"use strict";

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };

/*!
 * jQuery JavaScript Library v2.2.4
 * http://jquery.com/
 *
 * Includes Sizzle.js
 * http://sizzlejs.com/
 *
 * Copyright jQuery Foundation and other contributors
 * Released under the MIT license
 * http://jquery.org/license
 *
 * Date: 2016-05-20T17:23Z
 */

(function (global, factory) {

    if ((typeof module === "undefined" ? "undefined" : _typeof(module)) === "object" && _typeof(module.exports) === "object") {
		// For CommonJS and CommonJS-like environments where a proper `window`
		// is present, execute the factory and get jQuery.
		// For environments that do not have a `window` with a `document`
		// (such as Node.js), expose a factory as module.exports.
		// This accentuates the need for the creation of a real `window`.
		// e.g. var jQuery = require("jquery")(window);
		// See ticket #14549 for more info.
		module.exports = global.document ? factory(global, true) : function (w) {
			if (!w.document) {
				throw new Error("jQuery requires a window with a document");
			}
			return factory(w);
		};
	} else {
		factory(global);
	}

	// Pass this if window is not defined yet
})(typeof window !== "undefined" ? window : undefined, function (window, noGlobal) {

	// Support: Firefox 18+
	// Can't be in strict mode, several libs including ASP.NET trace
	// the stack via arguments.caller.callee and Firefox dies if
	// you try to trace through "use strict" call chains. (#13335)
	//"use strict";
	var arr = [];

	var document = window.document;

	var _slice = arr.slice;

	var concat = arr.concat;

	var push = arr.push;

	var indexOf = arr.indexOf;

	var class2type = {};

	var toString = class2type.toString;

	var hasOwn = class2type.hasOwnProperty;

	var support = {};

	var version = "2.2.4",


	// Define a local copy of jQuery
	jQuery = function jQuery(selector, context) {

		// The jQuery object is actually just the init constructor 'enhanced'
		// Need init if jQuery is called (just allow error to be thrown if not included)
		return new jQuery.fn.init(selector, context);
	},


	// Support: Android<4.1
	// Make sure we trim BOM and NBSP
	rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,


	// Matches dashed string for camelizing
	rmsPrefix = /^-ms-/,
	    rdashAlpha = /-([\da-z])/gi,


	// Used by jQuery.camelCase as callback to replace()
	fcamelCase = function fcamelCase(all, letter) {
		return letter.toUpperCase();
	};

	jQuery.fn = jQuery.prototype = {

		// The current version of jQuery being used
		jquery: version,

		constructor: jQuery,

		// Start with an empty selector
		selector: "",

		// The default length of a jQuery object is 0
		length: 0,

		toArray: function toArray() {
			return _slice.call(this);
		},

		// Get the Nth element in the matched element set OR
		// Get the whole matched element set as a clean array
		get: function get(num) {
			return num != null ?

			// Return just the one element from the set
			num < 0 ? this[num + this.length] : this[num] :

			// Return all the elements in a clean array
			_slice.call(this);
		},

		// Take an array of elements and push it onto the stack
		// (returning the new matched element set)
		pushStack: function pushStack(elems) {

			// Build a new jQuery matched element set
			var ret = jQuery.merge(this.constructor(), elems);

			// Add the old object onto the stack (as a reference)
			ret.prevObject = this;
			ret.context = this.context;

			// Return the newly-formed element set
			return ret;
		},

		// Execute a callback for every element in the matched set.
		each: function each(callback) {
			return jQuery.each(this, callback);
		},

		map: function map(callback) {
			return this.pushStack(jQuery.map(this, function (elem, i) {
				return callback.call(elem, i, elem);
			}));
		},

		slice: function slice() {
			return this.pushStack(_slice.apply(this, arguments));
		},

		first: function first() {
			return this.eq(0);
		},

		last: function last() {
			return this.eq(-1);
		},

		eq: function eq(i) {
			var len = this.length,
			    j = +i + (i < 0 ? len : 0);
			return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
		},

		end: function end() {
			return this.prevObject || this.constructor();
		},

		// For internal use only.
		// Behaves like an Array's method, not like a jQuery method.
		push: push,
		sort: arr.sort,
		splice: arr.splice
	};

	jQuery.extend = jQuery.fn.extend = function () {
		var options,
		    name,
		    src,
		    copy,
		    copyIsArray,
		    clone,
		    target = arguments[0] || {},
		    i = 1,
		    length = arguments.length,
		    deep = false;

		// Handle a deep copy situation
		if (typeof target === "boolean") {
			deep = target;

			// Skip the boolean and the target
			target = arguments[i] || {};
			i++;
		}

		// Handle case when target is a string or something (possible in deep copy)
		if ((typeof target === "undefined" ? "undefined" : _typeof(target)) !== "object" && !jQuery.isFunction(target)) {
			target = {};
		}

		// Extend jQuery itself if only one argument is passed
		if (i === length) {
			target = this;
			i--;
		}

		for (; i < length; i++) {

			// Only deal with non-null/undefined values
			if ((options = arguments[i]) != null) {

				// Extend the base object
				for (name in options) {
					src = target[name];
					copy = options[name];

					// Prevent never-ending loop
					if (target === copy) {
						continue;
					}

					// Recurse if we're merging plain objects or arrays
					if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))) {

						if (copyIsArray) {
							copyIsArray = false;
							clone = src && jQuery.isArray(src) ? src : [];
						} else {
							clone = src && jQuery.isPlainObject(src) ? src : {};
						}

						// Never move original objects, clone them
						target[name] = jQuery.extend(deep, clone, copy);

						// Don't bring in undefined values
					} else if (copy !== undefined) {
						target[name] = copy;
					}
				}
			}
		}

		// Return the modified object
		return target;
	};

	jQuery.extend({

		// Unique for each copy of jQuery on the page
		expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""),

		// Assume jQuery is ready without the ready module
		isReady: true,

		error: function error(msg) {
			throw new Error(msg);
		},

		noop: function noop() {},

		isFunction: function isFunction(obj) {
			return jQuery.type(obj) === "function";
		},

		isArray: Array.isArray,

		isWindow: function isWindow(obj) {
			return obj != null && obj === obj.window;
		},

		isNumeric: function isNumeric(obj) {

			// parseFloat NaNs numeric-cast false positives (null|true|false|"")
			// ...but misinterprets leading-number strings, particularly hex literals ("0x...")
			// subtraction forces infinities to NaN
			// adding 1 corrects loss of precision from parseFloat (#15100)
			var realStringObj = obj && obj.toString();
			return !jQuery.isArray(obj) && realStringObj - parseFloat(realStringObj) + 1 >= 0;
		},

		isPlainObject: function isPlainObject(obj) {
			var key;

			// Not plain objects:
			// - Any object or value whose internal [[Class]] property is not "[object Object]"
			// - DOM nodes
			// - window
			if (jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow(obj)) {
				return false;
			}

			// Not own constructor property must be Object
			if (obj.constructor && !hasOwn.call(obj, "constructor") && !hasOwn.call(obj.constructor.prototype || {}, "isPrototypeOf")) {
				return false;
			}

			// Own properties are enumerated firstly, so to speed up,
			// if last one is own, then all properties are own
			for (key in obj) {}

			return key === undefined || hasOwn.call(obj, key);
		},

		isEmptyObject: function isEmptyObject(obj) {
			var name;
			for (name in obj) {
				return false;
			}
			return true;
		},

		type: function type(obj) {
			if (obj == null) {
				return obj + "";
			}

			// Support: Android<4.0, iOS<6 (functionish RegExp)
			return (typeof obj === "undefined" ? "undefined" : _typeof(obj)) === "object" || typeof obj === "function" ? class2type[toString.call(obj)] || "object" : typeof obj === "undefined" ? "undefined" : _typeof(obj);
		},

		// Evaluates a script in a global context
		globalEval: function globalEval(code) {
			var script,
			    indirect = eval;

			code = jQuery.trim(code);

			if (code) {

				// If the code includes a valid, prologue position
				// strict mode pragma, execute code by injecting a
				// script tag into the document.
				if (code.indexOf("use strict") === 1) {
					script = document.createElement("script");
					script.text = code;
					document.head.appendChild(script).parentNode.removeChild(script);
				} else {

					// Otherwise, avoid the DOM node creation, insertion
					// and removal by using an indirect global eval

					indirect(code);
				}
			}
		},

		// Convert dashed to camelCase; used by the css and data modules
		// Support: IE9-11+
		// Microsoft forgot to hump their vendor prefix (#9572)
		camelCase: function camelCase(string) {
			return string.replace(rmsPrefix, "ms-").replace(rdashAlpha, fcamelCase);
		},

		nodeName: function nodeName(elem, name) {
			return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
		},

		each: function each(obj, callback) {
			var length,
			    i = 0;

			if (isArrayLike(obj)) {
				length = obj.length;
				for (; i < length; i++) {
					if (callback.call(obj[i], i, obj[i]) === false) {
						break;
					}
				}
			} else {
				for (i in obj) {
					if (callback.call(obj[i], i, obj[i]) === false) {
						break;
					}
				}
			}

			return obj;
		},

		// Support: Android<4.1
		trim: function trim(text) {
			return text == null ? "" : (text + "").replace(rtrim, "");
		},

		// results is for internal usage only
		makeArray: function makeArray(arr, results) {
			var ret = results || [];

			if (arr != null) {
				if (isArrayLike(Object(arr))) {
					jQuery.merge(ret, typeof arr === "string" ? [arr] : arr);
				} else {
					push.call(ret, arr);
				}
			}

			return ret;
		},

		inArray: function inArray(elem, arr, i) {
			return arr == null ? -1 : indexOf.call(arr, elem, i);
		},

		merge: function merge(first, second) {
			var len = +second.length,
			    j = 0,
			    i = first.length;

			for (; j < len; j++) {
				first[i++] = second[j];
			}

			first.length = i;

			return first;
		},

		grep: function grep(elems, callback, invert) {
			var callbackInverse,
			    matches = [],
			    i = 0,
			    length = elems.length,
			    callbackExpect = !invert;

			// Go through the array, only saving the items
			// that pass the validator function
			for (; i < length; i++) {
				callbackInverse = !callback(elems[i], i);
				if (callbackInverse !== callbackExpect) {
					matches.push(elems[i]);
				}
			}

			return matches;
		},

		// arg is for internal usage only
		map: function map(elems, callback, arg) {
			var length,
			    value,
			    i = 0,
			    ret = [];

			// Go through the array, translating each of the items to their new values
			if (isArrayLike(elems)) {
				length = elems.length;
				for (; i < length; i++) {
					value = callback(elems[i], i, arg);

					if (value != null) {
						ret.push(value);
					}
				}

				// Go through every key on the object,
			} else {
				for (i in elems) {
					value = callback(elems[i], i, arg);

					if (value != null) {
						ret.push(value);
					}
				}
			}

			// Flatten any nested arrays
			return concat.apply([], ret);
		},

		// A global GUID counter for objects
		guid: 1,

		// Bind a function to a context, optionally partially applying any
		// arguments.
		proxy: function proxy(fn, context) {
			var tmp, args, proxy;

			if (typeof context === "string") {
				tmp = fn[context];
				context = fn;
				fn = tmp;
			}

			// Quick check to determine if target is callable, in the spec
			// this throws a TypeError, but we will just return undefined.
			if (!jQuery.isFunction(fn)) {
				return undefined;
			}

			// Simulated bind
			args = _slice.call(arguments, 2);
			proxy = function proxy() {
				return fn.apply(context || this, args.concat(_slice.call(arguments)));
			};

			// Set the guid of unique handler to the same of original handler, so it can be removed
			proxy.guid = fn.guid = fn.guid || jQuery.guid++;

			return proxy;
		},

		now: Date.now,

		// jQuery.support is not used in Core but other projects attach their
		// properties to it so it needs to exist.
		support: support
	});

	// JSHint would error on this code due to the Symbol not being defined in ES5.
	// Defining this global in .jshintrc would create a danger of using the global
	// unguarded in another place, it seems safer to just disable JSHint for these
	// three lines.
	/* jshint ignore: start */
	if (typeof Symbol === "function") {
		jQuery.fn[Symbol.iterator] = arr[Symbol.iterator];
	}
	/* jshint ignore: end */

	// Populate the class2type map
	jQuery.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "), function (i, name) {
		class2type["[object " + name + "]"] = name.toLowerCase();
	});

	function isArrayLike(obj) {

		// Support: iOS 8.2 (not reproducible in simulator)
		// `in` check used to prevent JIT error (gh-2145)
		// hasOwn isn't used here due to false negatives
		// regarding Nodelist length in IE
		var length = !!obj && "length" in obj && obj.length,
		    type = jQuery.type(obj);

		if (type === "function" || jQuery.isWindow(obj)) {
			return false;
		}

		return type === "array" || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj;
	}
	var Sizzle =
	/*!
  * Sizzle CSS Selector Engine v2.2.1
  * http://sizzlejs.com/
  *
  * Copyright jQuery Foundation and other contributors
  * Released under the MIT license
  * http://jquery.org/license
  *
  * Date: 2015-10-17
  */
	function (window) {

		var i,
		    support,
		    Expr,
		    getText,
		    isXML,
		    tokenize,
		    compile,
		    select,
		    outermostContext,
		    sortInput,
		    hasDuplicate,


		// Local document vars
		setDocument,
		    document,
		    docElem,
		    documentIsHTML,
		    rbuggyQSA,
		    rbuggyMatches,
		    matches,
		    contains,


		// Instance-specific data
		expando = "sizzle" + 1 * new Date(),
		    preferredDoc = window.document,
		    dirruns = 0,
		    done = 0,
		    classCache = createCache(),
		    tokenCache = createCache(),
		    compilerCache = createCache(),
		    sortOrder = function sortOrder(a, b) {
			if (a === b) {
				hasDuplicate = true;
			}
			return 0;
		},


		// General-purpose constants
		MAX_NEGATIVE = 1 << 31,


		// Instance methods
		hasOwn = {}.hasOwnProperty,
		    arr = [],
		    pop = arr.pop,
		    push_native = arr.push,
		    push = arr.push,
		    slice = arr.slice,

		// Use a stripped-down indexOf as it's faster than native
		// http://jsperf.com/thor-indexof-vs-for/5
		indexOf = function indexOf(list, elem) {
			var i = 0,
			    len = list.length;
			for (; i < len; i++) {
				if (list[i] === elem) {
					return i;
				}
			}
			return -1;
		},
		    booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",


		// Regular expressions

		// http://www.w3.org/TR/css3-selectors/#whitespace
		whitespace = "[\\x20\\t\\r\\n\\f]",


		// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
		identifier = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",


		// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
		attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
		// Operator (capture 2)
		"*([*^$|!~]?=)" + whitespace +
		// "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
		"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + "*\\]",
		    pseudos = ":(" + identifier + ")(?:\\((" +
		// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
		// 1. quoted (capture 3; capture 4 or capture 5)
		"('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
		// 2. simple (capture 6)
		"((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
		// 3. anything else (capture 2)
		".*" + ")\\)|)",


		// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter
		rwhitespace = new RegExp(whitespace + "+", "g"),
		    rtrim = new RegExp("^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g"),
		    rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*"),
		    rcombinators = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"),
		    rattributeQuotes = new RegExp("=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g"),
		    rpseudo = new RegExp(pseudos),
		    ridentifier = new RegExp("^" + identifier + "$"),
		    matchExpr = {
			"ID": new RegExp("^#(" + identifier + ")"),
			"CLASS": new RegExp("^\\.(" + identifier + ")"),
			"TAG": new RegExp("^(" + identifier + "|[*])"),
			"ATTR": new RegExp("^" + attributes),
			"PSEUDO": new RegExp("^" + pseudos),
			"CHILD": new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i"),
			"bool": new RegExp("^(?:" + booleans + ")$", "i"),
			// For use in libraries implementing .is()
			// We use this for POS matching in `select`
			"needsContext": new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i")
		},
		    rinputs = /^(?:input|select|textarea|button)$/i,
		    rheader = /^h\d$/i,
		    rnative = /^[^{]+\{\s*\[native \w/,


		// Easily-parseable/retrievable ID or TAG or CLASS selectors
		rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
		    rsibling = /[+~]/,
		    rescape = /'|\\/g,


		// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
		runescape = new RegExp("\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig"),
		    funescape = function funescape(_, escaped, escapedWhitespace) {
			var high = "0x" + escaped - 0x10000;
			// NaN means non-codepoint
			// Support: Firefox<24
			// Workaround erroneous numeric interpretation of +"0x"
			return high !== high || escapedWhitespace ? escaped : high < 0 ?
			// BMP codepoint
			String.fromCharCode(high + 0x10000) :
			// Supplemental Plane codepoint (surrogate pair)
			String.fromCharCode(high >> 10 | 0xD800, high & 0x3FF | 0xDC00);
		},


		// Used for iframes
		// See setDocument()
		// Removing the function wrapper causes a "Permission Denied"
		// error in IE
		unloadHandler = function unloadHandler() {
			setDocument();
		};

		// Optimize for push.apply( _, NodeList )
		try {
			push.apply(arr = slice.call(preferredDoc.childNodes), preferredDoc.childNodes);
			// Support: Android<4.0
			// Detect silently failing push.apply
			arr[preferredDoc.childNodes.length].nodeType;
		} catch (e) {
			push = { apply: arr.length ?

				// Leverage slice if possible
				function (target, els) {
					push_native.apply(target, slice.call(els));
				} :

				// Support: IE<9
				// Otherwise append directly
				function (target, els) {
					var j = target.length,
					    i = 0;
					// Can't trust NodeList.length
					while (target[j++] = els[i++]) {}
					target.length = j - 1;
				}
			};
		}

		function Sizzle(selector, context, results, seed) {
			var m,
			    i,
			    elem,
			    nid,
			    nidselect,
			    match,
			    groups,
			    newSelector,
			    newContext = context && context.ownerDocument,


			// nodeType defaults to 9, since context defaults to document
			nodeType = context ? context.nodeType : 9;

			results = results || [];

			// Return early from calls with invalid selector or context
			if (typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {

				return results;
			}

			// Try to shortcut find operations (as opposed to filters) in HTML documents
			if (!seed) {

				if ((context ? context.ownerDocument || context : preferredDoc) !== document) {
					setDocument(context);
				}
				context = context || document;

				if (documentIsHTML) {

					// If the selector is sufficiently simple, try using a "get*By*" DOM method
					// (excepting DocumentFragment context, where the methods don't exist)
					if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {

						// ID selector
						if (m = match[1]) {

							// Document context
							if (nodeType === 9) {
								if (elem = context.getElementById(m)) {

									// Support: IE, Opera, Webkit
									// TODO: identify versions
									// getElementById can match elements by name instead of ID
									if (elem.id === m) {
										results.push(elem);
										return results;
									}
								} else {
									return results;
								}

								// Element context
							} else {

								// Support: IE, Opera, Webkit
								// TODO: identify versions
								// getElementById can match elements by name instead of ID
								if (newContext && (elem = newContext.getElementById(m)) && contains(context, elem) && elem.id === m) {

									results.push(elem);
									return results;
								}
							}

							// Type selector
						} else if (match[2]) {
							push.apply(results, context.getElementsByTagName(selector));
							return results;

							// Class selector
						} else if ((m = match[3]) && support.getElementsByClassName && context.getElementsByClassName) {

							push.apply(results, context.getElementsByClassName(m));
							return results;
						}
					}

					// Take advantage of querySelectorAll
					if (support.qsa && !compilerCache[selector + " "] && (!rbuggyQSA || !rbuggyQSA.test(selector))) {

						if (nodeType !== 1) {
							newContext = context;
							newSelector = selector;

							// qSA looks outside Element context, which is not what we want
							// Thanks to Andrew Dupont for this workaround technique
							// Support: IE <=8
							// Exclude object elements
						} else if (context.nodeName.toLowerCase() !== "object") {

							// Capture the context ID, setting it first if necessary
							if (nid = context.getAttribute("id")) {
								nid = nid.replace(rescape, "\\$&");
							} else {
								context.setAttribute("id", nid = expando);
							}

							// Prefix every selector in the list
							groups = tokenize(selector);
							i = groups.length;
							nidselect = ridentifier.test(nid) ? "#" + nid : "[id='" + nid + "']";
							while (i--) {
								groups[i] = nidselect + " " + toSelector(groups[i]);
							}
							newSelector = groups.join(",");

							// Expand context for sibling selectors
							newContext = rsibling.test(selector) && testContext(context.parentNode) || context;
						}

						if (newSelector) {
							try {
								push.apply(results, newContext.querySelectorAll(newSelector));
								return results;
							} catch (qsaError) {} finally {
								if (nid === expando) {
									context.removeAttribute("id");
								}
							}
						}
					}
				}
			}

			// All others
			return select(selector.replace(rtrim, "$1"), context, results, seed);
		}

		/**
   * Create key-value caches of limited size
   * @returns {function(string, object)} Returns the Object data after storing it on itself with
   *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
   *	deleting the oldest entry
   */
		function createCache() {
			var keys = [];

			function cache(key, value) {
				// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
				if (keys.push(key + " ") > Expr.cacheLength) {
					// Only keep the most recent entries
					delete cache[keys.shift()];
				}
				return cache[key + " "] = value;
			}
			return cache;
		}

		/**
   * Mark a function for special use by Sizzle
   * @param {Function} fn The function to mark
   */
		function markFunction(fn) {
			fn[expando] = true;
			return fn;
		}

		/**
   * Support testing using an element
   * @param {Function} fn Passed the created div and expects a boolean result
   */
		function assert(fn) {
			var div = document.createElement("div");

			try {
				return !!fn(div);
			} catch (e) {
				return false;
			} finally {
				// Remove from its parent by default
				if (div.parentNode) {
					div.parentNode.removeChild(div);
				}
				// release memory in IE
				div = null;
			}
		}

		/**
   * Adds the same handler for all of the specified attrs
   * @param {String} attrs Pipe-separated list of attributes
   * @param {Function} handler The method that will be applied
   */
		function addHandle(attrs, handler) {
			var arr = attrs.split("|"),
			    i = arr.length;

			while (i--) {
				Expr.attrHandle[arr[i]] = handler;
			}
		}

		/**
   * Checks document order of two siblings
   * @param {Element} a
   * @param {Element} b
   * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
   */
		function siblingCheck(a, b) {
			var cur = b && a,
			    diff = cur && a.nodeType === 1 && b.nodeType === 1 && (~b.sourceIndex || MAX_NEGATIVE) - (~a.sourceIndex || MAX_NEGATIVE);

			// Use IE sourceIndex if available on both nodes
			if (diff) {
				return diff;
			}

			// Check if b follows a
			if (cur) {
				while (cur = cur.nextSibling) {
					if (cur === b) {
						return -1;
					}
				}
			}

			return a ? 1 : -1;
		}

		/**
   * Returns a function to use in pseudos for input types
   * @param {String} type
   */
		function createInputPseudo(type) {
			return function (elem) {
				var name = elem.nodeName.toLowerCase();
				return name === "input" && elem.type === type;
			};
		}

		/**
   * Returns a function to use in pseudos for buttons
   * @param {String} type
   */
		function createButtonPseudo(type) {
			return function (elem) {
				var name = elem.nodeName.toLowerCase();
				return (name === "input" || name === "button") && elem.type === type;
			};
		}

		/**
   * Returns a function to use in pseudos for positionals
   * @param {Function} fn
   */
		function createPositionalPseudo(fn) {
			return markFunction(function (argument) {
				argument = +argument;
				return markFunction(function (seed, matches) {
					var j,
					    matchIndexes = fn([], seed.length, argument),
					    i = matchIndexes.length;

					// Match elements found at the specified indexes
					while (i--) {
						if (seed[j = matchIndexes[i]]) {
							seed[j] = !(matches[j] = seed[j]);
						}
					}
				});
			});
		}

		/**
   * Checks a node for validity as a Sizzle context
   * @param {Element|Object=} context
   * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
   */
		function testContext(context) {
			return context && typeof context.getElementsByTagName !== "undefined" && context;
		}

		// Expose support vars for convenience
		support = Sizzle.support = {};

		/**
   * Detects XML nodes
   * @param {Element|Object} elem An element or a document
   * @returns {Boolean} True iff elem is a non-HTML XML node
   */
		isXML = Sizzle.isXML = function (elem) {
			// documentElement is verified for cases where it doesn't yet exist
			// (such as loading iframes in IE - #4833)
			var documentElement = elem && (elem.ownerDocument || elem).documentElement;
			return documentElement ? documentElement.nodeName !== "HTML" : false;
		};

		/**
   * Sets document-related variables once based on the current document
   * @param {Element|Object} [doc] An element or document object to use to set the document
   * @returns {Object} Returns the current document
   */
		setDocument = Sizzle.setDocument = function (node) {
			var hasCompare,
			    parent,
			    doc = node ? node.ownerDocument || node : preferredDoc;

			// Return early if doc is invalid or already selected
			if (doc === document || doc.nodeType !== 9 || !doc.documentElement) {
				return document;
			}

			// Update global variables
			document = doc;
			docElem = document.documentElement;
			documentIsHTML = !isXML(document);

			// Support: IE 9-11, Edge
			// Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
			if ((parent = document.defaultView) && parent.top !== parent) {
				// Support: IE 11
				if (parent.addEventListener) {
					parent.addEventListener("unload", unloadHandler, false);

					// Support: IE 9 - 10 only
				} else if (parent.attachEvent) {
					parent.attachEvent("onunload", unloadHandler);
				}
			}

			/* Attributes
   ---------------------------------------------------------------------- */

			// Support: IE<8
			// Verify that getAttribute really returns attributes and not properties
			// (excepting IE8 booleans)
			support.attributes = assert(function (div) {
				div.className = "i";
				return !div.getAttribute("className");
			});

			/* getElement(s)By*
   ---------------------------------------------------------------------- */

			// Check if getElementsByTagName("*") returns only elements
			support.getElementsByTagName = assert(function (div) {
				div.appendChild(document.createComment(""));
				return !div.getElementsByTagName("*").length;
			});

			// Support: IE<9
			support.getElementsByClassName = rnative.test(document.getElementsByClassName);

			// Support: IE<10
			// Check if getElementById returns elements by name
			// The broken getElementById methods don't pick up programatically-set names,
			// so use a roundabout getElementsByName test
			support.getById = assert(function (div) {
				docElem.appendChild(div).id = expando;
				return !document.getElementsByName || !document.getElementsByName(expando).length;
			});

			// ID find and filter
			if (support.getById) {
				Expr.find["ID"] = function (id, context) {
					if (typeof context.getElementById !== "undefined" && documentIsHTML) {
						var m = context.getElementById(id);
						return m ? [m] : [];
					}
				};
				Expr.filter["ID"] = function (id) {
					var attrId = id.replace(runescape, funescape);
					return function (elem) {
						return elem.getAttribute("id") === attrId;
					};
				};
			} else {
				// Support: IE6/7
				// getElementById is not reliable as a find shortcut
				delete Expr.find["ID"];

				Expr.filter["ID"] = function (id) {
					var attrId = id.replace(runescape, funescape);
					return function (elem) {
						var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
						return node && node.value === attrId;
					};
				};
			}

			// Tag
			Expr.find["TAG"] = support.getElementsByTagName ? function (tag, context) {
				if (typeof context.getElementsByTagName !== "undefined") {
					return context.getElementsByTagName(tag);

					// DocumentFragment nodes don't have gEBTN
				} else if (support.qsa) {
					return context.querySelectorAll(tag);
				}
			} : function (tag, context) {
				var elem,
				    tmp = [],
				    i = 0,

				// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too
				results = context.getElementsByTagName(tag);

				// Filter out possible comments
				if (tag === "*") {
					while (elem = results[i++]) {
						if (elem.nodeType === 1) {
							tmp.push(elem);
						}
					}

					return tmp;
				}
				return results;
			};

			// Class
			Expr.find["CLASS"] = support.getElementsByClassName && function (className, context) {
				if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) {
					return context.getElementsByClassName(className);
				}
			};

			/* QSA/matchesSelector
   ---------------------------------------------------------------------- */

			// QSA and matchesSelector support

			// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
			rbuggyMatches = [];

			// qSa(:focus) reports false when true (Chrome 21)
			// We allow this because of a bug in IE8/9 that throws an error
			// whenever `document.activeElement` is accessed on an iframe
			// So, we allow :focus to pass through QSA all the time to avoid the IE error
			// See http://bugs.jquery.com/ticket/13378
			rbuggyQSA = [];

			if (support.qsa = rnative.test(document.querySelectorAll)) {
				// Build QSA regex
				// Regex strategy adopted from Diego Perini
				assert(function (div) {
					// Select is set to empty string on purpose
					// This is to test IE's treatment of not explicitly
					// setting a boolean content attribute,
					// since its presence should be enough
					// http://bugs.jquery.com/ticket/12359
					docElem.appendChild(div).innerHTML = "<a id='" + expando + "'></a>" + "<select id='" + expando + "-\r\\' msallowcapture=''>" + "<option selected=''></option></select>";

					// Support: IE8, Opera 11-12.16
					// Nothing should be selected when empty strings follow ^= or $= or *=
					// The test attribute must be unknown in Opera but "safe" for WinRT
					// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
					if (div.querySelectorAll("[msallowcapture^='']").length) {
						rbuggyQSA.push("[*^$]=" + whitespace + "*(?:''|\"\")");
					}

					// Support: IE8
					// Boolean attributes and "value" are not treated correctly
					if (!div.querySelectorAll("[selected]").length) {
						rbuggyQSA.push("\\[" + whitespace + "*(?:value|" + booleans + ")");
					}

					// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
					if (!div.querySelectorAll("[id~=" + expando + "-]").length) {
						rbuggyQSA.push("~=");
					}

					// Webkit/Opera - :checked should return selected option elements
					// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
					// IE8 throws error here and will not see later tests
					if (!div.querySelectorAll(":checked").length) {
						rbuggyQSA.push(":checked");
					}

					// Support: Safari 8+, iOS 8+
					// https://bugs.webkit.org/show_bug.cgi?id=136851
					// In-page `selector#id sibing-combinator selector` fails
					if (!div.querySelectorAll("a#" + expando + "+*").length) {
						rbuggyQSA.push(".#.+[+~]");
					}
				});

				assert(function (div) {
					// Support: Windows 8 Native Apps
					// The type and name attributes are restricted during .innerHTML assignment
					var input = document.createElement("input");
					input.setAttribute("type", "hidden");
					div.appendChild(input).setAttribute("name", "D");

					// Support: IE8
					// Enforce case-sensitivity of name attribute
					if (div.querySelectorAll("[name=d]").length) {
						rbuggyQSA.push("name" + whitespace + "*[*^$|!~]?=");
					}

					// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
					// IE8 throws error here and will not see later tests
					if (!div.querySelectorAll(":enabled").length) {
						rbuggyQSA.push(":enabled", ":disabled");
					}

					// Opera 10-11 does not throw on post-comma invalid pseudos
					div.querySelectorAll("*,:x");
					rbuggyQSA.push(",.*:");
				});
			}

			if (support.matchesSelector = rnative.test(matches = docElem.matches || docElem.webkitMatchesSelector || docElem.mozMatchesSelector || docElem.oMatchesSelector || docElem.msMatchesSelector)) {

				assert(function (div) {
					// Check to see if it's possible to do matchesSelector
					// on a disconnected node (IE 9)
					support.disconnectedMatch = matches.call(div, "div");

					// This should fail with an exception
					// Gecko does not error, returns false instead
					matches.call(div, "[s!='']:x");
					rbuggyMatches.push("!=", pseudos);
				});
			}

			rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));
			rbuggyMatches = rbuggyMatches.length && new RegExp(rbuggyMatches.join("|"));

			/* Contains
   ---------------------------------------------------------------------- */
			hasCompare = rnative.test(docElem.compareDocumentPosition);

			// Element contains another
			// Purposefully self-exclusive
			// As in, an element does not contain itself
			contains = hasCompare || rnative.test(docElem.contains) ? function (a, b) {
				var adown = a.nodeType === 9 ? a.documentElement : a,
				    bup = b && b.parentNode;
				return a === bup || !!(bup && bup.nodeType === 1 && (adown.contains ? adown.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));
			} : function (a, b) {
				if (b) {
					while (b = b.parentNode) {
						if (b === a) {
							return true;
						}
					}
				}
				return false;
			};

			/* Sorting
   ---------------------------------------------------------------------- */

			// Document order sorting
			sortOrder = hasCompare ? function (a, b) {

				// Flag for duplicate removal
				if (a === b) {
					hasDuplicate = true;
					return 0;
				}

				// Sort on method existence if only one input has compareDocumentPosition
				var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
				if (compare) {
					return compare;
				}

				// Calculate position if both inputs belong to the same document
				compare = (a.ownerDocument || a) === (b.ownerDocument || b) ? a.compareDocumentPosition(b) :

				// Otherwise we know they are disconnected
				1;

				// Disconnected nodes
				if (compare & 1 || !support.sortDetached && b.compareDocumentPosition(a) === compare) {

					// Choose the first element that is related to our preferred document
					if (a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a)) {
						return -1;
					}
					if (b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b)) {
						return 1;
					}

					// Maintain original order
					return sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0;
				}

				return compare & 4 ? -1 : 1;
			} : function (a, b) {
				// Exit early if the nodes are identical
				if (a === b) {
					hasDuplicate = true;
					return 0;
				}

				var cur,
				    i = 0,
				    aup = a.parentNode,
				    bup = b.parentNode,
				    ap = [a],
				    bp = [b];

				// Parentless nodes are either documents or disconnected
				if (!aup || !bup) {
					return a === document ? -1 : b === document ? 1 : aup ? -1 : bup ? 1 : sortInput ? indexOf(sortInput, a) - indexOf(sortInput, b) : 0;

					// If the nodes are siblings, we can do a quick check
				} else if (aup === bup) {
					return siblingCheck(a, b);
				}

				// Otherwise we need full lists of their ancestors for comparison
				cur = a;
				while (cur = cur.parentNode) {
					ap.unshift(cur);
				}
				cur = b;
				while (cur = cur.parentNode) {
					bp.unshift(cur);
				}

				// Walk down the tree looking for a discrepancy
				while (ap[i] === bp[i]) {
					i++;
				}

				return i ?
				// Do a sibling check if the nodes have a common ancestor
				siblingCheck(ap[i], bp[i]) :

				// Otherwise nodes in our document sort first
				ap[i] === preferredDoc ? -1 : bp[i] === preferredDoc ? 1 : 0;
			};

			return document;
		};

		Sizzle.matches = function (expr, elements) {
			return Sizzle(expr, null, null, elements);
		};

		Sizzle.matchesSelector = function (elem, expr) {
			// Set document vars if needed
			if ((elem.ownerDocument || elem) !== document) {
				setDocument(elem);
			}

			// Make sure that attribute selectors are quoted
			expr = expr.replace(rattributeQuotes, "='$1']");

			if (support.matchesSelector && documentIsHTML && !compilerCache[expr + " "] && (!rbuggyMatches || !rbuggyMatches.test(expr)) && (!rbuggyQSA || !rbuggyQSA.test(expr))) {

				try {
					var ret = matches.call(elem, expr);

					// IE 9's matchesSelector returns false on disconnected nodes
					if (ret || support.disconnectedMatch ||
					// As well, disconnected nodes are said to be in a document
					// fragment in IE 9
					elem.document && elem.document.nodeType !== 11) {
						return ret;
					}
				} catch (e) {}
			}

			return Sizzle(expr, document, null, [elem]).length > 0;
		};

		Sizzle.contains = function (context, elem) {
			// Set document vars if needed
			if ((context.ownerDocument || context) !== document) {
				setDocument(context);
			}
			return contains(context, elem);
		};

		Sizzle.attr = function (elem, name) {
			// Set document vars if needed
			if ((elem.ownerDocument || elem) !== document) {
				setDocument(elem);
			}

			var fn = Expr.attrHandle[name.toLowerCase()],

			// Don't get fooled by Object.prototype properties (jQuery #13807)
			val = fn && hasOwn.call(Expr.attrHandle, name.toLowerCase()) ? fn(elem, name, !documentIsHTML) : undefined;

			return val !== undefined ? val : support.attributes || !documentIsHTML ? elem.getAttribute(name) : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;
		};

		Sizzle.error = function (msg) {
			throw new Error("Syntax error, unrecognized expression: " + msg);
		};

		/**
   * Document sorting and removing duplicates
   * @param {ArrayLike} results
   */
		Sizzle.uniqueSort = function (results) {
			var elem,
			    duplicates = [],
			    j = 0,
			    i = 0;

			// Unless we *know* we can detect duplicates, assume their presence
			hasDuplicate = !support.detectDuplicates;
			sortInput = !support.sortStable && results.slice(0);
			results.sort(sortOrder);

			if (hasDuplicate) {
				while (elem = results[i++]) {
					if (elem === results[i]) {
						j = duplicates.push(i);
					}
				}
				while (j--) {
					results.splice(duplicates[j], 1);
				}
			}

			// Clear input after sorting to release objects
			// See https://github.com/jquery/sizzle/pull/225
			sortInput = null;

			return results;
		};

		/**
   * Utility function for retrieving the text value of an array of DOM nodes
   * @param {Array|Element} elem
   */
		getText = Sizzle.getText = function (elem) {
			var node,
			    ret = "",
			    i = 0,
			    nodeType = elem.nodeType;

			if (!nodeType) {
				// If no nodeType, this is expected to be an array
				while (node = elem[i++]) {
					// Do not traverse comment nodes
					ret += getText(node);
				}
			} else if (nodeType === 1 || nodeType === 9 || nodeType === 11) {
				// Use textContent for elements
				// innerText usage removed for consistency of new lines (jQuery #11153)
				if (typeof elem.textContent === "string") {
					return elem.textContent;
				} else {
					// Traverse its children
					for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
						ret += getText(elem);
					}
				}
			} else if (nodeType === 3 || nodeType === 4) {
				return elem.nodeValue;
			}
			// Do not include comment or processing instruction nodes

			return ret;
		};

		Expr = Sizzle.selectors = {

			// Can be adjusted by the user
			cacheLength: 50,

			createPseudo: markFunction,

			match: matchExpr,

			attrHandle: {},

			find: {},

			relative: {
				">": { dir: "parentNode", first: true },
				" ": { dir: "parentNode" },
				"+": { dir: "previousSibling", first: true },
				"~": { dir: "previousSibling" }
			},

			preFilter: {
				"ATTR": function ATTR(match) {
					match[1] = match[1].replace(runescape, funescape);

					// Move the given value to match[3] whether quoted or unquoted
					match[3] = (match[3] || match[4] || match[5] || "").replace(runescape, funescape);

					if (match[2] === "~=") {
						match[3] = " " + match[3] + " ";
					}

					return match.slice(0, 4);
				},

				"CHILD": function CHILD(match) {
					/* matches from matchExpr["CHILD"]
     	1 type (only|nth|...)
     	2 what (child|of-type)
     	3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
     	4 xn-component of xn+y argument ([+-]?\d*n|)
     	5 sign of xn-component
     	6 x of xn-component
     	7 sign of y-component
     	8 y of y-component
     */
					match[1] = match[1].toLowerCase();

					if (match[1].slice(0, 3) === "nth") {
						// nth-* requires argument
						if (!match[3]) {
							Sizzle.error(match[0]);
						}

						// numeric x and y parameters for Expr.filter.CHILD
						// remember that false/true cast respectively to 0/1
						match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd"));
						match[5] = +(match[7] + match[8] || match[3] === "odd");

						// other types prohibit arguments
					} else if (match[3]) {
						Sizzle.error(match[0]);
					}

					return match;
				},

				"PSEUDO": function PSEUDO(match) {
					var excess,
					    unquoted = !match[6] && match[2];

					if (matchExpr["CHILD"].test(match[0])) {
						return null;
					}

					// Accept quoted arguments as-is
					if (match[3]) {
						match[2] = match[4] || match[5] || "";

						// Strip excess characters from unquoted arguments
					} else if (unquoted && rpseudo.test(unquoted) && (
					// Get excess from tokenize (recursively)
					excess = tokenize(unquoted, true)) && (
					// advance to the next closing parenthesis
					excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {

						// excess is a negative index
						match[0] = match[0].slice(0, excess);
						match[2] = unquoted.slice(0, excess);
					}

					// Return only captures needed by the pseudo filter method (type and argument)
					return match.slice(0, 3);
				}
			},

			filter: {

				"TAG": function TAG(nodeNameSelector) {
					var nodeName = nodeNameSelector.replace(runescape, funescape).toLowerCase();
					return nodeNameSelector === "*" ? function () {
						return true;
					} : function (elem) {
						return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
					};
				},

				"CLASS": function CLASS(className) {
					var pattern = classCache[className + " "];

					return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && classCache(className, function (elem) {
						return pattern.test(typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "");
					});
				},

				"ATTR": function ATTR(name, operator, check) {
					return function (elem) {
						var result = Sizzle.attr(elem, name);

						if (result == null) {
							return operator === "!=";
						}
						if (!operator) {
							return true;
						}

						result += "";

						return operator === "=" ? result === check : operator === "!=" ? result !== check : operator === "^=" ? check && result.indexOf(check) === 0 : operator === "*=" ? check && result.indexOf(check) > -1 : operator === "$=" ? check && result.slice(-check.length) === check : operator === "~=" ? (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1 : operator === "|=" ? result === check || result.slice(0, check.length + 1) === check + "-" : false;
					};
				},

				"CHILD": function CHILD(type, what, argument, first, last) {
					var simple = type.slice(0, 3) !== "nth",
					    forward = type.slice(-4) !== "last",
					    ofType = what === "of-type";

					return first === 1 && last === 0 ?

					// Shortcut for :nth-*(n)
					function (elem) {
						return !!elem.parentNode;
					} : function (elem, context, xml) {
						var cache,
						    uniqueCache,
						    outerCache,
						    node,
						    nodeIndex,
						    start,
						    dir = simple !== forward ? "nextSibling" : "previousSibling",
						    parent = elem.parentNode,
						    name = ofType && elem.nodeName.toLowerCase(),
						    useCache = !xml && !ofType,
						    diff = false;

						if (parent) {

							// :(first|last|only)-(child|of-type)
							if (simple) {
								while (dir) {
									node = elem;
									while (node = node[dir]) {
										if (ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) {

											return false;
										}
									}
									// Reverse direction for :only-* (if we haven't yet done so)
									start = dir = type === "only" && !start && "nextSibling";
								}
								return true;
							}

							start = [forward ? parent.firstChild : parent.lastChild];

							// non-xml :nth-child(...) stores cache data on `parent`
							if (forward && useCache) {

								// Seek `elem` from a previously-cached index

								// ...in a gzip-friendly way
								node = parent;
								outerCache = node[expando] || (node[expando] = {});

								// Support: IE <9 only
								// Defend against cloned attroperties (jQuery gh-1709)
								uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});

								cache = uniqueCache[type] || [];
								nodeIndex = cache[0] === dirruns && cache[1];
								diff = nodeIndex && cache[2];
								node = nodeIndex && parent.childNodes[nodeIndex];

								while (node = ++nodeIndex && node && node[dir] || (

								// Fallback to seeking `elem` from the start
								diff = nodeIndex = 0) || start.pop()) {

									// When found, cache indexes on `parent` and break
									if (node.nodeType === 1 && ++diff && node === elem) {
										uniqueCache[type] = [dirruns, nodeIndex, diff];
										break;
									}
								}
							} else {
								// Use previously-cached element index if available
								if (useCache) {
									// ...in a gzip-friendly way
									node = elem;
									outerCache = node[expando] || (node[expando] = {});

									// Support: IE <9 only
									// Defend against cloned attroperties (jQuery gh-1709)
									uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});

									cache = uniqueCache[type] || [];
									nodeIndex = cache[0] === dirruns && cache[1];
									diff = nodeIndex;
								}

								// xml :nth-child(...)
								// or :nth-last-child(...) or :nth(-last)?-of-type(...)
								if (diff === false) {
									// Use the same loop as above to seek `elem` from the start
									while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {

										if ((ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1) && ++diff) {

											// Cache the index of each encountered element
											if (useCache) {
												outerCache = node[expando] || (node[expando] = {});

												// Support: IE <9 only
												// Defend against cloned attroperties (jQuery gh-1709)
												uniqueCache = outerCache[node.uniqueID] || (outerCache[node.uniqueID] = {});

												uniqueCache[type] = [dirruns, diff];
											}

											if (node === elem) {
												break;
											}
										}
									}
								}
							}

							// Incorporate the offset, then check against cycle size
							diff -= last;
							return diff === first || diff % first === 0 && diff / first >= 0;
						}
					};
				},

				"PSEUDO": function PSEUDO(pseudo, argument) {
					// pseudo-class names are case-insensitive
					// http://www.w3.org/TR/selectors/#pseudo-classes
					// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters
					// Remember that setFilters inherits from pseudos
					var args,
					    fn = Expr.pseudos[pseudo] || Expr.setFilters[pseudo.toLowerCase()] || Sizzle.error("unsupported pseudo: " + pseudo);

					// The user may use createPseudo to indicate that
					// arguments are needed to create the filter function
					// just as Sizzle does
					if (fn[expando]) {
						return fn(argument);
					}

					// But maintain support for old signatures
					if (fn.length > 1) {
						args = [pseudo, pseudo, "", argument];
						return Expr.setFilters.hasOwnProperty(pseudo.toLowerCase()) ? markFunction(function (seed, matches) {
							var idx,
							    matched = fn(seed, argument),
							    i = matched.length;
							while (i--) {
								idx = indexOf(seed, matched[i]);
								seed[idx] = !(matches[idx] = matched[i]);
							}
						}) : function (elem) {
							return fn(elem, 0, args);
						};
					}

					return fn;
				}
			},

			pseudos: {
				// Potentially complex pseudos
				"not": markFunction(function (selector) {
					// Trim the selector passed to compile
					// to avoid treating leading and trailing
					// spaces as combinators
					var input = [],
					    results = [],
					    matcher = compile(selector.replace(rtrim, "$1"));

					return matcher[expando] ? markFunction(function (seed, matches, context, xml) {
						var elem,
						    unmatched = matcher(seed, null, xml, []),
						    i = seed.length;

						// Match elements unmatched by `matcher`
						while (i--) {
							if (elem = unmatched[i]) {
								seed[i] = !(matches[i] = elem);
							}
						}
					}) : function (elem, context, xml) {
						input[0] = elem;
						matcher(input, null, xml, results);
						// Don't keep the element (issue #299)
						input[0] = null;
						return !results.pop();
					};
				}),

				"has": markFunction(function (selector) {
					return function (elem) {
						return Sizzle(selector, elem).length > 0;
					};
				}),

				"contains": markFunction(function (text) {
					text = text.replace(runescape, funescape);
					return function (elem) {
						return (elem.textContent || elem.innerText || getText(elem)).indexOf(text) > -1;
					};
				}),

				// "Whether an element is represented by a :lang() selector
				// is based solely on the element's language value
				// being equal to the identifier C,
				// or beginning with the identifier C immediately followed by "-".
				// The matching of C against the element's language value is performed case-insensitively.
				// The identifier C does not have to be a valid language name."
				// http://www.w3.org/TR/selectors/#lang-pseudo
				"lang": markFunction(function (lang) {
					// lang value must be a valid identifier
					if (!ridentifier.test(lang || "")) {
						Sizzle.error("unsupported lang: " + lang);
					}
					lang = lang.replace(runescape, funescape).toLowerCase();
					return function (elem) {
						var elemLang;
						do {
							if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) {

								elemLang = elemLang.toLowerCase();
								return elemLang === lang || elemLang.indexOf(lang + "-") === 0;
							}
						} while ((elem = elem.parentNode) && elem.nodeType === 1);
						return false;
					};
				}),

				// Miscellaneous
				"target": function target(elem) {
					var hash = window.location && window.location.hash;
					return hash && hash.slice(1) === elem.id;
				},

				"root": function root(elem) {
					return elem === docElem;
				},

				"focus": function focus(elem) {
					return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
				},

				// Boolean properties
				"enabled": function enabled(elem) {
					return elem.disabled === false;
				},

				"disabled": function disabled(elem) {
					return elem.disabled === true;
				},

				"checked": function checked(elem) {
					// In CSS3, :checked should return both checked and selected elements
					// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
					var nodeName = elem.nodeName.toLowerCase();
					return nodeName === "input" && !!elem.checked || nodeName === "option" && !!elem.selected;
				},

				"selected": function selected(elem) {
					// Accessing this property makes selected-by-default
					// options in Safari work properly
					if (elem.parentNode) {
						elem.parentNode.selectedIndex;
					}

					return elem.selected === true;
				},

				// Contents
				"empty": function empty(elem) {
					// http://www.w3.org/TR/selectors/#empty-pseudo
					// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),
					//   but not by others (comment: 8; processing instruction: 7; etc.)
					// nodeType < 6 works because attributes (2) do not appear as children
					for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
						if (elem.nodeType < 6) {
							return false;
						}
					}
					return true;
				},

				"parent": function parent(elem) {
					return !Expr.pseudos["empty"](elem);
				},

				// Element/input types
				"header": function header(elem) {
					return rheader.test(elem.nodeName);
				},

				"input": function input(elem) {
					return rinputs.test(elem.nodeName);
				},

				"button": function button(elem) {
					var name = elem.nodeName.toLowerCase();
					return name === "input" && elem.type === "button" || name === "button";
				},

				"text": function text(elem) {
					var attr;
					return elem.nodeName.toLowerCase() === "input" && elem.type === "text" && (

					// Support: IE<8
					// New HTML5 attribute values (e.g., "search") appear with elem.type === "text"
					(attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text");
				},

				// Position-in-collection
				"first": createPositionalPseudo(function () {
					return [0];
				}),

				"last": createPositionalPseudo(function (matchIndexes, length) {
					return [length - 1];
				}),

				"eq": createPositionalPseudo(function (matchIndexes, length, argument) {
					return [argument < 0 ? argument + length : argument];
				}),

				"even": createPositionalPseudo(function (matchIndexes, length) {
					var i = 0;
					for (; i < length; i += 2) {
						matchIndexes.push(i);
					}
					return matchIndexes;
				}),

				"odd": createPositionalPseudo(function (matchIndexes, length) {
					var i = 1;
					for (; i < length; i += 2) {
						matchIndexes.push(i);
					}
					return matchIndexes;
				}),

				"lt": createPositionalPseudo(function (matchIndexes, length, argument) {
					var i = argument < 0 ? argument + length : argument;
					for (; --i >= 0;) {
						matchIndexes.push(i);
					}
					return matchIndexes;
				}),

				"gt": createPositionalPseudo(function (matchIndexes, length, argument) {
					var i = argument < 0 ? argument + length : argument;
					for (; ++i < length;) {
						matchIndexes.push(i);
					}
					return matchIndexes;
				})
			}
		};

		Expr.pseudos["nth"] = Expr.pseudos["eq"];

		// Add button/input type pseudos
		for (i in { radio: true, checkbox: true, file: true, password: true, image: true }) {
			Expr.pseudos[i] = createInputPseudo(i);
		}
		for (i in { submit: true, reset: true }) {
			Expr.pseudos[i] = createButtonPseudo(i);
		}

		// Easy API for creating new setFilters
		function setFilters() {}
		setFilters.prototype = Expr.filters = Expr.pseudos;
		Expr.setFilters = new setFilters();

		tokenize = Sizzle.tokenize = function (selector, parseOnly) {
			var matched,
			    match,
			    tokens,
			    type,
			    soFar,
			    groups,
			    preFilters,
			    cached = tokenCache[selector + " "];

			if (cached) {
				return parseOnly ? 0 : cached.slice(0);
			}

			soFar = selector;
			groups = [];
			preFilters = Expr.preFilter;

			while (soFar) {

				// Comma and first run
				if (!matched || (match = rcomma.exec(soFar))) {
					if (match) {
						// Don't consume trailing commas as valid
						soFar = soFar.slice(match[0].length) || soFar;
					}
					groups.push(tokens = []);
				}

				matched = false;

				// Combinators
				if (match = rcombinators.exec(soFar)) {
					matched = match.shift();
					tokens.push({
						value: matched,
						// Cast descendant combinators to space
						type: match[0].replace(rtrim, " ")
					});
					soFar = soFar.slice(matched.length);
				}

				// Filters
				for (type in Expr.filter) {
					if ((match = matchExpr[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {
						matched = match.shift();
						tokens.push({
							value: matched,
							type: type,
							matches: match
						});
						soFar = soFar.slice(matched.length);
					}
				}

				if (!matched) {
					break;
				}
			}

			// Return the length of the invalid excess
			// if we're just parsing
			// Otherwise, throw an error or return tokens
			return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) :
			// Cache the tokens
			tokenCache(selector, groups).slice(0);
		};

		function toSelector(tokens) {
			var i = 0,
			    len = tokens.length,
			    selector = "";
			for (; i < len; i++) {
				selector += tokens[i].value;
			}
			return selector;
		}

		function addCombinator(matcher, combinator, base) {
			var dir = combinator.dir,
			    checkNonElements = base && dir === "parentNode",
			    doneName = done++;

			return combinator.first ?
			// Check against closest ancestor/preceding element
			function (elem, context, xml) {
				while (elem = elem[dir]) {
					if (elem.nodeType === 1 || checkNonElements) {
						return matcher(elem, context, xml);
					}
				}
			} :

			// Check against all ancestor/preceding elements
			function (elem, context, xml) {
				var oldCache,
				    uniqueCache,
				    outerCache,
				    newCache = [dirruns, doneName];

				// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching
				if (xml) {
					while (elem = elem[dir]) {
						if (elem.nodeType === 1 || checkNonElements) {
							if (matcher(elem, context, xml)) {
								return true;
							}
						}
					}
				} else {
					while (elem = elem[dir]) {
						if (elem.nodeType === 1 || checkNonElements) {
							outerCache = elem[expando] || (elem[expando] = {});

							// Support: IE <9 only
							// Defend against cloned attroperties (jQuery gh-1709)
							uniqueCache = outerCache[elem.uniqueID] || (outerCache[elem.uniqueID] = {});

							if ((oldCache = uniqueCache[dir]) && oldCache[0] === dirruns && oldCache[1] === doneName) {

								// Assign to newCache so results back-propagate to previous elements
								return newCache[2] = oldCache[2];
							} else {
								// Reuse newcache so results back-propagate to previous elements
								uniqueCache[dir] = newCache;

								// A match means we're done; a fail means we have to keep checking
								if (newCache[2] = matcher(elem, context, xml)) {
									return true;
								}
							}
						}
					}
				}
			};
		}

		function elementMatcher(matchers) {
			return matchers.length > 1 ? function (elem, context, xml) {
				var i = matchers.length;
				while (i--) {
					if (!matchers[i](elem, context, xml)) {
						return false;
					}
				}
				return true;
			} : matchers[0];
		}

		function multipleContexts(selector, contexts, results) {
			var i = 0,
			    len = contexts.length;
			for (; i < len; i++) {
				Sizzle(selector, contexts[i], results);
			}
			return results;
		}

		function condense(unmatched, map, filter, context, xml) {
			var elem,
			    newUnmatched = [],
			    i = 0,
			    len = unmatched.length,
			    mapped = map != null;

			for (; i < len; i++) {
				if (elem = unmatched[i]) {
					if (!filter || filter(elem, context, xml)) {
						newUnmatched.push(elem);
						if (mapped) {
							map.push(i);
						}
					}
				}
			}

			return newUnmatched;
		}

		function setMatcher(preFilter, selector, matcher, postFilter, postFinder, postSelector) {
			if (postFilter && !postFilter[expando]) {
				postFilter = setMatcher(postFilter);
			}
			if (postFinder && !postFinder[expando]) {
				postFinder = setMatcher(postFinder, postSelector);
			}
			return markFunction(function (seed, results, context, xml) {
				var temp,
				    i,
				    elem,
				    preMap = [],
				    postMap = [],
				    preexisting = results.length,


				// Get initial elements from seed or context
				elems = seed || multipleContexts(selector || "*", context.nodeType ? [context] : context, []),


				// Prefilter to get matcher input, preserving a map for seed-results synchronization
				matcherIn = preFilter && (seed || !selector) ? condense(elems, preMap, preFilter, context, xml) : elems,
				    matcherOut = matcher ?
				// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,
				postFinder || (seed ? preFilter : preexisting || postFilter) ?

				// ...intermediate processing is necessary
				[] :

				// ...otherwise use results directly
				results : matcherIn;

				// Find primary matches
				if (matcher) {
					matcher(matcherIn, matcherOut, context, xml);
				}

				// Apply postFilter
				if (postFilter) {
					temp = condense(matcherOut, postMap);
					postFilter(temp, [], context, xml);

					// Un-match failing elements by moving them back to matcherIn
					i = temp.length;
					while (i--) {
						if (elem = temp[i]) {
							matcherOut[postMap[i]] = !(matcherIn[postMap[i]] = elem);
						}
					}
				}

				if (seed) {
					if (postFinder || preFilter) {
						if (postFinder) {
							// Get the final matcherOut by condensing this intermediate into postFinder contexts
							temp = [];
							i = matcherOut.length;
							while (i--) {
								if (elem = matcherOut[i]) {
									// Restore matcherIn since elem is not yet a final match
									temp.push(matcherIn[i] = elem);
								}
							}
							postFinder(null, matcherOut = [], temp, xml);
						}

						// Move matched elements from seed to results to keep them synchronized
						i = matcherOut.length;
						while (i--) {
							if ((elem = matcherOut[i]) && (temp = postFinder ? indexOf(seed, elem) : preMap[i]) > -1) {

								seed[temp] = !(results[temp] = elem);
							}
						}
					}

					// Add elements to results, through postFinder if defined
				} else {
					matcherOut = condense(matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut);
					if (postFinder) {
						postFinder(null, results, matcherOut, xml);
					} else {
						push.apply(results, matcherOut);
					}
				}
			});
		}

		function matcherFromTokens(tokens) {
			var checkContext,
			    matcher,
			    j,
			    len = tokens.length,
			    leadingRelative = Expr.relative[tokens[0].type],
			    implicitRelative = leadingRelative || Expr.relative[" "],
			    i = leadingRelative ? 1 : 0,


			// The foundational matcher ensures that elements are reachable from top-level context(s)
			matchContext = addCombinator(function (elem) {
				return elem === checkContext;
			}, implicitRelative, true),
			    matchAnyContext = addCombinator(function (elem) {
				return indexOf(checkContext, elem) > -1;
			}, implicitRelative, true),
			    matchers = [function (elem, context, xml) {
				var ret = !leadingRelative && (xml || context !== outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml));
				// Avoid hanging onto element (issue #299)
				checkContext = null;
				return ret;
			}];

			for (; i < len; i++) {
				if (matcher = Expr.relative[tokens[i].type]) {
					matchers = [addCombinator(elementMatcher(matchers), matcher)];
				} else {
					matcher = Expr.filter[tokens[i].type].apply(null, tokens[i].matches);

					// Return special upon seeing a positional matcher
					if (matcher[expando]) {
						// Find the next relative operator (if any) for proper handling
						j = ++i;
						for (; j < len; j++) {
							if (Expr.relative[tokens[j].type]) {
								break;
							}
						}
						return setMatcher(i > 1 && elementMatcher(matchers), i > 1 && toSelector(
						// If the preceding token was a descendant combinator, insert an implicit any-element `*`
						tokens.slice(0, i - 1).concat({ value: tokens[i - 2].type === " " ? "*" : "" })).replace(rtrim, "$1"), matcher, i < j && matcherFromTokens(tokens.slice(i, j)), j < len && matcherFromTokens(tokens = tokens.slice(j)), j < len && toSelector(tokens));
					}
					matchers.push(matcher);
				}
			}

			return elementMatcher(matchers);
		}

		function matcherFromGroupMatchers(elementMatchers, setMatchers) {
			var bySet = setMatchers.length > 0,
			    byElement = elementMatchers.length > 0,
			    superMatcher = function superMatcher(seed, context, xml, results, outermost) {
				var elem,
				    j,
				    matcher,
				    matchedCount = 0,
				    i = "0",
				    unmatched = seed && [],
				    setMatched = [],
				    contextBackup = outermostContext,

				// We must always have either seed elements or outermost context
				elems = seed || byElement && Expr.find["TAG"]("*", outermost),

				// Use integer dirruns iff this is the outermost matcher
				dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1,
				    len = elems.length;

				if (outermost) {
					outermostContext = context === document || context || outermost;
				}

				// Add elements passing elementMatchers directly to results
				// Support: IE<9, Safari
				// Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id
				for (; i !== len && (elem = elems[i]) != null; i++) {
					if (byElement && elem) {
						j = 0;
						if (!context && elem.ownerDocument !== document) {
							setDocument(elem);
							xml = !documentIsHTML;
						}
						while (matcher = elementMatchers[j++]) {
							if (matcher(elem, context || document, xml)) {
								results.push(elem);
								break;
							}
						}
						if (outermost) {
							dirruns = dirrunsUnique;
						}
					}

					// Track unmatched elements for set filters
					if (bySet) {
						// They will have gone through all possible matchers
						if (elem = !matcher && elem) {
							matchedCount--;
						}

						// Lengthen the array for every element, matched or not
						if (seed) {
							unmatched.push(elem);
						}
					}
				}

				// `i` is now the count of elements visited above, and adding it to `matchedCount`
				// makes the latter nonnegative.
				matchedCount += i;

				// Apply set filters to unmatched elements
				// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
				// equals `i`), unless we didn't visit _any_ elements in the above loop because we have
				// no element matchers and no seed.
				// Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
				// case, which will result in a "00" `matchedCount` that differs from `i` but is also
				// numerically zero.
				if (bySet && i !== matchedCount) {
					j = 0;
					while (matcher = setMatchers[j++]) {
						matcher(unmatched, setMatched, context, xml);
					}

					if (seed) {
						// Reintegrate element matches to eliminate the need for sorting
						if (matchedCount > 0) {
							while (i--) {
								if (!(unmatched[i] || setMatched[i])) {
									setMatched[i] = pop.call(results);
								}
							}
						}

						// Discard index placeholder values to get only actual matches
						setMatched = condense(setMatched);
					}

					// Add matches to results
					push.apply(results, setMatched);

					// Seedless set matches succeeding multiple successful matchers stipulate sorting
					if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {

						Sizzle.uniqueSort(results);
					}
				}

				// Override manipulation of globals by nested matchers
				if (outermost) {
					dirruns = dirrunsUnique;
					outermostContext = contextBackup;
				}

				return unmatched;
			};

			return bySet ? markFunction(superMatcher) : superMatcher;
		}

		compile = Sizzle.compile = function (selector, match /* Internal Use Only */) {
			var i,
			    setMatchers = [],
			    elementMatchers = [],
			    cached = compilerCache[selector + " "];

			if (!cached) {
				// Generate a function of recursive functions that can be used to check each element
				if (!match) {
					match = tokenize(selector);
				}
				i = match.length;
				while (i--) {
					cached = matcherFromTokens(match[i]);
					if (cached[expando]) {
						setMatchers.push(cached);
					} else {
						elementMatchers.push(cached);
					}
				}

				// Cache the compiled function
				cached = compilerCache(selector, matcherFromGroupMatchers(elementMatchers, setMatchers));

				// Save selector and tokenization
				cached.selector = selector;
			}
			return cached;
		};

		/**
   * A low-level selection function that works with Sizzle's compiled
   *  selector functions
   * @param {String|Function} selector A selector or a pre-compiled
   *  selector function built with Sizzle.compile
   * @param {Element} context
   * @param {Array} [results]
   * @param {Array} [seed] A set of elements to match against
   */
		select = Sizzle.select = function (selector, context, results, seed) {
			var i,
			    tokens,
			    token,
			    type,
			    find,
			    compiled = typeof selector === "function" && selector,
			    match = !seed && tokenize(selector = compiled.selector || selector);

			results = results || [];

			// Try to minimize operations if there is only one selector in the list and no seed
			// (the latter of which guarantees us context)
			if (match.length === 1) {

				// Reduce context if the leading compound selector is an ID
				tokens = match[0] = match[0].slice(0);
				if (tokens.length > 2 && (token = tokens[0]).type === "ID" && support.getById && context.nodeType === 9 && documentIsHTML && Expr.relative[tokens[1].type]) {

					context = (Expr.find["ID"](token.matches[0].replace(runescape, funescape), context) || [])[0];
					if (!context) {
						return results;

						// Precompiled matchers will still verify ancestry, so step up a level
					} else if (compiled) {
						context = context.parentNode;
					}

					selector = selector.slice(tokens.shift().value.length);
				}

				// Fetch a seed set for right-to-left matching
				i = matchExpr["needsContext"].test(selector) ? 0 : tokens.length;
				while (i--) {
					token = tokens[i];

					// Abort if we hit a combinator
					if (Expr.relative[type = token.type]) {
						break;
					}
					if (find = Expr.find[type]) {
						// Search, expanding context for leading sibling combinators
						if (seed = find(token.matches[0].replace(runescape, funescape), rsibling.test(tokens[0].type) && testContext(context.parentNode) || context)) {

							// If seed is empty or no tokens remain, we can return early
							tokens.splice(i, 1);
							selector = seed.length && toSelector(tokens);
							if (!selector) {
								push.apply(results, seed);
								return results;
							}

							break;
						}
					}
				}
			}

			// Compile and execute a filtering function if one is not provided
			// Provide `match` to avoid retokenization if we modified the selector above
			(compiled || compile(selector, match))(seed, context, !documentIsHTML, results, !context || rsibling.test(selector) && testContext(context.parentNode) || context);
			return results;
		};

		// One-time assignments

		// Sort stability
		support.sortStable = expando.split("").sort(sortOrder).join("") === expando;

		// Support: Chrome 14-35+
		// Always assume duplicates if they aren't passed to the comparison function
		support.detectDuplicates = !!hasDuplicate;

		// Initialize against the default document
		setDocument();

		// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
		// Detached nodes confoundingly follow *each other*
		support.sortDetached = assert(function (div1) {
			// Should return 1, but returns 4 (following)
			return div1.compareDocumentPosition(document.createElement("div")) & 1;
		});

		// Support: IE<8
		// Prevent attribute/property "interpolation"
		// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
		if (!assert(function (div) {
			div.innerHTML = "<a href='#'></a>";
			return div.firstChild.getAttribute("href") === "#";
		})) {
			addHandle("type|href|height|width", function (elem, name, isXML) {
				if (!isXML) {
					return elem.getAttribute(name, name.toLowerCase() === "type" ? 1 : 2);
				}
			});
		}

		// Support: IE<9
		// Use defaultValue in place of getAttribute("value")
		if (!support.attributes || !assert(function (div) {
			div.innerHTML = "<input/>";
			div.firstChild.setAttribute("value", "");
			return div.firstChild.getAttribute("value") === "";
		})) {
			addHandle("value", function (elem, name, isXML) {
				if (!isXML && elem.nodeName.toLowerCase() === "input") {
					return elem.defaultValue;
				}
			});
		}

		// Support: IE<9
		// Use getAttributeNode to fetch booleans when getAttribute lies
		if (!assert(function (div) {
			return div.getAttribute("disabled") == null;
		})) {
			addHandle(booleans, function (elem, name, isXML) {
				var val;
				if (!isXML) {
					return elem[name] === true ? name.toLowerCase() : (val = elem.getAttributeNode(name)) && val.specified ? val.value : null;
				}
			});
		}

		return Sizzle;
	}(window);

	jQuery.find = Sizzle;
	jQuery.expr = Sizzle.selectors;
	jQuery.expr[":"] = jQuery.expr.pseudos;
	jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
	jQuery.text = Sizzle.getText;
	jQuery.isXMLDoc = Sizzle.isXML;
	jQuery.contains = Sizzle.contains;

	var dir = function dir(elem, _dir, until) {
		var matched = [],
		    truncate = until !== undefined;

		while ((elem = elem[_dir]) && elem.nodeType !== 9) {
			if (elem.nodeType === 1) {
				if (truncate && jQuery(elem).is(until)) {
					break;
				}
				matched.push(elem);
			}
		}
		return matched;
	};

	var _siblings = function _siblings(n, elem) {
		var matched = [];

		for (; n; n = n.nextSibling) {
			if (n.nodeType === 1 && n !== elem) {
				matched.push(n);
			}
		}

		return matched;
	};

	var rneedsContext = jQuery.expr.match.needsContext;

	var rsingleTag = /^<([\w-]+)\s*\/?>(?:<\/\1>|)$/;

	var risSimple = /^.[^:#\[\.,]*$/;

	// Implement the identical functionality for filter and not
	function winnow(elements, qualifier, not) {
		if (jQuery.isFunction(qualifier)) {
			return jQuery.grep(elements, function (elem, i) {
				/* jshint -W018 */
				return !!qualifier.call(elem, i, elem) !== not;
			});
		}

		if (qualifier.nodeType) {
			return jQuery.grep(elements, function (elem) {
				return elem === qualifier !== not;
			});
		}

		if (typeof qualifier === "string") {
			if (risSimple.test(qualifier)) {
				return jQuery.filter(qualifier, elements, not);
			}

			qualifier = jQuery.filter(qualifier, elements);
		}

		return jQuery.grep(elements, function (elem) {
			return indexOf.call(qualifier, elem) > -1 !== not;
		});
	}

	jQuery.filter = function (expr, elems, not) {
		var elem = elems[0];

		if (not) {
			expr = ":not(" + expr + ")";
		}

		return elems.length === 1 && elem.nodeType === 1 ? jQuery.find.matchesSelector(elem, expr) ? [elem] : [] : jQuery.find.matches(expr, jQuery.grep(elems, function (elem) {
			return elem.nodeType === 1;
		}));
	};

	jQuery.fn.extend({
		find: function find(selector) {
			var i,
			    len = this.length,
			    ret = [],
			    self = this;

			if (typeof selector !== "string") {
				return this.pushStack(jQuery(selector).filter(function () {
					for (i = 0; i < len; i++) {
						if (jQuery.contains(self[i], this)) {
							return true;
						}
					}
				}));
			}

			for (i = 0; i < len; i++) {
				jQuery.find(selector, self[i], ret);
			}

			// Needed because $( selector, context ) becomes $( context ).find( selector )
			ret = this.pushStack(len > 1 ? jQuery.unique(ret) : ret);
			ret.selector = this.selector ? this.selector + " " + selector : selector;
			return ret;
		},
		filter: function filter(selector) {
			return this.pushStack(winnow(this, selector || [], false));
		},
		not: function not(selector) {
			return this.pushStack(winnow(this, selector || [], true));
		},
		is: function is(selector) {
			return !!winnow(this,

			// If this is a positional/relative selector, check membership in the returned set
			// so $("p:first").is("p:last") won't return true for a doc with two "p".
			typeof selector === "string" && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false).length;
		}
	});

	// Initialize a jQuery object


	// A central reference to the root jQuery(document)
	var rootjQuery,


	// A simple way to check for HTML strings
	// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
	// Strict HTML recognition (#11290: must start with <)
	rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,
	    init = jQuery.fn.init = function (selector, context, root) {
		var match, elem;

		// HANDLE: $(""), $(null), $(undefined), $(false)
		if (!selector) {
			return this;
		}

		// Method init() accepts an alternate rootjQuery
		// so migrate can support jQuery.sub (gh-2101)
		root = root || rootjQuery;

		// Handle HTML strings
		if (typeof selector === "string") {
			if (selector[0] === "<" && selector[selector.length - 1] === ">" && selector.length >= 3) {

				// Assume that strings that start and end with <> are HTML and skip the regex check
				match = [null, selector, null];
			} else {
				match = rquickExpr.exec(selector);
			}

			// Match html or make sure no context is specified for #id
			if (match && (match[1] || !context)) {

				// HANDLE: $(html) -> $(array)
				if (match[1]) {
					context = context instanceof jQuery ? context[0] : context;

					// Option to run scripts is true for back-compat
					// Intentionally let the error be thrown if parseHTML is not present
					jQuery.merge(this, jQuery.parseHTML(match[1], context && context.nodeType ? context.ownerDocument || context : document, true));

					// HANDLE: $(html, props)
					if (rsingleTag.test(match[1]) && jQuery.isPlainObject(context)) {
						for (match in context) {

							// Properties of context are called as methods if possible
							if (jQuery.isFunction(this[match])) {
								this[match](context[match]);

								// ...and otherwise set as attributes
							} else {
								this.attr(match, context[match]);
							}
						}
					}

					return this;

					// HANDLE: $(#id)
				} else {
					elem = document.getElementById(match[2]);

					// Support: Blackberry 4.6
					// gEBID returns nodes no longer in the document (#6963)
					if (elem && elem.parentNode) {

						// Inject the element directly into the jQuery object
						this.length = 1;
						this[0] = elem;
					}

					this.context = document;
					this.selector = selector;
					return this;
				}

				// HANDLE: $(expr, $(...))
			} else if (!context || context.jquery) {
				return (context || root).find(selector);

				// HANDLE: $(expr, context)
				// (which is just equivalent to: $(context).find(expr)
			} else {
				return this.constructor(context).find(selector);
			}

			// HANDLE: $(DOMElement)
		} else if (selector.nodeType) {
			this.context = this[0] = selector;
			this.length = 1;
			return this;

			// HANDLE: $(function)
			// Shortcut for document ready
		} else if (jQuery.isFunction(selector)) {
			return root.ready !== undefined ? root.ready(selector) :

			// Execute immediately if ready is not present
			selector(jQuery);
		}

		if (selector.selector !== undefined) {
			this.selector = selector.selector;
			this.context = selector.context;
		}

		return jQuery.makeArray(selector, this);
	};

	// Give the init function the jQuery prototype for later instantiation
	init.prototype = jQuery.fn;

	// Initialize central reference
	rootjQuery = jQuery(document);

	var rparentsprev = /^(?:parents|prev(?:Until|All))/,


	// Methods guaranteed to produce a unique set when starting from a unique set
	guaranteedUnique = {
		children: true,
		contents: true,
		next: true,
		prev: true
	};

	jQuery.fn.extend({
		has: function has(target) {
			var targets = jQuery(target, this),
			    l = targets.length;

			return this.filter(function () {
				var i = 0;
				for (; i < l; i++) {
					if (jQuery.contains(this, targets[i])) {
						return true;
					}
				}
			});
		},

		closest: function closest(selectors, context) {
			var cur,
			    i = 0,
			    l = this.length,
			    matched = [],
			    pos = rneedsContext.test(selectors) || typeof selectors !== "string" ? jQuery(selectors, context || this.context) : 0;

			for (; i < l; i++) {
				for (cur = this[i]; cur && cur !== context; cur = cur.parentNode) {

					// Always skip document fragments
					if (cur.nodeType < 11 && (pos ? pos.index(cur) > -1 :

					// Don't pass non-elements to Sizzle
					cur.nodeType === 1 && jQuery.find.matchesSelector(cur, selectors))) {

						matched.push(cur);
						break;
					}
				}
			}

			return this.pushStack(matched.length > 1 ? jQuery.uniqueSort(matched) : matched);
		},

		// Determine the position of an element within the set
		index: function index(elem) {

			// No argument, return index in parent
			if (!elem) {
				return this[0] && this[0].parentNode ? this.first().prevAll().length : -1;
			}

			// Index in selector
			if (typeof elem === "string") {
				return indexOf.call(jQuery(elem), this[0]);
			}

			// Locate the position of the desired element
			return indexOf.call(this,

			// If it receives a jQuery object, the first element is used
			elem.jquery ? elem[0] : elem);
		},

		add: function add(selector, context) {
			return this.pushStack(jQuery.uniqueSort(jQuery.merge(this.get(), jQuery(selector, context))));
		},

		addBack: function addBack(selector) {
			return this.add(selector == null ? this.prevObject : this.prevObject.filter(selector));
		}
	});

	function sibling(cur, dir) {
		while ((cur = cur[dir]) && cur.nodeType !== 1) {}
		return cur;
	}

	jQuery.each({
		parent: function parent(elem) {
			var parent = elem.parentNode;
			return parent && parent.nodeType !== 11 ? parent : null;
		},
		parents: function parents(elem) {
			return dir(elem, "parentNode");
		},
		parentsUntil: function parentsUntil(elem, i, until) {
			return dir(elem, "parentNode", until);
		},
		next: function next(elem) {
			return sibling(elem, "nextSibling");
		},
		prev: function prev(elem) {
			return sibling(elem, "previousSibling");
		},
		nextAll: function nextAll(elem) {
			return dir(elem, "nextSibling");
		},
		prevAll: function prevAll(elem) {
			return dir(elem, "previousSibling");
		},
		nextUntil: function nextUntil(elem, i, until) {
			return dir(elem, "nextSibling", until);
		},
		prevUntil: function prevUntil(elem, i, until) {
			return dir(elem, "previousSibling", until);
		},
		siblings: function siblings(elem) {
			return _siblings((elem.parentNode || {}).firstChild, elem);
		},
		children: function children(elem) {
			return _siblings(elem.firstChild);
		},
		contents: function contents(elem) {
			return elem.contentDocument || jQuery.merge([], elem.childNodes);
		}
	}, function (name, fn) {
		jQuery.fn[name] = function (until, selector) {
			var matched = jQuery.map(this, fn, until);

			if (name.slice(-5) !== "Until") {
				selector = until;
			}

			if (selector && typeof selector === "string") {
				matched = jQuery.filter(selector, matched);
			}

			if (this.length > 1) {

				// Remove duplicates
				if (!guaranteedUnique[name]) {
					jQuery.uniqueSort(matched);
				}

				// Reverse order for parents* and prev-derivatives
				if (rparentsprev.test(name)) {
					matched.reverse();
				}
			}

			return this.pushStack(matched);
		};
	});
	var rnotwhite = /\S+/g;

	// Convert String-formatted options into Object-formatted ones
	function createOptions(options) {
		var object = {};
		jQuery.each(options.match(rnotwhite) || [], function (_, flag) {
			object[flag] = true;
		});
		return object;
	}

	/*
  * Create a callback list using the following parameters:
  *
  *	options: an optional list of space-separated options that will change how
  *			the callback list behaves or a more traditional option object
  *
  * By default a callback list will act like an event callback list and can be
  * "fired" multiple times.
  *
  * Possible options:
  *
  *	once:			will ensure the callback list can only be fired once (like a Deferred)
  *
  *	memory:			will keep track of previous values and will call any callback added
  *					after the list has been fired right away with the latest "memorized"
  *					values (like a Deferred)
  *
  *	unique:			will ensure a callback can only be added once (no duplicate in the list)
  *
  *	stopOnFalse:	interrupt callings when a callback returns false
  *
  */
	jQuery.Callbacks = function (options) {

		// Convert options from String-formatted to Object-formatted if needed
		// (we check in cache first)
		options = typeof options === "string" ? createOptions(options) : jQuery.extend({}, options);

		var // Flag to know if list is currently firing
		firing,


		// Last fire value for non-forgettable lists
		memory,


		// Flag to know if list was already fired
		_fired,


		// Flag to prevent firing
		_locked,


		// Actual callback list
		list = [],


		// Queue of execution data for repeatable lists
		queue = [],


		// Index of currently firing callback (modified by add/remove as needed)
		firingIndex = -1,


		// Fire callbacks
		fire = function fire() {

			// Enforce single-firing
			_locked = options.once;

			// Execute callbacks for all pending executions,
			// respecting firingIndex overrides and runtime changes
			_fired = firing = true;
			for (; queue.length; firingIndex = -1) {
				memory = queue.shift();
				while (++firingIndex < list.length) {

					// Run callback and check for early termination
					if (list[firingIndex].apply(memory[0], memory[1]) === false && options.stopOnFalse) {

						// Jump to end and forget the data so .add doesn't re-fire
						firingIndex = list.length;
						memory = false;
					}
				}
			}

			// Forget the data if we're done with it
			if (!options.memory) {
				memory = false;
			}

			firing = false;

			// Clean up if we're done firing for good
			if (_locked) {

				// Keep an empty list if we have data for future add calls
				if (memory) {
					list = [];

					// Otherwise, this object is spent
				} else {
					list = "";
				}
			}
		},


		// Actual Callbacks object
		self = {

			// Add a callback or a collection of callbacks to the list
			add: function add() {
				if (list) {

					// If we have memory from a past run, we should fire after adding
					if (memory && !firing) {
						firingIndex = list.length - 1;
						queue.push(memory);
					}

					(function add(args) {
						jQuery.each(args, function (_, arg) {
							if (jQuery.isFunction(arg)) {
								if (!options.unique || !self.has(arg)) {
									list.push(arg);
								}
							} else if (arg && arg.length && jQuery.type(arg) !== "string") {

								// Inspect recursively
								add(arg);
							}
						});
					})(arguments);

					if (memory && !firing) {
						fire();
					}
				}
				return this;
			},

			// Remove a callback from the list
			remove: function remove() {
				jQuery.each(arguments, function (_, arg) {
					var index;
					while ((index = jQuery.inArray(arg, list, index)) > -1) {
						list.splice(index, 1);

						// Handle firing indexes
						if (index <= firingIndex) {
							firingIndex--;
						}
					}
				});
				return this;
			},

			// Check if a given callback is in the list.
			// If no argument is given, return whether or not list has callbacks attached.
			has: function has(fn) {
				return fn ? jQuery.inArray(fn, list) > -1 : list.length > 0;
			},

			// Remove all callbacks from the list
			empty: function empty() {
				if (list) {
					list = [];
				}
				return this;
			},

			// Disable .fire and .add
			// Abort any current/pending executions
			// Clear all callbacks and values
			disable: function disable() {
				_locked = queue = [];
				list = memory = "";
				return this;
			},
			disabled: function disabled() {
				return !list;
			},

			// Disable .fire
			// Also disable .add unless we have memory (since it would have no effect)
			// Abort any pending executions
			lock: function lock() {
				_locked = queue = [];
				if (!memory) {
					list = memory = "";
				}
				return this;
			},
			locked: function locked() {
				return !!_locked;
			},

			// Call all callbacks with the given context and arguments
			fireWith: function fireWith(context, args) {
				if (!_locked) {
					args = args || [];
					args = [context, args.slice ? args.slice() : args];
					queue.push(args);
					if (!firing) {
						fire();
					}
				}
				return this;
			},

			// Call all the callbacks with the given arguments
			fire: function fire() {
				self.fireWith(this, arguments);
				return this;
			},

			// To know if the callbacks have already been called at least once
			fired: function fired() {
				return !!_fired;
			}
		};

		return self;
	};

	jQuery.extend({

		Deferred: function Deferred(func) {
			var tuples = [

			// action, add listener, listener list, final state
			["resolve", "done", jQuery.Callbacks("once memory"), "resolved"], ["reject", "fail", jQuery.Callbacks("once memory"), "rejected"], ["notify", "progress", jQuery.Callbacks("memory")]],
			    _state = "pending",
			    _promise = {
				state: function state() {
					return _state;
				},
				always: function always() {
					deferred.done(arguments).fail(arguments);
					return this;
				},
				then: function then() /* fnDone, fnFail, fnProgress */{
					var fns = arguments;
					return jQuery.Deferred(function (newDefer) {
						jQuery.each(tuples, function (i, tuple) {
							var fn = jQuery.isFunction(fns[i]) && fns[i];

							// deferred[ done | fail | progress ] for forwarding actions to newDefer
							deferred[tuple[1]](function () {
								var returned = fn && fn.apply(this, arguments);
								if (returned && jQuery.isFunction(returned.promise)) {
									returned.promise().progress(newDefer.notify).done(newDefer.resolve).fail(newDefer.reject);
								} else {
									newDefer[tuple[0] + "With"](this === _promise ? newDefer.promise() : this, fn ? [returned] : arguments);
								}
							});
						});
						fns = null;
					}).promise();
				},

				// Get a promise for this deferred
				// If obj is provided, the promise aspect is added to the object
				promise: function promise(obj) {
					return obj != null ? jQuery.extend(obj, _promise) : _promise;
				}
			},
			    deferred = {};

			// Keep pipe for back-compat
			_promise.pipe = _promise.then;

			// Add list-specific methods
			jQuery.each(tuples, function (i, tuple) {
				var list = tuple[2],
				    stateString = tuple[3];

				// promise[ done | fail | progress ] = list.add
				_promise[tuple[1]] = list.add;

				// Handle state
				if (stateString) {
					list.add(function () {

						// state = [ resolved | rejected ]
						_state = stateString;

						// [ reject_list | resolve_list ].disable; progress_list.lock
					}, tuples[i ^ 1][2].disable, tuples[2][2].lock);
				}

				// deferred[ resolve | reject | notify ]
				deferred[tuple[0]] = function () {
					deferred[tuple[0] + "With"](this === deferred ? _promise : this, arguments);
					return this;
				};
				deferred[tuple[0] + "With"] = list.fireWith;
			});

			// Make the deferred a promise
			_promise.promise(deferred);

			// Call given func if any
			if (func) {
				func.call(deferred, deferred);
			}

			// All done!
			return deferred;
		},

		// Deferred helper
		when: function when(subordinate /* , ..., subordinateN */) {
			var i = 0,
			    resolveValues = _slice.call(arguments),
			    length = resolveValues.length,


			// the count of uncompleted subordinates
			remaining = length !== 1 || subordinate && jQuery.isFunction(subordinate.promise) ? length : 0,


			// the master Deferred.
			// If resolveValues consist of only a single Deferred, just use that.
			deferred = remaining === 1 ? subordinate : jQuery.Deferred(),


			// Update function for both resolve and progress values
			updateFunc = function updateFunc(i, contexts, values) {
				return function (value) {
					contexts[i] = this;
					values[i] = arguments.length > 1 ? _slice.call(arguments) : value;
					if (values === progressValues) {
						deferred.notifyWith(contexts, values);
					} else if (! --remaining) {
						deferred.resolveWith(contexts, values);
					}
				};
			},
			    progressValues,
			    progressContexts,
			    resolveContexts;

			// Add listeners to Deferred subordinates; treat others as resolved
			if (length > 1) {
				progressValues = new Array(length);
				progressContexts = new Array(length);
				resolveContexts = new Array(length);
				for (; i < length; i++) {
					if (resolveValues[i] && jQuery.isFunction(resolveValues[i].promise)) {
						resolveValues[i].promise().progress(updateFunc(i, progressContexts, progressValues)).done(updateFunc(i, resolveContexts, resolveValues)).fail(deferred.reject);
					} else {
						--remaining;
					}
				}
			}

			// If we're not waiting on anything, resolve the master
			if (!remaining) {
				deferred.resolveWith(resolveContexts, resolveValues);
			}

			return deferred.promise();
		}
	});

	// The deferred used on DOM ready
	var readyList;

	jQuery.fn.ready = function (fn) {

		// Add the callback
		jQuery.ready.promise().done(fn);

		return this;
	};

	jQuery.extend({

		// Is the DOM ready to be used? Set to true once it occurs.
		isReady: false,

		// A counter to track how many items to wait for before
		// the ready event fires. See #6781
		readyWait: 1,

		// Hold (or release) the ready event
		holdReady: function holdReady(hold) {
			if (hold) {
				jQuery.readyWait++;
			} else {
				jQuery.ready(true);
			}
		},

		// Handle when the DOM is ready
		ready: function ready(wait) {

			// Abort if there are pending holds or we're already ready
			if (wait === true ? --jQuery.readyWait : jQuery.isReady) {
				return;
			}

			// Remember that the DOM is ready
			jQuery.isReady = true;

			// If a normal DOM Ready event fired, decrement, and wait if need be
			if (wait !== true && --jQuery.readyWait > 0) {
				return;
			}

			// If there are functions bound, to execute
			readyList.resolveWith(document, [jQuery]);

			// Trigger any bound ready events
			if (jQuery.fn.triggerHandler) {
				jQuery(document).triggerHandler("ready");
				jQuery(document).off("ready");
			}
		}
	});

	/**
  * The ready event handler and self cleanup method
  */
	function completed() {
		document.removeEventListener("DOMContentLoaded", completed);
		window.removeEventListener("load", completed);
		jQuery.ready();
	}

	jQuery.ready.promise = function (obj) {
		if (!readyList) {

			readyList = jQuery.Deferred();

			// Catch cases where $(document).ready() is called
			// after the browser event has already occurred.
			// Support: IE9-10 only
			// Older IE sometimes signals "interactive" too soon
			if (document.readyState === "complete" || document.readyState !== "loading" && !document.documentElement.doScroll) {

				// Handle it asynchronously to allow scripts the opportunity to delay ready
				window.setTimeout(jQuery.ready);
			} else {

				// Use the handy event callback
				document.addEventListener("DOMContentLoaded", completed);

				// A fallback to window.onload, that will always work
				window.addEventListener("load", completed);
			}
		}
		return readyList.promise(obj);
	};

	// Kick off the DOM ready check even if the user does not
	jQuery.ready.promise();

	// Multifunctional method to get and set values of a collection
	// The value/s can optionally be executed if it's a function
	var access = function access(elems, fn, key, value, chainable, emptyGet, raw) {
		var i = 0,
		    len = elems.length,
		    bulk = key == null;

		// Sets many values
		if (jQuery.type(key) === "object") {
			chainable = true;
			for (i in key) {
				access(elems, fn, i, key[i], true, emptyGet, raw);
			}

			// Sets one value
		} else if (value !== undefined) {
			chainable = true;

			if (!jQuery.isFunction(value)) {
				raw = true;
			}

			if (bulk) {

				// Bulk operations run against the entire set
				if (raw) {
					fn.call(elems, value);
					fn = null;

					// ...except when executing function values
				} else {
					bulk = fn;
					fn = function fn(elem, key, value) {
						return bulk.call(jQuery(elem), value);
					};
				}
			}

			if (fn) {
				for (; i < len; i++) {
					fn(elems[i], key, raw ? value : value.call(elems[i], i, fn(elems[i], key)));
				}
			}
		}

		return chainable ? elems :

		// Gets
		bulk ? fn.call(elems) : len ? fn(elems[0], key) : emptyGet;
	};
	var acceptData = function acceptData(owner) {

		// Accepts only:
		//  - Node
		//    - Node.ELEMENT_NODE
		//    - Node.DOCUMENT_NODE
		//  - Object
		//    - Any
		/* jshint -W018 */
		return owner.nodeType === 1 || owner.nodeType === 9 || !+owner.nodeType;
	};

	function Data() {
		this.expando = jQuery.expando + Data.uid++;
	}

	Data.uid = 1;

	Data.prototype = {

		register: function register(owner, initial) {
			var value = initial || {};

			// If it is a node unlikely to be stringify-ed or looped over
			// use plain assignment
			if (owner.nodeType) {
				owner[this.expando] = value;

				// Otherwise secure it in a non-enumerable, non-writable property
				// configurability must be true to allow the property to be
				// deleted with the delete operator
			} else {
				Object.defineProperty(owner, this.expando, {
					value: value,
					writable: true,
					configurable: true
				});
			}
			return owner[this.expando];
		},
		cache: function cache(owner) {

			// We can accept data for non-element nodes in modern browsers,
			// but we should not, see #8335.
			// Always return an empty object.
			if (!acceptData(owner)) {
				return {};
			}

			// Check if the owner object already has a cache
			var value = owner[this.expando];

			// If not, create one
			if (!value) {
				value = {};

				// We can accept data for non-element nodes in modern browsers,
				// but we should not, see #8335.
				// Always return an empty object.
				if (acceptData(owner)) {

					// If it is a node unlikely to be stringify-ed or looped over
					// use plain assignment
					if (owner.nodeType) {
						owner[this.expando] = value;

						// Otherwise secure it in a non-enumerable property
						// configurable must be true to allow the property to be
						// deleted when data is removed
					} else {
						Object.defineProperty(owner, this.expando, {
							value: value,
							configurable: true
						});
					}
				}
			}

			return value;
		},
		set: function set(owner, data, value) {
			var prop,
			    cache = this.cache(owner);

			// Handle: [ owner, key, value ] args
			if (typeof data === "string") {
				cache[data] = value;

				// Handle: [ owner, { properties } ] args
			} else {

				// Copy the properties one-by-one to the cache object
				for (prop in data) {
					cache[prop] = data[prop];
				}
			}
			return cache;
		},
		get: function get(owner, key) {
			return key === undefined ? this.cache(owner) : owner[this.expando] && owner[this.expando][key];
		},
		access: function access(owner, key, value) {
			var stored;

			// In cases where either:
			//
			//   1. No key was specified
			//   2. A string key was specified, but no value provided
			//
			// Take the "read" path and allow the get method to determine
			// which value to return, respectively either:
			//
			//   1. The entire cache object
			//   2. The data stored at the key
			//
			if (key === undefined || key && typeof key === "string" && value === undefined) {

				stored = this.get(owner, key);

				return stored !== undefined ? stored : this.get(owner, jQuery.camelCase(key));
			}

			// When the key is not a string, or both a key and value
			// are specified, set or extend (existing objects) with either:
			//
			//   1. An object of properties
			//   2. A key and value
			//
			this.set(owner, key, value);

			// Since the "set" path can have two possible entry points
			// return the expected data based on which path was taken[*]
			return value !== undefined ? value : key;
		},
		remove: function remove(owner, key) {
			var i,
			    name,
			    camel,
			    cache = owner[this.expando];

			if (cache === undefined) {
				return;
			}

			if (key === undefined) {
				this.register(owner);
			} else {

				// Support array or space separated string of keys
				if (jQuery.isArray(key)) {

					// If "name" is an array of keys...
					// When data is initially created, via ("key", "val") signature,
					// keys will be converted to camelCase.
					// Since there is no way to tell _how_ a key was added, remove
					// both plain key and camelCase key. #12786
					// This will only penalize the array argument path.
					name = key.concat(key.map(jQuery.camelCase));
				} else {
					camel = jQuery.camelCase(key);

					// Try the string as a key before any manipulation
					if (key in cache) {
						name = [key, camel];
					} else {

						// If a key with the spaces exists, use it.
						// Otherwise, create an array by matching non-whitespace
						name = camel;
						name = name in cache ? [name] : name.match(rnotwhite) || [];
					}
				}

				i = name.length;

				while (i--) {
					delete cache[name[i]];
				}
			}

			// Remove the expando if there's no more data
			if (key === undefined || jQuery.isEmptyObject(cache)) {

				// Support: Chrome <= 35-45+
				// Webkit & Blink performance suffers when deleting properties
				// from DOM nodes, so set to undefined instead
				// https://code.google.com/p/chromium/issues/detail?id=378607
				if (owner.nodeType) {
					owner[this.expando] = undefined;
				} else {
					delete owner[this.expando];
				}
			}
		},
		hasData: function hasData(owner) {
			var cache = owner[this.expando];
			return cache !== undefined && !jQuery.isEmptyObject(cache);
		}
	};
	var dataPriv = new Data();

	var dataUser = new Data();

	//	Implementation Summary
	//
	//	1. Enforce API surface and semantic compatibility with 1.9.x branch
	//	2. Improve the module's maintainability by reducing the storage
	//		paths to a single mechanism.
	//	3. Use the same single mechanism to support "private" and "user" data.
	//	4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
	//	5. Avoid exposing implementation details on user objects (eg. expando properties)
	//	6. Provide a clear path for implementation upgrade to WeakMap in 2014

	var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
	    rmultiDash = /[A-Z]/g;

	function dataAttr(elem, key, data) {
		var name;

		// If nothing was found internally, try to fetch any
		// data from the HTML5 data-* attribute
		if (data === undefined && elem.nodeType === 1) {
			name = "data-" + key.replace(rmultiDash, "-$&").toLowerCase();
			data = elem.getAttribute(name);

			if (typeof data === "string") {
				try {
					data = data === "true" ? true : data === "false" ? false : data === "null" ? null :

					// Only convert to a number if it doesn't change the string
					+data + "" === data ? +data : rbrace.test(data) ? jQuery.parseJSON(data) : data;
				} catch (e) {}

				// Make sure we set the data so it isn't changed later
				dataUser.set(elem, key, data);
			} else {
				data = undefined;
			}
		}
		return data;
	}

	jQuery.extend({
		hasData: function hasData(elem) {
			return dataUser.hasData(elem) || dataPriv.hasData(elem);
		},

		data: function data(elem, name, _data) {
			return dataUser.access(elem, name, _data);
		},

		removeData: function removeData(elem, name) {
			dataUser.remove(elem, name);
		},

		// TODO: Now that all calls to _data and _removeData have been replaced
		// with direct calls to dataPriv methods, these can be deprecated.
		_data: function _data(elem, name, data) {
			return dataPriv.access(elem, name, data);
		},

		_removeData: function _removeData(elem, name) {
			dataPriv.remove(elem, name);
		}
	});

	jQuery.fn.extend({
		data: function data(key, value) {
			var i,
			    name,
			    data,
			    elem = this[0],
			    attrs = elem && elem.attributes;

			// Gets all values
			if (key === undefined) {
				if (this.length) {
					data = dataUser.get(elem);

					if (elem.nodeType === 1 && !dataPriv.get(elem, "hasDataAttrs")) {
						i = attrs.length;
						while (i--) {

							// Support: IE11+
							// The attrs elements can be null (#14894)
							if (attrs[i]) {
								name = attrs[i].name;
								if (name.indexOf("data-") === 0) {
									name = jQuery.camelCase(name.slice(5));
									dataAttr(elem, name, data[name]);
								}
							}
						}
						dataPriv.set(elem, "hasDataAttrs", true);
					}
				}

				return data;
			}

			// Sets multiple values
			if ((typeof key === "undefined" ? "undefined" : _typeof(key)) === "object") {
				return this.each(function () {
					dataUser.set(this, key);
				});
			}

			return access(this, function (value) {
				var data, camelKey;

				// The calling jQuery object (element matches) is not empty
				// (and therefore has an element appears at this[ 0 ]) and the
				// `value` parameter was not undefined. An empty jQuery object
				// will result in `undefined` for elem = this[ 0 ] which will
				// throw an exception if an attempt to read a data cache is made.
				if (elem && value === undefined) {

					// Attempt to get data from the cache
					// with the key as-is
					data = dataUser.get(elem, key) ||

					// Try to find dashed key if it exists (gh-2779)
					// This is for 2.2.x only
					dataUser.get(elem, key.replace(rmultiDash, "-$&").toLowerCase());

					if (data !== undefined) {
						return data;
					}

					camelKey = jQuery.camelCase(key);

					// Attempt to get data from the cache
					// with the key camelized
					data = dataUser.get(elem, camelKey);
					if (data !== undefined) {
						return data;
					}

					// Attempt to "discover" the data in
					// HTML5 custom data-* attrs
					data = dataAttr(elem, camelKey, undefined);
					if (data !== undefined) {
						return data;
					}

					// We tried really hard, but the data doesn't exist.
					return;
				}

				// Set the data...
				camelKey = jQuery.camelCase(key);
				this.each(function () {

					// First, attempt to store a copy or reference of any
					// data that might've been store with a camelCased key.
					var data = dataUser.get(this, camelKey);

					// For HTML5 data-* attribute interop, we have to
					// store property names with dashes in a camelCase form.
					// This might not apply to all properties...*
					dataUser.set(this, camelKey, value);

					// *... In the case of properties that might _actually_
					// have dashes, we need to also store a copy of that
					// unchanged property.
					if (key.indexOf("-") > -1 && data !== undefined) {
						dataUser.set(this, key, value);
					}
				});
			}, null, value, arguments.length > 1, null, true);
		},

		removeData: function removeData(key) {
			return this.each(function () {
				dataUser.remove(this, key);
			});
		}
	});

	jQuery.extend({
		queue: function queue(elem, type, data) {
			var queue;

			if (elem) {
				type = (type || "fx") + "queue";
				queue = dataPriv.get(elem, type);

				// Speed up dequeue by getting out quickly if this is just a lookup
				if (data) {
					if (!queue || jQuery.isArray(data)) {
						queue = dataPriv.access(elem, type, jQuery.makeArray(data));
					} else {
						queue.push(data);
					}
				}
				return queue || [];
			}
		},

		dequeue: function dequeue(elem, type) {
			type = type || "fx";

			var queue = jQuery.queue(elem, type),
			    startLength = queue.length,
			    fn = queue.shift(),
			    hooks = jQuery._queueHooks(elem, type),
			    next = function next() {
				jQuery.dequeue(elem, type);
			};

			// If the fx queue is dequeued, always remove the progress sentinel
			if (fn === "inprogress") {
				fn = queue.shift();
				startLength--;
			}

			if (fn) {

				// Add a progress sentinel to prevent the fx queue from being
				// automatically dequeued
				if (type === "fx") {
					queue.unshift("inprogress");
				}

				// Clear up the last queue stop function
				delete hooks.stop;
				fn.call(elem, next, hooks);
			}

			if (!startLength && hooks) {
				hooks.empty.fire();
			}
		},

		// Not public - generate a queueHooks object, or return the current one
		_queueHooks: function _queueHooks(elem, type) {
			var key = type + "queueHooks";
			return dataPriv.get(elem, key) || dataPriv.access(elem, key, {
				empty: jQuery.Callbacks("once memory").add(function () {
					dataPriv.remove(elem, [type + "queue", key]);
				})
			});
		}
	});

	jQuery.fn.extend({
		queue: function queue(type, data) {
			var setter = 2;

			if (typeof type !== "string") {
				data = type;
				type = "fx";
				setter--;
			}

			if (arguments.length < setter) {
				return jQuery.queue(this[0], type);
			}

			return data === undefined ? this : this.each(function () {
				var queue = jQuery.queue(this, type, data);

				// Ensure a hooks for this queue
				jQuery._queueHooks(this, type);

				if (type === "fx" && queue[0] !== "inprogress") {
					jQuery.dequeue(this, type);
				}
			});
		},
		dequeue: function dequeue(type) {
			return this.each(function () {
				jQuery.dequeue(this, type);
			});
		},
		clearQueue: function clearQueue(type) {
			return this.queue(type || "fx", []);
		},

		// Get a promise resolved when queues of a certain type
		// are emptied (fx is the type by default)
		promise: function promise(type, obj) {
			var tmp,
			    count = 1,
			    defer = jQuery.Deferred(),
			    elements = this,
			    i = this.length,
			    resolve = function resolve() {
				if (! --count) {
					defer.resolveWith(elements, [elements]);
				}
			};

			if (typeof type !== "string") {
				obj = type;
				type = undefined;
			}
			type = type || "fx";

			while (i--) {
				tmp = dataPriv.get(elements[i], type + "queueHooks");
				if (tmp && tmp.empty) {
					count++;
					tmp.empty.add(resolve);
				}
			}
			resolve();
			return defer.promise(obj);
		}
	});
	var pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source;

	var rcssNum = new RegExp("^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i");

	var cssExpand = ["Top", "Right", "Bottom", "Left"];

	var isHidden = function isHidden(elem, el) {

		// isHidden might be called from jQuery#filter function;
		// in that case, element will be second argument
		elem = el || elem;
		return jQuery.css(elem, "display") === "none" || !jQuery.contains(elem.ownerDocument, elem);
	};

	function adjustCSS(elem, prop, valueParts, tween) {
		var adjusted,
		    scale = 1,
		    maxIterations = 20,
		    currentValue = tween ? function () {
			return tween.cur();
		} : function () {
			return jQuery.css(elem, prop, "");
		},
		    initial = currentValue(),
		    unit = valueParts && valueParts[3] || (jQuery.cssNumber[prop] ? "" : "px"),


		// Starting value computation is required for potential unit mismatches
		initialInUnit = (jQuery.cssNumber[prop] || unit !== "px" && +initial) && rcssNum.exec(jQuery.css(elem, prop));

		if (initialInUnit && initialInUnit[3] !== unit) {

			// Trust units reported by jQuery.css
			unit = unit || initialInUnit[3];

			// Make sure we update the tween properties later on
			valueParts = valueParts || [];

			// Iteratively approximate from a nonzero starting point
			initialInUnit = +initial || 1;

			do {

				// If previous iteration zeroed out, double until we get *something*.
				// Use string for doubling so we don't accidentally see scale as unchanged below
				scale = scale || ".5";

				// Adjust and apply
				initialInUnit = initialInUnit / scale;
				jQuery.style(elem, prop, initialInUnit + unit);

				// Update scale, tolerating zero or NaN from tween.cur()
				// Break the loop if scale is unchanged or perfect, or if we've just had enough.
			} while (scale !== (scale = currentValue() / initial) && scale !== 1 && --maxIterations);
		}

		if (valueParts) {
			initialInUnit = +initialInUnit || +initial || 0;

			// Apply relative offset (+=/-=) if specified
			adjusted = valueParts[1] ? initialInUnit + (valueParts[1] + 1) * valueParts[2] : +valueParts[2];
			if (tween) {
				tween.unit = unit;
				tween.start = initialInUnit;
				tween.end = adjusted;
			}
		}
		return adjusted;
	}
	var rcheckableType = /^(?:checkbox|radio)$/i;

	var rtagName = /<([\w:-]+)/;

	var rscriptType = /^$|\/(?:java|ecma)script/i;

	// We have to close these tags to support XHTML (#13200)
	var wrapMap = {

		// Support: IE9
		option: [1, "<select multiple='multiple'>", "</select>"],

		// XHTML parsers do not magically insert elements in the
		// same way that tag soup parsers do. So we cannot shorten
		// this by omitting <tbody> or other required elements.
		thead: [1, "<table>", "</table>"],
		col: [2, "<table><colgroup>", "</colgroup></table>"],
		tr: [2, "<table><tbody>", "</tbody></table>"],
		td: [3, "<table><tbody><tr>", "</tr></tbody></table>"],

		_default: [0, "", ""]
	};

	// Support: IE9
	wrapMap.optgroup = wrapMap.option;

	wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
	wrapMap.th = wrapMap.td;

	function getAll(context, tag) {

		// Support: IE9-11+
		// Use typeof to avoid zero-argument method invocation on host objects (#15151)
		var ret = typeof context.getElementsByTagName !== "undefined" ? context.getElementsByTagName(tag || "*") : typeof context.querySelectorAll !== "undefined" ? context.querySelectorAll(tag || "*") : [];

		return tag === undefined || tag && jQuery.nodeName(context, tag) ? jQuery.merge([context], ret) : ret;
	}

	// Mark scripts as having already been evaluated
	function setGlobalEval(elems, refElements) {
		var i = 0,
		    l = elems.length;

		for (; i < l; i++) {
			dataPriv.set(elems[i], "globalEval", !refElements || dataPriv.get(refElements[i], "globalEval"));
		}
	}

	var rhtml = /<|&#?\w+;/;

	function buildFragment(elems, context, scripts, selection, ignored) {
		var elem,
		    tmp,
		    tag,
		    wrap,
		    contains,
		    j,
		    fragment = context.createDocumentFragment(),
		    nodes = [],
		    i = 0,
		    l = elems.length;

		for (; i < l; i++) {
			elem = elems[i];

			if (elem || elem === 0) {

				// Add nodes directly
				if (jQuery.type(elem) === "object") {

					// Support: Android<4.1, PhantomJS<2
					// push.apply(_, arraylike) throws on ancient WebKit
					jQuery.merge(nodes, elem.nodeType ? [elem] : elem);

					// Convert non-html into a text node
				} else if (!rhtml.test(elem)) {
					nodes.push(context.createTextNode(elem));

					// Convert html into DOM nodes
				} else {
					tmp = tmp || fragment.appendChild(context.createElement("div"));

					// Deserialize a standard representation
					tag = (rtagName.exec(elem) || ["", ""])[1].toLowerCase();
					wrap = wrapMap[tag] || wrapMap._default;
					tmp.innerHTML = wrap[1] + jQuery.htmlPrefilter(elem) + wrap[2];

					// Descend through wrappers to the right content
					j = wrap[0];
					while (j--) {
						tmp = tmp.lastChild;
					}

					// Support: Android<4.1, PhantomJS<2
					// push.apply(_, arraylike) throws on ancient WebKit
					jQuery.merge(nodes, tmp.childNodes);

					// Remember the top-level container
					tmp = fragment.firstChild;

					// Ensure the created nodes are orphaned (#12392)
					tmp.textContent = "";
				}
			}
		}

		// Remove wrapper from fragment
		fragment.textContent = "";

		i = 0;
		while (elem = nodes[i++]) {

			// Skip elements already in the context collection (trac-4087)
			if (selection && jQuery.inArray(elem, selection) > -1) {
				if (ignored) {
					ignored.push(elem);
				}
				continue;
			}

			contains = jQuery.contains(elem.ownerDocument, elem);

			// Append to fragment
			tmp = getAll(fragment.appendChild(elem), "script");

			// Preserve script evaluation history
			if (contains) {
				setGlobalEval(tmp);
			}

			// Capture executables
			if (scripts) {
				j = 0;
				while (elem = tmp[j++]) {
					if (rscriptType.test(elem.type || "")) {
						scripts.push(elem);
					}
				}
			}
		}

		return fragment;
	}

	(function () {
		var fragment = document.createDocumentFragment(),
		    div = fragment.appendChild(document.createElement("div")),
		    input = document.createElement("input");

		// Support: Android 4.0-4.3, Safari<=5.1
		// Check state lost if the name is set (#11217)
		// Support: Windows Web Apps (WWA)
		// `name` and `type` must use .setAttribute for WWA (#14901)
		input.setAttribute("type", "radio");
		input.setAttribute("checked", "checked");
		input.setAttribute("name", "t");

		div.appendChild(input);

		// Support: Safari<=5.1, Android<4.2
		// Older WebKit doesn't clone checked state correctly in fragments
		support.checkClone = div.cloneNode(true).cloneNode(true).lastChild.checked;

		// Support: IE<=11+
		// Make sure textarea (and checkbox) defaultValue is properly cloned
		div.innerHTML = "<textarea>x</textarea>";
		support.noCloneChecked = !!div.cloneNode(true).lastChild.defaultValue;
	})();

	var rkeyEvent = /^key/,
	    rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
	    rtypenamespace = /^([^.]*)(?:\.(.+)|)/;

	function returnTrue() {
		return true;
	}

	function returnFalse() {
		return false;
	}

	// Support: IE9
	// See #13393 for more info
	function safeActiveElement() {
		try {
			return document.activeElement;
		} catch (err) {}
	}

	function _on(elem, types, selector, data, fn, one) {
		var origFn, type;

		// Types can be a map of types/handlers
		if ((typeof types === "undefined" ? "undefined" : _typeof(types)) === "object") {

			// ( types-Object, selector, data )
			if (typeof selector !== "string") {

				// ( types-Object, data )
				data = data || selector;
				selector = undefined;
			}
			for (type in types) {
				_on(elem, type, selector, data, types[type], one);
			}
			return elem;
		}

		if (data == null && fn == null) {

			// ( types, fn )
			fn = selector;
			data = selector = undefined;
		} else if (fn == null) {
			if (typeof selector === "string") {

				// ( types, selector, fn )
				fn = data;
				data = undefined;
			} else {

				// ( types, data, fn )
				fn = data;
				data = selector;
				selector = undefined;
			}
		}
		if (fn === false) {
			fn = returnFalse;
		} else if (!fn) {
			return elem;
		}

		if (one === 1) {
			origFn = fn;
			fn = function fn(event) {

				// Can use an empty set, since event contains the info
				jQuery().off(event);
				return origFn.apply(this, arguments);
			};

			// Use same guid so caller can remove using origFn
			fn.guid = origFn.guid || (origFn.guid = jQuery.guid++);
		}
		return elem.each(function () {
			jQuery.event.add(this, types, fn, data, selector);
		});
	}

	/*
  * Helper functions for managing events -- not part of the public interface.
  * Props to Dean Edwards' addEvent library for many of the ideas.
  */
	jQuery.event = {

		global: {},

		add: function add(elem, types, handler, data, selector) {

			var handleObjIn,
			    eventHandle,
			    tmp,
			    events,
			    t,
			    handleObj,
			    special,
			    handlers,
			    type,
			    namespaces,
			    origType,
			    elemData = dataPriv.get(elem);

			// Don't attach events to noData or text/comment nodes (but allow plain objects)
			if (!elemData) {
				return;
			}

			// Caller can pass in an object of custom data in lieu of the handler
			if (handler.handler) {
				handleObjIn = handler;
				handler = handleObjIn.handler;
				selector = handleObjIn.selector;
			}

			// Make sure that the handler has a unique ID, used to find/remove it later
			if (!handler.guid) {
				handler.guid = jQuery.guid++;
			}

			// Init the element's event structure and main handler, if this is the first
			if (!(events = elemData.events)) {
				events = elemData.events = {};
			}
			if (!(eventHandle = elemData.handle)) {
				eventHandle = elemData.handle = function (e) {

					// Discard the second event of a jQuery.event.trigger() and
					// when an event is called after a page has unloaded
					return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? jQuery.event.dispatch.apply(elem, arguments) : undefined;
				};
			}

			// Handle multiple events separated by a space
			types = (types || "").match(rnotwhite) || [""];
			t = types.length;
			while (t--) {
				tmp = rtypenamespace.exec(types[t]) || [];
				type = origType = tmp[1];
				namespaces = (tmp[2] || "").split(".").sort();

				// There *must* be a type, no attaching namespace-only handlers
				if (!type) {
					continue;
				}

				// If event changes its type, use the special event handlers for the changed type
				special = jQuery.event.special[type] || {};

				// If selector defined, determine special event api type, otherwise given type
				type = (selector ? special.delegateType : special.bindType) || type;

				// Update special based on newly reset type
				special = jQuery.event.special[type] || {};

				// handleObj is passed to all event handlers
				handleObj = jQuery.extend({
					type: type,
					origType: origType,
					data: data,
					handler: handler,
					guid: handler.guid,
					selector: selector,
					needsContext: selector && jQuery.expr.match.needsContext.test(selector),
					namespace: namespaces.join(".")
				}, handleObjIn);

				// Init the event handler queue if we're the first
				if (!(handlers = events[type])) {
					handlers = events[type] = [];
					handlers.delegateCount = 0;

					// Only use addEventListener if the special events handler returns false
					if (!special.setup || special.setup.call(elem, data, namespaces, eventHandle) === false) {

						if (elem.addEventListener) {
							elem.addEventListener(type, eventHandle);
						}
					}
				}

				if (special.add) {
					special.add.call(elem, handleObj);

					if (!handleObj.handler.guid) {
						handleObj.handler.guid = handler.guid;
					}
				}

				// Add to the element's handler list, delegates in front
				if (selector) {
					handlers.splice(handlers.delegateCount++, 0, handleObj);
				} else {
					handlers.push(handleObj);
				}

				// Keep track of which events have ever been used, for event optimization
				jQuery.event.global[type] = true;
			}
		},

		// Detach an event or set of events from an element
		remove: function remove(elem, types, handler, selector, mappedTypes) {

			var j,
			    origCount,
			    tmp,
			    events,
			    t,
			    handleObj,
			    special,
			    handlers,
			    type,
			    namespaces,
			    origType,
			    elemData = dataPriv.hasData(elem) && dataPriv.get(elem);

			if (!elemData || !(events = elemData.events)) {
				return;
			}

			// Once for each type.namespace in types; type may be omitted
			types = (types || "").match(rnotwhite) || [""];
			t = types.length;
			while (t--) {
				tmp = rtypenamespace.exec(types[t]) || [];
				type = origType = tmp[1];
				namespaces = (tmp[2] || "").split(".").sort();

				// Unbind all events (on this namespace, if provided) for the element
				if (!type) {
					for (type in events) {
						jQuery.event.remove(elem, type + types[t], handler, selector, true);
					}
					continue;
				}

				special = jQuery.event.special[type] || {};
				type = (selector ? special.delegateType : special.bindType) || type;
				handlers = events[type] || [];
				tmp = tmp[2] && new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)");

				// Remove matching events
				origCount = j = handlers.length;
				while (j--) {
					handleObj = handlers[j];

					if ((mappedTypes || origType === handleObj.origType) && (!handler || handler.guid === handleObj.guid) && (!tmp || tmp.test(handleObj.namespace)) && (!selector || selector === handleObj.selector || selector === "**" && handleObj.selector)) {
						handlers.splice(j, 1);

						if (handleObj.selector) {
							handlers.delegateCount--;
						}
						if (special.remove) {
							special.remove.call(elem, handleObj);
						}
					}
				}

				// Remove generic event handler if we removed something and no more handlers exist
				// (avoids potential for endless recursion during removal of special event handlers)
				if (origCount && !handlers.length) {
					if (!special.teardown || special.teardown.call(elem, namespaces, elemData.handle) === false) {

						jQuery.removeEvent(elem, type, elemData.handle);
					}

					delete events[type];
				}
			}

			// Remove data and the expando if it's no longer used
			if (jQuery.isEmptyObject(events)) {
				dataPriv.remove(elem, "handle events");
			}
		},

		dispatch: function dispatch(event) {

			// Make a writable jQuery.Event from the native event object
			event = jQuery.event.fix(event);

			var i,
			    j,
			    ret,
			    matched,
			    handleObj,
			    handlerQueue = [],
			    args = _slice.call(arguments),
			    handlers = (dataPriv.get(this, "events") || {})[event.type] || [],
			    special = jQuery.event.special[event.type] || {};

			// Use the fix-ed jQuery.Event rather than the (read-only) native event
			args[0] = event;
			event.delegateTarget = this;

			// Call the preDispatch hook for the mapped type, and let it bail if desired
			if (special.preDispatch && special.preDispatch.call(this, event) === false) {
				return;
			}

			// Determine handlers
			handlerQueue = jQuery.event.handlers.call(this, event, handlers);

			// Run delegates first; they may want to stop propagation beneath us
			i = 0;
			while ((matched = handlerQueue[i++]) && !event.isPropagationStopped()) {
				event.currentTarget = matched.elem;

				j = 0;
				while ((handleObj = matched.handlers[j++]) && !event.isImmediatePropagationStopped()) {

					// Triggered event must either 1) have no namespace, or 2) have namespace(s)
					// a subset or equal to those in the bound event (both can have no namespace).
					if (!event.rnamespace || event.rnamespace.test(handleObj.namespace)) {

						event.handleObj = handleObj;
						event.data = handleObj.data;

						ret = ((jQuery.event.special[handleObj.origType] || {}).handle || handleObj.handler).apply(matched.elem, args);

						if (ret !== undefined) {
							if ((event.result = ret) === false) {
								event.preventDefault();
								event.stopPropagation();
							}
						}
					}
				}
			}

			// Call the postDispatch hook for the mapped type
			if (special.postDispatch) {
				special.postDispatch.call(this, event);
			}

			return event.result;
		},

		handlers: function handlers(event, _handlers) {
			var i,
			    matches,
			    sel,
			    handleObj,
			    handlerQueue = [],
			    delegateCount = _handlers.delegateCount,
			    cur = event.target;

			// Support (at least): Chrome, IE9
			// Find delegate handlers
			// Black-hole SVG <use> instance trees (#13180)
			//
			// Support: Firefox<=42+
			// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)
			if (delegateCount && cur.nodeType && (event.type !== "click" || isNaN(event.button) || event.button < 1)) {

				for (; cur !== this; cur = cur.parentNode || this) {

					// Don't check non-elements (#13208)
					// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
					if (cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click")) {
						matches = [];
						for (i = 0; i < delegateCount; i++) {
							handleObj = _handlers[i];

							// Don't conflict with Object.prototype properties (#13203)
							sel = handleObj.selector + " ";

							if (matches[sel] === undefined) {
								matches[sel] = handleObj.needsContext ? jQuery(sel, this).index(cur) > -1 : jQuery.find(sel, this, null, [cur]).length;
							}
							if (matches[sel]) {
								matches.push(handleObj);
							}
						}
						if (matches.length) {
							handlerQueue.push({ elem: cur, handlers: matches });
						}
					}
				}
			}

			// Add the remaining (directly-bound) handlers
			if (delegateCount < _handlers.length) {
				handlerQueue.push({ elem: this, handlers: _handlers.slice(delegateCount) });
			}

			return handlerQueue;
		},

		// Includes some event props shared by KeyEvent and MouseEvent
		props: ("altKey bubbles cancelable ctrlKey currentTarget detail eventPhase " + "metaKey relatedTarget shiftKey target timeStamp view which").split(" "),

		fixHooks: {},

		keyHooks: {
			props: "char charCode key keyCode".split(" "),
			filter: function filter(event, original) {

				// Add which for key events
				if (event.which == null) {
					event.which = original.charCode != null ? original.charCode : original.keyCode;
				}

				return event;
			}
		},

		mouseHooks: {
			props: ("button buttons clientX clientY offsetX offsetY pageX pageY " + "screenX screenY toElement").split(" "),
			filter: function filter(event, original) {
				var eventDoc,
				    doc,
				    body,
				    button = original.button;

				// Calculate pageX/Y if missing and clientX/Y available
				if (event.pageX == null && original.clientX != null) {
					eventDoc = event.target.ownerDocument || document;
					doc = eventDoc.documentElement;
					body = eventDoc.body;

					event.pageX = original.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
					event.pageY = original.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
				}

				// Add which for click: 1 === left; 2 === middle; 3 === right
				// Note: button is not normalized, so don't use it
				if (!event.which && button !== undefined) {
					event.which = button & 1 ? 1 : button & 2 ? 3 : button & 4 ? 2 : 0;
				}

				return event;
			}
		},

		fix: function fix(event) {
			if (event[jQuery.expando]) {
				return event;
			}

			// Create a writable copy of the event object and normalize some properties
			var i,
			    prop,
			    copy,
			    type = event.type,
			    originalEvent = event,
			    fixHook = this.fixHooks[type];

			if (!fixHook) {
				this.fixHooks[type] = fixHook = rmouseEvent.test(type) ? this.mouseHooks : rkeyEvent.test(type) ? this.keyHooks : {};
			}
			copy = fixHook.props ? this.props.concat(fixHook.props) : this.props;

			event = new jQuery.Event(originalEvent);

			i = copy.length;
			while (i--) {
				prop = copy[i];
				event[prop] = originalEvent[prop];
			}

			// Support: Cordova 2.5 (WebKit) (#13255)
			// All events should have a target; Cordova deviceready doesn't
			if (!event.target) {
				event.target = document;
			}

			// Support: Safari 6.0+, Chrome<28
			// Target should not be a text node (#504, #13143)
			if (event.target.nodeType === 3) {
				event.target = event.target.parentNode;
			}

			return fixHook.filter ? fixHook.filter(event, originalEvent) : event;
		},

		special: {
			load: {

				// Prevent triggered image.load events from bubbling to window.load
				noBubble: true
			},
			focus: {

				// Fire native event if possible so blur/focus sequence is correct
				trigger: function trigger() {
					if (this !== safeActiveElement() && this.focus) {
						this.focus();
						return false;
					}
				},
				delegateType: "focusin"
			},
			blur: {
				trigger: function trigger() {
					if (this === safeActiveElement() && this.blur) {
						this.blur();
						return false;
					}
				},
				delegateType: "focusout"
			},
			click: {

				// For checkbox, fire native event so checked state will be right
				trigger: function trigger() {
					if (this.type === "checkbox" && this.click && jQuery.nodeName(this, "input")) {
						this.click();
						return false;
					}
				},

				// For cross-browser consistency, don't fire native .click() on links
				_default: function _default(event) {
					return jQuery.nodeName(event.target, "a");
				}
			},

			beforeunload: {
				postDispatch: function postDispatch(event) {

					// Support: Firefox 20+
					// Firefox doesn't alert if the returnValue field is not set.
					if (event.result !== undefined && event.originalEvent) {
						event.originalEvent.returnValue = event.result;
					}
				}
			}
		}
	};

	jQuery.removeEvent = function (elem, type, handle) {

		// This "if" is needed for plain objects
		if (elem.removeEventListener) {
			elem.removeEventListener(type, handle);
		}
	};

	jQuery.Event = function (src, props) {

		// Allow instantiation without the 'new' keyword
		if (!(this instanceof jQuery.Event)) {
			return new jQuery.Event(src, props);
		}

		// Event object
		if (src && src.type) {
			this.originalEvent = src;
			this.type = src.type;

			// Events bubbling up the document may have been marked as prevented
			// by a handler lower down the tree; reflect the correct value.
			this.isDefaultPrevented = src.defaultPrevented || src.defaultPrevented === undefined &&

			// Support: Android<4.0
			src.returnValue === false ? returnTrue : returnFalse;

			// Event type
		} else {
			this.type = src;
		}

		// Put explicitly provided properties onto the event object
		if (props) {
			jQuery.extend(this, props);
		}

		// Create a timestamp if incoming event doesn't have one
		this.timeStamp = src && src.timeStamp || jQuery.now();

		// Mark it as fixed
		this[jQuery.expando] = true;
	};

	// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
	// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
	jQuery.Event.prototype = {
		constructor: jQuery.Event,
		isDefaultPrevented: returnFalse,
		isPropagationStopped: returnFalse,
		isImmediatePropagationStopped: returnFalse,
		isSimulated: false,

		preventDefault: function preventDefault() {
			var e = this.originalEvent;

			this.isDefaultPrevented = returnTrue;

			if (e && !this.isSimulated) {
				e.preventDefault();
			}
		},
		stopPropagation: function stopPropagation() {
			var e = this.originalEvent;

			this.isPropagationStopped = returnTrue;

			if (e && !this.isSimulated) {
				e.stopPropagation();
			}
		},
		stopImmediatePropagation: function stopImmediatePropagation() {
			var e = this.originalEvent;

			this.isImmediatePropagationStopped = returnTrue;

			if (e && !this.isSimulated) {
				e.stopImmediatePropagation();
			}

			this.stopPropagation();
		}
	};

	// Create mouseenter/leave events using mouseover/out and event-time checks
	// so that event delegation works in jQuery.
	// Do the same for pointerenter/pointerleave and pointerover/pointerout
	//
	// Support: Safari 7 only
	// Safari sends mouseenter too often; see:
	// https://code.google.com/p/chromium/issues/detail?id=470258
	// for the description of the bug (it existed in older Chrome versions as well).
	jQuery.each({
		mouseenter: "mouseover",
		mouseleave: "mouseout",
		pointerenter: "pointerover",
		pointerleave: "pointerout"
	}, function (orig, fix) {
		jQuery.event.special[orig] = {
			delegateType: fix,
			bindType: fix,

			handle: function handle(event) {
				var ret,
				    target = this,
				    related = event.relatedTarget,
				    handleObj = event.handleObj;

				// For mouseenter/leave call the handler if related is outside the target.
				// NB: No relatedTarget if the mouse left/entered the browser window
				if (!related || related !== target && !jQuery.contains(target, related)) {
					event.type = handleObj.origType;
					ret = handleObj.handler.apply(this, arguments);
					event.type = fix;
				}
				return ret;
			}
		};
	});

	jQuery.fn.extend({
		on: function on(types, selector, data, fn) {
			return _on(this, types, selector, data, fn);
		},
		one: function one(types, selector, data, fn) {
			return _on(this, types, selector, data, fn, 1);
		},
		off: function off(types, selector, fn) {
			var handleObj, type;
			if (types && types.preventDefault && types.handleObj) {

				// ( event )  dispatched jQuery.Event
				handleObj = types.handleObj;
				jQuery(types.delegateTarget).off(handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, handleObj.selector, handleObj.handler);
				return this;
			}
			if ((typeof types === "undefined" ? "undefined" : _typeof(types)) === "object") {

				// ( types-object [, selector] )
				for (type in types) {
					this.off(type, selector, types[type]);
				}
				return this;
			}
			if (selector === false || typeof selector === "function") {

				// ( types [, fn] )
				fn = selector;
				selector = undefined;
			}
			if (fn === false) {
				fn = returnFalse;
			}
			return this.each(function () {
				jQuery.event.remove(this, types, fn, selector);
			});
		}
	});

	var rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,


	// Support: IE 10-11, Edge 10240+
	// In IE/Edge using regex groups here causes severe slowdowns.
	// See https://connect.microsoft.com/IE/feedback/details/1736512/
	rnoInnerhtml = /<script|<style|<link/i,


	// checked="checked" or checked
	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
	    rscriptTypeMasked = /^true\/(.*)/,
	    rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;

	// Manipulating tables requires a tbody
	function manipulationTarget(elem, content) {
		return jQuery.nodeName(elem, "table") && jQuery.nodeName(content.nodeType !== 11 ? content : content.firstChild, "tr") ? elem.getElementsByTagName("tbody")[0] || elem.appendChild(elem.ownerDocument.createElement("tbody")) : elem;
	}

	// Replace/restore the type attribute of script elements for safe DOM manipulation
	function disableScript(elem) {
		elem.type = (elem.getAttribute("type") !== null) + "/" + elem.type;
		return elem;
	}
	function restoreScript(elem) {
		var match = rscriptTypeMasked.exec(elem.type);

		if (match) {
			elem.type = match[1];
		} else {
			elem.removeAttribute("type");
		}

		return elem;
	}

	function cloneCopyEvent(src, dest) {
		var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;

		if (dest.nodeType !== 1) {
			return;
		}

		// 1. Copy private data: events, handlers, etc.
		if (dataPriv.hasData(src)) {
			pdataOld = dataPriv.access(src);
			pdataCur = dataPriv.set(dest, pdataOld);
			events = pdataOld.events;

			if (events) {
				delete pdataCur.handle;
				pdataCur.events = {};

				for (type in events) {
					for (i = 0, l = events[type].length; i < l; i++) {
						jQuery.event.add(dest, type, events[type][i]);
					}
				}
			}
		}

		// 2. Copy user data
		if (dataUser.hasData(src)) {
			udataOld = dataUser.access(src);
			udataCur = jQuery.extend({}, udataOld);

			dataUser.set(dest, udataCur);
		}
	}

	// Fix IE bugs, see support tests
	function fixInput(src, dest) {
		var nodeName = dest.nodeName.toLowerCase();

		// Fails to persist the checked state of a cloned checkbox or radio button.
		if (nodeName === "input" && rcheckableType.test(src.type)) {
			dest.checked = src.checked;

			// Fails to return the selected option to the default selected state when cloning options
		} else if (nodeName === "input" || nodeName === "textarea") {
			dest.defaultValue = src.defaultValue;
		}
	}

	function domManip(collection, args, callback, ignored) {

		// Flatten any nested arrays
		args = concat.apply([], args);

		var fragment,
		    first,
		    scripts,
		    hasScripts,
		    node,
		    doc,
		    i = 0,
		    l = collection.length,
		    iNoClone = l - 1,
		    value = args[0],
		    isFunction = jQuery.isFunction(value);

		// We can't cloneNode fragments that contain checked, in WebKit
		if (isFunction || l > 1 && typeof value === "string" && !support.checkClone && rchecked.test(value)) {
			return collection.each(function (index) {
				var self = collection.eq(index);
				if (isFunction) {
					args[0] = value.call(this, index, self.html());
				}
				domManip(self, args, callback, ignored);
			});
		}

		if (l) {
			fragment = buildFragment(args, collection[0].ownerDocument, false, collection, ignored);
			first = fragment.firstChild;

			if (fragment.childNodes.length === 1) {
				fragment = first;
			}

			// Require either new content or an interest in ignored elements to invoke the callback
			if (first || ignored) {
				scripts = jQuery.map(getAll(fragment, "script"), disableScript);
				hasScripts = scripts.length;

				// Use the original fragment for the last item
				// instead of the first because it can end up
				// being emptied incorrectly in certain situations (#8070).
				for (; i < l; i++) {
					node = fragment;

					if (i !== iNoClone) {
						node = jQuery.clone(node, true, true);

						// Keep references to cloned scripts for later restoration
						if (hasScripts) {

							// Support: Android<4.1, PhantomJS<2
							// push.apply(_, arraylike) throws on ancient WebKit
							jQuery.merge(scripts, getAll(node, "script"));
						}
					}

					callback.call(collection[i], node, i);
				}

				if (hasScripts) {
					doc = scripts[scripts.length - 1].ownerDocument;

					// Reenable scripts
					jQuery.map(scripts, restoreScript);

					// Evaluate executable scripts on first document insertion
					for (i = 0; i < hasScripts; i++) {
						node = scripts[i];
						if (rscriptType.test(node.type || "") && !dataPriv.access(node, "globalEval") && jQuery.contains(doc, node)) {

							if (node.src) {

								// Optional AJAX dependency, but won't run scripts if not present
								if (jQuery._evalUrl) {
									jQuery._evalUrl(node.src);
								}
							} else {
								jQuery.globalEval(node.textContent.replace(rcleanScript, ""));
							}
						}
					}
				}
			}
		}

		return collection;
	}

	function _remove(elem, selector, keepData) {
		var node,
		    nodes = selector ? jQuery.filter(selector, elem) : elem,
		    i = 0;

		for (; (node = nodes[i]) != null; i++) {
			if (!keepData && node.nodeType === 1) {
				jQuery.cleanData(getAll(node));
			}

			if (node.parentNode) {
				if (keepData && jQuery.contains(node.ownerDocument, node)) {
					setGlobalEval(getAll(node, "script"));
				}
				node.parentNode.removeChild(node);
			}
		}

		return elem;
	}

	jQuery.extend({
		htmlPrefilter: function htmlPrefilter(html) {
			return html.replace(rxhtmlTag, "<$1></$2>");
		},

		clone: function clone(elem, dataAndEvents, deepDataAndEvents) {
			var i,
			    l,
			    srcElements,
			    destElements,
			    clone = elem.cloneNode(true),
			    inPage = jQuery.contains(elem.ownerDocument, elem);

			// Fix IE cloning issues
			if (!support.noCloneChecked && (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem)) {

				// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
				destElements = getAll(clone);
				srcElements = getAll(elem);

				for (i = 0, l = srcElements.length; i < l; i++) {
					fixInput(srcElements[i], destElements[i]);
				}
			}

			// Copy the events from the original to the clone
			if (dataAndEvents) {
				if (deepDataAndEvents) {
					srcElements = srcElements || getAll(elem);
					destElements = destElements || getAll(clone);

					for (i = 0, l = srcElements.length; i < l; i++) {
						cloneCopyEvent(srcElements[i], destElements[i]);
					}
				} else {
					cloneCopyEvent(elem, clone);
				}
			}

			// Preserve script evaluation history
			destElements = getAll(clone, "script");
			if (destElements.length > 0) {
				setGlobalEval(destElements, !inPage && getAll(elem, "script"));
			}

			// Return the cloned set
			return clone;
		},

		cleanData: function cleanData(elems) {
			var data,
			    elem,
			    type,
			    special = jQuery.event.special,
			    i = 0;

			for (; (elem = elems[i]) !== undefined; i++) {
				if (acceptData(elem)) {
					if (data = elem[dataPriv.expando]) {
						if (data.events) {
							for (type in data.events) {
								if (special[type]) {
									jQuery.event.remove(elem, type);

									// This is a shortcut to avoid jQuery.event.remove's overhead
								} else {
									jQuery.removeEvent(elem, type, data.handle);
								}
							}
						}

						// Support: Chrome <= 35-45+
						// Assign undefined instead of using delete, see Data#remove
						elem[dataPriv.expando] = undefined;
					}
					if (elem[dataUser.expando]) {

						// Support: Chrome <= 35-45+
						// Assign undefined instead of using delete, see Data#remove
						elem[dataUser.expando] = undefined;
					}
				}
			}
		}
	});

	jQuery.fn.extend({

		// Keep domManip exposed until 3.0 (gh-2225)
		domManip: domManip,

		detach: function detach(selector) {
			return _remove(this, selector, true);
		},

		remove: function remove(selector) {
			return _remove(this, selector);
		},

		text: function text(value) {
			return access(this, function (value) {
				return value === undefined ? jQuery.text(this) : this.empty().each(function () {
					if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
						this.textContent = value;
					}
				});
			}, null, value, arguments.length);
		},

		append: function append() {
			return domManip(this, arguments, function (elem) {
				if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
					var target = manipulationTarget(this, elem);
					target.appendChild(elem);
				}
			});
		},

		prepend: function prepend() {
			return domManip(this, arguments, function (elem) {
				if (this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9) {
					var target = manipulationTarget(this, elem);
					target.insertBefore(elem, target.firstChild);
				}
			});
		},

		before: function before() {
			return domManip(this, arguments, function (elem) {
				if (this.parentNode) {
					this.parentNode.insertBefore(elem, this);
				}
			});
		},

		after: function after() {
			return domManip(this, arguments, function (elem) {
				if (this.parentNode) {
					this.parentNode.insertBefore(elem, this.nextSibling);
				}
			});
		},

		empty: function empty() {
			var elem,
			    i = 0;

			for (; (elem = this[i]) != null; i++) {
				if (elem.nodeType === 1) {

					// Prevent memory leaks
					jQuery.cleanData(getAll(elem, false));

					// Remove any remaining nodes
					elem.textContent = "";
				}
			}

			return this;
		},

		clone: function clone(dataAndEvents, deepDataAndEvents) {
			dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
			deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;

			return this.map(function () {
				return jQuery.clone(this, dataAndEvents, deepDataAndEvents);
			});
		},

		html: function html(value) {
			return access(this, function (value) {
				var elem = this[0] || {},
				    i = 0,
				    l = this.length;

				if (value === undefined && elem.nodeType === 1) {
					return elem.innerHTML;
				}

				// See if we can take a shortcut and just use innerHTML
				if (typeof value === "string" && !rnoInnerhtml.test(value) && !wrapMap[(rtagName.exec(value) || ["", ""])[1].toLowerCase()]) {

					value = jQuery.htmlPrefilter(value);

					try {
						for (; i < l; i++) {
							elem = this[i] || {};

							// Remove element nodes and prevent memory leaks
							if (elem.nodeType === 1) {
								jQuery.cleanData(getAll(elem, false));
								elem.innerHTML = value;
							}
						}

						elem = 0;

						// If using innerHTML throws an exception, use the fallback method
					} catch (e) {}
				}

				if (elem) {
					this.empty().append(value);
				}
			}, null, value, arguments.length);
		},

		replaceWith: function replaceWith() {
			var ignored = [];

			// Make the changes, replacing each non-ignored context element with the new content
			return domManip(this, arguments, function (elem) {
				var parent = this.parentNode;

				if (jQuery.inArray(this, ignored) < 0) {
					jQuery.cleanData(getAll(this));
					if (parent) {
						parent.replaceChild(elem, this);
					}
				}

				// Force callback invocation
			}, ignored);
		}
	});

	jQuery.each({
		appendTo: "append",
		prependTo: "prepend",
		insertBefore: "before",
		insertAfter: "after",
		replaceAll: "replaceWith"
	}, function (name, original) {
		jQuery.fn[name] = function (selector) {
			var elems,
			    ret = [],
			    insert = jQuery(selector),
			    last = insert.length - 1,
			    i = 0;

			for (; i <= last; i++) {
				elems = i === last ? this : this.clone(true);
				jQuery(insert[i])[original](elems);

				// Support: QtWebKit
				// .get() because push.apply(_, arraylike) throws
				push.apply(ret, elems.get());
			}

			return this.pushStack(ret);
		};
	});

	var iframe,
	    elemdisplay = {

		// Support: Firefox
		// We have to pre-define these values for FF (#10227)
		HTML: "block",
		BODY: "block"
	};

	/**
  * Retrieve the actual display of a element
  * @param {String} name nodeName of the element
  * @param {Object} doc Document object
  */

	// Called only from within defaultDisplay
	function actualDisplay(name, doc) {
		var elem = jQuery(doc.createElement(name)).appendTo(doc.body),
		    display = jQuery.css(elem[0], "display");

		// We don't have any data stored on the element,
		// so use "detach" method as fast way to get rid of the element
		elem.detach();

		return display;
	}

	/**
  * Try to determine the default display value of an element
  * @param {String} nodeName
  */
	function defaultDisplay(nodeName) {
		var doc = document,
		    display = elemdisplay[nodeName];

		if (!display) {
			display = actualDisplay(nodeName, doc);

			// If the simple way fails, read from inside an iframe
			if (display === "none" || !display) {

				// Use the already-created iframe if possible
				iframe = (iframe || jQuery("<iframe frameborder='0' width='0' height='0'/>")).appendTo(doc.documentElement);

				// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
				doc = iframe[0].contentDocument;

				// Support: IE
				doc.write();
				doc.close();

				display = actualDisplay(nodeName, doc);
				iframe.detach();
			}

			// Store the correct default display
			elemdisplay[nodeName] = display;
		}

		return display;
	}
	var rmargin = /^margin/;

	var rnumnonpx = new RegExp("^(" + pnum + ")(?!px)[a-z%]+$", "i");

	var getStyles = function getStyles(elem) {

		// Support: IE<=11+, Firefox<=30+ (#15098, #14150)
		// IE throws on elements created in popups
		// FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
		var view = elem.ownerDocument.defaultView;

		if (!view || !view.opener) {
			view = window;
		}

		return view.getComputedStyle(elem);
	};

	var swap = function swap(elem, options, callback, args) {
		var ret,
		    name,
		    old = {};

		// Remember the old values, and insert the new ones
		for (name in options) {
			old[name] = elem.style[name];
			elem.style[name] = options[name];
		}

		ret = callback.apply(elem, args || []);

		// Revert the old values
		for (name in options) {
			elem.style[name] = old[name];
		}

		return ret;
	};

	var documentElement = document.documentElement;

	(function () {
		var pixelPositionVal,
		    boxSizingReliableVal,
		    pixelMarginRightVal,
		    reliableMarginLeftVal,
		    container = document.createElement("div"),
		    div = document.createElement("div");

		// Finish early in limited (non-browser) environments
		if (!div.style) {
			return;
		}

		// Support: IE9-11+
		// Style of cloned element affects source element cloned (#8908)
		div.style.backgroundClip = "content-box";
		div.cloneNode(true).style.backgroundClip = "";
		support.clearCloneStyle = div.style.backgroundClip === "content-box";

		container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" + "padding:0;margin-top:1px;position:absolute";
		container.appendChild(div);

		// Executing both pixelPosition & boxSizingReliable tests require only one layout
		// so they're executed at the same time to save the second computation.
		function computeStyleTests() {
			div.style.cssText =

			// Support: Firefox<29, Android 2.3
			// Vendor-prefix box-sizing
			"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;" + "position:relative;display:block;" + "margin:auto;border:1px;padding:1px;" + "top:1%;width:50%";
			div.innerHTML = "";
			documentElement.appendChild(container);

			var divStyle = window.getComputedStyle(div);
			pixelPositionVal = divStyle.top !== "1%";
			reliableMarginLeftVal = divStyle.marginLeft === "2px";
			boxSizingReliableVal = divStyle.width === "4px";

			// Support: Android 4.0 - 4.3 only
			// Some styles come back with percentage values, even though they shouldn't
			div.style.marginRight = "50%";
			pixelMarginRightVal = divStyle.marginRight === "4px";

			documentElement.removeChild(container);
		}

		jQuery.extend(support, {
			pixelPosition: function pixelPosition() {

				// This test is executed only once but we still do memoizing
				// since we can use the boxSizingReliable pre-computing.
				// No need to check if the test was already performed, though.
				computeStyleTests();
				return pixelPositionVal;
			},
			boxSizingReliable: function boxSizingReliable() {
				if (boxSizingReliableVal == null) {
					computeStyleTests();
				}
				return boxSizingReliableVal;
			},
			pixelMarginRight: function pixelMarginRight() {

				// Support: Android 4.0-4.3
				// We're checking for boxSizingReliableVal here instead of pixelMarginRightVal
				// since that compresses better and they're computed together anyway.
				if (boxSizingReliableVal == null) {
					computeStyleTests();
				}
				return pixelMarginRightVal;
			},
			reliableMarginLeft: function reliableMarginLeft() {

				// Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37
				if (boxSizingReliableVal == null) {
					computeStyleTests();
				}
				return reliableMarginLeftVal;
			},
			reliableMarginRight: function reliableMarginRight() {

				// Support: Android 2.3
				// Check if div with explicit width and no margin-right incorrectly
				// gets computed margin-right based on width of container. (#3333)
				// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
				// This support function is only executed once so no memoizing is needed.
				var ret,
				    marginDiv = div.appendChild(document.createElement("div"));

				// Reset CSS: box-sizing; display; margin; border; padding
				marginDiv.style.cssText = div.style.cssText =

				// Support: Android 2.3
				// Vendor-prefix box-sizing
				"-webkit-box-sizing:content-box;box-sizing:content-box;" + "display:block;margin:0;border:0;padding:0";
				marginDiv.style.marginRight = marginDiv.style.width = "0";
				div.style.width = "1px";
				documentElement.appendChild(container);

				ret = !parseFloat(window.getComputedStyle(marginDiv).marginRight);

				documentElement.removeChild(container);
				div.removeChild(marginDiv);

				return ret;
			}
		});
	})();

	function curCSS(elem, name, computed) {
		var width,
		    minWidth,
		    maxWidth,
		    ret,
		    style = elem.style;

		computed = computed || getStyles(elem);
		ret = computed ? computed.getPropertyValue(name) || computed[name] : undefined;

		// Support: Opera 12.1x only
		// Fall back to style even without computed
		// computed is undefined for elems on document fragments
		if ((ret === "" || ret === undefined) && !jQuery.contains(elem.ownerDocument, elem)) {
			ret = jQuery.style(elem, name);
		}

		// Support: IE9
		// getPropertyValue is only needed for .css('filter') (#12537)
		if (computed) {

			// A tribute to the "awesome hack by Dean Edwards"
			// Android Browser returns percentage for some values,
			// but width seems to be reliably pixels.
			// This is against the CSSOM draft spec:
			// http://dev.w3.org/csswg/cssom/#resolved-values
			if (!support.pixelMarginRight() && rnumnonpx.test(ret) && rmargin.test(name)) {

				// Remember the original values
				width = style.width;
				minWidth = style.minWidth;
				maxWidth = style.maxWidth;

				// Put in the new values to get a computed value out
				style.minWidth = style.maxWidth = style.width = ret;
				ret = computed.width;

				// Revert the changed values
				style.width = width;
				style.minWidth = minWidth;
				style.maxWidth = maxWidth;
			}
		}

		return ret !== undefined ?

		// Support: IE9-11+
		// IE returns zIndex value as an integer.
		ret + "" : ret;
	}

	function addGetHookIf(conditionFn, hookFn) {

		// Define the hook, we'll check on the first run if it's really needed.
		return {
			get: function get() {
				if (conditionFn()) {

					// Hook not needed (or it's not possible to use it due
					// to missing dependency), remove it.
					delete this.get;
					return;
				}

				// Hook needed; redefine it so that the support test is not executed again.
				return (this.get = hookFn).apply(this, arguments);
			}
		};
	}

	var

	// Swappable if display is none or starts with table
	// except "table", "table-cell", or "table-caption"
	// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
	rdisplayswap = /^(none|table(?!-c[ea]).+)/,
	    cssShow = { position: "absolute", visibility: "hidden", display: "block" },
	    cssNormalTransform = {
		letterSpacing: "0",
		fontWeight: "400"
	},
	    cssPrefixes = ["Webkit", "O", "Moz", "ms"],
	    emptyStyle = document.createElement("div").style;

	// Return a css property mapped to a potentially vendor prefixed property
	function vendorPropName(name) {

		// Shortcut for names that are not vendor prefixed
		if (name in emptyStyle) {
			return name;
		}

		// Check for vendor prefixed names
		var capName = name[0].toUpperCase() + name.slice(1),
		    i = cssPrefixes.length;

		while (i--) {
			name = cssPrefixes[i] + capName;
			if (name in emptyStyle) {
				return name;
			}
		}
	}

	function setPositiveNumber(elem, value, subtract) {

		// Any relative (+/-) values have already been
		// normalized at this point
		var matches = rcssNum.exec(value);
		return matches ?

		// Guard against undefined "subtract", e.g., when used as in cssHooks
		Math.max(0, matches[2] - (subtract || 0)) + (matches[3] || "px") : value;
	}

	function augmentWidthOrHeight(elem, name, extra, isBorderBox, styles) {
		var i = extra === (isBorderBox ? "border" : "content") ?

		// If we already have the right measurement, avoid augmentation
		4 :

		// Otherwise initialize for horizontal or vertical properties
		name === "width" ? 1 : 0,
		    val = 0;

		for (; i < 4; i += 2) {

			// Both box models exclude margin, so add it if we want it
			if (extra === "margin") {
				val += jQuery.css(elem, extra + cssExpand[i], true, styles);
			}

			if (isBorderBox) {

				// border-box includes padding, so remove it if we want content
				if (extra === "content") {
					val -= jQuery.css(elem, "padding" + cssExpand[i], true, styles);
				}

				// At this point, extra isn't border nor margin, so remove border
				if (extra !== "margin") {
					val -= jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
				}
			} else {

				// At this point, extra isn't content, so add padding
				val += jQuery.css(elem, "padding" + cssExpand[i], true, styles);

				// At this point, extra isn't content nor padding, so add border
				if (extra !== "padding") {
					val += jQuery.css(elem, "border" + cssExpand[i] + "Width", true, styles);
				}
			}
		}

		return val;
	}

	function getWidthOrHeight(elem, name, extra) {

		// Start with offset property, which is equivalent to the border-box value
		var valueIsBorderBox = true,
		    val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
		    styles = getStyles(elem),
		    isBorderBox = jQuery.css(elem, "boxSizing", false, styles) === "border-box";

		// Some non-html elements return undefined for offsetWidth, so check for null/undefined
		// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285
		// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668
		if (val <= 0 || val == null) {

			// Fall back to computed then uncomputed css if necessary
			val = curCSS(elem, name, styles);
			if (val < 0 || val == null) {
				val = elem.style[name];
			}

			// Computed unit is not pixels. Stop here and return.
			if (rnumnonpx.test(val)) {
				return val;
			}

			// Check for style in case a browser which returns unreliable values
			// for getComputedStyle silently falls back to the reliable elem.style
			valueIsBorderBox = isBorderBox && (support.boxSizingReliable() || val === elem.style[name]);

			// Normalize "", auto, and prepare for extra
			val = parseFloat(val) || 0;
		}

		// Use the active box-sizing model to add/subtract irrelevant styles
		return val + augmentWidthOrHeight(elem, name, extra || (isBorderBox ? "border" : "content"), valueIsBorderBox, styles) + "px";
	}

	function showHide(elements, show) {
		var display,
		    elem,
		    hidden,
		    values = [],
		    index = 0,
		    length = elements.length;

		for (; index < length; index++) {
			elem = elements[index];
			if (!elem.style) {
				continue;
			}

			values[index] = dataPriv.get(elem, "olddisplay");
			display = elem.style.display;
			if (show) {

				// Reset the inline display of this element to learn if it is
				// being hidden by cascaded rules or not
				if (!values[index] && display === "none") {
					elem.style.display = "";
				}

				// Set elements which have been overridden with display: none
				// in a stylesheet to whatever the default browser style is
				// for such an element
				if (elem.style.display === "" && isHidden(elem)) {
					values[index] = dataPriv.access(elem, "olddisplay", defaultDisplay(elem.nodeName));
				}
			} else {
				hidden = isHidden(elem);

				if (display !== "none" || !hidden) {
					dataPriv.set(elem, "olddisplay", hidden ? display : jQuery.css(elem, "display"));
				}
			}
		}

		// Set the display of most of the elements in a second loop
		// to avoid the constant reflow
		for (index = 0; index < length; index++) {
			elem = elements[index];
			if (!elem.style) {
				continue;
			}
			if (!show || elem.style.display === "none" || elem.style.display === "") {
				elem.style.display = show ? values[index] || "" : "none";
			}
		}

		return elements;
	}

	jQuery.extend({

		// Add in style property hooks for overriding the default
		// behavior of getting and setting a style property
		cssHooks: {
			opacity: {
				get: function get(elem, computed) {
					if (computed) {

						// We should always get a number back from opacity
						var ret = curCSS(elem, "opacity");
						return ret === "" ? "1" : ret;
					}
				}
			}
		},

		// Don't automatically add "px" to these possibly-unitless properties
		cssNumber: {
			"animationIterationCount": true,
			"columnCount": true,
			"fillOpacity": true,
			"flexGrow": true,
			"flexShrink": true,
			"fontWeight": true,
			"lineHeight": true,
			"opacity": true,
			"order": true,
			"orphans": true,
			"widows": true,
			"zIndex": true,
			"zoom": true
		},

		// Add in properties whose names you wish to fix before
		// setting or getting the value
		cssProps: {
			"float": "cssFloat"
		},

		// Get and set the style property on a DOM Node
		style: function style(elem, name, value, extra) {

			// Don't set styles on text and comment nodes
			if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) {
				return;
			}

			// Make sure that we're working with the right name
			var ret,
			    type,
			    hooks,
			    origName = jQuery.camelCase(name),
			    style = elem.style;

			name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(origName) || origName);

			// Gets hook for the prefixed version, then unprefixed version
			hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];

			// Check if we're setting a value
			if (value !== undefined) {
				type = typeof value === "undefined" ? "undefined" : _typeof(value);

				// Convert "+=" or "-=" to relative numbers (#7345)
				if (type === "string" && (ret = rcssNum.exec(value)) && ret[1]) {
					value = adjustCSS(elem, name, ret);

					// Fixes bug #9237
					type = "number";
				}

				// Make sure that null and NaN values aren't set (#7116)
				if (value == null || value !== value) {
					return;
				}

				// If a number was passed in, add the unit (except for certain CSS properties)
				if (type === "number") {
					value += ret && ret[3] || (jQuery.cssNumber[origName] ? "" : "px");
				}

				// Support: IE9-11+
				// background-* props affect original clone's values
				if (!support.clearCloneStyle && value === "" && name.indexOf("background") === 0) {
					style[name] = "inherit";
				}

				// If a hook was provided, use that value, otherwise just set the specified value
				if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) {

					style[name] = value;
				}
			} else {

				// If a hook was provided get the non-computed value from there
				if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) {

					return ret;
				}

				// Otherwise just get the value from the style object
				return style[name];
			}
		},

		css: function css(elem, name, extra, styles) {
			var val,
			    num,
			    hooks,
			    origName = jQuery.camelCase(name);

			// Make sure that we're working with the right name
			name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(origName) || origName);

			// Try prefixed name followed by the unprefixed name
			hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName];

			// If a hook was provided get the computed value from there
			if (hooks && "get" in hooks) {
				val = hooks.get(elem, true, extra);
			}

			// Otherwise, if a way to get the computed value exists, use that
			if (val === undefined) {
				val = curCSS(elem, name, styles);
			}

			// Convert "normal" to computed value
			if (val === "normal" && name in cssNormalTransform) {
				val = cssNormalTransform[name];
			}

			// Make numeric if forced or a qualifier was provided and val looks numeric
			if (extra === "" || extra) {
				num = parseFloat(val);
				return extra === true || isFinite(num) ? num || 0 : val;
			}
			return val;
		}
	});

	jQuery.each(["height", "width"], function (i, name) {
		jQuery.cssHooks[name] = {
			get: function get(elem, computed, extra) {
				if (computed) {

					// Certain elements can have dimension info if we invisibly show them
					// but it must have a current display style that would benefit
					return rdisplayswap.test(jQuery.css(elem, "display")) && elem.offsetWidth === 0 ? swap(elem, cssShow, function () {
						return getWidthOrHeight(elem, name, extra);
					}) : getWidthOrHeight(elem, name, extra);
				}
			},

			set: function set(elem, value, extra) {
				var matches,
				    styles = extra && getStyles(elem),
				    subtract = extra && augmentWidthOrHeight(elem, name, extra, jQuery.css(elem, "boxSizing", false, styles) === "border-box", styles);

				// Convert to pixels if value adjustment is needed
				if (subtract && (matches = rcssNum.exec(value)) && (matches[3] || "px") !== "px") {

					elem.style[name] = value;
					value = jQuery.css(elem, name);
				}

				return setPositiveNumber(elem, value, subtract);
			}
		};
	});

	jQuery.cssHooks.marginLeft = addGetHookIf(support.reliableMarginLeft, function (elem, computed) {
		if (computed) {
			return (parseFloat(curCSS(elem, "marginLeft")) || elem.getBoundingClientRect().left - swap(elem, { marginLeft: 0 }, function () {
				return elem.getBoundingClientRect().left;
			})) + "px";
		}
	});

	// Support: Android 2.3
	jQuery.cssHooks.marginRight = addGetHookIf(support.reliableMarginRight, function (elem, computed) {
		if (computed) {
			return swap(elem, { "display": "inline-block" }, curCSS, [elem, "marginRight"]);
		}
	});

	// These hooks are used by animate to expand properties
	jQuery.each({
		margin: "",
		padding: "",
		border: "Width"
	}, function (prefix, suffix) {
		jQuery.cssHooks[prefix + suffix] = {
			expand: function expand(value) {
				var i = 0,
				    expanded = {},


				// Assumes a single number if not a string
				parts = typeof value === "string" ? value.split(" ") : [value];

				for (; i < 4; i++) {
					expanded[prefix + cssExpand[i] + suffix] = parts[i] || parts[i - 2] || parts[0];
				}

				return expanded;
			}
		};

		if (!rmargin.test(prefix)) {
			jQuery.cssHooks[prefix + suffix].set = setPositiveNumber;
		}
	});

	jQuery.fn.extend({
		css: function css(name, value) {
			return access(this, function (elem, name, value) {
				var styles,
				    len,
				    map = {},
				    i = 0;

				if (jQuery.isArray(name)) {
					styles = getStyles(elem);
					len = name.length;

					for (; i < len; i++) {
						map[name[i]] = jQuery.css(elem, name[i], false, styles);
					}

					return map;
				}

				return value !== undefined ? jQuery.style(elem, name, value) : jQuery.css(elem, name);
			}, name, value, arguments.length > 1);
		},
		show: function show() {
			return showHide(this, true);
		},
		hide: function hide() {
			return showHide(this);
		},
		toggle: function toggle(state) {
			if (typeof state === "boolean") {
				return state ? this.show() : this.hide();
			}

			return this.each(function () {
				if (isHidden(this)) {
					jQuery(this).show();
				} else {
					jQuery(this).hide();
				}
			});
		}
	});

	function Tween(elem, options, prop, end, easing) {
		return new Tween.prototype.init(elem, options, prop, end, easing);
	}
	jQuery.Tween = Tween;

	Tween.prototype = {
		constructor: Tween,
		init: function init(elem, options, prop, end, easing, unit) {
			this.elem = elem;
			this.prop = prop;
			this.easing = easing || jQuery.easing._default;
			this.options = options;
			this.start = this.now = this.cur();
			this.end = end;
			this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px");
		},
		cur: function cur() {
			var hooks = Tween.propHooks[this.prop];

			return hooks && hooks.get ? hooks.get(this) : Tween.propHooks._default.get(this);
		},
		run: function run(percent) {
			var eased,
			    hooks = Tween.propHooks[this.prop];

			if (this.options.duration) {
				this.pos = eased = jQuery.easing[this.easing](percent, this.options.duration * percent, 0, 1, this.options.duration);
			} else {
				this.pos = eased = percent;
			}
			this.now = (this.end - this.start) * eased + this.start;

			if (this.options.step) {
				this.options.step.call(this.elem, this.now, this);
			}

			if (hooks && hooks.set) {
				hooks.set(this);
			} else {
				Tween.propHooks._default.set(this);
			}
			return this;
		}
	};

	Tween.prototype.init.prototype = Tween.prototype;

	Tween.propHooks = {
		_default: {
			get: function get(tween) {
				var result;

				// Use a property on the element directly when it is not a DOM element,
				// or when there is no matching style property that exists.
				if (tween.elem.nodeType !== 1 || tween.elem[tween.prop] != null && tween.elem.style[tween.prop] == null) {
					return tween.elem[tween.prop];
				}

				// Passing an empty string as a 3rd parameter to .css will automatically
				// attempt a parseFloat and fallback to a string if the parse fails.
				// Simple values such as "10px" are parsed to Float;
				// complex values such as "rotate(1rad)" are returned as-is.
				result = jQuery.css(tween.elem, tween.prop, "");

				// Empty strings, null, undefined and "auto" are converted to 0.
				return !result || result === "auto" ? 0 : result;
			},
			set: function set(tween) {

				// Use step hook for back compat.
				// Use cssHook if its there.
				// Use .style if available and use plain properties where available.
				if (jQuery.fx.step[tween.prop]) {
					jQuery.fx.step[tween.prop](tween);
				} else if (tween.elem.nodeType === 1 && (tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop])) {
					jQuery.style(tween.elem, tween.prop, tween.now + tween.unit);
				} else {
					tween.elem[tween.prop] = tween.now;
				}
			}
		}
	};

	// Support: IE9
	// Panic based approach to setting things on disconnected nodes
	Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
		set: function set(tween) {
			if (tween.elem.nodeType && tween.elem.parentNode) {
				tween.elem[tween.prop] = tween.now;
			}
		}
	};

	jQuery.easing = {
		linear: function linear(p) {
			return p;
		},
		swing: function swing(p) {
			return 0.5 - Math.cos(p * Math.PI) / 2;
		},
		_default: "swing"
	};

	jQuery.fx = Tween.prototype.init;

	// Back Compat <1.8 extension point
	jQuery.fx.step = {};

	var fxNow,
	    timerId,
	    rfxtypes = /^(?:toggle|show|hide)$/,
	    rrun = /queueHooks$/;

	// Animations created synchronously will run synchronously
	function createFxNow() {
		window.setTimeout(function () {
			fxNow = undefined;
		});
		return fxNow = jQuery.now();
	}

	// Generate parameters to create a standard animation
	function genFx(type, includeWidth) {
		var which,
		    i = 0,
		    attrs = { height: type };

		// If we include width, step value is 1 to do all cssExpand values,
		// otherwise step value is 2 to skip over Left and Right
		includeWidth = includeWidth ? 1 : 0;
		for (; i < 4; i += 2 - includeWidth) {
			which = cssExpand[i];
			attrs["margin" + which] = attrs["padding" + which] = type;
		}

		if (includeWidth) {
			attrs.opacity = attrs.width = type;
		}

		return attrs;
	}

	function createTween(value, prop, animation) {
		var tween,
		    collection = (Animation.tweeners[prop] || []).concat(Animation.tweeners["*"]),
		    index = 0,
		    length = collection.length;
		for (; index < length; index++) {
			if (tween = collection[index].call(animation, prop, value)) {

				// We're done with this property
				return tween;
			}
		}
	}

	function defaultPrefilter(elem, props, opts) {
		/* jshint validthis: true */
		var prop,
		    value,
		    toggle,
		    tween,
		    hooks,
		    oldfire,
		    display,
		    checkDisplay,
		    anim = this,
		    orig = {},
		    style = elem.style,
		    hidden = elem.nodeType && isHidden(elem),
		    dataShow = dataPriv.get(elem, "fxshow");

		// Handle queue: false promises
		if (!opts.queue) {
			hooks = jQuery._queueHooks(elem, "fx");
			if (hooks.unqueued == null) {
				hooks.unqueued = 0;
				oldfire = hooks.empty.fire;
				hooks.empty.fire = function () {
					if (!hooks.unqueued) {
						oldfire();
					}
				};
			}
			hooks.unqueued++;

			anim.always(function () {

				// Ensure the complete handler is called before this completes
				anim.always(function () {
					hooks.unqueued--;
					if (!jQuery.queue(elem, "fx").length) {
						hooks.empty.fire();
					}
				});
			});
		}

		// Height/width overflow pass
		if (elem.nodeType === 1 && ("height" in props || "width" in props)) {

			// Make sure that nothing sneaks out
			// Record all 3 overflow attributes because IE9-10 do not
			// change the overflow attribute when overflowX and
			// overflowY are set to the same value
			opts.overflow = [style.overflow, style.overflowX, style.overflowY];

			// Set display property to inline-block for height/width
			// animations on inline elements that are having width/height animated
			display = jQuery.css(elem, "display");

			// Test default display if display is currently "none"
			checkDisplay = display === "none" ? dataPriv.get(elem, "olddisplay") || defaultDisplay(elem.nodeName) : display;

			if (checkDisplay === "inline" && jQuery.css(elem, "float") === "none") {
				style.display = "inline-block";
			}
		}

		if (opts.overflow) {
			style.overflow = "hidden";
			anim.always(function () {
				style.overflow = opts.overflow[0];
				style.overflowX = opts.overflow[1];
				style.overflowY = opts.overflow[2];
			});
		}

		// show/hide pass
		for (prop in props) {
			value = props[prop];
			if (rfxtypes.exec(value)) {
				delete props[prop];
				toggle = toggle || value === "toggle";
				if (value === (hidden ? "hide" : "show")) {

					// If there is dataShow left over from a stopped hide or show
					// and we are going to proceed with show, we should pretend to be hidden
					if (value === "show" && dataShow && dataShow[prop] !== undefined) {
						hidden = true;
					} else {
						continue;
					}
				}
				orig[prop] = dataShow && dataShow[prop] || jQuery.style(elem, prop);

				// Any non-fx value stops us from restoring the original display value
			} else {
				display = undefined;
			}
		}

		if (!jQuery.isEmptyObject(orig)) {
			if (dataShow) {
				if ("hidden" in dataShow) {
					hidden = dataShow.hidden;
				}
			} else {
				dataShow = dataPriv.access(elem, "fxshow", {});
			}

			// Store state if its toggle - enables .stop().toggle() to "reverse"
			if (toggle) {
				dataShow.hidden = !hidden;
			}
			if (hidden) {
				jQuery(elem).show();
			} else {
				anim.done(function () {
					jQuery(elem).hide();
				});
			}
			anim.done(function () {
				var prop;

				dataPriv.remove(elem, "fxshow");
				for (prop in orig) {
					jQuery.style(elem, prop, orig[prop]);
				}
			});
			for (prop in orig) {
				tween = createTween(hidden ? dataShow[prop] : 0, prop, anim);

				if (!(prop in dataShow)) {
					dataShow[prop] = tween.start;
					if (hidden) {
						tween.end = tween.start;
						tween.start = prop === "width" || prop === "height" ? 1 : 0;
					}
				}
			}

			// If this is a noop like .hide().hide(), restore an overwritten display value
		} else if ((display === "none" ? defaultDisplay(elem.nodeName) : display) === "inline") {
			style.display = display;
		}
	}

	function propFilter(props, specialEasing) {
		var index, name, easing, value, hooks;

		// camelCase, specialEasing and expand cssHook pass
		for (index in props) {
			name = jQuery.camelCase(index);
			easing = specialEasing[name];
			value = props[index];
			if (jQuery.isArray(value)) {
				easing = value[1];
				value = props[index] = value[0];
			}

			if (index !== name) {
				props[name] = value;
				delete props[index];
			}

			hooks = jQuery.cssHooks[name];
			if (hooks && "expand" in hooks) {
				value = hooks.expand(value);
				delete props[name];

				// Not quite $.extend, this won't overwrite existing keys.
				// Reusing 'index' because we have the correct "name"
				for (index in value) {
					if (!(index in props)) {
						props[index] = value[index];
						specialEasing[index] = easing;
					}
				}
			} else {
				specialEasing[name] = easing;
			}
		}
	}

	function Animation(elem, properties, options) {
		var result,
		    stopped,
		    index = 0,
		    length = Animation.prefilters.length,
		    deferred = jQuery.Deferred().always(function () {

			// Don't match elem in the :animated selector
			delete tick.elem;
		}),
		    tick = function tick() {
			if (stopped) {
				return false;
			}
			var currentTime = fxNow || createFxNow(),
			    remaining = Math.max(0, animation.startTime + animation.duration - currentTime),


			// Support: Android 2.3
			// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
			temp = remaining / animation.duration || 0,
			    percent = 1 - temp,
			    index = 0,
			    length = animation.tweens.length;

			for (; index < length; index++) {
				animation.tweens[index].run(percent);
			}

			deferred.notifyWith(elem, [animation, percent, remaining]);

			if (percent < 1 && length) {
				return remaining;
			} else {
				deferred.resolveWith(elem, [animation]);
				return false;
			}
		},
		    animation = deferred.promise({
			elem: elem,
			props: jQuery.extend({}, properties),
			opts: jQuery.extend(true, {
				specialEasing: {},
				easing: jQuery.easing._default
			}, options),
			originalProperties: properties,
			originalOptions: options,
			startTime: fxNow || createFxNow(),
			duration: options.duration,
			tweens: [],
			createTween: function createTween(prop, end) {
				var tween = jQuery.Tween(elem, animation.opts, prop, end, animation.opts.specialEasing[prop] || animation.opts.easing);
				animation.tweens.push(tween);
				return tween;
			},
			stop: function stop(gotoEnd) {
				var index = 0,


				// If we are going to the end, we want to run all the tweens
				// otherwise we skip this part
				length = gotoEnd ? animation.tweens.length : 0;
				if (stopped) {
					return this;
				}
				stopped = true;
				for (; index < length; index++) {
					animation.tweens[index].run(1);
				}

				// Resolve when we played the last frame; otherwise, reject
				if (gotoEnd) {
					deferred.notifyWith(elem, [animation, 1, 0]);
					deferred.resolveWith(elem, [animation, gotoEnd]);
				} else {
					deferred.rejectWith(elem, [animation, gotoEnd]);
				}
				return this;
			}
		}),
		    props = animation.props;

		propFilter(props, animation.opts.specialEasing);

		for (; index < length; index++) {
			result = Animation.prefilters[index].call(animation, elem, props, animation.opts);
			if (result) {
				if (jQuery.isFunction(result.stop)) {
					jQuery._queueHooks(animation.elem, animation.opts.queue).stop = jQuery.proxy(result.stop, result);
				}
				return result;
			}
		}

		jQuery.map(props, createTween, animation);

		if (jQuery.isFunction(animation.opts.start)) {
			animation.opts.start.call(elem, animation);
		}

		jQuery.fx.timer(jQuery.extend(tick, {
			elem: elem,
			anim: animation,
			queue: animation.opts.queue
		}));

		// attach callbacks from options
		return animation.progress(animation.opts.progress).done(animation.opts.done, animation.opts.complete).fail(animation.opts.fail).always(animation.opts.always);
	}

	jQuery.Animation = jQuery.extend(Animation, {
		tweeners: {
			"*": [function (prop, value) {
				var tween = this.createTween(prop, value);
				adjustCSS(tween.elem, prop, rcssNum.exec(value), tween);
				return tween;
			}]
		},

		tweener: function tweener(props, callback) {
			if (jQuery.isFunction(props)) {
				callback = props;
				props = ["*"];
			} else {
				props = props.match(rnotwhite);
			}

			var prop,
			    index = 0,
			    length = props.length;

			for (; index < length; index++) {
				prop = props[index];
				Animation.tweeners[prop] = Animation.tweeners[prop] || [];
				Animation.tweeners[prop].unshift(callback);
			}
		},

		prefilters: [defaultPrefilter],

		prefilter: function prefilter(callback, prepend) {
			if (prepend) {
				Animation.prefilters.unshift(callback);
			} else {
				Animation.prefilters.push(callback);
			}
		}
	});

	jQuery.speed = function (speed, easing, fn) {
		var opt = speed && (typeof speed === "undefined" ? "undefined" : _typeof(speed)) === "object" ? jQuery.extend({}, speed) : {
			complete: fn || !fn && easing || jQuery.isFunction(speed) && speed,
			duration: speed,
			easing: fn && easing || easing && !jQuery.isFunction(easing) && easing
		};

		opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default;

		// Normalize opt.queue - true/undefined/null -> "fx"
		if (opt.queue == null || opt.queue === true) {
			opt.queue = "fx";
		}

		// Queueing
		opt.old = opt.complete;

		opt.complete = function () {
			if (jQuery.isFunction(opt.old)) {
				opt.old.call(this);
			}

			if (opt.queue) {
				jQuery.dequeue(this, opt.queue);
			}
		};

		return opt;
	};

	jQuery.fn.extend({
		fadeTo: function fadeTo(speed, to, easing, callback) {

			// Show any hidden elements after setting opacity to 0
			return this.filter(isHidden).css("opacity", 0).show()

			// Animate to the value specified
			.end().animate({ opacity: to }, speed, easing, callback);
		},
		animate: function animate(prop, speed, easing, callback) {
			var empty = jQuery.isEmptyObject(prop),
			    optall = jQuery.speed(speed, easing, callback),
			    doAnimation = function doAnimation() {

				// Operate on a copy of prop so per-property easing won't be lost
				var anim = Animation(this, jQuery.extend({}, prop), optall);

				// Empty animations, or finishing resolves immediately
				if (empty || dataPriv.get(this, "finish")) {
					anim.stop(true);
				}
			};
			doAnimation.finish = doAnimation;

			return empty || optall.queue === false ? this.each(doAnimation) : this.queue(optall.queue, doAnimation);
		},
		stop: function stop(type, clearQueue, gotoEnd) {
			var stopQueue = function stopQueue(hooks) {
				var stop = hooks.stop;
				delete hooks.stop;
				stop(gotoEnd);
			};

			if (typeof type !== "string") {
				gotoEnd = clearQueue;
				clearQueue = type;
				type = undefined;
			}
			if (clearQueue && type !== false) {
				this.queue(type || "fx", []);
			}

			return this.each(function () {
				var dequeue = true,
				    index = type != null && type + "queueHooks",
				    timers = jQuery.timers,
				    data = dataPriv.get(this);

				if (index) {
					if (data[index] && data[index].stop) {
						stopQueue(data[index]);
					}
				} else {
					for (index in data) {
						if (data[index] && data[index].stop && rrun.test(index)) {
							stopQueue(data[index]);
						}
					}
				}

				for (index = timers.length; index--;) {
					if (timers[index].elem === this && (type == null || timers[index].queue === type)) {

						timers[index].anim.stop(gotoEnd);
						dequeue = false;
						timers.splice(index, 1);
					}
				}

				// Start the next in the queue if the last step wasn't forced.
				// Timers currently will call their complete callbacks, which
				// will dequeue but only if they were gotoEnd.
				if (dequeue || !gotoEnd) {
					jQuery.dequeue(this, type);
				}
			});
		},
		finish: function finish(type) {
			if (type !== false) {
				type = type || "fx";
			}
			return this.each(function () {
				var index,
				    data = dataPriv.get(this),
				    queue = data[type + "queue"],
				    hooks = data[type + "queueHooks"],
				    timers = jQuery.timers,
				    length = queue ? queue.length : 0;

				// Enable finishing flag on private data
				data.finish = true;

				// Empty the queue first
				jQuery.queue(this, type, []);

				if (hooks && hooks.stop) {
					hooks.stop.call(this, true);
				}

				// Look for any active animations, and finish them
				for (index = timers.length; index--;) {
					if (timers[index].elem === this && timers[index].queue === type) {
						timers[index].anim.stop(true);
						timers.splice(index, 1);
					}
				}

				// Look for any animations in the old queue and finish them
				for (index = 0; index < length; index++) {
					if (queue[index] && queue[index].finish) {
						queue[index].finish.call(this);
					}
				}

				// Turn off finishing flag
				delete data.finish;
			});
		}
	});

	jQuery.each(["toggle", "show", "hide"], function (i, name) {
		var cssFn = jQuery.fn[name];
		jQuery.fn[name] = function (speed, easing, callback) {
			return speed == null || typeof speed === "boolean" ? cssFn.apply(this, arguments) : this.animate(genFx(name, true), speed, easing, callback);
		};
	});

	// Generate shortcuts for custom animations
	jQuery.each({
		slideDown: genFx("show"),
		slideUp: genFx("hide"),
		slideToggle: genFx("toggle"),
		fadeIn: { opacity: "show" },
		fadeOut: { opacity: "hide" },
		fadeToggle: { opacity: "toggle" }
	}, function (name, props) {
		jQuery.fn[name] = function (speed, easing, callback) {
			return this.animate(props, speed, easing, callback);
		};
	});

	jQuery.timers = [];
	jQuery.fx.tick = function () {
		var timer,
		    i = 0,
		    timers = jQuery.timers;

		fxNow = jQuery.now();

		for (; i < timers.length; i++) {
			timer = timers[i];

			// Checks the timer has not already been removed
			if (!timer() && timers[i] === timer) {
				timers.splice(i--, 1);
			}
		}

		if (!timers.length) {
			jQuery.fx.stop();
		}
		fxNow = undefined;
	};

	jQuery.fx.timer = function (timer) {
		jQuery.timers.push(timer);
		if (timer()) {
			jQuery.fx.start();
		} else {
			jQuery.timers.pop();
		}
	};

	jQuery.fx.interval = 13;
	jQuery.fx.start = function () {
		if (!timerId) {
			timerId = window.setInterval(jQuery.fx.tick, jQuery.fx.interval);
		}
	};

	jQuery.fx.stop = function () {
		window.clearInterval(timerId);

		timerId = null;
	};

	jQuery.fx.speeds = {
		slow: 600,
		fast: 200,

		// Default speed
		_default: 400
	};

	// Based off of the plugin by Clint Helfers, with permission.
	// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
	jQuery.fn.delay = function (time, type) {
		time = jQuery.fx ? jQuery.fx.speeds[time] || time : time;
		type = type || "fx";

		return this.queue(type, function (next, hooks) {
			var timeout = window.setTimeout(next, time);
			hooks.stop = function () {
				window.clearTimeout(timeout);
			};
		});
	};

	(function () {
		var input = document.createElement("input"),
		    select = document.createElement("select"),
		    opt = select.appendChild(document.createElement("option"));

		input.type = "checkbox";

		// Support: iOS<=5.1, Android<=4.2+
		// Default value for a checkbox should be "on"
		support.checkOn = input.value !== "";

		// Support: IE<=11+
		// Must access selectedIndex to make default options select
		support.optSelected = opt.selected;

		// Support: Android<=2.3
		// Options inside disabled selects are incorrectly marked as disabled
		select.disabled = true;
		support.optDisabled = !opt.disabled;

		// Support: IE<=11+
		// An input loses its value after becoming a radio
		input = document.createElement("input");
		input.value = "t";
		input.type = "radio";
		support.radioValue = input.value === "t";
	})();

	var boolHook,
	    attrHandle = jQuery.expr.attrHandle;

	jQuery.fn.extend({
		attr: function attr(name, value) {
			return access(this, jQuery.attr, name, value, arguments.length > 1);
		},

		removeAttr: function removeAttr(name) {
			return this.each(function () {
				jQuery.removeAttr(this, name);
			});
		}
	});

	jQuery.extend({
		attr: function attr(elem, name, value) {
			var ret,
			    hooks,
			    nType = elem.nodeType;

			// Don't get/set attributes on text, comment and attribute nodes
			if (nType === 3 || nType === 8 || nType === 2) {
				return;
			}

			// Fallback to prop when attributes are not supported
			if (typeof elem.getAttribute === "undefined") {
				return jQuery.prop(elem, name, value);
			}

			// All attributes are lowercase
			// Grab necessary hook if one is defined
			if (nType !== 1 || !jQuery.isXMLDoc(elem)) {
				name = name.toLowerCase();
				hooks = jQuery.attrHooks[name] || (jQuery.expr.match.bool.test(name) ? boolHook : undefined);
			}

			if (value !== undefined) {
				if (value === null) {
					jQuery.removeAttr(elem, name);
					return;
				}

				if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {
					return ret;
				}

				elem.setAttribute(name, value + "");
				return value;
			}

			if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
				return ret;
			}

			ret = jQuery.find.attr(elem, name);

			// Non-existent attributes return null, we normalize to undefined
			return ret == null ? undefined : ret;
		},

		attrHooks: {
			type: {
				set: function set(elem, value) {
					if (!support.radioValue && value === "radio" && jQuery.nodeName(elem, "input")) {
						var val = elem.value;
						elem.setAttribute("type", value);
						if (val) {
							elem.value = val;
						}
						return value;
					}
				}
			}
		},

		removeAttr: function removeAttr(elem, value) {
			var name,
			    propName,
			    i = 0,
			    attrNames = value && value.match(rnotwhite);

			if (attrNames && elem.nodeType === 1) {
				while (name = attrNames[i++]) {
					propName = jQuery.propFix[name] || name;

					// Boolean attributes get special treatment (#10870)
					if (jQuery.expr.match.bool.test(name)) {

						// Set corresponding property to false
						elem[propName] = false;
					}

					elem.removeAttribute(name);
				}
			}
		}
	});

	// Hooks for boolean attributes
	boolHook = {
		set: function set(elem, value, name) {
			if (value === false) {

				// Remove boolean attributes when set to false
				jQuery.removeAttr(elem, name);
			} else {
				elem.setAttribute(name, name);
			}
			return name;
		}
	};
	jQuery.each(jQuery.expr.match.bool.source.match(/\w+/g), function (i, name) {
		var getter = attrHandle[name] || jQuery.find.attr;

		attrHandle[name] = function (elem, name, isXML) {
			var ret, handle;
			if (!isXML) {

				// Avoid an infinite loop by temporarily removing this function from the getter
				handle = attrHandle[name];
				attrHandle[name] = ret;
				ret = getter(elem, name, isXML) != null ? name.toLowerCase() : null;
				attrHandle[name] = handle;
			}
			return ret;
		};
	});

	var rfocusable = /^(?:input|select|textarea|button)$/i,
	    rclickable = /^(?:a|area)$/i;

	jQuery.fn.extend({
		prop: function prop(name, value) {
			return access(this, jQuery.prop, name, value, arguments.length > 1);
		},

		removeProp: function removeProp(name) {
			return this.each(function () {
				delete this[jQuery.propFix[name] || name];
			});
		}
	});

	jQuery.extend({
		prop: function prop(elem, name, value) {
			var ret,
			    hooks,
			    nType = elem.nodeType;

			// Don't get/set properties on text, comment and attribute nodes
			if (nType === 3 || nType === 8 || nType === 2) {
				return;
			}

			if (nType !== 1 || !jQuery.isXMLDoc(elem)) {

				// Fix name and attach hooks
				name = jQuery.propFix[name] || name;
				hooks = jQuery.propHooks[name];
			}

			if (value !== undefined) {
				if (hooks && "set" in hooks && (ret = hooks.set(elem, value, name)) !== undefined) {
					return ret;
				}

				return elem[name] = value;
			}

			if (hooks && "get" in hooks && (ret = hooks.get(elem, name)) !== null) {
				return ret;
			}

			return elem[name];
		},

		propHooks: {
			tabIndex: {
				get: function get(elem) {

					// elem.tabIndex doesn't always return the
					// correct value when it hasn't been explicitly set
					// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
					// Use proper attribute retrieval(#12072)
					var tabindex = jQuery.find.attr(elem, "tabindex");

					return tabindex ? parseInt(tabindex, 10) : rfocusable.test(elem.nodeName) || rclickable.test(elem.nodeName) && elem.href ? 0 : -1;
				}
			}
		},

		propFix: {
			"for": "htmlFor",
			"class": "className"
		}
	});

	// Support: IE <=11 only
	// Accessing the selectedIndex property
	// forces the browser to respect setting selected
	// on the option
	// The getter ensures a default option is selected
	// when in an optgroup
	if (!support.optSelected) {
		jQuery.propHooks.selected = {
			get: function get(elem) {
				var parent = elem.parentNode;
				if (parent && parent.parentNode) {
					parent.parentNode.selectedIndex;
				}
				return null;
			},
			set: function set(elem) {
				var parent = elem.parentNode;
				if (parent) {
					parent.selectedIndex;

					if (parent.parentNode) {
						parent.parentNode.selectedIndex;
					}
				}
			}
		};
	}

	jQuery.each(["tabIndex", "readOnly", "maxLength", "cellSpacing", "cellPadding", "rowSpan", "colSpan", "useMap", "frameBorder", "contentEditable"], function () {
		jQuery.propFix[this.toLowerCase()] = this;
	});

	var rclass = /[\t\r\n\f]/g;

	function getClass(elem) {
		return elem.getAttribute && elem.getAttribute("class") || "";
	}

	jQuery.fn.extend({
		addClass: function addClass(value) {
			var classes,
			    elem,
			    cur,
			    curValue,
			    clazz,
			    j,
			    finalValue,
			    i = 0;

			if (jQuery.isFunction(value)) {
				return this.each(function (j) {
					jQuery(this).addClass(value.call(this, j, getClass(this)));
				});
			}

			if (typeof value === "string" && value) {
				classes = value.match(rnotwhite) || [];

				while (elem = this[i++]) {
					curValue = getClass(elem);
					cur = elem.nodeType === 1 && (" " + curValue + " ").replace(rclass, " ");

					if (cur) {
						j = 0;
						while (clazz = classes[j++]) {
							if (cur.indexOf(" " + clazz + " ") < 0) {
								cur += clazz + " ";
							}
						}

						// Only assign if different to avoid unneeded rendering.
						finalValue = jQuery.trim(cur);
						if (curValue !== finalValue) {
							elem.setAttribute("class", finalValue);
						}
					}
				}
			}

			return this;
		},

		removeClass: function removeClass(value) {
			var classes,
			    elem,
			    cur,
			    curValue,
			    clazz,
			    j,
			    finalValue,
			    i = 0;

			if (jQuery.isFunction(value)) {
				return this.each(function (j) {
					jQuery(this).removeClass(value.call(this, j, getClass(this)));
				});
			}

			if (!arguments.length) {
				return this.attr("class", "");
			}

			if (typeof value === "string" && value) {
				classes = value.match(rnotwhite) || [];

				while (elem = this[i++]) {
					curValue = getClass(elem);

					// This expression is here for better compressibility (see addClass)
					cur = elem.nodeType === 1 && (" " + curValue + " ").replace(rclass, " ");

					if (cur) {
						j = 0;
						while (clazz = classes[j++]) {

							// Remove *all* instances
							while (cur.indexOf(" " + clazz + " ") > -1) {
								cur = cur.replace(" " + clazz + " ", " ");
							}
						}

						// Only assign if different to avoid unneeded rendering.
						finalValue = jQuery.trim(cur);
						if (curValue !== finalValue) {
							elem.setAttribute("class", finalValue);
						}
					}
				}
			}

			return this;
		},

		toggleClass: function toggleClass(value, stateVal) {
			var type = typeof value === "undefined" ? "undefined" : _typeof(value);

			if (typeof stateVal === "boolean" && type === "string") {
				return stateVal ? this.addClass(value) : this.removeClass(value);
			}

			if (jQuery.isFunction(value)) {
				return this.each(function (i) {
					jQuery(this).toggleClass(value.call(this, i, getClass(this), stateVal), stateVal);
				});
			}

			return this.each(function () {
				var className, i, self, classNames;

				if (type === "string") {

					// Toggle individual class names
					i = 0;
					self = jQuery(this);
					classNames = value.match(rnotwhite) || [];

					while (className = classNames[i++]) {

						// Check each className given, space separated list
						if (self.hasClass(className)) {
							self.removeClass(className);
						} else {
							self.addClass(className);
						}
					}

					// Toggle whole class name
				} else if (value === undefined || type === "boolean") {
					className = getClass(this);
					if (className) {

						// Store className if set
						dataPriv.set(this, "__className__", className);
					}

					// If the element has a class name or if we're passed `false`,
					// then remove the whole classname (if there was one, the above saved it).
					// Otherwise bring back whatever was previously saved (if anything),
					// falling back to the empty string if nothing was stored.
					if (this.setAttribute) {
						this.setAttribute("class", className || value === false ? "" : dataPriv.get(this, "__className__") || "");
					}
				}
			});
		},

		hasClass: function hasClass(selector) {
			var className,
			    elem,
			    i = 0;

			className = " " + selector + " ";
			while (elem = this[i++]) {
				if (elem.nodeType === 1 && (" " + getClass(elem) + " ").replace(rclass, " ").indexOf(className) > -1) {
					return true;
				}
			}

			return false;
		}
	});

	var rreturn = /\r/g,
	    rspaces = /[\x20\t\r\n\f]+/g;

	jQuery.fn.extend({
		val: function val(value) {
			var hooks,
			    ret,
			    isFunction,
			    elem = this[0];

			if (!arguments.length) {
				if (elem) {
					hooks = jQuery.valHooks[elem.type] || jQuery.valHooks[elem.nodeName.toLowerCase()];

					if (hooks && "get" in hooks && (ret = hooks.get(elem, "value")) !== undefined) {
						return ret;
					}

					ret = elem.value;

					return typeof ret === "string" ?

					// Handle most common string cases
					ret.replace(rreturn, "") :

					// Handle cases where value is null/undef or number
					ret == null ? "" : ret;
				}

				return;
			}

			isFunction = jQuery.isFunction(value);

			return this.each(function (i) {
				var val;

				if (this.nodeType !== 1) {
					return;
				}

				if (isFunction) {
					val = value.call(this, i, jQuery(this).val());
				} else {
					val = value;
				}

				// Treat null/undefined as ""; convert numbers to string
				if (val == null) {
					val = "";
				} else if (typeof val === "number") {
					val += "";
				} else if (jQuery.isArray(val)) {
					val = jQuery.map(val, function (value) {
						return value == null ? "" : value + "";
					});
				}

				hooks = jQuery.valHooks[this.type] || jQuery.valHooks[this.nodeName.toLowerCase()];

				// If set returns undefined, fall back to normal setting
				if (!hooks || !("set" in hooks) || hooks.set(this, val, "value") === undefined) {
					this.value = val;
				}
			});
		}
	});

	jQuery.extend({
		valHooks: {
			option: {
				get: function get(elem) {

					var val = jQuery.find.attr(elem, "value");
					return val != null ? val :

					// Support: IE10-11+
					// option.text throws exceptions (#14686, #14858)
					// Strip and collapse whitespace
					// https://html.spec.whatwg.org/#strip-and-collapse-whitespace
					jQuery.trim(jQuery.text(elem)).replace(rspaces, " ");
				}
			},
			select: {
				get: function get(elem) {
					var value,
					    option,
					    options = elem.options,
					    index = elem.selectedIndex,
					    one = elem.type === "select-one" || index < 0,
					    values = one ? null : [],
					    max = one ? index + 1 : options.length,
					    i = index < 0 ? max : one ? index : 0;

					// Loop through all the selected options
					for (; i < max; i++) {
						option = options[i];

						// IE8-9 doesn't update selected after form reset (#2551)
						if ((option.selected || i === index) && (

						// Don't return options that are disabled or in a disabled optgroup
						support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && (!option.parentNode.disabled || !jQuery.nodeName(option.parentNode, "optgroup"))) {

							// Get the specific value for the option
							value = jQuery(option).val();

							// We don't need an array for one selects
							if (one) {
								return value;
							}

							// Multi-Selects return an array
							values.push(value);
						}
					}

					return values;
				},

				set: function set(elem, value) {
					var optionSet,
					    option,
					    options = elem.options,
					    values = jQuery.makeArray(value),
					    i = options.length;

					while (i--) {
						option = options[i];
						if (option.selected = jQuery.inArray(jQuery.valHooks.option.get(option), values) > -1) {
							optionSet = true;
						}
					}

					// Force browsers to behave consistently when non-matching value is set
					if (!optionSet) {
						elem.selectedIndex = -1;
					}
					return values;
				}
			}
		}
	});

	// Radios and checkboxes getter/setter
	jQuery.each(["radio", "checkbox"], function () {
		jQuery.valHooks[this] = {
			set: function set(elem, value) {
				if (jQuery.isArray(value)) {
					return elem.checked = jQuery.inArray(jQuery(elem).val(), value) > -1;
				}
			}
		};
		if (!support.checkOn) {
			jQuery.valHooks[this].get = function (elem) {
				return elem.getAttribute("value") === null ? "on" : elem.value;
			};
		}
	});

	// Return jQuery for attributes-only inclusion


	var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;

	jQuery.extend(jQuery.event, {

		trigger: function trigger(event, data, elem, onlyHandlers) {

			var i,
			    cur,
			    tmp,
			    bubbleType,
			    ontype,
			    handle,
			    special,
			    eventPath = [elem || document],
			    type = hasOwn.call(event, "type") ? event.type : event,
			    namespaces = hasOwn.call(event, "namespace") ? event.namespace.split(".") : [];

			cur = tmp = elem = elem || document;

			// Don't do events on text and comment nodes
			if (elem.nodeType === 3 || elem.nodeType === 8) {
				return;
			}

			// focus/blur morphs to focusin/out; ensure we're not firing them right now
			if (rfocusMorph.test(type + jQuery.event.triggered)) {
				return;
			}

			if (type.indexOf(".") > -1) {

				// Namespaced trigger; create a regexp to match event type in handle()
				namespaces = type.split(".");
				type = namespaces.shift();
				namespaces.sort();
			}
			ontype = type.indexOf(":") < 0 && "on" + type;

			// Caller can pass in a jQuery.Event object, Object, or just an event type string
			event = event[jQuery.expando] ? event : new jQuery.Event(type, (typeof event === "undefined" ? "undefined" : _typeof(event)) === "object" && event);

			// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
			event.isTrigger = onlyHandlers ? 2 : 3;
			event.namespace = namespaces.join(".");
			event.rnamespace = event.namespace ? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null;

			// Clean up the event in case it is being reused
			event.result = undefined;
			if (!event.target) {
				event.target = elem;
			}

			// Clone any incoming data and prepend the event, creating the handler arg list
			data = data == null ? [event] : jQuery.makeArray(data, [event]);

			// Allow special events to draw outside the lines
			special = jQuery.event.special[type] || {};
			if (!onlyHandlers && special.trigger && special.trigger.apply(elem, data) === false) {
				return;
			}

			// Determine event propagation path in advance, per W3C events spec (#9951)
			// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
			if (!onlyHandlers && !special.noBubble && !jQuery.isWindow(elem)) {

				bubbleType = special.delegateType || type;
				if (!rfocusMorph.test(bubbleType + type)) {
					cur = cur.parentNode;
				}
				for (; cur; cur = cur.parentNode) {
					eventPath.push(cur);
					tmp = cur;
				}

				// Only add window if we got to document (e.g., not plain obj or detached DOM)
				if (tmp === (elem.ownerDocument || document)) {
					eventPath.push(tmp.defaultView || tmp.parentWindow || window);
				}
			}

			// Fire handlers on the event path
			i = 0;
			while ((cur = eventPath[i++]) && !event.isPropagationStopped()) {

				event.type = i > 1 ? bubbleType : special.bindType || type;

				// jQuery handler
				handle = (dataPriv.get(cur, "events") || {})[event.type] && dataPriv.get(cur, "handle");
				if (handle) {
					handle.apply(cur, data);
				}

				// Native handler
				handle = ontype && cur[ontype];
				if (handle && handle.apply && acceptData(cur)) {
					event.result = handle.apply(cur, data);
					if (event.result === false) {
						event.preventDefault();
					}
				}
			}
			event.type = type;

			// If nobody prevented the default action, do it now
			if (!onlyHandlers && !event.isDefaultPrevented()) {

				if ((!special._default || special._default.apply(eventPath.pop(), data) === false) && acceptData(elem)) {

					// Call a native DOM method on the target with the same name name as the event.
					// Don't do default actions on window, that's where global variables be (#6170)
					if (ontype && jQuery.isFunction(elem[type]) && !jQuery.isWindow(elem)) {

						// Don't re-trigger an onFOO event when we call its FOO() method
						tmp = elem[ontype];

						if (tmp) {
							elem[ontype] = null;
						}

						// Prevent re-triggering of the same event, since we already bubbled it above
						jQuery.event.triggered = type;
						elem[type]();
						jQuery.event.triggered = undefined;

						if (tmp) {
							elem[ontype] = tmp;
						}
					}
				}
			}

			return event.result;
		},

		// Piggyback on a donor event to simulate a different one
		// Used only for `focus(in | out)` events
		simulate: function simulate(type, elem, event) {
			var e = jQuery.extend(new jQuery.Event(), event, {
				type: type,
				isSimulated: true
			});

			jQuery.event.trigger(e, null, elem);
		}

	});

	jQuery.fn.extend({

		trigger: function trigger(type, data) {
			return this.each(function () {
				jQuery.event.trigger(type, data, this);
			});
		},
		triggerHandler: function triggerHandler(type, data) {
			var elem = this[0];
			if (elem) {
				return jQuery.event.trigger(type, data, elem, true);
			}
		}
	});

	jQuery.each(("blur focus focusin focusout load resize scroll unload click dblclick " + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + "change select submit keydown keypress keyup error contextmenu").split(" "), function (i, name) {

		// Handle event binding
		jQuery.fn[name] = function (data, fn) {
			return arguments.length > 0 ? this.on(name, null, data, fn) : this.trigger(name);
		};
	});

	jQuery.fn.extend({
		hover: function hover(fnOver, fnOut) {
			return this.mouseenter(fnOver).mouseleave(fnOut || fnOver);
		}
	});

	support.focusin = "onfocusin" in window;

	// Support: Firefox
	// Firefox doesn't have focus(in | out) events
	// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
	//
	// Support: Chrome, Safari
	// focus(in | out) events fire after focus & blur events,
	// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
	// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857
	if (!support.focusin) {
		jQuery.each({ focus: "focusin", blur: "focusout" }, function (orig, fix) {

			// Attach a single capturing handler on the document while someone wants focusin/focusout
			var handler = function handler(event) {
				jQuery.event.simulate(fix, event.target, jQuery.event.fix(event));
			};

			jQuery.event.special[fix] = {
				setup: function setup() {
					var doc = this.ownerDocument || this,
					    attaches = dataPriv.access(doc, fix);

					if (!attaches) {
						doc.addEventListener(orig, handler, true);
					}
					dataPriv.access(doc, fix, (attaches || 0) + 1);
				},
				teardown: function teardown() {
					var doc = this.ownerDocument || this,
					    attaches = dataPriv.access(doc, fix) - 1;

					if (!attaches) {
						doc.removeEventListener(orig, handler, true);
						dataPriv.remove(doc, fix);
					} else {
						dataPriv.access(doc, fix, attaches);
					}
				}
			};
		});
	}
	var location = window.location;

	var nonce = jQuery.now();

	var rquery = /\?/;

	// Support: Android 2.3
	// Workaround failure to string-cast null input
	jQuery.parseJSON = function (data) {
		return JSON.parse(data + "");
	};

	// Cross-browser xml parsing
	jQuery.parseXML = function (data) {
		var xml;
		if (!data || typeof data !== "string") {
			return null;
		}

		// Support: IE9
		try {
			xml = new window.DOMParser().parseFromString(data, "text/xml");
		} catch (e) {
			xml = undefined;
		}

		if (!xml || xml.getElementsByTagName("parsererror").length) {
			jQuery.error("Invalid XML: " + data);
		}
		return xml;
	};

	var rhash = /#.*$/,
	    rts = /([?&])_=[^&]*/,
	    rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,


	// #7653, #8125, #8152: local protocol detection
	rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
	    rnoContent = /^(?:GET|HEAD)$/,
	    rprotocol = /^\/\//,


	/* Prefilters
  * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
  * 2) These are called:
  *    - BEFORE asking for a transport
  *    - AFTER param serialization (s.data is a string if s.processData is true)
  * 3) key is the dataType
  * 4) the catchall symbol "*" can be used
  * 5) execution will start with transport dataType and THEN continue down to "*" if needed
  */
	prefilters = {},


	/* Transports bindings
  * 1) key is the dataType
  * 2) the catchall symbol "*" can be used
  * 3) selection will start with transport dataType and THEN go to "*" if needed
  */
	transports = {},


	// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
	allTypes = "*/".concat("*"),


	// Anchor tag for parsing the document origin
	originAnchor = document.createElement("a");
	originAnchor.href = location.href;

	// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
	function addToPrefiltersOrTransports(structure) {

		// dataTypeExpression is optional and defaults to "*"
		return function (dataTypeExpression, func) {

			if (typeof dataTypeExpression !== "string") {
				func = dataTypeExpression;
				dataTypeExpression = "*";
			}

			var dataType,
			    i = 0,
			    dataTypes = dataTypeExpression.toLowerCase().match(rnotwhite) || [];

			if (jQuery.isFunction(func)) {

				// For each dataType in the dataTypeExpression
				while (dataType = dataTypes[i++]) {

					// Prepend if requested
					if (dataType[0] === "+") {
						dataType = dataType.slice(1) || "*";
						(structure[dataType] = structure[dataType] || []).unshift(func);

						// Otherwise append
					} else {
						(structure[dataType] = structure[dataType] || []).push(func);
					}
				}
			}
		};
	}

	// Base inspection function for prefilters and transports
	function inspectPrefiltersOrTransports(structure, options, originalOptions, jqXHR) {

		var inspected = {},
		    seekingTransport = structure === transports;

		function inspect(dataType) {
			var selected;
			inspected[dataType] = true;
			jQuery.each(structure[dataType] || [], function (_, prefilterOrFactory) {
				var dataTypeOrTransport = prefilterOrFactory(options, originalOptions, jqXHR);
				if (typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[dataTypeOrTransport]) {

					options.dataTypes.unshift(dataTypeOrTransport);
					inspect(dataTypeOrTransport);
					return false;
				} else if (seekingTransport) {
					return !(selected = dataTypeOrTransport);
				}
			});
			return selected;
		}

		return inspect(options.dataTypes[0]) || !inspected["*"] && inspect("*");
	}

	// A special extend for ajax options
	// that takes "flat" options (not to be deep extended)
	// Fixes #9887
	function ajaxExtend(target, src) {
		var key,
		    deep,
		    flatOptions = jQuery.ajaxSettings.flatOptions || {};

		for (key in src) {
			if (src[key] !== undefined) {
				(flatOptions[key] ? target : deep || (deep = {}))[key] = src[key];
			}
		}
		if (deep) {
			jQuery.extend(true, target, deep);
		}

		return target;
	}

	/* Handles responses to an ajax request:
  * - finds the right dataType (mediates between content-type and expected dataType)
  * - returns the corresponding response
  */
	function ajaxHandleResponses(s, jqXHR, responses) {

		var ct,
		    type,
		    finalDataType,
		    firstDataType,
		    contents = s.contents,
		    dataTypes = s.dataTypes;

		// Remove auto dataType and get content-type in the process
		while (dataTypes[0] === "*") {
			dataTypes.shift();
			if (ct === undefined) {
				ct = s.mimeType || jqXHR.getResponseHeader("Content-Type");
			}
		}

		// Check if we're dealing with a known content-type
		if (ct) {
			for (type in contents) {
				if (contents[type] && contents[type].test(ct)) {
					dataTypes.unshift(type);
					break;
				}
			}
		}

		// Check to see if we have a response for the expected dataType
		if (dataTypes[0] in responses) {
			finalDataType = dataTypes[0];
		} else {

			// Try convertible dataTypes
			for (type in responses) {
				if (!dataTypes[0] || s.converters[type + " " + dataTypes[0]]) {
					finalDataType = type;
					break;
				}
				if (!firstDataType) {
					firstDataType = type;
				}
			}

			// Or just use first one
			finalDataType = finalDataType || firstDataType;
		}

		// If we found a dataType
		// We add the dataType to the list if needed
		// and return the corresponding response
		if (finalDataType) {
			if (finalDataType !== dataTypes[0]) {
				dataTypes.unshift(finalDataType);
			}
			return responses[finalDataType];
		}
	}

	/* Chain conversions given the request and the original response
  * Also sets the responseXXX fields on the jqXHR instance
  */
	function ajaxConvert(s, response, jqXHR, isSuccess) {
		var conv2,
		    current,
		    conv,
		    tmp,
		    prev,
		    converters = {},


		// Work with a copy of dataTypes in case we need to modify it for conversion
		dataTypes = s.dataTypes.slice();

		// Create converters map with lowercased keys
		if (dataTypes[1]) {
			for (conv in s.converters) {
				converters[conv.toLowerCase()] = s.converters[conv];
			}
		}

		current = dataTypes.shift();

		// Convert to each sequential dataType
		while (current) {

			if (s.responseFields[current]) {
				jqXHR[s.responseFields[current]] = response;
			}

			// Apply the dataFilter if provided
			if (!prev && isSuccess && s.dataFilter) {
				response = s.dataFilter(response, s.dataType);
			}

			prev = current;
			current = dataTypes.shift();

			if (current) {

				// There's only work to do if current dataType is non-auto
				if (current === "*") {

					current = prev;

					// Convert response if prev dataType is non-auto and differs from current
				} else if (prev !== "*" && prev !== current) {

					// Seek a direct converter
					conv = converters[prev + " " + current] || converters["* " + current];

					// If none found, seek a pair
					if (!conv) {
						for (conv2 in converters) {

							// If conv2 outputs current
							tmp = conv2.split(" ");
							if (tmp[1] === current) {

								// If prev can be converted to accepted input
								conv = converters[prev + " " + tmp[0]] || converters["* " + tmp[0]];
								if (conv) {

									// Condense equivalence converters
									if (conv === true) {
										conv = converters[conv2];

										// Otherwise, insert the intermediate dataType
									} else if (converters[conv2] !== true) {
										current = tmp[0];
										dataTypes.unshift(tmp[1]);
									}
									break;
								}
							}
						}
					}

					// Apply converter (if not an equivalence)
					if (conv !== true) {

						// Unless errors are allowed to bubble, catch and return them
						if (conv && s.throws) {
							response = conv(response);
						} else {
							try {
								response = conv(response);
							} catch (e) {
								return {
									state: "parsererror",
									error: conv ? e : "No conversion from " + prev + " to " + current
								};
							}
						}
					}
				}
			}
		}

		return { state: "success", data: response };
	}

	jQuery.extend({

		// Counter for holding the number of active queries
		active: 0,

		// Last-Modified header cache for next request
		lastModified: {},
		etag: {},

		ajaxSettings: {
			url: location.href,
			type: "GET",
			isLocal: rlocalProtocol.test(location.protocol),
			global: true,
			processData: true,
			async: true,
			contentType: "application/x-www-form-urlencoded; charset=UTF-8",
			/*
   timeout: 0,
   data: null,
   dataType: null,
   username: null,
   password: null,
   cache: null,
   throws: false,
   traditional: false,
   headers: {},
   */

			accepts: {
				"*": allTypes,
				text: "text/plain",
				html: "text/html",
				xml: "application/xml, text/xml",
				json: "application/json, text/javascript"
			},

			contents: {
				xml: /\bxml\b/,
				html: /\bhtml/,
				json: /\bjson\b/
			},

			responseFields: {
				xml: "responseXML",
				text: "responseText",
				json: "responseJSON"
			},

			// Data converters
			// Keys separate source (or catchall "*") and destination types with a single space
			converters: {

				// Convert anything to text
				"* text": String,

				// Text to html (true = no transformation)
				"text html": true,

				// Evaluate text as a json expression
				"text json": jQuery.parseJSON,

				// Parse text as xml
				"text xml": jQuery.parseXML
			},

			// For options that shouldn't be deep extended:
			// you can add your own custom options here if
			// and when you create one that shouldn't be
			// deep extended (see ajaxExtend)
			flatOptions: {
				url: true,
				context: true
			}
		},

		// Creates a full fledged settings object into target
		// with both ajaxSettings and settings fields.
		// If target is omitted, writes into ajaxSettings.
		ajaxSetup: function ajaxSetup(target, settings) {
			return settings ?

			// Building a settings object
			ajaxExtend(ajaxExtend(target, jQuery.ajaxSettings), settings) :

			// Extending ajaxSettings
			ajaxExtend(jQuery.ajaxSettings, target);
		},

		ajaxPrefilter: addToPrefiltersOrTransports(prefilters),
		ajaxTransport: addToPrefiltersOrTransports(transports),

		// Main method
		ajax: function ajax(url, options) {

			// If url is an object, simulate pre-1.5 signature
			if ((typeof url === "undefined" ? "undefined" : _typeof(url)) === "object") {
				options = url;
				url = undefined;
			}

			// Force options to be an object
			options = options || {};

			var transport,


			// URL without anti-cache param
			cacheURL,


			// Response headers
			responseHeadersString,
			    responseHeaders,


			// timeout handle
			timeoutTimer,


			// Url cleanup var
			urlAnchor,


			// To know if global events are to be dispatched
			fireGlobals,


			// Loop variable
			i,


			// Create the final options object
			s = jQuery.ajaxSetup({}, options),


			// Callbacks context
			callbackContext = s.context || s,


			// Context for global events is callbackContext if it is a DOM node or jQuery collection
			globalEventContext = s.context && (callbackContext.nodeType || callbackContext.jquery) ? jQuery(callbackContext) : jQuery.event,


			// Deferreds
			deferred = jQuery.Deferred(),
			    completeDeferred = jQuery.Callbacks("once memory"),


			// Status-dependent callbacks
			_statusCode = s.statusCode || {},


			// Headers (they are sent all at once)
			requestHeaders = {},
			    requestHeadersNames = {},


			// The jqXHR state
			state = 0,


			// Default abort message
			strAbort = "canceled",


			// Fake xhr
			jqXHR = {
				readyState: 0,

				// Builds headers hashtable if needed
				getResponseHeader: function getResponseHeader(key) {
					var match;
					if (state === 2) {
						if (!responseHeaders) {
							responseHeaders = {};
							while (match = rheaders.exec(responseHeadersString)) {
								responseHeaders[match[1].toLowerCase()] = match[2];
							}
						}
						match = responseHeaders[key.toLowerCase()];
					}
					return match == null ? null : match;
				},

				// Raw string
				getAllResponseHeaders: function getAllResponseHeaders() {
					return state === 2 ? responseHeadersString : null;
				},

				// Caches the header
				setRequestHeader: function setRequestHeader(name, value) {
					var lname = name.toLowerCase();
					if (!state) {
						name = requestHeadersNames[lname] = requestHeadersNames[lname] || name;
						requestHeaders[name] = value;
					}
					return this;
				},

				// Overrides response content-type header
				overrideMimeType: function overrideMimeType(type) {
					if (!state) {
						s.mimeType = type;
					}
					return this;
				},

				// Status-dependent callbacks
				statusCode: function statusCode(map) {
					var code;
					if (map) {
						if (state < 2) {
							for (code in map) {

								// Lazy-add the new callback in a way that preserves old ones
								_statusCode[code] = [_statusCode[code], map[code]];
							}
						} else {

							// Execute the appropriate callbacks
							jqXHR.always(map[jqXHR.status]);
						}
					}
					return this;
				},

				// Cancel the request
				abort: function abort(statusText) {
					var finalText = statusText || strAbort;
					if (transport) {
						transport.abort(finalText);
					}
					done(0, finalText);
					return this;
				}
			};

			// Attach deferreds
			deferred.promise(jqXHR).complete = completeDeferred.add;
			jqXHR.success = jqXHR.done;
			jqXHR.error = jqXHR.fail;

			// Remove hash character (#7531: and string promotion)
			// Add protocol if not provided (prefilters might expect it)
			// Handle falsy url in the settings object (#10093: consistency with old signature)
			// We also use the url parameter if available
			s.url = ((url || s.url || location.href) + "").replace(rhash, "").replace(rprotocol, location.protocol + "//");

			// Alias method option to type as per ticket #12004
			s.type = options.method || options.type || s.method || s.type;

			// Extract dataTypes list
			s.dataTypes = jQuery.trim(s.dataType || "*").toLowerCase().match(rnotwhite) || [""];

			// A cross-domain request is in order when the origin doesn't match the current origin.
			if (s.crossDomain == null) {
				urlAnchor = document.createElement("a");

				// Support: IE8-11+
				// IE throws exception if url is malformed, e.g. http://example.com:80x/
				try {
					urlAnchor.href = s.url;

					// Support: IE8-11+
					// Anchor's host property isn't correctly set when s.url is relative
					urlAnchor.href = urlAnchor.href;
					s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== urlAnchor.protocol + "//" + urlAnchor.host;
				} catch (e) {

					// If there is an error parsing the URL, assume it is crossDomain,
					// it can be rejected by the transport if it is invalid
					s.crossDomain = true;
				}
			}

			// Convert data if not already a string
			if (s.data && s.processData && typeof s.data !== "string") {
				s.data = jQuery.param(s.data, s.traditional);
			}

			// Apply prefilters
			inspectPrefiltersOrTransports(prefilters, s, options, jqXHR);

			// If request was aborted inside a prefilter, stop there
			if (state === 2) {
				return jqXHR;
			}

			// We can fire global events as of now if asked to
			// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
			fireGlobals = jQuery.event && s.global;

			// Watch for a new set of requests
			if (fireGlobals && jQuery.active++ === 0) {
				jQuery.event.trigger("ajaxStart");
			}

			// Uppercase the type
			s.type = s.type.toUpperCase();

			// Determine if request has content
			s.hasContent = !rnoContent.test(s.type);

			// Save the URL in case we're toying with the If-Modified-Since
			// and/or If-None-Match header later on
			cacheURL = s.url;

			// More options handling for requests with no content
			if (!s.hasContent) {

				// If data is available, append data to url
				if (s.data) {
					cacheURL = s.url += (rquery.test(cacheURL) ? "&" : "?") + s.data;

					// #9682: remove data so that it's not used in an eventual retry
					delete s.data;
				}

				// Add anti-cache in url if needed
				if (s.cache === false) {
					s.url = rts.test(cacheURL) ?

					// If there is already a '_' parameter, set its value
					cacheURL.replace(rts, "$1_=" + nonce++) :

					// Otherwise add one to the end
					cacheURL + (rquery.test(cacheURL) ? "&" : "?") + "_=" + nonce++;
				}
			}

			// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
			if (s.ifModified) {
				if (jQuery.lastModified[cacheURL]) {
					jqXHR.setRequestHeader("If-Modified-Since", jQuery.lastModified[cacheURL]);
				}
				if (jQuery.etag[cacheURL]) {
					jqXHR.setRequestHeader("If-None-Match", jQuery.etag[cacheURL]);
				}
			}

			// Set the correct header, if data is being sent
			if (s.data && s.hasContent && s.contentType !== false || options.contentType) {
				jqXHR.setRequestHeader("Content-Type", s.contentType);
			}

			// Set the Accepts header for the server, depending on the dataType
			jqXHR.setRequestHeader("Accept", s.dataTypes[0] && s.accepts[s.dataTypes[0]] ? s.accepts[s.dataTypes[0]] + (s.dataTypes[0] !== "*" ? ", " + allTypes + "; q=0.01" : "") : s.accepts["*"]);

			// Check for headers option
			for (i in s.headers) {
				jqXHR.setRequestHeader(i, s.headers[i]);
			}

			// Allow custom headers/mimetypes and early abort
			if (s.beforeSend && (s.beforeSend.call(callbackContext, jqXHR, s) === false || state === 2)) {

				// Abort if not done already and return
				return jqXHR.abort();
			}

			// Aborting is no longer a cancellation
			strAbort = "abort";

			// Install callbacks on deferreds
			for (i in { success: 1, error: 1, complete: 1 }) {
				jqXHR[i](s[i]);
			}

			// Get transport
			transport = inspectPrefiltersOrTransports(transports, s, options, jqXHR);

			// If no transport, we auto-abort
			if (!transport) {
				done(-1, "No Transport");
			} else {
				jqXHR.readyState = 1;

				// Send global event
				if (fireGlobals) {
					globalEventContext.trigger("ajaxSend", [jqXHR, s]);
				}

				// If request was aborted inside ajaxSend, stop there
				if (state === 2) {
					return jqXHR;
				}

				// Timeout
				if (s.async && s.timeout > 0) {
					timeoutTimer = window.setTimeout(function () {
						jqXHR.abort("timeout");
					}, s.timeout);
				}

				try {
					state = 1;
					transport.send(requestHeaders, done);
				} catch (e) {

					// Propagate exception as error if not done
					if (state < 2) {
						done(-1, e);

						// Simply rethrow otherwise
					} else {
						throw e;
					}
				}
			}

			// Callback for when everything is done
			function done(status, nativeStatusText, responses, headers) {
				var isSuccess,
				    success,
				    error,
				    response,
				    modified,
				    statusText = nativeStatusText;

				// Called once
				if (state === 2) {
					return;
				}

				// State is "done" now
				state = 2;

				// Clear timeout if it exists
				if (timeoutTimer) {
					window.clearTimeout(timeoutTimer);
				}

				// Dereference transport for early garbage collection
				// (no matter how long the jqXHR object will be used)
				transport = undefined;

				// Cache response headers
				responseHeadersString = headers || "";

				// Set readyState
				jqXHR.readyState = status > 0 ? 4 : 0;

				// Determine if successful
				isSuccess = status >= 200 && status < 300 || status === 304;

				// Get response data
				if (responses) {
					response = ajaxHandleResponses(s, jqXHR, responses);
				}

				// Convert no matter what (that way responseXXX fields are always set)
				response = ajaxConvert(s, response, jqXHR, isSuccess);

				// If successful, handle type chaining
				if (isSuccess) {

					// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
					if (s.ifModified) {
						modified = jqXHR.getResponseHeader("Last-Modified");
						if (modified) {
							jQuery.lastModified[cacheURL] = modified;
						}
						modified = jqXHR.getResponseHeader("etag");
						if (modified) {
							jQuery.etag[cacheURL] = modified;
						}
					}

					// if no content
					if (status === 204 || s.type === "HEAD") {
						statusText = "nocontent";

						// if not modified
					} else if (status === 304) {
						statusText = "notmodified";

						// If we have data, let's convert it
					} else {
						statusText = response.state;
						success = response.data;
						error = response.error;
						isSuccess = !error;
					}
				} else {

					// Extract error from statusText and normalize for non-aborts
					error = statusText;
					if (status || !statusText) {
						statusText = "error";
						if (status < 0) {
							status = 0;
						}
					}
				}

				// Set data for the fake xhr object
				jqXHR.status = status;
				jqXHR.statusText = (nativeStatusText || statusText) + "";

				// Success/Error
				if (isSuccess) {
					deferred.resolveWith(callbackContext, [success, statusText, jqXHR]);
				} else {
					deferred.rejectWith(callbackContext, [jqXHR, statusText, error]);
				}

				// Status-dependent callbacks
				jqXHR.statusCode(_statusCode);
				_statusCode = undefined;

				if (fireGlobals) {
					globalEventContext.trigger(isSuccess ? "ajaxSuccess" : "ajaxError", [jqXHR, s, isSuccess ? success : error]);
				}

				// Complete
				completeDeferred.fireWith(callbackContext, [jqXHR, statusText]);

				if (fireGlobals) {
					globalEventContext.trigger("ajaxComplete", [jqXHR, s]);

					// Handle the global AJAX counter
					if (! --jQuery.active) {
						jQuery.event.trigger("ajaxStop");
					}
				}
			}

			return jqXHR;
		},

		getJSON: function getJSON(url, data, callback) {
			return jQuery.get(url, data, callback, "json");
		},

		getScript: function getScript(url, callback) {
			return jQuery.get(url, undefined, callback, "script");
		}
	});

	jQuery.each(["get", "post"], function (i, method) {
		jQuery[method] = function (url, data, callback, type) {

			// Shift arguments if data argument was omitted
			if (jQuery.isFunction(data)) {
				type = type || callback;
				callback = data;
				data = undefined;
			}

			// The url can be an options object (which then must have .url)
			return jQuery.ajax(jQuery.extend({
				url: url,
				type: method,
				dataType: type,
				data: data,
				success: callback
			}, jQuery.isPlainObject(url) && url));
		};
	});

	jQuery._evalUrl = function (url) {
		return jQuery.ajax({
			url: url,

			// Make this explicit, since user can override this through ajaxSetup (#11264)
			type: "GET",
			dataType: "script",
			async: false,
			global: false,
			"throws": true
		});
	};

	jQuery.fn.extend({
		wrapAll: function wrapAll(html) {
			var wrap;

			if (jQuery.isFunction(html)) {
				return this.each(function (i) {
					jQuery(this).wrapAll(html.call(this, i));
				});
			}

			if (this[0]) {

				// The elements to wrap the target around
				wrap = jQuery(html, this[0].ownerDocument).eq(0).clone(true);

				if (this[0].parentNode) {
					wrap.insertBefore(this[0]);
				}

				wrap.map(function () {
					var elem = this;

					while (elem.firstElementChild) {
						elem = elem.firstElementChild;
					}

					return elem;
				}).append(this);
			}

			return this;
		},

		wrapInner: function wrapInner(html) {
			if (jQuery.isFunction(html)) {
				return this.each(function (i) {
					jQuery(this).wrapInner(html.call(this, i));
				});
			}

			return this.each(function () {
				var self = jQuery(this),
				    contents = self.contents();

				if (contents.length) {
					contents.wrapAll(html);
				} else {
					self.append(html);
				}
			});
		},

		wrap: function wrap(html) {
			var isFunction = jQuery.isFunction(html);

			return this.each(function (i) {
				jQuery(this).wrapAll(isFunction ? html.call(this, i) : html);
			});
		},

		unwrap: function unwrap() {
			return this.parent().each(function () {
				if (!jQuery.nodeName(this, "body")) {
					jQuery(this).replaceWith(this.childNodes);
				}
			}).end();
		}
	});

	jQuery.expr.filters.hidden = function (elem) {
		return !jQuery.expr.filters.visible(elem);
	};
	jQuery.expr.filters.visible = function (elem) {

		// Support: Opera <= 12.12
		// Opera reports offsetWidths and offsetHeights less than zero on some elements
		// Use OR instead of AND as the element is not visible if either is true
		// See tickets #10406 and #13132
		return elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0;
	};

	var r20 = /%20/g,
	    rbracket = /\[\]$/,
	    rCRLF = /\r?\n/g,
	    rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
	    rsubmittable = /^(?:input|select|textarea|keygen)/i;

	function buildParams(prefix, obj, traditional, add) {
		var name;

		if (jQuery.isArray(obj)) {

			// Serialize array item.
			jQuery.each(obj, function (i, v) {
				if (traditional || rbracket.test(prefix)) {

					// Treat each array item as a scalar.
					add(prefix, v);
				} else {

					// Item is non-scalar (array or object), encode its numeric index.
					buildParams(prefix + "[" + ((typeof v === "undefined" ? "undefined" : _typeof(v)) === "object" && v != null ? i : "") + "]", v, traditional, add);
				}
			});
		} else if (!traditional && jQuery.type(obj) === "object") {

			// Serialize object item.
			for (name in obj) {
				buildParams(prefix + "[" + name + "]", obj[name], traditional, add);
			}
		} else {

			// Serialize scalar item.
			add(prefix, obj);
		}
	}

	// Serialize an array of form elements or a set of
	// key/values into a query string
	jQuery.param = function (a, traditional) {
		var prefix,
		    s = [],
		    add = function add(key, value) {

			// If value is a function, invoke it and return its value
			value = jQuery.isFunction(value) ? value() : value == null ? "" : value;
			s[s.length] = encodeURIComponent(key) + "=" + encodeURIComponent(value);
		};

		// Set traditional to true for jQuery <= 1.3.2 behavior.
		if (traditional === undefined) {
			traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;
		}

		// If an array was passed in, assume that it is an array of form elements.
		if (jQuery.isArray(a) || a.jquery && !jQuery.isPlainObject(a)) {

			// Serialize the form elements
			jQuery.each(a, function () {
				add(this.name, this.value);
			});
		} else {

			// If traditional, encode the "old" way (the way 1.3.2 or older
			// did it), otherwise encode params recursively.
			for (prefix in a) {
				buildParams(prefix, a[prefix], traditional, add);
			}
		}

		// Return the resulting serialization
		return s.join("&").replace(r20, "+");
	};

	jQuery.fn.extend({
		serialize: function serialize() {
			return jQuery.param(this.serializeArray());
		},
		serializeArray: function serializeArray() {
			return this.map(function () {

				// Can add propHook for "elements" to filter or add form elements
				var elements = jQuery.prop(this, "elements");
				return elements ? jQuery.makeArray(elements) : this;
			}).filter(function () {
				var type = this.type;

				// Use .is( ":disabled" ) so that fieldset[disabled] works
				return this.name && !jQuery(this).is(":disabled") && rsubmittable.test(this.nodeName) && !rsubmitterTypes.test(type) && (this.checked || !rcheckableType.test(type));
			}).map(function (i, elem) {
				var val = jQuery(this).val();

				return val == null ? null : jQuery.isArray(val) ? jQuery.map(val, function (val) {
					return { name: elem.name, value: val.replace(rCRLF, "\r\n") };
				}) : { name: elem.name, value: val.replace(rCRLF, "\r\n") };
			}).get();
		}
	});

	jQuery.ajaxSettings.xhr = function () {
		try {
			return new window.XMLHttpRequest();
		} catch (e) {}
	};

	var xhrSuccessStatus = {

		// File protocol always yields status code 0, assume 200
		0: 200,

		// Support: IE9
		// #1450: sometimes IE returns 1223 when it should be 204
		1223: 204
	},
	    xhrSupported = jQuery.ajaxSettings.xhr();

	support.cors = !!xhrSupported && "withCredentials" in xhrSupported;
	support.ajax = xhrSupported = !!xhrSupported;

	jQuery.ajaxTransport(function (options) {
		var _callback, errorCallback;

		// Cross domain only allowed if supported through XMLHttpRequest
		if (support.cors || xhrSupported && !options.crossDomain) {
			return {
				send: function send(headers, complete) {
					var i,
					    xhr = options.xhr();

					xhr.open(options.type, options.url, options.async, options.username, options.password);

					// Apply custom fields if provided
					if (options.xhrFields) {
						for (i in options.xhrFields) {
							xhr[i] = options.xhrFields[i];
						}
					}

					// Override mime type if needed
					if (options.mimeType && xhr.overrideMimeType) {
						xhr.overrideMimeType(options.mimeType);
					}

					// X-Requested-With header
					// For cross-domain requests, seeing as conditions for a preflight are
					// akin to a jigsaw puzzle, we simply never set it to be sure.
					// (it can always be set on a per-request basis or even using ajaxSetup)
					// For same-domain requests, won't change header if already provided.
					if (!options.crossDomain && !headers["X-Requested-With"]) {
						headers["X-Requested-With"] = "XMLHttpRequest";
					}

					// Set headers
					for (i in headers) {
						xhr.setRequestHeader(i, headers[i]);
					}

					// Callback
					_callback = function callback(type) {
						return function () {
							if (_callback) {
								_callback = errorCallback = xhr.onload = xhr.onerror = xhr.onabort = xhr.onreadystatechange = null;

								if (type === "abort") {
									xhr.abort();
								} else if (type === "error") {

									// Support: IE9
									// On a manual native abort, IE9 throws
									// errors on any property access that is not readyState
									if (typeof xhr.status !== "number") {
										complete(0, "error");
									} else {
										complete(

										// File: protocol always yields status 0; see #8605, #14207
										xhr.status, xhr.statusText);
									}
								} else {
									complete(xhrSuccessStatus[xhr.status] || xhr.status, xhr.statusText,

									// Support: IE9 only
									// IE9 has no XHR2 but throws on binary (trac-11426)
									// For XHR2 non-text, let the caller handle it (gh-2498)
									(xhr.responseType || "text") !== "text" || typeof xhr.responseText !== "string" ? { binary: xhr.response } : { text: xhr.responseText }, xhr.getAllResponseHeaders());
								}
							}
						};
					};

					// Listen to events
					xhr.onload = _callback();
					errorCallback = xhr.onerror = _callback("error");

					// Support: IE9
					// Use onreadystatechange to replace onabort
					// to handle uncaught aborts
					if (xhr.onabort !== undefined) {
						xhr.onabort = errorCallback;
					} else {
						xhr.onreadystatechange = function () {

							// Check readyState before timeout as it changes
							if (xhr.readyState === 4) {

								// Allow onerror to be called first,
								// but that will not handle a native abort
								// Also, save errorCallback to a variable
								// as xhr.onerror cannot be accessed
								window.setTimeout(function () {
									if (_callback) {
										errorCallback();
									}
								});
							}
						};
					}

					// Create the abort callback
					_callback = _callback("abort");

					try {

						// Do send the request (this may raise an exception)
						xhr.send(options.hasContent && options.data || null);
					} catch (e) {

						// #14683: Only rethrow if this hasn't been notified as an error yet
						if (_callback) {
							throw e;
						}
					}
				},

				abort: function abort() {
					if (_callback) {
						_callback();
					}
				}
			};
		}
	});

	// Install script dataType
	jQuery.ajaxSetup({
		accepts: {
			script: "text/javascript, application/javascript, " + "application/ecmascript, application/x-ecmascript"
		},
		contents: {
			script: /\b(?:java|ecma)script\b/
		},
		converters: {
			"text script": function textScript(text) {
				jQuery.globalEval(text);
				return text;
			}
		}
	});

	// Handle cache's special case and crossDomain
	jQuery.ajaxPrefilter("script", function (s) {
		if (s.cache === undefined) {
			s.cache = false;
		}
		if (s.crossDomain) {
			s.type = "GET";
		}
	});

	// Bind script tag hack transport
	jQuery.ajaxTransport("script", function (s) {

		// This transport only deals with cross domain requests
		if (s.crossDomain) {
			var script, _callback2;
			return {
				send: function send(_, complete) {
					script = jQuery("<script>").prop({
						charset: s.scriptCharset,
						src: s.url
					}).on("load error", _callback2 = function callback(evt) {
						script.remove();
						_callback2 = null;
						if (evt) {
							complete(evt.type === "error" ? 404 : 200, evt.type);
						}
					});

					// Use native DOM manipulation to avoid our domManip AJAX trickery
					document.head.appendChild(script[0]);
				},
				abort: function abort() {
					if (_callback2) {
						_callback2();
					}
				}
			};
		}
	});

	var oldCallbacks = [],
	    rjsonp = /(=)\?(?=&|$)|\?\?/;

	// Default jsonp settings
	jQuery.ajaxSetup({
		jsonp: "callback",
		jsonpCallback: function jsonpCallback() {
			var callback = oldCallbacks.pop() || jQuery.expando + "_" + nonce++;
			this[callback] = true;
			return callback;
		}
	});

	// Detect, normalize options and install callbacks for jsonp requests
	jQuery.ajaxPrefilter("json jsonp", function (s, originalSettings, jqXHR) {

		var callbackName,
		    overwritten,
		    responseContainer,
		    jsonProp = s.jsonp !== false && (rjsonp.test(s.url) ? "url" : typeof s.data === "string" && (s.contentType || "").indexOf("application/x-www-form-urlencoded") === 0 && rjsonp.test(s.data) && "data");

		// Handle iff the expected data type is "jsonp" or we have a parameter to set
		if (jsonProp || s.dataTypes[0] === "jsonp") {

			// Get callback name, remembering preexisting value associated with it
			callbackName = s.jsonpCallback = jQuery.isFunction(s.jsonpCallback) ? s.jsonpCallback() : s.jsonpCallback;

			// Insert callback into url or form data
			if (jsonProp) {
				s[jsonProp] = s[jsonProp].replace(rjsonp, "$1" + callbackName);
			} else if (s.jsonp !== false) {
				s.url += (rquery.test(s.url) ? "&" : "?") + s.jsonp + "=" + callbackName;
			}

			// Use data converter to retrieve json after script execution
			s.converters["script json"] = function () {
				if (!responseContainer) {
					jQuery.error(callbackName + " was not called");
				}
				return responseContainer[0];
			};

			// Force json dataType
			s.dataTypes[0] = "json";

			// Install callback
			overwritten = window[callbackName];
			window[callbackName] = function () {
				responseContainer = arguments;
			};

			// Clean-up function (fires after converters)
			jqXHR.always(function () {

				// If previous value didn't exist - remove it
				if (overwritten === undefined) {
					jQuery(window).removeProp(callbackName);

					// Otherwise restore preexisting value
				} else {
					window[callbackName] = overwritten;
				}

				// Save back as free
				if (s[callbackName]) {

					// Make sure that re-using the options doesn't screw things around
					s.jsonpCallback = originalSettings.jsonpCallback;

					// Save the callback name for future use
					oldCallbacks.push(callbackName);
				}

				// Call if it was a function and we have a response
				if (responseContainer && jQuery.isFunction(overwritten)) {
					overwritten(responseContainer[0]);
				}

				responseContainer = overwritten = undefined;
			});

			// Delegate to script
			return "script";
		}
	});

	// Argument "data" should be string of html
	// context (optional): If specified, the fragment will be created in this context,
	// defaults to document
	// keepScripts (optional): If true, will include scripts passed in the html string
	jQuery.parseHTML = function (data, context, keepScripts) {
		if (!data || typeof data !== "string") {
			return null;
		}
		if (typeof context === "boolean") {
			keepScripts = context;
			context = false;
		}
		context = context || document;

		var parsed = rsingleTag.exec(data),
		    scripts = !keepScripts && [];

		// Single tag
		if (parsed) {
			return [context.createElement(parsed[1])];
		}

		parsed = buildFragment([data], context, scripts);

		if (scripts && scripts.length) {
			jQuery(scripts).remove();
		}

		return jQuery.merge([], parsed.childNodes);
	};

	// Keep a copy of the old load method
	var _load = jQuery.fn.load;

	/**
  * Load a url into a page
  */
	jQuery.fn.load = function (url, params, callback) {
		if (typeof url !== "string" && _load) {
			return _load.apply(this, arguments);
		}

		var selector,
		    type,
		    response,
		    self = this,
		    off = url.indexOf(" ");

		if (off > -1) {
			selector = jQuery.trim(url.slice(off));
			url = url.slice(0, off);
		}

		// If it's a function
		if (jQuery.isFunction(params)) {

			// We assume that it's the callback
			callback = params;
			params = undefined;

			// Otherwise, build a param string
		} else if (params && (typeof params === "undefined" ? "undefined" : _typeof(params)) === "object") {
			type = "POST";
		}

		// If we have elements to modify, make the request
		if (self.length > 0) {
			jQuery.ajax({
				url: url,

				// If "type" variable is undefined, then "GET" method will be used.
				// Make value of this field explicit since
				// user can override it through ajaxSetup method
				type: type || "GET",
				dataType: "html",
				data: params
			}).done(function (responseText) {

				// Save response for use in complete callback
				response = arguments;

				self.html(selector ?

				// If a selector was specified, locate the right elements in a dummy div
				// Exclude scripts to avoid IE 'Permission Denied' errors
				jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) :

				// Otherwise use the full result
				responseText);

				// If the request succeeds, this function gets "data", "status", "jqXHR"
				// but they are ignored because response was set above.
				// If it fails, this function gets "jqXHR", "status", "error"
			}).always(callback && function (jqXHR, status) {
				self.each(function () {
					callback.apply(this, response || [jqXHR.responseText, status, jqXHR]);
				});
			});
		}

		return this;
	};

	// Attach a bunch of functions for handling common AJAX events
	jQuery.each(["ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend"], function (i, type) {
		jQuery.fn[type] = function (fn) {
			return this.on(type, fn);
		};
	});

	jQuery.expr.filters.animated = function (elem) {
		return jQuery.grep(jQuery.timers, function (fn) {
			return elem === fn.elem;
		}).length;
	};

	/**
  * Gets a window from an element
  */
	function getWindow(elem) {
		return jQuery.isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView;
	}

	jQuery.offset = {
		setOffset: function setOffset(elem, options, i) {
			var curPosition,
			    curLeft,
			    curCSSTop,
			    curTop,
			    curOffset,
			    curCSSLeft,
			    calculatePosition,
			    position = jQuery.css(elem, "position"),
			    curElem = jQuery(elem),
			    props = {};

			// Set position first, in-case top/left are set even on static elem
			if (position === "static") {
				elem.style.position = "relative";
			}

			curOffset = curElem.offset();
			curCSSTop = jQuery.css(elem, "top");
			curCSSLeft = jQuery.css(elem, "left");
			calculatePosition = (position === "absolute" || position === "fixed") && (curCSSTop + curCSSLeft).indexOf("auto") > -1;

			// Need to be able to calculate position if either
			// top or left is auto and position is either absolute or fixed
			if (calculatePosition) {
				curPosition = curElem.position();
				curTop = curPosition.top;
				curLeft = curPosition.left;
			} else {
				curTop = parseFloat(curCSSTop) || 0;
				curLeft = parseFloat(curCSSLeft) || 0;
			}

			if (jQuery.isFunction(options)) {

				// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
				options = options.call(elem, i, jQuery.extend({}, curOffset));
			}

			if (options.top != null) {
				props.top = options.top - curOffset.top + curTop;
			}
			if (options.left != null) {
				props.left = options.left - curOffset.left + curLeft;
			}

			if ("using" in options) {
				options.using.call(elem, props);
			} else {
				curElem.css(props);
			}
		}
	};

	jQuery.fn.extend({
		offset: function offset(options) {
			if (arguments.length) {
				return options === undefined ? this : this.each(function (i) {
					jQuery.offset.setOffset(this, options, i);
				});
			}

			var docElem,
			    win,
			    elem = this[0],
			    box = { top: 0, left: 0 },
			    doc = elem && elem.ownerDocument;

			if (!doc) {
				return;
			}

			docElem = doc.documentElement;

			// Make sure it's not a disconnected DOM node
			if (!jQuery.contains(docElem, elem)) {
				return box;
			}

			box = elem.getBoundingClientRect();
			win = getWindow(doc);
			return {
				top: box.top + win.pageYOffset - docElem.clientTop,
				left: box.left + win.pageXOffset - docElem.clientLeft
			};
		},

		position: function position() {
			if (!this[0]) {
				return;
			}

			var offsetParent,
			    offset,
			    elem = this[0],
			    parentOffset = { top: 0, left: 0 };

			// Fixed elements are offset from window (parentOffset = {top:0, left: 0},
			// because it is its only offset parent
			if (jQuery.css(elem, "position") === "fixed") {

				// Assume getBoundingClientRect is there when computed position is fixed
				offset = elem.getBoundingClientRect();
			} else {

				// Get *real* offsetParent
				offsetParent = this.offsetParent();

				// Get correct offsets
				offset = this.offset();
				if (!jQuery.nodeName(offsetParent[0], "html")) {
					parentOffset = offsetParent.offset();
				}

				// Add offsetParent borders
				parentOffset.top += jQuery.css(offsetParent[0], "borderTopWidth", true);
				parentOffset.left += jQuery.css(offsetParent[0], "borderLeftWidth", true);
			}

			// Subtract parent offsets and element margins
			return {
				top: offset.top - parentOffset.top - jQuery.css(elem, "marginTop", true),
				left: offset.left - parentOffset.left - jQuery.css(elem, "marginLeft", true)
			};
		},

		// This method will return documentElement in the following cases:
		// 1) For the element inside the iframe without offsetParent, this method will return
		//    documentElement of the parent window
		// 2) For the hidden or detached element
		// 3) For body or html element, i.e. in case of the html node - it will return itself
		//
		// but those exceptions were never presented as a real life use-cases
		// and might be considered as more preferable results.
		//
		// This logic, however, is not guaranteed and can change at any point in the future
		offsetParent: function offsetParent() {
			return this.map(function () {
				var offsetParent = this.offsetParent;

				while (offsetParent && jQuery.css(offsetParent, "position") === "static") {
					offsetParent = offsetParent.offsetParent;
				}

				return offsetParent || documentElement;
			});
		}
	});

	// Create scrollLeft and scrollTop methods
	jQuery.each({ scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function (method, prop) {
		var top = "pageYOffset" === prop;

		jQuery.fn[method] = function (val) {
			return access(this, function (elem, method, val) {
				var win = getWindow(elem);

				if (val === undefined) {
					return win ? win[prop] : elem[method];
				}

				if (win) {
					win.scrollTo(!top ? val : win.pageXOffset, top ? val : win.pageYOffset);
				} else {
					elem[method] = val;
				}
			}, method, val, arguments.length);
		};
	});

	// Support: Safari<7-8+, Chrome<37-44+
	// Add the top/left cssHooks using jQuery.fn.position
	// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
	// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280
	// getComputedStyle returns percent when specified for top/left/bottom/right;
	// rather than make the css module depend on the offset module, just check for it here
	jQuery.each(["top", "left"], function (i, prop) {
		jQuery.cssHooks[prop] = addGetHookIf(support.pixelPosition, function (elem, computed) {
			if (computed) {
				computed = curCSS(elem, prop);

				// If curCSS returns percentage, fallback to offset
				return rnumnonpx.test(computed) ? jQuery(elem).position()[prop] + "px" : computed;
			}
		});
	});

	// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
	jQuery.each({ Height: "height", Width: "width" }, function (name, type) {
		jQuery.each({ padding: "inner" + name, content: type, "": "outer" + name }, function (defaultExtra, funcName) {

			// Margin is only for outerHeight, outerWidth
			jQuery.fn[funcName] = function (margin, value) {
				var chainable = arguments.length && (defaultExtra || typeof margin !== "boolean"),
				    extra = defaultExtra || (margin === true || value === true ? "margin" : "border");

				return access(this, function (elem, type, value) {
					var doc;

					if (jQuery.isWindow(elem)) {

						// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there
						// isn't a whole lot we can do. See pull request at this URL for discussion:
						// https://github.com/jquery/jquery/pull/764
						return elem.document.documentElement["client" + name];
					}

					// Get document width or height
					if (elem.nodeType === 9) {
						doc = elem.documentElement;

						// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],
						// whichever is greatest
						return Math.max(elem.body["scroll" + name], doc["scroll" + name], elem.body["offset" + name], doc["offset" + name], doc["client" + name]);
					}

					return value === undefined ?

					// Get width or height on the element, requesting but not forcing parseFloat
					jQuery.css(elem, type, extra) :

					// Set width or height on the element
					jQuery.style(elem, type, value, extra);
				}, type, chainable ? margin : undefined, chainable, null);
			};
		});
	});

	jQuery.fn.extend({

		bind: function bind(types, data, fn) {
			return this.on(types, null, data, fn);
		},
		unbind: function unbind(types, fn) {
			return this.off(types, null, fn);
		},

		delegate: function delegate(selector, types, data, fn) {
			return this.on(types, selector, data, fn);
		},
		undelegate: function undelegate(selector, types, fn) {

			// ( namespace ) or ( selector, types [, fn] )
			return arguments.length === 1 ? this.off(selector, "**") : this.off(types, selector || "**", fn);
		},
		size: function size() {
			return this.length;
		}
	});

	jQuery.fn.andSelf = jQuery.fn.addBack;

	// Register as a named AMD module, since jQuery can be concatenated with other
	// files that may use define, but not via a proper concatenation script that
	// understands anonymous AMD modules. A named AMD is safest and most robust
	// way to register. Lowercase jquery is used because AMD module names are
	// derived from file names, and jQuery is normally delivered in a lowercase
	// file name. Do this after creating the global so that if an AMD module wants
	// to call noConflict to hide this version of jQuery, it will work.

	// Note that for maximum portability, libraries that are not jQuery should
	// declare themselves as anonymous modules, and avoid setting a global if an
	// AMD loader is present. jQuery is a special case. For more information, see
	// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon

	if (typeof define === "function" && define.amd) {
		define("jquery", [], function () {
			return jQuery;
		});
	}

	var

	// Map over jQuery in case of overwrite
	_jQuery = window.jQuery,


	// Map over the $ in case of overwrite
	_$ = window.$;

	jQuery.noConflict = function (deep) {
		if (window.$ === jQuery) {
			window.$ = _$;
		}

		if (deep && window.jQuery === jQuery) {
			window.jQuery = _jQuery;
		}

		return jQuery;
	};

	// Expose jQuery and $ identifiers, even in AMD
	// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
	// and CommonJS for browser emulators (#13566)
	if (!noGlobal) {
		window.jQuery = window.$ = jQuery;
	}

	return jQuery;
});
'use strict';

window.whatInput = function () {

  'use strict';

  /*
    ---------------
    variables
    ---------------
  */

  // array of actively pressed keys

  var activeKeys = [];

  // cache document.body
  var body;

  // boolean: true if touch buffer timer is running
  var buffer = false;

  // the last used input type
  var currentInput = null;

  // `input` types that don't accept text
  var nonTypingInputs = ['button', 'checkbox', 'file', 'image', 'radio', 'reset', 'submit'];

  // detect version of mouse wheel event to use
  // via https://developer.mozilla.org/en-US/docs/Web/Events/wheel
  var mouseWheel = detectWheel();

  // list of modifier keys commonly used with the mouse and
  // can be safely ignored to prevent false keyboard detection
  var ignoreMap = [16, // shift
  17, // control
  18, // alt
  91, // Windows key / left Apple cmd
  93 // Windows menu / right Apple cmd
  ];

  // mapping of events to input types
  var inputMap = {
    'keydown': 'keyboard',
    'keyup': 'keyboard',
    'mousedown': 'mouse',
    'mousemove': 'mouse',
    'MSPointerDown': 'pointer',
    'MSPointerMove': 'pointer',
    'pointerdown': 'pointer',
    'pointermove': 'pointer',
    'touchstart': 'touch'
  };

  // add correct mouse wheel event mapping to `inputMap`
  inputMap[detectWheel()] = 'mouse';

  // array of all used input types
  var inputTypes = [];

  // mapping of key codes to a common name
  var keyMap = {
    9: 'tab',
    13: 'enter',
    16: 'shift',
    27: 'esc',
    32: 'space',
    37: 'left',
    38: 'up',
    39: 'right',
    40: 'down'
  };

  // map of IE 10 pointer events
  var pointerMap = {
    2: 'touch',
    3: 'touch', // treat pen like touch
    4: 'mouse'
  };

  // touch buffer timer
  var timer;

  /*
    ---------------
    functions
    ---------------
  */

  // allows events that are also triggered to be filtered out for `touchstart`
  function eventBuffer() {
    clearTimer();
    setInput(event);

    buffer = true;
    timer = window.setTimeout(function () {
      buffer = false;
    }, 650);
  }

  function bufferedEvent(event) {
    if (!buffer) setInput(event);
  }

  function unBufferedEvent(event) {
    clearTimer();
    setInput(event);
  }

  function clearTimer() {
    window.clearTimeout(timer);
  }

  function setInput(event) {
    var eventKey = key(event);
    var value = inputMap[event.type];
    if (value === 'pointer') value = pointerType(event);

    // don't do anything if the value matches the input type already set
    if (currentInput !== value) {
      var eventTarget = target(event);
      var eventTargetNode = eventTarget.nodeName.toLowerCase();
      var eventTargetType = eventTargetNode === 'input' ? eventTarget.getAttribute('type') : null;

      if ( // only if the user flag to allow typing in form fields isn't set
      !body.hasAttribute('data-whatinput-formtyping') &&

      // only if currentInput has a value
      currentInput &&

      // only if the input is `keyboard`
      value === 'keyboard' &&

      // not if the key is `TAB`
      keyMap[eventKey] !== 'tab' && (

      // only if the target is a form input that accepts text
      eventTargetNode === 'textarea' || eventTargetNode === 'select' || eventTargetNode === 'input' && nonTypingInputs.indexOf(eventTargetType) < 0) ||
      // ignore modifier keys
      ignoreMap.indexOf(eventKey) > -1) {
        // ignore keyboard typing
      } else {
        switchInput(value);
      }
    }

    if (value === 'keyboard') logKeys(eventKey);
  }

  function switchInput(string) {
    currentInput = string;
    body.setAttribute('data-whatinput', currentInput);

    if (inputTypes.indexOf(currentInput) === -1) inputTypes.push(currentInput);
  }

  function key(event) {
    return event.keyCode ? event.keyCode : event.which;
  }

  function target(event) {
    return event.target || event.srcElement;
  }

  function pointerType(event) {
    if (typeof event.pointerType === 'number') {
      return pointerMap[event.pointerType];
    } else {
      return event.pointerType === 'pen' ? 'touch' : event.pointerType; // treat pen like touch
    }
  }

  // keyboard logging
  function logKeys(eventKey) {
    if (activeKeys.indexOf(keyMap[eventKey]) === -1 && keyMap[eventKey]) activeKeys.push(keyMap[eventKey]);
  }

  function unLogKeys(event) {
    var eventKey = key(event);
    var arrayPos = activeKeys.indexOf(keyMap[eventKey]);

    if (arrayPos !== -1) activeKeys.splice(arrayPos, 1);
  }

  function bindEvents() {
    body = document.body;

    // pointer events (mouse, pen, touch)
    if (window.PointerEvent) {
      body.addEventListener('pointerdown', bufferedEvent);
      body.addEventListener('pointermove', bufferedEvent);
    } else if (window.MSPointerEvent) {
      body.addEventListener('MSPointerDown', bufferedEvent);
      body.addEventListener('MSPointerMove', bufferedEvent);
    } else {

      // mouse events
      body.addEventListener('mousedown', bufferedEvent);
      body.addEventListener('mousemove', bufferedEvent);

      // touch events
      if ('ontouchstart' in window) {
        body.addEventListener('touchstart', eventBuffer);
      }
    }

    // mouse wheel
    body.addEventListener(mouseWheel, bufferedEvent);

    // keyboard events
    body.addEventListener('keydown', unBufferedEvent);
    body.addEventListener('keyup', unBufferedEvent);
    document.addEventListener('keyup', unLogKeys);
  }

  /*
    ---------------
    utilities
    ---------------
  */

  // detect version of mouse wheel event to use
  // via https://developer.mozilla.org/en-US/docs/Web/Events/wheel
  function detectWheel() {
    return mouseWheel = 'onwheel' in document.createElement('div') ? 'wheel' : // Modern browsers support "wheel"

    document.onmousewheel !== undefined ? 'mousewheel' : // Webkit and IE support at least "mousewheel"
    'DOMMouseScroll'; // let's assume that remaining browsers are older Firefox
  }

  /*
    ---------------
    init
      don't start script unless browser cuts the mustard,
    also passes if polyfills are used
    ---------------
  */

  if ('addEventListener' in window && Array.prototype.indexOf) {

    // if the dom is already ready already (script was placed at bottom of <body>)
    if (document.body) {
      bindEvents();

      // otherwise wait for the dom to load (script was placed in the <head>)
    } else {
      document.addEventListener('DOMContentLoaded', bindEvents);
    }
  }

  /*
    ---------------
    api
    ---------------
  */

  return {

    // returns string: the current input type
    ask: function ask() {
      return currentInput;
    },

    // returns array: currently pressed keys
    keys: function keys() {
      return activeKeys;
    },

    // returns array: all the detected input types
    types: function types() {
      return inputTypes;
    },

    // accepts string: manually set the input type
    set: switchInput
  };
}();
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };

!function ($) {

  "use strict";

  var FOUNDATION_VERSION = '6.2.2';

  // Global Foundation object
  // This is attached to the window, or used as a module for AMD/Browserify
  var Foundation = {
    version: FOUNDATION_VERSION,

    /**
     * Stores initialized plugins.
     */
    _plugins: {},

    /**
     * Stores generated unique ids for plugin instances
     */
    _uuids: [],

    /**
     * Returns a boolean for RTL support
     */
    rtl: function rtl() {
      return $('html').attr('dir') === 'rtl';
    },
    /**
     * Defines a Foundation plugin, adding it to the `Foundation` namespace and the list of plugins to initialize when reflowing.
     * @param {Object} plugin - The constructor of the plugin.
     */
    plugin: function plugin(_plugin, name) {
      // Object key to use when adding to global Foundation object
      // Examples: Foundation.Reveal, Foundation.OffCanvas
      var className = name || functionName(_plugin);
      // Object key to use when storing the plugin, also used to create the identifying data attribute for the plugin
      // Examples: data-reveal, data-off-canvas
      var attrName = hyphenate(className);

      // Add to the Foundation object and the plugins list (for reflowing)
      this._plugins[attrName] = this[className] = _plugin;
    },
    /**
     * @function
     * Populates the _uuids array with pointers to each individual plugin instance.
     * Adds the `zfPlugin` data-attribute to programmatically created plugins to allow use of $(selector).foundation(method) calls.
     * Also fires the initialization event for each plugin, consolidating repetitive code.
     * @param {Object} plugin - an instance of a plugin, usually `this` in context.
     * @param {String} name - the name of the plugin, passed as a camelCased string.
     * @fires Plugin#init
     */
    registerPlugin: function registerPlugin(plugin, name) {
      var pluginName = name ? hyphenate(name) : functionName(plugin.constructor).toLowerCase();
      plugin.uuid = this.GetYoDigits(6, pluginName);

      if (!plugin.$element.attr('data-' + pluginName)) {
        plugin.$element.attr('data-' + pluginName, plugin.uuid);
      }
      if (!plugin.$element.data('zfPlugin')) {
        plugin.$element.data('zfPlugin', plugin);
      }
      /**
       * Fires when the plugin has initialized.
       * @event Plugin#init
       */
      plugin.$element.trigger('init.zf.' + pluginName);

      this._uuids.push(plugin.uuid);

      return;
    },
    /**
     * @function
     * Removes the plugins uuid from the _uuids array.
     * Removes the zfPlugin data attribute, as well as the data-plugin-name attribute.
     * Also fires the destroyed event for the plugin, consolidating repetitive code.
     * @param {Object} plugin - an instance of a plugin, usually `this` in context.
     * @fires Plugin#destroyed
     */
    unregisterPlugin: function unregisterPlugin(plugin) {
      var pluginName = hyphenate(functionName(plugin.$element.data('zfPlugin').constructor));

      this._uuids.splice(this._uuids.indexOf(plugin.uuid), 1);
      plugin.$element.removeAttr('data-' + pluginName).removeData('zfPlugin')
      /**
       * Fires when the plugin has been destroyed.
       * @event Plugin#destroyed
       */
      .trigger('destroyed.zf.' + pluginName);
      for (var prop in plugin) {
        plugin[prop] = null; //clean up script to prep for garbage collection.
      }
      return;
    },

    /**
     * @function
     * Causes one or more active plugins to re-initialize, resetting event listeners, recalculating positions, etc.
     * @param {String} plugins - optional string of an individual plugin key, attained by calling `$(element).data('pluginName')`, or string of a plugin class i.e. `'dropdown'`
     * @default If no argument is passed, reflow all currently active plugins.
     */
    reInit: function reInit(plugins) {
      var isJQ = plugins instanceof $;
      try {
        if (isJQ) {
          plugins.each(function () {
            $(this).data('zfPlugin')._init();
          });
        } else {
          var type = typeof plugins === 'undefined' ? 'undefined' : _typeof(plugins),
              _this = this,
              fns = {
            'object': function object(plgs) {
              plgs.forEach(function (p) {
                p = hyphenate(p);
                $('[data-' + p + ']').foundation('_init');
              });
            },
            'string': function string() {
              plugins = hyphenate(plugins);
              $('[data-' + plugins + ']').foundation('_init');
            },
            'undefined': function undefined() {
              this['object'](Object.keys(_this._plugins));
            }
          };
          fns[type](plugins);
        }
      } catch (err) {
        console.error(err);
      } finally {
        return plugins;
      }
    },

    /**
     * returns a random base-36 uid with namespacing
     * @function
     * @param {Number} length - number of random base-36 digits desired. Increase for more random strings.
     * @param {String} namespace - name of plugin to be incorporated in uid, optional.
     * @default {String} '' - if no plugin name is provided, nothing is appended to the uid.
     * @returns {String} - unique id
     */
    GetYoDigits: function GetYoDigits(length, namespace) {
      length = length || 6;
      return Math.round(Math.pow(36, length + 1) - Math.random() * Math.pow(36, length)).toString(36).slice(1) + (namespace ? '-' + namespace : '');
    },
    /**
     * Initialize plugins on any elements within `elem` (and `elem` itself) that aren't already initialized.
     * @param {Object} elem - jQuery object containing the element to check inside. Also checks the element itself, unless it's the `document` object.
     * @param {String|Array} plugins - A list of plugins to initialize. Leave this out to initialize everything.
     */
    reflow: function reflow(elem, plugins) {

      // If plugins is undefined, just grab everything
      if (typeof plugins === 'undefined') {
        plugins = Object.keys(this._plugins);
      }
      // If plugins is a string, convert it to an array with one item
      else if (typeof plugins === 'string') {
          plugins = [plugins];
        }

      var _this = this;

      // Iterate through each plugin
      $.each(plugins, function (i, name) {
        // Get the current plugin
        var plugin = _this._plugins[name];

        // Localize the search to all elements inside elem, as well as elem itself, unless elem === document
        var $elem = $(elem).find('[data-' + name + ']').addBack('[data-' + name + ']');

        // For each plugin found, initialize it
        $elem.each(function () {
          var $el = $(this),
              opts = {};
          // Don't double-dip on plugins
          if ($el.data('zfPlugin')) {
            console.warn("Tried to initialize " + name + " on an element that already has a Foundation plugin.");
            return;
          }

          if ($el.attr('data-options')) {
            var thing = $el.attr('data-options').split(';').forEach(function (e, i) {
              var opt = e.split(':').map(function (el) {
                return el.trim();
              });
              if (opt[0]) opts[opt[0]] = parseValue(opt[1]);
            });
          }
          try {
            $el.data('zfPlugin', new plugin($(this), opts));
          } catch (er) {
            console.error(er);
          } finally {
            return;
          }
        });
      });
    },
    getFnName: functionName,
    transitionend: function transitionend($elem) {
      var transitions = {
        'transition': 'transitionend',
        'WebkitTransition': 'webkitTransitionEnd',
        'MozTransition': 'transitionend',
        'OTransition': 'otransitionend'
      };
      var elem = document.createElement('div'),
          end;

      for (var t in transitions) {
        if (typeof elem.style[t] !== 'undefined') {
          end = transitions[t];
        }
      }
      if (end) {
        return end;
      } else {
        end = setTimeout(function () {
          $elem.triggerHandler('transitionend', [$elem]);
        }, 1);
        return 'transitionend';
      }
    }
  };

  Foundation.util = {
    /**
     * Function for applying a debounce effect to a function call.
     * @function
     * @param {Function} func - Function to be called at end of timeout.
     * @param {Number} delay - Time in ms to delay the call of `func`.
     * @returns function
     */
    throttle: function throttle(func, delay) {
      var timer = null;

      return function () {
        var context = this,
            args = arguments;

        if (timer === null) {
          timer = setTimeout(function () {
            func.apply(context, args);
            timer = null;
          }, delay);
        }
      };
    }
  };

  // TODO: consider not making this a jQuery function
  // TODO: need way to reflow vs. re-initialize
  /**
   * The Foundation jQuery method.
   * @param {String|Array} method - An action to perform on the current jQuery object.
   */
  var foundation = function foundation(method) {
    var type = typeof method === 'undefined' ? 'undefined' : _typeof(method),
        $meta = $('meta.foundation-mq'),
        $noJS = $('.no-js');

    if (!$meta.length) {
      $('<meta class="foundation-mq">').appendTo(document.head);
    }
    if ($noJS.length) {
      $noJS.removeClass('no-js');
    }

    if (type === 'undefined') {
      //needs to initialize the Foundation object, or an individual plugin.
      Foundation.MediaQuery._init();
      Foundation.reflow(this);
    } else if (type === 'string') {
      //an individual method to invoke on a plugin or group of plugins
      var args = Array.prototype.slice.call(arguments, 1); //collect all the arguments, if necessary
      var plugClass = this.data('zfPlugin'); //determine the class of plugin

      if (plugClass !== undefined && plugClass[method] !== undefined) {
        //make sure both the class and method exist
        if (this.length === 1) {
          //if there's only one, call it directly.
          plugClass[method].apply(plugClass, args);
        } else {
          this.each(function (i, el) {
            //otherwise loop through the jQuery collection and invoke the method on each
            plugClass[method].apply($(el).data('zfPlugin'), args);
          });
        }
      } else {
        //error for no class or no method
        throw new ReferenceError("We're sorry, '" + method + "' is not an available method for " + (plugClass ? functionName(plugClass) : 'this element') + '.');
      }
    } else {
      //error for invalid argument type
      throw new TypeError('We\'re sorry, ' + type + ' is not a valid parameter. You must use a string representing the method you wish to invoke.');
    }
    return this;
  };

  window.Foundation = Foundation;
  $.fn.foundation = foundation;

  // Polyfill for requestAnimationFrame
  (function () {
    if (!Date.now || !window.Date.now) window.Date.now = Date.now = function () {
      return new Date().getTime();
    };

    var vendors = ['webkit', 'moz'];
    for (var i = 0; i < vendors.length && !window.requestAnimationFrame; ++i) {
      var vp = vendors[i];
      window.requestAnimationFrame = window[vp + 'RequestAnimationFrame'];
      window.cancelAnimationFrame = window[vp + 'CancelAnimationFrame'] || window[vp + 'CancelRequestAnimationFrame'];
    }
    if (/iP(ad|hone|od).*OS 6/.test(window.navigator.userAgent) || !window.requestAnimationFrame || !window.cancelAnimationFrame) {
      var lastTime = 0;
      window.requestAnimationFrame = function (callback) {
        var now = Date.now();
        var nextTime = Math.max(lastTime + 16, now);
        return setTimeout(function () {
          callback(lastTime = nextTime);
        }, nextTime - now);
      };
      window.cancelAnimationFrame = clearTimeout;
    }
    /**
     * Polyfill for performance.now, required by rAF
     */
    if (!window.performance || !window.performance.now) {
      window.performance = {
        start: Date.now(),
        now: function now() {
          return Date.now() - this.start;
        }
      };
    }
  })();
  if (!Function.prototype.bind) {
    Function.prototype.bind = function (oThis) {
      if (typeof this !== 'function') {
        // closest thing possible to the ECMAScript 5
        // internal IsCallable function
        throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
      }

      var aArgs = Array.prototype.slice.call(arguments, 1),
          fToBind = this,
          fNOP = function fNOP() {},
          fBound = function fBound() {
        return fToBind.apply(this instanceof fNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments)));
      };

      if (this.prototype) {
        // native functions don't have a prototype
        fNOP.prototype = this.prototype;
      }
      fBound.prototype = new fNOP();

      return fBound;
    };
  }
  // Polyfill to get the name of a function in IE9
  function functionName(fn) {
    if (Function.prototype.name === undefined) {
      var funcNameRegex = /function\s([^(]{1,})\(/;
      var results = funcNameRegex.exec(fn.toString());
      return results && results.length > 1 ? results[1].trim() : "";
    } else if (fn.prototype === undefined) {
      return fn.constructor.name;
    } else {
      return fn.prototype.constructor.name;
    }
  }
  function parseValue(str) {
    if (/true/.test(str)) return true;else if (/false/.test(str)) return false;else if (!isNaN(str * 1)) return parseFloat(str);
    return str;
  }
  // Convert PascalCase to kebab-case
  // Thank you: http://stackoverflow.com/a/8955580
  function hyphenate(str) {
    return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
  }
}(jQuery);
'use strict';

!function ($) {

  Foundation.Box = {
    ImNotTouchingYou: ImNotTouchingYou,
    GetDimensions: GetDimensions,
    GetOffsets: GetOffsets
  };

  /**
   * Compares the dimensions of an element to a container and determines collision events with container.
   * @function
   * @param {jQuery} element - jQuery object to test for collisions.
   * @param {jQuery} parent - jQuery object to use as bounding container.
   * @param {Boolean} lrOnly - set to true to check left and right values only.
   * @param {Boolean} tbOnly - set to true to check top and bottom values only.
   * @default if no parent object passed, detects collisions with `window`.
   * @returns {Boolean} - true if collision free, false if a collision in any direction.
   */
  function ImNotTouchingYou(element, parent, lrOnly, tbOnly) {
    var eleDims = GetDimensions(element),
        top,
        bottom,
        left,
        right;

    if (parent) {
      var parDims = GetDimensions(parent);

      bottom = eleDims.offset.top + eleDims.height <= parDims.height + parDims.offset.top;
      top = eleDims.offset.top >= parDims.offset.top;
      left = eleDims.offset.left >= parDims.offset.left;
      right = eleDims.offset.left + eleDims.width <= parDims.width + parDims.offset.left;
    } else {
      bottom = eleDims.offset.top + eleDims.height <= eleDims.windowDims.height + eleDims.windowDims.offset.top;
      top = eleDims.offset.top >= eleDims.windowDims.offset.top;
      left = eleDims.offset.left >= eleDims.windowDims.offset.left;
      right = eleDims.offset.left + eleDims.width <= eleDims.windowDims.width;
    }

    var allDirs = [bottom, top, left, right];

    if (lrOnly) {
      return left === right === true;
    }

    if (tbOnly) {
      return top === bottom === true;
    }

    return allDirs.indexOf(false) === -1;
  };

  /**
   * Uses native methods to return an object of dimension values.
   * @function
   * @param {jQuery || HTML} element - jQuery object or DOM element for which to get the dimensions. Can be any element other that document or window.
   * @returns {Object} - nested object of integer pixel values
   * TODO - if element is window, return only those values.
   */
  function GetDimensions(elem, test) {
    elem = elem.length ? elem[0] : elem;

    if (elem === window || elem === document) {
      throw new Error("I'm sorry, Dave. I'm afraid I can't do that.");
    }

    var rect = elem.getBoundingClientRect(),
        parRect = elem.parentNode.getBoundingClientRect(),
        winRect = document.body.getBoundingClientRect(),
        winY = window.pageYOffset,
        winX = window.pageXOffset;

    return {
      width: rect.width,
      height: rect.height,
      offset: {
        top: rect.top + winY,
        left: rect.left + winX
      },
      parentDims: {
        width: parRect.width,
        height: parRect.height,
        offset: {
          top: parRect.top + winY,
          left: parRect.left + winX
        }
      },
      windowDims: {
        width: winRect.width,
        height: winRect.height,
        offset: {
          top: winY,
          left: winX
        }
      }
    };
  }

  /**
   * Returns an object of top and left integer pixel values for dynamically rendered elements,
   * such as: Tooltip, Reveal, and Dropdown
   * @function
   * @param {jQuery} element - jQuery object for the element being positioned.
   * @param {jQuery} anchor - jQuery object for the element's anchor point.
   * @param {String} position - a string relating to the desired position of the element, relative to it's anchor
   * @param {Number} vOffset - integer pixel value of desired vertical separation between anchor and element.
   * @param {Number} hOffset - integer pixel value of desired horizontal separation between anchor and element.
   * @param {Boolean} isOverflow - if a collision event is detected, sets to true to default the element to full width - any desired offset.
   * TODO alter/rewrite to work with `em` values as well/instead of pixels
   */
  function GetOffsets(element, anchor, position, vOffset, hOffset, isOverflow) {
    var $eleDims = GetDimensions(element),
        $anchorDims = anchor ? GetDimensions(anchor) : null;

    switch (position) {
      case 'top':
        return {
          left: Foundation.rtl() ? $anchorDims.offset.left - $eleDims.width + $anchorDims.width : $anchorDims.offset.left,
          top: $anchorDims.offset.top - ($eleDims.height + vOffset)
        };
        break;
      case 'left':
        return {
          left: $anchorDims.offset.left - ($eleDims.width + hOffset),
          top: $anchorDims.offset.top
        };
        break;
      case 'right':
        return {
          left: $anchorDims.offset.left + $anchorDims.width + hOffset,
          top: $anchorDims.offset.top
        };
        break;
      case 'center top':
        return {
          left: $anchorDims.offset.left + $anchorDims.width / 2 - $eleDims.width / 2,
          top: $anchorDims.offset.top - ($eleDims.height + vOffset)
        };
        break;
      case 'center bottom':
        return {
          left: isOverflow ? hOffset : $anchorDims.offset.left + $anchorDims.width / 2 - $eleDims.width / 2,
          top: $anchorDims.offset.top + $anchorDims.height + vOffset
        };
        break;
      case 'center left':
        return {
          left: $anchorDims.offset.left - ($eleDims.width + hOffset),
          top: $anchorDims.offset.top + $anchorDims.height / 2 - $eleDims.height / 2
        };
        break;
      case 'center right':
        return {
          left: $anchorDims.offset.left + $anchorDims.width + hOffset + 1,
          top: $anchorDims.offset.top + $anchorDims.height / 2 - $eleDims.height / 2
        };
        break;
      case 'center':
        return {
          left: $eleDims.windowDims.offset.left + $eleDims.windowDims.width / 2 - $eleDims.width / 2,
          top: $eleDims.windowDims.offset.top + $eleDims.windowDims.height / 2 - $eleDims.height / 2
        };
        break;
      case 'reveal':
        return {
          left: ($eleDims.windowDims.width - $eleDims.width) / 2,
          top: $eleDims.windowDims.offset.top + vOffset
        };
      case 'reveal full':
        return {
          left: $eleDims.windowDims.offset.left,
          top: $eleDims.windowDims.offset.top
        };
        break;
      case 'left bottom':
        return {
          left: $anchorDims.offset.left - ($eleDims.width + hOffset),
          top: $anchorDims.offset.top + $anchorDims.height
        };
        break;
      case 'right bottom':
        return {
          left: $anchorDims.offset.left + $anchorDims.width + hOffset - $eleDims.width,
          top: $anchorDims.offset.top + $anchorDims.height
        };
        break;
      default:
        return {
          left: Foundation.rtl() ? $anchorDims.offset.left - $eleDims.width + $anchorDims.width : $anchorDims.offset.left,
          top: $anchorDims.offset.top + $anchorDims.height + vOffset
        };
    }
  }
}(jQuery);
/*******************************************
 *                                         *
 * This util was created by Marius Olbertz *
 * Please thank Marius on GitHub /owlbertz *
 * or the web http://www.mariusolbertz.de/ *
 *                                         *
 ******************************************/

'use strict';

!function ($) {

  var keyCodes = {
    9: 'TAB',
    13: 'ENTER',
    27: 'ESCAPE',
    32: 'SPACE',
    37: 'ARROW_LEFT',
    38: 'ARROW_UP',
    39: 'ARROW_RIGHT',
    40: 'ARROW_DOWN'
  };

  var commands = {};

  var Keyboard = {
    keys: getKeyCodes(keyCodes),

    /**
     * Parses the (keyboard) event and returns a String that represents its key
     * Can be used like Foundation.parseKey(event) === Foundation.keys.SPACE
     * @param {Event} event - the event generated by the event handler
     * @return String key - String that represents the key pressed
     */
    parseKey: function parseKey(event) {
      var key = keyCodes[event.which || event.keyCode] || String.fromCharCode(event.which).toUpperCase();
      if (event.shiftKey) key = 'SHIFT_' + key;
      if (event.ctrlKey) key = 'CTRL_' + key;
      if (event.altKey) key = 'ALT_' + key;
      return key;
    },


    /**
     * Handles the given (keyboard) event
     * @param {Event} event - the event generated by the event handler
     * @param {String} component - Foundation component's name, e.g. Slider or Reveal
     * @param {Objects} functions - collection of functions that are to be executed
     */
    handleKey: function handleKey(event, component, functions) {
      var commandList = commands[component],
          keyCode = this.parseKey(event),
          cmds,
          command,
          fn;

      if (!commandList) return console.warn('Component not defined!');

      if (typeof commandList.ltr === 'undefined') {
        // this component does not differentiate between ltr and rtl
        cmds = commandList; // use plain list
      } else {
        // merge ltr and rtl: if document is rtl, rtl overwrites ltr and vice versa
        if (Foundation.rtl()) cmds = $.extend({}, commandList.ltr, commandList.rtl);else cmds = $.extend({}, commandList.rtl, commandList.ltr);
      }
      command = cmds[keyCode];

      fn = functions[command];
      if (fn && typeof fn === 'function') {
        // execute function  if exists
        var returnValue = fn.apply();
        if (functions.handled || typeof functions.handled === 'function') {
          // execute function when event was handled
          functions.handled(returnValue);
        }
      } else {
        if (functions.unhandled || typeof functions.unhandled === 'function') {
          // execute function when event was not handled
          functions.unhandled();
        }
      }
    },


    /**
     * Finds all focusable elements within the given `$element`
     * @param {jQuery} $element - jQuery object to search within
     * @return {jQuery} $focusable - all focusable elements within `$element`
     */
    findFocusable: function findFocusable($element) {
      return $element.find('a[href], area[href], input:not([disabled]), select:not([disabled]), textarea:not([disabled]), button:not([disabled]), iframe, object, embed, *[tabindex], *[contenteditable]').filter(function () {
        if (!$(this).is(':visible') || $(this).attr('tabindex') < 0) {
          return false;
        } //only have visible elements and those that have a tabindex greater or equal 0
        return true;
      });
    },


    /**
     * Returns the component name name
     * @param {Object} component - Foundation component, e.g. Slider or Reveal
     * @return String componentName
     */

    register: function register(componentName, cmds) {
      commands[componentName] = cmds;
    }
  };

  /*
   * Constants for easier comparing.
   * Can be used like Foundation.parseKey(event) === Foundation.keys.SPACE
   */
  function getKeyCodes(kcs) {
    var k = {};
    for (var kc in kcs) {
      k[kcs[kc]] = kcs[kc];
    }return k;
  }

  Foundation.Keyboard = Keyboard;
}(jQuery);
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };

!function ($) {

  // Default set of media queries
  var defaultQueries = {
    'default': 'only screen',
    landscape: 'only screen and (orientation: landscape)',
    portrait: 'only screen and (orientation: portrait)',
    retina: 'only screen and (-webkit-min-device-pixel-ratio: 2),' + 'only screen and (min--moz-device-pixel-ratio: 2),' + 'only screen and (-o-min-device-pixel-ratio: 2/1),' + 'only screen and (min-device-pixel-ratio: 2),' + 'only screen and (min-resolution: 192dpi),' + 'only screen and (min-resolution: 2dppx)'
  };

  var MediaQuery = {
    queries: [],

    current: '',

    /**
     * Initializes the media query helper, by extracting the breakpoint list from the CSS and activating the breakpoint watcher.
     * @function
     * @private
     */
    _init: function _init() {
      var self = this;
      var extractedStyles = $('.foundation-mq').css('font-family');
      var namedQueries;

      namedQueries = parseStyleToObject(extractedStyles);

      for (var key in namedQueries) {
        if (namedQueries.hasOwnProperty(key)) {
          self.queries.push({
            name: key,
            value: 'only screen and (min-width: ' + namedQueries[key] + ')'
          });
        }
      }

      this.current = this._getCurrentSize();

      this._watcher();
    },


    /**
     * Checks if the screen is at least as wide as a breakpoint.
     * @function
     * @param {String} size - Name of the breakpoint to check.
     * @returns {Boolean} `true` if the breakpoint matches, `false` if it's smaller.
     */
    atLeast: function atLeast(size) {
      var query = this.get(size);

      if (query) {
        return window.matchMedia(query).matches;
      }

      return false;
    },


    /**
     * Gets the media query of a breakpoint.
     * @function
     * @param {String} size - Name of the breakpoint to get.
     * @returns {String|null} - The media query of the breakpoint, or `null` if the breakpoint doesn't exist.
     */
    get: function get(size) {
      for (var i in this.queries) {
        if (this.queries.hasOwnProperty(i)) {
          var query = this.queries[i];
          if (size === query.name) return query.value;
        }
      }

      return null;
    },


    /**
     * Gets the current breakpoint name by testing every breakpoint and returning the last one to match (the biggest one).
     * @function
     * @private
     * @returns {String} Name of the current breakpoint.
     */
    _getCurrentSize: function _getCurrentSize() {
      var matched;

      for (var i = 0; i < this.queries.length; i++) {
        var query = this.queries[i];

        if (window.matchMedia(query.value).matches) {
          matched = query;
        }
      }

      if ((typeof matched === 'undefined' ? 'undefined' : _typeof(matched)) === 'object') {
        return matched.name;
      } else {
        return matched;
      }
    },


    /**
     * Activates the breakpoint watcher, which fires an event on the window whenever the breakpoint changes.
     * @function
     * @private
     */
    _watcher: function _watcher() {
      var _this = this;

      $(window).on('resize.zf.mediaquery', function () {
        var newSize = _this._getCurrentSize(),
            currentSize = _this.current;

        if (newSize !== currentSize) {
          // Change the current media query
          _this.current = newSize;

          // Broadcast the media query change on the window
          $(window).trigger('changed.zf.mediaquery', [newSize, currentSize]);
        }
      });
    }
  };

  Foundation.MediaQuery = MediaQuery;

  // matchMedia() polyfill - Test a CSS media type/query in JS.
  // Authors & copyright (c) 2012: Scott Jehl, Paul Irish, Nicholas Zakas, David Knight. Dual MIT/BSD license
  window.matchMedia || (window.matchMedia = function () {
    'use strict';

    // For browsers that support matchMedium api such as IE 9 and webkit

    var styleMedia = window.styleMedia || window.media;

    // For those that don't support matchMedium
    if (!styleMedia) {
      var style = document.createElement('style'),
          script = document.getElementsByTagName('script')[0],
          info = null;

      style.type = 'text/css';
      style.id = 'matchmediajs-test';

      script.parentNode.insertBefore(style, script);

      // 'style.currentStyle' is used by IE <= 8 and 'window.getComputedStyle' for all other browsers
      info = 'getComputedStyle' in window && window.getComputedStyle(style, null) || style.currentStyle;

      styleMedia = {
        matchMedium: function matchMedium(media) {
          var text = '@media ' + media + '{ #matchmediajs-test { width: 1px; } }';

          // 'style.styleSheet' is used by IE <= 8 and 'style.textContent' for all other browsers
          if (style.styleSheet) {
            style.styleSheet.cssText = text;
          } else {
            style.textContent = text;
          }

          // Test if media query is true or false
          return info.width === '1px';
        }
      };
    }

    return function (media) {
      return {
        matches: styleMedia.matchMedium(media || 'all'),
        media: media || 'all'
      };
    };
  }());

  // Thank you: https://github.com/sindresorhus/query-string
  function parseStyleToObject(str) {
    var styleObject = {};

    if (typeof str !== 'string') {
      return styleObject;
    }

    str = str.trim().slice(1, -1); // browsers re-quote string style values

    if (!str) {
      return styleObject;
    }

    styleObject = str.split('&').reduce(function (ret, param) {
      var parts = param.replace(/\+/g, ' ').split('=');
      var key = parts[0];
      var val = parts[1];
      key = decodeURIComponent(key);

      // missing `=` should be `null`:
      // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
      val = val === undefined ? null : decodeURIComponent(val);

      if (!ret.hasOwnProperty(key)) {
        ret[key] = val;
      } else if (Array.isArray(ret[key])) {
        ret[key].push(val);
      } else {
        ret[key] = [ret[key], val];
      }
      return ret;
    }, {});

    return styleObject;
  }

  Foundation.MediaQuery = MediaQuery;
}(jQuery);
'use strict';

!function ($) {

  /**
   * Motion module.
   * @module foundation.motion
   */

  var initClasses = ['mui-enter', 'mui-leave'];
  var activeClasses = ['mui-enter-active', 'mui-leave-active'];

  var Motion = {
    animateIn: function animateIn(element, animation, cb) {
      animate(true, element, animation, cb);
    },

    animateOut: function animateOut(element, animation, cb) {
      animate(false, element, animation, cb);
    }
  };

  function Move(duration, elem, fn) {
    var anim,
        prog,
        start = null;
    // console.log('called');

    function move(ts) {
      if (!start) start = window.performance.now();
      // console.log(start, ts);
      prog = ts - start;
      fn.apply(elem);

      if (prog < duration) {
        anim = window.requestAnimationFrame(move, elem);
      } else {
        window.cancelAnimationFrame(anim);
        elem.trigger('finished.zf.animate', [elem]).triggerHandler('finished.zf.animate', [elem]);
      }
    }
    anim = window.requestAnimationFrame(move);
  }

  /**
   * Animates an element in or out using a CSS transition class.
   * @function
   * @private
   * @param {Boolean} isIn - Defines if the animation is in or out.
   * @param {Object} element - jQuery or HTML object to animate.
   * @param {String} animation - CSS class to use.
   * @param {Function} cb - Callback to run when animation is finished.
   */
  function animate(isIn, element, animation, cb) {
    element = $(element).eq(0);

    if (!element.length) return;

    var initClass = isIn ? initClasses[0] : initClasses[1];
    var activeClass = isIn ? activeClasses[0] : activeClasses[1];

    // Set up the animation
    reset();

    element.addClass(animation).css('transition', 'none');

    requestAnimationFrame(function () {
      element.addClass(initClass);
      if (isIn) element.show();
    });

    // Start the animation
    requestAnimationFrame(function () {
      element[0].offsetWidth;
      element.css('transition', '').addClass(activeClass);
    });

    // Clean up the animation when it finishes
    element.one(Foundation.transitionend(element), finish);

    // Hides the element (for out animations), resets the element, and runs a callback
    function finish() {
      if (!isIn) element.hide();
      reset();
      if (cb) cb.apply(element);
    }

    // Resets transitions and removes motion-specific classes
    function reset() {
      element[0].style.transitionDuration = 0;
      element.removeClass(initClass + ' ' + activeClass + ' ' + animation);
    }
  }

  Foundation.Move = Move;
  Foundation.Motion = Motion;
}(jQuery);
'use strict';

!function ($) {

  var Nest = {
    Feather: function Feather(menu) {
      var type = arguments.length <= 1 || arguments[1] === undefined ? 'zf' : arguments[1];

      menu.attr('role', 'menubar');

      var items = menu.find('li').attr({ 'role': 'menuitem' }),
          subMenuClass = 'is-' + type + '-submenu',
          subItemClass = subMenuClass + '-item',
          hasSubClass = 'is-' + type + '-submenu-parent';

      menu.find('a:first').attr('tabindex', 0);

      items.each(function () {
        var $item = $(this),
            $sub = $item.children('ul');

        if ($sub.length) {
          $item.addClass(hasSubClass).attr({
            'aria-haspopup': true,
            'aria-expanded': false,
            'aria-label': $item.children('a:first').text()
          });

          $sub.addClass('submenu ' + subMenuClass).attr({
            'data-submenu': '',
            'aria-hidden': true,
            'role': 'menu'
          });
        }

        if ($item.parent('[data-submenu]').length) {
          $item.addClass('is-submenu-item ' + subItemClass);
        }
      });

      return;
    },
    Burn: function Burn(menu, type) {
      var items = menu.find('li').removeAttr('tabindex'),
          subMenuClass = 'is-' + type + '-submenu',
          subItemClass = subMenuClass + '-item',
          hasSubClass = 'is-' + type + '-submenu-parent';

      menu.find('*').removeClass(subMenuClass + ' ' + subItemClass + ' ' + hasSubClass + ' is-submenu-item submenu is-active').removeAttr('data-submenu').css('display', '');

      // console.log(      menu.find('.' + subMenuClass + ', .' + subItemClass + ', .has-submenu, .is-submenu-item, .submenu, [data-submenu]')
      //           .removeClass(subMenuClass + ' ' + subItemClass + ' has-submenu is-submenu-item submenu')
      //           .removeAttr('data-submenu'));
      // items.each(function(){
      //   var $item = $(this),
      //       $sub = $item.children('ul');
      //   if($item.parent('[data-submenu]').length){
      //     $item.removeClass('is-submenu-item ' + subItemClass);
      //   }
      //   if($sub.length){
      //     $item.removeClass('has-submenu');
      //     $sub.removeClass('submenu ' + subMenuClass).removeAttr('data-submenu');
      //   }
      // });
    }
  };

  Foundation.Nest = Nest;
}(jQuery);
'use strict';

!function ($) {

  function Timer(elem, options, cb) {
    var _this = this,
        duration = options.duration,
        //options is an object for easily adding features later.
    nameSpace = Object.keys(elem.data())[0] || 'timer',
        remain = -1,
        start,
        timer;

    this.isPaused = false;

    this.restart = function () {
      remain = -1;
      clearTimeout(timer);
      this.start();
    };

    this.start = function () {
      this.isPaused = false;
      // if(!elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things.
      clearTimeout(timer);
      remain = remain <= 0 ? duration : remain;
      elem.data('paused', false);
      start = Date.now();
      timer = setTimeout(function () {
        if (options.infinite) {
          _this.restart(); //rerun the timer.
        }
        cb();
      }, remain);
      elem.trigger('timerstart.zf.' + nameSpace);
    };

    this.pause = function () {
      this.isPaused = true;
      //if(elem.data('paused')){ return false; }//maybe implement this sanity check if used for other things.
      clearTimeout(timer);
      elem.data('paused', true);
      var end = Date.now();
      remain = remain - (end - start);
      elem.trigger('timerpaused.zf.' + nameSpace);
    };
  }

  /**
   * Runs a callback function when images are fully loaded.
   * @param {Object} images - Image(s) to check if loaded.
   * @param {Func} callback - Function to execute when image is fully loaded.
   */
  function onImagesLoaded(images, callback) {
    var self = this,
        unloaded = images.length;

    if (unloaded === 0) {
      callback();
    }

    images.each(function () {
      if (this.complete) {
        singleImageLoaded();
      } else if (typeof this.naturalWidth !== 'undefined' && this.naturalWidth > 0) {
        singleImageLoaded();
      } else {
        $(this).one('load', function () {
          singleImageLoaded();
        });
      }
    });

    function singleImageLoaded() {
      unloaded--;
      if (unloaded === 0) {
        callback();
      }
    }
  }

  Foundation.Timer = Timer;
  Foundation.onImagesLoaded = onImagesLoaded;
}(jQuery);
'use strict';

//**************************************************
//**Work inspired by multiple jquery swipe plugins**
//**Done by Yohai Ararat ***************************
//**************************************************
(function ($) {

		$.spotSwipe = {
				version: '1.0.0',
				enabled: 'ontouchstart' in document.documentElement,
				preventDefault: false,
				moveThreshold: 75,
				timeThreshold: 200
		};

		var startPosX,
		    startPosY,
		    startTime,
		    elapsedTime,
		    isMoving = false;

		function onTouchEnd() {
				//  alert(this);
				this.removeEventListener('touchmove', onTouchMove);
				this.removeEventListener('touchend', onTouchEnd);
				isMoving = false;
		}

		function onTouchMove(e) {
				if ($.spotSwipe.preventDefault) {
						e.preventDefault();
				}
				if (isMoving) {
						var x = e.touches[0].pageX;
						var y = e.touches[0].pageY;
						var dx = startPosX - x;
						var dy = startPosY - y;
						var dir;
						elapsedTime = new Date().getTime() - startTime;
						if (Math.abs(dx) >= $.spotSwipe.moveThreshold && elapsedTime <= $.spotSwipe.timeThreshold) {
								dir = dx > 0 ? 'left' : 'right';
						}
						// else if(Math.abs(dy) >= $.spotSwipe.moveThreshold && elapsedTime <= $.spotSwipe.timeThreshold) {
						//   dir = dy > 0 ? 'down' : 'up';
						// }
						if (dir) {
								e.preventDefault();
								onTouchEnd.call(this);
								$(this).trigger('swipe', dir).trigger('swipe' + dir);
						}
				}
		}

		function onTouchStart(e) {
				if (e.touches.length == 1) {
						startPosX = e.touches[0].pageX;
						startPosY = e.touches[0].pageY;
						isMoving = true;
						startTime = new Date().getTime();
						this.addEventListener('touchmove', onTouchMove, false);
						this.addEventListener('touchend', onTouchEnd, false);
				}
		}

		function init() {
				this.addEventListener && this.addEventListener('touchstart', onTouchStart, false);
		}

		function teardown() {
				this.removeEventListener('touchstart', onTouchStart);
		}

		$.event.special.swipe = { setup: init };

		$.each(['left', 'up', 'down', 'right'], function () {
				$.event.special['swipe' + this] = { setup: function setup() {
								$(this).on('swipe', $.noop);
						} };
		});
})(jQuery);
/****************************************************
 * Method for adding psuedo drag events to elements *
 ***************************************************/
!function ($) {
		$.fn.addTouch = function () {
				this.each(function (i, el) {
						$(el).bind('touchstart touchmove touchend touchcancel', function () {
								//we pass the original event object because the jQuery event
								//object is normalized to w3c specs and does not provide the TouchList
								handleTouch(event);
						});
				});

				var handleTouch = function handleTouch(event) {
						var touches = event.changedTouches,
						    first = touches[0],
						    eventTypes = {
								touchstart: 'mousedown',
								touchmove: 'mousemove',
								touchend: 'mouseup'
						},
						    type = eventTypes[event.type],
						    simulatedEvent;

						if ('MouseEvent' in window && typeof window.MouseEvent === 'function') {
								simulatedEvent = new window.MouseEvent(type, {
										'bubbles': true,
										'cancelable': true,
										'screenX': first.screenX,
										'screenY': first.screenY,
										'clientX': first.clientX,
										'clientY': first.clientY
								});
						} else {
								simulatedEvent = document.createEvent('MouseEvent');
								simulatedEvent.initMouseEvent(type, true, true, window, 1, first.screenX, first.screenY, first.clientX, first.clientY, false, false, false, false, 0 /*left*/, null);
						}
						first.target.dispatchEvent(simulatedEvent);
				};
		};
}(jQuery);

//**********************************
//**From the jQuery Mobile Library**
//**need to recreate functionality**
//**and try to improve if possible**
//**********************************

/* Removing the jQuery function ****
************************************

(function( $, window, undefined ) {

	var $document = $( document ),
		// supportTouch = $.mobile.support.touch,
		touchStartEvent = 'touchstart'//supportTouch ? "touchstart" : "mousedown",
		touchStopEvent = 'touchend'//supportTouch ? "touchend" : "mouseup",
		touchMoveEvent = 'touchmove'//supportTouch ? "touchmove" : "mousemove";

	// setup new event shortcuts
	$.each( ( "touchstart touchmove touchend " +
		"swipe swipeleft swiperight" ).split( " " ), function( i, name ) {

		$.fn[ name ] = function( fn ) {
			return fn ? this.bind( name, fn ) : this.trigger( name );
		};

		// jQuery < 1.8
		if ( $.attrFn ) {
			$.attrFn[ name ] = true;
		}
	});

	function triggerCustomEvent( obj, eventType, event, bubble ) {
		var originalType = event.type;
		event.type = eventType;
		if ( bubble ) {
			$.event.trigger( event, undefined, obj );
		} else {
			$.event.dispatch.call( obj, event );
		}
		event.type = originalType;
	}

	// also handles taphold

	// Also handles swipeleft, swiperight
	$.event.special.swipe = {

		// More than this horizontal displacement, and we will suppress scrolling.
		scrollSupressionThreshold: 30,

		// More time than this, and it isn't a swipe.
		durationThreshold: 1000,

		// Swipe horizontal displacement must be more than this.
		horizontalDistanceThreshold: window.devicePixelRatio >= 2 ? 15 : 30,

		// Swipe vertical displacement must be less than this.
		verticalDistanceThreshold: window.devicePixelRatio >= 2 ? 15 : 30,

		getLocation: function ( event ) {
			var winPageX = window.pageXOffset,
				winPageY = window.pageYOffset,
				x = event.clientX,
				y = event.clientY;

			if ( event.pageY === 0 && Math.floor( y ) > Math.floor( event.pageY ) ||
				event.pageX === 0 && Math.floor( x ) > Math.floor( event.pageX ) ) {

				// iOS4 clientX/clientY have the value that should have been
				// in pageX/pageY. While pageX/page/ have the value 0
				x = x - winPageX;
				y = y - winPageY;
			} else if ( y < ( event.pageY - winPageY) || x < ( event.pageX - winPageX ) ) {

				// Some Android browsers have totally bogus values for clientX/Y
				// when scrolling/zooming a page. Detectable since clientX/clientY
				// should never be smaller than pageX/pageY minus page scroll
				x = event.pageX - winPageX;
				y = event.pageY - winPageY;
			}

			return {
				x: x,
				y: y
			};
		},

		start: function( event ) {
			var data = event.originalEvent.touches ?
					event.originalEvent.touches[ 0 ] : event,
				location = $.event.special.swipe.getLocation( data );
			return {
						time: ( new Date() ).getTime(),
						coords: [ location.x, location.y ],
						origin: $( event.target )
					};
		},

		stop: function( event ) {
			var data = event.originalEvent.touches ?
					event.originalEvent.touches[ 0 ] : event,
				location = $.event.special.swipe.getLocation( data );
			return {
						time: ( new Date() ).getTime(),
						coords: [ location.x, location.y ]
					};
		},

		handleSwipe: function( start, stop, thisObject, origTarget ) {
			if ( stop.time - start.time < $.event.special.swipe.durationThreshold &&
				Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.horizontalDistanceThreshold &&
				Math.abs( start.coords[ 1 ] - stop.coords[ 1 ] ) < $.event.special.swipe.verticalDistanceThreshold ) {
				var direction = start.coords[0] > stop.coords[ 0 ] ? "swipeleft" : "swiperight";

				triggerCustomEvent( thisObject, "swipe", $.Event( "swipe", { target: origTarget, swipestart: start, swipestop: stop }), true );
				triggerCustomEvent( thisObject, direction,$.Event( direction, { target: origTarget, swipestart: start, swipestop: stop } ), true );
				return true;
			}
			return false;

		},

		// This serves as a flag to ensure that at most one swipe event event is
		// in work at any given time
		eventInProgress: false,

		setup: function() {
			var events,
				thisObject = this,
				$this = $( thisObject ),
				context = {};

			// Retrieve the events data for this element and add the swipe context
			events = $.data( this, "mobile-events" );
			if ( !events ) {
				events = { length: 0 };
				$.data( this, "mobile-events", events );
			}
			events.length++;
			events.swipe = context;

			context.start = function( event ) {

				// Bail if we're already working on a swipe event
				if ( $.event.special.swipe.eventInProgress ) {
					return;
				}
				$.event.special.swipe.eventInProgress = true;

				var stop,
					start = $.event.special.swipe.start( event ),
					origTarget = event.target,
					emitted = false;

				context.move = function( event ) {
					if ( !start || event.isDefaultPrevented() ) {
						return;
					}

					stop = $.event.special.swipe.stop( event );
					if ( !emitted ) {
						emitted = $.event.special.swipe.handleSwipe( start, stop, thisObject, origTarget );
						if ( emitted ) {

							// Reset the context to make way for the next swipe event
							$.event.special.swipe.eventInProgress = false;
						}
					}
					// prevent scrolling
					if ( Math.abs( start.coords[ 0 ] - stop.coords[ 0 ] ) > $.event.special.swipe.scrollSupressionThreshold ) {
						event.preventDefault();
					}
				};

				context.stop = function() {
						emitted = true;

						// Reset the context to make way for the next swipe event
						$.event.special.swipe.eventInProgress = false;
						$document.off( touchMoveEvent, context.move );
						context.move = null;
				};

				$document.on( touchMoveEvent, context.move )
					.one( touchStopEvent, context.stop );
			};
			$this.on( touchStartEvent, context.start );
		},

		teardown: function() {
			var events, context;

			events = $.data( this, "mobile-events" );
			if ( events ) {
				context = events.swipe;
				delete events.swipe;
				events.length--;
				if ( events.length === 0 ) {
					$.removeData( this, "mobile-events" );
				}
			}

			if ( context ) {
				if ( context.start ) {
					$( this ).off( touchStartEvent, context.start );
				}
				if ( context.move ) {
					$document.off( touchMoveEvent, context.move );
				}
				if ( context.stop ) {
					$document.off( touchStopEvent, context.stop );
				}
			}
		}
	};
	$.each({
		swipeleft: "swipe.left",
		swiperight: "swipe.right"
	}, function( event, sourceEvent ) {

		$.event.special[ event ] = {
			setup: function() {
				$( this ).bind( sourceEvent, $.noop );
			},
			teardown: function() {
				$( this ).unbind( sourceEvent );
			}
		};
	});
})( jQuery, this );
*/
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };

!function ($) {

  var MutationObserver = function () {
    var prefixes = ['WebKit', 'Moz', 'O', 'Ms', ''];
    for (var i = 0; i < prefixes.length; i++) {
      if (prefixes[i] + 'MutationObserver' in window) {
        return window[prefixes[i] + 'MutationObserver'];
      }
    }
    return false;
  }();

  var triggers = function triggers(el, type) {
    el.data(type).split(' ').forEach(function (id) {
      $('#' + id)[type === 'close' ? 'trigger' : 'triggerHandler'](type + '.zf.trigger', [el]);
    });
  };
  // Elements with [data-open] will reveal a plugin that supports it when clicked.
  $(document).on('click.zf.trigger', '[data-open]', function () {
    triggers($(this), 'open');
  });

  // Elements with [data-close] will close a plugin that supports it when clicked.
  // If used without a value on [data-close], the event will bubble, allowing it to close a parent component.
  $(document).on('click.zf.trigger', '[data-close]', function () {
    var id = $(this).data('close');
    if (id) {
      triggers($(this), 'close');
    } else {
      $(this).trigger('close.zf.trigger');
    }
  });

  // Elements with [data-toggle] will toggle a plugin that supports it when clicked.
  $(document).on('click.zf.trigger', '[data-toggle]', function () {
    triggers($(this), 'toggle');
  });

  // Elements with [data-closable] will respond to close.zf.trigger events.
  $(document).on('close.zf.trigger', '[data-closable]', function (e) {
    e.stopPropagation();
    var animation = $(this).data('closable');

    if (animation !== '') {
      Foundation.Motion.animateOut($(this), animation, function () {
        $(this).trigger('closed.zf');
      });
    } else {
      $(this).fadeOut().trigger('closed.zf');
    }
  });

  $(document).on('focus.zf.trigger blur.zf.trigger', '[data-toggle-focus]', function () {
    var id = $(this).data('toggle-focus');
    $('#' + id).triggerHandler('toggle.zf.trigger', [$(this)]);
  });

  /**
  * Fires once after all other scripts have loaded
  * @function
  * @private
  */
  $(window).load(function () {
    checkListeners();
  });

  function checkListeners() {
    eventsListener();
    resizeListener();
    scrollListener();
    closemeListener();
  }

  //******** only fires this function once on load, if there's something to watch ********
  function closemeListener(pluginName) {
    var yetiBoxes = $('[data-yeti-box]'),
        plugNames = ['dropdown', 'tooltip', 'reveal'];

    if (pluginName) {
      if (typeof pluginName === 'string') {
        plugNames.push(pluginName);
      } else if ((typeof pluginName === 'undefined' ? 'undefined' : _typeof(pluginName)) === 'object' && typeof pluginName[0] === 'string') {
        plugNames.concat(pluginName);
      } else {
        console.error('Plugin names must be strings');
      }
    }
    if (yetiBoxes.length) {
      var listeners = plugNames.map(function (name) {
        return 'closeme.zf.' + name;
      }).join(' ');

      $(window).off(listeners).on(listeners, function (e, pluginId) {
        var plugin = e.namespace.split('.')[0];
        var plugins = $('[data-' + plugin + ']').not('[data-yeti-box="' + pluginId + '"]');

        plugins.each(function () {
          var _this = $(this);

          _this.triggerHandler('close.zf.trigger', [_this]);
        });
      });
    }
  }

  function resizeListener(debounce) {
    var timer = void 0,
        $nodes = $('[data-resize]');
    if ($nodes.length) {
      $(window).off('resize.zf.trigger').on('resize.zf.trigger', function (e) {
        if (timer) {
          clearTimeout(timer);
        }

        timer = setTimeout(function () {

          if (!MutationObserver) {
            //fallback for IE 9
            $nodes.each(function () {
              $(this).triggerHandler('resizeme.zf.trigger');
            });
          }
          //trigger all listening elements and signal a resize event
          $nodes.attr('data-events', "resize");
        }, debounce || 10); //default time to emit resize event
      });
    }
  }

  function scrollListener(debounce) {
    var timer = void 0,
        $nodes = $('[data-scroll]');
    if ($nodes.length) {
      $(window).off('scroll.zf.trigger').on('scroll.zf.trigger', function (e) {
        if (timer) {
          clearTimeout(timer);
        }

        timer = setTimeout(function () {

          if (!MutationObserver) {
            //fallback for IE 9
            $nodes.each(function () {
              $(this).triggerHandler('scrollme.zf.trigger');
            });
          }
          //trigger all listening elements and signal a scroll event
          $nodes.attr('data-events', "scroll");
        }, debounce || 10); //default time to emit scroll event
      });
    }
  }

  function eventsListener() {
    if (!MutationObserver) {
      return false;
    }
    var nodes = document.querySelectorAll('[data-resize], [data-scroll], [data-mutate]');

    //element callback
    var listeningElementsMutation = function listeningElementsMutation(mutationRecordsList) {
      var $target = $(mutationRecordsList[0].target);
      //trigger the event handler for the element depending on type
      switch ($target.attr("data-events")) {

        case "resize":
          $target.triggerHandler('resizeme.zf.trigger', [$target]);
          break;

        case "scroll":
          $target.triggerHandler('scrollme.zf.trigger', [$target, window.pageYOffset]);
          break;

        // case "mutate" :
        // console.log('mutate', $target);
        // $target.triggerHandler('mutate.zf.trigger');
        //
        // //make sure we don't get stuck in an infinite loop from sloppy codeing
        // if ($target.index('[data-mutate]') == $("[data-mutate]").length-1) {
        //   domMutationObserver();
        // }
        // break;

        default:
          return false;
        //nothing
      }
    };

    if (nodes.length) {
      //for each element that needs to listen for resizing, scrolling, (or coming soon mutation) add a single observer
      for (var i = 0; i <= nodes.length - 1; i++) {
        var elementObserver = new MutationObserver(listeningElementsMutation);
        elementObserver.observe(nodes[i], { attributes: true, childList: false, characterData: false, subtree: false, attributeFilter: ["data-events"] });
      }
    }
  }

  // ------------------------------------

  // [PH]
  // Foundation.CheckWatchers = checkWatchers;
  Foundation.IHearYou = checkListeners;
  // Foundation.ISeeYou = scrollListener;
  // Foundation.IFeelYou = closemeListener;
}(jQuery);

// function domMutationObserver(debounce) {
//   // !!! This is coming soon and needs more work; not active  !!! //
//   var timer,
//   nodes = document.querySelectorAll('[data-mutate]');
//   //
//   if (nodes.length) {
//     // var MutationObserver = (function () {
//     //   var prefixes = ['WebKit', 'Moz', 'O', 'Ms', ''];
//     //   for (var i=0; i < prefixes.length; i++) {
//     //     if (prefixes[i] + 'MutationObserver' in window) {
//     //       return window[prefixes[i] + 'MutationObserver'];
//     //     }
//     //   }
//     //   return false;
//     // }());
//
//
//     //for the body, we need to listen for all changes effecting the style and class attributes
//     var bodyObserver = new MutationObserver(bodyMutation);
//     bodyObserver.observe(document.body, { attributes: true, childList: true, characterData: false, subtree:true, attributeFilter:["style", "class"]});
//
//
//     //body callback
//     function bodyMutation(mutate) {
//       //trigger all listening elements and signal a mutation event
//       if (timer) { clearTimeout(timer); }
//
//       timer = setTimeout(function() {
//         bodyObserver.disconnect();
//         $('[data-mutate]').attr('data-events',"mutate");
//       }, debounce || 150);
//     }
//   }
// }
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * Abide module.
   * @module foundation.abide
   */

  var Abide = function () {
    /**
     * Creates a new instance of Abide.
     * @class
     * @fires Abide#init
     * @param {Object} element - jQuery object to add the trigger to.
     * @param {Object} options - Overrides to the default plugin settings.
     */
    function Abide(element) {
      var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];

      _classCallCheck(this, Abide);

      this.$element = element;
      this.options = $.extend({}, Abide.defaults, this.$element.data(), options);

      this._init();

      Foundation.registerPlugin(this, 'Abide');
    }

    /**
     * Initializes the Abide plugin and calls functions to get Abide functioning on load.
     * @private
     */


    _createClass(Abide, [{
      key: '_init',
      value: function _init() {
        this.$inputs = this.$element.find('input, textarea, select');

        this._events();
      }

      /**
       * Initializes events for Abide.
       * @private
       */

    }, {
      key: '_events',
      value: function _events() {
        var _this2 = this;

        this.$element.off('.abide').on('reset.zf.abide', function () {
          _this2.resetForm();
        }).on('submit.zf.abide', function () {
          return _this2.validateForm();
        });

        if (this.options.validateOn === 'fieldChange') {
          this.$inputs.off('change.zf.abide').on('change.zf.abide', function (e) {
            _this2.validateInput($(e.target));
          });
        }

        if (this.options.liveValidate) {
          this.$inputs.off('input.zf.abide').on('input.zf.abide', function (e) {
            _this2.validateInput($(e.target));
          });
        }
      }

      /**
       * Calls necessary functions to update Abide upon DOM change
       * @private
       */

    }, {
      key: '_reflow',
      value: function _reflow() {
        this._init();
      }

      /**
       * Checks whether or not a form element has the required attribute and if it's checked or not
       * @param {Object} element - jQuery object to check for required attribute
       * @returns {Boolean} Boolean value depends on whether or not attribute is checked or empty
       */

    }, {
      key: 'requiredCheck',
      value: function requiredCheck($el) {
        if (!$el.attr('required')) return true;

        var isGood = true;

        switch ($el[0].type) {
          case 'checkbox':
            isGood = $el[0].checked;
            break;

          case 'select':
          case 'select-one':
          case 'select-multiple':
            var opt = $el.find('option:selected');
            if (!opt.length || !opt.val()) isGood = false;
            break;

          default:
            if (!$el.val() || !$el.val().length) isGood = false;
        }

        return isGood;
      }

      /**
       * Based on $el, get the first element with selector in this order:
       * 1. The element's direct sibling('s).
       * 3. The element's parent's children.
       *
       * This allows for multiple form errors per input, though if none are found, no form errors will be shown.
       *
       * @param {Object} $el - jQuery object to use as reference to find the form error selector.
       * @returns {Object} jQuery object with the selector.
       */

    }, {
      key: 'findFormError',
      value: function findFormError($el) {
        var $error = $el.siblings(this.options.formErrorSelector);

        if (!$error.length) {
          $error = $el.parent().find(this.options.formErrorSelector);
        }

        return $error;
      }

      /**
       * Get the first element in this order:
       * 2. The <label> with the attribute `[for="someInputId"]`
       * 3. The `.closest()` <label>
       *
       * @param {Object} $el - jQuery object to check for required attribute
       * @returns {Boolean} Boolean value depends on whether or not attribute is checked or empty
       */

    }, {
      key: 'findLabel',
      value: function findLabel($el) {
        var id = $el[0].id;
        var $label = this.$element.find('label[for="' + id + '"]');

        if (!$label.length) {
          return $el.closest('label');
        }

        return $label;
      }

      /**
       * Get the set of labels associated with a set of radio els in this order
       * 2. The <label> with the attribute `[for="someInputId"]`
       * 3. The `.closest()` <label>
       *
       * @param {Object} $el - jQuery object to check for required attribute
       * @returns {Boolean} Boolean value depends on whether or not attribute is checked or empty
       */

    }, {
      key: 'findRadioLabels',
      value: function findRadioLabels($els) {
        var _this3 = this;

        var labels = $els.map(function (i, el) {
          var id = el.id;
          var $label = _this3.$element.find('label[for="' + id + '"]');

          if (!$label.length) {
            $label = $(el).closest('label');
          }
          return $label[0];
        });

        return $(labels);
      }

      /**
       * Adds the CSS error class as specified by the Abide settings to the label, input, and the form
       * @param {Object} $el - jQuery object to add the class to
       */

    }, {
      key: 'addErrorClasses',
      value: function addErrorClasses($el) {
        var $label = this.findLabel($el);
        var $formError = this.findFormError($el);

        if ($label.length) {
          $label.addClass(this.options.labelErrorClass);
        }

        if ($formError.length) {
          $formError.addClass(this.options.formErrorClass);
        }

        $el.addClass(this.options.inputErrorClass).attr('data-invalid', '');
      }

      /**
       * Remove CSS error classes etc from an entire radio button group
       * @param {String} groupName - A string that specifies the name of a radio button group
       *
       */

    }, {
      key: 'removeRadioErrorClasses',
      value: function removeRadioErrorClasses(groupName) {
        var $els = this.$element.find(':radio[name="' + groupName + '"]');
        var $labels = this.findRadioLabels($els);
        var $formErrors = this.findFormError($els);

        if ($labels.length) {
          $labels.removeClass(this.options.labelErrorClass);
        }

        if ($formErrors.length) {
          $formErrors.removeClass(this.options.formErrorClass);
        }

        $els.removeClass(this.options.inputErrorClass).removeAttr('data-invalid');
      }

      /**
       * Removes CSS error class as specified by the Abide settings from the label, input, and the form
       * @param {Object} $el - jQuery object to remove the class from
       */

    }, {
      key: 'removeErrorClasses',
      value: function removeErrorClasses($el) {
        // radios need to clear all of the els
        if ($el[0].type == 'radio') {
          return this.removeRadioErrorClasses($el.attr('name'));
        }

        var $label = this.findLabel($el);
        var $formError = this.findFormError($el);

        if ($label.length) {
          $label.removeClass(this.options.labelErrorClass);
        }

        if ($formError.length) {
          $formError.removeClass(this.options.formErrorClass);
        }

        $el.removeClass(this.options.inputErrorClass).removeAttr('data-invalid');
      }

      /**
       * Goes through a form to find inputs and proceeds to validate them in ways specific to their type
       * @fires Abide#invalid
       * @fires Abide#valid
       * @param {Object} element - jQuery object to validate, should be an HTML input
       * @returns {Boolean} goodToGo - If the input is valid or not.
       */

    }, {
      key: 'validateInput',
      value: function validateInput($el) {
        var clearRequire = this.requiredCheck($el),
            validated = false,
            customValidator = true,
            validator = $el.attr('data-validator'),
            equalTo = true;

        // don't validate ignored inputs or hidden inputs
        if ($el.is('[data-abide-ignore]') || $el.is('[type="hidden"]')) {
          return true;
        }

        switch ($el[0].type) {
          case 'radio':
            validated = this.validateRadio($el.attr('name'));
            break;

          case 'checkbox':
            validated = clearRequire;
            break;

          case 'select':
          case 'select-one':
          case 'select-multiple':
            validated = clearRequire;
            break;

          default:
            validated = this.validateText($el);
        }

        if (validator) {
          customValidator = this.matchValidation($el, validator, $el.attr('required'));
        }

        if ($el.attr('data-equalto')) {
          equalTo = this.options.validators.equalTo($el);
        }

        var goodToGo = [clearRequire, validated, customValidator, equalTo].indexOf(false) === -1;
        var message = (goodToGo ? 'valid' : 'invalid') + '.zf.abide';

        this[goodToGo ? 'removeErrorClasses' : 'addErrorClasses']($el);

        /**
         * Fires when the input is done checking for validation. Event trigger is either `valid.zf.abide` or `invalid.zf.abide`
         * Trigger includes the DOM element of the input.
         * @event Abide#valid
         * @event Abide#invalid
         */
        $el.trigger(message, [$el]);

        return goodToGo;
      }

      /**
       * Goes through a form and if there are any invalid inputs, it will display the form error element
       * @returns {Boolean} noError - true if no errors were detected...
       * @fires Abide#formvalid
       * @fires Abide#forminvalid
       */

    }, {
      key: 'validateForm',
      value: function validateForm() {
        var acc = [];
        var _this = this;

        this.$inputs.each(function () {
          acc.push(_this.validateInput($(this)));
        });

        var noError = acc.indexOf(false) === -1;

        this.$element.find('[data-abide-error]').css('display', noError ? 'none' : 'block');

        /**
         * Fires when the form is finished validating. Event trigger is either `formvalid.zf.abide` or `forminvalid.zf.abide`.
         * Trigger includes the element of the form.
         * @event Abide#formvalid
         * @event Abide#forminvalid
         */
        this.$element.trigger((noError ? 'formvalid' : 'forminvalid') + '.zf.abide', [this.$element]);

        return noError;
      }

      /**
       * Determines whether or a not a text input is valid based on the pattern specified in the attribute. If no matching pattern is found, returns true.
       * @param {Object} $el - jQuery object to validate, should be a text input HTML element
       * @param {String} pattern - string value of one of the RegEx patterns in Abide.options.patterns
       * @returns {Boolean} Boolean value depends on whether or not the input value matches the pattern specified
       */

    }, {
      key: 'validateText',
      value: function validateText($el, pattern) {
        // A pattern can be passed to this function, or it will be infered from the input's "pattern" attribute, or it's "type" attribute
        pattern = pattern || $el.attr('pattern') || $el.attr('type');
        var inputText = $el.val();
        var valid = false;

        if (inputText.length) {
          // If the pattern attribute on the element is in Abide's list of patterns, then test that regexp
          if (this.options.patterns.hasOwnProperty(pattern)) {
            valid = this.options.patterns[pattern].test(inputText);
          }
          // If the pattern name isn't also the type attribute of the field, then test it as a regexp
          else if (pattern !== $el.attr('type')) {
              valid = new RegExp(pattern).test(inputText);
            } else {
              valid = true;
            }
        }
        // An empty field is valid if it's not required
        else if (!$el.prop('required')) {
            valid = true;
          }

        return valid;
      }

      /**
       * Determines whether or a not a radio input is valid based on whether or not it is required and selected. Although the function targets a single `<input>`, it validates by checking the `required` and `checked` properties of all radio buttons in its group.
       * @param {String} groupName - A string that specifies the name of a radio button group
       * @returns {Boolean} Boolean value depends on whether or not at least one radio input has been selected (if it's required)
       */

    }, {
      key: 'validateRadio',
      value: function validateRadio(groupName) {
        // If at least one radio in the group has the `required` attribute, the group is considered required
        // Per W3C spec, all radio buttons in a group should have `required`, but we're being nice
        var $group = this.$element.find(':radio[name="' + groupName + '"]');
        var valid = false,
            required = false;

        // For the group to be required, at least one radio needs to be required
        $group.each(function (i, e) {
          if ($(e).attr('required')) {
            required = true;
          }
        });
        if (!required) valid = true;

        if (!valid) {
          // For the group to be valid, at least one radio needs to be checked
          $group.each(function (i, e) {
            if ($(e).prop('checked')) {
              valid = true;
            }
          });
        };

        return valid;
      }

      /**
       * Determines if a selected input passes a custom validation function. Multiple validations can be used, if passed to the element with `data-validator="foo bar baz"` in a space separated listed.
       * @param {Object} $el - jQuery input element.
       * @param {String} validators - a string of function names matching functions in the Abide.options.validators object.
       * @param {Boolean} required - self explanatory?
       * @returns {Boolean} - true if validations passed.
       */

    }, {
      key: 'matchValidation',
      value: function matchValidation($el, validators, required) {
        var _this4 = this;

        required = required ? true : false;

        var clear = validators.split(' ').map(function (v) {
          return _this4.options.validators[v]($el, required, $el.parent());
        });
        return clear.indexOf(false) === -1;
      }

      /**
       * Resets form inputs and styles
       * @fires Abide#formreset
       */

    }, {
      key: 'resetForm',
      value: function resetForm() {
        var $form = this.$element,
            opts = this.options;

        $('.' + opts.labelErrorClass, $form).not('small').removeClass(opts.labelErrorClass);
        $('.' + opts.inputErrorClass, $form).not('small').removeClass(opts.inputErrorClass);
        $(opts.formErrorSelector + '.' + opts.formErrorClass).removeClass(opts.formErrorClass);
        $form.find('[data-abide-error]').css('display', 'none');
        $(':input', $form).not(':button, :submit, :reset, :hidden, :radio, :checkbox, [data-abide-ignore]').val('').removeAttr('data-invalid');
        $(':input:radio', $form).not('[data-abide-ignore]').prop('checked', false).removeAttr('data-invalid');
        $(':input:checkbox', $form).not('[data-abide-ignore]').prop('checked', false).removeAttr('data-invalid');
        /**
         * Fires when the form has been reset.
         * @event Abide#formreset
         */
        $form.trigger('formreset.zf.abide', [$form]);
      }

      /**
       * Destroys an instance of Abide.
       * Removes error styles and classes from elements, without resetting their values.
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        var _this = this;
        this.$element.off('.abide').find('[data-abide-error]').css('display', 'none');

        this.$inputs.off('.abide').each(function () {
          _this.removeErrorClasses($(this));
        });

        Foundation.unregisterPlugin(this);
      }
    }]);

    return Abide;
  }();

  /**
   * Default settings for plugin
   */


  Abide.defaults = {
    /**
     * The default event to validate inputs. Checkboxes and radios validate immediately.
     * Remove or change this value for manual validation.
     * @option
     * @example 'fieldChange'
     */
    validateOn: 'fieldChange',

    /**
     * Class to be applied to input labels on failed validation.
     * @option
     * @example 'is-invalid-label'
     */
    labelErrorClass: 'is-invalid-label',

    /**
     * Class to be applied to inputs on failed validation.
     * @option
     * @example 'is-invalid-input'
     */
    inputErrorClass: 'is-invalid-input',

    /**
     * Class selector to use to target Form Errors for show/hide.
     * @option
     * @example '.form-error'
     */
    formErrorSelector: '.form-error',

    /**
     * Class added to Form Errors on failed validation.
     * @option
     * @example 'is-visible'
     */
    formErrorClass: 'is-visible',

    /**
     * Set to true to validate text inputs on any value change.
     * @option
     * @example false
     */
    liveValidate: false,

    patterns: {
      alpha: /^[a-zA-Z]+$/,
      alpha_numeric: /^[a-zA-Z0-9]+$/,
      integer: /^[-+]?\d+$/,
      number: /^[-+]?\d*(?:[\.\,]\d+)?$/,

      // amex, visa, diners
      card: /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$/,
      cvv: /^([0-9]){3,4}$/,

      // http://www.whatwg.org/specs/web-apps/current-work/multipage/states-of-the-type-attribute.html#valid-e-mail-address
      email: /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/,

      url: /^(https?|ftp|file|ssh):\/\/(((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-zA-Z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-zA-Z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/,
      // abc.de
      domain: /^([a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,8}$/,

      datetime: /^([0-2][0-9]{3})\-([0-1][0-9])\-([0-3][0-9])T([0-5][0-9])\:([0-5][0-9])\:([0-5][0-9])(Z|([\-\+]([0-1][0-9])\:00))$/,
      // YYYY-MM-DD
      date: /(?:19|20)[0-9]{2}-(?:(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-9])|(?:(?!02)(?:0[1-9]|1[0-2])-(?:30))|(?:(?:0[13578]|1[02])-31))$/,
      // HH:MM:SS
      time: /^(0[0-9]|1[0-9]|2[0-3])(:[0-5][0-9]){2}$/,
      dateISO: /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/,
      // MM/DD/YYYY
      month_day_year: /^(0[1-9]|1[012])[- \/.](0[1-9]|[12][0-9]|3[01])[- \/.]\d{4}$/,
      // DD/MM/YYYY
      day_month_year: /^(0[1-9]|[12][0-9]|3[01])[- \/.](0[1-9]|1[012])[- \/.]\d{4}$/,

      // #FFF or #FFFFFF
      color: /^#?([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$/
    },

    /**
     * Optional validation functions to be used. `equalTo` being the only default included function.
     * Functions should return only a boolean if the input is valid or not. Functions are given the following arguments:
     * el : The jQuery element to validate.
     * required : Boolean value of the required attribute be present or not.
     * parent : The direct parent of the input.
     * @option
     */
    validators: {
      equalTo: function equalTo(el, required, parent) {
        return $('#' + el.attr('data-equalto')).val() === el.val();
      }
    }
  };

  // Window exports
  Foundation.plugin(Abide, 'Abide');
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * Accordion module.
   * @module foundation.accordion
   * @requires foundation.util.keyboard
   * @requires foundation.util.motion
   */

  var Accordion = function () {
    /**
     * Creates a new instance of an accordion.
     * @class
     * @fires Accordion#init
     * @param {jQuery} element - jQuery object to make into an accordion.
     * @param {Object} options - a plain object with settings to override the default options.
     */
    function Accordion(element, options) {
      _classCallCheck(this, Accordion);

      this.$element = element;
      this.options = $.extend({}, Accordion.defaults, this.$element.data(), options);

      this._init();

      Foundation.registerPlugin(this, 'Accordion');
      Foundation.Keyboard.register('Accordion', {
        'ENTER': 'toggle',
        'SPACE': 'toggle',
        'ARROW_DOWN': 'next',
        'ARROW_UP': 'previous'
      });
    }

    /**
     * Initializes the accordion by animating the preset active pane(s).
     * @private
     */


    _createClass(Accordion, [{
      key: '_init',
      value: function _init() {
        this.$element.attr('role', 'tablist');
        this.$tabs = this.$element.children('li, [data-accordion-item]');

        this.$tabs.each(function (idx, el) {
          var $el = $(el),
              $content = $el.children('[data-tab-content]'),
              id = $content[0].id || Foundation.GetYoDigits(6, 'accordion'),
              linkId = el.id || id + '-label';

          $el.find('a:first').attr({
            'aria-controls': id,
            'role': 'tab',
            'id': linkId,
            'aria-expanded': false,
            'aria-selected': false
          });

          $content.attr({ 'role': 'tabpanel', 'aria-labelledby': linkId, 'aria-hidden': true, 'id': id });
        });
        var $initActive = this.$element.find('.is-active').children('[data-tab-content]');
        if ($initActive.length) {
          this.down($initActive, true);
        }
        this._events();
      }

      /**
       * Adds event handlers for items within the accordion.
       * @private
       */

    }, {
      key: '_events',
      value: function _events() {
        var _this = this;

        this.$tabs.each(function () {
          var $elem = $(this);
          var $tabContent = $elem.children('[data-tab-content]');
          if ($tabContent.length) {
            $elem.children('a').off('click.zf.accordion keydown.zf.accordion').on('click.zf.accordion', function (e) {
              // $(this).children('a').on('click.zf.accordion', function(e) {
              e.preventDefault();
              if ($elem.hasClass('is-active')) {
                if (_this.options.allowAllClosed || $elem.siblings().hasClass('is-active')) {
                  _this.up($tabContent);
                }
              } else {
                _this.down($tabContent);
              }
            }).on('keydown.zf.accordion', function (e) {
              Foundation.Keyboard.handleKey(e, 'Accordion', {
                toggle: function toggle() {
                  _this.toggle($tabContent);
                },
                next: function next() {
                  var $a = $elem.next().find('a').focus();
                  if (!_this.options.multiExpand) {
                    $a.trigger('click.zf.accordion');
                  }
                },
                previous: function previous() {
                  var $a = $elem.prev().find('a').focus();
                  if (!_this.options.multiExpand) {
                    $a.trigger('click.zf.accordion');
                  }
                },
                handled: function handled() {
                  e.preventDefault();
                  e.stopPropagation();
                }
              });
            });
          }
        });
      }

      /**
       * Toggles the selected content pane's open/close state.
       * @param {jQuery} $target - jQuery object of the pane to toggle.
       * @function
       */

    }, {
      key: 'toggle',
      value: function toggle($target) {
        if ($target.parent().hasClass('is-active')) {
          if (this.options.allowAllClosed || $target.parent().siblings().hasClass('is-active')) {
            this.up($target);
          } else {
            return;
          }
        } else {
          this.down($target);
        }
      }

      /**
       * Opens the accordion tab defined by `$target`.
       * @param {jQuery} $target - Accordion pane to open.
       * @param {Boolean} firstTime - flag to determine if reflow should happen.
       * @fires Accordion#down
       * @function
       */

    }, {
      key: 'down',
      value: function down($target, firstTime) {
        var _this2 = this;

        if (!this.options.multiExpand && !firstTime) {
          var $currentActive = this.$element.children('.is-active').children('[data-tab-content]');
          if ($currentActive.length) {
            this.up($currentActive);
          }
        }

        $target.attr('aria-hidden', false).parent('[data-tab-content]').addBack().parent().addClass('is-active');

        $target.slideDown(this.options.slideSpeed, function () {
          /**
           * Fires when the tab is done opening.
           * @event Accordion#down
           */
          _this2.$element.trigger('down.zf.accordion', [$target]);
        });

        $('#' + $target.attr('aria-labelledby')).attr({
          'aria-expanded': true,
          'aria-selected': true
        });
      }

      /**
       * Closes the tab defined by `$target`.
       * @param {jQuery} $target - Accordion tab to close.
       * @fires Accordion#up
       * @function
       */

    }, {
      key: 'up',
      value: function up($target) {
        var $aunts = $target.parent().siblings(),
            _this = this;
        var canClose = this.options.multiExpand ? $aunts.hasClass('is-active') : $target.parent().hasClass('is-active');

        if (!this.options.allowAllClosed && !canClose) {
          return;
        }

        // Foundation.Move(this.options.slideSpeed, $target, function(){
        $target.slideUp(_this.options.slideSpeed, function () {
          /**
           * Fires when the tab is done collapsing up.
           * @event Accordion#up
           */
          _this.$element.trigger('up.zf.accordion', [$target]);
        });
        // });

        $target.attr('aria-hidden', true).parent().removeClass('is-active');

        $('#' + $target.attr('aria-labelledby')).attr({
          'aria-expanded': false,
          'aria-selected': false
        });
      }

      /**
       * Destroys an instance of an accordion.
       * @fires Accordion#destroyed
       * @function
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        this.$element.find('[data-tab-content]').stop(true).slideUp(0).css('display', '');
        this.$element.find('a').off('.zf.accordion');

        Foundation.unregisterPlugin(this);
      }
    }]);

    return Accordion;
  }();

  Accordion.defaults = {
    /**
     * Amount of time to animate the opening of an accordion pane.
     * @option
     * @example 250
     */
    slideSpeed: 250,
    /**
     * Allow the accordion to have multiple open panes.
     * @option
     * @example false
     */
    multiExpand: false,
    /**
     * Allow the accordion to close all panes.
     * @option
     * @example false
     */
    allowAllClosed: false
  };

  // Window exports
  Foundation.plugin(Accordion, 'Accordion');
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * AccordionMenu module.
   * @module foundation.accordionMenu
   * @requires foundation.util.keyboard
   * @requires foundation.util.motion
   * @requires foundation.util.nest
   */

  var AccordionMenu = function () {
    /**
     * Creates a new instance of an accordion menu.
     * @class
     * @fires AccordionMenu#init
     * @param {jQuery} element - jQuery object to make into an accordion menu.
     * @param {Object} options - Overrides to the default plugin settings.
     */
    function AccordionMenu(element, options) {
      _classCallCheck(this, AccordionMenu);

      this.$element = element;
      this.options = $.extend({}, AccordionMenu.defaults, this.$element.data(), options);

      Foundation.Nest.Feather(this.$element, 'accordion');

      this._init();

      Foundation.registerPlugin(this, 'AccordionMenu');
      Foundation.Keyboard.register('AccordionMenu', {
        'ENTER': 'toggle',
        'SPACE': 'toggle',
        'ARROW_RIGHT': 'open',
        'ARROW_UP': 'up',
        'ARROW_DOWN': 'down',
        'ARROW_LEFT': 'close',
        'ESCAPE': 'closeAll',
        'TAB': 'down',
        'SHIFT_TAB': 'up'
      });
    }

    /**
     * Initializes the accordion menu by hiding all nested menus.
     * @private
     */


    _createClass(AccordionMenu, [{
      key: '_init',
      value: function _init() {
        this.$element.find('[data-submenu]').not('.is-active').slideUp(0); //.find('a').css('padding-left', '1rem');
        this.$element.attr({
          'role': 'tablist',
          'aria-multiselectable': this.options.multiOpen
        });

        this.$menuLinks = this.$element.find('.is-accordion-submenu-parent');
        this.$menuLinks.each(function () {
          var linkId = this.id || Foundation.GetYoDigits(6, 'acc-menu-link'),
              $elem = $(this),
              $sub = $elem.children('[data-submenu]'),
              subId = $sub[0].id || Foundation.GetYoDigits(6, 'acc-menu'),
              isActive = $sub.hasClass('is-active');
          $elem.attr({
            'aria-controls': subId,
            'aria-expanded': isActive,
            'role': 'tab',
            'id': linkId
          });
          $sub.attr({
            'aria-labelledby': linkId,
            'aria-hidden': !isActive,
            'role': 'tabpanel',
            'id': subId
          });
        });
        var initPanes = this.$element.find('.is-active');
        if (initPanes.length) {
          var _this = this;
          initPanes.each(function () {
            _this.down($(this));
          });
        }
        this._events();
      }

      /**
       * Adds event handlers for items within the menu.
       * @private
       */

    }, {
      key: '_events',
      value: function _events() {
        var _this = this;

        this.$element.find('li').each(function () {
          var $submenu = $(this).children('[data-submenu]');

          if ($submenu.length) {
            $(this).children('a').off('click.zf.accordionMenu').on('click.zf.accordionMenu', function (e) {
              e.preventDefault();

              _this.toggle($submenu);
            });
          }
        }).on('keydown.zf.accordionmenu', function (e) {
          var $element = $(this),
              $elements = $element.parent('ul').children('li'),
              $prevElement,
              $nextElement,
              $target = $element.children('[data-submenu]');

          $elements.each(function (i) {
            if ($(this).is($element)) {
              $prevElement = $elements.eq(Math.max(0, i - 1)).find('a').first();
              $nextElement = $elements.eq(Math.min(i + 1, $elements.length - 1)).find('a').first();

              if ($(this).children('[data-submenu]:visible').length) {
                // has open sub menu
                $nextElement = $element.find('li:first-child').find('a').first();
              }
              if ($(this).is(':first-child')) {
                // is first element of sub menu
                $prevElement = $element.parents('li').first().find('a').first();
              } else if ($prevElement.children('[data-submenu]:visible').length) {
                // if previous element has open sub menu
                $prevElement = $prevElement.find('li:last-child').find('a').first();
              }
              if ($(this).is(':last-child')) {
                // is last element of sub menu
                $nextElement = $element.parents('li').first().next('li').find('a').first();
              }

              return;
            }
          });
          Foundation.Keyboard.handleKey(e, 'AccordionMenu', {
            open: function open() {
              if ($target.is(':hidden')) {
                _this.down($target);
                $target.find('li').first().find('a').first().focus();
              }
            },
            close: function close() {
              if ($target.length && !$target.is(':hidden')) {
                // close active sub of this item
                _this.up($target);
              } else if ($element.parent('[data-submenu]').length) {
                // close currently open sub
                _this.up($element.parent('[data-submenu]'));
                $element.parents('li').first().find('a').first().focus();
              }
            },
            up: function up() {
              $prevElement.attr('tabindex', -1).focus();
              return true;
            },
            down: function down() {
              $nextElement.attr('tabindex', -1).focus();
              return true;
            },
            toggle: function toggle() {
              if ($element.children('[data-submenu]').length) {
                _this.toggle($element.children('[data-submenu]'));
              }
            },
            closeAll: function closeAll() {
              _this.hideAll();
            },
            handled: function handled(preventDefault) {
              if (preventDefault) {
                e.preventDefault();
              }
              e.stopImmediatePropagation();
            }
          });
        }); //.attr('tabindex', 0);
      }

      /**
       * Closes all panes of the menu.
       * @function
       */

    }, {
      key: 'hideAll',
      value: function hideAll() {
        this.$element.find('[data-submenu]').slideUp(this.options.slideSpeed);
      }

      /**
       * Toggles the open/close state of a submenu.
       * @function
       * @param {jQuery} $target - the submenu to toggle
       */

    }, {
      key: 'toggle',
      value: function toggle($target) {
        if (!$target.is(':animated')) {
          if (!$target.is(':hidden')) {
            this.up($target);
          } else {
            this.down($target);
          }
        }
      }

      /**
       * Opens the sub-menu defined by `$target`.
       * @param {jQuery} $target - Sub-menu to open.
       * @fires AccordionMenu#down
       */

    }, {
      key: 'down',
      value: function down($target) {
        var _this = this;

        if (!this.options.multiOpen) {
          this.up(this.$element.find('.is-active').not($target.parentsUntil(this.$element).add($target)));
        }

        $target.addClass('is-active').attr({ 'aria-hidden': false }).parent('.is-accordion-submenu-parent').attr({ 'aria-expanded': true });

        //Foundation.Move(this.options.slideSpeed, $target, function() {
        $target.slideDown(_this.options.slideSpeed, function () {
          /**
           * Fires when the menu is done opening.
           * @event AccordionMenu#down
           */
          _this.$element.trigger('down.zf.accordionMenu', [$target]);
        });
        //});
      }

      /**
       * Closes the sub-menu defined by `$target`. All sub-menus inside the target will be closed as well.
       * @param {jQuery} $target - Sub-menu to close.
       * @fires AccordionMenu#up
       */

    }, {
      key: 'up',
      value: function up($target) {
        var _this = this;
        //Foundation.Move(this.options.slideSpeed, $target, function(){
        $target.slideUp(_this.options.slideSpeed, function () {
          /**
           * Fires when the menu is done collapsing up.
           * @event AccordionMenu#up
           */
          _this.$element.trigger('up.zf.accordionMenu', [$target]);
        });
        //});

        var $menus = $target.find('[data-submenu]').slideUp(0).addBack().attr('aria-hidden', true);

        $menus.parent('.is-accordion-submenu-parent').attr('aria-expanded', false);
      }

      /**
       * Destroys an instance of accordion menu.
       * @fires AccordionMenu#destroyed
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        this.$element.find('[data-submenu]').slideDown(0).css('display', '');
        this.$element.find('a').off('click.zf.accordionMenu');

        Foundation.Nest.Burn(this.$element, 'accordion');
        Foundation.unregisterPlugin(this);
      }
    }]);

    return AccordionMenu;
  }();

  AccordionMenu.defaults = {
    /**
     * Amount of time to animate the opening of a submenu in ms.
     * @option
     * @example 250
     */
    slideSpeed: 250,
    /**
     * Allow the menu to have multiple open panes.
     * @option
     * @example true
     */
    multiOpen: true
  };

  // Window exports
  Foundation.plugin(AccordionMenu, 'AccordionMenu');
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * Drilldown module.
   * @module foundation.drilldown
   * @requires foundation.util.keyboard
   * @requires foundation.util.motion
   * @requires foundation.util.nest
   */

  var Drilldown = function () {
    /**
     * Creates a new instance of a drilldown menu.
     * @class
     * @param {jQuery} element - jQuery object to make into an accordion menu.
     * @param {Object} options - Overrides to the default plugin settings.
     */
    function Drilldown(element, options) {
      _classCallCheck(this, Drilldown);

      this.$element = element;
      this.options = $.extend({}, Drilldown.defaults, this.$element.data(), options);

      Foundation.Nest.Feather(this.$element, 'drilldown');

      this._init();

      Foundation.registerPlugin(this, 'Drilldown');
      Foundation.Keyboard.register('Drilldown', {
        'ENTER': 'open',
        'SPACE': 'open',
        'ARROW_RIGHT': 'next',
        'ARROW_UP': 'up',
        'ARROW_DOWN': 'down',
        'ARROW_LEFT': 'previous',
        'ESCAPE': 'close',
        'TAB': 'down',
        'SHIFT_TAB': 'up'
      });
    }

    /**
     * Initializes the drilldown by creating jQuery collections of elements
     * @private
     */


    _createClass(Drilldown, [{
      key: '_init',
      value: function _init() {
        this.$submenuAnchors = this.$element.find('li.is-drilldown-submenu-parent').children('a');
        this.$submenus = this.$submenuAnchors.parent('li').children('[data-submenu]');
        this.$menuItems = this.$element.find('li').not('.js-drilldown-back').attr('role', 'menuitem').find('a');

        this._prepareMenu();

        this._keyboardEvents();
      }

      /**
       * prepares drilldown menu by setting attributes to links and elements
       * sets a min height to prevent content jumping
       * wraps the element if not already wrapped
       * @private
       * @function
       */

    }, {
      key: '_prepareMenu',
      value: function _prepareMenu() {
        var _this = this;
        // if(!this.options.holdOpen){
        //   this._menuLinkEvents();
        // }
        this.$submenuAnchors.each(function () {
          var $link = $(this);
          var $sub = $link.parent();
          if (_this.options.parentLink) {
            $link.clone().prependTo($sub.children('[data-submenu]')).wrap('<li class="is-submenu-parent-item is-submenu-item is-drilldown-submenu-item" role="menu-item"></li>');
          }
          $link.data('savedHref', $link.attr('href')).removeAttr('href');
          $link.children('[data-submenu]').attr({
            'aria-hidden': true,
            'tabindex': 0,
            'role': 'menu'
          });
          _this._events($link);
        });
        this.$submenus.each(function () {
          var $menu = $(this),
              $back = $menu.find('.js-drilldown-back');
          if (!$back.length) {
            $menu.prepend(_this.options.backButton);
          }
          _this._back($menu);
        });
        if (!this.$element.parent().hasClass('is-drilldown')) {
          this.$wrapper = $(this.options.wrapper).addClass('is-drilldown');
          this.$wrapper = this.$element.wrap(this.$wrapper).parent().css(this._getMaxDims());
        }
      }

      /**
       * Adds event handlers to elements in the menu.
       * @function
       * @private
       * @param {jQuery} $elem - the current menu item to add handlers to.
       */

    }, {
      key: '_events',
      value: function _events($elem) {
        var _this = this;

        $elem.off('click.zf.drilldown').on('click.zf.drilldown', function (e) {
          if ($(e.target).parentsUntil('ul', 'li').hasClass('is-drilldown-submenu-parent')) {
            e.stopImmediatePropagation();
            e.preventDefault();
          }

          // if(e.target !== e.currentTarget.firstElementChild){
          //   return false;
          // }
          _this._show($elem.parent('li'));

          if (_this.options.closeOnClick) {
            var $body = $('body');
            $body.off('.zf.drilldown').on('click.zf.drilldown', function (e) {
              if (e.target === _this.$element[0] || $.contains(_this.$element[0], e.target)) {
                return;
              }
              e.preventDefault();
              _this._hideAll();
              $body.off('.zf.drilldown');
            });
          }
        });
      }

      /**
       * Adds keydown event listener to `li`'s in the menu.
       * @private
       */

    }, {
      key: '_keyboardEvents',
      value: function _keyboardEvents() {
        var _this = this;

        this.$menuItems.add(this.$element.find('.js-drilldown-back > a')).on('keydown.zf.drilldown', function (e) {

          var $element = $(this),
              $elements = $element.parent('li').parent('ul').children('li').children('a'),
              $prevElement,
              $nextElement;

          $elements.each(function (i) {
            if ($(this).is($element)) {
              $prevElement = $elements.eq(Math.max(0, i - 1));
              $nextElement = $elements.eq(Math.min(i + 1, $elements.length - 1));
              return;
            }
          });

          Foundation.Keyboard.handleKey(e, 'Drilldown', {
            next: function next() {
              if ($element.is(_this.$submenuAnchors)) {
                _this._show($element.parent('li'));
                $element.parent('li').one(Foundation.transitionend($element), function () {
                  $element.parent('li').find('ul li a').filter(_this.$menuItems).first().focus();
                });
                return true;
              }
            },
            previous: function previous() {
              _this._hide($element.parent('li').parent('ul'));
              $element.parent('li').parent('ul').one(Foundation.transitionend($element), function () {
                setTimeout(function () {
                  $element.parent('li').parent('ul').parent('li').children('a').first().focus();
                }, 1);
              });
              return true;
            },
            up: function up() {
              $prevElement.focus();
              return true;
            },
            down: function down() {
              $nextElement.focus();
              return true;
            },
            close: function close() {
              _this._back();
              //_this.$menuItems.first().focus(); // focus to first element
            },
            open: function open() {
              if (!$element.is(_this.$menuItems)) {
                // not menu item means back button
                _this._hide($element.parent('li').parent('ul'));
                $element.parent('li').parent('ul').one(Foundation.transitionend($element), function () {
                  setTimeout(function () {
                    $element.parent('li').parent('ul').parent('li').children('a').first().focus();
                  }, 1);
                });
              } else if ($element.is(_this.$submenuAnchors)) {
                _this._show($element.parent('li'));
                $element.parent('li').one(Foundation.transitionend($element), function () {
                  $element.parent('li').find('ul li a').filter(_this.$menuItems).first().focus();
                });
              }
              return true;
            },
            handled: function handled(preventDefault) {
              if (preventDefault) {
                e.preventDefault();
              }
              e.stopImmediatePropagation();
            }
          });
        }); // end keyboardAccess
      }

      /**
       * Closes all open elements, and returns to root menu.
       * @function
       * @fires Drilldown#closed
       */

    }, {
      key: '_hideAll',
      value: function _hideAll() {
        var $elem = this.$element.find('.is-drilldown-submenu.is-active').addClass('is-closing');
        $elem.one(Foundation.transitionend($elem), function (e) {
          $elem.removeClass('is-active is-closing');
        });
        /**
         * Fires when the menu is fully closed.
         * @event Drilldown#closed
         */
        this.$element.trigger('closed.zf.drilldown');
      }

      /**
       * Adds event listener for each `back` button, and closes open menus.
       * @function
       * @fires Drilldown#back
       * @param {jQuery} $elem - the current sub-menu to add `back` event.
       */

    }, {
      key: '_back',
      value: function _back($elem) {
        var _this = this;
        $elem.off('click.zf.drilldown');
        $elem.children('.js-drilldown-back').on('click.zf.drilldown', function (e) {
          e.stopImmediatePropagation();
          // console.log('mouseup on back');
          _this._hide($elem);
        });
      }

      /**
       * Adds event listener to menu items w/o submenus to close open menus on click.
       * @function
       * @private
       */

    }, {
      key: '_menuLinkEvents',
      value: function _menuLinkEvents() {
        var _this = this;
        this.$menuItems.not('.is-drilldown-submenu-parent').off('click.zf.drilldown').on('click.zf.drilldown', function (e) {
          // e.stopImmediatePropagation();
          setTimeout(function () {
            _this._hideAll();
          }, 0);
        });
      }

      /**
       * Opens a submenu.
       * @function
       * @fires Drilldown#open
       * @param {jQuery} $elem - the current element with a submenu to open, i.e. the `li` tag.
       */

    }, {
      key: '_show',
      value: function _show($elem) {
        $elem.children('[data-submenu]').addClass('is-active');
        /**
         * Fires when the submenu has opened.
         * @event Drilldown#open
         */
        this.$element.trigger('open.zf.drilldown', [$elem]);
      }
    }, {
      key: '_hide',


      /**
       * Hides a submenu
       * @function
       * @fires Drilldown#hide
       * @param {jQuery} $elem - the current sub-menu to hide, i.e. the `ul` tag.
       */
      value: function _hide($elem) {
        var _this = this;
        $elem.addClass('is-closing').one(Foundation.transitionend($elem), function () {
          $elem.removeClass('is-active is-closing');
          $elem.blur();
        });
        /**
         * Fires when the submenu has closed.
         * @event Drilldown#hide
         */
        $elem.trigger('hide.zf.drilldown', [$elem]);
      }

      /**
       * Iterates through the nested menus to calculate the min-height, and max-width for the menu.
       * Prevents content jumping.
       * @function
       * @private
       */

    }, {
      key: '_getMaxDims',
      value: function _getMaxDims() {
        var max = 0,
            result = {};
        this.$submenus.add(this.$element).each(function () {
          var numOfElems = $(this).children('li').length;
          max = numOfElems > max ? numOfElems : max;
        });

        result['min-height'] = max * this.$menuItems[0].getBoundingClientRect().height + 'px';
        result['max-width'] = this.$element[0].getBoundingClientRect().width + 'px';

        return result;
      }

      /**
       * Destroys the Drilldown Menu
       * @function
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        this._hideAll();
        Foundation.Nest.Burn(this.$element, 'drilldown');
        this.$element.unwrap().find('.js-drilldown-back, .is-submenu-parent-item').remove().end().find('.is-active, .is-closing, .is-drilldown-submenu').removeClass('is-active is-closing is-drilldown-submenu').end().find('[data-submenu]').removeAttr('aria-hidden tabindex role');
        this.$submenuAnchors.each(function () {
          $(this).off('.zf.drilldown');
        });
        this.$element.find('a').each(function () {
          var $link = $(this);
          if ($link.data('savedHref')) {
            $link.attr('href', $link.data('savedHref')).removeData('savedHref');
          } else {
            return;
          }
        });
        Foundation.unregisterPlugin(this);
      }
    }]);

    return Drilldown;
  }();

  Drilldown.defaults = {
    /**
     * Markup used for JS generated back button. Prepended to submenu lists and deleted on `destroy` method, 'js-drilldown-back' class required. Remove the backslash (`\`) if copy and pasting.
     * @option
     * @example '<\li><\a>Back<\/a><\/li>'
     */
    backButton: '<li class="js-drilldown-back"><a tabindex="0">Back</a></li>',
    /**
     * Markup used to wrap drilldown menu. Use a class name for independent styling; the JS applied class: `is-drilldown` is required. Remove the backslash (`\`) if copy and pasting.
     * @option
     * @example '<\div class="is-drilldown"><\/div>'
     */
    wrapper: '<div></div>',
    /**
     * Adds the parent link to the submenu.
     * @option
     * @example false
     */
    parentLink: false,
    /**
     * Allow the menu to return to root list on body click.
     * @option
     * @example false
     */
    closeOnClick: false
    // holdOpen: false
  };

  // Window exports
  Foundation.plugin(Drilldown, 'Drilldown');
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * Dropdown module.
   * @module foundation.dropdown
   * @requires foundation.util.keyboard
   * @requires foundation.util.box
   * @requires foundation.util.triggers
   */

  var Dropdown = function () {
    /**
     * Creates a new instance of a dropdown.
     * @class
     * @param {jQuery} element - jQuery object to make into a dropdown.
     *        Object should be of the dropdown panel, rather than its anchor.
     * @param {Object} options - Overrides to the default plugin settings.
     */
    function Dropdown(element, options) {
      _classCallCheck(this, Dropdown);

      this.$element = element;
      this.options = $.extend({}, Dropdown.defaults, this.$element.data(), options);
      this._init();

      Foundation.registerPlugin(this, 'Dropdown');
      Foundation.Keyboard.register('Dropdown', {
        'ENTER': 'open',
        'SPACE': 'open',
        'ESCAPE': 'close',
        'TAB': 'tab_forward',
        'SHIFT_TAB': 'tab_backward'
      });
    }

    /**
     * Initializes the plugin by setting/checking options and attributes, adding helper variables, and saving the anchor.
     * @function
     * @private
     */


    _createClass(Dropdown, [{
      key: '_init',
      value: function _init() {
        var $id = this.$element.attr('id');

        this.$anchor = $('[data-toggle="' + $id + '"]') || $('[data-open="' + $id + '"]');
        this.$anchor.attr({
          'aria-controls': $id,
          'data-is-focus': false,
          'data-yeti-box': $id,
          'aria-haspopup': true,
          'aria-expanded': false

        });

        this.options.positionClass = this.getPositionClass();
        this.counter = 4;
        this.usedPositions = [];
        this.$element.attr({
          'aria-hidden': 'true',
          'data-yeti-box': $id,
          'data-resize': $id,
          'aria-labelledby': this.$anchor[0].id || Foundation.GetYoDigits(6, 'dd-anchor')
        });
        this._events();
      }

      /**
       * Helper function to determine current orientation of dropdown pane.
       * @function
       * @returns {String} position - string value of a position class.
       */

    }, {
      key: 'getPositionClass',
      value: function getPositionClass() {
        var verticalPosition = this.$element[0].className.match(/(top|left|right|bottom)/g);
        verticalPosition = verticalPosition ? verticalPosition[0] : '';
        var horizontalPosition = /float-(\S+)\s/.exec(this.$anchor[0].className);
        horizontalPosition = horizontalPosition ? horizontalPosition[1] : '';
        var position = horizontalPosition ? horizontalPosition + ' ' + verticalPosition : verticalPosition;
        return position;
      }

      /**
       * Adjusts the dropdown panes orientation by adding/removing positioning classes.
       * @function
       * @private
       * @param {String} position - position class to remove.
       */

    }, {
      key: '_reposition',
      value: function _reposition(position) {
        this.usedPositions.push(position ? position : 'bottom');
        //default, try switching to opposite side
        if (!position && this.usedPositions.indexOf('top') < 0) {
          this.$element.addClass('top');
        } else if (position === 'top' && this.usedPositions.indexOf('bottom') < 0) {
          this.$element.removeClass(position);
        } else if (position === 'left' && this.usedPositions.indexOf('right') < 0) {
          this.$element.removeClass(position).addClass('right');
        } else if (position === 'right' && this.usedPositions.indexOf('left') < 0) {
          this.$element.removeClass(position).addClass('left');
        }

        //if default change didn't work, try bottom or left first
        else if (!position && this.usedPositions.indexOf('top') > -1 && this.usedPositions.indexOf('left') < 0) {
            this.$element.addClass('left');
          } else if (position === 'top' && this.usedPositions.indexOf('bottom') > -1 && this.usedPositions.indexOf('left') < 0) {
            this.$element.removeClass(position).addClass('left');
          } else if (position === 'left' && this.usedPositions.indexOf('right') > -1 && this.usedPositions.indexOf('bottom') < 0) {
            this.$element.removeClass(position);
          } else if (position === 'right' && this.usedPositions.indexOf('left') > -1 && this.usedPositions.indexOf('bottom') < 0) {
            this.$element.removeClass(position);
          }
          //if nothing cleared, set to bottom
          else {
              this.$element.removeClass(position);
            }
        this.classChanged = true;
        this.counter--;
      }

      /**
       * Sets the position and orientation of the dropdown pane, checks for collisions.
       * Recursively calls itself if a collision is detected, with a new position class.
       * @function
       * @private
       */

    }, {
      key: '_setPosition',
      value: function _setPosition() {
        if (this.$anchor.attr('aria-expanded') === 'false') {
          return false;
        }
        var position = this.getPositionClass(),
            $eleDims = Foundation.Box.GetDimensions(this.$element),
            $anchorDims = Foundation.Box.GetDimensions(this.$anchor),
            _this = this,
            direction = position === 'left' ? 'left' : position === 'right' ? 'left' : 'top',
            param = direction === 'top' ? 'height' : 'width',
            offset = param === 'height' ? this.options.vOffset : this.options.hOffset;

        if ($eleDims.width >= $eleDims.windowDims.width || !this.counter && !Foundation.Box.ImNotTouchingYou(this.$element)) {
          this.$element.offset(Foundation.Box.GetOffsets(this.$element, this.$anchor, 'center bottom', this.options.vOffset, this.options.hOffset, true)).css({
            'width': $eleDims.windowDims.width - this.options.hOffset * 2,
            'height': 'auto'
          });
          this.classChanged = true;
          return false;
        }

        this.$element.offset(Foundation.Box.GetOffsets(this.$element, this.$anchor, position, this.options.vOffset, this.options.hOffset));

        while (!Foundation.Box.ImNotTouchingYou(this.$element, false, true) && this.counter) {
          this._reposition(position);
          this._setPosition();
        }
      }

      /**
       * Adds event listeners to the element utilizing the triggers utility library.
       * @function
       * @private
       */

    }, {
      key: '_events',
      value: function _events() {
        var _this = this;
        this.$element.on({
          'open.zf.trigger': this.open.bind(this),
          'close.zf.trigger': this.close.bind(this),
          'toggle.zf.trigger': this.toggle.bind(this),
          'resizeme.zf.trigger': this._setPosition.bind(this)
        });

        if (this.options.hover) {
          this.$anchor.off('mouseenter.zf.dropdown mouseleave.zf.dropdown').on('mouseenter.zf.dropdown', function () {
            clearTimeout(_this.timeout);
            _this.timeout = setTimeout(function () {
              _this.open();
              _this.$anchor.data('hover', true);
            }, _this.options.hoverDelay);
          }).on('mouseleave.zf.dropdown', function () {
            clearTimeout(_this.timeout);
            _this.timeout = setTimeout(function () {
              _this.close();
              _this.$anchor.data('hover', false);
            }, _this.options.hoverDelay);
          });
          if (this.options.hoverPane) {
            this.$element.off('mouseenter.zf.dropdown mouseleave.zf.dropdown').on('mouseenter.zf.dropdown', function () {
              clearTimeout(_this.timeout);
            }).on('mouseleave.zf.dropdown', function () {
              clearTimeout(_this.timeout);
              _this.timeout = setTimeout(function () {
                _this.close();
                _this.$anchor.data('hover', false);
              }, _this.options.hoverDelay);
            });
          }
        }
        this.$anchor.add(this.$element).on('keydown.zf.dropdown', function (e) {

          var $target = $(this),
              visibleFocusableElements = Foundation.Keyboard.findFocusable(_this.$element);

          Foundation.Keyboard.handleKey(e, 'Dropdown', {
            tab_forward: function tab_forward() {
              if (_this.$element.find(':focus').is(visibleFocusableElements.eq(-1))) {
                // left modal downwards, setting focus to first element
                if (_this.options.trapFocus) {
                  // if focus shall be trapped
                  visibleFocusableElements.eq(0).focus();
                  e.preventDefault();
                } else {
                  // if focus is not trapped, close dropdown on focus out
                  _this.close();
                }
              }
            },
            tab_backward: function tab_backward() {
              if (_this.$element.find(':focus').is(visibleFocusableElements.eq(0)) || _this.$element.is(':focus')) {
                // left modal upwards, setting focus to last element
                if (_this.options.trapFocus) {
                  // if focus shall be trapped
                  visibleFocusableElements.eq(-1).focus();
                  e.preventDefault();
                } else {
                  // if focus is not trapped, close dropdown on focus out
                  _this.close();
                }
              }
            },
            open: function open() {
              if ($target.is(_this.$anchor)) {
                _this.open();
                _this.$element.attr('tabindex', -1).focus();
                e.preventDefault();
              }
            },
            close: function close() {
              _this.close();
              _this.$anchor.focus();
            }
          });
        });
      }

      /**
       * Adds an event handler to the body to close any dropdowns on a click.
       * @function
       * @private
       */

    }, {
      key: '_addBodyHandler',
      value: function _addBodyHandler() {
        var $body = $(document.body).not(this.$element),
            _this = this;
        $body.off('click.zf.dropdown').on('click.zf.dropdown', function (e) {
          if (_this.$anchor.is(e.target) || _this.$anchor.find(e.target).length) {
            return;
          }
          if (_this.$element.find(e.target).length) {
            return;
          }
          _this.close();
          $body.off('click.zf.dropdown');
        });
      }

      /**
       * Opens the dropdown pane, and fires a bubbling event to close other dropdowns.
       * @function
       * @fires Dropdown#closeme
       * @fires Dropdown#show
       */

    }, {
      key: 'open',
      value: function open() {
        // var _this = this;
        /**
         * Fires to close other open dropdowns
         * @event Dropdown#closeme
         */
        this.$element.trigger('closeme.zf.dropdown', this.$element.attr('id'));
        this.$anchor.addClass('hover').attr({ 'aria-expanded': true });
        // this.$element/*.show()*/;
        this._setPosition();
        this.$element.addClass('is-open').attr({ 'aria-hidden': false });

        if (this.options.autoFocus) {
          var $focusable = Foundation.Keyboard.findFocusable(this.$element);
          if ($focusable.length) {
            $focusable.eq(0).focus();
          }
        }

        if (this.options.closeOnClick) {
          this._addBodyHandler();
        }

        /**
         * Fires once the dropdown is visible.
         * @event Dropdown#show
         */
        this.$element.trigger('show.zf.dropdown', [this.$element]);
      }

      /**
       * Closes the open dropdown pane.
       * @function
       * @fires Dropdown#hide
       */

    }, {
      key: 'close',
      value: function close() {
        if (!this.$element.hasClass('is-open')) {
          return false;
        }
        this.$element.removeClass('is-open').attr({ 'aria-hidden': true });

        this.$anchor.removeClass('hover').attr('aria-expanded', false);

        if (this.classChanged) {
          var curPositionClass = this.getPositionClass();
          if (curPositionClass) {
            this.$element.removeClass(curPositionClass);
          }
          this.$element.addClass(this.options.positionClass)
          /*.hide()*/.css({ height: '', width: '' });
          this.classChanged = false;
          this.counter = 4;
          this.usedPositions.length = 0;
        }
        this.$element.trigger('hide.zf.dropdown', [this.$element]);
      }

      /**
       * Toggles the dropdown pane's visibility.
       * @function
       */

    }, {
      key: 'toggle',
      value: function toggle() {
        if (this.$element.hasClass('is-open')) {
          if (this.$anchor.data('hover')) return;
          this.close();
        } else {
          this.open();
        }
      }

      /**
       * Destroys the dropdown.
       * @function
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        this.$element.off('.zf.trigger').hide();
        this.$anchor.off('.zf.dropdown');

        Foundation.unregisterPlugin(this);
      }
    }]);

    return Dropdown;
  }();

  Dropdown.defaults = {
    /**
     * Amount of time to delay opening a submenu on hover event.
     * @option
     * @example 250
     */
    hoverDelay: 250,
    /**
     * Allow submenus to open on hover events
     * @option
     * @example false
     */
    hover: false,
    /**
     * Don't close dropdown when hovering over dropdown pane
     * @option
     * @example true
     */
    hoverPane: false,
    /**
     * Number of pixels between the dropdown pane and the triggering element on open.
     * @option
     * @example 1
     */
    vOffset: 1,
    /**
     * Number of pixels between the dropdown pane and the triggering element on open.
     * @option
     * @example 1
     */
    hOffset: 1,
    /**
     * Class applied to adjust open position. JS will test and fill this in.
     * @option
     * @example 'top'
     */
    positionClass: '',
    /**
     * Allow the plugin to trap focus to the dropdown pane if opened with keyboard commands.
     * @option
     * @example false
     */
    trapFocus: false,
    /**
     * Allow the plugin to set focus to the first focusable element within the pane, regardless of method of opening.
     * @option
     * @example true
     */
    autoFocus: false,
    /**
     * Allows a click on the body to close the dropdown.
     * @option
     * @example false
     */
    closeOnClick: false
  };

  // Window exports
  Foundation.plugin(Dropdown, 'Dropdown');
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * DropdownMenu module.
   * @module foundation.dropdown-menu
   * @requires foundation.util.keyboard
   * @requires foundation.util.box
   * @requires foundation.util.nest
   */

  var DropdownMenu = function () {
    /**
     * Creates a new instance of DropdownMenu.
     * @class
     * @fires DropdownMenu#init
     * @param {jQuery} element - jQuery object to make into a dropdown menu.
     * @param {Object} options - Overrides to the default plugin settings.
     */
    function DropdownMenu(element, options) {
      _classCallCheck(this, DropdownMenu);

      this.$element = element;
      this.options = $.extend({}, DropdownMenu.defaults, this.$element.data(), options);

      Foundation.Nest.Feather(this.$element, 'dropdown');
      this._init();

      Foundation.registerPlugin(this, 'DropdownMenu');
      Foundation.Keyboard.register('DropdownMenu', {
        'ENTER': 'open',
        'SPACE': 'open',
        'ARROW_RIGHT': 'next',
        'ARROW_UP': 'up',
        'ARROW_DOWN': 'down',
        'ARROW_LEFT': 'previous',
        'ESCAPE': 'close'
      });
    }

    /**
     * Initializes the plugin, and calls _prepareMenu
     * @private
     * @function
     */


    _createClass(DropdownMenu, [{
      key: '_init',
      value: function _init() {
        var subs = this.$element.find('li.is-dropdown-submenu-parent');
        this.$element.children('.is-dropdown-submenu-parent').children('.is-dropdown-submenu').addClass('first-sub');

        this.$menuItems = this.$element.find('[role="menuitem"]');
        this.$tabs = this.$element.children('[role="menuitem"]');
        this.$tabs.find('ul.is-dropdown-submenu').addClass(this.options.verticalClass);

        if (this.$element.hasClass(this.options.rightClass) || this.options.alignment === 'right' || Foundation.rtl() || this.$element.parents('.top-bar-right').is('*')) {
          this.options.alignment = 'right';
          subs.addClass('opens-left');
        } else {
          subs.addClass('opens-right');
        }
        this.changed = false;
        this._events();
      }
    }, {
      key: '_events',

      /**
       * Adds event listeners to elements within the menu
       * @private
       * @function
       */
      value: function _events() {
        var _this = this,
            hasTouch = 'ontouchstart' in window || typeof window.ontouchstart !== 'undefined',
            parClass = 'is-dropdown-submenu-parent';

        // used for onClick and in the keyboard handlers
        var handleClickFn = function handleClickFn(e) {
          var $elem = $(e.target).parentsUntil('ul', '.' + parClass),
              hasSub = $elem.hasClass(parClass),
              hasClicked = $elem.attr('data-is-click') === 'true',
              $sub = $elem.children('.is-dropdown-submenu');

          if (hasSub) {
            if (hasClicked) {
              if (!_this.options.closeOnClick || !_this.options.clickOpen && !hasTouch || _this.options.forceFollow && hasTouch) {
                return;
              } else {
                e.stopImmediatePropagation();
                e.preventDefault();
                _this._hide($elem);
              }
            } else {
              e.preventDefault();
              e.stopImmediatePropagation();
              _this._show($elem.children('.is-dropdown-submenu'));
              $elem.add($elem.parentsUntil(_this.$element, '.' + parClass)).attr('data-is-click', true);
            }
          } else {
            return;
          }
        };

        if (this.options.clickOpen || hasTouch) {
          this.$menuItems.on('click.zf.dropdownmenu touchstart.zf.dropdownmenu', handleClickFn);
        }

        if (!this.options.disableHover) {
          this.$menuItems.on('mouseenter.zf.dropdownmenu', function (e) {
            var $elem = $(this),
                hasSub = $elem.hasClass(parClass);

            if (hasSub) {
              clearTimeout(_this.delay);
              _this.delay = setTimeout(function () {
                _this._show($elem.children('.is-dropdown-submenu'));
              }, _this.options.hoverDelay);
            }
          }).on('mouseleave.zf.dropdownmenu', function (e) {
            var $elem = $(this),
                hasSub = $elem.hasClass(parClass);
            if (hasSub && _this.options.autoclose) {
              if ($elem.attr('data-is-click') === 'true' && _this.options.clickOpen) {
                return false;
              }

              clearTimeout(_this.delay);
              _this.delay = setTimeout(function () {
                _this._hide($elem);
              }, _this.options.closingTime);
            }
          });
        }
        this.$menuItems.on('keydown.zf.dropdownmenu', function (e) {
          var $element = $(e.target).parentsUntil('ul', '[role="menuitem"]'),
              isTab = _this.$tabs.index($element) > -1,
              $elements = isTab ? _this.$tabs : $element.siblings('li').add($element),
              $prevElement,
              $nextElement;

          $elements.each(function (i) {
            if ($(this).is($element)) {
              $prevElement = $elements.eq(i - 1);
              $nextElement = $elements.eq(i + 1);
              return;
            }
          });

          var nextSibling = function nextSibling() {
            if (!$element.is(':last-child')) {
              $nextElement.children('a:first').focus();
              e.preventDefault();
            }
          },
              prevSibling = function prevSibling() {
            $prevElement.children('a:first').focus();
            e.preventDefault();
          },
              openSub = function openSub() {
            var $sub = $element.children('ul.is-dropdown-submenu');
            if ($sub.length) {
              _this._show($sub);
              $element.find('li > a:first').focus();
              e.preventDefault();
            } else {
              return;
            }
          },
              closeSub = function closeSub() {
            //if ($element.is(':first-child')) {
            var close = $element.parent('ul').parent('li');
            close.children('a:first').focus();
            _this._hide(close);
            e.preventDefault();
            //}
          };
          var functions = {
            open: openSub,
            close: function close() {
              _this._hide(_this.$element);
              _this.$menuItems.find('a:first').focus(); // focus to first element
              e.preventDefault();
            },
            handled: function handled() {
              e.stopImmediatePropagation();
            }
          };

          if (isTab) {
            if (_this.$element.hasClass(_this.options.verticalClass)) {
              // vertical menu
              if (_this.options.alignment === 'left') {
                // left aligned
                $.extend(functions, {
                  down: nextSibling,
                  up: prevSibling,
                  next: openSub,
                  previous: closeSub
                });
              } else {
                // right aligned
                $.extend(functions, {
                  down: nextSibling,
                  up: prevSibling,
                  next: closeSub,
                  previous: openSub
                });
              }
            } else {
              // horizontal menu
              $.extend(functions, {
                next: nextSibling,
                previous: prevSibling,
                down: openSub,
                up: closeSub
              });
            }
          } else {
            // not tabs -> one sub
            if (_this.options.alignment === 'left') {
              // left aligned
              $.extend(functions, {
                next: openSub,
                previous: closeSub,
                down: nextSibling,
                up: prevSibling
              });
            } else {
              // right aligned
              $.extend(functions, {
                next: closeSub,
                previous: openSub,
                down: nextSibling,
                up: prevSibling
              });
            }
          }
          Foundation.Keyboard.handleKey(e, 'DropdownMenu', functions);
        });
      }

      /**
       * Adds an event handler to the body to close any dropdowns on a click.
       * @function
       * @private
       */

    }, {
      key: '_addBodyHandler',
      value: function _addBodyHandler() {
        var $body = $(document.body),
            _this = this;
        $body.off('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu').on('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu', function (e) {
          var $link = _this.$element.find(e.target);
          if ($link.length) {
            return;
          }

          _this._hide();
          $body.off('mouseup.zf.dropdownmenu touchend.zf.dropdownmenu');
        });
      }

      /**
       * Opens a dropdown pane, and checks for collisions first.
       * @param {jQuery} $sub - ul element that is a submenu to show
       * @function
       * @private
       * @fires DropdownMenu#show
       */

    }, {
      key: '_show',
      value: function _show($sub) {
        var idx = this.$tabs.index(this.$tabs.filter(function (i, el) {
          return $(el).find($sub).length > 0;
        }));
        var $sibs = $sub.parent('li.is-dropdown-submenu-parent').siblings('li.is-dropdown-submenu-parent');
        this._hide($sibs, idx);
        $sub.css('visibility', 'hidden').addClass('js-dropdown-active').attr({ 'aria-hidden': false }).parent('li.is-dropdown-submenu-parent').addClass('is-active').attr({ 'aria-expanded': true });
        var clear = Foundation.Box.ImNotTouchingYou($sub, null, true);
        if (!clear) {
          var oldClass = this.options.alignment === 'left' ? '-right' : '-left',
              $parentLi = $sub.parent('.is-dropdown-submenu-parent');
          $parentLi.removeClass('opens' + oldClass).addClass('opens-' + this.options.alignment);
          clear = Foundation.Box.ImNotTouchingYou($sub, null, true);
          if (!clear) {
            $parentLi.removeClass('opens-' + this.options.alignment).addClass('opens-inner');
          }
          this.changed = true;
        }
        $sub.css('visibility', '');
        if (this.options.closeOnClick) {
          this._addBodyHandler();
        }
        /**
         * Fires when the new dropdown pane is visible.
         * @event DropdownMenu#show
         */
        this.$element.trigger('show.zf.dropdownmenu', [$sub]);
      }

      /**
       * Hides a single, currently open dropdown pane, if passed a parameter, otherwise, hides everything.
       * @function
       * @param {jQuery} $elem - element with a submenu to hide
       * @param {Number} idx - index of the $tabs collection to hide
       * @private
       */

    }, {
      key: '_hide',
      value: function _hide($elem, idx) {
        var $toClose;
        if ($elem && $elem.length) {
          $toClose = $elem;
        } else if (idx !== undefined) {
          $toClose = this.$tabs.not(function (i, el) {
            return i === idx;
          });
        } else {
          $toClose = this.$element;
        }
        var somethingToClose = $toClose.hasClass('is-active') || $toClose.find('.is-active').length > 0;

        if (somethingToClose) {
          $toClose.find('li.is-active').add($toClose).attr({
            'aria-expanded': false,
            'data-is-click': false
          }).removeClass('is-active');

          $toClose.find('ul.js-dropdown-active').attr({
            'aria-hidden': true
          }).removeClass('js-dropdown-active');

          if (this.changed || $toClose.find('opens-inner').length) {
            var oldClass = this.options.alignment === 'left' ? 'right' : 'left';
            $toClose.find('li.is-dropdown-submenu-parent').add($toClose).removeClass('opens-inner opens-' + this.options.alignment).addClass('opens-' + oldClass);
            this.changed = false;
          }
          /**
           * Fires when the open menus are closed.
           * @event DropdownMenu#hide
           */
          this.$element.trigger('hide.zf.dropdownmenu', [$toClose]);
        }
      }

      /**
       * Destroys the plugin.
       * @function
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        this.$menuItems.off('.zf.dropdownmenu').removeAttr('data-is-click').removeClass('is-right-arrow is-left-arrow is-down-arrow opens-right opens-left opens-inner');
        $(document.body).off('.zf.dropdownmenu');
        Foundation.Nest.Burn(this.$element, 'dropdown');
        Foundation.unregisterPlugin(this);
      }
    }]);

    return DropdownMenu;
  }();

  /**
   * Default settings for plugin
   */


  DropdownMenu.defaults = {
    /**
     * Disallows hover events from opening submenus
     * @option
     * @example false
     */
    disableHover: false,
    /**
     * Allow a submenu to automatically close on a mouseleave event, if not clicked open.
     * @option
     * @example true
     */
    autoclose: true,
    /**
     * Amount of time to delay opening a submenu on hover event.
     * @option
     * @example 50
     */
    hoverDelay: 50,
    /**
     * Allow a submenu to open/remain open on parent click event. Allows cursor to move away from menu.
     * @option
     * @example true
     */
    clickOpen: false,
    /**
     * Amount of time to delay closing a submenu on a mouseleave event.
     * @option
     * @example 500
     */

    closingTime: 500,
    /**
     * Position of the menu relative to what direction the submenus should open. Handled by JS.
     * @option
     * @example 'left'
     */
    alignment: 'left',
    /**
     * Allow clicks on the body to close any open submenus.
     * @option
     * @example true
     */
    closeOnClick: true,
    /**
     * Class applied to vertical oriented menus, Foundation default is `vertical`. Update this if using your own class.
     * @option
     * @example 'vertical'
     */
    verticalClass: 'vertical',
    /**
     * Class applied to right-side oriented menus, Foundation default is `align-right`. Update this if using your own class.
     * @option
     * @example 'align-right'
     */
    rightClass: 'align-right',
    /**
     * Boolean to force overide the clicking of links to perform default action, on second touch event for mobile.
     * @option
     * @example false
     */
    forceFollow: true
  };

  // Window exports
  Foundation.plugin(DropdownMenu, 'DropdownMenu');
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * Equalizer module.
   * @module foundation.equalizer
   */

  var Equalizer = function () {
    /**
     * Creates a new instance of Equalizer.
     * @class
     * @fires Equalizer#init
     * @param {Object} element - jQuery object to add the trigger to.
     * @param {Object} options - Overrides to the default plugin settings.
     */
    function Equalizer(element, options) {
      _classCallCheck(this, Equalizer);

      this.$element = element;
      this.options = $.extend({}, Equalizer.defaults, this.$element.data(), options);

      this._init();

      Foundation.registerPlugin(this, 'Equalizer');
    }

    /**
     * Initializes the Equalizer plugin and calls functions to get equalizer functioning on load.
     * @private
     */


    _createClass(Equalizer, [{
      key: '_init',
      value: function _init() {
        var eqId = this.$element.attr('data-equalizer') || '';
        var $watched = this.$element.find('[data-equalizer-watch="' + eqId + '"]');

        this.$watched = $watched.length ? $watched : this.$element.find('[data-equalizer-watch]');
        this.$element.attr('data-resize', eqId || Foundation.GetYoDigits(6, 'eq'));

        this.hasNested = this.$element.find('[data-equalizer]').length > 0;
        this.isNested = this.$element.parentsUntil(document.body, '[data-equalizer]').length > 0;
        this.isOn = false;
        this._bindHandler = {
          onResizeMeBound: this._onResizeMe.bind(this),
          onPostEqualizedBound: this._onPostEqualized.bind(this)
        };

        var imgs = this.$element.find('img');
        var tooSmall;
        if (this.options.equalizeOn) {
          tooSmall = this._checkMQ();
          $(window).on('changed.zf.mediaquery', this._checkMQ.bind(this));
        } else {
          this._events();
        }
        if (tooSmall !== undefined && tooSmall === false || tooSmall === undefined) {
          if (imgs.length) {
            Foundation.onImagesLoaded(imgs, this._reflow.bind(this));
          } else {
            this._reflow();
          }
        }
      }

      /**
       * Removes event listeners if the breakpoint is too small.
       * @private
       */

    }, {
      key: '_pauseEvents',
      value: function _pauseEvents() {
        this.isOn = false;
        this.$element.off({
          '.zf.equalizer': this._bindHandler.onPostEqualizedBound,
          'resizeme.zf.trigger': this._bindHandler.onResizeMeBound
        });
      }

      /**
       * function to handle $elements resizeme.zf.trigger, with bound this on _bindHandler.onResizeMeBound
       * @private
       */

    }, {
      key: '_onResizeMe',
      value: function _onResizeMe(e) {
        this._reflow();
      }

      /**
       * function to handle $elements postequalized.zf.equalizer, with bound this on _bindHandler.onPostEqualizedBound
       * @private
       */

    }, {
      key: '_onPostEqualized',
      value: function _onPostEqualized(e) {
        if (e.target !== this.$element[0]) {
          this._reflow();
        }
      }

      /**
       * Initializes events for Equalizer.
       * @private
       */

    }, {
      key: '_events',
      value: function _events() {
        var _this = this;
        this._pauseEvents();
        if (this.hasNested) {
          this.$element.on('postequalized.zf.equalizer', this._bindHandler.onPostEqualizedBound);
        } else {
          this.$element.on('resizeme.zf.trigger', this._bindHandler.onResizeMeBound);
        }
        this.isOn = true;
      }

      /**
       * Checks the current breakpoint to the minimum required size.
       * @private
       */

    }, {
      key: '_checkMQ',
      value: function _checkMQ() {
        var tooSmall = !Foundation.MediaQuery.atLeast(this.options.equalizeOn);
        if (tooSmall) {
          if (this.isOn) {
            this._pauseEvents();
            this.$watched.css('height', 'auto');
          }
        } else {
          if (!this.isOn) {
            this._events();
          }
        }
        return tooSmall;
      }

      /**
       * A noop version for the plugin
       * @private
       */

    }, {
      key: '_killswitch',
      value: function _killswitch() {
        return;
      }

      /**
       * Calls necessary functions to update Equalizer upon DOM change
       * @private
       */

    }, {
      key: '_reflow',
      value: function _reflow() {
        if (!this.options.equalizeOnStack) {
          if (this._isStacked()) {
            this.$watched.css('height', 'auto');
            return false;
          }
        }
        if (this.options.equalizeByRow) {
          this.getHeightsByRow(this.applyHeightByRow.bind(this));
        } else {
          this.getHeights(this.applyHeight.bind(this));
        }
      }

      /**
       * Manually determines if the first 2 elements are *NOT* stacked.
       * @private
       */

    }, {
      key: '_isStacked',
      value: function _isStacked() {
        return this.$watched[0].getBoundingClientRect().top !== this.$watched[1].getBoundingClientRect().top;
      }

      /**
       * Finds the outer heights of children contained within an Equalizer parent and returns them in an array
       * @param {Function} cb - A non-optional callback to return the heights array to.
       * @returns {Array} heights - An array of heights of children within Equalizer container
       */

    }, {
      key: 'getHeights',
      value: function getHeights(cb) {
        var heights = [];
        for (var i = 0, len = this.$watched.length; i < len; i++) {
          this.$watched[i].style.height = 'auto';
          heights.push(this.$watched[i].offsetHeight);
        }
        cb(heights);
      }

      /**
       * Finds the outer heights of children contained within an Equalizer parent and returns them in an array
       * @param {Function} cb - A non-optional callback to return the heights array to.
       * @returns {Array} groups - An array of heights of children within Equalizer container grouped by row with element,height and max as last child
       */

    }, {
      key: 'getHeightsByRow',
      value: function getHeightsByRow(cb) {
        var lastElTopOffset = this.$watched.length ? this.$watched.first().offset().top : 0,
            groups = [],
            group = 0;
        //group by Row
        groups[group] = [];
        for (var i = 0, len = this.$watched.length; i < len; i++) {
          this.$watched[i].style.height = 'auto';
          //maybe could use this.$watched[i].offsetTop
          var elOffsetTop = $(this.$watched[i]).offset().top;
          if (elOffsetTop != lastElTopOffset) {
            group++;
            groups[group] = [];
            lastElTopOffset = elOffsetTop;
          }
          groups[group].push([this.$watched[i], this.$watched[i].offsetHeight]);
        }

        for (var j = 0, ln = groups.length; j < ln; j++) {
          var heights = $(groups[j]).map(function () {
            return this[1];
          }).get();
          var max = Math.max.apply(null, heights);
          groups[j].push(max);
        }
        cb(groups);
      }

      /**
       * Changes the CSS height property of each child in an Equalizer parent to match the tallest
       * @param {array} heights - An array of heights of children within Equalizer container
       * @fires Equalizer#preequalized
       * @fires Equalizer#postequalized
       */

    }, {
      key: 'applyHeight',
      value: function applyHeight(heights) {
        var max = Math.max.apply(null, heights);
        /**
         * Fires before the heights are applied
         * @event Equalizer#preequalized
         */
        this.$element.trigger('preequalized.zf.equalizer');

        this.$watched.css('height', max);

        /**
         * Fires when the heights have been applied
         * @event Equalizer#postequalized
         */
        this.$element.trigger('postequalized.zf.equalizer');
      }

      /**
       * Changes the CSS height property of each child in an Equalizer parent to match the tallest by row
       * @param {array} groups - An array of heights of children within Equalizer container grouped by row with element,height and max as last child
       * @fires Equalizer#preequalized
       * @fires Equalizer#preequalizedRow
       * @fires Equalizer#postequalizedRow
       * @fires Equalizer#postequalized
       */

    }, {
      key: 'applyHeightByRow',
      value: function applyHeightByRow(groups) {
        /**
         * Fires before the heights are applied
         */
        this.$element.trigger('preequalized.zf.equalizer');
        for (var i = 0, len = groups.length; i < len; i++) {
          var groupsILength = groups[i].length,
              max = groups[i][groupsILength - 1];
          if (groupsILength <= 2) {
            $(groups[i][0][0]).css({ 'height': 'auto' });
            continue;
          }
          /**
            * Fires before the heights per row are applied
            * @event Equalizer#preequalizedRow
            */
          this.$element.trigger('preequalizedrow.zf.equalizer');
          for (var j = 0, lenJ = groupsILength - 1; j < lenJ; j++) {
            $(groups[i][j][0]).css({ 'height': max });
          }
          /**
            * Fires when the heights per row have been applied
            * @event Equalizer#postequalizedRow
            */
          this.$element.trigger('postequalizedrow.zf.equalizer');
        }
        /**
         * Fires when the heights have been applied
         */
        this.$element.trigger('postequalized.zf.equalizer');
      }

      /**
       * Destroys an instance of Equalizer.
       * @function
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        this._pauseEvents();
        this.$watched.css('height', 'auto');

        Foundation.unregisterPlugin(this);
      }
    }]);

    return Equalizer;
  }();

  /**
   * Default settings for plugin
   */


  Equalizer.defaults = {
    /**
     * Enable height equalization when stacked on smaller screens.
     * @option
     * @example true
     */
    equalizeOnStack: true,
    /**
     * Enable height equalization row by row.
     * @option
     * @example false
     */
    equalizeByRow: false,
    /**
     * String representing the minimum breakpoint size the plugin should equalize heights on.
     * @option
     * @example 'medium'
     */
    equalizeOn: ''
  };

  // Window exports
  Foundation.plugin(Equalizer, 'Equalizer');
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * Interchange module.
   * @module foundation.interchange
   * @requires foundation.util.mediaQuery
   * @requires foundation.util.timerAndImageLoader
   */

  var Interchange = function () {
    /**
     * Creates a new instance of Interchange.
     * @class
     * @fires Interchange#init
     * @param {Object} element - jQuery object to add the trigger to.
     * @param {Object} options - Overrides to the default plugin settings.
     */
    function Interchange(element, options) {
      _classCallCheck(this, Interchange);

      this.$element = element;
      this.options = $.extend({}, Interchange.defaults, options);
      this.rules = [];
      this.currentPath = '';

      this._init();
      this._events();

      Foundation.registerPlugin(this, 'Interchange');
    }

    /**
     * Initializes the Interchange plugin and calls functions to get interchange functioning on load.
     * @function
     * @private
     */


    _createClass(Interchange, [{
      key: '_init',
      value: function _init() {
        this._addBreakpoints();
        this._generateRules();
        this._reflow();
      }

      /**
       * Initializes events for Interchange.
       * @function
       * @private
       */

    }, {
      key: '_events',
      value: function _events() {
        $(window).on('resize.zf.interchange', Foundation.util.throttle(this._reflow.bind(this), 50));
      }

      /**
       * Calls necessary functions to update Interchange upon DOM change
       * @function
       * @private
       */

    }, {
      key: '_reflow',
      value: function _reflow() {
        var match;

        // Iterate through each rule, but only save the last match
        for (var i in this.rules) {
          if (this.rules.hasOwnProperty(i)) {
            var rule = this.rules[i];

            if (window.matchMedia(rule.query).matches) {
              match = rule;
            }
          }
        }

        if (match) {
          this.replace(match.path);
        }
      }

      /**
       * Gets the Foundation breakpoints and adds them to the Interchange.SPECIAL_QUERIES object.
       * @function
       * @private
       */

    }, {
      key: '_addBreakpoints',
      value: function _addBreakpoints() {
        for (var i in Foundation.MediaQuery.queries) {
          if (Foundation.MediaQuery.queries.hasOwnProperty(i)) {
            var query = Foundation.MediaQuery.queries[i];
            Interchange.SPECIAL_QUERIES[query.name] = query.value;
          }
        }
      }

      /**
       * Checks the Interchange element for the provided media query + content pairings
       * @function
       * @private
       * @param {Object} element - jQuery object that is an Interchange instance
       * @returns {Array} scenarios - Array of objects that have 'mq' and 'path' keys with corresponding keys
       */

    }, {
      key: '_generateRules',
      value: function _generateRules(element) {
        var rulesList = [];
        var rules;

        if (this.options.rules) {
          rules = this.options.rules;
        } else {
          rules = this.$element.data('interchange').match(/\[.*?\]/g);
        }

        for (var i in rules) {
          if (rules.hasOwnProperty(i)) {
            var rule = rules[i].slice(1, -1).split(', ');
            var path = rule.slice(0, -1).join('');
            var query = rule[rule.length - 1];

            if (Interchange.SPECIAL_QUERIES[query]) {
              query = Interchange.SPECIAL_QUERIES[query];
            }

            rulesList.push({
              path: path,
              query: query
            });
          }
        }

        this.rules = rulesList;
      }

      /**
       * Update the `src` property of an image, or change the HTML of a container, to the specified path.
       * @function
       * @param {String} path - Path to the image or HTML partial.
       * @fires Interchange#replaced
       */

    }, {
      key: 'replace',
      value: function replace(path) {
        if (this.currentPath === path) return;

        var _this = this,
            trigger = 'replaced.zf.interchange';

        // Replacing images
        if (this.$element[0].nodeName === 'IMG') {
          this.$element.attr('src', path).load(function () {
            _this.currentPath = path;
          }).trigger(trigger);
        }
        // Replacing background images
        else if (path.match(/\.(gif|jpg|jpeg|png|svg|tiff)([?#].*)?/i)) {
            this.$element.css({ 'background-image': 'url(' + path + ')' }).trigger(trigger);
          }
          // Replacing HTML
          else {
              $.get(path, function (response) {
                _this.$element.html(response).trigger(trigger);
                $(response).foundation();
                _this.currentPath = path;
              });
            }

        /**
         * Fires when content in an Interchange element is done being loaded.
         * @event Interchange#replaced
         */
        // this.$element.trigger('replaced.zf.interchange');
      }

      /**
       * Destroys an instance of interchange.
       * @function
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        //TODO this.
      }
    }]);

    return Interchange;
  }();

  /**
   * Default settings for plugin
   */


  Interchange.defaults = {
    /**
     * Rules to be applied to Interchange elements. Set with the `data-interchange` array notation.
     * @option
     */
    rules: null
  };

  Interchange.SPECIAL_QUERIES = {
    'landscape': 'screen and (orientation: landscape)',
    'portrait': 'screen and (orientation: portrait)',
    'retina': 'only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min--moz-device-pixel-ratio: 2), only screen and (-o-min-device-pixel-ratio: 2/1), only screen and (min-device-pixel-ratio: 2), only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx)'
  };

  // Window exports
  Foundation.plugin(Interchange, 'Interchange');
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * Magellan module.
   * @module foundation.magellan
   */

  var Magellan = function () {
    /**
     * Creates a new instance of Magellan.
     * @class
     * @fires Magellan#init
     * @param {Object} element - jQuery object to add the trigger to.
     * @param {Object} options - Overrides to the default plugin settings.
     */
    function Magellan(element, options) {
      _classCallCheck(this, Magellan);

      this.$element = element;
      this.options = $.extend({}, Magellan.defaults, this.$element.data(), options);

      this._init();

      Foundation.registerPlugin(this, 'Magellan');
    }

    /**
     * Initializes the Magellan plugin and calls functions to get equalizer functioning on load.
     * @private
     */


    _createClass(Magellan, [{
      key: '_init',
      value: function _init() {
        var id = this.$element[0].id || Foundation.GetYoDigits(6, 'magellan');
        var _this = this;
        this.$targets = $('[data-magellan-target]');
        this.$links = this.$element.find('a');
        this.$element.attr({
          'data-resize': id,
          'data-scroll': id,
          'id': id
        });
        this.$active = $();
        this.scrollPos = parseInt(window.pageYOffset, 10);

        this._events();
      }

      /**
       * Calculates an array of pixel values that are the demarcation lines between locations on the page.
       * Can be invoked if new elements are added or the size of a location changes.
       * @function
       */

    }, {
      key: 'calcPoints',
      value: function calcPoints() {
        var _this = this,
            body = document.body,
            html = document.documentElement;

        this.points = [];
        this.winHeight = Math.round(Math.max(window.innerHeight, html.clientHeight));
        this.docHeight = Math.round(Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight));

        this.$targets.each(function () {
          var $tar = $(this),
              pt = Math.round($tar.offset().top - _this.options.threshold);
          $tar.targetPoint = pt;
          _this.points.push(pt);
        });
      }

      /**
       * Initializes events for Magellan.
       * @private
       */

    }, {
      key: '_events',
      value: function _events() {
        var _this = this,
            $body = $('html, body'),
            opts = {
          duration: _this.options.animationDuration,
          easing: _this.options.animationEasing
        };
        $(window).one('load', function () {
          if (_this.options.deepLinking) {
            if (location.hash) {
              _this.scrollToLoc(location.hash);
            }
          }
          _this.calcPoints();
          _this._updateActive();
        });

        this.$element.on({
          'resizeme.zf.trigger': this.reflow.bind(this),
          'scrollme.zf.trigger': this._updateActive.bind(this)
        }).on('click.zf.magellan', 'a[href^="#"]', function (e) {
          e.preventDefault();
          var arrival = this.getAttribute('href');
          _this.scrollToLoc(arrival);
        });
      }

      /**
       * Function to scroll to a given location on the page.
       * @param {String} loc - a properly formatted jQuery id selector. Example: '#foo'
       * @function
       */

    }, {
      key: 'scrollToLoc',
      value: function scrollToLoc(loc) {
        var scrollPos = Math.round($(loc).offset().top - this.options.threshold / 2 - this.options.barOffset);

        $('html, body').stop(true).animate({ scrollTop: scrollPos }, this.options.animationDuration, this.options.animationEasing);
      }

      /**
       * Calls necessary functions to update Magellan upon DOM change
       * @function
       */

    }, {
      key: 'reflow',
      value: function reflow() {
        this.calcPoints();
        this._updateActive();
      }

      /**
       * Updates the visibility of an active location link, and updates the url hash for the page, if deepLinking enabled.
       * @private
       * @function
       * @fires Magellan#update
       */

    }, {
      key: '_updateActive',
      value: function _updateActive() /*evt, elem, scrollPos*/{
        var winPos = /*scrollPos ||*/parseInt(window.pageYOffset, 10),
            curIdx;

        if (winPos + this.winHeight === this.docHeight) {
          curIdx = this.points.length - 1;
        } else if (winPos < this.points[0]) {
          curIdx = 0;
        } else {
          var isDown = this.scrollPos < winPos,
              _this = this,
              curVisible = this.points.filter(function (p, i) {
            return isDown ? p - _this.options.barOffset <= winPos : p - _this.options.barOffset - _this.options.threshold <= winPos;
          });
          curIdx = curVisible.length ? curVisible.length - 1 : 0;
        }

        this.$active.removeClass(this.options.activeClass);
        this.$active = this.$links.eq(curIdx).addClass(this.options.activeClass);

        if (this.options.deepLinking) {
          var hash = this.$active[0].getAttribute('href');
          if (window.history.pushState) {
            window.history.pushState(null, null, hash);
          } else {
            window.location.hash = hash;
          }
        }

        this.scrollPos = winPos;
        /**
         * Fires when magellan is finished updating to the new active element.
         * @event Magellan#update
         */
        this.$element.trigger('update.zf.magellan', [this.$active]);
      }

      /**
       * Destroys an instance of Magellan and resets the url of the window.
       * @function
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        this.$element.off('.zf.trigger .zf.magellan').find('.' + this.options.activeClass).removeClass(this.options.activeClass);

        if (this.options.deepLinking) {
          var hash = this.$active[0].getAttribute('href');
          window.location.hash.replace(hash, '');
        }

        Foundation.unregisterPlugin(this);
      }
    }]);

    return Magellan;
  }();

  /**
   * Default settings for plugin
   */


  Magellan.defaults = {
    /**
     * Amount of time, in ms, the animated scrolling should take between locations.
     * @option
     * @example 500
     */
    animationDuration: 500,
    /**
     * Animation style to use when scrolling between locations.
     * @option
     * @example 'ease-in-out'
     */
    animationEasing: 'linear',
    /**
     * Number of pixels to use as a marker for location changes.
     * @option
     * @example 50
     */
    threshold: 50,
    /**
     * Class applied to the active locations link on the magellan container.
     * @option
     * @example 'active'
     */
    activeClass: 'active',
    /**
     * Allows the script to manipulate the url of the current page, and if supported, alter the history.
     * @option
     * @example true
     */
    deepLinking: false,
    /**
     * Number of pixels to offset the scroll of the page on item click if using a sticky nav bar.
     * @option
     * @example 25
     */
    barOffset: 0
  };

  // Window exports
  Foundation.plugin(Magellan, 'Magellan');
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * OffCanvas module.
   * @module foundation.offcanvas
   * @requires foundation.util.mediaQuery
   * @requires foundation.util.triggers
   * @requires foundation.util.motion
   */

  var OffCanvas = function () {
    /**
     * Creates a new instance of an off-canvas wrapper.
     * @class
     * @fires OffCanvas#init
     * @param {Object} element - jQuery object to initialize.
     * @param {Object} options - Overrides to the default plugin settings.
     */
    function OffCanvas(element, options) {
      _classCallCheck(this, OffCanvas);

      this.$element = element;
      this.options = $.extend({}, OffCanvas.defaults, this.$element.data(), options);
      this.$lastTrigger = $();
      this.$triggers = $();

      this._init();
      this._events();

      Foundation.registerPlugin(this, 'OffCanvas');
    }

    /**
     * Initializes the off-canvas wrapper by adding the exit overlay (if needed).
     * @function
     * @private
     */


    _createClass(OffCanvas, [{
      key: '_init',
      value: function _init() {
        var id = this.$element.attr('id');

        this.$element.attr('aria-hidden', 'true');

        // Find triggers that affect this element and add aria-expanded to them
        this.$triggers = $(document).find('[data-open="' + id + '"], [data-close="' + id + '"], [data-toggle="' + id + '"]').attr('aria-expanded', 'false').attr('aria-controls', id);

        // Add a close trigger over the body if necessary
        if (this.options.closeOnClick) {
          if ($('.js-off-canvas-exit').length) {
            this.$exiter = $('.js-off-canvas-exit');
          } else {
            var exiter = document.createElement('div');
            exiter.setAttribute('class', 'js-off-canvas-exit');
            $('[data-off-canvas-content]').append(exiter);

            this.$exiter = $(exiter);
          }
        }

        this.options.isRevealed = this.options.isRevealed || new RegExp(this.options.revealClass, 'g').test(this.$element[0].className);

        if (this.options.isRevealed) {
          this.options.revealOn = this.options.revealOn || this.$element[0].className.match(/(reveal-for-medium|reveal-for-large)/g)[0].split('-')[2];
          this._setMQChecker();
        }
        if (!this.options.transitionTime) {
          this.options.transitionTime = parseFloat(window.getComputedStyle($('[data-off-canvas-wrapper]')[0]).transitionDuration) * 1000;
        }
      }

      /**
       * Adds event handlers to the off-canvas wrapper and the exit overlay.
       * @function
       * @private
       */

    }, {
      key: '_events',
      value: function _events() {
        this.$element.off('.zf.trigger .zf.offcanvas').on({
          'open.zf.trigger': this.open.bind(this),
          'close.zf.trigger': this.close.bind(this),
          'toggle.zf.trigger': this.toggle.bind(this),
          'keydown.zf.offcanvas': this._handleKeyboard.bind(this)
        });

        if (this.options.closeOnClick && this.$exiter.length) {
          this.$exiter.on({ 'click.zf.offcanvas': this.close.bind(this) });
        }
      }

      /**
       * Applies event listener for elements that will reveal at certain breakpoints.
       * @private
       */

    }, {
      key: '_setMQChecker',
      value: function _setMQChecker() {
        var _this = this;

        $(window).on('changed.zf.mediaquery', function () {
          if (Foundation.MediaQuery.atLeast(_this.options.revealOn)) {
            _this.reveal(true);
          } else {
            _this.reveal(false);
          }
        }).one('load.zf.offcanvas', function () {
          if (Foundation.MediaQuery.atLeast(_this.options.revealOn)) {
            _this.reveal(true);
          }
        });
      }

      /**
       * Handles the revealing/hiding the off-canvas at breakpoints, not the same as open.
       * @param {Boolean} isRevealed - true if element should be revealed.
       * @function
       */

    }, {
      key: 'reveal',
      value: function reveal(isRevealed) {
        var $closer = this.$element.find('[data-close]');
        if (isRevealed) {
          this.close();
          this.isRevealed = true;
          // if (!this.options.forceTop) {
          //   var scrollPos = parseInt(window.pageYOffset);
          //   this.$element[0].style.transform = 'translate(0,' + scrollPos + 'px)';
          // }
          // if (this.options.isSticky) { this._stick(); }
          this.$element.off('open.zf.trigger toggle.zf.trigger');
          if ($closer.length) {
            $closer.hide();
          }
        } else {
          this.isRevealed = false;
          // if (this.options.isSticky || !this.options.forceTop) {
          //   this.$element[0].style.transform = '';
          //   $(window).off('scroll.zf.offcanvas');
          // }
          this.$element.on({
            'open.zf.trigger': this.open.bind(this),
            'toggle.zf.trigger': this.toggle.bind(this)
          });
          if ($closer.length) {
            $closer.show();
          }
        }
      }

      /**
       * Opens the off-canvas menu.
       * @function
       * @param {Object} event - Event object passed from listener.
       * @param {jQuery} trigger - element that triggered the off-canvas to open.
       * @fires OffCanvas#opened
       */

    }, {
      key: 'open',
      value: function open(event, trigger) {
        if (this.$element.hasClass('is-open') || this.isRevealed) {
          return;
        }
        var _this = this,
            $body = $(document.body);

        if (this.options.forceTop) {
          $('body').scrollTop(0);
        }
        // window.pageYOffset = 0;

        // if (!this.options.forceTop) {
        //   var scrollPos = parseInt(window.pageYOffset);
        //   this.$element[0].style.transform = 'translate(0,' + scrollPos + 'px)';
        //   if (this.$exiter.length) {
        //     this.$exiter[0].style.transform = 'translate(0,' + scrollPos + 'px)';
        //   }
        // }
        /**
         * Fires when the off-canvas menu opens.
         * @event OffCanvas#opened
         */
        Foundation.Move(this.options.transitionTime, this.$element, function () {
          $('[data-off-canvas-wrapper]').addClass('is-off-canvas-open is-open-' + _this.options.position);

          _this.$element.addClass('is-open');

          // if (_this.options.isSticky) {
          //   _this._stick();
          // }
        });

        this.$triggers.attr('aria-expanded', 'true');
        this.$element.attr('aria-hidden', 'false').trigger('opened.zf.offcanvas');

        if (this.options.closeOnClick) {
          this.$exiter.addClass('is-visible');
        }

        if (trigger) {
          this.$lastTrigger = trigger;
        }

        if (this.options.autoFocus) {
          this.$element.one(Foundation.transitionend(this.$element), function () {
            _this.$element.find('a, button').eq(0).focus();
          });
        }

        if (this.options.trapFocus) {
          $('[data-off-canvas-content]').attr('tabindex', '-1');
          this._trapFocus();
        }
      }

      /**
       * Traps focus within the offcanvas on open.
       * @private
       */

    }, {
      key: '_trapFocus',
      value: function _trapFocus() {
        var focusable = Foundation.Keyboard.findFocusable(this.$element),
            first = focusable.eq(0),
            last = focusable.eq(-1);

        focusable.off('.zf.offcanvas').on('keydown.zf.offcanvas', function (e) {
          if (e.which === 9 || e.keycode === 9) {
            if (e.target === last[0] && !e.shiftKey) {
              e.preventDefault();
              first.focus();
            }
            if (e.target === first[0] && e.shiftKey) {
              e.preventDefault();
              last.focus();
            }
          }
        });
      }

      /**
       * Allows the offcanvas to appear sticky utilizing translate properties.
       * @private
       */
      // OffCanvas.prototype._stick = function() {
      //   var elStyle = this.$element[0].style;
      //
      //   if (this.options.closeOnClick) {
      //     var exitStyle = this.$exiter[0].style;
      //   }
      //
      //   $(window).on('scroll.zf.offcanvas', function(e) {
      //     console.log(e);
      //     var pageY = window.pageYOffset;
      //     elStyle.transform = 'translate(0,' + pageY + 'px)';
      //     if (exitStyle !== undefined) { exitStyle.transform = 'translate(0,' + pageY + 'px)'; }
      //   });
      //   // this.$element.trigger('stuck.zf.offcanvas');
      // };
      /**
       * Closes the off-canvas menu.
       * @function
       * @param {Function} cb - optional cb to fire after closure.
       * @fires OffCanvas#closed
       */

    }, {
      key: 'close',
      value: function close(cb) {
        if (!this.$element.hasClass('is-open') || this.isRevealed) {
          return;
        }

        var _this = this;

        //  Foundation.Move(this.options.transitionTime, this.$element, function() {
        $('[data-off-canvas-wrapper]').removeClass('is-off-canvas-open is-open-' + _this.options.position);
        _this.$element.removeClass('is-open');
        // Foundation._reflow();
        // });
        this.$element.attr('aria-hidden', 'true')
        /**
         * Fires when the off-canvas menu opens.
         * @event OffCanvas#closed
         */
        .trigger('closed.zf.offcanvas');
        // if (_this.options.isSticky || !_this.options.forceTop) {
        //   setTimeout(function() {
        //     _this.$element[0].style.transform = '';
        //     $(window).off('scroll.zf.offcanvas');
        //   }, this.options.transitionTime);
        // }
        if (this.options.closeOnClick) {
          this.$exiter.removeClass('is-visible');
        }

        this.$triggers.attr('aria-expanded', 'false');
        if (this.options.trapFocus) {
          $('[data-off-canvas-content]').removeAttr('tabindex');
        }
      }

      /**
       * Toggles the off-canvas menu open or closed.
       * @function
       * @param {Object} event - Event object passed from listener.
       * @param {jQuery} trigger - element that triggered the off-canvas to open.
       */

    }, {
      key: 'toggle',
      value: function toggle(event, trigger) {
        if (this.$element.hasClass('is-open')) {
          this.close(event, trigger);
        } else {
          this.open(event, trigger);
        }
      }

      /**
       * Handles keyboard input when detected. When the escape key is pressed, the off-canvas menu closes, and focus is restored to the element that opened the menu.
       * @function
       * @private
       */

    }, {
      key: '_handleKeyboard',
      value: function _handleKeyboard(event) {
        if (event.which !== 27) return;

        event.stopPropagation();
        event.preventDefault();
        this.close();
        this.$lastTrigger.focus();
      }

      /**
       * Destroys the offcanvas plugin.
       * @function
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        this.close();
        this.$element.off('.zf.trigger .zf.offcanvas');
        this.$exiter.off('.zf.offcanvas');

        Foundation.unregisterPlugin(this);
      }
    }]);

    return OffCanvas;
  }();

  OffCanvas.defaults = {
    /**
     * Allow the user to click outside of the menu to close it.
     * @option
     * @example true
     */
    closeOnClick: true,

    /**
     * Amount of time in ms the open and close transition requires. If none selected, pulls from body style.
     * @option
     * @example 500
     */
    transitionTime: 0,

    /**
     * Direction the offcanvas opens from. Determines class applied to body.
     * @option
     * @example left
     */
    position: 'left',

    /**
     * Force the page to scroll to top on open.
     * @option
     * @example true
     */
    forceTop: true,

    /**
     * Allow the offcanvas to remain open for certain breakpoints.
     * @option
     * @example false
     */
    isRevealed: false,

    /**
     * Breakpoint at which to reveal. JS will use a RegExp to target standard classes, if changing classnames, pass your class with the `revealClass` option.
     * @option
     * @example reveal-for-large
     */
    revealOn: null,

    /**
     * Force focus to the offcanvas on open. If true, will focus the opening trigger on close.
     * @option
     * @example true
     */
    autoFocus: true,

    /**
     * Class used to force an offcanvas to remain open. Foundation defaults for this are `reveal-for-large` & `reveal-for-medium`.
     * @option
     * TODO improve the regex testing for this.
     * @example reveal-for-large
     */
    revealClass: 'reveal-for-',

    /**
     * Triggers optional focus trapping when opening an offcanvas. Sets tabindex of [data-off-canvas-content] to -1 for accessibility purposes.
     * @option
     * @example true
     */
    trapFocus: false
  };

  // Window exports
  Foundation.plugin(OffCanvas, 'OffCanvas');
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * Orbit module.
   * @module foundation.orbit
   * @requires foundation.util.keyboard
   * @requires foundation.util.motion
   * @requires foundation.util.timerAndImageLoader
   * @requires foundation.util.touch
   */

  var Orbit = function () {
    /**
    * Creates a new instance of an orbit carousel.
    * @class
    * @param {jQuery} element - jQuery object to make into an Orbit Carousel.
    * @param {Object} options - Overrides to the default plugin settings.
    */
    function Orbit(element, options) {
      _classCallCheck(this, Orbit);

      this.$element = element;
      this.options = $.extend({}, Orbit.defaults, this.$element.data(), options);

      this._init();

      Foundation.registerPlugin(this, 'Orbit');
      Foundation.Keyboard.register('Orbit', {
        'ltr': {
          'ARROW_RIGHT': 'next',
          'ARROW_LEFT': 'previous'
        },
        'rtl': {
          'ARROW_LEFT': 'next',
          'ARROW_RIGHT': 'previous'
        }
      });
    }

    /**
    * Initializes the plugin by creating jQuery collections, setting attributes, and starting the animation.
    * @function
    * @private
    */


    _createClass(Orbit, [{
      key: '_init',
      value: function _init() {
        this.$wrapper = this.$element.find('.' + this.options.containerClass);
        this.$slides = this.$element.find('.' + this.options.slideClass);
        var $images = this.$element.find('img'),
            initActive = this.$slides.filter('.is-active');

        if (!initActive.length) {
          this.$slides.eq(0).addClass('is-active');
        }

        if (!this.options.useMUI) {
          this.$slides.addClass('no-motionui');
        }

        if ($images.length) {
          Foundation.onImagesLoaded($images, this._prepareForOrbit.bind(this));
        } else {
          this._prepareForOrbit(); //hehe
        }

        if (this.options.bullets) {
          this._loadBullets();
        }

        this._events();

        if (this.options.autoPlay && this.$slides.length > 1) {
          this.geoSync();
        }

        if (this.options.accessible) {
          // allow wrapper to be focusable to enable arrow navigation
          this.$wrapper.attr('tabindex', 0);
        }
      }

      /**
      * Creates a jQuery collection of bullets, if they are being used.
      * @function
      * @private
      */

    }, {
      key: '_loadBullets',
      value: function _loadBullets() {
        this.$bullets = this.$element.find('.' + this.options.boxOfBullets).find('button');
      }

      /**
      * Sets a `timer` object on the orbit, and starts the counter for the next slide.
      * @function
      */

    }, {
      key: 'geoSync',
      value: function geoSync() {
        var _this = this;
        this.timer = new Foundation.Timer(this.$element, {
          duration: this.options.timerDelay,
          infinite: false
        }, function () {
          _this.changeSlide(true);
        });
        this.timer.start();
      }

      /**
      * Sets wrapper and slide heights for the orbit.
      * @function
      * @private
      */

    }, {
      key: '_prepareForOrbit',
      value: function _prepareForOrbit() {
        var _this = this;
        this._setWrapperHeight(function (max) {
          _this._setSlideHeight(max);
        });
      }

      /**
      * Calulates the height of each slide in the collection, and uses the tallest one for the wrapper height.
      * @function
      * @private
      * @param {Function} cb - a callback function to fire when complete.
      */

    }, {
      key: '_setWrapperHeight',
      value: function _setWrapperHeight(cb) {
        //rewrite this to `for` loop
        var max = 0,
            temp,
            counter = 0;

        this.$slides.each(function () {
          temp = this.getBoundingClientRect().height;
          $(this).attr('data-slide', counter);

          if (counter) {
            //if not the first slide, set css position and display property
            $(this).css({ 'position': 'relative', 'display': 'none' });
          }
          max = temp > max ? temp : max;
          counter++;
        });

        if (counter === this.$slides.length) {
          this.$wrapper.css({ 'height': max }); //only change the wrapper height property once.
          cb(max); //fire callback with max height dimension.
        }
      }

      /**
      * Sets the max-height of each slide.
      * @function
      * @private
      */

    }, {
      key: '_setSlideHeight',
      value: function _setSlideHeight(height) {
        this.$slides.each(function () {
          $(this).css('max-height', height);
        });
      }

      /**
      * Adds event listeners to basically everything within the element.
      * @function
      * @private
      */

    }, {
      key: '_events',
      value: function _events() {
        var _this = this;

        //***************************************
        //**Now using custom event - thanks to:**
        //**      Yohai Ararat of Toronto      **
        //***************************************
        if (this.$slides.length > 1) {

          if (this.options.swipe) {
            this.$slides.off('swipeleft.zf.orbit swiperight.zf.orbit').on('swipeleft.zf.orbit', function (e) {
              e.preventDefault();
              _this.changeSlide(true);
            }).on('swiperight.zf.orbit', function (e) {
              e.preventDefault();
              _this.changeSlide(false);
            });
          }
          //***************************************

          if (this.options.autoPlay) {
            this.$slides.on('click.zf.orbit', function () {
              _this.$element.data('clickedOn', _this.$element.data('clickedOn') ? false : true);
              _this.timer[_this.$element.data('clickedOn') ? 'pause' : 'start']();
            });

            if (this.options.pauseOnHover) {
              this.$element.on('mouseenter.zf.orbit', function () {
                _this.timer.pause();
              }).on('mouseleave.zf.orbit', function () {
                if (!_this.$element.data('clickedOn')) {
                  _this.timer.start();
                }
              });
            }
          }

          if (this.options.navButtons) {
            var $controls = this.$element.find('.' + this.options.nextClass + ', .' + this.options.prevClass);
            $controls.attr('tabindex', 0)
            //also need to handle enter/return and spacebar key presses
            .on('click.zf.orbit touchend.zf.orbit', function (e) {
              e.preventDefault();
              _this.changeSlide($(this).hasClass(_this.options.nextClass));
            });
          }

          if (this.options.bullets) {
            this.$bullets.on('click.zf.orbit touchend.zf.orbit', function () {
              if (/is-active/g.test(this.className)) {
                return false;
              } //if this is active, kick out of function.
              var idx = $(this).data('slide'),
                  ltr = idx > _this.$slides.filter('.is-active').data('slide'),
                  $slide = _this.$slides.eq(idx);

              _this.changeSlide(ltr, $slide, idx);
            });
          }

          this.$wrapper.add(this.$bullets).on('keydown.zf.orbit', function (e) {
            // handle keyboard event with keyboard util
            Foundation.Keyboard.handleKey(e, 'Orbit', {
              next: function next() {
                _this.changeSlide(true);
              },
              previous: function previous() {
                _this.changeSlide(false);
              },
              handled: function handled() {
                // if bullet is focused, make sure focus moves
                if ($(e.target).is(_this.$bullets)) {
                  _this.$bullets.filter('.is-active').focus();
                }
              }
            });
          });
        }
      }

      /**
      * Changes the current slide to a new one.
      * @function
      * @param {Boolean} isLTR - flag if the slide should move left to right.
      * @param {jQuery} chosenSlide - the jQuery element of the slide to show next, if one is selected.
      * @param {Number} idx - the index of the new slide in its collection, if one chosen.
      * @fires Orbit#slidechange
      */

    }, {
      key: 'changeSlide',
      value: function changeSlide(isLTR, chosenSlide, idx) {
        var $curSlide = this.$slides.filter('.is-active').eq(0);

        if (/mui/g.test($curSlide[0].className)) {
          return false;
        } //if the slide is currently animating, kick out of the function

        var $firstSlide = this.$slides.first(),
            $lastSlide = this.$slides.last(),
            dirIn = isLTR ? 'Right' : 'Left',
            dirOut = isLTR ? 'Left' : 'Right',
            _this = this,
            $newSlide;

        if (!chosenSlide) {
          //most of the time, this will be auto played or clicked from the navButtons.
          $newSlide = isLTR ? //if wrapping enabled, check to see if there is a `next` or `prev` sibling, if not, select the first or last slide to fill in. if wrapping not enabled, attempt to select `next` or `prev`, if there's nothing there, the function will kick out on next step. CRAZY NESTED TERNARIES!!!!!
          this.options.infiniteWrap ? $curSlide.next('.' + this.options.slideClass).length ? $curSlide.next('.' + this.options.slideClass) : $firstSlide : $curSlide.next('.' + this.options.slideClass) : //pick next slide if moving left to right
          this.options.infiniteWrap ? $curSlide.prev('.' + this.options.slideClass).length ? $curSlide.prev('.' + this.options.slideClass) : $lastSlide : $curSlide.prev('.' + this.options.slideClass); //pick prev slide if moving right to left
        } else {
          $newSlide = chosenSlide;
        }

        if ($newSlide.length) {
          if (this.options.bullets) {
            idx = idx || this.$slides.index($newSlide); //grab index to update bullets
            this._updateBullets(idx);
          }

          if (this.options.useMUI) {
            Foundation.Motion.animateIn($newSlide.addClass('is-active').css({ 'position': 'absolute', 'top': 0 }), this.options['animInFrom' + dirIn], function () {
              $newSlide.css({ 'position': 'relative', 'display': 'block' }).attr('aria-live', 'polite');
            });

            Foundation.Motion.animateOut($curSlide.removeClass('is-active'), this.options['animOutTo' + dirOut], function () {
              $curSlide.removeAttr('aria-live');
              if (_this.options.autoPlay && !_this.timer.isPaused) {
                _this.timer.restart();
              }
              //do stuff?
            });
          } else {
            $curSlide.removeClass('is-active is-in').removeAttr('aria-live').hide();
            $newSlide.addClass('is-active is-in').attr('aria-live', 'polite').show();
            if (this.options.autoPlay && !this.timer.isPaused) {
              this.timer.restart();
            }
          }
          /**
          * Triggers when the slide has finished animating in.
          * @event Orbit#slidechange
          */
          this.$element.trigger('slidechange.zf.orbit', [$newSlide]);
        }
      }

      /**
      * Updates the active state of the bullets, if displayed.
      * @function
      * @private
      * @param {Number} idx - the index of the current slide.
      */

    }, {
      key: '_updateBullets',
      value: function _updateBullets(idx) {
        var $oldBullet = this.$element.find('.' + this.options.boxOfBullets).find('.is-active').removeClass('is-active').blur(),
            span = $oldBullet.find('span:last').detach(),
            $newBullet = this.$bullets.eq(idx).addClass('is-active').append(span);
      }

      /**
      * Destroys the carousel and hides the element.
      * @function
      */

    }, {
      key: 'destroy',
      value: function destroy() {
        this.$element.off('.zf.orbit').find('*').off('.zf.orbit').end().hide();
        Foundation.unregisterPlugin(this);
      }
    }]);

    return Orbit;
  }();

  Orbit.defaults = {
    /**
    * Tells the JS to look for and loadBullets.
    * @option
    * @example true
    */
    bullets: true,
    /**
    * Tells the JS to apply event listeners to nav buttons
    * @option
    * @example true
    */
    navButtons: true,
    /**
    * motion-ui animation class to apply
    * @option
    * @example 'slide-in-right'
    */
    animInFromRight: 'slide-in-right',
    /**
    * motion-ui animation class to apply
    * @option
    * @example 'slide-out-right'
    */
    animOutToRight: 'slide-out-right',
    /**
    * motion-ui animation class to apply
    * @option
    * @example 'slide-in-left'
    *
    */
    animInFromLeft: 'slide-in-left',
    /**
    * motion-ui animation class to apply
    * @option
    * @example 'slide-out-left'
    */
    animOutToLeft: 'slide-out-left',
    /**
    * Allows Orbit to automatically animate on page load.
    * @option
    * @example true
    */
    autoPlay: true,
    /**
    * Amount of time, in ms, between slide transitions
    * @option
    * @example 5000
    */
    timerDelay: 5000,
    /**
    * Allows Orbit to infinitely loop through the slides
    * @option
    * @example true
    */
    infiniteWrap: true,
    /**
    * Allows the Orbit slides to bind to swipe events for mobile, requires an additional util library
    * @option
    * @example true
    */
    swipe: true,
    /**
    * Allows the timing function to pause animation on hover.
    * @option
    * @example true
    */
    pauseOnHover: true,
    /**
    * Allows Orbit to bind keyboard events to the slider, to animate frames with arrow keys
    * @option
    * @example true
    */
    accessible: true,
    /**
    * Class applied to the container of Orbit
    * @option
    * @example 'orbit-container'
    */
    containerClass: 'orbit-container',
    /**
    * Class applied to individual slides.
    * @option
    * @example 'orbit-slide'
    */
    slideClass: 'orbit-slide',
    /**
    * Class applied to the bullet container. You're welcome.
    * @option
    * @example 'orbit-bullets'
    */
    boxOfBullets: 'orbit-bullets',
    /**
    * Class applied to the `next` navigation button.
    * @option
    * @example 'orbit-next'
    */
    nextClass: 'orbit-next',
    /**
    * Class applied to the `previous` navigation button.
    * @option
    * @example 'orbit-previous'
    */
    prevClass: 'orbit-previous',
    /**
    * Boolean to flag the js to use motion ui classes or not. Default to true for backwards compatability.
    * @option
    * @example true
    */
    useMUI: true
  };

  // Window exports
  Foundation.plugin(Orbit, 'Orbit');
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * ResponsiveMenu module.
   * @module foundation.responsiveMenu
   * @requires foundation.util.triggers
   * @requires foundation.util.mediaQuery
   * @requires foundation.util.accordionMenu
   * @requires foundation.util.drilldown
   * @requires foundation.util.dropdown-menu
   */

  var ResponsiveMenu = function () {
    /**
     * Creates a new instance of a responsive menu.
     * @class
     * @fires ResponsiveMenu#init
     * @param {jQuery} element - jQuery object to make into a dropdown menu.
     * @param {Object} options - Overrides to the default plugin settings.
     */
    function ResponsiveMenu(element, options) {
      _classCallCheck(this, ResponsiveMenu);

      this.$element = $(element);
      this.rules = this.$element.data('responsive-menu');
      this.currentMq = null;
      this.currentPlugin = null;

      this._init();
      this._events();

      Foundation.registerPlugin(this, 'ResponsiveMenu');
    }

    /**
     * Initializes the Menu by parsing the classes from the 'data-ResponsiveMenu' attribute on the element.
     * @function
     * @private
     */


    _createClass(ResponsiveMenu, [{
      key: '_init',
      value: function _init() {
        // The first time an Interchange plugin is initialized, this.rules is converted from a string of "classes" to an object of rules
        if (typeof this.rules === 'string') {
          var rulesTree = {};

          // Parse rules from "classes" pulled from data attribute
          var rules = this.rules.split(' ');

          // Iterate through every rule found
          for (var i = 0; i < rules.length; i++) {
            var rule = rules[i].split('-');
            var ruleSize = rule.length > 1 ? rule[0] : 'small';
            var rulePlugin = rule.length > 1 ? rule[1] : rule[0];

            if (MenuPlugins[rulePlugin] !== null) {
              rulesTree[ruleSize] = MenuPlugins[rulePlugin];
            }
          }

          this.rules = rulesTree;
        }

        if (!$.isEmptyObject(this.rules)) {
          this._checkMediaQueries();
        }
      }

      /**
       * Initializes events for the Menu.
       * @function
       * @private
       */

    }, {
      key: '_events',
      value: function _events() {
        var _this = this;

        $(window).on('changed.zf.mediaquery', function () {
          _this._checkMediaQueries();
        });
        // $(window).on('resize.zf.ResponsiveMenu', function() {
        //   _this._checkMediaQueries();
        // });
      }

      /**
       * Checks the current screen width against available media queries. If the media query has changed, and the plugin needed has changed, the plugins will swap out.
       * @function
       * @private
       */

    }, {
      key: '_checkMediaQueries',
      value: function _checkMediaQueries() {
        var matchedMq,
            _this = this;
        // Iterate through each rule and find the last matching rule
        $.each(this.rules, function (key) {
          if (Foundation.MediaQuery.atLeast(key)) {
            matchedMq = key;
          }
        });

        // No match? No dice
        if (!matchedMq) return;

        // Plugin already initialized? We good
        if (this.currentPlugin instanceof this.rules[matchedMq].plugin) return;

        // Remove existing plugin-specific CSS classes
        $.each(MenuPlugins, function (key, value) {
          _this.$element.removeClass(value.cssClass);
        });

        // Add the CSS class for the new plugin
        this.$element.addClass(this.rules[matchedMq].cssClass);

        // Create an instance of the new plugin
        if (this.currentPlugin) this.currentPlugin.destroy();
        this.currentPlugin = new this.rules[matchedMq].plugin(this.$element, {});
      }

      /**
       * Destroys the instance of the current plugin on this element, as well as the window resize handler that switches the plugins out.
       * @function
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        this.currentPlugin.destroy();
        $(window).off('.zf.ResponsiveMenu');
        Foundation.unregisterPlugin(this);
      }
    }]);

    return ResponsiveMenu;
  }();

  ResponsiveMenu.defaults = {};

  // The plugin matches the plugin classes with these plugin instances.
  var MenuPlugins = {
    dropdown: {
      cssClass: 'dropdown',
      plugin: Foundation._plugins['dropdown-menu'] || null
    },
    drilldown: {
      cssClass: 'drilldown',
      plugin: Foundation._plugins['drilldown'] || null
    },
    accordion: {
      cssClass: 'accordion-menu',
      plugin: Foundation._plugins['accordion-menu'] || null
    }
  };

  // Window exports
  Foundation.plugin(ResponsiveMenu, 'ResponsiveMenu');
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * ResponsiveToggle module.
   * @module foundation.responsiveToggle
   * @requires foundation.util.mediaQuery
   */

  var ResponsiveToggle = function () {
    /**
     * Creates a new instance of Tab Bar.
     * @class
     * @fires ResponsiveToggle#init
     * @param {jQuery} element - jQuery object to attach tab bar functionality to.
     * @param {Object} options - Overrides to the default plugin settings.
     */
    function ResponsiveToggle(element, options) {
      _classCallCheck(this, ResponsiveToggle);

      this.$element = $(element);
      this.options = $.extend({}, ResponsiveToggle.defaults, this.$element.data(), options);

      this._init();
      this._events();

      Foundation.registerPlugin(this, 'ResponsiveToggle');
    }

    /**
     * Initializes the tab bar by finding the target element, toggling element, and running update().
     * @function
     * @private
     */


    _createClass(ResponsiveToggle, [{
      key: '_init',
      value: function _init() {
        var targetID = this.$element.data('responsive-toggle');
        if (!targetID) {
          console.error('Your tab bar needs an ID of a Menu as the value of data-tab-bar.');
        }

        this.$targetMenu = $('#' + targetID);
        this.$toggler = this.$element.find('[data-toggle]');

        this._update();
      }

      /**
       * Adds necessary event handlers for the tab bar to work.
       * @function
       * @private
       */

    }, {
      key: '_events',
      value: function _events() {
        var _this = this;

        this._updateMqHandler = this._update.bind(this);

        $(window).on('changed.zf.mediaquery', this._updateMqHandler);

        this.$toggler.on('click.zf.responsiveToggle', this.toggleMenu.bind(this));
      }

      /**
       * Checks the current media query to determine if the tab bar should be visible or hidden.
       * @function
       * @private
       */

    }, {
      key: '_update',
      value: function _update() {
        // Mobile
        if (!Foundation.MediaQuery.atLeast(this.options.hideFor)) {
          this.$element.show();
          this.$targetMenu.hide();
        }

        // Desktop
        else {
            this.$element.hide();
            this.$targetMenu.show();
          }
      }

      /**
       * Toggles the element attached to the tab bar. The toggle only happens if the screen is small enough to allow it.
       * @function
       * @fires ResponsiveToggle#toggled
       */

    }, {
      key: 'toggleMenu',
      value: function toggleMenu() {
        if (!Foundation.MediaQuery.atLeast(this.options.hideFor)) {
          this.$targetMenu.toggle(0);

          /**
           * Fires when the element attached to the tab bar toggles.
           * @event ResponsiveToggle#toggled
           */
          this.$element.trigger('toggled.zf.responsiveToggle');
        }
      }
    }, {
      key: 'destroy',
      value: function destroy() {
        this.$element.off('.zf.responsiveToggle');
        this.$toggler.off('.zf.responsiveToggle');

        $(window).off('changed.zf.mediaquery', this._updateMqHandler);

        Foundation.unregisterPlugin(this);
      }
    }]);

    return ResponsiveToggle;
  }();

  ResponsiveToggle.defaults = {
    /**
     * The breakpoint after which the menu is always shown, and the tab bar is hidden.
     * @option
     * @example 'medium'
     */
    hideFor: 'medium'
  };

  // Window exports
  Foundation.plugin(ResponsiveToggle, 'ResponsiveToggle');
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * Reveal module.
   * @module foundation.reveal
   * @requires foundation.util.keyboard
   * @requires foundation.util.box
   * @requires foundation.util.triggers
   * @requires foundation.util.mediaQuery
   * @requires foundation.util.motion if using animations
   */

  var Reveal = function () {
    /**
     * Creates a new instance of Reveal.
     * @class
     * @param {jQuery} element - jQuery object to use for the modal.
     * @param {Object} options - optional parameters.
     */
    function Reveal(element, options) {
      _classCallCheck(this, Reveal);

      this.$element = element;
      this.options = $.extend({}, Reveal.defaults, this.$element.data(), options);
      this._init();

      Foundation.registerPlugin(this, 'Reveal');
      Foundation.Keyboard.register('Reveal', {
        'ENTER': 'open',
        'SPACE': 'open',
        'ESCAPE': 'close',
        'TAB': 'tab_forward',
        'SHIFT_TAB': 'tab_backward'
      });
    }

    /**
     * Initializes the modal by adding the overlay and close buttons, (if selected).
     * @private
     */


    _createClass(Reveal, [{
      key: '_init',
      value: function _init() {
        this.id = this.$element.attr('id');
        this.isActive = false;
        this.cached = { mq: Foundation.MediaQuery.current };
        this.isMobile = mobileSniff();

        this.$anchor = $('[data-open="' + this.id + '"]').length ? $('[data-open="' + this.id + '"]') : $('[data-toggle="' + this.id + '"]');
        this.$anchor.attr({
          'aria-controls': this.id,
          'aria-haspopup': true,
          'tabindex': 0
        });

        if (this.options.fullScreen || this.$element.hasClass('full')) {
          this.options.fullScreen = true;
          this.options.overlay = false;
        }
        if (this.options.overlay && !this.$overlay) {
          this.$overlay = this._makeOverlay(this.id);
        }

        this.$element.attr({
          'role': 'dialog',
          'aria-hidden': true,
          'data-yeti-box': this.id,
          'data-resize': this.id
        });

        if (this.$overlay) {
          this.$element.detach().appendTo(this.$overlay);
        } else {
          this.$element.detach().appendTo($('body'));
          this.$element.addClass('without-overlay');
        }
        this._events();
        if (this.options.deepLink && window.location.hash === '#' + this.id) {
          $(window).one('load.zf.reveal', this.open.bind(this));
        }
      }

      /**
       * Creates an overlay div to display behind the modal.
       * @private
       */

    }, {
      key: '_makeOverlay',
      value: function _makeOverlay(id) {
        var $overlay = $('<div></div>').addClass('reveal-overlay').appendTo('body');
        return $overlay;
      }

      /**
       * Updates position of modal
       * TODO:  Figure out if we actually need to cache these values or if it doesn't matter
       * @private
       */

    }, {
      key: '_updatePosition',
      value: function _updatePosition() {
        var width = this.$element.outerWidth();
        var outerWidth = $(window).width();
        var height = this.$element.outerHeight();
        var outerHeight = $(window).height();
        var left, top;
        if (this.options.hOffset === 'auto') {
          left = parseInt((outerWidth - width) / 2, 10);
        } else {
          left = parseInt(this.options.hOffset, 10);
        }
        if (this.options.vOffset === 'auto') {
          if (height > outerHeight) {
            top = parseInt(Math.min(100, outerHeight / 10), 10);
          } else {
            top = parseInt((outerHeight - height) / 4, 10);
          }
        } else {
          top = parseInt(this.options.vOffset, 10);
        }
        this.$element.css({ top: top + 'px' });
        // only worry about left if we don't have an overlay or we havea  horizontal offset,
        // otherwise we're perfectly in the middle
        if (!this.$overlay || this.options.hOffset !== 'auto') {
          this.$element.css({ left: left + 'px' });
          this.$element.css({ margin: '0px' });
        }
      }

      /**
       * Adds event handlers for the modal.
       * @private
       */

    }, {
      key: '_events',
      value: function _events() {
        var _this2 = this;

        var _this = this;

        this.$element.on({
          'open.zf.trigger': this.open.bind(this),
          'close.zf.trigger': function closeZfTrigger(event, $element) {
            if (event.target === _this.$element[0] || $(event.target).parents('[data-closable]')[0] === $element) {
              // only close reveal when it's explicitly called
              return _this2.close.apply(_this2);
            }
          },
          'toggle.zf.trigger': this.toggle.bind(this),
          'resizeme.zf.trigger': function resizemeZfTrigger() {
            _this._updatePosition();
          }
        });

        if (this.$anchor.length) {
          this.$anchor.on('keydown.zf.reveal', function (e) {
            if (e.which === 13 || e.which === 32) {
              e.stopPropagation();
              e.preventDefault();
              _this.open();
            }
          });
        }

        if (this.options.closeOnClick && this.options.overlay) {
          this.$overlay.off('.zf.reveal').on('click.zf.reveal', function (e) {
            if (e.target === _this.$element[0] || $.contains(_this.$element[0], e.target)) {
              return;
            }
            _this.close();
          });
        }
        if (this.options.deepLink) {
          $(window).on('popstate.zf.reveal:' + this.id, this._handleState.bind(this));
        }
      }

      /**
       * Handles modal methods on back/forward button clicks or any other event that triggers popstate.
       * @private
       */

    }, {
      key: '_handleState',
      value: function _handleState(e) {
        if (window.location.hash === '#' + this.id && !this.isActive) {
          this.open();
        } else {
          this.close();
        }
      }

      /**
       * Opens the modal controlled by `this.$anchor`, and closes all others by default.
       * @function
       * @fires Reveal#closeme
       * @fires Reveal#open
       */

    }, {
      key: 'open',
      value: function open() {
        var _this3 = this;

        if (this.options.deepLink) {
          var hash = '#' + this.id;

          if (window.history.pushState) {
            window.history.pushState(null, null, hash);
          } else {
            window.location.hash = hash;
          }
        }

        this.isActive = true;

        // Make elements invisible, but remove display: none so we can get size and positioning
        this.$element.css({ 'visibility': 'hidden' }).show().scrollTop(0);
        if (this.options.overlay) {
          this.$overlay.css({ 'visibility': 'hidden' }).show();
        }

        this._updatePosition();

        this.$element.hide().css({ 'visibility': '' });

        if (this.$overlay) {
          this.$overlay.css({ 'visibility': '' }).hide();
          if (this.$element.hasClass('fast')) {
            this.$overlay.addClass('fast');
          } else if (this.$element.hasClass('slow')) {
            this.$overlay.addClass('slow');
          }
        }

        if (!this.options.multipleOpened) {
          /**
           * Fires immediately before the modal opens.
           * Closes any other modals that are currently open
           * @event Reveal#closeme
           */
          this.$element.trigger('closeme.zf.reveal', this.id);
        }
        // Motion UI method of reveal
        if (this.options.animationIn) {
          var _this;

          (function () {
            var afterAnimationFocus = function afterAnimationFocus() {
              _this.$element.attr({
                'aria-hidden': false,
                'tabindex': -1
              }).focus();
              console.log('focus');
            };

            _this = _this3;

            if (_this3.options.overlay) {
              Foundation.Motion.animateIn(_this3.$overlay, 'fade-in');
            }
            Foundation.Motion.animateIn(_this3.$element, _this3.options.animationIn, function () {
              _this3.focusableElements = Foundation.Keyboard.findFocusable(_this3.$element);
              afterAnimationFocus();
            });
          })();
        }
        // jQuery method of reveal
        else {
            if (this.options.overlay) {
              this.$overlay.show(0);
            }
            this.$element.show(this.options.showDelay);
          }

        // handle accessibility
        this.$element.attr({
          'aria-hidden': false,
          'tabindex': -1
        }).focus();

        /**
         * Fires when the modal has successfully opened.
         * @event Reveal#open
         */
        this.$element.trigger('open.zf.reveal');

        if (this.isMobile) {
          this.originalScrollPos = window.pageYOffset;
          $('html, body').addClass('is-reveal-open');
        } else {
          $('body').addClass('is-reveal-open');
        }

        setTimeout(function () {
          _this3._extraHandlers();
        }, 0);
      }

      /**
       * Adds extra event handlers for the body and window if necessary.
       * @private
       */

    }, {
      key: '_extraHandlers',
      value: function _extraHandlers() {
        var _this = this;
        this.focusableElements = Foundation.Keyboard.findFocusable(this.$element);

        if (!this.options.overlay && this.options.closeOnClick && !this.options.fullScreen) {
          $('body').on('click.zf.reveal', function (e) {
            if (e.target === _this.$element[0] || $.contains(_this.$element[0], e.target)) {
              return;
            }
            _this.close();
          });
        }

        if (this.options.closeOnEsc) {
          $(window).on('keydown.zf.reveal', function (e) {
            Foundation.Keyboard.handleKey(e, 'Reveal', {
              close: function close() {
                if (_this.options.closeOnEsc) {
                  _this.close();
                  _this.$anchor.focus();
                }
              }
            });
          });
        }

        // lock focus within modal while tabbing
        this.$element.on('keydown.zf.reveal', function (e) {
          var $target = $(this);
          // handle keyboard event with keyboard util
          Foundation.Keyboard.handleKey(e, 'Reveal', {
            tab_forward: function tab_forward() {
              if (_this.$element.find(':focus').is(_this.focusableElements.eq(-1))) {
                // left modal downwards, setting focus to first element
                _this.focusableElements.eq(0).focus();
                return true;
              }
              if (_this.focusableElements.length === 0) {
                // no focusable elements inside the modal at all, prevent tabbing in general
                return true;
              }
            },
            tab_backward: function tab_backward() {
              if (_this.$element.find(':focus').is(_this.focusableElements.eq(0)) || _this.$element.is(':focus')) {
                // left modal upwards, setting focus to last element
                _this.focusableElements.eq(-1).focus();
                return true;
              }
              if (_this.focusableElements.length === 0) {
                // no focusable elements inside the modal at all, prevent tabbing in general
                return true;
              }
            },
            open: function open() {
              if (_this.$element.find(':focus').is(_this.$element.find('[data-close]'))) {
                setTimeout(function () {
                  // set focus back to anchor if close button has been activated
                  _this.$anchor.focus();
                }, 1);
              } else if ($target.is(_this.focusableElements)) {
                // dont't trigger if acual element has focus (i.e. inputs, links, ...)
                _this.open();
              }
            },
            close: function close() {
              if (_this.options.closeOnEsc) {
                _this.close();
                _this.$anchor.focus();
              }
            },
            handled: function handled(preventDefault) {
              if (preventDefault) {
                e.preventDefault();
              }
            }
          });
        });
      }

      /**
       * Closes the modal.
       * @function
       * @fires Reveal#closed
       */

    }, {
      key: 'close',
      value: function close() {
        if (!this.isActive || !this.$element.is(':visible')) {
          return false;
        }
        var _this = this;

        // Motion UI method of hiding
        if (this.options.animationOut) {
          if (this.options.overlay) {
            Foundation.Motion.animateOut(this.$overlay, 'fade-out', finishUp);
          } else {
            finishUp();
          }

          Foundation.Motion.animateOut(this.$element, this.options.animationOut);
        }
        // jQuery method of hiding
        else {
            if (this.options.overlay) {
              this.$overlay.hide(0, finishUp);
            } else {
              finishUp();
            }

            this.$element.hide(this.options.hideDelay);
          }

        // Conditionals to remove extra event listeners added on open
        if (this.options.closeOnEsc) {
          $(window).off('keydown.zf.reveal');
        }

        if (!this.options.overlay && this.options.closeOnClick) {
          $('body').off('click.zf.reveal');
        }

        this.$element.off('keydown.zf.reveal');

        function finishUp() {
          if (_this.isMobile) {
            $('html, body').removeClass('is-reveal-open');
            if (_this.originalScrollPos) {
              $('body').scrollTop(_this.originalScrollPos);
              _this.originalScrollPos = null;
            }
          } else {
            $('body').removeClass('is-reveal-open');
          }

          _this.$element.attr('aria-hidden', true);

          /**
          * Fires when the modal is done closing.
          * @event Reveal#closed
          */
          _this.$element.trigger('closed.zf.reveal');
        }

        /**
        * Resets the modal content
        * This prevents a running video to keep going in the background
        */
        if (this.options.resetOnClose) {
          this.$element.html(this.$element.html());
        }

        this.isActive = false;
        if (_this.options.deepLink) {
          if (window.history.replaceState) {
            window.history.replaceState("", document.title, window.location.pathname);
          } else {
            window.location.hash = '';
          }
        }
      }

      /**
       * Toggles the open/closed state of a modal.
       * @function
       */

    }, {
      key: 'toggle',
      value: function toggle() {
        if (this.isActive) {
          this.close();
        } else {
          this.open();
        }
      }
    }, {
      key: 'destroy',


      /**
       * Destroys an instance of a modal.
       * @function
       */
      value: function destroy() {
        if (this.options.overlay) {
          this.$element.appendTo($('body')); // move $element outside of $overlay to prevent error unregisterPlugin()
          this.$overlay.hide().off().remove();
        }
        this.$element.hide().off();
        this.$anchor.off('.zf');
        $(window).off('.zf.reveal:' + this.id);

        Foundation.unregisterPlugin(this);
      }
    }]);

    return Reveal;
  }();

  Reveal.defaults = {
    /**
     * Motion-UI class to use for animated elements. If none used, defaults to simple show/hide.
     * @option
     * @example 'slide-in-left'
     */
    animationIn: '',
    /**
     * Motion-UI class to use for animated elements. If none used, defaults to simple show/hide.
     * @option
     * @example 'slide-out-right'
     */
    animationOut: '',
    /**
     * Time, in ms, to delay the opening of a modal after a click if no animation used.
     * @option
     * @example 10
     */
    showDelay: 0,
    /**
     * Time, in ms, to delay the closing of a modal after a click if no animation used.
     * @option
     * @example 10
     */
    hideDelay: 0,
    /**
     * Allows a click on the body/overlay to close the modal.
     * @option
     * @example true
     */
    closeOnClick: true,
    /**
     * Allows the modal to close if the user presses the `ESCAPE` key.
     * @option
     * @example true
     */
    closeOnEsc: true,
    /**
     * If true, allows multiple modals to be displayed at once.
     * @option
     * @example false
     */
    multipleOpened: false,
    /**
     * Distance, in pixels, the modal should push down from the top of the screen.
     * @option
     * @example auto
     */
    vOffset: 'auto',
    /**
     * Distance, in pixels, the modal should push in from the side of the screen.
     * @option
     * @example auto
     */
    hOffset: 'auto',
    /**
     * Allows the modal to be fullscreen, completely blocking out the rest of the view. JS checks for this as well.
     * @option
     * @example false
     */
    fullScreen: false,
    /**
     * Percentage of screen height the modal should push up from the bottom of the view.
     * @option
     * @example 10
     */
    btmOffsetPct: 10,
    /**
     * Allows the modal to generate an overlay div, which will cover the view when modal opens.
     * @option
     * @example true
     */
    overlay: true,
    /**
     * Allows the modal to remove and reinject markup on close. Should be true if using video elements w/o using provider's api, otherwise, videos will continue to play in the background.
     * @option
     * @example false
     */
    resetOnClose: false,
    /**
     * Allows the modal to alter the url on open/close, and allows the use of the `back` button to close modals. ALSO, allows a modal to auto-maniacally open on page load IF the hash === the modal's user-set id.
     * @option
     * @example false
     */
    deepLink: false
  };

  // Window exports
  Foundation.plugin(Reveal, 'Reveal');

  function iPhoneSniff() {
    return (/iP(ad|hone|od).*OS/.test(window.navigator.userAgent)
    );
  }

  function androidSniff() {
    return (/Android/.test(window.navigator.userAgent)
    );
  }

  function mobileSniff() {
    return iPhoneSniff() || androidSniff();
  }
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * Slider module.
   * @module foundation.slider
   * @requires foundation.util.motion
   * @requires foundation.util.triggers
   * @requires foundation.util.keyboard
   * @requires foundation.util.touch
   */

  var Slider = function () {
    /**
     * Creates a new instance of a drilldown menu.
     * @class
     * @param {jQuery} element - jQuery object to make into an accordion menu.
     * @param {Object} options - Overrides to the default plugin settings.
     */
    function Slider(element, options) {
      _classCallCheck(this, Slider);

      this.$element = element;
      this.options = $.extend({}, Slider.defaults, this.$element.data(), options);

      this._init();

      Foundation.registerPlugin(this, 'Slider');
      Foundation.Keyboard.register('Slider', {
        'ltr': {
          'ARROW_RIGHT': 'increase',
          'ARROW_UP': 'increase',
          'ARROW_DOWN': 'decrease',
          'ARROW_LEFT': 'decrease',
          'SHIFT_ARROW_RIGHT': 'increase_fast',
          'SHIFT_ARROW_UP': 'increase_fast',
          'SHIFT_ARROW_DOWN': 'decrease_fast',
          'SHIFT_ARROW_LEFT': 'decrease_fast'
        },
        'rtl': {
          'ARROW_LEFT': 'increase',
          'ARROW_RIGHT': 'decrease',
          'SHIFT_ARROW_LEFT': 'increase_fast',
          'SHIFT_ARROW_RIGHT': 'decrease_fast'
        }
      });
    }

    /**
     * Initilizes the plugin by reading/setting attributes, creating collections and setting the initial position of the handle(s).
     * @function
     * @private
     */


    _createClass(Slider, [{
      key: '_init',
      value: function _init() {
        this.inputs = this.$element.find('input');
        this.handles = this.$element.find('[data-slider-handle]');

        this.$handle = this.handles.eq(0);
        this.$input = this.inputs.length ? this.inputs.eq(0) : $('#' + this.$handle.attr('aria-controls'));
        this.$fill = this.$element.find('[data-slider-fill]').css(this.options.vertical ? 'height' : 'width', 0);

        var isDbl = false,
            _this = this;
        if (this.options.disabled || this.$element.hasClass(this.options.disabledClass)) {
          this.options.disabled = true;
          this.$element.addClass(this.options.disabledClass);
        }
        if (!this.inputs.length) {
          this.inputs = $().add(this.$input);
          this.options.binding = true;
        }
        this._setInitAttr(0);
        this._events(this.$handle);

        if (this.handles[1]) {
          this.options.doubleSided = true;
          this.$handle2 = this.handles.eq(1);
          this.$input2 = this.inputs.length > 1 ? this.inputs.eq(1) : $('#' + this.$handle2.attr('aria-controls'));

          if (!this.inputs[1]) {
            this.inputs = this.inputs.add(this.$input2);
          }
          isDbl = true;

          this._setHandlePos(this.$handle, this.options.initialStart, true, function () {

            _this._setHandlePos(_this.$handle2, _this.options.initialEnd, true);
          });
          // this.$handle.triggerHandler('click.zf.slider');
          this._setInitAttr(1);
          this._events(this.$handle2);
        }

        if (!isDbl) {
          this._setHandlePos(this.$handle, this.options.initialStart, true);
        }
      }

      /**
       * Sets the position of the selected handle and fill bar.
       * @function
       * @private
       * @param {jQuery} $hndl - the selected handle to move.
       * @param {Number} location - floating point between the start and end values of the slider bar.
       * @param {Function} cb - callback function to fire on completion.
       * @fires Slider#moved
       * @fires Slider#changed
       */

    }, {
      key: '_setHandlePos',
      value: function _setHandlePos($hndl, location, noInvert, cb) {
        // don't move if the slider has been disabled since its initialization
        if (this.$element.hasClass(this.options.disabledClass)) {
          return;
        }
        //might need to alter that slightly for bars that will have odd number selections.
        location = parseFloat(location); //on input change events, convert string to number...grumble.

        // prevent slider from running out of bounds, if value exceeds the limits set through options, override the value to min/max
        if (location < this.options.start) {
          location = this.options.start;
        } else if (location > this.options.end) {
          location = this.options.end;
        }

        var isDbl = this.options.doubleSided;

        if (isDbl) {
          //this block is to prevent 2 handles from crossing eachother. Could/should be improved.
          if (this.handles.index($hndl) === 0) {
            var h2Val = parseFloat(this.$handle2.attr('aria-valuenow'));
            location = location >= h2Val ? h2Val - this.options.step : location;
          } else {
            var h1Val = parseFloat(this.$handle.attr('aria-valuenow'));
            location = location <= h1Val ? h1Val + this.options.step : location;
          }
        }

        //this is for single-handled vertical sliders, it adjusts the value to account for the slider being "upside-down"
        //for click and drag events, it's weird due to the scale(-1, 1) css property
        if (this.options.vertical && !noInvert) {
          location = this.options.end - location;
        }

        var _this = this,
            vert = this.options.vertical,
            hOrW = vert ? 'height' : 'width',
            lOrT = vert ? 'top' : 'left',
            handleDim = $hndl[0].getBoundingClientRect()[hOrW],
            elemDim = this.$element[0].getBoundingClientRect()[hOrW],

        //percentage of bar min/max value based on click or drag point
        pctOfBar = percent(location - this.options.start, this.options.end - this.options.start).toFixed(2),

        //number of actual pixels to shift the handle, based on the percentage obtained above
        pxToMove = (elemDim - handleDim) * pctOfBar,

        //percentage of bar to shift the handle
        movement = (percent(pxToMove, elemDim) * 100).toFixed(this.options.decimal);
        //fixing the decimal value for the location number, is passed to other methods as a fixed floating-point value
        location = parseFloat(location.toFixed(this.options.decimal));
        // declare empty object for css adjustments, only used with 2 handled-sliders
        var css = {};

        this._setValues($hndl, location);

        // TODO update to calculate based on values set to respective inputs??
        if (isDbl) {
          var isLeftHndl = this.handles.index($hndl) === 0,

          //empty variable, will be used for min-height/width for fill bar
          dim,

          //percentage w/h of the handle compared to the slider bar
          handlePct = ~~(percent(handleDim, elemDim) * 100);
          //if left handle, the math is slightly different than if it's the right handle, and the left/top property needs to be changed for the fill bar
          if (isLeftHndl) {
            //left or top percentage value to apply to the fill bar.
            css[lOrT] = movement + '%';
            //calculate the new min-height/width for the fill bar.
            dim = parseFloat(this.$handle2[0].style[lOrT]) - movement + handlePct;
            //this callback is necessary to prevent errors and allow the proper placement and initialization of a 2-handled slider
            //plus, it means we don't care if 'dim' isNaN on init, it won't be in the future.
            if (cb && typeof cb === 'function') {
              cb();
            } //this is only needed for the initialization of 2 handled sliders
          } else {
            //just caching the value of the left/bottom handle's left/top property
            var handlePos = parseFloat(this.$handle[0].style[lOrT]);
            //calculate the new min-height/width for the fill bar. Use isNaN to prevent false positives for numbers <= 0
            //based on the percentage of movement of the handle being manipulated, less the opposing handle's left/top position, plus the percentage w/h of the handle itself
            dim = movement - (isNaN(handlePos) ? this.options.initialStart / ((this.options.end - this.options.start) / 100) : handlePos) + handlePct;
          }
          // assign the min-height/width to our css object
          css['min-' + hOrW] = dim + '%';
        }

        this.$element.one('finished.zf.animate', function () {
          /**
           * Fires when the handle is done moving.
           * @event Slider#moved
           */
          _this.$element.trigger('moved.zf.slider', [$hndl]);
        });

        //because we don't know exactly how the handle will be moved, check the amount of time it should take to move.
        var moveTime = this.$element.data('dragging') ? 1000 / 60 : this.options.moveTime;

        Foundation.Move(moveTime, $hndl, function () {
          //adjusting the left/top property of the handle, based on the percentage calculated above
          $hndl.css(lOrT, movement + '%');

          if (!_this.options.doubleSided) {
            //if single-handled, a simple method to expand the fill bar
            _this.$fill.css(hOrW, pctOfBar * 100 + '%');
          } else {
            //otherwise, use the css object we created above
            _this.$fill.css(css);
          }
        });

        /**
         * Fires when the value has not been change for a given time.
         * @event Slider#changed
         */
        clearTimeout(_this.timeout);
        _this.timeout = setTimeout(function () {
          _this.$element.trigger('changed.zf.slider', [$hndl]);
        }, _this.options.changedDelay);
      }

      /**
       * Sets the initial attribute for the slider element.
       * @function
       * @private
       * @param {Number} idx - index of the current handle/input to use.
       */

    }, {
      key: '_setInitAttr',
      value: function _setInitAttr(idx) {
        var id = this.inputs.eq(idx).attr('id') || Foundation.GetYoDigits(6, 'slider');
        this.inputs.eq(idx).attr({
          'id': id,
          'max': this.options.end,
          'min': this.options.start,
          'step': this.options.step
        });
        this.handles.eq(idx).attr({
          'role': 'slider',
          'aria-controls': id,
          'aria-valuemax': this.options.end,
          'aria-valuemin': this.options.start,
          'aria-valuenow': idx === 0 ? this.options.initialStart : this.options.initialEnd,
          'aria-orientation': this.options.vertical ? 'vertical' : 'horizontal',
          'tabindex': 0
        });
      }

      /**
       * Sets the input and `aria-valuenow` values for the slider element.
       * @function
       * @private
       * @param {jQuery} $handle - the currently selected handle.
       * @param {Number} val - floating point of the new value.
       */

    }, {
      key: '_setValues',
      value: function _setValues($handle, val) {
        var idx = this.options.doubleSided ? this.handles.index($handle) : 0;
        this.inputs.eq(idx).val(val);
        $handle.attr('aria-valuenow', val);
      }

      /**
       * Handles events on the slider element.
       * Calculates the new location of the current handle.
       * If there are two handles and the bar was clicked, it determines which handle to move.
       * @function
       * @private
       * @param {Object} e - the `event` object passed from the listener.
       * @param {jQuery} $handle - the current handle to calculate for, if selected.
       * @param {Number} val - floating point number for the new value of the slider.
       * TODO clean this up, there's a lot of repeated code between this and the _setHandlePos fn.
       */

    }, {
      key: '_handleEvent',
      value: function _handleEvent(e, $handle, val) {
        var value, hasVal;
        if (!val) {
          //click or drag events
          e.preventDefault();
          var _this = this,
              vertical = this.options.vertical,
              param = vertical ? 'height' : 'width',
              direction = vertical ? 'top' : 'left',
              eventOffset = vertical ? e.pageY : e.pageX,
              halfOfHandle = this.$handle[0].getBoundingClientRect()[param] / 2,
              barDim = this.$element[0].getBoundingClientRect()[param],
              windowScroll = vertical ? $(window).scrollTop() : $(window).scrollLeft();

          var elemOffset = this.$element.offset()[direction];

          // touch events emulated by the touch util give position relative to screen, add window.scroll to event coordinates...
          // best way to guess this is simulated is if clientY == pageY
          if (e.clientY === e.pageY) {
            eventOffset = eventOffset + windowScroll;
          }
          var eventFromBar = eventOffset - elemOffset;
          var barXY;
          if (eventFromBar < 0) {
            barXY = 0;
          } else if (eventFromBar > barDim) {
            barXY = barDim;
          } else {
            barXY = eventFromBar;
          }
          offsetPct = percent(barXY, barDim);

          value = (this.options.end - this.options.start) * offsetPct + this.options.start;

          // turn everything around for RTL, yay math!
          if (Foundation.rtl() && !this.options.vertical) {
            value = this.options.end - value;
          }

          value = _this._adjustValue(null, value);
          //boolean flag for the setHandlePos fn, specifically for vertical sliders
          hasVal = false;

          if (!$handle) {
            //figure out which handle it is, pass it to the next function.
            var firstHndlPos = absPosition(this.$handle, direction, barXY, param),
                secndHndlPos = absPosition(this.$handle2, direction, barXY, param);
            $handle = firstHndlPos <= secndHndlPos ? this.$handle : this.$handle2;
          }
        } else {
          //change event on input
          value = this._adjustValue(null, val);
          hasVal = true;
        }

        this._setHandlePos($handle, value, hasVal);
      }

      /**
       * Adjustes value for handle in regard to step value. returns adjusted value
       * @function
       * @private
       * @param {jQuery} $handle - the selected handle.
       * @param {Number} value - value to adjust. used if $handle is falsy
       */

    }, {
      key: '_adjustValue',
      value: function _adjustValue($handle, value) {
        var val,
            step = this.options.step,
            div = parseFloat(step / 2),
            left,
            prev_val,
            next_val;
        if (!!$handle) {
          val = parseFloat($handle.attr('aria-valuenow'));
        } else {
          val = value;
        }
        left = val % step;
        prev_val = val - left;
        next_val = prev_val + step;
        if (left === 0) {
          return val;
        }
        val = val >= prev_val + div ? next_val : prev_val;
        return val;
      }

      /**
       * Adds event listeners to the slider elements.
       * @function
       * @private
       * @param {jQuery} $handle - the current handle to apply listeners to.
       */

    }, {
      key: '_events',
      value: function _events($handle) {
        var _this = this,
            curHandle,
            timer;

        this.inputs.off('change.zf.slider').on('change.zf.slider', function (e) {
          var idx = _this.inputs.index($(this));
          _this._handleEvent(e, _this.handles.eq(idx), $(this).val());
        });

        if (this.options.clickSelect) {
          this.$element.off('click.zf.slider').on('click.zf.slider', function (e) {
            if (_this.$element.data('dragging')) {
              return false;
            }

            if (!$(e.target).is('[data-slider-handle]')) {
              if (_this.options.doubleSided) {
                _this._handleEvent(e);
              } else {
                _this._handleEvent(e, _this.$handle);
              }
            }
          });
        }

        if (this.options.draggable) {
          this.handles.addTouch();

          var $body = $('body');
          $handle.off('mousedown.zf.slider').on('mousedown.zf.slider', function (e) {
            $handle.addClass('is-dragging');
            _this.$fill.addClass('is-dragging'); //
            _this.$element.data('dragging', true);

            curHandle = $(e.currentTarget);

            $body.on('mousemove.zf.slider', function (e) {
              e.preventDefault();
              _this._handleEvent(e, curHandle);
            }).on('mouseup.zf.slider', function (e) {
              _this._handleEvent(e, curHandle);

              $handle.removeClass('is-dragging');
              _this.$fill.removeClass('is-dragging');
              _this.$element.data('dragging', false);

              $body.off('mousemove.zf.slider mouseup.zf.slider');
            });
          })
          // prevent events triggered by touch
          .on('selectstart.zf.slider touchmove.zf.slider', function (e) {
            e.preventDefault();
          });
        }

        $handle.off('keydown.zf.slider').on('keydown.zf.slider', function (e) {
          var _$handle = $(this),
              idx = _this.options.doubleSided ? _this.handles.index(_$handle) : 0,
              oldValue = parseFloat(_this.inputs.eq(idx).val()),
              newValue;

          // handle keyboard event with keyboard util
          Foundation.Keyboard.handleKey(e, 'Slider', {
            decrease: function decrease() {
              newValue = oldValue - _this.options.step;
            },
            increase: function increase() {
              newValue = oldValue + _this.options.step;
            },
            decrease_fast: function decrease_fast() {
              newValue = oldValue - _this.options.step * 10;
            },
            increase_fast: function increase_fast() {
              newValue = oldValue + _this.options.step * 10;
            },
            handled: function handled() {
              // only set handle pos when event was handled specially
              e.preventDefault();
              _this._setHandlePos(_$handle, newValue, true);
            }
          });
          /*if (newValue) { // if pressed key has special function, update value
            e.preventDefault();
            _this._setHandlePos(_$handle, newValue);
          }*/
        });
      }

      /**
       * Destroys the slider plugin.
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        this.handles.off('.zf.slider');
        this.inputs.off('.zf.slider');
        this.$element.off('.zf.slider');

        Foundation.unregisterPlugin(this);
      }
    }]);

    return Slider;
  }();

  Slider.defaults = {
    /**
     * Minimum value for the slider scale.
     * @option
     * @example 0
     */
    start: 0,
    /**
     * Maximum value for the slider scale.
     * @option
     * @example 100
     */
    end: 100,
    /**
     * Minimum value change per change event.
     * @option
     * @example 1
     */
    step: 1,
    /**
     * Value at which the handle/input *(left handle/first input)* should be set to on initialization.
     * @option
     * @example 0
     */
    initialStart: 0,
    /**
     * Value at which the right handle/second input should be set to on initialization.
     * @option
     * @example 100
     */
    initialEnd: 100,
    /**
     * Allows the input to be located outside the container and visible. Set to by the JS
     * @option
     * @example false
     */
    binding: false,
    /**
     * Allows the user to click/tap on the slider bar to select a value.
     * @option
     * @example true
     */
    clickSelect: true,
    /**
     * Set to true and use the `vertical` class to change alignment to vertical.
     * @option
     * @example false
     */
    vertical: false,
    /**
     * Allows the user to drag the slider handle(s) to select a value.
     * @option
     * @example true
     */
    draggable: true,
    /**
     * Disables the slider and prevents event listeners from being applied. Double checked by JS with `disabledClass`.
     * @option
     * @example false
     */
    disabled: false,
    /**
     * Allows the use of two handles. Double checked by the JS. Changes some logic handling.
     * @option
     * @example false
     */
    doubleSided: false,
    /**
     * Potential future feature.
     */
    // steps: 100,
    /**
     * Number of decimal places the plugin should go to for floating point precision.
     * @option
     * @example 2
     */
    decimal: 2,
    /**
     * Time delay for dragged elements.
     */
    // dragDelay: 0,
    /**
     * Time, in ms, to animate the movement of a slider handle if user clicks/taps on the bar. Needs to be manually set if updating the transition time in the Sass settings.
     * @option
     * @example 200
     */
    moveTime: 200, //update this if changing the transition time in the sass
    /**
     * Class applied to disabled sliders.
     * @option
     * @example 'disabled'
     */
    disabledClass: 'disabled',
    /**
     * Will invert the default layout for a vertical<span data-tooltip title="who would do this???"> </span>slider.
     * @option
     * @example false
     */
    invertVertical: false,
    /**
     * Milliseconds before the `changed.zf-slider` event is triggered after value change.
     * @option
     * @example 500
     */
    changedDelay: 500
  };

  function percent(frac, num) {
    return frac / num;
  }
  function absPosition($handle, dir, clickPos, param) {
    return Math.abs($handle.position()[dir] + $handle[param]() / 2 - clickPos);
  }

  // Window exports
  Foundation.plugin(Slider, 'Slider');
}(jQuery);

//*********this is in case we go to static, absolute positions instead of dynamic positioning********
// this.setSteps(function() {
//   _this._events();
//   var initStart = _this.options.positions[_this.options.initialStart - 1] || null;
//   var initEnd = _this.options.initialEnd ? _this.options.position[_this.options.initialEnd - 1] : null;
//   if (initStart || initEnd) {
//     _this._handleEvent(initStart, initEnd);
//   }
// });

//***********the other part of absolute positions*************
// Slider.prototype.setSteps = function(cb) {
//   var posChange = this.$element.outerWidth() / this.options.steps;
//   var counter = 0
//   while(counter < this.options.steps) {
//     if (counter) {
//       this.options.positions.push(this.options.positions[counter - 1] + posChange);
//     } else {
//       this.options.positions.push(posChange);
//     }
//     counter++;
//   }
//   cb();
// };
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * Sticky module.
   * @module foundation.sticky
   * @requires foundation.util.triggers
   * @requires foundation.util.mediaQuery
   */

  var Sticky = function () {
    /**
     * Creates a new instance of a sticky thing.
     * @class
     * @param {jQuery} element - jQuery object to make sticky.
     * @param {Object} options - options object passed when creating the element programmatically.
     */
    function Sticky(element, options) {
      _classCallCheck(this, Sticky);

      this.$element = element;
      this.options = $.extend({}, Sticky.defaults, this.$element.data(), options);

      this._init();

      Foundation.registerPlugin(this, 'Sticky');
    }

    /**
     * Initializes the sticky element by adding classes, getting/setting dimensions, breakpoints and attributes
     * @function
     * @private
     */


    _createClass(Sticky, [{
      key: '_init',
      value: function _init() {
        var $parent = this.$element.parent('[data-sticky-container]'),
            id = this.$element[0].id || Foundation.GetYoDigits(6, 'sticky'),
            _this = this;

        if (!$parent.length) {
          this.wasWrapped = true;
        }
        this.$container = $parent.length ? $parent : $(this.options.container).wrapInner(this.$element);
        this.$container.addClass(this.options.containerClass);

        this.$element.addClass(this.options.stickyClass).attr({ 'data-resize': id });

        this.scrollCount = this.options.checkEvery;
        this.isStuck = false;
        $(window).one('load.zf.sticky', function () {
          if (_this.options.anchor !== '') {
            _this.$anchor = $('#' + _this.options.anchor);
          } else {
            _this._parsePoints();
          }

          _this._setSizes(function () {
            _this._calc(false);
          });
          _this._events(id.split('-').reverse().join('-'));
        });
      }

      /**
       * If using multiple elements as anchors, calculates the top and bottom pixel values the sticky thing should stick and unstick on.
       * @function
       * @private
       */

    }, {
      key: '_parsePoints',
      value: function _parsePoints() {
        var top = this.options.topAnchor == "" ? 1 : this.options.topAnchor,
            btm = this.options.btmAnchor == "" ? document.documentElement.scrollHeight : this.options.btmAnchor,
            pts = [top, btm],
            breaks = {};
        for (var i = 0, len = pts.length; i < len && pts[i]; i++) {
          var pt;
          if (typeof pts[i] === 'number') {
            pt = pts[i];
          } else {
            var place = pts[i].split(':'),
                anchor = $('#' + place[0]);

            pt = anchor.offset().top;
            if (place[1] && place[1].toLowerCase() === 'bottom') {
              pt += anchor[0].getBoundingClientRect().height;
            }
          }
          breaks[i] = pt;
        }

        this.points = breaks;
        return;
      }

      /**
       * Adds event handlers for the scrolling element.
       * @private
       * @param {String} id - psuedo-random id for unique scroll event listener.
       */

    }, {
      key: '_events',
      value: function _events(id) {
        var _this = this,
            scrollListener = this.scrollListener = 'scroll.zf.' + id;
        if (this.isOn) {
          return;
        }
        if (this.canStick) {
          this.isOn = true;
          $(window).off(scrollListener).on(scrollListener, function (e) {
            if (_this.scrollCount === 0) {
              _this.scrollCount = _this.options.checkEvery;
              _this._setSizes(function () {
                _this._calc(false, window.pageYOffset);
              });
            } else {
              _this.scrollCount--;
              _this._calc(false, window.pageYOffset);
            }
          });
        }

        this.$element.off('resizeme.zf.trigger').on('resizeme.zf.trigger', function (e, el) {
          _this._setSizes(function () {
            _this._calc(false);
            if (_this.canStick) {
              if (!_this.isOn) {
                _this._events(id);
              }
            } else if (_this.isOn) {
              _this._pauseListeners(scrollListener);
            }
          });
        });
      }

      /**
       * Removes event handlers for scroll and change events on anchor.
       * @fires Sticky#pause
       * @param {String} scrollListener - unique, namespaced scroll listener attached to `window`
       */

    }, {
      key: '_pauseListeners',
      value: function _pauseListeners(scrollListener) {
        this.isOn = false;
        $(window).off(scrollListener);

        /**
         * Fires when the plugin is paused due to resize event shrinking the view.
         * @event Sticky#pause
         * @private
         */
        this.$element.trigger('pause.zf.sticky');
      }

      /**
       * Called on every `scroll` event and on `_init`
       * fires functions based on booleans and cached values
       * @param {Boolean} checkSizes - true if plugin should recalculate sizes and breakpoints.
       * @param {Number} scroll - current scroll position passed from scroll event cb function. If not passed, defaults to `window.pageYOffset`.
       */

    }, {
      key: '_calc',
      value: function _calc(checkSizes, scroll) {
        if (checkSizes) {
          this._setSizes();
        }

        if (!this.canStick) {
          if (this.isStuck) {
            this._removeSticky(true);
          }
          return false;
        }

        if (!scroll) {
          scroll = window.pageYOffset;
        }

        if (scroll >= this.topPoint) {
          if (scroll <= this.bottomPoint) {
            if (!this.isStuck) {
              this._setSticky();
            }
          } else {
            if (this.isStuck) {
              this._removeSticky(false);
            }
          }
        } else {
          if (this.isStuck) {
            this._removeSticky(true);
          }
        }
      }

      /**
       * Causes the $element to become stuck.
       * Adds `position: fixed;`, and helper classes.
       * @fires Sticky#stuckto
       * @function
       * @private
       */

    }, {
      key: '_setSticky',
      value: function _setSticky() {
        var _this = this,
            stickTo = this.options.stickTo,
            mrgn = stickTo === 'top' ? 'marginTop' : 'marginBottom',
            notStuckTo = stickTo === 'top' ? 'bottom' : 'top',
            css = {};

        css[mrgn] = this.options[mrgn] + 'em';
        css[stickTo] = 0;
        css[notStuckTo] = 'auto';
        css['left'] = this.$container.offset().left + parseInt(window.getComputedStyle(this.$container[0])["padding-left"], 10);
        this.isStuck = true;
        this.$element.removeClass('is-anchored is-at-' + notStuckTo).addClass('is-stuck is-at-' + stickTo).css(css)
        /**
         * Fires when the $element has become `position: fixed;`
         * Namespaced to `top` or `bottom`, e.g. `sticky.zf.stuckto:top`
         * @event Sticky#stuckto
         */
        .trigger('sticky.zf.stuckto:' + stickTo);
        this.$element.on("transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd", function () {
          _this._setSizes();
        });
      }

      /**
       * Causes the $element to become unstuck.
       * Removes `position: fixed;`, and helper classes.
       * Adds other helper classes.
       * @param {Boolean} isTop - tells the function if the $element should anchor to the top or bottom of its $anchor element.
       * @fires Sticky#unstuckfrom
       * @private
       */

    }, {
      key: '_removeSticky',
      value: function _removeSticky(isTop) {
        var stickTo = this.options.stickTo,
            stickToTop = stickTo === 'top',
            css = {},
            anchorPt = (this.points ? this.points[1] - this.points[0] : this.anchorHeight) - this.elemHeight,
            mrgn = stickToTop ? 'marginTop' : 'marginBottom',
            notStuckTo = stickToTop ? 'bottom' : 'top',
            topOrBottom = isTop ? 'top' : 'bottom';

        css[mrgn] = 0;

        css['bottom'] = 'auto';
        if (isTop) {
          css['top'] = 0;
        } else {
          css['top'] = anchorPt;
        }

        css['left'] = '';
        this.isStuck = false;
        this.$element.removeClass('is-stuck is-at-' + stickTo).addClass('is-anchored is-at-' + topOrBottom).css(css)
        /**
         * Fires when the $element has become anchored.
         * Namespaced to `top` or `bottom`, e.g. `sticky.zf.unstuckfrom:bottom`
         * @event Sticky#unstuckfrom
         */
        .trigger('sticky.zf.unstuckfrom:' + topOrBottom);
      }

      /**
       * Sets the $element and $container sizes for plugin.
       * Calls `_setBreakPoints`.
       * @param {Function} cb - optional callback function to fire on completion of `_setBreakPoints`.
       * @private
       */

    }, {
      key: '_setSizes',
      value: function _setSizes(cb) {
        this.canStick = Foundation.MediaQuery.atLeast(this.options.stickyOn);
        if (!this.canStick) {
          cb();
        }
        var _this = this,
            newElemWidth = this.$container[0].getBoundingClientRect().width,
            comp = window.getComputedStyle(this.$container[0]),
            pdng = parseInt(comp['padding-right'], 10);

        if (this.$anchor && this.$anchor.length) {
          this.anchorHeight = this.$anchor[0].getBoundingClientRect().height;
        } else {
          this._parsePoints();
        }

        this.$element.css({
          'max-width': newElemWidth - pdng + 'px'
        });

        var newContainerHeight = this.$element[0].getBoundingClientRect().height || this.containerHeight;
        if (this.$element.css("display") == "none") {
          newContainerHeight = 0;
        }
        this.containerHeight = newContainerHeight;
        this.$container.css({
          height: newContainerHeight
        });
        this.elemHeight = newContainerHeight;

        if (this.isStuck) {
          this.$element.css({ "left": this.$container.offset().left + parseInt(comp['padding-left'], 10) });
        }

        this._setBreakPoints(newContainerHeight, function () {
          if (cb) {
            cb();
          }
        });
      }

      /**
       * Sets the upper and lower breakpoints for the element to become sticky/unsticky.
       * @param {Number} elemHeight - px value for sticky.$element height, calculated by `_setSizes`.
       * @param {Function} cb - optional callback function to be called on completion.
       * @private
       */

    }, {
      key: '_setBreakPoints',
      value: function _setBreakPoints(elemHeight, cb) {
        if (!this.canStick) {
          if (cb) {
            cb();
          } else {
            return false;
          }
        }
        var mTop = emCalc(this.options.marginTop),
            mBtm = emCalc(this.options.marginBottom),
            topPoint = this.points ? this.points[0] : this.$anchor.offset().top,
            bottomPoint = this.points ? this.points[1] : topPoint + this.anchorHeight,

        // topPoint = this.$anchor.offset().top || this.points[0],
        // bottomPoint = topPoint + this.anchorHeight || this.points[1],
        winHeight = window.innerHeight;

        if (this.options.stickTo === 'top') {
          topPoint -= mTop;
          bottomPoint -= elemHeight + mTop;
        } else if (this.options.stickTo === 'bottom') {
          topPoint -= winHeight - (elemHeight + mBtm);
          bottomPoint -= winHeight - mBtm;
        } else {
          //this would be the stickTo: both option... tricky
        }

        this.topPoint = topPoint;
        this.bottomPoint = bottomPoint;

        if (cb) {
          cb();
        }
      }

      /**
       * Destroys the current sticky element.
       * Resets the element to the top position first.
       * Removes event listeners, JS-added css properties and classes, and unwraps the $element if the JS added the $container.
       * @function
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        this._removeSticky(true);

        this.$element.removeClass(this.options.stickyClass + ' is-anchored is-at-top').css({
          height: '',
          top: '',
          bottom: '',
          'max-width': ''
        }).off('resizeme.zf.trigger');
        if (this.$anchor && this.$anchor.length) {
          this.$anchor.off('change.zf.sticky');
        }
        $(window).off(this.scrollListener);

        if (this.wasWrapped) {
          this.$element.unwrap();
        } else {
          this.$container.removeClass(this.options.containerClass).css({
            height: ''
          });
        }
        Foundation.unregisterPlugin(this);
      }
    }]);

    return Sticky;
  }();

  Sticky.defaults = {
    /**
     * Customizable container template. Add your own classes for styling and sizing.
     * @option
     * @example '&lt;div data-sticky-container class="small-6 columns"&gt;&lt;/div&gt;'
     */
    container: '<div data-sticky-container></div>',
    /**
     * Location in the view the element sticks to.
     * @option
     * @example 'top'
     */
    stickTo: 'top',
    /**
     * If anchored to a single element, the id of that element.
     * @option
     * @example 'exampleId'
     */
    anchor: '',
    /**
     * If using more than one element as anchor points, the id of the top anchor.
     * @option
     * @example 'exampleId:top'
     */
    topAnchor: '',
    /**
     * If using more than one element as anchor points, the id of the bottom anchor.
     * @option
     * @example 'exampleId:bottom'
     */
    btmAnchor: '',
    /**
     * Margin, in `em`'s to apply to the top of the element when it becomes sticky.
     * @option
     * @example 1
     */
    marginTop: 1,
    /**
     * Margin, in `em`'s to apply to the bottom of the element when it becomes sticky.
     * @option
     * @example 1
     */
    marginBottom: 1,
    /**
     * Breakpoint string that is the minimum screen size an element should become sticky.
     * @option
     * @example 'medium'
     */
    stickyOn: 'medium',
    /**
     * Class applied to sticky element, and removed on destruction. Foundation defaults to `sticky`.
     * @option
     * @example 'sticky'
     */
    stickyClass: 'sticky',
    /**
     * Class applied to sticky container. Foundation defaults to `sticky-container`.
     * @option
     * @example 'sticky-container'
     */
    containerClass: 'sticky-container',
    /**
     * Number of scroll events between the plugin's recalculating sticky points. Setting it to `0` will cause it to recalc every scroll event, setting it to `-1` will prevent recalc on scroll.
     * @option
     * @example 50
     */
    checkEvery: -1
  };

  /**
   * Helper function to calculate em values
   * @param Number {em} - number of em's to calculate into pixels
   */
  function emCalc(em) {
    return parseInt(window.getComputedStyle(document.body, null).fontSize, 10) * em;
  }

  // Window exports
  Foundation.plugin(Sticky, 'Sticky');
}(jQuery);
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * Tabs module.
   * @module foundation.tabs
   * @requires foundation.util.keyboard
   * @requires foundation.util.timerAndImageLoader if tabs contain images
   */

  var Tabs = function () {
    /**
     * Creates a new instance of tabs.
     * @class
     * @fires Tabs#init
     * @param {jQuery} element - jQuery object to make into tabs.
     * @param {Object} options - Overrides to the default plugin settings.
     */
    function Tabs(element, options) {
      _classCallCheck(this, Tabs);

      this.$element = element;
      this.options = $.extend({}, Tabs.defaults, this.$element.data(), options);

      this._init();
      Foundation.registerPlugin(this, 'Tabs');
      Foundation.Keyboard.register('Tabs', {
        'ENTER': 'open',
        'SPACE': 'open',
        'ARROW_RIGHT': 'next',
        'ARROW_UP': 'previous',
        'ARROW_DOWN': 'next',
        'ARROW_LEFT': 'previous'
        // 'TAB': 'next',
        // 'SHIFT_TAB': 'previous'
      });
    }

    /**
     * Initializes the tabs by showing and focusing (if autoFocus=true) the preset active tab.
     * @private
     */


    _createClass(Tabs, [{
      key: '_init',
      value: function _init() {
        var _this = this;

        this.$tabTitles = this.$element.find('.' + this.options.linkClass);
        this.$tabContent = $('[data-tabs-content="' + this.$element[0].id + '"]');

        this.$tabTitles.each(function () {
          var $elem = $(this),
              $link = $elem.find('a'),
              isActive = $elem.hasClass('is-active'),
              hash = $link[0].hash.slice(1),
              linkId = $link[0].id ? $link[0].id : hash + '-label',
              $tabContent = $('#' + hash);

          $elem.attr({ 'role': 'presentation' });

          $link.attr({
            'role': 'tab',
            'aria-controls': hash,
            'aria-selected': isActive,
            'id': linkId
          });

          $tabContent.attr({
            'role': 'tabpanel',
            'aria-hidden': !isActive,
            'aria-labelledby': linkId
          });

          if (isActive && _this.options.autoFocus) {
            $link.focus();
          }
        });

        if (this.options.matchHeight) {
          var $images = this.$tabContent.find('img');

          if ($images.length) {
            Foundation.onImagesLoaded($images, this._setHeight.bind(this));
          } else {
            this._setHeight();
          }
        }

        this._events();
      }

      /**
       * Adds event handlers for items within the tabs.
       * @private
       */

    }, {
      key: '_events',
      value: function _events() {
        this._addKeyHandler();
        this._addClickHandler();
        this._setHeightMqHandler = null;

        if (this.options.matchHeight) {
          this._setHeightMqHandler = this._setHeight.bind(this);

          $(window).on('changed.zf.mediaquery', this._setHeightMqHandler);
        }
      }

      /**
       * Adds click handlers for items within the tabs.
       * @private
       */

    }, {
      key: '_addClickHandler',
      value: function _addClickHandler() {
        var _this = this;

        this.$element.off('click.zf.tabs').on('click.zf.tabs', '.' + this.options.linkClass, function (e) {
          e.preventDefault();
          e.stopPropagation();
          if ($(this).hasClass('is-active')) {
            return;
          }
          _this._handleTabChange($(this));
        });
      }

      /**
       * Adds keyboard event handlers for items within the tabs.
       * @private
       */

    }, {
      key: '_addKeyHandler',
      value: function _addKeyHandler() {
        var _this = this;
        var $firstTab = _this.$element.find('li:first-of-type');
        var $lastTab = _this.$element.find('li:last-of-type');

        this.$tabTitles.off('keydown.zf.tabs').on('keydown.zf.tabs', function (e) {
          if (e.which === 9) return;

          var $element = $(this),
              $elements = $element.parent('ul').children('li'),
              $prevElement,
              $nextElement;

          $elements.each(function (i) {
            if ($(this).is($element)) {
              if (_this.options.wrapOnKeys) {
                $prevElement = i === 0 ? $elements.last() : $elements.eq(i - 1);
                $nextElement = i === $elements.length - 1 ? $elements.first() : $elements.eq(i + 1);
              } else {
                $prevElement = $elements.eq(Math.max(0, i - 1));
                $nextElement = $elements.eq(Math.min(i + 1, $elements.length - 1));
              }
              return;
            }
          });

          // handle keyboard event with keyboard util
          Foundation.Keyboard.handleKey(e, 'Tabs', {
            open: function open() {
              $element.find('[role="tab"]').focus();
              _this._handleTabChange($element);
            },
            previous: function previous() {
              $prevElement.find('[role="tab"]').focus();
              _this._handleTabChange($prevElement);
            },
            next: function next() {
              $nextElement.find('[role="tab"]').focus();
              _this._handleTabChange($nextElement);
            },
            handled: function handled() {
              e.stopPropagation();
              e.preventDefault();
            }
          });
        });
      }

      /**
       * Opens the tab `$targetContent` defined by `$target`.
       * @param {jQuery} $target - Tab to open.
       * @fires Tabs#change
       * @function
       */

    }, {
      key: '_handleTabChange',
      value: function _handleTabChange($target) {
        var $tabLink = $target.find('[role="tab"]'),
            hash = $tabLink[0].hash,
            $targetContent = this.$tabContent.find(hash),
            $oldTab = this.$element.find('.' + this.options.linkClass + '.is-active').removeClass('is-active').find('[role="tab"]').attr({ 'aria-selected': 'false' });

        $('#' + $oldTab.attr('aria-controls')).removeClass('is-active').attr({ 'aria-hidden': 'true' });

        $target.addClass('is-active');

        $tabLink.attr({ 'aria-selected': 'true' });

        $targetContent.addClass('is-active').attr({ 'aria-hidden': 'false' });

        /**
         * Fires when the plugin has successfully changed tabs.
         * @event Tabs#change
         */
        this.$element.trigger('change.zf.tabs', [$target]);
      }

      /**
       * Public method for selecting a content pane to display.
       * @param {jQuery | String} elem - jQuery object or string of the id of the pane to display.
       * @function
       */

    }, {
      key: 'selectTab',
      value: function selectTab(elem) {
        var idStr;

        if ((typeof elem === 'undefined' ? 'undefined' : _typeof(elem)) === 'object') {
          idStr = elem[0].id;
        } else {
          idStr = elem;
        }

        if (idStr.indexOf('#') < 0) {
          idStr = '#' + idStr;
        }

        var $target = this.$tabTitles.find('[href="' + idStr + '"]').parent('.' + this.options.linkClass);

        this._handleTabChange($target);
      }
    }, {
      key: '_setHeight',

      /**
       * Sets the height of each panel to the height of the tallest panel.
       * If enabled in options, gets called on media query change.
       * If loading content via external source, can be called directly or with _reflow.
       * @function
       * @private
       */
      value: function _setHeight() {
        var max = 0;
        this.$tabContent.find('.' + this.options.panelClass).css('height', '').each(function () {
          var panel = $(this),
              isActive = panel.hasClass('is-active');

          if (!isActive) {
            panel.css({ 'visibility': 'hidden', 'display': 'block' });
          }

          var temp = this.getBoundingClientRect().height;

          if (!isActive) {
            panel.css({
              'visibility': '',
              'display': ''
            });
          }

          max = temp > max ? temp : max;
        }).css('height', max + 'px');
      }

      /**
       * Destroys an instance of an tabs.
       * @fires Tabs#destroyed
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        this.$element.find('.' + this.options.linkClass).off('.zf.tabs').hide().end().find('.' + this.options.panelClass).hide();

        if (this.options.matchHeight) {
          if (this._setHeightMqHandler != null) {
            $(window).off('changed.zf.mediaquery', this._setHeightMqHandler);
          }
        }

        Foundation.unregisterPlugin(this);
      }
    }]);

    return Tabs;
  }();

  Tabs.defaults = {
    /**
     * Allows the window to scroll to content of active pane on load if set to true.
     * @option
     * @example false
     */
    autoFocus: false,

    /**
     * Allows keyboard input to 'wrap' around the tab links.
     * @option
     * @example true
     */
    wrapOnKeys: true,

    /**
     * Allows the tab content panes to match heights if set to true.
     * @option
     * @example false
     */
    matchHeight: false,

    /**
     * Class applied to `li`'s in tab link list.
     * @option
     * @example 'tabs-title'
     */
    linkClass: 'tabs-title',

    /**
     * Class applied to the content containers.
     * @option
     * @example 'tabs-panel'
     */
    panelClass: 'tabs-panel'
  };

  function checkClass($elem) {
    return $elem.hasClass('is-active');
  }

  // Window exports
  Foundation.plugin(Tabs, 'Tabs');
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * Toggler module.
   * @module foundation.toggler
   * @requires foundation.util.motion
   * @requires foundation.util.triggers
   */

  var Toggler = function () {
    /**
     * Creates a new instance of Toggler.
     * @class
     * @fires Toggler#init
     * @param {Object} element - jQuery object to add the trigger to.
     * @param {Object} options - Overrides to the default plugin settings.
     */
    function Toggler(element, options) {
      _classCallCheck(this, Toggler);

      this.$element = element;
      this.options = $.extend({}, Toggler.defaults, element.data(), options);
      this.className = '';

      this._init();
      this._events();

      Foundation.registerPlugin(this, 'Toggler');
    }

    /**
     * Initializes the Toggler plugin by parsing the toggle class from data-toggler, or animation classes from data-animate.
     * @function
     * @private
     */


    _createClass(Toggler, [{
      key: '_init',
      value: function _init() {
        var input;
        // Parse animation classes if they were set
        if (this.options.animate) {
          input = this.options.animate.split(' ');

          this.animationIn = input[0];
          this.animationOut = input[1] || null;
        }
        // Otherwise, parse toggle class
        else {
            input = this.$element.data('toggler');
            // Allow for a . at the beginning of the string
            this.className = input[0] === '.' ? input.slice(1) : input;
          }

        // Add ARIA attributes to triggers
        var id = this.$element[0].id;
        $('[data-open="' + id + '"], [data-close="' + id + '"], [data-toggle="' + id + '"]').attr('aria-controls', id);
        // If the target is hidden, add aria-hidden
        this.$element.attr('aria-expanded', this.$element.is(':hidden') ? false : true);
      }

      /**
       * Initializes events for the toggle trigger.
       * @function
       * @private
       */

    }, {
      key: '_events',
      value: function _events() {
        this.$element.off('toggle.zf.trigger').on('toggle.zf.trigger', this.toggle.bind(this));
      }

      /**
       * Toggles the target class on the target element. An event is fired from the original trigger depending on if the resultant state was "on" or "off".
       * @function
       * @fires Toggler#on
       * @fires Toggler#off
       */

    }, {
      key: 'toggle',
      value: function toggle() {
        this[this.options.animate ? '_toggleAnimate' : '_toggleClass']();
      }
    }, {
      key: '_toggleClass',
      value: function _toggleClass() {
        this.$element.toggleClass(this.className);

        var isOn = this.$element.hasClass(this.className);
        if (isOn) {
          /**
           * Fires if the target element has the class after a toggle.
           * @event Toggler#on
           */
          this.$element.trigger('on.zf.toggler');
        } else {
          /**
           * Fires if the target element does not have the class after a toggle.
           * @event Toggler#off
           */
          this.$element.trigger('off.zf.toggler');
        }

        this._updateARIA(isOn);
      }
    }, {
      key: '_toggleAnimate',
      value: function _toggleAnimate() {
        var _this = this;

        if (this.$element.is(':hidden')) {
          Foundation.Motion.animateIn(this.$element, this.animationIn, function () {
            _this._updateARIA(true);
            this.trigger('on.zf.toggler');
          });
        } else {
          Foundation.Motion.animateOut(this.$element, this.animationOut, function () {
            _this._updateARIA(false);
            this.trigger('off.zf.toggler');
          });
        }
      }
    }, {
      key: '_updateARIA',
      value: function _updateARIA(isOn) {
        this.$element.attr('aria-expanded', isOn ? true : false);
      }

      /**
       * Destroys the instance of Toggler on the element.
       * @function
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        this.$element.off('.zf.toggler');
        Foundation.unregisterPlugin(this);
      }
    }]);

    return Toggler;
  }();

  Toggler.defaults = {
    /**
     * Tells the plugin if the element should animated when toggled.
     * @option
     * @example false
     */
    animate: false
  };

  // Window exports
  Foundation.plugin(Toggler, 'Toggler');
}(jQuery);
'use strict';

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

!function ($) {

  /**
   * Tooltip module.
   * @module foundation.tooltip
   * @requires foundation.util.box
   * @requires foundation.util.triggers
   */

  var Tooltip = function () {
    /**
     * Creates a new instance of a Tooltip.
     * @class
     * @fires Tooltip#init
     * @param {jQuery} element - jQuery object to attach a tooltip to.
     * @param {Object} options - object to extend the default configuration.
     */
    function Tooltip(element, options) {
      _classCallCheck(this, Tooltip);

      this.$element = element;
      this.options = $.extend({}, Tooltip.defaults, this.$element.data(), options);

      this.isActive = false;
      this.isClick = false;
      this._init();

      Foundation.registerPlugin(this, 'Tooltip');
    }

    /**
     * Initializes the tooltip by setting the creating the tip element, adding it's text, setting private variables and setting attributes on the anchor.
     * @private
     */


    _createClass(Tooltip, [{
      key: '_init',
      value: function _init() {
        var elemId = this.$element.attr('aria-describedby') || Foundation.GetYoDigits(6, 'tooltip');

        this.options.positionClass = this.options.positionClass || this._getPositionClass(this.$element);
        this.options.tipText = this.options.tipText || this.$element.attr('title');
        this.template = this.options.template ? $(this.options.template) : this._buildTemplate(elemId);

        this.template.appendTo(document.body).text(this.options.tipText).hide();

        this.$element.attr({
          'title': '',
          'aria-describedby': elemId,
          'data-yeti-box': elemId,
          'data-toggle': elemId,
          'data-resize': elemId
        }).addClass(this.triggerClass);

        //helper variables to track movement on collisions
        this.usedPositions = [];
        this.counter = 4;
        this.classChanged = false;

        this._events();
      }

      /**
       * Grabs the current positioning class, if present, and returns the value or an empty string.
       * @private
       */

    }, {
      key: '_getPositionClass',
      value: function _getPositionClass(element) {
        if (!element) {
          return '';
        }
        // var position = element.attr('class').match(/top|left|right/g);
        var position = element[0].className.match(/\b(top|left|right)\b/g);
        position = position ? position[0] : '';
        return position;
      }
    }, {
      key: '_buildTemplate',

      /**
       * builds the tooltip element, adds attributes, and returns the template.
       * @private
       */
      value: function _buildTemplate(id) {
        var templateClasses = (this.options.tooltipClass + ' ' + this.options.positionClass + ' ' + this.options.templateClasses).trim();
        var $template = $('<div></div>').addClass(templateClasses).attr({
          'role': 'tooltip',
          'aria-hidden': true,
          'data-is-active': false,
          'data-is-focus': false,
          'id': id
        });
        return $template;
      }

      /**
       * Function that gets called if a collision event is detected.
       * @param {String} position - positioning class to try
       * @private
       */

    }, {
      key: '_reposition',
      value: function _reposition(position) {
        this.usedPositions.push(position ? position : 'bottom');

        //default, try switching to opposite side
        if (!position && this.usedPositions.indexOf('top') < 0) {
          this.template.addClass('top');
        } else if (position === 'top' && this.usedPositions.indexOf('bottom') < 0) {
          this.template.removeClass(position);
        } else if (position === 'left' && this.usedPositions.indexOf('right') < 0) {
          this.template.removeClass(position).addClass('right');
        } else if (position === 'right' && this.usedPositions.indexOf('left') < 0) {
          this.template.removeClass(position).addClass('left');
        }

        //if default change didn't work, try bottom or left first
        else if (!position && this.usedPositions.indexOf('top') > -1 && this.usedPositions.indexOf('left') < 0) {
            this.template.addClass('left');
          } else if (position === 'top' && this.usedPositions.indexOf('bottom') > -1 && this.usedPositions.indexOf('left') < 0) {
            this.template.removeClass(position).addClass('left');
          } else if (position === 'left' && this.usedPositions.indexOf('right') > -1 && this.usedPositions.indexOf('bottom') < 0) {
            this.template.removeClass(position);
          } else if (position === 'right' && this.usedPositions.indexOf('left') > -1 && this.usedPositions.indexOf('bottom') < 0) {
            this.template.removeClass(position);
          }
          //if nothing cleared, set to bottom
          else {
              this.template.removeClass(position);
            }
        this.classChanged = true;
        this.counter--;
      }

      /**
       * sets the position class of an element and recursively calls itself until there are no more possible positions to attempt, or the tooltip element is no longer colliding.
       * if the tooltip is larger than the screen width, default to full width - any user selected margin
       * @private
       */

    }, {
      key: '_setPosition',
      value: function _setPosition() {
        var position = this._getPositionClass(this.template),
            $tipDims = Foundation.Box.GetDimensions(this.template),
            $anchorDims = Foundation.Box.GetDimensions(this.$element),
            direction = position === 'left' ? 'left' : position === 'right' ? 'left' : 'top',
            param = direction === 'top' ? 'height' : 'width',
            offset = param === 'height' ? this.options.vOffset : this.options.hOffset,
            _this = this;

        if ($tipDims.width >= $tipDims.windowDims.width || !this.counter && !Foundation.Box.ImNotTouchingYou(this.template)) {
          this.template.offset(Foundation.Box.GetOffsets(this.template, this.$element, 'center bottom', this.options.vOffset, this.options.hOffset, true)).css({
            // this.$element.offset(Foundation.GetOffsets(this.template, this.$element, 'center bottom', this.options.vOffset, this.options.hOffset, true)).css({
            'width': $anchorDims.windowDims.width - this.options.hOffset * 2,
            'height': 'auto'
          });
          return false;
        }

        this.template.offset(Foundation.Box.GetOffsets(this.template, this.$element, 'center ' + (position || 'bottom'), this.options.vOffset, this.options.hOffset));

        while (!Foundation.Box.ImNotTouchingYou(this.template) && this.counter) {
          this._reposition(position);
          this._setPosition();
        }
      }

      /**
       * reveals the tooltip, and fires an event to close any other open tooltips on the page
       * @fires Tooltip#closeme
       * @fires Tooltip#show
       * @function
       */

    }, {
      key: 'show',
      value: function show() {
        if (this.options.showOn !== 'all' && !Foundation.MediaQuery.atLeast(this.options.showOn)) {
          // console.error('The screen is too small to display this tooltip');
          return false;
        }

        var _this = this;
        this.template.css('visibility', 'hidden').show();
        this._setPosition();

        /**
         * Fires to close all other open tooltips on the page
         * @event Closeme#tooltip
         */
        this.$element.trigger('closeme.zf.tooltip', this.template.attr('id'));

        this.template.attr({
          'data-is-active': true,
          'aria-hidden': false
        });
        _this.isActive = true;
        // console.log(this.template);
        this.template.stop().hide().css('visibility', '').fadeIn(this.options.fadeInDuration, function () {
          //maybe do stuff?
        });
        /**
         * Fires when the tooltip is shown
         * @event Tooltip#show
         */
        this.$element.trigger('show.zf.tooltip');
      }

      /**
       * Hides the current tooltip, and resets the positioning class if it was changed due to collision
       * @fires Tooltip#hide
       * @function
       */

    }, {
      key: 'hide',
      value: function hide() {
        // console.log('hiding', this.$element.data('yeti-box'));
        var _this = this;
        this.template.stop().attr({
          'aria-hidden': true,
          'data-is-active': false
        }).fadeOut(this.options.fadeOutDuration, function () {
          _this.isActive = false;
          _this.isClick = false;
          if (_this.classChanged) {
            _this.template.removeClass(_this._getPositionClass(_this.template)).addClass(_this.options.positionClass);

            _this.usedPositions = [];
            _this.counter = 4;
            _this.classChanged = false;
          }
        });
        /**
         * fires when the tooltip is hidden
         * @event Tooltip#hide
         */
        this.$element.trigger('hide.zf.tooltip');
      }

      /**
       * adds event listeners for the tooltip and its anchor
       * TODO combine some of the listeners like focus and mouseenter, etc.
       * @private
       */

    }, {
      key: '_events',
      value: function _events() {
        var _this = this;
        var $template = this.template;
        var isFocus = false;

        if (!this.options.disableHover) {

          this.$element.on('mouseenter.zf.tooltip', function (e) {
            if (!_this.isActive) {
              _this.timeout = setTimeout(function () {
                _this.show();
              }, _this.options.hoverDelay);
            }
          }).on('mouseleave.zf.tooltip', function (e) {
            clearTimeout(_this.timeout);
            if (!isFocus || _this.isClick && !_this.options.clickOpen) {
              _this.hide();
            }
          });
        }

        if (this.options.clickOpen) {
          this.$element.on('mousedown.zf.tooltip', function (e) {
            e.stopImmediatePropagation();
            if (_this.isClick) {
              //_this.hide();
              // _this.isClick = false;
            } else {
              _this.isClick = true;
              if ((_this.options.disableHover || !_this.$element.attr('tabindex')) && !_this.isActive) {
                _this.show();
              }
            }
          });
        } else {
          this.$element.on('mousedown.zf.tooltip', function (e) {
            e.stopImmediatePropagation();
            _this.isClick = true;
          });
        }

        if (!this.options.disableForTouch) {
          this.$element.on('tap.zf.tooltip touchend.zf.tooltip', function (e) {
            _this.isActive ? _this.hide() : _this.show();
          });
        }

        this.$element.on({
          // 'toggle.zf.trigger': this.toggle.bind(this),
          // 'close.zf.trigger': this.hide.bind(this)
          'close.zf.trigger': this.hide.bind(this)
        });

        this.$element.on('focus.zf.tooltip', function (e) {
          isFocus = true;
          if (_this.isClick) {
            // If we're not showing open on clicks, we need to pretend a click-launched focus isn't
            // a real focus, otherwise on hover and come back we get bad behavior
            if (!_this.options.clickOpen) {
              isFocus = false;
            }
            return false;
          } else {
            _this.show();
          }
        }).on('focusout.zf.tooltip', function (e) {
          isFocus = false;
          _this.isClick = false;
          _this.hide();
        }).on('resizeme.zf.trigger', function () {
          if (_this.isActive) {
            _this._setPosition();
          }
        });
      }

      /**
       * adds a toggle method, in addition to the static show() & hide() functions
       * @function
       */

    }, {
      key: 'toggle',
      value: function toggle() {
        if (this.isActive) {
          this.hide();
        } else {
          this.show();
        }
      }

      /**
       * Destroys an instance of tooltip, removes template element from the view.
       * @function
       */

    }, {
      key: 'destroy',
      value: function destroy() {
        this.$element.attr('title', this.template.text()).off('.zf.trigger .zf.tootip')
        //  .removeClass('has-tip')
        .removeAttr('aria-describedby').removeAttr('data-yeti-box').removeAttr('data-toggle').removeAttr('data-resize');

        this.template.remove();

        Foundation.unregisterPlugin(this);
      }
    }]);

    return Tooltip;
  }();

  Tooltip.defaults = {
    disableForTouch: false,
    /**
     * Time, in ms, before a tooltip should open on hover.
     * @option
     * @example 200
     */
    hoverDelay: 200,
    /**
     * Time, in ms, a tooltip should take to fade into view.
     * @option
     * @example 150
     */
    fadeInDuration: 150,
    /**
     * Time, in ms, a tooltip should take to fade out of view.
     * @option
     * @example 150
     */
    fadeOutDuration: 150,
    /**
     * Disables hover events from opening the tooltip if set to true
     * @option
     * @example false
     */
    disableHover: false,
    /**
     * Optional addtional classes to apply to the tooltip template on init.
     * @option
     * @example 'my-cool-tip-class'
     */
    templateClasses: '',
    /**
     * Non-optional class added to tooltip templates. Foundation default is 'tooltip'.
     * @option
     * @example 'tooltip'
     */
    tooltipClass: 'tooltip',
    /**
     * Class applied to the tooltip anchor element.
     * @option
     * @example 'has-tip'
     */
    triggerClass: 'has-tip',
    /**
     * Minimum breakpoint size at which to open the tooltip.
     * @option
     * @example 'small'
     */
    showOn: 'small',
    /**
     * Custom template to be used to generate markup for tooltip.
     * @option
     * @example '&lt;div class="tooltip"&gt;&lt;/div&gt;'
     */
    template: '',
    /**
     * Text displayed in the tooltip template on open.
     * @option
     * @example 'Some cool space fact here.'
     */
    tipText: '',
    touchCloseText: 'Tap to close.',
    /**
     * Allows the tooltip to remain open if triggered with a click or touch event.
     * @option
     * @example true
     */
    clickOpen: true,
    /**
     * Additional positioning classes, set by the JS
     * @option
     * @example 'top'
     */
    positionClass: '',
    /**
     * Distance, in pixels, the template should push away from the anchor on the Y axis.
     * @option
     * @example 10
     */
    vOffset: 10,
    /**
     * Distance, in pixels, the template should push away from the anchor on the X axis, if aligned to a side.
     * @option
     * @example 12
     */
    hOffset: 12
  };

  /**
   * TODO utilize resize event trigger
   */

  // Window exports
  Foundation.plugin(Tooltip, 'Tooltip');
}(jQuery);
'use strict';

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };

/*
     _ _      _       _
 ___| (_) ___| | __  (_)___
/ __| | |/ __| |/ /  | / __|
\__ \ | | (__|   < _ | \__ \
|___/_|_|\___|_|\_(_)/ |___/
                   |__/

 Version: 1.6.0
  Author: Ken Wheeler
 Website: http://kenwheeler.github.io
    Docs: http://kenwheeler.github.io/slick
    Repo: http://github.com/kenwheeler/slick
  Issues: http://github.com/kenwheeler/slick/issues

 */
/* global window, document, define, jQuery, setInterval, clearInterval */
(function (factory) {
    'use strict';

    if (typeof define === 'function' && define.amd) {
        define(['jquery'], factory);
    } else if (typeof exports !== 'undefined') {
        module.exports = factory(require('jquery'));
    } else {
        factory(jQuery);
    }
})(function ($) {
    'use strict';

    var Slick = window.Slick || {};

    Slick = function () {

        var instanceUid = 0;

        function Slick(element, settings) {

            var _ = this,
                dataSettings;

            _.defaults = {
                accessibility: true,
                adaptiveHeight: false,
                appendArrows: $(element),
                appendDots: $(element),
                arrows: true,
                asNavFor: null,
                prevArrow: '<button type="button" data-role="none" class="slick-prev" aria-label="Previous" tabindex="0" role="button">Previous</button>',
                nextArrow: '<button type="button" data-role="none" class="slick-next" aria-label="Next" tabindex="0" role="button">Next</button>',
                autoplay: false,
                autoplaySpeed: 3000,
                centerMode: false,
                centerPadding: '50px',
                cssEase: 'ease',
                customPaging: function customPaging(slider, i) {
                    return $('<button type="button" data-role="none" role="button" tabindex="0" />').text(i + 1);
                },
                dots: false,
                dotsClass: 'slick-dots',
                draggable: true,
                easing: 'linear',
                edgeFriction: 0.35,
                fade: false,
                focusOnSelect: false,
                infinite: true,
                initialSlide: 0,
                lazyLoad: 'ondemand',
                mobileFirst: false,
                pauseOnHover: true,
                pauseOnFocus: true,
                pauseOnDotsHover: false,
                respondTo: 'window',
                responsive: null,
                rows: 1,
                rtl: false,
                slide: '',
                slidesPerRow: 1,
                slidesToShow: 1,
                slidesToScroll: 1,
                speed: 500,
                swipe: true,
                swipeToSlide: false,
                touchMove: true,
                touchThreshold: 5,
                useCSS: true,
                useTransform: true,
                variableWidth: false,
                vertical: false,
                verticalSwiping: false,
                waitForAnimate: true,
                zIndex: 1000
            };

            _.initials = {
                animating: false,
                dragging: false,
                autoPlayTimer: null,
                currentDirection: 0,
                currentLeft: null,
                currentSlide: 0,
                direction: 1,
                $dots: null,
                listWidth: null,
                listHeight: null,
                loadIndex: 0,
                $nextArrow: null,
                $prevArrow: null,
                slideCount: null,
                slideWidth: null,
                $slideTrack: null,
                $slides: null,
                sliding: false,
                slideOffset: 0,
                swipeLeft: null,
                $list: null,
                touchObject: {},
                transformsEnabled: false,
                unslicked: false
            };

            $.extend(_, _.initials);

            _.activeBreakpoint = null;
            _.animType = null;
            _.animProp = null;
            _.breakpoints = [];
            _.breakpointSettings = [];
            _.cssTransitions = false;
            _.focussed = false;
            _.interrupted = false;
            _.hidden = 'hidden';
            _.paused = true;
            _.positionProp = null;
            _.respondTo = null;
            _.rowCount = 1;
            _.shouldClick = true;
            _.$slider = $(element);
            _.$slidesCache = null;
            _.transformType = null;
            _.transitionType = null;
            _.visibilityChange = 'visibilitychange';
            _.windowWidth = 0;
            _.windowTimer = null;

            dataSettings = $(element).data('slick') || {};

            _.options = $.extend({}, _.defaults, settings, dataSettings);

            _.currentSlide = _.options.initialSlide;

            _.originalSettings = _.options;

            if (typeof document.mozHidden !== 'undefined') {
                _.hidden = 'mozHidden';
                _.visibilityChange = 'mozvisibilitychange';
            } else if (typeof document.webkitHidden !== 'undefined') {
                _.hidden = 'webkitHidden';
                _.visibilityChange = 'webkitvisibilitychange';
            }

            _.autoPlay = $.proxy(_.autoPlay, _);
            _.autoPlayClear = $.proxy(_.autoPlayClear, _);
            _.autoPlayIterator = $.proxy(_.autoPlayIterator, _);
            _.changeSlide = $.proxy(_.changeSlide, _);
            _.clickHandler = $.proxy(_.clickHandler, _);
            _.selectHandler = $.proxy(_.selectHandler, _);
            _.setPosition = $.proxy(_.setPosition, _);
            _.swipeHandler = $.proxy(_.swipeHandler, _);
            _.dragHandler = $.proxy(_.dragHandler, _);
            _.keyHandler = $.proxy(_.keyHandler, _);

            _.instanceUid = instanceUid++;

            // A simple way to check for HTML strings
            // Strict HTML recognition (must start with <)
            // Extracted from jQuery v1.11 source
            _.htmlExpr = /^(?:\s*(<[\w\W]+>)[^>]*)$/;

            _.registerBreakpoints();
            _.init(true);
        }

        return Slick;
    }();

    Slick.prototype.activateADA = function () {
        var _ = this;

        _.$slideTrack.find('.slick-active').attr({
            'aria-hidden': 'false'
        }).find('a, input, button, select').attr({
            'tabindex': '0'
        });
    };

    Slick.prototype.addSlide = Slick.prototype.slickAdd = function (markup, index, addBefore) {

        var _ = this;

        if (typeof index === 'boolean') {
            addBefore = index;
            index = null;
        } else if (index < 0 || index >= _.slideCount) {
            return false;
        }

        _.unload();

        if (typeof index === 'number') {
            if (index === 0 && _.$slides.length === 0) {
                $(markup).appendTo(_.$slideTrack);
            } else if (addBefore) {
                $(markup).insertBefore(_.$slides.eq(index));
            } else {
                $(markup).insertAfter(_.$slides.eq(index));
            }
        } else {
            if (addBefore === true) {
                $(markup).prependTo(_.$slideTrack);
            } else {
                $(markup).appendTo(_.$slideTrack);
            }
        }

        _.$slides = _.$slideTrack.children(this.options.slide);

        _.$slideTrack.children(this.options.slide).detach();

        _.$slideTrack.append(_.$slides);

        _.$slides.each(function (index, element) {
            $(element).attr('data-slick-index', index);
        });

        _.$slidesCache = _.$slides;

        _.reinit();
    };

    Slick.prototype.animateHeight = function () {
        var _ = this;
        if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
            var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
            _.$list.animate({
                height: targetHeight
            }, _.options.speed);
        }
    };

    Slick.prototype.animateSlide = function (targetLeft, callback) {

        var animProps = {},
            _ = this;

        _.animateHeight();

        if (_.options.rtl === true && _.options.vertical === false) {
            targetLeft = -targetLeft;
        }
        if (_.transformsEnabled === false) {
            if (_.options.vertical === false) {
                _.$slideTrack.animate({
                    left: targetLeft
                }, _.options.speed, _.options.easing, callback);
            } else {
                _.$slideTrack.animate({
                    top: targetLeft
                }, _.options.speed, _.options.easing, callback);
            }
        } else {

            if (_.cssTransitions === false) {
                if (_.options.rtl === true) {
                    _.currentLeft = -_.currentLeft;
                }
                $({
                    animStart: _.currentLeft
                }).animate({
                    animStart: targetLeft
                }, {
                    duration: _.options.speed,
                    easing: _.options.easing,
                    step: function step(now) {
                        now = Math.ceil(now);
                        if (_.options.vertical === false) {
                            animProps[_.animType] = 'translate(' + now + 'px, 0px)';
                            _.$slideTrack.css(animProps);
                        } else {
                            animProps[_.animType] = 'translate(0px,' + now + 'px)';
                            _.$slideTrack.css(animProps);
                        }
                    },
                    complete: function complete() {
                        if (callback) {
                            callback.call();
                        }
                    }
                });
            } else {

                _.applyTransition();
                targetLeft = Math.ceil(targetLeft);

                if (_.options.vertical === false) {
                    animProps[_.animType] = 'translate3d(' + targetLeft + 'px, 0px, 0px)';
                } else {
                    animProps[_.animType] = 'translate3d(0px,' + targetLeft + 'px, 0px)';
                }
                _.$slideTrack.css(animProps);

                if (callback) {
                    setTimeout(function () {

                        _.disableTransition();

                        callback.call();
                    }, _.options.speed);
                }
            }
        }
    };

    Slick.prototype.getNavTarget = function () {

        var _ = this,
            asNavFor = _.options.asNavFor;

        if (asNavFor && asNavFor !== null) {
            asNavFor = $(asNavFor).not(_.$slider);
        }

        return asNavFor;
    };

    Slick.prototype.asNavFor = function (index) {

        var _ = this,
            asNavFor = _.getNavTarget();

        if (asNavFor !== null && (typeof asNavFor === 'undefined' ? 'undefined' : _typeof(asNavFor)) === 'object') {
            asNavFor.each(function () {
                var target = $(this).slick('getSlick');
                if (!target.unslicked) {
                    target.slideHandler(index, true);
                }
            });
        }
    };

    Slick.prototype.applyTransition = function (slide) {

        var _ = this,
            transition = {};

        if (_.options.fade === false) {
            transition[_.transitionType] = _.transformType + ' ' + _.options.speed + 'ms ' + _.options.cssEase;
        } else {
            transition[_.transitionType] = 'opacity ' + _.options.speed + 'ms ' + _.options.cssEase;
        }

        if (_.options.fade === false) {
            _.$slideTrack.css(transition);
        } else {
            _.$slides.eq(slide).css(transition);
        }
    };

    Slick.prototype.autoPlay = function () {

        var _ = this;

        _.autoPlayClear();

        if (_.slideCount > _.options.slidesToShow) {
            _.autoPlayTimer = setInterval(_.autoPlayIterator, _.options.autoplaySpeed);
        }
    };

    Slick.prototype.autoPlayClear = function () {

        var _ = this;

        if (_.autoPlayTimer) {
            clearInterval(_.autoPlayTimer);
        }
    };

    Slick.prototype.autoPlayIterator = function () {

        var _ = this,
            slideTo = _.currentSlide + _.options.slidesToScroll;

        if (!_.paused && !_.interrupted && !_.focussed) {

            if (_.options.infinite === false) {

                if (_.direction === 1 && _.currentSlide + 1 === _.slideCount - 1) {
                    _.direction = 0;
                } else if (_.direction === 0) {

                    slideTo = _.currentSlide - _.options.slidesToScroll;

                    if (_.currentSlide - 1 === 0) {
                        _.direction = 1;
                    }
                }
            }

            _.slideHandler(slideTo);
        }
    };

    Slick.prototype.buildArrows = function () {

        var _ = this;

        if (_.options.arrows === true) {

            _.$prevArrow = $(_.options.prevArrow).addClass('slick-arrow');
            _.$nextArrow = $(_.options.nextArrow).addClass('slick-arrow');

            if (_.slideCount > _.options.slidesToShow) {

                _.$prevArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');
                _.$nextArrow.removeClass('slick-hidden').removeAttr('aria-hidden tabindex');

                if (_.htmlExpr.test(_.options.prevArrow)) {
                    _.$prevArrow.prependTo(_.options.appendArrows);
                }

                if (_.htmlExpr.test(_.options.nextArrow)) {
                    _.$nextArrow.appendTo(_.options.appendArrows);
                }

                if (_.options.infinite !== true) {
                    _.$prevArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
                }
            } else {

                _.$prevArrow.add(_.$nextArrow).addClass('slick-hidden').attr({
                    'aria-disabled': 'true',
                    'tabindex': '-1'
                });
            }
        }
    };

    Slick.prototype.buildDots = function () {

        var _ = this,
            i,
            dot;

        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {

            _.$slider.addClass('slick-dotted');

            dot = $('<ul />').addClass(_.options.dotsClass);

            for (i = 0; i <= _.getDotCount(); i += 1) {
                dot.append($('<li />').append(_.options.customPaging.call(this, _, i)));
            }

            _.$dots = dot.appendTo(_.options.appendDots);

            _.$dots.find('li').first().addClass('slick-active').attr('aria-hidden', 'false');
        }
    };

    Slick.prototype.buildOut = function () {

        var _ = this;

        _.$slides = _.$slider.children(_.options.slide + ':not(.slick-cloned)').addClass('slick-slide');

        _.slideCount = _.$slides.length;

        _.$slides.each(function (index, element) {
            $(element).attr('data-slick-index', index).data('originalStyling', $(element).attr('style') || '');
        });

        _.$slider.addClass('slick-slider');

        _.$slideTrack = _.slideCount === 0 ? $('<div class="slick-track"/>').appendTo(_.$slider) : _.$slides.wrapAll('<div class="slick-track"/>').parent();

        _.$list = _.$slideTrack.wrap('<div aria-live="polite" class="slick-list"/>').parent();
        _.$slideTrack.css('opacity', 0);

        if (_.options.centerMode === true || _.options.swipeToSlide === true) {
            _.options.slidesToScroll = 1;
        }

        $('img[data-lazy]', _.$slider).not('[src]').addClass('slick-loading');

        _.setupInfinite();

        _.buildArrows();

        _.buildDots();

        _.updateDots();

        _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);

        if (_.options.draggable === true) {
            _.$list.addClass('draggable');
        }
    };

    Slick.prototype.buildRows = function () {

        var _ = this,
            a,
            b,
            c,
            newSlides,
            numOfSlides,
            originalSlides,
            slidesPerSection;

        newSlides = document.createDocumentFragment();
        originalSlides = _.$slider.children();

        if (_.options.rows > 1) {

            slidesPerSection = _.options.slidesPerRow * _.options.rows;
            numOfSlides = Math.ceil(originalSlides.length / slidesPerSection);

            for (a = 0; a < numOfSlides; a++) {
                var slide = document.createElement('div');
                for (b = 0; b < _.options.rows; b++) {
                    var row = document.createElement('div');
                    for (c = 0; c < _.options.slidesPerRow; c++) {
                        var target = a * slidesPerSection + (b * _.options.slidesPerRow + c);
                        if (originalSlides.get(target)) {
                            row.appendChild(originalSlides.get(target));
                        }
                    }
                    slide.appendChild(row);
                }
                newSlides.appendChild(slide);
            }

            _.$slider.empty().append(newSlides);
            _.$slider.children().children().children().css({
                'width': 100 / _.options.slidesPerRow + '%',
                'display': 'inline-block'
            });
        }
    };

    Slick.prototype.checkResponsive = function (initial, forceUpdate) {

        var _ = this,
            breakpoint,
            targetBreakpoint,
            respondToWidth,
            triggerBreakpoint = false;
        var sliderWidth = _.$slider.width();
        var windowWidth = window.innerWidth || $(window).width();

        if (_.respondTo === 'window') {
            respondToWidth = windowWidth;
        } else if (_.respondTo === 'slider') {
            respondToWidth = sliderWidth;
        } else if (_.respondTo === 'min') {
            respondToWidth = Math.min(windowWidth, sliderWidth);
        }

        if (_.options.responsive && _.options.responsive.length && _.options.responsive !== null) {

            targetBreakpoint = null;

            for (breakpoint in _.breakpoints) {
                if (_.breakpoints.hasOwnProperty(breakpoint)) {
                    if (_.originalSettings.mobileFirst === false) {
                        if (respondToWidth < _.breakpoints[breakpoint]) {
                            targetBreakpoint = _.breakpoints[breakpoint];
                        }
                    } else {
                        if (respondToWidth > _.breakpoints[breakpoint]) {
                            targetBreakpoint = _.breakpoints[breakpoint];
                        }
                    }
                }
            }

            if (targetBreakpoint !== null) {
                if (_.activeBreakpoint !== null) {
                    if (targetBreakpoint !== _.activeBreakpoint || forceUpdate) {
                        _.activeBreakpoint = targetBreakpoint;
                        if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
                            _.unslick(targetBreakpoint);
                        } else {
                            _.options = $.extend({}, _.originalSettings, _.breakpointSettings[targetBreakpoint]);
                            if (initial === true) {
                                _.currentSlide = _.options.initialSlide;
                            }
                            _.refresh(initial);
                        }
                        triggerBreakpoint = targetBreakpoint;
                    }
                } else {
                    _.activeBreakpoint = targetBreakpoint;
                    if (_.breakpointSettings[targetBreakpoint] === 'unslick') {
                        _.unslick(targetBreakpoint);
                    } else {
                        _.options = $.extend({}, _.originalSettings, _.breakpointSettings[targetBreakpoint]);
                        if (initial === true) {
                            _.currentSlide = _.options.initialSlide;
                        }
                        _.refresh(initial);
                    }
                    triggerBreakpoint = targetBreakpoint;
                }
            } else {
                if (_.activeBreakpoint !== null) {
                    _.activeBreakpoint = null;
                    _.options = _.originalSettings;
                    if (initial === true) {
                        _.currentSlide = _.options.initialSlide;
                    }
                    _.refresh(initial);
                    triggerBreakpoint = targetBreakpoint;
                }
            }

            // only trigger breakpoints during an actual break. not on initialize.
            if (!initial && triggerBreakpoint !== false) {
                _.$slider.trigger('breakpoint', [_, triggerBreakpoint]);
            }
        }
    };

    Slick.prototype.changeSlide = function (event, dontAnimate) {

        var _ = this,
            $target = $(event.currentTarget),
            indexOffset,
            slideOffset,
            unevenOffset;

        // If target is a link, prevent default action.
        if ($target.is('a')) {
            event.preventDefault();
        }

        // If target is not the <li> element (ie: a child), find the <li>.
        if (!$target.is('li')) {
            $target = $target.closest('li');
        }

        unevenOffset = _.slideCount % _.options.slidesToScroll !== 0;
        indexOffset = unevenOffset ? 0 : (_.slideCount - _.currentSlide) % _.options.slidesToScroll;

        switch (event.data.message) {

            case 'previous':
                slideOffset = indexOffset === 0 ? _.options.slidesToScroll : _.options.slidesToShow - indexOffset;
                if (_.slideCount > _.options.slidesToShow) {
                    _.slideHandler(_.currentSlide - slideOffset, false, dontAnimate);
                }
                break;

            case 'next':
                slideOffset = indexOffset === 0 ? _.options.slidesToScroll : indexOffset;
                if (_.slideCount > _.options.slidesToShow) {
                    _.slideHandler(_.currentSlide + slideOffset, false, dontAnimate);
                }
                break;

            case 'index':
                var index = event.data.index === 0 ? 0 : event.data.index || $target.index() * _.options.slidesToScroll;

                _.slideHandler(_.checkNavigable(index), false, dontAnimate);
                $target.children().trigger('focus');
                break;

            default:
                return;
        }
    };

    Slick.prototype.checkNavigable = function (index) {

        var _ = this,
            navigables,
            prevNavigable;

        navigables = _.getNavigableIndexes();
        prevNavigable = 0;
        if (index > navigables[navigables.length - 1]) {
            index = navigables[navigables.length - 1];
        } else {
            for (var n in navigables) {
                if (index < navigables[n]) {
                    index = prevNavigable;
                    break;
                }
                prevNavigable = navigables[n];
            }
        }

        return index;
    };

    Slick.prototype.cleanUpEvents = function () {

        var _ = this;

        if (_.options.dots && _.$dots !== null) {

            $('li', _.$dots).off('click.slick', _.changeSlide).off('mouseenter.slick', $.proxy(_.interrupt, _, true)).off('mouseleave.slick', $.proxy(_.interrupt, _, false));
        }

        _.$slider.off('focus.slick blur.slick');

        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
            _.$prevArrow && _.$prevArrow.off('click.slick', _.changeSlide);
            _.$nextArrow && _.$nextArrow.off('click.slick', _.changeSlide);
        }

        _.$list.off('touchstart.slick mousedown.slick', _.swipeHandler);
        _.$list.off('touchmove.slick mousemove.slick', _.swipeHandler);
        _.$list.off('touchend.slick mouseup.slick', _.swipeHandler);
        _.$list.off('touchcancel.slick mouseleave.slick', _.swipeHandler);

        _.$list.off('click.slick', _.clickHandler);

        $(document).off(_.visibilityChange, _.visibility);

        _.cleanUpSlideEvents();

        if (_.options.accessibility === true) {
            _.$list.off('keydown.slick', _.keyHandler);
        }

        if (_.options.focusOnSelect === true) {
            $(_.$slideTrack).children().off('click.slick', _.selectHandler);
        }

        $(window).off('orientationchange.slick.slick-' + _.instanceUid, _.orientationChange);

        $(window).off('resize.slick.slick-' + _.instanceUid, _.resize);

        $('[draggable!=true]', _.$slideTrack).off('dragstart', _.preventDefault);

        $(window).off('load.slick.slick-' + _.instanceUid, _.setPosition);
        $(document).off('ready.slick.slick-' + _.instanceUid, _.setPosition);
    };

    Slick.prototype.cleanUpSlideEvents = function () {

        var _ = this;

        _.$list.off('mouseenter.slick', $.proxy(_.interrupt, _, true));
        _.$list.off('mouseleave.slick', $.proxy(_.interrupt, _, false));
    };

    Slick.prototype.cleanUpRows = function () {

        var _ = this,
            originalSlides;

        if (_.options.rows > 1) {
            originalSlides = _.$slides.children().children();
            originalSlides.removeAttr('style');
            _.$slider.empty().append(originalSlides);
        }
    };

    Slick.prototype.clickHandler = function (event) {

        var _ = this;

        if (_.shouldClick === false) {
            event.stopImmediatePropagation();
            event.stopPropagation();
            event.preventDefault();
        }
    };

    Slick.prototype.destroy = function (refresh) {

        var _ = this;

        _.autoPlayClear();

        _.touchObject = {};

        _.cleanUpEvents();

        $('.slick-cloned', _.$slider).detach();

        if (_.$dots) {
            _.$dots.remove();
        }

        if (_.$prevArrow && _.$prevArrow.length) {

            _.$prevArrow.removeClass('slick-disabled slick-arrow slick-hidden').removeAttr('aria-hidden aria-disabled tabindex').css('display', '');

            if (_.htmlExpr.test(_.options.prevArrow)) {
                _.$prevArrow.remove();
            }
        }

        if (_.$nextArrow && _.$nextArrow.length) {

            _.$nextArrow.removeClass('slick-disabled slick-arrow slick-hidden').removeAttr('aria-hidden aria-disabled tabindex').css('display', '');

            if (_.htmlExpr.test(_.options.nextArrow)) {
                _.$nextArrow.remove();
            }
        }

        if (_.$slides) {

            _.$slides.removeClass('slick-slide slick-active slick-center slick-visible slick-current').removeAttr('aria-hidden').removeAttr('data-slick-index').each(function () {
                $(this).attr('style', $(this).data('originalStyling'));
            });

            _.$slideTrack.children(this.options.slide).detach();

            _.$slideTrack.detach();

            _.$list.detach();

            _.$slider.append(_.$slides);
        }

        _.cleanUpRows();

        _.$slider.removeClass('slick-slider');
        _.$slider.removeClass('slick-initialized');
        _.$slider.removeClass('slick-dotted');

        _.unslicked = true;

        if (!refresh) {
            _.$slider.trigger('destroy', [_]);
        }
    };

    Slick.prototype.disableTransition = function (slide) {

        var _ = this,
            transition = {};

        transition[_.transitionType] = '';

        if (_.options.fade === false) {
            _.$slideTrack.css(transition);
        } else {
            _.$slides.eq(slide).css(transition);
        }
    };

    Slick.prototype.fadeSlide = function (slideIndex, callback) {

        var _ = this;

        if (_.cssTransitions === false) {

            _.$slides.eq(slideIndex).css({
                zIndex: _.options.zIndex
            });

            _.$slides.eq(slideIndex).animate({
                opacity: 1
            }, _.options.speed, _.options.easing, callback);
        } else {

            _.applyTransition(slideIndex);

            _.$slides.eq(slideIndex).css({
                opacity: 1,
                zIndex: _.options.zIndex
            });

            if (callback) {
                setTimeout(function () {

                    _.disableTransition(slideIndex);

                    callback.call();
                }, _.options.speed);
            }
        }
    };

    Slick.prototype.fadeSlideOut = function (slideIndex) {

        var _ = this;

        if (_.cssTransitions === false) {

            _.$slides.eq(slideIndex).animate({
                opacity: 0,
                zIndex: _.options.zIndex - 2
            }, _.options.speed, _.options.easing);
        } else {

            _.applyTransition(slideIndex);

            _.$slides.eq(slideIndex).css({
                opacity: 0,
                zIndex: _.options.zIndex - 2
            });
        }
    };

    Slick.prototype.filterSlides = Slick.prototype.slickFilter = function (filter) {

        var _ = this;

        if (filter !== null) {

            _.$slidesCache = _.$slides;

            _.unload();

            _.$slideTrack.children(this.options.slide).detach();

            _.$slidesCache.filter(filter).appendTo(_.$slideTrack);

            _.reinit();
        }
    };

    Slick.prototype.focusHandler = function () {

        var _ = this;

        _.$slider.off('focus.slick blur.slick').on('focus.slick blur.slick', '*:not(.slick-arrow)', function (event) {

            event.stopImmediatePropagation();
            var $sf = $(this);

            setTimeout(function () {

                if (_.options.pauseOnFocus) {
                    _.focussed = $sf.is(':focus');
                    _.autoPlay();
                }
            }, 0);
        });
    };

    Slick.prototype.getCurrent = Slick.prototype.slickCurrentSlide = function () {

        var _ = this;
        return _.currentSlide;
    };

    Slick.prototype.getDotCount = function () {

        var _ = this;

        var breakPoint = 0;
        var counter = 0;
        var pagerQty = 0;

        if (_.options.infinite === true) {
            while (breakPoint < _.slideCount) {
                ++pagerQty;
                breakPoint = counter + _.options.slidesToScroll;
                counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
            }
        } else if (_.options.centerMode === true) {
            pagerQty = _.slideCount;
        } else if (!_.options.asNavFor) {
            pagerQty = 1 + Math.ceil((_.slideCount - _.options.slidesToShow) / _.options.slidesToScroll);
        } else {
            while (breakPoint < _.slideCount) {
                ++pagerQty;
                breakPoint = counter + _.options.slidesToScroll;
                counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
            }
        }

        return pagerQty - 1;
    };

    Slick.prototype.getLeft = function (slideIndex) {

        var _ = this,
            targetLeft,
            verticalHeight,
            verticalOffset = 0,
            targetSlide;

        _.slideOffset = 0;
        verticalHeight = _.$slides.first().outerHeight(true);

        if (_.options.infinite === true) {
            if (_.slideCount > _.options.slidesToShow) {
                _.slideOffset = _.slideWidth * _.options.slidesToShow * -1;
                verticalOffset = verticalHeight * _.options.slidesToShow * -1;
            }
            if (_.slideCount % _.options.slidesToScroll !== 0) {
                if (slideIndex + _.options.slidesToScroll > _.slideCount && _.slideCount > _.options.slidesToShow) {
                    if (slideIndex > _.slideCount) {
                        _.slideOffset = (_.options.slidesToShow - (slideIndex - _.slideCount)) * _.slideWidth * -1;
                        verticalOffset = (_.options.slidesToShow - (slideIndex - _.slideCount)) * verticalHeight * -1;
                    } else {
                        _.slideOffset = _.slideCount % _.options.slidesToScroll * _.slideWidth * -1;
                        verticalOffset = _.slideCount % _.options.slidesToScroll * verticalHeight * -1;
                    }
                }
            }
        } else {
            if (slideIndex + _.options.slidesToShow > _.slideCount) {
                _.slideOffset = (slideIndex + _.options.slidesToShow - _.slideCount) * _.slideWidth;
                verticalOffset = (slideIndex + _.options.slidesToShow - _.slideCount) * verticalHeight;
            }
        }

        if (_.slideCount <= _.options.slidesToShow) {
            _.slideOffset = 0;
            verticalOffset = 0;
        }

        if (_.options.centerMode === true && _.options.infinite === true) {
            _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2) - _.slideWidth;
        } else if (_.options.centerMode === true) {
            _.slideOffset = 0;
            _.slideOffset += _.slideWidth * Math.floor(_.options.slidesToShow / 2);
        }

        if (_.options.vertical === false) {
            targetLeft = slideIndex * _.slideWidth * -1 + _.slideOffset;
        } else {
            targetLeft = slideIndex * verticalHeight * -1 + verticalOffset;
        }

        if (_.options.variableWidth === true) {

            if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
                targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
            } else {
                targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow);
            }

            if (_.options.rtl === true) {
                if (targetSlide[0]) {
                    targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
                } else {
                    targetLeft = 0;
                }
            } else {
                targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
            }

            if (_.options.centerMode === true) {
                if (_.slideCount <= _.options.slidesToShow || _.options.infinite === false) {
                    targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex);
                } else {
                    targetSlide = _.$slideTrack.children('.slick-slide').eq(slideIndex + _.options.slidesToShow + 1);
                }

                if (_.options.rtl === true) {
                    if (targetSlide[0]) {
                        targetLeft = (_.$slideTrack.width() - targetSlide[0].offsetLeft - targetSlide.width()) * -1;
                    } else {
                        targetLeft = 0;
                    }
                } else {
                    targetLeft = targetSlide[0] ? targetSlide[0].offsetLeft * -1 : 0;
                }

                targetLeft += (_.$list.width() - targetSlide.outerWidth()) / 2;
            }
        }

        return targetLeft;
    };

    Slick.prototype.getOption = Slick.prototype.slickGetOption = function (option) {

        var _ = this;

        return _.options[option];
    };

    Slick.prototype.getNavigableIndexes = function () {

        var _ = this,
            breakPoint = 0,
            counter = 0,
            indexes = [],
            max;

        if (_.options.infinite === false) {
            max = _.slideCount;
        } else {
            breakPoint = _.options.slidesToScroll * -1;
            counter = _.options.slidesToScroll * -1;
            max = _.slideCount * 2;
        }

        while (breakPoint < max) {
            indexes.push(breakPoint);
            breakPoint = counter + _.options.slidesToScroll;
            counter += _.options.slidesToScroll <= _.options.slidesToShow ? _.options.slidesToScroll : _.options.slidesToShow;
        }

        return indexes;
    };

    Slick.prototype.getSlick = function () {

        return this;
    };

    Slick.prototype.getSlideCount = function () {

        var _ = this,
            slidesTraversed,
            swipedSlide,
            centerOffset;

        centerOffset = _.options.centerMode === true ? _.slideWidth * Math.floor(_.options.slidesToShow / 2) : 0;

        if (_.options.swipeToSlide === true) {
            _.$slideTrack.find('.slick-slide').each(function (index, slide) {
                if (slide.offsetLeft - centerOffset + $(slide).outerWidth() / 2 > _.swipeLeft * -1) {
                    swipedSlide = slide;
                    return false;
                }
            });

            slidesTraversed = Math.abs($(swipedSlide).attr('data-slick-index') - _.currentSlide) || 1;

            return slidesTraversed;
        } else {
            return _.options.slidesToScroll;
        }
    };

    Slick.prototype.goTo = Slick.prototype.slickGoTo = function (slide, dontAnimate) {

        var _ = this;

        _.changeSlide({
            data: {
                message: 'index',
                index: parseInt(slide)
            }
        }, dontAnimate);
    };

    Slick.prototype.init = function (creation) {

        var _ = this;

        if (!$(_.$slider).hasClass('slick-initialized')) {

            $(_.$slider).addClass('slick-initialized');

            _.buildRows();
            _.buildOut();
            _.setProps();
            _.startLoad();
            _.loadSlider();
            _.initializeEvents();
            _.updateArrows();
            _.updateDots();
            _.checkResponsive(true);
            _.focusHandler();
        }

        if (creation) {
            _.$slider.trigger('init', [_]);
        }

        if (_.options.accessibility === true) {
            _.initADA();
        }

        if (_.options.autoplay) {

            _.paused = false;
            _.autoPlay();
        }
    };

    Slick.prototype.initADA = function () {
        var _ = this;
        _.$slides.add(_.$slideTrack.find('.slick-cloned')).attr({
            'aria-hidden': 'true',
            'tabindex': '-1'
        }).find('a, input, button, select').attr({
            'tabindex': '-1'
        });

        _.$slideTrack.attr('role', 'listbox');

        _.$slides.not(_.$slideTrack.find('.slick-cloned')).each(function (i) {
            $(this).attr({
                'role': 'option',
                'aria-describedby': 'slick-slide' + _.instanceUid + i + ''
            });
        });

        if (_.$dots !== null) {
            _.$dots.attr('role', 'tablist').find('li').each(function (i) {
                $(this).attr({
                    'role': 'presentation',
                    'aria-selected': 'false',
                    'aria-controls': 'navigation' + _.instanceUid + i + '',
                    'id': 'slick-slide' + _.instanceUid + i + ''
                });
            }).first().attr('aria-selected', 'true').end().find('button').attr('role', 'button').end().closest('div').attr('role', 'toolbar');
        }
        _.activateADA();
    };

    Slick.prototype.initArrowEvents = function () {

        var _ = this;

        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {
            _.$prevArrow.off('click.slick').on('click.slick', {
                message: 'previous'
            }, _.changeSlide);
            _.$nextArrow.off('click.slick').on('click.slick', {
                message: 'next'
            }, _.changeSlide);
        }
    };

    Slick.prototype.initDotEvents = function () {

        var _ = this;

        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {
            $('li', _.$dots).on('click.slick', {
                message: 'index'
            }, _.changeSlide);
        }

        if (_.options.dots === true && _.options.pauseOnDotsHover === true) {

            $('li', _.$dots).on('mouseenter.slick', $.proxy(_.interrupt, _, true)).on('mouseleave.slick', $.proxy(_.interrupt, _, false));
        }
    };

    Slick.prototype.initSlideEvents = function () {

        var _ = this;

        if (_.options.pauseOnHover) {

            _.$list.on('mouseenter.slick', $.proxy(_.interrupt, _, true));
            _.$list.on('mouseleave.slick', $.proxy(_.interrupt, _, false));
        }
    };

    Slick.prototype.initializeEvents = function () {

        var _ = this;

        _.initArrowEvents();

        _.initDotEvents();
        _.initSlideEvents();

        _.$list.on('touchstart.slick mousedown.slick', {
            action: 'start'
        }, _.swipeHandler);
        _.$list.on('touchmove.slick mousemove.slick', {
            action: 'move'
        }, _.swipeHandler);
        _.$list.on('touchend.slick mouseup.slick', {
            action: 'end'
        }, _.swipeHandler);
        _.$list.on('touchcancel.slick mouseleave.slick', {
            action: 'end'
        }, _.swipeHandler);

        _.$list.on('click.slick', _.clickHandler);

        $(document).on(_.visibilityChange, $.proxy(_.visibility, _));

        if (_.options.accessibility === true) {
            _.$list.on('keydown.slick', _.keyHandler);
        }

        if (_.options.focusOnSelect === true) {
            $(_.$slideTrack).children().on('click.slick', _.selectHandler);
        }

        $(window).on('orientationchange.slick.slick-' + _.instanceUid, $.proxy(_.orientationChange, _));

        $(window).on('resize.slick.slick-' + _.instanceUid, $.proxy(_.resize, _));

        $('[draggable!=true]', _.$slideTrack).on('dragstart', _.preventDefault);

        $(window).on('load.slick.slick-' + _.instanceUid, _.setPosition);
        $(document).on('ready.slick.slick-' + _.instanceUid, _.setPosition);
    };

    Slick.prototype.initUI = function () {

        var _ = this;

        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {

            _.$prevArrow.show();
            _.$nextArrow.show();
        }

        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {

            _.$dots.show();
        }
    };

    Slick.prototype.keyHandler = function (event) {

        var _ = this;
        //Dont slide if the cursor is inside the form fields and arrow keys are pressed
        if (!event.target.tagName.match('TEXTAREA|INPUT|SELECT')) {
            if (event.keyCode === 37 && _.options.accessibility === true) {
                _.changeSlide({
                    data: {
                        message: _.options.rtl === true ? 'next' : 'previous'
                    }
                });
            } else if (event.keyCode === 39 && _.options.accessibility === true) {
                _.changeSlide({
                    data: {
                        message: _.options.rtl === true ? 'previous' : 'next'
                    }
                });
            }
        }
    };

    Slick.prototype.lazyLoad = function () {

        var _ = this,
            loadRange,
            cloneRange,
            rangeStart,
            rangeEnd;

        function loadImages(imagesScope) {

            $('img[data-lazy]', imagesScope).each(function () {

                var image = $(this),
                    imageSource = $(this).attr('data-lazy'),
                    imageToLoad = document.createElement('img');

                imageToLoad.onload = function () {

                    image.animate({ opacity: 0 }, 100, function () {
                        image.attr('src', imageSource).animate({ opacity: 1 }, 200, function () {
                            image.removeAttr('data-lazy').removeClass('slick-loading');
                        });
                        _.$slider.trigger('lazyLoaded', [_, image, imageSource]);
                    });
                };

                imageToLoad.onerror = function () {

                    image.removeAttr('data-lazy').removeClass('slick-loading').addClass('slick-lazyload-error');

                    _.$slider.trigger('lazyLoadError', [_, image, imageSource]);
                };

                imageToLoad.src = imageSource;
            });
        }

        if (_.options.centerMode === true) {
            if (_.options.infinite === true) {
                rangeStart = _.currentSlide + (_.options.slidesToShow / 2 + 1);
                rangeEnd = rangeStart + _.options.slidesToShow + 2;
            } else {
                rangeStart = Math.max(0, _.currentSlide - (_.options.slidesToShow / 2 + 1));
                rangeEnd = 2 + (_.options.slidesToShow / 2 + 1) + _.currentSlide;
            }
        } else {
            rangeStart = _.options.infinite ? _.options.slidesToShow + _.currentSlide : _.currentSlide;
            rangeEnd = Math.ceil(rangeStart + _.options.slidesToShow);
            if (_.options.fade === true) {
                if (rangeStart > 0) rangeStart--;
                if (rangeEnd <= _.slideCount) rangeEnd++;
            }
        }

        loadRange = _.$slider.find('.slick-slide').slice(rangeStart, rangeEnd);
        loadImages(loadRange);

        if (_.slideCount <= _.options.slidesToShow) {
            cloneRange = _.$slider.find('.slick-slide');
            loadImages(cloneRange);
        } else if (_.currentSlide >= _.slideCount - _.options.slidesToShow) {
            cloneRange = _.$slider.find('.slick-cloned').slice(0, _.options.slidesToShow);
            loadImages(cloneRange);
        } else if (_.currentSlide === 0) {
            cloneRange = _.$slider.find('.slick-cloned').slice(_.options.slidesToShow * -1);
            loadImages(cloneRange);
        }
    };

    Slick.prototype.loadSlider = function () {

        var _ = this;

        _.setPosition();

        _.$slideTrack.css({
            opacity: 1
        });

        _.$slider.removeClass('slick-loading');

        _.initUI();

        if (_.options.lazyLoad === 'progressive') {
            _.progressiveLazyLoad();
        }
    };

    Slick.prototype.next = Slick.prototype.slickNext = function () {

        var _ = this;

        _.changeSlide({
            data: {
                message: 'next'
            }
        });
    };

    Slick.prototype.orientationChange = function () {

        var _ = this;

        _.checkResponsive();
        _.setPosition();
    };

    Slick.prototype.pause = Slick.prototype.slickPause = function () {

        var _ = this;

        _.autoPlayClear();
        _.paused = true;
    };

    Slick.prototype.play = Slick.prototype.slickPlay = function () {

        var _ = this;

        _.autoPlay();
        _.options.autoplay = true;
        _.paused = false;
        _.focussed = false;
        _.interrupted = false;
    };

    Slick.prototype.postSlide = function (index) {

        var _ = this;

        if (!_.unslicked) {

            _.$slider.trigger('afterChange', [_, index]);

            _.animating = false;

            _.setPosition();

            _.swipeLeft = null;

            if (_.options.autoplay) {
                _.autoPlay();
            }

            if (_.options.accessibility === true) {
                _.initADA();
            }
        }
    };

    Slick.prototype.prev = Slick.prototype.slickPrev = function () {

        var _ = this;

        _.changeSlide({
            data: {
                message: 'previous'
            }
        });
    };

    Slick.prototype.preventDefault = function (event) {

        event.preventDefault();
    };

    Slick.prototype.progressiveLazyLoad = function (tryCount) {

        tryCount = tryCount || 1;

        var _ = this,
            $imgsToLoad = $('img[data-lazy]', _.$slider),
            image,
            imageSource,
            imageToLoad;

        if ($imgsToLoad.length) {

            image = $imgsToLoad.first();
            imageSource = image.attr('data-lazy');
            imageToLoad = document.createElement('img');

            imageToLoad.onload = function () {

                image.attr('src', imageSource).removeAttr('data-lazy').removeClass('slick-loading');

                if (_.options.adaptiveHeight === true) {
                    _.setPosition();
                }

                _.$slider.trigger('lazyLoaded', [_, image, imageSource]);
                _.progressiveLazyLoad();
            };

            imageToLoad.onerror = function () {

                if (tryCount < 3) {

                    /**
                     * try to load the image 3 times,
                     * leave a slight delay so we don't get
                     * servers blocking the request.
                     */
                    setTimeout(function () {
                        _.progressiveLazyLoad(tryCount + 1);
                    }, 500);
                } else {

                    image.removeAttr('data-lazy').removeClass('slick-loading').addClass('slick-lazyload-error');

                    _.$slider.trigger('lazyLoadError', [_, image, imageSource]);

                    _.progressiveLazyLoad();
                }
            };

            imageToLoad.src = imageSource;
        } else {

            _.$slider.trigger('allImagesLoaded', [_]);
        }
    };

    Slick.prototype.refresh = function (initializing) {

        var _ = this,
            currentSlide,
            lastVisibleIndex;

        lastVisibleIndex = _.slideCount - _.options.slidesToShow;

        // in non-infinite sliders, we don't want to go past the
        // last visible index.
        if (!_.options.infinite && _.currentSlide > lastVisibleIndex) {
            _.currentSlide = lastVisibleIndex;
        }

        // if less slides than to show, go to start.
        if (_.slideCount <= _.options.slidesToShow) {
            _.currentSlide = 0;
        }

        currentSlide = _.currentSlide;

        _.destroy(true);

        $.extend(_, _.initials, { currentSlide: currentSlide });

        _.init();

        if (!initializing) {

            _.changeSlide({
                data: {
                    message: 'index',
                    index: currentSlide
                }
            }, false);
        }
    };

    Slick.prototype.registerBreakpoints = function () {

        var _ = this,
            breakpoint,
            currentBreakpoint,
            l,
            responsiveSettings = _.options.responsive || null;

        if ($.type(responsiveSettings) === 'array' && responsiveSettings.length) {

            _.respondTo = _.options.respondTo || 'window';

            for (breakpoint in responsiveSettings) {

                l = _.breakpoints.length - 1;
                currentBreakpoint = responsiveSettings[breakpoint].breakpoint;

                if (responsiveSettings.hasOwnProperty(breakpoint)) {

                    // loop through the breakpoints and cut out any existing
                    // ones with the same breakpoint number, we don't want dupes.
                    while (l >= 0) {
                        if (_.breakpoints[l] && _.breakpoints[l] === currentBreakpoint) {
                            _.breakpoints.splice(l, 1);
                        }
                        l--;
                    }

                    _.breakpoints.push(currentBreakpoint);
                    _.breakpointSettings[currentBreakpoint] = responsiveSettings[breakpoint].settings;
                }
            }

            _.breakpoints.sort(function (a, b) {
                return _.options.mobileFirst ? a - b : b - a;
            });
        }
    };

    Slick.prototype.reinit = function () {

        var _ = this;

        _.$slides = _.$slideTrack.children(_.options.slide).addClass('slick-slide');

        _.slideCount = _.$slides.length;

        if (_.currentSlide >= _.slideCount && _.currentSlide !== 0) {
            _.currentSlide = _.currentSlide - _.options.slidesToScroll;
        }

        if (_.slideCount <= _.options.slidesToShow) {
            _.currentSlide = 0;
        }

        _.registerBreakpoints();

        _.setProps();
        _.setupInfinite();
        _.buildArrows();
        _.updateArrows();
        _.initArrowEvents();
        _.buildDots();
        _.updateDots();
        _.initDotEvents();
        _.cleanUpSlideEvents();
        _.initSlideEvents();

        _.checkResponsive(false, true);

        if (_.options.focusOnSelect === true) {
            $(_.$slideTrack).children().on('click.slick', _.selectHandler);
        }

        _.setSlideClasses(typeof _.currentSlide === 'number' ? _.currentSlide : 0);

        _.setPosition();
        _.focusHandler();

        _.paused = !_.options.autoplay;
        _.autoPlay();

        _.$slider.trigger('reInit', [_]);
    };

    Slick.prototype.resize = function () {

        var _ = this;

        if ($(window).width() !== _.windowWidth) {
            clearTimeout(_.windowDelay);
            _.windowDelay = window.setTimeout(function () {
                _.windowWidth = $(window).width();
                _.checkResponsive();
                if (!_.unslicked) {
                    _.setPosition();
                }
            }, 50);
        }
    };

    Slick.prototype.removeSlide = Slick.prototype.slickRemove = function (index, removeBefore, removeAll) {

        var _ = this;

        if (typeof index === 'boolean') {
            removeBefore = index;
            index = removeBefore === true ? 0 : _.slideCount - 1;
        } else {
            index = removeBefore === true ? --index : index;
        }

        if (_.slideCount < 1 || index < 0 || index > _.slideCount - 1) {
            return false;
        }

        _.unload();

        if (removeAll === true) {
            _.$slideTrack.children().remove();
        } else {
            _.$slideTrack.children(this.options.slide).eq(index).remove();
        }

        _.$slides = _.$slideTrack.children(this.options.slide);

        _.$slideTrack.children(this.options.slide).detach();

        _.$slideTrack.append(_.$slides);

        _.$slidesCache = _.$slides;

        _.reinit();
    };

    Slick.prototype.setCSS = function (position) {

        var _ = this,
            positionProps = {},
            x,
            y;

        if (_.options.rtl === true) {
            position = -position;
        }
        x = _.positionProp == 'left' ? Math.ceil(position) + 'px' : '0px';
        y = _.positionProp == 'top' ? Math.ceil(position) + 'px' : '0px';

        positionProps[_.positionProp] = position;

        if (_.transformsEnabled === false) {
            _.$slideTrack.css(positionProps);
        } else {
            positionProps = {};
            if (_.cssTransitions === false) {
                positionProps[_.animType] = 'translate(' + x + ', ' + y + ')';
                _.$slideTrack.css(positionProps);
            } else {
                positionProps[_.animType] = 'translate3d(' + x + ', ' + y + ', 0px)';
                _.$slideTrack.css(positionProps);
            }
        }
    };

    Slick.prototype.setDimensions = function () {

        var _ = this;

        if (_.options.vertical === false) {
            if (_.options.centerMode === true) {
                _.$list.css({
                    padding: '0px ' + _.options.centerPadding
                });
            }
        } else {
            _.$list.height(_.$slides.first().outerHeight(true) * _.options.slidesToShow);
            if (_.options.centerMode === true) {
                _.$list.css({
                    padding: _.options.centerPadding + ' 0px'
                });
            }
        }

        _.listWidth = _.$list.width();
        _.listHeight = _.$list.height();

        if (_.options.vertical === false && _.options.variableWidth === false) {
            _.slideWidth = Math.ceil(_.listWidth / _.options.slidesToShow);
            _.$slideTrack.width(Math.ceil(_.slideWidth * _.$slideTrack.children('.slick-slide').length));
        } else if (_.options.variableWidth === true) {
            _.$slideTrack.width(5000 * _.slideCount);
        } else {
            _.slideWidth = Math.ceil(_.listWidth);
            _.$slideTrack.height(Math.ceil(_.$slides.first().outerHeight(true) * _.$slideTrack.children('.slick-slide').length));
        }

        var offset = _.$slides.first().outerWidth(true) - _.$slides.first().width();
        if (_.options.variableWidth === false) _.$slideTrack.children('.slick-slide').width(_.slideWidth - offset);
    };

    Slick.prototype.setFade = function () {

        var _ = this,
            targetLeft;

        _.$slides.each(function (index, element) {
            targetLeft = _.slideWidth * index * -1;
            if (_.options.rtl === true) {
                $(element).css({
                    position: 'relative',
                    right: targetLeft,
                    top: 0,
                    zIndex: _.options.zIndex - 2,
                    opacity: 0
                });
            } else {
                $(element).css({
                    position: 'relative',
                    left: targetLeft,
                    top: 0,
                    zIndex: _.options.zIndex - 2,
                    opacity: 0
                });
            }
        });

        _.$slides.eq(_.currentSlide).css({
            zIndex: _.options.zIndex - 1,
            opacity: 1
        });
    };

    Slick.prototype.setHeight = function () {

        var _ = this;

        if (_.options.slidesToShow === 1 && _.options.adaptiveHeight === true && _.options.vertical === false) {
            var targetHeight = _.$slides.eq(_.currentSlide).outerHeight(true);
            _.$list.css('height', targetHeight);
        }
    };

    Slick.prototype.setOption = Slick.prototype.slickSetOption = function () {

        /**
         * accepts arguments in format of:
         *
         *  - for changing a single option's value:
         *     .slick("setOption", option, value, refresh )
         *
         *  - for changing a set of responsive options:
         *     .slick("setOption", 'responsive', [{}, ...], refresh )
         *
         *  - for updating multiple values at once (not responsive)
         *     .slick("setOption", { 'option': value, ... }, refresh )
         */

        var _ = this,
            l,
            item,
            option,
            value,
            refresh = false,
            type;

        if ($.type(arguments[0]) === 'object') {

            option = arguments[0];
            refresh = arguments[1];
            type = 'multiple';
        } else if ($.type(arguments[0]) === 'string') {

            option = arguments[0];
            value = arguments[1];
            refresh = arguments[2];

            if (arguments[0] === 'responsive' && $.type(arguments[1]) === 'array') {

                type = 'responsive';
            } else if (typeof arguments[1] !== 'undefined') {

                type = 'single';
            }
        }

        if (type === 'single') {

            _.options[option] = value;
        } else if (type === 'multiple') {

            $.each(option, function (opt, val) {

                _.options[opt] = val;
            });
        } else if (type === 'responsive') {

            for (item in value) {

                if ($.type(_.options.responsive) !== 'array') {

                    _.options.responsive = [value[item]];
                } else {

                    l = _.options.responsive.length - 1;

                    // loop through the responsive object and splice out duplicates.
                    while (l >= 0) {

                        if (_.options.responsive[l].breakpoint === value[item].breakpoint) {

                            _.options.responsive.splice(l, 1);
                        }

                        l--;
                    }

                    _.options.responsive.push(value[item]);
                }
            }
        }

        if (refresh) {

            _.unload();
            _.reinit();
        }
    };

    Slick.prototype.setPosition = function () {

        var _ = this;

        _.setDimensions();

        _.setHeight();

        if (_.options.fade === false) {
            _.setCSS(_.getLeft(_.currentSlide));
        } else {
            _.setFade();
        }

        _.$slider.trigger('setPosition', [_]);
    };

    Slick.prototype.setProps = function () {

        var _ = this,
            bodyStyle = document.body.style;

        _.positionProp = _.options.vertical === true ? 'top' : 'left';

        if (_.positionProp === 'top') {
            _.$slider.addClass('slick-vertical');
        } else {
            _.$slider.removeClass('slick-vertical');
        }

        if (bodyStyle.WebkitTransition !== undefined || bodyStyle.MozTransition !== undefined || bodyStyle.msTransition !== undefined) {
            if (_.options.useCSS === true) {
                _.cssTransitions = true;
            }
        }

        if (_.options.fade) {
            if (typeof _.options.zIndex === 'number') {
                if (_.options.zIndex < 3) {
                    _.options.zIndex = 3;
                }
            } else {
                _.options.zIndex = _.defaults.zIndex;
            }
        }

        if (bodyStyle.OTransform !== undefined) {
            _.animType = 'OTransform';
            _.transformType = '-o-transform';
            _.transitionType = 'OTransition';
            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
        }
        if (bodyStyle.MozTransform !== undefined) {
            _.animType = 'MozTransform';
            _.transformType = '-moz-transform';
            _.transitionType = 'MozTransition';
            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.MozPerspective === undefined) _.animType = false;
        }
        if (bodyStyle.webkitTransform !== undefined) {
            _.animType = 'webkitTransform';
            _.transformType = '-webkit-transform';
            _.transitionType = 'webkitTransition';
            if (bodyStyle.perspectiveProperty === undefined && bodyStyle.webkitPerspective === undefined) _.animType = false;
        }
        if (bodyStyle.msTransform !== undefined) {
            _.animType = 'msTransform';
            _.transformType = '-ms-transform';
            _.transitionType = 'msTransition';
            if (bodyStyle.msTransform === undefined) _.animType = false;
        }
        if (bodyStyle.transform !== undefined && _.animType !== false) {
            _.animType = 'transform';
            _.transformType = 'transform';
            _.transitionType = 'transition';
        }
        _.transformsEnabled = _.options.useTransform && _.animType !== null && _.animType !== false;
    };

    Slick.prototype.setSlideClasses = function (index) {

        var _ = this,
            centerOffset,
            allSlides,
            indexOffset,
            remainder;

        allSlides = _.$slider.find('.slick-slide').removeClass('slick-active slick-center slick-current').attr('aria-hidden', 'true');

        _.$slides.eq(index).addClass('slick-current');

        if (_.options.centerMode === true) {

            centerOffset = Math.floor(_.options.slidesToShow / 2);

            if (_.options.infinite === true) {

                if (index >= centerOffset && index <= _.slideCount - 1 - centerOffset) {

                    _.$slides.slice(index - centerOffset, index + centerOffset + 1).addClass('slick-active').attr('aria-hidden', 'false');
                } else {

                    indexOffset = _.options.slidesToShow + index;
                    allSlides.slice(indexOffset - centerOffset + 1, indexOffset + centerOffset + 2).addClass('slick-active').attr('aria-hidden', 'false');
                }

                if (index === 0) {

                    allSlides.eq(allSlides.length - 1 - _.options.slidesToShow).addClass('slick-center');
                } else if (index === _.slideCount - 1) {

                    allSlides.eq(_.options.slidesToShow).addClass('slick-center');
                }
            }

            _.$slides.eq(index).addClass('slick-center');
        } else {

            if (index >= 0 && index <= _.slideCount - _.options.slidesToShow) {

                _.$slides.slice(index, index + _.options.slidesToShow).addClass('slick-active').attr('aria-hidden', 'false');
            } else if (allSlides.length <= _.options.slidesToShow) {

                allSlides.addClass('slick-active').attr('aria-hidden', 'false');
            } else {

                remainder = _.slideCount % _.options.slidesToShow;
                indexOffset = _.options.infinite === true ? _.options.slidesToShow + index : index;

                if (_.options.slidesToShow == _.options.slidesToScroll && _.slideCount - index < _.options.slidesToShow) {

                    allSlides.slice(indexOffset - (_.options.slidesToShow - remainder), indexOffset + remainder).addClass('slick-active').attr('aria-hidden', 'false');
                } else {

                    allSlides.slice(indexOffset, indexOffset + _.options.slidesToShow).addClass('slick-active').attr('aria-hidden', 'false');
                }
            }
        }

        if (_.options.lazyLoad === 'ondemand') {
            _.lazyLoad();
        }
    };

    Slick.prototype.setupInfinite = function () {

        var _ = this,
            i,
            slideIndex,
            infiniteCount;

        if (_.options.fade === true) {
            _.options.centerMode = false;
        }

        if (_.options.infinite === true && _.options.fade === false) {

            slideIndex = null;

            if (_.slideCount > _.options.slidesToShow) {

                if (_.options.centerMode === true) {
                    infiniteCount = _.options.slidesToShow + 1;
                } else {
                    infiniteCount = _.options.slidesToShow;
                }

                for (i = _.slideCount; i > _.slideCount - infiniteCount; i -= 1) {
                    slideIndex = i - 1;
                    $(_.$slides[slideIndex]).clone(true).attr('id', '').attr('data-slick-index', slideIndex - _.slideCount).prependTo(_.$slideTrack).addClass('slick-cloned');
                }
                for (i = 0; i < infiniteCount; i += 1) {
                    slideIndex = i;
                    $(_.$slides[slideIndex]).clone(true).attr('id', '').attr('data-slick-index', slideIndex + _.slideCount).appendTo(_.$slideTrack).addClass('slick-cloned');
                }
                _.$slideTrack.find('.slick-cloned').find('[id]').each(function () {
                    $(this).attr('id', '');
                });
            }
        }
    };

    Slick.prototype.interrupt = function (toggle) {

        var _ = this;

        if (!toggle) {
            _.autoPlay();
        }
        _.interrupted = toggle;
    };

    Slick.prototype.selectHandler = function (event) {

        var _ = this;

        var targetElement = $(event.target).is('.slick-slide') ? $(event.target) : $(event.target).parents('.slick-slide');

        var index = parseInt(targetElement.attr('data-slick-index'));

        if (!index) index = 0;

        if (_.slideCount <= _.options.slidesToShow) {

            _.setSlideClasses(index);
            _.asNavFor(index);
            return;
        }

        _.slideHandler(index);
    };

    Slick.prototype.slideHandler = function (index, sync, dontAnimate) {

        var targetSlide,
            animSlide,
            oldSlide,
            slideLeft,
            targetLeft = null,
            _ = this,
            navTarget;

        sync = sync || false;

        if (_.animating === true && _.options.waitForAnimate === true) {
            return;
        }

        if (_.options.fade === true && _.currentSlide === index) {
            return;
        }

        if (_.slideCount <= _.options.slidesToShow) {
            return;
        }

        if (sync === false) {
            _.asNavFor(index);
        }

        targetSlide = index;
        targetLeft = _.getLeft(targetSlide);
        slideLeft = _.getLeft(_.currentSlide);

        _.currentLeft = _.swipeLeft === null ? slideLeft : _.swipeLeft;

        if (_.options.infinite === false && _.options.centerMode === false && (index < 0 || index > _.getDotCount() * _.options.slidesToScroll)) {
            if (_.options.fade === false) {
                targetSlide = _.currentSlide;
                if (dontAnimate !== true) {
                    _.animateSlide(slideLeft, function () {
                        _.postSlide(targetSlide);
                    });
                } else {
                    _.postSlide(targetSlide);
                }
            }
            return;
        } else if (_.options.infinite === false && _.options.centerMode === true && (index < 0 || index > _.slideCount - _.options.slidesToScroll)) {
            if (_.options.fade === false) {
                targetSlide = _.currentSlide;
                if (dontAnimate !== true) {
                    _.animateSlide(slideLeft, function () {
                        _.postSlide(targetSlide);
                    });
                } else {
                    _.postSlide(targetSlide);
                }
            }
            return;
        }

        if (_.options.autoplay) {
            clearInterval(_.autoPlayTimer);
        }

        if (targetSlide < 0) {
            if (_.slideCount % _.options.slidesToScroll !== 0) {
                animSlide = _.slideCount - _.slideCount % _.options.slidesToScroll;
            } else {
                animSlide = _.slideCount + targetSlide;
            }
        } else if (targetSlide >= _.slideCount) {
            if (_.slideCount % _.options.slidesToScroll !== 0) {
                animSlide = 0;
            } else {
                animSlide = targetSlide - _.slideCount;
            }
        } else {
            animSlide = targetSlide;
        }

        _.animating = true;

        _.$slider.trigger('beforeChange', [_, _.currentSlide, animSlide]);

        oldSlide = _.currentSlide;
        _.currentSlide = animSlide;

        _.setSlideClasses(_.currentSlide);

        if (_.options.asNavFor) {

            navTarget = _.getNavTarget();
            navTarget = navTarget.slick('getSlick');

            if (navTarget.slideCount <= navTarget.options.slidesToShow) {
                navTarget.setSlideClasses(_.currentSlide);
            }
        }

        _.updateDots();
        _.updateArrows();

        if (_.options.fade === true) {
            if (dontAnimate !== true) {

                _.fadeSlideOut(oldSlide);

                _.fadeSlide(animSlide, function () {
                    _.postSlide(animSlide);
                });
            } else {
                _.postSlide(animSlide);
            }
            _.animateHeight();
            return;
        }

        if (dontAnimate !== true) {
            _.animateSlide(targetLeft, function () {
                _.postSlide(animSlide);
            });
        } else {
            _.postSlide(animSlide);
        }
    };

    Slick.prototype.startLoad = function () {

        var _ = this;

        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow) {

            _.$prevArrow.hide();
            _.$nextArrow.hide();
        }

        if (_.options.dots === true && _.slideCount > _.options.slidesToShow) {

            _.$dots.hide();
        }

        _.$slider.addClass('slick-loading');
    };

    Slick.prototype.swipeDirection = function () {

        var xDist,
            yDist,
            r,
            swipeAngle,
            _ = this;

        xDist = _.touchObject.startX - _.touchObject.curX;
        yDist = _.touchObject.startY - _.touchObject.curY;
        r = Math.atan2(yDist, xDist);

        swipeAngle = Math.round(r * 180 / Math.PI);
        if (swipeAngle < 0) {
            swipeAngle = 360 - Math.abs(swipeAngle);
        }

        if (swipeAngle <= 45 && swipeAngle >= 0) {
            return _.options.rtl === false ? 'left' : 'right';
        }
        if (swipeAngle <= 360 && swipeAngle >= 315) {
            return _.options.rtl === false ? 'left' : 'right';
        }
        if (swipeAngle >= 135 && swipeAngle <= 225) {
            return _.options.rtl === false ? 'right' : 'left';
        }
        if (_.options.verticalSwiping === true) {
            if (swipeAngle >= 35 && swipeAngle <= 135) {
                return 'down';
            } else {
                return 'up';
            }
        }

        return 'vertical';
    };

    Slick.prototype.swipeEnd = function (event) {

        var _ = this,
            slideCount,
            direction;

        _.dragging = false;
        _.interrupted = false;
        _.shouldClick = _.touchObject.swipeLength > 10 ? false : true;

        if (_.touchObject.curX === undefined) {
            return false;
        }

        if (_.touchObject.edgeHit === true) {
            _.$slider.trigger('edge', [_, _.swipeDirection()]);
        }

        if (_.touchObject.swipeLength >= _.touchObject.minSwipe) {

            direction = _.swipeDirection();

            switch (direction) {

                case 'left':
                case 'down':

                    slideCount = _.options.swipeToSlide ? _.checkNavigable(_.currentSlide + _.getSlideCount()) : _.currentSlide + _.getSlideCount();

                    _.currentDirection = 0;

                    break;

                case 'right':
                case 'up':

                    slideCount = _.options.swipeToSlide ? _.checkNavigable(_.currentSlide - _.getSlideCount()) : _.currentSlide - _.getSlideCount();

                    _.currentDirection = 1;

                    break;

                default:

            }

            if (direction != 'vertical') {

                _.slideHandler(slideCount);
                _.touchObject = {};
                _.$slider.trigger('swipe', [_, direction]);
            }
        } else {

            if (_.touchObject.startX !== _.touchObject.curX) {

                _.slideHandler(_.currentSlide);
                _.touchObject = {};
            }
        }
    };

    Slick.prototype.swipeHandler = function (event) {

        var _ = this;

        if (_.options.swipe === false || 'ontouchend' in document && _.options.swipe === false) {
            return;
        } else if (_.options.draggable === false && event.type.indexOf('mouse') !== -1) {
            return;
        }

        _.touchObject.fingerCount = event.originalEvent && event.originalEvent.touches !== undefined ? event.originalEvent.touches.length : 1;

        _.touchObject.minSwipe = _.listWidth / _.options.touchThreshold;

        if (_.options.verticalSwiping === true) {
            _.touchObject.minSwipe = _.listHeight / _.options.touchThreshold;
        }

        switch (event.data.action) {

            case 'start':
                _.swipeStart(event);
                break;

            case 'move':
                _.swipeMove(event);
                break;

            case 'end':
                _.swipeEnd(event);
                break;

        }
    };

    Slick.prototype.swipeMove = function (event) {

        var _ = this,
            edgeWasHit = false,
            curLeft,
            swipeDirection,
            swipeLength,
            positionOffset,
            touches;

        touches = event.originalEvent !== undefined ? event.originalEvent.touches : null;

        if (!_.dragging || touches && touches.length !== 1) {
            return false;
        }

        curLeft = _.getLeft(_.currentSlide);

        _.touchObject.curX = touches !== undefined ? touches[0].pageX : event.clientX;
        _.touchObject.curY = touches !== undefined ? touches[0].pageY : event.clientY;

        _.touchObject.swipeLength = Math.round(Math.sqrt(Math.pow(_.touchObject.curX - _.touchObject.startX, 2)));

        if (_.options.verticalSwiping === true) {
            _.touchObject.swipeLength = Math.round(Math.sqrt(Math.pow(_.touchObject.curY - _.touchObject.startY, 2)));
        }

        swipeDirection = _.swipeDirection();

        if (swipeDirection === 'vertical') {
            return;
        }

        if (event.originalEvent !== undefined && _.touchObject.swipeLength > 4) {
            event.preventDefault();
        }

        positionOffset = (_.options.rtl === false ? 1 : -1) * (_.touchObject.curX > _.touchObject.startX ? 1 : -1);
        if (_.options.verticalSwiping === true) {
            positionOffset = _.touchObject.curY > _.touchObject.startY ? 1 : -1;
        }

        swipeLength = _.touchObject.swipeLength;

        _.touchObject.edgeHit = false;

        if (_.options.infinite === false) {
            if (_.currentSlide === 0 && swipeDirection === 'right' || _.currentSlide >= _.getDotCount() && swipeDirection === 'left') {
                swipeLength = _.touchObject.swipeLength * _.options.edgeFriction;
                _.touchObject.edgeHit = true;
            }
        }

        if (_.options.vertical === false) {
            _.swipeLeft = curLeft + swipeLength * positionOffset;
        } else {
            _.swipeLeft = curLeft + swipeLength * (_.$list.height() / _.listWidth) * positionOffset;
        }
        if (_.options.verticalSwiping === true) {
            _.swipeLeft = curLeft + swipeLength * positionOffset;
        }

        if (_.options.fade === true || _.options.touchMove === false) {
            return false;
        }

        if (_.animating === true) {
            _.swipeLeft = null;
            return false;
        }

        _.setCSS(_.swipeLeft);
    };

    Slick.prototype.swipeStart = function (event) {

        var _ = this,
            touches;

        _.interrupted = true;

        if (_.touchObject.fingerCount !== 1 || _.slideCount <= _.options.slidesToShow) {
            _.touchObject = {};
            return false;
        }

        if (event.originalEvent !== undefined && event.originalEvent.touches !== undefined) {
            touches = event.originalEvent.touches[0];
        }

        _.touchObject.startX = _.touchObject.curX = touches !== undefined ? touches.pageX : event.clientX;
        _.touchObject.startY = _.touchObject.curY = touches !== undefined ? touches.pageY : event.clientY;

        _.dragging = true;
    };

    Slick.prototype.unfilterSlides = Slick.prototype.slickUnfilter = function () {

        var _ = this;

        if (_.$slidesCache !== null) {

            _.unload();

            _.$slideTrack.children(this.options.slide).detach();

            _.$slidesCache.appendTo(_.$slideTrack);

            _.reinit();
        }
    };

    Slick.prototype.unload = function () {

        var _ = this;

        $('.slick-cloned', _.$slider).remove();

        if (_.$dots) {
            _.$dots.remove();
        }

        if (_.$prevArrow && _.htmlExpr.test(_.options.prevArrow)) {
            _.$prevArrow.remove();
        }

        if (_.$nextArrow && _.htmlExpr.test(_.options.nextArrow)) {
            _.$nextArrow.remove();
        }

        _.$slides.removeClass('slick-slide slick-active slick-visible slick-current').attr('aria-hidden', 'true').css('width', '');
    };

    Slick.prototype.unslick = function (fromBreakpoint) {

        var _ = this;
        _.$slider.trigger('unslick', [_, fromBreakpoint]);
        _.destroy();
    };

    Slick.prototype.updateArrows = function () {

        var _ = this,
            centerOffset;

        centerOffset = Math.floor(_.options.slidesToShow / 2);

        if (_.options.arrows === true && _.slideCount > _.options.slidesToShow && !_.options.infinite) {

            _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
            _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');

            if (_.currentSlide === 0) {

                _.$prevArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
                _.$nextArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
            } else if (_.currentSlide >= _.slideCount - _.options.slidesToShow && _.options.centerMode === false) {

                _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
                _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
            } else if (_.currentSlide >= _.slideCount - 1 && _.options.centerMode === true) {

                _.$nextArrow.addClass('slick-disabled').attr('aria-disabled', 'true');
                _.$prevArrow.removeClass('slick-disabled').attr('aria-disabled', 'false');
            }
        }
    };

    Slick.prototype.updateDots = function () {

        var _ = this;

        if (_.$dots !== null) {

            _.$dots.find('li').removeClass('slick-active').attr('aria-hidden', 'true');

            _.$dots.find('li').eq(Math.floor(_.currentSlide / _.options.slidesToScroll)).addClass('slick-active').attr('aria-hidden', 'false');
        }
    };

    Slick.prototype.visibility = function () {

        var _ = this;

        if (_.options.autoplay) {

            if (document[_.hidden]) {

                _.interrupted = true;
            } else {

                _.interrupted = false;
            }
        }
    };

    $.fn.slick = function () {
        var _ = this,
            opt = arguments[0],
            args = Array.prototype.slice.call(arguments, 1),
            l = _.length,
            i,
            ret;
        for (i = 0; i < l; i++) {
            if ((typeof opt === 'undefined' ? 'undefined' : _typeof(opt)) == 'object' || typeof opt == 'undefined') _[i].slick = new Slick(_[i], opt);else ret = _[i].slick[opt].apply(_[i].slick, args);
            if (typeof ret != 'undefined') return ret;
        }
        return _;
    };
});
'use strict';

;
(function () {
    $(document).foundation();

    var $window = $(window),
        $slick = $('.slick'),
        $slickLinks = $('.slick__links'),
        wMedium = 640,
        wLarge = 1024,
        equalheight = function equalheight() {
        $('.content--with-form').each(function () {

            // Cache the highest
            var $column = '.same-height',
                highestBox = 0;

            // Select and loop the elements you want to equalise
            $($column, this).each(function () {

                // If this box is higher than the cached highest then store it
                if ($(this).height() > highestBox) {
                    highestBox = $(this).height();
                }
            });

            // Set the height of all those children to whichever was highest
            $($column, this).css('min-height', highestBox);
        });
    },
        changeSlickMenu = function changeSlickMenu() {
        var $this = $(this),
            slideIndex = $slick.slick('slickCurrentSlide') + 1;

        $('.slick__links li').removeClass('active');
        $('.slick__links li:nth-child(' + slideIndex + ')').addClass('active');
    };

    $window.load(function () {
        if ($window.width() > wMedium) {
            equalheight();
        }
    });
    $window.resize(function () {
        if ($window.width() > wMedium) {
            equalheight();
            console.log($window.width());
        } else {
            $('.same-height').removeAttr('style');
        }
    });

    $slick.slick({
        dots: false,
        arrows: true,
        infinite: true,
        adaptiveHeight: true
    });

    $slickLinks.on('click', 'a', function (e) {
        var $this = $(this),
            slideIndex = $this.closest('li').index();

        $('.slick__links li').removeClass('active');
        $this.parent().addClass('active');

        $slick.slick('slickGoTo', parseInt(slideIndex));
        e.preventDefault();
    });

    $('.slick-arrow').on('click', function (e) {
        changeSlickMenu();
    });

    $slick.on('swipe', function (event, slick, direction) {
        changeSlickMenu();
    });
})();
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImpxdWVyeS5qcyIsIndoYXQtaW5wdXQuanMiLCJmb3VuZGF0aW9uLmNvcmUuanMiLCJmb3VuZGF0aW9uLnV0aWwuYm94LmpzIiwiZm91bmRhdGlvbi51dGlsLmtleWJvYXJkLmpzIiwiZm91bmRhdGlvbi51dGlsLm1lZGlhUXVlcnkuanMiLCJmb3VuZGF0aW9uLnV0aWwubW90aW9uLmpzIiwiZm91bmRhdGlvbi51dGlsLm5lc3QuanMiLCJmb3VuZGF0aW9uLnV0aWwudGltZXJBbmRJbWFnZUxvYWRlci5qcyIsImZvdW5kYXRpb24udXRpbC50b3VjaC5qcyIsImZvdW5kYXRpb24udXRpbC50cmlnZ2Vycy5qcyIsImZvdW5kYXRpb24uYWJpZGUuanMiLCJmb3VuZGF0aW9uLmFjY29yZGlvbi5qcyIsImZvdW5kYXRpb24uYWNjb3JkaW9uTWVudS5qcyIsImZvdW5kYXRpb24uZHJpbGxkb3duLmpzIiwiZm91bmRhdGlvbi5kcm9wZG93bi5qcyIsImZvdW5kYXRpb24uZHJvcGRvd25NZW51LmpzIiwiZm91bmRhdGlvbi5lcXVhbGl6ZXIuanMiLCJmb3VuZGF0aW9uLmludGVyY2hhbmdlLmpzIiwiZm91bmRhdGlvbi5tYWdlbGxhbi5qcyIsImZvdW5kYXRpb24ub2ZmY2FudmFzLmpzIiwiZm91bmRhdGlvbi5vcmJpdC5qcyIsImZvdW5kYXRpb24ucmVzcG9uc2l2ZU1lbnUuanMiLCJmb3VuZGF0aW9uLnJlc3BvbnNpdmVUb2dnbGUuanMiLCJmb3VuZGF0aW9uLnJldmVhbC5qcyIsImZvdW5kYXRpb24uc2xpZGVyLmpzIiwiZm91bmRhdGlvbi5zdGlja3kuanMiLCJmb3VuZGF0aW9uLnRhYnMuanMiLCJmb3VuZGF0aW9uLnRvZ2dsZXIuanMiLCJmb3VuZGF0aW9uLnRvb2x0aXAuanMiLCJzbGljay5qcyIsImFwcC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUE7Ozs7Ozs7Ozs7Ozs7O0FBY0MsV0FBVSxNQUFWLEVBQWtCLE9BQWxCLEVBQTRCOztB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QUMzQjtBQUNIO0FBQ0osS0FKRDtBQUtBLFlBQVEsTUFBUixDQUFlLFlBQVc7QUFDdEIsWUFBSSxRQUFRLEtBQVIsS0FBa0IsT0FBdEIsRUFBK0I7QUFDM0I7QUFDQSxvQkFBUSxHQUFSLENBQVksUUFBUSxLQUFSLEVBQVo7QUFDSCxTQUhELE1BR087QUFDSCxjQUFFLGNBQUYsRUFBa0IsVUFBbEIsQ0FBNkIsT0FBN0I7QUFDSDtBQUNKLEtBUEQ7O0FBV0EsV0FBTyxLQUFQLENBQWE7QUFDVCxjQUFNLEtBREc7QUFFVCxnQkFBUSxJQUZDO0FBR1Qsa0JBQVUsSUFIRDtBQUlULHdCQUFnQjtBQUpQLEtBQWI7O0FBT0EsZ0JBQVksRUFBWixDQUFlLE9BQWYsRUFBd0IsR0FBeEIsRUFBNkIsVUFBUyxDQUFULEVBQVk7QUFDckMsWUFBSSxRQUFRLEVBQUUsSUFBRixDQUFaO0FBQUEsWUFDSSxhQUFhLE1BQU0sT0FBTixDQUFjLElBQWQsRUFBb0IsS0FBcEIsRUFEakI7O0FBR0EsVUFBRSxrQkFBRixFQUFzQixXQUF0QixDQUFrQyxRQUFsQztBQUNBLGNBQU0sTUFBTixHQUFlLFFBQWYsQ0FBd0IsUUFBeEI7O0FBRUEsZUFBTyxLQUFQLENBQWEsV0FBYixFQUEwQixTQUFTLFVBQVQsQ0FBMUI7QUFDQSxVQUFFLGNBQUY7QUFDSCxLQVREOztBQVdBLE1BQUUsY0FBRixFQUFrQixFQUFsQixDQUFxQixPQUFyQixFQUE4QixVQUFTLENBQVQsRUFBWTtBQUN0QztBQUNILEtBRkQ7O0FBSUEsV0FBTyxFQUFQLENBQVUsT0FBVixFQUFtQixVQUFTLEtBQVQsRUFBZ0IsS0FBaEIsRUFBdUIsU0FBdkIsRUFBa0M7QUFDakQ7QUFDSCxLQUZEO0FBWUgsQ0F4RkQiLCJmaWxlIjoiYXBwLmpzIiwic291cmNlc0NvbnRlbnQiOlsiLyohXHJcbiAqIGpRdWVyeSBKYXZhU2NyaXB0IExpYnJhcnkgdjIuMi40XHJcbiAqIGh0dHA6Ly9qcXVlcnkuY29tL1xyXG4gKlxyXG4gKiBJbmNsdWRlcyBTaXp6bGUuanNcclxuICogaHR0cDovL3NpenpsZWpzLmNvbS9cclxuICpcclxuICogQ29weXJpZ2h0IGpRdWVyeSBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnNcclxuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXHJcbiAqIGh0dHA6Ly9qcXVlcnkub3JnL2xpY2Vuc2VcclxuICpcclxuICogRGF0ZTogMjAxNi0wNS0yMFQxNzoyM1pcclxuICovXHJcblxyXG4oZnVuY3Rpb24oIGdsb2JhbCwgZmFjdG9yeSApIHtcclxuXHJcblx0aWYgKCB0eXBlb2YgbW9kdWxlID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUuZXhwb3J0cyA9PT0gXCJvYmplY3RcIiApIHtcclxuXHRcdC8vIEZvciBDb21tb25KUyBhbmQgQ29tbW9uSlMtbGlrZSBlbnZpcm9ubWVudHMgd2hlcmUgYSBwcm9wZXIgYHdpbmRvd2BcclxuXHRcdC8vIGlzIHByZXNlbnQsIGV4ZWN1dGUgdGhlIGZhY3RvcnkgYW5kIGdldCBqUXVlcnkuXHJcblx0XHQvLyBGb3IgZW52aXJvbm1lbnRzIHRoYXQgZG8gbm90IGhhdmUgYSBgd2luZG93YCB3aXRoIGEgYGRvY3VtZW50YFxyXG5cdFx0Ly8gKHN1Y2ggYXMgTm9kZS5qcyksIGV4cG9zZSBhIGZhY3RvcnkgYXMgbW9kdWxlLmV4cG9ydHMuXHJcblx0XHQvLyBUaGlzIGFjY2VudHVhdGVzIHRoZSBuZWVkIGZvciB0aGUgY3JlYXRpb24gb2YgYSByZWFsIGB3aW5kb3dgLlxyXG5cdFx0Ly8gZS5nLiB2YXIgalF1ZXJ5ID0gcmVxdWlyZShcImpxdWVyeVwiKSh3aW5kb3cpO1xyXG5cdFx0Ly8gU2VlIHRpY2tldCAjMTQ1NDkgZm9yIG1vcmUgaW5mby5cclxuXHRcdG1vZHVsZS5leHBvcnRzID0gZ2xvYmFsLmRvY3VtZW50ID9cclxuXHRcdFx0ZmFjdG9yeSggZ2xvYmFsLCB0cnVlICkgOlxyXG5cdFx0XHRmdW5jdGlvbiggdyApIHtcclxuXHRcdFx0XHRpZiAoICF3LmRvY3VtZW50ICkge1xyXG5cdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKCBcImpRdWVyeSByZXF1aXJlcyBhIHdpbmRvdyB3aXRoIGEgZG9jdW1lbnRcIiApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRyZXR1cm4gZmFjdG9yeSggdyApO1xyXG5cdFx0XHR9O1xyXG5cdH0gZWxzZSB7XHJcblx0XHRmYWN0b3J5KCBnbG9iYWwgKTtcclxuXHR9XHJcblxyXG4vLyBQYXNzIHRoaXMgaWYgd2luZG93IGlzIG5vdCBkZWZpbmVkIHlldFxyXG59KHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB0aGlzLCBmdW5jdGlvbiggd2luZG93LCBub0dsb2JhbCApIHtcclxuXHJcbi8vIFN1cHBvcnQ6IEZpcmVmb3ggMTgrXHJcbi8vIENhbid0IGJlIGluIHN0cmljdCBtb2RlLCBzZXZlcmFsIGxpYnMgaW5jbHVkaW5nIEFTUC5ORVQgdHJhY2VcclxuLy8gdGhlIHN0YWNrIHZpYSBhcmd1bWVudHMuY2FsbGVyLmNhbGxlZSBhbmQgRmlyZWZveCBkaWVzIGlmXHJcbi8vIHlvdSB0cnkgdG8gdHJhY2UgdGhyb3VnaCBcInVzZSBzdHJpY3RcIiBjYWxsIGNoYWlucy4gKCMxMzMzNSlcclxuLy9cInVzZSBzdHJpY3RcIjtcclxudmFyIGFyciA9IFtdO1xyXG5cclxudmFyIGRvY3VtZW50ID0gd2luZG93LmRvY3VtZW50O1xyXG5cclxudmFyIHNsaWNlID0gYXJyLnNsaWNlO1xyXG5cclxudmFyIGNvbmNhdCA9IGFyci5jb25jYXQ7XHJcblxyXG52YXIgcHVzaCA9IGFyci5wdXNoO1xyXG5cclxudmFyIGluZGV4T2YgPSBhcnIuaW5kZXhPZjtcclxuXHJcbnZhciBjbGFzczJ0eXBlID0ge307XHJcblxyXG52YXIgdG9TdHJpbmcgPSBjbGFzczJ0eXBlLnRvU3RyaW5nO1xyXG5cclxudmFyIGhhc093biA9IGNsYXNzMnR5cGUuaGFzT3duUHJvcGVydHk7XHJcblxyXG52YXIgc3VwcG9ydCA9IHt9O1xyXG5cclxuXHJcblxyXG52YXJcclxuXHR2ZXJzaW9uID0gXCIyLjIuNFwiLFxyXG5cclxuXHQvLyBEZWZpbmUgYSBsb2NhbCBjb3B5IG9mIGpRdWVyeVxyXG5cdGpRdWVyeSA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCApIHtcclxuXHJcblx0XHQvLyBUaGUgalF1ZXJ5IG9iamVjdCBpcyBhY3R1YWxseSBqdXN0IHRoZSBpbml0IGNvbnN0cnVjdG9yICdlbmhhbmNlZCdcclxuXHRcdC8vIE5lZWQgaW5pdCBpZiBqUXVlcnkgaXMgY2FsbGVkIChqdXN0IGFsbG93IGVycm9yIHRvIGJlIHRocm93biBpZiBub3QgaW5jbHVkZWQpXHJcblx0XHRyZXR1cm4gbmV3IGpRdWVyeS5mbi5pbml0KCBzZWxlY3RvciwgY29udGV4dCApO1xyXG5cdH0sXHJcblxyXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQ8NC4xXHJcblx0Ly8gTWFrZSBzdXJlIHdlIHRyaW0gQk9NIGFuZCBOQlNQXHJcblx0cnRyaW0gPSAvXltcXHNcXHVGRUZGXFx4QTBdK3xbXFxzXFx1RkVGRlxceEEwXSskL2csXHJcblxyXG5cdC8vIE1hdGNoZXMgZGFzaGVkIHN0cmluZyBmb3IgY2FtZWxpemluZ1xyXG5cdHJtc1ByZWZpeCA9IC9eLW1zLS8sXHJcblx0cmRhc2hBbHBoYSA9IC8tKFtcXGRhLXpdKS9naSxcclxuXHJcblx0Ly8gVXNlZCBieSBqUXVlcnkuY2FtZWxDYXNlIGFzIGNhbGxiYWNrIHRvIHJlcGxhY2UoKVxyXG5cdGZjYW1lbENhc2UgPSBmdW5jdGlvbiggYWxsLCBsZXR0ZXIgKSB7XHJcblx0XHRyZXR1cm4gbGV0dGVyLnRvVXBwZXJDYXNlKCk7XHJcblx0fTtcclxuXHJcbmpRdWVyeS5mbiA9IGpRdWVyeS5wcm90b3R5cGUgPSB7XHJcblxyXG5cdC8vIFRoZSBjdXJyZW50IHZlcnNpb24gb2YgalF1ZXJ5IGJlaW5nIHVzZWRcclxuXHRqcXVlcnk6IHZlcnNpb24sXHJcblxyXG5cdGNvbnN0cnVjdG9yOiBqUXVlcnksXHJcblxyXG5cdC8vIFN0YXJ0IHdpdGggYW4gZW1wdHkgc2VsZWN0b3JcclxuXHRzZWxlY3RvcjogXCJcIixcclxuXHJcblx0Ly8gVGhlIGRlZmF1bHQgbGVuZ3RoIG9mIGEgalF1ZXJ5IG9iamVjdCBpcyAwXHJcblx0bGVuZ3RoOiAwLFxyXG5cclxuXHR0b0FycmF5OiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiBzbGljZS5jYWxsKCB0aGlzICk7XHJcblx0fSxcclxuXHJcblx0Ly8gR2V0IHRoZSBOdGggZWxlbWVudCBpbiB0aGUgbWF0Y2hlZCBlbGVtZW50IHNldCBPUlxyXG5cdC8vIEdldCB0aGUgd2hvbGUgbWF0Y2hlZCBlbGVtZW50IHNldCBhcyBhIGNsZWFuIGFycmF5XHJcblx0Z2V0OiBmdW5jdGlvbiggbnVtICkge1xyXG5cdFx0cmV0dXJuIG51bSAhPSBudWxsID9cclxuXHJcblx0XHRcdC8vIFJldHVybiBqdXN0IHRoZSBvbmUgZWxlbWVudCBmcm9tIHRoZSBzZXRcclxuXHRcdFx0KCBudW0gPCAwID8gdGhpc1sgbnVtICsgdGhpcy5sZW5ndGggXSA6IHRoaXNbIG51bSBdICkgOlxyXG5cclxuXHRcdFx0Ly8gUmV0dXJuIGFsbCB0aGUgZWxlbWVudHMgaW4gYSBjbGVhbiBhcnJheVxyXG5cdFx0XHRzbGljZS5jYWxsKCB0aGlzICk7XHJcblx0fSxcclxuXHJcblx0Ly8gVGFrZSBhbiBhcnJheSBvZiBlbGVtZW50cyBhbmQgcHVzaCBpdCBvbnRvIHRoZSBzdGFja1xyXG5cdC8vIChyZXR1cm5pbmcgdGhlIG5ldyBtYXRjaGVkIGVsZW1lbnQgc2V0KVxyXG5cdHB1c2hTdGFjazogZnVuY3Rpb24oIGVsZW1zICkge1xyXG5cclxuXHRcdC8vIEJ1aWxkIGEgbmV3IGpRdWVyeSBtYXRjaGVkIGVsZW1lbnQgc2V0XHJcblx0XHR2YXIgcmV0ID0galF1ZXJ5Lm1lcmdlKCB0aGlzLmNvbnN0cnVjdG9yKCksIGVsZW1zICk7XHJcblxyXG5cdFx0Ly8gQWRkIHRoZSBvbGQgb2JqZWN0IG9udG8gdGhlIHN0YWNrIChhcyBhIHJlZmVyZW5jZSlcclxuXHRcdHJldC5wcmV2T2JqZWN0ID0gdGhpcztcclxuXHRcdHJldC5jb250ZXh0ID0gdGhpcy5jb250ZXh0O1xyXG5cclxuXHRcdC8vIFJldHVybiB0aGUgbmV3bHktZm9ybWVkIGVsZW1lbnQgc2V0XHJcblx0XHRyZXR1cm4gcmV0O1xyXG5cdH0sXHJcblxyXG5cdC8vIEV4ZWN1dGUgYSBjYWxsYmFjayBmb3IgZXZlcnkgZWxlbWVudCBpbiB0aGUgbWF0Y2hlZCBzZXQuXHJcblx0ZWFjaDogZnVuY3Rpb24oIGNhbGxiYWNrICkge1xyXG5cdFx0cmV0dXJuIGpRdWVyeS5lYWNoKCB0aGlzLCBjYWxsYmFjayApO1xyXG5cdH0sXHJcblxyXG5cdG1hcDogZnVuY3Rpb24oIGNhbGxiYWNrICkge1xyXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBqUXVlcnkubWFwKCB0aGlzLCBmdW5jdGlvbiggZWxlbSwgaSApIHtcclxuXHRcdFx0cmV0dXJuIGNhbGxiYWNrLmNhbGwoIGVsZW0sIGksIGVsZW0gKTtcclxuXHRcdH0gKSApO1xyXG5cdH0sXHJcblxyXG5cdHNsaWNlOiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggc2xpY2UuYXBwbHkoIHRoaXMsIGFyZ3VtZW50cyApICk7XHJcblx0fSxcclxuXHJcblx0Zmlyc3Q6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMuZXEoIDAgKTtcclxuXHR9LFxyXG5cclxuXHRsYXN0OiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLmVxKCAtMSApO1xyXG5cdH0sXHJcblxyXG5cdGVxOiBmdW5jdGlvbiggaSApIHtcclxuXHRcdHZhciBsZW4gPSB0aGlzLmxlbmd0aCxcclxuXHRcdFx0aiA9ICtpICsgKCBpIDwgMCA/IGxlbiA6IDAgKTtcclxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggaiA+PSAwICYmIGogPCBsZW4gPyBbIHRoaXNbIGogXSBdIDogW10gKTtcclxuXHR9LFxyXG5cclxuXHRlbmQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMucHJldk9iamVjdCB8fCB0aGlzLmNvbnN0cnVjdG9yKCk7XHJcblx0fSxcclxuXHJcblx0Ly8gRm9yIGludGVybmFsIHVzZSBvbmx5LlxyXG5cdC8vIEJlaGF2ZXMgbGlrZSBhbiBBcnJheSdzIG1ldGhvZCwgbm90IGxpa2UgYSBqUXVlcnkgbWV0aG9kLlxyXG5cdHB1c2g6IHB1c2gsXHJcblx0c29ydDogYXJyLnNvcnQsXHJcblx0c3BsaWNlOiBhcnIuc3BsaWNlXHJcbn07XHJcblxyXG5qUXVlcnkuZXh0ZW5kID0galF1ZXJ5LmZuLmV4dGVuZCA9IGZ1bmN0aW9uKCkge1xyXG5cdHZhciBvcHRpb25zLCBuYW1lLCBzcmMsIGNvcHksIGNvcHlJc0FycmF5LCBjbG9uZSxcclxuXHRcdHRhcmdldCA9IGFyZ3VtZW50c1sgMCBdIHx8IHt9LFxyXG5cdFx0aSA9IDEsXHJcblx0XHRsZW5ndGggPSBhcmd1bWVudHMubGVuZ3RoLFxyXG5cdFx0ZGVlcCA9IGZhbHNlO1xyXG5cclxuXHQvLyBIYW5kbGUgYSBkZWVwIGNvcHkgc2l0dWF0aW9uXHJcblx0aWYgKCB0eXBlb2YgdGFyZ2V0ID09PSBcImJvb2xlYW5cIiApIHtcclxuXHRcdGRlZXAgPSB0YXJnZXQ7XHJcblxyXG5cdFx0Ly8gU2tpcCB0aGUgYm9vbGVhbiBhbmQgdGhlIHRhcmdldFxyXG5cdFx0dGFyZ2V0ID0gYXJndW1lbnRzWyBpIF0gfHwge307XHJcblx0XHRpKys7XHJcblx0fVxyXG5cclxuXHQvLyBIYW5kbGUgY2FzZSB3aGVuIHRhcmdldCBpcyBhIHN0cmluZyBvciBzb21ldGhpbmcgKHBvc3NpYmxlIGluIGRlZXAgY29weSlcclxuXHRpZiAoIHR5cGVvZiB0YXJnZXQgIT09IFwib2JqZWN0XCIgJiYgIWpRdWVyeS5pc0Z1bmN0aW9uKCB0YXJnZXQgKSApIHtcclxuXHRcdHRhcmdldCA9IHt9O1xyXG5cdH1cclxuXHJcblx0Ly8gRXh0ZW5kIGpRdWVyeSBpdHNlbGYgaWYgb25seSBvbmUgYXJndW1lbnQgaXMgcGFzc2VkXHJcblx0aWYgKCBpID09PSBsZW5ndGggKSB7XHJcblx0XHR0YXJnZXQgPSB0aGlzO1xyXG5cdFx0aS0tO1xyXG5cdH1cclxuXHJcblx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpKysgKSB7XHJcblxyXG5cdFx0Ly8gT25seSBkZWFsIHdpdGggbm9uLW51bGwvdW5kZWZpbmVkIHZhbHVlc1xyXG5cdFx0aWYgKCAoIG9wdGlvbnMgPSBhcmd1bWVudHNbIGkgXSApICE9IG51bGwgKSB7XHJcblxyXG5cdFx0XHQvLyBFeHRlbmQgdGhlIGJhc2Ugb2JqZWN0XHJcblx0XHRcdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcclxuXHRcdFx0XHRzcmMgPSB0YXJnZXRbIG5hbWUgXTtcclxuXHRcdFx0XHRjb3B5ID0gb3B0aW9uc1sgbmFtZSBdO1xyXG5cclxuXHRcdFx0XHQvLyBQcmV2ZW50IG5ldmVyLWVuZGluZyBsb29wXHJcblx0XHRcdFx0aWYgKCB0YXJnZXQgPT09IGNvcHkgKSB7XHJcblx0XHRcdFx0XHRjb250aW51ZTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIFJlY3Vyc2UgaWYgd2UncmUgbWVyZ2luZyBwbGFpbiBvYmplY3RzIG9yIGFycmF5c1xyXG5cdFx0XHRcdGlmICggZGVlcCAmJiBjb3B5ICYmICggalF1ZXJ5LmlzUGxhaW5PYmplY3QoIGNvcHkgKSB8fFxyXG5cdFx0XHRcdFx0KCBjb3B5SXNBcnJheSA9IGpRdWVyeS5pc0FycmF5KCBjb3B5ICkgKSApICkge1xyXG5cclxuXHRcdFx0XHRcdGlmICggY29weUlzQXJyYXkgKSB7XHJcblx0XHRcdFx0XHRcdGNvcHlJc0FycmF5ID0gZmFsc2U7XHJcblx0XHRcdFx0XHRcdGNsb25lID0gc3JjICYmIGpRdWVyeS5pc0FycmF5KCBzcmMgKSA/IHNyYyA6IFtdO1xyXG5cclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdGNsb25lID0gc3JjICYmIGpRdWVyeS5pc1BsYWluT2JqZWN0KCBzcmMgKSA/IHNyYyA6IHt9O1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdC8vIE5ldmVyIG1vdmUgb3JpZ2luYWwgb2JqZWN0cywgY2xvbmUgdGhlbVxyXG5cdFx0XHRcdFx0dGFyZ2V0WyBuYW1lIF0gPSBqUXVlcnkuZXh0ZW5kKCBkZWVwLCBjbG9uZSwgY29weSApO1xyXG5cclxuXHRcdFx0XHQvLyBEb24ndCBicmluZyBpbiB1bmRlZmluZWQgdmFsdWVzXHJcblx0XHRcdFx0fSBlbHNlIGlmICggY29weSAhPT0gdW5kZWZpbmVkICkge1xyXG5cdFx0XHRcdFx0dGFyZ2V0WyBuYW1lIF0gPSBjb3B5O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0Ly8gUmV0dXJuIHRoZSBtb2RpZmllZCBvYmplY3RcclxuXHRyZXR1cm4gdGFyZ2V0O1xyXG59O1xyXG5cclxualF1ZXJ5LmV4dGVuZCgge1xyXG5cclxuXHQvLyBVbmlxdWUgZm9yIGVhY2ggY29weSBvZiBqUXVlcnkgb24gdGhlIHBhZ2VcclxuXHRleHBhbmRvOiBcImpRdWVyeVwiICsgKCB2ZXJzaW9uICsgTWF0aC5yYW5kb20oKSApLnJlcGxhY2UoIC9cXEQvZywgXCJcIiApLFxyXG5cclxuXHQvLyBBc3N1bWUgalF1ZXJ5IGlzIHJlYWR5IHdpdGhvdXQgdGhlIHJlYWR5IG1vZHVsZVxyXG5cdGlzUmVhZHk6IHRydWUsXHJcblxyXG5cdGVycm9yOiBmdW5jdGlvbiggbXNnICkge1xyXG5cdFx0dGhyb3cgbmV3IEVycm9yKCBtc2cgKTtcclxuXHR9LFxyXG5cclxuXHRub29wOiBmdW5jdGlvbigpIHt9LFxyXG5cclxuXHRpc0Z1bmN0aW9uOiBmdW5jdGlvbiggb2JqICkge1xyXG5cdFx0cmV0dXJuIGpRdWVyeS50eXBlKCBvYmogKSA9PT0gXCJmdW5jdGlvblwiO1xyXG5cdH0sXHJcblxyXG5cdGlzQXJyYXk6IEFycmF5LmlzQXJyYXksXHJcblxyXG5cdGlzV2luZG93OiBmdW5jdGlvbiggb2JqICkge1xyXG5cdFx0cmV0dXJuIG9iaiAhPSBudWxsICYmIG9iaiA9PT0gb2JqLndpbmRvdztcclxuXHR9LFxyXG5cclxuXHRpc051bWVyaWM6IGZ1bmN0aW9uKCBvYmogKSB7XHJcblxyXG5cdFx0Ly8gcGFyc2VGbG9hdCBOYU5zIG51bWVyaWMtY2FzdCBmYWxzZSBwb3NpdGl2ZXMgKG51bGx8dHJ1ZXxmYWxzZXxcIlwiKVxyXG5cdFx0Ly8gLi4uYnV0IG1pc2ludGVycHJldHMgbGVhZGluZy1udW1iZXIgc3RyaW5ncywgcGFydGljdWxhcmx5IGhleCBsaXRlcmFscyAoXCIweC4uLlwiKVxyXG5cdFx0Ly8gc3VidHJhY3Rpb24gZm9yY2VzIGluZmluaXRpZXMgdG8gTmFOXHJcblx0XHQvLyBhZGRpbmcgMSBjb3JyZWN0cyBsb3NzIG9mIHByZWNpc2lvbiBmcm9tIHBhcnNlRmxvYXQgKCMxNTEwMClcclxuXHRcdHZhciByZWFsU3RyaW5nT2JqID0gb2JqICYmIG9iai50b1N0cmluZygpO1xyXG5cdFx0cmV0dXJuICFqUXVlcnkuaXNBcnJheSggb2JqICkgJiYgKCByZWFsU3RyaW5nT2JqIC0gcGFyc2VGbG9hdCggcmVhbFN0cmluZ09iaiApICsgMSApID49IDA7XHJcblx0fSxcclxuXHJcblx0aXNQbGFpbk9iamVjdDogZnVuY3Rpb24oIG9iaiApIHtcclxuXHRcdHZhciBrZXk7XHJcblxyXG5cdFx0Ly8gTm90IHBsYWluIG9iamVjdHM6XHJcblx0XHQvLyAtIEFueSBvYmplY3Qgb3IgdmFsdWUgd2hvc2UgaW50ZXJuYWwgW1tDbGFzc11dIHByb3BlcnR5IGlzIG5vdCBcIltvYmplY3QgT2JqZWN0XVwiXHJcblx0XHQvLyAtIERPTSBub2Rlc1xyXG5cdFx0Ly8gLSB3aW5kb3dcclxuXHRcdGlmICggalF1ZXJ5LnR5cGUoIG9iaiApICE9PSBcIm9iamVjdFwiIHx8IG9iai5ub2RlVHlwZSB8fCBqUXVlcnkuaXNXaW5kb3coIG9iaiApICkge1xyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gTm90IG93biBjb25zdHJ1Y3RvciBwcm9wZXJ0eSBtdXN0IGJlIE9iamVjdFxyXG5cdFx0aWYgKCBvYmouY29uc3RydWN0b3IgJiZcclxuXHRcdFx0XHQhaGFzT3duLmNhbGwoIG9iaiwgXCJjb25zdHJ1Y3RvclwiICkgJiZcclxuXHRcdFx0XHQhaGFzT3duLmNhbGwoIG9iai5jb25zdHJ1Y3Rvci5wcm90b3R5cGUgfHwge30sIFwiaXNQcm90b3R5cGVPZlwiICkgKSB7XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBPd24gcHJvcGVydGllcyBhcmUgZW51bWVyYXRlZCBmaXJzdGx5LCBzbyB0byBzcGVlZCB1cCxcclxuXHRcdC8vIGlmIGxhc3Qgb25lIGlzIG93biwgdGhlbiBhbGwgcHJvcGVydGllcyBhcmUgb3duXHJcblx0XHRmb3IgKCBrZXkgaW4gb2JqICkge31cclxuXHJcblx0XHRyZXR1cm4ga2V5ID09PSB1bmRlZmluZWQgfHwgaGFzT3duLmNhbGwoIG9iaiwga2V5ICk7XHJcblx0fSxcclxuXHJcblx0aXNFbXB0eU9iamVjdDogZnVuY3Rpb24oIG9iaiApIHtcclxuXHRcdHZhciBuYW1lO1xyXG5cdFx0Zm9yICggbmFtZSBpbiBvYmogKSB7XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH1cclxuXHRcdHJldHVybiB0cnVlO1xyXG5cdH0sXHJcblxyXG5cdHR5cGU6IGZ1bmN0aW9uKCBvYmogKSB7XHJcblx0XHRpZiAoIG9iaiA9PSBudWxsICkge1xyXG5cdFx0XHRyZXR1cm4gb2JqICsgXCJcIjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMCwgaU9TPDYgKGZ1bmN0aW9uaXNoIFJlZ0V4cClcclxuXHRcdHJldHVybiB0eXBlb2Ygb2JqID09PSBcIm9iamVjdFwiIHx8IHR5cGVvZiBvYmogPT09IFwiZnVuY3Rpb25cIiA/XHJcblx0XHRcdGNsYXNzMnR5cGVbIHRvU3RyaW5nLmNhbGwoIG9iaiApIF0gfHwgXCJvYmplY3RcIiA6XHJcblx0XHRcdHR5cGVvZiBvYmo7XHJcblx0fSxcclxuXHJcblx0Ly8gRXZhbHVhdGVzIGEgc2NyaXB0IGluIGEgZ2xvYmFsIGNvbnRleHRcclxuXHRnbG9iYWxFdmFsOiBmdW5jdGlvbiggY29kZSApIHtcclxuXHRcdHZhciBzY3JpcHQsXHJcblx0XHRcdGluZGlyZWN0ID0gZXZhbDtcclxuXHJcblx0XHRjb2RlID0galF1ZXJ5LnRyaW0oIGNvZGUgKTtcclxuXHJcblx0XHRpZiAoIGNvZGUgKSB7XHJcblxyXG5cdFx0XHQvLyBJZiB0aGUgY29kZSBpbmNsdWRlcyBhIHZhbGlkLCBwcm9sb2d1ZSBwb3NpdGlvblxyXG5cdFx0XHQvLyBzdHJpY3QgbW9kZSBwcmFnbWEsIGV4ZWN1dGUgY29kZSBieSBpbmplY3RpbmcgYVxyXG5cdFx0XHQvLyBzY3JpcHQgdGFnIGludG8gdGhlIGRvY3VtZW50LlxyXG5cdFx0XHRpZiAoIGNvZGUuaW5kZXhPZiggXCJ1c2Ugc3RyaWN0XCIgKSA9PT0gMSApIHtcclxuXHRcdFx0XHRzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcInNjcmlwdFwiICk7XHJcblx0XHRcdFx0c2NyaXB0LnRleHQgPSBjb2RlO1xyXG5cdFx0XHRcdGRvY3VtZW50LmhlYWQuYXBwZW5kQ2hpbGQoIHNjcmlwdCApLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIHNjcmlwdCApO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cclxuXHRcdFx0XHQvLyBPdGhlcndpc2UsIGF2b2lkIHRoZSBET00gbm9kZSBjcmVhdGlvbiwgaW5zZXJ0aW9uXHJcblx0XHRcdFx0Ly8gYW5kIHJlbW92YWwgYnkgdXNpbmcgYW4gaW5kaXJlY3QgZ2xvYmFsIGV2YWxcclxuXHJcblx0XHRcdFx0aW5kaXJlY3QoIGNvZGUgKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8vIENvbnZlcnQgZGFzaGVkIHRvIGNhbWVsQ2FzZTsgdXNlZCBieSB0aGUgY3NzIGFuZCBkYXRhIG1vZHVsZXNcclxuXHQvLyBTdXBwb3J0OiBJRTktMTErXHJcblx0Ly8gTWljcm9zb2Z0IGZvcmdvdCB0byBodW1wIHRoZWlyIHZlbmRvciBwcmVmaXggKCM5NTcyKVxyXG5cdGNhbWVsQ2FzZTogZnVuY3Rpb24oIHN0cmluZyApIHtcclxuXHRcdHJldHVybiBzdHJpbmcucmVwbGFjZSggcm1zUHJlZml4LCBcIm1zLVwiICkucmVwbGFjZSggcmRhc2hBbHBoYSwgZmNhbWVsQ2FzZSApO1xyXG5cdH0sXHJcblxyXG5cdG5vZGVOYW1lOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcclxuXHRcdHJldHVybiBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZS50b0xvd2VyQ2FzZSgpO1xyXG5cdH0sXHJcblxyXG5cdGVhY2g6IGZ1bmN0aW9uKCBvYmosIGNhbGxiYWNrICkge1xyXG5cdFx0dmFyIGxlbmd0aCwgaSA9IDA7XHJcblxyXG5cdFx0aWYgKCBpc0FycmF5TGlrZSggb2JqICkgKSB7XHJcblx0XHRcdGxlbmd0aCA9IG9iai5sZW5ndGg7XHJcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xyXG5cdFx0XHRcdGlmICggY2FsbGJhY2suY2FsbCggb2JqWyBpIF0sIGksIG9ialsgaSBdICkgPT09IGZhbHNlICkge1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRmb3IgKCBpIGluIG9iaiApIHtcclxuXHRcdFx0XHRpZiAoIGNhbGxiYWNrLmNhbGwoIG9ialsgaSBdLCBpLCBvYmpbIGkgXSApID09PSBmYWxzZSApIHtcclxuXHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBvYmo7XHJcblx0fSxcclxuXHJcblx0Ly8gU3VwcG9ydDogQW5kcm9pZDw0LjFcclxuXHR0cmltOiBmdW5jdGlvbiggdGV4dCApIHtcclxuXHRcdHJldHVybiB0ZXh0ID09IG51bGwgP1xyXG5cdFx0XHRcIlwiIDpcclxuXHRcdFx0KCB0ZXh0ICsgXCJcIiApLnJlcGxhY2UoIHJ0cmltLCBcIlwiICk7XHJcblx0fSxcclxuXHJcblx0Ly8gcmVzdWx0cyBpcyBmb3IgaW50ZXJuYWwgdXNhZ2Ugb25seVxyXG5cdG1ha2VBcnJheTogZnVuY3Rpb24oIGFyciwgcmVzdWx0cyApIHtcclxuXHRcdHZhciByZXQgPSByZXN1bHRzIHx8IFtdO1xyXG5cclxuXHRcdGlmICggYXJyICE9IG51bGwgKSB7XHJcblx0XHRcdGlmICggaXNBcnJheUxpa2UoIE9iamVjdCggYXJyICkgKSApIHtcclxuXHRcdFx0XHRqUXVlcnkubWVyZ2UoIHJldCxcclxuXHRcdFx0XHRcdHR5cGVvZiBhcnIgPT09IFwic3RyaW5nXCIgP1xyXG5cdFx0XHRcdFx0WyBhcnIgXSA6IGFyclxyXG5cdFx0XHRcdCk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0cHVzaC5jYWxsKCByZXQsIGFyciApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHJldDtcclxuXHR9LFxyXG5cclxuXHRpbkFycmF5OiBmdW5jdGlvbiggZWxlbSwgYXJyLCBpICkge1xyXG5cdFx0cmV0dXJuIGFyciA9PSBudWxsID8gLTEgOiBpbmRleE9mLmNhbGwoIGFyciwgZWxlbSwgaSApO1xyXG5cdH0sXHJcblxyXG5cdG1lcmdlOiBmdW5jdGlvbiggZmlyc3QsIHNlY29uZCApIHtcclxuXHRcdHZhciBsZW4gPSArc2Vjb25kLmxlbmd0aCxcclxuXHRcdFx0aiA9IDAsXHJcblx0XHRcdGkgPSBmaXJzdC5sZW5ndGg7XHJcblxyXG5cdFx0Zm9yICggOyBqIDwgbGVuOyBqKysgKSB7XHJcblx0XHRcdGZpcnN0WyBpKysgXSA9IHNlY29uZFsgaiBdO1xyXG5cdFx0fVxyXG5cclxuXHRcdGZpcnN0Lmxlbmd0aCA9IGk7XHJcblxyXG5cdFx0cmV0dXJuIGZpcnN0O1xyXG5cdH0sXHJcblxyXG5cdGdyZXA6IGZ1bmN0aW9uKCBlbGVtcywgY2FsbGJhY2ssIGludmVydCApIHtcclxuXHRcdHZhciBjYWxsYmFja0ludmVyc2UsXHJcblx0XHRcdG1hdGNoZXMgPSBbXSxcclxuXHRcdFx0aSA9IDAsXHJcblx0XHRcdGxlbmd0aCA9IGVsZW1zLmxlbmd0aCxcclxuXHRcdFx0Y2FsbGJhY2tFeHBlY3QgPSAhaW52ZXJ0O1xyXG5cclxuXHRcdC8vIEdvIHRocm91Z2ggdGhlIGFycmF5LCBvbmx5IHNhdmluZyB0aGUgaXRlbXNcclxuXHRcdC8vIHRoYXQgcGFzcyB0aGUgdmFsaWRhdG9yIGZ1bmN0aW9uXHJcblx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcclxuXHRcdFx0Y2FsbGJhY2tJbnZlcnNlID0gIWNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpICk7XHJcblx0XHRcdGlmICggY2FsbGJhY2tJbnZlcnNlICE9PSBjYWxsYmFja0V4cGVjdCApIHtcclxuXHRcdFx0XHRtYXRjaGVzLnB1c2goIGVsZW1zWyBpIF0gKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBtYXRjaGVzO1xyXG5cdH0sXHJcblxyXG5cdC8vIGFyZyBpcyBmb3IgaW50ZXJuYWwgdXNhZ2Ugb25seVxyXG5cdG1hcDogZnVuY3Rpb24oIGVsZW1zLCBjYWxsYmFjaywgYXJnICkge1xyXG5cdFx0dmFyIGxlbmd0aCwgdmFsdWUsXHJcblx0XHRcdGkgPSAwLFxyXG5cdFx0XHRyZXQgPSBbXTtcclxuXHJcblx0XHQvLyBHbyB0aHJvdWdoIHRoZSBhcnJheSwgdHJhbnNsYXRpbmcgZWFjaCBvZiB0aGUgaXRlbXMgdG8gdGhlaXIgbmV3IHZhbHVlc1xyXG5cdFx0aWYgKCBpc0FycmF5TGlrZSggZWxlbXMgKSApIHtcclxuXHRcdFx0bGVuZ3RoID0gZWxlbXMubGVuZ3RoO1xyXG5cdFx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcclxuXHRcdFx0XHR2YWx1ZSA9IGNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpLCBhcmcgKTtcclxuXHJcblx0XHRcdFx0aWYgKCB2YWx1ZSAhPSBudWxsICkge1xyXG5cdFx0XHRcdFx0cmV0LnB1c2goIHZhbHVlICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0Ly8gR28gdGhyb3VnaCBldmVyeSBrZXkgb24gdGhlIG9iamVjdCxcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGZvciAoIGkgaW4gZWxlbXMgKSB7XHJcblx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjayggZWxlbXNbIGkgXSwgaSwgYXJnICk7XHJcblxyXG5cdFx0XHRcdGlmICggdmFsdWUgIT0gbnVsbCApIHtcclxuXHRcdFx0XHRcdHJldC5wdXNoKCB2YWx1ZSApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEZsYXR0ZW4gYW55IG5lc3RlZCBhcnJheXNcclxuXHRcdHJldHVybiBjb25jYXQuYXBwbHkoIFtdLCByZXQgKTtcclxuXHR9LFxyXG5cclxuXHQvLyBBIGdsb2JhbCBHVUlEIGNvdW50ZXIgZm9yIG9iamVjdHNcclxuXHRndWlkOiAxLFxyXG5cclxuXHQvLyBCaW5kIGEgZnVuY3Rpb24gdG8gYSBjb250ZXh0LCBvcHRpb25hbGx5IHBhcnRpYWxseSBhcHBseWluZyBhbnlcclxuXHQvLyBhcmd1bWVudHMuXHJcblx0cHJveHk6IGZ1bmN0aW9uKCBmbiwgY29udGV4dCApIHtcclxuXHRcdHZhciB0bXAsIGFyZ3MsIHByb3h5O1xyXG5cclxuXHRcdGlmICggdHlwZW9mIGNvbnRleHQgPT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdHRtcCA9IGZuWyBjb250ZXh0IF07XHJcblx0XHRcdGNvbnRleHQgPSBmbjtcclxuXHRcdFx0Zm4gPSB0bXA7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gUXVpY2sgY2hlY2sgdG8gZGV0ZXJtaW5lIGlmIHRhcmdldCBpcyBjYWxsYWJsZSwgaW4gdGhlIHNwZWNcclxuXHRcdC8vIHRoaXMgdGhyb3dzIGEgVHlwZUVycm9yLCBidXQgd2Ugd2lsbCBqdXN0IHJldHVybiB1bmRlZmluZWQuXHJcblx0XHRpZiAoICFqUXVlcnkuaXNGdW5jdGlvbiggZm4gKSApIHtcclxuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBTaW11bGF0ZWQgYmluZFxyXG5cdFx0YXJncyA9IHNsaWNlLmNhbGwoIGFyZ3VtZW50cywgMiApO1xyXG5cdFx0cHJveHkgPSBmdW5jdGlvbigpIHtcclxuXHRcdFx0cmV0dXJuIGZuLmFwcGx5KCBjb250ZXh0IHx8IHRoaXMsIGFyZ3MuY29uY2F0KCBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSApICk7XHJcblx0XHR9O1xyXG5cclxuXHRcdC8vIFNldCB0aGUgZ3VpZCBvZiB1bmlxdWUgaGFuZGxlciB0byB0aGUgc2FtZSBvZiBvcmlnaW5hbCBoYW5kbGVyLCBzbyBpdCBjYW4gYmUgcmVtb3ZlZFxyXG5cdFx0cHJveHkuZ3VpZCA9IGZuLmd1aWQgPSBmbi5ndWlkIHx8IGpRdWVyeS5ndWlkKys7XHJcblxyXG5cdFx0cmV0dXJuIHByb3h5O1xyXG5cdH0sXHJcblxyXG5cdG5vdzogRGF0ZS5ub3csXHJcblxyXG5cdC8vIGpRdWVyeS5zdXBwb3J0IGlzIG5vdCB1c2VkIGluIENvcmUgYnV0IG90aGVyIHByb2plY3RzIGF0dGFjaCB0aGVpclxyXG5cdC8vIHByb3BlcnRpZXMgdG8gaXQgc28gaXQgbmVlZHMgdG8gZXhpc3QuXHJcblx0c3VwcG9ydDogc3VwcG9ydFxyXG59ICk7XHJcblxyXG4vLyBKU0hpbnQgd291bGQgZXJyb3Igb24gdGhpcyBjb2RlIGR1ZSB0byB0aGUgU3ltYm9sIG5vdCBiZWluZyBkZWZpbmVkIGluIEVTNS5cclxuLy8gRGVmaW5pbmcgdGhpcyBnbG9iYWwgaW4gLmpzaGludHJjIHdvdWxkIGNyZWF0ZSBhIGRhbmdlciBvZiB1c2luZyB0aGUgZ2xvYmFsXHJcbi8vIHVuZ3VhcmRlZCBpbiBhbm90aGVyIHBsYWNlLCBpdCBzZWVtcyBzYWZlciB0byBqdXN0IGRpc2FibGUgSlNIaW50IGZvciB0aGVzZVxyXG4vLyB0aHJlZSBsaW5lcy5cclxuLyoganNoaW50IGlnbm9yZTogc3RhcnQgKi9cclxuaWYgKCB0eXBlb2YgU3ltYm9sID09PSBcImZ1bmN0aW9uXCIgKSB7XHJcblx0alF1ZXJ5LmZuWyBTeW1ib2wuaXRlcmF0b3IgXSA9IGFyclsgU3ltYm9sLml0ZXJhdG9yIF07XHJcbn1cclxuLyoganNoaW50IGlnbm9yZTogZW5kICovXHJcblxyXG4vLyBQb3B1bGF0ZSB0aGUgY2xhc3MydHlwZSBtYXBcclxualF1ZXJ5LmVhY2goIFwiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvciBTeW1ib2xcIi5zcGxpdCggXCIgXCIgKSxcclxuZnVuY3Rpb24oIGksIG5hbWUgKSB7XHJcblx0Y2xhc3MydHlwZVsgXCJbb2JqZWN0IFwiICsgbmFtZSArIFwiXVwiIF0gPSBuYW1lLnRvTG93ZXJDYXNlKCk7XHJcbn0gKTtcclxuXHJcbmZ1bmN0aW9uIGlzQXJyYXlMaWtlKCBvYmogKSB7XHJcblxyXG5cdC8vIFN1cHBvcnQ6IGlPUyA4LjIgKG5vdCByZXByb2R1Y2libGUgaW4gc2ltdWxhdG9yKVxyXG5cdC8vIGBpbmAgY2hlY2sgdXNlZCB0byBwcmV2ZW50IEpJVCBlcnJvciAoZ2gtMjE0NSlcclxuXHQvLyBoYXNPd24gaXNuJ3QgdXNlZCBoZXJlIGR1ZSB0byBmYWxzZSBuZWdhdGl2ZXNcclxuXHQvLyByZWdhcmRpbmcgTm9kZWxpc3QgbGVuZ3RoIGluIElFXHJcblx0dmFyIGxlbmd0aCA9ICEhb2JqICYmIFwibGVuZ3RoXCIgaW4gb2JqICYmIG9iai5sZW5ndGgsXHJcblx0XHR0eXBlID0galF1ZXJ5LnR5cGUoIG9iaiApO1xyXG5cclxuXHRpZiAoIHR5cGUgPT09IFwiZnVuY3Rpb25cIiB8fCBqUXVlcnkuaXNXaW5kb3coIG9iaiApICkge1xyXG5cdFx0cmV0dXJuIGZhbHNlO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIHR5cGUgPT09IFwiYXJyYXlcIiB8fCBsZW5ndGggPT09IDAgfHxcclxuXHRcdHR5cGVvZiBsZW5ndGggPT09IFwibnVtYmVyXCIgJiYgbGVuZ3RoID4gMCAmJiAoIGxlbmd0aCAtIDEgKSBpbiBvYmo7XHJcbn1cclxudmFyIFNpenpsZSA9XHJcbi8qIVxyXG4gKiBTaXp6bGUgQ1NTIFNlbGVjdG9yIEVuZ2luZSB2Mi4yLjFcclxuICogaHR0cDovL3NpenpsZWpzLmNvbS9cclxuICpcclxuICogQ29weXJpZ2h0IGpRdWVyeSBGb3VuZGF0aW9uIGFuZCBvdGhlciBjb250cmlidXRvcnNcclxuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXHJcbiAqIGh0dHA6Ly9qcXVlcnkub3JnL2xpY2Vuc2VcclxuICpcclxuICogRGF0ZTogMjAxNS0xMC0xN1xyXG4gKi9cclxuKGZ1bmN0aW9uKCB3aW5kb3cgKSB7XHJcblxyXG52YXIgaSxcclxuXHRzdXBwb3J0LFxyXG5cdEV4cHIsXHJcblx0Z2V0VGV4dCxcclxuXHRpc1hNTCxcclxuXHR0b2tlbml6ZSxcclxuXHRjb21waWxlLFxyXG5cdHNlbGVjdCxcclxuXHRvdXRlcm1vc3RDb250ZXh0LFxyXG5cdHNvcnRJbnB1dCxcclxuXHRoYXNEdXBsaWNhdGUsXHJcblxyXG5cdC8vIExvY2FsIGRvY3VtZW50IHZhcnNcclxuXHRzZXREb2N1bWVudCxcclxuXHRkb2N1bWVudCxcclxuXHRkb2NFbGVtLFxyXG5cdGRvY3VtZW50SXNIVE1MLFxyXG5cdHJidWdneVFTQSxcclxuXHRyYnVnZ3lNYXRjaGVzLFxyXG5cdG1hdGNoZXMsXHJcblx0Y29udGFpbnMsXHJcblxyXG5cdC8vIEluc3RhbmNlLXNwZWNpZmljIGRhdGFcclxuXHRleHBhbmRvID0gXCJzaXp6bGVcIiArIDEgKiBuZXcgRGF0ZSgpLFxyXG5cdHByZWZlcnJlZERvYyA9IHdpbmRvdy5kb2N1bWVudCxcclxuXHRkaXJydW5zID0gMCxcclxuXHRkb25lID0gMCxcclxuXHRjbGFzc0NhY2hlID0gY3JlYXRlQ2FjaGUoKSxcclxuXHR0b2tlbkNhY2hlID0gY3JlYXRlQ2FjaGUoKSxcclxuXHRjb21waWxlckNhY2hlID0gY3JlYXRlQ2FjaGUoKSxcclxuXHRzb3J0T3JkZXIgPSBmdW5jdGlvbiggYSwgYiApIHtcclxuXHRcdGlmICggYSA9PT0gYiApIHtcclxuXHRcdFx0aGFzRHVwbGljYXRlID0gdHJ1ZTtcclxuXHRcdH1cclxuXHRcdHJldHVybiAwO1xyXG5cdH0sXHJcblxyXG5cdC8vIEdlbmVyYWwtcHVycG9zZSBjb25zdGFudHNcclxuXHRNQVhfTkVHQVRJVkUgPSAxIDw8IDMxLFxyXG5cclxuXHQvLyBJbnN0YW5jZSBtZXRob2RzXHJcblx0aGFzT3duID0gKHt9KS5oYXNPd25Qcm9wZXJ0eSxcclxuXHRhcnIgPSBbXSxcclxuXHRwb3AgPSBhcnIucG9wLFxyXG5cdHB1c2hfbmF0aXZlID0gYXJyLnB1c2gsXHJcblx0cHVzaCA9IGFyci5wdXNoLFxyXG5cdHNsaWNlID0gYXJyLnNsaWNlLFxyXG5cdC8vIFVzZSBhIHN0cmlwcGVkLWRvd24gaW5kZXhPZiBhcyBpdCdzIGZhc3RlciB0aGFuIG5hdGl2ZVxyXG5cdC8vIGh0dHA6Ly9qc3BlcmYuY29tL3Rob3ItaW5kZXhvZi12cy1mb3IvNVxyXG5cdGluZGV4T2YgPSBmdW5jdGlvbiggbGlzdCwgZWxlbSApIHtcclxuXHRcdHZhciBpID0gMCxcclxuXHRcdFx0bGVuID0gbGlzdC5sZW5ndGg7XHJcblx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcclxuXHRcdFx0aWYgKCBsaXN0W2ldID09PSBlbGVtICkge1xyXG5cdFx0XHRcdHJldHVybiBpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gLTE7XHJcblx0fSxcclxuXHJcblx0Ym9vbGVhbnMgPSBcImNoZWNrZWR8c2VsZWN0ZWR8YXN5bmN8YXV0b2ZvY3VzfGF1dG9wbGF5fGNvbnRyb2xzfGRlZmVyfGRpc2FibGVkfGhpZGRlbnxpc21hcHxsb29wfG11bHRpcGxlfG9wZW58cmVhZG9ubHl8cmVxdWlyZWR8c2NvcGVkXCIsXHJcblxyXG5cdC8vIFJlZ3VsYXIgZXhwcmVzc2lvbnNcclxuXHJcblx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvY3NzMy1zZWxlY3RvcnMvI3doaXRlc3BhY2VcclxuXHR3aGl0ZXNwYWNlID0gXCJbXFxcXHgyMFxcXFx0XFxcXHJcXFxcblxcXFxmXVwiLFxyXG5cclxuXHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9DU1MyMS9zeW5kYXRhLmh0bWwjdmFsdWUtZGVmLWlkZW50aWZpZXJcclxuXHRpZGVudGlmaWVyID0gXCIoPzpcXFxcXFxcXC58W1xcXFx3LV18W15cXFxceDAwLVxcXFx4YTBdKStcIixcclxuXHJcblx0Ly8gQXR0cmlidXRlIHNlbGVjdG9yczogaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNhdHRyaWJ1dGUtc2VsZWN0b3JzXHJcblx0YXR0cmlidXRlcyA9IFwiXFxcXFtcIiArIHdoaXRlc3BhY2UgKyBcIiooXCIgKyBpZGVudGlmaWVyICsgXCIpKD86XCIgKyB3aGl0ZXNwYWNlICtcclxuXHRcdC8vIE9wZXJhdG9yIChjYXB0dXJlIDIpXHJcblx0XHRcIiooWypeJHwhfl0/PSlcIiArIHdoaXRlc3BhY2UgK1xyXG5cdFx0Ly8gXCJBdHRyaWJ1dGUgdmFsdWVzIG11c3QgYmUgQ1NTIGlkZW50aWZpZXJzIFtjYXB0dXJlIDVdIG9yIHN0cmluZ3MgW2NhcHR1cmUgMyBvciBjYXB0dXJlIDRdXCJcclxuXHRcdFwiKig/OicoKD86XFxcXFxcXFwufFteXFxcXFxcXFwnXSkqKSd8XFxcIigoPzpcXFxcXFxcXC58W15cXFxcXFxcXFxcXCJdKSopXFxcInwoXCIgKyBpZGVudGlmaWVyICsgXCIpKXwpXCIgKyB3aGl0ZXNwYWNlICtcclxuXHRcdFwiKlxcXFxdXCIsXHJcblxyXG5cdHBzZXVkb3MgPSBcIjooXCIgKyBpZGVudGlmaWVyICsgXCIpKD86XFxcXCgoXCIgK1xyXG5cdFx0Ly8gVG8gcmVkdWNlIHRoZSBudW1iZXIgb2Ygc2VsZWN0b3JzIG5lZWRpbmcgdG9rZW5pemUgaW4gdGhlIHByZUZpbHRlciwgcHJlZmVyIGFyZ3VtZW50czpcclxuXHRcdC8vIDEuIHF1b3RlZCAoY2FwdHVyZSAzOyBjYXB0dXJlIDQgb3IgY2FwdHVyZSA1KVxyXG5cdFx0XCIoJygoPzpcXFxcXFxcXC58W15cXFxcXFxcXCddKSopJ3xcXFwiKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcXFxcIl0pKilcXFwiKXxcIiArXHJcblx0XHQvLyAyLiBzaW1wbGUgKGNhcHR1cmUgNilcclxuXHRcdFwiKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcKClbXFxcXF1dfFwiICsgYXR0cmlidXRlcyArIFwiKSopfFwiICtcclxuXHRcdC8vIDMuIGFueXRoaW5nIGVsc2UgKGNhcHR1cmUgMilcclxuXHRcdFwiLipcIiArXHJcblx0XHRcIilcXFxcKXwpXCIsXHJcblxyXG5cdC8vIExlYWRpbmcgYW5kIG5vbi1lc2NhcGVkIHRyYWlsaW5nIHdoaXRlc3BhY2UsIGNhcHR1cmluZyBzb21lIG5vbi13aGl0ZXNwYWNlIGNoYXJhY3RlcnMgcHJlY2VkaW5nIHRoZSBsYXR0ZXJcclxuXHRyd2hpdGVzcGFjZSA9IG5ldyBSZWdFeHAoIHdoaXRlc3BhY2UgKyBcIitcIiwgXCJnXCIgKSxcclxuXHRydHJpbSA9IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiK3woKD86XnxbXlxcXFxcXFxcXSkoPzpcXFxcXFxcXC4pKilcIiArIHdoaXRlc3BhY2UgKyBcIiskXCIsIFwiZ1wiICksXHJcblxyXG5cdHJjb21tYSA9IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKixcIiArIHdoaXRlc3BhY2UgKyBcIipcIiApLFxyXG5cdHJjb21iaW5hdG9ycyA9IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKihbPit+XXxcIiArIHdoaXRlc3BhY2UgKyBcIilcIiArIHdoaXRlc3BhY2UgKyBcIipcIiApLFxyXG5cclxuXHRyYXR0cmlidXRlUXVvdGVzID0gbmV3IFJlZ0V4cCggXCI9XCIgKyB3aGl0ZXNwYWNlICsgXCIqKFteXFxcXF0nXFxcIl0qPylcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcXVwiLCBcImdcIiApLFxyXG5cclxuXHRycHNldWRvID0gbmV3IFJlZ0V4cCggcHNldWRvcyApLFxyXG5cdHJpZGVudGlmaWVyID0gbmV3IFJlZ0V4cCggXCJeXCIgKyBpZGVudGlmaWVyICsgXCIkXCIgKSxcclxuXHJcblx0bWF0Y2hFeHByID0ge1xyXG5cdFx0XCJJRFwiOiBuZXcgUmVnRXhwKCBcIl4jKFwiICsgaWRlbnRpZmllciArIFwiKVwiICksXHJcblx0XHRcIkNMQVNTXCI6IG5ldyBSZWdFeHAoIFwiXlxcXFwuKFwiICsgaWRlbnRpZmllciArIFwiKVwiICksXHJcblx0XHRcIlRBR1wiOiBuZXcgUmVnRXhwKCBcIl4oXCIgKyBpZGVudGlmaWVyICsgXCJ8WypdKVwiICksXHJcblx0XHRcIkFUVFJcIjogbmV3IFJlZ0V4cCggXCJeXCIgKyBhdHRyaWJ1dGVzICksXHJcblx0XHRcIlBTRVVET1wiOiBuZXcgUmVnRXhwKCBcIl5cIiArIHBzZXVkb3MgKSxcclxuXHRcdFwiQ0hJTERcIjogbmV3IFJlZ0V4cCggXCJeOihvbmx5fGZpcnN0fGxhc3R8bnRofG50aC1sYXN0KS0oY2hpbGR8b2YtdHlwZSkoPzpcXFxcKFwiICsgd2hpdGVzcGFjZSArXHJcblx0XHRcdFwiKihldmVufG9kZHwoKFsrLV18KShcXFxcZCopbnwpXCIgKyB3aGl0ZXNwYWNlICsgXCIqKD86KFsrLV18KVwiICsgd2hpdGVzcGFjZSArXHJcblx0XHRcdFwiKihcXFxcZCspfCkpXCIgKyB3aGl0ZXNwYWNlICsgXCIqXFxcXCl8KVwiLCBcImlcIiApLFxyXG5cdFx0XCJib29sXCI6IG5ldyBSZWdFeHAoIFwiXig/OlwiICsgYm9vbGVhbnMgKyBcIikkXCIsIFwiaVwiICksXHJcblx0XHQvLyBGb3IgdXNlIGluIGxpYnJhcmllcyBpbXBsZW1lbnRpbmcgLmlzKClcclxuXHRcdC8vIFdlIHVzZSB0aGlzIGZvciBQT1MgbWF0Y2hpbmcgaW4gYHNlbGVjdGBcclxuXHRcdFwibmVlZHNDb250ZXh0XCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKls+K35dfDooZXZlbnxvZGR8ZXF8Z3R8bHR8bnRofGZpcnN0fGxhc3QpKD86XFxcXChcIiArXHJcblx0XHRcdHdoaXRlc3BhY2UgKyBcIiooKD86LVxcXFxkKT9cXFxcZCopXCIgKyB3aGl0ZXNwYWNlICsgXCIqXFxcXCl8KSg/PVteLV18JClcIiwgXCJpXCIgKVxyXG5cdH0sXHJcblxyXG5cdHJpbnB1dHMgPSAvXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYXxidXR0b24pJC9pLFxyXG5cdHJoZWFkZXIgPSAvXmhcXGQkL2ksXHJcblxyXG5cdHJuYXRpdmUgPSAvXltee10rXFx7XFxzKlxcW25hdGl2ZSBcXHcvLFxyXG5cclxuXHQvLyBFYXNpbHktcGFyc2VhYmxlL3JldHJpZXZhYmxlIElEIG9yIFRBRyBvciBDTEFTUyBzZWxlY3RvcnNcclxuXHRycXVpY2tFeHByID0gL14oPzojKFtcXHctXSspfChcXHcrKXxcXC4oW1xcdy1dKykpJC8sXHJcblxyXG5cdHJzaWJsaW5nID0gL1srfl0vLFxyXG5cdHJlc2NhcGUgPSAvJ3xcXFxcL2csXHJcblxyXG5cdC8vIENTUyBlc2NhcGVzIGh0dHA6Ly93d3cudzMub3JnL1RSL0NTUzIxL3N5bmRhdGEuaHRtbCNlc2NhcGVkLWNoYXJhY3RlcnNcclxuXHRydW5lc2NhcGUgPSBuZXcgUmVnRXhwKCBcIlxcXFxcXFxcKFtcXFxcZGEtZl17MSw2fVwiICsgd2hpdGVzcGFjZSArIFwiP3woXCIgKyB3aGl0ZXNwYWNlICsgXCIpfC4pXCIsIFwiaWdcIiApLFxyXG5cdGZ1bmVzY2FwZSA9IGZ1bmN0aW9uKCBfLCBlc2NhcGVkLCBlc2NhcGVkV2hpdGVzcGFjZSApIHtcclxuXHRcdHZhciBoaWdoID0gXCIweFwiICsgZXNjYXBlZCAtIDB4MTAwMDA7XHJcblx0XHQvLyBOYU4gbWVhbnMgbm9uLWNvZGVwb2ludFxyXG5cdFx0Ly8gU3VwcG9ydDogRmlyZWZveDwyNFxyXG5cdFx0Ly8gV29ya2Fyb3VuZCBlcnJvbmVvdXMgbnVtZXJpYyBpbnRlcnByZXRhdGlvbiBvZiArXCIweFwiXHJcblx0XHRyZXR1cm4gaGlnaCAhPT0gaGlnaCB8fCBlc2NhcGVkV2hpdGVzcGFjZSA/XHJcblx0XHRcdGVzY2FwZWQgOlxyXG5cdFx0XHRoaWdoIDwgMCA/XHJcblx0XHRcdFx0Ly8gQk1QIGNvZGVwb2ludFxyXG5cdFx0XHRcdFN0cmluZy5mcm9tQ2hhckNvZGUoIGhpZ2ggKyAweDEwMDAwICkgOlxyXG5cdFx0XHRcdC8vIFN1cHBsZW1lbnRhbCBQbGFuZSBjb2RlcG9pbnQgKHN1cnJvZ2F0ZSBwYWlyKVxyXG5cdFx0XHRcdFN0cmluZy5mcm9tQ2hhckNvZGUoIGhpZ2ggPj4gMTAgfCAweEQ4MDAsIGhpZ2ggJiAweDNGRiB8IDB4REMwMCApO1xyXG5cdH0sXHJcblxyXG5cdC8vIFVzZWQgZm9yIGlmcmFtZXNcclxuXHQvLyBTZWUgc2V0RG9jdW1lbnQoKVxyXG5cdC8vIFJlbW92aW5nIHRoZSBmdW5jdGlvbiB3cmFwcGVyIGNhdXNlcyBhIFwiUGVybWlzc2lvbiBEZW5pZWRcIlxyXG5cdC8vIGVycm9yIGluIElFXHJcblx0dW5sb2FkSGFuZGxlciA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0c2V0RG9jdW1lbnQoKTtcclxuXHR9O1xyXG5cclxuLy8gT3B0aW1pemUgZm9yIHB1c2guYXBwbHkoIF8sIE5vZGVMaXN0IClcclxudHJ5IHtcclxuXHRwdXNoLmFwcGx5KFxyXG5cdFx0KGFyciA9IHNsaWNlLmNhbGwoIHByZWZlcnJlZERvYy5jaGlsZE5vZGVzICkpLFxyXG5cdFx0cHJlZmVycmVkRG9jLmNoaWxkTm9kZXNcclxuXHQpO1xyXG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQ8NC4wXHJcblx0Ly8gRGV0ZWN0IHNpbGVudGx5IGZhaWxpbmcgcHVzaC5hcHBseVxyXG5cdGFyclsgcHJlZmVycmVkRG9jLmNoaWxkTm9kZXMubGVuZ3RoIF0ubm9kZVR5cGU7XHJcbn0gY2F0Y2ggKCBlICkge1xyXG5cdHB1c2ggPSB7IGFwcGx5OiBhcnIubGVuZ3RoID9cclxuXHJcblx0XHQvLyBMZXZlcmFnZSBzbGljZSBpZiBwb3NzaWJsZVxyXG5cdFx0ZnVuY3Rpb24oIHRhcmdldCwgZWxzICkge1xyXG5cdFx0XHRwdXNoX25hdGl2ZS5hcHBseSggdGFyZ2V0LCBzbGljZS5jYWxsKGVscykgKTtcclxuXHRcdH0gOlxyXG5cclxuXHRcdC8vIFN1cHBvcnQ6IElFPDlcclxuXHRcdC8vIE90aGVyd2lzZSBhcHBlbmQgZGlyZWN0bHlcclxuXHRcdGZ1bmN0aW9uKCB0YXJnZXQsIGVscyApIHtcclxuXHRcdFx0dmFyIGogPSB0YXJnZXQubGVuZ3RoLFxyXG5cdFx0XHRcdGkgPSAwO1xyXG5cdFx0XHQvLyBDYW4ndCB0cnVzdCBOb2RlTGlzdC5sZW5ndGhcclxuXHRcdFx0d2hpbGUgKCAodGFyZ2V0W2orK10gPSBlbHNbaSsrXSkgKSB7fVxyXG5cdFx0XHR0YXJnZXQubGVuZ3RoID0gaiAtIDE7XHJcblx0XHR9XHJcblx0fTtcclxufVxyXG5cclxuZnVuY3Rpb24gU2l6emxlKCBzZWxlY3RvciwgY29udGV4dCwgcmVzdWx0cywgc2VlZCApIHtcclxuXHR2YXIgbSwgaSwgZWxlbSwgbmlkLCBuaWRzZWxlY3QsIG1hdGNoLCBncm91cHMsIG5ld1NlbGVjdG9yLFxyXG5cdFx0bmV3Q29udGV4dCA9IGNvbnRleHQgJiYgY29udGV4dC5vd25lckRvY3VtZW50LFxyXG5cclxuXHRcdC8vIG5vZGVUeXBlIGRlZmF1bHRzIHRvIDksIHNpbmNlIGNvbnRleHQgZGVmYXVsdHMgdG8gZG9jdW1lbnRcclxuXHRcdG5vZGVUeXBlID0gY29udGV4dCA/IGNvbnRleHQubm9kZVR5cGUgOiA5O1xyXG5cclxuXHRyZXN1bHRzID0gcmVzdWx0cyB8fCBbXTtcclxuXHJcblx0Ly8gUmV0dXJuIGVhcmx5IGZyb20gY2FsbHMgd2l0aCBpbnZhbGlkIHNlbGVjdG9yIG9yIGNvbnRleHRcclxuXHRpZiAoIHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiB8fCAhc2VsZWN0b3IgfHxcclxuXHRcdG5vZGVUeXBlICE9PSAxICYmIG5vZGVUeXBlICE9PSA5ICYmIG5vZGVUeXBlICE9PSAxMSApIHtcclxuXHJcblx0XHRyZXR1cm4gcmVzdWx0cztcclxuXHR9XHJcblxyXG5cdC8vIFRyeSB0byBzaG9ydGN1dCBmaW5kIG9wZXJhdGlvbnMgKGFzIG9wcG9zZWQgdG8gZmlsdGVycykgaW4gSFRNTCBkb2N1bWVudHNcclxuXHRpZiAoICFzZWVkICkge1xyXG5cclxuXHRcdGlmICggKCBjb250ZXh0ID8gY29udGV4dC5vd25lckRvY3VtZW50IHx8IGNvbnRleHQgOiBwcmVmZXJyZWREb2MgKSAhPT0gZG9jdW1lbnQgKSB7XHJcblx0XHRcdHNldERvY3VtZW50KCBjb250ZXh0ICk7XHJcblx0XHR9XHJcblx0XHRjb250ZXh0ID0gY29udGV4dCB8fCBkb2N1bWVudDtcclxuXHJcblx0XHRpZiAoIGRvY3VtZW50SXNIVE1MICkge1xyXG5cclxuXHRcdFx0Ly8gSWYgdGhlIHNlbGVjdG9yIGlzIHN1ZmZpY2llbnRseSBzaW1wbGUsIHRyeSB1c2luZyBhIFwiZ2V0KkJ5KlwiIERPTSBtZXRob2RcclxuXHRcdFx0Ly8gKGV4Y2VwdGluZyBEb2N1bWVudEZyYWdtZW50IGNvbnRleHQsIHdoZXJlIHRoZSBtZXRob2RzIGRvbid0IGV4aXN0KVxyXG5cdFx0XHRpZiAoIG5vZGVUeXBlICE9PSAxMSAmJiAobWF0Y2ggPSBycXVpY2tFeHByLmV4ZWMoIHNlbGVjdG9yICkpICkge1xyXG5cclxuXHRcdFx0XHQvLyBJRCBzZWxlY3RvclxyXG5cdFx0XHRcdGlmICggKG0gPSBtYXRjaFsxXSkgKSB7XHJcblxyXG5cdFx0XHRcdFx0Ly8gRG9jdW1lbnQgY29udGV4dFxyXG5cdFx0XHRcdFx0aWYgKCBub2RlVHlwZSA9PT0gOSApIHtcclxuXHRcdFx0XHRcdFx0aWYgKCAoZWxlbSA9IGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIG0gKSkgKSB7XHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFLCBPcGVyYSwgV2Via2l0XHJcblx0XHRcdFx0XHRcdFx0Ly8gVE9ETzogaWRlbnRpZnkgdmVyc2lvbnNcclxuXHRcdFx0XHRcdFx0XHQvLyBnZXRFbGVtZW50QnlJZCBjYW4gbWF0Y2ggZWxlbWVudHMgYnkgbmFtZSBpbnN0ZWFkIG9mIElEXHJcblx0XHRcdFx0XHRcdFx0aWYgKCBlbGVtLmlkID09PSBtICkge1xyXG5cdFx0XHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XHJcblx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XHJcblx0XHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHQvLyBFbGVtZW50IGNvbnRleHRcclxuXHRcdFx0XHRcdH0gZWxzZSB7XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSwgT3BlcmEsIFdlYmtpdFxyXG5cdFx0XHRcdFx0XHQvLyBUT0RPOiBpZGVudGlmeSB2ZXJzaW9uc1xyXG5cdFx0XHRcdFx0XHQvLyBnZXRFbGVtZW50QnlJZCBjYW4gbWF0Y2ggZWxlbWVudHMgYnkgbmFtZSBpbnN0ZWFkIG9mIElEXHJcblx0XHRcdFx0XHRcdGlmICggbmV3Q29udGV4dCAmJiAoZWxlbSA9IG5ld0NvbnRleHQuZ2V0RWxlbWVudEJ5SWQoIG0gKSkgJiZcclxuXHRcdFx0XHRcdFx0XHRjb250YWlucyggY29udGV4dCwgZWxlbSApICYmXHJcblx0XHRcdFx0XHRcdFx0ZWxlbS5pZCA9PT0gbSApIHtcclxuXHJcblx0XHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gVHlwZSBzZWxlY3RvclxyXG5cdFx0XHRcdH0gZWxzZSBpZiAoIG1hdGNoWzJdICkge1xyXG5cdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggc2VsZWN0b3IgKSApO1xyXG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XHJcblxyXG5cdFx0XHRcdC8vIENsYXNzIHNlbGVjdG9yXHJcblx0XHRcdFx0fSBlbHNlIGlmICggKG0gPSBtYXRjaFszXSkgJiYgc3VwcG9ydC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICYmXHJcblx0XHRcdFx0XHRjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgKSB7XHJcblxyXG5cdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgY29udGV4dC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCBtICkgKTtcclxuXHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gVGFrZSBhZHZhbnRhZ2Ugb2YgcXVlcnlTZWxlY3RvckFsbFxyXG5cdFx0XHRpZiAoIHN1cHBvcnQucXNhICYmXHJcblx0XHRcdFx0IWNvbXBpbGVyQ2FjaGVbIHNlbGVjdG9yICsgXCIgXCIgXSAmJlxyXG5cdFx0XHRcdCghcmJ1Z2d5UVNBIHx8ICFyYnVnZ3lRU0EudGVzdCggc2VsZWN0b3IgKSkgKSB7XHJcblxyXG5cdFx0XHRcdGlmICggbm9kZVR5cGUgIT09IDEgKSB7XHJcblx0XHRcdFx0XHRuZXdDb250ZXh0ID0gY29udGV4dDtcclxuXHRcdFx0XHRcdG5ld1NlbGVjdG9yID0gc2VsZWN0b3I7XHJcblxyXG5cdFx0XHRcdC8vIHFTQSBsb29rcyBvdXRzaWRlIEVsZW1lbnQgY29udGV4dCwgd2hpY2ggaXMgbm90IHdoYXQgd2Ugd2FudFxyXG5cdFx0XHRcdC8vIFRoYW5rcyB0byBBbmRyZXcgRHVwb250IGZvciB0aGlzIHdvcmthcm91bmQgdGVjaG5pcXVlXHJcblx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPD04XHJcblx0XHRcdFx0Ly8gRXhjbHVkZSBvYmplY3QgZWxlbWVudHNcclxuXHRcdFx0XHR9IGVsc2UgaWYgKCBjb250ZXh0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgIT09IFwib2JqZWN0XCIgKSB7XHJcblxyXG5cdFx0XHRcdFx0Ly8gQ2FwdHVyZSB0aGUgY29udGV4dCBJRCwgc2V0dGluZyBpdCBmaXJzdCBpZiBuZWNlc3NhcnlcclxuXHRcdFx0XHRcdGlmICggKG5pZCA9IGNvbnRleHQuZ2V0QXR0cmlidXRlKCBcImlkXCIgKSkgKSB7XHJcblx0XHRcdFx0XHRcdG5pZCA9IG5pZC5yZXBsYWNlKCByZXNjYXBlLCBcIlxcXFwkJlwiICk7XHJcblx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRjb250ZXh0LnNldEF0dHJpYnV0ZSggXCJpZFwiLCAobmlkID0gZXhwYW5kbykgKTtcclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHQvLyBQcmVmaXggZXZlcnkgc2VsZWN0b3IgaW4gdGhlIGxpc3RcclxuXHRcdFx0XHRcdGdyb3VwcyA9IHRva2VuaXplKCBzZWxlY3RvciApO1xyXG5cdFx0XHRcdFx0aSA9IGdyb3Vwcy5sZW5ndGg7XHJcblx0XHRcdFx0XHRuaWRzZWxlY3QgPSByaWRlbnRpZmllci50ZXN0KCBuaWQgKSA/IFwiI1wiICsgbmlkIDogXCJbaWQ9J1wiICsgbmlkICsgXCInXVwiO1xyXG5cdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XHJcblx0XHRcdFx0XHRcdGdyb3Vwc1tpXSA9IG5pZHNlbGVjdCArIFwiIFwiICsgdG9TZWxlY3RvciggZ3JvdXBzW2ldICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRuZXdTZWxlY3RvciA9IGdyb3Vwcy5qb2luKCBcIixcIiApO1xyXG5cclxuXHRcdFx0XHRcdC8vIEV4cGFuZCBjb250ZXh0IGZvciBzaWJsaW5nIHNlbGVjdG9yc1xyXG5cdFx0XHRcdFx0bmV3Q29udGV4dCA9IHJzaWJsaW5nLnRlc3QoIHNlbGVjdG9yICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8XHJcblx0XHRcdFx0XHRcdGNvbnRleHQ7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpZiAoIG5ld1NlbGVjdG9yICkge1xyXG5cdFx0XHRcdFx0dHJ5IHtcclxuXHRcdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cyxcclxuXHRcdFx0XHRcdFx0XHRuZXdDb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoIG5ld1NlbGVjdG9yIClcclxuXHRcdFx0XHRcdFx0KTtcclxuXHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XHJcblx0XHRcdFx0XHR9IGNhdGNoICggcXNhRXJyb3IgKSB7XHJcblx0XHRcdFx0XHR9IGZpbmFsbHkge1xyXG5cdFx0XHRcdFx0XHRpZiAoIG5pZCA9PT0gZXhwYW5kbyApIHtcclxuXHRcdFx0XHRcdFx0XHRjb250ZXh0LnJlbW92ZUF0dHJpYnV0ZSggXCJpZFwiICk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8vIEFsbCBvdGhlcnNcclxuXHRyZXR1cm4gc2VsZWN0KCBzZWxlY3Rvci5yZXBsYWNlKCBydHJpbSwgXCIkMVwiICksIGNvbnRleHQsIHJlc3VsdHMsIHNlZWQgKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIENyZWF0ZSBrZXktdmFsdWUgY2FjaGVzIG9mIGxpbWl0ZWQgc2l6ZVxyXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb24oc3RyaW5nLCBvYmplY3QpfSBSZXR1cm5zIHRoZSBPYmplY3QgZGF0YSBhZnRlciBzdG9yaW5nIGl0IG9uIGl0c2VsZiB3aXRoXHJcbiAqXHRwcm9wZXJ0eSBuYW1lIHRoZSAoc3BhY2Utc3VmZml4ZWQpIHN0cmluZyBhbmQgKGlmIHRoZSBjYWNoZSBpcyBsYXJnZXIgdGhhbiBFeHByLmNhY2hlTGVuZ3RoKVxyXG4gKlx0ZGVsZXRpbmcgdGhlIG9sZGVzdCBlbnRyeVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlQ2FjaGUoKSB7XHJcblx0dmFyIGtleXMgPSBbXTtcclxuXHJcblx0ZnVuY3Rpb24gY2FjaGUoIGtleSwgdmFsdWUgKSB7XHJcblx0XHQvLyBVc2UgKGtleSArIFwiIFwiKSB0byBhdm9pZCBjb2xsaXNpb24gd2l0aCBuYXRpdmUgcHJvdG90eXBlIHByb3BlcnRpZXMgKHNlZSBJc3N1ZSAjMTU3KVxyXG5cdFx0aWYgKCBrZXlzLnB1c2goIGtleSArIFwiIFwiICkgPiBFeHByLmNhY2hlTGVuZ3RoICkge1xyXG5cdFx0XHQvLyBPbmx5IGtlZXAgdGhlIG1vc3QgcmVjZW50IGVudHJpZXNcclxuXHRcdFx0ZGVsZXRlIGNhY2hlWyBrZXlzLnNoaWZ0KCkgXTtcclxuXHRcdH1cclxuXHRcdHJldHVybiAoY2FjaGVbIGtleSArIFwiIFwiIF0gPSB2YWx1ZSk7XHJcblx0fVxyXG5cdHJldHVybiBjYWNoZTtcclxufVxyXG5cclxuLyoqXHJcbiAqIE1hcmsgYSBmdW5jdGlvbiBmb3Igc3BlY2lhbCB1c2UgYnkgU2l6emxlXHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFRoZSBmdW5jdGlvbiB0byBtYXJrXHJcbiAqL1xyXG5mdW5jdGlvbiBtYXJrRnVuY3Rpb24oIGZuICkge1xyXG5cdGZuWyBleHBhbmRvIF0gPSB0cnVlO1xyXG5cdHJldHVybiBmbjtcclxufVxyXG5cclxuLyoqXHJcbiAqIFN1cHBvcnQgdGVzdGluZyB1c2luZyBhbiBlbGVtZW50XHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIFBhc3NlZCB0aGUgY3JlYXRlZCBkaXYgYW5kIGV4cGVjdHMgYSBib29sZWFuIHJlc3VsdFxyXG4gKi9cclxuZnVuY3Rpb24gYXNzZXJ0KCBmbiApIHtcclxuXHR2YXIgZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcclxuXHJcblx0dHJ5IHtcclxuXHRcdHJldHVybiAhIWZuKCBkaXYgKTtcclxuXHR9IGNhdGNoIChlKSB7XHJcblx0XHRyZXR1cm4gZmFsc2U7XHJcblx0fSBmaW5hbGx5IHtcclxuXHRcdC8vIFJlbW92ZSBmcm9tIGl0cyBwYXJlbnQgYnkgZGVmYXVsdFxyXG5cdFx0aWYgKCBkaXYucGFyZW50Tm9kZSApIHtcclxuXHRcdFx0ZGl2LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQoIGRpdiApO1xyXG5cdFx0fVxyXG5cdFx0Ly8gcmVsZWFzZSBtZW1vcnkgaW4gSUVcclxuXHRcdGRpdiA9IG51bGw7XHJcblx0fVxyXG59XHJcblxyXG4vKipcclxuICogQWRkcyB0aGUgc2FtZSBoYW5kbGVyIGZvciBhbGwgb2YgdGhlIHNwZWNpZmllZCBhdHRyc1xyXG4gKiBAcGFyYW0ge1N0cmluZ30gYXR0cnMgUGlwZS1zZXBhcmF0ZWQgbGlzdCBvZiBhdHRyaWJ1dGVzXHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXIgVGhlIG1ldGhvZCB0aGF0IHdpbGwgYmUgYXBwbGllZFxyXG4gKi9cclxuZnVuY3Rpb24gYWRkSGFuZGxlKCBhdHRycywgaGFuZGxlciApIHtcclxuXHR2YXIgYXJyID0gYXR0cnMuc3BsaXQoXCJ8XCIpLFxyXG5cdFx0aSA9IGFyci5sZW5ndGg7XHJcblxyXG5cdHdoaWxlICggaS0tICkge1xyXG5cdFx0RXhwci5hdHRySGFuZGxlWyBhcnJbaV0gXSA9IGhhbmRsZXI7XHJcblx0fVxyXG59XHJcblxyXG4vKipcclxuICogQ2hlY2tzIGRvY3VtZW50IG9yZGVyIG9mIHR3byBzaWJsaW5nc1xyXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGFcclxuICogQHBhcmFtIHtFbGVtZW50fSBiXHJcbiAqIEByZXR1cm5zIHtOdW1iZXJ9IFJldHVybnMgbGVzcyB0aGFuIDAgaWYgYSBwcmVjZWRlcyBiLCBncmVhdGVyIHRoYW4gMCBpZiBhIGZvbGxvd3MgYlxyXG4gKi9cclxuZnVuY3Rpb24gc2libGluZ0NoZWNrKCBhLCBiICkge1xyXG5cdHZhciBjdXIgPSBiICYmIGEsXHJcblx0XHRkaWZmID0gY3VyICYmIGEubm9kZVR5cGUgPT09IDEgJiYgYi5ub2RlVHlwZSA9PT0gMSAmJlxyXG5cdFx0XHQoIH5iLnNvdXJjZUluZGV4IHx8IE1BWF9ORUdBVElWRSApIC1cclxuXHRcdFx0KCB+YS5zb3VyY2VJbmRleCB8fCBNQVhfTkVHQVRJVkUgKTtcclxuXHJcblx0Ly8gVXNlIElFIHNvdXJjZUluZGV4IGlmIGF2YWlsYWJsZSBvbiBib3RoIG5vZGVzXHJcblx0aWYgKCBkaWZmICkge1xyXG5cdFx0cmV0dXJuIGRpZmY7XHJcblx0fVxyXG5cclxuXHQvLyBDaGVjayBpZiBiIGZvbGxvd3MgYVxyXG5cdGlmICggY3VyICkge1xyXG5cdFx0d2hpbGUgKCAoY3VyID0gY3VyLm5leHRTaWJsaW5nKSApIHtcclxuXHRcdFx0aWYgKCBjdXIgPT09IGIgKSB7XHJcblx0XHRcdFx0cmV0dXJuIC0xO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gYSA/IDEgOiAtMTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgaW5wdXQgdHlwZXNcclxuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcclxuICovXHJcbmZ1bmN0aW9uIGNyZWF0ZUlucHV0UHNldWRvKCB0eXBlICkge1xyXG5cdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0cmV0dXJuIG5hbWUgPT09IFwiaW5wdXRcIiAmJiBlbGVtLnR5cGUgPT09IHR5cGU7XHJcblx0fTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgYnV0dG9uc1xyXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxyXG4gKi9cclxuZnVuY3Rpb24gY3JlYXRlQnV0dG9uUHNldWRvKCB0eXBlICkge1xyXG5cdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0cmV0dXJuIChuYW1lID09PSBcImlucHV0XCIgfHwgbmFtZSA9PT0gXCJidXR0b25cIikgJiYgZWxlbS50eXBlID09PSB0eXBlO1xyXG5cdH07XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdG8gdXNlIGluIHBzZXVkb3MgZm9yIHBvc2l0aW9uYWxzXHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXHJcbiAqL1xyXG5mdW5jdGlvbiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKCBmbiApIHtcclxuXHRyZXR1cm4gbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBhcmd1bWVudCApIHtcclxuXHRcdGFyZ3VtZW50ID0gK2FyZ3VtZW50O1xyXG5cdFx0cmV0dXJuIG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcyApIHtcclxuXHRcdFx0dmFyIGosXHJcblx0XHRcdFx0bWF0Y2hJbmRleGVzID0gZm4oIFtdLCBzZWVkLmxlbmd0aCwgYXJndW1lbnQgKSxcclxuXHRcdFx0XHRpID0gbWF0Y2hJbmRleGVzLmxlbmd0aDtcclxuXHJcblx0XHRcdC8vIE1hdGNoIGVsZW1lbnRzIGZvdW5kIGF0IHRoZSBzcGVjaWZpZWQgaW5kZXhlc1xyXG5cdFx0XHR3aGlsZSAoIGktLSApIHtcclxuXHRcdFx0XHRpZiAoIHNlZWRbIChqID0gbWF0Y2hJbmRleGVzW2ldKSBdICkge1xyXG5cdFx0XHRcdFx0c2VlZFtqXSA9ICEobWF0Y2hlc1tqXSA9IHNlZWRbal0pO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSk7XHJcblx0fSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDaGVja3MgYSBub2RlIGZvciB2YWxpZGl0eSBhcyBhIFNpenpsZSBjb250ZXh0XHJcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3Q9fSBjb250ZXh0XHJcbiAqIEByZXR1cm5zIHtFbGVtZW50fE9iamVjdHxCb29sZWFufSBUaGUgaW5wdXQgbm9kZSBpZiBhY2NlcHRhYmxlLCBvdGhlcndpc2UgYSBmYWxzeSB2YWx1ZVxyXG4gKi9cclxuZnVuY3Rpb24gdGVzdENvbnRleHQoIGNvbnRleHQgKSB7XHJcblx0cmV0dXJuIGNvbnRleHQgJiYgdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09IFwidW5kZWZpbmVkXCIgJiYgY29udGV4dDtcclxufVxyXG5cclxuLy8gRXhwb3NlIHN1cHBvcnQgdmFycyBmb3IgY29udmVuaWVuY2Vcclxuc3VwcG9ydCA9IFNpenpsZS5zdXBwb3J0ID0ge307XHJcblxyXG4vKipcclxuICogRGV0ZWN0cyBYTUwgbm9kZXNcclxuICogQHBhcmFtIHtFbGVtZW50fE9iamVjdH0gZWxlbSBBbiBlbGVtZW50IG9yIGEgZG9jdW1lbnRcclxuICogQHJldHVybnMge0Jvb2xlYW59IFRydWUgaWZmIGVsZW0gaXMgYSBub24tSFRNTCBYTUwgbm9kZVxyXG4gKi9cclxuaXNYTUwgPSBTaXp6bGUuaXNYTUwgPSBmdW5jdGlvbiggZWxlbSApIHtcclxuXHQvLyBkb2N1bWVudEVsZW1lbnQgaXMgdmVyaWZpZWQgZm9yIGNhc2VzIHdoZXJlIGl0IGRvZXNuJ3QgeWV0IGV4aXN0XHJcblx0Ly8gKHN1Y2ggYXMgbG9hZGluZyBpZnJhbWVzIGluIElFIC0gIzQ4MzMpXHJcblx0dmFyIGRvY3VtZW50RWxlbWVudCA9IGVsZW0gJiYgKGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtKS5kb2N1bWVudEVsZW1lbnQ7XHJcblx0cmV0dXJuIGRvY3VtZW50RWxlbWVudCA/IGRvY3VtZW50RWxlbWVudC5ub2RlTmFtZSAhPT0gXCJIVE1MXCIgOiBmYWxzZTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBTZXRzIGRvY3VtZW50LXJlbGF0ZWQgdmFyaWFibGVzIG9uY2UgYmFzZWQgb24gdGhlIGN1cnJlbnQgZG9jdW1lbnRcclxuICogQHBhcmFtIHtFbGVtZW50fE9iamVjdH0gW2RvY10gQW4gZWxlbWVudCBvciBkb2N1bWVudCBvYmplY3QgdG8gdXNlIHRvIHNldCB0aGUgZG9jdW1lbnRcclxuICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyB0aGUgY3VycmVudCBkb2N1bWVudFxyXG4gKi9cclxuc2V0RG9jdW1lbnQgPSBTaXp6bGUuc2V0RG9jdW1lbnQgPSBmdW5jdGlvbiggbm9kZSApIHtcclxuXHR2YXIgaGFzQ29tcGFyZSwgcGFyZW50LFxyXG5cdFx0ZG9jID0gbm9kZSA/IG5vZGUub3duZXJEb2N1bWVudCB8fCBub2RlIDogcHJlZmVycmVkRG9jO1xyXG5cclxuXHQvLyBSZXR1cm4gZWFybHkgaWYgZG9jIGlzIGludmFsaWQgb3IgYWxyZWFkeSBzZWxlY3RlZFxyXG5cdGlmICggZG9jID09PSBkb2N1bWVudCB8fCBkb2Mubm9kZVR5cGUgIT09IDkgfHwgIWRvYy5kb2N1bWVudEVsZW1lbnQgKSB7XHJcblx0XHRyZXR1cm4gZG9jdW1lbnQ7XHJcblx0fVxyXG5cclxuXHQvLyBVcGRhdGUgZ2xvYmFsIHZhcmlhYmxlc1xyXG5cdGRvY3VtZW50ID0gZG9jO1xyXG5cdGRvY0VsZW0gPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XHJcblx0ZG9jdW1lbnRJc0hUTUwgPSAhaXNYTUwoIGRvY3VtZW50ICk7XHJcblxyXG5cdC8vIFN1cHBvcnQ6IElFIDktMTEsIEVkZ2VcclxuXHQvLyBBY2Nlc3NpbmcgaWZyYW1lIGRvY3VtZW50cyBhZnRlciB1bmxvYWQgdGhyb3dzIFwicGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvcnMgKGpRdWVyeSAjMTM5MzYpXHJcblx0aWYgKCAocGFyZW50ID0gZG9jdW1lbnQuZGVmYXVsdFZpZXcpICYmIHBhcmVudC50b3AgIT09IHBhcmVudCApIHtcclxuXHRcdC8vIFN1cHBvcnQ6IElFIDExXHJcblx0XHRpZiAoIHBhcmVudC5hZGRFdmVudExpc3RlbmVyICkge1xyXG5cdFx0XHRwYXJlbnQuYWRkRXZlbnRMaXN0ZW5lciggXCJ1bmxvYWRcIiwgdW5sb2FkSGFuZGxlciwgZmFsc2UgKTtcclxuXHJcblx0XHQvLyBTdXBwb3J0OiBJRSA5IC0gMTAgb25seVxyXG5cdFx0fSBlbHNlIGlmICggcGFyZW50LmF0dGFjaEV2ZW50ICkge1xyXG5cdFx0XHRwYXJlbnQuYXR0YWNoRXZlbnQoIFwib251bmxvYWRcIiwgdW5sb2FkSGFuZGxlciApO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0LyogQXR0cmlidXRlc1xyXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cclxuXHJcblx0Ly8gU3VwcG9ydDogSUU8OFxyXG5cdC8vIFZlcmlmeSB0aGF0IGdldEF0dHJpYnV0ZSByZWFsbHkgcmV0dXJucyBhdHRyaWJ1dGVzIGFuZCBub3QgcHJvcGVydGllc1xyXG5cdC8vIChleGNlcHRpbmcgSUU4IGJvb2xlYW5zKVxyXG5cdHN1cHBvcnQuYXR0cmlidXRlcyA9IGFzc2VydChmdW5jdGlvbiggZGl2ICkge1xyXG5cdFx0ZGl2LmNsYXNzTmFtZSA9IFwiaVwiO1xyXG5cdFx0cmV0dXJuICFkaXYuZ2V0QXR0cmlidXRlKFwiY2xhc3NOYW1lXCIpO1xyXG5cdH0pO1xyXG5cclxuXHQvKiBnZXRFbGVtZW50KHMpQnkqXHJcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xyXG5cclxuXHQvLyBDaGVjayBpZiBnZXRFbGVtZW50c0J5VGFnTmFtZShcIipcIikgcmV0dXJucyBvbmx5IGVsZW1lbnRzXHJcblx0c3VwcG9ydC5nZXRFbGVtZW50c0J5VGFnTmFtZSA9IGFzc2VydChmdW5jdGlvbiggZGl2ICkge1xyXG5cdFx0ZGl2LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVDb21tZW50KFwiXCIpICk7XHJcblx0XHRyZXR1cm4gIWRpdi5nZXRFbGVtZW50c0J5VGFnTmFtZShcIipcIikubGVuZ3RoO1xyXG5cdH0pO1xyXG5cclxuXHQvLyBTdXBwb3J0OiBJRTw5XHJcblx0c3VwcG9ydC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lID0gcm5hdGl2ZS50ZXN0KCBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICk7XHJcblxyXG5cdC8vIFN1cHBvcnQ6IElFPDEwXHJcblx0Ly8gQ2hlY2sgaWYgZ2V0RWxlbWVudEJ5SWQgcmV0dXJucyBlbGVtZW50cyBieSBuYW1lXHJcblx0Ly8gVGhlIGJyb2tlbiBnZXRFbGVtZW50QnlJZCBtZXRob2RzIGRvbid0IHBpY2sgdXAgcHJvZ3JhbWF0aWNhbGx5LXNldCBuYW1lcyxcclxuXHQvLyBzbyB1c2UgYSByb3VuZGFib3V0IGdldEVsZW1lbnRzQnlOYW1lIHRlc3RcclxuXHRzdXBwb3J0LmdldEJ5SWQgPSBhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcclxuXHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGRpdiApLmlkID0gZXhwYW5kbztcclxuXHRcdHJldHVybiAhZG9jdW1lbnQuZ2V0RWxlbWVudHNCeU5hbWUgfHwgIWRvY3VtZW50LmdldEVsZW1lbnRzQnlOYW1lKCBleHBhbmRvICkubGVuZ3RoO1xyXG5cdH0pO1xyXG5cclxuXHQvLyBJRCBmaW5kIGFuZCBmaWx0ZXJcclxuXHRpZiAoIHN1cHBvcnQuZ2V0QnlJZCApIHtcclxuXHRcdEV4cHIuZmluZFtcIklEXCJdID0gZnVuY3Rpb24oIGlkLCBjb250ZXh0ICkge1xyXG5cdFx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRCeUlkICE9PSBcInVuZGVmaW5lZFwiICYmIGRvY3VtZW50SXNIVE1MICkge1xyXG5cdFx0XHRcdHZhciBtID0gY29udGV4dC5nZXRFbGVtZW50QnlJZCggaWQgKTtcclxuXHRcdFx0XHRyZXR1cm4gbSA/IFsgbSBdIDogW107XHJcblx0XHRcdH1cclxuXHRcdH07XHJcblx0XHRFeHByLmZpbHRlcltcIklEXCJdID0gZnVuY3Rpb24oIGlkICkge1xyXG5cdFx0XHR2YXIgYXR0cklkID0gaWQucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcclxuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZShcImlkXCIpID09PSBhdHRySWQ7XHJcblx0XHRcdH07XHJcblx0XHR9O1xyXG5cdH0gZWxzZSB7XHJcblx0XHQvLyBTdXBwb3J0OiBJRTYvN1xyXG5cdFx0Ly8gZ2V0RWxlbWVudEJ5SWQgaXMgbm90IHJlbGlhYmxlIGFzIGEgZmluZCBzaG9ydGN1dFxyXG5cdFx0ZGVsZXRlIEV4cHIuZmluZFtcIklEXCJdO1xyXG5cclxuXHRcdEV4cHIuZmlsdGVyW1wiSURcIl0gPSAgZnVuY3Rpb24oIGlkICkge1xyXG5cdFx0XHR2YXIgYXR0cklkID0gaWQucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcclxuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHRcdHZhciBub2RlID0gdHlwZW9mIGVsZW0uZ2V0QXR0cmlidXRlTm9kZSAhPT0gXCJ1bmRlZmluZWRcIiAmJlxyXG5cdFx0XHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGVOb2RlKFwiaWRcIik7XHJcblx0XHRcdFx0cmV0dXJuIG5vZGUgJiYgbm9kZS52YWx1ZSA9PT0gYXR0cklkO1xyXG5cdFx0XHR9O1xyXG5cdFx0fTtcclxuXHR9XHJcblxyXG5cdC8vIFRhZ1xyXG5cdEV4cHIuZmluZFtcIlRBR1wiXSA9IHN1cHBvcnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgP1xyXG5cdFx0ZnVuY3Rpb24oIHRhZywgY29udGV4dCApIHtcclxuXHRcdFx0aWYgKCB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSAhPT0gXCJ1bmRlZmluZWRcIiApIHtcclxuXHRcdFx0XHRyZXR1cm4gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnICk7XHJcblxyXG5cdFx0XHQvLyBEb2N1bWVudEZyYWdtZW50IG5vZGVzIGRvbid0IGhhdmUgZ0VCVE5cclxuXHRcdFx0fSBlbHNlIGlmICggc3VwcG9ydC5xc2EgKSB7XHJcblx0XHRcdFx0cmV0dXJuIGNvbnRleHQucXVlcnlTZWxlY3RvckFsbCggdGFnICk7XHJcblx0XHRcdH1cclxuXHRcdH0gOlxyXG5cclxuXHRcdGZ1bmN0aW9uKCB0YWcsIGNvbnRleHQgKSB7XHJcblx0XHRcdHZhciBlbGVtLFxyXG5cdFx0XHRcdHRtcCA9IFtdLFxyXG5cdFx0XHRcdGkgPSAwLFxyXG5cdFx0XHRcdC8vIEJ5IGhhcHB5IGNvaW5jaWRlbmNlLCBhIChicm9rZW4pIGdFQlROIGFwcGVhcnMgb24gRG9jdW1lbnRGcmFnbWVudCBub2RlcyB0b29cclxuXHRcdFx0XHRyZXN1bHRzID0gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnICk7XHJcblxyXG5cdFx0XHQvLyBGaWx0ZXIgb3V0IHBvc3NpYmxlIGNvbW1lbnRzXHJcblx0XHRcdGlmICggdGFnID09PSBcIipcIiApIHtcclxuXHRcdFx0XHR3aGlsZSAoIChlbGVtID0gcmVzdWx0c1tpKytdKSApIHtcclxuXHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcclxuXHRcdFx0XHRcdFx0dG1wLnB1c2goIGVsZW0gKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdHJldHVybiB0bXA7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIHJlc3VsdHM7XHJcblx0XHR9O1xyXG5cclxuXHQvLyBDbGFzc1xyXG5cdEV4cHIuZmluZFtcIkNMQVNTXCJdID0gc3VwcG9ydC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lICYmIGZ1bmN0aW9uKCBjbGFzc05hbWUsIGNvbnRleHQgKSB7XHJcblx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgIT09IFwidW5kZWZpbmVkXCIgJiYgZG9jdW1lbnRJc0hUTUwgKSB7XHJcblx0XHRcdHJldHVybiBjb250ZXh0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoIGNsYXNzTmFtZSApO1xyXG5cdFx0fVxyXG5cdH07XHJcblxyXG5cdC8qIFFTQS9tYXRjaGVzU2VsZWN0b3JcclxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXHJcblxyXG5cdC8vIFFTQSBhbmQgbWF0Y2hlc1NlbGVjdG9yIHN1cHBvcnRcclxuXHJcblx0Ly8gbWF0Y2hlc1NlbGVjdG9yKDphY3RpdmUpIHJlcG9ydHMgZmFsc2Ugd2hlbiB0cnVlIChJRTkvT3BlcmEgMTEuNSlcclxuXHRyYnVnZ3lNYXRjaGVzID0gW107XHJcblxyXG5cdC8vIHFTYSg6Zm9jdXMpIHJlcG9ydHMgZmFsc2Ugd2hlbiB0cnVlIChDaHJvbWUgMjEpXHJcblx0Ly8gV2UgYWxsb3cgdGhpcyBiZWNhdXNlIG9mIGEgYnVnIGluIElFOC85IHRoYXQgdGhyb3dzIGFuIGVycm9yXHJcblx0Ly8gd2hlbmV2ZXIgYGRvY3VtZW50LmFjdGl2ZUVsZW1lbnRgIGlzIGFjY2Vzc2VkIG9uIGFuIGlmcmFtZVxyXG5cdC8vIFNvLCB3ZSBhbGxvdyA6Zm9jdXMgdG8gcGFzcyB0aHJvdWdoIFFTQSBhbGwgdGhlIHRpbWUgdG8gYXZvaWQgdGhlIElFIGVycm9yXHJcblx0Ly8gU2VlIGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEzMzc4XHJcblx0cmJ1Z2d5UVNBID0gW107XHJcblxyXG5cdGlmICggKHN1cHBvcnQucXNhID0gcm5hdGl2ZS50ZXN0KCBkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsICkpICkge1xyXG5cdFx0Ly8gQnVpbGQgUVNBIHJlZ2V4XHJcblx0XHQvLyBSZWdleCBzdHJhdGVneSBhZG9wdGVkIGZyb20gRGllZ28gUGVyaW5pXHJcblx0XHRhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcclxuXHRcdFx0Ly8gU2VsZWN0IGlzIHNldCB0byBlbXB0eSBzdHJpbmcgb24gcHVycG9zZVxyXG5cdFx0XHQvLyBUaGlzIGlzIHRvIHRlc3QgSUUncyB0cmVhdG1lbnQgb2Ygbm90IGV4cGxpY2l0bHlcclxuXHRcdFx0Ly8gc2V0dGluZyBhIGJvb2xlYW4gY29udGVudCBhdHRyaWJ1dGUsXHJcblx0XHRcdC8vIHNpbmNlIGl0cyBwcmVzZW5jZSBzaG91bGQgYmUgZW5vdWdoXHJcblx0XHRcdC8vIGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEyMzU5XHJcblx0XHRcdGRvY0VsZW0uYXBwZW5kQ2hpbGQoIGRpdiApLmlubmVySFRNTCA9IFwiPGEgaWQ9J1wiICsgZXhwYW5kbyArIFwiJz48L2E+XCIgK1xyXG5cdFx0XHRcdFwiPHNlbGVjdCBpZD0nXCIgKyBleHBhbmRvICsgXCItXFxyXFxcXCcgbXNhbGxvd2NhcHR1cmU9Jyc+XCIgK1xyXG5cdFx0XHRcdFwiPG9wdGlvbiBzZWxlY3RlZD0nJz48L29wdGlvbj48L3NlbGVjdD5cIjtcclxuXHJcblx0XHRcdC8vIFN1cHBvcnQ6IElFOCwgT3BlcmEgMTEtMTIuMTZcclxuXHRcdFx0Ly8gTm90aGluZyBzaG91bGQgYmUgc2VsZWN0ZWQgd2hlbiBlbXB0eSBzdHJpbmdzIGZvbGxvdyBePSBvciAkPSBvciAqPVxyXG5cdFx0XHQvLyBUaGUgdGVzdCBhdHRyaWJ1dGUgbXVzdCBiZSB1bmtub3duIGluIE9wZXJhIGJ1dCBcInNhZmVcIiBmb3IgV2luUlRcclxuXHRcdFx0Ly8gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2hoNDY1Mzg4LmFzcHgjYXR0cmlidXRlX3NlY3Rpb25cclxuXHRcdFx0aWYgKCBkaXYucXVlcnlTZWxlY3RvckFsbChcIlttc2FsbG93Y2FwdHVyZV49JyddXCIpLmxlbmd0aCApIHtcclxuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJbKl4kXT1cIiArIHdoaXRlc3BhY2UgKyBcIiooPzonJ3xcXFwiXFxcIilcIiApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTdXBwb3J0OiBJRThcclxuXHRcdFx0Ly8gQm9vbGVhbiBhdHRyaWJ1dGVzIGFuZCBcInZhbHVlXCIgYXJlIG5vdCB0cmVhdGVkIGNvcnJlY3RseVxyXG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbChcIltzZWxlY3RlZF1cIikubGVuZ3RoICkge1xyXG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKCBcIlxcXFxbXCIgKyB3aGl0ZXNwYWNlICsgXCIqKD86dmFsdWV8XCIgKyBib29sZWFucyArIFwiKVwiICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZTwyOSwgQW5kcm9pZDw0LjQsIFNhZmFyaTw3LjArLCBpT1M8Ny4wKywgUGhhbnRvbUpTPDEuOS44K1xyXG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbCggXCJbaWR+PVwiICsgZXhwYW5kbyArIFwiLV1cIiApLmxlbmd0aCApIHtcclxuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaChcIn49XCIpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBXZWJraXQvT3BlcmEgLSA6Y2hlY2tlZCBzaG91bGQgcmV0dXJuIHNlbGVjdGVkIG9wdGlvbiBlbGVtZW50c1xyXG5cdFx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDExL1JFQy1jc3MzLXNlbGVjdG9ycy0yMDExMDkyOS8jY2hlY2tlZFxyXG5cdFx0XHQvLyBJRTggdGhyb3dzIGVycm9yIGhlcmUgYW5kIHdpbGwgbm90IHNlZSBsYXRlciB0ZXN0c1xyXG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbChcIjpjaGVja2VkXCIpLmxlbmd0aCApIHtcclxuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaChcIjpjaGVja2VkXCIpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTdXBwb3J0OiBTYWZhcmkgOCssIGlPUyA4K1xyXG5cdFx0XHQvLyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTM2ODUxXHJcblx0XHRcdC8vIEluLXBhZ2UgYHNlbGVjdG9yI2lkIHNpYmluZy1jb21iaW5hdG9yIHNlbGVjdG9yYCBmYWlsc1xyXG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbCggXCJhI1wiICsgZXhwYW5kbyArIFwiKypcIiApLmxlbmd0aCApIHtcclxuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaChcIi4jLitbK35dXCIpO1xyXG5cdFx0XHR9XHJcblx0XHR9KTtcclxuXHJcblx0XHRhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcclxuXHRcdFx0Ly8gU3VwcG9ydDogV2luZG93cyA4IE5hdGl2ZSBBcHBzXHJcblx0XHRcdC8vIFRoZSB0eXBlIGFuZCBuYW1lIGF0dHJpYnV0ZXMgYXJlIHJlc3RyaWN0ZWQgZHVyaW5nIC5pbm5lckhUTUwgYXNzaWdubWVudFxyXG5cdFx0XHR2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiaW5wdXRcIik7XHJcblx0XHRcdGlucHV0LnNldEF0dHJpYnV0ZSggXCJ0eXBlXCIsIFwiaGlkZGVuXCIgKTtcclxuXHRcdFx0ZGl2LmFwcGVuZENoaWxkKCBpbnB1dCApLnNldEF0dHJpYnV0ZSggXCJuYW1lXCIsIFwiRFwiICk7XHJcblxyXG5cdFx0XHQvLyBTdXBwb3J0OiBJRThcclxuXHRcdFx0Ly8gRW5mb3JjZSBjYXNlLXNlbnNpdGl2aXR5IG9mIG5hbWUgYXR0cmlidXRlXHJcblx0XHRcdGlmICggZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoXCJbbmFtZT1kXVwiKS5sZW5ndGggKSB7XHJcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwibmFtZVwiICsgd2hpdGVzcGFjZSArIFwiKlsqXiR8IX5dPz1cIiApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBGRiAzLjUgLSA6ZW5hYmxlZC86ZGlzYWJsZWQgYW5kIGhpZGRlbiBlbGVtZW50cyAoaGlkZGVuIGVsZW1lbnRzIGFyZSBzdGlsbCBlbmFibGVkKVxyXG5cdFx0XHQvLyBJRTggdGhyb3dzIGVycm9yIGhlcmUgYW5kIHdpbGwgbm90IHNlZSBsYXRlciB0ZXN0c1xyXG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbChcIjplbmFibGVkXCIpLmxlbmd0aCApIHtcclxuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCI6ZW5hYmxlZFwiLCBcIjpkaXNhYmxlZFwiICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIE9wZXJhIDEwLTExIGRvZXMgbm90IHRocm93IG9uIHBvc3QtY29tbWEgaW52YWxpZCBwc2V1ZG9zXHJcblx0XHRcdGRpdi5xdWVyeVNlbGVjdG9yQWxsKFwiKiw6eFwiKTtcclxuXHRcdFx0cmJ1Z2d5UVNBLnB1c2goXCIsLio6XCIpO1xyXG5cdFx0fSk7XHJcblx0fVxyXG5cclxuXHRpZiAoIChzdXBwb3J0Lm1hdGNoZXNTZWxlY3RvciA9IHJuYXRpdmUudGVzdCggKG1hdGNoZXMgPSBkb2NFbGVtLm1hdGNoZXMgfHxcclxuXHRcdGRvY0VsZW0ud2Via2l0TWF0Y2hlc1NlbGVjdG9yIHx8XHJcblx0XHRkb2NFbGVtLm1vek1hdGNoZXNTZWxlY3RvciB8fFxyXG5cdFx0ZG9jRWxlbS5vTWF0Y2hlc1NlbGVjdG9yIHx8XHJcblx0XHRkb2NFbGVtLm1zTWF0Y2hlc1NlbGVjdG9yKSApKSApIHtcclxuXHJcblx0XHRhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcclxuXHRcdFx0Ly8gQ2hlY2sgdG8gc2VlIGlmIGl0J3MgcG9zc2libGUgdG8gZG8gbWF0Y2hlc1NlbGVjdG9yXHJcblx0XHRcdC8vIG9uIGEgZGlzY29ubmVjdGVkIG5vZGUgKElFIDkpXHJcblx0XHRcdHN1cHBvcnQuZGlzY29ubmVjdGVkTWF0Y2ggPSBtYXRjaGVzLmNhbGwoIGRpdiwgXCJkaXZcIiApO1xyXG5cclxuXHRcdFx0Ly8gVGhpcyBzaG91bGQgZmFpbCB3aXRoIGFuIGV4Y2VwdGlvblxyXG5cdFx0XHQvLyBHZWNrbyBkb2VzIG5vdCBlcnJvciwgcmV0dXJucyBmYWxzZSBpbnN0ZWFkXHJcblx0XHRcdG1hdGNoZXMuY2FsbCggZGl2LCBcIltzIT0nJ106eFwiICk7XHJcblx0XHRcdHJidWdneU1hdGNoZXMucHVzaCggXCIhPVwiLCBwc2V1ZG9zICk7XHJcblx0XHR9KTtcclxuXHR9XHJcblxyXG5cdHJidWdneVFTQSA9IHJidWdneVFTQS5sZW5ndGggJiYgbmV3IFJlZ0V4cCggcmJ1Z2d5UVNBLmpvaW4oXCJ8XCIpICk7XHJcblx0cmJ1Z2d5TWF0Y2hlcyA9IHJidWdneU1hdGNoZXMubGVuZ3RoICYmIG5ldyBSZWdFeHAoIHJidWdneU1hdGNoZXMuam9pbihcInxcIikgKTtcclxuXHJcblx0LyogQ29udGFpbnNcclxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXHJcblx0aGFzQ29tcGFyZSA9IHJuYXRpdmUudGVzdCggZG9jRWxlbS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiApO1xyXG5cclxuXHQvLyBFbGVtZW50IGNvbnRhaW5zIGFub3RoZXJcclxuXHQvLyBQdXJwb3NlZnVsbHkgc2VsZi1leGNsdXNpdmVcclxuXHQvLyBBcyBpbiwgYW4gZWxlbWVudCBkb2VzIG5vdCBjb250YWluIGl0c2VsZlxyXG5cdGNvbnRhaW5zID0gaGFzQ29tcGFyZSB8fCBybmF0aXZlLnRlc3QoIGRvY0VsZW0uY29udGFpbnMgKSA/XHJcblx0XHRmdW5jdGlvbiggYSwgYiApIHtcclxuXHRcdFx0dmFyIGFkb3duID0gYS5ub2RlVHlwZSA9PT0gOSA/IGEuZG9jdW1lbnRFbGVtZW50IDogYSxcclxuXHRcdFx0XHRidXAgPSBiICYmIGIucGFyZW50Tm9kZTtcclxuXHRcdFx0cmV0dXJuIGEgPT09IGJ1cCB8fCAhISggYnVwICYmIGJ1cC5ub2RlVHlwZSA9PT0gMSAmJiAoXHJcblx0XHRcdFx0YWRvd24uY29udGFpbnMgP1xyXG5cdFx0XHRcdFx0YWRvd24uY29udGFpbnMoIGJ1cCApIDpcclxuXHRcdFx0XHRcdGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24gJiYgYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggYnVwICkgJiAxNlxyXG5cdFx0XHQpKTtcclxuXHRcdH0gOlxyXG5cdFx0ZnVuY3Rpb24oIGEsIGIgKSB7XHJcblx0XHRcdGlmICggYiApIHtcclxuXHRcdFx0XHR3aGlsZSAoIChiID0gYi5wYXJlbnROb2RlKSApIHtcclxuXHRcdFx0XHRcdGlmICggYiA9PT0gYSApIHtcclxuXHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdH07XHJcblxyXG5cdC8qIFNvcnRpbmdcclxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXHJcblxyXG5cdC8vIERvY3VtZW50IG9yZGVyIHNvcnRpbmdcclxuXHRzb3J0T3JkZXIgPSBoYXNDb21wYXJlID9cclxuXHRmdW5jdGlvbiggYSwgYiApIHtcclxuXHJcblx0XHQvLyBGbGFnIGZvciBkdXBsaWNhdGUgcmVtb3ZhbFxyXG5cdFx0aWYgKCBhID09PSBiICkge1xyXG5cdFx0XHRoYXNEdXBsaWNhdGUgPSB0cnVlO1xyXG5cdFx0XHRyZXR1cm4gMDtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBTb3J0IG9uIG1ldGhvZCBleGlzdGVuY2UgaWYgb25seSBvbmUgaW5wdXQgaGFzIGNvbXBhcmVEb2N1bWVudFBvc2l0aW9uXHJcblx0XHR2YXIgY29tcGFyZSA9ICFhLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uIC0gIWIuY29tcGFyZURvY3VtZW50UG9zaXRpb247XHJcblx0XHRpZiAoIGNvbXBhcmUgKSB7XHJcblx0XHRcdHJldHVybiBjb21wYXJlO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIENhbGN1bGF0ZSBwb3NpdGlvbiBpZiBib3RoIGlucHV0cyBiZWxvbmcgdG8gdGhlIHNhbWUgZG9jdW1lbnRcclxuXHRcdGNvbXBhcmUgPSAoIGEub3duZXJEb2N1bWVudCB8fCBhICkgPT09ICggYi5vd25lckRvY3VtZW50IHx8IGIgKSA/XHJcblx0XHRcdGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24oIGIgKSA6XHJcblxyXG5cdFx0XHQvLyBPdGhlcndpc2Ugd2Uga25vdyB0aGV5IGFyZSBkaXNjb25uZWN0ZWRcclxuXHRcdFx0MTtcclxuXHJcblx0XHQvLyBEaXNjb25uZWN0ZWQgbm9kZXNcclxuXHRcdGlmICggY29tcGFyZSAmIDEgfHxcclxuXHRcdFx0KCFzdXBwb3J0LnNvcnREZXRhY2hlZCAmJiBiLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBhICkgPT09IGNvbXBhcmUpICkge1xyXG5cclxuXHRcdFx0Ly8gQ2hvb3NlIHRoZSBmaXJzdCBlbGVtZW50IHRoYXQgaXMgcmVsYXRlZCB0byBvdXIgcHJlZmVycmVkIGRvY3VtZW50XHJcblx0XHRcdGlmICggYSA9PT0gZG9jdW1lbnQgfHwgYS5vd25lckRvY3VtZW50ID09PSBwcmVmZXJyZWREb2MgJiYgY29udGFpbnMocHJlZmVycmVkRG9jLCBhKSApIHtcclxuXHRcdFx0XHRyZXR1cm4gLTE7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCBiID09PSBkb2N1bWVudCB8fCBiLm93bmVyRG9jdW1lbnQgPT09IHByZWZlcnJlZERvYyAmJiBjb250YWlucyhwcmVmZXJyZWREb2MsIGIpICkge1xyXG5cdFx0XHRcdHJldHVybiAxO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBNYWludGFpbiBvcmlnaW5hbCBvcmRlclxyXG5cdFx0XHRyZXR1cm4gc29ydElucHV0ID9cclxuXHRcdFx0XHQoIGluZGV4T2YoIHNvcnRJbnB1dCwgYSApIC0gaW5kZXhPZiggc29ydElucHV0LCBiICkgKSA6XHJcblx0XHRcdFx0MDtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gY29tcGFyZSAmIDQgPyAtMSA6IDE7XHJcblx0fSA6XHJcblx0ZnVuY3Rpb24oIGEsIGIgKSB7XHJcblx0XHQvLyBFeGl0IGVhcmx5IGlmIHRoZSBub2RlcyBhcmUgaWRlbnRpY2FsXHJcblx0XHRpZiAoIGEgPT09IGIgKSB7XHJcblx0XHRcdGhhc0R1cGxpY2F0ZSA9IHRydWU7XHJcblx0XHRcdHJldHVybiAwO1xyXG5cdFx0fVxyXG5cclxuXHRcdHZhciBjdXIsXHJcblx0XHRcdGkgPSAwLFxyXG5cdFx0XHRhdXAgPSBhLnBhcmVudE5vZGUsXHJcblx0XHRcdGJ1cCA9IGIucGFyZW50Tm9kZSxcclxuXHRcdFx0YXAgPSBbIGEgXSxcclxuXHRcdFx0YnAgPSBbIGIgXTtcclxuXHJcblx0XHQvLyBQYXJlbnRsZXNzIG5vZGVzIGFyZSBlaXRoZXIgZG9jdW1lbnRzIG9yIGRpc2Nvbm5lY3RlZFxyXG5cdFx0aWYgKCAhYXVwIHx8ICFidXAgKSB7XHJcblx0XHRcdHJldHVybiBhID09PSBkb2N1bWVudCA/IC0xIDpcclxuXHRcdFx0XHRiID09PSBkb2N1bWVudCA/IDEgOlxyXG5cdFx0XHRcdGF1cCA/IC0xIDpcclxuXHRcdFx0XHRidXAgPyAxIDpcclxuXHRcdFx0XHRzb3J0SW5wdXQgP1xyXG5cdFx0XHRcdCggaW5kZXhPZiggc29ydElucHV0LCBhICkgLSBpbmRleE9mKCBzb3J0SW5wdXQsIGIgKSApIDpcclxuXHRcdFx0XHQwO1xyXG5cclxuXHRcdC8vIElmIHRoZSBub2RlcyBhcmUgc2libGluZ3MsIHdlIGNhbiBkbyBhIHF1aWNrIGNoZWNrXHJcblx0XHR9IGVsc2UgaWYgKCBhdXAgPT09IGJ1cCApIHtcclxuXHRcdFx0cmV0dXJuIHNpYmxpbmdDaGVjayggYSwgYiApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIE90aGVyd2lzZSB3ZSBuZWVkIGZ1bGwgbGlzdHMgb2YgdGhlaXIgYW5jZXN0b3JzIGZvciBjb21wYXJpc29uXHJcblx0XHRjdXIgPSBhO1xyXG5cdFx0d2hpbGUgKCAoY3VyID0gY3VyLnBhcmVudE5vZGUpICkge1xyXG5cdFx0XHRhcC51bnNoaWZ0KCBjdXIgKTtcclxuXHRcdH1cclxuXHRcdGN1ciA9IGI7XHJcblx0XHR3aGlsZSAoIChjdXIgPSBjdXIucGFyZW50Tm9kZSkgKSB7XHJcblx0XHRcdGJwLnVuc2hpZnQoIGN1ciApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFdhbGsgZG93biB0aGUgdHJlZSBsb29raW5nIGZvciBhIGRpc2NyZXBhbmN5XHJcblx0XHR3aGlsZSAoIGFwW2ldID09PSBicFtpXSApIHtcclxuXHRcdFx0aSsrO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBpID9cclxuXHRcdFx0Ly8gRG8gYSBzaWJsaW5nIGNoZWNrIGlmIHRoZSBub2RlcyBoYXZlIGEgY29tbW9uIGFuY2VzdG9yXHJcblx0XHRcdHNpYmxpbmdDaGVjayggYXBbaV0sIGJwW2ldICkgOlxyXG5cclxuXHRcdFx0Ly8gT3RoZXJ3aXNlIG5vZGVzIGluIG91ciBkb2N1bWVudCBzb3J0IGZpcnN0XHJcblx0XHRcdGFwW2ldID09PSBwcmVmZXJyZWREb2MgPyAtMSA6XHJcblx0XHRcdGJwW2ldID09PSBwcmVmZXJyZWREb2MgPyAxIDpcclxuXHRcdFx0MDtcclxuXHR9O1xyXG5cclxuXHRyZXR1cm4gZG9jdW1lbnQ7XHJcbn07XHJcblxyXG5TaXp6bGUubWF0Y2hlcyA9IGZ1bmN0aW9uKCBleHByLCBlbGVtZW50cyApIHtcclxuXHRyZXR1cm4gU2l6emxlKCBleHByLCBudWxsLCBudWxsLCBlbGVtZW50cyApO1xyXG59O1xyXG5cclxuU2l6emxlLm1hdGNoZXNTZWxlY3RvciA9IGZ1bmN0aW9uKCBlbGVtLCBleHByICkge1xyXG5cdC8vIFNldCBkb2N1bWVudCB2YXJzIGlmIG5lZWRlZFxyXG5cdGlmICggKCBlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSApICE9PSBkb2N1bWVudCApIHtcclxuXHRcdHNldERvY3VtZW50KCBlbGVtICk7XHJcblx0fVxyXG5cclxuXHQvLyBNYWtlIHN1cmUgdGhhdCBhdHRyaWJ1dGUgc2VsZWN0b3JzIGFyZSBxdW90ZWRcclxuXHRleHByID0gZXhwci5yZXBsYWNlKCByYXR0cmlidXRlUXVvdGVzLCBcIj0nJDEnXVwiICk7XHJcblxyXG5cdGlmICggc3VwcG9ydC5tYXRjaGVzU2VsZWN0b3IgJiYgZG9jdW1lbnRJc0hUTUwgJiZcclxuXHRcdCFjb21waWxlckNhY2hlWyBleHByICsgXCIgXCIgXSAmJlxyXG5cdFx0KCAhcmJ1Z2d5TWF0Y2hlcyB8fCAhcmJ1Z2d5TWF0Y2hlcy50ZXN0KCBleHByICkgKSAmJlxyXG5cdFx0KCAhcmJ1Z2d5UVNBICAgICB8fCAhcmJ1Z2d5UVNBLnRlc3QoIGV4cHIgKSApICkge1xyXG5cclxuXHRcdHRyeSB7XHJcblx0XHRcdHZhciByZXQgPSBtYXRjaGVzLmNhbGwoIGVsZW0sIGV4cHIgKTtcclxuXHJcblx0XHRcdC8vIElFIDkncyBtYXRjaGVzU2VsZWN0b3IgcmV0dXJucyBmYWxzZSBvbiBkaXNjb25uZWN0ZWQgbm9kZXNcclxuXHRcdFx0aWYgKCByZXQgfHwgc3VwcG9ydC5kaXNjb25uZWN0ZWRNYXRjaCB8fFxyXG5cdFx0XHRcdFx0Ly8gQXMgd2VsbCwgZGlzY29ubmVjdGVkIG5vZGVzIGFyZSBzYWlkIHRvIGJlIGluIGEgZG9jdW1lbnRcclxuXHRcdFx0XHRcdC8vIGZyYWdtZW50IGluIElFIDlcclxuXHRcdFx0XHRcdGVsZW0uZG9jdW1lbnQgJiYgZWxlbS5kb2N1bWVudC5ub2RlVHlwZSAhPT0gMTEgKSB7XHJcblx0XHRcdFx0cmV0dXJuIHJldDtcclxuXHRcdFx0fVxyXG5cdFx0fSBjYXRjaCAoZSkge31cclxuXHR9XHJcblxyXG5cdHJldHVybiBTaXp6bGUoIGV4cHIsIGRvY3VtZW50LCBudWxsLCBbIGVsZW0gXSApLmxlbmd0aCA+IDA7XHJcbn07XHJcblxyXG5TaXp6bGUuY29udGFpbnMgPSBmdW5jdGlvbiggY29udGV4dCwgZWxlbSApIHtcclxuXHQvLyBTZXQgZG9jdW1lbnQgdmFycyBpZiBuZWVkZWRcclxuXHRpZiAoICggY29udGV4dC5vd25lckRvY3VtZW50IHx8IGNvbnRleHQgKSAhPT0gZG9jdW1lbnQgKSB7XHJcblx0XHRzZXREb2N1bWVudCggY29udGV4dCApO1xyXG5cdH1cclxuXHRyZXR1cm4gY29udGFpbnMoIGNvbnRleHQsIGVsZW0gKTtcclxufTtcclxuXHJcblNpenpsZS5hdHRyID0gZnVuY3Rpb24oIGVsZW0sIG5hbWUgKSB7XHJcblx0Ly8gU2V0IGRvY3VtZW50IHZhcnMgaWYgbmVlZGVkXHJcblx0aWYgKCAoIGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtICkgIT09IGRvY3VtZW50ICkge1xyXG5cdFx0c2V0RG9jdW1lbnQoIGVsZW0gKTtcclxuXHR9XHJcblxyXG5cdHZhciBmbiA9IEV4cHIuYXR0ckhhbmRsZVsgbmFtZS50b0xvd2VyQ2FzZSgpIF0sXHJcblx0XHQvLyBEb24ndCBnZXQgZm9vbGVkIGJ5IE9iamVjdC5wcm90b3R5cGUgcHJvcGVydGllcyAoalF1ZXJ5ICMxMzgwNylcclxuXHRcdHZhbCA9IGZuICYmIGhhc093bi5jYWxsKCBFeHByLmF0dHJIYW5kbGUsIG5hbWUudG9Mb3dlckNhc2UoKSApID9cclxuXHRcdFx0Zm4oIGVsZW0sIG5hbWUsICFkb2N1bWVudElzSFRNTCApIDpcclxuXHRcdFx0dW5kZWZpbmVkO1xyXG5cclxuXHRyZXR1cm4gdmFsICE9PSB1bmRlZmluZWQgP1xyXG5cdFx0dmFsIDpcclxuXHRcdHN1cHBvcnQuYXR0cmlidXRlcyB8fCAhZG9jdW1lbnRJc0hUTUwgP1xyXG5cdFx0XHRlbGVtLmdldEF0dHJpYnV0ZSggbmFtZSApIDpcclxuXHRcdFx0KHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZShuYW1lKSkgJiYgdmFsLnNwZWNpZmllZCA/XHJcblx0XHRcdFx0dmFsLnZhbHVlIDpcclxuXHRcdFx0XHRudWxsO1xyXG59O1xyXG5cclxuU2l6emxlLmVycm9yID0gZnVuY3Rpb24oIG1zZyApIHtcclxuXHR0aHJvdyBuZXcgRXJyb3IoIFwiU3ludGF4IGVycm9yLCB1bnJlY29nbml6ZWQgZXhwcmVzc2lvbjogXCIgKyBtc2cgKTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBEb2N1bWVudCBzb3J0aW5nIGFuZCByZW1vdmluZyBkdXBsaWNhdGVzXHJcbiAqIEBwYXJhbSB7QXJyYXlMaWtlfSByZXN1bHRzXHJcbiAqL1xyXG5TaXp6bGUudW5pcXVlU29ydCA9IGZ1bmN0aW9uKCByZXN1bHRzICkge1xyXG5cdHZhciBlbGVtLFxyXG5cdFx0ZHVwbGljYXRlcyA9IFtdLFxyXG5cdFx0aiA9IDAsXHJcblx0XHRpID0gMDtcclxuXHJcblx0Ly8gVW5sZXNzIHdlICprbm93KiB3ZSBjYW4gZGV0ZWN0IGR1cGxpY2F0ZXMsIGFzc3VtZSB0aGVpciBwcmVzZW5jZVxyXG5cdGhhc0R1cGxpY2F0ZSA9ICFzdXBwb3J0LmRldGVjdER1cGxpY2F0ZXM7XHJcblx0c29ydElucHV0ID0gIXN1cHBvcnQuc29ydFN0YWJsZSAmJiByZXN1bHRzLnNsaWNlKCAwICk7XHJcblx0cmVzdWx0cy5zb3J0KCBzb3J0T3JkZXIgKTtcclxuXHJcblx0aWYgKCBoYXNEdXBsaWNhdGUgKSB7XHJcblx0XHR3aGlsZSAoIChlbGVtID0gcmVzdWx0c1tpKytdKSApIHtcclxuXHRcdFx0aWYgKCBlbGVtID09PSByZXN1bHRzWyBpIF0gKSB7XHJcblx0XHRcdFx0aiA9IGR1cGxpY2F0ZXMucHVzaCggaSApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHR3aGlsZSAoIGotLSApIHtcclxuXHRcdFx0cmVzdWx0cy5zcGxpY2UoIGR1cGxpY2F0ZXNbIGogXSwgMSApO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0Ly8gQ2xlYXIgaW5wdXQgYWZ0ZXIgc29ydGluZyB0byByZWxlYXNlIG9iamVjdHNcclxuXHQvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9zaXp6bGUvcHVsbC8yMjVcclxuXHRzb3J0SW5wdXQgPSBudWxsO1xyXG5cclxuXHRyZXR1cm4gcmVzdWx0cztcclxufTtcclxuXHJcbi8qKlxyXG4gKiBVdGlsaXR5IGZ1bmN0aW9uIGZvciByZXRyaWV2aW5nIHRoZSB0ZXh0IHZhbHVlIG9mIGFuIGFycmF5IG9mIERPTSBub2Rlc1xyXG4gKiBAcGFyYW0ge0FycmF5fEVsZW1lbnR9IGVsZW1cclxuICovXHJcbmdldFRleHQgPSBTaXp6bGUuZ2V0VGV4dCA9IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdHZhciBub2RlLFxyXG5cdFx0cmV0ID0gXCJcIixcclxuXHRcdGkgPSAwLFxyXG5cdFx0bm9kZVR5cGUgPSBlbGVtLm5vZGVUeXBlO1xyXG5cclxuXHRpZiAoICFub2RlVHlwZSApIHtcclxuXHRcdC8vIElmIG5vIG5vZGVUeXBlLCB0aGlzIGlzIGV4cGVjdGVkIHRvIGJlIGFuIGFycmF5XHJcblx0XHR3aGlsZSAoIChub2RlID0gZWxlbVtpKytdKSApIHtcclxuXHRcdFx0Ly8gRG8gbm90IHRyYXZlcnNlIGNvbW1lbnQgbm9kZXNcclxuXHRcdFx0cmV0ICs9IGdldFRleHQoIG5vZGUgKTtcclxuXHRcdH1cclxuXHR9IGVsc2UgaWYgKCBub2RlVHlwZSA9PT0gMSB8fCBub2RlVHlwZSA9PT0gOSB8fCBub2RlVHlwZSA9PT0gMTEgKSB7XHJcblx0XHQvLyBVc2UgdGV4dENvbnRlbnQgZm9yIGVsZW1lbnRzXHJcblx0XHQvLyBpbm5lclRleHQgdXNhZ2UgcmVtb3ZlZCBmb3IgY29uc2lzdGVuY3kgb2YgbmV3IGxpbmVzIChqUXVlcnkgIzExMTUzKVxyXG5cdFx0aWYgKCB0eXBlb2YgZWxlbS50ZXh0Q29udGVudCA9PT0gXCJzdHJpbmdcIiApIHtcclxuXHRcdFx0cmV0dXJuIGVsZW0udGV4dENvbnRlbnQ7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHQvLyBUcmF2ZXJzZSBpdHMgY2hpbGRyZW5cclxuXHRcdFx0Zm9yICggZWxlbSA9IGVsZW0uZmlyc3RDaGlsZDsgZWxlbTsgZWxlbSA9IGVsZW0ubmV4dFNpYmxpbmcgKSB7XHJcblx0XHRcdFx0cmV0ICs9IGdldFRleHQoIGVsZW0gKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0gZWxzZSBpZiAoIG5vZGVUeXBlID09PSAzIHx8IG5vZGVUeXBlID09PSA0ICkge1xyXG5cdFx0cmV0dXJuIGVsZW0ubm9kZVZhbHVlO1xyXG5cdH1cclxuXHQvLyBEbyBub3QgaW5jbHVkZSBjb21tZW50IG9yIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gbm9kZXNcclxuXHJcblx0cmV0dXJuIHJldDtcclxufTtcclxuXHJcbkV4cHIgPSBTaXp6bGUuc2VsZWN0b3JzID0ge1xyXG5cclxuXHQvLyBDYW4gYmUgYWRqdXN0ZWQgYnkgdGhlIHVzZXJcclxuXHRjYWNoZUxlbmd0aDogNTAsXHJcblxyXG5cdGNyZWF0ZVBzZXVkbzogbWFya0Z1bmN0aW9uLFxyXG5cclxuXHRtYXRjaDogbWF0Y2hFeHByLFxyXG5cclxuXHRhdHRySGFuZGxlOiB7fSxcclxuXHJcblx0ZmluZDoge30sXHJcblxyXG5cdHJlbGF0aXZlOiB7XHJcblx0XHRcIj5cIjogeyBkaXI6IFwicGFyZW50Tm9kZVwiLCBmaXJzdDogdHJ1ZSB9LFxyXG5cdFx0XCIgXCI6IHsgZGlyOiBcInBhcmVudE5vZGVcIiB9LFxyXG5cdFx0XCIrXCI6IHsgZGlyOiBcInByZXZpb3VzU2libGluZ1wiLCBmaXJzdDogdHJ1ZSB9LFxyXG5cdFx0XCJ+XCI6IHsgZGlyOiBcInByZXZpb3VzU2libGluZ1wiIH1cclxuXHR9LFxyXG5cclxuXHRwcmVGaWx0ZXI6IHtcclxuXHRcdFwiQVRUUlwiOiBmdW5jdGlvbiggbWF0Y2ggKSB7XHJcblx0XHRcdG1hdGNoWzFdID0gbWF0Y2hbMV0ucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcclxuXHJcblx0XHRcdC8vIE1vdmUgdGhlIGdpdmVuIHZhbHVlIHRvIG1hdGNoWzNdIHdoZXRoZXIgcXVvdGVkIG9yIHVucXVvdGVkXHJcblx0XHRcdG1hdGNoWzNdID0gKCBtYXRjaFszXSB8fCBtYXRjaFs0XSB8fCBtYXRjaFs1XSB8fCBcIlwiICkucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcclxuXHJcblx0XHRcdGlmICggbWF0Y2hbMl0gPT09IFwifj1cIiApIHtcclxuXHRcdFx0XHRtYXRjaFszXSA9IFwiIFwiICsgbWF0Y2hbM10gKyBcIiBcIjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIG1hdGNoLnNsaWNlKCAwLCA0ICk7XHJcblx0XHR9LFxyXG5cclxuXHRcdFwiQ0hJTERcIjogZnVuY3Rpb24oIG1hdGNoICkge1xyXG5cdFx0XHQvKiBtYXRjaGVzIGZyb20gbWF0Y2hFeHByW1wiQ0hJTERcIl1cclxuXHRcdFx0XHQxIHR5cGUgKG9ubHl8bnRofC4uLilcclxuXHRcdFx0XHQyIHdoYXQgKGNoaWxkfG9mLXR5cGUpXHJcblx0XHRcdFx0MyBhcmd1bWVudCAoZXZlbnxvZGR8XFxkKnxcXGQqbihbKy1dXFxkKyk/fC4uLilcclxuXHRcdFx0XHQ0IHhuLWNvbXBvbmVudCBvZiB4bit5IGFyZ3VtZW50IChbKy1dP1xcZCpufClcclxuXHRcdFx0XHQ1IHNpZ24gb2YgeG4tY29tcG9uZW50XHJcblx0XHRcdFx0NiB4IG9mIHhuLWNvbXBvbmVudFxyXG5cdFx0XHRcdDcgc2lnbiBvZiB5LWNvbXBvbmVudFxyXG5cdFx0XHRcdDggeSBvZiB5LWNvbXBvbmVudFxyXG5cdFx0XHQqL1xyXG5cdFx0XHRtYXRjaFsxXSA9IG1hdGNoWzFdLnRvTG93ZXJDYXNlKCk7XHJcblxyXG5cdFx0XHRpZiAoIG1hdGNoWzFdLnNsaWNlKCAwLCAzICkgPT09IFwibnRoXCIgKSB7XHJcblx0XHRcdFx0Ly8gbnRoLSogcmVxdWlyZXMgYXJndW1lbnRcclxuXHRcdFx0XHRpZiAoICFtYXRjaFszXSApIHtcclxuXHRcdFx0XHRcdFNpenpsZS5lcnJvciggbWF0Y2hbMF0gKTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIG51bWVyaWMgeCBhbmQgeSBwYXJhbWV0ZXJzIGZvciBFeHByLmZpbHRlci5DSElMRFxyXG5cdFx0XHRcdC8vIHJlbWVtYmVyIHRoYXQgZmFsc2UvdHJ1ZSBjYXN0IHJlc3BlY3RpdmVseSB0byAwLzFcclxuXHRcdFx0XHRtYXRjaFs0XSA9ICsoIG1hdGNoWzRdID8gbWF0Y2hbNV0gKyAobWF0Y2hbNl0gfHwgMSkgOiAyICogKCBtYXRjaFszXSA9PT0gXCJldmVuXCIgfHwgbWF0Y2hbM10gPT09IFwib2RkXCIgKSApO1xyXG5cdFx0XHRcdG1hdGNoWzVdID0gKyggKCBtYXRjaFs3XSArIG1hdGNoWzhdICkgfHwgbWF0Y2hbM10gPT09IFwib2RkXCIgKTtcclxuXHJcblx0XHRcdC8vIG90aGVyIHR5cGVzIHByb2hpYml0IGFyZ3VtZW50c1xyXG5cdFx0XHR9IGVsc2UgaWYgKCBtYXRjaFszXSApIHtcclxuXHRcdFx0XHRTaXp6bGUuZXJyb3IoIG1hdGNoWzBdICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHJldHVybiBtYXRjaDtcclxuXHRcdH0sXHJcblxyXG5cdFx0XCJQU0VVRE9cIjogZnVuY3Rpb24oIG1hdGNoICkge1xyXG5cdFx0XHR2YXIgZXhjZXNzLFxyXG5cdFx0XHRcdHVucXVvdGVkID0gIW1hdGNoWzZdICYmIG1hdGNoWzJdO1xyXG5cclxuXHRcdFx0aWYgKCBtYXRjaEV4cHJbXCJDSElMRFwiXS50ZXN0KCBtYXRjaFswXSApICkge1xyXG5cdFx0XHRcdHJldHVybiBudWxsO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBBY2NlcHQgcXVvdGVkIGFyZ3VtZW50cyBhcy1pc1xyXG5cdFx0XHRpZiAoIG1hdGNoWzNdICkge1xyXG5cdFx0XHRcdG1hdGNoWzJdID0gbWF0Y2hbNF0gfHwgbWF0Y2hbNV0gfHwgXCJcIjtcclxuXHJcblx0XHRcdC8vIFN0cmlwIGV4Y2VzcyBjaGFyYWN0ZXJzIGZyb20gdW5xdW90ZWQgYXJndW1lbnRzXHJcblx0XHRcdH0gZWxzZSBpZiAoIHVucXVvdGVkICYmIHJwc2V1ZG8udGVzdCggdW5xdW90ZWQgKSAmJlxyXG5cdFx0XHRcdC8vIEdldCBleGNlc3MgZnJvbSB0b2tlbml6ZSAocmVjdXJzaXZlbHkpXHJcblx0XHRcdFx0KGV4Y2VzcyA9IHRva2VuaXplKCB1bnF1b3RlZCwgdHJ1ZSApKSAmJlxyXG5cdFx0XHRcdC8vIGFkdmFuY2UgdG8gdGhlIG5leHQgY2xvc2luZyBwYXJlbnRoZXNpc1xyXG5cdFx0XHRcdChleGNlc3MgPSB1bnF1b3RlZC5pbmRleE9mKCBcIilcIiwgdW5xdW90ZWQubGVuZ3RoIC0gZXhjZXNzICkgLSB1bnF1b3RlZC5sZW5ndGgpICkge1xyXG5cclxuXHRcdFx0XHQvLyBleGNlc3MgaXMgYSBuZWdhdGl2ZSBpbmRleFxyXG5cdFx0XHRcdG1hdGNoWzBdID0gbWF0Y2hbMF0uc2xpY2UoIDAsIGV4Y2VzcyApO1xyXG5cdFx0XHRcdG1hdGNoWzJdID0gdW5xdW90ZWQuc2xpY2UoIDAsIGV4Y2VzcyApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBSZXR1cm4gb25seSBjYXB0dXJlcyBuZWVkZWQgYnkgdGhlIHBzZXVkbyBmaWx0ZXIgbWV0aG9kICh0eXBlIGFuZCBhcmd1bWVudClcclxuXHRcdFx0cmV0dXJuIG1hdGNoLnNsaWNlKCAwLCAzICk7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0ZmlsdGVyOiB7XHJcblxyXG5cdFx0XCJUQUdcIjogZnVuY3Rpb24oIG5vZGVOYW1lU2VsZWN0b3IgKSB7XHJcblx0XHRcdHZhciBub2RlTmFtZSA9IG5vZGVOYW1lU2VsZWN0b3IucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0XHRyZXR1cm4gbm9kZU5hbWVTZWxlY3RvciA9PT0gXCIqXCIgP1xyXG5cdFx0XHRcdGZ1bmN0aW9uKCkgeyByZXR1cm4gdHJ1ZTsgfSA6XHJcblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5vZGVOYW1lO1xyXG5cdFx0XHRcdH07XHJcblx0XHR9LFxyXG5cclxuXHRcdFwiQ0xBU1NcIjogZnVuY3Rpb24oIGNsYXNzTmFtZSApIHtcclxuXHRcdFx0dmFyIHBhdHRlcm4gPSBjbGFzc0NhY2hlWyBjbGFzc05hbWUgKyBcIiBcIiBdO1xyXG5cclxuXHRcdFx0cmV0dXJuIHBhdHRlcm4gfHxcclxuXHRcdFx0XHQocGF0dGVybiA9IG5ldyBSZWdFeHAoIFwiKF58XCIgKyB3aGl0ZXNwYWNlICsgXCIpXCIgKyBjbGFzc05hbWUgKyBcIihcIiArIHdoaXRlc3BhY2UgKyBcInwkKVwiICkpICYmXHJcblx0XHRcdFx0Y2xhc3NDYWNoZSggY2xhc3NOYW1lLCBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0XHRcdHJldHVybiBwYXR0ZXJuLnRlc3QoIHR5cGVvZiBlbGVtLmNsYXNzTmFtZSA9PT0gXCJzdHJpbmdcIiAmJiBlbGVtLmNsYXNzTmFtZSB8fCB0eXBlb2YgZWxlbS5nZXRBdHRyaWJ1dGUgIT09IFwidW5kZWZpbmVkXCIgJiYgZWxlbS5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKSB8fCBcIlwiICk7XHJcblx0XHRcdFx0fSk7XHJcblx0XHR9LFxyXG5cclxuXHRcdFwiQVRUUlwiOiBmdW5jdGlvbiggbmFtZSwgb3BlcmF0b3IsIGNoZWNrICkge1xyXG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdFx0dmFyIHJlc3VsdCA9IFNpenpsZS5hdHRyKCBlbGVtLCBuYW1lICk7XHJcblxyXG5cdFx0XHRcdGlmICggcmVzdWx0ID09IG51bGwgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gb3BlcmF0b3IgPT09IFwiIT1cIjtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0aWYgKCAhb3BlcmF0b3IgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdHJlc3VsdCArPSBcIlwiO1xyXG5cclxuXHRcdFx0XHRyZXR1cm4gb3BlcmF0b3IgPT09IFwiPVwiID8gcmVzdWx0ID09PSBjaGVjayA6XHJcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCIhPVwiID8gcmVzdWx0ICE9PSBjaGVjayA6XHJcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJePVwiID8gY2hlY2sgJiYgcmVzdWx0LmluZGV4T2YoIGNoZWNrICkgPT09IDAgOlxyXG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiKj1cIiA/IGNoZWNrICYmIHJlc3VsdC5pbmRleE9mKCBjaGVjayApID4gLTEgOlxyXG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiJD1cIiA/IGNoZWNrICYmIHJlc3VsdC5zbGljZSggLWNoZWNrLmxlbmd0aCApID09PSBjaGVjayA6XHJcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCJ+PVwiID8gKCBcIiBcIiArIHJlc3VsdC5yZXBsYWNlKCByd2hpdGVzcGFjZSwgXCIgXCIgKSArIFwiIFwiICkuaW5kZXhPZiggY2hlY2sgKSA+IC0xIDpcclxuXHRcdFx0XHRcdG9wZXJhdG9yID09PSBcInw9XCIgPyByZXN1bHQgPT09IGNoZWNrIHx8IHJlc3VsdC5zbGljZSggMCwgY2hlY2subGVuZ3RoICsgMSApID09PSBjaGVjayArIFwiLVwiIDpcclxuXHRcdFx0XHRcdGZhbHNlO1xyXG5cdFx0XHR9O1xyXG5cdFx0fSxcclxuXHJcblx0XHRcIkNISUxEXCI6IGZ1bmN0aW9uKCB0eXBlLCB3aGF0LCBhcmd1bWVudCwgZmlyc3QsIGxhc3QgKSB7XHJcblx0XHRcdHZhciBzaW1wbGUgPSB0eXBlLnNsaWNlKCAwLCAzICkgIT09IFwibnRoXCIsXHJcblx0XHRcdFx0Zm9yd2FyZCA9IHR5cGUuc2xpY2UoIC00ICkgIT09IFwibGFzdFwiLFxyXG5cdFx0XHRcdG9mVHlwZSA9IHdoYXQgPT09IFwib2YtdHlwZVwiO1xyXG5cclxuXHRcdFx0cmV0dXJuIGZpcnN0ID09PSAxICYmIGxhc3QgPT09IDAgP1xyXG5cclxuXHRcdFx0XHQvLyBTaG9ydGN1dCBmb3IgOm50aC0qKG4pXHJcblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gISFlbGVtLnBhcmVudE5vZGU7XHJcblx0XHRcdFx0fSA6XHJcblxyXG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XHJcblx0XHRcdFx0XHR2YXIgY2FjaGUsIHVuaXF1ZUNhY2hlLCBvdXRlckNhY2hlLCBub2RlLCBub2RlSW5kZXgsIHN0YXJ0LFxyXG5cdFx0XHRcdFx0XHRkaXIgPSBzaW1wbGUgIT09IGZvcndhcmQgPyBcIm5leHRTaWJsaW5nXCIgOiBcInByZXZpb3VzU2libGluZ1wiLFxyXG5cdFx0XHRcdFx0XHRwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGUsXHJcblx0XHRcdFx0XHRcdG5hbWUgPSBvZlR5cGUgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpLFxyXG5cdFx0XHRcdFx0XHR1c2VDYWNoZSA9ICF4bWwgJiYgIW9mVHlwZSxcclxuXHRcdFx0XHRcdFx0ZGlmZiA9IGZhbHNlO1xyXG5cclxuXHRcdFx0XHRcdGlmICggcGFyZW50ICkge1xyXG5cclxuXHRcdFx0XHRcdFx0Ly8gOihmaXJzdHxsYXN0fG9ubHkpLShjaGlsZHxvZi10eXBlKVxyXG5cdFx0XHRcdFx0XHRpZiAoIHNpbXBsZSApIHtcclxuXHRcdFx0XHRcdFx0XHR3aGlsZSAoIGRpciApIHtcclxuXHRcdFx0XHRcdFx0XHRcdG5vZGUgPSBlbGVtO1xyXG5cdFx0XHRcdFx0XHRcdFx0d2hpbGUgKCAobm9kZSA9IG5vZGVbIGRpciBdKSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBvZlR5cGUgP1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZSA6XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0bm9kZS5ub2RlVHlwZSA9PT0gMSApIHtcclxuXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0XHQvLyBSZXZlcnNlIGRpcmVjdGlvbiBmb3IgOm9ubHktKiAoaWYgd2UgaGF2ZW4ndCB5ZXQgZG9uZSBzbylcclxuXHRcdFx0XHRcdFx0XHRcdHN0YXJ0ID0gZGlyID0gdHlwZSA9PT0gXCJvbmx5XCIgJiYgIXN0YXJ0ICYmIFwibmV4dFNpYmxpbmdcIjtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRcdHN0YXJ0ID0gWyBmb3J3YXJkID8gcGFyZW50LmZpcnN0Q2hpbGQgOiBwYXJlbnQubGFzdENoaWxkIF07XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBub24teG1sIDpudGgtY2hpbGQoLi4uKSBzdG9yZXMgY2FjaGUgZGF0YSBvbiBgcGFyZW50YFxyXG5cdFx0XHRcdFx0XHRpZiAoIGZvcndhcmQgJiYgdXNlQ2FjaGUgKSB7XHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIFNlZWsgYGVsZW1gIGZyb20gYSBwcmV2aW91c2x5LWNhY2hlZCBpbmRleFxyXG5cclxuXHRcdFx0XHRcdFx0XHQvLyAuLi5pbiBhIGd6aXAtZnJpZW5kbHkgd2F5XHJcblx0XHRcdFx0XHRcdFx0bm9kZSA9IHBhcmVudDtcclxuXHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlID0gbm9kZVsgZXhwYW5kbyBdIHx8IChub2RlWyBleHBhbmRvIF0gPSB7fSk7XHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw5IG9ubHlcclxuXHRcdFx0XHRcdFx0XHQvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSlcclxuXHRcdFx0XHRcdFx0XHR1bmlxdWVDYWNoZSA9IG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSB8fFxyXG5cdFx0XHRcdFx0XHRcdFx0KG91dGVyQ2FjaGVbIG5vZGUudW5pcXVlSUQgXSA9IHt9KTtcclxuXHJcblx0XHRcdFx0XHRcdFx0Y2FjaGUgPSB1bmlxdWVDYWNoZVsgdHlwZSBdIHx8IFtdO1xyXG5cdFx0XHRcdFx0XHRcdG5vZGVJbmRleCA9IGNhY2hlWyAwIF0gPT09IGRpcnJ1bnMgJiYgY2FjaGVbIDEgXTtcclxuXHRcdFx0XHRcdFx0XHRkaWZmID0gbm9kZUluZGV4ICYmIGNhY2hlWyAyIF07XHJcblx0XHRcdFx0XHRcdFx0bm9kZSA9IG5vZGVJbmRleCAmJiBwYXJlbnQuY2hpbGROb2Rlc1sgbm9kZUluZGV4IF07XHJcblxyXG5cdFx0XHRcdFx0XHRcdHdoaWxlICggKG5vZGUgPSArK25vZGVJbmRleCAmJiBub2RlICYmIG5vZGVbIGRpciBdIHx8XHJcblxyXG5cdFx0XHRcdFx0XHRcdFx0Ly8gRmFsbGJhY2sgdG8gc2Vla2luZyBgZWxlbWAgZnJvbSB0aGUgc3RhcnRcclxuXHRcdFx0XHRcdFx0XHRcdChkaWZmID0gbm9kZUluZGV4ID0gMCkgfHwgc3RhcnQucG9wKCkpICkge1xyXG5cclxuXHRcdFx0XHRcdFx0XHRcdC8vIFdoZW4gZm91bmQsIGNhY2hlIGluZGV4ZXMgb24gYHBhcmVudGAgYW5kIGJyZWFrXHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoIG5vZGUubm9kZVR5cGUgPT09IDEgJiYgKytkaWZmICYmIG5vZGUgPT09IGVsZW0gKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlWyB0eXBlIF0gPSBbIGRpcnJ1bnMsIG5vZGVJbmRleCwgZGlmZiBdO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdC8vIFVzZSBwcmV2aW91c2x5LWNhY2hlZCBlbGVtZW50IGluZGV4IGlmIGF2YWlsYWJsZVxyXG5cdFx0XHRcdFx0XHRcdGlmICggdXNlQ2FjaGUgKSB7XHJcblx0XHRcdFx0XHRcdFx0XHQvLyAuLi5pbiBhIGd6aXAtZnJpZW5kbHkgd2F5XHJcblx0XHRcdFx0XHRcdFx0XHRub2RlID0gZWxlbTtcclxuXHRcdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBub2RlWyBleHBhbmRvIF0gfHwgKG5vZGVbIGV4cGFuZG8gXSA9IHt9KTtcclxuXHJcblx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8OSBvbmx5XHJcblx0XHRcdFx0XHRcdFx0XHQvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSlcclxuXHRcdFx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlID0gb3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdIHx8XHJcblx0XHRcdFx0XHRcdFx0XHRcdChvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gPSB7fSk7XHJcblxyXG5cdFx0XHRcdFx0XHRcdFx0Y2FjaGUgPSB1bmlxdWVDYWNoZVsgdHlwZSBdIHx8IFtdO1xyXG5cdFx0XHRcdFx0XHRcdFx0bm9kZUluZGV4ID0gY2FjaGVbIDAgXSA9PT0gZGlycnVucyAmJiBjYWNoZVsgMSBdO1xyXG5cdFx0XHRcdFx0XHRcdFx0ZGlmZiA9IG5vZGVJbmRleDtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIHhtbCA6bnRoLWNoaWxkKC4uLilcclxuXHRcdFx0XHRcdFx0XHQvLyBvciA6bnRoLWxhc3QtY2hpbGQoLi4uKSBvciA6bnRoKC1sYXN0KT8tb2YtdHlwZSguLi4pXHJcblx0XHRcdFx0XHRcdFx0aWYgKCBkaWZmID09PSBmYWxzZSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdC8vIFVzZSB0aGUgc2FtZSBsb29wIGFzIGFib3ZlIHRvIHNlZWsgYGVsZW1gIGZyb20gdGhlIHN0YXJ0XHJcblx0XHRcdFx0XHRcdFx0XHR3aGlsZSAoIChub2RlID0gKytub2RlSW5kZXggJiYgbm9kZSAmJiBub2RlWyBkaXIgXSB8fFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQoZGlmZiA9IG5vZGVJbmRleCA9IDApIHx8IHN0YXJ0LnBvcCgpKSApIHtcclxuXHJcblx0XHRcdFx0XHRcdFx0XHRcdGlmICggKCBvZlR5cGUgP1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZSA6XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0bm9kZS5ub2RlVHlwZSA9PT0gMSApICYmXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0KytkaWZmICkge1xyXG5cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBDYWNoZSB0aGUgaW5kZXggb2YgZWFjaCBlbmNvdW50ZXJlZCBlbGVtZW50XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCB1c2VDYWNoZSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBub2RlWyBleHBhbmRvIF0gfHwgKG5vZGVbIGV4cGFuZG8gXSA9IHt9KTtcclxuXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRSA8OSBvbmx5XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQvLyBEZWZlbmQgYWdhaW5zdCBjbG9uZWQgYXR0cm9wZXJ0aWVzIChqUXVlcnkgZ2gtMTcwOSlcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlID0gb3V0ZXJDYWNoZVsgbm9kZS51bmlxdWVJRCBdIHx8XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHRcdChvdXRlckNhY2hlWyBub2RlLnVuaXF1ZUlEIF0gPSB7fSk7XHJcblxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0dW5pcXVlQ2FjaGVbIHR5cGUgXSA9IFsgZGlycnVucywgZGlmZiBdO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBub2RlID09PSBlbGVtICkge1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBJbmNvcnBvcmF0ZSB0aGUgb2Zmc2V0LCB0aGVuIGNoZWNrIGFnYWluc3QgY3ljbGUgc2l6ZVxyXG5cdFx0XHRcdFx0XHRkaWZmIC09IGxhc3Q7XHJcblx0XHRcdFx0XHRcdHJldHVybiBkaWZmID09PSBmaXJzdCB8fCAoIGRpZmYgJSBmaXJzdCA9PT0gMCAmJiBkaWZmIC8gZmlyc3QgPj0gMCApO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH07XHJcblx0XHR9LFxyXG5cclxuXHRcdFwiUFNFVURPXCI6IGZ1bmN0aW9uKCBwc2V1ZG8sIGFyZ3VtZW50ICkge1xyXG5cdFx0XHQvLyBwc2V1ZG8tY2xhc3MgbmFtZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmVcclxuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNwc2V1ZG8tY2xhc3Nlc1xyXG5cdFx0XHQvLyBQcmlvcml0aXplIGJ5IGNhc2Ugc2Vuc2l0aXZpdHkgaW4gY2FzZSBjdXN0b20gcHNldWRvcyBhcmUgYWRkZWQgd2l0aCB1cHBlcmNhc2UgbGV0dGVyc1xyXG5cdFx0XHQvLyBSZW1lbWJlciB0aGF0IHNldEZpbHRlcnMgaW5oZXJpdHMgZnJvbSBwc2V1ZG9zXHJcblx0XHRcdHZhciBhcmdzLFxyXG5cdFx0XHRcdGZuID0gRXhwci5wc2V1ZG9zWyBwc2V1ZG8gXSB8fCBFeHByLnNldEZpbHRlcnNbIHBzZXVkby50b0xvd2VyQ2FzZSgpIF0gfHxcclxuXHRcdFx0XHRcdFNpenpsZS5lcnJvciggXCJ1bnN1cHBvcnRlZCBwc2V1ZG86IFwiICsgcHNldWRvICk7XHJcblxyXG5cdFx0XHQvLyBUaGUgdXNlciBtYXkgdXNlIGNyZWF0ZVBzZXVkbyB0byBpbmRpY2F0ZSB0aGF0XHJcblx0XHRcdC8vIGFyZ3VtZW50cyBhcmUgbmVlZGVkIHRvIGNyZWF0ZSB0aGUgZmlsdGVyIGZ1bmN0aW9uXHJcblx0XHRcdC8vIGp1c3QgYXMgU2l6emxlIGRvZXNcclxuXHRcdFx0aWYgKCBmblsgZXhwYW5kbyBdICkge1xyXG5cdFx0XHRcdHJldHVybiBmbiggYXJndW1lbnQgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gQnV0IG1haW50YWluIHN1cHBvcnQgZm9yIG9sZCBzaWduYXR1cmVzXHJcblx0XHRcdGlmICggZm4ubGVuZ3RoID4gMSApIHtcclxuXHRcdFx0XHRhcmdzID0gWyBwc2V1ZG8sIHBzZXVkbywgXCJcIiwgYXJndW1lbnQgXTtcclxuXHRcdFx0XHRyZXR1cm4gRXhwci5zZXRGaWx0ZXJzLmhhc093blByb3BlcnR5KCBwc2V1ZG8udG9Mb3dlckNhc2UoKSApID9cclxuXHRcdFx0XHRcdG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgbWF0Y2hlcyApIHtcclxuXHRcdFx0XHRcdFx0dmFyIGlkeCxcclxuXHRcdFx0XHRcdFx0XHRtYXRjaGVkID0gZm4oIHNlZWQsIGFyZ3VtZW50ICksXHJcblx0XHRcdFx0XHRcdFx0aSA9IG1hdGNoZWQubGVuZ3RoO1xyXG5cdFx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcclxuXHRcdFx0XHRcdFx0XHRpZHggPSBpbmRleE9mKCBzZWVkLCBtYXRjaGVkW2ldICk7XHJcblx0XHRcdFx0XHRcdFx0c2VlZFsgaWR4IF0gPSAhKCBtYXRjaGVzWyBpZHggXSA9IG1hdGNoZWRbaV0gKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fSkgOlxyXG5cdFx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdFx0XHRcdHJldHVybiBmbiggZWxlbSwgMCwgYXJncyApO1xyXG5cdFx0XHRcdFx0fTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIGZuO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdHBzZXVkb3M6IHtcclxuXHRcdC8vIFBvdGVudGlhbGx5IGNvbXBsZXggcHNldWRvc1xyXG5cdFx0XCJub3RcIjogbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcclxuXHRcdFx0Ly8gVHJpbSB0aGUgc2VsZWN0b3IgcGFzc2VkIHRvIGNvbXBpbGVcclxuXHRcdFx0Ly8gdG8gYXZvaWQgdHJlYXRpbmcgbGVhZGluZyBhbmQgdHJhaWxpbmdcclxuXHRcdFx0Ly8gc3BhY2VzIGFzIGNvbWJpbmF0b3JzXHJcblx0XHRcdHZhciBpbnB1dCA9IFtdLFxyXG5cdFx0XHRcdHJlc3VsdHMgPSBbXSxcclxuXHRcdFx0XHRtYXRjaGVyID0gY29tcGlsZSggc2VsZWN0b3IucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApICk7XHJcblxyXG5cdFx0XHRyZXR1cm4gbWF0Y2hlclsgZXhwYW5kbyBdID9cclxuXHRcdFx0XHRtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMsIGNvbnRleHQsIHhtbCApIHtcclxuXHRcdFx0XHRcdHZhciBlbGVtLFxyXG5cdFx0XHRcdFx0XHR1bm1hdGNoZWQgPSBtYXRjaGVyKCBzZWVkLCBudWxsLCB4bWwsIFtdICksXHJcblx0XHRcdFx0XHRcdGkgPSBzZWVkLmxlbmd0aDtcclxuXHJcblx0XHRcdFx0XHQvLyBNYXRjaCBlbGVtZW50cyB1bm1hdGNoZWQgYnkgYG1hdGNoZXJgXHJcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcclxuXHRcdFx0XHRcdFx0aWYgKCAoZWxlbSA9IHVubWF0Y2hlZFtpXSkgKSB7XHJcblx0XHRcdFx0XHRcdFx0c2VlZFtpXSA9ICEobWF0Y2hlc1tpXSA9IGVsZW0pO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fSkgOlxyXG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XHJcblx0XHRcdFx0XHRpbnB1dFswXSA9IGVsZW07XHJcblx0XHRcdFx0XHRtYXRjaGVyKCBpbnB1dCwgbnVsbCwgeG1sLCByZXN1bHRzICk7XHJcblx0XHRcdFx0XHQvLyBEb24ndCBrZWVwIHRoZSBlbGVtZW50IChpc3N1ZSAjMjk5KVxyXG5cdFx0XHRcdFx0aW5wdXRbMF0gPSBudWxsO1xyXG5cdFx0XHRcdFx0cmV0dXJuICFyZXN1bHRzLnBvcCgpO1xyXG5cdFx0XHRcdH07XHJcblx0XHR9KSxcclxuXHJcblx0XHRcImhhc1wiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlbGVjdG9yICkge1xyXG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdFx0cmV0dXJuIFNpenpsZSggc2VsZWN0b3IsIGVsZW0gKS5sZW5ndGggPiAwO1xyXG5cdFx0XHR9O1xyXG5cdFx0fSksXHJcblxyXG5cdFx0XCJjb250YWluc1wiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHRleHQgKSB7XHJcblx0XHRcdHRleHQgPSB0ZXh0LnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XHJcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0XHRyZXR1cm4gKCBlbGVtLnRleHRDb250ZW50IHx8IGVsZW0uaW5uZXJUZXh0IHx8IGdldFRleHQoIGVsZW0gKSApLmluZGV4T2YoIHRleHQgKSA+IC0xO1xyXG5cdFx0XHR9O1xyXG5cdFx0fSksXHJcblxyXG5cdFx0Ly8gXCJXaGV0aGVyIGFuIGVsZW1lbnQgaXMgcmVwcmVzZW50ZWQgYnkgYSA6bGFuZygpIHNlbGVjdG9yXHJcblx0XHQvLyBpcyBiYXNlZCBzb2xlbHkgb24gdGhlIGVsZW1lbnQncyBsYW5ndWFnZSB2YWx1ZVxyXG5cdFx0Ly8gYmVpbmcgZXF1YWwgdG8gdGhlIGlkZW50aWZpZXIgQyxcclxuXHRcdC8vIG9yIGJlZ2lubmluZyB3aXRoIHRoZSBpZGVudGlmaWVyIEMgaW1tZWRpYXRlbHkgZm9sbG93ZWQgYnkgXCItXCIuXHJcblx0XHQvLyBUaGUgbWF0Y2hpbmcgb2YgQyBhZ2FpbnN0IHRoZSBlbGVtZW50J3MgbGFuZ3VhZ2UgdmFsdWUgaXMgcGVyZm9ybWVkIGNhc2UtaW5zZW5zaXRpdmVseS5cclxuXHRcdC8vIFRoZSBpZGVudGlmaWVyIEMgZG9lcyBub3QgaGF2ZSB0byBiZSBhIHZhbGlkIGxhbmd1YWdlIG5hbWUuXCJcclxuXHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jbGFuZy1wc2V1ZG9cclxuXHRcdFwibGFuZ1wiOiBtYXJrRnVuY3Rpb24oIGZ1bmN0aW9uKCBsYW5nICkge1xyXG5cdFx0XHQvLyBsYW5nIHZhbHVlIG11c3QgYmUgYSB2YWxpZCBpZGVudGlmaWVyXHJcblx0XHRcdGlmICggIXJpZGVudGlmaWVyLnRlc3QobGFuZyB8fCBcIlwiKSApIHtcclxuXHRcdFx0XHRTaXp6bGUuZXJyb3IoIFwidW5zdXBwb3J0ZWQgbGFuZzogXCIgKyBsYW5nICk7XHJcblx0XHRcdH1cclxuXHRcdFx0bGFuZyA9IGxhbmcucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKS50b0xvd2VyQ2FzZSgpO1xyXG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdFx0dmFyIGVsZW1MYW5nO1xyXG5cdFx0XHRcdGRvIHtcclxuXHRcdFx0XHRcdGlmICggKGVsZW1MYW5nID0gZG9jdW1lbnRJc0hUTUwgP1xyXG5cdFx0XHRcdFx0XHRlbGVtLmxhbmcgOlxyXG5cdFx0XHRcdFx0XHRlbGVtLmdldEF0dHJpYnV0ZShcInhtbDpsYW5nXCIpIHx8IGVsZW0uZ2V0QXR0cmlidXRlKFwibGFuZ1wiKSkgKSB7XHJcblxyXG5cdFx0XHRcdFx0XHRlbGVtTGFuZyA9IGVsZW1MYW5nLnRvTG93ZXJDYXNlKCk7XHJcblx0XHRcdFx0XHRcdHJldHVybiBlbGVtTGFuZyA9PT0gbGFuZyB8fCBlbGVtTGFuZy5pbmRleE9mKCBsYW5nICsgXCItXCIgKSA9PT0gMDtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9IHdoaWxlICggKGVsZW0gPSBlbGVtLnBhcmVudE5vZGUpICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKTtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH07XHJcblx0XHR9KSxcclxuXHJcblx0XHQvLyBNaXNjZWxsYW5lb3VzXHJcblx0XHRcInRhcmdldFwiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0dmFyIGhhc2ggPSB3aW5kb3cubG9jYXRpb24gJiYgd2luZG93LmxvY2F0aW9uLmhhc2g7XHJcblx0XHRcdHJldHVybiBoYXNoICYmIGhhc2guc2xpY2UoIDEgKSA9PT0gZWxlbS5pZDtcclxuXHRcdH0sXHJcblxyXG5cdFx0XCJyb290XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gZG9jRWxlbTtcclxuXHRcdH0sXHJcblxyXG5cdFx0XCJmb2N1c1wiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0cmV0dXJuIGVsZW0gPT09IGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgJiYgKCFkb2N1bWVudC5oYXNGb2N1cyB8fCBkb2N1bWVudC5oYXNGb2N1cygpKSAmJiAhIShlbGVtLnR5cGUgfHwgZWxlbS5ocmVmIHx8IH5lbGVtLnRhYkluZGV4KTtcclxuXHRcdH0sXHJcblxyXG5cdFx0Ly8gQm9vbGVhbiBwcm9wZXJ0aWVzXHJcblx0XHRcImVuYWJsZWRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdHJldHVybiBlbGVtLmRpc2FibGVkID09PSBmYWxzZTtcclxuXHRcdH0sXHJcblxyXG5cdFx0XCJkaXNhYmxlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0cmV0dXJuIGVsZW0uZGlzYWJsZWQgPT09IHRydWU7XHJcblx0XHR9LFxyXG5cclxuXHRcdFwiY2hlY2tlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0Ly8gSW4gQ1NTMywgOmNoZWNrZWQgc2hvdWxkIHJldHVybiBib3RoIGNoZWNrZWQgYW5kIHNlbGVjdGVkIGVsZW1lbnRzXHJcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTEvUkVDLWNzczMtc2VsZWN0b3JzLTIwMTEwOTI5LyNjaGVja2VkXHJcblx0XHRcdHZhciBub2RlTmFtZSA9IGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtcclxuXHRcdFx0cmV0dXJuIChub2RlTmFtZSA9PT0gXCJpbnB1dFwiICYmICEhZWxlbS5jaGVja2VkKSB8fCAobm9kZU5hbWUgPT09IFwib3B0aW9uXCIgJiYgISFlbGVtLnNlbGVjdGVkKTtcclxuXHRcdH0sXHJcblxyXG5cdFx0XCJzZWxlY3RlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0Ly8gQWNjZXNzaW5nIHRoaXMgcHJvcGVydHkgbWFrZXMgc2VsZWN0ZWQtYnktZGVmYXVsdFxyXG5cdFx0XHQvLyBvcHRpb25zIGluIFNhZmFyaSB3b3JrIHByb3Blcmx5XHJcblx0XHRcdGlmICggZWxlbS5wYXJlbnROb2RlICkge1xyXG5cdFx0XHRcdGVsZW0ucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4O1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gZWxlbS5zZWxlY3RlZCA9PT0gdHJ1ZTtcclxuXHRcdH0sXHJcblxyXG5cdFx0Ly8gQ29udGVudHNcclxuXHRcdFwiZW1wdHlcIjogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jZW1wdHktcHNldWRvXHJcblx0XHRcdC8vIDplbXB0eSBpcyBuZWdhdGVkIGJ5IGVsZW1lbnQgKDEpIG9yIGNvbnRlbnQgbm9kZXMgKHRleHQ6IDM7IGNkYXRhOiA0OyBlbnRpdHkgcmVmOiA1KSxcclxuXHRcdFx0Ly8gICBidXQgbm90IGJ5IG90aGVycyAoY29tbWVudDogODsgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbjogNzsgZXRjLilcclxuXHRcdFx0Ly8gbm9kZVR5cGUgPCA2IHdvcmtzIGJlY2F1c2UgYXR0cmlidXRlcyAoMikgZG8gbm90IGFwcGVhciBhcyBjaGlsZHJlblxyXG5cdFx0XHRmb3IgKCBlbGVtID0gZWxlbS5maXJzdENoaWxkOyBlbGVtOyBlbGVtID0gZWxlbS5uZXh0U2libGluZyApIHtcclxuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPCA2ICkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdH0sXHJcblxyXG5cdFx0XCJwYXJlbnRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdHJldHVybiAhRXhwci5wc2V1ZG9zW1wiZW1wdHlcIl0oIGVsZW0gKTtcclxuXHRcdH0sXHJcblxyXG5cdFx0Ly8gRWxlbWVudC9pbnB1dCB0eXBlc1xyXG5cdFx0XCJoZWFkZXJcIjogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdHJldHVybiByaGVhZGVyLnRlc3QoIGVsZW0ubm9kZU5hbWUgKTtcclxuXHRcdH0sXHJcblxyXG5cdFx0XCJpbnB1dFwiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0cmV0dXJuIHJpbnB1dHMudGVzdCggZWxlbS5ub2RlTmFtZSApO1xyXG5cdFx0fSxcclxuXHJcblx0XHRcImJ1dHRvblwiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0dmFyIG5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XHJcblx0XHRcdHJldHVybiBuYW1lID09PSBcImlucHV0XCIgJiYgZWxlbS50eXBlID09PSBcImJ1dHRvblwiIHx8IG5hbWUgPT09IFwiYnV0dG9uXCI7XHJcblx0XHR9LFxyXG5cclxuXHRcdFwidGV4dFwiOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0dmFyIGF0dHI7XHJcblx0XHRcdHJldHVybiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwiaW5wdXRcIiAmJlxyXG5cdFx0XHRcdGVsZW0udHlwZSA9PT0gXCJ0ZXh0XCIgJiZcclxuXHJcblx0XHRcdFx0Ly8gU3VwcG9ydDogSUU8OFxyXG5cdFx0XHRcdC8vIE5ldyBIVE1MNSBhdHRyaWJ1dGUgdmFsdWVzIChlLmcuLCBcInNlYXJjaFwiKSBhcHBlYXIgd2l0aCBlbGVtLnR5cGUgPT09IFwidGV4dFwiXHJcblx0XHRcdFx0KCAoYXR0ciA9IGVsZW0uZ2V0QXR0cmlidXRlKFwidHlwZVwiKSkgPT0gbnVsbCB8fCBhdHRyLnRvTG93ZXJDYXNlKCkgPT09IFwidGV4dFwiICk7XHJcblx0XHR9LFxyXG5cclxuXHRcdC8vIFBvc2l0aW9uLWluLWNvbGxlY3Rpb25cclxuXHRcdFwiZmlyc3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbigpIHtcclxuXHRcdFx0cmV0dXJuIFsgMCBdO1xyXG5cdFx0fSksXHJcblxyXG5cdFx0XCJsYXN0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xyXG5cdFx0XHRyZXR1cm4gWyBsZW5ndGggLSAxIF07XHJcblx0XHR9KSxcclxuXHJcblx0XHRcImVxXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcclxuXHRcdFx0cmV0dXJuIFsgYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudCBdO1xyXG5cdFx0fSksXHJcblxyXG5cdFx0XCJldmVuXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xyXG5cdFx0XHR2YXIgaSA9IDA7XHJcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSArPSAyICkge1xyXG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcclxuXHRcdH0pLFxyXG5cclxuXHRcdFwib2RkXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xyXG5cdFx0XHR2YXIgaSA9IDE7XHJcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSArPSAyICkge1xyXG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcclxuXHRcdH0pLFxyXG5cclxuXHRcdFwibHRcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGgsIGFyZ3VtZW50ICkge1xyXG5cdFx0XHR2YXIgaSA9IGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQ7XHJcblx0XHRcdGZvciAoIDsgLS1pID49IDA7ICkge1xyXG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcclxuXHRcdH0pLFxyXG5cclxuXHRcdFwiZ3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGgsIGFyZ3VtZW50ICkge1xyXG5cdFx0XHR2YXIgaSA9IGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQ7XHJcblx0XHRcdGZvciAoIDsgKytpIDwgbGVuZ3RoOyApIHtcclxuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XHJcblx0XHR9KVxyXG5cdH1cclxufTtcclxuXHJcbkV4cHIucHNldWRvc1tcIm50aFwiXSA9IEV4cHIucHNldWRvc1tcImVxXCJdO1xyXG5cclxuLy8gQWRkIGJ1dHRvbi9pbnB1dCB0eXBlIHBzZXVkb3NcclxuZm9yICggaSBpbiB7IHJhZGlvOiB0cnVlLCBjaGVja2JveDogdHJ1ZSwgZmlsZTogdHJ1ZSwgcGFzc3dvcmQ6IHRydWUsIGltYWdlOiB0cnVlIH0gKSB7XHJcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVJbnB1dFBzZXVkbyggaSApO1xyXG59XHJcbmZvciAoIGkgaW4geyBzdWJtaXQ6IHRydWUsIHJlc2V0OiB0cnVlIH0gKSB7XHJcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVCdXR0b25Qc2V1ZG8oIGkgKTtcclxufVxyXG5cclxuLy8gRWFzeSBBUEkgZm9yIGNyZWF0aW5nIG5ldyBzZXRGaWx0ZXJzXHJcbmZ1bmN0aW9uIHNldEZpbHRlcnMoKSB7fVxyXG5zZXRGaWx0ZXJzLnByb3RvdHlwZSA9IEV4cHIuZmlsdGVycyA9IEV4cHIucHNldWRvcztcclxuRXhwci5zZXRGaWx0ZXJzID0gbmV3IHNldEZpbHRlcnMoKTtcclxuXHJcbnRva2VuaXplID0gU2l6emxlLnRva2VuaXplID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBwYXJzZU9ubHkgKSB7XHJcblx0dmFyIG1hdGNoZWQsIG1hdGNoLCB0b2tlbnMsIHR5cGUsXHJcblx0XHRzb0ZhciwgZ3JvdXBzLCBwcmVGaWx0ZXJzLFxyXG5cdFx0Y2FjaGVkID0gdG9rZW5DYWNoZVsgc2VsZWN0b3IgKyBcIiBcIiBdO1xyXG5cclxuXHRpZiAoIGNhY2hlZCApIHtcclxuXHRcdHJldHVybiBwYXJzZU9ubHkgPyAwIDogY2FjaGVkLnNsaWNlKCAwICk7XHJcblx0fVxyXG5cclxuXHRzb0ZhciA9IHNlbGVjdG9yO1xyXG5cdGdyb3VwcyA9IFtdO1xyXG5cdHByZUZpbHRlcnMgPSBFeHByLnByZUZpbHRlcjtcclxuXHJcblx0d2hpbGUgKCBzb0ZhciApIHtcclxuXHJcblx0XHQvLyBDb21tYSBhbmQgZmlyc3QgcnVuXHJcblx0XHRpZiAoICFtYXRjaGVkIHx8IChtYXRjaCA9IHJjb21tYS5leGVjKCBzb0ZhciApKSApIHtcclxuXHRcdFx0aWYgKCBtYXRjaCApIHtcclxuXHRcdFx0XHQvLyBEb24ndCBjb25zdW1lIHRyYWlsaW5nIGNvbW1hcyBhcyB2YWxpZFxyXG5cdFx0XHRcdHNvRmFyID0gc29GYXIuc2xpY2UoIG1hdGNoWzBdLmxlbmd0aCApIHx8IHNvRmFyO1xyXG5cdFx0XHR9XHJcblx0XHRcdGdyb3Vwcy5wdXNoKCAodG9rZW5zID0gW10pICk7XHJcblx0XHR9XHJcblxyXG5cdFx0bWF0Y2hlZCA9IGZhbHNlO1xyXG5cclxuXHRcdC8vIENvbWJpbmF0b3JzXHJcblx0XHRpZiAoIChtYXRjaCA9IHJjb21iaW5hdG9ycy5leGVjKCBzb0ZhciApKSApIHtcclxuXHRcdFx0bWF0Y2hlZCA9IG1hdGNoLnNoaWZ0KCk7XHJcblx0XHRcdHRva2Vucy5wdXNoKHtcclxuXHRcdFx0XHR2YWx1ZTogbWF0Y2hlZCxcclxuXHRcdFx0XHQvLyBDYXN0IGRlc2NlbmRhbnQgY29tYmluYXRvcnMgdG8gc3BhY2VcclxuXHRcdFx0XHR0eXBlOiBtYXRjaFswXS5yZXBsYWNlKCBydHJpbSwgXCIgXCIgKVxyXG5cdFx0XHR9KTtcclxuXHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hlZC5sZW5ndGggKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBGaWx0ZXJzXHJcblx0XHRmb3IgKCB0eXBlIGluIEV4cHIuZmlsdGVyICkge1xyXG5cdFx0XHRpZiAoIChtYXRjaCA9IG1hdGNoRXhwclsgdHlwZSBdLmV4ZWMoIHNvRmFyICkpICYmICghcHJlRmlsdGVyc1sgdHlwZSBdIHx8XHJcblx0XHRcdFx0KG1hdGNoID0gcHJlRmlsdGVyc1sgdHlwZSBdKCBtYXRjaCApKSkgKSB7XHJcblx0XHRcdFx0bWF0Y2hlZCA9IG1hdGNoLnNoaWZ0KCk7XHJcblx0XHRcdFx0dG9rZW5zLnB1c2goe1xyXG5cdFx0XHRcdFx0dmFsdWU6IG1hdGNoZWQsXHJcblx0XHRcdFx0XHR0eXBlOiB0eXBlLFxyXG5cdFx0XHRcdFx0bWF0Y2hlczogbWF0Y2hcclxuXHRcdFx0XHR9KTtcclxuXHRcdFx0XHRzb0ZhciA9IHNvRmFyLnNsaWNlKCBtYXRjaGVkLmxlbmd0aCApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCAhbWF0Y2hlZCApIHtcclxuXHRcdFx0YnJlYWs7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyBSZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgaW52YWxpZCBleGNlc3NcclxuXHQvLyBpZiB3ZSdyZSBqdXN0IHBhcnNpbmdcclxuXHQvLyBPdGhlcndpc2UsIHRocm93IGFuIGVycm9yIG9yIHJldHVybiB0b2tlbnNcclxuXHRyZXR1cm4gcGFyc2VPbmx5ID9cclxuXHRcdHNvRmFyLmxlbmd0aCA6XHJcblx0XHRzb0ZhciA/XHJcblx0XHRcdFNpenpsZS5lcnJvciggc2VsZWN0b3IgKSA6XHJcblx0XHRcdC8vIENhY2hlIHRoZSB0b2tlbnNcclxuXHRcdFx0dG9rZW5DYWNoZSggc2VsZWN0b3IsIGdyb3VwcyApLnNsaWNlKCAwICk7XHJcbn07XHJcblxyXG5mdW5jdGlvbiB0b1NlbGVjdG9yKCB0b2tlbnMgKSB7XHJcblx0dmFyIGkgPSAwLFxyXG5cdFx0bGVuID0gdG9rZW5zLmxlbmd0aCxcclxuXHRcdHNlbGVjdG9yID0gXCJcIjtcclxuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcclxuXHRcdHNlbGVjdG9yICs9IHRva2Vuc1tpXS52YWx1ZTtcclxuXHR9XHJcblx0cmV0dXJuIHNlbGVjdG9yO1xyXG59XHJcblxyXG5mdW5jdGlvbiBhZGRDb21iaW5hdG9yKCBtYXRjaGVyLCBjb21iaW5hdG9yLCBiYXNlICkge1xyXG5cdHZhciBkaXIgPSBjb21iaW5hdG9yLmRpcixcclxuXHRcdGNoZWNrTm9uRWxlbWVudHMgPSBiYXNlICYmIGRpciA9PT0gXCJwYXJlbnROb2RlXCIsXHJcblx0XHRkb25lTmFtZSA9IGRvbmUrKztcclxuXHJcblx0cmV0dXJuIGNvbWJpbmF0b3IuZmlyc3QgP1xyXG5cdFx0Ly8gQ2hlY2sgYWdhaW5zdCBjbG9zZXN0IGFuY2VzdG9yL3ByZWNlZGluZyBlbGVtZW50XHJcblx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xyXG5cdFx0XHR3aGlsZSAoIChlbGVtID0gZWxlbVsgZGlyIF0pICkge1xyXG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSB8fCBjaGVja05vbkVsZW1lbnRzICkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSA6XHJcblxyXG5cdFx0Ly8gQ2hlY2sgYWdhaW5zdCBhbGwgYW5jZXN0b3IvcHJlY2VkaW5nIGVsZW1lbnRzXHJcblx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xyXG5cdFx0XHR2YXIgb2xkQ2FjaGUsIHVuaXF1ZUNhY2hlLCBvdXRlckNhY2hlLFxyXG5cdFx0XHRcdG5ld0NhY2hlID0gWyBkaXJydW5zLCBkb25lTmFtZSBdO1xyXG5cclxuXHRcdFx0Ly8gV2UgY2FuJ3Qgc2V0IGFyYml0cmFyeSBkYXRhIG9uIFhNTCBub2Rlcywgc28gdGhleSBkb24ndCBiZW5lZml0IGZyb20gY29tYmluYXRvciBjYWNoaW5nXHJcblx0XHRcdGlmICggeG1sICkge1xyXG5cdFx0XHRcdHdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgKSB7XHJcblx0XHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgY2hlY2tOb25FbGVtZW50cyApIHtcclxuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcclxuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHR3aGlsZSAoIChlbGVtID0gZWxlbVsgZGlyIF0pICkge1xyXG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7XHJcblx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBlbGVtWyBleHBhbmRvIF0gfHwgKGVsZW1bIGV4cGFuZG8gXSA9IHt9KTtcclxuXHJcblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFIDw5IG9ubHlcclxuXHRcdFx0XHRcdFx0Ly8gRGVmZW5kIGFnYWluc3QgY2xvbmVkIGF0dHJvcGVydGllcyAoalF1ZXJ5IGdoLTE3MDkpXHJcblx0XHRcdFx0XHRcdHVuaXF1ZUNhY2hlID0gb3V0ZXJDYWNoZVsgZWxlbS51bmlxdWVJRCBdIHx8IChvdXRlckNhY2hlWyBlbGVtLnVuaXF1ZUlEIF0gPSB7fSk7XHJcblxyXG5cdFx0XHRcdFx0XHRpZiAoIChvbGRDYWNoZSA9IHVuaXF1ZUNhY2hlWyBkaXIgXSkgJiZcclxuXHRcdFx0XHRcdFx0XHRvbGRDYWNoZVsgMCBdID09PSBkaXJydW5zICYmIG9sZENhY2hlWyAxIF0gPT09IGRvbmVOYW1lICkge1xyXG5cclxuXHRcdFx0XHRcdFx0XHQvLyBBc3NpZ24gdG8gbmV3Q2FjaGUgc28gcmVzdWx0cyBiYWNrLXByb3BhZ2F0ZSB0byBwcmV2aW91cyBlbGVtZW50c1xyXG5cdFx0XHRcdFx0XHRcdHJldHVybiAobmV3Q2FjaGVbIDIgXSA9IG9sZENhY2hlWyAyIF0pO1xyXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdC8vIFJldXNlIG5ld2NhY2hlIHNvIHJlc3VsdHMgYmFjay1wcm9wYWdhdGUgdG8gcHJldmlvdXMgZWxlbWVudHNcclxuXHRcdFx0XHRcdFx0XHR1bmlxdWVDYWNoZVsgZGlyIF0gPSBuZXdDYWNoZTtcclxuXHJcblx0XHRcdFx0XHRcdFx0Ly8gQSBtYXRjaCBtZWFucyB3ZSdyZSBkb25lOyBhIGZhaWwgbWVhbnMgd2UgaGF2ZSB0byBrZWVwIGNoZWNraW5nXHJcblx0XHRcdFx0XHRcdFx0aWYgKCAobmV3Q2FjaGVbIDIgXSA9IG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApKSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fTtcclxufVxyXG5cclxuZnVuY3Rpb24gZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICkge1xyXG5cdHJldHVybiBtYXRjaGVycy5sZW5ndGggPiAxID9cclxuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XHJcblx0XHRcdHZhciBpID0gbWF0Y2hlcnMubGVuZ3RoO1xyXG5cdFx0XHR3aGlsZSAoIGktLSApIHtcclxuXHRcdFx0XHRpZiAoICFtYXRjaGVyc1tpXSggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0fSA6XHJcblx0XHRtYXRjaGVyc1swXTtcclxufVxyXG5cclxuZnVuY3Rpb24gbXVsdGlwbGVDb250ZXh0cyggc2VsZWN0b3IsIGNvbnRleHRzLCByZXN1bHRzICkge1xyXG5cdHZhciBpID0gMCxcclxuXHRcdGxlbiA9IGNvbnRleHRzLmxlbmd0aDtcclxuXHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcclxuXHRcdFNpenpsZSggc2VsZWN0b3IsIGNvbnRleHRzW2ldLCByZXN1bHRzICk7XHJcblx0fVxyXG5cdHJldHVybiByZXN1bHRzO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjb25kZW5zZSggdW5tYXRjaGVkLCBtYXAsIGZpbHRlciwgY29udGV4dCwgeG1sICkge1xyXG5cdHZhciBlbGVtLFxyXG5cdFx0bmV3VW5tYXRjaGVkID0gW10sXHJcblx0XHRpID0gMCxcclxuXHRcdGxlbiA9IHVubWF0Y2hlZC5sZW5ndGgsXHJcblx0XHRtYXBwZWQgPSBtYXAgIT0gbnVsbDtcclxuXHJcblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XHJcblx0XHRpZiAoIChlbGVtID0gdW5tYXRjaGVkW2ldKSApIHtcclxuXHRcdFx0aWYgKCAhZmlsdGVyIHx8IGZpbHRlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XHJcblx0XHRcdFx0bmV3VW5tYXRjaGVkLnB1c2goIGVsZW0gKTtcclxuXHRcdFx0XHRpZiAoIG1hcHBlZCApIHtcclxuXHRcdFx0XHRcdG1hcC5wdXNoKCBpICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gbmV3VW5tYXRjaGVkO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzZXRNYXRjaGVyKCBwcmVGaWx0ZXIsIHNlbGVjdG9yLCBtYXRjaGVyLCBwb3N0RmlsdGVyLCBwb3N0RmluZGVyLCBwb3N0U2VsZWN0b3IgKSB7XHJcblx0aWYgKCBwb3N0RmlsdGVyICYmICFwb3N0RmlsdGVyWyBleHBhbmRvIF0gKSB7XHJcblx0XHRwb3N0RmlsdGVyID0gc2V0TWF0Y2hlciggcG9zdEZpbHRlciApO1xyXG5cdH1cclxuXHRpZiAoIHBvc3RGaW5kZXIgJiYgIXBvc3RGaW5kZXJbIGV4cGFuZG8gXSApIHtcclxuXHRcdHBvc3RGaW5kZXIgPSBzZXRNYXRjaGVyKCBwb3N0RmluZGVyLCBwb3N0U2VsZWN0b3IgKTtcclxuXHR9XHJcblx0cmV0dXJuIG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgcmVzdWx0cywgY29udGV4dCwgeG1sICkge1xyXG5cdFx0dmFyIHRlbXAsIGksIGVsZW0sXHJcblx0XHRcdHByZU1hcCA9IFtdLFxyXG5cdFx0XHRwb3N0TWFwID0gW10sXHJcblx0XHRcdHByZWV4aXN0aW5nID0gcmVzdWx0cy5sZW5ndGgsXHJcblxyXG5cdFx0XHQvLyBHZXQgaW5pdGlhbCBlbGVtZW50cyBmcm9tIHNlZWQgb3IgY29udGV4dFxyXG5cdFx0XHRlbGVtcyA9IHNlZWQgfHwgbXVsdGlwbGVDb250ZXh0cyggc2VsZWN0b3IgfHwgXCIqXCIsIGNvbnRleHQubm9kZVR5cGUgPyBbIGNvbnRleHQgXSA6IGNvbnRleHQsIFtdICksXHJcblxyXG5cdFx0XHQvLyBQcmVmaWx0ZXIgdG8gZ2V0IG1hdGNoZXIgaW5wdXQsIHByZXNlcnZpbmcgYSBtYXAgZm9yIHNlZWQtcmVzdWx0cyBzeW5jaHJvbml6YXRpb25cclxuXHRcdFx0bWF0Y2hlckluID0gcHJlRmlsdGVyICYmICggc2VlZCB8fCAhc2VsZWN0b3IgKSA/XHJcblx0XHRcdFx0Y29uZGVuc2UoIGVsZW1zLCBwcmVNYXAsIHByZUZpbHRlciwgY29udGV4dCwgeG1sICkgOlxyXG5cdFx0XHRcdGVsZW1zLFxyXG5cclxuXHRcdFx0bWF0Y2hlck91dCA9IG1hdGNoZXIgP1xyXG5cdFx0XHRcdC8vIElmIHdlIGhhdmUgYSBwb3N0RmluZGVyLCBvciBmaWx0ZXJlZCBzZWVkLCBvciBub24tc2VlZCBwb3N0RmlsdGVyIG9yIHByZWV4aXN0aW5nIHJlc3VsdHMsXHJcblx0XHRcdFx0cG9zdEZpbmRlciB8fCAoIHNlZWQgPyBwcmVGaWx0ZXIgOiBwcmVleGlzdGluZyB8fCBwb3N0RmlsdGVyICkgP1xyXG5cclxuXHRcdFx0XHRcdC8vIC4uLmludGVybWVkaWF0ZSBwcm9jZXNzaW5nIGlzIG5lY2Vzc2FyeVxyXG5cdFx0XHRcdFx0W10gOlxyXG5cclxuXHRcdFx0XHRcdC8vIC4uLm90aGVyd2lzZSB1c2UgcmVzdWx0cyBkaXJlY3RseVxyXG5cdFx0XHRcdFx0cmVzdWx0cyA6XHJcblx0XHRcdFx0bWF0Y2hlckluO1xyXG5cclxuXHRcdC8vIEZpbmQgcHJpbWFyeSBtYXRjaGVzXHJcblx0XHRpZiAoIG1hdGNoZXIgKSB7XHJcblx0XHRcdG1hdGNoZXIoIG1hdGNoZXJJbiwgbWF0Y2hlck91dCwgY29udGV4dCwgeG1sICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQXBwbHkgcG9zdEZpbHRlclxyXG5cdFx0aWYgKCBwb3N0RmlsdGVyICkge1xyXG5cdFx0XHR0ZW1wID0gY29uZGVuc2UoIG1hdGNoZXJPdXQsIHBvc3RNYXAgKTtcclxuXHRcdFx0cG9zdEZpbHRlciggdGVtcCwgW10sIGNvbnRleHQsIHhtbCApO1xyXG5cclxuXHRcdFx0Ly8gVW4tbWF0Y2ggZmFpbGluZyBlbGVtZW50cyBieSBtb3ZpbmcgdGhlbSBiYWNrIHRvIG1hdGNoZXJJblxyXG5cdFx0XHRpID0gdGVtcC5sZW5ndGg7XHJcblx0XHRcdHdoaWxlICggaS0tICkge1xyXG5cdFx0XHRcdGlmICggKGVsZW0gPSB0ZW1wW2ldKSApIHtcclxuXHRcdFx0XHRcdG1hdGNoZXJPdXRbIHBvc3RNYXBbaV0gXSA9ICEobWF0Y2hlckluWyBwb3N0TWFwW2ldIF0gPSBlbGVtKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIHNlZWQgKSB7XHJcblx0XHRcdGlmICggcG9zdEZpbmRlciB8fCBwcmVGaWx0ZXIgKSB7XHJcblx0XHRcdFx0aWYgKCBwb3N0RmluZGVyICkge1xyXG5cdFx0XHRcdFx0Ly8gR2V0IHRoZSBmaW5hbCBtYXRjaGVyT3V0IGJ5IGNvbmRlbnNpbmcgdGhpcyBpbnRlcm1lZGlhdGUgaW50byBwb3N0RmluZGVyIGNvbnRleHRzXHJcblx0XHRcdFx0XHR0ZW1wID0gW107XHJcblx0XHRcdFx0XHRpID0gbWF0Y2hlck91dC5sZW5ndGg7XHJcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcclxuXHRcdFx0XHRcdFx0aWYgKCAoZWxlbSA9IG1hdGNoZXJPdXRbaV0pICkge1xyXG5cdFx0XHRcdFx0XHRcdC8vIFJlc3RvcmUgbWF0Y2hlckluIHNpbmNlIGVsZW0gaXMgbm90IHlldCBhIGZpbmFsIG1hdGNoXHJcblx0XHRcdFx0XHRcdFx0dGVtcC5wdXNoKCAobWF0Y2hlckluW2ldID0gZWxlbSkgKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0cG9zdEZpbmRlciggbnVsbCwgKG1hdGNoZXJPdXQgPSBbXSksIHRlbXAsIHhtbCApO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gTW92ZSBtYXRjaGVkIGVsZW1lbnRzIGZyb20gc2VlZCB0byByZXN1bHRzIHRvIGtlZXAgdGhlbSBzeW5jaHJvbml6ZWRcclxuXHRcdFx0XHRpID0gbWF0Y2hlck91dC5sZW5ndGg7XHJcblx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XHJcblx0XHRcdFx0XHRpZiAoIChlbGVtID0gbWF0Y2hlck91dFtpXSkgJiZcclxuXHRcdFx0XHRcdFx0KHRlbXAgPSBwb3N0RmluZGVyID8gaW5kZXhPZiggc2VlZCwgZWxlbSApIDogcHJlTWFwW2ldKSA+IC0xICkge1xyXG5cclxuXHRcdFx0XHRcdFx0c2VlZFt0ZW1wXSA9ICEocmVzdWx0c1t0ZW1wXSA9IGVsZW0pO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdC8vIEFkZCBlbGVtZW50cyB0byByZXN1bHRzLCB0aHJvdWdoIHBvc3RGaW5kZXIgaWYgZGVmaW5lZFxyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0bWF0Y2hlck91dCA9IGNvbmRlbnNlKFxyXG5cdFx0XHRcdG1hdGNoZXJPdXQgPT09IHJlc3VsdHMgP1xyXG5cdFx0XHRcdFx0bWF0Y2hlck91dC5zcGxpY2UoIHByZWV4aXN0aW5nLCBtYXRjaGVyT3V0Lmxlbmd0aCApIDpcclxuXHRcdFx0XHRcdG1hdGNoZXJPdXRcclxuXHRcdFx0KTtcclxuXHRcdFx0aWYgKCBwb3N0RmluZGVyICkge1xyXG5cdFx0XHRcdHBvc3RGaW5kZXIoIG51bGwsIHJlc3VsdHMsIG1hdGNoZXJPdXQsIHhtbCApO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIG1hdGNoZXJPdXQgKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0pO1xyXG59XHJcblxyXG5mdW5jdGlvbiBtYXRjaGVyRnJvbVRva2VucyggdG9rZW5zICkge1xyXG5cdHZhciBjaGVja0NvbnRleHQsIG1hdGNoZXIsIGosXHJcblx0XHRsZW4gPSB0b2tlbnMubGVuZ3RoLFxyXG5cdFx0bGVhZGluZ1JlbGF0aXZlID0gRXhwci5yZWxhdGl2ZVsgdG9rZW5zWzBdLnR5cGUgXSxcclxuXHRcdGltcGxpY2l0UmVsYXRpdmUgPSBsZWFkaW5nUmVsYXRpdmUgfHwgRXhwci5yZWxhdGl2ZVtcIiBcIl0sXHJcblx0XHRpID0gbGVhZGluZ1JlbGF0aXZlID8gMSA6IDAsXHJcblxyXG5cdFx0Ly8gVGhlIGZvdW5kYXRpb25hbCBtYXRjaGVyIGVuc3VyZXMgdGhhdCBlbGVtZW50cyBhcmUgcmVhY2hhYmxlIGZyb20gdG9wLWxldmVsIGNvbnRleHQocylcclxuXHRcdG1hdGNoQ29udGV4dCA9IGFkZENvbWJpbmF0b3IoIGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gY2hlY2tDb250ZXh0O1xyXG5cdFx0fSwgaW1wbGljaXRSZWxhdGl2ZSwgdHJ1ZSApLFxyXG5cdFx0bWF0Y2hBbnlDb250ZXh0ID0gYWRkQ29tYmluYXRvciggZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdHJldHVybiBpbmRleE9mKCBjaGVja0NvbnRleHQsIGVsZW0gKSA+IC0xO1xyXG5cdFx0fSwgaW1wbGljaXRSZWxhdGl2ZSwgdHJ1ZSApLFxyXG5cdFx0bWF0Y2hlcnMgPSBbIGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XHJcblx0XHRcdHZhciByZXQgPSAoICFsZWFkaW5nUmVsYXRpdmUgJiYgKCB4bWwgfHwgY29udGV4dCAhPT0gb3V0ZXJtb3N0Q29udGV4dCApICkgfHwgKFxyXG5cdFx0XHRcdChjaGVja0NvbnRleHQgPSBjb250ZXh0KS5ub2RlVHlwZSA/XHJcblx0XHRcdFx0XHRtYXRjaENvbnRleHQoIGVsZW0sIGNvbnRleHQsIHhtbCApIDpcclxuXHRcdFx0XHRcdG1hdGNoQW55Q29udGV4dCggZWxlbSwgY29udGV4dCwgeG1sICkgKTtcclxuXHRcdFx0Ly8gQXZvaWQgaGFuZ2luZyBvbnRvIGVsZW1lbnQgKGlzc3VlICMyOTkpXHJcblx0XHRcdGNoZWNrQ29udGV4dCA9IG51bGw7XHJcblx0XHRcdHJldHVybiByZXQ7XHJcblx0XHR9IF07XHJcblxyXG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xyXG5cdFx0aWYgKCAobWF0Y2hlciA9IEV4cHIucmVsYXRpdmVbIHRva2Vuc1tpXS50eXBlIF0pICkge1xyXG5cdFx0XHRtYXRjaGVycyA9IFsgYWRkQ29tYmluYXRvcihlbGVtZW50TWF0Y2hlciggbWF0Y2hlcnMgKSwgbWF0Y2hlcikgXTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdG1hdGNoZXIgPSBFeHByLmZpbHRlclsgdG9rZW5zW2ldLnR5cGUgXS5hcHBseSggbnVsbCwgdG9rZW5zW2ldLm1hdGNoZXMgKTtcclxuXHJcblx0XHRcdC8vIFJldHVybiBzcGVjaWFsIHVwb24gc2VlaW5nIGEgcG9zaXRpb25hbCBtYXRjaGVyXHJcblx0XHRcdGlmICggbWF0Y2hlclsgZXhwYW5kbyBdICkge1xyXG5cdFx0XHRcdC8vIEZpbmQgdGhlIG5leHQgcmVsYXRpdmUgb3BlcmF0b3IgKGlmIGFueSkgZm9yIHByb3BlciBoYW5kbGluZ1xyXG5cdFx0XHRcdGogPSArK2k7XHJcblx0XHRcdFx0Zm9yICggOyBqIDwgbGVuOyBqKysgKSB7XHJcblx0XHRcdFx0XHRpZiAoIEV4cHIucmVsYXRpdmVbIHRva2Vuc1tqXS50eXBlIF0gKSB7XHJcblx0XHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRyZXR1cm4gc2V0TWF0Y2hlcihcclxuXHRcdFx0XHRcdGkgPiAxICYmIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApLFxyXG5cdFx0XHRcdFx0aSA+IDEgJiYgdG9TZWxlY3RvcihcclxuXHRcdFx0XHRcdFx0Ly8gSWYgdGhlIHByZWNlZGluZyB0b2tlbiB3YXMgYSBkZXNjZW5kYW50IGNvbWJpbmF0b3IsIGluc2VydCBhbiBpbXBsaWNpdCBhbnktZWxlbWVudCBgKmBcclxuXHRcdFx0XHRcdFx0dG9rZW5zLnNsaWNlKCAwLCBpIC0gMSApLmNvbmNhdCh7IHZhbHVlOiB0b2tlbnNbIGkgLSAyIF0udHlwZSA9PT0gXCIgXCIgPyBcIipcIiA6IFwiXCIgfSlcclxuXHRcdFx0XHRcdCkucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApLFxyXG5cdFx0XHRcdFx0bWF0Y2hlcixcclxuXHRcdFx0XHRcdGkgPCBqICYmIG1hdGNoZXJGcm9tVG9rZW5zKCB0b2tlbnMuc2xpY2UoIGksIGogKSApLFxyXG5cdFx0XHRcdFx0aiA8IGxlbiAmJiBtYXRjaGVyRnJvbVRva2VucyggKHRva2VucyA9IHRva2Vucy5zbGljZSggaiApKSApLFxyXG5cdFx0XHRcdFx0aiA8IGxlbiAmJiB0b1NlbGVjdG9yKCB0b2tlbnMgKVxyXG5cdFx0XHRcdCk7XHJcblx0XHRcdH1cclxuXHRcdFx0bWF0Y2hlcnMucHVzaCggbWF0Y2hlciApO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApO1xyXG59XHJcblxyXG5mdW5jdGlvbiBtYXRjaGVyRnJvbUdyb3VwTWF0Y2hlcnMoIGVsZW1lbnRNYXRjaGVycywgc2V0TWF0Y2hlcnMgKSB7XHJcblx0dmFyIGJ5U2V0ID0gc2V0TWF0Y2hlcnMubGVuZ3RoID4gMCxcclxuXHRcdGJ5RWxlbWVudCA9IGVsZW1lbnRNYXRjaGVycy5sZW5ndGggPiAwLFxyXG5cdFx0c3VwZXJNYXRjaGVyID0gZnVuY3Rpb24oIHNlZWQsIGNvbnRleHQsIHhtbCwgcmVzdWx0cywgb3V0ZXJtb3N0ICkge1xyXG5cdFx0XHR2YXIgZWxlbSwgaiwgbWF0Y2hlcixcclxuXHRcdFx0XHRtYXRjaGVkQ291bnQgPSAwLFxyXG5cdFx0XHRcdGkgPSBcIjBcIixcclxuXHRcdFx0XHR1bm1hdGNoZWQgPSBzZWVkICYmIFtdLFxyXG5cdFx0XHRcdHNldE1hdGNoZWQgPSBbXSxcclxuXHRcdFx0XHRjb250ZXh0QmFja3VwID0gb3V0ZXJtb3N0Q29udGV4dCxcclxuXHRcdFx0XHQvLyBXZSBtdXN0IGFsd2F5cyBoYXZlIGVpdGhlciBzZWVkIGVsZW1lbnRzIG9yIG91dGVybW9zdCBjb250ZXh0XHJcblx0XHRcdFx0ZWxlbXMgPSBzZWVkIHx8IGJ5RWxlbWVudCAmJiBFeHByLmZpbmRbXCJUQUdcIl0oIFwiKlwiLCBvdXRlcm1vc3QgKSxcclxuXHRcdFx0XHQvLyBVc2UgaW50ZWdlciBkaXJydW5zIGlmZiB0aGlzIGlzIHRoZSBvdXRlcm1vc3QgbWF0Y2hlclxyXG5cdFx0XHRcdGRpcnJ1bnNVbmlxdWUgPSAoZGlycnVucyArPSBjb250ZXh0QmFja3VwID09IG51bGwgPyAxIDogTWF0aC5yYW5kb20oKSB8fCAwLjEpLFxyXG5cdFx0XHRcdGxlbiA9IGVsZW1zLmxlbmd0aDtcclxuXHJcblx0XHRcdGlmICggb3V0ZXJtb3N0ICkge1xyXG5cdFx0XHRcdG91dGVybW9zdENvbnRleHQgPSBjb250ZXh0ID09PSBkb2N1bWVudCB8fCBjb250ZXh0IHx8IG91dGVybW9zdDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gQWRkIGVsZW1lbnRzIHBhc3NpbmcgZWxlbWVudE1hdGNoZXJzIGRpcmVjdGx5IHRvIHJlc3VsdHNcclxuXHRcdFx0Ly8gU3VwcG9ydDogSUU8OSwgU2FmYXJpXHJcblx0XHRcdC8vIFRvbGVyYXRlIE5vZGVMaXN0IHByb3BlcnRpZXMgKElFOiBcImxlbmd0aFwiOyBTYWZhcmk6IDxudW1iZXI+KSBtYXRjaGluZyBlbGVtZW50cyBieSBpZFxyXG5cdFx0XHRmb3IgKCA7IGkgIT09IGxlbiAmJiAoZWxlbSA9IGVsZW1zW2ldKSAhPSBudWxsOyBpKysgKSB7XHJcblx0XHRcdFx0aWYgKCBieUVsZW1lbnQgJiYgZWxlbSApIHtcclxuXHRcdFx0XHRcdGogPSAwO1xyXG5cdFx0XHRcdFx0aWYgKCAhY29udGV4dCAmJiBlbGVtLm93bmVyRG9jdW1lbnQgIT09IGRvY3VtZW50ICkge1xyXG5cdFx0XHRcdFx0XHRzZXREb2N1bWVudCggZWxlbSApO1xyXG5cdFx0XHRcdFx0XHR4bWwgPSAhZG9jdW1lbnRJc0hUTUw7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR3aGlsZSAoIChtYXRjaGVyID0gZWxlbWVudE1hdGNoZXJzW2orK10pICkge1xyXG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZXIoIGVsZW0sIGNvbnRleHQgfHwgZG9jdW1lbnQsIHhtbCkgKSB7XHJcblx0XHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XHJcblx0XHRcdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdGlmICggb3V0ZXJtb3N0ICkge1xyXG5cdFx0XHRcdFx0XHRkaXJydW5zID0gZGlycnVuc1VuaXF1ZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIFRyYWNrIHVubWF0Y2hlZCBlbGVtZW50cyBmb3Igc2V0IGZpbHRlcnNcclxuXHRcdFx0XHRpZiAoIGJ5U2V0ICkge1xyXG5cdFx0XHRcdFx0Ly8gVGhleSB3aWxsIGhhdmUgZ29uZSB0aHJvdWdoIGFsbCBwb3NzaWJsZSBtYXRjaGVyc1xyXG5cdFx0XHRcdFx0aWYgKCAoZWxlbSA9ICFtYXRjaGVyICYmIGVsZW0pICkge1xyXG5cdFx0XHRcdFx0XHRtYXRjaGVkQ291bnQtLTtcclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHQvLyBMZW5ndGhlbiB0aGUgYXJyYXkgZm9yIGV2ZXJ5IGVsZW1lbnQsIG1hdGNoZWQgb3Igbm90XHJcblx0XHRcdFx0XHRpZiAoIHNlZWQgKSB7XHJcblx0XHRcdFx0XHRcdHVubWF0Y2hlZC5wdXNoKCBlbGVtICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBgaWAgaXMgbm93IHRoZSBjb3VudCBvZiBlbGVtZW50cyB2aXNpdGVkIGFib3ZlLCBhbmQgYWRkaW5nIGl0IHRvIGBtYXRjaGVkQ291bnRgXHJcblx0XHRcdC8vIG1ha2VzIHRoZSBsYXR0ZXIgbm9ubmVnYXRpdmUuXHJcblx0XHRcdG1hdGNoZWRDb3VudCArPSBpO1xyXG5cclxuXHRcdFx0Ly8gQXBwbHkgc2V0IGZpbHRlcnMgdG8gdW5tYXRjaGVkIGVsZW1lbnRzXHJcblx0XHRcdC8vIE5PVEU6IFRoaXMgY2FuIGJlIHNraXBwZWQgaWYgdGhlcmUgYXJlIG5vIHVubWF0Y2hlZCBlbGVtZW50cyAoaS5lLiwgYG1hdGNoZWRDb3VudGBcclxuXHRcdFx0Ly8gZXF1YWxzIGBpYCksIHVubGVzcyB3ZSBkaWRuJ3QgdmlzaXQgX2FueV8gZWxlbWVudHMgaW4gdGhlIGFib3ZlIGxvb3AgYmVjYXVzZSB3ZSBoYXZlXHJcblx0XHRcdC8vIG5vIGVsZW1lbnQgbWF0Y2hlcnMgYW5kIG5vIHNlZWQuXHJcblx0XHRcdC8vIEluY3JlbWVudGluZyBhbiBpbml0aWFsbHktc3RyaW5nIFwiMFwiIGBpYCBhbGxvd3MgYGlgIHRvIHJlbWFpbiBhIHN0cmluZyBvbmx5IGluIHRoYXRcclxuXHRcdFx0Ly8gY2FzZSwgd2hpY2ggd2lsbCByZXN1bHQgaW4gYSBcIjAwXCIgYG1hdGNoZWRDb3VudGAgdGhhdCBkaWZmZXJzIGZyb20gYGlgIGJ1dCBpcyBhbHNvXHJcblx0XHRcdC8vIG51bWVyaWNhbGx5IHplcm8uXHJcblx0XHRcdGlmICggYnlTZXQgJiYgaSAhPT0gbWF0Y2hlZENvdW50ICkge1xyXG5cdFx0XHRcdGogPSAwO1xyXG5cdFx0XHRcdHdoaWxlICggKG1hdGNoZXIgPSBzZXRNYXRjaGVyc1tqKytdKSApIHtcclxuXHRcdFx0XHRcdG1hdGNoZXIoIHVubWF0Y2hlZCwgc2V0TWF0Y2hlZCwgY29udGV4dCwgeG1sICk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRpZiAoIHNlZWQgKSB7XHJcblx0XHRcdFx0XHQvLyBSZWludGVncmF0ZSBlbGVtZW50IG1hdGNoZXMgdG8gZWxpbWluYXRlIHRoZSBuZWVkIGZvciBzb3J0aW5nXHJcblx0XHRcdFx0XHRpZiAoIG1hdGNoZWRDb3VudCA+IDAgKSB7XHJcblx0XHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xyXG5cdFx0XHRcdFx0XHRcdGlmICggISh1bm1hdGNoZWRbaV0gfHwgc2V0TWF0Y2hlZFtpXSkgKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRzZXRNYXRjaGVkW2ldID0gcG9wLmNhbGwoIHJlc3VsdHMgKTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHQvLyBEaXNjYXJkIGluZGV4IHBsYWNlaG9sZGVyIHZhbHVlcyB0byBnZXQgb25seSBhY3R1YWwgbWF0Y2hlc1xyXG5cdFx0XHRcdFx0c2V0TWF0Y2hlZCA9IGNvbmRlbnNlKCBzZXRNYXRjaGVkICk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHQvLyBBZGQgbWF0Y2hlcyB0byByZXN1bHRzXHJcblx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgc2V0TWF0Y2hlZCApO1xyXG5cclxuXHRcdFx0XHQvLyBTZWVkbGVzcyBzZXQgbWF0Y2hlcyBzdWNjZWVkaW5nIG11bHRpcGxlIHN1Y2Nlc3NmdWwgbWF0Y2hlcnMgc3RpcHVsYXRlIHNvcnRpbmdcclxuXHRcdFx0XHRpZiAoIG91dGVybW9zdCAmJiAhc2VlZCAmJiBzZXRNYXRjaGVkLmxlbmd0aCA+IDAgJiZcclxuXHRcdFx0XHRcdCggbWF0Y2hlZENvdW50ICsgc2V0TWF0Y2hlcnMubGVuZ3RoICkgPiAxICkge1xyXG5cclxuXHRcdFx0XHRcdFNpenpsZS51bmlxdWVTb3J0KCByZXN1bHRzICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBPdmVycmlkZSBtYW5pcHVsYXRpb24gb2YgZ2xvYmFscyBieSBuZXN0ZWQgbWF0Y2hlcnNcclxuXHRcdFx0aWYgKCBvdXRlcm1vc3QgKSB7XHJcblx0XHRcdFx0ZGlycnVucyA9IGRpcnJ1bnNVbmlxdWU7XHJcblx0XHRcdFx0b3V0ZXJtb3N0Q29udGV4dCA9IGNvbnRleHRCYWNrdXA7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHJldHVybiB1bm1hdGNoZWQ7XHJcblx0XHR9O1xyXG5cclxuXHRyZXR1cm4gYnlTZXQgP1xyXG5cdFx0bWFya0Z1bmN0aW9uKCBzdXBlck1hdGNoZXIgKSA6XHJcblx0XHRzdXBlck1hdGNoZXI7XHJcbn1cclxuXHJcbmNvbXBpbGUgPSBTaXp6bGUuY29tcGlsZSA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgbWF0Y2ggLyogSW50ZXJuYWwgVXNlIE9ubHkgKi8gKSB7XHJcblx0dmFyIGksXHJcblx0XHRzZXRNYXRjaGVycyA9IFtdLFxyXG5cdFx0ZWxlbWVudE1hdGNoZXJzID0gW10sXHJcblx0XHRjYWNoZWQgPSBjb21waWxlckNhY2hlWyBzZWxlY3RvciArIFwiIFwiIF07XHJcblxyXG5cdGlmICggIWNhY2hlZCApIHtcclxuXHRcdC8vIEdlbmVyYXRlIGEgZnVuY3Rpb24gb2YgcmVjdXJzaXZlIGZ1bmN0aW9ucyB0aGF0IGNhbiBiZSB1c2VkIHRvIGNoZWNrIGVhY2ggZWxlbWVudFxyXG5cdFx0aWYgKCAhbWF0Y2ggKSB7XHJcblx0XHRcdG1hdGNoID0gdG9rZW5pemUoIHNlbGVjdG9yICk7XHJcblx0XHR9XHJcblx0XHRpID0gbWF0Y2gubGVuZ3RoO1xyXG5cdFx0d2hpbGUgKCBpLS0gKSB7XHJcblx0XHRcdGNhY2hlZCA9IG1hdGNoZXJGcm9tVG9rZW5zKCBtYXRjaFtpXSApO1xyXG5cdFx0XHRpZiAoIGNhY2hlZFsgZXhwYW5kbyBdICkge1xyXG5cdFx0XHRcdHNldE1hdGNoZXJzLnB1c2goIGNhY2hlZCApO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGVsZW1lbnRNYXRjaGVycy5wdXNoKCBjYWNoZWQgKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIENhY2hlIHRoZSBjb21waWxlZCBmdW5jdGlvblxyXG5cdFx0Y2FjaGVkID0gY29tcGlsZXJDYWNoZSggc2VsZWN0b3IsIG1hdGNoZXJGcm9tR3JvdXBNYXRjaGVycyggZWxlbWVudE1hdGNoZXJzLCBzZXRNYXRjaGVycyApICk7XHJcblxyXG5cdFx0Ly8gU2F2ZSBzZWxlY3RvciBhbmQgdG9rZW5pemF0aW9uXHJcblx0XHRjYWNoZWQuc2VsZWN0b3IgPSBzZWxlY3RvcjtcclxuXHR9XHJcblx0cmV0dXJuIGNhY2hlZDtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBBIGxvdy1sZXZlbCBzZWxlY3Rpb24gZnVuY3Rpb24gdGhhdCB3b3JrcyB3aXRoIFNpenpsZSdzIGNvbXBpbGVkXHJcbiAqICBzZWxlY3RvciBmdW5jdGlvbnNcclxuICogQHBhcmFtIHtTdHJpbmd8RnVuY3Rpb259IHNlbGVjdG9yIEEgc2VsZWN0b3Igb3IgYSBwcmUtY29tcGlsZWRcclxuICogIHNlbGVjdG9yIGZ1bmN0aW9uIGJ1aWx0IHdpdGggU2l6emxlLmNvbXBpbGVcclxuICogQHBhcmFtIHtFbGVtZW50fSBjb250ZXh0XHJcbiAqIEBwYXJhbSB7QXJyYXl9IFtyZXN1bHRzXVxyXG4gKiBAcGFyYW0ge0FycmF5fSBbc2VlZF0gQSBzZXQgb2YgZWxlbWVudHMgdG8gbWF0Y2ggYWdhaW5zdFxyXG4gKi9cclxuc2VsZWN0ID0gU2l6emxlLnNlbGVjdCA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCwgcmVzdWx0cywgc2VlZCApIHtcclxuXHR2YXIgaSwgdG9rZW5zLCB0b2tlbiwgdHlwZSwgZmluZCxcclxuXHRcdGNvbXBpbGVkID0gdHlwZW9mIHNlbGVjdG9yID09PSBcImZ1bmN0aW9uXCIgJiYgc2VsZWN0b3IsXHJcblx0XHRtYXRjaCA9ICFzZWVkICYmIHRva2VuaXplKCAoc2VsZWN0b3IgPSBjb21waWxlZC5zZWxlY3RvciB8fCBzZWxlY3RvcikgKTtcclxuXHJcblx0cmVzdWx0cyA9IHJlc3VsdHMgfHwgW107XHJcblxyXG5cdC8vIFRyeSB0byBtaW5pbWl6ZSBvcGVyYXRpb25zIGlmIHRoZXJlIGlzIG9ubHkgb25lIHNlbGVjdG9yIGluIHRoZSBsaXN0IGFuZCBubyBzZWVkXHJcblx0Ly8gKHRoZSBsYXR0ZXIgb2Ygd2hpY2ggZ3VhcmFudGVlcyB1cyBjb250ZXh0KVxyXG5cdGlmICggbWF0Y2gubGVuZ3RoID09PSAxICkge1xyXG5cclxuXHRcdC8vIFJlZHVjZSBjb250ZXh0IGlmIHRoZSBsZWFkaW5nIGNvbXBvdW5kIHNlbGVjdG9yIGlzIGFuIElEXHJcblx0XHR0b2tlbnMgPSBtYXRjaFswXSA9IG1hdGNoWzBdLnNsaWNlKCAwICk7XHJcblx0XHRpZiAoIHRva2Vucy5sZW5ndGggPiAyICYmICh0b2tlbiA9IHRva2Vuc1swXSkudHlwZSA9PT0gXCJJRFwiICYmXHJcblx0XHRcdFx0c3VwcG9ydC5nZXRCeUlkICYmIGNvbnRleHQubm9kZVR5cGUgPT09IDkgJiYgZG9jdW1lbnRJc0hUTUwgJiZcclxuXHRcdFx0XHRFeHByLnJlbGF0aXZlWyB0b2tlbnNbMV0udHlwZSBdICkge1xyXG5cclxuXHRcdFx0Y29udGV4dCA9ICggRXhwci5maW5kW1wiSURcIl0oIHRva2VuLm1hdGNoZXNbMF0ucmVwbGFjZShydW5lc2NhcGUsIGZ1bmVzY2FwZSksIGNvbnRleHQgKSB8fCBbXSApWzBdO1xyXG5cdFx0XHRpZiAoICFjb250ZXh0ICkge1xyXG5cdFx0XHRcdHJldHVybiByZXN1bHRzO1xyXG5cclxuXHRcdFx0Ly8gUHJlY29tcGlsZWQgbWF0Y2hlcnMgd2lsbCBzdGlsbCB2ZXJpZnkgYW5jZXN0cnksIHNvIHN0ZXAgdXAgYSBsZXZlbFxyXG5cdFx0XHR9IGVsc2UgaWYgKCBjb21waWxlZCApIHtcclxuXHRcdFx0XHRjb250ZXh0ID0gY29udGV4dC5wYXJlbnROb2RlO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRzZWxlY3RvciA9IHNlbGVjdG9yLnNsaWNlKCB0b2tlbnMuc2hpZnQoKS52YWx1ZS5sZW5ndGggKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBGZXRjaCBhIHNlZWQgc2V0IGZvciByaWdodC10by1sZWZ0IG1hdGNoaW5nXHJcblx0XHRpID0gbWF0Y2hFeHByW1wibmVlZHNDb250ZXh0XCJdLnRlc3QoIHNlbGVjdG9yICkgPyAwIDogdG9rZW5zLmxlbmd0aDtcclxuXHRcdHdoaWxlICggaS0tICkge1xyXG5cdFx0XHR0b2tlbiA9IHRva2Vuc1tpXTtcclxuXHJcblx0XHRcdC8vIEFib3J0IGlmIHdlIGhpdCBhIGNvbWJpbmF0b3JcclxuXHRcdFx0aWYgKCBFeHByLnJlbGF0aXZlWyAodHlwZSA9IHRva2VuLnR5cGUpIF0gKSB7XHJcblx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCAoZmluZCA9IEV4cHIuZmluZFsgdHlwZSBdKSApIHtcclxuXHRcdFx0XHQvLyBTZWFyY2gsIGV4cGFuZGluZyBjb250ZXh0IGZvciBsZWFkaW5nIHNpYmxpbmcgY29tYmluYXRvcnNcclxuXHRcdFx0XHRpZiAoIChzZWVkID0gZmluZChcclxuXHRcdFx0XHRcdHRva2VuLm1hdGNoZXNbMF0ucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKSxcclxuXHRcdFx0XHRcdHJzaWJsaW5nLnRlc3QoIHRva2Vuc1swXS50eXBlICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8IGNvbnRleHRcclxuXHRcdFx0XHQpKSApIHtcclxuXHJcblx0XHRcdFx0XHQvLyBJZiBzZWVkIGlzIGVtcHR5IG9yIG5vIHRva2VucyByZW1haW4sIHdlIGNhbiByZXR1cm4gZWFybHlcclxuXHRcdFx0XHRcdHRva2Vucy5zcGxpY2UoIGksIDEgKTtcclxuXHRcdFx0XHRcdHNlbGVjdG9yID0gc2VlZC5sZW5ndGggJiYgdG9TZWxlY3RvciggdG9rZW5zICk7XHJcblx0XHRcdFx0XHRpZiAoICFzZWxlY3RvciApIHtcclxuXHRcdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgc2VlZCApO1xyXG5cdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRicmVhaztcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8vIENvbXBpbGUgYW5kIGV4ZWN1dGUgYSBmaWx0ZXJpbmcgZnVuY3Rpb24gaWYgb25lIGlzIG5vdCBwcm92aWRlZFxyXG5cdC8vIFByb3ZpZGUgYG1hdGNoYCB0byBhdm9pZCByZXRva2VuaXphdGlvbiBpZiB3ZSBtb2RpZmllZCB0aGUgc2VsZWN0b3IgYWJvdmVcclxuXHQoIGNvbXBpbGVkIHx8IGNvbXBpbGUoIHNlbGVjdG9yLCBtYXRjaCApICkoXHJcblx0XHRzZWVkLFxyXG5cdFx0Y29udGV4dCxcclxuXHRcdCFkb2N1bWVudElzSFRNTCxcclxuXHRcdHJlc3VsdHMsXHJcblx0XHQhY29udGV4dCB8fCByc2libGluZy50ZXN0KCBzZWxlY3RvciApICYmIHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fCBjb250ZXh0XHJcblx0KTtcclxuXHRyZXR1cm4gcmVzdWx0cztcclxufTtcclxuXHJcbi8vIE9uZS10aW1lIGFzc2lnbm1lbnRzXHJcblxyXG4vLyBTb3J0IHN0YWJpbGl0eVxyXG5zdXBwb3J0LnNvcnRTdGFibGUgPSBleHBhbmRvLnNwbGl0KFwiXCIpLnNvcnQoIHNvcnRPcmRlciApLmpvaW4oXCJcIikgPT09IGV4cGFuZG87XHJcblxyXG4vLyBTdXBwb3J0OiBDaHJvbWUgMTQtMzUrXHJcbi8vIEFsd2F5cyBhc3N1bWUgZHVwbGljYXRlcyBpZiB0aGV5IGFyZW4ndCBwYXNzZWQgdG8gdGhlIGNvbXBhcmlzb24gZnVuY3Rpb25cclxuc3VwcG9ydC5kZXRlY3REdXBsaWNhdGVzID0gISFoYXNEdXBsaWNhdGU7XHJcblxyXG4vLyBJbml0aWFsaXplIGFnYWluc3QgdGhlIGRlZmF1bHQgZG9jdW1lbnRcclxuc2V0RG9jdW1lbnQoKTtcclxuXHJcbi8vIFN1cHBvcnQ6IFdlYmtpdDw1MzcuMzIgLSBTYWZhcmkgNi4wLjMvQ2hyb21lIDI1IChmaXhlZCBpbiBDaHJvbWUgMjcpXHJcbi8vIERldGFjaGVkIG5vZGVzIGNvbmZvdW5kaW5nbHkgZm9sbG93ICplYWNoIG90aGVyKlxyXG5zdXBwb3J0LnNvcnREZXRhY2hlZCA9IGFzc2VydChmdW5jdGlvbiggZGl2MSApIHtcclxuXHQvLyBTaG91bGQgcmV0dXJuIDEsIGJ1dCByZXR1cm5zIDQgKGZvbGxvd2luZylcclxuXHRyZXR1cm4gZGl2MS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKSApICYgMTtcclxufSk7XHJcblxyXG4vLyBTdXBwb3J0OiBJRTw4XHJcbi8vIFByZXZlbnQgYXR0cmlidXRlL3Byb3BlcnR5IFwiaW50ZXJwb2xhdGlvblwiXHJcbi8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNjQyOSUyOFZTLjg1JTI5LmFzcHhcclxuaWYgKCAhYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XHJcblx0ZGl2LmlubmVySFRNTCA9IFwiPGEgaHJlZj0nIyc+PC9hPlwiO1xyXG5cdHJldHVybiBkaXYuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpID09PSBcIiNcIiA7XHJcbn0pICkge1xyXG5cdGFkZEhhbmRsZSggXCJ0eXBlfGhyZWZ8aGVpZ2h0fHdpZHRoXCIsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcclxuXHRcdGlmICggIWlzWE1MICkge1xyXG5cdFx0XHRyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUsIG5hbWUudG9Mb3dlckNhc2UoKSA9PT0gXCJ0eXBlXCIgPyAxIDogMiApO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG59XHJcblxyXG4vLyBTdXBwb3J0OiBJRTw5XHJcbi8vIFVzZSBkZWZhdWx0VmFsdWUgaW4gcGxhY2Ugb2YgZ2V0QXR0cmlidXRlKFwidmFsdWVcIilcclxuaWYgKCAhc3VwcG9ydC5hdHRyaWJ1dGVzIHx8ICFhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcclxuXHRkaXYuaW5uZXJIVE1MID0gXCI8aW5wdXQvPlwiO1xyXG5cdGRpdi5maXJzdENoaWxkLnNldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiLCBcIlwiICk7XHJcblx0cmV0dXJuIGRpdi5maXJzdENoaWxkLmdldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiICkgPT09IFwiXCI7XHJcbn0pICkge1xyXG5cdGFkZEhhbmRsZSggXCJ2YWx1ZVwiLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XHJcblx0XHRpZiAoICFpc1hNTCAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IFwiaW5wdXRcIiApIHtcclxuXHRcdFx0cmV0dXJuIGVsZW0uZGVmYXVsdFZhbHVlO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG59XHJcblxyXG4vLyBTdXBwb3J0OiBJRTw5XHJcbi8vIFVzZSBnZXRBdHRyaWJ1dGVOb2RlIHRvIGZldGNoIGJvb2xlYW5zIHdoZW4gZ2V0QXR0cmlidXRlIGxpZXNcclxuaWYgKCAhYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XHJcblx0cmV0dXJuIGRpdi5nZXRBdHRyaWJ1dGUoXCJkaXNhYmxlZFwiKSA9PSBudWxsO1xyXG59KSApIHtcclxuXHRhZGRIYW5kbGUoIGJvb2xlYW5zLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XHJcblx0XHR2YXIgdmFsO1xyXG5cdFx0aWYgKCAhaXNYTUwgKSB7XHJcblx0XHRcdHJldHVybiBlbGVtWyBuYW1lIF0gPT09IHRydWUgPyBuYW1lLnRvTG93ZXJDYXNlKCkgOlxyXG5cdFx0XHRcdFx0KHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZSggbmFtZSApKSAmJiB2YWwuc3BlY2lmaWVkID9cclxuXHRcdFx0XHRcdHZhbC52YWx1ZSA6XHJcblx0XHRcdFx0bnVsbDtcclxuXHRcdH1cclxuXHR9KTtcclxufVxyXG5cclxucmV0dXJuIFNpenpsZTtcclxuXHJcbn0pKCB3aW5kb3cgKTtcclxuXHJcblxyXG5cclxualF1ZXJ5LmZpbmQgPSBTaXp6bGU7XHJcbmpRdWVyeS5leHByID0gU2l6emxlLnNlbGVjdG9ycztcclxualF1ZXJ5LmV4cHJbIFwiOlwiIF0gPSBqUXVlcnkuZXhwci5wc2V1ZG9zO1xyXG5qUXVlcnkudW5pcXVlU29ydCA9IGpRdWVyeS51bmlxdWUgPSBTaXp6bGUudW5pcXVlU29ydDtcclxualF1ZXJ5LnRleHQgPSBTaXp6bGUuZ2V0VGV4dDtcclxualF1ZXJ5LmlzWE1MRG9jID0gU2l6emxlLmlzWE1MO1xyXG5qUXVlcnkuY29udGFpbnMgPSBTaXp6bGUuY29udGFpbnM7XHJcblxyXG5cclxuXHJcbnZhciBkaXIgPSBmdW5jdGlvbiggZWxlbSwgZGlyLCB1bnRpbCApIHtcclxuXHR2YXIgbWF0Y2hlZCA9IFtdLFxyXG5cdFx0dHJ1bmNhdGUgPSB1bnRpbCAhPT0gdW5kZWZpbmVkO1xyXG5cclxuXHR3aGlsZSAoICggZWxlbSA9IGVsZW1bIGRpciBdICkgJiYgZWxlbS5ub2RlVHlwZSAhPT0gOSApIHtcclxuXHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcclxuXHRcdFx0aWYgKCB0cnVuY2F0ZSAmJiBqUXVlcnkoIGVsZW0gKS5pcyggdW50aWwgKSApIHtcclxuXHRcdFx0XHRicmVhaztcclxuXHRcdFx0fVxyXG5cdFx0XHRtYXRjaGVkLnB1c2goIGVsZW0gKTtcclxuXHRcdH1cclxuXHR9XHJcblx0cmV0dXJuIG1hdGNoZWQ7XHJcbn07XHJcblxyXG5cclxudmFyIHNpYmxpbmdzID0gZnVuY3Rpb24oIG4sIGVsZW0gKSB7XHJcblx0dmFyIG1hdGNoZWQgPSBbXTtcclxuXHJcblx0Zm9yICggOyBuOyBuID0gbi5uZXh0U2libGluZyApIHtcclxuXHRcdGlmICggbi5ub2RlVHlwZSA9PT0gMSAmJiBuICE9PSBlbGVtICkge1xyXG5cdFx0XHRtYXRjaGVkLnB1c2goIG4gKTtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJldHVybiBtYXRjaGVkO1xyXG59O1xyXG5cclxuXHJcbnZhciBybmVlZHNDb250ZXh0ID0galF1ZXJ5LmV4cHIubWF0Y2gubmVlZHNDb250ZXh0O1xyXG5cclxudmFyIHJzaW5nbGVUYWcgPSAoIC9ePChbXFx3LV0rKVxccypcXC8/Pig/OjxcXC9cXDE+fCkkLyApO1xyXG5cclxuXHJcblxyXG52YXIgcmlzU2ltcGxlID0gL14uW146I1xcW1xcLixdKiQvO1xyXG5cclxuLy8gSW1wbGVtZW50IHRoZSBpZGVudGljYWwgZnVuY3Rpb25hbGl0eSBmb3IgZmlsdGVyIGFuZCBub3RcclxuZnVuY3Rpb24gd2lubm93KCBlbGVtZW50cywgcXVhbGlmaWVyLCBub3QgKSB7XHJcblx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggcXVhbGlmaWVyICkgKSB7XHJcblx0XHRyZXR1cm4galF1ZXJ5LmdyZXAoIGVsZW1lbnRzLCBmdW5jdGlvbiggZWxlbSwgaSApIHtcclxuXHRcdFx0LyoganNoaW50IC1XMDE4ICovXHJcblx0XHRcdHJldHVybiAhIXF1YWxpZmllci5jYWxsKCBlbGVtLCBpLCBlbGVtICkgIT09IG5vdDtcclxuXHRcdH0gKTtcclxuXHJcblx0fVxyXG5cclxuXHRpZiAoIHF1YWxpZmllci5ub2RlVHlwZSApIHtcclxuXHRcdHJldHVybiBqUXVlcnkuZ3JlcCggZWxlbWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHRyZXR1cm4gKCBlbGVtID09PSBxdWFsaWZpZXIgKSAhPT0gbm90O1xyXG5cdFx0fSApO1xyXG5cclxuXHR9XHJcblxyXG5cdGlmICggdHlwZW9mIHF1YWxpZmllciA9PT0gXCJzdHJpbmdcIiApIHtcclxuXHRcdGlmICggcmlzU2ltcGxlLnRlc3QoIHF1YWxpZmllciApICkge1xyXG5cdFx0XHRyZXR1cm4galF1ZXJ5LmZpbHRlciggcXVhbGlmaWVyLCBlbGVtZW50cywgbm90ICk7XHJcblx0XHR9XHJcblxyXG5cdFx0cXVhbGlmaWVyID0galF1ZXJ5LmZpbHRlciggcXVhbGlmaWVyLCBlbGVtZW50cyApO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIGpRdWVyeS5ncmVwKCBlbGVtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRyZXR1cm4gKCBpbmRleE9mLmNhbGwoIHF1YWxpZmllciwgZWxlbSApID4gLTEgKSAhPT0gbm90O1xyXG5cdH0gKTtcclxufVxyXG5cclxualF1ZXJ5LmZpbHRlciA9IGZ1bmN0aW9uKCBleHByLCBlbGVtcywgbm90ICkge1xyXG5cdHZhciBlbGVtID0gZWxlbXNbIDAgXTtcclxuXHJcblx0aWYgKCBub3QgKSB7XHJcblx0XHRleHByID0gXCI6bm90KFwiICsgZXhwciArIFwiKVwiO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIGVsZW1zLmxlbmd0aCA9PT0gMSAmJiBlbGVtLm5vZGVUeXBlID09PSAxID9cclxuXHRcdGpRdWVyeS5maW5kLm1hdGNoZXNTZWxlY3RvciggZWxlbSwgZXhwciApID8gWyBlbGVtIF0gOiBbXSA6XHJcblx0XHRqUXVlcnkuZmluZC5tYXRjaGVzKCBleHByLCBqUXVlcnkuZ3JlcCggZWxlbXMsIGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHRyZXR1cm4gZWxlbS5ub2RlVHlwZSA9PT0gMTtcclxuXHRcdH0gKSApO1xyXG59O1xyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdGZpbmQ6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcclxuXHRcdHZhciBpLFxyXG5cdFx0XHRsZW4gPSB0aGlzLmxlbmd0aCxcclxuXHRcdFx0cmV0ID0gW10sXHJcblx0XHRcdHNlbGYgPSB0aGlzO1xyXG5cclxuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yICE9PSBcInN0cmluZ1wiICkge1xyXG5cdFx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIGpRdWVyeSggc2VsZWN0b3IgKS5maWx0ZXIoIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgbGVuOyBpKysgKSB7XHJcblx0XHRcdFx0XHRpZiAoIGpRdWVyeS5jb250YWlucyggc2VsZlsgaSBdLCB0aGlzICkgKSB7XHJcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSApICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Zm9yICggaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcclxuXHRcdFx0alF1ZXJ5LmZpbmQoIHNlbGVjdG9yLCBzZWxmWyBpIF0sIHJldCApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIE5lZWRlZCBiZWNhdXNlICQoIHNlbGVjdG9yLCBjb250ZXh0ICkgYmVjb21lcyAkKCBjb250ZXh0ICkuZmluZCggc2VsZWN0b3IgKVxyXG5cdFx0cmV0ID0gdGhpcy5wdXNoU3RhY2soIGxlbiA+IDEgPyBqUXVlcnkudW5pcXVlKCByZXQgKSA6IHJldCApO1xyXG5cdFx0cmV0LnNlbGVjdG9yID0gdGhpcy5zZWxlY3RvciA/IHRoaXMuc2VsZWN0b3IgKyBcIiBcIiArIHNlbGVjdG9yIDogc2VsZWN0b3I7XHJcblx0XHRyZXR1cm4gcmV0O1xyXG5cdH0sXHJcblx0ZmlsdGVyOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHdpbm5vdyggdGhpcywgc2VsZWN0b3IgfHwgW10sIGZhbHNlICkgKTtcclxuXHR9LFxyXG5cdG5vdDogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xyXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCB3aW5ub3coIHRoaXMsIHNlbGVjdG9yIHx8IFtdLCB0cnVlICkgKTtcclxuXHR9LFxyXG5cdGlzOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XHJcblx0XHRyZXR1cm4gISF3aW5ub3coXHJcblx0XHRcdHRoaXMsXHJcblxyXG5cdFx0XHQvLyBJZiB0aGlzIGlzIGEgcG9zaXRpb25hbC9yZWxhdGl2ZSBzZWxlY3RvciwgY2hlY2sgbWVtYmVyc2hpcCBpbiB0aGUgcmV0dXJuZWQgc2V0XHJcblx0XHRcdC8vIHNvICQoXCJwOmZpcnN0XCIpLmlzKFwicDpsYXN0XCIpIHdvbid0IHJldHVybiB0cnVlIGZvciBhIGRvYyB3aXRoIHR3byBcInBcIi5cclxuXHRcdFx0dHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICYmIHJuZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3IgKSA/XHJcblx0XHRcdFx0alF1ZXJ5KCBzZWxlY3RvciApIDpcclxuXHRcdFx0XHRzZWxlY3RvciB8fCBbXSxcclxuXHRcdFx0ZmFsc2VcclxuXHRcdCkubGVuZ3RoO1xyXG5cdH1cclxufSApO1xyXG5cclxuXHJcbi8vIEluaXRpYWxpemUgYSBqUXVlcnkgb2JqZWN0XHJcblxyXG5cclxuLy8gQSBjZW50cmFsIHJlZmVyZW5jZSB0byB0aGUgcm9vdCBqUXVlcnkoZG9jdW1lbnQpXHJcbnZhciByb290alF1ZXJ5LFxyXG5cclxuXHQvLyBBIHNpbXBsZSB3YXkgdG8gY2hlY2sgZm9yIEhUTUwgc3RyaW5nc1xyXG5cdC8vIFByaW9yaXRpemUgI2lkIG92ZXIgPHRhZz4gdG8gYXZvaWQgWFNTIHZpYSBsb2NhdGlvbi5oYXNoICgjOTUyMSlcclxuXHQvLyBTdHJpY3QgSFRNTCByZWNvZ25pdGlvbiAoIzExMjkwOiBtdXN0IHN0YXJ0IHdpdGggPClcclxuXHRycXVpY2tFeHByID0gL14oPzpcXHMqKDxbXFx3XFxXXSs+KVtePl0qfCMoW1xcdy1dKikpJC8sXHJcblxyXG5cdGluaXQgPSBqUXVlcnkuZm4uaW5pdCA9IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCwgcm9vdCApIHtcclxuXHRcdHZhciBtYXRjaCwgZWxlbTtcclxuXHJcblx0XHQvLyBIQU5ETEU6ICQoXCJcIiksICQobnVsbCksICQodW5kZWZpbmVkKSwgJChmYWxzZSlcclxuXHRcdGlmICggIXNlbGVjdG9yICkge1xyXG5cdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdH1cclxuXHJcblx0XHQvLyBNZXRob2QgaW5pdCgpIGFjY2VwdHMgYW4gYWx0ZXJuYXRlIHJvb3RqUXVlcnlcclxuXHRcdC8vIHNvIG1pZ3JhdGUgY2FuIHN1cHBvcnQgalF1ZXJ5LnN1YiAoZ2gtMjEwMSlcclxuXHRcdHJvb3QgPSByb290IHx8IHJvb3RqUXVlcnk7XHJcblxyXG5cdFx0Ly8gSGFuZGxlIEhUTUwgc3RyaW5nc1xyXG5cdFx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdGlmICggc2VsZWN0b3JbIDAgXSA9PT0gXCI8XCIgJiZcclxuXHRcdFx0XHRzZWxlY3Rvclsgc2VsZWN0b3IubGVuZ3RoIC0gMSBdID09PSBcIj5cIiAmJlxyXG5cdFx0XHRcdHNlbGVjdG9yLmxlbmd0aCA+PSAzICkge1xyXG5cclxuXHRcdFx0XHQvLyBBc3N1bWUgdGhhdCBzdHJpbmdzIHRoYXQgc3RhcnQgYW5kIGVuZCB3aXRoIDw+IGFyZSBIVE1MIGFuZCBza2lwIHRoZSByZWdleCBjaGVja1xyXG5cdFx0XHRcdG1hdGNoID0gWyBudWxsLCBzZWxlY3RvciwgbnVsbCBdO1xyXG5cclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRtYXRjaCA9IHJxdWlja0V4cHIuZXhlYyggc2VsZWN0b3IgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gTWF0Y2ggaHRtbCBvciBtYWtlIHN1cmUgbm8gY29udGV4dCBpcyBzcGVjaWZpZWQgZm9yICNpZFxyXG5cdFx0XHRpZiAoIG1hdGNoICYmICggbWF0Y2hbIDEgXSB8fCAhY29udGV4dCApICkge1xyXG5cclxuXHRcdFx0XHQvLyBIQU5ETEU6ICQoaHRtbCkgLT4gJChhcnJheSlcclxuXHRcdFx0XHRpZiAoIG1hdGNoWyAxIF0gKSB7XHJcblx0XHRcdFx0XHRjb250ZXh0ID0gY29udGV4dCBpbnN0YW5jZW9mIGpRdWVyeSA/IGNvbnRleHRbIDAgXSA6IGNvbnRleHQ7XHJcblxyXG5cdFx0XHRcdFx0Ly8gT3B0aW9uIHRvIHJ1biBzY3JpcHRzIGlzIHRydWUgZm9yIGJhY2stY29tcGF0XHJcblx0XHRcdFx0XHQvLyBJbnRlbnRpb25hbGx5IGxldCB0aGUgZXJyb3IgYmUgdGhyb3duIGlmIHBhcnNlSFRNTCBpcyBub3QgcHJlc2VudFxyXG5cdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCB0aGlzLCBqUXVlcnkucGFyc2VIVE1MKFxyXG5cdFx0XHRcdFx0XHRtYXRjaFsgMSBdLFxyXG5cdFx0XHRcdFx0XHRjb250ZXh0ICYmIGNvbnRleHQubm9kZVR5cGUgPyBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCA6IGRvY3VtZW50LFxyXG5cdFx0XHRcdFx0XHR0cnVlXHJcblx0XHRcdFx0XHQpICk7XHJcblxyXG5cdFx0XHRcdFx0Ly8gSEFORExFOiAkKGh0bWwsIHByb3BzKVxyXG5cdFx0XHRcdFx0aWYgKCByc2luZ2xlVGFnLnRlc3QoIG1hdGNoWyAxIF0gKSAmJiBqUXVlcnkuaXNQbGFpbk9iamVjdCggY29udGV4dCApICkge1xyXG5cdFx0XHRcdFx0XHRmb3IgKCBtYXRjaCBpbiBjb250ZXh0ICkge1xyXG5cclxuXHRcdFx0XHRcdFx0XHQvLyBQcm9wZXJ0aWVzIG9mIGNvbnRleHQgYXJlIGNhbGxlZCBhcyBtZXRob2RzIGlmIHBvc3NpYmxlXHJcblx0XHRcdFx0XHRcdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggdGhpc1sgbWF0Y2ggXSApICkge1xyXG5cdFx0XHRcdFx0XHRcdFx0dGhpc1sgbWF0Y2ggXSggY29udGV4dFsgbWF0Y2ggXSApO1xyXG5cclxuXHRcdFx0XHRcdFx0XHQvLyAuLi5hbmQgb3RoZXJ3aXNlIHNldCBhcyBhdHRyaWJ1dGVzXHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdHRoaXMuYXR0ciggbWF0Y2gsIGNvbnRleHRbIG1hdGNoIF0gKTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcclxuXHJcblx0XHRcdFx0Ly8gSEFORExFOiAkKCNpZClcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0ZWxlbSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCBtYXRjaFsgMiBdICk7XHJcblxyXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogQmxhY2tiZXJyeSA0LjZcclxuXHRcdFx0XHRcdC8vIGdFQklEIHJldHVybnMgbm9kZXMgbm8gbG9uZ2VyIGluIHRoZSBkb2N1bWVudCAoIzY5NjMpXHJcblx0XHRcdFx0XHRpZiAoIGVsZW0gJiYgZWxlbS5wYXJlbnROb2RlICkge1xyXG5cclxuXHRcdFx0XHRcdFx0Ly8gSW5qZWN0IHRoZSBlbGVtZW50IGRpcmVjdGx5IGludG8gdGhlIGpRdWVyeSBvYmplY3RcclxuXHRcdFx0XHRcdFx0dGhpcy5sZW5ndGggPSAxO1xyXG5cdFx0XHRcdFx0XHR0aGlzWyAwIF0gPSBlbGVtO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdHRoaXMuY29udGV4dCA9IGRvY3VtZW50O1xyXG5cdFx0XHRcdFx0dGhpcy5zZWxlY3RvciA9IHNlbGVjdG9yO1xyXG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gSEFORExFOiAkKGV4cHIsICQoLi4uKSlcclxuXHRcdFx0fSBlbHNlIGlmICggIWNvbnRleHQgfHwgY29udGV4dC5qcXVlcnkgKSB7XHJcblx0XHRcdFx0cmV0dXJuICggY29udGV4dCB8fCByb290ICkuZmluZCggc2VsZWN0b3IgKTtcclxuXHJcblx0XHRcdC8vIEhBTkRMRTogJChleHByLCBjb250ZXh0KVxyXG5cdFx0XHQvLyAod2hpY2ggaXMganVzdCBlcXVpdmFsZW50IHRvOiAkKGNvbnRleHQpLmZpbmQoZXhwcilcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRyZXR1cm4gdGhpcy5jb25zdHJ1Y3RvciggY29udGV4dCApLmZpbmQoIHNlbGVjdG9yICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHQvLyBIQU5ETEU6ICQoRE9NRWxlbWVudClcclxuXHRcdH0gZWxzZSBpZiAoIHNlbGVjdG9yLm5vZGVUeXBlICkge1xyXG5cdFx0XHR0aGlzLmNvbnRleHQgPSB0aGlzWyAwIF0gPSBzZWxlY3RvcjtcclxuXHRcdFx0dGhpcy5sZW5ndGggPSAxO1xyXG5cdFx0XHRyZXR1cm4gdGhpcztcclxuXHJcblx0XHQvLyBIQU5ETEU6ICQoZnVuY3Rpb24pXHJcblx0XHQvLyBTaG9ydGN1dCBmb3IgZG9jdW1lbnQgcmVhZHlcclxuXHRcdH0gZWxzZSBpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBzZWxlY3RvciApICkge1xyXG5cdFx0XHRyZXR1cm4gcm9vdC5yZWFkeSAhPT0gdW5kZWZpbmVkID9cclxuXHRcdFx0XHRyb290LnJlYWR5KCBzZWxlY3RvciApIDpcclxuXHJcblx0XHRcdFx0Ly8gRXhlY3V0ZSBpbW1lZGlhdGVseSBpZiByZWFkeSBpcyBub3QgcHJlc2VudFxyXG5cdFx0XHRcdHNlbGVjdG9yKCBqUXVlcnkgKTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIHNlbGVjdG9yLnNlbGVjdG9yICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdHRoaXMuc2VsZWN0b3IgPSBzZWxlY3Rvci5zZWxlY3RvcjtcclxuXHRcdFx0dGhpcy5jb250ZXh0ID0gc2VsZWN0b3IuY29udGV4dDtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4galF1ZXJ5Lm1ha2VBcnJheSggc2VsZWN0b3IsIHRoaXMgKTtcclxuXHR9O1xyXG5cclxuLy8gR2l2ZSB0aGUgaW5pdCBmdW5jdGlvbiB0aGUgalF1ZXJ5IHByb3RvdHlwZSBmb3IgbGF0ZXIgaW5zdGFudGlhdGlvblxyXG5pbml0LnByb3RvdHlwZSA9IGpRdWVyeS5mbjtcclxuXHJcbi8vIEluaXRpYWxpemUgY2VudHJhbCByZWZlcmVuY2Vcclxucm9vdGpRdWVyeSA9IGpRdWVyeSggZG9jdW1lbnQgKTtcclxuXHJcblxyXG52YXIgcnBhcmVudHNwcmV2ID0gL14oPzpwYXJlbnRzfHByZXYoPzpVbnRpbHxBbGwpKS8sXHJcblxyXG5cdC8vIE1ldGhvZHMgZ3VhcmFudGVlZCB0byBwcm9kdWNlIGEgdW5pcXVlIHNldCB3aGVuIHN0YXJ0aW5nIGZyb20gYSB1bmlxdWUgc2V0XHJcblx0Z3VhcmFudGVlZFVuaXF1ZSA9IHtcclxuXHRcdGNoaWxkcmVuOiB0cnVlLFxyXG5cdFx0Y29udGVudHM6IHRydWUsXHJcblx0XHRuZXh0OiB0cnVlLFxyXG5cdFx0cHJldjogdHJ1ZVxyXG5cdH07XHJcblxyXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XHJcblx0aGFzOiBmdW5jdGlvbiggdGFyZ2V0ICkge1xyXG5cdFx0dmFyIHRhcmdldHMgPSBqUXVlcnkoIHRhcmdldCwgdGhpcyApLFxyXG5cdFx0XHRsID0gdGFyZ2V0cy5sZW5ndGg7XHJcblxyXG5cdFx0cmV0dXJuIHRoaXMuZmlsdGVyKCBmdW5jdGlvbigpIHtcclxuXHRcdFx0dmFyIGkgPSAwO1xyXG5cdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XHJcblx0XHRcdFx0aWYgKCBqUXVlcnkuY29udGFpbnMoIHRoaXMsIHRhcmdldHNbIGkgXSApICkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9ICk7XHJcblx0fSxcclxuXHJcblx0Y2xvc2VzdDogZnVuY3Rpb24oIHNlbGVjdG9ycywgY29udGV4dCApIHtcclxuXHRcdHZhciBjdXIsXHJcblx0XHRcdGkgPSAwLFxyXG5cdFx0XHRsID0gdGhpcy5sZW5ndGgsXHJcblx0XHRcdG1hdGNoZWQgPSBbXSxcclxuXHRcdFx0cG9zID0gcm5lZWRzQ29udGV4dC50ZXN0KCBzZWxlY3RvcnMgKSB8fCB0eXBlb2Ygc2VsZWN0b3JzICE9PSBcInN0cmluZ1wiID9cclxuXHRcdFx0XHRqUXVlcnkoIHNlbGVjdG9ycywgY29udGV4dCB8fCB0aGlzLmNvbnRleHQgKSA6XHJcblx0XHRcdFx0MDtcclxuXHJcblx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XHJcblx0XHRcdGZvciAoIGN1ciA9IHRoaXNbIGkgXTsgY3VyICYmIGN1ciAhPT0gY29udGV4dDsgY3VyID0gY3VyLnBhcmVudE5vZGUgKSB7XHJcblxyXG5cdFx0XHRcdC8vIEFsd2F5cyBza2lwIGRvY3VtZW50IGZyYWdtZW50c1xyXG5cdFx0XHRcdGlmICggY3VyLm5vZGVUeXBlIDwgMTEgJiYgKCBwb3MgP1xyXG5cdFx0XHRcdFx0cG9zLmluZGV4KCBjdXIgKSA+IC0xIDpcclxuXHJcblx0XHRcdFx0XHQvLyBEb24ndCBwYXNzIG5vbi1lbGVtZW50cyB0byBTaXp6bGVcclxuXHRcdFx0XHRcdGN1ci5ub2RlVHlwZSA9PT0gMSAmJlxyXG5cdFx0XHRcdFx0XHRqUXVlcnkuZmluZC5tYXRjaGVzU2VsZWN0b3IoIGN1ciwgc2VsZWN0b3JzICkgKSApIHtcclxuXHJcblx0XHRcdFx0XHRtYXRjaGVkLnB1c2goIGN1ciApO1xyXG5cdFx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCBtYXRjaGVkLmxlbmd0aCA+IDEgPyBqUXVlcnkudW5pcXVlU29ydCggbWF0Y2hlZCApIDogbWF0Y2hlZCApO1xyXG5cdH0sXHJcblxyXG5cdC8vIERldGVybWluZSB0aGUgcG9zaXRpb24gb2YgYW4gZWxlbWVudCB3aXRoaW4gdGhlIHNldFxyXG5cdGluZGV4OiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHJcblx0XHQvLyBObyBhcmd1bWVudCwgcmV0dXJuIGluZGV4IGluIHBhcmVudFxyXG5cdFx0aWYgKCAhZWxlbSApIHtcclxuXHRcdFx0cmV0dXJuICggdGhpc1sgMCBdICYmIHRoaXNbIDAgXS5wYXJlbnROb2RlICkgPyB0aGlzLmZpcnN0KCkucHJldkFsbCgpLmxlbmd0aCA6IC0xO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEluZGV4IGluIHNlbGVjdG9yXHJcblx0XHRpZiAoIHR5cGVvZiBlbGVtID09PSBcInN0cmluZ1wiICkge1xyXG5cdFx0XHRyZXR1cm4gaW5kZXhPZi5jYWxsKCBqUXVlcnkoIGVsZW0gKSwgdGhpc1sgMCBdICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gTG9jYXRlIHRoZSBwb3NpdGlvbiBvZiB0aGUgZGVzaXJlZCBlbGVtZW50XHJcblx0XHRyZXR1cm4gaW5kZXhPZi5jYWxsKCB0aGlzLFxyXG5cclxuXHRcdFx0Ly8gSWYgaXQgcmVjZWl2ZXMgYSBqUXVlcnkgb2JqZWN0LCB0aGUgZmlyc3QgZWxlbWVudCBpcyB1c2VkXHJcblx0XHRcdGVsZW0uanF1ZXJ5ID8gZWxlbVsgMCBdIDogZWxlbVxyXG5cdFx0KTtcclxuXHR9LFxyXG5cclxuXHRhZGQ6IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCApIHtcclxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayhcclxuXHRcdFx0alF1ZXJ5LnVuaXF1ZVNvcnQoXHJcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCB0aGlzLmdldCgpLCBqUXVlcnkoIHNlbGVjdG9yLCBjb250ZXh0ICkgKVxyXG5cdFx0XHQpXHJcblx0XHQpO1xyXG5cdH0sXHJcblxyXG5cdGFkZEJhY2s6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcclxuXHRcdHJldHVybiB0aGlzLmFkZCggc2VsZWN0b3IgPT0gbnVsbCA/XHJcblx0XHRcdHRoaXMucHJldk9iamVjdCA6IHRoaXMucHJldk9iamVjdC5maWx0ZXIoIHNlbGVjdG9yIClcclxuXHRcdCk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5mdW5jdGlvbiBzaWJsaW5nKCBjdXIsIGRpciApIHtcclxuXHR3aGlsZSAoICggY3VyID0gY3VyWyBkaXIgXSApICYmIGN1ci5ub2RlVHlwZSAhPT0gMSApIHt9XHJcblx0cmV0dXJuIGN1cjtcclxufVxyXG5cclxualF1ZXJ5LmVhY2goIHtcclxuXHRwYXJlbnQ6IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0dmFyIHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZTtcclxuXHRcdHJldHVybiBwYXJlbnQgJiYgcGFyZW50Lm5vZGVUeXBlICE9PSAxMSA/IHBhcmVudCA6IG51bGw7XHJcblx0fSxcclxuXHRwYXJlbnRzOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwicGFyZW50Tm9kZVwiICk7XHJcblx0fSxcclxuXHRwYXJlbnRzVW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBpLCB1bnRpbCApIHtcclxuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwicGFyZW50Tm9kZVwiLCB1bnRpbCApO1xyXG5cdH0sXHJcblx0bmV4dDogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRyZXR1cm4gc2libGluZyggZWxlbSwgXCJuZXh0U2libGluZ1wiICk7XHJcblx0fSxcclxuXHRwcmV2OiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdHJldHVybiBzaWJsaW5nKCBlbGVtLCBcInByZXZpb3VzU2libGluZ1wiICk7XHJcblx0fSxcclxuXHRuZXh0QWxsOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiApO1xyXG5cdH0sXHJcblx0cHJldkFsbDogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRyZXR1cm4gZGlyKCBlbGVtLCBcInByZXZpb3VzU2libGluZ1wiICk7XHJcblx0fSxcclxuXHRuZXh0VW50aWw6IGZ1bmN0aW9uKCBlbGVtLCBpLCB1bnRpbCApIHtcclxuXHRcdHJldHVybiBkaXIoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiwgdW50aWwgKTtcclxuXHR9LFxyXG5cdHByZXZVbnRpbDogZnVuY3Rpb24oIGVsZW0sIGksIHVudGlsICkge1xyXG5cdFx0cmV0dXJuIGRpciggZWxlbSwgXCJwcmV2aW91c1NpYmxpbmdcIiwgdW50aWwgKTtcclxuXHR9LFxyXG5cdHNpYmxpbmdzOiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdHJldHVybiBzaWJsaW5ncyggKCBlbGVtLnBhcmVudE5vZGUgfHwge30gKS5maXJzdENoaWxkLCBlbGVtICk7XHJcblx0fSxcclxuXHRjaGlsZHJlbjogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRyZXR1cm4gc2libGluZ3MoIGVsZW0uZmlyc3RDaGlsZCApO1xyXG5cdH0sXHJcblx0Y29udGVudHM6IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0cmV0dXJuIGVsZW0uY29udGVudERvY3VtZW50IHx8IGpRdWVyeS5tZXJnZSggW10sIGVsZW0uY2hpbGROb2RlcyApO1xyXG5cdH1cclxufSwgZnVuY3Rpb24oIG5hbWUsIGZuICkge1xyXG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHVudGlsLCBzZWxlY3RvciApIHtcclxuXHRcdHZhciBtYXRjaGVkID0galF1ZXJ5Lm1hcCggdGhpcywgZm4sIHVudGlsICk7XHJcblxyXG5cdFx0aWYgKCBuYW1lLnNsaWNlKCAtNSApICE9PSBcIlVudGlsXCIgKSB7XHJcblx0XHRcdHNlbGVjdG9yID0gdW50aWw7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBzZWxlY3RvciAmJiB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdG1hdGNoZWQgPSBqUXVlcnkuZmlsdGVyKCBzZWxlY3RvciwgbWF0Y2hlZCApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggdGhpcy5sZW5ndGggPiAxICkge1xyXG5cclxuXHRcdFx0Ly8gUmVtb3ZlIGR1cGxpY2F0ZXNcclxuXHRcdFx0aWYgKCAhZ3VhcmFudGVlZFVuaXF1ZVsgbmFtZSBdICkge1xyXG5cdFx0XHRcdGpRdWVyeS51bmlxdWVTb3J0KCBtYXRjaGVkICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFJldmVyc2Ugb3JkZXIgZm9yIHBhcmVudHMqIGFuZCBwcmV2LWRlcml2YXRpdmVzXHJcblx0XHRcdGlmICggcnBhcmVudHNwcmV2LnRlc3QoIG5hbWUgKSApIHtcclxuXHRcdFx0XHRtYXRjaGVkLnJldmVyc2UoKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggbWF0Y2hlZCApO1xyXG5cdH07XHJcbn0gKTtcclxudmFyIHJub3R3aGl0ZSA9ICggL1xcUysvZyApO1xyXG5cclxuXHJcblxyXG4vLyBDb252ZXJ0IFN0cmluZy1mb3JtYXR0ZWQgb3B0aW9ucyBpbnRvIE9iamVjdC1mb3JtYXR0ZWQgb25lc1xyXG5mdW5jdGlvbiBjcmVhdGVPcHRpb25zKCBvcHRpb25zICkge1xyXG5cdHZhciBvYmplY3QgPSB7fTtcclxuXHRqUXVlcnkuZWFjaCggb3B0aW9ucy5tYXRjaCggcm5vdHdoaXRlICkgfHwgW10sIGZ1bmN0aW9uKCBfLCBmbGFnICkge1xyXG5cdFx0b2JqZWN0WyBmbGFnIF0gPSB0cnVlO1xyXG5cdH0gKTtcclxuXHRyZXR1cm4gb2JqZWN0O1xyXG59XHJcblxyXG4vKlxyXG4gKiBDcmVhdGUgYSBjYWxsYmFjayBsaXN0IHVzaW5nIHRoZSBmb2xsb3dpbmcgcGFyYW1ldGVyczpcclxuICpcclxuICpcdG9wdGlvbnM6IGFuIG9wdGlvbmFsIGxpc3Qgb2Ygc3BhY2Utc2VwYXJhdGVkIG9wdGlvbnMgdGhhdCB3aWxsIGNoYW5nZSBob3dcclxuICpcdFx0XHR0aGUgY2FsbGJhY2sgbGlzdCBiZWhhdmVzIG9yIGEgbW9yZSB0cmFkaXRpb25hbCBvcHRpb24gb2JqZWN0XHJcbiAqXHJcbiAqIEJ5IGRlZmF1bHQgYSBjYWxsYmFjayBsaXN0IHdpbGwgYWN0IGxpa2UgYW4gZXZlbnQgY2FsbGJhY2sgbGlzdCBhbmQgY2FuIGJlXHJcbiAqIFwiZmlyZWRcIiBtdWx0aXBsZSB0aW1lcy5cclxuICpcclxuICogUG9zc2libGUgb3B0aW9uczpcclxuICpcclxuICpcdG9uY2U6XHRcdFx0d2lsbCBlbnN1cmUgdGhlIGNhbGxiYWNrIGxpc3QgY2FuIG9ubHkgYmUgZmlyZWQgb25jZSAobGlrZSBhIERlZmVycmVkKVxyXG4gKlxyXG4gKlx0bWVtb3J5Olx0XHRcdHdpbGwga2VlcCB0cmFjayBvZiBwcmV2aW91cyB2YWx1ZXMgYW5kIHdpbGwgY2FsbCBhbnkgY2FsbGJhY2sgYWRkZWRcclxuICpcdFx0XHRcdFx0YWZ0ZXIgdGhlIGxpc3QgaGFzIGJlZW4gZmlyZWQgcmlnaHQgYXdheSB3aXRoIHRoZSBsYXRlc3QgXCJtZW1vcml6ZWRcIlxyXG4gKlx0XHRcdFx0XHR2YWx1ZXMgKGxpa2UgYSBEZWZlcnJlZClcclxuICpcclxuICpcdHVuaXF1ZTpcdFx0XHR3aWxsIGVuc3VyZSBhIGNhbGxiYWNrIGNhbiBvbmx5IGJlIGFkZGVkIG9uY2UgKG5vIGR1cGxpY2F0ZSBpbiB0aGUgbGlzdClcclxuICpcclxuICpcdHN0b3BPbkZhbHNlOlx0aW50ZXJydXB0IGNhbGxpbmdzIHdoZW4gYSBjYWxsYmFjayByZXR1cm5zIGZhbHNlXHJcbiAqXHJcbiAqL1xyXG5qUXVlcnkuQ2FsbGJhY2tzID0gZnVuY3Rpb24oIG9wdGlvbnMgKSB7XHJcblxyXG5cdC8vIENvbnZlcnQgb3B0aW9ucyBmcm9tIFN0cmluZy1mb3JtYXR0ZWQgdG8gT2JqZWN0LWZvcm1hdHRlZCBpZiBuZWVkZWRcclxuXHQvLyAod2UgY2hlY2sgaW4gY2FjaGUgZmlyc3QpXHJcblx0b3B0aW9ucyA9IHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiID9cclxuXHRcdGNyZWF0ZU9wdGlvbnMoIG9wdGlvbnMgKSA6XHJcblx0XHRqUXVlcnkuZXh0ZW5kKCB7fSwgb3B0aW9ucyApO1xyXG5cclxuXHR2YXIgLy8gRmxhZyB0byBrbm93IGlmIGxpc3QgaXMgY3VycmVudGx5IGZpcmluZ1xyXG5cdFx0ZmlyaW5nLFxyXG5cclxuXHRcdC8vIExhc3QgZmlyZSB2YWx1ZSBmb3Igbm9uLWZvcmdldHRhYmxlIGxpc3RzXHJcblx0XHRtZW1vcnksXHJcblxyXG5cdFx0Ly8gRmxhZyB0byBrbm93IGlmIGxpc3Qgd2FzIGFscmVhZHkgZmlyZWRcclxuXHRcdGZpcmVkLFxyXG5cclxuXHRcdC8vIEZsYWcgdG8gcHJldmVudCBmaXJpbmdcclxuXHRcdGxvY2tlZCxcclxuXHJcblx0XHQvLyBBY3R1YWwgY2FsbGJhY2sgbGlzdFxyXG5cdFx0bGlzdCA9IFtdLFxyXG5cclxuXHRcdC8vIFF1ZXVlIG9mIGV4ZWN1dGlvbiBkYXRhIGZvciByZXBlYXRhYmxlIGxpc3RzXHJcblx0XHRxdWV1ZSA9IFtdLFxyXG5cclxuXHRcdC8vIEluZGV4IG9mIGN1cnJlbnRseSBmaXJpbmcgY2FsbGJhY2sgKG1vZGlmaWVkIGJ5IGFkZC9yZW1vdmUgYXMgbmVlZGVkKVxyXG5cdFx0ZmlyaW5nSW5kZXggPSAtMSxcclxuXHJcblx0XHQvLyBGaXJlIGNhbGxiYWNrc1xyXG5cdFx0ZmlyZSA9IGZ1bmN0aW9uKCkge1xyXG5cclxuXHRcdFx0Ly8gRW5mb3JjZSBzaW5nbGUtZmlyaW5nXHJcblx0XHRcdGxvY2tlZCA9IG9wdGlvbnMub25jZTtcclxuXHJcblx0XHRcdC8vIEV4ZWN1dGUgY2FsbGJhY2tzIGZvciBhbGwgcGVuZGluZyBleGVjdXRpb25zLFxyXG5cdFx0XHQvLyByZXNwZWN0aW5nIGZpcmluZ0luZGV4IG92ZXJyaWRlcyBhbmQgcnVudGltZSBjaGFuZ2VzXHJcblx0XHRcdGZpcmVkID0gZmlyaW5nID0gdHJ1ZTtcclxuXHRcdFx0Zm9yICggOyBxdWV1ZS5sZW5ndGg7IGZpcmluZ0luZGV4ID0gLTEgKSB7XHJcblx0XHRcdFx0bWVtb3J5ID0gcXVldWUuc2hpZnQoKTtcclxuXHRcdFx0XHR3aGlsZSAoICsrZmlyaW5nSW5kZXggPCBsaXN0Lmxlbmd0aCApIHtcclxuXHJcblx0XHRcdFx0XHQvLyBSdW4gY2FsbGJhY2sgYW5kIGNoZWNrIGZvciBlYXJseSB0ZXJtaW5hdGlvblxyXG5cdFx0XHRcdFx0aWYgKCBsaXN0WyBmaXJpbmdJbmRleCBdLmFwcGx5KCBtZW1vcnlbIDAgXSwgbWVtb3J5WyAxIF0gKSA9PT0gZmFsc2UgJiZcclxuXHRcdFx0XHRcdFx0b3B0aW9ucy5zdG9wT25GYWxzZSApIHtcclxuXHJcblx0XHRcdFx0XHRcdC8vIEp1bXAgdG8gZW5kIGFuZCBmb3JnZXQgdGhlIGRhdGEgc28gLmFkZCBkb2Vzbid0IHJlLWZpcmVcclxuXHRcdFx0XHRcdFx0ZmlyaW5nSW5kZXggPSBsaXN0Lmxlbmd0aDtcclxuXHRcdFx0XHRcdFx0bWVtb3J5ID0gZmFsc2U7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBGb3JnZXQgdGhlIGRhdGEgaWYgd2UncmUgZG9uZSB3aXRoIGl0XHJcblx0XHRcdGlmICggIW9wdGlvbnMubWVtb3J5ICkge1xyXG5cdFx0XHRcdG1lbW9yeSA9IGZhbHNlO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRmaXJpbmcgPSBmYWxzZTtcclxuXHJcblx0XHRcdC8vIENsZWFuIHVwIGlmIHdlJ3JlIGRvbmUgZmlyaW5nIGZvciBnb29kXHJcblx0XHRcdGlmICggbG9ja2VkICkge1xyXG5cclxuXHRcdFx0XHQvLyBLZWVwIGFuIGVtcHR5IGxpc3QgaWYgd2UgaGF2ZSBkYXRhIGZvciBmdXR1cmUgYWRkIGNhbGxzXHJcblx0XHRcdFx0aWYgKCBtZW1vcnkgKSB7XHJcblx0XHRcdFx0XHRsaXN0ID0gW107XHJcblxyXG5cdFx0XHRcdC8vIE90aGVyd2lzZSwgdGhpcyBvYmplY3QgaXMgc3BlbnRcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0bGlzdCA9IFwiXCI7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9LFxyXG5cclxuXHRcdC8vIEFjdHVhbCBDYWxsYmFja3Mgb2JqZWN0XHJcblx0XHRzZWxmID0ge1xyXG5cclxuXHRcdFx0Ly8gQWRkIGEgY2FsbGJhY2sgb3IgYSBjb2xsZWN0aW9uIG9mIGNhbGxiYWNrcyB0byB0aGUgbGlzdFxyXG5cdFx0XHRhZGQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGlmICggbGlzdCApIHtcclxuXHJcblx0XHRcdFx0XHQvLyBJZiB3ZSBoYXZlIG1lbW9yeSBmcm9tIGEgcGFzdCBydW4sIHdlIHNob3VsZCBmaXJlIGFmdGVyIGFkZGluZ1xyXG5cdFx0XHRcdFx0aWYgKCBtZW1vcnkgJiYgIWZpcmluZyApIHtcclxuXHRcdFx0XHRcdFx0ZmlyaW5nSW5kZXggPSBsaXN0Lmxlbmd0aCAtIDE7XHJcblx0XHRcdFx0XHRcdHF1ZXVlLnB1c2goIG1lbW9yeSApO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdCggZnVuY3Rpb24gYWRkKCBhcmdzICkge1xyXG5cdFx0XHRcdFx0XHRqUXVlcnkuZWFjaCggYXJncywgZnVuY3Rpb24oIF8sIGFyZyApIHtcclxuXHRcdFx0XHRcdFx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBhcmcgKSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdGlmICggIW9wdGlvbnMudW5pcXVlIHx8ICFzZWxmLmhhcyggYXJnICkgKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdGxpc3QucHVzaCggYXJnICk7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggYXJnICYmIGFyZy5sZW5ndGggJiYgalF1ZXJ5LnR5cGUoIGFyZyApICE9PSBcInN0cmluZ1wiICkge1xyXG5cclxuXHRcdFx0XHRcdFx0XHRcdC8vIEluc3BlY3QgcmVjdXJzaXZlbHlcclxuXHRcdFx0XHRcdFx0XHRcdGFkZCggYXJnICk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9ICk7XHJcblx0XHRcdFx0XHR9ICkoIGFyZ3VtZW50cyApO1xyXG5cclxuXHRcdFx0XHRcdGlmICggbWVtb3J5ICYmICFmaXJpbmcgKSB7XHJcblx0XHRcdFx0XHRcdGZpcmUoKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0cmV0dXJuIHRoaXM7XHJcblx0XHRcdH0sXHJcblxyXG5cdFx0XHQvLyBSZW1vdmUgYSBjYWxsYmFjayBmcm9tIHRoZSBsaXN0XHJcblx0XHRcdHJlbW92ZTogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0alF1ZXJ5LmVhY2goIGFyZ3VtZW50cywgZnVuY3Rpb24oIF8sIGFyZyApIHtcclxuXHRcdFx0XHRcdHZhciBpbmRleDtcclxuXHRcdFx0XHRcdHdoaWxlICggKCBpbmRleCA9IGpRdWVyeS5pbkFycmF5KCBhcmcsIGxpc3QsIGluZGV4ICkgKSA+IC0xICkge1xyXG5cdFx0XHRcdFx0XHRsaXN0LnNwbGljZSggaW5kZXgsIDEgKTtcclxuXHJcblx0XHRcdFx0XHRcdC8vIEhhbmRsZSBmaXJpbmcgaW5kZXhlc1xyXG5cdFx0XHRcdFx0XHRpZiAoIGluZGV4IDw9IGZpcmluZ0luZGV4ICkge1xyXG5cdFx0XHRcdFx0XHRcdGZpcmluZ0luZGV4LS07XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9ICk7XHJcblx0XHRcdFx0cmV0dXJuIHRoaXM7XHJcblx0XHRcdH0sXHJcblxyXG5cdFx0XHQvLyBDaGVjayBpZiBhIGdpdmVuIGNhbGxiYWNrIGlzIGluIHRoZSBsaXN0LlxyXG5cdFx0XHQvLyBJZiBubyBhcmd1bWVudCBpcyBnaXZlbiwgcmV0dXJuIHdoZXRoZXIgb3Igbm90IGxpc3QgaGFzIGNhbGxiYWNrcyBhdHRhY2hlZC5cclxuXHRcdFx0aGFzOiBmdW5jdGlvbiggZm4gKSB7XHJcblx0XHRcdFx0cmV0dXJuIGZuID9cclxuXHRcdFx0XHRcdGpRdWVyeS5pbkFycmF5KCBmbiwgbGlzdCApID4gLTEgOlxyXG5cdFx0XHRcdFx0bGlzdC5sZW5ndGggPiAwO1xyXG5cdFx0XHR9LFxyXG5cclxuXHRcdFx0Ly8gUmVtb3ZlIGFsbCBjYWxsYmFja3MgZnJvbSB0aGUgbGlzdFxyXG5cdFx0XHRlbXB0eTogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0aWYgKCBsaXN0ICkge1xyXG5cdFx0XHRcdFx0bGlzdCA9IFtdO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdFx0fSxcclxuXHJcblx0XHRcdC8vIERpc2FibGUgLmZpcmUgYW5kIC5hZGRcclxuXHRcdFx0Ly8gQWJvcnQgYW55IGN1cnJlbnQvcGVuZGluZyBleGVjdXRpb25zXHJcblx0XHRcdC8vIENsZWFyIGFsbCBjYWxsYmFja3MgYW5kIHZhbHVlc1xyXG5cdFx0XHRkaXNhYmxlOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRsb2NrZWQgPSBxdWV1ZSA9IFtdO1xyXG5cdFx0XHRcdGxpc3QgPSBtZW1vcnkgPSBcIlwiO1xyXG5cdFx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0XHR9LFxyXG5cdFx0XHRkaXNhYmxlZDogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0cmV0dXJuICFsaXN0O1xyXG5cdFx0XHR9LFxyXG5cclxuXHRcdFx0Ly8gRGlzYWJsZSAuZmlyZVxyXG5cdFx0XHQvLyBBbHNvIGRpc2FibGUgLmFkZCB1bmxlc3Mgd2UgaGF2ZSBtZW1vcnkgKHNpbmNlIGl0IHdvdWxkIGhhdmUgbm8gZWZmZWN0KVxyXG5cdFx0XHQvLyBBYm9ydCBhbnkgcGVuZGluZyBleGVjdXRpb25zXHJcblx0XHRcdGxvY2s6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGxvY2tlZCA9IHF1ZXVlID0gW107XHJcblx0XHRcdFx0aWYgKCAhbWVtb3J5ICkge1xyXG5cdFx0XHRcdFx0bGlzdCA9IG1lbW9yeSA9IFwiXCI7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0XHR9LFxyXG5cdFx0XHRsb2NrZWQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdHJldHVybiAhIWxvY2tlZDtcclxuXHRcdFx0fSxcclxuXHJcblx0XHRcdC8vIENhbGwgYWxsIGNhbGxiYWNrcyB3aXRoIHRoZSBnaXZlbiBjb250ZXh0IGFuZCBhcmd1bWVudHNcclxuXHRcdFx0ZmlyZVdpdGg6IGZ1bmN0aW9uKCBjb250ZXh0LCBhcmdzICkge1xyXG5cdFx0XHRcdGlmICggIWxvY2tlZCApIHtcclxuXHRcdFx0XHRcdGFyZ3MgPSBhcmdzIHx8IFtdO1xyXG5cdFx0XHRcdFx0YXJncyA9IFsgY29udGV4dCwgYXJncy5zbGljZSA/IGFyZ3Muc2xpY2UoKSA6IGFyZ3MgXTtcclxuXHRcdFx0XHRcdHF1ZXVlLnB1c2goIGFyZ3MgKTtcclxuXHRcdFx0XHRcdGlmICggIWZpcmluZyApIHtcclxuXHRcdFx0XHRcdFx0ZmlyZSgpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdFx0fSxcclxuXHJcblx0XHRcdC8vIENhbGwgYWxsIHRoZSBjYWxsYmFja3Mgd2l0aCB0aGUgZ2l2ZW4gYXJndW1lbnRzXHJcblx0XHRcdGZpcmU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdHNlbGYuZmlyZVdpdGgoIHRoaXMsIGFyZ3VtZW50cyApO1xyXG5cdFx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0XHR9LFxyXG5cclxuXHRcdFx0Ly8gVG8ga25vdyBpZiB0aGUgY2FsbGJhY2tzIGhhdmUgYWxyZWFkeSBiZWVuIGNhbGxlZCBhdCBsZWFzdCBvbmNlXHJcblx0XHRcdGZpcmVkOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRyZXR1cm4gISFmaXJlZDtcclxuXHRcdFx0fVxyXG5cdFx0fTtcclxuXHJcblx0cmV0dXJuIHNlbGY7XHJcbn07XHJcblxyXG5cclxualF1ZXJ5LmV4dGVuZCgge1xyXG5cclxuXHREZWZlcnJlZDogZnVuY3Rpb24oIGZ1bmMgKSB7XHJcblx0XHR2YXIgdHVwbGVzID0gW1xyXG5cclxuXHRcdFx0XHQvLyBhY3Rpb24sIGFkZCBsaXN0ZW5lciwgbGlzdGVuZXIgbGlzdCwgZmluYWwgc3RhdGVcclxuXHRcdFx0XHRbIFwicmVzb2x2ZVwiLCBcImRvbmVcIiwgalF1ZXJ5LkNhbGxiYWNrcyggXCJvbmNlIG1lbW9yeVwiICksIFwicmVzb2x2ZWRcIiBdLFxyXG5cdFx0XHRcdFsgXCJyZWplY3RcIiwgXCJmYWlsXCIsIGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLCBcInJlamVjdGVkXCIgXSxcclxuXHRcdFx0XHRbIFwibm90aWZ5XCIsIFwicHJvZ3Jlc3NcIiwgalF1ZXJ5LkNhbGxiYWNrcyggXCJtZW1vcnlcIiApIF1cclxuXHRcdFx0XSxcclxuXHRcdFx0c3RhdGUgPSBcInBlbmRpbmdcIixcclxuXHRcdFx0cHJvbWlzZSA9IHtcclxuXHRcdFx0XHRzdGF0ZTogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gc3RhdGU7XHJcblx0XHRcdFx0fSxcclxuXHRcdFx0XHRhbHdheXM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0ZGVmZXJyZWQuZG9uZSggYXJndW1lbnRzICkuZmFpbCggYXJndW1lbnRzICk7XHJcblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdFx0XHR9LFxyXG5cdFx0XHRcdHRoZW46IGZ1bmN0aW9uKCAvKiBmbkRvbmUsIGZuRmFpbCwgZm5Qcm9ncmVzcyAqLyApIHtcclxuXHRcdFx0XHRcdHZhciBmbnMgPSBhcmd1bWVudHM7XHJcblx0XHRcdFx0XHRyZXR1cm4galF1ZXJ5LkRlZmVycmVkKCBmdW5jdGlvbiggbmV3RGVmZXIgKSB7XHJcblx0XHRcdFx0XHRcdGpRdWVyeS5lYWNoKCB0dXBsZXMsIGZ1bmN0aW9uKCBpLCB0dXBsZSApIHtcclxuXHRcdFx0XHRcdFx0XHR2YXIgZm4gPSBqUXVlcnkuaXNGdW5jdGlvbiggZm5zWyBpIF0gKSAmJiBmbnNbIGkgXTtcclxuXHJcblx0XHRcdFx0XHRcdFx0Ly8gZGVmZXJyZWRbIGRvbmUgfCBmYWlsIHwgcHJvZ3Jlc3MgXSBmb3IgZm9yd2FyZGluZyBhY3Rpb25zIHRvIG5ld0RlZmVyXHJcblx0XHRcdFx0XHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAxIF0gXSggZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0XHRcdFx0XHR2YXIgcmV0dXJuZWQgPSBmbiAmJiBmbi5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XHJcblx0XHRcdFx0XHRcdFx0XHRpZiAoIHJldHVybmVkICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCByZXR1cm5lZC5wcm9taXNlICkgKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRcdHJldHVybmVkLnByb21pc2UoKVxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC5wcm9ncmVzcyggbmV3RGVmZXIubm90aWZ5IClcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHQuZG9uZSggbmV3RGVmZXIucmVzb2x2ZSApXHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0LmZhaWwoIG5ld0RlZmVyLnJlamVjdCApO1xyXG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0bmV3RGVmZXJbIHR1cGxlWyAwIF0gKyBcIldpdGhcIiBdKFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHRoaXMgPT09IHByb21pc2UgPyBuZXdEZWZlci5wcm9taXNlKCkgOiB0aGlzLFxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdGZuID8gWyByZXR1cm5lZCBdIDogYXJndW1lbnRzXHJcblx0XHRcdFx0XHRcdFx0XHRcdCk7XHJcblx0XHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdFx0fSApO1xyXG5cdFx0XHRcdFx0XHR9ICk7XHJcblx0XHRcdFx0XHRcdGZucyA9IG51bGw7XHJcblx0XHRcdFx0XHR9ICkucHJvbWlzZSgpO1xyXG5cdFx0XHRcdH0sXHJcblxyXG5cdFx0XHRcdC8vIEdldCBhIHByb21pc2UgZm9yIHRoaXMgZGVmZXJyZWRcclxuXHRcdFx0XHQvLyBJZiBvYmogaXMgcHJvdmlkZWQsIHRoZSBwcm9taXNlIGFzcGVjdCBpcyBhZGRlZCB0byB0aGUgb2JqZWN0XHJcblx0XHRcdFx0cHJvbWlzZTogZnVuY3Rpb24oIG9iaiApIHtcclxuXHRcdFx0XHRcdHJldHVybiBvYmogIT0gbnVsbCA/IGpRdWVyeS5leHRlbmQoIG9iaiwgcHJvbWlzZSApIDogcHJvbWlzZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0sXHJcblx0XHRcdGRlZmVycmVkID0ge307XHJcblxyXG5cdFx0Ly8gS2VlcCBwaXBlIGZvciBiYWNrLWNvbXBhdFxyXG5cdFx0cHJvbWlzZS5waXBlID0gcHJvbWlzZS50aGVuO1xyXG5cclxuXHRcdC8vIEFkZCBsaXN0LXNwZWNpZmljIG1ldGhvZHNcclxuXHRcdGpRdWVyeS5lYWNoKCB0dXBsZXMsIGZ1bmN0aW9uKCBpLCB0dXBsZSApIHtcclxuXHRcdFx0dmFyIGxpc3QgPSB0dXBsZVsgMiBdLFxyXG5cdFx0XHRcdHN0YXRlU3RyaW5nID0gdHVwbGVbIDMgXTtcclxuXHJcblx0XHRcdC8vIHByb21pc2VbIGRvbmUgfCBmYWlsIHwgcHJvZ3Jlc3MgXSA9IGxpc3QuYWRkXHJcblx0XHRcdHByb21pc2VbIHR1cGxlWyAxIF0gXSA9IGxpc3QuYWRkO1xyXG5cclxuXHRcdFx0Ly8gSGFuZGxlIHN0YXRlXHJcblx0XHRcdGlmICggc3RhdGVTdHJpbmcgKSB7XHJcblx0XHRcdFx0bGlzdC5hZGQoIGZ1bmN0aW9uKCkge1xyXG5cclxuXHRcdFx0XHRcdC8vIHN0YXRlID0gWyByZXNvbHZlZCB8IHJlamVjdGVkIF1cclxuXHRcdFx0XHRcdHN0YXRlID0gc3RhdGVTdHJpbmc7XHJcblxyXG5cdFx0XHRcdC8vIFsgcmVqZWN0X2xpc3QgfCByZXNvbHZlX2xpc3QgXS5kaXNhYmxlOyBwcm9ncmVzc19saXN0LmxvY2tcclxuXHRcdFx0XHR9LCB0dXBsZXNbIGkgXiAxIF1bIDIgXS5kaXNhYmxlLCB0dXBsZXNbIDIgXVsgMiBdLmxvY2sgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gZGVmZXJyZWRbIHJlc29sdmUgfCByZWplY3QgfCBub3RpZnkgXVxyXG5cdFx0XHRkZWZlcnJlZFsgdHVwbGVbIDAgXSBdID0gZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAwIF0gKyBcIldpdGhcIiBdKCB0aGlzID09PSBkZWZlcnJlZCA/IHByb21pc2UgOiB0aGlzLCBhcmd1bWVudHMgKTtcclxuXHRcdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdFx0fTtcclxuXHRcdFx0ZGVmZXJyZWRbIHR1cGxlWyAwIF0gKyBcIldpdGhcIiBdID0gbGlzdC5maXJlV2l0aDtcclxuXHRcdH0gKTtcclxuXHJcblx0XHQvLyBNYWtlIHRoZSBkZWZlcnJlZCBhIHByb21pc2VcclxuXHRcdHByb21pc2UucHJvbWlzZSggZGVmZXJyZWQgKTtcclxuXHJcblx0XHQvLyBDYWxsIGdpdmVuIGZ1bmMgaWYgYW55XHJcblx0XHRpZiAoIGZ1bmMgKSB7XHJcblx0XHRcdGZ1bmMuY2FsbCggZGVmZXJyZWQsIGRlZmVycmVkICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQWxsIGRvbmUhXHJcblx0XHRyZXR1cm4gZGVmZXJyZWQ7XHJcblx0fSxcclxuXHJcblx0Ly8gRGVmZXJyZWQgaGVscGVyXHJcblx0d2hlbjogZnVuY3Rpb24oIHN1Ym9yZGluYXRlIC8qICwgLi4uLCBzdWJvcmRpbmF0ZU4gKi8gKSB7XHJcblx0XHR2YXIgaSA9IDAsXHJcblx0XHRcdHJlc29sdmVWYWx1ZXMgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSxcclxuXHRcdFx0bGVuZ3RoID0gcmVzb2x2ZVZhbHVlcy5sZW5ndGgsXHJcblxyXG5cdFx0XHQvLyB0aGUgY291bnQgb2YgdW5jb21wbGV0ZWQgc3Vib3JkaW5hdGVzXHJcblx0XHRcdHJlbWFpbmluZyA9IGxlbmd0aCAhPT0gMSB8fFxyXG5cdFx0XHRcdCggc3Vib3JkaW5hdGUgJiYgalF1ZXJ5LmlzRnVuY3Rpb24oIHN1Ym9yZGluYXRlLnByb21pc2UgKSApID8gbGVuZ3RoIDogMCxcclxuXHJcblx0XHRcdC8vIHRoZSBtYXN0ZXIgRGVmZXJyZWQuXHJcblx0XHRcdC8vIElmIHJlc29sdmVWYWx1ZXMgY29uc2lzdCBvZiBvbmx5IGEgc2luZ2xlIERlZmVycmVkLCBqdXN0IHVzZSB0aGF0LlxyXG5cdFx0XHRkZWZlcnJlZCA9IHJlbWFpbmluZyA9PT0gMSA/IHN1Ym9yZGluYXRlIDogalF1ZXJ5LkRlZmVycmVkKCksXHJcblxyXG5cdFx0XHQvLyBVcGRhdGUgZnVuY3Rpb24gZm9yIGJvdGggcmVzb2x2ZSBhbmQgcHJvZ3Jlc3MgdmFsdWVzXHJcblx0XHRcdHVwZGF0ZUZ1bmMgPSBmdW5jdGlvbiggaSwgY29udGV4dHMsIHZhbHVlcyApIHtcclxuXHRcdFx0XHRyZXR1cm4gZnVuY3Rpb24oIHZhbHVlICkge1xyXG5cdFx0XHRcdFx0Y29udGV4dHNbIGkgXSA9IHRoaXM7XHJcblx0XHRcdFx0XHR2YWx1ZXNbIGkgXSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gc2xpY2UuY2FsbCggYXJndW1lbnRzICkgOiB2YWx1ZTtcclxuXHRcdFx0XHRcdGlmICggdmFsdWVzID09PSBwcm9ncmVzc1ZhbHVlcyApIHtcclxuXHRcdFx0XHRcdFx0ZGVmZXJyZWQubm90aWZ5V2l0aCggY29udGV4dHMsIHZhbHVlcyApO1xyXG5cdFx0XHRcdFx0fSBlbHNlIGlmICggISggLS1yZW1haW5pbmcgKSApIHtcclxuXHRcdFx0XHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIGNvbnRleHRzLCB2YWx1ZXMgKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9O1xyXG5cdFx0XHR9LFxyXG5cclxuXHRcdFx0cHJvZ3Jlc3NWYWx1ZXMsIHByb2dyZXNzQ29udGV4dHMsIHJlc29sdmVDb250ZXh0cztcclxuXHJcblx0XHQvLyBBZGQgbGlzdGVuZXJzIHRvIERlZmVycmVkIHN1Ym9yZGluYXRlczsgdHJlYXQgb3RoZXJzIGFzIHJlc29sdmVkXHJcblx0XHRpZiAoIGxlbmd0aCA+IDEgKSB7XHJcblx0XHRcdHByb2dyZXNzVmFsdWVzID0gbmV3IEFycmF5KCBsZW5ndGggKTtcclxuXHRcdFx0cHJvZ3Jlc3NDb250ZXh0cyA9IG5ldyBBcnJheSggbGVuZ3RoICk7XHJcblx0XHRcdHJlc29sdmVDb250ZXh0cyA9IG5ldyBBcnJheSggbGVuZ3RoICk7XHJcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xyXG5cdFx0XHRcdGlmICggcmVzb2x2ZVZhbHVlc1sgaSBdICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCByZXNvbHZlVmFsdWVzWyBpIF0ucHJvbWlzZSApICkge1xyXG5cdFx0XHRcdFx0cmVzb2x2ZVZhbHVlc1sgaSBdLnByb21pc2UoKVxyXG5cdFx0XHRcdFx0XHQucHJvZ3Jlc3MoIHVwZGF0ZUZ1bmMoIGksIHByb2dyZXNzQ29udGV4dHMsIHByb2dyZXNzVmFsdWVzICkgKVxyXG5cdFx0XHRcdFx0XHQuZG9uZSggdXBkYXRlRnVuYyggaSwgcmVzb2x2ZUNvbnRleHRzLCByZXNvbHZlVmFsdWVzICkgKVxyXG5cdFx0XHRcdFx0XHQuZmFpbCggZGVmZXJyZWQucmVqZWN0ICk7XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdC0tcmVtYWluaW5nO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIElmIHdlJ3JlIG5vdCB3YWl0aW5nIG9uIGFueXRoaW5nLCByZXNvbHZlIHRoZSBtYXN0ZXJcclxuXHRcdGlmICggIXJlbWFpbmluZyApIHtcclxuXHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIHJlc29sdmVDb250ZXh0cywgcmVzb2x2ZVZhbHVlcyApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBkZWZlcnJlZC5wcm9taXNlKCk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5cclxuLy8gVGhlIGRlZmVycmVkIHVzZWQgb24gRE9NIHJlYWR5XHJcbnZhciByZWFkeUxpc3Q7XHJcblxyXG5qUXVlcnkuZm4ucmVhZHkgPSBmdW5jdGlvbiggZm4gKSB7XHJcblxyXG5cdC8vIEFkZCB0aGUgY2FsbGJhY2tcclxuXHRqUXVlcnkucmVhZHkucHJvbWlzZSgpLmRvbmUoIGZuICk7XHJcblxyXG5cdHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxualF1ZXJ5LmV4dGVuZCgge1xyXG5cclxuXHQvLyBJcyB0aGUgRE9NIHJlYWR5IHRvIGJlIHVzZWQ/IFNldCB0byB0cnVlIG9uY2UgaXQgb2NjdXJzLlxyXG5cdGlzUmVhZHk6IGZhbHNlLFxyXG5cclxuXHQvLyBBIGNvdW50ZXIgdG8gdHJhY2sgaG93IG1hbnkgaXRlbXMgdG8gd2FpdCBmb3IgYmVmb3JlXHJcblx0Ly8gdGhlIHJlYWR5IGV2ZW50IGZpcmVzLiBTZWUgIzY3ODFcclxuXHRyZWFkeVdhaXQ6IDEsXHJcblxyXG5cdC8vIEhvbGQgKG9yIHJlbGVhc2UpIHRoZSByZWFkeSBldmVudFxyXG5cdGhvbGRSZWFkeTogZnVuY3Rpb24oIGhvbGQgKSB7XHJcblx0XHRpZiAoIGhvbGQgKSB7XHJcblx0XHRcdGpRdWVyeS5yZWFkeVdhaXQrKztcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGpRdWVyeS5yZWFkeSggdHJ1ZSApO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8vIEhhbmRsZSB3aGVuIHRoZSBET00gaXMgcmVhZHlcclxuXHRyZWFkeTogZnVuY3Rpb24oIHdhaXQgKSB7XHJcblxyXG5cdFx0Ly8gQWJvcnQgaWYgdGhlcmUgYXJlIHBlbmRpbmcgaG9sZHMgb3Igd2UncmUgYWxyZWFkeSByZWFkeVxyXG5cdFx0aWYgKCB3YWl0ID09PSB0cnVlID8gLS1qUXVlcnkucmVhZHlXYWl0IDogalF1ZXJ5LmlzUmVhZHkgKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBSZW1lbWJlciB0aGF0IHRoZSBET00gaXMgcmVhZHlcclxuXHRcdGpRdWVyeS5pc1JlYWR5ID0gdHJ1ZTtcclxuXHJcblx0XHQvLyBJZiBhIG5vcm1hbCBET00gUmVhZHkgZXZlbnQgZmlyZWQsIGRlY3JlbWVudCwgYW5kIHdhaXQgaWYgbmVlZCBiZVxyXG5cdFx0aWYgKCB3YWl0ICE9PSB0cnVlICYmIC0talF1ZXJ5LnJlYWR5V2FpdCA+IDAgKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBJZiB0aGVyZSBhcmUgZnVuY3Rpb25zIGJvdW5kLCB0byBleGVjdXRlXHJcblx0XHRyZWFkeUxpc3QucmVzb2x2ZVdpdGgoIGRvY3VtZW50LCBbIGpRdWVyeSBdICk7XHJcblxyXG5cdFx0Ly8gVHJpZ2dlciBhbnkgYm91bmQgcmVhZHkgZXZlbnRzXHJcblx0XHRpZiAoIGpRdWVyeS5mbi50cmlnZ2VySGFuZGxlciApIHtcclxuXHRcdFx0alF1ZXJ5KCBkb2N1bWVudCApLnRyaWdnZXJIYW5kbGVyKCBcInJlYWR5XCIgKTtcclxuXHRcdFx0alF1ZXJ5KCBkb2N1bWVudCApLm9mZiggXCJyZWFkeVwiICk7XHJcblx0XHR9XHJcblx0fVxyXG59ICk7XHJcblxyXG4vKipcclxuICogVGhlIHJlYWR5IGV2ZW50IGhhbmRsZXIgYW5kIHNlbGYgY2xlYW51cCBtZXRob2RcclxuICovXHJcbmZ1bmN0aW9uIGNvbXBsZXRlZCgpIHtcclxuXHRkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCBcIkRPTUNvbnRlbnRMb2FkZWRcIiwgY29tcGxldGVkICk7XHJcblx0d2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoIFwibG9hZFwiLCBjb21wbGV0ZWQgKTtcclxuXHRqUXVlcnkucmVhZHkoKTtcclxufVxyXG5cclxualF1ZXJ5LnJlYWR5LnByb21pc2UgPSBmdW5jdGlvbiggb2JqICkge1xyXG5cdGlmICggIXJlYWR5TGlzdCApIHtcclxuXHJcblx0XHRyZWFkeUxpc3QgPSBqUXVlcnkuRGVmZXJyZWQoKTtcclxuXHJcblx0XHQvLyBDYXRjaCBjYXNlcyB3aGVyZSAkKGRvY3VtZW50KS5yZWFkeSgpIGlzIGNhbGxlZFxyXG5cdFx0Ly8gYWZ0ZXIgdGhlIGJyb3dzZXIgZXZlbnQgaGFzIGFscmVhZHkgb2NjdXJyZWQuXHJcblx0XHQvLyBTdXBwb3J0OiBJRTktMTAgb25seVxyXG5cdFx0Ly8gT2xkZXIgSUUgc29tZXRpbWVzIHNpZ25hbHMgXCJpbnRlcmFjdGl2ZVwiIHRvbyBzb29uXHJcblx0XHRpZiAoIGRvY3VtZW50LnJlYWR5U3RhdGUgPT09IFwiY29tcGxldGVcIiB8fFxyXG5cdFx0XHQoIGRvY3VtZW50LnJlYWR5U3RhdGUgIT09IFwibG9hZGluZ1wiICYmICFkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuZG9TY3JvbGwgKSApIHtcclxuXHJcblx0XHRcdC8vIEhhbmRsZSBpdCBhc3luY2hyb25vdXNseSB0byBhbGxvdyBzY3JpcHRzIHRoZSBvcHBvcnR1bml0eSB0byBkZWxheSByZWFkeVxyXG5cdFx0XHR3aW5kb3cuc2V0VGltZW91dCggalF1ZXJ5LnJlYWR5ICk7XHJcblxyXG5cdFx0fSBlbHNlIHtcclxuXHJcblx0XHRcdC8vIFVzZSB0aGUgaGFuZHkgZXZlbnQgY2FsbGJhY2tcclxuXHRcdFx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lciggXCJET01Db250ZW50TG9hZGVkXCIsIGNvbXBsZXRlZCApO1xyXG5cclxuXHRcdFx0Ly8gQSBmYWxsYmFjayB0byB3aW5kb3cub25sb2FkLCB0aGF0IHdpbGwgYWx3YXlzIHdvcmtcclxuXHRcdFx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoIFwibG9hZFwiLCBjb21wbGV0ZWQgKTtcclxuXHRcdH1cclxuXHR9XHJcblx0cmV0dXJuIHJlYWR5TGlzdC5wcm9taXNlKCBvYmogKTtcclxufTtcclxuXHJcbi8vIEtpY2sgb2ZmIHRoZSBET00gcmVhZHkgY2hlY2sgZXZlbiBpZiB0aGUgdXNlciBkb2VzIG5vdFxyXG5qUXVlcnkucmVhZHkucHJvbWlzZSgpO1xyXG5cclxuXHJcblxyXG5cclxuLy8gTXVsdGlmdW5jdGlvbmFsIG1ldGhvZCB0byBnZXQgYW5kIHNldCB2YWx1ZXMgb2YgYSBjb2xsZWN0aW9uXHJcbi8vIFRoZSB2YWx1ZS9zIGNhbiBvcHRpb25hbGx5IGJlIGV4ZWN1dGVkIGlmIGl0J3MgYSBmdW5jdGlvblxyXG52YXIgYWNjZXNzID0gZnVuY3Rpb24oIGVsZW1zLCBmbiwga2V5LCB2YWx1ZSwgY2hhaW5hYmxlLCBlbXB0eUdldCwgcmF3ICkge1xyXG5cdHZhciBpID0gMCxcclxuXHRcdGxlbiA9IGVsZW1zLmxlbmd0aCxcclxuXHRcdGJ1bGsgPSBrZXkgPT0gbnVsbDtcclxuXHJcblx0Ly8gU2V0cyBtYW55IHZhbHVlc1xyXG5cdGlmICggalF1ZXJ5LnR5cGUoIGtleSApID09PSBcIm9iamVjdFwiICkge1xyXG5cdFx0Y2hhaW5hYmxlID0gdHJ1ZTtcclxuXHRcdGZvciAoIGkgaW4ga2V5ICkge1xyXG5cdFx0XHRhY2Nlc3MoIGVsZW1zLCBmbiwgaSwga2V5WyBpIF0sIHRydWUsIGVtcHR5R2V0LCByYXcgKTtcclxuXHRcdH1cclxuXHJcblx0Ly8gU2V0cyBvbmUgdmFsdWVcclxuXHR9IGVsc2UgaWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xyXG5cdFx0Y2hhaW5hYmxlID0gdHJ1ZTtcclxuXHJcblx0XHRpZiAoICFqUXVlcnkuaXNGdW5jdGlvbiggdmFsdWUgKSApIHtcclxuXHRcdFx0cmF3ID0gdHJ1ZTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIGJ1bGsgKSB7XHJcblxyXG5cdFx0XHQvLyBCdWxrIG9wZXJhdGlvbnMgcnVuIGFnYWluc3QgdGhlIGVudGlyZSBzZXRcclxuXHRcdFx0aWYgKCByYXcgKSB7XHJcblx0XHRcdFx0Zm4uY2FsbCggZWxlbXMsIHZhbHVlICk7XHJcblx0XHRcdFx0Zm4gPSBudWxsO1xyXG5cclxuXHRcdFx0Ly8gLi4uZXhjZXB0IHdoZW4gZXhlY3V0aW5nIGZ1bmN0aW9uIHZhbHVlc1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGJ1bGsgPSBmbjtcclxuXHRcdFx0XHRmbiA9IGZ1bmN0aW9uKCBlbGVtLCBrZXksIHZhbHVlICkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIGJ1bGsuY2FsbCggalF1ZXJ5KCBlbGVtICksIHZhbHVlICk7XHJcblx0XHRcdFx0fTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggZm4gKSB7XHJcblx0XHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xyXG5cdFx0XHRcdGZuKFxyXG5cdFx0XHRcdFx0ZWxlbXNbIGkgXSwga2V5LCByYXcgP1xyXG5cdFx0XHRcdFx0dmFsdWUgOlxyXG5cdFx0XHRcdFx0dmFsdWUuY2FsbCggZWxlbXNbIGkgXSwgaSwgZm4oIGVsZW1zWyBpIF0sIGtleSApIClcclxuXHRcdFx0XHQpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gY2hhaW5hYmxlID9cclxuXHRcdGVsZW1zIDpcclxuXHJcblx0XHQvLyBHZXRzXHJcblx0XHRidWxrID9cclxuXHRcdFx0Zm4uY2FsbCggZWxlbXMgKSA6XHJcblx0XHRcdGxlbiA/IGZuKCBlbGVtc1sgMCBdLCBrZXkgKSA6IGVtcHR5R2V0O1xyXG59O1xyXG52YXIgYWNjZXB0RGF0YSA9IGZ1bmN0aW9uKCBvd25lciApIHtcclxuXHJcblx0Ly8gQWNjZXB0cyBvbmx5OlxyXG5cdC8vICAtIE5vZGVcclxuXHQvLyAgICAtIE5vZGUuRUxFTUVOVF9OT0RFXHJcblx0Ly8gICAgLSBOb2RlLkRPQ1VNRU5UX05PREVcclxuXHQvLyAgLSBPYmplY3RcclxuXHQvLyAgICAtIEFueVxyXG5cdC8qIGpzaGludCAtVzAxOCAqL1xyXG5cdHJldHVybiBvd25lci5ub2RlVHlwZSA9PT0gMSB8fCBvd25lci5ub2RlVHlwZSA9PT0gOSB8fCAhKCArb3duZXIubm9kZVR5cGUgKTtcclxufTtcclxuXHJcblxyXG5cclxuXHJcbmZ1bmN0aW9uIERhdGEoKSB7XHJcblx0dGhpcy5leHBhbmRvID0galF1ZXJ5LmV4cGFuZG8gKyBEYXRhLnVpZCsrO1xyXG59XHJcblxyXG5EYXRhLnVpZCA9IDE7XHJcblxyXG5EYXRhLnByb3RvdHlwZSA9IHtcclxuXHJcblx0cmVnaXN0ZXI6IGZ1bmN0aW9uKCBvd25lciwgaW5pdGlhbCApIHtcclxuXHRcdHZhciB2YWx1ZSA9IGluaXRpYWwgfHwge307XHJcblxyXG5cdFx0Ly8gSWYgaXQgaXMgYSBub2RlIHVubGlrZWx5IHRvIGJlIHN0cmluZ2lmeS1lZCBvciBsb29wZWQgb3ZlclxyXG5cdFx0Ly8gdXNlIHBsYWluIGFzc2lnbm1lbnRcclxuXHRcdGlmICggb3duZXIubm9kZVR5cGUgKSB7XHJcblx0XHRcdG93bmVyWyB0aGlzLmV4cGFuZG8gXSA9IHZhbHVlO1xyXG5cclxuXHRcdC8vIE90aGVyd2lzZSBzZWN1cmUgaXQgaW4gYSBub24tZW51bWVyYWJsZSwgbm9uLXdyaXRhYmxlIHByb3BlcnR5XHJcblx0XHQvLyBjb25maWd1cmFiaWxpdHkgbXVzdCBiZSB0cnVlIHRvIGFsbG93IHRoZSBwcm9wZXJ0eSB0byBiZVxyXG5cdFx0Ly8gZGVsZXRlZCB3aXRoIHRoZSBkZWxldGUgb3BlcmF0b3JcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eSggb3duZXIsIHRoaXMuZXhwYW5kbywge1xyXG5cdFx0XHRcdHZhbHVlOiB2YWx1ZSxcclxuXHRcdFx0XHR3cml0YWJsZTogdHJ1ZSxcclxuXHRcdFx0XHRjb25maWd1cmFibGU6IHRydWVcclxuXHRcdFx0fSApO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIG93bmVyWyB0aGlzLmV4cGFuZG8gXTtcclxuXHR9LFxyXG5cdGNhY2hlOiBmdW5jdGlvbiggb3duZXIgKSB7XHJcblxyXG5cdFx0Ly8gV2UgY2FuIGFjY2VwdCBkYXRhIGZvciBub24tZWxlbWVudCBub2RlcyBpbiBtb2Rlcm4gYnJvd3NlcnMsXHJcblx0XHQvLyBidXQgd2Ugc2hvdWxkIG5vdCwgc2VlICM4MzM1LlxyXG5cdFx0Ly8gQWx3YXlzIHJldHVybiBhbiBlbXB0eSBvYmplY3QuXHJcblx0XHRpZiAoICFhY2NlcHREYXRhKCBvd25lciApICkge1xyXG5cdFx0XHRyZXR1cm4ge307XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ2hlY2sgaWYgdGhlIG93bmVyIG9iamVjdCBhbHJlYWR5IGhhcyBhIGNhY2hlXHJcblx0XHR2YXIgdmFsdWUgPSBvd25lclsgdGhpcy5leHBhbmRvIF07XHJcblxyXG5cdFx0Ly8gSWYgbm90LCBjcmVhdGUgb25lXHJcblx0XHRpZiAoICF2YWx1ZSApIHtcclxuXHRcdFx0dmFsdWUgPSB7fTtcclxuXHJcblx0XHRcdC8vIFdlIGNhbiBhY2NlcHQgZGF0YSBmb3Igbm9uLWVsZW1lbnQgbm9kZXMgaW4gbW9kZXJuIGJyb3dzZXJzLFxyXG5cdFx0XHQvLyBidXQgd2Ugc2hvdWxkIG5vdCwgc2VlICM4MzM1LlxyXG5cdFx0XHQvLyBBbHdheXMgcmV0dXJuIGFuIGVtcHR5IG9iamVjdC5cclxuXHRcdFx0aWYgKCBhY2NlcHREYXRhKCBvd25lciApICkge1xyXG5cclxuXHRcdFx0XHQvLyBJZiBpdCBpcyBhIG5vZGUgdW5saWtlbHkgdG8gYmUgc3RyaW5naWZ5LWVkIG9yIGxvb3BlZCBvdmVyXHJcblx0XHRcdFx0Ly8gdXNlIHBsYWluIGFzc2lnbm1lbnRcclxuXHRcdFx0XHRpZiAoIG93bmVyLm5vZGVUeXBlICkge1xyXG5cdFx0XHRcdFx0b3duZXJbIHRoaXMuZXhwYW5kbyBdID0gdmFsdWU7XHJcblxyXG5cdFx0XHRcdC8vIE90aGVyd2lzZSBzZWN1cmUgaXQgaW4gYSBub24tZW51bWVyYWJsZSBwcm9wZXJ0eVxyXG5cdFx0XHRcdC8vIGNvbmZpZ3VyYWJsZSBtdXN0IGJlIHRydWUgdG8gYWxsb3cgdGhlIHByb3BlcnR5IHRvIGJlXHJcblx0XHRcdFx0Ly8gZGVsZXRlZCB3aGVuIGRhdGEgaXMgcmVtb3ZlZFxyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRPYmplY3QuZGVmaW5lUHJvcGVydHkoIG93bmVyLCB0aGlzLmV4cGFuZG8sIHtcclxuXHRcdFx0XHRcdFx0dmFsdWU6IHZhbHVlLFxyXG5cdFx0XHRcdFx0XHRjb25maWd1cmFibGU6IHRydWVcclxuXHRcdFx0XHRcdH0gKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gdmFsdWU7XHJcblx0fSxcclxuXHRzZXQ6IGZ1bmN0aW9uKCBvd25lciwgZGF0YSwgdmFsdWUgKSB7XHJcblx0XHR2YXIgcHJvcCxcclxuXHRcdFx0Y2FjaGUgPSB0aGlzLmNhY2hlKCBvd25lciApO1xyXG5cclxuXHRcdC8vIEhhbmRsZTogWyBvd25lciwga2V5LCB2YWx1ZSBdIGFyZ3NcclxuXHRcdGlmICggdHlwZW9mIGRhdGEgPT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdGNhY2hlWyBkYXRhIF0gPSB2YWx1ZTtcclxuXHJcblx0XHQvLyBIYW5kbGU6IFsgb3duZXIsIHsgcHJvcGVydGllcyB9IF0gYXJnc1xyXG5cdFx0fSBlbHNlIHtcclxuXHJcblx0XHRcdC8vIENvcHkgdGhlIHByb3BlcnRpZXMgb25lLWJ5LW9uZSB0byB0aGUgY2FjaGUgb2JqZWN0XHJcblx0XHRcdGZvciAoIHByb3AgaW4gZGF0YSApIHtcclxuXHRcdFx0XHRjYWNoZVsgcHJvcCBdID0gZGF0YVsgcHJvcCBdO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gY2FjaGU7XHJcblx0fSxcclxuXHRnZXQ6IGZ1bmN0aW9uKCBvd25lciwga2V5ICkge1xyXG5cdFx0cmV0dXJuIGtleSA9PT0gdW5kZWZpbmVkID9cclxuXHRcdFx0dGhpcy5jYWNoZSggb3duZXIgKSA6XHJcblx0XHRcdG93bmVyWyB0aGlzLmV4cGFuZG8gXSAmJiBvd25lclsgdGhpcy5leHBhbmRvIF1bIGtleSBdO1xyXG5cdH0sXHJcblx0YWNjZXNzOiBmdW5jdGlvbiggb3duZXIsIGtleSwgdmFsdWUgKSB7XHJcblx0XHR2YXIgc3RvcmVkO1xyXG5cclxuXHRcdC8vIEluIGNhc2VzIHdoZXJlIGVpdGhlcjpcclxuXHRcdC8vXHJcblx0XHQvLyAgIDEuIE5vIGtleSB3YXMgc3BlY2lmaWVkXHJcblx0XHQvLyAgIDIuIEEgc3RyaW5nIGtleSB3YXMgc3BlY2lmaWVkLCBidXQgbm8gdmFsdWUgcHJvdmlkZWRcclxuXHRcdC8vXHJcblx0XHQvLyBUYWtlIHRoZSBcInJlYWRcIiBwYXRoIGFuZCBhbGxvdyB0aGUgZ2V0IG1ldGhvZCB0byBkZXRlcm1pbmVcclxuXHRcdC8vIHdoaWNoIHZhbHVlIHRvIHJldHVybiwgcmVzcGVjdGl2ZWx5IGVpdGhlcjpcclxuXHRcdC8vXHJcblx0XHQvLyAgIDEuIFRoZSBlbnRpcmUgY2FjaGUgb2JqZWN0XHJcblx0XHQvLyAgIDIuIFRoZSBkYXRhIHN0b3JlZCBhdCB0aGUga2V5XHJcblx0XHQvL1xyXG5cdFx0aWYgKCBrZXkgPT09IHVuZGVmaW5lZCB8fFxyXG5cdFx0XHRcdCggKCBrZXkgJiYgdHlwZW9mIGtleSA9PT0gXCJzdHJpbmdcIiApICYmIHZhbHVlID09PSB1bmRlZmluZWQgKSApIHtcclxuXHJcblx0XHRcdHN0b3JlZCA9IHRoaXMuZ2V0KCBvd25lciwga2V5ICk7XHJcblxyXG5cdFx0XHRyZXR1cm4gc3RvcmVkICE9PSB1bmRlZmluZWQgP1xyXG5cdFx0XHRcdHN0b3JlZCA6IHRoaXMuZ2V0KCBvd25lciwgalF1ZXJ5LmNhbWVsQ2FzZSgga2V5ICkgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBXaGVuIHRoZSBrZXkgaXMgbm90IGEgc3RyaW5nLCBvciBib3RoIGEga2V5IGFuZCB2YWx1ZVxyXG5cdFx0Ly8gYXJlIHNwZWNpZmllZCwgc2V0IG9yIGV4dGVuZCAoZXhpc3Rpbmcgb2JqZWN0cykgd2l0aCBlaXRoZXI6XHJcblx0XHQvL1xyXG5cdFx0Ly8gICAxLiBBbiBvYmplY3Qgb2YgcHJvcGVydGllc1xyXG5cdFx0Ly8gICAyLiBBIGtleSBhbmQgdmFsdWVcclxuXHRcdC8vXHJcblx0XHR0aGlzLnNldCggb3duZXIsIGtleSwgdmFsdWUgKTtcclxuXHJcblx0XHQvLyBTaW5jZSB0aGUgXCJzZXRcIiBwYXRoIGNhbiBoYXZlIHR3byBwb3NzaWJsZSBlbnRyeSBwb2ludHNcclxuXHRcdC8vIHJldHVybiB0aGUgZXhwZWN0ZWQgZGF0YSBiYXNlZCBvbiB3aGljaCBwYXRoIHdhcyB0YWtlblsqXVxyXG5cdFx0cmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgPyB2YWx1ZSA6IGtleTtcclxuXHR9LFxyXG5cdHJlbW92ZTogZnVuY3Rpb24oIG93bmVyLCBrZXkgKSB7XHJcblx0XHR2YXIgaSwgbmFtZSwgY2FtZWwsXHJcblx0XHRcdGNhY2hlID0gb3duZXJbIHRoaXMuZXhwYW5kbyBdO1xyXG5cclxuXHRcdGlmICggY2FjaGUgPT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdHRoaXMucmVnaXN0ZXIoIG93bmVyICk7XHJcblxyXG5cdFx0fSBlbHNlIHtcclxuXHJcblx0XHRcdC8vIFN1cHBvcnQgYXJyYXkgb3Igc3BhY2Ugc2VwYXJhdGVkIHN0cmluZyBvZiBrZXlzXHJcblx0XHRcdGlmICggalF1ZXJ5LmlzQXJyYXkoIGtleSApICkge1xyXG5cclxuXHRcdFx0XHQvLyBJZiBcIm5hbWVcIiBpcyBhbiBhcnJheSBvZiBrZXlzLi4uXHJcblx0XHRcdFx0Ly8gV2hlbiBkYXRhIGlzIGluaXRpYWxseSBjcmVhdGVkLCB2aWEgKFwia2V5XCIsIFwidmFsXCIpIHNpZ25hdHVyZSxcclxuXHRcdFx0XHQvLyBrZXlzIHdpbGwgYmUgY29udmVydGVkIHRvIGNhbWVsQ2FzZS5cclxuXHRcdFx0XHQvLyBTaW5jZSB0aGVyZSBpcyBubyB3YXkgdG8gdGVsbCBfaG93XyBhIGtleSB3YXMgYWRkZWQsIHJlbW92ZVxyXG5cdFx0XHRcdC8vIGJvdGggcGxhaW4ga2V5IGFuZCBjYW1lbENhc2Uga2V5LiAjMTI3ODZcclxuXHRcdFx0XHQvLyBUaGlzIHdpbGwgb25seSBwZW5hbGl6ZSB0aGUgYXJyYXkgYXJndW1lbnQgcGF0aC5cclxuXHRcdFx0XHRuYW1lID0ga2V5LmNvbmNhdCgga2V5Lm1hcCggalF1ZXJ5LmNhbWVsQ2FzZSApICk7XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0Y2FtZWwgPSBqUXVlcnkuY2FtZWxDYXNlKCBrZXkgKTtcclxuXHJcblx0XHRcdFx0Ly8gVHJ5IHRoZSBzdHJpbmcgYXMgYSBrZXkgYmVmb3JlIGFueSBtYW5pcHVsYXRpb25cclxuXHRcdFx0XHRpZiAoIGtleSBpbiBjYWNoZSApIHtcclxuXHRcdFx0XHRcdG5hbWUgPSBbIGtleSwgY2FtZWwgXTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cclxuXHRcdFx0XHRcdC8vIElmIGEga2V5IHdpdGggdGhlIHNwYWNlcyBleGlzdHMsIHVzZSBpdC5cclxuXHRcdFx0XHRcdC8vIE90aGVyd2lzZSwgY3JlYXRlIGFuIGFycmF5IGJ5IG1hdGNoaW5nIG5vbi13aGl0ZXNwYWNlXHJcblx0XHRcdFx0XHRuYW1lID0gY2FtZWw7XHJcblx0XHRcdFx0XHRuYW1lID0gbmFtZSBpbiBjYWNoZSA/XHJcblx0XHRcdFx0XHRcdFsgbmFtZSBdIDogKCBuYW1lLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbXSApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aSA9IG5hbWUubGVuZ3RoO1xyXG5cclxuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XHJcblx0XHRcdFx0ZGVsZXRlIGNhY2hlWyBuYW1lWyBpIF0gXTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFJlbW92ZSB0aGUgZXhwYW5kbyBpZiB0aGVyZSdzIG5vIG1vcmUgZGF0YVxyXG5cdFx0aWYgKCBrZXkgPT09IHVuZGVmaW5lZCB8fCBqUXVlcnkuaXNFbXB0eU9iamVjdCggY2FjaGUgKSApIHtcclxuXHJcblx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZSA8PSAzNS00NStcclxuXHRcdFx0Ly8gV2Via2l0ICYgQmxpbmsgcGVyZm9ybWFuY2Ugc3VmZmVycyB3aGVuIGRlbGV0aW5nIHByb3BlcnRpZXNcclxuXHRcdFx0Ly8gZnJvbSBET00gbm9kZXMsIHNvIHNldCB0byB1bmRlZmluZWQgaW5zdGVhZFxyXG5cdFx0XHQvLyBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL2Nocm9taXVtL2lzc3Vlcy9kZXRhaWw/aWQ9Mzc4NjA3XHJcblx0XHRcdGlmICggb3duZXIubm9kZVR5cGUgKSB7XHJcblx0XHRcdFx0b3duZXJbIHRoaXMuZXhwYW5kbyBdID0gdW5kZWZpbmVkO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGRlbGV0ZSBvd25lclsgdGhpcy5leHBhbmRvIF07XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9LFxyXG5cdGhhc0RhdGE6IGZ1bmN0aW9uKCBvd25lciApIHtcclxuXHRcdHZhciBjYWNoZSA9IG93bmVyWyB0aGlzLmV4cGFuZG8gXTtcclxuXHRcdHJldHVybiBjYWNoZSAhPT0gdW5kZWZpbmVkICYmICFqUXVlcnkuaXNFbXB0eU9iamVjdCggY2FjaGUgKTtcclxuXHR9XHJcbn07XHJcbnZhciBkYXRhUHJpdiA9IG5ldyBEYXRhKCk7XHJcblxyXG52YXIgZGF0YVVzZXIgPSBuZXcgRGF0YSgpO1xyXG5cclxuXHJcblxyXG4vL1x0SW1wbGVtZW50YXRpb24gU3VtbWFyeVxyXG4vL1xyXG4vL1x0MS4gRW5mb3JjZSBBUEkgc3VyZmFjZSBhbmQgc2VtYW50aWMgY29tcGF0aWJpbGl0eSB3aXRoIDEuOS54IGJyYW5jaFxyXG4vL1x0Mi4gSW1wcm92ZSB0aGUgbW9kdWxlJ3MgbWFpbnRhaW5hYmlsaXR5IGJ5IHJlZHVjaW5nIHRoZSBzdG9yYWdlXHJcbi8vXHRcdHBhdGhzIHRvIGEgc2luZ2xlIG1lY2hhbmlzbS5cclxuLy9cdDMuIFVzZSB0aGUgc2FtZSBzaW5nbGUgbWVjaGFuaXNtIHRvIHN1cHBvcnQgXCJwcml2YXRlXCIgYW5kIFwidXNlclwiIGRhdGEuXHJcbi8vXHQ0LiBfTmV2ZXJfIGV4cG9zZSBcInByaXZhdGVcIiBkYXRhIHRvIHVzZXIgY29kZSAoVE9ETzogRHJvcCBfZGF0YSwgX3JlbW92ZURhdGEpXHJcbi8vXHQ1LiBBdm9pZCBleHBvc2luZyBpbXBsZW1lbnRhdGlvbiBkZXRhaWxzIG9uIHVzZXIgb2JqZWN0cyAoZWcuIGV4cGFuZG8gcHJvcGVydGllcylcclxuLy9cdDYuIFByb3ZpZGUgYSBjbGVhciBwYXRoIGZvciBpbXBsZW1lbnRhdGlvbiB1cGdyYWRlIHRvIFdlYWtNYXAgaW4gMjAxNFxyXG5cclxudmFyIHJicmFjZSA9IC9eKD86XFx7W1xcd1xcV10qXFx9fFxcW1tcXHdcXFddKlxcXSkkLyxcclxuXHRybXVsdGlEYXNoID0gL1tBLVpdL2c7XHJcblxyXG5mdW5jdGlvbiBkYXRhQXR0ciggZWxlbSwga2V5LCBkYXRhICkge1xyXG5cdHZhciBuYW1lO1xyXG5cclxuXHQvLyBJZiBub3RoaW5nIHdhcyBmb3VuZCBpbnRlcm5hbGx5LCB0cnkgdG8gZmV0Y2ggYW55XHJcblx0Ly8gZGF0YSBmcm9tIHRoZSBIVE1MNSBkYXRhLSogYXR0cmlidXRlXHJcblx0aWYgKCBkYXRhID09PSB1bmRlZmluZWQgJiYgZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcclxuXHRcdG5hbWUgPSBcImRhdGEtXCIgKyBrZXkucmVwbGFjZSggcm11bHRpRGFzaCwgXCItJCZcIiApLnRvTG93ZXJDYXNlKCk7XHJcblx0XHRkYXRhID0gZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUgKTtcclxuXHJcblx0XHRpZiAoIHR5cGVvZiBkYXRhID09PSBcInN0cmluZ1wiICkge1xyXG5cdFx0XHR0cnkge1xyXG5cdFx0XHRcdGRhdGEgPSBkYXRhID09PSBcInRydWVcIiA/IHRydWUgOlxyXG5cdFx0XHRcdFx0ZGF0YSA9PT0gXCJmYWxzZVwiID8gZmFsc2UgOlxyXG5cdFx0XHRcdFx0ZGF0YSA9PT0gXCJudWxsXCIgPyBudWxsIDpcclxuXHJcblx0XHRcdFx0XHQvLyBPbmx5IGNvbnZlcnQgdG8gYSBudW1iZXIgaWYgaXQgZG9lc24ndCBjaGFuZ2UgdGhlIHN0cmluZ1xyXG5cdFx0XHRcdFx0K2RhdGEgKyBcIlwiID09PSBkYXRhID8gK2RhdGEgOlxyXG5cdFx0XHRcdFx0cmJyYWNlLnRlc3QoIGRhdGEgKSA/IGpRdWVyeS5wYXJzZUpTT04oIGRhdGEgKSA6XHJcblx0XHRcdFx0XHRkYXRhO1xyXG5cdFx0XHR9IGNhdGNoICggZSApIHt9XHJcblxyXG5cdFx0XHQvLyBNYWtlIHN1cmUgd2Ugc2V0IHRoZSBkYXRhIHNvIGl0IGlzbid0IGNoYW5nZWQgbGF0ZXJcclxuXHRcdFx0ZGF0YVVzZXIuc2V0KCBlbGVtLCBrZXksIGRhdGEgKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGRhdGEgPSB1bmRlZmluZWQ7XHJcblx0XHR9XHJcblx0fVxyXG5cdHJldHVybiBkYXRhO1xyXG59XHJcblxyXG5qUXVlcnkuZXh0ZW5kKCB7XHJcblx0aGFzRGF0YTogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRyZXR1cm4gZGF0YVVzZXIuaGFzRGF0YSggZWxlbSApIHx8IGRhdGFQcml2Lmhhc0RhdGEoIGVsZW0gKTtcclxuXHR9LFxyXG5cclxuXHRkYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgZGF0YSApIHtcclxuXHRcdHJldHVybiBkYXRhVXNlci5hY2Nlc3MoIGVsZW0sIG5hbWUsIGRhdGEgKTtcclxuXHR9LFxyXG5cclxuXHRyZW1vdmVEYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcclxuXHRcdGRhdGFVc2VyLnJlbW92ZSggZWxlbSwgbmFtZSApO1xyXG5cdH0sXHJcblxyXG5cdC8vIFRPRE86IE5vdyB0aGF0IGFsbCBjYWxscyB0byBfZGF0YSBhbmQgX3JlbW92ZURhdGEgaGF2ZSBiZWVuIHJlcGxhY2VkXHJcblx0Ly8gd2l0aCBkaXJlY3QgY2FsbHMgdG8gZGF0YVByaXYgbWV0aG9kcywgdGhlc2UgY2FuIGJlIGRlcHJlY2F0ZWQuXHJcblx0X2RhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBkYXRhICkge1xyXG5cdFx0cmV0dXJuIGRhdGFQcml2LmFjY2VzcyggZWxlbSwgbmFtZSwgZGF0YSApO1xyXG5cdH0sXHJcblxyXG5cdF9yZW1vdmVEYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcclxuXHRcdGRhdGFQcml2LnJlbW92ZSggZWxlbSwgbmFtZSApO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdGRhdGE6IGZ1bmN0aW9uKCBrZXksIHZhbHVlICkge1xyXG5cdFx0dmFyIGksIG5hbWUsIGRhdGEsXHJcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF0sXHJcblx0XHRcdGF0dHJzID0gZWxlbSAmJiBlbGVtLmF0dHJpYnV0ZXM7XHJcblxyXG5cdFx0Ly8gR2V0cyBhbGwgdmFsdWVzXHJcblx0XHRpZiAoIGtleSA9PT0gdW5kZWZpbmVkICkge1xyXG5cdFx0XHRpZiAoIHRoaXMubGVuZ3RoICkge1xyXG5cdFx0XHRcdGRhdGEgPSBkYXRhVXNlci5nZXQoIGVsZW0gKTtcclxuXHJcblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICYmICFkYXRhUHJpdi5nZXQoIGVsZW0sIFwiaGFzRGF0YUF0dHJzXCIgKSApIHtcclxuXHRcdFx0XHRcdGkgPSBhdHRycy5sZW5ndGg7XHJcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcclxuXHJcblx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFMTErXHJcblx0XHRcdFx0XHRcdC8vIFRoZSBhdHRycyBlbGVtZW50cyBjYW4gYmUgbnVsbCAoIzE0ODk0KVxyXG5cdFx0XHRcdFx0XHRpZiAoIGF0dHJzWyBpIF0gKSB7XHJcblx0XHRcdFx0XHRcdFx0bmFtZSA9IGF0dHJzWyBpIF0ubmFtZTtcclxuXHRcdFx0XHRcdFx0XHRpZiAoIG5hbWUuaW5kZXhPZiggXCJkYXRhLVwiICkgPT09IDAgKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRuYW1lID0galF1ZXJ5LmNhbWVsQ2FzZSggbmFtZS5zbGljZSggNSApICk7XHJcblx0XHRcdFx0XHRcdFx0XHRkYXRhQXR0ciggZWxlbSwgbmFtZSwgZGF0YVsgbmFtZSBdICk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRkYXRhUHJpdi5zZXQoIGVsZW0sIFwiaGFzRGF0YUF0dHJzXCIsIHRydWUgKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHJldHVybiBkYXRhO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFNldHMgbXVsdGlwbGUgdmFsdWVzXHJcblx0XHRpZiAoIHR5cGVvZiBrZXkgPT09IFwib2JqZWN0XCIgKSB7XHJcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGRhdGFVc2VyLnNldCggdGhpcywga2V5ICk7XHJcblx0XHRcdH0gKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggdmFsdWUgKSB7XHJcblx0XHRcdHZhciBkYXRhLCBjYW1lbEtleTtcclxuXHJcblx0XHRcdC8vIFRoZSBjYWxsaW5nIGpRdWVyeSBvYmplY3QgKGVsZW1lbnQgbWF0Y2hlcykgaXMgbm90IGVtcHR5XHJcblx0XHRcdC8vIChhbmQgdGhlcmVmb3JlIGhhcyBhbiBlbGVtZW50IGFwcGVhcnMgYXQgdGhpc1sgMCBdKSBhbmQgdGhlXHJcblx0XHRcdC8vIGB2YWx1ZWAgcGFyYW1ldGVyIHdhcyBub3QgdW5kZWZpbmVkLiBBbiBlbXB0eSBqUXVlcnkgb2JqZWN0XHJcblx0XHRcdC8vIHdpbGwgcmVzdWx0IGluIGB1bmRlZmluZWRgIGZvciBlbGVtID0gdGhpc1sgMCBdIHdoaWNoIHdpbGxcclxuXHRcdFx0Ly8gdGhyb3cgYW4gZXhjZXB0aW9uIGlmIGFuIGF0dGVtcHQgdG8gcmVhZCBhIGRhdGEgY2FjaGUgaXMgbWFkZS5cclxuXHRcdFx0aWYgKCBlbGVtICYmIHZhbHVlID09PSB1bmRlZmluZWQgKSB7XHJcblxyXG5cdFx0XHRcdC8vIEF0dGVtcHQgdG8gZ2V0IGRhdGEgZnJvbSB0aGUgY2FjaGVcclxuXHRcdFx0XHQvLyB3aXRoIHRoZSBrZXkgYXMtaXNcclxuXHRcdFx0XHRkYXRhID0gZGF0YVVzZXIuZ2V0KCBlbGVtLCBrZXkgKSB8fFxyXG5cclxuXHRcdFx0XHRcdC8vIFRyeSB0byBmaW5kIGRhc2hlZCBrZXkgaWYgaXQgZXhpc3RzIChnaC0yNzc5KVxyXG5cdFx0XHRcdFx0Ly8gVGhpcyBpcyBmb3IgMi4yLnggb25seVxyXG5cdFx0XHRcdFx0ZGF0YVVzZXIuZ2V0KCBlbGVtLCBrZXkucmVwbGFjZSggcm11bHRpRGFzaCwgXCItJCZcIiApLnRvTG93ZXJDYXNlKCkgKTtcclxuXHJcblx0XHRcdFx0aWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gZGF0YTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGNhbWVsS2V5ID0galF1ZXJ5LmNhbWVsQ2FzZSgga2V5ICk7XHJcblxyXG5cdFx0XHRcdC8vIEF0dGVtcHQgdG8gZ2V0IGRhdGEgZnJvbSB0aGUgY2FjaGVcclxuXHRcdFx0XHQvLyB3aXRoIHRoZSBrZXkgY2FtZWxpemVkXHJcblx0XHRcdFx0ZGF0YSA9IGRhdGFVc2VyLmdldCggZWxlbSwgY2FtZWxLZXkgKTtcclxuXHRcdFx0XHRpZiAoIGRhdGEgIT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0XHRcdHJldHVybiBkYXRhO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gQXR0ZW1wdCB0byBcImRpc2NvdmVyXCIgdGhlIGRhdGEgaW5cclxuXHRcdFx0XHQvLyBIVE1MNSBjdXN0b20gZGF0YS0qIGF0dHJzXHJcblx0XHRcdFx0ZGF0YSA9IGRhdGFBdHRyKCBlbGVtLCBjYW1lbEtleSwgdW5kZWZpbmVkICk7XHJcblx0XHRcdFx0aWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gZGF0YTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIFdlIHRyaWVkIHJlYWxseSBoYXJkLCBidXQgdGhlIGRhdGEgZG9lc24ndCBleGlzdC5cclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFNldCB0aGUgZGF0YS4uLlxyXG5cdFx0XHRjYW1lbEtleSA9IGpRdWVyeS5jYW1lbENhc2UoIGtleSApO1xyXG5cdFx0XHR0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cclxuXHRcdFx0XHQvLyBGaXJzdCwgYXR0ZW1wdCB0byBzdG9yZSBhIGNvcHkgb3IgcmVmZXJlbmNlIG9mIGFueVxyXG5cdFx0XHRcdC8vIGRhdGEgdGhhdCBtaWdodCd2ZSBiZWVuIHN0b3JlIHdpdGggYSBjYW1lbENhc2VkIGtleS5cclxuXHRcdFx0XHR2YXIgZGF0YSA9IGRhdGFVc2VyLmdldCggdGhpcywgY2FtZWxLZXkgKTtcclxuXHJcblx0XHRcdFx0Ly8gRm9yIEhUTUw1IGRhdGEtKiBhdHRyaWJ1dGUgaW50ZXJvcCwgd2UgaGF2ZSB0b1xyXG5cdFx0XHRcdC8vIHN0b3JlIHByb3BlcnR5IG5hbWVzIHdpdGggZGFzaGVzIGluIGEgY2FtZWxDYXNlIGZvcm0uXHJcblx0XHRcdFx0Ly8gVGhpcyBtaWdodCBub3QgYXBwbHkgdG8gYWxsIHByb3BlcnRpZXMuLi4qXHJcblx0XHRcdFx0ZGF0YVVzZXIuc2V0KCB0aGlzLCBjYW1lbEtleSwgdmFsdWUgKTtcclxuXHJcblx0XHRcdFx0Ly8gKi4uLiBJbiB0aGUgY2FzZSBvZiBwcm9wZXJ0aWVzIHRoYXQgbWlnaHQgX2FjdHVhbGx5X1xyXG5cdFx0XHRcdC8vIGhhdmUgZGFzaGVzLCB3ZSBuZWVkIHRvIGFsc28gc3RvcmUgYSBjb3B5IG9mIHRoYXRcclxuXHRcdFx0XHQvLyB1bmNoYW5nZWQgcHJvcGVydHkuXHJcblx0XHRcdFx0aWYgKCBrZXkuaW5kZXhPZiggXCItXCIgKSA+IC0xICYmIGRhdGEgIT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0XHRcdGRhdGFVc2VyLnNldCggdGhpcywga2V5LCB2YWx1ZSApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSApO1xyXG5cdFx0fSwgbnVsbCwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxLCBudWxsLCB0cnVlICk7XHJcblx0fSxcclxuXHJcblx0cmVtb3ZlRGF0YTogZnVuY3Rpb24oIGtleSApIHtcclxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRkYXRhVXNlci5yZW1vdmUoIHRoaXMsIGtleSApO1xyXG5cdFx0fSApO1xyXG5cdH1cclxufSApO1xyXG5cclxuXHJcbmpRdWVyeS5leHRlbmQoIHtcclxuXHRxdWV1ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGUsIGRhdGEgKSB7XHJcblx0XHR2YXIgcXVldWU7XHJcblxyXG5cdFx0aWYgKCBlbGVtICkge1xyXG5cdFx0XHR0eXBlID0gKCB0eXBlIHx8IFwiZnhcIiApICsgXCJxdWV1ZVwiO1xyXG5cdFx0XHRxdWV1ZSA9IGRhdGFQcml2LmdldCggZWxlbSwgdHlwZSApO1xyXG5cclxuXHRcdFx0Ly8gU3BlZWQgdXAgZGVxdWV1ZSBieSBnZXR0aW5nIG91dCBxdWlja2x5IGlmIHRoaXMgaXMganVzdCBhIGxvb2t1cFxyXG5cdFx0XHRpZiAoIGRhdGEgKSB7XHJcblx0XHRcdFx0aWYgKCAhcXVldWUgfHwgalF1ZXJ5LmlzQXJyYXkoIGRhdGEgKSApIHtcclxuXHRcdFx0XHRcdHF1ZXVlID0gZGF0YVByaXYuYWNjZXNzKCBlbGVtLCB0eXBlLCBqUXVlcnkubWFrZUFycmF5KCBkYXRhICkgKTtcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0cXVldWUucHVzaCggZGF0YSApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gcXVldWUgfHwgW107XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0ZGVxdWV1ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGUgKSB7XHJcblx0XHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XHJcblxyXG5cdFx0dmFyIHF1ZXVlID0galF1ZXJ5LnF1ZXVlKCBlbGVtLCB0eXBlICksXHJcblx0XHRcdHN0YXJ0TGVuZ3RoID0gcXVldWUubGVuZ3RoLFxyXG5cdFx0XHRmbiA9IHF1ZXVlLnNoaWZ0KCksXHJcblx0XHRcdGhvb2tzID0galF1ZXJ5Ll9xdWV1ZUhvb2tzKCBlbGVtLCB0eXBlICksXHJcblx0XHRcdG5leHQgPSBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRqUXVlcnkuZGVxdWV1ZSggZWxlbSwgdHlwZSApO1xyXG5cdFx0XHR9O1xyXG5cclxuXHRcdC8vIElmIHRoZSBmeCBxdWV1ZSBpcyBkZXF1ZXVlZCwgYWx3YXlzIHJlbW92ZSB0aGUgcHJvZ3Jlc3Mgc2VudGluZWxcclxuXHRcdGlmICggZm4gPT09IFwiaW5wcm9ncmVzc1wiICkge1xyXG5cdFx0XHRmbiA9IHF1ZXVlLnNoaWZ0KCk7XHJcblx0XHRcdHN0YXJ0TGVuZ3RoLS07XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBmbiApIHtcclxuXHJcblx0XHRcdC8vIEFkZCBhIHByb2dyZXNzIHNlbnRpbmVsIHRvIHByZXZlbnQgdGhlIGZ4IHF1ZXVlIGZyb20gYmVpbmdcclxuXHRcdFx0Ly8gYXV0b21hdGljYWxseSBkZXF1ZXVlZFxyXG5cdFx0XHRpZiAoIHR5cGUgPT09IFwiZnhcIiApIHtcclxuXHRcdFx0XHRxdWV1ZS51bnNoaWZ0KCBcImlucHJvZ3Jlc3NcIiApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBDbGVhciB1cCB0aGUgbGFzdCBxdWV1ZSBzdG9wIGZ1bmN0aW9uXHJcblx0XHRcdGRlbGV0ZSBob29rcy5zdG9wO1xyXG5cdFx0XHRmbi5jYWxsKCBlbGVtLCBuZXh0LCBob29rcyApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggIXN0YXJ0TGVuZ3RoICYmIGhvb2tzICkge1xyXG5cdFx0XHRob29rcy5lbXB0eS5maXJlKCk7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0Ly8gTm90IHB1YmxpYyAtIGdlbmVyYXRlIGEgcXVldWVIb29rcyBvYmplY3QsIG9yIHJldHVybiB0aGUgY3VycmVudCBvbmVcclxuXHRfcXVldWVIb29rczogZnVuY3Rpb24oIGVsZW0sIHR5cGUgKSB7XHJcblx0XHR2YXIga2V5ID0gdHlwZSArIFwicXVldWVIb29rc1wiO1xyXG5cdFx0cmV0dXJuIGRhdGFQcml2LmdldCggZWxlbSwga2V5ICkgfHwgZGF0YVByaXYuYWNjZXNzKCBlbGVtLCBrZXksIHtcclxuXHRcdFx0ZW1wdHk6IGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLmFkZCggZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0ZGF0YVByaXYucmVtb3ZlKCBlbGVtLCBbIHR5cGUgKyBcInF1ZXVlXCIsIGtleSBdICk7XHJcblx0XHRcdH0gKVxyXG5cdFx0fSApO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdHF1ZXVlOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHtcclxuXHRcdHZhciBzZXR0ZXIgPSAyO1xyXG5cclxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdGRhdGEgPSB0eXBlO1xyXG5cdFx0XHR0eXBlID0gXCJmeFwiO1xyXG5cdFx0XHRzZXR0ZXItLTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIGFyZ3VtZW50cy5sZW5ndGggPCBzZXR0ZXIgKSB7XHJcblx0XHRcdHJldHVybiBqUXVlcnkucXVldWUoIHRoaXNbIDAgXSwgdHlwZSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBkYXRhID09PSB1bmRlZmluZWQgP1xyXG5cdFx0XHR0aGlzIDpcclxuXHRcdFx0dGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHR2YXIgcXVldWUgPSBqUXVlcnkucXVldWUoIHRoaXMsIHR5cGUsIGRhdGEgKTtcclxuXHJcblx0XHRcdFx0Ly8gRW5zdXJlIGEgaG9va3MgZm9yIHRoaXMgcXVldWVcclxuXHRcdFx0XHRqUXVlcnkuX3F1ZXVlSG9va3MoIHRoaXMsIHR5cGUgKTtcclxuXHJcblx0XHRcdFx0aWYgKCB0eXBlID09PSBcImZ4XCIgJiYgcXVldWVbIDAgXSAhPT0gXCJpbnByb2dyZXNzXCIgKSB7XHJcblx0XHRcdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgdHlwZSApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSApO1xyXG5cdH0sXHJcblx0ZGVxdWV1ZTogZnVuY3Rpb24oIHR5cGUgKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcclxuXHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIHR5cGUgKTtcclxuXHRcdH0gKTtcclxuXHR9LFxyXG5cdGNsZWFyUXVldWU6IGZ1bmN0aW9uKCB0eXBlICkge1xyXG5cdFx0cmV0dXJuIHRoaXMucXVldWUoIHR5cGUgfHwgXCJmeFwiLCBbXSApO1xyXG5cdH0sXHJcblxyXG5cdC8vIEdldCBhIHByb21pc2UgcmVzb2x2ZWQgd2hlbiBxdWV1ZXMgb2YgYSBjZXJ0YWluIHR5cGVcclxuXHQvLyBhcmUgZW1wdGllZCAoZnggaXMgdGhlIHR5cGUgYnkgZGVmYXVsdClcclxuXHRwcm9taXNlOiBmdW5jdGlvbiggdHlwZSwgb2JqICkge1xyXG5cdFx0dmFyIHRtcCxcclxuXHRcdFx0Y291bnQgPSAxLFxyXG5cdFx0XHRkZWZlciA9IGpRdWVyeS5EZWZlcnJlZCgpLFxyXG5cdFx0XHRlbGVtZW50cyA9IHRoaXMsXHJcblx0XHRcdGkgPSB0aGlzLmxlbmd0aCxcclxuXHRcdFx0cmVzb2x2ZSA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGlmICggISggLS1jb3VudCApICkge1xyXG5cdFx0XHRcdFx0ZGVmZXIucmVzb2x2ZVdpdGgoIGVsZW1lbnRzLCBbIGVsZW1lbnRzIF0gKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH07XHJcblxyXG5cdFx0aWYgKCB0eXBlb2YgdHlwZSAhPT0gXCJzdHJpbmdcIiApIHtcclxuXHRcdFx0b2JqID0gdHlwZTtcclxuXHRcdFx0dHlwZSA9IHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHRcdHR5cGUgPSB0eXBlIHx8IFwiZnhcIjtcclxuXHJcblx0XHR3aGlsZSAoIGktLSApIHtcclxuXHRcdFx0dG1wID0gZGF0YVByaXYuZ2V0KCBlbGVtZW50c1sgaSBdLCB0eXBlICsgXCJxdWV1ZUhvb2tzXCIgKTtcclxuXHRcdFx0aWYgKCB0bXAgJiYgdG1wLmVtcHR5ICkge1xyXG5cdFx0XHRcdGNvdW50Kys7XHJcblx0XHRcdFx0dG1wLmVtcHR5LmFkZCggcmVzb2x2ZSApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRyZXNvbHZlKCk7XHJcblx0XHRyZXR1cm4gZGVmZXIucHJvbWlzZSggb2JqICk7XHJcblx0fVxyXG59ICk7XHJcbnZhciBwbnVtID0gKCAvWystXT8oPzpcXGQqXFwufClcXGQrKD86W2VFXVsrLV0/XFxkK3wpLyApLnNvdXJjZTtcclxuXHJcbnZhciByY3NzTnVtID0gbmV3IFJlZ0V4cCggXCJeKD86KFsrLV0pPXwpKFwiICsgcG51bSArIFwiKShbYS16JV0qKSRcIiwgXCJpXCIgKTtcclxuXHJcblxyXG52YXIgY3NzRXhwYW5kID0gWyBcIlRvcFwiLCBcIlJpZ2h0XCIsIFwiQm90dG9tXCIsIFwiTGVmdFwiIF07XHJcblxyXG52YXIgaXNIaWRkZW4gPSBmdW5jdGlvbiggZWxlbSwgZWwgKSB7XHJcblxyXG5cdFx0Ly8gaXNIaWRkZW4gbWlnaHQgYmUgY2FsbGVkIGZyb20galF1ZXJ5I2ZpbHRlciBmdW5jdGlvbjtcclxuXHRcdC8vIGluIHRoYXQgY2FzZSwgZWxlbWVudCB3aWxsIGJlIHNlY29uZCBhcmd1bWVudFxyXG5cdFx0ZWxlbSA9IGVsIHx8IGVsZW07XHJcblx0XHRyZXR1cm4galF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKSA9PT0gXCJub25lXCIgfHxcclxuXHRcdFx0IWpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICk7XHJcblx0fTtcclxuXHJcblxyXG5cclxuZnVuY3Rpb24gYWRqdXN0Q1NTKCBlbGVtLCBwcm9wLCB2YWx1ZVBhcnRzLCB0d2VlbiApIHtcclxuXHR2YXIgYWRqdXN0ZWQsXHJcblx0XHRzY2FsZSA9IDEsXHJcblx0XHRtYXhJdGVyYXRpb25zID0gMjAsXHJcblx0XHRjdXJyZW50VmFsdWUgPSB0d2VlbiA/XHJcblx0XHRcdGZ1bmN0aW9uKCkgeyByZXR1cm4gdHdlZW4uY3VyKCk7IH0gOlxyXG5cdFx0XHRmdW5jdGlvbigpIHsgcmV0dXJuIGpRdWVyeS5jc3MoIGVsZW0sIHByb3AsIFwiXCIgKTsgfSxcclxuXHRcdGluaXRpYWwgPSBjdXJyZW50VmFsdWUoKSxcclxuXHRcdHVuaXQgPSB2YWx1ZVBhcnRzICYmIHZhbHVlUGFydHNbIDMgXSB8fCAoIGpRdWVyeS5jc3NOdW1iZXJbIHByb3AgXSA/IFwiXCIgOiBcInB4XCIgKSxcclxuXHJcblx0XHQvLyBTdGFydGluZyB2YWx1ZSBjb21wdXRhdGlvbiBpcyByZXF1aXJlZCBmb3IgcG90ZW50aWFsIHVuaXQgbWlzbWF0Y2hlc1xyXG5cdFx0aW5pdGlhbEluVW5pdCA9ICggalF1ZXJ5LmNzc051bWJlclsgcHJvcCBdIHx8IHVuaXQgIT09IFwicHhcIiAmJiAraW5pdGlhbCApICYmXHJcblx0XHRcdHJjc3NOdW0uZXhlYyggalF1ZXJ5LmNzcyggZWxlbSwgcHJvcCApICk7XHJcblxyXG5cdGlmICggaW5pdGlhbEluVW5pdCAmJiBpbml0aWFsSW5Vbml0WyAzIF0gIT09IHVuaXQgKSB7XHJcblxyXG5cdFx0Ly8gVHJ1c3QgdW5pdHMgcmVwb3J0ZWQgYnkgalF1ZXJ5LmNzc1xyXG5cdFx0dW5pdCA9IHVuaXQgfHwgaW5pdGlhbEluVW5pdFsgMyBdO1xyXG5cclxuXHRcdC8vIE1ha2Ugc3VyZSB3ZSB1cGRhdGUgdGhlIHR3ZWVuIHByb3BlcnRpZXMgbGF0ZXIgb25cclxuXHRcdHZhbHVlUGFydHMgPSB2YWx1ZVBhcnRzIHx8IFtdO1xyXG5cclxuXHRcdC8vIEl0ZXJhdGl2ZWx5IGFwcHJveGltYXRlIGZyb20gYSBub256ZXJvIHN0YXJ0aW5nIHBvaW50XHJcblx0XHRpbml0aWFsSW5Vbml0ID0gK2luaXRpYWwgfHwgMTtcclxuXHJcblx0XHRkbyB7XHJcblxyXG5cdFx0XHQvLyBJZiBwcmV2aW91cyBpdGVyYXRpb24gemVyb2VkIG91dCwgZG91YmxlIHVudGlsIHdlIGdldCAqc29tZXRoaW5nKi5cclxuXHRcdFx0Ly8gVXNlIHN0cmluZyBmb3IgZG91Ymxpbmcgc28gd2UgZG9uJ3QgYWNjaWRlbnRhbGx5IHNlZSBzY2FsZSBhcyB1bmNoYW5nZWQgYmVsb3dcclxuXHRcdFx0c2NhbGUgPSBzY2FsZSB8fCBcIi41XCI7XHJcblxyXG5cdFx0XHQvLyBBZGp1c3QgYW5kIGFwcGx5XHJcblx0XHRcdGluaXRpYWxJblVuaXQgPSBpbml0aWFsSW5Vbml0IC8gc2NhbGU7XHJcblx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgcHJvcCwgaW5pdGlhbEluVW5pdCArIHVuaXQgKTtcclxuXHJcblx0XHQvLyBVcGRhdGUgc2NhbGUsIHRvbGVyYXRpbmcgemVybyBvciBOYU4gZnJvbSB0d2Vlbi5jdXIoKVxyXG5cdFx0Ly8gQnJlYWsgdGhlIGxvb3AgaWYgc2NhbGUgaXMgdW5jaGFuZ2VkIG9yIHBlcmZlY3QsIG9yIGlmIHdlJ3ZlIGp1c3QgaGFkIGVub3VnaC5cclxuXHRcdH0gd2hpbGUgKFxyXG5cdFx0XHRzY2FsZSAhPT0gKCBzY2FsZSA9IGN1cnJlbnRWYWx1ZSgpIC8gaW5pdGlhbCApICYmIHNjYWxlICE9PSAxICYmIC0tbWF4SXRlcmF0aW9uc1xyXG5cdFx0KTtcclxuXHR9XHJcblxyXG5cdGlmICggdmFsdWVQYXJ0cyApIHtcclxuXHRcdGluaXRpYWxJblVuaXQgPSAraW5pdGlhbEluVW5pdCB8fCAraW5pdGlhbCB8fCAwO1xyXG5cclxuXHRcdC8vIEFwcGx5IHJlbGF0aXZlIG9mZnNldCAoKz0vLT0pIGlmIHNwZWNpZmllZFxyXG5cdFx0YWRqdXN0ZWQgPSB2YWx1ZVBhcnRzWyAxIF0gP1xyXG5cdFx0XHRpbml0aWFsSW5Vbml0ICsgKCB2YWx1ZVBhcnRzWyAxIF0gKyAxICkgKiB2YWx1ZVBhcnRzWyAyIF0gOlxyXG5cdFx0XHQrdmFsdWVQYXJ0c1sgMiBdO1xyXG5cdFx0aWYgKCB0d2VlbiApIHtcclxuXHRcdFx0dHdlZW4udW5pdCA9IHVuaXQ7XHJcblx0XHRcdHR3ZWVuLnN0YXJ0ID0gaW5pdGlhbEluVW5pdDtcclxuXHRcdFx0dHdlZW4uZW5kID0gYWRqdXN0ZWQ7XHJcblx0XHR9XHJcblx0fVxyXG5cdHJldHVybiBhZGp1c3RlZDtcclxufVxyXG52YXIgcmNoZWNrYWJsZVR5cGUgPSAoIC9eKD86Y2hlY2tib3h8cmFkaW8pJC9pICk7XHJcblxyXG52YXIgcnRhZ05hbWUgPSAoIC88KFtcXHc6LV0rKS8gKTtcclxuXHJcbnZhciByc2NyaXB0VHlwZSA9ICggL14kfFxcLyg/OmphdmF8ZWNtYSlzY3JpcHQvaSApO1xyXG5cclxuXHJcblxyXG4vLyBXZSBoYXZlIHRvIGNsb3NlIHRoZXNlIHRhZ3MgdG8gc3VwcG9ydCBYSFRNTCAoIzEzMjAwKVxyXG52YXIgd3JhcE1hcCA9IHtcclxuXHJcblx0Ly8gU3VwcG9ydDogSUU5XHJcblx0b3B0aW9uOiBbIDEsIFwiPHNlbGVjdCBtdWx0aXBsZT0nbXVsdGlwbGUnPlwiLCBcIjwvc2VsZWN0PlwiIF0sXHJcblxyXG5cdC8vIFhIVE1MIHBhcnNlcnMgZG8gbm90IG1hZ2ljYWxseSBpbnNlcnQgZWxlbWVudHMgaW4gdGhlXHJcblx0Ly8gc2FtZSB3YXkgdGhhdCB0YWcgc291cCBwYXJzZXJzIGRvLiBTbyB3ZSBjYW5ub3Qgc2hvcnRlblxyXG5cdC8vIHRoaXMgYnkgb21pdHRpbmcgPHRib2R5PiBvciBvdGhlciByZXF1aXJlZCBlbGVtZW50cy5cclxuXHR0aGVhZDogWyAxLCBcIjx0YWJsZT5cIiwgXCI8L3RhYmxlPlwiIF0sXHJcblx0Y29sOiBbIDIsIFwiPHRhYmxlPjxjb2xncm91cD5cIiwgXCI8L2NvbGdyb3VwPjwvdGFibGU+XCIgXSxcclxuXHR0cjogWyAyLCBcIjx0YWJsZT48dGJvZHk+XCIsIFwiPC90Ym9keT48L3RhYmxlPlwiIF0sXHJcblx0dGQ6IFsgMywgXCI8dGFibGU+PHRib2R5Pjx0cj5cIiwgXCI8L3RyPjwvdGJvZHk+PC90YWJsZT5cIiBdLFxyXG5cclxuXHRfZGVmYXVsdDogWyAwLCBcIlwiLCBcIlwiIF1cclxufTtcclxuXHJcbi8vIFN1cHBvcnQ6IElFOVxyXG53cmFwTWFwLm9wdGdyb3VwID0gd3JhcE1hcC5vcHRpb247XHJcblxyXG53cmFwTWFwLnRib2R5ID0gd3JhcE1hcC50Zm9vdCA9IHdyYXBNYXAuY29sZ3JvdXAgPSB3cmFwTWFwLmNhcHRpb24gPSB3cmFwTWFwLnRoZWFkO1xyXG53cmFwTWFwLnRoID0gd3JhcE1hcC50ZDtcclxuXHJcblxyXG5mdW5jdGlvbiBnZXRBbGwoIGNvbnRleHQsIHRhZyApIHtcclxuXHJcblx0Ly8gU3VwcG9ydDogSUU5LTExK1xyXG5cdC8vIFVzZSB0eXBlb2YgdG8gYXZvaWQgemVyby1hcmd1bWVudCBtZXRob2QgaW52b2NhdGlvbiBvbiBob3N0IG9iamVjdHMgKCMxNTE1MSlcclxuXHR2YXIgcmV0ID0gdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgIT09IFwidW5kZWZpbmVkXCIgP1xyXG5cdFx0XHRjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCB0YWcgfHwgXCIqXCIgKSA6XHJcblx0XHRcdHR5cGVvZiBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwgIT09IFwidW5kZWZpbmVkXCIgP1xyXG5cdFx0XHRcdGNvbnRleHQucXVlcnlTZWxlY3RvckFsbCggdGFnIHx8IFwiKlwiICkgOlxyXG5cdFx0XHRbXTtcclxuXHJcblx0cmV0dXJuIHRhZyA9PT0gdW5kZWZpbmVkIHx8IHRhZyAmJiBqUXVlcnkubm9kZU5hbWUoIGNvbnRleHQsIHRhZyApID9cclxuXHRcdGpRdWVyeS5tZXJnZSggWyBjb250ZXh0IF0sIHJldCApIDpcclxuXHRcdHJldDtcclxufVxyXG5cclxuXHJcbi8vIE1hcmsgc2NyaXB0cyBhcyBoYXZpbmcgYWxyZWFkeSBiZWVuIGV2YWx1YXRlZFxyXG5mdW5jdGlvbiBzZXRHbG9iYWxFdmFsKCBlbGVtcywgcmVmRWxlbWVudHMgKSB7XHJcblx0dmFyIGkgPSAwLFxyXG5cdFx0bCA9IGVsZW1zLmxlbmd0aDtcclxuXHJcblx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xyXG5cdFx0ZGF0YVByaXYuc2V0KFxyXG5cdFx0XHRlbGVtc1sgaSBdLFxyXG5cdFx0XHRcImdsb2JhbEV2YWxcIixcclxuXHRcdFx0IXJlZkVsZW1lbnRzIHx8IGRhdGFQcml2LmdldCggcmVmRWxlbWVudHNbIGkgXSwgXCJnbG9iYWxFdmFsXCIgKVxyXG5cdFx0KTtcclxuXHR9XHJcbn1cclxuXHJcblxyXG52YXIgcmh0bWwgPSAvPHwmIz9cXHcrOy87XHJcblxyXG5mdW5jdGlvbiBidWlsZEZyYWdtZW50KCBlbGVtcywgY29udGV4dCwgc2NyaXB0cywgc2VsZWN0aW9uLCBpZ25vcmVkICkge1xyXG5cdHZhciBlbGVtLCB0bXAsIHRhZywgd3JhcCwgY29udGFpbnMsIGosXHJcblx0XHRmcmFnbWVudCA9IGNvbnRleHQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLFxyXG5cdFx0bm9kZXMgPSBbXSxcclxuXHRcdGkgPSAwLFxyXG5cdFx0bCA9IGVsZW1zLmxlbmd0aDtcclxuXHJcblx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xyXG5cdFx0ZWxlbSA9IGVsZW1zWyBpIF07XHJcblxyXG5cdFx0aWYgKCBlbGVtIHx8IGVsZW0gPT09IDAgKSB7XHJcblxyXG5cdFx0XHQvLyBBZGQgbm9kZXMgZGlyZWN0bHlcclxuXHRcdFx0aWYgKCBqUXVlcnkudHlwZSggZWxlbSApID09PSBcIm9iamVjdFwiICkge1xyXG5cclxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMSwgUGhhbnRvbUpTPDJcclxuXHRcdFx0XHQvLyBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzIG9uIGFuY2llbnQgV2ViS2l0XHJcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBub2RlcywgZWxlbS5ub2RlVHlwZSA/IFsgZWxlbSBdIDogZWxlbSApO1xyXG5cclxuXHRcdFx0Ly8gQ29udmVydCBub24taHRtbCBpbnRvIGEgdGV4dCBub2RlXHJcblx0XHRcdH0gZWxzZSBpZiAoICFyaHRtbC50ZXN0KCBlbGVtICkgKSB7XHJcblx0XHRcdFx0bm9kZXMucHVzaCggY29udGV4dC5jcmVhdGVUZXh0Tm9kZSggZWxlbSApICk7XHJcblxyXG5cdFx0XHQvLyBDb252ZXJ0IGh0bWwgaW50byBET00gbm9kZXNcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHR0bXAgPSB0bXAgfHwgZnJhZ21lbnQuYXBwZW5kQ2hpbGQoIGNvbnRleHQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApICk7XHJcblxyXG5cdFx0XHRcdC8vIERlc2VyaWFsaXplIGEgc3RhbmRhcmQgcmVwcmVzZW50YXRpb25cclxuXHRcdFx0XHR0YWcgPSAoIHJ0YWdOYW1lLmV4ZWMoIGVsZW0gKSB8fCBbIFwiXCIsIFwiXCIgXSApWyAxIF0udG9Mb3dlckNhc2UoKTtcclxuXHRcdFx0XHR3cmFwID0gd3JhcE1hcFsgdGFnIF0gfHwgd3JhcE1hcC5fZGVmYXVsdDtcclxuXHRcdFx0XHR0bXAuaW5uZXJIVE1MID0gd3JhcFsgMSBdICsgalF1ZXJ5Lmh0bWxQcmVmaWx0ZXIoIGVsZW0gKSArIHdyYXBbIDIgXTtcclxuXHJcblx0XHRcdFx0Ly8gRGVzY2VuZCB0aHJvdWdoIHdyYXBwZXJzIHRvIHRoZSByaWdodCBjb250ZW50XHJcblx0XHRcdFx0aiA9IHdyYXBbIDAgXTtcclxuXHRcdFx0XHR3aGlsZSAoIGotLSApIHtcclxuXHRcdFx0XHRcdHRtcCA9IHRtcC5sYXN0Q2hpbGQ7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMSwgUGhhbnRvbUpTPDJcclxuXHRcdFx0XHQvLyBwdXNoLmFwcGx5KF8sIGFycmF5bGlrZSkgdGhyb3dzIG9uIGFuY2llbnQgV2ViS2l0XHJcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBub2RlcywgdG1wLmNoaWxkTm9kZXMgKTtcclxuXHJcblx0XHRcdFx0Ly8gUmVtZW1iZXIgdGhlIHRvcC1sZXZlbCBjb250YWluZXJcclxuXHRcdFx0XHR0bXAgPSBmcmFnbWVudC5maXJzdENoaWxkO1xyXG5cclxuXHRcdFx0XHQvLyBFbnN1cmUgdGhlIGNyZWF0ZWQgbm9kZXMgYXJlIG9ycGhhbmVkICgjMTIzOTIpXHJcblx0XHRcdFx0dG1wLnRleHRDb250ZW50ID0gXCJcIjtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0Ly8gUmVtb3ZlIHdyYXBwZXIgZnJvbSBmcmFnbWVudFxyXG5cdGZyYWdtZW50LnRleHRDb250ZW50ID0gXCJcIjtcclxuXHJcblx0aSA9IDA7XHJcblx0d2hpbGUgKCAoIGVsZW0gPSBub2Rlc1sgaSsrIF0gKSApIHtcclxuXHJcblx0XHQvLyBTa2lwIGVsZW1lbnRzIGFscmVhZHkgaW4gdGhlIGNvbnRleHQgY29sbGVjdGlvbiAodHJhYy00MDg3KVxyXG5cdFx0aWYgKCBzZWxlY3Rpb24gJiYgalF1ZXJ5LmluQXJyYXkoIGVsZW0sIHNlbGVjdGlvbiApID4gLTEgKSB7XHJcblx0XHRcdGlmICggaWdub3JlZCApIHtcclxuXHRcdFx0XHRpZ25vcmVkLnB1c2goIGVsZW0gKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRjb250aW51ZTtcclxuXHRcdH1cclxuXHJcblx0XHRjb250YWlucyA9IGpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICk7XHJcblxyXG5cdFx0Ly8gQXBwZW5kIHRvIGZyYWdtZW50XHJcblx0XHR0bXAgPSBnZXRBbGwoIGZyYWdtZW50LmFwcGVuZENoaWxkKCBlbGVtICksIFwic2NyaXB0XCIgKTtcclxuXHJcblx0XHQvLyBQcmVzZXJ2ZSBzY3JpcHQgZXZhbHVhdGlvbiBoaXN0b3J5XHJcblx0XHRpZiAoIGNvbnRhaW5zICkge1xyXG5cdFx0XHRzZXRHbG9iYWxFdmFsKCB0bXAgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBDYXB0dXJlIGV4ZWN1dGFibGVzXHJcblx0XHRpZiAoIHNjcmlwdHMgKSB7XHJcblx0XHRcdGogPSAwO1xyXG5cdFx0XHR3aGlsZSAoICggZWxlbSA9IHRtcFsgaisrIF0gKSApIHtcclxuXHRcdFx0XHRpZiAoIHJzY3JpcHRUeXBlLnRlc3QoIGVsZW0udHlwZSB8fCBcIlwiICkgKSB7XHJcblx0XHRcdFx0XHRzY3JpcHRzLnB1c2goIGVsZW0gKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJldHVybiBmcmFnbWVudDtcclxufVxyXG5cclxuXHJcbiggZnVuY3Rpb24oKSB7XHJcblx0dmFyIGZyYWdtZW50ID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpLFxyXG5cdFx0ZGl2ID0gZnJhZ21lbnQuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKSApLFxyXG5cdFx0aW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKTtcclxuXHJcblx0Ly8gU3VwcG9ydDogQW5kcm9pZCA0LjAtNC4zLCBTYWZhcmk8PTUuMVxyXG5cdC8vIENoZWNrIHN0YXRlIGxvc3QgaWYgdGhlIG5hbWUgaXMgc2V0ICgjMTEyMTcpXHJcblx0Ly8gU3VwcG9ydDogV2luZG93cyBXZWIgQXBwcyAoV1dBKVxyXG5cdC8vIGBuYW1lYCBhbmQgYHR5cGVgIG11c3QgdXNlIC5zZXRBdHRyaWJ1dGUgZm9yIFdXQSAoIzE0OTAxKVxyXG5cdGlucHV0LnNldEF0dHJpYnV0ZSggXCJ0eXBlXCIsIFwicmFkaW9cIiApO1xyXG5cdGlucHV0LnNldEF0dHJpYnV0ZSggXCJjaGVja2VkXCIsIFwiY2hlY2tlZFwiICk7XHJcblx0aW5wdXQuc2V0QXR0cmlidXRlKCBcIm5hbWVcIiwgXCJ0XCIgKTtcclxuXHJcblx0ZGl2LmFwcGVuZENoaWxkKCBpbnB1dCApO1xyXG5cclxuXHQvLyBTdXBwb3J0OiBTYWZhcmk8PTUuMSwgQW5kcm9pZDw0LjJcclxuXHQvLyBPbGRlciBXZWJLaXQgZG9lc24ndCBjbG9uZSBjaGVja2VkIHN0YXRlIGNvcnJlY3RseSBpbiBmcmFnbWVudHNcclxuXHRzdXBwb3J0LmNoZWNrQ2xvbmUgPSBkaXYuY2xvbmVOb2RlKCB0cnVlICkuY2xvbmVOb2RlKCB0cnVlICkubGFzdENoaWxkLmNoZWNrZWQ7XHJcblxyXG5cdC8vIFN1cHBvcnQ6IElFPD0xMStcclxuXHQvLyBNYWtlIHN1cmUgdGV4dGFyZWEgKGFuZCBjaGVja2JveCkgZGVmYXVsdFZhbHVlIGlzIHByb3Blcmx5IGNsb25lZFxyXG5cdGRpdi5pbm5lckhUTUwgPSBcIjx0ZXh0YXJlYT54PC90ZXh0YXJlYT5cIjtcclxuXHRzdXBwb3J0Lm5vQ2xvbmVDaGVja2VkID0gISFkaXYuY2xvbmVOb2RlKCB0cnVlICkubGFzdENoaWxkLmRlZmF1bHRWYWx1ZTtcclxufSApKCk7XHJcblxyXG5cclxudmFyXHJcblx0cmtleUV2ZW50ID0gL15rZXkvLFxyXG5cdHJtb3VzZUV2ZW50ID0gL14oPzptb3VzZXxwb2ludGVyfGNvbnRleHRtZW51fGRyYWd8ZHJvcCl8Y2xpY2svLFxyXG5cdHJ0eXBlbmFtZXNwYWNlID0gL14oW14uXSopKD86XFwuKC4rKXwpLztcclxuXHJcbmZ1bmN0aW9uIHJldHVyblRydWUoKSB7XHJcblx0cmV0dXJuIHRydWU7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJldHVybkZhbHNlKCkge1xyXG5cdHJldHVybiBmYWxzZTtcclxufVxyXG5cclxuLy8gU3VwcG9ydDogSUU5XHJcbi8vIFNlZSAjMTMzOTMgZm9yIG1vcmUgaW5mb1xyXG5mdW5jdGlvbiBzYWZlQWN0aXZlRWxlbWVudCgpIHtcclxuXHR0cnkge1xyXG5cdFx0cmV0dXJuIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7XHJcblx0fSBjYXRjaCAoIGVyciApIHsgfVxyXG59XHJcblxyXG5mdW5jdGlvbiBvbiggZWxlbSwgdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiwgb25lICkge1xyXG5cdHZhciBvcmlnRm4sIHR5cGU7XHJcblxyXG5cdC8vIFR5cGVzIGNhbiBiZSBhIG1hcCBvZiB0eXBlcy9oYW5kbGVyc1xyXG5cdGlmICggdHlwZW9mIHR5cGVzID09PSBcIm9iamVjdFwiICkge1xyXG5cclxuXHRcdC8vICggdHlwZXMtT2JqZWN0LCBzZWxlY3RvciwgZGF0YSApXHJcblx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiApIHtcclxuXHJcblx0XHRcdC8vICggdHlwZXMtT2JqZWN0LCBkYXRhIClcclxuXHRcdFx0ZGF0YSA9IGRhdGEgfHwgc2VsZWN0b3I7XHJcblx0XHRcdHNlbGVjdG9yID0gdW5kZWZpbmVkO1xyXG5cdFx0fVxyXG5cdFx0Zm9yICggdHlwZSBpbiB0eXBlcyApIHtcclxuXHRcdFx0b24oIGVsZW0sIHR5cGUsIHNlbGVjdG9yLCBkYXRhLCB0eXBlc1sgdHlwZSBdLCBvbmUgKTtcclxuXHRcdH1cclxuXHRcdHJldHVybiBlbGVtO1xyXG5cdH1cclxuXHJcblx0aWYgKCBkYXRhID09IG51bGwgJiYgZm4gPT0gbnVsbCApIHtcclxuXHJcblx0XHQvLyAoIHR5cGVzLCBmbiApXHJcblx0XHRmbiA9IHNlbGVjdG9yO1xyXG5cdFx0ZGF0YSA9IHNlbGVjdG9yID0gdW5kZWZpbmVkO1xyXG5cdH0gZWxzZSBpZiAoIGZuID09IG51bGwgKSB7XHJcblx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiApIHtcclxuXHJcblx0XHRcdC8vICggdHlwZXMsIHNlbGVjdG9yLCBmbiApXHJcblx0XHRcdGZuID0gZGF0YTtcclxuXHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcclxuXHRcdH0gZWxzZSB7XHJcblxyXG5cdFx0XHQvLyAoIHR5cGVzLCBkYXRhLCBmbiApXHJcblx0XHRcdGZuID0gZGF0YTtcclxuXHRcdFx0ZGF0YSA9IHNlbGVjdG9yO1xyXG5cdFx0XHRzZWxlY3RvciA9IHVuZGVmaW5lZDtcclxuXHRcdH1cclxuXHR9XHJcblx0aWYgKCBmbiA9PT0gZmFsc2UgKSB7XHJcblx0XHRmbiA9IHJldHVybkZhbHNlO1xyXG5cdH0gZWxzZSBpZiAoICFmbiApIHtcclxuXHRcdHJldHVybiBlbGVtO1xyXG5cdH1cclxuXHJcblx0aWYgKCBvbmUgPT09IDEgKSB7XHJcblx0XHRvcmlnRm4gPSBmbjtcclxuXHRcdGZuID0gZnVuY3Rpb24oIGV2ZW50ICkge1xyXG5cclxuXHRcdFx0Ly8gQ2FuIHVzZSBhbiBlbXB0eSBzZXQsIHNpbmNlIGV2ZW50IGNvbnRhaW5zIHRoZSBpbmZvXHJcblx0XHRcdGpRdWVyeSgpLm9mZiggZXZlbnQgKTtcclxuXHRcdFx0cmV0dXJuIG9yaWdGbi5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XHJcblx0XHR9O1xyXG5cclxuXHRcdC8vIFVzZSBzYW1lIGd1aWQgc28gY2FsbGVyIGNhbiByZW1vdmUgdXNpbmcgb3JpZ0ZuXHJcblx0XHRmbi5ndWlkID0gb3JpZ0ZuLmd1aWQgfHwgKCBvcmlnRm4uZ3VpZCA9IGpRdWVyeS5ndWlkKysgKTtcclxuXHR9XHJcblx0cmV0dXJuIGVsZW0uZWFjaCggZnVuY3Rpb24oKSB7XHJcblx0XHRqUXVlcnkuZXZlbnQuYWRkKCB0aGlzLCB0eXBlcywgZm4sIGRhdGEsIHNlbGVjdG9yICk7XHJcblx0fSApO1xyXG59XHJcblxyXG4vKlxyXG4gKiBIZWxwZXIgZnVuY3Rpb25zIGZvciBtYW5hZ2luZyBldmVudHMgLS0gbm90IHBhcnQgb2YgdGhlIHB1YmxpYyBpbnRlcmZhY2UuXHJcbiAqIFByb3BzIHRvIERlYW4gRWR3YXJkcycgYWRkRXZlbnQgbGlicmFyeSBmb3IgbWFueSBvZiB0aGUgaWRlYXMuXHJcbiAqL1xyXG5qUXVlcnkuZXZlbnQgPSB7XHJcblxyXG5cdGdsb2JhbDoge30sXHJcblxyXG5cdGFkZDogZnVuY3Rpb24oIGVsZW0sIHR5cGVzLCBoYW5kbGVyLCBkYXRhLCBzZWxlY3RvciApIHtcclxuXHJcblx0XHR2YXIgaGFuZGxlT2JqSW4sIGV2ZW50SGFuZGxlLCB0bXAsXHJcblx0XHRcdGV2ZW50cywgdCwgaGFuZGxlT2JqLFxyXG5cdFx0XHRzcGVjaWFsLCBoYW5kbGVycywgdHlwZSwgbmFtZXNwYWNlcywgb3JpZ1R5cGUsXHJcblx0XHRcdGVsZW1EYXRhID0gZGF0YVByaXYuZ2V0KCBlbGVtICk7XHJcblxyXG5cdFx0Ly8gRG9uJ3QgYXR0YWNoIGV2ZW50cyB0byBub0RhdGEgb3IgdGV4dC9jb21tZW50IG5vZGVzIChidXQgYWxsb3cgcGxhaW4gb2JqZWN0cylcclxuXHRcdGlmICggIWVsZW1EYXRhICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ2FsbGVyIGNhbiBwYXNzIGluIGFuIG9iamVjdCBvZiBjdXN0b20gZGF0YSBpbiBsaWV1IG9mIHRoZSBoYW5kbGVyXHJcblx0XHRpZiAoIGhhbmRsZXIuaGFuZGxlciApIHtcclxuXHRcdFx0aGFuZGxlT2JqSW4gPSBoYW5kbGVyO1xyXG5cdFx0XHRoYW5kbGVyID0gaGFuZGxlT2JqSW4uaGFuZGxlcjtcclxuXHRcdFx0c2VsZWN0b3IgPSBoYW5kbGVPYmpJbi5zZWxlY3RvcjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB0aGUgaGFuZGxlciBoYXMgYSB1bmlxdWUgSUQsIHVzZWQgdG8gZmluZC9yZW1vdmUgaXQgbGF0ZXJcclxuXHRcdGlmICggIWhhbmRsZXIuZ3VpZCApIHtcclxuXHRcdFx0aGFuZGxlci5ndWlkID0galF1ZXJ5Lmd1aWQrKztcclxuXHRcdH1cclxuXHJcblx0XHQvLyBJbml0IHRoZSBlbGVtZW50J3MgZXZlbnQgc3RydWN0dXJlIGFuZCBtYWluIGhhbmRsZXIsIGlmIHRoaXMgaXMgdGhlIGZpcnN0XHJcblx0XHRpZiAoICEoIGV2ZW50cyA9IGVsZW1EYXRhLmV2ZW50cyApICkge1xyXG5cdFx0XHRldmVudHMgPSBlbGVtRGF0YS5ldmVudHMgPSB7fTtcclxuXHRcdH1cclxuXHRcdGlmICggISggZXZlbnRIYW5kbGUgPSBlbGVtRGF0YS5oYW5kbGUgKSApIHtcclxuXHRcdFx0ZXZlbnRIYW5kbGUgPSBlbGVtRGF0YS5oYW5kbGUgPSBmdW5jdGlvbiggZSApIHtcclxuXHJcblx0XHRcdFx0Ly8gRGlzY2FyZCB0aGUgc2Vjb25kIGV2ZW50IG9mIGEgalF1ZXJ5LmV2ZW50LnRyaWdnZXIoKSBhbmRcclxuXHRcdFx0XHQvLyB3aGVuIGFuIGV2ZW50IGlzIGNhbGxlZCBhZnRlciBhIHBhZ2UgaGFzIHVubG9hZGVkXHJcblx0XHRcdFx0cmV0dXJuIHR5cGVvZiBqUXVlcnkgIT09IFwidW5kZWZpbmVkXCIgJiYgalF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCAhPT0gZS50eXBlID9cclxuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5kaXNwYXRjaC5hcHBseSggZWxlbSwgYXJndW1lbnRzICkgOiB1bmRlZmluZWQ7XHJcblx0XHRcdH07XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gSGFuZGxlIG11bHRpcGxlIGV2ZW50cyBzZXBhcmF0ZWQgYnkgYSBzcGFjZVxyXG5cdFx0dHlwZXMgPSAoIHR5cGVzIHx8IFwiXCIgKS5tYXRjaCggcm5vdHdoaXRlICkgfHwgWyBcIlwiIF07XHJcblx0XHR0ID0gdHlwZXMubGVuZ3RoO1xyXG5cdFx0d2hpbGUgKCB0LS0gKSB7XHJcblx0XHRcdHRtcCA9IHJ0eXBlbmFtZXNwYWNlLmV4ZWMoIHR5cGVzWyB0IF0gKSB8fCBbXTtcclxuXHRcdFx0dHlwZSA9IG9yaWdUeXBlID0gdG1wWyAxIF07XHJcblx0XHRcdG5hbWVzcGFjZXMgPSAoIHRtcFsgMiBdIHx8IFwiXCIgKS5zcGxpdCggXCIuXCIgKS5zb3J0KCk7XHJcblxyXG5cdFx0XHQvLyBUaGVyZSAqbXVzdCogYmUgYSB0eXBlLCBubyBhdHRhY2hpbmcgbmFtZXNwYWNlLW9ubHkgaGFuZGxlcnNcclxuXHRcdFx0aWYgKCAhdHlwZSApIHtcclxuXHRcdFx0XHRjb250aW51ZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gSWYgZXZlbnQgY2hhbmdlcyBpdHMgdHlwZSwgdXNlIHRoZSBzcGVjaWFsIGV2ZW50IGhhbmRsZXJzIGZvciB0aGUgY2hhbmdlZCB0eXBlXHJcblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xyXG5cclxuXHRcdFx0Ly8gSWYgc2VsZWN0b3IgZGVmaW5lZCwgZGV0ZXJtaW5lIHNwZWNpYWwgZXZlbnQgYXBpIHR5cGUsIG90aGVyd2lzZSBnaXZlbiB0eXBlXHJcblx0XHRcdHR5cGUgPSAoIHNlbGVjdG9yID8gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgOiBzcGVjaWFsLmJpbmRUeXBlICkgfHwgdHlwZTtcclxuXHJcblx0XHRcdC8vIFVwZGF0ZSBzcGVjaWFsIGJhc2VkIG9uIG5ld2x5IHJlc2V0IHR5cGVcclxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyB0eXBlIF0gfHwge307XHJcblxyXG5cdFx0XHQvLyBoYW5kbGVPYmogaXMgcGFzc2VkIHRvIGFsbCBldmVudCBoYW5kbGVyc1xyXG5cdFx0XHRoYW5kbGVPYmogPSBqUXVlcnkuZXh0ZW5kKCB7XHJcblx0XHRcdFx0dHlwZTogdHlwZSxcclxuXHRcdFx0XHRvcmlnVHlwZTogb3JpZ1R5cGUsXHJcblx0XHRcdFx0ZGF0YTogZGF0YSxcclxuXHRcdFx0XHRoYW5kbGVyOiBoYW5kbGVyLFxyXG5cdFx0XHRcdGd1aWQ6IGhhbmRsZXIuZ3VpZCxcclxuXHRcdFx0XHRzZWxlY3Rvcjogc2VsZWN0b3IsXHJcblx0XHRcdFx0bmVlZHNDb250ZXh0OiBzZWxlY3RvciAmJiBqUXVlcnkuZXhwci5tYXRjaC5uZWVkc0NvbnRleHQudGVzdCggc2VsZWN0b3IgKSxcclxuXHRcdFx0XHRuYW1lc3BhY2U6IG5hbWVzcGFjZXMuam9pbiggXCIuXCIgKVxyXG5cdFx0XHR9LCBoYW5kbGVPYmpJbiApO1xyXG5cclxuXHRcdFx0Ly8gSW5pdCB0aGUgZXZlbnQgaGFuZGxlciBxdWV1ZSBpZiB3ZSdyZSB0aGUgZmlyc3RcclxuXHRcdFx0aWYgKCAhKCBoYW5kbGVycyA9IGV2ZW50c1sgdHlwZSBdICkgKSB7XHJcblx0XHRcdFx0aGFuZGxlcnMgPSBldmVudHNbIHR5cGUgXSA9IFtdO1xyXG5cdFx0XHRcdGhhbmRsZXJzLmRlbGVnYXRlQ291bnQgPSAwO1xyXG5cclxuXHRcdFx0XHQvLyBPbmx5IHVzZSBhZGRFdmVudExpc3RlbmVyIGlmIHRoZSBzcGVjaWFsIGV2ZW50cyBoYW5kbGVyIHJldHVybnMgZmFsc2VcclxuXHRcdFx0XHRpZiAoICFzcGVjaWFsLnNldHVwIHx8XHJcblx0XHRcdFx0XHRzcGVjaWFsLnNldHVwLmNhbGwoIGVsZW0sIGRhdGEsIG5hbWVzcGFjZXMsIGV2ZW50SGFuZGxlICkgPT09IGZhbHNlICkge1xyXG5cclxuXHRcdFx0XHRcdGlmICggZWxlbS5hZGRFdmVudExpc3RlbmVyICkge1xyXG5cdFx0XHRcdFx0XHRlbGVtLmFkZEV2ZW50TGlzdGVuZXIoIHR5cGUsIGV2ZW50SGFuZGxlICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAoIHNwZWNpYWwuYWRkICkge1xyXG5cdFx0XHRcdHNwZWNpYWwuYWRkLmNhbGwoIGVsZW0sIGhhbmRsZU9iaiApO1xyXG5cclxuXHRcdFx0XHRpZiAoICFoYW5kbGVPYmouaGFuZGxlci5ndWlkICkge1xyXG5cdFx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXIuZ3VpZCA9IGhhbmRsZXIuZ3VpZDtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIEFkZCB0byB0aGUgZWxlbWVudCdzIGhhbmRsZXIgbGlzdCwgZGVsZWdhdGVzIGluIGZyb250XHJcblx0XHRcdGlmICggc2VsZWN0b3IgKSB7XHJcblx0XHRcdFx0aGFuZGxlcnMuc3BsaWNlKCBoYW5kbGVycy5kZWxlZ2F0ZUNvdW50KyssIDAsIGhhbmRsZU9iaiApO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGhhbmRsZXJzLnB1c2goIGhhbmRsZU9iaiApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBLZWVwIHRyYWNrIG9mIHdoaWNoIGV2ZW50cyBoYXZlIGV2ZXIgYmVlbiB1c2VkLCBmb3IgZXZlbnQgb3B0aW1pemF0aW9uXHJcblx0XHRcdGpRdWVyeS5ldmVudC5nbG9iYWxbIHR5cGUgXSA9IHRydWU7XHJcblx0XHR9XHJcblxyXG5cdH0sXHJcblxyXG5cdC8vIERldGFjaCBhbiBldmVudCBvciBzZXQgb2YgZXZlbnRzIGZyb20gYW4gZWxlbWVudFxyXG5cdHJlbW92ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGVzLCBoYW5kbGVyLCBzZWxlY3RvciwgbWFwcGVkVHlwZXMgKSB7XHJcblxyXG5cdFx0dmFyIGosIG9yaWdDb3VudCwgdG1wLFxyXG5cdFx0XHRldmVudHMsIHQsIGhhbmRsZU9iaixcclxuXHRcdFx0c3BlY2lhbCwgaGFuZGxlcnMsIHR5cGUsIG5hbWVzcGFjZXMsIG9yaWdUeXBlLFxyXG5cdFx0XHRlbGVtRGF0YSA9IGRhdGFQcml2Lmhhc0RhdGEoIGVsZW0gKSAmJiBkYXRhUHJpdi5nZXQoIGVsZW0gKTtcclxuXHJcblx0XHRpZiAoICFlbGVtRGF0YSB8fCAhKCBldmVudHMgPSBlbGVtRGF0YS5ldmVudHMgKSApIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIE9uY2UgZm9yIGVhY2ggdHlwZS5uYW1lc3BhY2UgaW4gdHlwZXM7IHR5cGUgbWF5IGJlIG9taXR0ZWRcclxuXHRcdHR5cGVzID0gKCB0eXBlcyB8fCBcIlwiICkubWF0Y2goIHJub3R3aGl0ZSApIHx8IFsgXCJcIiBdO1xyXG5cdFx0dCA9IHR5cGVzLmxlbmd0aDtcclxuXHRcdHdoaWxlICggdC0tICkge1xyXG5cdFx0XHR0bXAgPSBydHlwZW5hbWVzcGFjZS5leGVjKCB0eXBlc1sgdCBdICkgfHwgW107XHJcblx0XHRcdHR5cGUgPSBvcmlnVHlwZSA9IHRtcFsgMSBdO1xyXG5cdFx0XHRuYW1lc3BhY2VzID0gKCB0bXBbIDIgXSB8fCBcIlwiICkuc3BsaXQoIFwiLlwiICkuc29ydCgpO1xyXG5cclxuXHRcdFx0Ly8gVW5iaW5kIGFsbCBldmVudHMgKG9uIHRoaXMgbmFtZXNwYWNlLCBpZiBwcm92aWRlZCkgZm9yIHRoZSBlbGVtZW50XHJcblx0XHRcdGlmICggIXR5cGUgKSB7XHJcblx0XHRcdFx0Zm9yICggdHlwZSBpbiBldmVudHMgKSB7XHJcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQucmVtb3ZlKCBlbGVtLCB0eXBlICsgdHlwZXNbIHQgXSwgaGFuZGxlciwgc2VsZWN0b3IsIHRydWUgKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0Y29udGludWU7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xyXG5cdFx0XHR0eXBlID0gKCBzZWxlY3RvciA/IHNwZWNpYWwuZGVsZWdhdGVUeXBlIDogc3BlY2lhbC5iaW5kVHlwZSApIHx8IHR5cGU7XHJcblx0XHRcdGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gfHwgW107XHJcblx0XHRcdHRtcCA9IHRtcFsgMiBdICYmXHJcblx0XHRcdFx0bmV3IFJlZ0V4cCggXCIoXnxcXFxcLilcIiArIG5hbWVzcGFjZXMuam9pbiggXCJcXFxcLig/Oi4qXFxcXC58KVwiICkgKyBcIihcXFxcLnwkKVwiICk7XHJcblxyXG5cdFx0XHQvLyBSZW1vdmUgbWF0Y2hpbmcgZXZlbnRzXHJcblx0XHRcdG9yaWdDb3VudCA9IGogPSBoYW5kbGVycy5sZW5ndGg7XHJcblx0XHRcdHdoaWxlICggai0tICkge1xyXG5cdFx0XHRcdGhhbmRsZU9iaiA9IGhhbmRsZXJzWyBqIF07XHJcblxyXG5cdFx0XHRcdGlmICggKCBtYXBwZWRUeXBlcyB8fCBvcmlnVHlwZSA9PT0gaGFuZGxlT2JqLm9yaWdUeXBlICkgJiZcclxuXHRcdFx0XHRcdCggIWhhbmRsZXIgfHwgaGFuZGxlci5ndWlkID09PSBoYW5kbGVPYmouZ3VpZCApICYmXHJcblx0XHRcdFx0XHQoICF0bXAgfHwgdG1wLnRlc3QoIGhhbmRsZU9iai5uYW1lc3BhY2UgKSApICYmXHJcblx0XHRcdFx0XHQoICFzZWxlY3RvciB8fCBzZWxlY3RvciA9PT0gaGFuZGxlT2JqLnNlbGVjdG9yIHx8XHJcblx0XHRcdFx0XHRcdHNlbGVjdG9yID09PSBcIioqXCIgJiYgaGFuZGxlT2JqLnNlbGVjdG9yICkgKSB7XHJcblx0XHRcdFx0XHRoYW5kbGVycy5zcGxpY2UoIGosIDEgKTtcclxuXHJcblx0XHRcdFx0XHRpZiAoIGhhbmRsZU9iai5zZWxlY3RvciApIHtcclxuXHRcdFx0XHRcdFx0aGFuZGxlcnMuZGVsZWdhdGVDb3VudC0tO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0aWYgKCBzcGVjaWFsLnJlbW92ZSApIHtcclxuXHRcdFx0XHRcdFx0c3BlY2lhbC5yZW1vdmUuY2FsbCggZWxlbSwgaGFuZGxlT2JqICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBSZW1vdmUgZ2VuZXJpYyBldmVudCBoYW5kbGVyIGlmIHdlIHJlbW92ZWQgc29tZXRoaW5nIGFuZCBubyBtb3JlIGhhbmRsZXJzIGV4aXN0XHJcblx0XHRcdC8vIChhdm9pZHMgcG90ZW50aWFsIGZvciBlbmRsZXNzIHJlY3Vyc2lvbiBkdXJpbmcgcmVtb3ZhbCBvZiBzcGVjaWFsIGV2ZW50IGhhbmRsZXJzKVxyXG5cdFx0XHRpZiAoIG9yaWdDb3VudCAmJiAhaGFuZGxlcnMubGVuZ3RoICkge1xyXG5cdFx0XHRcdGlmICggIXNwZWNpYWwudGVhcmRvd24gfHxcclxuXHRcdFx0XHRcdHNwZWNpYWwudGVhcmRvd24uY2FsbCggZWxlbSwgbmFtZXNwYWNlcywgZWxlbURhdGEuaGFuZGxlICkgPT09IGZhbHNlICkge1xyXG5cclxuXHRcdFx0XHRcdGpRdWVyeS5yZW1vdmVFdmVudCggZWxlbSwgdHlwZSwgZWxlbURhdGEuaGFuZGxlICk7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRkZWxldGUgZXZlbnRzWyB0eXBlIF07XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBSZW1vdmUgZGF0YSBhbmQgdGhlIGV4cGFuZG8gaWYgaXQncyBubyBsb25nZXIgdXNlZFxyXG5cdFx0aWYgKCBqUXVlcnkuaXNFbXB0eU9iamVjdCggZXZlbnRzICkgKSB7XHJcblx0XHRcdGRhdGFQcml2LnJlbW92ZSggZWxlbSwgXCJoYW5kbGUgZXZlbnRzXCIgKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRkaXNwYXRjaDogZnVuY3Rpb24oIGV2ZW50ICkge1xyXG5cclxuXHRcdC8vIE1ha2UgYSB3cml0YWJsZSBqUXVlcnkuRXZlbnQgZnJvbSB0aGUgbmF0aXZlIGV2ZW50IG9iamVjdFxyXG5cdFx0ZXZlbnQgPSBqUXVlcnkuZXZlbnQuZml4KCBldmVudCApO1xyXG5cclxuXHRcdHZhciBpLCBqLCByZXQsIG1hdGNoZWQsIGhhbmRsZU9iaixcclxuXHRcdFx0aGFuZGxlclF1ZXVlID0gW10sXHJcblx0XHRcdGFyZ3MgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSxcclxuXHRcdFx0aGFuZGxlcnMgPSAoIGRhdGFQcml2LmdldCggdGhpcywgXCJldmVudHNcIiApIHx8IHt9IClbIGV2ZW50LnR5cGUgXSB8fCBbXSxcclxuXHRcdFx0c3BlY2lhbCA9IGpRdWVyeS5ldmVudC5zcGVjaWFsWyBldmVudC50eXBlIF0gfHwge307XHJcblxyXG5cdFx0Ly8gVXNlIHRoZSBmaXgtZWQgalF1ZXJ5LkV2ZW50IHJhdGhlciB0aGFuIHRoZSAocmVhZC1vbmx5KSBuYXRpdmUgZXZlbnRcclxuXHRcdGFyZ3NbIDAgXSA9IGV2ZW50O1xyXG5cdFx0ZXZlbnQuZGVsZWdhdGVUYXJnZXQgPSB0aGlzO1xyXG5cclxuXHRcdC8vIENhbGwgdGhlIHByZURpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZSwgYW5kIGxldCBpdCBiYWlsIGlmIGRlc2lyZWRcclxuXHRcdGlmICggc3BlY2lhbC5wcmVEaXNwYXRjaCAmJiBzcGVjaWFsLnByZURpc3BhdGNoLmNhbGwoIHRoaXMsIGV2ZW50ICkgPT09IGZhbHNlICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRGV0ZXJtaW5lIGhhbmRsZXJzXHJcblx0XHRoYW5kbGVyUXVldWUgPSBqUXVlcnkuZXZlbnQuaGFuZGxlcnMuY2FsbCggdGhpcywgZXZlbnQsIGhhbmRsZXJzICk7XHJcblxyXG5cdFx0Ly8gUnVuIGRlbGVnYXRlcyBmaXJzdDsgdGhleSBtYXkgd2FudCB0byBzdG9wIHByb3BhZ2F0aW9uIGJlbmVhdGggdXNcclxuXHRcdGkgPSAwO1xyXG5cdFx0d2hpbGUgKCAoIG1hdGNoZWQgPSBoYW5kbGVyUXVldWVbIGkrKyBdICkgJiYgIWV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7XHJcblx0XHRcdGV2ZW50LmN1cnJlbnRUYXJnZXQgPSBtYXRjaGVkLmVsZW07XHJcblxyXG5cdFx0XHRqID0gMDtcclxuXHRcdFx0d2hpbGUgKCAoIGhhbmRsZU9iaiA9IG1hdGNoZWQuaGFuZGxlcnNbIGorKyBdICkgJiZcclxuXHRcdFx0XHQhZXZlbnQuaXNJbW1lZGlhdGVQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcclxuXHJcblx0XHRcdFx0Ly8gVHJpZ2dlcmVkIGV2ZW50IG11c3QgZWl0aGVyIDEpIGhhdmUgbm8gbmFtZXNwYWNlLCBvciAyKSBoYXZlIG5hbWVzcGFjZShzKVxyXG5cdFx0XHRcdC8vIGEgc3Vic2V0IG9yIGVxdWFsIHRvIHRob3NlIGluIHRoZSBib3VuZCBldmVudCAoYm90aCBjYW4gaGF2ZSBubyBuYW1lc3BhY2UpLlxyXG5cdFx0XHRcdGlmICggIWV2ZW50LnJuYW1lc3BhY2UgfHwgZXZlbnQucm5hbWVzcGFjZS50ZXN0KCBoYW5kbGVPYmoubmFtZXNwYWNlICkgKSB7XHJcblxyXG5cdFx0XHRcdFx0ZXZlbnQuaGFuZGxlT2JqID0gaGFuZGxlT2JqO1xyXG5cdFx0XHRcdFx0ZXZlbnQuZGF0YSA9IGhhbmRsZU9iai5kYXRhO1xyXG5cclxuXHRcdFx0XHRcdHJldCA9ICggKCBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgaGFuZGxlT2JqLm9yaWdUeXBlIF0gfHwge30gKS5oYW5kbGUgfHxcclxuXHRcdFx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXIgKS5hcHBseSggbWF0Y2hlZC5lbGVtLCBhcmdzICk7XHJcblxyXG5cdFx0XHRcdFx0aWYgKCByZXQgIT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0XHRcdFx0aWYgKCAoIGV2ZW50LnJlc3VsdCA9IHJldCApID09PSBmYWxzZSApIHtcclxuXHRcdFx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdFx0XHRcdGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ2FsbCB0aGUgcG9zdERpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZVxyXG5cdFx0aWYgKCBzcGVjaWFsLnBvc3REaXNwYXRjaCApIHtcclxuXHRcdFx0c3BlY2lhbC5wb3N0RGlzcGF0Y2guY2FsbCggdGhpcywgZXZlbnQgKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gZXZlbnQucmVzdWx0O1xyXG5cdH0sXHJcblxyXG5cdGhhbmRsZXJzOiBmdW5jdGlvbiggZXZlbnQsIGhhbmRsZXJzICkge1xyXG5cdFx0dmFyIGksIG1hdGNoZXMsIHNlbCwgaGFuZGxlT2JqLFxyXG5cdFx0XHRoYW5kbGVyUXVldWUgPSBbXSxcclxuXHRcdFx0ZGVsZWdhdGVDb3VudCA9IGhhbmRsZXJzLmRlbGVnYXRlQ291bnQsXHJcblx0XHRcdGN1ciA9IGV2ZW50LnRhcmdldDtcclxuXHJcblx0XHQvLyBTdXBwb3J0IChhdCBsZWFzdCk6IENocm9tZSwgSUU5XHJcblx0XHQvLyBGaW5kIGRlbGVnYXRlIGhhbmRsZXJzXHJcblx0XHQvLyBCbGFjay1ob2xlIFNWRyA8dXNlPiBpbnN0YW5jZSB0cmVlcyAoIzEzMTgwKVxyXG5cdFx0Ly9cclxuXHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3g8PTQyK1xyXG5cdFx0Ly8gQXZvaWQgbm9uLWxlZnQtY2xpY2sgaW4gRkYgYnV0IGRvbid0IGJsb2NrIElFIHJhZGlvIGV2ZW50cyAoIzM4NjEsIGdoLTIzNDMpXHJcblx0XHRpZiAoIGRlbGVnYXRlQ291bnQgJiYgY3VyLm5vZGVUeXBlICYmXHJcblx0XHRcdCggZXZlbnQudHlwZSAhPT0gXCJjbGlja1wiIHx8IGlzTmFOKCBldmVudC5idXR0b24gKSB8fCBldmVudC5idXR0b24gPCAxICkgKSB7XHJcblxyXG5cdFx0XHRmb3IgKCA7IGN1ciAhPT0gdGhpczsgY3VyID0gY3VyLnBhcmVudE5vZGUgfHwgdGhpcyApIHtcclxuXHJcblx0XHRcdFx0Ly8gRG9uJ3QgY2hlY2sgbm9uLWVsZW1lbnRzICgjMTMyMDgpXHJcblx0XHRcdFx0Ly8gRG9uJ3QgcHJvY2VzcyBjbGlja3Mgb24gZGlzYWJsZWQgZWxlbWVudHMgKCM2OTExLCAjODE2NSwgIzExMzgyLCAjMTE3NjQpXHJcblx0XHRcdFx0aWYgKCBjdXIubm9kZVR5cGUgPT09IDEgJiYgKCBjdXIuZGlzYWJsZWQgIT09IHRydWUgfHwgZXZlbnQudHlwZSAhPT0gXCJjbGlja1wiICkgKSB7XHJcblx0XHRcdFx0XHRtYXRjaGVzID0gW107XHJcblx0XHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGRlbGVnYXRlQ291bnQ7IGkrKyApIHtcclxuXHRcdFx0XHRcdFx0aGFuZGxlT2JqID0gaGFuZGxlcnNbIGkgXTtcclxuXHJcblx0XHRcdFx0XHRcdC8vIERvbid0IGNvbmZsaWN0IHdpdGggT2JqZWN0LnByb3RvdHlwZSBwcm9wZXJ0aWVzICgjMTMyMDMpXHJcblx0XHRcdFx0XHRcdHNlbCA9IGhhbmRsZU9iai5zZWxlY3RvciArIFwiIFwiO1xyXG5cclxuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVzWyBzZWwgXSA9PT0gdW5kZWZpbmVkICkge1xyXG5cdFx0XHRcdFx0XHRcdG1hdGNoZXNbIHNlbCBdID0gaGFuZGxlT2JqLm5lZWRzQ29udGV4dCA/XHJcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkoIHNlbCwgdGhpcyApLmluZGV4KCBjdXIgKSA+IC0xIDpcclxuXHRcdFx0XHRcdFx0XHRcdGpRdWVyeS5maW5kKCBzZWwsIHRoaXMsIG51bGwsIFsgY3VyIF0gKS5sZW5ndGg7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVzWyBzZWwgXSApIHtcclxuXHRcdFx0XHRcdFx0XHRtYXRjaGVzLnB1c2goIGhhbmRsZU9iaiApO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRpZiAoIG1hdGNoZXMubGVuZ3RoICkge1xyXG5cdFx0XHRcdFx0XHRoYW5kbGVyUXVldWUucHVzaCggeyBlbGVtOiBjdXIsIGhhbmRsZXJzOiBtYXRjaGVzIH0gKTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBBZGQgdGhlIHJlbWFpbmluZyAoZGlyZWN0bHktYm91bmQpIGhhbmRsZXJzXHJcblx0XHRpZiAoIGRlbGVnYXRlQ291bnQgPCBoYW5kbGVycy5sZW5ndGggKSB7XHJcblx0XHRcdGhhbmRsZXJRdWV1ZS5wdXNoKCB7IGVsZW06IHRoaXMsIGhhbmRsZXJzOiBoYW5kbGVycy5zbGljZSggZGVsZWdhdGVDb3VudCApIH0gKTtcclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gaGFuZGxlclF1ZXVlO1xyXG5cdH0sXHJcblxyXG5cdC8vIEluY2x1ZGVzIHNvbWUgZXZlbnQgcHJvcHMgc2hhcmVkIGJ5IEtleUV2ZW50IGFuZCBNb3VzZUV2ZW50XHJcblx0cHJvcHM6ICggXCJhbHRLZXkgYnViYmxlcyBjYW5jZWxhYmxlIGN0cmxLZXkgY3VycmVudFRhcmdldCBkZXRhaWwgZXZlbnRQaGFzZSBcIiArXHJcblx0XHRcIm1ldGFLZXkgcmVsYXRlZFRhcmdldCBzaGlmdEtleSB0YXJnZXQgdGltZVN0YW1wIHZpZXcgd2hpY2hcIiApLnNwbGl0KCBcIiBcIiApLFxyXG5cclxuXHRmaXhIb29rczoge30sXHJcblxyXG5cdGtleUhvb2tzOiB7XHJcblx0XHRwcm9wczogXCJjaGFyIGNoYXJDb2RlIGtleSBrZXlDb2RlXCIuc3BsaXQoIFwiIFwiICksXHJcblx0XHRmaWx0ZXI6IGZ1bmN0aW9uKCBldmVudCwgb3JpZ2luYWwgKSB7XHJcblxyXG5cdFx0XHQvLyBBZGQgd2hpY2ggZm9yIGtleSBldmVudHNcclxuXHRcdFx0aWYgKCBldmVudC53aGljaCA9PSBudWxsICkge1xyXG5cdFx0XHRcdGV2ZW50LndoaWNoID0gb3JpZ2luYWwuY2hhckNvZGUgIT0gbnVsbCA/IG9yaWdpbmFsLmNoYXJDb2RlIDogb3JpZ2luYWwua2V5Q29kZTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIGV2ZW50O1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdG1vdXNlSG9va3M6IHtcclxuXHRcdHByb3BzOiAoIFwiYnV0dG9uIGJ1dHRvbnMgY2xpZW50WCBjbGllbnRZIG9mZnNldFggb2Zmc2V0WSBwYWdlWCBwYWdlWSBcIiArXHJcblx0XHRcdFwic2NyZWVuWCBzY3JlZW5ZIHRvRWxlbWVudFwiICkuc3BsaXQoIFwiIFwiICksXHJcblx0XHRmaWx0ZXI6IGZ1bmN0aW9uKCBldmVudCwgb3JpZ2luYWwgKSB7XHJcblx0XHRcdHZhciBldmVudERvYywgZG9jLCBib2R5LFxyXG5cdFx0XHRcdGJ1dHRvbiA9IG9yaWdpbmFsLmJ1dHRvbjtcclxuXHJcblx0XHRcdC8vIENhbGN1bGF0ZSBwYWdlWC9ZIGlmIG1pc3NpbmcgYW5kIGNsaWVudFgvWSBhdmFpbGFibGVcclxuXHRcdFx0aWYgKCBldmVudC5wYWdlWCA9PSBudWxsICYmIG9yaWdpbmFsLmNsaWVudFggIT0gbnVsbCApIHtcclxuXHRcdFx0XHRldmVudERvYyA9IGV2ZW50LnRhcmdldC5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50O1xyXG5cdFx0XHRcdGRvYyA9IGV2ZW50RG9jLmRvY3VtZW50RWxlbWVudDtcclxuXHRcdFx0XHRib2R5ID0gZXZlbnREb2MuYm9keTtcclxuXHJcblx0XHRcdFx0ZXZlbnQucGFnZVggPSBvcmlnaW5hbC5jbGllbnRYICtcclxuXHRcdFx0XHRcdCggZG9jICYmIGRvYy5zY3JvbGxMZWZ0IHx8IGJvZHkgJiYgYm9keS5zY3JvbGxMZWZ0IHx8IDAgKSAtXHJcblx0XHRcdFx0XHQoIGRvYyAmJiBkb2MuY2xpZW50TGVmdCB8fCBib2R5ICYmIGJvZHkuY2xpZW50TGVmdCB8fCAwICk7XHJcblx0XHRcdFx0ZXZlbnQucGFnZVkgPSBvcmlnaW5hbC5jbGllbnRZICtcclxuXHRcdFx0XHRcdCggZG9jICYmIGRvYy5zY3JvbGxUb3AgIHx8IGJvZHkgJiYgYm9keS5zY3JvbGxUb3AgIHx8IDAgKSAtXHJcblx0XHRcdFx0XHQoIGRvYyAmJiBkb2MuY2xpZW50VG9wICB8fCBib2R5ICYmIGJvZHkuY2xpZW50VG9wICB8fCAwICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIEFkZCB3aGljaCBmb3IgY2xpY2s6IDEgPT09IGxlZnQ7IDIgPT09IG1pZGRsZTsgMyA9PT0gcmlnaHRcclxuXHRcdFx0Ly8gTm90ZTogYnV0dG9uIGlzIG5vdCBub3JtYWxpemVkLCBzbyBkb24ndCB1c2UgaXRcclxuXHRcdFx0aWYgKCAhZXZlbnQud2hpY2ggJiYgYnV0dG9uICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdFx0ZXZlbnQud2hpY2ggPSAoIGJ1dHRvbiAmIDEgPyAxIDogKCBidXR0b24gJiAyID8gMyA6ICggYnV0dG9uICYgNCA/IDIgOiAwICkgKSApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gZXZlbnQ7XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0Zml4OiBmdW5jdGlvbiggZXZlbnQgKSB7XHJcblx0XHRpZiAoIGV2ZW50WyBqUXVlcnkuZXhwYW5kbyBdICkge1xyXG5cdFx0XHRyZXR1cm4gZXZlbnQ7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ3JlYXRlIGEgd3JpdGFibGUgY29weSBvZiB0aGUgZXZlbnQgb2JqZWN0IGFuZCBub3JtYWxpemUgc29tZSBwcm9wZXJ0aWVzXHJcblx0XHR2YXIgaSwgcHJvcCwgY29weSxcclxuXHRcdFx0dHlwZSA9IGV2ZW50LnR5cGUsXHJcblx0XHRcdG9yaWdpbmFsRXZlbnQgPSBldmVudCxcclxuXHRcdFx0Zml4SG9vayA9IHRoaXMuZml4SG9va3NbIHR5cGUgXTtcclxuXHJcblx0XHRpZiAoICFmaXhIb29rICkge1xyXG5cdFx0XHR0aGlzLmZpeEhvb2tzWyB0eXBlIF0gPSBmaXhIb29rID1cclxuXHRcdFx0XHRybW91c2VFdmVudC50ZXN0KCB0eXBlICkgPyB0aGlzLm1vdXNlSG9va3MgOlxyXG5cdFx0XHRcdHJrZXlFdmVudC50ZXN0KCB0eXBlICkgPyB0aGlzLmtleUhvb2tzIDpcclxuXHRcdFx0XHR7fTtcclxuXHRcdH1cclxuXHRcdGNvcHkgPSBmaXhIb29rLnByb3BzID8gdGhpcy5wcm9wcy5jb25jYXQoIGZpeEhvb2sucHJvcHMgKSA6IHRoaXMucHJvcHM7XHJcblxyXG5cdFx0ZXZlbnQgPSBuZXcgalF1ZXJ5LkV2ZW50KCBvcmlnaW5hbEV2ZW50ICk7XHJcblxyXG5cdFx0aSA9IGNvcHkubGVuZ3RoO1xyXG5cdFx0d2hpbGUgKCBpLS0gKSB7XHJcblx0XHRcdHByb3AgPSBjb3B5WyBpIF07XHJcblx0XHRcdGV2ZW50WyBwcm9wIF0gPSBvcmlnaW5hbEV2ZW50WyBwcm9wIF07XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gU3VwcG9ydDogQ29yZG92YSAyLjUgKFdlYktpdCkgKCMxMzI1NSlcclxuXHRcdC8vIEFsbCBldmVudHMgc2hvdWxkIGhhdmUgYSB0YXJnZXQ7IENvcmRvdmEgZGV2aWNlcmVhZHkgZG9lc24ndFxyXG5cdFx0aWYgKCAhZXZlbnQudGFyZ2V0ICkge1xyXG5cdFx0XHRldmVudC50YXJnZXQgPSBkb2N1bWVudDtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBTdXBwb3J0OiBTYWZhcmkgNi4wKywgQ2hyb21lPDI4XHJcblx0XHQvLyBUYXJnZXQgc2hvdWxkIG5vdCBiZSBhIHRleHQgbm9kZSAoIzUwNCwgIzEzMTQzKVxyXG5cdFx0aWYgKCBldmVudC50YXJnZXQubm9kZVR5cGUgPT09IDMgKSB7XHJcblx0XHRcdGV2ZW50LnRhcmdldCA9IGV2ZW50LnRhcmdldC5wYXJlbnROb2RlO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBmaXhIb29rLmZpbHRlciA/IGZpeEhvb2suZmlsdGVyKCBldmVudCwgb3JpZ2luYWxFdmVudCApIDogZXZlbnQ7XHJcblx0fSxcclxuXHJcblx0c3BlY2lhbDoge1xyXG5cdFx0bG9hZDoge1xyXG5cclxuXHRcdFx0Ly8gUHJldmVudCB0cmlnZ2VyZWQgaW1hZ2UubG9hZCBldmVudHMgZnJvbSBidWJibGluZyB0byB3aW5kb3cubG9hZFxyXG5cdFx0XHRub0J1YmJsZTogdHJ1ZVxyXG5cdFx0fSxcclxuXHRcdGZvY3VzOiB7XHJcblxyXG5cdFx0XHQvLyBGaXJlIG5hdGl2ZSBldmVudCBpZiBwb3NzaWJsZSBzbyBibHVyL2ZvY3VzIHNlcXVlbmNlIGlzIGNvcnJlY3RcclxuXHRcdFx0dHJpZ2dlcjogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0aWYgKCB0aGlzICE9PSBzYWZlQWN0aXZlRWxlbWVudCgpICYmIHRoaXMuZm9jdXMgKSB7XHJcblx0XHRcdFx0XHR0aGlzLmZvY3VzKCk7XHJcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9LFxyXG5cdFx0XHRkZWxlZ2F0ZVR5cGU6IFwiZm9jdXNpblwiXHJcblx0XHR9LFxyXG5cdFx0Ymx1cjoge1xyXG5cdFx0XHR0cmlnZ2VyOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRpZiAoIHRoaXMgPT09IHNhZmVBY3RpdmVFbGVtZW50KCkgJiYgdGhpcy5ibHVyICkge1xyXG5cdFx0XHRcdFx0dGhpcy5ibHVyKCk7XHJcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9LFxyXG5cdFx0XHRkZWxlZ2F0ZVR5cGU6IFwiZm9jdXNvdXRcIlxyXG5cdFx0fSxcclxuXHRcdGNsaWNrOiB7XHJcblxyXG5cdFx0XHQvLyBGb3IgY2hlY2tib3gsIGZpcmUgbmF0aXZlIGV2ZW50IHNvIGNoZWNrZWQgc3RhdGUgd2lsbCBiZSByaWdodFxyXG5cdFx0XHR0cmlnZ2VyOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRpZiAoIHRoaXMudHlwZSA9PT0gXCJjaGVja2JveFwiICYmIHRoaXMuY2xpY2sgJiYgalF1ZXJ5Lm5vZGVOYW1lKCB0aGlzLCBcImlucHV0XCIgKSApIHtcclxuXHRcdFx0XHRcdHRoaXMuY2xpY2soKTtcclxuXHRcdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0sXHJcblxyXG5cdFx0XHQvLyBGb3IgY3Jvc3MtYnJvd3NlciBjb25zaXN0ZW5jeSwgZG9uJ3QgZmlyZSBuYXRpdmUgLmNsaWNrKCkgb24gbGlua3NcclxuXHRcdFx0X2RlZmF1bHQ6IGZ1bmN0aW9uKCBldmVudCApIHtcclxuXHRcdFx0XHRyZXR1cm4galF1ZXJ5Lm5vZGVOYW1lKCBldmVudC50YXJnZXQsIFwiYVwiICk7XHJcblx0XHRcdH1cclxuXHRcdH0sXHJcblxyXG5cdFx0YmVmb3JldW5sb2FkOiB7XHJcblx0XHRcdHBvc3REaXNwYXRjaDogZnVuY3Rpb24oIGV2ZW50ICkge1xyXG5cclxuXHRcdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94IDIwK1xyXG5cdFx0XHRcdC8vIEZpcmVmb3ggZG9lc24ndCBhbGVydCBpZiB0aGUgcmV0dXJuVmFsdWUgZmllbGQgaXMgbm90IHNldC5cclxuXHRcdFx0XHRpZiAoIGV2ZW50LnJlc3VsdCAhPT0gdW5kZWZpbmVkICYmIGV2ZW50Lm9yaWdpbmFsRXZlbnQgKSB7XHJcblx0XHRcdFx0XHRldmVudC5vcmlnaW5hbEV2ZW50LnJldHVyblZhbHVlID0gZXZlbnQucmVzdWx0O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxufTtcclxuXHJcbmpRdWVyeS5yZW1vdmVFdmVudCA9IGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCBoYW5kbGUgKSB7XHJcblxyXG5cdC8vIFRoaXMgXCJpZlwiIGlzIG5lZWRlZCBmb3IgcGxhaW4gb2JqZWN0c1xyXG5cdGlmICggZWxlbS5yZW1vdmVFdmVudExpc3RlbmVyICkge1xyXG5cdFx0ZWxlbS5yZW1vdmVFdmVudExpc3RlbmVyKCB0eXBlLCBoYW5kbGUgKTtcclxuXHR9XHJcbn07XHJcblxyXG5qUXVlcnkuRXZlbnQgPSBmdW5jdGlvbiggc3JjLCBwcm9wcyApIHtcclxuXHJcblx0Ly8gQWxsb3cgaW5zdGFudGlhdGlvbiB3aXRob3V0IHRoZSAnbmV3JyBrZXl3b3JkXHJcblx0aWYgKCAhKCB0aGlzIGluc3RhbmNlb2YgalF1ZXJ5LkV2ZW50ICkgKSB7XHJcblx0XHRyZXR1cm4gbmV3IGpRdWVyeS5FdmVudCggc3JjLCBwcm9wcyApO1xyXG5cdH1cclxuXHJcblx0Ly8gRXZlbnQgb2JqZWN0XHJcblx0aWYgKCBzcmMgJiYgc3JjLnR5cGUgKSB7XHJcblx0XHR0aGlzLm9yaWdpbmFsRXZlbnQgPSBzcmM7XHJcblx0XHR0aGlzLnR5cGUgPSBzcmMudHlwZTtcclxuXHJcblx0XHQvLyBFdmVudHMgYnViYmxpbmcgdXAgdGhlIGRvY3VtZW50IG1heSBoYXZlIGJlZW4gbWFya2VkIGFzIHByZXZlbnRlZFxyXG5cdFx0Ly8gYnkgYSBoYW5kbGVyIGxvd2VyIGRvd24gdGhlIHRyZWU7IHJlZmxlY3QgdGhlIGNvcnJlY3QgdmFsdWUuXHJcblx0XHR0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IHNyYy5kZWZhdWx0UHJldmVudGVkIHx8XHJcblx0XHRcdFx0c3JjLmRlZmF1bHRQcmV2ZW50ZWQgPT09IHVuZGVmaW5lZCAmJlxyXG5cclxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMFxyXG5cdFx0XHRcdHNyYy5yZXR1cm5WYWx1ZSA9PT0gZmFsc2UgP1xyXG5cdFx0XHRyZXR1cm5UcnVlIDpcclxuXHRcdFx0cmV0dXJuRmFsc2U7XHJcblxyXG5cdC8vIEV2ZW50IHR5cGVcclxuXHR9IGVsc2Uge1xyXG5cdFx0dGhpcy50eXBlID0gc3JjO1xyXG5cdH1cclxuXHJcblx0Ly8gUHV0IGV4cGxpY2l0bHkgcHJvdmlkZWQgcHJvcGVydGllcyBvbnRvIHRoZSBldmVudCBvYmplY3RcclxuXHRpZiAoIHByb3BzICkge1xyXG5cdFx0alF1ZXJ5LmV4dGVuZCggdGhpcywgcHJvcHMgKTtcclxuXHR9XHJcblxyXG5cdC8vIENyZWF0ZSBhIHRpbWVzdGFtcCBpZiBpbmNvbWluZyBldmVudCBkb2Vzbid0IGhhdmUgb25lXHJcblx0dGhpcy50aW1lU3RhbXAgPSBzcmMgJiYgc3JjLnRpbWVTdGFtcCB8fCBqUXVlcnkubm93KCk7XHJcblxyXG5cdC8vIE1hcmsgaXQgYXMgZml4ZWRcclxuXHR0aGlzWyBqUXVlcnkuZXhwYW5kbyBdID0gdHJ1ZTtcclxufTtcclxuXHJcbi8vIGpRdWVyeS5FdmVudCBpcyBiYXNlZCBvbiBET00zIEV2ZW50cyBhcyBzcGVjaWZpZWQgYnkgdGhlIEVDTUFTY3JpcHQgTGFuZ3VhZ2UgQmluZGluZ1xyXG4vLyBodHRwOi8vd3d3LnczLm9yZy9UUi8yMDAzL1dELURPTS1MZXZlbC0zLUV2ZW50cy0yMDAzMDMzMS9lY21hLXNjcmlwdC1iaW5kaW5nLmh0bWxcclxualF1ZXJ5LkV2ZW50LnByb3RvdHlwZSA9IHtcclxuXHRjb25zdHJ1Y3RvcjogalF1ZXJ5LkV2ZW50LFxyXG5cdGlzRGVmYXVsdFByZXZlbnRlZDogcmV0dXJuRmFsc2UsXHJcblx0aXNQcm9wYWdhdGlvblN0b3BwZWQ6IHJldHVybkZhbHNlLFxyXG5cdGlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOiByZXR1cm5GYWxzZSxcclxuXHRpc1NpbXVsYXRlZDogZmFsc2UsXHJcblxyXG5cdHByZXZlbnREZWZhdWx0OiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBlID0gdGhpcy5vcmlnaW5hbEV2ZW50O1xyXG5cclxuXHRcdHRoaXMuaXNEZWZhdWx0UHJldmVudGVkID0gcmV0dXJuVHJ1ZTtcclxuXHJcblx0XHRpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7XHJcblx0XHRcdGUucHJldmVudERlZmF1bHQoKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cdHN0b3BQcm9wYWdhdGlvbjogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgZSA9IHRoaXMub3JpZ2luYWxFdmVudDtcclxuXHJcblx0XHR0aGlzLmlzUHJvcGFnYXRpb25TdG9wcGVkID0gcmV0dXJuVHJ1ZTtcclxuXHJcblx0XHRpZiAoIGUgJiYgIXRoaXMuaXNTaW11bGF0ZWQgKSB7XHJcblx0XHRcdGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcblx0XHR9XHJcblx0fSxcclxuXHRzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb246IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7XHJcblxyXG5cdFx0dGhpcy5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCA9IHJldHVyblRydWU7XHJcblxyXG5cdFx0aWYgKCBlICYmICF0aGlzLmlzU2ltdWxhdGVkICkge1xyXG5cdFx0XHRlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHRoaXMuc3RvcFByb3BhZ2F0aW9uKCk7XHJcblx0fVxyXG59O1xyXG5cclxuLy8gQ3JlYXRlIG1vdXNlZW50ZXIvbGVhdmUgZXZlbnRzIHVzaW5nIG1vdXNlb3Zlci9vdXQgYW5kIGV2ZW50LXRpbWUgY2hlY2tzXHJcbi8vIHNvIHRoYXQgZXZlbnQgZGVsZWdhdGlvbiB3b3JrcyBpbiBqUXVlcnkuXHJcbi8vIERvIHRoZSBzYW1lIGZvciBwb2ludGVyZW50ZXIvcG9pbnRlcmxlYXZlIGFuZCBwb2ludGVyb3Zlci9wb2ludGVyb3V0XHJcbi8vXHJcbi8vIFN1cHBvcnQ6IFNhZmFyaSA3IG9ubHlcclxuLy8gU2FmYXJpIHNlbmRzIG1vdXNlZW50ZXIgdG9vIG9mdGVuOyBzZWU6XHJcbi8vIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD00NzAyNThcclxuLy8gZm9yIHRoZSBkZXNjcmlwdGlvbiBvZiB0aGUgYnVnIChpdCBleGlzdGVkIGluIG9sZGVyIENocm9tZSB2ZXJzaW9ucyBhcyB3ZWxsKS5cclxualF1ZXJ5LmVhY2goIHtcclxuXHRtb3VzZWVudGVyOiBcIm1vdXNlb3ZlclwiLFxyXG5cdG1vdXNlbGVhdmU6IFwibW91c2VvdXRcIixcclxuXHRwb2ludGVyZW50ZXI6IFwicG9pbnRlcm92ZXJcIixcclxuXHRwb2ludGVybGVhdmU6IFwicG9pbnRlcm91dFwiXHJcbn0sIGZ1bmN0aW9uKCBvcmlnLCBmaXggKSB7XHJcblx0alF1ZXJ5LmV2ZW50LnNwZWNpYWxbIG9yaWcgXSA9IHtcclxuXHRcdGRlbGVnYXRlVHlwZTogZml4LFxyXG5cdFx0YmluZFR5cGU6IGZpeCxcclxuXHJcblx0XHRoYW5kbGU6IGZ1bmN0aW9uKCBldmVudCApIHtcclxuXHRcdFx0dmFyIHJldCxcclxuXHRcdFx0XHR0YXJnZXQgPSB0aGlzLFxyXG5cdFx0XHRcdHJlbGF0ZWQgPSBldmVudC5yZWxhdGVkVGFyZ2V0LFxyXG5cdFx0XHRcdGhhbmRsZU9iaiA9IGV2ZW50LmhhbmRsZU9iajtcclxuXHJcblx0XHRcdC8vIEZvciBtb3VzZWVudGVyL2xlYXZlIGNhbGwgdGhlIGhhbmRsZXIgaWYgcmVsYXRlZCBpcyBvdXRzaWRlIHRoZSB0YXJnZXQuXHJcblx0XHRcdC8vIE5COiBObyByZWxhdGVkVGFyZ2V0IGlmIHRoZSBtb3VzZSBsZWZ0L2VudGVyZWQgdGhlIGJyb3dzZXIgd2luZG93XHJcblx0XHRcdGlmICggIXJlbGF0ZWQgfHwgKCByZWxhdGVkICE9PSB0YXJnZXQgJiYgIWpRdWVyeS5jb250YWlucyggdGFyZ2V0LCByZWxhdGVkICkgKSApIHtcclxuXHRcdFx0XHRldmVudC50eXBlID0gaGFuZGxlT2JqLm9yaWdUeXBlO1xyXG5cdFx0XHRcdHJldCA9IGhhbmRsZU9iai5oYW5kbGVyLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcclxuXHRcdFx0XHRldmVudC50eXBlID0gZml4O1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiByZXQ7XHJcblx0XHR9XHJcblx0fTtcclxufSApO1xyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdG9uOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApIHtcclxuXHRcdHJldHVybiBvbiggdGhpcywgdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApO1xyXG5cdH0sXHJcblx0b25lOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApIHtcclxuXHRcdHJldHVybiBvbiggdGhpcywgdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiwgMSApO1xyXG5cdH0sXHJcblx0b2ZmOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBmbiApIHtcclxuXHRcdHZhciBoYW5kbGVPYmosIHR5cGU7XHJcblx0XHRpZiAoIHR5cGVzICYmIHR5cGVzLnByZXZlbnREZWZhdWx0ICYmIHR5cGVzLmhhbmRsZU9iaiApIHtcclxuXHJcblx0XHRcdC8vICggZXZlbnQgKSAgZGlzcGF0Y2hlZCBqUXVlcnkuRXZlbnRcclxuXHRcdFx0aGFuZGxlT2JqID0gdHlwZXMuaGFuZGxlT2JqO1xyXG5cdFx0XHRqUXVlcnkoIHR5cGVzLmRlbGVnYXRlVGFyZ2V0ICkub2ZmKFxyXG5cdFx0XHRcdGhhbmRsZU9iai5uYW1lc3BhY2UgP1xyXG5cdFx0XHRcdFx0aGFuZGxlT2JqLm9yaWdUeXBlICsgXCIuXCIgKyBoYW5kbGVPYmoubmFtZXNwYWNlIDpcclxuXHRcdFx0XHRcdGhhbmRsZU9iai5vcmlnVHlwZSxcclxuXHRcdFx0XHRoYW5kbGVPYmouc2VsZWN0b3IsXHJcblx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXJcclxuXHRcdFx0KTtcclxuXHRcdFx0cmV0dXJuIHRoaXM7XHJcblx0XHR9XHJcblx0XHRpZiAoIHR5cGVvZiB0eXBlcyA9PT0gXCJvYmplY3RcIiApIHtcclxuXHJcblx0XHRcdC8vICggdHlwZXMtb2JqZWN0IFssIHNlbGVjdG9yXSApXHJcblx0XHRcdGZvciAoIHR5cGUgaW4gdHlwZXMgKSB7XHJcblx0XHRcdFx0dGhpcy5vZmYoIHR5cGUsIHNlbGVjdG9yLCB0eXBlc1sgdHlwZSBdICk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIHRoaXM7XHJcblx0XHR9XHJcblx0XHRpZiAoIHNlbGVjdG9yID09PSBmYWxzZSB8fCB0eXBlb2Ygc2VsZWN0b3IgPT09IFwiZnVuY3Rpb25cIiApIHtcclxuXHJcblx0XHRcdC8vICggdHlwZXMgWywgZm5dIClcclxuXHRcdFx0Zm4gPSBzZWxlY3RvcjtcclxuXHRcdFx0c2VsZWN0b3IgPSB1bmRlZmluZWQ7XHJcblx0XHR9XHJcblx0XHRpZiAoIGZuID09PSBmYWxzZSApIHtcclxuXHRcdFx0Zm4gPSByZXR1cm5GYWxzZTtcclxuXHRcdH1cclxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRqUXVlcnkuZXZlbnQucmVtb3ZlKCB0aGlzLCB0eXBlcywgZm4sIHNlbGVjdG9yICk7XHJcblx0XHR9ICk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5cclxudmFyXHJcblx0cnhodG1sVGFnID0gLzwoPyFhcmVhfGJyfGNvbHxlbWJlZHxocnxpbWd8aW5wdXR8bGlua3xtZXRhfHBhcmFtKSgoW1xcdzotXSspW14+XSopXFwvPi9naSxcclxuXHJcblx0Ly8gU3VwcG9ydDogSUUgMTAtMTEsIEVkZ2UgMTAyNDArXHJcblx0Ly8gSW4gSUUvRWRnZSB1c2luZyByZWdleCBncm91cHMgaGVyZSBjYXVzZXMgc2V2ZXJlIHNsb3dkb3ducy5cclxuXHQvLyBTZWUgaHR0cHM6Ly9jb25uZWN0Lm1pY3Jvc29mdC5jb20vSUUvZmVlZGJhY2svZGV0YWlscy8xNzM2NTEyL1xyXG5cdHJub0lubmVyaHRtbCA9IC88c2NyaXB0fDxzdHlsZXw8bGluay9pLFxyXG5cclxuXHQvLyBjaGVja2VkPVwiY2hlY2tlZFwiIG9yIGNoZWNrZWRcclxuXHRyY2hlY2tlZCA9IC9jaGVja2VkXFxzKig/OltePV18PVxccyouY2hlY2tlZC4pL2ksXHJcblx0cnNjcmlwdFR5cGVNYXNrZWQgPSAvXnRydWVcXC8oLiopLyxcclxuXHRyY2xlYW5TY3JpcHQgPSAvXlxccyo8ISg/OlxcW0NEQVRBXFxbfC0tKXwoPzpcXF1cXF18LS0pPlxccyokL2c7XHJcblxyXG4vLyBNYW5pcHVsYXRpbmcgdGFibGVzIHJlcXVpcmVzIGEgdGJvZHlcclxuZnVuY3Rpb24gbWFuaXB1bGF0aW9uVGFyZ2V0KCBlbGVtLCBjb250ZW50ICkge1xyXG5cdHJldHVybiBqUXVlcnkubm9kZU5hbWUoIGVsZW0sIFwidGFibGVcIiApICYmXHJcblx0XHRqUXVlcnkubm9kZU5hbWUoIGNvbnRlbnQubm9kZVR5cGUgIT09IDExID8gY29udGVudCA6IGNvbnRlbnQuZmlyc3RDaGlsZCwgXCJ0clwiICkgP1xyXG5cclxuXHRcdGVsZW0uZ2V0RWxlbWVudHNCeVRhZ05hbWUoIFwidGJvZHlcIiApWyAwIF0gfHxcclxuXHRcdFx0ZWxlbS5hcHBlbmRDaGlsZCggZWxlbS5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwidGJvZHlcIiApICkgOlxyXG5cdFx0ZWxlbTtcclxufVxyXG5cclxuLy8gUmVwbGFjZS9yZXN0b3JlIHRoZSB0eXBlIGF0dHJpYnV0ZSBvZiBzY3JpcHQgZWxlbWVudHMgZm9yIHNhZmUgRE9NIG1hbmlwdWxhdGlvblxyXG5mdW5jdGlvbiBkaXNhYmxlU2NyaXB0KCBlbGVtICkge1xyXG5cdGVsZW0udHlwZSA9ICggZWxlbS5nZXRBdHRyaWJ1dGUoIFwidHlwZVwiICkgIT09IG51bGwgKSArIFwiL1wiICsgZWxlbS50eXBlO1xyXG5cdHJldHVybiBlbGVtO1xyXG59XHJcbmZ1bmN0aW9uIHJlc3RvcmVTY3JpcHQoIGVsZW0gKSB7XHJcblx0dmFyIG1hdGNoID0gcnNjcmlwdFR5cGVNYXNrZWQuZXhlYyggZWxlbS50eXBlICk7XHJcblxyXG5cdGlmICggbWF0Y2ggKSB7XHJcblx0XHRlbGVtLnR5cGUgPSBtYXRjaFsgMSBdO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRlbGVtLnJlbW92ZUF0dHJpYnV0ZSggXCJ0eXBlXCIgKTtcclxuXHR9XHJcblxyXG5cdHJldHVybiBlbGVtO1xyXG59XHJcblxyXG5mdW5jdGlvbiBjbG9uZUNvcHlFdmVudCggc3JjLCBkZXN0ICkge1xyXG5cdHZhciBpLCBsLCB0eXBlLCBwZGF0YU9sZCwgcGRhdGFDdXIsIHVkYXRhT2xkLCB1ZGF0YUN1ciwgZXZlbnRzO1xyXG5cclxuXHRpZiAoIGRlc3Qubm9kZVR5cGUgIT09IDEgKSB7XHJcblx0XHRyZXR1cm47XHJcblx0fVxyXG5cclxuXHQvLyAxLiBDb3B5IHByaXZhdGUgZGF0YTogZXZlbnRzLCBoYW5kbGVycywgZXRjLlxyXG5cdGlmICggZGF0YVByaXYuaGFzRGF0YSggc3JjICkgKSB7XHJcblx0XHRwZGF0YU9sZCA9IGRhdGFQcml2LmFjY2Vzcyggc3JjICk7XHJcblx0XHRwZGF0YUN1ciA9IGRhdGFQcml2LnNldCggZGVzdCwgcGRhdGFPbGQgKTtcclxuXHRcdGV2ZW50cyA9IHBkYXRhT2xkLmV2ZW50cztcclxuXHJcblx0XHRpZiAoIGV2ZW50cyApIHtcclxuXHRcdFx0ZGVsZXRlIHBkYXRhQ3VyLmhhbmRsZTtcclxuXHRcdFx0cGRhdGFDdXIuZXZlbnRzID0ge307XHJcblxyXG5cdFx0XHRmb3IgKCB0eXBlIGluIGV2ZW50cyApIHtcclxuXHRcdFx0XHRmb3IgKCBpID0gMCwgbCA9IGV2ZW50c1sgdHlwZSBdLmxlbmd0aDsgaSA8IGw7IGkrKyApIHtcclxuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5hZGQoIGRlc3QsIHR5cGUsIGV2ZW50c1sgdHlwZSBdWyBpIF0gKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdC8vIDIuIENvcHkgdXNlciBkYXRhXHJcblx0aWYgKCBkYXRhVXNlci5oYXNEYXRhKCBzcmMgKSApIHtcclxuXHRcdHVkYXRhT2xkID0gZGF0YVVzZXIuYWNjZXNzKCBzcmMgKTtcclxuXHRcdHVkYXRhQ3VyID0galF1ZXJ5LmV4dGVuZCgge30sIHVkYXRhT2xkICk7XHJcblxyXG5cdFx0ZGF0YVVzZXIuc2V0KCBkZXN0LCB1ZGF0YUN1ciApO1xyXG5cdH1cclxufVxyXG5cclxuLy8gRml4IElFIGJ1Z3MsIHNlZSBzdXBwb3J0IHRlc3RzXHJcbmZ1bmN0aW9uIGZpeElucHV0KCBzcmMsIGRlc3QgKSB7XHJcblx0dmFyIG5vZGVOYW1lID0gZGVzdC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xyXG5cclxuXHQvLyBGYWlscyB0byBwZXJzaXN0IHRoZSBjaGVja2VkIHN0YXRlIG9mIGEgY2xvbmVkIGNoZWNrYm94IG9yIHJhZGlvIGJ1dHRvbi5cclxuXHRpZiAoIG5vZGVOYW1lID09PSBcImlucHV0XCIgJiYgcmNoZWNrYWJsZVR5cGUudGVzdCggc3JjLnR5cGUgKSApIHtcclxuXHRcdGRlc3QuY2hlY2tlZCA9IHNyYy5jaGVja2VkO1xyXG5cclxuXHQvLyBGYWlscyB0byByZXR1cm4gdGhlIHNlbGVjdGVkIG9wdGlvbiB0byB0aGUgZGVmYXVsdCBzZWxlY3RlZCBzdGF0ZSB3aGVuIGNsb25pbmcgb3B0aW9uc1xyXG5cdH0gZWxzZSBpZiAoIG5vZGVOYW1lID09PSBcImlucHV0XCIgfHwgbm9kZU5hbWUgPT09IFwidGV4dGFyZWFcIiApIHtcclxuXHRcdGRlc3QuZGVmYXVsdFZhbHVlID0gc3JjLmRlZmF1bHRWYWx1ZTtcclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGRvbU1hbmlwKCBjb2xsZWN0aW9uLCBhcmdzLCBjYWxsYmFjaywgaWdub3JlZCApIHtcclxuXHJcblx0Ly8gRmxhdHRlbiBhbnkgbmVzdGVkIGFycmF5c1xyXG5cdGFyZ3MgPSBjb25jYXQuYXBwbHkoIFtdLCBhcmdzICk7XHJcblxyXG5cdHZhciBmcmFnbWVudCwgZmlyc3QsIHNjcmlwdHMsIGhhc1NjcmlwdHMsIG5vZGUsIGRvYyxcclxuXHRcdGkgPSAwLFxyXG5cdFx0bCA9IGNvbGxlY3Rpb24ubGVuZ3RoLFxyXG5cdFx0aU5vQ2xvbmUgPSBsIC0gMSxcclxuXHRcdHZhbHVlID0gYXJnc1sgMCBdLFxyXG5cdFx0aXNGdW5jdGlvbiA9IGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApO1xyXG5cclxuXHQvLyBXZSBjYW4ndCBjbG9uZU5vZGUgZnJhZ21lbnRzIHRoYXQgY29udGFpbiBjaGVja2VkLCBpbiBXZWJLaXRcclxuXHRpZiAoIGlzRnVuY3Rpb24gfHxcclxuXHRcdFx0KCBsID4gMSAmJiB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiZcclxuXHRcdFx0XHQhc3VwcG9ydC5jaGVja0Nsb25lICYmIHJjaGVja2VkLnRlc3QoIHZhbHVlICkgKSApIHtcclxuXHRcdHJldHVybiBjb2xsZWN0aW9uLmVhY2goIGZ1bmN0aW9uKCBpbmRleCApIHtcclxuXHRcdFx0dmFyIHNlbGYgPSBjb2xsZWN0aW9uLmVxKCBpbmRleCApO1xyXG5cdFx0XHRpZiAoIGlzRnVuY3Rpb24gKSB7XHJcblx0XHRcdFx0YXJnc1sgMCBdID0gdmFsdWUuY2FsbCggdGhpcywgaW5kZXgsIHNlbGYuaHRtbCgpICk7XHJcblx0XHRcdH1cclxuXHRcdFx0ZG9tTWFuaXAoIHNlbGYsIGFyZ3MsIGNhbGxiYWNrLCBpZ25vcmVkICk7XHJcblx0XHR9ICk7XHJcblx0fVxyXG5cclxuXHRpZiAoIGwgKSB7XHJcblx0XHRmcmFnbWVudCA9IGJ1aWxkRnJhZ21lbnQoIGFyZ3MsIGNvbGxlY3Rpb25bIDAgXS5vd25lckRvY3VtZW50LCBmYWxzZSwgY29sbGVjdGlvbiwgaWdub3JlZCApO1xyXG5cdFx0Zmlyc3QgPSBmcmFnbWVudC5maXJzdENoaWxkO1xyXG5cclxuXHRcdGlmICggZnJhZ21lbnQuY2hpbGROb2Rlcy5sZW5ndGggPT09IDEgKSB7XHJcblx0XHRcdGZyYWdtZW50ID0gZmlyc3Q7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gUmVxdWlyZSBlaXRoZXIgbmV3IGNvbnRlbnQgb3IgYW4gaW50ZXJlc3QgaW4gaWdub3JlZCBlbGVtZW50cyB0byBpbnZva2UgdGhlIGNhbGxiYWNrXHJcblx0XHRpZiAoIGZpcnN0IHx8IGlnbm9yZWQgKSB7XHJcblx0XHRcdHNjcmlwdHMgPSBqUXVlcnkubWFwKCBnZXRBbGwoIGZyYWdtZW50LCBcInNjcmlwdFwiICksIGRpc2FibGVTY3JpcHQgKTtcclxuXHRcdFx0aGFzU2NyaXB0cyA9IHNjcmlwdHMubGVuZ3RoO1xyXG5cclxuXHRcdFx0Ly8gVXNlIHRoZSBvcmlnaW5hbCBmcmFnbWVudCBmb3IgdGhlIGxhc3QgaXRlbVxyXG5cdFx0XHQvLyBpbnN0ZWFkIG9mIHRoZSBmaXJzdCBiZWNhdXNlIGl0IGNhbiBlbmQgdXBcclxuXHRcdFx0Ly8gYmVpbmcgZW1wdGllZCBpbmNvcnJlY3RseSBpbiBjZXJ0YWluIHNpdHVhdGlvbnMgKCM4MDcwKS5cclxuXHRcdFx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xyXG5cdFx0XHRcdG5vZGUgPSBmcmFnbWVudDtcclxuXHJcblx0XHRcdFx0aWYgKCBpICE9PSBpTm9DbG9uZSApIHtcclxuXHRcdFx0XHRcdG5vZGUgPSBqUXVlcnkuY2xvbmUoIG5vZGUsIHRydWUsIHRydWUgKTtcclxuXHJcblx0XHRcdFx0XHQvLyBLZWVwIHJlZmVyZW5jZXMgdG8gY2xvbmVkIHNjcmlwdHMgZm9yIGxhdGVyIHJlc3RvcmF0aW9uXHJcblx0XHRcdFx0XHRpZiAoIGhhc1NjcmlwdHMgKSB7XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMSwgUGhhbnRvbUpTPDJcclxuXHRcdFx0XHRcdFx0Ly8gcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93cyBvbiBhbmNpZW50IFdlYktpdFxyXG5cdFx0XHRcdFx0XHRqUXVlcnkubWVyZ2UoIHNjcmlwdHMsIGdldEFsbCggbm9kZSwgXCJzY3JpcHRcIiApICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRjYWxsYmFjay5jYWxsKCBjb2xsZWN0aW9uWyBpIF0sIG5vZGUsIGkgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0aWYgKCBoYXNTY3JpcHRzICkge1xyXG5cdFx0XHRcdGRvYyA9IHNjcmlwdHNbIHNjcmlwdHMubGVuZ3RoIC0gMSBdLm93bmVyRG9jdW1lbnQ7XHJcblxyXG5cdFx0XHRcdC8vIFJlZW5hYmxlIHNjcmlwdHNcclxuXHRcdFx0XHRqUXVlcnkubWFwKCBzY3JpcHRzLCByZXN0b3JlU2NyaXB0ICk7XHJcblxyXG5cdFx0XHRcdC8vIEV2YWx1YXRlIGV4ZWN1dGFibGUgc2NyaXB0cyBvbiBmaXJzdCBkb2N1bWVudCBpbnNlcnRpb25cclxuXHRcdFx0XHRmb3IgKCBpID0gMDsgaSA8IGhhc1NjcmlwdHM7IGkrKyApIHtcclxuXHRcdFx0XHRcdG5vZGUgPSBzY3JpcHRzWyBpIF07XHJcblx0XHRcdFx0XHRpZiAoIHJzY3JpcHRUeXBlLnRlc3QoIG5vZGUudHlwZSB8fCBcIlwiICkgJiZcclxuXHRcdFx0XHRcdFx0IWRhdGFQcml2LmFjY2Vzcyggbm9kZSwgXCJnbG9iYWxFdmFsXCIgKSAmJlxyXG5cdFx0XHRcdFx0XHRqUXVlcnkuY29udGFpbnMoIGRvYywgbm9kZSApICkge1xyXG5cclxuXHRcdFx0XHRcdFx0aWYgKCBub2RlLnNyYyApIHtcclxuXHJcblx0XHRcdFx0XHRcdFx0Ly8gT3B0aW9uYWwgQUpBWCBkZXBlbmRlbmN5LCBidXQgd29uJ3QgcnVuIHNjcmlwdHMgaWYgbm90IHByZXNlbnRcclxuXHRcdFx0XHRcdFx0XHRpZiAoIGpRdWVyeS5fZXZhbFVybCApIHtcclxuXHRcdFx0XHRcdFx0XHRcdGpRdWVyeS5fZXZhbFVybCggbm9kZS5zcmMgKTtcclxuXHRcdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0alF1ZXJ5Lmdsb2JhbEV2YWwoIG5vZGUudGV4dENvbnRlbnQucmVwbGFjZSggcmNsZWFuU2NyaXB0LCBcIlwiICkgKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIGNvbGxlY3Rpb247XHJcbn1cclxuXHJcbmZ1bmN0aW9uIHJlbW92ZSggZWxlbSwgc2VsZWN0b3IsIGtlZXBEYXRhICkge1xyXG5cdHZhciBub2RlLFxyXG5cdFx0bm9kZXMgPSBzZWxlY3RvciA/IGpRdWVyeS5maWx0ZXIoIHNlbGVjdG9yLCBlbGVtICkgOiBlbGVtLFxyXG5cdFx0aSA9IDA7XHJcblxyXG5cdGZvciAoIDsgKCBub2RlID0gbm9kZXNbIGkgXSApICE9IG51bGw7IGkrKyApIHtcclxuXHRcdGlmICggIWtlZXBEYXRhICYmIG5vZGUubm9kZVR5cGUgPT09IDEgKSB7XHJcblx0XHRcdGpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggbm9kZSApICk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBub2RlLnBhcmVudE5vZGUgKSB7XHJcblx0XHRcdGlmICgga2VlcERhdGEgJiYgalF1ZXJ5LmNvbnRhaW5zKCBub2RlLm93bmVyRG9jdW1lbnQsIG5vZGUgKSApIHtcclxuXHRcdFx0XHRzZXRHbG9iYWxFdmFsKCBnZXRBbGwoIG5vZGUsIFwic2NyaXB0XCIgKSApO1xyXG5cdFx0XHR9XHJcblx0XHRcdG5vZGUucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggbm9kZSApO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIGVsZW07XHJcbn1cclxuXHJcbmpRdWVyeS5leHRlbmQoIHtcclxuXHRodG1sUHJlZmlsdGVyOiBmdW5jdGlvbiggaHRtbCApIHtcclxuXHRcdHJldHVybiBodG1sLnJlcGxhY2UoIHJ4aHRtbFRhZywgXCI8JDE+PC8kMj5cIiApO1xyXG5cdH0sXHJcblxyXG5cdGNsb25lOiBmdW5jdGlvbiggZWxlbSwgZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKSB7XHJcblx0XHR2YXIgaSwgbCwgc3JjRWxlbWVudHMsIGRlc3RFbGVtZW50cyxcclxuXHRcdFx0Y2xvbmUgPSBlbGVtLmNsb25lTm9kZSggdHJ1ZSApLFxyXG5cdFx0XHRpblBhZ2UgPSBqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApO1xyXG5cclxuXHRcdC8vIEZpeCBJRSBjbG9uaW5nIGlzc3Vlc1xyXG5cdFx0aWYgKCAhc3VwcG9ydC5ub0Nsb25lQ2hlY2tlZCAmJiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgZWxlbS5ub2RlVHlwZSA9PT0gMTEgKSAmJlxyXG5cdFx0XHRcdCFqUXVlcnkuaXNYTUxEb2MoIGVsZW0gKSApIHtcclxuXHJcblx0XHRcdC8vIFdlIGVzY2hldyBTaXp6bGUgaGVyZSBmb3IgcGVyZm9ybWFuY2UgcmVhc29uczogaHR0cDovL2pzcGVyZi5jb20vZ2V0YWxsLXZzLXNpenpsZS8yXHJcblx0XHRcdGRlc3RFbGVtZW50cyA9IGdldEFsbCggY2xvbmUgKTtcclxuXHRcdFx0c3JjRWxlbWVudHMgPSBnZXRBbGwoIGVsZW0gKTtcclxuXHJcblx0XHRcdGZvciAoIGkgPSAwLCBsID0gc3JjRWxlbWVudHMubGVuZ3RoOyBpIDwgbDsgaSsrICkge1xyXG5cdFx0XHRcdGZpeElucHV0KCBzcmNFbGVtZW50c1sgaSBdLCBkZXN0RWxlbWVudHNbIGkgXSApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ29weSB0aGUgZXZlbnRzIGZyb20gdGhlIG9yaWdpbmFsIHRvIHRoZSBjbG9uZVxyXG5cdFx0aWYgKCBkYXRhQW5kRXZlbnRzICkge1xyXG5cdFx0XHRpZiAoIGRlZXBEYXRhQW5kRXZlbnRzICkge1xyXG5cdFx0XHRcdHNyY0VsZW1lbnRzID0gc3JjRWxlbWVudHMgfHwgZ2V0QWxsKCBlbGVtICk7XHJcblx0XHRcdFx0ZGVzdEVsZW1lbnRzID0gZGVzdEVsZW1lbnRzIHx8IGdldEFsbCggY2xvbmUgKTtcclxuXHJcblx0XHRcdFx0Zm9yICggaSA9IDAsIGwgPSBzcmNFbGVtZW50cy5sZW5ndGg7IGkgPCBsOyBpKysgKSB7XHJcblx0XHRcdFx0XHRjbG9uZUNvcHlFdmVudCggc3JjRWxlbWVudHNbIGkgXSwgZGVzdEVsZW1lbnRzWyBpIF0gKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0Y2xvbmVDb3B5RXZlbnQoIGVsZW0sIGNsb25lICk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBQcmVzZXJ2ZSBzY3JpcHQgZXZhbHVhdGlvbiBoaXN0b3J5XHJcblx0XHRkZXN0RWxlbWVudHMgPSBnZXRBbGwoIGNsb25lLCBcInNjcmlwdFwiICk7XHJcblx0XHRpZiAoIGRlc3RFbGVtZW50cy5sZW5ndGggPiAwICkge1xyXG5cdFx0XHRzZXRHbG9iYWxFdmFsKCBkZXN0RWxlbWVudHMsICFpblBhZ2UgJiYgZ2V0QWxsKCBlbGVtLCBcInNjcmlwdFwiICkgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBSZXR1cm4gdGhlIGNsb25lZCBzZXRcclxuXHRcdHJldHVybiBjbG9uZTtcclxuXHR9LFxyXG5cclxuXHRjbGVhbkRhdGE6IGZ1bmN0aW9uKCBlbGVtcyApIHtcclxuXHRcdHZhciBkYXRhLCBlbGVtLCB0eXBlLFxyXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWwsXHJcblx0XHRcdGkgPSAwO1xyXG5cclxuXHRcdGZvciAoIDsgKCBlbGVtID0gZWxlbXNbIGkgXSApICE9PSB1bmRlZmluZWQ7IGkrKyApIHtcclxuXHRcdFx0aWYgKCBhY2NlcHREYXRhKCBlbGVtICkgKSB7XHJcblx0XHRcdFx0aWYgKCAoIGRhdGEgPSBlbGVtWyBkYXRhUHJpdi5leHBhbmRvIF0gKSApIHtcclxuXHRcdFx0XHRcdGlmICggZGF0YS5ldmVudHMgKSB7XHJcblx0XHRcdFx0XHRcdGZvciAoIHR5cGUgaW4gZGF0YS5ldmVudHMgKSB7XHJcblx0XHRcdFx0XHRcdFx0aWYgKCBzcGVjaWFsWyB0eXBlIF0gKSB7XHJcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuZXZlbnQucmVtb3ZlKCBlbGVtLCB0eXBlICk7XHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIFRoaXMgaXMgYSBzaG9ydGN1dCB0byBhdm9pZCBqUXVlcnkuZXZlbnQucmVtb3ZlJ3Mgb3ZlcmhlYWRcclxuXHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LnJlbW92ZUV2ZW50KCBlbGVtLCB0eXBlLCBkYXRhLmhhbmRsZSApO1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IENocm9tZSA8PSAzNS00NStcclxuXHRcdFx0XHRcdC8vIEFzc2lnbiB1bmRlZmluZWQgaW5zdGVhZCBvZiB1c2luZyBkZWxldGUsIHNlZSBEYXRhI3JlbW92ZVxyXG5cdFx0XHRcdFx0ZWxlbVsgZGF0YVByaXYuZXhwYW5kbyBdID0gdW5kZWZpbmVkO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoIGVsZW1bIGRhdGFVc2VyLmV4cGFuZG8gXSApIHtcclxuXHJcblx0XHRcdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWUgPD0gMzUtNDUrXHJcblx0XHRcdFx0XHQvLyBBc3NpZ24gdW5kZWZpbmVkIGluc3RlYWQgb2YgdXNpbmcgZGVsZXRlLCBzZWUgRGF0YSNyZW1vdmVcclxuXHRcdFx0XHRcdGVsZW1bIGRhdGFVc2VyLmV4cGFuZG8gXSA9IHVuZGVmaW5lZDtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcbn0gKTtcclxuXHJcbmpRdWVyeS5mbi5leHRlbmQoIHtcclxuXHJcblx0Ly8gS2VlcCBkb21NYW5pcCBleHBvc2VkIHVudGlsIDMuMCAoZ2gtMjIyNSlcclxuXHRkb21NYW5pcDogZG9tTWFuaXAsXHJcblxyXG5cdGRldGFjaDogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xyXG5cdFx0cmV0dXJuIHJlbW92ZSggdGhpcywgc2VsZWN0b3IsIHRydWUgKTtcclxuXHR9LFxyXG5cclxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcclxuXHRcdHJldHVybiByZW1vdmUoIHRoaXMsIHNlbGVjdG9yICk7XHJcblx0fSxcclxuXHJcblx0dGV4dDogZnVuY3Rpb24oIHZhbHVlICkge1xyXG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIHZhbHVlICkge1xyXG5cdFx0XHRyZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/XHJcblx0XHRcdFx0alF1ZXJ5LnRleHQoIHRoaXMgKSA6XHJcblx0XHRcdFx0dGhpcy5lbXB0eSgpLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0aWYgKCB0aGlzLm5vZGVUeXBlID09PSAxIHx8IHRoaXMubm9kZVR5cGUgPT09IDExIHx8IHRoaXMubm9kZVR5cGUgPT09IDkgKSB7XHJcblx0XHRcdFx0XHRcdHRoaXMudGV4dENvbnRlbnQgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9ICk7XHJcblx0XHR9LCBudWxsLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCApO1xyXG5cdH0sXHJcblxyXG5cdGFwcGVuZDogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSA9PT0gMSB8fCB0aGlzLm5vZGVUeXBlID09PSAxMSB8fCB0aGlzLm5vZGVUeXBlID09PSA5ICkge1xyXG5cdFx0XHRcdHZhciB0YXJnZXQgPSBtYW5pcHVsYXRpb25UYXJnZXQoIHRoaXMsIGVsZW0gKTtcclxuXHRcdFx0XHR0YXJnZXQuYXBwZW5kQ2hpbGQoIGVsZW0gKTtcclxuXHRcdFx0fVxyXG5cdFx0fSApO1xyXG5cdH0sXHJcblxyXG5cdHByZXBlbmQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIGRvbU1hbmlwKCB0aGlzLCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgPT09IDEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gMTEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gOSApIHtcclxuXHRcdFx0XHR2YXIgdGFyZ2V0ID0gbWFuaXB1bGF0aW9uVGFyZ2V0KCB0aGlzLCBlbGVtICk7XHJcblx0XHRcdFx0dGFyZ2V0Lmluc2VydEJlZm9yZSggZWxlbSwgdGFyZ2V0LmZpcnN0Q2hpbGQgKTtcclxuXHRcdFx0fVxyXG5cdFx0fSApO1xyXG5cdH0sXHJcblxyXG5cdGJlZm9yZTogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdGlmICggdGhpcy5wYXJlbnROb2RlICkge1xyXG5cdFx0XHRcdHRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoIGVsZW0sIHRoaXMgKTtcclxuXHRcdFx0fVxyXG5cdFx0fSApO1xyXG5cdH0sXHJcblxyXG5cdGFmdGVyOiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiBkb21NYW5pcCggdGhpcywgYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0aWYgKCB0aGlzLnBhcmVudE5vZGUgKSB7XHJcblx0XHRcdFx0dGhpcy5wYXJlbnROb2RlLmluc2VydEJlZm9yZSggZWxlbSwgdGhpcy5uZXh0U2libGluZyApO1xyXG5cdFx0XHR9XHJcblx0XHR9ICk7XHJcblx0fSxcclxuXHJcblx0ZW1wdHk6IGZ1bmN0aW9uKCkge1xyXG5cdFx0dmFyIGVsZW0sXHJcblx0XHRcdGkgPSAwO1xyXG5cclxuXHRcdGZvciAoIDsgKCBlbGVtID0gdGhpc1sgaSBdICkgIT0gbnVsbDsgaSsrICkge1xyXG5cdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XHJcblxyXG5cdFx0XHRcdC8vIFByZXZlbnQgbWVtb3J5IGxlYWtzXHJcblx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtLCBmYWxzZSApICk7XHJcblxyXG5cdFx0XHRcdC8vIFJlbW92ZSBhbnkgcmVtYWluaW5nIG5vZGVzXHJcblx0XHRcdFx0ZWxlbS50ZXh0Q29udGVudCA9IFwiXCI7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHRyZXR1cm4gdGhpcztcclxuXHR9LFxyXG5cclxuXHRjbG9uZTogZnVuY3Rpb24oIGRhdGFBbmRFdmVudHMsIGRlZXBEYXRhQW5kRXZlbnRzICkge1xyXG5cdFx0ZGF0YUFuZEV2ZW50cyA9IGRhdGFBbmRFdmVudHMgPT0gbnVsbCA/IGZhbHNlIDogZGF0YUFuZEV2ZW50cztcclxuXHRcdGRlZXBEYXRhQW5kRXZlbnRzID0gZGVlcERhdGFBbmRFdmVudHMgPT0gbnVsbCA/IGRhdGFBbmRFdmVudHMgOiBkZWVwRGF0YUFuZEV2ZW50cztcclxuXHJcblx0XHRyZXR1cm4gdGhpcy5tYXAoIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRyZXR1cm4galF1ZXJ5LmNsb25lKCB0aGlzLCBkYXRhQW5kRXZlbnRzLCBkZWVwRGF0YUFuZEV2ZW50cyApO1xyXG5cdFx0fSApO1xyXG5cdH0sXHJcblxyXG5cdGh0bWw6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcclxuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcclxuXHRcdFx0dmFyIGVsZW0gPSB0aGlzWyAwIF0gfHwge30sXHJcblx0XHRcdFx0aSA9IDAsXHJcblx0XHRcdFx0bCA9IHRoaXMubGVuZ3RoO1xyXG5cclxuXHRcdFx0aWYgKCB2YWx1ZSA9PT0gdW5kZWZpbmVkICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XHJcblx0XHRcdFx0cmV0dXJuIGVsZW0uaW5uZXJIVE1MO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTZWUgaWYgd2UgY2FuIHRha2UgYSBzaG9ydGN1dCBhbmQganVzdCB1c2UgaW5uZXJIVE1MXHJcblx0XHRcdGlmICggdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmICFybm9Jbm5lcmh0bWwudGVzdCggdmFsdWUgKSAmJlxyXG5cdFx0XHRcdCF3cmFwTWFwWyAoIHJ0YWdOYW1lLmV4ZWMoIHZhbHVlICkgfHwgWyBcIlwiLCBcIlwiIF0gKVsgMSBdLnRvTG93ZXJDYXNlKCkgXSApIHtcclxuXHJcblx0XHRcdFx0dmFsdWUgPSBqUXVlcnkuaHRtbFByZWZpbHRlciggdmFsdWUgKTtcclxuXHJcblx0XHRcdFx0dHJ5IHtcclxuXHRcdFx0XHRcdGZvciAoIDsgaSA8IGw7IGkrKyApIHtcclxuXHRcdFx0XHRcdFx0ZWxlbSA9IHRoaXNbIGkgXSB8fCB7fTtcclxuXHJcblx0XHRcdFx0XHRcdC8vIFJlbW92ZSBlbGVtZW50IG5vZGVzIGFuZCBwcmV2ZW50IG1lbW9yeSBsZWFrc1xyXG5cdFx0XHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XHJcblx0XHRcdFx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtLCBmYWxzZSApICk7XHJcblx0XHRcdFx0XHRcdFx0ZWxlbS5pbm5lckhUTUwgPSB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdGVsZW0gPSAwO1xyXG5cclxuXHRcdFx0XHQvLyBJZiB1c2luZyBpbm5lckhUTUwgdGhyb3dzIGFuIGV4Y2VwdGlvbiwgdXNlIHRoZSBmYWxsYmFjayBtZXRob2RcclxuXHRcdFx0XHR9IGNhdGNoICggZSApIHt9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmICggZWxlbSApIHtcclxuXHRcdFx0XHR0aGlzLmVtcHR5KCkuYXBwZW5kKCB2YWx1ZSApO1xyXG5cdFx0XHR9XHJcblx0XHR9LCBudWxsLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCApO1xyXG5cdH0sXHJcblxyXG5cdHJlcGxhY2VXaXRoOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBpZ25vcmVkID0gW107XHJcblxyXG5cdFx0Ly8gTWFrZSB0aGUgY2hhbmdlcywgcmVwbGFjaW5nIGVhY2ggbm9uLWlnbm9yZWQgY29udGV4dCBlbGVtZW50IHdpdGggdGhlIG5ldyBjb250ZW50XHJcblx0XHRyZXR1cm4gZG9tTWFuaXAoIHRoaXMsIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudE5vZGU7XHJcblxyXG5cdFx0XHRpZiAoIGpRdWVyeS5pbkFycmF5KCB0aGlzLCBpZ25vcmVkICkgPCAwICkge1xyXG5cdFx0XHRcdGpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggdGhpcyApICk7XHJcblx0XHRcdFx0aWYgKCBwYXJlbnQgKSB7XHJcblx0XHRcdFx0XHRwYXJlbnQucmVwbGFjZUNoaWxkKCBlbGVtLCB0aGlzICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0Ly8gRm9yY2UgY2FsbGJhY2sgaW52b2NhdGlvblxyXG5cdFx0fSwgaWdub3JlZCApO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmVhY2goIHtcclxuXHRhcHBlbmRUbzogXCJhcHBlbmRcIixcclxuXHRwcmVwZW5kVG86IFwicHJlcGVuZFwiLFxyXG5cdGluc2VydEJlZm9yZTogXCJiZWZvcmVcIixcclxuXHRpbnNlcnRBZnRlcjogXCJhZnRlclwiLFxyXG5cdHJlcGxhY2VBbGw6IFwicmVwbGFjZVdpdGhcIlxyXG59LCBmdW5jdGlvbiggbmFtZSwgb3JpZ2luYWwgKSB7XHJcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XHJcblx0XHR2YXIgZWxlbXMsXHJcblx0XHRcdHJldCA9IFtdLFxyXG5cdFx0XHRpbnNlcnQgPSBqUXVlcnkoIHNlbGVjdG9yICksXHJcblx0XHRcdGxhc3QgPSBpbnNlcnQubGVuZ3RoIC0gMSxcclxuXHRcdFx0aSA9IDA7XHJcblxyXG5cdFx0Zm9yICggOyBpIDw9IGxhc3Q7IGkrKyApIHtcclxuXHRcdFx0ZWxlbXMgPSBpID09PSBsYXN0ID8gdGhpcyA6IHRoaXMuY2xvbmUoIHRydWUgKTtcclxuXHRcdFx0alF1ZXJ5KCBpbnNlcnRbIGkgXSApWyBvcmlnaW5hbCBdKCBlbGVtcyApO1xyXG5cclxuXHRcdFx0Ly8gU3VwcG9ydDogUXRXZWJLaXRcclxuXHRcdFx0Ly8gLmdldCgpIGJlY2F1c2UgcHVzaC5hcHBseShfLCBhcnJheWxpa2UpIHRocm93c1xyXG5cdFx0XHRwdXNoLmFwcGx5KCByZXQsIGVsZW1zLmdldCgpICk7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCByZXQgKTtcclxuXHR9O1xyXG59ICk7XHJcblxyXG5cclxudmFyIGlmcmFtZSxcclxuXHRlbGVtZGlzcGxheSA9IHtcclxuXHJcblx0XHQvLyBTdXBwb3J0OiBGaXJlZm94XHJcblx0XHQvLyBXZSBoYXZlIHRvIHByZS1kZWZpbmUgdGhlc2UgdmFsdWVzIGZvciBGRiAoIzEwMjI3KVxyXG5cdFx0SFRNTDogXCJibG9ja1wiLFxyXG5cdFx0Qk9EWTogXCJibG9ja1wiXHJcblx0fTtcclxuXHJcbi8qKlxyXG4gKiBSZXRyaWV2ZSB0aGUgYWN0dWFsIGRpc3BsYXkgb2YgYSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lIG5vZGVOYW1lIG9mIHRoZSBlbGVtZW50XHJcbiAqIEBwYXJhbSB7T2JqZWN0fSBkb2MgRG9jdW1lbnQgb2JqZWN0XHJcbiAqL1xyXG5cclxuLy8gQ2FsbGVkIG9ubHkgZnJvbSB3aXRoaW4gZGVmYXVsdERpc3BsYXlcclxuZnVuY3Rpb24gYWN0dWFsRGlzcGxheSggbmFtZSwgZG9jICkge1xyXG5cdHZhciBlbGVtID0galF1ZXJ5KCBkb2MuY3JlYXRlRWxlbWVudCggbmFtZSApICkuYXBwZW5kVG8oIGRvYy5ib2R5ICksXHJcblxyXG5cdFx0ZGlzcGxheSA9IGpRdWVyeS5jc3MoIGVsZW1bIDAgXSwgXCJkaXNwbGF5XCIgKTtcclxuXHJcblx0Ly8gV2UgZG9uJ3QgaGF2ZSBhbnkgZGF0YSBzdG9yZWQgb24gdGhlIGVsZW1lbnQsXHJcblx0Ly8gc28gdXNlIFwiZGV0YWNoXCIgbWV0aG9kIGFzIGZhc3Qgd2F5IHRvIGdldCByaWQgb2YgdGhlIGVsZW1lbnRcclxuXHRlbGVtLmRldGFjaCgpO1xyXG5cclxuXHRyZXR1cm4gZGlzcGxheTtcclxufVxyXG5cclxuLyoqXHJcbiAqIFRyeSB0byBkZXRlcm1pbmUgdGhlIGRlZmF1bHQgZGlzcGxheSB2YWx1ZSBvZiBhbiBlbGVtZW50XHJcbiAqIEBwYXJhbSB7U3RyaW5nfSBub2RlTmFtZVxyXG4gKi9cclxuZnVuY3Rpb24gZGVmYXVsdERpc3BsYXkoIG5vZGVOYW1lICkge1xyXG5cdHZhciBkb2MgPSBkb2N1bWVudCxcclxuXHRcdGRpc3BsYXkgPSBlbGVtZGlzcGxheVsgbm9kZU5hbWUgXTtcclxuXHJcblx0aWYgKCAhZGlzcGxheSApIHtcclxuXHRcdGRpc3BsYXkgPSBhY3R1YWxEaXNwbGF5KCBub2RlTmFtZSwgZG9jICk7XHJcblxyXG5cdFx0Ly8gSWYgdGhlIHNpbXBsZSB3YXkgZmFpbHMsIHJlYWQgZnJvbSBpbnNpZGUgYW4gaWZyYW1lXHJcblx0XHRpZiAoIGRpc3BsYXkgPT09IFwibm9uZVwiIHx8ICFkaXNwbGF5ICkge1xyXG5cclxuXHRcdFx0Ly8gVXNlIHRoZSBhbHJlYWR5LWNyZWF0ZWQgaWZyYW1lIGlmIHBvc3NpYmxlXHJcblx0XHRcdGlmcmFtZSA9ICggaWZyYW1lIHx8IGpRdWVyeSggXCI8aWZyYW1lIGZyYW1lYm9yZGVyPScwJyB3aWR0aD0nMCcgaGVpZ2h0PScwJy8+XCIgKSApXHJcblx0XHRcdFx0LmFwcGVuZFRvKCBkb2MuZG9jdW1lbnRFbGVtZW50ICk7XHJcblxyXG5cdFx0XHQvLyBBbHdheXMgd3JpdGUgYSBuZXcgSFRNTCBza2VsZXRvbiBzbyBXZWJraXQgYW5kIEZpcmVmb3ggZG9uJ3QgY2hva2Ugb24gcmV1c2VcclxuXHRcdFx0ZG9jID0gaWZyYW1lWyAwIF0uY29udGVudERvY3VtZW50O1xyXG5cclxuXHRcdFx0Ly8gU3VwcG9ydDogSUVcclxuXHRcdFx0ZG9jLndyaXRlKCk7XHJcblx0XHRcdGRvYy5jbG9zZSgpO1xyXG5cclxuXHRcdFx0ZGlzcGxheSA9IGFjdHVhbERpc3BsYXkoIG5vZGVOYW1lLCBkb2MgKTtcclxuXHRcdFx0aWZyYW1lLmRldGFjaCgpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFN0b3JlIHRoZSBjb3JyZWN0IGRlZmF1bHQgZGlzcGxheVxyXG5cdFx0ZWxlbWRpc3BsYXlbIG5vZGVOYW1lIF0gPSBkaXNwbGF5O1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIGRpc3BsYXk7XHJcbn1cclxudmFyIHJtYXJnaW4gPSAoIC9ebWFyZ2luLyApO1xyXG5cclxudmFyIHJudW1ub25weCA9IG5ldyBSZWdFeHAoIFwiXihcIiArIHBudW0gKyBcIikoPyFweClbYS16JV0rJFwiLCBcImlcIiApO1xyXG5cclxudmFyIGdldFN0eWxlcyA9IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cclxuXHRcdC8vIFN1cHBvcnQ6IElFPD0xMSssIEZpcmVmb3g8PTMwKyAoIzE1MDk4LCAjMTQxNTApXHJcblx0XHQvLyBJRSB0aHJvd3Mgb24gZWxlbWVudHMgY3JlYXRlZCBpbiBwb3B1cHNcclxuXHRcdC8vIEZGIG1lYW53aGlsZSB0aHJvd3Mgb24gZnJhbWUgZWxlbWVudHMgdGhyb3VnaCBcImRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGVcIlxyXG5cdFx0dmFyIHZpZXcgPSBlbGVtLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXc7XHJcblxyXG5cdFx0aWYgKCAhdmlldyB8fCAhdmlldy5vcGVuZXIgKSB7XHJcblx0XHRcdHZpZXcgPSB3aW5kb3c7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIHZpZXcuZ2V0Q29tcHV0ZWRTdHlsZSggZWxlbSApO1xyXG5cdH07XHJcblxyXG52YXIgc3dhcCA9IGZ1bmN0aW9uKCBlbGVtLCBvcHRpb25zLCBjYWxsYmFjaywgYXJncyApIHtcclxuXHR2YXIgcmV0LCBuYW1lLFxyXG5cdFx0b2xkID0ge307XHJcblxyXG5cdC8vIFJlbWVtYmVyIHRoZSBvbGQgdmFsdWVzLCBhbmQgaW5zZXJ0IHRoZSBuZXcgb25lc1xyXG5cdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcclxuXHRcdG9sZFsgbmFtZSBdID0gZWxlbS5zdHlsZVsgbmFtZSBdO1xyXG5cdFx0ZWxlbS5zdHlsZVsgbmFtZSBdID0gb3B0aW9uc1sgbmFtZSBdO1xyXG5cdH1cclxuXHJcblx0cmV0ID0gY2FsbGJhY2suYXBwbHkoIGVsZW0sIGFyZ3MgfHwgW10gKTtcclxuXHJcblx0Ly8gUmV2ZXJ0IHRoZSBvbGQgdmFsdWVzXHJcblx0Zm9yICggbmFtZSBpbiBvcHRpb25zICkge1xyXG5cdFx0ZWxlbS5zdHlsZVsgbmFtZSBdID0gb2xkWyBuYW1lIF07XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gcmV0O1xyXG59O1xyXG5cclxuXHJcbnZhciBkb2N1bWVudEVsZW1lbnQgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XHJcblxyXG5cclxuXHJcbiggZnVuY3Rpb24oKSB7XHJcblx0dmFyIHBpeGVsUG9zaXRpb25WYWwsIGJveFNpemluZ1JlbGlhYmxlVmFsLCBwaXhlbE1hcmdpblJpZ2h0VmFsLCByZWxpYWJsZU1hcmdpbkxlZnRWYWwsXHJcblx0XHRjb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICksXHJcblx0XHRkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICk7XHJcblxyXG5cdC8vIEZpbmlzaCBlYXJseSBpbiBsaW1pdGVkIChub24tYnJvd3NlcikgZW52aXJvbm1lbnRzXHJcblx0aWYgKCAhZGl2LnN0eWxlICkge1xyXG5cdFx0cmV0dXJuO1xyXG5cdH1cclxuXHJcblx0Ly8gU3VwcG9ydDogSUU5LTExK1xyXG5cdC8vIFN0eWxlIG9mIGNsb25lZCBlbGVtZW50IGFmZmVjdHMgc291cmNlIGVsZW1lbnQgY2xvbmVkICgjODkwOClcclxuXHRkaXYuc3R5bGUuYmFja2dyb3VuZENsaXAgPSBcImNvbnRlbnQtYm94XCI7XHJcblx0ZGl2LmNsb25lTm9kZSggdHJ1ZSApLnN0eWxlLmJhY2tncm91bmRDbGlwID0gXCJcIjtcclxuXHRzdXBwb3J0LmNsZWFyQ2xvbmVTdHlsZSA9IGRpdi5zdHlsZS5iYWNrZ3JvdW5kQ2xpcCA9PT0gXCJjb250ZW50LWJveFwiO1xyXG5cclxuXHRjb250YWluZXIuc3R5bGUuY3NzVGV4dCA9IFwiYm9yZGVyOjA7d2lkdGg6OHB4O2hlaWdodDowO3RvcDowO2xlZnQ6LTk5OTlweDtcIiArXHJcblx0XHRcInBhZGRpbmc6MDttYXJnaW4tdG9wOjFweDtwb3NpdGlvbjphYnNvbHV0ZVwiO1xyXG5cdGNvbnRhaW5lci5hcHBlbmRDaGlsZCggZGl2ICk7XHJcblxyXG5cdC8vIEV4ZWN1dGluZyBib3RoIHBpeGVsUG9zaXRpb24gJiBib3hTaXppbmdSZWxpYWJsZSB0ZXN0cyByZXF1aXJlIG9ubHkgb25lIGxheW91dFxyXG5cdC8vIHNvIHRoZXkncmUgZXhlY3V0ZWQgYXQgdGhlIHNhbWUgdGltZSB0byBzYXZlIHRoZSBzZWNvbmQgY29tcHV0YXRpb24uXHJcblx0ZnVuY3Rpb24gY29tcHV0ZVN0eWxlVGVzdHMoKSB7XHJcblx0XHRkaXYuc3R5bGUuY3NzVGV4dCA9XHJcblxyXG5cdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94PDI5LCBBbmRyb2lkIDIuM1xyXG5cdFx0XHQvLyBWZW5kb3ItcHJlZml4IGJveC1zaXppbmdcclxuXHRcdFx0XCItd2Via2l0LWJveC1zaXppbmc6Ym9yZGVyLWJveDstbW96LWJveC1zaXppbmc6Ym9yZGVyLWJveDtib3gtc2l6aW5nOmJvcmRlci1ib3g7XCIgK1xyXG5cdFx0XHRcInBvc2l0aW9uOnJlbGF0aXZlO2Rpc3BsYXk6YmxvY2s7XCIgK1xyXG5cdFx0XHRcIm1hcmdpbjphdXRvO2JvcmRlcjoxcHg7cGFkZGluZzoxcHg7XCIgK1xyXG5cdFx0XHRcInRvcDoxJTt3aWR0aDo1MCVcIjtcclxuXHRcdGRpdi5pbm5lckhUTUwgPSBcIlwiO1xyXG5cdFx0ZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKCBjb250YWluZXIgKTtcclxuXHJcblx0XHR2YXIgZGl2U3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSggZGl2ICk7XHJcblx0XHRwaXhlbFBvc2l0aW9uVmFsID0gZGl2U3R5bGUudG9wICE9PSBcIjElXCI7XHJcblx0XHRyZWxpYWJsZU1hcmdpbkxlZnRWYWwgPSBkaXZTdHlsZS5tYXJnaW5MZWZ0ID09PSBcIjJweFwiO1xyXG5cdFx0Ym94U2l6aW5nUmVsaWFibGVWYWwgPSBkaXZTdHlsZS53aWR0aCA9PT0gXCI0cHhcIjtcclxuXHJcblx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDQuMCAtIDQuMyBvbmx5XHJcblx0XHQvLyBTb21lIHN0eWxlcyBjb21lIGJhY2sgd2l0aCBwZXJjZW50YWdlIHZhbHVlcywgZXZlbiB0aG91Z2ggdGhleSBzaG91bGRuJ3RcclxuXHRcdGRpdi5zdHlsZS5tYXJnaW5SaWdodCA9IFwiNTAlXCI7XHJcblx0XHRwaXhlbE1hcmdpblJpZ2h0VmFsID0gZGl2U3R5bGUubWFyZ2luUmlnaHQgPT09IFwiNHB4XCI7XHJcblxyXG5cdFx0ZG9jdW1lbnRFbGVtZW50LnJlbW92ZUNoaWxkKCBjb250YWluZXIgKTtcclxuXHR9XHJcblxyXG5cdGpRdWVyeS5leHRlbmQoIHN1cHBvcnQsIHtcclxuXHRcdHBpeGVsUG9zaXRpb246IGZ1bmN0aW9uKCkge1xyXG5cclxuXHRcdFx0Ly8gVGhpcyB0ZXN0IGlzIGV4ZWN1dGVkIG9ubHkgb25jZSBidXQgd2Ugc3RpbGwgZG8gbWVtb2l6aW5nXHJcblx0XHRcdC8vIHNpbmNlIHdlIGNhbiB1c2UgdGhlIGJveFNpemluZ1JlbGlhYmxlIHByZS1jb21wdXRpbmcuXHJcblx0XHRcdC8vIE5vIG5lZWQgdG8gY2hlY2sgaWYgdGhlIHRlc3Qgd2FzIGFscmVhZHkgcGVyZm9ybWVkLCB0aG91Z2guXHJcblx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XHJcblx0XHRcdHJldHVybiBwaXhlbFBvc2l0aW9uVmFsO1xyXG5cdFx0fSxcclxuXHRcdGJveFNpemluZ1JlbGlhYmxlOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0aWYgKCBib3hTaXppbmdSZWxpYWJsZVZhbCA9PSBudWxsICkge1xyXG5cdFx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIGJveFNpemluZ1JlbGlhYmxlVmFsO1xyXG5cdFx0fSxcclxuXHRcdHBpeGVsTWFyZ2luUmlnaHQ6IGZ1bmN0aW9uKCkge1xyXG5cclxuXHRcdFx0Ly8gU3VwcG9ydDogQW5kcm9pZCA0LjAtNC4zXHJcblx0XHRcdC8vIFdlJ3JlIGNoZWNraW5nIGZvciBib3hTaXppbmdSZWxpYWJsZVZhbCBoZXJlIGluc3RlYWQgb2YgcGl4ZWxNYXJnaW5SaWdodFZhbFxyXG5cdFx0XHQvLyBzaW5jZSB0aGF0IGNvbXByZXNzZXMgYmV0dGVyIGFuZCB0aGV5J3JlIGNvbXB1dGVkIHRvZ2V0aGVyIGFueXdheS5cclxuXHRcdFx0aWYgKCBib3hTaXppbmdSZWxpYWJsZVZhbCA9PSBudWxsICkge1xyXG5cdFx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XHJcblx0XHRcdH1cclxuXHRcdFx0cmV0dXJuIHBpeGVsTWFyZ2luUmlnaHRWYWw7XHJcblx0XHR9LFxyXG5cdFx0cmVsaWFibGVNYXJnaW5MZWZ0OiBmdW5jdGlvbigpIHtcclxuXHJcblx0XHRcdC8vIFN1cHBvcnQ6IElFIDw9OCBvbmx5LCBBbmRyb2lkIDQuMCAtIDQuMyBvbmx5LCBGaXJlZm94IDw9MyAtIDM3XHJcblx0XHRcdGlmICggYm94U2l6aW5nUmVsaWFibGVWYWwgPT0gbnVsbCApIHtcclxuXHRcdFx0XHRjb21wdXRlU3R5bGVUZXN0cygpO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiByZWxpYWJsZU1hcmdpbkxlZnRWYWw7XHJcblx0XHR9LFxyXG5cdFx0cmVsaWFibGVNYXJnaW5SaWdodDogZnVuY3Rpb24oKSB7XHJcblxyXG5cdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDIuM1xyXG5cdFx0XHQvLyBDaGVjayBpZiBkaXYgd2l0aCBleHBsaWNpdCB3aWR0aCBhbmQgbm8gbWFyZ2luLXJpZ2h0IGluY29ycmVjdGx5XHJcblx0XHRcdC8vIGdldHMgY29tcHV0ZWQgbWFyZ2luLXJpZ2h0IGJhc2VkIG9uIHdpZHRoIG9mIGNvbnRhaW5lci4gKCMzMzMzKVxyXG5cdFx0XHQvLyBXZWJLaXQgQnVnIDEzMzQzIC0gZ2V0Q29tcHV0ZWRTdHlsZSByZXR1cm5zIHdyb25nIHZhbHVlIGZvciBtYXJnaW4tcmlnaHRcclxuXHRcdFx0Ly8gVGhpcyBzdXBwb3J0IGZ1bmN0aW9uIGlzIG9ubHkgZXhlY3V0ZWQgb25jZSBzbyBubyBtZW1vaXppbmcgaXMgbmVlZGVkLlxyXG5cdFx0XHR2YXIgcmV0LFxyXG5cdFx0XHRcdG1hcmdpbkRpdiA9IGRpdi5hcHBlbmRDaGlsZCggZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApICk7XHJcblxyXG5cdFx0XHQvLyBSZXNldCBDU1M6IGJveC1zaXppbmc7IGRpc3BsYXk7IG1hcmdpbjsgYm9yZGVyOyBwYWRkaW5nXHJcblx0XHRcdG1hcmdpbkRpdi5zdHlsZS5jc3NUZXh0ID0gZGl2LnN0eWxlLmNzc1RleHQgPVxyXG5cclxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDIuM1xyXG5cdFx0XHRcdC8vIFZlbmRvci1wcmVmaXggYm94LXNpemluZ1xyXG5cdFx0XHRcdFwiLXdlYmtpdC1ib3gtc2l6aW5nOmNvbnRlbnQtYm94O2JveC1zaXppbmc6Y29udGVudC1ib3g7XCIgK1xyXG5cdFx0XHRcdFwiZGlzcGxheTpibG9jazttYXJnaW46MDtib3JkZXI6MDtwYWRkaW5nOjBcIjtcclxuXHRcdFx0bWFyZ2luRGl2LnN0eWxlLm1hcmdpblJpZ2h0ID0gbWFyZ2luRGl2LnN0eWxlLndpZHRoID0gXCIwXCI7XHJcblx0XHRcdGRpdi5zdHlsZS53aWR0aCA9IFwiMXB4XCI7XHJcblx0XHRcdGRvY3VtZW50RWxlbWVudC5hcHBlbmRDaGlsZCggY29udGFpbmVyICk7XHJcblxyXG5cdFx0XHRyZXQgPSAhcGFyc2VGbG9hdCggd2luZG93LmdldENvbXB1dGVkU3R5bGUoIG1hcmdpbkRpdiApLm1hcmdpblJpZ2h0ICk7XHJcblxyXG5cdFx0XHRkb2N1bWVudEVsZW1lbnQucmVtb3ZlQ2hpbGQoIGNvbnRhaW5lciApO1xyXG5cdFx0XHRkaXYucmVtb3ZlQ2hpbGQoIG1hcmdpbkRpdiApO1xyXG5cclxuXHRcdFx0cmV0dXJuIHJldDtcclxuXHRcdH1cclxuXHR9ICk7XHJcbn0gKSgpO1xyXG5cclxuXHJcbmZ1bmN0aW9uIGN1ckNTUyggZWxlbSwgbmFtZSwgY29tcHV0ZWQgKSB7XHJcblx0dmFyIHdpZHRoLCBtaW5XaWR0aCwgbWF4V2lkdGgsIHJldCxcclxuXHRcdHN0eWxlID0gZWxlbS5zdHlsZTtcclxuXHJcblx0Y29tcHV0ZWQgPSBjb21wdXRlZCB8fCBnZXRTdHlsZXMoIGVsZW0gKTtcclxuXHRyZXQgPSBjb21wdXRlZCA/IGNvbXB1dGVkLmdldFByb3BlcnR5VmFsdWUoIG5hbWUgKSB8fCBjb21wdXRlZFsgbmFtZSBdIDogdW5kZWZpbmVkO1xyXG5cclxuXHQvLyBTdXBwb3J0OiBPcGVyYSAxMi4xeCBvbmx5XHJcblx0Ly8gRmFsbCBiYWNrIHRvIHN0eWxlIGV2ZW4gd2l0aG91dCBjb21wdXRlZFxyXG5cdC8vIGNvbXB1dGVkIGlzIHVuZGVmaW5lZCBmb3IgZWxlbXMgb24gZG9jdW1lbnQgZnJhZ21lbnRzXHJcblx0aWYgKCAoIHJldCA9PT0gXCJcIiB8fCByZXQgPT09IHVuZGVmaW5lZCApICYmICFqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApICkge1xyXG5cdFx0cmV0ID0galF1ZXJ5LnN0eWxlKCBlbGVtLCBuYW1lICk7XHJcblx0fVxyXG5cclxuXHQvLyBTdXBwb3J0OiBJRTlcclxuXHQvLyBnZXRQcm9wZXJ0eVZhbHVlIGlzIG9ubHkgbmVlZGVkIGZvciAuY3NzKCdmaWx0ZXInKSAoIzEyNTM3KVxyXG5cdGlmICggY29tcHV0ZWQgKSB7XHJcblxyXG5cdFx0Ly8gQSB0cmlidXRlIHRvIHRoZSBcImF3ZXNvbWUgaGFjayBieSBEZWFuIEVkd2FyZHNcIlxyXG5cdFx0Ly8gQW5kcm9pZCBCcm93c2VyIHJldHVybnMgcGVyY2VudGFnZSBmb3Igc29tZSB2YWx1ZXMsXHJcblx0XHQvLyBidXQgd2lkdGggc2VlbXMgdG8gYmUgcmVsaWFibHkgcGl4ZWxzLlxyXG5cdFx0Ly8gVGhpcyBpcyBhZ2FpbnN0IHRoZSBDU1NPTSBkcmFmdCBzcGVjOlxyXG5cdFx0Ly8gaHR0cDovL2Rldi53My5vcmcvY3Nzd2cvY3Nzb20vI3Jlc29sdmVkLXZhbHVlc1xyXG5cdFx0aWYgKCAhc3VwcG9ydC5waXhlbE1hcmdpblJpZ2h0KCkgJiYgcm51bW5vbnB4LnRlc3QoIHJldCApICYmIHJtYXJnaW4udGVzdCggbmFtZSApICkge1xyXG5cclxuXHRcdFx0Ly8gUmVtZW1iZXIgdGhlIG9yaWdpbmFsIHZhbHVlc1xyXG5cdFx0XHR3aWR0aCA9IHN0eWxlLndpZHRoO1xyXG5cdFx0XHRtaW5XaWR0aCA9IHN0eWxlLm1pbldpZHRoO1xyXG5cdFx0XHRtYXhXaWR0aCA9IHN0eWxlLm1heFdpZHRoO1xyXG5cclxuXHRcdFx0Ly8gUHV0IGluIHRoZSBuZXcgdmFsdWVzIHRvIGdldCBhIGNvbXB1dGVkIHZhbHVlIG91dFxyXG5cdFx0XHRzdHlsZS5taW5XaWR0aCA9IHN0eWxlLm1heFdpZHRoID0gc3R5bGUud2lkdGggPSByZXQ7XHJcblx0XHRcdHJldCA9IGNvbXB1dGVkLndpZHRoO1xyXG5cclxuXHRcdFx0Ly8gUmV2ZXJ0IHRoZSBjaGFuZ2VkIHZhbHVlc1xyXG5cdFx0XHRzdHlsZS53aWR0aCA9IHdpZHRoO1xyXG5cdFx0XHRzdHlsZS5taW5XaWR0aCA9IG1pbldpZHRoO1xyXG5cdFx0XHRzdHlsZS5tYXhXaWR0aCA9IG1heFdpZHRoO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIHJldCAhPT0gdW5kZWZpbmVkID9cclxuXHJcblx0XHQvLyBTdXBwb3J0OiBJRTktMTErXHJcblx0XHQvLyBJRSByZXR1cm5zIHpJbmRleCB2YWx1ZSBhcyBhbiBpbnRlZ2VyLlxyXG5cdFx0cmV0ICsgXCJcIiA6XHJcblx0XHRyZXQ7XHJcbn1cclxuXHJcblxyXG5mdW5jdGlvbiBhZGRHZXRIb29rSWYoIGNvbmRpdGlvbkZuLCBob29rRm4gKSB7XHJcblxyXG5cdC8vIERlZmluZSB0aGUgaG9vaywgd2UnbGwgY2hlY2sgb24gdGhlIGZpcnN0IHJ1biBpZiBpdCdzIHJlYWxseSBuZWVkZWQuXHJcblx0cmV0dXJuIHtcclxuXHRcdGdldDogZnVuY3Rpb24oKSB7XHJcblx0XHRcdGlmICggY29uZGl0aW9uRm4oKSApIHtcclxuXHJcblx0XHRcdFx0Ly8gSG9vayBub3QgbmVlZGVkIChvciBpdCdzIG5vdCBwb3NzaWJsZSB0byB1c2UgaXQgZHVlXHJcblx0XHRcdFx0Ly8gdG8gbWlzc2luZyBkZXBlbmRlbmN5KSwgcmVtb3ZlIGl0LlxyXG5cdFx0XHRcdGRlbGV0ZSB0aGlzLmdldDtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIEhvb2sgbmVlZGVkOyByZWRlZmluZSBpdCBzbyB0aGF0IHRoZSBzdXBwb3J0IHRlc3QgaXMgbm90IGV4ZWN1dGVkIGFnYWluLlxyXG5cdFx0XHRyZXR1cm4gKCB0aGlzLmdldCA9IGhvb2tGbiApLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcclxuXHRcdH1cclxuXHR9O1xyXG59XHJcblxyXG5cclxudmFyXHJcblxyXG5cdC8vIFN3YXBwYWJsZSBpZiBkaXNwbGF5IGlzIG5vbmUgb3Igc3RhcnRzIHdpdGggdGFibGVcclxuXHQvLyBleGNlcHQgXCJ0YWJsZVwiLCBcInRhYmxlLWNlbGxcIiwgb3IgXCJ0YWJsZS1jYXB0aW9uXCJcclxuXHQvLyBTZWUgaGVyZSBmb3IgZGlzcGxheSB2YWx1ZXM6IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvQ1NTL2Rpc3BsYXlcclxuXHRyZGlzcGxheXN3YXAgPSAvXihub25lfHRhYmxlKD8hLWNbZWFdKS4rKS8sXHJcblxyXG5cdGNzc1Nob3cgPSB7IHBvc2l0aW9uOiBcImFic29sdXRlXCIsIHZpc2liaWxpdHk6IFwiaGlkZGVuXCIsIGRpc3BsYXk6IFwiYmxvY2tcIiB9LFxyXG5cdGNzc05vcm1hbFRyYW5zZm9ybSA9IHtcclxuXHRcdGxldHRlclNwYWNpbmc6IFwiMFwiLFxyXG5cdFx0Zm9udFdlaWdodDogXCI0MDBcIlxyXG5cdH0sXHJcblxyXG5cdGNzc1ByZWZpeGVzID0gWyBcIldlYmtpdFwiLCBcIk9cIiwgXCJNb3pcIiwgXCJtc1wiIF0sXHJcblx0ZW1wdHlTdHlsZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKS5zdHlsZTtcclxuXHJcbi8vIFJldHVybiBhIGNzcyBwcm9wZXJ0eSBtYXBwZWQgdG8gYSBwb3RlbnRpYWxseSB2ZW5kb3IgcHJlZml4ZWQgcHJvcGVydHlcclxuZnVuY3Rpb24gdmVuZG9yUHJvcE5hbWUoIG5hbWUgKSB7XHJcblxyXG5cdC8vIFNob3J0Y3V0IGZvciBuYW1lcyB0aGF0IGFyZSBub3QgdmVuZG9yIHByZWZpeGVkXHJcblx0aWYgKCBuYW1lIGluIGVtcHR5U3R5bGUgKSB7XHJcblx0XHRyZXR1cm4gbmFtZTtcclxuXHR9XHJcblxyXG5cdC8vIENoZWNrIGZvciB2ZW5kb3IgcHJlZml4ZWQgbmFtZXNcclxuXHR2YXIgY2FwTmFtZSA9IG5hbWVbIDAgXS50b1VwcGVyQ2FzZSgpICsgbmFtZS5zbGljZSggMSApLFxyXG5cdFx0aSA9IGNzc1ByZWZpeGVzLmxlbmd0aDtcclxuXHJcblx0d2hpbGUgKCBpLS0gKSB7XHJcblx0XHRuYW1lID0gY3NzUHJlZml4ZXNbIGkgXSArIGNhcE5hbWU7XHJcblx0XHRpZiAoIG5hbWUgaW4gZW1wdHlTdHlsZSApIHtcclxuXHRcdFx0cmV0dXJuIG5hbWU7XHJcblx0XHR9XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBzZXRQb3NpdGl2ZU51bWJlciggZWxlbSwgdmFsdWUsIHN1YnRyYWN0ICkge1xyXG5cclxuXHQvLyBBbnkgcmVsYXRpdmUgKCsvLSkgdmFsdWVzIGhhdmUgYWxyZWFkeSBiZWVuXHJcblx0Ly8gbm9ybWFsaXplZCBhdCB0aGlzIHBvaW50XHJcblx0dmFyIG1hdGNoZXMgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICk7XHJcblx0cmV0dXJuIG1hdGNoZXMgP1xyXG5cclxuXHRcdC8vIEd1YXJkIGFnYWluc3QgdW5kZWZpbmVkIFwic3VidHJhY3RcIiwgZS5nLiwgd2hlbiB1c2VkIGFzIGluIGNzc0hvb2tzXHJcblx0XHRNYXRoLm1heCggMCwgbWF0Y2hlc1sgMiBdIC0gKCBzdWJ0cmFjdCB8fCAwICkgKSArICggbWF0Y2hlc1sgMyBdIHx8IFwicHhcIiApIDpcclxuXHRcdHZhbHVlO1xyXG59XHJcblxyXG5mdW5jdGlvbiBhdWdtZW50V2lkdGhPckhlaWdodCggZWxlbSwgbmFtZSwgZXh0cmEsIGlzQm9yZGVyQm94LCBzdHlsZXMgKSB7XHJcblx0dmFyIGkgPSBleHRyYSA9PT0gKCBpc0JvcmRlckJveCA/IFwiYm9yZGVyXCIgOiBcImNvbnRlbnRcIiApID9cclxuXHJcblx0XHQvLyBJZiB3ZSBhbHJlYWR5IGhhdmUgdGhlIHJpZ2h0IG1lYXN1cmVtZW50LCBhdm9pZCBhdWdtZW50YXRpb25cclxuXHRcdDQgOlxyXG5cclxuXHRcdC8vIE90aGVyd2lzZSBpbml0aWFsaXplIGZvciBob3Jpem9udGFsIG9yIHZlcnRpY2FsIHByb3BlcnRpZXNcclxuXHRcdG5hbWUgPT09IFwid2lkdGhcIiA/IDEgOiAwLFxyXG5cclxuXHRcdHZhbCA9IDA7XHJcblxyXG5cdGZvciAoIDsgaSA8IDQ7IGkgKz0gMiApIHtcclxuXHJcblx0XHQvLyBCb3RoIGJveCBtb2RlbHMgZXhjbHVkZSBtYXJnaW4sIHNvIGFkZCBpdCBpZiB3ZSB3YW50IGl0XHJcblx0XHRpZiAoIGV4dHJhID09PSBcIm1hcmdpblwiICkge1xyXG5cdFx0XHR2YWwgKz0galF1ZXJ5LmNzcyggZWxlbSwgZXh0cmEgKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBpc0JvcmRlckJveCApIHtcclxuXHJcblx0XHRcdC8vIGJvcmRlci1ib3ggaW5jbHVkZXMgcGFkZGluZywgc28gcmVtb3ZlIGl0IGlmIHdlIHdhbnQgY29udGVudFxyXG5cdFx0XHRpZiAoIGV4dHJhID09PSBcImNvbnRlbnRcIiApIHtcclxuXHRcdFx0XHR2YWwgLT0galF1ZXJ5LmNzcyggZWxlbSwgXCJwYWRkaW5nXCIgKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIEF0IHRoaXMgcG9pbnQsIGV4dHJhIGlzbid0IGJvcmRlciBub3IgbWFyZ2luLCBzbyByZW1vdmUgYm9yZGVyXHJcblx0XHRcdGlmICggZXh0cmEgIT09IFwibWFyZ2luXCIgKSB7XHJcblx0XHRcdFx0dmFsIC09IGpRdWVyeS5jc3MoIGVsZW0sIFwiYm9yZGVyXCIgKyBjc3NFeHBhbmRbIGkgXSArIFwiV2lkdGhcIiwgdHJ1ZSwgc3R5bGVzICk7XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSB7XHJcblxyXG5cdFx0XHQvLyBBdCB0aGlzIHBvaW50LCBleHRyYSBpc24ndCBjb250ZW50LCBzbyBhZGQgcGFkZGluZ1xyXG5cdFx0XHR2YWwgKz0galF1ZXJ5LmNzcyggZWxlbSwgXCJwYWRkaW5nXCIgKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7XHJcblxyXG5cdFx0XHQvLyBBdCB0aGlzIHBvaW50LCBleHRyYSBpc24ndCBjb250ZW50IG5vciBwYWRkaW5nLCBzbyBhZGQgYm9yZGVyXHJcblx0XHRcdGlmICggZXh0cmEgIT09IFwicGFkZGluZ1wiICkge1xyXG5cdFx0XHRcdHZhbCArPSBqUXVlcnkuY3NzKCBlbGVtLCBcImJvcmRlclwiICsgY3NzRXhwYW5kWyBpIF0gKyBcIldpZHRoXCIsIHRydWUsIHN0eWxlcyApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gdmFsO1xyXG59XHJcblxyXG5mdW5jdGlvbiBnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBuYW1lLCBleHRyYSApIHtcclxuXHJcblx0Ly8gU3RhcnQgd2l0aCBvZmZzZXQgcHJvcGVydHksIHdoaWNoIGlzIGVxdWl2YWxlbnQgdG8gdGhlIGJvcmRlci1ib3ggdmFsdWVcclxuXHR2YXIgdmFsdWVJc0JvcmRlckJveCA9IHRydWUsXHJcblx0XHR2YWwgPSBuYW1lID09PSBcIndpZHRoXCIgPyBlbGVtLm9mZnNldFdpZHRoIDogZWxlbS5vZmZzZXRIZWlnaHQsXHJcblx0XHRzdHlsZXMgPSBnZXRTdHlsZXMoIGVsZW0gKSxcclxuXHRcdGlzQm9yZGVyQm94ID0galF1ZXJ5LmNzcyggZWxlbSwgXCJib3hTaXppbmdcIiwgZmFsc2UsIHN0eWxlcyApID09PSBcImJvcmRlci1ib3hcIjtcclxuXHJcblx0Ly8gU29tZSBub24taHRtbCBlbGVtZW50cyByZXR1cm4gdW5kZWZpbmVkIGZvciBvZmZzZXRXaWR0aCwgc28gY2hlY2sgZm9yIG51bGwvdW5kZWZpbmVkXHJcblx0Ly8gc3ZnIC0gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9NjQ5Mjg1XHJcblx0Ly8gTWF0aE1MIC0gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9NDkxNjY4XHJcblx0aWYgKCB2YWwgPD0gMCB8fCB2YWwgPT0gbnVsbCApIHtcclxuXHJcblx0XHQvLyBGYWxsIGJhY2sgdG8gY29tcHV0ZWQgdGhlbiB1bmNvbXB1dGVkIGNzcyBpZiBuZWNlc3NhcnlcclxuXHRcdHZhbCA9IGN1ckNTUyggZWxlbSwgbmFtZSwgc3R5bGVzICk7XHJcblx0XHRpZiAoIHZhbCA8IDAgfHwgdmFsID09IG51bGwgKSB7XHJcblx0XHRcdHZhbCA9IGVsZW0uc3R5bGVbIG5hbWUgXTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBDb21wdXRlZCB1bml0IGlzIG5vdCBwaXhlbHMuIFN0b3AgaGVyZSBhbmQgcmV0dXJuLlxyXG5cdFx0aWYgKCBybnVtbm9ucHgudGVzdCggdmFsICkgKSB7XHJcblx0XHRcdHJldHVybiB2YWw7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ2hlY2sgZm9yIHN0eWxlIGluIGNhc2UgYSBicm93c2VyIHdoaWNoIHJldHVybnMgdW5yZWxpYWJsZSB2YWx1ZXNcclxuXHRcdC8vIGZvciBnZXRDb21wdXRlZFN0eWxlIHNpbGVudGx5IGZhbGxzIGJhY2sgdG8gdGhlIHJlbGlhYmxlIGVsZW0uc3R5bGVcclxuXHRcdHZhbHVlSXNCb3JkZXJCb3ggPSBpc0JvcmRlckJveCAmJlxyXG5cdFx0XHQoIHN1cHBvcnQuYm94U2l6aW5nUmVsaWFibGUoKSB8fCB2YWwgPT09IGVsZW0uc3R5bGVbIG5hbWUgXSApO1xyXG5cclxuXHRcdC8vIE5vcm1hbGl6ZSBcIlwiLCBhdXRvLCBhbmQgcHJlcGFyZSBmb3IgZXh0cmFcclxuXHRcdHZhbCA9IHBhcnNlRmxvYXQoIHZhbCApIHx8IDA7XHJcblx0fVxyXG5cclxuXHQvLyBVc2UgdGhlIGFjdGl2ZSBib3gtc2l6aW5nIG1vZGVsIHRvIGFkZC9zdWJ0cmFjdCBpcnJlbGV2YW50IHN0eWxlc1xyXG5cdHJldHVybiAoIHZhbCArXHJcblx0XHRhdWdtZW50V2lkdGhPckhlaWdodChcclxuXHRcdFx0ZWxlbSxcclxuXHRcdFx0bmFtZSxcclxuXHRcdFx0ZXh0cmEgfHwgKCBpc0JvcmRlckJveCA/IFwiYm9yZGVyXCIgOiBcImNvbnRlbnRcIiApLFxyXG5cdFx0XHR2YWx1ZUlzQm9yZGVyQm94LFxyXG5cdFx0XHRzdHlsZXNcclxuXHRcdClcclxuXHQpICsgXCJweFwiO1xyXG59XHJcblxyXG5mdW5jdGlvbiBzaG93SGlkZSggZWxlbWVudHMsIHNob3cgKSB7XHJcblx0dmFyIGRpc3BsYXksIGVsZW0sIGhpZGRlbixcclxuXHRcdHZhbHVlcyA9IFtdLFxyXG5cdFx0aW5kZXggPSAwLFxyXG5cdFx0bGVuZ3RoID0gZWxlbWVudHMubGVuZ3RoO1xyXG5cclxuXHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xyXG5cdFx0ZWxlbSA9IGVsZW1lbnRzWyBpbmRleCBdO1xyXG5cdFx0aWYgKCAhZWxlbS5zdHlsZSApIHtcclxuXHRcdFx0Y29udGludWU7XHJcblx0XHR9XHJcblxyXG5cdFx0dmFsdWVzWyBpbmRleCBdID0gZGF0YVByaXYuZ2V0KCBlbGVtLCBcIm9sZGRpc3BsYXlcIiApO1xyXG5cdFx0ZGlzcGxheSA9IGVsZW0uc3R5bGUuZGlzcGxheTtcclxuXHRcdGlmICggc2hvdyApIHtcclxuXHJcblx0XHRcdC8vIFJlc2V0IHRoZSBpbmxpbmUgZGlzcGxheSBvZiB0aGlzIGVsZW1lbnQgdG8gbGVhcm4gaWYgaXQgaXNcclxuXHRcdFx0Ly8gYmVpbmcgaGlkZGVuIGJ5IGNhc2NhZGVkIHJ1bGVzIG9yIG5vdFxyXG5cdFx0XHRpZiAoICF2YWx1ZXNbIGluZGV4IF0gJiYgZGlzcGxheSA9PT0gXCJub25lXCIgKSB7XHJcblx0XHRcdFx0ZWxlbS5zdHlsZS5kaXNwbGF5ID0gXCJcIjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gU2V0IGVsZW1lbnRzIHdoaWNoIGhhdmUgYmVlbiBvdmVycmlkZGVuIHdpdGggZGlzcGxheTogbm9uZVxyXG5cdFx0XHQvLyBpbiBhIHN0eWxlc2hlZXQgdG8gd2hhdGV2ZXIgdGhlIGRlZmF1bHQgYnJvd3NlciBzdHlsZSBpc1xyXG5cdFx0XHQvLyBmb3Igc3VjaCBhbiBlbGVtZW50XHJcblx0XHRcdGlmICggZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIlwiICYmIGlzSGlkZGVuKCBlbGVtICkgKSB7XHJcblx0XHRcdFx0dmFsdWVzWyBpbmRleCBdID0gZGF0YVByaXYuYWNjZXNzKFxyXG5cdFx0XHRcdFx0ZWxlbSxcclxuXHRcdFx0XHRcdFwib2xkZGlzcGxheVwiLFxyXG5cdFx0XHRcdFx0ZGVmYXVsdERpc3BsYXkoIGVsZW0ubm9kZU5hbWUgKVxyXG5cdFx0XHRcdCk7XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGhpZGRlbiA9IGlzSGlkZGVuKCBlbGVtICk7XHJcblxyXG5cdFx0XHRpZiAoIGRpc3BsYXkgIT09IFwibm9uZVwiIHx8ICFoaWRkZW4gKSB7XHJcblx0XHRcdFx0ZGF0YVByaXYuc2V0KFxyXG5cdFx0XHRcdFx0ZWxlbSxcclxuXHRcdFx0XHRcdFwib2xkZGlzcGxheVwiLFxyXG5cdFx0XHRcdFx0aGlkZGVuID8gZGlzcGxheSA6IGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiIClcclxuXHRcdFx0XHQpO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyBTZXQgdGhlIGRpc3BsYXkgb2YgbW9zdCBvZiB0aGUgZWxlbWVudHMgaW4gYSBzZWNvbmQgbG9vcFxyXG5cdC8vIHRvIGF2b2lkIHRoZSBjb25zdGFudCByZWZsb3dcclxuXHRmb3IgKCBpbmRleCA9IDA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xyXG5cdFx0ZWxlbSA9IGVsZW1lbnRzWyBpbmRleCBdO1xyXG5cdFx0aWYgKCAhZWxlbS5zdHlsZSApIHtcclxuXHRcdFx0Y29udGludWU7XHJcblx0XHR9XHJcblx0XHRpZiAoICFzaG93IHx8IGVsZW0uc3R5bGUuZGlzcGxheSA9PT0gXCJub25lXCIgfHwgZWxlbS5zdHlsZS5kaXNwbGF5ID09PSBcIlwiICkge1xyXG5cdFx0XHRlbGVtLnN0eWxlLmRpc3BsYXkgPSBzaG93ID8gdmFsdWVzWyBpbmRleCBdIHx8IFwiXCIgOiBcIm5vbmVcIjtcclxuXHRcdH1cclxuXHR9XHJcblxyXG5cdHJldHVybiBlbGVtZW50cztcclxufVxyXG5cclxualF1ZXJ5LmV4dGVuZCgge1xyXG5cclxuXHQvLyBBZGQgaW4gc3R5bGUgcHJvcGVydHkgaG9va3MgZm9yIG92ZXJyaWRpbmcgdGhlIGRlZmF1bHRcclxuXHQvLyBiZWhhdmlvciBvZiBnZXR0aW5nIGFuZCBzZXR0aW5nIGEgc3R5bGUgcHJvcGVydHlcclxuXHRjc3NIb29rczoge1xyXG5cdFx0b3BhY2l0eToge1xyXG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcclxuXHRcdFx0XHRpZiAoIGNvbXB1dGVkICkge1xyXG5cclxuXHRcdFx0XHRcdC8vIFdlIHNob3VsZCBhbHdheXMgZ2V0IGEgbnVtYmVyIGJhY2sgZnJvbSBvcGFjaXR5XHJcblx0XHRcdFx0XHR2YXIgcmV0ID0gY3VyQ1NTKCBlbGVtLCBcIm9wYWNpdHlcIiApO1xyXG5cdFx0XHRcdFx0cmV0dXJuIHJldCA9PT0gXCJcIiA/IFwiMVwiIDogcmV0O1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8vIERvbid0IGF1dG9tYXRpY2FsbHkgYWRkIFwicHhcIiB0byB0aGVzZSBwb3NzaWJseS11bml0bGVzcyBwcm9wZXJ0aWVzXHJcblx0Y3NzTnVtYmVyOiB7XHJcblx0XHRcImFuaW1hdGlvbkl0ZXJhdGlvbkNvdW50XCI6IHRydWUsXHJcblx0XHRcImNvbHVtbkNvdW50XCI6IHRydWUsXHJcblx0XHRcImZpbGxPcGFjaXR5XCI6IHRydWUsXHJcblx0XHRcImZsZXhHcm93XCI6IHRydWUsXHJcblx0XHRcImZsZXhTaHJpbmtcIjogdHJ1ZSxcclxuXHRcdFwiZm9udFdlaWdodFwiOiB0cnVlLFxyXG5cdFx0XCJsaW5lSGVpZ2h0XCI6IHRydWUsXHJcblx0XHRcIm9wYWNpdHlcIjogdHJ1ZSxcclxuXHRcdFwib3JkZXJcIjogdHJ1ZSxcclxuXHRcdFwib3JwaGFuc1wiOiB0cnVlLFxyXG5cdFx0XCJ3aWRvd3NcIjogdHJ1ZSxcclxuXHRcdFwiekluZGV4XCI6IHRydWUsXHJcblx0XHRcInpvb21cIjogdHJ1ZVxyXG5cdH0sXHJcblxyXG5cdC8vIEFkZCBpbiBwcm9wZXJ0aWVzIHdob3NlIG5hbWVzIHlvdSB3aXNoIHRvIGZpeCBiZWZvcmVcclxuXHQvLyBzZXR0aW5nIG9yIGdldHRpbmcgdGhlIHZhbHVlXHJcblx0Y3NzUHJvcHM6IHtcclxuXHRcdFwiZmxvYXRcIjogXCJjc3NGbG9hdFwiXHJcblx0fSxcclxuXHJcblx0Ly8gR2V0IGFuZCBzZXQgdGhlIHN0eWxlIHByb3BlcnR5IG9uIGEgRE9NIE5vZGVcclxuXHRzdHlsZTogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlLCBleHRyYSApIHtcclxuXHJcblx0XHQvLyBEb24ndCBzZXQgc3R5bGVzIG9uIHRleHQgYW5kIGNvbW1lbnQgbm9kZXNcclxuXHRcdGlmICggIWVsZW0gfHwgZWxlbS5ub2RlVHlwZSA9PT0gMyB8fCBlbGVtLm5vZGVUeXBlID09PSA4IHx8ICFlbGVtLnN0eWxlICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gTWFrZSBzdXJlIHRoYXQgd2UncmUgd29ya2luZyB3aXRoIHRoZSByaWdodCBuYW1lXHJcblx0XHR2YXIgcmV0LCB0eXBlLCBob29rcyxcclxuXHRcdFx0b3JpZ05hbWUgPSBqUXVlcnkuY2FtZWxDYXNlKCBuYW1lICksXHJcblx0XHRcdHN0eWxlID0gZWxlbS5zdHlsZTtcclxuXHJcblx0XHRuYW1lID0galF1ZXJ5LmNzc1Byb3BzWyBvcmlnTmFtZSBdIHx8XHJcblx0XHRcdCggalF1ZXJ5LmNzc1Byb3BzWyBvcmlnTmFtZSBdID0gdmVuZG9yUHJvcE5hbWUoIG9yaWdOYW1lICkgfHwgb3JpZ05hbWUgKTtcclxuXHJcblx0XHQvLyBHZXRzIGhvb2sgZm9yIHRoZSBwcmVmaXhlZCB2ZXJzaW9uLCB0aGVuIHVucHJlZml4ZWQgdmVyc2lvblxyXG5cdFx0aG9va3MgPSBqUXVlcnkuY3NzSG9va3NbIG5hbWUgXSB8fCBqUXVlcnkuY3NzSG9va3NbIG9yaWdOYW1lIF07XHJcblxyXG5cdFx0Ly8gQ2hlY2sgaWYgd2UncmUgc2V0dGluZyBhIHZhbHVlXHJcblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdHR5cGUgPSB0eXBlb2YgdmFsdWU7XHJcblxyXG5cdFx0XHQvLyBDb252ZXJ0IFwiKz1cIiBvciBcIi09XCIgdG8gcmVsYXRpdmUgbnVtYmVycyAoIzczNDUpXHJcblx0XHRcdGlmICggdHlwZSA9PT0gXCJzdHJpbmdcIiAmJiAoIHJldCA9IHJjc3NOdW0uZXhlYyggdmFsdWUgKSApICYmIHJldFsgMSBdICkge1xyXG5cdFx0XHRcdHZhbHVlID0gYWRqdXN0Q1NTKCBlbGVtLCBuYW1lLCByZXQgKTtcclxuXHJcblx0XHRcdFx0Ly8gRml4ZXMgYnVnICM5MjM3XHJcblx0XHRcdFx0dHlwZSA9IFwibnVtYmVyXCI7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIE1ha2Ugc3VyZSB0aGF0IG51bGwgYW5kIE5hTiB2YWx1ZXMgYXJlbid0IHNldCAoIzcxMTYpXHJcblx0XHRcdGlmICggdmFsdWUgPT0gbnVsbCB8fCB2YWx1ZSAhPT0gdmFsdWUgKSB7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBJZiBhIG51bWJlciB3YXMgcGFzc2VkIGluLCBhZGQgdGhlIHVuaXQgKGV4Y2VwdCBmb3IgY2VydGFpbiBDU1MgcHJvcGVydGllcylcclxuXHRcdFx0aWYgKCB0eXBlID09PSBcIm51bWJlclwiICkge1xyXG5cdFx0XHRcdHZhbHVlICs9IHJldCAmJiByZXRbIDMgXSB8fCAoIGpRdWVyeS5jc3NOdW1iZXJbIG9yaWdOYW1lIF0gPyBcIlwiIDogXCJweFwiICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFN1cHBvcnQ6IElFOS0xMStcclxuXHRcdFx0Ly8gYmFja2dyb3VuZC0qIHByb3BzIGFmZmVjdCBvcmlnaW5hbCBjbG9uZSdzIHZhbHVlc1xyXG5cdFx0XHRpZiAoICFzdXBwb3J0LmNsZWFyQ2xvbmVTdHlsZSAmJiB2YWx1ZSA9PT0gXCJcIiAmJiBuYW1lLmluZGV4T2YoIFwiYmFja2dyb3VuZFwiICkgPT09IDAgKSB7XHJcblx0XHRcdFx0c3R5bGVbIG5hbWUgXSA9IFwiaW5oZXJpdFwiO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBJZiBhIGhvb2sgd2FzIHByb3ZpZGVkLCB1c2UgdGhhdCB2YWx1ZSwgb3RoZXJ3aXNlIGp1c3Qgc2V0IHRoZSBzcGVjaWZpZWQgdmFsdWVcclxuXHRcdFx0aWYgKCAhaG9va3MgfHwgISggXCJzZXRcIiBpbiBob29rcyApIHx8XHJcblx0XHRcdFx0KCB2YWx1ZSA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIGV4dHJhICkgKSAhPT0gdW5kZWZpbmVkICkge1xyXG5cclxuXHRcdFx0XHRzdHlsZVsgbmFtZSBdID0gdmFsdWU7XHJcblx0XHRcdH1cclxuXHJcblx0XHR9IGVsc2Uge1xyXG5cclxuXHRcdFx0Ly8gSWYgYSBob29rIHdhcyBwcm92aWRlZCBnZXQgdGhlIG5vbi1jb21wdXRlZCB2YWx1ZSBmcm9tIHRoZXJlXHJcblx0XHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJlxyXG5cdFx0XHRcdCggcmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBmYWxzZSwgZXh0cmEgKSApICE9PSB1bmRlZmluZWQgKSB7XHJcblxyXG5cdFx0XHRcdHJldHVybiByZXQ7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIE90aGVyd2lzZSBqdXN0IGdldCB0aGUgdmFsdWUgZnJvbSB0aGUgc3R5bGUgb2JqZWN0XHJcblx0XHRcdHJldHVybiBzdHlsZVsgbmFtZSBdO1xyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdGNzczogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGV4dHJhLCBzdHlsZXMgKSB7XHJcblx0XHR2YXIgdmFsLCBudW0sIGhvb2tzLFxyXG5cdFx0XHRvcmlnTmFtZSA9IGpRdWVyeS5jYW1lbENhc2UoIG5hbWUgKTtcclxuXHJcblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWVcclxuXHRcdG5hbWUgPSBqUXVlcnkuY3NzUHJvcHNbIG9yaWdOYW1lIF0gfHxcclxuXHRcdFx0KCBqUXVlcnkuY3NzUHJvcHNbIG9yaWdOYW1lIF0gPSB2ZW5kb3JQcm9wTmFtZSggb3JpZ05hbWUgKSB8fCBvcmlnTmFtZSApO1xyXG5cclxuXHRcdC8vIFRyeSBwcmVmaXhlZCBuYW1lIGZvbGxvd2VkIGJ5IHRoZSB1bnByZWZpeGVkIG5hbWVcclxuXHRcdGhvb2tzID0galF1ZXJ5LmNzc0hvb2tzWyBuYW1lIF0gfHwgalF1ZXJ5LmNzc0hvb2tzWyBvcmlnTmFtZSBdO1xyXG5cclxuXHRcdC8vIElmIGEgaG9vayB3YXMgcHJvdmlkZWQgZ2V0IHRoZSBjb21wdXRlZCB2YWx1ZSBmcm9tIHRoZXJlXHJcblx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgKSB7XHJcblx0XHRcdHZhbCA9IGhvb2tzLmdldCggZWxlbSwgdHJ1ZSwgZXh0cmEgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBPdGhlcndpc2UsIGlmIGEgd2F5IHRvIGdldCB0aGUgY29tcHV0ZWQgdmFsdWUgZXhpc3RzLCB1c2UgdGhhdFxyXG5cdFx0aWYgKCB2YWwgPT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0dmFsID0gY3VyQ1NTKCBlbGVtLCBuYW1lLCBzdHlsZXMgKTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBDb252ZXJ0IFwibm9ybWFsXCIgdG8gY29tcHV0ZWQgdmFsdWVcclxuXHRcdGlmICggdmFsID09PSBcIm5vcm1hbFwiICYmIG5hbWUgaW4gY3NzTm9ybWFsVHJhbnNmb3JtICkge1xyXG5cdFx0XHR2YWwgPSBjc3NOb3JtYWxUcmFuc2Zvcm1bIG5hbWUgXTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBNYWtlIG51bWVyaWMgaWYgZm9yY2VkIG9yIGEgcXVhbGlmaWVyIHdhcyBwcm92aWRlZCBhbmQgdmFsIGxvb2tzIG51bWVyaWNcclxuXHRcdGlmICggZXh0cmEgPT09IFwiXCIgfHwgZXh0cmEgKSB7XHJcblx0XHRcdG51bSA9IHBhcnNlRmxvYXQoIHZhbCApO1xyXG5cdFx0XHRyZXR1cm4gZXh0cmEgPT09IHRydWUgfHwgaXNGaW5pdGUoIG51bSApID8gbnVtIHx8IDAgOiB2YWw7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gdmFsO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmVhY2goIFsgXCJoZWlnaHRcIiwgXCJ3aWR0aFwiIF0sIGZ1bmN0aW9uKCBpLCBuYW1lICkge1xyXG5cdGpRdWVyeS5jc3NIb29rc1sgbmFtZSBdID0ge1xyXG5cdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQsIGV4dHJhICkge1xyXG5cdFx0XHRpZiAoIGNvbXB1dGVkICkge1xyXG5cclxuXHRcdFx0XHQvLyBDZXJ0YWluIGVsZW1lbnRzIGNhbiBoYXZlIGRpbWVuc2lvbiBpbmZvIGlmIHdlIGludmlzaWJseSBzaG93IHRoZW1cclxuXHRcdFx0XHQvLyBidXQgaXQgbXVzdCBoYXZlIGEgY3VycmVudCBkaXNwbGF5IHN0eWxlIHRoYXQgd291bGQgYmVuZWZpdFxyXG5cdFx0XHRcdHJldHVybiByZGlzcGxheXN3YXAudGVzdCggalF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKSApICYmXHJcblx0XHRcdFx0XHRlbGVtLm9mZnNldFdpZHRoID09PSAwID9cclxuXHRcdFx0XHRcdFx0c3dhcCggZWxlbSwgY3NzU2hvdywgZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0XHRcdFx0cmV0dXJuIGdldFdpZHRoT3JIZWlnaHQoIGVsZW0sIG5hbWUsIGV4dHJhICk7XHJcblx0XHRcdFx0XHRcdH0gKSA6XHJcblx0XHRcdFx0XHRcdGdldFdpZHRoT3JIZWlnaHQoIGVsZW0sIG5hbWUsIGV4dHJhICk7XHJcblx0XHRcdH1cclxuXHRcdH0sXHJcblxyXG5cdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUsIGV4dHJhICkge1xyXG5cdFx0XHR2YXIgbWF0Y2hlcyxcclxuXHRcdFx0XHRzdHlsZXMgPSBleHRyYSAmJiBnZXRTdHlsZXMoIGVsZW0gKSxcclxuXHRcdFx0XHRzdWJ0cmFjdCA9IGV4dHJhICYmIGF1Z21lbnRXaWR0aE9ySGVpZ2h0KFxyXG5cdFx0XHRcdFx0ZWxlbSxcclxuXHRcdFx0XHRcdG5hbWUsXHJcblx0XHRcdFx0XHRleHRyYSxcclxuXHRcdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIFwiYm94U2l6aW5nXCIsIGZhbHNlLCBzdHlsZXMgKSA9PT0gXCJib3JkZXItYm94XCIsXHJcblx0XHRcdFx0XHRzdHlsZXNcclxuXHRcdFx0XHQpO1xyXG5cclxuXHRcdFx0Ly8gQ29udmVydCB0byBwaXhlbHMgaWYgdmFsdWUgYWRqdXN0bWVudCBpcyBuZWVkZWRcclxuXHRcdFx0aWYgKCBzdWJ0cmFjdCAmJiAoIG1hdGNoZXMgPSByY3NzTnVtLmV4ZWMoIHZhbHVlICkgKSAmJlxyXG5cdFx0XHRcdCggbWF0Y2hlc1sgMyBdIHx8IFwicHhcIiApICE9PSBcInB4XCIgKSB7XHJcblxyXG5cdFx0XHRcdGVsZW0uc3R5bGVbIG5hbWUgXSA9IHZhbHVlO1xyXG5cdFx0XHRcdHZhbHVlID0galF1ZXJ5LmNzcyggZWxlbSwgbmFtZSApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gc2V0UG9zaXRpdmVOdW1iZXIoIGVsZW0sIHZhbHVlLCBzdWJ0cmFjdCApO1xyXG5cdFx0fVxyXG5cdH07XHJcbn0gKTtcclxuXHJcbmpRdWVyeS5jc3NIb29rcy5tYXJnaW5MZWZ0ID0gYWRkR2V0SG9va0lmKCBzdXBwb3J0LnJlbGlhYmxlTWFyZ2luTGVmdCxcclxuXHRmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XHJcblx0XHRpZiAoIGNvbXB1dGVkICkge1xyXG5cdFx0XHRyZXR1cm4gKCBwYXJzZUZsb2F0KCBjdXJDU1MoIGVsZW0sIFwibWFyZ2luTGVmdFwiICkgKSB8fFxyXG5cdFx0XHRcdGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkubGVmdCAtXHJcblx0XHRcdFx0XHRzd2FwKCBlbGVtLCB7IG1hcmdpbkxlZnQ6IDAgfSwgZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0XHRcdHJldHVybiBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQ7XHJcblx0XHRcdFx0XHR9IClcclxuXHRcdFx0XHQpICsgXCJweFwiO1xyXG5cdFx0fVxyXG5cdH1cclxuKTtcclxuXHJcbi8vIFN1cHBvcnQ6IEFuZHJvaWQgMi4zXHJcbmpRdWVyeS5jc3NIb29rcy5tYXJnaW5SaWdodCA9IGFkZEdldEhvb2tJZiggc3VwcG9ydC5yZWxpYWJsZU1hcmdpblJpZ2h0LFxyXG5cdGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcclxuXHRcdGlmICggY29tcHV0ZWQgKSB7XHJcblx0XHRcdHJldHVybiBzd2FwKCBlbGVtLCB7IFwiZGlzcGxheVwiOiBcImlubGluZS1ibG9ja1wiIH0sXHJcblx0XHRcdFx0Y3VyQ1NTLCBbIGVsZW0sIFwibWFyZ2luUmlnaHRcIiBdICk7XHJcblx0XHR9XHJcblx0fVxyXG4pO1xyXG5cclxuLy8gVGhlc2UgaG9va3MgYXJlIHVzZWQgYnkgYW5pbWF0ZSB0byBleHBhbmQgcHJvcGVydGllc1xyXG5qUXVlcnkuZWFjaCgge1xyXG5cdG1hcmdpbjogXCJcIixcclxuXHRwYWRkaW5nOiBcIlwiLFxyXG5cdGJvcmRlcjogXCJXaWR0aFwiXHJcbn0sIGZ1bmN0aW9uKCBwcmVmaXgsIHN1ZmZpeCApIHtcclxuXHRqUXVlcnkuY3NzSG9va3NbIHByZWZpeCArIHN1ZmZpeCBdID0ge1xyXG5cdFx0ZXhwYW5kOiBmdW5jdGlvbiggdmFsdWUgKSB7XHJcblx0XHRcdHZhciBpID0gMCxcclxuXHRcdFx0XHRleHBhbmRlZCA9IHt9LFxyXG5cclxuXHRcdFx0XHQvLyBBc3N1bWVzIGEgc2luZ2xlIG51bWJlciBpZiBub3QgYSBzdHJpbmdcclxuXHRcdFx0XHRwYXJ0cyA9IHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiA/IHZhbHVlLnNwbGl0KCBcIiBcIiApIDogWyB2YWx1ZSBdO1xyXG5cclxuXHRcdFx0Zm9yICggOyBpIDwgNDsgaSsrICkge1xyXG5cdFx0XHRcdGV4cGFuZGVkWyBwcmVmaXggKyBjc3NFeHBhbmRbIGkgXSArIHN1ZmZpeCBdID1cclxuXHRcdFx0XHRcdHBhcnRzWyBpIF0gfHwgcGFydHNbIGkgLSAyIF0gfHwgcGFydHNbIDAgXTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIGV4cGFuZGVkO1xyXG5cdFx0fVxyXG5cdH07XHJcblxyXG5cdGlmICggIXJtYXJnaW4udGVzdCggcHJlZml4ICkgKSB7XHJcblx0XHRqUXVlcnkuY3NzSG9va3NbIHByZWZpeCArIHN1ZmZpeCBdLnNldCA9IHNldFBvc2l0aXZlTnVtYmVyO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdGNzczogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xyXG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkge1xyXG5cdFx0XHR2YXIgc3R5bGVzLCBsZW4sXHJcblx0XHRcdFx0bWFwID0ge30sXHJcblx0XHRcdFx0aSA9IDA7XHJcblxyXG5cdFx0XHRpZiAoIGpRdWVyeS5pc0FycmF5KCBuYW1lICkgKSB7XHJcblx0XHRcdFx0c3R5bGVzID0gZ2V0U3R5bGVzKCBlbGVtICk7XHJcblx0XHRcdFx0bGVuID0gbmFtZS5sZW5ndGg7XHJcblxyXG5cdFx0XHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xyXG5cdFx0XHRcdFx0bWFwWyBuYW1lWyBpIF0gXSA9IGpRdWVyeS5jc3MoIGVsZW0sIG5hbWVbIGkgXSwgZmFsc2UsIHN0eWxlcyApO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0cmV0dXJuIG1hcDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIHZhbHVlICE9PSB1bmRlZmluZWQgP1xyXG5cdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgbmFtZSwgdmFsdWUgKSA6XHJcblx0XHRcdFx0alF1ZXJ5LmNzcyggZWxlbSwgbmFtZSApO1xyXG5cdFx0fSwgbmFtZSwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxICk7XHJcblx0fSxcclxuXHRzaG93OiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiBzaG93SGlkZSggdGhpcywgdHJ1ZSApO1xyXG5cdH0sXHJcblx0aGlkZTogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4gc2hvd0hpZGUoIHRoaXMgKTtcclxuXHR9LFxyXG5cdHRvZ2dsZTogZnVuY3Rpb24oIHN0YXRlICkge1xyXG5cdFx0aWYgKCB0eXBlb2Ygc3RhdGUgPT09IFwiYm9vbGVhblwiICkge1xyXG5cdFx0XHRyZXR1cm4gc3RhdGUgPyB0aGlzLnNob3coKSA6IHRoaXMuaGlkZSgpO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRpZiAoIGlzSGlkZGVuKCB0aGlzICkgKSB7XHJcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkuc2hvdygpO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLmhpZGUoKTtcclxuXHRcdFx0fVxyXG5cdFx0fSApO1xyXG5cdH1cclxufSApO1xyXG5cclxuXHJcbmZ1bmN0aW9uIFR3ZWVuKCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZyApIHtcclxuXHRyZXR1cm4gbmV3IFR3ZWVuLnByb3RvdHlwZS5pbml0KCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZyApO1xyXG59XHJcbmpRdWVyeS5Ud2VlbiA9IFR3ZWVuO1xyXG5cclxuVHdlZW4ucHJvdG90eXBlID0ge1xyXG5cdGNvbnN0cnVjdG9yOiBUd2VlbixcclxuXHRpbml0OiBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgcHJvcCwgZW5kLCBlYXNpbmcsIHVuaXQgKSB7XHJcblx0XHR0aGlzLmVsZW0gPSBlbGVtO1xyXG5cdFx0dGhpcy5wcm9wID0gcHJvcDtcclxuXHRcdHRoaXMuZWFzaW5nID0gZWFzaW5nIHx8IGpRdWVyeS5lYXNpbmcuX2RlZmF1bHQ7XHJcblx0XHR0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xyXG5cdFx0dGhpcy5zdGFydCA9IHRoaXMubm93ID0gdGhpcy5jdXIoKTtcclxuXHRcdHRoaXMuZW5kID0gZW5kO1xyXG5cdFx0dGhpcy51bml0ID0gdW5pdCB8fCAoIGpRdWVyeS5jc3NOdW1iZXJbIHByb3AgXSA/IFwiXCIgOiBcInB4XCIgKTtcclxuXHR9LFxyXG5cdGN1cjogZnVuY3Rpb24oKSB7XHJcblx0XHR2YXIgaG9va3MgPSBUd2Vlbi5wcm9wSG9va3NbIHRoaXMucHJvcCBdO1xyXG5cclxuXHRcdHJldHVybiBob29rcyAmJiBob29rcy5nZXQgP1xyXG5cdFx0XHRob29rcy5nZXQoIHRoaXMgKSA6XHJcblx0XHRcdFR3ZWVuLnByb3BIb29rcy5fZGVmYXVsdC5nZXQoIHRoaXMgKTtcclxuXHR9LFxyXG5cdHJ1bjogZnVuY3Rpb24oIHBlcmNlbnQgKSB7XHJcblx0XHR2YXIgZWFzZWQsXHJcblx0XHRcdGhvb2tzID0gVHdlZW4ucHJvcEhvb2tzWyB0aGlzLnByb3AgXTtcclxuXHJcblx0XHRpZiAoIHRoaXMub3B0aW9ucy5kdXJhdGlvbiApIHtcclxuXHRcdFx0dGhpcy5wb3MgPSBlYXNlZCA9IGpRdWVyeS5lYXNpbmdbIHRoaXMuZWFzaW5nIF0oXHJcblx0XHRcdFx0cGVyY2VudCwgdGhpcy5vcHRpb25zLmR1cmF0aW9uICogcGVyY2VudCwgMCwgMSwgdGhpcy5vcHRpb25zLmR1cmF0aW9uXHJcblx0XHRcdCk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHR0aGlzLnBvcyA9IGVhc2VkID0gcGVyY2VudDtcclxuXHRcdH1cclxuXHRcdHRoaXMubm93ID0gKCB0aGlzLmVuZCAtIHRoaXMuc3RhcnQgKSAqIGVhc2VkICsgdGhpcy5zdGFydDtcclxuXHJcblx0XHRpZiAoIHRoaXMub3B0aW9ucy5zdGVwICkge1xyXG5cdFx0XHR0aGlzLm9wdGlvbnMuc3RlcC5jYWxsKCB0aGlzLmVsZW0sIHRoaXMubm93LCB0aGlzICk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBob29rcyAmJiBob29rcy5zZXQgKSB7XHJcblx0XHRcdGhvb2tzLnNldCggdGhpcyApO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0VHdlZW4ucHJvcEhvb2tzLl9kZWZhdWx0LnNldCggdGhpcyApO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHRoaXM7XHJcblx0fVxyXG59O1xyXG5cclxuVHdlZW4ucHJvdG90eXBlLmluaXQucHJvdG90eXBlID0gVHdlZW4ucHJvdG90eXBlO1xyXG5cclxuVHdlZW4ucHJvcEhvb2tzID0ge1xyXG5cdF9kZWZhdWx0OiB7XHJcblx0XHRnZXQ6IGZ1bmN0aW9uKCB0d2VlbiApIHtcclxuXHRcdFx0dmFyIHJlc3VsdDtcclxuXHJcblx0XHRcdC8vIFVzZSBhIHByb3BlcnR5IG9uIHRoZSBlbGVtZW50IGRpcmVjdGx5IHdoZW4gaXQgaXMgbm90IGEgRE9NIGVsZW1lbnQsXHJcblx0XHRcdC8vIG9yIHdoZW4gdGhlcmUgaXMgbm8gbWF0Y2hpbmcgc3R5bGUgcHJvcGVydHkgdGhhdCBleGlzdHMuXHJcblx0XHRcdGlmICggdHdlZW4uZWxlbS5ub2RlVHlwZSAhPT0gMSB8fFxyXG5cdFx0XHRcdHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXSAhPSBudWxsICYmIHR3ZWVuLmVsZW0uc3R5bGVbIHR3ZWVuLnByb3AgXSA9PSBudWxsICkge1xyXG5cdFx0XHRcdHJldHVybiB0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF07XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFBhc3NpbmcgYW4gZW1wdHkgc3RyaW5nIGFzIGEgM3JkIHBhcmFtZXRlciB0byAuY3NzIHdpbGwgYXV0b21hdGljYWxseVxyXG5cdFx0XHQvLyBhdHRlbXB0IGEgcGFyc2VGbG9hdCBhbmQgZmFsbGJhY2sgdG8gYSBzdHJpbmcgaWYgdGhlIHBhcnNlIGZhaWxzLlxyXG5cdFx0XHQvLyBTaW1wbGUgdmFsdWVzIHN1Y2ggYXMgXCIxMHB4XCIgYXJlIHBhcnNlZCB0byBGbG9hdDtcclxuXHRcdFx0Ly8gY29tcGxleCB2YWx1ZXMgc3VjaCBhcyBcInJvdGF0ZSgxcmFkKVwiIGFyZSByZXR1cm5lZCBhcy1pcy5cclxuXHRcdFx0cmVzdWx0ID0galF1ZXJ5LmNzcyggdHdlZW4uZWxlbSwgdHdlZW4ucHJvcCwgXCJcIiApO1xyXG5cclxuXHRcdFx0Ly8gRW1wdHkgc3RyaW5ncywgbnVsbCwgdW5kZWZpbmVkIGFuZCBcImF1dG9cIiBhcmUgY29udmVydGVkIHRvIDAuXHJcblx0XHRcdHJldHVybiAhcmVzdWx0IHx8IHJlc3VsdCA9PT0gXCJhdXRvXCIgPyAwIDogcmVzdWx0O1xyXG5cdFx0fSxcclxuXHRcdHNldDogZnVuY3Rpb24oIHR3ZWVuICkge1xyXG5cclxuXHRcdFx0Ly8gVXNlIHN0ZXAgaG9vayBmb3IgYmFjayBjb21wYXQuXHJcblx0XHRcdC8vIFVzZSBjc3NIb29rIGlmIGl0cyB0aGVyZS5cclxuXHRcdFx0Ly8gVXNlIC5zdHlsZSBpZiBhdmFpbGFibGUgYW5kIHVzZSBwbGFpbiBwcm9wZXJ0aWVzIHdoZXJlIGF2YWlsYWJsZS5cclxuXHRcdFx0aWYgKCBqUXVlcnkuZnguc3RlcFsgdHdlZW4ucHJvcCBdICkge1xyXG5cdFx0XHRcdGpRdWVyeS5meC5zdGVwWyB0d2Vlbi5wcm9wIF0oIHR3ZWVuICk7XHJcblx0XHRcdH0gZWxzZSBpZiAoIHR3ZWVuLmVsZW0ubm9kZVR5cGUgPT09IDEgJiZcclxuXHRcdFx0XHQoIHR3ZWVuLmVsZW0uc3R5bGVbIGpRdWVyeS5jc3NQcm9wc1sgdHdlZW4ucHJvcCBdIF0gIT0gbnVsbCB8fFxyXG5cdFx0XHRcdFx0alF1ZXJ5LmNzc0hvb2tzWyB0d2Vlbi5wcm9wIF0gKSApIHtcclxuXHRcdFx0XHRqUXVlcnkuc3R5bGUoIHR3ZWVuLmVsZW0sIHR3ZWVuLnByb3AsIHR3ZWVuLm5vdyArIHR3ZWVuLnVuaXQgKTtcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHR0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gPSB0d2Vlbi5ub3c7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcbn07XHJcblxyXG4vLyBTdXBwb3J0OiBJRTlcclxuLy8gUGFuaWMgYmFzZWQgYXBwcm9hY2ggdG8gc2V0dGluZyB0aGluZ3Mgb24gZGlzY29ubmVjdGVkIG5vZGVzXHJcblR3ZWVuLnByb3BIb29rcy5zY3JvbGxUb3AgPSBUd2Vlbi5wcm9wSG9va3Muc2Nyb2xsTGVmdCA9IHtcclxuXHRzZXQ6IGZ1bmN0aW9uKCB0d2VlbiApIHtcclxuXHRcdGlmICggdHdlZW4uZWxlbS5ub2RlVHlwZSAmJiB0d2Vlbi5lbGVtLnBhcmVudE5vZGUgKSB7XHJcblx0XHRcdHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXSA9IHR3ZWVuLm5vdztcclxuXHRcdH1cclxuXHR9XHJcbn07XHJcblxyXG5qUXVlcnkuZWFzaW5nID0ge1xyXG5cdGxpbmVhcjogZnVuY3Rpb24oIHAgKSB7XHJcblx0XHRyZXR1cm4gcDtcclxuXHR9LFxyXG5cdHN3aW5nOiBmdW5jdGlvbiggcCApIHtcclxuXHRcdHJldHVybiAwLjUgLSBNYXRoLmNvcyggcCAqIE1hdGguUEkgKSAvIDI7XHJcblx0fSxcclxuXHRfZGVmYXVsdDogXCJzd2luZ1wiXHJcbn07XHJcblxyXG5qUXVlcnkuZnggPSBUd2Vlbi5wcm90b3R5cGUuaW5pdDtcclxuXHJcbi8vIEJhY2sgQ29tcGF0IDwxLjggZXh0ZW5zaW9uIHBvaW50XHJcbmpRdWVyeS5meC5zdGVwID0ge307XHJcblxyXG5cclxuXHJcblxyXG52YXJcclxuXHRmeE5vdywgdGltZXJJZCxcclxuXHRyZnh0eXBlcyA9IC9eKD86dG9nZ2xlfHNob3d8aGlkZSkkLyxcclxuXHRycnVuID0gL3F1ZXVlSG9va3MkLztcclxuXHJcbi8vIEFuaW1hdGlvbnMgY3JlYXRlZCBzeW5jaHJvbm91c2x5IHdpbGwgcnVuIHN5bmNocm9ub3VzbHlcclxuZnVuY3Rpb24gY3JlYXRlRnhOb3coKSB7XHJcblx0d2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xyXG5cdFx0ZnhOb3cgPSB1bmRlZmluZWQ7XHJcblx0fSApO1xyXG5cdHJldHVybiAoIGZ4Tm93ID0galF1ZXJ5Lm5vdygpICk7XHJcbn1cclxuXHJcbi8vIEdlbmVyYXRlIHBhcmFtZXRlcnMgdG8gY3JlYXRlIGEgc3RhbmRhcmQgYW5pbWF0aW9uXHJcbmZ1bmN0aW9uIGdlbkZ4KCB0eXBlLCBpbmNsdWRlV2lkdGggKSB7XHJcblx0dmFyIHdoaWNoLFxyXG5cdFx0aSA9IDAsXHJcblx0XHRhdHRycyA9IHsgaGVpZ2h0OiB0eXBlIH07XHJcblxyXG5cdC8vIElmIHdlIGluY2x1ZGUgd2lkdGgsIHN0ZXAgdmFsdWUgaXMgMSB0byBkbyBhbGwgY3NzRXhwYW5kIHZhbHVlcyxcclxuXHQvLyBvdGhlcndpc2Ugc3RlcCB2YWx1ZSBpcyAyIHRvIHNraXAgb3ZlciBMZWZ0IGFuZCBSaWdodFxyXG5cdGluY2x1ZGVXaWR0aCA9IGluY2x1ZGVXaWR0aCA/IDEgOiAwO1xyXG5cdGZvciAoIDsgaSA8IDQgOyBpICs9IDIgLSBpbmNsdWRlV2lkdGggKSB7XHJcblx0XHR3aGljaCA9IGNzc0V4cGFuZFsgaSBdO1xyXG5cdFx0YXR0cnNbIFwibWFyZ2luXCIgKyB3aGljaCBdID0gYXR0cnNbIFwicGFkZGluZ1wiICsgd2hpY2ggXSA9IHR5cGU7XHJcblx0fVxyXG5cclxuXHRpZiAoIGluY2x1ZGVXaWR0aCApIHtcclxuXHRcdGF0dHJzLm9wYWNpdHkgPSBhdHRycy53aWR0aCA9IHR5cGU7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gYXR0cnM7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGNyZWF0ZVR3ZWVuKCB2YWx1ZSwgcHJvcCwgYW5pbWF0aW9uICkge1xyXG5cdHZhciB0d2VlbixcclxuXHRcdGNvbGxlY3Rpb24gPSAoIEFuaW1hdGlvbi50d2VlbmVyc1sgcHJvcCBdIHx8IFtdICkuY29uY2F0KCBBbmltYXRpb24udHdlZW5lcnNbIFwiKlwiIF0gKSxcclxuXHRcdGluZGV4ID0gMCxcclxuXHRcdGxlbmd0aCA9IGNvbGxlY3Rpb24ubGVuZ3RoO1xyXG5cdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XHJcblx0XHRpZiAoICggdHdlZW4gPSBjb2xsZWN0aW9uWyBpbmRleCBdLmNhbGwoIGFuaW1hdGlvbiwgcHJvcCwgdmFsdWUgKSApICkge1xyXG5cclxuXHRcdFx0Ly8gV2UncmUgZG9uZSB3aXRoIHRoaXMgcHJvcGVydHlcclxuXHRcdFx0cmV0dXJuIHR3ZWVuO1xyXG5cdFx0fVxyXG5cdH1cclxufVxyXG5cclxuZnVuY3Rpb24gZGVmYXVsdFByZWZpbHRlciggZWxlbSwgcHJvcHMsIG9wdHMgKSB7XHJcblx0LyoganNoaW50IHZhbGlkdGhpczogdHJ1ZSAqL1xyXG5cdHZhciBwcm9wLCB2YWx1ZSwgdG9nZ2xlLCB0d2VlbiwgaG9va3MsIG9sZGZpcmUsIGRpc3BsYXksIGNoZWNrRGlzcGxheSxcclxuXHRcdGFuaW0gPSB0aGlzLFxyXG5cdFx0b3JpZyA9IHt9LFxyXG5cdFx0c3R5bGUgPSBlbGVtLnN0eWxlLFxyXG5cdFx0aGlkZGVuID0gZWxlbS5ub2RlVHlwZSAmJiBpc0hpZGRlbiggZWxlbSApLFxyXG5cdFx0ZGF0YVNob3cgPSBkYXRhUHJpdi5nZXQoIGVsZW0sIFwiZnhzaG93XCIgKTtcclxuXHJcblx0Ly8gSGFuZGxlIHF1ZXVlOiBmYWxzZSBwcm9taXNlc1xyXG5cdGlmICggIW9wdHMucXVldWUgKSB7XHJcblx0XHRob29rcyA9IGpRdWVyeS5fcXVldWVIb29rcyggZWxlbSwgXCJmeFwiICk7XHJcblx0XHRpZiAoIGhvb2tzLnVucXVldWVkID09IG51bGwgKSB7XHJcblx0XHRcdGhvb2tzLnVucXVldWVkID0gMDtcclxuXHRcdFx0b2xkZmlyZSA9IGhvb2tzLmVtcHR5LmZpcmU7XHJcblx0XHRcdGhvb2tzLmVtcHR5LmZpcmUgPSBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRpZiAoICFob29rcy51bnF1ZXVlZCApIHtcclxuXHRcdFx0XHRcdG9sZGZpcmUoKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH07XHJcblx0XHR9XHJcblx0XHRob29rcy51bnF1ZXVlZCsrO1xyXG5cclxuXHRcdGFuaW0uYWx3YXlzKCBmdW5jdGlvbigpIHtcclxuXHJcblx0XHRcdC8vIEVuc3VyZSB0aGUgY29tcGxldGUgaGFuZGxlciBpcyBjYWxsZWQgYmVmb3JlIHRoaXMgY29tcGxldGVzXHJcblx0XHRcdGFuaW0uYWx3YXlzKCBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHRob29rcy51bnF1ZXVlZC0tO1xyXG5cdFx0XHRcdGlmICggIWpRdWVyeS5xdWV1ZSggZWxlbSwgXCJmeFwiICkubGVuZ3RoICkge1xyXG5cdFx0XHRcdFx0aG9va3MuZW1wdHkuZmlyZSgpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fSApO1xyXG5cdFx0fSApO1xyXG5cdH1cclxuXHJcblx0Ly8gSGVpZ2h0L3dpZHRoIG92ZXJmbG93IHBhc3NcclxuXHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgKCBcImhlaWdodFwiIGluIHByb3BzIHx8IFwid2lkdGhcIiBpbiBwcm9wcyApICkge1xyXG5cclxuXHRcdC8vIE1ha2Ugc3VyZSB0aGF0IG5vdGhpbmcgc25lYWtzIG91dFxyXG5cdFx0Ly8gUmVjb3JkIGFsbCAzIG92ZXJmbG93IGF0dHJpYnV0ZXMgYmVjYXVzZSBJRTktMTAgZG8gbm90XHJcblx0XHQvLyBjaGFuZ2UgdGhlIG92ZXJmbG93IGF0dHJpYnV0ZSB3aGVuIG92ZXJmbG93WCBhbmRcclxuXHRcdC8vIG92ZXJmbG93WSBhcmUgc2V0IHRvIHRoZSBzYW1lIHZhbHVlXHJcblx0XHRvcHRzLm92ZXJmbG93ID0gWyBzdHlsZS5vdmVyZmxvdywgc3R5bGUub3ZlcmZsb3dYLCBzdHlsZS5vdmVyZmxvd1kgXTtcclxuXHJcblx0XHQvLyBTZXQgZGlzcGxheSBwcm9wZXJ0eSB0byBpbmxpbmUtYmxvY2sgZm9yIGhlaWdodC93aWR0aFxyXG5cdFx0Ly8gYW5pbWF0aW9ucyBvbiBpbmxpbmUgZWxlbWVudHMgdGhhdCBhcmUgaGF2aW5nIHdpZHRoL2hlaWdodCBhbmltYXRlZFxyXG5cdFx0ZGlzcGxheSA9IGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICk7XHJcblxyXG5cdFx0Ly8gVGVzdCBkZWZhdWx0IGRpc3BsYXkgaWYgZGlzcGxheSBpcyBjdXJyZW50bHkgXCJub25lXCJcclxuXHRcdGNoZWNrRGlzcGxheSA9IGRpc3BsYXkgPT09IFwibm9uZVwiID9cclxuXHRcdFx0ZGF0YVByaXYuZ2V0KCBlbGVtLCBcIm9sZGRpc3BsYXlcIiApIHx8IGRlZmF1bHREaXNwbGF5KCBlbGVtLm5vZGVOYW1lICkgOiBkaXNwbGF5O1xyXG5cclxuXHRcdGlmICggY2hlY2tEaXNwbGF5ID09PSBcImlubGluZVwiICYmIGpRdWVyeS5jc3MoIGVsZW0sIFwiZmxvYXRcIiApID09PSBcIm5vbmVcIiApIHtcclxuXHRcdFx0c3R5bGUuZGlzcGxheSA9IFwiaW5saW5lLWJsb2NrXCI7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRpZiAoIG9wdHMub3ZlcmZsb3cgKSB7XHJcblx0XHRzdHlsZS5vdmVyZmxvdyA9IFwiaGlkZGVuXCI7XHJcblx0XHRhbmltLmFsd2F5cyggZnVuY3Rpb24oKSB7XHJcblx0XHRcdHN0eWxlLm92ZXJmbG93ID0gb3B0cy5vdmVyZmxvd1sgMCBdO1xyXG5cdFx0XHRzdHlsZS5vdmVyZmxvd1ggPSBvcHRzLm92ZXJmbG93WyAxIF07XHJcblx0XHRcdHN0eWxlLm92ZXJmbG93WSA9IG9wdHMub3ZlcmZsb3dbIDIgXTtcclxuXHRcdH0gKTtcclxuXHR9XHJcblxyXG5cdC8vIHNob3cvaGlkZSBwYXNzXHJcblx0Zm9yICggcHJvcCBpbiBwcm9wcyApIHtcclxuXHRcdHZhbHVlID0gcHJvcHNbIHByb3AgXTtcclxuXHRcdGlmICggcmZ4dHlwZXMuZXhlYyggdmFsdWUgKSApIHtcclxuXHRcdFx0ZGVsZXRlIHByb3BzWyBwcm9wIF07XHJcblx0XHRcdHRvZ2dsZSA9IHRvZ2dsZSB8fCB2YWx1ZSA9PT0gXCJ0b2dnbGVcIjtcclxuXHRcdFx0aWYgKCB2YWx1ZSA9PT0gKCBoaWRkZW4gPyBcImhpZGVcIiA6IFwic2hvd1wiICkgKSB7XHJcblxyXG5cdFx0XHRcdC8vIElmIHRoZXJlIGlzIGRhdGFTaG93IGxlZnQgb3ZlciBmcm9tIGEgc3RvcHBlZCBoaWRlIG9yIHNob3dcclxuXHRcdFx0XHQvLyBhbmQgd2UgYXJlIGdvaW5nIHRvIHByb2NlZWQgd2l0aCBzaG93LCB3ZSBzaG91bGQgcHJldGVuZCB0byBiZSBoaWRkZW5cclxuXHRcdFx0XHRpZiAoIHZhbHVlID09PSBcInNob3dcIiAmJiBkYXRhU2hvdyAmJiBkYXRhU2hvd1sgcHJvcCBdICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdFx0XHRoaWRkZW4gPSB0cnVlO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRjb250aW51ZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdFx0b3JpZ1sgcHJvcCBdID0gZGF0YVNob3cgJiYgZGF0YVNob3dbIHByb3AgXSB8fCBqUXVlcnkuc3R5bGUoIGVsZW0sIHByb3AgKTtcclxuXHJcblx0XHQvLyBBbnkgbm9uLWZ4IHZhbHVlIHN0b3BzIHVzIGZyb20gcmVzdG9yaW5nIHRoZSBvcmlnaW5hbCBkaXNwbGF5IHZhbHVlXHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRkaXNwbGF5ID0gdW5kZWZpbmVkO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0aWYgKCAhalF1ZXJ5LmlzRW1wdHlPYmplY3QoIG9yaWcgKSApIHtcclxuXHRcdGlmICggZGF0YVNob3cgKSB7XHJcblx0XHRcdGlmICggXCJoaWRkZW5cIiBpbiBkYXRhU2hvdyApIHtcclxuXHRcdFx0XHRoaWRkZW4gPSBkYXRhU2hvdy5oaWRkZW47XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGRhdGFTaG93ID0gZGF0YVByaXYuYWNjZXNzKCBlbGVtLCBcImZ4c2hvd1wiLCB7fSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFN0b3JlIHN0YXRlIGlmIGl0cyB0b2dnbGUgLSBlbmFibGVzIC5zdG9wKCkudG9nZ2xlKCkgdG8gXCJyZXZlcnNlXCJcclxuXHRcdGlmICggdG9nZ2xlICkge1xyXG5cdFx0XHRkYXRhU2hvdy5oaWRkZW4gPSAhaGlkZGVuO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCBoaWRkZW4gKSB7XHJcblx0XHRcdGpRdWVyeSggZWxlbSApLnNob3coKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGFuaW0uZG9uZSggZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0alF1ZXJ5KCBlbGVtICkuaGlkZSgpO1xyXG5cdFx0XHR9ICk7XHJcblx0XHR9XHJcblx0XHRhbmltLmRvbmUoIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR2YXIgcHJvcDtcclxuXHJcblx0XHRcdGRhdGFQcml2LnJlbW92ZSggZWxlbSwgXCJmeHNob3dcIiApO1xyXG5cdFx0XHRmb3IgKCBwcm9wIGluIG9yaWcgKSB7XHJcblx0XHRcdFx0alF1ZXJ5LnN0eWxlKCBlbGVtLCBwcm9wLCBvcmlnWyBwcm9wIF0gKTtcclxuXHRcdFx0fVxyXG5cdFx0fSApO1xyXG5cdFx0Zm9yICggcHJvcCBpbiBvcmlnICkge1xyXG5cdFx0XHR0d2VlbiA9IGNyZWF0ZVR3ZWVuKCBoaWRkZW4gPyBkYXRhU2hvd1sgcHJvcCBdIDogMCwgcHJvcCwgYW5pbSApO1xyXG5cclxuXHRcdFx0aWYgKCAhKCBwcm9wIGluIGRhdGFTaG93ICkgKSB7XHJcblx0XHRcdFx0ZGF0YVNob3dbIHByb3AgXSA9IHR3ZWVuLnN0YXJ0O1xyXG5cdFx0XHRcdGlmICggaGlkZGVuICkge1xyXG5cdFx0XHRcdFx0dHdlZW4uZW5kID0gdHdlZW4uc3RhcnQ7XHJcblx0XHRcdFx0XHR0d2Vlbi5zdGFydCA9IHByb3AgPT09IFwid2lkdGhcIiB8fCBwcm9wID09PSBcImhlaWdodFwiID8gMSA6IDA7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdC8vIElmIHRoaXMgaXMgYSBub29wIGxpa2UgLmhpZGUoKS5oaWRlKCksIHJlc3RvcmUgYW4gb3ZlcndyaXR0ZW4gZGlzcGxheSB2YWx1ZVxyXG5cdH0gZWxzZSBpZiAoICggZGlzcGxheSA9PT0gXCJub25lXCIgPyBkZWZhdWx0RGlzcGxheSggZWxlbS5ub2RlTmFtZSApIDogZGlzcGxheSApID09PSBcImlubGluZVwiICkge1xyXG5cdFx0c3R5bGUuZGlzcGxheSA9IGRpc3BsYXk7XHJcblx0fVxyXG59XHJcblxyXG5mdW5jdGlvbiBwcm9wRmlsdGVyKCBwcm9wcywgc3BlY2lhbEVhc2luZyApIHtcclxuXHR2YXIgaW5kZXgsIG5hbWUsIGVhc2luZywgdmFsdWUsIGhvb2tzO1xyXG5cclxuXHQvLyBjYW1lbENhc2UsIHNwZWNpYWxFYXNpbmcgYW5kIGV4cGFuZCBjc3NIb29rIHBhc3NcclxuXHRmb3IgKCBpbmRleCBpbiBwcm9wcyApIHtcclxuXHRcdG5hbWUgPSBqUXVlcnkuY2FtZWxDYXNlKCBpbmRleCApO1xyXG5cdFx0ZWFzaW5nID0gc3BlY2lhbEVhc2luZ1sgbmFtZSBdO1xyXG5cdFx0dmFsdWUgPSBwcm9wc1sgaW5kZXggXTtcclxuXHRcdGlmICggalF1ZXJ5LmlzQXJyYXkoIHZhbHVlICkgKSB7XHJcblx0XHRcdGVhc2luZyA9IHZhbHVlWyAxIF07XHJcblx0XHRcdHZhbHVlID0gcHJvcHNbIGluZGV4IF0gPSB2YWx1ZVsgMCBdO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggaW5kZXggIT09IG5hbWUgKSB7XHJcblx0XHRcdHByb3BzWyBuYW1lIF0gPSB2YWx1ZTtcclxuXHRcdFx0ZGVsZXRlIHByb3BzWyBpbmRleCBdO1xyXG5cdFx0fVxyXG5cclxuXHRcdGhvb2tzID0galF1ZXJ5LmNzc0hvb2tzWyBuYW1lIF07XHJcblx0XHRpZiAoIGhvb2tzICYmIFwiZXhwYW5kXCIgaW4gaG9va3MgKSB7XHJcblx0XHRcdHZhbHVlID0gaG9va3MuZXhwYW5kKCB2YWx1ZSApO1xyXG5cdFx0XHRkZWxldGUgcHJvcHNbIG5hbWUgXTtcclxuXHJcblx0XHRcdC8vIE5vdCBxdWl0ZSAkLmV4dGVuZCwgdGhpcyB3b24ndCBvdmVyd3JpdGUgZXhpc3Rpbmcga2V5cy5cclxuXHRcdFx0Ly8gUmV1c2luZyAnaW5kZXgnIGJlY2F1c2Ugd2UgaGF2ZSB0aGUgY29ycmVjdCBcIm5hbWVcIlxyXG5cdFx0XHRmb3IgKCBpbmRleCBpbiB2YWx1ZSApIHtcclxuXHRcdFx0XHRpZiAoICEoIGluZGV4IGluIHByb3BzICkgKSB7XHJcblx0XHRcdFx0XHRwcm9wc1sgaW5kZXggXSA9IHZhbHVlWyBpbmRleCBdO1xyXG5cdFx0XHRcdFx0c3BlY2lhbEVhc2luZ1sgaW5kZXggXSA9IGVhc2luZztcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdHNwZWNpYWxFYXNpbmdbIG5hbWUgXSA9IGVhc2luZztcclxuXHRcdH1cclxuXHR9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIEFuaW1hdGlvbiggZWxlbSwgcHJvcGVydGllcywgb3B0aW9ucyApIHtcclxuXHR2YXIgcmVzdWx0LFxyXG5cdFx0c3RvcHBlZCxcclxuXHRcdGluZGV4ID0gMCxcclxuXHRcdGxlbmd0aCA9IEFuaW1hdGlvbi5wcmVmaWx0ZXJzLmxlbmd0aCxcclxuXHRcdGRlZmVycmVkID0galF1ZXJ5LkRlZmVycmVkKCkuYWx3YXlzKCBmdW5jdGlvbigpIHtcclxuXHJcblx0XHRcdC8vIERvbid0IG1hdGNoIGVsZW0gaW4gdGhlIDphbmltYXRlZCBzZWxlY3RvclxyXG5cdFx0XHRkZWxldGUgdGljay5lbGVtO1xyXG5cdFx0fSApLFxyXG5cdFx0dGljayA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRpZiAoIHN0b3BwZWQgKSB7XHJcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xyXG5cdFx0XHR9XHJcblx0XHRcdHZhciBjdXJyZW50VGltZSA9IGZ4Tm93IHx8IGNyZWF0ZUZ4Tm93KCksXHJcblx0XHRcdFx0cmVtYWluaW5nID0gTWF0aC5tYXgoIDAsIGFuaW1hdGlvbi5zdGFydFRpbWUgKyBhbmltYXRpb24uZHVyYXRpb24gLSBjdXJyZW50VGltZSApLFxyXG5cclxuXHRcdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDIuM1xyXG5cdFx0XHRcdC8vIEFyY2hhaWMgY3Jhc2ggYnVnIHdvbid0IGFsbG93IHVzIHRvIHVzZSBgMSAtICggMC41IHx8IDAgKWAgKCMxMjQ5NylcclxuXHRcdFx0XHR0ZW1wID0gcmVtYWluaW5nIC8gYW5pbWF0aW9uLmR1cmF0aW9uIHx8IDAsXHJcblx0XHRcdFx0cGVyY2VudCA9IDEgLSB0ZW1wLFxyXG5cdFx0XHRcdGluZGV4ID0gMCxcclxuXHRcdFx0XHRsZW5ndGggPSBhbmltYXRpb24udHdlZW5zLmxlbmd0aDtcclxuXHJcblx0XHRcdGZvciAoIDsgaW5kZXggPCBsZW5ndGggOyBpbmRleCsrICkge1xyXG5cdFx0XHRcdGFuaW1hdGlvbi50d2VlbnNbIGluZGV4IF0ucnVuKCBwZXJjZW50ICk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGRlZmVycmVkLm5vdGlmeVdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uLCBwZXJjZW50LCByZW1haW5pbmcgXSApO1xyXG5cclxuXHRcdFx0aWYgKCBwZXJjZW50IDwgMSAmJiBsZW5ndGggKSB7XHJcblx0XHRcdFx0cmV0dXJuIHJlbWFpbmluZztcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggZWxlbSwgWyBhbmltYXRpb24gXSApO1xyXG5cdFx0XHRcdHJldHVybiBmYWxzZTtcclxuXHRcdFx0fVxyXG5cdFx0fSxcclxuXHRcdGFuaW1hdGlvbiA9IGRlZmVycmVkLnByb21pc2UoIHtcclxuXHRcdFx0ZWxlbTogZWxlbSxcclxuXHRcdFx0cHJvcHM6IGpRdWVyeS5leHRlbmQoIHt9LCBwcm9wZXJ0aWVzICksXHJcblx0XHRcdG9wdHM6IGpRdWVyeS5leHRlbmQoIHRydWUsIHtcclxuXHRcdFx0XHRzcGVjaWFsRWFzaW5nOiB7fSxcclxuXHRcdFx0XHRlYXNpbmc6IGpRdWVyeS5lYXNpbmcuX2RlZmF1bHRcclxuXHRcdFx0fSwgb3B0aW9ucyApLFxyXG5cdFx0XHRvcmlnaW5hbFByb3BlcnRpZXM6IHByb3BlcnRpZXMsXHJcblx0XHRcdG9yaWdpbmFsT3B0aW9uczogb3B0aW9ucyxcclxuXHRcdFx0c3RhcnRUaW1lOiBmeE5vdyB8fCBjcmVhdGVGeE5vdygpLFxyXG5cdFx0XHRkdXJhdGlvbjogb3B0aW9ucy5kdXJhdGlvbixcclxuXHRcdFx0dHdlZW5zOiBbXSxcclxuXHRcdFx0Y3JlYXRlVHdlZW46IGZ1bmN0aW9uKCBwcm9wLCBlbmQgKSB7XHJcblx0XHRcdFx0dmFyIHR3ZWVuID0galF1ZXJ5LlR3ZWVuKCBlbGVtLCBhbmltYXRpb24ub3B0cywgcHJvcCwgZW5kLFxyXG5cdFx0XHRcdFx0XHRhbmltYXRpb24ub3B0cy5zcGVjaWFsRWFzaW5nWyBwcm9wIF0gfHwgYW5pbWF0aW9uLm9wdHMuZWFzaW5nICk7XHJcblx0XHRcdFx0YW5pbWF0aW9uLnR3ZWVucy5wdXNoKCB0d2VlbiApO1xyXG5cdFx0XHRcdHJldHVybiB0d2VlbjtcclxuXHRcdFx0fSxcclxuXHRcdFx0c3RvcDogZnVuY3Rpb24oIGdvdG9FbmQgKSB7XHJcblx0XHRcdFx0dmFyIGluZGV4ID0gMCxcclxuXHJcblx0XHRcdFx0XHQvLyBJZiB3ZSBhcmUgZ29pbmcgdG8gdGhlIGVuZCwgd2Ugd2FudCB0byBydW4gYWxsIHRoZSB0d2VlbnNcclxuXHRcdFx0XHRcdC8vIG90aGVyd2lzZSB3ZSBza2lwIHRoaXMgcGFydFxyXG5cdFx0XHRcdFx0bGVuZ3RoID0gZ290b0VuZCA/IGFuaW1hdGlvbi50d2VlbnMubGVuZ3RoIDogMDtcclxuXHRcdFx0XHRpZiAoIHN0b3BwZWQgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gdGhpcztcclxuXHRcdFx0XHR9XHJcblx0XHRcdFx0c3RvcHBlZCA9IHRydWU7XHJcblx0XHRcdFx0Zm9yICggOyBpbmRleCA8IGxlbmd0aCA7IGluZGV4KysgKSB7XHJcblx0XHRcdFx0XHRhbmltYXRpb24udHdlZW5zWyBpbmRleCBdLnJ1biggMSApO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gUmVzb2x2ZSB3aGVuIHdlIHBsYXllZCB0aGUgbGFzdCBmcmFtZTsgb3RoZXJ3aXNlLCByZWplY3RcclxuXHRcdFx0XHRpZiAoIGdvdG9FbmQgKSB7XHJcblx0XHRcdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgMSwgMCBdICk7XHJcblx0XHRcdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggZWxlbSwgWyBhbmltYXRpb24sIGdvdG9FbmQgXSApO1xyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRkZWZlcnJlZC5yZWplY3RXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgZ290b0VuZCBdICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0XHR9XHJcblx0XHR9ICksXHJcblx0XHRwcm9wcyA9IGFuaW1hdGlvbi5wcm9wcztcclxuXHJcblx0cHJvcEZpbHRlciggcHJvcHMsIGFuaW1hdGlvbi5vcHRzLnNwZWNpYWxFYXNpbmcgKTtcclxuXHJcblx0Zm9yICggOyBpbmRleCA8IGxlbmd0aCA7IGluZGV4KysgKSB7XHJcblx0XHRyZXN1bHQgPSBBbmltYXRpb24ucHJlZmlsdGVyc1sgaW5kZXggXS5jYWxsKCBhbmltYXRpb24sIGVsZW0sIHByb3BzLCBhbmltYXRpb24ub3B0cyApO1xyXG5cdFx0aWYgKCByZXN1bHQgKSB7XHJcblx0XHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHJlc3VsdC5zdG9wICkgKSB7XHJcblx0XHRcdFx0alF1ZXJ5Ll9xdWV1ZUhvb2tzKCBhbmltYXRpb24uZWxlbSwgYW5pbWF0aW9uLm9wdHMucXVldWUgKS5zdG9wID1cclxuXHRcdFx0XHRcdGpRdWVyeS5wcm94eSggcmVzdWx0LnN0b3AsIHJlc3VsdCApO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiByZXN1bHQ7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRqUXVlcnkubWFwKCBwcm9wcywgY3JlYXRlVHdlZW4sIGFuaW1hdGlvbiApO1xyXG5cclxuXHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBhbmltYXRpb24ub3B0cy5zdGFydCApICkge1xyXG5cdFx0YW5pbWF0aW9uLm9wdHMuc3RhcnQuY2FsbCggZWxlbSwgYW5pbWF0aW9uICk7XHJcblx0fVxyXG5cclxuXHRqUXVlcnkuZngudGltZXIoXHJcblx0XHRqUXVlcnkuZXh0ZW5kKCB0aWNrLCB7XHJcblx0XHRcdGVsZW06IGVsZW0sXHJcblx0XHRcdGFuaW06IGFuaW1hdGlvbixcclxuXHRcdFx0cXVldWU6IGFuaW1hdGlvbi5vcHRzLnF1ZXVlXHJcblx0XHR9IClcclxuXHQpO1xyXG5cclxuXHQvLyBhdHRhY2ggY2FsbGJhY2tzIGZyb20gb3B0aW9uc1xyXG5cdHJldHVybiBhbmltYXRpb24ucHJvZ3Jlc3MoIGFuaW1hdGlvbi5vcHRzLnByb2dyZXNzIClcclxuXHRcdC5kb25lKCBhbmltYXRpb24ub3B0cy5kb25lLCBhbmltYXRpb24ub3B0cy5jb21wbGV0ZSApXHJcblx0XHQuZmFpbCggYW5pbWF0aW9uLm9wdHMuZmFpbCApXHJcblx0XHQuYWx3YXlzKCBhbmltYXRpb24ub3B0cy5hbHdheXMgKTtcclxufVxyXG5cclxualF1ZXJ5LkFuaW1hdGlvbiA9IGpRdWVyeS5leHRlbmQoIEFuaW1hdGlvbiwge1xyXG5cdHR3ZWVuZXJzOiB7XHJcblx0XHRcIipcIjogWyBmdW5jdGlvbiggcHJvcCwgdmFsdWUgKSB7XHJcblx0XHRcdHZhciB0d2VlbiA9IHRoaXMuY3JlYXRlVHdlZW4oIHByb3AsIHZhbHVlICk7XHJcblx0XHRcdGFkanVzdENTUyggdHdlZW4uZWxlbSwgcHJvcCwgcmNzc051bS5leGVjKCB2YWx1ZSApLCB0d2VlbiApO1xyXG5cdFx0XHRyZXR1cm4gdHdlZW47XHJcblx0XHR9IF1cclxuXHR9LFxyXG5cclxuXHR0d2VlbmVyOiBmdW5jdGlvbiggcHJvcHMsIGNhbGxiYWNrICkge1xyXG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggcHJvcHMgKSApIHtcclxuXHRcdFx0Y2FsbGJhY2sgPSBwcm9wcztcclxuXHRcdFx0cHJvcHMgPSBbIFwiKlwiIF07XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRwcm9wcyA9IHByb3BzLm1hdGNoKCBybm90d2hpdGUgKTtcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgcHJvcCxcclxuXHRcdFx0aW5kZXggPSAwLFxyXG5cdFx0XHRsZW5ndGggPSBwcm9wcy5sZW5ndGg7XHJcblxyXG5cdFx0Zm9yICggOyBpbmRleCA8IGxlbmd0aCA7IGluZGV4KysgKSB7XHJcblx0XHRcdHByb3AgPSBwcm9wc1sgaW5kZXggXTtcclxuXHRcdFx0QW5pbWF0aW9uLnR3ZWVuZXJzWyBwcm9wIF0gPSBBbmltYXRpb24udHdlZW5lcnNbIHByb3AgXSB8fCBbXTtcclxuXHRcdFx0QW5pbWF0aW9uLnR3ZWVuZXJzWyBwcm9wIF0udW5zaGlmdCggY2FsbGJhY2sgKTtcclxuXHRcdH1cclxuXHR9LFxyXG5cclxuXHRwcmVmaWx0ZXJzOiBbIGRlZmF1bHRQcmVmaWx0ZXIgXSxcclxuXHJcblx0cHJlZmlsdGVyOiBmdW5jdGlvbiggY2FsbGJhY2ssIHByZXBlbmQgKSB7XHJcblx0XHRpZiAoIHByZXBlbmQgKSB7XHJcblx0XHRcdEFuaW1hdGlvbi5wcmVmaWx0ZXJzLnVuc2hpZnQoIGNhbGxiYWNrICk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHRBbmltYXRpb24ucHJlZmlsdGVycy5wdXNoKCBjYWxsYmFjayApO1xyXG5cdFx0fVxyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LnNwZWVkID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGZuICkge1xyXG5cdHZhciBvcHQgPSBzcGVlZCAmJiB0eXBlb2Ygc3BlZWQgPT09IFwib2JqZWN0XCIgPyBqUXVlcnkuZXh0ZW5kKCB7fSwgc3BlZWQgKSA6IHtcclxuXHRcdGNvbXBsZXRlOiBmbiB8fCAhZm4gJiYgZWFzaW5nIHx8XHJcblx0XHRcdGpRdWVyeS5pc0Z1bmN0aW9uKCBzcGVlZCApICYmIHNwZWVkLFxyXG5cdFx0ZHVyYXRpb246IHNwZWVkLFxyXG5cdFx0ZWFzaW5nOiBmbiAmJiBlYXNpbmcgfHwgZWFzaW5nICYmICFqUXVlcnkuaXNGdW5jdGlvbiggZWFzaW5nICkgJiYgZWFzaW5nXHJcblx0fTtcclxuXHJcblx0b3B0LmR1cmF0aW9uID0galF1ZXJ5LmZ4Lm9mZiA/IDAgOiB0eXBlb2Ygb3B0LmR1cmF0aW9uID09PSBcIm51bWJlclwiID9cclxuXHRcdG9wdC5kdXJhdGlvbiA6IG9wdC5kdXJhdGlvbiBpbiBqUXVlcnkuZnguc3BlZWRzID9cclxuXHRcdFx0alF1ZXJ5LmZ4LnNwZWVkc1sgb3B0LmR1cmF0aW9uIF0gOiBqUXVlcnkuZnguc3BlZWRzLl9kZWZhdWx0O1xyXG5cclxuXHQvLyBOb3JtYWxpemUgb3B0LnF1ZXVlIC0gdHJ1ZS91bmRlZmluZWQvbnVsbCAtPiBcImZ4XCJcclxuXHRpZiAoIG9wdC5xdWV1ZSA9PSBudWxsIHx8IG9wdC5xdWV1ZSA9PT0gdHJ1ZSApIHtcclxuXHRcdG9wdC5xdWV1ZSA9IFwiZnhcIjtcclxuXHR9XHJcblxyXG5cdC8vIFF1ZXVlaW5nXHJcblx0b3B0Lm9sZCA9IG9wdC5jb21wbGV0ZTtcclxuXHJcblx0b3B0LmNvbXBsZXRlID0gZnVuY3Rpb24oKSB7XHJcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBvcHQub2xkICkgKSB7XHJcblx0XHRcdG9wdC5vbGQuY2FsbCggdGhpcyApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggb3B0LnF1ZXVlICkge1xyXG5cdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgb3B0LnF1ZXVlICk7XHJcblx0XHR9XHJcblx0fTtcclxuXHJcblx0cmV0dXJuIG9wdDtcclxufTtcclxuXHJcbmpRdWVyeS5mbi5leHRlbmQoIHtcclxuXHRmYWRlVG86IGZ1bmN0aW9uKCBzcGVlZCwgdG8sIGVhc2luZywgY2FsbGJhY2sgKSB7XHJcblxyXG5cdFx0Ly8gU2hvdyBhbnkgaGlkZGVuIGVsZW1lbnRzIGFmdGVyIHNldHRpbmcgb3BhY2l0eSB0byAwXHJcblx0XHRyZXR1cm4gdGhpcy5maWx0ZXIoIGlzSGlkZGVuICkuY3NzKCBcIm9wYWNpdHlcIiwgMCApLnNob3coKVxyXG5cclxuXHRcdFx0Ly8gQW5pbWF0ZSB0byB0aGUgdmFsdWUgc3BlY2lmaWVkXHJcblx0XHRcdC5lbmQoKS5hbmltYXRlKCB7IG9wYWNpdHk6IHRvIH0sIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICk7XHJcblx0fSxcclxuXHRhbmltYXRlOiBmdW5jdGlvbiggcHJvcCwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSB7XHJcblx0XHR2YXIgZW1wdHkgPSBqUXVlcnkuaXNFbXB0eU9iamVjdCggcHJvcCApLFxyXG5cdFx0XHRvcHRhbGwgPSBqUXVlcnkuc3BlZWQoIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICksXHJcblx0XHRcdGRvQW5pbWF0aW9uID0gZnVuY3Rpb24oKSB7XHJcblxyXG5cdFx0XHRcdC8vIE9wZXJhdGUgb24gYSBjb3B5IG9mIHByb3Agc28gcGVyLXByb3BlcnR5IGVhc2luZyB3b24ndCBiZSBsb3N0XHJcblx0XHRcdFx0dmFyIGFuaW0gPSBBbmltYXRpb24oIHRoaXMsIGpRdWVyeS5leHRlbmQoIHt9LCBwcm9wICksIG9wdGFsbCApO1xyXG5cclxuXHRcdFx0XHQvLyBFbXB0eSBhbmltYXRpb25zLCBvciBmaW5pc2hpbmcgcmVzb2x2ZXMgaW1tZWRpYXRlbHlcclxuXHRcdFx0XHRpZiAoIGVtcHR5IHx8IGRhdGFQcml2LmdldCggdGhpcywgXCJmaW5pc2hcIiApICkge1xyXG5cdFx0XHRcdFx0YW5pbS5zdG9wKCB0cnVlICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9O1xyXG5cdFx0XHRkb0FuaW1hdGlvbi5maW5pc2ggPSBkb0FuaW1hdGlvbjtcclxuXHJcblx0XHRyZXR1cm4gZW1wdHkgfHwgb3B0YWxsLnF1ZXVlID09PSBmYWxzZSA/XHJcblx0XHRcdHRoaXMuZWFjaCggZG9BbmltYXRpb24gKSA6XHJcblx0XHRcdHRoaXMucXVldWUoIG9wdGFsbC5xdWV1ZSwgZG9BbmltYXRpb24gKTtcclxuXHR9LFxyXG5cdHN0b3A6IGZ1bmN0aW9uKCB0eXBlLCBjbGVhclF1ZXVlLCBnb3RvRW5kICkge1xyXG5cdFx0dmFyIHN0b3BRdWV1ZSA9IGZ1bmN0aW9uKCBob29rcyApIHtcclxuXHRcdFx0dmFyIHN0b3AgPSBob29rcy5zdG9wO1xyXG5cdFx0XHRkZWxldGUgaG9va3Muc3RvcDtcclxuXHRcdFx0c3RvcCggZ290b0VuZCApO1xyXG5cdFx0fTtcclxuXHJcblx0XHRpZiAoIHR5cGVvZiB0eXBlICE9PSBcInN0cmluZ1wiICkge1xyXG5cdFx0XHRnb3RvRW5kID0gY2xlYXJRdWV1ZTtcclxuXHRcdFx0Y2xlYXJRdWV1ZSA9IHR5cGU7XHJcblx0XHRcdHR5cGUgPSB1bmRlZmluZWQ7XHJcblx0XHR9XHJcblx0XHRpZiAoIGNsZWFyUXVldWUgJiYgdHlwZSAhPT0gZmFsc2UgKSB7XHJcblx0XHRcdHRoaXMucXVldWUoIHR5cGUgfHwgXCJmeFwiLCBbXSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR2YXIgZGVxdWV1ZSA9IHRydWUsXHJcblx0XHRcdFx0aW5kZXggPSB0eXBlICE9IG51bGwgJiYgdHlwZSArIFwicXVldWVIb29rc1wiLFxyXG5cdFx0XHRcdHRpbWVycyA9IGpRdWVyeS50aW1lcnMsXHJcblx0XHRcdFx0ZGF0YSA9IGRhdGFQcml2LmdldCggdGhpcyApO1xyXG5cclxuXHRcdFx0aWYgKCBpbmRleCApIHtcclxuXHRcdFx0XHRpZiAoIGRhdGFbIGluZGV4IF0gJiYgZGF0YVsgaW5kZXggXS5zdG9wICkge1xyXG5cdFx0XHRcdFx0c3RvcFF1ZXVlKCBkYXRhWyBpbmRleCBdICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGZvciAoIGluZGV4IGluIGRhdGEgKSB7XHJcblx0XHRcdFx0XHRpZiAoIGRhdGFbIGluZGV4IF0gJiYgZGF0YVsgaW5kZXggXS5zdG9wICYmIHJydW4udGVzdCggaW5kZXggKSApIHtcclxuXHRcdFx0XHRcdFx0c3RvcFF1ZXVlKCBkYXRhWyBpbmRleCBdICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRmb3IgKCBpbmRleCA9IHRpbWVycy5sZW5ndGg7IGluZGV4LS07ICkge1xyXG5cdFx0XHRcdGlmICggdGltZXJzWyBpbmRleCBdLmVsZW0gPT09IHRoaXMgJiZcclxuXHRcdFx0XHRcdCggdHlwZSA9PSBudWxsIHx8IHRpbWVyc1sgaW5kZXggXS5xdWV1ZSA9PT0gdHlwZSApICkge1xyXG5cclxuXHRcdFx0XHRcdHRpbWVyc1sgaW5kZXggXS5hbmltLnN0b3AoIGdvdG9FbmQgKTtcclxuXHRcdFx0XHRcdGRlcXVldWUgPSBmYWxzZTtcclxuXHRcdFx0XHRcdHRpbWVycy5zcGxpY2UoIGluZGV4LCAxICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTdGFydCB0aGUgbmV4dCBpbiB0aGUgcXVldWUgaWYgdGhlIGxhc3Qgc3RlcCB3YXNuJ3QgZm9yY2VkLlxyXG5cdFx0XHQvLyBUaW1lcnMgY3VycmVudGx5IHdpbGwgY2FsbCB0aGVpciBjb21wbGV0ZSBjYWxsYmFja3MsIHdoaWNoXHJcblx0XHRcdC8vIHdpbGwgZGVxdWV1ZSBidXQgb25seSBpZiB0aGV5IHdlcmUgZ290b0VuZC5cclxuXHRcdFx0aWYgKCBkZXF1ZXVlIHx8ICFnb3RvRW5kICkge1xyXG5cdFx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XHJcblx0XHRcdH1cclxuXHRcdH0gKTtcclxuXHR9LFxyXG5cdGZpbmlzaDogZnVuY3Rpb24oIHR5cGUgKSB7XHJcblx0XHRpZiAoIHR5cGUgIT09IGZhbHNlICkge1xyXG5cdFx0XHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcclxuXHRcdFx0dmFyIGluZGV4LFxyXG5cdFx0XHRcdGRhdGEgPSBkYXRhUHJpdi5nZXQoIHRoaXMgKSxcclxuXHRcdFx0XHRxdWV1ZSA9IGRhdGFbIHR5cGUgKyBcInF1ZXVlXCIgXSxcclxuXHRcdFx0XHRob29rcyA9IGRhdGFbIHR5cGUgKyBcInF1ZXVlSG9va3NcIiBdLFxyXG5cdFx0XHRcdHRpbWVycyA9IGpRdWVyeS50aW1lcnMsXHJcblx0XHRcdFx0bGVuZ3RoID0gcXVldWUgPyBxdWV1ZS5sZW5ndGggOiAwO1xyXG5cclxuXHRcdFx0Ly8gRW5hYmxlIGZpbmlzaGluZyBmbGFnIG9uIHByaXZhdGUgZGF0YVxyXG5cdFx0XHRkYXRhLmZpbmlzaCA9IHRydWU7XHJcblxyXG5cdFx0XHQvLyBFbXB0eSB0aGUgcXVldWUgZmlyc3RcclxuXHRcdFx0alF1ZXJ5LnF1ZXVlKCB0aGlzLCB0eXBlLCBbXSApO1xyXG5cclxuXHRcdFx0aWYgKCBob29rcyAmJiBob29rcy5zdG9wICkge1xyXG5cdFx0XHRcdGhvb2tzLnN0b3AuY2FsbCggdGhpcywgdHJ1ZSApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBMb29rIGZvciBhbnkgYWN0aXZlIGFuaW1hdGlvbnMsIGFuZCBmaW5pc2ggdGhlbVxyXG5cdFx0XHRmb3IgKCBpbmRleCA9IHRpbWVycy5sZW5ndGg7IGluZGV4LS07ICkge1xyXG5cdFx0XHRcdGlmICggdGltZXJzWyBpbmRleCBdLmVsZW0gPT09IHRoaXMgJiYgdGltZXJzWyBpbmRleCBdLnF1ZXVlID09PSB0eXBlICkge1xyXG5cdFx0XHRcdFx0dGltZXJzWyBpbmRleCBdLmFuaW0uc3RvcCggdHJ1ZSApO1xyXG5cdFx0XHRcdFx0dGltZXJzLnNwbGljZSggaW5kZXgsIDEgKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIExvb2sgZm9yIGFueSBhbmltYXRpb25zIGluIHRoZSBvbGQgcXVldWUgYW5kIGZpbmlzaCB0aGVtXHJcblx0XHRcdGZvciAoIGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XHJcblx0XHRcdFx0aWYgKCBxdWV1ZVsgaW5kZXggXSAmJiBxdWV1ZVsgaW5kZXggXS5maW5pc2ggKSB7XHJcblx0XHRcdFx0XHRxdWV1ZVsgaW5kZXggXS5maW5pc2guY2FsbCggdGhpcyApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gVHVybiBvZmYgZmluaXNoaW5nIGZsYWdcclxuXHRcdFx0ZGVsZXRlIGRhdGEuZmluaXNoO1xyXG5cdFx0fSApO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmVhY2goIFsgXCJ0b2dnbGVcIiwgXCJzaG93XCIsIFwiaGlkZVwiIF0sIGZ1bmN0aW9uKCBpLCBuYW1lICkge1xyXG5cdHZhciBjc3NGbiA9IGpRdWVyeS5mblsgbmFtZSBdO1xyXG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xyXG5cdFx0cmV0dXJuIHNwZWVkID09IG51bGwgfHwgdHlwZW9mIHNwZWVkID09PSBcImJvb2xlYW5cIiA/XHJcblx0XHRcdGNzc0ZuLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKSA6XHJcblx0XHRcdHRoaXMuYW5pbWF0ZSggZ2VuRngoIG5hbWUsIHRydWUgKSwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKTtcclxuXHR9O1xyXG59ICk7XHJcblxyXG4vLyBHZW5lcmF0ZSBzaG9ydGN1dHMgZm9yIGN1c3RvbSBhbmltYXRpb25zXHJcbmpRdWVyeS5lYWNoKCB7XHJcblx0c2xpZGVEb3duOiBnZW5GeCggXCJzaG93XCIgKSxcclxuXHRzbGlkZVVwOiBnZW5GeCggXCJoaWRlXCIgKSxcclxuXHRzbGlkZVRvZ2dsZTogZ2VuRngoIFwidG9nZ2xlXCIgKSxcclxuXHRmYWRlSW46IHsgb3BhY2l0eTogXCJzaG93XCIgfSxcclxuXHRmYWRlT3V0OiB7IG9wYWNpdHk6IFwiaGlkZVwiIH0sXHJcblx0ZmFkZVRvZ2dsZTogeyBvcGFjaXR5OiBcInRvZ2dsZVwiIH1cclxufSwgZnVuY3Rpb24oIG5hbWUsIHByb3BzICkge1xyXG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xyXG5cdFx0cmV0dXJuIHRoaXMuYW5pbWF0ZSggcHJvcHMsIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICk7XHJcblx0fTtcclxufSApO1xyXG5cclxualF1ZXJ5LnRpbWVycyA9IFtdO1xyXG5qUXVlcnkuZngudGljayA9IGZ1bmN0aW9uKCkge1xyXG5cdHZhciB0aW1lcixcclxuXHRcdGkgPSAwLFxyXG5cdFx0dGltZXJzID0galF1ZXJ5LnRpbWVycztcclxuXHJcblx0ZnhOb3cgPSBqUXVlcnkubm93KCk7XHJcblxyXG5cdGZvciAoIDsgaSA8IHRpbWVycy5sZW5ndGg7IGkrKyApIHtcclxuXHRcdHRpbWVyID0gdGltZXJzWyBpIF07XHJcblxyXG5cdFx0Ly8gQ2hlY2tzIHRoZSB0aW1lciBoYXMgbm90IGFscmVhZHkgYmVlbiByZW1vdmVkXHJcblx0XHRpZiAoICF0aW1lcigpICYmIHRpbWVyc1sgaSBdID09PSB0aW1lciApIHtcclxuXHRcdFx0dGltZXJzLnNwbGljZSggaS0tLCAxICk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRpZiAoICF0aW1lcnMubGVuZ3RoICkge1xyXG5cdFx0alF1ZXJ5LmZ4LnN0b3AoKTtcclxuXHR9XHJcblx0ZnhOb3cgPSB1bmRlZmluZWQ7XHJcbn07XHJcblxyXG5qUXVlcnkuZngudGltZXIgPSBmdW5jdGlvbiggdGltZXIgKSB7XHJcblx0alF1ZXJ5LnRpbWVycy5wdXNoKCB0aW1lciApO1xyXG5cdGlmICggdGltZXIoKSApIHtcclxuXHRcdGpRdWVyeS5meC5zdGFydCgpO1xyXG5cdH0gZWxzZSB7XHJcblx0XHRqUXVlcnkudGltZXJzLnBvcCgpO1xyXG5cdH1cclxufTtcclxuXHJcbmpRdWVyeS5meC5pbnRlcnZhbCA9IDEzO1xyXG5qUXVlcnkuZnguc3RhcnQgPSBmdW5jdGlvbigpIHtcclxuXHRpZiAoICF0aW1lcklkICkge1xyXG5cdFx0dGltZXJJZCA9IHdpbmRvdy5zZXRJbnRlcnZhbCggalF1ZXJ5LmZ4LnRpY2ssIGpRdWVyeS5meC5pbnRlcnZhbCApO1xyXG5cdH1cclxufTtcclxuXHJcbmpRdWVyeS5meC5zdG9wID0gZnVuY3Rpb24oKSB7XHJcblx0d2luZG93LmNsZWFySW50ZXJ2YWwoIHRpbWVySWQgKTtcclxuXHJcblx0dGltZXJJZCA9IG51bGw7XHJcbn07XHJcblxyXG5qUXVlcnkuZnguc3BlZWRzID0ge1xyXG5cdHNsb3c6IDYwMCxcclxuXHRmYXN0OiAyMDAsXHJcblxyXG5cdC8vIERlZmF1bHQgc3BlZWRcclxuXHRfZGVmYXVsdDogNDAwXHJcbn07XHJcblxyXG5cclxuLy8gQmFzZWQgb2ZmIG9mIHRoZSBwbHVnaW4gYnkgQ2xpbnQgSGVsZmVycywgd2l0aCBwZXJtaXNzaW9uLlxyXG4vLyBodHRwOi8vd2ViLmFyY2hpdmUub3JnL3dlYi8yMDEwMDMyNDAxNDc0Ny9odHRwOi8vYmxpbmRzaWduYWxzLmNvbS9pbmRleC5waHAvMjAwOS8wNy9qcXVlcnktZGVsYXkvXHJcbmpRdWVyeS5mbi5kZWxheSA9IGZ1bmN0aW9uKCB0aW1lLCB0eXBlICkge1xyXG5cdHRpbWUgPSBqUXVlcnkuZnggPyBqUXVlcnkuZnguc3BlZWRzWyB0aW1lIF0gfHwgdGltZSA6IHRpbWU7XHJcblx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xyXG5cclxuXHRyZXR1cm4gdGhpcy5xdWV1ZSggdHlwZSwgZnVuY3Rpb24oIG5leHQsIGhvb2tzICkge1xyXG5cdFx0dmFyIHRpbWVvdXQgPSB3aW5kb3cuc2V0VGltZW91dCggbmV4dCwgdGltZSApO1xyXG5cdFx0aG9va3Muc3RvcCA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR3aW5kb3cuY2xlYXJUaW1lb3V0KCB0aW1lb3V0ICk7XHJcblx0XHR9O1xyXG5cdH0gKTtcclxufTtcclxuXHJcblxyXG4oIGZ1bmN0aW9uKCkge1xyXG5cdHZhciBpbnB1dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiaW5wdXRcIiApLFxyXG5cdFx0c2VsZWN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJzZWxlY3RcIiApLFxyXG5cdFx0b3B0ID0gc2VsZWN0LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcIm9wdGlvblwiICkgKTtcclxuXHJcblx0aW5wdXQudHlwZSA9IFwiY2hlY2tib3hcIjtcclxuXHJcblx0Ly8gU3VwcG9ydDogaU9TPD01LjEsIEFuZHJvaWQ8PTQuMitcclxuXHQvLyBEZWZhdWx0IHZhbHVlIGZvciBhIGNoZWNrYm94IHNob3VsZCBiZSBcIm9uXCJcclxuXHRzdXBwb3J0LmNoZWNrT24gPSBpbnB1dC52YWx1ZSAhPT0gXCJcIjtcclxuXHJcblx0Ly8gU3VwcG9ydDogSUU8PTExK1xyXG5cdC8vIE11c3QgYWNjZXNzIHNlbGVjdGVkSW5kZXggdG8gbWFrZSBkZWZhdWx0IG9wdGlvbnMgc2VsZWN0XHJcblx0c3VwcG9ydC5vcHRTZWxlY3RlZCA9IG9wdC5zZWxlY3RlZDtcclxuXHJcblx0Ly8gU3VwcG9ydDogQW5kcm9pZDw9Mi4zXHJcblx0Ly8gT3B0aW9ucyBpbnNpZGUgZGlzYWJsZWQgc2VsZWN0cyBhcmUgaW5jb3JyZWN0bHkgbWFya2VkIGFzIGRpc2FibGVkXHJcblx0c2VsZWN0LmRpc2FibGVkID0gdHJ1ZTtcclxuXHRzdXBwb3J0Lm9wdERpc2FibGVkID0gIW9wdC5kaXNhYmxlZDtcclxuXHJcblx0Ly8gU3VwcG9ydDogSUU8PTExK1xyXG5cdC8vIEFuIGlucHV0IGxvc2VzIGl0cyB2YWx1ZSBhZnRlciBiZWNvbWluZyBhIHJhZGlvXHJcblx0aW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKTtcclxuXHRpbnB1dC52YWx1ZSA9IFwidFwiO1xyXG5cdGlucHV0LnR5cGUgPSBcInJhZGlvXCI7XHJcblx0c3VwcG9ydC5yYWRpb1ZhbHVlID0gaW5wdXQudmFsdWUgPT09IFwidFwiO1xyXG59ICkoKTtcclxuXHJcblxyXG52YXIgYm9vbEhvb2ssXHJcblx0YXR0ckhhbmRsZSA9IGpRdWVyeS5leHByLmF0dHJIYW5kbGU7XHJcblxyXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XHJcblx0YXR0cjogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xyXG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgalF1ZXJ5LmF0dHIsIG5hbWUsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSApO1xyXG5cdH0sXHJcblxyXG5cdHJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBuYW1lICkge1xyXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XHJcblx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCB0aGlzLCBuYW1lICk7XHJcblx0XHR9ICk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5qUXVlcnkuZXh0ZW5kKCB7XHJcblx0YXR0cjogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlICkge1xyXG5cdFx0dmFyIHJldCwgaG9va3MsXHJcblx0XHRcdG5UeXBlID0gZWxlbS5ub2RlVHlwZTtcclxuXHJcblx0XHQvLyBEb24ndCBnZXQvc2V0IGF0dHJpYnV0ZXMgb24gdGV4dCwgY29tbWVudCBhbmQgYXR0cmlidXRlIG5vZGVzXHJcblx0XHRpZiAoIG5UeXBlID09PSAzIHx8IG5UeXBlID09PSA4IHx8IG5UeXBlID09PSAyICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRmFsbGJhY2sgdG8gcHJvcCB3aGVuIGF0dHJpYnV0ZXMgYXJlIG5vdCBzdXBwb3J0ZWRcclxuXHRcdGlmICggdHlwZW9mIGVsZW0uZ2V0QXR0cmlidXRlID09PSBcInVuZGVmaW5lZFwiICkge1xyXG5cdFx0XHRyZXR1cm4galF1ZXJ5LnByb3AoIGVsZW0sIG5hbWUsIHZhbHVlICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQWxsIGF0dHJpYnV0ZXMgYXJlIGxvd2VyY2FzZVxyXG5cdFx0Ly8gR3JhYiBuZWNlc3NhcnkgaG9vayBpZiBvbmUgaXMgZGVmaW5lZFxyXG5cdFx0aWYgKCBuVHlwZSAhPT0gMSB8fCAhalF1ZXJ5LmlzWE1MRG9jKCBlbGVtICkgKSB7XHJcblx0XHRcdG5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKCk7XHJcblx0XHRcdGhvb2tzID0galF1ZXJ5LmF0dHJIb29rc1sgbmFtZSBdIHx8XHJcblx0XHRcdFx0KCBqUXVlcnkuZXhwci5tYXRjaC5ib29sLnRlc3QoIG5hbWUgKSA/IGJvb2xIb29rIDogdW5kZWZpbmVkICk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xyXG5cdFx0XHRpZiAoIHZhbHVlID09PSBudWxsICkge1xyXG5cdFx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCBlbGVtLCBuYW1lICk7XHJcblx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAoIGhvb2tzICYmIFwic2V0XCIgaW4gaG9va3MgJiZcclxuXHRcdFx0XHQoIHJldCA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIG5hbWUgKSApICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdFx0cmV0dXJuIHJldDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIG5hbWUsIHZhbHVlICsgXCJcIiApO1xyXG5cdFx0XHRyZXR1cm4gdmFsdWU7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICYmICggcmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBuYW1lICkgKSAhPT0gbnVsbCApIHtcclxuXHRcdFx0cmV0dXJuIHJldDtcclxuXHRcdH1cclxuXHJcblx0XHRyZXQgPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBuYW1lICk7XHJcblxyXG5cdFx0Ly8gTm9uLWV4aXN0ZW50IGF0dHJpYnV0ZXMgcmV0dXJuIG51bGwsIHdlIG5vcm1hbGl6ZSB0byB1bmRlZmluZWRcclxuXHRcdHJldHVybiByZXQgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IHJldDtcclxuXHR9LFxyXG5cclxuXHRhdHRySG9va3M6IHtcclxuXHRcdHR5cGU6IHtcclxuXHRcdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XHJcblx0XHRcdFx0aWYgKCAhc3VwcG9ydC5yYWRpb1ZhbHVlICYmIHZhbHVlID09PSBcInJhZGlvXCIgJiZcclxuXHRcdFx0XHRcdGpRdWVyeS5ub2RlTmFtZSggZWxlbSwgXCJpbnB1dFwiICkgKSB7XHJcblx0XHRcdFx0XHR2YXIgdmFsID0gZWxlbS52YWx1ZTtcclxuXHRcdFx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCBcInR5cGVcIiwgdmFsdWUgKTtcclxuXHRcdFx0XHRcdGlmICggdmFsICkge1xyXG5cdFx0XHRcdFx0XHRlbGVtLnZhbHVlID0gdmFsO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0cmV0dXJuIHZhbHVlO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdHJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcclxuXHRcdHZhciBuYW1lLCBwcm9wTmFtZSxcclxuXHRcdFx0aSA9IDAsXHJcblx0XHRcdGF0dHJOYW1lcyA9IHZhbHVlICYmIHZhbHVlLm1hdGNoKCBybm90d2hpdGUgKTtcclxuXHJcblx0XHRpZiAoIGF0dHJOYW1lcyAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkge1xyXG5cdFx0XHR3aGlsZSAoICggbmFtZSA9IGF0dHJOYW1lc1sgaSsrIF0gKSApIHtcclxuXHRcdFx0XHRwcm9wTmFtZSA9IGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZTtcclxuXHJcblx0XHRcdFx0Ly8gQm9vbGVhbiBhdHRyaWJ1dGVzIGdldCBzcGVjaWFsIHRyZWF0bWVudCAoIzEwODcwKVxyXG5cdFx0XHRcdGlmICggalF1ZXJ5LmV4cHIubWF0Y2guYm9vbC50ZXN0KCBuYW1lICkgKSB7XHJcblxyXG5cdFx0XHRcdFx0Ly8gU2V0IGNvcnJlc3BvbmRpbmcgcHJvcGVydHkgdG8gZmFsc2VcclxuXHRcdFx0XHRcdGVsZW1bIHByb3BOYW1lIF0gPSBmYWxzZTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdGVsZW0ucmVtb3ZlQXR0cmlidXRlKCBuYW1lICk7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcbn0gKTtcclxuXHJcbi8vIEhvb2tzIGZvciBib29sZWFuIGF0dHJpYnV0ZXNcclxuYm9vbEhvb2sgPSB7XHJcblx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUsIG5hbWUgKSB7XHJcblx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcclxuXHJcblx0XHRcdC8vIFJlbW92ZSBib29sZWFuIGF0dHJpYnV0ZXMgd2hlbiBzZXQgdG8gZmFsc2VcclxuXHRcdFx0alF1ZXJ5LnJlbW92ZUF0dHIoIGVsZW0sIG5hbWUgKTtcclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCBuYW1lLCBuYW1lICk7XHJcblx0XHR9XHJcblx0XHRyZXR1cm4gbmFtZTtcclxuXHR9XHJcbn07XHJcbmpRdWVyeS5lYWNoKCBqUXVlcnkuZXhwci5tYXRjaC5ib29sLnNvdXJjZS5tYXRjaCggL1xcdysvZyApLCBmdW5jdGlvbiggaSwgbmFtZSApIHtcclxuXHR2YXIgZ2V0dGVyID0gYXR0ckhhbmRsZVsgbmFtZSBdIHx8IGpRdWVyeS5maW5kLmF0dHI7XHJcblxyXG5cdGF0dHJIYW5kbGVbIG5hbWUgXSA9IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcclxuXHRcdHZhciByZXQsIGhhbmRsZTtcclxuXHRcdGlmICggIWlzWE1MICkge1xyXG5cclxuXHRcdFx0Ly8gQXZvaWQgYW4gaW5maW5pdGUgbG9vcCBieSB0ZW1wb3JhcmlseSByZW1vdmluZyB0aGlzIGZ1bmN0aW9uIGZyb20gdGhlIGdldHRlclxyXG5cdFx0XHRoYW5kbGUgPSBhdHRySGFuZGxlWyBuYW1lIF07XHJcblx0XHRcdGF0dHJIYW5kbGVbIG5hbWUgXSA9IHJldDtcclxuXHRcdFx0cmV0ID0gZ2V0dGVyKCBlbGVtLCBuYW1lLCBpc1hNTCApICE9IG51bGwgP1xyXG5cdFx0XHRcdG5hbWUudG9Mb3dlckNhc2UoKSA6XHJcblx0XHRcdFx0bnVsbDtcclxuXHRcdFx0YXR0ckhhbmRsZVsgbmFtZSBdID0gaGFuZGxlO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHJldDtcclxuXHR9O1xyXG59ICk7XHJcblxyXG5cclxuXHJcblxyXG52YXIgcmZvY3VzYWJsZSA9IC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhfGJ1dHRvbikkL2ksXHJcblx0cmNsaWNrYWJsZSA9IC9eKD86YXxhcmVhKSQvaTtcclxuXHJcbmpRdWVyeS5mbi5leHRlbmQoIHtcclxuXHRwcm9wOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XHJcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBqUXVlcnkucHJvcCwgbmFtZSwgdmFsdWUsIGFyZ3VtZW50cy5sZW5ndGggPiAxICk7XHJcblx0fSxcclxuXHJcblx0cmVtb3ZlUHJvcDogZnVuY3Rpb24oIG5hbWUgKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcclxuXHRcdFx0ZGVsZXRlIHRoaXNbIGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZSBdO1xyXG5cdFx0fSApO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmV4dGVuZCgge1xyXG5cdHByb3A6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSApIHtcclxuXHRcdHZhciByZXQsIGhvb2tzLFxyXG5cdFx0XHRuVHlwZSA9IGVsZW0ubm9kZVR5cGU7XHJcblxyXG5cdFx0Ly8gRG9uJ3QgZ2V0L3NldCBwcm9wZXJ0aWVzIG9uIHRleHQsIGNvbW1lbnQgYW5kIGF0dHJpYnV0ZSBub2Rlc1xyXG5cdFx0aWYgKCBuVHlwZSA9PT0gMyB8fCBuVHlwZSA9PT0gOCB8fCBuVHlwZSA9PT0gMiApIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggblR5cGUgIT09IDEgfHwgIWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xyXG5cclxuXHRcdFx0Ly8gRml4IG5hbWUgYW5kIGF0dGFjaCBob29rc1xyXG5cdFx0XHRuYW1lID0galF1ZXJ5LnByb3BGaXhbIG5hbWUgXSB8fCBuYW1lO1xyXG5cdFx0XHRob29rcyA9IGpRdWVyeS5wcm9wSG9va3NbIG5hbWUgXTtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XHJcblx0XHRcdGlmICggaG9va3MgJiYgXCJzZXRcIiBpbiBob29rcyAmJlxyXG5cdFx0XHRcdCggcmV0ID0gaG9va3Muc2V0KCBlbGVtLCB2YWx1ZSwgbmFtZSApICkgIT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0XHRyZXR1cm4gcmV0O1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRyZXR1cm4gKCBlbGVtWyBuYW1lIF0gPSB2YWx1ZSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJiAoIHJldCA9IGhvb2tzLmdldCggZWxlbSwgbmFtZSApICkgIT09IG51bGwgKSB7XHJcblx0XHRcdHJldHVybiByZXQ7XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGVsZW1bIG5hbWUgXTtcclxuXHR9LFxyXG5cclxuXHRwcm9wSG9va3M6IHtcclxuXHRcdHRhYkluZGV4OiB7XHJcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblxyXG5cdFx0XHRcdC8vIGVsZW0udGFiSW5kZXggZG9lc24ndCBhbHdheXMgcmV0dXJuIHRoZVxyXG5cdFx0XHRcdC8vIGNvcnJlY3QgdmFsdWUgd2hlbiBpdCBoYXNuJ3QgYmVlbiBleHBsaWNpdGx5IHNldFxyXG5cdFx0XHRcdC8vIGh0dHA6Ly9mbHVpZHByb2plY3Qub3JnL2Jsb2cvMjAwOC8wMS8wOS9nZXR0aW5nLXNldHRpbmctYW5kLXJlbW92aW5nLXRhYmluZGV4LXZhbHVlcy13aXRoLWphdmFzY3JpcHQvXHJcblx0XHRcdFx0Ly8gVXNlIHByb3BlciBhdHRyaWJ1dGUgcmV0cmlldmFsKCMxMjA3MilcclxuXHRcdFx0XHR2YXIgdGFiaW5kZXggPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBcInRhYmluZGV4XCIgKTtcclxuXHJcblx0XHRcdFx0cmV0dXJuIHRhYmluZGV4ID9cclxuXHRcdFx0XHRcdHBhcnNlSW50KCB0YWJpbmRleCwgMTAgKSA6XHJcblx0XHRcdFx0XHRyZm9jdXNhYmxlLnRlc3QoIGVsZW0ubm9kZU5hbWUgKSB8fFxyXG5cdFx0XHRcdFx0XHRyY2xpY2thYmxlLnRlc3QoIGVsZW0ubm9kZU5hbWUgKSAmJiBlbGVtLmhyZWYgP1xyXG5cdFx0XHRcdFx0XHRcdDAgOlxyXG5cdFx0XHRcdFx0XHRcdC0xO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fSxcclxuXHJcblx0cHJvcEZpeDoge1xyXG5cdFx0XCJmb3JcIjogXCJodG1sRm9yXCIsXHJcblx0XHRcImNsYXNzXCI6IFwiY2xhc3NOYW1lXCJcclxuXHR9XHJcbn0gKTtcclxuXHJcbi8vIFN1cHBvcnQ6IElFIDw9MTEgb25seVxyXG4vLyBBY2Nlc3NpbmcgdGhlIHNlbGVjdGVkSW5kZXggcHJvcGVydHlcclxuLy8gZm9yY2VzIHRoZSBicm93c2VyIHRvIHJlc3BlY3Qgc2V0dGluZyBzZWxlY3RlZFxyXG4vLyBvbiB0aGUgb3B0aW9uXHJcbi8vIFRoZSBnZXR0ZXIgZW5zdXJlcyBhIGRlZmF1bHQgb3B0aW9uIGlzIHNlbGVjdGVkXHJcbi8vIHdoZW4gaW4gYW4gb3B0Z3JvdXBcclxuaWYgKCAhc3VwcG9ydC5vcHRTZWxlY3RlZCApIHtcclxuXHRqUXVlcnkucHJvcEhvb2tzLnNlbGVjdGVkID0ge1xyXG5cdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRcdFx0dmFyIHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZTtcclxuXHRcdFx0aWYgKCBwYXJlbnQgJiYgcGFyZW50LnBhcmVudE5vZGUgKSB7XHJcblx0XHRcdFx0cGFyZW50LnBhcmVudE5vZGUuc2VsZWN0ZWRJbmRleDtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gbnVsbDtcclxuXHRcdH0sXHJcblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdFx0XHR2YXIgcGFyZW50ID0gZWxlbS5wYXJlbnROb2RlO1xyXG5cdFx0XHRpZiAoIHBhcmVudCApIHtcclxuXHRcdFx0XHRwYXJlbnQuc2VsZWN0ZWRJbmRleDtcclxuXHJcblx0XHRcdFx0aWYgKCBwYXJlbnQucGFyZW50Tm9kZSApIHtcclxuXHRcdFx0XHRcdHBhcmVudC5wYXJlbnROb2RlLnNlbGVjdGVkSW5kZXg7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fTtcclxufVxyXG5cclxualF1ZXJ5LmVhY2goIFtcclxuXHRcInRhYkluZGV4XCIsXHJcblx0XCJyZWFkT25seVwiLFxyXG5cdFwibWF4TGVuZ3RoXCIsXHJcblx0XCJjZWxsU3BhY2luZ1wiLFxyXG5cdFwiY2VsbFBhZGRpbmdcIixcclxuXHRcInJvd1NwYW5cIixcclxuXHRcImNvbFNwYW5cIixcclxuXHRcInVzZU1hcFwiLFxyXG5cdFwiZnJhbWVCb3JkZXJcIixcclxuXHRcImNvbnRlbnRFZGl0YWJsZVwiXHJcbl0sIGZ1bmN0aW9uKCkge1xyXG5cdGpRdWVyeS5wcm9wRml4WyB0aGlzLnRvTG93ZXJDYXNlKCkgXSA9IHRoaXM7XHJcbn0gKTtcclxuXHJcblxyXG5cclxuXHJcbnZhciByY2xhc3MgPSAvW1xcdFxcclxcblxcZl0vZztcclxuXHJcbmZ1bmN0aW9uIGdldENsYXNzKCBlbGVtICkge1xyXG5cdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSAmJiBlbGVtLmdldEF0dHJpYnV0ZSggXCJjbGFzc1wiICkgfHwgXCJcIjtcclxufVxyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdGFkZENsYXNzOiBmdW5jdGlvbiggdmFsdWUgKSB7XHJcblx0XHR2YXIgY2xhc3NlcywgZWxlbSwgY3VyLCBjdXJWYWx1ZSwgY2xhenosIGosIGZpbmFsVmFsdWUsXHJcblx0XHRcdGkgPSAwO1xyXG5cclxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XHJcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBqICkge1xyXG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLmFkZENsYXNzKCB2YWx1ZS5jYWxsKCB0aGlzLCBqLCBnZXRDbGFzcyggdGhpcyApICkgKTtcclxuXHRcdFx0fSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmIHZhbHVlICkge1xyXG5cdFx0XHRjbGFzc2VzID0gdmFsdWUubWF0Y2goIHJub3R3aGl0ZSApIHx8IFtdO1xyXG5cclxuXHRcdFx0d2hpbGUgKCAoIGVsZW0gPSB0aGlzWyBpKysgXSApICkge1xyXG5cdFx0XHRcdGN1clZhbHVlID0gZ2V0Q2xhc3MoIGVsZW0gKTtcclxuXHRcdFx0XHRjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmXHJcblx0XHRcdFx0XHQoIFwiIFwiICsgY3VyVmFsdWUgKyBcIiBcIiApLnJlcGxhY2UoIHJjbGFzcywgXCIgXCIgKTtcclxuXHJcblx0XHRcdFx0aWYgKCBjdXIgKSB7XHJcblx0XHRcdFx0XHRqID0gMDtcclxuXHRcdFx0XHRcdHdoaWxlICggKCBjbGF6eiA9IGNsYXNzZXNbIGorKyBdICkgKSB7XHJcblx0XHRcdFx0XHRcdGlmICggY3VyLmluZGV4T2YoIFwiIFwiICsgY2xhenogKyBcIiBcIiApIDwgMCApIHtcclxuXHRcdFx0XHRcdFx0XHRjdXIgKz0gY2xhenogKyBcIiBcIjtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdC8vIE9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXHJcblx0XHRcdFx0XHRmaW5hbFZhbHVlID0galF1ZXJ5LnRyaW0oIGN1ciApO1xyXG5cdFx0XHRcdFx0aWYgKCBjdXJWYWx1ZSAhPT0gZmluYWxWYWx1ZSApIHtcclxuXHRcdFx0XHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIFwiY2xhc3NcIiwgZmluYWxWYWx1ZSApO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH0sXHJcblxyXG5cdHJlbW92ZUNsYXNzOiBmdW5jdGlvbiggdmFsdWUgKSB7XHJcblx0XHR2YXIgY2xhc3NlcywgZWxlbSwgY3VyLCBjdXJWYWx1ZSwgY2xhenosIGosIGZpbmFsVmFsdWUsXHJcblx0XHRcdGkgPSAwO1xyXG5cclxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XHJcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBqICkge1xyXG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnJlbW92ZUNsYXNzKCB2YWx1ZS5jYWxsKCB0aGlzLCBqLCBnZXRDbGFzcyggdGhpcyApICkgKTtcclxuXHRcdFx0fSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggIWFyZ3VtZW50cy5sZW5ndGggKSB7XHJcblx0XHRcdHJldHVybiB0aGlzLmF0dHIoIFwiY2xhc3NcIiwgXCJcIiApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmIHZhbHVlICkge1xyXG5cdFx0XHRjbGFzc2VzID0gdmFsdWUubWF0Y2goIHJub3R3aGl0ZSApIHx8IFtdO1xyXG5cclxuXHRcdFx0d2hpbGUgKCAoIGVsZW0gPSB0aGlzWyBpKysgXSApICkge1xyXG5cdFx0XHRcdGN1clZhbHVlID0gZ2V0Q2xhc3MoIGVsZW0gKTtcclxuXHJcblx0XHRcdFx0Ly8gVGhpcyBleHByZXNzaW9uIGlzIGhlcmUgZm9yIGJldHRlciBjb21wcmVzc2liaWxpdHkgKHNlZSBhZGRDbGFzcylcclxuXHRcdFx0XHRjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmXHJcblx0XHRcdFx0XHQoIFwiIFwiICsgY3VyVmFsdWUgKyBcIiBcIiApLnJlcGxhY2UoIHJjbGFzcywgXCIgXCIgKTtcclxuXHJcblx0XHRcdFx0aWYgKCBjdXIgKSB7XHJcblx0XHRcdFx0XHRqID0gMDtcclxuXHRcdFx0XHRcdHdoaWxlICggKCBjbGF6eiA9IGNsYXNzZXNbIGorKyBdICkgKSB7XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBSZW1vdmUgKmFsbCogaW5zdGFuY2VzXHJcblx0XHRcdFx0XHRcdHdoaWxlICggY3VyLmluZGV4T2YoIFwiIFwiICsgY2xhenogKyBcIiBcIiApID4gLTEgKSB7XHJcblx0XHRcdFx0XHRcdFx0Y3VyID0gY3VyLnJlcGxhY2UoIFwiIFwiICsgY2xhenogKyBcIiBcIiwgXCIgXCIgKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdC8vIE9ubHkgYXNzaWduIGlmIGRpZmZlcmVudCB0byBhdm9pZCB1bm5lZWRlZCByZW5kZXJpbmcuXHJcblx0XHRcdFx0XHRmaW5hbFZhbHVlID0galF1ZXJ5LnRyaW0oIGN1ciApO1xyXG5cdFx0XHRcdFx0aWYgKCBjdXJWYWx1ZSAhPT0gZmluYWxWYWx1ZSApIHtcclxuXHRcdFx0XHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIFwiY2xhc3NcIiwgZmluYWxWYWx1ZSApO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH0sXHJcblxyXG5cdHRvZ2dsZUNsYXNzOiBmdW5jdGlvbiggdmFsdWUsIHN0YXRlVmFsICkge1xyXG5cdFx0dmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XHJcblxyXG5cdFx0aWYgKCB0eXBlb2Ygc3RhdGVWYWwgPT09IFwiYm9vbGVhblwiICYmIHR5cGUgPT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdHJldHVybiBzdGF0ZVZhbCA/IHRoaXMuYWRkQ2xhc3MoIHZhbHVlICkgOiB0aGlzLnJlbW92ZUNsYXNzKCB2YWx1ZSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XHJcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkge1xyXG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnRvZ2dsZUNsYXNzKFxyXG5cdFx0XHRcdFx0dmFsdWUuY2FsbCggdGhpcywgaSwgZ2V0Q2xhc3MoIHRoaXMgKSwgc3RhdGVWYWwgKSxcclxuXHRcdFx0XHRcdHN0YXRlVmFsXHJcblx0XHRcdFx0KTtcclxuXHRcdFx0fSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR2YXIgY2xhc3NOYW1lLCBpLCBzZWxmLCBjbGFzc05hbWVzO1xyXG5cclxuXHRcdFx0aWYgKCB0eXBlID09PSBcInN0cmluZ1wiICkge1xyXG5cclxuXHRcdFx0XHQvLyBUb2dnbGUgaW5kaXZpZHVhbCBjbGFzcyBuYW1lc1xyXG5cdFx0XHRcdGkgPSAwO1xyXG5cdFx0XHRcdHNlbGYgPSBqUXVlcnkoIHRoaXMgKTtcclxuXHRcdFx0XHRjbGFzc05hbWVzID0gdmFsdWUubWF0Y2goIHJub3R3aGl0ZSApIHx8IFtdO1xyXG5cclxuXHRcdFx0XHR3aGlsZSAoICggY2xhc3NOYW1lID0gY2xhc3NOYW1lc1sgaSsrIF0gKSApIHtcclxuXHJcblx0XHRcdFx0XHQvLyBDaGVjayBlYWNoIGNsYXNzTmFtZSBnaXZlbiwgc3BhY2Ugc2VwYXJhdGVkIGxpc3RcclxuXHRcdFx0XHRcdGlmICggc2VsZi5oYXNDbGFzcyggY2xhc3NOYW1lICkgKSB7XHJcblx0XHRcdFx0XHRcdHNlbGYucmVtb3ZlQ2xhc3MoIGNsYXNzTmFtZSApO1xyXG5cdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0c2VsZi5hZGRDbGFzcyggY2xhc3NOYW1lICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gVG9nZ2xlIHdob2xlIGNsYXNzIG5hbWVcclxuXHRcdFx0fSBlbHNlIGlmICggdmFsdWUgPT09IHVuZGVmaW5lZCB8fCB0eXBlID09PSBcImJvb2xlYW5cIiApIHtcclxuXHRcdFx0XHRjbGFzc05hbWUgPSBnZXRDbGFzcyggdGhpcyApO1xyXG5cdFx0XHRcdGlmICggY2xhc3NOYW1lICkge1xyXG5cclxuXHRcdFx0XHRcdC8vIFN0b3JlIGNsYXNzTmFtZSBpZiBzZXRcclxuXHRcdFx0XHRcdGRhdGFQcml2LnNldCggdGhpcywgXCJfX2NsYXNzTmFtZV9fXCIsIGNsYXNzTmFtZSApO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gSWYgdGhlIGVsZW1lbnQgaGFzIGEgY2xhc3MgbmFtZSBvciBpZiB3ZSdyZSBwYXNzZWQgYGZhbHNlYCxcclxuXHRcdFx0XHQvLyB0aGVuIHJlbW92ZSB0aGUgd2hvbGUgY2xhc3NuYW1lIChpZiB0aGVyZSB3YXMgb25lLCB0aGUgYWJvdmUgc2F2ZWQgaXQpLlxyXG5cdFx0XHRcdC8vIE90aGVyd2lzZSBicmluZyBiYWNrIHdoYXRldmVyIHdhcyBwcmV2aW91c2x5IHNhdmVkIChpZiBhbnl0aGluZyksXHJcblx0XHRcdFx0Ly8gZmFsbGluZyBiYWNrIHRvIHRoZSBlbXB0eSBzdHJpbmcgaWYgbm90aGluZyB3YXMgc3RvcmVkLlxyXG5cdFx0XHRcdGlmICggdGhpcy5zZXRBdHRyaWJ1dGUgKSB7XHJcblx0XHRcdFx0XHR0aGlzLnNldEF0dHJpYnV0ZSggXCJjbGFzc1wiLFxyXG5cdFx0XHRcdFx0XHRjbGFzc05hbWUgfHwgdmFsdWUgPT09IGZhbHNlID9cclxuXHRcdFx0XHRcdFx0XCJcIiA6XHJcblx0XHRcdFx0XHRcdGRhdGFQcml2LmdldCggdGhpcywgXCJfX2NsYXNzTmFtZV9fXCIgKSB8fCBcIlwiXHJcblx0XHRcdFx0XHQpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fSApO1xyXG5cdH0sXHJcblxyXG5cdGhhc0NsYXNzOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XHJcblx0XHR2YXIgY2xhc3NOYW1lLCBlbGVtLFxyXG5cdFx0XHRpID0gMDtcclxuXHJcblx0XHRjbGFzc05hbWUgPSBcIiBcIiArIHNlbGVjdG9yICsgXCIgXCI7XHJcblx0XHR3aGlsZSAoICggZWxlbSA9IHRoaXNbIGkrKyBdICkgKSB7XHJcblx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSAmJlxyXG5cdFx0XHRcdCggXCIgXCIgKyBnZXRDbGFzcyggZWxlbSApICsgXCIgXCIgKS5yZXBsYWNlKCByY2xhc3MsIFwiIFwiIClcclxuXHRcdFx0XHRcdC5pbmRleE9mKCBjbGFzc05hbWUgKSA+IC0xXHJcblx0XHRcdCkge1xyXG5cdFx0XHRcdHJldHVybiB0cnVlO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGZhbHNlO1xyXG5cdH1cclxufSApO1xyXG5cclxuXHJcblxyXG5cclxudmFyIHJyZXR1cm4gPSAvXFxyL2csXHJcblx0cnNwYWNlcyA9IC9bXFx4MjBcXHRcXHJcXG5cXGZdKy9nO1xyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdHZhbDogZnVuY3Rpb24oIHZhbHVlICkge1xyXG5cdFx0dmFyIGhvb2tzLCByZXQsIGlzRnVuY3Rpb24sXHJcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF07XHJcblxyXG5cdFx0aWYgKCAhYXJndW1lbnRzLmxlbmd0aCApIHtcclxuXHRcdFx0aWYgKCBlbGVtICkge1xyXG5cdFx0XHRcdGhvb2tzID0galF1ZXJ5LnZhbEhvb2tzWyBlbGVtLnR5cGUgXSB8fFxyXG5cdFx0XHRcdFx0alF1ZXJ5LnZhbEhvb2tzWyBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgXTtcclxuXHJcblx0XHRcdFx0aWYgKCBob29rcyAmJlxyXG5cdFx0XHRcdFx0XCJnZXRcIiBpbiBob29rcyAmJlxyXG5cdFx0XHRcdFx0KCByZXQgPSBob29rcy5nZXQoIGVsZW0sIFwidmFsdWVcIiApICkgIT09IHVuZGVmaW5lZFxyXG5cdFx0XHRcdCkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIHJldDtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdHJldCA9IGVsZW0udmFsdWU7XHJcblxyXG5cdFx0XHRcdHJldHVybiB0eXBlb2YgcmV0ID09PSBcInN0cmluZ1wiID9cclxuXHJcblx0XHRcdFx0XHQvLyBIYW5kbGUgbW9zdCBjb21tb24gc3RyaW5nIGNhc2VzXHJcblx0XHRcdFx0XHRyZXQucmVwbGFjZSggcnJldHVybiwgXCJcIiApIDpcclxuXHJcblx0XHRcdFx0XHQvLyBIYW5kbGUgY2FzZXMgd2hlcmUgdmFsdWUgaXMgbnVsbC91bmRlZiBvciBudW1iZXJcclxuXHRcdFx0XHRcdHJldCA9PSBudWxsID8gXCJcIiA6IHJldDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlzRnVuY3Rpb24gPSBqUXVlcnkuaXNGdW5jdGlvbiggdmFsdWUgKTtcclxuXHJcblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbiggaSApIHtcclxuXHRcdFx0dmFyIHZhbDtcclxuXHJcblx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSAhPT0gMSApIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdGlmICggaXNGdW5jdGlvbiApIHtcclxuXHRcdFx0XHR2YWwgPSB2YWx1ZS5jYWxsKCB0aGlzLCBpLCBqUXVlcnkoIHRoaXMgKS52YWwoKSApO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdHZhbCA9IHZhbHVlO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBUcmVhdCBudWxsL3VuZGVmaW5lZCBhcyBcIlwiOyBjb252ZXJ0IG51bWJlcnMgdG8gc3RyaW5nXHJcblx0XHRcdGlmICggdmFsID09IG51bGwgKSB7XHJcblx0XHRcdFx0dmFsID0gXCJcIjtcclxuXHJcblx0XHRcdH0gZWxzZSBpZiAoIHR5cGVvZiB2YWwgPT09IFwibnVtYmVyXCIgKSB7XHJcblx0XHRcdFx0dmFsICs9IFwiXCI7XHJcblxyXG5cdFx0XHR9IGVsc2UgaWYgKCBqUXVlcnkuaXNBcnJheSggdmFsICkgKSB7XHJcblx0XHRcdFx0dmFsID0galF1ZXJ5Lm1hcCggdmFsLCBmdW5jdGlvbiggdmFsdWUgKSB7XHJcblx0XHRcdFx0XHRyZXR1cm4gdmFsdWUgPT0gbnVsbCA/IFwiXCIgOiB2YWx1ZSArIFwiXCI7XHJcblx0XHRcdFx0fSApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRob29rcyA9IGpRdWVyeS52YWxIb29rc1sgdGhpcy50eXBlIF0gfHwgalF1ZXJ5LnZhbEhvb2tzWyB0aGlzLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgXTtcclxuXHJcblx0XHRcdC8vIElmIHNldCByZXR1cm5zIHVuZGVmaW5lZCwgZmFsbCBiYWNrIHRvIG5vcm1hbCBzZXR0aW5nXHJcblx0XHRcdGlmICggIWhvb2tzIHx8ICEoIFwic2V0XCIgaW4gaG9va3MgKSB8fCBob29rcy5zZXQoIHRoaXMsIHZhbCwgXCJ2YWx1ZVwiICkgPT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0XHR0aGlzLnZhbHVlID0gdmFsO1xyXG5cdFx0XHR9XHJcblx0XHR9ICk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5qUXVlcnkuZXh0ZW5kKCB7XHJcblx0dmFsSG9va3M6IHtcclxuXHRcdG9wdGlvbjoge1xyXG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cclxuXHRcdFx0XHR2YXIgdmFsID0galF1ZXJ5LmZpbmQuYXR0ciggZWxlbSwgXCJ2YWx1ZVwiICk7XHJcblx0XHRcdFx0cmV0dXJuIHZhbCAhPSBudWxsID9cclxuXHRcdFx0XHRcdHZhbCA6XHJcblxyXG5cdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUxMC0xMStcclxuXHRcdFx0XHRcdC8vIG9wdGlvbi50ZXh0IHRocm93cyBleGNlcHRpb25zICgjMTQ2ODYsICMxNDg1OClcclxuXHRcdFx0XHRcdC8vIFN0cmlwIGFuZCBjb2xsYXBzZSB3aGl0ZXNwYWNlXHJcblx0XHRcdFx0XHQvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnLyNzdHJpcC1hbmQtY29sbGFwc2Utd2hpdGVzcGFjZVxyXG5cdFx0XHRcdFx0alF1ZXJ5LnRyaW0oIGpRdWVyeS50ZXh0KCBlbGVtICkgKS5yZXBsYWNlKCByc3BhY2VzLCBcIiBcIiApO1xyXG5cdFx0XHR9XHJcblx0XHR9LFxyXG5cdFx0c2VsZWN0OiB7XHJcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdFx0dmFyIHZhbHVlLCBvcHRpb24sXHJcblx0XHRcdFx0XHRvcHRpb25zID0gZWxlbS5vcHRpb25zLFxyXG5cdFx0XHRcdFx0aW5kZXggPSBlbGVtLnNlbGVjdGVkSW5kZXgsXHJcblx0XHRcdFx0XHRvbmUgPSBlbGVtLnR5cGUgPT09IFwic2VsZWN0LW9uZVwiIHx8IGluZGV4IDwgMCxcclxuXHRcdFx0XHRcdHZhbHVlcyA9IG9uZSA/IG51bGwgOiBbXSxcclxuXHRcdFx0XHRcdG1heCA9IG9uZSA/IGluZGV4ICsgMSA6IG9wdGlvbnMubGVuZ3RoLFxyXG5cdFx0XHRcdFx0aSA9IGluZGV4IDwgMCA/XHJcblx0XHRcdFx0XHRcdG1heCA6XHJcblx0XHRcdFx0XHRcdG9uZSA/IGluZGV4IDogMDtcclxuXHJcblx0XHRcdFx0Ly8gTG9vcCB0aHJvdWdoIGFsbCB0aGUgc2VsZWN0ZWQgb3B0aW9uc1xyXG5cdFx0XHRcdGZvciAoIDsgaSA8IG1heDsgaSsrICkge1xyXG5cdFx0XHRcdFx0b3B0aW9uID0gb3B0aW9uc1sgaSBdO1xyXG5cclxuXHRcdFx0XHRcdC8vIElFOC05IGRvZXNuJ3QgdXBkYXRlIHNlbGVjdGVkIGFmdGVyIGZvcm0gcmVzZXQgKCMyNTUxKVxyXG5cdFx0XHRcdFx0aWYgKCAoIG9wdGlvbi5zZWxlY3RlZCB8fCBpID09PSBpbmRleCApICYmXHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIERvbid0IHJldHVybiBvcHRpb25zIHRoYXQgYXJlIGRpc2FibGVkIG9yIGluIGEgZGlzYWJsZWQgb3B0Z3JvdXBcclxuXHRcdFx0XHRcdFx0XHQoIHN1cHBvcnQub3B0RGlzYWJsZWQgP1xyXG5cdFx0XHRcdFx0XHRcdFx0IW9wdGlvbi5kaXNhYmxlZCA6IG9wdGlvbi5nZXRBdHRyaWJ1dGUoIFwiZGlzYWJsZWRcIiApID09PSBudWxsICkgJiZcclxuXHRcdFx0XHRcdFx0XHQoICFvcHRpb24ucGFyZW50Tm9kZS5kaXNhYmxlZCB8fFxyXG5cdFx0XHRcdFx0XHRcdFx0IWpRdWVyeS5ub2RlTmFtZSggb3B0aW9uLnBhcmVudE5vZGUsIFwib3B0Z3JvdXBcIiApICkgKSB7XHJcblxyXG5cdFx0XHRcdFx0XHQvLyBHZXQgdGhlIHNwZWNpZmljIHZhbHVlIGZvciB0aGUgb3B0aW9uXHJcblx0XHRcdFx0XHRcdHZhbHVlID0galF1ZXJ5KCBvcHRpb24gKS52YWwoKTtcclxuXHJcblx0XHRcdFx0XHRcdC8vIFdlIGRvbid0IG5lZWQgYW4gYXJyYXkgZm9yIG9uZSBzZWxlY3RzXHJcblx0XHRcdFx0XHRcdGlmICggb25lICkge1xyXG5cdFx0XHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdFx0Ly8gTXVsdGktU2VsZWN0cyByZXR1cm4gYW4gYXJyYXlcclxuXHRcdFx0XHRcdFx0dmFsdWVzLnB1c2goIHZhbHVlICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRyZXR1cm4gdmFsdWVzO1xyXG5cdFx0XHR9LFxyXG5cclxuXHRcdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XHJcblx0XHRcdFx0dmFyIG9wdGlvblNldCwgb3B0aW9uLFxyXG5cdFx0XHRcdFx0b3B0aW9ucyA9IGVsZW0ub3B0aW9ucyxcclxuXHRcdFx0XHRcdHZhbHVlcyA9IGpRdWVyeS5tYWtlQXJyYXkoIHZhbHVlICksXHJcblx0XHRcdFx0XHRpID0gb3B0aW9ucy5sZW5ndGg7XHJcblxyXG5cdFx0XHRcdHdoaWxlICggaS0tICkge1xyXG5cdFx0XHRcdFx0b3B0aW9uID0gb3B0aW9uc1sgaSBdO1xyXG5cdFx0XHRcdFx0aWYgKCBvcHRpb24uc2VsZWN0ZWQgPVxyXG5cdFx0XHRcdFx0XHRqUXVlcnkuaW5BcnJheSggalF1ZXJ5LnZhbEhvb2tzLm9wdGlvbi5nZXQoIG9wdGlvbiApLCB2YWx1ZXMgKSA+IC0xXHJcblx0XHRcdFx0XHQpIHtcclxuXHRcdFx0XHRcdFx0b3B0aW9uU2V0ID0gdHJ1ZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIEZvcmNlIGJyb3dzZXJzIHRvIGJlaGF2ZSBjb25zaXN0ZW50bHkgd2hlbiBub24tbWF0Y2hpbmcgdmFsdWUgaXMgc2V0XHJcblx0XHRcdFx0aWYgKCAhb3B0aW9uU2V0ICkge1xyXG5cdFx0XHRcdFx0ZWxlbS5zZWxlY3RlZEluZGV4ID0gLTE7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdHJldHVybiB2YWx1ZXM7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9XHJcbn0gKTtcclxuXHJcbi8vIFJhZGlvcyBhbmQgY2hlY2tib3hlcyBnZXR0ZXIvc2V0dGVyXHJcbmpRdWVyeS5lYWNoKCBbIFwicmFkaW9cIiwgXCJjaGVja2JveFwiIF0sIGZ1bmN0aW9uKCkge1xyXG5cdGpRdWVyeS52YWxIb29rc1sgdGhpcyBdID0ge1xyXG5cdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XHJcblx0XHRcdGlmICggalF1ZXJ5LmlzQXJyYXkoIHZhbHVlICkgKSB7XHJcblx0XHRcdFx0cmV0dXJuICggZWxlbS5jaGVja2VkID0galF1ZXJ5LmluQXJyYXkoIGpRdWVyeSggZWxlbSApLnZhbCgpLCB2YWx1ZSApID4gLTEgKTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH07XHJcblx0aWYgKCAhc3VwcG9ydC5jaGVja09uICkge1xyXG5cdFx0alF1ZXJ5LnZhbEhvb2tzWyB0aGlzIF0uZ2V0ID0gZnVuY3Rpb24oIGVsZW0gKSB7XHJcblx0XHRcdHJldHVybiBlbGVtLmdldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiICkgPT09IG51bGwgPyBcIm9uXCIgOiBlbGVtLnZhbHVlO1xyXG5cdFx0fTtcclxuXHR9XHJcbn0gKTtcclxuXHJcblxyXG5cclxuXHJcbi8vIFJldHVybiBqUXVlcnkgZm9yIGF0dHJpYnV0ZXMtb25seSBpbmNsdXNpb25cclxuXHJcblxyXG52YXIgcmZvY3VzTW9ycGggPSAvXig/OmZvY3VzaW5mb2N1c3xmb2N1c291dGJsdXIpJC87XHJcblxyXG5qUXVlcnkuZXh0ZW5kKCBqUXVlcnkuZXZlbnQsIHtcclxuXHJcblx0dHJpZ2dlcjogZnVuY3Rpb24oIGV2ZW50LCBkYXRhLCBlbGVtLCBvbmx5SGFuZGxlcnMgKSB7XHJcblxyXG5cdFx0dmFyIGksIGN1ciwgdG1wLCBidWJibGVUeXBlLCBvbnR5cGUsIGhhbmRsZSwgc3BlY2lhbCxcclxuXHRcdFx0ZXZlbnRQYXRoID0gWyBlbGVtIHx8IGRvY3VtZW50IF0sXHJcblx0XHRcdHR5cGUgPSBoYXNPd24uY2FsbCggZXZlbnQsIFwidHlwZVwiICkgPyBldmVudC50eXBlIDogZXZlbnQsXHJcblx0XHRcdG5hbWVzcGFjZXMgPSBoYXNPd24uY2FsbCggZXZlbnQsIFwibmFtZXNwYWNlXCIgKSA/IGV2ZW50Lm5hbWVzcGFjZS5zcGxpdCggXCIuXCIgKSA6IFtdO1xyXG5cclxuXHRcdGN1ciA9IHRtcCA9IGVsZW0gPSBlbGVtIHx8IGRvY3VtZW50O1xyXG5cclxuXHRcdC8vIERvbid0IGRvIGV2ZW50cyBvbiB0ZXh0IGFuZCBjb21tZW50IG5vZGVzXHJcblx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDMgfHwgZWxlbS5ub2RlVHlwZSA9PT0gOCApIHtcclxuXHRcdFx0cmV0dXJuO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIGZvY3VzL2JsdXIgbW9ycGhzIHRvIGZvY3VzaW4vb3V0OyBlbnN1cmUgd2UncmUgbm90IGZpcmluZyB0aGVtIHJpZ2h0IG5vd1xyXG5cdFx0aWYgKCByZm9jdXNNb3JwaC50ZXN0KCB0eXBlICsgalF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCApICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCB0eXBlLmluZGV4T2YoIFwiLlwiICkgPiAtMSApIHtcclxuXHJcblx0XHRcdC8vIE5hbWVzcGFjZWQgdHJpZ2dlcjsgY3JlYXRlIGEgcmVnZXhwIHRvIG1hdGNoIGV2ZW50IHR5cGUgaW4gaGFuZGxlKClcclxuXHRcdFx0bmFtZXNwYWNlcyA9IHR5cGUuc3BsaXQoIFwiLlwiICk7XHJcblx0XHRcdHR5cGUgPSBuYW1lc3BhY2VzLnNoaWZ0KCk7XHJcblx0XHRcdG5hbWVzcGFjZXMuc29ydCgpO1xyXG5cdFx0fVxyXG5cdFx0b250eXBlID0gdHlwZS5pbmRleE9mKCBcIjpcIiApIDwgMCAmJiBcIm9uXCIgKyB0eXBlO1xyXG5cclxuXHRcdC8vIENhbGxlciBjYW4gcGFzcyBpbiBhIGpRdWVyeS5FdmVudCBvYmplY3QsIE9iamVjdCwgb3IganVzdCBhbiBldmVudCB0eXBlIHN0cmluZ1xyXG5cdFx0ZXZlbnQgPSBldmVudFsgalF1ZXJ5LmV4cGFuZG8gXSA/XHJcblx0XHRcdGV2ZW50IDpcclxuXHRcdFx0bmV3IGpRdWVyeS5FdmVudCggdHlwZSwgdHlwZW9mIGV2ZW50ID09PSBcIm9iamVjdFwiICYmIGV2ZW50ICk7XHJcblxyXG5cdFx0Ly8gVHJpZ2dlciBiaXRtYXNrOiAmIDEgZm9yIG5hdGl2ZSBoYW5kbGVyczsgJiAyIGZvciBqUXVlcnkgKGFsd2F5cyB0cnVlKVxyXG5cdFx0ZXZlbnQuaXNUcmlnZ2VyID0gb25seUhhbmRsZXJzID8gMiA6IDM7XHJcblx0XHRldmVudC5uYW1lc3BhY2UgPSBuYW1lc3BhY2VzLmpvaW4oIFwiLlwiICk7XHJcblx0XHRldmVudC5ybmFtZXNwYWNlID0gZXZlbnQubmFtZXNwYWNlID9cclxuXHRcdFx0bmV3IFJlZ0V4cCggXCIoXnxcXFxcLilcIiArIG5hbWVzcGFjZXMuam9pbiggXCJcXFxcLig/Oi4qXFxcXC58KVwiICkgKyBcIihcXFxcLnwkKVwiICkgOlxyXG5cdFx0XHRudWxsO1xyXG5cclxuXHRcdC8vIENsZWFuIHVwIHRoZSBldmVudCBpbiBjYXNlIGl0IGlzIGJlaW5nIHJldXNlZFxyXG5cdFx0ZXZlbnQucmVzdWx0ID0gdW5kZWZpbmVkO1xyXG5cdFx0aWYgKCAhZXZlbnQudGFyZ2V0ICkge1xyXG5cdFx0XHRldmVudC50YXJnZXQgPSBlbGVtO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIENsb25lIGFueSBpbmNvbWluZyBkYXRhIGFuZCBwcmVwZW5kIHRoZSBldmVudCwgY3JlYXRpbmcgdGhlIGhhbmRsZXIgYXJnIGxpc3RcclxuXHRcdGRhdGEgPSBkYXRhID09IG51bGwgP1xyXG5cdFx0XHRbIGV2ZW50IF0gOlxyXG5cdFx0XHRqUXVlcnkubWFrZUFycmF5KCBkYXRhLCBbIGV2ZW50IF0gKTtcclxuXHJcblx0XHQvLyBBbGxvdyBzcGVjaWFsIGV2ZW50cyB0byBkcmF3IG91dHNpZGUgdGhlIGxpbmVzXHJcblx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcclxuXHRcdGlmICggIW9ubHlIYW5kbGVycyAmJiBzcGVjaWFsLnRyaWdnZXIgJiYgc3BlY2lhbC50cmlnZ2VyLmFwcGx5KCBlbGVtLCBkYXRhICkgPT09IGZhbHNlICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRGV0ZXJtaW5lIGV2ZW50IHByb3BhZ2F0aW9uIHBhdGggaW4gYWR2YW5jZSwgcGVyIFczQyBldmVudHMgc3BlYyAoIzk5NTEpXHJcblx0XHQvLyBCdWJibGUgdXAgdG8gZG9jdW1lbnQsIHRoZW4gdG8gd2luZG93OyB3YXRjaCBmb3IgYSBnbG9iYWwgb3duZXJEb2N1bWVudCB2YXIgKCM5NzI0KVxyXG5cdFx0aWYgKCAhb25seUhhbmRsZXJzICYmICFzcGVjaWFsLm5vQnViYmxlICYmICFqUXVlcnkuaXNXaW5kb3coIGVsZW0gKSApIHtcclxuXHJcblx0XHRcdGJ1YmJsZVR5cGUgPSBzcGVjaWFsLmRlbGVnYXRlVHlwZSB8fCB0eXBlO1xyXG5cdFx0XHRpZiAoICFyZm9jdXNNb3JwaC50ZXN0KCBidWJibGVUeXBlICsgdHlwZSApICkge1xyXG5cdFx0XHRcdGN1ciA9IGN1ci5wYXJlbnROb2RlO1xyXG5cdFx0XHR9XHJcblx0XHRcdGZvciAoIDsgY3VyOyBjdXIgPSBjdXIucGFyZW50Tm9kZSApIHtcclxuXHRcdFx0XHRldmVudFBhdGgucHVzaCggY3VyICk7XHJcblx0XHRcdFx0dG1wID0gY3VyO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBPbmx5IGFkZCB3aW5kb3cgaWYgd2UgZ290IHRvIGRvY3VtZW50IChlLmcuLCBub3QgcGxhaW4gb2JqIG9yIGRldGFjaGVkIERPTSlcclxuXHRcdFx0aWYgKCB0bXAgPT09ICggZWxlbS5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50ICkgKSB7XHJcblx0XHRcdFx0ZXZlbnRQYXRoLnB1c2goIHRtcC5kZWZhdWx0VmlldyB8fCB0bXAucGFyZW50V2luZG93IHx8IHdpbmRvdyApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gRmlyZSBoYW5kbGVycyBvbiB0aGUgZXZlbnQgcGF0aFxyXG5cdFx0aSA9IDA7XHJcblx0XHR3aGlsZSAoICggY3VyID0gZXZlbnRQYXRoWyBpKysgXSApICYmICFldmVudC5pc1Byb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xyXG5cclxuXHRcdFx0ZXZlbnQudHlwZSA9IGkgPiAxID9cclxuXHRcdFx0XHRidWJibGVUeXBlIDpcclxuXHRcdFx0XHRzcGVjaWFsLmJpbmRUeXBlIHx8IHR5cGU7XHJcblxyXG5cdFx0XHQvLyBqUXVlcnkgaGFuZGxlclxyXG5cdFx0XHRoYW5kbGUgPSAoIGRhdGFQcml2LmdldCggY3VyLCBcImV2ZW50c1wiICkgfHwge30gKVsgZXZlbnQudHlwZSBdICYmXHJcblx0XHRcdFx0ZGF0YVByaXYuZ2V0KCBjdXIsIFwiaGFuZGxlXCIgKTtcclxuXHRcdFx0aWYgKCBoYW5kbGUgKSB7XHJcblx0XHRcdFx0aGFuZGxlLmFwcGx5KCBjdXIsIGRhdGEgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gTmF0aXZlIGhhbmRsZXJcclxuXHRcdFx0aGFuZGxlID0gb250eXBlICYmIGN1clsgb250eXBlIF07XHJcblx0XHRcdGlmICggaGFuZGxlICYmIGhhbmRsZS5hcHBseSAmJiBhY2NlcHREYXRhKCBjdXIgKSApIHtcclxuXHRcdFx0XHRldmVudC5yZXN1bHQgPSBoYW5kbGUuYXBwbHkoIGN1ciwgZGF0YSApO1xyXG5cdFx0XHRcdGlmICggZXZlbnQucmVzdWx0ID09PSBmYWxzZSApIHtcclxuXHRcdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0XHRldmVudC50eXBlID0gdHlwZTtcclxuXHJcblx0XHQvLyBJZiBub2JvZHkgcHJldmVudGVkIHRoZSBkZWZhdWx0IGFjdGlvbiwgZG8gaXQgbm93XHJcblx0XHRpZiAoICFvbmx5SGFuZGxlcnMgJiYgIWV2ZW50LmlzRGVmYXVsdFByZXZlbnRlZCgpICkge1xyXG5cclxuXHRcdFx0aWYgKCAoICFzcGVjaWFsLl9kZWZhdWx0IHx8XHJcblx0XHRcdFx0c3BlY2lhbC5fZGVmYXVsdC5hcHBseSggZXZlbnRQYXRoLnBvcCgpLCBkYXRhICkgPT09IGZhbHNlICkgJiZcclxuXHRcdFx0XHRhY2NlcHREYXRhKCBlbGVtICkgKSB7XHJcblxyXG5cdFx0XHRcdC8vIENhbGwgYSBuYXRpdmUgRE9NIG1ldGhvZCBvbiB0aGUgdGFyZ2V0IHdpdGggdGhlIHNhbWUgbmFtZSBuYW1lIGFzIHRoZSBldmVudC5cclxuXHRcdFx0XHQvLyBEb24ndCBkbyBkZWZhdWx0IGFjdGlvbnMgb24gd2luZG93LCB0aGF0J3Mgd2hlcmUgZ2xvYmFsIHZhcmlhYmxlcyBiZSAoIzYxNzApXHJcblx0XHRcdFx0aWYgKCBvbnR5cGUgJiYgalF1ZXJ5LmlzRnVuY3Rpb24oIGVsZW1bIHR5cGUgXSApICYmICFqUXVlcnkuaXNXaW5kb3coIGVsZW0gKSApIHtcclxuXHJcblx0XHRcdFx0XHQvLyBEb24ndCByZS10cmlnZ2VyIGFuIG9uRk9PIGV2ZW50IHdoZW4gd2UgY2FsbCBpdHMgRk9PKCkgbWV0aG9kXHJcblx0XHRcdFx0XHR0bXAgPSBlbGVtWyBvbnR5cGUgXTtcclxuXHJcblx0XHRcdFx0XHRpZiAoIHRtcCApIHtcclxuXHRcdFx0XHRcdFx0ZWxlbVsgb250eXBlIF0gPSBudWxsO1xyXG5cdFx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRcdC8vIFByZXZlbnQgcmUtdHJpZ2dlcmluZyBvZiB0aGUgc2FtZSBldmVudCwgc2luY2Ugd2UgYWxyZWFkeSBidWJibGVkIGl0IGFib3ZlXHJcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlcmVkID0gdHlwZTtcclxuXHRcdFx0XHRcdGVsZW1bIHR5cGUgXSgpO1xyXG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCA9IHVuZGVmaW5lZDtcclxuXHJcblx0XHRcdFx0XHRpZiAoIHRtcCApIHtcclxuXHRcdFx0XHRcdFx0ZWxlbVsgb250eXBlIF0gPSB0bXA7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0cmV0dXJuIGV2ZW50LnJlc3VsdDtcclxuXHR9LFxyXG5cclxuXHQvLyBQaWdneWJhY2sgb24gYSBkb25vciBldmVudCB0byBzaW11bGF0ZSBhIGRpZmZlcmVudCBvbmVcclxuXHQvLyBVc2VkIG9ubHkgZm9yIGBmb2N1cyhpbiB8IG91dClgIGV2ZW50c1xyXG5cdHNpbXVsYXRlOiBmdW5jdGlvbiggdHlwZSwgZWxlbSwgZXZlbnQgKSB7XHJcblx0XHR2YXIgZSA9IGpRdWVyeS5leHRlbmQoXHJcblx0XHRcdG5ldyBqUXVlcnkuRXZlbnQoKSxcclxuXHRcdFx0ZXZlbnQsXHJcblx0XHRcdHtcclxuXHRcdFx0XHR0eXBlOiB0eXBlLFxyXG5cdFx0XHRcdGlzU2ltdWxhdGVkOiB0cnVlXHJcblx0XHRcdH1cclxuXHRcdCk7XHJcblxyXG5cdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoIGUsIG51bGwsIGVsZW0gKTtcclxuXHR9XHJcblxyXG59ICk7XHJcblxyXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XHJcblxyXG5cdHRyaWdnZXI6IGZ1bmN0aW9uKCB0eXBlLCBkYXRhICkge1xyXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oKSB7XHJcblx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyKCB0eXBlLCBkYXRhLCB0aGlzICk7XHJcblx0XHR9ICk7XHJcblx0fSxcclxuXHR0cmlnZ2VySGFuZGxlcjogZnVuY3Rpb24oIHR5cGUsIGRhdGEgKSB7XHJcblx0XHR2YXIgZWxlbSA9IHRoaXNbIDAgXTtcclxuXHRcdGlmICggZWxlbSApIHtcclxuXHRcdFx0cmV0dXJuIGpRdWVyeS5ldmVudC50cmlnZ2VyKCB0eXBlLCBkYXRhLCBlbGVtLCB0cnVlICk7XHJcblx0XHR9XHJcblx0fVxyXG59ICk7XHJcblxyXG5cclxualF1ZXJ5LmVhY2goICggXCJibHVyIGZvY3VzIGZvY3VzaW4gZm9jdXNvdXQgbG9hZCByZXNpemUgc2Nyb2xsIHVubG9hZCBjbGljayBkYmxjbGljayBcIiArXHJcblx0XCJtb3VzZWRvd24gbW91c2V1cCBtb3VzZW1vdmUgbW91c2VvdmVyIG1vdXNlb3V0IG1vdXNlZW50ZXIgbW91c2VsZWF2ZSBcIiArXHJcblx0XCJjaGFuZ2Ugc2VsZWN0IHN1Ym1pdCBrZXlkb3duIGtleXByZXNzIGtleXVwIGVycm9yIGNvbnRleHRtZW51XCIgKS5zcGxpdCggXCIgXCIgKSxcclxuXHRmdW5jdGlvbiggaSwgbmFtZSApIHtcclxuXHJcblx0Ly8gSGFuZGxlIGV2ZW50IGJpbmRpbmdcclxuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBkYXRhLCBmbiApIHtcclxuXHRcdHJldHVybiBhcmd1bWVudHMubGVuZ3RoID4gMCA/XHJcblx0XHRcdHRoaXMub24oIG5hbWUsIG51bGwsIGRhdGEsIGZuICkgOlxyXG5cdFx0XHR0aGlzLnRyaWdnZXIoIG5hbWUgKTtcclxuXHR9O1xyXG59ICk7XHJcblxyXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XHJcblx0aG92ZXI6IGZ1bmN0aW9uKCBmbk92ZXIsIGZuT3V0ICkge1xyXG5cdFx0cmV0dXJuIHRoaXMubW91c2VlbnRlciggZm5PdmVyICkubW91c2VsZWF2ZSggZm5PdXQgfHwgZm5PdmVyICk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5cclxuXHJcblxyXG5zdXBwb3J0LmZvY3VzaW4gPSBcIm9uZm9jdXNpblwiIGluIHdpbmRvdztcclxuXHJcblxyXG4vLyBTdXBwb3J0OiBGaXJlZm94XHJcbi8vIEZpcmVmb3ggZG9lc24ndCBoYXZlIGZvY3VzKGluIHwgb3V0KSBldmVudHNcclxuLy8gUmVsYXRlZCB0aWNrZXQgLSBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD02ODc3ODdcclxuLy9cclxuLy8gU3VwcG9ydDogQ2hyb21lLCBTYWZhcmlcclxuLy8gZm9jdXMoaW4gfCBvdXQpIGV2ZW50cyBmaXJlIGFmdGVyIGZvY3VzICYgYmx1ciBldmVudHMsXHJcbi8vIHdoaWNoIGlzIHNwZWMgdmlvbGF0aW9uIC0gaHR0cDovL3d3dy53My5vcmcvVFIvRE9NLUxldmVsLTMtRXZlbnRzLyNldmVudHMtZm9jdXNldmVudC1ldmVudC1vcmRlclxyXG4vLyBSZWxhdGVkIHRpY2tldCAtIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY2hyb21pdW0vaXNzdWVzL2RldGFpbD9pZD00NDk4NTdcclxuaWYgKCAhc3VwcG9ydC5mb2N1c2luICkge1xyXG5cdGpRdWVyeS5lYWNoKCB7IGZvY3VzOiBcImZvY3VzaW5cIiwgYmx1cjogXCJmb2N1c291dFwiIH0sIGZ1bmN0aW9uKCBvcmlnLCBmaXggKSB7XHJcblxyXG5cdFx0Ly8gQXR0YWNoIGEgc2luZ2xlIGNhcHR1cmluZyBoYW5kbGVyIG9uIHRoZSBkb2N1bWVudCB3aGlsZSBzb21lb25lIHdhbnRzIGZvY3VzaW4vZm9jdXNvdXRcclxuXHRcdHZhciBoYW5kbGVyID0gZnVuY3Rpb24oIGV2ZW50ICkge1xyXG5cdFx0XHRqUXVlcnkuZXZlbnQuc2ltdWxhdGUoIGZpeCwgZXZlbnQudGFyZ2V0LCBqUXVlcnkuZXZlbnQuZml4KCBldmVudCApICk7XHJcblx0XHR9O1xyXG5cclxuXHRcdGpRdWVyeS5ldmVudC5zcGVjaWFsWyBmaXggXSA9IHtcclxuXHRcdFx0c2V0dXA6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdHZhciBkb2MgPSB0aGlzLm93bmVyRG9jdW1lbnQgfHwgdGhpcyxcclxuXHRcdFx0XHRcdGF0dGFjaGVzID0gZGF0YVByaXYuYWNjZXNzKCBkb2MsIGZpeCApO1xyXG5cclxuXHRcdFx0XHRpZiAoICFhdHRhY2hlcyApIHtcclxuXHRcdFx0XHRcdGRvYy5hZGRFdmVudExpc3RlbmVyKCBvcmlnLCBoYW5kbGVyLCB0cnVlICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGRhdGFQcml2LmFjY2VzcyggZG9jLCBmaXgsICggYXR0YWNoZXMgfHwgMCApICsgMSApO1xyXG5cdFx0XHR9LFxyXG5cdFx0XHR0ZWFyZG93bjogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0dmFyIGRvYyA9IHRoaXMub3duZXJEb2N1bWVudCB8fCB0aGlzLFxyXG5cdFx0XHRcdFx0YXR0YWNoZXMgPSBkYXRhUHJpdi5hY2Nlc3MoIGRvYywgZml4ICkgLSAxO1xyXG5cclxuXHRcdFx0XHRpZiAoICFhdHRhY2hlcyApIHtcclxuXHRcdFx0XHRcdGRvYy5yZW1vdmVFdmVudExpc3RlbmVyKCBvcmlnLCBoYW5kbGVyLCB0cnVlICk7XHJcblx0XHRcdFx0XHRkYXRhUHJpdi5yZW1vdmUoIGRvYywgZml4ICk7XHJcblxyXG5cdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRkYXRhUHJpdi5hY2Nlc3MoIGRvYywgZml4LCBhdHRhY2hlcyApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fTtcclxuXHR9ICk7XHJcbn1cclxudmFyIGxvY2F0aW9uID0gd2luZG93LmxvY2F0aW9uO1xyXG5cclxudmFyIG5vbmNlID0galF1ZXJ5Lm5vdygpO1xyXG5cclxudmFyIHJxdWVyeSA9ICggL1xcPy8gKTtcclxuXHJcblxyXG5cclxuLy8gU3VwcG9ydDogQW5kcm9pZCAyLjNcclxuLy8gV29ya2Fyb3VuZCBmYWlsdXJlIHRvIHN0cmluZy1jYXN0IG51bGwgaW5wdXRcclxualF1ZXJ5LnBhcnNlSlNPTiA9IGZ1bmN0aW9uKCBkYXRhICkge1xyXG5cdHJldHVybiBKU09OLnBhcnNlKCBkYXRhICsgXCJcIiApO1xyXG59O1xyXG5cclxuXHJcbi8vIENyb3NzLWJyb3dzZXIgeG1sIHBhcnNpbmdcclxualF1ZXJ5LnBhcnNlWE1MID0gZnVuY3Rpb24oIGRhdGEgKSB7XHJcblx0dmFyIHhtbDtcclxuXHRpZiAoICFkYXRhIHx8IHR5cGVvZiBkYXRhICE9PSBcInN0cmluZ1wiICkge1xyXG5cdFx0cmV0dXJuIG51bGw7XHJcblx0fVxyXG5cclxuXHQvLyBTdXBwb3J0OiBJRTlcclxuXHR0cnkge1xyXG5cdFx0eG1sID0gKCBuZXcgd2luZG93LkRPTVBhcnNlcigpICkucGFyc2VGcm9tU3RyaW5nKCBkYXRhLCBcInRleHQveG1sXCIgKTtcclxuXHR9IGNhdGNoICggZSApIHtcclxuXHRcdHhtbCA9IHVuZGVmaW5lZDtcclxuXHR9XHJcblxyXG5cdGlmICggIXhtbCB8fCB4bWwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIFwicGFyc2VyZXJyb3JcIiApLmxlbmd0aCApIHtcclxuXHRcdGpRdWVyeS5lcnJvciggXCJJbnZhbGlkIFhNTDogXCIgKyBkYXRhICk7XHJcblx0fVxyXG5cdHJldHVybiB4bWw7XHJcbn07XHJcblxyXG5cclxudmFyXHJcblx0cmhhc2ggPSAvIy4qJC8sXHJcblx0cnRzID0gLyhbPyZdKV89W14mXSovLFxyXG5cdHJoZWFkZXJzID0gL14oLio/KTpbIFxcdF0qKFteXFxyXFxuXSopJC9tZyxcclxuXHJcblx0Ly8gIzc2NTMsICM4MTI1LCAjODE1MjogbG9jYWwgcHJvdG9jb2wgZGV0ZWN0aW9uXHJcblx0cmxvY2FsUHJvdG9jb2wgPSAvXig/OmFib3V0fGFwcHxhcHAtc3RvcmFnZXwuKy1leHRlbnNpb258ZmlsZXxyZXN8d2lkZ2V0KTokLyxcclxuXHRybm9Db250ZW50ID0gL14oPzpHRVR8SEVBRCkkLyxcclxuXHRycHJvdG9jb2wgPSAvXlxcL1xcLy8sXHJcblxyXG5cdC8qIFByZWZpbHRlcnNcclxuXHQgKiAxKSBUaGV5IGFyZSB1c2VmdWwgdG8gaW50cm9kdWNlIGN1c3RvbSBkYXRhVHlwZXMgKHNlZSBhamF4L2pzb25wLmpzIGZvciBhbiBleGFtcGxlKVxyXG5cdCAqIDIpIFRoZXNlIGFyZSBjYWxsZWQ6XHJcblx0ICogICAgLSBCRUZPUkUgYXNraW5nIGZvciBhIHRyYW5zcG9ydFxyXG5cdCAqICAgIC0gQUZURVIgcGFyYW0gc2VyaWFsaXphdGlvbiAocy5kYXRhIGlzIGEgc3RyaW5nIGlmIHMucHJvY2Vzc0RhdGEgaXMgdHJ1ZSlcclxuXHQgKiAzKSBrZXkgaXMgdGhlIGRhdGFUeXBlXHJcblx0ICogNCkgdGhlIGNhdGNoYWxsIHN5bWJvbCBcIipcIiBjYW4gYmUgdXNlZFxyXG5cdCAqIDUpIGV4ZWN1dGlvbiB3aWxsIHN0YXJ0IHdpdGggdHJhbnNwb3J0IGRhdGFUeXBlIGFuZCBUSEVOIGNvbnRpbnVlIGRvd24gdG8gXCIqXCIgaWYgbmVlZGVkXHJcblx0ICovXHJcblx0cHJlZmlsdGVycyA9IHt9LFxyXG5cclxuXHQvKiBUcmFuc3BvcnRzIGJpbmRpbmdzXHJcblx0ICogMSkga2V5IGlzIHRoZSBkYXRhVHlwZVxyXG5cdCAqIDIpIHRoZSBjYXRjaGFsbCBzeW1ib2wgXCIqXCIgY2FuIGJlIHVzZWRcclxuXHQgKiAzKSBzZWxlY3Rpb24gd2lsbCBzdGFydCB3aXRoIHRyYW5zcG9ydCBkYXRhVHlwZSBhbmQgVEhFTiBnbyB0byBcIipcIiBpZiBuZWVkZWRcclxuXHQgKi9cclxuXHR0cmFuc3BvcnRzID0ge30sXHJcblxyXG5cdC8vIEF2b2lkIGNvbW1lbnQtcHJvbG9nIGNoYXIgc2VxdWVuY2UgKCMxMDA5OCk7IG11c3QgYXBwZWFzZSBsaW50IGFuZCBldmFkZSBjb21wcmVzc2lvblxyXG5cdGFsbFR5cGVzID0gXCIqL1wiLmNvbmNhdCggXCIqXCIgKSxcclxuXHJcblx0Ly8gQW5jaG9yIHRhZyBmb3IgcGFyc2luZyB0aGUgZG9jdW1lbnQgb3JpZ2luXHJcblx0b3JpZ2luQW5jaG9yID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJhXCIgKTtcclxuXHRvcmlnaW5BbmNob3IuaHJlZiA9IGxvY2F0aW9uLmhyZWY7XHJcblxyXG4vLyBCYXNlIFwiY29uc3RydWN0b3JcIiBmb3IgalF1ZXJ5LmFqYXhQcmVmaWx0ZXIgYW5kIGpRdWVyeS5hamF4VHJhbnNwb3J0XHJcbmZ1bmN0aW9uIGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggc3RydWN0dXJlICkge1xyXG5cclxuXHQvLyBkYXRhVHlwZUV4cHJlc3Npb24gaXMgb3B0aW9uYWwgYW5kIGRlZmF1bHRzIHRvIFwiKlwiXHJcblx0cmV0dXJuIGZ1bmN0aW9uKCBkYXRhVHlwZUV4cHJlc3Npb24sIGZ1bmMgKSB7XHJcblxyXG5cdFx0aWYgKCB0eXBlb2YgZGF0YVR5cGVFeHByZXNzaW9uICE9PSBcInN0cmluZ1wiICkge1xyXG5cdFx0XHRmdW5jID0gZGF0YVR5cGVFeHByZXNzaW9uO1xyXG5cdFx0XHRkYXRhVHlwZUV4cHJlc3Npb24gPSBcIipcIjtcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgZGF0YVR5cGUsXHJcblx0XHRcdGkgPSAwLFxyXG5cdFx0XHRkYXRhVHlwZXMgPSBkYXRhVHlwZUV4cHJlc3Npb24udG9Mb3dlckNhc2UoKS5tYXRjaCggcm5vdHdoaXRlICkgfHwgW107XHJcblxyXG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggZnVuYyApICkge1xyXG5cclxuXHRcdFx0Ly8gRm9yIGVhY2ggZGF0YVR5cGUgaW4gdGhlIGRhdGFUeXBlRXhwcmVzc2lvblxyXG5cdFx0XHR3aGlsZSAoICggZGF0YVR5cGUgPSBkYXRhVHlwZXNbIGkrKyBdICkgKSB7XHJcblxyXG5cdFx0XHRcdC8vIFByZXBlbmQgaWYgcmVxdWVzdGVkXHJcblx0XHRcdFx0aWYgKCBkYXRhVHlwZVsgMCBdID09PSBcIitcIiApIHtcclxuXHRcdFx0XHRcdGRhdGFUeXBlID0gZGF0YVR5cGUuc2xpY2UoIDEgKSB8fCBcIipcIjtcclxuXHRcdFx0XHRcdCggc3RydWN0dXJlWyBkYXRhVHlwZSBdID0gc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdICkudW5zaGlmdCggZnVuYyApO1xyXG5cclxuXHRcdFx0XHQvLyBPdGhlcndpc2UgYXBwZW5kXHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdCggc3RydWN0dXJlWyBkYXRhVHlwZSBdID0gc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdICkucHVzaCggZnVuYyApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH07XHJcbn1cclxuXHJcbi8vIEJhc2UgaW5zcGVjdGlvbiBmdW5jdGlvbiBmb3IgcHJlZmlsdGVycyBhbmQgdHJhbnNwb3J0c1xyXG5mdW5jdGlvbiBpbnNwZWN0UHJlZmlsdGVyc09yVHJhbnNwb3J0cyggc3RydWN0dXJlLCBvcHRpb25zLCBvcmlnaW5hbE9wdGlvbnMsIGpxWEhSICkge1xyXG5cclxuXHR2YXIgaW5zcGVjdGVkID0ge30sXHJcblx0XHRzZWVraW5nVHJhbnNwb3J0ID0gKCBzdHJ1Y3R1cmUgPT09IHRyYW5zcG9ydHMgKTtcclxuXHJcblx0ZnVuY3Rpb24gaW5zcGVjdCggZGF0YVR5cGUgKSB7XHJcblx0XHR2YXIgc2VsZWN0ZWQ7XHJcblx0XHRpbnNwZWN0ZWRbIGRhdGFUeXBlIF0gPSB0cnVlO1xyXG5cdFx0alF1ZXJ5LmVhY2goIHN0cnVjdHVyZVsgZGF0YVR5cGUgXSB8fCBbXSwgZnVuY3Rpb24oIF8sIHByZWZpbHRlck9yRmFjdG9yeSApIHtcclxuXHRcdFx0dmFyIGRhdGFUeXBlT3JUcmFuc3BvcnQgPSBwcmVmaWx0ZXJPckZhY3RvcnkoIG9wdGlvbnMsIG9yaWdpbmFsT3B0aW9ucywganFYSFIgKTtcclxuXHRcdFx0aWYgKCB0eXBlb2YgZGF0YVR5cGVPclRyYW5zcG9ydCA9PT0gXCJzdHJpbmdcIiAmJlxyXG5cdFx0XHRcdCFzZWVraW5nVHJhbnNwb3J0ICYmICFpbnNwZWN0ZWRbIGRhdGFUeXBlT3JUcmFuc3BvcnQgXSApIHtcclxuXHJcblx0XHRcdFx0b3B0aW9ucy5kYXRhVHlwZXMudW5zaGlmdCggZGF0YVR5cGVPclRyYW5zcG9ydCApO1xyXG5cdFx0XHRcdGluc3BlY3QoIGRhdGFUeXBlT3JUcmFuc3BvcnQgKTtcclxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XHJcblx0XHRcdH0gZWxzZSBpZiAoIHNlZWtpbmdUcmFuc3BvcnQgKSB7XHJcblx0XHRcdFx0cmV0dXJuICEoIHNlbGVjdGVkID0gZGF0YVR5cGVPclRyYW5zcG9ydCApO1xyXG5cdFx0XHR9XHJcblx0XHR9ICk7XHJcblx0XHRyZXR1cm4gc2VsZWN0ZWQ7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gaW5zcGVjdCggb3B0aW9ucy5kYXRhVHlwZXNbIDAgXSApIHx8ICFpbnNwZWN0ZWRbIFwiKlwiIF0gJiYgaW5zcGVjdCggXCIqXCIgKTtcclxufVxyXG5cclxuLy8gQSBzcGVjaWFsIGV4dGVuZCBmb3IgYWpheCBvcHRpb25zXHJcbi8vIHRoYXQgdGFrZXMgXCJmbGF0XCIgb3B0aW9ucyAobm90IHRvIGJlIGRlZXAgZXh0ZW5kZWQpXHJcbi8vIEZpeGVzICM5ODg3XHJcbmZ1bmN0aW9uIGFqYXhFeHRlbmQoIHRhcmdldCwgc3JjICkge1xyXG5cdHZhciBrZXksIGRlZXAsXHJcblx0XHRmbGF0T3B0aW9ucyA9IGpRdWVyeS5hamF4U2V0dGluZ3MuZmxhdE9wdGlvbnMgfHwge307XHJcblxyXG5cdGZvciAoIGtleSBpbiBzcmMgKSB7XHJcblx0XHRpZiAoIHNyY1sga2V5IF0gIT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0KCBmbGF0T3B0aW9uc1sga2V5IF0gPyB0YXJnZXQgOiAoIGRlZXAgfHwgKCBkZWVwID0ge30gKSApIClbIGtleSBdID0gc3JjWyBrZXkgXTtcclxuXHRcdH1cclxuXHR9XHJcblx0aWYgKCBkZWVwICkge1xyXG5cdFx0alF1ZXJ5LmV4dGVuZCggdHJ1ZSwgdGFyZ2V0LCBkZWVwICk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4gdGFyZ2V0O1xyXG59XHJcblxyXG4vKiBIYW5kbGVzIHJlc3BvbnNlcyB0byBhbiBhamF4IHJlcXVlc3Q6XHJcbiAqIC0gZmluZHMgdGhlIHJpZ2h0IGRhdGFUeXBlIChtZWRpYXRlcyBiZXR3ZWVuIGNvbnRlbnQtdHlwZSBhbmQgZXhwZWN0ZWQgZGF0YVR5cGUpXHJcbiAqIC0gcmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyByZXNwb25zZVxyXG4gKi9cclxuZnVuY3Rpb24gYWpheEhhbmRsZVJlc3BvbnNlcyggcywganFYSFIsIHJlc3BvbnNlcyApIHtcclxuXHJcblx0dmFyIGN0LCB0eXBlLCBmaW5hbERhdGFUeXBlLCBmaXJzdERhdGFUeXBlLFxyXG5cdFx0Y29udGVudHMgPSBzLmNvbnRlbnRzLFxyXG5cdFx0ZGF0YVR5cGVzID0gcy5kYXRhVHlwZXM7XHJcblxyXG5cdC8vIFJlbW92ZSBhdXRvIGRhdGFUeXBlIGFuZCBnZXQgY29udGVudC10eXBlIGluIHRoZSBwcm9jZXNzXHJcblx0d2hpbGUgKCBkYXRhVHlwZXNbIDAgXSA9PT0gXCIqXCIgKSB7XHJcblx0XHRkYXRhVHlwZXMuc2hpZnQoKTtcclxuXHRcdGlmICggY3QgPT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0Y3QgPSBzLm1pbWVUeXBlIHx8IGpxWEhSLmdldFJlc3BvbnNlSGVhZGVyKCBcIkNvbnRlbnQtVHlwZVwiICk7XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyBDaGVjayBpZiB3ZSdyZSBkZWFsaW5nIHdpdGggYSBrbm93biBjb250ZW50LXR5cGVcclxuXHRpZiAoIGN0ICkge1xyXG5cdFx0Zm9yICggdHlwZSBpbiBjb250ZW50cyApIHtcclxuXHRcdFx0aWYgKCBjb250ZW50c1sgdHlwZSBdICYmIGNvbnRlbnRzWyB0eXBlIF0udGVzdCggY3QgKSApIHtcclxuXHRcdFx0XHRkYXRhVHlwZXMudW5zaGlmdCggdHlwZSApO1xyXG5cdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHQvLyBDaGVjayB0byBzZWUgaWYgd2UgaGF2ZSBhIHJlc3BvbnNlIGZvciB0aGUgZXhwZWN0ZWQgZGF0YVR5cGVcclxuXHRpZiAoIGRhdGFUeXBlc1sgMCBdIGluIHJlc3BvbnNlcyApIHtcclxuXHRcdGZpbmFsRGF0YVR5cGUgPSBkYXRhVHlwZXNbIDAgXTtcclxuXHR9IGVsc2Uge1xyXG5cclxuXHRcdC8vIFRyeSBjb252ZXJ0aWJsZSBkYXRhVHlwZXNcclxuXHRcdGZvciAoIHR5cGUgaW4gcmVzcG9uc2VzICkge1xyXG5cdFx0XHRpZiAoICFkYXRhVHlwZXNbIDAgXSB8fCBzLmNvbnZlcnRlcnNbIHR5cGUgKyBcIiBcIiArIGRhdGFUeXBlc1sgMCBdIF0gKSB7XHJcblx0XHRcdFx0ZmluYWxEYXRhVHlwZSA9IHR5cGU7XHJcblx0XHRcdFx0YnJlYWs7XHJcblx0XHRcdH1cclxuXHRcdFx0aWYgKCAhZmlyc3REYXRhVHlwZSApIHtcclxuXHRcdFx0XHRmaXJzdERhdGFUeXBlID0gdHlwZTtcclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdC8vIE9yIGp1c3QgdXNlIGZpcnN0IG9uZVxyXG5cdFx0ZmluYWxEYXRhVHlwZSA9IGZpbmFsRGF0YVR5cGUgfHwgZmlyc3REYXRhVHlwZTtcclxuXHR9XHJcblxyXG5cdC8vIElmIHdlIGZvdW5kIGEgZGF0YVR5cGVcclxuXHQvLyBXZSBhZGQgdGhlIGRhdGFUeXBlIHRvIHRoZSBsaXN0IGlmIG5lZWRlZFxyXG5cdC8vIGFuZCByZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgcmVzcG9uc2VcclxuXHRpZiAoIGZpbmFsRGF0YVR5cGUgKSB7XHJcblx0XHRpZiAoIGZpbmFsRGF0YVR5cGUgIT09IGRhdGFUeXBlc1sgMCBdICkge1xyXG5cdFx0XHRkYXRhVHlwZXMudW5zaGlmdCggZmluYWxEYXRhVHlwZSApO1xyXG5cdFx0fVxyXG5cdFx0cmV0dXJuIHJlc3BvbnNlc1sgZmluYWxEYXRhVHlwZSBdO1xyXG5cdH1cclxufVxyXG5cclxuLyogQ2hhaW4gY29udmVyc2lvbnMgZ2l2ZW4gdGhlIHJlcXVlc3QgYW5kIHRoZSBvcmlnaW5hbCByZXNwb25zZVxyXG4gKiBBbHNvIHNldHMgdGhlIHJlc3BvbnNlWFhYIGZpZWxkcyBvbiB0aGUganFYSFIgaW5zdGFuY2VcclxuICovXHJcbmZ1bmN0aW9uIGFqYXhDb252ZXJ0KCBzLCByZXNwb25zZSwganFYSFIsIGlzU3VjY2VzcyApIHtcclxuXHR2YXIgY29udjIsIGN1cnJlbnQsIGNvbnYsIHRtcCwgcHJldixcclxuXHRcdGNvbnZlcnRlcnMgPSB7fSxcclxuXHJcblx0XHQvLyBXb3JrIHdpdGggYSBjb3B5IG9mIGRhdGFUeXBlcyBpbiBjYXNlIHdlIG5lZWQgdG8gbW9kaWZ5IGl0IGZvciBjb252ZXJzaW9uXHJcblx0XHRkYXRhVHlwZXMgPSBzLmRhdGFUeXBlcy5zbGljZSgpO1xyXG5cclxuXHQvLyBDcmVhdGUgY29udmVydGVycyBtYXAgd2l0aCBsb3dlcmNhc2VkIGtleXNcclxuXHRpZiAoIGRhdGFUeXBlc1sgMSBdICkge1xyXG5cdFx0Zm9yICggY29udiBpbiBzLmNvbnZlcnRlcnMgKSB7XHJcblx0XHRcdGNvbnZlcnRlcnNbIGNvbnYudG9Mb3dlckNhc2UoKSBdID0gcy5jb252ZXJ0ZXJzWyBjb252IF07XHJcblx0XHR9XHJcblx0fVxyXG5cclxuXHRjdXJyZW50ID0gZGF0YVR5cGVzLnNoaWZ0KCk7XHJcblxyXG5cdC8vIENvbnZlcnQgdG8gZWFjaCBzZXF1ZW50aWFsIGRhdGFUeXBlXHJcblx0d2hpbGUgKCBjdXJyZW50ICkge1xyXG5cclxuXHRcdGlmICggcy5yZXNwb25zZUZpZWxkc1sgY3VycmVudCBdICkge1xyXG5cdFx0XHRqcVhIUlsgcy5yZXNwb25zZUZpZWxkc1sgY3VycmVudCBdIF0gPSByZXNwb25zZTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBBcHBseSB0aGUgZGF0YUZpbHRlciBpZiBwcm92aWRlZFxyXG5cdFx0aWYgKCAhcHJldiAmJiBpc1N1Y2Nlc3MgJiYgcy5kYXRhRmlsdGVyICkge1xyXG5cdFx0XHRyZXNwb25zZSA9IHMuZGF0YUZpbHRlciggcmVzcG9uc2UsIHMuZGF0YVR5cGUgKTtcclxuXHRcdH1cclxuXHJcblx0XHRwcmV2ID0gY3VycmVudDtcclxuXHRcdGN1cnJlbnQgPSBkYXRhVHlwZXMuc2hpZnQoKTtcclxuXHJcblx0XHRpZiAoIGN1cnJlbnQgKSB7XHJcblxyXG5cdFx0Ly8gVGhlcmUncyBvbmx5IHdvcmsgdG8gZG8gaWYgY3VycmVudCBkYXRhVHlwZSBpcyBub24tYXV0b1xyXG5cdFx0XHRpZiAoIGN1cnJlbnQgPT09IFwiKlwiICkge1xyXG5cclxuXHRcdFx0XHRjdXJyZW50ID0gcHJldjtcclxuXHJcblx0XHRcdC8vIENvbnZlcnQgcmVzcG9uc2UgaWYgcHJldiBkYXRhVHlwZSBpcyBub24tYXV0byBhbmQgZGlmZmVycyBmcm9tIGN1cnJlbnRcclxuXHRcdFx0fSBlbHNlIGlmICggcHJldiAhPT0gXCIqXCIgJiYgcHJldiAhPT0gY3VycmVudCApIHtcclxuXHJcblx0XHRcdFx0Ly8gU2VlayBhIGRpcmVjdCBjb252ZXJ0ZXJcclxuXHRcdFx0XHRjb252ID0gY29udmVydGVyc1sgcHJldiArIFwiIFwiICsgY3VycmVudCBdIHx8IGNvbnZlcnRlcnNbIFwiKiBcIiArIGN1cnJlbnQgXTtcclxuXHJcblx0XHRcdFx0Ly8gSWYgbm9uZSBmb3VuZCwgc2VlayBhIHBhaXJcclxuXHRcdFx0XHRpZiAoICFjb252ICkge1xyXG5cdFx0XHRcdFx0Zm9yICggY29udjIgaW4gY29udmVydGVycyApIHtcclxuXHJcblx0XHRcdFx0XHRcdC8vIElmIGNvbnYyIG91dHB1dHMgY3VycmVudFxyXG5cdFx0XHRcdFx0XHR0bXAgPSBjb252Mi5zcGxpdCggXCIgXCIgKTtcclxuXHRcdFx0XHRcdFx0aWYgKCB0bXBbIDEgXSA9PT0gY3VycmVudCApIHtcclxuXHJcblx0XHRcdFx0XHRcdFx0Ly8gSWYgcHJldiBjYW4gYmUgY29udmVydGVkIHRvIGFjY2VwdGVkIGlucHV0XHJcblx0XHRcdFx0XHRcdFx0Y29udiA9IGNvbnZlcnRlcnNbIHByZXYgKyBcIiBcIiArIHRtcFsgMCBdIF0gfHxcclxuXHRcdFx0XHRcdFx0XHRcdGNvbnZlcnRlcnNbIFwiKiBcIiArIHRtcFsgMCBdIF07XHJcblx0XHRcdFx0XHRcdFx0aWYgKCBjb252ICkge1xyXG5cclxuXHRcdFx0XHRcdFx0XHRcdC8vIENvbmRlbnNlIGVxdWl2YWxlbmNlIGNvbnZlcnRlcnNcclxuXHRcdFx0XHRcdFx0XHRcdGlmICggY29udiA9PT0gdHJ1ZSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0Y29udiA9IGNvbnZlcnRlcnNbIGNvbnYyIF07XHJcblxyXG5cdFx0XHRcdFx0XHRcdFx0Ly8gT3RoZXJ3aXNlLCBpbnNlcnQgdGhlIGludGVybWVkaWF0ZSBkYXRhVHlwZVxyXG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggY29udmVydGVyc1sgY29udjIgXSAhPT0gdHJ1ZSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0Y3VycmVudCA9IHRtcFsgMCBdO1xyXG5cdFx0XHRcdFx0XHRcdFx0XHRkYXRhVHlwZXMudW5zaGlmdCggdG1wWyAxIF0gKTtcclxuXHRcdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gQXBwbHkgY29udmVydGVyIChpZiBub3QgYW4gZXF1aXZhbGVuY2UpXHJcblx0XHRcdFx0aWYgKCBjb252ICE9PSB0cnVlICkge1xyXG5cclxuXHRcdFx0XHRcdC8vIFVubGVzcyBlcnJvcnMgYXJlIGFsbG93ZWQgdG8gYnViYmxlLCBjYXRjaCBhbmQgcmV0dXJuIHRoZW1cclxuXHRcdFx0XHRcdGlmICggY29udiAmJiBzLnRocm93cyApIHtcclxuXHRcdFx0XHRcdFx0cmVzcG9uc2UgPSBjb252KCByZXNwb25zZSApO1xyXG5cdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0dHJ5IHtcclxuXHRcdFx0XHRcdFx0XHRyZXNwb25zZSA9IGNvbnYoIHJlc3BvbnNlICk7XHJcblx0XHRcdFx0XHRcdH0gY2F0Y2ggKCBlICkge1xyXG5cdFx0XHRcdFx0XHRcdHJldHVybiB7XHJcblx0XHRcdFx0XHRcdFx0XHRzdGF0ZTogXCJwYXJzZXJlcnJvclwiLFxyXG5cdFx0XHRcdFx0XHRcdFx0ZXJyb3I6IGNvbnYgPyBlIDogXCJObyBjb252ZXJzaW9uIGZyb20gXCIgKyBwcmV2ICsgXCIgdG8gXCIgKyBjdXJyZW50XHJcblx0XHRcdFx0XHRcdFx0fTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0cmV0dXJuIHsgc3RhdGU6IFwic3VjY2Vzc1wiLCBkYXRhOiByZXNwb25zZSB9O1xyXG59XHJcblxyXG5qUXVlcnkuZXh0ZW5kKCB7XHJcblxyXG5cdC8vIENvdW50ZXIgZm9yIGhvbGRpbmcgdGhlIG51bWJlciBvZiBhY3RpdmUgcXVlcmllc1xyXG5cdGFjdGl2ZTogMCxcclxuXHJcblx0Ly8gTGFzdC1Nb2RpZmllZCBoZWFkZXIgY2FjaGUgZm9yIG5leHQgcmVxdWVzdFxyXG5cdGxhc3RNb2RpZmllZDoge30sXHJcblx0ZXRhZzoge30sXHJcblxyXG5cdGFqYXhTZXR0aW5nczoge1xyXG5cdFx0dXJsOiBsb2NhdGlvbi5ocmVmLFxyXG5cdFx0dHlwZTogXCJHRVRcIixcclxuXHRcdGlzTG9jYWw6IHJsb2NhbFByb3RvY29sLnRlc3QoIGxvY2F0aW9uLnByb3RvY29sICksXHJcblx0XHRnbG9iYWw6IHRydWUsXHJcblx0XHRwcm9jZXNzRGF0YTogdHJ1ZSxcclxuXHRcdGFzeW5jOiB0cnVlLFxyXG5cdFx0Y29udGVudFR5cGU6IFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkOyBjaGFyc2V0PVVURi04XCIsXHJcblx0XHQvKlxyXG5cdFx0dGltZW91dDogMCxcclxuXHRcdGRhdGE6IG51bGwsXHJcblx0XHRkYXRhVHlwZTogbnVsbCxcclxuXHRcdHVzZXJuYW1lOiBudWxsLFxyXG5cdFx0cGFzc3dvcmQ6IG51bGwsXHJcblx0XHRjYWNoZTogbnVsbCxcclxuXHRcdHRocm93czogZmFsc2UsXHJcblx0XHR0cmFkaXRpb25hbDogZmFsc2UsXHJcblx0XHRoZWFkZXJzOiB7fSxcclxuXHRcdCovXHJcblxyXG5cdFx0YWNjZXB0czoge1xyXG5cdFx0XHRcIipcIjogYWxsVHlwZXMsXHJcblx0XHRcdHRleHQ6IFwidGV4dC9wbGFpblwiLFxyXG5cdFx0XHRodG1sOiBcInRleHQvaHRtbFwiLFxyXG5cdFx0XHR4bWw6IFwiYXBwbGljYXRpb24veG1sLCB0ZXh0L3htbFwiLFxyXG5cdFx0XHRqc29uOiBcImFwcGxpY2F0aW9uL2pzb24sIHRleHQvamF2YXNjcmlwdFwiXHJcblx0XHR9LFxyXG5cclxuXHRcdGNvbnRlbnRzOiB7XHJcblx0XHRcdHhtbDogL1xcYnhtbFxcYi8sXHJcblx0XHRcdGh0bWw6IC9cXGJodG1sLyxcclxuXHRcdFx0anNvbjogL1xcYmpzb25cXGIvXHJcblx0XHR9LFxyXG5cclxuXHRcdHJlc3BvbnNlRmllbGRzOiB7XHJcblx0XHRcdHhtbDogXCJyZXNwb25zZVhNTFwiLFxyXG5cdFx0XHR0ZXh0OiBcInJlc3BvbnNlVGV4dFwiLFxyXG5cdFx0XHRqc29uOiBcInJlc3BvbnNlSlNPTlwiXHJcblx0XHR9LFxyXG5cclxuXHRcdC8vIERhdGEgY29udmVydGVyc1xyXG5cdFx0Ly8gS2V5cyBzZXBhcmF0ZSBzb3VyY2UgKG9yIGNhdGNoYWxsIFwiKlwiKSBhbmQgZGVzdGluYXRpb24gdHlwZXMgd2l0aCBhIHNpbmdsZSBzcGFjZVxyXG5cdFx0Y29udmVydGVyczoge1xyXG5cclxuXHRcdFx0Ly8gQ29udmVydCBhbnl0aGluZyB0byB0ZXh0XHJcblx0XHRcdFwiKiB0ZXh0XCI6IFN0cmluZyxcclxuXHJcblx0XHRcdC8vIFRleHQgdG8gaHRtbCAodHJ1ZSA9IG5vIHRyYW5zZm9ybWF0aW9uKVxyXG5cdFx0XHRcInRleHQgaHRtbFwiOiB0cnVlLFxyXG5cclxuXHRcdFx0Ly8gRXZhbHVhdGUgdGV4dCBhcyBhIGpzb24gZXhwcmVzc2lvblxyXG5cdFx0XHRcInRleHQganNvblwiOiBqUXVlcnkucGFyc2VKU09OLFxyXG5cclxuXHRcdFx0Ly8gUGFyc2UgdGV4dCBhcyB4bWxcclxuXHRcdFx0XCJ0ZXh0IHhtbFwiOiBqUXVlcnkucGFyc2VYTUxcclxuXHRcdH0sXHJcblxyXG5cdFx0Ly8gRm9yIG9wdGlvbnMgdGhhdCBzaG91bGRuJ3QgYmUgZGVlcCBleHRlbmRlZDpcclxuXHRcdC8vIHlvdSBjYW4gYWRkIHlvdXIgb3duIGN1c3RvbSBvcHRpb25zIGhlcmUgaWZcclxuXHRcdC8vIGFuZCB3aGVuIHlvdSBjcmVhdGUgb25lIHRoYXQgc2hvdWxkbid0IGJlXHJcblx0XHQvLyBkZWVwIGV4dGVuZGVkIChzZWUgYWpheEV4dGVuZClcclxuXHRcdGZsYXRPcHRpb25zOiB7XHJcblx0XHRcdHVybDogdHJ1ZSxcclxuXHRcdFx0Y29udGV4dDogdHJ1ZVxyXG5cdFx0fVxyXG5cdH0sXHJcblxyXG5cdC8vIENyZWF0ZXMgYSBmdWxsIGZsZWRnZWQgc2V0dGluZ3Mgb2JqZWN0IGludG8gdGFyZ2V0XHJcblx0Ly8gd2l0aCBib3RoIGFqYXhTZXR0aW5ncyBhbmQgc2V0dGluZ3MgZmllbGRzLlxyXG5cdC8vIElmIHRhcmdldCBpcyBvbWl0dGVkLCB3cml0ZXMgaW50byBhamF4U2V0dGluZ3MuXHJcblx0YWpheFNldHVwOiBmdW5jdGlvbiggdGFyZ2V0LCBzZXR0aW5ncyApIHtcclxuXHRcdHJldHVybiBzZXR0aW5ncyA/XHJcblxyXG5cdFx0XHQvLyBCdWlsZGluZyBhIHNldHRpbmdzIG9iamVjdFxyXG5cdFx0XHRhamF4RXh0ZW5kKCBhamF4RXh0ZW5kKCB0YXJnZXQsIGpRdWVyeS5hamF4U2V0dGluZ3MgKSwgc2V0dGluZ3MgKSA6XHJcblxyXG5cdFx0XHQvLyBFeHRlbmRpbmcgYWpheFNldHRpbmdzXHJcblx0XHRcdGFqYXhFeHRlbmQoIGpRdWVyeS5hamF4U2V0dGluZ3MsIHRhcmdldCApO1xyXG5cdH0sXHJcblxyXG5cdGFqYXhQcmVmaWx0ZXI6IGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggcHJlZmlsdGVycyApLFxyXG5cdGFqYXhUcmFuc3BvcnQ6IGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggdHJhbnNwb3J0cyApLFxyXG5cclxuXHQvLyBNYWluIG1ldGhvZFxyXG5cdGFqYXg6IGZ1bmN0aW9uKCB1cmwsIG9wdGlvbnMgKSB7XHJcblxyXG5cdFx0Ly8gSWYgdXJsIGlzIGFuIG9iamVjdCwgc2ltdWxhdGUgcHJlLTEuNSBzaWduYXR1cmVcclxuXHRcdGlmICggdHlwZW9mIHVybCA9PT0gXCJvYmplY3RcIiApIHtcclxuXHRcdFx0b3B0aW9ucyA9IHVybDtcclxuXHRcdFx0dXJsID0gdW5kZWZpbmVkO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEZvcmNlIG9wdGlvbnMgdG8gYmUgYW4gb2JqZWN0XHJcblx0XHRvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcclxuXHJcblx0XHR2YXIgdHJhbnNwb3J0LFxyXG5cclxuXHRcdFx0Ly8gVVJMIHdpdGhvdXQgYW50aS1jYWNoZSBwYXJhbVxyXG5cdFx0XHRjYWNoZVVSTCxcclxuXHJcblx0XHRcdC8vIFJlc3BvbnNlIGhlYWRlcnNcclxuXHRcdFx0cmVzcG9uc2VIZWFkZXJzU3RyaW5nLFxyXG5cdFx0XHRyZXNwb25zZUhlYWRlcnMsXHJcblxyXG5cdFx0XHQvLyB0aW1lb3V0IGhhbmRsZVxyXG5cdFx0XHR0aW1lb3V0VGltZXIsXHJcblxyXG5cdFx0XHQvLyBVcmwgY2xlYW51cCB2YXJcclxuXHRcdFx0dXJsQW5jaG9yLFxyXG5cclxuXHRcdFx0Ly8gVG8ga25vdyBpZiBnbG9iYWwgZXZlbnRzIGFyZSB0byBiZSBkaXNwYXRjaGVkXHJcblx0XHRcdGZpcmVHbG9iYWxzLFxyXG5cclxuXHRcdFx0Ly8gTG9vcCB2YXJpYWJsZVxyXG5cdFx0XHRpLFxyXG5cclxuXHRcdFx0Ly8gQ3JlYXRlIHRoZSBmaW5hbCBvcHRpb25zIG9iamVjdFxyXG5cdFx0XHRzID0galF1ZXJ5LmFqYXhTZXR1cCgge30sIG9wdGlvbnMgKSxcclxuXHJcblx0XHRcdC8vIENhbGxiYWNrcyBjb250ZXh0XHJcblx0XHRcdGNhbGxiYWNrQ29udGV4dCA9IHMuY29udGV4dCB8fCBzLFxyXG5cclxuXHRcdFx0Ly8gQ29udGV4dCBmb3IgZ2xvYmFsIGV2ZW50cyBpcyBjYWxsYmFja0NvbnRleHQgaWYgaXQgaXMgYSBET00gbm9kZSBvciBqUXVlcnkgY29sbGVjdGlvblxyXG5cdFx0XHRnbG9iYWxFdmVudENvbnRleHQgPSBzLmNvbnRleHQgJiZcclxuXHRcdFx0XHQoIGNhbGxiYWNrQ29udGV4dC5ub2RlVHlwZSB8fCBjYWxsYmFja0NvbnRleHQuanF1ZXJ5ICkgP1xyXG5cdFx0XHRcdFx0alF1ZXJ5KCBjYWxsYmFja0NvbnRleHQgKSA6XHJcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQsXHJcblxyXG5cdFx0XHQvLyBEZWZlcnJlZHNcclxuXHRcdFx0ZGVmZXJyZWQgPSBqUXVlcnkuRGVmZXJyZWQoKSxcclxuXHRcdFx0Y29tcGxldGVEZWZlcnJlZCA9IGpRdWVyeS5DYWxsYmFja3MoIFwib25jZSBtZW1vcnlcIiApLFxyXG5cclxuXHRcdFx0Ly8gU3RhdHVzLWRlcGVuZGVudCBjYWxsYmFja3NcclxuXHRcdFx0c3RhdHVzQ29kZSA9IHMuc3RhdHVzQ29kZSB8fCB7fSxcclxuXHJcblx0XHRcdC8vIEhlYWRlcnMgKHRoZXkgYXJlIHNlbnQgYWxsIGF0IG9uY2UpXHJcblx0XHRcdHJlcXVlc3RIZWFkZXJzID0ge30sXHJcblx0XHRcdHJlcXVlc3RIZWFkZXJzTmFtZXMgPSB7fSxcclxuXHJcblx0XHRcdC8vIFRoZSBqcVhIUiBzdGF0ZVxyXG5cdFx0XHRzdGF0ZSA9IDAsXHJcblxyXG5cdFx0XHQvLyBEZWZhdWx0IGFib3J0IG1lc3NhZ2VcclxuXHRcdFx0c3RyQWJvcnQgPSBcImNhbmNlbGVkXCIsXHJcblxyXG5cdFx0XHQvLyBGYWtlIHhoclxyXG5cdFx0XHRqcVhIUiA9IHtcclxuXHRcdFx0XHRyZWFkeVN0YXRlOiAwLFxyXG5cclxuXHRcdFx0XHQvLyBCdWlsZHMgaGVhZGVycyBoYXNodGFibGUgaWYgbmVlZGVkXHJcblx0XHRcdFx0Z2V0UmVzcG9uc2VIZWFkZXI6IGZ1bmN0aW9uKCBrZXkgKSB7XHJcblx0XHRcdFx0XHR2YXIgbWF0Y2g7XHJcblx0XHRcdFx0XHRpZiAoIHN0YXRlID09PSAyICkge1xyXG5cdFx0XHRcdFx0XHRpZiAoICFyZXNwb25zZUhlYWRlcnMgKSB7XHJcblx0XHRcdFx0XHRcdFx0cmVzcG9uc2VIZWFkZXJzID0ge307XHJcblx0XHRcdFx0XHRcdFx0d2hpbGUgKCAoIG1hdGNoID0gcmhlYWRlcnMuZXhlYyggcmVzcG9uc2VIZWFkZXJzU3RyaW5nICkgKSApIHtcclxuXHRcdFx0XHRcdFx0XHRcdHJlc3BvbnNlSGVhZGVyc1sgbWF0Y2hbIDEgXS50b0xvd2VyQ2FzZSgpIF0gPSBtYXRjaFsgMiBdO1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRtYXRjaCA9IHJlc3BvbnNlSGVhZGVyc1sga2V5LnRvTG93ZXJDYXNlKCkgXTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdHJldHVybiBtYXRjaCA9PSBudWxsID8gbnVsbCA6IG1hdGNoO1xyXG5cdFx0XHRcdH0sXHJcblxyXG5cdFx0XHRcdC8vIFJhdyBzdHJpbmdcclxuXHRcdFx0XHRnZXRBbGxSZXNwb25zZUhlYWRlcnM6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIHN0YXRlID09PSAyID8gcmVzcG9uc2VIZWFkZXJzU3RyaW5nIDogbnVsbDtcclxuXHRcdFx0XHR9LFxyXG5cclxuXHRcdFx0XHQvLyBDYWNoZXMgdGhlIGhlYWRlclxyXG5cdFx0XHRcdHNldFJlcXVlc3RIZWFkZXI6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcclxuXHRcdFx0XHRcdHZhciBsbmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcclxuXHRcdFx0XHRcdGlmICggIXN0YXRlICkge1xyXG5cdFx0XHRcdFx0XHRuYW1lID0gcmVxdWVzdEhlYWRlcnNOYW1lc1sgbG5hbWUgXSA9IHJlcXVlc3RIZWFkZXJzTmFtZXNbIGxuYW1lIF0gfHwgbmFtZTtcclxuXHRcdFx0XHRcdFx0cmVxdWVzdEhlYWRlcnNbIG5hbWUgXSA9IHZhbHVlO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XHJcblx0XHRcdFx0fSxcclxuXHJcblx0XHRcdFx0Ly8gT3ZlcnJpZGVzIHJlc3BvbnNlIGNvbnRlbnQtdHlwZSBoZWFkZXJcclxuXHRcdFx0XHRvdmVycmlkZU1pbWVUeXBlOiBmdW5jdGlvbiggdHlwZSApIHtcclxuXHRcdFx0XHRcdGlmICggIXN0YXRlICkge1xyXG5cdFx0XHRcdFx0XHRzLm1pbWVUeXBlID0gdHlwZTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0XHRcdH0sXHJcblxyXG5cdFx0XHRcdC8vIFN0YXR1cy1kZXBlbmRlbnQgY2FsbGJhY2tzXHJcblx0XHRcdFx0c3RhdHVzQ29kZTogZnVuY3Rpb24oIG1hcCApIHtcclxuXHRcdFx0XHRcdHZhciBjb2RlO1xyXG5cdFx0XHRcdFx0aWYgKCBtYXAgKSB7XHJcblx0XHRcdFx0XHRcdGlmICggc3RhdGUgPCAyICkge1xyXG5cdFx0XHRcdFx0XHRcdGZvciAoIGNvZGUgaW4gbWFwICkge1xyXG5cclxuXHRcdFx0XHRcdFx0XHRcdC8vIExhenktYWRkIHRoZSBuZXcgY2FsbGJhY2sgaW4gYSB3YXkgdGhhdCBwcmVzZXJ2ZXMgb2xkIG9uZXNcclxuXHRcdFx0XHRcdFx0XHRcdHN0YXR1c0NvZGVbIGNvZGUgXSA9IFsgc3RhdHVzQ29kZVsgY29kZSBdLCBtYXBbIGNvZGUgXSBdO1xyXG5cdFx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHJcblx0XHRcdFx0XHRcdFx0Ly8gRXhlY3V0ZSB0aGUgYXBwcm9wcmlhdGUgY2FsbGJhY2tzXHJcblx0XHRcdFx0XHRcdFx0anFYSFIuYWx3YXlzKCBtYXBbIGpxWEhSLnN0YXR1cyBdICk7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0XHRcdH0sXHJcblxyXG5cdFx0XHRcdC8vIENhbmNlbCB0aGUgcmVxdWVzdFxyXG5cdFx0XHRcdGFib3J0OiBmdW5jdGlvbiggc3RhdHVzVGV4dCApIHtcclxuXHRcdFx0XHRcdHZhciBmaW5hbFRleHQgPSBzdGF0dXNUZXh0IHx8IHN0ckFib3J0O1xyXG5cdFx0XHRcdFx0aWYgKCB0cmFuc3BvcnQgKSB7XHJcblx0XHRcdFx0XHRcdHRyYW5zcG9ydC5hYm9ydCggZmluYWxUZXh0ICk7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHRkb25lKCAwLCBmaW5hbFRleHQgKTtcclxuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fTtcclxuXHJcblx0XHQvLyBBdHRhY2ggZGVmZXJyZWRzXHJcblx0XHRkZWZlcnJlZC5wcm9taXNlKCBqcVhIUiApLmNvbXBsZXRlID0gY29tcGxldGVEZWZlcnJlZC5hZGQ7XHJcblx0XHRqcVhIUi5zdWNjZXNzID0ganFYSFIuZG9uZTtcclxuXHRcdGpxWEhSLmVycm9yID0ganFYSFIuZmFpbDtcclxuXHJcblx0XHQvLyBSZW1vdmUgaGFzaCBjaGFyYWN0ZXIgKCM3NTMxOiBhbmQgc3RyaW5nIHByb21vdGlvbilcclxuXHRcdC8vIEFkZCBwcm90b2NvbCBpZiBub3QgcHJvdmlkZWQgKHByZWZpbHRlcnMgbWlnaHQgZXhwZWN0IGl0KVxyXG5cdFx0Ly8gSGFuZGxlIGZhbHN5IHVybCBpbiB0aGUgc2V0dGluZ3Mgb2JqZWN0ICgjMTAwOTM6IGNvbnNpc3RlbmN5IHdpdGggb2xkIHNpZ25hdHVyZSlcclxuXHRcdC8vIFdlIGFsc28gdXNlIHRoZSB1cmwgcGFyYW1ldGVyIGlmIGF2YWlsYWJsZVxyXG5cdFx0cy51cmwgPSAoICggdXJsIHx8IHMudXJsIHx8IGxvY2F0aW9uLmhyZWYgKSArIFwiXCIgKS5yZXBsYWNlKCByaGFzaCwgXCJcIiApXHJcblx0XHRcdC5yZXBsYWNlKCBycHJvdG9jb2wsIGxvY2F0aW9uLnByb3RvY29sICsgXCIvL1wiICk7XHJcblxyXG5cdFx0Ly8gQWxpYXMgbWV0aG9kIG9wdGlvbiB0byB0eXBlIGFzIHBlciB0aWNrZXQgIzEyMDA0XHJcblx0XHRzLnR5cGUgPSBvcHRpb25zLm1ldGhvZCB8fCBvcHRpb25zLnR5cGUgfHwgcy5tZXRob2QgfHwgcy50eXBlO1xyXG5cclxuXHRcdC8vIEV4dHJhY3QgZGF0YVR5cGVzIGxpc3RcclxuXHRcdHMuZGF0YVR5cGVzID0galF1ZXJ5LnRyaW0oIHMuZGF0YVR5cGUgfHwgXCIqXCIgKS50b0xvd2VyQ2FzZSgpLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbIFwiXCIgXTtcclxuXHJcblx0XHQvLyBBIGNyb3NzLWRvbWFpbiByZXF1ZXN0IGlzIGluIG9yZGVyIHdoZW4gdGhlIG9yaWdpbiBkb2Vzbid0IG1hdGNoIHRoZSBjdXJyZW50IG9yaWdpbi5cclxuXHRcdGlmICggcy5jcm9zc0RvbWFpbiA9PSBudWxsICkge1xyXG5cdFx0XHR1cmxBbmNob3IgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImFcIiApO1xyXG5cclxuXHRcdFx0Ly8gU3VwcG9ydDogSUU4LTExK1xyXG5cdFx0XHQvLyBJRSB0aHJvd3MgZXhjZXB0aW9uIGlmIHVybCBpcyBtYWxmb3JtZWQsIGUuZy4gaHR0cDovL2V4YW1wbGUuY29tOjgweC9cclxuXHRcdFx0dHJ5IHtcclxuXHRcdFx0XHR1cmxBbmNob3IuaHJlZiA9IHMudXJsO1xyXG5cclxuXHRcdFx0XHQvLyBTdXBwb3J0OiBJRTgtMTErXHJcblx0XHRcdFx0Ly8gQW5jaG9yJ3MgaG9zdCBwcm9wZXJ0eSBpc24ndCBjb3JyZWN0bHkgc2V0IHdoZW4gcy51cmwgaXMgcmVsYXRpdmVcclxuXHRcdFx0XHR1cmxBbmNob3IuaHJlZiA9IHVybEFuY2hvci5ocmVmO1xyXG5cdFx0XHRcdHMuY3Jvc3NEb21haW4gPSBvcmlnaW5BbmNob3IucHJvdG9jb2wgKyBcIi8vXCIgKyBvcmlnaW5BbmNob3IuaG9zdCAhPT1cclxuXHRcdFx0XHRcdHVybEFuY2hvci5wcm90b2NvbCArIFwiLy9cIiArIHVybEFuY2hvci5ob3N0O1xyXG5cdFx0XHR9IGNhdGNoICggZSApIHtcclxuXHJcblx0XHRcdFx0Ly8gSWYgdGhlcmUgaXMgYW4gZXJyb3IgcGFyc2luZyB0aGUgVVJMLCBhc3N1bWUgaXQgaXMgY3Jvc3NEb21haW4sXHJcblx0XHRcdFx0Ly8gaXQgY2FuIGJlIHJlamVjdGVkIGJ5IHRoZSB0cmFuc3BvcnQgaWYgaXQgaXMgaW52YWxpZFxyXG5cdFx0XHRcdHMuY3Jvc3NEb21haW4gPSB0cnVlO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQ29udmVydCBkYXRhIGlmIG5vdCBhbHJlYWR5IGEgc3RyaW5nXHJcblx0XHRpZiAoIHMuZGF0YSAmJiBzLnByb2Nlc3NEYXRhICYmIHR5cGVvZiBzLmRhdGEgIT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRcdHMuZGF0YSA9IGpRdWVyeS5wYXJhbSggcy5kYXRhLCBzLnRyYWRpdGlvbmFsICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQXBwbHkgcHJlZmlsdGVyc1xyXG5cdFx0aW5zcGVjdFByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHByZWZpbHRlcnMsIHMsIG9wdGlvbnMsIGpxWEhSICk7XHJcblxyXG5cdFx0Ly8gSWYgcmVxdWVzdCB3YXMgYWJvcnRlZCBpbnNpZGUgYSBwcmVmaWx0ZXIsIHN0b3AgdGhlcmVcclxuXHRcdGlmICggc3RhdGUgPT09IDIgKSB7XHJcblx0XHRcdHJldHVybiBqcVhIUjtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBXZSBjYW4gZmlyZSBnbG9iYWwgZXZlbnRzIGFzIG9mIG5vdyBpZiBhc2tlZCB0b1xyXG5cdFx0Ly8gRG9uJ3QgZmlyZSBldmVudHMgaWYgalF1ZXJ5LmV2ZW50IGlzIHVuZGVmaW5lZCBpbiBhbiBBTUQtdXNhZ2Ugc2NlbmFyaW8gKCMxNTExOClcclxuXHRcdGZpcmVHbG9iYWxzID0galF1ZXJ5LmV2ZW50ICYmIHMuZ2xvYmFsO1xyXG5cclxuXHRcdC8vIFdhdGNoIGZvciBhIG5ldyBzZXQgb2YgcmVxdWVzdHNcclxuXHRcdGlmICggZmlyZUdsb2JhbHMgJiYgalF1ZXJ5LmFjdGl2ZSsrID09PSAwICkge1xyXG5cdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlciggXCJhamF4U3RhcnRcIiApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFVwcGVyY2FzZSB0aGUgdHlwZVxyXG5cdFx0cy50eXBlID0gcy50eXBlLnRvVXBwZXJDYXNlKCk7XHJcblxyXG5cdFx0Ly8gRGV0ZXJtaW5lIGlmIHJlcXVlc3QgaGFzIGNvbnRlbnRcclxuXHRcdHMuaGFzQ29udGVudCA9ICFybm9Db250ZW50LnRlc3QoIHMudHlwZSApO1xyXG5cclxuXHRcdC8vIFNhdmUgdGhlIFVSTCBpbiBjYXNlIHdlJ3JlIHRveWluZyB3aXRoIHRoZSBJZi1Nb2RpZmllZC1TaW5jZVxyXG5cdFx0Ly8gYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyIGxhdGVyIG9uXHJcblx0XHRjYWNoZVVSTCA9IHMudXJsO1xyXG5cclxuXHRcdC8vIE1vcmUgb3B0aW9ucyBoYW5kbGluZyBmb3IgcmVxdWVzdHMgd2l0aCBubyBjb250ZW50XHJcblx0XHRpZiAoICFzLmhhc0NvbnRlbnQgKSB7XHJcblxyXG5cdFx0XHQvLyBJZiBkYXRhIGlzIGF2YWlsYWJsZSwgYXBwZW5kIGRhdGEgdG8gdXJsXHJcblx0XHRcdGlmICggcy5kYXRhICkge1xyXG5cdFx0XHRcdGNhY2hlVVJMID0gKCBzLnVybCArPSAoIHJxdWVyeS50ZXN0KCBjYWNoZVVSTCApID8gXCImXCIgOiBcIj9cIiApICsgcy5kYXRhICk7XHJcblxyXG5cdFx0XHRcdC8vICM5NjgyOiByZW1vdmUgZGF0YSBzbyB0aGF0IGl0J3Mgbm90IHVzZWQgaW4gYW4gZXZlbnR1YWwgcmV0cnlcclxuXHRcdFx0XHRkZWxldGUgcy5kYXRhO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBBZGQgYW50aS1jYWNoZSBpbiB1cmwgaWYgbmVlZGVkXHJcblx0XHRcdGlmICggcy5jYWNoZSA9PT0gZmFsc2UgKSB7XHJcblx0XHRcdFx0cy51cmwgPSBydHMudGVzdCggY2FjaGVVUkwgKSA/XHJcblxyXG5cdFx0XHRcdFx0Ly8gSWYgdGhlcmUgaXMgYWxyZWFkeSBhICdfJyBwYXJhbWV0ZXIsIHNldCBpdHMgdmFsdWVcclxuXHRcdFx0XHRcdGNhY2hlVVJMLnJlcGxhY2UoIHJ0cywgXCIkMV89XCIgKyBub25jZSsrICkgOlxyXG5cclxuXHRcdFx0XHRcdC8vIE90aGVyd2lzZSBhZGQgb25lIHRvIHRoZSBlbmRcclxuXHRcdFx0XHRcdGNhY2hlVVJMICsgKCBycXVlcnkudGVzdCggY2FjaGVVUkwgKSA/IFwiJlwiIDogXCI/XCIgKSArIFwiXz1cIiArIG5vbmNlKys7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBTZXQgdGhlIElmLU1vZGlmaWVkLVNpbmNlIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciwgaWYgaW4gaWZNb2RpZmllZCBtb2RlLlxyXG5cdFx0aWYgKCBzLmlmTW9kaWZpZWQgKSB7XHJcblx0XHRcdGlmICggalF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSApIHtcclxuXHRcdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBcIklmLU1vZGlmaWVkLVNpbmNlXCIsIGpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRpZiAoIGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdICkge1xyXG5cdFx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIFwiSWYtTm9uZS1NYXRjaFwiLCBqUXVlcnkuZXRhZ1sgY2FjaGVVUkwgXSApO1xyXG5cdFx0XHR9XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gU2V0IHRoZSBjb3JyZWN0IGhlYWRlciwgaWYgZGF0YSBpcyBiZWluZyBzZW50XHJcblx0XHRpZiAoIHMuZGF0YSAmJiBzLmhhc0NvbnRlbnQgJiYgcy5jb250ZW50VHlwZSAhPT0gZmFsc2UgfHwgb3B0aW9ucy5jb250ZW50VHlwZSApIHtcclxuXHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggXCJDb250ZW50LVR5cGVcIiwgcy5jb250ZW50VHlwZSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFNldCB0aGUgQWNjZXB0cyBoZWFkZXIgZm9yIHRoZSBzZXJ2ZXIsIGRlcGVuZGluZyBvbiB0aGUgZGF0YVR5cGVcclxuXHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoXHJcblx0XHRcdFwiQWNjZXB0XCIsXHJcblx0XHRcdHMuZGF0YVR5cGVzWyAwIF0gJiYgcy5hY2NlcHRzWyBzLmRhdGFUeXBlc1sgMCBdIF0gP1xyXG5cdFx0XHRcdHMuYWNjZXB0c1sgcy5kYXRhVHlwZXNbIDAgXSBdICtcclxuXHRcdFx0XHRcdCggcy5kYXRhVHlwZXNbIDAgXSAhPT0gXCIqXCIgPyBcIiwgXCIgKyBhbGxUeXBlcyArIFwiOyBxPTAuMDFcIiA6IFwiXCIgKSA6XHJcblx0XHRcdFx0cy5hY2NlcHRzWyBcIipcIiBdXHJcblx0XHQpO1xyXG5cclxuXHRcdC8vIENoZWNrIGZvciBoZWFkZXJzIG9wdGlvblxyXG5cdFx0Zm9yICggaSBpbiBzLmhlYWRlcnMgKSB7XHJcblx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIGksIHMuaGVhZGVyc1sgaSBdICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gQWxsb3cgY3VzdG9tIGhlYWRlcnMvbWltZXR5cGVzIGFuZCBlYXJseSBhYm9ydFxyXG5cdFx0aWYgKCBzLmJlZm9yZVNlbmQgJiZcclxuXHRcdFx0KCBzLmJlZm9yZVNlbmQuY2FsbCggY2FsbGJhY2tDb250ZXh0LCBqcVhIUiwgcyApID09PSBmYWxzZSB8fCBzdGF0ZSA9PT0gMiApICkge1xyXG5cclxuXHRcdFx0Ly8gQWJvcnQgaWYgbm90IGRvbmUgYWxyZWFkeSBhbmQgcmV0dXJuXHJcblx0XHRcdHJldHVybiBqcVhIUi5hYm9ydCgpO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEFib3J0aW5nIGlzIG5vIGxvbmdlciBhIGNhbmNlbGxhdGlvblxyXG5cdFx0c3RyQWJvcnQgPSBcImFib3J0XCI7XHJcblxyXG5cdFx0Ly8gSW5zdGFsbCBjYWxsYmFja3Mgb24gZGVmZXJyZWRzXHJcblx0XHRmb3IgKCBpIGluIHsgc3VjY2VzczogMSwgZXJyb3I6IDEsIGNvbXBsZXRlOiAxIH0gKSB7XHJcblx0XHRcdGpxWEhSWyBpIF0oIHNbIGkgXSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIEdldCB0cmFuc3BvcnRcclxuXHRcdHRyYW5zcG9ydCA9IGluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCB0cmFuc3BvcnRzLCBzLCBvcHRpb25zLCBqcVhIUiApO1xyXG5cclxuXHRcdC8vIElmIG5vIHRyYW5zcG9ydCwgd2UgYXV0by1hYm9ydFxyXG5cdFx0aWYgKCAhdHJhbnNwb3J0ICkge1xyXG5cdFx0XHRkb25lKCAtMSwgXCJObyBUcmFuc3BvcnRcIiApO1xyXG5cdFx0fSBlbHNlIHtcclxuXHRcdFx0anFYSFIucmVhZHlTdGF0ZSA9IDE7XHJcblxyXG5cdFx0XHQvLyBTZW5kIGdsb2JhbCBldmVudFxyXG5cdFx0XHRpZiAoIGZpcmVHbG9iYWxzICkge1xyXG5cdFx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCBcImFqYXhTZW5kXCIsIFsganFYSFIsIHMgXSApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBJZiByZXF1ZXN0IHdhcyBhYm9ydGVkIGluc2lkZSBhamF4U2VuZCwgc3RvcCB0aGVyZVxyXG5cdFx0XHRpZiAoIHN0YXRlID09PSAyICkge1xyXG5cdFx0XHRcdHJldHVybiBqcVhIUjtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gVGltZW91dFxyXG5cdFx0XHRpZiAoIHMuYXN5bmMgJiYgcy50aW1lb3V0ID4gMCApIHtcclxuXHRcdFx0XHR0aW1lb3V0VGltZXIgPSB3aW5kb3cuc2V0VGltZW91dCggZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0XHRqcVhIUi5hYm9ydCggXCJ0aW1lb3V0XCIgKTtcclxuXHRcdFx0XHR9LCBzLnRpbWVvdXQgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0dHJ5IHtcclxuXHRcdFx0XHRzdGF0ZSA9IDE7XHJcblx0XHRcdFx0dHJhbnNwb3J0LnNlbmQoIHJlcXVlc3RIZWFkZXJzLCBkb25lICk7XHJcblx0XHRcdH0gY2F0Y2ggKCBlICkge1xyXG5cclxuXHRcdFx0XHQvLyBQcm9wYWdhdGUgZXhjZXB0aW9uIGFzIGVycm9yIGlmIG5vdCBkb25lXHJcblx0XHRcdFx0aWYgKCBzdGF0ZSA8IDIgKSB7XHJcblx0XHRcdFx0XHRkb25lKCAtMSwgZSApO1xyXG5cclxuXHRcdFx0XHQvLyBTaW1wbHkgcmV0aHJvdyBvdGhlcndpc2VcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0dGhyb3cgZTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHJcblx0XHQvLyBDYWxsYmFjayBmb3Igd2hlbiBldmVyeXRoaW5nIGlzIGRvbmVcclxuXHRcdGZ1bmN0aW9uIGRvbmUoIHN0YXR1cywgbmF0aXZlU3RhdHVzVGV4dCwgcmVzcG9uc2VzLCBoZWFkZXJzICkge1xyXG5cdFx0XHR2YXIgaXNTdWNjZXNzLCBzdWNjZXNzLCBlcnJvciwgcmVzcG9uc2UsIG1vZGlmaWVkLFxyXG5cdFx0XHRcdHN0YXR1c1RleHQgPSBuYXRpdmVTdGF0dXNUZXh0O1xyXG5cclxuXHRcdFx0Ly8gQ2FsbGVkIG9uY2VcclxuXHRcdFx0aWYgKCBzdGF0ZSA9PT0gMiApIHtcclxuXHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFN0YXRlIGlzIFwiZG9uZVwiIG5vd1xyXG5cdFx0XHRzdGF0ZSA9IDI7XHJcblxyXG5cdFx0XHQvLyBDbGVhciB0aW1lb3V0IGlmIGl0IGV4aXN0c1xyXG5cdFx0XHRpZiAoIHRpbWVvdXRUaW1lciApIHtcclxuXHRcdFx0XHR3aW5kb3cuY2xlYXJUaW1lb3V0KCB0aW1lb3V0VGltZXIgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gRGVyZWZlcmVuY2UgdHJhbnNwb3J0IGZvciBlYXJseSBnYXJiYWdlIGNvbGxlY3Rpb25cclxuXHRcdFx0Ly8gKG5vIG1hdHRlciBob3cgbG9uZyB0aGUganFYSFIgb2JqZWN0IHdpbGwgYmUgdXNlZClcclxuXHRcdFx0dHJhbnNwb3J0ID0gdW5kZWZpbmVkO1xyXG5cclxuXHRcdFx0Ly8gQ2FjaGUgcmVzcG9uc2UgaGVhZGVyc1xyXG5cdFx0XHRyZXNwb25zZUhlYWRlcnNTdHJpbmcgPSBoZWFkZXJzIHx8IFwiXCI7XHJcblxyXG5cdFx0XHQvLyBTZXQgcmVhZHlTdGF0ZVxyXG5cdFx0XHRqcVhIUi5yZWFkeVN0YXRlID0gc3RhdHVzID4gMCA/IDQgOiAwO1xyXG5cclxuXHRcdFx0Ly8gRGV0ZXJtaW5lIGlmIHN1Y2Nlc3NmdWxcclxuXHRcdFx0aXNTdWNjZXNzID0gc3RhdHVzID49IDIwMCAmJiBzdGF0dXMgPCAzMDAgfHwgc3RhdHVzID09PSAzMDQ7XHJcblxyXG5cdFx0XHQvLyBHZXQgcmVzcG9uc2UgZGF0YVxyXG5cdFx0XHRpZiAoIHJlc3BvbnNlcyApIHtcclxuXHRcdFx0XHRyZXNwb25zZSA9IGFqYXhIYW5kbGVSZXNwb25zZXMoIHMsIGpxWEhSLCByZXNwb25zZXMgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gQ29udmVydCBubyBtYXR0ZXIgd2hhdCAodGhhdCB3YXkgcmVzcG9uc2VYWFggZmllbGRzIGFyZSBhbHdheXMgc2V0KVxyXG5cdFx0XHRyZXNwb25zZSA9IGFqYXhDb252ZXJ0KCBzLCByZXNwb25zZSwganFYSFIsIGlzU3VjY2VzcyApO1xyXG5cclxuXHRcdFx0Ly8gSWYgc3VjY2Vzc2Z1bCwgaGFuZGxlIHR5cGUgY2hhaW5pbmdcclxuXHRcdFx0aWYgKCBpc1N1Y2Nlc3MgKSB7XHJcblxyXG5cdFx0XHRcdC8vIFNldCB0aGUgSWYtTW9kaWZpZWQtU2luY2UgYW5kL29yIElmLU5vbmUtTWF0Y2ggaGVhZGVyLCBpZiBpbiBpZk1vZGlmaWVkIG1vZGUuXHJcblx0XHRcdFx0aWYgKCBzLmlmTW9kaWZpZWQgKSB7XHJcblx0XHRcdFx0XHRtb2RpZmllZCA9IGpxWEhSLmdldFJlc3BvbnNlSGVhZGVyKCBcIkxhc3QtTW9kaWZpZWRcIiApO1xyXG5cdFx0XHRcdFx0aWYgKCBtb2RpZmllZCApIHtcclxuXHRcdFx0XHRcdFx0alF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSA9IG1vZGlmaWVkO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0bW9kaWZpZWQgPSBqcVhIUi5nZXRSZXNwb25zZUhlYWRlciggXCJldGFnXCIgKTtcclxuXHRcdFx0XHRcdGlmICggbW9kaWZpZWQgKSB7XHJcblx0XHRcdFx0XHRcdGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdID0gbW9kaWZpZWQ7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHQvLyBpZiBubyBjb250ZW50XHJcblx0XHRcdFx0aWYgKCBzdGF0dXMgPT09IDIwNCB8fCBzLnR5cGUgPT09IFwiSEVBRFwiICkge1xyXG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwibm9jb250ZW50XCI7XHJcblxyXG5cdFx0XHRcdC8vIGlmIG5vdCBtb2RpZmllZFxyXG5cdFx0XHRcdH0gZWxzZSBpZiAoIHN0YXR1cyA9PT0gMzA0ICkge1xyXG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwibm90bW9kaWZpZWRcIjtcclxuXHJcblx0XHRcdFx0Ly8gSWYgd2UgaGF2ZSBkYXRhLCBsZXQncyBjb252ZXJ0IGl0XHJcblx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdHN0YXR1c1RleHQgPSByZXNwb25zZS5zdGF0ZTtcclxuXHRcdFx0XHRcdHN1Y2Nlc3MgPSByZXNwb25zZS5kYXRhO1xyXG5cdFx0XHRcdFx0ZXJyb3IgPSByZXNwb25zZS5lcnJvcjtcclxuXHRcdFx0XHRcdGlzU3VjY2VzcyA9ICFlcnJvcjtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH0gZWxzZSB7XHJcblxyXG5cdFx0XHRcdC8vIEV4dHJhY3QgZXJyb3IgZnJvbSBzdGF0dXNUZXh0IGFuZCBub3JtYWxpemUgZm9yIG5vbi1hYm9ydHNcclxuXHRcdFx0XHRlcnJvciA9IHN0YXR1c1RleHQ7XHJcblx0XHRcdFx0aWYgKCBzdGF0dXMgfHwgIXN0YXR1c1RleHQgKSB7XHJcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gXCJlcnJvclwiO1xyXG5cdFx0XHRcdFx0aWYgKCBzdGF0dXMgPCAwICkge1xyXG5cdFx0XHRcdFx0XHRzdGF0dXMgPSAwO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gU2V0IGRhdGEgZm9yIHRoZSBmYWtlIHhociBvYmplY3RcclxuXHRcdFx0anFYSFIuc3RhdHVzID0gc3RhdHVzO1xyXG5cdFx0XHRqcVhIUi5zdGF0dXNUZXh0ID0gKCBuYXRpdmVTdGF0dXNUZXh0IHx8IHN0YXR1c1RleHQgKSArIFwiXCI7XHJcblxyXG5cdFx0XHQvLyBTdWNjZXNzL0Vycm9yXHJcblx0XHRcdGlmICggaXNTdWNjZXNzICkge1xyXG5cdFx0XHRcdGRlZmVycmVkLnJlc29sdmVXaXRoKCBjYWxsYmFja0NvbnRleHQsIFsgc3VjY2Vzcywgc3RhdHVzVGV4dCwganFYSFIgXSApO1xyXG5cdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdGRlZmVycmVkLnJlamVjdFdpdGgoIGNhbGxiYWNrQ29udGV4dCwgWyBqcVhIUiwgc3RhdHVzVGV4dCwgZXJyb3IgXSApO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBTdGF0dXMtZGVwZW5kZW50IGNhbGxiYWNrc1xyXG5cdFx0XHRqcVhIUi5zdGF0dXNDb2RlKCBzdGF0dXNDb2RlICk7XHJcblx0XHRcdHN0YXR1c0NvZGUgPSB1bmRlZmluZWQ7XHJcblxyXG5cdFx0XHRpZiAoIGZpcmVHbG9iYWxzICkge1xyXG5cdFx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCBpc1N1Y2Nlc3MgPyBcImFqYXhTdWNjZXNzXCIgOiBcImFqYXhFcnJvclwiLFxyXG5cdFx0XHRcdFx0WyBqcVhIUiwgcywgaXNTdWNjZXNzID8gc3VjY2VzcyA6IGVycm9yIF0gKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gQ29tcGxldGVcclxuXHRcdFx0Y29tcGxldGVEZWZlcnJlZC5maXJlV2l0aCggY2FsbGJhY2tDb250ZXh0LCBbIGpxWEhSLCBzdGF0dXNUZXh0IF0gKTtcclxuXHJcblx0XHRcdGlmICggZmlyZUdsb2JhbHMgKSB7XHJcblx0XHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0LnRyaWdnZXIoIFwiYWpheENvbXBsZXRlXCIsIFsganFYSFIsIHMgXSApO1xyXG5cclxuXHRcdFx0XHQvLyBIYW5kbGUgdGhlIGdsb2JhbCBBSkFYIGNvdW50ZXJcclxuXHRcdFx0XHRpZiAoICEoIC0talF1ZXJ5LmFjdGl2ZSApICkge1xyXG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoIFwiYWpheFN0b3BcIiApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiBqcVhIUjtcclxuXHR9LFxyXG5cclxuXHRnZXRKU09OOiBmdW5jdGlvbiggdXJsLCBkYXRhLCBjYWxsYmFjayApIHtcclxuXHRcdHJldHVybiBqUXVlcnkuZ2V0KCB1cmwsIGRhdGEsIGNhbGxiYWNrLCBcImpzb25cIiApO1xyXG5cdH0sXHJcblxyXG5cdGdldFNjcmlwdDogZnVuY3Rpb24oIHVybCwgY2FsbGJhY2sgKSB7XHJcblx0XHRyZXR1cm4galF1ZXJ5LmdldCggdXJsLCB1bmRlZmluZWQsIGNhbGxiYWNrLCBcInNjcmlwdFwiICk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5qUXVlcnkuZWFjaCggWyBcImdldFwiLCBcInBvc3RcIiBdLCBmdW5jdGlvbiggaSwgbWV0aG9kICkge1xyXG5cdGpRdWVyeVsgbWV0aG9kIF0gPSBmdW5jdGlvbiggdXJsLCBkYXRhLCBjYWxsYmFjaywgdHlwZSApIHtcclxuXHJcblx0XHQvLyBTaGlmdCBhcmd1bWVudHMgaWYgZGF0YSBhcmd1bWVudCB3YXMgb21pdHRlZFxyXG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggZGF0YSApICkge1xyXG5cdFx0XHR0eXBlID0gdHlwZSB8fCBjYWxsYmFjaztcclxuXHRcdFx0Y2FsbGJhY2sgPSBkYXRhO1xyXG5cdFx0XHRkYXRhID0gdW5kZWZpbmVkO1xyXG5cdFx0fVxyXG5cclxuXHRcdC8vIFRoZSB1cmwgY2FuIGJlIGFuIG9wdGlvbnMgb2JqZWN0ICh3aGljaCB0aGVuIG11c3QgaGF2ZSAudXJsKVxyXG5cdFx0cmV0dXJuIGpRdWVyeS5hamF4KCBqUXVlcnkuZXh0ZW5kKCB7XHJcblx0XHRcdHVybDogdXJsLFxyXG5cdFx0XHR0eXBlOiBtZXRob2QsXHJcblx0XHRcdGRhdGFUeXBlOiB0eXBlLFxyXG5cdFx0XHRkYXRhOiBkYXRhLFxyXG5cdFx0XHRzdWNjZXNzOiBjYWxsYmFja1xyXG5cdFx0fSwgalF1ZXJ5LmlzUGxhaW5PYmplY3QoIHVybCApICYmIHVybCApICk7XHJcblx0fTtcclxufSApO1xyXG5cclxuXHJcbmpRdWVyeS5fZXZhbFVybCA9IGZ1bmN0aW9uKCB1cmwgKSB7XHJcblx0cmV0dXJuIGpRdWVyeS5hamF4KCB7XHJcblx0XHR1cmw6IHVybCxcclxuXHJcblx0XHQvLyBNYWtlIHRoaXMgZXhwbGljaXQsIHNpbmNlIHVzZXIgY2FuIG92ZXJyaWRlIHRoaXMgdGhyb3VnaCBhamF4U2V0dXAgKCMxMTI2NClcclxuXHRcdHR5cGU6IFwiR0VUXCIsXHJcblx0XHRkYXRhVHlwZTogXCJzY3JpcHRcIixcclxuXHRcdGFzeW5jOiBmYWxzZSxcclxuXHRcdGdsb2JhbDogZmFsc2UsXHJcblx0XHRcInRocm93c1wiOiB0cnVlXHJcblx0fSApO1xyXG59O1xyXG5cclxuXHJcbmpRdWVyeS5mbi5leHRlbmQoIHtcclxuXHR3cmFwQWxsOiBmdW5jdGlvbiggaHRtbCApIHtcclxuXHRcdHZhciB3cmFwO1xyXG5cclxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIGh0bWwgKSApIHtcclxuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XHJcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkud3JhcEFsbCggaHRtbC5jYWxsKCB0aGlzLCBpICkgKTtcclxuXHRcdFx0fSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdGlmICggdGhpc1sgMCBdICkge1xyXG5cclxuXHRcdFx0Ly8gVGhlIGVsZW1lbnRzIHRvIHdyYXAgdGhlIHRhcmdldCBhcm91bmRcclxuXHRcdFx0d3JhcCA9IGpRdWVyeSggaHRtbCwgdGhpc1sgMCBdLm93bmVyRG9jdW1lbnQgKS5lcSggMCApLmNsb25lKCB0cnVlICk7XHJcblxyXG5cdFx0XHRpZiAoIHRoaXNbIDAgXS5wYXJlbnROb2RlICkge1xyXG5cdFx0XHRcdHdyYXAuaW5zZXJ0QmVmb3JlKCB0aGlzWyAwIF0gKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0d3JhcC5tYXAoIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdHZhciBlbGVtID0gdGhpcztcclxuXHJcblx0XHRcdFx0d2hpbGUgKCBlbGVtLmZpcnN0RWxlbWVudENoaWxkICkge1xyXG5cdFx0XHRcdFx0ZWxlbSA9IGVsZW0uZmlyc3RFbGVtZW50Q2hpbGQ7XHJcblx0XHRcdFx0fVxyXG5cclxuXHRcdFx0XHRyZXR1cm4gZWxlbTtcclxuXHRcdFx0fSApLmFwcGVuZCggdGhpcyApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzO1xyXG5cdH0sXHJcblxyXG5cdHdyYXBJbm5lcjogZnVuY3Rpb24oIGh0bWwgKSB7XHJcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBodG1sICkgKSB7XHJcblx0XHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkge1xyXG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLndyYXBJbm5lciggaHRtbC5jYWxsKCB0aGlzLCBpICkgKTtcclxuXHRcdFx0fSApO1xyXG5cdFx0fVxyXG5cclxuXHRcdHJldHVybiB0aGlzLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR2YXIgc2VsZiA9IGpRdWVyeSggdGhpcyApLFxyXG5cdFx0XHRcdGNvbnRlbnRzID0gc2VsZi5jb250ZW50cygpO1xyXG5cclxuXHRcdFx0aWYgKCBjb250ZW50cy5sZW5ndGggKSB7XHJcblx0XHRcdFx0Y29udGVudHMud3JhcEFsbCggaHRtbCApO1xyXG5cclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRzZWxmLmFwcGVuZCggaHRtbCApO1xyXG5cdFx0XHR9XHJcblx0XHR9ICk7XHJcblx0fSxcclxuXHJcblx0d3JhcDogZnVuY3Rpb24oIGh0bWwgKSB7XHJcblx0XHR2YXIgaXNGdW5jdGlvbiA9IGpRdWVyeS5pc0Z1bmN0aW9uKCBodG1sICk7XHJcblxyXG5cdFx0cmV0dXJuIHRoaXMuZWFjaCggZnVuY3Rpb24oIGkgKSB7XHJcblx0XHRcdGpRdWVyeSggdGhpcyApLndyYXBBbGwoIGlzRnVuY3Rpb24gPyBodG1sLmNhbGwoIHRoaXMsIGkgKSA6IGh0bWwgKTtcclxuXHRcdH0gKTtcclxuXHR9LFxyXG5cclxuXHR1bndyYXA6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMucGFyZW50KCkuZWFjaCggZnVuY3Rpb24oKSB7XHJcblx0XHRcdGlmICggIWpRdWVyeS5ub2RlTmFtZSggdGhpcywgXCJib2R5XCIgKSApIHtcclxuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5yZXBsYWNlV2l0aCggdGhpcy5jaGlsZE5vZGVzICk7XHJcblx0XHRcdH1cclxuXHRcdH0gKS5lbmQoKTtcclxuXHR9XHJcbn0gKTtcclxuXHJcblxyXG5qUXVlcnkuZXhwci5maWx0ZXJzLmhpZGRlbiA9IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cdHJldHVybiAhalF1ZXJ5LmV4cHIuZmlsdGVycy52aXNpYmxlKCBlbGVtICk7XHJcbn07XHJcbmpRdWVyeS5leHByLmZpbHRlcnMudmlzaWJsZSA9IGZ1bmN0aW9uKCBlbGVtICkge1xyXG5cclxuXHQvLyBTdXBwb3J0OiBPcGVyYSA8PSAxMi4xMlxyXG5cdC8vIE9wZXJhIHJlcG9ydHMgb2Zmc2V0V2lkdGhzIGFuZCBvZmZzZXRIZWlnaHRzIGxlc3MgdGhhbiB6ZXJvIG9uIHNvbWUgZWxlbWVudHNcclxuXHQvLyBVc2UgT1IgaW5zdGVhZCBvZiBBTkQgYXMgdGhlIGVsZW1lbnQgaXMgbm90IHZpc2libGUgaWYgZWl0aGVyIGlzIHRydWVcclxuXHQvLyBTZWUgdGlja2V0cyAjMTA0MDYgYW5kICMxMzEzMlxyXG5cdHJldHVybiBlbGVtLm9mZnNldFdpZHRoID4gMCB8fCBlbGVtLm9mZnNldEhlaWdodCA+IDAgfHwgZWxlbS5nZXRDbGllbnRSZWN0cygpLmxlbmd0aCA+IDA7XHJcbn07XHJcblxyXG5cclxuXHJcblxyXG52YXIgcjIwID0gLyUyMC9nLFxyXG5cdHJicmFja2V0ID0gL1xcW1xcXSQvLFxyXG5cdHJDUkxGID0gL1xccj9cXG4vZyxcclxuXHRyc3VibWl0dGVyVHlwZXMgPSAvXig/OnN1Ym1pdHxidXR0b258aW1hZ2V8cmVzZXR8ZmlsZSkkL2ksXHJcblx0cnN1Ym1pdHRhYmxlID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8a2V5Z2VuKS9pO1xyXG5cclxuZnVuY3Rpb24gYnVpbGRQYXJhbXMoIHByZWZpeCwgb2JqLCB0cmFkaXRpb25hbCwgYWRkICkge1xyXG5cdHZhciBuYW1lO1xyXG5cclxuXHRpZiAoIGpRdWVyeS5pc0FycmF5KCBvYmogKSApIHtcclxuXHJcblx0XHQvLyBTZXJpYWxpemUgYXJyYXkgaXRlbS5cclxuXHRcdGpRdWVyeS5lYWNoKCBvYmosIGZ1bmN0aW9uKCBpLCB2ICkge1xyXG5cdFx0XHRpZiAoIHRyYWRpdGlvbmFsIHx8IHJicmFja2V0LnRlc3QoIHByZWZpeCApICkge1xyXG5cclxuXHRcdFx0XHQvLyBUcmVhdCBlYWNoIGFycmF5IGl0ZW0gYXMgYSBzY2FsYXIuXHJcblx0XHRcdFx0YWRkKCBwcmVmaXgsIHYgKTtcclxuXHJcblx0XHRcdH0gZWxzZSB7XHJcblxyXG5cdFx0XHRcdC8vIEl0ZW0gaXMgbm9uLXNjYWxhciAoYXJyYXkgb3Igb2JqZWN0KSwgZW5jb2RlIGl0cyBudW1lcmljIGluZGV4LlxyXG5cdFx0XHRcdGJ1aWxkUGFyYW1zKFxyXG5cdFx0XHRcdFx0cHJlZml4ICsgXCJbXCIgKyAoIHR5cGVvZiB2ID09PSBcIm9iamVjdFwiICYmIHYgIT0gbnVsbCA/IGkgOiBcIlwiICkgKyBcIl1cIixcclxuXHRcdFx0XHRcdHYsXHJcblx0XHRcdFx0XHR0cmFkaXRpb25hbCxcclxuXHRcdFx0XHRcdGFkZFxyXG5cdFx0XHRcdCk7XHJcblx0XHRcdH1cclxuXHRcdH0gKTtcclxuXHJcblx0fSBlbHNlIGlmICggIXRyYWRpdGlvbmFsICYmIGpRdWVyeS50eXBlKCBvYmogKSA9PT0gXCJvYmplY3RcIiApIHtcclxuXHJcblx0XHQvLyBTZXJpYWxpemUgb2JqZWN0IGl0ZW0uXHJcblx0XHRmb3IgKCBuYW1lIGluIG9iaiApIHtcclxuXHRcdFx0YnVpbGRQYXJhbXMoIHByZWZpeCArIFwiW1wiICsgbmFtZSArIFwiXVwiLCBvYmpbIG5hbWUgXSwgdHJhZGl0aW9uYWwsIGFkZCApO1xyXG5cdFx0fVxyXG5cclxuXHR9IGVsc2Uge1xyXG5cclxuXHRcdC8vIFNlcmlhbGl6ZSBzY2FsYXIgaXRlbS5cclxuXHRcdGFkZCggcHJlZml4LCBvYmogKTtcclxuXHR9XHJcbn1cclxuXHJcbi8vIFNlcmlhbGl6ZSBhbiBhcnJheSBvZiBmb3JtIGVsZW1lbnRzIG9yIGEgc2V0IG9mXHJcbi8vIGtleS92YWx1ZXMgaW50byBhIHF1ZXJ5IHN0cmluZ1xyXG5qUXVlcnkucGFyYW0gPSBmdW5jdGlvbiggYSwgdHJhZGl0aW9uYWwgKSB7XHJcblx0dmFyIHByZWZpeCxcclxuXHRcdHMgPSBbXSxcclxuXHRcdGFkZCA9IGZ1bmN0aW9uKCBrZXksIHZhbHVlICkge1xyXG5cclxuXHRcdFx0Ly8gSWYgdmFsdWUgaXMgYSBmdW5jdGlvbiwgaW52b2tlIGl0IGFuZCByZXR1cm4gaXRzIHZhbHVlXHJcblx0XHRcdHZhbHVlID0galF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgPyB2YWx1ZSgpIDogKCB2YWx1ZSA9PSBudWxsID8gXCJcIiA6IHZhbHVlICk7XHJcblx0XHRcdHNbIHMubGVuZ3RoIF0gPSBlbmNvZGVVUklDb21wb25lbnQoIGtleSApICsgXCI9XCIgKyBlbmNvZGVVUklDb21wb25lbnQoIHZhbHVlICk7XHJcblx0XHR9O1xyXG5cclxuXHQvLyBTZXQgdHJhZGl0aW9uYWwgdG8gdHJ1ZSBmb3IgalF1ZXJ5IDw9IDEuMy4yIGJlaGF2aW9yLlxyXG5cdGlmICggdHJhZGl0aW9uYWwgPT09IHVuZGVmaW5lZCApIHtcclxuXHRcdHRyYWRpdGlvbmFsID0galF1ZXJ5LmFqYXhTZXR0aW5ncyAmJiBqUXVlcnkuYWpheFNldHRpbmdzLnRyYWRpdGlvbmFsO1xyXG5cdH1cclxuXHJcblx0Ly8gSWYgYW4gYXJyYXkgd2FzIHBhc3NlZCBpbiwgYXNzdW1lIHRoYXQgaXQgaXMgYW4gYXJyYXkgb2YgZm9ybSBlbGVtZW50cy5cclxuXHRpZiAoIGpRdWVyeS5pc0FycmF5KCBhICkgfHwgKCBhLmpxdWVyeSAmJiAhalF1ZXJ5LmlzUGxhaW5PYmplY3QoIGEgKSApICkge1xyXG5cclxuXHRcdC8vIFNlcmlhbGl6ZSB0aGUgZm9ybSBlbGVtZW50c1xyXG5cdFx0alF1ZXJ5LmVhY2goIGEsIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRhZGQoIHRoaXMubmFtZSwgdGhpcy52YWx1ZSApO1xyXG5cdFx0fSApO1xyXG5cclxuXHR9IGVsc2Uge1xyXG5cclxuXHRcdC8vIElmIHRyYWRpdGlvbmFsLCBlbmNvZGUgdGhlIFwib2xkXCIgd2F5ICh0aGUgd2F5IDEuMy4yIG9yIG9sZGVyXHJcblx0XHQvLyBkaWQgaXQpLCBvdGhlcndpc2UgZW5jb2RlIHBhcmFtcyByZWN1cnNpdmVseS5cclxuXHRcdGZvciAoIHByZWZpeCBpbiBhICkge1xyXG5cdFx0XHRidWlsZFBhcmFtcyggcHJlZml4LCBhWyBwcmVmaXggXSwgdHJhZGl0aW9uYWwsIGFkZCApO1xyXG5cdFx0fVxyXG5cdH1cclxuXHJcblx0Ly8gUmV0dXJuIHRoZSByZXN1bHRpbmcgc2VyaWFsaXphdGlvblxyXG5cdHJldHVybiBzLmpvaW4oIFwiJlwiICkucmVwbGFjZSggcjIwLCBcIitcIiApO1xyXG59O1xyXG5cclxualF1ZXJ5LmZuLmV4dGVuZCgge1xyXG5cdHNlcmlhbGl6ZTogZnVuY3Rpb24oKSB7XHJcblx0XHRyZXR1cm4galF1ZXJ5LnBhcmFtKCB0aGlzLnNlcmlhbGl6ZUFycmF5KCkgKTtcclxuXHR9LFxyXG5cdHNlcmlhbGl6ZUFycmF5OiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLm1hcCggZnVuY3Rpb24oKSB7XHJcblxyXG5cdFx0XHQvLyBDYW4gYWRkIHByb3BIb29rIGZvciBcImVsZW1lbnRzXCIgdG8gZmlsdGVyIG9yIGFkZCBmb3JtIGVsZW1lbnRzXHJcblx0XHRcdHZhciBlbGVtZW50cyA9IGpRdWVyeS5wcm9wKCB0aGlzLCBcImVsZW1lbnRzXCIgKTtcclxuXHRcdFx0cmV0dXJuIGVsZW1lbnRzID8galF1ZXJ5Lm1ha2VBcnJheSggZWxlbWVudHMgKSA6IHRoaXM7XHJcblx0XHR9IClcclxuXHRcdC5maWx0ZXIoIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR2YXIgdHlwZSA9IHRoaXMudHlwZTtcclxuXHJcblx0XHRcdC8vIFVzZSAuaXMoIFwiOmRpc2FibGVkXCIgKSBzbyB0aGF0IGZpZWxkc2V0W2Rpc2FibGVkXSB3b3Jrc1xyXG5cdFx0XHRyZXR1cm4gdGhpcy5uYW1lICYmICFqUXVlcnkoIHRoaXMgKS5pcyggXCI6ZGlzYWJsZWRcIiApICYmXHJcblx0XHRcdFx0cnN1Ym1pdHRhYmxlLnRlc3QoIHRoaXMubm9kZU5hbWUgKSAmJiAhcnN1Ym1pdHRlclR5cGVzLnRlc3QoIHR5cGUgKSAmJlxyXG5cdFx0XHRcdCggdGhpcy5jaGVja2VkIHx8ICFyY2hlY2thYmxlVHlwZS50ZXN0KCB0eXBlICkgKTtcclxuXHRcdH0gKVxyXG5cdFx0Lm1hcCggZnVuY3Rpb24oIGksIGVsZW0gKSB7XHJcblx0XHRcdHZhciB2YWwgPSBqUXVlcnkoIHRoaXMgKS52YWwoKTtcclxuXHJcblx0XHRcdHJldHVybiB2YWwgPT0gbnVsbCA/XHJcblx0XHRcdFx0bnVsbCA6XHJcblx0XHRcdFx0alF1ZXJ5LmlzQXJyYXkoIHZhbCApID9cclxuXHRcdFx0XHRcdGpRdWVyeS5tYXAoIHZhbCwgZnVuY3Rpb24oIHZhbCApIHtcclxuXHRcdFx0XHRcdFx0cmV0dXJuIHsgbmFtZTogZWxlbS5uYW1lLCB2YWx1ZTogdmFsLnJlcGxhY2UoIHJDUkxGLCBcIlxcclxcblwiICkgfTtcclxuXHRcdFx0XHRcdH0gKSA6XHJcblx0XHRcdFx0XHR7IG5hbWU6IGVsZW0ubmFtZSwgdmFsdWU6IHZhbC5yZXBsYWNlKCByQ1JMRiwgXCJcXHJcXG5cIiApIH07XHJcblx0XHR9ICkuZ2V0KCk7XHJcblx0fVxyXG59ICk7XHJcblxyXG5cclxualF1ZXJ5LmFqYXhTZXR0aW5ncy54aHIgPSBmdW5jdGlvbigpIHtcclxuXHR0cnkge1xyXG5cdFx0cmV0dXJuIG5ldyB3aW5kb3cuWE1MSHR0cFJlcXVlc3QoKTtcclxuXHR9IGNhdGNoICggZSApIHt9XHJcbn07XHJcblxyXG52YXIgeGhyU3VjY2Vzc1N0YXR1cyA9IHtcclxuXHJcblx0XHQvLyBGaWxlIHByb3RvY29sIGFsd2F5cyB5aWVsZHMgc3RhdHVzIGNvZGUgMCwgYXNzdW1lIDIwMFxyXG5cdFx0MDogMjAwLFxyXG5cclxuXHRcdC8vIFN1cHBvcnQ6IElFOVxyXG5cdFx0Ly8gIzE0NTA6IHNvbWV0aW1lcyBJRSByZXR1cm5zIDEyMjMgd2hlbiBpdCBzaG91bGQgYmUgMjA0XHJcblx0XHQxMjIzOiAyMDRcclxuXHR9LFxyXG5cdHhoclN1cHBvcnRlZCA9IGpRdWVyeS5hamF4U2V0dGluZ3MueGhyKCk7XHJcblxyXG5zdXBwb3J0LmNvcnMgPSAhIXhoclN1cHBvcnRlZCAmJiAoIFwid2l0aENyZWRlbnRpYWxzXCIgaW4geGhyU3VwcG9ydGVkICk7XHJcbnN1cHBvcnQuYWpheCA9IHhoclN1cHBvcnRlZCA9ICEheGhyU3VwcG9ydGVkO1xyXG5cclxualF1ZXJ5LmFqYXhUcmFuc3BvcnQoIGZ1bmN0aW9uKCBvcHRpb25zICkge1xyXG5cdHZhciBjYWxsYmFjaywgZXJyb3JDYWxsYmFjaztcclxuXHJcblx0Ly8gQ3Jvc3MgZG9tYWluIG9ubHkgYWxsb3dlZCBpZiBzdXBwb3J0ZWQgdGhyb3VnaCBYTUxIdHRwUmVxdWVzdFxyXG5cdGlmICggc3VwcG9ydC5jb3JzIHx8IHhoclN1cHBvcnRlZCAmJiAhb3B0aW9ucy5jcm9zc0RvbWFpbiApIHtcclxuXHRcdHJldHVybiB7XHJcblx0XHRcdHNlbmQ6IGZ1bmN0aW9uKCBoZWFkZXJzLCBjb21wbGV0ZSApIHtcclxuXHRcdFx0XHR2YXIgaSxcclxuXHRcdFx0XHRcdHhociA9IG9wdGlvbnMueGhyKCk7XHJcblxyXG5cdFx0XHRcdHhoci5vcGVuKFxyXG5cdFx0XHRcdFx0b3B0aW9ucy50eXBlLFxyXG5cdFx0XHRcdFx0b3B0aW9ucy51cmwsXHJcblx0XHRcdFx0XHRvcHRpb25zLmFzeW5jLFxyXG5cdFx0XHRcdFx0b3B0aW9ucy51c2VybmFtZSxcclxuXHRcdFx0XHRcdG9wdGlvbnMucGFzc3dvcmRcclxuXHRcdFx0XHQpO1xyXG5cclxuXHRcdFx0XHQvLyBBcHBseSBjdXN0b20gZmllbGRzIGlmIHByb3ZpZGVkXHJcblx0XHRcdFx0aWYgKCBvcHRpb25zLnhockZpZWxkcyApIHtcclxuXHRcdFx0XHRcdGZvciAoIGkgaW4gb3B0aW9ucy54aHJGaWVsZHMgKSB7XHJcblx0XHRcdFx0XHRcdHhoclsgaSBdID0gb3B0aW9ucy54aHJGaWVsZHNbIGkgXTtcclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIE92ZXJyaWRlIG1pbWUgdHlwZSBpZiBuZWVkZWRcclxuXHRcdFx0XHRpZiAoIG9wdGlvbnMubWltZVR5cGUgJiYgeGhyLm92ZXJyaWRlTWltZVR5cGUgKSB7XHJcblx0XHRcdFx0XHR4aHIub3ZlcnJpZGVNaW1lVHlwZSggb3B0aW9ucy5taW1lVHlwZSApO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gWC1SZXF1ZXN0ZWQtV2l0aCBoZWFkZXJcclxuXHRcdFx0XHQvLyBGb3IgY3Jvc3MtZG9tYWluIHJlcXVlc3RzLCBzZWVpbmcgYXMgY29uZGl0aW9ucyBmb3IgYSBwcmVmbGlnaHQgYXJlXHJcblx0XHRcdFx0Ly8gYWtpbiB0byBhIGppZ3NhdyBwdXp6bGUsIHdlIHNpbXBseSBuZXZlciBzZXQgaXQgdG8gYmUgc3VyZS5cclxuXHRcdFx0XHQvLyAoaXQgY2FuIGFsd2F5cyBiZSBzZXQgb24gYSBwZXItcmVxdWVzdCBiYXNpcyBvciBldmVuIHVzaW5nIGFqYXhTZXR1cClcclxuXHRcdFx0XHQvLyBGb3Igc2FtZS1kb21haW4gcmVxdWVzdHMsIHdvbid0IGNoYW5nZSBoZWFkZXIgaWYgYWxyZWFkeSBwcm92aWRlZC5cclxuXHRcdFx0XHRpZiAoICFvcHRpb25zLmNyb3NzRG9tYWluICYmICFoZWFkZXJzWyBcIlgtUmVxdWVzdGVkLVdpdGhcIiBdICkge1xyXG5cdFx0XHRcdFx0aGVhZGVyc1sgXCJYLVJlcXVlc3RlZC1XaXRoXCIgXSA9IFwiWE1MSHR0cFJlcXVlc3RcIjtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIFNldCBoZWFkZXJzXHJcblx0XHRcdFx0Zm9yICggaSBpbiBoZWFkZXJzICkge1xyXG5cdFx0XHRcdFx0eGhyLnNldFJlcXVlc3RIZWFkZXIoIGksIGhlYWRlcnNbIGkgXSApO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gQ2FsbGJhY2tcclxuXHRcdFx0XHRjYWxsYmFjayA9IGZ1bmN0aW9uKCB0eXBlICkge1xyXG5cdFx0XHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0XHRpZiAoIGNhbGxiYWNrICkge1xyXG5cdFx0XHRcdFx0XHRcdGNhbGxiYWNrID0gZXJyb3JDYWxsYmFjayA9IHhoci5vbmxvYWQgPVxyXG5cdFx0XHRcdFx0XHRcdFx0eGhyLm9uZXJyb3IgPSB4aHIub25hYm9ydCA9IHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBudWxsO1xyXG5cclxuXHRcdFx0XHRcdFx0XHRpZiAoIHR5cGUgPT09IFwiYWJvcnRcIiApIHtcclxuXHRcdFx0XHRcdFx0XHRcdHhoci5hYm9ydCgpO1xyXG5cdFx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIHR5cGUgPT09IFwiZXJyb3JcIiApIHtcclxuXHJcblx0XHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRTlcclxuXHRcdFx0XHRcdFx0XHRcdC8vIE9uIGEgbWFudWFsIG5hdGl2ZSBhYm9ydCwgSUU5IHRocm93c1xyXG5cdFx0XHRcdFx0XHRcdFx0Ly8gZXJyb3JzIG9uIGFueSBwcm9wZXJ0eSBhY2Nlc3MgdGhhdCBpcyBub3QgcmVhZHlTdGF0ZVxyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCB0eXBlb2YgeGhyLnN0YXR1cyAhPT0gXCJudW1iZXJcIiApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0Y29tcGxldGUoIDAsIFwiZXJyb3JcIiApO1xyXG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0Y29tcGxldGUoXHJcblxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdC8vIEZpbGU6IHByb3RvY29sIGFsd2F5cyB5aWVsZHMgc3RhdHVzIDA7IHNlZSAjODYwNSwgIzE0MjA3XHJcblx0XHRcdFx0XHRcdFx0XHRcdFx0eGhyLnN0YXR1cyxcclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR4aHIuc3RhdHVzVGV4dFxyXG5cdFx0XHRcdFx0XHRcdFx0XHQpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0XHRcdFx0XHRjb21wbGV0ZShcclxuXHRcdFx0XHRcdFx0XHRcdFx0eGhyU3VjY2Vzc1N0YXR1c1sgeGhyLnN0YXR1cyBdIHx8IHhoci5zdGF0dXMsXHJcblx0XHRcdFx0XHRcdFx0XHRcdHhoci5zdGF0dXNUZXh0LFxyXG5cclxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUU5IG9ubHlcclxuXHRcdFx0XHRcdFx0XHRcdFx0Ly8gSUU5IGhhcyBubyBYSFIyIGJ1dCB0aHJvd3Mgb24gYmluYXJ5ICh0cmFjLTExNDI2KVxyXG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBGb3IgWEhSMiBub24tdGV4dCwgbGV0IHRoZSBjYWxsZXIgaGFuZGxlIGl0IChnaC0yNDk4KVxyXG5cdFx0XHRcdFx0XHRcdFx0XHQoIHhoci5yZXNwb25zZVR5cGUgfHwgXCJ0ZXh0XCIgKSAhPT0gXCJ0ZXh0XCIgIHx8XHJcblx0XHRcdFx0XHRcdFx0XHRcdHR5cGVvZiB4aHIucmVzcG9uc2VUZXh0ICE9PSBcInN0cmluZ1wiID9cclxuXHRcdFx0XHRcdFx0XHRcdFx0XHR7IGJpbmFyeTogeGhyLnJlc3BvbnNlIH0gOlxyXG5cdFx0XHRcdFx0XHRcdFx0XHRcdHsgdGV4dDogeGhyLnJlc3BvbnNlVGV4dCB9LFxyXG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKClcclxuXHRcdFx0XHRcdFx0XHRcdCk7XHJcblx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9O1xyXG5cdFx0XHRcdH07XHJcblxyXG5cdFx0XHRcdC8vIExpc3RlbiB0byBldmVudHNcclxuXHRcdFx0XHR4aHIub25sb2FkID0gY2FsbGJhY2soKTtcclxuXHRcdFx0XHRlcnJvckNhbGxiYWNrID0geGhyLm9uZXJyb3IgPSBjYWxsYmFjayggXCJlcnJvclwiICk7XHJcblxyXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFOVxyXG5cdFx0XHRcdC8vIFVzZSBvbnJlYWR5c3RhdGVjaGFuZ2UgdG8gcmVwbGFjZSBvbmFib3J0XHJcblx0XHRcdFx0Ly8gdG8gaGFuZGxlIHVuY2F1Z2h0IGFib3J0c1xyXG5cdFx0XHRcdGlmICggeGhyLm9uYWJvcnQgIT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0XHRcdHhoci5vbmFib3J0ID0gZXJyb3JDYWxsYmFjaztcclxuXHRcdFx0XHR9IGVsc2Uge1xyXG5cdFx0XHRcdFx0eGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKCkge1xyXG5cclxuXHRcdFx0XHRcdFx0Ly8gQ2hlY2sgcmVhZHlTdGF0ZSBiZWZvcmUgdGltZW91dCBhcyBpdCBjaGFuZ2VzXHJcblx0XHRcdFx0XHRcdGlmICggeGhyLnJlYWR5U3RhdGUgPT09IDQgKSB7XHJcblxyXG5cdFx0XHRcdFx0XHRcdC8vIEFsbG93IG9uZXJyb3IgdG8gYmUgY2FsbGVkIGZpcnN0LFxyXG5cdFx0XHRcdFx0XHRcdC8vIGJ1dCB0aGF0IHdpbGwgbm90IGhhbmRsZSBhIG5hdGl2ZSBhYm9ydFxyXG5cdFx0XHRcdFx0XHRcdC8vIEFsc28sIHNhdmUgZXJyb3JDYWxsYmFjayB0byBhIHZhcmlhYmxlXHJcblx0XHRcdFx0XHRcdFx0Ly8gYXMgeGhyLm9uZXJyb3IgY2Fubm90IGJlIGFjY2Vzc2VkXHJcblx0XHRcdFx0XHRcdFx0d2luZG93LnNldFRpbWVvdXQoIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcclxuXHRcdFx0XHRcdFx0XHRcdFx0ZXJyb3JDYWxsYmFjaygpO1xyXG5cdFx0XHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0XHRcdH0gKTtcclxuXHRcdFx0XHRcdFx0fVxyXG5cdFx0XHRcdFx0fTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdC8vIENyZWF0ZSB0aGUgYWJvcnQgY2FsbGJhY2tcclxuXHRcdFx0XHRjYWxsYmFjayA9IGNhbGxiYWNrKCBcImFib3J0XCIgKTtcclxuXHJcblx0XHRcdFx0dHJ5IHtcclxuXHJcblx0XHRcdFx0XHQvLyBEbyBzZW5kIHRoZSByZXF1ZXN0ICh0aGlzIG1heSByYWlzZSBhbiBleGNlcHRpb24pXHJcblx0XHRcdFx0XHR4aHIuc2VuZCggb3B0aW9ucy5oYXNDb250ZW50ICYmIG9wdGlvbnMuZGF0YSB8fCBudWxsICk7XHJcblx0XHRcdFx0fSBjYXRjaCAoIGUgKSB7XHJcblxyXG5cdFx0XHRcdFx0Ly8gIzE0NjgzOiBPbmx5IHJldGhyb3cgaWYgdGhpcyBoYXNuJ3QgYmVlbiBub3RpZmllZCBhcyBhbiBlcnJvciB5ZXRcclxuXHRcdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XHJcblx0XHRcdFx0XHRcdHRocm93IGU7XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9LFxyXG5cclxuXHRcdFx0YWJvcnQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XHJcblx0XHRcdFx0XHRjYWxsYmFjaygpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fTtcclxuXHR9XHJcbn0gKTtcclxuXHJcblxyXG5cclxuXHJcbi8vIEluc3RhbGwgc2NyaXB0IGRhdGFUeXBlXHJcbmpRdWVyeS5hamF4U2V0dXAoIHtcclxuXHRhY2NlcHRzOiB7XHJcblx0XHRzY3JpcHQ6IFwidGV4dC9qYXZhc2NyaXB0LCBhcHBsaWNhdGlvbi9qYXZhc2NyaXB0LCBcIiArXHJcblx0XHRcdFwiYXBwbGljYXRpb24vZWNtYXNjcmlwdCwgYXBwbGljYXRpb24veC1lY21hc2NyaXB0XCJcclxuXHR9LFxyXG5cdGNvbnRlbnRzOiB7XHJcblx0XHRzY3JpcHQ6IC9cXGIoPzpqYXZhfGVjbWEpc2NyaXB0XFxiL1xyXG5cdH0sXHJcblx0Y29udmVydGVyczoge1xyXG5cdFx0XCJ0ZXh0IHNjcmlwdFwiOiBmdW5jdGlvbiggdGV4dCApIHtcclxuXHRcdFx0alF1ZXJ5Lmdsb2JhbEV2YWwoIHRleHQgKTtcclxuXHRcdFx0cmV0dXJuIHRleHQ7XHJcblx0XHR9XHJcblx0fVxyXG59ICk7XHJcblxyXG4vLyBIYW5kbGUgY2FjaGUncyBzcGVjaWFsIGNhc2UgYW5kIGNyb3NzRG9tYWluXHJcbmpRdWVyeS5hamF4UHJlZmlsdGVyKCBcInNjcmlwdFwiLCBmdW5jdGlvbiggcyApIHtcclxuXHRpZiAoIHMuY2FjaGUgPT09IHVuZGVmaW5lZCApIHtcclxuXHRcdHMuY2FjaGUgPSBmYWxzZTtcclxuXHR9XHJcblx0aWYgKCBzLmNyb3NzRG9tYWluICkge1xyXG5cdFx0cy50eXBlID0gXCJHRVRcIjtcclxuXHR9XHJcbn0gKTtcclxuXHJcbi8vIEJpbmQgc2NyaXB0IHRhZyBoYWNrIHRyYW5zcG9ydFxyXG5qUXVlcnkuYWpheFRyYW5zcG9ydCggXCJzY3JpcHRcIiwgZnVuY3Rpb24oIHMgKSB7XHJcblxyXG5cdC8vIFRoaXMgdHJhbnNwb3J0IG9ubHkgZGVhbHMgd2l0aCBjcm9zcyBkb21haW4gcmVxdWVzdHNcclxuXHRpZiAoIHMuY3Jvc3NEb21haW4gKSB7XHJcblx0XHR2YXIgc2NyaXB0LCBjYWxsYmFjaztcclxuXHRcdHJldHVybiB7XHJcblx0XHRcdHNlbmQ6IGZ1bmN0aW9uKCBfLCBjb21wbGV0ZSApIHtcclxuXHRcdFx0XHRzY3JpcHQgPSBqUXVlcnkoIFwiPHNjcmlwdD5cIiApLnByb3AoIHtcclxuXHRcdFx0XHRcdGNoYXJzZXQ6IHMuc2NyaXB0Q2hhcnNldCxcclxuXHRcdFx0XHRcdHNyYzogcy51cmxcclxuXHRcdFx0XHR9ICkub24oXHJcblx0XHRcdFx0XHRcImxvYWQgZXJyb3JcIixcclxuXHRcdFx0XHRcdGNhbGxiYWNrID0gZnVuY3Rpb24oIGV2dCApIHtcclxuXHRcdFx0XHRcdFx0c2NyaXB0LnJlbW92ZSgpO1xyXG5cdFx0XHRcdFx0XHRjYWxsYmFjayA9IG51bGw7XHJcblx0XHRcdFx0XHRcdGlmICggZXZ0ICkge1xyXG5cdFx0XHRcdFx0XHRcdGNvbXBsZXRlKCBldnQudHlwZSA9PT0gXCJlcnJvclwiID8gNDA0IDogMjAwLCBldnQudHlwZSApO1xyXG5cdFx0XHRcdFx0XHR9XHJcblx0XHRcdFx0XHR9XHJcblx0XHRcdFx0KTtcclxuXHJcblx0XHRcdFx0Ly8gVXNlIG5hdGl2ZSBET00gbWFuaXB1bGF0aW9uIHRvIGF2b2lkIG91ciBkb21NYW5pcCBBSkFYIHRyaWNrZXJ5XHJcblx0XHRcdFx0ZG9jdW1lbnQuaGVhZC5hcHBlbmRDaGlsZCggc2NyaXB0WyAwIF0gKTtcclxuXHRcdFx0fSxcclxuXHRcdFx0YWJvcnQ6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGlmICggY2FsbGJhY2sgKSB7XHJcblx0XHRcdFx0XHRjYWxsYmFjaygpO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0fVxyXG5cdFx0fTtcclxuXHR9XHJcbn0gKTtcclxuXHJcblxyXG5cclxuXHJcbnZhciBvbGRDYWxsYmFja3MgPSBbXSxcclxuXHRyanNvbnAgPSAvKD0pXFw/KD89JnwkKXxcXD9cXD8vO1xyXG5cclxuLy8gRGVmYXVsdCBqc29ucCBzZXR0aW5nc1xyXG5qUXVlcnkuYWpheFNldHVwKCB7XHJcblx0anNvbnA6IFwiY2FsbGJhY2tcIixcclxuXHRqc29ucENhbGxiYWNrOiBmdW5jdGlvbigpIHtcclxuXHRcdHZhciBjYWxsYmFjayA9IG9sZENhbGxiYWNrcy5wb3AoKSB8fCAoIGpRdWVyeS5leHBhbmRvICsgXCJfXCIgKyAoIG5vbmNlKysgKSApO1xyXG5cdFx0dGhpc1sgY2FsbGJhY2sgXSA9IHRydWU7XHJcblx0XHRyZXR1cm4gY2FsbGJhY2s7XHJcblx0fVxyXG59ICk7XHJcblxyXG4vLyBEZXRlY3QsIG5vcm1hbGl6ZSBvcHRpb25zIGFuZCBpbnN0YWxsIGNhbGxiYWNrcyBmb3IganNvbnAgcmVxdWVzdHNcclxualF1ZXJ5LmFqYXhQcmVmaWx0ZXIoIFwianNvbiBqc29ucFwiLCBmdW5jdGlvbiggcywgb3JpZ2luYWxTZXR0aW5ncywganFYSFIgKSB7XHJcblxyXG5cdHZhciBjYWxsYmFja05hbWUsIG92ZXJ3cml0dGVuLCByZXNwb25zZUNvbnRhaW5lcixcclxuXHRcdGpzb25Qcm9wID0gcy5qc29ucCAhPT0gZmFsc2UgJiYgKCByanNvbnAudGVzdCggcy51cmwgKSA/XHJcblx0XHRcdFwidXJsXCIgOlxyXG5cdFx0XHR0eXBlb2Ygcy5kYXRhID09PSBcInN0cmluZ1wiICYmXHJcblx0XHRcdFx0KCBzLmNvbnRlbnRUeXBlIHx8IFwiXCIgKVxyXG5cdFx0XHRcdFx0LmluZGV4T2YoIFwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkXCIgKSA9PT0gMCAmJlxyXG5cdFx0XHRcdHJqc29ucC50ZXN0KCBzLmRhdGEgKSAmJiBcImRhdGFcIlxyXG5cdFx0KTtcclxuXHJcblx0Ly8gSGFuZGxlIGlmZiB0aGUgZXhwZWN0ZWQgZGF0YSB0eXBlIGlzIFwianNvbnBcIiBvciB3ZSBoYXZlIGEgcGFyYW1ldGVyIHRvIHNldFxyXG5cdGlmICgganNvblByb3AgfHwgcy5kYXRhVHlwZXNbIDAgXSA9PT0gXCJqc29ucFwiICkge1xyXG5cclxuXHRcdC8vIEdldCBjYWxsYmFjayBuYW1lLCByZW1lbWJlcmluZyBwcmVleGlzdGluZyB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggaXRcclxuXHRcdGNhbGxiYWNrTmFtZSA9IHMuanNvbnBDYWxsYmFjayA9IGpRdWVyeS5pc0Z1bmN0aW9uKCBzLmpzb25wQ2FsbGJhY2sgKSA/XHJcblx0XHRcdHMuanNvbnBDYWxsYmFjaygpIDpcclxuXHRcdFx0cy5qc29ucENhbGxiYWNrO1xyXG5cclxuXHRcdC8vIEluc2VydCBjYWxsYmFjayBpbnRvIHVybCBvciBmb3JtIGRhdGFcclxuXHRcdGlmICgganNvblByb3AgKSB7XHJcblx0XHRcdHNbIGpzb25Qcm9wIF0gPSBzWyBqc29uUHJvcCBdLnJlcGxhY2UoIHJqc29ucCwgXCIkMVwiICsgY2FsbGJhY2tOYW1lICk7XHJcblx0XHR9IGVsc2UgaWYgKCBzLmpzb25wICE9PSBmYWxzZSApIHtcclxuXHRcdFx0cy51cmwgKz0gKCBycXVlcnkudGVzdCggcy51cmwgKSA/IFwiJlwiIDogXCI/XCIgKSArIHMuanNvbnAgKyBcIj1cIiArIGNhbGxiYWNrTmFtZTtcclxuXHRcdH1cclxuXHJcblx0XHQvLyBVc2UgZGF0YSBjb252ZXJ0ZXIgdG8gcmV0cmlldmUganNvbiBhZnRlciBzY3JpcHQgZXhlY3V0aW9uXHJcblx0XHRzLmNvbnZlcnRlcnNbIFwic2NyaXB0IGpzb25cIiBdID0gZnVuY3Rpb24oKSB7XHJcblx0XHRcdGlmICggIXJlc3BvbnNlQ29udGFpbmVyICkge1xyXG5cdFx0XHRcdGpRdWVyeS5lcnJvciggY2FsbGJhY2tOYW1lICsgXCIgd2FzIG5vdCBjYWxsZWRcIiApO1xyXG5cdFx0XHR9XHJcblx0XHRcdHJldHVybiByZXNwb25zZUNvbnRhaW5lclsgMCBdO1xyXG5cdFx0fTtcclxuXHJcblx0XHQvLyBGb3JjZSBqc29uIGRhdGFUeXBlXHJcblx0XHRzLmRhdGFUeXBlc1sgMCBdID0gXCJqc29uXCI7XHJcblxyXG5cdFx0Ly8gSW5zdGFsbCBjYWxsYmFja1xyXG5cdFx0b3ZlcndyaXR0ZW4gPSB3aW5kb3dbIGNhbGxiYWNrTmFtZSBdO1xyXG5cdFx0d2luZG93WyBjYWxsYmFja05hbWUgXSA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRyZXNwb25zZUNvbnRhaW5lciA9IGFyZ3VtZW50cztcclxuXHRcdH07XHJcblxyXG5cdFx0Ly8gQ2xlYW4tdXAgZnVuY3Rpb24gKGZpcmVzIGFmdGVyIGNvbnZlcnRlcnMpXHJcblx0XHRqcVhIUi5hbHdheXMoIGZ1bmN0aW9uKCkge1xyXG5cclxuXHRcdFx0Ly8gSWYgcHJldmlvdXMgdmFsdWUgZGlkbid0IGV4aXN0IC0gcmVtb3ZlIGl0XHJcblx0XHRcdGlmICggb3ZlcndyaXR0ZW4gPT09IHVuZGVmaW5lZCApIHtcclxuXHRcdFx0XHRqUXVlcnkoIHdpbmRvdyApLnJlbW92ZVByb3AoIGNhbGxiYWNrTmFtZSApO1xyXG5cclxuXHRcdFx0Ly8gT3RoZXJ3aXNlIHJlc3RvcmUgcHJlZXhpc3RpbmcgdmFsdWVcclxuXHRcdFx0fSBlbHNlIHtcclxuXHRcdFx0XHR3aW5kb3dbIGNhbGxiYWNrTmFtZSBdID0gb3ZlcndyaXR0ZW47XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdC8vIFNhdmUgYmFjayBhcyBmcmVlXHJcblx0XHRcdGlmICggc1sgY2FsbGJhY2tOYW1lIF0gKSB7XHJcblxyXG5cdFx0XHRcdC8vIE1ha2Ugc3VyZSB0aGF0IHJlLXVzaW5nIHRoZSBvcHRpb25zIGRvZXNuJ3Qgc2NyZXcgdGhpbmdzIGFyb3VuZFxyXG5cdFx0XHRcdHMuanNvbnBDYWxsYmFjayA9IG9yaWdpbmFsU2V0dGluZ3MuanNvbnBDYWxsYmFjaztcclxuXHJcblx0XHRcdFx0Ly8gU2F2ZSB0aGUgY2FsbGJhY2sgbmFtZSBmb3IgZnV0dXJlIHVzZVxyXG5cdFx0XHRcdG9sZENhbGxiYWNrcy5wdXNoKCBjYWxsYmFja05hbWUgKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0Ly8gQ2FsbCBpZiBpdCB3YXMgYSBmdW5jdGlvbiBhbmQgd2UgaGF2ZSBhIHJlc3BvbnNlXHJcblx0XHRcdGlmICggcmVzcG9uc2VDb250YWluZXIgJiYgalF1ZXJ5LmlzRnVuY3Rpb24oIG92ZXJ3cml0dGVuICkgKSB7XHJcblx0XHRcdFx0b3ZlcndyaXR0ZW4oIHJlc3BvbnNlQ29udGFpbmVyWyAwIF0gKTtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmVzcG9uc2VDb250YWluZXIgPSBvdmVyd3JpdHRlbiA9IHVuZGVmaW5lZDtcclxuXHRcdH0gKTtcclxuXHJcblx0XHQvLyBEZWxlZ2F0ZSB0byBzY3JpcHRcclxuXHRcdHJldHVybiBcInNjcmlwdFwiO1xyXG5cdH1cclxufSApO1xyXG5cclxuXHJcblxyXG5cclxuLy8gQXJndW1lbnQgXCJkYXRhXCIgc2hvdWxkIGJlIHN0cmluZyBvZiBodG1sXHJcbi8vIGNvbnRleHQgKG9wdGlvbmFsKTogSWYgc3BlY2lmaWVkLCB0aGUgZnJhZ21lbnQgd2lsbCBiZSBjcmVhdGVkIGluIHRoaXMgY29udGV4dCxcclxuLy8gZGVmYXVsdHMgdG8gZG9jdW1lbnRcclxuLy8ga2VlcFNjcmlwdHMgKG9wdGlvbmFsKTogSWYgdHJ1ZSwgd2lsbCBpbmNsdWRlIHNjcmlwdHMgcGFzc2VkIGluIHRoZSBodG1sIHN0cmluZ1xyXG5qUXVlcnkucGFyc2VIVE1MID0gZnVuY3Rpb24oIGRhdGEsIGNvbnRleHQsIGtlZXBTY3JpcHRzICkge1xyXG5cdGlmICggIWRhdGEgfHwgdHlwZW9mIGRhdGEgIT09IFwic3RyaW5nXCIgKSB7XHJcblx0XHRyZXR1cm4gbnVsbDtcclxuXHR9XHJcblx0aWYgKCB0eXBlb2YgY29udGV4dCA9PT0gXCJib29sZWFuXCIgKSB7XHJcblx0XHRrZWVwU2NyaXB0cyA9IGNvbnRleHQ7XHJcblx0XHRjb250ZXh0ID0gZmFsc2U7XHJcblx0fVxyXG5cdGNvbnRleHQgPSBjb250ZXh0IHx8IGRvY3VtZW50O1xyXG5cclxuXHR2YXIgcGFyc2VkID0gcnNpbmdsZVRhZy5leGVjKCBkYXRhICksXHJcblx0XHRzY3JpcHRzID0gIWtlZXBTY3JpcHRzICYmIFtdO1xyXG5cclxuXHQvLyBTaW5nbGUgdGFnXHJcblx0aWYgKCBwYXJzZWQgKSB7XHJcblx0XHRyZXR1cm4gWyBjb250ZXh0LmNyZWF0ZUVsZW1lbnQoIHBhcnNlZFsgMSBdICkgXTtcclxuXHR9XHJcblxyXG5cdHBhcnNlZCA9IGJ1aWxkRnJhZ21lbnQoIFsgZGF0YSBdLCBjb250ZXh0LCBzY3JpcHRzICk7XHJcblxyXG5cdGlmICggc2NyaXB0cyAmJiBzY3JpcHRzLmxlbmd0aCApIHtcclxuXHRcdGpRdWVyeSggc2NyaXB0cyApLnJlbW92ZSgpO1xyXG5cdH1cclxuXHJcblx0cmV0dXJuIGpRdWVyeS5tZXJnZSggW10sIHBhcnNlZC5jaGlsZE5vZGVzICk7XHJcbn07XHJcblxyXG5cclxuLy8gS2VlcCBhIGNvcHkgb2YgdGhlIG9sZCBsb2FkIG1ldGhvZFxyXG52YXIgX2xvYWQgPSBqUXVlcnkuZm4ubG9hZDtcclxuXHJcbi8qKlxyXG4gKiBMb2FkIGEgdXJsIGludG8gYSBwYWdlXHJcbiAqL1xyXG5qUXVlcnkuZm4ubG9hZCA9IGZ1bmN0aW9uKCB1cmwsIHBhcmFtcywgY2FsbGJhY2sgKSB7XHJcblx0aWYgKCB0eXBlb2YgdXJsICE9PSBcInN0cmluZ1wiICYmIF9sb2FkICkge1xyXG5cdFx0cmV0dXJuIF9sb2FkLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcclxuXHR9XHJcblxyXG5cdHZhciBzZWxlY3RvciwgdHlwZSwgcmVzcG9uc2UsXHJcblx0XHRzZWxmID0gdGhpcyxcclxuXHRcdG9mZiA9IHVybC5pbmRleE9mKCBcIiBcIiApO1xyXG5cclxuXHRpZiAoIG9mZiA+IC0xICkge1xyXG5cdFx0c2VsZWN0b3IgPSBqUXVlcnkudHJpbSggdXJsLnNsaWNlKCBvZmYgKSApO1xyXG5cdFx0dXJsID0gdXJsLnNsaWNlKCAwLCBvZmYgKTtcclxuXHR9XHJcblxyXG5cdC8vIElmIGl0J3MgYSBmdW5jdGlvblxyXG5cdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHBhcmFtcyApICkge1xyXG5cclxuXHRcdC8vIFdlIGFzc3VtZSB0aGF0IGl0J3MgdGhlIGNhbGxiYWNrXHJcblx0XHRjYWxsYmFjayA9IHBhcmFtcztcclxuXHRcdHBhcmFtcyA9IHVuZGVmaW5lZDtcclxuXHJcblx0Ly8gT3RoZXJ3aXNlLCBidWlsZCBhIHBhcmFtIHN0cmluZ1xyXG5cdH0gZWxzZSBpZiAoIHBhcmFtcyAmJiB0eXBlb2YgcGFyYW1zID09PSBcIm9iamVjdFwiICkge1xyXG5cdFx0dHlwZSA9IFwiUE9TVFwiO1xyXG5cdH1cclxuXHJcblx0Ly8gSWYgd2UgaGF2ZSBlbGVtZW50cyB0byBtb2RpZnksIG1ha2UgdGhlIHJlcXVlc3RcclxuXHRpZiAoIHNlbGYubGVuZ3RoID4gMCApIHtcclxuXHRcdGpRdWVyeS5hamF4KCB7XHJcblx0XHRcdHVybDogdXJsLFxyXG5cclxuXHRcdFx0Ly8gSWYgXCJ0eXBlXCIgdmFyaWFibGUgaXMgdW5kZWZpbmVkLCB0aGVuIFwiR0VUXCIgbWV0aG9kIHdpbGwgYmUgdXNlZC5cclxuXHRcdFx0Ly8gTWFrZSB2YWx1ZSBvZiB0aGlzIGZpZWxkIGV4cGxpY2l0IHNpbmNlXHJcblx0XHRcdC8vIHVzZXIgY2FuIG92ZXJyaWRlIGl0IHRocm91Z2ggYWpheFNldHVwIG1ldGhvZFxyXG5cdFx0XHR0eXBlOiB0eXBlIHx8IFwiR0VUXCIsXHJcblx0XHRcdGRhdGFUeXBlOiBcImh0bWxcIixcclxuXHRcdFx0ZGF0YTogcGFyYW1zXHJcblx0XHR9ICkuZG9uZSggZnVuY3Rpb24oIHJlc3BvbnNlVGV4dCApIHtcclxuXHJcblx0XHRcdC8vIFNhdmUgcmVzcG9uc2UgZm9yIHVzZSBpbiBjb21wbGV0ZSBjYWxsYmFja1xyXG5cdFx0XHRyZXNwb25zZSA9IGFyZ3VtZW50cztcclxuXHJcblx0XHRcdHNlbGYuaHRtbCggc2VsZWN0b3IgP1xyXG5cclxuXHRcdFx0XHQvLyBJZiBhIHNlbGVjdG9yIHdhcyBzcGVjaWZpZWQsIGxvY2F0ZSB0aGUgcmlnaHQgZWxlbWVudHMgaW4gYSBkdW1teSBkaXZcclxuXHRcdFx0XHQvLyBFeGNsdWRlIHNjcmlwdHMgdG8gYXZvaWQgSUUgJ1Blcm1pc3Npb24gRGVuaWVkJyBlcnJvcnNcclxuXHRcdFx0XHRqUXVlcnkoIFwiPGRpdj5cIiApLmFwcGVuZCggalF1ZXJ5LnBhcnNlSFRNTCggcmVzcG9uc2VUZXh0ICkgKS5maW5kKCBzZWxlY3RvciApIDpcclxuXHJcblx0XHRcdFx0Ly8gT3RoZXJ3aXNlIHVzZSB0aGUgZnVsbCByZXN1bHRcclxuXHRcdFx0XHRyZXNwb25zZVRleHQgKTtcclxuXHJcblx0XHQvLyBJZiB0aGUgcmVxdWVzdCBzdWNjZWVkcywgdGhpcyBmdW5jdGlvbiBnZXRzIFwiZGF0YVwiLCBcInN0YXR1c1wiLCBcImpxWEhSXCJcclxuXHRcdC8vIGJ1dCB0aGV5IGFyZSBpZ25vcmVkIGJlY2F1c2UgcmVzcG9uc2Ugd2FzIHNldCBhYm92ZS5cclxuXHRcdC8vIElmIGl0IGZhaWxzLCB0aGlzIGZ1bmN0aW9uIGdldHMgXCJqcVhIUlwiLCBcInN0YXR1c1wiLCBcImVycm9yXCJcclxuXHRcdH0gKS5hbHdheXMoIGNhbGxiYWNrICYmIGZ1bmN0aW9uKCBqcVhIUiwgc3RhdHVzICkge1xyXG5cdFx0XHRzZWxmLmVhY2goIGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdGNhbGxiYWNrLmFwcGx5KCB0aGlzLCByZXNwb25zZSB8fCBbIGpxWEhSLnJlc3BvbnNlVGV4dCwgc3RhdHVzLCBqcVhIUiBdICk7XHJcblx0XHRcdH0gKTtcclxuXHRcdH0gKTtcclxuXHR9XHJcblxyXG5cdHJldHVybiB0aGlzO1xyXG59O1xyXG5cclxuXHJcblxyXG5cclxuLy8gQXR0YWNoIGEgYnVuY2ggb2YgZnVuY3Rpb25zIGZvciBoYW5kbGluZyBjb21tb24gQUpBWCBldmVudHNcclxualF1ZXJ5LmVhY2goIFtcclxuXHRcImFqYXhTdGFydFwiLFxyXG5cdFwiYWpheFN0b3BcIixcclxuXHRcImFqYXhDb21wbGV0ZVwiLFxyXG5cdFwiYWpheEVycm9yXCIsXHJcblx0XCJhamF4U3VjY2Vzc1wiLFxyXG5cdFwiYWpheFNlbmRcIlxyXG5dLCBmdW5jdGlvbiggaSwgdHlwZSApIHtcclxuXHRqUXVlcnkuZm5bIHR5cGUgXSA9IGZ1bmN0aW9uKCBmbiApIHtcclxuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlLCBmbiApO1xyXG5cdH07XHJcbn0gKTtcclxuXHJcblxyXG5cclxuXHJcbmpRdWVyeS5leHByLmZpbHRlcnMuYW5pbWF0ZWQgPSBmdW5jdGlvbiggZWxlbSApIHtcclxuXHRyZXR1cm4galF1ZXJ5LmdyZXAoIGpRdWVyeS50aW1lcnMsIGZ1bmN0aW9uKCBmbiApIHtcclxuXHRcdHJldHVybiBlbGVtID09PSBmbi5lbGVtO1xyXG5cdH0gKS5sZW5ndGg7XHJcbn07XHJcblxyXG5cclxuXHJcblxyXG4vKipcclxuICogR2V0cyBhIHdpbmRvdyBmcm9tIGFuIGVsZW1lbnRcclxuICovXHJcbmZ1bmN0aW9uIGdldFdpbmRvdyggZWxlbSApIHtcclxuXHRyZXR1cm4galF1ZXJ5LmlzV2luZG93KCBlbGVtICkgPyBlbGVtIDogZWxlbS5ub2RlVHlwZSA9PT0gOSAmJiBlbGVtLmRlZmF1bHRWaWV3O1xyXG59XHJcblxyXG5qUXVlcnkub2Zmc2V0ID0ge1xyXG5cdHNldE9mZnNldDogZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIGkgKSB7XHJcblx0XHR2YXIgY3VyUG9zaXRpb24sIGN1ckxlZnQsIGN1ckNTU1RvcCwgY3VyVG9wLCBjdXJPZmZzZXQsIGN1ckNTU0xlZnQsIGNhbGN1bGF0ZVBvc2l0aW9uLFxyXG5cdFx0XHRwb3NpdGlvbiA9IGpRdWVyeS5jc3MoIGVsZW0sIFwicG9zaXRpb25cIiApLFxyXG5cdFx0XHRjdXJFbGVtID0galF1ZXJ5KCBlbGVtICksXHJcblx0XHRcdHByb3BzID0ge307XHJcblxyXG5cdFx0Ly8gU2V0IHBvc2l0aW9uIGZpcnN0LCBpbi1jYXNlIHRvcC9sZWZ0IGFyZSBzZXQgZXZlbiBvbiBzdGF0aWMgZWxlbVxyXG5cdFx0aWYgKCBwb3NpdGlvbiA9PT0gXCJzdGF0aWNcIiApIHtcclxuXHRcdFx0ZWxlbS5zdHlsZS5wb3NpdGlvbiA9IFwicmVsYXRpdmVcIjtcclxuXHRcdH1cclxuXHJcblx0XHRjdXJPZmZzZXQgPSBjdXJFbGVtLm9mZnNldCgpO1xyXG5cdFx0Y3VyQ1NTVG9wID0galF1ZXJ5LmNzcyggZWxlbSwgXCJ0b3BcIiApO1xyXG5cdFx0Y3VyQ1NTTGVmdCA9IGpRdWVyeS5jc3MoIGVsZW0sIFwibGVmdFwiICk7XHJcblx0XHRjYWxjdWxhdGVQb3NpdGlvbiA9ICggcG9zaXRpb24gPT09IFwiYWJzb2x1dGVcIiB8fCBwb3NpdGlvbiA9PT0gXCJmaXhlZFwiICkgJiZcclxuXHRcdFx0KCBjdXJDU1NUb3AgKyBjdXJDU1NMZWZ0ICkuaW5kZXhPZiggXCJhdXRvXCIgKSA+IC0xO1xyXG5cclxuXHRcdC8vIE5lZWQgdG8gYmUgYWJsZSB0byBjYWxjdWxhdGUgcG9zaXRpb24gaWYgZWl0aGVyXHJcblx0XHQvLyB0b3Agb3IgbGVmdCBpcyBhdXRvIGFuZCBwb3NpdGlvbiBpcyBlaXRoZXIgYWJzb2x1dGUgb3IgZml4ZWRcclxuXHRcdGlmICggY2FsY3VsYXRlUG9zaXRpb24gKSB7XHJcblx0XHRcdGN1clBvc2l0aW9uID0gY3VyRWxlbS5wb3NpdGlvbigpO1xyXG5cdFx0XHRjdXJUb3AgPSBjdXJQb3NpdGlvbi50b3A7XHJcblx0XHRcdGN1ckxlZnQgPSBjdXJQb3NpdGlvbi5sZWZ0O1xyXG5cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGN1clRvcCA9IHBhcnNlRmxvYXQoIGN1ckNTU1RvcCApIHx8IDA7XHJcblx0XHRcdGN1ckxlZnQgPSBwYXJzZUZsb2F0KCBjdXJDU1NMZWZ0ICkgfHwgMDtcclxuXHRcdH1cclxuXHJcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBvcHRpb25zICkgKSB7XHJcblxyXG5cdFx0XHQvLyBVc2UgalF1ZXJ5LmV4dGVuZCBoZXJlIHRvIGFsbG93IG1vZGlmaWNhdGlvbiBvZiBjb29yZGluYXRlcyBhcmd1bWVudCAoZ2gtMTg0OClcclxuXHRcdFx0b3B0aW9ucyA9IG9wdGlvbnMuY2FsbCggZWxlbSwgaSwgalF1ZXJ5LmV4dGVuZCgge30sIGN1ck9mZnNldCApICk7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBvcHRpb25zLnRvcCAhPSBudWxsICkge1xyXG5cdFx0XHRwcm9wcy50b3AgPSAoIG9wdGlvbnMudG9wIC0gY3VyT2Zmc2V0LnRvcCApICsgY3VyVG9wO1xyXG5cdFx0fVxyXG5cdFx0aWYgKCBvcHRpb25zLmxlZnQgIT0gbnVsbCApIHtcclxuXHRcdFx0cHJvcHMubGVmdCA9ICggb3B0aW9ucy5sZWZ0IC0gY3VyT2Zmc2V0LmxlZnQgKSArIGN1ckxlZnQ7XHJcblx0XHR9XHJcblxyXG5cdFx0aWYgKCBcInVzaW5nXCIgaW4gb3B0aW9ucyApIHtcclxuXHRcdFx0b3B0aW9ucy51c2luZy5jYWxsKCBlbGVtLCBwcm9wcyApO1xyXG5cclxuXHRcdH0gZWxzZSB7XHJcblx0XHRcdGN1ckVsZW0uY3NzKCBwcm9wcyApO1xyXG5cdFx0fVxyXG5cdH1cclxufTtcclxuXHJcbmpRdWVyeS5mbi5leHRlbmQoIHtcclxuXHRvZmZzZXQ6IGZ1bmN0aW9uKCBvcHRpb25zICkge1xyXG5cdFx0aWYgKCBhcmd1bWVudHMubGVuZ3RoICkge1xyXG5cdFx0XHRyZXR1cm4gb3B0aW9ucyA9PT0gdW5kZWZpbmVkID9cclxuXHRcdFx0XHR0aGlzIDpcclxuXHRcdFx0XHR0aGlzLmVhY2goIGZ1bmN0aW9uKCBpICkge1xyXG5cdFx0XHRcdFx0alF1ZXJ5Lm9mZnNldC5zZXRPZmZzZXQoIHRoaXMsIG9wdGlvbnMsIGkgKTtcclxuXHRcdFx0XHR9ICk7XHJcblx0XHR9XHJcblxyXG5cdFx0dmFyIGRvY0VsZW0sIHdpbixcclxuXHRcdFx0ZWxlbSA9IHRoaXNbIDAgXSxcclxuXHRcdFx0Ym94ID0geyB0b3A6IDAsIGxlZnQ6IDAgfSxcclxuXHRcdFx0ZG9jID0gZWxlbSAmJiBlbGVtLm93bmVyRG9jdW1lbnQ7XHJcblxyXG5cdFx0aWYgKCAhZG9jICkge1xyXG5cdFx0XHRyZXR1cm47XHJcblx0XHR9XHJcblxyXG5cdFx0ZG9jRWxlbSA9IGRvYy5kb2N1bWVudEVsZW1lbnQ7XHJcblxyXG5cdFx0Ly8gTWFrZSBzdXJlIGl0J3Mgbm90IGEgZGlzY29ubmVjdGVkIERPTSBub2RlXHJcblx0XHRpZiAoICFqUXVlcnkuY29udGFpbnMoIGRvY0VsZW0sIGVsZW0gKSApIHtcclxuXHRcdFx0cmV0dXJuIGJveDtcclxuXHRcdH1cclxuXHJcblx0XHRib3ggPSBlbGVtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG5cdFx0d2luID0gZ2V0V2luZG93KCBkb2MgKTtcclxuXHRcdHJldHVybiB7XHJcblx0XHRcdHRvcDogYm94LnRvcCArIHdpbi5wYWdlWU9mZnNldCAtIGRvY0VsZW0uY2xpZW50VG9wLFxyXG5cdFx0XHRsZWZ0OiBib3gubGVmdCArIHdpbi5wYWdlWE9mZnNldCAtIGRvY0VsZW0uY2xpZW50TGVmdFxyXG5cdFx0fTtcclxuXHR9LFxyXG5cclxuXHRwb3NpdGlvbjogZnVuY3Rpb24oKSB7XHJcblx0XHRpZiAoICF0aGlzWyAwIF0gKSB7XHJcblx0XHRcdHJldHVybjtcclxuXHRcdH1cclxuXHJcblx0XHR2YXIgb2Zmc2V0UGFyZW50LCBvZmZzZXQsXHJcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF0sXHJcblx0XHRcdHBhcmVudE9mZnNldCA9IHsgdG9wOiAwLCBsZWZ0OiAwIH07XHJcblxyXG5cdFx0Ly8gRml4ZWQgZWxlbWVudHMgYXJlIG9mZnNldCBmcm9tIHdpbmRvdyAocGFyZW50T2Zmc2V0ID0ge3RvcDowLCBsZWZ0OiAwfSxcclxuXHRcdC8vIGJlY2F1c2UgaXQgaXMgaXRzIG9ubHkgb2Zmc2V0IHBhcmVudFxyXG5cdFx0aWYgKCBqUXVlcnkuY3NzKCBlbGVtLCBcInBvc2l0aW9uXCIgKSA9PT0gXCJmaXhlZFwiICkge1xyXG5cclxuXHRcdFx0Ly8gQXNzdW1lIGdldEJvdW5kaW5nQ2xpZW50UmVjdCBpcyB0aGVyZSB3aGVuIGNvbXB1dGVkIHBvc2l0aW9uIGlzIGZpeGVkXHJcblx0XHRcdG9mZnNldCA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcblxyXG5cdFx0fSBlbHNlIHtcclxuXHJcblx0XHRcdC8vIEdldCAqcmVhbCogb2Zmc2V0UGFyZW50XHJcblx0XHRcdG9mZnNldFBhcmVudCA9IHRoaXMub2Zmc2V0UGFyZW50KCk7XHJcblxyXG5cdFx0XHQvLyBHZXQgY29ycmVjdCBvZmZzZXRzXHJcblx0XHRcdG9mZnNldCA9IHRoaXMub2Zmc2V0KCk7XHJcblx0XHRcdGlmICggIWpRdWVyeS5ub2RlTmFtZSggb2Zmc2V0UGFyZW50WyAwIF0sIFwiaHRtbFwiICkgKSB7XHJcblx0XHRcdFx0cGFyZW50T2Zmc2V0ID0gb2Zmc2V0UGFyZW50Lm9mZnNldCgpO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHQvLyBBZGQgb2Zmc2V0UGFyZW50IGJvcmRlcnNcclxuXHRcdFx0cGFyZW50T2Zmc2V0LnRvcCArPSBqUXVlcnkuY3NzKCBvZmZzZXRQYXJlbnRbIDAgXSwgXCJib3JkZXJUb3BXaWR0aFwiLCB0cnVlICk7XHJcblx0XHRcdHBhcmVudE9mZnNldC5sZWZ0ICs9IGpRdWVyeS5jc3MoIG9mZnNldFBhcmVudFsgMCBdLCBcImJvcmRlckxlZnRXaWR0aFwiLCB0cnVlICk7XHJcblx0XHR9XHJcblxyXG5cdFx0Ly8gU3VidHJhY3QgcGFyZW50IG9mZnNldHMgYW5kIGVsZW1lbnQgbWFyZ2luc1xyXG5cdFx0cmV0dXJuIHtcclxuXHRcdFx0dG9wOiBvZmZzZXQudG9wIC0gcGFyZW50T2Zmc2V0LnRvcCAtIGpRdWVyeS5jc3MoIGVsZW0sIFwibWFyZ2luVG9wXCIsIHRydWUgKSxcclxuXHRcdFx0bGVmdDogb2Zmc2V0LmxlZnQgLSBwYXJlbnRPZmZzZXQubGVmdCAtIGpRdWVyeS5jc3MoIGVsZW0sIFwibWFyZ2luTGVmdFwiLCB0cnVlIClcclxuXHRcdH07XHJcblx0fSxcclxuXHJcblx0Ly8gVGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gZG9jdW1lbnRFbGVtZW50IGluIHRoZSBmb2xsb3dpbmcgY2FzZXM6XHJcblx0Ly8gMSkgRm9yIHRoZSBlbGVtZW50IGluc2lkZSB0aGUgaWZyYW1lIHdpdGhvdXQgb2Zmc2V0UGFyZW50LCB0aGlzIG1ldGhvZCB3aWxsIHJldHVyblxyXG5cdC8vICAgIGRvY3VtZW50RWxlbWVudCBvZiB0aGUgcGFyZW50IHdpbmRvd1xyXG5cdC8vIDIpIEZvciB0aGUgaGlkZGVuIG9yIGRldGFjaGVkIGVsZW1lbnRcclxuXHQvLyAzKSBGb3IgYm9keSBvciBodG1sIGVsZW1lbnQsIGkuZS4gaW4gY2FzZSBvZiB0aGUgaHRtbCBub2RlIC0gaXQgd2lsbCByZXR1cm4gaXRzZWxmXHJcblx0Ly9cclxuXHQvLyBidXQgdGhvc2UgZXhjZXB0aW9ucyB3ZXJlIG5ldmVyIHByZXNlbnRlZCBhcyBhIHJlYWwgbGlmZSB1c2UtY2FzZXNcclxuXHQvLyBhbmQgbWlnaHQgYmUgY29uc2lkZXJlZCBhcyBtb3JlIHByZWZlcmFibGUgcmVzdWx0cy5cclxuXHQvL1xyXG5cdC8vIFRoaXMgbG9naWMsIGhvd2V2ZXIsIGlzIG5vdCBndWFyYW50ZWVkIGFuZCBjYW4gY2hhbmdlIGF0IGFueSBwb2ludCBpbiB0aGUgZnV0dXJlXHJcblx0b2Zmc2V0UGFyZW50OiBmdW5jdGlvbigpIHtcclxuXHRcdHJldHVybiB0aGlzLm1hcCggZnVuY3Rpb24oKSB7XHJcblx0XHRcdHZhciBvZmZzZXRQYXJlbnQgPSB0aGlzLm9mZnNldFBhcmVudDtcclxuXHJcblx0XHRcdHdoaWxlICggb2Zmc2V0UGFyZW50ICYmIGpRdWVyeS5jc3MoIG9mZnNldFBhcmVudCwgXCJwb3NpdGlvblwiICkgPT09IFwic3RhdGljXCIgKSB7XHJcblx0XHRcdFx0b2Zmc2V0UGFyZW50ID0gb2Zmc2V0UGFyZW50Lm9mZnNldFBhcmVudDtcclxuXHRcdFx0fVxyXG5cclxuXHRcdFx0cmV0dXJuIG9mZnNldFBhcmVudCB8fCBkb2N1bWVudEVsZW1lbnQ7XHJcblx0XHR9ICk7XHJcblx0fVxyXG59ICk7XHJcblxyXG4vLyBDcmVhdGUgc2Nyb2xsTGVmdCBhbmQgc2Nyb2xsVG9wIG1ldGhvZHNcclxualF1ZXJ5LmVhY2goIHsgc2Nyb2xsTGVmdDogXCJwYWdlWE9mZnNldFwiLCBzY3JvbGxUb3A6IFwicGFnZVlPZmZzZXRcIiB9LCBmdW5jdGlvbiggbWV0aG9kLCBwcm9wICkge1xyXG5cdHZhciB0b3AgPSBcInBhZ2VZT2Zmc2V0XCIgPT09IHByb3A7XHJcblxyXG5cdGpRdWVyeS5mblsgbWV0aG9kIF0gPSBmdW5jdGlvbiggdmFsICkge1xyXG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgZnVuY3Rpb24oIGVsZW0sIG1ldGhvZCwgdmFsICkge1xyXG5cdFx0XHR2YXIgd2luID0gZ2V0V2luZG93KCBlbGVtICk7XHJcblxyXG5cdFx0XHRpZiAoIHZhbCA9PT0gdW5kZWZpbmVkICkge1xyXG5cdFx0XHRcdHJldHVybiB3aW4gPyB3aW5bIHByb3AgXSA6IGVsZW1bIG1ldGhvZCBdO1xyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAoIHdpbiApIHtcclxuXHRcdFx0XHR3aW4uc2Nyb2xsVG8oXHJcblx0XHRcdFx0XHQhdG9wID8gdmFsIDogd2luLnBhZ2VYT2Zmc2V0LFxyXG5cdFx0XHRcdFx0dG9wID8gdmFsIDogd2luLnBhZ2VZT2Zmc2V0XHJcblx0XHRcdFx0KTtcclxuXHJcblx0XHRcdH0gZWxzZSB7XHJcblx0XHRcdFx0ZWxlbVsgbWV0aG9kIF0gPSB2YWw7XHJcblx0XHRcdH1cclxuXHRcdH0sIG1ldGhvZCwgdmFsLCBhcmd1bWVudHMubGVuZ3RoICk7XHJcblx0fTtcclxufSApO1xyXG5cclxuLy8gU3VwcG9ydDogU2FmYXJpPDctOCssIENocm9tZTwzNy00NCtcclxuLy8gQWRkIHRoZSB0b3AvbGVmdCBjc3NIb29rcyB1c2luZyBqUXVlcnkuZm4ucG9zaXRpb25cclxuLy8gV2Via2l0IGJ1ZzogaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTI5MDg0XHJcbi8vIEJsaW5rIGJ1ZzogaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jaHJvbWl1bS9pc3N1ZXMvZGV0YWlsP2lkPTIyOTI4MFxyXG4vLyBnZXRDb21wdXRlZFN0eWxlIHJldHVybnMgcGVyY2VudCB3aGVuIHNwZWNpZmllZCBmb3IgdG9wL2xlZnQvYm90dG9tL3JpZ2h0O1xyXG4vLyByYXRoZXIgdGhhbiBtYWtlIHRoZSBjc3MgbW9kdWxlIGRlcGVuZCBvbiB0aGUgb2Zmc2V0IG1vZHVsZSwganVzdCBjaGVjayBmb3IgaXQgaGVyZVxyXG5qUXVlcnkuZWFjaCggWyBcInRvcFwiLCBcImxlZnRcIiBdLCBmdW5jdGlvbiggaSwgcHJvcCApIHtcclxuXHRqUXVlcnkuY3NzSG9va3NbIHByb3AgXSA9IGFkZEdldEhvb2tJZiggc3VwcG9ydC5waXhlbFBvc2l0aW9uLFxyXG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkICkge1xyXG5cdFx0XHRpZiAoIGNvbXB1dGVkICkge1xyXG5cdFx0XHRcdGNvbXB1dGVkID0gY3VyQ1NTKCBlbGVtLCBwcm9wICk7XHJcblxyXG5cdFx0XHRcdC8vIElmIGN1ckNTUyByZXR1cm5zIHBlcmNlbnRhZ2UsIGZhbGxiYWNrIHRvIG9mZnNldFxyXG5cdFx0XHRcdHJldHVybiBybnVtbm9ucHgudGVzdCggY29tcHV0ZWQgKSA/XHJcblx0XHRcdFx0XHRqUXVlcnkoIGVsZW0gKS5wb3NpdGlvbigpWyBwcm9wIF0gKyBcInB4XCIgOlxyXG5cdFx0XHRcdFx0Y29tcHV0ZWQ7XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHQpO1xyXG59ICk7XHJcblxyXG5cclxuLy8gQ3JlYXRlIGlubmVySGVpZ2h0LCBpbm5lcldpZHRoLCBoZWlnaHQsIHdpZHRoLCBvdXRlckhlaWdodCBhbmQgb3V0ZXJXaWR0aCBtZXRob2RzXHJcbmpRdWVyeS5lYWNoKCB7IEhlaWdodDogXCJoZWlnaHRcIiwgV2lkdGg6IFwid2lkdGhcIiB9LCBmdW5jdGlvbiggbmFtZSwgdHlwZSApIHtcclxuXHRqUXVlcnkuZWFjaCggeyBwYWRkaW5nOiBcImlubmVyXCIgKyBuYW1lLCBjb250ZW50OiB0eXBlLCBcIlwiOiBcIm91dGVyXCIgKyBuYW1lIH0sXHJcblx0XHRmdW5jdGlvbiggZGVmYXVsdEV4dHJhLCBmdW5jTmFtZSApIHtcclxuXHJcblx0XHQvLyBNYXJnaW4gaXMgb25seSBmb3Igb3V0ZXJIZWlnaHQsIG91dGVyV2lkdGhcclxuXHRcdGpRdWVyeS5mblsgZnVuY05hbWUgXSA9IGZ1bmN0aW9uKCBtYXJnaW4sIHZhbHVlICkge1xyXG5cdFx0XHR2YXIgY2hhaW5hYmxlID0gYXJndW1lbnRzLmxlbmd0aCAmJiAoIGRlZmF1bHRFeHRyYSB8fCB0eXBlb2YgbWFyZ2luICE9PSBcImJvb2xlYW5cIiApLFxyXG5cdFx0XHRcdGV4dHJhID0gZGVmYXVsdEV4dHJhIHx8ICggbWFyZ2luID09PSB0cnVlIHx8IHZhbHVlID09PSB0cnVlID8gXCJtYXJnaW5cIiA6IFwiYm9yZGVyXCIgKTtcclxuXHJcblx0XHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCB2YWx1ZSApIHtcclxuXHRcdFx0XHR2YXIgZG9jO1xyXG5cclxuXHRcdFx0XHRpZiAoIGpRdWVyeS5pc1dpbmRvdyggZWxlbSApICkge1xyXG5cclxuXHRcdFx0XHRcdC8vIEFzIG9mIDUvOC8yMDEyIHRoaXMgd2lsbCB5aWVsZCBpbmNvcnJlY3QgcmVzdWx0cyBmb3IgTW9iaWxlIFNhZmFyaSwgYnV0IHRoZXJlXHJcblx0XHRcdFx0XHQvLyBpc24ndCBhIHdob2xlIGxvdCB3ZSBjYW4gZG8uIFNlZSBwdWxsIHJlcXVlc3QgYXQgdGhpcyBVUkwgZm9yIGRpc2N1c3Npb246XHJcblx0XHRcdFx0XHQvLyBodHRwczovL2dpdGh1Yi5jb20vanF1ZXJ5L2pxdWVyeS9wdWxsLzc2NFxyXG5cdFx0XHRcdFx0cmV0dXJuIGVsZW0uZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50WyBcImNsaWVudFwiICsgbmFtZSBdO1xyXG5cdFx0XHRcdH1cclxuXHJcblx0XHRcdFx0Ly8gR2V0IGRvY3VtZW50IHdpZHRoIG9yIGhlaWdodFxyXG5cdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gOSApIHtcclxuXHRcdFx0XHRcdGRvYyA9IGVsZW0uZG9jdW1lbnRFbGVtZW50O1xyXG5cclxuXHRcdFx0XHRcdC8vIEVpdGhlciBzY3JvbGxbV2lkdGgvSGVpZ2h0XSBvciBvZmZzZXRbV2lkdGgvSGVpZ2h0XSBvciBjbGllbnRbV2lkdGgvSGVpZ2h0XSxcclxuXHRcdFx0XHRcdC8vIHdoaWNoZXZlciBpcyBncmVhdGVzdFxyXG5cdFx0XHRcdFx0cmV0dXJuIE1hdGgubWF4KFxyXG5cdFx0XHRcdFx0XHRlbGVtLmJvZHlbIFwic2Nyb2xsXCIgKyBuYW1lIF0sIGRvY1sgXCJzY3JvbGxcIiArIG5hbWUgXSxcclxuXHRcdFx0XHRcdFx0ZWxlbS5ib2R5WyBcIm9mZnNldFwiICsgbmFtZSBdLCBkb2NbIFwib2Zmc2V0XCIgKyBuYW1lIF0sXHJcblx0XHRcdFx0XHRcdGRvY1sgXCJjbGllbnRcIiArIG5hbWUgXVxyXG5cdFx0XHRcdFx0KTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdHJldHVybiB2YWx1ZSA9PT0gdW5kZWZpbmVkID9cclxuXHJcblx0XHRcdFx0XHQvLyBHZXQgd2lkdGggb3IgaGVpZ2h0IG9uIHRoZSBlbGVtZW50LCByZXF1ZXN0aW5nIGJ1dCBub3QgZm9yY2luZyBwYXJzZUZsb2F0XHJcblx0XHRcdFx0XHRqUXVlcnkuY3NzKCBlbGVtLCB0eXBlLCBleHRyYSApIDpcclxuXHJcblx0XHRcdFx0XHQvLyBTZXQgd2lkdGggb3IgaGVpZ2h0IG9uIHRoZSBlbGVtZW50XHJcblx0XHRcdFx0XHRqUXVlcnkuc3R5bGUoIGVsZW0sIHR5cGUsIHZhbHVlLCBleHRyYSApO1xyXG5cdFx0XHR9LCB0eXBlLCBjaGFpbmFibGUgPyBtYXJnaW4gOiB1bmRlZmluZWQsIGNoYWluYWJsZSwgbnVsbCApO1xyXG5cdFx0fTtcclxuXHR9ICk7XHJcbn0gKTtcclxuXHJcblxyXG5qUXVlcnkuZm4uZXh0ZW5kKCB7XHJcblxyXG5cdGJpbmQ6IGZ1bmN0aW9uKCB0eXBlcywgZGF0YSwgZm4gKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZXMsIG51bGwsIGRhdGEsIGZuICk7XHJcblx0fSxcclxuXHR1bmJpbmQ6IGZ1bmN0aW9uKCB0eXBlcywgZm4gKSB7XHJcblx0XHRyZXR1cm4gdGhpcy5vZmYoIHR5cGVzLCBudWxsLCBmbiApO1xyXG5cdH0sXHJcblxyXG5cdGRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBkYXRhLCBmbiApIHtcclxuXHRcdHJldHVybiB0aGlzLm9uKCB0eXBlcywgc2VsZWN0b3IsIGRhdGEsIGZuICk7XHJcblx0fSxcclxuXHR1bmRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBmbiApIHtcclxuXHJcblx0XHQvLyAoIG5hbWVzcGFjZSApIG9yICggc2VsZWN0b3IsIHR5cGVzIFssIGZuXSApXHJcblx0XHRyZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/XHJcblx0XHRcdHRoaXMub2ZmKCBzZWxlY3RvciwgXCIqKlwiICkgOlxyXG5cdFx0XHR0aGlzLm9mZiggdHlwZXMsIHNlbGVjdG9yIHx8IFwiKipcIiwgZm4gKTtcclxuXHR9LFxyXG5cdHNpemU6IGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIHRoaXMubGVuZ3RoO1xyXG5cdH1cclxufSApO1xyXG5cclxualF1ZXJ5LmZuLmFuZFNlbGYgPSBqUXVlcnkuZm4uYWRkQmFjaztcclxuXHJcblxyXG5cclxuXHJcbi8vIFJlZ2lzdGVyIGFzIGEgbmFtZWQgQU1EIG1vZHVsZSwgc2luY2UgalF1ZXJ5IGNhbiBiZSBjb25jYXRlbmF0ZWQgd2l0aCBvdGhlclxyXG4vLyBmaWxlcyB0aGF0IG1heSB1c2UgZGVmaW5lLCBidXQgbm90IHZpYSBhIHByb3BlciBjb25jYXRlbmF0aW9uIHNjcmlwdCB0aGF0XHJcbi8vIHVuZGVyc3RhbmRzIGFub255bW91cyBBTUQgbW9kdWxlcy4gQSBuYW1lZCBBTUQgaXMgc2FmZXN0IGFuZCBtb3N0IHJvYnVzdFxyXG4vLyB3YXkgdG8gcmVnaXN0ZXIuIExvd2VyY2FzZSBqcXVlcnkgaXMgdXNlZCBiZWNhdXNlIEFNRCBtb2R1bGUgbmFtZXMgYXJlXHJcbi8vIGRlcml2ZWQgZnJvbSBmaWxlIG5hbWVzLCBhbmQgalF1ZXJ5IGlzIG5vcm1hbGx5IGRlbGl2ZXJlZCBpbiBhIGxvd2VyY2FzZVxyXG4vLyBmaWxlIG5hbWUuIERvIHRoaXMgYWZ0ZXIgY3JlYXRpbmcgdGhlIGdsb2JhbCBzbyB0aGF0IGlmIGFuIEFNRCBtb2R1bGUgd2FudHNcclxuLy8gdG8gY2FsbCBub0NvbmZsaWN0IHRvIGhpZGUgdGhpcyB2ZXJzaW9uIG9mIGpRdWVyeSwgaXQgd2lsbCB3b3JrLlxyXG5cclxuLy8gTm90ZSB0aGF0IGZvciBtYXhpbXVtIHBvcnRhYmlsaXR5LCBsaWJyYXJpZXMgdGhhdCBhcmUgbm90IGpRdWVyeSBzaG91bGRcclxuLy8gZGVjbGFyZSB0aGVtc2VsdmVzIGFzIGFub255bW91cyBtb2R1bGVzLCBhbmQgYXZvaWQgc2V0dGluZyBhIGdsb2JhbCBpZiBhblxyXG4vLyBBTUQgbG9hZGVyIGlzIHByZXNlbnQuIGpRdWVyeSBpcyBhIHNwZWNpYWwgY2FzZS4gRm9yIG1vcmUgaW5mb3JtYXRpb24sIHNlZVxyXG4vLyBodHRwczovL2dpdGh1Yi5jb20vanJidXJrZS9yZXF1aXJlanMvd2lraS9VcGRhdGluZy1leGlzdGluZy1saWJyYXJpZXMjd2lraS1hbm9uXHJcblxyXG5pZiAoIHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kICkge1xyXG5cdGRlZmluZSggXCJqcXVlcnlcIiwgW10sIGZ1bmN0aW9uKCkge1xyXG5cdFx0cmV0dXJuIGpRdWVyeTtcclxuXHR9ICk7XHJcbn1cclxuXHJcblxyXG5cclxudmFyXHJcblxyXG5cdC8vIE1hcCBvdmVyIGpRdWVyeSBpbiBjYXNlIG9mIG92ZXJ3cml0ZVxyXG5cdF9qUXVlcnkgPSB3aW5kb3cualF1ZXJ5LFxyXG5cclxuXHQvLyBNYXAgb3ZlciB0aGUgJCBpbiBjYXNlIG9mIG92ZXJ3cml0ZVxyXG5cdF8kID0gd2luZG93LiQ7XHJcblxyXG5qUXVlcnkubm9Db25mbGljdCA9IGZ1bmN0aW9uKCBkZWVwICkge1xyXG5cdGlmICggd2luZG93LiQgPT09IGpRdWVyeSApIHtcclxuXHRcdHdpbmRvdy4kID0gXyQ7XHJcblx0fVxyXG5cclxuXHRpZiAoIGRlZXAgJiYgd2luZG93LmpRdWVyeSA9PT0galF1ZXJ5ICkge1xyXG5cdFx0d2luZG93LmpRdWVyeSA9IF9qUXVlcnk7XHJcblx0fVxyXG5cclxuXHRyZXR1cm4galF1ZXJ5O1xyXG59O1xyXG5cclxuLy8gRXhwb3NlIGpRdWVyeSBhbmQgJCBpZGVudGlmaWVycywgZXZlbiBpbiBBTURcclxuLy8gKCM3MTAyI2NvbW1lbnQ6MTAsIGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvanF1ZXJ5L3B1bGwvNTU3KVxyXG4vLyBhbmQgQ29tbW9uSlMgZm9yIGJyb3dzZXIgZW11bGF0b3JzICgjMTM1NjYpXHJcbmlmICggIW5vR2xvYmFsICkge1xyXG5cdHdpbmRvdy5qUXVlcnkgPSB3aW5kb3cuJCA9IGpRdWVyeTtcclxufVxyXG5cclxucmV0dXJuIGpRdWVyeTtcclxufSkpO1xyXG4iLCJ3aW5kb3cud2hhdElucHV0ID0gKGZ1bmN0aW9uKCkge1xyXG5cclxuICAndXNlIHN0cmljdCc7XHJcblxyXG4gIC8qXHJcbiAgICAtLS0tLS0tLS0tLS0tLS1cclxuICAgIHZhcmlhYmxlc1xyXG4gICAgLS0tLS0tLS0tLS0tLS0tXHJcbiAgKi9cclxuXHJcbiAgLy8gYXJyYXkgb2YgYWN0aXZlbHkgcHJlc3NlZCBrZXlzXHJcbiAgdmFyIGFjdGl2ZUtleXMgPSBbXTtcclxuXHJcbiAgLy8gY2FjaGUgZG9jdW1lbnQuYm9keVxyXG4gIHZhciBib2R5O1xyXG5cclxuICAvLyBib29sZWFuOiB0cnVlIGlmIHRvdWNoIGJ1ZmZlciB0aW1lciBpcyBydW5uaW5nXHJcbiAgdmFyIGJ1ZmZlciA9IGZhbHNlO1xyXG5cclxuICAvLyB0aGUgbGFzdCB1c2VkIGlucHV0IHR5cGVcclxuICB2YXIgY3VycmVudElucHV0ID0gbnVsbDtcclxuXHJcbiAgLy8gYGlucHV0YCB0eXBlcyB0aGF0IGRvbid0IGFjY2VwdCB0ZXh0XHJcbiAgdmFyIG5vblR5cGluZ0lucHV0cyA9IFtcclxuICAgICdidXR0b24nLFxyXG4gICAgJ2NoZWNrYm94JyxcclxuICAgICdmaWxlJyxcclxuICAgICdpbWFnZScsXHJcbiAgICAncmFkaW8nLFxyXG4gICAgJ3Jlc2V0JyxcclxuICAgICdzdWJtaXQnXHJcbiAgXTtcclxuXHJcbiAgLy8gZGV0ZWN0IHZlcnNpb24gb2YgbW91c2Ugd2hlZWwgZXZlbnQgdG8gdXNlXHJcbiAgLy8gdmlhIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0V2ZW50cy93aGVlbFxyXG4gIHZhciBtb3VzZVdoZWVsID0gZGV0ZWN0V2hlZWwoKTtcclxuXHJcbiAgLy8gbGlzdCBvZiBtb2RpZmllciBrZXlzIGNvbW1vbmx5IHVzZWQgd2l0aCB0aGUgbW91c2UgYW5kXHJcbiAgLy8gY2FuIGJlIHNhZmVseSBpZ25vcmVkIHRvIHByZXZlbnQgZmFsc2Uga2V5Ym9hcmQgZGV0ZWN0aW9uXHJcbiAgdmFyIGlnbm9yZU1hcCA9IFtcclxuICAgIDE2LCAvLyBzaGlmdFxyXG4gICAgMTcsIC8vIGNvbnRyb2xcclxuICAgIDE4LCAvLyBhbHRcclxuICAgIDkxLCAvLyBXaW5kb3dzIGtleSAvIGxlZnQgQXBwbGUgY21kXHJcbiAgICA5MyAgLy8gV2luZG93cyBtZW51IC8gcmlnaHQgQXBwbGUgY21kXHJcbiAgXTtcclxuXHJcbiAgLy8gbWFwcGluZyBvZiBldmVudHMgdG8gaW5wdXQgdHlwZXNcclxuICB2YXIgaW5wdXRNYXAgPSB7XHJcbiAgICAna2V5ZG93bic6ICdrZXlib2FyZCcsXHJcbiAgICAna2V5dXAnOiAna2V5Ym9hcmQnLFxyXG4gICAgJ21vdXNlZG93bic6ICdtb3VzZScsXHJcbiAgICAnbW91c2Vtb3ZlJzogJ21vdXNlJyxcclxuICAgICdNU1BvaW50ZXJEb3duJzogJ3BvaW50ZXInLFxyXG4gICAgJ01TUG9pbnRlck1vdmUnOiAncG9pbnRlcicsXHJcbiAgICAncG9pbnRlcmRvd24nOiAncG9pbnRlcicsXHJcbiAgICAncG9pbnRlcm1vdmUnOiAncG9pbnRlcicsXHJcbiAgICAndG91Y2hzdGFydCc6ICd0b3VjaCdcclxuICB9O1xyXG5cclxuICAvLyBhZGQgY29ycmVjdCBtb3VzZSB3aGVlbCBldmVudCBtYXBwaW5nIHRvIGBpbnB1dE1hcGBcclxuICBpbnB1dE1hcFtkZXRlY3RXaGVlbCgpXSA9ICdtb3VzZSc7XHJcblxyXG4gIC8vIGFycmF5IG9mIGFsbCB1c2VkIGlucHV0IHR5cGVzXHJcbiAgdmFyIGlucHV0VHlwZXMgPSBbXTtcclxuXHJcbiAgLy8gbWFwcGluZyBvZiBrZXkgY29kZXMgdG8gYSBjb21tb24gbmFtZVxyXG4gIHZhciBrZXlNYXAgPSB7XHJcbiAgICA5OiAndGFiJyxcclxuICAgIDEzOiAnZW50ZXInLFxyXG4gICAgMTY6ICdzaGlmdCcsXHJcbiAgICAyNzogJ2VzYycsXHJcbiAgICAzMjogJ3NwYWNlJyxcclxuICAgIDM3OiAnbGVmdCcsXHJcbiAgICAzODogJ3VwJyxcclxuICAgIDM5OiAncmlnaHQnLFxyXG4gICAgNDA6ICdkb3duJ1xyXG4gIH07XHJcblxyXG4gIC8vIG1hcCBvZiBJRSAxMCBwb2ludGVyIGV2ZW50c1xyXG4gIHZhciBwb2ludGVyTWFwID0ge1xyXG4gICAgMjogJ3RvdWNoJyxcclxuICAgIDM6ICd0b3VjaCcsIC8vIHRyZWF0IHBlbiBsaWtlIHRvdWNoXHJcbiAgICA0OiAnbW91c2UnXHJcbiAgfTtcclxuXHJcbiAgLy8gdG91Y2ggYnVmZmVyIHRpbWVyXHJcbiAgdmFyIHRpbWVyO1xyXG5cclxuXHJcbiAgLypcclxuICAgIC0tLS0tLS0tLS0tLS0tLVxyXG4gICAgZnVuY3Rpb25zXHJcbiAgICAtLS0tLS0tLS0tLS0tLS1cclxuICAqL1xyXG5cclxuICAvLyBhbGxvd3MgZXZlbnRzIHRoYXQgYXJlIGFsc28gdHJpZ2dlcmVkIHRvIGJlIGZpbHRlcmVkIG91dCBmb3IgYHRvdWNoc3RhcnRgXHJcbiAgZnVuY3Rpb24gZXZlbnRCdWZmZXIoKSB7XHJcbiAgICBjbGVhclRpbWVyKCk7XHJcbiAgICBzZXRJbnB1dChldmVudCk7XHJcblxyXG4gICAgYnVmZmVyID0gdHJ1ZTtcclxuICAgIHRpbWVyID0gd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcbiAgICAgIGJ1ZmZlciA9IGZhbHNlO1xyXG4gICAgfSwgNjUwKTtcclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIGJ1ZmZlcmVkRXZlbnQoZXZlbnQpIHtcclxuICAgIGlmICghYnVmZmVyKSBzZXRJbnB1dChldmVudCk7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiB1bkJ1ZmZlcmVkRXZlbnQoZXZlbnQpIHtcclxuICAgIGNsZWFyVGltZXIoKTtcclxuICAgIHNldElucHV0KGV2ZW50KTtcclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIGNsZWFyVGltZXIoKSB7XHJcbiAgICB3aW5kb3cuY2xlYXJUaW1lb3V0KHRpbWVyKTtcclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIHNldElucHV0KGV2ZW50KSB7XHJcbiAgICB2YXIgZXZlbnRLZXkgPSBrZXkoZXZlbnQpO1xyXG4gICAgdmFyIHZhbHVlID0gaW5wdXRNYXBbZXZlbnQudHlwZV07XHJcbiAgICBpZiAodmFsdWUgPT09ICdwb2ludGVyJykgdmFsdWUgPSBwb2ludGVyVHlwZShldmVudCk7XHJcblxyXG4gICAgLy8gZG9uJ3QgZG8gYW55dGhpbmcgaWYgdGhlIHZhbHVlIG1hdGNoZXMgdGhlIGlucHV0IHR5cGUgYWxyZWFkeSBzZXRcclxuICAgIGlmIChjdXJyZW50SW5wdXQgIT09IHZhbHVlKSB7XHJcbiAgICAgIHZhciBldmVudFRhcmdldCA9IHRhcmdldChldmVudCk7XHJcbiAgICAgIHZhciBldmVudFRhcmdldE5vZGUgPSBldmVudFRhcmdldC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xyXG4gICAgICB2YXIgZXZlbnRUYXJnZXRUeXBlID0gKGV2ZW50VGFyZ2V0Tm9kZSA9PT0gJ2lucHV0JykgPyBldmVudFRhcmdldC5nZXRBdHRyaWJ1dGUoJ3R5cGUnKSA6IG51bGw7XHJcblxyXG4gICAgICBpZiAoXHJcbiAgICAgICAgKC8vIG9ubHkgaWYgdGhlIHVzZXIgZmxhZyB0byBhbGxvdyB0eXBpbmcgaW4gZm9ybSBmaWVsZHMgaXNuJ3Qgc2V0XHJcbiAgICAgICAgIWJvZHkuaGFzQXR0cmlidXRlKCdkYXRhLXdoYXRpbnB1dC1mb3JtdHlwaW5nJykgJiZcclxuXHJcbiAgICAgICAgLy8gb25seSBpZiBjdXJyZW50SW5wdXQgaGFzIGEgdmFsdWVcclxuICAgICAgICBjdXJyZW50SW5wdXQgJiZcclxuXHJcbiAgICAgICAgLy8gb25seSBpZiB0aGUgaW5wdXQgaXMgYGtleWJvYXJkYFxyXG4gICAgICAgIHZhbHVlID09PSAna2V5Ym9hcmQnICYmXHJcblxyXG4gICAgICAgIC8vIG5vdCBpZiB0aGUga2V5IGlzIGBUQUJgXHJcbiAgICAgICAga2V5TWFwW2V2ZW50S2V5XSAhPT0gJ3RhYicgJiZcclxuXHJcbiAgICAgICAgLy8gb25seSBpZiB0aGUgdGFyZ2V0IGlzIGEgZm9ybSBpbnB1dCB0aGF0IGFjY2VwdHMgdGV4dFxyXG4gICAgICAgIChcclxuICAgICAgICAgICBldmVudFRhcmdldE5vZGUgPT09ICd0ZXh0YXJlYScgfHxcclxuICAgICAgICAgICBldmVudFRhcmdldE5vZGUgPT09ICdzZWxlY3QnIHx8XHJcbiAgICAgICAgICAgKGV2ZW50VGFyZ2V0Tm9kZSA9PT0gJ2lucHV0JyAmJiBub25UeXBpbmdJbnB1dHMuaW5kZXhPZihldmVudFRhcmdldFR5cGUpIDwgMClcclxuICAgICAgICApKSB8fCAoXHJcbiAgICAgICAgICAvLyBpZ25vcmUgbW9kaWZpZXIga2V5c1xyXG4gICAgICAgICAgaWdub3JlTWFwLmluZGV4T2YoZXZlbnRLZXkpID4gLTFcclxuICAgICAgICApXHJcbiAgICAgICkge1xyXG4gICAgICAgIC8vIGlnbm9yZSBrZXlib2FyZCB0eXBpbmdcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzd2l0Y2hJbnB1dCh2YWx1ZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAodmFsdWUgPT09ICdrZXlib2FyZCcpIGxvZ0tleXMoZXZlbnRLZXkpO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gc3dpdGNoSW5wdXQoc3RyaW5nKSB7XHJcbiAgICBjdXJyZW50SW5wdXQgPSBzdHJpbmc7XHJcbiAgICBib2R5LnNldEF0dHJpYnV0ZSgnZGF0YS13aGF0aW5wdXQnLCBjdXJyZW50SW5wdXQpO1xyXG5cclxuICAgIGlmIChpbnB1dFR5cGVzLmluZGV4T2YoY3VycmVudElucHV0KSA9PT0gLTEpIGlucHV0VHlwZXMucHVzaChjdXJyZW50SW5wdXQpO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24ga2V5KGV2ZW50KSB7XHJcbiAgICByZXR1cm4gKGV2ZW50LmtleUNvZGUpID8gZXZlbnQua2V5Q29kZSA6IGV2ZW50LndoaWNoO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gdGFyZ2V0KGV2ZW50KSB7XHJcbiAgICByZXR1cm4gZXZlbnQudGFyZ2V0IHx8IGV2ZW50LnNyY0VsZW1lbnQ7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBwb2ludGVyVHlwZShldmVudCkge1xyXG4gICAgaWYgKHR5cGVvZiBldmVudC5wb2ludGVyVHlwZSA9PT0gJ251bWJlcicpIHtcclxuICAgICAgcmV0dXJuIHBvaW50ZXJNYXBbZXZlbnQucG9pbnRlclR5cGVdO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIChldmVudC5wb2ludGVyVHlwZSA9PT0gJ3BlbicpID8gJ3RvdWNoJyA6IGV2ZW50LnBvaW50ZXJUeXBlOyAvLyB0cmVhdCBwZW4gbGlrZSB0b3VjaFxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8ga2V5Ym9hcmQgbG9nZ2luZ1xyXG4gIGZ1bmN0aW9uIGxvZ0tleXMoZXZlbnRLZXkpIHtcclxuICAgIGlmIChhY3RpdmVLZXlzLmluZGV4T2Yoa2V5TWFwW2V2ZW50S2V5XSkgPT09IC0xICYmIGtleU1hcFtldmVudEtleV0pIGFjdGl2ZUtleXMucHVzaChrZXlNYXBbZXZlbnRLZXldKTtcclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIHVuTG9nS2V5cyhldmVudCkge1xyXG4gICAgdmFyIGV2ZW50S2V5ID0ga2V5KGV2ZW50KTtcclxuICAgIHZhciBhcnJheVBvcyA9IGFjdGl2ZUtleXMuaW5kZXhPZihrZXlNYXBbZXZlbnRLZXldKTtcclxuXHJcbiAgICBpZiAoYXJyYXlQb3MgIT09IC0xKSBhY3RpdmVLZXlzLnNwbGljZShhcnJheVBvcywgMSk7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBiaW5kRXZlbnRzKCkge1xyXG4gICAgYm9keSA9IGRvY3VtZW50LmJvZHk7XHJcblxyXG4gICAgLy8gcG9pbnRlciBldmVudHMgKG1vdXNlLCBwZW4sIHRvdWNoKVxyXG4gICAgaWYgKHdpbmRvdy5Qb2ludGVyRXZlbnQpIHtcclxuICAgICAgYm9keS5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyZG93bicsIGJ1ZmZlcmVkRXZlbnQpO1xyXG4gICAgICBib2R5LmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgYnVmZmVyZWRFdmVudCk7XHJcbiAgICB9IGVsc2UgaWYgKHdpbmRvdy5NU1BvaW50ZXJFdmVudCkge1xyXG4gICAgICBib2R5LmFkZEV2ZW50TGlzdGVuZXIoJ01TUG9pbnRlckRvd24nLCBidWZmZXJlZEV2ZW50KTtcclxuICAgICAgYm9keS5hZGRFdmVudExpc3RlbmVyKCdNU1BvaW50ZXJNb3ZlJywgYnVmZmVyZWRFdmVudCk7XHJcbiAgICB9IGVsc2Uge1xyXG5cclxuICAgICAgLy8gbW91c2UgZXZlbnRzXHJcbiAgICAgIGJvZHkuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgYnVmZmVyZWRFdmVudCk7XHJcbiAgICAgIGJvZHkuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgYnVmZmVyZWRFdmVudCk7XHJcblxyXG4gICAgICAvLyB0b3VjaCBldmVudHNcclxuICAgICAgaWYgKCdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdykge1xyXG4gICAgICAgIGJvZHkuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIGV2ZW50QnVmZmVyKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIG1vdXNlIHdoZWVsXHJcbiAgICBib2R5LmFkZEV2ZW50TGlzdGVuZXIobW91c2VXaGVlbCwgYnVmZmVyZWRFdmVudCk7XHJcblxyXG4gICAgLy8ga2V5Ym9hcmQgZXZlbnRzXHJcbiAgICBib2R5LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB1bkJ1ZmZlcmVkRXZlbnQpO1xyXG4gICAgYm9keS5hZGRFdmVudExpc3RlbmVyKCdrZXl1cCcsIHVuQnVmZmVyZWRFdmVudCk7XHJcbiAgICBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdrZXl1cCcsIHVuTG9nS2V5cyk7XHJcbiAgfVxyXG5cclxuXHJcbiAgLypcclxuICAgIC0tLS0tLS0tLS0tLS0tLVxyXG4gICAgdXRpbGl0aWVzXHJcbiAgICAtLS0tLS0tLS0tLS0tLS1cclxuICAqL1xyXG5cclxuICAvLyBkZXRlY3QgdmVyc2lvbiBvZiBtb3VzZSB3aGVlbCBldmVudCB0byB1c2VcclxuICAvLyB2aWEgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvRXZlbnRzL3doZWVsXHJcbiAgZnVuY3Rpb24gZGV0ZWN0V2hlZWwoKSB7XHJcbiAgICByZXR1cm4gbW91c2VXaGVlbCA9ICdvbndoZWVsJyBpbiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKSA/XHJcbiAgICAgICd3aGVlbCcgOiAvLyBNb2Rlcm4gYnJvd3NlcnMgc3VwcG9ydCBcIndoZWVsXCJcclxuXHJcbiAgICAgIGRvY3VtZW50Lm9ubW91c2V3aGVlbCAhPT0gdW5kZWZpbmVkID9cclxuICAgICAgICAnbW91c2V3aGVlbCcgOiAvLyBXZWJraXQgYW5kIElFIHN1cHBvcnQgYXQgbGVhc3QgXCJtb3VzZXdoZWVsXCJcclxuICAgICAgICAnRE9NTW91c2VTY3JvbGwnOyAvLyBsZXQncyBhc3N1bWUgdGhhdCByZW1haW5pbmcgYnJvd3NlcnMgYXJlIG9sZGVyIEZpcmVmb3hcclxuICB9XHJcblxyXG5cclxuICAvKlxyXG4gICAgLS0tLS0tLS0tLS0tLS0tXHJcbiAgICBpbml0XHJcblxyXG4gICAgZG9uJ3Qgc3RhcnQgc2NyaXB0IHVubGVzcyBicm93c2VyIGN1dHMgdGhlIG11c3RhcmQsXHJcbiAgICBhbHNvIHBhc3NlcyBpZiBwb2x5ZmlsbHMgYXJlIHVzZWRcclxuICAgIC0tLS0tLS0tLS0tLS0tLVxyXG4gICovXHJcblxyXG4gIGlmIChcclxuICAgICdhZGRFdmVudExpc3RlbmVyJyBpbiB3aW5kb3cgJiZcclxuICAgIEFycmF5LnByb3RvdHlwZS5pbmRleE9mXHJcbiAgKSB7XHJcblxyXG4gICAgLy8gaWYgdGhlIGRvbSBpcyBhbHJlYWR5IHJlYWR5IGFscmVhZHkgKHNjcmlwdCB3YXMgcGxhY2VkIGF0IGJvdHRvbSBvZiA8Ym9keT4pXHJcbiAgICBpZiAoZG9jdW1lbnQuYm9keSkge1xyXG4gICAgICBiaW5kRXZlbnRzKCk7XHJcblxyXG4gICAgLy8gb3RoZXJ3aXNlIHdhaXQgZm9yIHRoZSBkb20gdG8gbG9hZCAoc2NyaXB0IHdhcyBwbGFjZWQgaW4gdGhlIDxoZWFkPilcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ0RPTUNvbnRlbnRMb2FkZWQnLCBiaW5kRXZlbnRzKTtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICAvKlxyXG4gICAgLS0tLS0tLS0tLS0tLS0tXHJcbiAgICBhcGlcclxuICAgIC0tLS0tLS0tLS0tLS0tLVxyXG4gICovXHJcblxyXG4gIHJldHVybiB7XHJcblxyXG4gICAgLy8gcmV0dXJucyBzdHJpbmc6IHRoZSBjdXJyZW50IGlucHV0IHR5cGVcclxuICAgIGFzazogZnVuY3Rpb24oKSB7IHJldHVybiBjdXJyZW50SW5wdXQ7IH0sXHJcblxyXG4gICAgLy8gcmV0dXJucyBhcnJheTogY3VycmVudGx5IHByZXNzZWQga2V5c1xyXG4gICAga2V5czogZnVuY3Rpb24oKSB7IHJldHVybiBhY3RpdmVLZXlzOyB9LFxyXG5cclxuICAgIC8vIHJldHVybnMgYXJyYXk6IGFsbCB0aGUgZGV0ZWN0ZWQgaW5wdXQgdHlwZXNcclxuICAgIHR5cGVzOiBmdW5jdGlvbigpIHsgcmV0dXJuIGlucHV0VHlwZXM7IH0sXHJcblxyXG4gICAgLy8gYWNjZXB0cyBzdHJpbmc6IG1hbnVhbGx5IHNldCB0aGUgaW5wdXQgdHlwZVxyXG4gICAgc2V0OiBzd2l0Y2hJbnB1dFxyXG4gIH07XHJcblxyXG59KCkpO1xyXG4iLCIhZnVuY3Rpb24oJCkge1xyXG5cclxuXCJ1c2Ugc3RyaWN0XCI7XHJcblxyXG52YXIgRk9VTkRBVElPTl9WRVJTSU9OID0gJzYuMi4yJztcclxuXHJcbi8vIEdsb2JhbCBGb3VuZGF0aW9uIG9iamVjdFxyXG4vLyBUaGlzIGlzIGF0dGFjaGVkIHRvIHRoZSB3aW5kb3csIG9yIHVzZWQgYXMgYSBtb2R1bGUgZm9yIEFNRC9Ccm93c2VyaWZ5XHJcbnZhciBGb3VuZGF0aW9uID0ge1xyXG4gIHZlcnNpb246IEZPVU5EQVRJT05fVkVSU0lPTixcclxuXHJcbiAgLyoqXHJcbiAgICogU3RvcmVzIGluaXRpYWxpemVkIHBsdWdpbnMuXHJcbiAgICovXHJcbiAgX3BsdWdpbnM6IHt9LFxyXG5cclxuICAvKipcclxuICAgKiBTdG9yZXMgZ2VuZXJhdGVkIHVuaXF1ZSBpZHMgZm9yIHBsdWdpbiBpbnN0YW5jZXNcclxuICAgKi9cclxuICBfdXVpZHM6IFtdLFxyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm5zIGEgYm9vbGVhbiBmb3IgUlRMIHN1cHBvcnRcclxuICAgKi9cclxuICBydGw6IGZ1bmN0aW9uKCl7XHJcbiAgICByZXR1cm4gJCgnaHRtbCcpLmF0dHIoJ2RpcicpID09PSAncnRsJztcclxuICB9LFxyXG4gIC8qKlxyXG4gICAqIERlZmluZXMgYSBGb3VuZGF0aW9uIHBsdWdpbiwgYWRkaW5nIGl0IHRvIHRoZSBgRm91bmRhdGlvbmAgbmFtZXNwYWNlIGFuZCB0aGUgbGlzdCBvZiBwbHVnaW5zIHRvIGluaXRpYWxpemUgd2hlbiByZWZsb3dpbmcuXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IHBsdWdpbiAtIFRoZSBjb25zdHJ1Y3RvciBvZiB0aGUgcGx1Z2luLlxyXG4gICAqL1xyXG4gIHBsdWdpbjogZnVuY3Rpb24ocGx1Z2luLCBuYW1lKSB7XHJcbiAgICAvLyBPYmplY3Qga2V5IHRvIHVzZSB3aGVuIGFkZGluZyB0byBnbG9iYWwgRm91bmRhdGlvbiBvYmplY3RcclxuICAgIC8vIEV4YW1wbGVzOiBGb3VuZGF0aW9uLlJldmVhbCwgRm91bmRhdGlvbi5PZmZDYW52YXNcclxuICAgIHZhciBjbGFzc05hbWUgPSAobmFtZSB8fCBmdW5jdGlvbk5hbWUocGx1Z2luKSk7XHJcbiAgICAvLyBPYmplY3Qga2V5IHRvIHVzZSB3aGVuIHN0b3JpbmcgdGhlIHBsdWdpbiwgYWxzbyB1c2VkIHRvIGNyZWF0ZSB0aGUgaWRlbnRpZnlpbmcgZGF0YSBhdHRyaWJ1dGUgZm9yIHRoZSBwbHVnaW5cclxuICAgIC8vIEV4YW1wbGVzOiBkYXRhLXJldmVhbCwgZGF0YS1vZmYtY2FudmFzXHJcbiAgICB2YXIgYXR0ck5hbWUgID0gaHlwaGVuYXRlKGNsYXNzTmFtZSk7XHJcblxyXG4gICAgLy8gQWRkIHRvIHRoZSBGb3VuZGF0aW9uIG9iamVjdCBhbmQgdGhlIHBsdWdpbnMgbGlzdCAoZm9yIHJlZmxvd2luZylcclxuICAgIHRoaXMuX3BsdWdpbnNbYXR0ck5hbWVdID0gdGhpc1tjbGFzc05hbWVdID0gcGx1Z2luO1xyXG4gIH0sXHJcbiAgLyoqXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogUG9wdWxhdGVzIHRoZSBfdXVpZHMgYXJyYXkgd2l0aCBwb2ludGVycyB0byBlYWNoIGluZGl2aWR1YWwgcGx1Z2luIGluc3RhbmNlLlxyXG4gICAqIEFkZHMgdGhlIGB6ZlBsdWdpbmAgZGF0YS1hdHRyaWJ1dGUgdG8gcHJvZ3JhbW1hdGljYWxseSBjcmVhdGVkIHBsdWdpbnMgdG8gYWxsb3cgdXNlIG9mICQoc2VsZWN0b3IpLmZvdW5kYXRpb24obWV0aG9kKSBjYWxscy5cclxuICAgKiBBbHNvIGZpcmVzIHRoZSBpbml0aWFsaXphdGlvbiBldmVudCBmb3IgZWFjaCBwbHVnaW4sIGNvbnNvbGlkYXRpbmcgcmVwZXRpdGl2ZSBjb2RlLlxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwbHVnaW4gLSBhbiBpbnN0YW5jZSBvZiBhIHBsdWdpbiwgdXN1YWxseSBgdGhpc2AgaW4gY29udGV4dC5cclxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZSAtIHRoZSBuYW1lIG9mIHRoZSBwbHVnaW4sIHBhc3NlZCBhcyBhIGNhbWVsQ2FzZWQgc3RyaW5nLlxyXG4gICAqIEBmaXJlcyBQbHVnaW4jaW5pdFxyXG4gICAqL1xyXG4gIHJlZ2lzdGVyUGx1Z2luOiBmdW5jdGlvbihwbHVnaW4sIG5hbWUpe1xyXG4gICAgdmFyIHBsdWdpbk5hbWUgPSBuYW1lID8gaHlwaGVuYXRlKG5hbWUpIDogZnVuY3Rpb25OYW1lKHBsdWdpbi5jb25zdHJ1Y3RvcikudG9Mb3dlckNhc2UoKTtcclxuICAgIHBsdWdpbi51dWlkID0gdGhpcy5HZXRZb0RpZ2l0cyg2LCBwbHVnaW5OYW1lKTtcclxuXHJcbiAgICBpZighcGx1Z2luLiRlbGVtZW50LmF0dHIoYGRhdGEtJHtwbHVnaW5OYW1lfWApKXsgcGx1Z2luLiRlbGVtZW50LmF0dHIoYGRhdGEtJHtwbHVnaW5OYW1lfWAsIHBsdWdpbi51dWlkKTsgfVxyXG4gICAgaWYoIXBsdWdpbi4kZWxlbWVudC5kYXRhKCd6ZlBsdWdpbicpKXsgcGx1Z2luLiRlbGVtZW50LmRhdGEoJ3pmUGx1Z2luJywgcGx1Z2luKTsgfVxyXG4gICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgKiBGaXJlcyB3aGVuIHRoZSBwbHVnaW4gaGFzIGluaXRpYWxpemVkLlxyXG4gICAgICAgICAgICogQGV2ZW50IFBsdWdpbiNpbml0XHJcbiAgICAgICAgICAgKi9cclxuICAgIHBsdWdpbi4kZWxlbWVudC50cmlnZ2VyKGBpbml0LnpmLiR7cGx1Z2luTmFtZX1gKTtcclxuXHJcbiAgICB0aGlzLl91dWlkcy5wdXNoKHBsdWdpbi51dWlkKTtcclxuXHJcbiAgICByZXR1cm47XHJcbiAgfSxcclxuICAvKipcclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBSZW1vdmVzIHRoZSBwbHVnaW5zIHV1aWQgZnJvbSB0aGUgX3V1aWRzIGFycmF5LlxyXG4gICAqIFJlbW92ZXMgdGhlIHpmUGx1Z2luIGRhdGEgYXR0cmlidXRlLCBhcyB3ZWxsIGFzIHRoZSBkYXRhLXBsdWdpbi1uYW1lIGF0dHJpYnV0ZS5cclxuICAgKiBBbHNvIGZpcmVzIHRoZSBkZXN0cm95ZWQgZXZlbnQgZm9yIHRoZSBwbHVnaW4sIGNvbnNvbGlkYXRpbmcgcmVwZXRpdGl2ZSBjb2RlLlxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBwbHVnaW4gLSBhbiBpbnN0YW5jZSBvZiBhIHBsdWdpbiwgdXN1YWxseSBgdGhpc2AgaW4gY29udGV4dC5cclxuICAgKiBAZmlyZXMgUGx1Z2luI2Rlc3Ryb3llZFxyXG4gICAqL1xyXG4gIHVucmVnaXN0ZXJQbHVnaW46IGZ1bmN0aW9uKHBsdWdpbil7XHJcbiAgICB2YXIgcGx1Z2luTmFtZSA9IGh5cGhlbmF0ZShmdW5jdGlvbk5hbWUocGx1Z2luLiRlbGVtZW50LmRhdGEoJ3pmUGx1Z2luJykuY29uc3RydWN0b3IpKTtcclxuXHJcbiAgICB0aGlzLl91dWlkcy5zcGxpY2UodGhpcy5fdXVpZHMuaW5kZXhPZihwbHVnaW4udXVpZCksIDEpO1xyXG4gICAgcGx1Z2luLiRlbGVtZW50LnJlbW92ZUF0dHIoYGRhdGEtJHtwbHVnaW5OYW1lfWApLnJlbW92ZURhdGEoJ3pmUGx1Z2luJylcclxuICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICogRmlyZXMgd2hlbiB0aGUgcGx1Z2luIGhhcyBiZWVuIGRlc3Ryb3llZC5cclxuICAgICAgICAgICAqIEBldmVudCBQbHVnaW4jZGVzdHJveWVkXHJcbiAgICAgICAgICAgKi9cclxuICAgICAgICAgIC50cmlnZ2VyKGBkZXN0cm95ZWQuemYuJHtwbHVnaW5OYW1lfWApO1xyXG4gICAgZm9yKHZhciBwcm9wIGluIHBsdWdpbil7XHJcbiAgICAgIHBsdWdpbltwcm9wXSA9IG51bGw7Ly9jbGVhbiB1cCBzY3JpcHQgdG8gcHJlcCBmb3IgZ2FyYmFnZSBjb2xsZWN0aW9uLlxyXG4gICAgfVxyXG4gICAgcmV0dXJuO1xyXG4gIH0sXHJcblxyXG4gIC8qKlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIENhdXNlcyBvbmUgb3IgbW9yZSBhY3RpdmUgcGx1Z2lucyB0byByZS1pbml0aWFsaXplLCByZXNldHRpbmcgZXZlbnQgbGlzdGVuZXJzLCByZWNhbGN1bGF0aW5nIHBvc2l0aW9ucywgZXRjLlxyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwbHVnaW5zIC0gb3B0aW9uYWwgc3RyaW5nIG9mIGFuIGluZGl2aWR1YWwgcGx1Z2luIGtleSwgYXR0YWluZWQgYnkgY2FsbGluZyBgJChlbGVtZW50KS5kYXRhKCdwbHVnaW5OYW1lJylgLCBvciBzdHJpbmcgb2YgYSBwbHVnaW4gY2xhc3MgaS5lLiBgJ2Ryb3Bkb3duJ2BcclxuICAgKiBAZGVmYXVsdCBJZiBubyBhcmd1bWVudCBpcyBwYXNzZWQsIHJlZmxvdyBhbGwgY3VycmVudGx5IGFjdGl2ZSBwbHVnaW5zLlxyXG4gICAqL1xyXG4gICByZUluaXQ6IGZ1bmN0aW9uKHBsdWdpbnMpe1xyXG4gICAgIHZhciBpc0pRID0gcGx1Z2lucyBpbnN0YW5jZW9mICQ7XHJcbiAgICAgdHJ5e1xyXG4gICAgICAgaWYoaXNKUSl7XHJcbiAgICAgICAgIHBsdWdpbnMuZWFjaChmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICQodGhpcykuZGF0YSgnemZQbHVnaW4nKS5faW5pdCgpO1xyXG4gICAgICAgICB9KTtcclxuICAgICAgIH1lbHNle1xyXG4gICAgICAgICB2YXIgdHlwZSA9IHR5cGVvZiBwbHVnaW5zLFxyXG4gICAgICAgICBfdGhpcyA9IHRoaXMsXHJcbiAgICAgICAgIGZucyA9IHtcclxuICAgICAgICAgICAnb2JqZWN0JzogZnVuY3Rpb24ocGxncyl7XHJcbiAgICAgICAgICAgICBwbGdzLmZvckVhY2goZnVuY3Rpb24ocCl7XHJcbiAgICAgICAgICAgICAgIHAgPSBoeXBoZW5hdGUocCk7XHJcbiAgICAgICAgICAgICAgICQoJ1tkYXRhLScrIHAgKyddJykuZm91bmRhdGlvbignX2luaXQnKTtcclxuICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgJ3N0cmluZyc6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICBwbHVnaW5zID0gaHlwaGVuYXRlKHBsdWdpbnMpO1xyXG4gICAgICAgICAgICAgJCgnW2RhdGEtJysgcGx1Z2lucyArJ10nKS5mb3VuZGF0aW9uKCdfaW5pdCcpO1xyXG4gICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgJ3VuZGVmaW5lZCc6IGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICB0aGlzWydvYmplY3QnXShPYmplY3Qua2V5cyhfdGhpcy5fcGx1Z2lucykpO1xyXG4gICAgICAgICAgIH1cclxuICAgICAgICAgfTtcclxuICAgICAgICAgZm5zW3R5cGVdKHBsdWdpbnMpO1xyXG4gICAgICAgfVxyXG4gICAgIH1jYXRjaChlcnIpe1xyXG4gICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xyXG4gICAgIH1maW5hbGx5e1xyXG4gICAgICAgcmV0dXJuIHBsdWdpbnM7XHJcbiAgICAgfVxyXG4gICB9LFxyXG5cclxuICAvKipcclxuICAgKiByZXR1cm5zIGEgcmFuZG9tIGJhc2UtMzYgdWlkIHdpdGggbmFtZXNwYWNpbmdcclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcGFyYW0ge051bWJlcn0gbGVuZ3RoIC0gbnVtYmVyIG9mIHJhbmRvbSBiYXNlLTM2IGRpZ2l0cyBkZXNpcmVkLiBJbmNyZWFzZSBmb3IgbW9yZSByYW5kb20gc3RyaW5ncy5cclxuICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlIC0gbmFtZSBvZiBwbHVnaW4gdG8gYmUgaW5jb3Jwb3JhdGVkIGluIHVpZCwgb3B0aW9uYWwuXHJcbiAgICogQGRlZmF1bHQge1N0cmluZ30gJycgLSBpZiBubyBwbHVnaW4gbmFtZSBpcyBwcm92aWRlZCwgbm90aGluZyBpcyBhcHBlbmRlZCB0byB0aGUgdWlkLlxyXG4gICAqIEByZXR1cm5zIHtTdHJpbmd9IC0gdW5pcXVlIGlkXHJcbiAgICovXHJcbiAgR2V0WW9EaWdpdHM6IGZ1bmN0aW9uKGxlbmd0aCwgbmFtZXNwYWNlKXtcclxuICAgIGxlbmd0aCA9IGxlbmd0aCB8fCA2O1xyXG4gICAgcmV0dXJuIE1hdGgucm91bmQoKE1hdGgucG93KDM2LCBsZW5ndGggKyAxKSAtIE1hdGgucmFuZG9tKCkgKiBNYXRoLnBvdygzNiwgbGVuZ3RoKSkpLnRvU3RyaW5nKDM2KS5zbGljZSgxKSArIChuYW1lc3BhY2UgPyBgLSR7bmFtZXNwYWNlfWAgOiAnJyk7XHJcbiAgfSxcclxuICAvKipcclxuICAgKiBJbml0aWFsaXplIHBsdWdpbnMgb24gYW55IGVsZW1lbnRzIHdpdGhpbiBgZWxlbWAgKGFuZCBgZWxlbWAgaXRzZWxmKSB0aGF0IGFyZW4ndCBhbHJlYWR5IGluaXRpYWxpemVkLlxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbGVtIC0galF1ZXJ5IG9iamVjdCBjb250YWluaW5nIHRoZSBlbGVtZW50IHRvIGNoZWNrIGluc2lkZS4gQWxzbyBjaGVja3MgdGhlIGVsZW1lbnQgaXRzZWxmLCB1bmxlc3MgaXQncyB0aGUgYGRvY3VtZW50YCBvYmplY3QuXHJcbiAgICogQHBhcmFtIHtTdHJpbmd8QXJyYXl9IHBsdWdpbnMgLSBBIGxpc3Qgb2YgcGx1Z2lucyB0byBpbml0aWFsaXplLiBMZWF2ZSB0aGlzIG91dCB0byBpbml0aWFsaXplIGV2ZXJ5dGhpbmcuXHJcbiAgICovXHJcbiAgcmVmbG93OiBmdW5jdGlvbihlbGVtLCBwbHVnaW5zKSB7XHJcblxyXG4gICAgLy8gSWYgcGx1Z2lucyBpcyB1bmRlZmluZWQsIGp1c3QgZ3JhYiBldmVyeXRoaW5nXHJcbiAgICBpZiAodHlwZW9mIHBsdWdpbnMgPT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgIHBsdWdpbnMgPSBPYmplY3Qua2V5cyh0aGlzLl9wbHVnaW5zKTtcclxuICAgIH1cclxuICAgIC8vIElmIHBsdWdpbnMgaXMgYSBzdHJpbmcsIGNvbnZlcnQgaXQgdG8gYW4gYXJyYXkgd2l0aCBvbmUgaXRlbVxyXG4gICAgZWxzZSBpZiAodHlwZW9mIHBsdWdpbnMgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgIHBsdWdpbnMgPSBbcGx1Z2luc107XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuXHJcbiAgICAvLyBJdGVyYXRlIHRocm91Z2ggZWFjaCBwbHVnaW5cclxuICAgICQuZWFjaChwbHVnaW5zLCBmdW5jdGlvbihpLCBuYW1lKSB7XHJcbiAgICAgIC8vIEdldCB0aGUgY3VycmVudCBwbHVnaW5cclxuICAgICAgdmFyIHBsdWdpbiA9IF90aGlzLl9wbHVnaW5zW25hbWVdO1xyXG5cclxuICAgICAgLy8gTG9jYWxpemUgdGhlIHNlYXJjaCB0byBhbGwgZWxlbWVudHMgaW5zaWRlIGVsZW0sIGFzIHdlbGwgYXMgZWxlbSBpdHNlbGYsIHVubGVzcyBlbGVtID09PSBkb2N1bWVudFxyXG4gICAgICB2YXIgJGVsZW0gPSAkKGVsZW0pLmZpbmQoJ1tkYXRhLScrbmFtZSsnXScpLmFkZEJhY2soJ1tkYXRhLScrbmFtZSsnXScpO1xyXG5cclxuICAgICAgLy8gRm9yIGVhY2ggcGx1Z2luIGZvdW5kLCBpbml0aWFsaXplIGl0XHJcbiAgICAgICRlbGVtLmVhY2goZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgdmFyICRlbCA9ICQodGhpcyksXHJcbiAgICAgICAgICAgIG9wdHMgPSB7fTtcclxuICAgICAgICAvLyBEb24ndCBkb3VibGUtZGlwIG9uIHBsdWdpbnNcclxuICAgICAgICBpZiAoJGVsLmRhdGEoJ3pmUGx1Z2luJykpIHtcclxuICAgICAgICAgIGNvbnNvbGUud2FybihcIlRyaWVkIHRvIGluaXRpYWxpemUgXCIrbmFtZStcIiBvbiBhbiBlbGVtZW50IHRoYXQgYWxyZWFkeSBoYXMgYSBGb3VuZGF0aW9uIHBsdWdpbi5cIik7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZigkZWwuYXR0cignZGF0YS1vcHRpb25zJykpe1xyXG4gICAgICAgICAgdmFyIHRoaW5nID0gJGVsLmF0dHIoJ2RhdGEtb3B0aW9ucycpLnNwbGl0KCc7JykuZm9yRWFjaChmdW5jdGlvbihlLCBpKXtcclxuICAgICAgICAgICAgdmFyIG9wdCA9IGUuc3BsaXQoJzonKS5tYXAoZnVuY3Rpb24oZWwpeyByZXR1cm4gZWwudHJpbSgpOyB9KTtcclxuICAgICAgICAgICAgaWYob3B0WzBdKSBvcHRzW29wdFswXV0gPSBwYXJzZVZhbHVlKG9wdFsxXSk7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdHJ5e1xyXG4gICAgICAgICAgJGVsLmRhdGEoJ3pmUGx1Z2luJywgbmV3IHBsdWdpbigkKHRoaXMpLCBvcHRzKSk7XHJcbiAgICAgICAgfWNhdGNoKGVyKXtcclxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXIpO1xyXG4gICAgICAgIH1maW5hbGx5e1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9LFxyXG4gIGdldEZuTmFtZTogZnVuY3Rpb25OYW1lLFxyXG4gIHRyYW5zaXRpb25lbmQ6IGZ1bmN0aW9uKCRlbGVtKXtcclxuICAgIHZhciB0cmFuc2l0aW9ucyA9IHtcclxuICAgICAgJ3RyYW5zaXRpb24nOiAndHJhbnNpdGlvbmVuZCcsXHJcbiAgICAgICdXZWJraXRUcmFuc2l0aW9uJzogJ3dlYmtpdFRyYW5zaXRpb25FbmQnLFxyXG4gICAgICAnTW96VHJhbnNpdGlvbic6ICd0cmFuc2l0aW9uZW5kJyxcclxuICAgICAgJ09UcmFuc2l0aW9uJzogJ290cmFuc2l0aW9uZW5kJ1xyXG4gICAgfTtcclxuICAgIHZhciBlbGVtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JyksXHJcbiAgICAgICAgZW5kO1xyXG5cclxuICAgIGZvciAodmFyIHQgaW4gdHJhbnNpdGlvbnMpe1xyXG4gICAgICBpZiAodHlwZW9mIGVsZW0uc3R5bGVbdF0gIT09ICd1bmRlZmluZWQnKXtcclxuICAgICAgICBlbmQgPSB0cmFuc2l0aW9uc1t0XTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYoZW5kKXtcclxuICAgICAgcmV0dXJuIGVuZDtcclxuICAgIH1lbHNle1xyXG4gICAgICBlbmQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgJGVsZW0udHJpZ2dlckhhbmRsZXIoJ3RyYW5zaXRpb25lbmQnLCBbJGVsZW1dKTtcclxuICAgICAgfSwgMSk7XHJcbiAgICAgIHJldHVybiAndHJhbnNpdGlvbmVuZCc7XHJcbiAgICB9XHJcbiAgfVxyXG59O1xyXG5cclxuRm91bmRhdGlvbi51dGlsID0ge1xyXG4gIC8qKlxyXG4gICAqIEZ1bmN0aW9uIGZvciBhcHBseWluZyBhIGRlYm91bmNlIGVmZmVjdCB0byBhIGZ1bmN0aW9uIGNhbGwuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuYyAtIEZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBhdCBlbmQgb2YgdGltZW91dC5cclxuICAgKiBAcGFyYW0ge051bWJlcn0gZGVsYXkgLSBUaW1lIGluIG1zIHRvIGRlbGF5IHRoZSBjYWxsIG9mIGBmdW5jYC5cclxuICAgKiBAcmV0dXJucyBmdW5jdGlvblxyXG4gICAqL1xyXG4gIHRocm90dGxlOiBmdW5jdGlvbiAoZnVuYywgZGVsYXkpIHtcclxuICAgIHZhciB0aW1lciA9IG51bGw7XHJcblxyXG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIGNvbnRleHQgPSB0aGlzLCBhcmdzID0gYXJndW1lbnRzO1xyXG5cclxuICAgICAgaWYgKHRpbWVyID09PSBudWxsKSB7XHJcbiAgICAgICAgdGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XHJcbiAgICAgICAgICB0aW1lciA9IG51bGw7XHJcbiAgICAgICAgfSwgZGVsYXkpO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG4gIH1cclxufTtcclxuXHJcbi8vIFRPRE86IGNvbnNpZGVyIG5vdCBtYWtpbmcgdGhpcyBhIGpRdWVyeSBmdW5jdGlvblxyXG4vLyBUT0RPOiBuZWVkIHdheSB0byByZWZsb3cgdnMuIHJlLWluaXRpYWxpemVcclxuLyoqXHJcbiAqIFRoZSBGb3VuZGF0aW9uIGpRdWVyeSBtZXRob2QuXHJcbiAqIEBwYXJhbSB7U3RyaW5nfEFycmF5fSBtZXRob2QgLSBBbiBhY3Rpb24gdG8gcGVyZm9ybSBvbiB0aGUgY3VycmVudCBqUXVlcnkgb2JqZWN0LlxyXG4gKi9cclxudmFyIGZvdW5kYXRpb24gPSBmdW5jdGlvbihtZXRob2QpIHtcclxuICB2YXIgdHlwZSA9IHR5cGVvZiBtZXRob2QsXHJcbiAgICAgICRtZXRhID0gJCgnbWV0YS5mb3VuZGF0aW9uLW1xJyksXHJcbiAgICAgICRub0pTID0gJCgnLm5vLWpzJyk7XHJcblxyXG4gIGlmKCEkbWV0YS5sZW5ndGgpe1xyXG4gICAgJCgnPG1ldGEgY2xhc3M9XCJmb3VuZGF0aW9uLW1xXCI+JykuYXBwZW5kVG8oZG9jdW1lbnQuaGVhZCk7XHJcbiAgfVxyXG4gIGlmKCRub0pTLmxlbmd0aCl7XHJcbiAgICAkbm9KUy5yZW1vdmVDbGFzcygnbm8tanMnKTtcclxuICB9XHJcblxyXG4gIGlmKHR5cGUgPT09ICd1bmRlZmluZWQnKXsvL25lZWRzIHRvIGluaXRpYWxpemUgdGhlIEZvdW5kYXRpb24gb2JqZWN0LCBvciBhbiBpbmRpdmlkdWFsIHBsdWdpbi5cclxuICAgIEZvdW5kYXRpb24uTWVkaWFRdWVyeS5faW5pdCgpO1xyXG4gICAgRm91bmRhdGlvbi5yZWZsb3codGhpcyk7XHJcbiAgfWVsc2UgaWYodHlwZSA9PT0gJ3N0cmluZycpey8vYW4gaW5kaXZpZHVhbCBtZXRob2QgdG8gaW52b2tlIG9uIGEgcGx1Z2luIG9yIGdyb3VwIG9mIHBsdWdpbnNcclxuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTsvL2NvbGxlY3QgYWxsIHRoZSBhcmd1bWVudHMsIGlmIG5lY2Vzc2FyeVxyXG4gICAgdmFyIHBsdWdDbGFzcyA9IHRoaXMuZGF0YSgnemZQbHVnaW4nKTsvL2RldGVybWluZSB0aGUgY2xhc3Mgb2YgcGx1Z2luXHJcblxyXG4gICAgaWYocGx1Z0NsYXNzICE9PSB1bmRlZmluZWQgJiYgcGx1Z0NsYXNzW21ldGhvZF0gIT09IHVuZGVmaW5lZCl7Ly9tYWtlIHN1cmUgYm90aCB0aGUgY2xhc3MgYW5kIG1ldGhvZCBleGlzdFxyXG4gICAgICBpZih0aGlzLmxlbmd0aCA9PT0gMSl7Ly9pZiB0aGVyZSdzIG9ubHkgb25lLCBjYWxsIGl0IGRpcmVjdGx5LlxyXG4gICAgICAgICAgcGx1Z0NsYXNzW21ldGhvZF0uYXBwbHkocGx1Z0NsYXNzLCBhcmdzKTtcclxuICAgICAgfWVsc2V7XHJcbiAgICAgICAgdGhpcy5lYWNoKGZ1bmN0aW9uKGksIGVsKXsvL290aGVyd2lzZSBsb29wIHRocm91Z2ggdGhlIGpRdWVyeSBjb2xsZWN0aW9uIGFuZCBpbnZva2UgdGhlIG1ldGhvZCBvbiBlYWNoXHJcbiAgICAgICAgICBwbHVnQ2xhc3NbbWV0aG9kXS5hcHBseSgkKGVsKS5kYXRhKCd6ZlBsdWdpbicpLCBhcmdzKTtcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfWVsc2V7Ly9lcnJvciBmb3Igbm8gY2xhc3Mgb3Igbm8gbWV0aG9kXHJcbiAgICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihcIldlJ3JlIHNvcnJ5LCAnXCIgKyBtZXRob2QgKyBcIicgaXMgbm90IGFuIGF2YWlsYWJsZSBtZXRob2QgZm9yIFwiICsgKHBsdWdDbGFzcyA/IGZ1bmN0aW9uTmFtZShwbHVnQ2xhc3MpIDogJ3RoaXMgZWxlbWVudCcpICsgJy4nKTtcclxuICAgIH1cclxuICB9ZWxzZXsvL2Vycm9yIGZvciBpbnZhbGlkIGFyZ3VtZW50IHR5cGVcclxuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFdlJ3JlIHNvcnJ5LCAke3R5cGV9IGlzIG5vdCBhIHZhbGlkIHBhcmFtZXRlci4gWW91IG11c3QgdXNlIGEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgbWV0aG9kIHlvdSB3aXNoIHRvIGludm9rZS5gKTtcclxuICB9XHJcbiAgcmV0dXJuIHRoaXM7XHJcbn07XHJcblxyXG53aW5kb3cuRm91bmRhdGlvbiA9IEZvdW5kYXRpb247XHJcbiQuZm4uZm91bmRhdGlvbiA9IGZvdW5kYXRpb247XHJcblxyXG4vLyBQb2x5ZmlsbCBmb3IgcmVxdWVzdEFuaW1hdGlvbkZyYW1lXHJcbihmdW5jdGlvbigpIHtcclxuICBpZiAoIURhdGUubm93IHx8ICF3aW5kb3cuRGF0ZS5ub3cpXHJcbiAgICB3aW5kb3cuRGF0ZS5ub3cgPSBEYXRlLm5vdyA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gbmV3IERhdGUoKS5nZXRUaW1lKCk7IH07XHJcblxyXG4gIHZhciB2ZW5kb3JzID0gWyd3ZWJraXQnLCAnbW96J107XHJcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCB2ZW5kb3JzLmxlbmd0aCAmJiAhd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZTsgKytpKSB7XHJcbiAgICAgIHZhciB2cCA9IHZlbmRvcnNbaV07XHJcbiAgICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPSB3aW5kb3dbdnArJ1JlcXVlc3RBbmltYXRpb25GcmFtZSddO1xyXG4gICAgICB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUgPSAod2luZG93W3ZwKydDYW5jZWxBbmltYXRpb25GcmFtZSddXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHx8IHdpbmRvd1t2cCsnQ2FuY2VsUmVxdWVzdEFuaW1hdGlvbkZyYW1lJ10pO1xyXG4gIH1cclxuICBpZiAoL2lQKGFkfGhvbmV8b2QpLipPUyA2Ly50ZXN0KHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50KVxyXG4gICAgfHwgIXdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHwgIXdpbmRvdy5jYW5jZWxBbmltYXRpb25GcmFtZSkge1xyXG4gICAgdmFyIGxhc3RUaW1lID0gMDtcclxuICAgIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPSBmdW5jdGlvbihjYWxsYmFjaykge1xyXG4gICAgICAgIHZhciBub3cgPSBEYXRlLm5vdygpO1xyXG4gICAgICAgIHZhciBuZXh0VGltZSA9IE1hdGgubWF4KGxhc3RUaW1lICsgMTYsIG5vdyk7XHJcbiAgICAgICAgcmV0dXJuIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7IGNhbGxiYWNrKGxhc3RUaW1lID0gbmV4dFRpbWUpOyB9LFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIG5leHRUaW1lIC0gbm93KTtcclxuICAgIH07XHJcbiAgICB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUgPSBjbGVhclRpbWVvdXQ7XHJcbiAgfVxyXG4gIC8qKlxyXG4gICAqIFBvbHlmaWxsIGZvciBwZXJmb3JtYW5jZS5ub3csIHJlcXVpcmVkIGJ5IHJBRlxyXG4gICAqL1xyXG4gIGlmKCF3aW5kb3cucGVyZm9ybWFuY2UgfHwgIXdpbmRvdy5wZXJmb3JtYW5jZS5ub3cpe1xyXG4gICAgd2luZG93LnBlcmZvcm1hbmNlID0ge1xyXG4gICAgICBzdGFydDogRGF0ZS5ub3coKSxcclxuICAgICAgbm93OiBmdW5jdGlvbigpeyByZXR1cm4gRGF0ZS5ub3coKSAtIHRoaXMuc3RhcnQ7IH1cclxuICAgIH07XHJcbiAgfVxyXG59KSgpO1xyXG5pZiAoIUZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kKSB7XHJcbiAgRnVuY3Rpb24ucHJvdG90eXBlLmJpbmQgPSBmdW5jdGlvbihvVGhpcykge1xyXG4gICAgaWYgKHR5cGVvZiB0aGlzICE9PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIC8vIGNsb3Nlc3QgdGhpbmcgcG9zc2libGUgdG8gdGhlIEVDTUFTY3JpcHQgNVxyXG4gICAgICAvLyBpbnRlcm5hbCBJc0NhbGxhYmxlIGZ1bmN0aW9uXHJcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Z1bmN0aW9uLnByb3RvdHlwZS5iaW5kIC0gd2hhdCBpcyB0cnlpbmcgdG8gYmUgYm91bmQgaXMgbm90IGNhbGxhYmxlJyk7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGFBcmdzICAgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpLFxyXG4gICAgICAgIGZUb0JpbmQgPSB0aGlzLFxyXG4gICAgICAgIGZOT1AgICAgPSBmdW5jdGlvbigpIHt9LFxyXG4gICAgICAgIGZCb3VuZCAgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICAgIHJldHVybiBmVG9CaW5kLmFwcGx5KHRoaXMgaW5zdGFuY2VvZiBmTk9QXHJcbiAgICAgICAgICAgICAgICAgPyB0aGlzXHJcbiAgICAgICAgICAgICAgICAgOiBvVGhpcyxcclxuICAgICAgICAgICAgICAgICBhQXJncy5jb25jYXQoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgaWYgKHRoaXMucHJvdG90eXBlKSB7XHJcbiAgICAgIC8vIG5hdGl2ZSBmdW5jdGlvbnMgZG9uJ3QgaGF2ZSBhIHByb3RvdHlwZVxyXG4gICAgICBmTk9QLnByb3RvdHlwZSA9IHRoaXMucHJvdG90eXBlO1xyXG4gICAgfVxyXG4gICAgZkJvdW5kLnByb3RvdHlwZSA9IG5ldyBmTk9QKCk7XHJcblxyXG4gICAgcmV0dXJuIGZCb3VuZDtcclxuICB9O1xyXG59XHJcbi8vIFBvbHlmaWxsIHRvIGdldCB0aGUgbmFtZSBvZiBhIGZ1bmN0aW9uIGluIElFOVxyXG5mdW5jdGlvbiBmdW5jdGlvbk5hbWUoZm4pIHtcclxuICBpZiAoRnVuY3Rpb24ucHJvdG90eXBlLm5hbWUgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgdmFyIGZ1bmNOYW1lUmVnZXggPSAvZnVuY3Rpb25cXHMoW14oXXsxLH0pXFwoLztcclxuICAgIHZhciByZXN1bHRzID0gKGZ1bmNOYW1lUmVnZXgpLmV4ZWMoKGZuKS50b1N0cmluZygpKTtcclxuICAgIHJldHVybiAocmVzdWx0cyAmJiByZXN1bHRzLmxlbmd0aCA+IDEpID8gcmVzdWx0c1sxXS50cmltKCkgOiBcIlwiO1xyXG4gIH1cclxuICBlbHNlIGlmIChmbi5wcm90b3R5cGUgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgcmV0dXJuIGZuLmNvbnN0cnVjdG9yLm5hbWU7XHJcbiAgfVxyXG4gIGVsc2Uge1xyXG4gICAgcmV0dXJuIGZuLnByb3RvdHlwZS5jb25zdHJ1Y3Rvci5uYW1lO1xyXG4gIH1cclxufVxyXG5mdW5jdGlvbiBwYXJzZVZhbHVlKHN0cil7XHJcbiAgaWYoL3RydWUvLnRlc3Qoc3RyKSkgcmV0dXJuIHRydWU7XHJcbiAgZWxzZSBpZigvZmFsc2UvLnRlc3Qoc3RyKSkgcmV0dXJuIGZhbHNlO1xyXG4gIGVsc2UgaWYoIWlzTmFOKHN0ciAqIDEpKSByZXR1cm4gcGFyc2VGbG9hdChzdHIpO1xyXG4gIHJldHVybiBzdHI7XHJcbn1cclxuLy8gQ29udmVydCBQYXNjYWxDYXNlIHRvIGtlYmFiLWNhc2VcclxuLy8gVGhhbmsgeW91OiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS84OTU1NTgwXHJcbmZ1bmN0aW9uIGh5cGhlbmF0ZShzdHIpIHtcclxuICByZXR1cm4gc3RyLnJlcGxhY2UoLyhbYS16XSkoW0EtWl0pL2csICckMS0kMicpLnRvTG93ZXJDYXNlKCk7XHJcbn1cclxuXHJcbn0oalF1ZXJ5KTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxuIWZ1bmN0aW9uKCQpIHtcclxuXHJcbkZvdW5kYXRpb24uQm94ID0ge1xyXG4gIEltTm90VG91Y2hpbmdZb3U6IEltTm90VG91Y2hpbmdZb3UsXHJcbiAgR2V0RGltZW5zaW9uczogR2V0RGltZW5zaW9ucyxcclxuICBHZXRPZmZzZXRzOiBHZXRPZmZzZXRzXHJcbn1cclxuXHJcbi8qKlxyXG4gKiBDb21wYXJlcyB0aGUgZGltZW5zaW9ucyBvZiBhbiBlbGVtZW50IHRvIGEgY29udGFpbmVyIGFuZCBkZXRlcm1pbmVzIGNvbGxpc2lvbiBldmVudHMgd2l0aCBjb250YWluZXIuXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge2pRdWVyeX0gZWxlbWVudCAtIGpRdWVyeSBvYmplY3QgdG8gdGVzdCBmb3IgY29sbGlzaW9ucy5cclxuICogQHBhcmFtIHtqUXVlcnl9IHBhcmVudCAtIGpRdWVyeSBvYmplY3QgdG8gdXNlIGFzIGJvdW5kaW5nIGNvbnRhaW5lci5cclxuICogQHBhcmFtIHtCb29sZWFufSBsck9ubHkgLSBzZXQgdG8gdHJ1ZSB0byBjaGVjayBsZWZ0IGFuZCByaWdodCB2YWx1ZXMgb25seS5cclxuICogQHBhcmFtIHtCb29sZWFufSB0Yk9ubHkgLSBzZXQgdG8gdHJ1ZSB0byBjaGVjayB0b3AgYW5kIGJvdHRvbSB2YWx1ZXMgb25seS5cclxuICogQGRlZmF1bHQgaWYgbm8gcGFyZW50IG9iamVjdCBwYXNzZWQsIGRldGVjdHMgY29sbGlzaW9ucyB3aXRoIGB3aW5kb3dgLlxyXG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gLSB0cnVlIGlmIGNvbGxpc2lvbiBmcmVlLCBmYWxzZSBpZiBhIGNvbGxpc2lvbiBpbiBhbnkgZGlyZWN0aW9uLlxyXG4gKi9cclxuZnVuY3Rpb24gSW1Ob3RUb3VjaGluZ1lvdShlbGVtZW50LCBwYXJlbnQsIGxyT25seSwgdGJPbmx5KSB7XHJcbiAgdmFyIGVsZURpbXMgPSBHZXREaW1lbnNpb25zKGVsZW1lbnQpLFxyXG4gICAgICB0b3AsIGJvdHRvbSwgbGVmdCwgcmlnaHQ7XHJcblxyXG4gIGlmIChwYXJlbnQpIHtcclxuICAgIHZhciBwYXJEaW1zID0gR2V0RGltZW5zaW9ucyhwYXJlbnQpO1xyXG5cclxuICAgIGJvdHRvbSA9IChlbGVEaW1zLm9mZnNldC50b3AgKyBlbGVEaW1zLmhlaWdodCA8PSBwYXJEaW1zLmhlaWdodCArIHBhckRpbXMub2Zmc2V0LnRvcCk7XHJcbiAgICB0b3AgICAgPSAoZWxlRGltcy5vZmZzZXQudG9wID49IHBhckRpbXMub2Zmc2V0LnRvcCk7XHJcbiAgICBsZWZ0ICAgPSAoZWxlRGltcy5vZmZzZXQubGVmdCA+PSBwYXJEaW1zLm9mZnNldC5sZWZ0KTtcclxuICAgIHJpZ2h0ICA9IChlbGVEaW1zLm9mZnNldC5sZWZ0ICsgZWxlRGltcy53aWR0aCA8PSBwYXJEaW1zLndpZHRoICsgcGFyRGltcy5vZmZzZXQubGVmdCk7XHJcbiAgfVxyXG4gIGVsc2Uge1xyXG4gICAgYm90dG9tID0gKGVsZURpbXMub2Zmc2V0LnRvcCArIGVsZURpbXMuaGVpZ2h0IDw9IGVsZURpbXMud2luZG93RGltcy5oZWlnaHQgKyBlbGVEaW1zLndpbmRvd0RpbXMub2Zmc2V0LnRvcCk7XHJcbiAgICB0b3AgICAgPSAoZWxlRGltcy5vZmZzZXQudG9wID49IGVsZURpbXMud2luZG93RGltcy5vZmZzZXQudG9wKTtcclxuICAgIGxlZnQgICA9IChlbGVEaW1zLm9mZnNldC5sZWZ0ID49IGVsZURpbXMud2luZG93RGltcy5vZmZzZXQubGVmdCk7XHJcbiAgICByaWdodCAgPSAoZWxlRGltcy5vZmZzZXQubGVmdCArIGVsZURpbXMud2lkdGggPD0gZWxlRGltcy53aW5kb3dEaW1zLndpZHRoKTtcclxuICB9XHJcblxyXG4gIHZhciBhbGxEaXJzID0gW2JvdHRvbSwgdG9wLCBsZWZ0LCByaWdodF07XHJcblxyXG4gIGlmIChsck9ubHkpIHtcclxuICAgIHJldHVybiBsZWZ0ID09PSByaWdodCA9PT0gdHJ1ZTtcclxuICB9XHJcblxyXG4gIGlmICh0Yk9ubHkpIHtcclxuICAgIHJldHVybiB0b3AgPT09IGJvdHRvbSA9PT0gdHJ1ZTtcclxuICB9XHJcblxyXG4gIHJldHVybiBhbGxEaXJzLmluZGV4T2YoZmFsc2UpID09PSAtMTtcclxufTtcclxuXHJcbi8qKlxyXG4gKiBVc2VzIG5hdGl2ZSBtZXRob2RzIHRvIHJldHVybiBhbiBvYmplY3Qgb2YgZGltZW5zaW9uIHZhbHVlcy5cclxuICogQGZ1bmN0aW9uXHJcbiAqIEBwYXJhbSB7alF1ZXJ5IHx8IEhUTUx9IGVsZW1lbnQgLSBqUXVlcnkgb2JqZWN0IG9yIERPTSBlbGVtZW50IGZvciB3aGljaCB0byBnZXQgdGhlIGRpbWVuc2lvbnMuIENhbiBiZSBhbnkgZWxlbWVudCBvdGhlciB0aGF0IGRvY3VtZW50IG9yIHdpbmRvdy5cclxuICogQHJldHVybnMge09iamVjdH0gLSBuZXN0ZWQgb2JqZWN0IG9mIGludGVnZXIgcGl4ZWwgdmFsdWVzXHJcbiAqIFRPRE8gLSBpZiBlbGVtZW50IGlzIHdpbmRvdywgcmV0dXJuIG9ubHkgdGhvc2UgdmFsdWVzLlxyXG4gKi9cclxuZnVuY3Rpb24gR2V0RGltZW5zaW9ucyhlbGVtLCB0ZXN0KXtcclxuICBlbGVtID0gZWxlbS5sZW5ndGggPyBlbGVtWzBdIDogZWxlbTtcclxuXHJcbiAgaWYgKGVsZW0gPT09IHdpbmRvdyB8fCBlbGVtID09PSBkb2N1bWVudCkge1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKFwiSSdtIHNvcnJ5LCBEYXZlLiBJJ20gYWZyYWlkIEkgY2FuJ3QgZG8gdGhhdC5cIik7XHJcbiAgfVxyXG5cclxuICB2YXIgcmVjdCA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksXHJcbiAgICAgIHBhclJlY3QgPSBlbGVtLnBhcmVudE5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksXHJcbiAgICAgIHdpblJlY3QgPSBkb2N1bWVudC5ib2R5LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLFxyXG4gICAgICB3aW5ZID0gd2luZG93LnBhZ2VZT2Zmc2V0LFxyXG4gICAgICB3aW5YID0gd2luZG93LnBhZ2VYT2Zmc2V0O1xyXG5cclxuICByZXR1cm4ge1xyXG4gICAgd2lkdGg6IHJlY3Qud2lkdGgsXHJcbiAgICBoZWlnaHQ6IHJlY3QuaGVpZ2h0LFxyXG4gICAgb2Zmc2V0OiB7XHJcbiAgICAgIHRvcDogcmVjdC50b3AgKyB3aW5ZLFxyXG4gICAgICBsZWZ0OiByZWN0LmxlZnQgKyB3aW5YXHJcbiAgICB9LFxyXG4gICAgcGFyZW50RGltczoge1xyXG4gICAgICB3aWR0aDogcGFyUmVjdC53aWR0aCxcclxuICAgICAgaGVpZ2h0OiBwYXJSZWN0LmhlaWdodCxcclxuICAgICAgb2Zmc2V0OiB7XHJcbiAgICAgICAgdG9wOiBwYXJSZWN0LnRvcCArIHdpblksXHJcbiAgICAgICAgbGVmdDogcGFyUmVjdC5sZWZ0ICsgd2luWFxyXG4gICAgICB9XHJcbiAgICB9LFxyXG4gICAgd2luZG93RGltczoge1xyXG4gICAgICB3aWR0aDogd2luUmVjdC53aWR0aCxcclxuICAgICAgaGVpZ2h0OiB3aW5SZWN0LmhlaWdodCxcclxuICAgICAgb2Zmc2V0OiB7XHJcbiAgICAgICAgdG9wOiB3aW5ZLFxyXG4gICAgICAgIGxlZnQ6IHdpblhcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFJldHVybnMgYW4gb2JqZWN0IG9mIHRvcCBhbmQgbGVmdCBpbnRlZ2VyIHBpeGVsIHZhbHVlcyBmb3IgZHluYW1pY2FsbHkgcmVuZGVyZWQgZWxlbWVudHMsXHJcbiAqIHN1Y2ggYXM6IFRvb2x0aXAsIFJldmVhbCwgYW5kIERyb3Bkb3duXHJcbiAqIEBmdW5jdGlvblxyXG4gKiBAcGFyYW0ge2pRdWVyeX0gZWxlbWVudCAtIGpRdWVyeSBvYmplY3QgZm9yIHRoZSBlbGVtZW50IGJlaW5nIHBvc2l0aW9uZWQuXHJcbiAqIEBwYXJhbSB7alF1ZXJ5fSBhbmNob3IgLSBqUXVlcnkgb2JqZWN0IGZvciB0aGUgZWxlbWVudCdzIGFuY2hvciBwb2ludC5cclxuICogQHBhcmFtIHtTdHJpbmd9IHBvc2l0aW9uIC0gYSBzdHJpbmcgcmVsYXRpbmcgdG8gdGhlIGRlc2lyZWQgcG9zaXRpb24gb2YgdGhlIGVsZW1lbnQsIHJlbGF0aXZlIHRvIGl0J3MgYW5jaG9yXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSB2T2Zmc2V0IC0gaW50ZWdlciBwaXhlbCB2YWx1ZSBvZiBkZXNpcmVkIHZlcnRpY2FsIHNlcGFyYXRpb24gYmV0d2VlbiBhbmNob3IgYW5kIGVsZW1lbnQuXHJcbiAqIEBwYXJhbSB7TnVtYmVyfSBoT2Zmc2V0IC0gaW50ZWdlciBwaXhlbCB2YWx1ZSBvZiBkZXNpcmVkIGhvcml6b250YWwgc2VwYXJhdGlvbiBiZXR3ZWVuIGFuY2hvciBhbmQgZWxlbWVudC5cclxuICogQHBhcmFtIHtCb29sZWFufSBpc092ZXJmbG93IC0gaWYgYSBjb2xsaXNpb24gZXZlbnQgaXMgZGV0ZWN0ZWQsIHNldHMgdG8gdHJ1ZSB0byBkZWZhdWx0IHRoZSBlbGVtZW50IHRvIGZ1bGwgd2lkdGggLSBhbnkgZGVzaXJlZCBvZmZzZXQuXHJcbiAqIFRPRE8gYWx0ZXIvcmV3cml0ZSB0byB3b3JrIHdpdGggYGVtYCB2YWx1ZXMgYXMgd2VsbC9pbnN0ZWFkIG9mIHBpeGVsc1xyXG4gKi9cclxuZnVuY3Rpb24gR2V0T2Zmc2V0cyhlbGVtZW50LCBhbmNob3IsIHBvc2l0aW9uLCB2T2Zmc2V0LCBoT2Zmc2V0LCBpc092ZXJmbG93KSB7XHJcbiAgdmFyICRlbGVEaW1zID0gR2V0RGltZW5zaW9ucyhlbGVtZW50KSxcclxuICAgICAgJGFuY2hvckRpbXMgPSBhbmNob3IgPyBHZXREaW1lbnNpb25zKGFuY2hvcikgOiBudWxsO1xyXG5cclxuICBzd2l0Y2ggKHBvc2l0aW9uKSB7XHJcbiAgICBjYXNlICd0b3AnOlxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGxlZnQ6IChGb3VuZGF0aW9uLnJ0bCgpID8gJGFuY2hvckRpbXMub2Zmc2V0LmxlZnQgLSAkZWxlRGltcy53aWR0aCArICRhbmNob3JEaW1zLndpZHRoIDogJGFuY2hvckRpbXMub2Zmc2V0LmxlZnQpLFxyXG4gICAgICAgIHRvcDogJGFuY2hvckRpbXMub2Zmc2V0LnRvcCAtICgkZWxlRGltcy5oZWlnaHQgKyB2T2Zmc2V0KVxyXG4gICAgICB9XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgY2FzZSAnbGVmdCc6XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgbGVmdDogJGFuY2hvckRpbXMub2Zmc2V0LmxlZnQgLSAoJGVsZURpbXMud2lkdGggKyBoT2Zmc2V0KSxcclxuICAgICAgICB0b3A6ICRhbmNob3JEaW1zLm9mZnNldC50b3BcclxuICAgICAgfVxyXG4gICAgICBicmVhaztcclxuICAgIGNhc2UgJ3JpZ2h0JzpcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBsZWZ0OiAkYW5jaG9yRGltcy5vZmZzZXQubGVmdCArICRhbmNob3JEaW1zLndpZHRoICsgaE9mZnNldCxcclxuICAgICAgICB0b3A6ICRhbmNob3JEaW1zLm9mZnNldC50b3BcclxuICAgICAgfVxyXG4gICAgICBicmVhaztcclxuICAgIGNhc2UgJ2NlbnRlciB0b3AnOlxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGxlZnQ6ICgkYW5jaG9yRGltcy5vZmZzZXQubGVmdCArICgkYW5jaG9yRGltcy53aWR0aCAvIDIpKSAtICgkZWxlRGltcy53aWR0aCAvIDIpLFxyXG4gICAgICAgIHRvcDogJGFuY2hvckRpbXMub2Zmc2V0LnRvcCAtICgkZWxlRGltcy5oZWlnaHQgKyB2T2Zmc2V0KVxyXG4gICAgICB9XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgY2FzZSAnY2VudGVyIGJvdHRvbSc6XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgbGVmdDogaXNPdmVyZmxvdyA/IGhPZmZzZXQgOiAoKCRhbmNob3JEaW1zLm9mZnNldC5sZWZ0ICsgKCRhbmNob3JEaW1zLndpZHRoIC8gMikpIC0gKCRlbGVEaW1zLndpZHRoIC8gMikpLFxyXG4gICAgICAgIHRvcDogJGFuY2hvckRpbXMub2Zmc2V0LnRvcCArICRhbmNob3JEaW1zLmhlaWdodCArIHZPZmZzZXRcclxuICAgICAgfVxyXG4gICAgICBicmVhaztcclxuICAgIGNhc2UgJ2NlbnRlciBsZWZ0JzpcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBsZWZ0OiAkYW5jaG9yRGltcy5vZmZzZXQubGVmdCAtICgkZWxlRGltcy53aWR0aCArIGhPZmZzZXQpLFxyXG4gICAgICAgIHRvcDogKCRhbmNob3JEaW1zLm9mZnNldC50b3AgKyAoJGFuY2hvckRpbXMuaGVpZ2h0IC8gMikpIC0gKCRlbGVEaW1zLmhlaWdodCAvIDIpXHJcbiAgICAgIH1cclxuICAgICAgYnJlYWs7XHJcbiAgICBjYXNlICdjZW50ZXIgcmlnaHQnOlxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGxlZnQ6ICRhbmNob3JEaW1zLm9mZnNldC5sZWZ0ICsgJGFuY2hvckRpbXMud2lkdGggKyBoT2Zmc2V0ICsgMSxcclxuICAgICAgICB0b3A6ICgkYW5jaG9yRGltcy5vZmZzZXQudG9wICsgKCRhbmNob3JEaW1zLmhlaWdodCAvIDIpKSAtICgkZWxlRGltcy5oZWlnaHQgLyAyKVxyXG4gICAgICB9XHJcbiAgICAgIGJyZWFrO1xyXG4gICAgY2FzZSAnY2VudGVyJzpcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBsZWZ0OiAoJGVsZURpbXMud2luZG93RGltcy5vZmZzZXQubGVmdCArICgkZWxlRGltcy53aW5kb3dEaW1zLndpZHRoIC8gMikpIC0gKCRlbGVEaW1zLndpZHRoIC8gMiksXHJcbiAgICAgICAgdG9wOiAoJGVsZURpbXMud2luZG93RGltcy5vZmZzZXQudG9wICsgKCRlbGVEaW1zLndpbmRvd0RpbXMuaGVpZ2h0IC8gMikpIC0gKCRlbGVEaW1zLmhlaWdodCAvIDIpXHJcbiAgICAgIH1cclxuICAgICAgYnJlYWs7XHJcbiAgICBjYXNlICdyZXZlYWwnOlxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGxlZnQ6ICgkZWxlRGltcy53aW5kb3dEaW1zLndpZHRoIC0gJGVsZURpbXMud2lkdGgpIC8gMixcclxuICAgICAgICB0b3A6ICRlbGVEaW1zLndpbmRvd0RpbXMub2Zmc2V0LnRvcCArIHZPZmZzZXRcclxuICAgICAgfVxyXG4gICAgY2FzZSAncmV2ZWFsIGZ1bGwnOlxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGxlZnQ6ICRlbGVEaW1zLndpbmRvd0RpbXMub2Zmc2V0LmxlZnQsXHJcbiAgICAgICAgdG9wOiAkZWxlRGltcy53aW5kb3dEaW1zLm9mZnNldC50b3BcclxuICAgICAgfVxyXG4gICAgICBicmVhaztcclxuICAgIGNhc2UgJ2xlZnQgYm90dG9tJzpcclxuICAgICAgcmV0dXJuIHtcclxuICAgICAgICBsZWZ0OiAkYW5jaG9yRGltcy5vZmZzZXQubGVmdCAtICgkZWxlRGltcy53aWR0aCArIGhPZmZzZXQpLFxyXG4gICAgICAgIHRvcDogJGFuY2hvckRpbXMub2Zmc2V0LnRvcCArICRhbmNob3JEaW1zLmhlaWdodFxyXG4gICAgICB9O1xyXG4gICAgICBicmVhaztcclxuICAgIGNhc2UgJ3JpZ2h0IGJvdHRvbSc6XHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgbGVmdDogJGFuY2hvckRpbXMub2Zmc2V0LmxlZnQgKyAkYW5jaG9yRGltcy53aWR0aCArIGhPZmZzZXQgLSAkZWxlRGltcy53aWR0aCxcclxuICAgICAgICB0b3A6ICRhbmNob3JEaW1zLm9mZnNldC50b3AgKyAkYW5jaG9yRGltcy5oZWlnaHRcclxuICAgICAgfTtcclxuICAgICAgYnJlYWs7XHJcbiAgICBkZWZhdWx0OlxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGxlZnQ6IChGb3VuZGF0aW9uLnJ0bCgpID8gJGFuY2hvckRpbXMub2Zmc2V0LmxlZnQgLSAkZWxlRGltcy53aWR0aCArICRhbmNob3JEaW1zLndpZHRoIDogJGFuY2hvckRpbXMub2Zmc2V0LmxlZnQpLFxyXG4gICAgICAgIHRvcDogJGFuY2hvckRpbXMub2Zmc2V0LnRvcCArICRhbmNob3JEaW1zLmhlaWdodCArIHZPZmZzZXRcclxuICAgICAgfVxyXG4gIH1cclxufVxyXG5cclxufShqUXVlcnkpO1xyXG4iLCIvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxyXG4gKiBUaGlzIHV0aWwgd2FzIGNyZWF0ZWQgYnkgTWFyaXVzIE9sYmVydHogKlxyXG4gKiBQbGVhc2UgdGhhbmsgTWFyaXVzIG9uIEdpdEh1YiAvb3dsYmVydHogKlxyXG4gKiBvciB0aGUgd2ViIGh0dHA6Ly93d3cubWFyaXVzb2xiZXJ0ei5kZS8gKlxyXG4gKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKlxyXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG5cclxuJ3VzZSBzdHJpY3QnO1xyXG5cclxuIWZ1bmN0aW9uKCQpIHtcclxuXHJcbmNvbnN0IGtleUNvZGVzID0ge1xyXG4gIDk6ICdUQUInLFxyXG4gIDEzOiAnRU5URVInLFxyXG4gIDI3OiAnRVNDQVBFJyxcclxuICAzMjogJ1NQQUNFJyxcclxuICAzNzogJ0FSUk9XX0xFRlQnLFxyXG4gIDM4OiAnQVJST1dfVVAnLFxyXG4gIDM5OiAnQVJST1dfUklHSFQnLFxyXG4gIDQwOiAnQVJST1dfRE9XTidcclxufVxyXG5cclxudmFyIGNvbW1hbmRzID0ge31cclxuXHJcbnZhciBLZXlib2FyZCA9IHtcclxuICBrZXlzOiBnZXRLZXlDb2RlcyhrZXlDb2RlcyksXHJcblxyXG4gIC8qKlxyXG4gICAqIFBhcnNlcyB0aGUgKGtleWJvYXJkKSBldmVudCBhbmQgcmV0dXJucyBhIFN0cmluZyB0aGF0IHJlcHJlc2VudHMgaXRzIGtleVxyXG4gICAqIENhbiBiZSB1c2VkIGxpa2UgRm91bmRhdGlvbi5wYXJzZUtleShldmVudCkgPT09IEZvdW5kYXRpb24ua2V5cy5TUEFDRVxyXG4gICAqIEBwYXJhbSB7RXZlbnR9IGV2ZW50IC0gdGhlIGV2ZW50IGdlbmVyYXRlZCBieSB0aGUgZXZlbnQgaGFuZGxlclxyXG4gICAqIEByZXR1cm4gU3RyaW5nIGtleSAtIFN0cmluZyB0aGF0IHJlcHJlc2VudHMgdGhlIGtleSBwcmVzc2VkXHJcbiAgICovXHJcbiAgcGFyc2VLZXkoZXZlbnQpIHtcclxuICAgIHZhciBrZXkgPSBrZXlDb2Rlc1tldmVudC53aGljaCB8fCBldmVudC5rZXlDb2RlXSB8fCBTdHJpbmcuZnJvbUNoYXJDb2RlKGV2ZW50LndoaWNoKS50b1VwcGVyQ2FzZSgpO1xyXG4gICAgaWYgKGV2ZW50LnNoaWZ0S2V5KSBrZXkgPSBgU0hJRlRfJHtrZXl9YDtcclxuICAgIGlmIChldmVudC5jdHJsS2V5KSBrZXkgPSBgQ1RSTF8ke2tleX1gO1xyXG4gICAgaWYgKGV2ZW50LmFsdEtleSkga2V5ID0gYEFMVF8ke2tleX1gO1xyXG4gICAgcmV0dXJuIGtleTtcclxuICB9LFxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGVzIHRoZSBnaXZlbiAoa2V5Ym9hcmQpIGV2ZW50XHJcbiAgICogQHBhcmFtIHtFdmVudH0gZXZlbnQgLSB0aGUgZXZlbnQgZ2VuZXJhdGVkIGJ5IHRoZSBldmVudCBoYW5kbGVyXHJcbiAgICogQHBhcmFtIHtTdHJpbmd9IGNvbXBvbmVudCAtIEZvdW5kYXRpb24gY29tcG9uZW50J3MgbmFtZSwgZS5nLiBTbGlkZXIgb3IgUmV2ZWFsXHJcbiAgICogQHBhcmFtIHtPYmplY3RzfSBmdW5jdGlvbnMgLSBjb2xsZWN0aW9uIG9mIGZ1bmN0aW9ucyB0aGF0IGFyZSB0byBiZSBleGVjdXRlZFxyXG4gICAqL1xyXG4gIGhhbmRsZUtleShldmVudCwgY29tcG9uZW50LCBmdW5jdGlvbnMpIHtcclxuICAgIHZhciBjb21tYW5kTGlzdCA9IGNvbW1hbmRzW2NvbXBvbmVudF0sXHJcbiAgICAgIGtleUNvZGUgPSB0aGlzLnBhcnNlS2V5KGV2ZW50KSxcclxuICAgICAgY21kcyxcclxuICAgICAgY29tbWFuZCxcclxuICAgICAgZm47XHJcblxyXG4gICAgaWYgKCFjb21tYW5kTGlzdCkgcmV0dXJuIGNvbnNvbGUud2FybignQ29tcG9uZW50IG5vdCBkZWZpbmVkIScpO1xyXG5cclxuICAgIGlmICh0eXBlb2YgY29tbWFuZExpc3QubHRyID09PSAndW5kZWZpbmVkJykgeyAvLyB0aGlzIGNvbXBvbmVudCBkb2VzIG5vdCBkaWZmZXJlbnRpYXRlIGJldHdlZW4gbHRyIGFuZCBydGxcclxuICAgICAgICBjbWRzID0gY29tbWFuZExpc3Q7IC8vIHVzZSBwbGFpbiBsaXN0XHJcbiAgICB9IGVsc2UgeyAvLyBtZXJnZSBsdHIgYW5kIHJ0bDogaWYgZG9jdW1lbnQgaXMgcnRsLCBydGwgb3ZlcndyaXRlcyBsdHIgYW5kIHZpY2UgdmVyc2FcclxuICAgICAgICBpZiAoRm91bmRhdGlvbi5ydGwoKSkgY21kcyA9ICQuZXh0ZW5kKHt9LCBjb21tYW5kTGlzdC5sdHIsIGNvbW1hbmRMaXN0LnJ0bCk7XHJcblxyXG4gICAgICAgIGVsc2UgY21kcyA9ICQuZXh0ZW5kKHt9LCBjb21tYW5kTGlzdC5ydGwsIGNvbW1hbmRMaXN0Lmx0cik7XHJcbiAgICB9XHJcbiAgICBjb21tYW5kID0gY21kc1trZXlDb2RlXTtcclxuXHJcbiAgICBmbiA9IGZ1bmN0aW9uc1tjb21tYW5kXTtcclxuICAgIGlmIChmbiAmJiB0eXBlb2YgZm4gPT09ICdmdW5jdGlvbicpIHsgLy8gZXhlY3V0ZSBmdW5jdGlvbiAgaWYgZXhpc3RzXHJcbiAgICAgIHZhciByZXR1cm5WYWx1ZSA9IGZuLmFwcGx5KCk7XHJcbiAgICAgIGlmIChmdW5jdGlvbnMuaGFuZGxlZCB8fCB0eXBlb2YgZnVuY3Rpb25zLmhhbmRsZWQgPT09ICdmdW5jdGlvbicpIHsgLy8gZXhlY3V0ZSBmdW5jdGlvbiB3aGVuIGV2ZW50IHdhcyBoYW5kbGVkXHJcbiAgICAgICAgICBmdW5jdGlvbnMuaGFuZGxlZChyZXR1cm5WYWx1ZSk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlmIChmdW5jdGlvbnMudW5oYW5kbGVkIHx8IHR5cGVvZiBmdW5jdGlvbnMudW5oYW5kbGVkID09PSAnZnVuY3Rpb24nKSB7IC8vIGV4ZWN1dGUgZnVuY3Rpb24gd2hlbiBldmVudCB3YXMgbm90IGhhbmRsZWRcclxuICAgICAgICAgIGZ1bmN0aW9ucy51bmhhbmRsZWQoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH0sXHJcblxyXG4gIC8qKlxyXG4gICAqIEZpbmRzIGFsbCBmb2N1c2FibGUgZWxlbWVudHMgd2l0aGluIHRoZSBnaXZlbiBgJGVsZW1lbnRgXHJcbiAgICogQHBhcmFtIHtqUXVlcnl9ICRlbGVtZW50IC0galF1ZXJ5IG9iamVjdCB0byBzZWFyY2ggd2l0aGluXHJcbiAgICogQHJldHVybiB7alF1ZXJ5fSAkZm9jdXNhYmxlIC0gYWxsIGZvY3VzYWJsZSBlbGVtZW50cyB3aXRoaW4gYCRlbGVtZW50YFxyXG4gICAqL1xyXG4gIGZpbmRGb2N1c2FibGUoJGVsZW1lbnQpIHtcclxuICAgIHJldHVybiAkZWxlbWVudC5maW5kKCdhW2hyZWZdLCBhcmVhW2hyZWZdLCBpbnB1dDpub3QoW2Rpc2FibGVkXSksIHNlbGVjdDpub3QoW2Rpc2FibGVkXSksIHRleHRhcmVhOm5vdChbZGlzYWJsZWRdKSwgYnV0dG9uOm5vdChbZGlzYWJsZWRdKSwgaWZyYW1lLCBvYmplY3QsIGVtYmVkLCAqW3RhYmluZGV4XSwgKltjb250ZW50ZWRpdGFibGVdJykuZmlsdGVyKGZ1bmN0aW9uKCkge1xyXG4gICAgICBpZiAoISQodGhpcykuaXMoJzp2aXNpYmxlJykgfHwgJCh0aGlzKS5hdHRyKCd0YWJpbmRleCcpIDwgMCkgeyByZXR1cm4gZmFsc2U7IH0gLy9vbmx5IGhhdmUgdmlzaWJsZSBlbGVtZW50cyBhbmQgdGhvc2UgdGhhdCBoYXZlIGEgdGFiaW5kZXggZ3JlYXRlciBvciBlcXVhbCAwXHJcbiAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgfSk7XHJcbiAgfSxcclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJucyB0aGUgY29tcG9uZW50IG5hbWUgbmFtZVxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBjb21wb25lbnQgLSBGb3VuZGF0aW9uIGNvbXBvbmVudCwgZS5nLiBTbGlkZXIgb3IgUmV2ZWFsXHJcbiAgICogQHJldHVybiBTdHJpbmcgY29tcG9uZW50TmFtZVxyXG4gICAqL1xyXG5cclxuICByZWdpc3Rlcihjb21wb25lbnROYW1lLCBjbWRzKSB7XHJcbiAgICBjb21tYW5kc1tjb21wb25lbnROYW1lXSA9IGNtZHM7XHJcbiAgfVxyXG59XHJcblxyXG4vKlxyXG4gKiBDb25zdGFudHMgZm9yIGVhc2llciBjb21wYXJpbmcuXHJcbiAqIENhbiBiZSB1c2VkIGxpa2UgRm91bmRhdGlvbi5wYXJzZUtleShldmVudCkgPT09IEZvdW5kYXRpb24ua2V5cy5TUEFDRVxyXG4gKi9cclxuZnVuY3Rpb24gZ2V0S2V5Q29kZXMoa2NzKSB7XHJcbiAgdmFyIGsgPSB7fTtcclxuICBmb3IgKHZhciBrYyBpbiBrY3MpIGtba2NzW2tjXV0gPSBrY3Nba2NdO1xyXG4gIHJldHVybiBrO1xyXG59XHJcblxyXG5Gb3VuZGF0aW9uLktleWJvYXJkID0gS2V5Ym9hcmQ7XHJcblxyXG59KGpRdWVyeSk7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbiFmdW5jdGlvbigkKSB7XHJcblxyXG4vLyBEZWZhdWx0IHNldCBvZiBtZWRpYSBxdWVyaWVzXHJcbmNvbnN0IGRlZmF1bHRRdWVyaWVzID0ge1xyXG4gICdkZWZhdWx0JyA6ICdvbmx5IHNjcmVlbicsXHJcbiAgbGFuZHNjYXBlIDogJ29ubHkgc2NyZWVuIGFuZCAob3JpZW50YXRpb246IGxhbmRzY2FwZSknLFxyXG4gIHBvcnRyYWl0IDogJ29ubHkgc2NyZWVuIGFuZCAob3JpZW50YXRpb246IHBvcnRyYWl0KScsXHJcbiAgcmV0aW5hIDogJ29ubHkgc2NyZWVuIGFuZCAoLXdlYmtpdC1taW4tZGV2aWNlLXBpeGVsLXJhdGlvOiAyKSwnICtcclxuICAgICdvbmx5IHNjcmVlbiBhbmQgKG1pbi0tbW96LWRldmljZS1waXhlbC1yYXRpbzogMiksJyArXHJcbiAgICAnb25seSBzY3JlZW4gYW5kICgtby1taW4tZGV2aWNlLXBpeGVsLXJhdGlvOiAyLzEpLCcgK1xyXG4gICAgJ29ubHkgc2NyZWVuIGFuZCAobWluLWRldmljZS1waXhlbC1yYXRpbzogMiksJyArXHJcbiAgICAnb25seSBzY3JlZW4gYW5kIChtaW4tcmVzb2x1dGlvbjogMTkyZHBpKSwnICtcclxuICAgICdvbmx5IHNjcmVlbiBhbmQgKG1pbi1yZXNvbHV0aW9uOiAyZHBweCknXHJcbn07XHJcblxyXG52YXIgTWVkaWFRdWVyeSA9IHtcclxuICBxdWVyaWVzOiBbXSxcclxuXHJcbiAgY3VycmVudDogJycsXHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpYWxpemVzIHRoZSBtZWRpYSBxdWVyeSBoZWxwZXIsIGJ5IGV4dHJhY3RpbmcgdGhlIGJyZWFrcG9pbnQgbGlzdCBmcm9tIHRoZSBDU1MgYW5kIGFjdGl2YXRpbmcgdGhlIGJyZWFrcG9pbnQgd2F0Y2hlci5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9pbml0KCkge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgdmFyIGV4dHJhY3RlZFN0eWxlcyA9ICQoJy5mb3VuZGF0aW9uLW1xJykuY3NzKCdmb250LWZhbWlseScpO1xyXG4gICAgdmFyIG5hbWVkUXVlcmllcztcclxuXHJcbiAgICBuYW1lZFF1ZXJpZXMgPSBwYXJzZVN0eWxlVG9PYmplY3QoZXh0cmFjdGVkU3R5bGVzKTtcclxuXHJcbiAgICBmb3IgKHZhciBrZXkgaW4gbmFtZWRRdWVyaWVzKSB7XHJcbiAgICAgIGlmKG5hbWVkUXVlcmllcy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XHJcbiAgICAgICAgc2VsZi5xdWVyaWVzLnB1c2goe1xyXG4gICAgICAgICAgbmFtZToga2V5LFxyXG4gICAgICAgICAgdmFsdWU6IGBvbmx5IHNjcmVlbiBhbmQgKG1pbi13aWR0aDogJHtuYW1lZFF1ZXJpZXNba2V5XX0pYFxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5jdXJyZW50ID0gdGhpcy5fZ2V0Q3VycmVudFNpemUoKTtcclxuXHJcbiAgICB0aGlzLl93YXRjaGVyKCk7XHJcbiAgfSxcclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2tzIGlmIHRoZSBzY3JlZW4gaXMgYXQgbGVhc3QgYXMgd2lkZSBhcyBhIGJyZWFrcG9pbnQuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHBhcmFtIHtTdHJpbmd9IHNpemUgLSBOYW1lIG9mIHRoZSBicmVha3BvaW50IHRvIGNoZWNrLlxyXG4gICAqIEByZXR1cm5zIHtCb29sZWFufSBgdHJ1ZWAgaWYgdGhlIGJyZWFrcG9pbnQgbWF0Y2hlcywgYGZhbHNlYCBpZiBpdCdzIHNtYWxsZXIuXHJcbiAgICovXHJcbiAgYXRMZWFzdChzaXplKSB7XHJcbiAgICB2YXIgcXVlcnkgPSB0aGlzLmdldChzaXplKTtcclxuXHJcbiAgICBpZiAocXVlcnkpIHtcclxuICAgICAgcmV0dXJuIHdpbmRvdy5tYXRjaE1lZGlhKHF1ZXJ5KS5tYXRjaGVzO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9LFxyXG5cclxuICAvKipcclxuICAgKiBHZXRzIHRoZSBtZWRpYSBxdWVyeSBvZiBhIGJyZWFrcG9pbnQuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHBhcmFtIHtTdHJpbmd9IHNpemUgLSBOYW1lIG9mIHRoZSBicmVha3BvaW50IHRvIGdldC5cclxuICAgKiBAcmV0dXJucyB7U3RyaW5nfG51bGx9IC0gVGhlIG1lZGlhIHF1ZXJ5IG9mIHRoZSBicmVha3BvaW50LCBvciBgbnVsbGAgaWYgdGhlIGJyZWFrcG9pbnQgZG9lc24ndCBleGlzdC5cclxuICAgKi9cclxuICBnZXQoc2l6ZSkge1xyXG4gICAgZm9yICh2YXIgaSBpbiB0aGlzLnF1ZXJpZXMpIHtcclxuICAgICAgaWYodGhpcy5xdWVyaWVzLmhhc093blByb3BlcnR5KGkpKSB7XHJcbiAgICAgICAgdmFyIHF1ZXJ5ID0gdGhpcy5xdWVyaWVzW2ldO1xyXG4gICAgICAgIGlmIChzaXplID09PSBxdWVyeS5uYW1lKSByZXR1cm4gcXVlcnkudmFsdWU7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9LFxyXG5cclxuICAvKipcclxuICAgKiBHZXRzIHRoZSBjdXJyZW50IGJyZWFrcG9pbnQgbmFtZSBieSB0ZXN0aW5nIGV2ZXJ5IGJyZWFrcG9pbnQgYW5kIHJldHVybmluZyB0aGUgbGFzdCBvbmUgdG8gbWF0Y2ggKHRoZSBiaWdnZXN0IG9uZSkuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHByaXZhdGVcclxuICAgKiBAcmV0dXJucyB7U3RyaW5nfSBOYW1lIG9mIHRoZSBjdXJyZW50IGJyZWFrcG9pbnQuXHJcbiAgICovXHJcbiAgX2dldEN1cnJlbnRTaXplKCkge1xyXG4gICAgdmFyIG1hdGNoZWQ7XHJcblxyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnF1ZXJpZXMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgdmFyIHF1ZXJ5ID0gdGhpcy5xdWVyaWVzW2ldO1xyXG5cclxuICAgICAgaWYgKHdpbmRvdy5tYXRjaE1lZGlhKHF1ZXJ5LnZhbHVlKS5tYXRjaGVzKSB7XHJcbiAgICAgICAgbWF0Y2hlZCA9IHF1ZXJ5O1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHR5cGVvZiBtYXRjaGVkID09PSAnb2JqZWN0Jykge1xyXG4gICAgICByZXR1cm4gbWF0Y2hlZC5uYW1lO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgcmV0dXJuIG1hdGNoZWQ7XHJcbiAgICB9XHJcbiAgfSxcclxuXHJcbiAgLyoqXHJcbiAgICogQWN0aXZhdGVzIHRoZSBicmVha3BvaW50IHdhdGNoZXIsIHdoaWNoIGZpcmVzIGFuIGV2ZW50IG9uIHRoZSB3aW5kb3cgd2hlbmV2ZXIgdGhlIGJyZWFrcG9pbnQgY2hhbmdlcy5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF93YXRjaGVyKCkge1xyXG4gICAgJCh3aW5kb3cpLm9uKCdyZXNpemUuemYubWVkaWFxdWVyeScsICgpID0+IHtcclxuICAgICAgdmFyIG5ld1NpemUgPSB0aGlzLl9nZXRDdXJyZW50U2l6ZSgpLCBjdXJyZW50U2l6ZSA9IHRoaXMuY3VycmVudDtcclxuXHJcbiAgICAgIGlmIChuZXdTaXplICE9PSBjdXJyZW50U2l6ZSkge1xyXG4gICAgICAgIC8vIENoYW5nZSB0aGUgY3VycmVudCBtZWRpYSBxdWVyeVxyXG4gICAgICAgIHRoaXMuY3VycmVudCA9IG5ld1NpemU7XHJcblxyXG4gICAgICAgIC8vIEJyb2FkY2FzdCB0aGUgbWVkaWEgcXVlcnkgY2hhbmdlIG9uIHRoZSB3aW5kb3dcclxuICAgICAgICAkKHdpbmRvdykudHJpZ2dlcignY2hhbmdlZC56Zi5tZWRpYXF1ZXJ5JywgW25ld1NpemUsIGN1cnJlbnRTaXplXSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxufTtcclxuXHJcbkZvdW5kYXRpb24uTWVkaWFRdWVyeSA9IE1lZGlhUXVlcnk7XHJcblxyXG4vLyBtYXRjaE1lZGlhKCkgcG9seWZpbGwgLSBUZXN0IGEgQ1NTIG1lZGlhIHR5cGUvcXVlcnkgaW4gSlMuXHJcbi8vIEF1dGhvcnMgJiBjb3B5cmlnaHQgKGMpIDIwMTI6IFNjb3R0IEplaGwsIFBhdWwgSXJpc2gsIE5pY2hvbGFzIFpha2FzLCBEYXZpZCBLbmlnaHQuIER1YWwgTUlUL0JTRCBsaWNlbnNlXHJcbndpbmRvdy5tYXRjaE1lZGlhIHx8ICh3aW5kb3cubWF0Y2hNZWRpYSA9IGZ1bmN0aW9uKCkge1xyXG4gICd1c2Ugc3RyaWN0JztcclxuXHJcbiAgLy8gRm9yIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBtYXRjaE1lZGl1bSBhcGkgc3VjaCBhcyBJRSA5IGFuZCB3ZWJraXRcclxuICB2YXIgc3R5bGVNZWRpYSA9ICh3aW5kb3cuc3R5bGVNZWRpYSB8fCB3aW5kb3cubWVkaWEpO1xyXG5cclxuICAvLyBGb3IgdGhvc2UgdGhhdCBkb24ndCBzdXBwb3J0IG1hdGNoTWVkaXVtXHJcbiAgaWYgKCFzdHlsZU1lZGlhKSB7XHJcbiAgICB2YXIgc3R5bGUgICA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3N0eWxlJyksXHJcbiAgICBzY3JpcHQgICAgICA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdzY3JpcHQnKVswXSxcclxuICAgIGluZm8gICAgICAgID0gbnVsbDtcclxuXHJcbiAgICBzdHlsZS50eXBlICA9ICd0ZXh0L2Nzcyc7XHJcbiAgICBzdHlsZS5pZCAgICA9ICdtYXRjaG1lZGlhanMtdGVzdCc7XHJcblxyXG4gICAgc2NyaXB0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHN0eWxlLCBzY3JpcHQpO1xyXG5cclxuICAgIC8vICdzdHlsZS5jdXJyZW50U3R5bGUnIGlzIHVzZWQgYnkgSUUgPD0gOCBhbmQgJ3dpbmRvdy5nZXRDb21wdXRlZFN0eWxlJyBmb3IgYWxsIG90aGVyIGJyb3dzZXJzXHJcbiAgICBpbmZvID0gKCdnZXRDb21wdXRlZFN0eWxlJyBpbiB3aW5kb3cpICYmIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKHN0eWxlLCBudWxsKSB8fCBzdHlsZS5jdXJyZW50U3R5bGU7XHJcblxyXG4gICAgc3R5bGVNZWRpYSA9IHtcclxuICAgICAgbWF0Y2hNZWRpdW0obWVkaWEpIHtcclxuICAgICAgICB2YXIgdGV4dCA9IGBAbWVkaWEgJHttZWRpYX17ICNtYXRjaG1lZGlhanMtdGVzdCB7IHdpZHRoOiAxcHg7IH0gfWA7XHJcblxyXG4gICAgICAgIC8vICdzdHlsZS5zdHlsZVNoZWV0JyBpcyB1c2VkIGJ5IElFIDw9IDggYW5kICdzdHlsZS50ZXh0Q29udGVudCcgZm9yIGFsbCBvdGhlciBicm93c2Vyc1xyXG4gICAgICAgIGlmIChzdHlsZS5zdHlsZVNoZWV0KSB7XHJcbiAgICAgICAgICBzdHlsZS5zdHlsZVNoZWV0LmNzc1RleHQgPSB0ZXh0O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBzdHlsZS50ZXh0Q29udGVudCA9IHRleHQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBUZXN0IGlmIG1lZGlhIHF1ZXJ5IGlzIHRydWUgb3IgZmFsc2VcclxuICAgICAgICByZXR1cm4gaW5mby53aWR0aCA9PT0gJzFweCc7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIHJldHVybiBmdW5jdGlvbihtZWRpYSkge1xyXG4gICAgcmV0dXJuIHtcclxuICAgICAgbWF0Y2hlczogc3R5bGVNZWRpYS5tYXRjaE1lZGl1bShtZWRpYSB8fCAnYWxsJyksXHJcbiAgICAgIG1lZGlhOiBtZWRpYSB8fCAnYWxsJ1xyXG4gICAgfTtcclxuICB9XHJcbn0oKSk7XHJcblxyXG4vLyBUaGFuayB5b3U6IGh0dHBzOi8vZ2l0aHViLmNvbS9zaW5kcmVzb3JodXMvcXVlcnktc3RyaW5nXHJcbmZ1bmN0aW9uIHBhcnNlU3R5bGVUb09iamVjdChzdHIpIHtcclxuICB2YXIgc3R5bGVPYmplY3QgPSB7fTtcclxuXHJcbiAgaWYgKHR5cGVvZiBzdHIgIT09ICdzdHJpbmcnKSB7XHJcbiAgICByZXR1cm4gc3R5bGVPYmplY3Q7XHJcbiAgfVxyXG5cclxuICBzdHIgPSBzdHIudHJpbSgpLnNsaWNlKDEsIC0xKTsgLy8gYnJvd3NlcnMgcmUtcXVvdGUgc3RyaW5nIHN0eWxlIHZhbHVlc1xyXG5cclxuICBpZiAoIXN0cikge1xyXG4gICAgcmV0dXJuIHN0eWxlT2JqZWN0O1xyXG4gIH1cclxuXHJcbiAgc3R5bGVPYmplY3QgPSBzdHIuc3BsaXQoJyYnKS5yZWR1Y2UoZnVuY3Rpb24ocmV0LCBwYXJhbSkge1xyXG4gICAgdmFyIHBhcnRzID0gcGFyYW0ucmVwbGFjZSgvXFwrL2csICcgJykuc3BsaXQoJz0nKTtcclxuICAgIHZhciBrZXkgPSBwYXJ0c1swXTtcclxuICAgIHZhciB2YWwgPSBwYXJ0c1sxXTtcclxuICAgIGtleSA9IGRlY29kZVVSSUNvbXBvbmVudChrZXkpO1xyXG5cclxuICAgIC8vIG1pc3NpbmcgYD1gIHNob3VsZCBiZSBgbnVsbGA6XHJcbiAgICAvLyBodHRwOi8vdzMub3JnL1RSLzIwMTIvV0QtdXJsLTIwMTIwNTI0LyNjb2xsZWN0LXVybC1wYXJhbWV0ZXJzXHJcbiAgICB2YWwgPSB2YWwgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBkZWNvZGVVUklDb21wb25lbnQodmFsKTtcclxuXHJcbiAgICBpZiAoIXJldC5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XHJcbiAgICAgIHJldFtrZXldID0gdmFsO1xyXG4gICAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHJldFtrZXldKSkge1xyXG4gICAgICByZXRba2V5XS5wdXNoKHZhbCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICByZXRba2V5XSA9IFtyZXRba2V5XSwgdmFsXTtcclxuICAgIH1cclxuICAgIHJldHVybiByZXQ7XHJcbiAgfSwge30pO1xyXG5cclxuICByZXR1cm4gc3R5bGVPYmplY3Q7XHJcbn1cclxuXHJcbkZvdW5kYXRpb24uTWVkaWFRdWVyeSA9IE1lZGlhUXVlcnk7XHJcblxyXG59KGpRdWVyeSk7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbiFmdW5jdGlvbigkKSB7XHJcblxyXG4vKipcclxuICogTW90aW9uIG1vZHVsZS5cclxuICogQG1vZHVsZSBmb3VuZGF0aW9uLm1vdGlvblxyXG4gKi9cclxuXHJcbmNvbnN0IGluaXRDbGFzc2VzICAgPSBbJ211aS1lbnRlcicsICdtdWktbGVhdmUnXTtcclxuY29uc3QgYWN0aXZlQ2xhc3NlcyA9IFsnbXVpLWVudGVyLWFjdGl2ZScsICdtdWktbGVhdmUtYWN0aXZlJ107XHJcblxyXG5jb25zdCBNb3Rpb24gPSB7XHJcbiAgYW5pbWF0ZUluOiBmdW5jdGlvbihlbGVtZW50LCBhbmltYXRpb24sIGNiKSB7XHJcbiAgICBhbmltYXRlKHRydWUsIGVsZW1lbnQsIGFuaW1hdGlvbiwgY2IpO1xyXG4gIH0sXHJcblxyXG4gIGFuaW1hdGVPdXQ6IGZ1bmN0aW9uKGVsZW1lbnQsIGFuaW1hdGlvbiwgY2IpIHtcclxuICAgIGFuaW1hdGUoZmFsc2UsIGVsZW1lbnQsIGFuaW1hdGlvbiwgY2IpO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gTW92ZShkdXJhdGlvbiwgZWxlbSwgZm4pe1xyXG4gIHZhciBhbmltLCBwcm9nLCBzdGFydCA9IG51bGw7XHJcbiAgLy8gY29uc29sZS5sb2coJ2NhbGxlZCcpO1xyXG5cclxuICBmdW5jdGlvbiBtb3ZlKHRzKXtcclxuICAgIGlmKCFzdGFydCkgc3RhcnQgPSB3aW5kb3cucGVyZm9ybWFuY2Uubm93KCk7XHJcbiAgICAvLyBjb25zb2xlLmxvZyhzdGFydCwgdHMpO1xyXG4gICAgcHJvZyA9IHRzIC0gc3RhcnQ7XHJcbiAgICBmbi5hcHBseShlbGVtKTtcclxuXHJcbiAgICBpZihwcm9nIDwgZHVyYXRpb24peyBhbmltID0gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZShtb3ZlLCBlbGVtKTsgfVxyXG4gICAgZWxzZXtcclxuICAgICAgd2luZG93LmNhbmNlbEFuaW1hdGlvbkZyYW1lKGFuaW0pO1xyXG4gICAgICBlbGVtLnRyaWdnZXIoJ2ZpbmlzaGVkLnpmLmFuaW1hdGUnLCBbZWxlbV0pLnRyaWdnZXJIYW5kbGVyKCdmaW5pc2hlZC56Zi5hbmltYXRlJywgW2VsZW1dKTtcclxuICAgIH1cclxuICB9XHJcbiAgYW5pbSA9IHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUobW92ZSk7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBbmltYXRlcyBhbiBlbGVtZW50IGluIG9yIG91dCB1c2luZyBhIENTUyB0cmFuc2l0aW9uIGNsYXNzLlxyXG4gKiBAZnVuY3Rpb25cclxuICogQHByaXZhdGVcclxuICogQHBhcmFtIHtCb29sZWFufSBpc0luIC0gRGVmaW5lcyBpZiB0aGUgYW5pbWF0aW9uIGlzIGluIG9yIG91dC5cclxuICogQHBhcmFtIHtPYmplY3R9IGVsZW1lbnQgLSBqUXVlcnkgb3IgSFRNTCBvYmplY3QgdG8gYW5pbWF0ZS5cclxuICogQHBhcmFtIHtTdHJpbmd9IGFuaW1hdGlvbiAtIENTUyBjbGFzcyB0byB1c2UuXHJcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNiIC0gQ2FsbGJhY2sgdG8gcnVuIHdoZW4gYW5pbWF0aW9uIGlzIGZpbmlzaGVkLlxyXG4gKi9cclxuZnVuY3Rpb24gYW5pbWF0ZShpc0luLCBlbGVtZW50LCBhbmltYXRpb24sIGNiKSB7XHJcbiAgZWxlbWVudCA9ICQoZWxlbWVudCkuZXEoMCk7XHJcblxyXG4gIGlmICghZWxlbWVudC5sZW5ndGgpIHJldHVybjtcclxuXHJcbiAgdmFyIGluaXRDbGFzcyA9IGlzSW4gPyBpbml0Q2xhc3Nlc1swXSA6IGluaXRDbGFzc2VzWzFdO1xyXG4gIHZhciBhY3RpdmVDbGFzcyA9IGlzSW4gPyBhY3RpdmVDbGFzc2VzWzBdIDogYWN0aXZlQ2xhc3Nlc1sxXTtcclxuXHJcbiAgLy8gU2V0IHVwIHRoZSBhbmltYXRpb25cclxuICByZXNldCgpO1xyXG5cclxuICBlbGVtZW50XHJcbiAgICAuYWRkQ2xhc3MoYW5pbWF0aW9uKVxyXG4gICAgLmNzcygndHJhbnNpdGlvbicsICdub25lJyk7XHJcblxyXG4gIHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XHJcbiAgICBlbGVtZW50LmFkZENsYXNzKGluaXRDbGFzcyk7XHJcbiAgICBpZiAoaXNJbikgZWxlbWVudC5zaG93KCk7XHJcbiAgfSk7XHJcblxyXG4gIC8vIFN0YXJ0IHRoZSBhbmltYXRpb25cclxuICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xyXG4gICAgZWxlbWVudFswXS5vZmZzZXRXaWR0aDtcclxuICAgIGVsZW1lbnRcclxuICAgICAgLmNzcygndHJhbnNpdGlvbicsICcnKVxyXG4gICAgICAuYWRkQ2xhc3MoYWN0aXZlQ2xhc3MpO1xyXG4gIH0pO1xyXG5cclxuICAvLyBDbGVhbiB1cCB0aGUgYW5pbWF0aW9uIHdoZW4gaXQgZmluaXNoZXNcclxuICBlbGVtZW50Lm9uZShGb3VuZGF0aW9uLnRyYW5zaXRpb25lbmQoZWxlbWVudCksIGZpbmlzaCk7XHJcblxyXG4gIC8vIEhpZGVzIHRoZSBlbGVtZW50IChmb3Igb3V0IGFuaW1hdGlvbnMpLCByZXNldHMgdGhlIGVsZW1lbnQsIGFuZCBydW5zIGEgY2FsbGJhY2tcclxuICBmdW5jdGlvbiBmaW5pc2goKSB7XHJcbiAgICBpZiAoIWlzSW4pIGVsZW1lbnQuaGlkZSgpO1xyXG4gICAgcmVzZXQoKTtcclxuICAgIGlmIChjYikgY2IuYXBwbHkoZWxlbWVudCk7XHJcbiAgfVxyXG5cclxuICAvLyBSZXNldHMgdHJhbnNpdGlvbnMgYW5kIHJlbW92ZXMgbW90aW9uLXNwZWNpZmljIGNsYXNzZXNcclxuICBmdW5jdGlvbiByZXNldCgpIHtcclxuICAgIGVsZW1lbnRbMF0uc3R5bGUudHJhbnNpdGlvbkR1cmF0aW9uID0gMDtcclxuICAgIGVsZW1lbnQucmVtb3ZlQ2xhc3MoYCR7aW5pdENsYXNzfSAke2FjdGl2ZUNsYXNzfSAke2FuaW1hdGlvbn1gKTtcclxuICB9XHJcbn1cclxuXHJcbkZvdW5kYXRpb24uTW92ZSA9IE1vdmU7XHJcbkZvdW5kYXRpb24uTW90aW9uID0gTW90aW9uO1xyXG5cclxufShqUXVlcnkpO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG4hZnVuY3Rpb24oJCkge1xyXG5cclxuY29uc3QgTmVzdCA9IHtcclxuICBGZWF0aGVyKG1lbnUsIHR5cGUgPSAnemYnKSB7XHJcbiAgICBtZW51LmF0dHIoJ3JvbGUnLCAnbWVudWJhcicpO1xyXG5cclxuICAgIHZhciBpdGVtcyA9IG1lbnUuZmluZCgnbGknKS5hdHRyKHsncm9sZSc6ICdtZW51aXRlbSd9KSxcclxuICAgICAgICBzdWJNZW51Q2xhc3MgPSBgaXMtJHt0eXBlfS1zdWJtZW51YCxcclxuICAgICAgICBzdWJJdGVtQ2xhc3MgPSBgJHtzdWJNZW51Q2xhc3N9LWl0ZW1gLFxyXG4gICAgICAgIGhhc1N1YkNsYXNzID0gYGlzLSR7dHlwZX0tc3VibWVudS1wYXJlbnRgO1xyXG5cclxuICAgIG1lbnUuZmluZCgnYTpmaXJzdCcpLmF0dHIoJ3RhYmluZGV4JywgMCk7XHJcblxyXG4gICAgaXRlbXMuZWFjaChmdW5jdGlvbigpIHtcclxuICAgICAgdmFyICRpdGVtID0gJCh0aGlzKSxcclxuICAgICAgICAgICRzdWIgPSAkaXRlbS5jaGlsZHJlbigndWwnKTtcclxuXHJcbiAgICAgIGlmICgkc3ViLmxlbmd0aCkge1xyXG4gICAgICAgICRpdGVtXHJcbiAgICAgICAgICAuYWRkQ2xhc3MoaGFzU3ViQ2xhc3MpXHJcbiAgICAgICAgICAuYXR0cih7XHJcbiAgICAgICAgICAgICdhcmlhLWhhc3BvcHVwJzogdHJ1ZSxcclxuICAgICAgICAgICAgJ2FyaWEtZXhwYW5kZWQnOiBmYWxzZSxcclxuICAgICAgICAgICAgJ2FyaWEtbGFiZWwnOiAkaXRlbS5jaGlsZHJlbignYTpmaXJzdCcpLnRleHQoKVxyXG4gICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICRzdWJcclxuICAgICAgICAgIC5hZGRDbGFzcyhgc3VibWVudSAke3N1Yk1lbnVDbGFzc31gKVxyXG4gICAgICAgICAgLmF0dHIoe1xyXG4gICAgICAgICAgICAnZGF0YS1zdWJtZW51JzogJycsXHJcbiAgICAgICAgICAgICdhcmlhLWhpZGRlbic6IHRydWUsXHJcbiAgICAgICAgICAgICdyb2xlJzogJ21lbnUnXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCRpdGVtLnBhcmVudCgnW2RhdGEtc3VibWVudV0nKS5sZW5ndGgpIHtcclxuICAgICAgICAkaXRlbS5hZGRDbGFzcyhgaXMtc3VibWVudS1pdGVtICR7c3ViSXRlbUNsYXNzfWApO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm47XHJcbiAgfSxcclxuXHJcbiAgQnVybihtZW51LCB0eXBlKSB7XHJcbiAgICB2YXIgaXRlbXMgPSBtZW51LmZpbmQoJ2xpJykucmVtb3ZlQXR0cigndGFiaW5kZXgnKSxcclxuICAgICAgICBzdWJNZW51Q2xhc3MgPSBgaXMtJHt0eXBlfS1zdWJtZW51YCxcclxuICAgICAgICBzdWJJdGVtQ2xhc3MgPSBgJHtzdWJNZW51Q2xhc3N9LWl0ZW1gLFxyXG4gICAgICAgIGhhc1N1YkNsYXNzID0gYGlzLSR7dHlwZX0tc3VibWVudS1wYXJlbnRgO1xyXG5cclxuICAgIG1lbnVcclxuICAgICAgLmZpbmQoJyonKVxyXG4gICAgICAucmVtb3ZlQ2xhc3MoYCR7c3ViTWVudUNsYXNzfSAke3N1Ykl0ZW1DbGFzc30gJHtoYXNTdWJDbGFzc30gaXMtc3VibWVudS1pdGVtIHN1Ym1lbnUgaXMtYWN0aXZlYClcclxuICAgICAgLnJlbW92ZUF0dHIoJ2RhdGEtc3VibWVudScpLmNzcygnZGlzcGxheScsICcnKTtcclxuXHJcbiAgICAvLyBjb25zb2xlLmxvZyggICAgICBtZW51LmZpbmQoJy4nICsgc3ViTWVudUNsYXNzICsgJywgLicgKyBzdWJJdGVtQ2xhc3MgKyAnLCAuaGFzLXN1Ym1lbnUsIC5pcy1zdWJtZW51LWl0ZW0sIC5zdWJtZW51LCBbZGF0YS1zdWJtZW51XScpXHJcbiAgICAvLyAgICAgICAgICAgLnJlbW92ZUNsYXNzKHN1Yk1lbnVDbGFzcyArICcgJyArIHN1Ykl0ZW1DbGFzcyArICcgaGFzLXN1Ym1lbnUgaXMtc3VibWVudS1pdGVtIHN1Ym1lbnUnKVxyXG4gICAgLy8gICAgICAgICAgIC5yZW1vdmVBdHRyKCdkYXRhLXN1Ym1lbnUnKSk7XHJcbiAgICAvLyBpdGVtcy5lYWNoKGZ1bmN0aW9uKCl7XHJcbiAgICAvLyAgIHZhciAkaXRlbSA9ICQodGhpcyksXHJcbiAgICAvLyAgICAgICAkc3ViID0gJGl0ZW0uY2hpbGRyZW4oJ3VsJyk7XHJcbiAgICAvLyAgIGlmKCRpdGVtLnBhcmVudCgnW2RhdGEtc3VibWVudV0nKS5sZW5ndGgpe1xyXG4gICAgLy8gICAgICRpdGVtLnJlbW92ZUNsYXNzKCdpcy1zdWJtZW51LWl0ZW0gJyArIHN1Ykl0ZW1DbGFzcyk7XHJcbiAgICAvLyAgIH1cclxuICAgIC8vICAgaWYoJHN1Yi5sZW5ndGgpe1xyXG4gICAgLy8gICAgICRpdGVtLnJlbW92ZUNsYXNzKCdoYXMtc3VibWVudScpO1xyXG4gICAgLy8gICAgICRzdWIucmVtb3ZlQ2xhc3MoJ3N1Ym1lbnUgJyArIHN1Yk1lbnVDbGFzcykucmVtb3ZlQXR0cignZGF0YS1zdWJtZW51Jyk7XHJcbiAgICAvLyAgIH1cclxuICAgIC8vIH0pO1xyXG4gIH1cclxufVxyXG5cclxuRm91bmRhdGlvbi5OZXN0ID0gTmVzdDtcclxuXHJcbn0oalF1ZXJ5KTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxuIWZ1bmN0aW9uKCQpIHtcclxuXHJcbmZ1bmN0aW9uIFRpbWVyKGVsZW0sIG9wdGlvbnMsIGNiKSB7XHJcbiAgdmFyIF90aGlzID0gdGhpcyxcclxuICAgICAgZHVyYXRpb24gPSBvcHRpb25zLmR1cmF0aW9uLC8vb3B0aW9ucyBpcyBhbiBvYmplY3QgZm9yIGVhc2lseSBhZGRpbmcgZmVhdHVyZXMgbGF0ZXIuXHJcbiAgICAgIG5hbWVTcGFjZSA9IE9iamVjdC5rZXlzKGVsZW0uZGF0YSgpKVswXSB8fCAndGltZXInLFxyXG4gICAgICByZW1haW4gPSAtMSxcclxuICAgICAgc3RhcnQsXHJcbiAgICAgIHRpbWVyO1xyXG5cclxuICB0aGlzLmlzUGF1c2VkID0gZmFsc2U7XHJcblxyXG4gIHRoaXMucmVzdGFydCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgcmVtYWluID0gLTE7XHJcbiAgICBjbGVhclRpbWVvdXQodGltZXIpO1xyXG4gICAgdGhpcy5zdGFydCgpO1xyXG4gIH1cclxuXHJcbiAgdGhpcy5zdGFydCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgdGhpcy5pc1BhdXNlZCA9IGZhbHNlO1xyXG4gICAgLy8gaWYoIWVsZW0uZGF0YSgncGF1c2VkJykpeyByZXR1cm4gZmFsc2U7IH0vL21heWJlIGltcGxlbWVudCB0aGlzIHNhbml0eSBjaGVjayBpZiB1c2VkIGZvciBvdGhlciB0aGluZ3MuXHJcbiAgICBjbGVhclRpbWVvdXQodGltZXIpO1xyXG4gICAgcmVtYWluID0gcmVtYWluIDw9IDAgPyBkdXJhdGlvbiA6IHJlbWFpbjtcclxuICAgIGVsZW0uZGF0YSgncGF1c2VkJywgZmFsc2UpO1xyXG4gICAgc3RhcnQgPSBEYXRlLm5vdygpO1xyXG4gICAgdGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XHJcbiAgICAgIGlmKG9wdGlvbnMuaW5maW5pdGUpe1xyXG4gICAgICAgIF90aGlzLnJlc3RhcnQoKTsvL3JlcnVuIHRoZSB0aW1lci5cclxuICAgICAgfVxyXG4gICAgICBjYigpO1xyXG4gICAgfSwgcmVtYWluKTtcclxuICAgIGVsZW0udHJpZ2dlcihgdGltZXJzdGFydC56Zi4ke25hbWVTcGFjZX1gKTtcclxuICB9XHJcblxyXG4gIHRoaXMucGF1c2UgPSBmdW5jdGlvbigpIHtcclxuICAgIHRoaXMuaXNQYXVzZWQgPSB0cnVlO1xyXG4gICAgLy9pZihlbGVtLmRhdGEoJ3BhdXNlZCcpKXsgcmV0dXJuIGZhbHNlOyB9Ly9tYXliZSBpbXBsZW1lbnQgdGhpcyBzYW5pdHkgY2hlY2sgaWYgdXNlZCBmb3Igb3RoZXIgdGhpbmdzLlxyXG4gICAgY2xlYXJUaW1lb3V0KHRpbWVyKTtcclxuICAgIGVsZW0uZGF0YSgncGF1c2VkJywgdHJ1ZSk7XHJcbiAgICB2YXIgZW5kID0gRGF0ZS5ub3coKTtcclxuICAgIHJlbWFpbiA9IHJlbWFpbiAtIChlbmQgLSBzdGFydCk7XHJcbiAgICBlbGVtLnRyaWdnZXIoYHRpbWVycGF1c2VkLnpmLiR7bmFtZVNwYWNlfWApO1xyXG4gIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIFJ1bnMgYSBjYWxsYmFjayBmdW5jdGlvbiB3aGVuIGltYWdlcyBhcmUgZnVsbHkgbG9hZGVkLlxyXG4gKiBAcGFyYW0ge09iamVjdH0gaW1hZ2VzIC0gSW1hZ2UocykgdG8gY2hlY2sgaWYgbG9hZGVkLlxyXG4gKiBAcGFyYW0ge0Z1bmN9IGNhbGxiYWNrIC0gRnVuY3Rpb24gdG8gZXhlY3V0ZSB3aGVuIGltYWdlIGlzIGZ1bGx5IGxvYWRlZC5cclxuICovXHJcbmZ1bmN0aW9uIG9uSW1hZ2VzTG9hZGVkKGltYWdlcywgY2FsbGJhY2spe1xyXG4gIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgdW5sb2FkZWQgPSBpbWFnZXMubGVuZ3RoO1xyXG5cclxuICBpZiAodW5sb2FkZWQgPT09IDApIHtcclxuICAgIGNhbGxiYWNrKCk7XHJcbiAgfVxyXG5cclxuICBpbWFnZXMuZWFjaChmdW5jdGlvbigpIHtcclxuICAgIGlmICh0aGlzLmNvbXBsZXRlKSB7XHJcbiAgICAgIHNpbmdsZUltYWdlTG9hZGVkKCk7XHJcbiAgICB9XHJcbiAgICBlbHNlIGlmICh0eXBlb2YgdGhpcy5uYXR1cmFsV2lkdGggIT09ICd1bmRlZmluZWQnICYmIHRoaXMubmF0dXJhbFdpZHRoID4gMCkge1xyXG4gICAgICBzaW5nbGVJbWFnZUxvYWRlZCgpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgICQodGhpcykub25lKCdsb2FkJywgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgc2luZ2xlSW1hZ2VMb2FkZWQoKTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfSk7XHJcblxyXG4gIGZ1bmN0aW9uIHNpbmdsZUltYWdlTG9hZGVkKCkge1xyXG4gICAgdW5sb2FkZWQtLTtcclxuICAgIGlmICh1bmxvYWRlZCA9PT0gMCkge1xyXG4gICAgICBjYWxsYmFjaygpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuRm91bmRhdGlvbi5UaW1lciA9IFRpbWVyO1xyXG5Gb3VuZGF0aW9uLm9uSW1hZ2VzTG9hZGVkID0gb25JbWFnZXNMb2FkZWQ7XHJcblxyXG59KGpRdWVyeSk7XHJcbiIsIi8vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuLy8qKldvcmsgaW5zcGlyZWQgYnkgbXVsdGlwbGUganF1ZXJ5IHN3aXBlIHBsdWdpbnMqKlxyXG4vLyoqRG9uZSBieSBZb2hhaSBBcmFyYXQgKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcbi8vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuKGZ1bmN0aW9uKCQpIHtcclxuXHJcbiAgJC5zcG90U3dpcGUgPSB7XHJcbiAgICB2ZXJzaW9uOiAnMS4wLjAnLFxyXG4gICAgZW5hYmxlZDogJ29udG91Y2hzdGFydCcgaW4gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LFxyXG4gICAgcHJldmVudERlZmF1bHQ6IGZhbHNlLFxyXG4gICAgbW92ZVRocmVzaG9sZDogNzUsXHJcbiAgICB0aW1lVGhyZXNob2xkOiAyMDBcclxuICB9O1xyXG5cclxuICB2YXIgICBzdGFydFBvc1gsXHJcbiAgICAgICAgc3RhcnRQb3NZLFxyXG4gICAgICAgIHN0YXJ0VGltZSxcclxuICAgICAgICBlbGFwc2VkVGltZSxcclxuICAgICAgICBpc01vdmluZyA9IGZhbHNlO1xyXG5cclxuICBmdW5jdGlvbiBvblRvdWNoRW5kKCkge1xyXG4gICAgLy8gIGFsZXJ0KHRoaXMpO1xyXG4gICAgdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCd0b3VjaG1vdmUnLCBvblRvdWNoTW92ZSk7XHJcbiAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoZW5kJywgb25Ub3VjaEVuZCk7XHJcbiAgICBpc01vdmluZyA9IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gb25Ub3VjaE1vdmUoZSkge1xyXG4gICAgaWYgKCQuc3BvdFN3aXBlLnByZXZlbnREZWZhdWx0KSB7IGUucHJldmVudERlZmF1bHQoKTsgfVxyXG4gICAgaWYoaXNNb3ZpbmcpIHtcclxuICAgICAgdmFyIHggPSBlLnRvdWNoZXNbMF0ucGFnZVg7XHJcbiAgICAgIHZhciB5ID0gZS50b3VjaGVzWzBdLnBhZ2VZO1xyXG4gICAgICB2YXIgZHggPSBzdGFydFBvc1ggLSB4O1xyXG4gICAgICB2YXIgZHkgPSBzdGFydFBvc1kgLSB5O1xyXG4gICAgICB2YXIgZGlyO1xyXG4gICAgICBlbGFwc2VkVGltZSA9IG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gc3RhcnRUaW1lO1xyXG4gICAgICBpZihNYXRoLmFicyhkeCkgPj0gJC5zcG90U3dpcGUubW92ZVRocmVzaG9sZCAmJiBlbGFwc2VkVGltZSA8PSAkLnNwb3RTd2lwZS50aW1lVGhyZXNob2xkKSB7XHJcbiAgICAgICAgZGlyID0gZHggPiAwID8gJ2xlZnQnIDogJ3JpZ2h0JztcclxuICAgICAgfVxyXG4gICAgICAvLyBlbHNlIGlmKE1hdGguYWJzKGR5KSA+PSAkLnNwb3RTd2lwZS5tb3ZlVGhyZXNob2xkICYmIGVsYXBzZWRUaW1lIDw9ICQuc3BvdFN3aXBlLnRpbWVUaHJlc2hvbGQpIHtcclxuICAgICAgLy8gICBkaXIgPSBkeSA+IDAgPyAnZG93bicgOiAndXAnO1xyXG4gICAgICAvLyB9XHJcbiAgICAgIGlmKGRpcikge1xyXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICBvblRvdWNoRW5kLmNhbGwodGhpcyk7XHJcbiAgICAgICAgJCh0aGlzKS50cmlnZ2VyKCdzd2lwZScsIGRpcikudHJpZ2dlcihgc3dpcGUke2Rpcn1gKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gb25Ub3VjaFN0YXJ0KGUpIHtcclxuICAgIGlmIChlLnRvdWNoZXMubGVuZ3RoID09IDEpIHtcclxuICAgICAgc3RhcnRQb3NYID0gZS50b3VjaGVzWzBdLnBhZ2VYO1xyXG4gICAgICBzdGFydFBvc1kgPSBlLnRvdWNoZXNbMF0ucGFnZVk7XHJcbiAgICAgIGlzTW92aW5nID0gdHJ1ZTtcclxuICAgICAgc3RhcnRUaW1lID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcbiAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcigndG91Y2htb3ZlJywgb25Ub3VjaE1vdmUsIGZhbHNlKTtcclxuICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGVuZCcsIG9uVG91Y2hFbmQsIGZhbHNlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIGluaXQoKSB7XHJcbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIgJiYgdGhpcy5hZGRFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0Jywgb25Ub3VjaFN0YXJ0LCBmYWxzZSk7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiB0ZWFyZG93bigpIHtcclxuICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIG9uVG91Y2hTdGFydCk7XHJcbiAgfVxyXG5cclxuICAkLmV2ZW50LnNwZWNpYWwuc3dpcGUgPSB7IHNldHVwOiBpbml0IH07XHJcblxyXG4gICQuZWFjaChbJ2xlZnQnLCAndXAnLCAnZG93bicsICdyaWdodCddLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAkLmV2ZW50LnNwZWNpYWxbYHN3aXBlJHt0aGlzfWBdID0geyBzZXR1cDogZnVuY3Rpb24oKXtcclxuICAgICAgJCh0aGlzKS5vbignc3dpcGUnLCAkLm5vb3ApO1xyXG4gICAgfSB9O1xyXG4gIH0pO1xyXG59KShqUXVlcnkpO1xyXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG4gKiBNZXRob2QgZm9yIGFkZGluZyBwc3VlZG8gZHJhZyBldmVudHMgdG8gZWxlbWVudHMgKlxyXG4gKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xyXG4hZnVuY3Rpb24oJCl7XHJcbiAgJC5mbi5hZGRUb3VjaCA9IGZ1bmN0aW9uKCl7XHJcbiAgICB0aGlzLmVhY2goZnVuY3Rpb24oaSxlbCl7XHJcbiAgICAgICQoZWwpLmJpbmQoJ3RvdWNoc3RhcnQgdG91Y2htb3ZlIHRvdWNoZW5kIHRvdWNoY2FuY2VsJyxmdW5jdGlvbigpe1xyXG4gICAgICAgIC8vd2UgcGFzcyB0aGUgb3JpZ2luYWwgZXZlbnQgb2JqZWN0IGJlY2F1c2UgdGhlIGpRdWVyeSBldmVudFxyXG4gICAgICAgIC8vb2JqZWN0IGlzIG5vcm1hbGl6ZWQgdG8gdzNjIHNwZWNzIGFuZCBkb2VzIG5vdCBwcm92aWRlIHRoZSBUb3VjaExpc3RcclxuICAgICAgICBoYW5kbGVUb3VjaChldmVudCk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdmFyIGhhbmRsZVRvdWNoID0gZnVuY3Rpb24oZXZlbnQpe1xyXG4gICAgICB2YXIgdG91Y2hlcyA9IGV2ZW50LmNoYW5nZWRUb3VjaGVzLFxyXG4gICAgICAgICAgZmlyc3QgPSB0b3VjaGVzWzBdLFxyXG4gICAgICAgICAgZXZlbnRUeXBlcyA9IHtcclxuICAgICAgICAgICAgdG91Y2hzdGFydDogJ21vdXNlZG93bicsXHJcbiAgICAgICAgICAgIHRvdWNobW92ZTogJ21vdXNlbW92ZScsXHJcbiAgICAgICAgICAgIHRvdWNoZW5kOiAnbW91c2V1cCdcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICB0eXBlID0gZXZlbnRUeXBlc1tldmVudC50eXBlXSxcclxuICAgICAgICAgIHNpbXVsYXRlZEV2ZW50XHJcbiAgICAgICAgO1xyXG5cclxuICAgICAgaWYoJ01vdXNlRXZlbnQnIGluIHdpbmRvdyAmJiB0eXBlb2Ygd2luZG93Lk1vdXNlRXZlbnQgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICBzaW11bGF0ZWRFdmVudCA9IG5ldyB3aW5kb3cuTW91c2VFdmVudCh0eXBlLCB7XHJcbiAgICAgICAgICAnYnViYmxlcyc6IHRydWUsXHJcbiAgICAgICAgICAnY2FuY2VsYWJsZSc6IHRydWUsXHJcbiAgICAgICAgICAnc2NyZWVuWCc6IGZpcnN0LnNjcmVlblgsXHJcbiAgICAgICAgICAnc2NyZWVuWSc6IGZpcnN0LnNjcmVlblksXHJcbiAgICAgICAgICAnY2xpZW50WCc6IGZpcnN0LmNsaWVudFgsXHJcbiAgICAgICAgICAnY2xpZW50WSc6IGZpcnN0LmNsaWVudFlcclxuICAgICAgICB9KTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBzaW11bGF0ZWRFdmVudCA9IGRvY3VtZW50LmNyZWF0ZUV2ZW50KCdNb3VzZUV2ZW50Jyk7XHJcbiAgICAgICAgc2ltdWxhdGVkRXZlbnQuaW5pdE1vdXNlRXZlbnQodHlwZSwgdHJ1ZSwgdHJ1ZSwgd2luZG93LCAxLCBmaXJzdC5zY3JlZW5YLCBmaXJzdC5zY3JlZW5ZLCBmaXJzdC5jbGllbnRYLCBmaXJzdC5jbGllbnRZLCBmYWxzZSwgZmFsc2UsIGZhbHNlLCBmYWxzZSwgMC8qbGVmdCovLCBudWxsKTtcclxuICAgICAgfVxyXG4gICAgICBmaXJzdC50YXJnZXQuZGlzcGF0Y2hFdmVudChzaW11bGF0ZWRFdmVudCk7XHJcbiAgICB9O1xyXG4gIH07XHJcbn0oalF1ZXJ5KTtcclxuXHJcblxyXG4vLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcclxuLy8qKkZyb20gdGhlIGpRdWVyeSBNb2JpbGUgTGlicmFyeSoqXHJcbi8vKipuZWVkIHRvIHJlY3JlYXRlIGZ1bmN0aW9uYWxpdHkqKlxyXG4vLyoqYW5kIHRyeSB0byBpbXByb3ZlIGlmIHBvc3NpYmxlKipcclxuLy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcblxyXG4vKiBSZW1vdmluZyB0aGUgalF1ZXJ5IGZ1bmN0aW9uICoqKipcclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcblxyXG4oZnVuY3Rpb24oICQsIHdpbmRvdywgdW5kZWZpbmVkICkge1xyXG5cclxuXHR2YXIgJGRvY3VtZW50ID0gJCggZG9jdW1lbnQgKSxcclxuXHRcdC8vIHN1cHBvcnRUb3VjaCA9ICQubW9iaWxlLnN1cHBvcnQudG91Y2gsXHJcblx0XHR0b3VjaFN0YXJ0RXZlbnQgPSAndG91Y2hzdGFydCcvL3N1cHBvcnRUb3VjaCA/IFwidG91Y2hzdGFydFwiIDogXCJtb3VzZWRvd25cIixcclxuXHRcdHRvdWNoU3RvcEV2ZW50ID0gJ3RvdWNoZW5kJy8vc3VwcG9ydFRvdWNoID8gXCJ0b3VjaGVuZFwiIDogXCJtb3VzZXVwXCIsXHJcblx0XHR0b3VjaE1vdmVFdmVudCA9ICd0b3VjaG1vdmUnLy9zdXBwb3J0VG91Y2ggPyBcInRvdWNobW92ZVwiIDogXCJtb3VzZW1vdmVcIjtcclxuXHJcblx0Ly8gc2V0dXAgbmV3IGV2ZW50IHNob3J0Y3V0c1xyXG5cdCQuZWFjaCggKCBcInRvdWNoc3RhcnQgdG91Y2htb3ZlIHRvdWNoZW5kIFwiICtcclxuXHRcdFwic3dpcGUgc3dpcGVsZWZ0IHN3aXBlcmlnaHRcIiApLnNwbGl0KCBcIiBcIiApLCBmdW5jdGlvbiggaSwgbmFtZSApIHtcclxuXHJcblx0XHQkLmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggZm4gKSB7XHJcblx0XHRcdHJldHVybiBmbiA/IHRoaXMuYmluZCggbmFtZSwgZm4gKSA6IHRoaXMudHJpZ2dlciggbmFtZSApO1xyXG5cdFx0fTtcclxuXHJcblx0XHQvLyBqUXVlcnkgPCAxLjhcclxuXHRcdGlmICggJC5hdHRyRm4gKSB7XHJcblx0XHRcdCQuYXR0ckZuWyBuYW1lIF0gPSB0cnVlO1xyXG5cdFx0fVxyXG5cdH0pO1xyXG5cclxuXHRmdW5jdGlvbiB0cmlnZ2VyQ3VzdG9tRXZlbnQoIG9iaiwgZXZlbnRUeXBlLCBldmVudCwgYnViYmxlICkge1xyXG5cdFx0dmFyIG9yaWdpbmFsVHlwZSA9IGV2ZW50LnR5cGU7XHJcblx0XHRldmVudC50eXBlID0gZXZlbnRUeXBlO1xyXG5cdFx0aWYgKCBidWJibGUgKSB7XHJcblx0XHRcdCQuZXZlbnQudHJpZ2dlciggZXZlbnQsIHVuZGVmaW5lZCwgb2JqICk7XHJcblx0XHR9IGVsc2Uge1xyXG5cdFx0XHQkLmV2ZW50LmRpc3BhdGNoLmNhbGwoIG9iaiwgZXZlbnQgKTtcclxuXHRcdH1cclxuXHRcdGV2ZW50LnR5cGUgPSBvcmlnaW5hbFR5cGU7XHJcblx0fVxyXG5cclxuXHQvLyBhbHNvIGhhbmRsZXMgdGFwaG9sZFxyXG5cclxuXHQvLyBBbHNvIGhhbmRsZXMgc3dpcGVsZWZ0LCBzd2lwZXJpZ2h0XHJcblx0JC5ldmVudC5zcGVjaWFsLnN3aXBlID0ge1xyXG5cclxuXHRcdC8vIE1vcmUgdGhhbiB0aGlzIGhvcml6b250YWwgZGlzcGxhY2VtZW50LCBhbmQgd2Ugd2lsbCBzdXBwcmVzcyBzY3JvbGxpbmcuXHJcblx0XHRzY3JvbGxTdXByZXNzaW9uVGhyZXNob2xkOiAzMCxcclxuXHJcblx0XHQvLyBNb3JlIHRpbWUgdGhhbiB0aGlzLCBhbmQgaXQgaXNuJ3QgYSBzd2lwZS5cclxuXHRcdGR1cmF0aW9uVGhyZXNob2xkOiAxMDAwLFxyXG5cclxuXHRcdC8vIFN3aXBlIGhvcml6b250YWwgZGlzcGxhY2VtZW50IG11c3QgYmUgbW9yZSB0aGFuIHRoaXMuXHJcblx0XHRob3Jpem9udGFsRGlzdGFuY2VUaHJlc2hvbGQ6IHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvID49IDIgPyAxNSA6IDMwLFxyXG5cclxuXHRcdC8vIFN3aXBlIHZlcnRpY2FsIGRpc3BsYWNlbWVudCBtdXN0IGJlIGxlc3MgdGhhbiB0aGlzLlxyXG5cdFx0dmVydGljYWxEaXN0YW5jZVRocmVzaG9sZDogd2luZG93LmRldmljZVBpeGVsUmF0aW8gPj0gMiA/IDE1IDogMzAsXHJcblxyXG5cdFx0Z2V0TG9jYXRpb246IGZ1bmN0aW9uICggZXZlbnQgKSB7XHJcblx0XHRcdHZhciB3aW5QYWdlWCA9IHdpbmRvdy5wYWdlWE9mZnNldCxcclxuXHRcdFx0XHR3aW5QYWdlWSA9IHdpbmRvdy5wYWdlWU9mZnNldCxcclxuXHRcdFx0XHR4ID0gZXZlbnQuY2xpZW50WCxcclxuXHRcdFx0XHR5ID0gZXZlbnQuY2xpZW50WTtcclxuXHJcblx0XHRcdGlmICggZXZlbnQucGFnZVkgPT09IDAgJiYgTWF0aC5mbG9vciggeSApID4gTWF0aC5mbG9vciggZXZlbnQucGFnZVkgKSB8fFxyXG5cdFx0XHRcdGV2ZW50LnBhZ2VYID09PSAwICYmIE1hdGguZmxvb3IoIHggKSA+IE1hdGguZmxvb3IoIGV2ZW50LnBhZ2VYICkgKSB7XHJcblxyXG5cdFx0XHRcdC8vIGlPUzQgY2xpZW50WC9jbGllbnRZIGhhdmUgdGhlIHZhbHVlIHRoYXQgc2hvdWxkIGhhdmUgYmVlblxyXG5cdFx0XHRcdC8vIGluIHBhZ2VYL3BhZ2VZLiBXaGlsZSBwYWdlWC9wYWdlLyBoYXZlIHRoZSB2YWx1ZSAwXHJcblx0XHRcdFx0eCA9IHggLSB3aW5QYWdlWDtcclxuXHRcdFx0XHR5ID0geSAtIHdpblBhZ2VZO1xyXG5cdFx0XHR9IGVsc2UgaWYgKCB5IDwgKCBldmVudC5wYWdlWSAtIHdpblBhZ2VZKSB8fCB4IDwgKCBldmVudC5wYWdlWCAtIHdpblBhZ2VYICkgKSB7XHJcblxyXG5cdFx0XHRcdC8vIFNvbWUgQW5kcm9pZCBicm93c2VycyBoYXZlIHRvdGFsbHkgYm9ndXMgdmFsdWVzIGZvciBjbGllbnRYL1lcclxuXHRcdFx0XHQvLyB3aGVuIHNjcm9sbGluZy96b29taW5nIGEgcGFnZS4gRGV0ZWN0YWJsZSBzaW5jZSBjbGllbnRYL2NsaWVudFlcclxuXHRcdFx0XHQvLyBzaG91bGQgbmV2ZXIgYmUgc21hbGxlciB0aGFuIHBhZ2VYL3BhZ2VZIG1pbnVzIHBhZ2Ugc2Nyb2xsXHJcblx0XHRcdFx0eCA9IGV2ZW50LnBhZ2VYIC0gd2luUGFnZVg7XHJcblx0XHRcdFx0eSA9IGV2ZW50LnBhZ2VZIC0gd2luUGFnZVk7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHJldHVybiB7XHJcblx0XHRcdFx0eDogeCxcclxuXHRcdFx0XHR5OiB5XHJcblx0XHRcdH07XHJcblx0XHR9LFxyXG5cclxuXHRcdHN0YXJ0OiBmdW5jdGlvbiggZXZlbnQgKSB7XHJcblx0XHRcdHZhciBkYXRhID0gZXZlbnQub3JpZ2luYWxFdmVudC50b3VjaGVzID9cclxuXHRcdFx0XHRcdGV2ZW50Lm9yaWdpbmFsRXZlbnQudG91Y2hlc1sgMCBdIDogZXZlbnQsXHJcblx0XHRcdFx0bG9jYXRpb24gPSAkLmV2ZW50LnNwZWNpYWwuc3dpcGUuZ2V0TG9jYXRpb24oIGRhdGEgKTtcclxuXHRcdFx0cmV0dXJuIHtcclxuXHRcdFx0XHRcdFx0dGltZTogKCBuZXcgRGF0ZSgpICkuZ2V0VGltZSgpLFxyXG5cdFx0XHRcdFx0XHRjb29yZHM6IFsgbG9jYXRpb24ueCwgbG9jYXRpb24ueSBdLFxyXG5cdFx0XHRcdFx0XHRvcmlnaW46ICQoIGV2ZW50LnRhcmdldCApXHJcblx0XHRcdFx0XHR9O1xyXG5cdFx0fSxcclxuXHJcblx0XHRzdG9wOiBmdW5jdGlvbiggZXZlbnQgKSB7XHJcblx0XHRcdHZhciBkYXRhID0gZXZlbnQub3JpZ2luYWxFdmVudC50b3VjaGVzID9cclxuXHRcdFx0XHRcdGV2ZW50Lm9yaWdpbmFsRXZlbnQudG91Y2hlc1sgMCBdIDogZXZlbnQsXHJcblx0XHRcdFx0bG9jYXRpb24gPSAkLmV2ZW50LnNwZWNpYWwuc3dpcGUuZ2V0TG9jYXRpb24oIGRhdGEgKTtcclxuXHRcdFx0cmV0dXJuIHtcclxuXHRcdFx0XHRcdFx0dGltZTogKCBuZXcgRGF0ZSgpICkuZ2V0VGltZSgpLFxyXG5cdFx0XHRcdFx0XHRjb29yZHM6IFsgbG9jYXRpb24ueCwgbG9jYXRpb24ueSBdXHJcblx0XHRcdFx0XHR9O1xyXG5cdFx0fSxcclxuXHJcblx0XHRoYW5kbGVTd2lwZTogZnVuY3Rpb24oIHN0YXJ0LCBzdG9wLCB0aGlzT2JqZWN0LCBvcmlnVGFyZ2V0ICkge1xyXG5cdFx0XHRpZiAoIHN0b3AudGltZSAtIHN0YXJ0LnRpbWUgPCAkLmV2ZW50LnNwZWNpYWwuc3dpcGUuZHVyYXRpb25UaHJlc2hvbGQgJiZcclxuXHRcdFx0XHRNYXRoLmFicyggc3RhcnQuY29vcmRzWyAwIF0gLSBzdG9wLmNvb3Jkc1sgMCBdICkgPiAkLmV2ZW50LnNwZWNpYWwuc3dpcGUuaG9yaXpvbnRhbERpc3RhbmNlVGhyZXNob2xkICYmXHJcblx0XHRcdFx0TWF0aC5hYnMoIHN0YXJ0LmNvb3Jkc1sgMSBdIC0gc3RvcC5jb29yZHNbIDEgXSApIDwgJC5ldmVudC5zcGVjaWFsLnN3aXBlLnZlcnRpY2FsRGlzdGFuY2VUaHJlc2hvbGQgKSB7XHJcblx0XHRcdFx0dmFyIGRpcmVjdGlvbiA9IHN0YXJ0LmNvb3Jkc1swXSA+IHN0b3AuY29vcmRzWyAwIF0gPyBcInN3aXBlbGVmdFwiIDogXCJzd2lwZXJpZ2h0XCI7XHJcblxyXG5cdFx0XHRcdHRyaWdnZXJDdXN0b21FdmVudCggdGhpc09iamVjdCwgXCJzd2lwZVwiLCAkLkV2ZW50KCBcInN3aXBlXCIsIHsgdGFyZ2V0OiBvcmlnVGFyZ2V0LCBzd2lwZXN0YXJ0OiBzdGFydCwgc3dpcGVzdG9wOiBzdG9wIH0pLCB0cnVlICk7XHJcblx0XHRcdFx0dHJpZ2dlckN1c3RvbUV2ZW50KCB0aGlzT2JqZWN0LCBkaXJlY3Rpb24sJC5FdmVudCggZGlyZWN0aW9uLCB7IHRhcmdldDogb3JpZ1RhcmdldCwgc3dpcGVzdGFydDogc3RhcnQsIHN3aXBlc3RvcDogc3RvcCB9ICksIHRydWUgKTtcclxuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcclxuXHRcdFx0fVxyXG5cdFx0XHRyZXR1cm4gZmFsc2U7XHJcblxyXG5cdFx0fSxcclxuXHJcblx0XHQvLyBUaGlzIHNlcnZlcyBhcyBhIGZsYWcgdG8gZW5zdXJlIHRoYXQgYXQgbW9zdCBvbmUgc3dpcGUgZXZlbnQgZXZlbnQgaXNcclxuXHRcdC8vIGluIHdvcmsgYXQgYW55IGdpdmVuIHRpbWVcclxuXHRcdGV2ZW50SW5Qcm9ncmVzczogZmFsc2UsXHJcblxyXG5cdFx0c2V0dXA6IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHR2YXIgZXZlbnRzLFxyXG5cdFx0XHRcdHRoaXNPYmplY3QgPSB0aGlzLFxyXG5cdFx0XHRcdCR0aGlzID0gJCggdGhpc09iamVjdCApLFxyXG5cdFx0XHRcdGNvbnRleHQgPSB7fTtcclxuXHJcblx0XHRcdC8vIFJldHJpZXZlIHRoZSBldmVudHMgZGF0YSBmb3IgdGhpcyBlbGVtZW50IGFuZCBhZGQgdGhlIHN3aXBlIGNvbnRleHRcclxuXHRcdFx0ZXZlbnRzID0gJC5kYXRhKCB0aGlzLCBcIm1vYmlsZS1ldmVudHNcIiApO1xyXG5cdFx0XHRpZiAoICFldmVudHMgKSB7XHJcblx0XHRcdFx0ZXZlbnRzID0geyBsZW5ndGg6IDAgfTtcclxuXHRcdFx0XHQkLmRhdGEoIHRoaXMsIFwibW9iaWxlLWV2ZW50c1wiLCBldmVudHMgKTtcclxuXHRcdFx0fVxyXG5cdFx0XHRldmVudHMubGVuZ3RoKys7XHJcblx0XHRcdGV2ZW50cy5zd2lwZSA9IGNvbnRleHQ7XHJcblxyXG5cdFx0XHRjb250ZXh0LnN0YXJ0ID0gZnVuY3Rpb24oIGV2ZW50ICkge1xyXG5cclxuXHRcdFx0XHQvLyBCYWlsIGlmIHdlJ3JlIGFscmVhZHkgd29ya2luZyBvbiBhIHN3aXBlIGV2ZW50XHJcblx0XHRcdFx0aWYgKCAkLmV2ZW50LnNwZWNpYWwuc3dpcGUuZXZlbnRJblByb2dyZXNzICkge1xyXG5cdFx0XHRcdFx0cmV0dXJuO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHQkLmV2ZW50LnNwZWNpYWwuc3dpcGUuZXZlbnRJblByb2dyZXNzID0gdHJ1ZTtcclxuXHJcblx0XHRcdFx0dmFyIHN0b3AsXHJcblx0XHRcdFx0XHRzdGFydCA9ICQuZXZlbnQuc3BlY2lhbC5zd2lwZS5zdGFydCggZXZlbnQgKSxcclxuXHRcdFx0XHRcdG9yaWdUYXJnZXQgPSBldmVudC50YXJnZXQsXHJcblx0XHRcdFx0XHRlbWl0dGVkID0gZmFsc2U7XHJcblxyXG5cdFx0XHRcdGNvbnRleHQubW92ZSA9IGZ1bmN0aW9uKCBldmVudCApIHtcclxuXHRcdFx0XHRcdGlmICggIXN0YXJ0IHx8IGV2ZW50LmlzRGVmYXVsdFByZXZlbnRlZCgpICkge1xyXG5cdFx0XHRcdFx0XHRyZXR1cm47XHJcblx0XHRcdFx0XHR9XHJcblxyXG5cdFx0XHRcdFx0c3RvcCA9ICQuZXZlbnQuc3BlY2lhbC5zd2lwZS5zdG9wKCBldmVudCApO1xyXG5cdFx0XHRcdFx0aWYgKCAhZW1pdHRlZCApIHtcclxuXHRcdFx0XHRcdFx0ZW1pdHRlZCA9ICQuZXZlbnQuc3BlY2lhbC5zd2lwZS5oYW5kbGVTd2lwZSggc3RhcnQsIHN0b3AsIHRoaXNPYmplY3QsIG9yaWdUYXJnZXQgKTtcclxuXHRcdFx0XHRcdFx0aWYgKCBlbWl0dGVkICkge1xyXG5cclxuXHRcdFx0XHRcdFx0XHQvLyBSZXNldCB0aGUgY29udGV4dCB0byBtYWtlIHdheSBmb3IgdGhlIG5leHQgc3dpcGUgZXZlbnRcclxuXHRcdFx0XHRcdFx0XHQkLmV2ZW50LnNwZWNpYWwuc3dpcGUuZXZlbnRJblByb2dyZXNzID0gZmFsc2U7XHJcblx0XHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdH1cclxuXHRcdFx0XHRcdC8vIHByZXZlbnQgc2Nyb2xsaW5nXHJcblx0XHRcdFx0XHRpZiAoIE1hdGguYWJzKCBzdGFydC5jb29yZHNbIDAgXSAtIHN0b3AuY29vcmRzWyAwIF0gKSA+ICQuZXZlbnQuc3BlY2lhbC5zd2lwZS5zY3JvbGxTdXByZXNzaW9uVGhyZXNob2xkICkge1xyXG5cdFx0XHRcdFx0XHRldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cdFx0XHRcdFx0fVxyXG5cdFx0XHRcdH07XHJcblxyXG5cdFx0XHRcdGNvbnRleHQuc3RvcCA9IGZ1bmN0aW9uKCkge1xyXG5cdFx0XHRcdFx0XHRlbWl0dGVkID0gdHJ1ZTtcclxuXHJcblx0XHRcdFx0XHRcdC8vIFJlc2V0IHRoZSBjb250ZXh0IHRvIG1ha2Ugd2F5IGZvciB0aGUgbmV4dCBzd2lwZSBldmVudFxyXG5cdFx0XHRcdFx0XHQkLmV2ZW50LnNwZWNpYWwuc3dpcGUuZXZlbnRJblByb2dyZXNzID0gZmFsc2U7XHJcblx0XHRcdFx0XHRcdCRkb2N1bWVudC5vZmYoIHRvdWNoTW92ZUV2ZW50LCBjb250ZXh0Lm1vdmUgKTtcclxuXHRcdFx0XHRcdFx0Y29udGV4dC5tb3ZlID0gbnVsbDtcclxuXHRcdFx0XHR9O1xyXG5cclxuXHRcdFx0XHQkZG9jdW1lbnQub24oIHRvdWNoTW92ZUV2ZW50LCBjb250ZXh0Lm1vdmUgKVxyXG5cdFx0XHRcdFx0Lm9uZSggdG91Y2hTdG9wRXZlbnQsIGNvbnRleHQuc3RvcCApO1xyXG5cdFx0XHR9O1xyXG5cdFx0XHQkdGhpcy5vbiggdG91Y2hTdGFydEV2ZW50LCBjb250ZXh0LnN0YXJ0ICk7XHJcblx0XHR9LFxyXG5cclxuXHRcdHRlYXJkb3duOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0dmFyIGV2ZW50cywgY29udGV4dDtcclxuXHJcblx0XHRcdGV2ZW50cyA9ICQuZGF0YSggdGhpcywgXCJtb2JpbGUtZXZlbnRzXCIgKTtcclxuXHRcdFx0aWYgKCBldmVudHMgKSB7XHJcblx0XHRcdFx0Y29udGV4dCA9IGV2ZW50cy5zd2lwZTtcclxuXHRcdFx0XHRkZWxldGUgZXZlbnRzLnN3aXBlO1xyXG5cdFx0XHRcdGV2ZW50cy5sZW5ndGgtLTtcclxuXHRcdFx0XHRpZiAoIGV2ZW50cy5sZW5ndGggPT09IDAgKSB7XHJcblx0XHRcdFx0XHQkLnJlbW92ZURhdGEoIHRoaXMsIFwibW9iaWxlLWV2ZW50c1wiICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHR9XHJcblxyXG5cdFx0XHRpZiAoIGNvbnRleHQgKSB7XHJcblx0XHRcdFx0aWYgKCBjb250ZXh0LnN0YXJ0ICkge1xyXG5cdFx0XHRcdFx0JCggdGhpcyApLm9mZiggdG91Y2hTdGFydEV2ZW50LCBjb250ZXh0LnN0YXJ0ICk7XHJcblx0XHRcdFx0fVxyXG5cdFx0XHRcdGlmICggY29udGV4dC5tb3ZlICkge1xyXG5cdFx0XHRcdFx0JGRvY3VtZW50Lm9mZiggdG91Y2hNb3ZlRXZlbnQsIGNvbnRleHQubW92ZSApO1xyXG5cdFx0XHRcdH1cclxuXHRcdFx0XHRpZiAoIGNvbnRleHQuc3RvcCApIHtcclxuXHRcdFx0XHRcdCRkb2N1bWVudC5vZmYoIHRvdWNoU3RvcEV2ZW50LCBjb250ZXh0LnN0b3AgKTtcclxuXHRcdFx0XHR9XHJcblx0XHRcdH1cclxuXHRcdH1cclxuXHR9O1xyXG5cdCQuZWFjaCh7XHJcblx0XHRzd2lwZWxlZnQ6IFwic3dpcGUubGVmdFwiLFxyXG5cdFx0c3dpcGVyaWdodDogXCJzd2lwZS5yaWdodFwiXHJcblx0fSwgZnVuY3Rpb24oIGV2ZW50LCBzb3VyY2VFdmVudCApIHtcclxuXHJcblx0XHQkLmV2ZW50LnNwZWNpYWxbIGV2ZW50IF0gPSB7XHJcblx0XHRcdHNldHVwOiBmdW5jdGlvbigpIHtcclxuXHRcdFx0XHQkKCB0aGlzICkuYmluZCggc291cmNlRXZlbnQsICQubm9vcCApO1xyXG5cdFx0XHR9LFxyXG5cdFx0XHR0ZWFyZG93bjogZnVuY3Rpb24oKSB7XHJcblx0XHRcdFx0JCggdGhpcyApLnVuYmluZCggc291cmNlRXZlbnQgKTtcclxuXHRcdFx0fVxyXG5cdFx0fTtcclxuXHR9KTtcclxufSkoIGpRdWVyeSwgdGhpcyApO1xyXG4qL1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG4hZnVuY3Rpb24oJCkge1xyXG5cclxuY29uc3QgTXV0YXRpb25PYnNlcnZlciA9IChmdW5jdGlvbiAoKSB7XHJcbiAgdmFyIHByZWZpeGVzID0gWydXZWJLaXQnLCAnTW96JywgJ08nLCAnTXMnLCAnJ107XHJcbiAgZm9yICh2YXIgaT0wOyBpIDwgcHJlZml4ZXMubGVuZ3RoOyBpKyspIHtcclxuICAgIGlmIChgJHtwcmVmaXhlc1tpXX1NdXRhdGlvbk9ic2VydmVyYCBpbiB3aW5kb3cpIHtcclxuICAgICAgcmV0dXJuIHdpbmRvd1tgJHtwcmVmaXhlc1tpXX1NdXRhdGlvbk9ic2VydmVyYF07XHJcbiAgICB9XHJcbiAgfVxyXG4gIHJldHVybiBmYWxzZTtcclxufSgpKTtcclxuXHJcbmNvbnN0IHRyaWdnZXJzID0gKGVsLCB0eXBlKSA9PiB7XHJcbiAgZWwuZGF0YSh0eXBlKS5zcGxpdCgnICcpLmZvckVhY2goaWQgPT4ge1xyXG4gICAgJChgIyR7aWR9YClbIHR5cGUgPT09ICdjbG9zZScgPyAndHJpZ2dlcicgOiAndHJpZ2dlckhhbmRsZXInXShgJHt0eXBlfS56Zi50cmlnZ2VyYCwgW2VsXSk7XHJcbiAgfSk7XHJcbn07XHJcbi8vIEVsZW1lbnRzIHdpdGggW2RhdGEtb3Blbl0gd2lsbCByZXZlYWwgYSBwbHVnaW4gdGhhdCBzdXBwb3J0cyBpdCB3aGVuIGNsaWNrZWQuXHJcbiQoZG9jdW1lbnQpLm9uKCdjbGljay56Zi50cmlnZ2VyJywgJ1tkYXRhLW9wZW5dJywgZnVuY3Rpb24oKSB7XHJcbiAgdHJpZ2dlcnMoJCh0aGlzKSwgJ29wZW4nKTtcclxufSk7XHJcblxyXG4vLyBFbGVtZW50cyB3aXRoIFtkYXRhLWNsb3NlXSB3aWxsIGNsb3NlIGEgcGx1Z2luIHRoYXQgc3VwcG9ydHMgaXQgd2hlbiBjbGlja2VkLlxyXG4vLyBJZiB1c2VkIHdpdGhvdXQgYSB2YWx1ZSBvbiBbZGF0YS1jbG9zZV0sIHRoZSBldmVudCB3aWxsIGJ1YmJsZSwgYWxsb3dpbmcgaXQgdG8gY2xvc2UgYSBwYXJlbnQgY29tcG9uZW50LlxyXG4kKGRvY3VtZW50KS5vbignY2xpY2suemYudHJpZ2dlcicsICdbZGF0YS1jbG9zZV0nLCBmdW5jdGlvbigpIHtcclxuICBsZXQgaWQgPSAkKHRoaXMpLmRhdGEoJ2Nsb3NlJyk7XHJcbiAgaWYgKGlkKSB7XHJcbiAgICB0cmlnZ2VycygkKHRoaXMpLCAnY2xvc2UnKTtcclxuICB9XHJcbiAgZWxzZSB7XHJcbiAgICAkKHRoaXMpLnRyaWdnZXIoJ2Nsb3NlLnpmLnRyaWdnZXInKTtcclxuICB9XHJcbn0pO1xyXG5cclxuLy8gRWxlbWVudHMgd2l0aCBbZGF0YS10b2dnbGVdIHdpbGwgdG9nZ2xlIGEgcGx1Z2luIHRoYXQgc3VwcG9ydHMgaXQgd2hlbiBjbGlja2VkLlxyXG4kKGRvY3VtZW50KS5vbignY2xpY2suemYudHJpZ2dlcicsICdbZGF0YS10b2dnbGVdJywgZnVuY3Rpb24oKSB7XHJcbiAgdHJpZ2dlcnMoJCh0aGlzKSwgJ3RvZ2dsZScpO1xyXG59KTtcclxuXHJcbi8vIEVsZW1lbnRzIHdpdGggW2RhdGEtY2xvc2FibGVdIHdpbGwgcmVzcG9uZCB0byBjbG9zZS56Zi50cmlnZ2VyIGV2ZW50cy5cclxuJChkb2N1bWVudCkub24oJ2Nsb3NlLnpmLnRyaWdnZXInLCAnW2RhdGEtY2xvc2FibGVdJywgZnVuY3Rpb24oZSl7XHJcbiAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICBsZXQgYW5pbWF0aW9uID0gJCh0aGlzKS5kYXRhKCdjbG9zYWJsZScpO1xyXG5cclxuICBpZihhbmltYXRpb24gIT09ICcnKXtcclxuICAgIEZvdW5kYXRpb24uTW90aW9uLmFuaW1hdGVPdXQoJCh0aGlzKSwgYW5pbWF0aW9uLCBmdW5jdGlvbigpIHtcclxuICAgICAgJCh0aGlzKS50cmlnZ2VyKCdjbG9zZWQuemYnKTtcclxuICAgIH0pO1xyXG4gIH1lbHNle1xyXG4gICAgJCh0aGlzKS5mYWRlT3V0KCkudHJpZ2dlcignY2xvc2VkLnpmJyk7XHJcbiAgfVxyXG59KTtcclxuXHJcbiQoZG9jdW1lbnQpLm9uKCdmb2N1cy56Zi50cmlnZ2VyIGJsdXIuemYudHJpZ2dlcicsICdbZGF0YS10b2dnbGUtZm9jdXNdJywgZnVuY3Rpb24oKSB7XHJcbiAgbGV0IGlkID0gJCh0aGlzKS5kYXRhKCd0b2dnbGUtZm9jdXMnKTtcclxuICAkKGAjJHtpZH1gKS50cmlnZ2VySGFuZGxlcigndG9nZ2xlLnpmLnRyaWdnZXInLCBbJCh0aGlzKV0pO1xyXG59KTtcclxuXHJcbi8qKlxyXG4qIEZpcmVzIG9uY2UgYWZ0ZXIgYWxsIG90aGVyIHNjcmlwdHMgaGF2ZSBsb2FkZWRcclxuKiBAZnVuY3Rpb25cclxuKiBAcHJpdmF0ZVxyXG4qL1xyXG4kKHdpbmRvdykubG9hZCgoKSA9PiB7XHJcbiAgY2hlY2tMaXN0ZW5lcnMoKTtcclxufSk7XHJcblxyXG5mdW5jdGlvbiBjaGVja0xpc3RlbmVycygpIHtcclxuICBldmVudHNMaXN0ZW5lcigpO1xyXG4gIHJlc2l6ZUxpc3RlbmVyKCk7XHJcbiAgc2Nyb2xsTGlzdGVuZXIoKTtcclxuICBjbG9zZW1lTGlzdGVuZXIoKTtcclxufVxyXG5cclxuLy8qKioqKioqKiBvbmx5IGZpcmVzIHRoaXMgZnVuY3Rpb24gb25jZSBvbiBsb2FkLCBpZiB0aGVyZSdzIHNvbWV0aGluZyB0byB3YXRjaCAqKioqKioqKlxyXG5mdW5jdGlvbiBjbG9zZW1lTGlzdGVuZXIocGx1Z2luTmFtZSkge1xyXG4gIHZhciB5ZXRpQm94ZXMgPSAkKCdbZGF0YS15ZXRpLWJveF0nKSxcclxuICAgICAgcGx1Z05hbWVzID0gWydkcm9wZG93bicsICd0b29sdGlwJywgJ3JldmVhbCddO1xyXG5cclxuICBpZihwbHVnaW5OYW1lKXtcclxuICAgIGlmKHR5cGVvZiBwbHVnaW5OYW1lID09PSAnc3RyaW5nJyl7XHJcbiAgICAgIHBsdWdOYW1lcy5wdXNoKHBsdWdpbk5hbWUpO1xyXG4gICAgfWVsc2UgaWYodHlwZW9mIHBsdWdpbk5hbWUgPT09ICdvYmplY3QnICYmIHR5cGVvZiBwbHVnaW5OYW1lWzBdID09PSAnc3RyaW5nJyl7XHJcbiAgICAgIHBsdWdOYW1lcy5jb25jYXQocGx1Z2luTmFtZSk7XHJcbiAgICB9ZWxzZXtcclxuICAgICAgY29uc29sZS5lcnJvcignUGx1Z2luIG5hbWVzIG11c3QgYmUgc3RyaW5ncycpO1xyXG4gICAgfVxyXG4gIH1cclxuICBpZih5ZXRpQm94ZXMubGVuZ3RoKXtcclxuICAgIGxldCBsaXN0ZW5lcnMgPSBwbHVnTmFtZXMubWFwKChuYW1lKSA9PiB7XHJcbiAgICAgIHJldHVybiBgY2xvc2VtZS56Zi4ke25hbWV9YDtcclxuICAgIH0pLmpvaW4oJyAnKTtcclxuXHJcbiAgICAkKHdpbmRvdykub2ZmKGxpc3RlbmVycykub24obGlzdGVuZXJzLCBmdW5jdGlvbihlLCBwbHVnaW5JZCl7XHJcbiAgICAgIGxldCBwbHVnaW4gPSBlLm5hbWVzcGFjZS5zcGxpdCgnLicpWzBdO1xyXG4gICAgICBsZXQgcGx1Z2lucyA9ICQoYFtkYXRhLSR7cGx1Z2lufV1gKS5ub3QoYFtkYXRhLXlldGktYm94PVwiJHtwbHVnaW5JZH1cIl1gKTtcclxuXHJcbiAgICAgIHBsdWdpbnMuZWFjaChmdW5jdGlvbigpe1xyXG4gICAgICAgIGxldCBfdGhpcyA9ICQodGhpcyk7XHJcblxyXG4gICAgICAgIF90aGlzLnRyaWdnZXJIYW5kbGVyKCdjbG9zZS56Zi50cmlnZ2VyJywgW190aGlzXSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG59XHJcblxyXG5mdW5jdGlvbiByZXNpemVMaXN0ZW5lcihkZWJvdW5jZSl7XHJcbiAgbGV0IHRpbWVyLFxyXG4gICAgICAkbm9kZXMgPSAkKCdbZGF0YS1yZXNpemVdJyk7XHJcbiAgaWYoJG5vZGVzLmxlbmd0aCl7XHJcbiAgICAkKHdpbmRvdykub2ZmKCdyZXNpemUuemYudHJpZ2dlcicpXHJcbiAgICAub24oJ3Jlc2l6ZS56Zi50cmlnZ2VyJywgZnVuY3Rpb24oZSkge1xyXG4gICAgICBpZiAodGltZXIpIHsgY2xlYXJUaW1lb3V0KHRpbWVyKTsgfVxyXG5cclxuICAgICAgdGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XHJcblxyXG4gICAgICAgIGlmKCFNdXRhdGlvbk9ic2VydmVyKXsvL2ZhbGxiYWNrIGZvciBJRSA5XHJcbiAgICAgICAgICAkbm9kZXMuZWFjaChmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICAkKHRoaXMpLnRyaWdnZXJIYW5kbGVyKCdyZXNpemVtZS56Zi50cmlnZ2VyJyk7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy90cmlnZ2VyIGFsbCBsaXN0ZW5pbmcgZWxlbWVudHMgYW5kIHNpZ25hbCBhIHJlc2l6ZSBldmVudFxyXG4gICAgICAgICRub2Rlcy5hdHRyKCdkYXRhLWV2ZW50cycsIFwicmVzaXplXCIpO1xyXG4gICAgICB9LCBkZWJvdW5jZSB8fCAxMCk7Ly9kZWZhdWx0IHRpbWUgdG8gZW1pdCByZXNpemUgZXZlbnRcclxuICAgIH0pO1xyXG4gIH1cclxufVxyXG5cclxuZnVuY3Rpb24gc2Nyb2xsTGlzdGVuZXIoZGVib3VuY2Upe1xyXG4gIGxldCB0aW1lcixcclxuICAgICAgJG5vZGVzID0gJCgnW2RhdGEtc2Nyb2xsXScpO1xyXG4gIGlmKCRub2Rlcy5sZW5ndGgpe1xyXG4gICAgJCh3aW5kb3cpLm9mZignc2Nyb2xsLnpmLnRyaWdnZXInKVxyXG4gICAgLm9uKCdzY3JvbGwuemYudHJpZ2dlcicsIGZ1bmN0aW9uKGUpe1xyXG4gICAgICBpZih0aW1lcil7IGNsZWFyVGltZW91dCh0aW1lcik7IH1cclxuXHJcbiAgICAgIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpe1xyXG5cclxuICAgICAgICBpZighTXV0YXRpb25PYnNlcnZlcil7Ly9mYWxsYmFjayBmb3IgSUUgOVxyXG4gICAgICAgICAgJG5vZGVzLmVhY2goZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgJCh0aGlzKS50cmlnZ2VySGFuZGxlcignc2Nyb2xsbWUuemYudHJpZ2dlcicpO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vdHJpZ2dlciBhbGwgbGlzdGVuaW5nIGVsZW1lbnRzIGFuZCBzaWduYWwgYSBzY3JvbGwgZXZlbnRcclxuICAgICAgICAkbm9kZXMuYXR0cignZGF0YS1ldmVudHMnLCBcInNjcm9sbFwiKTtcclxuICAgICAgfSwgZGVib3VuY2UgfHwgMTApOy8vZGVmYXVsdCB0aW1lIHRvIGVtaXQgc2Nyb2xsIGV2ZW50XHJcbiAgICB9KTtcclxuICB9XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGV2ZW50c0xpc3RlbmVyKCkge1xyXG4gIGlmKCFNdXRhdGlvbk9ic2VydmVyKXsgcmV0dXJuIGZhbHNlOyB9XHJcbiAgbGV0IG5vZGVzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnW2RhdGEtcmVzaXplXSwgW2RhdGEtc2Nyb2xsXSwgW2RhdGEtbXV0YXRlXScpO1xyXG5cclxuICAvL2VsZW1lbnQgY2FsbGJhY2tcclxuICB2YXIgbGlzdGVuaW5nRWxlbWVudHNNdXRhdGlvbiA9IGZ1bmN0aW9uKG11dGF0aW9uUmVjb3Jkc0xpc3QpIHtcclxuICAgIHZhciAkdGFyZ2V0ID0gJChtdXRhdGlvblJlY29yZHNMaXN0WzBdLnRhcmdldCk7XHJcbiAgICAvL3RyaWdnZXIgdGhlIGV2ZW50IGhhbmRsZXIgZm9yIHRoZSBlbGVtZW50IGRlcGVuZGluZyBvbiB0eXBlXHJcbiAgICBzd2l0Y2ggKCR0YXJnZXQuYXR0cihcImRhdGEtZXZlbnRzXCIpKSB7XHJcblxyXG4gICAgICBjYXNlIFwicmVzaXplXCIgOlxyXG4gICAgICAkdGFyZ2V0LnRyaWdnZXJIYW5kbGVyKCdyZXNpemVtZS56Zi50cmlnZ2VyJywgWyR0YXJnZXRdKTtcclxuICAgICAgYnJlYWs7XHJcblxyXG4gICAgICBjYXNlIFwic2Nyb2xsXCIgOlxyXG4gICAgICAkdGFyZ2V0LnRyaWdnZXJIYW5kbGVyKCdzY3JvbGxtZS56Zi50cmlnZ2VyJywgWyR0YXJnZXQsIHdpbmRvdy5wYWdlWU9mZnNldF0pO1xyXG4gICAgICBicmVhaztcclxuXHJcbiAgICAgIC8vIGNhc2UgXCJtdXRhdGVcIiA6XHJcbiAgICAgIC8vIGNvbnNvbGUubG9nKCdtdXRhdGUnLCAkdGFyZ2V0KTtcclxuICAgICAgLy8gJHRhcmdldC50cmlnZ2VySGFuZGxlcignbXV0YXRlLnpmLnRyaWdnZXInKTtcclxuICAgICAgLy9cclxuICAgICAgLy8gLy9tYWtlIHN1cmUgd2UgZG9uJ3QgZ2V0IHN0dWNrIGluIGFuIGluZmluaXRlIGxvb3AgZnJvbSBzbG9wcHkgY29kZWluZ1xyXG4gICAgICAvLyBpZiAoJHRhcmdldC5pbmRleCgnW2RhdGEtbXV0YXRlXScpID09ICQoXCJbZGF0YS1tdXRhdGVdXCIpLmxlbmd0aC0xKSB7XHJcbiAgICAgIC8vICAgZG9tTXV0YXRpb25PYnNlcnZlcigpO1xyXG4gICAgICAvLyB9XHJcbiAgICAgIC8vIGJyZWFrO1xyXG5cclxuICAgICAgZGVmYXVsdCA6XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgLy9ub3RoaW5nXHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBpZihub2Rlcy5sZW5ndGgpe1xyXG4gICAgLy9mb3IgZWFjaCBlbGVtZW50IHRoYXQgbmVlZHMgdG8gbGlzdGVuIGZvciByZXNpemluZywgc2Nyb2xsaW5nLCAob3IgY29taW5nIHNvb24gbXV0YXRpb24pIGFkZCBhIHNpbmdsZSBvYnNlcnZlclxyXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPD0gbm9kZXMubGVuZ3RoLTE7IGkrKykge1xyXG4gICAgICBsZXQgZWxlbWVudE9ic2VydmVyID0gbmV3IE11dGF0aW9uT2JzZXJ2ZXIobGlzdGVuaW5nRWxlbWVudHNNdXRhdGlvbik7XHJcbiAgICAgIGVsZW1lbnRPYnNlcnZlci5vYnNlcnZlKG5vZGVzW2ldLCB7IGF0dHJpYnV0ZXM6IHRydWUsIGNoaWxkTGlzdDogZmFsc2UsIGNoYXJhY3RlckRhdGE6IGZhbHNlLCBzdWJ0cmVlOmZhbHNlLCBhdHRyaWJ1dGVGaWx0ZXI6W1wiZGF0YS1ldmVudHNcIl19KTtcclxuICAgIH1cclxuICB9XHJcbn1cclxuXHJcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuLy8gW1BIXVxyXG4vLyBGb3VuZGF0aW9uLkNoZWNrV2F0Y2hlcnMgPSBjaGVja1dhdGNoZXJzO1xyXG5Gb3VuZGF0aW9uLklIZWFyWW91ID0gY2hlY2tMaXN0ZW5lcnM7XHJcbi8vIEZvdW5kYXRpb24uSVNlZVlvdSA9IHNjcm9sbExpc3RlbmVyO1xyXG4vLyBGb3VuZGF0aW9uLklGZWVsWW91ID0gY2xvc2VtZUxpc3RlbmVyO1xyXG5cclxufShqUXVlcnkpO1xyXG5cclxuLy8gZnVuY3Rpb24gZG9tTXV0YXRpb25PYnNlcnZlcihkZWJvdW5jZSkge1xyXG4vLyAgIC8vICEhISBUaGlzIGlzIGNvbWluZyBzb29uIGFuZCBuZWVkcyBtb3JlIHdvcms7IG5vdCBhY3RpdmUgICEhISAvL1xyXG4vLyAgIHZhciB0aW1lcixcclxuLy8gICBub2RlcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJ1tkYXRhLW11dGF0ZV0nKTtcclxuLy8gICAvL1xyXG4vLyAgIGlmIChub2Rlcy5sZW5ndGgpIHtcclxuLy8gICAgIC8vIHZhciBNdXRhdGlvbk9ic2VydmVyID0gKGZ1bmN0aW9uICgpIHtcclxuLy8gICAgIC8vICAgdmFyIHByZWZpeGVzID0gWydXZWJLaXQnLCAnTW96JywgJ08nLCAnTXMnLCAnJ107XHJcbi8vICAgICAvLyAgIGZvciAodmFyIGk9MDsgaSA8IHByZWZpeGVzLmxlbmd0aDsgaSsrKSB7XHJcbi8vICAgICAvLyAgICAgaWYgKHByZWZpeGVzW2ldICsgJ011dGF0aW9uT2JzZXJ2ZXInIGluIHdpbmRvdykge1xyXG4vLyAgICAgLy8gICAgICAgcmV0dXJuIHdpbmRvd1twcmVmaXhlc1tpXSArICdNdXRhdGlvbk9ic2VydmVyJ107XHJcbi8vICAgICAvLyAgICAgfVxyXG4vLyAgICAgLy8gICB9XHJcbi8vICAgICAvLyAgIHJldHVybiBmYWxzZTtcclxuLy8gICAgIC8vIH0oKSk7XHJcbi8vXHJcbi8vXHJcbi8vICAgICAvL2ZvciB0aGUgYm9keSwgd2UgbmVlZCB0byBsaXN0ZW4gZm9yIGFsbCBjaGFuZ2VzIGVmZmVjdGluZyB0aGUgc3R5bGUgYW5kIGNsYXNzIGF0dHJpYnV0ZXNcclxuLy8gICAgIHZhciBib2R5T2JzZXJ2ZXIgPSBuZXcgTXV0YXRpb25PYnNlcnZlcihib2R5TXV0YXRpb24pO1xyXG4vLyAgICAgYm9keU9ic2VydmVyLm9ic2VydmUoZG9jdW1lbnQuYm9keSwgeyBhdHRyaWJ1dGVzOiB0cnVlLCBjaGlsZExpc3Q6IHRydWUsIGNoYXJhY3RlckRhdGE6IGZhbHNlLCBzdWJ0cmVlOnRydWUsIGF0dHJpYnV0ZUZpbHRlcjpbXCJzdHlsZVwiLCBcImNsYXNzXCJdfSk7XHJcbi8vXHJcbi8vXHJcbi8vICAgICAvL2JvZHkgY2FsbGJhY2tcclxuLy8gICAgIGZ1bmN0aW9uIGJvZHlNdXRhdGlvbihtdXRhdGUpIHtcclxuLy8gICAgICAgLy90cmlnZ2VyIGFsbCBsaXN0ZW5pbmcgZWxlbWVudHMgYW5kIHNpZ25hbCBhIG11dGF0aW9uIGV2ZW50XHJcbi8vICAgICAgIGlmICh0aW1lcikgeyBjbGVhclRpbWVvdXQodGltZXIpOyB9XHJcbi8vXHJcbi8vICAgICAgIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpIHtcclxuLy8gICAgICAgICBib2R5T2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xyXG4vLyAgICAgICAgICQoJ1tkYXRhLW11dGF0ZV0nKS5hdHRyKCdkYXRhLWV2ZW50cycsXCJtdXRhdGVcIik7XHJcbi8vICAgICAgIH0sIGRlYm91bmNlIHx8IDE1MCk7XHJcbi8vICAgICB9XHJcbi8vICAgfVxyXG4vLyB9XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbiFmdW5jdGlvbigkKSB7XHJcblxyXG4vKipcclxuICogQWJpZGUgbW9kdWxlLlxyXG4gKiBAbW9kdWxlIGZvdW5kYXRpb24uYWJpZGVcclxuICovXHJcblxyXG5jbGFzcyBBYmlkZSB7XHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBBYmlkZS5cclxuICAgKiBAY2xhc3NcclxuICAgKiBAZmlyZXMgQWJpZGUjaW5pdFxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbGVtZW50IC0galF1ZXJ5IG9iamVjdCB0byBhZGQgdGhlIHRyaWdnZXIgdG8uXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBPdmVycmlkZXMgdG8gdGhlIGRlZmF1bHQgcGx1Z2luIHNldHRpbmdzLlxyXG4gICAqL1xyXG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQsIG9wdGlvbnMgPSB7fSkge1xyXG4gICAgdGhpcy4kZWxlbWVudCA9IGVsZW1lbnQ7XHJcbiAgICB0aGlzLm9wdGlvbnMgID0gJC5leHRlbmQoe30sIEFiaWRlLmRlZmF1bHRzLCB0aGlzLiRlbGVtZW50LmRhdGEoKSwgb3B0aW9ucyk7XHJcblxyXG4gICAgdGhpcy5faW5pdCgpO1xyXG5cclxuICAgIEZvdW5kYXRpb24ucmVnaXN0ZXJQbHVnaW4odGhpcywgJ0FiaWRlJyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbml0aWFsaXplcyB0aGUgQWJpZGUgcGx1Z2luIGFuZCBjYWxscyBmdW5jdGlvbnMgdG8gZ2V0IEFiaWRlIGZ1bmN0aW9uaW5nIG9uIGxvYWQuXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfaW5pdCgpIHtcclxuICAgIHRoaXMuJGlucHV0cyA9IHRoaXMuJGVsZW1lbnQuZmluZCgnaW5wdXQsIHRleHRhcmVhLCBzZWxlY3QnKTtcclxuXHJcbiAgICB0aGlzLl9ldmVudHMoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpYWxpemVzIGV2ZW50cyBmb3IgQWJpZGUuXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfZXZlbnRzKCkge1xyXG4gICAgdGhpcy4kZWxlbWVudC5vZmYoJy5hYmlkZScpXHJcbiAgICAgIC5vbigncmVzZXQuemYuYWJpZGUnLCAoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5yZXNldEZvcm0oKTtcclxuICAgICAgfSlcclxuICAgICAgLm9uKCdzdWJtaXQuemYuYWJpZGUnLCAoKSA9PiB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsaWRhdGVGb3JtKCk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMudmFsaWRhdGVPbiA9PT0gJ2ZpZWxkQ2hhbmdlJykge1xyXG4gICAgICB0aGlzLiRpbnB1dHNcclxuICAgICAgICAub2ZmKCdjaGFuZ2UuemYuYWJpZGUnKVxyXG4gICAgICAgIC5vbignY2hhbmdlLnpmLmFiaWRlJywgKGUpID0+IHtcclxuICAgICAgICAgIHRoaXMudmFsaWRhdGVJbnB1dCgkKGUudGFyZ2V0KSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5saXZlVmFsaWRhdGUpIHtcclxuICAgICAgdGhpcy4kaW5wdXRzXHJcbiAgICAgICAgLm9mZignaW5wdXQuemYuYWJpZGUnKVxyXG4gICAgICAgIC5vbignaW5wdXQuemYuYWJpZGUnLCAoZSkgPT4ge1xyXG4gICAgICAgICAgdGhpcy52YWxpZGF0ZUlucHV0KCQoZS50YXJnZXQpKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENhbGxzIG5lY2Vzc2FyeSBmdW5jdGlvbnMgdG8gdXBkYXRlIEFiaWRlIHVwb24gRE9NIGNoYW5nZVxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX3JlZmxvdygpIHtcclxuICAgIHRoaXMuX2luaXQoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENoZWNrcyB3aGV0aGVyIG9yIG5vdCBhIGZvcm0gZWxlbWVudCBoYXMgdGhlIHJlcXVpcmVkIGF0dHJpYnV0ZSBhbmQgaWYgaXQncyBjaGVja2VkIG9yIG5vdFxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbGVtZW50IC0galF1ZXJ5IG9iamVjdCB0byBjaGVjayBmb3IgcmVxdWlyZWQgYXR0cmlidXRlXHJcbiAgICogQHJldHVybnMge0Jvb2xlYW59IEJvb2xlYW4gdmFsdWUgZGVwZW5kcyBvbiB3aGV0aGVyIG9yIG5vdCBhdHRyaWJ1dGUgaXMgY2hlY2tlZCBvciBlbXB0eVxyXG4gICAqL1xyXG4gIHJlcXVpcmVkQ2hlY2soJGVsKSB7XHJcbiAgICBpZiAoISRlbC5hdHRyKCdyZXF1aXJlZCcpKSByZXR1cm4gdHJ1ZTtcclxuXHJcbiAgICB2YXIgaXNHb29kID0gdHJ1ZTtcclxuXHJcbiAgICBzd2l0Y2ggKCRlbFswXS50eXBlKSB7XHJcbiAgICAgIGNhc2UgJ2NoZWNrYm94JzpcclxuICAgICAgICBpc0dvb2QgPSAkZWxbMF0uY2hlY2tlZDtcclxuICAgICAgICBicmVhaztcclxuXHJcbiAgICAgIGNhc2UgJ3NlbGVjdCc6XHJcbiAgICAgIGNhc2UgJ3NlbGVjdC1vbmUnOlxyXG4gICAgICBjYXNlICdzZWxlY3QtbXVsdGlwbGUnOlxyXG4gICAgICAgIHZhciBvcHQgPSAkZWwuZmluZCgnb3B0aW9uOnNlbGVjdGVkJyk7XHJcbiAgICAgICAgaWYgKCFvcHQubGVuZ3RoIHx8ICFvcHQudmFsKCkpIGlzR29vZCA9IGZhbHNlO1xyXG4gICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgZGVmYXVsdDpcclxuICAgICAgICBpZighJGVsLnZhbCgpIHx8ICEkZWwudmFsKCkubGVuZ3RoKSBpc0dvb2QgPSBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gaXNHb29kO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQmFzZWQgb24gJGVsLCBnZXQgdGhlIGZpcnN0IGVsZW1lbnQgd2l0aCBzZWxlY3RvciBpbiB0aGlzIG9yZGVyOlxyXG4gICAqIDEuIFRoZSBlbGVtZW50J3MgZGlyZWN0IHNpYmxpbmcoJ3MpLlxyXG4gICAqIDMuIFRoZSBlbGVtZW50J3MgcGFyZW50J3MgY2hpbGRyZW4uXHJcbiAgICpcclxuICAgKiBUaGlzIGFsbG93cyBmb3IgbXVsdGlwbGUgZm9ybSBlcnJvcnMgcGVyIGlucHV0LCB0aG91Z2ggaWYgbm9uZSBhcmUgZm91bmQsIG5vIGZvcm0gZXJyb3JzIHdpbGwgYmUgc2hvd24uXHJcbiAgICpcclxuICAgKiBAcGFyYW0ge09iamVjdH0gJGVsIC0galF1ZXJ5IG9iamVjdCB0byB1c2UgYXMgcmVmZXJlbmNlIHRvIGZpbmQgdGhlIGZvcm0gZXJyb3Igc2VsZWN0b3IuXHJcbiAgICogQHJldHVybnMge09iamVjdH0galF1ZXJ5IG9iamVjdCB3aXRoIHRoZSBzZWxlY3Rvci5cclxuICAgKi9cclxuICBmaW5kRm9ybUVycm9yKCRlbCkge1xyXG4gICAgdmFyICRlcnJvciA9ICRlbC5zaWJsaW5ncyh0aGlzLm9wdGlvbnMuZm9ybUVycm9yU2VsZWN0b3IpO1xyXG5cclxuICAgIGlmICghJGVycm9yLmxlbmd0aCkge1xyXG4gICAgICAkZXJyb3IgPSAkZWwucGFyZW50KCkuZmluZCh0aGlzLm9wdGlvbnMuZm9ybUVycm9yU2VsZWN0b3IpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiAkZXJyb3I7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhpcyBvcmRlcjpcclxuICAgKiAyLiBUaGUgPGxhYmVsPiB3aXRoIHRoZSBhdHRyaWJ1dGUgYFtmb3I9XCJzb21lSW5wdXRJZFwiXWBcclxuICAgKiAzLiBUaGUgYC5jbG9zZXN0KClgIDxsYWJlbD5cclxuICAgKlxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSAkZWwgLSBqUXVlcnkgb2JqZWN0IHRvIGNoZWNrIGZvciByZXF1aXJlZCBhdHRyaWJ1dGVcclxuICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gQm9vbGVhbiB2YWx1ZSBkZXBlbmRzIG9uIHdoZXRoZXIgb3Igbm90IGF0dHJpYnV0ZSBpcyBjaGVja2VkIG9yIGVtcHR5XHJcbiAgICovXHJcbiAgZmluZExhYmVsKCRlbCkge1xyXG4gICAgdmFyIGlkID0gJGVsWzBdLmlkO1xyXG4gICAgdmFyICRsYWJlbCA9IHRoaXMuJGVsZW1lbnQuZmluZChgbGFiZWxbZm9yPVwiJHtpZH1cIl1gKTtcclxuXHJcbiAgICBpZiAoISRsYWJlbC5sZW5ndGgpIHtcclxuICAgICAgcmV0dXJuICRlbC5jbG9zZXN0KCdsYWJlbCcpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiAkbGFiZWw7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXQgdGhlIHNldCBvZiBsYWJlbHMgYXNzb2NpYXRlZCB3aXRoIGEgc2V0IG9mIHJhZGlvIGVscyBpbiB0aGlzIG9yZGVyXHJcbiAgICogMi4gVGhlIDxsYWJlbD4gd2l0aCB0aGUgYXR0cmlidXRlIGBbZm9yPVwic29tZUlucHV0SWRcIl1gXHJcbiAgICogMy4gVGhlIGAuY2xvc2VzdCgpYCA8bGFiZWw+XHJcbiAgICpcclxuICAgKiBAcGFyYW0ge09iamVjdH0gJGVsIC0galF1ZXJ5IG9iamVjdCB0byBjaGVjayBmb3IgcmVxdWlyZWQgYXR0cmlidXRlXHJcbiAgICogQHJldHVybnMge0Jvb2xlYW59IEJvb2xlYW4gdmFsdWUgZGVwZW5kcyBvbiB3aGV0aGVyIG9yIG5vdCBhdHRyaWJ1dGUgaXMgY2hlY2tlZCBvciBlbXB0eVxyXG4gICAqL1xyXG4gIGZpbmRSYWRpb0xhYmVscygkZWxzKSB7XHJcbiAgICB2YXIgbGFiZWxzID0gJGVscy5tYXAoKGksIGVsKSA9PiB7XHJcbiAgICAgIHZhciBpZCA9IGVsLmlkO1xyXG4gICAgICB2YXIgJGxhYmVsID0gdGhpcy4kZWxlbWVudC5maW5kKGBsYWJlbFtmb3I9XCIke2lkfVwiXWApO1xyXG5cclxuICAgICAgaWYgKCEkbGFiZWwubGVuZ3RoKSB7XHJcbiAgICAgICAgJGxhYmVsID0gJChlbCkuY2xvc2VzdCgnbGFiZWwnKTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gJGxhYmVsWzBdO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuICQobGFiZWxzKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZHMgdGhlIENTUyBlcnJvciBjbGFzcyBhcyBzcGVjaWZpZWQgYnkgdGhlIEFiaWRlIHNldHRpbmdzIHRvIHRoZSBsYWJlbCwgaW5wdXQsIGFuZCB0aGUgZm9ybVxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSAkZWwgLSBqUXVlcnkgb2JqZWN0IHRvIGFkZCB0aGUgY2xhc3MgdG9cclxuICAgKi9cclxuICBhZGRFcnJvckNsYXNzZXMoJGVsKSB7XHJcbiAgICB2YXIgJGxhYmVsID0gdGhpcy5maW5kTGFiZWwoJGVsKTtcclxuICAgIHZhciAkZm9ybUVycm9yID0gdGhpcy5maW5kRm9ybUVycm9yKCRlbCk7XHJcblxyXG4gICAgaWYgKCRsYWJlbC5sZW5ndGgpIHtcclxuICAgICAgJGxhYmVsLmFkZENsYXNzKHRoaXMub3B0aW9ucy5sYWJlbEVycm9yQ2xhc3MpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICgkZm9ybUVycm9yLmxlbmd0aCkge1xyXG4gICAgICAkZm9ybUVycm9yLmFkZENsYXNzKHRoaXMub3B0aW9ucy5mb3JtRXJyb3JDbGFzcyk7XHJcbiAgICB9XHJcblxyXG4gICAgJGVsLmFkZENsYXNzKHRoaXMub3B0aW9ucy5pbnB1dEVycm9yQ2xhc3MpLmF0dHIoJ2RhdGEtaW52YWxpZCcsICcnKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlbW92ZSBDU1MgZXJyb3IgY2xhc3NlcyBldGMgZnJvbSBhbiBlbnRpcmUgcmFkaW8gYnV0dG9uIGdyb3VwXHJcbiAgICogQHBhcmFtIHtTdHJpbmd9IGdyb3VwTmFtZSAtIEEgc3RyaW5nIHRoYXQgc3BlY2lmaWVzIHRoZSBuYW1lIG9mIGEgcmFkaW8gYnV0dG9uIGdyb3VwXHJcbiAgICpcclxuICAgKi9cclxuXHJcbiAgcmVtb3ZlUmFkaW9FcnJvckNsYXNzZXMoZ3JvdXBOYW1lKSB7XHJcbiAgICB2YXIgJGVscyA9IHRoaXMuJGVsZW1lbnQuZmluZChgOnJhZGlvW25hbWU9XCIke2dyb3VwTmFtZX1cIl1gKTtcclxuICAgIHZhciAkbGFiZWxzID0gdGhpcy5maW5kUmFkaW9MYWJlbHMoJGVscyk7XHJcbiAgICB2YXIgJGZvcm1FcnJvcnMgPSB0aGlzLmZpbmRGb3JtRXJyb3IoJGVscyk7XHJcblxyXG4gICAgaWYgKCRsYWJlbHMubGVuZ3RoKSB7XHJcbiAgICAgICRsYWJlbHMucmVtb3ZlQ2xhc3ModGhpcy5vcHRpb25zLmxhYmVsRXJyb3JDbGFzcyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCRmb3JtRXJyb3JzLmxlbmd0aCkge1xyXG4gICAgICAkZm9ybUVycm9ycy5yZW1vdmVDbGFzcyh0aGlzLm9wdGlvbnMuZm9ybUVycm9yQ2xhc3MpO1xyXG4gICAgfVxyXG5cclxuICAgICRlbHMucmVtb3ZlQ2xhc3ModGhpcy5vcHRpb25zLmlucHV0RXJyb3JDbGFzcykucmVtb3ZlQXR0cignZGF0YS1pbnZhbGlkJyk7XHJcblxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVtb3ZlcyBDU1MgZXJyb3IgY2xhc3MgYXMgc3BlY2lmaWVkIGJ5IHRoZSBBYmlkZSBzZXR0aW5ncyBmcm9tIHRoZSBsYWJlbCwgaW5wdXQsIGFuZCB0aGUgZm9ybVxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSAkZWwgLSBqUXVlcnkgb2JqZWN0IHRvIHJlbW92ZSB0aGUgY2xhc3MgZnJvbVxyXG4gICAqL1xyXG4gIHJlbW92ZUVycm9yQ2xhc3NlcygkZWwpIHtcclxuICAgIC8vIHJhZGlvcyBuZWVkIHRvIGNsZWFyIGFsbCBvZiB0aGUgZWxzXHJcbiAgICBpZigkZWxbMF0udHlwZSA9PSAncmFkaW8nKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLnJlbW92ZVJhZGlvRXJyb3JDbGFzc2VzKCRlbC5hdHRyKCduYW1lJykpO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciAkbGFiZWwgPSB0aGlzLmZpbmRMYWJlbCgkZWwpO1xyXG4gICAgdmFyICRmb3JtRXJyb3IgPSB0aGlzLmZpbmRGb3JtRXJyb3IoJGVsKTtcclxuXHJcbiAgICBpZiAoJGxhYmVsLmxlbmd0aCkge1xyXG4gICAgICAkbGFiZWwucmVtb3ZlQ2xhc3ModGhpcy5vcHRpb25zLmxhYmVsRXJyb3JDbGFzcyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCRmb3JtRXJyb3IubGVuZ3RoKSB7XHJcbiAgICAgICRmb3JtRXJyb3IucmVtb3ZlQ2xhc3ModGhpcy5vcHRpb25zLmZvcm1FcnJvckNsYXNzKTtcclxuICAgIH1cclxuXHJcbiAgICAkZWwucmVtb3ZlQ2xhc3ModGhpcy5vcHRpb25zLmlucHV0RXJyb3JDbGFzcykucmVtb3ZlQXR0cignZGF0YS1pbnZhbGlkJyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHb2VzIHRocm91Z2ggYSBmb3JtIHRvIGZpbmQgaW5wdXRzIGFuZCBwcm9jZWVkcyB0byB2YWxpZGF0ZSB0aGVtIGluIHdheXMgc3BlY2lmaWMgdG8gdGhlaXIgdHlwZVxyXG4gICAqIEBmaXJlcyBBYmlkZSNpbnZhbGlkXHJcbiAgICogQGZpcmVzIEFiaWRlI3ZhbGlkXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IGVsZW1lbnQgLSBqUXVlcnkgb2JqZWN0IHRvIHZhbGlkYXRlLCBzaG91bGQgYmUgYW4gSFRNTCBpbnB1dFxyXG4gICAqIEByZXR1cm5zIHtCb29sZWFufSBnb29kVG9HbyAtIElmIHRoZSBpbnB1dCBpcyB2YWxpZCBvciBub3QuXHJcbiAgICovXHJcbiAgdmFsaWRhdGVJbnB1dCgkZWwpIHtcclxuICAgIHZhciBjbGVhclJlcXVpcmUgPSB0aGlzLnJlcXVpcmVkQ2hlY2soJGVsKSxcclxuICAgICAgICB2YWxpZGF0ZWQgPSBmYWxzZSxcclxuICAgICAgICBjdXN0b21WYWxpZGF0b3IgPSB0cnVlLFxyXG4gICAgICAgIHZhbGlkYXRvciA9ICRlbC5hdHRyKCdkYXRhLXZhbGlkYXRvcicpLFxyXG4gICAgICAgIGVxdWFsVG8gPSB0cnVlO1xyXG5cclxuICAgIC8vIGRvbid0IHZhbGlkYXRlIGlnbm9yZWQgaW5wdXRzIG9yIGhpZGRlbiBpbnB1dHNcclxuICAgIGlmICgkZWwuaXMoJ1tkYXRhLWFiaWRlLWlnbm9yZV0nKSB8fCAkZWwuaXMoJ1t0eXBlPVwiaGlkZGVuXCJdJykpIHtcclxuICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICB9XHJcblxyXG4gICAgc3dpdGNoICgkZWxbMF0udHlwZSkge1xyXG4gICAgICBjYXNlICdyYWRpbyc6XHJcbiAgICAgICAgdmFsaWRhdGVkID0gdGhpcy52YWxpZGF0ZVJhZGlvKCRlbC5hdHRyKCduYW1lJykpO1xyXG4gICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgY2FzZSAnY2hlY2tib3gnOlxyXG4gICAgICAgIHZhbGlkYXRlZCA9IGNsZWFyUmVxdWlyZTtcclxuICAgICAgICBicmVhaztcclxuXHJcbiAgICAgIGNhc2UgJ3NlbGVjdCc6XHJcbiAgICAgIGNhc2UgJ3NlbGVjdC1vbmUnOlxyXG4gICAgICBjYXNlICdzZWxlY3QtbXVsdGlwbGUnOlxyXG4gICAgICAgIHZhbGlkYXRlZCA9IGNsZWFyUmVxdWlyZTtcclxuICAgICAgICBicmVhaztcclxuXHJcbiAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgdmFsaWRhdGVkID0gdGhpcy52YWxpZGF0ZVRleHQoJGVsKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodmFsaWRhdG9yKSB7XHJcbiAgICAgIGN1c3RvbVZhbGlkYXRvciA9IHRoaXMubWF0Y2hWYWxpZGF0aW9uKCRlbCwgdmFsaWRhdG9yLCAkZWwuYXR0cigncmVxdWlyZWQnKSk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCRlbC5hdHRyKCdkYXRhLWVxdWFsdG8nKSkge1xyXG4gICAgICBlcXVhbFRvID0gdGhpcy5vcHRpb25zLnZhbGlkYXRvcnMuZXF1YWxUbygkZWwpO1xyXG4gICAgfVxyXG5cclxuXHJcbiAgICB2YXIgZ29vZFRvR28gPSBbY2xlYXJSZXF1aXJlLCB2YWxpZGF0ZWQsIGN1c3RvbVZhbGlkYXRvciwgZXF1YWxUb10uaW5kZXhPZihmYWxzZSkgPT09IC0xO1xyXG4gICAgdmFyIG1lc3NhZ2UgPSAoZ29vZFRvR28gPyAndmFsaWQnIDogJ2ludmFsaWQnKSArICcuemYuYWJpZGUnO1xyXG5cclxuICAgIHRoaXNbZ29vZFRvR28gPyAncmVtb3ZlRXJyb3JDbGFzc2VzJyA6ICdhZGRFcnJvckNsYXNzZXMnXSgkZWwpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZXMgd2hlbiB0aGUgaW5wdXQgaXMgZG9uZSBjaGVja2luZyBmb3IgdmFsaWRhdGlvbi4gRXZlbnQgdHJpZ2dlciBpcyBlaXRoZXIgYHZhbGlkLnpmLmFiaWRlYCBvciBgaW52YWxpZC56Zi5hYmlkZWBcclxuICAgICAqIFRyaWdnZXIgaW5jbHVkZXMgdGhlIERPTSBlbGVtZW50IG9mIHRoZSBpbnB1dC5cclxuICAgICAqIEBldmVudCBBYmlkZSN2YWxpZFxyXG4gICAgICogQGV2ZW50IEFiaWRlI2ludmFsaWRcclxuICAgICAqL1xyXG4gICAgJGVsLnRyaWdnZXIobWVzc2FnZSwgWyRlbF0pO1xyXG5cclxuICAgIHJldHVybiBnb29kVG9HbztcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdvZXMgdGhyb3VnaCBhIGZvcm0gYW5kIGlmIHRoZXJlIGFyZSBhbnkgaW52YWxpZCBpbnB1dHMsIGl0IHdpbGwgZGlzcGxheSB0aGUgZm9ybSBlcnJvciBlbGVtZW50XHJcbiAgICogQHJldHVybnMge0Jvb2xlYW59IG5vRXJyb3IgLSB0cnVlIGlmIG5vIGVycm9ycyB3ZXJlIGRldGVjdGVkLi4uXHJcbiAgICogQGZpcmVzIEFiaWRlI2Zvcm12YWxpZFxyXG4gICAqIEBmaXJlcyBBYmlkZSNmb3JtaW52YWxpZFxyXG4gICAqL1xyXG4gIHZhbGlkYXRlRm9ybSgpIHtcclxuICAgIHZhciBhY2MgPSBbXTtcclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcblxyXG4gICAgdGhpcy4kaW5wdXRzLmVhY2goZnVuY3Rpb24oKSB7XHJcbiAgICAgIGFjYy5wdXNoKF90aGlzLnZhbGlkYXRlSW5wdXQoJCh0aGlzKSkpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgdmFyIG5vRXJyb3IgPSBhY2MuaW5kZXhPZihmYWxzZSkgPT09IC0xO1xyXG5cclxuICAgIHRoaXMuJGVsZW1lbnQuZmluZCgnW2RhdGEtYWJpZGUtZXJyb3JdJykuY3NzKCdkaXNwbGF5JywgKG5vRXJyb3IgPyAnbm9uZScgOiAnYmxvY2snKSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlcyB3aGVuIHRoZSBmb3JtIGlzIGZpbmlzaGVkIHZhbGlkYXRpbmcuIEV2ZW50IHRyaWdnZXIgaXMgZWl0aGVyIGBmb3JtdmFsaWQuemYuYWJpZGVgIG9yIGBmb3JtaW52YWxpZC56Zi5hYmlkZWAuXHJcbiAgICAgKiBUcmlnZ2VyIGluY2x1ZGVzIHRoZSBlbGVtZW50IG9mIHRoZSBmb3JtLlxyXG4gICAgICogQGV2ZW50IEFiaWRlI2Zvcm12YWxpZFxyXG4gICAgICogQGV2ZW50IEFiaWRlI2Zvcm1pbnZhbGlkXHJcbiAgICAgKi9cclxuICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcigobm9FcnJvciA/ICdmb3JtdmFsaWQnIDogJ2Zvcm1pbnZhbGlkJykgKyAnLnpmLmFiaWRlJywgW3RoaXMuJGVsZW1lbnRdKTtcclxuXHJcbiAgICByZXR1cm4gbm9FcnJvcjtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERldGVybWluZXMgd2hldGhlciBvciBhIG5vdCBhIHRleHQgaW5wdXQgaXMgdmFsaWQgYmFzZWQgb24gdGhlIHBhdHRlcm4gc3BlY2lmaWVkIGluIHRoZSBhdHRyaWJ1dGUuIElmIG5vIG1hdGNoaW5nIHBhdHRlcm4gaXMgZm91bmQsIHJldHVybnMgdHJ1ZS5cclxuICAgKiBAcGFyYW0ge09iamVjdH0gJGVsIC0galF1ZXJ5IG9iamVjdCB0byB2YWxpZGF0ZSwgc2hvdWxkIGJlIGEgdGV4dCBpbnB1dCBIVE1MIGVsZW1lbnRcclxuICAgKiBAcGFyYW0ge1N0cmluZ30gcGF0dGVybiAtIHN0cmluZyB2YWx1ZSBvZiBvbmUgb2YgdGhlIFJlZ0V4IHBhdHRlcm5zIGluIEFiaWRlLm9wdGlvbnMucGF0dGVybnNcclxuICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gQm9vbGVhbiB2YWx1ZSBkZXBlbmRzIG9uIHdoZXRoZXIgb3Igbm90IHRoZSBpbnB1dCB2YWx1ZSBtYXRjaGVzIHRoZSBwYXR0ZXJuIHNwZWNpZmllZFxyXG4gICAqL1xyXG4gIHZhbGlkYXRlVGV4dCgkZWwsIHBhdHRlcm4pIHtcclxuICAgIC8vIEEgcGF0dGVybiBjYW4gYmUgcGFzc2VkIHRvIHRoaXMgZnVuY3Rpb24sIG9yIGl0IHdpbGwgYmUgaW5mZXJlZCBmcm9tIHRoZSBpbnB1dCdzIFwicGF0dGVyblwiIGF0dHJpYnV0ZSwgb3IgaXQncyBcInR5cGVcIiBhdHRyaWJ1dGVcclxuICAgIHBhdHRlcm4gPSAocGF0dGVybiB8fCAkZWwuYXR0cigncGF0dGVybicpIHx8ICRlbC5hdHRyKCd0eXBlJykpO1xyXG4gICAgdmFyIGlucHV0VGV4dCA9ICRlbC52YWwoKTtcclxuICAgIHZhciB2YWxpZCA9IGZhbHNlO1xyXG5cclxuICAgIGlmIChpbnB1dFRleHQubGVuZ3RoKSB7XHJcbiAgICAgIC8vIElmIHRoZSBwYXR0ZXJuIGF0dHJpYnV0ZSBvbiB0aGUgZWxlbWVudCBpcyBpbiBBYmlkZSdzIGxpc3Qgb2YgcGF0dGVybnMsIHRoZW4gdGVzdCB0aGF0IHJlZ2V4cFxyXG4gICAgICBpZiAodGhpcy5vcHRpb25zLnBhdHRlcm5zLmhhc093blByb3BlcnR5KHBhdHRlcm4pKSB7XHJcbiAgICAgICAgdmFsaWQgPSB0aGlzLm9wdGlvbnMucGF0dGVybnNbcGF0dGVybl0udGVzdChpbnB1dFRleHQpO1xyXG4gICAgICB9XHJcbiAgICAgIC8vIElmIHRoZSBwYXR0ZXJuIG5hbWUgaXNuJ3QgYWxzbyB0aGUgdHlwZSBhdHRyaWJ1dGUgb2YgdGhlIGZpZWxkLCB0aGVuIHRlc3QgaXQgYXMgYSByZWdleHBcclxuICAgICAgZWxzZSBpZiAocGF0dGVybiAhPT0gJGVsLmF0dHIoJ3R5cGUnKSkge1xyXG4gICAgICAgIHZhbGlkID0gbmV3IFJlZ0V4cChwYXR0ZXJuKS50ZXN0KGlucHV0VGV4dCk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSB7XHJcbiAgICAgICAgdmFsaWQgPSB0cnVlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvLyBBbiBlbXB0eSBmaWVsZCBpcyB2YWxpZCBpZiBpdCdzIG5vdCByZXF1aXJlZFxyXG4gICAgZWxzZSBpZiAoISRlbC5wcm9wKCdyZXF1aXJlZCcpKSB7XHJcbiAgICAgIHZhbGlkID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gdmFsaWQ7XHJcbiAgIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIG9yIGEgbm90IGEgcmFkaW8gaW5wdXQgaXMgdmFsaWQgYmFzZWQgb24gd2hldGhlciBvciBub3QgaXQgaXMgcmVxdWlyZWQgYW5kIHNlbGVjdGVkLiBBbHRob3VnaCB0aGUgZnVuY3Rpb24gdGFyZ2V0cyBhIHNpbmdsZSBgPGlucHV0PmAsIGl0IHZhbGlkYXRlcyBieSBjaGVja2luZyB0aGUgYHJlcXVpcmVkYCBhbmQgYGNoZWNrZWRgIHByb3BlcnRpZXMgb2YgYWxsIHJhZGlvIGJ1dHRvbnMgaW4gaXRzIGdyb3VwLlxyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBncm91cE5hbWUgLSBBIHN0cmluZyB0aGF0IHNwZWNpZmllcyB0aGUgbmFtZSBvZiBhIHJhZGlvIGJ1dHRvbiBncm91cFxyXG4gICAqIEByZXR1cm5zIHtCb29sZWFufSBCb29sZWFuIHZhbHVlIGRlcGVuZHMgb24gd2hldGhlciBvciBub3QgYXQgbGVhc3Qgb25lIHJhZGlvIGlucHV0IGhhcyBiZWVuIHNlbGVjdGVkIChpZiBpdCdzIHJlcXVpcmVkKVxyXG4gICAqL1xyXG4gIHZhbGlkYXRlUmFkaW8oZ3JvdXBOYW1lKSB7XHJcbiAgICAvLyBJZiBhdCBsZWFzdCBvbmUgcmFkaW8gaW4gdGhlIGdyb3VwIGhhcyB0aGUgYHJlcXVpcmVkYCBhdHRyaWJ1dGUsIHRoZSBncm91cCBpcyBjb25zaWRlcmVkIHJlcXVpcmVkXHJcbiAgICAvLyBQZXIgVzNDIHNwZWMsIGFsbCByYWRpbyBidXR0b25zIGluIGEgZ3JvdXAgc2hvdWxkIGhhdmUgYHJlcXVpcmVkYCwgYnV0IHdlJ3JlIGJlaW5nIG5pY2VcclxuICAgIHZhciAkZ3JvdXAgPSB0aGlzLiRlbGVtZW50LmZpbmQoYDpyYWRpb1tuYW1lPVwiJHtncm91cE5hbWV9XCJdYCk7XHJcbiAgICB2YXIgdmFsaWQgPSBmYWxzZSwgcmVxdWlyZWQgPSBmYWxzZTtcclxuXHJcbiAgICAvLyBGb3IgdGhlIGdyb3VwIHRvIGJlIHJlcXVpcmVkLCBhdCBsZWFzdCBvbmUgcmFkaW8gbmVlZHMgdG8gYmUgcmVxdWlyZWRcclxuICAgICRncm91cC5lYWNoKChpLCBlKSA9PiB7XHJcbiAgICAgIGlmICgkKGUpLmF0dHIoJ3JlcXVpcmVkJykpIHtcclxuICAgICAgICByZXF1aXJlZCA9IHRydWU7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgaWYoIXJlcXVpcmVkKSB2YWxpZD10cnVlO1xyXG5cclxuICAgIGlmICghdmFsaWQpIHtcclxuICAgICAgLy8gRm9yIHRoZSBncm91cCB0byBiZSB2YWxpZCwgYXQgbGVhc3Qgb25lIHJhZGlvIG5lZWRzIHRvIGJlIGNoZWNrZWRcclxuICAgICAgJGdyb3VwLmVhY2goKGksIGUpID0+IHtcclxuICAgICAgICBpZiAoJChlKS5wcm9wKCdjaGVja2VkJykpIHtcclxuICAgICAgICAgIHZhbGlkID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4gdmFsaWQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBEZXRlcm1pbmVzIGlmIGEgc2VsZWN0ZWQgaW5wdXQgcGFzc2VzIGEgY3VzdG9tIHZhbGlkYXRpb24gZnVuY3Rpb24uIE11bHRpcGxlIHZhbGlkYXRpb25zIGNhbiBiZSB1c2VkLCBpZiBwYXNzZWQgdG8gdGhlIGVsZW1lbnQgd2l0aCBgZGF0YS12YWxpZGF0b3I9XCJmb28gYmFyIGJhelwiYCBpbiBhIHNwYWNlIHNlcGFyYXRlZCBsaXN0ZWQuXHJcbiAgICogQHBhcmFtIHtPYmplY3R9ICRlbCAtIGpRdWVyeSBpbnB1dCBlbGVtZW50LlxyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSB2YWxpZGF0b3JzIC0gYSBzdHJpbmcgb2YgZnVuY3Rpb24gbmFtZXMgbWF0Y2hpbmcgZnVuY3Rpb25zIGluIHRoZSBBYmlkZS5vcHRpb25zLnZhbGlkYXRvcnMgb2JqZWN0LlxyXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gcmVxdWlyZWQgLSBzZWxmIGV4cGxhbmF0b3J5P1xyXG4gICAqIEByZXR1cm5zIHtCb29sZWFufSAtIHRydWUgaWYgdmFsaWRhdGlvbnMgcGFzc2VkLlxyXG4gICAqL1xyXG4gIG1hdGNoVmFsaWRhdGlvbigkZWwsIHZhbGlkYXRvcnMsIHJlcXVpcmVkKSB7XHJcbiAgICByZXF1aXJlZCA9IHJlcXVpcmVkID8gdHJ1ZSA6IGZhbHNlO1xyXG5cclxuICAgIHZhciBjbGVhciA9IHZhbGlkYXRvcnMuc3BsaXQoJyAnKS5tYXAoKHYpID0+IHtcclxuICAgICAgcmV0dXJuIHRoaXMub3B0aW9ucy52YWxpZGF0b3JzW3ZdKCRlbCwgcmVxdWlyZWQsICRlbC5wYXJlbnQoKSk7XHJcbiAgICB9KTtcclxuICAgIHJldHVybiBjbGVhci5pbmRleE9mKGZhbHNlKSA9PT0gLTE7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBSZXNldHMgZm9ybSBpbnB1dHMgYW5kIHN0eWxlc1xyXG4gICAqIEBmaXJlcyBBYmlkZSNmb3JtcmVzZXRcclxuICAgKi9cclxuICByZXNldEZvcm0oKSB7XHJcbiAgICB2YXIgJGZvcm0gPSB0aGlzLiRlbGVtZW50LFxyXG4gICAgICAgIG9wdHMgPSB0aGlzLm9wdGlvbnM7XHJcblxyXG4gICAgJChgLiR7b3B0cy5sYWJlbEVycm9yQ2xhc3N9YCwgJGZvcm0pLm5vdCgnc21hbGwnKS5yZW1vdmVDbGFzcyhvcHRzLmxhYmVsRXJyb3JDbGFzcyk7XHJcbiAgICAkKGAuJHtvcHRzLmlucHV0RXJyb3JDbGFzc31gLCAkZm9ybSkubm90KCdzbWFsbCcpLnJlbW92ZUNsYXNzKG9wdHMuaW5wdXRFcnJvckNsYXNzKTtcclxuICAgICQoYCR7b3B0cy5mb3JtRXJyb3JTZWxlY3Rvcn0uJHtvcHRzLmZvcm1FcnJvckNsYXNzfWApLnJlbW92ZUNsYXNzKG9wdHMuZm9ybUVycm9yQ2xhc3MpO1xyXG4gICAgJGZvcm0uZmluZCgnW2RhdGEtYWJpZGUtZXJyb3JdJykuY3NzKCdkaXNwbGF5JywgJ25vbmUnKTtcclxuICAgICQoJzppbnB1dCcsICRmb3JtKS5ub3QoJzpidXR0b24sIDpzdWJtaXQsIDpyZXNldCwgOmhpZGRlbiwgOnJhZGlvLCA6Y2hlY2tib3gsIFtkYXRhLWFiaWRlLWlnbm9yZV0nKS52YWwoJycpLnJlbW92ZUF0dHIoJ2RhdGEtaW52YWxpZCcpO1xyXG4gICAgJCgnOmlucHV0OnJhZGlvJywgJGZvcm0pLm5vdCgnW2RhdGEtYWJpZGUtaWdub3JlXScpLnByb3AoJ2NoZWNrZWQnLGZhbHNlKS5yZW1vdmVBdHRyKCdkYXRhLWludmFsaWQnKTtcclxuICAgICQoJzppbnB1dDpjaGVja2JveCcsICRmb3JtKS5ub3QoJ1tkYXRhLWFiaWRlLWlnbm9yZV0nKS5wcm9wKCdjaGVja2VkJyxmYWxzZSkucmVtb3ZlQXR0cignZGF0YS1pbnZhbGlkJyk7XHJcbiAgICAvKipcclxuICAgICAqIEZpcmVzIHdoZW4gdGhlIGZvcm0gaGFzIGJlZW4gcmVzZXQuXHJcbiAgICAgKiBAZXZlbnQgQWJpZGUjZm9ybXJlc2V0XHJcbiAgICAgKi9cclxuICAgICRmb3JtLnRyaWdnZXIoJ2Zvcm1yZXNldC56Zi5hYmlkZScsIFskZm9ybV0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGVzdHJveXMgYW4gaW5zdGFuY2Ugb2YgQWJpZGUuXHJcbiAgICogUmVtb3ZlcyBlcnJvciBzdHlsZXMgYW5kIGNsYXNzZXMgZnJvbSBlbGVtZW50cywgd2l0aG91dCByZXNldHRpbmcgdGhlaXIgdmFsdWVzLlxyXG4gICAqL1xyXG4gIGRlc3Ryb3koKSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgdGhpcy4kZWxlbWVudFxyXG4gICAgICAub2ZmKCcuYWJpZGUnKVxyXG4gICAgICAuZmluZCgnW2RhdGEtYWJpZGUtZXJyb3JdJylcclxuICAgICAgICAuY3NzKCdkaXNwbGF5JywgJ25vbmUnKTtcclxuXHJcbiAgICB0aGlzLiRpbnB1dHNcclxuICAgICAgLm9mZignLmFiaWRlJylcclxuICAgICAgLmVhY2goZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgX3RoaXMucmVtb3ZlRXJyb3JDbGFzc2VzKCQodGhpcykpO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICBGb3VuZGF0aW9uLnVucmVnaXN0ZXJQbHVnaW4odGhpcyk7XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogRGVmYXVsdCBzZXR0aW5ncyBmb3IgcGx1Z2luXHJcbiAqL1xyXG5BYmlkZS5kZWZhdWx0cyA9IHtcclxuICAvKipcclxuICAgKiBUaGUgZGVmYXVsdCBldmVudCB0byB2YWxpZGF0ZSBpbnB1dHMuIENoZWNrYm94ZXMgYW5kIHJhZGlvcyB2YWxpZGF0ZSBpbW1lZGlhdGVseS5cclxuICAgKiBSZW1vdmUgb3IgY2hhbmdlIHRoaXMgdmFsdWUgZm9yIG1hbnVhbCB2YWxpZGF0aW9uLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAnZmllbGRDaGFuZ2UnXHJcbiAgICovXHJcbiAgdmFsaWRhdGVPbjogJ2ZpZWxkQ2hhbmdlJyxcclxuXHJcbiAgLyoqXHJcbiAgICogQ2xhc3MgdG8gYmUgYXBwbGllZCB0byBpbnB1dCBsYWJlbHMgb24gZmFpbGVkIHZhbGlkYXRpb24uXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlICdpcy1pbnZhbGlkLWxhYmVsJ1xyXG4gICAqL1xyXG4gIGxhYmVsRXJyb3JDbGFzczogJ2lzLWludmFsaWQtbGFiZWwnLFxyXG5cclxuICAvKipcclxuICAgKiBDbGFzcyB0byBiZSBhcHBsaWVkIHRvIGlucHV0cyBvbiBmYWlsZWQgdmFsaWRhdGlvbi5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgJ2lzLWludmFsaWQtaW5wdXQnXHJcbiAgICovXHJcbiAgaW5wdXRFcnJvckNsYXNzOiAnaXMtaW52YWxpZC1pbnB1dCcsXHJcblxyXG4gIC8qKlxyXG4gICAqIENsYXNzIHNlbGVjdG9yIHRvIHVzZSB0byB0YXJnZXQgRm9ybSBFcnJvcnMgZm9yIHNob3cvaGlkZS5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgJy5mb3JtLWVycm9yJ1xyXG4gICAqL1xyXG4gIGZvcm1FcnJvclNlbGVjdG9yOiAnLmZvcm0tZXJyb3InLFxyXG5cclxuICAvKipcclxuICAgKiBDbGFzcyBhZGRlZCB0byBGb3JtIEVycm9ycyBvbiBmYWlsZWQgdmFsaWRhdGlvbi5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgJ2lzLXZpc2libGUnXHJcbiAgICovXHJcbiAgZm9ybUVycm9yQ2xhc3M6ICdpcy12aXNpYmxlJyxcclxuXHJcbiAgLyoqXHJcbiAgICogU2V0IHRvIHRydWUgdG8gdmFsaWRhdGUgdGV4dCBpbnB1dHMgb24gYW55IHZhbHVlIGNoYW5nZS5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgZmFsc2VcclxuICAgKi9cclxuICBsaXZlVmFsaWRhdGU6IGZhbHNlLFxyXG5cclxuICBwYXR0ZXJuczoge1xyXG4gICAgYWxwaGEgOiAvXlthLXpBLVpdKyQvLFxyXG4gICAgYWxwaGFfbnVtZXJpYyA6IC9eW2EtekEtWjAtOV0rJC8sXHJcbiAgICBpbnRlZ2VyIDogL15bLStdP1xcZCskLyxcclxuICAgIG51bWJlciA6IC9eWy0rXT9cXGQqKD86W1xcLlxcLF1cXGQrKT8kLyxcclxuXHJcbiAgICAvLyBhbWV4LCB2aXNhLCBkaW5lcnNcclxuICAgIGNhcmQgOiAvXig/OjRbMC05XXsxMn0oPzpbMC05XXszfSk/fDVbMS01XVswLTldezE0fXw2KD86MDExfDVbMC05XVswLTldKVswLTldezEyfXwzWzQ3XVswLTldezEzfXwzKD86MFswLTVdfFs2OF1bMC05XSlbMC05XXsxMX18KD86MjEzMXwxODAwfDM1XFxkezN9KVxcZHsxMX0pJC8sXHJcbiAgICBjdnYgOiAvXihbMC05XSl7Myw0fSQvLFxyXG5cclxuICAgIC8vIGh0dHA6Ly93d3cud2hhdHdnLm9yZy9zcGVjcy93ZWItYXBwcy9jdXJyZW50LXdvcmsvbXVsdGlwYWdlL3N0YXRlcy1vZi10aGUtdHlwZS1hdHRyaWJ1dGUuaHRtbCN2YWxpZC1lLW1haWwtYWRkcmVzc1xyXG4gICAgZW1haWwgOiAvXlthLXpBLVowLTkuISMkJSYnKitcXC89P15fYHt8fX4tXStAW2EtekEtWjAtOV0oPzpbYS16QS1aMC05LV17MCw2MX1bYS16QS1aMC05XSk/KD86XFwuW2EtekEtWjAtOV0oPzpbYS16QS1aMC05LV17MCw2MX1bYS16QS1aMC05XSk/KSskLyxcclxuXHJcbiAgICB1cmwgOiAvXihodHRwcz98ZnRwfGZpbGV8c3NoKTpcXC9cXC8oKCgoW2EtekEtWl18XFxkfC18XFwufF98fnxbXFx1MDBBMC1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkVGXSl8KCVbXFxkYS1mXXsyfSl8WyFcXCQmJ1xcKFxcKVxcKlxcKyw7PV18OikqQCk/KCgoXFxkfFsxLTldXFxkfDFcXGRcXGR8MlswLTRdXFxkfDI1WzAtNV0pXFwuKFxcZHxbMS05XVxcZHwxXFxkXFxkfDJbMC00XVxcZHwyNVswLTVdKVxcLihcXGR8WzEtOV1cXGR8MVxcZFxcZHwyWzAtNF1cXGR8MjVbMC01XSlcXC4oXFxkfFsxLTldXFxkfDFcXGRcXGR8MlswLTRdXFxkfDI1WzAtNV0pKXwoKChbYS16QS1aXXxcXGR8W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pfCgoW2EtekEtWl18XFxkfFtcXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUZdKShbYS16QS1aXXxcXGR8LXxcXC58X3x+fFtcXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUZdKSooW2EtekEtWl18XFxkfFtcXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUZdKSkpXFwuKSsoKFthLXpBLVpdfFtcXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUZdKXwoKFthLXpBLVpdfFtcXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUZdKShbYS16QS1aXXxcXGR8LXxcXC58X3x+fFtcXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUZdKSooW2EtekEtWl18W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pKSlcXC4/KSg6XFxkKik/KShcXC8oKChbYS16QS1aXXxcXGR8LXxcXC58X3x+fFtcXHUwMEEwLVxcdUQ3RkZcXHVGOTAwLVxcdUZEQ0ZcXHVGREYwLVxcdUZGRUZdKXwoJVtcXGRhLWZdezJ9KXxbIVxcJCYnXFwoXFwpXFwqXFwrLDs9XXw6fEApKyhcXC8oKFthLXpBLVpdfFxcZHwtfFxcLnxffH58W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pfCglW1xcZGEtZl17Mn0pfFshXFwkJidcXChcXClcXCpcXCssOz1dfDp8QCkqKSopPyk/KFxcPygoKFthLXpBLVpdfFxcZHwtfFxcLnxffH58W1xcdTAwQTAtXFx1RDdGRlxcdUY5MDAtXFx1RkRDRlxcdUZERjAtXFx1RkZFRl0pfCglW1xcZGEtZl17Mn0pfFshXFwkJidcXChcXClcXCpcXCssOz1dfDp8QCl8W1xcdUUwMDAtXFx1RjhGRl18XFwvfFxcPykqKT8oXFwjKCgoW2EtekEtWl18XFxkfC18XFwufF98fnxbXFx1MDBBMC1cXHVEN0ZGXFx1RjkwMC1cXHVGRENGXFx1RkRGMC1cXHVGRkVGXSl8KCVbXFxkYS1mXXsyfSl8WyFcXCQmJ1xcKFxcKVxcKlxcKyw7PV18OnxAKXxcXC98XFw/KSopPyQvLFxyXG4gICAgLy8gYWJjLmRlXHJcbiAgICBkb21haW4gOiAvXihbYS16QS1aMC05XShbYS16QS1aMC05XFwtXXswLDYxfVthLXpBLVowLTldKT9cXC4pK1thLXpBLVpdezIsOH0kLyxcclxuXHJcbiAgICBkYXRldGltZSA6IC9eKFswLTJdWzAtOV17M30pXFwtKFswLTFdWzAtOV0pXFwtKFswLTNdWzAtOV0pVChbMC01XVswLTldKVxcOihbMC01XVswLTldKVxcOihbMC01XVswLTldKShafChbXFwtXFwrXShbMC0xXVswLTldKVxcOjAwKSkkLyxcclxuICAgIC8vIFlZWVktTU0tRERcclxuICAgIGRhdGUgOiAvKD86MTl8MjApWzAtOV17Mn0tKD86KD86MFsxLTldfDFbMC0yXSktKD86MFsxLTldfDFbMC05XXwyWzAtOV0pfCg/Oig/ITAyKSg/OjBbMS05XXwxWzAtMl0pLSg/OjMwKSl8KD86KD86MFsxMzU3OF18MVswMl0pLTMxKSkkLyxcclxuICAgIC8vIEhIOk1NOlNTXHJcbiAgICB0aW1lIDogL14oMFswLTldfDFbMC05XXwyWzAtM10pKDpbMC01XVswLTldKXsyfSQvLFxyXG4gICAgZGF0ZUlTTyA6IC9eXFxkezR9W1xcL1xcLV1cXGR7MSwyfVtcXC9cXC1dXFxkezEsMn0kLyxcclxuICAgIC8vIE1NL0REL1lZWVlcclxuICAgIG1vbnRoX2RheV95ZWFyIDogL14oMFsxLTldfDFbMDEyXSlbLSBcXC8uXSgwWzEtOV18WzEyXVswLTldfDNbMDFdKVstIFxcLy5dXFxkezR9JC8sXHJcbiAgICAvLyBERC9NTS9ZWVlZXHJcbiAgICBkYXlfbW9udGhfeWVhciA6IC9eKDBbMS05XXxbMTJdWzAtOV18M1swMV0pWy0gXFwvLl0oMFsxLTldfDFbMDEyXSlbLSBcXC8uXVxcZHs0fSQvLFxyXG5cclxuICAgIC8vICNGRkYgb3IgI0ZGRkZGRlxyXG4gICAgY29sb3IgOiAvXiM/KFthLWZBLUYwLTldezZ9fFthLWZBLUYwLTldezN9KSQvXHJcbiAgfSxcclxuXHJcbiAgLyoqXHJcbiAgICogT3B0aW9uYWwgdmFsaWRhdGlvbiBmdW5jdGlvbnMgdG8gYmUgdXNlZC4gYGVxdWFsVG9gIGJlaW5nIHRoZSBvbmx5IGRlZmF1bHQgaW5jbHVkZWQgZnVuY3Rpb24uXHJcbiAgICogRnVuY3Rpb25zIHNob3VsZCByZXR1cm4gb25seSBhIGJvb2xlYW4gaWYgdGhlIGlucHV0IGlzIHZhbGlkIG9yIG5vdC4gRnVuY3Rpb25zIGFyZSBnaXZlbiB0aGUgZm9sbG93aW5nIGFyZ3VtZW50czpcclxuICAgKiBlbCA6IFRoZSBqUXVlcnkgZWxlbWVudCB0byB2YWxpZGF0ZS5cclxuICAgKiByZXF1aXJlZCA6IEJvb2xlYW4gdmFsdWUgb2YgdGhlIHJlcXVpcmVkIGF0dHJpYnV0ZSBiZSBwcmVzZW50IG9yIG5vdC5cclxuICAgKiBwYXJlbnQgOiBUaGUgZGlyZWN0IHBhcmVudCBvZiB0aGUgaW5wdXQuXHJcbiAgICogQG9wdGlvblxyXG4gICAqL1xyXG4gIHZhbGlkYXRvcnM6IHtcclxuICAgIGVxdWFsVG86IGZ1bmN0aW9uIChlbCwgcmVxdWlyZWQsIHBhcmVudCkge1xyXG4gICAgICByZXR1cm4gJChgIyR7ZWwuYXR0cignZGF0YS1lcXVhbHRvJyl9YCkudmFsKCkgPT09IGVsLnZhbCgpO1xyXG4gICAgfVxyXG4gIH1cclxufVxyXG5cclxuLy8gV2luZG93IGV4cG9ydHNcclxuRm91bmRhdGlvbi5wbHVnaW4oQWJpZGUsICdBYmlkZScpO1xyXG5cclxufShqUXVlcnkpO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG4hZnVuY3Rpb24oJCkge1xyXG5cclxuLyoqXHJcbiAqIEFjY29yZGlvbiBtb2R1bGUuXHJcbiAqIEBtb2R1bGUgZm91bmRhdGlvbi5hY2NvcmRpb25cclxuICogQHJlcXVpcmVzIGZvdW5kYXRpb24udXRpbC5rZXlib2FyZFxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLm1vdGlvblxyXG4gKi9cclxuXHJcbmNsYXNzIEFjY29yZGlvbiB7XHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBhbiBhY2NvcmRpb24uXHJcbiAgICogQGNsYXNzXHJcbiAgICogQGZpcmVzIEFjY29yZGlvbiNpbml0XHJcbiAgICogQHBhcmFtIHtqUXVlcnl9IGVsZW1lbnQgLSBqUXVlcnkgb2JqZWN0IHRvIG1ha2UgaW50byBhbiBhY2NvcmRpb24uXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBhIHBsYWluIG9iamVjdCB3aXRoIHNldHRpbmdzIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0IG9wdGlvbnMuXHJcbiAgICovXHJcbiAgY29uc3RydWN0b3IoZWxlbWVudCwgb3B0aW9ucykge1xyXG4gICAgdGhpcy4kZWxlbWVudCA9IGVsZW1lbnQ7XHJcbiAgICB0aGlzLm9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgQWNjb3JkaW9uLmRlZmF1bHRzLCB0aGlzLiRlbGVtZW50LmRhdGEoKSwgb3B0aW9ucyk7XHJcblxyXG4gICAgdGhpcy5faW5pdCgpO1xyXG5cclxuICAgIEZvdW5kYXRpb24ucmVnaXN0ZXJQbHVnaW4odGhpcywgJ0FjY29yZGlvbicpO1xyXG4gICAgRm91bmRhdGlvbi5LZXlib2FyZC5yZWdpc3RlcignQWNjb3JkaW9uJywge1xyXG4gICAgICAnRU5URVInOiAndG9nZ2xlJyxcclxuICAgICAgJ1NQQUNFJzogJ3RvZ2dsZScsXHJcbiAgICAgICdBUlJPV19ET1dOJzogJ25leHQnLFxyXG4gICAgICAnQVJST1dfVVAnOiAncHJldmlvdXMnXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpYWxpemVzIHRoZSBhY2NvcmRpb24gYnkgYW5pbWF0aW5nIHRoZSBwcmVzZXQgYWN0aXZlIHBhbmUocykuXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfaW5pdCgpIHtcclxuICAgIHRoaXMuJGVsZW1lbnQuYXR0cigncm9sZScsICd0YWJsaXN0Jyk7XHJcbiAgICB0aGlzLiR0YWJzID0gdGhpcy4kZWxlbWVudC5jaGlsZHJlbignbGksIFtkYXRhLWFjY29yZGlvbi1pdGVtXScpO1xyXG5cclxuICAgIHRoaXMuJHRhYnMuZWFjaChmdW5jdGlvbihpZHgsIGVsKSB7XHJcbiAgICAgIHZhciAkZWwgPSAkKGVsKSxcclxuICAgICAgICAgICRjb250ZW50ID0gJGVsLmNoaWxkcmVuKCdbZGF0YS10YWItY29udGVudF0nKSxcclxuICAgICAgICAgIGlkID0gJGNvbnRlbnRbMF0uaWQgfHwgRm91bmRhdGlvbi5HZXRZb0RpZ2l0cyg2LCAnYWNjb3JkaW9uJyksXHJcbiAgICAgICAgICBsaW5rSWQgPSBlbC5pZCB8fCBgJHtpZH0tbGFiZWxgO1xyXG5cclxuICAgICAgJGVsLmZpbmQoJ2E6Zmlyc3QnKS5hdHRyKHtcclxuICAgICAgICAnYXJpYS1jb250cm9scyc6IGlkLFxyXG4gICAgICAgICdyb2xlJzogJ3RhYicsXHJcbiAgICAgICAgJ2lkJzogbGlua0lkLFxyXG4gICAgICAgICdhcmlhLWV4cGFuZGVkJzogZmFsc2UsXHJcbiAgICAgICAgJ2FyaWEtc2VsZWN0ZWQnOiBmYWxzZVxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgICRjb250ZW50LmF0dHIoeydyb2xlJzogJ3RhYnBhbmVsJywgJ2FyaWEtbGFiZWxsZWRieSc6IGxpbmtJZCwgJ2FyaWEtaGlkZGVuJzogdHJ1ZSwgJ2lkJzogaWR9KTtcclxuICAgIH0pO1xyXG4gICAgdmFyICRpbml0QWN0aXZlID0gdGhpcy4kZWxlbWVudC5maW5kKCcuaXMtYWN0aXZlJykuY2hpbGRyZW4oJ1tkYXRhLXRhYi1jb250ZW50XScpO1xyXG4gICAgaWYoJGluaXRBY3RpdmUubGVuZ3RoKXtcclxuICAgICAgdGhpcy5kb3duKCRpbml0QWN0aXZlLCB0cnVlKTtcclxuICAgIH1cclxuICAgIHRoaXMuX2V2ZW50cygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQWRkcyBldmVudCBoYW5kbGVycyBmb3IgaXRlbXMgd2l0aGluIHRoZSBhY2NvcmRpb24uXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfZXZlbnRzKCkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuXHJcbiAgICB0aGlzLiR0YWJzLmVhY2goZnVuY3Rpb24oKSB7XHJcbiAgICAgIHZhciAkZWxlbSA9ICQodGhpcyk7XHJcbiAgICAgIHZhciAkdGFiQ29udGVudCA9ICRlbGVtLmNoaWxkcmVuKCdbZGF0YS10YWItY29udGVudF0nKTtcclxuICAgICAgaWYgKCR0YWJDb250ZW50Lmxlbmd0aCkge1xyXG4gICAgICAgICRlbGVtLmNoaWxkcmVuKCdhJykub2ZmKCdjbGljay56Zi5hY2NvcmRpb24ga2V5ZG93bi56Zi5hY2NvcmRpb24nKVxyXG4gICAgICAgICAgICAgICAub24oJ2NsaWNrLnpmLmFjY29yZGlvbicsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICAvLyAkKHRoaXMpLmNoaWxkcmVuKCdhJykub24oJ2NsaWNrLnpmLmFjY29yZGlvbicsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgIGlmICgkZWxlbS5oYXNDbGFzcygnaXMtYWN0aXZlJykpIHtcclxuICAgICAgICAgICAgaWYoX3RoaXMub3B0aW9ucy5hbGxvd0FsbENsb3NlZCB8fCAkZWxlbS5zaWJsaW5ncygpLmhhc0NsYXNzKCdpcy1hY3RpdmUnKSl7XHJcbiAgICAgICAgICAgICAgX3RoaXMudXAoJHRhYkNvbnRlbnQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgX3RoaXMuZG93bigkdGFiQ29udGVudCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSkub24oJ2tleWRvd24uemYuYWNjb3JkaW9uJywgZnVuY3Rpb24oZSl7XHJcbiAgICAgICAgICBGb3VuZGF0aW9uLktleWJvYXJkLmhhbmRsZUtleShlLCAnQWNjb3JkaW9uJywge1xyXG4gICAgICAgICAgICB0b2dnbGU6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgIF90aGlzLnRvZ2dsZSgkdGFiQ29udGVudCk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIG5leHQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgIHZhciAkYSA9ICRlbGVtLm5leHQoKS5maW5kKCdhJykuZm9jdXMoKTtcclxuICAgICAgICAgICAgICBpZiAoIV90aGlzLm9wdGlvbnMubXVsdGlFeHBhbmQpIHtcclxuICAgICAgICAgICAgICAgICRhLnRyaWdnZXIoJ2NsaWNrLnpmLmFjY29yZGlvbicpXHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBwcmV2aW91czogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgdmFyICRhID0gJGVsZW0ucHJldigpLmZpbmQoJ2EnKS5mb2N1cygpO1xyXG4gICAgICAgICAgICAgIGlmICghX3RoaXMub3B0aW9ucy5tdWx0aUV4cGFuZCkge1xyXG4gICAgICAgICAgICAgICAgJGEudHJpZ2dlcignY2xpY2suemYuYWNjb3JkaW9uJylcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGhhbmRsZWQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUb2dnbGVzIHRoZSBzZWxlY3RlZCBjb250ZW50IHBhbmUncyBvcGVuL2Nsb3NlIHN0YXRlLlxyXG4gICAqIEBwYXJhbSB7alF1ZXJ5fSAkdGFyZ2V0IC0galF1ZXJ5IG9iamVjdCBvZiB0aGUgcGFuZSB0byB0b2dnbGUuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICovXHJcbiAgdG9nZ2xlKCR0YXJnZXQpIHtcclxuICAgIGlmKCR0YXJnZXQucGFyZW50KCkuaGFzQ2xhc3MoJ2lzLWFjdGl2ZScpKSB7XHJcbiAgICAgIGlmKHRoaXMub3B0aW9ucy5hbGxvd0FsbENsb3NlZCB8fCAkdGFyZ2V0LnBhcmVudCgpLnNpYmxpbmdzKCkuaGFzQ2xhc3MoJ2lzLWFjdGl2ZScpKXtcclxuICAgICAgICB0aGlzLnVwKCR0YXJnZXQpO1xyXG4gICAgICB9IGVsc2UgeyByZXR1cm47IH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuZG93bigkdGFyZ2V0KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE9wZW5zIHRoZSBhY2NvcmRpb24gdGFiIGRlZmluZWQgYnkgYCR0YXJnZXRgLlxyXG4gICAqIEBwYXJhbSB7alF1ZXJ5fSAkdGFyZ2V0IC0gQWNjb3JkaW9uIHBhbmUgdG8gb3Blbi5cclxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IGZpcnN0VGltZSAtIGZsYWcgdG8gZGV0ZXJtaW5lIGlmIHJlZmxvdyBzaG91bGQgaGFwcGVuLlxyXG4gICAqIEBmaXJlcyBBY2NvcmRpb24jZG93blxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqL1xyXG4gIGRvd24oJHRhcmdldCwgZmlyc3RUaW1lKSB7XHJcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5tdWx0aUV4cGFuZCAmJiAhZmlyc3RUaW1lKSB7XHJcbiAgICAgIHZhciAkY3VycmVudEFjdGl2ZSA9IHRoaXMuJGVsZW1lbnQuY2hpbGRyZW4oJy5pcy1hY3RpdmUnKS5jaGlsZHJlbignW2RhdGEtdGFiLWNvbnRlbnRdJyk7XHJcbiAgICAgIGlmKCRjdXJyZW50QWN0aXZlLmxlbmd0aCl7XHJcbiAgICAgICAgdGhpcy51cCgkY3VycmVudEFjdGl2ZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAkdGFyZ2V0XHJcbiAgICAgIC5hdHRyKCdhcmlhLWhpZGRlbicsIGZhbHNlKVxyXG4gICAgICAucGFyZW50KCdbZGF0YS10YWItY29udGVudF0nKVxyXG4gICAgICAuYWRkQmFjaygpXHJcbiAgICAgIC5wYXJlbnQoKS5hZGRDbGFzcygnaXMtYWN0aXZlJyk7XHJcblxyXG4gICAgJHRhcmdldC5zbGlkZURvd24odGhpcy5vcHRpb25zLnNsaWRlU3BlZWQsICgpID0+IHtcclxuICAgICAgLyoqXHJcbiAgICAgICAqIEZpcmVzIHdoZW4gdGhlIHRhYiBpcyBkb25lIG9wZW5pbmcuXHJcbiAgICAgICAqIEBldmVudCBBY2NvcmRpb24jZG93blxyXG4gICAgICAgKi9cclxuICAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKCdkb3duLnpmLmFjY29yZGlvbicsIFskdGFyZ2V0XSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICAkKGAjJHskdGFyZ2V0LmF0dHIoJ2FyaWEtbGFiZWxsZWRieScpfWApLmF0dHIoe1xyXG4gICAgICAnYXJpYS1leHBhbmRlZCc6IHRydWUsXHJcbiAgICAgICdhcmlhLXNlbGVjdGVkJzogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDbG9zZXMgdGhlIHRhYiBkZWZpbmVkIGJ5IGAkdGFyZ2V0YC5cclxuICAgKiBAcGFyYW0ge2pRdWVyeX0gJHRhcmdldCAtIEFjY29yZGlvbiB0YWIgdG8gY2xvc2UuXHJcbiAgICogQGZpcmVzIEFjY29yZGlvbiN1cFxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqL1xyXG4gIHVwKCR0YXJnZXQpIHtcclxuICAgIHZhciAkYXVudHMgPSAkdGFyZ2V0LnBhcmVudCgpLnNpYmxpbmdzKCksXHJcbiAgICAgICAgX3RoaXMgPSB0aGlzO1xyXG4gICAgdmFyIGNhbkNsb3NlID0gdGhpcy5vcHRpb25zLm11bHRpRXhwYW5kID8gJGF1bnRzLmhhc0NsYXNzKCdpcy1hY3RpdmUnKSA6ICR0YXJnZXQucGFyZW50KCkuaGFzQ2xhc3MoJ2lzLWFjdGl2ZScpO1xyXG5cclxuICAgIGlmKCF0aGlzLm9wdGlvbnMuYWxsb3dBbGxDbG9zZWQgJiYgIWNhbkNsb3NlKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICAvLyBGb3VuZGF0aW9uLk1vdmUodGhpcy5vcHRpb25zLnNsaWRlU3BlZWQsICR0YXJnZXQsIGZ1bmN0aW9uKCl7XHJcbiAgICAgICR0YXJnZXQuc2xpZGVVcChfdGhpcy5vcHRpb25zLnNsaWRlU3BlZWQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBGaXJlcyB3aGVuIHRoZSB0YWIgaXMgZG9uZSBjb2xsYXBzaW5nIHVwLlxyXG4gICAgICAgICAqIEBldmVudCBBY2NvcmRpb24jdXBcclxuICAgICAgICAgKi9cclxuICAgICAgICBfdGhpcy4kZWxlbWVudC50cmlnZ2VyKCd1cC56Zi5hY2NvcmRpb24nLCBbJHRhcmdldF0pO1xyXG4gICAgICB9KTtcclxuICAgIC8vIH0pO1xyXG5cclxuICAgICR0YXJnZXQuYXR0cignYXJpYS1oaWRkZW4nLCB0cnVlKVxyXG4gICAgICAgICAgIC5wYXJlbnQoKS5yZW1vdmVDbGFzcygnaXMtYWN0aXZlJyk7XHJcblxyXG4gICAgJChgIyR7JHRhcmdldC5hdHRyKCdhcmlhLWxhYmVsbGVkYnknKX1gKS5hdHRyKHtcclxuICAgICAnYXJpYS1leHBhbmRlZCc6IGZhbHNlLFxyXG4gICAgICdhcmlhLXNlbGVjdGVkJzogZmFsc2VcclxuICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBEZXN0cm95cyBhbiBpbnN0YW5jZSBvZiBhbiBhY2NvcmRpb24uXHJcbiAgICogQGZpcmVzIEFjY29yZGlvbiNkZXN0cm95ZWRcclxuICAgKiBAZnVuY3Rpb25cclxuICAgKi9cclxuICBkZXN0cm95KCkge1xyXG4gICAgdGhpcy4kZWxlbWVudC5maW5kKCdbZGF0YS10YWItY29udGVudF0nKS5zdG9wKHRydWUpLnNsaWRlVXAoMCkuY3NzKCdkaXNwbGF5JywgJycpO1xyXG4gICAgdGhpcy4kZWxlbWVudC5maW5kKCdhJykub2ZmKCcuemYuYWNjb3JkaW9uJyk7XHJcblxyXG4gICAgRm91bmRhdGlvbi51bnJlZ2lzdGVyUGx1Z2luKHRoaXMpO1xyXG4gIH1cclxufVxyXG5cclxuQWNjb3JkaW9uLmRlZmF1bHRzID0ge1xyXG4gIC8qKlxyXG4gICAqIEFtb3VudCBvZiB0aW1lIHRvIGFuaW1hdGUgdGhlIG9wZW5pbmcgb2YgYW4gYWNjb3JkaW9uIHBhbmUuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIDI1MFxyXG4gICAqL1xyXG4gIHNsaWRlU3BlZWQ6IDI1MCxcclxuICAvKipcclxuICAgKiBBbGxvdyB0aGUgYWNjb3JkaW9uIHRvIGhhdmUgbXVsdGlwbGUgb3BlbiBwYW5lcy5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgZmFsc2VcclxuICAgKi9cclxuICBtdWx0aUV4cGFuZDogZmFsc2UsXHJcbiAgLyoqXHJcbiAgICogQWxsb3cgdGhlIGFjY29yZGlvbiB0byBjbG9zZSBhbGwgcGFuZXMuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIGZhbHNlXHJcbiAgICovXHJcbiAgYWxsb3dBbGxDbG9zZWQ6IGZhbHNlXHJcbn07XHJcblxyXG4vLyBXaW5kb3cgZXhwb3J0c1xyXG5Gb3VuZGF0aW9uLnBsdWdpbihBY2NvcmRpb24sICdBY2NvcmRpb24nKTtcclxuXHJcbn0oalF1ZXJ5KTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxuIWZ1bmN0aW9uKCQpIHtcclxuXHJcbi8qKlxyXG4gKiBBY2NvcmRpb25NZW51IG1vZHVsZS5cclxuICogQG1vZHVsZSBmb3VuZGF0aW9uLmFjY29yZGlvbk1lbnVcclxuICogQHJlcXVpcmVzIGZvdW5kYXRpb24udXRpbC5rZXlib2FyZFxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLm1vdGlvblxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLm5lc3RcclxuICovXHJcblxyXG5jbGFzcyBBY2NvcmRpb25NZW51IHtcclxuICAvKipcclxuICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIGFuIGFjY29yZGlvbiBtZW51LlxyXG4gICAqIEBjbGFzc1xyXG4gICAqIEBmaXJlcyBBY2NvcmRpb25NZW51I2luaXRcclxuICAgKiBAcGFyYW0ge2pRdWVyeX0gZWxlbWVudCAtIGpRdWVyeSBvYmplY3QgdG8gbWFrZSBpbnRvIGFuIGFjY29yZGlvbiBtZW51LlxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gT3ZlcnJpZGVzIHRvIHRoZSBkZWZhdWx0IHBsdWdpbiBzZXR0aW5ncy5cclxuICAgKi9cclxuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBvcHRpb25zKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50ID0gZWxlbWVudDtcclxuICAgIHRoaXMub3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBBY2NvcmRpb25NZW51LmRlZmF1bHRzLCB0aGlzLiRlbGVtZW50LmRhdGEoKSwgb3B0aW9ucyk7XHJcblxyXG4gICAgRm91bmRhdGlvbi5OZXN0LkZlYXRoZXIodGhpcy4kZWxlbWVudCwgJ2FjY29yZGlvbicpO1xyXG5cclxuICAgIHRoaXMuX2luaXQoKTtcclxuXHJcbiAgICBGb3VuZGF0aW9uLnJlZ2lzdGVyUGx1Z2luKHRoaXMsICdBY2NvcmRpb25NZW51Jyk7XHJcbiAgICBGb3VuZGF0aW9uLktleWJvYXJkLnJlZ2lzdGVyKCdBY2NvcmRpb25NZW51Jywge1xyXG4gICAgICAnRU5URVInOiAndG9nZ2xlJyxcclxuICAgICAgJ1NQQUNFJzogJ3RvZ2dsZScsXHJcbiAgICAgICdBUlJPV19SSUdIVCc6ICdvcGVuJyxcclxuICAgICAgJ0FSUk9XX1VQJzogJ3VwJyxcclxuICAgICAgJ0FSUk9XX0RPV04nOiAnZG93bicsXHJcbiAgICAgICdBUlJPV19MRUZUJzogJ2Nsb3NlJyxcclxuICAgICAgJ0VTQ0FQRSc6ICdjbG9zZUFsbCcsXHJcbiAgICAgICdUQUInOiAnZG93bicsXHJcbiAgICAgICdTSElGVF9UQUInOiAndXAnXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG5cclxuXHJcbiAgLyoqXHJcbiAgICogSW5pdGlhbGl6ZXMgdGhlIGFjY29yZGlvbiBtZW51IGJ5IGhpZGluZyBhbGwgbmVzdGVkIG1lbnVzLlxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX2luaXQoKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50LmZpbmQoJ1tkYXRhLXN1Ym1lbnVdJykubm90KCcuaXMtYWN0aXZlJykuc2xpZGVVcCgwKTsvLy5maW5kKCdhJykuY3NzKCdwYWRkaW5nLWxlZnQnLCAnMXJlbScpO1xyXG4gICAgdGhpcy4kZWxlbWVudC5hdHRyKHtcclxuICAgICAgJ3JvbGUnOiAndGFibGlzdCcsXHJcbiAgICAgICdhcmlhLW11bHRpc2VsZWN0YWJsZSc6IHRoaXMub3B0aW9ucy5tdWx0aU9wZW5cclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuJG1lbnVMaW5rcyA9IHRoaXMuJGVsZW1lbnQuZmluZCgnLmlzLWFjY29yZGlvbi1zdWJtZW51LXBhcmVudCcpO1xyXG4gICAgdGhpcy4kbWVudUxpbmtzLmVhY2goZnVuY3Rpb24oKXtcclxuICAgICAgdmFyIGxpbmtJZCA9IHRoaXMuaWQgfHwgRm91bmRhdGlvbi5HZXRZb0RpZ2l0cyg2LCAnYWNjLW1lbnUtbGluaycpLFxyXG4gICAgICAgICAgJGVsZW0gPSAkKHRoaXMpLFxyXG4gICAgICAgICAgJHN1YiA9ICRlbGVtLmNoaWxkcmVuKCdbZGF0YS1zdWJtZW51XScpLFxyXG4gICAgICAgICAgc3ViSWQgPSAkc3ViWzBdLmlkIHx8IEZvdW5kYXRpb24uR2V0WW9EaWdpdHMoNiwgJ2FjYy1tZW51JyksXHJcbiAgICAgICAgICBpc0FjdGl2ZSA9ICRzdWIuaGFzQ2xhc3MoJ2lzLWFjdGl2ZScpO1xyXG4gICAgICAkZWxlbS5hdHRyKHtcclxuICAgICAgICAnYXJpYS1jb250cm9scyc6IHN1YklkLFxyXG4gICAgICAgICdhcmlhLWV4cGFuZGVkJzogaXNBY3RpdmUsXHJcbiAgICAgICAgJ3JvbGUnOiAndGFiJyxcclxuICAgICAgICAnaWQnOiBsaW5rSWRcclxuICAgICAgfSk7XHJcbiAgICAgICRzdWIuYXR0cih7XHJcbiAgICAgICAgJ2FyaWEtbGFiZWxsZWRieSc6IGxpbmtJZCxcclxuICAgICAgICAnYXJpYS1oaWRkZW4nOiAhaXNBY3RpdmUsXHJcbiAgICAgICAgJ3JvbGUnOiAndGFicGFuZWwnLFxyXG4gICAgICAgICdpZCc6IHN1YklkXHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgICB2YXIgaW5pdFBhbmVzID0gdGhpcy4kZWxlbWVudC5maW5kKCcuaXMtYWN0aXZlJyk7XHJcbiAgICBpZihpbml0UGFuZXMubGVuZ3RoKXtcclxuICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgaW5pdFBhbmVzLmVhY2goZnVuY3Rpb24oKXtcclxuICAgICAgICBfdGhpcy5kb3duKCQodGhpcykpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIHRoaXMuX2V2ZW50cygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQWRkcyBldmVudCBoYW5kbGVycyBmb3IgaXRlbXMgd2l0aGluIHRoZSBtZW51LlxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX2V2ZW50cygpIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcblxyXG4gICAgdGhpcy4kZWxlbWVudC5maW5kKCdsaScpLmVhY2goZnVuY3Rpb24oKSB7XHJcbiAgICAgIHZhciAkc3VibWVudSA9ICQodGhpcykuY2hpbGRyZW4oJ1tkYXRhLXN1Ym1lbnVdJyk7XHJcblxyXG4gICAgICBpZiAoJHN1Ym1lbnUubGVuZ3RoKSB7XHJcbiAgICAgICAgJCh0aGlzKS5jaGlsZHJlbignYScpLm9mZignY2xpY2suemYuYWNjb3JkaW9uTWVudScpLm9uKCdjbGljay56Zi5hY2NvcmRpb25NZW51JywgZnVuY3Rpb24oZSkge1xyXG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG5cclxuICAgICAgICAgIF90aGlzLnRvZ2dsZSgkc3VibWVudSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH0pLm9uKCdrZXlkb3duLnpmLmFjY29yZGlvbm1lbnUnLCBmdW5jdGlvbihlKXtcclxuICAgICAgdmFyICRlbGVtZW50ID0gJCh0aGlzKSxcclxuICAgICAgICAgICRlbGVtZW50cyA9ICRlbGVtZW50LnBhcmVudCgndWwnKS5jaGlsZHJlbignbGknKSxcclxuICAgICAgICAgICRwcmV2RWxlbWVudCxcclxuICAgICAgICAgICRuZXh0RWxlbWVudCxcclxuICAgICAgICAgICR0YXJnZXQgPSAkZWxlbWVudC5jaGlsZHJlbignW2RhdGEtc3VibWVudV0nKTtcclxuXHJcbiAgICAgICRlbGVtZW50cy5lYWNoKGZ1bmN0aW9uKGkpIHtcclxuICAgICAgICBpZiAoJCh0aGlzKS5pcygkZWxlbWVudCkpIHtcclxuICAgICAgICAgICRwcmV2RWxlbWVudCA9ICRlbGVtZW50cy5lcShNYXRoLm1heCgwLCBpLTEpKS5maW5kKCdhJykuZmlyc3QoKTtcclxuICAgICAgICAgICRuZXh0RWxlbWVudCA9ICRlbGVtZW50cy5lcShNYXRoLm1pbihpKzEsICRlbGVtZW50cy5sZW5ndGgtMSkpLmZpbmQoJ2EnKS5maXJzdCgpO1xyXG5cclxuICAgICAgICAgIGlmICgkKHRoaXMpLmNoaWxkcmVuKCdbZGF0YS1zdWJtZW51XTp2aXNpYmxlJykubGVuZ3RoKSB7IC8vIGhhcyBvcGVuIHN1YiBtZW51XHJcbiAgICAgICAgICAgICRuZXh0RWxlbWVudCA9ICRlbGVtZW50LmZpbmQoJ2xpOmZpcnN0LWNoaWxkJykuZmluZCgnYScpLmZpcnN0KCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBpZiAoJCh0aGlzKS5pcygnOmZpcnN0LWNoaWxkJykpIHsgLy8gaXMgZmlyc3QgZWxlbWVudCBvZiBzdWIgbWVudVxyXG4gICAgICAgICAgICAkcHJldkVsZW1lbnQgPSAkZWxlbWVudC5wYXJlbnRzKCdsaScpLmZpcnN0KCkuZmluZCgnYScpLmZpcnN0KCk7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKCRwcmV2RWxlbWVudC5jaGlsZHJlbignW2RhdGEtc3VibWVudV06dmlzaWJsZScpLmxlbmd0aCkgeyAvLyBpZiBwcmV2aW91cyBlbGVtZW50IGhhcyBvcGVuIHN1YiBtZW51XHJcbiAgICAgICAgICAgICRwcmV2RWxlbWVudCA9ICRwcmV2RWxlbWVudC5maW5kKCdsaTpsYXN0LWNoaWxkJykuZmluZCgnYScpLmZpcnN0KCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBpZiAoJCh0aGlzKS5pcygnOmxhc3QtY2hpbGQnKSkgeyAvLyBpcyBsYXN0IGVsZW1lbnQgb2Ygc3ViIG1lbnVcclxuICAgICAgICAgICAgJG5leHRFbGVtZW50ID0gJGVsZW1lbnQucGFyZW50cygnbGknKS5maXJzdCgpLm5leHQoJ2xpJykuZmluZCgnYScpLmZpcnN0KCk7XHJcbiAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICAgIEZvdW5kYXRpb24uS2V5Ym9hcmQuaGFuZGxlS2V5KGUsICdBY2NvcmRpb25NZW51Jywge1xyXG4gICAgICAgIG9wZW46IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgaWYgKCR0YXJnZXQuaXMoJzpoaWRkZW4nKSkge1xyXG4gICAgICAgICAgICBfdGhpcy5kb3duKCR0YXJnZXQpO1xyXG4gICAgICAgICAgICAkdGFyZ2V0LmZpbmQoJ2xpJykuZmlyc3QoKS5maW5kKCdhJykuZmlyc3QoKS5mb2N1cygpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgY2xvc2U6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgaWYgKCR0YXJnZXQubGVuZ3RoICYmICEkdGFyZ2V0LmlzKCc6aGlkZGVuJykpIHsgLy8gY2xvc2UgYWN0aXZlIHN1YiBvZiB0aGlzIGl0ZW1cclxuICAgICAgICAgICAgX3RoaXMudXAoJHRhcmdldCk7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKCRlbGVtZW50LnBhcmVudCgnW2RhdGEtc3VibWVudV0nKS5sZW5ndGgpIHsgLy8gY2xvc2UgY3VycmVudGx5IG9wZW4gc3ViXHJcbiAgICAgICAgICAgIF90aGlzLnVwKCRlbGVtZW50LnBhcmVudCgnW2RhdGEtc3VibWVudV0nKSk7XHJcbiAgICAgICAgICAgICRlbGVtZW50LnBhcmVudHMoJ2xpJykuZmlyc3QoKS5maW5kKCdhJykuZmlyc3QoKS5mb2N1cygpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgdXA6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgJHByZXZFbGVtZW50LmF0dHIoJ3RhYmluZGV4JywgLTEpLmZvY3VzKCk7XHJcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGRvd246IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgJG5leHRFbGVtZW50LmF0dHIoJ3RhYmluZGV4JywgLTEpLmZvY3VzKCk7XHJcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIHRvZ2dsZTogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICBpZiAoJGVsZW1lbnQuY2hpbGRyZW4oJ1tkYXRhLXN1Ym1lbnVdJykubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLnRvZ2dsZSgkZWxlbWVudC5jaGlsZHJlbignW2RhdGEtc3VibWVudV0nKSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBjbG9zZUFsbDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICBfdGhpcy5oaWRlQWxsKCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBoYW5kbGVkOiBmdW5jdGlvbihwcmV2ZW50RGVmYXVsdCkge1xyXG4gICAgICAgICAgaWYgKHByZXZlbnREZWZhdWx0KSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0pOy8vLmF0dHIoJ3RhYmluZGV4JywgMCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDbG9zZXMgYWxsIHBhbmVzIG9mIHRoZSBtZW51LlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqL1xyXG4gIGhpZGVBbGwoKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50LmZpbmQoJ1tkYXRhLXN1Ym1lbnVdJykuc2xpZGVVcCh0aGlzLm9wdGlvbnMuc2xpZGVTcGVlZCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUb2dnbGVzIHRoZSBvcGVuL2Nsb3NlIHN0YXRlIG9mIGEgc3VibWVudS5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcGFyYW0ge2pRdWVyeX0gJHRhcmdldCAtIHRoZSBzdWJtZW51IHRvIHRvZ2dsZVxyXG4gICAqL1xyXG4gIHRvZ2dsZSgkdGFyZ2V0KXtcclxuICAgIGlmKCEkdGFyZ2V0LmlzKCc6YW5pbWF0ZWQnKSkge1xyXG4gICAgICBpZiAoISR0YXJnZXQuaXMoJzpoaWRkZW4nKSkge1xyXG4gICAgICAgIHRoaXMudXAoJHRhcmdldCk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSB7XHJcbiAgICAgICAgdGhpcy5kb3duKCR0YXJnZXQpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBPcGVucyB0aGUgc3ViLW1lbnUgZGVmaW5lZCBieSBgJHRhcmdldGAuXHJcbiAgICogQHBhcmFtIHtqUXVlcnl9ICR0YXJnZXQgLSBTdWItbWVudSB0byBvcGVuLlxyXG4gICAqIEBmaXJlcyBBY2NvcmRpb25NZW51I2Rvd25cclxuICAgKi9cclxuICBkb3duKCR0YXJnZXQpIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcblxyXG4gICAgaWYoIXRoaXMub3B0aW9ucy5tdWx0aU9wZW4pIHtcclxuICAgICAgdGhpcy51cCh0aGlzLiRlbGVtZW50LmZpbmQoJy5pcy1hY3RpdmUnKS5ub3QoJHRhcmdldC5wYXJlbnRzVW50aWwodGhpcy4kZWxlbWVudCkuYWRkKCR0YXJnZXQpKSk7XHJcbiAgICB9XHJcblxyXG4gICAgJHRhcmdldC5hZGRDbGFzcygnaXMtYWN0aXZlJykuYXR0cih7J2FyaWEtaGlkZGVuJzogZmFsc2V9KVxyXG4gICAgICAucGFyZW50KCcuaXMtYWNjb3JkaW9uLXN1Ym1lbnUtcGFyZW50JykuYXR0cih7J2FyaWEtZXhwYW5kZWQnOiB0cnVlfSk7XHJcblxyXG4gICAgICAvL0ZvdW5kYXRpb24uTW92ZSh0aGlzLm9wdGlvbnMuc2xpZGVTcGVlZCwgJHRhcmdldCwgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgJHRhcmdldC5zbGlkZURvd24oX3RoaXMub3B0aW9ucy5zbGlkZVNwZWVkLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAvKipcclxuICAgICAgICAgICAqIEZpcmVzIHdoZW4gdGhlIG1lbnUgaXMgZG9uZSBvcGVuaW5nLlxyXG4gICAgICAgICAgICogQGV2ZW50IEFjY29yZGlvbk1lbnUjZG93blxyXG4gICAgICAgICAgICovXHJcbiAgICAgICAgICBfdGhpcy4kZWxlbWVudC50cmlnZ2VyKCdkb3duLnpmLmFjY29yZGlvbk1lbnUnLCBbJHRhcmdldF0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAvL30pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2xvc2VzIHRoZSBzdWItbWVudSBkZWZpbmVkIGJ5IGAkdGFyZ2V0YC4gQWxsIHN1Yi1tZW51cyBpbnNpZGUgdGhlIHRhcmdldCB3aWxsIGJlIGNsb3NlZCBhcyB3ZWxsLlxyXG4gICAqIEBwYXJhbSB7alF1ZXJ5fSAkdGFyZ2V0IC0gU3ViLW1lbnUgdG8gY2xvc2UuXHJcbiAgICogQGZpcmVzIEFjY29yZGlvbk1lbnUjdXBcclxuICAgKi9cclxuICB1cCgkdGFyZ2V0KSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgLy9Gb3VuZGF0aW9uLk1vdmUodGhpcy5vcHRpb25zLnNsaWRlU3BlZWQsICR0YXJnZXQsIGZ1bmN0aW9uKCl7XHJcbiAgICAgICR0YXJnZXQuc2xpZGVVcChfdGhpcy5vcHRpb25zLnNsaWRlU3BlZWQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBGaXJlcyB3aGVuIHRoZSBtZW51IGlzIGRvbmUgY29sbGFwc2luZyB1cC5cclxuICAgICAgICAgKiBAZXZlbnQgQWNjb3JkaW9uTWVudSN1cFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIF90aGlzLiRlbGVtZW50LnRyaWdnZXIoJ3VwLnpmLmFjY29yZGlvbk1lbnUnLCBbJHRhcmdldF0pO1xyXG4gICAgICB9KTtcclxuICAgIC8vfSk7XHJcblxyXG4gICAgdmFyICRtZW51cyA9ICR0YXJnZXQuZmluZCgnW2RhdGEtc3VibWVudV0nKS5zbGlkZVVwKDApLmFkZEJhY2soKS5hdHRyKCdhcmlhLWhpZGRlbicsIHRydWUpO1xyXG5cclxuICAgICRtZW51cy5wYXJlbnQoJy5pcy1hY2NvcmRpb24tc3VibWVudS1wYXJlbnQnKS5hdHRyKCdhcmlhLWV4cGFuZGVkJywgZmFsc2UpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGVzdHJveXMgYW4gaW5zdGFuY2Ugb2YgYWNjb3JkaW9uIG1lbnUuXHJcbiAgICogQGZpcmVzIEFjY29yZGlvbk1lbnUjZGVzdHJveWVkXHJcbiAgICovXHJcbiAgZGVzdHJveSgpIHtcclxuICAgIHRoaXMuJGVsZW1lbnQuZmluZCgnW2RhdGEtc3VibWVudV0nKS5zbGlkZURvd24oMCkuY3NzKCdkaXNwbGF5JywgJycpO1xyXG4gICAgdGhpcy4kZWxlbWVudC5maW5kKCdhJykub2ZmKCdjbGljay56Zi5hY2NvcmRpb25NZW51Jyk7XHJcblxyXG4gICAgRm91bmRhdGlvbi5OZXN0LkJ1cm4odGhpcy4kZWxlbWVudCwgJ2FjY29yZGlvbicpO1xyXG4gICAgRm91bmRhdGlvbi51bnJlZ2lzdGVyUGx1Z2luKHRoaXMpO1xyXG4gIH1cclxufVxyXG5cclxuQWNjb3JkaW9uTWVudS5kZWZhdWx0cyA9IHtcclxuICAvKipcclxuICAgKiBBbW91bnQgb2YgdGltZSB0byBhbmltYXRlIHRoZSBvcGVuaW5nIG9mIGEgc3VibWVudSBpbiBtcy5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgMjUwXHJcbiAgICovXHJcbiAgc2xpZGVTcGVlZDogMjUwLFxyXG4gIC8qKlxyXG4gICAqIEFsbG93IHRoZSBtZW51IHRvIGhhdmUgbXVsdGlwbGUgb3BlbiBwYW5lcy5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgdHJ1ZVxyXG4gICAqL1xyXG4gIG11bHRpT3BlbjogdHJ1ZVxyXG59O1xyXG5cclxuLy8gV2luZG93IGV4cG9ydHNcclxuRm91bmRhdGlvbi5wbHVnaW4oQWNjb3JkaW9uTWVudSwgJ0FjY29yZGlvbk1lbnUnKTtcclxuXHJcbn0oalF1ZXJ5KTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxuIWZ1bmN0aW9uKCQpIHtcclxuXHJcbi8qKlxyXG4gKiBEcmlsbGRvd24gbW9kdWxlLlxyXG4gKiBAbW9kdWxlIGZvdW5kYXRpb24uZHJpbGxkb3duXHJcbiAqIEByZXF1aXJlcyBmb3VuZGF0aW9uLnV0aWwua2V5Ym9hcmRcclxuICogQHJlcXVpcmVzIGZvdW5kYXRpb24udXRpbC5tb3Rpb25cclxuICogQHJlcXVpcmVzIGZvdW5kYXRpb24udXRpbC5uZXN0XHJcbiAqL1xyXG5cclxuY2xhc3MgRHJpbGxkb3duIHtcclxuICAvKipcclxuICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIGEgZHJpbGxkb3duIG1lbnUuXHJcbiAgICogQGNsYXNzXHJcbiAgICogQHBhcmFtIHtqUXVlcnl9IGVsZW1lbnQgLSBqUXVlcnkgb2JqZWN0IHRvIG1ha2UgaW50byBhbiBhY2NvcmRpb24gbWVudS5cclxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIE92ZXJyaWRlcyB0byB0aGUgZGVmYXVsdCBwbHVnaW4gc2V0dGluZ3MuXHJcbiAgICovXHJcbiAgY29uc3RydWN0b3IoZWxlbWVudCwgb3B0aW9ucykge1xyXG4gICAgdGhpcy4kZWxlbWVudCA9IGVsZW1lbnQ7XHJcbiAgICB0aGlzLm9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgRHJpbGxkb3duLmRlZmF1bHRzLCB0aGlzLiRlbGVtZW50LmRhdGEoKSwgb3B0aW9ucyk7XHJcblxyXG4gICAgRm91bmRhdGlvbi5OZXN0LkZlYXRoZXIodGhpcy4kZWxlbWVudCwgJ2RyaWxsZG93bicpO1xyXG5cclxuICAgIHRoaXMuX2luaXQoKTtcclxuXHJcbiAgICBGb3VuZGF0aW9uLnJlZ2lzdGVyUGx1Z2luKHRoaXMsICdEcmlsbGRvd24nKTtcclxuICAgIEZvdW5kYXRpb24uS2V5Ym9hcmQucmVnaXN0ZXIoJ0RyaWxsZG93bicsIHtcclxuICAgICAgJ0VOVEVSJzogJ29wZW4nLFxyXG4gICAgICAnU1BBQ0UnOiAnb3BlbicsXHJcbiAgICAgICdBUlJPV19SSUdIVCc6ICduZXh0JyxcclxuICAgICAgJ0FSUk9XX1VQJzogJ3VwJyxcclxuICAgICAgJ0FSUk9XX0RPV04nOiAnZG93bicsXHJcbiAgICAgICdBUlJPV19MRUZUJzogJ3ByZXZpb3VzJyxcclxuICAgICAgJ0VTQ0FQRSc6ICdjbG9zZScsXHJcbiAgICAgICdUQUInOiAnZG93bicsXHJcbiAgICAgICdTSElGVF9UQUInOiAndXAnXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpYWxpemVzIHRoZSBkcmlsbGRvd24gYnkgY3JlYXRpbmcgalF1ZXJ5IGNvbGxlY3Rpb25zIG9mIGVsZW1lbnRzXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfaW5pdCgpIHtcclxuICAgIHRoaXMuJHN1Ym1lbnVBbmNob3JzID0gdGhpcy4kZWxlbWVudC5maW5kKCdsaS5pcy1kcmlsbGRvd24tc3VibWVudS1wYXJlbnQnKS5jaGlsZHJlbignYScpO1xyXG4gICAgdGhpcy4kc3VibWVudXMgPSB0aGlzLiRzdWJtZW51QW5jaG9ycy5wYXJlbnQoJ2xpJykuY2hpbGRyZW4oJ1tkYXRhLXN1Ym1lbnVdJyk7XHJcbiAgICB0aGlzLiRtZW51SXRlbXMgPSB0aGlzLiRlbGVtZW50LmZpbmQoJ2xpJykubm90KCcuanMtZHJpbGxkb3duLWJhY2snKS5hdHRyKCdyb2xlJywgJ21lbnVpdGVtJykuZmluZCgnYScpO1xyXG5cclxuICAgIHRoaXMuX3ByZXBhcmVNZW51KCk7XHJcblxyXG4gICAgdGhpcy5fa2V5Ym9hcmRFdmVudHMoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIHByZXBhcmVzIGRyaWxsZG93biBtZW51IGJ5IHNldHRpbmcgYXR0cmlidXRlcyB0byBsaW5rcyBhbmQgZWxlbWVudHNcclxuICAgKiBzZXRzIGEgbWluIGhlaWdodCB0byBwcmV2ZW50IGNvbnRlbnQganVtcGluZ1xyXG4gICAqIHdyYXBzIHRoZSBlbGVtZW50IGlmIG5vdCBhbHJlYWR5IHdyYXBwZWRcclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqL1xyXG4gIF9wcmVwYXJlTWVudSgpIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAvLyBpZighdGhpcy5vcHRpb25zLmhvbGRPcGVuKXtcclxuICAgIC8vICAgdGhpcy5fbWVudUxpbmtFdmVudHMoKTtcclxuICAgIC8vIH1cclxuICAgIHRoaXMuJHN1Ym1lbnVBbmNob3JzLmVhY2goZnVuY3Rpb24oKXtcclxuICAgICAgdmFyICRsaW5rID0gJCh0aGlzKTtcclxuICAgICAgdmFyICRzdWIgPSAkbGluay5wYXJlbnQoKTtcclxuICAgICAgaWYoX3RoaXMub3B0aW9ucy5wYXJlbnRMaW5rKXtcclxuICAgICAgICAkbGluay5jbG9uZSgpLnByZXBlbmRUbygkc3ViLmNoaWxkcmVuKCdbZGF0YS1zdWJtZW51XScpKS53cmFwKCc8bGkgY2xhc3M9XCJpcy1zdWJtZW51LXBhcmVudC1pdGVtIGlzLXN1Ym1lbnUtaXRlbSBpcy1kcmlsbGRvd24tc3VibWVudS1pdGVtXCIgcm9sZT1cIm1lbnUtaXRlbVwiPjwvbGk+Jyk7XHJcbiAgICAgIH1cclxuICAgICAgJGxpbmsuZGF0YSgnc2F2ZWRIcmVmJywgJGxpbmsuYXR0cignaHJlZicpKS5yZW1vdmVBdHRyKCdocmVmJyk7XHJcbiAgICAgICRsaW5rLmNoaWxkcmVuKCdbZGF0YS1zdWJtZW51XScpXHJcbiAgICAgICAgICAuYXR0cih7XHJcbiAgICAgICAgICAgICdhcmlhLWhpZGRlbic6IHRydWUsXHJcbiAgICAgICAgICAgICd0YWJpbmRleCc6IDAsXHJcbiAgICAgICAgICAgICdyb2xlJzogJ21lbnUnXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgX3RoaXMuX2V2ZW50cygkbGluayk7XHJcbiAgICB9KTtcclxuICAgIHRoaXMuJHN1Ym1lbnVzLmVhY2goZnVuY3Rpb24oKXtcclxuICAgICAgdmFyICRtZW51ID0gJCh0aGlzKSxcclxuICAgICAgICAgICRiYWNrID0gJG1lbnUuZmluZCgnLmpzLWRyaWxsZG93bi1iYWNrJyk7XHJcbiAgICAgIGlmKCEkYmFjay5sZW5ndGgpe1xyXG4gICAgICAgICRtZW51LnByZXBlbmQoX3RoaXMub3B0aW9ucy5iYWNrQnV0dG9uKTtcclxuICAgICAgfVxyXG4gICAgICBfdGhpcy5fYmFjaygkbWVudSk7XHJcbiAgICB9KTtcclxuICAgIGlmKCF0aGlzLiRlbGVtZW50LnBhcmVudCgpLmhhc0NsYXNzKCdpcy1kcmlsbGRvd24nKSl7XHJcbiAgICAgIHRoaXMuJHdyYXBwZXIgPSAkKHRoaXMub3B0aW9ucy53cmFwcGVyKS5hZGRDbGFzcygnaXMtZHJpbGxkb3duJyk7XHJcbiAgICAgIHRoaXMuJHdyYXBwZXIgPSB0aGlzLiRlbGVtZW50LndyYXAodGhpcy4kd3JhcHBlcikucGFyZW50KCkuY3NzKHRoaXMuX2dldE1heERpbXMoKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBZGRzIGV2ZW50IGhhbmRsZXJzIHRvIGVsZW1lbnRzIGluIHRoZSBtZW51LlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIEBwcml2YXRlXHJcbiAgICogQHBhcmFtIHtqUXVlcnl9ICRlbGVtIC0gdGhlIGN1cnJlbnQgbWVudSBpdGVtIHRvIGFkZCBoYW5kbGVycyB0by5cclxuICAgKi9cclxuICBfZXZlbnRzKCRlbGVtKSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG5cclxuICAgICRlbGVtLm9mZignY2xpY2suemYuZHJpbGxkb3duJylcclxuICAgIC5vbignY2xpY2suemYuZHJpbGxkb3duJywgZnVuY3Rpb24oZSl7XHJcbiAgICAgIGlmKCQoZS50YXJnZXQpLnBhcmVudHNVbnRpbCgndWwnLCAnbGknKS5oYXNDbGFzcygnaXMtZHJpbGxkb3duLXN1Ym1lbnUtcGFyZW50Jykpe1xyXG4gICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBpZihlLnRhcmdldCAhPT0gZS5jdXJyZW50VGFyZ2V0LmZpcnN0RWxlbWVudENoaWxkKXtcclxuICAgICAgLy8gICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIC8vIH1cclxuICAgICAgX3RoaXMuX3Nob3coJGVsZW0ucGFyZW50KCdsaScpKTtcclxuXHJcbiAgICAgIGlmKF90aGlzLm9wdGlvbnMuY2xvc2VPbkNsaWNrKXtcclxuICAgICAgICB2YXIgJGJvZHkgPSAkKCdib2R5Jyk7XHJcbiAgICAgICAgJGJvZHkub2ZmKCcuemYuZHJpbGxkb3duJykub24oJ2NsaWNrLnpmLmRyaWxsZG93bicsIGZ1bmN0aW9uKGUpe1xyXG4gICAgICAgICAgaWYgKGUudGFyZ2V0ID09PSBfdGhpcy4kZWxlbWVudFswXSB8fCAkLmNvbnRhaW5zKF90aGlzLiRlbGVtZW50WzBdLCBlLnRhcmdldCkpIHsgcmV0dXJuOyB9XHJcbiAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICBfdGhpcy5faGlkZUFsbCgpO1xyXG4gICAgICAgICAgJGJvZHkub2ZmKCcuemYuZHJpbGxkb3duJyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQWRkcyBrZXlkb3duIGV2ZW50IGxpc3RlbmVyIHRvIGBsaWAncyBpbiB0aGUgbWVudS5cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9rZXlib2FyZEV2ZW50cygpIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcblxyXG4gICAgdGhpcy4kbWVudUl0ZW1zLmFkZCh0aGlzLiRlbGVtZW50LmZpbmQoJy5qcy1kcmlsbGRvd24tYmFjayA+IGEnKSkub24oJ2tleWRvd24uemYuZHJpbGxkb3duJywgZnVuY3Rpb24oZSl7XHJcblxyXG4gICAgICB2YXIgJGVsZW1lbnQgPSAkKHRoaXMpLFxyXG4gICAgICAgICAgJGVsZW1lbnRzID0gJGVsZW1lbnQucGFyZW50KCdsaScpLnBhcmVudCgndWwnKS5jaGlsZHJlbignbGknKS5jaGlsZHJlbignYScpLFxyXG4gICAgICAgICAgJHByZXZFbGVtZW50LFxyXG4gICAgICAgICAgJG5leHRFbGVtZW50O1xyXG5cclxuICAgICAgJGVsZW1lbnRzLmVhY2goZnVuY3Rpb24oaSkge1xyXG4gICAgICAgIGlmICgkKHRoaXMpLmlzKCRlbGVtZW50KSkge1xyXG4gICAgICAgICAgJHByZXZFbGVtZW50ID0gJGVsZW1lbnRzLmVxKE1hdGgubWF4KDAsIGktMSkpO1xyXG4gICAgICAgICAgJG5leHRFbGVtZW50ID0gJGVsZW1lbnRzLmVxKE1hdGgubWluKGkrMSwgJGVsZW1lbnRzLmxlbmd0aC0xKSk7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIEZvdW5kYXRpb24uS2V5Ym9hcmQuaGFuZGxlS2V5KGUsICdEcmlsbGRvd24nLCB7XHJcbiAgICAgICAgbmV4dDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICBpZiAoJGVsZW1lbnQuaXMoX3RoaXMuJHN1Ym1lbnVBbmNob3JzKSkge1xyXG4gICAgICAgICAgICBfdGhpcy5fc2hvdygkZWxlbWVudC5wYXJlbnQoJ2xpJykpO1xyXG4gICAgICAgICAgICAkZWxlbWVudC5wYXJlbnQoJ2xpJykub25lKEZvdW5kYXRpb24udHJhbnNpdGlvbmVuZCgkZWxlbWVudCksIGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICAgJGVsZW1lbnQucGFyZW50KCdsaScpLmZpbmQoJ3VsIGxpIGEnKS5maWx0ZXIoX3RoaXMuJG1lbnVJdGVtcykuZmlyc3QoKS5mb2N1cygpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBwcmV2aW91czogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICBfdGhpcy5faGlkZSgkZWxlbWVudC5wYXJlbnQoJ2xpJykucGFyZW50KCd1bCcpKTtcclxuICAgICAgICAgICRlbGVtZW50LnBhcmVudCgnbGknKS5wYXJlbnQoJ3VsJykub25lKEZvdW5kYXRpb24udHJhbnNpdGlvbmVuZCgkZWxlbWVudCksIGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgJGVsZW1lbnQucGFyZW50KCdsaScpLnBhcmVudCgndWwnKS5wYXJlbnQoJ2xpJykuY2hpbGRyZW4oJ2EnKS5maXJzdCgpLmZvY3VzKCk7XHJcbiAgICAgICAgICAgIH0sIDEpO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIHVwOiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICRwcmV2RWxlbWVudC5mb2N1cygpO1xyXG4gICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBkb3duOiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICRuZXh0RWxlbWVudC5mb2N1cygpO1xyXG4gICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBjbG9zZTogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICBfdGhpcy5fYmFjaygpO1xyXG4gICAgICAgICAgLy9fdGhpcy4kbWVudUl0ZW1zLmZpcnN0KCkuZm9jdXMoKTsgLy8gZm9jdXMgdG8gZmlyc3QgZWxlbWVudFxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgb3BlbjogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICBpZiAoISRlbGVtZW50LmlzKF90aGlzLiRtZW51SXRlbXMpKSB7IC8vIG5vdCBtZW51IGl0ZW0gbWVhbnMgYmFjayBidXR0b25cclxuICAgICAgICAgICAgX3RoaXMuX2hpZGUoJGVsZW1lbnQucGFyZW50KCdsaScpLnBhcmVudCgndWwnKSk7XHJcbiAgICAgICAgICAgICRlbGVtZW50LnBhcmVudCgnbGknKS5wYXJlbnQoJ3VsJykub25lKEZvdW5kYXRpb24udHJhbnNpdGlvbmVuZCgkZWxlbWVudCksIGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICRlbGVtZW50LnBhcmVudCgnbGknKS5wYXJlbnQoJ3VsJykucGFyZW50KCdsaScpLmNoaWxkcmVuKCdhJykuZmlyc3QoKS5mb2N1cygpO1xyXG4gICAgICAgICAgICAgIH0sIDEpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgIH0gZWxzZSBpZiAoJGVsZW1lbnQuaXMoX3RoaXMuJHN1Ym1lbnVBbmNob3JzKSkge1xyXG4gICAgICAgICAgICBfdGhpcy5fc2hvdygkZWxlbWVudC5wYXJlbnQoJ2xpJykpO1xyXG4gICAgICAgICAgICAkZWxlbWVudC5wYXJlbnQoJ2xpJykub25lKEZvdW5kYXRpb24udHJhbnNpdGlvbmVuZCgkZWxlbWVudCksIGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICAgJGVsZW1lbnQucGFyZW50KCdsaScpLmZpbmQoJ3VsIGxpIGEnKS5maWx0ZXIoX3RoaXMuJG1lbnVJdGVtcykuZmlyc3QoKS5mb2N1cygpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgaGFuZGxlZDogZnVuY3Rpb24ocHJldmVudERlZmF1bHQpIHtcclxuICAgICAgICAgIGlmIChwcmV2ZW50RGVmYXVsdCkge1xyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9KTsgLy8gZW5kIGtleWJvYXJkQWNjZXNzXHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDbG9zZXMgYWxsIG9wZW4gZWxlbWVudHMsIGFuZCByZXR1cm5zIHRvIHJvb3QgbWVudS5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAZmlyZXMgRHJpbGxkb3duI2Nsb3NlZFxyXG4gICAqL1xyXG4gIF9oaWRlQWxsKCkge1xyXG4gICAgdmFyICRlbGVtID0gdGhpcy4kZWxlbWVudC5maW5kKCcuaXMtZHJpbGxkb3duLXN1Ym1lbnUuaXMtYWN0aXZlJykuYWRkQ2xhc3MoJ2lzLWNsb3NpbmcnKTtcclxuICAgICRlbGVtLm9uZShGb3VuZGF0aW9uLnRyYW5zaXRpb25lbmQoJGVsZW0pLCBmdW5jdGlvbihlKXtcclxuICAgICAgJGVsZW0ucmVtb3ZlQ2xhc3MoJ2lzLWFjdGl2ZSBpcy1jbG9zaW5nJyk7XHJcbiAgICB9KTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBGaXJlcyB3aGVuIHRoZSBtZW51IGlzIGZ1bGx5IGNsb3NlZC5cclxuICAgICAgICAgKiBAZXZlbnQgRHJpbGxkb3duI2Nsb3NlZFxyXG4gICAgICAgICAqL1xyXG4gICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKCdjbG9zZWQuemYuZHJpbGxkb3duJyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBZGRzIGV2ZW50IGxpc3RlbmVyIGZvciBlYWNoIGBiYWNrYCBidXR0b24sIGFuZCBjbG9zZXMgb3BlbiBtZW51cy5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAZmlyZXMgRHJpbGxkb3duI2JhY2tcclxuICAgKiBAcGFyYW0ge2pRdWVyeX0gJGVsZW0gLSB0aGUgY3VycmVudCBzdWItbWVudSB0byBhZGQgYGJhY2tgIGV2ZW50LlxyXG4gICAqL1xyXG4gIF9iYWNrKCRlbGVtKSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgJGVsZW0ub2ZmKCdjbGljay56Zi5kcmlsbGRvd24nKTtcclxuICAgICRlbGVtLmNoaWxkcmVuKCcuanMtZHJpbGxkb3duLWJhY2snKVxyXG4gICAgICAub24oJ2NsaWNrLnpmLmRyaWxsZG93bicsIGZ1bmN0aW9uKGUpe1xyXG4gICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgLy8gY29uc29sZS5sb2coJ21vdXNldXAgb24gYmFjaycpO1xyXG4gICAgICAgIF90aGlzLl9oaWRlKCRlbGVtKTtcclxuICAgICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBZGRzIGV2ZW50IGxpc3RlbmVyIHRvIG1lbnUgaXRlbXMgdy9vIHN1Ym1lbnVzIHRvIGNsb3NlIG9wZW4gbWVudXMgb24gY2xpY2suXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfbWVudUxpbmtFdmVudHMoKSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgdGhpcy4kbWVudUl0ZW1zLm5vdCgnLmlzLWRyaWxsZG93bi1zdWJtZW51LXBhcmVudCcpXHJcbiAgICAgICAgLm9mZignY2xpY2suemYuZHJpbGxkb3duJylcclxuICAgICAgICAub24oJ2NsaWNrLnpmLmRyaWxsZG93bicsIGZ1bmN0aW9uKGUpe1xyXG4gICAgICAgICAgLy8gZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgX3RoaXMuX2hpZGVBbGwoKTtcclxuICAgICAgICAgIH0sIDApO1xyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIE9wZW5zIGEgc3VibWVudS5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAZmlyZXMgRHJpbGxkb3duI29wZW5cclxuICAgKiBAcGFyYW0ge2pRdWVyeX0gJGVsZW0gLSB0aGUgY3VycmVudCBlbGVtZW50IHdpdGggYSBzdWJtZW51IHRvIG9wZW4sIGkuZS4gdGhlIGBsaWAgdGFnLlxyXG4gICAqL1xyXG4gIF9zaG93KCRlbGVtKSB7XHJcbiAgICAkZWxlbS5jaGlsZHJlbignW2RhdGEtc3VibWVudV0nKS5hZGRDbGFzcygnaXMtYWN0aXZlJyk7XHJcbiAgICAvKipcclxuICAgICAqIEZpcmVzIHdoZW4gdGhlIHN1Ym1lbnUgaGFzIG9wZW5lZC5cclxuICAgICAqIEBldmVudCBEcmlsbGRvd24jb3BlblxyXG4gICAgICovXHJcbiAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ29wZW4uemYuZHJpbGxkb3duJywgWyRlbGVtXSk7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogSGlkZXMgYSBzdWJtZW51XHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQGZpcmVzIERyaWxsZG93biNoaWRlXHJcbiAgICogQHBhcmFtIHtqUXVlcnl9ICRlbGVtIC0gdGhlIGN1cnJlbnQgc3ViLW1lbnUgdG8gaGlkZSwgaS5lLiB0aGUgYHVsYCB0YWcuXHJcbiAgICovXHJcbiAgX2hpZGUoJGVsZW0pIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAkZWxlbS5hZGRDbGFzcygnaXMtY2xvc2luZycpXHJcbiAgICAgICAgIC5vbmUoRm91bmRhdGlvbi50cmFuc2l0aW9uZW5kKCRlbGVtKSwgZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAkZWxlbS5yZW1vdmVDbGFzcygnaXMtYWN0aXZlIGlzLWNsb3NpbmcnKTtcclxuICAgICAgICAgICAkZWxlbS5ibHVyKCk7XHJcbiAgICAgICAgIH0pO1xyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlcyB3aGVuIHRoZSBzdWJtZW51IGhhcyBjbG9zZWQuXHJcbiAgICAgKiBAZXZlbnQgRHJpbGxkb3duI2hpZGVcclxuICAgICAqL1xyXG4gICAgJGVsZW0udHJpZ2dlcignaGlkZS56Zi5kcmlsbGRvd24nLCBbJGVsZW1dKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEl0ZXJhdGVzIHRocm91Z2ggdGhlIG5lc3RlZCBtZW51cyB0byBjYWxjdWxhdGUgdGhlIG1pbi1oZWlnaHQsIGFuZCBtYXgtd2lkdGggZm9yIHRoZSBtZW51LlxyXG4gICAqIFByZXZlbnRzIGNvbnRlbnQganVtcGluZy5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9nZXRNYXhEaW1zKCkge1xyXG4gICAgdmFyIG1heCA9IDAsIHJlc3VsdCA9IHt9O1xyXG4gICAgdGhpcy4kc3VibWVudXMuYWRkKHRoaXMuJGVsZW1lbnQpLmVhY2goZnVuY3Rpb24oKXtcclxuICAgICAgdmFyIG51bU9mRWxlbXMgPSAkKHRoaXMpLmNoaWxkcmVuKCdsaScpLmxlbmd0aDtcclxuICAgICAgbWF4ID0gbnVtT2ZFbGVtcyA+IG1heCA/IG51bU9mRWxlbXMgOiBtYXg7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXN1bHRbJ21pbi1oZWlnaHQnXSA9IGAke21heCAqIHRoaXMuJG1lbnVJdGVtc1swXS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHR9cHhgO1xyXG4gICAgcmVzdWx0WydtYXgtd2lkdGgnXSA9IGAke3RoaXMuJGVsZW1lbnRbMF0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGh9cHhgO1xyXG5cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBEZXN0cm95cyB0aGUgRHJpbGxkb3duIE1lbnVcclxuICAgKiBAZnVuY3Rpb25cclxuICAgKi9cclxuICBkZXN0cm95KCkge1xyXG4gICAgdGhpcy5faGlkZUFsbCgpO1xyXG4gICAgRm91bmRhdGlvbi5OZXN0LkJ1cm4odGhpcy4kZWxlbWVudCwgJ2RyaWxsZG93bicpO1xyXG4gICAgdGhpcy4kZWxlbWVudC51bndyYXAoKVxyXG4gICAgICAgICAgICAgICAgIC5maW5kKCcuanMtZHJpbGxkb3duLWJhY2ssIC5pcy1zdWJtZW51LXBhcmVudC1pdGVtJykucmVtb3ZlKClcclxuICAgICAgICAgICAgICAgICAuZW5kKCkuZmluZCgnLmlzLWFjdGl2ZSwgLmlzLWNsb3NpbmcsIC5pcy1kcmlsbGRvd24tc3VibWVudScpLnJlbW92ZUNsYXNzKCdpcy1hY3RpdmUgaXMtY2xvc2luZyBpcy1kcmlsbGRvd24tc3VibWVudScpXHJcbiAgICAgICAgICAgICAgICAgLmVuZCgpLmZpbmQoJ1tkYXRhLXN1Ym1lbnVdJykucmVtb3ZlQXR0cignYXJpYS1oaWRkZW4gdGFiaW5kZXggcm9sZScpO1xyXG4gICAgdGhpcy4kc3VibWVudUFuY2hvcnMuZWFjaChmdW5jdGlvbigpIHtcclxuICAgICAgJCh0aGlzKS5vZmYoJy56Zi5kcmlsbGRvd24nKTtcclxuICAgIH0pO1xyXG4gICAgdGhpcy4kZWxlbWVudC5maW5kKCdhJykuZWFjaChmdW5jdGlvbigpe1xyXG4gICAgICB2YXIgJGxpbmsgPSAkKHRoaXMpO1xyXG4gICAgICBpZigkbGluay5kYXRhKCdzYXZlZEhyZWYnKSl7XHJcbiAgICAgICAgJGxpbmsuYXR0cignaHJlZicsICRsaW5rLmRhdGEoJ3NhdmVkSHJlZicpKS5yZW1vdmVEYXRhKCdzYXZlZEhyZWYnKTtcclxuICAgICAgfWVsc2V7IHJldHVybjsgfVxyXG4gICAgfSk7XHJcbiAgICBGb3VuZGF0aW9uLnVucmVnaXN0ZXJQbHVnaW4odGhpcyk7XHJcbiAgfTtcclxufVxyXG5cclxuRHJpbGxkb3duLmRlZmF1bHRzID0ge1xyXG4gIC8qKlxyXG4gICAqIE1hcmt1cCB1c2VkIGZvciBKUyBnZW5lcmF0ZWQgYmFjayBidXR0b24uIFByZXBlbmRlZCB0byBzdWJtZW51IGxpc3RzIGFuZCBkZWxldGVkIG9uIGBkZXN0cm95YCBtZXRob2QsICdqcy1kcmlsbGRvd24tYmFjaycgY2xhc3MgcmVxdWlyZWQuIFJlbW92ZSB0aGUgYmFja3NsYXNoIChgXFxgKSBpZiBjb3B5IGFuZCBwYXN0aW5nLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAnPFxcbGk+PFxcYT5CYWNrPFxcL2E+PFxcL2xpPidcclxuICAgKi9cclxuICBiYWNrQnV0dG9uOiAnPGxpIGNsYXNzPVwianMtZHJpbGxkb3duLWJhY2tcIj48YSB0YWJpbmRleD1cIjBcIj5CYWNrPC9hPjwvbGk+JyxcclxuICAvKipcclxuICAgKiBNYXJrdXAgdXNlZCB0byB3cmFwIGRyaWxsZG93biBtZW51LiBVc2UgYSBjbGFzcyBuYW1lIGZvciBpbmRlcGVuZGVudCBzdHlsaW5nOyB0aGUgSlMgYXBwbGllZCBjbGFzczogYGlzLWRyaWxsZG93bmAgaXMgcmVxdWlyZWQuIFJlbW92ZSB0aGUgYmFja3NsYXNoIChgXFxgKSBpZiBjb3B5IGFuZCBwYXN0aW5nLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAnPFxcZGl2IGNsYXNzPVwiaXMtZHJpbGxkb3duXCI+PFxcL2Rpdj4nXHJcbiAgICovXHJcbiAgd3JhcHBlcjogJzxkaXY+PC9kaXY+JyxcclxuICAvKipcclxuICAgKiBBZGRzIHRoZSBwYXJlbnQgbGluayB0byB0aGUgc3VibWVudS5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgZmFsc2VcclxuICAgKi9cclxuICBwYXJlbnRMaW5rOiBmYWxzZSxcclxuICAvKipcclxuICAgKiBBbGxvdyB0aGUgbWVudSB0byByZXR1cm4gdG8gcm9vdCBsaXN0IG9uIGJvZHkgY2xpY2suXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIGZhbHNlXHJcbiAgICovXHJcbiAgY2xvc2VPbkNsaWNrOiBmYWxzZVxyXG4gIC8vIGhvbGRPcGVuOiBmYWxzZVxyXG59O1xyXG5cclxuLy8gV2luZG93IGV4cG9ydHNcclxuRm91bmRhdGlvbi5wbHVnaW4oRHJpbGxkb3duLCAnRHJpbGxkb3duJyk7XHJcblxyXG59KGpRdWVyeSk7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbiFmdW5jdGlvbigkKSB7XHJcblxyXG4vKipcclxuICogRHJvcGRvd24gbW9kdWxlLlxyXG4gKiBAbW9kdWxlIGZvdW5kYXRpb24uZHJvcGRvd25cclxuICogQHJlcXVpcmVzIGZvdW5kYXRpb24udXRpbC5rZXlib2FyZFxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLmJveFxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLnRyaWdnZXJzXHJcbiAqL1xyXG5cclxuY2xhc3MgRHJvcGRvd24ge1xyXG4gIC8qKlxyXG4gICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgYSBkcm9wZG93bi5cclxuICAgKiBAY2xhc3NcclxuICAgKiBAcGFyYW0ge2pRdWVyeX0gZWxlbWVudCAtIGpRdWVyeSBvYmplY3QgdG8gbWFrZSBpbnRvIGEgZHJvcGRvd24uXHJcbiAgICogICAgICAgIE9iamVjdCBzaG91bGQgYmUgb2YgdGhlIGRyb3Bkb3duIHBhbmVsLCByYXRoZXIgdGhhbiBpdHMgYW5jaG9yLlxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gT3ZlcnJpZGVzIHRvIHRoZSBkZWZhdWx0IHBsdWdpbiBzZXR0aW5ncy5cclxuICAgKi9cclxuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBvcHRpb25zKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50ID0gZWxlbWVudDtcclxuICAgIHRoaXMub3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBEcm9wZG93bi5kZWZhdWx0cywgdGhpcy4kZWxlbWVudC5kYXRhKCksIG9wdGlvbnMpO1xyXG4gICAgdGhpcy5faW5pdCgpO1xyXG5cclxuICAgIEZvdW5kYXRpb24ucmVnaXN0ZXJQbHVnaW4odGhpcywgJ0Ryb3Bkb3duJyk7XHJcbiAgICBGb3VuZGF0aW9uLktleWJvYXJkLnJlZ2lzdGVyKCdEcm9wZG93bicsIHtcclxuICAgICAgJ0VOVEVSJzogJ29wZW4nLFxyXG4gICAgICAnU1BBQ0UnOiAnb3BlbicsXHJcbiAgICAgICdFU0NBUEUnOiAnY2xvc2UnLFxyXG4gICAgICAnVEFCJzogJ3RhYl9mb3J3YXJkJyxcclxuICAgICAgJ1NISUZUX1RBQic6ICd0YWJfYmFja3dhcmQnXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpYWxpemVzIHRoZSBwbHVnaW4gYnkgc2V0dGluZy9jaGVja2luZyBvcHRpb25zIGFuZCBhdHRyaWJ1dGVzLCBhZGRpbmcgaGVscGVyIHZhcmlhYmxlcywgYW5kIHNhdmluZyB0aGUgYW5jaG9yLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX2luaXQoKSB7XHJcbiAgICB2YXIgJGlkID0gdGhpcy4kZWxlbWVudC5hdHRyKCdpZCcpO1xyXG5cclxuICAgIHRoaXMuJGFuY2hvciA9ICQoYFtkYXRhLXRvZ2dsZT1cIiR7JGlkfVwiXWApIHx8ICQoYFtkYXRhLW9wZW49XCIkeyRpZH1cIl1gKTtcclxuICAgIHRoaXMuJGFuY2hvci5hdHRyKHtcclxuICAgICAgJ2FyaWEtY29udHJvbHMnOiAkaWQsXHJcbiAgICAgICdkYXRhLWlzLWZvY3VzJzogZmFsc2UsXHJcbiAgICAgICdkYXRhLXlldGktYm94JzogJGlkLFxyXG4gICAgICAnYXJpYS1oYXNwb3B1cCc6IHRydWUsXHJcbiAgICAgICdhcmlhLWV4cGFuZGVkJzogZmFsc2VcclxuXHJcbiAgICB9KTtcclxuXHJcbiAgICB0aGlzLm9wdGlvbnMucG9zaXRpb25DbGFzcyA9IHRoaXMuZ2V0UG9zaXRpb25DbGFzcygpO1xyXG4gICAgdGhpcy5jb3VudGVyID0gNDtcclxuICAgIHRoaXMudXNlZFBvc2l0aW9ucyA9IFtdO1xyXG4gICAgdGhpcy4kZWxlbWVudC5hdHRyKHtcclxuICAgICAgJ2FyaWEtaGlkZGVuJzogJ3RydWUnLFxyXG4gICAgICAnZGF0YS15ZXRpLWJveCc6ICRpZCxcclxuICAgICAgJ2RhdGEtcmVzaXplJzogJGlkLFxyXG4gICAgICAnYXJpYS1sYWJlbGxlZGJ5JzogdGhpcy4kYW5jaG9yWzBdLmlkIHx8IEZvdW5kYXRpb24uR2V0WW9EaWdpdHMoNiwgJ2RkLWFuY2hvcicpXHJcbiAgICB9KTtcclxuICAgIHRoaXMuX2V2ZW50cygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGVscGVyIGZ1bmN0aW9uIHRvIGRldGVybWluZSBjdXJyZW50IG9yaWVudGF0aW9uIG9mIGRyb3Bkb3duIHBhbmUuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHJldHVybnMge1N0cmluZ30gcG9zaXRpb24gLSBzdHJpbmcgdmFsdWUgb2YgYSBwb3NpdGlvbiBjbGFzcy5cclxuICAgKi9cclxuICBnZXRQb3NpdGlvbkNsYXNzKCkge1xyXG4gICAgdmFyIHZlcnRpY2FsUG9zaXRpb24gPSB0aGlzLiRlbGVtZW50WzBdLmNsYXNzTmFtZS5tYXRjaCgvKHRvcHxsZWZ0fHJpZ2h0fGJvdHRvbSkvZyk7XHJcbiAgICAgICAgdmVydGljYWxQb3NpdGlvbiA9IHZlcnRpY2FsUG9zaXRpb24gPyB2ZXJ0aWNhbFBvc2l0aW9uWzBdIDogJyc7XHJcbiAgICB2YXIgaG9yaXpvbnRhbFBvc2l0aW9uID0gL2Zsb2F0LShcXFMrKVxccy8uZXhlYyh0aGlzLiRhbmNob3JbMF0uY2xhc3NOYW1lKTtcclxuICAgICAgICBob3Jpem9udGFsUG9zaXRpb24gPSBob3Jpem9udGFsUG9zaXRpb24gPyBob3Jpem9udGFsUG9zaXRpb25bMV0gOiAnJztcclxuICAgIHZhciBwb3NpdGlvbiA9IGhvcml6b250YWxQb3NpdGlvbiA/IGhvcml6b250YWxQb3NpdGlvbiArICcgJyArIHZlcnRpY2FsUG9zaXRpb24gOiB2ZXJ0aWNhbFBvc2l0aW9uO1xyXG4gICAgcmV0dXJuIHBvc2l0aW9uO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQWRqdXN0cyB0aGUgZHJvcGRvd24gcGFuZXMgb3JpZW50YXRpb24gYnkgYWRkaW5nL3JlbW92aW5nIHBvc2l0aW9uaW5nIGNsYXNzZXMuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHByaXZhdGVcclxuICAgKiBAcGFyYW0ge1N0cmluZ30gcG9zaXRpb24gLSBwb3NpdGlvbiBjbGFzcyB0byByZW1vdmUuXHJcbiAgICovXHJcbiAgX3JlcG9zaXRpb24ocG9zaXRpb24pIHtcclxuICAgIHRoaXMudXNlZFBvc2l0aW9ucy5wdXNoKHBvc2l0aW9uID8gcG9zaXRpb24gOiAnYm90dG9tJyk7XHJcbiAgICAvL2RlZmF1bHQsIHRyeSBzd2l0Y2hpbmcgdG8gb3Bwb3NpdGUgc2lkZVxyXG4gICAgaWYoIXBvc2l0aW9uICYmICh0aGlzLnVzZWRQb3NpdGlvbnMuaW5kZXhPZigndG9wJykgPCAwKSl7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnQuYWRkQ2xhc3MoJ3RvcCcpO1xyXG4gICAgfWVsc2UgaWYocG9zaXRpb24gPT09ICd0b3AnICYmICh0aGlzLnVzZWRQb3NpdGlvbnMuaW5kZXhPZignYm90dG9tJykgPCAwKSl7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnQucmVtb3ZlQ2xhc3MocG9zaXRpb24pO1xyXG4gICAgfWVsc2UgaWYocG9zaXRpb24gPT09ICdsZWZ0JyAmJiAodGhpcy51c2VkUG9zaXRpb25zLmluZGV4T2YoJ3JpZ2h0JykgPCAwKSl7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnQucmVtb3ZlQ2xhc3MocG9zaXRpb24pXHJcbiAgICAgICAgICAuYWRkQ2xhc3MoJ3JpZ2h0Jyk7XHJcbiAgICB9ZWxzZSBpZihwb3NpdGlvbiA9PT0gJ3JpZ2h0JyAmJiAodGhpcy51c2VkUG9zaXRpb25zLmluZGV4T2YoJ2xlZnQnKSA8IDApKXtcclxuICAgICAgdGhpcy4kZWxlbWVudC5yZW1vdmVDbGFzcyhwb3NpdGlvbilcclxuICAgICAgICAgIC5hZGRDbGFzcygnbGVmdCcpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vaWYgZGVmYXVsdCBjaGFuZ2UgZGlkbid0IHdvcmssIHRyeSBib3R0b20gb3IgbGVmdCBmaXJzdFxyXG4gICAgZWxzZSBpZighcG9zaXRpb24gJiYgKHRoaXMudXNlZFBvc2l0aW9ucy5pbmRleE9mKCd0b3AnKSA+IC0xKSAmJiAodGhpcy51c2VkUG9zaXRpb25zLmluZGV4T2YoJ2xlZnQnKSA8IDApKXtcclxuICAgICAgdGhpcy4kZWxlbWVudC5hZGRDbGFzcygnbGVmdCcpO1xyXG4gICAgfWVsc2UgaWYocG9zaXRpb24gPT09ICd0b3AnICYmICh0aGlzLnVzZWRQb3NpdGlvbnMuaW5kZXhPZignYm90dG9tJykgPiAtMSkgJiYgKHRoaXMudXNlZFBvc2l0aW9ucy5pbmRleE9mKCdsZWZ0JykgPCAwKSl7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnQucmVtb3ZlQ2xhc3MocG9zaXRpb24pXHJcbiAgICAgICAgICAuYWRkQ2xhc3MoJ2xlZnQnKTtcclxuICAgIH1lbHNlIGlmKHBvc2l0aW9uID09PSAnbGVmdCcgJiYgKHRoaXMudXNlZFBvc2l0aW9ucy5pbmRleE9mKCdyaWdodCcpID4gLTEpICYmICh0aGlzLnVzZWRQb3NpdGlvbnMuaW5kZXhPZignYm90dG9tJykgPCAwKSl7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnQucmVtb3ZlQ2xhc3MocG9zaXRpb24pO1xyXG4gICAgfWVsc2UgaWYocG9zaXRpb24gPT09ICdyaWdodCcgJiYgKHRoaXMudXNlZFBvc2l0aW9ucy5pbmRleE9mKCdsZWZ0JykgPiAtMSkgJiYgKHRoaXMudXNlZFBvc2l0aW9ucy5pbmRleE9mKCdib3R0b20nKSA8IDApKXtcclxuICAgICAgdGhpcy4kZWxlbWVudC5yZW1vdmVDbGFzcyhwb3NpdGlvbik7XHJcbiAgICB9XHJcbiAgICAvL2lmIG5vdGhpbmcgY2xlYXJlZCwgc2V0IHRvIGJvdHRvbVxyXG4gICAgZWxzZXtcclxuICAgICAgdGhpcy4kZWxlbWVudC5yZW1vdmVDbGFzcyhwb3NpdGlvbik7XHJcbiAgICB9XHJcbiAgICB0aGlzLmNsYXNzQ2hhbmdlZCA9IHRydWU7XHJcbiAgICB0aGlzLmNvdW50ZXItLTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNldHMgdGhlIHBvc2l0aW9uIGFuZCBvcmllbnRhdGlvbiBvZiB0aGUgZHJvcGRvd24gcGFuZSwgY2hlY2tzIGZvciBjb2xsaXNpb25zLlxyXG4gICAqIFJlY3Vyc2l2ZWx5IGNhbGxzIGl0c2VsZiBpZiBhIGNvbGxpc2lvbiBpcyBkZXRlY3RlZCwgd2l0aCBhIG5ldyBwb3NpdGlvbiBjbGFzcy5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9zZXRQb3NpdGlvbigpIHtcclxuICAgIGlmKHRoaXMuJGFuY2hvci5hdHRyKCdhcmlhLWV4cGFuZGVkJykgPT09ICdmYWxzZScpeyByZXR1cm4gZmFsc2U7IH1cclxuICAgIHZhciBwb3NpdGlvbiA9IHRoaXMuZ2V0UG9zaXRpb25DbGFzcygpLFxyXG4gICAgICAgICRlbGVEaW1zID0gRm91bmRhdGlvbi5Cb3guR2V0RGltZW5zaW9ucyh0aGlzLiRlbGVtZW50KSxcclxuICAgICAgICAkYW5jaG9yRGltcyA9IEZvdW5kYXRpb24uQm94LkdldERpbWVuc2lvbnModGhpcy4kYW5jaG9yKSxcclxuICAgICAgICBfdGhpcyA9IHRoaXMsXHJcbiAgICAgICAgZGlyZWN0aW9uID0gKHBvc2l0aW9uID09PSAnbGVmdCcgPyAnbGVmdCcgOiAoKHBvc2l0aW9uID09PSAncmlnaHQnKSA/ICdsZWZ0JyA6ICd0b3AnKSksXHJcbiAgICAgICAgcGFyYW0gPSAoZGlyZWN0aW9uID09PSAndG9wJykgPyAnaGVpZ2h0JyA6ICd3aWR0aCcsXHJcbiAgICAgICAgb2Zmc2V0ID0gKHBhcmFtID09PSAnaGVpZ2h0JykgPyB0aGlzLm9wdGlvbnMudk9mZnNldCA6IHRoaXMub3B0aW9ucy5oT2Zmc2V0O1xyXG5cclxuXHJcblxyXG4gICAgaWYoKCRlbGVEaW1zLndpZHRoID49ICRlbGVEaW1zLndpbmRvd0RpbXMud2lkdGgpIHx8ICghdGhpcy5jb3VudGVyICYmICFGb3VuZGF0aW9uLkJveC5JbU5vdFRvdWNoaW5nWW91KHRoaXMuJGVsZW1lbnQpKSl7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnQub2Zmc2V0KEZvdW5kYXRpb24uQm94LkdldE9mZnNldHModGhpcy4kZWxlbWVudCwgdGhpcy4kYW5jaG9yLCAnY2VudGVyIGJvdHRvbScsIHRoaXMub3B0aW9ucy52T2Zmc2V0LCB0aGlzLm9wdGlvbnMuaE9mZnNldCwgdHJ1ZSkpLmNzcyh7XHJcbiAgICAgICAgJ3dpZHRoJzogJGVsZURpbXMud2luZG93RGltcy53aWR0aCAtICh0aGlzLm9wdGlvbnMuaE9mZnNldCAqIDIpLFxyXG4gICAgICAgICdoZWlnaHQnOiAnYXV0bydcclxuICAgICAgfSk7XHJcbiAgICAgIHRoaXMuY2xhc3NDaGFuZ2VkID0gdHJ1ZTtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuJGVsZW1lbnQub2Zmc2V0KEZvdW5kYXRpb24uQm94LkdldE9mZnNldHModGhpcy4kZWxlbWVudCwgdGhpcy4kYW5jaG9yLCBwb3NpdGlvbiwgdGhpcy5vcHRpb25zLnZPZmZzZXQsIHRoaXMub3B0aW9ucy5oT2Zmc2V0KSk7XHJcblxyXG4gICAgd2hpbGUoIUZvdW5kYXRpb24uQm94LkltTm90VG91Y2hpbmdZb3UodGhpcy4kZWxlbWVudCwgZmFsc2UsIHRydWUpICYmIHRoaXMuY291bnRlcil7XHJcbiAgICAgIHRoaXMuX3JlcG9zaXRpb24ocG9zaXRpb24pO1xyXG4gICAgICB0aGlzLl9zZXRQb3NpdGlvbigpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQWRkcyBldmVudCBsaXN0ZW5lcnMgdG8gdGhlIGVsZW1lbnQgdXRpbGl6aW5nIHRoZSB0cmlnZ2VycyB1dGlsaXR5IGxpYnJhcnkuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfZXZlbnRzKCkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgIHRoaXMuJGVsZW1lbnQub24oe1xyXG4gICAgICAnb3Blbi56Zi50cmlnZ2VyJzogdGhpcy5vcGVuLmJpbmQodGhpcyksXHJcbiAgICAgICdjbG9zZS56Zi50cmlnZ2VyJzogdGhpcy5jbG9zZS5iaW5kKHRoaXMpLFxyXG4gICAgICAndG9nZ2xlLnpmLnRyaWdnZXInOiB0aGlzLnRvZ2dsZS5iaW5kKHRoaXMpLFxyXG4gICAgICAncmVzaXplbWUuemYudHJpZ2dlcic6IHRoaXMuX3NldFBvc2l0aW9uLmJpbmQodGhpcylcclxuICAgIH0pO1xyXG5cclxuICAgIGlmKHRoaXMub3B0aW9ucy5ob3Zlcil7XHJcbiAgICAgIHRoaXMuJGFuY2hvci5vZmYoJ21vdXNlZW50ZXIuemYuZHJvcGRvd24gbW91c2VsZWF2ZS56Zi5kcm9wZG93bicpXHJcbiAgICAgICAgICAub24oJ21vdXNlZW50ZXIuemYuZHJvcGRvd24nLCBmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICBjbGVhclRpbWVvdXQoX3RoaXMudGltZW91dCk7XHJcbiAgICAgICAgICAgIF90aGlzLnRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICAgX3RoaXMub3BlbigpO1xyXG4gICAgICAgICAgICAgIF90aGlzLiRhbmNob3IuZGF0YSgnaG92ZXInLCB0cnVlKTtcclxuICAgICAgICAgICAgfSwgX3RoaXMub3B0aW9ucy5ob3ZlckRlbGF5KTtcclxuICAgICAgICAgIH0pLm9uKCdtb3VzZWxlYXZlLnpmLmRyb3Bkb3duJywgZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KF90aGlzLnRpbWVvdXQpO1xyXG4gICAgICAgICAgICBfdGhpcy50aW1lb3V0ID0gc2V0VGltZW91dChmdW5jdGlvbigpe1xyXG4gICAgICAgICAgICAgIF90aGlzLmNsb3NlKCk7XHJcbiAgICAgICAgICAgICAgX3RoaXMuJGFuY2hvci5kYXRhKCdob3ZlcicsIGZhbHNlKTtcclxuICAgICAgICAgICAgfSwgX3RoaXMub3B0aW9ucy5ob3ZlckRlbGF5KTtcclxuICAgICAgICAgIH0pO1xyXG4gICAgICBpZih0aGlzLm9wdGlvbnMuaG92ZXJQYW5lKXtcclxuICAgICAgICB0aGlzLiRlbGVtZW50Lm9mZignbW91c2VlbnRlci56Zi5kcm9wZG93biBtb3VzZWxlYXZlLnpmLmRyb3Bkb3duJylcclxuICAgICAgICAgICAgLm9uKCdtb3VzZWVudGVyLnpmLmRyb3Bkb3duJywgZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoX3RoaXMudGltZW91dCk7XHJcbiAgICAgICAgICAgIH0pLm9uKCdtb3VzZWxlYXZlLnpmLmRyb3Bkb3duJywgZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgICBjbGVhclRpbWVvdXQoX3RoaXMudGltZW91dCk7XHJcbiAgICAgICAgICAgICAgX3RoaXMudGltZW91dCA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgICAgIF90aGlzLmNsb3NlKCk7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy4kYW5jaG9yLmRhdGEoJ2hvdmVyJywgZmFsc2UpO1xyXG4gICAgICAgICAgICAgIH0sIF90aGlzLm9wdGlvbnMuaG92ZXJEZWxheSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICB0aGlzLiRhbmNob3IuYWRkKHRoaXMuJGVsZW1lbnQpLm9uKCdrZXlkb3duLnpmLmRyb3Bkb3duJywgZnVuY3Rpb24oZSkge1xyXG5cclxuICAgICAgdmFyICR0YXJnZXQgPSAkKHRoaXMpLFxyXG4gICAgICAgIHZpc2libGVGb2N1c2FibGVFbGVtZW50cyA9IEZvdW5kYXRpb24uS2V5Ym9hcmQuZmluZEZvY3VzYWJsZShfdGhpcy4kZWxlbWVudCk7XHJcblxyXG4gICAgICBGb3VuZGF0aW9uLktleWJvYXJkLmhhbmRsZUtleShlLCAnRHJvcGRvd24nLCB7XHJcbiAgICAgICAgdGFiX2ZvcndhcmQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgaWYgKF90aGlzLiRlbGVtZW50LmZpbmQoJzpmb2N1cycpLmlzKHZpc2libGVGb2N1c2FibGVFbGVtZW50cy5lcSgtMSkpKSB7IC8vIGxlZnQgbW9kYWwgZG93bndhcmRzLCBzZXR0aW5nIGZvY3VzIHRvIGZpcnN0IGVsZW1lbnRcclxuICAgICAgICAgICAgaWYgKF90aGlzLm9wdGlvbnMudHJhcEZvY3VzKSB7IC8vIGlmIGZvY3VzIHNoYWxsIGJlIHRyYXBwZWRcclxuICAgICAgICAgICAgICB2aXNpYmxlRm9jdXNhYmxlRWxlbWVudHMuZXEoMCkuZm9jdXMoKTtcclxuICAgICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7IC8vIGlmIGZvY3VzIGlzIG5vdCB0cmFwcGVkLCBjbG9zZSBkcm9wZG93biBvbiBmb2N1cyBvdXRcclxuICAgICAgICAgICAgICBfdGhpcy5jbG9zZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICB0YWJfYmFja3dhcmQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgaWYgKF90aGlzLiRlbGVtZW50LmZpbmQoJzpmb2N1cycpLmlzKHZpc2libGVGb2N1c2FibGVFbGVtZW50cy5lcSgwKSkgfHwgX3RoaXMuJGVsZW1lbnQuaXMoJzpmb2N1cycpKSB7IC8vIGxlZnQgbW9kYWwgdXB3YXJkcywgc2V0dGluZyBmb2N1cyB0byBsYXN0IGVsZW1lbnRcclxuICAgICAgICAgICAgaWYgKF90aGlzLm9wdGlvbnMudHJhcEZvY3VzKSB7IC8vIGlmIGZvY3VzIHNoYWxsIGJlIHRyYXBwZWRcclxuICAgICAgICAgICAgICB2aXNpYmxlRm9jdXNhYmxlRWxlbWVudHMuZXEoLTEpLmZvY3VzKCk7XHJcbiAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICB9IGVsc2UgeyAvLyBpZiBmb2N1cyBpcyBub3QgdHJhcHBlZCwgY2xvc2UgZHJvcGRvd24gb24gZm9jdXMgb3V0XHJcbiAgICAgICAgICAgICAgX3RoaXMuY2xvc2UoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgb3BlbjogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICBpZiAoJHRhcmdldC5pcyhfdGhpcy4kYW5jaG9yKSkge1xyXG4gICAgICAgICAgICBfdGhpcy5vcGVuKCk7XHJcbiAgICAgICAgICAgIF90aGlzLiRlbGVtZW50LmF0dHIoJ3RhYmluZGV4JywgLTEpLmZvY3VzKCk7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIGNsb3NlOiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgIF90aGlzLmNsb3NlKCk7XHJcbiAgICAgICAgICBfdGhpcy4kYW5jaG9yLmZvY3VzKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQWRkcyBhbiBldmVudCBoYW5kbGVyIHRvIHRoZSBib2R5IHRvIGNsb3NlIGFueSBkcm9wZG93bnMgb24gYSBjbGljay5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9hZGRCb2R5SGFuZGxlcigpIHtcclxuICAgICB2YXIgJGJvZHkgPSAkKGRvY3VtZW50LmJvZHkpLm5vdCh0aGlzLiRlbGVtZW50KSxcclxuICAgICAgICAgX3RoaXMgPSB0aGlzO1xyXG4gICAgICRib2R5Lm9mZignY2xpY2suemYuZHJvcGRvd24nKVxyXG4gICAgICAgICAgLm9uKCdjbGljay56Zi5kcm9wZG93bicsIGZ1bmN0aW9uKGUpe1xyXG4gICAgICAgICAgICBpZihfdGhpcy4kYW5jaG9yLmlzKGUudGFyZ2V0KSB8fCBfdGhpcy4kYW5jaG9yLmZpbmQoZS50YXJnZXQpLmxlbmd0aCkge1xyXG4gICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZihfdGhpcy4kZWxlbWVudC5maW5kKGUudGFyZ2V0KS5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgX3RoaXMuY2xvc2UoKTtcclxuICAgICAgICAgICAgJGJvZHkub2ZmKCdjbGljay56Zi5kcm9wZG93bicpO1xyXG4gICAgICAgICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBPcGVucyB0aGUgZHJvcGRvd24gcGFuZSwgYW5kIGZpcmVzIGEgYnViYmxpbmcgZXZlbnQgdG8gY2xvc2Ugb3RoZXIgZHJvcGRvd25zLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIEBmaXJlcyBEcm9wZG93biNjbG9zZW1lXHJcbiAgICogQGZpcmVzIERyb3Bkb3duI3Nob3dcclxuICAgKi9cclxuICBvcGVuKCkge1xyXG4gICAgLy8gdmFyIF90aGlzID0gdGhpcztcclxuICAgIC8qKlxyXG4gICAgICogRmlyZXMgdG8gY2xvc2Ugb3RoZXIgb3BlbiBkcm9wZG93bnNcclxuICAgICAqIEBldmVudCBEcm9wZG93biNjbG9zZW1lXHJcbiAgICAgKi9cclxuICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcignY2xvc2VtZS56Zi5kcm9wZG93bicsIHRoaXMuJGVsZW1lbnQuYXR0cignaWQnKSk7XHJcbiAgICB0aGlzLiRhbmNob3IuYWRkQ2xhc3MoJ2hvdmVyJylcclxuICAgICAgICAuYXR0cih7J2FyaWEtZXhwYW5kZWQnOiB0cnVlfSk7XHJcbiAgICAvLyB0aGlzLiRlbGVtZW50Lyouc2hvdygpKi87XHJcbiAgICB0aGlzLl9zZXRQb3NpdGlvbigpO1xyXG4gICAgdGhpcy4kZWxlbWVudC5hZGRDbGFzcygnaXMtb3BlbicpXHJcbiAgICAgICAgLmF0dHIoeydhcmlhLWhpZGRlbic6IGZhbHNlfSk7XHJcblxyXG4gICAgaWYodGhpcy5vcHRpb25zLmF1dG9Gb2N1cyl7XHJcbiAgICAgIHZhciAkZm9jdXNhYmxlID0gRm91bmRhdGlvbi5LZXlib2FyZC5maW5kRm9jdXNhYmxlKHRoaXMuJGVsZW1lbnQpO1xyXG4gICAgICBpZigkZm9jdXNhYmxlLmxlbmd0aCl7XHJcbiAgICAgICAgJGZvY3VzYWJsZS5lcSgwKS5mb2N1cygpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYodGhpcy5vcHRpb25zLmNsb3NlT25DbGljayl7IHRoaXMuX2FkZEJvZHlIYW5kbGVyKCk7IH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVzIG9uY2UgdGhlIGRyb3Bkb3duIGlzIHZpc2libGUuXHJcbiAgICAgKiBAZXZlbnQgRHJvcGRvd24jc2hvd1xyXG4gICAgICovXHJcbiAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ3Nob3cuemYuZHJvcGRvd24nLCBbdGhpcy4kZWxlbWVudF0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2xvc2VzIHRoZSBvcGVuIGRyb3Bkb3duIHBhbmUuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQGZpcmVzIERyb3Bkb3duI2hpZGVcclxuICAgKi9cclxuICBjbG9zZSgpIHtcclxuICAgIGlmKCF0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCdpcy1vcGVuJykpe1xyXG4gICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcbiAgICB0aGlzLiRlbGVtZW50LnJlbW92ZUNsYXNzKCdpcy1vcGVuJylcclxuICAgICAgICAuYXR0cih7J2FyaWEtaGlkZGVuJzogdHJ1ZX0pO1xyXG5cclxuICAgIHRoaXMuJGFuY2hvci5yZW1vdmVDbGFzcygnaG92ZXInKVxyXG4gICAgICAgIC5hdHRyKCdhcmlhLWV4cGFuZGVkJywgZmFsc2UpO1xyXG5cclxuICAgIGlmKHRoaXMuY2xhc3NDaGFuZ2VkKXtcclxuICAgICAgdmFyIGN1clBvc2l0aW9uQ2xhc3MgPSB0aGlzLmdldFBvc2l0aW9uQ2xhc3MoKTtcclxuICAgICAgaWYoY3VyUG9zaXRpb25DbGFzcyl7XHJcbiAgICAgICAgdGhpcy4kZWxlbWVudC5yZW1vdmVDbGFzcyhjdXJQb3NpdGlvbkNsYXNzKTtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLiRlbGVtZW50LmFkZENsYXNzKHRoaXMub3B0aW9ucy5wb3NpdGlvbkNsYXNzKVxyXG4gICAgICAgICAgLyouaGlkZSgpKi8uY3NzKHtoZWlnaHQ6ICcnLCB3aWR0aDogJyd9KTtcclxuICAgICAgdGhpcy5jbGFzc0NoYW5nZWQgPSBmYWxzZTtcclxuICAgICAgdGhpcy5jb3VudGVyID0gNDtcclxuICAgICAgdGhpcy51c2VkUG9zaXRpb25zLmxlbmd0aCA9IDA7XHJcbiAgICB9XHJcbiAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ2hpZGUuemYuZHJvcGRvd24nLCBbdGhpcy4kZWxlbWVudF0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVG9nZ2xlcyB0aGUgZHJvcGRvd24gcGFuZSdzIHZpc2liaWxpdHkuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICovXHJcbiAgdG9nZ2xlKCkge1xyXG4gICAgaWYodGhpcy4kZWxlbWVudC5oYXNDbGFzcygnaXMtb3BlbicpKXtcclxuICAgICAgaWYodGhpcy4kYW5jaG9yLmRhdGEoJ2hvdmVyJykpIHJldHVybjtcclxuICAgICAgdGhpcy5jbG9zZSgpO1xyXG4gICAgfWVsc2V7XHJcbiAgICAgIHRoaXMub3BlbigpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGVzdHJveXMgdGhlIGRyb3Bkb3duLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqL1xyXG4gIGRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50Lm9mZignLnpmLnRyaWdnZXInKS5oaWRlKCk7XHJcbiAgICB0aGlzLiRhbmNob3Iub2ZmKCcuemYuZHJvcGRvd24nKTtcclxuXHJcbiAgICBGb3VuZGF0aW9uLnVucmVnaXN0ZXJQbHVnaW4odGhpcyk7XHJcbiAgfVxyXG59XHJcblxyXG5Ecm9wZG93bi5kZWZhdWx0cyA9IHtcclxuICAvKipcclxuICAgKiBBbW91bnQgb2YgdGltZSB0byBkZWxheSBvcGVuaW5nIGEgc3VibWVudSBvbiBob3ZlciBldmVudC5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgMjUwXHJcbiAgICovXHJcbiAgaG92ZXJEZWxheTogMjUwLFxyXG4gIC8qKlxyXG4gICAqIEFsbG93IHN1Ym1lbnVzIHRvIG9wZW4gb24gaG92ZXIgZXZlbnRzXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIGZhbHNlXHJcbiAgICovXHJcbiAgaG92ZXI6IGZhbHNlLFxyXG4gIC8qKlxyXG4gICAqIERvbid0IGNsb3NlIGRyb3Bkb3duIHdoZW4gaG92ZXJpbmcgb3ZlciBkcm9wZG93biBwYW5lXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIHRydWVcclxuICAgKi9cclxuICBob3ZlclBhbmU6IGZhbHNlLFxyXG4gIC8qKlxyXG4gICAqIE51bWJlciBvZiBwaXhlbHMgYmV0d2VlbiB0aGUgZHJvcGRvd24gcGFuZSBhbmQgdGhlIHRyaWdnZXJpbmcgZWxlbWVudCBvbiBvcGVuLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAxXHJcbiAgICovXHJcbiAgdk9mZnNldDogMSxcclxuICAvKipcclxuICAgKiBOdW1iZXIgb2YgcGl4ZWxzIGJldHdlZW4gdGhlIGRyb3Bkb3duIHBhbmUgYW5kIHRoZSB0cmlnZ2VyaW5nIGVsZW1lbnQgb24gb3Blbi5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgMVxyXG4gICAqL1xyXG4gIGhPZmZzZXQ6IDEsXHJcbiAgLyoqXHJcbiAgICogQ2xhc3MgYXBwbGllZCB0byBhZGp1c3Qgb3BlbiBwb3NpdGlvbi4gSlMgd2lsbCB0ZXN0IGFuZCBmaWxsIHRoaXMgaW4uXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlICd0b3AnXHJcbiAgICovXHJcbiAgcG9zaXRpb25DbGFzczogJycsXHJcbiAgLyoqXHJcbiAgICogQWxsb3cgdGhlIHBsdWdpbiB0byB0cmFwIGZvY3VzIHRvIHRoZSBkcm9wZG93biBwYW5lIGlmIG9wZW5lZCB3aXRoIGtleWJvYXJkIGNvbW1hbmRzLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSBmYWxzZVxyXG4gICAqL1xyXG4gIHRyYXBGb2N1czogZmFsc2UsXHJcbiAgLyoqXHJcbiAgICogQWxsb3cgdGhlIHBsdWdpbiB0byBzZXQgZm9jdXMgdG8gdGhlIGZpcnN0IGZvY3VzYWJsZSBlbGVtZW50IHdpdGhpbiB0aGUgcGFuZSwgcmVnYXJkbGVzcyBvZiBtZXRob2Qgb2Ygb3BlbmluZy5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgdHJ1ZVxyXG4gICAqL1xyXG4gIGF1dG9Gb2N1czogZmFsc2UsXHJcbiAgLyoqXHJcbiAgICogQWxsb3dzIGEgY2xpY2sgb24gdGhlIGJvZHkgdG8gY2xvc2UgdGhlIGRyb3Bkb3duLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSBmYWxzZVxyXG4gICAqL1xyXG4gIGNsb3NlT25DbGljazogZmFsc2VcclxufVxyXG5cclxuLy8gV2luZG93IGV4cG9ydHNcclxuRm91bmRhdGlvbi5wbHVnaW4oRHJvcGRvd24sICdEcm9wZG93bicpO1xyXG5cclxufShqUXVlcnkpO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG4hZnVuY3Rpb24oJCkge1xyXG5cclxuLyoqXHJcbiAqIERyb3Bkb3duTWVudSBtb2R1bGUuXHJcbiAqIEBtb2R1bGUgZm91bmRhdGlvbi5kcm9wZG93bi1tZW51XHJcbiAqIEByZXF1aXJlcyBmb3VuZGF0aW9uLnV0aWwua2V5Ym9hcmRcclxuICogQHJlcXVpcmVzIGZvdW5kYXRpb24udXRpbC5ib3hcclxuICogQHJlcXVpcmVzIGZvdW5kYXRpb24udXRpbC5uZXN0XHJcbiAqL1xyXG5cclxuY2xhc3MgRHJvcGRvd25NZW51IHtcclxuICAvKipcclxuICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIERyb3Bkb3duTWVudS5cclxuICAgKiBAY2xhc3NcclxuICAgKiBAZmlyZXMgRHJvcGRvd25NZW51I2luaXRcclxuICAgKiBAcGFyYW0ge2pRdWVyeX0gZWxlbWVudCAtIGpRdWVyeSBvYmplY3QgdG8gbWFrZSBpbnRvIGEgZHJvcGRvd24gbWVudS5cclxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIE92ZXJyaWRlcyB0byB0aGUgZGVmYXVsdCBwbHVnaW4gc2V0dGluZ3MuXHJcbiAgICovXHJcbiAgY29uc3RydWN0b3IoZWxlbWVudCwgb3B0aW9ucykge1xyXG4gICAgdGhpcy4kZWxlbWVudCA9IGVsZW1lbnQ7XHJcbiAgICB0aGlzLm9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgRHJvcGRvd25NZW51LmRlZmF1bHRzLCB0aGlzLiRlbGVtZW50LmRhdGEoKSwgb3B0aW9ucyk7XHJcblxyXG4gICAgRm91bmRhdGlvbi5OZXN0LkZlYXRoZXIodGhpcy4kZWxlbWVudCwgJ2Ryb3Bkb3duJyk7XHJcbiAgICB0aGlzLl9pbml0KCk7XHJcblxyXG4gICAgRm91bmRhdGlvbi5yZWdpc3RlclBsdWdpbih0aGlzLCAnRHJvcGRvd25NZW51Jyk7XHJcbiAgICBGb3VuZGF0aW9uLktleWJvYXJkLnJlZ2lzdGVyKCdEcm9wZG93bk1lbnUnLCB7XHJcbiAgICAgICdFTlRFUic6ICdvcGVuJyxcclxuICAgICAgJ1NQQUNFJzogJ29wZW4nLFxyXG4gICAgICAnQVJST1dfUklHSFQnOiAnbmV4dCcsXHJcbiAgICAgICdBUlJPV19VUCc6ICd1cCcsXHJcbiAgICAgICdBUlJPV19ET1dOJzogJ2Rvd24nLFxyXG4gICAgICAnQVJST1dfTEVGVCc6ICdwcmV2aW91cycsXHJcbiAgICAgICdFU0NBUEUnOiAnY2xvc2UnXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpYWxpemVzIHRoZSBwbHVnaW4sIGFuZCBjYWxscyBfcHJlcGFyZU1lbnVcclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqL1xyXG4gIF9pbml0KCkge1xyXG4gICAgdmFyIHN1YnMgPSB0aGlzLiRlbGVtZW50LmZpbmQoJ2xpLmlzLWRyb3Bkb3duLXN1Ym1lbnUtcGFyZW50Jyk7XHJcbiAgICB0aGlzLiRlbGVtZW50LmNoaWxkcmVuKCcuaXMtZHJvcGRvd24tc3VibWVudS1wYXJlbnQnKS5jaGlsZHJlbignLmlzLWRyb3Bkb3duLXN1Ym1lbnUnKS5hZGRDbGFzcygnZmlyc3Qtc3ViJyk7XHJcblxyXG4gICAgdGhpcy4kbWVudUl0ZW1zID0gdGhpcy4kZWxlbWVudC5maW5kKCdbcm9sZT1cIm1lbnVpdGVtXCJdJyk7XHJcbiAgICB0aGlzLiR0YWJzID0gdGhpcy4kZWxlbWVudC5jaGlsZHJlbignW3JvbGU9XCJtZW51aXRlbVwiXScpO1xyXG4gICAgdGhpcy4kdGFicy5maW5kKCd1bC5pcy1kcm9wZG93bi1zdWJtZW51JykuYWRkQ2xhc3ModGhpcy5vcHRpb25zLnZlcnRpY2FsQ2xhc3MpO1xyXG5cclxuICAgIGlmICh0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKHRoaXMub3B0aW9ucy5yaWdodENsYXNzKSB8fCB0aGlzLm9wdGlvbnMuYWxpZ25tZW50ID09PSAncmlnaHQnIHx8IEZvdW5kYXRpb24ucnRsKCkgfHwgdGhpcy4kZWxlbWVudC5wYXJlbnRzKCcudG9wLWJhci1yaWdodCcpLmlzKCcqJykpIHtcclxuICAgICAgdGhpcy5vcHRpb25zLmFsaWdubWVudCA9ICdyaWdodCc7XHJcbiAgICAgIHN1YnMuYWRkQ2xhc3MoJ29wZW5zLWxlZnQnKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHN1YnMuYWRkQ2xhc3MoJ29wZW5zLXJpZ2h0Jyk7XHJcbiAgICB9XHJcbiAgICB0aGlzLmNoYW5nZWQgPSBmYWxzZTtcclxuICAgIHRoaXMuX2V2ZW50cygpO1xyXG4gIH07XHJcbiAgLyoqXHJcbiAgICogQWRkcyBldmVudCBsaXN0ZW5lcnMgdG8gZWxlbWVudHMgd2l0aGluIHRoZSBtZW51XHJcbiAgICogQHByaXZhdGVcclxuICAgKiBAZnVuY3Rpb25cclxuICAgKi9cclxuICBfZXZlbnRzKCkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcyxcclxuICAgICAgICBoYXNUb3VjaCA9ICdvbnRvdWNoc3RhcnQnIGluIHdpbmRvdyB8fCAodHlwZW9mIHdpbmRvdy5vbnRvdWNoc3RhcnQgIT09ICd1bmRlZmluZWQnKSxcclxuICAgICAgICBwYXJDbGFzcyA9ICdpcy1kcm9wZG93bi1zdWJtZW51LXBhcmVudCc7XHJcblxyXG4gICAgLy8gdXNlZCBmb3Igb25DbGljayBhbmQgaW4gdGhlIGtleWJvYXJkIGhhbmRsZXJzXHJcbiAgICB2YXIgaGFuZGxlQ2xpY2tGbiA9IGZ1bmN0aW9uKGUpIHtcclxuICAgICAgdmFyICRlbGVtID0gJChlLnRhcmdldCkucGFyZW50c1VudGlsKCd1bCcsIGAuJHtwYXJDbGFzc31gKSxcclxuICAgICAgICAgIGhhc1N1YiA9ICRlbGVtLmhhc0NsYXNzKHBhckNsYXNzKSxcclxuICAgICAgICAgIGhhc0NsaWNrZWQgPSAkZWxlbS5hdHRyKCdkYXRhLWlzLWNsaWNrJykgPT09ICd0cnVlJyxcclxuICAgICAgICAgICRzdWIgPSAkZWxlbS5jaGlsZHJlbignLmlzLWRyb3Bkb3duLXN1Ym1lbnUnKTtcclxuXHJcbiAgICAgIGlmIChoYXNTdWIpIHtcclxuICAgICAgICBpZiAoaGFzQ2xpY2tlZCkge1xyXG4gICAgICAgICAgaWYgKCFfdGhpcy5vcHRpb25zLmNsb3NlT25DbGljayB8fCAoIV90aGlzLm9wdGlvbnMuY2xpY2tPcGVuICYmICFoYXNUb3VjaCkgfHwgKF90aGlzLm9wdGlvbnMuZm9yY2VGb2xsb3cgJiYgaGFzVG91Y2gpKSB7IHJldHVybjsgfVxyXG4gICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgX3RoaXMuX2hpZGUoJGVsZW0pO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgX3RoaXMuX3Nob3coJGVsZW0uY2hpbGRyZW4oJy5pcy1kcm9wZG93bi1zdWJtZW51JykpO1xyXG4gICAgICAgICAgJGVsZW0uYWRkKCRlbGVtLnBhcmVudHNVbnRpbChfdGhpcy4kZWxlbWVudCwgYC4ke3BhckNsYXNzfWApKS5hdHRyKCdkYXRhLWlzLWNsaWNrJywgdHJ1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2UgeyByZXR1cm47IH1cclxuICAgIH07XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5jbGlja09wZW4gfHwgaGFzVG91Y2gpIHtcclxuICAgICAgdGhpcy4kbWVudUl0ZW1zLm9uKCdjbGljay56Zi5kcm9wZG93bm1lbnUgdG91Y2hzdGFydC56Zi5kcm9wZG93bm1lbnUnLCBoYW5kbGVDbGlja0ZuKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5kaXNhYmxlSG92ZXIpIHtcclxuICAgICAgdGhpcy4kbWVudUl0ZW1zLm9uKCdtb3VzZWVudGVyLnpmLmRyb3Bkb3dubWVudScsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICB2YXIgJGVsZW0gPSAkKHRoaXMpLFxyXG4gICAgICAgICAgICBoYXNTdWIgPSAkZWxlbS5oYXNDbGFzcyhwYXJDbGFzcyk7XHJcblxyXG4gICAgICAgIGlmIChoYXNTdWIpIHtcclxuICAgICAgICAgIGNsZWFyVGltZW91dChfdGhpcy5kZWxheSk7XHJcbiAgICAgICAgICBfdGhpcy5kZWxheSA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIF90aGlzLl9zaG93KCRlbGVtLmNoaWxkcmVuKCcuaXMtZHJvcGRvd24tc3VibWVudScpKTtcclxuICAgICAgICAgIH0sIF90aGlzLm9wdGlvbnMuaG92ZXJEZWxheSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KS5vbignbW91c2VsZWF2ZS56Zi5kcm9wZG93bm1lbnUnLCBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgdmFyICRlbGVtID0gJCh0aGlzKSxcclxuICAgICAgICAgICAgaGFzU3ViID0gJGVsZW0uaGFzQ2xhc3MocGFyQ2xhc3MpO1xyXG4gICAgICAgIGlmIChoYXNTdWIgJiYgX3RoaXMub3B0aW9ucy5hdXRvY2xvc2UpIHtcclxuICAgICAgICAgIGlmICgkZWxlbS5hdHRyKCdkYXRhLWlzLWNsaWNrJykgPT09ICd0cnVlJyAmJiBfdGhpcy5vcHRpb25zLmNsaWNrT3BlbikgeyByZXR1cm4gZmFsc2U7IH1cclxuXHJcbiAgICAgICAgICBjbGVhclRpbWVvdXQoX3RoaXMuZGVsYXkpO1xyXG4gICAgICAgICAgX3RoaXMuZGVsYXkgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5faGlkZSgkZWxlbSk7XHJcbiAgICAgICAgICB9LCBfdGhpcy5vcHRpb25zLmNsb3NpbmdUaW1lKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgdGhpcy4kbWVudUl0ZW1zLm9uKCdrZXlkb3duLnpmLmRyb3Bkb3dubWVudScsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgdmFyICRlbGVtZW50ID0gJChlLnRhcmdldCkucGFyZW50c1VudGlsKCd1bCcsICdbcm9sZT1cIm1lbnVpdGVtXCJdJyksXHJcbiAgICAgICAgICBpc1RhYiA9IF90aGlzLiR0YWJzLmluZGV4KCRlbGVtZW50KSA+IC0xLFxyXG4gICAgICAgICAgJGVsZW1lbnRzID0gaXNUYWIgPyBfdGhpcy4kdGFicyA6ICRlbGVtZW50LnNpYmxpbmdzKCdsaScpLmFkZCgkZWxlbWVudCksXHJcbiAgICAgICAgICAkcHJldkVsZW1lbnQsXHJcbiAgICAgICAgICAkbmV4dEVsZW1lbnQ7XHJcblxyXG4gICAgICAkZWxlbWVudHMuZWFjaChmdW5jdGlvbihpKSB7XHJcbiAgICAgICAgaWYgKCQodGhpcykuaXMoJGVsZW1lbnQpKSB7XHJcbiAgICAgICAgICAkcHJldkVsZW1lbnQgPSAkZWxlbWVudHMuZXEoaS0xKTtcclxuICAgICAgICAgICRuZXh0RWxlbWVudCA9ICRlbGVtZW50cy5lcShpKzEpO1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcblxyXG4gICAgICB2YXIgbmV4dFNpYmxpbmcgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICBpZiAoISRlbGVtZW50LmlzKCc6bGFzdC1jaGlsZCcpKSB7XHJcbiAgICAgICAgICAkbmV4dEVsZW1lbnQuY2hpbGRyZW4oJ2E6Zmlyc3QnKS5mb2N1cygpO1xyXG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSwgcHJldlNpYmxpbmcgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICAkcHJldkVsZW1lbnQuY2hpbGRyZW4oJ2E6Zmlyc3QnKS5mb2N1cygpO1xyXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgfSwgb3BlblN1YiA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHZhciAkc3ViID0gJGVsZW1lbnQuY2hpbGRyZW4oJ3VsLmlzLWRyb3Bkb3duLXN1Ym1lbnUnKTtcclxuICAgICAgICBpZiAoJHN1Yi5sZW5ndGgpIHtcclxuICAgICAgICAgIF90aGlzLl9zaG93KCRzdWIpO1xyXG4gICAgICAgICAgJGVsZW1lbnQuZmluZCgnbGkgPiBhOmZpcnN0JykuZm9jdXMoKTtcclxuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICB9IGVsc2UgeyByZXR1cm47IH1cclxuICAgICAgfSwgY2xvc2VTdWIgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICAvL2lmICgkZWxlbWVudC5pcygnOmZpcnN0LWNoaWxkJykpIHtcclxuICAgICAgICB2YXIgY2xvc2UgPSAkZWxlbWVudC5wYXJlbnQoJ3VsJykucGFyZW50KCdsaScpO1xyXG4gICAgICAgIGNsb3NlLmNoaWxkcmVuKCdhOmZpcnN0JykuZm9jdXMoKTtcclxuICAgICAgICBfdGhpcy5faGlkZShjbG9zZSk7XHJcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIC8vfVxyXG4gICAgICB9O1xyXG4gICAgICB2YXIgZnVuY3Rpb25zID0ge1xyXG4gICAgICAgIG9wZW46IG9wZW5TdWIsXHJcbiAgICAgICAgY2xvc2U6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgX3RoaXMuX2hpZGUoX3RoaXMuJGVsZW1lbnQpO1xyXG4gICAgICAgICAgX3RoaXMuJG1lbnVJdGVtcy5maW5kKCdhOmZpcnN0JykuZm9jdXMoKTsgLy8gZm9jdXMgdG8gZmlyc3QgZWxlbWVudFxyXG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgaGFuZGxlZDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgIH1cclxuICAgICAgfTtcclxuXHJcbiAgICAgIGlmIChpc1RhYikge1xyXG4gICAgICAgIGlmIChfdGhpcy4kZWxlbWVudC5oYXNDbGFzcyhfdGhpcy5vcHRpb25zLnZlcnRpY2FsQ2xhc3MpKSB7IC8vIHZlcnRpY2FsIG1lbnVcclxuICAgICAgICAgIGlmIChfdGhpcy5vcHRpb25zLmFsaWdubWVudCA9PT0gJ2xlZnQnKSB7IC8vIGxlZnQgYWxpZ25lZFxyXG4gICAgICAgICAgICAkLmV4dGVuZChmdW5jdGlvbnMsIHtcclxuICAgICAgICAgICAgICBkb3duOiBuZXh0U2libGluZyxcclxuICAgICAgICAgICAgICB1cDogcHJldlNpYmxpbmcsXHJcbiAgICAgICAgICAgICAgbmV4dDogb3BlblN1YixcclxuICAgICAgICAgICAgICBwcmV2aW91czogY2xvc2VTdWJcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICB9IGVsc2UgeyAvLyByaWdodCBhbGlnbmVkXHJcbiAgICAgICAgICAgICQuZXh0ZW5kKGZ1bmN0aW9ucywge1xyXG4gICAgICAgICAgICAgIGRvd246IG5leHRTaWJsaW5nLFxyXG4gICAgICAgICAgICAgIHVwOiBwcmV2U2libGluZyxcclxuICAgICAgICAgICAgICBuZXh0OiBjbG9zZVN1YixcclxuICAgICAgICAgICAgICBwcmV2aW91czogb3BlblN1YlxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgeyAvLyBob3Jpem9udGFsIG1lbnVcclxuICAgICAgICAgICQuZXh0ZW5kKGZ1bmN0aW9ucywge1xyXG4gICAgICAgICAgICBuZXh0OiBuZXh0U2libGluZyxcclxuICAgICAgICAgICAgcHJldmlvdXM6IHByZXZTaWJsaW5nLFxyXG4gICAgICAgICAgICBkb3duOiBvcGVuU3ViLFxyXG4gICAgICAgICAgICB1cDogY2xvc2VTdWJcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHsgLy8gbm90IHRhYnMgLT4gb25lIHN1YlxyXG4gICAgICAgIGlmIChfdGhpcy5vcHRpb25zLmFsaWdubWVudCA9PT0gJ2xlZnQnKSB7IC8vIGxlZnQgYWxpZ25lZFxyXG4gICAgICAgICAgJC5leHRlbmQoZnVuY3Rpb25zLCB7XHJcbiAgICAgICAgICAgIG5leHQ6IG9wZW5TdWIsXHJcbiAgICAgICAgICAgIHByZXZpb3VzOiBjbG9zZVN1YixcclxuICAgICAgICAgICAgZG93bjogbmV4dFNpYmxpbmcsXHJcbiAgICAgICAgICAgIHVwOiBwcmV2U2libGluZ1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfSBlbHNlIHsgLy8gcmlnaHQgYWxpZ25lZFxyXG4gICAgICAgICAgJC5leHRlbmQoZnVuY3Rpb25zLCB7XHJcbiAgICAgICAgICAgIG5leHQ6IGNsb3NlU3ViLFxyXG4gICAgICAgICAgICBwcmV2aW91czogb3BlblN1YixcclxuICAgICAgICAgICAgZG93bjogbmV4dFNpYmxpbmcsXHJcbiAgICAgICAgICAgIHVwOiBwcmV2U2libGluZ1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIEZvdW5kYXRpb24uS2V5Ym9hcmQuaGFuZGxlS2V5KGUsICdEcm9wZG93bk1lbnUnLCBmdW5jdGlvbnMpO1xyXG5cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQWRkcyBhbiBldmVudCBoYW5kbGVyIHRvIHRoZSBib2R5IHRvIGNsb3NlIGFueSBkcm9wZG93bnMgb24gYSBjbGljay5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9hZGRCb2R5SGFuZGxlcigpIHtcclxuICAgIHZhciAkYm9keSA9ICQoZG9jdW1lbnQuYm9keSksXHJcbiAgICAgICAgX3RoaXMgPSB0aGlzO1xyXG4gICAgJGJvZHkub2ZmKCdtb3VzZXVwLnpmLmRyb3Bkb3dubWVudSB0b3VjaGVuZC56Zi5kcm9wZG93bm1lbnUnKVxyXG4gICAgICAgICAub24oJ21vdXNldXAuemYuZHJvcGRvd25tZW51IHRvdWNoZW5kLnpmLmRyb3Bkb3dubWVudScsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICAgICB2YXIgJGxpbmsgPSBfdGhpcy4kZWxlbWVudC5maW5kKGUudGFyZ2V0KTtcclxuICAgICAgICAgICBpZiAoJGxpbmsubGVuZ3RoKSB7IHJldHVybjsgfVxyXG5cclxuICAgICAgICAgICBfdGhpcy5faGlkZSgpO1xyXG4gICAgICAgICAgICRib2R5Lm9mZignbW91c2V1cC56Zi5kcm9wZG93bm1lbnUgdG91Y2hlbmQuemYuZHJvcGRvd25tZW51Jyk7XHJcbiAgICAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogT3BlbnMgYSBkcm9wZG93biBwYW5lLCBhbmQgY2hlY2tzIGZvciBjb2xsaXNpb25zIGZpcnN0LlxyXG4gICAqIEBwYXJhbSB7alF1ZXJ5fSAkc3ViIC0gdWwgZWxlbWVudCB0aGF0IGlzIGEgc3VibWVudSB0byBzaG93XHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHByaXZhdGVcclxuICAgKiBAZmlyZXMgRHJvcGRvd25NZW51I3Nob3dcclxuICAgKi9cclxuICBfc2hvdygkc3ViKSB7XHJcbiAgICB2YXIgaWR4ID0gdGhpcy4kdGFicy5pbmRleCh0aGlzLiR0YWJzLmZpbHRlcihmdW5jdGlvbihpLCBlbCkge1xyXG4gICAgICByZXR1cm4gJChlbCkuZmluZCgkc3ViKS5sZW5ndGggPiAwO1xyXG4gICAgfSkpO1xyXG4gICAgdmFyICRzaWJzID0gJHN1Yi5wYXJlbnQoJ2xpLmlzLWRyb3Bkb3duLXN1Ym1lbnUtcGFyZW50Jykuc2libGluZ3MoJ2xpLmlzLWRyb3Bkb3duLXN1Ym1lbnUtcGFyZW50Jyk7XHJcbiAgICB0aGlzLl9oaWRlKCRzaWJzLCBpZHgpO1xyXG4gICAgJHN1Yi5jc3MoJ3Zpc2liaWxpdHknLCAnaGlkZGVuJykuYWRkQ2xhc3MoJ2pzLWRyb3Bkb3duLWFjdGl2ZScpLmF0dHIoeydhcmlhLWhpZGRlbic6IGZhbHNlfSlcclxuICAgICAgICAucGFyZW50KCdsaS5pcy1kcm9wZG93bi1zdWJtZW51LXBhcmVudCcpLmFkZENsYXNzKCdpcy1hY3RpdmUnKVxyXG4gICAgICAgIC5hdHRyKHsnYXJpYS1leHBhbmRlZCc6IHRydWV9KTtcclxuICAgIHZhciBjbGVhciA9IEZvdW5kYXRpb24uQm94LkltTm90VG91Y2hpbmdZb3UoJHN1YiwgbnVsbCwgdHJ1ZSk7XHJcbiAgICBpZiAoIWNsZWFyKSB7XHJcbiAgICAgIHZhciBvbGRDbGFzcyA9IHRoaXMub3B0aW9ucy5hbGlnbm1lbnQgPT09ICdsZWZ0JyA/ICctcmlnaHQnIDogJy1sZWZ0JyxcclxuICAgICAgICAgICRwYXJlbnRMaSA9ICRzdWIucGFyZW50KCcuaXMtZHJvcGRvd24tc3VibWVudS1wYXJlbnQnKTtcclxuICAgICAgJHBhcmVudExpLnJlbW92ZUNsYXNzKGBvcGVucyR7b2xkQ2xhc3N9YCkuYWRkQ2xhc3MoYG9wZW5zLSR7dGhpcy5vcHRpb25zLmFsaWdubWVudH1gKTtcclxuICAgICAgY2xlYXIgPSBGb3VuZGF0aW9uLkJveC5JbU5vdFRvdWNoaW5nWW91KCRzdWIsIG51bGwsIHRydWUpO1xyXG4gICAgICBpZiAoIWNsZWFyKSB7XHJcbiAgICAgICAgJHBhcmVudExpLnJlbW92ZUNsYXNzKGBvcGVucy0ke3RoaXMub3B0aW9ucy5hbGlnbm1lbnR9YCkuYWRkQ2xhc3MoJ29wZW5zLWlubmVyJyk7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5jaGFuZ2VkID0gdHJ1ZTtcclxuICAgIH1cclxuICAgICRzdWIuY3NzKCd2aXNpYmlsaXR5JywgJycpO1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5jbG9zZU9uQ2xpY2spIHsgdGhpcy5fYWRkQm9keUhhbmRsZXIoKTsgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlcyB3aGVuIHRoZSBuZXcgZHJvcGRvd24gcGFuZSBpcyB2aXNpYmxlLlxyXG4gICAgICogQGV2ZW50IERyb3Bkb3duTWVudSNzaG93XHJcbiAgICAgKi9cclxuICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcignc2hvdy56Zi5kcm9wZG93bm1lbnUnLCBbJHN1Yl0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGlkZXMgYSBzaW5nbGUsIGN1cnJlbnRseSBvcGVuIGRyb3Bkb3duIHBhbmUsIGlmIHBhc3NlZCBhIHBhcmFtZXRlciwgb3RoZXJ3aXNlLCBoaWRlcyBldmVyeXRoaW5nLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIEBwYXJhbSB7alF1ZXJ5fSAkZWxlbSAtIGVsZW1lbnQgd2l0aCBhIHN1Ym1lbnUgdG8gaGlkZVxyXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBpZHggLSBpbmRleCBvZiB0aGUgJHRhYnMgY29sbGVjdGlvbiB0byBoaWRlXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfaGlkZSgkZWxlbSwgaWR4KSB7XHJcbiAgICB2YXIgJHRvQ2xvc2U7XHJcbiAgICBpZiAoJGVsZW0gJiYgJGVsZW0ubGVuZ3RoKSB7XHJcbiAgICAgICR0b0Nsb3NlID0gJGVsZW07XHJcbiAgICB9IGVsc2UgaWYgKGlkeCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICR0b0Nsb3NlID0gdGhpcy4kdGFicy5ub3QoZnVuY3Rpb24oaSwgZWwpIHtcclxuICAgICAgICByZXR1cm4gaSA9PT0gaWR4O1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAkdG9DbG9zZSA9IHRoaXMuJGVsZW1lbnQ7XHJcbiAgICB9XHJcbiAgICB2YXIgc29tZXRoaW5nVG9DbG9zZSA9ICR0b0Nsb3NlLmhhc0NsYXNzKCdpcy1hY3RpdmUnKSB8fCAkdG9DbG9zZS5maW5kKCcuaXMtYWN0aXZlJykubGVuZ3RoID4gMDtcclxuXHJcbiAgICBpZiAoc29tZXRoaW5nVG9DbG9zZSkge1xyXG4gICAgICAkdG9DbG9zZS5maW5kKCdsaS5pcy1hY3RpdmUnKS5hZGQoJHRvQ2xvc2UpLmF0dHIoe1xyXG4gICAgICAgICdhcmlhLWV4cGFuZGVkJzogZmFsc2UsXHJcbiAgICAgICAgJ2RhdGEtaXMtY2xpY2snOiBmYWxzZVxyXG4gICAgICB9KS5yZW1vdmVDbGFzcygnaXMtYWN0aXZlJyk7XHJcblxyXG4gICAgICAkdG9DbG9zZS5maW5kKCd1bC5qcy1kcm9wZG93bi1hY3RpdmUnKS5hdHRyKHtcclxuICAgICAgICAnYXJpYS1oaWRkZW4nOiB0cnVlXHJcbiAgICAgIH0pLnJlbW92ZUNsYXNzKCdqcy1kcm9wZG93bi1hY3RpdmUnKTtcclxuXHJcbiAgICAgIGlmICh0aGlzLmNoYW5nZWQgfHwgJHRvQ2xvc2UuZmluZCgnb3BlbnMtaW5uZXInKS5sZW5ndGgpIHtcclxuICAgICAgICB2YXIgb2xkQ2xhc3MgPSB0aGlzLm9wdGlvbnMuYWxpZ25tZW50ID09PSAnbGVmdCcgPyAncmlnaHQnIDogJ2xlZnQnO1xyXG4gICAgICAgICR0b0Nsb3NlLmZpbmQoJ2xpLmlzLWRyb3Bkb3duLXN1Ym1lbnUtcGFyZW50JykuYWRkKCR0b0Nsb3NlKVxyXG4gICAgICAgICAgICAgICAgLnJlbW92ZUNsYXNzKGBvcGVucy1pbm5lciBvcGVucy0ke3RoaXMub3B0aW9ucy5hbGlnbm1lbnR9YClcclxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcyhgb3BlbnMtJHtvbGRDbGFzc31gKTtcclxuICAgICAgICB0aGlzLmNoYW5nZWQgPSBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgICAvKipcclxuICAgICAgICogRmlyZXMgd2hlbiB0aGUgb3BlbiBtZW51cyBhcmUgY2xvc2VkLlxyXG4gICAgICAgKiBAZXZlbnQgRHJvcGRvd25NZW51I2hpZGVcclxuICAgICAgICovXHJcbiAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcignaGlkZS56Zi5kcm9wZG93bm1lbnUnLCBbJHRvQ2xvc2VdKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlc3Ryb3lzIHRoZSBwbHVnaW4uXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICovXHJcbiAgZGVzdHJveSgpIHtcclxuICAgIHRoaXMuJG1lbnVJdGVtcy5vZmYoJy56Zi5kcm9wZG93bm1lbnUnKS5yZW1vdmVBdHRyKCdkYXRhLWlzLWNsaWNrJylcclxuICAgICAgICAucmVtb3ZlQ2xhc3MoJ2lzLXJpZ2h0LWFycm93IGlzLWxlZnQtYXJyb3cgaXMtZG93bi1hcnJvdyBvcGVucy1yaWdodCBvcGVucy1sZWZ0IG9wZW5zLWlubmVyJyk7XHJcbiAgICAkKGRvY3VtZW50LmJvZHkpLm9mZignLnpmLmRyb3Bkb3dubWVudScpO1xyXG4gICAgRm91bmRhdGlvbi5OZXN0LkJ1cm4odGhpcy4kZWxlbWVudCwgJ2Ryb3Bkb3duJyk7XHJcbiAgICBGb3VuZGF0aW9uLnVucmVnaXN0ZXJQbHVnaW4odGhpcyk7XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogRGVmYXVsdCBzZXR0aW5ncyBmb3IgcGx1Z2luXHJcbiAqL1xyXG5Ecm9wZG93bk1lbnUuZGVmYXVsdHMgPSB7XHJcbiAgLyoqXHJcbiAgICogRGlzYWxsb3dzIGhvdmVyIGV2ZW50cyBmcm9tIG9wZW5pbmcgc3VibWVudXNcclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgZmFsc2VcclxuICAgKi9cclxuICBkaXNhYmxlSG92ZXI6IGZhbHNlLFxyXG4gIC8qKlxyXG4gICAqIEFsbG93IGEgc3VibWVudSB0byBhdXRvbWF0aWNhbGx5IGNsb3NlIG9uIGEgbW91c2VsZWF2ZSBldmVudCwgaWYgbm90IGNsaWNrZWQgb3Blbi5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgdHJ1ZVxyXG4gICAqL1xyXG4gIGF1dG9jbG9zZTogdHJ1ZSxcclxuICAvKipcclxuICAgKiBBbW91bnQgb2YgdGltZSB0byBkZWxheSBvcGVuaW5nIGEgc3VibWVudSBvbiBob3ZlciBldmVudC5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgNTBcclxuICAgKi9cclxuICBob3ZlckRlbGF5OiA1MCxcclxuICAvKipcclxuICAgKiBBbGxvdyBhIHN1Ym1lbnUgdG8gb3Blbi9yZW1haW4gb3BlbiBvbiBwYXJlbnQgY2xpY2sgZXZlbnQuIEFsbG93cyBjdXJzb3IgdG8gbW92ZSBhd2F5IGZyb20gbWVudS5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgdHJ1ZVxyXG4gICAqL1xyXG4gIGNsaWNrT3BlbjogZmFsc2UsXHJcbiAgLyoqXHJcbiAgICogQW1vdW50IG9mIHRpbWUgdG8gZGVsYXkgY2xvc2luZyBhIHN1Ym1lbnUgb24gYSBtb3VzZWxlYXZlIGV2ZW50LlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSA1MDBcclxuICAgKi9cclxuXHJcbiAgY2xvc2luZ1RpbWU6IDUwMCxcclxuICAvKipcclxuICAgKiBQb3NpdGlvbiBvZiB0aGUgbWVudSByZWxhdGl2ZSB0byB3aGF0IGRpcmVjdGlvbiB0aGUgc3VibWVudXMgc2hvdWxkIG9wZW4uIEhhbmRsZWQgYnkgSlMuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlICdsZWZ0J1xyXG4gICAqL1xyXG4gIGFsaWdubWVudDogJ2xlZnQnLFxyXG4gIC8qKlxyXG4gICAqIEFsbG93IGNsaWNrcyBvbiB0aGUgYm9keSB0byBjbG9zZSBhbnkgb3BlbiBzdWJtZW51cy5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgdHJ1ZVxyXG4gICAqL1xyXG4gIGNsb3NlT25DbGljazogdHJ1ZSxcclxuICAvKipcclxuICAgKiBDbGFzcyBhcHBsaWVkIHRvIHZlcnRpY2FsIG9yaWVudGVkIG1lbnVzLCBGb3VuZGF0aW9uIGRlZmF1bHQgaXMgYHZlcnRpY2FsYC4gVXBkYXRlIHRoaXMgaWYgdXNpbmcgeW91ciBvd24gY2xhc3MuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlICd2ZXJ0aWNhbCdcclxuICAgKi9cclxuICB2ZXJ0aWNhbENsYXNzOiAndmVydGljYWwnLFxyXG4gIC8qKlxyXG4gICAqIENsYXNzIGFwcGxpZWQgdG8gcmlnaHQtc2lkZSBvcmllbnRlZCBtZW51cywgRm91bmRhdGlvbiBkZWZhdWx0IGlzIGBhbGlnbi1yaWdodGAuIFVwZGF0ZSB0aGlzIGlmIHVzaW5nIHlvdXIgb3duIGNsYXNzLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAnYWxpZ24tcmlnaHQnXHJcbiAgICovXHJcbiAgcmlnaHRDbGFzczogJ2FsaWduLXJpZ2h0JyxcclxuICAvKipcclxuICAgKiBCb29sZWFuIHRvIGZvcmNlIG92ZXJpZGUgdGhlIGNsaWNraW5nIG9mIGxpbmtzIHRvIHBlcmZvcm0gZGVmYXVsdCBhY3Rpb24sIG9uIHNlY29uZCB0b3VjaCBldmVudCBmb3IgbW9iaWxlLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSBmYWxzZVxyXG4gICAqL1xyXG4gIGZvcmNlRm9sbG93OiB0cnVlXHJcbn07XHJcblxyXG4vLyBXaW5kb3cgZXhwb3J0c1xyXG5Gb3VuZGF0aW9uLnBsdWdpbihEcm9wZG93bk1lbnUsICdEcm9wZG93bk1lbnUnKTtcclxuXHJcbn0oalF1ZXJ5KTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxuIWZ1bmN0aW9uKCQpIHtcclxuXHJcbi8qKlxyXG4gKiBFcXVhbGl6ZXIgbW9kdWxlLlxyXG4gKiBAbW9kdWxlIGZvdW5kYXRpb24uZXF1YWxpemVyXHJcbiAqL1xyXG5cclxuY2xhc3MgRXF1YWxpemVyIHtcclxuICAvKipcclxuICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIEVxdWFsaXplci5cclxuICAgKiBAY2xhc3NcclxuICAgKiBAZmlyZXMgRXF1YWxpemVyI2luaXRcclxuICAgKiBAcGFyYW0ge09iamVjdH0gZWxlbWVudCAtIGpRdWVyeSBvYmplY3QgdG8gYWRkIHRoZSB0cmlnZ2VyIHRvLlxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gT3ZlcnJpZGVzIHRvIHRoZSBkZWZhdWx0IHBsdWdpbiBzZXR0aW5ncy5cclxuICAgKi9cclxuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBvcHRpb25zKXtcclxuICAgIHRoaXMuJGVsZW1lbnQgPSBlbGVtZW50O1xyXG4gICAgdGhpcy5vcHRpb25zICA9ICQuZXh0ZW5kKHt9LCBFcXVhbGl6ZXIuZGVmYXVsdHMsIHRoaXMuJGVsZW1lbnQuZGF0YSgpLCBvcHRpb25zKTtcclxuXHJcbiAgICB0aGlzLl9pbml0KCk7XHJcblxyXG4gICAgRm91bmRhdGlvbi5yZWdpc3RlclBsdWdpbih0aGlzLCAnRXF1YWxpemVyJyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbml0aWFsaXplcyB0aGUgRXF1YWxpemVyIHBsdWdpbiBhbmQgY2FsbHMgZnVuY3Rpb25zIHRvIGdldCBlcXVhbGl6ZXIgZnVuY3Rpb25pbmcgb24gbG9hZC5cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9pbml0KCkge1xyXG4gICAgdmFyIGVxSWQgPSB0aGlzLiRlbGVtZW50LmF0dHIoJ2RhdGEtZXF1YWxpemVyJykgfHwgJyc7XHJcbiAgICB2YXIgJHdhdGNoZWQgPSB0aGlzLiRlbGVtZW50LmZpbmQoYFtkYXRhLWVxdWFsaXplci13YXRjaD1cIiR7ZXFJZH1cIl1gKTtcclxuXHJcbiAgICB0aGlzLiR3YXRjaGVkID0gJHdhdGNoZWQubGVuZ3RoID8gJHdhdGNoZWQgOiB0aGlzLiRlbGVtZW50LmZpbmQoJ1tkYXRhLWVxdWFsaXplci13YXRjaF0nKTtcclxuICAgIHRoaXMuJGVsZW1lbnQuYXR0cignZGF0YS1yZXNpemUnLCAoZXFJZCB8fCBGb3VuZGF0aW9uLkdldFlvRGlnaXRzKDYsICdlcScpKSk7XHJcblxyXG4gICAgdGhpcy5oYXNOZXN0ZWQgPSB0aGlzLiRlbGVtZW50LmZpbmQoJ1tkYXRhLWVxdWFsaXplcl0nKS5sZW5ndGggPiAwO1xyXG4gICAgdGhpcy5pc05lc3RlZCA9IHRoaXMuJGVsZW1lbnQucGFyZW50c1VudGlsKGRvY3VtZW50LmJvZHksICdbZGF0YS1lcXVhbGl6ZXJdJykubGVuZ3RoID4gMDtcclxuICAgIHRoaXMuaXNPbiA9IGZhbHNlO1xyXG4gICAgdGhpcy5fYmluZEhhbmRsZXIgPSB7XHJcbiAgICAgIG9uUmVzaXplTWVCb3VuZDogdGhpcy5fb25SZXNpemVNZS5iaW5kKHRoaXMpLFxyXG4gICAgICBvblBvc3RFcXVhbGl6ZWRCb3VuZDogdGhpcy5fb25Qb3N0RXF1YWxpemVkLmJpbmQodGhpcylcclxuICAgIH07XHJcblxyXG4gICAgdmFyIGltZ3MgPSB0aGlzLiRlbGVtZW50LmZpbmQoJ2ltZycpO1xyXG4gICAgdmFyIHRvb1NtYWxsO1xyXG4gICAgaWYodGhpcy5vcHRpb25zLmVxdWFsaXplT24pe1xyXG4gICAgICB0b29TbWFsbCA9IHRoaXMuX2NoZWNrTVEoKTtcclxuICAgICAgJCh3aW5kb3cpLm9uKCdjaGFuZ2VkLnpmLm1lZGlhcXVlcnknLCB0aGlzLl9jaGVja01RLmJpbmQodGhpcykpO1xyXG4gICAgfWVsc2V7XHJcbiAgICAgIHRoaXMuX2V2ZW50cygpO1xyXG4gICAgfVxyXG4gICAgaWYoKHRvb1NtYWxsICE9PSB1bmRlZmluZWQgJiYgdG9vU21hbGwgPT09IGZhbHNlKSB8fCB0b29TbWFsbCA9PT0gdW5kZWZpbmVkKXtcclxuICAgICAgaWYoaW1ncy5sZW5ndGgpe1xyXG4gICAgICAgIEZvdW5kYXRpb24ub25JbWFnZXNMb2FkZWQoaW1ncywgdGhpcy5fcmVmbG93LmJpbmQodGhpcykpO1xyXG4gICAgICB9ZWxzZXtcclxuICAgICAgICB0aGlzLl9yZWZsb3coKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVtb3ZlcyBldmVudCBsaXN0ZW5lcnMgaWYgdGhlIGJyZWFrcG9pbnQgaXMgdG9vIHNtYWxsLlxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX3BhdXNlRXZlbnRzKCkge1xyXG4gICAgdGhpcy5pc09uID0gZmFsc2U7XHJcbiAgICB0aGlzLiRlbGVtZW50Lm9mZih7XHJcbiAgICAgICcuemYuZXF1YWxpemVyJzogdGhpcy5fYmluZEhhbmRsZXIub25Qb3N0RXF1YWxpemVkQm91bmQsXHJcbiAgICAgICdyZXNpemVtZS56Zi50cmlnZ2VyJzogdGhpcy5fYmluZEhhbmRsZXIub25SZXNpemVNZUJvdW5kXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGZ1bmN0aW9uIHRvIGhhbmRsZSAkZWxlbWVudHMgcmVzaXplbWUuemYudHJpZ2dlciwgd2l0aCBib3VuZCB0aGlzIG9uIF9iaW5kSGFuZGxlci5vblJlc2l6ZU1lQm91bmRcclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9vblJlc2l6ZU1lKGUpIHtcclxuICAgIHRoaXMuX3JlZmxvdygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogZnVuY3Rpb24gdG8gaGFuZGxlICRlbGVtZW50cyBwb3N0ZXF1YWxpemVkLnpmLmVxdWFsaXplciwgd2l0aCBib3VuZCB0aGlzIG9uIF9iaW5kSGFuZGxlci5vblBvc3RFcXVhbGl6ZWRCb3VuZFxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX29uUG9zdEVxdWFsaXplZChlKSB7XHJcbiAgICBpZihlLnRhcmdldCAhPT0gdGhpcy4kZWxlbWVudFswXSl7IHRoaXMuX3JlZmxvdygpOyB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbml0aWFsaXplcyBldmVudHMgZm9yIEVxdWFsaXplci5cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9ldmVudHMoKSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgdGhpcy5fcGF1c2VFdmVudHMoKTtcclxuICAgIGlmKHRoaXMuaGFzTmVzdGVkKXtcclxuICAgICAgdGhpcy4kZWxlbWVudC5vbigncG9zdGVxdWFsaXplZC56Zi5lcXVhbGl6ZXInLCB0aGlzLl9iaW5kSGFuZGxlci5vblBvc3RFcXVhbGl6ZWRCb3VuZCk7XHJcbiAgICB9ZWxzZXtcclxuICAgICAgdGhpcy4kZWxlbWVudC5vbigncmVzaXplbWUuemYudHJpZ2dlcicsIHRoaXMuX2JpbmRIYW5kbGVyLm9uUmVzaXplTWVCb3VuZCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLmlzT24gPSB0cnVlO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2tzIHRoZSBjdXJyZW50IGJyZWFrcG9pbnQgdG8gdGhlIG1pbmltdW0gcmVxdWlyZWQgc2l6ZS5cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9jaGVja01RKCkge1xyXG4gICAgdmFyIHRvb1NtYWxsID0gIUZvdW5kYXRpb24uTWVkaWFRdWVyeS5hdExlYXN0KHRoaXMub3B0aW9ucy5lcXVhbGl6ZU9uKTtcclxuICAgIGlmKHRvb1NtYWxsKXtcclxuICAgICAgaWYodGhpcy5pc09uKXtcclxuICAgICAgICB0aGlzLl9wYXVzZUV2ZW50cygpO1xyXG4gICAgICAgIHRoaXMuJHdhdGNoZWQuY3NzKCdoZWlnaHQnLCAnYXV0bycpO1xyXG4gICAgICB9XHJcbiAgICB9ZWxzZXtcclxuICAgICAgaWYoIXRoaXMuaXNPbil7XHJcbiAgICAgICAgdGhpcy5fZXZlbnRzKCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiB0b29TbWFsbDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEEgbm9vcCB2ZXJzaW9uIGZvciB0aGUgcGx1Z2luXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfa2lsbHN3aXRjaCgpIHtcclxuICAgIHJldHVybjtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENhbGxzIG5lY2Vzc2FyeSBmdW5jdGlvbnMgdG8gdXBkYXRlIEVxdWFsaXplciB1cG9uIERPTSBjaGFuZ2VcclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9yZWZsb3coKSB7XHJcbiAgICBpZighdGhpcy5vcHRpb25zLmVxdWFsaXplT25TdGFjayl7XHJcbiAgICAgIGlmKHRoaXMuX2lzU3RhY2tlZCgpKXtcclxuICAgICAgICB0aGlzLiR3YXRjaGVkLmNzcygnaGVpZ2h0JywgJ2F1dG8nKTtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuZXF1YWxpemVCeVJvdykge1xyXG4gICAgICB0aGlzLmdldEhlaWdodHNCeVJvdyh0aGlzLmFwcGx5SGVpZ2h0QnlSb3cuYmluZCh0aGlzKSk7XHJcbiAgICB9ZWxzZXtcclxuICAgICAgdGhpcy5nZXRIZWlnaHRzKHRoaXMuYXBwbHlIZWlnaHQuYmluZCh0aGlzKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBNYW51YWxseSBkZXRlcm1pbmVzIGlmIHRoZSBmaXJzdCAyIGVsZW1lbnRzIGFyZSAqTk9UKiBzdGFja2VkLlxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX2lzU3RhY2tlZCgpIHtcclxuICAgIHJldHVybiB0aGlzLiR3YXRjaGVkWzBdLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcCAhPT0gdGhpcy4kd2F0Y2hlZFsxXS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS50b3A7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBGaW5kcyB0aGUgb3V0ZXIgaGVpZ2h0cyBvZiBjaGlsZHJlbiBjb250YWluZWQgd2l0aGluIGFuIEVxdWFsaXplciBwYXJlbnQgYW5kIHJldHVybnMgdGhlbSBpbiBhbiBhcnJheVxyXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNiIC0gQSBub24tb3B0aW9uYWwgY2FsbGJhY2sgdG8gcmV0dXJuIHRoZSBoZWlnaHRzIGFycmF5IHRvLlxyXG4gICAqIEByZXR1cm5zIHtBcnJheX0gaGVpZ2h0cyAtIEFuIGFycmF5IG9mIGhlaWdodHMgb2YgY2hpbGRyZW4gd2l0aGluIEVxdWFsaXplciBjb250YWluZXJcclxuICAgKi9cclxuICBnZXRIZWlnaHRzKGNiKSB7XHJcbiAgICB2YXIgaGVpZ2h0cyA9IFtdO1xyXG4gICAgZm9yKHZhciBpID0gMCwgbGVuID0gdGhpcy4kd2F0Y2hlZC5sZW5ndGg7IGkgPCBsZW47IGkrKyl7XHJcbiAgICAgIHRoaXMuJHdhdGNoZWRbaV0uc3R5bGUuaGVpZ2h0ID0gJ2F1dG8nO1xyXG4gICAgICBoZWlnaHRzLnB1c2godGhpcy4kd2F0Y2hlZFtpXS5vZmZzZXRIZWlnaHQpO1xyXG4gICAgfVxyXG4gICAgY2IoaGVpZ2h0cyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBGaW5kcyB0aGUgb3V0ZXIgaGVpZ2h0cyBvZiBjaGlsZHJlbiBjb250YWluZWQgd2l0aGluIGFuIEVxdWFsaXplciBwYXJlbnQgYW5kIHJldHVybnMgdGhlbSBpbiBhbiBhcnJheVxyXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNiIC0gQSBub24tb3B0aW9uYWwgY2FsbGJhY2sgdG8gcmV0dXJuIHRoZSBoZWlnaHRzIGFycmF5IHRvLlxyXG4gICAqIEByZXR1cm5zIHtBcnJheX0gZ3JvdXBzIC0gQW4gYXJyYXkgb2YgaGVpZ2h0cyBvZiBjaGlsZHJlbiB3aXRoaW4gRXF1YWxpemVyIGNvbnRhaW5lciBncm91cGVkIGJ5IHJvdyB3aXRoIGVsZW1lbnQsaGVpZ2h0IGFuZCBtYXggYXMgbGFzdCBjaGlsZFxyXG4gICAqL1xyXG4gIGdldEhlaWdodHNCeVJvdyhjYikge1xyXG4gICAgdmFyIGxhc3RFbFRvcE9mZnNldCA9ICh0aGlzLiR3YXRjaGVkLmxlbmd0aCA/IHRoaXMuJHdhdGNoZWQuZmlyc3QoKS5vZmZzZXQoKS50b3AgOiAwKSxcclxuICAgICAgICBncm91cHMgPSBbXSxcclxuICAgICAgICBncm91cCA9IDA7XHJcbiAgICAvL2dyb3VwIGJ5IFJvd1xyXG4gICAgZ3JvdXBzW2dyb3VwXSA9IFtdO1xyXG4gICAgZm9yKHZhciBpID0gMCwgbGVuID0gdGhpcy4kd2F0Y2hlZC5sZW5ndGg7IGkgPCBsZW47IGkrKyl7XHJcbiAgICAgIHRoaXMuJHdhdGNoZWRbaV0uc3R5bGUuaGVpZ2h0ID0gJ2F1dG8nO1xyXG4gICAgICAvL21heWJlIGNvdWxkIHVzZSB0aGlzLiR3YXRjaGVkW2ldLm9mZnNldFRvcFxyXG4gICAgICB2YXIgZWxPZmZzZXRUb3AgPSAkKHRoaXMuJHdhdGNoZWRbaV0pLm9mZnNldCgpLnRvcDtcclxuICAgICAgaWYgKGVsT2Zmc2V0VG9wIT1sYXN0RWxUb3BPZmZzZXQpIHtcclxuICAgICAgICBncm91cCsrO1xyXG4gICAgICAgIGdyb3Vwc1tncm91cF0gPSBbXTtcclxuICAgICAgICBsYXN0RWxUb3BPZmZzZXQ9ZWxPZmZzZXRUb3A7XHJcbiAgICAgIH1cclxuICAgICAgZ3JvdXBzW2dyb3VwXS5wdXNoKFt0aGlzLiR3YXRjaGVkW2ldLHRoaXMuJHdhdGNoZWRbaV0ub2Zmc2V0SGVpZ2h0XSk7XHJcbiAgICB9XHJcblxyXG4gICAgZm9yICh2YXIgaiA9IDAsIGxuID0gZ3JvdXBzLmxlbmd0aDsgaiA8IGxuOyBqKyspIHtcclxuICAgICAgdmFyIGhlaWdodHMgPSAkKGdyb3Vwc1tqXSkubWFwKGZ1bmN0aW9uKCl7IHJldHVybiB0aGlzWzFdOyB9KS5nZXQoKTtcclxuICAgICAgdmFyIG1heCAgICAgICAgID0gTWF0aC5tYXguYXBwbHkobnVsbCwgaGVpZ2h0cyk7XHJcbiAgICAgIGdyb3Vwc1tqXS5wdXNoKG1heCk7XHJcbiAgICB9XHJcbiAgICBjYihncm91cHMpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hhbmdlcyB0aGUgQ1NTIGhlaWdodCBwcm9wZXJ0eSBvZiBlYWNoIGNoaWxkIGluIGFuIEVxdWFsaXplciBwYXJlbnQgdG8gbWF0Y2ggdGhlIHRhbGxlc3RcclxuICAgKiBAcGFyYW0ge2FycmF5fSBoZWlnaHRzIC0gQW4gYXJyYXkgb2YgaGVpZ2h0cyBvZiBjaGlsZHJlbiB3aXRoaW4gRXF1YWxpemVyIGNvbnRhaW5lclxyXG4gICAqIEBmaXJlcyBFcXVhbGl6ZXIjcHJlZXF1YWxpemVkXHJcbiAgICogQGZpcmVzIEVxdWFsaXplciNwb3N0ZXF1YWxpemVkXHJcbiAgICovXHJcbiAgYXBwbHlIZWlnaHQoaGVpZ2h0cykge1xyXG4gICAgdmFyIG1heCA9IE1hdGgubWF4LmFwcGx5KG51bGwsIGhlaWdodHMpO1xyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlcyBiZWZvcmUgdGhlIGhlaWdodHMgYXJlIGFwcGxpZWRcclxuICAgICAqIEBldmVudCBFcXVhbGl6ZXIjcHJlZXF1YWxpemVkXHJcbiAgICAgKi9cclxuICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcigncHJlZXF1YWxpemVkLnpmLmVxdWFsaXplcicpO1xyXG5cclxuICAgIHRoaXMuJHdhdGNoZWQuY3NzKCdoZWlnaHQnLCBtYXgpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZXMgd2hlbiB0aGUgaGVpZ2h0cyBoYXZlIGJlZW4gYXBwbGllZFxyXG4gICAgICogQGV2ZW50IEVxdWFsaXplciNwb3N0ZXF1YWxpemVkXHJcbiAgICAgKi9cclxuICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ3Bvc3RlcXVhbGl6ZWQuemYuZXF1YWxpemVyJyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGFuZ2VzIHRoZSBDU1MgaGVpZ2h0IHByb3BlcnR5IG9mIGVhY2ggY2hpbGQgaW4gYW4gRXF1YWxpemVyIHBhcmVudCB0byBtYXRjaCB0aGUgdGFsbGVzdCBieSByb3dcclxuICAgKiBAcGFyYW0ge2FycmF5fSBncm91cHMgLSBBbiBhcnJheSBvZiBoZWlnaHRzIG9mIGNoaWxkcmVuIHdpdGhpbiBFcXVhbGl6ZXIgY29udGFpbmVyIGdyb3VwZWQgYnkgcm93IHdpdGggZWxlbWVudCxoZWlnaHQgYW5kIG1heCBhcyBsYXN0IGNoaWxkXHJcbiAgICogQGZpcmVzIEVxdWFsaXplciNwcmVlcXVhbGl6ZWRcclxuICAgKiBAZmlyZXMgRXF1YWxpemVyI3ByZWVxdWFsaXplZFJvd1xyXG4gICAqIEBmaXJlcyBFcXVhbGl6ZXIjcG9zdGVxdWFsaXplZFJvd1xyXG4gICAqIEBmaXJlcyBFcXVhbGl6ZXIjcG9zdGVxdWFsaXplZFxyXG4gICAqL1xyXG4gIGFwcGx5SGVpZ2h0QnlSb3coZ3JvdXBzKSB7XHJcbiAgICAvKipcclxuICAgICAqIEZpcmVzIGJlZm9yZSB0aGUgaGVpZ2h0cyBhcmUgYXBwbGllZFxyXG4gICAgICovXHJcbiAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ3ByZWVxdWFsaXplZC56Zi5lcXVhbGl6ZXInKTtcclxuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBncm91cHMubGVuZ3RoOyBpIDwgbGVuIDsgaSsrKSB7XHJcbiAgICAgIHZhciBncm91cHNJTGVuZ3RoID0gZ3JvdXBzW2ldLmxlbmd0aCxcclxuICAgICAgICAgIG1heCA9IGdyb3Vwc1tpXVtncm91cHNJTGVuZ3RoIC0gMV07XHJcbiAgICAgIGlmIChncm91cHNJTGVuZ3RoPD0yKSB7XHJcbiAgICAgICAgJChncm91cHNbaV1bMF1bMF0pLmNzcyh7J2hlaWdodCc6J2F1dG8nfSk7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuICAgICAgLyoqXHJcbiAgICAgICAgKiBGaXJlcyBiZWZvcmUgdGhlIGhlaWdodHMgcGVyIHJvdyBhcmUgYXBwbGllZFxyXG4gICAgICAgICogQGV2ZW50IEVxdWFsaXplciNwcmVlcXVhbGl6ZWRSb3dcclxuICAgICAgICAqL1xyXG4gICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ3ByZWVxdWFsaXplZHJvdy56Zi5lcXVhbGl6ZXInKTtcclxuICAgICAgZm9yICh2YXIgaiA9IDAsIGxlbkogPSAoZ3JvdXBzSUxlbmd0aC0xKTsgaiA8IGxlbkogOyBqKyspIHtcclxuICAgICAgICAkKGdyb3Vwc1tpXVtqXVswXSkuY3NzKHsnaGVpZ2h0JzptYXh9KTtcclxuICAgICAgfVxyXG4gICAgICAvKipcclxuICAgICAgICAqIEZpcmVzIHdoZW4gdGhlIGhlaWdodHMgcGVyIHJvdyBoYXZlIGJlZW4gYXBwbGllZFxyXG4gICAgICAgICogQGV2ZW50IEVxdWFsaXplciNwb3N0ZXF1YWxpemVkUm93XHJcbiAgICAgICAgKi9cclxuICAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKCdwb3N0ZXF1YWxpemVkcm93LnpmLmVxdWFsaXplcicpO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlcyB3aGVuIHRoZSBoZWlnaHRzIGhhdmUgYmVlbiBhcHBsaWVkXHJcbiAgICAgKi9cclxuICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ3Bvc3RlcXVhbGl6ZWQuemYuZXF1YWxpemVyJyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBEZXN0cm95cyBhbiBpbnN0YW5jZSBvZiBFcXVhbGl6ZXIuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICovXHJcbiAgZGVzdHJveSgpIHtcclxuICAgIHRoaXMuX3BhdXNlRXZlbnRzKCk7XHJcbiAgICB0aGlzLiR3YXRjaGVkLmNzcygnaGVpZ2h0JywgJ2F1dG8nKTtcclxuXHJcbiAgICBGb3VuZGF0aW9uLnVucmVnaXN0ZXJQbHVnaW4odGhpcyk7XHJcbiAgfVxyXG59XHJcblxyXG4vKipcclxuICogRGVmYXVsdCBzZXR0aW5ncyBmb3IgcGx1Z2luXHJcbiAqL1xyXG5FcXVhbGl6ZXIuZGVmYXVsdHMgPSB7XHJcbiAgLyoqXHJcbiAgICogRW5hYmxlIGhlaWdodCBlcXVhbGl6YXRpb24gd2hlbiBzdGFja2VkIG9uIHNtYWxsZXIgc2NyZWVucy5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgdHJ1ZVxyXG4gICAqL1xyXG4gIGVxdWFsaXplT25TdGFjazogdHJ1ZSxcclxuICAvKipcclxuICAgKiBFbmFibGUgaGVpZ2h0IGVxdWFsaXphdGlvbiByb3cgYnkgcm93LlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSBmYWxzZVxyXG4gICAqL1xyXG4gIGVxdWFsaXplQnlSb3c6IGZhbHNlLFxyXG4gIC8qKlxyXG4gICAqIFN0cmluZyByZXByZXNlbnRpbmcgdGhlIG1pbmltdW0gYnJlYWtwb2ludCBzaXplIHRoZSBwbHVnaW4gc2hvdWxkIGVxdWFsaXplIGhlaWdodHMgb24uXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlICdtZWRpdW0nXHJcbiAgICovXHJcbiAgZXF1YWxpemVPbjogJydcclxufTtcclxuXHJcbi8vIFdpbmRvdyBleHBvcnRzXHJcbkZvdW5kYXRpb24ucGx1Z2luKEVxdWFsaXplciwgJ0VxdWFsaXplcicpO1xyXG5cclxufShqUXVlcnkpO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG4hZnVuY3Rpb24oJCkge1xyXG5cclxuLyoqXHJcbiAqIEludGVyY2hhbmdlIG1vZHVsZS5cclxuICogQG1vZHVsZSBmb3VuZGF0aW9uLmludGVyY2hhbmdlXHJcbiAqIEByZXF1aXJlcyBmb3VuZGF0aW9uLnV0aWwubWVkaWFRdWVyeVxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLnRpbWVyQW5kSW1hZ2VMb2FkZXJcclxuICovXHJcblxyXG5jbGFzcyBJbnRlcmNoYW5nZSB7XHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBJbnRlcmNoYW5nZS5cclxuICAgKiBAY2xhc3NcclxuICAgKiBAZmlyZXMgSW50ZXJjaGFuZ2UjaW5pdFxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbGVtZW50IC0galF1ZXJ5IG9iamVjdCB0byBhZGQgdGhlIHRyaWdnZXIgdG8uXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBPdmVycmlkZXMgdG8gdGhlIGRlZmF1bHQgcGx1Z2luIHNldHRpbmdzLlxyXG4gICAqL1xyXG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQsIG9wdGlvbnMpIHtcclxuICAgIHRoaXMuJGVsZW1lbnQgPSBlbGVtZW50O1xyXG4gICAgdGhpcy5vcHRpb25zID0gJC5leHRlbmQoe30sIEludGVyY2hhbmdlLmRlZmF1bHRzLCBvcHRpb25zKTtcclxuICAgIHRoaXMucnVsZXMgPSBbXTtcclxuICAgIHRoaXMuY3VycmVudFBhdGggPSAnJztcclxuXHJcbiAgICB0aGlzLl9pbml0KCk7XHJcbiAgICB0aGlzLl9ldmVudHMoKTtcclxuXHJcbiAgICBGb3VuZGF0aW9uLnJlZ2lzdGVyUGx1Z2luKHRoaXMsICdJbnRlcmNoYW5nZScpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW5pdGlhbGl6ZXMgdGhlIEludGVyY2hhbmdlIHBsdWdpbiBhbmQgY2FsbHMgZnVuY3Rpb25zIHRvIGdldCBpbnRlcmNoYW5nZSBmdW5jdGlvbmluZyBvbiBsb2FkLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX2luaXQoKSB7XHJcbiAgICB0aGlzLl9hZGRCcmVha3BvaW50cygpO1xyXG4gICAgdGhpcy5fZ2VuZXJhdGVSdWxlcygpO1xyXG4gICAgdGhpcy5fcmVmbG93KCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbml0aWFsaXplcyBldmVudHMgZm9yIEludGVyY2hhbmdlLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX2V2ZW50cygpIHtcclxuICAgICQod2luZG93KS5vbigncmVzaXplLnpmLmludGVyY2hhbmdlJywgRm91bmRhdGlvbi51dGlsLnRocm90dGxlKHRoaXMuX3JlZmxvdy5iaW5kKHRoaXMpLCA1MCkpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2FsbHMgbmVjZXNzYXJ5IGZ1bmN0aW9ucyB0byB1cGRhdGUgSW50ZXJjaGFuZ2UgdXBvbiBET00gY2hhbmdlXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfcmVmbG93KCkge1xyXG4gICAgdmFyIG1hdGNoO1xyXG5cclxuICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBlYWNoIHJ1bGUsIGJ1dCBvbmx5IHNhdmUgdGhlIGxhc3QgbWF0Y2hcclxuICAgIGZvciAodmFyIGkgaW4gdGhpcy5ydWxlcykge1xyXG4gICAgICBpZih0aGlzLnJ1bGVzLmhhc093blByb3BlcnR5KGkpKSB7XHJcbiAgICAgICAgdmFyIHJ1bGUgPSB0aGlzLnJ1bGVzW2ldO1xyXG5cclxuICAgICAgICBpZiAod2luZG93Lm1hdGNoTWVkaWEocnVsZS5xdWVyeSkubWF0Y2hlcykge1xyXG4gICAgICAgICAgbWF0Y2ggPSBydWxlO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmIChtYXRjaCkge1xyXG4gICAgICB0aGlzLnJlcGxhY2UobWF0Y2gucGF0aCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBHZXRzIHRoZSBGb3VuZGF0aW9uIGJyZWFrcG9pbnRzIGFuZCBhZGRzIHRoZW0gdG8gdGhlIEludGVyY2hhbmdlLlNQRUNJQUxfUVVFUklFUyBvYmplY3QuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfYWRkQnJlYWtwb2ludHMoKSB7XHJcbiAgICBmb3IgKHZhciBpIGluIEZvdW5kYXRpb24uTWVkaWFRdWVyeS5xdWVyaWVzKSB7XHJcbiAgICAgIGlmIChGb3VuZGF0aW9uLk1lZGlhUXVlcnkucXVlcmllcy5oYXNPd25Qcm9wZXJ0eShpKSkge1xyXG4gICAgICAgIHZhciBxdWVyeSA9IEZvdW5kYXRpb24uTWVkaWFRdWVyeS5xdWVyaWVzW2ldO1xyXG4gICAgICAgIEludGVyY2hhbmdlLlNQRUNJQUxfUVVFUklFU1txdWVyeS5uYW1lXSA9IHF1ZXJ5LnZhbHVlO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGVja3MgdGhlIEludGVyY2hhbmdlIGVsZW1lbnQgZm9yIHRoZSBwcm92aWRlZCBtZWRpYSBxdWVyeSArIGNvbnRlbnQgcGFpcmluZ3NcclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBlbGVtZW50IC0galF1ZXJ5IG9iamVjdCB0aGF0IGlzIGFuIEludGVyY2hhbmdlIGluc3RhbmNlXHJcbiAgICogQHJldHVybnMge0FycmF5fSBzY2VuYXJpb3MgLSBBcnJheSBvZiBvYmplY3RzIHRoYXQgaGF2ZSAnbXEnIGFuZCAncGF0aCcga2V5cyB3aXRoIGNvcnJlc3BvbmRpbmcga2V5c1xyXG4gICAqL1xyXG4gIF9nZW5lcmF0ZVJ1bGVzKGVsZW1lbnQpIHtcclxuICAgIHZhciBydWxlc0xpc3QgPSBbXTtcclxuICAgIHZhciBydWxlcztcclxuXHJcbiAgICBpZiAodGhpcy5vcHRpb25zLnJ1bGVzKSB7XHJcbiAgICAgIHJ1bGVzID0gdGhpcy5vcHRpb25zLnJ1bGVzO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgIHJ1bGVzID0gdGhpcy4kZWxlbWVudC5kYXRhKCdpbnRlcmNoYW5nZScpLm1hdGNoKC9cXFsuKj9cXF0vZyk7XHJcbiAgICB9XHJcblxyXG4gICAgZm9yICh2YXIgaSBpbiBydWxlcykge1xyXG4gICAgICBpZihydWxlcy5oYXNPd25Qcm9wZXJ0eShpKSkge1xyXG4gICAgICAgIHZhciBydWxlID0gcnVsZXNbaV0uc2xpY2UoMSwgLTEpLnNwbGl0KCcsICcpO1xyXG4gICAgICAgIHZhciBwYXRoID0gcnVsZS5zbGljZSgwLCAtMSkuam9pbignJyk7XHJcbiAgICAgICAgdmFyIHF1ZXJ5ID0gcnVsZVtydWxlLmxlbmd0aCAtIDFdO1xyXG5cclxuICAgICAgICBpZiAoSW50ZXJjaGFuZ2UuU1BFQ0lBTF9RVUVSSUVTW3F1ZXJ5XSkge1xyXG4gICAgICAgICAgcXVlcnkgPSBJbnRlcmNoYW5nZS5TUEVDSUFMX1FVRVJJRVNbcXVlcnldO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcnVsZXNMaXN0LnB1c2goe1xyXG4gICAgICAgICAgcGF0aDogcGF0aCxcclxuICAgICAgICAgIHF1ZXJ5OiBxdWVyeVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5ydWxlcyA9IHJ1bGVzTGlzdDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFVwZGF0ZSB0aGUgYHNyY2AgcHJvcGVydHkgb2YgYW4gaW1hZ2UsIG9yIGNoYW5nZSB0aGUgSFRNTCBvZiBhIGNvbnRhaW5lciwgdG8gdGhlIHNwZWNpZmllZCBwYXRoLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBwYXRoIC0gUGF0aCB0byB0aGUgaW1hZ2Ugb3IgSFRNTCBwYXJ0aWFsLlxyXG4gICAqIEBmaXJlcyBJbnRlcmNoYW5nZSNyZXBsYWNlZFxyXG4gICAqL1xyXG4gIHJlcGxhY2UocGF0aCkge1xyXG4gICAgaWYgKHRoaXMuY3VycmVudFBhdGggPT09IHBhdGgpIHJldHVybjtcclxuXHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzLFxyXG4gICAgICAgIHRyaWdnZXIgPSAncmVwbGFjZWQuemYuaW50ZXJjaGFuZ2UnO1xyXG5cclxuICAgIC8vIFJlcGxhY2luZyBpbWFnZXNcclxuICAgIGlmICh0aGlzLiRlbGVtZW50WzBdLm5vZGVOYW1lID09PSAnSU1HJykge1xyXG4gICAgICB0aGlzLiRlbGVtZW50LmF0dHIoJ3NyYycsIHBhdGgpLmxvYWQoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgX3RoaXMuY3VycmVudFBhdGggPSBwYXRoO1xyXG4gICAgICB9KVxyXG4gICAgICAudHJpZ2dlcih0cmlnZ2VyKTtcclxuICAgIH1cclxuICAgIC8vIFJlcGxhY2luZyBiYWNrZ3JvdW5kIGltYWdlc1xyXG4gICAgZWxzZSBpZiAocGF0aC5tYXRjaCgvXFwuKGdpZnxqcGd8anBlZ3xwbmd8c3ZnfHRpZmYpKFs/I10uKik/L2kpKSB7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnQuY3NzKHsgJ2JhY2tncm91bmQtaW1hZ2UnOiAndXJsKCcrcGF0aCsnKScgfSlcclxuICAgICAgICAgIC50cmlnZ2VyKHRyaWdnZXIpO1xyXG4gICAgfVxyXG4gICAgLy8gUmVwbGFjaW5nIEhUTUxcclxuICAgIGVsc2Uge1xyXG4gICAgICAkLmdldChwYXRoLCBmdW5jdGlvbihyZXNwb25zZSkge1xyXG4gICAgICAgIF90aGlzLiRlbGVtZW50Lmh0bWwocmVzcG9uc2UpXHJcbiAgICAgICAgICAgICAudHJpZ2dlcih0cmlnZ2VyKTtcclxuICAgICAgICAkKHJlc3BvbnNlKS5mb3VuZGF0aW9uKCk7XHJcbiAgICAgICAgX3RoaXMuY3VycmVudFBhdGggPSBwYXRoO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVzIHdoZW4gY29udGVudCBpbiBhbiBJbnRlcmNoYW5nZSBlbGVtZW50IGlzIGRvbmUgYmVpbmcgbG9hZGVkLlxyXG4gICAgICogQGV2ZW50IEludGVyY2hhbmdlI3JlcGxhY2VkXHJcbiAgICAgKi9cclxuICAgIC8vIHRoaXMuJGVsZW1lbnQudHJpZ2dlcigncmVwbGFjZWQuemYuaW50ZXJjaGFuZ2UnKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlc3Ryb3lzIGFuIGluc3RhbmNlIG9mIGludGVyY2hhbmdlLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqL1xyXG4gIGRlc3Ryb3koKSB7XHJcbiAgICAvL1RPRE8gdGhpcy5cclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBEZWZhdWx0IHNldHRpbmdzIGZvciBwbHVnaW5cclxuICovXHJcbkludGVyY2hhbmdlLmRlZmF1bHRzID0ge1xyXG4gIC8qKlxyXG4gICAqIFJ1bGVzIHRvIGJlIGFwcGxpZWQgdG8gSW50ZXJjaGFuZ2UgZWxlbWVudHMuIFNldCB3aXRoIHRoZSBgZGF0YS1pbnRlcmNoYW5nZWAgYXJyYXkgbm90YXRpb24uXHJcbiAgICogQG9wdGlvblxyXG4gICAqL1xyXG4gIHJ1bGVzOiBudWxsXHJcbn07XHJcblxyXG5JbnRlcmNoYW5nZS5TUEVDSUFMX1FVRVJJRVMgPSB7XHJcbiAgJ2xhbmRzY2FwZSc6ICdzY3JlZW4gYW5kIChvcmllbnRhdGlvbjogbGFuZHNjYXBlKScsXHJcbiAgJ3BvcnRyYWl0JzogJ3NjcmVlbiBhbmQgKG9yaWVudGF0aW9uOiBwb3J0cmFpdCknLFxyXG4gICdyZXRpbmEnOiAnb25seSBzY3JlZW4gYW5kICgtd2Via2l0LW1pbi1kZXZpY2UtcGl4ZWwtcmF0aW86IDIpLCBvbmx5IHNjcmVlbiBhbmQgKG1pbi0tbW96LWRldmljZS1waXhlbC1yYXRpbzogMiksIG9ubHkgc2NyZWVuIGFuZCAoLW8tbWluLWRldmljZS1waXhlbC1yYXRpbzogMi8xKSwgb25seSBzY3JlZW4gYW5kIChtaW4tZGV2aWNlLXBpeGVsLXJhdGlvOiAyKSwgb25seSBzY3JlZW4gYW5kIChtaW4tcmVzb2x1dGlvbjogMTkyZHBpKSwgb25seSBzY3JlZW4gYW5kIChtaW4tcmVzb2x1dGlvbjogMmRwcHgpJ1xyXG59O1xyXG5cclxuLy8gV2luZG93IGV4cG9ydHNcclxuRm91bmRhdGlvbi5wbHVnaW4oSW50ZXJjaGFuZ2UsICdJbnRlcmNoYW5nZScpO1xyXG5cclxufShqUXVlcnkpO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG4hZnVuY3Rpb24oJCkge1xyXG5cclxuLyoqXHJcbiAqIE1hZ2VsbGFuIG1vZHVsZS5cclxuICogQG1vZHVsZSBmb3VuZGF0aW9uLm1hZ2VsbGFuXHJcbiAqL1xyXG5cclxuY2xhc3MgTWFnZWxsYW4ge1xyXG4gIC8qKlxyXG4gICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgTWFnZWxsYW4uXHJcbiAgICogQGNsYXNzXHJcbiAgICogQGZpcmVzIE1hZ2VsbGFuI2luaXRcclxuICAgKiBAcGFyYW0ge09iamVjdH0gZWxlbWVudCAtIGpRdWVyeSBvYmplY3QgdG8gYWRkIHRoZSB0cmlnZ2VyIHRvLlxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gT3ZlcnJpZGVzIHRvIHRoZSBkZWZhdWx0IHBsdWdpbiBzZXR0aW5ncy5cclxuICAgKi9cclxuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBvcHRpb25zKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50ID0gZWxlbWVudDtcclxuICAgIHRoaXMub3B0aW9ucyAgPSAkLmV4dGVuZCh7fSwgTWFnZWxsYW4uZGVmYXVsdHMsIHRoaXMuJGVsZW1lbnQuZGF0YSgpLCBvcHRpb25zKTtcclxuXHJcbiAgICB0aGlzLl9pbml0KCk7XHJcblxyXG4gICAgRm91bmRhdGlvbi5yZWdpc3RlclBsdWdpbih0aGlzLCAnTWFnZWxsYW4nKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpYWxpemVzIHRoZSBNYWdlbGxhbiBwbHVnaW4gYW5kIGNhbGxzIGZ1bmN0aW9ucyB0byBnZXQgZXF1YWxpemVyIGZ1bmN0aW9uaW5nIG9uIGxvYWQuXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfaW5pdCgpIHtcclxuICAgIHZhciBpZCA9IHRoaXMuJGVsZW1lbnRbMF0uaWQgfHwgRm91bmRhdGlvbi5HZXRZb0RpZ2l0cyg2LCAnbWFnZWxsYW4nKTtcclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICB0aGlzLiR0YXJnZXRzID0gJCgnW2RhdGEtbWFnZWxsYW4tdGFyZ2V0XScpO1xyXG4gICAgdGhpcy4kbGlua3MgPSB0aGlzLiRlbGVtZW50LmZpbmQoJ2EnKTtcclxuICAgIHRoaXMuJGVsZW1lbnQuYXR0cih7XHJcbiAgICAgICdkYXRhLXJlc2l6ZSc6IGlkLFxyXG4gICAgICAnZGF0YS1zY3JvbGwnOiBpZCxcclxuICAgICAgJ2lkJzogaWRcclxuICAgIH0pO1xyXG4gICAgdGhpcy4kYWN0aXZlID0gJCgpO1xyXG4gICAgdGhpcy5zY3JvbGxQb3MgPSBwYXJzZUludCh3aW5kb3cucGFnZVlPZmZzZXQsIDEwKTtcclxuXHJcbiAgICB0aGlzLl9ldmVudHMoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENhbGN1bGF0ZXMgYW4gYXJyYXkgb2YgcGl4ZWwgdmFsdWVzIHRoYXQgYXJlIHRoZSBkZW1hcmNhdGlvbiBsaW5lcyBiZXR3ZWVuIGxvY2F0aW9ucyBvbiB0aGUgcGFnZS5cclxuICAgKiBDYW4gYmUgaW52b2tlZCBpZiBuZXcgZWxlbWVudHMgYXJlIGFkZGVkIG9yIHRoZSBzaXplIG9mIGEgbG9jYXRpb24gY2hhbmdlcy5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKi9cclxuICBjYWxjUG9pbnRzKCkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcyxcclxuICAgICAgICBib2R5ID0gZG9jdW1lbnQuYm9keSxcclxuICAgICAgICBodG1sID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xyXG5cclxuICAgIHRoaXMucG9pbnRzID0gW107XHJcbiAgICB0aGlzLndpbkhlaWdodCA9IE1hdGgucm91bmQoTWF0aC5tYXgod2luZG93LmlubmVySGVpZ2h0LCBodG1sLmNsaWVudEhlaWdodCkpO1xyXG4gICAgdGhpcy5kb2NIZWlnaHQgPSBNYXRoLnJvdW5kKE1hdGgubWF4KGJvZHkuc2Nyb2xsSGVpZ2h0LCBib2R5Lm9mZnNldEhlaWdodCwgaHRtbC5jbGllbnRIZWlnaHQsIGh0bWwuc2Nyb2xsSGVpZ2h0LCBodG1sLm9mZnNldEhlaWdodCkpO1xyXG5cclxuICAgIHRoaXMuJHRhcmdldHMuZWFjaChmdW5jdGlvbigpe1xyXG4gICAgICB2YXIgJHRhciA9ICQodGhpcyksXHJcbiAgICAgICAgICBwdCA9IE1hdGgucm91bmQoJHRhci5vZmZzZXQoKS50b3AgLSBfdGhpcy5vcHRpb25zLnRocmVzaG9sZCk7XHJcbiAgICAgICR0YXIudGFyZ2V0UG9pbnQgPSBwdDtcclxuICAgICAgX3RoaXMucG9pbnRzLnB1c2gocHQpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbml0aWFsaXplcyBldmVudHMgZm9yIE1hZ2VsbGFuLlxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX2V2ZW50cygpIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXMsXHJcbiAgICAgICAgJGJvZHkgPSAkKCdodG1sLCBib2R5JyksXHJcbiAgICAgICAgb3B0cyA9IHtcclxuICAgICAgICAgIGR1cmF0aW9uOiBfdGhpcy5vcHRpb25zLmFuaW1hdGlvbkR1cmF0aW9uLFxyXG4gICAgICAgICAgZWFzaW5nOiAgIF90aGlzLm9wdGlvbnMuYW5pbWF0aW9uRWFzaW5nXHJcbiAgICAgICAgfTtcclxuICAgICQod2luZG93KS5vbmUoJ2xvYWQnLCBmdW5jdGlvbigpe1xyXG4gICAgICBpZihfdGhpcy5vcHRpb25zLmRlZXBMaW5raW5nKXtcclxuICAgICAgICBpZihsb2NhdGlvbi5oYXNoKXtcclxuICAgICAgICAgIF90aGlzLnNjcm9sbFRvTG9jKGxvY2F0aW9uLmhhc2gpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBfdGhpcy5jYWxjUG9pbnRzKCk7XHJcbiAgICAgIF90aGlzLl91cGRhdGVBY3RpdmUoKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuJGVsZW1lbnQub24oe1xyXG4gICAgICAncmVzaXplbWUuemYudHJpZ2dlcic6IHRoaXMucmVmbG93LmJpbmQodGhpcyksXHJcbiAgICAgICdzY3JvbGxtZS56Zi50cmlnZ2VyJzogdGhpcy5fdXBkYXRlQWN0aXZlLmJpbmQodGhpcylcclxuICAgIH0pLm9uKCdjbGljay56Zi5tYWdlbGxhbicsICdhW2hyZWZePVwiI1wiXScsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgdmFyIGFycml2YWwgICA9IHRoaXMuZ2V0QXR0cmlidXRlKCdocmVmJyk7XHJcbiAgICAgICAgX3RoaXMuc2Nyb2xsVG9Mb2MoYXJyaXZhbCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZ1bmN0aW9uIHRvIHNjcm9sbCB0byBhIGdpdmVuIGxvY2F0aW9uIG9uIHRoZSBwYWdlLlxyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBsb2MgLSBhIHByb3Blcmx5IGZvcm1hdHRlZCBqUXVlcnkgaWQgc2VsZWN0b3IuIEV4YW1wbGU6ICcjZm9vJ1xyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqL1xyXG4gIHNjcm9sbFRvTG9jKGxvYykge1xyXG4gICAgdmFyIHNjcm9sbFBvcyA9IE1hdGgucm91bmQoJChsb2MpLm9mZnNldCgpLnRvcCAtIHRoaXMub3B0aW9ucy50aHJlc2hvbGQgLyAyIC0gdGhpcy5vcHRpb25zLmJhck9mZnNldCk7XHJcblxyXG4gICAgJCgnaHRtbCwgYm9keScpLnN0b3AodHJ1ZSkuYW5pbWF0ZSh7IHNjcm9sbFRvcDogc2Nyb2xsUG9zIH0sIHRoaXMub3B0aW9ucy5hbmltYXRpb25EdXJhdGlvbiwgdGhpcy5vcHRpb25zLmFuaW1hdGlvbkVhc2luZyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDYWxscyBuZWNlc3NhcnkgZnVuY3Rpb25zIHRvIHVwZGF0ZSBNYWdlbGxhbiB1cG9uIERPTSBjaGFuZ2VcclxuICAgKiBAZnVuY3Rpb25cclxuICAgKi9cclxuICByZWZsb3coKSB7XHJcbiAgICB0aGlzLmNhbGNQb2ludHMoKTtcclxuICAgIHRoaXMuX3VwZGF0ZUFjdGl2ZSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVXBkYXRlcyB0aGUgdmlzaWJpbGl0eSBvZiBhbiBhY3RpdmUgbG9jYXRpb24gbGluaywgYW5kIHVwZGF0ZXMgdGhlIHVybCBoYXNoIGZvciB0aGUgcGFnZSwgaWYgZGVlcExpbmtpbmcgZW5hYmxlZC5cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIEBmaXJlcyBNYWdlbGxhbiN1cGRhdGVcclxuICAgKi9cclxuICBfdXBkYXRlQWN0aXZlKC8qZXZ0LCBlbGVtLCBzY3JvbGxQb3MqLykge1xyXG4gICAgdmFyIHdpblBvcyA9IC8qc2Nyb2xsUG9zIHx8Ki8gcGFyc2VJbnQod2luZG93LnBhZ2VZT2Zmc2V0LCAxMCksXHJcbiAgICAgICAgY3VySWR4O1xyXG5cclxuICAgIGlmKHdpblBvcyArIHRoaXMud2luSGVpZ2h0ID09PSB0aGlzLmRvY0hlaWdodCl7IGN1cklkeCA9IHRoaXMucG9pbnRzLmxlbmd0aCAtIDE7IH1cclxuICAgIGVsc2UgaWYod2luUG9zIDwgdGhpcy5wb2ludHNbMF0peyBjdXJJZHggPSAwOyB9XHJcbiAgICBlbHNle1xyXG4gICAgICB2YXIgaXNEb3duID0gdGhpcy5zY3JvbGxQb3MgPCB3aW5Qb3MsXHJcbiAgICAgICAgICBfdGhpcyA9IHRoaXMsXHJcbiAgICAgICAgICBjdXJWaXNpYmxlID0gdGhpcy5wb2ludHMuZmlsdGVyKGZ1bmN0aW9uKHAsIGkpe1xyXG4gICAgICAgICAgICByZXR1cm4gaXNEb3duID8gcCAtIF90aGlzLm9wdGlvbnMuYmFyT2Zmc2V0IDw9IHdpblBvcyA6IHAgLSBfdGhpcy5vcHRpb25zLmJhck9mZnNldCAtIF90aGlzLm9wdGlvbnMudGhyZXNob2xkIDw9IHdpblBvcztcclxuICAgICAgICAgIH0pO1xyXG4gICAgICBjdXJJZHggPSBjdXJWaXNpYmxlLmxlbmd0aCA/IGN1clZpc2libGUubGVuZ3RoIC0gMSA6IDA7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy4kYWN0aXZlLnJlbW92ZUNsYXNzKHRoaXMub3B0aW9ucy5hY3RpdmVDbGFzcyk7XHJcbiAgICB0aGlzLiRhY3RpdmUgPSB0aGlzLiRsaW5rcy5lcShjdXJJZHgpLmFkZENsYXNzKHRoaXMub3B0aW9ucy5hY3RpdmVDbGFzcyk7XHJcblxyXG4gICAgaWYodGhpcy5vcHRpb25zLmRlZXBMaW5raW5nKXtcclxuICAgICAgdmFyIGhhc2ggPSB0aGlzLiRhY3RpdmVbMF0uZ2V0QXR0cmlidXRlKCdocmVmJyk7XHJcbiAgICAgIGlmKHdpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZSl7XHJcbiAgICAgICAgd2luZG93Lmhpc3RvcnkucHVzaFN0YXRlKG51bGwsIG51bGwsIGhhc2gpO1xyXG4gICAgICB9ZWxzZXtcclxuICAgICAgICB3aW5kb3cubG9jYXRpb24uaGFzaCA9IGhhc2g7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnNjcm9sbFBvcyA9IHdpblBvcztcclxuICAgIC8qKlxyXG4gICAgICogRmlyZXMgd2hlbiBtYWdlbGxhbiBpcyBmaW5pc2hlZCB1cGRhdGluZyB0byB0aGUgbmV3IGFjdGl2ZSBlbGVtZW50LlxyXG4gICAgICogQGV2ZW50IE1hZ2VsbGFuI3VwZGF0ZVxyXG4gICAgICovXHJcbiAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ3VwZGF0ZS56Zi5tYWdlbGxhbicsIFt0aGlzLiRhY3RpdmVdKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlc3Ryb3lzIGFuIGluc3RhbmNlIG9mIE1hZ2VsbGFuIGFuZCByZXNldHMgdGhlIHVybCBvZiB0aGUgd2luZG93LlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqL1xyXG4gIGRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50Lm9mZignLnpmLnRyaWdnZXIgLnpmLm1hZ2VsbGFuJylcclxuICAgICAgICAuZmluZChgLiR7dGhpcy5vcHRpb25zLmFjdGl2ZUNsYXNzfWApLnJlbW92ZUNsYXNzKHRoaXMub3B0aW9ucy5hY3RpdmVDbGFzcyk7XHJcblxyXG4gICAgaWYodGhpcy5vcHRpb25zLmRlZXBMaW5raW5nKXtcclxuICAgICAgdmFyIGhhc2ggPSB0aGlzLiRhY3RpdmVbMF0uZ2V0QXR0cmlidXRlKCdocmVmJyk7XHJcbiAgICAgIHdpbmRvdy5sb2NhdGlvbi5oYXNoLnJlcGxhY2UoaGFzaCwgJycpO1xyXG4gICAgfVxyXG5cclxuICAgIEZvdW5kYXRpb24udW5yZWdpc3RlclBsdWdpbih0aGlzKTtcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBEZWZhdWx0IHNldHRpbmdzIGZvciBwbHVnaW5cclxuICovXHJcbk1hZ2VsbGFuLmRlZmF1bHRzID0ge1xyXG4gIC8qKlxyXG4gICAqIEFtb3VudCBvZiB0aW1lLCBpbiBtcywgdGhlIGFuaW1hdGVkIHNjcm9sbGluZyBzaG91bGQgdGFrZSBiZXR3ZWVuIGxvY2F0aW9ucy5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgNTAwXHJcbiAgICovXHJcbiAgYW5pbWF0aW9uRHVyYXRpb246IDUwMCxcclxuICAvKipcclxuICAgKiBBbmltYXRpb24gc3R5bGUgdG8gdXNlIHdoZW4gc2Nyb2xsaW5nIGJldHdlZW4gbG9jYXRpb25zLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAnZWFzZS1pbi1vdXQnXHJcbiAgICovXHJcbiAgYW5pbWF0aW9uRWFzaW5nOiAnbGluZWFyJyxcclxuICAvKipcclxuICAgKiBOdW1iZXIgb2YgcGl4ZWxzIHRvIHVzZSBhcyBhIG1hcmtlciBmb3IgbG9jYXRpb24gY2hhbmdlcy5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgNTBcclxuICAgKi9cclxuICB0aHJlc2hvbGQ6IDUwLFxyXG4gIC8qKlxyXG4gICAqIENsYXNzIGFwcGxpZWQgdG8gdGhlIGFjdGl2ZSBsb2NhdGlvbnMgbGluayBvbiB0aGUgbWFnZWxsYW4gY29udGFpbmVyLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAnYWN0aXZlJ1xyXG4gICAqL1xyXG4gIGFjdGl2ZUNsYXNzOiAnYWN0aXZlJyxcclxuICAvKipcclxuICAgKiBBbGxvd3MgdGhlIHNjcmlwdCB0byBtYW5pcHVsYXRlIHRoZSB1cmwgb2YgdGhlIGN1cnJlbnQgcGFnZSwgYW5kIGlmIHN1cHBvcnRlZCwgYWx0ZXIgdGhlIGhpc3RvcnkuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIHRydWVcclxuICAgKi9cclxuICBkZWVwTGlua2luZzogZmFsc2UsXHJcbiAgLyoqXHJcbiAgICogTnVtYmVyIG9mIHBpeGVscyB0byBvZmZzZXQgdGhlIHNjcm9sbCBvZiB0aGUgcGFnZSBvbiBpdGVtIGNsaWNrIGlmIHVzaW5nIGEgc3RpY2t5IG5hdiBiYXIuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIDI1XHJcbiAgICovXHJcbiAgYmFyT2Zmc2V0OiAwXHJcbn1cclxuXHJcbi8vIFdpbmRvdyBleHBvcnRzXHJcbkZvdW5kYXRpb24ucGx1Z2luKE1hZ2VsbGFuLCAnTWFnZWxsYW4nKTtcclxuXHJcbn0oalF1ZXJ5KTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxuIWZ1bmN0aW9uKCQpIHtcclxuXHJcbi8qKlxyXG4gKiBPZmZDYW52YXMgbW9kdWxlLlxyXG4gKiBAbW9kdWxlIGZvdW5kYXRpb24ub2ZmY2FudmFzXHJcbiAqIEByZXF1aXJlcyBmb3VuZGF0aW9uLnV0aWwubWVkaWFRdWVyeVxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLnRyaWdnZXJzXHJcbiAqIEByZXF1aXJlcyBmb3VuZGF0aW9uLnV0aWwubW90aW9uXHJcbiAqL1xyXG5cclxuY2xhc3MgT2ZmQ2FudmFzIHtcclxuICAvKipcclxuICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIGFuIG9mZi1jYW52YXMgd3JhcHBlci5cclxuICAgKiBAY2xhc3NcclxuICAgKiBAZmlyZXMgT2ZmQ2FudmFzI2luaXRcclxuICAgKiBAcGFyYW0ge09iamVjdH0gZWxlbWVudCAtIGpRdWVyeSBvYmplY3QgdG8gaW5pdGlhbGl6ZS5cclxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIE92ZXJyaWRlcyB0byB0aGUgZGVmYXVsdCBwbHVnaW4gc2V0dGluZ3MuXHJcbiAgICovXHJcbiAgY29uc3RydWN0b3IoZWxlbWVudCwgb3B0aW9ucykge1xyXG4gICAgdGhpcy4kZWxlbWVudCA9IGVsZW1lbnQ7XHJcbiAgICB0aGlzLm9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgT2ZmQ2FudmFzLmRlZmF1bHRzLCB0aGlzLiRlbGVtZW50LmRhdGEoKSwgb3B0aW9ucyk7XHJcbiAgICB0aGlzLiRsYXN0VHJpZ2dlciA9ICQoKTtcclxuICAgIHRoaXMuJHRyaWdnZXJzID0gJCgpO1xyXG5cclxuICAgIHRoaXMuX2luaXQoKTtcclxuICAgIHRoaXMuX2V2ZW50cygpO1xyXG5cclxuICAgIEZvdW5kYXRpb24ucmVnaXN0ZXJQbHVnaW4odGhpcywgJ09mZkNhbnZhcycpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW5pdGlhbGl6ZXMgdGhlIG9mZi1jYW52YXMgd3JhcHBlciBieSBhZGRpbmcgdGhlIGV4aXQgb3ZlcmxheSAoaWYgbmVlZGVkKS5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9pbml0KCkge1xyXG4gICAgdmFyIGlkID0gdGhpcy4kZWxlbWVudC5hdHRyKCdpZCcpO1xyXG5cclxuICAgIHRoaXMuJGVsZW1lbnQuYXR0cignYXJpYS1oaWRkZW4nLCAndHJ1ZScpO1xyXG5cclxuICAgIC8vIEZpbmQgdHJpZ2dlcnMgdGhhdCBhZmZlY3QgdGhpcyBlbGVtZW50IGFuZCBhZGQgYXJpYS1leHBhbmRlZCB0byB0aGVtXHJcbiAgICB0aGlzLiR0cmlnZ2VycyA9ICQoZG9jdW1lbnQpXHJcbiAgICAgIC5maW5kKCdbZGF0YS1vcGVuPVwiJytpZCsnXCJdLCBbZGF0YS1jbG9zZT1cIicraWQrJ1wiXSwgW2RhdGEtdG9nZ2xlPVwiJytpZCsnXCJdJylcclxuICAgICAgLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAnZmFsc2UnKVxyXG4gICAgICAuYXR0cignYXJpYS1jb250cm9scycsIGlkKTtcclxuXHJcbiAgICAvLyBBZGQgYSBjbG9zZSB0cmlnZ2VyIG92ZXIgdGhlIGJvZHkgaWYgbmVjZXNzYXJ5XHJcbiAgICBpZiAodGhpcy5vcHRpb25zLmNsb3NlT25DbGljaykge1xyXG4gICAgICBpZiAoJCgnLmpzLW9mZi1jYW52YXMtZXhpdCcpLmxlbmd0aCkge1xyXG4gICAgICAgIHRoaXMuJGV4aXRlciA9ICQoJy5qcy1vZmYtY2FudmFzLWV4aXQnKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB2YXIgZXhpdGVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICAgICAgZXhpdGVyLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnanMtb2ZmLWNhbnZhcy1leGl0Jyk7XHJcbiAgICAgICAgJCgnW2RhdGEtb2ZmLWNhbnZhcy1jb250ZW50XScpLmFwcGVuZChleGl0ZXIpO1xyXG5cclxuICAgICAgICB0aGlzLiRleGl0ZXIgPSAkKGV4aXRlcik7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLm9wdGlvbnMuaXNSZXZlYWxlZCA9IHRoaXMub3B0aW9ucy5pc1JldmVhbGVkIHx8IG5ldyBSZWdFeHAodGhpcy5vcHRpb25zLnJldmVhbENsYXNzLCAnZycpLnRlc3QodGhpcy4kZWxlbWVudFswXS5jbGFzc05hbWUpO1xyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuaXNSZXZlYWxlZCkge1xyXG4gICAgICB0aGlzLm9wdGlvbnMucmV2ZWFsT24gPSB0aGlzLm9wdGlvbnMucmV2ZWFsT24gfHwgdGhpcy4kZWxlbWVudFswXS5jbGFzc05hbWUubWF0Y2goLyhyZXZlYWwtZm9yLW1lZGl1bXxyZXZlYWwtZm9yLWxhcmdlKS9nKVswXS5zcGxpdCgnLScpWzJdO1xyXG4gICAgICB0aGlzLl9zZXRNUUNoZWNrZXIoKTtcclxuICAgIH1cclxuICAgIGlmICghdGhpcy5vcHRpb25zLnRyYW5zaXRpb25UaW1lKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy50cmFuc2l0aW9uVGltZSA9IHBhcnNlRmxvYXQod2luZG93LmdldENvbXB1dGVkU3R5bGUoJCgnW2RhdGEtb2ZmLWNhbnZhcy13cmFwcGVyXScpWzBdKS50cmFuc2l0aW9uRHVyYXRpb24pICogMTAwMDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZHMgZXZlbnQgaGFuZGxlcnMgdG8gdGhlIG9mZi1jYW52YXMgd3JhcHBlciBhbmQgdGhlIGV4aXQgb3ZlcmxheS5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9ldmVudHMoKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50Lm9mZignLnpmLnRyaWdnZXIgLnpmLm9mZmNhbnZhcycpLm9uKHtcclxuICAgICAgJ29wZW4uemYudHJpZ2dlcic6IHRoaXMub3Blbi5iaW5kKHRoaXMpLFxyXG4gICAgICAnY2xvc2UuemYudHJpZ2dlcic6IHRoaXMuY2xvc2UuYmluZCh0aGlzKSxcclxuICAgICAgJ3RvZ2dsZS56Zi50cmlnZ2VyJzogdGhpcy50b2dnbGUuYmluZCh0aGlzKSxcclxuICAgICAgJ2tleWRvd24uemYub2ZmY2FudmFzJzogdGhpcy5faGFuZGxlS2V5Ym9hcmQuYmluZCh0aGlzKVxyXG4gICAgfSk7XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5jbG9zZU9uQ2xpY2sgJiYgdGhpcy4kZXhpdGVyLmxlbmd0aCkge1xyXG4gICAgICB0aGlzLiRleGl0ZXIub24oeydjbGljay56Zi5vZmZjYW52YXMnOiB0aGlzLmNsb3NlLmJpbmQodGhpcyl9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFwcGxpZXMgZXZlbnQgbGlzdGVuZXIgZm9yIGVsZW1lbnRzIHRoYXQgd2lsbCByZXZlYWwgYXQgY2VydGFpbiBicmVha3BvaW50cy5cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9zZXRNUUNoZWNrZXIoKSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG5cclxuICAgICQod2luZG93KS5vbignY2hhbmdlZC56Zi5tZWRpYXF1ZXJ5JywgZnVuY3Rpb24oKSB7XHJcbiAgICAgIGlmIChGb3VuZGF0aW9uLk1lZGlhUXVlcnkuYXRMZWFzdChfdGhpcy5vcHRpb25zLnJldmVhbE9uKSkge1xyXG4gICAgICAgIF90aGlzLnJldmVhbCh0cnVlKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBfdGhpcy5yZXZlYWwoZmFsc2UpO1xyXG4gICAgICB9XHJcbiAgICB9KS5vbmUoJ2xvYWQuemYub2ZmY2FudmFzJywgZnVuY3Rpb24oKSB7XHJcbiAgICAgIGlmIChGb3VuZGF0aW9uLk1lZGlhUXVlcnkuYXRMZWFzdChfdGhpcy5vcHRpb25zLnJldmVhbE9uKSkge1xyXG4gICAgICAgIF90aGlzLnJldmVhbCh0cnVlKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBIYW5kbGVzIHRoZSByZXZlYWxpbmcvaGlkaW5nIHRoZSBvZmYtY2FudmFzIGF0IGJyZWFrcG9pbnRzLCBub3QgdGhlIHNhbWUgYXMgb3Blbi5cclxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzUmV2ZWFsZWQgLSB0cnVlIGlmIGVsZW1lbnQgc2hvdWxkIGJlIHJldmVhbGVkLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqL1xyXG4gIHJldmVhbChpc1JldmVhbGVkKSB7XHJcbiAgICB2YXIgJGNsb3NlciA9IHRoaXMuJGVsZW1lbnQuZmluZCgnW2RhdGEtY2xvc2VdJyk7XHJcbiAgICBpZiAoaXNSZXZlYWxlZCkge1xyXG4gICAgICB0aGlzLmNsb3NlKCk7XHJcbiAgICAgIHRoaXMuaXNSZXZlYWxlZCA9IHRydWU7XHJcbiAgICAgIC8vIGlmICghdGhpcy5vcHRpb25zLmZvcmNlVG9wKSB7XHJcbiAgICAgIC8vICAgdmFyIHNjcm9sbFBvcyA9IHBhcnNlSW50KHdpbmRvdy5wYWdlWU9mZnNldCk7XHJcbiAgICAgIC8vICAgdGhpcy4kZWxlbWVudFswXS5zdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlKDAsJyArIHNjcm9sbFBvcyArICdweCknO1xyXG4gICAgICAvLyB9XHJcbiAgICAgIC8vIGlmICh0aGlzLm9wdGlvbnMuaXNTdGlja3kpIHsgdGhpcy5fc3RpY2soKTsgfVxyXG4gICAgICB0aGlzLiRlbGVtZW50Lm9mZignb3Blbi56Zi50cmlnZ2VyIHRvZ2dsZS56Zi50cmlnZ2VyJyk7XHJcbiAgICAgIGlmICgkY2xvc2VyLmxlbmd0aCkgeyAkY2xvc2VyLmhpZGUoKTsgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5pc1JldmVhbGVkID0gZmFsc2U7XHJcbiAgICAgIC8vIGlmICh0aGlzLm9wdGlvbnMuaXNTdGlja3kgfHwgIXRoaXMub3B0aW9ucy5mb3JjZVRvcCkge1xyXG4gICAgICAvLyAgIHRoaXMuJGVsZW1lbnRbMF0uc3R5bGUudHJhbnNmb3JtID0gJyc7XHJcbiAgICAgIC8vICAgJCh3aW5kb3cpLm9mZignc2Nyb2xsLnpmLm9mZmNhbnZhcycpO1xyXG4gICAgICAvLyB9XHJcbiAgICAgIHRoaXMuJGVsZW1lbnQub24oe1xyXG4gICAgICAgICdvcGVuLnpmLnRyaWdnZXInOiB0aGlzLm9wZW4uYmluZCh0aGlzKSxcclxuICAgICAgICAndG9nZ2xlLnpmLnRyaWdnZXInOiB0aGlzLnRvZ2dsZS5iaW5kKHRoaXMpXHJcbiAgICAgIH0pO1xyXG4gICAgICBpZiAoJGNsb3Nlci5sZW5ndGgpIHtcclxuICAgICAgICAkY2xvc2VyLnNob3coKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogT3BlbnMgdGhlIG9mZi1jYW52YXMgbWVudS5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcGFyYW0ge09iamVjdH0gZXZlbnQgLSBFdmVudCBvYmplY3QgcGFzc2VkIGZyb20gbGlzdGVuZXIuXHJcbiAgICogQHBhcmFtIHtqUXVlcnl9IHRyaWdnZXIgLSBlbGVtZW50IHRoYXQgdHJpZ2dlcmVkIHRoZSBvZmYtY2FudmFzIHRvIG9wZW4uXHJcbiAgICogQGZpcmVzIE9mZkNhbnZhcyNvcGVuZWRcclxuICAgKi9cclxuICBvcGVuKGV2ZW50LCB0cmlnZ2VyKSB7XHJcbiAgICBpZiAodGhpcy4kZWxlbWVudC5oYXNDbGFzcygnaXMtb3BlbicpIHx8IHRoaXMuaXNSZXZlYWxlZCkgeyByZXR1cm47IH1cclxuICAgIHZhciBfdGhpcyA9IHRoaXMsXHJcbiAgICAgICAgJGJvZHkgPSAkKGRvY3VtZW50LmJvZHkpO1xyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuZm9yY2VUb3ApIHtcclxuICAgICAgJCgnYm9keScpLnNjcm9sbFRvcCgwKTtcclxuICAgIH1cclxuICAgIC8vIHdpbmRvdy5wYWdlWU9mZnNldCA9IDA7XHJcblxyXG4gICAgLy8gaWYgKCF0aGlzLm9wdGlvbnMuZm9yY2VUb3ApIHtcclxuICAgIC8vICAgdmFyIHNjcm9sbFBvcyA9IHBhcnNlSW50KHdpbmRvdy5wYWdlWU9mZnNldCk7XHJcbiAgICAvLyAgIHRoaXMuJGVsZW1lbnRbMF0uc3R5bGUudHJhbnNmb3JtID0gJ3RyYW5zbGF0ZSgwLCcgKyBzY3JvbGxQb3MgKyAncHgpJztcclxuICAgIC8vICAgaWYgKHRoaXMuJGV4aXRlci5sZW5ndGgpIHtcclxuICAgIC8vICAgICB0aGlzLiRleGl0ZXJbMF0uc3R5bGUudHJhbnNmb3JtID0gJ3RyYW5zbGF0ZSgwLCcgKyBzY3JvbGxQb3MgKyAncHgpJztcclxuICAgIC8vICAgfVxyXG4gICAgLy8gfVxyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlcyB3aGVuIHRoZSBvZmYtY2FudmFzIG1lbnUgb3BlbnMuXHJcbiAgICAgKiBAZXZlbnQgT2ZmQ2FudmFzI29wZW5lZFxyXG4gICAgICovXHJcbiAgICBGb3VuZGF0aW9uLk1vdmUodGhpcy5vcHRpb25zLnRyYW5zaXRpb25UaW1lLCB0aGlzLiRlbGVtZW50LCBmdW5jdGlvbigpIHtcclxuICAgICAgJCgnW2RhdGEtb2ZmLWNhbnZhcy13cmFwcGVyXScpLmFkZENsYXNzKCdpcy1vZmYtY2FudmFzLW9wZW4gaXMtb3Blbi0nKyBfdGhpcy5vcHRpb25zLnBvc2l0aW9uKTtcclxuXHJcbiAgICAgIF90aGlzLiRlbGVtZW50XHJcbiAgICAgICAgLmFkZENsYXNzKCdpcy1vcGVuJylcclxuXHJcbiAgICAgIC8vIGlmIChfdGhpcy5vcHRpb25zLmlzU3RpY2t5KSB7XHJcbiAgICAgIC8vICAgX3RoaXMuX3N0aWNrKCk7XHJcbiAgICAgIC8vIH1cclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuJHRyaWdnZXJzLmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCAndHJ1ZScpO1xyXG4gICAgdGhpcy4kZWxlbWVudC5hdHRyKCdhcmlhLWhpZGRlbicsICdmYWxzZScpXHJcbiAgICAgICAgLnRyaWdnZXIoJ29wZW5lZC56Zi5vZmZjYW52YXMnKTtcclxuXHJcbiAgICBpZiAodGhpcy5vcHRpb25zLmNsb3NlT25DbGljaykge1xyXG4gICAgICB0aGlzLiRleGl0ZXIuYWRkQ2xhc3MoJ2lzLXZpc2libGUnKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodHJpZ2dlcikge1xyXG4gICAgICB0aGlzLiRsYXN0VHJpZ2dlciA9IHRyaWdnZXI7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5hdXRvRm9jdXMpIHtcclxuICAgICAgdGhpcy4kZWxlbWVudC5vbmUoRm91bmRhdGlvbi50cmFuc2l0aW9uZW5kKHRoaXMuJGVsZW1lbnQpLCBmdW5jdGlvbigpIHtcclxuICAgICAgICBfdGhpcy4kZWxlbWVudC5maW5kKCdhLCBidXR0b24nKS5lcSgwKS5mb2N1cygpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5vcHRpb25zLnRyYXBGb2N1cykge1xyXG4gICAgICAkKCdbZGF0YS1vZmYtY2FudmFzLWNvbnRlbnRdJykuYXR0cigndGFiaW5kZXgnLCAnLTEnKTtcclxuICAgICAgdGhpcy5fdHJhcEZvY3VzKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUcmFwcyBmb2N1cyB3aXRoaW4gdGhlIG9mZmNhbnZhcyBvbiBvcGVuLlxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX3RyYXBGb2N1cygpIHtcclxuICAgIHZhciBmb2N1c2FibGUgPSBGb3VuZGF0aW9uLktleWJvYXJkLmZpbmRGb2N1c2FibGUodGhpcy4kZWxlbWVudCksXHJcbiAgICAgICAgZmlyc3QgPSBmb2N1c2FibGUuZXEoMCksXHJcbiAgICAgICAgbGFzdCA9IGZvY3VzYWJsZS5lcSgtMSk7XHJcblxyXG4gICAgZm9jdXNhYmxlLm9mZignLnpmLm9mZmNhbnZhcycpLm9uKCdrZXlkb3duLnpmLm9mZmNhbnZhcycsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgaWYgKGUud2hpY2ggPT09IDkgfHwgZS5rZXljb2RlID09PSA5KSB7XHJcbiAgICAgICAgaWYgKGUudGFyZ2V0ID09PSBsYXN0WzBdICYmICFlLnNoaWZ0S2V5KSB7XHJcbiAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICBmaXJzdC5mb2N1cygpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZS50YXJnZXQgPT09IGZpcnN0WzBdICYmIGUuc2hpZnRLZXkpIHtcclxuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgIGxhc3QuZm9jdXMoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQWxsb3dzIHRoZSBvZmZjYW52YXMgdG8gYXBwZWFyIHN0aWNreSB1dGlsaXppbmcgdHJhbnNsYXRlIHByb3BlcnRpZXMuXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICAvLyBPZmZDYW52YXMucHJvdG90eXBlLl9zdGljayA9IGZ1bmN0aW9uKCkge1xyXG4gIC8vICAgdmFyIGVsU3R5bGUgPSB0aGlzLiRlbGVtZW50WzBdLnN0eWxlO1xyXG4gIC8vXHJcbiAgLy8gICBpZiAodGhpcy5vcHRpb25zLmNsb3NlT25DbGljaykge1xyXG4gIC8vICAgICB2YXIgZXhpdFN0eWxlID0gdGhpcy4kZXhpdGVyWzBdLnN0eWxlO1xyXG4gIC8vICAgfVxyXG4gIC8vXHJcbiAgLy8gICAkKHdpbmRvdykub24oJ3Njcm9sbC56Zi5vZmZjYW52YXMnLCBmdW5jdGlvbihlKSB7XHJcbiAgLy8gICAgIGNvbnNvbGUubG9nKGUpO1xyXG4gIC8vICAgICB2YXIgcGFnZVkgPSB3aW5kb3cucGFnZVlPZmZzZXQ7XHJcbiAgLy8gICAgIGVsU3R5bGUudHJhbnNmb3JtID0gJ3RyYW5zbGF0ZSgwLCcgKyBwYWdlWSArICdweCknO1xyXG4gIC8vICAgICBpZiAoZXhpdFN0eWxlICE9PSB1bmRlZmluZWQpIHsgZXhpdFN0eWxlLnRyYW5zZm9ybSA9ICd0cmFuc2xhdGUoMCwnICsgcGFnZVkgKyAncHgpJzsgfVxyXG4gIC8vICAgfSk7XHJcbiAgLy8gICAvLyB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ3N0dWNrLnpmLm9mZmNhbnZhcycpO1xyXG4gIC8vIH07XHJcbiAgLyoqXHJcbiAgICogQ2xvc2VzIHRoZSBvZmYtY2FudmFzIG1lbnUuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2IgLSBvcHRpb25hbCBjYiB0byBmaXJlIGFmdGVyIGNsb3N1cmUuXHJcbiAgICogQGZpcmVzIE9mZkNhbnZhcyNjbG9zZWRcclxuICAgKi9cclxuICBjbG9zZShjYikge1xyXG4gICAgaWYgKCF0aGlzLiRlbGVtZW50Lmhhc0NsYXNzKCdpcy1vcGVuJykgfHwgdGhpcy5pc1JldmVhbGVkKSB7IHJldHVybjsgfVxyXG5cclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcblxyXG4gICAgLy8gIEZvdW5kYXRpb24uTW92ZSh0aGlzLm9wdGlvbnMudHJhbnNpdGlvblRpbWUsIHRoaXMuJGVsZW1lbnQsIGZ1bmN0aW9uKCkge1xyXG4gICAgJCgnW2RhdGEtb2ZmLWNhbnZhcy13cmFwcGVyXScpLnJlbW92ZUNsYXNzKGBpcy1vZmYtY2FudmFzLW9wZW4gaXMtb3Blbi0ke190aGlzLm9wdGlvbnMucG9zaXRpb259YCk7XHJcbiAgICBfdGhpcy4kZWxlbWVudC5yZW1vdmVDbGFzcygnaXMtb3BlbicpO1xyXG4gICAgICAvLyBGb3VuZGF0aW9uLl9yZWZsb3coKTtcclxuICAgIC8vIH0pO1xyXG4gICAgdGhpcy4kZWxlbWVudC5hdHRyKCdhcmlhLWhpZGRlbicsICd0cnVlJylcclxuICAgICAgLyoqXHJcbiAgICAgICAqIEZpcmVzIHdoZW4gdGhlIG9mZi1jYW52YXMgbWVudSBvcGVucy5cclxuICAgICAgICogQGV2ZW50IE9mZkNhbnZhcyNjbG9zZWRcclxuICAgICAgICovXHJcbiAgICAgICAgLnRyaWdnZXIoJ2Nsb3NlZC56Zi5vZmZjYW52YXMnKTtcclxuICAgIC8vIGlmIChfdGhpcy5vcHRpb25zLmlzU3RpY2t5IHx8ICFfdGhpcy5vcHRpb25zLmZvcmNlVG9wKSB7XHJcbiAgICAvLyAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcbiAgICAvLyAgICAgX3RoaXMuJGVsZW1lbnRbMF0uc3R5bGUudHJhbnNmb3JtID0gJyc7XHJcbiAgICAvLyAgICAgJCh3aW5kb3cpLm9mZignc2Nyb2xsLnpmLm9mZmNhbnZhcycpO1xyXG4gICAgLy8gICB9LCB0aGlzLm9wdGlvbnMudHJhbnNpdGlvblRpbWUpO1xyXG4gICAgLy8gfVxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5jbG9zZU9uQ2xpY2spIHtcclxuICAgICAgdGhpcy4kZXhpdGVyLnJlbW92ZUNsYXNzKCdpcy12aXNpYmxlJyk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy4kdHJpZ2dlcnMuYXR0cignYXJpYS1leHBhbmRlZCcsICdmYWxzZScpO1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy50cmFwRm9jdXMpIHtcclxuICAgICAgJCgnW2RhdGEtb2ZmLWNhbnZhcy1jb250ZW50XScpLnJlbW92ZUF0dHIoJ3RhYmluZGV4Jyk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBUb2dnbGVzIHRoZSBvZmYtY2FudmFzIG1lbnUgb3BlbiBvciBjbG9zZWQuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IGV2ZW50IC0gRXZlbnQgb2JqZWN0IHBhc3NlZCBmcm9tIGxpc3RlbmVyLlxyXG4gICAqIEBwYXJhbSB7alF1ZXJ5fSB0cmlnZ2VyIC0gZWxlbWVudCB0aGF0IHRyaWdnZXJlZCB0aGUgb2ZmLWNhbnZhcyB0byBvcGVuLlxyXG4gICAqL1xyXG4gIHRvZ2dsZShldmVudCwgdHJpZ2dlcikge1xyXG4gICAgaWYgKHRoaXMuJGVsZW1lbnQuaGFzQ2xhc3MoJ2lzLW9wZW4nKSkge1xyXG4gICAgICB0aGlzLmNsb3NlKGV2ZW50LCB0cmlnZ2VyKTtcclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICB0aGlzLm9wZW4oZXZlbnQsIHRyaWdnZXIpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlcyBrZXlib2FyZCBpbnB1dCB3aGVuIGRldGVjdGVkLiBXaGVuIHRoZSBlc2NhcGUga2V5IGlzIHByZXNzZWQsIHRoZSBvZmYtY2FudmFzIG1lbnUgY2xvc2VzLCBhbmQgZm9jdXMgaXMgcmVzdG9yZWQgdG8gdGhlIGVsZW1lbnQgdGhhdCBvcGVuZWQgdGhlIG1lbnUuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfaGFuZGxlS2V5Ym9hcmQoZXZlbnQpIHtcclxuICAgIGlmIChldmVudC53aGljaCAhPT0gMjcpIHJldHVybjtcclxuXHJcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICB0aGlzLmNsb3NlKCk7XHJcbiAgICB0aGlzLiRsYXN0VHJpZ2dlci5mb2N1cygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGVzdHJveXMgdGhlIG9mZmNhbnZhcyBwbHVnaW4uXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICovXHJcbiAgZGVzdHJveSgpIHtcclxuICAgIHRoaXMuY2xvc2UoKTtcclxuICAgIHRoaXMuJGVsZW1lbnQub2ZmKCcuemYudHJpZ2dlciAuemYub2ZmY2FudmFzJyk7XHJcbiAgICB0aGlzLiRleGl0ZXIub2ZmKCcuemYub2ZmY2FudmFzJyk7XHJcblxyXG4gICAgRm91bmRhdGlvbi51bnJlZ2lzdGVyUGx1Z2luKHRoaXMpO1xyXG4gIH1cclxufVxyXG5cclxuT2ZmQ2FudmFzLmRlZmF1bHRzID0ge1xyXG4gIC8qKlxyXG4gICAqIEFsbG93IHRoZSB1c2VyIHRvIGNsaWNrIG91dHNpZGUgb2YgdGhlIG1lbnUgdG8gY2xvc2UgaXQuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIHRydWVcclxuICAgKi9cclxuICBjbG9zZU9uQ2xpY2s6IHRydWUsXHJcblxyXG4gIC8qKlxyXG4gICAqIEFtb3VudCBvZiB0aW1lIGluIG1zIHRoZSBvcGVuIGFuZCBjbG9zZSB0cmFuc2l0aW9uIHJlcXVpcmVzLiBJZiBub25lIHNlbGVjdGVkLCBwdWxscyBmcm9tIGJvZHkgc3R5bGUuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIDUwMFxyXG4gICAqL1xyXG4gIHRyYW5zaXRpb25UaW1lOiAwLFxyXG5cclxuICAvKipcclxuICAgKiBEaXJlY3Rpb24gdGhlIG9mZmNhbnZhcyBvcGVucyBmcm9tLiBEZXRlcm1pbmVzIGNsYXNzIGFwcGxpZWQgdG8gYm9keS5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgbGVmdFxyXG4gICAqL1xyXG4gIHBvc2l0aW9uOiAnbGVmdCcsXHJcblxyXG4gIC8qKlxyXG4gICAqIEZvcmNlIHRoZSBwYWdlIHRvIHNjcm9sbCB0byB0b3Agb24gb3Blbi5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgdHJ1ZVxyXG4gICAqL1xyXG4gIGZvcmNlVG9wOiB0cnVlLFxyXG5cclxuICAvKipcclxuICAgKiBBbGxvdyB0aGUgb2ZmY2FudmFzIHRvIHJlbWFpbiBvcGVuIGZvciBjZXJ0YWluIGJyZWFrcG9pbnRzLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSBmYWxzZVxyXG4gICAqL1xyXG4gIGlzUmV2ZWFsZWQ6IGZhbHNlLFxyXG5cclxuICAvKipcclxuICAgKiBCcmVha3BvaW50IGF0IHdoaWNoIHRvIHJldmVhbC4gSlMgd2lsbCB1c2UgYSBSZWdFeHAgdG8gdGFyZ2V0IHN0YW5kYXJkIGNsYXNzZXMsIGlmIGNoYW5naW5nIGNsYXNzbmFtZXMsIHBhc3MgeW91ciBjbGFzcyB3aXRoIHRoZSBgcmV2ZWFsQ2xhc3NgIG9wdGlvbi5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgcmV2ZWFsLWZvci1sYXJnZVxyXG4gICAqL1xyXG4gIHJldmVhbE9uOiBudWxsLFxyXG5cclxuICAvKipcclxuICAgKiBGb3JjZSBmb2N1cyB0byB0aGUgb2ZmY2FudmFzIG9uIG9wZW4uIElmIHRydWUsIHdpbGwgZm9jdXMgdGhlIG9wZW5pbmcgdHJpZ2dlciBvbiBjbG9zZS5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgdHJ1ZVxyXG4gICAqL1xyXG4gIGF1dG9Gb2N1czogdHJ1ZSxcclxuXHJcbiAgLyoqXHJcbiAgICogQ2xhc3MgdXNlZCB0byBmb3JjZSBhbiBvZmZjYW52YXMgdG8gcmVtYWluIG9wZW4uIEZvdW5kYXRpb24gZGVmYXVsdHMgZm9yIHRoaXMgYXJlIGByZXZlYWwtZm9yLWxhcmdlYCAmIGByZXZlYWwtZm9yLW1lZGl1bWAuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIFRPRE8gaW1wcm92ZSB0aGUgcmVnZXggdGVzdGluZyBmb3IgdGhpcy5cclxuICAgKiBAZXhhbXBsZSByZXZlYWwtZm9yLWxhcmdlXHJcbiAgICovXHJcbiAgcmV2ZWFsQ2xhc3M6ICdyZXZlYWwtZm9yLScsXHJcblxyXG4gIC8qKlxyXG4gICAqIFRyaWdnZXJzIG9wdGlvbmFsIGZvY3VzIHRyYXBwaW5nIHdoZW4gb3BlbmluZyBhbiBvZmZjYW52YXMuIFNldHMgdGFiaW5kZXggb2YgW2RhdGEtb2ZmLWNhbnZhcy1jb250ZW50XSB0byAtMSBmb3IgYWNjZXNzaWJpbGl0eSBwdXJwb3Nlcy5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgdHJ1ZVxyXG4gICAqL1xyXG4gIHRyYXBGb2N1czogZmFsc2VcclxufVxyXG5cclxuLy8gV2luZG93IGV4cG9ydHNcclxuRm91bmRhdGlvbi5wbHVnaW4oT2ZmQ2FudmFzLCAnT2ZmQ2FudmFzJyk7XHJcblxyXG59KGpRdWVyeSk7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbiFmdW5jdGlvbigkKSB7XHJcblxyXG4vKipcclxuICogT3JiaXQgbW9kdWxlLlxyXG4gKiBAbW9kdWxlIGZvdW5kYXRpb24ub3JiaXRcclxuICogQHJlcXVpcmVzIGZvdW5kYXRpb24udXRpbC5rZXlib2FyZFxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLm1vdGlvblxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLnRpbWVyQW5kSW1hZ2VMb2FkZXJcclxuICogQHJlcXVpcmVzIGZvdW5kYXRpb24udXRpbC50b3VjaFxyXG4gKi9cclxuXHJcbmNsYXNzIE9yYml0IHtcclxuICAvKipcclxuICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgYW4gb3JiaXQgY2Fyb3VzZWwuXHJcbiAgKiBAY2xhc3NcclxuICAqIEBwYXJhbSB7alF1ZXJ5fSBlbGVtZW50IC0galF1ZXJ5IG9iamVjdCB0byBtYWtlIGludG8gYW4gT3JiaXQgQ2Fyb3VzZWwuXHJcbiAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIE92ZXJyaWRlcyB0byB0aGUgZGVmYXVsdCBwbHVnaW4gc2V0dGluZ3MuXHJcbiAgKi9cclxuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBvcHRpb25zKXtcclxuICAgIHRoaXMuJGVsZW1lbnQgPSBlbGVtZW50O1xyXG4gICAgdGhpcy5vcHRpb25zID0gJC5leHRlbmQoe30sIE9yYml0LmRlZmF1bHRzLCB0aGlzLiRlbGVtZW50LmRhdGEoKSwgb3B0aW9ucyk7XHJcblxyXG4gICAgdGhpcy5faW5pdCgpO1xyXG5cclxuICAgIEZvdW5kYXRpb24ucmVnaXN0ZXJQbHVnaW4odGhpcywgJ09yYml0Jyk7XHJcbiAgICBGb3VuZGF0aW9uLktleWJvYXJkLnJlZ2lzdGVyKCdPcmJpdCcsIHtcclxuICAgICAgJ2x0cic6IHtcclxuICAgICAgICAnQVJST1dfUklHSFQnOiAnbmV4dCcsXHJcbiAgICAgICAgJ0FSUk9XX0xFRlQnOiAncHJldmlvdXMnXHJcbiAgICAgIH0sXHJcbiAgICAgICdydGwnOiB7XHJcbiAgICAgICAgJ0FSUk9XX0xFRlQnOiAnbmV4dCcsXHJcbiAgICAgICAgJ0FSUk9XX1JJR0hUJzogJ3ByZXZpb3VzJ1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICogSW5pdGlhbGl6ZXMgdGhlIHBsdWdpbiBieSBjcmVhdGluZyBqUXVlcnkgY29sbGVjdGlvbnMsIHNldHRpbmcgYXR0cmlidXRlcywgYW5kIHN0YXJ0aW5nIHRoZSBhbmltYXRpb24uXHJcbiAgKiBAZnVuY3Rpb25cclxuICAqIEBwcml2YXRlXHJcbiAgKi9cclxuICBfaW5pdCgpIHtcclxuICAgIHRoaXMuJHdyYXBwZXIgPSB0aGlzLiRlbGVtZW50LmZpbmQoYC4ke3RoaXMub3B0aW9ucy5jb250YWluZXJDbGFzc31gKTtcclxuICAgIHRoaXMuJHNsaWRlcyA9IHRoaXMuJGVsZW1lbnQuZmluZChgLiR7dGhpcy5vcHRpb25zLnNsaWRlQ2xhc3N9YCk7XHJcbiAgICB2YXIgJGltYWdlcyA9IHRoaXMuJGVsZW1lbnQuZmluZCgnaW1nJyksXHJcbiAgICBpbml0QWN0aXZlID0gdGhpcy4kc2xpZGVzLmZpbHRlcignLmlzLWFjdGl2ZScpO1xyXG5cclxuICAgIGlmICghaW5pdEFjdGl2ZS5sZW5ndGgpIHtcclxuICAgICAgdGhpcy4kc2xpZGVzLmVxKDApLmFkZENsYXNzKCdpcy1hY3RpdmUnKTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMub3B0aW9ucy51c2VNVUkpIHtcclxuICAgICAgdGhpcy4kc2xpZGVzLmFkZENsYXNzKCduby1tb3Rpb251aScpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICgkaW1hZ2VzLmxlbmd0aCkge1xyXG4gICAgICBGb3VuZGF0aW9uLm9uSW1hZ2VzTG9hZGVkKCRpbWFnZXMsIHRoaXMuX3ByZXBhcmVGb3JPcmJpdC5iaW5kKHRoaXMpKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuX3ByZXBhcmVGb3JPcmJpdCgpOy8vaGVoZVxyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuYnVsbGV0cykge1xyXG4gICAgICB0aGlzLl9sb2FkQnVsbGV0cygpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX2V2ZW50cygpO1xyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuYXV0b1BsYXkgJiYgdGhpcy4kc2xpZGVzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgdGhpcy5nZW9TeW5jKCk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5hY2Nlc3NpYmxlKSB7IC8vIGFsbG93IHdyYXBwZXIgdG8gYmUgZm9jdXNhYmxlIHRvIGVuYWJsZSBhcnJvdyBuYXZpZ2F0aW9uXHJcbiAgICAgIHRoaXMuJHdyYXBwZXIuYXR0cigndGFiaW5kZXgnLCAwKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICogQ3JlYXRlcyBhIGpRdWVyeSBjb2xsZWN0aW9uIG9mIGJ1bGxldHMsIGlmIHRoZXkgYXJlIGJlaW5nIHVzZWQuXHJcbiAgKiBAZnVuY3Rpb25cclxuICAqIEBwcml2YXRlXHJcbiAgKi9cclxuICBfbG9hZEJ1bGxldHMoKSB7XHJcbiAgICB0aGlzLiRidWxsZXRzID0gdGhpcy4kZWxlbWVudC5maW5kKGAuJHt0aGlzLm9wdGlvbnMuYm94T2ZCdWxsZXRzfWApLmZpbmQoJ2J1dHRvbicpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgKiBTZXRzIGEgYHRpbWVyYCBvYmplY3Qgb24gdGhlIG9yYml0LCBhbmQgc3RhcnRzIHRoZSBjb3VudGVyIGZvciB0aGUgbmV4dCBzbGlkZS5cclxuICAqIEBmdW5jdGlvblxyXG4gICovXHJcbiAgZ2VvU3luYygpIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICB0aGlzLnRpbWVyID0gbmV3IEZvdW5kYXRpb24uVGltZXIoXHJcbiAgICAgIHRoaXMuJGVsZW1lbnQsXHJcbiAgICAgIHtcclxuICAgICAgICBkdXJhdGlvbjogdGhpcy5vcHRpb25zLnRpbWVyRGVsYXksXHJcbiAgICAgICAgaW5maW5pdGU6IGZhbHNlXHJcbiAgICAgIH0sXHJcbiAgICAgIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIF90aGlzLmNoYW5nZVNsaWRlKHRydWUpO1xyXG4gICAgICB9KTtcclxuICAgIHRoaXMudGltZXIuc3RhcnQoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICogU2V0cyB3cmFwcGVyIGFuZCBzbGlkZSBoZWlnaHRzIGZvciB0aGUgb3JiaXQuXHJcbiAgKiBAZnVuY3Rpb25cclxuICAqIEBwcml2YXRlXHJcbiAgKi9cclxuICBfcHJlcGFyZUZvck9yYml0KCkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgIHRoaXMuX3NldFdyYXBwZXJIZWlnaHQoZnVuY3Rpb24obWF4KXtcclxuICAgICAgX3RoaXMuX3NldFNsaWRlSGVpZ2h0KG1heCk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICogQ2FsdWxhdGVzIHRoZSBoZWlnaHQgb2YgZWFjaCBzbGlkZSBpbiB0aGUgY29sbGVjdGlvbiwgYW5kIHVzZXMgdGhlIHRhbGxlc3Qgb25lIGZvciB0aGUgd3JhcHBlciBoZWlnaHQuXHJcbiAgKiBAZnVuY3Rpb25cclxuICAqIEBwcml2YXRlXHJcbiAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYiAtIGEgY2FsbGJhY2sgZnVuY3Rpb24gdG8gZmlyZSB3aGVuIGNvbXBsZXRlLlxyXG4gICovXHJcbiAgX3NldFdyYXBwZXJIZWlnaHQoY2IpIHsvL3Jld3JpdGUgdGhpcyB0byBgZm9yYCBsb29wXHJcbiAgICB2YXIgbWF4ID0gMCwgdGVtcCwgY291bnRlciA9IDA7XHJcblxyXG4gICAgdGhpcy4kc2xpZGVzLmVhY2goZnVuY3Rpb24oKSB7XHJcbiAgICAgIHRlbXAgPSB0aGlzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodDtcclxuICAgICAgJCh0aGlzKS5hdHRyKCdkYXRhLXNsaWRlJywgY291bnRlcik7XHJcblxyXG4gICAgICBpZiAoY291bnRlcikgey8vaWYgbm90IHRoZSBmaXJzdCBzbGlkZSwgc2V0IGNzcyBwb3NpdGlvbiBhbmQgZGlzcGxheSBwcm9wZXJ0eVxyXG4gICAgICAgICQodGhpcykuY3NzKHsncG9zaXRpb24nOiAncmVsYXRpdmUnLCAnZGlzcGxheSc6ICdub25lJ30pO1xyXG4gICAgICB9XHJcbiAgICAgIG1heCA9IHRlbXAgPiBtYXggPyB0ZW1wIDogbWF4O1xyXG4gICAgICBjb3VudGVyKys7XHJcbiAgICB9KTtcclxuXHJcbiAgICBpZiAoY291bnRlciA9PT0gdGhpcy4kc2xpZGVzLmxlbmd0aCkge1xyXG4gICAgICB0aGlzLiR3cmFwcGVyLmNzcyh7J2hlaWdodCc6IG1heH0pOyAvL29ubHkgY2hhbmdlIHRoZSB3cmFwcGVyIGhlaWdodCBwcm9wZXJ0eSBvbmNlLlxyXG4gICAgICBjYihtYXgpOyAvL2ZpcmUgY2FsbGJhY2sgd2l0aCBtYXggaGVpZ2h0IGRpbWVuc2lvbi5cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICogU2V0cyB0aGUgbWF4LWhlaWdodCBvZiBlYWNoIHNsaWRlLlxyXG4gICogQGZ1bmN0aW9uXHJcbiAgKiBAcHJpdmF0ZVxyXG4gICovXHJcbiAgX3NldFNsaWRlSGVpZ2h0KGhlaWdodCkge1xyXG4gICAgdGhpcy4kc2xpZGVzLmVhY2goZnVuY3Rpb24oKSB7XHJcbiAgICAgICQodGhpcykuY3NzKCdtYXgtaGVpZ2h0JywgaGVpZ2h0KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgKiBBZGRzIGV2ZW50IGxpc3RlbmVycyB0byBiYXNpY2FsbHkgZXZlcnl0aGluZyB3aXRoaW4gdGhlIGVsZW1lbnQuXHJcbiAgKiBAZnVuY3Rpb25cclxuICAqIEBwcml2YXRlXHJcbiAgKi9cclxuICBfZXZlbnRzKCkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuXHJcbiAgICAvLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG4gICAgLy8qKk5vdyB1c2luZyBjdXN0b20gZXZlbnQgLSB0aGFua3MgdG86KipcclxuICAgIC8vKiogICAgICBZb2hhaSBBcmFyYXQgb2YgVG9yb250byAgICAgICoqXHJcbiAgICAvLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKlxyXG4gICAgaWYgKHRoaXMuJHNsaWRlcy5sZW5ndGggPiAxKSB7XHJcblxyXG4gICAgICBpZiAodGhpcy5vcHRpb25zLnN3aXBlKSB7XHJcbiAgICAgICAgdGhpcy4kc2xpZGVzLm9mZignc3dpcGVsZWZ0LnpmLm9yYml0IHN3aXBlcmlnaHQuemYub3JiaXQnKVxyXG4gICAgICAgIC5vbignc3dpcGVsZWZ0LnpmLm9yYml0JywgZnVuY3Rpb24oZSl7XHJcbiAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICBfdGhpcy5jaGFuZ2VTbGlkZSh0cnVlKTtcclxuICAgICAgICB9KS5vbignc3dpcGVyaWdodC56Zi5vcmJpdCcsIGZ1bmN0aW9uKGUpe1xyXG4gICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgX3RoaXMuY2hhbmdlU2xpZGUoZmFsc2UpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9XHJcbiAgICAgIC8vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXHJcblxyXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmF1dG9QbGF5KSB7XHJcbiAgICAgICAgdGhpcy4kc2xpZGVzLm9uKCdjbGljay56Zi5vcmJpdCcsIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgX3RoaXMuJGVsZW1lbnQuZGF0YSgnY2xpY2tlZE9uJywgX3RoaXMuJGVsZW1lbnQuZGF0YSgnY2xpY2tlZE9uJykgPyBmYWxzZSA6IHRydWUpO1xyXG4gICAgICAgICAgX3RoaXMudGltZXJbX3RoaXMuJGVsZW1lbnQuZGF0YSgnY2xpY2tlZE9uJykgPyAncGF1c2UnIDogJ3N0YXJ0J10oKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5wYXVzZU9uSG92ZXIpIHtcclxuICAgICAgICAgIHRoaXMuJGVsZW1lbnQub24oJ21vdXNlZW50ZXIuemYub3JiaXQnLCBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgX3RoaXMudGltZXIucGF1c2UoKTtcclxuICAgICAgICAgIH0pLm9uKCdtb3VzZWxlYXZlLnpmLm9yYml0JywgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIGlmICghX3RoaXMuJGVsZW1lbnQuZGF0YSgnY2xpY2tlZE9uJykpIHtcclxuICAgICAgICAgICAgICBfdGhpcy50aW1lci5zdGFydCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMubmF2QnV0dG9ucykge1xyXG4gICAgICAgIHZhciAkY29udHJvbHMgPSB0aGlzLiRlbGVtZW50LmZpbmQoYC4ke3RoaXMub3B0aW9ucy5uZXh0Q2xhc3N9LCAuJHt0aGlzLm9wdGlvbnMucHJldkNsYXNzfWApO1xyXG4gICAgICAgICRjb250cm9scy5hdHRyKCd0YWJpbmRleCcsIDApXHJcbiAgICAgICAgLy9hbHNvIG5lZWQgdG8gaGFuZGxlIGVudGVyL3JldHVybiBhbmQgc3BhY2ViYXIga2V5IHByZXNzZXNcclxuICAgICAgICAub24oJ2NsaWNrLnpmLm9yYml0IHRvdWNoZW5kLnpmLm9yYml0JywgZnVuY3Rpb24oZSl7XHJcblx0ICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICBfdGhpcy5jaGFuZ2VTbGlkZSgkKHRoaXMpLmhhc0NsYXNzKF90aGlzLm9wdGlvbnMubmV4dENsYXNzKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuYnVsbGV0cykge1xyXG4gICAgICAgIHRoaXMuJGJ1bGxldHMub24oJ2NsaWNrLnpmLm9yYml0IHRvdWNoZW5kLnpmLm9yYml0JywgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICBpZiAoL2lzLWFjdGl2ZS9nLnRlc3QodGhpcy5jbGFzc05hbWUpKSB7IHJldHVybiBmYWxzZTsgfS8vaWYgdGhpcyBpcyBhY3RpdmUsIGtpY2sgb3V0IG9mIGZ1bmN0aW9uLlxyXG4gICAgICAgICAgdmFyIGlkeCA9ICQodGhpcykuZGF0YSgnc2xpZGUnKSxcclxuICAgICAgICAgIGx0ciA9IGlkeCA+IF90aGlzLiRzbGlkZXMuZmlsdGVyKCcuaXMtYWN0aXZlJykuZGF0YSgnc2xpZGUnKSxcclxuICAgICAgICAgICRzbGlkZSA9IF90aGlzLiRzbGlkZXMuZXEoaWR4KTtcclxuXHJcbiAgICAgICAgICBfdGhpcy5jaGFuZ2VTbGlkZShsdHIsICRzbGlkZSwgaWR4KTtcclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy4kd3JhcHBlci5hZGQodGhpcy4kYnVsbGV0cykub24oJ2tleWRvd24uemYub3JiaXQnLCBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgLy8gaGFuZGxlIGtleWJvYXJkIGV2ZW50IHdpdGgga2V5Ym9hcmQgdXRpbFxyXG4gICAgICAgIEZvdW5kYXRpb24uS2V5Ym9hcmQuaGFuZGxlS2V5KGUsICdPcmJpdCcsIHtcclxuICAgICAgICAgIG5leHQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5jaGFuZ2VTbGlkZSh0cnVlKTtcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICBwcmV2aW91czogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIF90aGlzLmNoYW5nZVNsaWRlKGZhbHNlKTtcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICBoYW5kbGVkOiBmdW5jdGlvbigpIHsgLy8gaWYgYnVsbGV0IGlzIGZvY3VzZWQsIG1ha2Ugc3VyZSBmb2N1cyBtb3Zlc1xyXG4gICAgICAgICAgICBpZiAoJChlLnRhcmdldCkuaXMoX3RoaXMuJGJ1bGxldHMpKSB7XHJcbiAgICAgICAgICAgICAgX3RoaXMuJGJ1bGxldHMuZmlsdGVyKCcuaXMtYWN0aXZlJykuZm9jdXMoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICogQ2hhbmdlcyB0aGUgY3VycmVudCBzbGlkZSB0byBhIG5ldyBvbmUuXHJcbiAgKiBAZnVuY3Rpb25cclxuICAqIEBwYXJhbSB7Qm9vbGVhbn0gaXNMVFIgLSBmbGFnIGlmIHRoZSBzbGlkZSBzaG91bGQgbW92ZSBsZWZ0IHRvIHJpZ2h0LlxyXG4gICogQHBhcmFtIHtqUXVlcnl9IGNob3NlblNsaWRlIC0gdGhlIGpRdWVyeSBlbGVtZW50IG9mIHRoZSBzbGlkZSB0byBzaG93IG5leHQsIGlmIG9uZSBpcyBzZWxlY3RlZC5cclxuICAqIEBwYXJhbSB7TnVtYmVyfSBpZHggLSB0aGUgaW5kZXggb2YgdGhlIG5ldyBzbGlkZSBpbiBpdHMgY29sbGVjdGlvbiwgaWYgb25lIGNob3Nlbi5cclxuICAqIEBmaXJlcyBPcmJpdCNzbGlkZWNoYW5nZVxyXG4gICovXHJcbiAgY2hhbmdlU2xpZGUoaXNMVFIsIGNob3NlblNsaWRlLCBpZHgpIHtcclxuICAgIHZhciAkY3VyU2xpZGUgPSB0aGlzLiRzbGlkZXMuZmlsdGVyKCcuaXMtYWN0aXZlJykuZXEoMCk7XHJcblxyXG4gICAgaWYgKC9tdWkvZy50ZXN0KCRjdXJTbGlkZVswXS5jbGFzc05hbWUpKSB7IHJldHVybiBmYWxzZTsgfSAvL2lmIHRoZSBzbGlkZSBpcyBjdXJyZW50bHkgYW5pbWF0aW5nLCBraWNrIG91dCBvZiB0aGUgZnVuY3Rpb25cclxuXHJcbiAgICB2YXIgJGZpcnN0U2xpZGUgPSB0aGlzLiRzbGlkZXMuZmlyc3QoKSxcclxuICAgICRsYXN0U2xpZGUgPSB0aGlzLiRzbGlkZXMubGFzdCgpLFxyXG4gICAgZGlySW4gPSBpc0xUUiA/ICdSaWdodCcgOiAnTGVmdCcsXHJcbiAgICBkaXJPdXQgPSBpc0xUUiA/ICdMZWZ0JyA6ICdSaWdodCcsXHJcbiAgICBfdGhpcyA9IHRoaXMsXHJcbiAgICAkbmV3U2xpZGU7XHJcblxyXG4gICAgaWYgKCFjaG9zZW5TbGlkZSkgeyAvL21vc3Qgb2YgdGhlIHRpbWUsIHRoaXMgd2lsbCBiZSBhdXRvIHBsYXllZCBvciBjbGlja2VkIGZyb20gdGhlIG5hdkJ1dHRvbnMuXHJcbiAgICAgICRuZXdTbGlkZSA9IGlzTFRSID8gLy9pZiB3cmFwcGluZyBlbmFibGVkLCBjaGVjayB0byBzZWUgaWYgdGhlcmUgaXMgYSBgbmV4dGAgb3IgYHByZXZgIHNpYmxpbmcsIGlmIG5vdCwgc2VsZWN0IHRoZSBmaXJzdCBvciBsYXN0IHNsaWRlIHRvIGZpbGwgaW4uIGlmIHdyYXBwaW5nIG5vdCBlbmFibGVkLCBhdHRlbXB0IHRvIHNlbGVjdCBgbmV4dGAgb3IgYHByZXZgLCBpZiB0aGVyZSdzIG5vdGhpbmcgdGhlcmUsIHRoZSBmdW5jdGlvbiB3aWxsIGtpY2sgb3V0IG9uIG5leHQgc3RlcC4gQ1JBWlkgTkVTVEVEIFRFUk5BUklFUyEhISEhXHJcbiAgICAgICh0aGlzLm9wdGlvbnMuaW5maW5pdGVXcmFwID8gJGN1clNsaWRlLm5leHQoYC4ke3RoaXMub3B0aW9ucy5zbGlkZUNsYXNzfWApLmxlbmd0aCA/ICRjdXJTbGlkZS5uZXh0KGAuJHt0aGlzLm9wdGlvbnMuc2xpZGVDbGFzc31gKSA6ICRmaXJzdFNsaWRlIDogJGN1clNsaWRlLm5leHQoYC4ke3RoaXMub3B0aW9ucy5zbGlkZUNsYXNzfWApKS8vcGljayBuZXh0IHNsaWRlIGlmIG1vdmluZyBsZWZ0IHRvIHJpZ2h0XHJcbiAgICAgIDpcclxuICAgICAgKHRoaXMub3B0aW9ucy5pbmZpbml0ZVdyYXAgPyAkY3VyU2xpZGUucHJldihgLiR7dGhpcy5vcHRpb25zLnNsaWRlQ2xhc3N9YCkubGVuZ3RoID8gJGN1clNsaWRlLnByZXYoYC4ke3RoaXMub3B0aW9ucy5zbGlkZUNsYXNzfWApIDogJGxhc3RTbGlkZSA6ICRjdXJTbGlkZS5wcmV2KGAuJHt0aGlzLm9wdGlvbnMuc2xpZGVDbGFzc31gKSk7Ly9waWNrIHByZXYgc2xpZGUgaWYgbW92aW5nIHJpZ2h0IHRvIGxlZnRcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICRuZXdTbGlkZSA9IGNob3NlblNsaWRlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICgkbmV3U2xpZGUubGVuZ3RoKSB7XHJcbiAgICAgIGlmICh0aGlzLm9wdGlvbnMuYnVsbGV0cykge1xyXG4gICAgICAgIGlkeCA9IGlkeCB8fCB0aGlzLiRzbGlkZXMuaW5kZXgoJG5ld1NsaWRlKTsgLy9ncmFiIGluZGV4IHRvIHVwZGF0ZSBidWxsZXRzXHJcbiAgICAgICAgdGhpcy5fdXBkYXRlQnVsbGV0cyhpZHgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAodGhpcy5vcHRpb25zLnVzZU1VSSkge1xyXG4gICAgICAgIEZvdW5kYXRpb24uTW90aW9uLmFuaW1hdGVJbihcclxuICAgICAgICAgICRuZXdTbGlkZS5hZGRDbGFzcygnaXMtYWN0aXZlJykuY3NzKHsncG9zaXRpb24nOiAnYWJzb2x1dGUnLCAndG9wJzogMH0pLFxyXG4gICAgICAgICAgdGhpcy5vcHRpb25zW2BhbmltSW5Gcm9tJHtkaXJJbn1gXSxcclxuICAgICAgICAgIGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICRuZXdTbGlkZS5jc3Moeydwb3NpdGlvbic6ICdyZWxhdGl2ZScsICdkaXNwbGF5JzogJ2Jsb2NrJ30pXHJcbiAgICAgICAgICAgIC5hdHRyKCdhcmlhLWxpdmUnLCAncG9saXRlJyk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIEZvdW5kYXRpb24uTW90aW9uLmFuaW1hdGVPdXQoXHJcbiAgICAgICAgICAkY3VyU2xpZGUucmVtb3ZlQ2xhc3MoJ2lzLWFjdGl2ZScpLFxyXG4gICAgICAgICAgdGhpcy5vcHRpb25zW2BhbmltT3V0VG8ke2Rpck91dH1gXSxcclxuICAgICAgICAgIGZ1bmN0aW9uKCl7XHJcbiAgICAgICAgICAgICRjdXJTbGlkZS5yZW1vdmVBdHRyKCdhcmlhLWxpdmUnKTtcclxuICAgICAgICAgICAgaWYoX3RoaXMub3B0aW9ucy5hdXRvUGxheSAmJiAhX3RoaXMudGltZXIuaXNQYXVzZWQpe1xyXG4gICAgICAgICAgICAgIF90aGlzLnRpbWVyLnJlc3RhcnQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvL2RvIHN0dWZmP1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgJGN1clNsaWRlLnJlbW92ZUNsYXNzKCdpcy1hY3RpdmUgaXMtaW4nKS5yZW1vdmVBdHRyKCdhcmlhLWxpdmUnKS5oaWRlKCk7XHJcbiAgICAgICAgJG5ld1NsaWRlLmFkZENsYXNzKCdpcy1hY3RpdmUgaXMtaW4nKS5hdHRyKCdhcmlhLWxpdmUnLCAncG9saXRlJykuc2hvdygpO1xyXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMuYXV0b1BsYXkgJiYgIXRoaXMudGltZXIuaXNQYXVzZWQpIHtcclxuICAgICAgICAgIHRoaXMudGltZXIucmVzdGFydCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgLyoqXHJcbiAgICAqIFRyaWdnZXJzIHdoZW4gdGhlIHNsaWRlIGhhcyBmaW5pc2hlZCBhbmltYXRpbmcgaW4uXHJcbiAgICAqIEBldmVudCBPcmJpdCNzbGlkZWNoYW5nZVxyXG4gICAgKi9cclxuICAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKCdzbGlkZWNoYW5nZS56Zi5vcmJpdCcsIFskbmV3U2xpZGVdKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICogVXBkYXRlcyB0aGUgYWN0aXZlIHN0YXRlIG9mIHRoZSBidWxsZXRzLCBpZiBkaXNwbGF5ZWQuXHJcbiAgKiBAZnVuY3Rpb25cclxuICAqIEBwcml2YXRlXHJcbiAgKiBAcGFyYW0ge051bWJlcn0gaWR4IC0gdGhlIGluZGV4IG9mIHRoZSBjdXJyZW50IHNsaWRlLlxyXG4gICovXHJcbiAgX3VwZGF0ZUJ1bGxldHMoaWR4KSB7XHJcbiAgICB2YXIgJG9sZEJ1bGxldCA9IHRoaXMuJGVsZW1lbnQuZmluZChgLiR7dGhpcy5vcHRpb25zLmJveE9mQnVsbGV0c31gKVxyXG4gICAgLmZpbmQoJy5pcy1hY3RpdmUnKS5yZW1vdmVDbGFzcygnaXMtYWN0aXZlJykuYmx1cigpLFxyXG4gICAgc3BhbiA9ICRvbGRCdWxsZXQuZmluZCgnc3BhbjpsYXN0JykuZGV0YWNoKCksXHJcbiAgICAkbmV3QnVsbGV0ID0gdGhpcy4kYnVsbGV0cy5lcShpZHgpLmFkZENsYXNzKCdpcy1hY3RpdmUnKS5hcHBlbmQoc3Bhbik7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAqIERlc3Ryb3lzIHRoZSBjYXJvdXNlbCBhbmQgaGlkZXMgdGhlIGVsZW1lbnQuXHJcbiAgKiBAZnVuY3Rpb25cclxuICAqL1xyXG4gIGRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50Lm9mZignLnpmLm9yYml0JykuZmluZCgnKicpLm9mZignLnpmLm9yYml0JykuZW5kKCkuaGlkZSgpO1xyXG4gICAgRm91bmRhdGlvbi51bnJlZ2lzdGVyUGx1Z2luKHRoaXMpO1xyXG4gIH1cclxufVxyXG5cclxuT3JiaXQuZGVmYXVsdHMgPSB7XHJcbiAgLyoqXHJcbiAgKiBUZWxscyB0aGUgSlMgdG8gbG9vayBmb3IgYW5kIGxvYWRCdWxsZXRzLlxyXG4gICogQG9wdGlvblxyXG4gICogQGV4YW1wbGUgdHJ1ZVxyXG4gICovXHJcbiAgYnVsbGV0czogdHJ1ZSxcclxuICAvKipcclxuICAqIFRlbGxzIHRoZSBKUyB0byBhcHBseSBldmVudCBsaXN0ZW5lcnMgdG8gbmF2IGJ1dHRvbnNcclxuICAqIEBvcHRpb25cclxuICAqIEBleGFtcGxlIHRydWVcclxuICAqL1xyXG4gIG5hdkJ1dHRvbnM6IHRydWUsXHJcbiAgLyoqXHJcbiAgKiBtb3Rpb24tdWkgYW5pbWF0aW9uIGNsYXNzIHRvIGFwcGx5XHJcbiAgKiBAb3B0aW9uXHJcbiAgKiBAZXhhbXBsZSAnc2xpZGUtaW4tcmlnaHQnXHJcbiAgKi9cclxuICBhbmltSW5Gcm9tUmlnaHQ6ICdzbGlkZS1pbi1yaWdodCcsXHJcbiAgLyoqXHJcbiAgKiBtb3Rpb24tdWkgYW5pbWF0aW9uIGNsYXNzIHRvIGFwcGx5XHJcbiAgKiBAb3B0aW9uXHJcbiAgKiBAZXhhbXBsZSAnc2xpZGUtb3V0LXJpZ2h0J1xyXG4gICovXHJcbiAgYW5pbU91dFRvUmlnaHQ6ICdzbGlkZS1vdXQtcmlnaHQnLFxyXG4gIC8qKlxyXG4gICogbW90aW9uLXVpIGFuaW1hdGlvbiBjbGFzcyB0byBhcHBseVxyXG4gICogQG9wdGlvblxyXG4gICogQGV4YW1wbGUgJ3NsaWRlLWluLWxlZnQnXHJcbiAgKlxyXG4gICovXHJcbiAgYW5pbUluRnJvbUxlZnQ6ICdzbGlkZS1pbi1sZWZ0JyxcclxuICAvKipcclxuICAqIG1vdGlvbi11aSBhbmltYXRpb24gY2xhc3MgdG8gYXBwbHlcclxuICAqIEBvcHRpb25cclxuICAqIEBleGFtcGxlICdzbGlkZS1vdXQtbGVmdCdcclxuICAqL1xyXG4gIGFuaW1PdXRUb0xlZnQ6ICdzbGlkZS1vdXQtbGVmdCcsXHJcbiAgLyoqXHJcbiAgKiBBbGxvd3MgT3JiaXQgdG8gYXV0b21hdGljYWxseSBhbmltYXRlIG9uIHBhZ2UgbG9hZC5cclxuICAqIEBvcHRpb25cclxuICAqIEBleGFtcGxlIHRydWVcclxuICAqL1xyXG4gIGF1dG9QbGF5OiB0cnVlLFxyXG4gIC8qKlxyXG4gICogQW1vdW50IG9mIHRpbWUsIGluIG1zLCBiZXR3ZWVuIHNsaWRlIHRyYW5zaXRpb25zXHJcbiAgKiBAb3B0aW9uXHJcbiAgKiBAZXhhbXBsZSA1MDAwXHJcbiAgKi9cclxuICB0aW1lckRlbGF5OiA1MDAwLFxyXG4gIC8qKlxyXG4gICogQWxsb3dzIE9yYml0IHRvIGluZmluaXRlbHkgbG9vcCB0aHJvdWdoIHRoZSBzbGlkZXNcclxuICAqIEBvcHRpb25cclxuICAqIEBleGFtcGxlIHRydWVcclxuICAqL1xyXG4gIGluZmluaXRlV3JhcDogdHJ1ZSxcclxuICAvKipcclxuICAqIEFsbG93cyB0aGUgT3JiaXQgc2xpZGVzIHRvIGJpbmQgdG8gc3dpcGUgZXZlbnRzIGZvciBtb2JpbGUsIHJlcXVpcmVzIGFuIGFkZGl0aW9uYWwgdXRpbCBsaWJyYXJ5XHJcbiAgKiBAb3B0aW9uXHJcbiAgKiBAZXhhbXBsZSB0cnVlXHJcbiAgKi9cclxuICBzd2lwZTogdHJ1ZSxcclxuICAvKipcclxuICAqIEFsbG93cyB0aGUgdGltaW5nIGZ1bmN0aW9uIHRvIHBhdXNlIGFuaW1hdGlvbiBvbiBob3Zlci5cclxuICAqIEBvcHRpb25cclxuICAqIEBleGFtcGxlIHRydWVcclxuICAqL1xyXG4gIHBhdXNlT25Ib3ZlcjogdHJ1ZSxcclxuICAvKipcclxuICAqIEFsbG93cyBPcmJpdCB0byBiaW5kIGtleWJvYXJkIGV2ZW50cyB0byB0aGUgc2xpZGVyLCB0byBhbmltYXRlIGZyYW1lcyB3aXRoIGFycm93IGtleXNcclxuICAqIEBvcHRpb25cclxuICAqIEBleGFtcGxlIHRydWVcclxuICAqL1xyXG4gIGFjY2Vzc2libGU6IHRydWUsXHJcbiAgLyoqXHJcbiAgKiBDbGFzcyBhcHBsaWVkIHRvIHRoZSBjb250YWluZXIgb2YgT3JiaXRcclxuICAqIEBvcHRpb25cclxuICAqIEBleGFtcGxlICdvcmJpdC1jb250YWluZXInXHJcbiAgKi9cclxuICBjb250YWluZXJDbGFzczogJ29yYml0LWNvbnRhaW5lcicsXHJcbiAgLyoqXHJcbiAgKiBDbGFzcyBhcHBsaWVkIHRvIGluZGl2aWR1YWwgc2xpZGVzLlxyXG4gICogQG9wdGlvblxyXG4gICogQGV4YW1wbGUgJ29yYml0LXNsaWRlJ1xyXG4gICovXHJcbiAgc2xpZGVDbGFzczogJ29yYml0LXNsaWRlJyxcclxuICAvKipcclxuICAqIENsYXNzIGFwcGxpZWQgdG8gdGhlIGJ1bGxldCBjb250YWluZXIuIFlvdSdyZSB3ZWxjb21lLlxyXG4gICogQG9wdGlvblxyXG4gICogQGV4YW1wbGUgJ29yYml0LWJ1bGxldHMnXHJcbiAgKi9cclxuICBib3hPZkJ1bGxldHM6ICdvcmJpdC1idWxsZXRzJyxcclxuICAvKipcclxuICAqIENsYXNzIGFwcGxpZWQgdG8gdGhlIGBuZXh0YCBuYXZpZ2F0aW9uIGJ1dHRvbi5cclxuICAqIEBvcHRpb25cclxuICAqIEBleGFtcGxlICdvcmJpdC1uZXh0J1xyXG4gICovXHJcbiAgbmV4dENsYXNzOiAnb3JiaXQtbmV4dCcsXHJcbiAgLyoqXHJcbiAgKiBDbGFzcyBhcHBsaWVkIHRvIHRoZSBgcHJldmlvdXNgIG5hdmlnYXRpb24gYnV0dG9uLlxyXG4gICogQG9wdGlvblxyXG4gICogQGV4YW1wbGUgJ29yYml0LXByZXZpb3VzJ1xyXG4gICovXHJcbiAgcHJldkNsYXNzOiAnb3JiaXQtcHJldmlvdXMnLFxyXG4gIC8qKlxyXG4gICogQm9vbGVhbiB0byBmbGFnIHRoZSBqcyB0byB1c2UgbW90aW9uIHVpIGNsYXNzZXMgb3Igbm90LiBEZWZhdWx0IHRvIHRydWUgZm9yIGJhY2t3YXJkcyBjb21wYXRhYmlsaXR5LlxyXG4gICogQG9wdGlvblxyXG4gICogQGV4YW1wbGUgdHJ1ZVxyXG4gICovXHJcbiAgdXNlTVVJOiB0cnVlXHJcbn07XHJcblxyXG4vLyBXaW5kb3cgZXhwb3J0c1xyXG5Gb3VuZGF0aW9uLnBsdWdpbihPcmJpdCwgJ09yYml0Jyk7XHJcblxyXG59KGpRdWVyeSk7XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbiFmdW5jdGlvbigkKSB7XHJcblxyXG4vKipcclxuICogUmVzcG9uc2l2ZU1lbnUgbW9kdWxlLlxyXG4gKiBAbW9kdWxlIGZvdW5kYXRpb24ucmVzcG9uc2l2ZU1lbnVcclxuICogQHJlcXVpcmVzIGZvdW5kYXRpb24udXRpbC50cmlnZ2Vyc1xyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLm1lZGlhUXVlcnlcclxuICogQHJlcXVpcmVzIGZvdW5kYXRpb24udXRpbC5hY2NvcmRpb25NZW51XHJcbiAqIEByZXF1aXJlcyBmb3VuZGF0aW9uLnV0aWwuZHJpbGxkb3duXHJcbiAqIEByZXF1aXJlcyBmb3VuZGF0aW9uLnV0aWwuZHJvcGRvd24tbWVudVxyXG4gKi9cclxuXHJcbmNsYXNzIFJlc3BvbnNpdmVNZW51IHtcclxuICAvKipcclxuICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIGEgcmVzcG9uc2l2ZSBtZW51LlxyXG4gICAqIEBjbGFzc1xyXG4gICAqIEBmaXJlcyBSZXNwb25zaXZlTWVudSNpbml0XHJcbiAgICogQHBhcmFtIHtqUXVlcnl9IGVsZW1lbnQgLSBqUXVlcnkgb2JqZWN0IHRvIG1ha2UgaW50byBhIGRyb3Bkb3duIG1lbnUuXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBPdmVycmlkZXMgdG8gdGhlIGRlZmF1bHQgcGx1Z2luIHNldHRpbmdzLlxyXG4gICAqL1xyXG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQsIG9wdGlvbnMpIHtcclxuICAgIHRoaXMuJGVsZW1lbnQgPSAkKGVsZW1lbnQpO1xyXG4gICAgdGhpcy5ydWxlcyA9IHRoaXMuJGVsZW1lbnQuZGF0YSgncmVzcG9uc2l2ZS1tZW51Jyk7XHJcbiAgICB0aGlzLmN1cnJlbnRNcSA9IG51bGw7XHJcbiAgICB0aGlzLmN1cnJlbnRQbHVnaW4gPSBudWxsO1xyXG5cclxuICAgIHRoaXMuX2luaXQoKTtcclxuICAgIHRoaXMuX2V2ZW50cygpO1xyXG5cclxuICAgIEZvdW5kYXRpb24ucmVnaXN0ZXJQbHVnaW4odGhpcywgJ1Jlc3BvbnNpdmVNZW51Jyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbml0aWFsaXplcyB0aGUgTWVudSBieSBwYXJzaW5nIHRoZSBjbGFzc2VzIGZyb20gdGhlICdkYXRhLVJlc3BvbnNpdmVNZW51JyBhdHRyaWJ1dGUgb24gdGhlIGVsZW1lbnQuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfaW5pdCgpIHtcclxuICAgIC8vIFRoZSBmaXJzdCB0aW1lIGFuIEludGVyY2hhbmdlIHBsdWdpbiBpcyBpbml0aWFsaXplZCwgdGhpcy5ydWxlcyBpcyBjb252ZXJ0ZWQgZnJvbSBhIHN0cmluZyBvZiBcImNsYXNzZXNcIiB0byBhbiBvYmplY3Qgb2YgcnVsZXNcclxuICAgIGlmICh0eXBlb2YgdGhpcy5ydWxlcyA9PT0gJ3N0cmluZycpIHtcclxuICAgICAgbGV0IHJ1bGVzVHJlZSA9IHt9O1xyXG5cclxuICAgICAgLy8gUGFyc2UgcnVsZXMgZnJvbSBcImNsYXNzZXNcIiBwdWxsZWQgZnJvbSBkYXRhIGF0dHJpYnV0ZVxyXG4gICAgICBsZXQgcnVsZXMgPSB0aGlzLnJ1bGVzLnNwbGl0KCcgJyk7XHJcblxyXG4gICAgICAvLyBJdGVyYXRlIHRocm91Z2ggZXZlcnkgcnVsZSBmb3VuZFxyXG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJ1bGVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgbGV0IHJ1bGUgPSBydWxlc1tpXS5zcGxpdCgnLScpO1xyXG4gICAgICAgIGxldCBydWxlU2l6ZSA9IHJ1bGUubGVuZ3RoID4gMSA/IHJ1bGVbMF0gOiAnc21hbGwnO1xyXG4gICAgICAgIGxldCBydWxlUGx1Z2luID0gcnVsZS5sZW5ndGggPiAxID8gcnVsZVsxXSA6IHJ1bGVbMF07XHJcblxyXG4gICAgICAgIGlmIChNZW51UGx1Z2luc1tydWxlUGx1Z2luXSAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgcnVsZXNUcmVlW3J1bGVTaXplXSA9IE1lbnVQbHVnaW5zW3J1bGVQbHVnaW5dO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgdGhpcy5ydWxlcyA9IHJ1bGVzVHJlZTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoISQuaXNFbXB0eU9iamVjdCh0aGlzLnJ1bGVzKSkge1xyXG4gICAgICB0aGlzLl9jaGVja01lZGlhUXVlcmllcygpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW5pdGlhbGl6ZXMgZXZlbnRzIGZvciB0aGUgTWVudS5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9ldmVudHMoKSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG5cclxuICAgICQod2luZG93KS5vbignY2hhbmdlZC56Zi5tZWRpYXF1ZXJ5JywgZnVuY3Rpb24oKSB7XHJcbiAgICAgIF90aGlzLl9jaGVja01lZGlhUXVlcmllcygpO1xyXG4gICAgfSk7XHJcbiAgICAvLyAkKHdpbmRvdykub24oJ3Jlc2l6ZS56Zi5SZXNwb25zaXZlTWVudScsIGZ1bmN0aW9uKCkge1xyXG4gICAgLy8gICBfdGhpcy5fY2hlY2tNZWRpYVF1ZXJpZXMoKTtcclxuICAgIC8vIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQ2hlY2tzIHRoZSBjdXJyZW50IHNjcmVlbiB3aWR0aCBhZ2FpbnN0IGF2YWlsYWJsZSBtZWRpYSBxdWVyaWVzLiBJZiB0aGUgbWVkaWEgcXVlcnkgaGFzIGNoYW5nZWQsIGFuZCB0aGUgcGx1Z2luIG5lZWRlZCBoYXMgY2hhbmdlZCwgdGhlIHBsdWdpbnMgd2lsbCBzd2FwIG91dC5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9jaGVja01lZGlhUXVlcmllcygpIHtcclxuICAgIHZhciBtYXRjaGVkTXEsIF90aGlzID0gdGhpcztcclxuICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBlYWNoIHJ1bGUgYW5kIGZpbmQgdGhlIGxhc3QgbWF0Y2hpbmcgcnVsZVxyXG4gICAgJC5lYWNoKHRoaXMucnVsZXMsIGZ1bmN0aW9uKGtleSkge1xyXG4gICAgICBpZiAoRm91bmRhdGlvbi5NZWRpYVF1ZXJ5LmF0TGVhc3Qoa2V5KSkge1xyXG4gICAgICAgIG1hdGNoZWRNcSA9IGtleTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gTm8gbWF0Y2g/IE5vIGRpY2VcclxuICAgIGlmICghbWF0Y2hlZE1xKSByZXR1cm47XHJcblxyXG4gICAgLy8gUGx1Z2luIGFscmVhZHkgaW5pdGlhbGl6ZWQ/IFdlIGdvb2RcclxuICAgIGlmICh0aGlzLmN1cnJlbnRQbHVnaW4gaW5zdGFuY2VvZiB0aGlzLnJ1bGVzW21hdGNoZWRNcV0ucGx1Z2luKSByZXR1cm47XHJcblxyXG4gICAgLy8gUmVtb3ZlIGV4aXN0aW5nIHBsdWdpbi1zcGVjaWZpYyBDU1MgY2xhc3Nlc1xyXG4gICAgJC5lYWNoKE1lbnVQbHVnaW5zLCBmdW5jdGlvbihrZXksIHZhbHVlKSB7XHJcbiAgICAgIF90aGlzLiRlbGVtZW50LnJlbW92ZUNsYXNzKHZhbHVlLmNzc0NsYXNzKTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIEFkZCB0aGUgQ1NTIGNsYXNzIGZvciB0aGUgbmV3IHBsdWdpblxyXG4gICAgdGhpcy4kZWxlbWVudC5hZGRDbGFzcyh0aGlzLnJ1bGVzW21hdGNoZWRNcV0uY3NzQ2xhc3MpO1xyXG5cclxuICAgIC8vIENyZWF0ZSBhbiBpbnN0YW5jZSBvZiB0aGUgbmV3IHBsdWdpblxyXG4gICAgaWYgKHRoaXMuY3VycmVudFBsdWdpbikgdGhpcy5jdXJyZW50UGx1Z2luLmRlc3Ryb3koKTtcclxuICAgIHRoaXMuY3VycmVudFBsdWdpbiA9IG5ldyB0aGlzLnJ1bGVzW21hdGNoZWRNcV0ucGx1Z2luKHRoaXMuJGVsZW1lbnQsIHt9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlc3Ryb3lzIHRoZSBpbnN0YW5jZSBvZiB0aGUgY3VycmVudCBwbHVnaW4gb24gdGhpcyBlbGVtZW50LCBhcyB3ZWxsIGFzIHRoZSB3aW5kb3cgcmVzaXplIGhhbmRsZXIgdGhhdCBzd2l0Y2hlcyB0aGUgcGx1Z2lucyBvdXQuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICovXHJcbiAgZGVzdHJveSgpIHtcclxuICAgIHRoaXMuY3VycmVudFBsdWdpbi5kZXN0cm95KCk7XHJcbiAgICAkKHdpbmRvdykub2ZmKCcuemYuUmVzcG9uc2l2ZU1lbnUnKTtcclxuICAgIEZvdW5kYXRpb24udW5yZWdpc3RlclBsdWdpbih0aGlzKTtcclxuICB9XHJcbn1cclxuXHJcblJlc3BvbnNpdmVNZW51LmRlZmF1bHRzID0ge307XHJcblxyXG4vLyBUaGUgcGx1Z2luIG1hdGNoZXMgdGhlIHBsdWdpbiBjbGFzc2VzIHdpdGggdGhlc2UgcGx1Z2luIGluc3RhbmNlcy5cclxudmFyIE1lbnVQbHVnaW5zID0ge1xyXG4gIGRyb3Bkb3duOiB7XHJcbiAgICBjc3NDbGFzczogJ2Ryb3Bkb3duJyxcclxuICAgIHBsdWdpbjogRm91bmRhdGlvbi5fcGx1Z2luc1snZHJvcGRvd24tbWVudSddIHx8IG51bGxcclxuICB9LFxyXG4gZHJpbGxkb3duOiB7XHJcbiAgICBjc3NDbGFzczogJ2RyaWxsZG93bicsXHJcbiAgICBwbHVnaW46IEZvdW5kYXRpb24uX3BsdWdpbnNbJ2RyaWxsZG93biddIHx8IG51bGxcclxuICB9LFxyXG4gIGFjY29yZGlvbjoge1xyXG4gICAgY3NzQ2xhc3M6ICdhY2NvcmRpb24tbWVudScsXHJcbiAgICBwbHVnaW46IEZvdW5kYXRpb24uX3BsdWdpbnNbJ2FjY29yZGlvbi1tZW51J10gfHwgbnVsbFxyXG4gIH1cclxufTtcclxuXHJcbi8vIFdpbmRvdyBleHBvcnRzXHJcbkZvdW5kYXRpb24ucGx1Z2luKFJlc3BvbnNpdmVNZW51LCAnUmVzcG9uc2l2ZU1lbnUnKTtcclxuXHJcbn0oalF1ZXJ5KTtcclxuIiwiJ3VzZSBzdHJpY3QnO1xyXG5cclxuIWZ1bmN0aW9uKCQpIHtcclxuXHJcbi8qKlxyXG4gKiBSZXNwb25zaXZlVG9nZ2xlIG1vZHVsZS5cclxuICogQG1vZHVsZSBmb3VuZGF0aW9uLnJlc3BvbnNpdmVUb2dnbGVcclxuICogQHJlcXVpcmVzIGZvdW5kYXRpb24udXRpbC5tZWRpYVF1ZXJ5XHJcbiAqL1xyXG5cclxuY2xhc3MgUmVzcG9uc2l2ZVRvZ2dsZSB7XHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBUYWIgQmFyLlxyXG4gICAqIEBjbGFzc1xyXG4gICAqIEBmaXJlcyBSZXNwb25zaXZlVG9nZ2xlI2luaXRcclxuICAgKiBAcGFyYW0ge2pRdWVyeX0gZWxlbWVudCAtIGpRdWVyeSBvYmplY3QgdG8gYXR0YWNoIHRhYiBiYXIgZnVuY3Rpb25hbGl0eSB0by5cclxuICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9ucyAtIE92ZXJyaWRlcyB0byB0aGUgZGVmYXVsdCBwbHVnaW4gc2V0dGluZ3MuXHJcbiAgICovXHJcbiAgY29uc3RydWN0b3IoZWxlbWVudCwgb3B0aW9ucykge1xyXG4gICAgdGhpcy4kZWxlbWVudCA9ICQoZWxlbWVudCk7XHJcbiAgICB0aGlzLm9wdGlvbnMgPSAkLmV4dGVuZCh7fSwgUmVzcG9uc2l2ZVRvZ2dsZS5kZWZhdWx0cywgdGhpcy4kZWxlbWVudC5kYXRhKCksIG9wdGlvbnMpO1xyXG5cclxuICAgIHRoaXMuX2luaXQoKTtcclxuICAgIHRoaXMuX2V2ZW50cygpO1xyXG5cclxuICAgIEZvdW5kYXRpb24ucmVnaXN0ZXJQbHVnaW4odGhpcywgJ1Jlc3BvbnNpdmVUb2dnbGUnKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpYWxpemVzIHRoZSB0YWIgYmFyIGJ5IGZpbmRpbmcgdGhlIHRhcmdldCBlbGVtZW50LCB0b2dnbGluZyBlbGVtZW50LCBhbmQgcnVubmluZyB1cGRhdGUoKS5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9pbml0KCkge1xyXG4gICAgdmFyIHRhcmdldElEID0gdGhpcy4kZWxlbWVudC5kYXRhKCdyZXNwb25zaXZlLXRvZ2dsZScpO1xyXG4gICAgaWYgKCF0YXJnZXRJRCkge1xyXG4gICAgICBjb25zb2xlLmVycm9yKCdZb3VyIHRhYiBiYXIgbmVlZHMgYW4gSUQgb2YgYSBNZW51IGFzIHRoZSB2YWx1ZSBvZiBkYXRhLXRhYi1iYXIuJyk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy4kdGFyZ2V0TWVudSA9ICQoYCMke3RhcmdldElEfWApO1xyXG4gICAgdGhpcy4kdG9nZ2xlciA9IHRoaXMuJGVsZW1lbnQuZmluZCgnW2RhdGEtdG9nZ2xlXScpO1xyXG5cclxuICAgIHRoaXMuX3VwZGF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQWRkcyBuZWNlc3NhcnkgZXZlbnQgaGFuZGxlcnMgZm9yIHRoZSB0YWIgYmFyIHRvIHdvcmsuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfZXZlbnRzKCkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuXHJcbiAgICB0aGlzLl91cGRhdGVNcUhhbmRsZXIgPSB0aGlzLl91cGRhdGUuYmluZCh0aGlzKTtcclxuICAgIFxyXG4gICAgJCh3aW5kb3cpLm9uKCdjaGFuZ2VkLnpmLm1lZGlhcXVlcnknLCB0aGlzLl91cGRhdGVNcUhhbmRsZXIpO1xyXG5cclxuICAgIHRoaXMuJHRvZ2dsZXIub24oJ2NsaWNrLnpmLnJlc3BvbnNpdmVUb2dnbGUnLCB0aGlzLnRvZ2dsZU1lbnUuYmluZCh0aGlzKSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDaGVja3MgdGhlIGN1cnJlbnQgbWVkaWEgcXVlcnkgdG8gZGV0ZXJtaW5lIGlmIHRoZSB0YWIgYmFyIHNob3VsZCBiZSB2aXNpYmxlIG9yIGhpZGRlbi5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF91cGRhdGUoKSB7XHJcbiAgICAvLyBNb2JpbGVcclxuICAgIGlmICghRm91bmRhdGlvbi5NZWRpYVF1ZXJ5LmF0TGVhc3QodGhpcy5vcHRpb25zLmhpZGVGb3IpKSB7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnQuc2hvdygpO1xyXG4gICAgICB0aGlzLiR0YXJnZXRNZW51LmhpZGUoKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBEZXNrdG9wXHJcbiAgICBlbHNlIHtcclxuICAgICAgdGhpcy4kZWxlbWVudC5oaWRlKCk7XHJcbiAgICAgIHRoaXMuJHRhcmdldE1lbnUuc2hvdygpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVG9nZ2xlcyB0aGUgZWxlbWVudCBhdHRhY2hlZCB0byB0aGUgdGFiIGJhci4gVGhlIHRvZ2dsZSBvbmx5IGhhcHBlbnMgaWYgdGhlIHNjcmVlbiBpcyBzbWFsbCBlbm91Z2ggdG8gYWxsb3cgaXQuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQGZpcmVzIFJlc3BvbnNpdmVUb2dnbGUjdG9nZ2xlZFxyXG4gICAqL1xyXG4gIHRvZ2dsZU1lbnUoKSB7ICAgXHJcbiAgICBpZiAoIUZvdW5kYXRpb24uTWVkaWFRdWVyeS5hdExlYXN0KHRoaXMub3B0aW9ucy5oaWRlRm9yKSkge1xyXG4gICAgICB0aGlzLiR0YXJnZXRNZW51LnRvZ2dsZSgwKTtcclxuXHJcbiAgICAgIC8qKlxyXG4gICAgICAgKiBGaXJlcyB3aGVuIHRoZSBlbGVtZW50IGF0dGFjaGVkIHRvIHRoZSB0YWIgYmFyIHRvZ2dsZXMuXHJcbiAgICAgICAqIEBldmVudCBSZXNwb25zaXZlVG9nZ2xlI3RvZ2dsZWRcclxuICAgICAgICovXHJcbiAgICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcigndG9nZ2xlZC56Zi5yZXNwb25zaXZlVG9nZ2xlJyk7XHJcbiAgICB9XHJcbiAgfTtcclxuXHJcbiAgZGVzdHJveSgpIHtcclxuICAgIHRoaXMuJGVsZW1lbnQub2ZmKCcuemYucmVzcG9uc2l2ZVRvZ2dsZScpO1xyXG4gICAgdGhpcy4kdG9nZ2xlci5vZmYoJy56Zi5yZXNwb25zaXZlVG9nZ2xlJyk7XHJcbiAgICBcclxuICAgICQod2luZG93KS5vZmYoJ2NoYW5nZWQuemYubWVkaWFxdWVyeScsIHRoaXMuX3VwZGF0ZU1xSGFuZGxlcik7XHJcbiAgICBcclxuICAgIEZvdW5kYXRpb24udW5yZWdpc3RlclBsdWdpbih0aGlzKTtcclxuICB9XHJcbn1cclxuXHJcblJlc3BvbnNpdmVUb2dnbGUuZGVmYXVsdHMgPSB7XHJcbiAgLyoqXHJcbiAgICogVGhlIGJyZWFrcG9pbnQgYWZ0ZXIgd2hpY2ggdGhlIG1lbnUgaXMgYWx3YXlzIHNob3duLCBhbmQgdGhlIHRhYiBiYXIgaXMgaGlkZGVuLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAnbWVkaXVtJ1xyXG4gICAqL1xyXG4gIGhpZGVGb3I6ICdtZWRpdW0nXHJcbn07XHJcblxyXG4vLyBXaW5kb3cgZXhwb3J0c1xyXG5Gb3VuZGF0aW9uLnBsdWdpbihSZXNwb25zaXZlVG9nZ2xlLCAnUmVzcG9uc2l2ZVRvZ2dsZScpO1xyXG5cclxufShqUXVlcnkpO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG4hZnVuY3Rpb24oJCkge1xyXG5cclxuLyoqXHJcbiAqIFJldmVhbCBtb2R1bGUuXHJcbiAqIEBtb2R1bGUgZm91bmRhdGlvbi5yZXZlYWxcclxuICogQHJlcXVpcmVzIGZvdW5kYXRpb24udXRpbC5rZXlib2FyZFxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLmJveFxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLnRyaWdnZXJzXHJcbiAqIEByZXF1aXJlcyBmb3VuZGF0aW9uLnV0aWwubWVkaWFRdWVyeVxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLm1vdGlvbiBpZiB1c2luZyBhbmltYXRpb25zXHJcbiAqL1xyXG5cclxuY2xhc3MgUmV2ZWFsIHtcclxuICAvKipcclxuICAgKiBDcmVhdGVzIGEgbmV3IGluc3RhbmNlIG9mIFJldmVhbC5cclxuICAgKiBAY2xhc3NcclxuICAgKiBAcGFyYW0ge2pRdWVyeX0gZWxlbWVudCAtIGpRdWVyeSBvYmplY3QgdG8gdXNlIGZvciB0aGUgbW9kYWwuXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBvcHRpb25hbCBwYXJhbWV0ZXJzLlxyXG4gICAqL1xyXG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQsIG9wdGlvbnMpIHtcclxuICAgIHRoaXMuJGVsZW1lbnQgPSBlbGVtZW50O1xyXG4gICAgdGhpcy5vcHRpb25zID0gJC5leHRlbmQoe30sIFJldmVhbC5kZWZhdWx0cywgdGhpcy4kZWxlbWVudC5kYXRhKCksIG9wdGlvbnMpO1xyXG4gICAgdGhpcy5faW5pdCgpO1xyXG5cclxuICAgIEZvdW5kYXRpb24ucmVnaXN0ZXJQbHVnaW4odGhpcywgJ1JldmVhbCcpO1xyXG4gICAgRm91bmRhdGlvbi5LZXlib2FyZC5yZWdpc3RlcignUmV2ZWFsJywge1xyXG4gICAgICAnRU5URVInOiAnb3BlbicsXHJcbiAgICAgICdTUEFDRSc6ICdvcGVuJyxcclxuICAgICAgJ0VTQ0FQRSc6ICdjbG9zZScsXHJcbiAgICAgICdUQUInOiAndGFiX2ZvcndhcmQnLFxyXG4gICAgICAnU0hJRlRfVEFCJzogJ3RhYl9iYWNrd2FyZCdcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSW5pdGlhbGl6ZXMgdGhlIG1vZGFsIGJ5IGFkZGluZyB0aGUgb3ZlcmxheSBhbmQgY2xvc2UgYnV0dG9ucywgKGlmIHNlbGVjdGVkKS5cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9pbml0KCkge1xyXG4gICAgdGhpcy5pZCA9IHRoaXMuJGVsZW1lbnQuYXR0cignaWQnKTtcclxuICAgIHRoaXMuaXNBY3RpdmUgPSBmYWxzZTtcclxuICAgIHRoaXMuY2FjaGVkID0ge21xOiBGb3VuZGF0aW9uLk1lZGlhUXVlcnkuY3VycmVudH07XHJcbiAgICB0aGlzLmlzTW9iaWxlID0gbW9iaWxlU25pZmYoKTtcclxuXHJcbiAgICB0aGlzLiRhbmNob3IgPSAkKGBbZGF0YS1vcGVuPVwiJHt0aGlzLmlkfVwiXWApLmxlbmd0aCA/ICQoYFtkYXRhLW9wZW49XCIke3RoaXMuaWR9XCJdYCkgOiAkKGBbZGF0YS10b2dnbGU9XCIke3RoaXMuaWR9XCJdYCk7XHJcbiAgICB0aGlzLiRhbmNob3IuYXR0cih7XHJcbiAgICAgICdhcmlhLWNvbnRyb2xzJzogdGhpcy5pZCxcclxuICAgICAgJ2FyaWEtaGFzcG9wdXAnOiB0cnVlLFxyXG4gICAgICAndGFiaW5kZXgnOiAwXHJcbiAgICB9KTtcclxuXHJcbiAgICBpZiAodGhpcy5vcHRpb25zLmZ1bGxTY3JlZW4gfHwgdGhpcy4kZWxlbWVudC5oYXNDbGFzcygnZnVsbCcpKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5mdWxsU2NyZWVuID0gdHJ1ZTtcclxuICAgICAgdGhpcy5vcHRpb25zLm92ZXJsYXkgPSBmYWxzZTtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLm9wdGlvbnMub3ZlcmxheSAmJiAhdGhpcy4kb3ZlcmxheSkge1xyXG4gICAgICB0aGlzLiRvdmVybGF5ID0gdGhpcy5fbWFrZU92ZXJsYXkodGhpcy5pZCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy4kZWxlbWVudC5hdHRyKHtcclxuICAgICAgICAncm9sZSc6ICdkaWFsb2cnLFxyXG4gICAgICAgICdhcmlhLWhpZGRlbic6IHRydWUsXHJcbiAgICAgICAgJ2RhdGEteWV0aS1ib3gnOiB0aGlzLmlkLFxyXG4gICAgICAgICdkYXRhLXJlc2l6ZSc6IHRoaXMuaWRcclxuICAgIH0pO1xyXG5cclxuICAgIGlmKHRoaXMuJG92ZXJsYXkpIHtcclxuICAgICAgdGhpcy4kZWxlbWVudC5kZXRhY2goKS5hcHBlbmRUbyh0aGlzLiRvdmVybGF5KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnQuZGV0YWNoKCkuYXBwZW5kVG8oJCgnYm9keScpKTtcclxuICAgICAgdGhpcy4kZWxlbWVudC5hZGRDbGFzcygnd2l0aG91dC1vdmVybGF5Jyk7XHJcbiAgICB9XHJcbiAgICB0aGlzLl9ldmVudHMoKTtcclxuICAgIGlmICh0aGlzLm9wdGlvbnMuZGVlcExpbmsgJiYgd2luZG93LmxvY2F0aW9uLmhhc2ggPT09ICggYCMke3RoaXMuaWR9YCkpIHtcclxuICAgICAgJCh3aW5kb3cpLm9uZSgnbG9hZC56Zi5yZXZlYWwnLCB0aGlzLm9wZW4uYmluZCh0aGlzKSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDcmVhdGVzIGFuIG92ZXJsYXkgZGl2IHRvIGRpc3BsYXkgYmVoaW5kIHRoZSBtb2RhbC5cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9tYWtlT3ZlcmxheShpZCkge1xyXG4gICAgdmFyICRvdmVybGF5ID0gJCgnPGRpdj48L2Rpdj4nKVxyXG4gICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygncmV2ZWFsLW92ZXJsYXknKVxyXG4gICAgICAgICAgICAgICAgICAgIC5hcHBlbmRUbygnYm9keScpO1xyXG4gICAgcmV0dXJuICRvdmVybGF5O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVXBkYXRlcyBwb3NpdGlvbiBvZiBtb2RhbFxyXG4gICAqIFRPRE86ICBGaWd1cmUgb3V0IGlmIHdlIGFjdHVhbGx5IG5lZWQgdG8gY2FjaGUgdGhlc2UgdmFsdWVzIG9yIGlmIGl0IGRvZXNuJ3QgbWF0dGVyXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfdXBkYXRlUG9zaXRpb24oKSB7XHJcbiAgICB2YXIgd2lkdGggPSB0aGlzLiRlbGVtZW50Lm91dGVyV2lkdGgoKTtcclxuICAgIHZhciBvdXRlcldpZHRoID0gJCh3aW5kb3cpLndpZHRoKCk7XHJcbiAgICB2YXIgaGVpZ2h0ID0gdGhpcy4kZWxlbWVudC5vdXRlckhlaWdodCgpO1xyXG4gICAgdmFyIG91dGVySGVpZ2h0ID0gJCh3aW5kb3cpLmhlaWdodCgpO1xyXG4gICAgdmFyIGxlZnQsIHRvcDtcclxuICAgIGlmICh0aGlzLm9wdGlvbnMuaE9mZnNldCA9PT0gJ2F1dG8nKSB7XHJcbiAgICAgIGxlZnQgPSBwYXJzZUludCgob3V0ZXJXaWR0aCAtIHdpZHRoKSAvIDIsIDEwKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGxlZnQgPSBwYXJzZUludCh0aGlzLm9wdGlvbnMuaE9mZnNldCwgMTApO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy52T2Zmc2V0ID09PSAnYXV0bycpIHtcclxuICAgICAgaWYgKGhlaWdodCA+IG91dGVySGVpZ2h0KSB7XHJcbiAgICAgICAgdG9wID0gcGFyc2VJbnQoTWF0aC5taW4oMTAwLCBvdXRlckhlaWdodCAvIDEwKSwgMTApO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRvcCA9IHBhcnNlSW50KChvdXRlckhlaWdodCAtIGhlaWdodCkgLyA0LCAxMCk7XHJcbiAgICAgIH1cclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRvcCA9IHBhcnNlSW50KHRoaXMub3B0aW9ucy52T2Zmc2V0LCAxMCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLiRlbGVtZW50LmNzcyh7dG9wOiB0b3AgKyAncHgnfSk7XHJcbiAgICAvLyBvbmx5IHdvcnJ5IGFib3V0IGxlZnQgaWYgd2UgZG9uJ3QgaGF2ZSBhbiBvdmVybGF5IG9yIHdlIGhhdmVhICBob3Jpem9udGFsIG9mZnNldCxcclxuICAgIC8vIG90aGVyd2lzZSB3ZSdyZSBwZXJmZWN0bHkgaW4gdGhlIG1pZGRsZVxyXG4gICAgaWYoIXRoaXMuJG92ZXJsYXkgfHwgKHRoaXMub3B0aW9ucy5oT2Zmc2V0ICE9PSAnYXV0bycpKSB7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnQuY3NzKHtsZWZ0OiBsZWZ0ICsgJ3B4J30pO1xyXG4gICAgICB0aGlzLiRlbGVtZW50LmNzcyh7bWFyZ2luOiAnMHB4J30pO1xyXG4gICAgfVxyXG5cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZHMgZXZlbnQgaGFuZGxlcnMgZm9yIHRoZSBtb2RhbC5cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9ldmVudHMoKSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG5cclxuICAgIHRoaXMuJGVsZW1lbnQub24oe1xyXG4gICAgICAnb3Blbi56Zi50cmlnZ2VyJzogdGhpcy5vcGVuLmJpbmQodGhpcyksXHJcbiAgICAgICdjbG9zZS56Zi50cmlnZ2VyJzogKGV2ZW50LCAkZWxlbWVudCkgPT4ge1xyXG4gICAgICAgIGlmICgoZXZlbnQudGFyZ2V0ID09PSBfdGhpcy4kZWxlbWVudFswXSkgfHxcclxuICAgICAgICAgICAgKCQoZXZlbnQudGFyZ2V0KS5wYXJlbnRzKCdbZGF0YS1jbG9zYWJsZV0nKVswXSA9PT0gJGVsZW1lbnQpKSB7IC8vIG9ubHkgY2xvc2UgcmV2ZWFsIHdoZW4gaXQncyBleHBsaWNpdGx5IGNhbGxlZFxyXG4gICAgICAgICAgcmV0dXJuIHRoaXMuY2xvc2UuYXBwbHkodGhpcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9LFxyXG4gICAgICAndG9nZ2xlLnpmLnRyaWdnZXInOiB0aGlzLnRvZ2dsZS5iaW5kKHRoaXMpLFxyXG4gICAgICAncmVzaXplbWUuemYudHJpZ2dlcic6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIF90aGlzLl91cGRhdGVQb3NpdGlvbigpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBpZiAodGhpcy4kYW5jaG9yLmxlbmd0aCkge1xyXG4gICAgICB0aGlzLiRhbmNob3Iub24oJ2tleWRvd24uemYucmV2ZWFsJywgZnVuY3Rpb24oZSkge1xyXG4gICAgICAgIGlmIChlLndoaWNoID09PSAxMyB8fCBlLndoaWNoID09PSAzMikge1xyXG4gICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgIF90aGlzLm9wZW4oKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuY2xvc2VPbkNsaWNrICYmIHRoaXMub3B0aW9ucy5vdmVybGF5KSB7XHJcbiAgICAgIHRoaXMuJG92ZXJsYXkub2ZmKCcuemYucmV2ZWFsJykub24oJ2NsaWNrLnpmLnJldmVhbCcsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICBpZiAoZS50YXJnZXQgPT09IF90aGlzLiRlbGVtZW50WzBdIHx8ICQuY29udGFpbnMoX3RoaXMuJGVsZW1lbnRbMF0sIGUudGFyZ2V0KSkgeyByZXR1cm47IH1cclxuICAgICAgICBfdGhpcy5jbG9zZSgpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuZGVlcExpbmspIHtcclxuICAgICAgJCh3aW5kb3cpLm9uKGBwb3BzdGF0ZS56Zi5yZXZlYWw6JHt0aGlzLmlkfWAsIHRoaXMuX2hhbmRsZVN0YXRlLmJpbmQodGhpcykpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlcyBtb2RhbCBtZXRob2RzIG9uIGJhY2svZm9yd2FyZCBidXR0b24gY2xpY2tzIG9yIGFueSBvdGhlciBldmVudCB0aGF0IHRyaWdnZXJzIHBvcHN0YXRlLlxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX2hhbmRsZVN0YXRlKGUpIHtcclxuICAgIGlmKHdpbmRvdy5sb2NhdGlvbi5oYXNoID09PSAoICcjJyArIHRoaXMuaWQpICYmICF0aGlzLmlzQWN0aXZlKXsgdGhpcy5vcGVuKCk7IH1cclxuICAgIGVsc2V7IHRoaXMuY2xvc2UoKTsgfVxyXG4gIH1cclxuXHJcblxyXG4gIC8qKlxyXG4gICAqIE9wZW5zIHRoZSBtb2RhbCBjb250cm9sbGVkIGJ5IGB0aGlzLiRhbmNob3JgLCBhbmQgY2xvc2VzIGFsbCBvdGhlcnMgYnkgZGVmYXVsdC5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAZmlyZXMgUmV2ZWFsI2Nsb3NlbWVcclxuICAgKiBAZmlyZXMgUmV2ZWFsI29wZW5cclxuICAgKi9cclxuICBvcGVuKCkge1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5kZWVwTGluaykge1xyXG4gICAgICB2YXIgaGFzaCA9IGAjJHt0aGlzLmlkfWA7XHJcblxyXG4gICAgICBpZiAod2luZG93Lmhpc3RvcnkucHVzaFN0YXRlKSB7XHJcbiAgICAgICAgd2luZG93Lmhpc3RvcnkucHVzaFN0YXRlKG51bGwsIG51bGwsIGhhc2gpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHdpbmRvdy5sb2NhdGlvbi5oYXNoID0gaGFzaDtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuaXNBY3RpdmUgPSB0cnVlO1xyXG5cclxuICAgIC8vIE1ha2UgZWxlbWVudHMgaW52aXNpYmxlLCBidXQgcmVtb3ZlIGRpc3BsYXk6IG5vbmUgc28gd2UgY2FuIGdldCBzaXplIGFuZCBwb3NpdGlvbmluZ1xyXG4gICAgdGhpcy4kZWxlbWVudFxyXG4gICAgICAgIC5jc3MoeyAndmlzaWJpbGl0eSc6ICdoaWRkZW4nIH0pXHJcbiAgICAgICAgLnNob3coKVxyXG4gICAgICAgIC5zY3JvbGxUb3AoMCk7XHJcbiAgICBpZiAodGhpcy5vcHRpb25zLm92ZXJsYXkpIHtcclxuICAgICAgdGhpcy4kb3ZlcmxheS5jc3Moeyd2aXNpYmlsaXR5JzogJ2hpZGRlbid9KS5zaG93KCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fdXBkYXRlUG9zaXRpb24oKTtcclxuXHJcbiAgICB0aGlzLiRlbGVtZW50XHJcbiAgICAgIC5oaWRlKClcclxuICAgICAgLmNzcyh7ICd2aXNpYmlsaXR5JzogJycgfSk7XHJcblxyXG4gICAgaWYodGhpcy4kb3ZlcmxheSkge1xyXG4gICAgICB0aGlzLiRvdmVybGF5LmNzcyh7J3Zpc2liaWxpdHknOiAnJ30pLmhpZGUoKTtcclxuICAgICAgaWYodGhpcy4kZWxlbWVudC5oYXNDbGFzcygnZmFzdCcpKSB7XHJcbiAgICAgICAgdGhpcy4kb3ZlcmxheS5hZGRDbGFzcygnZmFzdCcpO1xyXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuJGVsZW1lbnQuaGFzQ2xhc3MoJ3Nsb3cnKSkge1xyXG4gICAgICAgIHRoaXMuJG92ZXJsYXkuYWRkQ2xhc3MoJ3Nsb3cnKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuXHJcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5tdWx0aXBsZU9wZW5lZCkge1xyXG4gICAgICAvKipcclxuICAgICAgICogRmlyZXMgaW1tZWRpYXRlbHkgYmVmb3JlIHRoZSBtb2RhbCBvcGVucy5cclxuICAgICAgICogQ2xvc2VzIGFueSBvdGhlciBtb2RhbHMgdGhhdCBhcmUgY3VycmVudGx5IG9wZW5cclxuICAgICAgICogQGV2ZW50IFJldmVhbCNjbG9zZW1lXHJcbiAgICAgICAqL1xyXG4gICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ2Nsb3NlbWUuemYucmV2ZWFsJywgdGhpcy5pZCk7XHJcbiAgICB9XHJcbiAgICAvLyBNb3Rpb24gVUkgbWV0aG9kIG9mIHJldmVhbFxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5hbmltYXRpb25Jbikge1xyXG4gICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICBmdW5jdGlvbiBhZnRlckFuaW1hdGlvbkZvY3VzKCl7XHJcbiAgICAgICAgX3RoaXMuJGVsZW1lbnRcclxuICAgICAgICAgIC5hdHRyKHtcclxuICAgICAgICAgICAgJ2FyaWEtaGlkZGVuJzogZmFsc2UsXHJcbiAgICAgICAgICAgICd0YWJpbmRleCc6IC0xXHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgICAgLmZvY3VzKCk7XHJcbiAgICAgICAgICBjb25zb2xlLmxvZygnZm9jdXMnKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAodGhpcy5vcHRpb25zLm92ZXJsYXkpIHtcclxuICAgICAgICBGb3VuZGF0aW9uLk1vdGlvbi5hbmltYXRlSW4odGhpcy4kb3ZlcmxheSwgJ2ZhZGUtaW4nKTtcclxuICAgICAgfVxyXG4gICAgICBGb3VuZGF0aW9uLk1vdGlvbi5hbmltYXRlSW4odGhpcy4kZWxlbWVudCwgdGhpcy5vcHRpb25zLmFuaW1hdGlvbkluLCAoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5mb2N1c2FibGVFbGVtZW50cyA9IEZvdW5kYXRpb24uS2V5Ym9hcmQuZmluZEZvY3VzYWJsZSh0aGlzLiRlbGVtZW50KTtcclxuICAgICAgICBhZnRlckFuaW1hdGlvbkZvY3VzKCk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgLy8galF1ZXJ5IG1ldGhvZCBvZiByZXZlYWxcclxuICAgIGVsc2Uge1xyXG4gICAgICBpZiAodGhpcy5vcHRpb25zLm92ZXJsYXkpIHtcclxuICAgICAgICB0aGlzLiRvdmVybGF5LnNob3coMCk7XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy4kZWxlbWVudC5zaG93KHRoaXMub3B0aW9ucy5zaG93RGVsYXkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGhhbmRsZSBhY2Nlc3NpYmlsaXR5XHJcbiAgICB0aGlzLiRlbGVtZW50XHJcbiAgICAgIC5hdHRyKHtcclxuICAgICAgICAnYXJpYS1oaWRkZW4nOiBmYWxzZSxcclxuICAgICAgICAndGFiaW5kZXgnOiAtMVxyXG4gICAgICB9KVxyXG4gICAgICAuZm9jdXMoKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVzIHdoZW4gdGhlIG1vZGFsIGhhcyBzdWNjZXNzZnVsbHkgb3BlbmVkLlxyXG4gICAgICogQGV2ZW50IFJldmVhbCNvcGVuXHJcbiAgICAgKi9cclxuICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcignb3Blbi56Zi5yZXZlYWwnKTtcclxuXHJcbiAgICBpZiAodGhpcy5pc01vYmlsZSkge1xyXG4gICAgICB0aGlzLm9yaWdpbmFsU2Nyb2xsUG9zID0gd2luZG93LnBhZ2VZT2Zmc2V0O1xyXG4gICAgICAkKCdodG1sLCBib2R5JykuYWRkQ2xhc3MoJ2lzLXJldmVhbC1vcGVuJyk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgJCgnYm9keScpLmFkZENsYXNzKCdpcy1yZXZlYWwtb3BlbicpO1xyXG4gICAgfVxyXG5cclxuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xyXG4gICAgICB0aGlzLl9leHRyYUhhbmRsZXJzKCk7XHJcbiAgICB9LCAwKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZHMgZXh0cmEgZXZlbnQgaGFuZGxlcnMgZm9yIHRoZSBib2R5IGFuZCB3aW5kb3cgaWYgbmVjZXNzYXJ5LlxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX2V4dHJhSGFuZGxlcnMoKSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgdGhpcy5mb2N1c2FibGVFbGVtZW50cyA9IEZvdW5kYXRpb24uS2V5Ym9hcmQuZmluZEZvY3VzYWJsZSh0aGlzLiRlbGVtZW50KTtcclxuXHJcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5vdmVybGF5ICYmIHRoaXMub3B0aW9ucy5jbG9zZU9uQ2xpY2sgJiYgIXRoaXMub3B0aW9ucy5mdWxsU2NyZWVuKSB7XHJcbiAgICAgICQoJ2JvZHknKS5vbignY2xpY2suemYucmV2ZWFsJywgZnVuY3Rpb24oZSkge1xyXG4gICAgICAgIGlmIChlLnRhcmdldCA9PT0gX3RoaXMuJGVsZW1lbnRbMF0gfHwgJC5jb250YWlucyhfdGhpcy4kZWxlbWVudFswXSwgZS50YXJnZXQpKSB7IHJldHVybjsgfVxyXG4gICAgICAgIF90aGlzLmNsb3NlKCk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuY2xvc2VPbkVzYykge1xyXG4gICAgICAkKHdpbmRvdykub24oJ2tleWRvd24uemYucmV2ZWFsJywgZnVuY3Rpb24oZSkge1xyXG4gICAgICAgIEZvdW5kYXRpb24uS2V5Ym9hcmQuaGFuZGxlS2V5KGUsICdSZXZlYWwnLCB7XHJcbiAgICAgICAgICBjbG9zZTogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgIGlmIChfdGhpcy5vcHRpb25zLmNsb3NlT25Fc2MpIHtcclxuICAgICAgICAgICAgICBfdGhpcy5jbG9zZSgpO1xyXG4gICAgICAgICAgICAgIF90aGlzLiRhbmNob3IuZm9jdXMoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBsb2NrIGZvY3VzIHdpdGhpbiBtb2RhbCB3aGlsZSB0YWJiaW5nXHJcbiAgICB0aGlzLiRlbGVtZW50Lm9uKCdrZXlkb3duLnpmLnJldmVhbCcsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgdmFyICR0YXJnZXQgPSAkKHRoaXMpO1xyXG4gICAgICAvLyBoYW5kbGUga2V5Ym9hcmQgZXZlbnQgd2l0aCBrZXlib2FyZCB1dGlsXHJcbiAgICAgIEZvdW5kYXRpb24uS2V5Ym9hcmQuaGFuZGxlS2V5KGUsICdSZXZlYWwnLCB7XHJcbiAgICAgICAgdGFiX2ZvcndhcmQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgaWYgKF90aGlzLiRlbGVtZW50LmZpbmQoJzpmb2N1cycpLmlzKF90aGlzLmZvY3VzYWJsZUVsZW1lbnRzLmVxKC0xKSkpIHsgLy8gbGVmdCBtb2RhbCBkb3dud2FyZHMsIHNldHRpbmcgZm9jdXMgdG8gZmlyc3QgZWxlbWVudFxyXG4gICAgICAgICAgICBfdGhpcy5mb2N1c2FibGVFbGVtZW50cy5lcSgwKS5mb2N1cygpO1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmIChfdGhpcy5mb2N1c2FibGVFbGVtZW50cy5sZW5ndGggPT09IDApIHsgLy8gbm8gZm9jdXNhYmxlIGVsZW1lbnRzIGluc2lkZSB0aGUgbW9kYWwgYXQgYWxsLCBwcmV2ZW50IHRhYmJpbmcgaW4gZ2VuZXJhbFxyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIHRhYl9iYWNrd2FyZDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICBpZiAoX3RoaXMuJGVsZW1lbnQuZmluZCgnOmZvY3VzJykuaXMoX3RoaXMuZm9jdXNhYmxlRWxlbWVudHMuZXEoMCkpIHx8IF90aGlzLiRlbGVtZW50LmlzKCc6Zm9jdXMnKSkgeyAvLyBsZWZ0IG1vZGFsIHVwd2FyZHMsIHNldHRpbmcgZm9jdXMgdG8gbGFzdCBlbGVtZW50XHJcbiAgICAgICAgICAgIF90aGlzLmZvY3VzYWJsZUVsZW1lbnRzLmVxKC0xKS5mb2N1cygpO1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmIChfdGhpcy5mb2N1c2FibGVFbGVtZW50cy5sZW5ndGggPT09IDApIHsgLy8gbm8gZm9jdXNhYmxlIGVsZW1lbnRzIGluc2lkZSB0aGUgbW9kYWwgYXQgYWxsLCBwcmV2ZW50IHRhYmJpbmcgaW4gZ2VuZXJhbFxyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9LFxyXG4gICAgICAgIG9wZW46IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgaWYgKF90aGlzLiRlbGVtZW50LmZpbmQoJzpmb2N1cycpLmlzKF90aGlzLiRlbGVtZW50LmZpbmQoJ1tkYXRhLWNsb3NlXScpKSkge1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyAvLyBzZXQgZm9jdXMgYmFjayB0byBhbmNob3IgaWYgY2xvc2UgYnV0dG9uIGhhcyBiZWVuIGFjdGl2YXRlZFxyXG4gICAgICAgICAgICAgIF90aGlzLiRhbmNob3IuZm9jdXMoKTtcclxuICAgICAgICAgICAgfSwgMSk7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKCR0YXJnZXQuaXMoX3RoaXMuZm9jdXNhYmxlRWxlbWVudHMpKSB7IC8vIGRvbnQndCB0cmlnZ2VyIGlmIGFjdWFsIGVsZW1lbnQgaGFzIGZvY3VzIChpLmUuIGlucHV0cywgbGlua3MsIC4uLilcclxuICAgICAgICAgICAgX3RoaXMub3BlbigpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0sXHJcbiAgICAgICAgY2xvc2U6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgaWYgKF90aGlzLm9wdGlvbnMuY2xvc2VPbkVzYykge1xyXG4gICAgICAgICAgICBfdGhpcy5jbG9zZSgpO1xyXG4gICAgICAgICAgICBfdGhpcy4kYW5jaG9yLmZvY3VzKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBoYW5kbGVkOiBmdW5jdGlvbihwcmV2ZW50RGVmYXVsdCkge1xyXG4gICAgICAgICAgaWYgKHByZXZlbnREZWZhdWx0KSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDbG9zZXMgdGhlIG1vZGFsLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIEBmaXJlcyBSZXZlYWwjY2xvc2VkXHJcbiAgICovXHJcbiAgY2xvc2UoKSB7XHJcbiAgICBpZiAoIXRoaXMuaXNBY3RpdmUgfHwgIXRoaXMuJGVsZW1lbnQuaXMoJzp2aXNpYmxlJykpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuXHJcbiAgICAvLyBNb3Rpb24gVUkgbWV0aG9kIG9mIGhpZGluZ1xyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5hbmltYXRpb25PdXQpIHtcclxuICAgICAgaWYgKHRoaXMub3B0aW9ucy5vdmVybGF5KSB7XHJcbiAgICAgICAgRm91bmRhdGlvbi5Nb3Rpb24uYW5pbWF0ZU91dCh0aGlzLiRvdmVybGF5LCAnZmFkZS1vdXQnLCBmaW5pc2hVcCk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSB7XHJcbiAgICAgICAgZmluaXNoVXAoKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgRm91bmRhdGlvbi5Nb3Rpb24uYW5pbWF0ZU91dCh0aGlzLiRlbGVtZW50LCB0aGlzLm9wdGlvbnMuYW5pbWF0aW9uT3V0KTtcclxuICAgIH1cclxuICAgIC8vIGpRdWVyeSBtZXRob2Qgb2YgaGlkaW5nXHJcbiAgICBlbHNlIHtcclxuICAgICAgaWYgKHRoaXMub3B0aW9ucy5vdmVybGF5KSB7XHJcbiAgICAgICAgdGhpcy4kb3ZlcmxheS5oaWRlKDAsIGZpbmlzaFVwKTtcclxuICAgICAgfVxyXG4gICAgICBlbHNlIHtcclxuICAgICAgICBmaW5pc2hVcCgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB0aGlzLiRlbGVtZW50LmhpZGUodGhpcy5vcHRpb25zLmhpZGVEZWxheSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ29uZGl0aW9uYWxzIHRvIHJlbW92ZSBleHRyYSBldmVudCBsaXN0ZW5lcnMgYWRkZWQgb24gb3BlblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5jbG9zZU9uRXNjKSB7XHJcbiAgICAgICQod2luZG93KS5vZmYoJ2tleWRvd24uemYucmV2ZWFsJyk7XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKCF0aGlzLm9wdGlvbnMub3ZlcmxheSAmJiB0aGlzLm9wdGlvbnMuY2xvc2VPbkNsaWNrKSB7XHJcbiAgICAgICQoJ2JvZHknKS5vZmYoJ2NsaWNrLnpmLnJldmVhbCcpO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuJGVsZW1lbnQub2ZmKCdrZXlkb3duLnpmLnJldmVhbCcpO1xyXG5cclxuICAgIGZ1bmN0aW9uIGZpbmlzaFVwKCkge1xyXG4gICAgICBpZiAoX3RoaXMuaXNNb2JpbGUpIHtcclxuICAgICAgICAkKCdodG1sLCBib2R5JykucmVtb3ZlQ2xhc3MoJ2lzLXJldmVhbC1vcGVuJyk7XHJcbiAgICAgICAgaWYoX3RoaXMub3JpZ2luYWxTY3JvbGxQb3MpIHtcclxuICAgICAgICAgICQoJ2JvZHknKS5zY3JvbGxUb3AoX3RoaXMub3JpZ2luYWxTY3JvbGxQb3MpO1xyXG4gICAgICAgICAgX3RoaXMub3JpZ2luYWxTY3JvbGxQb3MgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBlbHNlIHtcclxuICAgICAgICAkKCdib2R5JykucmVtb3ZlQ2xhc3MoJ2lzLXJldmVhbC1vcGVuJyk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIF90aGlzLiRlbGVtZW50LmF0dHIoJ2FyaWEtaGlkZGVuJywgdHJ1ZSk7XHJcblxyXG4gICAgICAvKipcclxuICAgICAgKiBGaXJlcyB3aGVuIHRoZSBtb2RhbCBpcyBkb25lIGNsb3NpbmcuXHJcbiAgICAgICogQGV2ZW50IFJldmVhbCNjbG9zZWRcclxuICAgICAgKi9cclxuICAgICAgX3RoaXMuJGVsZW1lbnQudHJpZ2dlcignY2xvc2VkLnpmLnJldmVhbCcpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgKiBSZXNldHMgdGhlIG1vZGFsIGNvbnRlbnRcclxuICAgICogVGhpcyBwcmV2ZW50cyBhIHJ1bm5pbmcgdmlkZW8gdG8ga2VlcCBnb2luZyBpbiB0aGUgYmFja2dyb3VuZFxyXG4gICAgKi9cclxuICAgIGlmICh0aGlzLm9wdGlvbnMucmVzZXRPbkNsb3NlKSB7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnQuaHRtbCh0aGlzLiRlbGVtZW50Lmh0bWwoKSk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5pc0FjdGl2ZSA9IGZhbHNlO1xyXG4gICAgIGlmIChfdGhpcy5vcHRpb25zLmRlZXBMaW5rKSB7XHJcbiAgICAgICBpZiAod2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKSB7XHJcbiAgICAgICAgIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZShcIlwiLCBkb2N1bWVudC50aXRsZSwgd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lKTtcclxuICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgIHdpbmRvdy5sb2NhdGlvbi5oYXNoID0gJyc7XHJcbiAgICAgICB9XHJcbiAgICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVG9nZ2xlcyB0aGUgb3Blbi9jbG9zZWQgc3RhdGUgb2YgYSBtb2RhbC5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKi9cclxuICB0b2dnbGUoKSB7XHJcbiAgICBpZiAodGhpcy5pc0FjdGl2ZSkge1xyXG4gICAgICB0aGlzLmNsb3NlKCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLm9wZW4oKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBEZXN0cm95cyBhbiBpbnN0YW5jZSBvZiBhIG1vZGFsLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqL1xyXG4gIGRlc3Ryb3koKSB7XHJcbiAgICBpZiAodGhpcy5vcHRpb25zLm92ZXJsYXkpIHtcclxuICAgICAgdGhpcy4kZWxlbWVudC5hcHBlbmRUbygkKCdib2R5JykpOyAvLyBtb3ZlICRlbGVtZW50IG91dHNpZGUgb2YgJG92ZXJsYXkgdG8gcHJldmVudCBlcnJvciB1bnJlZ2lzdGVyUGx1Z2luKClcclxuICAgICAgdGhpcy4kb3ZlcmxheS5oaWRlKCkub2ZmKCkucmVtb3ZlKCk7XHJcbiAgICB9XHJcbiAgICB0aGlzLiRlbGVtZW50LmhpZGUoKS5vZmYoKTtcclxuICAgIHRoaXMuJGFuY2hvci5vZmYoJy56ZicpO1xyXG4gICAgJCh3aW5kb3cpLm9mZihgLnpmLnJldmVhbDoke3RoaXMuaWR9YCk7XHJcblxyXG4gICAgRm91bmRhdGlvbi51bnJlZ2lzdGVyUGx1Z2luKHRoaXMpO1xyXG4gIH07XHJcbn1cclxuXHJcblJldmVhbC5kZWZhdWx0cyA9IHtcclxuICAvKipcclxuICAgKiBNb3Rpb24tVUkgY2xhc3MgdG8gdXNlIGZvciBhbmltYXRlZCBlbGVtZW50cy4gSWYgbm9uZSB1c2VkLCBkZWZhdWx0cyB0byBzaW1wbGUgc2hvdy9oaWRlLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAnc2xpZGUtaW4tbGVmdCdcclxuICAgKi9cclxuICBhbmltYXRpb25JbjogJycsXHJcbiAgLyoqXHJcbiAgICogTW90aW9uLVVJIGNsYXNzIHRvIHVzZSBmb3IgYW5pbWF0ZWQgZWxlbWVudHMuIElmIG5vbmUgdXNlZCwgZGVmYXVsdHMgdG8gc2ltcGxlIHNob3cvaGlkZS5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgJ3NsaWRlLW91dC1yaWdodCdcclxuICAgKi9cclxuICBhbmltYXRpb25PdXQ6ICcnLFxyXG4gIC8qKlxyXG4gICAqIFRpbWUsIGluIG1zLCB0byBkZWxheSB0aGUgb3BlbmluZyBvZiBhIG1vZGFsIGFmdGVyIGEgY2xpY2sgaWYgbm8gYW5pbWF0aW9uIHVzZWQuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIDEwXHJcbiAgICovXHJcbiAgc2hvd0RlbGF5OiAwLFxyXG4gIC8qKlxyXG4gICAqIFRpbWUsIGluIG1zLCB0byBkZWxheSB0aGUgY2xvc2luZyBvZiBhIG1vZGFsIGFmdGVyIGEgY2xpY2sgaWYgbm8gYW5pbWF0aW9uIHVzZWQuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIDEwXHJcbiAgICovXHJcbiAgaGlkZURlbGF5OiAwLFxyXG4gIC8qKlxyXG4gICAqIEFsbG93cyBhIGNsaWNrIG9uIHRoZSBib2R5L292ZXJsYXkgdG8gY2xvc2UgdGhlIG1vZGFsLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSB0cnVlXHJcbiAgICovXHJcbiAgY2xvc2VPbkNsaWNrOiB0cnVlLFxyXG4gIC8qKlxyXG4gICAqIEFsbG93cyB0aGUgbW9kYWwgdG8gY2xvc2UgaWYgdGhlIHVzZXIgcHJlc3NlcyB0aGUgYEVTQ0FQRWAga2V5LlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSB0cnVlXHJcbiAgICovXHJcbiAgY2xvc2VPbkVzYzogdHJ1ZSxcclxuICAvKipcclxuICAgKiBJZiB0cnVlLCBhbGxvd3MgbXVsdGlwbGUgbW9kYWxzIHRvIGJlIGRpc3BsYXllZCBhdCBvbmNlLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSBmYWxzZVxyXG4gICAqL1xyXG4gIG11bHRpcGxlT3BlbmVkOiBmYWxzZSxcclxuICAvKipcclxuICAgKiBEaXN0YW5jZSwgaW4gcGl4ZWxzLCB0aGUgbW9kYWwgc2hvdWxkIHB1c2ggZG93biBmcm9tIHRoZSB0b3Agb2YgdGhlIHNjcmVlbi5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgYXV0b1xyXG4gICAqL1xyXG4gIHZPZmZzZXQ6ICdhdXRvJyxcclxuICAvKipcclxuICAgKiBEaXN0YW5jZSwgaW4gcGl4ZWxzLCB0aGUgbW9kYWwgc2hvdWxkIHB1c2ggaW4gZnJvbSB0aGUgc2lkZSBvZiB0aGUgc2NyZWVuLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSBhdXRvXHJcbiAgICovXHJcbiAgaE9mZnNldDogJ2F1dG8nLFxyXG4gIC8qKlxyXG4gICAqIEFsbG93cyB0aGUgbW9kYWwgdG8gYmUgZnVsbHNjcmVlbiwgY29tcGxldGVseSBibG9ja2luZyBvdXQgdGhlIHJlc3Qgb2YgdGhlIHZpZXcuIEpTIGNoZWNrcyBmb3IgdGhpcyBhcyB3ZWxsLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSBmYWxzZVxyXG4gICAqL1xyXG4gIGZ1bGxTY3JlZW46IGZhbHNlLFxyXG4gIC8qKlxyXG4gICAqIFBlcmNlbnRhZ2Ugb2Ygc2NyZWVuIGhlaWdodCB0aGUgbW9kYWwgc2hvdWxkIHB1c2ggdXAgZnJvbSB0aGUgYm90dG9tIG9mIHRoZSB2aWV3LlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAxMFxyXG4gICAqL1xyXG4gIGJ0bU9mZnNldFBjdDogMTAsXHJcbiAgLyoqXHJcbiAgICogQWxsb3dzIHRoZSBtb2RhbCB0byBnZW5lcmF0ZSBhbiBvdmVybGF5IGRpdiwgd2hpY2ggd2lsbCBjb3ZlciB0aGUgdmlldyB3aGVuIG1vZGFsIG9wZW5zLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSB0cnVlXHJcbiAgICovXHJcbiAgb3ZlcmxheTogdHJ1ZSxcclxuICAvKipcclxuICAgKiBBbGxvd3MgdGhlIG1vZGFsIHRvIHJlbW92ZSBhbmQgcmVpbmplY3QgbWFya3VwIG9uIGNsb3NlLiBTaG91bGQgYmUgdHJ1ZSBpZiB1c2luZyB2aWRlbyBlbGVtZW50cyB3L28gdXNpbmcgcHJvdmlkZXIncyBhcGksIG90aGVyd2lzZSwgdmlkZW9zIHdpbGwgY29udGludWUgdG8gcGxheSBpbiB0aGUgYmFja2dyb3VuZC5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgZmFsc2VcclxuICAgKi9cclxuICByZXNldE9uQ2xvc2U6IGZhbHNlLFxyXG4gIC8qKlxyXG4gICAqIEFsbG93cyB0aGUgbW9kYWwgdG8gYWx0ZXIgdGhlIHVybCBvbiBvcGVuL2Nsb3NlLCBhbmQgYWxsb3dzIHRoZSB1c2Ugb2YgdGhlIGBiYWNrYCBidXR0b24gdG8gY2xvc2UgbW9kYWxzLiBBTFNPLCBhbGxvd3MgYSBtb2RhbCB0byBhdXRvLW1hbmlhY2FsbHkgb3BlbiBvbiBwYWdlIGxvYWQgSUYgdGhlIGhhc2ggPT09IHRoZSBtb2RhbCdzIHVzZXItc2V0IGlkLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSBmYWxzZVxyXG4gICAqL1xyXG4gIGRlZXBMaW5rOiBmYWxzZVxyXG59O1xyXG5cclxuLy8gV2luZG93IGV4cG9ydHNcclxuRm91bmRhdGlvbi5wbHVnaW4oUmV2ZWFsLCAnUmV2ZWFsJyk7XHJcblxyXG5mdW5jdGlvbiBpUGhvbmVTbmlmZigpIHtcclxuICByZXR1cm4gL2lQKGFkfGhvbmV8b2QpLipPUy8udGVzdCh3aW5kb3cubmF2aWdhdG9yLnVzZXJBZ2VudCk7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGFuZHJvaWRTbmlmZigpIHtcclxuICByZXR1cm4gL0FuZHJvaWQvLnRlc3Qod2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQpO1xyXG59XHJcblxyXG5mdW5jdGlvbiBtb2JpbGVTbmlmZigpIHtcclxuICByZXR1cm4gaVBob25lU25pZmYoKSB8fCBhbmRyb2lkU25pZmYoKTtcclxufVxyXG5cclxufShqUXVlcnkpO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG4hZnVuY3Rpb24oJCkge1xyXG5cclxuLyoqXHJcbiAqIFNsaWRlciBtb2R1bGUuXHJcbiAqIEBtb2R1bGUgZm91bmRhdGlvbi5zbGlkZXJcclxuICogQHJlcXVpcmVzIGZvdW5kYXRpb24udXRpbC5tb3Rpb25cclxuICogQHJlcXVpcmVzIGZvdW5kYXRpb24udXRpbC50cmlnZ2Vyc1xyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLmtleWJvYXJkXHJcbiAqIEByZXF1aXJlcyBmb3VuZGF0aW9uLnV0aWwudG91Y2hcclxuICovXHJcblxyXG5jbGFzcyBTbGlkZXIge1xyXG4gIC8qKlxyXG4gICAqIENyZWF0ZXMgYSBuZXcgaW5zdGFuY2Ugb2YgYSBkcmlsbGRvd24gbWVudS5cclxuICAgKiBAY2xhc3NcclxuICAgKiBAcGFyYW0ge2pRdWVyeX0gZWxlbWVudCAtIGpRdWVyeSBvYmplY3QgdG8gbWFrZSBpbnRvIGFuIGFjY29yZGlvbiBtZW51LlxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gT3ZlcnJpZGVzIHRvIHRoZSBkZWZhdWx0IHBsdWdpbiBzZXR0aW5ncy5cclxuICAgKi9cclxuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBvcHRpb25zKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50ID0gZWxlbWVudDtcclxuICAgIHRoaXMub3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBTbGlkZXIuZGVmYXVsdHMsIHRoaXMuJGVsZW1lbnQuZGF0YSgpLCBvcHRpb25zKTtcclxuXHJcbiAgICB0aGlzLl9pbml0KCk7XHJcblxyXG4gICAgRm91bmRhdGlvbi5yZWdpc3RlclBsdWdpbih0aGlzLCAnU2xpZGVyJyk7XHJcbiAgICBGb3VuZGF0aW9uLktleWJvYXJkLnJlZ2lzdGVyKCdTbGlkZXInLCB7XHJcbiAgICAgICdsdHInOiB7XHJcbiAgICAgICAgJ0FSUk9XX1JJR0hUJzogJ2luY3JlYXNlJyxcclxuICAgICAgICAnQVJST1dfVVAnOiAnaW5jcmVhc2UnLFxyXG4gICAgICAgICdBUlJPV19ET1dOJzogJ2RlY3JlYXNlJyxcclxuICAgICAgICAnQVJST1dfTEVGVCc6ICdkZWNyZWFzZScsXHJcbiAgICAgICAgJ1NISUZUX0FSUk9XX1JJR0hUJzogJ2luY3JlYXNlX2Zhc3QnLFxyXG4gICAgICAgICdTSElGVF9BUlJPV19VUCc6ICdpbmNyZWFzZV9mYXN0JyxcclxuICAgICAgICAnU0hJRlRfQVJST1dfRE9XTic6ICdkZWNyZWFzZV9mYXN0JyxcclxuICAgICAgICAnU0hJRlRfQVJST1dfTEVGVCc6ICdkZWNyZWFzZV9mYXN0J1xyXG4gICAgICB9LFxyXG4gICAgICAncnRsJzoge1xyXG4gICAgICAgICdBUlJPV19MRUZUJzogJ2luY3JlYXNlJyxcclxuICAgICAgICAnQVJST1dfUklHSFQnOiAnZGVjcmVhc2UnLFxyXG4gICAgICAgICdTSElGVF9BUlJPV19MRUZUJzogJ2luY3JlYXNlX2Zhc3QnLFxyXG4gICAgICAgICdTSElGVF9BUlJPV19SSUdIVCc6ICdkZWNyZWFzZV9mYXN0J1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpbGl6ZXMgdGhlIHBsdWdpbiBieSByZWFkaW5nL3NldHRpbmcgYXR0cmlidXRlcywgY3JlYXRpbmcgY29sbGVjdGlvbnMgYW5kIHNldHRpbmcgdGhlIGluaXRpYWwgcG9zaXRpb24gb2YgdGhlIGhhbmRsZShzKS5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9pbml0KCkge1xyXG4gICAgdGhpcy5pbnB1dHMgPSB0aGlzLiRlbGVtZW50LmZpbmQoJ2lucHV0Jyk7XHJcbiAgICB0aGlzLmhhbmRsZXMgPSB0aGlzLiRlbGVtZW50LmZpbmQoJ1tkYXRhLXNsaWRlci1oYW5kbGVdJyk7XHJcblxyXG4gICAgdGhpcy4kaGFuZGxlID0gdGhpcy5oYW5kbGVzLmVxKDApO1xyXG4gICAgdGhpcy4kaW5wdXQgPSB0aGlzLmlucHV0cy5sZW5ndGggPyB0aGlzLmlucHV0cy5lcSgwKSA6ICQoYCMke3RoaXMuJGhhbmRsZS5hdHRyKCdhcmlhLWNvbnRyb2xzJyl9YCk7XHJcbiAgICB0aGlzLiRmaWxsID0gdGhpcy4kZWxlbWVudC5maW5kKCdbZGF0YS1zbGlkZXItZmlsbF0nKS5jc3ModGhpcy5vcHRpb25zLnZlcnRpY2FsID8gJ2hlaWdodCcgOiAnd2lkdGgnLCAwKTtcclxuXHJcbiAgICB2YXIgaXNEYmwgPSBmYWxzZSxcclxuICAgICAgICBfdGhpcyA9IHRoaXM7XHJcbiAgICBpZiAodGhpcy5vcHRpb25zLmRpc2FibGVkIHx8IHRoaXMuJGVsZW1lbnQuaGFzQ2xhc3ModGhpcy5vcHRpb25zLmRpc2FibGVkQ2xhc3MpKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5kaXNhYmxlZCA9IHRydWU7XHJcbiAgICAgIHRoaXMuJGVsZW1lbnQuYWRkQ2xhc3ModGhpcy5vcHRpb25zLmRpc2FibGVkQ2xhc3MpO1xyXG4gICAgfVxyXG4gICAgaWYgKCF0aGlzLmlucHV0cy5sZW5ndGgpIHtcclxuICAgICAgdGhpcy5pbnB1dHMgPSAkKCkuYWRkKHRoaXMuJGlucHV0KTtcclxuICAgICAgdGhpcy5vcHRpb25zLmJpbmRpbmcgPSB0cnVlO1xyXG4gICAgfVxyXG4gICAgdGhpcy5fc2V0SW5pdEF0dHIoMCk7XHJcbiAgICB0aGlzLl9ldmVudHModGhpcy4kaGFuZGxlKTtcclxuXHJcbiAgICBpZiAodGhpcy5oYW5kbGVzWzFdKSB7XHJcbiAgICAgIHRoaXMub3B0aW9ucy5kb3VibGVTaWRlZCA9IHRydWU7XHJcbiAgICAgIHRoaXMuJGhhbmRsZTIgPSB0aGlzLmhhbmRsZXMuZXEoMSk7XHJcbiAgICAgIHRoaXMuJGlucHV0MiA9IHRoaXMuaW5wdXRzLmxlbmd0aCA+IDEgPyB0aGlzLmlucHV0cy5lcSgxKSA6ICQoYCMke3RoaXMuJGhhbmRsZTIuYXR0cignYXJpYS1jb250cm9scycpfWApO1xyXG5cclxuICAgICAgaWYgKCF0aGlzLmlucHV0c1sxXSkge1xyXG4gICAgICAgIHRoaXMuaW5wdXRzID0gdGhpcy5pbnB1dHMuYWRkKHRoaXMuJGlucHV0Mik7XHJcbiAgICAgIH1cclxuICAgICAgaXNEYmwgPSB0cnVlO1xyXG5cclxuICAgICAgdGhpcy5fc2V0SGFuZGxlUG9zKHRoaXMuJGhhbmRsZSwgdGhpcy5vcHRpb25zLmluaXRpYWxTdGFydCwgdHJ1ZSwgZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIF90aGlzLl9zZXRIYW5kbGVQb3MoX3RoaXMuJGhhbmRsZTIsIF90aGlzLm9wdGlvbnMuaW5pdGlhbEVuZCwgdHJ1ZSk7XHJcbiAgICAgIH0pO1xyXG4gICAgICAvLyB0aGlzLiRoYW5kbGUudHJpZ2dlckhhbmRsZXIoJ2NsaWNrLnpmLnNsaWRlcicpO1xyXG4gICAgICB0aGlzLl9zZXRJbml0QXR0cigxKTtcclxuICAgICAgdGhpcy5fZXZlbnRzKHRoaXMuJGhhbmRsZTIpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghaXNEYmwpIHtcclxuICAgICAgdGhpcy5fc2V0SGFuZGxlUG9zKHRoaXMuJGhhbmRsZSwgdGhpcy5vcHRpb25zLmluaXRpYWxTdGFydCwgdHJ1ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZXRzIHRoZSBwb3NpdGlvbiBvZiB0aGUgc2VsZWN0ZWQgaGFuZGxlIGFuZCBmaWxsIGJhci5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqIEBwYXJhbSB7alF1ZXJ5fSAkaG5kbCAtIHRoZSBzZWxlY3RlZCBoYW5kbGUgdG8gbW92ZS5cclxuICAgKiBAcGFyYW0ge051bWJlcn0gbG9jYXRpb24gLSBmbG9hdGluZyBwb2ludCBiZXR3ZWVuIHRoZSBzdGFydCBhbmQgZW5kIHZhbHVlcyBvZiB0aGUgc2xpZGVyIGJhci5cclxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYiAtIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGZpcmUgb24gY29tcGxldGlvbi5cclxuICAgKiBAZmlyZXMgU2xpZGVyI21vdmVkXHJcbiAgICogQGZpcmVzIFNsaWRlciNjaGFuZ2VkXHJcbiAgICovXHJcbiAgX3NldEhhbmRsZVBvcygkaG5kbCwgbG9jYXRpb24sIG5vSW52ZXJ0LCBjYikge1xyXG4gICAgLy8gZG9uJ3QgbW92ZSBpZiB0aGUgc2xpZGVyIGhhcyBiZWVuIGRpc2FibGVkIHNpbmNlIGl0cyBpbml0aWFsaXphdGlvblxyXG4gICAgaWYgKHRoaXMuJGVsZW1lbnQuaGFzQ2xhc3ModGhpcy5vcHRpb25zLmRpc2FibGVkQ2xhc3MpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIC8vbWlnaHQgbmVlZCB0byBhbHRlciB0aGF0IHNsaWdodGx5IGZvciBiYXJzIHRoYXQgd2lsbCBoYXZlIG9kZCBudW1iZXIgc2VsZWN0aW9ucy5cclxuICAgIGxvY2F0aW9uID0gcGFyc2VGbG9hdChsb2NhdGlvbik7Ly9vbiBpbnB1dCBjaGFuZ2UgZXZlbnRzLCBjb252ZXJ0IHN0cmluZyB0byBudW1iZXIuLi5ncnVtYmxlLlxyXG5cclxuICAgIC8vIHByZXZlbnQgc2xpZGVyIGZyb20gcnVubmluZyBvdXQgb2YgYm91bmRzLCBpZiB2YWx1ZSBleGNlZWRzIHRoZSBsaW1pdHMgc2V0IHRocm91Z2ggb3B0aW9ucywgb3ZlcnJpZGUgdGhlIHZhbHVlIHRvIG1pbi9tYXhcclxuICAgIGlmIChsb2NhdGlvbiA8IHRoaXMub3B0aW9ucy5zdGFydCkgeyBsb2NhdGlvbiA9IHRoaXMub3B0aW9ucy5zdGFydDsgfVxyXG4gICAgZWxzZSBpZiAobG9jYXRpb24gPiB0aGlzLm9wdGlvbnMuZW5kKSB7IGxvY2F0aW9uID0gdGhpcy5vcHRpb25zLmVuZDsgfVxyXG5cclxuICAgIHZhciBpc0RibCA9IHRoaXMub3B0aW9ucy5kb3VibGVTaWRlZDtcclxuXHJcbiAgICBpZiAoaXNEYmwpIHsgLy90aGlzIGJsb2NrIGlzIHRvIHByZXZlbnQgMiBoYW5kbGVzIGZyb20gY3Jvc3NpbmcgZWFjaG90aGVyLiBDb3VsZC9zaG91bGQgYmUgaW1wcm92ZWQuXHJcbiAgICAgIGlmICh0aGlzLmhhbmRsZXMuaW5kZXgoJGhuZGwpID09PSAwKSB7XHJcbiAgICAgICAgdmFyIGgyVmFsID0gcGFyc2VGbG9hdCh0aGlzLiRoYW5kbGUyLmF0dHIoJ2FyaWEtdmFsdWVub3cnKSk7XHJcbiAgICAgICAgbG9jYXRpb24gPSBsb2NhdGlvbiA+PSBoMlZhbCA/IGgyVmFsIC0gdGhpcy5vcHRpb25zLnN0ZXAgOiBsb2NhdGlvbjtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB2YXIgaDFWYWwgPSBwYXJzZUZsb2F0KHRoaXMuJGhhbmRsZS5hdHRyKCdhcmlhLXZhbHVlbm93JykpO1xyXG4gICAgICAgIGxvY2F0aW9uID0gbG9jYXRpb24gPD0gaDFWYWwgPyBoMVZhbCArIHRoaXMub3B0aW9ucy5zdGVwIDogbG9jYXRpb247XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvL3RoaXMgaXMgZm9yIHNpbmdsZS1oYW5kbGVkIHZlcnRpY2FsIHNsaWRlcnMsIGl0IGFkanVzdHMgdGhlIHZhbHVlIHRvIGFjY291bnQgZm9yIHRoZSBzbGlkZXIgYmVpbmcgXCJ1cHNpZGUtZG93blwiXHJcbiAgICAvL2ZvciBjbGljayBhbmQgZHJhZyBldmVudHMsIGl0J3Mgd2VpcmQgZHVlIHRvIHRoZSBzY2FsZSgtMSwgMSkgY3NzIHByb3BlcnR5XHJcbiAgICBpZiAodGhpcy5vcHRpb25zLnZlcnRpY2FsICYmICFub0ludmVydCkge1xyXG4gICAgICBsb2NhdGlvbiA9IHRoaXMub3B0aW9ucy5lbmQgLSBsb2NhdGlvbjtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzLFxyXG4gICAgICAgIHZlcnQgPSB0aGlzLm9wdGlvbnMudmVydGljYWwsXHJcbiAgICAgICAgaE9yVyA9IHZlcnQgPyAnaGVpZ2h0JyA6ICd3aWR0aCcsXHJcbiAgICAgICAgbE9yVCA9IHZlcnQgPyAndG9wJyA6ICdsZWZ0JyxcclxuICAgICAgICBoYW5kbGVEaW0gPSAkaG5kbFswXS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVtoT3JXXSxcclxuICAgICAgICBlbGVtRGltID0gdGhpcy4kZWxlbWVudFswXS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKVtoT3JXXSxcclxuICAgICAgICAvL3BlcmNlbnRhZ2Ugb2YgYmFyIG1pbi9tYXggdmFsdWUgYmFzZWQgb24gY2xpY2sgb3IgZHJhZyBwb2ludFxyXG4gICAgICAgIHBjdE9mQmFyID0gcGVyY2VudChsb2NhdGlvbiAtIHRoaXMub3B0aW9ucy5zdGFydCwgdGhpcy5vcHRpb25zLmVuZCAtIHRoaXMub3B0aW9ucy5zdGFydCkudG9GaXhlZCgyKSxcclxuICAgICAgICAvL251bWJlciBvZiBhY3R1YWwgcGl4ZWxzIHRvIHNoaWZ0IHRoZSBoYW5kbGUsIGJhc2VkIG9uIHRoZSBwZXJjZW50YWdlIG9idGFpbmVkIGFib3ZlXHJcbiAgICAgICAgcHhUb01vdmUgPSAoZWxlbURpbSAtIGhhbmRsZURpbSkgKiBwY3RPZkJhcixcclxuICAgICAgICAvL3BlcmNlbnRhZ2Ugb2YgYmFyIHRvIHNoaWZ0IHRoZSBoYW5kbGVcclxuICAgICAgICBtb3ZlbWVudCA9IChwZXJjZW50KHB4VG9Nb3ZlLCBlbGVtRGltKSAqIDEwMCkudG9GaXhlZCh0aGlzLm9wdGlvbnMuZGVjaW1hbCk7XHJcbiAgICAgICAgLy9maXhpbmcgdGhlIGRlY2ltYWwgdmFsdWUgZm9yIHRoZSBsb2NhdGlvbiBudW1iZXIsIGlzIHBhc3NlZCB0byBvdGhlciBtZXRob2RzIGFzIGEgZml4ZWQgZmxvYXRpbmctcG9pbnQgdmFsdWVcclxuICAgICAgICBsb2NhdGlvbiA9IHBhcnNlRmxvYXQobG9jYXRpb24udG9GaXhlZCh0aGlzLm9wdGlvbnMuZGVjaW1hbCkpO1xyXG4gICAgICAgIC8vIGRlY2xhcmUgZW1wdHkgb2JqZWN0IGZvciBjc3MgYWRqdXN0bWVudHMsIG9ubHkgdXNlZCB3aXRoIDIgaGFuZGxlZC1zbGlkZXJzXHJcbiAgICB2YXIgY3NzID0ge307XHJcblxyXG4gICAgdGhpcy5fc2V0VmFsdWVzKCRobmRsLCBsb2NhdGlvbik7XHJcblxyXG4gICAgLy8gVE9ETyB1cGRhdGUgdG8gY2FsY3VsYXRlIGJhc2VkIG9uIHZhbHVlcyBzZXQgdG8gcmVzcGVjdGl2ZSBpbnB1dHM/P1xyXG4gICAgaWYgKGlzRGJsKSB7XHJcbiAgICAgIHZhciBpc0xlZnRIbmRsID0gdGhpcy5oYW5kbGVzLmluZGV4KCRobmRsKSA9PT0gMCxcclxuICAgICAgICAgIC8vZW1wdHkgdmFyaWFibGUsIHdpbGwgYmUgdXNlZCBmb3IgbWluLWhlaWdodC93aWR0aCBmb3IgZmlsbCBiYXJcclxuICAgICAgICAgIGRpbSxcclxuICAgICAgICAgIC8vcGVyY2VudGFnZSB3L2ggb2YgdGhlIGhhbmRsZSBjb21wYXJlZCB0byB0aGUgc2xpZGVyIGJhclxyXG4gICAgICAgICAgaGFuZGxlUGN0ID0gIH5+KHBlcmNlbnQoaGFuZGxlRGltLCBlbGVtRGltKSAqIDEwMCk7XHJcbiAgICAgIC8vaWYgbGVmdCBoYW5kbGUsIHRoZSBtYXRoIGlzIHNsaWdodGx5IGRpZmZlcmVudCB0aGFuIGlmIGl0J3MgdGhlIHJpZ2h0IGhhbmRsZSwgYW5kIHRoZSBsZWZ0L3RvcCBwcm9wZXJ0eSBuZWVkcyB0byBiZSBjaGFuZ2VkIGZvciB0aGUgZmlsbCBiYXJcclxuICAgICAgaWYgKGlzTGVmdEhuZGwpIHtcclxuICAgICAgICAvL2xlZnQgb3IgdG9wIHBlcmNlbnRhZ2UgdmFsdWUgdG8gYXBwbHkgdG8gdGhlIGZpbGwgYmFyLlxyXG4gICAgICAgIGNzc1tsT3JUXSA9IGAke21vdmVtZW50fSVgO1xyXG4gICAgICAgIC8vY2FsY3VsYXRlIHRoZSBuZXcgbWluLWhlaWdodC93aWR0aCBmb3IgdGhlIGZpbGwgYmFyLlxyXG4gICAgICAgIGRpbSA9IHBhcnNlRmxvYXQodGhpcy4kaGFuZGxlMlswXS5zdHlsZVtsT3JUXSkgLSBtb3ZlbWVudCArIGhhbmRsZVBjdDtcclxuICAgICAgICAvL3RoaXMgY2FsbGJhY2sgaXMgbmVjZXNzYXJ5IHRvIHByZXZlbnQgZXJyb3JzIGFuZCBhbGxvdyB0aGUgcHJvcGVyIHBsYWNlbWVudCBhbmQgaW5pdGlhbGl6YXRpb24gb2YgYSAyLWhhbmRsZWQgc2xpZGVyXHJcbiAgICAgICAgLy9wbHVzLCBpdCBtZWFucyB3ZSBkb24ndCBjYXJlIGlmICdkaW0nIGlzTmFOIG9uIGluaXQsIGl0IHdvbid0IGJlIGluIHRoZSBmdXR1cmUuXHJcbiAgICAgICAgaWYgKGNiICYmIHR5cGVvZiBjYiA9PT0gJ2Z1bmN0aW9uJykgeyBjYigpOyB9Ly90aGlzIGlzIG9ubHkgbmVlZGVkIGZvciB0aGUgaW5pdGlhbGl6YXRpb24gb2YgMiBoYW5kbGVkIHNsaWRlcnNcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICAvL2p1c3QgY2FjaGluZyB0aGUgdmFsdWUgb2YgdGhlIGxlZnQvYm90dG9tIGhhbmRsZSdzIGxlZnQvdG9wIHByb3BlcnR5XHJcbiAgICAgICAgdmFyIGhhbmRsZVBvcyA9IHBhcnNlRmxvYXQodGhpcy4kaGFuZGxlWzBdLnN0eWxlW2xPclRdKTtcclxuICAgICAgICAvL2NhbGN1bGF0ZSB0aGUgbmV3IG1pbi1oZWlnaHQvd2lkdGggZm9yIHRoZSBmaWxsIGJhci4gVXNlIGlzTmFOIHRvIHByZXZlbnQgZmFsc2UgcG9zaXRpdmVzIGZvciBudW1iZXJzIDw9IDBcclxuICAgICAgICAvL2Jhc2VkIG9uIHRoZSBwZXJjZW50YWdlIG9mIG1vdmVtZW50IG9mIHRoZSBoYW5kbGUgYmVpbmcgbWFuaXB1bGF0ZWQsIGxlc3MgdGhlIG9wcG9zaW5nIGhhbmRsZSdzIGxlZnQvdG9wIHBvc2l0aW9uLCBwbHVzIHRoZSBwZXJjZW50YWdlIHcvaCBvZiB0aGUgaGFuZGxlIGl0c2VsZlxyXG4gICAgICAgIGRpbSA9IG1vdmVtZW50IC0gKGlzTmFOKGhhbmRsZVBvcykgPyB0aGlzLm9wdGlvbnMuaW5pdGlhbFN0YXJ0LygodGhpcy5vcHRpb25zLmVuZC10aGlzLm9wdGlvbnMuc3RhcnQpLzEwMCkgOiBoYW5kbGVQb3MpICsgaGFuZGxlUGN0O1xyXG4gICAgICB9XHJcbiAgICAgIC8vIGFzc2lnbiB0aGUgbWluLWhlaWdodC93aWR0aCB0byBvdXIgY3NzIG9iamVjdFxyXG4gICAgICBjc3NbYG1pbi0ke2hPcld9YF0gPSBgJHtkaW19JWA7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy4kZWxlbWVudC5vbmUoJ2ZpbmlzaGVkLnpmLmFuaW1hdGUnLCBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAgICAgKiBGaXJlcyB3aGVuIHRoZSBoYW5kbGUgaXMgZG9uZSBtb3ZpbmcuXHJcbiAgICAgICAgICAgICAgICAgICAgICogQGV2ZW50IFNsaWRlciNtb3ZlZFxyXG4gICAgICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLiRlbGVtZW50LnRyaWdnZXIoJ21vdmVkLnpmLnNsaWRlcicsIFskaG5kbF0pO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgLy9iZWNhdXNlIHdlIGRvbid0IGtub3cgZXhhY3RseSBob3cgdGhlIGhhbmRsZSB3aWxsIGJlIG1vdmVkLCBjaGVjayB0aGUgYW1vdW50IG9mIHRpbWUgaXQgc2hvdWxkIHRha2UgdG8gbW92ZS5cclxuICAgIHZhciBtb3ZlVGltZSA9IHRoaXMuJGVsZW1lbnQuZGF0YSgnZHJhZ2dpbmcnKSA/IDEwMDAvNjAgOiB0aGlzLm9wdGlvbnMubW92ZVRpbWU7XHJcblxyXG4gICAgRm91bmRhdGlvbi5Nb3ZlKG1vdmVUaW1lLCAkaG5kbCwgZnVuY3Rpb24oKSB7XHJcbiAgICAgIC8vYWRqdXN0aW5nIHRoZSBsZWZ0L3RvcCBwcm9wZXJ0eSBvZiB0aGUgaGFuZGxlLCBiYXNlZCBvbiB0aGUgcGVyY2VudGFnZSBjYWxjdWxhdGVkIGFib3ZlXHJcbiAgICAgICRobmRsLmNzcyhsT3JULCBgJHttb3ZlbWVudH0lYCk7XHJcblxyXG4gICAgICBpZiAoIV90aGlzLm9wdGlvbnMuZG91YmxlU2lkZWQpIHtcclxuICAgICAgICAvL2lmIHNpbmdsZS1oYW5kbGVkLCBhIHNpbXBsZSBtZXRob2QgdG8gZXhwYW5kIHRoZSBmaWxsIGJhclxyXG4gICAgICAgIF90aGlzLiRmaWxsLmNzcyhoT3JXLCBgJHtwY3RPZkJhciAqIDEwMH0lYCk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgLy9vdGhlcndpc2UsIHVzZSB0aGUgY3NzIG9iamVjdCB3ZSBjcmVhdGVkIGFib3ZlXHJcbiAgICAgICAgX3RoaXMuJGZpbGwuY3NzKGNzcyk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmlyZXMgd2hlbiB0aGUgdmFsdWUgaGFzIG5vdCBiZWVuIGNoYW5nZSBmb3IgYSBnaXZlbiB0aW1lLlxyXG4gICAgICogQGV2ZW50IFNsaWRlciNjaGFuZ2VkXHJcbiAgICAgKi9cclxuICAgIGNsZWFyVGltZW91dChfdGhpcy50aW1lb3V0KTtcclxuICAgIF90aGlzLnRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7XHJcbiAgICAgIF90aGlzLiRlbGVtZW50LnRyaWdnZXIoJ2NoYW5nZWQuemYuc2xpZGVyJywgWyRobmRsXSk7XHJcbiAgICB9LCBfdGhpcy5vcHRpb25zLmNoYW5nZWREZWxheSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZXRzIHRoZSBpbml0aWFsIGF0dHJpYnV0ZSBmb3IgdGhlIHNsaWRlciBlbGVtZW50LlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIEBwcml2YXRlXHJcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGlkeCAtIGluZGV4IG9mIHRoZSBjdXJyZW50IGhhbmRsZS9pbnB1dCB0byB1c2UuXHJcbiAgICovXHJcbiAgX3NldEluaXRBdHRyKGlkeCkge1xyXG4gICAgdmFyIGlkID0gdGhpcy5pbnB1dHMuZXEoaWR4KS5hdHRyKCdpZCcpIHx8IEZvdW5kYXRpb24uR2V0WW9EaWdpdHMoNiwgJ3NsaWRlcicpO1xyXG4gICAgdGhpcy5pbnB1dHMuZXEoaWR4KS5hdHRyKHtcclxuICAgICAgJ2lkJzogaWQsXHJcbiAgICAgICdtYXgnOiB0aGlzLm9wdGlvbnMuZW5kLFxyXG4gICAgICAnbWluJzogdGhpcy5vcHRpb25zLnN0YXJ0LFxyXG4gICAgICAnc3RlcCc6IHRoaXMub3B0aW9ucy5zdGVwXHJcbiAgICB9KTtcclxuICAgIHRoaXMuaGFuZGxlcy5lcShpZHgpLmF0dHIoe1xyXG4gICAgICAncm9sZSc6ICdzbGlkZXInLFxyXG4gICAgICAnYXJpYS1jb250cm9scyc6IGlkLFxyXG4gICAgICAnYXJpYS12YWx1ZW1heCc6IHRoaXMub3B0aW9ucy5lbmQsXHJcbiAgICAgICdhcmlhLXZhbHVlbWluJzogdGhpcy5vcHRpb25zLnN0YXJ0LFxyXG4gICAgICAnYXJpYS12YWx1ZW5vdyc6IGlkeCA9PT0gMCA/IHRoaXMub3B0aW9ucy5pbml0aWFsU3RhcnQgOiB0aGlzLm9wdGlvbnMuaW5pdGlhbEVuZCxcclxuICAgICAgJ2FyaWEtb3JpZW50YXRpb24nOiB0aGlzLm9wdGlvbnMudmVydGljYWwgPyAndmVydGljYWwnIDogJ2hvcml6b250YWwnLFxyXG4gICAgICAndGFiaW5kZXgnOiAwXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFNldHMgdGhlIGlucHV0IGFuZCBgYXJpYS12YWx1ZW5vd2AgdmFsdWVzIGZvciB0aGUgc2xpZGVyIGVsZW1lbnQuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHByaXZhdGVcclxuICAgKiBAcGFyYW0ge2pRdWVyeX0gJGhhbmRsZSAtIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgaGFuZGxlLlxyXG4gICAqIEBwYXJhbSB7TnVtYmVyfSB2YWwgLSBmbG9hdGluZyBwb2ludCBvZiB0aGUgbmV3IHZhbHVlLlxyXG4gICAqL1xyXG4gIF9zZXRWYWx1ZXMoJGhhbmRsZSwgdmFsKSB7XHJcbiAgICB2YXIgaWR4ID0gdGhpcy5vcHRpb25zLmRvdWJsZVNpZGVkID8gdGhpcy5oYW5kbGVzLmluZGV4KCRoYW5kbGUpIDogMDtcclxuICAgIHRoaXMuaW5wdXRzLmVxKGlkeCkudmFsKHZhbCk7XHJcbiAgICAkaGFuZGxlLmF0dHIoJ2FyaWEtdmFsdWVub3cnLCB2YWwpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSGFuZGxlcyBldmVudHMgb24gdGhlIHNsaWRlciBlbGVtZW50LlxyXG4gICAqIENhbGN1bGF0ZXMgdGhlIG5ldyBsb2NhdGlvbiBvZiB0aGUgY3VycmVudCBoYW5kbGUuXHJcbiAgICogSWYgdGhlcmUgYXJlIHR3byBoYW5kbGVzIGFuZCB0aGUgYmFyIHdhcyBjbGlja2VkLCBpdCBkZXRlcm1pbmVzIHdoaWNoIGhhbmRsZSB0byBtb3ZlLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIEBwcml2YXRlXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IGUgLSB0aGUgYGV2ZW50YCBvYmplY3QgcGFzc2VkIGZyb20gdGhlIGxpc3RlbmVyLlxyXG4gICAqIEBwYXJhbSB7alF1ZXJ5fSAkaGFuZGxlIC0gdGhlIGN1cnJlbnQgaGFuZGxlIHRvIGNhbGN1bGF0ZSBmb3IsIGlmIHNlbGVjdGVkLlxyXG4gICAqIEBwYXJhbSB7TnVtYmVyfSB2YWwgLSBmbG9hdGluZyBwb2ludCBudW1iZXIgZm9yIHRoZSBuZXcgdmFsdWUgb2YgdGhlIHNsaWRlci5cclxuICAgKiBUT0RPIGNsZWFuIHRoaXMgdXAsIHRoZXJlJ3MgYSBsb3Qgb2YgcmVwZWF0ZWQgY29kZSBiZXR3ZWVuIHRoaXMgYW5kIHRoZSBfc2V0SGFuZGxlUG9zIGZuLlxyXG4gICAqL1xyXG4gIF9oYW5kbGVFdmVudChlLCAkaGFuZGxlLCB2YWwpIHtcclxuICAgIHZhciB2YWx1ZSwgaGFzVmFsO1xyXG4gICAgaWYgKCF2YWwpIHsvL2NsaWNrIG9yIGRyYWcgZXZlbnRzXHJcbiAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgdmFyIF90aGlzID0gdGhpcyxcclxuICAgICAgICAgIHZlcnRpY2FsID0gdGhpcy5vcHRpb25zLnZlcnRpY2FsLFxyXG4gICAgICAgICAgcGFyYW0gPSB2ZXJ0aWNhbCA/ICdoZWlnaHQnIDogJ3dpZHRoJyxcclxuICAgICAgICAgIGRpcmVjdGlvbiA9IHZlcnRpY2FsID8gJ3RvcCcgOiAnbGVmdCcsXHJcbiAgICAgICAgICBldmVudE9mZnNldCA9IHZlcnRpY2FsID8gZS5wYWdlWSA6IGUucGFnZVgsXHJcbiAgICAgICAgICBoYWxmT2ZIYW5kbGUgPSB0aGlzLiRoYW5kbGVbMF0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClbcGFyYW1dIC8gMixcclxuICAgICAgICAgIGJhckRpbSA9IHRoaXMuJGVsZW1lbnRbMF0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KClbcGFyYW1dLFxyXG4gICAgICAgICAgd2luZG93U2Nyb2xsID0gdmVydGljYWwgPyAkKHdpbmRvdykuc2Nyb2xsVG9wKCkgOiAkKHdpbmRvdykuc2Nyb2xsTGVmdCgpO1xyXG5cclxuXHJcbiAgICAgIHZhciBlbGVtT2Zmc2V0ID0gdGhpcy4kZWxlbWVudC5vZmZzZXQoKVtkaXJlY3Rpb25dO1xyXG5cclxuICAgICAgLy8gdG91Y2ggZXZlbnRzIGVtdWxhdGVkIGJ5IHRoZSB0b3VjaCB1dGlsIGdpdmUgcG9zaXRpb24gcmVsYXRpdmUgdG8gc2NyZWVuLCBhZGQgd2luZG93LnNjcm9sbCB0byBldmVudCBjb29yZGluYXRlcy4uLlxyXG4gICAgICAvLyBiZXN0IHdheSB0byBndWVzcyB0aGlzIGlzIHNpbXVsYXRlZCBpcyBpZiBjbGllbnRZID09IHBhZ2VZXHJcbiAgICAgIGlmIChlLmNsaWVudFkgPT09IGUucGFnZVkpIHsgZXZlbnRPZmZzZXQgPSBldmVudE9mZnNldCArIHdpbmRvd1Njcm9sbDsgfVxyXG4gICAgICB2YXIgZXZlbnRGcm9tQmFyID0gZXZlbnRPZmZzZXQgLSBlbGVtT2Zmc2V0O1xyXG4gICAgICB2YXIgYmFyWFk7XHJcbiAgICAgIGlmIChldmVudEZyb21CYXIgPCAwKSB7XHJcbiAgICAgICAgYmFyWFkgPSAwO1xyXG4gICAgICB9IGVsc2UgaWYgKGV2ZW50RnJvbUJhciA+IGJhckRpbSkge1xyXG4gICAgICAgIGJhclhZID0gYmFyRGltO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGJhclhZID0gZXZlbnRGcm9tQmFyO1xyXG4gICAgICB9XHJcbiAgICAgIG9mZnNldFBjdCA9IHBlcmNlbnQoYmFyWFksIGJhckRpbSk7XHJcblxyXG4gICAgICB2YWx1ZSA9ICh0aGlzLm9wdGlvbnMuZW5kIC0gdGhpcy5vcHRpb25zLnN0YXJ0KSAqIG9mZnNldFBjdCArIHRoaXMub3B0aW9ucy5zdGFydDtcclxuXHJcbiAgICAgIC8vIHR1cm4gZXZlcnl0aGluZyBhcm91bmQgZm9yIFJUTCwgeWF5IG1hdGghXHJcbiAgICAgIGlmIChGb3VuZGF0aW9uLnJ0bCgpICYmICF0aGlzLm9wdGlvbnMudmVydGljYWwpIHt2YWx1ZSA9IHRoaXMub3B0aW9ucy5lbmQgLSB2YWx1ZTt9XHJcblxyXG4gICAgICB2YWx1ZSA9IF90aGlzLl9hZGp1c3RWYWx1ZShudWxsLCB2YWx1ZSk7XHJcbiAgICAgIC8vYm9vbGVhbiBmbGFnIGZvciB0aGUgc2V0SGFuZGxlUG9zIGZuLCBzcGVjaWZpY2FsbHkgZm9yIHZlcnRpY2FsIHNsaWRlcnNcclxuICAgICAgaGFzVmFsID0gZmFsc2U7XHJcblxyXG4gICAgICBpZiAoISRoYW5kbGUpIHsvL2ZpZ3VyZSBvdXQgd2hpY2ggaGFuZGxlIGl0IGlzLCBwYXNzIGl0IHRvIHRoZSBuZXh0IGZ1bmN0aW9uLlxyXG4gICAgICAgIHZhciBmaXJzdEhuZGxQb3MgPSBhYnNQb3NpdGlvbih0aGlzLiRoYW5kbGUsIGRpcmVjdGlvbiwgYmFyWFksIHBhcmFtKSxcclxuICAgICAgICAgICAgc2VjbmRIbmRsUG9zID0gYWJzUG9zaXRpb24odGhpcy4kaGFuZGxlMiwgZGlyZWN0aW9uLCBiYXJYWSwgcGFyYW0pO1xyXG4gICAgICAgICAgICAkaGFuZGxlID0gZmlyc3RIbmRsUG9zIDw9IHNlY25kSG5kbFBvcyA/IHRoaXMuJGhhbmRsZSA6IHRoaXMuJGhhbmRsZTI7XHJcbiAgICAgIH1cclxuXHJcbiAgICB9IGVsc2Ugey8vY2hhbmdlIGV2ZW50IG9uIGlucHV0XHJcbiAgICAgIHZhbHVlID0gdGhpcy5fYWRqdXN0VmFsdWUobnVsbCwgdmFsKTtcclxuICAgICAgaGFzVmFsID0gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9zZXRIYW5kbGVQb3MoJGhhbmRsZSwgdmFsdWUsIGhhc1ZhbCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBZGp1c3RlcyB2YWx1ZSBmb3IgaGFuZGxlIGluIHJlZ2FyZCB0byBzdGVwIHZhbHVlLiByZXR1cm5zIGFkanVzdGVkIHZhbHVlXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHByaXZhdGVcclxuICAgKiBAcGFyYW0ge2pRdWVyeX0gJGhhbmRsZSAtIHRoZSBzZWxlY3RlZCBoYW5kbGUuXHJcbiAgICogQHBhcmFtIHtOdW1iZXJ9IHZhbHVlIC0gdmFsdWUgdG8gYWRqdXN0LiB1c2VkIGlmICRoYW5kbGUgaXMgZmFsc3lcclxuICAgKi9cclxuICBfYWRqdXN0VmFsdWUoJGhhbmRsZSwgdmFsdWUpIHtcclxuICAgIHZhciB2YWwsXHJcbiAgICAgIHN0ZXAgPSB0aGlzLm9wdGlvbnMuc3RlcCxcclxuICAgICAgZGl2ID0gcGFyc2VGbG9hdChzdGVwLzIpLFxyXG4gICAgICBsZWZ0LCBwcmV2X3ZhbCwgbmV4dF92YWw7XHJcbiAgICBpZiAoISEkaGFuZGxlKSB7XHJcbiAgICAgIHZhbCA9IHBhcnNlRmxvYXQoJGhhbmRsZS5hdHRyKCdhcmlhLXZhbHVlbm93JykpO1xyXG4gICAgfVxyXG4gICAgZWxzZSB7XHJcbiAgICAgIHZhbCA9IHZhbHVlO1xyXG4gICAgfVxyXG4gICAgbGVmdCA9IHZhbCAlIHN0ZXA7XHJcbiAgICBwcmV2X3ZhbCA9IHZhbCAtIGxlZnQ7XHJcbiAgICBuZXh0X3ZhbCA9IHByZXZfdmFsICsgc3RlcDtcclxuICAgIGlmIChsZWZ0ID09PSAwKSB7XHJcbiAgICAgIHJldHVybiB2YWw7XHJcbiAgICB9XHJcbiAgICB2YWwgPSB2YWwgPj0gcHJldl92YWwgKyBkaXYgPyBuZXh0X3ZhbCA6IHByZXZfdmFsO1xyXG4gICAgcmV0dXJuIHZhbDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZHMgZXZlbnQgbGlzdGVuZXJzIHRvIHRoZSBzbGlkZXIgZWxlbWVudHMuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHByaXZhdGVcclxuICAgKiBAcGFyYW0ge2pRdWVyeX0gJGhhbmRsZSAtIHRoZSBjdXJyZW50IGhhbmRsZSB0byBhcHBseSBsaXN0ZW5lcnMgdG8uXHJcbiAgICovXHJcbiAgX2V2ZW50cygkaGFuZGxlKSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzLFxyXG4gICAgICAgIGN1ckhhbmRsZSxcclxuICAgICAgICB0aW1lcjtcclxuXHJcbiAgICAgIHRoaXMuaW5wdXRzLm9mZignY2hhbmdlLnpmLnNsaWRlcicpLm9uKCdjaGFuZ2UuemYuc2xpZGVyJywgZnVuY3Rpb24oZSkge1xyXG4gICAgICAgIHZhciBpZHggPSBfdGhpcy5pbnB1dHMuaW5kZXgoJCh0aGlzKSk7XHJcbiAgICAgICAgX3RoaXMuX2hhbmRsZUV2ZW50KGUsIF90aGlzLmhhbmRsZXMuZXEoaWR4KSwgJCh0aGlzKS52YWwoKSk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgaWYgKHRoaXMub3B0aW9ucy5jbGlja1NlbGVjdCkge1xyXG4gICAgICAgIHRoaXMuJGVsZW1lbnQub2ZmKCdjbGljay56Zi5zbGlkZXInKS5vbignY2xpY2suemYuc2xpZGVyJywgZnVuY3Rpb24oZSkge1xyXG4gICAgICAgICAgaWYgKF90aGlzLiRlbGVtZW50LmRhdGEoJ2RyYWdnaW5nJykpIHsgcmV0dXJuIGZhbHNlOyB9XHJcblxyXG4gICAgICAgICAgaWYgKCEkKGUudGFyZ2V0KS5pcygnW2RhdGEtc2xpZGVyLWhhbmRsZV0nKSkge1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMub3B0aW9ucy5kb3VibGVTaWRlZCkge1xyXG4gICAgICAgICAgICAgIF90aGlzLl9oYW5kbGVFdmVudChlKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICBfdGhpcy5faGFuZGxlRXZlbnQoZSwgX3RoaXMuJGhhbmRsZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgfVxyXG5cclxuICAgIGlmICh0aGlzLm9wdGlvbnMuZHJhZ2dhYmxlKSB7XHJcbiAgICAgIHRoaXMuaGFuZGxlcy5hZGRUb3VjaCgpO1xyXG5cclxuICAgICAgdmFyICRib2R5ID0gJCgnYm9keScpO1xyXG4gICAgICAkaGFuZGxlXHJcbiAgICAgICAgLm9mZignbW91c2Vkb3duLnpmLnNsaWRlcicpXHJcbiAgICAgICAgLm9uKCdtb3VzZWRvd24uemYuc2xpZGVyJywgZnVuY3Rpb24oZSkge1xyXG4gICAgICAgICAgJGhhbmRsZS5hZGRDbGFzcygnaXMtZHJhZ2dpbmcnKTtcclxuICAgICAgICAgIF90aGlzLiRmaWxsLmFkZENsYXNzKCdpcy1kcmFnZ2luZycpOy8vXHJcbiAgICAgICAgICBfdGhpcy4kZWxlbWVudC5kYXRhKCdkcmFnZ2luZycsIHRydWUpO1xyXG5cclxuICAgICAgICAgIGN1ckhhbmRsZSA9ICQoZS5jdXJyZW50VGFyZ2V0KTtcclxuXHJcbiAgICAgICAgICAkYm9keS5vbignbW91c2Vtb3ZlLnpmLnNsaWRlcicsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICBfdGhpcy5faGFuZGxlRXZlbnQoZSwgY3VySGFuZGxlKTtcclxuXHJcbiAgICAgICAgICB9KS5vbignbW91c2V1cC56Zi5zbGlkZXInLCBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgICAgIF90aGlzLl9oYW5kbGVFdmVudChlLCBjdXJIYW5kbGUpO1xyXG5cclxuICAgICAgICAgICAgJGhhbmRsZS5yZW1vdmVDbGFzcygnaXMtZHJhZ2dpbmcnKTtcclxuICAgICAgICAgICAgX3RoaXMuJGZpbGwucmVtb3ZlQ2xhc3MoJ2lzLWRyYWdnaW5nJyk7XHJcbiAgICAgICAgICAgIF90aGlzLiRlbGVtZW50LmRhdGEoJ2RyYWdnaW5nJywgZmFsc2UpO1xyXG5cclxuICAgICAgICAgICAgJGJvZHkub2ZmKCdtb3VzZW1vdmUuemYuc2xpZGVyIG1vdXNldXAuemYuc2xpZGVyJyk7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgfSlcclxuICAgICAgLy8gcHJldmVudCBldmVudHMgdHJpZ2dlcmVkIGJ5IHRvdWNoXHJcbiAgICAgIC5vbignc2VsZWN0c3RhcnQuemYuc2xpZGVyIHRvdWNobW92ZS56Zi5zbGlkZXInLCBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAkaGFuZGxlLm9mZigna2V5ZG93bi56Zi5zbGlkZXInKS5vbigna2V5ZG93bi56Zi5zbGlkZXInLCBmdW5jdGlvbihlKSB7XHJcbiAgICAgIHZhciBfJGhhbmRsZSA9ICQodGhpcyksXHJcbiAgICAgICAgICBpZHggPSBfdGhpcy5vcHRpb25zLmRvdWJsZVNpZGVkID8gX3RoaXMuaGFuZGxlcy5pbmRleChfJGhhbmRsZSkgOiAwLFxyXG4gICAgICAgICAgb2xkVmFsdWUgPSBwYXJzZUZsb2F0KF90aGlzLmlucHV0cy5lcShpZHgpLnZhbCgpKSxcclxuICAgICAgICAgIG5ld1ZhbHVlO1xyXG5cclxuICAgICAgLy8gaGFuZGxlIGtleWJvYXJkIGV2ZW50IHdpdGgga2V5Ym9hcmQgdXRpbFxyXG4gICAgICBGb3VuZGF0aW9uLktleWJvYXJkLmhhbmRsZUtleShlLCAnU2xpZGVyJywge1xyXG4gICAgICAgIGRlY3JlYXNlOiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgIG5ld1ZhbHVlID0gb2xkVmFsdWUgLSBfdGhpcy5vcHRpb25zLnN0ZXA7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBpbmNyZWFzZTogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICBuZXdWYWx1ZSA9IG9sZFZhbHVlICsgX3RoaXMub3B0aW9ucy5zdGVwO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZGVjcmVhc2VfZmFzdDogZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICBuZXdWYWx1ZSA9IG9sZFZhbHVlIC0gX3RoaXMub3B0aW9ucy5zdGVwICogMTA7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBpbmNyZWFzZV9mYXN0OiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgIG5ld1ZhbHVlID0gb2xkVmFsdWUgKyBfdGhpcy5vcHRpb25zLnN0ZXAgKiAxMDtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGhhbmRsZWQ6IGZ1bmN0aW9uKCkgeyAvLyBvbmx5IHNldCBoYW5kbGUgcG9zIHdoZW4gZXZlbnQgd2FzIGhhbmRsZWQgc3BlY2lhbGx5XHJcbiAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICBfdGhpcy5fc2V0SGFuZGxlUG9zKF8kaGFuZGxlLCBuZXdWYWx1ZSwgdHJ1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgICAgLyppZiAobmV3VmFsdWUpIHsgLy8gaWYgcHJlc3NlZCBrZXkgaGFzIHNwZWNpYWwgZnVuY3Rpb24sIHVwZGF0ZSB2YWx1ZVxyXG4gICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICBfdGhpcy5fc2V0SGFuZGxlUG9zKF8kaGFuZGxlLCBuZXdWYWx1ZSk7XHJcbiAgICAgIH0qL1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBEZXN0cm95cyB0aGUgc2xpZGVyIHBsdWdpbi5cclxuICAgKi9cclxuICBkZXN0cm95KCkge1xyXG4gICAgdGhpcy5oYW5kbGVzLm9mZignLnpmLnNsaWRlcicpO1xyXG4gICAgdGhpcy5pbnB1dHMub2ZmKCcuemYuc2xpZGVyJyk7XHJcbiAgICB0aGlzLiRlbGVtZW50Lm9mZignLnpmLnNsaWRlcicpO1xyXG5cclxuICAgIEZvdW5kYXRpb24udW5yZWdpc3RlclBsdWdpbih0aGlzKTtcclxuICB9XHJcbn1cclxuXHJcblNsaWRlci5kZWZhdWx0cyA9IHtcclxuICAvKipcclxuICAgKiBNaW5pbXVtIHZhbHVlIGZvciB0aGUgc2xpZGVyIHNjYWxlLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAwXHJcbiAgICovXHJcbiAgc3RhcnQ6IDAsXHJcbiAgLyoqXHJcbiAgICogTWF4aW11bSB2YWx1ZSBmb3IgdGhlIHNsaWRlciBzY2FsZS5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgMTAwXHJcbiAgICovXHJcbiAgZW5kOiAxMDAsXHJcbiAgLyoqXHJcbiAgICogTWluaW11bSB2YWx1ZSBjaGFuZ2UgcGVyIGNoYW5nZSBldmVudC5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgMVxyXG4gICAqL1xyXG4gIHN0ZXA6IDEsXHJcbiAgLyoqXHJcbiAgICogVmFsdWUgYXQgd2hpY2ggdGhlIGhhbmRsZS9pbnB1dCAqKGxlZnQgaGFuZGxlL2ZpcnN0IGlucHV0KSogc2hvdWxkIGJlIHNldCB0byBvbiBpbml0aWFsaXphdGlvbi5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgMFxyXG4gICAqL1xyXG4gIGluaXRpYWxTdGFydDogMCxcclxuICAvKipcclxuICAgKiBWYWx1ZSBhdCB3aGljaCB0aGUgcmlnaHQgaGFuZGxlL3NlY29uZCBpbnB1dCBzaG91bGQgYmUgc2V0IHRvIG9uIGluaXRpYWxpemF0aW9uLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAxMDBcclxuICAgKi9cclxuICBpbml0aWFsRW5kOiAxMDAsXHJcbiAgLyoqXHJcbiAgICogQWxsb3dzIHRoZSBpbnB1dCB0byBiZSBsb2NhdGVkIG91dHNpZGUgdGhlIGNvbnRhaW5lciBhbmQgdmlzaWJsZS4gU2V0IHRvIGJ5IHRoZSBKU1xyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSBmYWxzZVxyXG4gICAqL1xyXG4gIGJpbmRpbmc6IGZhbHNlLFxyXG4gIC8qKlxyXG4gICAqIEFsbG93cyB0aGUgdXNlciB0byBjbGljay90YXAgb24gdGhlIHNsaWRlciBiYXIgdG8gc2VsZWN0IGEgdmFsdWUuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIHRydWVcclxuICAgKi9cclxuICBjbGlja1NlbGVjdDogdHJ1ZSxcclxuICAvKipcclxuICAgKiBTZXQgdG8gdHJ1ZSBhbmQgdXNlIHRoZSBgdmVydGljYWxgIGNsYXNzIHRvIGNoYW5nZSBhbGlnbm1lbnQgdG8gdmVydGljYWwuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIGZhbHNlXHJcbiAgICovXHJcbiAgdmVydGljYWw6IGZhbHNlLFxyXG4gIC8qKlxyXG4gICAqIEFsbG93cyB0aGUgdXNlciB0byBkcmFnIHRoZSBzbGlkZXIgaGFuZGxlKHMpIHRvIHNlbGVjdCBhIHZhbHVlLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSB0cnVlXHJcbiAgICovXHJcbiAgZHJhZ2dhYmxlOiB0cnVlLFxyXG4gIC8qKlxyXG4gICAqIERpc2FibGVzIHRoZSBzbGlkZXIgYW5kIHByZXZlbnRzIGV2ZW50IGxpc3RlbmVycyBmcm9tIGJlaW5nIGFwcGxpZWQuIERvdWJsZSBjaGVja2VkIGJ5IEpTIHdpdGggYGRpc2FibGVkQ2xhc3NgLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSBmYWxzZVxyXG4gICAqL1xyXG4gIGRpc2FibGVkOiBmYWxzZSxcclxuICAvKipcclxuICAgKiBBbGxvd3MgdGhlIHVzZSBvZiB0d28gaGFuZGxlcy4gRG91YmxlIGNoZWNrZWQgYnkgdGhlIEpTLiBDaGFuZ2VzIHNvbWUgbG9naWMgaGFuZGxpbmcuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIGZhbHNlXHJcbiAgICovXHJcbiAgZG91YmxlU2lkZWQ6IGZhbHNlLFxyXG4gIC8qKlxyXG4gICAqIFBvdGVudGlhbCBmdXR1cmUgZmVhdHVyZS5cclxuICAgKi9cclxuICAvLyBzdGVwczogMTAwLFxyXG4gIC8qKlxyXG4gICAqIE51bWJlciBvZiBkZWNpbWFsIHBsYWNlcyB0aGUgcGx1Z2luIHNob3VsZCBnbyB0byBmb3IgZmxvYXRpbmcgcG9pbnQgcHJlY2lzaW9uLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAyXHJcbiAgICovXHJcbiAgZGVjaW1hbDogMixcclxuICAvKipcclxuICAgKiBUaW1lIGRlbGF5IGZvciBkcmFnZ2VkIGVsZW1lbnRzLlxyXG4gICAqL1xyXG4gIC8vIGRyYWdEZWxheTogMCxcclxuICAvKipcclxuICAgKiBUaW1lLCBpbiBtcywgdG8gYW5pbWF0ZSB0aGUgbW92ZW1lbnQgb2YgYSBzbGlkZXIgaGFuZGxlIGlmIHVzZXIgY2xpY2tzL3RhcHMgb24gdGhlIGJhci4gTmVlZHMgdG8gYmUgbWFudWFsbHkgc2V0IGlmIHVwZGF0aW5nIHRoZSB0cmFuc2l0aW9uIHRpbWUgaW4gdGhlIFNhc3Mgc2V0dGluZ3MuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIDIwMFxyXG4gICAqL1xyXG4gIG1vdmVUaW1lOiAyMDAsLy91cGRhdGUgdGhpcyBpZiBjaGFuZ2luZyB0aGUgdHJhbnNpdGlvbiB0aW1lIGluIHRoZSBzYXNzXHJcbiAgLyoqXHJcbiAgICogQ2xhc3MgYXBwbGllZCB0byBkaXNhYmxlZCBzbGlkZXJzLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAnZGlzYWJsZWQnXHJcbiAgICovXHJcbiAgZGlzYWJsZWRDbGFzczogJ2Rpc2FibGVkJyxcclxuICAvKipcclxuICAgKiBXaWxsIGludmVydCB0aGUgZGVmYXVsdCBsYXlvdXQgZm9yIGEgdmVydGljYWw8c3BhbiBkYXRhLXRvb2x0aXAgdGl0bGU9XCJ3aG8gd291bGQgZG8gdGhpcz8/P1wiPiA8L3NwYW4+c2xpZGVyLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSBmYWxzZVxyXG4gICAqL1xyXG4gIGludmVydFZlcnRpY2FsOiBmYWxzZSxcclxuICAvKipcclxuICAgKiBNaWxsaXNlY29uZHMgYmVmb3JlIHRoZSBgY2hhbmdlZC56Zi1zbGlkZXJgIGV2ZW50IGlzIHRyaWdnZXJlZCBhZnRlciB2YWx1ZSBjaGFuZ2UuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIDUwMFxyXG4gICAqL1xyXG4gIGNoYW5nZWREZWxheTogNTAwXHJcbn07XHJcblxyXG5mdW5jdGlvbiBwZXJjZW50KGZyYWMsIG51bSkge1xyXG4gIHJldHVybiAoZnJhYyAvIG51bSk7XHJcbn1cclxuZnVuY3Rpb24gYWJzUG9zaXRpb24oJGhhbmRsZSwgZGlyLCBjbGlja1BvcywgcGFyYW0pIHtcclxuICByZXR1cm4gTWF0aC5hYnMoKCRoYW5kbGUucG9zaXRpb24oKVtkaXJdICsgKCRoYW5kbGVbcGFyYW1dKCkgLyAyKSkgLSBjbGlja1Bvcyk7XHJcbn1cclxuXHJcbi8vIFdpbmRvdyBleHBvcnRzXHJcbkZvdW5kYXRpb24ucGx1Z2luKFNsaWRlciwgJ1NsaWRlcicpO1xyXG5cclxufShqUXVlcnkpO1xyXG5cclxuLy8qKioqKioqKip0aGlzIGlzIGluIGNhc2Ugd2UgZ28gdG8gc3RhdGljLCBhYnNvbHV0ZSBwb3NpdGlvbnMgaW5zdGVhZCBvZiBkeW5hbWljIHBvc2l0aW9uaW5nKioqKioqKipcclxuLy8gdGhpcy5zZXRTdGVwcyhmdW5jdGlvbigpIHtcclxuLy8gICBfdGhpcy5fZXZlbnRzKCk7XHJcbi8vICAgdmFyIGluaXRTdGFydCA9IF90aGlzLm9wdGlvbnMucG9zaXRpb25zW190aGlzLm9wdGlvbnMuaW5pdGlhbFN0YXJ0IC0gMV0gfHwgbnVsbDtcclxuLy8gICB2YXIgaW5pdEVuZCA9IF90aGlzLm9wdGlvbnMuaW5pdGlhbEVuZCA/IF90aGlzLm9wdGlvbnMucG9zaXRpb25bX3RoaXMub3B0aW9ucy5pbml0aWFsRW5kIC0gMV0gOiBudWxsO1xyXG4vLyAgIGlmIChpbml0U3RhcnQgfHwgaW5pdEVuZCkge1xyXG4vLyAgICAgX3RoaXMuX2hhbmRsZUV2ZW50KGluaXRTdGFydCwgaW5pdEVuZCk7XHJcbi8vICAgfVxyXG4vLyB9KTtcclxuXHJcbi8vKioqKioqKioqKip0aGUgb3RoZXIgcGFydCBvZiBhYnNvbHV0ZSBwb3NpdGlvbnMqKioqKioqKioqKioqXHJcbi8vIFNsaWRlci5wcm90b3R5cGUuc2V0U3RlcHMgPSBmdW5jdGlvbihjYikge1xyXG4vLyAgIHZhciBwb3NDaGFuZ2UgPSB0aGlzLiRlbGVtZW50Lm91dGVyV2lkdGgoKSAvIHRoaXMub3B0aW9ucy5zdGVwcztcclxuLy8gICB2YXIgY291bnRlciA9IDBcclxuLy8gICB3aGlsZShjb3VudGVyIDwgdGhpcy5vcHRpb25zLnN0ZXBzKSB7XHJcbi8vICAgICBpZiAoY291bnRlcikge1xyXG4vLyAgICAgICB0aGlzLm9wdGlvbnMucG9zaXRpb25zLnB1c2godGhpcy5vcHRpb25zLnBvc2l0aW9uc1tjb3VudGVyIC0gMV0gKyBwb3NDaGFuZ2UpO1xyXG4vLyAgICAgfSBlbHNlIHtcclxuLy8gICAgICAgdGhpcy5vcHRpb25zLnBvc2l0aW9ucy5wdXNoKHBvc0NoYW5nZSk7XHJcbi8vICAgICB9XHJcbi8vICAgICBjb3VudGVyKys7XHJcbi8vICAgfVxyXG4vLyAgIGNiKCk7XHJcbi8vIH07XHJcbiIsIid1c2Ugc3RyaWN0JztcclxuXHJcbiFmdW5jdGlvbigkKSB7XHJcblxyXG4vKipcclxuICogU3RpY2t5IG1vZHVsZS5cclxuICogQG1vZHVsZSBmb3VuZGF0aW9uLnN0aWNreVxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLnRyaWdnZXJzXHJcbiAqIEByZXF1aXJlcyBmb3VuZGF0aW9uLnV0aWwubWVkaWFRdWVyeVxyXG4gKi9cclxuXHJcbmNsYXNzIFN0aWNreSB7XHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBhIHN0aWNreSB0aGluZy5cclxuICAgKiBAY2xhc3NcclxuICAgKiBAcGFyYW0ge2pRdWVyeX0gZWxlbWVudCAtIGpRdWVyeSBvYmplY3QgdG8gbWFrZSBzdGlja3kuXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBvcHRpb25zIG9iamVjdCBwYXNzZWQgd2hlbiBjcmVhdGluZyB0aGUgZWxlbWVudCBwcm9ncmFtbWF0aWNhbGx5LlxyXG4gICAqL1xyXG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQsIG9wdGlvbnMpIHtcclxuICAgIHRoaXMuJGVsZW1lbnQgPSBlbGVtZW50O1xyXG4gICAgdGhpcy5vcHRpb25zID0gJC5leHRlbmQoe30sIFN0aWNreS5kZWZhdWx0cywgdGhpcy4kZWxlbWVudC5kYXRhKCksIG9wdGlvbnMpO1xyXG5cclxuICAgIHRoaXMuX2luaXQoKTtcclxuXHJcbiAgICBGb3VuZGF0aW9uLnJlZ2lzdGVyUGx1Z2luKHRoaXMsICdTdGlja3knKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpYWxpemVzIHRoZSBzdGlja3kgZWxlbWVudCBieSBhZGRpbmcgY2xhc3NlcywgZ2V0dGluZy9zZXR0aW5nIGRpbWVuc2lvbnMsIGJyZWFrcG9pbnRzIGFuZCBhdHRyaWJ1dGVzXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfaW5pdCgpIHtcclxuICAgIHZhciAkcGFyZW50ID0gdGhpcy4kZWxlbWVudC5wYXJlbnQoJ1tkYXRhLXN0aWNreS1jb250YWluZXJdJyksXHJcbiAgICAgICAgaWQgPSB0aGlzLiRlbGVtZW50WzBdLmlkIHx8IEZvdW5kYXRpb24uR2V0WW9EaWdpdHMoNiwgJ3N0aWNreScpLFxyXG4gICAgICAgIF90aGlzID0gdGhpcztcclxuXHJcbiAgICBpZiAoISRwYXJlbnQubGVuZ3RoKSB7XHJcbiAgICAgIHRoaXMud2FzV3JhcHBlZCA9IHRydWU7XHJcbiAgICB9XHJcbiAgICB0aGlzLiRjb250YWluZXIgPSAkcGFyZW50Lmxlbmd0aCA/ICRwYXJlbnQgOiAkKHRoaXMub3B0aW9ucy5jb250YWluZXIpLndyYXBJbm5lcih0aGlzLiRlbGVtZW50KTtcclxuICAgIHRoaXMuJGNvbnRhaW5lci5hZGRDbGFzcyh0aGlzLm9wdGlvbnMuY29udGFpbmVyQ2xhc3MpO1xyXG5cclxuICAgIHRoaXMuJGVsZW1lbnQuYWRkQ2xhc3ModGhpcy5vcHRpb25zLnN0aWNreUNsYXNzKVxyXG4gICAgICAgICAgICAgICAgIC5hdHRyKHsnZGF0YS1yZXNpemUnOiBpZH0pO1xyXG5cclxuICAgIHRoaXMuc2Nyb2xsQ291bnQgPSB0aGlzLm9wdGlvbnMuY2hlY2tFdmVyeTtcclxuICAgIHRoaXMuaXNTdHVjayA9IGZhbHNlO1xyXG4gICAgJCh3aW5kb3cpLm9uZSgnbG9hZC56Zi5zdGlja3knLCBmdW5jdGlvbigpe1xyXG4gICAgICBpZihfdGhpcy5vcHRpb25zLmFuY2hvciAhPT0gJycpe1xyXG4gICAgICAgIF90aGlzLiRhbmNob3IgPSAkKCcjJyArIF90aGlzLm9wdGlvbnMuYW5jaG9yKTtcclxuICAgICAgfWVsc2V7XHJcbiAgICAgICAgX3RoaXMuX3BhcnNlUG9pbnRzKCk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIF90aGlzLl9zZXRTaXplcyhmdW5jdGlvbigpe1xyXG4gICAgICAgIF90aGlzLl9jYWxjKGZhbHNlKTtcclxuICAgICAgfSk7XHJcbiAgICAgIF90aGlzLl9ldmVudHMoaWQuc3BsaXQoJy0nKS5yZXZlcnNlKCkuam9pbignLScpKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogSWYgdXNpbmcgbXVsdGlwbGUgZWxlbWVudHMgYXMgYW5jaG9ycywgY2FsY3VsYXRlcyB0aGUgdG9wIGFuZCBib3R0b20gcGl4ZWwgdmFsdWVzIHRoZSBzdGlja3kgdGhpbmcgc2hvdWxkIHN0aWNrIGFuZCB1bnN0aWNrIG9uLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX3BhcnNlUG9pbnRzKCkge1xyXG4gICAgdmFyIHRvcCA9IHRoaXMub3B0aW9ucy50b3BBbmNob3IgPT0gXCJcIiA/IDEgOiB0aGlzLm9wdGlvbnMudG9wQW5jaG9yLFxyXG4gICAgICAgIGJ0bSA9IHRoaXMub3B0aW9ucy5idG1BbmNob3I9PSBcIlwiID8gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbEhlaWdodCA6IHRoaXMub3B0aW9ucy5idG1BbmNob3IsXHJcbiAgICAgICAgcHRzID0gW3RvcCwgYnRtXSxcclxuICAgICAgICBicmVha3MgPSB7fTtcclxuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBwdHMubGVuZ3RoOyBpIDwgbGVuICYmIHB0c1tpXTsgaSsrKSB7XHJcbiAgICAgIHZhciBwdDtcclxuICAgICAgaWYgKHR5cGVvZiBwdHNbaV0gPT09ICdudW1iZXInKSB7XHJcbiAgICAgICAgcHQgPSBwdHNbaV07XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdmFyIHBsYWNlID0gcHRzW2ldLnNwbGl0KCc6JyksXHJcbiAgICAgICAgICAgIGFuY2hvciA9ICQoYCMke3BsYWNlWzBdfWApO1xyXG5cclxuICAgICAgICBwdCA9IGFuY2hvci5vZmZzZXQoKS50b3A7XHJcbiAgICAgICAgaWYgKHBsYWNlWzFdICYmIHBsYWNlWzFdLnRvTG93ZXJDYXNlKCkgPT09ICdib3R0b20nKSB7XHJcbiAgICAgICAgICBwdCArPSBhbmNob3JbMF0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0O1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBicmVha3NbaV0gPSBwdDtcclxuICAgIH1cclxuXHJcblxyXG4gICAgdGhpcy5wb2ludHMgPSBicmVha3M7XHJcbiAgICByZXR1cm47XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBZGRzIGV2ZW50IGhhbmRsZXJzIGZvciB0aGUgc2Nyb2xsaW5nIGVsZW1lbnQuXHJcbiAgICogQHByaXZhdGVcclxuICAgKiBAcGFyYW0ge1N0cmluZ30gaWQgLSBwc3VlZG8tcmFuZG9tIGlkIGZvciB1bmlxdWUgc2Nyb2xsIGV2ZW50IGxpc3RlbmVyLlxyXG4gICAqL1xyXG4gIF9ldmVudHMoaWQpIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXMsXHJcbiAgICAgICAgc2Nyb2xsTGlzdGVuZXIgPSB0aGlzLnNjcm9sbExpc3RlbmVyID0gYHNjcm9sbC56Zi4ke2lkfWA7XHJcbiAgICBpZiAodGhpcy5pc09uKSB7IHJldHVybjsgfVxyXG4gICAgaWYgKHRoaXMuY2FuU3RpY2spIHtcclxuICAgICAgdGhpcy5pc09uID0gdHJ1ZTtcclxuICAgICAgJCh3aW5kb3cpLm9mZihzY3JvbGxMaXN0ZW5lcilcclxuICAgICAgICAgICAgICAgLm9uKHNjcm9sbExpc3RlbmVyLCBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgICAgICAgICAgaWYgKF90aGlzLnNjcm9sbENvdW50ID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICBfdGhpcy5zY3JvbGxDb3VudCA9IF90aGlzLm9wdGlvbnMuY2hlY2tFdmVyeTtcclxuICAgICAgICAgICAgICAgICAgIF90aGlzLl9zZXRTaXplcyhmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICAgX3RoaXMuX2NhbGMoZmFsc2UsIHdpbmRvdy5wYWdlWU9mZnNldCk7XHJcbiAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgX3RoaXMuc2Nyb2xsQ291bnQtLTtcclxuICAgICAgICAgICAgICAgICAgIF90aGlzLl9jYWxjKGZhbHNlLCB3aW5kb3cucGFnZVlPZmZzZXQpO1xyXG4gICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLiRlbGVtZW50Lm9mZigncmVzaXplbWUuemYudHJpZ2dlcicpXHJcbiAgICAgICAgICAgICAgICAgLm9uKCdyZXNpemVtZS56Zi50cmlnZ2VyJywgZnVuY3Rpb24oZSwgZWwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgX3RoaXMuX3NldFNpemVzKGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgIF90aGlzLl9jYWxjKGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICBpZiAoX3RoaXMuY2FuU3RpY2spIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghX3RoaXMuaXNPbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5fZXZlbnRzKGlkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKF90aGlzLmlzT24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgIF90aGlzLl9wYXVzZUxpc3RlbmVycyhzY3JvbGxMaXN0ZW5lcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogUmVtb3ZlcyBldmVudCBoYW5kbGVycyBmb3Igc2Nyb2xsIGFuZCBjaGFuZ2UgZXZlbnRzIG9uIGFuY2hvci5cclxuICAgKiBAZmlyZXMgU3RpY2t5I3BhdXNlXHJcbiAgICogQHBhcmFtIHtTdHJpbmd9IHNjcm9sbExpc3RlbmVyIC0gdW5pcXVlLCBuYW1lc3BhY2VkIHNjcm9sbCBsaXN0ZW5lciBhdHRhY2hlZCB0byBgd2luZG93YFxyXG4gICAqL1xyXG4gIF9wYXVzZUxpc3RlbmVycyhzY3JvbGxMaXN0ZW5lcikge1xyXG4gICAgdGhpcy5pc09uID0gZmFsc2U7XHJcbiAgICAkKHdpbmRvdykub2ZmKHNjcm9sbExpc3RlbmVyKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVzIHdoZW4gdGhlIHBsdWdpbiBpcyBwYXVzZWQgZHVlIHRvIHJlc2l6ZSBldmVudCBzaHJpbmtpbmcgdGhlIHZpZXcuXHJcbiAgICAgKiBAZXZlbnQgU3RpY2t5I3BhdXNlXHJcbiAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICovXHJcbiAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKCdwYXVzZS56Zi5zdGlja3knKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIENhbGxlZCBvbiBldmVyeSBgc2Nyb2xsYCBldmVudCBhbmQgb24gYF9pbml0YFxyXG4gICAqIGZpcmVzIGZ1bmN0aW9ucyBiYXNlZCBvbiBib29sZWFucyBhbmQgY2FjaGVkIHZhbHVlc1xyXG4gICAqIEBwYXJhbSB7Qm9vbGVhbn0gY2hlY2tTaXplcyAtIHRydWUgaWYgcGx1Z2luIHNob3VsZCByZWNhbGN1bGF0ZSBzaXplcyBhbmQgYnJlYWtwb2ludHMuXHJcbiAgICogQHBhcmFtIHtOdW1iZXJ9IHNjcm9sbCAtIGN1cnJlbnQgc2Nyb2xsIHBvc2l0aW9uIHBhc3NlZCBmcm9tIHNjcm9sbCBldmVudCBjYiBmdW5jdGlvbi4gSWYgbm90IHBhc3NlZCwgZGVmYXVsdHMgdG8gYHdpbmRvdy5wYWdlWU9mZnNldGAuXHJcbiAgICovXHJcbiAgX2NhbGMoY2hlY2tTaXplcywgc2Nyb2xsKSB7XHJcbiAgICBpZiAoY2hlY2tTaXplcykgeyB0aGlzLl9zZXRTaXplcygpOyB9XHJcblxyXG4gICAgaWYgKCF0aGlzLmNhblN0aWNrKSB7XHJcbiAgICAgIGlmICh0aGlzLmlzU3R1Y2spIHtcclxuICAgICAgICB0aGlzLl9yZW1vdmVTdGlja3kodHJ1ZSk7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghc2Nyb2xsKSB7IHNjcm9sbCA9IHdpbmRvdy5wYWdlWU9mZnNldDsgfVxyXG5cclxuICAgIGlmIChzY3JvbGwgPj0gdGhpcy50b3BQb2ludCkge1xyXG4gICAgICBpZiAoc2Nyb2xsIDw9IHRoaXMuYm90dG9tUG9pbnQpIHtcclxuICAgICAgICBpZiAoIXRoaXMuaXNTdHVjaykge1xyXG4gICAgICAgICAgdGhpcy5fc2V0U3RpY2t5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGlmICh0aGlzLmlzU3R1Y2spIHtcclxuICAgICAgICAgIHRoaXMuX3JlbW92ZVN0aWNreShmYWxzZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAodGhpcy5pc1N0dWNrKSB7XHJcbiAgICAgICAgdGhpcy5fcmVtb3ZlU3RpY2t5KHRydWUpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDYXVzZXMgdGhlICRlbGVtZW50IHRvIGJlY29tZSBzdHVjay5cclxuICAgKiBBZGRzIGBwb3NpdGlvbjogZml4ZWQ7YCwgYW5kIGhlbHBlciBjbGFzc2VzLlxyXG4gICAqIEBmaXJlcyBTdGlja3kjc3R1Y2t0b1xyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX3NldFN0aWNreSgpIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXMsXHJcbiAgICAgICAgc3RpY2tUbyA9IHRoaXMub3B0aW9ucy5zdGlja1RvLFxyXG4gICAgICAgIG1yZ24gPSBzdGlja1RvID09PSAndG9wJyA/ICdtYXJnaW5Ub3AnIDogJ21hcmdpbkJvdHRvbScsXHJcbiAgICAgICAgbm90U3R1Y2tUbyA9IHN0aWNrVG8gPT09ICd0b3AnID8gJ2JvdHRvbScgOiAndG9wJyxcclxuICAgICAgICBjc3MgPSB7fTtcclxuXHJcbiAgICBjc3NbbXJnbl0gPSBgJHt0aGlzLm9wdGlvbnNbbXJnbl19ZW1gO1xyXG4gICAgY3NzW3N0aWNrVG9dID0gMDtcclxuICAgIGNzc1tub3RTdHVja1RvXSA9ICdhdXRvJztcclxuICAgIGNzc1snbGVmdCddID0gdGhpcy4kY29udGFpbmVyLm9mZnNldCgpLmxlZnQgKyBwYXJzZUludCh3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSh0aGlzLiRjb250YWluZXJbMF0pW1wicGFkZGluZy1sZWZ0XCJdLCAxMCk7XHJcbiAgICB0aGlzLmlzU3R1Y2sgPSB0cnVlO1xyXG4gICAgdGhpcy4kZWxlbWVudC5yZW1vdmVDbGFzcyhgaXMtYW5jaG9yZWQgaXMtYXQtJHtub3RTdHVja1RvfWApXHJcbiAgICAgICAgICAgICAgICAgLmFkZENsYXNzKGBpcy1zdHVjayBpcy1hdC0ke3N0aWNrVG99YClcclxuICAgICAgICAgICAgICAgICAuY3NzKGNzcylcclxuICAgICAgICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICAgICAgKiBGaXJlcyB3aGVuIHRoZSAkZWxlbWVudCBoYXMgYmVjb21lIGBwb3NpdGlvbjogZml4ZWQ7YFxyXG4gICAgICAgICAgICAgICAgICAqIE5hbWVzcGFjZWQgdG8gYHRvcGAgb3IgYGJvdHRvbWAsIGUuZy4gYHN0aWNreS56Zi5zdHVja3RvOnRvcGBcclxuICAgICAgICAgICAgICAgICAgKiBAZXZlbnQgU3RpY2t5I3N0dWNrdG9cclxuICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAudHJpZ2dlcihgc3RpY2t5LnpmLnN0dWNrdG86JHtzdGlja1RvfWApO1xyXG4gICAgdGhpcy4kZWxlbWVudC5vbihcInRyYW5zaXRpb25lbmQgd2Via2l0VHJhbnNpdGlvbkVuZCBvVHJhbnNpdGlvbkVuZCBvdHJhbnNpdGlvbmVuZCBNU1RyYW5zaXRpb25FbmRcIiwgZnVuY3Rpb24oKSB7XHJcbiAgICAgIF90aGlzLl9zZXRTaXplcygpO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDYXVzZXMgdGhlICRlbGVtZW50IHRvIGJlY29tZSB1bnN0dWNrLlxyXG4gICAqIFJlbW92ZXMgYHBvc2l0aW9uOiBmaXhlZDtgLCBhbmQgaGVscGVyIGNsYXNzZXMuXHJcbiAgICogQWRkcyBvdGhlciBoZWxwZXIgY2xhc3Nlcy5cclxuICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlzVG9wIC0gdGVsbHMgdGhlIGZ1bmN0aW9uIGlmIHRoZSAkZWxlbWVudCBzaG91bGQgYW5jaG9yIHRvIHRoZSB0b3Agb3IgYm90dG9tIG9mIGl0cyAkYW5jaG9yIGVsZW1lbnQuXHJcbiAgICogQGZpcmVzIFN0aWNreSN1bnN0dWNrZnJvbVxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX3JlbW92ZVN0aWNreShpc1RvcCkge1xyXG4gICAgdmFyIHN0aWNrVG8gPSB0aGlzLm9wdGlvbnMuc3RpY2tUbyxcclxuICAgICAgICBzdGlja1RvVG9wID0gc3RpY2tUbyA9PT0gJ3RvcCcsXHJcbiAgICAgICAgY3NzID0ge30sXHJcbiAgICAgICAgYW5jaG9yUHQgPSAodGhpcy5wb2ludHMgPyB0aGlzLnBvaW50c1sxXSAtIHRoaXMucG9pbnRzWzBdIDogdGhpcy5hbmNob3JIZWlnaHQpIC0gdGhpcy5lbGVtSGVpZ2h0LFxyXG4gICAgICAgIG1yZ24gPSBzdGlja1RvVG9wID8gJ21hcmdpblRvcCcgOiAnbWFyZ2luQm90dG9tJyxcclxuICAgICAgICBub3RTdHVja1RvID0gc3RpY2tUb1RvcCA/ICdib3R0b20nIDogJ3RvcCcsXHJcbiAgICAgICAgdG9wT3JCb3R0b20gPSBpc1RvcCA/ICd0b3AnIDogJ2JvdHRvbSc7XHJcblxyXG4gICAgY3NzW21yZ25dID0gMDtcclxuXHJcbiAgICBjc3NbJ2JvdHRvbSddID0gJ2F1dG8nO1xyXG4gICAgaWYoaXNUb3ApIHtcclxuICAgICAgY3NzWyd0b3AnXSA9IDA7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBjc3NbJ3RvcCddID0gYW5jaG9yUHQ7XHJcbiAgICB9XHJcblxyXG4gICAgY3NzWydsZWZ0J10gPSAnJztcclxuICAgIHRoaXMuaXNTdHVjayA9IGZhbHNlO1xyXG4gICAgdGhpcy4kZWxlbWVudC5yZW1vdmVDbGFzcyhgaXMtc3R1Y2sgaXMtYXQtJHtzdGlja1RvfWApXHJcbiAgICAgICAgICAgICAgICAgLmFkZENsYXNzKGBpcy1hbmNob3JlZCBpcy1hdC0ke3RvcE9yQm90dG9tfWApXHJcbiAgICAgICAgICAgICAgICAgLmNzcyhjc3MpXHJcbiAgICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgICogRmlyZXMgd2hlbiB0aGUgJGVsZW1lbnQgaGFzIGJlY29tZSBhbmNob3JlZC5cclxuICAgICAgICAgICAgICAgICAgKiBOYW1lc3BhY2VkIHRvIGB0b3BgIG9yIGBib3R0b21gLCBlLmcuIGBzdGlja3kuemYudW5zdHVja2Zyb206Ym90dG9tYFxyXG4gICAgICAgICAgICAgICAgICAqIEBldmVudCBTdGlja3kjdW5zdHVja2Zyb21cclxuICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAudHJpZ2dlcihgc3RpY2t5LnpmLnVuc3R1Y2tmcm9tOiR7dG9wT3JCb3R0b219YCk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZXRzIHRoZSAkZWxlbWVudCBhbmQgJGNvbnRhaW5lciBzaXplcyBmb3IgcGx1Z2luLlxyXG4gICAqIENhbGxzIGBfc2V0QnJlYWtQb2ludHNgLlxyXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNiIC0gb3B0aW9uYWwgY2FsbGJhY2sgZnVuY3Rpb24gdG8gZmlyZSBvbiBjb21wbGV0aW9uIG9mIGBfc2V0QnJlYWtQb2ludHNgLlxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX3NldFNpemVzKGNiKSB7XHJcbiAgICB0aGlzLmNhblN0aWNrID0gRm91bmRhdGlvbi5NZWRpYVF1ZXJ5LmF0TGVhc3QodGhpcy5vcHRpb25zLnN0aWNreU9uKTtcclxuICAgIGlmICghdGhpcy5jYW5TdGljaykgeyBjYigpOyB9XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzLFxyXG4gICAgICAgIG5ld0VsZW1XaWR0aCA9IHRoaXMuJGNvbnRhaW5lclswXS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aCxcclxuICAgICAgICBjb21wID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUodGhpcy4kY29udGFpbmVyWzBdKSxcclxuICAgICAgICBwZG5nID0gcGFyc2VJbnQoY29tcFsncGFkZGluZy1yaWdodCddLCAxMCk7XHJcblxyXG4gICAgaWYgKHRoaXMuJGFuY2hvciAmJiB0aGlzLiRhbmNob3IubGVuZ3RoKSB7XHJcbiAgICAgIHRoaXMuYW5jaG9ySGVpZ2h0ID0gdGhpcy4kYW5jaG9yWzBdLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuX3BhcnNlUG9pbnRzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy4kZWxlbWVudC5jc3Moe1xyXG4gICAgICAnbWF4LXdpZHRoJzogYCR7bmV3RWxlbVdpZHRoIC0gcGRuZ31weGBcclxuICAgIH0pO1xyXG5cclxuICAgIHZhciBuZXdDb250YWluZXJIZWlnaHQgPSB0aGlzLiRlbGVtZW50WzBdLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmhlaWdodCB8fCB0aGlzLmNvbnRhaW5lckhlaWdodDtcclxuICAgIGlmICh0aGlzLiRlbGVtZW50LmNzcyhcImRpc3BsYXlcIikgPT0gXCJub25lXCIpIHtcclxuICAgICAgbmV3Q29udGFpbmVySGVpZ2h0ID0gMDtcclxuICAgIH1cclxuICAgIHRoaXMuY29udGFpbmVySGVpZ2h0ID0gbmV3Q29udGFpbmVySGVpZ2h0O1xyXG4gICAgdGhpcy4kY29udGFpbmVyLmNzcyh7XHJcbiAgICAgIGhlaWdodDogbmV3Q29udGFpbmVySGVpZ2h0XHJcbiAgICB9KTtcclxuICAgIHRoaXMuZWxlbUhlaWdodCA9IG5ld0NvbnRhaW5lckhlaWdodDtcclxuXHJcbiAgXHRpZiAodGhpcy5pc1N0dWNrKSB7XHJcbiAgXHRcdHRoaXMuJGVsZW1lbnQuY3NzKHtcImxlZnRcIjp0aGlzLiRjb250YWluZXIub2Zmc2V0KCkubGVmdCArIHBhcnNlSW50KGNvbXBbJ3BhZGRpbmctbGVmdCddLCAxMCl9KTtcclxuICBcdH1cclxuXHJcbiAgICB0aGlzLl9zZXRCcmVha1BvaW50cyhuZXdDb250YWluZXJIZWlnaHQsIGZ1bmN0aW9uKCkge1xyXG4gICAgICBpZiAoY2IpIHsgY2IoKTsgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBTZXRzIHRoZSB1cHBlciBhbmQgbG93ZXIgYnJlYWtwb2ludHMgZm9yIHRoZSBlbGVtZW50IHRvIGJlY29tZSBzdGlja3kvdW5zdGlja3kuXHJcbiAgICogQHBhcmFtIHtOdW1iZXJ9IGVsZW1IZWlnaHQgLSBweCB2YWx1ZSBmb3Igc3RpY2t5LiRlbGVtZW50IGhlaWdodCwgY2FsY3VsYXRlZCBieSBgX3NldFNpemVzYC5cclxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYiAtIG9wdGlvbmFsIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGJlIGNhbGxlZCBvbiBjb21wbGV0aW9uLlxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX3NldEJyZWFrUG9pbnRzKGVsZW1IZWlnaHQsIGNiKSB7XHJcbiAgICBpZiAoIXRoaXMuY2FuU3RpY2spIHtcclxuICAgICAgaWYgKGNiKSB7IGNiKCk7IH1cclxuICAgICAgZWxzZSB7IHJldHVybiBmYWxzZTsgfVxyXG4gICAgfVxyXG4gICAgdmFyIG1Ub3AgPSBlbUNhbGModGhpcy5vcHRpb25zLm1hcmdpblRvcCksXHJcbiAgICAgICAgbUJ0bSA9IGVtQ2FsYyh0aGlzLm9wdGlvbnMubWFyZ2luQm90dG9tKSxcclxuICAgICAgICB0b3BQb2ludCA9IHRoaXMucG9pbnRzID8gdGhpcy5wb2ludHNbMF0gOiB0aGlzLiRhbmNob3Iub2Zmc2V0KCkudG9wLFxyXG4gICAgICAgIGJvdHRvbVBvaW50ID0gdGhpcy5wb2ludHMgPyB0aGlzLnBvaW50c1sxXSA6IHRvcFBvaW50ICsgdGhpcy5hbmNob3JIZWlnaHQsXHJcbiAgICAgICAgLy8gdG9wUG9pbnQgPSB0aGlzLiRhbmNob3Iub2Zmc2V0KCkudG9wIHx8IHRoaXMucG9pbnRzWzBdLFxyXG4gICAgICAgIC8vIGJvdHRvbVBvaW50ID0gdG9wUG9pbnQgKyB0aGlzLmFuY2hvckhlaWdodCB8fCB0aGlzLnBvaW50c1sxXSxcclxuICAgICAgICB3aW5IZWlnaHQgPSB3aW5kb3cuaW5uZXJIZWlnaHQ7XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5zdGlja1RvID09PSAndG9wJykge1xyXG4gICAgICB0b3BQb2ludCAtPSBtVG9wO1xyXG4gICAgICBib3R0b21Qb2ludCAtPSAoZWxlbUhlaWdodCArIG1Ub3ApO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLm9wdGlvbnMuc3RpY2tUbyA9PT0gJ2JvdHRvbScpIHtcclxuICAgICAgdG9wUG9pbnQgLT0gKHdpbkhlaWdodCAtIChlbGVtSGVpZ2h0ICsgbUJ0bSkpO1xyXG4gICAgICBib3R0b21Qb2ludCAtPSAod2luSGVpZ2h0IC0gbUJ0bSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAvL3RoaXMgd291bGQgYmUgdGhlIHN0aWNrVG86IGJvdGggb3B0aW9uLi4uIHRyaWNreVxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMudG9wUG9pbnQgPSB0b3BQb2ludDtcclxuICAgIHRoaXMuYm90dG9tUG9pbnQgPSBib3R0b21Qb2ludDtcclxuXHJcbiAgICBpZiAoY2IpIHsgY2IoKTsgfVxyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRGVzdHJveXMgdGhlIGN1cnJlbnQgc3RpY2t5IGVsZW1lbnQuXHJcbiAgICogUmVzZXRzIHRoZSBlbGVtZW50IHRvIHRoZSB0b3AgcG9zaXRpb24gZmlyc3QuXHJcbiAgICogUmVtb3ZlcyBldmVudCBsaXN0ZW5lcnMsIEpTLWFkZGVkIGNzcyBwcm9wZXJ0aWVzIGFuZCBjbGFzc2VzLCBhbmQgdW53cmFwcyB0aGUgJGVsZW1lbnQgaWYgdGhlIEpTIGFkZGVkIHRoZSAkY29udGFpbmVyLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqL1xyXG4gIGRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLl9yZW1vdmVTdGlja3kodHJ1ZSk7XHJcblxyXG4gICAgdGhpcy4kZWxlbWVudC5yZW1vdmVDbGFzcyhgJHt0aGlzLm9wdGlvbnMuc3RpY2t5Q2xhc3N9IGlzLWFuY2hvcmVkIGlzLWF0LXRvcGApXHJcbiAgICAgICAgICAgICAgICAgLmNzcyh7XHJcbiAgICAgICAgICAgICAgICAgICBoZWlnaHQ6ICcnLFxyXG4gICAgICAgICAgICAgICAgICAgdG9wOiAnJyxcclxuICAgICAgICAgICAgICAgICAgIGJvdHRvbTogJycsXHJcbiAgICAgICAgICAgICAgICAgICAnbWF4LXdpZHRoJzogJydcclxuICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgIC5vZmYoJ3Jlc2l6ZW1lLnpmLnRyaWdnZXInKTtcclxuICAgIGlmICh0aGlzLiRhbmNob3IgJiYgdGhpcy4kYW5jaG9yLmxlbmd0aCkge1xyXG4gICAgICB0aGlzLiRhbmNob3Iub2ZmKCdjaGFuZ2UuemYuc3RpY2t5Jyk7XHJcbiAgICB9XHJcbiAgICAkKHdpbmRvdykub2ZmKHRoaXMuc2Nyb2xsTGlzdGVuZXIpO1xyXG5cclxuICAgIGlmICh0aGlzLndhc1dyYXBwZWQpIHtcclxuICAgICAgdGhpcy4kZWxlbWVudC51bndyYXAoKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuJGNvbnRhaW5lci5yZW1vdmVDbGFzcyh0aGlzLm9wdGlvbnMuY29udGFpbmVyQ2xhc3MpXHJcbiAgICAgICAgICAgICAgICAgICAgIC5jc3Moe1xyXG4gICAgICAgICAgICAgICAgICAgICAgIGhlaWdodDogJydcclxuICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBGb3VuZGF0aW9uLnVucmVnaXN0ZXJQbHVnaW4odGhpcyk7XHJcbiAgfVxyXG59XHJcblxyXG5TdGlja3kuZGVmYXVsdHMgPSB7XHJcbiAgLyoqXHJcbiAgICogQ3VzdG9taXphYmxlIGNvbnRhaW5lciB0ZW1wbGF0ZS4gQWRkIHlvdXIgb3duIGNsYXNzZXMgZm9yIHN0eWxpbmcgYW5kIHNpemluZy5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgJyZsdDtkaXYgZGF0YS1zdGlja3ktY29udGFpbmVyIGNsYXNzPVwic21hbGwtNiBjb2x1bW5zXCImZ3Q7Jmx0Oy9kaXYmZ3Q7J1xyXG4gICAqL1xyXG4gIGNvbnRhaW5lcjogJzxkaXYgZGF0YS1zdGlja3ktY29udGFpbmVyPjwvZGl2PicsXHJcbiAgLyoqXHJcbiAgICogTG9jYXRpb24gaW4gdGhlIHZpZXcgdGhlIGVsZW1lbnQgc3RpY2tzIHRvLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAndG9wJ1xyXG4gICAqL1xyXG4gIHN0aWNrVG86ICd0b3AnLFxyXG4gIC8qKlxyXG4gICAqIElmIGFuY2hvcmVkIHRvIGEgc2luZ2xlIGVsZW1lbnQsIHRoZSBpZCBvZiB0aGF0IGVsZW1lbnQuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlICdleGFtcGxlSWQnXHJcbiAgICovXHJcbiAgYW5jaG9yOiAnJyxcclxuICAvKipcclxuICAgKiBJZiB1c2luZyBtb3JlIHRoYW4gb25lIGVsZW1lbnQgYXMgYW5jaG9yIHBvaW50cywgdGhlIGlkIG9mIHRoZSB0b3AgYW5jaG9yLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAnZXhhbXBsZUlkOnRvcCdcclxuICAgKi9cclxuICB0b3BBbmNob3I6ICcnLFxyXG4gIC8qKlxyXG4gICAqIElmIHVzaW5nIG1vcmUgdGhhbiBvbmUgZWxlbWVudCBhcyBhbmNob3IgcG9pbnRzLCB0aGUgaWQgb2YgdGhlIGJvdHRvbSBhbmNob3IuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlICdleGFtcGxlSWQ6Ym90dG9tJ1xyXG4gICAqL1xyXG4gIGJ0bUFuY2hvcjogJycsXHJcbiAgLyoqXHJcbiAgICogTWFyZ2luLCBpbiBgZW1gJ3MgdG8gYXBwbHkgdG8gdGhlIHRvcCBvZiB0aGUgZWxlbWVudCB3aGVuIGl0IGJlY29tZXMgc3RpY2t5LlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAxXHJcbiAgICovXHJcbiAgbWFyZ2luVG9wOiAxLFxyXG4gIC8qKlxyXG4gICAqIE1hcmdpbiwgaW4gYGVtYCdzIHRvIGFwcGx5IHRvIHRoZSBib3R0b20gb2YgdGhlIGVsZW1lbnQgd2hlbiBpdCBiZWNvbWVzIHN0aWNreS5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgMVxyXG4gICAqL1xyXG4gIG1hcmdpbkJvdHRvbTogMSxcclxuICAvKipcclxuICAgKiBCcmVha3BvaW50IHN0cmluZyB0aGF0IGlzIHRoZSBtaW5pbXVtIHNjcmVlbiBzaXplIGFuIGVsZW1lbnQgc2hvdWxkIGJlY29tZSBzdGlja3kuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlICdtZWRpdW0nXHJcbiAgICovXHJcbiAgc3RpY2t5T246ICdtZWRpdW0nLFxyXG4gIC8qKlxyXG4gICAqIENsYXNzIGFwcGxpZWQgdG8gc3RpY2t5IGVsZW1lbnQsIGFuZCByZW1vdmVkIG9uIGRlc3RydWN0aW9uLiBGb3VuZGF0aW9uIGRlZmF1bHRzIHRvIGBzdGlja3lgLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAnc3RpY2t5J1xyXG4gICAqL1xyXG4gIHN0aWNreUNsYXNzOiAnc3RpY2t5JyxcclxuICAvKipcclxuICAgKiBDbGFzcyBhcHBsaWVkIHRvIHN0aWNreSBjb250YWluZXIuIEZvdW5kYXRpb24gZGVmYXVsdHMgdG8gYHN0aWNreS1jb250YWluZXJgLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAnc3RpY2t5LWNvbnRhaW5lcidcclxuICAgKi9cclxuICBjb250YWluZXJDbGFzczogJ3N0aWNreS1jb250YWluZXInLFxyXG4gIC8qKlxyXG4gICAqIE51bWJlciBvZiBzY3JvbGwgZXZlbnRzIGJldHdlZW4gdGhlIHBsdWdpbidzIHJlY2FsY3VsYXRpbmcgc3RpY2t5IHBvaW50cy4gU2V0dGluZyBpdCB0byBgMGAgd2lsbCBjYXVzZSBpdCB0byByZWNhbGMgZXZlcnkgc2Nyb2xsIGV2ZW50LCBzZXR0aW5nIGl0IHRvIGAtMWAgd2lsbCBwcmV2ZW50IHJlY2FsYyBvbiBzY3JvbGwuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIDUwXHJcbiAgICovXHJcbiAgY2hlY2tFdmVyeTogLTFcclxufTtcclxuXHJcbi8qKlxyXG4gKiBIZWxwZXIgZnVuY3Rpb24gdG8gY2FsY3VsYXRlIGVtIHZhbHVlc1xyXG4gKiBAcGFyYW0gTnVtYmVyIHtlbX0gLSBudW1iZXIgb2YgZW0ncyB0byBjYWxjdWxhdGUgaW50byBwaXhlbHNcclxuICovXHJcbmZ1bmN0aW9uIGVtQ2FsYyhlbSkge1xyXG4gIHJldHVybiBwYXJzZUludCh3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShkb2N1bWVudC5ib2R5LCBudWxsKS5mb250U2l6ZSwgMTApICogZW07XHJcbn1cclxuXHJcbi8vIFdpbmRvdyBleHBvcnRzXHJcbkZvdW5kYXRpb24ucGx1Z2luKFN0aWNreSwgJ1N0aWNreScpO1xyXG5cclxufShqUXVlcnkpO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG4hZnVuY3Rpb24oJCkge1xyXG5cclxuLyoqXHJcbiAqIFRhYnMgbW9kdWxlLlxyXG4gKiBAbW9kdWxlIGZvdW5kYXRpb24udGFic1xyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLmtleWJvYXJkXHJcbiAqIEByZXF1aXJlcyBmb3VuZGF0aW9uLnV0aWwudGltZXJBbmRJbWFnZUxvYWRlciBpZiB0YWJzIGNvbnRhaW4gaW1hZ2VzXHJcbiAqL1xyXG5cclxuY2xhc3MgVGFicyB7XHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiB0YWJzLlxyXG4gICAqIEBjbGFzc1xyXG4gICAqIEBmaXJlcyBUYWJzI2luaXRcclxuICAgKiBAcGFyYW0ge2pRdWVyeX0gZWxlbWVudCAtIGpRdWVyeSBvYmplY3QgdG8gbWFrZSBpbnRvIHRhYnMuXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMgLSBPdmVycmlkZXMgdG8gdGhlIGRlZmF1bHQgcGx1Z2luIHNldHRpbmdzLlxyXG4gICAqL1xyXG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQsIG9wdGlvbnMpIHtcclxuICAgIHRoaXMuJGVsZW1lbnQgPSBlbGVtZW50O1xyXG4gICAgdGhpcy5vcHRpb25zID0gJC5leHRlbmQoe30sIFRhYnMuZGVmYXVsdHMsIHRoaXMuJGVsZW1lbnQuZGF0YSgpLCBvcHRpb25zKTtcclxuXHJcbiAgICB0aGlzLl9pbml0KCk7XHJcbiAgICBGb3VuZGF0aW9uLnJlZ2lzdGVyUGx1Z2luKHRoaXMsICdUYWJzJyk7XHJcbiAgICBGb3VuZGF0aW9uLktleWJvYXJkLnJlZ2lzdGVyKCdUYWJzJywge1xyXG4gICAgICAnRU5URVInOiAnb3BlbicsXHJcbiAgICAgICdTUEFDRSc6ICdvcGVuJyxcclxuICAgICAgJ0FSUk9XX1JJR0hUJzogJ25leHQnLFxyXG4gICAgICAnQVJST1dfVVAnOiAncHJldmlvdXMnLFxyXG4gICAgICAnQVJST1dfRE9XTic6ICduZXh0JyxcclxuICAgICAgJ0FSUk9XX0xFRlQnOiAncHJldmlvdXMnXHJcbiAgICAgIC8vICdUQUInOiAnbmV4dCcsXHJcbiAgICAgIC8vICdTSElGVF9UQUInOiAncHJldmlvdXMnXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpYWxpemVzIHRoZSB0YWJzIGJ5IHNob3dpbmcgYW5kIGZvY3VzaW5nIChpZiBhdXRvRm9jdXM9dHJ1ZSkgdGhlIHByZXNldCBhY3RpdmUgdGFiLlxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX2luaXQoKSB7XHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG5cclxuICAgIHRoaXMuJHRhYlRpdGxlcyA9IHRoaXMuJGVsZW1lbnQuZmluZChgLiR7dGhpcy5vcHRpb25zLmxpbmtDbGFzc31gKTtcclxuICAgIHRoaXMuJHRhYkNvbnRlbnQgPSAkKGBbZGF0YS10YWJzLWNvbnRlbnQ9XCIke3RoaXMuJGVsZW1lbnRbMF0uaWR9XCJdYCk7XHJcblxyXG4gICAgdGhpcy4kdGFiVGl0bGVzLmVhY2goZnVuY3Rpb24oKXtcclxuICAgICAgdmFyICRlbGVtID0gJCh0aGlzKSxcclxuICAgICAgICAgICRsaW5rID0gJGVsZW0uZmluZCgnYScpLFxyXG4gICAgICAgICAgaXNBY3RpdmUgPSAkZWxlbS5oYXNDbGFzcygnaXMtYWN0aXZlJyksXHJcbiAgICAgICAgICBoYXNoID0gJGxpbmtbMF0uaGFzaC5zbGljZSgxKSxcclxuICAgICAgICAgIGxpbmtJZCA9ICRsaW5rWzBdLmlkID8gJGxpbmtbMF0uaWQgOiBgJHtoYXNofS1sYWJlbGAsXHJcbiAgICAgICAgICAkdGFiQ29udGVudCA9ICQoYCMke2hhc2h9YCk7XHJcblxyXG4gICAgICAkZWxlbS5hdHRyKHsncm9sZSc6ICdwcmVzZW50YXRpb24nfSk7XHJcblxyXG4gICAgICAkbGluay5hdHRyKHtcclxuICAgICAgICAncm9sZSc6ICd0YWInLFxyXG4gICAgICAgICdhcmlhLWNvbnRyb2xzJzogaGFzaCxcclxuICAgICAgICAnYXJpYS1zZWxlY3RlZCc6IGlzQWN0aXZlLFxyXG4gICAgICAgICdpZCc6IGxpbmtJZFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgICR0YWJDb250ZW50LmF0dHIoe1xyXG4gICAgICAgICdyb2xlJzogJ3RhYnBhbmVsJyxcclxuICAgICAgICAnYXJpYS1oaWRkZW4nOiAhaXNBY3RpdmUsXHJcbiAgICAgICAgJ2FyaWEtbGFiZWxsZWRieSc6IGxpbmtJZFxyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIGlmKGlzQWN0aXZlICYmIF90aGlzLm9wdGlvbnMuYXV0b0ZvY3VzKXtcclxuICAgICAgICAkbGluay5mb2N1cygpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuXHJcbiAgICBpZih0aGlzLm9wdGlvbnMubWF0Y2hIZWlnaHQpIHtcclxuICAgICAgdmFyICRpbWFnZXMgPSB0aGlzLiR0YWJDb250ZW50LmZpbmQoJ2ltZycpO1xyXG5cclxuICAgICAgaWYgKCRpbWFnZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgRm91bmRhdGlvbi5vbkltYWdlc0xvYWRlZCgkaW1hZ2VzLCB0aGlzLl9zZXRIZWlnaHQuYmluZCh0aGlzKSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5fc2V0SGVpZ2h0KCk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICB0aGlzLl9ldmVudHMoKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEFkZHMgZXZlbnQgaGFuZGxlcnMgZm9yIGl0ZW1zIHdpdGhpbiB0aGUgdGFicy5cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9ldmVudHMoKSB7XHJcbiAgICB0aGlzLl9hZGRLZXlIYW5kbGVyKCk7XHJcbiAgICB0aGlzLl9hZGRDbGlja0hhbmRsZXIoKTtcclxuICAgIHRoaXMuX3NldEhlaWdodE1xSGFuZGxlciA9IG51bGw7XHJcbiAgICBcclxuICAgIGlmICh0aGlzLm9wdGlvbnMubWF0Y2hIZWlnaHQpIHtcclxuICAgICAgdGhpcy5fc2V0SGVpZ2h0TXFIYW5kbGVyID0gdGhpcy5fc2V0SGVpZ2h0LmJpbmQodGhpcyk7XHJcbiAgICAgIFxyXG4gICAgICAkKHdpbmRvdykub24oJ2NoYW5nZWQuemYubWVkaWFxdWVyeScsIHRoaXMuX3NldEhlaWdodE1xSGFuZGxlcik7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBZGRzIGNsaWNrIGhhbmRsZXJzIGZvciBpdGVtcyB3aXRoaW4gdGhlIHRhYnMuXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfYWRkQ2xpY2tIYW5kbGVyKCkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuXHJcbiAgICB0aGlzLiRlbGVtZW50XHJcbiAgICAgIC5vZmYoJ2NsaWNrLnpmLnRhYnMnKVxyXG4gICAgICAub24oJ2NsaWNrLnpmLnRhYnMnLCBgLiR7dGhpcy5vcHRpb25zLmxpbmtDbGFzc31gLCBmdW5jdGlvbihlKXtcclxuICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICBpZiAoJCh0aGlzKS5oYXNDbGFzcygnaXMtYWN0aXZlJykpIHtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgX3RoaXMuX2hhbmRsZVRhYkNoYW5nZSgkKHRoaXMpKTtcclxuICAgICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBBZGRzIGtleWJvYXJkIGV2ZW50IGhhbmRsZXJzIGZvciBpdGVtcyB3aXRoaW4gdGhlIHRhYnMuXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfYWRkS2V5SGFuZGxlcigpIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICB2YXIgJGZpcnN0VGFiID0gX3RoaXMuJGVsZW1lbnQuZmluZCgnbGk6Zmlyc3Qtb2YtdHlwZScpO1xyXG4gICAgdmFyICRsYXN0VGFiID0gX3RoaXMuJGVsZW1lbnQuZmluZCgnbGk6bGFzdC1vZi10eXBlJyk7XHJcblxyXG4gICAgdGhpcy4kdGFiVGl0bGVzLm9mZigna2V5ZG93bi56Zi50YWJzJykub24oJ2tleWRvd24uemYudGFicycsIGZ1bmN0aW9uKGUpe1xyXG4gICAgICBpZiAoZS53aGljaCA9PT0gOSkgcmV0dXJuO1xyXG4gICAgICBcclxuXHJcbiAgICAgIHZhciAkZWxlbWVudCA9ICQodGhpcyksXHJcbiAgICAgICAgJGVsZW1lbnRzID0gJGVsZW1lbnQucGFyZW50KCd1bCcpLmNoaWxkcmVuKCdsaScpLFxyXG4gICAgICAgICRwcmV2RWxlbWVudCxcclxuICAgICAgICAkbmV4dEVsZW1lbnQ7XHJcblxyXG4gICAgICAkZWxlbWVudHMuZWFjaChmdW5jdGlvbihpKSB7XHJcbiAgICAgICAgaWYgKCQodGhpcykuaXMoJGVsZW1lbnQpKSB7XHJcbiAgICAgICAgICBpZiAoX3RoaXMub3B0aW9ucy53cmFwT25LZXlzKSB7XHJcbiAgICAgICAgICAgICRwcmV2RWxlbWVudCA9IGkgPT09IDAgPyAkZWxlbWVudHMubGFzdCgpIDogJGVsZW1lbnRzLmVxKGktMSk7XHJcbiAgICAgICAgICAgICRuZXh0RWxlbWVudCA9IGkgPT09ICRlbGVtZW50cy5sZW5ndGggLTEgPyAkZWxlbWVudHMuZmlyc3QoKSA6ICRlbGVtZW50cy5lcShpKzEpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgJHByZXZFbGVtZW50ID0gJGVsZW1lbnRzLmVxKE1hdGgubWF4KDAsIGktMSkpO1xyXG4gICAgICAgICAgICAkbmV4dEVsZW1lbnQgPSAkZWxlbWVudHMuZXEoTWF0aC5taW4oaSsxLCAkZWxlbWVudHMubGVuZ3RoLTEpKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgLy8gaGFuZGxlIGtleWJvYXJkIGV2ZW50IHdpdGgga2V5Ym9hcmQgdXRpbFxyXG4gICAgICBGb3VuZGF0aW9uLktleWJvYXJkLmhhbmRsZUtleShlLCAnVGFicycsIHtcclxuICAgICAgICBvcGVuOiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICRlbGVtZW50LmZpbmQoJ1tyb2xlPVwidGFiXCJdJykuZm9jdXMoKTtcclxuICAgICAgICAgIF90aGlzLl9oYW5kbGVUYWJDaGFuZ2UoJGVsZW1lbnQpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgcHJldmlvdXM6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgJHByZXZFbGVtZW50LmZpbmQoJ1tyb2xlPVwidGFiXCJdJykuZm9jdXMoKTtcclxuICAgICAgICAgIF90aGlzLl9oYW5kbGVUYWJDaGFuZ2UoJHByZXZFbGVtZW50KTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIG5leHQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgJG5leHRFbGVtZW50LmZpbmQoJ1tyb2xlPVwidGFiXCJdJykuZm9jdXMoKTtcclxuICAgICAgICAgIF90aGlzLl9oYW5kbGVUYWJDaGFuZ2UoJG5leHRFbGVtZW50KTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGhhbmRsZWQ6IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBPcGVucyB0aGUgdGFiIGAkdGFyZ2V0Q29udGVudGAgZGVmaW5lZCBieSBgJHRhcmdldGAuXHJcbiAgICogQHBhcmFtIHtqUXVlcnl9ICR0YXJnZXQgLSBUYWIgdG8gb3Blbi5cclxuICAgKiBAZmlyZXMgVGFicyNjaGFuZ2VcclxuICAgKiBAZnVuY3Rpb25cclxuICAgKi9cclxuICBfaGFuZGxlVGFiQ2hhbmdlKCR0YXJnZXQpIHtcclxuICAgIHZhciAkdGFiTGluayA9ICR0YXJnZXQuZmluZCgnW3JvbGU9XCJ0YWJcIl0nKSxcclxuICAgICAgICBoYXNoID0gJHRhYkxpbmtbMF0uaGFzaCxcclxuICAgICAgICAkdGFyZ2V0Q29udGVudCA9IHRoaXMuJHRhYkNvbnRlbnQuZmluZChoYXNoKSxcclxuICAgICAgICAkb2xkVGFiID0gdGhpcy4kZWxlbWVudC5cclxuICAgICAgICAgIGZpbmQoYC4ke3RoaXMub3B0aW9ucy5saW5rQ2xhc3N9LmlzLWFjdGl2ZWApXHJcbiAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ2lzLWFjdGl2ZScpXHJcbiAgICAgICAgICAuZmluZCgnW3JvbGU9XCJ0YWJcIl0nKVxyXG4gICAgICAgICAgLmF0dHIoeyAnYXJpYS1zZWxlY3RlZCc6ICdmYWxzZScgfSk7XHJcblxyXG4gICAgJChgIyR7JG9sZFRhYi5hdHRyKCdhcmlhLWNvbnRyb2xzJyl9YClcclxuICAgICAgLnJlbW92ZUNsYXNzKCdpcy1hY3RpdmUnKVxyXG4gICAgICAuYXR0cih7ICdhcmlhLWhpZGRlbic6ICd0cnVlJyB9KTtcclxuXHJcbiAgICAkdGFyZ2V0LmFkZENsYXNzKCdpcy1hY3RpdmUnKTtcclxuXHJcbiAgICAkdGFiTGluay5hdHRyKHsnYXJpYS1zZWxlY3RlZCc6ICd0cnVlJ30pO1xyXG5cclxuICAgICR0YXJnZXRDb250ZW50XHJcbiAgICAgIC5hZGRDbGFzcygnaXMtYWN0aXZlJylcclxuICAgICAgLmF0dHIoeydhcmlhLWhpZGRlbic6ICdmYWxzZSd9KTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVzIHdoZW4gdGhlIHBsdWdpbiBoYXMgc3VjY2Vzc2Z1bGx5IGNoYW5nZWQgdGFicy5cclxuICAgICAqIEBldmVudCBUYWJzI2NoYW5nZVxyXG4gICAgICovXHJcbiAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ2NoYW5nZS56Zi50YWJzJywgWyR0YXJnZXRdKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFB1YmxpYyBtZXRob2QgZm9yIHNlbGVjdGluZyBhIGNvbnRlbnQgcGFuZSB0byBkaXNwbGF5LlxyXG4gICAqIEBwYXJhbSB7alF1ZXJ5IHwgU3RyaW5nfSBlbGVtIC0galF1ZXJ5IG9iamVjdCBvciBzdHJpbmcgb2YgdGhlIGlkIG9mIHRoZSBwYW5lIHRvIGRpc3BsYXkuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICovXHJcbiAgc2VsZWN0VGFiKGVsZW0pIHtcclxuICAgIHZhciBpZFN0cjtcclxuXHJcbiAgICBpZiAodHlwZW9mIGVsZW0gPT09ICdvYmplY3QnKSB7XHJcbiAgICAgIGlkU3RyID0gZWxlbVswXS5pZDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGlkU3RyID0gZWxlbTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoaWRTdHIuaW5kZXhPZignIycpIDwgMCkge1xyXG4gICAgICBpZFN0ciA9IGAjJHtpZFN0cn1gO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciAkdGFyZ2V0ID0gdGhpcy4kdGFiVGl0bGVzLmZpbmQoYFtocmVmPVwiJHtpZFN0cn1cIl1gKS5wYXJlbnQoYC4ke3RoaXMub3B0aW9ucy5saW5rQ2xhc3N9YCk7XHJcblxyXG4gICAgdGhpcy5faGFuZGxlVGFiQ2hhbmdlKCR0YXJnZXQpO1xyXG4gIH07XHJcbiAgLyoqXHJcbiAgICogU2V0cyB0aGUgaGVpZ2h0IG9mIGVhY2ggcGFuZWwgdG8gdGhlIGhlaWdodCBvZiB0aGUgdGFsbGVzdCBwYW5lbC5cclxuICAgKiBJZiBlbmFibGVkIGluIG9wdGlvbnMsIGdldHMgY2FsbGVkIG9uIG1lZGlhIHF1ZXJ5IGNoYW5nZS5cclxuICAgKiBJZiBsb2FkaW5nIGNvbnRlbnQgdmlhIGV4dGVybmFsIHNvdXJjZSwgY2FuIGJlIGNhbGxlZCBkaXJlY3RseSBvciB3aXRoIF9yZWZsb3cuXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfc2V0SGVpZ2h0KCkge1xyXG4gICAgdmFyIG1heCA9IDA7XHJcbiAgICB0aGlzLiR0YWJDb250ZW50XHJcbiAgICAgIC5maW5kKGAuJHt0aGlzLm9wdGlvbnMucGFuZWxDbGFzc31gKVxyXG4gICAgICAuY3NzKCdoZWlnaHQnLCAnJylcclxuICAgICAgLmVhY2goZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgdmFyIHBhbmVsID0gJCh0aGlzKSxcclxuICAgICAgICAgICAgaXNBY3RpdmUgPSBwYW5lbC5oYXNDbGFzcygnaXMtYWN0aXZlJyk7XHJcblxyXG4gICAgICAgIGlmICghaXNBY3RpdmUpIHtcclxuICAgICAgICAgIHBhbmVsLmNzcyh7J3Zpc2liaWxpdHknOiAnaGlkZGVuJywgJ2Rpc3BsYXknOiAnYmxvY2snfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgdGVtcCA9IHRoaXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0O1xyXG5cclxuICAgICAgICBpZiAoIWlzQWN0aXZlKSB7XHJcbiAgICAgICAgICBwYW5lbC5jc3Moe1xyXG4gICAgICAgICAgICAndmlzaWJpbGl0eSc6ICcnLFxyXG4gICAgICAgICAgICAnZGlzcGxheSc6ICcnXHJcbiAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIG1heCA9IHRlbXAgPiBtYXggPyB0ZW1wIDogbWF4O1xyXG4gICAgICB9KVxyXG4gICAgICAuY3NzKCdoZWlnaHQnLCBgJHttYXh9cHhgKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlc3Ryb3lzIGFuIGluc3RhbmNlIG9mIGFuIHRhYnMuXHJcbiAgICogQGZpcmVzIFRhYnMjZGVzdHJveWVkXHJcbiAgICovXHJcbiAgZGVzdHJveSgpIHtcclxuICAgIHRoaXMuJGVsZW1lbnRcclxuICAgICAgLmZpbmQoYC4ke3RoaXMub3B0aW9ucy5saW5rQ2xhc3N9YClcclxuICAgICAgLm9mZignLnpmLnRhYnMnKS5oaWRlKCkuZW5kKClcclxuICAgICAgLmZpbmQoYC4ke3RoaXMub3B0aW9ucy5wYW5lbENsYXNzfWApXHJcbiAgICAgIC5oaWRlKCk7XHJcblxyXG4gICAgaWYgKHRoaXMub3B0aW9ucy5tYXRjaEhlaWdodCkge1xyXG4gICAgICBpZiAodGhpcy5fc2V0SGVpZ2h0TXFIYW5kbGVyICE9IG51bGwpIHtcclxuICAgICAgICAgJCh3aW5kb3cpLm9mZignY2hhbmdlZC56Zi5tZWRpYXF1ZXJ5JywgdGhpcy5fc2V0SGVpZ2h0TXFIYW5kbGVyKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIEZvdW5kYXRpb24udW5yZWdpc3RlclBsdWdpbih0aGlzKTtcclxuICB9XHJcbn1cclxuXHJcblRhYnMuZGVmYXVsdHMgPSB7XHJcbiAgLyoqXHJcbiAgICogQWxsb3dzIHRoZSB3aW5kb3cgdG8gc2Nyb2xsIHRvIGNvbnRlbnQgb2YgYWN0aXZlIHBhbmUgb24gbG9hZCBpZiBzZXQgdG8gdHJ1ZS5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgZmFsc2VcclxuICAgKi9cclxuICBhdXRvRm9jdXM6IGZhbHNlLFxyXG5cclxuICAvKipcclxuICAgKiBBbGxvd3Mga2V5Ym9hcmQgaW5wdXQgdG8gJ3dyYXAnIGFyb3VuZCB0aGUgdGFiIGxpbmtzLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSB0cnVlXHJcbiAgICovXHJcbiAgd3JhcE9uS2V5czogdHJ1ZSxcclxuXHJcbiAgLyoqXHJcbiAgICogQWxsb3dzIHRoZSB0YWIgY29udGVudCBwYW5lcyB0byBtYXRjaCBoZWlnaHRzIGlmIHNldCB0byB0cnVlLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSBmYWxzZVxyXG4gICAqL1xyXG4gIG1hdGNoSGVpZ2h0OiBmYWxzZSxcclxuXHJcbiAgLyoqXHJcbiAgICogQ2xhc3MgYXBwbGllZCB0byBgbGlgJ3MgaW4gdGFiIGxpbmsgbGlzdC5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgJ3RhYnMtdGl0bGUnXHJcbiAgICovXHJcbiAgbGlua0NsYXNzOiAndGFicy10aXRsZScsXHJcblxyXG4gIC8qKlxyXG4gICAqIENsYXNzIGFwcGxpZWQgdG8gdGhlIGNvbnRlbnQgY29udGFpbmVycy5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgJ3RhYnMtcGFuZWwnXHJcbiAgICovXHJcbiAgcGFuZWxDbGFzczogJ3RhYnMtcGFuZWwnXHJcbn07XHJcblxyXG5mdW5jdGlvbiBjaGVja0NsYXNzKCRlbGVtKXtcclxuICByZXR1cm4gJGVsZW0uaGFzQ2xhc3MoJ2lzLWFjdGl2ZScpO1xyXG59XHJcblxyXG4vLyBXaW5kb3cgZXhwb3J0c1xyXG5Gb3VuZGF0aW9uLnBsdWdpbihUYWJzLCAnVGFicycpO1xyXG5cclxufShqUXVlcnkpO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG4hZnVuY3Rpb24oJCkge1xyXG5cclxuLyoqXHJcbiAqIFRvZ2dsZXIgbW9kdWxlLlxyXG4gKiBAbW9kdWxlIGZvdW5kYXRpb24udG9nZ2xlclxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLm1vdGlvblxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLnRyaWdnZXJzXHJcbiAqL1xyXG5cclxuY2xhc3MgVG9nZ2xlciB7XHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBUb2dnbGVyLlxyXG4gICAqIEBjbGFzc1xyXG4gICAqIEBmaXJlcyBUb2dnbGVyI2luaXRcclxuICAgKiBAcGFyYW0ge09iamVjdH0gZWxlbWVudCAtIGpRdWVyeSBvYmplY3QgdG8gYWRkIHRoZSB0cmlnZ2VyIHRvLlxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gT3ZlcnJpZGVzIHRvIHRoZSBkZWZhdWx0IHBsdWdpbiBzZXR0aW5ncy5cclxuICAgKi9cclxuICBjb25zdHJ1Y3RvcihlbGVtZW50LCBvcHRpb25zKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50ID0gZWxlbWVudDtcclxuICAgIHRoaXMub3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBUb2dnbGVyLmRlZmF1bHRzLCBlbGVtZW50LmRhdGEoKSwgb3B0aW9ucyk7XHJcbiAgICB0aGlzLmNsYXNzTmFtZSA9ICcnO1xyXG5cclxuICAgIHRoaXMuX2luaXQoKTtcclxuICAgIHRoaXMuX2V2ZW50cygpO1xyXG5cclxuICAgIEZvdW5kYXRpb24ucmVnaXN0ZXJQbHVnaW4odGhpcywgJ1RvZ2dsZXInKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEluaXRpYWxpemVzIHRoZSBUb2dnbGVyIHBsdWdpbiBieSBwYXJzaW5nIHRoZSB0b2dnbGUgY2xhc3MgZnJvbSBkYXRhLXRvZ2dsZXIsIG9yIGFuaW1hdGlvbiBjbGFzc2VzIGZyb20gZGF0YS1hbmltYXRlLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX2luaXQoKSB7XHJcbiAgICB2YXIgaW5wdXQ7XHJcbiAgICAvLyBQYXJzZSBhbmltYXRpb24gY2xhc3NlcyBpZiB0aGV5IHdlcmUgc2V0XHJcbiAgICBpZiAodGhpcy5vcHRpb25zLmFuaW1hdGUpIHtcclxuICAgICAgaW5wdXQgPSB0aGlzLm9wdGlvbnMuYW5pbWF0ZS5zcGxpdCgnICcpO1xyXG5cclxuICAgICAgdGhpcy5hbmltYXRpb25JbiA9IGlucHV0WzBdO1xyXG4gICAgICB0aGlzLmFuaW1hdGlvbk91dCA9IGlucHV0WzFdIHx8IG51bGw7XHJcbiAgICB9XHJcbiAgICAvLyBPdGhlcndpc2UsIHBhcnNlIHRvZ2dsZSBjbGFzc1xyXG4gICAgZWxzZSB7XHJcbiAgICAgIGlucHV0ID0gdGhpcy4kZWxlbWVudC5kYXRhKCd0b2dnbGVyJyk7XHJcbiAgICAgIC8vIEFsbG93IGZvciBhIC4gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgc3RyaW5nXHJcbiAgICAgIHRoaXMuY2xhc3NOYW1lID0gaW5wdXRbMF0gPT09ICcuJyA/IGlucHV0LnNsaWNlKDEpIDogaW5wdXQ7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQWRkIEFSSUEgYXR0cmlidXRlcyB0byB0cmlnZ2Vyc1xyXG4gICAgdmFyIGlkID0gdGhpcy4kZWxlbWVudFswXS5pZDtcclxuICAgICQoYFtkYXRhLW9wZW49XCIke2lkfVwiXSwgW2RhdGEtY2xvc2U9XCIke2lkfVwiXSwgW2RhdGEtdG9nZ2xlPVwiJHtpZH1cIl1gKVxyXG4gICAgICAuYXR0cignYXJpYS1jb250cm9scycsIGlkKTtcclxuICAgIC8vIElmIHRoZSB0YXJnZXQgaXMgaGlkZGVuLCBhZGQgYXJpYS1oaWRkZW5cclxuICAgIHRoaXMuJGVsZW1lbnQuYXR0cignYXJpYS1leHBhbmRlZCcsIHRoaXMuJGVsZW1lbnQuaXMoJzpoaWRkZW4nKSA/IGZhbHNlIDogdHJ1ZSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbml0aWFsaXplcyBldmVudHMgZm9yIHRoZSB0b2dnbGUgdHJpZ2dlci5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKiBAcHJpdmF0ZVxyXG4gICAqL1xyXG4gIF9ldmVudHMoKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50Lm9mZigndG9nZ2xlLnpmLnRyaWdnZXInKS5vbigndG9nZ2xlLnpmLnRyaWdnZXInLCB0aGlzLnRvZ2dsZS5iaW5kKHRoaXMpKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFRvZ2dsZXMgdGhlIHRhcmdldCBjbGFzcyBvbiB0aGUgdGFyZ2V0IGVsZW1lbnQuIEFuIGV2ZW50IGlzIGZpcmVkIGZyb20gdGhlIG9yaWdpbmFsIHRyaWdnZXIgZGVwZW5kaW5nIG9uIGlmIHRoZSByZXN1bHRhbnQgc3RhdGUgd2FzIFwib25cIiBvciBcIm9mZlwiLlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqIEBmaXJlcyBUb2dnbGVyI29uXHJcbiAgICogQGZpcmVzIFRvZ2dsZXIjb2ZmXHJcbiAgICovXHJcbiAgdG9nZ2xlKCkge1xyXG4gICAgdGhpc1sgdGhpcy5vcHRpb25zLmFuaW1hdGUgPyAnX3RvZ2dsZUFuaW1hdGUnIDogJ190b2dnbGVDbGFzcyddKCk7XHJcbiAgfVxyXG5cclxuICBfdG9nZ2xlQ2xhc3MoKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50LnRvZ2dsZUNsYXNzKHRoaXMuY2xhc3NOYW1lKTtcclxuXHJcbiAgICB2YXIgaXNPbiA9IHRoaXMuJGVsZW1lbnQuaGFzQ2xhc3ModGhpcy5jbGFzc05hbWUpO1xyXG4gICAgaWYgKGlzT24pIHtcclxuICAgICAgLyoqXHJcbiAgICAgICAqIEZpcmVzIGlmIHRoZSB0YXJnZXQgZWxlbWVudCBoYXMgdGhlIGNsYXNzIGFmdGVyIGEgdG9nZ2xlLlxyXG4gICAgICAgKiBAZXZlbnQgVG9nZ2xlciNvblxyXG4gICAgICAgKi9cclxuICAgICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKCdvbi56Zi50b2dnbGVyJyk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgLyoqXHJcbiAgICAgICAqIEZpcmVzIGlmIHRoZSB0YXJnZXQgZWxlbWVudCBkb2VzIG5vdCBoYXZlIHRoZSBjbGFzcyBhZnRlciBhIHRvZ2dsZS5cclxuICAgICAgICogQGV2ZW50IFRvZ2dsZXIjb2ZmXHJcbiAgICAgICAqL1xyXG4gICAgICB0aGlzLiRlbGVtZW50LnRyaWdnZXIoJ29mZi56Zi50b2dnbGVyJyk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fdXBkYXRlQVJJQShpc09uKTtcclxuICB9XHJcblxyXG4gIF90b2dnbGVBbmltYXRlKCkge1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuXHJcbiAgICBpZiAodGhpcy4kZWxlbWVudC5pcygnOmhpZGRlbicpKSB7XHJcbiAgICAgIEZvdW5kYXRpb24uTW90aW9uLmFuaW1hdGVJbih0aGlzLiRlbGVtZW50LCB0aGlzLmFuaW1hdGlvbkluLCBmdW5jdGlvbigpIHtcclxuICAgICAgICBfdGhpcy5fdXBkYXRlQVJJQSh0cnVlKTtcclxuICAgICAgICB0aGlzLnRyaWdnZXIoJ29uLnpmLnRvZ2dsZXInKTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICBlbHNlIHtcclxuICAgICAgRm91bmRhdGlvbi5Nb3Rpb24uYW5pbWF0ZU91dCh0aGlzLiRlbGVtZW50LCB0aGlzLmFuaW1hdGlvbk91dCwgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgX3RoaXMuX3VwZGF0ZUFSSUEoZmFsc2UpO1xyXG4gICAgICAgIHRoaXMudHJpZ2dlcignb2ZmLnpmLnRvZ2dsZXInKTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBfdXBkYXRlQVJJQShpc09uKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50LmF0dHIoJ2FyaWEtZXhwYW5kZWQnLCBpc09uID8gdHJ1ZSA6IGZhbHNlKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIERlc3Ryb3lzIHRoZSBpbnN0YW5jZSBvZiBUb2dnbGVyIG9uIHRoZSBlbGVtZW50LlxyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqL1xyXG4gIGRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLiRlbGVtZW50Lm9mZignLnpmLnRvZ2dsZXInKTtcclxuICAgIEZvdW5kYXRpb24udW5yZWdpc3RlclBsdWdpbih0aGlzKTtcclxuICB9XHJcbn1cclxuXHJcblRvZ2dsZXIuZGVmYXVsdHMgPSB7XHJcbiAgLyoqXHJcbiAgICogVGVsbHMgdGhlIHBsdWdpbiBpZiB0aGUgZWxlbWVudCBzaG91bGQgYW5pbWF0ZWQgd2hlbiB0b2dnbGVkLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSBmYWxzZVxyXG4gICAqL1xyXG4gIGFuaW1hdGU6IGZhbHNlXHJcbn07XHJcblxyXG4vLyBXaW5kb3cgZXhwb3J0c1xyXG5Gb3VuZGF0aW9uLnBsdWdpbihUb2dnbGVyLCAnVG9nZ2xlcicpO1xyXG5cclxufShqUXVlcnkpO1xyXG4iLCIndXNlIHN0cmljdCc7XHJcblxyXG4hZnVuY3Rpb24oJCkge1xyXG5cclxuLyoqXHJcbiAqIFRvb2x0aXAgbW9kdWxlLlxyXG4gKiBAbW9kdWxlIGZvdW5kYXRpb24udG9vbHRpcFxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLmJveFxyXG4gKiBAcmVxdWlyZXMgZm91bmRhdGlvbi51dGlsLnRyaWdnZXJzXHJcbiAqL1xyXG5cclxuY2xhc3MgVG9vbHRpcCB7XHJcbiAgLyoqXHJcbiAgICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBhIFRvb2x0aXAuXHJcbiAgICogQGNsYXNzXHJcbiAgICogQGZpcmVzIFRvb2x0aXAjaW5pdFxyXG4gICAqIEBwYXJhbSB7alF1ZXJ5fSBlbGVtZW50IC0galF1ZXJ5IG9iamVjdCB0byBhdHRhY2ggYSB0b29sdGlwIHRvLlxyXG4gICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zIC0gb2JqZWN0IHRvIGV4dGVuZCB0aGUgZGVmYXVsdCBjb25maWd1cmF0aW9uLlxyXG4gICAqL1xyXG4gIGNvbnN0cnVjdG9yKGVsZW1lbnQsIG9wdGlvbnMpIHtcclxuICAgIHRoaXMuJGVsZW1lbnQgPSBlbGVtZW50O1xyXG4gICAgdGhpcy5vcHRpb25zID0gJC5leHRlbmQoe30sIFRvb2x0aXAuZGVmYXVsdHMsIHRoaXMuJGVsZW1lbnQuZGF0YSgpLCBvcHRpb25zKTtcclxuXHJcbiAgICB0aGlzLmlzQWN0aXZlID0gZmFsc2U7XHJcbiAgICB0aGlzLmlzQ2xpY2sgPSBmYWxzZTtcclxuICAgIHRoaXMuX2luaXQoKTtcclxuXHJcbiAgICBGb3VuZGF0aW9uLnJlZ2lzdGVyUGx1Z2luKHRoaXMsICdUb29sdGlwJyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBJbml0aWFsaXplcyB0aGUgdG9vbHRpcCBieSBzZXR0aW5nIHRoZSBjcmVhdGluZyB0aGUgdGlwIGVsZW1lbnQsIGFkZGluZyBpdCdzIHRleHQsIHNldHRpbmcgcHJpdmF0ZSB2YXJpYWJsZXMgYW5kIHNldHRpbmcgYXR0cmlidXRlcyBvbiB0aGUgYW5jaG9yLlxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX2luaXQoKSB7XHJcbiAgICB2YXIgZWxlbUlkID0gdGhpcy4kZWxlbWVudC5hdHRyKCdhcmlhLWRlc2NyaWJlZGJ5JykgfHwgRm91bmRhdGlvbi5HZXRZb0RpZ2l0cyg2LCAndG9vbHRpcCcpO1xyXG5cclxuICAgIHRoaXMub3B0aW9ucy5wb3NpdGlvbkNsYXNzID0gdGhpcy5vcHRpb25zLnBvc2l0aW9uQ2xhc3MgfHwgdGhpcy5fZ2V0UG9zaXRpb25DbGFzcyh0aGlzLiRlbGVtZW50KTtcclxuICAgIHRoaXMub3B0aW9ucy50aXBUZXh0ID0gdGhpcy5vcHRpb25zLnRpcFRleHQgfHwgdGhpcy4kZWxlbWVudC5hdHRyKCd0aXRsZScpO1xyXG4gICAgdGhpcy50ZW1wbGF0ZSA9IHRoaXMub3B0aW9ucy50ZW1wbGF0ZSA/ICQodGhpcy5vcHRpb25zLnRlbXBsYXRlKSA6IHRoaXMuX2J1aWxkVGVtcGxhdGUoZWxlbUlkKTtcclxuXHJcbiAgICB0aGlzLnRlbXBsYXRlLmFwcGVuZFRvKGRvY3VtZW50LmJvZHkpXHJcbiAgICAgICAgLnRleHQodGhpcy5vcHRpb25zLnRpcFRleHQpXHJcbiAgICAgICAgLmhpZGUoKTtcclxuXHJcbiAgICB0aGlzLiRlbGVtZW50LmF0dHIoe1xyXG4gICAgICAndGl0bGUnOiAnJyxcclxuICAgICAgJ2FyaWEtZGVzY3JpYmVkYnknOiBlbGVtSWQsXHJcbiAgICAgICdkYXRhLXlldGktYm94JzogZWxlbUlkLFxyXG4gICAgICAnZGF0YS10b2dnbGUnOiBlbGVtSWQsXHJcbiAgICAgICdkYXRhLXJlc2l6ZSc6IGVsZW1JZFxyXG4gICAgfSkuYWRkQ2xhc3ModGhpcy50cmlnZ2VyQ2xhc3MpO1xyXG5cclxuICAgIC8vaGVscGVyIHZhcmlhYmxlcyB0byB0cmFjayBtb3ZlbWVudCBvbiBjb2xsaXNpb25zXHJcbiAgICB0aGlzLnVzZWRQb3NpdGlvbnMgPSBbXTtcclxuICAgIHRoaXMuY291bnRlciA9IDQ7XHJcbiAgICB0aGlzLmNsYXNzQ2hhbmdlZCA9IGZhbHNlO1xyXG5cclxuICAgIHRoaXMuX2V2ZW50cygpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR3JhYnMgdGhlIGN1cnJlbnQgcG9zaXRpb25pbmcgY2xhc3MsIGlmIHByZXNlbnQsIGFuZCByZXR1cm5zIHRoZSB2YWx1ZSBvciBhbiBlbXB0eSBzdHJpbmcuXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfZ2V0UG9zaXRpb25DbGFzcyhlbGVtZW50KSB7XHJcbiAgICBpZiAoIWVsZW1lbnQpIHsgcmV0dXJuICcnOyB9XHJcbiAgICAvLyB2YXIgcG9zaXRpb24gPSBlbGVtZW50LmF0dHIoJ2NsYXNzJykubWF0Y2goL3RvcHxsZWZ0fHJpZ2h0L2cpO1xyXG4gICAgdmFyIHBvc2l0aW9uID0gZWxlbWVudFswXS5jbGFzc05hbWUubWF0Y2goL1xcYih0b3B8bGVmdHxyaWdodClcXGIvZyk7XHJcbiAgICAgICAgcG9zaXRpb24gPSBwb3NpdGlvbiA/IHBvc2l0aW9uWzBdIDogJyc7XHJcbiAgICByZXR1cm4gcG9zaXRpb247XHJcbiAgfTtcclxuICAvKipcclxuICAgKiBidWlsZHMgdGhlIHRvb2x0aXAgZWxlbWVudCwgYWRkcyBhdHRyaWJ1dGVzLCBhbmQgcmV0dXJucyB0aGUgdGVtcGxhdGUuXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfYnVpbGRUZW1wbGF0ZShpZCkge1xyXG4gICAgdmFyIHRlbXBsYXRlQ2xhc3NlcyA9IChgJHt0aGlzLm9wdGlvbnMudG9vbHRpcENsYXNzfSAke3RoaXMub3B0aW9ucy5wb3NpdGlvbkNsYXNzfSAke3RoaXMub3B0aW9ucy50ZW1wbGF0ZUNsYXNzZXN9YCkudHJpbSgpO1xyXG4gICAgdmFyICR0ZW1wbGF0ZSA9ICAkKCc8ZGl2PjwvZGl2PicpLmFkZENsYXNzKHRlbXBsYXRlQ2xhc3NlcykuYXR0cih7XHJcbiAgICAgICdyb2xlJzogJ3Rvb2x0aXAnLFxyXG4gICAgICAnYXJpYS1oaWRkZW4nOiB0cnVlLFxyXG4gICAgICAnZGF0YS1pcy1hY3RpdmUnOiBmYWxzZSxcclxuICAgICAgJ2RhdGEtaXMtZm9jdXMnOiBmYWxzZSxcclxuICAgICAgJ2lkJzogaWRcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuICR0ZW1wbGF0ZTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEZ1bmN0aW9uIHRoYXQgZ2V0cyBjYWxsZWQgaWYgYSBjb2xsaXNpb24gZXZlbnQgaXMgZGV0ZWN0ZWQuXHJcbiAgICogQHBhcmFtIHtTdHJpbmd9IHBvc2l0aW9uIC0gcG9zaXRpb25pbmcgY2xhc3MgdG8gdHJ5XHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfcmVwb3NpdGlvbihwb3NpdGlvbikge1xyXG4gICAgdGhpcy51c2VkUG9zaXRpb25zLnB1c2gocG9zaXRpb24gPyBwb3NpdGlvbiA6ICdib3R0b20nKTtcclxuXHJcbiAgICAvL2RlZmF1bHQsIHRyeSBzd2l0Y2hpbmcgdG8gb3Bwb3NpdGUgc2lkZVxyXG4gICAgaWYgKCFwb3NpdGlvbiAmJiAodGhpcy51c2VkUG9zaXRpb25zLmluZGV4T2YoJ3RvcCcpIDwgMCkpIHtcclxuICAgICAgdGhpcy50ZW1wbGF0ZS5hZGRDbGFzcygndG9wJyk7XHJcbiAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSAndG9wJyAmJiAodGhpcy51c2VkUG9zaXRpb25zLmluZGV4T2YoJ2JvdHRvbScpIDwgMCkpIHtcclxuICAgICAgdGhpcy50ZW1wbGF0ZS5yZW1vdmVDbGFzcyhwb3NpdGlvbik7XHJcbiAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSAnbGVmdCcgJiYgKHRoaXMudXNlZFBvc2l0aW9ucy5pbmRleE9mKCdyaWdodCcpIDwgMCkpIHtcclxuICAgICAgdGhpcy50ZW1wbGF0ZS5yZW1vdmVDbGFzcyhwb3NpdGlvbilcclxuICAgICAgICAgIC5hZGRDbGFzcygncmlnaHQnKTtcclxuICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICdyaWdodCcgJiYgKHRoaXMudXNlZFBvc2l0aW9ucy5pbmRleE9mKCdsZWZ0JykgPCAwKSkge1xyXG4gICAgICB0aGlzLnRlbXBsYXRlLnJlbW92ZUNsYXNzKHBvc2l0aW9uKVxyXG4gICAgICAgICAgLmFkZENsYXNzKCdsZWZ0Jyk7XHJcbiAgICB9XHJcblxyXG4gICAgLy9pZiBkZWZhdWx0IGNoYW5nZSBkaWRuJ3Qgd29yaywgdHJ5IGJvdHRvbSBvciBsZWZ0IGZpcnN0XHJcbiAgICBlbHNlIGlmICghcG9zaXRpb24gJiYgKHRoaXMudXNlZFBvc2l0aW9ucy5pbmRleE9mKCd0b3AnKSA+IC0xKSAmJiAodGhpcy51c2VkUG9zaXRpb25zLmluZGV4T2YoJ2xlZnQnKSA8IDApKSB7XHJcbiAgICAgIHRoaXMudGVtcGxhdGUuYWRkQ2xhc3MoJ2xlZnQnKTtcclxuICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICd0b3AnICYmICh0aGlzLnVzZWRQb3NpdGlvbnMuaW5kZXhPZignYm90dG9tJykgPiAtMSkgJiYgKHRoaXMudXNlZFBvc2l0aW9ucy5pbmRleE9mKCdsZWZ0JykgPCAwKSkge1xyXG4gICAgICB0aGlzLnRlbXBsYXRlLnJlbW92ZUNsYXNzKHBvc2l0aW9uKVxyXG4gICAgICAgICAgLmFkZENsYXNzKCdsZWZ0Jyk7XHJcbiAgICB9IGVsc2UgaWYgKHBvc2l0aW9uID09PSAnbGVmdCcgJiYgKHRoaXMudXNlZFBvc2l0aW9ucy5pbmRleE9mKCdyaWdodCcpID4gLTEpICYmICh0aGlzLnVzZWRQb3NpdGlvbnMuaW5kZXhPZignYm90dG9tJykgPCAwKSkge1xyXG4gICAgICB0aGlzLnRlbXBsYXRlLnJlbW92ZUNsYXNzKHBvc2l0aW9uKTtcclxuICAgIH0gZWxzZSBpZiAocG9zaXRpb24gPT09ICdyaWdodCcgJiYgKHRoaXMudXNlZFBvc2l0aW9ucy5pbmRleE9mKCdsZWZ0JykgPiAtMSkgJiYgKHRoaXMudXNlZFBvc2l0aW9ucy5pbmRleE9mKCdib3R0b20nKSA8IDApKSB7XHJcbiAgICAgIHRoaXMudGVtcGxhdGUucmVtb3ZlQ2xhc3MocG9zaXRpb24pO1xyXG4gICAgfVxyXG4gICAgLy9pZiBub3RoaW5nIGNsZWFyZWQsIHNldCB0byBib3R0b21cclxuICAgIGVsc2Uge1xyXG4gICAgICB0aGlzLnRlbXBsYXRlLnJlbW92ZUNsYXNzKHBvc2l0aW9uKTtcclxuICAgIH1cclxuICAgIHRoaXMuY2xhc3NDaGFuZ2VkID0gdHJ1ZTtcclxuICAgIHRoaXMuY291bnRlci0tO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogc2V0cyB0aGUgcG9zaXRpb24gY2xhc3Mgb2YgYW4gZWxlbWVudCBhbmQgcmVjdXJzaXZlbHkgY2FsbHMgaXRzZWxmIHVudGlsIHRoZXJlIGFyZSBubyBtb3JlIHBvc3NpYmxlIHBvc2l0aW9ucyB0byBhdHRlbXB0LCBvciB0aGUgdG9vbHRpcCBlbGVtZW50IGlzIG5vIGxvbmdlciBjb2xsaWRpbmcuXHJcbiAgICogaWYgdGhlIHRvb2x0aXAgaXMgbGFyZ2VyIHRoYW4gdGhlIHNjcmVlbiB3aWR0aCwgZGVmYXVsdCB0byBmdWxsIHdpZHRoIC0gYW55IHVzZXIgc2VsZWN0ZWQgbWFyZ2luXHJcbiAgICogQHByaXZhdGVcclxuICAgKi9cclxuICBfc2V0UG9zaXRpb24oKSB7XHJcbiAgICB2YXIgcG9zaXRpb24gPSB0aGlzLl9nZXRQb3NpdGlvbkNsYXNzKHRoaXMudGVtcGxhdGUpLFxyXG4gICAgICAgICR0aXBEaW1zID0gRm91bmRhdGlvbi5Cb3guR2V0RGltZW5zaW9ucyh0aGlzLnRlbXBsYXRlKSxcclxuICAgICAgICAkYW5jaG9yRGltcyA9IEZvdW5kYXRpb24uQm94LkdldERpbWVuc2lvbnModGhpcy4kZWxlbWVudCksXHJcbiAgICAgICAgZGlyZWN0aW9uID0gKHBvc2l0aW9uID09PSAnbGVmdCcgPyAnbGVmdCcgOiAoKHBvc2l0aW9uID09PSAncmlnaHQnKSA/ICdsZWZ0JyA6ICd0b3AnKSksXHJcbiAgICAgICAgcGFyYW0gPSAoZGlyZWN0aW9uID09PSAndG9wJykgPyAnaGVpZ2h0JyA6ICd3aWR0aCcsXHJcbiAgICAgICAgb2Zmc2V0ID0gKHBhcmFtID09PSAnaGVpZ2h0JykgPyB0aGlzLm9wdGlvbnMudk9mZnNldCA6IHRoaXMub3B0aW9ucy5oT2Zmc2V0LFxyXG4gICAgICAgIF90aGlzID0gdGhpcztcclxuXHJcbiAgICBpZiAoKCR0aXBEaW1zLndpZHRoID49ICR0aXBEaW1zLndpbmRvd0RpbXMud2lkdGgpIHx8ICghdGhpcy5jb3VudGVyICYmICFGb3VuZGF0aW9uLkJveC5JbU5vdFRvdWNoaW5nWW91KHRoaXMudGVtcGxhdGUpKSkge1xyXG4gICAgICB0aGlzLnRlbXBsYXRlLm9mZnNldChGb3VuZGF0aW9uLkJveC5HZXRPZmZzZXRzKHRoaXMudGVtcGxhdGUsIHRoaXMuJGVsZW1lbnQsICdjZW50ZXIgYm90dG9tJywgdGhpcy5vcHRpb25zLnZPZmZzZXQsIHRoaXMub3B0aW9ucy5oT2Zmc2V0LCB0cnVlKSkuY3NzKHtcclxuICAgICAgLy8gdGhpcy4kZWxlbWVudC5vZmZzZXQoRm91bmRhdGlvbi5HZXRPZmZzZXRzKHRoaXMudGVtcGxhdGUsIHRoaXMuJGVsZW1lbnQsICdjZW50ZXIgYm90dG9tJywgdGhpcy5vcHRpb25zLnZPZmZzZXQsIHRoaXMub3B0aW9ucy5oT2Zmc2V0LCB0cnVlKSkuY3NzKHtcclxuICAgICAgICAnd2lkdGgnOiAkYW5jaG9yRGltcy53aW5kb3dEaW1zLndpZHRoIC0gKHRoaXMub3B0aW9ucy5oT2Zmc2V0ICogMiksXHJcbiAgICAgICAgJ2hlaWdodCc6ICdhdXRvJ1xyXG4gICAgICB9KTtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMudGVtcGxhdGUub2Zmc2V0KEZvdW5kYXRpb24uQm94LkdldE9mZnNldHModGhpcy50ZW1wbGF0ZSwgdGhpcy4kZWxlbWVudCwnY2VudGVyICcgKyAocG9zaXRpb24gfHwgJ2JvdHRvbScpLCB0aGlzLm9wdGlvbnMudk9mZnNldCwgdGhpcy5vcHRpb25zLmhPZmZzZXQpKTtcclxuXHJcbiAgICB3aGlsZSghRm91bmRhdGlvbi5Cb3guSW1Ob3RUb3VjaGluZ1lvdSh0aGlzLnRlbXBsYXRlKSAmJiB0aGlzLmNvdW50ZXIpIHtcclxuICAgICAgdGhpcy5fcmVwb3NpdGlvbihwb3NpdGlvbik7XHJcbiAgICAgIHRoaXMuX3NldFBvc2l0aW9uKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiByZXZlYWxzIHRoZSB0b29sdGlwLCBhbmQgZmlyZXMgYW4gZXZlbnQgdG8gY2xvc2UgYW55IG90aGVyIG9wZW4gdG9vbHRpcHMgb24gdGhlIHBhZ2VcclxuICAgKiBAZmlyZXMgVG9vbHRpcCNjbG9zZW1lXHJcbiAgICogQGZpcmVzIFRvb2x0aXAjc2hvd1xyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqL1xyXG4gIHNob3coKSB7XHJcbiAgICBpZiAodGhpcy5vcHRpb25zLnNob3dPbiAhPT0gJ2FsbCcgJiYgIUZvdW5kYXRpb24uTWVkaWFRdWVyeS5hdExlYXN0KHRoaXMub3B0aW9ucy5zaG93T24pKSB7XHJcbiAgICAgIC8vIGNvbnNvbGUuZXJyb3IoJ1RoZSBzY3JlZW4gaXMgdG9vIHNtYWxsIHRvIGRpc3BsYXkgdGhpcyB0b29sdGlwJyk7XHJcbiAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgdGhpcy50ZW1wbGF0ZS5jc3MoJ3Zpc2liaWxpdHknLCAnaGlkZGVuJykuc2hvdygpO1xyXG4gICAgdGhpcy5fc2V0UG9zaXRpb24oKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEZpcmVzIHRvIGNsb3NlIGFsbCBvdGhlciBvcGVuIHRvb2x0aXBzIG9uIHRoZSBwYWdlXHJcbiAgICAgKiBAZXZlbnQgQ2xvc2VtZSN0b29sdGlwXHJcbiAgICAgKi9cclxuICAgIHRoaXMuJGVsZW1lbnQudHJpZ2dlcignY2xvc2VtZS56Zi50b29sdGlwJywgdGhpcy50ZW1wbGF0ZS5hdHRyKCdpZCcpKTtcclxuXHJcblxyXG4gICAgdGhpcy50ZW1wbGF0ZS5hdHRyKHtcclxuICAgICAgJ2RhdGEtaXMtYWN0aXZlJzogdHJ1ZSxcclxuICAgICAgJ2FyaWEtaGlkZGVuJzogZmFsc2VcclxuICAgIH0pO1xyXG4gICAgX3RoaXMuaXNBY3RpdmUgPSB0cnVlO1xyXG4gICAgLy8gY29uc29sZS5sb2codGhpcy50ZW1wbGF0ZSk7XHJcbiAgICB0aGlzLnRlbXBsYXRlLnN0b3AoKS5oaWRlKCkuY3NzKCd2aXNpYmlsaXR5JywgJycpLmZhZGVJbih0aGlzLm9wdGlvbnMuZmFkZUluRHVyYXRpb24sIGZ1bmN0aW9uKCkge1xyXG4gICAgICAvL21heWJlIGRvIHN0dWZmP1xyXG4gICAgfSk7XHJcbiAgICAvKipcclxuICAgICAqIEZpcmVzIHdoZW4gdGhlIHRvb2x0aXAgaXMgc2hvd25cclxuICAgICAqIEBldmVudCBUb29sdGlwI3Nob3dcclxuICAgICAqL1xyXG4gICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKCdzaG93LnpmLnRvb2x0aXAnKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEhpZGVzIHRoZSBjdXJyZW50IHRvb2x0aXAsIGFuZCByZXNldHMgdGhlIHBvc2l0aW9uaW5nIGNsYXNzIGlmIGl0IHdhcyBjaGFuZ2VkIGR1ZSB0byBjb2xsaXNpb25cclxuICAgKiBAZmlyZXMgVG9vbHRpcCNoaWRlXHJcbiAgICogQGZ1bmN0aW9uXHJcbiAgICovXHJcbiAgaGlkZSgpIHtcclxuICAgIC8vIGNvbnNvbGUubG9nKCdoaWRpbmcnLCB0aGlzLiRlbGVtZW50LmRhdGEoJ3lldGktYm94JykpO1xyXG4gICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgIHRoaXMudGVtcGxhdGUuc3RvcCgpLmF0dHIoe1xyXG4gICAgICAnYXJpYS1oaWRkZW4nOiB0cnVlLFxyXG4gICAgICAnZGF0YS1pcy1hY3RpdmUnOiBmYWxzZVxyXG4gICAgfSkuZmFkZU91dCh0aGlzLm9wdGlvbnMuZmFkZU91dER1cmF0aW9uLCBmdW5jdGlvbigpIHtcclxuICAgICAgX3RoaXMuaXNBY3RpdmUgPSBmYWxzZTtcclxuICAgICAgX3RoaXMuaXNDbGljayA9IGZhbHNlO1xyXG4gICAgICBpZiAoX3RoaXMuY2xhc3NDaGFuZ2VkKSB7XHJcbiAgICAgICAgX3RoaXMudGVtcGxhdGVcclxuICAgICAgICAgICAgIC5yZW1vdmVDbGFzcyhfdGhpcy5fZ2V0UG9zaXRpb25DbGFzcyhfdGhpcy50ZW1wbGF0ZSkpXHJcbiAgICAgICAgICAgICAuYWRkQ2xhc3MoX3RoaXMub3B0aW9ucy5wb3NpdGlvbkNsYXNzKTtcclxuXHJcbiAgICAgICBfdGhpcy51c2VkUG9zaXRpb25zID0gW107XHJcbiAgICAgICBfdGhpcy5jb3VudGVyID0gNDtcclxuICAgICAgIF90aGlzLmNsYXNzQ2hhbmdlZCA9IGZhbHNlO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIC8qKlxyXG4gICAgICogZmlyZXMgd2hlbiB0aGUgdG9vbHRpcCBpcyBoaWRkZW5cclxuICAgICAqIEBldmVudCBUb29sdGlwI2hpZGVcclxuICAgICAqL1xyXG4gICAgdGhpcy4kZWxlbWVudC50cmlnZ2VyKCdoaWRlLnpmLnRvb2x0aXAnKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIGFkZHMgZXZlbnQgbGlzdGVuZXJzIGZvciB0aGUgdG9vbHRpcCBhbmQgaXRzIGFuY2hvclxyXG4gICAqIFRPRE8gY29tYmluZSBzb21lIG9mIHRoZSBsaXN0ZW5lcnMgbGlrZSBmb2N1cyBhbmQgbW91c2VlbnRlciwgZXRjLlxyXG4gICAqIEBwcml2YXRlXHJcbiAgICovXHJcbiAgX2V2ZW50cygpIHtcclxuICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICB2YXIgJHRlbXBsYXRlID0gdGhpcy50ZW1wbGF0ZTtcclxuICAgIHZhciBpc0ZvY3VzID0gZmFsc2U7XHJcblxyXG4gICAgaWYgKCF0aGlzLm9wdGlvbnMuZGlzYWJsZUhvdmVyKSB7XHJcblxyXG4gICAgICB0aGlzLiRlbGVtZW50XHJcbiAgICAgIC5vbignbW91c2VlbnRlci56Zi50b29sdGlwJywgZnVuY3Rpb24oZSkge1xyXG4gICAgICAgIGlmICghX3RoaXMuaXNBY3RpdmUpIHtcclxuICAgICAgICAgIF90aGlzLnRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5zaG93KCk7XHJcbiAgICAgICAgICB9LCBfdGhpcy5vcHRpb25zLmhvdmVyRGVsYXkpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgICAgLm9uKCdtb3VzZWxlYXZlLnpmLnRvb2x0aXAnLCBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgY2xlYXJUaW1lb3V0KF90aGlzLnRpbWVvdXQpO1xyXG4gICAgICAgIGlmICghaXNGb2N1cyB8fCAoX3RoaXMuaXNDbGljayAmJiAhX3RoaXMub3B0aW9ucy5jbGlja09wZW4pKSB7XHJcbiAgICAgICAgICBfdGhpcy5oaWRlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5vcHRpb25zLmNsaWNrT3Blbikge1xyXG4gICAgICB0aGlzLiRlbGVtZW50Lm9uKCdtb3VzZWRvd24uemYudG9vbHRpcCcsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgIGlmIChfdGhpcy5pc0NsaWNrKSB7XHJcbiAgICAgICAgICAvL190aGlzLmhpZGUoKTtcclxuICAgICAgICAgIC8vIF90aGlzLmlzQ2xpY2sgPSBmYWxzZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgX3RoaXMuaXNDbGljayA9IHRydWU7XHJcbiAgICAgICAgICBpZiAoKF90aGlzLm9wdGlvbnMuZGlzYWJsZUhvdmVyIHx8ICFfdGhpcy4kZWxlbWVudC5hdHRyKCd0YWJpbmRleCcpKSAmJiAhX3RoaXMuaXNBY3RpdmUpIHtcclxuICAgICAgICAgICAgX3RoaXMuc2hvdygpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLiRlbGVtZW50Lm9uKCdtb3VzZWRvd24uemYudG9vbHRpcCcsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgIF90aGlzLmlzQ2xpY2sgPSB0cnVlO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoIXRoaXMub3B0aW9ucy5kaXNhYmxlRm9yVG91Y2gpIHtcclxuICAgICAgdGhpcy4kZWxlbWVudFxyXG4gICAgICAub24oJ3RhcC56Zi50b29sdGlwIHRvdWNoZW5kLnpmLnRvb2x0aXAnLCBmdW5jdGlvbihlKSB7XHJcbiAgICAgICAgX3RoaXMuaXNBY3RpdmUgPyBfdGhpcy5oaWRlKCkgOiBfdGhpcy5zaG93KCk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuJGVsZW1lbnQub24oe1xyXG4gICAgICAvLyAndG9nZ2xlLnpmLnRyaWdnZXInOiB0aGlzLnRvZ2dsZS5iaW5kKHRoaXMpLFxyXG4gICAgICAvLyAnY2xvc2UuemYudHJpZ2dlcic6IHRoaXMuaGlkZS5iaW5kKHRoaXMpXHJcbiAgICAgICdjbG9zZS56Zi50cmlnZ2VyJzogdGhpcy5oaWRlLmJpbmQodGhpcylcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuJGVsZW1lbnRcclxuICAgICAgLm9uKCdmb2N1cy56Zi50b29sdGlwJywgZnVuY3Rpb24oZSkge1xyXG4gICAgICAgIGlzRm9jdXMgPSB0cnVlO1xyXG4gICAgICAgIGlmIChfdGhpcy5pc0NsaWNrKSB7XHJcbiAgICAgICAgICAvLyBJZiB3ZSdyZSBub3Qgc2hvd2luZyBvcGVuIG9uIGNsaWNrcywgd2UgbmVlZCB0byBwcmV0ZW5kIGEgY2xpY2stbGF1bmNoZWQgZm9jdXMgaXNuJ3RcclxuICAgICAgICAgIC8vIGEgcmVhbCBmb2N1cywgb3RoZXJ3aXNlIG9uIGhvdmVyIGFuZCBjb21lIGJhY2sgd2UgZ2V0IGJhZCBiZWhhdmlvclxyXG4gICAgICAgICAgaWYoIV90aGlzLm9wdGlvbnMuY2xpY2tPcGVuKSB7IGlzRm9jdXMgPSBmYWxzZTsgfVxyXG4gICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBfdGhpcy5zaG93KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KVxyXG5cclxuICAgICAgLm9uKCdmb2N1c291dC56Zi50b29sdGlwJywgZnVuY3Rpb24oZSkge1xyXG4gICAgICAgIGlzRm9jdXMgPSBmYWxzZTtcclxuICAgICAgICBfdGhpcy5pc0NsaWNrID0gZmFsc2U7XHJcbiAgICAgICAgX3RoaXMuaGlkZSgpO1xyXG4gICAgICB9KVxyXG5cclxuICAgICAgLm9uKCdyZXNpemVtZS56Zi50cmlnZ2VyJywgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgaWYgKF90aGlzLmlzQWN0aXZlKSB7XHJcbiAgICAgICAgICBfdGhpcy5fc2V0UG9zaXRpb24oKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogYWRkcyBhIHRvZ2dsZSBtZXRob2QsIGluIGFkZGl0aW9uIHRvIHRoZSBzdGF0aWMgc2hvdygpICYgaGlkZSgpIGZ1bmN0aW9uc1xyXG4gICAqIEBmdW5jdGlvblxyXG4gICAqL1xyXG4gIHRvZ2dsZSgpIHtcclxuICAgIGlmICh0aGlzLmlzQWN0aXZlKSB7XHJcbiAgICAgIHRoaXMuaGlkZSgpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5zaG93KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBEZXN0cm95cyBhbiBpbnN0YW5jZSBvZiB0b29sdGlwLCByZW1vdmVzIHRlbXBsYXRlIGVsZW1lbnQgZnJvbSB0aGUgdmlldy5cclxuICAgKiBAZnVuY3Rpb25cclxuICAgKi9cclxuICBkZXN0cm95KCkge1xyXG4gICAgdGhpcy4kZWxlbWVudC5hdHRyKCd0aXRsZScsIHRoaXMudGVtcGxhdGUudGV4dCgpKVxyXG4gICAgICAgICAgICAgICAgIC5vZmYoJy56Zi50cmlnZ2VyIC56Zi50b290aXAnKVxyXG4gICAgICAgICAgICAgICAgLy8gIC5yZW1vdmVDbGFzcygnaGFzLXRpcCcpXHJcbiAgICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2FyaWEtZGVzY3JpYmVkYnknKVxyXG4gICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkYXRhLXlldGktYm94JylcclxuICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGF0YS10b2dnbGUnKVxyXG4gICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdkYXRhLXJlc2l6ZScpO1xyXG5cclxuICAgIHRoaXMudGVtcGxhdGUucmVtb3ZlKCk7XHJcblxyXG4gICAgRm91bmRhdGlvbi51bnJlZ2lzdGVyUGx1Z2luKHRoaXMpO1xyXG4gIH1cclxufVxyXG5cclxuVG9vbHRpcC5kZWZhdWx0cyA9IHtcclxuICBkaXNhYmxlRm9yVG91Y2g6IGZhbHNlLFxyXG4gIC8qKlxyXG4gICAqIFRpbWUsIGluIG1zLCBiZWZvcmUgYSB0b29sdGlwIHNob3VsZCBvcGVuIG9uIGhvdmVyLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAyMDBcclxuICAgKi9cclxuICBob3ZlckRlbGF5OiAyMDAsXHJcbiAgLyoqXHJcbiAgICogVGltZSwgaW4gbXMsIGEgdG9vbHRpcCBzaG91bGQgdGFrZSB0byBmYWRlIGludG8gdmlldy5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgMTUwXHJcbiAgICovXHJcbiAgZmFkZUluRHVyYXRpb246IDE1MCxcclxuICAvKipcclxuICAgKiBUaW1lLCBpbiBtcywgYSB0b29sdGlwIHNob3VsZCB0YWtlIHRvIGZhZGUgb3V0IG9mIHZpZXcuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIDE1MFxyXG4gICAqL1xyXG4gIGZhZGVPdXREdXJhdGlvbjogMTUwLFxyXG4gIC8qKlxyXG4gICAqIERpc2FibGVzIGhvdmVyIGV2ZW50cyBmcm9tIG9wZW5pbmcgdGhlIHRvb2x0aXAgaWYgc2V0IHRvIHRydWVcclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgZmFsc2VcclxuICAgKi9cclxuICBkaXNhYmxlSG92ZXI6IGZhbHNlLFxyXG4gIC8qKlxyXG4gICAqIE9wdGlvbmFsIGFkZHRpb25hbCBjbGFzc2VzIHRvIGFwcGx5IHRvIHRoZSB0b29sdGlwIHRlbXBsYXRlIG9uIGluaXQuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlICdteS1jb29sLXRpcC1jbGFzcydcclxuICAgKi9cclxuICB0ZW1wbGF0ZUNsYXNzZXM6ICcnLFxyXG4gIC8qKlxyXG4gICAqIE5vbi1vcHRpb25hbCBjbGFzcyBhZGRlZCB0byB0b29sdGlwIHRlbXBsYXRlcy4gRm91bmRhdGlvbiBkZWZhdWx0IGlzICd0b29sdGlwJy5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgJ3Rvb2x0aXAnXHJcbiAgICovXHJcbiAgdG9vbHRpcENsYXNzOiAndG9vbHRpcCcsXHJcbiAgLyoqXHJcbiAgICogQ2xhc3MgYXBwbGllZCB0byB0aGUgdG9vbHRpcCBhbmNob3IgZWxlbWVudC5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgJ2hhcy10aXAnXHJcbiAgICovXHJcbiAgdHJpZ2dlckNsYXNzOiAnaGFzLXRpcCcsXHJcbiAgLyoqXHJcbiAgICogTWluaW11bSBicmVha3BvaW50IHNpemUgYXQgd2hpY2ggdG8gb3BlbiB0aGUgdG9vbHRpcC5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgJ3NtYWxsJ1xyXG4gICAqL1xyXG4gIHNob3dPbjogJ3NtYWxsJyxcclxuICAvKipcclxuICAgKiBDdXN0b20gdGVtcGxhdGUgdG8gYmUgdXNlZCB0byBnZW5lcmF0ZSBtYXJrdXAgZm9yIHRvb2x0aXAuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlICcmbHQ7ZGl2IGNsYXNzPVwidG9vbHRpcFwiJmd0OyZsdDsvZGl2Jmd0OydcclxuICAgKi9cclxuICB0ZW1wbGF0ZTogJycsXHJcbiAgLyoqXHJcbiAgICogVGV4dCBkaXNwbGF5ZWQgaW4gdGhlIHRvb2x0aXAgdGVtcGxhdGUgb24gb3Blbi5cclxuICAgKiBAb3B0aW9uXHJcbiAgICogQGV4YW1wbGUgJ1NvbWUgY29vbCBzcGFjZSBmYWN0IGhlcmUuJ1xyXG4gICAqL1xyXG4gIHRpcFRleHQ6ICcnLFxyXG4gIHRvdWNoQ2xvc2VUZXh0OiAnVGFwIHRvIGNsb3NlLicsXHJcbiAgLyoqXHJcbiAgICogQWxsb3dzIHRoZSB0b29sdGlwIHRvIHJlbWFpbiBvcGVuIGlmIHRyaWdnZXJlZCB3aXRoIGEgY2xpY2sgb3IgdG91Y2ggZXZlbnQuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIHRydWVcclxuICAgKi9cclxuICBjbGlja09wZW46IHRydWUsXHJcbiAgLyoqXHJcbiAgICogQWRkaXRpb25hbCBwb3NpdGlvbmluZyBjbGFzc2VzLCBzZXQgYnkgdGhlIEpTXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlICd0b3AnXHJcbiAgICovXHJcbiAgcG9zaXRpb25DbGFzczogJycsXHJcbiAgLyoqXHJcbiAgICogRGlzdGFuY2UsIGluIHBpeGVscywgdGhlIHRlbXBsYXRlIHNob3VsZCBwdXNoIGF3YXkgZnJvbSB0aGUgYW5jaG9yIG9uIHRoZSBZIGF4aXMuXHJcbiAgICogQG9wdGlvblxyXG4gICAqIEBleGFtcGxlIDEwXHJcbiAgICovXHJcbiAgdk9mZnNldDogMTAsXHJcbiAgLyoqXHJcbiAgICogRGlzdGFuY2UsIGluIHBpeGVscywgdGhlIHRlbXBsYXRlIHNob3VsZCBwdXNoIGF3YXkgZnJvbSB0aGUgYW5jaG9yIG9uIHRoZSBYIGF4aXMsIGlmIGFsaWduZWQgdG8gYSBzaWRlLlxyXG4gICAqIEBvcHRpb25cclxuICAgKiBAZXhhbXBsZSAxMlxyXG4gICAqL1xyXG4gIGhPZmZzZXQ6IDEyXHJcbn07XHJcblxyXG4vKipcclxuICogVE9ETyB1dGlsaXplIHJlc2l6ZSBldmVudCB0cmlnZ2VyXHJcbiAqL1xyXG5cclxuLy8gV2luZG93IGV4cG9ydHNcclxuRm91bmRhdGlvbi5wbHVnaW4oVG9vbHRpcCwgJ1Rvb2x0aXAnKTtcclxuXHJcbn0oalF1ZXJ5KTsiLCIvKlxyXG4gICAgIF8gXyAgICAgIF8gICAgICAgX1xyXG4gX19ffCAoXykgX19ffCB8IF9fICAoXylfX19cclxuLyBfX3wgfCB8LyBfX3wgfC8gLyAgfCAvIF9ffFxyXG5cXF9fIFxcIHwgfCAoX198ICAgPCBfIHwgXFxfXyBcXFxyXG58X19fL198X3xcXF9fX3xffFxcXyhfKS8gfF9fXy9cclxuICAgICAgICAgICAgICAgICAgIHxfXy9cclxuXHJcbiBWZXJzaW9uOiAxLjYuMFxyXG4gIEF1dGhvcjogS2VuIFdoZWVsZXJcclxuIFdlYnNpdGU6IGh0dHA6Ly9rZW53aGVlbGVyLmdpdGh1Yi5pb1xyXG4gICAgRG9jczogaHR0cDovL2tlbndoZWVsZXIuZ2l0aHViLmlvL3NsaWNrXHJcbiAgICBSZXBvOiBodHRwOi8vZ2l0aHViLmNvbS9rZW53aGVlbGVyL3NsaWNrXHJcbiAgSXNzdWVzOiBodHRwOi8vZ2l0aHViLmNvbS9rZW53aGVlbGVyL3NsaWNrL2lzc3Vlc1xyXG5cclxuICovXHJcbi8qIGdsb2JhbCB3aW5kb3csIGRvY3VtZW50LCBkZWZpbmUsIGpRdWVyeSwgc2V0SW50ZXJ2YWwsIGNsZWFySW50ZXJ2YWwgKi9cclxuKGZ1bmN0aW9uKGZhY3RvcnkpIHtcclxuICAgICd1c2Ugc3RyaWN0JztcclxuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcclxuICAgICAgICBkZWZpbmUoWydqcXVlcnknXSwgZmFjdG9yeSk7XHJcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFjdG9yeShyZXF1aXJlKCdqcXVlcnknKSk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICAgIGZhY3RvcnkoalF1ZXJ5KTtcclxuICAgIH1cclxuXHJcbn0oZnVuY3Rpb24oJCkge1xyXG4gICAgJ3VzZSBzdHJpY3QnO1xyXG4gICAgdmFyIFNsaWNrID0gd2luZG93LlNsaWNrIHx8IHt9O1xyXG5cclxuICAgIFNsaWNrID0gKGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgaW5zdGFuY2VVaWQgPSAwO1xyXG5cclxuICAgICAgICBmdW5jdGlvbiBTbGljayhlbGVtZW50LCBzZXR0aW5ncykge1xyXG5cclxuICAgICAgICAgICAgdmFyIF8gPSB0aGlzLCBkYXRhU2V0dGluZ3M7XHJcblxyXG4gICAgICAgICAgICBfLmRlZmF1bHRzID0ge1xyXG4gICAgICAgICAgICAgICAgYWNjZXNzaWJpbGl0eTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGFkYXB0aXZlSGVpZ2h0OiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGFwcGVuZEFycm93czogJChlbGVtZW50KSxcclxuICAgICAgICAgICAgICAgIGFwcGVuZERvdHM6ICQoZWxlbWVudCksXHJcbiAgICAgICAgICAgICAgICBhcnJvd3M6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBhc05hdkZvcjogbnVsbCxcclxuICAgICAgICAgICAgICAgIHByZXZBcnJvdzogJzxidXR0b24gdHlwZT1cImJ1dHRvblwiIGRhdGEtcm9sZT1cIm5vbmVcIiBjbGFzcz1cInNsaWNrLXByZXZcIiBhcmlhLWxhYmVsPVwiUHJldmlvdXNcIiB0YWJpbmRleD1cIjBcIiByb2xlPVwiYnV0dG9uXCI+UHJldmlvdXM8L2J1dHRvbj4nLFxyXG4gICAgICAgICAgICAgICAgbmV4dEFycm93OiAnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1yb2xlPVwibm9uZVwiIGNsYXNzPVwic2xpY2stbmV4dFwiIGFyaWEtbGFiZWw9XCJOZXh0XCIgdGFiaW5kZXg9XCIwXCIgcm9sZT1cImJ1dHRvblwiPk5leHQ8L2J1dHRvbj4nLFxyXG4gICAgICAgICAgICAgICAgYXV0b3BsYXk6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgYXV0b3BsYXlTcGVlZDogMzAwMCxcclxuICAgICAgICAgICAgICAgIGNlbnRlck1vZGU6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgY2VudGVyUGFkZGluZzogJzUwcHgnLFxyXG4gICAgICAgICAgICAgICAgY3NzRWFzZTogJ2Vhc2UnLFxyXG4gICAgICAgICAgICAgICAgY3VzdG9tUGFnaW5nOiBmdW5jdGlvbihzbGlkZXIsIGkpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gJCgnPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgZGF0YS1yb2xlPVwibm9uZVwiIHJvbGU9XCJidXR0b25cIiB0YWJpbmRleD1cIjBcIiAvPicpLnRleHQoaSArIDEpO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIGRvdHM6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgZG90c0NsYXNzOiAnc2xpY2stZG90cycsXHJcbiAgICAgICAgICAgICAgICBkcmFnZ2FibGU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBlYXNpbmc6ICdsaW5lYXInLFxyXG4gICAgICAgICAgICAgICAgZWRnZUZyaWN0aW9uOiAwLjM1LFxyXG4gICAgICAgICAgICAgICAgZmFkZTogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBmb2N1c09uU2VsZWN0OiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGluZmluaXRlOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgaW5pdGlhbFNsaWRlOiAwLFxyXG4gICAgICAgICAgICAgICAgbGF6eUxvYWQ6ICdvbmRlbWFuZCcsXHJcbiAgICAgICAgICAgICAgICBtb2JpbGVGaXJzdDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBwYXVzZU9uSG92ZXI6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBwYXVzZU9uRm9jdXM6IHRydWUsXHJcbiAgICAgICAgICAgICAgICBwYXVzZU9uRG90c0hvdmVyOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIHJlc3BvbmRUbzogJ3dpbmRvdycsXHJcbiAgICAgICAgICAgICAgICByZXNwb25zaXZlOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgcm93czogMSxcclxuICAgICAgICAgICAgICAgIHJ0bDogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBzbGlkZTogJycsXHJcbiAgICAgICAgICAgICAgICBzbGlkZXNQZXJSb3c6IDEsXHJcbiAgICAgICAgICAgICAgICBzbGlkZXNUb1Nob3c6IDEsXHJcbiAgICAgICAgICAgICAgICBzbGlkZXNUb1Njcm9sbDogMSxcclxuICAgICAgICAgICAgICAgIHNwZWVkOiA1MDAsXHJcbiAgICAgICAgICAgICAgICBzd2lwZTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIHN3aXBlVG9TbGlkZTogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICB0b3VjaE1vdmU6IHRydWUsXHJcbiAgICAgICAgICAgICAgICB0b3VjaFRocmVzaG9sZDogNSxcclxuICAgICAgICAgICAgICAgIHVzZUNTUzogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIHVzZVRyYW5zZm9ybTogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIHZhcmlhYmxlV2lkdGg6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgdmVydGljYWw6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgdmVydGljYWxTd2lwaW5nOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIHdhaXRGb3JBbmltYXRlOiB0cnVlLFxyXG4gICAgICAgICAgICAgICAgekluZGV4OiAxMDAwXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBfLmluaXRpYWxzID0ge1xyXG4gICAgICAgICAgICAgICAgYW5pbWF0aW5nOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGRyYWdnaW5nOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIGF1dG9QbGF5VGltZXI6IG51bGwsXHJcbiAgICAgICAgICAgICAgICBjdXJyZW50RGlyZWN0aW9uOiAwLFxyXG4gICAgICAgICAgICAgICAgY3VycmVudExlZnQ6IG51bGwsXHJcbiAgICAgICAgICAgICAgICBjdXJyZW50U2xpZGU6IDAsXHJcbiAgICAgICAgICAgICAgICBkaXJlY3Rpb246IDEsXHJcbiAgICAgICAgICAgICAgICAkZG90czogbnVsbCxcclxuICAgICAgICAgICAgICAgIGxpc3RXaWR0aDogbnVsbCxcclxuICAgICAgICAgICAgICAgIGxpc3RIZWlnaHQ6IG51bGwsXHJcbiAgICAgICAgICAgICAgICBsb2FkSW5kZXg6IDAsXHJcbiAgICAgICAgICAgICAgICAkbmV4dEFycm93OiBudWxsLFxyXG4gICAgICAgICAgICAgICAgJHByZXZBcnJvdzogbnVsbCxcclxuICAgICAgICAgICAgICAgIHNsaWRlQ291bnQ6IG51bGwsXHJcbiAgICAgICAgICAgICAgICBzbGlkZVdpZHRoOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgJHNsaWRlVHJhY2s6IG51bGwsXHJcbiAgICAgICAgICAgICAgICAkc2xpZGVzOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgc2xpZGluZzogZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBzbGlkZU9mZnNldDogMCxcclxuICAgICAgICAgICAgICAgIHN3aXBlTGVmdDogbnVsbCxcclxuICAgICAgICAgICAgICAgICRsaXN0OiBudWxsLFxyXG4gICAgICAgICAgICAgICAgdG91Y2hPYmplY3Q6IHt9LFxyXG4gICAgICAgICAgICAgICAgdHJhbnNmb3Jtc0VuYWJsZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgdW5zbGlja2VkOiBmYWxzZVxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgJC5leHRlbmQoXywgXy5pbml0aWFscyk7XHJcblxyXG4gICAgICAgICAgICBfLmFjdGl2ZUJyZWFrcG9pbnQgPSBudWxsO1xyXG4gICAgICAgICAgICBfLmFuaW1UeXBlID0gbnVsbDtcclxuICAgICAgICAgICAgXy5hbmltUHJvcCA9IG51bGw7XHJcbiAgICAgICAgICAgIF8uYnJlYWtwb2ludHMgPSBbXTtcclxuICAgICAgICAgICAgXy5icmVha3BvaW50U2V0dGluZ3MgPSBbXTtcclxuICAgICAgICAgICAgXy5jc3NUcmFuc2l0aW9ucyA9IGZhbHNlO1xyXG4gICAgICAgICAgICBfLmZvY3Vzc2VkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIF8uaW50ZXJydXB0ZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgXy5oaWRkZW4gPSAnaGlkZGVuJztcclxuICAgICAgICAgICAgXy5wYXVzZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICBfLnBvc2l0aW9uUHJvcCA9IG51bGw7XHJcbiAgICAgICAgICAgIF8ucmVzcG9uZFRvID0gbnVsbDtcclxuICAgICAgICAgICAgXy5yb3dDb3VudCA9IDE7XHJcbiAgICAgICAgICAgIF8uc2hvdWxkQ2xpY2sgPSB0cnVlO1xyXG4gICAgICAgICAgICBfLiRzbGlkZXIgPSAkKGVsZW1lbnQpO1xyXG4gICAgICAgICAgICBfLiRzbGlkZXNDYWNoZSA9IG51bGw7XHJcbiAgICAgICAgICAgIF8udHJhbnNmb3JtVHlwZSA9IG51bGw7XHJcbiAgICAgICAgICAgIF8udHJhbnNpdGlvblR5cGUgPSBudWxsO1xyXG4gICAgICAgICAgICBfLnZpc2liaWxpdHlDaGFuZ2UgPSAndmlzaWJpbGl0eWNoYW5nZSc7XHJcbiAgICAgICAgICAgIF8ud2luZG93V2lkdGggPSAwO1xyXG4gICAgICAgICAgICBfLndpbmRvd1RpbWVyID0gbnVsbDtcclxuXHJcbiAgICAgICAgICAgIGRhdGFTZXR0aW5ncyA9ICQoZWxlbWVudCkuZGF0YSgnc2xpY2snKSB8fCB7fTtcclxuXHJcbiAgICAgICAgICAgIF8ub3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBfLmRlZmF1bHRzLCBzZXR0aW5ncywgZGF0YVNldHRpbmdzKTtcclxuXHJcbiAgICAgICAgICAgIF8uY3VycmVudFNsaWRlID0gXy5vcHRpb25zLmluaXRpYWxTbGlkZTtcclxuXHJcbiAgICAgICAgICAgIF8ub3JpZ2luYWxTZXR0aW5ncyA9IF8ub3B0aW9ucztcclxuXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZG9jdW1lbnQubW96SGlkZGVuICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICAgICAgXy5oaWRkZW4gPSAnbW96SGlkZGVuJztcclxuICAgICAgICAgICAgICAgIF8udmlzaWJpbGl0eUNoYW5nZSA9ICdtb3p2aXNpYmlsaXR5Y2hhbmdlJztcclxuICAgICAgICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZG9jdW1lbnQud2Via2l0SGlkZGVuICE9PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgICAgICAgICAgXy5oaWRkZW4gPSAnd2Via2l0SGlkZGVuJztcclxuICAgICAgICAgICAgICAgIF8udmlzaWJpbGl0eUNoYW5nZSA9ICd3ZWJraXR2aXNpYmlsaXR5Y2hhbmdlJztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgXy5hdXRvUGxheSA9ICQucHJveHkoXy5hdXRvUGxheSwgXyk7XHJcbiAgICAgICAgICAgIF8uYXV0b1BsYXlDbGVhciA9ICQucHJveHkoXy5hdXRvUGxheUNsZWFyLCBfKTtcclxuICAgICAgICAgICAgXy5hdXRvUGxheUl0ZXJhdG9yID0gJC5wcm94eShfLmF1dG9QbGF5SXRlcmF0b3IsIF8pO1xyXG4gICAgICAgICAgICBfLmNoYW5nZVNsaWRlID0gJC5wcm94eShfLmNoYW5nZVNsaWRlLCBfKTtcclxuICAgICAgICAgICAgXy5jbGlja0hhbmRsZXIgPSAkLnByb3h5KF8uY2xpY2tIYW5kbGVyLCBfKTtcclxuICAgICAgICAgICAgXy5zZWxlY3RIYW5kbGVyID0gJC5wcm94eShfLnNlbGVjdEhhbmRsZXIsIF8pO1xyXG4gICAgICAgICAgICBfLnNldFBvc2l0aW9uID0gJC5wcm94eShfLnNldFBvc2l0aW9uLCBfKTtcclxuICAgICAgICAgICAgXy5zd2lwZUhhbmRsZXIgPSAkLnByb3h5KF8uc3dpcGVIYW5kbGVyLCBfKTtcclxuICAgICAgICAgICAgXy5kcmFnSGFuZGxlciA9ICQucHJveHkoXy5kcmFnSGFuZGxlciwgXyk7XHJcbiAgICAgICAgICAgIF8ua2V5SGFuZGxlciA9ICQucHJveHkoXy5rZXlIYW5kbGVyLCBfKTtcclxuXHJcbiAgICAgICAgICAgIF8uaW5zdGFuY2VVaWQgPSBpbnN0YW5jZVVpZCsrO1xyXG5cclxuICAgICAgICAgICAgLy8gQSBzaW1wbGUgd2F5IHRvIGNoZWNrIGZvciBIVE1MIHN0cmluZ3NcclxuICAgICAgICAgICAgLy8gU3RyaWN0IEhUTUwgcmVjb2duaXRpb24gKG11c3Qgc3RhcnQgd2l0aCA8KVxyXG4gICAgICAgICAgICAvLyBFeHRyYWN0ZWQgZnJvbSBqUXVlcnkgdjEuMTEgc291cmNlXHJcbiAgICAgICAgICAgIF8uaHRtbEV4cHIgPSAvXig/OlxccyooPFtcXHdcXFddKz4pW14+XSopJC87XHJcblxyXG5cclxuICAgICAgICAgICAgXy5yZWdpc3RlckJyZWFrcG9pbnRzKCk7XHJcbiAgICAgICAgICAgIF8uaW5pdCh0cnVlKTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gU2xpY2s7XHJcblxyXG4gICAgfSgpKTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuYWN0aXZhdGVBREEgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIF8uJHNsaWRlVHJhY2suZmluZCgnLnNsaWNrLWFjdGl2ZScpLmF0dHIoe1xyXG4gICAgICAgICAgICAnYXJpYS1oaWRkZW4nOiAnZmFsc2UnXHJcbiAgICAgICAgfSkuZmluZCgnYSwgaW5wdXQsIGJ1dHRvbiwgc2VsZWN0JykuYXR0cih7XHJcbiAgICAgICAgICAgICd0YWJpbmRleCc6ICcwJ1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmFkZFNsaWRlID0gU2xpY2sucHJvdG90eXBlLnNsaWNrQWRkID0gZnVuY3Rpb24obWFya3VwLCBpbmRleCwgYWRkQmVmb3JlKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcztcclxuXHJcbiAgICAgICAgaWYgKHR5cGVvZihpbmRleCkgPT09ICdib29sZWFuJykge1xyXG4gICAgICAgICAgICBhZGRCZWZvcmUgPSBpbmRleDtcclxuICAgICAgICAgICAgaW5kZXggPSBudWxsO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoaW5kZXggPCAwIHx8IChpbmRleCA+PSBfLnNsaWRlQ291bnQpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIF8udW5sb2FkKCk7XHJcblxyXG4gICAgICAgIGlmICh0eXBlb2YoaW5kZXgpID09PSAnbnVtYmVyJykge1xyXG4gICAgICAgICAgICBpZiAoaW5kZXggPT09IDAgJiYgXy4kc2xpZGVzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgJChtYXJrdXApLmFwcGVuZFRvKF8uJHNsaWRlVHJhY2spO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGFkZEJlZm9yZSkge1xyXG4gICAgICAgICAgICAgICAgJChtYXJrdXApLmluc2VydEJlZm9yZShfLiRzbGlkZXMuZXEoaW5kZXgpKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICQobWFya3VwKS5pbnNlcnRBZnRlcihfLiRzbGlkZXMuZXEoaW5kZXgpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmIChhZGRCZWZvcmUgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgICAgICQobWFya3VwKS5wcmVwZW5kVG8oXy4kc2xpZGVUcmFjayk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAkKG1hcmt1cCkuYXBwZW5kVG8oXy4kc2xpZGVUcmFjayk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIF8uJHNsaWRlcyA9IF8uJHNsaWRlVHJhY2suY2hpbGRyZW4odGhpcy5vcHRpb25zLnNsaWRlKTtcclxuXHJcbiAgICAgICAgXy4kc2xpZGVUcmFjay5jaGlsZHJlbih0aGlzLm9wdGlvbnMuc2xpZGUpLmRldGFjaCgpO1xyXG5cclxuICAgICAgICBfLiRzbGlkZVRyYWNrLmFwcGVuZChfLiRzbGlkZXMpO1xyXG5cclxuICAgICAgICBfLiRzbGlkZXMuZWFjaChmdW5jdGlvbihpbmRleCwgZWxlbWVudCkge1xyXG4gICAgICAgICAgICAkKGVsZW1lbnQpLmF0dHIoJ2RhdGEtc2xpY2staW5kZXgnLCBpbmRleCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIF8uJHNsaWRlc0NhY2hlID0gXy4kc2xpZGVzO1xyXG5cclxuICAgICAgICBfLnJlaW5pdCgpO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmFuaW1hdGVIZWlnaHQgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cgPT09IDEgJiYgXy5vcHRpb25zLmFkYXB0aXZlSGVpZ2h0ID09PSB0cnVlICYmIF8ub3B0aW9ucy52ZXJ0aWNhbCA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgdmFyIHRhcmdldEhlaWdodCA9IF8uJHNsaWRlcy5lcShfLmN1cnJlbnRTbGlkZSkub3V0ZXJIZWlnaHQodHJ1ZSk7XHJcbiAgICAgICAgICAgIF8uJGxpc3QuYW5pbWF0ZSh7XHJcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IHRhcmdldEhlaWdodFxyXG4gICAgICAgICAgICB9LCBfLm9wdGlvbnMuc3BlZWQpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmFuaW1hdGVTbGlkZSA9IGZ1bmN0aW9uKHRhcmdldExlZnQsIGNhbGxiYWNrKSB7XHJcblxyXG4gICAgICAgIHZhciBhbmltUHJvcHMgPSB7fSxcclxuICAgICAgICAgICAgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIF8uYW5pbWF0ZUhlaWdodCgpO1xyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLnJ0bCA9PT0gdHJ1ZSAmJiBfLm9wdGlvbnMudmVydGljYWwgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIHRhcmdldExlZnQgPSAtdGFyZ2V0TGVmdDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKF8udHJhbnNmb3Jtc0VuYWJsZWQgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIGlmIChfLm9wdGlvbnMudmVydGljYWwgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICBfLiRzbGlkZVRyYWNrLmFuaW1hdGUoe1xyXG4gICAgICAgICAgICAgICAgICAgIGxlZnQ6IHRhcmdldExlZnRcclxuICAgICAgICAgICAgICAgIH0sIF8ub3B0aW9ucy5zcGVlZCwgXy5vcHRpb25zLmVhc2luZywgY2FsbGJhY2spO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgXy4kc2xpZGVUcmFjay5hbmltYXRlKHtcclxuICAgICAgICAgICAgICAgICAgICB0b3A6IHRhcmdldExlZnRcclxuICAgICAgICAgICAgICAgIH0sIF8ub3B0aW9ucy5zcGVlZCwgXy5vcHRpb25zLmVhc2luZywgY2FsbGJhY2spO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICAgICAgICBpZiAoXy5jc3NUcmFuc2l0aW9ucyA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgICAgIGlmIChfLm9wdGlvbnMucnRsID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgXy5jdXJyZW50TGVmdCA9IC0oXy5jdXJyZW50TGVmdCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAkKHtcclxuICAgICAgICAgICAgICAgICAgICBhbmltU3RhcnQ6IF8uY3VycmVudExlZnRcclxuICAgICAgICAgICAgICAgIH0pLmFuaW1hdGUoe1xyXG4gICAgICAgICAgICAgICAgICAgIGFuaW1TdGFydDogdGFyZ2V0TGVmdFxyXG4gICAgICAgICAgICAgICAgfSwge1xyXG4gICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiBfLm9wdGlvbnMuc3BlZWQsXHJcbiAgICAgICAgICAgICAgICAgICAgZWFzaW5nOiBfLm9wdGlvbnMuZWFzaW5nLFxyXG4gICAgICAgICAgICAgICAgICAgIHN0ZXA6IGZ1bmN0aW9uKG5vdykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBub3cgPSBNYXRoLmNlaWwobm93KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF8ub3B0aW9ucy52ZXJ0aWNhbCA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFuaW1Qcm9wc1tfLmFuaW1UeXBlXSA9ICd0cmFuc2xhdGUoJyArXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbm93ICsgJ3B4LCAwcHgpJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF8uJHNsaWRlVHJhY2suY3NzKGFuaW1Qcm9wcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbmltUHJvcHNbXy5hbmltVHlwZV0gPSAndHJhbnNsYXRlKDBweCwnICtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBub3cgKyAncHgpJztcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF8uJHNsaWRlVHJhY2suY3NzKGFuaW1Qcm9wcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbXBsZXRlOiBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjay5jYWxsKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICAgICAgICAgICAgXy5hcHBseVRyYW5zaXRpb24oKTtcclxuICAgICAgICAgICAgICAgIHRhcmdldExlZnQgPSBNYXRoLmNlaWwodGFyZ2V0TGVmdCk7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKF8ub3B0aW9ucy52ZXJ0aWNhbCA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgICAgICAgICBhbmltUHJvcHNbXy5hbmltVHlwZV0gPSAndHJhbnNsYXRlM2QoJyArIHRhcmdldExlZnQgKyAncHgsIDBweCwgMHB4KSc7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGFuaW1Qcm9wc1tfLmFuaW1UeXBlXSA9ICd0cmFuc2xhdGUzZCgwcHgsJyArIHRhcmdldExlZnQgKyAncHgsIDBweCknO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgXy4kc2xpZGVUcmFjay5jc3MoYW5pbVByb3BzKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoY2FsbGJhY2spIHtcclxuICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgXy5kaXNhYmxlVHJhbnNpdGlvbigpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2suY2FsbCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sIF8ub3B0aW9ucy5zcGVlZCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5nZXROYXZUYXJnZXQgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzLFxyXG4gICAgICAgICAgICBhc05hdkZvciA9IF8ub3B0aW9ucy5hc05hdkZvcjtcclxuXHJcbiAgICAgICAgaWYgKCBhc05hdkZvciAmJiBhc05hdkZvciAhPT0gbnVsbCApIHtcclxuICAgICAgICAgICAgYXNOYXZGb3IgPSAkKGFzTmF2Rm9yKS5ub3QoXy4kc2xpZGVyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBhc05hdkZvcjtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5hc05hdkZvciA9IGZ1bmN0aW9uKGluZGV4KSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcyxcclxuICAgICAgICAgICAgYXNOYXZGb3IgPSBfLmdldE5hdlRhcmdldCgpO1xyXG5cclxuICAgICAgICBpZiAoIGFzTmF2Rm9yICE9PSBudWxsICYmIHR5cGVvZiBhc05hdkZvciA9PT0gJ29iamVjdCcgKSB7XHJcbiAgICAgICAgICAgIGFzTmF2Rm9yLmVhY2goZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgdGFyZ2V0ID0gJCh0aGlzKS5zbGljaygnZ2V0U2xpY2snKTtcclxuICAgICAgICAgICAgICAgIGlmKCF0YXJnZXQudW5zbGlja2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0LnNsaWRlSGFuZGxlcihpbmRleCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5hcHBseVRyYW5zaXRpb24gPSBmdW5jdGlvbihzbGlkZSkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXMsXHJcbiAgICAgICAgICAgIHRyYW5zaXRpb24gPSB7fTtcclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5mYWRlID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICB0cmFuc2l0aW9uW18udHJhbnNpdGlvblR5cGVdID0gXy50cmFuc2Zvcm1UeXBlICsgJyAnICsgXy5vcHRpb25zLnNwZWVkICsgJ21zICcgKyBfLm9wdGlvbnMuY3NzRWFzZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0cmFuc2l0aW9uW18udHJhbnNpdGlvblR5cGVdID0gJ29wYWNpdHkgJyArIF8ub3B0aW9ucy5zcGVlZCArICdtcyAnICsgXy5vcHRpb25zLmNzc0Vhc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLmZhZGUgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIF8uJHNsaWRlVHJhY2suY3NzKHRyYW5zaXRpb24pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIF8uJHNsaWRlcy5lcShzbGlkZSkuY3NzKHRyYW5zaXRpb24pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5hdXRvUGxheSA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIF8uYXV0b1BsYXlDbGVhcigpO1xyXG5cclxuICAgICAgICBpZiAoIF8uc2xpZGVDb3VudCA+IF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cgKSB7XHJcbiAgICAgICAgICAgIF8uYXV0b1BsYXlUaW1lciA9IHNldEludGVydmFsKCBfLmF1dG9QbGF5SXRlcmF0b3IsIF8ub3B0aW9ucy5hdXRvcGxheVNwZWVkICk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmF1dG9QbGF5Q2xlYXIgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgICBpZiAoXy5hdXRvUGxheVRpbWVyKSB7XHJcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwoXy5hdXRvUGxheVRpbWVyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuYXV0b1BsYXlJdGVyYXRvciA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXMsXHJcbiAgICAgICAgICAgIHNsaWRlVG8gPSBfLmN1cnJlbnRTbGlkZSArIF8ub3B0aW9ucy5zbGlkZXNUb1Njcm9sbDtcclxuXHJcbiAgICAgICAgaWYgKCAhXy5wYXVzZWQgJiYgIV8uaW50ZXJydXB0ZWQgJiYgIV8uZm9jdXNzZWQgKSB7XHJcblxyXG4gICAgICAgICAgICBpZiAoIF8ub3B0aW9ucy5pbmZpbml0ZSA9PT0gZmFsc2UgKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCBfLmRpcmVjdGlvbiA9PT0gMSAmJiAoIF8uY3VycmVudFNsaWRlICsgMSApID09PSAoIF8uc2xpZGVDb3VudCAtIDEgKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIF8uZGlyZWN0aW9uID0gMDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmICggXy5kaXJlY3Rpb24gPT09IDAgKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHNsaWRlVG8gPSBfLmN1cnJlbnRTbGlkZSAtIF8ub3B0aW9ucy5zbGlkZXNUb1Njcm9sbDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCBfLmN1cnJlbnRTbGlkZSAtIDEgPT09IDAgKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF8uZGlyZWN0aW9uID0gMTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgXy5zbGlkZUhhbmRsZXIoIHNsaWRlVG8gKTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmJ1aWxkQXJyb3dzID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcztcclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5hcnJvd3MgPT09IHRydWUgKSB7XHJcblxyXG4gICAgICAgICAgICBfLiRwcmV2QXJyb3cgPSAkKF8ub3B0aW9ucy5wcmV2QXJyb3cpLmFkZENsYXNzKCdzbGljay1hcnJvdycpO1xyXG4gICAgICAgICAgICBfLiRuZXh0QXJyb3cgPSAkKF8ub3B0aW9ucy5uZXh0QXJyb3cpLmFkZENsYXNzKCdzbGljay1hcnJvdycpO1xyXG5cclxuICAgICAgICAgICAgaWYoIF8uc2xpZGVDb3VudCA+IF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cgKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgXy4kcHJldkFycm93LnJlbW92ZUNsYXNzKCdzbGljay1oaWRkZW4nKS5yZW1vdmVBdHRyKCdhcmlhLWhpZGRlbiB0YWJpbmRleCcpO1xyXG4gICAgICAgICAgICAgICAgXy4kbmV4dEFycm93LnJlbW92ZUNsYXNzKCdzbGljay1oaWRkZW4nKS5yZW1vdmVBdHRyKCdhcmlhLWhpZGRlbiB0YWJpbmRleCcpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChfLmh0bWxFeHByLnRlc3QoXy5vcHRpb25zLnByZXZBcnJvdykpIHtcclxuICAgICAgICAgICAgICAgICAgICBfLiRwcmV2QXJyb3cucHJlcGVuZFRvKF8ub3B0aW9ucy5hcHBlbmRBcnJvd3MpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChfLmh0bWxFeHByLnRlc3QoXy5vcHRpb25zLm5leHRBcnJvdykpIHtcclxuICAgICAgICAgICAgICAgICAgICBfLiRuZXh0QXJyb3cuYXBwZW5kVG8oXy5vcHRpb25zLmFwcGVuZEFycm93cyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKF8ub3B0aW9ucy5pbmZpbml0ZSAhPT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIF8uJHByZXZBcnJvd1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ3NsaWNrLWRpc2FibGVkJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2FyaWEtZGlzYWJsZWQnLCAndHJ1ZScpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuXHJcbiAgICAgICAgICAgICAgICBfLiRwcmV2QXJyb3cuYWRkKCBfLiRuZXh0QXJyb3cgKVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ3NsaWNrLWhpZGRlbicpXHJcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAnYXJpYS1kaXNhYmxlZCc6ICd0cnVlJyxcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ3RhYmluZGV4JzogJy0xJ1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG5cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuYnVpbGREb3RzID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcyxcclxuICAgICAgICAgICAgaSwgZG90O1xyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLmRvdHMgPT09IHRydWUgJiYgXy5zbGlkZUNvdW50ID4gXy5vcHRpb25zLnNsaWRlc1RvU2hvdykge1xyXG5cclxuICAgICAgICAgICAgXy4kc2xpZGVyLmFkZENsYXNzKCdzbGljay1kb3R0ZWQnKTtcclxuXHJcbiAgICAgICAgICAgIGRvdCA9ICQoJzx1bCAvPicpLmFkZENsYXNzKF8ub3B0aW9ucy5kb3RzQ2xhc3MpO1xyXG5cclxuICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8PSBfLmdldERvdENvdW50KCk7IGkgKz0gMSkge1xyXG4gICAgICAgICAgICAgICAgZG90LmFwcGVuZCgkKCc8bGkgLz4nKS5hcHBlbmQoXy5vcHRpb25zLmN1c3RvbVBhZ2luZy5jYWxsKHRoaXMsIF8sIGkpKSk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIF8uJGRvdHMgPSBkb3QuYXBwZW5kVG8oXy5vcHRpb25zLmFwcGVuZERvdHMpO1xyXG5cclxuICAgICAgICAgICAgXy4kZG90cy5maW5kKCdsaScpLmZpcnN0KCkuYWRkQ2xhc3MoJ3NsaWNrLWFjdGl2ZScpLmF0dHIoJ2FyaWEtaGlkZGVuJywgJ2ZhbHNlJyk7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5idWlsZE91dCA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIF8uJHNsaWRlcyA9XHJcbiAgICAgICAgICAgIF8uJHNsaWRlclxyXG4gICAgICAgICAgICAgICAgLmNoaWxkcmVuKCBfLm9wdGlvbnMuc2xpZGUgKyAnOm5vdCguc2xpY2stY2xvbmVkKScpXHJcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ3NsaWNrLXNsaWRlJyk7XHJcblxyXG4gICAgICAgIF8uc2xpZGVDb3VudCA9IF8uJHNsaWRlcy5sZW5ndGg7XHJcblxyXG4gICAgICAgIF8uJHNsaWRlcy5lYWNoKGZ1bmN0aW9uKGluZGV4LCBlbGVtZW50KSB7XHJcbiAgICAgICAgICAgICQoZWxlbWVudClcclxuICAgICAgICAgICAgICAgIC5hdHRyKCdkYXRhLXNsaWNrLWluZGV4JywgaW5kZXgpXHJcbiAgICAgICAgICAgICAgICAuZGF0YSgnb3JpZ2luYWxTdHlsaW5nJywgJChlbGVtZW50KS5hdHRyKCdzdHlsZScpIHx8ICcnKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgXy4kc2xpZGVyLmFkZENsYXNzKCdzbGljay1zbGlkZXInKTtcclxuXHJcbiAgICAgICAgXy4kc2xpZGVUcmFjayA9IChfLnNsaWRlQ291bnQgPT09IDApID9cclxuICAgICAgICAgICAgJCgnPGRpdiBjbGFzcz1cInNsaWNrLXRyYWNrXCIvPicpLmFwcGVuZFRvKF8uJHNsaWRlcikgOlxyXG4gICAgICAgICAgICBfLiRzbGlkZXMud3JhcEFsbCgnPGRpdiBjbGFzcz1cInNsaWNrLXRyYWNrXCIvPicpLnBhcmVudCgpO1xyXG5cclxuICAgICAgICBfLiRsaXN0ID0gXy4kc2xpZGVUcmFjay53cmFwKFxyXG4gICAgICAgICAgICAnPGRpdiBhcmlhLWxpdmU9XCJwb2xpdGVcIiBjbGFzcz1cInNsaWNrLWxpc3RcIi8+JykucGFyZW50KCk7XHJcbiAgICAgICAgXy4kc2xpZGVUcmFjay5jc3MoJ29wYWNpdHknLCAwKTtcclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5jZW50ZXJNb2RlID09PSB0cnVlIHx8IF8ub3B0aW9ucy5zd2lwZVRvU2xpZGUgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgXy5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsID0gMTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgICQoJ2ltZ1tkYXRhLWxhenldJywgXy4kc2xpZGVyKS5ub3QoJ1tzcmNdJykuYWRkQ2xhc3MoJ3NsaWNrLWxvYWRpbmcnKTtcclxuXHJcbiAgICAgICAgXy5zZXR1cEluZmluaXRlKCk7XHJcblxyXG4gICAgICAgIF8uYnVpbGRBcnJvd3MoKTtcclxuXHJcbiAgICAgICAgXy5idWlsZERvdHMoKTtcclxuXHJcbiAgICAgICAgXy51cGRhdGVEb3RzKCk7XHJcblxyXG5cclxuICAgICAgICBfLnNldFNsaWRlQ2xhc3Nlcyh0eXBlb2YgXy5jdXJyZW50U2xpZGUgPT09ICdudW1iZXInID8gXy5jdXJyZW50U2xpZGUgOiAwKTtcclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5kcmFnZ2FibGUgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgXy4kbGlzdC5hZGRDbGFzcygnZHJhZ2dhYmxlJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmJ1aWxkUm93cyA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXMsIGEsIGIsIGMsIG5ld1NsaWRlcywgbnVtT2ZTbGlkZXMsIG9yaWdpbmFsU2xpZGVzLHNsaWRlc1BlclNlY3Rpb247XHJcblxyXG4gICAgICAgIG5ld1NsaWRlcyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcclxuICAgICAgICBvcmlnaW5hbFNsaWRlcyA9IF8uJHNsaWRlci5jaGlsZHJlbigpO1xyXG5cclxuICAgICAgICBpZihfLm9wdGlvbnMucm93cyA+IDEpIHtcclxuXHJcbiAgICAgICAgICAgIHNsaWRlc1BlclNlY3Rpb24gPSBfLm9wdGlvbnMuc2xpZGVzUGVyUm93ICogXy5vcHRpb25zLnJvd3M7XHJcbiAgICAgICAgICAgIG51bU9mU2xpZGVzID0gTWF0aC5jZWlsKFxyXG4gICAgICAgICAgICAgICAgb3JpZ2luYWxTbGlkZXMubGVuZ3RoIC8gc2xpZGVzUGVyU2VjdGlvblxyXG4gICAgICAgICAgICApO1xyXG5cclxuICAgICAgICAgICAgZm9yKGEgPSAwOyBhIDwgbnVtT2ZTbGlkZXM7IGErKyl7XHJcbiAgICAgICAgICAgICAgICB2YXIgc2xpZGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgICAgICAgICAgICAgIGZvcihiID0gMDsgYiA8IF8ub3B0aW9ucy5yb3dzOyBiKyspIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcm93ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yKGMgPSAwOyBjIDwgXy5vcHRpb25zLnNsaWRlc1BlclJvdzsgYysrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB0YXJnZXQgPSAoYSAqIHNsaWRlc1BlclNlY3Rpb24gKyAoKGIgKiBfLm9wdGlvbnMuc2xpZGVzUGVyUm93KSArIGMpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKG9yaWdpbmFsU2xpZGVzLmdldCh0YXJnZXQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3cuYXBwZW5kQ2hpbGQob3JpZ2luYWxTbGlkZXMuZ2V0KHRhcmdldCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHNsaWRlLmFwcGVuZENoaWxkKHJvdyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBuZXdTbGlkZXMuYXBwZW5kQ2hpbGQoc2xpZGUpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBfLiRzbGlkZXIuZW1wdHkoKS5hcHBlbmQobmV3U2xpZGVzKTtcclxuICAgICAgICAgICAgXy4kc2xpZGVyLmNoaWxkcmVuKCkuY2hpbGRyZW4oKS5jaGlsZHJlbigpXHJcbiAgICAgICAgICAgICAgICAuY3NzKHtcclxuICAgICAgICAgICAgICAgICAgICAnd2lkdGgnOigxMDAgLyBfLm9wdGlvbnMuc2xpZGVzUGVyUm93KSArICclJyxcclxuICAgICAgICAgICAgICAgICAgICAnZGlzcGxheSc6ICdpbmxpbmUtYmxvY2snXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmNoZWNrUmVzcG9uc2l2ZSA9IGZ1bmN0aW9uKGluaXRpYWwsIGZvcmNlVXBkYXRlKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcyxcclxuICAgICAgICAgICAgYnJlYWtwb2ludCwgdGFyZ2V0QnJlYWtwb2ludCwgcmVzcG9uZFRvV2lkdGgsIHRyaWdnZXJCcmVha3BvaW50ID0gZmFsc2U7XHJcbiAgICAgICAgdmFyIHNsaWRlcldpZHRoID0gXy4kc2xpZGVyLndpZHRoKCk7XHJcbiAgICAgICAgdmFyIHdpbmRvd1dpZHRoID0gd2luZG93LmlubmVyV2lkdGggfHwgJCh3aW5kb3cpLndpZHRoKCk7XHJcblxyXG4gICAgICAgIGlmIChfLnJlc3BvbmRUbyA9PT0gJ3dpbmRvdycpIHtcclxuICAgICAgICAgICAgcmVzcG9uZFRvV2lkdGggPSB3aW5kb3dXaWR0aDtcclxuICAgICAgICB9IGVsc2UgaWYgKF8ucmVzcG9uZFRvID09PSAnc2xpZGVyJykge1xyXG4gICAgICAgICAgICByZXNwb25kVG9XaWR0aCA9IHNsaWRlcldpZHRoO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoXy5yZXNwb25kVG8gPT09ICdtaW4nKSB7XHJcbiAgICAgICAgICAgIHJlc3BvbmRUb1dpZHRoID0gTWF0aC5taW4od2luZG93V2lkdGgsIHNsaWRlcldpZHRoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICggXy5vcHRpb25zLnJlc3BvbnNpdmUgJiZcclxuICAgICAgICAgICAgXy5vcHRpb25zLnJlc3BvbnNpdmUubGVuZ3RoICYmXHJcbiAgICAgICAgICAgIF8ub3B0aW9ucy5yZXNwb25zaXZlICE9PSBudWxsKSB7XHJcblxyXG4gICAgICAgICAgICB0YXJnZXRCcmVha3BvaW50ID0gbnVsbDtcclxuXHJcbiAgICAgICAgICAgIGZvciAoYnJlYWtwb2ludCBpbiBfLmJyZWFrcG9pbnRzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoXy5icmVha3BvaW50cy5oYXNPd25Qcm9wZXJ0eShicmVha3BvaW50KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChfLm9yaWdpbmFsU2V0dGluZ3MubW9iaWxlRmlyc3QgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXNwb25kVG9XaWR0aCA8IF8uYnJlYWtwb2ludHNbYnJlYWtwb2ludF0pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEJyZWFrcG9pbnQgPSBfLmJyZWFrcG9pbnRzW2JyZWFrcG9pbnRdO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3BvbmRUb1dpZHRoID4gXy5icmVha3BvaW50c1ticmVha3BvaW50XSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0QnJlYWtwb2ludCA9IF8uYnJlYWtwb2ludHNbYnJlYWtwb2ludF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmICh0YXJnZXRCcmVha3BvaW50ICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoXy5hY3RpdmVCcmVha3BvaW50ICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldEJyZWFrcG9pbnQgIT09IF8uYWN0aXZlQnJlYWtwb2ludCB8fCBmb3JjZVVwZGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfLmFjdGl2ZUJyZWFrcG9pbnQgPVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0QnJlYWtwb2ludDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKF8uYnJlYWtwb2ludFNldHRpbmdzW3RhcmdldEJyZWFrcG9pbnRdID09PSAndW5zbGljaycpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF8udW5zbGljayh0YXJnZXRCcmVha3BvaW50KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF8ub3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBfLm9yaWdpbmFsU2V0dGluZ3MsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXy5icmVha3BvaW50U2V0dGluZ3NbXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEJyZWFrcG9pbnRdKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbml0aWFsID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXy5jdXJyZW50U2xpZGUgPSBfLm9wdGlvbnMuaW5pdGlhbFNsaWRlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXy5yZWZyZXNoKGluaXRpYWwpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRyaWdnZXJCcmVha3BvaW50ID0gdGFyZ2V0QnJlYWtwb2ludDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIF8uYWN0aXZlQnJlYWtwb2ludCA9IHRhcmdldEJyZWFrcG9pbnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKF8uYnJlYWtwb2ludFNldHRpbmdzW3RhcmdldEJyZWFrcG9pbnRdID09PSAndW5zbGljaycpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXy51bnNsaWNrKHRhcmdldEJyZWFrcG9pbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF8ub3B0aW9ucyA9ICQuZXh0ZW5kKHt9LCBfLm9yaWdpbmFsU2V0dGluZ3MsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfLmJyZWFrcG9pbnRTZXR0aW5nc1tcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRCcmVha3BvaW50XSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbml0aWFsID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfLmN1cnJlbnRTbGlkZSA9IF8ub3B0aW9ucy5pbml0aWFsU2xpZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgXy5yZWZyZXNoKGluaXRpYWwpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyQnJlYWtwb2ludCA9IHRhcmdldEJyZWFrcG9pbnQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoXy5hY3RpdmVCcmVha3BvaW50ICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgXy5hY3RpdmVCcmVha3BvaW50ID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICBfLm9wdGlvbnMgPSBfLm9yaWdpbmFsU2V0dGluZ3M7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGluaXRpYWwgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXy5jdXJyZW50U2xpZGUgPSBfLm9wdGlvbnMuaW5pdGlhbFNsaWRlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBfLnJlZnJlc2goaW5pdGlhbCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdHJpZ2dlckJyZWFrcG9pbnQgPSB0YXJnZXRCcmVha3BvaW50O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBvbmx5IHRyaWdnZXIgYnJlYWtwb2ludHMgZHVyaW5nIGFuIGFjdHVhbCBicmVhay4gbm90IG9uIGluaXRpYWxpemUuXHJcbiAgICAgICAgICAgIGlmKCAhaW5pdGlhbCAmJiB0cmlnZ2VyQnJlYWtwb2ludCAhPT0gZmFsc2UgKSB7XHJcbiAgICAgICAgICAgICAgICBfLiRzbGlkZXIudHJpZ2dlcignYnJlYWtwb2ludCcsIFtfLCB0cmlnZ2VyQnJlYWtwb2ludF0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmNoYW5nZVNsaWRlID0gZnVuY3Rpb24oZXZlbnQsIGRvbnRBbmltYXRlKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcyxcclxuICAgICAgICAgICAgJHRhcmdldCA9ICQoZXZlbnQuY3VycmVudFRhcmdldCksXHJcbiAgICAgICAgICAgIGluZGV4T2Zmc2V0LCBzbGlkZU9mZnNldCwgdW5ldmVuT2Zmc2V0O1xyXG5cclxuICAgICAgICAvLyBJZiB0YXJnZXQgaXMgYSBsaW5rLCBwcmV2ZW50IGRlZmF1bHQgYWN0aW9uLlxyXG4gICAgICAgIGlmKCR0YXJnZXQuaXMoJ2EnKSkge1xyXG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gSWYgdGFyZ2V0IGlzIG5vdCB0aGUgPGxpPiBlbGVtZW50IChpZTogYSBjaGlsZCksIGZpbmQgdGhlIDxsaT4uXHJcbiAgICAgICAgaWYoISR0YXJnZXQuaXMoJ2xpJykpIHtcclxuICAgICAgICAgICAgJHRhcmdldCA9ICR0YXJnZXQuY2xvc2VzdCgnbGknKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHVuZXZlbk9mZnNldCA9IChfLnNsaWRlQ291bnQgJSBfLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwgIT09IDApO1xyXG4gICAgICAgIGluZGV4T2Zmc2V0ID0gdW5ldmVuT2Zmc2V0ID8gMCA6IChfLnNsaWRlQ291bnQgLSBfLmN1cnJlbnRTbGlkZSkgJSBfLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGw7XHJcblxyXG4gICAgICAgIHN3aXRjaCAoZXZlbnQuZGF0YS5tZXNzYWdlKSB7XHJcblxyXG4gICAgICAgICAgICBjYXNlICdwcmV2aW91cyc6XHJcbiAgICAgICAgICAgICAgICBzbGlkZU9mZnNldCA9IGluZGV4T2Zmc2V0ID09PSAwID8gXy5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsIDogXy5vcHRpb25zLnNsaWRlc1RvU2hvdyAtIGluZGV4T2Zmc2V0O1xyXG4gICAgICAgICAgICAgICAgaWYgKF8uc2xpZGVDb3VudCA+IF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cpIHtcclxuICAgICAgICAgICAgICAgICAgICBfLnNsaWRlSGFuZGxlcihfLmN1cnJlbnRTbGlkZSAtIHNsaWRlT2Zmc2V0LCBmYWxzZSwgZG9udEFuaW1hdGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICBjYXNlICduZXh0JzpcclxuICAgICAgICAgICAgICAgIHNsaWRlT2Zmc2V0ID0gaW5kZXhPZmZzZXQgPT09IDAgPyBfLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwgOiBpbmRleE9mZnNldDtcclxuICAgICAgICAgICAgICAgIGlmIChfLnNsaWRlQ291bnQgPiBfLm9wdGlvbnMuc2xpZGVzVG9TaG93KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgXy5zbGlkZUhhbmRsZXIoXy5jdXJyZW50U2xpZGUgKyBzbGlkZU9mZnNldCwgZmFsc2UsIGRvbnRBbmltYXRlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG5cclxuICAgICAgICAgICAgY2FzZSAnaW5kZXgnOlxyXG4gICAgICAgICAgICAgICAgdmFyIGluZGV4ID0gZXZlbnQuZGF0YS5pbmRleCA9PT0gMCA/IDAgOlxyXG4gICAgICAgICAgICAgICAgICAgIGV2ZW50LmRhdGEuaW5kZXggfHwgJHRhcmdldC5pbmRleCgpICogXy5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsO1xyXG5cclxuICAgICAgICAgICAgICAgIF8uc2xpZGVIYW5kbGVyKF8uY2hlY2tOYXZpZ2FibGUoaW5kZXgpLCBmYWxzZSwgZG9udEFuaW1hdGUpO1xyXG4gICAgICAgICAgICAgICAgJHRhcmdldC5jaGlsZHJlbigpLnRyaWdnZXIoJ2ZvY3VzJyk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmNoZWNrTmF2aWdhYmxlID0gZnVuY3Rpb24oaW5kZXgpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzLFxyXG4gICAgICAgICAgICBuYXZpZ2FibGVzLCBwcmV2TmF2aWdhYmxlO1xyXG5cclxuICAgICAgICBuYXZpZ2FibGVzID0gXy5nZXROYXZpZ2FibGVJbmRleGVzKCk7XHJcbiAgICAgICAgcHJldk5hdmlnYWJsZSA9IDA7XHJcbiAgICAgICAgaWYgKGluZGV4ID4gbmF2aWdhYmxlc1tuYXZpZ2FibGVzLmxlbmd0aCAtIDFdKSB7XHJcbiAgICAgICAgICAgIGluZGV4ID0gbmF2aWdhYmxlc1tuYXZpZ2FibGVzLmxlbmd0aCAtIDFdO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGZvciAodmFyIG4gaW4gbmF2aWdhYmxlcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4IDwgbmF2aWdhYmxlc1tuXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGluZGV4ID0gcHJldk5hdmlnYWJsZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHByZXZOYXZpZ2FibGUgPSBuYXZpZ2FibGVzW25dO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gaW5kZXg7XHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5jbGVhblVwRXZlbnRzID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcztcclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5kb3RzICYmIF8uJGRvdHMgIT09IG51bGwpIHtcclxuXHJcbiAgICAgICAgICAgICQoJ2xpJywgXy4kZG90cylcclxuICAgICAgICAgICAgICAgIC5vZmYoJ2NsaWNrLnNsaWNrJywgXy5jaGFuZ2VTbGlkZSlcclxuICAgICAgICAgICAgICAgIC5vZmYoJ21vdXNlZW50ZXIuc2xpY2snLCAkLnByb3h5KF8uaW50ZXJydXB0LCBfLCB0cnVlKSlcclxuICAgICAgICAgICAgICAgIC5vZmYoJ21vdXNlbGVhdmUuc2xpY2snLCAkLnByb3h5KF8uaW50ZXJydXB0LCBfLCBmYWxzZSkpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIF8uJHNsaWRlci5vZmYoJ2ZvY3VzLnNsaWNrIGJsdXIuc2xpY2snKTtcclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5hcnJvd3MgPT09IHRydWUgJiYgXy5zbGlkZUNvdW50ID4gXy5vcHRpb25zLnNsaWRlc1RvU2hvdykge1xyXG4gICAgICAgICAgICBfLiRwcmV2QXJyb3cgJiYgXy4kcHJldkFycm93Lm9mZignY2xpY2suc2xpY2snLCBfLmNoYW5nZVNsaWRlKTtcclxuICAgICAgICAgICAgXy4kbmV4dEFycm93ICYmIF8uJG5leHRBcnJvdy5vZmYoJ2NsaWNrLnNsaWNrJywgXy5jaGFuZ2VTbGlkZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBfLiRsaXN0Lm9mZigndG91Y2hzdGFydC5zbGljayBtb3VzZWRvd24uc2xpY2snLCBfLnN3aXBlSGFuZGxlcik7XHJcbiAgICAgICAgXy4kbGlzdC5vZmYoJ3RvdWNobW92ZS5zbGljayBtb3VzZW1vdmUuc2xpY2snLCBfLnN3aXBlSGFuZGxlcik7XHJcbiAgICAgICAgXy4kbGlzdC5vZmYoJ3RvdWNoZW5kLnNsaWNrIG1vdXNldXAuc2xpY2snLCBfLnN3aXBlSGFuZGxlcik7XHJcbiAgICAgICAgXy4kbGlzdC5vZmYoJ3RvdWNoY2FuY2VsLnNsaWNrIG1vdXNlbGVhdmUuc2xpY2snLCBfLnN3aXBlSGFuZGxlcik7XHJcblxyXG4gICAgICAgIF8uJGxpc3Qub2ZmKCdjbGljay5zbGljaycsIF8uY2xpY2tIYW5kbGVyKTtcclxuXHJcbiAgICAgICAgJChkb2N1bWVudCkub2ZmKF8udmlzaWJpbGl0eUNoYW5nZSwgXy52aXNpYmlsaXR5KTtcclxuXHJcbiAgICAgICAgXy5jbGVhblVwU2xpZGVFdmVudHMoKTtcclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5hY2Nlc3NpYmlsaXR5ID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIF8uJGxpc3Qub2ZmKCdrZXlkb3duLnNsaWNrJywgXy5rZXlIYW5kbGVyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChfLm9wdGlvbnMuZm9jdXNPblNlbGVjdCA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAkKF8uJHNsaWRlVHJhY2spLmNoaWxkcmVuKCkub2ZmKCdjbGljay5zbGljaycsIF8uc2VsZWN0SGFuZGxlcik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAkKHdpbmRvdykub2ZmKCdvcmllbnRhdGlvbmNoYW5nZS5zbGljay5zbGljay0nICsgXy5pbnN0YW5jZVVpZCwgXy5vcmllbnRhdGlvbkNoYW5nZSk7XHJcblxyXG4gICAgICAgICQod2luZG93KS5vZmYoJ3Jlc2l6ZS5zbGljay5zbGljay0nICsgXy5pbnN0YW5jZVVpZCwgXy5yZXNpemUpO1xyXG5cclxuICAgICAgICAkKCdbZHJhZ2dhYmxlIT10cnVlXScsIF8uJHNsaWRlVHJhY2spLm9mZignZHJhZ3N0YXJ0JywgXy5wcmV2ZW50RGVmYXVsdCk7XHJcblxyXG4gICAgICAgICQod2luZG93KS5vZmYoJ2xvYWQuc2xpY2suc2xpY2stJyArIF8uaW5zdGFuY2VVaWQsIF8uc2V0UG9zaXRpb24pO1xyXG4gICAgICAgICQoZG9jdW1lbnQpLm9mZigncmVhZHkuc2xpY2suc2xpY2stJyArIF8uaW5zdGFuY2VVaWQsIF8uc2V0UG9zaXRpb24pO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmNsZWFuVXBTbGlkZUV2ZW50cyA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIF8uJGxpc3Qub2ZmKCdtb3VzZWVudGVyLnNsaWNrJywgJC5wcm94eShfLmludGVycnVwdCwgXywgdHJ1ZSkpO1xyXG4gICAgICAgIF8uJGxpc3Qub2ZmKCdtb3VzZWxlYXZlLnNsaWNrJywgJC5wcm94eShfLmludGVycnVwdCwgXywgZmFsc2UpKTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5jbGVhblVwUm93cyA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXMsIG9yaWdpbmFsU2xpZGVzO1xyXG5cclxuICAgICAgICBpZihfLm9wdGlvbnMucm93cyA+IDEpIHtcclxuICAgICAgICAgICAgb3JpZ2luYWxTbGlkZXMgPSBfLiRzbGlkZXMuY2hpbGRyZW4oKS5jaGlsZHJlbigpO1xyXG4gICAgICAgICAgICBvcmlnaW5hbFNsaWRlcy5yZW1vdmVBdHRyKCdzdHlsZScpO1xyXG4gICAgICAgICAgICBfLiRzbGlkZXIuZW1wdHkoKS5hcHBlbmQob3JpZ2luYWxTbGlkZXMpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5jbGlja0hhbmRsZXIgPSBmdW5jdGlvbihldmVudCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIGlmIChfLnNob3VsZENsaWNrID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbihyZWZyZXNoKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcztcclxuXHJcbiAgICAgICAgXy5hdXRvUGxheUNsZWFyKCk7XHJcblxyXG4gICAgICAgIF8udG91Y2hPYmplY3QgPSB7fTtcclxuXHJcbiAgICAgICAgXy5jbGVhblVwRXZlbnRzKCk7XHJcblxyXG4gICAgICAgICQoJy5zbGljay1jbG9uZWQnLCBfLiRzbGlkZXIpLmRldGFjaCgpO1xyXG5cclxuICAgICAgICBpZiAoXy4kZG90cykge1xyXG4gICAgICAgICAgICBfLiRkb3RzLnJlbW92ZSgpO1xyXG4gICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgIGlmICggXy4kcHJldkFycm93ICYmIF8uJHByZXZBcnJvdy5sZW5ndGggKSB7XHJcblxyXG4gICAgICAgICAgICBfLiRwcmV2QXJyb3dcclxuICAgICAgICAgICAgICAgIC5yZW1vdmVDbGFzcygnc2xpY2stZGlzYWJsZWQgc2xpY2stYXJyb3cgc2xpY2staGlkZGVuJylcclxuICAgICAgICAgICAgICAgIC5yZW1vdmVBdHRyKCdhcmlhLWhpZGRlbiBhcmlhLWRpc2FibGVkIHRhYmluZGV4JylcclxuICAgICAgICAgICAgICAgIC5jc3MoJ2Rpc3BsYXknLCcnKTtcclxuXHJcbiAgICAgICAgICAgIGlmICggXy5odG1sRXhwci50ZXN0KCBfLm9wdGlvbnMucHJldkFycm93ICkpIHtcclxuICAgICAgICAgICAgICAgIF8uJHByZXZBcnJvdy5yZW1vdmUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCBfLiRuZXh0QXJyb3cgJiYgXy4kbmV4dEFycm93Lmxlbmd0aCApIHtcclxuXHJcbiAgICAgICAgICAgIF8uJG5leHRBcnJvd1xyXG4gICAgICAgICAgICAgICAgLnJlbW92ZUNsYXNzKCdzbGljay1kaXNhYmxlZCBzbGljay1hcnJvdyBzbGljay1oaWRkZW4nKVxyXG4gICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2FyaWEtaGlkZGVuIGFyaWEtZGlzYWJsZWQgdGFiaW5kZXgnKVxyXG4gICAgICAgICAgICAgICAgLmNzcygnZGlzcGxheScsJycpO1xyXG5cclxuICAgICAgICAgICAgaWYgKCBfLmh0bWxFeHByLnRlc3QoIF8ub3B0aW9ucy5uZXh0QXJyb3cgKSkge1xyXG4gICAgICAgICAgICAgICAgXy4kbmV4dEFycm93LnJlbW92ZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgIGlmIChfLiRzbGlkZXMpIHtcclxuXHJcbiAgICAgICAgICAgIF8uJHNsaWRlc1xyXG4gICAgICAgICAgICAgICAgLnJlbW92ZUNsYXNzKCdzbGljay1zbGlkZSBzbGljay1hY3RpdmUgc2xpY2stY2VudGVyIHNsaWNrLXZpc2libGUgc2xpY2stY3VycmVudCcpXHJcbiAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignYXJpYS1oaWRkZW4nKVxyXG4gICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2RhdGEtc2xpY2staW5kZXgnKVxyXG4gICAgICAgICAgICAgICAgLmVhY2goZnVuY3Rpb24oKXtcclxuICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLmF0dHIoJ3N0eWxlJywgJCh0aGlzKS5kYXRhKCdvcmlnaW5hbFN0eWxpbmcnKSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIF8uJHNsaWRlVHJhY2suY2hpbGRyZW4odGhpcy5vcHRpb25zLnNsaWRlKS5kZXRhY2goKTtcclxuXHJcbiAgICAgICAgICAgIF8uJHNsaWRlVHJhY2suZGV0YWNoKCk7XHJcblxyXG4gICAgICAgICAgICBfLiRsaXN0LmRldGFjaCgpO1xyXG5cclxuICAgICAgICAgICAgXy4kc2xpZGVyLmFwcGVuZChfLiRzbGlkZXMpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgXy5jbGVhblVwUm93cygpO1xyXG5cclxuICAgICAgICBfLiRzbGlkZXIucmVtb3ZlQ2xhc3MoJ3NsaWNrLXNsaWRlcicpO1xyXG4gICAgICAgIF8uJHNsaWRlci5yZW1vdmVDbGFzcygnc2xpY2staW5pdGlhbGl6ZWQnKTtcclxuICAgICAgICBfLiRzbGlkZXIucmVtb3ZlQ2xhc3MoJ3NsaWNrLWRvdHRlZCcpO1xyXG5cclxuICAgICAgICBfLnVuc2xpY2tlZCA9IHRydWU7XHJcblxyXG4gICAgICAgIGlmKCFyZWZyZXNoKSB7XHJcbiAgICAgICAgICAgIF8uJHNsaWRlci50cmlnZ2VyKCdkZXN0cm95JywgW19dKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuZGlzYWJsZVRyYW5zaXRpb24gPSBmdW5jdGlvbihzbGlkZSkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXMsXHJcbiAgICAgICAgICAgIHRyYW5zaXRpb24gPSB7fTtcclxuXHJcbiAgICAgICAgdHJhbnNpdGlvbltfLnRyYW5zaXRpb25UeXBlXSA9ICcnO1xyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLmZhZGUgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIF8uJHNsaWRlVHJhY2suY3NzKHRyYW5zaXRpb24pO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIF8uJHNsaWRlcy5lcShzbGlkZSkuY3NzKHRyYW5zaXRpb24pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5mYWRlU2xpZGUgPSBmdW5jdGlvbihzbGlkZUluZGV4LCBjYWxsYmFjaykge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIGlmIChfLmNzc1RyYW5zaXRpb25zID09PSBmYWxzZSkge1xyXG5cclxuICAgICAgICAgICAgXy4kc2xpZGVzLmVxKHNsaWRlSW5kZXgpLmNzcyh7XHJcbiAgICAgICAgICAgICAgICB6SW5kZXg6IF8ub3B0aW9ucy56SW5kZXhcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICBfLiRzbGlkZXMuZXEoc2xpZGVJbmRleCkuYW5pbWF0ZSh7XHJcbiAgICAgICAgICAgICAgICBvcGFjaXR5OiAxXHJcbiAgICAgICAgICAgIH0sIF8ub3B0aW9ucy5zcGVlZCwgXy5vcHRpb25zLmVhc2luZywgY2FsbGJhY2spO1xyXG5cclxuICAgICAgICB9IGVsc2Uge1xyXG5cclxuICAgICAgICAgICAgXy5hcHBseVRyYW5zaXRpb24oc2xpZGVJbmRleCk7XHJcblxyXG4gICAgICAgICAgICBfLiRzbGlkZXMuZXEoc2xpZGVJbmRleCkuY3NzKHtcclxuICAgICAgICAgICAgICAgIG9wYWNpdHk6IDEsXHJcbiAgICAgICAgICAgICAgICB6SW5kZXg6IF8ub3B0aW9ucy56SW5kZXhcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICBpZiAoY2FsbGJhY2spIHtcclxuICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIF8uZGlzYWJsZVRyYW5zaXRpb24oc2xpZGVJbmRleCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrLmNhbGwoKTtcclxuICAgICAgICAgICAgICAgIH0sIF8ub3B0aW9ucy5zcGVlZCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmZhZGVTbGlkZU91dCA9IGZ1bmN0aW9uKHNsaWRlSW5kZXgpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgICBpZiAoXy5jc3NUcmFuc2l0aW9ucyA9PT0gZmFsc2UpIHtcclxuXHJcbiAgICAgICAgICAgIF8uJHNsaWRlcy5lcShzbGlkZUluZGV4KS5hbmltYXRlKHtcclxuICAgICAgICAgICAgICAgIG9wYWNpdHk6IDAsXHJcbiAgICAgICAgICAgICAgICB6SW5kZXg6IF8ub3B0aW9ucy56SW5kZXggLSAyXHJcbiAgICAgICAgICAgIH0sIF8ub3B0aW9ucy5zcGVlZCwgXy5vcHRpb25zLmVhc2luZyk7XHJcblxyXG4gICAgICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICAgICAgICBfLmFwcGx5VHJhbnNpdGlvbihzbGlkZUluZGV4KTtcclxuXHJcbiAgICAgICAgICAgIF8uJHNsaWRlcy5lcShzbGlkZUluZGV4KS5jc3Moe1xyXG4gICAgICAgICAgICAgICAgb3BhY2l0eTogMCxcclxuICAgICAgICAgICAgICAgIHpJbmRleDogXy5vcHRpb25zLnpJbmRleCAtIDJcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5maWx0ZXJTbGlkZXMgPSBTbGljay5wcm90b3R5cGUuc2xpY2tGaWx0ZXIgPSBmdW5jdGlvbihmaWx0ZXIpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgICBpZiAoZmlsdGVyICE9PSBudWxsKSB7XHJcblxyXG4gICAgICAgICAgICBfLiRzbGlkZXNDYWNoZSA9IF8uJHNsaWRlcztcclxuXHJcbiAgICAgICAgICAgIF8udW5sb2FkKCk7XHJcblxyXG4gICAgICAgICAgICBfLiRzbGlkZVRyYWNrLmNoaWxkcmVuKHRoaXMub3B0aW9ucy5zbGlkZSkuZGV0YWNoKCk7XHJcblxyXG4gICAgICAgICAgICBfLiRzbGlkZXNDYWNoZS5maWx0ZXIoZmlsdGVyKS5hcHBlbmRUbyhfLiRzbGlkZVRyYWNrKTtcclxuXHJcbiAgICAgICAgICAgIF8ucmVpbml0KCk7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5mb2N1c0hhbmRsZXIgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgICBfLiRzbGlkZXJcclxuICAgICAgICAgICAgLm9mZignZm9jdXMuc2xpY2sgYmx1ci5zbGljaycpXHJcbiAgICAgICAgICAgIC5vbignZm9jdXMuc2xpY2sgYmx1ci5zbGljaycsXHJcbiAgICAgICAgICAgICAgICAnKjpub3QoLnNsaWNrLWFycm93KScsIGZ1bmN0aW9uKGV2ZW50KSB7XHJcblxyXG4gICAgICAgICAgICBldmVudC5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgdmFyICRzZiA9ICQodGhpcyk7XHJcblxyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICAgICAgICAgIGlmKCBfLm9wdGlvbnMucGF1c2VPbkZvY3VzICkge1xyXG4gICAgICAgICAgICAgICAgICAgIF8uZm9jdXNzZWQgPSAkc2YuaXMoJzpmb2N1cycpO1xyXG4gICAgICAgICAgICAgICAgICAgIF8uYXV0b1BsYXkoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIH0sIDApO1xyXG5cclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmdldEN1cnJlbnQgPSBTbGljay5wcm90b3R5cGUuc2xpY2tDdXJyZW50U2xpZGUgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzO1xyXG4gICAgICAgIHJldHVybiBfLmN1cnJlbnRTbGlkZTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5nZXREb3RDb3VudCA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIHZhciBicmVha1BvaW50ID0gMDtcclxuICAgICAgICB2YXIgY291bnRlciA9IDA7XHJcbiAgICAgICAgdmFyIHBhZ2VyUXR5ID0gMDtcclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5pbmZpbml0ZSA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICB3aGlsZSAoYnJlYWtQb2ludCA8IF8uc2xpZGVDb3VudCkge1xyXG4gICAgICAgICAgICAgICAgKytwYWdlclF0eTtcclxuICAgICAgICAgICAgICAgIGJyZWFrUG9pbnQgPSBjb3VudGVyICsgXy5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsO1xyXG4gICAgICAgICAgICAgICAgY291bnRlciArPSBfLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwgPD0gXy5vcHRpb25zLnNsaWRlc1RvU2hvdyA/IF8ub3B0aW9ucy5zbGlkZXNUb1Njcm9sbCA6IF8ub3B0aW9ucy5zbGlkZXNUb1Nob3c7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKF8ub3B0aW9ucy5jZW50ZXJNb2RlID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIHBhZ2VyUXR5ID0gXy5zbGlkZUNvdW50O1xyXG4gICAgICAgIH0gZWxzZSBpZighXy5vcHRpb25zLmFzTmF2Rm9yKSB7XHJcbiAgICAgICAgICAgIHBhZ2VyUXR5ID0gMSArIE1hdGguY2VpbCgoXy5zbGlkZUNvdW50IC0gXy5vcHRpb25zLnNsaWRlc1RvU2hvdykgLyBfLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwpO1xyXG4gICAgICAgIH1lbHNlIHtcclxuICAgICAgICAgICAgd2hpbGUgKGJyZWFrUG9pbnQgPCBfLnNsaWRlQ291bnQpIHtcclxuICAgICAgICAgICAgICAgICsrcGFnZXJRdHk7XHJcbiAgICAgICAgICAgICAgICBicmVha1BvaW50ID0gY291bnRlciArIF8ub3B0aW9ucy5zbGlkZXNUb1Njcm9sbDtcclxuICAgICAgICAgICAgICAgIGNvdW50ZXIgKz0gXy5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsIDw9IF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cgPyBfLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwgOiBfLm9wdGlvbnMuc2xpZGVzVG9TaG93O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gcGFnZXJRdHkgLSAxO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmdldExlZnQgPSBmdW5jdGlvbihzbGlkZUluZGV4KSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcyxcclxuICAgICAgICAgICAgdGFyZ2V0TGVmdCxcclxuICAgICAgICAgICAgdmVydGljYWxIZWlnaHQsXHJcbiAgICAgICAgICAgIHZlcnRpY2FsT2Zmc2V0ID0gMCxcclxuICAgICAgICAgICAgdGFyZ2V0U2xpZGU7XHJcblxyXG4gICAgICAgIF8uc2xpZGVPZmZzZXQgPSAwO1xyXG4gICAgICAgIHZlcnRpY2FsSGVpZ2h0ID0gXy4kc2xpZGVzLmZpcnN0KCkub3V0ZXJIZWlnaHQodHJ1ZSk7XHJcblxyXG4gICAgICAgIGlmIChfLm9wdGlvbnMuaW5maW5pdGUgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgaWYgKF8uc2xpZGVDb3VudCA+IF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cpIHtcclxuICAgICAgICAgICAgICAgIF8uc2xpZGVPZmZzZXQgPSAoXy5zbGlkZVdpZHRoICogXy5vcHRpb25zLnNsaWRlc1RvU2hvdykgKiAtMTtcclxuICAgICAgICAgICAgICAgIHZlcnRpY2FsT2Zmc2V0ID0gKHZlcnRpY2FsSGVpZ2h0ICogXy5vcHRpb25zLnNsaWRlc1RvU2hvdykgKiAtMTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoXy5zbGlkZUNvdW50ICUgXy5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2xpZGVJbmRleCArIF8ub3B0aW9ucy5zbGlkZXNUb1Njcm9sbCA+IF8uc2xpZGVDb3VudCAmJiBfLnNsaWRlQ291bnQgPiBfLm9wdGlvbnMuc2xpZGVzVG9TaG93KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNsaWRlSW5kZXggPiBfLnNsaWRlQ291bnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXy5zbGlkZU9mZnNldCA9ICgoXy5vcHRpb25zLnNsaWRlc1RvU2hvdyAtIChzbGlkZUluZGV4IC0gXy5zbGlkZUNvdW50KSkgKiBfLnNsaWRlV2lkdGgpICogLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcnRpY2FsT2Zmc2V0ID0gKChfLm9wdGlvbnMuc2xpZGVzVG9TaG93IC0gKHNsaWRlSW5kZXggLSBfLnNsaWRlQ291bnQpKSAqIHZlcnRpY2FsSGVpZ2h0KSAqIC0xO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF8uc2xpZGVPZmZzZXQgPSAoKF8uc2xpZGVDb3VudCAlIF8ub3B0aW9ucy5zbGlkZXNUb1Njcm9sbCkgKiBfLnNsaWRlV2lkdGgpICogLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZlcnRpY2FsT2Zmc2V0ID0gKChfLnNsaWRlQ291bnQgJSBfLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwpICogdmVydGljYWxIZWlnaHQpICogLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaWYgKHNsaWRlSW5kZXggKyBfLm9wdGlvbnMuc2xpZGVzVG9TaG93ID4gXy5zbGlkZUNvdW50KSB7XHJcbiAgICAgICAgICAgICAgICBfLnNsaWRlT2Zmc2V0ID0gKChzbGlkZUluZGV4ICsgXy5vcHRpb25zLnNsaWRlc1RvU2hvdykgLSBfLnNsaWRlQ291bnQpICogXy5zbGlkZVdpZHRoO1xyXG4gICAgICAgICAgICAgICAgdmVydGljYWxPZmZzZXQgPSAoKHNsaWRlSW5kZXggKyBfLm9wdGlvbnMuc2xpZGVzVG9TaG93KSAtIF8uc2xpZGVDb3VudCkgKiB2ZXJ0aWNhbEhlaWdodDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKF8uc2xpZGVDb3VudCA8PSBfLm9wdGlvbnMuc2xpZGVzVG9TaG93KSB7XHJcbiAgICAgICAgICAgIF8uc2xpZGVPZmZzZXQgPSAwO1xyXG4gICAgICAgICAgICB2ZXJ0aWNhbE9mZnNldCA9IDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLmNlbnRlck1vZGUgPT09IHRydWUgJiYgXy5vcHRpb25zLmluZmluaXRlID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIF8uc2xpZGVPZmZzZXQgKz0gXy5zbGlkZVdpZHRoICogTWF0aC5mbG9vcihfLm9wdGlvbnMuc2xpZGVzVG9TaG93IC8gMikgLSBfLnNsaWRlV2lkdGg7XHJcbiAgICAgICAgfSBlbHNlIGlmIChfLm9wdGlvbnMuY2VudGVyTW9kZSA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICBfLnNsaWRlT2Zmc2V0ID0gMDtcclxuICAgICAgICAgICAgXy5zbGlkZU9mZnNldCArPSBfLnNsaWRlV2lkdGggKiBNYXRoLmZsb29yKF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cgLyAyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChfLm9wdGlvbnMudmVydGljYWwgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIHRhcmdldExlZnQgPSAoKHNsaWRlSW5kZXggKiBfLnNsaWRlV2lkdGgpICogLTEpICsgXy5zbGlkZU9mZnNldDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICB0YXJnZXRMZWZ0ID0gKChzbGlkZUluZGV4ICogdmVydGljYWxIZWlnaHQpICogLTEpICsgdmVydGljYWxPZmZzZXQ7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLnZhcmlhYmxlV2lkdGggPT09IHRydWUpIHtcclxuXHJcbiAgICAgICAgICAgIGlmIChfLnNsaWRlQ291bnQgPD0gXy5vcHRpb25zLnNsaWRlc1RvU2hvdyB8fCBfLm9wdGlvbnMuaW5maW5pdGUgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICB0YXJnZXRTbGlkZSA9IF8uJHNsaWRlVHJhY2suY2hpbGRyZW4oJy5zbGljay1zbGlkZScpLmVxKHNsaWRlSW5kZXgpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGFyZ2V0U2xpZGUgPSBfLiRzbGlkZVRyYWNrLmNoaWxkcmVuKCcuc2xpY2stc2xpZGUnKS5lcShzbGlkZUluZGV4ICsgXy5vcHRpb25zLnNsaWRlc1RvU2hvdyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChfLm9wdGlvbnMucnRsID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGFyZ2V0U2xpZGVbMF0pIHtcclxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRMZWZ0ID0gKF8uJHNsaWRlVHJhY2sud2lkdGgoKSAtIHRhcmdldFNsaWRlWzBdLm9mZnNldExlZnQgLSB0YXJnZXRTbGlkZS53aWR0aCgpKSAqIC0xO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0YXJnZXRMZWZ0ID0gIDA7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0YXJnZXRMZWZ0ID0gdGFyZ2V0U2xpZGVbMF0gPyB0YXJnZXRTbGlkZVswXS5vZmZzZXRMZWZ0ICogLTEgOiAwO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoXy5vcHRpb25zLmNlbnRlck1vZGUgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgICAgIGlmIChfLnNsaWRlQ291bnQgPD0gXy5vcHRpb25zLnNsaWRlc1RvU2hvdyB8fCBfLm9wdGlvbnMuaW5maW5pdGUgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0U2xpZGUgPSBfLiRzbGlkZVRyYWNrLmNoaWxkcmVuKCcuc2xpY2stc2xpZGUnKS5lcShzbGlkZUluZGV4KTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0U2xpZGUgPSBfLiRzbGlkZVRyYWNrLmNoaWxkcmVuKCcuc2xpY2stc2xpZGUnKS5lcShzbGlkZUluZGV4ICsgXy5vcHRpb25zLnNsaWRlc1RvU2hvdyArIDEpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmIChfLm9wdGlvbnMucnRsID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldFNsaWRlWzBdKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldExlZnQgPSAoXy4kc2xpZGVUcmFjay53aWR0aCgpIC0gdGFyZ2V0U2xpZGVbMF0ub2Zmc2V0TGVmdCAtIHRhcmdldFNsaWRlLndpZHRoKCkpICogLTE7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0TGVmdCA9ICAwO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGFyZ2V0TGVmdCA9IHRhcmdldFNsaWRlWzBdID8gdGFyZ2V0U2xpZGVbMF0ub2Zmc2V0TGVmdCAqIC0xIDogMDtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB0YXJnZXRMZWZ0ICs9IChfLiRsaXN0LndpZHRoKCkgLSB0YXJnZXRTbGlkZS5vdXRlcldpZHRoKCkpIC8gMjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHRhcmdldExlZnQ7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuZ2V0T3B0aW9uID0gU2xpY2sucHJvdG90eXBlLnNsaWNrR2V0T3B0aW9uID0gZnVuY3Rpb24ob3B0aW9uKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcztcclxuXHJcbiAgICAgICAgcmV0dXJuIF8ub3B0aW9uc1tvcHRpb25dO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmdldE5hdmlnYWJsZUluZGV4ZXMgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzLFxyXG4gICAgICAgICAgICBicmVha1BvaW50ID0gMCxcclxuICAgICAgICAgICAgY291bnRlciA9IDAsXHJcbiAgICAgICAgICAgIGluZGV4ZXMgPSBbXSxcclxuICAgICAgICAgICAgbWF4O1xyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLmluZmluaXRlID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICBtYXggPSBfLnNsaWRlQ291bnQ7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgYnJlYWtQb2ludCA9IF8ub3B0aW9ucy5zbGlkZXNUb1Njcm9sbCAqIC0xO1xyXG4gICAgICAgICAgICBjb3VudGVyID0gXy5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsICogLTE7XHJcbiAgICAgICAgICAgIG1heCA9IF8uc2xpZGVDb3VudCAqIDI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB3aGlsZSAoYnJlYWtQb2ludCA8IG1heCkge1xyXG4gICAgICAgICAgICBpbmRleGVzLnB1c2goYnJlYWtQb2ludCk7XHJcbiAgICAgICAgICAgIGJyZWFrUG9pbnQgPSBjb3VudGVyICsgXy5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsO1xyXG4gICAgICAgICAgICBjb3VudGVyICs9IF8ub3B0aW9ucy5zbGlkZXNUb1Njcm9sbCA8PSBfLm9wdGlvbnMuc2xpZGVzVG9TaG93ID8gXy5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsIDogXy5vcHRpb25zLnNsaWRlc1RvU2hvdztcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBpbmRleGVzO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmdldFNsaWNrID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmdldFNsaWRlQ291bnQgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzLFxyXG4gICAgICAgICAgICBzbGlkZXNUcmF2ZXJzZWQsIHN3aXBlZFNsaWRlLCBjZW50ZXJPZmZzZXQ7XHJcblxyXG4gICAgICAgIGNlbnRlck9mZnNldCA9IF8ub3B0aW9ucy5jZW50ZXJNb2RlID09PSB0cnVlID8gXy5zbGlkZVdpZHRoICogTWF0aC5mbG9vcihfLm9wdGlvbnMuc2xpZGVzVG9TaG93IC8gMikgOiAwO1xyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLnN3aXBlVG9TbGlkZSA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICBfLiRzbGlkZVRyYWNrLmZpbmQoJy5zbGljay1zbGlkZScpLmVhY2goZnVuY3Rpb24oaW5kZXgsIHNsaWRlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2xpZGUub2Zmc2V0TGVmdCAtIGNlbnRlck9mZnNldCArICgkKHNsaWRlKS5vdXRlcldpZHRoKCkgLyAyKSA+IChfLnN3aXBlTGVmdCAqIC0xKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHN3aXBlZFNsaWRlID0gc2xpZGU7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIHNsaWRlc1RyYXZlcnNlZCA9IE1hdGguYWJzKCQoc3dpcGVkU2xpZGUpLmF0dHIoJ2RhdGEtc2xpY2staW5kZXgnKSAtIF8uY3VycmVudFNsaWRlKSB8fCAxO1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHNsaWRlc1RyYXZlcnNlZDtcclxuXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIF8ub3B0aW9ucy5zbGlkZXNUb1Njcm9sbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuZ29UbyA9IFNsaWNrLnByb3RvdHlwZS5zbGlja0dvVG8gPSBmdW5jdGlvbihzbGlkZSwgZG9udEFuaW1hdGUpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgICBfLmNoYW5nZVNsaWRlKHtcclxuICAgICAgICAgICAgZGF0YToge1xyXG4gICAgICAgICAgICAgICAgbWVzc2FnZTogJ2luZGV4JyxcclxuICAgICAgICAgICAgICAgIGluZGV4OiBwYXJzZUludChzbGlkZSlcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sIGRvbnRBbmltYXRlKTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5pbml0ID0gZnVuY3Rpb24oY3JlYXRpb24pIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgICBpZiAoISQoXy4kc2xpZGVyKS5oYXNDbGFzcygnc2xpY2staW5pdGlhbGl6ZWQnKSkge1xyXG5cclxuICAgICAgICAgICAgJChfLiRzbGlkZXIpLmFkZENsYXNzKCdzbGljay1pbml0aWFsaXplZCcpO1xyXG5cclxuICAgICAgICAgICAgXy5idWlsZFJvd3MoKTtcclxuICAgICAgICAgICAgXy5idWlsZE91dCgpO1xyXG4gICAgICAgICAgICBfLnNldFByb3BzKCk7XHJcbiAgICAgICAgICAgIF8uc3RhcnRMb2FkKCk7XHJcbiAgICAgICAgICAgIF8ubG9hZFNsaWRlcigpO1xyXG4gICAgICAgICAgICBfLmluaXRpYWxpemVFdmVudHMoKTtcclxuICAgICAgICAgICAgXy51cGRhdGVBcnJvd3MoKTtcclxuICAgICAgICAgICAgXy51cGRhdGVEb3RzKCk7XHJcbiAgICAgICAgICAgIF8uY2hlY2tSZXNwb25zaXZlKHRydWUpO1xyXG4gICAgICAgICAgICBfLmZvY3VzSGFuZGxlcigpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChjcmVhdGlvbikge1xyXG4gICAgICAgICAgICBfLiRzbGlkZXIudHJpZ2dlcignaW5pdCcsIFtfXSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLmFjY2Vzc2liaWxpdHkgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgXy5pbml0QURBKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIF8ub3B0aW9ucy5hdXRvcGxheSApIHtcclxuXHJcbiAgICAgICAgICAgIF8ucGF1c2VkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIF8uYXV0b1BsYXkoKTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmluaXRBREEgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcbiAgICAgICAgXy4kc2xpZGVzLmFkZChfLiRzbGlkZVRyYWNrLmZpbmQoJy5zbGljay1jbG9uZWQnKSkuYXR0cih7XHJcbiAgICAgICAgICAgICdhcmlhLWhpZGRlbic6ICd0cnVlJyxcclxuICAgICAgICAgICAgJ3RhYmluZGV4JzogJy0xJ1xyXG4gICAgICAgIH0pLmZpbmQoJ2EsIGlucHV0LCBidXR0b24sIHNlbGVjdCcpLmF0dHIoe1xyXG4gICAgICAgICAgICAndGFiaW5kZXgnOiAnLTEnXHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIF8uJHNsaWRlVHJhY2suYXR0cigncm9sZScsICdsaXN0Ym94Jyk7XHJcblxyXG4gICAgICAgIF8uJHNsaWRlcy5ub3QoXy4kc2xpZGVUcmFjay5maW5kKCcuc2xpY2stY2xvbmVkJykpLmVhY2goZnVuY3Rpb24oaSkge1xyXG4gICAgICAgICAgICAkKHRoaXMpLmF0dHIoe1xyXG4gICAgICAgICAgICAgICAgJ3JvbGUnOiAnb3B0aW9uJyxcclxuICAgICAgICAgICAgICAgICdhcmlhLWRlc2NyaWJlZGJ5JzogJ3NsaWNrLXNsaWRlJyArIF8uaW5zdGFuY2VVaWQgKyBpICsgJydcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGlmIChfLiRkb3RzICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIF8uJGRvdHMuYXR0cigncm9sZScsICd0YWJsaXN0JykuZmluZCgnbGknKS5lYWNoKGZ1bmN0aW9uKGkpIHtcclxuICAgICAgICAgICAgICAgICQodGhpcykuYXR0cih7XHJcbiAgICAgICAgICAgICAgICAgICAgJ3JvbGUnOiAncHJlc2VudGF0aW9uJyxcclxuICAgICAgICAgICAgICAgICAgICAnYXJpYS1zZWxlY3RlZCc6ICdmYWxzZScsXHJcbiAgICAgICAgICAgICAgICAgICAgJ2FyaWEtY29udHJvbHMnOiAnbmF2aWdhdGlvbicgKyBfLmluc3RhbmNlVWlkICsgaSArICcnLFxyXG4gICAgICAgICAgICAgICAgICAgICdpZCc6ICdzbGljay1zbGlkZScgKyBfLmluc3RhbmNlVWlkICsgaSArICcnXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgIC5maXJzdCgpLmF0dHIoJ2FyaWEtc2VsZWN0ZWQnLCAndHJ1ZScpLmVuZCgpXHJcbiAgICAgICAgICAgICAgICAuZmluZCgnYnV0dG9uJykuYXR0cigncm9sZScsICdidXR0b24nKS5lbmQoKVxyXG4gICAgICAgICAgICAgICAgLmNsb3Nlc3QoJ2RpdicpLmF0dHIoJ3JvbGUnLCAndG9vbGJhcicpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBfLmFjdGl2YXRlQURBKCk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuaW5pdEFycm93RXZlbnRzID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcztcclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5hcnJvd3MgPT09IHRydWUgJiYgXy5zbGlkZUNvdW50ID4gXy5vcHRpb25zLnNsaWRlc1RvU2hvdykge1xyXG4gICAgICAgICAgICBfLiRwcmV2QXJyb3dcclxuICAgICAgICAgICAgICAgLm9mZignY2xpY2suc2xpY2snKVxyXG4gICAgICAgICAgICAgICAub24oJ2NsaWNrLnNsaWNrJywge1xyXG4gICAgICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICdwcmV2aW91cydcclxuICAgICAgICAgICAgICAgfSwgXy5jaGFuZ2VTbGlkZSk7XHJcbiAgICAgICAgICAgIF8uJG5leHRBcnJvd1xyXG4gICAgICAgICAgICAgICAub2ZmKCdjbGljay5zbGljaycpXHJcbiAgICAgICAgICAgICAgIC5vbignY2xpY2suc2xpY2snLCB7XHJcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZTogJ25leHQnXHJcbiAgICAgICAgICAgICAgIH0sIF8uY2hhbmdlU2xpZGUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5pbml0RG90RXZlbnRzID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcztcclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5kb3RzID09PSB0cnVlICYmIF8uc2xpZGVDb3VudCA+IF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cpIHtcclxuICAgICAgICAgICAgJCgnbGknLCBfLiRkb3RzKS5vbignY2xpY2suc2xpY2snLCB7XHJcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAnaW5kZXgnXHJcbiAgICAgICAgICAgIH0sIF8uY2hhbmdlU2xpZGUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKCBfLm9wdGlvbnMuZG90cyA9PT0gdHJ1ZSAmJiBfLm9wdGlvbnMucGF1c2VPbkRvdHNIb3ZlciA9PT0gdHJ1ZSApIHtcclxuXHJcbiAgICAgICAgICAgICQoJ2xpJywgXy4kZG90cylcclxuICAgICAgICAgICAgICAgIC5vbignbW91c2VlbnRlci5zbGljaycsICQucHJveHkoXy5pbnRlcnJ1cHQsIF8sIHRydWUpKVxyXG4gICAgICAgICAgICAgICAgLm9uKCdtb3VzZWxlYXZlLnNsaWNrJywgJC5wcm94eShfLmludGVycnVwdCwgXywgZmFsc2UpKTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmluaXRTbGlkZUV2ZW50cyA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIGlmICggXy5vcHRpb25zLnBhdXNlT25Ib3ZlciApIHtcclxuXHJcbiAgICAgICAgICAgIF8uJGxpc3Qub24oJ21vdXNlZW50ZXIuc2xpY2snLCAkLnByb3h5KF8uaW50ZXJydXB0LCBfLCB0cnVlKSk7XHJcbiAgICAgICAgICAgIF8uJGxpc3Qub24oJ21vdXNlbGVhdmUuc2xpY2snLCAkLnByb3h5KF8uaW50ZXJydXB0LCBfLCBmYWxzZSkpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuaW5pdGlhbGl6ZUV2ZW50cyA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIF8uaW5pdEFycm93RXZlbnRzKCk7XHJcblxyXG4gICAgICAgIF8uaW5pdERvdEV2ZW50cygpO1xyXG4gICAgICAgIF8uaW5pdFNsaWRlRXZlbnRzKCk7XHJcblxyXG4gICAgICAgIF8uJGxpc3Qub24oJ3RvdWNoc3RhcnQuc2xpY2sgbW91c2Vkb3duLnNsaWNrJywge1xyXG4gICAgICAgICAgICBhY3Rpb246ICdzdGFydCdcclxuICAgICAgICB9LCBfLnN3aXBlSGFuZGxlcik7XHJcbiAgICAgICAgXy4kbGlzdC5vbigndG91Y2htb3ZlLnNsaWNrIG1vdXNlbW92ZS5zbGljaycsIHtcclxuICAgICAgICAgICAgYWN0aW9uOiAnbW92ZSdcclxuICAgICAgICB9LCBfLnN3aXBlSGFuZGxlcik7XHJcbiAgICAgICAgXy4kbGlzdC5vbigndG91Y2hlbmQuc2xpY2sgbW91c2V1cC5zbGljaycsIHtcclxuICAgICAgICAgICAgYWN0aW9uOiAnZW5kJ1xyXG4gICAgICAgIH0sIF8uc3dpcGVIYW5kbGVyKTtcclxuICAgICAgICBfLiRsaXN0Lm9uKCd0b3VjaGNhbmNlbC5zbGljayBtb3VzZWxlYXZlLnNsaWNrJywge1xyXG4gICAgICAgICAgICBhY3Rpb246ICdlbmQnXHJcbiAgICAgICAgfSwgXy5zd2lwZUhhbmRsZXIpO1xyXG5cclxuICAgICAgICBfLiRsaXN0Lm9uKCdjbGljay5zbGljaycsIF8uY2xpY2tIYW5kbGVyKTtcclxuXHJcbiAgICAgICAgJChkb2N1bWVudCkub24oXy52aXNpYmlsaXR5Q2hhbmdlLCAkLnByb3h5KF8udmlzaWJpbGl0eSwgXykpO1xyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLmFjY2Vzc2liaWxpdHkgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgXy4kbGlzdC5vbigna2V5ZG93bi5zbGljaycsIF8ua2V5SGFuZGxlcik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLmZvY3VzT25TZWxlY3QgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgJChfLiRzbGlkZVRyYWNrKS5jaGlsZHJlbigpLm9uKCdjbGljay5zbGljaycsIF8uc2VsZWN0SGFuZGxlcik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAkKHdpbmRvdykub24oJ29yaWVudGF0aW9uY2hhbmdlLnNsaWNrLnNsaWNrLScgKyBfLmluc3RhbmNlVWlkLCAkLnByb3h5KF8ub3JpZW50YXRpb25DaGFuZ2UsIF8pKTtcclxuXHJcbiAgICAgICAgJCh3aW5kb3cpLm9uKCdyZXNpemUuc2xpY2suc2xpY2stJyArIF8uaW5zdGFuY2VVaWQsICQucHJveHkoXy5yZXNpemUsIF8pKTtcclxuXHJcbiAgICAgICAgJCgnW2RyYWdnYWJsZSE9dHJ1ZV0nLCBfLiRzbGlkZVRyYWNrKS5vbignZHJhZ3N0YXJ0JywgXy5wcmV2ZW50RGVmYXVsdCk7XHJcblxyXG4gICAgICAgICQod2luZG93KS5vbignbG9hZC5zbGljay5zbGljay0nICsgXy5pbnN0YW5jZVVpZCwgXy5zZXRQb3NpdGlvbik7XHJcbiAgICAgICAgJChkb2N1bWVudCkub24oJ3JlYWR5LnNsaWNrLnNsaWNrLScgKyBfLmluc3RhbmNlVWlkLCBfLnNldFBvc2l0aW9uKTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5pbml0VUkgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLmFycm93cyA9PT0gdHJ1ZSAmJiBfLnNsaWRlQ291bnQgPiBfLm9wdGlvbnMuc2xpZGVzVG9TaG93KSB7XHJcblxyXG4gICAgICAgICAgICBfLiRwcmV2QXJyb3cuc2hvdygpO1xyXG4gICAgICAgICAgICBfLiRuZXh0QXJyb3cuc2hvdygpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChfLm9wdGlvbnMuZG90cyA9PT0gdHJ1ZSAmJiBfLnNsaWRlQ291bnQgPiBfLm9wdGlvbnMuc2xpZGVzVG9TaG93KSB7XHJcblxyXG4gICAgICAgICAgICBfLiRkb3RzLnNob3coKTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmtleUhhbmRsZXIgPSBmdW5jdGlvbihldmVudCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcbiAgICAgICAgIC8vRG9udCBzbGlkZSBpZiB0aGUgY3Vyc29yIGlzIGluc2lkZSB0aGUgZm9ybSBmaWVsZHMgYW5kIGFycm93IGtleXMgYXJlIHByZXNzZWRcclxuICAgICAgICBpZighZXZlbnQudGFyZ2V0LnRhZ05hbWUubWF0Y2goJ1RFWFRBUkVBfElOUFVUfFNFTEVDVCcpKSB7XHJcbiAgICAgICAgICAgIGlmIChldmVudC5rZXlDb2RlID09PSAzNyAmJiBfLm9wdGlvbnMuYWNjZXNzaWJpbGl0eSA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgXy5jaGFuZ2VTbGlkZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgZGF0YToge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBfLm9wdGlvbnMucnRsID09PSB0cnVlID8gJ25leHQnIDogICdwcmV2aW91cydcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSBlbHNlIGlmIChldmVudC5rZXlDb2RlID09PSAzOSAmJiBfLm9wdGlvbnMuYWNjZXNzaWJpbGl0eSA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgXy5jaGFuZ2VTbGlkZSh7XHJcbiAgICAgICAgICAgICAgICAgICAgZGF0YToge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiBfLm9wdGlvbnMucnRsID09PSB0cnVlID8gJ3ByZXZpb3VzJyA6ICduZXh0J1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLmxhenlMb2FkID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcyxcclxuICAgICAgICAgICAgbG9hZFJhbmdlLCBjbG9uZVJhbmdlLCByYW5nZVN0YXJ0LCByYW5nZUVuZDtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gbG9hZEltYWdlcyhpbWFnZXNTY29wZSkge1xyXG5cclxuICAgICAgICAgICAgJCgnaW1nW2RhdGEtbGF6eV0nLCBpbWFnZXNTY29wZSkuZWFjaChmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgICAgICAgICB2YXIgaW1hZ2UgPSAkKHRoaXMpLFxyXG4gICAgICAgICAgICAgICAgICAgIGltYWdlU291cmNlID0gJCh0aGlzKS5hdHRyKCdkYXRhLWxhenknKSxcclxuICAgICAgICAgICAgICAgICAgICBpbWFnZVRvTG9hZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xyXG5cclxuICAgICAgICAgICAgICAgIGltYWdlVG9Mb2FkLm9ubG9hZCA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpbWFnZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuYW5pbWF0ZSh7IG9wYWNpdHk6IDAgfSwgMTAwLCBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGltYWdlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ3NyYycsIGltYWdlU291cmNlKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5hbmltYXRlKHsgb3BhY2l0eTogMSB9LCAyMDAsIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbWFnZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoJ2RhdGEtbGF6eScpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ3NsaWNrLWxvYWRpbmcnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF8uJHNsaWRlci50cmlnZ2VyKCdsYXp5TG9hZGVkJywgW18sIGltYWdlLCBpbWFnZVNvdXJjZV0pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIGltYWdlVG9Mb2FkLm9uZXJyb3IgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaW1hZ2VcclxuICAgICAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUF0dHIoICdkYXRhLWxhenknIClcclxuICAgICAgICAgICAgICAgICAgICAgICAgLnJlbW92ZUNsYXNzKCAnc2xpY2stbG9hZGluZycgKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoICdzbGljay1sYXp5bG9hZC1lcnJvcicgKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgXy4kc2xpZGVyLnRyaWdnZXIoJ2xhenlMb2FkRXJyb3InLCBbIF8sIGltYWdlLCBpbWFnZVNvdXJjZSBdKTtcclxuXHJcbiAgICAgICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgICAgIGltYWdlVG9Mb2FkLnNyYyA9IGltYWdlU291cmNlO1xyXG5cclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5jZW50ZXJNb2RlID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIGlmIChfLm9wdGlvbnMuaW5maW5pdGUgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgICAgIHJhbmdlU3RhcnQgPSBfLmN1cnJlbnRTbGlkZSArIChfLm9wdGlvbnMuc2xpZGVzVG9TaG93IC8gMiArIDEpO1xyXG4gICAgICAgICAgICAgICAgcmFuZ2VFbmQgPSByYW5nZVN0YXJ0ICsgXy5vcHRpb25zLnNsaWRlc1RvU2hvdyArIDI7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByYW5nZVN0YXJ0ID0gTWF0aC5tYXgoMCwgXy5jdXJyZW50U2xpZGUgLSAoXy5vcHRpb25zLnNsaWRlc1RvU2hvdyAvIDIgKyAxKSk7XHJcbiAgICAgICAgICAgICAgICByYW5nZUVuZCA9IDIgKyAoXy5vcHRpb25zLnNsaWRlc1RvU2hvdyAvIDIgKyAxKSArIF8uY3VycmVudFNsaWRlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmFuZ2VTdGFydCA9IF8ub3B0aW9ucy5pbmZpbml0ZSA/IF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cgKyBfLmN1cnJlbnRTbGlkZSA6IF8uY3VycmVudFNsaWRlO1xyXG4gICAgICAgICAgICByYW5nZUVuZCA9IE1hdGguY2VpbChyYW5nZVN0YXJ0ICsgXy5vcHRpb25zLnNsaWRlc1RvU2hvdyk7XHJcbiAgICAgICAgICAgIGlmIChfLm9wdGlvbnMuZmFkZSA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJhbmdlU3RhcnQgPiAwKSByYW5nZVN0YXJ0LS07XHJcbiAgICAgICAgICAgICAgICBpZiAocmFuZ2VFbmQgPD0gXy5zbGlkZUNvdW50KSByYW5nZUVuZCsrO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsb2FkUmFuZ2UgPSBfLiRzbGlkZXIuZmluZCgnLnNsaWNrLXNsaWRlJykuc2xpY2UocmFuZ2VTdGFydCwgcmFuZ2VFbmQpO1xyXG4gICAgICAgIGxvYWRJbWFnZXMobG9hZFJhbmdlKTtcclxuXHJcbiAgICAgICAgaWYgKF8uc2xpZGVDb3VudCA8PSBfLm9wdGlvbnMuc2xpZGVzVG9TaG93KSB7XHJcbiAgICAgICAgICAgIGNsb25lUmFuZ2UgPSBfLiRzbGlkZXIuZmluZCgnLnNsaWNrLXNsaWRlJyk7XHJcbiAgICAgICAgICAgIGxvYWRJbWFnZXMoY2xvbmVSYW5nZSk7XHJcbiAgICAgICAgfSBlbHNlXHJcbiAgICAgICAgaWYgKF8uY3VycmVudFNsaWRlID49IF8uc2xpZGVDb3VudCAtIF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cpIHtcclxuICAgICAgICAgICAgY2xvbmVSYW5nZSA9IF8uJHNsaWRlci5maW5kKCcuc2xpY2stY2xvbmVkJykuc2xpY2UoMCwgXy5vcHRpb25zLnNsaWRlc1RvU2hvdyk7XHJcbiAgICAgICAgICAgIGxvYWRJbWFnZXMoY2xvbmVSYW5nZSk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChfLmN1cnJlbnRTbGlkZSA9PT0gMCkge1xyXG4gICAgICAgICAgICBjbG9uZVJhbmdlID0gXy4kc2xpZGVyLmZpbmQoJy5zbGljay1jbG9uZWQnKS5zbGljZShfLm9wdGlvbnMuc2xpZGVzVG9TaG93ICogLTEpO1xyXG4gICAgICAgICAgICBsb2FkSW1hZ2VzKGNsb25lUmFuZ2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5sb2FkU2xpZGVyID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcztcclxuXHJcbiAgICAgICAgXy5zZXRQb3NpdGlvbigpO1xyXG5cclxuICAgICAgICBfLiRzbGlkZVRyYWNrLmNzcyh7XHJcbiAgICAgICAgICAgIG9wYWNpdHk6IDFcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgXy4kc2xpZGVyLnJlbW92ZUNsYXNzKCdzbGljay1sb2FkaW5nJyk7XHJcblxyXG4gICAgICAgIF8uaW5pdFVJKCk7XHJcblxyXG4gICAgICAgIGlmIChfLm9wdGlvbnMubGF6eUxvYWQgPT09ICdwcm9ncmVzc2l2ZScpIHtcclxuICAgICAgICAgICAgXy5wcm9ncmVzc2l2ZUxhenlMb2FkKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLm5leHQgPSBTbGljay5wcm90b3R5cGUuc2xpY2tOZXh0ID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcztcclxuXHJcbiAgICAgICAgXy5jaGFuZ2VTbGlkZSh7XHJcbiAgICAgICAgICAgIGRhdGE6IHtcclxuICAgICAgICAgICAgICAgIG1lc3NhZ2U6ICduZXh0J1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUub3JpZW50YXRpb25DaGFuZ2UgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgICBfLmNoZWNrUmVzcG9uc2l2ZSgpO1xyXG4gICAgICAgIF8uc2V0UG9zaXRpb24oKTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5wYXVzZSA9IFNsaWNrLnByb3RvdHlwZS5zbGlja1BhdXNlID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcztcclxuXHJcbiAgICAgICAgXy5hdXRvUGxheUNsZWFyKCk7XHJcbiAgICAgICAgXy5wYXVzZWQgPSB0cnVlO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLnBsYXkgPSBTbGljay5wcm90b3R5cGUuc2xpY2tQbGF5ID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcztcclxuXHJcbiAgICAgICAgXy5hdXRvUGxheSgpO1xyXG4gICAgICAgIF8ub3B0aW9ucy5hdXRvcGxheSA9IHRydWU7XHJcbiAgICAgICAgXy5wYXVzZWQgPSBmYWxzZTtcclxuICAgICAgICBfLmZvY3Vzc2VkID0gZmFsc2U7XHJcbiAgICAgICAgXy5pbnRlcnJ1cHRlZCA9IGZhbHNlO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLnBvc3RTbGlkZSA9IGZ1bmN0aW9uKGluZGV4KSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcztcclxuXHJcbiAgICAgICAgaWYoICFfLnVuc2xpY2tlZCApIHtcclxuXHJcbiAgICAgICAgICAgIF8uJHNsaWRlci50cmlnZ2VyKCdhZnRlckNoYW5nZScsIFtfLCBpbmRleF0pO1xyXG5cclxuICAgICAgICAgICAgXy5hbmltYXRpbmcgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIF8uc2V0UG9zaXRpb24oKTtcclxuXHJcbiAgICAgICAgICAgIF8uc3dpcGVMZWZ0ID0gbnVsbDtcclxuXHJcbiAgICAgICAgICAgIGlmICggXy5vcHRpb25zLmF1dG9wbGF5ICkge1xyXG4gICAgICAgICAgICAgICAgXy5hdXRvUGxheSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAoXy5vcHRpb25zLmFjY2Vzc2liaWxpdHkgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgICAgIF8uaW5pdEFEQSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5wcmV2ID0gU2xpY2sucHJvdG90eXBlLnNsaWNrUHJldiA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIF8uY2hhbmdlU2xpZGUoe1xyXG4gICAgICAgICAgICBkYXRhOiB7XHJcbiAgICAgICAgICAgICAgICBtZXNzYWdlOiAncHJldmlvdXMnXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5wcmV2ZW50RGVmYXVsdCA9IGZ1bmN0aW9uKGV2ZW50KSB7XHJcblxyXG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUucHJvZ3Jlc3NpdmVMYXp5TG9hZCA9IGZ1bmN0aW9uKCB0cnlDb3VudCApIHtcclxuXHJcbiAgICAgICAgdHJ5Q291bnQgPSB0cnlDb3VudCB8fCAxO1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXMsXHJcbiAgICAgICAgICAgICRpbWdzVG9Mb2FkID0gJCggJ2ltZ1tkYXRhLWxhenldJywgXy4kc2xpZGVyICksXHJcbiAgICAgICAgICAgIGltYWdlLFxyXG4gICAgICAgICAgICBpbWFnZVNvdXJjZSxcclxuICAgICAgICAgICAgaW1hZ2VUb0xvYWQ7XHJcblxyXG4gICAgICAgIGlmICggJGltZ3NUb0xvYWQubGVuZ3RoICkge1xyXG5cclxuICAgICAgICAgICAgaW1hZ2UgPSAkaW1nc1RvTG9hZC5maXJzdCgpO1xyXG4gICAgICAgICAgICBpbWFnZVNvdXJjZSA9IGltYWdlLmF0dHIoJ2RhdGEtbGF6eScpO1xyXG4gICAgICAgICAgICBpbWFnZVRvTG9hZCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2ltZycpO1xyXG5cclxuICAgICAgICAgICAgaW1hZ2VUb0xvYWQub25sb2FkID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgaW1hZ2VcclxuICAgICAgICAgICAgICAgICAgICAuYXR0ciggJ3NyYycsIGltYWdlU291cmNlIClcclxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0cignZGF0YS1sYXp5JylcclxuICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ3NsaWNrLWxvYWRpbmcnKTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIF8ub3B0aW9ucy5hZGFwdGl2ZUhlaWdodCA9PT0gdHJ1ZSApIHtcclxuICAgICAgICAgICAgICAgICAgICBfLnNldFBvc2l0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgXy4kc2xpZGVyLnRyaWdnZXIoJ2xhenlMb2FkZWQnLCBbIF8sIGltYWdlLCBpbWFnZVNvdXJjZSBdKTtcclxuICAgICAgICAgICAgICAgIF8ucHJvZ3Jlc3NpdmVMYXp5TG9hZCgpO1xyXG5cclxuICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgIGltYWdlVG9Mb2FkLm9uZXJyb3IgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIHRyeUNvdW50IDwgMyApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgICAgICogdHJ5IHRvIGxvYWQgdGhlIGltYWdlIDMgdGltZXMsXHJcbiAgICAgICAgICAgICAgICAgICAgICogbGVhdmUgYSBzbGlnaHQgZGVsYXkgc28gd2UgZG9uJ3QgZ2V0XHJcbiAgICAgICAgICAgICAgICAgICAgICogc2VydmVycyBibG9ja2luZyB0aGUgcmVxdWVzdC5cclxuICAgICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KCBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgXy5wcm9ncmVzc2l2ZUxhenlMb2FkKCB0cnlDb3VudCArIDEgKTtcclxuICAgICAgICAgICAgICAgICAgICB9LCA1MDAgKTtcclxuXHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBpbWFnZVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQXR0ciggJ2RhdGEtbGF6eScgKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoICdzbGljay1sb2FkaW5nJyApXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcyggJ3NsaWNrLWxhenlsb2FkLWVycm9yJyApO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBfLiRzbGlkZXIudHJpZ2dlcignbGF6eUxvYWRFcnJvcicsIFsgXywgaW1hZ2UsIGltYWdlU291cmNlIF0pO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBfLnByb2dyZXNzaXZlTGF6eUxvYWQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgaW1hZ2VUb0xvYWQuc3JjID0gaW1hZ2VTb3VyY2U7XHJcblxyXG4gICAgICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICAgICAgICBfLiRzbGlkZXIudHJpZ2dlcignYWxsSW1hZ2VzTG9hZGVkJywgWyBfIF0pO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUucmVmcmVzaCA9IGZ1bmN0aW9uKCBpbml0aWFsaXppbmcgKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcywgY3VycmVudFNsaWRlLCBsYXN0VmlzaWJsZUluZGV4O1xyXG5cclxuICAgICAgICBsYXN0VmlzaWJsZUluZGV4ID0gXy5zbGlkZUNvdW50IC0gXy5vcHRpb25zLnNsaWRlc1RvU2hvdztcclxuXHJcbiAgICAgICAgLy8gaW4gbm9uLWluZmluaXRlIHNsaWRlcnMsIHdlIGRvbid0IHdhbnQgdG8gZ28gcGFzdCB0aGVcclxuICAgICAgICAvLyBsYXN0IHZpc2libGUgaW5kZXguXHJcbiAgICAgICAgaWYoICFfLm9wdGlvbnMuaW5maW5pdGUgJiYgKCBfLmN1cnJlbnRTbGlkZSA+IGxhc3RWaXNpYmxlSW5kZXggKSkge1xyXG4gICAgICAgICAgICBfLmN1cnJlbnRTbGlkZSA9IGxhc3RWaXNpYmxlSW5kZXg7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBpZiBsZXNzIHNsaWRlcyB0aGFuIHRvIHNob3csIGdvIHRvIHN0YXJ0LlxyXG4gICAgICAgIGlmICggXy5zbGlkZUNvdW50IDw9IF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cgKSB7XHJcbiAgICAgICAgICAgIF8uY3VycmVudFNsaWRlID0gMDtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjdXJyZW50U2xpZGUgPSBfLmN1cnJlbnRTbGlkZTtcclxuXHJcbiAgICAgICAgXy5kZXN0cm95KHRydWUpO1xyXG5cclxuICAgICAgICAkLmV4dGVuZChfLCBfLmluaXRpYWxzLCB7IGN1cnJlbnRTbGlkZTogY3VycmVudFNsaWRlIH0pO1xyXG5cclxuICAgICAgICBfLmluaXQoKTtcclxuXHJcbiAgICAgICAgaWYoICFpbml0aWFsaXppbmcgKSB7XHJcblxyXG4gICAgICAgICAgICBfLmNoYW5nZVNsaWRlKHtcclxuICAgICAgICAgICAgICAgIGRhdGE6IHtcclxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlOiAnaW5kZXgnLFxyXG4gICAgICAgICAgICAgICAgICAgIGluZGV4OiBjdXJyZW50U2xpZGVcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgZmFsc2UpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUucmVnaXN0ZXJCcmVha3BvaW50cyA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXMsIGJyZWFrcG9pbnQsIGN1cnJlbnRCcmVha3BvaW50LCBsLFxyXG4gICAgICAgICAgICByZXNwb25zaXZlU2V0dGluZ3MgPSBfLm9wdGlvbnMucmVzcG9uc2l2ZSB8fCBudWxsO1xyXG5cclxuICAgICAgICBpZiAoICQudHlwZShyZXNwb25zaXZlU2V0dGluZ3MpID09PSAnYXJyYXknICYmIHJlc3BvbnNpdmVTZXR0aW5ncy5sZW5ndGggKSB7XHJcblxyXG4gICAgICAgICAgICBfLnJlc3BvbmRUbyA9IF8ub3B0aW9ucy5yZXNwb25kVG8gfHwgJ3dpbmRvdyc7XHJcblxyXG4gICAgICAgICAgICBmb3IgKCBicmVha3BvaW50IGluIHJlc3BvbnNpdmVTZXR0aW5ncyApIHtcclxuXHJcbiAgICAgICAgICAgICAgICBsID0gXy5icmVha3BvaW50cy5sZW5ndGgtMTtcclxuICAgICAgICAgICAgICAgIGN1cnJlbnRCcmVha3BvaW50ID0gcmVzcG9uc2l2ZVNldHRpbmdzW2JyZWFrcG9pbnRdLmJyZWFrcG9pbnQ7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKHJlc3BvbnNpdmVTZXR0aW5ncy5oYXNPd25Qcm9wZXJ0eShicmVha3BvaW50KSkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAvLyBsb29wIHRocm91Z2ggdGhlIGJyZWFrcG9pbnRzIGFuZCBjdXQgb3V0IGFueSBleGlzdGluZ1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIG9uZXMgd2l0aCB0aGUgc2FtZSBicmVha3BvaW50IG51bWJlciwgd2UgZG9uJ3Qgd2FudCBkdXBlcy5cclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSggbCA+PSAwICkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiggXy5icmVha3BvaW50c1tsXSAmJiBfLmJyZWFrcG9pbnRzW2xdID09PSBjdXJyZW50QnJlYWtwb2ludCApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIF8uYnJlYWtwb2ludHMuc3BsaWNlKGwsMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgbC0tO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgXy5icmVha3BvaW50cy5wdXNoKGN1cnJlbnRCcmVha3BvaW50KTtcclxuICAgICAgICAgICAgICAgICAgICBfLmJyZWFrcG9pbnRTZXR0aW5nc1tjdXJyZW50QnJlYWtwb2ludF0gPSByZXNwb25zaXZlU2V0dGluZ3NbYnJlYWtwb2ludF0uc2V0dGluZ3M7XHJcblxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgXy5icmVha3BvaW50cy5zb3J0KGZ1bmN0aW9uKGEsIGIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiAoIF8ub3B0aW9ucy5tb2JpbGVGaXJzdCApID8gYS1iIDogYi1hO1xyXG4gICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLnJlaW5pdCA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIF8uJHNsaWRlcyA9XHJcbiAgICAgICAgICAgIF8uJHNsaWRlVHJhY2tcclxuICAgICAgICAgICAgICAgIC5jaGlsZHJlbihfLm9wdGlvbnMuc2xpZGUpXHJcbiAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ3NsaWNrLXNsaWRlJyk7XHJcblxyXG4gICAgICAgIF8uc2xpZGVDb3VudCA9IF8uJHNsaWRlcy5sZW5ndGg7XHJcblxyXG4gICAgICAgIGlmIChfLmN1cnJlbnRTbGlkZSA+PSBfLnNsaWRlQ291bnQgJiYgXy5jdXJyZW50U2xpZGUgIT09IDApIHtcclxuICAgICAgICAgICAgXy5jdXJyZW50U2xpZGUgPSBfLmN1cnJlbnRTbGlkZSAtIF8ub3B0aW9ucy5zbGlkZXNUb1Njcm9sbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChfLnNsaWRlQ291bnQgPD0gXy5vcHRpb25zLnNsaWRlc1RvU2hvdykge1xyXG4gICAgICAgICAgICBfLmN1cnJlbnRTbGlkZSA9IDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBfLnJlZ2lzdGVyQnJlYWtwb2ludHMoKTtcclxuXHJcbiAgICAgICAgXy5zZXRQcm9wcygpO1xyXG4gICAgICAgIF8uc2V0dXBJbmZpbml0ZSgpO1xyXG4gICAgICAgIF8uYnVpbGRBcnJvd3MoKTtcclxuICAgICAgICBfLnVwZGF0ZUFycm93cygpO1xyXG4gICAgICAgIF8uaW5pdEFycm93RXZlbnRzKCk7XHJcbiAgICAgICAgXy5idWlsZERvdHMoKTtcclxuICAgICAgICBfLnVwZGF0ZURvdHMoKTtcclxuICAgICAgICBfLmluaXREb3RFdmVudHMoKTtcclxuICAgICAgICBfLmNsZWFuVXBTbGlkZUV2ZW50cygpO1xyXG4gICAgICAgIF8uaW5pdFNsaWRlRXZlbnRzKCk7XHJcblxyXG4gICAgICAgIF8uY2hlY2tSZXNwb25zaXZlKGZhbHNlLCB0cnVlKTtcclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5mb2N1c09uU2VsZWN0ID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICQoXy4kc2xpZGVUcmFjaykuY2hpbGRyZW4oKS5vbignY2xpY2suc2xpY2snLCBfLnNlbGVjdEhhbmRsZXIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgXy5zZXRTbGlkZUNsYXNzZXModHlwZW9mIF8uY3VycmVudFNsaWRlID09PSAnbnVtYmVyJyA/IF8uY3VycmVudFNsaWRlIDogMCk7XHJcblxyXG4gICAgICAgIF8uc2V0UG9zaXRpb24oKTtcclxuICAgICAgICBfLmZvY3VzSGFuZGxlcigpO1xyXG5cclxuICAgICAgICBfLnBhdXNlZCA9ICFfLm9wdGlvbnMuYXV0b3BsYXk7XHJcbiAgICAgICAgXy5hdXRvUGxheSgpO1xyXG5cclxuICAgICAgICBfLiRzbGlkZXIudHJpZ2dlcigncmVJbml0JywgW19dKTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5yZXNpemUgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgICBpZiAoJCh3aW5kb3cpLndpZHRoKCkgIT09IF8ud2luZG93V2lkdGgpIHtcclxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KF8ud2luZG93RGVsYXkpO1xyXG4gICAgICAgICAgICBfLndpbmRvd0RlbGF5ID0gd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICBfLndpbmRvd1dpZHRoID0gJCh3aW5kb3cpLndpZHRoKCk7XHJcbiAgICAgICAgICAgICAgICBfLmNoZWNrUmVzcG9uc2l2ZSgpO1xyXG4gICAgICAgICAgICAgICAgaWYoICFfLnVuc2xpY2tlZCApIHsgXy5zZXRQb3NpdGlvbigpOyB9XHJcbiAgICAgICAgICAgIH0sIDUwKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5yZW1vdmVTbGlkZSA9IFNsaWNrLnByb3RvdHlwZS5zbGlja1JlbW92ZSA9IGZ1bmN0aW9uKGluZGV4LCByZW1vdmVCZWZvcmUsIHJlbW92ZUFsbCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIGlmICh0eXBlb2YoaW5kZXgpID09PSAnYm9vbGVhbicpIHtcclxuICAgICAgICAgICAgcmVtb3ZlQmVmb3JlID0gaW5kZXg7XHJcbiAgICAgICAgICAgIGluZGV4ID0gcmVtb3ZlQmVmb3JlID09PSB0cnVlID8gMCA6IF8uc2xpZGVDb3VudCAtIDE7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaW5kZXggPSByZW1vdmVCZWZvcmUgPT09IHRydWUgPyAtLWluZGV4IDogaW5kZXg7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoXy5zbGlkZUNvdW50IDwgMSB8fCBpbmRleCA8IDAgfHwgaW5kZXggPiBfLnNsaWRlQ291bnQgLSAxKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIF8udW5sb2FkKCk7XHJcblxyXG4gICAgICAgIGlmIChyZW1vdmVBbGwgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgXy4kc2xpZGVUcmFjay5jaGlsZHJlbigpLnJlbW92ZSgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIF8uJHNsaWRlVHJhY2suY2hpbGRyZW4odGhpcy5vcHRpb25zLnNsaWRlKS5lcShpbmRleCkucmVtb3ZlKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBfLiRzbGlkZXMgPSBfLiRzbGlkZVRyYWNrLmNoaWxkcmVuKHRoaXMub3B0aW9ucy5zbGlkZSk7XHJcblxyXG4gICAgICAgIF8uJHNsaWRlVHJhY2suY2hpbGRyZW4odGhpcy5vcHRpb25zLnNsaWRlKS5kZXRhY2goKTtcclxuXHJcbiAgICAgICAgXy4kc2xpZGVUcmFjay5hcHBlbmQoXy4kc2xpZGVzKTtcclxuXHJcbiAgICAgICAgXy4kc2xpZGVzQ2FjaGUgPSBfLiRzbGlkZXM7XHJcblxyXG4gICAgICAgIF8ucmVpbml0KCk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuc2V0Q1NTID0gZnVuY3Rpb24ocG9zaXRpb24pIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzLFxyXG4gICAgICAgICAgICBwb3NpdGlvblByb3BzID0ge30sXHJcbiAgICAgICAgICAgIHgsIHk7XHJcblxyXG4gICAgICAgIGlmIChfLm9wdGlvbnMucnRsID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIHBvc2l0aW9uID0gLXBvc2l0aW9uO1xyXG4gICAgICAgIH1cclxuICAgICAgICB4ID0gXy5wb3NpdGlvblByb3AgPT0gJ2xlZnQnID8gTWF0aC5jZWlsKHBvc2l0aW9uKSArICdweCcgOiAnMHB4JztcclxuICAgICAgICB5ID0gXy5wb3NpdGlvblByb3AgPT0gJ3RvcCcgPyBNYXRoLmNlaWwocG9zaXRpb24pICsgJ3B4JyA6ICcwcHgnO1xyXG5cclxuICAgICAgICBwb3NpdGlvblByb3BzW18ucG9zaXRpb25Qcm9wXSA9IHBvc2l0aW9uO1xyXG5cclxuICAgICAgICBpZiAoXy50cmFuc2Zvcm1zRW5hYmxlZCA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgXy4kc2xpZGVUcmFjay5jc3MocG9zaXRpb25Qcm9wcyk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcG9zaXRpb25Qcm9wcyA9IHt9O1xyXG4gICAgICAgICAgICBpZiAoXy5jc3NUcmFuc2l0aW9ucyA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgICAgIHBvc2l0aW9uUHJvcHNbXy5hbmltVHlwZV0gPSAndHJhbnNsYXRlKCcgKyB4ICsgJywgJyArIHkgKyAnKSc7XHJcbiAgICAgICAgICAgICAgICBfLiRzbGlkZVRyYWNrLmNzcyhwb3NpdGlvblByb3BzKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHBvc2l0aW9uUHJvcHNbXy5hbmltVHlwZV0gPSAndHJhbnNsYXRlM2QoJyArIHggKyAnLCAnICsgeSArICcsIDBweCknO1xyXG4gICAgICAgICAgICAgICAgXy4kc2xpZGVUcmFjay5jc3MocG9zaXRpb25Qcm9wcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuc2V0RGltZW5zaW9ucyA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIGlmIChfLm9wdGlvbnMudmVydGljYWwgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIGlmIChfLm9wdGlvbnMuY2VudGVyTW9kZSA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgXy4kbGlzdC5jc3Moe1xyXG4gICAgICAgICAgICAgICAgICAgIHBhZGRpbmc6ICgnMHB4ICcgKyBfLm9wdGlvbnMuY2VudGVyUGFkZGluZylcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgXy4kbGlzdC5oZWlnaHQoXy4kc2xpZGVzLmZpcnN0KCkub3V0ZXJIZWlnaHQodHJ1ZSkgKiBfLm9wdGlvbnMuc2xpZGVzVG9TaG93KTtcclxuICAgICAgICAgICAgaWYgKF8ub3B0aW9ucy5jZW50ZXJNb2RlID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICBfLiRsaXN0LmNzcyh7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFkZGluZzogKF8ub3B0aW9ucy5jZW50ZXJQYWRkaW5nICsgJyAwcHgnKVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIF8ubGlzdFdpZHRoID0gXy4kbGlzdC53aWR0aCgpO1xyXG4gICAgICAgIF8ubGlzdEhlaWdodCA9IF8uJGxpc3QuaGVpZ2h0KCk7XHJcblxyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLnZlcnRpY2FsID09PSBmYWxzZSAmJiBfLm9wdGlvbnMudmFyaWFibGVXaWR0aCA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgXy5zbGlkZVdpZHRoID0gTWF0aC5jZWlsKF8ubGlzdFdpZHRoIC8gXy5vcHRpb25zLnNsaWRlc1RvU2hvdyk7XHJcbiAgICAgICAgICAgIF8uJHNsaWRlVHJhY2sud2lkdGgoTWF0aC5jZWlsKChfLnNsaWRlV2lkdGggKiBfLiRzbGlkZVRyYWNrLmNoaWxkcmVuKCcuc2xpY2stc2xpZGUnKS5sZW5ndGgpKSk7XHJcblxyXG4gICAgICAgIH0gZWxzZSBpZiAoXy5vcHRpb25zLnZhcmlhYmxlV2lkdGggPT09IHRydWUpIHtcclxuICAgICAgICAgICAgXy4kc2xpZGVUcmFjay53aWR0aCg1MDAwICogXy5zbGlkZUNvdW50KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBfLnNsaWRlV2lkdGggPSBNYXRoLmNlaWwoXy5saXN0V2lkdGgpO1xyXG4gICAgICAgICAgICBfLiRzbGlkZVRyYWNrLmhlaWdodChNYXRoLmNlaWwoKF8uJHNsaWRlcy5maXJzdCgpLm91dGVySGVpZ2h0KHRydWUpICogXy4kc2xpZGVUcmFjay5jaGlsZHJlbignLnNsaWNrLXNsaWRlJykubGVuZ3RoKSkpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIG9mZnNldCA9IF8uJHNsaWRlcy5maXJzdCgpLm91dGVyV2lkdGgodHJ1ZSkgLSBfLiRzbGlkZXMuZmlyc3QoKS53aWR0aCgpO1xyXG4gICAgICAgIGlmIChfLm9wdGlvbnMudmFyaWFibGVXaWR0aCA9PT0gZmFsc2UpIF8uJHNsaWRlVHJhY2suY2hpbGRyZW4oJy5zbGljay1zbGlkZScpLndpZHRoKF8uc2xpZGVXaWR0aCAtIG9mZnNldCk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuc2V0RmFkZSA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXMsXHJcbiAgICAgICAgICAgIHRhcmdldExlZnQ7XHJcblxyXG4gICAgICAgIF8uJHNsaWRlcy5lYWNoKGZ1bmN0aW9uKGluZGV4LCBlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIHRhcmdldExlZnQgPSAoXy5zbGlkZVdpZHRoICogaW5kZXgpICogLTE7XHJcbiAgICAgICAgICAgIGlmIChfLm9wdGlvbnMucnRsID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAkKGVsZW1lbnQpLmNzcyh7XHJcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246ICdyZWxhdGl2ZScsXHJcbiAgICAgICAgICAgICAgICAgICAgcmlnaHQ6IHRhcmdldExlZnQsXHJcbiAgICAgICAgICAgICAgICAgICAgdG9wOiAwLFxyXG4gICAgICAgICAgICAgICAgICAgIHpJbmRleDogXy5vcHRpb25zLnpJbmRleCAtIDIsXHJcbiAgICAgICAgICAgICAgICAgICAgb3BhY2l0eTogMFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAkKGVsZW1lbnQpLmNzcyh7XHJcbiAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246ICdyZWxhdGl2ZScsXHJcbiAgICAgICAgICAgICAgICAgICAgbGVmdDogdGFyZ2V0TGVmdCxcclxuICAgICAgICAgICAgICAgICAgICB0b3A6IDAsXHJcbiAgICAgICAgICAgICAgICAgICAgekluZGV4OiBfLm9wdGlvbnMuekluZGV4IC0gMixcclxuICAgICAgICAgICAgICAgICAgICBvcGFjaXR5OiAwXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICBfLiRzbGlkZXMuZXEoXy5jdXJyZW50U2xpZGUpLmNzcyh7XHJcbiAgICAgICAgICAgIHpJbmRleDogXy5vcHRpb25zLnpJbmRleCAtIDEsXHJcbiAgICAgICAgICAgIG9wYWNpdHk6IDFcclxuICAgICAgICB9KTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5zZXRIZWlnaHQgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLnNsaWRlc1RvU2hvdyA9PT0gMSAmJiBfLm9wdGlvbnMuYWRhcHRpdmVIZWlnaHQgPT09IHRydWUgJiYgXy5vcHRpb25zLnZlcnRpY2FsID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICB2YXIgdGFyZ2V0SGVpZ2h0ID0gXy4kc2xpZGVzLmVxKF8uY3VycmVudFNsaWRlKS5vdXRlckhlaWdodCh0cnVlKTtcclxuICAgICAgICAgICAgXy4kbGlzdC5jc3MoJ2hlaWdodCcsIHRhcmdldEhlaWdodCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLnNldE9wdGlvbiA9XHJcbiAgICBTbGljay5wcm90b3R5cGUuc2xpY2tTZXRPcHRpb24gPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogYWNjZXB0cyBhcmd1bWVudHMgaW4gZm9ybWF0IG9mOlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogIC0gZm9yIGNoYW5naW5nIGEgc2luZ2xlIG9wdGlvbidzIHZhbHVlOlxyXG4gICAgICAgICAqICAgICAuc2xpY2soXCJzZXRPcHRpb25cIiwgb3B0aW9uLCB2YWx1ZSwgcmVmcmVzaCApXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiAgLSBmb3IgY2hhbmdpbmcgYSBzZXQgb2YgcmVzcG9uc2l2ZSBvcHRpb25zOlxyXG4gICAgICAgICAqICAgICAuc2xpY2soXCJzZXRPcHRpb25cIiwgJ3Jlc3BvbnNpdmUnLCBbe30sIC4uLl0sIHJlZnJlc2ggKVxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogIC0gZm9yIHVwZGF0aW5nIG11bHRpcGxlIHZhbHVlcyBhdCBvbmNlIChub3QgcmVzcG9uc2l2ZSlcclxuICAgICAgICAgKiAgICAgLnNsaWNrKFwic2V0T3B0aW9uXCIsIHsgJ29wdGlvbic6IHZhbHVlLCAuLi4gfSwgcmVmcmVzaCApXHJcbiAgICAgICAgICovXHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcywgbCwgaXRlbSwgb3B0aW9uLCB2YWx1ZSwgcmVmcmVzaCA9IGZhbHNlLCB0eXBlO1xyXG5cclxuICAgICAgICBpZiggJC50eXBlKCBhcmd1bWVudHNbMF0gKSA9PT0gJ29iamVjdCcgKSB7XHJcblxyXG4gICAgICAgICAgICBvcHRpb24gPSAgYXJndW1lbnRzWzBdO1xyXG4gICAgICAgICAgICByZWZyZXNoID0gYXJndW1lbnRzWzFdO1xyXG4gICAgICAgICAgICB0eXBlID0gJ211bHRpcGxlJztcclxuXHJcbiAgICAgICAgfSBlbHNlIGlmICggJC50eXBlKCBhcmd1bWVudHNbMF0gKSA9PT0gJ3N0cmluZycgKSB7XHJcblxyXG4gICAgICAgICAgICBvcHRpb24gPSAgYXJndW1lbnRzWzBdO1xyXG4gICAgICAgICAgICB2YWx1ZSA9IGFyZ3VtZW50c1sxXTtcclxuICAgICAgICAgICAgcmVmcmVzaCA9IGFyZ3VtZW50c1syXTtcclxuXHJcbiAgICAgICAgICAgIGlmICggYXJndW1lbnRzWzBdID09PSAncmVzcG9uc2l2ZScgJiYgJC50eXBlKCBhcmd1bWVudHNbMV0gKSA9PT0gJ2FycmF5JyApIHtcclxuXHJcbiAgICAgICAgICAgICAgICB0eXBlID0gJ3Jlc3BvbnNpdmUnO1xyXG5cclxuICAgICAgICAgICAgfSBlbHNlIGlmICggdHlwZW9mIGFyZ3VtZW50c1sxXSAhPT0gJ3VuZGVmaW5lZCcgKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgdHlwZSA9ICdzaW5nbGUnO1xyXG5cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICggdHlwZSA9PT0gJ3NpbmdsZScgKSB7XHJcblxyXG4gICAgICAgICAgICBfLm9wdGlvbnNbb3B0aW9uXSA9IHZhbHVlO1xyXG5cclxuXHJcbiAgICAgICAgfSBlbHNlIGlmICggdHlwZSA9PT0gJ211bHRpcGxlJyApIHtcclxuXHJcbiAgICAgICAgICAgICQuZWFjaCggb3B0aW9uICwgZnVuY3Rpb24oIG9wdCwgdmFsICkge1xyXG5cclxuICAgICAgICAgICAgICAgIF8ub3B0aW9uc1tvcHRdID0gdmFsO1xyXG5cclxuICAgICAgICAgICAgfSk7XHJcblxyXG5cclxuICAgICAgICB9IGVsc2UgaWYgKCB0eXBlID09PSAncmVzcG9uc2l2ZScgKSB7XHJcblxyXG4gICAgICAgICAgICBmb3IgKCBpdGVtIGluIHZhbHVlICkge1xyXG5cclxuICAgICAgICAgICAgICAgIGlmKCAkLnR5cGUoIF8ub3B0aW9ucy5yZXNwb25zaXZlICkgIT09ICdhcnJheScgKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIF8ub3B0aW9ucy5yZXNwb25zaXZlID0gWyB2YWx1ZVtpdGVtXSBdO1xyXG5cclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGwgPSBfLm9wdGlvbnMucmVzcG9uc2l2ZS5sZW5ndGgtMTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gbG9vcCB0aHJvdWdoIHRoZSByZXNwb25zaXZlIG9iamVjdCBhbmQgc3BsaWNlIG91dCBkdXBsaWNhdGVzLlxyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlKCBsID49IDAgKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiggXy5vcHRpb25zLnJlc3BvbnNpdmVbbF0uYnJlYWtwb2ludCA9PT0gdmFsdWVbaXRlbV0uYnJlYWtwb2ludCApIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfLm9wdGlvbnMucmVzcG9uc2l2ZS5zcGxpY2UobCwxKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGwtLTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBfLm9wdGlvbnMucmVzcG9uc2l2ZS5wdXNoKCB2YWx1ZVtpdGVtXSApO1xyXG5cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIHJlZnJlc2ggKSB7XHJcblxyXG4gICAgICAgICAgICBfLnVubG9hZCgpO1xyXG4gICAgICAgICAgICBfLnJlaW5pdCgpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuc2V0UG9zaXRpb24gPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgICBfLnNldERpbWVuc2lvbnMoKTtcclxuXHJcbiAgICAgICAgXy5zZXRIZWlnaHQoKTtcclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5mYWRlID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICBfLnNldENTUyhfLmdldExlZnQoXy5jdXJyZW50U2xpZGUpKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBfLnNldEZhZGUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIF8uJHNsaWRlci50cmlnZ2VyKCdzZXRQb3NpdGlvbicsIFtfXSk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuc2V0UHJvcHMgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzLFxyXG4gICAgICAgICAgICBib2R5U3R5bGUgPSBkb2N1bWVudC5ib2R5LnN0eWxlO1xyXG5cclxuICAgICAgICBfLnBvc2l0aW9uUHJvcCA9IF8ub3B0aW9ucy52ZXJ0aWNhbCA9PT0gdHJ1ZSA/ICd0b3AnIDogJ2xlZnQnO1xyXG5cclxuICAgICAgICBpZiAoXy5wb3NpdGlvblByb3AgPT09ICd0b3AnKSB7XHJcbiAgICAgICAgICAgIF8uJHNsaWRlci5hZGRDbGFzcygnc2xpY2stdmVydGljYWwnKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBfLiRzbGlkZXIucmVtb3ZlQ2xhc3MoJ3NsaWNrLXZlcnRpY2FsJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoYm9keVN0eWxlLldlYmtpdFRyYW5zaXRpb24gIT09IHVuZGVmaW5lZCB8fFxyXG4gICAgICAgICAgICBib2R5U3R5bGUuTW96VHJhbnNpdGlvbiAhPT0gdW5kZWZpbmVkIHx8XHJcbiAgICAgICAgICAgIGJvZHlTdHlsZS5tc1RyYW5zaXRpb24gIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBpZiAoXy5vcHRpb25zLnVzZUNTUyA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgXy5jc3NUcmFuc2l0aW9ucyA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICggXy5vcHRpb25zLmZhZGUgKSB7XHJcbiAgICAgICAgICAgIGlmICggdHlwZW9mIF8ub3B0aW9ucy56SW5kZXggPT09ICdudW1iZXInICkge1xyXG4gICAgICAgICAgICAgICAgaWYoIF8ub3B0aW9ucy56SW5kZXggPCAzICkge1xyXG4gICAgICAgICAgICAgICAgICAgIF8ub3B0aW9ucy56SW5kZXggPSAzO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgXy5vcHRpb25zLnpJbmRleCA9IF8uZGVmYXVsdHMuekluZGV4O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoYm9keVN0eWxlLk9UcmFuc2Zvcm0gIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBfLmFuaW1UeXBlID0gJ09UcmFuc2Zvcm0nO1xyXG4gICAgICAgICAgICBfLnRyYW5zZm9ybVR5cGUgPSAnLW8tdHJhbnNmb3JtJztcclxuICAgICAgICAgICAgXy50cmFuc2l0aW9uVHlwZSA9ICdPVHJhbnNpdGlvbic7XHJcbiAgICAgICAgICAgIGlmIChib2R5U3R5bGUucGVyc3BlY3RpdmVQcm9wZXJ0eSA9PT0gdW5kZWZpbmVkICYmIGJvZHlTdHlsZS53ZWJraXRQZXJzcGVjdGl2ZSA9PT0gdW5kZWZpbmVkKSBfLmFuaW1UeXBlID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChib2R5U3R5bGUuTW96VHJhbnNmb3JtICE9PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgXy5hbmltVHlwZSA9ICdNb3pUcmFuc2Zvcm0nO1xyXG4gICAgICAgICAgICBfLnRyYW5zZm9ybVR5cGUgPSAnLW1vei10cmFuc2Zvcm0nO1xyXG4gICAgICAgICAgICBfLnRyYW5zaXRpb25UeXBlID0gJ01velRyYW5zaXRpb24nO1xyXG4gICAgICAgICAgICBpZiAoYm9keVN0eWxlLnBlcnNwZWN0aXZlUHJvcGVydHkgPT09IHVuZGVmaW5lZCAmJiBib2R5U3R5bGUuTW96UGVyc3BlY3RpdmUgPT09IHVuZGVmaW5lZCkgXy5hbmltVHlwZSA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYm9keVN0eWxlLndlYmtpdFRyYW5zZm9ybSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIF8uYW5pbVR5cGUgPSAnd2Via2l0VHJhbnNmb3JtJztcclxuICAgICAgICAgICAgXy50cmFuc2Zvcm1UeXBlID0gJy13ZWJraXQtdHJhbnNmb3JtJztcclxuICAgICAgICAgICAgXy50cmFuc2l0aW9uVHlwZSA9ICd3ZWJraXRUcmFuc2l0aW9uJztcclxuICAgICAgICAgICAgaWYgKGJvZHlTdHlsZS5wZXJzcGVjdGl2ZVByb3BlcnR5ID09PSB1bmRlZmluZWQgJiYgYm9keVN0eWxlLndlYmtpdFBlcnNwZWN0aXZlID09PSB1bmRlZmluZWQpIF8uYW5pbVR5cGUgPSBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGJvZHlTdHlsZS5tc1RyYW5zZm9ybSAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIF8uYW5pbVR5cGUgPSAnbXNUcmFuc2Zvcm0nO1xyXG4gICAgICAgICAgICBfLnRyYW5zZm9ybVR5cGUgPSAnLW1zLXRyYW5zZm9ybSc7XHJcbiAgICAgICAgICAgIF8udHJhbnNpdGlvblR5cGUgPSAnbXNUcmFuc2l0aW9uJztcclxuICAgICAgICAgICAgaWYgKGJvZHlTdHlsZS5tc1RyYW5zZm9ybSA9PT0gdW5kZWZpbmVkKSBfLmFuaW1UeXBlID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChib2R5U3R5bGUudHJhbnNmb3JtICE9PSB1bmRlZmluZWQgJiYgXy5hbmltVHlwZSAhPT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgXy5hbmltVHlwZSA9ICd0cmFuc2Zvcm0nO1xyXG4gICAgICAgICAgICBfLnRyYW5zZm9ybVR5cGUgPSAndHJhbnNmb3JtJztcclxuICAgICAgICAgICAgXy50cmFuc2l0aW9uVHlwZSA9ICd0cmFuc2l0aW9uJztcclxuICAgICAgICB9XHJcbiAgICAgICAgXy50cmFuc2Zvcm1zRW5hYmxlZCA9IF8ub3B0aW9ucy51c2VUcmFuc2Zvcm0gJiYgKF8uYW5pbVR5cGUgIT09IG51bGwgJiYgXy5hbmltVHlwZSAhPT0gZmFsc2UpO1xyXG4gICAgfTtcclxuXHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLnNldFNsaWRlQ2xhc3NlcyA9IGZ1bmN0aW9uKGluZGV4KSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcyxcclxuICAgICAgICAgICAgY2VudGVyT2Zmc2V0LCBhbGxTbGlkZXMsIGluZGV4T2Zmc2V0LCByZW1haW5kZXI7XHJcblxyXG4gICAgICAgIGFsbFNsaWRlcyA9IF8uJHNsaWRlclxyXG4gICAgICAgICAgICAuZmluZCgnLnNsaWNrLXNsaWRlJylcclxuICAgICAgICAgICAgLnJlbW92ZUNsYXNzKCdzbGljay1hY3RpdmUgc2xpY2stY2VudGVyIHNsaWNrLWN1cnJlbnQnKVxyXG4gICAgICAgICAgICAuYXR0cignYXJpYS1oaWRkZW4nLCAndHJ1ZScpO1xyXG5cclxuICAgICAgICBfLiRzbGlkZXNcclxuICAgICAgICAgICAgLmVxKGluZGV4KVxyXG4gICAgICAgICAgICAuYWRkQ2xhc3MoJ3NsaWNrLWN1cnJlbnQnKTtcclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5jZW50ZXJNb2RlID09PSB0cnVlKSB7XHJcblxyXG4gICAgICAgICAgICBjZW50ZXJPZmZzZXQgPSBNYXRoLmZsb29yKF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cgLyAyKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChfLm9wdGlvbnMuaW5maW5pdGUgPT09IHRydWUpIHtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoaW5kZXggPj0gY2VudGVyT2Zmc2V0ICYmIGluZGV4IDw9IChfLnNsaWRlQ291bnQgLSAxKSAtIGNlbnRlck9mZnNldCkge1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBfLiRzbGlkZXNcclxuICAgICAgICAgICAgICAgICAgICAgICAgLnNsaWNlKGluZGV4IC0gY2VudGVyT2Zmc2V0LCBpbmRleCArIGNlbnRlck9mZnNldCArIDEpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnc2xpY2stYWN0aXZlJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2FyaWEtaGlkZGVuJywgJ2ZhbHNlJyk7XHJcblxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaW5kZXhPZmZzZXQgPSBfLm9wdGlvbnMuc2xpZGVzVG9TaG93ICsgaW5kZXg7XHJcbiAgICAgICAgICAgICAgICAgICAgYWxsU2xpZGVzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5zbGljZShpbmRleE9mZnNldCAtIGNlbnRlck9mZnNldCArIDEsIGluZGV4T2Zmc2V0ICsgY2VudGVyT2Zmc2V0ICsgMilcclxuICAgICAgICAgICAgICAgICAgICAgICAgLmFkZENsYXNzKCdzbGljay1hY3RpdmUnKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuYXR0cignYXJpYS1oaWRkZW4nLCAnZmFsc2UnKTtcclxuXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGFsbFNsaWRlc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAuZXEoYWxsU2xpZGVzLmxlbmd0aCAtIDEgLSBfLm9wdGlvbnMuc2xpZGVzVG9TaG93KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ3NsaWNrLWNlbnRlcicpO1xyXG5cclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoaW5kZXggPT09IF8uc2xpZGVDb3VudCAtIDEpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYWxsU2xpZGVzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5lcShfLm9wdGlvbnMuc2xpZGVzVG9TaG93KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ3NsaWNrLWNlbnRlcicpO1xyXG5cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIF8uJHNsaWRlc1xyXG4gICAgICAgICAgICAgICAgLmVxKGluZGV4KVxyXG4gICAgICAgICAgICAgICAgLmFkZENsYXNzKCdzbGljay1jZW50ZXInKTtcclxuXHJcbiAgICAgICAgfSBlbHNlIHtcclxuXHJcbiAgICAgICAgICAgIGlmIChpbmRleCA+PSAwICYmIGluZGV4IDw9IChfLnNsaWRlQ291bnQgLSBfLm9wdGlvbnMuc2xpZGVzVG9TaG93KSkge1xyXG5cclxuICAgICAgICAgICAgICAgIF8uJHNsaWRlc1xyXG4gICAgICAgICAgICAgICAgICAgIC5zbGljZShpbmRleCwgaW5kZXggKyBfLm9wdGlvbnMuc2xpZGVzVG9TaG93KVxyXG4gICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnc2xpY2stYWN0aXZlJylcclxuICAgICAgICAgICAgICAgICAgICAuYXR0cignYXJpYS1oaWRkZW4nLCAnZmFsc2UnKTtcclxuXHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoYWxsU2xpZGVzLmxlbmd0aCA8PSBfLm9wdGlvbnMuc2xpZGVzVG9TaG93KSB7XHJcblxyXG4gICAgICAgICAgICAgICAgYWxsU2xpZGVzXHJcbiAgICAgICAgICAgICAgICAgICAgLmFkZENsYXNzKCdzbGljay1hY3RpdmUnKVxyXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCdhcmlhLWhpZGRlbicsICdmYWxzZScpO1xyXG5cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuXHJcbiAgICAgICAgICAgICAgICByZW1haW5kZXIgPSBfLnNsaWRlQ291bnQgJSBfLm9wdGlvbnMuc2xpZGVzVG9TaG93O1xyXG4gICAgICAgICAgICAgICAgaW5kZXhPZmZzZXQgPSBfLm9wdGlvbnMuaW5maW5pdGUgPT09IHRydWUgPyBfLm9wdGlvbnMuc2xpZGVzVG9TaG93ICsgaW5kZXggOiBpbmRleDtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoXy5vcHRpb25zLnNsaWRlc1RvU2hvdyA9PSBfLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwgJiYgKF8uc2xpZGVDb3VudCAtIGluZGV4KSA8IF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYWxsU2xpZGVzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5zbGljZShpbmRleE9mZnNldCAtIChfLm9wdGlvbnMuc2xpZGVzVG9TaG93IC0gcmVtYWluZGVyKSwgaW5kZXhPZmZzZXQgKyByZW1haW5kZXIpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnc2xpY2stYWN0aXZlJylcclxuICAgICAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2FyaWEtaGlkZGVuJywgJ2ZhbHNlJyk7XHJcblxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYWxsU2xpZGVzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5zbGljZShpbmRleE9mZnNldCwgaW5kZXhPZmZzZXQgKyBfLm9wdGlvbnMuc2xpZGVzVG9TaG93KVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuYWRkQ2xhc3MoJ3NsaWNrLWFjdGl2ZScpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5hdHRyKCdhcmlhLWhpZGRlbicsICdmYWxzZScpO1xyXG5cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLmxhenlMb2FkID09PSAnb25kZW1hbmQnKSB7XHJcbiAgICAgICAgICAgIF8ubGF6eUxvYWQoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuc2V0dXBJbmZpbml0ZSA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXMsXHJcbiAgICAgICAgICAgIGksIHNsaWRlSW5kZXgsIGluZmluaXRlQ291bnQ7XHJcblxyXG4gICAgICAgIGlmIChfLm9wdGlvbnMuZmFkZSA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICBfLm9wdGlvbnMuY2VudGVyTW9kZSA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5pbmZpbml0ZSA9PT0gdHJ1ZSAmJiBfLm9wdGlvbnMuZmFkZSA9PT0gZmFsc2UpIHtcclxuXHJcbiAgICAgICAgICAgIHNsaWRlSW5kZXggPSBudWxsO1xyXG5cclxuICAgICAgICAgICAgaWYgKF8uc2xpZGVDb3VudCA+IF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cpIHtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoXy5vcHRpb25zLmNlbnRlck1vZGUgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBpbmZpbml0ZUNvdW50ID0gXy5vcHRpb25zLnNsaWRlc1RvU2hvdyArIDE7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGluZmluaXRlQ291bnQgPSBfLm9wdGlvbnMuc2xpZGVzVG9TaG93O1xyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGZvciAoaSA9IF8uc2xpZGVDb3VudDsgaSA+IChfLnNsaWRlQ291bnQgLVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbmZpbml0ZUNvdW50KTsgaSAtPSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2xpZGVJbmRleCA9IGkgLSAxO1xyXG4gICAgICAgICAgICAgICAgICAgICQoXy4kc2xpZGVzW3NsaWRlSW5kZXhdKS5jbG9uZSh0cnVlKS5hdHRyKCdpZCcsICcnKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuYXR0cignZGF0YS1zbGljay1pbmRleCcsIHNsaWRlSW5kZXggLSBfLnNsaWRlQ291bnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5wcmVwZW5kVG8oXy4kc2xpZGVUcmFjaykuYWRkQ2xhc3MoJ3NsaWNrLWNsb25lZCcpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGluZmluaXRlQ291bnQ7IGkgKz0gMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNsaWRlSW5kZXggPSBpO1xyXG4gICAgICAgICAgICAgICAgICAgICQoXy4kc2xpZGVzW3NsaWRlSW5kZXhdKS5jbG9uZSh0cnVlKS5hdHRyKCdpZCcsICcnKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAuYXR0cignZGF0YS1zbGljay1pbmRleCcsIHNsaWRlSW5kZXggKyBfLnNsaWRlQ291bnQpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC5hcHBlbmRUbyhfLiRzbGlkZVRyYWNrKS5hZGRDbGFzcygnc2xpY2stY2xvbmVkJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBfLiRzbGlkZVRyYWNrLmZpbmQoJy5zbGljay1jbG9uZWQnKS5maW5kKCdbaWRdJykuZWFjaChmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgICAgICAgICAkKHRoaXMpLmF0dHIoJ2lkJywgJycpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5pbnRlcnJ1cHQgPSBmdW5jdGlvbiggdG9nZ2xlICkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIGlmKCAhdG9nZ2xlICkge1xyXG4gICAgICAgICAgICBfLmF1dG9QbGF5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIF8uaW50ZXJydXB0ZWQgPSB0b2dnbGU7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuc2VsZWN0SGFuZGxlciA9IGZ1bmN0aW9uKGV2ZW50KSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcztcclxuXHJcbiAgICAgICAgdmFyIHRhcmdldEVsZW1lbnQgPVxyXG4gICAgICAgICAgICAkKGV2ZW50LnRhcmdldCkuaXMoJy5zbGljay1zbGlkZScpID9cclxuICAgICAgICAgICAgICAgICQoZXZlbnQudGFyZ2V0KSA6XHJcbiAgICAgICAgICAgICAgICAkKGV2ZW50LnRhcmdldCkucGFyZW50cygnLnNsaWNrLXNsaWRlJyk7XHJcblxyXG4gICAgICAgIHZhciBpbmRleCA9IHBhcnNlSW50KHRhcmdldEVsZW1lbnQuYXR0cignZGF0YS1zbGljay1pbmRleCcpKTtcclxuXHJcbiAgICAgICAgaWYgKCFpbmRleCkgaW5kZXggPSAwO1xyXG5cclxuICAgICAgICBpZiAoXy5zbGlkZUNvdW50IDw9IF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cpIHtcclxuXHJcbiAgICAgICAgICAgIF8uc2V0U2xpZGVDbGFzc2VzKGluZGV4KTtcclxuICAgICAgICAgICAgXy5hc05hdkZvcihpbmRleCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBfLnNsaWRlSGFuZGxlcihpbmRleCk7XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUuc2xpZGVIYW5kbGVyID0gZnVuY3Rpb24oaW5kZXgsIHN5bmMsIGRvbnRBbmltYXRlKSB7XHJcblxyXG4gICAgICAgIHZhciB0YXJnZXRTbGlkZSwgYW5pbVNsaWRlLCBvbGRTbGlkZSwgc2xpZGVMZWZ0LCB0YXJnZXRMZWZ0ID0gbnVsbCxcclxuICAgICAgICAgICAgXyA9IHRoaXMsIG5hdlRhcmdldDtcclxuXHJcbiAgICAgICAgc3luYyA9IHN5bmMgfHwgZmFsc2U7XHJcblxyXG4gICAgICAgIGlmIChfLmFuaW1hdGluZyA9PT0gdHJ1ZSAmJiBfLm9wdGlvbnMud2FpdEZvckFuaW1hdGUgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5mYWRlID09PSB0cnVlICYmIF8uY3VycmVudFNsaWRlID09PSBpbmRleCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoXy5zbGlkZUNvdW50IDw9IF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKHN5bmMgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIF8uYXNOYXZGb3IoaW5kZXgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdGFyZ2V0U2xpZGUgPSBpbmRleDtcclxuICAgICAgICB0YXJnZXRMZWZ0ID0gXy5nZXRMZWZ0KHRhcmdldFNsaWRlKTtcclxuICAgICAgICBzbGlkZUxlZnQgPSBfLmdldExlZnQoXy5jdXJyZW50U2xpZGUpO1xyXG5cclxuICAgICAgICBfLmN1cnJlbnRMZWZ0ID0gXy5zd2lwZUxlZnQgPT09IG51bGwgPyBzbGlkZUxlZnQgOiBfLnN3aXBlTGVmdDtcclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5pbmZpbml0ZSA9PT0gZmFsc2UgJiYgXy5vcHRpb25zLmNlbnRlck1vZGUgPT09IGZhbHNlICYmIChpbmRleCA8IDAgfHwgaW5kZXggPiBfLmdldERvdENvdW50KCkgKiBfLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwpKSB7XHJcbiAgICAgICAgICAgIGlmIChfLm9wdGlvbnMuZmFkZSA9PT0gZmFsc2UpIHtcclxuICAgICAgICAgICAgICAgIHRhcmdldFNsaWRlID0gXy5jdXJyZW50U2xpZGU7XHJcbiAgICAgICAgICAgICAgICBpZiAoZG9udEFuaW1hdGUgIT09IHRydWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBfLmFuaW1hdGVTbGlkZShzbGlkZUxlZnQsIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfLnBvc3RTbGlkZSh0YXJnZXRTbGlkZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIF8ucG9zdFNsaWRlKHRhcmdldFNsaWRlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfSBlbHNlIGlmIChfLm9wdGlvbnMuaW5maW5pdGUgPT09IGZhbHNlICYmIF8ub3B0aW9ucy5jZW50ZXJNb2RlID09PSB0cnVlICYmIChpbmRleCA8IDAgfHwgaW5kZXggPiAoXy5zbGlkZUNvdW50IC0gXy5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsKSkpIHtcclxuICAgICAgICAgICAgaWYgKF8ub3B0aW9ucy5mYWRlID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICAgICAgdGFyZ2V0U2xpZGUgPSBfLmN1cnJlbnRTbGlkZTtcclxuICAgICAgICAgICAgICAgIGlmIChkb250QW5pbWF0ZSAhPT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIF8uYW5pbWF0ZVNsaWRlKHNsaWRlTGVmdCwgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIF8ucG9zdFNsaWRlKHRhcmdldFNsaWRlKTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgXy5wb3N0U2xpZGUodGFyZ2V0U2xpZGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICggXy5vcHRpb25zLmF1dG9wbGF5ICkge1xyXG4gICAgICAgICAgICBjbGVhckludGVydmFsKF8uYXV0b1BsYXlUaW1lcik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGFyZ2V0U2xpZGUgPCAwKSB7XHJcbiAgICAgICAgICAgIGlmIChfLnNsaWRlQ291bnQgJSBfLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwgIT09IDApIHtcclxuICAgICAgICAgICAgICAgIGFuaW1TbGlkZSA9IF8uc2xpZGVDb3VudCAtIChfLnNsaWRlQ291bnQgJSBfLm9wdGlvbnMuc2xpZGVzVG9TY3JvbGwpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYW5pbVNsaWRlID0gXy5zbGlkZUNvdW50ICsgdGFyZ2V0U2xpZGU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2UgaWYgKHRhcmdldFNsaWRlID49IF8uc2xpZGVDb3VudCkge1xyXG4gICAgICAgICAgICBpZiAoXy5zbGlkZUNvdW50ICUgXy5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBhbmltU2xpZGUgPSAwO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgYW5pbVNsaWRlID0gdGFyZ2V0U2xpZGUgLSBfLnNsaWRlQ291bnQ7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBhbmltU2xpZGUgPSB0YXJnZXRTbGlkZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIF8uYW5pbWF0aW5nID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgXy4kc2xpZGVyLnRyaWdnZXIoJ2JlZm9yZUNoYW5nZScsIFtfLCBfLmN1cnJlbnRTbGlkZSwgYW5pbVNsaWRlXSk7XHJcblxyXG4gICAgICAgIG9sZFNsaWRlID0gXy5jdXJyZW50U2xpZGU7XHJcbiAgICAgICAgXy5jdXJyZW50U2xpZGUgPSBhbmltU2xpZGU7XHJcblxyXG4gICAgICAgIF8uc2V0U2xpZGVDbGFzc2VzKF8uY3VycmVudFNsaWRlKTtcclxuXHJcbiAgICAgICAgaWYgKCBfLm9wdGlvbnMuYXNOYXZGb3IgKSB7XHJcblxyXG4gICAgICAgICAgICBuYXZUYXJnZXQgPSBfLmdldE5hdlRhcmdldCgpO1xyXG4gICAgICAgICAgICBuYXZUYXJnZXQgPSBuYXZUYXJnZXQuc2xpY2soJ2dldFNsaWNrJyk7XHJcblxyXG4gICAgICAgICAgICBpZiAoIG5hdlRhcmdldC5zbGlkZUNvdW50IDw9IG5hdlRhcmdldC5vcHRpb25zLnNsaWRlc1RvU2hvdyApIHtcclxuICAgICAgICAgICAgICAgIG5hdlRhcmdldC5zZXRTbGlkZUNsYXNzZXMoXy5jdXJyZW50U2xpZGUpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgXy51cGRhdGVEb3RzKCk7XHJcbiAgICAgICAgXy51cGRhdGVBcnJvd3MoKTtcclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5mYWRlID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIGlmIChkb250QW5pbWF0ZSAhPT0gdHJ1ZSkge1xyXG5cclxuICAgICAgICAgICAgICAgIF8uZmFkZVNsaWRlT3V0KG9sZFNsaWRlKTtcclxuXHJcbiAgICAgICAgICAgICAgICBfLmZhZGVTbGlkZShhbmltU2xpZGUsIGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIF8ucG9zdFNsaWRlKGFuaW1TbGlkZSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBfLnBvc3RTbGlkZShhbmltU2xpZGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF8uYW5pbWF0ZUhlaWdodCgpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoZG9udEFuaW1hdGUgIT09IHRydWUpIHtcclxuICAgICAgICAgICAgXy5hbmltYXRlU2xpZGUodGFyZ2V0TGVmdCwgZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgICAgICAgICBfLnBvc3RTbGlkZShhbmltU2xpZGUpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBfLnBvc3RTbGlkZShhbmltU2xpZGUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5zdGFydExvYWQgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLmFycm93cyA9PT0gdHJ1ZSAmJiBfLnNsaWRlQ291bnQgPiBfLm9wdGlvbnMuc2xpZGVzVG9TaG93KSB7XHJcblxyXG4gICAgICAgICAgICBfLiRwcmV2QXJyb3cuaGlkZSgpO1xyXG4gICAgICAgICAgICBfLiRuZXh0QXJyb3cuaGlkZSgpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChfLm9wdGlvbnMuZG90cyA9PT0gdHJ1ZSAmJiBfLnNsaWRlQ291bnQgPiBfLm9wdGlvbnMuc2xpZGVzVG9TaG93KSB7XHJcblxyXG4gICAgICAgICAgICBfLiRkb3RzLmhpZGUoKTtcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBfLiRzbGlkZXIuYWRkQ2xhc3MoJ3NsaWNrLWxvYWRpbmcnKTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5zd2lwZURpcmVjdGlvbiA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgeERpc3QsIHlEaXN0LCByLCBzd2lwZUFuZ2xlLCBfID0gdGhpcztcclxuXHJcbiAgICAgICAgeERpc3QgPSBfLnRvdWNoT2JqZWN0LnN0YXJ0WCAtIF8udG91Y2hPYmplY3QuY3VyWDtcclxuICAgICAgICB5RGlzdCA9IF8udG91Y2hPYmplY3Quc3RhcnRZIC0gXy50b3VjaE9iamVjdC5jdXJZO1xyXG4gICAgICAgIHIgPSBNYXRoLmF0YW4yKHlEaXN0LCB4RGlzdCk7XHJcblxyXG4gICAgICAgIHN3aXBlQW5nbGUgPSBNYXRoLnJvdW5kKHIgKiAxODAgLyBNYXRoLlBJKTtcclxuICAgICAgICBpZiAoc3dpcGVBbmdsZSA8IDApIHtcclxuICAgICAgICAgICAgc3dpcGVBbmdsZSA9IDM2MCAtIE1hdGguYWJzKHN3aXBlQW5nbGUpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKChzd2lwZUFuZ2xlIDw9IDQ1KSAmJiAoc3dpcGVBbmdsZSA+PSAwKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gKF8ub3B0aW9ucy5ydGwgPT09IGZhbHNlID8gJ2xlZnQnIDogJ3JpZ2h0Jyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICgoc3dpcGVBbmdsZSA8PSAzNjApICYmIChzd2lwZUFuZ2xlID49IDMxNSkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIChfLm9wdGlvbnMucnRsID09PSBmYWxzZSA/ICdsZWZ0JyA6ICdyaWdodCcpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoKHN3aXBlQW5nbGUgPj0gMTM1KSAmJiAoc3dpcGVBbmdsZSA8PSAyMjUpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAoXy5vcHRpb25zLnJ0bCA9PT0gZmFsc2UgPyAncmlnaHQnIDogJ2xlZnQnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy52ZXJ0aWNhbFN3aXBpbmcgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgaWYgKChzd2lwZUFuZ2xlID49IDM1KSAmJiAoc3dpcGVBbmdsZSA8PSAxMzUpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gJ2Rvd24nO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICd1cCc7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiAndmVydGljYWwnO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLnN3aXBlRW5kID0gZnVuY3Rpb24oZXZlbnQpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzLFxyXG4gICAgICAgICAgICBzbGlkZUNvdW50LFxyXG4gICAgICAgICAgICBkaXJlY3Rpb247XHJcblxyXG4gICAgICAgIF8uZHJhZ2dpbmcgPSBmYWxzZTtcclxuICAgICAgICBfLmludGVycnVwdGVkID0gZmFsc2U7XHJcbiAgICAgICAgXy5zaG91bGRDbGljayA9ICggXy50b3VjaE9iamVjdC5zd2lwZUxlbmd0aCA+IDEwICkgPyBmYWxzZSA6IHRydWU7XHJcblxyXG4gICAgICAgIGlmICggXy50b3VjaE9iamVjdC5jdXJYID09PSB1bmRlZmluZWQgKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICggXy50b3VjaE9iamVjdC5lZGdlSGl0ID09PSB0cnVlICkge1xyXG4gICAgICAgICAgICBfLiRzbGlkZXIudHJpZ2dlcignZWRnZScsIFtfLCBfLnN3aXBlRGlyZWN0aW9uKCkgXSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIF8udG91Y2hPYmplY3Quc3dpcGVMZW5ndGggPj0gXy50b3VjaE9iamVjdC5taW5Td2lwZSApIHtcclxuXHJcbiAgICAgICAgICAgIGRpcmVjdGlvbiA9IF8uc3dpcGVEaXJlY3Rpb24oKTtcclxuXHJcbiAgICAgICAgICAgIHN3aXRjaCAoIGRpcmVjdGlvbiApIHtcclxuXHJcbiAgICAgICAgICAgICAgICBjYXNlICdsZWZ0JzpcclxuICAgICAgICAgICAgICAgIGNhc2UgJ2Rvd24nOlxyXG5cclxuICAgICAgICAgICAgICAgICAgICBzbGlkZUNvdW50ID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgXy5vcHRpb25zLnN3aXBlVG9TbGlkZSA/XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfLmNoZWNrTmF2aWdhYmxlKCBfLmN1cnJlbnRTbGlkZSArIF8uZ2V0U2xpZGVDb3VudCgpICkgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXy5jdXJyZW50U2xpZGUgKyBfLmdldFNsaWRlQ291bnQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgXy5jdXJyZW50RGlyZWN0aW9uID0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICAgICAgY2FzZSAncmlnaHQnOlxyXG4gICAgICAgICAgICAgICAgY2FzZSAndXAnOlxyXG5cclxuICAgICAgICAgICAgICAgICAgICBzbGlkZUNvdW50ID1cclxuICAgICAgICAgICAgICAgICAgICAgICAgXy5vcHRpb25zLnN3aXBlVG9TbGlkZSA/XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBfLmNoZWNrTmF2aWdhYmxlKCBfLmN1cnJlbnRTbGlkZSAtIF8uZ2V0U2xpZGVDb3VudCgpICkgOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXy5jdXJyZW50U2xpZGUgLSBfLmdldFNsaWRlQ291bnQoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgXy5jdXJyZW50RGlyZWN0aW9uID0gMTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcclxuXHJcblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiggZGlyZWN0aW9uICE9ICd2ZXJ0aWNhbCcgKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgXy5zbGlkZUhhbmRsZXIoIHNsaWRlQ291bnQgKTtcclxuICAgICAgICAgICAgICAgIF8udG91Y2hPYmplY3QgPSB7fTtcclxuICAgICAgICAgICAgICAgIF8uJHNsaWRlci50cmlnZ2VyKCdzd2lwZScsIFtfLCBkaXJlY3Rpb24gXSk7XHJcblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH0gZWxzZSB7XHJcblxyXG4gICAgICAgICAgICBpZiAoIF8udG91Y2hPYmplY3Quc3RhcnRYICE9PSBfLnRvdWNoT2JqZWN0LmN1clggKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgXy5zbGlkZUhhbmRsZXIoIF8uY3VycmVudFNsaWRlICk7XHJcbiAgICAgICAgICAgICAgICBfLnRvdWNoT2JqZWN0ID0ge307XHJcblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5zd2lwZUhhbmRsZXIgPSBmdW5jdGlvbihldmVudCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIGlmICgoXy5vcHRpb25zLnN3aXBlID09PSBmYWxzZSkgfHwgKCdvbnRvdWNoZW5kJyBpbiBkb2N1bWVudCAmJiBfLm9wdGlvbnMuc3dpcGUgPT09IGZhbHNlKSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfSBlbHNlIGlmIChfLm9wdGlvbnMuZHJhZ2dhYmxlID09PSBmYWxzZSAmJiBldmVudC50eXBlLmluZGV4T2YoJ21vdXNlJykgIT09IC0xKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIF8udG91Y2hPYmplY3QuZmluZ2VyQ291bnQgPSBldmVudC5vcmlnaW5hbEV2ZW50ICYmIGV2ZW50Lm9yaWdpbmFsRXZlbnQudG91Y2hlcyAhPT0gdW5kZWZpbmVkID9cclxuICAgICAgICAgICAgZXZlbnQub3JpZ2luYWxFdmVudC50b3VjaGVzLmxlbmd0aCA6IDE7XHJcblxyXG4gICAgICAgIF8udG91Y2hPYmplY3QubWluU3dpcGUgPSBfLmxpc3RXaWR0aCAvIF8ub3B0aW9uc1xyXG4gICAgICAgICAgICAudG91Y2hUaHJlc2hvbGQ7XHJcblxyXG4gICAgICAgIGlmIChfLm9wdGlvbnMudmVydGljYWxTd2lwaW5nID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgIF8udG91Y2hPYmplY3QubWluU3dpcGUgPSBfLmxpc3RIZWlnaHQgLyBfLm9wdGlvbnNcclxuICAgICAgICAgICAgICAgIC50b3VjaFRocmVzaG9sZDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN3aXRjaCAoZXZlbnQuZGF0YS5hY3Rpb24pIHtcclxuXHJcbiAgICAgICAgICAgIGNhc2UgJ3N0YXJ0JzpcclxuICAgICAgICAgICAgICAgIF8uc3dpcGVTdGFydChldmVudCk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgICAgIGNhc2UgJ21vdmUnOlxyXG4gICAgICAgICAgICAgICAgXy5zd2lwZU1vdmUoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcblxyXG4gICAgICAgICAgICBjYXNlICdlbmQnOlxyXG4gICAgICAgICAgICAgICAgXy5zd2lwZUVuZChldmVudCk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLnN3aXBlTW92ZSA9IGZ1bmN0aW9uKGV2ZW50KSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcyxcclxuICAgICAgICAgICAgZWRnZVdhc0hpdCA9IGZhbHNlLFxyXG4gICAgICAgICAgICBjdXJMZWZ0LCBzd2lwZURpcmVjdGlvbiwgc3dpcGVMZW5ndGgsIHBvc2l0aW9uT2Zmc2V0LCB0b3VjaGVzO1xyXG5cclxuICAgICAgICB0b3VjaGVzID0gZXZlbnQub3JpZ2luYWxFdmVudCAhPT0gdW5kZWZpbmVkID8gZXZlbnQub3JpZ2luYWxFdmVudC50b3VjaGVzIDogbnVsbDtcclxuXHJcbiAgICAgICAgaWYgKCFfLmRyYWdnaW5nIHx8IHRvdWNoZXMgJiYgdG91Y2hlcy5sZW5ndGggIT09IDEpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY3VyTGVmdCA9IF8uZ2V0TGVmdChfLmN1cnJlbnRTbGlkZSk7XHJcblxyXG4gICAgICAgIF8udG91Y2hPYmplY3QuY3VyWCA9IHRvdWNoZXMgIT09IHVuZGVmaW5lZCA/IHRvdWNoZXNbMF0ucGFnZVggOiBldmVudC5jbGllbnRYO1xyXG4gICAgICAgIF8udG91Y2hPYmplY3QuY3VyWSA9IHRvdWNoZXMgIT09IHVuZGVmaW5lZCA/IHRvdWNoZXNbMF0ucGFnZVkgOiBldmVudC5jbGllbnRZO1xyXG5cclxuICAgICAgICBfLnRvdWNoT2JqZWN0LnN3aXBlTGVuZ3RoID0gTWF0aC5yb3VuZChNYXRoLnNxcnQoXHJcbiAgICAgICAgICAgIE1hdGgucG93KF8udG91Y2hPYmplY3QuY3VyWCAtIF8udG91Y2hPYmplY3Quc3RhcnRYLCAyKSkpO1xyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLnZlcnRpY2FsU3dpcGluZyA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICBfLnRvdWNoT2JqZWN0LnN3aXBlTGVuZ3RoID0gTWF0aC5yb3VuZChNYXRoLnNxcnQoXHJcbiAgICAgICAgICAgICAgICBNYXRoLnBvdyhfLnRvdWNoT2JqZWN0LmN1clkgLSBfLnRvdWNoT2JqZWN0LnN0YXJ0WSwgMikpKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHN3aXBlRGlyZWN0aW9uID0gXy5zd2lwZURpcmVjdGlvbigpO1xyXG5cclxuICAgICAgICBpZiAoc3dpcGVEaXJlY3Rpb24gPT09ICd2ZXJ0aWNhbCcpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGV2ZW50Lm9yaWdpbmFsRXZlbnQgIT09IHVuZGVmaW5lZCAmJiBfLnRvdWNoT2JqZWN0LnN3aXBlTGVuZ3RoID4gNCkge1xyXG4gICAgICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcG9zaXRpb25PZmZzZXQgPSAoXy5vcHRpb25zLnJ0bCA9PT0gZmFsc2UgPyAxIDogLTEpICogKF8udG91Y2hPYmplY3QuY3VyWCA+IF8udG91Y2hPYmplY3Quc3RhcnRYID8gMSA6IC0xKTtcclxuICAgICAgICBpZiAoXy5vcHRpb25zLnZlcnRpY2FsU3dpcGluZyA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICBwb3NpdGlvbk9mZnNldCA9IF8udG91Y2hPYmplY3QuY3VyWSA+IF8udG91Y2hPYmplY3Quc3RhcnRZID8gMSA6IC0xO1xyXG4gICAgICAgIH1cclxuXHJcblxyXG4gICAgICAgIHN3aXBlTGVuZ3RoID0gXy50b3VjaE9iamVjdC5zd2lwZUxlbmd0aDtcclxuXHJcbiAgICAgICAgXy50b3VjaE9iamVjdC5lZGdlSGl0ID0gZmFsc2U7XHJcblxyXG4gICAgICAgIGlmIChfLm9wdGlvbnMuaW5maW5pdGUgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIGlmICgoXy5jdXJyZW50U2xpZGUgPT09IDAgJiYgc3dpcGVEaXJlY3Rpb24gPT09ICdyaWdodCcpIHx8IChfLmN1cnJlbnRTbGlkZSA+PSBfLmdldERvdENvdW50KCkgJiYgc3dpcGVEaXJlY3Rpb24gPT09ICdsZWZ0JykpIHtcclxuICAgICAgICAgICAgICAgIHN3aXBlTGVuZ3RoID0gXy50b3VjaE9iamVjdC5zd2lwZUxlbmd0aCAqIF8ub3B0aW9ucy5lZGdlRnJpY3Rpb247XHJcbiAgICAgICAgICAgICAgICBfLnRvdWNoT2JqZWN0LmVkZ2VIaXQgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoXy5vcHRpb25zLnZlcnRpY2FsID09PSBmYWxzZSkge1xyXG4gICAgICAgICAgICBfLnN3aXBlTGVmdCA9IGN1ckxlZnQgKyBzd2lwZUxlbmd0aCAqIHBvc2l0aW9uT2Zmc2V0O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIF8uc3dpcGVMZWZ0ID0gY3VyTGVmdCArIChzd2lwZUxlbmd0aCAqIChfLiRsaXN0LmhlaWdodCgpIC8gXy5saXN0V2lkdGgpKSAqIHBvc2l0aW9uT2Zmc2V0O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoXy5vcHRpb25zLnZlcnRpY2FsU3dpcGluZyA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICBfLnN3aXBlTGVmdCA9IGN1ckxlZnQgKyBzd2lwZUxlbmd0aCAqIHBvc2l0aW9uT2Zmc2V0O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKF8ub3B0aW9ucy5mYWRlID09PSB0cnVlIHx8IF8ub3B0aW9ucy50b3VjaE1vdmUgPT09IGZhbHNlKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChfLmFuaW1hdGluZyA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICBfLnN3aXBlTGVmdCA9IG51bGw7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIF8uc2V0Q1NTKF8uc3dpcGVMZWZ0KTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS5zd2lwZVN0YXJ0ID0gZnVuY3Rpb24oZXZlbnQpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzLFxyXG4gICAgICAgICAgICB0b3VjaGVzO1xyXG5cclxuICAgICAgICBfLmludGVycnVwdGVkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgaWYgKF8udG91Y2hPYmplY3QuZmluZ2VyQ291bnQgIT09IDEgfHwgXy5zbGlkZUNvdW50IDw9IF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cpIHtcclxuICAgICAgICAgICAgXy50b3VjaE9iamVjdCA9IHt9O1xyXG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoZXZlbnQub3JpZ2luYWxFdmVudCAhPT0gdW5kZWZpbmVkICYmIGV2ZW50Lm9yaWdpbmFsRXZlbnQudG91Y2hlcyAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHRvdWNoZXMgPSBldmVudC5vcmlnaW5hbEV2ZW50LnRvdWNoZXNbMF07XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBfLnRvdWNoT2JqZWN0LnN0YXJ0WCA9IF8udG91Y2hPYmplY3QuY3VyWCA9IHRvdWNoZXMgIT09IHVuZGVmaW5lZCA/IHRvdWNoZXMucGFnZVggOiBldmVudC5jbGllbnRYO1xyXG4gICAgICAgIF8udG91Y2hPYmplY3Quc3RhcnRZID0gXy50b3VjaE9iamVjdC5jdXJZID0gdG91Y2hlcyAhPT0gdW5kZWZpbmVkID8gdG91Y2hlcy5wYWdlWSA6IGV2ZW50LmNsaWVudFk7XHJcblxyXG4gICAgICAgIF8uZHJhZ2dpbmcgPSB0cnVlO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLnVuZmlsdGVyU2xpZGVzID0gU2xpY2sucHJvdG90eXBlLnNsaWNrVW5maWx0ZXIgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgICBpZiAoXy4kc2xpZGVzQ2FjaGUgIT09IG51bGwpIHtcclxuXHJcbiAgICAgICAgICAgIF8udW5sb2FkKCk7XHJcblxyXG4gICAgICAgICAgICBfLiRzbGlkZVRyYWNrLmNoaWxkcmVuKHRoaXMub3B0aW9ucy5zbGlkZSkuZGV0YWNoKCk7XHJcblxyXG4gICAgICAgICAgICBfLiRzbGlkZXNDYWNoZS5hcHBlbmRUbyhfLiRzbGlkZVRyYWNrKTtcclxuXHJcbiAgICAgICAgICAgIF8ucmVpbml0KCk7XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS51bmxvYWQgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzO1xyXG5cclxuICAgICAgICAkKCcuc2xpY2stY2xvbmVkJywgXy4kc2xpZGVyKS5yZW1vdmUoKTtcclxuXHJcbiAgICAgICAgaWYgKF8uJGRvdHMpIHtcclxuICAgICAgICAgICAgXy4kZG90cy5yZW1vdmUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChfLiRwcmV2QXJyb3cgJiYgXy5odG1sRXhwci50ZXN0KF8ub3B0aW9ucy5wcmV2QXJyb3cpKSB7XHJcbiAgICAgICAgICAgIF8uJHByZXZBcnJvdy5yZW1vdmUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmIChfLiRuZXh0QXJyb3cgJiYgXy5odG1sRXhwci50ZXN0KF8ub3B0aW9ucy5uZXh0QXJyb3cpKSB7XHJcbiAgICAgICAgICAgIF8uJG5leHRBcnJvdy5yZW1vdmUoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIF8uJHNsaWRlc1xyXG4gICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ3NsaWNrLXNsaWRlIHNsaWNrLWFjdGl2ZSBzbGljay12aXNpYmxlIHNsaWNrLWN1cnJlbnQnKVxyXG4gICAgICAgICAgICAuYXR0cignYXJpYS1oaWRkZW4nLCAndHJ1ZScpXHJcbiAgICAgICAgICAgIC5jc3MoJ3dpZHRoJywgJycpO1xyXG5cclxuICAgIH07XHJcblxyXG4gICAgU2xpY2sucHJvdG90eXBlLnVuc2xpY2sgPSBmdW5jdGlvbihmcm9tQnJlYWtwb2ludCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcbiAgICAgICAgXy4kc2xpZGVyLnRyaWdnZXIoJ3Vuc2xpY2snLCBbXywgZnJvbUJyZWFrcG9pbnRdKTtcclxuICAgICAgICBfLmRlc3Ryb3koKTtcclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS51cGRhdGVBcnJvd3MgPSBmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgdmFyIF8gPSB0aGlzLFxyXG4gICAgICAgICAgICBjZW50ZXJPZmZzZXQ7XHJcblxyXG4gICAgICAgIGNlbnRlck9mZnNldCA9IE1hdGguZmxvb3IoXy5vcHRpb25zLnNsaWRlc1RvU2hvdyAvIDIpO1xyXG5cclxuICAgICAgICBpZiAoIF8ub3B0aW9ucy5hcnJvd3MgPT09IHRydWUgJiZcclxuICAgICAgICAgICAgXy5zbGlkZUNvdW50ID4gXy5vcHRpb25zLnNsaWRlc1RvU2hvdyAmJlxyXG4gICAgICAgICAgICAhXy5vcHRpb25zLmluZmluaXRlICkge1xyXG5cclxuICAgICAgICAgICAgXy4kcHJldkFycm93LnJlbW92ZUNsYXNzKCdzbGljay1kaXNhYmxlZCcpLmF0dHIoJ2FyaWEtZGlzYWJsZWQnLCAnZmFsc2UnKTtcclxuICAgICAgICAgICAgXy4kbmV4dEFycm93LnJlbW92ZUNsYXNzKCdzbGljay1kaXNhYmxlZCcpLmF0dHIoJ2FyaWEtZGlzYWJsZWQnLCAnZmFsc2UnKTtcclxuXHJcbiAgICAgICAgICAgIGlmIChfLmN1cnJlbnRTbGlkZSA9PT0gMCkge1xyXG5cclxuICAgICAgICAgICAgICAgIF8uJHByZXZBcnJvdy5hZGRDbGFzcygnc2xpY2stZGlzYWJsZWQnKS5hdHRyKCdhcmlhLWRpc2FibGVkJywgJ3RydWUnKTtcclxuICAgICAgICAgICAgICAgIF8uJG5leHRBcnJvdy5yZW1vdmVDbGFzcygnc2xpY2stZGlzYWJsZWQnKS5hdHRyKCdhcmlhLWRpc2FibGVkJywgJ2ZhbHNlJyk7XHJcblxyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKF8uY3VycmVudFNsaWRlID49IF8uc2xpZGVDb3VudCAtIF8ub3B0aW9ucy5zbGlkZXNUb1Nob3cgJiYgXy5vcHRpb25zLmNlbnRlck1vZGUgPT09IGZhbHNlKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgXy4kbmV4dEFycm93LmFkZENsYXNzKCdzbGljay1kaXNhYmxlZCcpLmF0dHIoJ2FyaWEtZGlzYWJsZWQnLCAndHJ1ZScpO1xyXG4gICAgICAgICAgICAgICAgXy4kcHJldkFycm93LnJlbW92ZUNsYXNzKCdzbGljay1kaXNhYmxlZCcpLmF0dHIoJ2FyaWEtZGlzYWJsZWQnLCAnZmFsc2UnKTtcclxuXHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXy5jdXJyZW50U2xpZGUgPj0gXy5zbGlkZUNvdW50IC0gMSAmJiBfLm9wdGlvbnMuY2VudGVyTW9kZSA9PT0gdHJ1ZSkge1xyXG5cclxuICAgICAgICAgICAgICAgIF8uJG5leHRBcnJvdy5hZGRDbGFzcygnc2xpY2stZGlzYWJsZWQnKS5hdHRyKCdhcmlhLWRpc2FibGVkJywgJ3RydWUnKTtcclxuICAgICAgICAgICAgICAgIF8uJHByZXZBcnJvdy5yZW1vdmVDbGFzcygnc2xpY2stZGlzYWJsZWQnKS5hdHRyKCdhcmlhLWRpc2FibGVkJywgJ2ZhbHNlJyk7XHJcblxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH1cclxuXHJcbiAgICB9O1xyXG5cclxuICAgIFNsaWNrLnByb3RvdHlwZS51cGRhdGVEb3RzID0gZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgIHZhciBfID0gdGhpcztcclxuXHJcbiAgICAgICAgaWYgKF8uJGRvdHMgIT09IG51bGwpIHtcclxuXHJcbiAgICAgICAgICAgIF8uJGRvdHNcclxuICAgICAgICAgICAgICAgIC5maW5kKCdsaScpXHJcbiAgICAgICAgICAgICAgICAucmVtb3ZlQ2xhc3MoJ3NsaWNrLWFjdGl2ZScpXHJcbiAgICAgICAgICAgICAgICAuYXR0cignYXJpYS1oaWRkZW4nLCAndHJ1ZScpO1xyXG5cclxuICAgICAgICAgICAgXy4kZG90c1xyXG4gICAgICAgICAgICAgICAgLmZpbmQoJ2xpJylcclxuICAgICAgICAgICAgICAgIC5lcShNYXRoLmZsb29yKF8uY3VycmVudFNsaWRlIC8gXy5vcHRpb25zLnNsaWRlc1RvU2Nyb2xsKSlcclxuICAgICAgICAgICAgICAgIC5hZGRDbGFzcygnc2xpY2stYWN0aXZlJylcclxuICAgICAgICAgICAgICAgIC5hdHRyKCdhcmlhLWhpZGRlbicsICdmYWxzZScpO1xyXG5cclxuICAgICAgICB9XHJcblxyXG4gICAgfTtcclxuXHJcbiAgICBTbGljay5wcm90b3R5cGUudmlzaWJpbGl0eSA9IGZ1bmN0aW9uKCkge1xyXG5cclxuICAgICAgICB2YXIgXyA9IHRoaXM7XHJcblxyXG4gICAgICAgIGlmICggXy5vcHRpb25zLmF1dG9wbGF5ICkge1xyXG5cclxuICAgICAgICAgICAgaWYgKCBkb2N1bWVudFtfLmhpZGRlbl0gKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgXy5pbnRlcnJ1cHRlZCA9IHRydWU7XHJcblxyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG5cclxuICAgICAgICAgICAgICAgIF8uaW50ZXJydXB0ZWQgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgfVxyXG5cclxuICAgIH07XHJcblxyXG4gICAgJC5mbi5zbGljayA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgIHZhciBfID0gdGhpcyxcclxuICAgICAgICAgICAgb3B0ID0gYXJndW1lbnRzWzBdLFxyXG4gICAgICAgICAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcclxuICAgICAgICAgICAgbCA9IF8ubGVuZ3RoLFxyXG4gICAgICAgICAgICBpLFxyXG4gICAgICAgICAgICByZXQ7XHJcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGw7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9wdCA9PSAnb2JqZWN0JyB8fCB0eXBlb2Ygb3B0ID09ICd1bmRlZmluZWQnKVxyXG4gICAgICAgICAgICAgICAgX1tpXS5zbGljayA9IG5ldyBTbGljayhfW2ldLCBvcHQpO1xyXG4gICAgICAgICAgICBlbHNlXHJcbiAgICAgICAgICAgICAgICByZXQgPSBfW2ldLnNsaWNrW29wdF0uYXBwbHkoX1tpXS5zbGljaywgYXJncyk7XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcmV0ICE9ICd1bmRlZmluZWQnKSByZXR1cm4gcmV0O1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gXztcclxuICAgIH07XHJcblxyXG59KSk7XHJcbiIsIjtcclxuKGZ1bmN0aW9uKCkge1xyXG4gICAgJChkb2N1bWVudCkuZm91bmRhdGlvbigpO1xyXG5cclxuICAgIHZhciAkd2luZG93ID0gJCh3aW5kb3cpLFxyXG4gICAgICAgICRzbGljayA9ICQoJy5zbGljaycpLFxyXG4gICAgICAgICRzbGlja0xpbmtzID0gJCgnLnNsaWNrX19saW5rcycpLFxyXG4gICAgICAgIHdNZWRpdW0gPSA2NDAsXHJcbiAgICAgICAgd0xhcmdlID0gMTAyNCxcclxuICAgICAgICBlcXVhbGhlaWdodCA9IGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICAkKCcuY29udGVudC0td2l0aC1mb3JtJykuZWFjaChmdW5jdGlvbigpIHtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBDYWNoZSB0aGUgaGlnaGVzdFxyXG4gICAgICAgICAgICAgICAgdmFyICRjb2x1bW4gPSAnLnNhbWUtaGVpZ2h0JyxcclxuICAgICAgICAgICAgICAgICAgICBoaWdoZXN0Qm94ID0gMDtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBTZWxlY3QgYW5kIGxvb3AgdGhlIGVsZW1lbnRzIHlvdSB3YW50IHRvIGVxdWFsaXNlXHJcbiAgICAgICAgICAgICAgICAkKCRjb2x1bW4sIHRoaXMpLmVhY2goZnVuY3Rpb24oKSB7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIElmIHRoaXMgYm94IGlzIGhpZ2hlciB0aGFuIHRoZSBjYWNoZWQgaGlnaGVzdCB0aGVuIHN0b3JlIGl0XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCQodGhpcykuaGVpZ2h0KCkgPiBoaWdoZXN0Qm94KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhpZ2hlc3RCb3ggPSAkKHRoaXMpLmhlaWdodCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgICAgICAgICAvLyBTZXQgdGhlIGhlaWdodCBvZiBhbGwgdGhvc2UgY2hpbGRyZW4gdG8gd2hpY2hldmVyIHdhcyBoaWdoZXN0XHJcbiAgICAgICAgICAgICAgICAkKCRjb2x1bW4sIHRoaXMpLmNzcygnbWluLWhlaWdodCcsIGhpZ2hlc3RCb3gpO1xyXG5cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBjaGFuZ2VTbGlja01lbnUgPSBmdW5jdGlvbigpIHtcclxuICAgICAgICAgICAgdmFyICR0aGlzID0gJCh0aGlzKSxcclxuICAgICAgICAgICAgICAgIHNsaWRlSW5kZXggPSAkc2xpY2suc2xpY2soJ3NsaWNrQ3VycmVudFNsaWRlJykgKyAxO1xyXG5cclxuICAgICAgICAgICAgJCgnLnNsaWNrX19saW5rcyBsaScpLnJlbW92ZUNsYXNzKCdhY3RpdmUnKTtcclxuICAgICAgICAgICAgJCgnLnNsaWNrX19saW5rcyBsaTpudGgtY2hpbGQoJyArIHNsaWRlSW5kZXggKyAnKScpLmFkZENsYXNzKCdhY3RpdmUnKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICR3aW5kb3cubG9hZChmdW5jdGlvbigpIHtcclxuICAgICAgICBpZiAoJHdpbmRvdy53aWR0aCgpID4gd01lZGl1bSkge1xyXG4gICAgICAgICAgICBlcXVhbGhlaWdodCgpO1xyXG4gICAgICAgIH1cclxuICAgIH0pO1xyXG4gICAgJHdpbmRvdy5yZXNpemUoZnVuY3Rpb24oKSB7XHJcbiAgICAgICAgaWYgKCR3aW5kb3cud2lkdGgoKSA+IHdNZWRpdW0pIHtcclxuICAgICAgICAgICAgZXF1YWxoZWlnaHQoKTtcclxuICAgICAgICAgICAgY29uc29sZS5sb2coJHdpbmRvdy53aWR0aCgpKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAkKCcuc2FtZS1oZWlnaHQnKS5yZW1vdmVBdHRyKCdzdHlsZScpO1xyXG4gICAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuXHJcblxyXG4gICAgJHNsaWNrLnNsaWNrKHtcclxuICAgICAgICBkb3RzOiBmYWxzZSxcclxuICAgICAgICBhcnJvd3M6IHRydWUsXHJcbiAgICAgICAgaW5maW5pdGU6IHRydWUsXHJcbiAgICAgICAgYWRhcHRpdmVIZWlnaHQ6IHRydWUsXHJcbiAgICB9KTtcclxuXHJcbiAgICAkc2xpY2tMaW5rcy5vbignY2xpY2snLCAnYScsIGZ1bmN0aW9uKGUpIHtcclxuICAgICAgICB2YXIgJHRoaXMgPSAkKHRoaXMpLFxyXG4gICAgICAgICAgICBzbGlkZUluZGV4ID0gJHRoaXMuY2xvc2VzdCgnbGknKS5pbmRleCgpO1xyXG5cclxuICAgICAgICAkKCcuc2xpY2tfX2xpbmtzIGxpJykucmVtb3ZlQ2xhc3MoJ2FjdGl2ZScpO1xyXG4gICAgICAgICR0aGlzLnBhcmVudCgpLmFkZENsYXNzKCdhY3RpdmUnKTtcclxuXHJcbiAgICAgICAgJHNsaWNrLnNsaWNrKCdzbGlja0dvVG8nLCBwYXJzZUludChzbGlkZUluZGV4KSk7XHJcbiAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgJCgnLnNsaWNrLWFycm93Jykub24oJ2NsaWNrJywgZnVuY3Rpb24oZSkge1xyXG4gICAgICAgIGNoYW5nZVNsaWNrTWVudSgpO1xyXG4gICAgfSk7XHJcblxyXG4gICAgJHNsaWNrLm9uKCdzd2lwZScsIGZ1bmN0aW9uKGV2ZW50LCBzbGljaywgZGlyZWN0aW9uKSB7XHJcbiAgICAgICAgY2hhbmdlU2xpY2tNZW51KCk7XHJcbiAgICB9KTtcclxuXHJcblxyXG5cclxuXHJcblxyXG5cclxuXHJcblxyXG5cclxufSkoKTtcclxuIl0sInNvdXJjZVJvb3QiOiIvc291cmNlLyJ9
