diff --git a/dist/mi-angular-bitdash-player.js b/dist/mi-angular-bitdash-player.js index 7986dc1..0f170f0 100644 --- a/dist/mi-angular-bitdash-player.js +++ b/dist/mi-angular-bitdash-player.js @@ -68,409 +68,409 @@ /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * Simple DOM manipulation and DOM element event handling modeled after jQuery (as replacement for jQuery). - * - * Like jQuery, DOM operates on single elements and lists of elements. For example: creating an element returns a DOM - * instance with a single element, selecting elements returns a DOM instance with zero, one, or many elements. Similar - * to jQuery, setters usually affect all elements, while getters operate on only the first element. - * Also similar to jQuery, most methods (except getters) return the DOM instance facilitating easy chaining of method - * calls. - * - * Built with the help of: http://youmightnotneedjquery.com/ - */ -var DOM = (function () { - function DOM(something, attributes) { - this.document = document; // Set the global document to the local document field - if (something instanceof Array) { - if (something.length > 0 && something[0] instanceof HTMLElement) { - var elements = something; - this.elements = elements; - } - } - else if (something instanceof HTMLElement) { - var element = something; - this.elements = [element]; - } - else if (something instanceof Document) { - // When a document is passed in, we do not do anything with it, but by setting this.elements to null - // we give the event handling method a means to detect if the events should be registered on the document - // instead of elements. - this.elements = null; - } - else if (attributes) { - var tagName = something; - var element = document.createElement(tagName); - for (var attributeName in attributes) { - var attributeValue = attributes[attributeName]; - element.setAttribute(attributeName, attributeValue); - } - this.elements = [element]; - } - else { - var selector = something; - this.elements = this.findChildElements(selector); - } - } - Object.defineProperty(DOM.prototype, "length", { - /** - * Gets the number of elements that this DOM instance currently holds. - * @returns {number} the number of elements - */ - get: function () { - return this.elements ? this.elements.length : 0; - }, - enumerable: true, - configurable: true - }); - /** - * Gets the HTML elements that this DOM instance currently holds. - * @returns {HTMLElement[]} the raw HTML elements - * @deprecated use {@link #get()} instead - */ - DOM.prototype.getElements = function () { - return this.get(); - }; - DOM.prototype.get = function (index) { - if (index === undefined) { - return this.elements; - } - else if (!this.elements || index >= this.elements.length || index < -this.elements.length) { - return undefined; - } - else if (index < 0) { - return this.elements[this.elements.length - index]; - } - else { - return this.elements[index]; - } - }; - /** - * A shortcut method for iterating all elements. Shorts this.elements.forEach(...) to this.forEach(...). - * @param handler the handler to execute an operation on an element - */ - DOM.prototype.forEach = function (handler) { - if (!this.elements) { - return; - } - this.elements.forEach(function (element) { - handler(element); - }); - }; - DOM.prototype.findChildElementsOfElement = function (element, selector) { - var childElements = element.querySelectorAll(selector); - // Convert NodeList to Array - // https://toddmotto.com/a-comprehensive-dive-into-nodelists-arrays-converting-nodelists-and-understanding-the-dom/ - return [].slice.call(childElements); - }; - DOM.prototype.findChildElements = function (selector) { - var _this = this; - var allChildElements = []; - if (this.elements) { - this.forEach(function (element) { - allChildElements = allChildElements.concat(_this.findChildElementsOfElement(element, selector)); - }); - } - else { - return this.findChildElementsOfElement(document, selector); - } - return allChildElements; - }; - /** - * Finds all child elements of all elements matching the supplied selector. - * @param selector the selector to match with child elements - * @returns {DOM} a new DOM instance representing all matched children - */ - DOM.prototype.find = function (selector) { - var allChildElements = this.findChildElements(selector); - return new DOM(allChildElements); - }; - DOM.prototype.html = function (content) { - if (arguments.length > 0) { - return this.setHtml(content); - } - else { - return this.getHtml(); - } - }; - DOM.prototype.getHtml = function () { - return this.elements[0].innerHTML; - }; - DOM.prototype.setHtml = function (content) { - if (content === undefined || content == null) { - // Set to empty string to avoid innerHTML getting set to 'undefined' (all browsers) or 'null' (IE9) - content = ''; - } - this.forEach(function (element) { - element.innerHTML = content; - }); - return this; - }; - /** - * Clears the inner HTML of all elements (deletes all children). - * @returns {DOM} - */ - DOM.prototype.empty = function () { - this.forEach(function (element) { - element.innerHTML = ''; - }); - return this; - }; - /** - * Returns the current value of the first form element, e.g. the selected value of a select box or the text if an - * input field. - * @returns {string} the value of a form element - */ - DOM.prototype.val = function () { - var element = this.elements[0]; - if (element instanceof HTMLSelectElement || element instanceof HTMLInputElement) { - return element.value; - } - else { - // TODO add support for missing form elements - throw new Error("val() not supported for " + typeof element); - } - }; - DOM.prototype.attr = function (attribute, value) { - if (arguments.length > 1) { - return this.setAttr(attribute, value); - } - else { - return this.getAttr(attribute); - } - }; - DOM.prototype.getAttr = function (attribute) { - return this.elements[0].getAttribute(attribute); - }; - DOM.prototype.setAttr = function (attribute, value) { - this.forEach(function (element) { - element.setAttribute(attribute, value); - }); - return this; - }; - DOM.prototype.data = function (dataAttribute, value) { - if (arguments.length > 1) { - return this.setData(dataAttribute, value); - } - else { - return this.getData(dataAttribute); - } - }; - DOM.prototype.getData = function (dataAttribute) { - return this.elements[0].getAttribute('data-' + dataAttribute); - }; - DOM.prototype.setData = function (dataAttribute, value) { - this.forEach(function (element) { - element.setAttribute('data-' + dataAttribute, value); - }); - return this; - }; - /** - * Appends one or more DOM elements as children to all elements. - * @param childElements the chrild elements to append - * @returns {DOM} - */ - DOM.prototype.append = function () { - var childElements = []; - for (var _i = 0; _i < arguments.length; _i++) { - childElements[_i] = arguments[_i]; - } - this.forEach(function (element) { - childElements.forEach(function (childElement) { - childElement.elements.forEach(function (_, index) { - element.appendChild(childElement.elements[index]); - }); - }); - }); - return this; - }; - /** - * Removes all elements from the DOM. - */ - DOM.prototype.remove = function () { - this.forEach(function (element) { - var parent = element.parentNode; - if (parent) { - parent.removeChild(element); - } - }); - }; - /** - * Returns the offset of the first element from the document's top left corner. - * @returns {Offset} - */ - DOM.prototype.offset = function () { - var element = this.elements[0]; - var elementRect = element.getBoundingClientRect(); - var htmlRect = document.body.parentElement.getBoundingClientRect(); - // Virtual viewport scroll handling (e.g. pinch zoomed viewports in mobile browsers or desktop Chrome/Edge) - // 'normal' zooms and virtual viewport zooms (aka layout viewport) result in different - // element.getBoundingClientRect() results: - // - with normal scrolls, the clientRect decreases with an increase in scroll(Top|Left)/page(X|Y)Offset - // - with pinch zoom scrolls, the clientRect stays the same while scroll/pageOffset changes - // This means, that the combination of clientRect + scroll/pageOffset does not work to calculate the offset - // from the document's upper left origin when pinch zoom is used. - // To work around this issue, we do not use scroll/pageOffset but get the clientRect of the html element and - // subtract it from the element's rect, which always results in the offset from the document origin. - // NOTE: the current way of offset calculation was implemented specifically to track event positions on the - // seek bar, and it might break compatibility with jQuery's offset() method. If this ever turns out to be a - // problem, this method should be reverted to the old version and the offset calculation moved to the seek bar. - return { - top: elementRect.top - htmlRect.top, - left: elementRect.left - htmlRect.left, - }; - }; - /** - * Returns the width of the first element. - * @returns {number} the width of the first element - */ - DOM.prototype.width = function () { - // TODO check if this is the same as jQuery's width() (probably not) - return this.elements[0].offsetWidth; - }; - /** - * Returns the height of the first element. - * @returns {number} the height of the first element - */ - DOM.prototype.height = function () { - // TODO check if this is the same as jQuery's height() (probably not) - return this.elements[0].offsetHeight; - }; - /** - * Attaches an event handler to one or more events on all elements. - * @param eventName the event name (or multiple names separated by space) to listen to - * @param eventHandler the event handler to call when the event fires - * @returns {DOM} - */ - DOM.prototype.on = function (eventName, eventHandler) { - var _this = this; - var events = eventName.split(' '); - events.forEach(function (event) { - if (_this.elements == null) { - _this.document.addEventListener(event, eventHandler); - } - else { - _this.forEach(function (element) { - element.addEventListener(event, eventHandler); - }); - } - }); - return this; - }; - /** - * Removes an event handler from one or more events on all elements. - * @param eventName the event name (or multiple names separated by space) to remove the handler from - * @param eventHandler the event handler to remove - * @returns {DOM} - */ - DOM.prototype.off = function (eventName, eventHandler) { - var _this = this; - var events = eventName.split(' '); - events.forEach(function (event) { - if (_this.elements == null) { - _this.document.removeEventListener(event, eventHandler); - } - else { - _this.forEach(function (element) { - element.removeEventListener(event, eventHandler); - }); - } - }); - return this; - }; - /** - * Adds the specified class(es) to all elements. - * @param className the class(es) to add, multiple classes separated by space - * @returns {DOM} - */ - DOM.prototype.addClass = function (className) { - this.forEach(function (element) { - if (element.classList) { - element.classList.add(className); - } - else { - element.className += ' ' + className; - } - }); - return this; - }; - /** - * Removed the specified class(es) from all elements. - * @param className the class(es) to remove, multiple classes separated by space - * @returns {DOM} - */ - DOM.prototype.removeClass = function (className) { - this.forEach(function (element) { - if (element.classList) { - element.classList.remove(className); - } - else { - element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); - } - }); - return this; - }; - /** - * Checks if any of the elements has the specified class. - * @param className the class name to check - * @returns {boolean} true if one of the elements has the class attached, else if no element has it attached - */ - DOM.prototype.hasClass = function (className) { - var hasClass = false; - this.forEach(function (element) { - if (element.classList) { - if (element.classList.contains(className)) { - // Since we are inside a handler, we can't just 'return true'. Instead, we save it to a variable - // and return it at the end of the function body. - hasClass = true; - } - } - else { - if (new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className)) { - // See comment above - hasClass = true; - } - } - }); - return hasClass; - }; - DOM.prototype.css = function (propertyNameOrCollection, value) { - if (typeof propertyNameOrCollection === 'string') { - var propertyName = propertyNameOrCollection; - if (arguments.length === 2) { - return this.setCss(propertyName, value); - } - else { - return this.getCss(propertyName); - } - } - else { - var propertyValueCollection = propertyNameOrCollection; - return this.setCssCollection(propertyValueCollection); - } - }; - DOM.prototype.getCss = function (propertyName) { - return getComputedStyle(this.elements[0])[propertyName]; - }; - DOM.prototype.setCss = function (propertyName, value) { - this.forEach(function (element) { - // cast to resolve TS7015: http://stackoverflow.com/a/36627114/370252 - element.style[propertyName] = value; - }); - return this; - }; - DOM.prototype.setCssCollection = function (ruleValueCollection) { - this.forEach(function (element) { - // http://stackoverflow.com/a/34490573/370252 - Object.assign(element.style, ruleValueCollection); - }); - return this; - }; - return DOM; -}()); -exports.DOM = DOM; + +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Simple DOM manipulation and DOM element event handling modeled after jQuery (as replacement for jQuery). + * + * Like jQuery, DOM operates on single elements and lists of elements. For example: creating an element returns a DOM + * instance with a single element, selecting elements returns a DOM instance with zero, one, or many elements. Similar + * to jQuery, setters usually affect all elements, while getters operate on only the first element. + * Also similar to jQuery, most methods (except getters) return the DOM instance facilitating easy chaining of method + * calls. + * + * Built with the help of: http://youmightnotneedjquery.com/ + */ +var DOM = (function () { + function DOM(something, attributes) { + this.document = document; // Set the global document to the local document field + if (something instanceof Array) { + if (something.length > 0 && something[0] instanceof HTMLElement) { + var elements = something; + this.elements = elements; + } + } + else if (something instanceof HTMLElement) { + var element = something; + this.elements = [element]; + } + else if (something instanceof Document) { + // When a document is passed in, we do not do anything with it, but by setting this.elements to null + // we give the event handling method a means to detect if the events should be registered on the document + // instead of elements. + this.elements = null; + } + else if (attributes) { + var tagName = something; + var element = document.createElement(tagName); + for (var attributeName in attributes) { + var attributeValue = attributes[attributeName]; + element.setAttribute(attributeName, attributeValue); + } + this.elements = [element]; + } + else { + var selector = something; + this.elements = this.findChildElements(selector); + } + } + Object.defineProperty(DOM.prototype, "length", { + /** + * Gets the number of elements that this DOM instance currently holds. + * @returns {number} the number of elements + */ + get: function () { + return this.elements ? this.elements.length : 0; + }, + enumerable: true, + configurable: true + }); + /** + * Gets the HTML elements that this DOM instance currently holds. + * @returns {HTMLElement[]} the raw HTML elements + * @deprecated use {@link #get()} instead + */ + DOM.prototype.getElements = function () { + return this.get(); + }; + DOM.prototype.get = function (index) { + if (index === undefined) { + return this.elements; + } + else if (!this.elements || index >= this.elements.length || index < -this.elements.length) { + return undefined; + } + else if (index < 0) { + return this.elements[this.elements.length - index]; + } + else { + return this.elements[index]; + } + }; + /** + * A shortcut method for iterating all elements. Shorts this.elements.forEach(...) to this.forEach(...). + * @param handler the handler to execute an operation on an element + */ + DOM.prototype.forEach = function (handler) { + if (!this.elements) { + return; + } + this.elements.forEach(function (element) { + handler(element); + }); + }; + DOM.prototype.findChildElementsOfElement = function (element, selector) { + var childElements = element.querySelectorAll(selector); + // Convert NodeList to Array + // https://toddmotto.com/a-comprehensive-dive-into-nodelists-arrays-converting-nodelists-and-understanding-the-dom/ + return [].slice.call(childElements); + }; + DOM.prototype.findChildElements = function (selector) { + var _this = this; + var allChildElements = []; + if (this.elements) { + this.forEach(function (element) { + allChildElements = allChildElements.concat(_this.findChildElementsOfElement(element, selector)); + }); + } + else { + return this.findChildElementsOfElement(document, selector); + } + return allChildElements; + }; + /** + * Finds all child elements of all elements matching the supplied selector. + * @param selector the selector to match with child elements + * @returns {DOM} a new DOM instance representing all matched children + */ + DOM.prototype.find = function (selector) { + var allChildElements = this.findChildElements(selector); + return new DOM(allChildElements); + }; + DOM.prototype.html = function (content) { + if (arguments.length > 0) { + return this.setHtml(content); + } + else { + return this.getHtml(); + } + }; + DOM.prototype.getHtml = function () { + return this.elements[0].innerHTML; + }; + DOM.prototype.setHtml = function (content) { + if (content === undefined || content == null) { + // Set to empty string to avoid innerHTML getting set to 'undefined' (all browsers) or 'null' (IE9) + content = ''; + } + this.forEach(function (element) { + element.innerHTML = content; + }); + return this; + }; + /** + * Clears the inner HTML of all elements (deletes all children). + * @returns {DOM} + */ + DOM.prototype.empty = function () { + this.forEach(function (element) { + element.innerHTML = ''; + }); + return this; + }; + /** + * Returns the current value of the first form element, e.g. the selected value of a select box or the text if an + * input field. + * @returns {string} the value of a form element + */ + DOM.prototype.val = function () { + var element = this.elements[0]; + if (element instanceof HTMLSelectElement || element instanceof HTMLInputElement) { + return element.value; + } + else { + // TODO add support for missing form elements + throw new Error("val() not supported for " + typeof element); + } + }; + DOM.prototype.attr = function (attribute, value) { + if (arguments.length > 1) { + return this.setAttr(attribute, value); + } + else { + return this.getAttr(attribute); + } + }; + DOM.prototype.getAttr = function (attribute) { + return this.elements[0].getAttribute(attribute); + }; + DOM.prototype.setAttr = function (attribute, value) { + this.forEach(function (element) { + element.setAttribute(attribute, value); + }); + return this; + }; + DOM.prototype.data = function (dataAttribute, value) { + if (arguments.length > 1) { + return this.setData(dataAttribute, value); + } + else { + return this.getData(dataAttribute); + } + }; + DOM.prototype.getData = function (dataAttribute) { + return this.elements[0].getAttribute('data-' + dataAttribute); + }; + DOM.prototype.setData = function (dataAttribute, value) { + this.forEach(function (element) { + element.setAttribute('data-' + dataAttribute, value); + }); + return this; + }; + /** + * Appends one or more DOM elements as children to all elements. + * @param childElements the chrild elements to append + * @returns {DOM} + */ + DOM.prototype.append = function () { + var childElements = []; + for (var _i = 0; _i < arguments.length; _i++) { + childElements[_i] = arguments[_i]; + } + this.forEach(function (element) { + childElements.forEach(function (childElement) { + childElement.elements.forEach(function (_, index) { + element.appendChild(childElement.elements[index]); + }); + }); + }); + return this; + }; + /** + * Removes all elements from the DOM. + */ + DOM.prototype.remove = function () { + this.forEach(function (element) { + var parent = element.parentNode; + if (parent) { + parent.removeChild(element); + } + }); + }; + /** + * Returns the offset of the first element from the document's top left corner. + * @returns {Offset} + */ + DOM.prototype.offset = function () { + var element = this.elements[0]; + var elementRect = element.getBoundingClientRect(); + var htmlRect = document.body.parentElement.getBoundingClientRect(); + // Virtual viewport scroll handling (e.g. pinch zoomed viewports in mobile browsers or desktop Chrome/Edge) + // 'normal' zooms and virtual viewport zooms (aka layout viewport) result in different + // element.getBoundingClientRect() results: + // - with normal scrolls, the clientRect decreases with an increase in scroll(Top|Left)/page(X|Y)Offset + // - with pinch zoom scrolls, the clientRect stays the same while scroll/pageOffset changes + // This means, that the combination of clientRect + scroll/pageOffset does not work to calculate the offset + // from the document's upper left origin when pinch zoom is used. + // To work around this issue, we do not use scroll/pageOffset but get the clientRect of the html element and + // subtract it from the element's rect, which always results in the offset from the document origin. + // NOTE: the current way of offset calculation was implemented specifically to track event positions on the + // seek bar, and it might break compatibility with jQuery's offset() method. If this ever turns out to be a + // problem, this method should be reverted to the old version and the offset calculation moved to the seek bar. + return { + top: elementRect.top - htmlRect.top, + left: elementRect.left - htmlRect.left, + }; + }; + /** + * Returns the width of the first element. + * @returns {number} the width of the first element + */ + DOM.prototype.width = function () { + // TODO check if this is the same as jQuery's width() (probably not) + return this.elements[0].offsetWidth; + }; + /** + * Returns the height of the first element. + * @returns {number} the height of the first element + */ + DOM.prototype.height = function () { + // TODO check if this is the same as jQuery's height() (probably not) + return this.elements[0].offsetHeight; + }; + /** + * Attaches an event handler to one or more events on all elements. + * @param eventName the event name (or multiple names separated by space) to listen to + * @param eventHandler the event handler to call when the event fires + * @returns {DOM} + */ + DOM.prototype.on = function (eventName, eventHandler) { + var _this = this; + var events = eventName.split(' '); + events.forEach(function (event) { + if (_this.elements == null) { + _this.document.addEventListener(event, eventHandler); + } + else { + _this.forEach(function (element) { + element.addEventListener(event, eventHandler); + }); + } + }); + return this; + }; + /** + * Removes an event handler from one or more events on all elements. + * @param eventName the event name (or multiple names separated by space) to remove the handler from + * @param eventHandler the event handler to remove + * @returns {DOM} + */ + DOM.prototype.off = function (eventName, eventHandler) { + var _this = this; + var events = eventName.split(' '); + events.forEach(function (event) { + if (_this.elements == null) { + _this.document.removeEventListener(event, eventHandler); + } + else { + _this.forEach(function (element) { + element.removeEventListener(event, eventHandler); + }); + } + }); + return this; + }; + /** + * Adds the specified class(es) to all elements. + * @param className the class(es) to add, multiple classes separated by space + * @returns {DOM} + */ + DOM.prototype.addClass = function (className) { + this.forEach(function (element) { + if (element.classList) { + element.classList.add(className); + } + else { + element.className += ' ' + className; + } + }); + return this; + }; + /** + * Removed the specified class(es) from all elements. + * @param className the class(es) to remove, multiple classes separated by space + * @returns {DOM} + */ + DOM.prototype.removeClass = function (className) { + this.forEach(function (element) { + if (element.classList) { + element.classList.remove(className); + } + else { + element.className = element.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); + } + }); + return this; + }; + /** + * Checks if any of the elements has the specified class. + * @param className the class name to check + * @returns {boolean} true if one of the elements has the class attached, else if no element has it attached + */ + DOM.prototype.hasClass = function (className) { + var hasClass = false; + this.forEach(function (element) { + if (element.classList) { + if (element.classList.contains(className)) { + // Since we are inside a handler, we can't just 'return true'. Instead, we save it to a variable + // and return it at the end of the function body. + hasClass = true; + } + } + else { + if (new RegExp('(^| )' + className + '( |$)', 'gi').test(element.className)) { + // See comment above + hasClass = true; + } + } + }); + return hasClass; + }; + DOM.prototype.css = function (propertyNameOrCollection, value) { + if (typeof propertyNameOrCollection === 'string') { + var propertyName = propertyNameOrCollection; + if (arguments.length === 2) { + return this.setCss(propertyName, value); + } + else { + return this.getCss(propertyName); + } + } + else { + var propertyValueCollection = propertyNameOrCollection; + return this.setCssCollection(propertyValueCollection); + } + }; + DOM.prototype.getCss = function (propertyName) { + return getComputedStyle(this.elements[0])[propertyName]; + }; + DOM.prototype.setCss = function (propertyName, value) { + this.forEach(function (element) { + // cast to resolve TS7015: http://stackoverflow.com/a/36627114/370252 + element.style[propertyName] = value; + }); + return this; + }; + DOM.prototype.setCssCollection = function (ruleValueCollection) { + this.forEach(function (element) { + // http://stackoverflow.com/a/34490573/370252 + Object.assign(element.style, ruleValueCollection); + }); + return this; + }; + return DOM; +}()); +exports.DOM = DOM; /***/ }), @@ -478,130 +478,130 @@ exports.DOM = DOM; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var component_1 = __webpack_require__(2); -var dom_1 = __webpack_require__(0); -var arrayutils_1 = __webpack_require__(4); -/** - * A container component that can contain a collection of child components. - * Components can be added at construction time through the {@link ContainerConfig#components} setting, or later - * through the {@link Container#addComponent} method. The UIManager automatically takes care of all components, i.e. it - * initializes and configures them automatically. - * - * In the DOM, the container consists of an outer
(that can be configured by the config) and an inner wrapper - *
that contains the components. This double-
-structure is often required to achieve many advanced effects - * in CSS and/or JS, e.g. animations and certain formatting with absolute positioning. - * - * DOM example: - * - *
- *
- * ... child components ... - *
- *
- *
- */ -var Container = (function (_super) { - __extends(Container, _super); - function Container(config) { - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-container', - components: [], - }, _this.config); - _this.componentsToAdd = []; - _this.componentsToRemove = []; - return _this; - } - /** - * Adds a child component to the container. - * @param component the component to add - */ - Container.prototype.addComponent = function (component) { - this.config.components.push(component); - this.componentsToAdd.push(component); - }; - /** - * Removes a child component from the container. - * @param component the component to remove - * @returns {boolean} true if the component has been removed, false if it is not contained in this container - */ - Container.prototype.removeComponent = function (component) { - if (arrayutils_1.ArrayUtils.remove(this.config.components, component) != null) { - this.componentsToRemove.push(component); - return true; - } - else { - return false; - } - }; - /** - * Gets an array of all child components in this container. - * @returns {Component[]} - */ - Container.prototype.getComponents = function () { - return this.config.components; - }; - /** - * Removes all child components from the container. - */ - Container.prototype.removeComponents = function () { - for (var _i = 0, _a = this.getComponents().slice(); _i < _a.length; _i++) { - var component = _a[_i]; - this.removeComponent(component); - } - }; - /** - * Updates the DOM of the container with the current components. - */ - Container.prototype.updateComponents = function () { - /* We cannot just clear the container to remove all elements and then re-add those that should stay, because - * IE looses the innerHTML of unattached elements, leading to empty elements within the container (e.g. missing - * subtitle text in SubtitleLabel). - * Instead, we keep a list of elements to add and remove, leaving remaining elements alone. By keeping them in - * the DOM, their content gets preserved in all browsers. - */ - var component; - while (component = this.componentsToRemove.shift()) { - component.getDomElement().remove(); - } - while (component = this.componentsToAdd.shift()) { - this.innerContainerElement.append(component.getDomElement()); - } - }; - Container.prototype.toDomElement = function () { - // Create the container element (the outer
) - var containerElement = new dom_1.DOM(this.config.tag, { - 'id': this.config.id, - 'class': this.getCssClasses(), - }); - // Create the inner container element (the inner
) that will contain the components - var innerContainer = new dom_1.DOM(this.config.tag, { - 'class': this.prefixCss('container-wrapper'), - }); - this.innerContainerElement = innerContainer; - for (var _i = 0, _a = this.config.components; _i < _a.length; _i++) { - var initialComponent = _a[_i]; - this.componentsToAdd.push(initialComponent); - } - this.updateComponents(); - containerElement.append(innerContainer); - return containerElement; - }; - return Container; -}(component_1.Component)); -exports.Container = Container; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var component_1 = __webpack_require__(2); +var dom_1 = __webpack_require__(0); +var arrayutils_1 = __webpack_require__(4); +/** + * A container component that can contain a collection of child components. + * Components can be added at construction time through the {@link ContainerConfig#components} setting, or later + * through the {@link Container#addComponent} method. The UIManager automatically takes care of all components, i.e. it + * initializes and configures them automatically. + * + * In the DOM, the container consists of an outer
(that can be configured by the config) and an inner wrapper + *
that contains the components. This double-
-structure is often required to achieve many advanced effects + * in CSS and/or JS, e.g. animations and certain formatting with absolute positioning. + * + * DOM example: + * + *
+ *
+ * ... child components ... + *
+ *
+ *
+ */ +var Container = (function (_super) { + __extends(Container, _super); + function Container(config) { + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-container', + components: [], + }, _this.config); + _this.componentsToAdd = []; + _this.componentsToRemove = []; + return _this; + } + /** + * Adds a child component to the container. + * @param component the component to add + */ + Container.prototype.addComponent = function (component) { + this.config.components.push(component); + this.componentsToAdd.push(component); + }; + /** + * Removes a child component from the container. + * @param component the component to remove + * @returns {boolean} true if the component has been removed, false if it is not contained in this container + */ + Container.prototype.removeComponent = function (component) { + if (arrayutils_1.ArrayUtils.remove(this.config.components, component) != null) { + this.componentsToRemove.push(component); + return true; + } + else { + return false; + } + }; + /** + * Gets an array of all child components in this container. + * @returns {Component[]} + */ + Container.prototype.getComponents = function () { + return this.config.components; + }; + /** + * Removes all child components from the container. + */ + Container.prototype.removeComponents = function () { + for (var _i = 0, _a = this.getComponents().slice(); _i < _a.length; _i++) { + var component = _a[_i]; + this.removeComponent(component); + } + }; + /** + * Updates the DOM of the container with the current components. + */ + Container.prototype.updateComponents = function () { + /* We cannot just clear the container to remove all elements and then re-add those that should stay, because + * IE looses the innerHTML of unattached elements, leading to empty elements within the container (e.g. missing + * subtitle text in SubtitleLabel). + * Instead, we keep a list of elements to add and remove, leaving remaining elements alone. By keeping them in + * the DOM, their content gets preserved in all browsers. + */ + var component; + while (component = this.componentsToRemove.shift()) { + component.getDomElement().remove(); + } + while (component = this.componentsToAdd.shift()) { + this.innerContainerElement.append(component.getDomElement()); + } + }; + Container.prototype.toDomElement = function () { + // Create the container element (the outer
) + var containerElement = new dom_1.DOM(this.config.tag, { + 'id': this.config.id, + 'class': this.getCssClasses(), + }); + // Create the inner container element (the inner
) that will contain the components + var innerContainer = new dom_1.DOM(this.config.tag, { + 'class': this.prefixCss('container-wrapper'), + }); + this.innerContainerElement = innerContainer; + for (var _i = 0, _a = this.config.components; _i < _a.length; _i++) { + var initialComponent = _a[_i]; + this.componentsToAdd.push(initialComponent); + } + this.updateComponents(); + containerElement.append(innerContainer); + return containerElement; + }; + return Container; +}(component_1.Component)); +exports.Container = Container; /***/ }), @@ -609,334 +609,334 @@ exports.Container = Container; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var guid_1 = __webpack_require__(36); -var dom_1 = __webpack_require__(0); -var eventdispatcher_1 = __webpack_require__(3); -/** - * The base class of the UI framework. - * Each component must extend this class and optionally the config interface. - */ -var Component = (function () { - /** - * Constructs a component with an optionally supplied config. All subclasses must call the constructor of their - * superclass and then merge their configuration into the component's configuration. - * @param config the configuration for the component - */ - function Component(config) { - if (config === void 0) { config = {}; } - /** - * The list of events that this component offers. These events should always be private and only directly - * accessed from within the implementing component. - * - * Because TypeScript does not support private properties with the same name on different class hierarchy levels - * (i.e. superclass and subclass cannot contain a private property with the same name), the default naming - * convention for the event list of a component that should be followed by subclasses is the concatenation of the - * camel-cased class name + 'Events' (e.g. SubClass extends Component => subClassEvents). - * See {@link #componentEvents} for an example. - * - * Event properties should be named in camel case with an 'on' prefix and in the present tense. Async events may - * have a start event (when the operation starts) in the present tense, and must have an end event (when the - * operation ends) in the past tense (or present tense in special cases (e.g. onStart/onStarted or onPlay/onPlaying). - * See {@link #componentEvents#onShow} for an example. - * - * Each event should be accompanied with a protected method named by the convention eventName + 'Event' - * (e.g. onStartEvent), that actually triggers the event by calling {@link EventDispatcher#dispatch dispatch} and - * passing a reference to the component as first parameter. Components should always trigger their events with these - * methods. Implementing this pattern gives subclasses means to directly listen to the events by overriding the - * method (and saving the overhead of passing a handler to the event dispatcher) and more importantly to trigger - * these events without having access to the private event list. - * See {@link #onShow} for an example. - * - * To provide external code the possibility to listen to this component's events (subscribe, unsubscribe, etc.), - * each event should also be accompanied by a public getter function with the same name as the event's property, - * that returns the {@link Event} obtained from the event dispatcher by calling {@link EventDispatcher#getEvent}. - * See {@link #onShow} for an example. - * - * Full example for an event representing an example action in a example component: - * - * - * // Define an example component class with an example event - * class ExampleComponent extends Component { - * - * private exampleComponentEvents = { - * onExampleAction: new EventDispatcher() - * } - * - * // constructor and other stuff... - * - * protected onExampleActionEvent() { - * this.exampleComponentEvents.onExampleAction.dispatch(this); - * } - * - * get onExampleAction(): Event { - * return this.exampleComponentEvents.onExampleAction.getEvent(); - * } - * } - * - * // Create an instance of the component somewhere - * var exampleComponentInstance = new ExampleComponent(); - * - * // Subscribe to the example event on the component - * exampleComponentInstance.onExampleAction.subscribe(function (sender: ExampleComponent) { - * console.log('onExampleAction of ' + sender + ' has fired!'); - * }); - * - */ - this.componentEvents = { - onShow: new eventdispatcher_1.EventDispatcher(), - onHide: new eventdispatcher_1.EventDispatcher(), - onHoverChanged: new eventdispatcher_1.EventDispatcher(), - }; - // Create the configuration for this component - this.config = this.mergeConfig(config, { - tag: 'div', - id: 'mi-wbc-id-' + guid_1.Guid.next(), - cssPrefix: 'mi-wbc', - cssClass: 'ui-component', - cssClasses: [], - hidden: false, - }, {}); - } - /** - * Initializes the component, e.g. by applying config settings. - * This method must not be called from outside the UI framework. - * - * This method is automatically called by the {@link UIInstanceManager}. If the component is an inner component of - * some component, and thus encapsulated abd managed internally and never directly exposed to the UIManager, - * this method must be called from the managing component's {@link #initialize} method. - */ - Component.prototype.initialize = function () { - this.hidden = this.config.hidden; - // Hide the component at initialization if it is configured to be hidden - if (this.isHidden()) { - this.hidden = false; // Set flag to false for the following hide() call to work (hide() checks the flag) - this.hide(); - } - }; - /** - * Configures the component for the supplied Player and UIInstanceManager. This is the place where all the magic - * happens, where components typically subscribe and react to events (on their DOM element, the Player, or the - * UIInstanceManager), and basically everything that makes them interactive. - * This method is called only once, when the UIManager initializes the UI. - * - * Subclasses usually overwrite this method to add their own functionality. - * - * @param player the player which this component controls - * @param uimanager the UIInstanceManager that manages this component - */ - Component.prototype.configure = function (player, uimanager) { - var _this = this; - this.onShow.subscribe(function () { - uimanager.onComponentShow.dispatch(_this); - }); - this.onHide.subscribe(function () { - uimanager.onComponentHide.dispatch(_this); - }); - // Track the hovered state of the element - this.getDomElement().on('mouseenter', function () { - _this.onHoverChangedEvent(true); - }); - this.getDomElement().on('mouseleave', function () { - _this.onHoverChangedEvent(false); - }); - }; - /** - * Releases all resources and dependencies that the component holds. Player, DOM, and UIManager events are - * automatically removed during release and do not explicitly need to be removed here. - * This method is called by the UIManager when it releases the UI. - * - * Subclasses that need to release resources should override this method and call super.release(). - */ - Component.prototype.release = function () { - // Nothing to do here, override where necessary - }; - /** - * Generate the DOM element for this component. - * - * Subclasses usually overwrite this method to extend or replace the DOM element with their own design. - */ - Component.prototype.toDomElement = function () { - var element = new dom_1.DOM(this.config.tag, { - 'id': this.config.id, - 'class': this.getCssClasses(), - }); - return element; - }; - /** - * Returns the DOM element of this component. Creates the DOM element if it does not yet exist. - * - * Should not be overwritten by subclasses. - * - * @returns {DOM} - */ - Component.prototype.getDomElement = function () { - if (!this.element) { - this.element = this.toDomElement(); - } - return this.element; - }; - /** - * Merges a configuration with a default configuration and a base configuration from the superclass. - * - * @param config the configuration settings for the components, as usually passed to the constructor - * @param defaults a default configuration for settings that are not passed with the configuration - * @param base configuration inherited from a superclass - * @returns {Config} - */ - Component.prototype.mergeConfig = function (config, defaults, base) { - // Extend default config with supplied config - var merged = Object.assign({}, base, defaults, config); - // Return the extended config - return merged; - }; - /** - * Helper method that returns a string of all CSS classes of the component. - * - * @returns {string} - */ - Component.prototype.getCssClasses = function () { - var _this = this; - // Merge all CSS classes into single array - var flattenedArray = [this.config.cssClass].concat(this.config.cssClasses); - // Prefix classes - flattenedArray = flattenedArray.map(function (css) { - return _this.prefixCss(css); - }); - // Join array values into a string - var flattenedString = flattenedArray.join(' '); - // Return trimmed string to prevent whitespace at the end from the join operation - return flattenedString.trim(); - }; - Component.prototype.prefixCss = function (cssClassOrId) { - return this.config.cssPrefix + '-' + cssClassOrId; - }; - /** - * Returns the configuration object of the component. - * @returns {Config} - */ - Component.prototype.getConfig = function () { - return this.config; - }; - /** - * Hides the component if shown. - * This method basically transfers the component into the hidden state. Actual hiding is done via CSS. - */ - Component.prototype.hide = function () { - if (!this.hidden) { - this.hidden = true; - this.getDomElement().addClass(this.prefixCss(Component.CLASS_HIDDEN)); - this.onHideEvent(); - } - }; - /** - * Shows the component if hidden. - */ - Component.prototype.show = function () { - if (this.hidden) { - this.getDomElement().removeClass(this.prefixCss(Component.CLASS_HIDDEN)); - this.hidden = false; - this.onShowEvent(); - } - }; - /** - * Determines if the component is hidden. - * @returns {boolean} true if the component is hidden, else false - */ - Component.prototype.isHidden = function () { - return this.hidden; - }; - /** - * Determines if the component is shown. - * @returns {boolean} true if the component is visible, else false - */ - Component.prototype.isShown = function () { - return !this.isHidden(); - }; - /** - * Toggles the hidden state by hiding the component if it is shown, or showing it if hidden. - */ - Component.prototype.toggleHidden = function () { - if (this.isHidden()) { - this.show(); - } - else { - this.hide(); - } - }; - /** - * Determines if the component is currently hovered. - * @returns {boolean} true if the component is hovered, else false - */ - Component.prototype.isHovered = function () { - return this.hovered; - }; - /** - * Fires the onShow event. - * See the detailed explanation on event architecture on the {@link #componentEvents events list}. - */ - Component.prototype.onShowEvent = function () { - this.componentEvents.onShow.dispatch(this); - }; - /** - * Fires the onHide event. - * See the detailed explanation on event architecture on the {@link #componentEvents events list}. - */ - Component.prototype.onHideEvent = function () { - this.componentEvents.onHide.dispatch(this); - }; - /** - * Fires the onHoverChanged event. - * See the detailed explanation on event architecture on the {@link #componentEvents events list}. - */ - Component.prototype.onHoverChangedEvent = function (hovered) { - this.hovered = hovered; - this.componentEvents.onHoverChanged.dispatch(this, { hovered: hovered }); - }; - Object.defineProperty(Component.prototype, "onShow", { - /** - * Gets the event that is fired when the component is showing. - * See the detailed explanation on event architecture on the {@link #componentEvents events list}. - * @returns {Event, NoArgs>} - */ - get: function () { - return this.componentEvents.onShow.getEvent(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Component.prototype, "onHide", { - /** - * Gets the event that is fired when the component is hiding. - * See the detailed explanation on event architecture on the {@link #componentEvents events list}. - * @returns {Event, NoArgs>} - */ - get: function () { - return this.componentEvents.onHide.getEvent(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Component.prototype, "onHoverChanged", { - /** - * Gets the event that is fired when the component's hover-state is changing. - * @returns {Event, ComponentHoverChangedEventArgs>} - */ - get: function () { - return this.componentEvents.onHoverChanged.getEvent(); - }, - enumerable: true, - configurable: true - }); - return Component; -}()); -/** - * The classname that is attached to the element when it is in the hidden state. - * @type {string} - */ -Component.CLASS_HIDDEN = 'hidden'; -exports.Component = Component; + +Object.defineProperty(exports, "__esModule", { value: true }); +var guid_1 = __webpack_require__(36); +var dom_1 = __webpack_require__(0); +var eventdispatcher_1 = __webpack_require__(3); +/** + * The base class of the UI framework. + * Each component must extend this class and optionally the config interface. + */ +var Component = (function () { + /** + * Constructs a component with an optionally supplied config. All subclasses must call the constructor of their + * superclass and then merge their configuration into the component's configuration. + * @param config the configuration for the component + */ + function Component(config) { + if (config === void 0) { config = {}; } + /** + * The list of events that this component offers. These events should always be private and only directly + * accessed from within the implementing component. + * + * Because TypeScript does not support private properties with the same name on different class hierarchy levels + * (i.e. superclass and subclass cannot contain a private property with the same name), the default naming + * convention for the event list of a component that should be followed by subclasses is the concatenation of the + * camel-cased class name + 'Events' (e.g. SubClass extends Component => subClassEvents). + * See {@link #componentEvents} for an example. + * + * Event properties should be named in camel case with an 'on' prefix and in the present tense. Async events may + * have a start event (when the operation starts) in the present tense, and must have an end event (when the + * operation ends) in the past tense (or present tense in special cases (e.g. onStart/onStarted or onPlay/onPlaying). + * See {@link #componentEvents#onShow} for an example. + * + * Each event should be accompanied with a protected method named by the convention eventName + 'Event' + * (e.g. onStartEvent), that actually triggers the event by calling {@link EventDispatcher#dispatch dispatch} and + * passing a reference to the component as first parameter. Components should always trigger their events with these + * methods. Implementing this pattern gives subclasses means to directly listen to the events by overriding the + * method (and saving the overhead of passing a handler to the event dispatcher) and more importantly to trigger + * these events without having access to the private event list. + * See {@link #onShow} for an example. + * + * To provide external code the possibility to listen to this component's events (subscribe, unsubscribe, etc.), + * each event should also be accompanied by a public getter function with the same name as the event's property, + * that returns the {@link Event} obtained from the event dispatcher by calling {@link EventDispatcher#getEvent}. + * See {@link #onShow} for an example. + * + * Full example for an event representing an example action in a example component: + * + * + * // Define an example component class with an example event + * class ExampleComponent extends Component { + * + * private exampleComponentEvents = { + * onExampleAction: new EventDispatcher() + * } + * + * // constructor and other stuff... + * + * protected onExampleActionEvent() { + * this.exampleComponentEvents.onExampleAction.dispatch(this); + * } + * + * get onExampleAction(): Event { + * return this.exampleComponentEvents.onExampleAction.getEvent(); + * } + * } + * + * // Create an instance of the component somewhere + * var exampleComponentInstance = new ExampleComponent(); + * + * // Subscribe to the example event on the component + * exampleComponentInstance.onExampleAction.subscribe(function (sender: ExampleComponent) { + * console.log('onExampleAction of ' + sender + ' has fired!'); + * }); + * + */ + this.componentEvents = { + onShow: new eventdispatcher_1.EventDispatcher(), + onHide: new eventdispatcher_1.EventDispatcher(), + onHoverChanged: new eventdispatcher_1.EventDispatcher(), + }; + // Create the configuration for this component + this.config = this.mergeConfig(config, { + tag: 'div', + id: 'mi-wbc-id-' + guid_1.Guid.next(), + cssPrefix: 'mi-wbc', + cssClass: 'ui-component', + cssClasses: [], + hidden: false, + }, {}); + } + /** + * Initializes the component, e.g. by applying config settings. + * This method must not be called from outside the UI framework. + * + * This method is automatically called by the {@link UIInstanceManager}. If the component is an inner component of + * some component, and thus encapsulated abd managed internally and never directly exposed to the UIManager, + * this method must be called from the managing component's {@link #initialize} method. + */ + Component.prototype.initialize = function () { + this.hidden = this.config.hidden; + // Hide the component at initialization if it is configured to be hidden + if (this.isHidden()) { + this.hidden = false; // Set flag to false for the following hide() call to work (hide() checks the flag) + this.hide(); + } + }; + /** + * Configures the component for the supplied Player and UIInstanceManager. This is the place where all the magic + * happens, where components typically subscribe and react to events (on their DOM element, the Player, or the + * UIInstanceManager), and basically everything that makes them interactive. + * This method is called only once, when the UIManager initializes the UI. + * + * Subclasses usually overwrite this method to add their own functionality. + * + * @param player the player which this component controls + * @param uimanager the UIInstanceManager that manages this component + */ + Component.prototype.configure = function (player, uimanager) { + var _this = this; + this.onShow.subscribe(function () { + uimanager.onComponentShow.dispatch(_this); + }); + this.onHide.subscribe(function () { + uimanager.onComponentHide.dispatch(_this); + }); + // Track the hovered state of the element + this.getDomElement().on('mouseenter', function () { + _this.onHoverChangedEvent(true); + }); + this.getDomElement().on('mouseleave', function () { + _this.onHoverChangedEvent(false); + }); + }; + /** + * Releases all resources and dependencies that the component holds. Player, DOM, and UIManager events are + * automatically removed during release and do not explicitly need to be removed here. + * This method is called by the UIManager when it releases the UI. + * + * Subclasses that need to release resources should override this method and call super.release(). + */ + Component.prototype.release = function () { + // Nothing to do here, override where necessary + }; + /** + * Generate the DOM element for this component. + * + * Subclasses usually overwrite this method to extend or replace the DOM element with their own design. + */ + Component.prototype.toDomElement = function () { + var element = new dom_1.DOM(this.config.tag, { + 'id': this.config.id, + 'class': this.getCssClasses(), + }); + return element; + }; + /** + * Returns the DOM element of this component. Creates the DOM element if it does not yet exist. + * + * Should not be overwritten by subclasses. + * + * @returns {DOM} + */ + Component.prototype.getDomElement = function () { + if (!this.element) { + this.element = this.toDomElement(); + } + return this.element; + }; + /** + * Merges a configuration with a default configuration and a base configuration from the superclass. + * + * @param config the configuration settings for the components, as usually passed to the constructor + * @param defaults a default configuration for settings that are not passed with the configuration + * @param base configuration inherited from a superclass + * @returns {Config} + */ + Component.prototype.mergeConfig = function (config, defaults, base) { + // Extend default config with supplied config + var merged = Object.assign({}, base, defaults, config); + // Return the extended config + return merged; + }; + /** + * Helper method that returns a string of all CSS classes of the component. + * + * @returns {string} + */ + Component.prototype.getCssClasses = function () { + var _this = this; + // Merge all CSS classes into single array + var flattenedArray = [this.config.cssClass].concat(this.config.cssClasses); + // Prefix classes + flattenedArray = flattenedArray.map(function (css) { + return _this.prefixCss(css); + }); + // Join array values into a string + var flattenedString = flattenedArray.join(' '); + // Return trimmed string to prevent whitespace at the end from the join operation + return flattenedString.trim(); + }; + Component.prototype.prefixCss = function (cssClassOrId) { + return this.config.cssPrefix + '-' + cssClassOrId; + }; + /** + * Returns the configuration object of the component. + * @returns {Config} + */ + Component.prototype.getConfig = function () { + return this.config; + }; + /** + * Hides the component if shown. + * This method basically transfers the component into the hidden state. Actual hiding is done via CSS. + */ + Component.prototype.hide = function () { + if (!this.hidden) { + this.hidden = true; + this.getDomElement().addClass(this.prefixCss(Component.CLASS_HIDDEN)); + this.onHideEvent(); + } + }; + /** + * Shows the component if hidden. + */ + Component.prototype.show = function () { + if (this.hidden) { + this.getDomElement().removeClass(this.prefixCss(Component.CLASS_HIDDEN)); + this.hidden = false; + this.onShowEvent(); + } + }; + /** + * Determines if the component is hidden. + * @returns {boolean} true if the component is hidden, else false + */ + Component.prototype.isHidden = function () { + return this.hidden; + }; + /** + * Determines if the component is shown. + * @returns {boolean} true if the component is visible, else false + */ + Component.prototype.isShown = function () { + return !this.isHidden(); + }; + /** + * Toggles the hidden state by hiding the component if it is shown, or showing it if hidden. + */ + Component.prototype.toggleHidden = function () { + if (this.isHidden()) { + this.show(); + } + else { + this.hide(); + } + }; + /** + * Determines if the component is currently hovered. + * @returns {boolean} true if the component is hovered, else false + */ + Component.prototype.isHovered = function () { + return this.hovered; + }; + /** + * Fires the onShow event. + * See the detailed explanation on event architecture on the {@link #componentEvents events list}. + */ + Component.prototype.onShowEvent = function () { + this.componentEvents.onShow.dispatch(this); + }; + /** + * Fires the onHide event. + * See the detailed explanation on event architecture on the {@link #componentEvents events list}. + */ + Component.prototype.onHideEvent = function () { + this.componentEvents.onHide.dispatch(this); + }; + /** + * Fires the onHoverChanged event. + * See the detailed explanation on event architecture on the {@link #componentEvents events list}. + */ + Component.prototype.onHoverChangedEvent = function (hovered) { + this.hovered = hovered; + this.componentEvents.onHoverChanged.dispatch(this, { hovered: hovered }); + }; + Object.defineProperty(Component.prototype, "onShow", { + /** + * Gets the event that is fired when the component is showing. + * See the detailed explanation on event architecture on the {@link #componentEvents events list}. + * @returns {Event, NoArgs>} + */ + get: function () { + return this.componentEvents.onShow.getEvent(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Component.prototype, "onHide", { + /** + * Gets the event that is fired when the component is hiding. + * See the detailed explanation on event architecture on the {@link #componentEvents events list}. + * @returns {Event, NoArgs>} + */ + get: function () { + return this.componentEvents.onHide.getEvent(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Component.prototype, "onHoverChanged", { + /** + * Gets the event that is fired when the component's hover-state is changing. + * @returns {Event, ComponentHoverChangedEventArgs>} + */ + get: function () { + return this.componentEvents.onHoverChanged.getEvent(); + }, + enumerable: true, + configurable: true + }); + return Component; +}()); +/** + * The classname that is attached to the element when it is in the hidden state. + * @type {string} + */ +Component.CLASS_HIDDEN = 'hidden'; +exports.Component = Component; /***/ }), @@ -944,166 +944,166 @@ exports.Component = Component; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var arrayutils_1 = __webpack_require__(4); -/** - * Event dispatcher to subscribe and trigger events. Each event should have its own dispatcher. - */ -var EventDispatcher = (function () { - function EventDispatcher() { - this.listeners = []; - } - /** - * {@inheritDoc} - */ - EventDispatcher.prototype.subscribe = function (listener) { - this.listeners.push(new EventListenerWrapper(listener)); - }; - /** - * {@inheritDoc} - */ - EventDispatcher.prototype.subscribeOnce = function (listener) { - this.listeners.push(new EventListenerWrapper(listener, true)); - }; - /** - * {@inheritDoc} - */ - EventDispatcher.prototype.subscribeRateLimited = function (listener, rateMs) { - this.listeners.push(new RateLimitedEventListenerWrapper(listener, rateMs)); - }; - /** - * {@inheritDoc} - */ - EventDispatcher.prototype.unsubscribe = function (listener) { - // Iterate through listeners, compare with parameter, and remove if found - for (var i = 0; i < this.listeners.length; i++) { - var subscribedListener = this.listeners[i]; - if (subscribedListener.listener === listener) { - arrayutils_1.ArrayUtils.remove(this.listeners, subscribedListener); - return true; - } - } - return false; - }; - /** - * Removes all listeners from this dispatcher. - */ - EventDispatcher.prototype.unsubscribeAll = function () { - this.listeners = []; - }; - /** - * Dispatches an event to all subscribed listeners. - * @param sender the source of the event - * @param args the arguments for the event - */ - EventDispatcher.prototype.dispatch = function (sender, args) { - if (args === void 0) { args = null; } - var listenersToRemove = []; - // Call every listener - for (var _i = 0, _a = this.listeners; _i < _a.length; _i++) { - var listener = _a[_i]; - listener.fire(sender, args); - if (listener.isOnce()) { - listenersToRemove.push(listener); - } - } - // Remove one-time listener - for (var _b = 0, listenersToRemove_1 = listenersToRemove; _b < listenersToRemove_1.length; _b++) { - var listenerToRemove = listenersToRemove_1[_b]; - arrayutils_1.ArrayUtils.remove(this.listeners, listenerToRemove); - } - }; - /** - * Returns the event that this dispatcher manages and on which listeners can subscribe and unsubscribe event handlers. - * @returns {Event} - */ - EventDispatcher.prototype.getEvent = function () { - // For now, just cast the event dispatcher to the event interface. At some point in the future when the - // codebase grows, it might make sense to split the dispatcher into separate dispatcher and event classes. - return this; - }; - return EventDispatcher; -}()); -exports.EventDispatcher = EventDispatcher; -/** - * A basic event listener wrapper to manage listeners within the {@link EventDispatcher}. This is a 'private' class - * for internal dispatcher use and it is therefore not exported. - */ -var EventListenerWrapper = (function () { - function EventListenerWrapper(listener, once) { - if (once === void 0) { once = false; } - this.eventListener = listener; - this.once = once; - } - Object.defineProperty(EventListenerWrapper.prototype, "listener", { - /** - * Returns the wrapped event listener. - * @returns {EventListener} - */ - get: function () { - return this.eventListener; - }, - enumerable: true, - configurable: true - }); - /** - * Fires the wrapped event listener with the given arguments. - * @param sender - * @param args - */ - EventListenerWrapper.prototype.fire = function (sender, args) { - this.eventListener(sender, args); - }; - /** - * Checks if this listener is scheduled to be called only once. - * @returns {boolean} once if true - */ - EventListenerWrapper.prototype.isOnce = function () { - return this.once; - }; - return EventListenerWrapper; -}()); -/** - * Extends the basic {@link EventListenerWrapper} with rate-limiting functionality. - */ -var RateLimitedEventListenerWrapper = (function (_super) { - __extends(RateLimitedEventListenerWrapper, _super); - function RateLimitedEventListenerWrapper(listener, rateMs) { - var _this = _super.call(this, listener) || this; - _this.rateMs = rateMs; - _this.lastFireTime = 0; - // Wrap the event listener with an event listener that does the rate-limiting - _this.rateLimitingEventListener = function (sender, args) { - if (Date.now() - _this.lastFireTime > _this.rateMs) { - // Only if enough time since the previous call has passed, call the - // actual event listener and record the current time - _this.fireSuper(sender, args); - _this.lastFireTime = Date.now(); - } - }; - return _this; - } - RateLimitedEventListenerWrapper.prototype.fireSuper = function (sender, args) { - // Fire the actual external event listener - _super.prototype.fire.call(this, sender, args); - }; - RateLimitedEventListenerWrapper.prototype.fire = function (sender, args) { - // Fire the internal rate-limiting listener instead of the external event listener - this.rateLimitingEventListener(sender, args); - }; - return RateLimitedEventListenerWrapper; -}(EventListenerWrapper)); + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var arrayutils_1 = __webpack_require__(4); +/** + * Event dispatcher to subscribe and trigger events. Each event should have its own dispatcher. + */ +var EventDispatcher = (function () { + function EventDispatcher() { + this.listeners = []; + } + /** + * {@inheritDoc} + */ + EventDispatcher.prototype.subscribe = function (listener) { + this.listeners.push(new EventListenerWrapper(listener)); + }; + /** + * {@inheritDoc} + */ + EventDispatcher.prototype.subscribeOnce = function (listener) { + this.listeners.push(new EventListenerWrapper(listener, true)); + }; + /** + * {@inheritDoc} + */ + EventDispatcher.prototype.subscribeRateLimited = function (listener, rateMs) { + this.listeners.push(new RateLimitedEventListenerWrapper(listener, rateMs)); + }; + /** + * {@inheritDoc} + */ + EventDispatcher.prototype.unsubscribe = function (listener) { + // Iterate through listeners, compare with parameter, and remove if found + for (var i = 0; i < this.listeners.length; i++) { + var subscribedListener = this.listeners[i]; + if (subscribedListener.listener === listener) { + arrayutils_1.ArrayUtils.remove(this.listeners, subscribedListener); + return true; + } + } + return false; + }; + /** + * Removes all listeners from this dispatcher. + */ + EventDispatcher.prototype.unsubscribeAll = function () { + this.listeners = []; + }; + /** + * Dispatches an event to all subscribed listeners. + * @param sender the source of the event + * @param args the arguments for the event + */ + EventDispatcher.prototype.dispatch = function (sender, args) { + if (args === void 0) { args = null; } + var listenersToRemove = []; + // Call every listener + for (var _i = 0, _a = this.listeners; _i < _a.length; _i++) { + var listener = _a[_i]; + listener.fire(sender, args); + if (listener.isOnce()) { + listenersToRemove.push(listener); + } + } + // Remove one-time listener + for (var _b = 0, listenersToRemove_1 = listenersToRemove; _b < listenersToRemove_1.length; _b++) { + var listenerToRemove = listenersToRemove_1[_b]; + arrayutils_1.ArrayUtils.remove(this.listeners, listenerToRemove); + } + }; + /** + * Returns the event that this dispatcher manages and on which listeners can subscribe and unsubscribe event handlers. + * @returns {Event} + */ + EventDispatcher.prototype.getEvent = function () { + // For now, just cast the event dispatcher to the event interface. At some point in the future when the + // codebase grows, it might make sense to split the dispatcher into separate dispatcher and event classes. + return this; + }; + return EventDispatcher; +}()); +exports.EventDispatcher = EventDispatcher; +/** + * A basic event listener wrapper to manage listeners within the {@link EventDispatcher}. This is a 'private' class + * for internal dispatcher use and it is therefore not exported. + */ +var EventListenerWrapper = (function () { + function EventListenerWrapper(listener, once) { + if (once === void 0) { once = false; } + this.eventListener = listener; + this.once = once; + } + Object.defineProperty(EventListenerWrapper.prototype, "listener", { + /** + * Returns the wrapped event listener. + * @returns {EventListener} + */ + get: function () { + return this.eventListener; + }, + enumerable: true, + configurable: true + }); + /** + * Fires the wrapped event listener with the given arguments. + * @param sender + * @param args + */ + EventListenerWrapper.prototype.fire = function (sender, args) { + this.eventListener(sender, args); + }; + /** + * Checks if this listener is scheduled to be called only once. + * @returns {boolean} once if true + */ + EventListenerWrapper.prototype.isOnce = function () { + return this.once; + }; + return EventListenerWrapper; +}()); +/** + * Extends the basic {@link EventListenerWrapper} with rate-limiting functionality. + */ +var RateLimitedEventListenerWrapper = (function (_super) { + __extends(RateLimitedEventListenerWrapper, _super); + function RateLimitedEventListenerWrapper(listener, rateMs) { + var _this = _super.call(this, listener) || this; + _this.rateMs = rateMs; + _this.lastFireTime = 0; + // Wrap the event listener with an event listener that does the rate-limiting + _this.rateLimitingEventListener = function (sender, args) { + if (Date.now() - _this.lastFireTime > _this.rateMs) { + // Only if enough time since the previous call has passed, call the + // actual event listener and record the current time + _this.fireSuper(sender, args); + _this.lastFireTime = Date.now(); + } + }; + return _this; + } + RateLimitedEventListenerWrapper.prototype.fireSuper = function (sender, args) { + // Fire the actual external event listener + _super.prototype.fire.call(this, sender, args); + }; + RateLimitedEventListenerWrapper.prototype.fire = function (sender, args) { + // Fire the internal rate-limiting listener instead of the external event listener + this.rateLimitingEventListener(sender, args); + }; + return RateLimitedEventListenerWrapper; +}(EventListenerWrapper)); /***/ }), @@ -1111,27 +1111,27 @@ var RateLimitedEventListenerWrapper = (function (_super) { /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var ArrayUtils; -(function (ArrayUtils) { - /** - * Removes an item from an array. - * @param array the array that may contain the item to remove - * @param item the item to remove from the array - * @returns {any} the removed item or null if it wasn't part of the array - */ - function remove(array, item) { - var index = array.indexOf(item); - if (index > -1) { - return array.splice(index, 1)[0]; - } - else { - return null; - } - } - ArrayUtils.remove = remove; -})(ArrayUtils = exports.ArrayUtils || (exports.ArrayUtils = {})); + +Object.defineProperty(exports, "__esModule", { value: true }); +var ArrayUtils; +(function (ArrayUtils) { + /** + * Removes an item from an array. + * @param array the array that may contain the item to remove + * @param item the item to remove from the array + * @returns {any} the removed item or null if it wasn't part of the array + */ + function remove(array, item) { + var index = array.indexOf(item); + if (index > -1) { + return array.splice(index, 1)[0]; + } + else { + return null; + } + } + ArrayUtils.remove = remove; +})(ArrayUtils = exports.ArrayUtils || (exports.ArrayUtils = {})); /***/ }), @@ -1139,133 +1139,133 @@ var ArrayUtils; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var eventdispatcher_1 = __webpack_require__(3); -var browserutils_1 = __webpack_require__(11); -var PlayerUtils; -(function (PlayerUtils) { - var PlayerState; - (function (PlayerState) { - PlayerState[PlayerState["IDLE"] = 0] = "IDLE"; - PlayerState[PlayerState["PREPARED"] = 1] = "PREPARED"; - PlayerState[PlayerState["PLAYING"] = 2] = "PLAYING"; - PlayerState[PlayerState["PAUSED"] = 3] = "PAUSED"; - PlayerState[PlayerState["FINISHED"] = 4] = "FINISHED"; - })(PlayerState = PlayerUtils.PlayerState || (PlayerUtils.PlayerState = {})); - function isSourceLoaded(player) { - return player.getConfig().source !== undefined; - } - PlayerUtils.isSourceLoaded = isSourceLoaded; - function isTimeShiftAvailable(player) { - return player.isLive() && player.getMaxTimeShift() !== 0; - } - PlayerUtils.isTimeShiftAvailable = isTimeShiftAvailable; - function getState(player) { - if (player.hasEnded()) { - return PlayerState.FINISHED; - } - else if (player.isPlaying()) { - return PlayerState.PLAYING; - } - else if (player.isPaused()) { - return PlayerState.PAUSED; - } - else if (isSourceLoaded(player)) { - return PlayerState.PREPARED; - } - else { - return PlayerState.IDLE; - } - } - PlayerUtils.getState = getState; - var TimeShiftAvailabilityDetector = (function () { - function TimeShiftAvailabilityDetector(player) { - var _this = this; - this.timeShiftAvailabilityChangedEvent = new eventdispatcher_1.EventDispatcher(); - this.player = player; - this.timeShiftAvailable = undefined; - var timeShiftDetector = function () { - _this.detect(); - }; - // Try to detect timeshift availability in ON_READY, which works for DASH streams - player.addEventHandler(player.EVENT.ON_READY, timeShiftDetector); - // With HLS/NativePlayer streams, getMaxTimeShift can be 0 before the buffer fills, so we need to additionally - // check timeshift availability in ON_TIME_CHANGED - player.addEventHandler(player.EVENT.ON_TIME_CHANGED, timeShiftDetector); - } - TimeShiftAvailabilityDetector.prototype.detect = function () { - if (this.player.isLive()) { - var timeShiftAvailableNow = PlayerUtils.isTimeShiftAvailable(this.player); - // When the availability changes, we fire the event - if (timeShiftAvailableNow !== this.timeShiftAvailable) { - this.timeShiftAvailabilityChangedEvent.dispatch(this.player, { timeShiftAvailable: timeShiftAvailableNow }); - this.timeShiftAvailable = timeShiftAvailableNow; - } - } - }; - Object.defineProperty(TimeShiftAvailabilityDetector.prototype, "onTimeShiftAvailabilityChanged", { - get: function () { - return this.timeShiftAvailabilityChangedEvent.getEvent(); - }, - enumerable: true, - configurable: true - }); - return TimeShiftAvailabilityDetector; - }()); - PlayerUtils.TimeShiftAvailabilityDetector = TimeShiftAvailabilityDetector; - /** - * Detects changes of the stream type, i.e. changes of the return value of the player#isLive method. - * Normally, a stream cannot change its type during playback, it's either VOD or live. Due to bugs on some - * platforms or browsers, it can still change. It is therefore unreliable to just check #isLive and this detector - * should be used as a workaround instead. - * - * Known cases: - * - * - HLS VOD on Android 4.3 - * Video duration is initially 'Infinity' and only gets available after playback starts, so streams are wrongly - * reported as 'live' before playback (the live-check in the player checks for infinite duration). - */ - var LiveStreamDetector = (function () { - function LiveStreamDetector(player) { - var _this = this; - this.liveChangedEvent = new eventdispatcher_1.EventDispatcher(); - this.player = player; - this.live = undefined; - var liveDetector = function () { - _this.detect(); - }; - // Initialize when player is ready - player.addEventHandler(player.EVENT.ON_READY, liveDetector); - // Re-evaluate when playback starts - player.addEventHandler(player.EVENT.ON_PLAY, liveDetector); - // HLS live detection workaround for Android: - // Also re-evaluate during playback, because that is when the live flag might change. - // (Doing it only in Android Chrome saves unnecessary overhead on other plattforms) - if (browserutils_1.BrowserUtils.isAndroid && browserutils_1.BrowserUtils.isChrome) { - player.addEventHandler(player.EVENT.ON_TIME_CHANGED, liveDetector); - } - } - LiveStreamDetector.prototype.detect = function () { - var liveNow = this.player.isLive(); - // Compare current to previous live state flag and fire event when it changes. Since we initialize the flag - // with undefined, there is always at least an initial event fired that tells listeners the live state. - if (liveNow !== this.live) { - this.liveChangedEvent.dispatch(this.player, { live: liveNow }); - this.live = liveNow; - } - }; - Object.defineProperty(LiveStreamDetector.prototype, "onLiveChanged", { - get: function () { - return this.liveChangedEvent.getEvent(); - }, - enumerable: true, - configurable: true - }); - return LiveStreamDetector; - }()); - PlayerUtils.LiveStreamDetector = LiveStreamDetector; -})(PlayerUtils = exports.PlayerUtils || (exports.PlayerUtils = {})); + +Object.defineProperty(exports, "__esModule", { value: true }); +var eventdispatcher_1 = __webpack_require__(3); +var browserutils_1 = __webpack_require__(11); +var PlayerUtils; +(function (PlayerUtils) { + var PlayerState; + (function (PlayerState) { + PlayerState[PlayerState["IDLE"] = 0] = "IDLE"; + PlayerState[PlayerState["PREPARED"] = 1] = "PREPARED"; + PlayerState[PlayerState["PLAYING"] = 2] = "PLAYING"; + PlayerState[PlayerState["PAUSED"] = 3] = "PAUSED"; + PlayerState[PlayerState["FINISHED"] = 4] = "FINISHED"; + })(PlayerState = PlayerUtils.PlayerState || (PlayerUtils.PlayerState = {})); + function isSourceLoaded(player) { + return player.getConfig().source !== undefined; + } + PlayerUtils.isSourceLoaded = isSourceLoaded; + function isTimeShiftAvailable(player) { + return player.isLive() && player.getMaxTimeShift() !== 0; + } + PlayerUtils.isTimeShiftAvailable = isTimeShiftAvailable; + function getState(player) { + if (player.hasEnded()) { + return PlayerState.FINISHED; + } + else if (player.isPlaying()) { + return PlayerState.PLAYING; + } + else if (player.isPaused()) { + return PlayerState.PAUSED; + } + else if (isSourceLoaded(player)) { + return PlayerState.PREPARED; + } + else { + return PlayerState.IDLE; + } + } + PlayerUtils.getState = getState; + var TimeShiftAvailabilityDetector = (function () { + function TimeShiftAvailabilityDetector(player) { + var _this = this; + this.timeShiftAvailabilityChangedEvent = new eventdispatcher_1.EventDispatcher(); + this.player = player; + this.timeShiftAvailable = undefined; + var timeShiftDetector = function () { + _this.detect(); + }; + // Try to detect timeshift availability in ON_READY, which works for DASH streams + player.addEventHandler(player.EVENT.ON_READY, timeShiftDetector); + // With HLS/NativePlayer streams, getMaxTimeShift can be 0 before the buffer fills, so we need to additionally + // check timeshift availability in ON_TIME_CHANGED + player.addEventHandler(player.EVENT.ON_TIME_CHANGED, timeShiftDetector); + } + TimeShiftAvailabilityDetector.prototype.detect = function () { + if (this.player.isLive()) { + var timeShiftAvailableNow = PlayerUtils.isTimeShiftAvailable(this.player); + // When the availability changes, we fire the event + if (timeShiftAvailableNow !== this.timeShiftAvailable) { + this.timeShiftAvailabilityChangedEvent.dispatch(this.player, { timeShiftAvailable: timeShiftAvailableNow }); + this.timeShiftAvailable = timeShiftAvailableNow; + } + } + }; + Object.defineProperty(TimeShiftAvailabilityDetector.prototype, "onTimeShiftAvailabilityChanged", { + get: function () { + return this.timeShiftAvailabilityChangedEvent.getEvent(); + }, + enumerable: true, + configurable: true + }); + return TimeShiftAvailabilityDetector; + }()); + PlayerUtils.TimeShiftAvailabilityDetector = TimeShiftAvailabilityDetector; + /** + * Detects changes of the stream type, i.e. changes of the return value of the player#isLive method. + * Normally, a stream cannot change its type during playback, it's either VOD or live. Due to bugs on some + * platforms or browsers, it can still change. It is therefore unreliable to just check #isLive and this detector + * should be used as a workaround instead. + * + * Known cases: + * + * - HLS VOD on Android 4.3 + * Video duration is initially 'Infinity' and only gets available after playback starts, so streams are wrongly + * reported as 'live' before playback (the live-check in the player checks for infinite duration). + */ + var LiveStreamDetector = (function () { + function LiveStreamDetector(player) { + var _this = this; + this.liveChangedEvent = new eventdispatcher_1.EventDispatcher(); + this.player = player; + this.live = undefined; + var liveDetector = function () { + _this.detect(); + }; + // Initialize when player is ready + player.addEventHandler(player.EVENT.ON_READY, liveDetector); + // Re-evaluate when playback starts + player.addEventHandler(player.EVENT.ON_PLAY, liveDetector); + // HLS live detection workaround for Android: + // Also re-evaluate during playback, because that is when the live flag might change. + // (Doing it only in Android Chrome saves unnecessary overhead on other plattforms) + if (browserutils_1.BrowserUtils.isAndroid && browserutils_1.BrowserUtils.isChrome) { + player.addEventHandler(player.EVENT.ON_TIME_CHANGED, liveDetector); + } + } + LiveStreamDetector.prototype.detect = function () { + var liveNow = this.player.isLive(); + // Compare current to previous live state flag and fire event when it changes. Since we initialize the flag + // with undefined, there is always at least an initial event fired that tells listeners the live state. + if (liveNow !== this.live) { + this.liveChangedEvent.dispatch(this.player, { live: liveNow }); + this.live = liveNow; + } + }; + Object.defineProperty(LiveStreamDetector.prototype, "onLiveChanged", { + get: function () { + return this.liveChangedEvent.getEvent(); + }, + enumerable: true, + configurable: true + }); + return LiveStreamDetector; + }()); + PlayerUtils.LiveStreamDetector = LiveStreamDetector; +})(PlayerUtils = exports.PlayerUtils || (exports.PlayerUtils = {})); /***/ }), @@ -1273,76 +1273,76 @@ var PlayerUtils; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var component_1 = __webpack_require__(2); -var dom_1 = __webpack_require__(0); -var eventdispatcher_1 = __webpack_require__(3); -/** - * A simple clickable button. - */ -var Button = (function (_super) { - __extends(Button, _super); - function Button(config) { - var _this = _super.call(this, config) || this; - _this.buttonEvents = { - onClick: new eventdispatcher_1.EventDispatcher(), - }; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-button', - }, _this.config); - return _this; - } - Button.prototype.toDomElement = function () { - var _this = this; - // Create the button element with the text label - var buttonElement = new dom_1.DOM('button', { - 'type': 'button', - 'id': this.config.id, - 'class': this.getCssClasses(), - }).append(new dom_1.DOM('span', { - 'class': this.prefixCss('label'), - }).html(this.config.text)); - // Listen for the click event on the button element and trigger the corresponding event on the button component - buttonElement.on('click', function () { - _this.onClickEvent(); - }); - return buttonElement; - }; - /** - * Sets text on the label of the button. - * @param text the text to put into the label of the button - */ - Button.prototype.setText = function (text) { - this.getDomElement().find('.' + this.prefixCss('label')).html(text); - }; - Button.prototype.onClickEvent = function () { - this.buttonEvents.onClick.dispatch(this); - }; - Object.defineProperty(Button.prototype, "onClick", { - /** - * Gets the event that is fired when the button is clicked. - * @returns {Event, NoArgs>} - */ - get: function () { - return this.buttonEvents.onClick.getEvent(); - }, - enumerable: true, - configurable: true - }); - return Button; -}(component_1.Component)); -exports.Button = Button; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var component_1 = __webpack_require__(2); +var dom_1 = __webpack_require__(0); +var eventdispatcher_1 = __webpack_require__(3); +/** + * A simple clickable button. + */ +var Button = (function (_super) { + __extends(Button, _super); + function Button(config) { + var _this = _super.call(this, config) || this; + _this.buttonEvents = { + onClick: new eventdispatcher_1.EventDispatcher(), + }; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-button', + }, _this.config); + return _this; + } + Button.prototype.toDomElement = function () { + var _this = this; + // Create the button element with the text label + var buttonElement = new dom_1.DOM('button', { + 'type': 'button', + 'id': this.config.id, + 'class': this.getCssClasses(), + }).append(new dom_1.DOM('span', { + 'class': this.prefixCss('label'), + }).html(this.config.text)); + // Listen for the click event on the button element and trigger the corresponding event on the button component + buttonElement.on('click', function () { + _this.onClickEvent(); + }); + return buttonElement; + }; + /** + * Sets text on the label of the button. + * @param text the text to put into the label of the button + */ + Button.prototype.setText = function (text) { + this.getDomElement().find('.' + this.prefixCss('label')).html(text); + }; + Button.prototype.onClickEvent = function () { + this.buttonEvents.onClick.dispatch(this); + }; + Object.defineProperty(Button.prototype, "onClick", { + /** + * Gets the event that is fired when the button is clicked. + * @returns {Event, NoArgs>} + */ + get: function () { + return this.buttonEvents.onClick.getEvent(); + }, + enumerable: true, + configurable: true + }); + return Button; +}(component_1.Component)); +exports.Button = Button; /***/ }), @@ -1350,126 +1350,126 @@ exports.Button = Button; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var component_1 = __webpack_require__(2); -var dom_1 = __webpack_require__(0); -var eventdispatcher_1 = __webpack_require__(3); -/** - * A simple text label. - * - * DOM example: - * - * ...some text... - * - */ -var Label = (function (_super) { - __extends(Label, _super); - function Label(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.labelEvents = { - onClick: new eventdispatcher_1.EventDispatcher(), - onTextChanged: new eventdispatcher_1.EventDispatcher(), - }; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-label', - }, _this.config); - _this.text = _this.config.text; - return _this; - } - Label.prototype.toDomElement = function () { - var _this = this; - var labelElement = new dom_1.DOM('span', { - 'id': this.config.id, - 'class': this.getCssClasses(), - }).html(this.text); - labelElement.on('click', function () { - _this.onClickEvent(); - }); - return labelElement; - }; - /** - * Set the text on this label. - * @param text - */ - Label.prototype.setText = function (text) { - this.text = text; - this.getDomElement().html(text); - this.onTextChangedEvent(text); - }; - /** - * Gets the text on this label. - * @return {string} The text on the label - */ - Label.prototype.getText = function () { - return this.text; - }; - /** - * Clears the text on this label. - */ - Label.prototype.clearText = function () { - this.getDomElement().html(''); - this.onTextChangedEvent(null); - }; - /** - * Tests if the label is empty and does not contain any text. - * @return {boolean} True if the label is empty, else false - */ - Label.prototype.isEmpty = function () { - return !this.text; - }; - /** - * Fires the {@link #onClick} event. - * Can be used by subclasses to listen to this event without subscribing an event listener by overwriting the method - * and calling the super method. - */ - Label.prototype.onClickEvent = function () { - this.labelEvents.onClick.dispatch(this); - }; - /** - * Fires the {@link #onClick} event. - * Can be used by subclasses to listen to this event without subscribing an event listener by overwriting the method - * and calling the super method. - */ - Label.prototype.onTextChangedEvent = function (text) { - this.labelEvents.onTextChanged.dispatch(this, text); - }; - Object.defineProperty(Label.prototype, "onClick", { - /** - * Gets the event that is fired when the label is clicked. - * @returns {Event, NoArgs>} - */ - get: function () { - return this.labelEvents.onClick.getEvent(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(Label.prototype, "onTextChanged", { - /** - * Gets the event that is fired when the text on the label is changed. - * @returns {Event, string>} - */ - get: function () { - return this.labelEvents.onTextChanged.getEvent(); - }, - enumerable: true, - configurable: true - }); - return Label; -}(component_1.Component)); -exports.Label = Label; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var component_1 = __webpack_require__(2); +var dom_1 = __webpack_require__(0); +var eventdispatcher_1 = __webpack_require__(3); +/** + * A simple text label. + * + * DOM example: + * + * ...some text... + * + */ +var Label = (function (_super) { + __extends(Label, _super); + function Label(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.labelEvents = { + onClick: new eventdispatcher_1.EventDispatcher(), + onTextChanged: new eventdispatcher_1.EventDispatcher(), + }; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-label', + }, _this.config); + _this.text = _this.config.text; + return _this; + } + Label.prototype.toDomElement = function () { + var _this = this; + var labelElement = new dom_1.DOM('span', { + 'id': this.config.id, + 'class': this.getCssClasses(), + }).html(this.text); + labelElement.on('click', function () { + _this.onClickEvent(); + }); + return labelElement; + }; + /** + * Set the text on this label. + * @param text + */ + Label.prototype.setText = function (text) { + this.text = text; + this.getDomElement().html(text); + this.onTextChangedEvent(text); + }; + /** + * Gets the text on this label. + * @return {string} The text on the label + */ + Label.prototype.getText = function () { + return this.text; + }; + /** + * Clears the text on this label. + */ + Label.prototype.clearText = function () { + this.getDomElement().html(''); + this.onTextChangedEvent(null); + }; + /** + * Tests if the label is empty and does not contain any text. + * @return {boolean} True if the label is empty, else false + */ + Label.prototype.isEmpty = function () { + return !this.text; + }; + /** + * Fires the {@link #onClick} event. + * Can be used by subclasses to listen to this event without subscribing an event listener by overwriting the method + * and calling the super method. + */ + Label.prototype.onClickEvent = function () { + this.labelEvents.onClick.dispatch(this); + }; + /** + * Fires the {@link #onClick} event. + * Can be used by subclasses to listen to this event without subscribing an event listener by overwriting the method + * and calling the super method. + */ + Label.prototype.onTextChangedEvent = function (text) { + this.labelEvents.onTextChanged.dispatch(this, text); + }; + Object.defineProperty(Label.prototype, "onClick", { + /** + * Gets the event that is fired when the label is clicked. + * @returns {Event, NoArgs>} + */ + get: function () { + return this.labelEvents.onClick.getEvent(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(Label.prototype, "onTextChanged", { + /** + * Gets the event that is fired when the text on the label is changed. + * @returns {Event, string>} + */ + get: function () { + return this.labelEvents.onTextChanged.getEvent(); + }, + enumerable: true, + configurable: true + }); + return Label; +}(component_1.Component)); +exports.Label = Label; /***/ }), @@ -1477,139 +1477,139 @@ exports.Label = Label; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var button_1 = __webpack_require__(6); -var eventdispatcher_1 = __webpack_require__(3); -/** - * A button that can be toggled between 'on' and 'off' states. - */ -var ToggleButton = (function (_super) { - __extends(ToggleButton, _super); - function ToggleButton(config) { - var _this = _super.call(this, config) || this; - _this.toggleButtonEvents = { - onToggle: new eventdispatcher_1.EventDispatcher(), - onToggleOn: new eventdispatcher_1.EventDispatcher(), - onToggleOff: new eventdispatcher_1.EventDispatcher(), - }; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-togglebutton', - }, _this.config); - return _this; - } - /** - * Toggles the button to the 'on' state. - */ - ToggleButton.prototype.on = function () { - if (this.isOff()) { - this.onState = true; - this.getDomElement().removeClass(this.prefixCss(ToggleButton.CLASS_OFF)); - this.getDomElement().addClass(this.prefixCss(ToggleButton.CLASS_ON)); - this.onToggleEvent(); - this.onToggleOnEvent(); - } - }; - /** - * Toggles the button to the 'off' state. - */ - ToggleButton.prototype.off = function () { - if (this.isOn()) { - this.onState = false; - this.getDomElement().removeClass(this.prefixCss(ToggleButton.CLASS_ON)); - this.getDomElement().addClass(this.prefixCss(ToggleButton.CLASS_OFF)); - this.onToggleEvent(); - this.onToggleOffEvent(); - } - }; - /** - * Toggle the button 'on' if it is 'off', or 'off' if it is 'on'. - */ - ToggleButton.prototype.toggle = function () { - if (this.isOn()) { - this.off(); - } - else { - this.on(); - } - }; - /** - * Checks if the toggle button is in the 'on' state. - * @returns {boolean} true if button is 'on', false if 'off' - */ - ToggleButton.prototype.isOn = function () { - return this.onState; - }; - /** - * Checks if the toggle button is in the 'off' state. - * @returns {boolean} true if button is 'off', false if 'on' - */ - ToggleButton.prototype.isOff = function () { - return !this.isOn(); - }; - ToggleButton.prototype.onClickEvent = function () { - _super.prototype.onClickEvent.call(this); - // Fire the toggle event together with the click event - // (they are technically the same, only the semantics are different) - this.onToggleEvent(); - }; - ToggleButton.prototype.onToggleEvent = function () { - this.toggleButtonEvents.onToggle.dispatch(this); - }; - ToggleButton.prototype.onToggleOnEvent = function () { - this.toggleButtonEvents.onToggleOn.dispatch(this); - }; - ToggleButton.prototype.onToggleOffEvent = function () { - this.toggleButtonEvents.onToggleOff.dispatch(this); - }; - Object.defineProperty(ToggleButton.prototype, "onToggle", { - /** - * Gets the event that is fired when the button is toggled. - * @returns {Event, NoArgs>} - */ - get: function () { - return this.toggleButtonEvents.onToggle.getEvent(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(ToggleButton.prototype, "onToggleOn", { - /** - * Gets the event that is fired when the button is toggled 'on'. - * @returns {Event, NoArgs>} - */ - get: function () { - return this.toggleButtonEvents.onToggleOn.getEvent(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(ToggleButton.prototype, "onToggleOff", { - /** - * Gets the event that is fired when the button is toggled 'off'. - * @returns {Event, NoArgs>} - */ - get: function () { - return this.toggleButtonEvents.onToggleOff.getEvent(); - }, - enumerable: true, - configurable: true - }); - return ToggleButton; -}(button_1.Button)); -ToggleButton.CLASS_ON = 'on'; -ToggleButton.CLASS_OFF = 'off'; -exports.ToggleButton = ToggleButton; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var button_1 = __webpack_require__(6); +var eventdispatcher_1 = __webpack_require__(3); +/** + * A button that can be toggled between 'on' and 'off' states. + */ +var ToggleButton = (function (_super) { + __extends(ToggleButton, _super); + function ToggleButton(config) { + var _this = _super.call(this, config) || this; + _this.toggleButtonEvents = { + onToggle: new eventdispatcher_1.EventDispatcher(), + onToggleOn: new eventdispatcher_1.EventDispatcher(), + onToggleOff: new eventdispatcher_1.EventDispatcher(), + }; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-togglebutton', + }, _this.config); + return _this; + } + /** + * Toggles the button to the 'on' state. + */ + ToggleButton.prototype.on = function () { + if (this.isOff()) { + this.onState = true; + this.getDomElement().removeClass(this.prefixCss(ToggleButton.CLASS_OFF)); + this.getDomElement().addClass(this.prefixCss(ToggleButton.CLASS_ON)); + this.onToggleEvent(); + this.onToggleOnEvent(); + } + }; + /** + * Toggles the button to the 'off' state. + */ + ToggleButton.prototype.off = function () { + if (this.isOn()) { + this.onState = false; + this.getDomElement().removeClass(this.prefixCss(ToggleButton.CLASS_ON)); + this.getDomElement().addClass(this.prefixCss(ToggleButton.CLASS_OFF)); + this.onToggleEvent(); + this.onToggleOffEvent(); + } + }; + /** + * Toggle the button 'on' if it is 'off', or 'off' if it is 'on'. + */ + ToggleButton.prototype.toggle = function () { + if (this.isOn()) { + this.off(); + } + else { + this.on(); + } + }; + /** + * Checks if the toggle button is in the 'on' state. + * @returns {boolean} true if button is 'on', false if 'off' + */ + ToggleButton.prototype.isOn = function () { + return this.onState; + }; + /** + * Checks if the toggle button is in the 'off' state. + * @returns {boolean} true if button is 'off', false if 'on' + */ + ToggleButton.prototype.isOff = function () { + return !this.isOn(); + }; + ToggleButton.prototype.onClickEvent = function () { + _super.prototype.onClickEvent.call(this); + // Fire the toggle event together with the click event + // (they are technically the same, only the semantics are different) + this.onToggleEvent(); + }; + ToggleButton.prototype.onToggleEvent = function () { + this.toggleButtonEvents.onToggle.dispatch(this); + }; + ToggleButton.prototype.onToggleOnEvent = function () { + this.toggleButtonEvents.onToggleOn.dispatch(this); + }; + ToggleButton.prototype.onToggleOffEvent = function () { + this.toggleButtonEvents.onToggleOff.dispatch(this); + }; + Object.defineProperty(ToggleButton.prototype, "onToggle", { + /** + * Gets the event that is fired when the button is toggled. + * @returns {Event, NoArgs>} + */ + get: function () { + return this.toggleButtonEvents.onToggle.getEvent(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(ToggleButton.prototype, "onToggleOn", { + /** + * Gets the event that is fired when the button is toggled 'on'. + * @returns {Event, NoArgs>} + */ + get: function () { + return this.toggleButtonEvents.onToggleOn.getEvent(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(ToggleButton.prototype, "onToggleOff", { + /** + * Gets the event that is fired when the button is toggled 'off'. + * @returns {Event, NoArgs>} + */ + get: function () { + return this.toggleButtonEvents.onToggleOff.getEvent(); + }, + enumerable: true, + configurable: true + }); + return ToggleButton; +}(button_1.Button)); +ToggleButton.CLASS_ON = 'on'; +ToggleButton.CLASS_OFF = 'off'; +exports.ToggleButton = ToggleButton; /***/ }), @@ -1623,68 +1623,68 @@ module.exports = angular; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -// TODO change to internal (not exported) class, how to use in other files? -/** - * Executes a callback after a specified amount of time, optionally repeatedly until stopped. - */ -var Timeout = (function () { - /** - * Creates a new timeout callback handler. - * @param delay the delay in milliseconds after which the callback should be executed - * @param callback the callback to execute after the delay time - * @param repeat if true, call the callback repeatedly in delay intervals - */ - function Timeout(delay, callback, repeat) { - if (repeat === void 0) { repeat = false; } - this.delay = delay; - this.callback = callback; - this.repeat = repeat; - this.timeoutHandle = 0; - } - /** - * Starts the timeout and calls the callback when the timeout delay has passed. - * @returns {Timeout} the current timeout (so the start call can be chained to the constructor) - */ - Timeout.prototype.start = function () { - this.reset(); - return this; - }; - /** - * Clears the timeout. The callback will not be called if clear is called during the timeout. - */ - Timeout.prototype.clear = function () { - clearTimeout(this.timeoutHandle); - }; - /** - * Resets the passed timeout delay to zero. Can be used to defer the calling of the callback. - */ - Timeout.prototype.reset = function () { - var _this = this; - var lastScheduleTime = 0; - var delayAdjust = 0; - this.clear(); - var internalCallback = function () { - _this.callback(); - if (_this.repeat) { - var now = Date.now(); - // The time of one iteration from scheduling to executing the callback (usually a bit longer than the delay - // time) - var delta = now - lastScheduleTime; - // Calculate the delay adjustment for the next schedule to keep a steady delay interval over time - delayAdjust = _this.delay - delta + delayAdjust; - lastScheduleTime = now; - // Schedule next execution by the adjusted delay - _this.timeoutHandle = window.setTimeout(internalCallback, _this.delay + delayAdjust); - } - }; - lastScheduleTime = Date.now(); - this.timeoutHandle = window.setTimeout(internalCallback, this.delay); - }; - return Timeout; -}()); -exports.Timeout = Timeout; + +Object.defineProperty(exports, "__esModule", { value: true }); +// TODO change to internal (not exported) class, how to use in other files? +/** + * Executes a callback after a specified amount of time, optionally repeatedly until stopped. + */ +var Timeout = (function () { + /** + * Creates a new timeout callback handler. + * @param delay the delay in milliseconds after which the callback should be executed + * @param callback the callback to execute after the delay time + * @param repeat if true, call the callback repeatedly in delay intervals + */ + function Timeout(delay, callback, repeat) { + if (repeat === void 0) { repeat = false; } + this.delay = delay; + this.callback = callback; + this.repeat = repeat; + this.timeoutHandle = 0; + } + /** + * Starts the timeout and calls the callback when the timeout delay has passed. + * @returns {Timeout} the current timeout (so the start call can be chained to the constructor) + */ + Timeout.prototype.start = function () { + this.reset(); + return this; + }; + /** + * Clears the timeout. The callback will not be called if clear is called during the timeout. + */ + Timeout.prototype.clear = function () { + clearTimeout(this.timeoutHandle); + }; + /** + * Resets the passed timeout delay to zero. Can be used to defer the calling of the callback. + */ + Timeout.prototype.reset = function () { + var _this = this; + var lastScheduleTime = 0; + var delayAdjust = 0; + this.clear(); + var internalCallback = function () { + _this.callback(); + if (_this.repeat) { + var now = Date.now(); + // The time of one iteration from scheduling to executing the callback (usually a bit longer than the delay + // time) + var delta = now - lastScheduleTime; + // Calculate the delay adjustment for the next schedule to keep a steady delay interval over time + delayAdjust = _this.delay - delta + delayAdjust; + lastScheduleTime = now; + // Schedule next execution by the adjusted delay + _this.timeoutHandle = window.setTimeout(internalCallback, _this.delay + delayAdjust); + } + }; + lastScheduleTime = Date.now(); + this.timeoutHandle = window.setTimeout(internalCallback, this.delay); + }; + return Timeout; +}()); +exports.Timeout = Timeout; /***/ }), @@ -1692,18 +1692,18 @@ exports.Timeout = Timeout; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var BrowserUtils; -(function (BrowserUtils) { - // isMobile only needs to be evaluated once (it cannot change during a browser session) - // Mobile detection according to Mozilla recommendation: "In summary, we recommend looking for the string “Mobi” - // anywhere in the User Agent to detect a mobile device." - // https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent - BrowserUtils.isMobile = navigator && navigator.userAgent && /Mobi/.test(navigator.userAgent); - BrowserUtils.isChrome = navigator && navigator.userAgent && /Chrome/.test(navigator.userAgent); - BrowserUtils.isAndroid = navigator && navigator.userAgent && /Android/.test(navigator.userAgent); -})(BrowserUtils = exports.BrowserUtils || (exports.BrowserUtils = {})); + +Object.defineProperty(exports, "__esModule", { value: true }); +var BrowserUtils; +(function (BrowserUtils) { + // isMobile only needs to be evaluated once (it cannot change during a browser session) + // Mobile detection according to Mozilla recommendation: "In summary, we recommend looking for the string “Mobi” + // anywhere in the User Agent to detect a mobile device." + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent + BrowserUtils.isMobile = navigator && navigator.userAgent && /Mobi/.test(navigator.userAgent); + BrowserUtils.isChrome = navigator && navigator.userAgent && /Chrome/.test(navigator.userAgent); + BrowserUtils.isAndroid = navigator && navigator.userAgent && /Android/.test(navigator.userAgent); +})(BrowserUtils = exports.BrowserUtils || (exports.BrowserUtils = {})); /***/ }), @@ -1711,100 +1711,100 @@ var BrowserUtils; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var togglebutton_1 = __webpack_require__(8); -var playerutils_1 = __webpack_require__(5); -/** - * A button that toggles between playback and pause. - */ -var PlaybackToggleButton = (function (_super) { - __extends(PlaybackToggleButton, _super); - function PlaybackToggleButton(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-playbacktogglebutton', - text: 'Play/Pause', - }, _this.config); - return _this; - } - PlaybackToggleButton.prototype.configure = function (player, uimanager, handleClickEvent) { - var _this = this; - if (handleClickEvent === void 0) { handleClickEvent = true; } - _super.prototype.configure.call(this, player, uimanager); - var isSeeking = false; - // Handler to update button state based on player state - var playbackStateHandler = function (event) { - // If the UI is currently seeking, playback is temporarily stopped but the buttons should - // not reflect that and stay as-is (e.g indicate playback while seeking). - if (isSeeking) { - return; - } - if (player.isPlaying()) { - _this.on(); - } - else { - _this.off(); - } - }; - // Call handler upon these events - player.addEventHandler(player.EVENT.ON_PLAY, playbackStateHandler); - player.addEventHandler(player.EVENT.ON_PAUSED, playbackStateHandler); - // when playback finishes, player turns to paused mode - player.addEventHandler(player.EVENT.ON_PLAYBACK_FINISHED, playbackStateHandler); - player.addEventHandler(player.EVENT.ON_CAST_STARTED, playbackStateHandler); - player.addEventHandler(player.EVENT.ON_CAST_PLAYING, playbackStateHandler); - player.addEventHandler(player.EVENT.ON_CAST_PAUSED, playbackStateHandler); - player.addEventHandler(player.EVENT.ON_CAST_PLAYBACK_FINISHED, playbackStateHandler); - // Detect absence of timeshifting on live streams and add tagging class to convert button icons to play/stop - var timeShiftDetector = new playerutils_1.PlayerUtils.TimeShiftAvailabilityDetector(player); - timeShiftDetector.onTimeShiftAvailabilityChanged.subscribe(function (sender, args) { - if (!args.timeShiftAvailable) { - _this.getDomElement().addClass(_this.prefixCss(PlaybackToggleButton.CLASS_STOPTOGGLE)); - } - else { - _this.getDomElement().removeClass(_this.prefixCss(PlaybackToggleButton.CLASS_STOPTOGGLE)); - } - }); - timeShiftDetector.detect(); // Initial detection - if (handleClickEvent) { - // Control player by button events - // When a button event triggers a player API call, events are fired which in turn call the event handler - // above that updated the button state. - this.onClick.subscribe(function () { - if (player.isPlaying()) { - player.pause('ui'); - } - else { - player.play('ui'); - } - }); - } - // Track UI seeking status - uimanager.onSeek.subscribe(function () { - isSeeking = true; - }); - uimanager.onSeeked.subscribe(function () { - isSeeking = false; - }); - // Startup init - playbackStateHandler(null); - }; - return PlaybackToggleButton; -}(togglebutton_1.ToggleButton)); -PlaybackToggleButton.CLASS_STOPTOGGLE = 'stoptoggle'; -exports.PlaybackToggleButton = PlaybackToggleButton; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var togglebutton_1 = __webpack_require__(8); +var playerutils_1 = __webpack_require__(5); +/** + * A button that toggles between playback and pause. + */ +var PlaybackToggleButton = (function (_super) { + __extends(PlaybackToggleButton, _super); + function PlaybackToggleButton(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-playbacktogglebutton', + text: 'Play/Pause', + }, _this.config); + return _this; + } + PlaybackToggleButton.prototype.configure = function (player, uimanager, handleClickEvent) { + var _this = this; + if (handleClickEvent === void 0) { handleClickEvent = true; } + _super.prototype.configure.call(this, player, uimanager); + var isSeeking = false; + // Handler to update button state based on player state + var playbackStateHandler = function (event) { + // If the UI is currently seeking, playback is temporarily stopped but the buttons should + // not reflect that and stay as-is (e.g indicate playback while seeking). + if (isSeeking) { + return; + } + if (player.isPlaying()) { + _this.on(); + } + else { + _this.off(); + } + }; + // Call handler upon these events + player.addEventHandler(player.EVENT.ON_PLAY, playbackStateHandler); + player.addEventHandler(player.EVENT.ON_PAUSED, playbackStateHandler); + // when playback finishes, player turns to paused mode + player.addEventHandler(player.EVENT.ON_PLAYBACK_FINISHED, playbackStateHandler); + player.addEventHandler(player.EVENT.ON_CAST_STARTED, playbackStateHandler); + player.addEventHandler(player.EVENT.ON_CAST_PLAYING, playbackStateHandler); + player.addEventHandler(player.EVENT.ON_CAST_PAUSED, playbackStateHandler); + player.addEventHandler(player.EVENT.ON_CAST_PLAYBACK_FINISHED, playbackStateHandler); + // Detect absence of timeshifting on live streams and add tagging class to convert button icons to play/stop + var timeShiftDetector = new playerutils_1.PlayerUtils.TimeShiftAvailabilityDetector(player); + timeShiftDetector.onTimeShiftAvailabilityChanged.subscribe(function (sender, args) { + if (!args.timeShiftAvailable) { + _this.getDomElement().addClass(_this.prefixCss(PlaybackToggleButton.CLASS_STOPTOGGLE)); + } + else { + _this.getDomElement().removeClass(_this.prefixCss(PlaybackToggleButton.CLASS_STOPTOGGLE)); + } + }); + timeShiftDetector.detect(); // Initial detection + if (handleClickEvent) { + // Control player by button events + // When a button event triggers a player API call, events are fired which in turn call the event handler + // above that updated the button state. + this.onClick.subscribe(function () { + if (player.isPlaying()) { + player.pause('ui'); + } + else { + player.play('ui'); + } + }); + } + // Track UI seeking status + uimanager.onSeek.subscribe(function () { + isSeeking = true; + }); + uimanager.onSeeked.subscribe(function () { + isSeeking = false; + }); + // Startup init + playbackStateHandler(null); + }; + return PlaybackToggleButton; +}(togglebutton_1.ToggleButton)); +PlaybackToggleButton.CLASS_STOPTOGGLE = 'stoptoggle'; +exports.PlaybackToggleButton = PlaybackToggleButton; /***/ }), @@ -1812,734 +1812,734 @@ exports.PlaybackToggleButton = PlaybackToggleButton; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var component_1 = __webpack_require__(2); -var dom_1 = __webpack_require__(0); -var eventdispatcher_1 = __webpack_require__(3); -var timeout_1 = __webpack_require__(10); -var playerutils_1 = __webpack_require__(5); -/** - * A seek bar to seek within the player's media. It displays the current playback position, amount of buffed data, seek - * target, and keeps status about an ongoing seek. - * - * The seek bar displays different 'bars': - * - the playback position, i.e. the position in the media at which the player current playback pointer is positioned - * - the buffer position, which usually is the playback position plus the time span that is already buffered ahead - * - the seek position, used to preview to where in the timeline a seek will jump to - */ -var SeekBar = (function (_super) { - __extends(SeekBar, _super); - function SeekBar(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - /** - * Buffer of the the current playback position. The position must be buffered in case the element - * needs to be refreshed with {@link #refreshPlaybackPosition}. - * @type {number} - */ - _this.playbackPositionPercentage = 0; - // https://hacks.mozilla.org/2013/04/detecting-touch-its-the-why-not-the-how/ - _this.touchSupported = ('ontouchstart' in window); - _this.seekBarEvents = { - /** - * Fired when a scrubbing seek operation is started. - */ - onSeek: new eventdispatcher_1.EventDispatcher(), - /** - * Fired during a scrubbing seek to indicate that the seek preview (i.e. the video frame) should be updated. - */ - onSeekPreview: new eventdispatcher_1.EventDispatcher(), - /** - * Fired when a scrubbing seek has finished or when a direct seek is issued. - */ - onSeeked: new eventdispatcher_1.EventDispatcher(), - }; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-seekbar', - vertical: false, - smoothPlaybackPositionUpdateIntervalMs: 50, - hideInLivePlayback: true, - }, _this.config); - _this.label = _this.config.label; - _this.timelineMarkers = []; - return _this; - } - SeekBar.prototype.initialize = function () { - _super.prototype.initialize.call(this); - if (this.hasLabel()) { - this.getLabel().initialize(); - } - }; - SeekBar.prototype.configure = function (player, uimanager, configureSeek) { - var _this = this; - if (configureSeek === void 0) { configureSeek = true; } - _super.prototype.configure.call(this, player, uimanager); - // let config = this.getConfig(); - if (!configureSeek) { - // The configureSeek flag can be used by subclasses to disable configuration as seek bar. E.g. the volume - // slider is reusing this component but adds its own functionality, and does not need the seek functionality. - // This is actually a hack, the proper solution would be for both seek bar and volume sliders to extend - // a common base slider component and implement their functionality there. - return; - } - var playbackNotInitialized = true; - var isPlaying = false; - var isSeeking = false; - // Update playback and buffer positions - var playbackPositionHandler = function (event, forceUpdate) { - if (event === void 0) { event = null; } - if (forceUpdate === void 0) { forceUpdate = false; } - // Once this handler os called, playback has been started and we set the flag to false - playbackNotInitialized = false; - if (isSeeking) { - // We caught a seek preview seek, do not update the seekbar - return; - } - if (player.isLive()) { - if (player.getMaxTimeShift() === 0) { - // This case must be explicitly handled to avoid division by zero - _this.setPlaybackPosition(100); - } - else { - var playbackPositionPercentage = 100 - (100 / player.getMaxTimeShift() * player.getTimeShift()); - _this.setPlaybackPosition(playbackPositionPercentage); - } - // Always show full buffer for live streams - _this.setBufferPosition(100); - // Hide SeekBar if required. - // if (config.hideInLivePlayback) { - _this.hide(); - // } - } - else { - var playbackPositionPercentage = 100 / player.getDuration() * player.getCurrentTime(); - var videoBufferLength = player.getVideoBufferLength(); - var audioBufferLength = player.getAudioBufferLength(); - // Calculate the buffer length which is the smaller length of the audio and video buffers. If one of these - // buffers is not available, we set it's value to MAX_VALUE to make sure that the other real value is taken - // as the buffer length. - var bufferLength = Math.min(videoBufferLength != null ? videoBufferLength : Number.MAX_VALUE, audioBufferLength != null ? audioBufferLength : Number.MAX_VALUE); - // If both buffer lengths are missing, we set the buffer length to zero - if (bufferLength === Number.MAX_VALUE) { - bufferLength = 0; - } - var bufferPercentage = 100 / player.getDuration() * bufferLength; - // Update playback position only in paused state or in the initial startup state where player is neither - // paused nor playing. Playback updates are handled in the Timeout below. - if (_this.config.smoothPlaybackPositionUpdateIntervalMs === SeekBar.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED - || forceUpdate || player.isPaused() || (player.isPaused() === player.isPlaying())) { - _this.setPlaybackPosition(playbackPositionPercentage); - } - _this.setBufferPosition(playbackPositionPercentage + bufferPercentage); - } - }; - // Update seekbar upon these events - // init playback position when the player is ready - player.addEventHandler(player.EVENT.ON_READY, playbackPositionHandler); - // update playback position when it changes - player.addEventHandler(player.EVENT.ON_TIME_CHANGED, playbackPositionHandler); - // update bufferlevel when buffering is complete - player.addEventHandler(player.EVENT.ON_STALL_ENDED, playbackPositionHandler); - // update playback position when a seek has finished - player.addEventHandler(player.EVENT.ON_SEEKED, playbackPositionHandler); - // update playback position when a timeshift has finished - player.addEventHandler(player.EVENT.ON_TIME_SHIFTED, playbackPositionHandler); - // update bufferlevel when a segment has been downloaded - player.addEventHandler(player.EVENT.ON_SEGMENT_REQUEST_FINISHED, playbackPositionHandler); - // update playback position of Cast playback - player.addEventHandler(player.EVENT.ON_CAST_TIME_UPDATED, playbackPositionHandler); - // Seek handling - player.addEventHandler(player.EVENT.ON_SEEK, function () { - _this.setSeeking(true); - }); - player.addEventHandler(player.EVENT.ON_SEEKED, function () { - _this.setSeeking(false); - }); - player.addEventHandler(player.EVENT.ON_TIME_SHIFT, function () { - _this.setSeeking(true); - }); - player.addEventHandler(player.EVENT.ON_TIME_SHIFTED, function () { - _this.setSeeking(false); - }); - var seek = function (percentage) { - if (player.isLive()) { - player.timeShift(player.getMaxTimeShift() - (player.getMaxTimeShift() * (percentage / 100)), 'ui'); - } - else { - player.seek(player.getDuration() * (percentage / 100), 'ui'); - } - }; - this.onSeek.subscribe(function (sender) { - isSeeking = true; // track seeking status so we can catch events from seek preview seeks - // Notify UI manager of started seek - uimanager.onSeek.dispatch(sender); - // Save current playback state - isPlaying = player.isPlaying(); - // Pause playback while seeking - if (isPlaying) { - player.pause('ui'); - } - }); - this.onSeekPreview.subscribe(function (sender, args) { - // Notify UI manager of seek preview - uimanager.onSeekPreview.dispatch(sender, args); - }); - this.onSeekPreview.subscribeRateLimited(function (sender, args) { - // Rate-limited scrubbing seek - if (args.scrubbing) { - seek(args.position); - } - }, 200); - this.onSeeked.subscribe(function (sender, percentage) { - isSeeking = false; - // Do the seek - seek(percentage); - // Continue playback after seek if player was playing when seek started - if (isPlaying) { - player.play('ui'); - } - // Notify UI manager of finished seek - uimanager.onSeeked.dispatch(sender); - }); - if (this.hasLabel()) { - // Configure a seekbar label that is internal to the seekbar) - this.getLabel().configure(player, uimanager); - } - // Hide seekbar for live sources without timeshift - var isLive = false; - var hasTimeShift = false; - var switchVisibility = function (isLive, hasTimeShift) { - if (isLive && !hasTimeShift) { - _this.hide(); - } - else { - _this.show(); - } - playbackPositionHandler(null, true); - _this.refreshPlaybackPosition(); - }; - var liveStreamDetector = new playerutils_1.PlayerUtils.LiveStreamDetector(player); - liveStreamDetector.onLiveChanged.subscribe(function (sender, args) { - isLive = args.live; - switchVisibility(isLive, hasTimeShift); - }); - var timeShiftDetector = new playerutils_1.PlayerUtils.TimeShiftAvailabilityDetector(player); - timeShiftDetector.onTimeShiftAvailabilityChanged.subscribe(function (sender, args) { - hasTimeShift = args.timeShiftAvailable; - switchVisibility(isLive, hasTimeShift); - }); - // Initial detection - liveStreamDetector.detect(); - timeShiftDetector.detect(); - // Refresh the playback position when the player resized or the UI is configured. The playback position marker - // is positioned absolutely and must therefore be updated when the size of the seekbar changes. - player.addEventHandler(player.EVENT.ON_PLAYER_RESIZE, function () { - _this.refreshPlaybackPosition(); - }); - // Additionally, when this code is called, the seekbar is not part of the UI yet and therefore does not have a size, - // resulting in a wrong initial position of the marker. Refreshing it once the UI is configured solved this issue. - uimanager.onConfigured.subscribe(function () { - _this.refreshPlaybackPosition(); - }); - // It can also happen that the value changes once the player is ready, or when a new source is loaded, so we need - // to update on ON_READY too - player.addEventHandler(player.EVENT.ON_READY, function () { - _this.refreshPlaybackPosition(); - }); - // Initialize seekbar - playbackPositionHandler(); // Set the playback position - this.setBufferPosition(0); - this.setSeekPosition(0); - if (this.config.smoothPlaybackPositionUpdateIntervalMs !== SeekBar.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED) { - this.configureSmoothPlaybackPositionUpdater(player, uimanager); - } - this.configureMarkers(player, uimanager); - }; - SeekBar.prototype.configureSmoothPlaybackPositionUpdater = function (player, uimanager) { - var _this = this; - /* - * Playback position update - * - * We do not update the position directly from the ON_TIME_CHANGED event, because it arrives very jittery and - * results in a jittery position indicator since the CSS transition time is statically set. - * To work around this issue, we maintain a local playback position that is updated in a stable regular interval - * and kept in sync with the player. - */ - var currentTimeSeekBar = 0; - var currentTimePlayer = 0; - var updateIntervalMs = 50; - var currentTimeUpdateDeltaSecs = updateIntervalMs / 1000; - this.smoothPlaybackPositionUpdater = new timeout_1.Timeout(updateIntervalMs, function () { - currentTimeSeekBar += currentTimeUpdateDeltaSecs; - currentTimePlayer = player.getCurrentTime(); - // Sync currentTime of seekbar to player - var currentTimeDelta = currentTimeSeekBar - currentTimePlayer; - // If the delta is larger that 2 secs, directly jump the seekbar to the - // player time instead of smoothly fast forwarding/rewinding. - if (Math.abs(currentTimeDelta) > 2) { - currentTimeSeekBar = currentTimePlayer; - } - else if (currentTimeDelta <= -currentTimeUpdateDeltaSecs) { - currentTimeSeekBar += currentTimeUpdateDeltaSecs; - } - else if (currentTimeDelta >= currentTimeUpdateDeltaSecs) { - currentTimeSeekBar -= currentTimeUpdateDeltaSecs; - } - var playbackPositionPercentage = 100 / player.getDuration() * currentTimeSeekBar; - _this.setPlaybackPosition(playbackPositionPercentage); - }, true); - var startSmoothPlaybackPositionUpdater = function () { - if (!player.isLive()) { - currentTimeSeekBar = player.getCurrentTime(); - _this.smoothPlaybackPositionUpdater.start(); - } - }; - var stopSmoothPlaybackPositionUpdater = function () { - _this.smoothPlaybackPositionUpdater.clear(); - }; - player.addEventHandler(player.EVENT.ON_PLAY, startSmoothPlaybackPositionUpdater); - player.addEventHandler(player.EVENT.ON_CAST_PLAYING, startSmoothPlaybackPositionUpdater); - player.addEventHandler(player.EVENT.ON_PAUSED, stopSmoothPlaybackPositionUpdater); - player.addEventHandler(player.EVENT.ON_CAST_PAUSED, stopSmoothPlaybackPositionUpdater); - player.addEventHandler(player.EVENT.ON_SEEKED, function () { - currentTimeSeekBar = player.getCurrentTime(); - }); - if (player.isPlaying()) { - startSmoothPlaybackPositionUpdater(); - } - }; - SeekBar.prototype.configureMarkers = function (player, uimanager) { - var _this = this; - var clearMarkers = function () { - _this.timelineMarkers = []; - _this.updateMarkers(); - }; - var setupMarkers = function () { - clearMarkers(); - var hasMarkersInUiConfig = uimanager.getConfig().metadata && uimanager.getConfig().metadata.markers - && uimanager.getConfig().metadata.markers.length > 0; - var hasMarkersInPlayerConfig = player.getConfig().source && player.getConfig().source.markers - && player.getConfig().source.markers.length > 0; - // Take markers from the UI config. If no markers defined, try to take them from the player's source config. - var markers = hasMarkersInUiConfig ? uimanager.getConfig().metadata.markers : - hasMarkersInPlayerConfig ? player.getConfig().source.markers : null; - // Generate timeline markers from the config if we have markers and if we have a duration - // The duration check is for buggy platforms where the duration is not available instantly (Chrome on Android 4.3) - if (markers && player.getDuration() !== Infinity) { - for (var _i = 0, markers_1 = markers; _i < markers_1.length; _i++) { - var marker = markers_1[_i]; - _this.timelineMarkers.push({ - time: 100 / player.getDuration() * marker.time, - title: marker.title, - }); - } - } - // Populate the timeline with the markers - _this.updateMarkers(); - }; - // Add markers when a source is loaded - player.addEventHandler(player.EVENT.ON_READY, setupMarkers); - // Remove markers when unloaded - player.addEventHandler(player.EVENT.ON_SOURCE_UNLOADED, clearMarkers); - // Init markers at startup - setupMarkers(); - }; - SeekBar.prototype.release = function () { - _super.prototype.release.call(this); - if (this.smoothPlaybackPositionUpdater) { - this.smoothPlaybackPositionUpdater.clear(); - } - }; - SeekBar.prototype.toDomElement = function () { - var _this = this; - if (this.config.vertical) { - this.config.cssClasses.push('vertical'); - } - var seekBarContainer = new dom_1.DOM('div', { - 'id': this.config.id, - 'class': this.getCssClasses(), - }); - var seekBar = new dom_1.DOM('div', { - 'class': this.prefixCss('seekbar'), - }); - this.seekBar = seekBar; - // Indicator that shows the buffer fill level - var seekBarBufferLevel = new dom_1.DOM('div', { - 'class': this.prefixCss('seekbar-bufferlevel'), - }); - this.seekBarBufferPosition = seekBarBufferLevel; - // Indicator that shows the current playback position - var seekBarPlaybackPosition = new dom_1.DOM('div', { - 'class': this.prefixCss('seekbar-playbackposition'), - }); - this.seekBarPlaybackPosition = seekBarPlaybackPosition; - // A marker of the current playback position, e.g. a dot or line - var seekBarPlaybackPositionMarker = new dom_1.DOM('div', { - 'class': this.prefixCss('seekbar-playbackposition-marker'), - }); - this.seekBarPlaybackPositionMarker = seekBarPlaybackPositionMarker; - // Indicator that show where a seek will go to - var seekBarSeekPosition = new dom_1.DOM('div', { - 'class': this.prefixCss('seekbar-seekposition'), - }); - this.seekBarSeekPosition = seekBarSeekPosition; - // Indicator that shows the full seekbar - var seekBarBackdrop = new dom_1.DOM('div', { - 'class': this.prefixCss('seekbar-backdrop'), - }); - this.seekBarBackdrop = seekBarBackdrop; - var seekBarChapterMarkersContainer = new dom_1.DOM('div', { - 'class': this.prefixCss('seekbar-markers'), - }); - this.seekBarMarkersContainer = seekBarChapterMarkersContainer; - seekBar.append(seekBarBackdrop, seekBarBufferLevel, seekBarSeekPosition, seekBarPlaybackPosition, seekBarChapterMarkersContainer, seekBarPlaybackPositionMarker); - var seeking = false; - // Define handler functions so we can attach/remove them later - var mouseTouchMoveHandler = function (e) { - e.preventDefault(); - // Avoid propagation to VR handler - e.stopPropagation(); - var targetPercentage = 100 * _this.getOffset(e); - _this.setSeekPosition(targetPercentage); - _this.setPlaybackPosition(targetPercentage); - _this.onSeekPreviewEvent(targetPercentage, true); - }; - var mouseTouchUpHandler = function (e) { - e.preventDefault(); - // Remove handlers, seek operation is finished - new dom_1.DOM(document).off('touchmove mousemove', mouseTouchMoveHandler); - new dom_1.DOM(document).off('touchend mouseup', mouseTouchUpHandler); - var targetPercentage = 100 * _this.getOffset(e); - var snappedChapter = _this.getMarkerAtPosition(targetPercentage); - _this.setSeeking(false); - seeking = false; - // Fire seeked event - _this.onSeekedEvent(snappedChapter ? snappedChapter.time : targetPercentage); - }; - // A seek always start with a touchstart or mousedown directly on the seekbar. - // To track a mouse seek also outside the seekbar (for touch events this works automatically), - // so the user does not need to take care that the mouse always stays on the seekbar, we attach the mousemove - // and mouseup handlers to the whole document. A seek is triggered when the user lifts the mouse key. - // A seek mouse gesture is thus basically a click with a long time frame between down and up events. - seekBar.on('touchstart mousedown', function (e) { - var isTouchEvent = _this.touchSupported && e instanceof TouchEvent; - // Prevent selection of DOM elements (also prevents mousedown if current event is touchstart) - e.preventDefault(); - // Avoid propagation to VR handler - e.stopPropagation(); - _this.setSeeking(true); // Set seeking class on DOM element - seeking = true; // Set seek tracking flag - // Fire seeked event - _this.onSeekEvent(); - // Add handler to track the seek operation over the whole document - new dom_1.DOM(document).on(isTouchEvent ? 'touchmove' : 'mousemove', mouseTouchMoveHandler); - new dom_1.DOM(document).on(isTouchEvent ? 'touchend' : 'mouseup', mouseTouchUpHandler); - }); - // Display seek target indicator when mouse hovers or finger slides over seekbar - seekBar.on('touchmove mousemove', function (e) { - e.preventDefault(); - if (seeking) { - // During a seek (when mouse is down or touch move active), we need to stop propagation to avoid - // the VR viewport reacting to the moves. - e.stopPropagation(); - // Because the stopped propagation inhibits the event on the document, we need to call it from here - mouseTouchMoveHandler(e); - } - var position = 100 * _this.getOffset(e); - _this.setSeekPosition(position); - _this.onSeekPreviewEvent(position, false); - if (_this.hasLabel() && _this.getLabel().isHidden()) { - _this.getLabel().show(); - } - }); - // Hide seek target indicator when mouse or finger leaves seekbar - seekBar.on('touchend mouseleave', function (e) { - e.preventDefault(); - _this.setSeekPosition(0); - if (_this.hasLabel()) { - _this.getLabel().hide(); - } - }); - seekBarContainer.append(seekBar); - if (this.label) { - seekBarContainer.append(this.label.getDomElement()); - } - return seekBarContainer; - }; - SeekBar.prototype.updateMarkers = function () { - this.seekBarMarkersContainer.empty(); - for (var _i = 0, _a = this.timelineMarkers; _i < _a.length; _i++) { - var marker = _a[_i]; - this.seekBarMarkersContainer.append(new dom_1.DOM('div', { - 'class': this.prefixCss('seekbar-marker'), - 'data-marker-time': String(marker.time), - 'data-marker-title': String(marker.title), - }).css({ - 'width': marker.time + '%', - })); - } - }; - SeekBar.prototype.getMarkerAtPosition = function (percentage) { - var snappedMarker = null; - var snappingRange = 1; - if (this.timelineMarkers.length > 0) { - for (var _i = 0, _a = this.timelineMarkers; _i < _a.length; _i++) { - var marker = _a[_i]; - if (percentage >= marker.time - snappingRange && percentage <= marker.time + snappingRange) { - snappedMarker = marker; - break; - } - } - } - return snappedMarker; - }; - /** - * Gets the horizontal offset of a mouse/touch event point from the left edge of the seek bar. - * @param eventPageX the pageX coordinate of an event to calculate the offset from - * @returns {number} a number in the range of [0, 1], where 0 is the left edge and 1 is the right edge - */ - SeekBar.prototype.getHorizontalOffset = function (eventPageX) { - var elementOffsetPx = this.seekBar.offset().left; - var widthPx = this.seekBar.width(); - var offsetPx = eventPageX - elementOffsetPx; - var offset = 1 / widthPx * offsetPx; - return this.sanitizeOffset(offset); - }; - /** - * Gets the vertical offset of a mouse/touch event point from the bottom edge of the seek bar. - * @param eventPageY the pageX coordinate of an event to calculate the offset from - * @returns {number} a number in the range of [0, 1], where 0 is the bottom edge and 1 is the top edge - */ - SeekBar.prototype.getVerticalOffset = function (eventPageY) { - var elementOffsetPx = this.seekBar.offset().top; - var widthPx = this.seekBar.height(); - var offsetPx = eventPageY - elementOffsetPx; - var offset = 1 / widthPx * offsetPx; - return 1 - this.sanitizeOffset(offset); - }; - /** - * Gets the mouse or touch event offset for the current configuration (horizontal or vertical). - * @param e the event to calculate the offset from - * @returns {number} a number in the range of [0, 1] - * @see #getHorizontalOffset - * @see #getVerticalOffset - */ - SeekBar.prototype.getOffset = function (e) { - if (this.touchSupported && e instanceof TouchEvent) { - if (this.config.vertical) { - return this.getVerticalOffset(e.type === 'touchend' ? e.changedTouches[0].pageY : e.touches[0].pageY); - } - else { - return this.getHorizontalOffset(e.type === 'touchend' ? e.changedTouches[0].pageX : e.touches[0].pageX); - } - } - else if (e instanceof MouseEvent) { - if (this.config.vertical) { - return this.getVerticalOffset(e.pageY); - } - else { - return this.getHorizontalOffset(e.pageX); - } - } - else { - if (console) { - console.warn('invalid event'); - } - return 0; - } - }; - /** - * Sanitizes the mouse offset to the range of [0, 1]. - * - * When tracking the mouse outside the seek bar, the offset can be outside the desired range and this method - * limits it to the desired range. E.g. a mouse event left of the left edge of a seek bar yields an offset below - * zero, but to display the seek target on the seek bar, we need to limit it to zero. - * - * @param offset the offset to sanitize - * @returns {number} the sanitized offset. - */ - SeekBar.prototype.sanitizeOffset = function (offset) { - // Since we track mouse moves over the whole document, the target can be outside the seek range, - // and we need to limit it to the [0, 1] range. - if (offset < 0) { - offset = 0; - } - else if (offset > 1) { - offset = 1; - } - return offset; - }; - /** - * Sets the position of the playback position indicator. - * @param percent a number between 0 and 100 as returned by the player - */ - SeekBar.prototype.setPlaybackPosition = function (percent) { - this.playbackPositionPercentage = percent; - // Set position of the bar - this.setPosition(this.seekBarPlaybackPosition, percent); - // Set position of the marker - var totalSize = (this.config.vertical ? (this.seekBar.height() - this.seekBarPlaybackPositionMarker.height()) : this.seekBar.width()); - var px = (totalSize) / 100 * percent; - if (this.config.vertical) { - px = this.seekBar.height() - px - this.seekBarPlaybackPositionMarker.height(); - } - var style = this.config.vertical ? - // -ms-transform required for IE9 - { 'transform': 'translateY(' + px + 'px)', '-ms-transform': 'translateY(' + px + 'px)' } : - { 'transform': 'translateX(' + px + 'px)', '-ms-transform': 'translateX(' + px + 'px)' }; - this.seekBarPlaybackPositionMarker.css(style); - }; - /** - * Refreshes the playback position. Can be used by subclasses to refresh the position when - * the size of the component changes. - */ - SeekBar.prototype.refreshPlaybackPosition = function () { - this.setPlaybackPosition(this.playbackPositionPercentage); - }; - /** - * Sets the position until which media is buffered. - * @param percent a number between 0 and 100 - */ - SeekBar.prototype.setBufferPosition = function (percent) { - this.setPosition(this.seekBarBufferPosition, percent); - }; - /** - * Sets the position where a seek, if executed, would jump to. - * @param percent a number between 0 and 100 - */ - SeekBar.prototype.setSeekPosition = function (percent) { - this.setPosition(this.seekBarSeekPosition, percent); - }; - /** - * Set the actual position (width or height) of a DOM element that represent a bar in the seek bar. - * @param element the element to set the position for - * @param percent a number between 0 and 100 - */ - SeekBar.prototype.setPosition = function (element, percent) { - var scale = percent / 100; - var style = this.config.vertical ? - // -ms-transform required for IE9 - { 'transform': 'scaleY(' + scale + ')', '-ms-transform': 'scaleY(' + scale + ')' } : - { 'transform': 'scaleX(' + scale + ')', '-ms-transform': 'scaleX(' + scale + ')' }; - element.css(style); - }; - /** - * Puts the seek bar into or out of seeking state by adding/removing a class to the DOM element. This can be used - * to adjust the styling while seeking. - * - * @param seeking should be true when entering seek state, false when exiting the seek state - */ - SeekBar.prototype.setSeeking = function (seeking) { - if (seeking) { - this.getDomElement().addClass(this.prefixCss(SeekBar.CLASS_SEEKING)); - } - else { - this.getDomElement().removeClass(this.prefixCss(SeekBar.CLASS_SEEKING)); - } - }; - /** - * Checks if the seek bar is currently in the seek state. - * @returns {boolean} true if in seek state, else false - */ - SeekBar.prototype.isSeeking = function () { - return this.getDomElement().hasClass(this.prefixCss(SeekBar.CLASS_SEEKING)); - }; - /** - * Checks if the seek bar has a {@link SeekBarLabel}. - * @returns {boolean} true if the seek bar has a label, else false - */ - SeekBar.prototype.hasLabel = function () { - return this.label != null; - }; - /** - * Gets the label of this seek bar. - * @returns {SeekBarLabel} the label if this seek bar has a label, else null - */ - SeekBar.prototype.getLabel = function () { - return this.label; - }; - SeekBar.prototype.onSeekEvent = function () { - this.seekBarEvents.onSeek.dispatch(this); - }; - SeekBar.prototype.onSeekPreviewEvent = function (percentage, scrubbing) { - var snappedMarker = this.getMarkerAtPosition(percentage); - if (this.label) { - this.label.getDomElement().css({ - 'left': (snappedMarker ? snappedMarker.time : percentage) + '%', - }); - } - this.seekBarEvents.onSeekPreview.dispatch(this, { - scrubbing: scrubbing, - position: percentage, - marker: snappedMarker, - }); - }; - SeekBar.prototype.onSeekedEvent = function (percentage) { - this.seekBarEvents.onSeeked.dispatch(this, percentage); - }; - Object.defineProperty(SeekBar.prototype, "onSeek", { - /** - * Gets the event that is fired when a scrubbing seek operation is started. - * @returns {Event} - */ - get: function () { - return this.seekBarEvents.onSeek.getEvent(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(SeekBar.prototype, "onSeekPreview", { - /** - * Gets the event that is fired during a scrubbing seek (to indicate that the seek preview, i.e. the video frame, - * should be updated), or during a normal seek preview when the seek bar is hovered (and the seek target, - * i.e. the seek bar label, should be updated). - * @returns {Event} - */ - get: function () { - return this.seekBarEvents.onSeekPreview.getEvent(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(SeekBar.prototype, "onSeeked", { - /** - * Gets the event that is fired when a scrubbing seek has finished or when a direct seek is issued. - * @returns {Event} - */ - get: function () { - return this.seekBarEvents.onSeeked.getEvent(); - }, - enumerable: true, - configurable: true - }); - SeekBar.prototype.onShowEvent = function () { - _super.prototype.onShowEvent.call(this); - // Refresh the position of the playback position when the seek bar becomes visible. To correctly set the position, - // the DOM element must be fully initialized an have its size calculated, because the position is set as an absolute - // value calculated from the size. This required size is not known when it is hidden. - // For such cases, we refresh the position here in onShow because here it is guaranteed that the component knows - // its size and can set the position correctly. - this.refreshPlaybackPosition(); - }; - return SeekBar; -}(component_1.Component)); -SeekBar.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED = -1; -/** - * The CSS class that is added to the DOM element while the seek bar is in 'seeking' state. - */ -SeekBar.CLASS_SEEKING = 'seeking'; -exports.SeekBar = SeekBar; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var component_1 = __webpack_require__(2); +var dom_1 = __webpack_require__(0); +var eventdispatcher_1 = __webpack_require__(3); +var timeout_1 = __webpack_require__(10); +var playerutils_1 = __webpack_require__(5); +/** + * A seek bar to seek within the player's media. It displays the current playback position, amount of buffed data, seek + * target, and keeps status about an ongoing seek. + * + * The seek bar displays different 'bars': + * - the playback position, i.e. the position in the media at which the player current playback pointer is positioned + * - the buffer position, which usually is the playback position plus the time span that is already buffered ahead + * - the seek position, used to preview to where in the timeline a seek will jump to + */ +var SeekBar = (function (_super) { + __extends(SeekBar, _super); + function SeekBar(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + /** + * Buffer of the the current playback position. The position must be buffered in case the element + * needs to be refreshed with {@link #refreshPlaybackPosition}. + * @type {number} + */ + _this.playbackPositionPercentage = 0; + // https://hacks.mozilla.org/2013/04/detecting-touch-its-the-why-not-the-how/ + _this.touchSupported = ('ontouchstart' in window); + _this.seekBarEvents = { + /** + * Fired when a scrubbing seek operation is started. + */ + onSeek: new eventdispatcher_1.EventDispatcher(), + /** + * Fired during a scrubbing seek to indicate that the seek preview (i.e. the video frame) should be updated. + */ + onSeekPreview: new eventdispatcher_1.EventDispatcher(), + /** + * Fired when a scrubbing seek has finished or when a direct seek is issued. + */ + onSeeked: new eventdispatcher_1.EventDispatcher(), + }; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-seekbar', + vertical: false, + smoothPlaybackPositionUpdateIntervalMs: 50, + hideInLivePlayback: true, + }, _this.config); + _this.label = _this.config.label; + _this.timelineMarkers = []; + return _this; + } + SeekBar.prototype.initialize = function () { + _super.prototype.initialize.call(this); + if (this.hasLabel()) { + this.getLabel().initialize(); + } + }; + SeekBar.prototype.configure = function (player, uimanager, configureSeek) { + var _this = this; + if (configureSeek === void 0) { configureSeek = true; } + _super.prototype.configure.call(this, player, uimanager); + // let config = this.getConfig(); + if (!configureSeek) { + // The configureSeek flag can be used by subclasses to disable configuration as seek bar. E.g. the volume + // slider is reusing this component but adds its own functionality, and does not need the seek functionality. + // This is actually a hack, the proper solution would be for both seek bar and volume sliders to extend + // a common base slider component and implement their functionality there. + return; + } + var playbackNotInitialized = true; + var isPlaying = false; + var isSeeking = false; + // Update playback and buffer positions + var playbackPositionHandler = function (event, forceUpdate) { + if (event === void 0) { event = null; } + if (forceUpdate === void 0) { forceUpdate = false; } + // Once this handler os called, playback has been started and we set the flag to false + playbackNotInitialized = false; + if (isSeeking) { + // We caught a seek preview seek, do not update the seekbar + return; + } + if (player.isLive()) { + if (player.getMaxTimeShift() === 0) { + // This case must be explicitly handled to avoid division by zero + _this.setPlaybackPosition(100); + } + else { + var playbackPositionPercentage = 100 - (100 / player.getMaxTimeShift() * player.getTimeShift()); + _this.setPlaybackPosition(playbackPositionPercentage); + } + // Always show full buffer for live streams + _this.setBufferPosition(100); + // Hide SeekBar if required. + // if (config.hideInLivePlayback) { + _this.hide(); + // } + } + else { + var playbackPositionPercentage = 100 / player.getDuration() * player.getCurrentTime(); + var videoBufferLength = player.getVideoBufferLength(); + var audioBufferLength = player.getAudioBufferLength(); + // Calculate the buffer length which is the smaller length of the audio and video buffers. If one of these + // buffers is not available, we set it's value to MAX_VALUE to make sure that the other real value is taken + // as the buffer length. + var bufferLength = Math.min(videoBufferLength != null ? videoBufferLength : Number.MAX_VALUE, audioBufferLength != null ? audioBufferLength : Number.MAX_VALUE); + // If both buffer lengths are missing, we set the buffer length to zero + if (bufferLength === Number.MAX_VALUE) { + bufferLength = 0; + } + var bufferPercentage = 100 / player.getDuration() * bufferLength; + // Update playback position only in paused state or in the initial startup state where player is neither + // paused nor playing. Playback updates are handled in the Timeout below. + if (_this.config.smoothPlaybackPositionUpdateIntervalMs === SeekBar.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED + || forceUpdate || player.isPaused() || (player.isPaused() === player.isPlaying())) { + _this.setPlaybackPosition(playbackPositionPercentage); + } + _this.setBufferPosition(playbackPositionPercentage + bufferPercentage); + } + }; + // Update seekbar upon these events + // init playback position when the player is ready + player.addEventHandler(player.EVENT.ON_READY, playbackPositionHandler); + // update playback position when it changes + player.addEventHandler(player.EVENT.ON_TIME_CHANGED, playbackPositionHandler); + // update bufferlevel when buffering is complete + player.addEventHandler(player.EVENT.ON_STALL_ENDED, playbackPositionHandler); + // update playback position when a seek has finished + player.addEventHandler(player.EVENT.ON_SEEKED, playbackPositionHandler); + // update playback position when a timeshift has finished + player.addEventHandler(player.EVENT.ON_TIME_SHIFTED, playbackPositionHandler); + // update bufferlevel when a segment has been downloaded + player.addEventHandler(player.EVENT.ON_SEGMENT_REQUEST_FINISHED, playbackPositionHandler); + // update playback position of Cast playback + player.addEventHandler(player.EVENT.ON_CAST_TIME_UPDATED, playbackPositionHandler); + // Seek handling + player.addEventHandler(player.EVENT.ON_SEEK, function () { + _this.setSeeking(true); + }); + player.addEventHandler(player.EVENT.ON_SEEKED, function () { + _this.setSeeking(false); + }); + player.addEventHandler(player.EVENT.ON_TIME_SHIFT, function () { + _this.setSeeking(true); + }); + player.addEventHandler(player.EVENT.ON_TIME_SHIFTED, function () { + _this.setSeeking(false); + }); + var seek = function (percentage) { + if (player.isLive()) { + player.timeShift(player.getMaxTimeShift() - (player.getMaxTimeShift() * (percentage / 100)), 'ui'); + } + else { + player.seek(player.getDuration() * (percentage / 100), 'ui'); + } + }; + this.onSeek.subscribe(function (sender) { + isSeeking = true; // track seeking status so we can catch events from seek preview seeks + // Notify UI manager of started seek + uimanager.onSeek.dispatch(sender); + // Save current playback state + isPlaying = player.isPlaying(); + // Pause playback while seeking + if (isPlaying) { + player.pause('ui'); + } + }); + this.onSeekPreview.subscribe(function (sender, args) { + // Notify UI manager of seek preview + uimanager.onSeekPreview.dispatch(sender, args); + }); + this.onSeekPreview.subscribeRateLimited(function (sender, args) { + // Rate-limited scrubbing seek + if (args.scrubbing) { + seek(args.position); + } + }, 200); + this.onSeeked.subscribe(function (sender, percentage) { + isSeeking = false; + // Do the seek + seek(percentage); + // Continue playback after seek if player was playing when seek started + if (isPlaying) { + player.play('ui'); + } + // Notify UI manager of finished seek + uimanager.onSeeked.dispatch(sender); + }); + if (this.hasLabel()) { + // Configure a seekbar label that is internal to the seekbar) + this.getLabel().configure(player, uimanager); + } + // Hide seekbar for live sources without timeshift + var isLive = false; + var hasTimeShift = false; + var switchVisibility = function (isLive, hasTimeShift) { + if (isLive && !hasTimeShift) { + _this.hide(); + } + else { + _this.show(); + } + playbackPositionHandler(null, true); + _this.refreshPlaybackPosition(); + }; + var liveStreamDetector = new playerutils_1.PlayerUtils.LiveStreamDetector(player); + liveStreamDetector.onLiveChanged.subscribe(function (sender, args) { + isLive = args.live; + switchVisibility(isLive, hasTimeShift); + }); + var timeShiftDetector = new playerutils_1.PlayerUtils.TimeShiftAvailabilityDetector(player); + timeShiftDetector.onTimeShiftAvailabilityChanged.subscribe(function (sender, args) { + hasTimeShift = args.timeShiftAvailable; + switchVisibility(isLive, hasTimeShift); + }); + // Initial detection + liveStreamDetector.detect(); + timeShiftDetector.detect(); + // Refresh the playback position when the player resized or the UI is configured. The playback position marker + // is positioned absolutely and must therefore be updated when the size of the seekbar changes. + player.addEventHandler(player.EVENT.ON_PLAYER_RESIZE, function () { + _this.refreshPlaybackPosition(); + }); + // Additionally, when this code is called, the seekbar is not part of the UI yet and therefore does not have a size, + // resulting in a wrong initial position of the marker. Refreshing it once the UI is configured solved this issue. + uimanager.onConfigured.subscribe(function () { + _this.refreshPlaybackPosition(); + }); + // It can also happen that the value changes once the player is ready, or when a new source is loaded, so we need + // to update on ON_READY too + player.addEventHandler(player.EVENT.ON_READY, function () { + _this.refreshPlaybackPosition(); + }); + // Initialize seekbar + playbackPositionHandler(); // Set the playback position + this.setBufferPosition(0); + this.setSeekPosition(0); + if (this.config.smoothPlaybackPositionUpdateIntervalMs !== SeekBar.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED) { + this.configureSmoothPlaybackPositionUpdater(player, uimanager); + } + this.configureMarkers(player, uimanager); + }; + SeekBar.prototype.configureSmoothPlaybackPositionUpdater = function (player, uimanager) { + var _this = this; + /* + * Playback position update + * + * We do not update the position directly from the ON_TIME_CHANGED event, because it arrives very jittery and + * results in a jittery position indicator since the CSS transition time is statically set. + * To work around this issue, we maintain a local playback position that is updated in a stable regular interval + * and kept in sync with the player. + */ + var currentTimeSeekBar = 0; + var currentTimePlayer = 0; + var updateIntervalMs = 50; + var currentTimeUpdateDeltaSecs = updateIntervalMs / 1000; + this.smoothPlaybackPositionUpdater = new timeout_1.Timeout(updateIntervalMs, function () { + currentTimeSeekBar += currentTimeUpdateDeltaSecs; + currentTimePlayer = player.getCurrentTime(); + // Sync currentTime of seekbar to player + var currentTimeDelta = currentTimeSeekBar - currentTimePlayer; + // If the delta is larger that 2 secs, directly jump the seekbar to the + // player time instead of smoothly fast forwarding/rewinding. + if (Math.abs(currentTimeDelta) > 2) { + currentTimeSeekBar = currentTimePlayer; + } + else if (currentTimeDelta <= -currentTimeUpdateDeltaSecs) { + currentTimeSeekBar += currentTimeUpdateDeltaSecs; + } + else if (currentTimeDelta >= currentTimeUpdateDeltaSecs) { + currentTimeSeekBar -= currentTimeUpdateDeltaSecs; + } + var playbackPositionPercentage = 100 / player.getDuration() * currentTimeSeekBar; + _this.setPlaybackPosition(playbackPositionPercentage); + }, true); + var startSmoothPlaybackPositionUpdater = function () { + if (!player.isLive()) { + currentTimeSeekBar = player.getCurrentTime(); + _this.smoothPlaybackPositionUpdater.start(); + } + }; + var stopSmoothPlaybackPositionUpdater = function () { + _this.smoothPlaybackPositionUpdater.clear(); + }; + player.addEventHandler(player.EVENT.ON_PLAY, startSmoothPlaybackPositionUpdater); + player.addEventHandler(player.EVENT.ON_CAST_PLAYING, startSmoothPlaybackPositionUpdater); + player.addEventHandler(player.EVENT.ON_PAUSED, stopSmoothPlaybackPositionUpdater); + player.addEventHandler(player.EVENT.ON_CAST_PAUSED, stopSmoothPlaybackPositionUpdater); + player.addEventHandler(player.EVENT.ON_SEEKED, function () { + currentTimeSeekBar = player.getCurrentTime(); + }); + if (player.isPlaying()) { + startSmoothPlaybackPositionUpdater(); + } + }; + SeekBar.prototype.configureMarkers = function (player, uimanager) { + var _this = this; + var clearMarkers = function () { + _this.timelineMarkers = []; + _this.updateMarkers(); + }; + var setupMarkers = function () { + clearMarkers(); + var hasMarkersInUiConfig = uimanager.getConfig().metadata && uimanager.getConfig().metadata.markers + && uimanager.getConfig().metadata.markers.length > 0; + var hasMarkersInPlayerConfig = player.getConfig().source && player.getConfig().source.markers + && player.getConfig().source.markers.length > 0; + // Take markers from the UI config. If no markers defined, try to take them from the player's source config. + var markers = hasMarkersInUiConfig ? uimanager.getConfig().metadata.markers : + hasMarkersInPlayerConfig ? player.getConfig().source.markers : null; + // Generate timeline markers from the config if we have markers and if we have a duration + // The duration check is for buggy platforms where the duration is not available instantly (Chrome on Android 4.3) + if (markers && player.getDuration() !== Infinity) { + for (var _i = 0, markers_1 = markers; _i < markers_1.length; _i++) { + var marker = markers_1[_i]; + _this.timelineMarkers.push({ + time: 100 / player.getDuration() * marker.time, + title: marker.title, + }); + } + } + // Populate the timeline with the markers + _this.updateMarkers(); + }; + // Add markers when a source is loaded + player.addEventHandler(player.EVENT.ON_READY, setupMarkers); + // Remove markers when unloaded + player.addEventHandler(player.EVENT.ON_SOURCE_UNLOADED, clearMarkers); + // Init markers at startup + setupMarkers(); + }; + SeekBar.prototype.release = function () { + _super.prototype.release.call(this); + if (this.smoothPlaybackPositionUpdater) { + this.smoothPlaybackPositionUpdater.clear(); + } + }; + SeekBar.prototype.toDomElement = function () { + var _this = this; + if (this.config.vertical) { + this.config.cssClasses.push('vertical'); + } + var seekBarContainer = new dom_1.DOM('div', { + 'id': this.config.id, + 'class': this.getCssClasses(), + }); + var seekBar = new dom_1.DOM('div', { + 'class': this.prefixCss('seekbar'), + }); + this.seekBar = seekBar; + // Indicator that shows the buffer fill level + var seekBarBufferLevel = new dom_1.DOM('div', { + 'class': this.prefixCss('seekbar-bufferlevel'), + }); + this.seekBarBufferPosition = seekBarBufferLevel; + // Indicator that shows the current playback position + var seekBarPlaybackPosition = new dom_1.DOM('div', { + 'class': this.prefixCss('seekbar-playbackposition'), + }); + this.seekBarPlaybackPosition = seekBarPlaybackPosition; + // A marker of the current playback position, e.g. a dot or line + var seekBarPlaybackPositionMarker = new dom_1.DOM('div', { + 'class': this.prefixCss('seekbar-playbackposition-marker'), + }); + this.seekBarPlaybackPositionMarker = seekBarPlaybackPositionMarker; + // Indicator that show where a seek will go to + var seekBarSeekPosition = new dom_1.DOM('div', { + 'class': this.prefixCss('seekbar-seekposition'), + }); + this.seekBarSeekPosition = seekBarSeekPosition; + // Indicator that shows the full seekbar + var seekBarBackdrop = new dom_1.DOM('div', { + 'class': this.prefixCss('seekbar-backdrop'), + }); + this.seekBarBackdrop = seekBarBackdrop; + var seekBarChapterMarkersContainer = new dom_1.DOM('div', { + 'class': this.prefixCss('seekbar-markers'), + }); + this.seekBarMarkersContainer = seekBarChapterMarkersContainer; + seekBar.append(seekBarBackdrop, seekBarBufferLevel, seekBarSeekPosition, seekBarPlaybackPosition, seekBarChapterMarkersContainer, seekBarPlaybackPositionMarker); + var seeking = false; + // Define handler functions so we can attach/remove them later + var mouseTouchMoveHandler = function (e) { + e.preventDefault(); + // Avoid propagation to VR handler + e.stopPropagation(); + var targetPercentage = 100 * _this.getOffset(e); + _this.setSeekPosition(targetPercentage); + _this.setPlaybackPosition(targetPercentage); + _this.onSeekPreviewEvent(targetPercentage, true); + }; + var mouseTouchUpHandler = function (e) { + e.preventDefault(); + // Remove handlers, seek operation is finished + new dom_1.DOM(document).off('touchmove mousemove', mouseTouchMoveHandler); + new dom_1.DOM(document).off('touchend mouseup', mouseTouchUpHandler); + var targetPercentage = 100 * _this.getOffset(e); + var snappedChapter = _this.getMarkerAtPosition(targetPercentage); + _this.setSeeking(false); + seeking = false; + // Fire seeked event + _this.onSeekedEvent(snappedChapter ? snappedChapter.time : targetPercentage); + }; + // A seek always start with a touchstart or mousedown directly on the seekbar. + // To track a mouse seek also outside the seekbar (for touch events this works automatically), + // so the user does not need to take care that the mouse always stays on the seekbar, we attach the mousemove + // and mouseup handlers to the whole document. A seek is triggered when the user lifts the mouse key. + // A seek mouse gesture is thus basically a click with a long time frame between down and up events. + seekBar.on('touchstart mousedown', function (e) { + var isTouchEvent = _this.touchSupported && e instanceof TouchEvent; + // Prevent selection of DOM elements (also prevents mousedown if current event is touchstart) + e.preventDefault(); + // Avoid propagation to VR handler + e.stopPropagation(); + _this.setSeeking(true); // Set seeking class on DOM element + seeking = true; // Set seek tracking flag + // Fire seeked event + _this.onSeekEvent(); + // Add handler to track the seek operation over the whole document + new dom_1.DOM(document).on(isTouchEvent ? 'touchmove' : 'mousemove', mouseTouchMoveHandler); + new dom_1.DOM(document).on(isTouchEvent ? 'touchend' : 'mouseup', mouseTouchUpHandler); + }); + // Display seek target indicator when mouse hovers or finger slides over seekbar + seekBar.on('touchmove mousemove', function (e) { + e.preventDefault(); + if (seeking) { + // During a seek (when mouse is down or touch move active), we need to stop propagation to avoid + // the VR viewport reacting to the moves. + e.stopPropagation(); + // Because the stopped propagation inhibits the event on the document, we need to call it from here + mouseTouchMoveHandler(e); + } + var position = 100 * _this.getOffset(e); + _this.setSeekPosition(position); + _this.onSeekPreviewEvent(position, false); + if (_this.hasLabel() && _this.getLabel().isHidden()) { + _this.getLabel().show(); + } + }); + // Hide seek target indicator when mouse or finger leaves seekbar + seekBar.on('touchend mouseleave', function (e) { + e.preventDefault(); + _this.setSeekPosition(0); + if (_this.hasLabel()) { + _this.getLabel().hide(); + } + }); + seekBarContainer.append(seekBar); + if (this.label) { + seekBarContainer.append(this.label.getDomElement()); + } + return seekBarContainer; + }; + SeekBar.prototype.updateMarkers = function () { + this.seekBarMarkersContainer.empty(); + for (var _i = 0, _a = this.timelineMarkers; _i < _a.length; _i++) { + var marker = _a[_i]; + this.seekBarMarkersContainer.append(new dom_1.DOM('div', { + 'class': this.prefixCss('seekbar-marker'), + 'data-marker-time': String(marker.time), + 'data-marker-title': String(marker.title), + }).css({ + 'width': marker.time + '%', + })); + } + }; + SeekBar.prototype.getMarkerAtPosition = function (percentage) { + var snappedMarker = null; + var snappingRange = 1; + if (this.timelineMarkers.length > 0) { + for (var _i = 0, _a = this.timelineMarkers; _i < _a.length; _i++) { + var marker = _a[_i]; + if (percentage >= marker.time - snappingRange && percentage <= marker.time + snappingRange) { + snappedMarker = marker; + break; + } + } + } + return snappedMarker; + }; + /** + * Gets the horizontal offset of a mouse/touch event point from the left edge of the seek bar. + * @param eventPageX the pageX coordinate of an event to calculate the offset from + * @returns {number} a number in the range of [0, 1], where 0 is the left edge and 1 is the right edge + */ + SeekBar.prototype.getHorizontalOffset = function (eventPageX) { + var elementOffsetPx = this.seekBar.offset().left; + var widthPx = this.seekBar.width(); + var offsetPx = eventPageX - elementOffsetPx; + var offset = 1 / widthPx * offsetPx; + return this.sanitizeOffset(offset); + }; + /** + * Gets the vertical offset of a mouse/touch event point from the bottom edge of the seek bar. + * @param eventPageY the pageX coordinate of an event to calculate the offset from + * @returns {number} a number in the range of [0, 1], where 0 is the bottom edge and 1 is the top edge + */ + SeekBar.prototype.getVerticalOffset = function (eventPageY) { + var elementOffsetPx = this.seekBar.offset().top; + var widthPx = this.seekBar.height(); + var offsetPx = eventPageY - elementOffsetPx; + var offset = 1 / widthPx * offsetPx; + return 1 - this.sanitizeOffset(offset); + }; + /** + * Gets the mouse or touch event offset for the current configuration (horizontal or vertical). + * @param e the event to calculate the offset from + * @returns {number} a number in the range of [0, 1] + * @see #getHorizontalOffset + * @see #getVerticalOffset + */ + SeekBar.prototype.getOffset = function (e) { + if (this.touchSupported && e instanceof TouchEvent) { + if (this.config.vertical) { + return this.getVerticalOffset(e.type === 'touchend' ? e.changedTouches[0].pageY : e.touches[0].pageY); + } + else { + return this.getHorizontalOffset(e.type === 'touchend' ? e.changedTouches[0].pageX : e.touches[0].pageX); + } + } + else if (e instanceof MouseEvent) { + if (this.config.vertical) { + return this.getVerticalOffset(e.pageY); + } + else { + return this.getHorizontalOffset(e.pageX); + } + } + else { + if (console) { + console.warn('invalid event'); + } + return 0; + } + }; + /** + * Sanitizes the mouse offset to the range of [0, 1]. + * + * When tracking the mouse outside the seek bar, the offset can be outside the desired range and this method + * limits it to the desired range. E.g. a mouse event left of the left edge of a seek bar yields an offset below + * zero, but to display the seek target on the seek bar, we need to limit it to zero. + * + * @param offset the offset to sanitize + * @returns {number} the sanitized offset. + */ + SeekBar.prototype.sanitizeOffset = function (offset) { + // Since we track mouse moves over the whole document, the target can be outside the seek range, + // and we need to limit it to the [0, 1] range. + if (offset < 0) { + offset = 0; + } + else if (offset > 1) { + offset = 1; + } + return offset; + }; + /** + * Sets the position of the playback position indicator. + * @param percent a number between 0 and 100 as returned by the player + */ + SeekBar.prototype.setPlaybackPosition = function (percent) { + this.playbackPositionPercentage = percent; + // Set position of the bar + this.setPosition(this.seekBarPlaybackPosition, percent); + // Set position of the marker + var totalSize = (this.config.vertical ? (this.seekBar.height() - this.seekBarPlaybackPositionMarker.height()) : this.seekBar.width()); + var px = (totalSize) / 100 * percent; + if (this.config.vertical) { + px = this.seekBar.height() - px - this.seekBarPlaybackPositionMarker.height(); + } + var style = this.config.vertical ? + // -ms-transform required for IE9 + { 'transform': 'translateY(' + px + 'px)', '-ms-transform': 'translateY(' + px + 'px)' } : + { 'transform': 'translateX(' + px + 'px)', '-ms-transform': 'translateX(' + px + 'px)' }; + this.seekBarPlaybackPositionMarker.css(style); + }; + /** + * Refreshes the playback position. Can be used by subclasses to refresh the position when + * the size of the component changes. + */ + SeekBar.prototype.refreshPlaybackPosition = function () { + this.setPlaybackPosition(this.playbackPositionPercentage); + }; + /** + * Sets the position until which media is buffered. + * @param percent a number between 0 and 100 + */ + SeekBar.prototype.setBufferPosition = function (percent) { + this.setPosition(this.seekBarBufferPosition, percent); + }; + /** + * Sets the position where a seek, if executed, would jump to. + * @param percent a number between 0 and 100 + */ + SeekBar.prototype.setSeekPosition = function (percent) { + this.setPosition(this.seekBarSeekPosition, percent); + }; + /** + * Set the actual position (width or height) of a DOM element that represent a bar in the seek bar. + * @param element the element to set the position for + * @param percent a number between 0 and 100 + */ + SeekBar.prototype.setPosition = function (element, percent) { + var scale = percent / 100; + var style = this.config.vertical ? + // -ms-transform required for IE9 + { 'transform': 'scaleY(' + scale + ')', '-ms-transform': 'scaleY(' + scale + ')' } : + { 'transform': 'scaleX(' + scale + ')', '-ms-transform': 'scaleX(' + scale + ')' }; + element.css(style); + }; + /** + * Puts the seek bar into or out of seeking state by adding/removing a class to the DOM element. This can be used + * to adjust the styling while seeking. + * + * @param seeking should be true when entering seek state, false when exiting the seek state + */ + SeekBar.prototype.setSeeking = function (seeking) { + if (seeking) { + this.getDomElement().addClass(this.prefixCss(SeekBar.CLASS_SEEKING)); + } + else { + this.getDomElement().removeClass(this.prefixCss(SeekBar.CLASS_SEEKING)); + } + }; + /** + * Checks if the seek bar is currently in the seek state. + * @returns {boolean} true if in seek state, else false + */ + SeekBar.prototype.isSeeking = function () { + return this.getDomElement().hasClass(this.prefixCss(SeekBar.CLASS_SEEKING)); + }; + /** + * Checks if the seek bar has a {@link SeekBarLabel}. + * @returns {boolean} true if the seek bar has a label, else false + */ + SeekBar.prototype.hasLabel = function () { + return this.label != null; + }; + /** + * Gets the label of this seek bar. + * @returns {SeekBarLabel} the label if this seek bar has a label, else null + */ + SeekBar.prototype.getLabel = function () { + return this.label; + }; + SeekBar.prototype.onSeekEvent = function () { + this.seekBarEvents.onSeek.dispatch(this); + }; + SeekBar.prototype.onSeekPreviewEvent = function (percentage, scrubbing) { + var snappedMarker = this.getMarkerAtPosition(percentage); + if (this.label) { + this.label.getDomElement().css({ + 'left': (snappedMarker ? snappedMarker.time : percentage) + '%', + }); + } + this.seekBarEvents.onSeekPreview.dispatch(this, { + scrubbing: scrubbing, + position: percentage, + marker: snappedMarker, + }); + }; + SeekBar.prototype.onSeekedEvent = function (percentage) { + this.seekBarEvents.onSeeked.dispatch(this, percentage); + }; + Object.defineProperty(SeekBar.prototype, "onSeek", { + /** + * Gets the event that is fired when a scrubbing seek operation is started. + * @returns {Event} + */ + get: function () { + return this.seekBarEvents.onSeek.getEvent(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SeekBar.prototype, "onSeekPreview", { + /** + * Gets the event that is fired during a scrubbing seek (to indicate that the seek preview, i.e. the video frame, + * should be updated), or during a normal seek preview when the seek bar is hovered (and the seek target, + * i.e. the seek bar label, should be updated). + * @returns {Event} + */ + get: function () { + return this.seekBarEvents.onSeekPreview.getEvent(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(SeekBar.prototype, "onSeeked", { + /** + * Gets the event that is fired when a scrubbing seek has finished or when a direct seek is issued. + * @returns {Event} + */ + get: function () { + return this.seekBarEvents.onSeeked.getEvent(); + }, + enumerable: true, + configurable: true + }); + SeekBar.prototype.onShowEvent = function () { + _super.prototype.onShowEvent.call(this); + // Refresh the position of the playback position when the seek bar becomes visible. To correctly set the position, + // the DOM element must be fully initialized an have its size calculated, because the position is set as an absolute + // value calculated from the size. This required size is not known when it is hidden. + // For such cases, we refresh the position here in onShow because here it is guaranteed that the component knows + // its size and can set the position correctly. + this.refreshPlaybackPosition(); + }; + return SeekBar; +}(component_1.Component)); +SeekBar.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED = -1; +/** + * The CSS class that is added to the DOM element while the seek bar is in 'seeking' state. + */ +SeekBar.CLASS_SEEKING = 'seeking'; +exports.SeekBar = SeekBar; /***/ }), @@ -2547,152 +2547,152 @@ exports.SeekBar = SeekBar; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var StringUtils; -(function (StringUtils) { - StringUtils.FORMAT_HHMMSS = 'hh:mm:ss'; - StringUtils.FORMAT_MMSS = 'mm:ss'; - /** - * Formats a number of seconds into a time string with the pattern hh:mm:ss. - * - * @param totalSeconds the total number of seconds to format to string - * @param format the time format to output (default: hh:mm:ss) - * @returns {string} the formatted time string - */ - function secondsToTime(totalSeconds, format) { - if (format === void 0) { format = StringUtils.FORMAT_HHMMSS; } - var isNegative = totalSeconds < 0; - if (isNegative) { - // If the time is negative, we make it positive for the calculation below - // (else we'd get all negative numbers) and reattach the negative sign later. - totalSeconds = -totalSeconds; - } - // Split into separate time parts - var hours = Math.floor(totalSeconds / 3600); - var minutes = Math.floor(totalSeconds / 60) - hours * 60; - var seconds = Math.floor(totalSeconds) % 60; - return (isNegative ? '-' : '') + format - .replace('hh', leftPadWithZeros(hours, 2)) - .replace('mm', leftPadWithZeros(minutes, 2)) - .replace('ss', leftPadWithZeros(seconds, 2)); - } - StringUtils.secondsToTime = secondsToTime; - /** - * Converts a number to a string and left-pads it with zeros to the specified length. - * Example: leftPadWithZeros(123, 5) => '00123' - * - * @param num the number to convert to string and pad with zeros - * @param length the desired length of the padded string - * @returns {string} the padded number as string - */ - function leftPadWithZeros(num, length) { - var text = num + ''; - var padding = '0000000000'.substr(0, length - text.length); - return padding + text; - } - /** - * Fills out placeholders in an ad message. - * - * Has the placeholders '{remainingTime[formatString]}', '{playedTime[formatString]}' and - * '{adDuration[formatString]}', which are replaced by the remaining time until the ad can be skipped, the current - * time or the ad duration. The format string is optional. If not specified, the placeholder is replaced by the time - * in seconds. If specified, it must be of the following format: - * - %d - Inserts the time as an integer. - * - %0Nd - Inserts the time as an integer with leading zeroes, if the length of the time string is smaller than N. - * - %f - Inserts the time as a float. - * - %0Nf - Inserts the time as a float with leading zeroes. - * - %.Mf - Inserts the time as a float with M decimal places. Can be combined with %0Nf, e.g. %04.2f (the time - * 10.123 - * would be printed as 0010.12). - * - %hh:mm:ss - * - %mm:ss - * - * @param adMessage an ad message with optional placeholders to fill - * @param skipOffset if specified, {remainingTime} will be filled with the remaining time until the ad can be skipped - * @param player the player to get the time data from - * @returns {string} the ad message with filled placeholders - */ - function replaceAdMessagePlaceholders(adMessage, skipOffset, player) { - var adMessagePlaceholderRegex = new RegExp('\\{(remainingTime|playedTime|adDuration)(}|%((0[1-9]\\d*(\\.\\d+(d|f)|d|f)|\\.\\d+f|d|f)|hh:mm:ss|mm:ss)})', 'g'); - return adMessage.replace(adMessagePlaceholderRegex, function (formatString) { - var time = 0; - if (formatString.indexOf('remainingTime') > -1) { - if (skipOffset) { - time = Math.ceil(skipOffset - player.getCurrentTime()); - } - else { - time = player.getDuration() - player.getCurrentTime(); - } - } - else if (formatString.indexOf('playedTime') > -1) { - time = player.getCurrentTime(); - } - else if (formatString.indexOf('adDuration') > -1) { - time = player.getDuration(); - } - return formatNumber(time, formatString); - }); - } - StringUtils.replaceAdMessagePlaceholders = replaceAdMessagePlaceholders; - function formatNumber(time, format) { - var formatStringValidationRegex = /%((0[1-9]\d*(\.\d+(d|f)|d|f)|\.\d+f|d|f)|hh:mm:ss|mm:ss)/; - var leadingZeroesRegex = /(%0[1-9]\d*)(?=(\.\d+f|f|d))/; - var decimalPlacesRegex = /\.\d*(?=f)/; - if (!formatStringValidationRegex.test(format)) { - // If the format is invalid, we set a default fallback format - format = '%d'; - } - // Determine the number of leading zeros - var leadingZeroes = 0; - var leadingZeroesMatches = format.match(leadingZeroesRegex); - if (leadingZeroesMatches) { - leadingZeroes = parseInt(leadingZeroesMatches[0].substring(2)); - } - // Determine the number of decimal places - var numDecimalPlaces = null; - var decimalPlacesMatches = format.match(decimalPlacesRegex); - if (decimalPlacesMatches && !isNaN(parseInt(decimalPlacesMatches[0].substring(1)))) { - numDecimalPlaces = parseInt(decimalPlacesMatches[0].substring(1)); - if (numDecimalPlaces > 20) { - numDecimalPlaces = 20; - } - } - // Float format - if (format.indexOf('f') > -1) { - var timeString = ''; - if (numDecimalPlaces !== null) { - // Apply fixed number of decimal places - timeString = time.toFixed(numDecimalPlaces); - } - else { - timeString = '' + time; - } - // Apply leading zeros - if (timeString.indexOf('.') > -1) { - return leftPadWithZeros(timeString, timeString.length + (leadingZeroes - timeString.indexOf('.'))); - } - else { - return leftPadWithZeros(timeString, leadingZeroes); - } - } - else if (format.indexOf(':') > -1) { - var totalSeconds = Math.ceil(time); - // hh:mm:ss format - if (format.indexOf('hh') > -1) { - return secondsToTime(totalSeconds); - } - else { - var minutes = Math.floor(totalSeconds / 60); - var seconds = totalSeconds % 60; - return leftPadWithZeros(minutes, 2) + ':' + leftPadWithZeros(seconds, 2); - } - } - else { - return leftPadWithZeros(Math.ceil(time), leadingZeroes); - } - } -})(StringUtils = exports.StringUtils || (exports.StringUtils = {})); + +Object.defineProperty(exports, "__esModule", { value: true }); +var StringUtils; +(function (StringUtils) { + StringUtils.FORMAT_HHMMSS = 'hh:mm:ss'; + StringUtils.FORMAT_MMSS = 'mm:ss'; + /** + * Formats a number of seconds into a time string with the pattern hh:mm:ss. + * + * @param totalSeconds the total number of seconds to format to string + * @param format the time format to output (default: hh:mm:ss) + * @returns {string} the formatted time string + */ + function secondsToTime(totalSeconds, format) { + if (format === void 0) { format = StringUtils.FORMAT_HHMMSS; } + var isNegative = totalSeconds < 0; + if (isNegative) { + // If the time is negative, we make it positive for the calculation below + // (else we'd get all negative numbers) and reattach the negative sign later. + totalSeconds = -totalSeconds; + } + // Split into separate time parts + var hours = Math.floor(totalSeconds / 3600); + var minutes = Math.floor(totalSeconds / 60) - hours * 60; + var seconds = Math.floor(totalSeconds) % 60; + return (isNegative ? '-' : '') + format + .replace('hh', leftPadWithZeros(hours, 2)) + .replace('mm', leftPadWithZeros(minutes, 2)) + .replace('ss', leftPadWithZeros(seconds, 2)); + } + StringUtils.secondsToTime = secondsToTime; + /** + * Converts a number to a string and left-pads it with zeros to the specified length. + * Example: leftPadWithZeros(123, 5) => '00123' + * + * @param num the number to convert to string and pad with zeros + * @param length the desired length of the padded string + * @returns {string} the padded number as string + */ + function leftPadWithZeros(num, length) { + var text = num + ''; + var padding = '0000000000'.substr(0, length - text.length); + return padding + text; + } + /** + * Fills out placeholders in an ad message. + * + * Has the placeholders '{remainingTime[formatString]}', '{playedTime[formatString]}' and + * '{adDuration[formatString]}', which are replaced by the remaining time until the ad can be skipped, the current + * time or the ad duration. The format string is optional. If not specified, the placeholder is replaced by the time + * in seconds. If specified, it must be of the following format: + * - %d - Inserts the time as an integer. + * - %0Nd - Inserts the time as an integer with leading zeroes, if the length of the time string is smaller than N. + * - %f - Inserts the time as a float. + * - %0Nf - Inserts the time as a float with leading zeroes. + * - %.Mf - Inserts the time as a float with M decimal places. Can be combined with %0Nf, e.g. %04.2f (the time + * 10.123 + * would be printed as 0010.12). + * - %hh:mm:ss + * - %mm:ss + * + * @param adMessage an ad message with optional placeholders to fill + * @param skipOffset if specified, {remainingTime} will be filled with the remaining time until the ad can be skipped + * @param player the player to get the time data from + * @returns {string} the ad message with filled placeholders + */ + function replaceAdMessagePlaceholders(adMessage, skipOffset, player) { + var adMessagePlaceholderRegex = new RegExp('\\{(remainingTime|playedTime|adDuration)(}|%((0[1-9]\\d*(\\.\\d+(d|f)|d|f)|\\.\\d+f|d|f)|hh:mm:ss|mm:ss)})', 'g'); + return adMessage.replace(adMessagePlaceholderRegex, function (formatString) { + var time = 0; + if (formatString.indexOf('remainingTime') > -1) { + if (skipOffset) { + time = Math.ceil(skipOffset - player.getCurrentTime()); + } + else { + time = player.getDuration() - player.getCurrentTime(); + } + } + else if (formatString.indexOf('playedTime') > -1) { + time = player.getCurrentTime(); + } + else if (formatString.indexOf('adDuration') > -1) { + time = player.getDuration(); + } + return formatNumber(time, formatString); + }); + } + StringUtils.replaceAdMessagePlaceholders = replaceAdMessagePlaceholders; + function formatNumber(time, format) { + var formatStringValidationRegex = /%((0[1-9]\d*(\.\d+(d|f)|d|f)|\.\d+f|d|f)|hh:mm:ss|mm:ss)/; + var leadingZeroesRegex = /(%0[1-9]\d*)(?=(\.\d+f|f|d))/; + var decimalPlacesRegex = /\.\d*(?=f)/; + if (!formatStringValidationRegex.test(format)) { + // If the format is invalid, we set a default fallback format + format = '%d'; + } + // Determine the number of leading zeros + var leadingZeroes = 0; + var leadingZeroesMatches = format.match(leadingZeroesRegex); + if (leadingZeroesMatches) { + leadingZeroes = parseInt(leadingZeroesMatches[0].substring(2)); + } + // Determine the number of decimal places + var numDecimalPlaces = null; + var decimalPlacesMatches = format.match(decimalPlacesRegex); + if (decimalPlacesMatches && !isNaN(parseInt(decimalPlacesMatches[0].substring(1)))) { + numDecimalPlaces = parseInt(decimalPlacesMatches[0].substring(1)); + if (numDecimalPlaces > 20) { + numDecimalPlaces = 20; + } + } + // Float format + if (format.indexOf('f') > -1) { + var timeString = ''; + if (numDecimalPlaces !== null) { + // Apply fixed number of decimal places + timeString = time.toFixed(numDecimalPlaces); + } + else { + timeString = '' + time; + } + // Apply leading zeros + if (timeString.indexOf('.') > -1) { + return leftPadWithZeros(timeString, timeString.length + (leadingZeroes - timeString.indexOf('.'))); + } + else { + return leftPadWithZeros(timeString, leadingZeroes); + } + } + else if (format.indexOf(':') > -1) { + var totalSeconds = Math.ceil(time); + // hh:mm:ss format + if (format.indexOf('hh') > -1) { + return secondsToTime(totalSeconds); + } + else { + var minutes = Math.floor(totalSeconds / 60); + var seconds = totalSeconds % 60; + return leftPadWithZeros(minutes, 2) + ':' + leftPadWithZeros(seconds, 2); + } + } + else { + return leftPadWithZeros(Math.ceil(time), leadingZeroes); + } + } +})(StringUtils = exports.StringUtils || (exports.StringUtils = {})); /***/ }), @@ -2700,74 +2700,74 @@ var StringUtils; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var container_1 = __webpack_require__(1); -var uiutils_1 = __webpack_require__(16); -var spacer_1 = __webpack_require__(19); -/** - * A container for main player control components, e.g. play toggle button, seek bar, volume control, fullscreen toggle - * button. - */ -var ControlBar = (function (_super) { - __extends(ControlBar, _super); - function ControlBar(config, autoHide) { - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-controlbar', - hidden: autoHide, - }, _this.config); - return _this; - } - ControlBar.prototype.configure = function (player, uimanager) { - _super.prototype.configure.call(this, player, uimanager); - var self = this; - // Counts how many components are hovered and block hiding of the control bar - var hoverStackCount = 0; - // Track hover status of child components - uiutils_1.UIUtils.traverseTree(this, function (component) { - // Do not track hover status of child containers or spacers, only of 'real' controls - if (component instanceof container_1.Container || component instanceof spacer_1.Spacer) { - return; - } - // Subscribe hover event and keep a count of the number of hovered children - component.onHoverChanged.subscribe(function (sender, args) { - if (args.hovered) { - hoverStackCount++; - } - else { - hoverStackCount--; - } - }); - }); - uimanager.onControlsShow.subscribe(function () { - if (self.config.hidden) { - self.show(); - } - }); - uimanager.onPreviewControlsHide.subscribe(function (sender, args) { - // Cancel the hide event if hovered child components block hiding - args.cancel = (hoverStackCount > 0); - }); - uimanager.onControlsHide.subscribe(function () { - if (self.config.hidden) { - self.hide(); - } - }); - }; - return ControlBar; -}(container_1.Container)); -exports.ControlBar = ControlBar; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var container_1 = __webpack_require__(1); +var uiutils_1 = __webpack_require__(16); +var spacer_1 = __webpack_require__(19); +/** + * A container for main player control components, e.g. play toggle button, seek bar, volume control, fullscreen toggle + * button. + */ +var ControlBar = (function (_super) { + __extends(ControlBar, _super); + function ControlBar(config, autoHide) { + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-controlbar', + hidden: autoHide, + }, _this.config); + return _this; + } + ControlBar.prototype.configure = function (player, uimanager) { + _super.prototype.configure.call(this, player, uimanager); + var self = this; + // Counts how many components are hovered and block hiding of the control bar + var hoverStackCount = 0; + // Track hover status of child components + uiutils_1.UIUtils.traverseTree(this, function (component) { + // Do not track hover status of child containers or spacers, only of 'real' controls + if (component instanceof container_1.Container || component instanceof spacer_1.Spacer) { + return; + } + // Subscribe hover event and keep a count of the number of hovered children + component.onHoverChanged.subscribe(function (sender, args) { + if (args.hovered) { + hoverStackCount++; + } + else { + hoverStackCount--; + } + }); + }); + uimanager.onControlsShow.subscribe(function () { + if (self.config.hidden) { + self.show(); + } + }); + uimanager.onPreviewControlsHide.subscribe(function (sender, args) { + // Cancel the hide event if hovered child components block hiding + args.cancel = (hoverStackCount > 0); + }); + uimanager.onControlsHide.subscribe(function () { + if (self.config.hidden) { + self.hide(); + } + }); + }; + return ControlBar; +}(container_1.Container)); +exports.ControlBar = ControlBar; /***/ }), @@ -2775,27 +2775,27 @@ exports.ControlBar = ControlBar; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var container_1 = __webpack_require__(1); -var UIUtils; -(function (UIUtils) { - function traverseTree(component, visit) { - var recursiveTreeWalker = function (component, parent) { - visit(component, parent); - // If the current component is a container, visit it's children - if (component instanceof container_1.Container) { - for (var _i = 0, _a = component.getComponents(); _i < _a.length; _i++) { - var childComponent = _a[_i]; - recursiveTreeWalker(childComponent, component); - } - } - }; - // Walk and configure the component tree - recursiveTreeWalker(component); - } - UIUtils.traverseTree = traverseTree; -})(UIUtils = exports.UIUtils || (exports.UIUtils = {})); + +Object.defineProperty(exports, "__esModule", { value: true }); +var container_1 = __webpack_require__(1); +var UIUtils; +(function (UIUtils) { + function traverseTree(component, visit) { + var recursiveTreeWalker = function (component, parent) { + visit(component, parent); + // If the current component is a container, visit it's children + if (component instanceof container_1.Container) { + for (var _i = 0, _a = component.getComponents(); _i < _a.length; _i++) { + var childComponent = _a[_i]; + recursiveTreeWalker(childComponent, component); + } + } + }; + // Walk and configure the component tree + recursiveTreeWalker(component); + } + UIUtils.traverseTree = traverseTree; +})(UIUtils = exports.UIUtils || (exports.UIUtils = {})); /***/ }), @@ -2803,261 +2803,261 @@ var UIUtils; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var container_1 = __webpack_require__(1); -var dom_1 = __webpack_require__(0); -var timeout_1 = __webpack_require__(10); -var playerutils_1 = __webpack_require__(5); -/** - * The base container that contains all of the UI. The UIContainer is passed to the {@link UIManager} to build and - * setup the UI. - */ -var UIContainer = (function (_super) { - __extends(UIContainer, _super); - function UIContainer(config) { - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-uicontainer', - hideDelay: 2500, - }, _this.config); - return _this; - } - UIContainer.prototype.configure = function (player, uimanager) { - _super.prototype.configure.call(this, player, uimanager); - this.configureUIShowHide(player, uimanager); - this.configurePlayerStates(player, uimanager); - }; - UIContainer.prototype.configureUIShowHide = function (player, uimanager) { - var _this = this; - var container = this.getDomElement(); - var config = this.getConfig(); - if (config.hideDelay === -1) { - uimanager.onConfigured.subscribe(function () { return uimanager.onControlsShow.dispatch(_this); }); - return; - } - var isUiShown = false; - var isSeeking = false; - var isFirstTouch = true; - var showUi = function () { - if (!isUiShown) { - // Let subscribers know that they should reveal themselves - uimanager.onControlsShow.dispatch(_this); - isUiShown = true; - } - // Don't trigger timeout while seeking (it will be triggered once the seek is finished) or casting - if (!isSeeking && !player.isCasting()) { - _this.uiHideTimeout.start(); - } - }; - var hideUi = function () { - // Hide the UI only if it is shown, and if not casting - if (isUiShown && !player.isCasting()) { - // Issue a preview event to check if we are good to hide the controls - var previewHideEventArgs = {}; - uimanager.onPreviewControlsHide.dispatch(_this, previewHideEventArgs); - if (!previewHideEventArgs.cancel) { - // If the preview wasn't canceled, let subscribers know that they should now hide themselves - uimanager.onControlsHide.dispatch(_this); - isUiShown = false; - } - else { - // If the hide preview was canceled, continue to show UI - showUi(); - } - } - }; - // Timeout to defer UI hiding by the configured delay time - this.uiHideTimeout = new timeout_1.Timeout(config.hideDelay, hideUi); - // On touch displays, the first touch reveals the UI - container.on('touchend', function (e) { - if (!isUiShown) { - // Only if the UI is hidden, we prevent other actions (except for the first touch) and reveal the UI instead. - // The first touch is not prevented to let other listeners receive the event and trigger an initial action, e.g. - // the huge playback button can directly start playback instead of requiring a double tap which 1. reveals - // the UI and 2. starts playback. - if (isFirstTouch) { - isFirstTouch = false; - } - else { - e.preventDefault(); - } - showUi(); - } - }); - // When the mouse enters, we show the UI - container.on('mouseenter', function () { - showUi(); - }); - // When the mouse moves within, we show the UI - container.on('mousemove', function () { - showUi(); - }); - // When the mouse leaves, we can prepare to hide the UI, except a seek is going on - container.on('mouseleave', function () { - // When a seek is going on, the seek scrub pointer may exit the UI area while still seeking, and we do not hide - // the UI in such cases - if (!isSeeking) { - _this.uiHideTimeout.start(); - } - }); - uimanager.onSeek.subscribe(function () { - _this.uiHideTimeout.clear(); // Don't hide UI while a seek is in progress - isSeeking = true; - }); - uimanager.onSeeked.subscribe(function () { - isSeeking = false; - _this.uiHideTimeout.start(); // Re-enable UI hide timeout after a seek - }); - player.addEventHandler(player.EVENT.ON_CAST_STARTED, function () { - showUi(); // Show UI when a Cast session has started (UI will then stay permanently on during the session) - }); - }; - UIContainer.prototype.configurePlayerStates = function (player, uimanager) { - var _this = this; - var container = this.getDomElement(); - // Convert player states into CSS class names - var stateClassNames = []; - for (var state in playerutils_1.PlayerUtils.PlayerState) { - if (isNaN(Number(state))) { - var enumName = playerutils_1.PlayerUtils.PlayerState[playerutils_1.PlayerUtils.PlayerState[state]]; - stateClassNames[playerutils_1.PlayerUtils.PlayerState[state]] = - this.prefixCss(UIContainer.STATE_PREFIX + enumName.toLowerCase()); - } - } - var removeStates = function () { - container.removeClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.IDLE]); - container.removeClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.PREPARED]); - container.removeClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.PLAYING]); - container.removeClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.PAUSED]); - container.removeClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.FINISHED]); - }; - player.addEventHandler(player.EVENT.ON_READY, function () { - removeStates(); - container.addClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.PREPARED]); - }); - player.addEventHandler(player.EVENT.ON_PLAY, function () { - removeStates(); - container.addClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.PLAYING]); - }); - player.addEventHandler(player.EVENT.ON_PAUSED, function () { - removeStates(); - container.addClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.PAUSED]); - }); - player.addEventHandler(player.EVENT.ON_PLAYBACK_FINISHED, function () { - removeStates(); - container.addClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.FINISHED]); - }); - player.addEventHandler(player.EVENT.ON_SOURCE_UNLOADED, function () { - removeStates(); - container.addClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.IDLE]); - }); - // Init in current player state - container.addClass(stateClassNames[playerutils_1.PlayerUtils.getState(player)]); - // Fullscreen marker class - player.addEventHandler(player.EVENT.ON_FULLSCREEN_ENTER, function () { - container.addClass(_this.prefixCss(UIContainer.FULLSCREEN)); - }); - player.addEventHandler(player.EVENT.ON_FULLSCREEN_EXIT, function () { - container.removeClass(_this.prefixCss(UIContainer.FULLSCREEN)); - }); - // Init fullscreen state - if (player.isFullscreen()) { - container.addClass(this.prefixCss(UIContainer.FULLSCREEN)); - } - // Buffering marker class - player.addEventHandler(player.EVENT.ON_STALL_STARTED, function () { - container.addClass(_this.prefixCss(UIContainer.BUFFERING)); - }); - player.addEventHandler(player.EVENT.ON_STALL_ENDED, function () { - container.removeClass(_this.prefixCss(UIContainer.BUFFERING)); - }); - // Init buffering state - if (player.isStalled()) { - container.addClass(this.prefixCss(UIContainer.BUFFERING)); - } - // RemoteControl marker class - player.addEventHandler(player.EVENT.ON_CAST_STARTED, function () { - container.addClass(_this.prefixCss(UIContainer.REMOTE_CONTROL)); - }); - player.addEventHandler(player.EVENT.ON_CAST_STOPPED, function () { - container.removeClass(_this.prefixCss(UIContainer.REMOTE_CONTROL)); - }); - // Init RemoteControl state - if (player.isCasting()) { - container.addClass(this.prefixCss(UIContainer.REMOTE_CONTROL)); - } - // Controls visibility marker class - uimanager.onControlsShow.subscribe(function () { - container.removeClass(_this.prefixCss(UIContainer.CONTROLS_HIDDEN)); - container.addClass(_this.prefixCss(UIContainer.CONTROLS_SHOWN)); - }); - uimanager.onControlsHide.subscribe(function () { - container.removeClass(_this.prefixCss(UIContainer.CONTROLS_SHOWN)); - container.addClass(_this.prefixCss(UIContainer.CONTROLS_HIDDEN)); - }); - // Layout size classes - var updateLayoutSizeClasses = function (width, height) { - container.removeClass(_this.prefixCss('layout-max-width-400')); - container.removeClass(_this.prefixCss('layout-max-width-600')); - container.removeClass(_this.prefixCss('layout-max-width-800')); - container.removeClass(_this.prefixCss('layout-max-width-1200')); - if (width <= 400) { - container.addClass(_this.prefixCss('layout-max-width-400')); - } - else if (width <= 600) { - container.addClass(_this.prefixCss('layout-max-width-600')); - } - else if (width <= 800) { - container.addClass(_this.prefixCss('layout-max-width-800')); - } - else if (width <= 1200) { - container.addClass(_this.prefixCss('layout-max-width-1200')); - } - }; - player.addEventHandler(player.EVENT.ON_PLAYER_RESIZE, function (e) { - // Convert strings (with "px" suffix) to ints - var width = Math.round(Number(e.width.substring(0, e.width.length - 2))); - var height = Math.round(Number(e.height.substring(0, e.height.length - 2))); - updateLayoutSizeClasses(width, height); - }); - // Init layout state - updateLayoutSizeClasses(new dom_1.DOM(player.getFigure()).width(), new dom_1.DOM(player.getFigure()).height()); - }; - UIContainer.prototype.release = function () { - _super.prototype.release.call(this); - this.uiHideTimeout.clear(); - }; - UIContainer.prototype.toDomElement = function () { - var container = _super.prototype.toDomElement.call(this); - // Detect flexbox support (not supported in IE9) - if (document && typeof document.createElement('p').style.flex !== 'undefined') { - container.addClass(this.prefixCss('flexbox')); - } - else { - container.addClass(this.prefixCss('no-flexbox')); - } - return container; - }; - return UIContainer; -}(container_1.Container)); -UIContainer.STATE_PREFIX = 'player-state-'; -UIContainer.FULLSCREEN = 'fullscreen'; -UIContainer.BUFFERING = 'buffering'; -UIContainer.REMOTE_CONTROL = 'remote-control'; -UIContainer.CONTROLS_SHOWN = 'controls-shown'; -UIContainer.CONTROLS_HIDDEN = 'controls-hidden'; -exports.UIContainer = UIContainer; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var container_1 = __webpack_require__(1); +var dom_1 = __webpack_require__(0); +var timeout_1 = __webpack_require__(10); +var playerutils_1 = __webpack_require__(5); +/** + * The base container that contains all of the UI. The UIContainer is passed to the {@link UIManager} to build and + * setup the UI. + */ +var UIContainer = (function (_super) { + __extends(UIContainer, _super); + function UIContainer(config) { + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-uicontainer', + hideDelay: 2500, + }, _this.config); + return _this; + } + UIContainer.prototype.configure = function (player, uimanager) { + _super.prototype.configure.call(this, player, uimanager); + this.configureUIShowHide(player, uimanager); + this.configurePlayerStates(player, uimanager); + }; + UIContainer.prototype.configureUIShowHide = function (player, uimanager) { + var _this = this; + var container = this.getDomElement(); + var config = this.getConfig(); + if (config.hideDelay === -1) { + uimanager.onConfigured.subscribe(function () { return uimanager.onControlsShow.dispatch(_this); }); + return; + } + var isUiShown = false; + var isSeeking = false; + var isFirstTouch = true; + var showUi = function () { + if (!isUiShown) { + // Let subscribers know that they should reveal themselves + uimanager.onControlsShow.dispatch(_this); + isUiShown = true; + } + // Don't trigger timeout while seeking (it will be triggered once the seek is finished) or casting + if (!isSeeking && !player.isCasting()) { + _this.uiHideTimeout.start(); + } + }; + var hideUi = function () { + // Hide the UI only if it is shown, and if not casting + if (isUiShown && !player.isCasting()) { + // Issue a preview event to check if we are good to hide the controls + var previewHideEventArgs = {}; + uimanager.onPreviewControlsHide.dispatch(_this, previewHideEventArgs); + if (!previewHideEventArgs.cancel) { + // If the preview wasn't canceled, let subscribers know that they should now hide themselves + uimanager.onControlsHide.dispatch(_this); + isUiShown = false; + } + else { + // If the hide preview was canceled, continue to show UI + showUi(); + } + } + }; + // Timeout to defer UI hiding by the configured delay time + this.uiHideTimeout = new timeout_1.Timeout(config.hideDelay, hideUi); + // On touch displays, the first touch reveals the UI + container.on('touchend', function (e) { + if (!isUiShown) { + // Only if the UI is hidden, we prevent other actions (except for the first touch) and reveal the UI instead. + // The first touch is not prevented to let other listeners receive the event and trigger an initial action, e.g. + // the huge playback button can directly start playback instead of requiring a double tap which 1. reveals + // the UI and 2. starts playback. + if (isFirstTouch) { + isFirstTouch = false; + } + else { + e.preventDefault(); + } + showUi(); + } + }); + // When the mouse enters, we show the UI + container.on('mouseenter', function () { + showUi(); + }); + // When the mouse moves within, we show the UI + container.on('mousemove', function () { + showUi(); + }); + // When the mouse leaves, we can prepare to hide the UI, except a seek is going on + container.on('mouseleave', function () { + // When a seek is going on, the seek scrub pointer may exit the UI area while still seeking, and we do not hide + // the UI in such cases + if (!isSeeking) { + _this.uiHideTimeout.start(); + } + }); + uimanager.onSeek.subscribe(function () { + _this.uiHideTimeout.clear(); // Don't hide UI while a seek is in progress + isSeeking = true; + }); + uimanager.onSeeked.subscribe(function () { + isSeeking = false; + _this.uiHideTimeout.start(); // Re-enable UI hide timeout after a seek + }); + player.addEventHandler(player.EVENT.ON_CAST_STARTED, function () { + showUi(); // Show UI when a Cast session has started (UI will then stay permanently on during the session) + }); + }; + UIContainer.prototype.configurePlayerStates = function (player, uimanager) { + var _this = this; + var container = this.getDomElement(); + // Convert player states into CSS class names + var stateClassNames = []; + for (var state in playerutils_1.PlayerUtils.PlayerState) { + if (isNaN(Number(state))) { + var enumName = playerutils_1.PlayerUtils.PlayerState[playerutils_1.PlayerUtils.PlayerState[state]]; + stateClassNames[playerutils_1.PlayerUtils.PlayerState[state]] = + this.prefixCss(UIContainer.STATE_PREFIX + enumName.toLowerCase()); + } + } + var removeStates = function () { + container.removeClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.IDLE]); + container.removeClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.PREPARED]); + container.removeClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.PLAYING]); + container.removeClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.PAUSED]); + container.removeClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.FINISHED]); + }; + player.addEventHandler(player.EVENT.ON_READY, function () { + removeStates(); + container.addClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.PREPARED]); + }); + player.addEventHandler(player.EVENT.ON_PLAY, function () { + removeStates(); + container.addClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.PLAYING]); + }); + player.addEventHandler(player.EVENT.ON_PAUSED, function () { + removeStates(); + container.addClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.PAUSED]); + }); + player.addEventHandler(player.EVENT.ON_PLAYBACK_FINISHED, function () { + removeStates(); + container.addClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.FINISHED]); + }); + player.addEventHandler(player.EVENT.ON_SOURCE_UNLOADED, function () { + removeStates(); + container.addClass(stateClassNames[playerutils_1.PlayerUtils.PlayerState.IDLE]); + }); + // Init in current player state + container.addClass(stateClassNames[playerutils_1.PlayerUtils.getState(player)]); + // Fullscreen marker class + player.addEventHandler(player.EVENT.ON_FULLSCREEN_ENTER, function () { + container.addClass(_this.prefixCss(UIContainer.FULLSCREEN)); + }); + player.addEventHandler(player.EVENT.ON_FULLSCREEN_EXIT, function () { + container.removeClass(_this.prefixCss(UIContainer.FULLSCREEN)); + }); + // Init fullscreen state + if (player.isFullscreen()) { + container.addClass(this.prefixCss(UIContainer.FULLSCREEN)); + } + // Buffering marker class + player.addEventHandler(player.EVENT.ON_STALL_STARTED, function () { + container.addClass(_this.prefixCss(UIContainer.BUFFERING)); + }); + player.addEventHandler(player.EVENT.ON_STALL_ENDED, function () { + container.removeClass(_this.prefixCss(UIContainer.BUFFERING)); + }); + // Init buffering state + if (player.isStalled()) { + container.addClass(this.prefixCss(UIContainer.BUFFERING)); + } + // RemoteControl marker class + player.addEventHandler(player.EVENT.ON_CAST_STARTED, function () { + container.addClass(_this.prefixCss(UIContainer.REMOTE_CONTROL)); + }); + player.addEventHandler(player.EVENT.ON_CAST_STOPPED, function () { + container.removeClass(_this.prefixCss(UIContainer.REMOTE_CONTROL)); + }); + // Init RemoteControl state + if (player.isCasting()) { + container.addClass(this.prefixCss(UIContainer.REMOTE_CONTROL)); + } + // Controls visibility marker class + uimanager.onControlsShow.subscribe(function () { + container.removeClass(_this.prefixCss(UIContainer.CONTROLS_HIDDEN)); + container.addClass(_this.prefixCss(UIContainer.CONTROLS_SHOWN)); + }); + uimanager.onControlsHide.subscribe(function () { + container.removeClass(_this.prefixCss(UIContainer.CONTROLS_SHOWN)); + container.addClass(_this.prefixCss(UIContainer.CONTROLS_HIDDEN)); + }); + // Layout size classes + var updateLayoutSizeClasses = function (width, height) { + container.removeClass(_this.prefixCss('layout-max-width-400')); + container.removeClass(_this.prefixCss('layout-max-width-600')); + container.removeClass(_this.prefixCss('layout-max-width-800')); + container.removeClass(_this.prefixCss('layout-max-width-1200')); + if (width <= 400) { + container.addClass(_this.prefixCss('layout-max-width-400')); + } + else if (width <= 600) { + container.addClass(_this.prefixCss('layout-max-width-600')); + } + else if (width <= 800) { + container.addClass(_this.prefixCss('layout-max-width-800')); + } + else if (width <= 1200) { + container.addClass(_this.prefixCss('layout-max-width-1200')); + } + }; + player.addEventHandler(player.EVENT.ON_PLAYER_RESIZE, function (e) { + // Convert strings (with "px" suffix) to ints + var width = Math.round(Number(e.width.substring(0, e.width.length - 2))); + var height = Math.round(Number(e.height.substring(0, e.height.length - 2))); + updateLayoutSizeClasses(width, height); + }); + // Init layout state + updateLayoutSizeClasses(new dom_1.DOM(player.getFigure()).width(), new dom_1.DOM(player.getFigure()).height()); + }; + UIContainer.prototype.release = function () { + _super.prototype.release.call(this); + this.uiHideTimeout.clear(); + }; + UIContainer.prototype.toDomElement = function () { + var container = _super.prototype.toDomElement.call(this); + // Detect flexbox support (not supported in IE9) + if (document && typeof document.createElement('p').style.flex !== 'undefined') { + container.addClass(this.prefixCss('flexbox')); + } + else { + container.addClass(this.prefixCss('no-flexbox')); + } + return container; + }; + return UIContainer; +}(container_1.Container)); +UIContainer.STATE_PREFIX = 'player-state-'; +UIContainer.FULLSCREEN = 'fullscreen'; +UIContainer.BUFFERING = 'buffering'; +UIContainer.REMOTE_CONTROL = 'remote-control'; +UIContainer.CONTROLS_SHOWN = 'controls-shown'; +UIContainer.CONTROLS_HIDDEN = 'controls-hidden'; +exports.UIContainer = UIContainer; /***/ }), @@ -3065,153 +3065,153 @@ exports.UIContainer = UIContainer; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var label_1 = __webpack_require__(7); -var playerutils_1 = __webpack_require__(5); -var stringutils_1 = __webpack_require__(14); -var PlaybackTimeLabelMode; -(function (PlaybackTimeLabelMode) { - PlaybackTimeLabelMode[PlaybackTimeLabelMode["CurrentTime"] = 0] = "CurrentTime"; - PlaybackTimeLabelMode[PlaybackTimeLabelMode["TotalTime"] = 1] = "TotalTime"; - PlaybackTimeLabelMode[PlaybackTimeLabelMode["CurrentAndTotalTime"] = 2] = "CurrentAndTotalTime"; -})(PlaybackTimeLabelMode = exports.PlaybackTimeLabelMode || (exports.PlaybackTimeLabelMode = {})); -/** - * A label that display the current playback time and the total time through {@link PlaybackTimeLabel#setTime setTime} - * or any string through {@link PlaybackTimeLabel#setText setText}. - */ -var PlaybackTimeLabel = (function (_super) { - __extends(PlaybackTimeLabel, _super); - function PlaybackTimeLabel(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-playbacktimelabel', - timeLabelMode: PlaybackTimeLabelMode.CurrentAndTotalTime, - hideInLivePlayback: false, - }, _this.config); - return _this; - } - PlaybackTimeLabel.prototype.configure = function (player, uimanager) { - var _this = this; - _super.prototype.configure.call(this, player, uimanager); - var config = this.getConfig(); - var live = false; - var liveCssClass = this.prefixCss('ui-playbacktimelabel-live'); - var liveEdgeCssClass = this.prefixCss('ui-playbacktimelabel-live-edge'); - var minWidth = 0; - var liveClickHandler = function () { - player.timeShift(0); - }; - var updateLiveState = function () { - // Player is playing a live stream when the duration is infinite - live = player.isLive(); - // Attach/detach live marker class - if (live) { - _this.getDomElement().addClass(liveCssClass); - _this.setText('Live'); - if (config.hideInLivePlayback) { - _this.hide(); - } - _this.onClick.subscribe(liveClickHandler); - updateLiveTimeshiftState(); - } - else { - _this.getDomElement().removeClass(liveCssClass); - _this.getDomElement().removeClass(liveEdgeCssClass); - _this.show(); - _this.onClick.unsubscribe(liveClickHandler); - } - }; - var updateLiveTimeshiftState = function () { - if (player.getTimeShift() === 0) { - _this.getDomElement().addClass(liveEdgeCssClass); - } - else { - _this.getDomElement().removeClass(liveEdgeCssClass); - } - }; - var liveStreamDetector = new playerutils_1.PlayerUtils.LiveStreamDetector(player); - liveStreamDetector.onLiveChanged.subscribe(function (sender, args) { - live = args.live; - updateLiveState(); - }); - liveStreamDetector.detect(); // Initial detection - var playbackTimeHandler = function () { - if (!live && player.getDuration() !== Infinity) { - _this.setTime(player.getCurrentTime(), player.getDuration()); - } - // To avoid 'jumping' in the UI by varying label sizes due to non-monospaced fonts, - // we gradually increase the min-width with the content to reach a stable size. - var width = _this.getDomElement().width(); - if (width > minWidth) { - minWidth = width; - _this.getDomElement().css({ - 'min-width': minWidth + 'px', - }); - } - }; - player.addEventHandler(player.EVENT.ON_TIME_CHANGED, playbackTimeHandler); - player.addEventHandler(player.EVENT.ON_SEEKED, playbackTimeHandler); - player.addEventHandler(player.EVENT.ON_CAST_TIME_UPDATED, playbackTimeHandler); - player.addEventHandler(player.EVENT.ON_TIME_SHIFT, updateLiveTimeshiftState); - player.addEventHandler(player.EVENT.ON_TIME_SHIFTED, updateLiveTimeshiftState); - var init = function () { - // Reset min-width when a new source is ready (especially for switching VOD/Live modes where the label content - // changes) - minWidth = 0; - _this.getDomElement().css({ - 'min-width': null, - }); - // Set time format depending on source duration - _this.timeFormat = Math.abs(player.isLive() ? player.getMaxTimeShift() : player.getDuration()) >= 3600 ? - stringutils_1.StringUtils.FORMAT_HHMMSS : stringutils_1.StringUtils.FORMAT_MMSS; - // Update time after the format has been set - playbackTimeHandler(); - }; - player.addEventHandler(player.EVENT.ON_READY, init); - init(); - }; - /** - * Sets the current playback time and total duration. - * @param playbackSeconds the current playback time in seconds - * @param durationSeconds the total duration in seconds - */ - PlaybackTimeLabel.prototype.setTime = function (playbackSeconds, durationSeconds) { - var currentTime = stringutils_1.StringUtils.secondsToTime(playbackSeconds, this.timeFormat); - var totalTime = stringutils_1.StringUtils.secondsToTime(durationSeconds, this.timeFormat); - switch (this.config.timeLabelMode) { - case PlaybackTimeLabelMode.CurrentTime: - this.setText("" + currentTime); - break; - case PlaybackTimeLabelMode.TotalTime: - this.setText("" + totalTime); - break; - case PlaybackTimeLabelMode.CurrentAndTotalTime: - this.setText(currentTime + " / " + totalTime); - break; - } - }; - /** - * Sets the current time format - * @param timeFormat the time format - */ - PlaybackTimeLabel.prototype.setTimeFormat = function (timeFormat) { - this.timeFormat = timeFormat; - }; - return PlaybackTimeLabel; -}(label_1.Label)); -exports.PlaybackTimeLabel = PlaybackTimeLabel; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var label_1 = __webpack_require__(7); +var playerutils_1 = __webpack_require__(5); +var stringutils_1 = __webpack_require__(14); +var PlaybackTimeLabelMode; +(function (PlaybackTimeLabelMode) { + PlaybackTimeLabelMode[PlaybackTimeLabelMode["CurrentTime"] = 0] = "CurrentTime"; + PlaybackTimeLabelMode[PlaybackTimeLabelMode["TotalTime"] = 1] = "TotalTime"; + PlaybackTimeLabelMode[PlaybackTimeLabelMode["CurrentAndTotalTime"] = 2] = "CurrentAndTotalTime"; +})(PlaybackTimeLabelMode = exports.PlaybackTimeLabelMode || (exports.PlaybackTimeLabelMode = {})); +/** + * A label that display the current playback time and the total time through {@link PlaybackTimeLabel#setTime setTime} + * or any string through {@link PlaybackTimeLabel#setText setText}. + */ +var PlaybackTimeLabel = (function (_super) { + __extends(PlaybackTimeLabel, _super); + function PlaybackTimeLabel(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-playbacktimelabel', + timeLabelMode: PlaybackTimeLabelMode.CurrentAndTotalTime, + hideInLivePlayback: false, + }, _this.config); + return _this; + } + PlaybackTimeLabel.prototype.configure = function (player, uimanager) { + var _this = this; + _super.prototype.configure.call(this, player, uimanager); + var config = this.getConfig(); + var live = false; + var liveCssClass = this.prefixCss('ui-playbacktimelabel-live'); + var liveEdgeCssClass = this.prefixCss('ui-playbacktimelabel-live-edge'); + var minWidth = 0; + var liveClickHandler = function () { + player.timeShift(0); + }; + var updateLiveState = function () { + // Player is playing a live stream when the duration is infinite + live = player.isLive(); + // Attach/detach live marker class + if (live) { + _this.getDomElement().addClass(liveCssClass); + _this.setText('Live'); + if (config.hideInLivePlayback) { + _this.hide(); + } + _this.onClick.subscribe(liveClickHandler); + updateLiveTimeshiftState(); + } + else { + _this.getDomElement().removeClass(liveCssClass); + _this.getDomElement().removeClass(liveEdgeCssClass); + _this.show(); + _this.onClick.unsubscribe(liveClickHandler); + } + }; + var updateLiveTimeshiftState = function () { + if (player.getTimeShift() === 0) { + _this.getDomElement().addClass(liveEdgeCssClass); + } + else { + _this.getDomElement().removeClass(liveEdgeCssClass); + } + }; + var liveStreamDetector = new playerutils_1.PlayerUtils.LiveStreamDetector(player); + liveStreamDetector.onLiveChanged.subscribe(function (sender, args) { + live = args.live; + updateLiveState(); + }); + liveStreamDetector.detect(); // Initial detection + var playbackTimeHandler = function () { + if (!live && player.getDuration() !== Infinity) { + _this.setTime(player.getCurrentTime(), player.getDuration()); + } + // To avoid 'jumping' in the UI by varying label sizes due to non-monospaced fonts, + // we gradually increase the min-width with the content to reach a stable size. + var width = _this.getDomElement().width(); + if (width > minWidth) { + minWidth = width; + _this.getDomElement().css({ + 'min-width': minWidth + 'px', + }); + } + }; + player.addEventHandler(player.EVENT.ON_TIME_CHANGED, playbackTimeHandler); + player.addEventHandler(player.EVENT.ON_SEEKED, playbackTimeHandler); + player.addEventHandler(player.EVENT.ON_CAST_TIME_UPDATED, playbackTimeHandler); + player.addEventHandler(player.EVENT.ON_TIME_SHIFT, updateLiveTimeshiftState); + player.addEventHandler(player.EVENT.ON_TIME_SHIFTED, updateLiveTimeshiftState); + var init = function () { + // Reset min-width when a new source is ready (especially for switching VOD/Live modes where the label content + // changes) + minWidth = 0; + _this.getDomElement().css({ + 'min-width': null, + }); + // Set time format depending on source duration + _this.timeFormat = Math.abs(player.isLive() ? player.getMaxTimeShift() : player.getDuration()) >= 3600 ? + stringutils_1.StringUtils.FORMAT_HHMMSS : stringutils_1.StringUtils.FORMAT_MMSS; + // Update time after the format has been set + playbackTimeHandler(); + }; + player.addEventHandler(player.EVENT.ON_READY, init); + init(); + }; + /** + * Sets the current playback time and total duration. + * @param playbackSeconds the current playback time in seconds + * @param durationSeconds the total duration in seconds + */ + PlaybackTimeLabel.prototype.setTime = function (playbackSeconds, durationSeconds) { + var currentTime = stringutils_1.StringUtils.secondsToTime(playbackSeconds, this.timeFormat); + var totalTime = stringutils_1.StringUtils.secondsToTime(durationSeconds, this.timeFormat); + switch (this.config.timeLabelMode) { + case PlaybackTimeLabelMode.CurrentTime: + this.setText("" + currentTime); + break; + case PlaybackTimeLabelMode.TotalTime: + this.setText("" + totalTime); + break; + case PlaybackTimeLabelMode.CurrentAndTotalTime: + this.setText(currentTime + " / " + totalTime); + break; + } + }; + /** + * Sets the current time format + * @param timeFormat the time format + */ + PlaybackTimeLabel.prototype.setTimeFormat = function (timeFormat) { + this.timeFormat = timeFormat; + }; + return PlaybackTimeLabel; +}(label_1.Label)); +exports.PlaybackTimeLabel = PlaybackTimeLabel; /***/ }), @@ -3219,44 +3219,44 @@ exports.PlaybackTimeLabel = PlaybackTimeLabel; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var component_1 = __webpack_require__(2); -/** - * A dummy component that just reserves some space and does nothing else. - */ -var Spacer = (function (_super) { - __extends(Spacer, _super); - function Spacer(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-spacer', - }, _this.config); - return _this; - } - Spacer.prototype.onShowEvent = function () { - // disable event firing by overwriting and not calling super - }; - Spacer.prototype.onHideEvent = function () { - // disable event firing by overwriting and not calling super - }; - Spacer.prototype.onHoverChangedEvent = function (hovered) { - // disable event firing by overwriting and not calling super - }; - return Spacer; -}(component_1.Component)); -exports.Spacer = Spacer; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var component_1 = __webpack_require__(2); +/** + * A dummy component that just reserves some space and does nothing else. + */ +var Spacer = (function (_super) { + __extends(Spacer, _super); + function Spacer(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-spacer', + }, _this.config); + return _this; + } + Spacer.prototype.onShowEvent = function () { + // disable event firing by overwriting and not calling super + }; + Spacer.prototype.onHideEvent = function () { + // disable event firing by overwriting and not calling super + }; + Spacer.prototype.onHoverChangedEvent = function (hovered) { + // disable event firing by overwriting and not calling super + }; + return Spacer; +}(component_1.Component)); +exports.Spacer = Spacer; /***/ }), @@ -3264,148 +3264,148 @@ exports.Spacer = Spacer; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var container_1 = __webpack_require__(1); -var label_1 = __webpack_require__(7); -var component_1 = __webpack_require__(2); -var stringutils_1 = __webpack_require__(14); -var imageloader_1 = __webpack_require__(38); -/** - * A label for a {@link SeekBar} that can display the seek target time, a thumbnail, and title (e.g. chapter title). - */ -var SeekBarLabel = (function (_super) { - __extends(SeekBarLabel, _super); - function SeekBarLabel(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.timeLabel = new label_1.Label({ cssClasses: ['seekbar-label-time'] }); - _this.titleLabel = new label_1.Label({ cssClasses: ['seekbar-label-title'] }); - _this.thumbnail = new component_1.Component({ cssClasses: ['seekbar-thumbnail'] }); - _this.thumbnailImageLoader = new imageloader_1.ImageLoader(); - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-seekbar-label', - components: [new container_1.Container({ - components: [ - // this.thumbnail, - new container_1.Container({ - components: [_this.titleLabel, _this.timeLabel], - cssClass: 'seekbar-label-metadata', - }) - ], - cssClass: 'seekbar-label-inner', - })], - hidden: true, - }, _this.config); - return _this; - } - SeekBarLabel.prototype.configure = function (player, uimanager) { - var _this = this; - _super.prototype.configure.call(this, player, uimanager); - uimanager.onSeekPreview.subscribeRateLimited(function (sender, args) { - if (player.isLive()) { - var maxTimeShift = player.getMaxTimeShift(); - var time = maxTimeShift - maxTimeShift * (args.position / 100); - _this.setTime(time); - } - else { - var percentage = 0; - if (args.marker) { - percentage = args.marker.time; - _this.setTitleText(args.marker.title); - } - else { - percentage = args.position; - _this.setTitleText(null); - } - var time = player.getDuration() * (percentage / 100); - _this.setTime(time); - _this.setThumbnail(player.getThumb(time)); - } - }, 100); - var init = function () { - // Set time format depending on source duration - _this.timeFormat = Math.abs(player.isLive() ? player.getMaxTimeShift() : player.getDuration()) >= 3600 ? - stringutils_1.StringUtils.FORMAT_HHMMSS : stringutils_1.StringUtils.FORMAT_MMSS; - }; - player.addEventHandler(player.EVENT.ON_READY, init); - init(); - }; - /** - * Sets arbitrary text on the label. - * @param text the text to show on the label - */ - SeekBarLabel.prototype.setText = function (text) { - this.timeLabel.setText(text); - }; - /** - * Sets a time to be displayed on the label. - * @param seconds the time in seconds to display on the label - */ - SeekBarLabel.prototype.setTime = function (seconds) { - this.setText(stringutils_1.StringUtils.secondsToTime(seconds, this.timeFormat)); - }; - /** - * Sets the text on the title label. - * @param text the text to show on the label - */ - SeekBarLabel.prototype.setTitleText = function (text) { - this.titleLabel.setText(text); - }; - /** - * Sets or removes a thumbnail on the label. - * @param thumbnail the thumbnail to display on the label or null to remove a displayed thumbnail - */ - SeekBarLabel.prototype.setThumbnail = function (thumbnail) { - if (thumbnail === void 0) { thumbnail = null; } - var thumbnailElement = this.thumbnail.getDomElement(); - if (thumbnail == null) { - thumbnailElement.css({ - 'background-image': null, - 'display': null, - 'width': null, - 'height': null, - }); - } - else { - // We use the thumbnail image loader to make sure the thumbnail is loaded and it's size is known before be can - // calculate the CSS properties and set them on the element. - this.thumbnailImageLoader.load(thumbnail.url, function (url, width, height) { - var thumbnailCountX = width / thumbnail.w; - var thumbnailCountY = height / thumbnail.h; - var thumbnailIndexX = thumbnail.x / thumbnail.w; - var thumbnailIndexY = thumbnail.y / thumbnail.h; - var sizeX = 100 * thumbnailCountX; - var sizeY = 100 * thumbnailCountY; - var offsetX = 100 * thumbnailIndexX; - var offsetY = 100 * thumbnailIndexY; - var aspectRatio = 1 / thumbnail.w * thumbnail.h; - // The thumbnail size is set by setting the CSS 'width' and 'padding-bottom' properties. 'padding-bottom' is - // used because it is relative to the width and can be used to set the aspect ratio of the thumbnail. - // A default value for width is set in the stylesheet and can be overwritten from there or anywhere else. - thumbnailElement.css({ - 'display': 'inherit', - 'background-image': "url(" + thumbnail.url + ")", - 'padding-bottom': 100 * aspectRatio + "%", - 'background-size': sizeX + "% " + sizeY + "%", - 'background-position': "-" + offsetX + "% -" + offsetY + "%", - }); - }); - } - }; - return SeekBarLabel; -}(container_1.Container)); -exports.SeekBarLabel = SeekBarLabel; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var container_1 = __webpack_require__(1); +var label_1 = __webpack_require__(7); +var component_1 = __webpack_require__(2); +var stringutils_1 = __webpack_require__(14); +var imageloader_1 = __webpack_require__(38); +/** + * A label for a {@link SeekBar} that can display the seek target time, a thumbnail, and title (e.g. chapter title). + */ +var SeekBarLabel = (function (_super) { + __extends(SeekBarLabel, _super); + function SeekBarLabel(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.timeLabel = new label_1.Label({ cssClasses: ['seekbar-label-time'] }); + _this.titleLabel = new label_1.Label({ cssClasses: ['seekbar-label-title'] }); + _this.thumbnail = new component_1.Component({ cssClasses: ['seekbar-thumbnail'] }); + _this.thumbnailImageLoader = new imageloader_1.ImageLoader(); + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-seekbar-label', + components: [new container_1.Container({ + components: [ + // this.thumbnail, + new container_1.Container({ + components: [_this.titleLabel, _this.timeLabel], + cssClass: 'seekbar-label-metadata', + }) + ], + cssClass: 'seekbar-label-inner', + })], + hidden: true, + }, _this.config); + return _this; + } + SeekBarLabel.prototype.configure = function (player, uimanager) { + var _this = this; + _super.prototype.configure.call(this, player, uimanager); + uimanager.onSeekPreview.subscribeRateLimited(function (sender, args) { + if (player.isLive()) { + var maxTimeShift = player.getMaxTimeShift(); + var time = maxTimeShift - maxTimeShift * (args.position / 100); + _this.setTime(time); + } + else { + var percentage = 0; + if (args.marker) { + percentage = args.marker.time; + _this.setTitleText(args.marker.title); + } + else { + percentage = args.position; + _this.setTitleText(null); + } + var time = player.getDuration() * (percentage / 100); + _this.setTime(time); + _this.setThumbnail(player.getThumb(time)); + } + }, 100); + var init = function () { + // Set time format depending on source duration + _this.timeFormat = Math.abs(player.isLive() ? player.getMaxTimeShift() : player.getDuration()) >= 3600 ? + stringutils_1.StringUtils.FORMAT_HHMMSS : stringutils_1.StringUtils.FORMAT_MMSS; + }; + player.addEventHandler(player.EVENT.ON_READY, init); + init(); + }; + /** + * Sets arbitrary text on the label. + * @param text the text to show on the label + */ + SeekBarLabel.prototype.setText = function (text) { + this.timeLabel.setText(text); + }; + /** + * Sets a time to be displayed on the label. + * @param seconds the time in seconds to display on the label + */ + SeekBarLabel.prototype.setTime = function (seconds) { + this.setText(stringutils_1.StringUtils.secondsToTime(seconds, this.timeFormat)); + }; + /** + * Sets the text on the title label. + * @param text the text to show on the label + */ + SeekBarLabel.prototype.setTitleText = function (text) { + this.titleLabel.setText(text); + }; + /** + * Sets or removes a thumbnail on the label. + * @param thumbnail the thumbnail to display on the label or null to remove a displayed thumbnail + */ + SeekBarLabel.prototype.setThumbnail = function (thumbnail) { + if (thumbnail === void 0) { thumbnail = null; } + var thumbnailElement = this.thumbnail.getDomElement(); + if (thumbnail == null) { + thumbnailElement.css({ + 'background-image': null, + 'display': null, + 'width': null, + 'height': null, + }); + } + else { + // We use the thumbnail image loader to make sure the thumbnail is loaded and it's size is known before be can + // calculate the CSS properties and set them on the element. + this.thumbnailImageLoader.load(thumbnail.url, function (url, width, height) { + var thumbnailCountX = width / thumbnail.w; + var thumbnailCountY = height / thumbnail.h; + var thumbnailIndexX = thumbnail.x / thumbnail.w; + var thumbnailIndexY = thumbnail.y / thumbnail.h; + var sizeX = 100 * thumbnailCountX; + var sizeY = 100 * thumbnailCountY; + var offsetX = 100 * thumbnailIndexX; + var offsetY = 100 * thumbnailIndexY; + var aspectRatio = 1 / thumbnail.w * thumbnail.h; + // The thumbnail size is set by setting the CSS 'width' and 'padding-bottom' properties. 'padding-bottom' is + // used because it is relative to the width and can be used to set the aspect ratio of the thumbnail. + // A default value for width is set in the stylesheet and can be overwritten from there or anywhere else. + thumbnailElement.css({ + 'display': 'inherit', + 'background-image': "url(" + thumbnail.url + ")", + 'padding-bottom': 100 * aspectRatio + "%", + 'background-size': sizeX + "% " + sizeY + "%", + 'background-position': "-" + offsetX + "% -" + offsetY + "%", + }); + }); + } + }; + return SeekBarLabel; +}(container_1.Container)); +exports.SeekBarLabel = SeekBarLabel; /***/ }), @@ -3413,89 +3413,89 @@ exports.SeekBarLabel = SeekBarLabel; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var listselector_1 = __webpack_require__(22); -var dom_1 = __webpack_require__(0); -/** - * A simple select box providing the possibility to select a single item out of a list of available items. - * - * DOM example: - * - * - * - */ -var SelectBox = (function (_super) { - __extends(SelectBox, _super); - function SelectBox(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-selectbox', - }, _this.config); - return _this; - } - SelectBox.prototype.toDomElement = function () { - var _this = this; - var selectElement = new dom_1.DOM('select', { - 'id': this.config.id, - 'class': this.getCssClasses(), - }); - this.selectElement = selectElement; - this.updateDomItems(); - selectElement.on('change', function () { - var value = selectElement.val(); - _this.onItemSelectedEvent(value, false); - }); - return selectElement; - }; - SelectBox.prototype.updateDomItems = function (selectedValue) { - if (selectedValue === void 0) { selectedValue = null; } - // Delete all children - this.selectElement.empty(); - // Add updated children - for (var _i = 0, _a = this.items; _i < _a.length; _i++) { - var item = _a[_i]; - var optionElement = new dom_1.DOM('option', { - 'value': item.key, - }).html(item.label); - if (item.key === String(selectedValue)) { - optionElement.attr('selected', 'selected'); - } - this.selectElement.append(optionElement); - } - }; - SelectBox.prototype.onItemAddedEvent = function (value) { - _super.prototype.onItemAddedEvent.call(this, value); - this.updateDomItems(this.selectedItem); - }; - SelectBox.prototype.onItemRemovedEvent = function (value) { - _super.prototype.onItemRemovedEvent.call(this, value); - this.updateDomItems(this.selectedItem); - }; - SelectBox.prototype.onItemSelectedEvent = function (value, updateDomItems) { - if (updateDomItems === void 0) { updateDomItems = true; } - _super.prototype.onItemSelectedEvent.call(this, value); - if (updateDomItems) { - this.updateDomItems(value); - } - }; - return SelectBox; -}(listselector_1.ListSelector)); -exports.SelectBox = SelectBox; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var listselector_1 = __webpack_require__(22); +var dom_1 = __webpack_require__(0); +/** + * A simple select box providing the possibility to select a single item out of a list of available items. + * + * DOM example: + * + * + * + */ +var SelectBox = (function (_super) { + __extends(SelectBox, _super); + function SelectBox(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-selectbox', + }, _this.config); + return _this; + } + SelectBox.prototype.toDomElement = function () { + var _this = this; + var selectElement = new dom_1.DOM('select', { + 'id': this.config.id, + 'class': this.getCssClasses(), + }); + this.selectElement = selectElement; + this.updateDomItems(); + selectElement.on('change', function () { + var value = selectElement.val(); + _this.onItemSelectedEvent(value, false); + }); + return selectElement; + }; + SelectBox.prototype.updateDomItems = function (selectedValue) { + if (selectedValue === void 0) { selectedValue = null; } + // Delete all children + this.selectElement.empty(); + // Add updated children + for (var _i = 0, _a = this.items; _i < _a.length; _i++) { + var item = _a[_i]; + var optionElement = new dom_1.DOM('option', { + 'value': item.key, + }).html(item.label); + if (item.key === String(selectedValue)) { + optionElement.attr('selected', 'selected'); + } + this.selectElement.append(optionElement); + } + }; + SelectBox.prototype.onItemAddedEvent = function (value) { + _super.prototype.onItemAddedEvent.call(this, value); + this.updateDomItems(this.selectedItem); + }; + SelectBox.prototype.onItemRemovedEvent = function (value) { + _super.prototype.onItemRemovedEvent.call(this, value); + this.updateDomItems(this.selectedItem); + }; + SelectBox.prototype.onItemSelectedEvent = function (value, updateDomItems) { + if (updateDomItems === void 0) { updateDomItems = true; } + _super.prototype.onItemSelectedEvent.call(this, value); + if (updateDomItems) { + this.updateDomItems(value); + } + }; + return SelectBox; +}(listselector_1.ListSelector)); +exports.SelectBox = SelectBox; /***/ }), @@ -3503,172 +3503,172 @@ exports.SelectBox = SelectBox; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var component_1 = __webpack_require__(2); -var eventdispatcher_1 = __webpack_require__(3); -var arrayutils_1 = __webpack_require__(4); -var ListSelector = (function (_super) { - __extends(ListSelector, _super); - function ListSelector(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.listSelectorEvents = { - onItemAdded: new eventdispatcher_1.EventDispatcher(), - onItemRemoved: new eventdispatcher_1.EventDispatcher(), - onItemSelected: new eventdispatcher_1.EventDispatcher(), - }; - _this.config = _this.mergeConfig(config, { - items: [], - cssClass: 'ui-listselector', - }, _this.config); - _this.items = _this.config.items; - return _this; - } - ListSelector.prototype.getItemIndex = function (key) { - for (var index in this.items) { - if (key === this.items[index].key) { - return parseInt(index); - } - } - return -1; - }; - /** - * Checks if the specified item is part of this selector. - * @param key the key of the item to check - * @returns {boolean} true if the item is part of this selector, else false - */ - ListSelector.prototype.hasItem = function (key) { - return this.getItemIndex(key) > -1; - }; - /** - * Adds an item to this selector by appending it to the end of the list of items. If an item with the specified - * key already exists, it is replaced. - * @param key the key of the item to add - * @param label the (human-readable) label of the item to add - */ - ListSelector.prototype.addItem = function (key, label) { - this.removeItem(key); // Try to remove key first to get overwrite behavior and avoid duplicate keys - this.items.push({ key: key, label: label }); - this.onItemAddedEvent(key); - }; - /** - * Removes an item from this selector. - * @param key the key of the item to remove - * @returns {boolean} true if removal was successful, false if the item is not part of this selector - */ - ListSelector.prototype.removeItem = function (key) { - var index = this.getItemIndex(key); - if (index > -1) { - arrayutils_1.ArrayUtils.remove(this.items, this.items[index]); - this.onItemRemovedEvent(key); - return true; - } - return false; - }; - /** - * Selects an item from the items in this selector. - * @param key the key of the item to select - * @returns {boolean} true is the selection was successful, false if the selected item is not part of the selector - */ - ListSelector.prototype.selectItem = function (key) { - if (key === this.selectedItem) { - // itemConfig is already selected, suppress any further action - return true; - } - var index = this.getItemIndex(key); - if (index > -1) { - this.selectedItem = key; - this.onItemSelectedEvent(key); - return true; - } - return false; - }; - /** - * Returns the key of the selected item. - * @returns {string} the key of the selected item or null if no item is selected - */ - ListSelector.prototype.getSelectedItem = function () { - return this.selectedItem; - }; - /** - * Removes all items from this selector. - */ - ListSelector.prototype.clearItems = function () { - // local copy for iteration after clear - var items = this.items; - // clear items - this.items = []; - // clear the selection as the selected item is also removed - this.selectedItem = null; - // fire events - for (var _i = 0, items_1 = items; _i < items_1.length; _i++) { - var item = items_1[_i]; - this.onItemRemovedEvent(item.key); - } - }; - /** - * Returns the number of items in this selector. - * @returns {number} - */ - ListSelector.prototype.itemCount = function () { - return Object.keys(this.items).length; - }; - ListSelector.prototype.onItemAddedEvent = function (key) { - this.listSelectorEvents.onItemAdded.dispatch(this, key); - }; - ListSelector.prototype.onItemRemovedEvent = function (key) { - this.listSelectorEvents.onItemRemoved.dispatch(this, key); - }; - ListSelector.prototype.onItemSelectedEvent = function (key) { - this.listSelectorEvents.onItemSelected.dispatch(this, key); - }; - Object.defineProperty(ListSelector.prototype, "onItemAdded", { - /** - * Gets the event that is fired when an item is added to the list of items. - * @returns {Event, string>} - */ - get: function () { - return this.listSelectorEvents.onItemAdded.getEvent(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(ListSelector.prototype, "onItemRemoved", { - /** - * Gets the event that is fired when an item is removed from the list of items. - * @returns {Event, string>} - */ - get: function () { - return this.listSelectorEvents.onItemRemoved.getEvent(); - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(ListSelector.prototype, "onItemSelected", { - /** - * Gets the event that is fired when an item is selected from the list of items. - * @returns {Event, string>} - */ - get: function () { - return this.listSelectorEvents.onItemSelected.getEvent(); - }, - enumerable: true, - configurable: true - }); - return ListSelector; -}(component_1.Component)); -exports.ListSelector = ListSelector; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var component_1 = __webpack_require__(2); +var eventdispatcher_1 = __webpack_require__(3); +var arrayutils_1 = __webpack_require__(4); +var ListSelector = (function (_super) { + __extends(ListSelector, _super); + function ListSelector(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.listSelectorEvents = { + onItemAdded: new eventdispatcher_1.EventDispatcher(), + onItemRemoved: new eventdispatcher_1.EventDispatcher(), + onItemSelected: new eventdispatcher_1.EventDispatcher(), + }; + _this.config = _this.mergeConfig(config, { + items: [], + cssClass: 'ui-listselector', + }, _this.config); + _this.items = _this.config.items; + return _this; + } + ListSelector.prototype.getItemIndex = function (key) { + for (var index in this.items) { + if (key === this.items[index].key) { + return parseInt(index); + } + } + return -1; + }; + /** + * Checks if the specified item is part of this selector. + * @param key the key of the item to check + * @returns {boolean} true if the item is part of this selector, else false + */ + ListSelector.prototype.hasItem = function (key) { + return this.getItemIndex(key) > -1; + }; + /** + * Adds an item to this selector by appending it to the end of the list of items. If an item with the specified + * key already exists, it is replaced. + * @param key the key of the item to add + * @param label the (human-readable) label of the item to add + */ + ListSelector.prototype.addItem = function (key, label) { + this.removeItem(key); // Try to remove key first to get overwrite behavior and avoid duplicate keys + this.items.push({ key: key, label: label }); + this.onItemAddedEvent(key); + }; + /** + * Removes an item from this selector. + * @param key the key of the item to remove + * @returns {boolean} true if removal was successful, false if the item is not part of this selector + */ + ListSelector.prototype.removeItem = function (key) { + var index = this.getItemIndex(key); + if (index > -1) { + arrayutils_1.ArrayUtils.remove(this.items, this.items[index]); + this.onItemRemovedEvent(key); + return true; + } + return false; + }; + /** + * Selects an item from the items in this selector. + * @param key the key of the item to select + * @returns {boolean} true is the selection was successful, false if the selected item is not part of the selector + */ + ListSelector.prototype.selectItem = function (key) { + if (key === this.selectedItem) { + // itemConfig is already selected, suppress any further action + return true; + } + var index = this.getItemIndex(key); + if (index > -1) { + this.selectedItem = key; + this.onItemSelectedEvent(key); + return true; + } + return false; + }; + /** + * Returns the key of the selected item. + * @returns {string} the key of the selected item or null if no item is selected + */ + ListSelector.prototype.getSelectedItem = function () { + return this.selectedItem; + }; + /** + * Removes all items from this selector. + */ + ListSelector.prototype.clearItems = function () { + // local copy for iteration after clear + var items = this.items; + // clear items + this.items = []; + // clear the selection as the selected item is also removed + this.selectedItem = null; + // fire events + for (var _i = 0, items_1 = items; _i < items_1.length; _i++) { + var item = items_1[_i]; + this.onItemRemovedEvent(item.key); + } + }; + /** + * Returns the number of items in this selector. + * @returns {number} + */ + ListSelector.prototype.itemCount = function () { + return Object.keys(this.items).length; + }; + ListSelector.prototype.onItemAddedEvent = function (key) { + this.listSelectorEvents.onItemAdded.dispatch(this, key); + }; + ListSelector.prototype.onItemRemovedEvent = function (key) { + this.listSelectorEvents.onItemRemoved.dispatch(this, key); + }; + ListSelector.prototype.onItemSelectedEvent = function (key) { + this.listSelectorEvents.onItemSelected.dispatch(this, key); + }; + Object.defineProperty(ListSelector.prototype, "onItemAdded", { + /** + * Gets the event that is fired when an item is added to the list of items. + * @returns {Event, string>} + */ + get: function () { + return this.listSelectorEvents.onItemAdded.getEvent(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(ListSelector.prototype, "onItemRemoved", { + /** + * Gets the event that is fired when an item is removed from the list of items. + * @returns {Event, string>} + */ + get: function () { + return this.listSelectorEvents.onItemRemoved.getEvent(); + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(ListSelector.prototype, "onItemSelected", { + /** + * Gets the event that is fired when an item is selected from the list of items. + * @returns {Event, string>} + */ + get: function () { + return this.listSelectorEvents.onItemSelected.getEvent(); + }, + enumerable: true, + configurable: true + }); + return ListSelector; +}(component_1.Component)); +exports.ListSelector = ListSelector; /***/ }), @@ -3676,114 +3676,114 @@ exports.ListSelector = ListSelector; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var container_1 = __webpack_require__(1); -var volumeslider_1 = __webpack_require__(24); -var volumetogglebutton_1 = __webpack_require__(25); -var timeout_1 = __webpack_require__(10); -/** - * A composite volume control that consists of and internally manages a volume control button that can be used - * for muting, and a (depending on the CSS style, e.g. slide-out) volume control bar. - */ -var VolumeControlButton = (function (_super) { - __extends(VolumeControlButton, _super); - function VolumeControlButton(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.volumeToggleButton = new volumetogglebutton_1.VolumeToggleButton(); - _this.volumeSlider = new volumeslider_1.VolumeSlider({ - vertical: config.vertical != null ? config.vertical : true, - hidden: true, - }); - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-volumecontrolbutton', - components: [_this.volumeToggleButton, _this.volumeSlider], - hideDelay: 500, - }, _this.config); - return _this; - } - VolumeControlButton.prototype.configure = function (player, uimanager) { - var _this = this; - _super.prototype.configure.call(this, player, uimanager); - var volumeToggleButton = this.getVolumeToggleButton(); - var volumeSlider = this.getVolumeSlider(); - this.volumeSliderHideTimeout = new timeout_1.Timeout(this.getConfig().hideDelay, function () { - volumeSlider.hide(); - }); - /* - * Volume Slider visibility handling - * - * The volume slider shall be visible while the user hovers the mute toggle button, while the user hovers the - * volume slider, and while the user slides the volume slider. If none of these situations are true, the slider - * shall disappear. - */ - var volumeSliderHovered = false; - volumeToggleButton.getDomElement().on('mouseenter', function () { - // Show volume slider when mouse enters the button area - if (volumeSlider.isHidden()) { - volumeSlider.show(); - } - // Avoid hiding of the slider when button is hovered - _this.volumeSliderHideTimeout.clear(); - }); - volumeToggleButton.getDomElement().on('mouseleave', function () { - // Hide slider delayed when button is left - _this.volumeSliderHideTimeout.reset(); - }); - volumeSlider.getDomElement().on('mouseenter', function () { - // When the slider is entered, cancel the hide timeout activated by leaving the button - _this.volumeSliderHideTimeout.clear(); - volumeSliderHovered = true; - }); - volumeSlider.getDomElement().on('mouseleave', function () { - // When mouse leaves the slider, only hide it if there is no slide operation in progress - if (volumeSlider.isSeeking()) { - _this.volumeSliderHideTimeout.clear(); - } - else { - _this.volumeSliderHideTimeout.reset(); - } - volumeSliderHovered = false; - }); - volumeSlider.onSeeked.subscribe(function () { - // When a slide operation is done and the slider not hovered (mouse outside slider), hide slider delayed - if (!volumeSliderHovered) { - _this.volumeSliderHideTimeout.reset(); - } - }); - }; - VolumeControlButton.prototype.release = function () { - _super.prototype.release.call(this); - this.volumeSliderHideTimeout.clear(); - }; - /** - * Provides access to the internally managed volume toggle button. - * @returns {VolumeToggleButton} - */ - VolumeControlButton.prototype.getVolumeToggleButton = function () { - return this.volumeToggleButton; - }; - /** - * Provides access to the internally managed volume silder. - * @returns {VolumeSlider} - */ - VolumeControlButton.prototype.getVolumeSlider = function () { - return this.volumeSlider; - }; - return VolumeControlButton; -}(container_1.Container)); -exports.VolumeControlButton = VolumeControlButton; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var container_1 = __webpack_require__(1); +var volumeslider_1 = __webpack_require__(24); +var volumetogglebutton_1 = __webpack_require__(25); +var timeout_1 = __webpack_require__(10); +/** + * A composite volume control that consists of and internally manages a volume control button that can be used + * for muting, and a (depending on the CSS style, e.g. slide-out) volume control bar. + */ +var VolumeControlButton = (function (_super) { + __extends(VolumeControlButton, _super); + function VolumeControlButton(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.volumeToggleButton = new volumetogglebutton_1.VolumeToggleButton(); + _this.volumeSlider = new volumeslider_1.VolumeSlider({ + vertical: config.vertical != null ? config.vertical : true, + hidden: true, + }); + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-volumecontrolbutton', + components: [_this.volumeToggleButton, _this.volumeSlider], + hideDelay: 500, + }, _this.config); + return _this; + } + VolumeControlButton.prototype.configure = function (player, uimanager) { + var _this = this; + _super.prototype.configure.call(this, player, uimanager); + var volumeToggleButton = this.getVolumeToggleButton(); + var volumeSlider = this.getVolumeSlider(); + this.volumeSliderHideTimeout = new timeout_1.Timeout(this.getConfig().hideDelay, function () { + volumeSlider.hide(); + }); + /* + * Volume Slider visibility handling + * + * The volume slider shall be visible while the user hovers the mute toggle button, while the user hovers the + * volume slider, and while the user slides the volume slider. If none of these situations are true, the slider + * shall disappear. + */ + var volumeSliderHovered = false; + volumeToggleButton.getDomElement().on('mouseenter', function () { + // Show volume slider when mouse enters the button area + if (volumeSlider.isHidden()) { + volumeSlider.show(); + } + // Avoid hiding of the slider when button is hovered + _this.volumeSliderHideTimeout.clear(); + }); + volumeToggleButton.getDomElement().on('mouseleave', function () { + // Hide slider delayed when button is left + _this.volumeSliderHideTimeout.reset(); + }); + volumeSlider.getDomElement().on('mouseenter', function () { + // When the slider is entered, cancel the hide timeout activated by leaving the button + _this.volumeSliderHideTimeout.clear(); + volumeSliderHovered = true; + }); + volumeSlider.getDomElement().on('mouseleave', function () { + // When mouse leaves the slider, only hide it if there is no slide operation in progress + if (volumeSlider.isSeeking()) { + _this.volumeSliderHideTimeout.clear(); + } + else { + _this.volumeSliderHideTimeout.reset(); + } + volumeSliderHovered = false; + }); + volumeSlider.onSeeked.subscribe(function () { + // When a slide operation is done and the slider not hovered (mouse outside slider), hide slider delayed + if (!volumeSliderHovered) { + _this.volumeSliderHideTimeout.reset(); + } + }); + }; + VolumeControlButton.prototype.release = function () { + _super.prototype.release.call(this); + this.volumeSliderHideTimeout.clear(); + }; + /** + * Provides access to the internally managed volume toggle button. + * @returns {VolumeToggleButton} + */ + VolumeControlButton.prototype.getVolumeToggleButton = function () { + return this.volumeToggleButton; + }; + /** + * Provides access to the internally managed volume silder. + * @returns {VolumeSlider} + */ + VolumeControlButton.prototype.getVolumeSlider = function () { + return this.volumeSlider; + }; + return VolumeControlButton; +}(container_1.Container)); +exports.VolumeControlButton = VolumeControlButton; /***/ }), @@ -3791,123 +3791,123 @@ exports.VolumeControlButton = VolumeControlButton; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var seekbar_1 = __webpack_require__(13); -/** - * A simple volume slider component to adjust the player's volume setting. - */ -var VolumeSlider = (function (_super) { - __extends(VolumeSlider, _super); - function VolumeSlider(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-volumeslider', - hideIfVolumeControlProhibited: true, - }, _this.config); - return _this; - } - VolumeSlider.prototype.configure = function (player, uimanager) { - var _this = this; - _super.prototype.configure.call(this, player, uimanager, false); - var config = this.getConfig(); - if (config.hideIfVolumeControlProhibited && !this.detectVolumeControlAvailability(player)) { - this.hide(); - // We can just return from here, because the user will never interact with the control and any configured - // functionality would only eat resources for no reason. - return; - } - var volumeChangeHandler = function () { - if (player.isMuted()) { - _this.setPlaybackPosition(0); - _this.setBufferPosition(0); - } - else { - _this.setPlaybackPosition(player.getVolume()); - _this.setBufferPosition(player.getVolume()); - } - }; - player.addEventHandler(player.EVENT.ON_READY, volumeChangeHandler); - player.addEventHandler(player.EVENT.ON_VOLUME_CHANGED, volumeChangeHandler); - player.addEventHandler(player.EVENT.ON_MUTED, volumeChangeHandler); - player.addEventHandler(player.EVENT.ON_UNMUTED, volumeChangeHandler); - this.onSeekPreview.subscribeRateLimited(function (sender, args) { - if (args.scrubbing) { - player.setVolume(args.position, VolumeSlider.issuerName); - } - }, 50); - this.onSeeked.subscribe(function (sender, percentage) { - player.setVolume(percentage, VolumeSlider.issuerName); - }); - // Update the volume slider marker when the player resized, a source is loaded and player is ready, - // or the UI is configured. Check the seekbar for a detailed description. - player.addEventHandler(player.EVENT.ON_PLAYER_RESIZE, function () { - _this.refreshPlaybackPosition(); - }); - player.addEventHandler(player.EVENT.ON_READY, function () { - _this.refreshPlaybackPosition(); - }); - uimanager.onConfigured.subscribe(function () { - _this.refreshPlaybackPosition(); - }); - // Init volume bar - volumeChangeHandler(); - }; - VolumeSlider.prototype.detectVolumeControlAvailability = function (player) { - // Store current player state so we can restore it later - var volume = player.getVolume(); - var muted = player.isMuted(); - var playing = player.isPlaying(); - /* - * "On iOS devices, the audio level is always under the user’s physical control. The volume property is not - * settable in JavaScript. Reading the volume property always returns 1." - * https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html - * - * Our player API returns a volume range of [0, 100] so we need to check for 100 instead of 1. - */ - // Only if the volume is 100, there's the possibility we are on a volume-control-restricted iOS device - if (volume === 100) { - // We set the volume to zero (that's the only value that does not unmute a muted player!) - player.setVolume(0, VolumeSlider.issuerName); - // Then we check if the value is still 100 - if (player.getVolume() === 100) { - // If the volume stayed at 100, we're on a volume-control-restricted device - return false; - } - else { - // We can control volume, so we must restore the previous player state - player.setVolume(volume, VolumeSlider.issuerName); - if (muted) { - player.mute(VolumeSlider.issuerName); - } - if (playing) { - // The volume restore above pauses autoplay on mobile devices (e.g. Android) so we need to resume playback - // (We cannot check isPaused() here because it is not set when playback is prohibited by the mobile platform) - player.play(VolumeSlider.issuerName); - } - return true; - } - } - else { - // Volume is not 100, so we're definitely not on a volume-control-restricted iOS device - return true; - } - }; - return VolumeSlider; -}(seekbar_1.SeekBar)); -VolumeSlider.issuerName = 'ui'; -exports.VolumeSlider = VolumeSlider; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var seekbar_1 = __webpack_require__(13); +/** + * A simple volume slider component to adjust the player's volume setting. + */ +var VolumeSlider = (function (_super) { + __extends(VolumeSlider, _super); + function VolumeSlider(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-volumeslider', + hideIfVolumeControlProhibited: true, + }, _this.config); + return _this; + } + VolumeSlider.prototype.configure = function (player, uimanager) { + var _this = this; + _super.prototype.configure.call(this, player, uimanager, false); + var config = this.getConfig(); + if (config.hideIfVolumeControlProhibited && !this.detectVolumeControlAvailability(player)) { + this.hide(); + // We can just return from here, because the user will never interact with the control and any configured + // functionality would only eat resources for no reason. + return; + } + var volumeChangeHandler = function () { + if (player.isMuted()) { + _this.setPlaybackPosition(0); + _this.setBufferPosition(0); + } + else { + _this.setPlaybackPosition(player.getVolume()); + _this.setBufferPosition(player.getVolume()); + } + }; + player.addEventHandler(player.EVENT.ON_READY, volumeChangeHandler); + player.addEventHandler(player.EVENT.ON_VOLUME_CHANGED, volumeChangeHandler); + player.addEventHandler(player.EVENT.ON_MUTED, volumeChangeHandler); + player.addEventHandler(player.EVENT.ON_UNMUTED, volumeChangeHandler); + this.onSeekPreview.subscribeRateLimited(function (sender, args) { + if (args.scrubbing) { + player.setVolume(args.position, VolumeSlider.issuerName); + } + }, 50); + this.onSeeked.subscribe(function (sender, percentage) { + player.setVolume(percentage, VolumeSlider.issuerName); + }); + // Update the volume slider marker when the player resized, a source is loaded and player is ready, + // or the UI is configured. Check the seekbar for a detailed description. + player.addEventHandler(player.EVENT.ON_PLAYER_RESIZE, function () { + _this.refreshPlaybackPosition(); + }); + player.addEventHandler(player.EVENT.ON_READY, function () { + _this.refreshPlaybackPosition(); + }); + uimanager.onConfigured.subscribe(function () { + _this.refreshPlaybackPosition(); + }); + // Init volume bar + volumeChangeHandler(); + }; + VolumeSlider.prototype.detectVolumeControlAvailability = function (player) { + // Store current player state so we can restore it later + var volume = player.getVolume(); + var muted = player.isMuted(); + var playing = player.isPlaying(); + /* + * "On iOS devices, the audio level is always under the user’s physical control. The volume property is not + * settable in JavaScript. Reading the volume property always returns 1." + * https://developer.apple.com/library/content/documentation/AudioVideo/Conceptual/Using_HTML5_Audio_Video/Device-SpecificConsiderations/Device-SpecificConsiderations.html + * + * Our player API returns a volume range of [0, 100] so we need to check for 100 instead of 1. + */ + // Only if the volume is 100, there's the possibility we are on a volume-control-restricted iOS device + if (volume === 100) { + // We set the volume to zero (that's the only value that does not unmute a muted player!) + player.setVolume(0, VolumeSlider.issuerName); + // Then we check if the value is still 100 + if (player.getVolume() === 100) { + // If the volume stayed at 100, we're on a volume-control-restricted device + return false; + } + else { + // We can control volume, so we must restore the previous player state + player.setVolume(volume, VolumeSlider.issuerName); + if (muted) { + player.mute(VolumeSlider.issuerName); + } + if (playing) { + // The volume restore above pauses autoplay on mobile devices (e.g. Android) so we need to resume playback + // (We cannot check isPaused() here because it is not set when playback is prohibited by the mobile platform) + player.play(VolumeSlider.issuerName); + } + return true; + } + } + else { + // Volume is not 100, so we're definitely not on a volume-control-restricted iOS device + return true; + } + }; + return VolumeSlider; +}(seekbar_1.SeekBar)); +VolumeSlider.issuerName = 'ui'; +exports.VolumeSlider = VolumeSlider; /***/ }), @@ -3915,71 +3915,71 @@ exports.VolumeSlider = VolumeSlider; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var togglebutton_1 = __webpack_require__(8); -/** - * A button that toggles audio muting. - */ -var VolumeToggleButton = (function (_super) { - __extends(VolumeToggleButton, _super); - function VolumeToggleButton(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-volumetogglebutton', - text: 'Volume/Mute', - }, _this.config); - return _this; - } - VolumeToggleButton.prototype.configure = function (player, uimanager) { - var _this = this; - _super.prototype.configure.call(this, player, uimanager); - var muteStateHandler = function () { - if (player.isMuted()) { - _this.on(); - } - else { - _this.off(); - } - }; - var volumeLevelHandler = function () { - // Toggle low class to display low volume icon below 50% volume - if (player.getVolume() < 50) { - _this.getDomElement().addClass(_this.prefixCss('low')); - } - else { - _this.getDomElement().removeClass(_this.prefixCss('low')); - } - }; - player.addEventHandler(player.EVENT.ON_MUTED, muteStateHandler); - player.addEventHandler(player.EVENT.ON_UNMUTED, muteStateHandler); - player.addEventHandler(player.EVENT.ON_VOLUME_CHANGED, volumeLevelHandler); - this.onClick.subscribe(function () { - if (player.isMuted()) { - player.unmute('ui-volumetogglebutton'); - } - else { - player.mute('ui-volumetogglebutton'); - } - }); - // Startup init - muteStateHandler(); - volumeLevelHandler(); - }; - return VolumeToggleButton; -}(togglebutton_1.ToggleButton)); -exports.VolumeToggleButton = VolumeToggleButton; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var togglebutton_1 = __webpack_require__(8); +/** + * A button that toggles audio muting. + */ +var VolumeToggleButton = (function (_super) { + __extends(VolumeToggleButton, _super); + function VolumeToggleButton(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-volumetogglebutton', + text: 'Volume/Mute', + }, _this.config); + return _this; + } + VolumeToggleButton.prototype.configure = function (player, uimanager) { + var _this = this; + _super.prototype.configure.call(this, player, uimanager); + var muteStateHandler = function () { + if (player.isMuted()) { + _this.on(); + } + else { + _this.off(); + } + }; + var volumeLevelHandler = function () { + // Toggle low class to display low volume icon below 50% volume + if (player.getVolume() < 50) { + _this.getDomElement().addClass(_this.prefixCss('low')); + } + else { + _this.getDomElement().removeClass(_this.prefixCss('low')); + } + }; + player.addEventHandler(player.EVENT.ON_MUTED, muteStateHandler); + player.addEventHandler(player.EVENT.ON_UNMUTED, muteStateHandler); + player.addEventHandler(player.EVENT.ON_VOLUME_CHANGED, volumeLevelHandler); + this.onClick.subscribe(function () { + if (player.isMuted()) { + player.unmute('ui-volumetogglebutton'); + } + else { + player.mute('ui-volumetogglebutton'); + } + }); + // Startup init + muteStateHandler(); + volumeLevelHandler(); + }; + return VolumeToggleButton; +}(togglebutton_1.ToggleButton)); +exports.VolumeToggleButton = VolumeToggleButton; /***/ }), @@ -3987,81 +3987,81 @@ exports.VolumeToggleButton = VolumeToggleButton; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var container_1 = __webpack_require__(1); -var label_1 = __webpack_require__(7); -var tvnoisecanvas_1 = __webpack_require__(41); -/** - * Overlays the player and displays error messages. - */ -var ErrorMessageOverlay = (function (_super) { - __extends(ErrorMessageOverlay, _super); - function ErrorMessageOverlay(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.errorLabel = new label_1.Label({ cssClass: 'ui-errormessage-label' }); - _this.tvNoiseBackground = new tvnoisecanvas_1.TvNoiseCanvas(); - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-errormessage-overlay', - components: [_this.tvNoiseBackground, _this.errorLabel], - hidden: true, - }, _this.config); - return _this; - } - ErrorMessageOverlay.prototype.configure = function (player, uimanager) { - var _this = this; - _super.prototype.configure.call(this, player, uimanager); - var config = this.getConfig(); - player.addEventHandler(player.EVENT.ON_ERROR, function (event) { - var message = event.message; - // Process message translations - if (config.messages) { - if (typeof config.messages === 'function') { - // Translation function for all errors - message = config.messages(event); - } - else if (config.messages[event.code]) { - // It's not a translation function, so it must be a map of strings or translation functions - var customMessage = config.messages[event.code]; - if (typeof customMessage === 'string') { - message = customMessage; - } - else { - // The message is a translation function, so we call it - message = customMessage(event); - } - } - } - _this.errorLabel.setText(message); - _this.tvNoiseBackground.start(); - _this.show(); - }); - player.addEventHandler(player.EVENT.ON_SOURCE_LOADED, function (event) { - if (_this.isShown()) { - _this.tvNoiseBackground.stop(); - _this.hide(); - } - }); - }; - ErrorMessageOverlay.prototype.release = function () { - _super.prototype.release.call(this); - // Canvas rendering must be explicitly stopped, else it just continues forever and hogs resources - this.tvNoiseBackground.stop(); - }; - return ErrorMessageOverlay; -}(container_1.Container)); -exports.ErrorMessageOverlay = ErrorMessageOverlay; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var container_1 = __webpack_require__(1); +var label_1 = __webpack_require__(7); +var tvnoisecanvas_1 = __webpack_require__(41); +/** + * Overlays the player and displays error messages. + */ +var ErrorMessageOverlay = (function (_super) { + __extends(ErrorMessageOverlay, _super); + function ErrorMessageOverlay(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.errorLabel = new label_1.Label({ cssClass: 'ui-errormessage-label' }); + _this.tvNoiseBackground = new tvnoisecanvas_1.TvNoiseCanvas(); + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-errormessage-overlay', + components: [_this.tvNoiseBackground, _this.errorLabel], + hidden: true, + }, _this.config); + return _this; + } + ErrorMessageOverlay.prototype.configure = function (player, uimanager) { + var _this = this; + _super.prototype.configure.call(this, player, uimanager); + var config = this.getConfig(); + player.addEventHandler(player.EVENT.ON_ERROR, function (event) { + var message = event.message; + // Process message translations + if (config.messages) { + if (typeof config.messages === 'function') { + // Translation function for all errors + message = config.messages(event); + } + else if (config.messages[event.code]) { + // It's not a translation function, so it must be a map of strings or translation functions + var customMessage = config.messages[event.code]; + if (typeof customMessage === 'string') { + message = customMessage; + } + else { + // The message is a translation function, so we call it + message = customMessage(event); + } + } + } + _this.errorLabel.setText(message); + _this.tvNoiseBackground.start(); + _this.show(); + }); + player.addEventHandler(player.EVENT.ON_SOURCE_LOADED, function (event) { + if (_this.isShown()) { + _this.tvNoiseBackground.stop(); + _this.hide(); + } + }); + }; + ErrorMessageOverlay.prototype.release = function () { + _super.prototype.release.call(this); + // Canvas rendering must be explicitly stopped, else it just continues forever and hogs resources + this.tvNoiseBackground.stop(); + }; + return ErrorMessageOverlay; +}(container_1.Container)); +exports.ErrorMessageOverlay = ErrorMessageOverlay; /***/ }), @@ -4069,38 +4069,38 @@ exports.ErrorMessageOverlay = ErrorMessageOverlay; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var container_1 = __webpack_require__(1); -var hugeplaybacktogglebutton_1 = __webpack_require__(28); -/** - * Overlays the player and displays error messages. - */ -var PlaybackToggleOverlay = (function (_super) { - __extends(PlaybackToggleOverlay, _super); - function PlaybackToggleOverlay(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.playbackToggleButton = new hugeplaybacktogglebutton_1.HugePlaybackToggleButton(); - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-playbacktoggle-overlay', - components: [_this.playbackToggleButton], - }, _this.config); - return _this; - } - return PlaybackToggleOverlay; -}(container_1.Container)); -exports.PlaybackToggleOverlay = PlaybackToggleOverlay; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var container_1 = __webpack_require__(1); +var hugeplaybacktogglebutton_1 = __webpack_require__(28); +/** + * Overlays the player and displays error messages. + */ +var PlaybackToggleOverlay = (function (_super) { + __extends(PlaybackToggleOverlay, _super); + function PlaybackToggleOverlay(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.playbackToggleButton = new hugeplaybacktogglebutton_1.HugePlaybackToggleButton(); + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-playbacktoggle-overlay', + components: [_this.playbackToggleButton], + }, _this.config); + return _this; + } + return PlaybackToggleOverlay; +}(container_1.Container)); +exports.PlaybackToggleOverlay = PlaybackToggleOverlay; /***/ }), @@ -4108,141 +4108,141 @@ exports.PlaybackToggleOverlay = PlaybackToggleOverlay; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var playbacktogglebutton_1 = __webpack_require__(12); -var dom_1 = __webpack_require__(0); -/** - * A button that overlays the video and toggles between playback and pause. - */ -var HugePlaybackToggleButton = (function (_super) { - __extends(HugePlaybackToggleButton, _super); - function HugePlaybackToggleButton(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-hugeplaybacktogglebutton', - text: 'Play/Pause', - }, _this.config); - return _this; - } - HugePlaybackToggleButton.prototype.configure = function (player, uimanager) { - var _this = this; - // Update button state through API events - _super.prototype.configure.call(this, player, uimanager, false); - var togglePlayback = function () { - if (player.isPlaying()) { - player.pause('ui'); - } - else { - player.play('ui'); - } - }; - var toggleFullscreen = function () { - if (player.isFullscreen()) { - player.exitFullscreen(); - } - else { - player.enterFullscreen(); - } - }; - var firstPlay = true; - var clickTime = 0; - var doubleClickTime = 0; - /* - * YouTube-style toggle button handling - * - * The goal is to prevent a short pause or playback interval between a click, that toggles playback, and a - * double click, that toggles fullscreen. In this naive approach, the first click would e.g. start playback, - * the second click would be detected as double click and toggle to fullscreen, and as second normal click stop - * playback, which results is a short playback interval with max length of the double click detection - * period (usually 500ms). - * - * To solve this issue, we defer handling of the first click for 200ms, which is almost unnoticeable to the user, - * and just toggle playback if no second click (double click) has been registered during this period. If a double - * click is registered, we just toggle the fullscreen. In the first 200ms, undesired playback changes thus cannot - * happen. If a double click is registered within 500ms, we undo the playback change and switch fullscreen mode. - * In the end, this method basically introduces a 200ms observing interval in which playback changes are prevented - * if a double click happens. - */ - this.onClick.subscribe(function () { - // Directly start playback on first click of the button. - // This is a required workaround for mobile browsers where video playback needs to be triggered directly - // by the user. A deferred playback start through the timeout below is not considered as user action and - // therefore ignored by mobile browsers. - if (firstPlay) { - // Try to start playback. Then we wait for ON_PLAY and only when it arrives, we disable the firstPlay flag. - // If we disable the flag here, onClick was triggered programmatically instead of by a user interaction, and - // playback is blocked (e.g. on mobile devices due to the programmatic play() call), we loose the chance to - // ever start playback through a user interaction again with this button. - togglePlayback(); - return; - } - var now = Date.now(); - if (now - clickTime < 200) { - // We have a double click inside the 200ms interval, just toggle fullscreen mode - toggleFullscreen(); - doubleClickTime = now; - return; - } - else if (now - clickTime < 500) { - // We have a double click inside the 500ms interval, undo playback toggle and toggle fullscreen mode - toggleFullscreen(); - togglePlayback(); - doubleClickTime = now; - return; - } - clickTime = now; - setTimeout(function () { - if (Date.now() - doubleClickTime > 200) { - // No double click detected, so we toggle playback and wait what happens next - togglePlayback(); - } - }, 200); - }); - player.addEventHandler(player.EVENT.ON_PLAY, function () { - // Playback has really started, we can disable the flag to switch to normal toggle button handling - firstPlay = false; - }); - // Hide button while initializing a Cast session - var castInitializationHandler = function (event) { - if (event.type === player.EVENT.ON_CAST_START) { - // Hide button when session is being initialized - _this.hide(); - } - else { - // Show button when session is established or initialization was aborted - _this.show(); - } - }; - player.addEventHandler(player.EVENT.ON_CAST_START, castInitializationHandler); - player.addEventHandler(player.EVENT.ON_CAST_STARTED, castInitializationHandler); - player.addEventHandler(player.EVENT.ON_CAST_STOPPED, castInitializationHandler); - }; - HugePlaybackToggleButton.prototype.toDomElement = function () { - var buttonElement = _super.prototype.toDomElement.call(this); - // Add child that contains the play button image - // Setting the image directly on the button does not work together with scaling animations, because the button - // can cover the whole video player are and scaling would extend it beyond. By adding an inner element, confined - // to the size if the image, it can scale inside the player without overshooting. - buttonElement.append(new dom_1.DOM('div', { - 'class': this.prefixCss('image'), - })); - return buttonElement; - }; - return HugePlaybackToggleButton; -}(playbacktogglebutton_1.PlaybackToggleButton)); -exports.HugePlaybackToggleButton = HugePlaybackToggleButton; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var playbacktogglebutton_1 = __webpack_require__(12); +var dom_1 = __webpack_require__(0); +/** + * A button that overlays the video and toggles between playback and pause. + */ +var HugePlaybackToggleButton = (function (_super) { + __extends(HugePlaybackToggleButton, _super); + function HugePlaybackToggleButton(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-hugeplaybacktogglebutton', + text: 'Play/Pause', + }, _this.config); + return _this; + } + HugePlaybackToggleButton.prototype.configure = function (player, uimanager) { + var _this = this; + // Update button state through API events + _super.prototype.configure.call(this, player, uimanager, false); + var togglePlayback = function () { + if (player.isPlaying()) { + player.pause('ui'); + } + else { + player.play('ui'); + } + }; + var toggleFullscreen = function () { + if (player.isFullscreen()) { + player.exitFullscreen(); + } + else { + player.enterFullscreen(); + } + }; + var firstPlay = true; + var clickTime = 0; + var doubleClickTime = 0; + /* + * YouTube-style toggle button handling + * + * The goal is to prevent a short pause or playback interval between a click, that toggles playback, and a + * double click, that toggles fullscreen. In this naive approach, the first click would e.g. start playback, + * the second click would be detected as double click and toggle to fullscreen, and as second normal click stop + * playback, which results is a short playback interval with max length of the double click detection + * period (usually 500ms). + * + * To solve this issue, we defer handling of the first click for 200ms, which is almost unnoticeable to the user, + * and just toggle playback if no second click (double click) has been registered during this period. If a double + * click is registered, we just toggle the fullscreen. In the first 200ms, undesired playback changes thus cannot + * happen. If a double click is registered within 500ms, we undo the playback change and switch fullscreen mode. + * In the end, this method basically introduces a 200ms observing interval in which playback changes are prevented + * if a double click happens. + */ + this.onClick.subscribe(function () { + // Directly start playback on first click of the button. + // This is a required workaround for mobile browsers where video playback needs to be triggered directly + // by the user. A deferred playback start through the timeout below is not considered as user action and + // therefore ignored by mobile browsers. + if (firstPlay) { + // Try to start playback. Then we wait for ON_PLAY and only when it arrives, we disable the firstPlay flag. + // If we disable the flag here, onClick was triggered programmatically instead of by a user interaction, and + // playback is blocked (e.g. on mobile devices due to the programmatic play() call), we loose the chance to + // ever start playback through a user interaction again with this button. + togglePlayback(); + return; + } + var now = Date.now(); + if (now - clickTime < 200) { + // We have a double click inside the 200ms interval, just toggle fullscreen mode + toggleFullscreen(); + doubleClickTime = now; + return; + } + else if (now - clickTime < 500) { + // We have a double click inside the 500ms interval, undo playback toggle and toggle fullscreen mode + toggleFullscreen(); + togglePlayback(); + doubleClickTime = now; + return; + } + clickTime = now; + setTimeout(function () { + if (Date.now() - doubleClickTime > 200) { + // No double click detected, so we toggle playback and wait what happens next + togglePlayback(); + } + }, 200); + }); + player.addEventHandler(player.EVENT.ON_PLAY, function () { + // Playback has really started, we can disable the flag to switch to normal toggle button handling + firstPlay = false; + }); + // Hide button while initializing a Cast session + var castInitializationHandler = function (event) { + if (event.type === player.EVENT.ON_CAST_START) { + // Hide button when session is being initialized + _this.hide(); + } + else { + // Show button when session is established or initialization was aborted + _this.show(); + } + }; + player.addEventHandler(player.EVENT.ON_CAST_START, castInitializationHandler); + player.addEventHandler(player.EVENT.ON_CAST_STARTED, castInitializationHandler); + player.addEventHandler(player.EVENT.ON_CAST_STOPPED, castInitializationHandler); + }; + HugePlaybackToggleButton.prototype.toDomElement = function () { + var buttonElement = _super.prototype.toDomElement.call(this); + // Add child that contains the play button image + // Setting the image directly on the button does not work together with scaling animations, because the button + // can cover the whole video player are and scaling would extend it beyond. By adding an inner element, confined + // to the size if the image, it can scale inside the player without overshooting. + buttonElement.append(new dom_1.DOM('div', { + 'class': this.prefixCss('image'), + })); + return buttonElement; + }; + return HugePlaybackToggleButton; +}(playbacktogglebutton_1.PlaybackToggleButton)); +exports.HugePlaybackToggleButton = HugePlaybackToggleButton; /***/ }), @@ -4250,60 +4250,60 @@ exports.HugePlaybackToggleButton = HugePlaybackToggleButton; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var container_1 = __webpack_require__(1); -var component_1 = __webpack_require__(2); -// import PlayerEvent = bitmovin.PlayerAPI.PlayerEvent; -/** - * Overlays the player and displays an audio-only indicator. - */ -var AudioOnlyOverlay = (function (_super) { - __extends(AudioOnlyOverlay, _super); - function AudioOnlyOverlay(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.audioonly = [ - new component_1.Component({ tag: 'div', cssClass: 'ui-audioonly-overlay-indicator' }), - ]; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-audioonly-overlay', - components: _this.audioonly, - hidden: false, - }, _this.config); - return _this; - } - AudioOnlyOverlay.prototype.configure = function (player, uimanager) { - _super.prototype.configure.call(this, player, uimanager); - var self = this; - var image = self.getDomElement().css('background-image'); - // Hide overlay when Player is paused, so we can see the Big Play Button - // player.addEventHandler(player.EVENT.ON_PAUSED, (event) => { - // self.getDomElement().css('background-image', 'none'); - // }); - // - // player.addEventHandler(player.EVENT.ON_PLAY, (event) => { - // self.getDomElement().css('background-image', image); - // }); - // - // // Hide overlay if player is paused at init (e.g. on mobile devices) - // if (!player.isPlaying()) { - // self.getDomElement().css('background-image', 'none'); - // } - }; - return AudioOnlyOverlay; -}(container_1.Container)); -exports.AudioOnlyOverlay = AudioOnlyOverlay; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var container_1 = __webpack_require__(1); +var component_1 = __webpack_require__(2); +// import PlayerEvent = bitmovin.PlayerAPI.PlayerEvent; +/** + * Overlays the player and displays an audio-only indicator. + */ +var AudioOnlyOverlay = (function (_super) { + __extends(AudioOnlyOverlay, _super); + function AudioOnlyOverlay(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.audioonly = [ + new component_1.Component({ tag: 'div', cssClass: 'ui-audioonly-overlay-indicator' }), + ]; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-audioonly-overlay', + components: _this.audioonly, + hidden: false, + }, _this.config); + return _this; + } + AudioOnlyOverlay.prototype.configure = function (player, uimanager) { + _super.prototype.configure.call(this, player, uimanager); + var self = this; + var image = self.getDomElement().css('background-image'); + // Hide overlay when Player is paused, so we can see the Big Play Button + // player.addEventHandler(player.EVENT.ON_PAUSED, (event) => { + // self.getDomElement().css('background-image', 'none'); + // }); + // + // player.addEventHandler(player.EVENT.ON_PLAY, (event) => { + // self.getDomElement().css('background-image', image); + // }); + // + // // Hide overlay if player is paused at init (e.g. on mobile devices) + // if (!player.isPlaying()) { + // self.getDomElement().css('background-image', 'none'); + // } + }; + return AudioOnlyOverlay; +}(container_1.Container)); +exports.AudioOnlyOverlay = AudioOnlyOverlay; /***/ }), @@ -4320,14 +4320,14 @@ module.exports = __webpack_require__(47); /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var angular = __webpack_require__(9); -var bitdash_controller_1 = __webpack_require__(32); -var bitdash_directive_1 = __webpack_require__(33); -exports.default = angular.module('mi.BitdashPlayer', []) - .controller('MiBitdashController', bitdash_controller_1.default) - .directive('miBitdashPlayer', bitdash_directive_1.default); + +Object.defineProperty(exports, "__esModule", { value: true }); +var angular = __webpack_require__(9); +var bitdash_controller_1 = __webpack_require__(32); +var bitdash_directive_1 = __webpack_require__(33); +exports.default = angular.module('mi.BitdashPlayer', []) + .controller('MiBitdashController', bitdash_controller_1.default) + .directive('miBitdashPlayer', bitdash_directive_1.default); /***/ }), @@ -4335,95 +4335,107 @@ exports.default = angular.module('mi.BitdashPlayer', []) /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var angular = __webpack_require__(9); -var BitmovinController = (function () { - function BitmovinController($scope, $log) { - this.$scope = $scope; - this.$log = $log; - this.config = {}; - this.options = {}; - this.$scope = $scope; - this.$log = $log; - } - BitmovinController.prototype.$onInit = function () { - if (angular.isDefined(this.$scope.config) && angular.isDefined(this.$scope.config.key)) { - this.config = this.$scope.config; - } - else { - this.$log.error("basic config for bitdash player is missing!"); - } - if (angular.isDefined(this.$scope.options)) { - this.options = this.$scope.options; - } - if (angular.isDefined(this.$scope.webcast)) { - this.processWebcast(this.$scope.webcast); - } - }; - BitmovinController.prototype.processWebcast = function (webcast) { - var stateProperty = webcast.state + "StateData"; - if (angular.isDefined(this.options.forcedState)) { - stateProperty = this.options.forcedState + "StateData"; - } - this.config.source = this.getPlayerConfigSource(webcast, stateProperty); - this.config.style = { ux: false }; - }; - BitmovinController.prototype.getPlayerConfigSource = function (webcast, state) { - if ((webcast.useDVRPlaybackInPostlive === true) && (state === 'postliveStateData')) { - return this.getDVRPlaybackToPostlive(webcast); - } - return this.getPlayerConfigSourceByState(webcast, state); - }; - BitmovinController.prototype.getDVRPlaybackToPostlive = function (webcast) { - var hls = webcast['liveStateData'].playout.hlsDvrUrl; - var title = webcast.name; - if (angular.isDefined(webcast['postliveStateData'].playout.offset)) { - var offset = parseInt(webcast['postliveStateData'].playout.offset, 10); - if (offset > 0) { - var offsetPrefix = void 0; - var parser = document.createElement('a'); - parser.href = webcast['liveStateData'].playout.hlsDvrUrl; - offsetPrefix = (parser.search) ? '&' : '?'; - hls += offsetPrefix + "wowzadvrplayliststart=" + offset + "000"; - } - } - return { hls: hls, title: title }; - }; - BitmovinController.prototype.getPlayerConfigSourceByState = function (webcast, state) { - var hls = webcast[state].playout.hlsUrl; - var title = webcast.name; - var hiveServiceUrl = this.getHiveServiceUrlByLang(webcast); - if (angular.isDefined(webcast[state].playout.videoManagerHlsUrl) && webcast[state].playout.videoManagerHlsUrl) { - hls = webcast[state].playout.videoManagerHlsUrl; - } - if (angular.isDefined(webcast[state].playout.offset)) { - var offset = parseInt(webcast[state].playout.offset, 10); - if (offset > 0) { - var offsetPrefix = void 0; - var parser = document.createElement('a'); - parser.href = hls; - offsetPrefix = (parser.search) ? '&' : '?'; - hls += offsetPrefix + "start=" + offset; - } - } - return { hls: hls, title: title, hiveServiceUrl: hiveServiceUrl }; - }; - BitmovinController.prototype.getHiveServiceUrlByLang = function (webcast) { - var hiveServiceUrl = null; - if (webcast.languages && webcast.language) { - webcast.languages.forEach(function (item) { - if (item.language === webcast.language) { - hiveServiceUrl = angular.copy(item.hiveServiceUrl); - } - }); - } - return hiveServiceUrl; - }; - return BitmovinController; -}()); -BitmovinController.$inject = ['$scope', '$log']; -exports.default = BitmovinController; + +Object.defineProperty(exports, "__esModule", { value: true }); +var angular = __webpack_require__(9); +var BitmovinController = (function () { + function BitmovinController($scope, $log) { + this.$scope = $scope; + this.$log = $log; + this.state = {}; + this.config = {}; + this.options = {}; + } + BitmovinController.prototype.$onInit = function () { + this.state = this.$scope.state = {}; + if (angular.isDefined(this.$scope.config) && angular.isDefined(this.$scope.config.key)) { + this.config = this.$scope.config; + } + else { + this.$log.error("basic config for bitdash player is missing!"); + } + if (angular.isDefined(this.$scope.options)) { + this.options = this.$scope.options; + } + if (angular.isDefined(this.$scope.webcast)) { + this.processWebcast(this.$scope.webcast); + } + }; + BitmovinController.prototype.processWebcast = function (webcast) { + var stateProperty = webcast.state + "StateData"; + if (angular.isDefined(this.options.forcedState)) { + stateProperty = this.options.forcedState + "StateData"; + } + if (webcast.state === 'ondemand') { + var languageIndex_1 = 0; + webcast.languages.some(function (lang, index) { + if (webcast.language === lang.language) { + languageIndex_1 = index; + return true; + } + }); + this.state.data = webcast.languages[languageIndex_1].ondemandStateData; + } + else { + this.state.data = webcast[stateProperty]; + } + this.config.source = this.getPlayerConfigSource(webcast); + this.config.style = { ux: false }; + }; + BitmovinController.prototype.getPlayerConfigSource = function (webcast) { + return webcast.useDVRPlaybackInPostlive && webcast.state === 'postlive' ? + this.getDVRPlaybackToPostlive(webcast) + : this.getPlayerConfigSourceByState(webcast); + }; + BitmovinController.prototype.getDVRPlaybackToPostlive = function (webcast) { + var hls = webcast['liveStateData'].playout.hlsDvrUrl; + var title = webcast.name; + if (angular.isDefined(webcast['postliveStateData'].playout.offset)) { + var offset = parseInt(webcast['postliveStateData'].playout.offset, 10); + if (offset) { + var offsetPrefix = void 0; + var parser = document.createElement('a'); + parser.href = webcast['liveStateData'].playout.hlsDvrUrl; + offsetPrefix = (parser.search) ? '&' : '?'; + hls += offsetPrefix + "wowzadvrplayliststart=" + offset + "000"; + } + } + return { hls: hls, title: title }; + }; + BitmovinController.prototype.getPlayerConfigSourceByState = function (webcast) { + var hls = this.state.data.playout.hlsUrl; + var title = webcast.name; + var hiveServiceUrl = this.getHiveServiceUrlByLang(webcast); + if (angular.isDefined(this.state.data.playout.videoManagerHlsUrl) && this.state.data.playout.videoManagerHlsUrl) { + hls = this.state.data.playout.videoManagerHlsUrl; + } + if (angular.isDefined(this.state.data.playout.offset)) { + var offset = parseInt(this.state.data.playout.offset, 10); + if (offset > 0) { + var offsetPrefix = void 0; + var parser = document.createElement('a'); + parser.href = hls; + offsetPrefix = (parser.search) ? '&' : '?'; + hls += offsetPrefix + "start=" + offset; + } + } + return { hls: hls, title: title, hiveServiceUrl: hiveServiceUrl }; + }; + BitmovinController.prototype.getHiveServiceUrlByLang = function (webcast) { + var hiveServiceUrl = null; + if (webcast.languages && webcast.language) { + webcast.languages.forEach(function (item) { + if (item.language === webcast.language) { + hiveServiceUrl = angular.copy(item.hiveServiceUrl); + } + }); + } + return hiveServiceUrl; + }; + return BitmovinController; +}()); +BitmovinController.$inject = ['$scope', '$log']; +exports.default = BitmovinController; /***/ }), @@ -4431,94 +4443,94 @@ exports.default = BitmovinController; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var angular = __webpack_require__(9); -var BitdashDirective = function ($window, $log) { return ({ - controller: 'MiBitdashController', - controllerAs: 'bitdashVm', - replace: true, - restrict: 'EA', - scope: { - config: '=', - options: '=?', - webcast: '=', - }, - template: "
", - link: function (scope) { - var bitmovinPlayer; - var bitmovinUIManager; - var bitmovinControlbar; - var config = scope.config; - var webcast = scope.webcast; - var state = scope.webcast.state + "StateData"; - buildPlayer(); - function buildPlayer() { - bitmovinPlayer = $window.window.bitmovin.player('mi-bitdash-player'); - if (angular.isDefined(bitmovinPlayer) && bitmovinPlayer.isReady() === true) { - bitmovinPlayer.destroy(); - bitmovinPlayer = $window.window.bitmovin.player('mi-bitdash-player'); - } - if ((state === 'liveStateData') && config.source.hiveServiceUrl) { - // Get a hive-enabled player through bitdash.initHiveSDN - $window.window.bitmovin.initHiveSDN(bitmovinPlayer, { debugLevel: 'off' }); - // Configure and Setup bitmovin in initSession callback - bitmovinPlayer.initSession(config.source.hiveServiceUrl).then(function (session) { - var hiveConfig = angular.copy(config); - hiveConfig.source.hls = session.manifest; - loadPlayer(hiveConfig); - }, function (reason) { - // Handle the case if Hive init fails - $log.warn("Hive init fails: " + reason.code + " - " + reason.message); - loadPlayer(config); - }); - } - else { - loadPlayer(config); - } - } - function loadPlayer(conf) { - bitmovinPlayer - .setup(conf) - .then(function () { - bitmovinUIManager = $window.window.bitmovin.playerui.UIManager.Factory; - if (isAudioOnly()) { - bitmovinUIManager.buildAudioOnlyUI(bitmovinPlayer); - setAudioOnlyStillImage(); - } - else { - bitmovinUIManager.buildAudioVideoUI(bitmovinPlayer); - } - bitmovinControlbar = getElementsByClassName('bitmovinplayer-container'); - if (angular.isDefined(bitmovinControlbar)) { - bitmovinControlbar.style.minWidth = '175px'; - bitmovinControlbar.style.minHeight = '101px'; - document.getElementById('bitmovinplayer-video-mi-bitdash-player').setAttribute('title', webcast.name); - } - }, function (reason) { - $log.log("Error: " + reason.code + " - " + reason.message); - }); - } - function isAudioOnly() { - return angular.isDefined(scope.webcast[state].playout.audioOnly) && - scope.webcast[state].playout.audioOnly; - } - function setAudioOnlyStillImage() { - if (angular.isDefined(scope.webcast[state].playout.audioOnlyStillUrl) && - scope.webcast[state].playout.audioOnlyStillUrl !== '') { - var element = getElementsByClassName('mi-wbc-ui-audioonly-overlay'); - element.style.backgroundImage = "url(" + scope.webcast[state].playout.audioOnlyStillUrl + ")"; - element.style.backgroundSize = 'contain'; - element.style.backgroundPosition = 'center'; - } - } - function getElementsByClassName(className) { - return document.getElementsByClassName(className)[0]; - } - } -}); }; -exports.default = BitdashDirective; -BitdashDirective.$inject = ['$window', '$log']; + +Object.defineProperty(exports, "__esModule", { value: true }); +var angular = __webpack_require__(9); +var BitdashDirective = function ($window, $log) { return ({ + controller: 'MiBitdashController', + controllerAs: 'bitdashVm', + replace: true, + restrict: 'EA', + scope: { + config: '=', + options: '=?', + webcast: '=', + }, + template: "
", + link: function (scope) { + var bitmovinPlayer; + var bitmovinUIManager; + var bitmovinControlbar; + var config = scope.config; + var webcast = scope.webcast; + var stateData = scope.state.data; + buildPlayer(); + function buildPlayer() { + bitmovinPlayer = $window.window.bitmovin.player('mi-bitdash-player'); + if (angular.isDefined(bitmovinPlayer) && bitmovinPlayer.isReady() === true) { + bitmovinPlayer.destroy(); + bitmovinPlayer = $window.window.bitmovin.player('mi-bitdash-player'); + } + if ((webcast.state === 'live') && config.source.hiveServiceUrl) { + // Get a hive-enabled player through bitdash.initHiveSDN + $window.window.bitmovin.initHiveSDN(bitmovinPlayer, { debugLevel: 'off' }); + // Configure and Setup bitmovin in initSession callback + bitmovinPlayer.initSession(config.source.hiveServiceUrl).then(function (session) { + var hiveConfig = angular.copy(config); + hiveConfig.source.hls = session.manifest; + loadPlayer(hiveConfig); + }, function (reason) { + // Handle the case if Hive init fails + $log.warn("Hive init fails: " + reason.code + " - " + reason.message); + loadPlayer(config); + }); + } + else { + loadPlayer(config); + } + } + function loadPlayer(conf) { + bitmovinPlayer + .setup(conf) + .then(function () { + bitmovinUIManager = $window.window.bitmovin.playerui.UIManager.Factory; + if (isAudioOnly()) { + bitmovinUIManager.buildAudioOnlyUI(bitmovinPlayer); + setAudioOnlyStillImage(); + } + else { + bitmovinUIManager.buildAudioVideoUI(bitmovinPlayer); + } + bitmovinControlbar = getElementsByClassName('bitmovinplayer-container'); + if (angular.isDefined(bitmovinControlbar)) { + bitmovinControlbar.style.minWidth = '175px'; + bitmovinControlbar.style.minHeight = '101px'; + document.getElementById('bitmovinplayer-video-mi-bitdash-player').setAttribute('title', webcast.name); + } + }, function (reason) { + $log.log("Error: " + reason.code + " - " + reason.message); + }); + } + function isAudioOnly() { + return angular.isDefined(stateData.playout.audioOnly) && + stateData.playout.audioOnly; + } + function setAudioOnlyStillImage() { + if (angular.isDefined(stateData.playout.audioOnlyStillUrl) && + stateData.playout.audioOnlyStillUrl !== '') { + var element = getElementsByClassName('mi-wbc-ui-audioonly-overlay'); + element.style.backgroundImage = "url(" + stateData.playout.audioOnlyStillUrl + ")"; + element.style.backgroundSize = 'contain'; + element.style.backgroundPosition = 'center'; + } + } + function getElementsByClassName(className) { + return document.getElementsByClassName(className)[0]; + } + } +}); }; +exports.default = BitdashDirective; +BitdashDirective.$inject = ['$window', '$log']; /***/ }), @@ -4526,118 +4538,118 @@ BitdashDirective.$inject = ['$window', '$log']; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -/// -var uimanager_1 = __webpack_require__(35); -var button_1 = __webpack_require__(6); -var controlbar_1 = __webpack_require__(15); -var hugeplaybacktogglebutton_1 = __webpack_require__(28); -var playbacktimelabel_1 = __webpack_require__(18); -var playbacktogglebutton_1 = __webpack_require__(12); -var seekbar_1 = __webpack_require__(13); -var selectbox_1 = __webpack_require__(21); -var itemselectionlist_1 = __webpack_require__(42); -// import {SettingsPanel, SettingsPanelItem} from './components/settingspanel'; -// import {SettingsToggleButton} from './components/settingstogglebutton'; -var togglebutton_1 = __webpack_require__(8); -// import {VideoQualitySelectBox} from './components/videoqualityselectbox'; -var volumetogglebutton_1 = __webpack_require__(25); -// import {Watermark} from './components/watermark'; -var uicontainer_1 = __webpack_require__(17); -var container_1 = __webpack_require__(1); -var label_1 = __webpack_require__(7); -var component_1 = __webpack_require__(2); -var errormessageoverlay_1 = __webpack_require__(26); -var seekbarlabel_1 = __webpack_require__(20); -// import {TitleBar} from './components/titlebar'; -var volumecontrolbutton_1 = __webpack_require__(23); -var clickoverlay_1 = __webpack_require__(43); -var hugereplaybutton_1 = __webpack_require__(44); -// import {BufferingOverlay} from './components/bufferingoverlay'; -var playbacktoggleoverlay_1 = __webpack_require__(27); -var closebutton_1 = __webpack_require__(45); -// import {MetadataLabel, MetadataLabelContent} from './components/metadatalabel'; -var volumeslider_1 = __webpack_require__(24); -var spacer_1 = __webpack_require__(19); -var arrayutils_1 = __webpack_require__(4); -var stringutils_1 = __webpack_require__(14); -var playerutils_1 = __webpack_require__(5); -var uiutils_1 = __webpack_require__(16); -var browserutils_1 = __webpack_require__(11); -var storageutils_1 = __webpack_require__(46); -var audioonlyoverlay_1 = __webpack_require__(29); -// Object.assign polyfill for ES5/IE9 -// https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/assign -if (typeof Object.assign !== 'function') { - Object.assign = function (target) { - 'use strict'; - if (target == null) { - throw new TypeError('Cannot convert undefined or null to object'); - } - target = Object(target); - for (var index = 1; index < arguments.length; index++) { - var source = arguments[index]; - if (source != null) { - for (var key in source) { - if (Object.prototype.hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - } - return target; - }; -} -var playerui = { - version: '{{VERSION}}', - // Management - UIManager: uimanager_1.UIManager, - UIInstanceManager: uimanager_1.UIInstanceManager, - // Utils - ArrayUtils: arrayutils_1.ArrayUtils, - StringUtils: stringutils_1.StringUtils, - PlayerUtils: playerutils_1.PlayerUtils, - UIUtils: uiutils_1.UIUtils, - BrowserUtils: browserutils_1.BrowserUtils, - StorageUtils: storageutils_1.StorageUtils, - // Components - AudioOnlyOverlay: audioonlyoverlay_1.AudioOnlyOverlay, - // BufferingOverlay, - Button: button_1.Button, - ClickOverlay: clickoverlay_1.ClickOverlay, - CloseButton: closebutton_1.CloseButton, - Component: component_1.Component, - Container: container_1.Container, - ControlBar: controlbar_1.ControlBar, - ErrorMessageOverlay: errormessageoverlay_1.ErrorMessageOverlay, - HugePlaybackToggleButton: hugeplaybacktogglebutton_1.HugePlaybackToggleButton, - HugeReplayButton: hugereplaybutton_1.HugeReplayButton, - Label: label_1.Label, - // MetadataLabel, - // MetadataLabelContent, - PlaybackTimeLabel: playbacktimelabel_1.PlaybackTimeLabel, - PlaybackTimeLabelMode: playbacktimelabel_1.PlaybackTimeLabelMode, - PlaybackToggleButton: playbacktogglebutton_1.PlaybackToggleButton, - PlaybackToggleOverlay: playbacktoggleoverlay_1.PlaybackToggleOverlay, - SeekBar: seekbar_1.SeekBar, - SeekBarLabel: seekbarlabel_1.SeekBarLabel, - SelectBox: selectbox_1.SelectBox, - ItemSelectionList: itemselectionlist_1.ItemSelectionList, - // SettingsPanel, - // SettingsPanelItem, - // SettingsToggleButton, - Spacer: spacer_1.Spacer, - // TitleBar, - ToggleButton: togglebutton_1.ToggleButton, - UIContainer: uicontainer_1.UIContainer, - // VideoQualitySelectBox, - VolumeControlButton: volumecontrolbutton_1.VolumeControlButton, - VolumeSlider: volumeslider_1.VolumeSlider, - VolumeToggleButton: volumetogglebutton_1.VolumeToggleButton, -}; -window.bitmovin.playerui = playerui; -module.exports = playerui; + +Object.defineProperty(exports, "__esModule", { value: true }); +/// +var uimanager_1 = __webpack_require__(35); +var button_1 = __webpack_require__(6); +var controlbar_1 = __webpack_require__(15); +var hugeplaybacktogglebutton_1 = __webpack_require__(28); +var playbacktimelabel_1 = __webpack_require__(18); +var playbacktogglebutton_1 = __webpack_require__(12); +var seekbar_1 = __webpack_require__(13); +var selectbox_1 = __webpack_require__(21); +var itemselectionlist_1 = __webpack_require__(42); +// import {SettingsPanel, SettingsPanelItem} from './components/settingspanel'; +// import {SettingsToggleButton} from './components/settingstogglebutton'; +var togglebutton_1 = __webpack_require__(8); +// import {VideoQualitySelectBox} from './components/videoqualityselectbox'; +var volumetogglebutton_1 = __webpack_require__(25); +// import {Watermark} from './components/watermark'; +var uicontainer_1 = __webpack_require__(17); +var container_1 = __webpack_require__(1); +var label_1 = __webpack_require__(7); +var component_1 = __webpack_require__(2); +var errormessageoverlay_1 = __webpack_require__(26); +var seekbarlabel_1 = __webpack_require__(20); +// import {TitleBar} from './components/titlebar'; +var volumecontrolbutton_1 = __webpack_require__(23); +var clickoverlay_1 = __webpack_require__(43); +var hugereplaybutton_1 = __webpack_require__(44); +// import {BufferingOverlay} from './components/bufferingoverlay'; +var playbacktoggleoverlay_1 = __webpack_require__(27); +var closebutton_1 = __webpack_require__(45); +// import {MetadataLabel, MetadataLabelContent} from './components/metadatalabel'; +var volumeslider_1 = __webpack_require__(24); +var spacer_1 = __webpack_require__(19); +var arrayutils_1 = __webpack_require__(4); +var stringutils_1 = __webpack_require__(14); +var playerutils_1 = __webpack_require__(5); +var uiutils_1 = __webpack_require__(16); +var browserutils_1 = __webpack_require__(11); +var storageutils_1 = __webpack_require__(46); +var audioonlyoverlay_1 = __webpack_require__(29); +// Object.assign polyfill for ES5/IE9 +// https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/assign +if (typeof Object.assign !== 'function') { + Object.assign = function (target) { + 'use strict'; + if (target == null) { + throw new TypeError('Cannot convert undefined or null to object'); + } + target = Object(target); + for (var index = 1; index < arguments.length; index++) { + var source = arguments[index]; + if (source != null) { + for (var key in source) { + if (Object.prototype.hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + } + return target; + }; +} +var playerui = { + version: '{{VERSION}}', + // Management + UIManager: uimanager_1.UIManager, + UIInstanceManager: uimanager_1.UIInstanceManager, + // Utils + ArrayUtils: arrayutils_1.ArrayUtils, + StringUtils: stringutils_1.StringUtils, + PlayerUtils: playerutils_1.PlayerUtils, + UIUtils: uiutils_1.UIUtils, + BrowserUtils: browserutils_1.BrowserUtils, + StorageUtils: storageutils_1.StorageUtils, + // Components + AudioOnlyOverlay: audioonlyoverlay_1.AudioOnlyOverlay, + // BufferingOverlay, + Button: button_1.Button, + ClickOverlay: clickoverlay_1.ClickOverlay, + CloseButton: closebutton_1.CloseButton, + Component: component_1.Component, + Container: container_1.Container, + ControlBar: controlbar_1.ControlBar, + ErrorMessageOverlay: errormessageoverlay_1.ErrorMessageOverlay, + HugePlaybackToggleButton: hugeplaybacktogglebutton_1.HugePlaybackToggleButton, + HugeReplayButton: hugereplaybutton_1.HugeReplayButton, + Label: label_1.Label, + // MetadataLabel, + // MetadataLabelContent, + PlaybackTimeLabel: playbacktimelabel_1.PlaybackTimeLabel, + PlaybackTimeLabelMode: playbacktimelabel_1.PlaybackTimeLabelMode, + PlaybackToggleButton: playbacktogglebutton_1.PlaybackToggleButton, + PlaybackToggleOverlay: playbacktoggleoverlay_1.PlaybackToggleOverlay, + SeekBar: seekbar_1.SeekBar, + SeekBarLabel: seekbarlabel_1.SeekBarLabel, + SelectBox: selectbox_1.SelectBox, + ItemSelectionList: itemselectionlist_1.ItemSelectionList, + // SettingsPanel, + // SettingsPanelItem, + // SettingsToggleButton, + Spacer: spacer_1.Spacer, + // TitleBar, + ToggleButton: togglebutton_1.ToggleButton, + UIContainer: uicontainer_1.UIContainer, + // VideoQualitySelectBox, + VolumeControlButton: volumecontrolbutton_1.VolumeControlButton, + VolumeSlider: volumeslider_1.VolumeSlider, + VolumeToggleButton: volumetogglebutton_1.VolumeToggleButton, +}; +window.bitmovin.playerui = playerui; +module.exports = playerui; /***/ }), @@ -4645,650 +4657,650 @@ module.exports = playerui; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var uicontainer_1 = __webpack_require__(17); -var dom_1 = __webpack_require__(0); -var component_1 = __webpack_require__(2); -var container_1 = __webpack_require__(1); -var playbacktogglebutton_1 = __webpack_require__(12); -var fullscreentogglebutton_1 = __webpack_require__(37); -// import {VRToggleButton} from './components/vrtogglebutton'; -// import {VolumeToggleButton} from './components/volumetogglebutton'; -var seekbar_1 = __webpack_require__(13); -var playbacktimelabel_1 = __webpack_require__(18); // , PlaybackTimeLabelMode -var controlbar_1 = __webpack_require__(15); -var eventdispatcher_1 = __webpack_require__(3); -// import {SettingsToggleButton} from './components/settingstogglebutton'; -// import {SettingsPanel, SettingsPanelItem} from './components/settingspanel'; -// import {VideoQualitySelectBox} from './components/videoqualityselectbox'; -// import {Watermark} from './components/watermark'; -// import {AudioQualitySelectBox} from './components/audioqualityselectbox'; -// import {AudioTrackSelectBox} from './components/audiotrackselectbox'; -var seekbarlabel_1 = __webpack_require__(20); -// import {VolumeSlider} from './components/volumeslider'; -var subtitleselectbox_1 = __webpack_require__(39); -var subtitleoverlay_1 = __webpack_require__(40); -var volumecontrolbutton_1 = __webpack_require__(23); -// import {CastToggleButton} from './components/casttogglebutton'; -// import {CastStatusOverlay} from './components/caststatusoverlay'; -var errormessageoverlay_1 = __webpack_require__(26); -// import {PlaybackSpeedSelectBox} from './components/playbackspeedselectbox'; -// import {BufferingOverlay} from './components/bufferingoverlay'; -var playbacktoggleoverlay_1 = __webpack_require__(27); -// import {AirPlayToggleButton} from './components/airplaytogglebutton'; -// import {PictureInPictureToggleButton} from './components/pictureinpicturetogglebutton'; -var audioonlyoverlay_1 = __webpack_require__(29); -// import {Spacer} from './components/spacer'; -var uiutils_1 = __webpack_require__(16); -var arrayutils_1 = __webpack_require__(4); -var browserutils_1 = __webpack_require__(11); -var UIManager = (function () { - function UIManager(player, playerUiOrUiVariants, config) { - if (config === void 0) { config = {}; } - var _this = this; - if (playerUiOrUiVariants instanceof uicontainer_1.UIContainer) { - // Single-UI constructor has been called, transform arguments to UIVariant[] signature - var playerUi = playerUiOrUiVariants; - var adsUi = null; - var uiVariants = []; - // Add the ads UI if defined - if (adsUi) { - uiVariants.push({ - ui: adsUi, - condition: function (context) { - return context.isAdWithUI; - }, - }); - } - // Add the default player UI - uiVariants.push({ ui: playerUi }); - this.uiVariants = uiVariants; - } - else { - // Default constructor (UIVariant[]) has been called - this.uiVariants = playerUiOrUiVariants; - } - this.player = player; - this.config = config; - this.managerPlayerWrapper = new PlayerWrapper(player); - if (config.container) { - // Unfortunately "uiContainerElement = new DOM(config.container)" will not accept the container with - // string|HTMLElement type directly, although it accepts both types, so we need to spit these two cases up here. - // TODO check in upcoming TS versions if the container can be passed in directly, or fix the constructor - this.uiContainerElement = config.container instanceof HTMLElement ? - new dom_1.DOM(config.container) : new dom_1.DOM(config.container); - } - else { - this.uiContainerElement = new dom_1.DOM(player.getFigure()); - } - // Create UI instance managers for the UI variants - // The instance managers map to the corresponding UI variants by their array index - this.uiInstanceManagers = []; - var uiVariantsWithoutCondition = []; - for (var _i = 0, _a = this.uiVariants; _i < _a.length; _i++) { - var uiVariant = _a[_i]; - if (uiVariant.condition == null) { - // Collect variants without conditions for error checking - uiVariantsWithoutCondition.push(uiVariant); - } - // Create the instance manager for a UI variant - this.uiInstanceManagers.push(new InternalUIInstanceManager(player, uiVariant.ui, this.config)); - } - // Make sure that there is only one UI variant without a condition - // It does not make sense to have multiple variants without condition, because only the first one in the list - // (the one with the lowest index) will ever be selected. - if (uiVariantsWithoutCondition.length > 1) { - throw Error('Too many UIs without a condition: You cannot have more than one default UI'); - } - // Make sure that the default UI variant, if defined, is at the end of the list (last index) - // If it comes earlier, the variants with conditions that come afterwards will never be selected because the - // default variant without a condition always evaluates to 'true' - if (uiVariantsWithoutCondition.length > 0 - && uiVariantsWithoutCondition[0] !== this.uiVariants[this.uiVariants.length - 1]) { - throw Error('Invalid UI variant order: the default UI (without condition) must be at the end of the list'); - } - var adStartedEvent = null; // keep the event stored here during ad playback - var isMobile = browserutils_1.BrowserUtils.isMobile; - // Dynamically select a UI variant that matches the current UI condition. - var resolveUiVariant = function (event) { - // Make sure that the ON_AD_STARTED event data is persisted through ad playback in case other events happen - // in the meantime, e.g. player resize. We need to store this data because there is no other way to find out - // ad details (e.g. the ad client) while an ad is playing. - // Existing event data signals that an ad is currently active. We cannot use player.isAd() because it returns - // true on ad start and also on ad end events, which is problematic. - if (event != null) { - switch (event.type) { - // When the ad starts, we store the event data - case player.EVENT.ON_AD_STARTED: - adStartedEvent = event; - break; - // When the ad ends, we delete the event data - case player.EVENT.ON_AD_FINISHED: - case player.EVENT.ON_AD_SKIPPED: - case player.EVENT.ON_AD_ERROR: - adStartedEvent = null; - break; - // When a new source is loaded during ad playback, there will be no ad end event so we detect the end - // of the ad playback by checking isAd() in ON_READY, because ON_READY always arrives when the source - // changes. - case player.EVENT.ON_READY: - if (adStartedEvent && !player.isAd()) { - adStartedEvent = null; - } - } - } - // Detect if an ad has started - var ad = adStartedEvent != null; - var adWithUI = ad && adStartedEvent.clientType === 'vast'; - // Determine the current context for which the UI variant will be resolved - var context = { - isAd: ad, - isAdWithUI: adWithUI, - adClientType: ad ? adStartedEvent.clientType : null, - isFullscreen: _this.player.isFullscreen(), - isMobile: isMobile, - isPlaying: _this.player.isPlaying(), - width: _this.uiContainerElement.width(), - documentWidth: document.body.clientWidth, - }; - var nextUi = null; - var uiVariantChanged = false; - // Select new UI variant - // If no variant condition is fulfilled, we switch to *no* UI - for (var _i = 0, _a = _this.uiVariants; _i < _a.length; _i++) { - var uiVariant = _a[_i]; - if (uiVariant.condition == null || uiVariant.condition(context) === true) { - nextUi = _this.uiInstanceManagers[_this.uiVariants.indexOf(uiVariant)]; - break; - } - } - // Determine if the UI variant is changing - if (nextUi !== _this.currentUi) { - uiVariantChanged = true; - // console.log('switched from ', this.currentUi ? this.currentUi.getUI() : 'none', - // ' to ', nextUi ? nextUi.getUI() : 'none'); - } - // Only if the UI variant is changing, we need to do some stuff. Else we just leave everything as-is. - if (uiVariantChanged) { - // Hide the currently active UI variant - if (_this.currentUi) { - _this.currentUi.getUI().hide(); - } - // Assign the new UI variant as current UI - _this.currentUi = nextUi; - // When we switch to a different UI instance, there's some additional stuff to manage. If we do not switch - // to an instance, we're done here. - if (_this.currentUi != null) { - // Add the UI to the DOM (and configure it) the first time it is selected - if (!_this.currentUi.isConfigured()) { - _this.addUi(_this.currentUi); - } - // If this is an ad UI, we need to relay the saved ON_AD_STARTED event data so ad components can configure - // themselves for the current ad. - if (context.isAd) { - /* Relay the ON_AD_STARTED event to the ads UI - * - * Because the ads UI is initialized in the ON_AD_STARTED handler, i.e. when the ON_AD_STARTED event has - * already been fired, components in the ads UI that listen for the ON_AD_STARTED event never receive it. - * Since this can break functionality of components that rely on this event, we relay the event to the - * ads UI components with the following call. - */ - _this.currentUi.getWrappedPlayer().fireEventInUI(_this.player.EVENT.ON_AD_STARTED, adStartedEvent); - } - _this.currentUi.getUI().show(); - } - } - }; - // Listen to the following events to trigger UI variant resolution - this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_READY, resolveUiVariant); - this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_PLAY, resolveUiVariant); - this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_PAUSED, resolveUiVariant); - this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_AD_STARTED, resolveUiVariant); - this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_AD_FINISHED, resolveUiVariant); - this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_AD_SKIPPED, resolveUiVariant); - this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_AD_ERROR, resolveUiVariant); - this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_PLAYER_RESIZE, resolveUiVariant); - this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_FULLSCREEN_ENTER, resolveUiVariant); - this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_FULLSCREEN_EXIT, resolveUiVariant); - // Initialize the UI - resolveUiVariant(null); - } - UIManager.prototype.getConfig = function () { - return this.config; - }; - UIManager.prototype.addUi = function (ui) { - var dom = ui.getUI().getDomElement(); - var player = ui.getWrappedPlayer(); - ui.configureControls(); - /* Append the UI DOM after configuration to avoid CSS transitions at initialization - * Example: Components are hidden during configuration and these hides may trigger CSS transitions that are - * undesirable at this time. */ - this.uiContainerElement.append(dom); - // Some components initialize their state on ON_READY. When the UI is loaded after the player is already ready, - // they will never receive the event so we fire it from here in such cases. - if (player.isReady()) { - player.fireEventInUI(player.EVENT.ON_READY, {}); - } - // Fire onConfigured after UI DOM elements are successfully added. When fired immediately, the DOM elements - // might not be fully configured and e.g. do not have a size. - // https://swizec.com/blog/how-to-properly-wait-for-dom-elements-to-show-up-in-modern-browsers/swizec/6663 - if (window.requestAnimationFrame) { - requestAnimationFrame(function () { ui.onConfigured.dispatch(ui.getUI()); }); - } - else { - // IE9 fallback - setTimeout(function () { ui.onConfigured.dispatch(ui.getUI()); }, 0); - } - }; - UIManager.prototype.releaseUi = function (ui) { - ui.releaseControls(); - ui.getUI().getDomElement().remove(); - ui.clearEventHandlers(); - }; - UIManager.prototype.release = function () { - for (var _i = 0, _a = this.uiInstanceManagers; _i < _a.length; _i++) { - var uiInstanceManager = _a[_i]; - this.releaseUi(uiInstanceManager); - } - this.managerPlayerWrapper.clearEventHandlers(); - }; - return UIManager; -}()); -exports.UIManager = UIManager; -(function (UIManager) { - var Factory; - (function (Factory) { - function buildAudioVideoUI(player, config) { - if (config === void 0) { config = {}; } - var controlBar = new controlbar_1.ControlBar({ - components: [ - new playbacktogglebutton_1.PlaybackToggleButton(), - new seekbar_1.SeekBar({ label: new seekbarlabel_1.SeekBarLabel() }), - new playbacktimelabel_1.PlaybackTimeLabel(), - new volumecontrolbutton_1.VolumeControlButton({ 'vertical': true }), - new fullscreentogglebutton_1.FullscreenToggleButton(), - ], - }, true); - var ui = new uicontainer_1.UIContainer({ - components: [ - new playbacktoggleoverlay_1.PlaybackToggleOverlay(), - controlBar, - new errormessageoverlay_1.ErrorMessageOverlay(), - ], cssClasses: ['ui-skin'], - }); - // Just here to avoid linter errors - var ssBox = new subtitleselectbox_1.SubtitleSelectBox(); - ssBox.hide(); - var ssOverlay = new subtitleoverlay_1.SubtitleOverlay(); - ssOverlay.hide(); - return new UIManager(player, ui, config); - } - Factory.buildAudioVideoUI = buildAudioVideoUI; - function buildAudioOnlyUI(player, config) { - if (config === void 0) { config = {}; } - var controlBar = new controlbar_1.ControlBar({ - components: [ - new playbacktogglebutton_1.PlaybackToggleButton(), - new seekbar_1.SeekBar({ label: new seekbarlabel_1.SeekBarLabel(), hideInLivePlayback: true }), - new playbacktimelabel_1.PlaybackTimeLabel(), - new volumecontrolbutton_1.VolumeControlButton({ 'vertical': true }), - new component_1.Component({ cssClass: 'spacer' }), - ], - }, false); - var ui = new uicontainer_1.UIContainer({ - components: [ - new audioonlyoverlay_1.AudioOnlyOverlay(), - new playbacktoggleoverlay_1.PlaybackToggleOverlay(), - controlBar, - new errormessageoverlay_1.ErrorMessageOverlay(), - ], cssClasses: ['ui-skin'], - }); - return new UIManager(player, ui, config); - } - Factory.buildAudioOnlyUI = buildAudioOnlyUI; - })(Factory = UIManager.Factory || (UIManager.Factory = {})); -})(UIManager = exports.UIManager || (exports.UIManager = {})); -exports.UIManager = UIManager; -/** - * Encapsulates functionality to manage a UI instance. Used by the {@link UIManager} to manage multiple UI instances. - */ -var UIInstanceManager = (function () { - function UIInstanceManager(player, ui, config) { - if (config === void 0) { config = {}; } - this.events = { - onConfigured: new eventdispatcher_1.EventDispatcher(), - onSeek: new eventdispatcher_1.EventDispatcher(), - onSeekPreview: new eventdispatcher_1.EventDispatcher(), - onSeeked: new eventdispatcher_1.EventDispatcher(), - onComponentShow: new eventdispatcher_1.EventDispatcher(), - onComponentHide: new eventdispatcher_1.EventDispatcher(), - onControlsShow: new eventdispatcher_1.EventDispatcher(), - onPreviewControlsHide: new eventdispatcher_1.EventDispatcher(), - onControlsHide: new eventdispatcher_1.EventDispatcher(), - }; - this.playerWrapper = new PlayerWrapper(player); - this.ui = ui; - this.config = config; - } - UIInstanceManager.prototype.getConfig = function () { - return this.config; - }; - UIInstanceManager.prototype.getUI = function () { - return this.ui; - }; - UIInstanceManager.prototype.getPlayer = function () { - return this.playerWrapper.getPlayer(); - }; - Object.defineProperty(UIInstanceManager.prototype, "onConfigured", { - /** - * Fires when the UI is fully configured and added to the DOM. - * @returns {EventDispatcher} - */ - get: function () { - return this.events.onConfigured; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(UIInstanceManager.prototype, "onSeek", { - /** - * Fires when a seek starts. - * @returns {EventDispatcher} - */ - get: function () { - return this.events.onSeek; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(UIInstanceManager.prototype, "onSeekPreview", { - /** - * Fires when the seek timeline is scrubbed. - * @returns {EventDispatcher} - */ - get: function () { - return this.events.onSeekPreview; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(UIInstanceManager.prototype, "onSeeked", { - /** - * Fires when a seek is finished. - * @returns {EventDispatcher} - */ - get: function () { - return this.events.onSeeked; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(UIInstanceManager.prototype, "onComponentShow", { - /** - * Fires when a component is showing. - * @returns {EventDispatcher} - */ - get: function () { - return this.events.onComponentShow; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(UIInstanceManager.prototype, "onComponentHide", { - /** - * Fires when a component is hiding. - * @returns {EventDispatcher} - */ - get: function () { - return this.events.onComponentHide; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(UIInstanceManager.prototype, "onControlsShow", { - /** - * Fires when the UI controls are showing. - * @returns {EventDispatcher} - */ - get: function () { - return this.events.onControlsShow; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(UIInstanceManager.prototype, "onPreviewControlsHide", { - /** - * Fires before the UI controls are hiding to check if they are allowed to hide. - * @returns {EventDispatcher} - */ - get: function () { - return this.events.onPreviewControlsHide; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(UIInstanceManager.prototype, "onControlsHide", { - /** - * Fires when the UI controls are hiding. - * @returns {EventDispatcher} - */ - get: function () { - return this.events.onControlsHide; - }, - enumerable: true, - configurable: true - }); - UIInstanceManager.prototype.clearEventHandlers = function () { - this.playerWrapper.clearEventHandlers(); - var events = this.events; // avoid TS7017 - for (var event_1 in events) { - var dispatcher = events[event_1]; - dispatcher.unsubscribeAll(); - } - }; - return UIInstanceManager; -}()); -exports.UIInstanceManager = UIInstanceManager; -/** - * Extends the {@link UIInstanceManager} for internal use in the {@link UIManager} and provides access to functionality - * that components receiving a reference to the {@link UIInstanceManager} should not have access to. - */ -var InternalUIInstanceManager = (function (_super) { - __extends(InternalUIInstanceManager, _super); - function InternalUIInstanceManager() { - return _super !== null && _super.apply(this, arguments) || this; - } - InternalUIInstanceManager.prototype.getWrappedPlayer = function () { - // TODO find a non-hacky way to provide the WrappedPlayer to the UIManager without exporting it - // getPlayer() actually returns the WrappedPlayer but its return type is set to Player so the WrappedPlayer does - // not need to be exported - return this.getPlayer(); - }; - InternalUIInstanceManager.prototype.configureControls = function () { - this.configureControlsTree(this.getUI()); - this.configured = true; - }; - InternalUIInstanceManager.prototype.isConfigured = function () { - return this.configured; - }; - InternalUIInstanceManager.prototype.configureControlsTree = function (component) { - var _this = this; - var configuredComponents = []; - uiutils_1.UIUtils.traverseTree(component, function (component) { - // First, check if we have already configured a component, and throw an error if we did. Multiple configuration - // of the same component leads to unexpected UI behavior. Also, a component that is in the UI tree multiple - // times hints at a wrong UI structure. - // We could just skip configuration in such a case and not throw an exception, but enforcing a clean UI tree - // seems like the better choice. - for (var _i = 0, configuredComponents_1 = configuredComponents; _i < configuredComponents_1.length; _i++) { - var configuredComponent = configuredComponents_1[_i]; - if (configuredComponent === component) { - // Write the component to the console to simplify identification of the culprit - // (e.g. by inspecting the config) - if (console) { - console.error('Circular reference in UI tree', component); - } - // Additionally throw an error, because this case must not happen and leads to unexpected UI behavior. - throw Error('Circular reference in UI tree: ' + component.constructor.name); - } - } - component.initialize(); - component.configure(_this.getPlayer(), _this); - configuredComponents.push(component); - }); - }; - InternalUIInstanceManager.prototype.releaseControls = function () { - // Do not call release methods if the components have never been configured; this can result in exceptions - if (this.configured) { - this.releaseControlsTree(this.getUI()); - this.configured = false; - } - this.released = true; - }; - InternalUIInstanceManager.prototype.isReleased = function () { - return this.released; - }; - InternalUIInstanceManager.prototype.releaseControlsTree = function (component) { - component.release(); - if (component instanceof container_1.Container) { - for (var _i = 0, _a = component.getComponents(); _i < _a.length; _i++) { - var childComponent = _a[_i]; - this.releaseControlsTree(childComponent); - } - } - }; - InternalUIInstanceManager.prototype.clearEventHandlers = function () { - _super.prototype.clearEventHandlers.call(this); - }; - return InternalUIInstanceManager; -}(UIInstanceManager)); -/** - * Wraps the player to track event handlers and provide a simple method to remove all registered event - * handlers from the player. - */ -var PlayerWrapper = (function () { - function PlayerWrapper(player) { - var _this = this; - this.eventHandlers = {}; - this.player = player; - // Collect all members of the player (public API methods and properties of the player) - // (Object.getOwnPropertyNames(player) does not work with the player TypeScript class starting in 7.2) - var members = []; - for (var member in player) { - members.push(member); - } - // Split the members into methods and properties - var methods = []; - var properties = []; - for (var _i = 0, members_1 = members; _i < members_1.length; _i++) { - var member = members_1[_i]; - if (typeof player[member] === 'function') { - methods.push(member); - } - else { - properties.push(member); - } - } - // Create wrapper object - var wrapper = {}; - var _loop_1 = function (method) { - wrapper[method] = function () { - // console.log('called ' + member); // track method calls on the player - return player[method].apply(player, arguments); - }; - }; - // Add function wrappers for all API methods that do nothing but calling the base method on the player - for (var _a = 0, methods_1 = methods; _a < methods_1.length; _a++) { - var method = methods_1[_a]; - _loop_1(method); - } - var _loop_2 = function (property) { - // Get an eventually existing property descriptor to differentiate between plain properties and properties with - // getters/setters. - var propertyDescriptor = Object.getOwnPropertyDescriptor(player, property) || - Object.getOwnPropertyDescriptor(Object.getPrototypeOf(player), property); - // If the property has getters/setters, wrap them accordingly... - if (propertyDescriptor && (propertyDescriptor.get || propertyDescriptor.set)) { - Object.defineProperty(wrapper, property, { - get: function () { return propertyDescriptor.get.call(player); }, - set: function (value) { return propertyDescriptor.set.call(player, value); }, - }); - } - else { - wrapper[property] = player[property]; - } - }; - // Add all public properties of the player to the wrapper - for (var _b = 0, properties_1 = properties; _b < properties_1.length; _b++) { - var property = properties_1[_b]; - _loop_2(property); - } - // Explicitly add a wrapper method for 'addEventHandler' that adds added event handlers to the event list - wrapper.addEventHandler = function (eventType, callback) { - player.addEventHandler(eventType, callback); - if (!_this.eventHandlers[eventType]) { - _this.eventHandlers[eventType] = []; - } - _this.eventHandlers[eventType].push(callback); - return wrapper; - }; - // Explicitly add a wrapper method for 'removeEventHandler' that removes removed event handlers from the event list - wrapper.removeEventHandler = function (eventType, callback) { - player.removeEventHandler(eventType, callback); - if (_this.eventHandlers[eventType]) { - arrayutils_1.ArrayUtils.remove(_this.eventHandlers[eventType], callback); - } - return wrapper; - }; - wrapper.fireEventInUI = function (event, data) { - if (_this.eventHandlers[event]) { - // Extend the data object with default values to convert it to a {@link PlayerEvent} object. - var playerEventData = Object.assign({}, { - timestamp: Date.now(), - type: event, - // Add a marker property so the UI can detect UI-internal player events - uiSourced: true, - }, data); - // Execute the registered callbacks - for (var _i = 0, _a = _this.eventHandlers[event]; _i < _a.length; _i++) { - var callback = _a[_i]; - callback(playerEventData); - } - } - }; - this.wrapper = wrapper; - } - /** - * Returns a wrapped player object that can be used on place of the normal player object. - * @returns {WrappedPlayer} a wrapped player - */ - PlayerWrapper.prototype.getPlayer = function () { - return this.wrapper; - }; - /** - * Clears all registered event handlers from the player that were added through the wrapped player. - */ - PlayerWrapper.prototype.clearEventHandlers = function () { - for (var eventType in this.eventHandlers) { - for (var _i = 0, _a = this.eventHandlers[eventType]; _i < _a.length; _i++) { - var callback = _a[_i]; - this.player.removeEventHandler(eventType, callback); - } - } - }; - return PlayerWrapper; -}()); + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var uicontainer_1 = __webpack_require__(17); +var dom_1 = __webpack_require__(0); +var component_1 = __webpack_require__(2); +var container_1 = __webpack_require__(1); +var playbacktogglebutton_1 = __webpack_require__(12); +var fullscreentogglebutton_1 = __webpack_require__(37); +// import {VRToggleButton} from './components/vrtogglebutton'; +// import {VolumeToggleButton} from './components/volumetogglebutton'; +var seekbar_1 = __webpack_require__(13); +var playbacktimelabel_1 = __webpack_require__(18); // , PlaybackTimeLabelMode +var controlbar_1 = __webpack_require__(15); +var eventdispatcher_1 = __webpack_require__(3); +// import {SettingsToggleButton} from './components/settingstogglebutton'; +// import {SettingsPanel, SettingsPanelItem} from './components/settingspanel'; +// import {VideoQualitySelectBox} from './components/videoqualityselectbox'; +// import {Watermark} from './components/watermark'; +// import {AudioQualitySelectBox} from './components/audioqualityselectbox'; +// import {AudioTrackSelectBox} from './components/audiotrackselectbox'; +var seekbarlabel_1 = __webpack_require__(20); +// import {VolumeSlider} from './components/volumeslider'; +var subtitleselectbox_1 = __webpack_require__(39); +var subtitleoverlay_1 = __webpack_require__(40); +var volumecontrolbutton_1 = __webpack_require__(23); +// import {CastToggleButton} from './components/casttogglebutton'; +// import {CastStatusOverlay} from './components/caststatusoverlay'; +var errormessageoverlay_1 = __webpack_require__(26); +// import {PlaybackSpeedSelectBox} from './components/playbackspeedselectbox'; +// import {BufferingOverlay} from './components/bufferingoverlay'; +var playbacktoggleoverlay_1 = __webpack_require__(27); +// import {AirPlayToggleButton} from './components/airplaytogglebutton'; +// import {PictureInPictureToggleButton} from './components/pictureinpicturetogglebutton'; +var audioonlyoverlay_1 = __webpack_require__(29); +// import {Spacer} from './components/spacer'; +var uiutils_1 = __webpack_require__(16); +var arrayutils_1 = __webpack_require__(4); +var browserutils_1 = __webpack_require__(11); +var UIManager = (function () { + function UIManager(player, playerUiOrUiVariants, config) { + if (config === void 0) { config = {}; } + var _this = this; + if (playerUiOrUiVariants instanceof uicontainer_1.UIContainer) { + // Single-UI constructor has been called, transform arguments to UIVariant[] signature + var playerUi = playerUiOrUiVariants; + var adsUi = null; + var uiVariants = []; + // Add the ads UI if defined + if (adsUi) { + uiVariants.push({ + ui: adsUi, + condition: function (context) { + return context.isAdWithUI; + }, + }); + } + // Add the default player UI + uiVariants.push({ ui: playerUi }); + this.uiVariants = uiVariants; + } + else { + // Default constructor (UIVariant[]) has been called + this.uiVariants = playerUiOrUiVariants; + } + this.player = player; + this.config = config; + this.managerPlayerWrapper = new PlayerWrapper(player); + if (config.container) { + // Unfortunately "uiContainerElement = new DOM(config.container)" will not accept the container with + // string|HTMLElement type directly, although it accepts both types, so we need to spit these two cases up here. + // TODO check in upcoming TS versions if the container can be passed in directly, or fix the constructor + this.uiContainerElement = config.container instanceof HTMLElement ? + new dom_1.DOM(config.container) : new dom_1.DOM(config.container); + } + else { + this.uiContainerElement = new dom_1.DOM(player.getFigure()); + } + // Create UI instance managers for the UI variants + // The instance managers map to the corresponding UI variants by their array index + this.uiInstanceManagers = []; + var uiVariantsWithoutCondition = []; + for (var _i = 0, _a = this.uiVariants; _i < _a.length; _i++) { + var uiVariant = _a[_i]; + if (uiVariant.condition == null) { + // Collect variants without conditions for error checking + uiVariantsWithoutCondition.push(uiVariant); + } + // Create the instance manager for a UI variant + this.uiInstanceManagers.push(new InternalUIInstanceManager(player, uiVariant.ui, this.config)); + } + // Make sure that there is only one UI variant without a condition + // It does not make sense to have multiple variants without condition, because only the first one in the list + // (the one with the lowest index) will ever be selected. + if (uiVariantsWithoutCondition.length > 1) { + throw Error('Too many UIs without a condition: You cannot have more than one default UI'); + } + // Make sure that the default UI variant, if defined, is at the end of the list (last index) + // If it comes earlier, the variants with conditions that come afterwards will never be selected because the + // default variant without a condition always evaluates to 'true' + if (uiVariantsWithoutCondition.length > 0 + && uiVariantsWithoutCondition[0] !== this.uiVariants[this.uiVariants.length - 1]) { + throw Error('Invalid UI variant order: the default UI (without condition) must be at the end of the list'); + } + var adStartedEvent = null; // keep the event stored here during ad playback + var isMobile = browserutils_1.BrowserUtils.isMobile; + // Dynamically select a UI variant that matches the current UI condition. + var resolveUiVariant = function (event) { + // Make sure that the ON_AD_STARTED event data is persisted through ad playback in case other events happen + // in the meantime, e.g. player resize. We need to store this data because there is no other way to find out + // ad details (e.g. the ad client) while an ad is playing. + // Existing event data signals that an ad is currently active. We cannot use player.isAd() because it returns + // true on ad start and also on ad end events, which is problematic. + if (event != null) { + switch (event.type) { + // When the ad starts, we store the event data + case player.EVENT.ON_AD_STARTED: + adStartedEvent = event; + break; + // When the ad ends, we delete the event data + case player.EVENT.ON_AD_FINISHED: + case player.EVENT.ON_AD_SKIPPED: + case player.EVENT.ON_AD_ERROR: + adStartedEvent = null; + break; + // When a new source is loaded during ad playback, there will be no ad end event so we detect the end + // of the ad playback by checking isAd() in ON_READY, because ON_READY always arrives when the source + // changes. + case player.EVENT.ON_READY: + if (adStartedEvent && !player.isAd()) { + adStartedEvent = null; + } + } + } + // Detect if an ad has started + var ad = adStartedEvent != null; + var adWithUI = ad && adStartedEvent.clientType === 'vast'; + // Determine the current context for which the UI variant will be resolved + var context = { + isAd: ad, + isAdWithUI: adWithUI, + adClientType: ad ? adStartedEvent.clientType : null, + isFullscreen: _this.player.isFullscreen(), + isMobile: isMobile, + isPlaying: _this.player.isPlaying(), + width: _this.uiContainerElement.width(), + documentWidth: document.body.clientWidth, + }; + var nextUi = null; + var uiVariantChanged = false; + // Select new UI variant + // If no variant condition is fulfilled, we switch to *no* UI + for (var _i = 0, _a = _this.uiVariants; _i < _a.length; _i++) { + var uiVariant = _a[_i]; + if (uiVariant.condition == null || uiVariant.condition(context) === true) { + nextUi = _this.uiInstanceManagers[_this.uiVariants.indexOf(uiVariant)]; + break; + } + } + // Determine if the UI variant is changing + if (nextUi !== _this.currentUi) { + uiVariantChanged = true; + // console.log('switched from ', this.currentUi ? this.currentUi.getUI() : 'none', + // ' to ', nextUi ? nextUi.getUI() : 'none'); + } + // Only if the UI variant is changing, we need to do some stuff. Else we just leave everything as-is. + if (uiVariantChanged) { + // Hide the currently active UI variant + if (_this.currentUi) { + _this.currentUi.getUI().hide(); + } + // Assign the new UI variant as current UI + _this.currentUi = nextUi; + // When we switch to a different UI instance, there's some additional stuff to manage. If we do not switch + // to an instance, we're done here. + if (_this.currentUi != null) { + // Add the UI to the DOM (and configure it) the first time it is selected + if (!_this.currentUi.isConfigured()) { + _this.addUi(_this.currentUi); + } + // If this is an ad UI, we need to relay the saved ON_AD_STARTED event data so ad components can configure + // themselves for the current ad. + if (context.isAd) { + /* Relay the ON_AD_STARTED event to the ads UI + * + * Because the ads UI is initialized in the ON_AD_STARTED handler, i.e. when the ON_AD_STARTED event has + * already been fired, components in the ads UI that listen for the ON_AD_STARTED event never receive it. + * Since this can break functionality of components that rely on this event, we relay the event to the + * ads UI components with the following call. + */ + _this.currentUi.getWrappedPlayer().fireEventInUI(_this.player.EVENT.ON_AD_STARTED, adStartedEvent); + } + _this.currentUi.getUI().show(); + } + } + }; + // Listen to the following events to trigger UI variant resolution + this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_READY, resolveUiVariant); + this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_PLAY, resolveUiVariant); + this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_PAUSED, resolveUiVariant); + this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_AD_STARTED, resolveUiVariant); + this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_AD_FINISHED, resolveUiVariant); + this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_AD_SKIPPED, resolveUiVariant); + this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_AD_ERROR, resolveUiVariant); + this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_PLAYER_RESIZE, resolveUiVariant); + this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_FULLSCREEN_ENTER, resolveUiVariant); + this.managerPlayerWrapper.getPlayer().addEventHandler(this.player.EVENT.ON_FULLSCREEN_EXIT, resolveUiVariant); + // Initialize the UI + resolveUiVariant(null); + } + UIManager.prototype.getConfig = function () { + return this.config; + }; + UIManager.prototype.addUi = function (ui) { + var dom = ui.getUI().getDomElement(); + var player = ui.getWrappedPlayer(); + ui.configureControls(); + /* Append the UI DOM after configuration to avoid CSS transitions at initialization + * Example: Components are hidden during configuration and these hides may trigger CSS transitions that are + * undesirable at this time. */ + this.uiContainerElement.append(dom); + // Some components initialize their state on ON_READY. When the UI is loaded after the player is already ready, + // they will never receive the event so we fire it from here in such cases. + if (player.isReady()) { + player.fireEventInUI(player.EVENT.ON_READY, {}); + } + // Fire onConfigured after UI DOM elements are successfully added. When fired immediately, the DOM elements + // might not be fully configured and e.g. do not have a size. + // https://swizec.com/blog/how-to-properly-wait-for-dom-elements-to-show-up-in-modern-browsers/swizec/6663 + if (window.requestAnimationFrame) { + requestAnimationFrame(function () { ui.onConfigured.dispatch(ui.getUI()); }); + } + else { + // IE9 fallback + setTimeout(function () { ui.onConfigured.dispatch(ui.getUI()); }, 0); + } + }; + UIManager.prototype.releaseUi = function (ui) { + ui.releaseControls(); + ui.getUI().getDomElement().remove(); + ui.clearEventHandlers(); + }; + UIManager.prototype.release = function () { + for (var _i = 0, _a = this.uiInstanceManagers; _i < _a.length; _i++) { + var uiInstanceManager = _a[_i]; + this.releaseUi(uiInstanceManager); + } + this.managerPlayerWrapper.clearEventHandlers(); + }; + return UIManager; +}()); +exports.UIManager = UIManager; +(function (UIManager) { + var Factory; + (function (Factory) { + function buildAudioVideoUI(player, config) { + if (config === void 0) { config = {}; } + var controlBar = new controlbar_1.ControlBar({ + components: [ + new playbacktogglebutton_1.PlaybackToggleButton(), + new seekbar_1.SeekBar({ label: new seekbarlabel_1.SeekBarLabel() }), + new playbacktimelabel_1.PlaybackTimeLabel(), + new volumecontrolbutton_1.VolumeControlButton({ 'vertical': true }), + new fullscreentogglebutton_1.FullscreenToggleButton(), + ], + }, true); + var ui = new uicontainer_1.UIContainer({ + components: [ + new playbacktoggleoverlay_1.PlaybackToggleOverlay(), + controlBar, + new errormessageoverlay_1.ErrorMessageOverlay(), + ], cssClasses: ['ui-skin'], + }); + // Just here to avoid linter errors + var ssBox = new subtitleselectbox_1.SubtitleSelectBox(); + ssBox.hide(); + var ssOverlay = new subtitleoverlay_1.SubtitleOverlay(); + ssOverlay.hide(); + return new UIManager(player, ui, config); + } + Factory.buildAudioVideoUI = buildAudioVideoUI; + function buildAudioOnlyUI(player, config) { + if (config === void 0) { config = {}; } + var controlBar = new controlbar_1.ControlBar({ + components: [ + new playbacktogglebutton_1.PlaybackToggleButton(), + new seekbar_1.SeekBar({ label: new seekbarlabel_1.SeekBarLabel(), hideInLivePlayback: true }), + new playbacktimelabel_1.PlaybackTimeLabel(), + new volumecontrolbutton_1.VolumeControlButton({ 'vertical': true }), + new component_1.Component({ cssClass: 'spacer' }), + ], + }, false); + var ui = new uicontainer_1.UIContainer({ + components: [ + new audioonlyoverlay_1.AudioOnlyOverlay(), + new playbacktoggleoverlay_1.PlaybackToggleOverlay(), + controlBar, + new errormessageoverlay_1.ErrorMessageOverlay(), + ], cssClasses: ['ui-skin'], + }); + return new UIManager(player, ui, config); + } + Factory.buildAudioOnlyUI = buildAudioOnlyUI; + })(Factory = UIManager.Factory || (UIManager.Factory = {})); +})(UIManager = exports.UIManager || (exports.UIManager = {})); +exports.UIManager = UIManager; +/** + * Encapsulates functionality to manage a UI instance. Used by the {@link UIManager} to manage multiple UI instances. + */ +var UIInstanceManager = (function () { + function UIInstanceManager(player, ui, config) { + if (config === void 0) { config = {}; } + this.events = { + onConfigured: new eventdispatcher_1.EventDispatcher(), + onSeek: new eventdispatcher_1.EventDispatcher(), + onSeekPreview: new eventdispatcher_1.EventDispatcher(), + onSeeked: new eventdispatcher_1.EventDispatcher(), + onComponentShow: new eventdispatcher_1.EventDispatcher(), + onComponentHide: new eventdispatcher_1.EventDispatcher(), + onControlsShow: new eventdispatcher_1.EventDispatcher(), + onPreviewControlsHide: new eventdispatcher_1.EventDispatcher(), + onControlsHide: new eventdispatcher_1.EventDispatcher(), + }; + this.playerWrapper = new PlayerWrapper(player); + this.ui = ui; + this.config = config; + } + UIInstanceManager.prototype.getConfig = function () { + return this.config; + }; + UIInstanceManager.prototype.getUI = function () { + return this.ui; + }; + UIInstanceManager.prototype.getPlayer = function () { + return this.playerWrapper.getPlayer(); + }; + Object.defineProperty(UIInstanceManager.prototype, "onConfigured", { + /** + * Fires when the UI is fully configured and added to the DOM. + * @returns {EventDispatcher} + */ + get: function () { + return this.events.onConfigured; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(UIInstanceManager.prototype, "onSeek", { + /** + * Fires when a seek starts. + * @returns {EventDispatcher} + */ + get: function () { + return this.events.onSeek; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(UIInstanceManager.prototype, "onSeekPreview", { + /** + * Fires when the seek timeline is scrubbed. + * @returns {EventDispatcher} + */ + get: function () { + return this.events.onSeekPreview; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(UIInstanceManager.prototype, "onSeeked", { + /** + * Fires when a seek is finished. + * @returns {EventDispatcher} + */ + get: function () { + return this.events.onSeeked; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(UIInstanceManager.prototype, "onComponentShow", { + /** + * Fires when a component is showing. + * @returns {EventDispatcher} + */ + get: function () { + return this.events.onComponentShow; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(UIInstanceManager.prototype, "onComponentHide", { + /** + * Fires when a component is hiding. + * @returns {EventDispatcher} + */ + get: function () { + return this.events.onComponentHide; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(UIInstanceManager.prototype, "onControlsShow", { + /** + * Fires when the UI controls are showing. + * @returns {EventDispatcher} + */ + get: function () { + return this.events.onControlsShow; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(UIInstanceManager.prototype, "onPreviewControlsHide", { + /** + * Fires before the UI controls are hiding to check if they are allowed to hide. + * @returns {EventDispatcher} + */ + get: function () { + return this.events.onPreviewControlsHide; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(UIInstanceManager.prototype, "onControlsHide", { + /** + * Fires when the UI controls are hiding. + * @returns {EventDispatcher} + */ + get: function () { + return this.events.onControlsHide; + }, + enumerable: true, + configurable: true + }); + UIInstanceManager.prototype.clearEventHandlers = function () { + this.playerWrapper.clearEventHandlers(); + var events = this.events; // avoid TS7017 + for (var event_1 in events) { + var dispatcher = events[event_1]; + dispatcher.unsubscribeAll(); + } + }; + return UIInstanceManager; +}()); +exports.UIInstanceManager = UIInstanceManager; +/** + * Extends the {@link UIInstanceManager} for internal use in the {@link UIManager} and provides access to functionality + * that components receiving a reference to the {@link UIInstanceManager} should not have access to. + */ +var InternalUIInstanceManager = (function (_super) { + __extends(InternalUIInstanceManager, _super); + function InternalUIInstanceManager() { + return _super !== null && _super.apply(this, arguments) || this; + } + InternalUIInstanceManager.prototype.getWrappedPlayer = function () { + // TODO find a non-hacky way to provide the WrappedPlayer to the UIManager without exporting it + // getPlayer() actually returns the WrappedPlayer but its return type is set to Player so the WrappedPlayer does + // not need to be exported + return this.getPlayer(); + }; + InternalUIInstanceManager.prototype.configureControls = function () { + this.configureControlsTree(this.getUI()); + this.configured = true; + }; + InternalUIInstanceManager.prototype.isConfigured = function () { + return this.configured; + }; + InternalUIInstanceManager.prototype.configureControlsTree = function (component) { + var _this = this; + var configuredComponents = []; + uiutils_1.UIUtils.traverseTree(component, function (component) { + // First, check if we have already configured a component, and throw an error if we did. Multiple configuration + // of the same component leads to unexpected UI behavior. Also, a component that is in the UI tree multiple + // times hints at a wrong UI structure. + // We could just skip configuration in such a case and not throw an exception, but enforcing a clean UI tree + // seems like the better choice. + for (var _i = 0, configuredComponents_1 = configuredComponents; _i < configuredComponents_1.length; _i++) { + var configuredComponent = configuredComponents_1[_i]; + if (configuredComponent === component) { + // Write the component to the console to simplify identification of the culprit + // (e.g. by inspecting the config) + if (console) { + console.error('Circular reference in UI tree', component); + } + // Additionally throw an error, because this case must not happen and leads to unexpected UI behavior. + throw Error('Circular reference in UI tree: ' + component.constructor.name); + } + } + component.initialize(); + component.configure(_this.getPlayer(), _this); + configuredComponents.push(component); + }); + }; + InternalUIInstanceManager.prototype.releaseControls = function () { + // Do not call release methods if the components have never been configured; this can result in exceptions + if (this.configured) { + this.releaseControlsTree(this.getUI()); + this.configured = false; + } + this.released = true; + }; + InternalUIInstanceManager.prototype.isReleased = function () { + return this.released; + }; + InternalUIInstanceManager.prototype.releaseControlsTree = function (component) { + component.release(); + if (component instanceof container_1.Container) { + for (var _i = 0, _a = component.getComponents(); _i < _a.length; _i++) { + var childComponent = _a[_i]; + this.releaseControlsTree(childComponent); + } + } + }; + InternalUIInstanceManager.prototype.clearEventHandlers = function () { + _super.prototype.clearEventHandlers.call(this); + }; + return InternalUIInstanceManager; +}(UIInstanceManager)); +/** + * Wraps the player to track event handlers and provide a simple method to remove all registered event + * handlers from the player. + */ +var PlayerWrapper = (function () { + function PlayerWrapper(player) { + var _this = this; + this.eventHandlers = {}; + this.player = player; + // Collect all members of the player (public API methods and properties of the player) + // (Object.getOwnPropertyNames(player) does not work with the player TypeScript class starting in 7.2) + var members = []; + for (var member in player) { + members.push(member); + } + // Split the members into methods and properties + var methods = []; + var properties = []; + for (var _i = 0, members_1 = members; _i < members_1.length; _i++) { + var member = members_1[_i]; + if (typeof player[member] === 'function') { + methods.push(member); + } + else { + properties.push(member); + } + } + // Create wrapper object + var wrapper = {}; + var _loop_1 = function (method) { + wrapper[method] = function () { + // console.log('called ' + member); // track method calls on the player + return player[method].apply(player, arguments); + }; + }; + // Add function wrappers for all API methods that do nothing but calling the base method on the player + for (var _a = 0, methods_1 = methods; _a < methods_1.length; _a++) { + var method = methods_1[_a]; + _loop_1(method); + } + var _loop_2 = function (property) { + // Get an eventually existing property descriptor to differentiate between plain properties and properties with + // getters/setters. + var propertyDescriptor = Object.getOwnPropertyDescriptor(player, property) || + Object.getOwnPropertyDescriptor(Object.getPrototypeOf(player), property); + // If the property has getters/setters, wrap them accordingly... + if (propertyDescriptor && (propertyDescriptor.get || propertyDescriptor.set)) { + Object.defineProperty(wrapper, property, { + get: function () { return propertyDescriptor.get.call(player); }, + set: function (value) { return propertyDescriptor.set.call(player, value); }, + }); + } + else { + wrapper[property] = player[property]; + } + }; + // Add all public properties of the player to the wrapper + for (var _b = 0, properties_1 = properties; _b < properties_1.length; _b++) { + var property = properties_1[_b]; + _loop_2(property); + } + // Explicitly add a wrapper method for 'addEventHandler' that adds added event handlers to the event list + wrapper.addEventHandler = function (eventType, callback) { + player.addEventHandler(eventType, callback); + if (!_this.eventHandlers[eventType]) { + _this.eventHandlers[eventType] = []; + } + _this.eventHandlers[eventType].push(callback); + return wrapper; + }; + // Explicitly add a wrapper method for 'removeEventHandler' that removes removed event handlers from the event list + wrapper.removeEventHandler = function (eventType, callback) { + player.removeEventHandler(eventType, callback); + if (_this.eventHandlers[eventType]) { + arrayutils_1.ArrayUtils.remove(_this.eventHandlers[eventType], callback); + } + return wrapper; + }; + wrapper.fireEventInUI = function (event, data) { + if (_this.eventHandlers[event]) { + // Extend the data object with default values to convert it to a {@link PlayerEvent} object. + var playerEventData = Object.assign({}, { + timestamp: Date.now(), + type: event, + // Add a marker property so the UI can detect UI-internal player events + uiSourced: true, + }, data); + // Execute the registered callbacks + for (var _i = 0, _a = _this.eventHandlers[event]; _i < _a.length; _i++) { + var callback = _a[_i]; + callback(playerEventData); + } + } + }; + this.wrapper = wrapper; + } + /** + * Returns a wrapped player object that can be used on place of the normal player object. + * @returns {WrappedPlayer} a wrapped player + */ + PlayerWrapper.prototype.getPlayer = function () { + return this.wrapper; + }; + /** + * Clears all registered event handlers from the player that were added through the wrapped player. + */ + PlayerWrapper.prototype.clearEventHandlers = function () { + for (var eventType in this.eventHandlers) { + for (var _i = 0, _a = this.eventHandlers[eventType]; _i < _a.length; _i++) { + var callback = _a[_i]; + this.player.removeEventHandler(eventType, callback); + } + } + }; + return PlayerWrapper; +}()); /***/ }), @@ -5296,16 +5308,16 @@ var PlayerWrapper = (function () { /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var Guid; -(function (Guid) { - var guid = 1; - function next() { - return guid++; - } - Guid.next = next; -})(Guid = exports.Guid || (exports.Guid = {})); + +Object.defineProperty(exports, "__esModule", { value: true }); +var Guid; +(function (Guid) { + var guid = 1; + function next() { + return guid++; + } + Guid.next = next; +})(Guid = exports.Guid || (exports.Guid = {})); /***/ }), @@ -5313,60 +5325,60 @@ var Guid; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var togglebutton_1 = __webpack_require__(8); -/** - * A button that toggles the player between windowed and fullscreen view. - */ -var FullscreenToggleButton = (function (_super) { - __extends(FullscreenToggleButton, _super); - function FullscreenToggleButton(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-fullscreentogglebutton', - text: 'Fullscreen', - }, _this.config); - return _this; - } - FullscreenToggleButton.prototype.configure = function (player, uimanager) { - var _this = this; - _super.prototype.configure.call(this, player, uimanager); - var fullscreenStateHandler = function () { - if (player.isFullscreen()) { - _this.on(); - } - else { - _this.off(); - } - }; - player.addEventHandler(player.EVENT.ON_FULLSCREEN_ENTER, fullscreenStateHandler); - player.addEventHandler(player.EVENT.ON_FULLSCREEN_EXIT, fullscreenStateHandler); - this.onClick.subscribe(function () { - if (player.isFullscreen()) { - player.exitFullscreen(); - } - else { - player.enterFullscreen(); - } - }); - // Startup init - fullscreenStateHandler(); - }; - return FullscreenToggleButton; -}(togglebutton_1.ToggleButton)); -exports.FullscreenToggleButton = FullscreenToggleButton; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var togglebutton_1 = __webpack_require__(8); +/** + * A button that toggles the player between windowed and fullscreen view. + */ +var FullscreenToggleButton = (function (_super) { + __extends(FullscreenToggleButton, _super); + function FullscreenToggleButton(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-fullscreentogglebutton', + text: 'Fullscreen', + }, _this.config); + return _this; + } + FullscreenToggleButton.prototype.configure = function (player, uimanager) { + var _this = this; + _super.prototype.configure.call(this, player, uimanager); + var fullscreenStateHandler = function () { + if (player.isFullscreen()) { + _this.on(); + } + else { + _this.off(); + } + }; + player.addEventHandler(player.EVENT.ON_FULLSCREEN_ENTER, fullscreenStateHandler); + player.addEventHandler(player.EVENT.ON_FULLSCREEN_EXIT, fullscreenStateHandler); + this.onClick.subscribe(function () { + if (player.isFullscreen()) { + player.exitFullscreen(); + } + else { + player.enterFullscreen(); + } + }); + // Startup init + fullscreenStateHandler(); + }; + return FullscreenToggleButton; +}(togglebutton_1.ToggleButton)); +exports.FullscreenToggleButton = FullscreenToggleButton; /***/ }), @@ -5374,66 +5386,66 @@ exports.FullscreenToggleButton = FullscreenToggleButton; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var dom_1 = __webpack_require__(0); -/** - * Tracks the loading state of images. - */ -var ImageLoader = (function () { - function ImageLoader() { - this.state = {}; - } - /** - * Loads an image and call the callback once the image is loaded. If the image is already loaded, the callback - * is called immediately, else it is called once loading has finished. Calling this method multiple times for the - * same image while it is loading calls only let callback passed into the last call. - * @param url The url to the image to load - * @param loadedCallback The callback that is called when the image is loaded - */ - ImageLoader.prototype.load = function (url, loadedCallback) { - var _this = this; - if (!this.state[url]) { - // When the image was never attempted to be loaded before, we create a state and store it in the state map - // for later use when the same image is requested to be loaded again. - var state_1 = { - url: url, - image: new dom_1.DOM('img', {}), - loadedCallback: loadedCallback, - loaded: false, - width: 0, - height: 0, - }; - this.state[url] = state_1; - // Listen to the load event, update the state and call the callback once the image is loaded - state_1.image.on('load', function (e) { - state_1.loaded = true; - state_1.width = state_1.image.get(0).width; - state_1.height = state_1.image.get(0).height; - _this.callLoadedCallback(state_1); - }); - // Set the image URL to start the loading - state_1.image.attr('src', state_1.url); - } - else { - // We have a state for the requested image, so it is either already loaded or currently loading - var state = this.state[url]; - // We overwrite the callback to make sure that only the callback of the latest call gets executed. - // Earlier callbacks become invalid once a new load call arrives, and they are not called as long as the image - // is not loaded. - state.loadedCallback = loadedCallback; - // When the image is already loaded, we directly execute the callback instead of waiting for the load event - if (state.loaded) { - this.callLoadedCallback(state); - } - } - }; - ImageLoader.prototype.callLoadedCallback = function (state) { - state.loadedCallback(state.url, state.width, state.height); - }; - return ImageLoader; -}()); -exports.ImageLoader = ImageLoader; + +Object.defineProperty(exports, "__esModule", { value: true }); +var dom_1 = __webpack_require__(0); +/** + * Tracks the loading state of images. + */ +var ImageLoader = (function () { + function ImageLoader() { + this.state = {}; + } + /** + * Loads an image and call the callback once the image is loaded. If the image is already loaded, the callback + * is called immediately, else it is called once loading has finished. Calling this method multiple times for the + * same image while it is loading calls only let callback passed into the last call. + * @param url The url to the image to load + * @param loadedCallback The callback that is called when the image is loaded + */ + ImageLoader.prototype.load = function (url, loadedCallback) { + var _this = this; + if (!this.state[url]) { + // When the image was never attempted to be loaded before, we create a state and store it in the state map + // for later use when the same image is requested to be loaded again. + var state_1 = { + url: url, + image: new dom_1.DOM('img', {}), + loadedCallback: loadedCallback, + loaded: false, + width: 0, + height: 0, + }; + this.state[url] = state_1; + // Listen to the load event, update the state and call the callback once the image is loaded + state_1.image.on('load', function (e) { + state_1.loaded = true; + state_1.width = state_1.image.get(0).width; + state_1.height = state_1.image.get(0).height; + _this.callLoadedCallback(state_1); + }); + // Set the image URL to start the loading + state_1.image.attr('src', state_1.url); + } + else { + // We have a state for the requested image, so it is either already loaded or currently loading + var state = this.state[url]; + // We overwrite the callback to make sure that only the callback of the latest call gets executed. + // Earlier callbacks become invalid once a new load call arrives, and they are not called as long as the image + // is not loaded. + state.loadedCallback = loadedCallback; + // When the image is already loaded, we directly execute the callback instead of waiting for the load event + if (state.loaded) { + this.callLoadedCallback(state); + } + } + }; + ImageLoader.prototype.callLoadedCallback = function (state) { + state.loadedCallback(state.url, state.width, state.height); + }; + return ImageLoader; +}()); +exports.ImageLoader = ImageLoader; /***/ }), @@ -5441,65 +5453,65 @@ exports.ImageLoader = ImageLoader; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var selectbox_1 = __webpack_require__(21); -/** - * A select box providing a selection between available subtitle and caption tracks. - */ -var SubtitleSelectBox = (function (_super) { - __extends(SubtitleSelectBox, _super); - function SubtitleSelectBox(config) { - if (config === void 0) { config = {}; } - return _super.call(this, config) || this; - } - SubtitleSelectBox.prototype.configure = function (player, uimanager) { - var _this = this; - _super.prototype.configure.call(this, player, uimanager); - var selectCurrentSubtitle = function () { - var currentSubtitle = player.getSubtitle(); - if (currentSubtitle) { - _this.selectItem(currentSubtitle.id); - } - }; - var updateSubtitles = function () { - _this.clearItems(); - for (var _i = 0, _a = player.getAvailableSubtitles(); _i < _a.length; _i++) { - var subtitle = _a[_i]; - _this.addItem(subtitle.id, subtitle.label); - } - // Select the correct subtitle after the subtitles have been added - selectCurrentSubtitle(); - }; - this.onItemSelected.subscribe(function (sender, value) { - player.setSubtitle(value === 'null' ? null : value); - }); - // React to API events - player.addEventHandler(player.EVENT.ON_SUBTITLE_ADDED, updateSubtitles); - player.addEventHandler(player.EVENT.ON_SUBTITLE_CHANGED, selectCurrentSubtitle); - player.addEventHandler(player.EVENT.ON_SUBTITLE_REMOVED, updateSubtitles); - // Update subtitles when source goes away - player.addEventHandler(player.EVENT.ON_SOURCE_UNLOADED, updateSubtitles); - // Update subtitles when a new source is loaded - player.addEventHandler(player.EVENT.ON_READY, updateSubtitles); - // Update subtitles when the period within a source changes - player.addEventHandler(player.EVENT.ON_PERIOD_SWITCHED, updateSubtitles); - // Populate subtitles at startup - updateSubtitles(); - }; - return SubtitleSelectBox; -}(selectbox_1.SelectBox)); -exports.SubtitleSelectBox = SubtitleSelectBox; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var selectbox_1 = __webpack_require__(21); +/** + * A select box providing a selection between available subtitle and caption tracks. + */ +var SubtitleSelectBox = (function (_super) { + __extends(SubtitleSelectBox, _super); + function SubtitleSelectBox(config) { + if (config === void 0) { config = {}; } + return _super.call(this, config) || this; + } + SubtitleSelectBox.prototype.configure = function (player, uimanager) { + var _this = this; + _super.prototype.configure.call(this, player, uimanager); + var selectCurrentSubtitle = function () { + var currentSubtitle = player.getSubtitle(); + if (currentSubtitle) { + _this.selectItem(currentSubtitle.id); + } + }; + var updateSubtitles = function () { + _this.clearItems(); + for (var _i = 0, _a = player.getAvailableSubtitles(); _i < _a.length; _i++) { + var subtitle = _a[_i]; + _this.addItem(subtitle.id, subtitle.label); + } + // Select the correct subtitle after the subtitles have been added + selectCurrentSubtitle(); + }; + this.onItemSelected.subscribe(function (sender, value) { + player.setSubtitle(value === 'null' ? null : value); + }); + // React to API events + player.addEventHandler(player.EVENT.ON_SUBTITLE_ADDED, updateSubtitles); + player.addEventHandler(player.EVENT.ON_SUBTITLE_CHANGED, selectCurrentSubtitle); + player.addEventHandler(player.EVENT.ON_SUBTITLE_REMOVED, updateSubtitles); + // Update subtitles when source goes away + player.addEventHandler(player.EVENT.ON_SOURCE_UNLOADED, updateSubtitles); + // Update subtitles when a new source is loaded + player.addEventHandler(player.EVENT.ON_READY, updateSubtitles); + // Update subtitles when the period within a source changes + player.addEventHandler(player.EVENT.ON_PERIOD_SWITCHED, updateSubtitles); + // Populate subtitles at startup + updateSubtitles(); + }; + return SubtitleSelectBox; +}(selectbox_1.SelectBox)); +exports.SubtitleSelectBox = SubtitleSelectBox; /***/ }), @@ -5507,362 +5519,362 @@ exports.SubtitleSelectBox = SubtitleSelectBox; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var container_1 = __webpack_require__(1); -var label_1 = __webpack_require__(7); -var controlbar_1 = __webpack_require__(15); -/** - * Overlays the player to display subtitles. - */ -var SubtitleOverlay = (function (_super) { - __extends(SubtitleOverlay, _super); - function SubtitleOverlay(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.previewSubtitleActive = false; - _this.previewSubtitle = new SubtitleLabel({ text: 'example subtitle' }); - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-subtitle-overlay', - }, _this.config); - return _this; - } - SubtitleOverlay.prototype.configure = function (player, uimanager) { - var _this = this; - _super.prototype.configure.call(this, player, uimanager); - var subtitleManager = new ActiveSubtitleManager(); - this.subtitleManager = subtitleManager; - player.addEventHandler(player.EVENT.ON_CUE_ENTER, function (event) { - // Sanitize cue data (must be done before the cue ID is generated in subtitleManager.cueEnter) - if (event.position) { - // Sometimes the positions are undefined, we assume them to be zero - event.position.row = event.position.row || 0; - event.position.column = event.position.column || 0; - } - var labelToAdd = subtitleManager.cueEnter(event); - if (_this.previewSubtitleActive) { - _this.removeComponent(_this.previewSubtitle); - } - _this.addComponent(labelToAdd); - _this.updateComponents(); - _this.show(); - }); - player.addEventHandler(player.EVENT.ON_CUE_EXIT, function (event) { - var labelToRemove = subtitleManager.cueExit(event); - if (labelToRemove) { - _this.removeComponent(labelToRemove); - _this.updateComponents(); - } - if (!subtitleManager.hasCues) { - if (!_this.previewSubtitleActive) { - _this.hide(); - } - else { - _this.addComponent(_this.previewSubtitle); - _this.updateComponents(); - } - } - }); - var subtitleClearHandler = function () { - _this.hide(); - subtitleManager.clear(); - _this.removeComponents(); - _this.updateComponents(); - }; - player.addEventHandler(player.EVENT.ON_AUDIO_CHANGED, subtitleClearHandler); - player.addEventHandler(player.EVENT.ON_SUBTITLE_CHANGED, subtitleClearHandler); - player.addEventHandler(player.EVENT.ON_SEEK, subtitleClearHandler); - player.addEventHandler(player.EVENT.ON_TIME_SHIFT, subtitleClearHandler); - player.addEventHandler(player.EVENT.ON_PLAYBACK_FINISHED, subtitleClearHandler); - player.addEventHandler(player.EVENT.ON_SOURCE_UNLOADED, subtitleClearHandler); - uimanager.onComponentShow.subscribe(function (component) { - if (component instanceof controlbar_1.ControlBar) { - _this.getDomElement().addClass(_this.prefixCss(SubtitleOverlay.CLASS_CONTROLBAR_VISIBLE)); - } - }); - uimanager.onComponentHide.subscribe(function (component) { - if (component instanceof controlbar_1.ControlBar) { - _this.getDomElement().removeClass(_this.prefixCss(SubtitleOverlay.CLASS_CONTROLBAR_VISIBLE)); - } - }); - this.configureCea608Captions(player, uimanager); - // Init - subtitleClearHandler(); - }; - SubtitleOverlay.prototype.configureCea608Captions = function (player, uimanager) { - var _this = this; - // The calculated font size - var fontSize = 0; - // The required letter spacing spread the text characters evenly across the grid - var fontLetterSpacing = 0; - // Flag telling if a font size calculation is required of if the current values are valid - var fontSizeCalculationRequired = true; - // Flag telling if the CEA-608 mode is enabled - var enabled = false; - var updateCEA608FontSize = function () { - var dummyLabel = new SubtitleLabel({ text: 'X' }); - dummyLabel.getDomElement().css({ - // By using a large font size we do not need to use multiple letters and can get still an - // accurate measurement even though the returned size is an integer value - 'font-size': '200px', - 'line-height': '200px', - 'visibility': 'hidden', - }); - _this.addComponent(dummyLabel); - _this.updateComponents(); - _this.show(); - var dummyLabelCharWidth = dummyLabel.getDomElement().width(); - var dummyLabelCharHeight = dummyLabel.getDomElement().height(); - var fontSizeRatio = dummyLabelCharWidth / dummyLabelCharHeight; - _this.removeComponent(dummyLabel); - _this.updateComponents(); - if (!_this.subtitleManager.hasCues) { - _this.hide(); - } - // The size ratio of the letter grid - var fontGridSizeRatio = (dummyLabelCharWidth * SubtitleOverlay.CEA608_NUM_COLUMNS) / - (dummyLabelCharHeight * SubtitleOverlay.CEA608_NUM_ROWS); - // The size ratio of the available space for the grid - var subtitleOverlaySizeRatio = _this.getDomElement().width() / _this.getDomElement().height(); - if (subtitleOverlaySizeRatio > fontGridSizeRatio) { - // When the available space is wider than the text grid, the font size is simply - // determined by the height of the available space. - fontSize = _this.getDomElement().height() / SubtitleOverlay.CEA608_NUM_ROWS; - // Calculate the additional letter spacing required to evenly spread the text across the grid's width - var gridSlotWidth = _this.getDomElement().width() / SubtitleOverlay.CEA608_NUM_COLUMNS; - var fontCharWidth = fontSize * fontSizeRatio; - fontLetterSpacing = gridSlotWidth - fontCharWidth; - } - else { - // When the available space is not wide enough, texts would vertically overlap if we take - // the height as a base for the font size, so we need to limit the height. We do that - // by determining the font size by the width of the available space. - fontSize = _this.getDomElement().width() / SubtitleOverlay.CEA608_NUM_COLUMNS / fontSizeRatio; - fontLetterSpacing = 0; - } - // Update font-size of all active subtitle labels - for (var _i = 0, _a = _this.getComponents(); _i < _a.length; _i++) { - var label = _a[_i]; - if (label instanceof SubtitleLabel) { - label.getDomElement().css({ - 'font-size': fontSize + "px", - 'letter-spacing': fontLetterSpacing + "px", - }); - } - } - }; - player.addEventHandler(player.EVENT.ON_PLAYER_RESIZE, function () { - if (enabled) { - updateCEA608FontSize(); - } - else { - fontSizeCalculationRequired = true; - } - }); - player.addEventHandler(player.EVENT.ON_CUE_ENTER, function (event) { - var isCEA608 = event.position != null; - if (!isCEA608) { - // Skip all non-CEA608 cues - return; - } - var labels = _this.subtitleManager.getCues(event); - if (!enabled) { - enabled = true; - _this.getDomElement().addClass(_this.prefixCss(SubtitleOverlay.CLASS_CEA_608)); - // We conditionally update the font size by this flag here to avoid updating every time a subtitle - // is added into an empty overlay. Because we reset the overlay when all subtitles are gone, this - // would trigger an unnecessary update every time, but it's only required under certain conditions, - // e.g. after the player size has changed. - if (fontSizeCalculationRequired) { - updateCEA608FontSize(); - fontSizeCalculationRequired = false; - } - } - for (var _i = 0, labels_1 = labels; _i < labels_1.length; _i++) { - var label = labels_1[_i]; - label.getDomElement().css({ - 'left': event.position.column * SubtitleOverlay.CEA608_COLUMN_OFFSET + "%", - 'top': event.position.row * SubtitleOverlay.CEA608_ROW_OFFSET + "%", - 'font-size': fontSize + "px", - 'letter-spacing': fontLetterSpacing + "px", - }); - } - }); - var reset = function () { - _this.getDomElement().removeClass(_this.prefixCss(SubtitleOverlay.CLASS_CEA_608)); - enabled = false; - }; - player.addEventHandler(player.EVENT.ON_CUE_EXIT, function () { - if (!_this.subtitleManager.hasCues) { - // Disable CEA-608 mode when all subtitles are gone (to allow correct formatting and - // display of other types of subtitles, e.g. the formatting preview subtitle) - reset(); - } - }); - player.addEventHandler(player.EVENT.ON_SOURCE_UNLOADED, reset); - player.addEventHandler(player.EVENT.ON_SUBTITLE_CHANGED, reset); - }; - SubtitleOverlay.prototype.enablePreviewSubtitleLabel = function () { - this.previewSubtitleActive = true; - if (!this.subtitleManager.hasCues) { - this.addComponent(this.previewSubtitle); - this.updateComponents(); - this.show(); - } - }; - SubtitleOverlay.prototype.removePreviewSubtitleLabel = function () { - this.previewSubtitleActive = false; - this.removeComponent(this.previewSubtitle); - this.updateComponents(); - }; - return SubtitleOverlay; -}(container_1.Container)); -SubtitleOverlay.CLASS_CONTROLBAR_VISIBLE = 'controlbar-visible'; -SubtitleOverlay.CLASS_CEA_608 = 'cea608'; -// The number of rows in a cea608 grid -SubtitleOverlay.CEA608_NUM_ROWS = 15; -// The number of columns in a cea608 grid -SubtitleOverlay.CEA608_NUM_COLUMNS = 32; -// The offset in percent for one row (which is also the height of a row) -SubtitleOverlay.CEA608_ROW_OFFSET = 100 / SubtitleOverlay.CEA608_NUM_ROWS; -// The offset in percent for one column (which is also the width of a column) -SubtitleOverlay.CEA608_COLUMN_OFFSET = 100 / SubtitleOverlay.CEA608_NUM_COLUMNS; -exports.SubtitleOverlay = SubtitleOverlay; -var SubtitleLabel = (function (_super) { - __extends(SubtitleLabel, _super); - function SubtitleLabel(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-subtitle-label', - }, _this.config); - return _this; - } - return SubtitleLabel; -}(label_1.Label)); -var ActiveSubtitleManager = (function () { - function ActiveSubtitleManager() { - this.activeSubtitleCueMap = {}; - this.activeSubtitleCueCount = 0; - } - /** - * Calculates a unique ID for a subtitle cue, which is needed to associate an ON_CUE_ENTER with its ON_CUE_EXIT - * event so we can remove the correct subtitle in ON_CUE_EXIT when multiple subtitles are active at the same time. - * The start time plus the text should make a unique identifier, and in the only case where a collision - * can happen, two similar texts will be displayed at a similar time and a similar position (or without position). - * The start time should always be known, because it is required to schedule the ON_CUE_ENTER event. The end time - * must not necessarily be known and therefore cannot be used for the ID. - * @param event - * @return {string} - */ - ActiveSubtitleManager.calculateId = function (event) { - var id = event.start + '-' + event.text; - if (event.position) { - id += '-' + event.position.row + '-' + event.position.column; - } - return id; - }; - /** - * Adds a subtitle cue to the manager and returns the label that should be added to the subtitle overlay. - * @param event - * @return {SubtitleLabel} - */ - ActiveSubtitleManager.prototype.cueEnter = function (event) { - var id = ActiveSubtitleManager.calculateId(event); - var label = new SubtitleLabel({ - // Prefer the HTML subtitle text if set, else use the plain text - text: event.html || event.text, - }); - // Create array for id if it does not exist - this.activeSubtitleCueMap[id] = this.activeSubtitleCueMap[id] || []; - // Add cue - this.activeSubtitleCueMap[id].push({ event: event, label: label }); - this.activeSubtitleCueCount++; - return label; - }; - /** - * Returns the label associated with an already added cue. - * @param event - * @return {SubtitleLabel} - */ - ActiveSubtitleManager.prototype.getCues = function (event) { - var id = ActiveSubtitleManager.calculateId(event); - var activeSubtitleCues = this.activeSubtitleCueMap[id]; - if (activeSubtitleCues && activeSubtitleCues.length > 0) { - return activeSubtitleCues.map(function (cue) { return cue.label; }); - } - else { - return null; - } - }; - /** - * Removes the subtitle cue from the manager and returns the label that should be removed from the subtitle overlay, - * or null if there is no associated label existing (e.g. because all labels have been {@link #clear cleared}. - * @param event - * @return {SubtitleLabel|null} - */ - ActiveSubtitleManager.prototype.cueExit = function (event) { - var id = ActiveSubtitleManager.calculateId(event); - var activeSubtitleCues = this.activeSubtitleCueMap[id]; - if (activeSubtitleCues && activeSubtitleCues.length > 0) { - // Remove cue - /* We apply the FIFO approach here and remove the oldest cue from the associated id. When there are multiple cues - * with the same id, there is no way to know which one of the cues is to be deleted, so we just hope that FIFO - * works fine. Theoretically it can happen that two cues with colliding ids are removed at different times, in - * the wrong order. This rare case has yet to be observed. If it ever gets an issue, we can take the unstable - * cue end time (which can change between ON_CUE_ENTER and ON_CUE_EXIT IN ON_CUE_UPDATE) and use it as an - * additional hint to try and remove the correct one of the colliding cues. - */ - var activeSubtitleCue = activeSubtitleCues.shift(); - this.activeSubtitleCueCount--; - return activeSubtitleCue.label; - } - else { - return null; - } - }; - Object.defineProperty(ActiveSubtitleManager.prototype, "cueCount", { - /** - * Returns the number of active subtitle cues. - * @return {number} - */ - get: function () { - // We explicitly count the cues to save an Array.reduce on every cueCount call (which can happen frequently) - return this.activeSubtitleCueCount; - }, - enumerable: true, - configurable: true - }); - Object.defineProperty(ActiveSubtitleManager.prototype, "hasCues", { - /** - * Returns true if there are active subtitle cues, else false. - * @return {boolean} - */ - get: function () { - return this.cueCount > 0; - }, - enumerable: true, - configurable: true - }); - /** - * Removes all subtitle cues from the manager. - */ - ActiveSubtitleManager.prototype.clear = function () { - this.activeSubtitleCueMap = {}; - this.activeSubtitleCueCount = 0; - }; - return ActiveSubtitleManager; -}()); + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var container_1 = __webpack_require__(1); +var label_1 = __webpack_require__(7); +var controlbar_1 = __webpack_require__(15); +/** + * Overlays the player to display subtitles. + */ +var SubtitleOverlay = (function (_super) { + __extends(SubtitleOverlay, _super); + function SubtitleOverlay(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.previewSubtitleActive = false; + _this.previewSubtitle = new SubtitleLabel({ text: 'example subtitle' }); + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-subtitle-overlay', + }, _this.config); + return _this; + } + SubtitleOverlay.prototype.configure = function (player, uimanager) { + var _this = this; + _super.prototype.configure.call(this, player, uimanager); + var subtitleManager = new ActiveSubtitleManager(); + this.subtitleManager = subtitleManager; + player.addEventHandler(player.EVENT.ON_CUE_ENTER, function (event) { + // Sanitize cue data (must be done before the cue ID is generated in subtitleManager.cueEnter) + if (event.position) { + // Sometimes the positions are undefined, we assume them to be zero + event.position.row = event.position.row || 0; + event.position.column = event.position.column || 0; + } + var labelToAdd = subtitleManager.cueEnter(event); + if (_this.previewSubtitleActive) { + _this.removeComponent(_this.previewSubtitle); + } + _this.addComponent(labelToAdd); + _this.updateComponents(); + _this.show(); + }); + player.addEventHandler(player.EVENT.ON_CUE_EXIT, function (event) { + var labelToRemove = subtitleManager.cueExit(event); + if (labelToRemove) { + _this.removeComponent(labelToRemove); + _this.updateComponents(); + } + if (!subtitleManager.hasCues) { + if (!_this.previewSubtitleActive) { + _this.hide(); + } + else { + _this.addComponent(_this.previewSubtitle); + _this.updateComponents(); + } + } + }); + var subtitleClearHandler = function () { + _this.hide(); + subtitleManager.clear(); + _this.removeComponents(); + _this.updateComponents(); + }; + player.addEventHandler(player.EVENT.ON_AUDIO_CHANGED, subtitleClearHandler); + player.addEventHandler(player.EVENT.ON_SUBTITLE_CHANGED, subtitleClearHandler); + player.addEventHandler(player.EVENT.ON_SEEK, subtitleClearHandler); + player.addEventHandler(player.EVENT.ON_TIME_SHIFT, subtitleClearHandler); + player.addEventHandler(player.EVENT.ON_PLAYBACK_FINISHED, subtitleClearHandler); + player.addEventHandler(player.EVENT.ON_SOURCE_UNLOADED, subtitleClearHandler); + uimanager.onComponentShow.subscribe(function (component) { + if (component instanceof controlbar_1.ControlBar) { + _this.getDomElement().addClass(_this.prefixCss(SubtitleOverlay.CLASS_CONTROLBAR_VISIBLE)); + } + }); + uimanager.onComponentHide.subscribe(function (component) { + if (component instanceof controlbar_1.ControlBar) { + _this.getDomElement().removeClass(_this.prefixCss(SubtitleOverlay.CLASS_CONTROLBAR_VISIBLE)); + } + }); + this.configureCea608Captions(player, uimanager); + // Init + subtitleClearHandler(); + }; + SubtitleOverlay.prototype.configureCea608Captions = function (player, uimanager) { + var _this = this; + // The calculated font size + var fontSize = 0; + // The required letter spacing spread the text characters evenly across the grid + var fontLetterSpacing = 0; + // Flag telling if a font size calculation is required of if the current values are valid + var fontSizeCalculationRequired = true; + // Flag telling if the CEA-608 mode is enabled + var enabled = false; + var updateCEA608FontSize = function () { + var dummyLabel = new SubtitleLabel({ text: 'X' }); + dummyLabel.getDomElement().css({ + // By using a large font size we do not need to use multiple letters and can get still an + // accurate measurement even though the returned size is an integer value + 'font-size': '200px', + 'line-height': '200px', + 'visibility': 'hidden', + }); + _this.addComponent(dummyLabel); + _this.updateComponents(); + _this.show(); + var dummyLabelCharWidth = dummyLabel.getDomElement().width(); + var dummyLabelCharHeight = dummyLabel.getDomElement().height(); + var fontSizeRatio = dummyLabelCharWidth / dummyLabelCharHeight; + _this.removeComponent(dummyLabel); + _this.updateComponents(); + if (!_this.subtitleManager.hasCues) { + _this.hide(); + } + // The size ratio of the letter grid + var fontGridSizeRatio = (dummyLabelCharWidth * SubtitleOverlay.CEA608_NUM_COLUMNS) / + (dummyLabelCharHeight * SubtitleOverlay.CEA608_NUM_ROWS); + // The size ratio of the available space for the grid + var subtitleOverlaySizeRatio = _this.getDomElement().width() / _this.getDomElement().height(); + if (subtitleOverlaySizeRatio > fontGridSizeRatio) { + // When the available space is wider than the text grid, the font size is simply + // determined by the height of the available space. + fontSize = _this.getDomElement().height() / SubtitleOverlay.CEA608_NUM_ROWS; + // Calculate the additional letter spacing required to evenly spread the text across the grid's width + var gridSlotWidth = _this.getDomElement().width() / SubtitleOverlay.CEA608_NUM_COLUMNS; + var fontCharWidth = fontSize * fontSizeRatio; + fontLetterSpacing = gridSlotWidth - fontCharWidth; + } + else { + // When the available space is not wide enough, texts would vertically overlap if we take + // the height as a base for the font size, so we need to limit the height. We do that + // by determining the font size by the width of the available space. + fontSize = _this.getDomElement().width() / SubtitleOverlay.CEA608_NUM_COLUMNS / fontSizeRatio; + fontLetterSpacing = 0; + } + // Update font-size of all active subtitle labels + for (var _i = 0, _a = _this.getComponents(); _i < _a.length; _i++) { + var label = _a[_i]; + if (label instanceof SubtitleLabel) { + label.getDomElement().css({ + 'font-size': fontSize + "px", + 'letter-spacing': fontLetterSpacing + "px", + }); + } + } + }; + player.addEventHandler(player.EVENT.ON_PLAYER_RESIZE, function () { + if (enabled) { + updateCEA608FontSize(); + } + else { + fontSizeCalculationRequired = true; + } + }); + player.addEventHandler(player.EVENT.ON_CUE_ENTER, function (event) { + var isCEA608 = event.position != null; + if (!isCEA608) { + // Skip all non-CEA608 cues + return; + } + var labels = _this.subtitleManager.getCues(event); + if (!enabled) { + enabled = true; + _this.getDomElement().addClass(_this.prefixCss(SubtitleOverlay.CLASS_CEA_608)); + // We conditionally update the font size by this flag here to avoid updating every time a subtitle + // is added into an empty overlay. Because we reset the overlay when all subtitles are gone, this + // would trigger an unnecessary update every time, but it's only required under certain conditions, + // e.g. after the player size has changed. + if (fontSizeCalculationRequired) { + updateCEA608FontSize(); + fontSizeCalculationRequired = false; + } + } + for (var _i = 0, labels_1 = labels; _i < labels_1.length; _i++) { + var label = labels_1[_i]; + label.getDomElement().css({ + 'left': event.position.column * SubtitleOverlay.CEA608_COLUMN_OFFSET + "%", + 'top': event.position.row * SubtitleOverlay.CEA608_ROW_OFFSET + "%", + 'font-size': fontSize + "px", + 'letter-spacing': fontLetterSpacing + "px", + }); + } + }); + var reset = function () { + _this.getDomElement().removeClass(_this.prefixCss(SubtitleOverlay.CLASS_CEA_608)); + enabled = false; + }; + player.addEventHandler(player.EVENT.ON_CUE_EXIT, function () { + if (!_this.subtitleManager.hasCues) { + // Disable CEA-608 mode when all subtitles are gone (to allow correct formatting and + // display of other types of subtitles, e.g. the formatting preview subtitle) + reset(); + } + }); + player.addEventHandler(player.EVENT.ON_SOURCE_UNLOADED, reset); + player.addEventHandler(player.EVENT.ON_SUBTITLE_CHANGED, reset); + }; + SubtitleOverlay.prototype.enablePreviewSubtitleLabel = function () { + this.previewSubtitleActive = true; + if (!this.subtitleManager.hasCues) { + this.addComponent(this.previewSubtitle); + this.updateComponents(); + this.show(); + } + }; + SubtitleOverlay.prototype.removePreviewSubtitleLabel = function () { + this.previewSubtitleActive = false; + this.removeComponent(this.previewSubtitle); + this.updateComponents(); + }; + return SubtitleOverlay; +}(container_1.Container)); +SubtitleOverlay.CLASS_CONTROLBAR_VISIBLE = 'controlbar-visible'; +SubtitleOverlay.CLASS_CEA_608 = 'cea608'; +// The number of rows in a cea608 grid +SubtitleOverlay.CEA608_NUM_ROWS = 15; +// The number of columns in a cea608 grid +SubtitleOverlay.CEA608_NUM_COLUMNS = 32; +// The offset in percent for one row (which is also the height of a row) +SubtitleOverlay.CEA608_ROW_OFFSET = 100 / SubtitleOverlay.CEA608_NUM_ROWS; +// The offset in percent for one column (which is also the width of a column) +SubtitleOverlay.CEA608_COLUMN_OFFSET = 100 / SubtitleOverlay.CEA608_NUM_COLUMNS; +exports.SubtitleOverlay = SubtitleOverlay; +var SubtitleLabel = (function (_super) { + __extends(SubtitleLabel, _super); + function SubtitleLabel(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-subtitle-label', + }, _this.config); + return _this; + } + return SubtitleLabel; +}(label_1.Label)); +var ActiveSubtitleManager = (function () { + function ActiveSubtitleManager() { + this.activeSubtitleCueMap = {}; + this.activeSubtitleCueCount = 0; + } + /** + * Calculates a unique ID for a subtitle cue, which is needed to associate an ON_CUE_ENTER with its ON_CUE_EXIT + * event so we can remove the correct subtitle in ON_CUE_EXIT when multiple subtitles are active at the same time. + * The start time plus the text should make a unique identifier, and in the only case where a collision + * can happen, two similar texts will be displayed at a similar time and a similar position (or without position). + * The start time should always be known, because it is required to schedule the ON_CUE_ENTER event. The end time + * must not necessarily be known and therefore cannot be used for the ID. + * @param event + * @return {string} + */ + ActiveSubtitleManager.calculateId = function (event) { + var id = event.start + '-' + event.text; + if (event.position) { + id += '-' + event.position.row + '-' + event.position.column; + } + return id; + }; + /** + * Adds a subtitle cue to the manager and returns the label that should be added to the subtitle overlay. + * @param event + * @return {SubtitleLabel} + */ + ActiveSubtitleManager.prototype.cueEnter = function (event) { + var id = ActiveSubtitleManager.calculateId(event); + var label = new SubtitleLabel({ + // Prefer the HTML subtitle text if set, else use the plain text + text: event.html || event.text, + }); + // Create array for id if it does not exist + this.activeSubtitleCueMap[id] = this.activeSubtitleCueMap[id] || []; + // Add cue + this.activeSubtitleCueMap[id].push({ event: event, label: label }); + this.activeSubtitleCueCount++; + return label; + }; + /** + * Returns the label associated with an already added cue. + * @param event + * @return {SubtitleLabel} + */ + ActiveSubtitleManager.prototype.getCues = function (event) { + var id = ActiveSubtitleManager.calculateId(event); + var activeSubtitleCues = this.activeSubtitleCueMap[id]; + if (activeSubtitleCues && activeSubtitleCues.length > 0) { + return activeSubtitleCues.map(function (cue) { return cue.label; }); + } + else { + return null; + } + }; + /** + * Removes the subtitle cue from the manager and returns the label that should be removed from the subtitle overlay, + * or null if there is no associated label existing (e.g. because all labels have been {@link #clear cleared}. + * @param event + * @return {SubtitleLabel|null} + */ + ActiveSubtitleManager.prototype.cueExit = function (event) { + var id = ActiveSubtitleManager.calculateId(event); + var activeSubtitleCues = this.activeSubtitleCueMap[id]; + if (activeSubtitleCues && activeSubtitleCues.length > 0) { + // Remove cue + /* We apply the FIFO approach here and remove the oldest cue from the associated id. When there are multiple cues + * with the same id, there is no way to know which one of the cues is to be deleted, so we just hope that FIFO + * works fine. Theoretically it can happen that two cues with colliding ids are removed at different times, in + * the wrong order. This rare case has yet to be observed. If it ever gets an issue, we can take the unstable + * cue end time (which can change between ON_CUE_ENTER and ON_CUE_EXIT IN ON_CUE_UPDATE) and use it as an + * additional hint to try and remove the correct one of the colliding cues. + */ + var activeSubtitleCue = activeSubtitleCues.shift(); + this.activeSubtitleCueCount--; + return activeSubtitleCue.label; + } + else { + return null; + } + }; + Object.defineProperty(ActiveSubtitleManager.prototype, "cueCount", { + /** + * Returns the number of active subtitle cues. + * @return {number} + */ + get: function () { + // We explicitly count the cues to save an Array.reduce on every cueCount call (which can happen frequently) + return this.activeSubtitleCueCount; + }, + enumerable: true, + configurable: true + }); + Object.defineProperty(ActiveSubtitleManager.prototype, "hasCues", { + /** + * Returns true if there are active subtitle cues, else false. + * @return {boolean} + */ + get: function () { + return this.cueCount > 0; + }, + enumerable: true, + configurable: true + }); + /** + * Removes all subtitle cues from the manager. + */ + ActiveSubtitleManager.prototype.clear = function () { + this.activeSubtitleCueMap = {}; + this.activeSubtitleCueCount = 0; + }; + return ActiveSubtitleManager; +}()); /***/ }), @@ -5870,104 +5882,104 @@ var ActiveSubtitleManager = (function () { /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var component_1 = __webpack_require__(2); -var dom_1 = __webpack_require__(0); -/** - * Animated analog TV static noise. - */ -var TvNoiseCanvas = (function (_super) { - __extends(TvNoiseCanvas, _super); - function TvNoiseCanvas(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.canvasWidth = 160; - _this.canvasHeight = 90; - _this.interferenceHeight = 50; - _this.lastFrameUpdate = 0; - _this.frameInterval = 60; - _this.useAnimationFrame = !!window.requestAnimationFrame; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-tvnoisecanvas', - }, _this.config); - return _this; - } - TvNoiseCanvas.prototype.toDomElement = function () { - return this.canvas = new dom_1.DOM('canvas', { 'class': this.getCssClasses() }); - }; - TvNoiseCanvas.prototype.start = function () { - this.canvasElement = this.canvas.get(0); - this.canvasContext = this.canvasElement.getContext('2d'); - this.noiseAnimationWindowPos = -this.canvasHeight; - this.lastFrameUpdate = 0; - this.canvasElement.width = this.canvasWidth; - this.canvasElement.height = this.canvasHeight; - this.renderFrame(); - }; - TvNoiseCanvas.prototype.stop = function () { - if (this.useAnimationFrame) { - cancelAnimationFrame(this.frameUpdateHandlerId); - } - else { - clearTimeout(this.frameUpdateHandlerId); - } - }; - TvNoiseCanvas.prototype.renderFrame = function () { - // This code has been copied from the player controls.js and simplified - if (this.lastFrameUpdate + this.frameInterval > new Date().getTime()) { - // It's too early to render the next frame - this.scheduleNextRender(); - return; - } - var currentPixelOffset; - var canvasWidth = this.canvasWidth; - var canvasHeight = this.canvasHeight; - // Create texture - var noiseImage = this.canvasContext.createImageData(canvasWidth, canvasHeight); - // Fill texture with noise - for (var y = 0; y < canvasHeight; y++) { - for (var x = 0; x < canvasWidth; x++) { - currentPixelOffset = (canvasWidth * y * 4) + x * 4; - noiseImage.data[currentPixelOffset] = Math.random() * 255; - if (y < this.noiseAnimationWindowPos || y > this.noiseAnimationWindowPos + this.interferenceHeight) { - noiseImage.data[currentPixelOffset] *= 0.85; - } - noiseImage.data[currentPixelOffset + 1] = noiseImage.data[currentPixelOffset]; - noiseImage.data[currentPixelOffset + 2] = noiseImage.data[currentPixelOffset]; - noiseImage.data[currentPixelOffset + 3] = 50; - } - } - // Put texture onto canvas - this.canvasContext.putImageData(noiseImage, 0, 0); - this.lastFrameUpdate = new Date().getTime(); - this.noiseAnimationWindowPos += 7; - if (this.noiseAnimationWindowPos > canvasHeight) { - this.noiseAnimationWindowPos = -canvasHeight; - } - this.scheduleNextRender(); - }; - TvNoiseCanvas.prototype.scheduleNextRender = function () { - if (this.useAnimationFrame) { - this.frameUpdateHandlerId = window.requestAnimationFrame(this.renderFrame.bind(this)); - } - else { - this.frameUpdateHandlerId = setTimeout(this.renderFrame.bind(this), this.frameInterval); - } - }; - return TvNoiseCanvas; -}(component_1.Component)); -exports.TvNoiseCanvas = TvNoiseCanvas; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var component_1 = __webpack_require__(2); +var dom_1 = __webpack_require__(0); +/** + * Animated analog TV static noise. + */ +var TvNoiseCanvas = (function (_super) { + __extends(TvNoiseCanvas, _super); + function TvNoiseCanvas(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.canvasWidth = 160; + _this.canvasHeight = 90; + _this.interferenceHeight = 50; + _this.lastFrameUpdate = 0; + _this.frameInterval = 60; + _this.useAnimationFrame = !!window.requestAnimationFrame; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-tvnoisecanvas', + }, _this.config); + return _this; + } + TvNoiseCanvas.prototype.toDomElement = function () { + return this.canvas = new dom_1.DOM('canvas', { 'class': this.getCssClasses() }); + }; + TvNoiseCanvas.prototype.start = function () { + this.canvasElement = this.canvas.get(0); + this.canvasContext = this.canvasElement.getContext('2d'); + this.noiseAnimationWindowPos = -this.canvasHeight; + this.lastFrameUpdate = 0; + this.canvasElement.width = this.canvasWidth; + this.canvasElement.height = this.canvasHeight; + this.renderFrame(); + }; + TvNoiseCanvas.prototype.stop = function () { + if (this.useAnimationFrame) { + cancelAnimationFrame(this.frameUpdateHandlerId); + } + else { + clearTimeout(this.frameUpdateHandlerId); + } + }; + TvNoiseCanvas.prototype.renderFrame = function () { + // This code has been copied from the player controls.js and simplified + if (this.lastFrameUpdate + this.frameInterval > new Date().getTime()) { + // It's too early to render the next frame + this.scheduleNextRender(); + return; + } + var currentPixelOffset; + var canvasWidth = this.canvasWidth; + var canvasHeight = this.canvasHeight; + // Create texture + var noiseImage = this.canvasContext.createImageData(canvasWidth, canvasHeight); + // Fill texture with noise + for (var y = 0; y < canvasHeight; y++) { + for (var x = 0; x < canvasWidth; x++) { + currentPixelOffset = (canvasWidth * y * 4) + x * 4; + noiseImage.data[currentPixelOffset] = Math.random() * 255; + if (y < this.noiseAnimationWindowPos || y > this.noiseAnimationWindowPos + this.interferenceHeight) { + noiseImage.data[currentPixelOffset] *= 0.85; + } + noiseImage.data[currentPixelOffset + 1] = noiseImage.data[currentPixelOffset]; + noiseImage.data[currentPixelOffset + 2] = noiseImage.data[currentPixelOffset]; + noiseImage.data[currentPixelOffset + 3] = 50; + } + } + // Put texture onto canvas + this.canvasContext.putImageData(noiseImage, 0, 0); + this.lastFrameUpdate = new Date().getTime(); + this.noiseAnimationWindowPos += 7; + if (this.noiseAnimationWindowPos > canvasHeight) { + this.noiseAnimationWindowPos = -canvasHeight; + } + this.scheduleNextRender(); + }; + TvNoiseCanvas.prototype.scheduleNextRender = function () { + if (this.useAnimationFrame) { + this.frameUpdateHandlerId = window.requestAnimationFrame(this.renderFrame.bind(this)); + } + else { + this.frameUpdateHandlerId = setTimeout(this.renderFrame.bind(this), this.frameInterval); + } + }; + return TvNoiseCanvas; +}(component_1.Component)); +exports.TvNoiseCanvas = TvNoiseCanvas; /***/ }), @@ -5975,111 +5987,111 @@ exports.TvNoiseCanvas = TvNoiseCanvas; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var listselector_1 = __webpack_require__(22); -var dom_1 = __webpack_require__(0); -var ItemSelectionList = (function (_super) { - __extends(ItemSelectionList, _super); - function ItemSelectionList(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - tag: 'ul', - cssClass: 'ui-itemselectionlist', - }, _this.config); - return _this; - } - ItemSelectionList.prototype.isActive = function () { - return this.items.length > 1; - }; - ItemSelectionList.prototype.toDomElement = function () { - var listElement = new dom_1.DOM('ul', { - 'id': this.config.id, - 'class': this.getCssClasses(), - }); - this.listElement = listElement; - this.updateDomItems(); - return listElement; - }; - ItemSelectionList.prototype.updateDomItems = function (selectedValue) { - var _this = this; - if (selectedValue === void 0) { selectedValue = null; } - // Delete all children - this.listElement.empty(); - var selectedListItem = null; - var selectItem = function (listItem) { - listItem.addClass(_this.prefixCss(ItemSelectionList.CLASS_SELECTED)); - }; - var deselectItem = function (listItem) { - listItem.removeClass(_this.prefixCss(ItemSelectionList.CLASS_SELECTED)); - }; - var _loop_1 = function (item) { - var listItem = new dom_1.DOM('li', { - 'type': 'li', - 'class': this_1.prefixCss('ui-selectionlistitem'), - }).append(new dom_1.DOM('a', {}).html(item.label)); - if (!selectedListItem) { - if (selectedValue == null) { - selectedListItem = listItem; - } - else if (String(selectedValue) === item.key) { - selectedListItem = listItem; - } - } - // Handle list item selections - listItem.on('click', function () { - // Deselect the previous item (if there was a selected item) - if (selectedListItem) { - deselectItem(selectedListItem); - } - // Select the clicked item - selectedListItem = listItem; - selectItem(listItem); - // Fire the event - _this.onItemSelectedEvent(item.key, false); - }); - // Select default item - if (selectedListItem) { - selectItem(selectedListItem); - } - this_1.listElement.append(listItem); - }; - var this_1 = this; - for (var _i = 0, _a = this.items; _i < _a.length; _i++) { - var item = _a[_i]; - _loop_1(item); - } - }; - ItemSelectionList.prototype.onItemAddedEvent = function (value) { - _super.prototype.onItemAddedEvent.call(this, value); - this.updateDomItems(this.selectedItem); - }; - ItemSelectionList.prototype.onItemRemovedEvent = function (value) { - _super.prototype.onItemRemovedEvent.call(this, value); - this.updateDomItems(this.selectedItem); - }; - ItemSelectionList.prototype.onItemSelectedEvent = function (value, updateDomItems) { - if (updateDomItems === void 0) { updateDomItems = true; } - _super.prototype.onItemSelectedEvent.call(this, value); - if (updateDomItems) { - this.updateDomItems(value); - } - }; - return ItemSelectionList; -}(listselector_1.ListSelector)); -ItemSelectionList.CLASS_SELECTED = 'selected'; -exports.ItemSelectionList = ItemSelectionList; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var listselector_1 = __webpack_require__(22); +var dom_1 = __webpack_require__(0); +var ItemSelectionList = (function (_super) { + __extends(ItemSelectionList, _super); + function ItemSelectionList(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + tag: 'ul', + cssClass: 'ui-itemselectionlist', + }, _this.config); + return _this; + } + ItemSelectionList.prototype.isActive = function () { + return this.items.length > 1; + }; + ItemSelectionList.prototype.toDomElement = function () { + var listElement = new dom_1.DOM('ul', { + 'id': this.config.id, + 'class': this.getCssClasses(), + }); + this.listElement = listElement; + this.updateDomItems(); + return listElement; + }; + ItemSelectionList.prototype.updateDomItems = function (selectedValue) { + var _this = this; + if (selectedValue === void 0) { selectedValue = null; } + // Delete all children + this.listElement.empty(); + var selectedListItem = null; + var selectItem = function (listItem) { + listItem.addClass(_this.prefixCss(ItemSelectionList.CLASS_SELECTED)); + }; + var deselectItem = function (listItem) { + listItem.removeClass(_this.prefixCss(ItemSelectionList.CLASS_SELECTED)); + }; + var _loop_1 = function (item) { + var listItem = new dom_1.DOM('li', { + 'type': 'li', + 'class': this_1.prefixCss('ui-selectionlistitem'), + }).append(new dom_1.DOM('a', {}).html(item.label)); + if (!selectedListItem) { + if (selectedValue == null) { + selectedListItem = listItem; + } + else if (String(selectedValue) === item.key) { + selectedListItem = listItem; + } + } + // Handle list item selections + listItem.on('click', function () { + // Deselect the previous item (if there was a selected item) + if (selectedListItem) { + deselectItem(selectedListItem); + } + // Select the clicked item + selectedListItem = listItem; + selectItem(listItem); + // Fire the event + _this.onItemSelectedEvent(item.key, false); + }); + // Select default item + if (selectedListItem) { + selectItem(selectedListItem); + } + this_1.listElement.append(listItem); + }; + var this_1 = this; + for (var _i = 0, _a = this.items; _i < _a.length; _i++) { + var item = _a[_i]; + _loop_1(item); + } + }; + ItemSelectionList.prototype.onItemAddedEvent = function (value) { + _super.prototype.onItemAddedEvent.call(this, value); + this.updateDomItems(this.selectedItem); + }; + ItemSelectionList.prototype.onItemRemovedEvent = function (value) { + _super.prototype.onItemRemovedEvent.call(this, value); + this.updateDomItems(this.selectedItem); + }; + ItemSelectionList.prototype.onItemSelectedEvent = function (value, updateDomItems) { + if (updateDomItems === void 0) { updateDomItems = true; } + _super.prototype.onItemSelectedEvent.call(this, value); + if (updateDomItems) { + this.updateDomItems(value); + } + }; + return ItemSelectionList; +}(listselector_1.ListSelector)); +ItemSelectionList.CLASS_SELECTED = 'selected'; +exports.ItemSelectionList = ItemSelectionList; /***/ }), @@ -6087,58 +6099,58 @@ exports.ItemSelectionList = ItemSelectionList; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var button_1 = __webpack_require__(6); -/** - * A click overlay that opens an url in a new tab if clicked. - */ -var ClickOverlay = (function (_super) { - __extends(ClickOverlay, _super); - function ClickOverlay(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-clickoverlay', - }, _this.config); - return _this; - } - ClickOverlay.prototype.initialize = function () { - _super.prototype.initialize.call(this); - this.setUrl(this.config.url); - var element = this.getDomElement(); - element.on('click', function () { - if (element.data('url')) { - window.open(element.data('url'), '_blank'); - } - }); - }; - /** - * Gets the URL that should be followed when the watermark is clicked. - * @returns {string} the watermark URL - */ - ClickOverlay.prototype.getUrl = function () { - return this.getDomElement().data('url'); - }; - ClickOverlay.prototype.setUrl = function (url) { - if (url === undefined || url == null) { - url = ''; - } - this.getDomElement().data('url', url); - }; - return ClickOverlay; -}(button_1.Button)); -exports.ClickOverlay = ClickOverlay; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var button_1 = __webpack_require__(6); +/** + * A click overlay that opens an url in a new tab if clicked. + */ +var ClickOverlay = (function (_super) { + __extends(ClickOverlay, _super); + function ClickOverlay(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-clickoverlay', + }, _this.config); + return _this; + } + ClickOverlay.prototype.initialize = function () { + _super.prototype.initialize.call(this); + this.setUrl(this.config.url); + var element = this.getDomElement(); + element.on('click', function () { + if (element.data('url')) { + window.open(element.data('url'), '_blank'); + } + }); + }; + /** + * Gets the URL that should be followed when the watermark is clicked. + * @returns {string} the watermark URL + */ + ClickOverlay.prototype.getUrl = function () { + return this.getDomElement().data('url'); + }; + ClickOverlay.prototype.setUrl = function (url) { + if (url === undefined || url == null) { + url = ''; + } + this.getDomElement().data('url', url); + }; + return ClickOverlay; +}(button_1.Button)); +exports.ClickOverlay = ClickOverlay; /***/ }), @@ -6146,54 +6158,54 @@ exports.ClickOverlay = ClickOverlay; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var button_1 = __webpack_require__(6); -var dom_1 = __webpack_require__(0); -/** - * A button to play/replay a video. - */ -var HugeReplayButton = (function (_super) { - __extends(HugeReplayButton, _super); - function HugeReplayButton(config) { - if (config === void 0) { config = {}; } - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-hugereplaybutton', - text: 'Replay', - }, _this.config); - return _this; - } - HugeReplayButton.prototype.configure = function (player, uimanager) { - _super.prototype.configure.call(this, player, uimanager); - this.onClick.subscribe(function () { - player.play('ui'); - }); - }; - HugeReplayButton.prototype.toDomElement = function () { - var buttonElement = _super.prototype.toDomElement.call(this); - // Add child that contains the play button image - // Setting the image directly on the button does not work together with scaling animations, because the button - // can cover the whole video player are and scaling would extend it beyond. By adding an inner element, confined - // to the size if the image, it can scale inside the player without overshooting. - buttonElement.append(new dom_1.DOM('div', { - 'class': this.prefixCss('image'), - })); - return buttonElement; - }; - return HugeReplayButton; -}(button_1.Button)); -exports.HugeReplayButton = HugeReplayButton; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var button_1 = __webpack_require__(6); +var dom_1 = __webpack_require__(0); +/** + * A button to play/replay a video. + */ +var HugeReplayButton = (function (_super) { + __extends(HugeReplayButton, _super); + function HugeReplayButton(config) { + if (config === void 0) { config = {}; } + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-hugereplaybutton', + text: 'Replay', + }, _this.config); + return _this; + } + HugeReplayButton.prototype.configure = function (player, uimanager) { + _super.prototype.configure.call(this, player, uimanager); + this.onClick.subscribe(function () { + player.play('ui'); + }); + }; + HugeReplayButton.prototype.toDomElement = function () { + var buttonElement = _super.prototype.toDomElement.call(this); + // Add child that contains the play button image + // Setting the image directly on the button does not work together with scaling animations, because the button + // can cover the whole video player are and scaling would extend it beyond. By adding an inner element, confined + // to the size if the image, it can scale inside the player without overshooting. + buttonElement.append(new dom_1.DOM('div', { + 'class': this.prefixCss('image'), + })); + return buttonElement; + }; + return HugeReplayButton; +}(button_1.Button)); +exports.HugeReplayButton = HugeReplayButton; /***/ }), @@ -6201,42 +6213,42 @@ exports.HugeReplayButton = HugeReplayButton; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -var __extends = (this && this.__extends) || (function () { - var extendStatics = Object.setPrototypeOf || - ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || - function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; - return function (d, b) { - extendStatics(d, b); - function __() { this.constructor = d; } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - }; -})(); -Object.defineProperty(exports, "__esModule", { value: true }); -var button_1 = __webpack_require__(6); -/** - * A button that closes (hides) a configured component. - */ -var CloseButton = (function (_super) { - __extends(CloseButton, _super); - function CloseButton(config) { - var _this = _super.call(this, config) || this; - _this.config = _this.mergeConfig(config, { - cssClass: 'ui-closebutton', - text: 'Close', - }, _this.config); - return _this; - } - CloseButton.prototype.configure = function (player, uimanager) { - _super.prototype.configure.call(this, player, uimanager); - var config = this.getConfig(); - this.onClick.subscribe(function () { - config.target.hide(); - }); - }; - return CloseButton; -}(button_1.Button)); -exports.CloseButton = CloseButton; + +var __extends = (this && this.__extends) || (function () { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; +})(); +Object.defineProperty(exports, "__esModule", { value: true }); +var button_1 = __webpack_require__(6); +/** + * A button that closes (hides) a configured component. + */ +var CloseButton = (function (_super) { + __extends(CloseButton, _super); + function CloseButton(config) { + var _this = _super.call(this, config) || this; + _this.config = _this.mergeConfig(config, { + cssClass: 'ui-closebutton', + text: 'Close', + }, _this.config); + return _this; + } + CloseButton.prototype.configure = function (player, uimanager) { + _super.prototype.configure.call(this, player, uimanager); + var config = this.getConfig(); + this.onClick.subscribe(function () { + config.target.hide(); + }); + }; + return CloseButton; +}(button_1.Button)); +exports.CloseButton = CloseButton; /***/ }), @@ -6244,101 +6256,101 @@ exports.CloseButton = CloseButton; /***/ (function(module, exports, __webpack_require__) { "use strict"; - -Object.defineProperty(exports, "__esModule", { value: true }); -var StorageUtils; -(function (StorageUtils) { - var hasLocalStorageCache; - function hasLocalStorage() { - if (hasLocalStorageCache) { - return hasLocalStorageCache; - } - // hasLocalStorage is used to safely ensure we can use localStorage - // taken from https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API#Feature-detecting_localStorage - var storage = window['localStorage']; - try { - var x = '__storage_test__'; - storage.setItem(x, x); - storage.removeItem(x); - hasLocalStorageCache = true; - } - catch (e) { - hasLocalStorageCache = e instanceof DOMException && ( - // everything except Firefox - e.code === 22 || - // Firefox - e.code === 1014 || - // test name field too, because code might not be present - // everything except Firefox - e.name === 'QuotaExceededError' || - // Firefox - e.name === 'NS_ERROR_DOM_QUOTA_REACHED') && - // acknowledge QuotaExceededError only if there's something already stored - storage.length !== 0; - } - return hasLocalStorageCache; - } - StorageUtils.hasLocalStorage = hasLocalStorage; - /** - * Stores a string item into localStorage. - * @param key the item's key - * @param data the item's data - */ - function setItem(key, data) { - if (StorageUtils.hasLocalStorage()) { - window.localStorage.setItem(key, data); - } - } - StorageUtils.setItem = setItem; - /** - * Gets an item's string value from the localStorage. - * @param key the key to look up its associated value - * @return {string | null} Returns the string if found, null if there is no data stored for the key - */ - function getItem(key) { - if (StorageUtils.hasLocalStorage()) { - return window.localStorage.getItem(key); - } - else { - return null; - } - } - StorageUtils.getItem = getItem; - /** - * Stores an object into localStorage. The object will be serialized to JSON. The following types are supported - * in addition to the default types: - * - ColorUtils.Color - * - * @param key the key to store the data to - * @param data the object to store - */ - function setObject(key, data) { - if (StorageUtils.hasLocalStorage()) { - var json = JSON.stringify(data); - setItem(key, json); - } - } - StorageUtils.setObject = setObject; - /** - * Gets an object for the given key from localStorage. The object will be deserialized from JSON. Beside the - * default types, the following types are supported: - * - ColorUtils.Color - * - * @param key the key to look up its associated object - * @return {any} Returns the object if found, null otherwise - */ - function getObject(key) { - if (StorageUtils.hasLocalStorage()) { - var json = getItem(key); - if (key) { - var object = JSON.parse(json); - return object; - } - } - return null; - } - StorageUtils.getObject = getObject; -})(StorageUtils = exports.StorageUtils || (exports.StorageUtils = {})); + +Object.defineProperty(exports, "__esModule", { value: true }); +var StorageUtils; +(function (StorageUtils) { + var hasLocalStorageCache; + function hasLocalStorage() { + if (hasLocalStorageCache) { + return hasLocalStorageCache; + } + // hasLocalStorage is used to safely ensure we can use localStorage + // taken from https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API#Feature-detecting_localStorage + var storage = window['localStorage']; + try { + var x = '__storage_test__'; + storage.setItem(x, x); + storage.removeItem(x); + hasLocalStorageCache = true; + } + catch (e) { + hasLocalStorageCache = e instanceof DOMException && ( + // everything except Firefox + e.code === 22 || + // Firefox + e.code === 1014 || + // test name field too, because code might not be present + // everything except Firefox + e.name === 'QuotaExceededError' || + // Firefox + e.name === 'NS_ERROR_DOM_QUOTA_REACHED') && + // acknowledge QuotaExceededError only if there's something already stored + storage.length !== 0; + } + return hasLocalStorageCache; + } + StorageUtils.hasLocalStorage = hasLocalStorage; + /** + * Stores a string item into localStorage. + * @param key the item's key + * @param data the item's data + */ + function setItem(key, data) { + if (StorageUtils.hasLocalStorage()) { + window.localStorage.setItem(key, data); + } + } + StorageUtils.setItem = setItem; + /** + * Gets an item's string value from the localStorage. + * @param key the key to look up its associated value + * @return {string | null} Returns the string if found, null if there is no data stored for the key + */ + function getItem(key) { + if (StorageUtils.hasLocalStorage()) { + return window.localStorage.getItem(key); + } + else { + return null; + } + } + StorageUtils.getItem = getItem; + /** + * Stores an object into localStorage. The object will be serialized to JSON. The following types are supported + * in addition to the default types: + * - ColorUtils.Color + * + * @param key the key to store the data to + * @param data the object to store + */ + function setObject(key, data) { + if (StorageUtils.hasLocalStorage()) { + var json = JSON.stringify(data); + setItem(key, json); + } + } + StorageUtils.setObject = setObject; + /** + * Gets an object for the given key from localStorage. The object will be deserialized from JSON. Beside the + * default types, the following types are supported: + * - ColorUtils.Color + * + * @param key the key to look up its associated object + * @return {any} Returns the object if found, null otherwise + */ + function getObject(key) { + if (StorageUtils.hasLocalStorage()) { + var json = getItem(key); + if (key) { + var object = JSON.parse(json); + return object; + } + } + return null; + } + StorageUtils.getObject = getObject; +})(StorageUtils = exports.StorageUtils || (exports.StorageUtils = {})); /***/ }), @@ -6428,4 +6440,4 @@ i.length&&t.push(i.shift());return t}function n(t){var e=!1;return t=JSON.parse( /***/ }) /******/ ]); -//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgODRkNGE4NmIyOWU2NDYxMzVjMGUiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvZG9tLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvY29udGFpbmVyLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvY29tcG9uZW50LnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2V2ZW50ZGlzcGF0Y2hlci50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9hcnJheXV0aWxzLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL3BsYXllcnV0aWxzLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvYnV0dG9uLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvbGFiZWwudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy90b2dnbGVidXR0b24udHMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiYW5ndWxhclwiIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL3RpbWVvdXQudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvYnJvd3NlcnV0aWxzLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvcGxheWJhY2t0b2dnbGVidXR0b24udHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9zZWVrYmFyLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL3N0cmluZ3V0aWxzLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvY29udHJvbGJhci50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci91aXV0aWxzLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvdWljb250YWluZXIudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9wbGF5YmFja3RpbWVsYWJlbC50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3NwYWNlci50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3NlZWtiYXJsYWJlbC50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3NlbGVjdGJveC50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2xpc3RzZWxlY3Rvci50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3ZvbHVtZWNvbnRyb2xidXR0b24udHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy92b2x1bWVzbGlkZXIudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy92b2x1bWV0b2dnbGVidXR0b24udHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9lcnJvcm1lc3NhZ2VvdmVybGF5LnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvcGxheWJhY2t0b2dnbGVvdmVybGF5LnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvaHVnZXBsYXliYWNrdG9nZ2xlYnV0dG9uLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvYXVkaW9vbmx5b3ZlcmxheS50cyIsIndlYnBhY2s6Ly8vLi9pbmRleC50cyIsIndlYnBhY2s6Ly8vLi9iaXRkYXNoLWNvbnRyb2xsZXIudHMiLCJ3ZWJwYWNrOi8vLy4vYml0ZGFzaC1kaXJlY3RpdmUudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvbWFpbi50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci91aW1hbmFnZXIudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvZ3VpZC50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2Z1bGxzY3JlZW50b2dnbGVidXR0b24udHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvaW1hZ2Vsb2FkZXIudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9zdWJ0aXRsZXNlbGVjdGJveC50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3N1YnRpdGxlb3ZlcmxheS50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3R2bm9pc2VjYW52YXMudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9pdGVtc2VsZWN0aW9ubGlzdC50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2NsaWNrb3ZlcmxheS50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2h1Z2VyZXBsYXlidXR0b24udHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9jbG9zZWJ1dHRvbi50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9zdG9yYWdldXRpbHMudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi9oaXZlL2JpdG1vdmluLmhpdmUubWluLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFD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Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0Esa0NBQWtDO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxREFBcUQsdUJBQXVCO0FBQzVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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Qix3QkFBd0IsSUFBSSx1QkFBdUIsR0FBRyxFQUFFLFNBQVMsZ0JBQWdCLEtBQUssa0NBQWtDLGlCQUFpQixhQUFhLHlCQUF5QixlQUFlLGtCQUFrQixPQUFPLE1BQU0sMENBQTBDLDBCQUEwQixvSEFBb0gsbURBQW1ELHFEQUFxRCxtQkFBbUIsa0JBQWtCLHFDQUFxQyxTQUFTLDBDQUEwQyxxREFBcUQsdUNBQXVDLFNBQVMseUpBQXlKLGNBQWMsU0FBUyw0QkFBNEIsa0JBQWtCLHlFQUF5RSx3QkFBd0IsZ05BQWdOLFFBQVEsRUFBRSxlQUFlLGlDQUFpQyxTQUFTLEdBQUcsb0RBQW9ELDRDQUE0QyxrQ0FBa0Msa0VBQWtFLCtCQUErQixRQUFRLDhDQUE4QyxFQUFFLDhDQUE4QyxFQUFFLEtBQUssRUFBRSxlQUFlLDZEQUE2RCxxQ0FBcUMsbUNBQW1DLHFDQUFxQyxRQUFRLEdBQUcsaUJBQWlCLHVFQUF1RSxnREFBZ0QsNkJBQTZCLGlIQUFpSCxTQUFTLHdFQUF3RSxTQUFTLGFBQWEsNEJBQTRCLEdBQUcsdUNBQXVDLHVMQUF1TCxlQUFlLGFBQWEsT0FBTyxjQUFjLCtOQUErTixpREFBaUQscUJBQXFCLEtBQUssU0FBUzs7QUFFMXVuQiIsImZpbGUiOiJtaS1hbmd1bGFyLWJpdGRhc2gtcGxheWVyLmpzIiwic291cmNlc0NvbnRlbnQiOlsiIFx0Ly8gVGhlIG1vZHVsZSBjYWNoZVxuIFx0dmFyIGluc3RhbGxlZE1vZHVsZXMgPSB7fTtcblxuIFx0Ly8gVGhlIHJlcXVpcmUgZnVuY3Rpb25cbiBcdGZ1bmN0aW9uIF9fd2VicGFja19yZXF1aXJlX18obW9kdWxlSWQpIHtcblxuIFx0XHQvLyBDaGVjayBpZiBtb2R1bGUgaXMgaW4gY2FjaGVcbiBcdFx0aWYoaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0pIHtcbiBcdFx0XHRyZXR1cm4gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0uZXhwb3J0cztcbiBcdFx0fVxuIFx0XHQvLyBDcmVhdGUgYSBuZXcgbW9kdWxlIChhbmQgcHV0IGl0IGludG8gdGhlIGNhY2hlKVxuIFx0XHR2YXIgbW9kdWxlID0gaW5zdGFsbGVkTW9kdWxlc1ttb2R1bGVJZF0gPSB7XG4gXHRcdFx0aTogbW9kdWxlSWQsXG4gXHRcdFx0bDogZmFsc2UsXG4gXHRcdFx0ZXhwb3J0czoge31cbiBcdFx0fTtcblxuIFx0XHQvLyBFeGVjdXRlIHRoZSBtb2R1bGUgZnVuY3Rpb25cbiBcdFx0bW9kdWxlc1ttb2R1bGVJZF0uY2FsbChtb2R1bGUuZXhwb3J0cywgbW9kdWxlLCBtb2R1bGUuZXhwb3J0cywgX193ZWJwYWNrX3JlcXVpcmVfXyk7XG5cbiBcdFx0Ly8gRmxhZyB0aGUgbW9kdWxlIGFzIGxvYWRlZFxuIFx0XHRtb2R1bGUubCA9IHRydWU7XG5cbiBcdFx0Ly8gUmV0dXJuIHRoZSBleHBvcnRzIG9mIHRoZSBtb2R1bGVcbiBcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzO1xuIFx0fVxuXG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlcyBvYmplY3QgKF9fd2VicGFja19tb2R1bGVzX18pXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm0gPSBtb2R1bGVzO1xuXG4gXHQvLyBleHBvc2UgdGhlIG1vZHVsZSBjYWNoZVxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5jID0gaW5zdGFsbGVkTW9kdWxlcztcblxuIFx0Ly8gZGVmaW5lIGdldHRlciBmdW5jdGlvbiBmb3IgaGFybW9ueSBleHBvcnRzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQgPSBmdW5jdGlvbihleHBvcnRzLCBuYW1lLCBnZXR0ZXIpIHtcbiBcdFx0aWYoIV9fd2VicGFja19yZXF1aXJlX18ubyhleHBvcnRzLCBuYW1lKSkge1xuIFx0XHRcdE9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBuYW1lLCB7XG4gXHRcdFx0XHRjb25maWd1cmFibGU6IGZhbHNlLFxuIFx0XHRcdFx0ZW51bWVyYWJsZTogdHJ1ZSxcbiBcdFx0XHRcdGdldDogZ2V0dGVyXG4gXHRcdFx0fSk7XG4gXHRcdH1cbiBcdH07XG5cbiBcdC8vIGdldERlZmF1bHRFeHBvcnQgZnVuY3Rpb24gZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBub24taGFybW9ueSBtb2R1bGVzXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLm4gPSBmdW5jdGlvbihtb2R1bGUpIHtcbiBcdFx0dmFyIGdldHRlciA9IG1vZHVsZSAmJiBtb2R1bGUuX19lc01vZHVsZSA/XG4gXHRcdFx0ZnVuY3Rpb24gZ2V0RGVmYXVsdCgpIHsgcmV0dXJuIG1vZHVsZVsnZGVmYXVsdCddOyB9IDpcbiBcdFx0XHRmdW5jdGlvbiBnZXRNb2R1bGVFeHBvcnRzKCkgeyByZXR1cm4gbW9kdWxlOyB9O1xuIFx0XHRfX3dlYnBhY2tfcmVxdWlyZV9fLmQoZ2V0dGVyLCAnYScsIGdldHRlcik7XG4gXHRcdHJldHVybiBnZXR0ZXI7XG4gXHR9O1xuXG4gXHQvLyBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGxcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubyA9IGZ1bmN0aW9uKG9iamVjdCwgcHJvcGVydHkpIHsgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KTsgfTtcblxuIFx0Ly8gX193ZWJwYWNrX3B1YmxpY19wYXRoX19cbiBcdF9fd2VicGFja19yZXF1aXJlX18ucCA9IFwiXCI7XG5cbiBcdC8vIExvYWQgZW50cnkgbW9kdWxlIGFuZCByZXR1cm4gZXhwb3J0c1xuIFx0cmV0dXJuIF9fd2VicGFja19yZXF1aXJlX18oX193ZWJwYWNrX3JlcXVpcmVfXy5zID0gMzApO1xuXG5cblxuLy8gV0VCUEFDSyBGT09URVIgLy9cbi8vIHdlYnBhY2svYm9vdHN0cmFwIDg0ZDRhODZiMjllNjQ2MTM1YzBlIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxuLyoqXHJcbiAqIFNpbXBsZSBET00gbWFuaXB1bGF0aW9uIGFuZCBET00gZWxlbWVudCBldmVudCBoYW5kbGluZyBtb2RlbGVkIGFmdGVyIGpRdWVyeSAoYXMgcmVwbGFjZW1lbnQgZm9yIGpRdWVyeSkuXHJcbiAqXHJcbiAqIExpa2UgalF1ZXJ5LCBET00gb3BlcmF0ZXMgb24gc2luZ2xlIGVsZW1lbnRzIGFuZCBsaXN0cyBvZiBlbGVtZW50cy4gRm9yIGV4YW1wbGU6IGNyZWF0aW5nIGFuIGVsZW1lbnQgcmV0dXJucyBhIERPTVxyXG4gKiBpbnN0YW5jZSB3aXRoIGEgc2luZ2xlIGVsZW1lbnQsIHNlbGVjdGluZyBlbGVtZW50cyByZXR1cm5zIGEgRE9NIGluc3RhbmNlIHdpdGggemVybywgb25lLCBvciBtYW55IGVsZW1lbnRzLiBTaW1pbGFyXHJcbiAqIHRvIGpRdWVyeSwgc2V0dGVycyB1c3VhbGx5IGFmZmVjdCBhbGwgZWxlbWVudHMsIHdoaWxlIGdldHRlcnMgb3BlcmF0ZSBvbiBvbmx5IHRoZSBmaXJzdCBlbGVtZW50LlxyXG4gKiBBbHNvIHNpbWlsYXIgdG8galF1ZXJ5LCBtb3N0IG1ldGhvZHMgKGV4Y2VwdCBnZXR0ZXJzKSByZXR1cm4gdGhlIERPTSBpbnN0YW5jZSBmYWNpbGl0YXRpbmcgZWFzeSBjaGFpbmluZyBvZiBtZXRob2RcclxuICogY2FsbHMuXHJcbiAqXHJcbiAqIEJ1aWx0IHdpdGggdGhlIGhlbHAgb2Y6IGh0dHA6Ly95b3VtaWdodG5vdG5lZWRqcXVlcnkuY29tL1xyXG4gKi9cclxudmFyIERPTSA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBET00oc29tZXRoaW5nLCBhdHRyaWJ1dGVzKSB7XHJcbiAgICAgICAgdGhpcy5kb2N1bWVudCA9IGRvY3VtZW50OyAvLyBTZXQgdGhlIGdsb2JhbCBkb2N1bWVudCB0byB0aGUgbG9jYWwgZG9jdW1lbnQgZmllbGRcclxuICAgICAgICBpZiAoc29tZXRoaW5nIGluc3RhbmNlb2YgQXJyYXkpIHtcclxuICAgICAgICAgICAgaWYgKHNvbWV0aGluZy5sZW5ndGggPiAwICYmIHNvbWV0aGluZ1swXSBpbnN0YW5jZW9mIEhUTUxFbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZWxlbWVudHMgPSBzb21ldGhpbmc7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVsZW1lbnRzID0gZWxlbWVudHM7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoc29tZXRoaW5nIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcclxuICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBzb21ldGhpbmc7XHJcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudHMgPSBbZWxlbWVudF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHNvbWV0aGluZyBpbnN0YW5jZW9mIERvY3VtZW50KSB7XHJcbiAgICAgICAgICAgIC8vIFdoZW4gYSBkb2N1bWVudCBpcyBwYXNzZWQgaW4sIHdlIGRvIG5vdCBkbyBhbnl0aGluZyB3aXRoIGl0LCBidXQgYnkgc2V0dGluZyB0aGlzLmVsZW1lbnRzIHRvIG51bGxcclxuICAgICAgICAgICAgLy8gd2UgZ2l2ZSB0aGUgZXZlbnQgaGFuZGxpbmcgbWV0aG9kIGEgbWVhbnMgdG8gZGV0ZWN0IGlmIHRoZSBldmVudHMgc2hvdWxkIGJlIHJlZ2lzdGVyZWQgb24gdGhlIGRvY3VtZW50XHJcbiAgICAgICAgICAgIC8vIGluc3RlYWQgb2YgZWxlbWVudHMuXHJcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudHMgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChhdHRyaWJ1dGVzKSB7XHJcbiAgICAgICAgICAgIHZhciB0YWdOYW1lID0gc29tZXRoaW5nO1xyXG4gICAgICAgICAgICB2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnTmFtZSk7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGF0dHJpYnV0ZU5hbWUgaW4gYXR0cmlidXRlcykge1xyXG4gICAgICAgICAgICAgICAgdmFyIGF0dHJpYnV0ZVZhbHVlID0gYXR0cmlidXRlc1thdHRyaWJ1dGVOYW1lXTtcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUsIGF0dHJpYnV0ZVZhbHVlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLmVsZW1lbnRzID0gW2VsZW1lbnRdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdmFyIHNlbGVjdG9yID0gc29tZXRoaW5nO1xyXG4gICAgICAgICAgICB0aGlzLmVsZW1lbnRzID0gdGhpcy5maW5kQ2hpbGRFbGVtZW50cyhzZWxlY3Rvcik7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KERPTS5wcm90b3R5cGUsIFwibGVuZ3RoXCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXRzIHRoZSBudW1iZXIgb2YgZWxlbWVudHMgdGhhdCB0aGlzIERPTSBpbnN0YW5jZSBjdXJyZW50bHkgaG9sZHMuXHJcbiAgICAgICAgICogQHJldHVybnMge251bWJlcn0gdGhlIG51bWJlciBvZiBlbGVtZW50c1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50cyA/IHRoaXMuZWxlbWVudHMubGVuZ3RoIDogMDtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgSFRNTCBlbGVtZW50cyB0aGF0IHRoaXMgRE9NIGluc3RhbmNlIGN1cnJlbnRseSBob2xkcy5cclxuICAgICAqIEByZXR1cm5zIHtIVE1MRWxlbWVudFtdfSB0aGUgcmF3IEhUTUwgZWxlbWVudHNcclxuICAgICAqIEBkZXByZWNhdGVkIHVzZSB7QGxpbmsgI2dldCgpfSBpbnN0ZWFkXHJcbiAgICAgKi9cclxuICAgIERPTS5wcm90b3R5cGUuZ2V0RWxlbWVudHMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0KCk7XHJcbiAgICB9O1xyXG4gICAgRE9NLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoaW5kZXgpIHtcclxuICAgICAgICBpZiAoaW5kZXggPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50cztcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoIXRoaXMuZWxlbWVudHMgfHwgaW5kZXggPj0gdGhpcy5lbGVtZW50cy5sZW5ndGggfHwgaW5kZXggPCAtdGhpcy5lbGVtZW50cy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoaW5kZXggPCAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRzW3RoaXMuZWxlbWVudHMubGVuZ3RoIC0gaW5kZXhdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudHNbaW5kZXhdO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEEgc2hvcnRjdXQgbWV0aG9kIGZvciBpdGVyYXRpbmcgYWxsIGVsZW1lbnRzLiBTaG9ydHMgdGhpcy5lbGVtZW50cy5mb3JFYWNoKC4uLikgdG8gdGhpcy5mb3JFYWNoKC4uLikuXHJcbiAgICAgKiBAcGFyYW0gaGFuZGxlciB0aGUgaGFuZGxlciB0byBleGVjdXRlIGFuIG9wZXJhdGlvbiBvbiBhbiBlbGVtZW50XHJcbiAgICAgKi9cclxuICAgIERPTS5wcm90b3R5cGUuZm9yRWFjaCA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmVsZW1lbnRzKSB7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5lbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGhhbmRsZXIoZWxlbWVudCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgRE9NLnByb3RvdHlwZS5maW5kQ2hpbGRFbGVtZW50c09mRWxlbWVudCA9IGZ1bmN0aW9uIChlbGVtZW50LCBzZWxlY3Rvcikge1xyXG4gICAgICAgIHZhciBjaGlsZEVsZW1lbnRzID0gZWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcclxuICAgICAgICAvLyBDb252ZXJ0IE5vZGVMaXN0IHRvIEFycmF5XHJcbiAgICAgICAgLy8gaHR0cHM6Ly90b2RkbW90dG8uY29tL2EtY29tcHJlaGVuc2l2ZS1kaXZlLWludG8tbm9kZWxpc3RzLWFycmF5cy1jb252ZXJ0aW5nLW5vZGVsaXN0cy1hbmQtdW5kZXJzdGFuZGluZy10aGUtZG9tL1xyXG4gICAgICAgIHJldHVybiBbXS5zbGljZS5jYWxsKGNoaWxkRWxlbWVudHMpO1xyXG4gICAgfTtcclxuICAgIERPTS5wcm90b3R5cGUuZmluZENoaWxkRWxlbWVudHMgPSBmdW5jdGlvbiAoc2VsZWN0b3IpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciBhbGxDaGlsZEVsZW1lbnRzID0gW107XHJcbiAgICAgICAgaWYgKHRoaXMuZWxlbWVudHMpIHtcclxuICAgICAgICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgICAgICBhbGxDaGlsZEVsZW1lbnRzID0gYWxsQ2hpbGRFbGVtZW50cy5jb25jYXQoX3RoaXMuZmluZENoaWxkRWxlbWVudHNPZkVsZW1lbnQoZWxlbWVudCwgc2VsZWN0b3IpKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5maW5kQ2hpbGRFbGVtZW50c09mRWxlbWVudChkb2N1bWVudCwgc2VsZWN0b3IpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYWxsQ2hpbGRFbGVtZW50cztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEZpbmRzIGFsbCBjaGlsZCBlbGVtZW50cyBvZiBhbGwgZWxlbWVudHMgbWF0Y2hpbmcgdGhlIHN1cHBsaWVkIHNlbGVjdG9yLlxyXG4gICAgICogQHBhcmFtIHNlbGVjdG9yIHRoZSBzZWxlY3RvciB0byBtYXRjaCB3aXRoIGNoaWxkIGVsZW1lbnRzXHJcbiAgICAgKiBAcmV0dXJucyB7RE9NfSBhIG5ldyBET00gaW5zdGFuY2UgcmVwcmVzZW50aW5nIGFsbCBtYXRjaGVkIGNoaWxkcmVuXHJcbiAgICAgKi9cclxuICAgIERPTS5wcm90b3R5cGUuZmluZCA9IGZ1bmN0aW9uIChzZWxlY3Rvcikge1xyXG4gICAgICAgIHZhciBhbGxDaGlsZEVsZW1lbnRzID0gdGhpcy5maW5kQ2hpbGRFbGVtZW50cyhzZWxlY3Rvcik7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBET00oYWxsQ2hpbGRFbGVtZW50cyk7XHJcbiAgICB9O1xyXG4gICAgRE9NLnByb3RvdHlwZS5odG1sID0gZnVuY3Rpb24gKGNvbnRlbnQpIHtcclxuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2V0SHRtbChjb250ZW50KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEh0bWwoKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgRE9NLnByb3RvdHlwZS5nZXRIdG1sID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRzWzBdLmlubmVySFRNTDtcclxuICAgIH07XHJcbiAgICBET00ucHJvdG90eXBlLnNldEh0bWwgPSBmdW5jdGlvbiAoY29udGVudCkge1xyXG4gICAgICAgIGlmIChjb250ZW50ID09PSB1bmRlZmluZWQgfHwgY29udGVudCA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIC8vIFNldCB0byBlbXB0eSBzdHJpbmcgdG8gYXZvaWQgaW5uZXJIVE1MIGdldHRpbmcgc2V0IHRvICd1bmRlZmluZWQnIChhbGwgYnJvd3NlcnMpIG9yICdudWxsJyAoSUU5KVxyXG4gICAgICAgICAgICBjb250ZW50ID0gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9IGNvbnRlbnQ7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBDbGVhcnMgdGhlIGlubmVyIEhUTUwgb2YgYWxsIGVsZW1lbnRzIChkZWxldGVzIGFsbCBjaGlsZHJlbikuXHJcbiAgICAgKiBAcmV0dXJucyB7RE9NfVxyXG4gICAgICovXHJcbiAgICBET00ucHJvdG90eXBlLmVtcHR5ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICBlbGVtZW50LmlubmVySFRNTCA9ICcnO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgY3VycmVudCB2YWx1ZSBvZiB0aGUgZmlyc3QgZm9ybSBlbGVtZW50LCBlLmcuIHRoZSBzZWxlY3RlZCB2YWx1ZSBvZiBhIHNlbGVjdCBib3ggb3IgdGhlIHRleHQgaWYgYW5cclxuICAgICAqIGlucHV0IGZpZWxkLlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gdGhlIHZhbHVlIG9mIGEgZm9ybSBlbGVtZW50XHJcbiAgICAgKi9cclxuICAgIERPTS5wcm90b3R5cGUudmFsID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBlbGVtZW50ID0gdGhpcy5lbGVtZW50c1swXTtcclxuICAgICAgICBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxTZWxlY3RFbGVtZW50IHx8IGVsZW1lbnQgaW5zdGFuY2VvZiBIVE1MSW5wdXRFbGVtZW50KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBlbGVtZW50LnZhbHVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgLy8gVE9ETyBhZGQgc3VwcG9ydCBmb3IgbWlzc2luZyBmb3JtIGVsZW1lbnRzXHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcInZhbCgpIG5vdCBzdXBwb3J0ZWQgZm9yIFwiICsgdHlwZW9mIGVsZW1lbnQpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBET00ucHJvdG90eXBlLmF0dHIgPSBmdW5jdGlvbiAoYXR0cmlidXRlLCB2YWx1ZSkge1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zZXRBdHRyKGF0dHJpYnV0ZSwgdmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0QXR0cihhdHRyaWJ1dGUpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBET00ucHJvdG90eXBlLmdldEF0dHIgPSBmdW5jdGlvbiAoYXR0cmlidXRlKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudHNbMF0uZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZSk7XHJcbiAgICB9O1xyXG4gICAgRE9NLnByb3RvdHlwZS5zZXRBdHRyID0gZnVuY3Rpb24gKGF0dHJpYnV0ZSwgdmFsdWUpIHtcclxuICAgICAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoYXR0cmlidXRlLCB2YWx1ZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgRE9NLnByb3RvdHlwZS5kYXRhID0gZnVuY3Rpb24gKGRhdGFBdHRyaWJ1dGUsIHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNldERhdGEoZGF0YUF0dHJpYnV0ZSwgdmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RGF0YShkYXRhQXR0cmlidXRlKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgRE9NLnByb3RvdHlwZS5nZXREYXRhID0gZnVuY3Rpb24gKGRhdGFBdHRyaWJ1dGUpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50c1swXS5nZXRBdHRyaWJ1dGUoJ2RhdGEtJyArIGRhdGFBdHRyaWJ1dGUpO1xyXG4gICAgfTtcclxuICAgIERPTS5wcm90b3R5cGUuc2V0RGF0YSA9IGZ1bmN0aW9uIChkYXRhQXR0cmlidXRlLCB2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZSgnZGF0YS0nICsgZGF0YUF0dHJpYnV0ZSwgdmFsdWUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQXBwZW5kcyBvbmUgb3IgbW9yZSBET00gZWxlbWVudHMgYXMgY2hpbGRyZW4gdG8gYWxsIGVsZW1lbnRzLlxyXG4gICAgICogQHBhcmFtIGNoaWxkRWxlbWVudHMgdGhlIGNocmlsZCBlbGVtZW50cyB0byBhcHBlbmRcclxuICAgICAqIEByZXR1cm5zIHtET019XHJcbiAgICAgKi9cclxuICAgIERPTS5wcm90b3R5cGUuYXBwZW5kID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBjaGlsZEVsZW1lbnRzID0gW107XHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgY2hpbGRFbGVtZW50c1tfaV0gPSBhcmd1bWVudHNbX2ldO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgY2hpbGRFbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChjaGlsZEVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgIGNoaWxkRWxlbWVudC5lbGVtZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChfLCBpbmRleCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYXBwZW5kQ2hpbGQoY2hpbGRFbGVtZW50LmVsZW1lbnRzW2luZGV4XSk7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIGFsbCBlbGVtZW50cyBmcm9tIHRoZSBET00uXHJcbiAgICAgKi9cclxuICAgIERPTS5wcm90b3R5cGUucmVtb3ZlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICB2YXIgcGFyZW50ID0gZWxlbWVudC5wYXJlbnROb2RlO1xyXG4gICAgICAgICAgICBpZiAocGFyZW50KSB7XHJcbiAgICAgICAgICAgICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQoZWxlbWVudCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIG9mZnNldCBvZiB0aGUgZmlyc3QgZWxlbWVudCBmcm9tIHRoZSBkb2N1bWVudCdzIHRvcCBsZWZ0IGNvcm5lci5cclxuICAgICAqIEByZXR1cm5zIHtPZmZzZXR9XHJcbiAgICAgKi9cclxuICAgIERPTS5wcm90b3R5cGUub2Zmc2V0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBlbGVtZW50ID0gdGhpcy5lbGVtZW50c1swXTtcclxuICAgICAgICB2YXIgZWxlbWVudFJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgIHZhciBodG1sUmVjdCA9IGRvY3VtZW50LmJvZHkucGFyZW50RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgICAgICAvLyBWaXJ0dWFsIHZpZXdwb3J0IHNjcm9sbCBoYW5kbGluZyAoZS5nLiBwaW5jaCB6b29tZWQgdmlld3BvcnRzIGluIG1vYmlsZSBicm93c2VycyBvciBkZXNrdG9wIENocm9tZS9FZGdlKVxyXG4gICAgICAgIC8vICdub3JtYWwnIHpvb21zIGFuZCB2aXJ0dWFsIHZpZXdwb3J0IHpvb21zIChha2EgbGF5b3V0IHZpZXdwb3J0KSByZXN1bHQgaW4gZGlmZmVyZW50XHJcbiAgICAgICAgLy8gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSByZXN1bHRzOlxyXG4gICAgICAgIC8vICAtIHdpdGggbm9ybWFsIHNjcm9sbHMsIHRoZSBjbGllbnRSZWN0IGRlY3JlYXNlcyB3aXRoIGFuIGluY3JlYXNlIGluIHNjcm9sbChUb3B8TGVmdCkvcGFnZShYfFkpT2Zmc2V0XHJcbiAgICAgICAgLy8gIC0gd2l0aCBwaW5jaCB6b29tIHNjcm9sbHMsIHRoZSBjbGllbnRSZWN0IHN0YXlzIHRoZSBzYW1lIHdoaWxlIHNjcm9sbC9wYWdlT2Zmc2V0IGNoYW5nZXNcclxuICAgICAgICAvLyBUaGlzIG1lYW5zLCB0aGF0IHRoZSBjb21iaW5hdGlvbiBvZiBjbGllbnRSZWN0ICsgc2Nyb2xsL3BhZ2VPZmZzZXQgZG9lcyBub3Qgd29yayB0byBjYWxjdWxhdGUgdGhlIG9mZnNldFxyXG4gICAgICAgIC8vIGZyb20gdGhlIGRvY3VtZW50J3MgdXBwZXIgbGVmdCBvcmlnaW4gd2hlbiBwaW5jaCB6b29tIGlzIHVzZWQuXHJcbiAgICAgICAgLy8gVG8gd29yayBhcm91bmQgdGhpcyBpc3N1ZSwgd2UgZG8gbm90IHVzZSBzY3JvbGwvcGFnZU9mZnNldCBidXQgZ2V0IHRoZSBjbGllbnRSZWN0IG9mIHRoZSBodG1sIGVsZW1lbnQgYW5kXHJcbiAgICAgICAgLy8gc3VidHJhY3QgaXQgZnJvbSB0aGUgZWxlbWVudCdzIHJlY3QsIHdoaWNoIGFsd2F5cyByZXN1bHRzIGluIHRoZSBvZmZzZXQgZnJvbSB0aGUgZG9jdW1lbnQgb3JpZ2luLlxyXG4gICAgICAgIC8vIE5PVEU6IHRoZSBjdXJyZW50IHdheSBvZiBvZmZzZXQgY2FsY3VsYXRpb24gd2FzIGltcGxlbWVudGVkIHNwZWNpZmljYWxseSB0byB0cmFjayBldmVudCBwb3NpdGlvbnMgb24gdGhlXHJcbiAgICAgICAgLy8gc2VlayBiYXIsIGFuZCBpdCBtaWdodCBicmVhayBjb21wYXRpYmlsaXR5IHdpdGggalF1ZXJ5J3Mgb2Zmc2V0KCkgbWV0aG9kLiBJZiB0aGlzIGV2ZXIgdHVybnMgb3V0IHRvIGJlIGFcclxuICAgICAgICAvLyBwcm9ibGVtLCB0aGlzIG1ldGhvZCBzaG91bGQgYmUgcmV2ZXJ0ZWQgdG8gdGhlIG9sZCB2ZXJzaW9uIGFuZCB0aGUgb2Zmc2V0IGNhbGN1bGF0aW9uIG1vdmVkIHRvIHRoZSBzZWVrIGJhci5cclxuICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICB0b3A6IGVsZW1lbnRSZWN0LnRvcCAtIGh0bWxSZWN0LnRvcCxcclxuICAgICAgICAgICAgbGVmdDogZWxlbWVudFJlY3QubGVmdCAtIGh0bWxSZWN0LmxlZnQsXHJcbiAgICAgICAgfTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIHdpZHRoIG9mIHRoZSBmaXJzdCBlbGVtZW50LlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gdGhlIHdpZHRoIG9mIHRoZSBmaXJzdCBlbGVtZW50XHJcbiAgICAgKi9cclxuICAgIERPTS5wcm90b3R5cGUud2lkdGggPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gVE9ETyBjaGVjayBpZiB0aGlzIGlzIHRoZSBzYW1lIGFzIGpRdWVyeSdzIHdpZHRoKCkgKHByb2JhYmx5IG5vdClcclxuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50c1swXS5vZmZzZXRXaWR0aDtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGhlaWdodCBvZiB0aGUgZmlyc3QgZWxlbWVudC5cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IHRoZSBoZWlnaHQgb2YgdGhlIGZpcnN0IGVsZW1lbnRcclxuICAgICAqL1xyXG4gICAgRE9NLnByb3RvdHlwZS5oZWlnaHQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gVE9ETyBjaGVjayBpZiB0aGlzIGlzIHRoZSBzYW1lIGFzIGpRdWVyeSdzIGhlaWdodCgpIChwcm9iYWJseSBub3QpXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudHNbMF0ub2Zmc2V0SGVpZ2h0O1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQXR0YWNoZXMgYW4gZXZlbnQgaGFuZGxlciB0byBvbmUgb3IgbW9yZSBldmVudHMgb24gYWxsIGVsZW1lbnRzLlxyXG4gICAgICogQHBhcmFtIGV2ZW50TmFtZSB0aGUgZXZlbnQgbmFtZSAob3IgbXVsdGlwbGUgbmFtZXMgc2VwYXJhdGVkIGJ5IHNwYWNlKSB0byBsaXN0ZW4gdG9cclxuICAgICAqIEBwYXJhbSBldmVudEhhbmRsZXIgdGhlIGV2ZW50IGhhbmRsZXIgdG8gY2FsbCB3aGVuIHRoZSBldmVudCBmaXJlc1xyXG4gICAgICogQHJldHVybnMge0RPTX1cclxuICAgICAqL1xyXG4gICAgRE9NLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIChldmVudE5hbWUsIGV2ZW50SGFuZGxlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIGV2ZW50cyA9IGV2ZW50TmFtZS5zcGxpdCgnICcpO1xyXG4gICAgICAgIGV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuZWxlbWVudHMgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgZXZlbnRIYW5kbGVyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIGV2ZW50SGFuZGxlcik7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmVtb3ZlcyBhbiBldmVudCBoYW5kbGVyIGZyb20gb25lIG9yIG1vcmUgZXZlbnRzIG9uIGFsbCBlbGVtZW50cy5cclxuICAgICAqIEBwYXJhbSBldmVudE5hbWUgdGhlIGV2ZW50IG5hbWUgKG9yIG11bHRpcGxlIG5hbWVzIHNlcGFyYXRlZCBieSBzcGFjZSkgdG8gcmVtb3ZlIHRoZSBoYW5kbGVyIGZyb21cclxuICAgICAqIEBwYXJhbSBldmVudEhhbmRsZXIgdGhlIGV2ZW50IGhhbmRsZXIgdG8gcmVtb3ZlXHJcbiAgICAgKiBAcmV0dXJucyB7RE9NfVxyXG4gICAgICovXHJcbiAgICBET00ucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIChldmVudE5hbWUsIGV2ZW50SGFuZGxlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIGV2ZW50cyA9IGV2ZW50TmFtZS5zcGxpdCgnICcpO1xyXG4gICAgICAgIGV2ZW50cy5mb3JFYWNoKGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuZWxlbWVudHMgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgZXZlbnRIYW5kbGVyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIGV2ZW50SGFuZGxlcik7XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQWRkcyB0aGUgc3BlY2lmaWVkIGNsYXNzKGVzKSB0byBhbGwgZWxlbWVudHMuXHJcbiAgICAgKiBAcGFyYW0gY2xhc3NOYW1lIHRoZSBjbGFzcyhlcykgdG8gYWRkLCBtdWx0aXBsZSBjbGFzc2VzIHNlcGFyYXRlZCBieSBzcGFjZVxyXG4gICAgICogQHJldHVybnMge0RPTX1cclxuICAgICAqL1xyXG4gICAgRE9NLnByb3RvdHlwZS5hZGRDbGFzcyA9IGZ1bmN0aW9uIChjbGFzc05hbWUpIHtcclxuICAgICAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgaWYgKGVsZW1lbnQuY2xhc3NMaXN0KSB7XHJcbiAgICAgICAgICAgICAgICBlbGVtZW50LmNsYXNzTGlzdC5hZGQoY2xhc3NOYW1lKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NOYW1lICs9ICcgJyArIGNsYXNzTmFtZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmVtb3ZlZCB0aGUgc3BlY2lmaWVkIGNsYXNzKGVzKSBmcm9tIGFsbCBlbGVtZW50cy5cclxuICAgICAqIEBwYXJhbSBjbGFzc05hbWUgdGhlIGNsYXNzKGVzKSB0byByZW1vdmUsIG11bHRpcGxlIGNsYXNzZXMgc2VwYXJhdGVkIGJ5IHNwYWNlXHJcbiAgICAgKiBAcmV0dXJucyB7RE9NfVxyXG4gICAgICovXHJcbiAgICBET00ucHJvdG90eXBlLnJlbW92ZUNsYXNzID0gZnVuY3Rpb24gKGNsYXNzTmFtZSkge1xyXG4gICAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICBpZiAoZWxlbWVudC5jbGFzc0xpc3QpIHtcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LnJlbW92ZShjbGFzc05hbWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgPSBlbGVtZW50LmNsYXNzTmFtZS5yZXBsYWNlKG5ldyBSZWdFeHAoJyhefFxcXFxiKScgKyBjbGFzc05hbWUuc3BsaXQoJyAnKS5qb2luKCd8JykgKyAnKFxcXFxifCQpJywgJ2dpJyksICcgJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIENoZWNrcyBpZiBhbnkgb2YgdGhlIGVsZW1lbnRzIGhhcyB0aGUgc3BlY2lmaWVkIGNsYXNzLlxyXG4gICAgICogQHBhcmFtIGNsYXNzTmFtZSB0aGUgY2xhc3MgbmFtZSB0byBjaGVja1xyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWYgb25lIG9mIHRoZSBlbGVtZW50cyBoYXMgdGhlIGNsYXNzIGF0dGFjaGVkLCBlbHNlIGlmIG5vIGVsZW1lbnQgaGFzIGl0IGF0dGFjaGVkXHJcbiAgICAgKi9cclxuICAgIERPTS5wcm90b3R5cGUuaGFzQ2xhc3MgPSBmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgdmFyIGhhc0NsYXNzID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGlmIChlbGVtZW50LmNsYXNzTGlzdCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKGNsYXNzTmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBTaW5jZSB3ZSBhcmUgaW5zaWRlIGEgaGFuZGxlciwgd2UgY2FuJ3QganVzdCAncmV0dXJuIHRydWUnLiBJbnN0ZWFkLCB3ZSBzYXZlIGl0IHRvIGEgdmFyaWFibGVcclxuICAgICAgICAgICAgICAgICAgICAvLyBhbmQgcmV0dXJuIGl0IGF0IHRoZSBlbmQgb2YgdGhlIGZ1bmN0aW9uIGJvZHkuXHJcbiAgICAgICAgICAgICAgICAgICAgaGFzQ2xhc3MgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKG5ldyBSZWdFeHAoJyhefCApJyArIGNsYXNzTmFtZSArICcoIHwkKScsICdnaScpLnRlc3QoZWxlbWVudC5jbGFzc05hbWUpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gU2VlIGNvbW1lbnQgYWJvdmVcclxuICAgICAgICAgICAgICAgICAgICBoYXNDbGFzcyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gaGFzQ2xhc3M7XHJcbiAgICB9O1xyXG4gICAgRE9NLnByb3RvdHlwZS5jc3MgPSBmdW5jdGlvbiAocHJvcGVydHlOYW1lT3JDb2xsZWN0aW9uLCB2YWx1ZSkge1xyXG4gICAgICAgIGlmICh0eXBlb2YgcHJvcGVydHlOYW1lT3JDb2xsZWN0aW9uID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICB2YXIgcHJvcGVydHlOYW1lID0gcHJvcGVydHlOYW1lT3JDb2xsZWN0aW9uO1xyXG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMikge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2V0Q3NzKHByb3BlcnR5TmFtZSwgdmFsdWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0Q3NzKHByb3BlcnR5TmFtZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHZhciBwcm9wZXJ0eVZhbHVlQ29sbGVjdGlvbiA9IHByb3BlcnR5TmFtZU9yQ29sbGVjdGlvbjtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2V0Q3NzQ29sbGVjdGlvbihwcm9wZXJ0eVZhbHVlQ29sbGVjdGlvbik7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIERPTS5wcm90b3R5cGUuZ2V0Q3NzID0gZnVuY3Rpb24gKHByb3BlcnR5TmFtZSkge1xyXG4gICAgICAgIHJldHVybiBnZXRDb21wdXRlZFN0eWxlKHRoaXMuZWxlbWVudHNbMF0pW3Byb3BlcnR5TmFtZV07XHJcbiAgICB9O1xyXG4gICAgRE9NLnByb3RvdHlwZS5zZXRDc3MgPSBmdW5jdGlvbiAocHJvcGVydHlOYW1lLCB2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICAvLyA8YW55PiBjYXN0IHRvIHJlc29sdmUgVFM3MDE1OiBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8zNjYyNzExNC8zNzAyNTJcclxuICAgICAgICAgICAgZWxlbWVudC5zdHlsZVtwcm9wZXJ0eU5hbWVdID0gdmFsdWU7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgRE9NLnByb3RvdHlwZS5zZXRDc3NDb2xsZWN0aW9uID0gZnVuY3Rpb24gKHJ1bGVWYWx1ZUNvbGxlY3Rpb24pIHtcclxuICAgICAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMzQ0OTA1NzMvMzcwMjUyXHJcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24oZWxlbWVudC5zdHlsZSwgcnVsZVZhbHVlQ29sbGVjdGlvbik7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIERPTTtcclxufSgpKTtcclxuZXhwb3J0cy5ET00gPSBET007XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvZG9tLnRzXG4vLyBtb2R1bGUgaWQgPSAwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRcIik7XHJcbnZhciBkb21fMSA9IHJlcXVpcmUoXCIuLi9kb21cIik7XHJcbnZhciBhcnJheXV0aWxzXzEgPSByZXF1aXJlKFwiLi4vYXJyYXl1dGlsc1wiKTtcclxuLyoqXHJcbiAqIEEgY29udGFpbmVyIGNvbXBvbmVudCB0aGF0IGNhbiBjb250YWluIGEgY29sbGVjdGlvbiBvZiBjaGlsZCBjb21wb25lbnRzLlxyXG4gKiBDb21wb25lbnRzIGNhbiBiZSBhZGRlZCBhdCBjb25zdHJ1Y3Rpb24gdGltZSB0aHJvdWdoIHRoZSB7QGxpbmsgQ29udGFpbmVyQ29uZmlnI2NvbXBvbmVudHN9IHNldHRpbmcsIG9yIGxhdGVyXHJcbiAqIHRocm91Z2ggdGhlIHtAbGluayBDb250YWluZXIjYWRkQ29tcG9uZW50fSBtZXRob2QuIFRoZSBVSU1hbmFnZXIgYXV0b21hdGljYWxseSB0YWtlcyBjYXJlIG9mIGFsbCBjb21wb25lbnRzLCBpLmUuIGl0XHJcbiAqIGluaXRpYWxpemVzIGFuZCBjb25maWd1cmVzIHRoZW0gYXV0b21hdGljYWxseS5cclxuICpcclxuICogSW4gdGhlIERPTSwgdGhlIGNvbnRhaW5lciBjb25zaXN0cyBvZiBhbiBvdXRlciA8ZGl2PiAodGhhdCBjYW4gYmUgY29uZmlndXJlZCBieSB0aGUgY29uZmlnKSBhbmQgYW4gaW5uZXIgd3JhcHBlclxyXG4gKiA8ZGl2PiB0aGF0IGNvbnRhaW5zIHRoZSBjb21wb25lbnRzLiBUaGlzIGRvdWJsZS08ZGl2Pi1zdHJ1Y3R1cmUgaXMgb2Z0ZW4gcmVxdWlyZWQgdG8gYWNoaWV2ZSBtYW55IGFkdmFuY2VkIGVmZmVjdHNcclxuICogaW4gQ1NTIGFuZC9vciBKUywgZS5nLiBhbmltYXRpb25zIGFuZCBjZXJ0YWluIGZvcm1hdHRpbmcgd2l0aCBhYnNvbHV0ZSBwb3NpdGlvbmluZy5cclxuICpcclxuICogRE9NIGV4YW1wbGU6XHJcbiAqIDxjb2RlPlxyXG4gKiAgICAgPGRpdiBjbGFzcz0ndWktY29udGFpbmVyJz5cclxuICogICAgICAgICA8ZGl2IGNsYXNzPSdjb250YWluZXItd3JhcHBlcic+XHJcbiAqICAgICAgICAgICAgIC4uLiBjaGlsZCBjb21wb25lbnRzIC4uLlxyXG4gKiAgICAgICAgIDwvZGl2PlxyXG4gKiAgICAgPC9kaXY+XHJcbiAqIDwvY29kZT5cclxuICovXHJcbnZhciBDb250YWluZXIgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKENvbnRhaW5lciwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIENvbnRhaW5lcihjb25maWcpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktY29udGFpbmVyJyxcclxuICAgICAgICAgICAgY29tcG9uZW50czogW10sXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICBfdGhpcy5jb21wb25lbnRzVG9BZGQgPSBbXTtcclxuICAgICAgICBfdGhpcy5jb21wb25lbnRzVG9SZW1vdmUgPSBbXTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIEFkZHMgYSBjaGlsZCBjb21wb25lbnQgdG8gdGhlIGNvbnRhaW5lci5cclxuICAgICAqIEBwYXJhbSBjb21wb25lbnQgdGhlIGNvbXBvbmVudCB0byBhZGRcclxuICAgICAqL1xyXG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5hZGRDb21wb25lbnQgPSBmdW5jdGlvbiAoY29tcG9uZW50KSB7XHJcbiAgICAgICAgdGhpcy5jb25maWcuY29tcG9uZW50cy5wdXNoKGNvbXBvbmVudCk7XHJcbiAgICAgICAgdGhpcy5jb21wb25lbnRzVG9BZGQucHVzaChjb21wb25lbnQpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmVtb3ZlcyBhIGNoaWxkIGNvbXBvbmVudCBmcm9tIHRoZSBjb250YWluZXIuXHJcbiAgICAgKiBAcGFyYW0gY29tcG9uZW50IHRoZSBjb21wb25lbnQgdG8gcmVtb3ZlXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgY29tcG9uZW50IGhhcyBiZWVuIHJlbW92ZWQsIGZhbHNlIGlmIGl0IGlzIG5vdCBjb250YWluZWQgaW4gdGhpcyBjb250YWluZXJcclxuICAgICAqL1xyXG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5yZW1vdmVDb21wb25lbnQgPSBmdW5jdGlvbiAoY29tcG9uZW50KSB7XHJcbiAgICAgICAgaWYgKGFycmF5dXRpbHNfMS5BcnJheVV0aWxzLnJlbW92ZSh0aGlzLmNvbmZpZy5jb21wb25lbnRzLCBjb21wb25lbnQpICE9IG51bGwpIHtcclxuICAgICAgICAgICAgdGhpcy5jb21wb25lbnRzVG9SZW1vdmUucHVzaChjb21wb25lbnQpO1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIGFuIGFycmF5IG9mIGFsbCBjaGlsZCBjb21wb25lbnRzIGluIHRoaXMgY29udGFpbmVyLlxyXG4gICAgICogQHJldHVybnMge0NvbXBvbmVudDxDb21wb25lbnRDb25maWc+W119XHJcbiAgICAgKi9cclxuICAgIENvbnRhaW5lci5wcm90b3R5cGUuZ2V0Q29tcG9uZW50cyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuY29tcG9uZW50cztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJlbW92ZXMgYWxsIGNoaWxkIGNvbXBvbmVudHMgZnJvbSB0aGUgY29udGFpbmVyLlxyXG4gICAgICovXHJcbiAgICBDb250YWluZXIucHJvdG90eXBlLnJlbW92ZUNvbXBvbmVudHMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMuZ2V0Q29tcG9uZW50cygpLnNsaWNlKCk7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgIHZhciBjb21wb25lbnQgPSBfYVtfaV07XHJcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlQ29tcG9uZW50KGNvbXBvbmVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogVXBkYXRlcyB0aGUgRE9NIG9mIHRoZSBjb250YWluZXIgd2l0aCB0aGUgY3VycmVudCBjb21wb25lbnRzLlxyXG4gICAgICovXHJcbiAgICBDb250YWluZXIucHJvdG90eXBlLnVwZGF0ZUNvbXBvbmVudHMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLyogV2UgY2Fubm90IGp1c3QgY2xlYXIgdGhlIGNvbnRhaW5lciB0byByZW1vdmUgYWxsIGVsZW1lbnRzIGFuZCB0aGVuIHJlLWFkZCB0aG9zZSB0aGF0IHNob3VsZCBzdGF5LCBiZWNhdXNlXHJcbiAgICAgICAgICogSUUgbG9vc2VzIHRoZSBpbm5lckhUTUwgb2YgdW5hdHRhY2hlZCBlbGVtZW50cywgbGVhZGluZyB0byBlbXB0eSBlbGVtZW50cyB3aXRoaW4gdGhlIGNvbnRhaW5lciAoZS5nLiBtaXNzaW5nXHJcbiAgICAgICAgICogc3VidGl0bGUgdGV4dCBpbiBTdWJ0aXRsZUxhYmVsKS5cclxuICAgICAgICAgKiBJbnN0ZWFkLCB3ZSBrZWVwIGEgbGlzdCBvZiBlbGVtZW50cyB0byBhZGQgYW5kIHJlbW92ZSwgbGVhdmluZyByZW1haW5pbmcgZWxlbWVudHMgYWxvbmUuIEJ5IGtlZXBpbmcgdGhlbSBpblxyXG4gICAgICAgICAqIHRoZSBET00sIHRoZWlyIGNvbnRlbnQgZ2V0cyBwcmVzZXJ2ZWQgaW4gYWxsIGJyb3dzZXJzLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHZhciBjb21wb25lbnQ7XHJcbiAgICAgICAgd2hpbGUgKGNvbXBvbmVudCA9IHRoaXMuY29tcG9uZW50c1RvUmVtb3ZlLnNoaWZ0KCkpIHtcclxuICAgICAgICAgICAgY29tcG9uZW50LmdldERvbUVsZW1lbnQoKS5yZW1vdmUoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgd2hpbGUgKGNvbXBvbmVudCA9IHRoaXMuY29tcG9uZW50c1RvQWRkLnNoaWZ0KCkpIHtcclxuICAgICAgICAgICAgdGhpcy5pbm5lckNvbnRhaW5lckVsZW1lbnQuYXBwZW5kKGNvbXBvbmVudC5nZXREb21FbGVtZW50KCkpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBDb250YWluZXIucHJvdG90eXBlLnRvRG9tRWxlbWVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBDcmVhdGUgdGhlIGNvbnRhaW5lciBlbGVtZW50ICh0aGUgb3V0ZXIgPGRpdj4pXHJcbiAgICAgICAgdmFyIGNvbnRhaW5lckVsZW1lbnQgPSBuZXcgZG9tXzEuRE9NKHRoaXMuY29uZmlnLnRhZywge1xyXG4gICAgICAgICAgICAnaWQnOiB0aGlzLmNvbmZpZy5pZCxcclxuICAgICAgICAgICAgJ2NsYXNzJzogdGhpcy5nZXRDc3NDbGFzc2VzKCksXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gQ3JlYXRlIHRoZSBpbm5lciBjb250YWluZXIgZWxlbWVudCAodGhlIGlubmVyIDxkaXY+KSB0aGF0IHdpbGwgY29udGFpbiB0aGUgY29tcG9uZW50c1xyXG4gICAgICAgIHZhciBpbm5lckNvbnRhaW5lciA9IG5ldyBkb21fMS5ET00odGhpcy5jb25maWcudGFnLCB7XHJcbiAgICAgICAgICAgICdjbGFzcyc6IHRoaXMucHJlZml4Q3NzKCdjb250YWluZXItd3JhcHBlcicpLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuaW5uZXJDb250YWluZXJFbGVtZW50ID0gaW5uZXJDb250YWluZXI7XHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMuY29uZmlnLmNvbXBvbmVudHM7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgIHZhciBpbml0aWFsQ29tcG9uZW50ID0gX2FbX2ldO1xyXG4gICAgICAgICAgICB0aGlzLmNvbXBvbmVudHNUb0FkZC5wdXNoKGluaXRpYWxDb21wb25lbnQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnVwZGF0ZUNvbXBvbmVudHMoKTtcclxuICAgICAgICBjb250YWluZXJFbGVtZW50LmFwcGVuZChpbm5lckNvbnRhaW5lcik7XHJcbiAgICAgICAgcmV0dXJuIGNvbnRhaW5lckVsZW1lbnQ7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIENvbnRhaW5lcjtcclxufShjb21wb25lbnRfMS5Db21wb25lbnQpKTtcclxuZXhwb3J0cy5Db250YWluZXIgPSBDb250YWluZXI7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9jb250YWluZXIudHNcbi8vIG1vZHVsZSBpZCA9IDFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGd1aWRfMSA9IHJlcXVpcmUoXCIuLi9ndWlkXCIpO1xyXG52YXIgZG9tXzEgPSByZXF1aXJlKFwiLi4vZG9tXCIpO1xyXG52YXIgZXZlbnRkaXNwYXRjaGVyXzEgPSByZXF1aXJlKFwiLi4vZXZlbnRkaXNwYXRjaGVyXCIpO1xyXG4vKipcclxuICogVGhlIGJhc2UgY2xhc3Mgb2YgdGhlIFVJIGZyYW1ld29yay5cclxuICogRWFjaCBjb21wb25lbnQgbXVzdCBleHRlbmQgdGhpcyBjbGFzcyBhbmQgb3B0aW9uYWxseSB0aGUgY29uZmlnIGludGVyZmFjZS5cclxuICovXHJcbnZhciBDb21wb25lbnQgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDb25zdHJ1Y3RzIGEgY29tcG9uZW50IHdpdGggYW4gb3B0aW9uYWxseSBzdXBwbGllZCBjb25maWcuIEFsbCBzdWJjbGFzc2VzIG11c3QgY2FsbCB0aGUgY29uc3RydWN0b3Igb2YgdGhlaXJcclxuICAgICAqIHN1cGVyY2xhc3MgYW5kIHRoZW4gbWVyZ2UgdGhlaXIgY29uZmlndXJhdGlvbiBpbnRvIHRoZSBjb21wb25lbnQncyBjb25maWd1cmF0aW9uLlxyXG4gICAgICogQHBhcmFtIGNvbmZpZyB0aGUgY29uZmlndXJhdGlvbiBmb3IgdGhlIGNvbXBvbmVudFxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBDb21wb25lbnQoY29uZmlnKSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogVGhlIGxpc3Qgb2YgZXZlbnRzIHRoYXQgdGhpcyBjb21wb25lbnQgb2ZmZXJzLiBUaGVzZSBldmVudHMgc2hvdWxkIGFsd2F5cyBiZSBwcml2YXRlIGFuZCBvbmx5IGRpcmVjdGx5XHJcbiAgICAgICAgICogYWNjZXNzZWQgZnJvbSB3aXRoaW4gdGhlIGltcGxlbWVudGluZyBjb21wb25lbnQuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBCZWNhdXNlIFR5cGVTY3JpcHQgZG9lcyBub3Qgc3VwcG9ydCBwcml2YXRlIHByb3BlcnRpZXMgd2l0aCB0aGUgc2FtZSBuYW1lIG9uIGRpZmZlcmVudCBjbGFzcyBoaWVyYXJjaHkgbGV2ZWxzXHJcbiAgICAgICAgICogKGkuZS4gc3VwZXJjbGFzcyBhbmQgc3ViY2xhc3MgY2Fubm90IGNvbnRhaW4gYSBwcml2YXRlIHByb3BlcnR5IHdpdGggdGhlIHNhbWUgbmFtZSksIHRoZSBkZWZhdWx0IG5hbWluZ1xyXG4gICAgICAgICAqIGNvbnZlbnRpb24gZm9yIHRoZSBldmVudCBsaXN0IG9mIGEgY29tcG9uZW50IHRoYXQgc2hvdWxkIGJlIGZvbGxvd2VkIGJ5IHN1YmNsYXNzZXMgaXMgdGhlIGNvbmNhdGVuYXRpb24gb2YgdGhlXHJcbiAgICAgICAgICogY2FtZWwtY2FzZWQgY2xhc3MgbmFtZSArICdFdmVudHMnIChlLmcuIFN1YkNsYXNzIGV4dGVuZHMgQ29tcG9uZW50ID0+IHN1YkNsYXNzRXZlbnRzKS5cclxuICAgICAgICAgKiBTZWUge0BsaW5rICNjb21wb25lbnRFdmVudHN9IGZvciBhbiBleGFtcGxlLlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogRXZlbnQgcHJvcGVydGllcyBzaG91bGQgYmUgbmFtZWQgaW4gY2FtZWwgY2FzZSB3aXRoIGFuICdvbicgcHJlZml4IGFuZCBpbiB0aGUgcHJlc2VudCB0ZW5zZS4gQXN5bmMgZXZlbnRzIG1heVxyXG4gICAgICAgICAqIGhhdmUgYSBzdGFydCBldmVudCAod2hlbiB0aGUgb3BlcmF0aW9uIHN0YXJ0cykgaW4gdGhlIHByZXNlbnQgdGVuc2UsIGFuZCBtdXN0IGhhdmUgYW4gZW5kIGV2ZW50ICh3aGVuIHRoZVxyXG4gICAgICAgICAqIG9wZXJhdGlvbiBlbmRzKSBpbiB0aGUgcGFzdCB0ZW5zZSAob3IgcHJlc2VudCB0ZW5zZSBpbiBzcGVjaWFsIGNhc2VzIChlLmcuIG9uU3RhcnQvb25TdGFydGVkIG9yIG9uUGxheS9vblBsYXlpbmcpLlxyXG4gICAgICAgICAqIFNlZSB7QGxpbmsgI2NvbXBvbmVudEV2ZW50cyNvblNob3d9IGZvciBhbiBleGFtcGxlLlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogRWFjaCBldmVudCBzaG91bGQgYmUgYWNjb21wYW5pZWQgd2l0aCBhIHByb3RlY3RlZCBtZXRob2QgbmFtZWQgYnkgdGhlIGNvbnZlbnRpb24gZXZlbnROYW1lICsgJ0V2ZW50J1xyXG4gICAgICAgICAqIChlLmcuIG9uU3RhcnRFdmVudCksIHRoYXQgYWN0dWFsbHkgdHJpZ2dlcnMgdGhlIGV2ZW50IGJ5IGNhbGxpbmcge0BsaW5rIEV2ZW50RGlzcGF0Y2hlciNkaXNwYXRjaCBkaXNwYXRjaH0gYW5kXHJcbiAgICAgICAgICogcGFzc2luZyBhIHJlZmVyZW5jZSB0byB0aGUgY29tcG9uZW50IGFzIGZpcnN0IHBhcmFtZXRlci4gQ29tcG9uZW50cyBzaG91bGQgYWx3YXlzIHRyaWdnZXIgdGhlaXIgZXZlbnRzIHdpdGggdGhlc2VcclxuICAgICAgICAgKiBtZXRob2RzLiBJbXBsZW1lbnRpbmcgdGhpcyBwYXR0ZXJuIGdpdmVzIHN1YmNsYXNzZXMgbWVhbnMgdG8gZGlyZWN0bHkgbGlzdGVuIHRvIHRoZSBldmVudHMgYnkgb3ZlcnJpZGluZyB0aGVcclxuICAgICAgICAgKiBtZXRob2QgKGFuZCBzYXZpbmcgdGhlIG92ZXJoZWFkIG9mIHBhc3NpbmcgYSBoYW5kbGVyIHRvIHRoZSBldmVudCBkaXNwYXRjaGVyKSBhbmQgbW9yZSBpbXBvcnRhbnRseSB0byB0cmlnZ2VyXHJcbiAgICAgICAgICogdGhlc2UgZXZlbnRzIHdpdGhvdXQgaGF2aW5nIGFjY2VzcyB0byB0aGUgcHJpdmF0ZSBldmVudCBsaXN0LlxyXG4gICAgICAgICAqIFNlZSB7QGxpbmsgI29uU2hvd30gZm9yIGFuIGV4YW1wbGUuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBUbyBwcm92aWRlIGV4dGVybmFsIGNvZGUgdGhlIHBvc3NpYmlsaXR5IHRvIGxpc3RlbiB0byB0aGlzIGNvbXBvbmVudCdzIGV2ZW50cyAoc3Vic2NyaWJlLCB1bnN1YnNjcmliZSwgZXRjLiksXHJcbiAgICAgICAgICogZWFjaCBldmVudCBzaG91bGQgYWxzbyBiZSBhY2NvbXBhbmllZCBieSBhIHB1YmxpYyBnZXR0ZXIgZnVuY3Rpb24gd2l0aCB0aGUgc2FtZSBuYW1lIGFzIHRoZSBldmVudCdzIHByb3BlcnR5LFxyXG4gICAgICAgICAqIHRoYXQgcmV0dXJucyB0aGUge0BsaW5rIEV2ZW50fSBvYnRhaW5lZCBmcm9tIHRoZSBldmVudCBkaXNwYXRjaGVyIGJ5IGNhbGxpbmcge0BsaW5rIEV2ZW50RGlzcGF0Y2hlciNnZXRFdmVudH0uXHJcbiAgICAgICAgICogU2VlIHtAbGluayAjb25TaG93fSBmb3IgYW4gZXhhbXBsZS5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEZ1bGwgZXhhbXBsZSBmb3IgYW4gZXZlbnQgcmVwcmVzZW50aW5nIGFuIGV4YW1wbGUgYWN0aW9uIGluIGEgZXhhbXBsZSBjb21wb25lbnQ6XHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiA8Y29kZT5cclxuICAgICAgICAgKiAvLyBEZWZpbmUgYW4gZXhhbXBsZSBjb21wb25lbnQgY2xhc3Mgd2l0aCBhbiBleGFtcGxlIGV2ZW50XHJcbiAgICAgICAgICogY2xhc3MgRXhhbXBsZUNvbXBvbmVudCBleHRlbmRzIENvbXBvbmVudDxDb21wb25lbnRDb25maWc+IHtcclxuICAgICAgICAgICAqXHJcbiAgICAgICAgICAgKiAgICAgcHJpdmF0ZSBleGFtcGxlQ29tcG9uZW50RXZlbnRzID0ge1xyXG4gICAgICAgICAgICogICAgICAgICBvbkV4YW1wbGVBY3Rpb246IG5ldyBFdmVudERpc3BhdGNoZXI8RXhhbXBsZUNvbXBvbmVudCwgTm9BcmdzPigpXHJcbiAgICAgICAgICAgKiAgICAgfVxyXG4gICAgICAgICAgICpcclxuICAgICAgICAgICAqICAgICAvLyBjb25zdHJ1Y3RvciBhbmQgb3RoZXIgc3R1ZmYuLi5cclxuICAgICAgICAgICAqXHJcbiAgICAgICAgICAgKiAgICAgcHJvdGVjdGVkIG9uRXhhbXBsZUFjdGlvbkV2ZW50KCkge1xyXG4gICAgICAgICAgICogICAgICAgIHRoaXMuZXhhbXBsZUNvbXBvbmVudEV2ZW50cy5vbkV4YW1wbGVBY3Rpb24uZGlzcGF0Y2godGhpcyk7XHJcbiAgICAgICAgICAgKiAgICB9XHJcbiAgICAgICAgICAgKlxyXG4gICAgICAgICAgICogICAgZ2V0IG9uRXhhbXBsZUFjdGlvbigpOiBFdmVudDxFeGFtcGxlQ29tcG9uZW50LCBOb0FyZ3M+IHtcclxuICAgICAgICAgICAqICAgICAgICByZXR1cm4gdGhpcy5leGFtcGxlQ29tcG9uZW50RXZlbnRzLm9uRXhhbXBsZUFjdGlvbi5nZXRFdmVudCgpO1xyXG4gICAgICAgICAgICogICAgfVxyXG4gICAgICAgICAgICogfVxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogLy8gQ3JlYXRlIGFuIGluc3RhbmNlIG9mIHRoZSBjb21wb25lbnQgc29tZXdoZXJlXHJcbiAgICAgICAgICogdmFyIGV4YW1wbGVDb21wb25lbnRJbnN0YW5jZSA9IG5ldyBFeGFtcGxlQ29tcG9uZW50KCk7XHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiAvLyBTdWJzY3JpYmUgdG8gdGhlIGV4YW1wbGUgZXZlbnQgb24gdGhlIGNvbXBvbmVudFxyXG4gICAgICAgICAqIGV4YW1wbGVDb21wb25lbnRJbnN0YW5jZS5vbkV4YW1wbGVBY3Rpb24uc3Vic2NyaWJlKGZ1bmN0aW9uIChzZW5kZXI6IEV4YW1wbGVDb21wb25lbnQpIHtcclxuICAgICAgICAgICAqICAgICBjb25zb2xlLmxvZygnb25FeGFtcGxlQWN0aW9uIG9mICcgKyBzZW5kZXIgKyAnIGhhcyBmaXJlZCEnKTtcclxuICAgICAgICAgICAqIH0pO1xyXG4gICAgICAgICAqIDwvY29kZT5cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLmNvbXBvbmVudEV2ZW50cyA9IHtcclxuICAgICAgICAgICAgb25TaG93OiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgICAgIG9uSGlkZTogbmV3IGV2ZW50ZGlzcGF0Y2hlcl8xLkV2ZW50RGlzcGF0Y2hlcigpLFxyXG4gICAgICAgICAgICBvbkhvdmVyQ2hhbmdlZDogbmV3IGV2ZW50ZGlzcGF0Y2hlcl8xLkV2ZW50RGlzcGF0Y2hlcigpLFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgLy8gQ3JlYXRlIHRoZSBjb25maWd1cmF0aW9uIGZvciB0aGlzIGNvbXBvbmVudFxyXG4gICAgICAgIHRoaXMuY29uZmlnID0gdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgdGFnOiAnZGl2JyxcclxuICAgICAgICAgICAgaWQ6ICdtaS13YmMtaWQtJyArIGd1aWRfMS5HdWlkLm5leHQoKSxcclxuICAgICAgICAgICAgY3NzUHJlZml4OiAnbWktd2JjJyxcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1jb21wb25lbnQnLFxyXG4gICAgICAgICAgICBjc3NDbGFzc2VzOiBbXSxcclxuICAgICAgICAgICAgaGlkZGVuOiBmYWxzZSxcclxuICAgICAgICB9LCB7fSk7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIEluaXRpYWxpemVzIHRoZSBjb21wb25lbnQsIGUuZy4gYnkgYXBwbHlpbmcgY29uZmlnIHNldHRpbmdzLlxyXG4gICAgICogVGhpcyBtZXRob2QgbXVzdCBub3QgYmUgY2FsbGVkIGZyb20gb3V0c2lkZSB0aGUgVUkgZnJhbWV3b3JrLlxyXG4gICAgICpcclxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGF1dG9tYXRpY2FsbHkgY2FsbGVkIGJ5IHRoZSB7QGxpbmsgVUlJbnN0YW5jZU1hbmFnZXJ9LiBJZiB0aGUgY29tcG9uZW50IGlzIGFuIGlubmVyIGNvbXBvbmVudCBvZlxyXG4gICAgICogc29tZSBjb21wb25lbnQsIGFuZCB0aHVzIGVuY2Fwc3VsYXRlZCBhYmQgbWFuYWdlZCBpbnRlcm5hbGx5IGFuZCBuZXZlciBkaXJlY3RseSBleHBvc2VkIHRvIHRoZSBVSU1hbmFnZXIsXHJcbiAgICAgKiB0aGlzIG1ldGhvZCBtdXN0IGJlIGNhbGxlZCBmcm9tIHRoZSBtYW5hZ2luZyBjb21wb25lbnQncyB7QGxpbmsgI2luaXRpYWxpemV9IG1ldGhvZC5cclxuICAgICAqL1xyXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5pbml0aWFsaXplID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMuaGlkZGVuID0gdGhpcy5jb25maWcuaGlkZGVuO1xyXG4gICAgICAgIC8vIEhpZGUgdGhlIGNvbXBvbmVudCBhdCBpbml0aWFsaXphdGlvbiBpZiBpdCBpcyBjb25maWd1cmVkIHRvIGJlIGhpZGRlblxyXG4gICAgICAgIGlmICh0aGlzLmlzSGlkZGVuKCkpIHtcclxuICAgICAgICAgICAgdGhpcy5oaWRkZW4gPSBmYWxzZTsgLy8gU2V0IGZsYWcgdG8gZmFsc2UgZm9yIHRoZSBmb2xsb3dpbmcgaGlkZSgpIGNhbGwgdG8gd29yayAoaGlkZSgpIGNoZWNrcyB0aGUgZmxhZylcclxuICAgICAgICAgICAgdGhpcy5oaWRlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQ29uZmlndXJlcyB0aGUgY29tcG9uZW50IGZvciB0aGUgc3VwcGxpZWQgUGxheWVyIGFuZCBVSUluc3RhbmNlTWFuYWdlci4gVGhpcyBpcyB0aGUgcGxhY2Ugd2hlcmUgYWxsIHRoZSBtYWdpY1xyXG4gICAgICogaGFwcGVucywgd2hlcmUgY29tcG9uZW50cyB0eXBpY2FsbHkgc3Vic2NyaWJlIGFuZCByZWFjdCB0byBldmVudHMgKG9uIHRoZWlyIERPTSBlbGVtZW50LCB0aGUgUGxheWVyLCBvciB0aGVcclxuICAgICAqIFVJSW5zdGFuY2VNYW5hZ2VyKSwgYW5kIGJhc2ljYWxseSBldmVyeXRoaW5nIHRoYXQgbWFrZXMgdGhlbSBpbnRlcmFjdGl2ZS5cclxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBvbmx5IG9uY2UsIHdoZW4gdGhlIFVJTWFuYWdlciBpbml0aWFsaXplcyB0aGUgVUkuXHJcbiAgICAgKlxyXG4gICAgICogU3ViY2xhc3NlcyB1c3VhbGx5IG92ZXJ3cml0ZSB0aGlzIG1ldGhvZCB0byBhZGQgdGhlaXIgb3duIGZ1bmN0aW9uYWxpdHkuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHBsYXllciB0aGUgcGxheWVyIHdoaWNoIHRoaXMgY29tcG9uZW50IGNvbnRyb2xzXHJcbiAgICAgKiBAcGFyYW0gdWltYW5hZ2VyIHRoZSBVSUluc3RhbmNlTWFuYWdlciB0aGF0IG1hbmFnZXMgdGhpcyBjb21wb25lbnRcclxuICAgICAqL1xyXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5jb25maWd1cmUgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHRoaXMub25TaG93LnN1YnNjcmliZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHVpbWFuYWdlci5vbkNvbXBvbmVudFNob3cuZGlzcGF0Y2goX3RoaXMpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMub25IaWRlLnN1YnNjcmliZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHVpbWFuYWdlci5vbkNvbXBvbmVudEhpZGUuZGlzcGF0Y2goX3RoaXMpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIFRyYWNrIHRoZSBob3ZlcmVkIHN0YXRlIG9mIHRoZSBlbGVtZW50XHJcbiAgICAgICAgdGhpcy5nZXREb21FbGVtZW50KCkub24oJ21vdXNlZW50ZXInLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLm9uSG92ZXJDaGFuZ2VkRXZlbnQodHJ1ZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5nZXREb21FbGVtZW50KCkub24oJ21vdXNlbGVhdmUnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLm9uSG92ZXJDaGFuZ2VkRXZlbnQoZmFsc2UpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmVsZWFzZXMgYWxsIHJlc291cmNlcyBhbmQgZGVwZW5kZW5jaWVzIHRoYXQgdGhlIGNvbXBvbmVudCBob2xkcy4gUGxheWVyLCBET00sIGFuZCBVSU1hbmFnZXIgZXZlbnRzIGFyZVxyXG4gICAgICogYXV0b21hdGljYWxseSByZW1vdmVkIGR1cmluZyByZWxlYXNlIGFuZCBkbyBub3QgZXhwbGljaXRseSBuZWVkIHRvIGJlIHJlbW92ZWQgaGVyZS5cclxuICAgICAqIFRoaXMgbWV0aG9kIGlzIGNhbGxlZCBieSB0aGUgVUlNYW5hZ2VyIHdoZW4gaXQgcmVsZWFzZXMgdGhlIFVJLlxyXG4gICAgICpcclxuICAgICAqIFN1YmNsYXNzZXMgdGhhdCBuZWVkIHRvIHJlbGVhc2UgcmVzb3VyY2VzIHNob3VsZCBvdmVycmlkZSB0aGlzIG1ldGhvZCBhbmQgY2FsbCBzdXBlci5yZWxlYXNlKCkuXHJcbiAgICAgKi9cclxuICAgIENvbXBvbmVudC5wcm90b3R5cGUucmVsZWFzZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBOb3RoaW5nIHRvIGRvIGhlcmUsIG92ZXJyaWRlIHdoZXJlIG5lY2Vzc2FyeVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogR2VuZXJhdGUgdGhlIERPTSBlbGVtZW50IGZvciB0aGlzIGNvbXBvbmVudC5cclxuICAgICAqXHJcbiAgICAgKiBTdWJjbGFzc2VzIHVzdWFsbHkgb3ZlcndyaXRlIHRoaXMgbWV0aG9kIHRvIGV4dGVuZCBvciByZXBsYWNlIHRoZSBET00gZWxlbWVudCB3aXRoIHRoZWlyIG93biBkZXNpZ24uXHJcbiAgICAgKi9cclxuICAgIENvbXBvbmVudC5wcm90b3R5cGUudG9Eb21FbGVtZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBlbGVtZW50ID0gbmV3IGRvbV8xLkRPTSh0aGlzLmNvbmZpZy50YWcsIHtcclxuICAgICAgICAgICAgJ2lkJzogdGhpcy5jb25maWcuaWQsXHJcbiAgICAgICAgICAgICdjbGFzcyc6IHRoaXMuZ2V0Q3NzQ2xhc3NlcygpLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiBlbGVtZW50O1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgRE9NIGVsZW1lbnQgb2YgdGhpcyBjb21wb25lbnQuIENyZWF0ZXMgdGhlIERPTSBlbGVtZW50IGlmIGl0IGRvZXMgbm90IHlldCBleGlzdC5cclxuICAgICAqXHJcbiAgICAgKiBTaG91bGQgbm90IGJlIG92ZXJ3cml0dGVuIGJ5IHN1YmNsYXNzZXMuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge0RPTX1cclxuICAgICAqL1xyXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5nZXREb21FbGVtZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5lbGVtZW50KSB7XHJcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudCA9IHRoaXMudG9Eb21FbGVtZW50KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnQ7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBNZXJnZXMgYSBjb25maWd1cmF0aW9uIHdpdGggYSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24gYW5kIGEgYmFzZSBjb25maWd1cmF0aW9uIGZyb20gdGhlIHN1cGVyY2xhc3MuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIGNvbmZpZyB0aGUgY29uZmlndXJhdGlvbiBzZXR0aW5ncyBmb3IgdGhlIGNvbXBvbmVudHMsIGFzIHVzdWFsbHkgcGFzc2VkIHRvIHRoZSBjb25zdHJ1Y3RvclxyXG4gICAgICogQHBhcmFtIGRlZmF1bHRzIGEgZGVmYXVsdCBjb25maWd1cmF0aW9uIGZvciBzZXR0aW5ncyB0aGF0IGFyZSBub3QgcGFzc2VkIHdpdGggdGhlIGNvbmZpZ3VyYXRpb25cclxuICAgICAqIEBwYXJhbSBiYXNlIGNvbmZpZ3VyYXRpb24gaW5oZXJpdGVkIGZyb20gYSBzdXBlcmNsYXNzXHJcbiAgICAgKiBAcmV0dXJucyB7Q29uZmlnfVxyXG4gICAgICovXHJcbiAgICBDb21wb25lbnQucHJvdG90eXBlLm1lcmdlQ29uZmlnID0gZnVuY3Rpb24gKGNvbmZpZywgZGVmYXVsdHMsIGJhc2UpIHtcclxuICAgICAgICAvLyBFeHRlbmQgZGVmYXVsdCBjb25maWcgd2l0aCBzdXBwbGllZCBjb25maWdcclxuICAgICAgICB2YXIgbWVyZ2VkID0gT2JqZWN0LmFzc2lnbih7fSwgYmFzZSwgZGVmYXVsdHMsIGNvbmZpZyk7XHJcbiAgICAgICAgLy8gUmV0dXJuIHRoZSBleHRlbmRlZCBjb25maWdcclxuICAgICAgICByZXR1cm4gbWVyZ2VkO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogSGVscGVyIG1ldGhvZCB0aGF0IHJldHVybnMgYSBzdHJpbmcgb2YgYWxsIENTUyBjbGFzc2VzIG9mIHRoZSBjb21wb25lbnQuXHJcbiAgICAgKlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ31cclxuICAgICAqL1xyXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5nZXRDc3NDbGFzc2VzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgLy8gTWVyZ2UgYWxsIENTUyBjbGFzc2VzIGludG8gc2luZ2xlIGFycmF5XHJcbiAgICAgICAgdmFyIGZsYXR0ZW5lZEFycmF5ID0gW3RoaXMuY29uZmlnLmNzc0NsYXNzXS5jb25jYXQodGhpcy5jb25maWcuY3NzQ2xhc3Nlcyk7XHJcbiAgICAgICAgLy8gUHJlZml4IGNsYXNzZXNcclxuICAgICAgICBmbGF0dGVuZWRBcnJheSA9IGZsYXR0ZW5lZEFycmF5Lm1hcChmdW5jdGlvbiAoY3NzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBfdGhpcy5wcmVmaXhDc3MoY3NzKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBKb2luIGFycmF5IHZhbHVlcyBpbnRvIGEgc3RyaW5nXHJcbiAgICAgICAgdmFyIGZsYXR0ZW5lZFN0cmluZyA9IGZsYXR0ZW5lZEFycmF5LmpvaW4oJyAnKTtcclxuICAgICAgICAvLyBSZXR1cm4gdHJpbW1lZCBzdHJpbmcgdG8gcHJldmVudCB3aGl0ZXNwYWNlIGF0IHRoZSBlbmQgZnJvbSB0aGUgam9pbiBvcGVyYXRpb25cclxuICAgICAgICByZXR1cm4gZmxhdHRlbmVkU3RyaW5nLnRyaW0oKTtcclxuICAgIH07XHJcbiAgICBDb21wb25lbnQucHJvdG90eXBlLnByZWZpeENzcyA9IGZ1bmN0aW9uIChjc3NDbGFzc09ySWQpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb25maWcuY3NzUHJlZml4ICsgJy0nICsgY3NzQ2xhc3NPcklkO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgY29uZmlndXJhdGlvbiBvYmplY3Qgb2YgdGhlIGNvbXBvbmVudC5cclxuICAgICAqIEByZXR1cm5zIHtDb25maWd9XHJcbiAgICAgKi9cclxuICAgIENvbXBvbmVudC5wcm90b3R5cGUuZ2V0Q29uZmlnID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEhpZGVzIHRoZSBjb21wb25lbnQgaWYgc2hvd24uXHJcbiAgICAgKiBUaGlzIG1ldGhvZCBiYXNpY2FsbHkgdHJhbnNmZXJzIHRoZSBjb21wb25lbnQgaW50byB0aGUgaGlkZGVuIHN0YXRlLiBBY3R1YWwgaGlkaW5nIGlzIGRvbmUgdmlhIENTUy5cclxuICAgICAqL1xyXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5oaWRlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICghdGhpcy5oaWRkZW4pIHtcclxuICAgICAgICAgICAgdGhpcy5oaWRkZW4gPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLmdldERvbUVsZW1lbnQoKS5hZGRDbGFzcyh0aGlzLnByZWZpeENzcyhDb21wb25lbnQuQ0xBU1NfSElEREVOKSk7XHJcbiAgICAgICAgICAgIHRoaXMub25IaWRlRXZlbnQoKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBTaG93cyB0aGUgY29tcG9uZW50IGlmIGhpZGRlbi5cclxuICAgICAqL1xyXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5zaG93ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmhpZGRlbikge1xyXG4gICAgICAgICAgICB0aGlzLmdldERvbUVsZW1lbnQoKS5yZW1vdmVDbGFzcyh0aGlzLnByZWZpeENzcyhDb21wb25lbnQuQ0xBU1NfSElEREVOKSk7XHJcbiAgICAgICAgICAgIHRoaXMuaGlkZGVuID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHRoaXMub25TaG93RXZlbnQoKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBjb21wb25lbnQgaXMgaGlkZGVuLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWYgdGhlIGNvbXBvbmVudCBpcyBoaWRkZW4sIGVsc2UgZmFsc2VcclxuICAgICAqL1xyXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5pc0hpZGRlbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5oaWRkZW47XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBEZXRlcm1pbmVzIGlmIHRoZSBjb21wb25lbnQgaXMgc2hvd24uXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgY29tcG9uZW50IGlzIHZpc2libGUsIGVsc2UgZmFsc2VcclxuICAgICAqL1xyXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5pc1Nob3duID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiAhdGhpcy5pc0hpZGRlbigpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogVG9nZ2xlcyB0aGUgaGlkZGVuIHN0YXRlIGJ5IGhpZGluZyB0aGUgY29tcG9uZW50IGlmIGl0IGlzIHNob3duLCBvciBzaG93aW5nIGl0IGlmIGhpZGRlbi5cclxuICAgICAqL1xyXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS50b2dnbGVIaWRkZW4gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNIaWRkZW4oKSkge1xyXG4gICAgICAgICAgICB0aGlzLnNob3coKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuaGlkZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIERldGVybWluZXMgaWYgdGhlIGNvbXBvbmVudCBpcyBjdXJyZW50bHkgaG92ZXJlZC5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlIGlmIHRoZSBjb21wb25lbnQgaXMgaG92ZXJlZCwgZWxzZSBmYWxzZVxyXG4gICAgICovXHJcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmlzSG92ZXJlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5ob3ZlcmVkO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogRmlyZXMgdGhlIG9uU2hvdyBldmVudC5cclxuICAgICAqIFNlZSB0aGUgZGV0YWlsZWQgZXhwbGFuYXRpb24gb24gZXZlbnQgYXJjaGl0ZWN0dXJlIG9uIHRoZSB7QGxpbmsgI2NvbXBvbmVudEV2ZW50cyBldmVudHMgbGlzdH0uXHJcbiAgICAgKi9cclxuICAgIENvbXBvbmVudC5wcm90b3R5cGUub25TaG93RXZlbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5jb21wb25lbnRFdmVudHMub25TaG93LmRpc3BhdGNoKHRoaXMpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogRmlyZXMgdGhlIG9uSGlkZSBldmVudC5cclxuICAgICAqIFNlZSB0aGUgZGV0YWlsZWQgZXhwbGFuYXRpb24gb24gZXZlbnQgYXJjaGl0ZWN0dXJlIG9uIHRoZSB7QGxpbmsgI2NvbXBvbmVudEV2ZW50cyBldmVudHMgbGlzdH0uXHJcbiAgICAgKi9cclxuICAgIENvbXBvbmVudC5wcm90b3R5cGUub25IaWRlRXZlbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5jb21wb25lbnRFdmVudHMub25IaWRlLmRpc3BhdGNoKHRoaXMpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogRmlyZXMgdGhlIG9uSG92ZXJDaGFuZ2VkIGV2ZW50LlxyXG4gICAgICogU2VlIHRoZSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvbiBldmVudCBhcmNoaXRlY3R1cmUgb24gdGhlIHtAbGluayAjY29tcG9uZW50RXZlbnRzIGV2ZW50cyBsaXN0fS5cclxuICAgICAqL1xyXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5vbkhvdmVyQ2hhbmdlZEV2ZW50ID0gZnVuY3Rpb24gKGhvdmVyZWQpIHtcclxuICAgICAgICB0aGlzLmhvdmVyZWQgPSBob3ZlcmVkO1xyXG4gICAgICAgIHRoaXMuY29tcG9uZW50RXZlbnRzLm9uSG92ZXJDaGFuZ2VkLmRpc3BhdGNoKHRoaXMsIHsgaG92ZXJlZDogaG92ZXJlZCB9KTtcclxuICAgIH07XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQ29tcG9uZW50LnByb3RvdHlwZSwgXCJvblNob3dcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldHMgdGhlIGV2ZW50IHRoYXQgaXMgZmlyZWQgd2hlbiB0aGUgY29tcG9uZW50IGlzIHNob3dpbmcuXHJcbiAgICAgICAgICogU2VlIHRoZSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvbiBldmVudCBhcmNoaXRlY3R1cmUgb24gdGhlIHtAbGluayAjY29tcG9uZW50RXZlbnRzIGV2ZW50cyBsaXN0fS5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnQ8Q29tcG9uZW50PENvbmZpZz4sIE5vQXJncz59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbXBvbmVudEV2ZW50cy5vblNob3cuZ2V0RXZlbnQoKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShDb21wb25lbnQucHJvdG90eXBlLCBcIm9uSGlkZVwiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogR2V0cyB0aGUgZXZlbnQgdGhhdCBpcyBmaXJlZCB3aGVuIHRoZSBjb21wb25lbnQgaXMgaGlkaW5nLlxyXG4gICAgICAgICAqIFNlZSB0aGUgZGV0YWlsZWQgZXhwbGFuYXRpb24gb24gZXZlbnQgYXJjaGl0ZWN0dXJlIG9uIHRoZSB7QGxpbmsgI2NvbXBvbmVudEV2ZW50cyBldmVudHMgbGlzdH0uXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50PENvbXBvbmVudDxDb25maWc+LCBOb0FyZ3M+fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jb21wb25lbnRFdmVudHMub25IaWRlLmdldEV2ZW50KCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQ29tcG9uZW50LnByb3RvdHlwZSwgXCJvbkhvdmVyQ2hhbmdlZFwiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogR2V0cyB0aGUgZXZlbnQgdGhhdCBpcyBmaXJlZCB3aGVuIHRoZSBjb21wb25lbnQncyBob3Zlci1zdGF0ZSBpcyBjaGFuZ2luZy5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnQ8Q29tcG9uZW50PENvbmZpZz4sIENvbXBvbmVudEhvdmVyQ2hhbmdlZEV2ZW50QXJncz59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbXBvbmVudEV2ZW50cy5vbkhvdmVyQ2hhbmdlZC5nZXRFdmVudCgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIENvbXBvbmVudDtcclxufSgpKTtcclxuLyoqXHJcbiAqIFRoZSBjbGFzc25hbWUgdGhhdCBpcyBhdHRhY2hlZCB0byB0aGUgZWxlbWVudCB3aGVuIGl0IGlzIGluIHRoZSBoaWRkZW4gc3RhdGUuXHJcbiAqIEB0eXBlIHtzdHJpbmd9XHJcbiAqL1xyXG5Db21wb25lbnQuQ0xBU1NfSElEREVOID0gJ2hpZGRlbic7XHJcbmV4cG9ydHMuQ29tcG9uZW50ID0gQ29tcG9uZW50O1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvY29tcG9uZW50LnRzXG4vLyBtb2R1bGUgaWQgPSAyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgYXJyYXl1dGlsc18xID0gcmVxdWlyZShcIi4vYXJyYXl1dGlsc1wiKTtcclxuLyoqXHJcbiAqIEV2ZW50IGRpc3BhdGNoZXIgdG8gc3Vic2NyaWJlIGFuZCB0cmlnZ2VyIGV2ZW50cy4gRWFjaCBldmVudCBzaG91bGQgaGF2ZSBpdHMgb3duIGRpc3BhdGNoZXIuXHJcbiAqL1xyXG52YXIgRXZlbnREaXNwYXRjaGVyID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIEV2ZW50RGlzcGF0Y2hlcigpIHtcclxuICAgICAgICB0aGlzLmxpc3RlbmVycyA9IFtdO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiB7QGluaGVyaXREb2N9XHJcbiAgICAgKi9cclxuICAgIEV2ZW50RGlzcGF0Y2hlci5wcm90b3R5cGUuc3Vic2NyaWJlID0gZnVuY3Rpb24gKGxpc3RlbmVyKSB7XHJcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMucHVzaChuZXcgRXZlbnRMaXN0ZW5lcldyYXBwZXIobGlzdGVuZXIpKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIHtAaW5oZXJpdERvY31cclxuICAgICAqL1xyXG4gICAgRXZlbnREaXNwYXRjaGVyLnByb3RvdHlwZS5zdWJzY3JpYmVPbmNlID0gZnVuY3Rpb24gKGxpc3RlbmVyKSB7XHJcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMucHVzaChuZXcgRXZlbnRMaXN0ZW5lcldyYXBwZXIobGlzdGVuZXIsIHRydWUpKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIHtAaW5oZXJpdERvY31cclxuICAgICAqL1xyXG4gICAgRXZlbnREaXNwYXRjaGVyLnByb3RvdHlwZS5zdWJzY3JpYmVSYXRlTGltaXRlZCA9IGZ1bmN0aW9uIChsaXN0ZW5lciwgcmF0ZU1zKSB7XHJcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMucHVzaChuZXcgUmF0ZUxpbWl0ZWRFdmVudExpc3RlbmVyV3JhcHBlcihsaXN0ZW5lciwgcmF0ZU1zKSk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiB7QGluaGVyaXREb2N9XHJcbiAgICAgKi9cclxuICAgIEV2ZW50RGlzcGF0Y2hlci5wcm90b3R5cGUudW5zdWJzY3JpYmUgPSBmdW5jdGlvbiAobGlzdGVuZXIpIHtcclxuICAgICAgICAvLyBJdGVyYXRlIHRocm91Z2ggbGlzdGVuZXJzLCBjb21wYXJlIHdpdGggcGFyYW1ldGVyLCBhbmQgcmVtb3ZlIGlmIGZvdW5kXHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxpc3RlbmVycy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICB2YXIgc3Vic2NyaWJlZExpc3RlbmVyID0gdGhpcy5saXN0ZW5lcnNbaV07XHJcbiAgICAgICAgICAgIGlmIChzdWJzY3JpYmVkTGlzdGVuZXIubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgICAgICBhcnJheXV0aWxzXzEuQXJyYXlVdGlscy5yZW1vdmUodGhpcy5saXN0ZW5lcnMsIHN1YnNjcmliZWRMaXN0ZW5lcik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIGFsbCBsaXN0ZW5lcnMgZnJvbSB0aGlzIGRpc3BhdGNoZXIuXHJcbiAgICAgKi9cclxuICAgIEV2ZW50RGlzcGF0Y2hlci5wcm90b3R5cGUudW5zdWJzY3JpYmVBbGwgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5saXN0ZW5lcnMgPSBbXTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIERpc3BhdGNoZXMgYW4gZXZlbnQgdG8gYWxsIHN1YnNjcmliZWQgbGlzdGVuZXJzLlxyXG4gICAgICogQHBhcmFtIHNlbmRlciB0aGUgc291cmNlIG9mIHRoZSBldmVudFxyXG4gICAgICogQHBhcmFtIGFyZ3MgdGhlIGFyZ3VtZW50cyBmb3IgdGhlIGV2ZW50XHJcbiAgICAgKi9cclxuICAgIEV2ZW50RGlzcGF0Y2hlci5wcm90b3R5cGUuZGlzcGF0Y2ggPSBmdW5jdGlvbiAoc2VuZGVyLCBhcmdzKSB7XHJcbiAgICAgICAgaWYgKGFyZ3MgPT09IHZvaWQgMCkgeyBhcmdzID0gbnVsbDsgfVxyXG4gICAgICAgIHZhciBsaXN0ZW5lcnNUb1JlbW92ZSA9IFtdO1xyXG4gICAgICAgIC8vIENhbGwgZXZlcnkgbGlzdGVuZXJcclxuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdGhpcy5saXN0ZW5lcnM7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgIHZhciBsaXN0ZW5lciA9IF9hW19pXTtcclxuICAgICAgICAgICAgbGlzdGVuZXIuZmlyZShzZW5kZXIsIGFyZ3MpO1xyXG4gICAgICAgICAgICBpZiAobGlzdGVuZXIuaXNPbmNlKCkpIHtcclxuICAgICAgICAgICAgICAgIGxpc3RlbmVyc1RvUmVtb3ZlLnB1c2gobGlzdGVuZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIFJlbW92ZSBvbmUtdGltZSBsaXN0ZW5lclxyXG4gICAgICAgIGZvciAodmFyIF9iID0gMCwgbGlzdGVuZXJzVG9SZW1vdmVfMSA9IGxpc3RlbmVyc1RvUmVtb3ZlOyBfYiA8IGxpc3RlbmVyc1RvUmVtb3ZlXzEubGVuZ3RoOyBfYisrKSB7XHJcbiAgICAgICAgICAgIHZhciBsaXN0ZW5lclRvUmVtb3ZlID0gbGlzdGVuZXJzVG9SZW1vdmVfMVtfYl07XHJcbiAgICAgICAgICAgIGFycmF5dXRpbHNfMS5BcnJheVV0aWxzLnJlbW92ZSh0aGlzLmxpc3RlbmVycywgbGlzdGVuZXJUb1JlbW92ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgZXZlbnQgdGhhdCB0aGlzIGRpc3BhdGNoZXIgbWFuYWdlcyBhbmQgb24gd2hpY2ggbGlzdGVuZXJzIGNhbiBzdWJzY3JpYmUgYW5kIHVuc3Vic2NyaWJlIGV2ZW50IGhhbmRsZXJzLlxyXG4gICAgICogQHJldHVybnMge0V2ZW50fVxyXG4gICAgICovXHJcbiAgICBFdmVudERpc3BhdGNoZXIucHJvdG90eXBlLmdldEV2ZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIEZvciBub3csIGp1c3QgY2FzdCB0aGUgZXZlbnQgZGlzcGF0Y2hlciB0byB0aGUgZXZlbnQgaW50ZXJmYWNlLiBBdCBzb21lIHBvaW50IGluIHRoZSBmdXR1cmUgd2hlbiB0aGVcclxuICAgICAgICAvLyBjb2RlYmFzZSBncm93cywgaXQgbWlnaHQgbWFrZSBzZW5zZSB0byBzcGxpdCB0aGUgZGlzcGF0Y2hlciBpbnRvIHNlcGFyYXRlIGRpc3BhdGNoZXIgYW5kIGV2ZW50IGNsYXNzZXMuXHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIEV2ZW50RGlzcGF0Y2hlcjtcclxufSgpKTtcclxuZXhwb3J0cy5FdmVudERpc3BhdGNoZXIgPSBFdmVudERpc3BhdGNoZXI7XHJcbi8qKlxyXG4gKiBBIGJhc2ljIGV2ZW50IGxpc3RlbmVyIHdyYXBwZXIgdG8gbWFuYWdlIGxpc3RlbmVycyB3aXRoaW4gdGhlIHtAbGluayBFdmVudERpc3BhdGNoZXJ9LiBUaGlzIGlzIGEgJ3ByaXZhdGUnIGNsYXNzXHJcbiAqIGZvciBpbnRlcm5hbCBkaXNwYXRjaGVyIHVzZSBhbmQgaXQgaXMgdGhlcmVmb3JlIG5vdCBleHBvcnRlZC5cclxuICovXHJcbnZhciBFdmVudExpc3RlbmVyV3JhcHBlciA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBFdmVudExpc3RlbmVyV3JhcHBlcihsaXN0ZW5lciwgb25jZSkge1xyXG4gICAgICAgIGlmIChvbmNlID09PSB2b2lkIDApIHsgb25jZSA9IGZhbHNlOyB9XHJcbiAgICAgICAgdGhpcy5ldmVudExpc3RlbmVyID0gbGlzdGVuZXI7XHJcbiAgICAgICAgdGhpcy5vbmNlID0gb25jZTtcclxuICAgIH1cclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShFdmVudExpc3RlbmVyV3JhcHBlci5wcm90b3R5cGUsIFwibGlzdGVuZXJcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJldHVybnMgdGhlIHdyYXBwZWQgZXZlbnQgbGlzdGVuZXIuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50TGlzdGVuZXI8U2VuZGVyLCBBcmdzPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRMaXN0ZW5lcjtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIC8qKlxyXG4gICAgICogRmlyZXMgdGhlIHdyYXBwZWQgZXZlbnQgbGlzdGVuZXIgd2l0aCB0aGUgZ2l2ZW4gYXJndW1lbnRzLlxyXG4gICAgICogQHBhcmFtIHNlbmRlclxyXG4gICAgICogQHBhcmFtIGFyZ3NcclxuICAgICAqL1xyXG4gICAgRXZlbnRMaXN0ZW5lcldyYXBwZXIucHJvdG90eXBlLmZpcmUgPSBmdW5jdGlvbiAoc2VuZGVyLCBhcmdzKSB7XHJcbiAgICAgICAgdGhpcy5ldmVudExpc3RlbmVyKHNlbmRlciwgYXJncyk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBDaGVja3MgaWYgdGhpcyBsaXN0ZW5lciBpcyBzY2hlZHVsZWQgdG8gYmUgY2FsbGVkIG9ubHkgb25jZS5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSBvbmNlIGlmIHRydWVcclxuICAgICAqL1xyXG4gICAgRXZlbnRMaXN0ZW5lcldyYXBwZXIucHJvdG90eXBlLmlzT25jZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5vbmNlO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBFdmVudExpc3RlbmVyV3JhcHBlcjtcclxufSgpKTtcclxuLyoqXHJcbiAqIEV4dGVuZHMgdGhlIGJhc2ljIHtAbGluayBFdmVudExpc3RlbmVyV3JhcHBlcn0gd2l0aCByYXRlLWxpbWl0aW5nIGZ1bmN0aW9uYWxpdHkuXHJcbiAqL1xyXG52YXIgUmF0ZUxpbWl0ZWRFdmVudExpc3RlbmVyV3JhcHBlciA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoUmF0ZUxpbWl0ZWRFdmVudExpc3RlbmVyV3JhcHBlciwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFJhdGVMaW1pdGVkRXZlbnRMaXN0ZW5lcldyYXBwZXIobGlzdGVuZXIsIHJhdGVNcykge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGxpc3RlbmVyKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLnJhdGVNcyA9IHJhdGVNcztcclxuICAgICAgICBfdGhpcy5sYXN0RmlyZVRpbWUgPSAwO1xyXG4gICAgICAgIC8vIFdyYXAgdGhlIGV2ZW50IGxpc3RlbmVyIHdpdGggYW4gZXZlbnQgbGlzdGVuZXIgdGhhdCBkb2VzIHRoZSByYXRlLWxpbWl0aW5nXHJcbiAgICAgICAgX3RoaXMucmF0ZUxpbWl0aW5nRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uIChzZW5kZXIsIGFyZ3MpIHtcclxuICAgICAgICAgICAgaWYgKERhdGUubm93KCkgLSBfdGhpcy5sYXN0RmlyZVRpbWUgPiBfdGhpcy5yYXRlTXMpIHtcclxuICAgICAgICAgICAgICAgIC8vIE9ubHkgaWYgZW5vdWdoIHRpbWUgc2luY2UgdGhlIHByZXZpb3VzIGNhbGwgaGFzIHBhc3NlZCwgY2FsbCB0aGVcclxuICAgICAgICAgICAgICAgIC8vIGFjdHVhbCBldmVudCBsaXN0ZW5lciBhbmQgcmVjb3JkIHRoZSBjdXJyZW50IHRpbWVcclxuICAgICAgICAgICAgICAgIF90aGlzLmZpcmVTdXBlcihzZW5kZXIsIGFyZ3MpO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMubGFzdEZpcmVUaW1lID0gRGF0ZS5ub3coKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgUmF0ZUxpbWl0ZWRFdmVudExpc3RlbmVyV3JhcHBlci5wcm90b3R5cGUuZmlyZVN1cGVyID0gZnVuY3Rpb24gKHNlbmRlciwgYXJncykge1xyXG4gICAgICAgIC8vIEZpcmUgdGhlIGFjdHVhbCBleHRlcm5hbCBldmVudCBsaXN0ZW5lclxyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuZmlyZS5jYWxsKHRoaXMsIHNlbmRlciwgYXJncyk7XHJcbiAgICB9O1xyXG4gICAgUmF0ZUxpbWl0ZWRFdmVudExpc3RlbmVyV3JhcHBlci5wcm90b3R5cGUuZmlyZSA9IGZ1bmN0aW9uIChzZW5kZXIsIGFyZ3MpIHtcclxuICAgICAgICAvLyBGaXJlIHRoZSBpbnRlcm5hbCByYXRlLWxpbWl0aW5nIGxpc3RlbmVyIGluc3RlYWQgb2YgdGhlIGV4dGVybmFsIGV2ZW50IGxpc3RlbmVyXHJcbiAgICAgICAgdGhpcy5yYXRlTGltaXRpbmdFdmVudExpc3RlbmVyKHNlbmRlciwgYXJncyk7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFJhdGVMaW1pdGVkRXZlbnRMaXN0ZW5lcldyYXBwZXI7XHJcbn0oRXZlbnRMaXN0ZW5lcldyYXBwZXIpKTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9ldmVudGRpc3BhdGNoZXIudHNcbi8vIG1vZHVsZSBpZCA9IDNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIEFycmF5VXRpbHM7XHJcbihmdW5jdGlvbiAoQXJyYXlVdGlscykge1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIGFuIGl0ZW0gZnJvbSBhbiBhcnJheS5cclxuICAgICAqIEBwYXJhbSBhcnJheSB0aGUgYXJyYXkgdGhhdCBtYXkgY29udGFpbiB0aGUgaXRlbSB0byByZW1vdmVcclxuICAgICAqIEBwYXJhbSBpdGVtIHRoZSBpdGVtIHRvIHJlbW92ZSBmcm9tIHRoZSBhcnJheVxyXG4gICAgICogQHJldHVybnMge2FueX0gdGhlIHJlbW92ZWQgaXRlbSBvciBudWxsIGlmIGl0IHdhc24ndCBwYXJ0IG9mIHRoZSBhcnJheVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiByZW1vdmUoYXJyYXksIGl0ZW0pIHtcclxuICAgICAgICB2YXIgaW5kZXggPSBhcnJheS5pbmRleE9mKGl0ZW0pO1xyXG4gICAgICAgIGlmIChpbmRleCA+IC0xKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBhcnJheS5zcGxpY2UoaW5kZXgsIDEpWzBdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG4gICAgQXJyYXlVdGlscy5yZW1vdmUgPSByZW1vdmU7XHJcbn0pKEFycmF5VXRpbHMgPSBleHBvcnRzLkFycmF5VXRpbHMgfHwgKGV4cG9ydHMuQXJyYXlVdGlscyA9IHt9KSk7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvYXJyYXl1dGlscy50c1xuLy8gbW9kdWxlIGlkID0gNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgZXZlbnRkaXNwYXRjaGVyXzEgPSByZXF1aXJlKFwiLi9ldmVudGRpc3BhdGNoZXJcIik7XHJcbnZhciBicm93c2VydXRpbHNfMSA9IHJlcXVpcmUoXCIuL2Jyb3dzZXJ1dGlsc1wiKTtcclxudmFyIFBsYXllclV0aWxzO1xyXG4oZnVuY3Rpb24gKFBsYXllclV0aWxzKSB7XHJcbiAgICB2YXIgUGxheWVyU3RhdGU7XHJcbiAgICAoZnVuY3Rpb24gKFBsYXllclN0YXRlKSB7XHJcbiAgICAgICAgUGxheWVyU3RhdGVbUGxheWVyU3RhdGVbXCJJRExFXCJdID0gMF0gPSBcIklETEVcIjtcclxuICAgICAgICBQbGF5ZXJTdGF0ZVtQbGF5ZXJTdGF0ZVtcIlBSRVBBUkVEXCJdID0gMV0gPSBcIlBSRVBBUkVEXCI7XHJcbiAgICAgICAgUGxheWVyU3RhdGVbUGxheWVyU3RhdGVbXCJQTEFZSU5HXCJdID0gMl0gPSBcIlBMQVlJTkdcIjtcclxuICAgICAgICBQbGF5ZXJTdGF0ZVtQbGF5ZXJTdGF0ZVtcIlBBVVNFRFwiXSA9IDNdID0gXCJQQVVTRURcIjtcclxuICAgICAgICBQbGF5ZXJTdGF0ZVtQbGF5ZXJTdGF0ZVtcIkZJTklTSEVEXCJdID0gNF0gPSBcIkZJTklTSEVEXCI7XHJcbiAgICB9KShQbGF5ZXJTdGF0ZSA9IFBsYXllclV0aWxzLlBsYXllclN0YXRlIHx8IChQbGF5ZXJVdGlscy5QbGF5ZXJTdGF0ZSA9IHt9KSk7XHJcbiAgICBmdW5jdGlvbiBpc1NvdXJjZUxvYWRlZChwbGF5ZXIpIHtcclxuICAgICAgICByZXR1cm4gcGxheWVyLmdldENvbmZpZygpLnNvdXJjZSAhPT0gdW5kZWZpbmVkO1xyXG4gICAgfVxyXG4gICAgUGxheWVyVXRpbHMuaXNTb3VyY2VMb2FkZWQgPSBpc1NvdXJjZUxvYWRlZDtcclxuICAgIGZ1bmN0aW9uIGlzVGltZVNoaWZ0QXZhaWxhYmxlKHBsYXllcikge1xyXG4gICAgICAgIHJldHVybiBwbGF5ZXIuaXNMaXZlKCkgJiYgcGxheWVyLmdldE1heFRpbWVTaGlmdCgpICE9PSAwO1xyXG4gICAgfVxyXG4gICAgUGxheWVyVXRpbHMuaXNUaW1lU2hpZnRBdmFpbGFibGUgPSBpc1RpbWVTaGlmdEF2YWlsYWJsZTtcclxuICAgIGZ1bmN0aW9uIGdldFN0YXRlKHBsYXllcikge1xyXG4gICAgICAgIGlmIChwbGF5ZXIuaGFzRW5kZWQoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gUGxheWVyU3RhdGUuRklOSVNIRUQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKHBsYXllci5pc1BsYXlpbmcoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gUGxheWVyU3RhdGUuUExBWUlORztcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAocGxheWVyLmlzUGF1c2VkKCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIFBsYXllclN0YXRlLlBBVVNFRDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoaXNTb3VyY2VMb2FkZWQocGxheWVyKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gUGxheWVyU3RhdGUuUFJFUEFSRUQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gUGxheWVyU3RhdGUuSURMRTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBQbGF5ZXJVdGlscy5nZXRTdGF0ZSA9IGdldFN0YXRlO1xyXG4gICAgdmFyIFRpbWVTaGlmdEF2YWlsYWJpbGl0eURldGVjdG9yID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBmdW5jdGlvbiBUaW1lU2hpZnRBdmFpbGFiaWxpdHlEZXRlY3RvcihwbGF5ZXIpIHtcclxuICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICAgICAgdGhpcy50aW1lU2hpZnRBdmFpbGFiaWxpdHlDaGFuZ2VkRXZlbnQgPSBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCk7XHJcbiAgICAgICAgICAgIHRoaXMucGxheWVyID0gcGxheWVyO1xyXG4gICAgICAgICAgICB0aGlzLnRpbWVTaGlmdEF2YWlsYWJsZSA9IHVuZGVmaW5lZDtcclxuICAgICAgICAgICAgdmFyIHRpbWVTaGlmdERldGVjdG9yID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZGV0ZWN0KCk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIC8vIFRyeSB0byBkZXRlY3QgdGltZXNoaWZ0IGF2YWlsYWJpbGl0eSBpbiBPTl9SRUFEWSwgd2hpY2ggd29ya3MgZm9yIERBU0ggc3RyZWFtc1xyXG4gICAgICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9SRUFEWSwgdGltZVNoaWZ0RGV0ZWN0b3IpO1xyXG4gICAgICAgICAgICAvLyBXaXRoIEhMUy9OYXRpdmVQbGF5ZXIgc3RyZWFtcywgZ2V0TWF4VGltZVNoaWZ0IGNhbiBiZSAwIGJlZm9yZSB0aGUgYnVmZmVyIGZpbGxzLCBzbyB3ZSBuZWVkIHRvIGFkZGl0aW9uYWxseVxyXG4gICAgICAgICAgICAvLyBjaGVjayB0aW1lc2hpZnQgYXZhaWxhYmlsaXR5IGluIE9OX1RJTUVfQ0hBTkdFRFxyXG4gICAgICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9USU1FX0NIQU5HRUQsIHRpbWVTaGlmdERldGVjdG9yKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgVGltZVNoaWZ0QXZhaWxhYmlsaXR5RGV0ZWN0b3IucHJvdG90eXBlLmRldGVjdCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMucGxheWVyLmlzTGl2ZSgpKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgdGltZVNoaWZ0QXZhaWxhYmxlTm93ID0gUGxheWVyVXRpbHMuaXNUaW1lU2hpZnRBdmFpbGFibGUodGhpcy5wbGF5ZXIpO1xyXG4gICAgICAgICAgICAgICAgLy8gV2hlbiB0aGUgYXZhaWxhYmlsaXR5IGNoYW5nZXMsIHdlIGZpcmUgdGhlIGV2ZW50XHJcbiAgICAgICAgICAgICAgICBpZiAodGltZVNoaWZ0QXZhaWxhYmxlTm93ICE9PSB0aGlzLnRpbWVTaGlmdEF2YWlsYWJsZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudGltZVNoaWZ0QXZhaWxhYmlsaXR5Q2hhbmdlZEV2ZW50LmRpc3BhdGNoKHRoaXMucGxheWVyLCB7IHRpbWVTaGlmdEF2YWlsYWJsZTogdGltZVNoaWZ0QXZhaWxhYmxlTm93IH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudGltZVNoaWZ0QXZhaWxhYmxlID0gdGltZVNoaWZ0QXZhaWxhYmxlTm93O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVGltZVNoaWZ0QXZhaWxhYmlsaXR5RGV0ZWN0b3IucHJvdG90eXBlLCBcIm9uVGltZVNoaWZ0QXZhaWxhYmlsaXR5Q2hhbmdlZFwiLCB7XHJcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMudGltZVNoaWZ0QXZhaWxhYmlsaXR5Q2hhbmdlZEV2ZW50LmdldEV2ZW50KCk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiBUaW1lU2hpZnRBdmFpbGFiaWxpdHlEZXRlY3RvcjtcclxuICAgIH0oKSk7XHJcbiAgICBQbGF5ZXJVdGlscy5UaW1lU2hpZnRBdmFpbGFiaWxpdHlEZXRlY3RvciA9IFRpbWVTaGlmdEF2YWlsYWJpbGl0eURldGVjdG9yO1xyXG4gICAgLyoqXHJcbiAgICAgKiBEZXRlY3RzIGNoYW5nZXMgb2YgdGhlIHN0cmVhbSB0eXBlLCBpLmUuIGNoYW5nZXMgb2YgdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgcGxheWVyI2lzTGl2ZSBtZXRob2QuXHJcbiAgICAgKiBOb3JtYWxseSwgYSBzdHJlYW0gY2Fubm90IGNoYW5nZSBpdHMgdHlwZSBkdXJpbmcgcGxheWJhY2ssIGl0J3MgZWl0aGVyIFZPRCBvciBsaXZlLiBEdWUgdG8gYnVncyBvbiBzb21lXHJcbiAgICAgKiBwbGF0Zm9ybXMgb3IgYnJvd3NlcnMsIGl0IGNhbiBzdGlsbCBjaGFuZ2UuIEl0IGlzIHRoZXJlZm9yZSB1bnJlbGlhYmxlIHRvIGp1c3QgY2hlY2sgI2lzTGl2ZSBhbmQgdGhpcyBkZXRlY3RvclxyXG4gICAgICogc2hvdWxkIGJlIHVzZWQgYXMgYSB3b3JrYXJvdW5kIGluc3RlYWQuXHJcbiAgICAgKlxyXG4gICAgICogS25vd24gY2FzZXM6XHJcbiAgICAgKlxyXG4gICAgICogLSBITFMgVk9EIG9uIEFuZHJvaWQgNC4zXHJcbiAgICAgKiBWaWRlbyBkdXJhdGlvbiBpcyBpbml0aWFsbHkgJ0luZmluaXR5JyBhbmQgb25seSBnZXRzIGF2YWlsYWJsZSBhZnRlciBwbGF5YmFjayBzdGFydHMsIHNvIHN0cmVhbXMgYXJlIHdyb25nbHlcclxuICAgICAqIHJlcG9ydGVkIGFzICdsaXZlJyBiZWZvcmUgcGxheWJhY2sgKHRoZSBsaXZlLWNoZWNrIGluIHRoZSBwbGF5ZXIgY2hlY2tzIGZvciBpbmZpbml0ZSBkdXJhdGlvbikuXHJcbiAgICAgKi9cclxuICAgIHZhciBMaXZlU3RyZWFtRGV0ZWN0b3IgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIExpdmVTdHJlYW1EZXRlY3RvcihwbGF5ZXIpIHtcclxuICAgICAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICAgICAgdGhpcy5saXZlQ2hhbmdlZEV2ZW50ID0gbmV3IGV2ZW50ZGlzcGF0Y2hlcl8xLkV2ZW50RGlzcGF0Y2hlcigpO1xyXG4gICAgICAgICAgICB0aGlzLnBsYXllciA9IHBsYXllcjtcclxuICAgICAgICAgICAgdGhpcy5saXZlID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICB2YXIgbGl2ZURldGVjdG9yID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZGV0ZWN0KCk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIC8vIEluaXRpYWxpemUgd2hlbiBwbGF5ZXIgaXMgcmVhZHlcclxuICAgICAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUkVBRFksIGxpdmVEZXRlY3Rvcik7XHJcbiAgICAgICAgICAgIC8vIFJlLWV2YWx1YXRlIHdoZW4gcGxheWJhY2sgc3RhcnRzXHJcbiAgICAgICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BMQVksIGxpdmVEZXRlY3Rvcik7XHJcbiAgICAgICAgICAgIC8vIEhMUyBsaXZlIGRldGVjdGlvbiB3b3JrYXJvdW5kIGZvciBBbmRyb2lkOlxyXG4gICAgICAgICAgICAvLyBBbHNvIHJlLWV2YWx1YXRlIGR1cmluZyBwbGF5YmFjaywgYmVjYXVzZSB0aGF0IGlzIHdoZW4gdGhlIGxpdmUgZmxhZyBtaWdodCBjaGFuZ2UuXHJcbiAgICAgICAgICAgIC8vIChEb2luZyBpdCBvbmx5IGluIEFuZHJvaWQgQ2hyb21lIHNhdmVzIHVubmVjZXNzYXJ5IG92ZXJoZWFkIG9uIG90aGVyIHBsYXR0Zm9ybXMpXHJcbiAgICAgICAgICAgIGlmIChicm93c2VydXRpbHNfMS5Ccm93c2VyVXRpbHMuaXNBbmRyb2lkICYmIGJyb3dzZXJ1dGlsc18xLkJyb3dzZXJVdGlscy5pc0Nocm9tZSkge1xyXG4gICAgICAgICAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fVElNRV9DSEFOR0VELCBsaXZlRGV0ZWN0b3IpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIExpdmVTdHJlYW1EZXRlY3Rvci5wcm90b3R5cGUuZGV0ZWN0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgbGl2ZU5vdyA9IHRoaXMucGxheWVyLmlzTGl2ZSgpO1xyXG4gICAgICAgICAgICAvLyBDb21wYXJlIGN1cnJlbnQgdG8gcHJldmlvdXMgbGl2ZSBzdGF0ZSBmbGFnIGFuZCBmaXJlIGV2ZW50IHdoZW4gaXQgY2hhbmdlcy4gU2luY2Ugd2UgaW5pdGlhbGl6ZSB0aGUgZmxhZ1xyXG4gICAgICAgICAgICAvLyB3aXRoIHVuZGVmaW5lZCwgdGhlcmUgaXMgYWx3YXlzIGF0IGxlYXN0IGFuIGluaXRpYWwgZXZlbnQgZmlyZWQgdGhhdCB0ZWxscyBsaXN0ZW5lcnMgdGhlIGxpdmUgc3RhdGUuXHJcbiAgICAgICAgICAgIGlmIChsaXZlTm93ICE9PSB0aGlzLmxpdmUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMubGl2ZUNoYW5nZWRFdmVudC5kaXNwYXRjaCh0aGlzLnBsYXllciwgeyBsaXZlOiBsaXZlTm93IH0pO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5saXZlID0gbGl2ZU5vdztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KExpdmVTdHJlYW1EZXRlY3Rvci5wcm90b3R5cGUsIFwib25MaXZlQ2hhbmdlZFwiLCB7XHJcbiAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMubGl2ZUNoYW5nZWRFdmVudC5nZXRFdmVudCgpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gTGl2ZVN0cmVhbURldGVjdG9yO1xyXG4gICAgfSgpKTtcclxuICAgIFBsYXllclV0aWxzLkxpdmVTdHJlYW1EZXRlY3RvciA9IExpdmVTdHJlYW1EZXRlY3RvcjtcclxufSkoUGxheWVyVXRpbHMgPSBleHBvcnRzLlBsYXllclV0aWxzIHx8IChleHBvcnRzLlBsYXllclV0aWxzID0ge30pKTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9wbGF5ZXJ1dGlscy50c1xuLy8gbW9kdWxlIGlkID0gNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGNvbXBvbmVudF8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50XCIpO1xyXG52YXIgZG9tXzEgPSByZXF1aXJlKFwiLi4vZG9tXCIpO1xyXG52YXIgZXZlbnRkaXNwYXRjaGVyXzEgPSByZXF1aXJlKFwiLi4vZXZlbnRkaXNwYXRjaGVyXCIpO1xyXG4vKipcclxuICogQSBzaW1wbGUgY2xpY2thYmxlIGJ1dHRvbi5cclxuICovXHJcbnZhciBCdXR0b24gPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKEJ1dHRvbiwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIEJ1dHRvbihjb25maWcpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuYnV0dG9uRXZlbnRzID0ge1xyXG4gICAgICAgICAgICBvbkNsaWNrOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgfTtcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1idXR0b24nLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgQnV0dG9uLnByb3RvdHlwZS50b0RvbUVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICAvLyBDcmVhdGUgdGhlIGJ1dHRvbiBlbGVtZW50IHdpdGggdGhlIHRleHQgbGFiZWxcclxuICAgICAgICB2YXIgYnV0dG9uRWxlbWVudCA9IG5ldyBkb21fMS5ET00oJ2J1dHRvbicsIHtcclxuICAgICAgICAgICAgJ3R5cGUnOiAnYnV0dG9uJyxcclxuICAgICAgICAgICAgJ2lkJzogdGhpcy5jb25maWcuaWQsXHJcbiAgICAgICAgICAgICdjbGFzcyc6IHRoaXMuZ2V0Q3NzQ2xhc3NlcygpLFxyXG4gICAgICAgIH0pLmFwcGVuZChuZXcgZG9tXzEuRE9NKCdzcGFuJywge1xyXG4gICAgICAgICAgICAnY2xhc3MnOiB0aGlzLnByZWZpeENzcygnbGFiZWwnKSxcclxuICAgICAgICB9KS5odG1sKHRoaXMuY29uZmlnLnRleHQpKTtcclxuICAgICAgICAvLyBMaXN0ZW4gZm9yIHRoZSBjbGljayBldmVudCBvbiB0aGUgYnV0dG9uIGVsZW1lbnQgYW5kIHRyaWdnZXIgdGhlIGNvcnJlc3BvbmRpbmcgZXZlbnQgb24gdGhlIGJ1dHRvbiBjb21wb25lbnRcclxuICAgICAgICBidXR0b25FbGVtZW50Lm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMub25DbGlja0V2ZW50KCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIGJ1dHRvbkVsZW1lbnQ7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIHRleHQgb24gdGhlIGxhYmVsIG9mIHRoZSBidXR0b24uXHJcbiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgdGV4dCB0byBwdXQgaW50byB0aGUgbGFiZWwgb2YgdGhlIGJ1dHRvblxyXG4gICAgICovXHJcbiAgICBCdXR0b24ucHJvdG90eXBlLnNldFRleHQgPSBmdW5jdGlvbiAodGV4dCkge1xyXG4gICAgICAgIHRoaXMuZ2V0RG9tRWxlbWVudCgpLmZpbmQoJy4nICsgdGhpcy5wcmVmaXhDc3MoJ2xhYmVsJykpLmh0bWwodGV4dCk7XHJcbiAgICB9O1xyXG4gICAgQnV0dG9uLnByb3RvdHlwZS5vbkNsaWNrRXZlbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5idXR0b25FdmVudHMub25DbGljay5kaXNwYXRjaCh0aGlzKTtcclxuICAgIH07XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoQnV0dG9uLnByb3RvdHlwZSwgXCJvbkNsaWNrXCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXRzIHRoZSBldmVudCB0aGF0IGlzIGZpcmVkIHdoZW4gdGhlIGJ1dHRvbiBpcyBjbGlja2VkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtFdmVudDxCdXR0b248Q29uZmlnPiwgTm9BcmdzPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYnV0dG9uRXZlbnRzLm9uQ2xpY2suZ2V0RXZlbnQoKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIHJldHVybiBCdXR0b247XHJcbn0oY29tcG9uZW50XzEuQ29tcG9uZW50KSk7XHJcbmV4cG9ydHMuQnV0dG9uID0gQnV0dG9uO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvYnV0dG9uLnRzXG4vLyBtb2R1bGUgaWQgPSA2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRcIik7XHJcbnZhciBkb21fMSA9IHJlcXVpcmUoXCIuLi9kb21cIik7XHJcbnZhciBldmVudGRpc3BhdGNoZXJfMSA9IHJlcXVpcmUoXCIuLi9ldmVudGRpc3BhdGNoZXJcIik7XHJcbi8qKlxyXG4gKiBBIHNpbXBsZSB0ZXh0IGxhYmVsLlxyXG4gKlxyXG4gKiBET00gZXhhbXBsZTpcclxuICogPGNvZGU+XHJcbiAqICAgICA8c3BhbiBjbGFzcz0ndWktbGFiZWwnPi4uLnNvbWUgdGV4dC4uLjwvc3Bhbj5cclxuICogPC9jb2RlPlxyXG4gKi9cclxudmFyIExhYmVsID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhMYWJlbCwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIExhYmVsKGNvbmZpZykge1xyXG4gICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5sYWJlbEV2ZW50cyA9IHtcclxuICAgICAgICAgICAgb25DbGljazogbmV3IGV2ZW50ZGlzcGF0Y2hlcl8xLkV2ZW50RGlzcGF0Y2hlcigpLFxyXG4gICAgICAgICAgICBvblRleHRDaGFuZ2VkOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgfTtcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1sYWJlbCcsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICBfdGhpcy50ZXh0ID0gX3RoaXMuY29uZmlnLnRleHQ7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgTGFiZWwucHJvdG90eXBlLnRvRG9tRWxlbWVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciBsYWJlbEVsZW1lbnQgPSBuZXcgZG9tXzEuRE9NKCdzcGFuJywge1xyXG4gICAgICAgICAgICAnaWQnOiB0aGlzLmNvbmZpZy5pZCxcclxuICAgICAgICAgICAgJ2NsYXNzJzogdGhpcy5nZXRDc3NDbGFzc2VzKCksXHJcbiAgICAgICAgfSkuaHRtbCh0aGlzLnRleHQpO1xyXG4gICAgICAgIGxhYmVsRWxlbWVudC5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLm9uQ2xpY2tFdmVudCgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiBsYWJlbEVsZW1lbnQ7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBTZXQgdGhlIHRleHQgb24gdGhpcyBsYWJlbC5cclxuICAgICAqIEBwYXJhbSB0ZXh0XHJcbiAgICAgKi9cclxuICAgIExhYmVsLnByb3RvdHlwZS5zZXRUZXh0ID0gZnVuY3Rpb24gKHRleHQpIHtcclxuICAgICAgICB0aGlzLnRleHQgPSB0ZXh0O1xyXG4gICAgICAgIHRoaXMuZ2V0RG9tRWxlbWVudCgpLmh0bWwodGV4dCk7XHJcbiAgICAgICAgdGhpcy5vblRleHRDaGFuZ2VkRXZlbnQodGV4dCk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSB0ZXh0IG9uIHRoaXMgbGFiZWwuXHJcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSB0ZXh0IG9uIHRoZSBsYWJlbFxyXG4gICAgICovXHJcbiAgICBMYWJlbC5wcm90b3R5cGUuZ2V0VGV4dCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy50ZXh0O1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQ2xlYXJzIHRoZSB0ZXh0IG9uIHRoaXMgbGFiZWwuXHJcbiAgICAgKi9cclxuICAgIExhYmVsLnByb3RvdHlwZS5jbGVhclRleHQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5nZXREb21FbGVtZW50KCkuaHRtbCgnJyk7XHJcbiAgICAgICAgdGhpcy5vblRleHRDaGFuZ2VkRXZlbnQobnVsbCk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBUZXN0cyBpZiB0aGUgbGFiZWwgaXMgZW1wdHkgYW5kIGRvZXMgbm90IGNvbnRhaW4gYW55IHRleHQuXHJcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBsYWJlbCBpcyBlbXB0eSwgZWxzZSBmYWxzZVxyXG4gICAgICovXHJcbiAgICBMYWJlbC5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gIXRoaXMudGV4dDtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEZpcmVzIHRoZSB7QGxpbmsgI29uQ2xpY2t9IGV2ZW50LlxyXG4gICAgICogQ2FuIGJlIHVzZWQgYnkgc3ViY2xhc3NlcyB0byBsaXN0ZW4gdG8gdGhpcyBldmVudCB3aXRob3V0IHN1YnNjcmliaW5nIGFuIGV2ZW50IGxpc3RlbmVyIGJ5IG92ZXJ3cml0aW5nIHRoZSBtZXRob2RcclxuICAgICAqIGFuZCBjYWxsaW5nIHRoZSBzdXBlciBtZXRob2QuXHJcbiAgICAgKi9cclxuICAgIExhYmVsLnByb3RvdHlwZS5vbkNsaWNrRXZlbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5sYWJlbEV2ZW50cy5vbkNsaWNrLmRpc3BhdGNoKHRoaXMpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogRmlyZXMgdGhlIHtAbGluayAjb25DbGlja30gZXZlbnQuXHJcbiAgICAgKiBDYW4gYmUgdXNlZCBieSBzdWJjbGFzc2VzIHRvIGxpc3RlbiB0byB0aGlzIGV2ZW50IHdpdGhvdXQgc3Vic2NyaWJpbmcgYW4gZXZlbnQgbGlzdGVuZXIgYnkgb3ZlcndyaXRpbmcgdGhlIG1ldGhvZFxyXG4gICAgICogYW5kIGNhbGxpbmcgdGhlIHN1cGVyIG1ldGhvZC5cclxuICAgICAqL1xyXG4gICAgTGFiZWwucHJvdG90eXBlLm9uVGV4dENoYW5nZWRFdmVudCA9IGZ1bmN0aW9uICh0ZXh0KSB7XHJcbiAgICAgICAgdGhpcy5sYWJlbEV2ZW50cy5vblRleHRDaGFuZ2VkLmRpc3BhdGNoKHRoaXMsIHRleHQpO1xyXG4gICAgfTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShMYWJlbC5wcm90b3R5cGUsIFwib25DbGlja1wiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogR2V0cyB0aGUgZXZlbnQgdGhhdCBpcyBmaXJlZCB3aGVuIHRoZSBsYWJlbCBpcyBjbGlja2VkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtFdmVudDxMYWJlbDxMYWJlbENvbmZpZz4sIE5vQXJncz59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxhYmVsRXZlbnRzLm9uQ2xpY2suZ2V0RXZlbnQoKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShMYWJlbC5wcm90b3R5cGUsIFwib25UZXh0Q2hhbmdlZFwiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogR2V0cyB0aGUgZXZlbnQgdGhhdCBpcyBmaXJlZCB3aGVuIHRoZSB0ZXh0IG9uIHRoZSBsYWJlbCBpcyBjaGFuZ2VkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtFdmVudDxMYWJlbDxMYWJlbENvbmZpZz4sIHN0cmluZz59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxhYmVsRXZlbnRzLm9uVGV4dENoYW5nZWQuZ2V0RXZlbnQoKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIHJldHVybiBMYWJlbDtcclxufShjb21wb25lbnRfMS5Db21wb25lbnQpKTtcclxuZXhwb3J0cy5MYWJlbCA9IExhYmVsO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvbGFiZWwudHNcbi8vIG1vZHVsZSBpZCA9IDdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBidXR0b25fMSA9IHJlcXVpcmUoXCIuL2J1dHRvblwiKTtcclxudmFyIGV2ZW50ZGlzcGF0Y2hlcl8xID0gcmVxdWlyZShcIi4uL2V2ZW50ZGlzcGF0Y2hlclwiKTtcclxuLyoqXHJcbiAqIEEgYnV0dG9uIHRoYXQgY2FuIGJlIHRvZ2dsZWQgYmV0d2VlbiAnb24nIGFuZCAnb2ZmJyBzdGF0ZXMuXHJcbiAqL1xyXG52YXIgVG9nZ2xlQnV0dG9uID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhUb2dnbGVCdXR0b24sIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBUb2dnbGVCdXR0b24oY29uZmlnKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLnRvZ2dsZUJ1dHRvbkV2ZW50cyA9IHtcclxuICAgICAgICAgICAgb25Ub2dnbGU6IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKSxcclxuICAgICAgICAgICAgb25Ub2dnbGVPbjogbmV3IGV2ZW50ZGlzcGF0Y2hlcl8xLkV2ZW50RGlzcGF0Y2hlcigpLFxyXG4gICAgICAgICAgICBvblRvZ2dsZU9mZjogbmV3IGV2ZW50ZGlzcGF0Y2hlcl8xLkV2ZW50RGlzcGF0Y2hlcigpLFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktdG9nZ2xlYnV0dG9uJyxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogVG9nZ2xlcyB0aGUgYnV0dG9uIHRvIHRoZSAnb24nIHN0YXRlLlxyXG4gICAgICovXHJcbiAgICBUb2dnbGVCdXR0b24ucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICh0aGlzLmlzT2ZmKCkpIHtcclxuICAgICAgICAgICAgdGhpcy5vblN0YXRlID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhpcy5nZXREb21FbGVtZW50KCkucmVtb3ZlQ2xhc3ModGhpcy5wcmVmaXhDc3MoVG9nZ2xlQnV0dG9uLkNMQVNTX09GRikpO1xyXG4gICAgICAgICAgICB0aGlzLmdldERvbUVsZW1lbnQoKS5hZGRDbGFzcyh0aGlzLnByZWZpeENzcyhUb2dnbGVCdXR0b24uQ0xBU1NfT04pKTtcclxuICAgICAgICAgICAgdGhpcy5vblRvZ2dsZUV2ZW50KCk7XHJcbiAgICAgICAgICAgIHRoaXMub25Ub2dnbGVPbkV2ZW50KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogVG9nZ2xlcyB0aGUgYnV0dG9uIHRvIHRoZSAnb2ZmJyBzdGF0ZS5cclxuICAgICAqL1xyXG4gICAgVG9nZ2xlQnV0dG9uLnByb3RvdHlwZS5vZmYgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNPbigpKSB7XHJcbiAgICAgICAgICAgIHRoaXMub25TdGF0ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLmdldERvbUVsZW1lbnQoKS5yZW1vdmVDbGFzcyh0aGlzLnByZWZpeENzcyhUb2dnbGVCdXR0b24uQ0xBU1NfT04pKTtcclxuICAgICAgICAgICAgdGhpcy5nZXREb21FbGVtZW50KCkuYWRkQ2xhc3ModGhpcy5wcmVmaXhDc3MoVG9nZ2xlQnV0dG9uLkNMQVNTX09GRikpO1xyXG4gICAgICAgICAgICB0aGlzLm9uVG9nZ2xlRXZlbnQoKTtcclxuICAgICAgICAgICAgdGhpcy5vblRvZ2dsZU9mZkV2ZW50KCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogVG9nZ2xlIHRoZSBidXR0b24gJ29uJyBpZiBpdCBpcyAnb2ZmJywgb3IgJ29mZicgaWYgaXQgaXMgJ29uJy5cclxuICAgICAqL1xyXG4gICAgVG9nZ2xlQnV0dG9uLnByb3RvdHlwZS50b2dnbGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNPbigpKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2ZmKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLm9uKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQ2hlY2tzIGlmIHRoZSB0b2dnbGUgYnV0dG9uIGlzIGluIHRoZSAnb24nIHN0YXRlLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWYgYnV0dG9uIGlzICdvbicsIGZhbHNlIGlmICdvZmYnXHJcbiAgICAgKi9cclxuICAgIFRvZ2dsZUJ1dHRvbi5wcm90b3R5cGUuaXNPbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5vblN0YXRlO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQ2hlY2tzIGlmIHRoZSB0b2dnbGUgYnV0dG9uIGlzIGluIHRoZSAnb2ZmJyBzdGF0ZS5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlIGlmIGJ1dHRvbiBpcyAnb2ZmJywgZmFsc2UgaWYgJ29uJ1xyXG4gICAgICovXHJcbiAgICBUb2dnbGVCdXR0b24ucHJvdG90eXBlLmlzT2ZmID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiAhdGhpcy5pc09uKCk7XHJcbiAgICB9O1xyXG4gICAgVG9nZ2xlQnV0dG9uLnByb3RvdHlwZS5vbkNsaWNrRXZlbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5vbkNsaWNrRXZlbnQuY2FsbCh0aGlzKTtcclxuICAgICAgICAvLyBGaXJlIHRoZSB0b2dnbGUgZXZlbnQgdG9nZXRoZXIgd2l0aCB0aGUgY2xpY2sgZXZlbnRcclxuICAgICAgICAvLyAodGhleSBhcmUgdGVjaG5pY2FsbHkgdGhlIHNhbWUsIG9ubHkgdGhlIHNlbWFudGljcyBhcmUgZGlmZmVyZW50KVxyXG4gICAgICAgIHRoaXMub25Ub2dnbGVFdmVudCgpO1xyXG4gICAgfTtcclxuICAgIFRvZ2dsZUJ1dHRvbi5wcm90b3R5cGUub25Ub2dnbGVFdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLnRvZ2dsZUJ1dHRvbkV2ZW50cy5vblRvZ2dsZS5kaXNwYXRjaCh0aGlzKTtcclxuICAgIH07XHJcbiAgICBUb2dnbGVCdXR0b24ucHJvdG90eXBlLm9uVG9nZ2xlT25FdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLnRvZ2dsZUJ1dHRvbkV2ZW50cy5vblRvZ2dsZU9uLmRpc3BhdGNoKHRoaXMpO1xyXG4gICAgfTtcclxuICAgIFRvZ2dsZUJ1dHRvbi5wcm90b3R5cGUub25Ub2dnbGVPZmZFdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLnRvZ2dsZUJ1dHRvbkV2ZW50cy5vblRvZ2dsZU9mZi5kaXNwYXRjaCh0aGlzKTtcclxuICAgIH07XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9nZ2xlQnV0dG9uLnByb3RvdHlwZSwgXCJvblRvZ2dsZVwiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogR2V0cyB0aGUgZXZlbnQgdGhhdCBpcyBmaXJlZCB3aGVuIHRoZSBidXR0b24gaXMgdG9nZ2xlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnQ8VG9nZ2xlQnV0dG9uPENvbmZpZz4sIE5vQXJncz59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnRvZ2dsZUJ1dHRvbkV2ZW50cy5vblRvZ2dsZS5nZXRFdmVudCgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvZ2dsZUJ1dHRvbi5wcm90b3R5cGUsIFwib25Ub2dnbGVPblwiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogR2V0cyB0aGUgZXZlbnQgdGhhdCBpcyBmaXJlZCB3aGVuIHRoZSBidXR0b24gaXMgdG9nZ2xlZCAnb24nLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtFdmVudDxUb2dnbGVCdXR0b248Q29uZmlnPiwgTm9BcmdzPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9nZ2xlQnV0dG9uRXZlbnRzLm9uVG9nZ2xlT24uZ2V0RXZlbnQoKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb2dnbGVCdXR0b24ucHJvdG90eXBlLCBcIm9uVG9nZ2xlT2ZmXCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXRzIHRoZSBldmVudCB0aGF0IGlzIGZpcmVkIHdoZW4gdGhlIGJ1dHRvbiBpcyB0b2dnbGVkICdvZmYnLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtFdmVudDxUb2dnbGVCdXR0b248Q29uZmlnPiwgTm9BcmdzPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9nZ2xlQnV0dG9uRXZlbnRzLm9uVG9nZ2xlT2ZmLmdldEV2ZW50KCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gVG9nZ2xlQnV0dG9uO1xyXG59KGJ1dHRvbl8xLkJ1dHRvbikpO1xyXG5Ub2dnbGVCdXR0b24uQ0xBU1NfT04gPSAnb24nO1xyXG5Ub2dnbGVCdXR0b24uQ0xBU1NfT0ZGID0gJ29mZic7XHJcbmV4cG9ydHMuVG9nZ2xlQnV0dG9uID0gVG9nZ2xlQnV0dG9uO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvdG9nZ2xlYnV0dG9uLnRzXG4vLyBtb2R1bGUgaWQgPSA4XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIm1vZHVsZS5leHBvcnRzID0gYW5ndWxhcjtcblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyBleHRlcm5hbCBcImFuZ3VsYXJcIlxuLy8gbW9kdWxlIGlkID0gOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG4vLyBUT0RPIGNoYW5nZSB0byBpbnRlcm5hbCAobm90IGV4cG9ydGVkKSBjbGFzcywgaG93IHRvIHVzZSBpbiBvdGhlciBmaWxlcz9cclxuLyoqXHJcbiAqIEV4ZWN1dGVzIGEgY2FsbGJhY2sgYWZ0ZXIgYSBzcGVjaWZpZWQgYW1vdW50IG9mIHRpbWUsIG9wdGlvbmFsbHkgcmVwZWF0ZWRseSB1bnRpbCBzdG9wcGVkLlxyXG4gKi9cclxudmFyIFRpbWVvdXQgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHRpbWVvdXQgY2FsbGJhY2sgaGFuZGxlci5cclxuICAgICAqIEBwYXJhbSBkZWxheSB0aGUgZGVsYXkgaW4gbWlsbGlzZWNvbmRzIGFmdGVyIHdoaWNoIHRoZSBjYWxsYmFjayBzaG91bGQgYmUgZXhlY3V0ZWRcclxuICAgICAqIEBwYXJhbSBjYWxsYmFjayB0aGUgY2FsbGJhY2sgdG8gZXhlY3V0ZSBhZnRlciB0aGUgZGVsYXkgdGltZVxyXG4gICAgICogQHBhcmFtIHJlcGVhdCBpZiB0cnVlLCBjYWxsIHRoZSBjYWxsYmFjayByZXBlYXRlZGx5IGluIGRlbGF5IGludGVydmFsc1xyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBUaW1lb3V0KGRlbGF5LCBjYWxsYmFjaywgcmVwZWF0KSB7XHJcbiAgICAgICAgaWYgKHJlcGVhdCA9PT0gdm9pZCAwKSB7IHJlcGVhdCA9IGZhbHNlOyB9XHJcbiAgICAgICAgdGhpcy5kZWxheSA9IGRlbGF5O1xyXG4gICAgICAgIHRoaXMuY2FsbGJhY2sgPSBjYWxsYmFjaztcclxuICAgICAgICB0aGlzLnJlcGVhdCA9IHJlcGVhdDtcclxuICAgICAgICB0aGlzLnRpbWVvdXRIYW5kbGUgPSAwO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBTdGFydHMgdGhlIHRpbWVvdXQgYW5kIGNhbGxzIHRoZSBjYWxsYmFjayB3aGVuIHRoZSB0aW1lb3V0IGRlbGF5IGhhcyBwYXNzZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7VGltZW91dH0gdGhlIGN1cnJlbnQgdGltZW91dCAoc28gdGhlIHN0YXJ0IGNhbGwgY2FuIGJlIGNoYWluZWQgdG8gdGhlIGNvbnN0cnVjdG9yKVxyXG4gICAgICovXHJcbiAgICBUaW1lb3V0LnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLnJlc2V0KCk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBDbGVhcnMgdGhlIHRpbWVvdXQuIFRoZSBjYWxsYmFjayB3aWxsIG5vdCBiZSBjYWxsZWQgaWYgY2xlYXIgaXMgY2FsbGVkIGR1cmluZyB0aGUgdGltZW91dC5cclxuICAgICAqL1xyXG4gICAgVGltZW91dC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZW91dEhhbmRsZSk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZXNldHMgdGhlIHBhc3NlZCB0aW1lb3V0IGRlbGF5IHRvIHplcm8uIENhbiBiZSB1c2VkIHRvIGRlZmVyIHRoZSBjYWxsaW5nIG9mIHRoZSBjYWxsYmFjay5cclxuICAgICAqL1xyXG4gICAgVGltZW91dC5wcm90b3R5cGUucmVzZXQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2YXIgbGFzdFNjaGVkdWxlVGltZSA9IDA7XHJcbiAgICAgICAgdmFyIGRlbGF5QWRqdXN0ID0gMDtcclxuICAgICAgICB0aGlzLmNsZWFyKCk7XHJcbiAgICAgICAgdmFyIGludGVybmFsQ2FsbGJhY2sgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLmNhbGxiYWNrKCk7XHJcbiAgICAgICAgICAgIGlmIChfdGhpcy5yZXBlYXQpIHtcclxuICAgICAgICAgICAgICAgIHZhciBub3cgPSBEYXRlLm5vdygpO1xyXG4gICAgICAgICAgICAgICAgLy8gVGhlIHRpbWUgb2Ygb25lIGl0ZXJhdGlvbiBmcm9tIHNjaGVkdWxpbmcgdG8gZXhlY3V0aW5nIHRoZSBjYWxsYmFjayAodXN1YWxseSBhIGJpdCBsb25nZXIgdGhhbiB0aGUgZGVsYXlcclxuICAgICAgICAgICAgICAgIC8vIHRpbWUpXHJcbiAgICAgICAgICAgICAgICB2YXIgZGVsdGEgPSBub3cgLSBsYXN0U2NoZWR1bGVUaW1lO1xyXG4gICAgICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBkZWxheSBhZGp1c3RtZW50IGZvciB0aGUgbmV4dCBzY2hlZHVsZSB0byBrZWVwIGEgc3RlYWR5IGRlbGF5IGludGVydmFsIG92ZXIgdGltZVxyXG4gICAgICAgICAgICAgICAgZGVsYXlBZGp1c3QgPSBfdGhpcy5kZWxheSAtIGRlbHRhICsgZGVsYXlBZGp1c3Q7XHJcbiAgICAgICAgICAgICAgICBsYXN0U2NoZWR1bGVUaW1lID0gbm93O1xyXG4gICAgICAgICAgICAgICAgLy8gU2NoZWR1bGUgbmV4dCBleGVjdXRpb24gYnkgdGhlIGFkanVzdGVkIGRlbGF5XHJcbiAgICAgICAgICAgICAgICBfdGhpcy50aW1lb3V0SGFuZGxlID0gd2luZG93LnNldFRpbWVvdXQoaW50ZXJuYWxDYWxsYmFjaywgX3RoaXMuZGVsYXkgKyBkZWxheUFkanVzdCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIGxhc3RTY2hlZHVsZVRpbWUgPSBEYXRlLm5vdygpO1xyXG4gICAgICAgIHRoaXMudGltZW91dEhhbmRsZSA9IHdpbmRvdy5zZXRUaW1lb3V0KGludGVybmFsQ2FsbGJhY2ssIHRoaXMuZGVsYXkpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBUaW1lb3V0O1xyXG59KCkpO1xyXG5leHBvcnRzLlRpbWVvdXQgPSBUaW1lb3V0O1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL3RpbWVvdXQudHNcbi8vIG1vZHVsZSBpZCA9IDEwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBCcm93c2VyVXRpbHM7XHJcbihmdW5jdGlvbiAoQnJvd3NlclV0aWxzKSB7XHJcbiAgICAvLyBpc01vYmlsZSBvbmx5IG5lZWRzIHRvIGJlIGV2YWx1YXRlZCBvbmNlIChpdCBjYW5ub3QgY2hhbmdlIGR1cmluZyBhIGJyb3dzZXIgc2Vzc2lvbilcclxuICAgIC8vIE1vYmlsZSBkZXRlY3Rpb24gYWNjb3JkaW5nIHRvIE1vemlsbGEgcmVjb21tZW5kYXRpb246IFwiSW4gc3VtbWFyeSwgd2UgcmVjb21tZW5kIGxvb2tpbmcgZm9yIHRoZSBzdHJpbmcg4oCcTW9iaeKAnVxyXG4gICAgLy8gYW55d2hlcmUgaW4gdGhlIFVzZXIgQWdlbnQgdG8gZGV0ZWN0IGEgbW9iaWxlIGRldmljZS5cIlxyXG4gICAgLy8gaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvSFRUUC9Ccm93c2VyX2RldGVjdGlvbl91c2luZ190aGVfdXNlcl9hZ2VudFxyXG4gICAgQnJvd3NlclV0aWxzLmlzTW9iaWxlID0gbmF2aWdhdG9yICYmIG5hdmlnYXRvci51c2VyQWdlbnQgJiYgL01vYmkvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XHJcbiAgICBCcm93c2VyVXRpbHMuaXNDaHJvbWUgPSBuYXZpZ2F0b3IgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudCAmJiAvQ2hyb21lLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xyXG4gICAgQnJvd3NlclV0aWxzLmlzQW5kcm9pZCA9IG5hdmlnYXRvciAmJiBuYXZpZ2F0b3IudXNlckFnZW50ICYmIC9BbmRyb2lkLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xyXG59KShCcm93c2VyVXRpbHMgPSBleHBvcnRzLkJyb3dzZXJVdGlscyB8fCAoZXhwb3J0cy5Ccm93c2VyVXRpbHMgPSB7fSkpO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2Jyb3dzZXJ1dGlscy50c1xuLy8gbW9kdWxlIGlkID0gMTFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciB0b2dnbGVidXR0b25fMSA9IHJlcXVpcmUoXCIuL3RvZ2dsZWJ1dHRvblwiKTtcclxudmFyIHBsYXllcnV0aWxzXzEgPSByZXF1aXJlKFwiLi4vcGxheWVydXRpbHNcIik7XHJcbi8qKlxyXG4gKiBBIGJ1dHRvbiB0aGF0IHRvZ2dsZXMgYmV0d2VlbiBwbGF5YmFjayBhbmQgcGF1c2UuXHJcbiAqL1xyXG52YXIgUGxheWJhY2tUb2dnbGVCdXR0b24gPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKFBsYXliYWNrVG9nZ2xlQnV0dG9uLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gUGxheWJhY2tUb2dnbGVCdXR0b24oY29uZmlnKSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLXBsYXliYWNrdG9nZ2xlYnV0dG9uJyxcclxuICAgICAgICAgICAgdGV4dDogJ1BsYXkvUGF1c2UnLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgUGxheWJhY2tUb2dnbGVCdXR0b24ucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlciwgaGFuZGxlQ2xpY2tFdmVudCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgaWYgKGhhbmRsZUNsaWNrRXZlbnQgPT09IHZvaWQgMCkgeyBoYW5kbGVDbGlja0V2ZW50ID0gdHJ1ZTsgfVxyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY29uZmlndXJlLmNhbGwodGhpcywgcGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIHZhciBpc1NlZWtpbmcgPSBmYWxzZTtcclxuICAgICAgICAvLyBIYW5kbGVyIHRvIHVwZGF0ZSBidXR0b24gc3RhdGUgYmFzZWQgb24gcGxheWVyIHN0YXRlXHJcbiAgICAgICAgdmFyIHBsYXliYWNrU3RhdGVIYW5kbGVyID0gZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgIC8vIElmIHRoZSBVSSBpcyBjdXJyZW50bHkgc2Vla2luZywgcGxheWJhY2sgaXMgdGVtcG9yYXJpbHkgc3RvcHBlZCBidXQgdGhlIGJ1dHRvbnMgc2hvdWxkXHJcbiAgICAgICAgICAgIC8vIG5vdCByZWZsZWN0IHRoYXQgYW5kIHN0YXkgYXMtaXMgKGUuZyBpbmRpY2F0ZSBwbGF5YmFjayB3aGlsZSBzZWVraW5nKS5cclxuICAgICAgICAgICAgaWYgKGlzU2Vla2luZykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChwbGF5ZXIuaXNQbGF5aW5nKCkpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLm9uKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5vZmYoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgLy8gQ2FsbCBoYW5kbGVyIHVwb24gdGhlc2UgZXZlbnRzXHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUExBWSwgcGxheWJhY2tTdGF0ZUhhbmRsZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BBVVNFRCwgcGxheWJhY2tTdGF0ZUhhbmRsZXIpO1xyXG4gICAgICAgIC8vIHdoZW4gcGxheWJhY2sgZmluaXNoZXMsIHBsYXllciB0dXJucyB0byBwYXVzZWQgbW9kZVxyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BMQVlCQUNLX0ZJTklTSEVELCBwbGF5YmFja1N0YXRlSGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fQ0FTVF9TVEFSVEVELCBwbGF5YmFja1N0YXRlSGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fQ0FTVF9QTEFZSU5HLCBwbGF5YmFja1N0YXRlSGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fQ0FTVF9QQVVTRUQsIHBsYXliYWNrU3RhdGVIYW5kbGVyKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9DQVNUX1BMQVlCQUNLX0ZJTklTSEVELCBwbGF5YmFja1N0YXRlSGFuZGxlcik7XHJcbiAgICAgICAgLy8gRGV0ZWN0IGFic2VuY2Ugb2YgdGltZXNoaWZ0aW5nIG9uIGxpdmUgc3RyZWFtcyBhbmQgYWRkIHRhZ2dpbmcgY2xhc3MgdG8gY29udmVydCBidXR0b24gaWNvbnMgdG8gcGxheS9zdG9wXHJcbiAgICAgICAgdmFyIHRpbWVTaGlmdERldGVjdG9yID0gbmV3IHBsYXllcnV0aWxzXzEuUGxheWVyVXRpbHMuVGltZVNoaWZ0QXZhaWxhYmlsaXR5RGV0ZWN0b3IocGxheWVyKTtcclxuICAgICAgICB0aW1lU2hpZnREZXRlY3Rvci5vblRpbWVTaGlmdEF2YWlsYWJpbGl0eUNoYW5nZWQuc3Vic2NyaWJlKGZ1bmN0aW9uIChzZW5kZXIsIGFyZ3MpIHtcclxuICAgICAgICAgICAgaWYgKCFhcmdzLnRpbWVTaGlmdEF2YWlsYWJsZSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZ2V0RG9tRWxlbWVudCgpLmFkZENsYXNzKF90aGlzLnByZWZpeENzcyhQbGF5YmFja1RvZ2dsZUJ1dHRvbi5DTEFTU19TVE9QVE9HR0xFKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5nZXREb21FbGVtZW50KCkucmVtb3ZlQ2xhc3MoX3RoaXMucHJlZml4Q3NzKFBsYXliYWNrVG9nZ2xlQnV0dG9uLkNMQVNTX1NUT1BUT0dHTEUpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRpbWVTaGlmdERldGVjdG9yLmRldGVjdCgpOyAvLyBJbml0aWFsIGRldGVjdGlvblxyXG4gICAgICAgIGlmIChoYW5kbGVDbGlja0V2ZW50KSB7XHJcbiAgICAgICAgICAgIC8vIENvbnRyb2wgcGxheWVyIGJ5IGJ1dHRvbiBldmVudHNcclxuICAgICAgICAgICAgLy8gV2hlbiBhIGJ1dHRvbiBldmVudCB0cmlnZ2VycyBhIHBsYXllciBBUEkgY2FsbCwgZXZlbnRzIGFyZSBmaXJlZCB3aGljaCBpbiB0dXJuIGNhbGwgdGhlIGV2ZW50IGhhbmRsZXJcclxuICAgICAgICAgICAgLy8gYWJvdmUgdGhhdCB1cGRhdGVkIHRoZSBidXR0b24gc3RhdGUuXHJcbiAgICAgICAgICAgIHRoaXMub25DbGljay5zdWJzY3JpYmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHBsYXllci5pc1BsYXlpbmcoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHBsYXllci5wYXVzZSgndWknKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHBsYXllci5wbGF5KCd1aScpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gVHJhY2sgVUkgc2Vla2luZyBzdGF0dXNcclxuICAgICAgICB1aW1hbmFnZXIub25TZWVrLnN1YnNjcmliZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlzU2Vla2luZyA9IHRydWU7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdWltYW5hZ2VyLm9uU2Vla2VkLnN1YnNjcmliZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlzU2Vla2luZyA9IGZhbHNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIFN0YXJ0dXAgaW5pdFxyXG4gICAgICAgIHBsYXliYWNrU3RhdGVIYW5kbGVyKG51bGwpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBQbGF5YmFja1RvZ2dsZUJ1dHRvbjtcclxufSh0b2dnbGVidXR0b25fMS5Ub2dnbGVCdXR0b24pKTtcclxuUGxheWJhY2tUb2dnbGVCdXR0b24uQ0xBU1NfU1RPUFRPR0dMRSA9ICdzdG9wdG9nZ2xlJztcclxuZXhwb3J0cy5QbGF5YmFja1RvZ2dsZUJ1dHRvbiA9IFBsYXliYWNrVG9nZ2xlQnV0dG9uO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvcGxheWJhY2t0b2dnbGVidXR0b24udHNcbi8vIG1vZHVsZSBpZCA9IDEyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRcIik7XHJcbnZhciBkb21fMSA9IHJlcXVpcmUoXCIuLi9kb21cIik7XHJcbnZhciBldmVudGRpc3BhdGNoZXJfMSA9IHJlcXVpcmUoXCIuLi9ldmVudGRpc3BhdGNoZXJcIik7XHJcbnZhciB0aW1lb3V0XzEgPSByZXF1aXJlKFwiLi4vdGltZW91dFwiKTtcclxudmFyIHBsYXllcnV0aWxzXzEgPSByZXF1aXJlKFwiLi4vcGxheWVydXRpbHNcIik7XHJcbi8qKlxyXG4gKiBBIHNlZWsgYmFyIHRvIHNlZWsgd2l0aGluIHRoZSBwbGF5ZXIncyBtZWRpYS4gSXQgZGlzcGxheXMgdGhlIGN1cnJlbnQgcGxheWJhY2sgcG9zaXRpb24sIGFtb3VudCBvZiBidWZmZWQgZGF0YSwgc2Vla1xyXG4gKiB0YXJnZXQsIGFuZCBrZWVwcyBzdGF0dXMgYWJvdXQgYW4gb25nb2luZyBzZWVrLlxyXG4gKlxyXG4gKiBUaGUgc2VlayBiYXIgZGlzcGxheXMgZGlmZmVyZW50ICdiYXJzJzpcclxuICogIC0gdGhlIHBsYXliYWNrIHBvc2l0aW9uLCBpLmUuIHRoZSBwb3NpdGlvbiBpbiB0aGUgbWVkaWEgYXQgd2hpY2ggdGhlIHBsYXllciBjdXJyZW50IHBsYXliYWNrIHBvaW50ZXIgaXMgcG9zaXRpb25lZFxyXG4gKiAgLSB0aGUgYnVmZmVyIHBvc2l0aW9uLCB3aGljaCB1c3VhbGx5IGlzIHRoZSBwbGF5YmFjayBwb3NpdGlvbiBwbHVzIHRoZSB0aW1lIHNwYW4gdGhhdCBpcyBhbHJlYWR5IGJ1ZmZlcmVkIGFoZWFkXHJcbiAqICAtIHRoZSBzZWVrIHBvc2l0aW9uLCB1c2VkIHRvIHByZXZpZXcgdG8gd2hlcmUgaW4gdGhlIHRpbWVsaW5lIGEgc2VlayB3aWxsIGp1bXAgdG9cclxuICovXHJcbnZhciBTZWVrQmFyID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhTZWVrQmFyLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gU2Vla0Jhcihjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQnVmZmVyIG9mIHRoZSB0aGUgY3VycmVudCBwbGF5YmFjayBwb3NpdGlvbi4gVGhlIHBvc2l0aW9uIG11c3QgYmUgYnVmZmVyZWQgaW4gY2FzZSB0aGUgZWxlbWVudFxyXG4gICAgICAgICAqIG5lZWRzIHRvIGJlIHJlZnJlc2hlZCB3aXRoIHtAbGluayAjcmVmcmVzaFBsYXliYWNrUG9zaXRpb259LlxyXG4gICAgICAgICAqIEB0eXBlIHtudW1iZXJ9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgX3RoaXMucGxheWJhY2tQb3NpdGlvblBlcmNlbnRhZ2UgPSAwO1xyXG4gICAgICAgIC8vIGh0dHBzOi8vaGFja3MubW96aWxsYS5vcmcvMjAxMy8wNC9kZXRlY3RpbmctdG91Y2gtaXRzLXRoZS13aHktbm90LXRoZS1ob3cvXHJcbiAgICAgICAgX3RoaXMudG91Y2hTdXBwb3J0ZWQgPSAoJ29udG91Y2hzdGFydCcgaW4gd2luZG93KTtcclxuICAgICAgICBfdGhpcy5zZWVrQmFyRXZlbnRzID0ge1xyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogRmlyZWQgd2hlbiBhIHNjcnViYmluZyBzZWVrIG9wZXJhdGlvbiBpcyBzdGFydGVkLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgb25TZWVrOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBGaXJlZCBkdXJpbmcgYSBzY3J1YmJpbmcgc2VlayB0byBpbmRpY2F0ZSB0aGF0IHRoZSBzZWVrIHByZXZpZXcgKGkuZS4gdGhlIHZpZGVvIGZyYW1lKSBzaG91bGQgYmUgdXBkYXRlZC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIG9uU2Vla1ByZXZpZXc6IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKSxcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEZpcmVkIHdoZW4gYSBzY3J1YmJpbmcgc2VlayBoYXMgZmluaXNoZWQgb3Igd2hlbiBhIGRpcmVjdCBzZWVrIGlzIGlzc3VlZC5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIG9uU2Vla2VkOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgfTtcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1zZWVrYmFyJyxcclxuICAgICAgICAgICAgdmVydGljYWw6IGZhbHNlLFxyXG4gICAgICAgICAgICBzbW9vdGhQbGF5YmFja1Bvc2l0aW9uVXBkYXRlSW50ZXJ2YWxNczogNTAsXHJcbiAgICAgICAgICAgIGhpZGVJbkxpdmVQbGF5YmFjazogdHJ1ZSxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIF90aGlzLmxhYmVsID0gX3RoaXMuY29uZmlnLmxhYmVsO1xyXG4gICAgICAgIF90aGlzLnRpbWVsaW5lTWFya2VycyA9IFtdO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIFNlZWtCYXIucHJvdG90eXBlLmluaXRpYWxpemUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5pbml0aWFsaXplLmNhbGwodGhpcyk7XHJcbiAgICAgICAgaWYgKHRoaXMuaGFzTGFiZWwoKSkge1xyXG4gICAgICAgICAgICB0aGlzLmdldExhYmVsKCkuaW5pdGlhbGl6ZSgpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBTZWVrQmFyLnByb3RvdHlwZS5jb25maWd1cmUgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIsIGNvbmZpZ3VyZVNlZWspIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIGlmIChjb25maWd1cmVTZWVrID09PSB2b2lkIDApIHsgY29uZmlndXJlU2VlayA9IHRydWU7IH1cclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNvbmZpZ3VyZS5jYWxsKHRoaXMsIHBsYXllciwgdWltYW5hZ2VyKTtcclxuICAgICAgICAvLyBsZXQgY29uZmlnID0gPFNlZWtCYXJDb25maWc+dGhpcy5nZXRDb25maWcoKTtcclxuICAgICAgICBpZiAoIWNvbmZpZ3VyZVNlZWspIHtcclxuICAgICAgICAgICAgLy8gVGhlIGNvbmZpZ3VyZVNlZWsgZmxhZyBjYW4gYmUgdXNlZCBieSBzdWJjbGFzc2VzIHRvIGRpc2FibGUgY29uZmlndXJhdGlvbiBhcyBzZWVrIGJhci4gRS5nLiB0aGUgdm9sdW1lXHJcbiAgICAgICAgICAgIC8vIHNsaWRlciBpcyByZXVzaW5nIHRoaXMgY29tcG9uZW50IGJ1dCBhZGRzIGl0cyBvd24gZnVuY3Rpb25hbGl0eSwgYW5kIGRvZXMgbm90IG5lZWQgdGhlIHNlZWsgZnVuY3Rpb25hbGl0eS5cclxuICAgICAgICAgICAgLy8gVGhpcyBpcyBhY3R1YWxseSBhIGhhY2ssIHRoZSBwcm9wZXIgc29sdXRpb24gd291bGQgYmUgZm9yIGJvdGggc2VlayBiYXIgYW5kIHZvbHVtZSBzbGlkZXJzIHRvIGV4dGVuZFxyXG4gICAgICAgICAgICAvLyBhIGNvbW1vbiBiYXNlIHNsaWRlciBjb21wb25lbnQgYW5kIGltcGxlbWVudCB0aGVpciBmdW5jdGlvbmFsaXR5IHRoZXJlLlxyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBwbGF5YmFja05vdEluaXRpYWxpemVkID0gdHJ1ZTtcclxuICAgICAgICB2YXIgaXNQbGF5aW5nID0gZmFsc2U7XHJcbiAgICAgICAgdmFyIGlzU2Vla2luZyA9IGZhbHNlO1xyXG4gICAgICAgIC8vIFVwZGF0ZSBwbGF5YmFjayBhbmQgYnVmZmVyIHBvc2l0aW9uc1xyXG4gICAgICAgIHZhciBwbGF5YmFja1Bvc2l0aW9uSGFuZGxlciA9IGZ1bmN0aW9uIChldmVudCwgZm9yY2VVcGRhdGUpIHtcclxuICAgICAgICAgICAgaWYgKGV2ZW50ID09PSB2b2lkIDApIHsgZXZlbnQgPSBudWxsOyB9XHJcbiAgICAgICAgICAgIGlmIChmb3JjZVVwZGF0ZSA9PT0gdm9pZCAwKSB7IGZvcmNlVXBkYXRlID0gZmFsc2U7IH1cclxuICAgICAgICAgICAgLy8gT25jZSB0aGlzIGhhbmRsZXIgb3MgY2FsbGVkLCBwbGF5YmFjayBoYXMgYmVlbiBzdGFydGVkIGFuZCB3ZSBzZXQgdGhlIGZsYWcgdG8gZmFsc2VcclxuICAgICAgICAgICAgcGxheWJhY2tOb3RJbml0aWFsaXplZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICBpZiAoaXNTZWVraW5nKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBXZSBjYXVnaHQgYSBzZWVrIHByZXZpZXcgc2VlaywgZG8gbm90IHVwZGF0ZSB0aGUgc2Vla2JhclxyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChwbGF5ZXIuaXNMaXZlKCkpIHtcclxuICAgICAgICAgICAgICAgIGlmIChwbGF5ZXIuZ2V0TWF4VGltZVNoaWZ0KCkgPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBUaGlzIGNhc2UgbXVzdCBiZSBleHBsaWNpdGx5IGhhbmRsZWQgdG8gYXZvaWQgZGl2aXNpb24gYnkgemVyb1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFBsYXliYWNrUG9zaXRpb24oMTAwKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBwbGF5YmFja1Bvc2l0aW9uUGVyY2VudGFnZSA9IDEwMCAtICgxMDAgLyBwbGF5ZXIuZ2V0TWF4VGltZVNoaWZ0KCkgKiBwbGF5ZXIuZ2V0VGltZVNoaWZ0KCkpO1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFBsYXliYWNrUG9zaXRpb24ocGxheWJhY2tQb3NpdGlvblBlcmNlbnRhZ2UpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgLy8gQWx3YXlzIHNob3cgZnVsbCBidWZmZXIgZm9yIGxpdmUgc3RyZWFtc1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0QnVmZmVyUG9zaXRpb24oMTAwKTtcclxuICAgICAgICAgICAgICAgIC8vIEhpZGUgU2Vla0JhciBpZiByZXF1aXJlZC5cclxuICAgICAgICAgICAgICAgIC8vIGlmIChjb25maWcuaGlkZUluTGl2ZVBsYXliYWNrKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5oaWRlKCk7XHJcbiAgICAgICAgICAgICAgICAvLyB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgcGxheWJhY2tQb3NpdGlvblBlcmNlbnRhZ2UgPSAxMDAgLyBwbGF5ZXIuZ2V0RHVyYXRpb24oKSAqIHBsYXllci5nZXRDdXJyZW50VGltZSgpO1xyXG4gICAgICAgICAgICAgICAgdmFyIHZpZGVvQnVmZmVyTGVuZ3RoID0gcGxheWVyLmdldFZpZGVvQnVmZmVyTGVuZ3RoKCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgYXVkaW9CdWZmZXJMZW5ndGggPSBwbGF5ZXIuZ2V0QXVkaW9CdWZmZXJMZW5ndGgoKTtcclxuICAgICAgICAgICAgICAgIC8vIENhbGN1bGF0ZSB0aGUgYnVmZmVyIGxlbmd0aCB3aGljaCBpcyB0aGUgc21hbGxlciBsZW5ndGggb2YgdGhlIGF1ZGlvIGFuZCB2aWRlbyBidWZmZXJzLiBJZiBvbmUgb2YgdGhlc2VcclxuICAgICAgICAgICAgICAgIC8vIGJ1ZmZlcnMgaXMgbm90IGF2YWlsYWJsZSwgd2Ugc2V0IGl0J3MgdmFsdWUgdG8gTUFYX1ZBTFVFIHRvIG1ha2Ugc3VyZSB0aGF0IHRoZSBvdGhlciByZWFsIHZhbHVlIGlzIHRha2VuXHJcbiAgICAgICAgICAgICAgICAvLyBhcyB0aGUgYnVmZmVyIGxlbmd0aC5cclxuICAgICAgICAgICAgICAgIHZhciBidWZmZXJMZW5ndGggPSBNYXRoLm1pbih2aWRlb0J1ZmZlckxlbmd0aCAhPSBudWxsID8gdmlkZW9CdWZmZXJMZW5ndGggOiBOdW1iZXIuTUFYX1ZBTFVFLCBhdWRpb0J1ZmZlckxlbmd0aCAhPSBudWxsID8gYXVkaW9CdWZmZXJMZW5ndGggOiBOdW1iZXIuTUFYX1ZBTFVFKTtcclxuICAgICAgICAgICAgICAgIC8vIElmIGJvdGggYnVmZmVyIGxlbmd0aHMgYXJlIG1pc3NpbmcsIHdlIHNldCB0aGUgYnVmZmVyIGxlbmd0aCB0byB6ZXJvXHJcbiAgICAgICAgICAgICAgICBpZiAoYnVmZmVyTGVuZ3RoID09PSBOdW1iZXIuTUFYX1ZBTFVFKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYnVmZmVyTGVuZ3RoID0gMDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHZhciBidWZmZXJQZXJjZW50YWdlID0gMTAwIC8gcGxheWVyLmdldER1cmF0aW9uKCkgKiBidWZmZXJMZW5ndGg7XHJcbiAgICAgICAgICAgICAgICAvLyBVcGRhdGUgcGxheWJhY2sgcG9zaXRpb24gb25seSBpbiBwYXVzZWQgc3RhdGUgb3IgaW4gdGhlIGluaXRpYWwgc3RhcnR1cCBzdGF0ZSB3aGVyZSBwbGF5ZXIgaXMgbmVpdGhlclxyXG4gICAgICAgICAgICAgICAgLy8gcGF1c2VkIG5vciBwbGF5aW5nLiBQbGF5YmFjayB1cGRhdGVzIGFyZSBoYW5kbGVkIGluIHRoZSBUaW1lb3V0IGJlbG93LlxyXG4gICAgICAgICAgICAgICAgaWYgKF90aGlzLmNvbmZpZy5zbW9vdGhQbGF5YmFja1Bvc2l0aW9uVXBkYXRlSW50ZXJ2YWxNcyA9PT0gU2Vla0Jhci5TTU9PVEhfUExBWUJBQ0tfUE9TSVRJT05fVVBEQVRFX0RJU0FCTEVEXHJcbiAgICAgICAgICAgICAgICAgICAgfHwgZm9yY2VVcGRhdGUgfHwgcGxheWVyLmlzUGF1c2VkKCkgfHwgKHBsYXllci5pc1BhdXNlZCgpID09PSBwbGF5ZXIuaXNQbGF5aW5nKCkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0UGxheWJhY2tQb3NpdGlvbihwbGF5YmFja1Bvc2l0aW9uUGVyY2VudGFnZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRCdWZmZXJQb3NpdGlvbihwbGF5YmFja1Bvc2l0aW9uUGVyY2VudGFnZSArIGJ1ZmZlclBlcmNlbnRhZ2UpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvLyBVcGRhdGUgc2Vla2JhciB1cG9uIHRoZXNlIGV2ZW50c1xyXG4gICAgICAgIC8vIGluaXQgcGxheWJhY2sgcG9zaXRpb24gd2hlbiB0aGUgcGxheWVyIGlzIHJlYWR5XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUkVBRFksIHBsYXliYWNrUG9zaXRpb25IYW5kbGVyKTtcclxuICAgICAgICAvLyB1cGRhdGUgcGxheWJhY2sgcG9zaXRpb24gd2hlbiBpdCBjaGFuZ2VzXHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fVElNRV9DSEFOR0VELCBwbGF5YmFja1Bvc2l0aW9uSGFuZGxlcik7XHJcbiAgICAgICAgLy8gdXBkYXRlIGJ1ZmZlcmxldmVsIHdoZW4gYnVmZmVyaW5nIGlzIGNvbXBsZXRlXHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fU1RBTExfRU5ERUQsIHBsYXliYWNrUG9zaXRpb25IYW5kbGVyKTtcclxuICAgICAgICAvLyB1cGRhdGUgcGxheWJhY2sgcG9zaXRpb24gd2hlbiBhIHNlZWsgaGFzIGZpbmlzaGVkXHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fU0VFS0VELCBwbGF5YmFja1Bvc2l0aW9uSGFuZGxlcik7XHJcbiAgICAgICAgLy8gdXBkYXRlIHBsYXliYWNrIHBvc2l0aW9uIHdoZW4gYSB0aW1lc2hpZnQgaGFzIGZpbmlzaGVkXHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fVElNRV9TSElGVEVELCBwbGF5YmFja1Bvc2l0aW9uSGFuZGxlcik7XHJcbiAgICAgICAgLy8gdXBkYXRlIGJ1ZmZlcmxldmVsIHdoZW4gYSBzZWdtZW50IGhhcyBiZWVuIGRvd25sb2FkZWRcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TRUdNRU5UX1JFUVVFU1RfRklOSVNIRUQsIHBsYXliYWNrUG9zaXRpb25IYW5kbGVyKTtcclxuICAgICAgICAvLyB1cGRhdGUgcGxheWJhY2sgcG9zaXRpb24gb2YgQ2FzdCBwbGF5YmFja1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0NBU1RfVElNRV9VUERBVEVELCBwbGF5YmFja1Bvc2l0aW9uSGFuZGxlcik7XHJcbiAgICAgICAgLy8gU2VlayBoYW5kbGluZ1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1NFRUssIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMuc2V0U2Vla2luZyh0cnVlKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TRUVLRUQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMuc2V0U2Vla2luZyhmYWxzZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fVElNRV9TSElGVCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5zZXRTZWVraW5nKHRydWUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1RJTUVfU0hJRlRFRCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5zZXRTZWVraW5nKGZhbHNlKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB2YXIgc2VlayA9IGZ1bmN0aW9uIChwZXJjZW50YWdlKSB7XHJcbiAgICAgICAgICAgIGlmIChwbGF5ZXIuaXNMaXZlKCkpIHtcclxuICAgICAgICAgICAgICAgIHBsYXllci50aW1lU2hpZnQocGxheWVyLmdldE1heFRpbWVTaGlmdCgpIC0gKHBsYXllci5nZXRNYXhUaW1lU2hpZnQoKSAqIChwZXJjZW50YWdlIC8gMTAwKSksICd1aScpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcGxheWVyLnNlZWsocGxheWVyLmdldER1cmF0aW9uKCkgKiAocGVyY2VudGFnZSAvIDEwMCksICd1aScpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICB0aGlzLm9uU2Vlay5zdWJzY3JpYmUoZnVuY3Rpb24gKHNlbmRlcikge1xyXG4gICAgICAgICAgICBpc1NlZWtpbmcgPSB0cnVlOyAvLyB0cmFjayBzZWVraW5nIHN0YXR1cyBzbyB3ZSBjYW4gY2F0Y2ggZXZlbnRzIGZyb20gc2VlayBwcmV2aWV3IHNlZWtzXHJcbiAgICAgICAgICAgIC8vIE5vdGlmeSBVSSBtYW5hZ2VyIG9mIHN0YXJ0ZWQgc2Vla1xyXG4gICAgICAgICAgICB1aW1hbmFnZXIub25TZWVrLmRpc3BhdGNoKHNlbmRlcik7XHJcbiAgICAgICAgICAgIC8vIFNhdmUgY3VycmVudCBwbGF5YmFjayBzdGF0ZVxyXG4gICAgICAgICAgICBpc1BsYXlpbmcgPSBwbGF5ZXIuaXNQbGF5aW5nKCk7XHJcbiAgICAgICAgICAgIC8vIFBhdXNlIHBsYXliYWNrIHdoaWxlIHNlZWtpbmdcclxuICAgICAgICAgICAgaWYgKGlzUGxheWluZykge1xyXG4gICAgICAgICAgICAgICAgcGxheWVyLnBhdXNlKCd1aScpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5vblNlZWtQcmV2aWV3LnN1YnNjcmliZShmdW5jdGlvbiAoc2VuZGVyLCBhcmdzKSB7XHJcbiAgICAgICAgICAgIC8vIE5vdGlmeSBVSSBtYW5hZ2VyIG9mIHNlZWsgcHJldmlld1xyXG4gICAgICAgICAgICB1aW1hbmFnZXIub25TZWVrUHJldmlldy5kaXNwYXRjaChzZW5kZXIsIGFyZ3MpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMub25TZWVrUHJldmlldy5zdWJzY3JpYmVSYXRlTGltaXRlZChmdW5jdGlvbiAoc2VuZGVyLCBhcmdzKSB7XHJcbiAgICAgICAgICAgIC8vIFJhdGUtbGltaXRlZCBzY3J1YmJpbmcgc2Vla1xyXG4gICAgICAgICAgICBpZiAoYXJncy5zY3J1YmJpbmcpIHtcclxuICAgICAgICAgICAgICAgIHNlZWsoYXJncy5wb3NpdGlvbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LCAyMDApO1xyXG4gICAgICAgIHRoaXMub25TZWVrZWQuc3Vic2NyaWJlKGZ1bmN0aW9uIChzZW5kZXIsIHBlcmNlbnRhZ2UpIHtcclxuICAgICAgICAgICAgaXNTZWVraW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgIC8vIERvIHRoZSBzZWVrXHJcbiAgICAgICAgICAgIHNlZWsocGVyY2VudGFnZSk7XHJcbiAgICAgICAgICAgIC8vIENvbnRpbnVlIHBsYXliYWNrIGFmdGVyIHNlZWsgaWYgcGxheWVyIHdhcyBwbGF5aW5nIHdoZW4gc2VlayBzdGFydGVkXHJcbiAgICAgICAgICAgIGlmIChpc1BsYXlpbmcpIHtcclxuICAgICAgICAgICAgICAgIHBsYXllci5wbGF5KCd1aScpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIE5vdGlmeSBVSSBtYW5hZ2VyIG9mIGZpbmlzaGVkIHNlZWtcclxuICAgICAgICAgICAgdWltYW5hZ2VyLm9uU2Vla2VkLmRpc3BhdGNoKHNlbmRlcik7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgaWYgKHRoaXMuaGFzTGFiZWwoKSkge1xyXG4gICAgICAgICAgICAvLyBDb25maWd1cmUgYSBzZWVrYmFyIGxhYmVsIHRoYXQgaXMgaW50ZXJuYWwgdG8gdGhlIHNlZWtiYXIpXHJcbiAgICAgICAgICAgIHRoaXMuZ2V0TGFiZWwoKS5jb25maWd1cmUocGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBIaWRlIHNlZWtiYXIgZm9yIGxpdmUgc291cmNlcyB3aXRob3V0IHRpbWVzaGlmdFxyXG4gICAgICAgIHZhciBpc0xpdmUgPSBmYWxzZTtcclxuICAgICAgICB2YXIgaGFzVGltZVNoaWZ0ID0gZmFsc2U7XHJcbiAgICAgICAgdmFyIHN3aXRjaFZpc2liaWxpdHkgPSBmdW5jdGlvbiAoaXNMaXZlLCBoYXNUaW1lU2hpZnQpIHtcclxuICAgICAgICAgICAgaWYgKGlzTGl2ZSAmJiAhaGFzVGltZVNoaWZ0KSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5oaWRlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5zaG93KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcGxheWJhY2tQb3NpdGlvbkhhbmRsZXIobnVsbCwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIF90aGlzLnJlZnJlc2hQbGF5YmFja1Bvc2l0aW9uKCk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICB2YXIgbGl2ZVN0cmVhbURldGVjdG9yID0gbmV3IHBsYXllcnV0aWxzXzEuUGxheWVyVXRpbHMuTGl2ZVN0cmVhbURldGVjdG9yKHBsYXllcik7XHJcbiAgICAgICAgbGl2ZVN0cmVhbURldGVjdG9yLm9uTGl2ZUNoYW5nZWQuc3Vic2NyaWJlKGZ1bmN0aW9uIChzZW5kZXIsIGFyZ3MpIHtcclxuICAgICAgICAgICAgaXNMaXZlID0gYXJncy5saXZlO1xyXG4gICAgICAgICAgICBzd2l0Y2hWaXNpYmlsaXR5KGlzTGl2ZSwgaGFzVGltZVNoaWZ0KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB2YXIgdGltZVNoaWZ0RGV0ZWN0b3IgPSBuZXcgcGxheWVydXRpbHNfMS5QbGF5ZXJVdGlscy5UaW1lU2hpZnRBdmFpbGFiaWxpdHlEZXRlY3RvcihwbGF5ZXIpO1xyXG4gICAgICAgIHRpbWVTaGlmdERldGVjdG9yLm9uVGltZVNoaWZ0QXZhaWxhYmlsaXR5Q2hhbmdlZC5zdWJzY3JpYmUoZnVuY3Rpb24gKHNlbmRlciwgYXJncykge1xyXG4gICAgICAgICAgICBoYXNUaW1lU2hpZnQgPSBhcmdzLnRpbWVTaGlmdEF2YWlsYWJsZTtcclxuICAgICAgICAgICAgc3dpdGNoVmlzaWJpbGl0eShpc0xpdmUsIGhhc1RpbWVTaGlmdCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gSW5pdGlhbCBkZXRlY3Rpb25cclxuICAgICAgICBsaXZlU3RyZWFtRGV0ZWN0b3IuZGV0ZWN0KCk7XHJcbiAgICAgICAgdGltZVNoaWZ0RGV0ZWN0b3IuZGV0ZWN0KCk7XHJcbiAgICAgICAgLy8gUmVmcmVzaCB0aGUgcGxheWJhY2sgcG9zaXRpb24gd2hlbiB0aGUgcGxheWVyIHJlc2l6ZWQgb3IgdGhlIFVJIGlzIGNvbmZpZ3VyZWQuIFRoZSBwbGF5YmFjayBwb3NpdGlvbiBtYXJrZXJcclxuICAgICAgICAvLyBpcyBwb3NpdGlvbmVkIGFic29sdXRlbHkgYW5kIG11c3QgdGhlcmVmb3JlIGJlIHVwZGF0ZWQgd2hlbiB0aGUgc2l6ZSBvZiB0aGUgc2Vla2JhciBjaGFuZ2VzLlxyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BMQVlFUl9SRVNJWkUsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMucmVmcmVzaFBsYXliYWNrUG9zaXRpb24oKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBBZGRpdGlvbmFsbHksIHdoZW4gdGhpcyBjb2RlIGlzIGNhbGxlZCwgdGhlIHNlZWtiYXIgaXMgbm90IHBhcnQgb2YgdGhlIFVJIHlldCBhbmQgdGhlcmVmb3JlIGRvZXMgbm90IGhhdmUgYSBzaXplLFxyXG4gICAgICAgIC8vIHJlc3VsdGluZyBpbiBhIHdyb25nIGluaXRpYWwgcG9zaXRpb24gb2YgdGhlIG1hcmtlci4gUmVmcmVzaGluZyBpdCBvbmNlIHRoZSBVSSBpcyBjb25maWd1cmVkIHNvbHZlZCB0aGlzIGlzc3VlLlxyXG4gICAgICAgIHVpbWFuYWdlci5vbkNvbmZpZ3VyZWQuc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMucmVmcmVzaFBsYXliYWNrUG9zaXRpb24oKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBJdCBjYW4gYWxzbyBoYXBwZW4gdGhhdCB0aGUgdmFsdWUgY2hhbmdlcyBvbmNlIHRoZSBwbGF5ZXIgaXMgcmVhZHksIG9yIHdoZW4gYSBuZXcgc291cmNlIGlzIGxvYWRlZCwgc28gd2UgbmVlZFxyXG4gICAgICAgIC8vIHRvIHVwZGF0ZSBvbiBPTl9SRUFEWSB0b29cclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9SRUFEWSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5yZWZyZXNoUGxheWJhY2tQb3NpdGlvbigpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIEluaXRpYWxpemUgc2Vla2JhclxyXG4gICAgICAgIHBsYXliYWNrUG9zaXRpb25IYW5kbGVyKCk7IC8vIFNldCB0aGUgcGxheWJhY2sgcG9zaXRpb25cclxuICAgICAgICB0aGlzLnNldEJ1ZmZlclBvc2l0aW9uKDApO1xyXG4gICAgICAgIHRoaXMuc2V0U2Vla1Bvc2l0aW9uKDApO1xyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy5zbW9vdGhQbGF5YmFja1Bvc2l0aW9uVXBkYXRlSW50ZXJ2YWxNcyAhPT0gU2Vla0Jhci5TTU9PVEhfUExBWUJBQ0tfUE9TSVRJT05fVVBEQVRFX0RJU0FCTEVEKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29uZmlndXJlU21vb3RoUGxheWJhY2tQb3NpdGlvblVwZGF0ZXIocGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmNvbmZpZ3VyZU1hcmtlcnMocGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgfTtcclxuICAgIFNlZWtCYXIucHJvdG90eXBlLmNvbmZpZ3VyZVNtb290aFBsYXliYWNrUG9zaXRpb25VcGRhdGVyID0gZnVuY3Rpb24gKHBsYXllciwgdWltYW5hZ2VyKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICAvKlxyXG4gICAgICAgICAqIFBsYXliYWNrIHBvc2l0aW9uIHVwZGF0ZVxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogV2UgZG8gbm90IHVwZGF0ZSB0aGUgcG9zaXRpb24gZGlyZWN0bHkgZnJvbSB0aGUgT05fVElNRV9DSEFOR0VEIGV2ZW50LCBiZWNhdXNlIGl0IGFycml2ZXMgdmVyeSBqaXR0ZXJ5IGFuZFxyXG4gICAgICAgICAqIHJlc3VsdHMgaW4gYSBqaXR0ZXJ5IHBvc2l0aW9uIGluZGljYXRvciBzaW5jZSB0aGUgQ1NTIHRyYW5zaXRpb24gdGltZSBpcyBzdGF0aWNhbGx5IHNldC5cclxuICAgICAgICAgKiBUbyB3b3JrIGFyb3VuZCB0aGlzIGlzc3VlLCB3ZSBtYWludGFpbiBhIGxvY2FsIHBsYXliYWNrIHBvc2l0aW9uIHRoYXQgaXMgdXBkYXRlZCBpbiBhIHN0YWJsZSByZWd1bGFyIGludGVydmFsXHJcbiAgICAgICAgICogYW5kIGtlcHQgaW4gc3luYyB3aXRoIHRoZSBwbGF5ZXIuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdmFyIGN1cnJlbnRUaW1lU2Vla0JhciA9IDA7XHJcbiAgICAgICAgdmFyIGN1cnJlbnRUaW1lUGxheWVyID0gMDtcclxuICAgICAgICB2YXIgdXBkYXRlSW50ZXJ2YWxNcyA9IDUwO1xyXG4gICAgICAgIHZhciBjdXJyZW50VGltZVVwZGF0ZURlbHRhU2VjcyA9IHVwZGF0ZUludGVydmFsTXMgLyAxMDAwO1xyXG4gICAgICAgIHRoaXMuc21vb3RoUGxheWJhY2tQb3NpdGlvblVwZGF0ZXIgPSBuZXcgdGltZW91dF8xLlRpbWVvdXQodXBkYXRlSW50ZXJ2YWxNcywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjdXJyZW50VGltZVNlZWtCYXIgKz0gY3VycmVudFRpbWVVcGRhdGVEZWx0YVNlY3M7XHJcbiAgICAgICAgICAgIGN1cnJlbnRUaW1lUGxheWVyID0gcGxheWVyLmdldEN1cnJlbnRUaW1lKCk7XHJcbiAgICAgICAgICAgIC8vIFN5bmMgY3VycmVudFRpbWUgb2Ygc2Vla2JhciB0byBwbGF5ZXJcclxuICAgICAgICAgICAgdmFyIGN1cnJlbnRUaW1lRGVsdGEgPSBjdXJyZW50VGltZVNlZWtCYXIgLSBjdXJyZW50VGltZVBsYXllcjtcclxuICAgICAgICAgICAgLy8gSWYgdGhlIGRlbHRhIGlzIGxhcmdlciB0aGF0IDIgc2VjcywgZGlyZWN0bHkganVtcCB0aGUgc2Vla2JhciB0byB0aGVcclxuICAgICAgICAgICAgLy8gcGxheWVyIHRpbWUgaW5zdGVhZCBvZiBzbW9vdGhseSBmYXN0IGZvcndhcmRpbmcvcmV3aW5kaW5nLlxyXG4gICAgICAgICAgICBpZiAoTWF0aC5hYnMoY3VycmVudFRpbWVEZWx0YSkgPiAyKSB7XHJcbiAgICAgICAgICAgICAgICBjdXJyZW50VGltZVNlZWtCYXIgPSBjdXJyZW50VGltZVBsYXllcjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChjdXJyZW50VGltZURlbHRhIDw9IC1jdXJyZW50VGltZVVwZGF0ZURlbHRhU2Vjcykge1xyXG4gICAgICAgICAgICAgICAgY3VycmVudFRpbWVTZWVrQmFyICs9IGN1cnJlbnRUaW1lVXBkYXRlRGVsdGFTZWNzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJlbnRUaW1lRGVsdGEgPj0gY3VycmVudFRpbWVVcGRhdGVEZWx0YVNlY3MpIHtcclxuICAgICAgICAgICAgICAgIGN1cnJlbnRUaW1lU2Vla0JhciAtPSBjdXJyZW50VGltZVVwZGF0ZURlbHRhU2VjcztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgcGxheWJhY2tQb3NpdGlvblBlcmNlbnRhZ2UgPSAxMDAgLyBwbGF5ZXIuZ2V0RHVyYXRpb24oKSAqIGN1cnJlbnRUaW1lU2Vla0JhcjtcclxuICAgICAgICAgICAgX3RoaXMuc2V0UGxheWJhY2tQb3NpdGlvbihwbGF5YmFja1Bvc2l0aW9uUGVyY2VudGFnZSk7XHJcbiAgICAgICAgfSwgdHJ1ZSk7XHJcbiAgICAgICAgdmFyIHN0YXJ0U21vb3RoUGxheWJhY2tQb3NpdGlvblVwZGF0ZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmICghcGxheWVyLmlzTGl2ZSgpKSB7XHJcbiAgICAgICAgICAgICAgICBjdXJyZW50VGltZVNlZWtCYXIgPSBwbGF5ZXIuZ2V0Q3VycmVudFRpbWUoKTtcclxuICAgICAgICAgICAgICAgIF90aGlzLnNtb290aFBsYXliYWNrUG9zaXRpb25VcGRhdGVyLnN0YXJ0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciBzdG9wU21vb3RoUGxheWJhY2tQb3NpdGlvblVwZGF0ZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLnNtb290aFBsYXliYWNrUG9zaXRpb25VcGRhdGVyLmNsZWFyKCk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9QTEFZLCBzdGFydFNtb290aFBsYXliYWNrUG9zaXRpb25VcGRhdGVyKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9DQVNUX1BMQVlJTkcsIHN0YXJ0U21vb3RoUGxheWJhY2tQb3NpdGlvblVwZGF0ZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BBVVNFRCwgc3RvcFNtb290aFBsYXliYWNrUG9zaXRpb25VcGRhdGVyKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9DQVNUX1BBVVNFRCwgc3RvcFNtb290aFBsYXliYWNrUG9zaXRpb25VcGRhdGVyKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TRUVLRUQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY3VycmVudFRpbWVTZWVrQmFyID0gcGxheWVyLmdldEN1cnJlbnRUaW1lKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgaWYgKHBsYXllci5pc1BsYXlpbmcoKSkge1xyXG4gICAgICAgICAgICBzdGFydFNtb290aFBsYXliYWNrUG9zaXRpb25VcGRhdGVyKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIFNlZWtCYXIucHJvdG90eXBlLmNvbmZpZ3VyZU1hcmtlcnMgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciBjbGVhck1hcmtlcnMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLnRpbWVsaW5lTWFya2VycyA9IFtdO1xyXG4gICAgICAgICAgICBfdGhpcy51cGRhdGVNYXJrZXJzKCk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICB2YXIgc2V0dXBNYXJrZXJzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjbGVhck1hcmtlcnMoKTtcclxuICAgICAgICAgICAgdmFyIGhhc01hcmtlcnNJblVpQ29uZmlnID0gdWltYW5hZ2VyLmdldENvbmZpZygpLm1ldGFkYXRhICYmIHVpbWFuYWdlci5nZXRDb25maWcoKS5tZXRhZGF0YS5tYXJrZXJzXHJcbiAgICAgICAgICAgICAgICAmJiB1aW1hbmFnZXIuZ2V0Q29uZmlnKCkubWV0YWRhdGEubWFya2Vycy5sZW5ndGggPiAwO1xyXG4gICAgICAgICAgICB2YXIgaGFzTWFya2Vyc0luUGxheWVyQ29uZmlnID0gcGxheWVyLmdldENvbmZpZygpLnNvdXJjZSAmJiBwbGF5ZXIuZ2V0Q29uZmlnKCkuc291cmNlLm1hcmtlcnNcclxuICAgICAgICAgICAgICAgICYmIHBsYXllci5nZXRDb25maWcoKS5zb3VyY2UubWFya2Vycy5sZW5ndGggPiAwO1xyXG4gICAgICAgICAgICAvLyBUYWtlIG1hcmtlcnMgZnJvbSB0aGUgVUkgY29uZmlnLiBJZiBubyBtYXJrZXJzIGRlZmluZWQsIHRyeSB0byB0YWtlIHRoZW0gZnJvbSB0aGUgcGxheWVyJ3Mgc291cmNlIGNvbmZpZy5cclxuICAgICAgICAgICAgdmFyIG1hcmtlcnMgPSBoYXNNYXJrZXJzSW5VaUNvbmZpZyA/IHVpbWFuYWdlci5nZXRDb25maWcoKS5tZXRhZGF0YS5tYXJrZXJzIDpcclxuICAgICAgICAgICAgICAgIGhhc01hcmtlcnNJblBsYXllckNvbmZpZyA/IHBsYXllci5nZXRDb25maWcoKS5zb3VyY2UubWFya2VycyA6IG51bGw7XHJcbiAgICAgICAgICAgIC8vIEdlbmVyYXRlIHRpbWVsaW5lIG1hcmtlcnMgZnJvbSB0aGUgY29uZmlnIGlmIHdlIGhhdmUgbWFya2VycyBhbmQgaWYgd2UgaGF2ZSBhIGR1cmF0aW9uXHJcbiAgICAgICAgICAgIC8vIFRoZSBkdXJhdGlvbiBjaGVjayBpcyBmb3IgYnVnZ3kgcGxhdGZvcm1zIHdoZXJlIHRoZSBkdXJhdGlvbiBpcyBub3QgYXZhaWxhYmxlIGluc3RhbnRseSAoQ2hyb21lIG9uIEFuZHJvaWQgNC4zKVxyXG4gICAgICAgICAgICBpZiAobWFya2VycyAmJiBwbGF5ZXIuZ2V0RHVyYXRpb24oKSAhPT0gSW5maW5pdHkpIHtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgbWFya2Vyc18xID0gbWFya2VyczsgX2kgPCBtYXJrZXJzXzEubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG1hcmtlciA9IG1hcmtlcnNfMVtfaV07XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMudGltZWxpbmVNYXJrZXJzLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aW1lOiAxMDAgLyBwbGF5ZXIuZ2V0RHVyYXRpb24oKSAqIG1hcmtlci50aW1lLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogbWFya2VyLnRpdGxlLFxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIFBvcHVsYXRlIHRoZSB0aW1lbGluZSB3aXRoIHRoZSBtYXJrZXJzXHJcbiAgICAgICAgICAgIF90aGlzLnVwZGF0ZU1hcmtlcnMoKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIEFkZCBtYXJrZXJzIHdoZW4gYSBzb3VyY2UgaXMgbG9hZGVkXHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUkVBRFksIHNldHVwTWFya2Vycyk7XHJcbiAgICAgICAgLy8gUmVtb3ZlIG1hcmtlcnMgd2hlbiB1bmxvYWRlZFxyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1NPVVJDRV9VTkxPQURFRCwgY2xlYXJNYXJrZXJzKTtcclxuICAgICAgICAvLyBJbml0IG1hcmtlcnMgYXQgc3RhcnR1cFxyXG4gICAgICAgIHNldHVwTWFya2VycygpO1xyXG4gICAgfTtcclxuICAgIFNlZWtCYXIucHJvdG90eXBlLnJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5yZWxlYXNlLmNhbGwodGhpcyk7XHJcbiAgICAgICAgaWYgKHRoaXMuc21vb3RoUGxheWJhY2tQb3NpdGlvblVwZGF0ZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5zbW9vdGhQbGF5YmFja1Bvc2l0aW9uVXBkYXRlci5jbGVhcigpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBTZWVrQmFyLnByb3RvdHlwZS50b0RvbUVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICBpZiAodGhpcy5jb25maWcudmVydGljYWwpIHtcclxuICAgICAgICAgICAgdGhpcy5jb25maWcuY3NzQ2xhc3Nlcy5wdXNoKCd2ZXJ0aWNhbCcpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc2Vla0JhckNvbnRhaW5lciA9IG5ldyBkb21fMS5ET00oJ2RpdicsIHtcclxuICAgICAgICAgICAgJ2lkJzogdGhpcy5jb25maWcuaWQsXHJcbiAgICAgICAgICAgICdjbGFzcyc6IHRoaXMuZ2V0Q3NzQ2xhc3NlcygpLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZhciBzZWVrQmFyID0gbmV3IGRvbV8xLkRPTSgnZGl2Jywge1xyXG4gICAgICAgICAgICAnY2xhc3MnOiB0aGlzLnByZWZpeENzcygnc2Vla2JhcicpLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuc2Vla0JhciA9IHNlZWtCYXI7XHJcbiAgICAgICAgLy8gSW5kaWNhdG9yIHRoYXQgc2hvd3MgdGhlIGJ1ZmZlciBmaWxsIGxldmVsXHJcbiAgICAgICAgdmFyIHNlZWtCYXJCdWZmZXJMZXZlbCA9IG5ldyBkb21fMS5ET00oJ2RpdicsIHtcclxuICAgICAgICAgICAgJ2NsYXNzJzogdGhpcy5wcmVmaXhDc3MoJ3NlZWtiYXItYnVmZmVybGV2ZWwnKSxcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLnNlZWtCYXJCdWZmZXJQb3NpdGlvbiA9IHNlZWtCYXJCdWZmZXJMZXZlbDtcclxuICAgICAgICAvLyBJbmRpY2F0b3IgdGhhdCBzaG93cyB0aGUgY3VycmVudCBwbGF5YmFjayBwb3NpdGlvblxyXG4gICAgICAgIHZhciBzZWVrQmFyUGxheWJhY2tQb3NpdGlvbiA9IG5ldyBkb21fMS5ET00oJ2RpdicsIHtcclxuICAgICAgICAgICAgJ2NsYXNzJzogdGhpcy5wcmVmaXhDc3MoJ3NlZWtiYXItcGxheWJhY2twb3NpdGlvbicpLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuc2Vla0JhclBsYXliYWNrUG9zaXRpb24gPSBzZWVrQmFyUGxheWJhY2tQb3NpdGlvbjtcclxuICAgICAgICAvLyBBIG1hcmtlciBvZiB0aGUgY3VycmVudCBwbGF5YmFjayBwb3NpdGlvbiwgZS5nLiBhIGRvdCBvciBsaW5lXHJcbiAgICAgICAgdmFyIHNlZWtCYXJQbGF5YmFja1Bvc2l0aW9uTWFya2VyID0gbmV3IGRvbV8xLkRPTSgnZGl2Jywge1xyXG4gICAgICAgICAgICAnY2xhc3MnOiB0aGlzLnByZWZpeENzcygnc2Vla2Jhci1wbGF5YmFja3Bvc2l0aW9uLW1hcmtlcicpLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuc2Vla0JhclBsYXliYWNrUG9zaXRpb25NYXJrZXIgPSBzZWVrQmFyUGxheWJhY2tQb3NpdGlvbk1hcmtlcjtcclxuICAgICAgICAvLyBJbmRpY2F0b3IgdGhhdCBzaG93IHdoZXJlIGEgc2VlayB3aWxsIGdvIHRvXHJcbiAgICAgICAgdmFyIHNlZWtCYXJTZWVrUG9zaXRpb24gPSBuZXcgZG9tXzEuRE9NKCdkaXYnLCB7XHJcbiAgICAgICAgICAgICdjbGFzcyc6IHRoaXMucHJlZml4Q3NzKCdzZWVrYmFyLXNlZWtwb3NpdGlvbicpLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuc2Vla0JhclNlZWtQb3NpdGlvbiA9IHNlZWtCYXJTZWVrUG9zaXRpb247XHJcbiAgICAgICAgLy8gSW5kaWNhdG9yIHRoYXQgc2hvd3MgdGhlIGZ1bGwgc2Vla2JhclxyXG4gICAgICAgIHZhciBzZWVrQmFyQmFja2Ryb3AgPSBuZXcgZG9tXzEuRE9NKCdkaXYnLCB7XHJcbiAgICAgICAgICAgICdjbGFzcyc6IHRoaXMucHJlZml4Q3NzKCdzZWVrYmFyLWJhY2tkcm9wJyksXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5zZWVrQmFyQmFja2Ryb3AgPSBzZWVrQmFyQmFja2Ryb3A7XHJcbiAgICAgICAgdmFyIHNlZWtCYXJDaGFwdGVyTWFya2Vyc0NvbnRhaW5lciA9IG5ldyBkb21fMS5ET00oJ2RpdicsIHtcclxuICAgICAgICAgICAgJ2NsYXNzJzogdGhpcy5wcmVmaXhDc3MoJ3NlZWtiYXItbWFya2VycycpLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuc2Vla0Jhck1hcmtlcnNDb250YWluZXIgPSBzZWVrQmFyQ2hhcHRlck1hcmtlcnNDb250YWluZXI7XHJcbiAgICAgICAgc2Vla0Jhci5hcHBlbmQoc2Vla0JhckJhY2tkcm9wLCBzZWVrQmFyQnVmZmVyTGV2ZWwsIHNlZWtCYXJTZWVrUG9zaXRpb24sIHNlZWtCYXJQbGF5YmFja1Bvc2l0aW9uLCBzZWVrQmFyQ2hhcHRlck1hcmtlcnNDb250YWluZXIsIHNlZWtCYXJQbGF5YmFja1Bvc2l0aW9uTWFya2VyKTtcclxuICAgICAgICB2YXIgc2Vla2luZyA9IGZhbHNlO1xyXG4gICAgICAgIC8vIERlZmluZSBoYW5kbGVyIGZ1bmN0aW9ucyBzbyB3ZSBjYW4gYXR0YWNoL3JlbW92ZSB0aGVtIGxhdGVyXHJcbiAgICAgICAgdmFyIG1vdXNlVG91Y2hNb3ZlSGFuZGxlciA9IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgLy8gQXZvaWQgcHJvcGFnYXRpb24gdG8gVlIgaGFuZGxlclxyXG4gICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgICB2YXIgdGFyZ2V0UGVyY2VudGFnZSA9IDEwMCAqIF90aGlzLmdldE9mZnNldChlKTtcclxuICAgICAgICAgICAgX3RoaXMuc2V0U2Vla1Bvc2l0aW9uKHRhcmdldFBlcmNlbnRhZ2UpO1xyXG4gICAgICAgICAgICBfdGhpcy5zZXRQbGF5YmFja1Bvc2l0aW9uKHRhcmdldFBlcmNlbnRhZ2UpO1xyXG4gICAgICAgICAgICBfdGhpcy5vblNlZWtQcmV2aWV3RXZlbnQodGFyZ2V0UGVyY2VudGFnZSwgdHJ1ZSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICB2YXIgbW91c2VUb3VjaFVwSGFuZGxlciA9IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgLy8gUmVtb3ZlIGhhbmRsZXJzLCBzZWVrIG9wZXJhdGlvbiBpcyBmaW5pc2hlZFxyXG4gICAgICAgICAgICBuZXcgZG9tXzEuRE9NKGRvY3VtZW50KS5vZmYoJ3RvdWNobW92ZSBtb3VzZW1vdmUnLCBtb3VzZVRvdWNoTW92ZUhhbmRsZXIpO1xyXG4gICAgICAgICAgICBuZXcgZG9tXzEuRE9NKGRvY3VtZW50KS5vZmYoJ3RvdWNoZW5kIG1vdXNldXAnLCBtb3VzZVRvdWNoVXBIYW5kbGVyKTtcclxuICAgICAgICAgICAgdmFyIHRhcmdldFBlcmNlbnRhZ2UgPSAxMDAgKiBfdGhpcy5nZXRPZmZzZXQoZSk7XHJcbiAgICAgICAgICAgIHZhciBzbmFwcGVkQ2hhcHRlciA9IF90aGlzLmdldE1hcmtlckF0UG9zaXRpb24odGFyZ2V0UGVyY2VudGFnZSk7XHJcbiAgICAgICAgICAgIF90aGlzLnNldFNlZWtpbmcoZmFsc2UpO1xyXG4gICAgICAgICAgICBzZWVraW5nID0gZmFsc2U7XHJcbiAgICAgICAgICAgIC8vIEZpcmUgc2Vla2VkIGV2ZW50XHJcbiAgICAgICAgICAgIF90aGlzLm9uU2Vla2VkRXZlbnQoc25hcHBlZENoYXB0ZXIgPyBzbmFwcGVkQ2hhcHRlci50aW1lIDogdGFyZ2V0UGVyY2VudGFnZSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvLyBBIHNlZWsgYWx3YXlzIHN0YXJ0IHdpdGggYSB0b3VjaHN0YXJ0IG9yIG1vdXNlZG93biBkaXJlY3RseSBvbiB0aGUgc2Vla2Jhci5cclxuICAgICAgICAvLyBUbyB0cmFjayBhIG1vdXNlIHNlZWsgYWxzbyBvdXRzaWRlIHRoZSBzZWVrYmFyIChmb3IgdG91Y2ggZXZlbnRzIHRoaXMgd29ya3MgYXV0b21hdGljYWxseSksXHJcbiAgICAgICAgLy8gc28gdGhlIHVzZXIgZG9lcyBub3QgbmVlZCB0byB0YWtlIGNhcmUgdGhhdCB0aGUgbW91c2UgYWx3YXlzIHN0YXlzIG9uIHRoZSBzZWVrYmFyLCB3ZSBhdHRhY2ggdGhlIG1vdXNlbW92ZVxyXG4gICAgICAgIC8vIGFuZCBtb3VzZXVwIGhhbmRsZXJzIHRvIHRoZSB3aG9sZSBkb2N1bWVudC4gQSBzZWVrIGlzIHRyaWdnZXJlZCB3aGVuIHRoZSB1c2VyIGxpZnRzIHRoZSBtb3VzZSBrZXkuXHJcbiAgICAgICAgLy8gQSBzZWVrIG1vdXNlIGdlc3R1cmUgaXMgdGh1cyBiYXNpY2FsbHkgYSBjbGljayB3aXRoIGEgbG9uZyB0aW1lIGZyYW1lIGJldHdlZW4gZG93biBhbmQgdXAgZXZlbnRzLlxyXG4gICAgICAgIHNlZWtCYXIub24oJ3RvdWNoc3RhcnQgbW91c2Vkb3duJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgdmFyIGlzVG91Y2hFdmVudCA9IF90aGlzLnRvdWNoU3VwcG9ydGVkICYmIGUgaW5zdGFuY2VvZiBUb3VjaEV2ZW50O1xyXG4gICAgICAgICAgICAvLyBQcmV2ZW50IHNlbGVjdGlvbiBvZiBET00gZWxlbWVudHMgKGFsc28gcHJldmVudHMgbW91c2Vkb3duIGlmIGN1cnJlbnQgZXZlbnQgaXMgdG91Y2hzdGFydClcclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAvLyBBdm9pZCBwcm9wYWdhdGlvbiB0byBWUiBoYW5kbGVyXHJcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgIF90aGlzLnNldFNlZWtpbmcodHJ1ZSk7IC8vIFNldCBzZWVraW5nIGNsYXNzIG9uIERPTSBlbGVtZW50XHJcbiAgICAgICAgICAgIHNlZWtpbmcgPSB0cnVlOyAvLyBTZXQgc2VlayB0cmFja2luZyBmbGFnXHJcbiAgICAgICAgICAgIC8vIEZpcmUgc2Vla2VkIGV2ZW50XHJcbiAgICAgICAgICAgIF90aGlzLm9uU2Vla0V2ZW50KCk7XHJcbiAgICAgICAgICAgIC8vIEFkZCBoYW5kbGVyIHRvIHRyYWNrIHRoZSBzZWVrIG9wZXJhdGlvbiBvdmVyIHRoZSB3aG9sZSBkb2N1bWVudFxyXG4gICAgICAgICAgICBuZXcgZG9tXzEuRE9NKGRvY3VtZW50KS5vbihpc1RvdWNoRXZlbnQgPyAndG91Y2htb3ZlJyA6ICdtb3VzZW1vdmUnLCBtb3VzZVRvdWNoTW92ZUhhbmRsZXIpO1xyXG4gICAgICAgICAgICBuZXcgZG9tXzEuRE9NKGRvY3VtZW50KS5vbihpc1RvdWNoRXZlbnQgPyAndG91Y2hlbmQnIDogJ21vdXNldXAnLCBtb3VzZVRvdWNoVXBIYW5kbGVyKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBEaXNwbGF5IHNlZWsgdGFyZ2V0IGluZGljYXRvciB3aGVuIG1vdXNlIGhvdmVycyBvciBmaW5nZXIgc2xpZGVzIG92ZXIgc2Vla2JhclxyXG4gICAgICAgIHNlZWtCYXIub24oJ3RvdWNobW92ZSBtb3VzZW1vdmUnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIGlmIChzZWVraW5nKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBEdXJpbmcgYSBzZWVrICh3aGVuIG1vdXNlIGlzIGRvd24gb3IgdG91Y2ggbW92ZSBhY3RpdmUpLCB3ZSBuZWVkIHRvIHN0b3AgcHJvcGFnYXRpb24gdG8gYXZvaWRcclxuICAgICAgICAgICAgICAgIC8vIHRoZSBWUiB2aWV3cG9ydCByZWFjdGluZyB0byB0aGUgbW92ZXMuXHJcbiAgICAgICAgICAgICAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xyXG4gICAgICAgICAgICAgICAgLy8gQmVjYXVzZSB0aGUgc3RvcHBlZCBwcm9wYWdhdGlvbiBpbmhpYml0cyB0aGUgZXZlbnQgb24gdGhlIGRvY3VtZW50LCB3ZSBuZWVkIHRvIGNhbGwgaXQgZnJvbSBoZXJlXHJcbiAgICAgICAgICAgICAgICBtb3VzZVRvdWNoTW92ZUhhbmRsZXIoZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIHBvc2l0aW9uID0gMTAwICogX3RoaXMuZ2V0T2Zmc2V0KGUpO1xyXG4gICAgICAgICAgICBfdGhpcy5zZXRTZWVrUG9zaXRpb24ocG9zaXRpb24pO1xyXG4gICAgICAgICAgICBfdGhpcy5vblNlZWtQcmV2aWV3RXZlbnQocG9zaXRpb24sIGZhbHNlKTtcclxuICAgICAgICAgICAgaWYgKF90aGlzLmhhc0xhYmVsKCkgJiYgX3RoaXMuZ2V0TGFiZWwoKS5pc0hpZGRlbigpKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5nZXRMYWJlbCgpLnNob3coKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIEhpZGUgc2VlayB0YXJnZXQgaW5kaWNhdG9yIHdoZW4gbW91c2Ugb3IgZmluZ2VyIGxlYXZlcyBzZWVrYmFyXHJcbiAgICAgICAgc2Vla0Jhci5vbigndG91Y2hlbmQgbW91c2VsZWF2ZScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgX3RoaXMuc2V0U2Vla1Bvc2l0aW9uKDApO1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuaGFzTGFiZWwoKSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZ2V0TGFiZWwoKS5oaWRlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBzZWVrQmFyQ29udGFpbmVyLmFwcGVuZChzZWVrQmFyKTtcclxuICAgICAgICBpZiAodGhpcy5sYWJlbCkge1xyXG4gICAgICAgICAgICBzZWVrQmFyQ29udGFpbmVyLmFwcGVuZCh0aGlzLmxhYmVsLmdldERvbUVsZW1lbnQoKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBzZWVrQmFyQ29udGFpbmVyO1xyXG4gICAgfTtcclxuICAgIFNlZWtCYXIucHJvdG90eXBlLnVwZGF0ZU1hcmtlcnMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5zZWVrQmFyTWFya2Vyc0NvbnRhaW5lci5lbXB0eSgpO1xyXG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSB0aGlzLnRpbWVsaW5lTWFya2VyczsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgdmFyIG1hcmtlciA9IF9hW19pXTtcclxuICAgICAgICAgICAgdGhpcy5zZWVrQmFyTWFya2Vyc0NvbnRhaW5lci5hcHBlbmQobmV3IGRvbV8xLkRPTSgnZGl2Jywge1xyXG4gICAgICAgICAgICAgICAgJ2NsYXNzJzogdGhpcy5wcmVmaXhDc3MoJ3NlZWtiYXItbWFya2VyJyksXHJcbiAgICAgICAgICAgICAgICAnZGF0YS1tYXJrZXItdGltZSc6IFN0cmluZyhtYXJrZXIudGltZSksXHJcbiAgICAgICAgICAgICAgICAnZGF0YS1tYXJrZXItdGl0bGUnOiBTdHJpbmcobWFya2VyLnRpdGxlKSxcclxuICAgICAgICAgICAgfSkuY3NzKHtcclxuICAgICAgICAgICAgICAgICd3aWR0aCc6IG1hcmtlci50aW1lICsgJyUnLFxyXG4gICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIFNlZWtCYXIucHJvdG90eXBlLmdldE1hcmtlckF0UG9zaXRpb24gPSBmdW5jdGlvbiAocGVyY2VudGFnZSkge1xyXG4gICAgICAgIHZhciBzbmFwcGVkTWFya2VyID0gbnVsbDtcclxuICAgICAgICB2YXIgc25hcHBpbmdSYW5nZSA9IDE7XHJcbiAgICAgICAgaWYgKHRoaXMudGltZWxpbmVNYXJrZXJzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMudGltZWxpbmVNYXJrZXJzOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICAgICAgdmFyIG1hcmtlciA9IF9hW19pXTtcclxuICAgICAgICAgICAgICAgIGlmIChwZXJjZW50YWdlID49IG1hcmtlci50aW1lIC0gc25hcHBpbmdSYW5nZSAmJiBwZXJjZW50YWdlIDw9IG1hcmtlci50aW1lICsgc25hcHBpbmdSYW5nZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNuYXBwZWRNYXJrZXIgPSBtYXJrZXI7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHNuYXBwZWRNYXJrZXI7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBob3Jpem9udGFsIG9mZnNldCBvZiBhIG1vdXNlL3RvdWNoIGV2ZW50IHBvaW50IGZyb20gdGhlIGxlZnQgZWRnZSBvZiB0aGUgc2VlayBiYXIuXHJcbiAgICAgKiBAcGFyYW0gZXZlbnRQYWdlWCB0aGUgcGFnZVggY29vcmRpbmF0ZSBvZiBhbiBldmVudCB0byBjYWxjdWxhdGUgdGhlIG9mZnNldCBmcm9tXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBhIG51bWJlciBpbiB0aGUgcmFuZ2Ugb2YgWzAsIDFdLCB3aGVyZSAwIGlzIHRoZSBsZWZ0IGVkZ2UgYW5kIDEgaXMgdGhlIHJpZ2h0IGVkZ2VcclxuICAgICAqL1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUuZ2V0SG9yaXpvbnRhbE9mZnNldCA9IGZ1bmN0aW9uIChldmVudFBhZ2VYKSB7XHJcbiAgICAgICAgdmFyIGVsZW1lbnRPZmZzZXRQeCA9IHRoaXMuc2Vla0Jhci5vZmZzZXQoKS5sZWZ0O1xyXG4gICAgICAgIHZhciB3aWR0aFB4ID0gdGhpcy5zZWVrQmFyLndpZHRoKCk7XHJcbiAgICAgICAgdmFyIG9mZnNldFB4ID0gZXZlbnRQYWdlWCAtIGVsZW1lbnRPZmZzZXRQeDtcclxuICAgICAgICB2YXIgb2Zmc2V0ID0gMSAvIHdpZHRoUHggKiBvZmZzZXRQeDtcclxuICAgICAgICByZXR1cm4gdGhpcy5zYW5pdGl6ZU9mZnNldChvZmZzZXQpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgdmVydGljYWwgb2Zmc2V0IG9mIGEgbW91c2UvdG91Y2ggZXZlbnQgcG9pbnQgZnJvbSB0aGUgYm90dG9tIGVkZ2Ugb2YgdGhlIHNlZWsgYmFyLlxyXG4gICAgICogQHBhcmFtIGV2ZW50UGFnZVkgdGhlIHBhZ2VYIGNvb3JkaW5hdGUgb2YgYW4gZXZlbnQgdG8gY2FsY3VsYXRlIHRoZSBvZmZzZXQgZnJvbVxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gYSBudW1iZXIgaW4gdGhlIHJhbmdlIG9mIFswLCAxXSwgd2hlcmUgMCBpcyB0aGUgYm90dG9tIGVkZ2UgYW5kIDEgaXMgdGhlIHRvcCBlZGdlXHJcbiAgICAgKi9cclxuICAgIFNlZWtCYXIucHJvdG90eXBlLmdldFZlcnRpY2FsT2Zmc2V0ID0gZnVuY3Rpb24gKGV2ZW50UGFnZVkpIHtcclxuICAgICAgICB2YXIgZWxlbWVudE9mZnNldFB4ID0gdGhpcy5zZWVrQmFyLm9mZnNldCgpLnRvcDtcclxuICAgICAgICB2YXIgd2lkdGhQeCA9IHRoaXMuc2Vla0Jhci5oZWlnaHQoKTtcclxuICAgICAgICB2YXIgb2Zmc2V0UHggPSBldmVudFBhZ2VZIC0gZWxlbWVudE9mZnNldFB4O1xyXG4gICAgICAgIHZhciBvZmZzZXQgPSAxIC8gd2lkdGhQeCAqIG9mZnNldFB4O1xyXG4gICAgICAgIHJldHVybiAxIC0gdGhpcy5zYW5pdGl6ZU9mZnNldChvZmZzZXQpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgbW91c2Ugb3IgdG91Y2ggZXZlbnQgb2Zmc2V0IGZvciB0aGUgY3VycmVudCBjb25maWd1cmF0aW9uIChob3Jpem9udGFsIG9yIHZlcnRpY2FsKS5cclxuICAgICAqIEBwYXJhbSBlIHRoZSBldmVudCB0byBjYWxjdWxhdGUgdGhlIG9mZnNldCBmcm9tXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBhIG51bWJlciBpbiB0aGUgcmFuZ2Ugb2YgWzAsIDFdXHJcbiAgICAgKiBAc2VlICNnZXRIb3Jpem9udGFsT2Zmc2V0XHJcbiAgICAgKiBAc2VlICNnZXRWZXJ0aWNhbE9mZnNldFxyXG4gICAgICovXHJcbiAgICBTZWVrQmFyLnByb3RvdHlwZS5nZXRPZmZzZXQgPSBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgIGlmICh0aGlzLnRvdWNoU3VwcG9ydGVkICYmIGUgaW5zdGFuY2VvZiBUb3VjaEV2ZW50KSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy52ZXJ0aWNhbCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VmVydGljYWxPZmZzZXQoZS50eXBlID09PSAndG91Y2hlbmQnID8gZS5jaGFuZ2VkVG91Y2hlc1swXS5wYWdlWSA6IGUudG91Y2hlc1swXS5wYWdlWSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRIb3Jpem9udGFsT2Zmc2V0KGUudHlwZSA9PT0gJ3RvdWNoZW5kJyA/IGUuY2hhbmdlZFRvdWNoZXNbMF0ucGFnZVggOiBlLnRvdWNoZXNbMF0ucGFnZVgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKGUgaW5zdGFuY2VvZiBNb3VzZUV2ZW50KSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbmZpZy52ZXJ0aWNhbCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0VmVydGljYWxPZmZzZXQoZS5wYWdlWSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRIb3Jpem9udGFsT2Zmc2V0KGUucGFnZVgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBpZiAoY29uc29sZSkge1xyXG4gICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdpbnZhbGlkIGV2ZW50Jyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIDA7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogU2FuaXRpemVzIHRoZSBtb3VzZSBvZmZzZXQgdG8gdGhlIHJhbmdlIG9mIFswLCAxXS5cclxuICAgICAqXHJcbiAgICAgKiBXaGVuIHRyYWNraW5nIHRoZSBtb3VzZSBvdXRzaWRlIHRoZSBzZWVrIGJhciwgdGhlIG9mZnNldCBjYW4gYmUgb3V0c2lkZSB0aGUgZGVzaXJlZCByYW5nZSBhbmQgdGhpcyBtZXRob2RcclxuICAgICAqIGxpbWl0cyBpdCB0byB0aGUgZGVzaXJlZCByYW5nZS4gRS5nLiBhIG1vdXNlIGV2ZW50IGxlZnQgb2YgdGhlIGxlZnQgZWRnZSBvZiBhIHNlZWsgYmFyIHlpZWxkcyBhbiBvZmZzZXQgYmVsb3dcclxuICAgICAqIHplcm8sIGJ1dCB0byBkaXNwbGF5IHRoZSBzZWVrIHRhcmdldCBvbiB0aGUgc2VlayBiYXIsIHdlIG5lZWQgdG8gbGltaXQgaXQgdG8gemVyby5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gb2Zmc2V0IHRoZSBvZmZzZXQgdG8gc2FuaXRpemVcclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IHRoZSBzYW5pdGl6ZWQgb2Zmc2V0LlxyXG4gICAgICovXHJcbiAgICBTZWVrQmFyLnByb3RvdHlwZS5zYW5pdGl6ZU9mZnNldCA9IGZ1bmN0aW9uIChvZmZzZXQpIHtcclxuICAgICAgICAvLyBTaW5jZSB3ZSB0cmFjayBtb3VzZSBtb3ZlcyBvdmVyIHRoZSB3aG9sZSBkb2N1bWVudCwgdGhlIHRhcmdldCBjYW4gYmUgb3V0c2lkZSB0aGUgc2VlayByYW5nZSxcclxuICAgICAgICAvLyBhbmQgd2UgbmVlZCB0byBsaW1pdCBpdCB0byB0aGUgWzAsIDFdIHJhbmdlLlxyXG4gICAgICAgIGlmIChvZmZzZXQgPCAwKSB7XHJcbiAgICAgICAgICAgIG9mZnNldCA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKG9mZnNldCA+IDEpIHtcclxuICAgICAgICAgICAgb2Zmc2V0ID0gMTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG9mZnNldDtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIHBvc2l0aW9uIG9mIHRoZSBwbGF5YmFjayBwb3NpdGlvbiBpbmRpY2F0b3IuXHJcbiAgICAgKiBAcGFyYW0gcGVyY2VudCBhIG51bWJlciBiZXR3ZWVuIDAgYW5kIDEwMCBhcyByZXR1cm5lZCBieSB0aGUgcGxheWVyXHJcbiAgICAgKi9cclxuICAgIFNlZWtCYXIucHJvdG90eXBlLnNldFBsYXliYWNrUG9zaXRpb24gPSBmdW5jdGlvbiAocGVyY2VudCkge1xyXG4gICAgICAgIHRoaXMucGxheWJhY2tQb3NpdGlvblBlcmNlbnRhZ2UgPSBwZXJjZW50O1xyXG4gICAgICAgIC8vIFNldCBwb3NpdGlvbiBvZiB0aGUgYmFyXHJcbiAgICAgICAgdGhpcy5zZXRQb3NpdGlvbih0aGlzLnNlZWtCYXJQbGF5YmFja1Bvc2l0aW9uLCBwZXJjZW50KTtcclxuICAgICAgICAvLyBTZXQgcG9zaXRpb24gb2YgdGhlIG1hcmtlclxyXG4gICAgICAgIHZhciB0b3RhbFNpemUgPSAodGhpcy5jb25maWcudmVydGljYWwgPyAodGhpcy5zZWVrQmFyLmhlaWdodCgpIC0gdGhpcy5zZWVrQmFyUGxheWJhY2tQb3NpdGlvbk1hcmtlci5oZWlnaHQoKSkgOiB0aGlzLnNlZWtCYXIud2lkdGgoKSk7XHJcbiAgICAgICAgdmFyIHB4ID0gKHRvdGFsU2l6ZSkgLyAxMDAgKiBwZXJjZW50O1xyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy52ZXJ0aWNhbCkge1xyXG4gICAgICAgICAgICBweCA9IHRoaXMuc2Vla0Jhci5oZWlnaHQoKSAtIHB4IC0gdGhpcy5zZWVrQmFyUGxheWJhY2tQb3NpdGlvbk1hcmtlci5oZWlnaHQoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHN0eWxlID0gdGhpcy5jb25maWcudmVydGljYWwgP1xyXG4gICAgICAgICAgICAvLyAtbXMtdHJhbnNmb3JtIHJlcXVpcmVkIGZvciBJRTlcclxuICAgICAgICAgICAgeyAndHJhbnNmb3JtJzogJ3RyYW5zbGF0ZVkoJyArIHB4ICsgJ3B4KScsICctbXMtdHJhbnNmb3JtJzogJ3RyYW5zbGF0ZVkoJyArIHB4ICsgJ3B4KScgfSA6XHJcbiAgICAgICAgICAgIHsgJ3RyYW5zZm9ybSc6ICd0cmFuc2xhdGVYKCcgKyBweCArICdweCknLCAnLW1zLXRyYW5zZm9ybSc6ICd0cmFuc2xhdGVYKCcgKyBweCArICdweCknIH07XHJcbiAgICAgICAgdGhpcy5zZWVrQmFyUGxheWJhY2tQb3NpdGlvbk1hcmtlci5jc3Moc3R5bGUpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmVmcmVzaGVzIHRoZSBwbGF5YmFjayBwb3NpdGlvbi4gQ2FuIGJlIHVzZWQgYnkgc3ViY2xhc3NlcyB0byByZWZyZXNoIHRoZSBwb3NpdGlvbiB3aGVuXHJcbiAgICAgKiB0aGUgc2l6ZSBvZiB0aGUgY29tcG9uZW50IGNoYW5nZXMuXHJcbiAgICAgKi9cclxuICAgIFNlZWtCYXIucHJvdG90eXBlLnJlZnJlc2hQbGF5YmFja1Bvc2l0aW9uID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMuc2V0UGxheWJhY2tQb3NpdGlvbih0aGlzLnBsYXliYWNrUG9zaXRpb25QZXJjZW50YWdlKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIHBvc2l0aW9uIHVudGlsIHdoaWNoIG1lZGlhIGlzIGJ1ZmZlcmVkLlxyXG4gICAgICogQHBhcmFtIHBlcmNlbnQgYSBudW1iZXIgYmV0d2VlbiAwIGFuZCAxMDBcclxuICAgICAqL1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUuc2V0QnVmZmVyUG9zaXRpb24gPSBmdW5jdGlvbiAocGVyY2VudCkge1xyXG4gICAgICAgIHRoaXMuc2V0UG9zaXRpb24odGhpcy5zZWVrQmFyQnVmZmVyUG9zaXRpb24sIHBlcmNlbnQpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgcG9zaXRpb24gd2hlcmUgYSBzZWVrLCBpZiBleGVjdXRlZCwgd291bGQganVtcCB0by5cclxuICAgICAqIEBwYXJhbSBwZXJjZW50IGEgbnVtYmVyIGJldHdlZW4gMCBhbmQgMTAwXHJcbiAgICAgKi9cclxuICAgIFNlZWtCYXIucHJvdG90eXBlLnNldFNlZWtQb3NpdGlvbiA9IGZ1bmN0aW9uIChwZXJjZW50KSB7XHJcbiAgICAgICAgdGhpcy5zZXRQb3NpdGlvbih0aGlzLnNlZWtCYXJTZWVrUG9zaXRpb24sIHBlcmNlbnQpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogU2V0IHRoZSBhY3R1YWwgcG9zaXRpb24gKHdpZHRoIG9yIGhlaWdodCkgb2YgYSBET00gZWxlbWVudCB0aGF0IHJlcHJlc2VudCBhIGJhciBpbiB0aGUgc2VlayBiYXIuXHJcbiAgICAgKiBAcGFyYW0gZWxlbWVudCB0aGUgZWxlbWVudCB0byBzZXQgdGhlIHBvc2l0aW9uIGZvclxyXG4gICAgICogQHBhcmFtIHBlcmNlbnQgYSBudW1iZXIgYmV0d2VlbiAwIGFuZCAxMDBcclxuICAgICAqL1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUuc2V0UG9zaXRpb24gPSBmdW5jdGlvbiAoZWxlbWVudCwgcGVyY2VudCkge1xyXG4gICAgICAgIHZhciBzY2FsZSA9IHBlcmNlbnQgLyAxMDA7XHJcbiAgICAgICAgdmFyIHN0eWxlID0gdGhpcy5jb25maWcudmVydGljYWwgP1xyXG4gICAgICAgICAgICAvLyAtbXMtdHJhbnNmb3JtIHJlcXVpcmVkIGZvciBJRTlcclxuICAgICAgICAgICAgeyAndHJhbnNmb3JtJzogJ3NjYWxlWSgnICsgc2NhbGUgKyAnKScsICctbXMtdHJhbnNmb3JtJzogJ3NjYWxlWSgnICsgc2NhbGUgKyAnKScgfSA6XHJcbiAgICAgICAgICAgIHsgJ3RyYW5zZm9ybSc6ICdzY2FsZVgoJyArIHNjYWxlICsgJyknLCAnLW1zLXRyYW5zZm9ybSc6ICdzY2FsZVgoJyArIHNjYWxlICsgJyknIH07XHJcbiAgICAgICAgZWxlbWVudC5jc3Moc3R5bGUpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUHV0cyB0aGUgc2VlayBiYXIgaW50byBvciBvdXQgb2Ygc2Vla2luZyBzdGF0ZSBieSBhZGRpbmcvcmVtb3ZpbmcgYSBjbGFzcyB0byB0aGUgRE9NIGVsZW1lbnQuIFRoaXMgY2FuIGJlIHVzZWRcclxuICAgICAqIHRvIGFkanVzdCB0aGUgc3R5bGluZyB3aGlsZSBzZWVraW5nLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBzZWVraW5nIHNob3VsZCBiZSB0cnVlIHdoZW4gZW50ZXJpbmcgc2VlayBzdGF0ZSwgZmFsc2Ugd2hlbiBleGl0aW5nIHRoZSBzZWVrIHN0YXRlXHJcbiAgICAgKi9cclxuICAgIFNlZWtCYXIucHJvdG90eXBlLnNldFNlZWtpbmcgPSBmdW5jdGlvbiAoc2Vla2luZykge1xyXG4gICAgICAgIGlmIChzZWVraW5nKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZ2V0RG9tRWxlbWVudCgpLmFkZENsYXNzKHRoaXMucHJlZml4Q3NzKFNlZWtCYXIuQ0xBU1NfU0VFS0lORykpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5nZXREb21FbGVtZW50KCkucmVtb3ZlQ2xhc3ModGhpcy5wcmVmaXhDc3MoU2Vla0Jhci5DTEFTU19TRUVLSU5HKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQ2hlY2tzIGlmIHRoZSBzZWVrIGJhciBpcyBjdXJyZW50bHkgaW4gdGhlIHNlZWsgc3RhdGUuXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiBpbiBzZWVrIHN0YXRlLCBlbHNlIGZhbHNlXHJcbiAgICAgKi9cclxuICAgIFNlZWtCYXIucHJvdG90eXBlLmlzU2Vla2luZyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXREb21FbGVtZW50KCkuaGFzQ2xhc3ModGhpcy5wcmVmaXhDc3MoU2Vla0Jhci5DTEFTU19TRUVLSU5HKSk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBDaGVja3MgaWYgdGhlIHNlZWsgYmFyIGhhcyBhIHtAbGluayBTZWVrQmFyTGFiZWx9LlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWYgdGhlIHNlZWsgYmFyIGhhcyBhIGxhYmVsLCBlbHNlIGZhbHNlXHJcbiAgICAgKi9cclxuICAgIFNlZWtCYXIucHJvdG90eXBlLmhhc0xhYmVsID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmxhYmVsICE9IG51bGw7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBsYWJlbCBvZiB0aGlzIHNlZWsgYmFyLlxyXG4gICAgICogQHJldHVybnMge1NlZWtCYXJMYWJlbH0gdGhlIGxhYmVsIGlmIHRoaXMgc2VlayBiYXIgaGFzIGEgbGFiZWwsIGVsc2UgbnVsbFxyXG4gICAgICovXHJcbiAgICBTZWVrQmFyLnByb3RvdHlwZS5nZXRMYWJlbCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5sYWJlbDtcclxuICAgIH07XHJcbiAgICBTZWVrQmFyLnByb3RvdHlwZS5vblNlZWtFdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLnNlZWtCYXJFdmVudHMub25TZWVrLmRpc3BhdGNoKHRoaXMpO1xyXG4gICAgfTtcclxuICAgIFNlZWtCYXIucHJvdG90eXBlLm9uU2Vla1ByZXZpZXdFdmVudCA9IGZ1bmN0aW9uIChwZXJjZW50YWdlLCBzY3J1YmJpbmcpIHtcclxuICAgICAgICB2YXIgc25hcHBlZE1hcmtlciA9IHRoaXMuZ2V0TWFya2VyQXRQb3NpdGlvbihwZXJjZW50YWdlKTtcclxuICAgICAgICBpZiAodGhpcy5sYWJlbCkge1xyXG4gICAgICAgICAgICB0aGlzLmxhYmVsLmdldERvbUVsZW1lbnQoKS5jc3Moe1xyXG4gICAgICAgICAgICAgICAgJ2xlZnQnOiAoc25hcHBlZE1hcmtlciA/IHNuYXBwZWRNYXJrZXIudGltZSA6IHBlcmNlbnRhZ2UpICsgJyUnLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5zZWVrQmFyRXZlbnRzLm9uU2Vla1ByZXZpZXcuZGlzcGF0Y2godGhpcywge1xyXG4gICAgICAgICAgICBzY3J1YmJpbmc6IHNjcnViYmluZyxcclxuICAgICAgICAgICAgcG9zaXRpb246IHBlcmNlbnRhZ2UsXHJcbiAgICAgICAgICAgIG1hcmtlcjogc25hcHBlZE1hcmtlcixcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBTZWVrQmFyLnByb3RvdHlwZS5vblNlZWtlZEV2ZW50ID0gZnVuY3Rpb24gKHBlcmNlbnRhZ2UpIHtcclxuICAgICAgICB0aGlzLnNlZWtCYXJFdmVudHMub25TZWVrZWQuZGlzcGF0Y2godGhpcywgcGVyY2VudGFnZSk7XHJcbiAgICB9O1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFNlZWtCYXIucHJvdG90eXBlLCBcIm9uU2Vla1wiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogR2V0cyB0aGUgZXZlbnQgdGhhdCBpcyBmaXJlZCB3aGVuIGEgc2NydWJiaW5nIHNlZWsgb3BlcmF0aW9uIGlzIHN0YXJ0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50PFNlZWtCYXIsIE5vQXJncz59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNlZWtCYXJFdmVudHMub25TZWVrLmdldEV2ZW50KCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoU2Vla0Jhci5wcm90b3R5cGUsIFwib25TZWVrUHJldmlld1wiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogR2V0cyB0aGUgZXZlbnQgdGhhdCBpcyBmaXJlZCBkdXJpbmcgYSBzY3J1YmJpbmcgc2VlayAodG8gaW5kaWNhdGUgdGhhdCB0aGUgc2VlayBwcmV2aWV3LCBpLmUuIHRoZSB2aWRlbyBmcmFtZSxcclxuICAgICAgICAgKiBzaG91bGQgYmUgdXBkYXRlZCksIG9yIGR1cmluZyBhIG5vcm1hbCBzZWVrIHByZXZpZXcgd2hlbiB0aGUgc2VlayBiYXIgaXMgaG92ZXJlZCAoYW5kIHRoZSBzZWVrIHRhcmdldCxcclxuICAgICAgICAgKiBpLmUuIHRoZSBzZWVrIGJhciBsYWJlbCwgc2hvdWxkIGJlIHVwZGF0ZWQpLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtFdmVudDxTZWVrQmFyLCBTZWVrUHJldmlld0V2ZW50QXJncz59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNlZWtCYXJFdmVudHMub25TZWVrUHJldmlldy5nZXRFdmVudCgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFNlZWtCYXIucHJvdG90eXBlLCBcIm9uU2Vla2VkXCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXRzIHRoZSBldmVudCB0aGF0IGlzIGZpcmVkIHdoZW4gYSBzY3J1YmJpbmcgc2VlayBoYXMgZmluaXNoZWQgb3Igd2hlbiBhIGRpcmVjdCBzZWVrIGlzIGlzc3VlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnQ8U2Vla0JhciwgbnVtYmVyPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2Vla0JhckV2ZW50cy5vblNlZWtlZC5nZXRFdmVudCgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUub25TaG93RXZlbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5vblNob3dFdmVudC5jYWxsKHRoaXMpO1xyXG4gICAgICAgIC8vIFJlZnJlc2ggdGhlIHBvc2l0aW9uIG9mIHRoZSBwbGF5YmFjayBwb3NpdGlvbiB3aGVuIHRoZSBzZWVrIGJhciBiZWNvbWVzIHZpc2libGUuIFRvIGNvcnJlY3RseSBzZXQgdGhlIHBvc2l0aW9uLFxyXG4gICAgICAgIC8vIHRoZSBET00gZWxlbWVudCBtdXN0IGJlIGZ1bGx5IGluaXRpYWxpemVkIGFuIGhhdmUgaXRzIHNpemUgY2FsY3VsYXRlZCwgYmVjYXVzZSB0aGUgcG9zaXRpb24gaXMgc2V0IGFzIGFuIGFic29sdXRlXHJcbiAgICAgICAgLy8gdmFsdWUgY2FsY3VsYXRlZCBmcm9tIHRoZSBzaXplLiBUaGlzIHJlcXVpcmVkIHNpemUgaXMgbm90IGtub3duIHdoZW4gaXQgaXMgaGlkZGVuLlxyXG4gICAgICAgIC8vIEZvciBzdWNoIGNhc2VzLCB3ZSByZWZyZXNoIHRoZSBwb3NpdGlvbiBoZXJlIGluIG9uU2hvdyBiZWNhdXNlIGhlcmUgaXQgaXMgZ3VhcmFudGVlZCB0aGF0IHRoZSBjb21wb25lbnQga25vd3NcclxuICAgICAgICAvLyBpdHMgc2l6ZSBhbmQgY2FuIHNldCB0aGUgcG9zaXRpb24gY29ycmVjdGx5LlxyXG4gICAgICAgIHRoaXMucmVmcmVzaFBsYXliYWNrUG9zaXRpb24oKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gU2Vla0JhcjtcclxufShjb21wb25lbnRfMS5Db21wb25lbnQpKTtcclxuU2Vla0Jhci5TTU9PVEhfUExBWUJBQ0tfUE9TSVRJT05fVVBEQVRFX0RJU0FCTEVEID0gLTE7XHJcbi8qKlxyXG4gKiBUaGUgQ1NTIGNsYXNzIHRoYXQgaXMgYWRkZWQgdG8gdGhlIERPTSBlbGVtZW50IHdoaWxlIHRoZSBzZWVrIGJhciBpcyBpbiAnc2Vla2luZycgc3RhdGUuXHJcbiAqL1xyXG5TZWVrQmFyLkNMQVNTX1NFRUtJTkcgPSAnc2Vla2luZyc7XHJcbmV4cG9ydHMuU2Vla0JhciA9IFNlZWtCYXI7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9zZWVrYmFyLnRzXG4vLyBtb2R1bGUgaWQgPSAxM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgU3RyaW5nVXRpbHM7XHJcbihmdW5jdGlvbiAoU3RyaW5nVXRpbHMpIHtcclxuICAgIFN0cmluZ1V0aWxzLkZPUk1BVF9ISE1NU1MgPSAnaGg6bW06c3MnO1xyXG4gICAgU3RyaW5nVXRpbHMuRk9STUFUX01NU1MgPSAnbW06c3MnO1xyXG4gICAgLyoqXHJcbiAgICAgKiBGb3JtYXRzIGEgbnVtYmVyIG9mIHNlY29uZHMgaW50byBhIHRpbWUgc3RyaW5nIHdpdGggdGhlIHBhdHRlcm4gaGg6bW06c3MuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHRvdGFsU2Vjb25kcyB0aGUgdG90YWwgbnVtYmVyIG9mIHNlY29uZHMgdG8gZm9ybWF0IHRvIHN0cmluZ1xyXG4gICAgICogQHBhcmFtIGZvcm1hdCB0aGUgdGltZSBmb3JtYXQgdG8gb3V0cHV0IChkZWZhdWx0OiBoaDptbTpzcylcclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IHRoZSBmb3JtYXR0ZWQgdGltZSBzdHJpbmdcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gc2Vjb25kc1RvVGltZSh0b3RhbFNlY29uZHMsIGZvcm1hdCkge1xyXG4gICAgICAgIGlmIChmb3JtYXQgPT09IHZvaWQgMCkgeyBmb3JtYXQgPSBTdHJpbmdVdGlscy5GT1JNQVRfSEhNTVNTOyB9XHJcbiAgICAgICAgdmFyIGlzTmVnYXRpdmUgPSB0b3RhbFNlY29uZHMgPCAwO1xyXG4gICAgICAgIGlmIChpc05lZ2F0aXZlKSB7XHJcbiAgICAgICAgICAgIC8vIElmIHRoZSB0aW1lIGlzIG5lZ2F0aXZlLCB3ZSBtYWtlIGl0IHBvc2l0aXZlIGZvciB0aGUgY2FsY3VsYXRpb24gYmVsb3dcclxuICAgICAgICAgICAgLy8gKGVsc2Ugd2UnZCBnZXQgYWxsIG5lZ2F0aXZlIG51bWJlcnMpIGFuZCByZWF0dGFjaCB0aGUgbmVnYXRpdmUgc2lnbiBsYXRlci5cclxuICAgICAgICAgICAgdG90YWxTZWNvbmRzID0gLXRvdGFsU2Vjb25kcztcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gU3BsaXQgaW50byBzZXBhcmF0ZSB0aW1lIHBhcnRzXHJcbiAgICAgICAgdmFyIGhvdXJzID0gTWF0aC5mbG9vcih0b3RhbFNlY29uZHMgLyAzNjAwKTtcclxuICAgICAgICB2YXIgbWludXRlcyA9IE1hdGguZmxvb3IodG90YWxTZWNvbmRzIC8gNjApIC0gaG91cnMgKiA2MDtcclxuICAgICAgICB2YXIgc2Vjb25kcyA9IE1hdGguZmxvb3IodG90YWxTZWNvbmRzKSAlIDYwO1xyXG4gICAgICAgIHJldHVybiAoaXNOZWdhdGl2ZSA/ICctJyA6ICcnKSArIGZvcm1hdFxyXG4gICAgICAgICAgICAucmVwbGFjZSgnaGgnLCBsZWZ0UGFkV2l0aFplcm9zKGhvdXJzLCAyKSlcclxuICAgICAgICAgICAgLnJlcGxhY2UoJ21tJywgbGVmdFBhZFdpdGhaZXJvcyhtaW51dGVzLCAyKSlcclxuICAgICAgICAgICAgLnJlcGxhY2UoJ3NzJywgbGVmdFBhZFdpdGhaZXJvcyhzZWNvbmRzLCAyKSk7XHJcbiAgICB9XHJcbiAgICBTdHJpbmdVdGlscy5zZWNvbmRzVG9UaW1lID0gc2Vjb25kc1RvVGltZTtcclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgYSBudW1iZXIgdG8gYSBzdHJpbmcgYW5kIGxlZnQtcGFkcyBpdCB3aXRoIHplcm9zIHRvIHRoZSBzcGVjaWZpZWQgbGVuZ3RoLlxyXG4gICAgICogRXhhbXBsZTogbGVmdFBhZFdpdGhaZXJvcygxMjMsIDUpID0+ICcwMDEyMydcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gbnVtIHRoZSBudW1iZXIgdG8gY29udmVydCB0byBzdHJpbmcgYW5kIHBhZCB3aXRoIHplcm9zXHJcbiAgICAgKiBAcGFyYW0gbGVuZ3RoIHRoZSBkZXNpcmVkIGxlbmd0aCBvZiB0aGUgcGFkZGVkIHN0cmluZ1xyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gdGhlIHBhZGRlZCBudW1iZXIgYXMgc3RyaW5nXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGxlZnRQYWRXaXRoWmVyb3MobnVtLCBsZW5ndGgpIHtcclxuICAgICAgICB2YXIgdGV4dCA9IG51bSArICcnO1xyXG4gICAgICAgIHZhciBwYWRkaW5nID0gJzAwMDAwMDAwMDAnLnN1YnN0cigwLCBsZW5ndGggLSB0ZXh0Lmxlbmd0aCk7XHJcbiAgICAgICAgcmV0dXJuIHBhZGRpbmcgKyB0ZXh0O1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBGaWxscyBvdXQgcGxhY2Vob2xkZXJzIGluIGFuIGFkIG1lc3NhZ2UuXHJcbiAgICAgKlxyXG4gICAgICogSGFzIHRoZSBwbGFjZWhvbGRlcnMgJ3tyZW1haW5pbmdUaW1lW2Zvcm1hdFN0cmluZ119JywgJ3twbGF5ZWRUaW1lW2Zvcm1hdFN0cmluZ119JyBhbmRcclxuICAgICAqICd7YWREdXJhdGlvbltmb3JtYXRTdHJpbmddfScsIHdoaWNoIGFyZSByZXBsYWNlZCBieSB0aGUgcmVtYWluaW5nIHRpbWUgdW50aWwgdGhlIGFkIGNhbiBiZSBza2lwcGVkLCB0aGUgY3VycmVudFxyXG4gICAgICogdGltZSBvciB0aGUgYWQgZHVyYXRpb24uIFRoZSBmb3JtYXQgc3RyaW5nIGlzIG9wdGlvbmFsLiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgcGxhY2Vob2xkZXIgaXMgcmVwbGFjZWQgYnkgdGhlIHRpbWVcclxuICAgICAqIGluIHNlY29uZHMuIElmIHNwZWNpZmllZCwgaXQgbXVzdCBiZSBvZiB0aGUgZm9sbG93aW5nIGZvcm1hdDpcclxuICAgICAqIC0gJWQgLSBJbnNlcnRzIHRoZSB0aW1lIGFzIGFuIGludGVnZXIuXHJcbiAgICAgKiAtICUwTmQgLSBJbnNlcnRzIHRoZSB0aW1lIGFzIGFuIGludGVnZXIgd2l0aCBsZWFkaW5nIHplcm9lcywgaWYgdGhlIGxlbmd0aCBvZiB0aGUgdGltZSBzdHJpbmcgaXMgc21hbGxlciB0aGFuIE4uXHJcbiAgICAgKiAtICVmIC0gSW5zZXJ0cyB0aGUgdGltZSBhcyBhIGZsb2F0LlxyXG4gICAgICogLSAlME5mIC0gSW5zZXJ0cyB0aGUgdGltZSBhcyBhIGZsb2F0IHdpdGggbGVhZGluZyB6ZXJvZXMuXHJcbiAgICAgKiAtICUuTWYgLSBJbnNlcnRzIHRoZSB0aW1lIGFzIGEgZmxvYXQgd2l0aCBNIGRlY2ltYWwgcGxhY2VzLiBDYW4gYmUgY29tYmluZWQgd2l0aCAlME5mLCBlLmcuICUwNC4yZiAodGhlIHRpbWVcclxuICAgICAqIDEwLjEyM1xyXG4gICAgICogd291bGQgYmUgcHJpbnRlZCBhcyAwMDEwLjEyKS5cclxuICAgICAqIC0gJWhoOm1tOnNzXHJcbiAgICAgKiAtICVtbTpzc1xyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBhZE1lc3NhZ2UgYW4gYWQgbWVzc2FnZSB3aXRoIG9wdGlvbmFsIHBsYWNlaG9sZGVycyB0byBmaWxsXHJcbiAgICAgKiBAcGFyYW0gc2tpcE9mZnNldCBpZiBzcGVjaWZpZWQsIHtyZW1haW5pbmdUaW1lfSB3aWxsIGJlIGZpbGxlZCB3aXRoIHRoZSByZW1haW5pbmcgdGltZSB1bnRpbCB0aGUgYWQgY2FuIGJlIHNraXBwZWRcclxuICAgICAqIEBwYXJhbSBwbGF5ZXIgdGhlIHBsYXllciB0byBnZXQgdGhlIHRpbWUgZGF0YSBmcm9tXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSB0aGUgYWQgbWVzc2FnZSB3aXRoIGZpbGxlZCBwbGFjZWhvbGRlcnNcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gcmVwbGFjZUFkTWVzc2FnZVBsYWNlaG9sZGVycyhhZE1lc3NhZ2UsIHNraXBPZmZzZXQsIHBsYXllcikge1xyXG4gICAgICAgIHZhciBhZE1lc3NhZ2VQbGFjZWhvbGRlclJlZ2V4ID0gbmV3IFJlZ0V4cCgnXFxcXHsocmVtYWluaW5nVGltZXxwbGF5ZWRUaW1lfGFkRHVyYXRpb24pKH18JSgoMFsxLTldXFxcXGQqKFxcXFwuXFxcXGQrKGR8Zil8ZHxmKXxcXFxcLlxcXFxkK2Z8ZHxmKXxoaDptbTpzc3xtbTpzcyl9KScsICdnJyk7XHJcbiAgICAgICAgcmV0dXJuIGFkTWVzc2FnZS5yZXBsYWNlKGFkTWVzc2FnZVBsYWNlaG9sZGVyUmVnZXgsIGZ1bmN0aW9uIChmb3JtYXRTdHJpbmcpIHtcclxuICAgICAgICAgICAgdmFyIHRpbWUgPSAwO1xyXG4gICAgICAgICAgICBpZiAoZm9ybWF0U3RyaW5nLmluZGV4T2YoJ3JlbWFpbmluZ1RpbWUnKSA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2tpcE9mZnNldCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRpbWUgPSBNYXRoLmNlaWwoc2tpcE9mZnNldCAtIHBsYXllci5nZXRDdXJyZW50VGltZSgpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRpbWUgPSBwbGF5ZXIuZ2V0RHVyYXRpb24oKSAtIHBsYXllci5nZXRDdXJyZW50VGltZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGZvcm1hdFN0cmluZy5pbmRleE9mKCdwbGF5ZWRUaW1lJykgPiAtMSkge1xyXG4gICAgICAgICAgICAgICAgdGltZSA9IHBsYXllci5nZXRDdXJyZW50VGltZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGZvcm1hdFN0cmluZy5pbmRleE9mKCdhZER1cmF0aW9uJykgPiAtMSkge1xyXG4gICAgICAgICAgICAgICAgdGltZSA9IHBsYXllci5nZXREdXJhdGlvbigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBmb3JtYXROdW1iZXIodGltZSwgZm9ybWF0U3RyaW5nKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuICAgIFN0cmluZ1V0aWxzLnJlcGxhY2VBZE1lc3NhZ2VQbGFjZWhvbGRlcnMgPSByZXBsYWNlQWRNZXNzYWdlUGxhY2Vob2xkZXJzO1xyXG4gICAgZnVuY3Rpb24gZm9ybWF0TnVtYmVyKHRpbWUsIGZvcm1hdCkge1xyXG4gICAgICAgIHZhciBmb3JtYXRTdHJpbmdWYWxpZGF0aW9uUmVnZXggPSAvJSgoMFsxLTldXFxkKihcXC5cXGQrKGR8Zil8ZHxmKXxcXC5cXGQrZnxkfGYpfGhoOm1tOnNzfG1tOnNzKS87XHJcbiAgICAgICAgdmFyIGxlYWRpbmdaZXJvZXNSZWdleCA9IC8oJTBbMS05XVxcZCopKD89KFxcLlxcZCtmfGZ8ZCkpLztcclxuICAgICAgICB2YXIgZGVjaW1hbFBsYWNlc1JlZ2V4ID0gL1xcLlxcZCooPz1mKS87XHJcbiAgICAgICAgaWYgKCFmb3JtYXRTdHJpbmdWYWxpZGF0aW9uUmVnZXgudGVzdChmb3JtYXQpKSB7XHJcbiAgICAgICAgICAgIC8vIElmIHRoZSBmb3JtYXQgaXMgaW52YWxpZCwgd2Ugc2V0IGEgZGVmYXVsdCBmYWxsYmFjayBmb3JtYXRcclxuICAgICAgICAgICAgZm9ybWF0ID0gJyVkJztcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gRGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgbGVhZGluZyB6ZXJvc1xyXG4gICAgICAgIHZhciBsZWFkaW5nWmVyb2VzID0gMDtcclxuICAgICAgICB2YXIgbGVhZGluZ1plcm9lc01hdGNoZXMgPSBmb3JtYXQubWF0Y2gobGVhZGluZ1plcm9lc1JlZ2V4KTtcclxuICAgICAgICBpZiAobGVhZGluZ1plcm9lc01hdGNoZXMpIHtcclxuICAgICAgICAgICAgbGVhZGluZ1plcm9lcyA9IHBhcnNlSW50KGxlYWRpbmdaZXJvZXNNYXRjaGVzWzBdLnN1YnN0cmluZygyKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIERldGVybWluZSB0aGUgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzXHJcbiAgICAgICAgdmFyIG51bURlY2ltYWxQbGFjZXMgPSBudWxsO1xyXG4gICAgICAgIHZhciBkZWNpbWFsUGxhY2VzTWF0Y2hlcyA9IGZvcm1hdC5tYXRjaChkZWNpbWFsUGxhY2VzUmVnZXgpO1xyXG4gICAgICAgIGlmIChkZWNpbWFsUGxhY2VzTWF0Y2hlcyAmJiAhaXNOYU4ocGFyc2VJbnQoZGVjaW1hbFBsYWNlc01hdGNoZXNbMF0uc3Vic3RyaW5nKDEpKSkpIHtcclxuICAgICAgICAgICAgbnVtRGVjaW1hbFBsYWNlcyA9IHBhcnNlSW50KGRlY2ltYWxQbGFjZXNNYXRjaGVzWzBdLnN1YnN0cmluZygxKSk7XHJcbiAgICAgICAgICAgIGlmIChudW1EZWNpbWFsUGxhY2VzID4gMjApIHtcclxuICAgICAgICAgICAgICAgIG51bURlY2ltYWxQbGFjZXMgPSAyMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBGbG9hdCBmb3JtYXRcclxuICAgICAgICBpZiAoZm9ybWF0LmluZGV4T2YoJ2YnKSA+IC0xKSB7XHJcbiAgICAgICAgICAgIHZhciB0aW1lU3RyaW5nID0gJyc7XHJcbiAgICAgICAgICAgIGlmIChudW1EZWNpbWFsUGxhY2VzICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBBcHBseSBmaXhlZCBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXNcclxuICAgICAgICAgICAgICAgIHRpbWVTdHJpbmcgPSB0aW1lLnRvRml4ZWQobnVtRGVjaW1hbFBsYWNlcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB0aW1lU3RyaW5nID0gJycgKyB0aW1lO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIEFwcGx5IGxlYWRpbmcgemVyb3NcclxuICAgICAgICAgICAgaWYgKHRpbWVTdHJpbmcuaW5kZXhPZignLicpID4gLTEpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBsZWZ0UGFkV2l0aFplcm9zKHRpbWVTdHJpbmcsIHRpbWVTdHJpbmcubGVuZ3RoICsgKGxlYWRpbmdaZXJvZXMgLSB0aW1lU3RyaW5nLmluZGV4T2YoJy4nKSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGxlZnRQYWRXaXRoWmVyb3ModGltZVN0cmluZywgbGVhZGluZ1plcm9lcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoZm9ybWF0LmluZGV4T2YoJzonKSA+IC0xKSB7XHJcbiAgICAgICAgICAgIHZhciB0b3RhbFNlY29uZHMgPSBNYXRoLmNlaWwodGltZSk7XHJcbiAgICAgICAgICAgIC8vIGhoOm1tOnNzIGZvcm1hdFxyXG4gICAgICAgICAgICBpZiAoZm9ybWF0LmluZGV4T2YoJ2hoJykgPiAtMSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHNlY29uZHNUb1RpbWUodG90YWxTZWNvbmRzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHZhciBtaW51dGVzID0gTWF0aC5mbG9vcih0b3RhbFNlY29uZHMgLyA2MCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgc2Vjb25kcyA9IHRvdGFsU2Vjb25kcyAlIDYwO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGxlZnRQYWRXaXRoWmVyb3MobWludXRlcywgMikgKyAnOicgKyBsZWZ0UGFkV2l0aFplcm9zKHNlY29uZHMsIDIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gbGVmdFBhZFdpdGhaZXJvcyhNYXRoLmNlaWwodGltZSksIGxlYWRpbmdaZXJvZXMpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxufSkoU3RyaW5nVXRpbHMgPSBleHBvcnRzLlN0cmluZ1V0aWxzIHx8IChleHBvcnRzLlN0cmluZ1V0aWxzID0ge30pKTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9zdHJpbmd1dGlscy50c1xuLy8gbW9kdWxlIGlkID0gMTRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBjb250YWluZXJfMSA9IHJlcXVpcmUoXCIuL2NvbnRhaW5lclwiKTtcclxudmFyIHVpdXRpbHNfMSA9IHJlcXVpcmUoXCIuLi91aXV0aWxzXCIpO1xyXG52YXIgc3BhY2VyXzEgPSByZXF1aXJlKFwiLi9zcGFjZXJcIik7XHJcbi8qKlxyXG4gKiBBIGNvbnRhaW5lciBmb3IgbWFpbiBwbGF5ZXIgY29udHJvbCBjb21wb25lbnRzLCBlLmcuIHBsYXkgdG9nZ2xlIGJ1dHRvbiwgc2VlayBiYXIsIHZvbHVtZSBjb250cm9sLCBmdWxsc2NyZWVuIHRvZ2dsZVxyXG4gKiBidXR0b24uXHJcbiAqL1xyXG52YXIgQ29udHJvbEJhciA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoQ29udHJvbEJhciwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIENvbnRyb2xCYXIoY29uZmlnLCBhdXRvSGlkZSkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1jb250cm9sYmFyJyxcclxuICAgICAgICAgICAgaGlkZGVuOiBhdXRvSGlkZSxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIENvbnRyb2xCYXIucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY29uZmlndXJlLmNhbGwodGhpcywgcGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICAvLyBDb3VudHMgaG93IG1hbnkgY29tcG9uZW50cyBhcmUgaG92ZXJlZCBhbmQgYmxvY2sgaGlkaW5nIG9mIHRoZSBjb250cm9sIGJhclxyXG4gICAgICAgIHZhciBob3ZlclN0YWNrQ291bnQgPSAwO1xyXG4gICAgICAgIC8vIFRyYWNrIGhvdmVyIHN0YXR1cyBvZiBjaGlsZCBjb21wb25lbnRzXHJcbiAgICAgICAgdWl1dGlsc18xLlVJVXRpbHMudHJhdmVyc2VUcmVlKHRoaXMsIGZ1bmN0aW9uIChjb21wb25lbnQpIHtcclxuICAgICAgICAgICAgLy8gRG8gbm90IHRyYWNrIGhvdmVyIHN0YXR1cyBvZiBjaGlsZCBjb250YWluZXJzIG9yIHNwYWNlcnMsIG9ubHkgb2YgJ3JlYWwnIGNvbnRyb2xzXHJcbiAgICAgICAgICAgIGlmIChjb21wb25lbnQgaW5zdGFuY2VvZiBjb250YWluZXJfMS5Db250YWluZXIgfHwgY29tcG9uZW50IGluc3RhbmNlb2Ygc3BhY2VyXzEuU3BhY2VyKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gU3Vic2NyaWJlIGhvdmVyIGV2ZW50IGFuZCBrZWVwIGEgY291bnQgb2YgdGhlIG51bWJlciBvZiBob3ZlcmVkIGNoaWxkcmVuXHJcbiAgICAgICAgICAgIGNvbXBvbmVudC5vbkhvdmVyQ2hhbmdlZC5zdWJzY3JpYmUoZnVuY3Rpb24gKHNlbmRlciwgYXJncykge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MuaG92ZXJlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGhvdmVyU3RhY2tDb3VudCsrO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaG92ZXJTdGFja0NvdW50LS07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHVpbWFuYWdlci5vbkNvbnRyb2xzU2hvdy5zdWJzY3JpYmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoc2VsZi5jb25maWcuaGlkZGVuKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxmLnNob3coKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHVpbWFuYWdlci5vblByZXZpZXdDb250cm9sc0hpZGUuc3Vic2NyaWJlKGZ1bmN0aW9uIChzZW5kZXIsIGFyZ3MpIHtcclxuICAgICAgICAgICAgLy8gQ2FuY2VsIHRoZSBoaWRlIGV2ZW50IGlmIGhvdmVyZWQgY2hpbGQgY29tcG9uZW50cyBibG9jayBoaWRpbmdcclxuICAgICAgICAgICAgYXJncy5jYW5jZWwgPSAoaG92ZXJTdGFja0NvdW50ID4gMCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdWltYW5hZ2VyLm9uQ29udHJvbHNIaWRlLnN1YnNjcmliZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy5oaWRkZW4pIHtcclxuICAgICAgICAgICAgICAgIHNlbGYuaGlkZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIENvbnRyb2xCYXI7XHJcbn0oY29udGFpbmVyXzEuQ29udGFpbmVyKSk7XHJcbmV4cG9ydHMuQ29udHJvbEJhciA9IENvbnRyb2xCYXI7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9jb250cm9sYmFyLnRzXG4vLyBtb2R1bGUgaWQgPSAxNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgY29udGFpbmVyXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL2NvbnRhaW5lclwiKTtcclxudmFyIFVJVXRpbHM7XHJcbihmdW5jdGlvbiAoVUlVdGlscykge1xyXG4gICAgZnVuY3Rpb24gdHJhdmVyc2VUcmVlKGNvbXBvbmVudCwgdmlzaXQpIHtcclxuICAgICAgICB2YXIgcmVjdXJzaXZlVHJlZVdhbGtlciA9IGZ1bmN0aW9uIChjb21wb25lbnQsIHBhcmVudCkge1xyXG4gICAgICAgICAgICB2aXNpdChjb21wb25lbnQsIHBhcmVudCk7XHJcbiAgICAgICAgICAgIC8vIElmIHRoZSBjdXJyZW50IGNvbXBvbmVudCBpcyBhIGNvbnRhaW5lciwgdmlzaXQgaXQncyBjaGlsZHJlblxyXG4gICAgICAgICAgICBpZiAoY29tcG9uZW50IGluc3RhbmNlb2YgY29udGFpbmVyXzEuQ29udGFpbmVyKSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gY29tcG9uZW50LmdldENvbXBvbmVudHMoKTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2hpbGRDb21wb25lbnQgPSBfYVtfaV07XHJcbiAgICAgICAgICAgICAgICAgICAgcmVjdXJzaXZlVHJlZVdhbGtlcihjaGlsZENvbXBvbmVudCwgY29tcG9uZW50KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgLy8gV2FsayBhbmQgY29uZmlndXJlIHRoZSBjb21wb25lbnQgdHJlZVxyXG4gICAgICAgIHJlY3Vyc2l2ZVRyZWVXYWxrZXIoY29tcG9uZW50KTtcclxuICAgIH1cclxuICAgIFVJVXRpbHMudHJhdmVyc2VUcmVlID0gdHJhdmVyc2VUcmVlO1xyXG59KShVSVV0aWxzID0gZXhwb3J0cy5VSVV0aWxzIHx8IChleHBvcnRzLlVJVXRpbHMgPSB7fSkpO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL3VpdXRpbHMudHNcbi8vIG1vZHVsZSBpZCA9IDE2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgY29udGFpbmVyXzEgPSByZXF1aXJlKFwiLi9jb250YWluZXJcIik7XHJcbnZhciBkb21fMSA9IHJlcXVpcmUoXCIuLi9kb21cIik7XHJcbnZhciB0aW1lb3V0XzEgPSByZXF1aXJlKFwiLi4vdGltZW91dFwiKTtcclxudmFyIHBsYXllcnV0aWxzXzEgPSByZXF1aXJlKFwiLi4vcGxheWVydXRpbHNcIik7XHJcbi8qKlxyXG4gKiBUaGUgYmFzZSBjb250YWluZXIgdGhhdCBjb250YWlucyBhbGwgb2YgdGhlIFVJLiBUaGUgVUlDb250YWluZXIgaXMgcGFzc2VkIHRvIHRoZSB7QGxpbmsgVUlNYW5hZ2VyfSB0byBidWlsZCBhbmRcclxuICogc2V0dXAgdGhlIFVJLlxyXG4gKi9cclxudmFyIFVJQ29udGFpbmVyID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhVSUNvbnRhaW5lciwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFVJQ29udGFpbmVyKGNvbmZpZykge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS11aWNvbnRhaW5lcicsXHJcbiAgICAgICAgICAgIGhpZGVEZWxheTogMjUwMCxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIFVJQ29udGFpbmVyLnByb3RvdHlwZS5jb25maWd1cmUgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNvbmZpZ3VyZS5jYWxsKHRoaXMsIHBsYXllciwgdWltYW5hZ2VyKTtcclxuICAgICAgICB0aGlzLmNvbmZpZ3VyZVVJU2hvd0hpZGUocGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIHRoaXMuY29uZmlndXJlUGxheWVyU3RhdGVzKHBsYXllciwgdWltYW5hZ2VyKTtcclxuICAgIH07XHJcbiAgICBVSUNvbnRhaW5lci5wcm90b3R5cGUuY29uZmlndXJlVUlTaG93SGlkZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuZ2V0RG9tRWxlbWVudCgpO1xyXG4gICAgICAgIHZhciBjb25maWcgPSB0aGlzLmdldENvbmZpZygpO1xyXG4gICAgICAgIGlmIChjb25maWcuaGlkZURlbGF5ID09PSAtMSkge1xyXG4gICAgICAgICAgICB1aW1hbmFnZXIub25Db25maWd1cmVkLnN1YnNjcmliZShmdW5jdGlvbiAoKSB7IHJldHVybiB1aW1hbmFnZXIub25Db250cm9sc1Nob3cuZGlzcGF0Y2goX3RoaXMpOyB9KTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgaXNVaVNob3duID0gZmFsc2U7XHJcbiAgICAgICAgdmFyIGlzU2Vla2luZyA9IGZhbHNlO1xyXG4gICAgICAgIHZhciBpc0ZpcnN0VG91Y2ggPSB0cnVlO1xyXG4gICAgICAgIHZhciBzaG93VWkgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmICghaXNVaVNob3duKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBMZXQgc3Vic2NyaWJlcnMga25vdyB0aGF0IHRoZXkgc2hvdWxkIHJldmVhbCB0aGVtc2VsdmVzXHJcbiAgICAgICAgICAgICAgICB1aW1hbmFnZXIub25Db250cm9sc1Nob3cuZGlzcGF0Y2goX3RoaXMpO1xyXG4gICAgICAgICAgICAgICAgaXNVaVNob3duID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBEb24ndCB0cmlnZ2VyIHRpbWVvdXQgd2hpbGUgc2Vla2luZyAoaXQgd2lsbCBiZSB0cmlnZ2VyZWQgb25jZSB0aGUgc2VlayBpcyBmaW5pc2hlZCkgb3IgY2FzdGluZ1xyXG4gICAgICAgICAgICBpZiAoIWlzU2Vla2luZyAmJiAhcGxheWVyLmlzQ2FzdGluZygpKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy51aUhpZGVUaW1lb3V0LnN0YXJ0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciBoaWRlVWkgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIC8vIEhpZGUgdGhlIFVJIG9ubHkgaWYgaXQgaXMgc2hvd24sIGFuZCBpZiBub3QgY2FzdGluZ1xyXG4gICAgICAgICAgICBpZiAoaXNVaVNob3duICYmICFwbGF5ZXIuaXNDYXN0aW5nKCkpIHtcclxuICAgICAgICAgICAgICAgIC8vIElzc3VlIGEgcHJldmlldyBldmVudCB0byBjaGVjayBpZiB3ZSBhcmUgZ29vZCB0byBoaWRlIHRoZSBjb250cm9sc1xyXG4gICAgICAgICAgICAgICAgdmFyIHByZXZpZXdIaWRlRXZlbnRBcmdzID0ge307XHJcbiAgICAgICAgICAgICAgICB1aW1hbmFnZXIub25QcmV2aWV3Q29udHJvbHNIaWRlLmRpc3BhdGNoKF90aGlzLCBwcmV2aWV3SGlkZUV2ZW50QXJncyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXByZXZpZXdIaWRlRXZlbnRBcmdzLmNhbmNlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBwcmV2aWV3IHdhc24ndCBjYW5jZWxlZCwgbGV0IHN1YnNjcmliZXJzIGtub3cgdGhhdCB0aGV5IHNob3VsZCBub3cgaGlkZSB0aGVtc2VsdmVzXHJcbiAgICAgICAgICAgICAgICAgICAgdWltYW5hZ2VyLm9uQ29udHJvbHNIaWRlLmRpc3BhdGNoKF90aGlzKTtcclxuICAgICAgICAgICAgICAgICAgICBpc1VpU2hvd24gPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBoaWRlIHByZXZpZXcgd2FzIGNhbmNlbGVkLCBjb250aW51ZSB0byBzaG93IFVJXHJcbiAgICAgICAgICAgICAgICAgICAgc2hvd1VpKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIFRpbWVvdXQgdG8gZGVmZXIgVUkgaGlkaW5nIGJ5IHRoZSBjb25maWd1cmVkIGRlbGF5IHRpbWVcclxuICAgICAgICB0aGlzLnVpSGlkZVRpbWVvdXQgPSBuZXcgdGltZW91dF8xLlRpbWVvdXQoY29uZmlnLmhpZGVEZWxheSwgaGlkZVVpKTtcclxuICAgICAgICAvLyBPbiB0b3VjaCBkaXNwbGF5cywgdGhlIGZpcnN0IHRvdWNoIHJldmVhbHMgdGhlIFVJXHJcbiAgICAgICAgY29udGFpbmVyLm9uKCd0b3VjaGVuZCcsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGlmICghaXNVaVNob3duKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBPbmx5IGlmIHRoZSBVSSBpcyBoaWRkZW4sIHdlIHByZXZlbnQgb3RoZXIgYWN0aW9ucyAoZXhjZXB0IGZvciB0aGUgZmlyc3QgdG91Y2gpIGFuZCByZXZlYWwgdGhlIFVJIGluc3RlYWQuXHJcbiAgICAgICAgICAgICAgICAvLyBUaGUgZmlyc3QgdG91Y2ggaXMgbm90IHByZXZlbnRlZCB0byBsZXQgb3RoZXIgbGlzdGVuZXJzIHJlY2VpdmUgdGhlIGV2ZW50IGFuZCB0cmlnZ2VyIGFuIGluaXRpYWwgYWN0aW9uLCBlLmcuXHJcbiAgICAgICAgICAgICAgICAvLyB0aGUgaHVnZSBwbGF5YmFjayBidXR0b24gY2FuIGRpcmVjdGx5IHN0YXJ0IHBsYXliYWNrIGluc3RlYWQgb2YgcmVxdWlyaW5nIGEgZG91YmxlIHRhcCB3aGljaCAxLiByZXZlYWxzXHJcbiAgICAgICAgICAgICAgICAvLyB0aGUgVUkgYW5kIDIuIHN0YXJ0cyBwbGF5YmFjay5cclxuICAgICAgICAgICAgICAgIGlmIChpc0ZpcnN0VG91Y2gpIHtcclxuICAgICAgICAgICAgICAgICAgICBpc0ZpcnN0VG91Y2ggPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHNob3dVaSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gV2hlbiB0aGUgbW91c2UgZW50ZXJzLCB3ZSBzaG93IHRoZSBVSVxyXG4gICAgICAgIGNvbnRhaW5lci5vbignbW91c2VlbnRlcicsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgc2hvd1VpKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gV2hlbiB0aGUgbW91c2UgbW92ZXMgd2l0aGluLCB3ZSBzaG93IHRoZSBVSVxyXG4gICAgICAgIGNvbnRhaW5lci5vbignbW91c2Vtb3ZlJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBzaG93VWkoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBXaGVuIHRoZSBtb3VzZSBsZWF2ZXMsIHdlIGNhbiBwcmVwYXJlIHRvIGhpZGUgdGhlIFVJLCBleGNlcHQgYSBzZWVrIGlzIGdvaW5nIG9uXHJcbiAgICAgICAgY29udGFpbmVyLm9uKCdtb3VzZWxlYXZlJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvLyBXaGVuIGEgc2VlayBpcyBnb2luZyBvbiwgdGhlIHNlZWsgc2NydWIgcG9pbnRlciBtYXkgZXhpdCB0aGUgVUkgYXJlYSB3aGlsZSBzdGlsbCBzZWVraW5nLCBhbmQgd2UgZG8gbm90IGhpZGVcclxuICAgICAgICAgICAgLy8gdGhlIFVJIGluIHN1Y2ggY2FzZXNcclxuICAgICAgICAgICAgaWYgKCFpc1NlZWtpbmcpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLnVpSGlkZVRpbWVvdXQuc3RhcnQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHVpbWFuYWdlci5vblNlZWsuc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMudWlIaWRlVGltZW91dC5jbGVhcigpOyAvLyBEb24ndCBoaWRlIFVJIHdoaWxlIGEgc2VlayBpcyBpbiBwcm9ncmVzc1xyXG4gICAgICAgICAgICBpc1NlZWtpbmcgPSB0cnVlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHVpbWFuYWdlci5vblNlZWtlZC5zdWJzY3JpYmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpc1NlZWtpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgX3RoaXMudWlIaWRlVGltZW91dC5zdGFydCgpOyAvLyBSZS1lbmFibGUgVUkgaGlkZSB0aW1lb3V0IGFmdGVyIGEgc2Vla1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0NBU1RfU1RBUlRFRCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBzaG93VWkoKTsgLy8gU2hvdyBVSSB3aGVuIGEgQ2FzdCBzZXNzaW9uIGhhcyBzdGFydGVkIChVSSB3aWxsIHRoZW4gc3RheSBwZXJtYW5lbnRseSBvbiBkdXJpbmcgdGhlIHNlc3Npb24pXHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgVUlDb250YWluZXIucHJvdG90eXBlLmNvbmZpZ3VyZVBsYXllclN0YXRlcyA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IHRoaXMuZ2V0RG9tRWxlbWVudCgpO1xyXG4gICAgICAgIC8vIENvbnZlcnQgcGxheWVyIHN0YXRlcyBpbnRvIENTUyBjbGFzcyBuYW1lc1xyXG4gICAgICAgIHZhciBzdGF0ZUNsYXNzTmFtZXMgPSBbXTtcclxuICAgICAgICBmb3IgKHZhciBzdGF0ZSBpbiBwbGF5ZXJ1dGlsc18xLlBsYXllclV0aWxzLlBsYXllclN0YXRlKSB7XHJcbiAgICAgICAgICAgIGlmIChpc05hTihOdW1iZXIoc3RhdGUpKSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGVudW1OYW1lID0gcGxheWVydXRpbHNfMS5QbGF5ZXJVdGlscy5QbGF5ZXJTdGF0ZVtwbGF5ZXJ1dGlsc18xLlBsYXllclV0aWxzLlBsYXllclN0YXRlW3N0YXRlXV07XHJcbiAgICAgICAgICAgICAgICBzdGF0ZUNsYXNzTmFtZXNbcGxheWVydXRpbHNfMS5QbGF5ZXJVdGlscy5QbGF5ZXJTdGF0ZVtzdGF0ZV1dID1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByZWZpeENzcyhVSUNvbnRhaW5lci5TVEFURV9QUkVGSVggKyBlbnVtTmFtZS50b0xvd2VyQ2FzZSgpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgcmVtb3ZlU3RhdGVzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjb250YWluZXIucmVtb3ZlQ2xhc3Moc3RhdGVDbGFzc05hbWVzW3BsYXllcnV0aWxzXzEuUGxheWVyVXRpbHMuUGxheWVyU3RhdGUuSURMRV0pO1xyXG4gICAgICAgICAgICBjb250YWluZXIucmVtb3ZlQ2xhc3Moc3RhdGVDbGFzc05hbWVzW3BsYXllcnV0aWxzXzEuUGxheWVyVXRpbHMuUGxheWVyU3RhdGUuUFJFUEFSRURdKTtcclxuICAgICAgICAgICAgY29udGFpbmVyLnJlbW92ZUNsYXNzKHN0YXRlQ2xhc3NOYW1lc1twbGF5ZXJ1dGlsc18xLlBsYXllclV0aWxzLlBsYXllclN0YXRlLlBMQVlJTkddKTtcclxuICAgICAgICAgICAgY29udGFpbmVyLnJlbW92ZUNsYXNzKHN0YXRlQ2xhc3NOYW1lc1twbGF5ZXJ1dGlsc18xLlBsYXllclV0aWxzLlBsYXllclN0YXRlLlBBVVNFRF0pO1xyXG4gICAgICAgICAgICBjb250YWluZXIucmVtb3ZlQ2xhc3Moc3RhdGVDbGFzc05hbWVzW3BsYXllcnV0aWxzXzEuUGxheWVyVXRpbHMuUGxheWVyU3RhdGUuRklOSVNIRURdKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1JFQURZLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJlbW92ZVN0YXRlcygpO1xyXG4gICAgICAgICAgICBjb250YWluZXIuYWRkQ2xhc3Moc3RhdGVDbGFzc05hbWVzW3BsYXllcnV0aWxzXzEuUGxheWVyVXRpbHMuUGxheWVyU3RhdGUuUFJFUEFSRURdKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9QTEFZLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJlbW92ZVN0YXRlcygpO1xyXG4gICAgICAgICAgICBjb250YWluZXIuYWRkQ2xhc3Moc3RhdGVDbGFzc05hbWVzW3BsYXllcnV0aWxzXzEuUGxheWVyVXRpbHMuUGxheWVyU3RhdGUuUExBWUlOR10pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BBVVNFRCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZW1vdmVTdGF0ZXMoKTtcclxuICAgICAgICAgICAgY29udGFpbmVyLmFkZENsYXNzKHN0YXRlQ2xhc3NOYW1lc1twbGF5ZXJ1dGlsc18xLlBsYXllclV0aWxzLlBsYXllclN0YXRlLlBBVVNFRF0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BMQVlCQUNLX0ZJTklTSEVELCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJlbW92ZVN0YXRlcygpO1xyXG4gICAgICAgICAgICBjb250YWluZXIuYWRkQ2xhc3Moc3RhdGVDbGFzc05hbWVzW3BsYXllcnV0aWxzXzEuUGxheWVyVXRpbHMuUGxheWVyU3RhdGUuRklOSVNIRURdKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TT1VSQ0VfVU5MT0FERUQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmVtb3ZlU3RhdGVzKCk7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyhzdGF0ZUNsYXNzTmFtZXNbcGxheWVydXRpbHNfMS5QbGF5ZXJVdGlscy5QbGF5ZXJTdGF0ZS5JRExFXSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gSW5pdCBpbiBjdXJyZW50IHBsYXllciBzdGF0ZVxyXG4gICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyhzdGF0ZUNsYXNzTmFtZXNbcGxheWVydXRpbHNfMS5QbGF5ZXJVdGlscy5nZXRTdGF0ZShwbGF5ZXIpXSk7XHJcbiAgICAgICAgLy8gRnVsbHNjcmVlbiBtYXJrZXIgY2xhc3NcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9GVUxMU0NSRUVOX0VOVEVSLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyhfdGhpcy5wcmVmaXhDc3MoVUlDb250YWluZXIuRlVMTFNDUkVFTikpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0ZVTExTQ1JFRU5fRVhJVCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjb250YWluZXIucmVtb3ZlQ2xhc3MoX3RoaXMucHJlZml4Q3NzKFVJQ29udGFpbmVyLkZVTExTQ1JFRU4pKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBJbml0IGZ1bGxzY3JlZW4gc3RhdGVcclxuICAgICAgICBpZiAocGxheWVyLmlzRnVsbHNjcmVlbigpKSB7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyh0aGlzLnByZWZpeENzcyhVSUNvbnRhaW5lci5GVUxMU0NSRUVOKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIEJ1ZmZlcmluZyBtYXJrZXIgY2xhc3NcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TVEFMTF9TVEFSVEVELCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyhfdGhpcy5wcmVmaXhDc3MoVUlDb250YWluZXIuQlVGRkVSSU5HKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fU1RBTExfRU5ERUQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY29udGFpbmVyLnJlbW92ZUNsYXNzKF90aGlzLnByZWZpeENzcyhVSUNvbnRhaW5lci5CVUZGRVJJTkcpKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBJbml0IGJ1ZmZlcmluZyBzdGF0ZVxyXG4gICAgICAgIGlmIChwbGF5ZXIuaXNTdGFsbGVkKCkpIHtcclxuICAgICAgICAgICAgY29udGFpbmVyLmFkZENsYXNzKHRoaXMucHJlZml4Q3NzKFVJQ29udGFpbmVyLkJVRkZFUklORykpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBSZW1vdGVDb250cm9sIG1hcmtlciBjbGFzc1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0NBU1RfU1RBUlRFRCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjb250YWluZXIuYWRkQ2xhc3MoX3RoaXMucHJlZml4Q3NzKFVJQ29udGFpbmVyLlJFTU9URV9DT05UUk9MKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fQ0FTVF9TVE9QUEVELCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDbGFzcyhfdGhpcy5wcmVmaXhDc3MoVUlDb250YWluZXIuUkVNT1RFX0NPTlRST0wpKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBJbml0IFJlbW90ZUNvbnRyb2wgc3RhdGVcclxuICAgICAgICBpZiAocGxheWVyLmlzQ2FzdGluZygpKSB7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyh0aGlzLnByZWZpeENzcyhVSUNvbnRhaW5lci5SRU1PVEVfQ09OVFJPTCkpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBDb250cm9scyB2aXNpYmlsaXR5IG1hcmtlciBjbGFzc1xyXG4gICAgICAgIHVpbWFuYWdlci5vbkNvbnRyb2xzU2hvdy5zdWJzY3JpYmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjb250YWluZXIucmVtb3ZlQ2xhc3MoX3RoaXMucHJlZml4Q3NzKFVJQ29udGFpbmVyLkNPTlRST0xTX0hJRERFTikpO1xyXG4gICAgICAgICAgICBjb250YWluZXIuYWRkQ2xhc3MoX3RoaXMucHJlZml4Q3NzKFVJQ29udGFpbmVyLkNPTlRST0xTX1NIT1dOKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdWltYW5hZ2VyLm9uQ29udHJvbHNIaWRlLnN1YnNjcmliZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDbGFzcyhfdGhpcy5wcmVmaXhDc3MoVUlDb250YWluZXIuQ09OVFJPTFNfU0hPV04pKTtcclxuICAgICAgICAgICAgY29udGFpbmVyLmFkZENsYXNzKF90aGlzLnByZWZpeENzcyhVSUNvbnRhaW5lci5DT05UUk9MU19ISURERU4pKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBMYXlvdXQgc2l6ZSBjbGFzc2VzXHJcbiAgICAgICAgdmFyIHVwZGF0ZUxheW91dFNpemVDbGFzc2VzID0gZnVuY3Rpb24gKHdpZHRoLCBoZWlnaHQpIHtcclxuICAgICAgICAgICAgY29udGFpbmVyLnJlbW92ZUNsYXNzKF90aGlzLnByZWZpeENzcygnbGF5b3V0LW1heC13aWR0aC00MDAnKSk7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDbGFzcyhfdGhpcy5wcmVmaXhDc3MoJ2xheW91dC1tYXgtd2lkdGgtNjAwJykpO1xyXG4gICAgICAgICAgICBjb250YWluZXIucmVtb3ZlQ2xhc3MoX3RoaXMucHJlZml4Q3NzKCdsYXlvdXQtbWF4LXdpZHRoLTgwMCcpKTtcclxuICAgICAgICAgICAgY29udGFpbmVyLnJlbW92ZUNsYXNzKF90aGlzLnByZWZpeENzcygnbGF5b3V0LW1heC13aWR0aC0xMjAwJykpO1xyXG4gICAgICAgICAgICBpZiAod2lkdGggPD0gNDAwKSB7XHJcbiAgICAgICAgICAgICAgICBjb250YWluZXIuYWRkQ2xhc3MoX3RoaXMucHJlZml4Q3NzKCdsYXlvdXQtbWF4LXdpZHRoLTQwMCcpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICh3aWR0aCA8PSA2MDApIHtcclxuICAgICAgICAgICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyhfdGhpcy5wcmVmaXhDc3MoJ2xheW91dC1tYXgtd2lkdGgtNjAwJykpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHdpZHRoIDw9IDgwMCkge1xyXG4gICAgICAgICAgICAgICAgY29udGFpbmVyLmFkZENsYXNzKF90aGlzLnByZWZpeENzcygnbGF5b3V0LW1heC13aWR0aC04MDAnKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAod2lkdGggPD0gMTIwMCkge1xyXG4gICAgICAgICAgICAgICAgY29udGFpbmVyLmFkZENsYXNzKF90aGlzLnByZWZpeENzcygnbGF5b3V0LW1heC13aWR0aC0xMjAwJykpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9QTEFZRVJfUkVTSVpFLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAvLyBDb252ZXJ0IHN0cmluZ3MgKHdpdGggXCJweFwiIHN1ZmZpeCkgdG8gaW50c1xyXG4gICAgICAgICAgICB2YXIgd2lkdGggPSBNYXRoLnJvdW5kKE51bWJlcihlLndpZHRoLnN1YnN0cmluZygwLCBlLndpZHRoLmxlbmd0aCAtIDIpKSk7XHJcbiAgICAgICAgICAgIHZhciBoZWlnaHQgPSBNYXRoLnJvdW5kKE51bWJlcihlLmhlaWdodC5zdWJzdHJpbmcoMCwgZS5oZWlnaHQubGVuZ3RoIC0gMikpKTtcclxuICAgICAgICAgICAgdXBkYXRlTGF5b3V0U2l6ZUNsYXNzZXMod2lkdGgsIGhlaWdodCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gSW5pdCBsYXlvdXQgc3RhdGVcclxuICAgICAgICB1cGRhdGVMYXlvdXRTaXplQ2xhc3NlcyhuZXcgZG9tXzEuRE9NKHBsYXllci5nZXRGaWd1cmUoKSkud2lkdGgoKSwgbmV3IGRvbV8xLkRPTShwbGF5ZXIuZ2V0RmlndXJlKCkpLmhlaWdodCgpKTtcclxuICAgIH07XHJcbiAgICBVSUNvbnRhaW5lci5wcm90b3R5cGUucmVsZWFzZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnJlbGVhc2UuY2FsbCh0aGlzKTtcclxuICAgICAgICB0aGlzLnVpSGlkZVRpbWVvdXQuY2xlYXIoKTtcclxuICAgIH07XHJcbiAgICBVSUNvbnRhaW5lci5wcm90b3R5cGUudG9Eb21FbGVtZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBjb250YWluZXIgPSBfc3VwZXIucHJvdG90eXBlLnRvRG9tRWxlbWVudC5jYWxsKHRoaXMpO1xyXG4gICAgICAgIC8vIERldGVjdCBmbGV4Ym94IHN1cHBvcnQgKG5vdCBzdXBwb3J0ZWQgaW4gSUU5KVxyXG4gICAgICAgIGlmIChkb2N1bWVudCAmJiB0eXBlb2YgZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgncCcpLnN0eWxlLmZsZXggIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyh0aGlzLnByZWZpeENzcygnZmxleGJveCcpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyh0aGlzLnByZWZpeENzcygnbm8tZmxleGJveCcpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGNvbnRhaW5lcjtcclxuICAgIH07XHJcbiAgICByZXR1cm4gVUlDb250YWluZXI7XHJcbn0oY29udGFpbmVyXzEuQ29udGFpbmVyKSk7XHJcblVJQ29udGFpbmVyLlNUQVRFX1BSRUZJWCA9ICdwbGF5ZXItc3RhdGUtJztcclxuVUlDb250YWluZXIuRlVMTFNDUkVFTiA9ICdmdWxsc2NyZWVuJztcclxuVUlDb250YWluZXIuQlVGRkVSSU5HID0gJ2J1ZmZlcmluZyc7XHJcblVJQ29udGFpbmVyLlJFTU9URV9DT05UUk9MID0gJ3JlbW90ZS1jb250cm9sJztcclxuVUlDb250YWluZXIuQ09OVFJPTFNfU0hPV04gPSAnY29udHJvbHMtc2hvd24nO1xyXG5VSUNvbnRhaW5lci5DT05UUk9MU19ISURERU4gPSAnY29udHJvbHMtaGlkZGVuJztcclxuZXhwb3J0cy5VSUNvbnRhaW5lciA9IFVJQ29udGFpbmVyO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvdWljb250YWluZXIudHNcbi8vIG1vZHVsZSBpZCA9IDE3XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgbGFiZWxfMSA9IHJlcXVpcmUoXCIuL2xhYmVsXCIpO1xyXG52YXIgcGxheWVydXRpbHNfMSA9IHJlcXVpcmUoXCIuLi9wbGF5ZXJ1dGlsc1wiKTtcclxudmFyIHN0cmluZ3V0aWxzXzEgPSByZXF1aXJlKFwiLi4vc3RyaW5ndXRpbHNcIik7XHJcbnZhciBQbGF5YmFja1RpbWVMYWJlbE1vZGU7XHJcbihmdW5jdGlvbiAoUGxheWJhY2tUaW1lTGFiZWxNb2RlKSB7XHJcbiAgICBQbGF5YmFja1RpbWVMYWJlbE1vZGVbUGxheWJhY2tUaW1lTGFiZWxNb2RlW1wiQ3VycmVudFRpbWVcIl0gPSAwXSA9IFwiQ3VycmVudFRpbWVcIjtcclxuICAgIFBsYXliYWNrVGltZUxhYmVsTW9kZVtQbGF5YmFja1RpbWVMYWJlbE1vZGVbXCJUb3RhbFRpbWVcIl0gPSAxXSA9IFwiVG90YWxUaW1lXCI7XHJcbiAgICBQbGF5YmFja1RpbWVMYWJlbE1vZGVbUGxheWJhY2tUaW1lTGFiZWxNb2RlW1wiQ3VycmVudEFuZFRvdGFsVGltZVwiXSA9IDJdID0gXCJDdXJyZW50QW5kVG90YWxUaW1lXCI7XHJcbn0pKFBsYXliYWNrVGltZUxhYmVsTW9kZSA9IGV4cG9ydHMuUGxheWJhY2tUaW1lTGFiZWxNb2RlIHx8IChleHBvcnRzLlBsYXliYWNrVGltZUxhYmVsTW9kZSA9IHt9KSk7XHJcbi8qKlxyXG4gKiBBIGxhYmVsIHRoYXQgZGlzcGxheSB0aGUgY3VycmVudCBwbGF5YmFjayB0aW1lIGFuZCB0aGUgdG90YWwgdGltZSB0aHJvdWdoIHtAbGluayBQbGF5YmFja1RpbWVMYWJlbCNzZXRUaW1lIHNldFRpbWV9XHJcbiAqIG9yIGFueSBzdHJpbmcgdGhyb3VnaCB7QGxpbmsgUGxheWJhY2tUaW1lTGFiZWwjc2V0VGV4dCBzZXRUZXh0fS5cclxuICovXHJcbnZhciBQbGF5YmFja1RpbWVMYWJlbCA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoUGxheWJhY2tUaW1lTGFiZWwsIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBQbGF5YmFja1RpbWVMYWJlbChjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktcGxheWJhY2t0aW1lbGFiZWwnLFxyXG4gICAgICAgICAgICB0aW1lTGFiZWxNb2RlOiBQbGF5YmFja1RpbWVMYWJlbE1vZGUuQ3VycmVudEFuZFRvdGFsVGltZSxcclxuICAgICAgICAgICAgaGlkZUluTGl2ZVBsYXliYWNrOiBmYWxzZSxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIFBsYXliYWNrVGltZUxhYmVsLnByb3RvdHlwZS5jb25maWd1cmUgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY29uZmlndXJlLmNhbGwodGhpcywgcGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIHZhciBjb25maWcgPSB0aGlzLmdldENvbmZpZygpO1xyXG4gICAgICAgIHZhciBsaXZlID0gZmFsc2U7XHJcbiAgICAgICAgdmFyIGxpdmVDc3NDbGFzcyA9IHRoaXMucHJlZml4Q3NzKCd1aS1wbGF5YmFja3RpbWVsYWJlbC1saXZlJyk7XHJcbiAgICAgICAgdmFyIGxpdmVFZGdlQ3NzQ2xhc3MgPSB0aGlzLnByZWZpeENzcygndWktcGxheWJhY2t0aW1lbGFiZWwtbGl2ZS1lZGdlJyk7XHJcbiAgICAgICAgdmFyIG1pbldpZHRoID0gMDtcclxuICAgICAgICB2YXIgbGl2ZUNsaWNrSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcGxheWVyLnRpbWVTaGlmdCgwKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciB1cGRhdGVMaXZlU3RhdGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIC8vIFBsYXllciBpcyBwbGF5aW5nIGEgbGl2ZSBzdHJlYW0gd2hlbiB0aGUgZHVyYXRpb24gaXMgaW5maW5pdGVcclxuICAgICAgICAgICAgbGl2ZSA9IHBsYXllci5pc0xpdmUoKTtcclxuICAgICAgICAgICAgLy8gQXR0YWNoL2RldGFjaCBsaXZlIG1hcmtlciBjbGFzc1xyXG4gICAgICAgICAgICBpZiAobGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZ2V0RG9tRWxlbWVudCgpLmFkZENsYXNzKGxpdmVDc3NDbGFzcyk7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRUZXh0KCdMaXZlJyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlnLmhpZGVJbkxpdmVQbGF5YmFjaykge1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmhpZGUoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIF90aGlzLm9uQ2xpY2suc3Vic2NyaWJlKGxpdmVDbGlja0hhbmRsZXIpO1xyXG4gICAgICAgICAgICAgICAgdXBkYXRlTGl2ZVRpbWVzaGlmdFN0YXRlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5nZXREb21FbGVtZW50KCkucmVtb3ZlQ2xhc3MobGl2ZUNzc0NsYXNzKTtcclxuICAgICAgICAgICAgICAgIF90aGlzLmdldERvbUVsZW1lbnQoKS5yZW1vdmVDbGFzcyhsaXZlRWRnZUNzc0NsYXNzKTtcclxuICAgICAgICAgICAgICAgIF90aGlzLnNob3coKTtcclxuICAgICAgICAgICAgICAgIF90aGlzLm9uQ2xpY2sudW5zdWJzY3JpYmUobGl2ZUNsaWNrSGFuZGxlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciB1cGRhdGVMaXZlVGltZXNoaWZ0U3RhdGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChwbGF5ZXIuZ2V0VGltZVNoaWZ0KCkgPT09IDApIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmdldERvbUVsZW1lbnQoKS5hZGRDbGFzcyhsaXZlRWRnZUNzc0NsYXNzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmdldERvbUVsZW1lbnQoKS5yZW1vdmVDbGFzcyhsaXZlRWRnZUNzc0NsYXNzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIGxpdmVTdHJlYW1EZXRlY3RvciA9IG5ldyBwbGF5ZXJ1dGlsc18xLlBsYXllclV0aWxzLkxpdmVTdHJlYW1EZXRlY3RvcihwbGF5ZXIpO1xyXG4gICAgICAgIGxpdmVTdHJlYW1EZXRlY3Rvci5vbkxpdmVDaGFuZ2VkLnN1YnNjcmliZShmdW5jdGlvbiAoc2VuZGVyLCBhcmdzKSB7XHJcbiAgICAgICAgICAgIGxpdmUgPSBhcmdzLmxpdmU7XHJcbiAgICAgICAgICAgIHVwZGF0ZUxpdmVTdGF0ZSgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGxpdmVTdHJlYW1EZXRlY3Rvci5kZXRlY3QoKTsgLy8gSW5pdGlhbCBkZXRlY3Rpb25cclxuICAgICAgICB2YXIgcGxheWJhY2tUaW1lSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKCFsaXZlICYmIHBsYXllci5nZXREdXJhdGlvbigpICE9PSBJbmZpbml0eSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0VGltZShwbGF5ZXIuZ2V0Q3VycmVudFRpbWUoKSwgcGxheWVyLmdldER1cmF0aW9uKCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIFRvIGF2b2lkICdqdW1waW5nJyBpbiB0aGUgVUkgYnkgdmFyeWluZyBsYWJlbCBzaXplcyBkdWUgdG8gbm9uLW1vbm9zcGFjZWQgZm9udHMsXHJcbiAgICAgICAgICAgIC8vIHdlIGdyYWR1YWxseSBpbmNyZWFzZSB0aGUgbWluLXdpZHRoIHdpdGggdGhlIGNvbnRlbnQgdG8gcmVhY2ggYSBzdGFibGUgc2l6ZS5cclxuICAgICAgICAgICAgdmFyIHdpZHRoID0gX3RoaXMuZ2V0RG9tRWxlbWVudCgpLndpZHRoKCk7XHJcbiAgICAgICAgICAgIGlmICh3aWR0aCA+IG1pbldpZHRoKSB7XHJcbiAgICAgICAgICAgICAgICBtaW5XaWR0aCA9IHdpZHRoO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZ2V0RG9tRWxlbWVudCgpLmNzcyh7XHJcbiAgICAgICAgICAgICAgICAgICAgJ21pbi13aWR0aCc6IG1pbldpZHRoICsgJ3B4JyxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9USU1FX0NIQU5HRUQsIHBsYXliYWNrVGltZUhhbmRsZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1NFRUtFRCwgcGxheWJhY2tUaW1lSGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fQ0FTVF9USU1FX1VQREFURUQsIHBsYXliYWNrVGltZUhhbmRsZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1RJTUVfU0hJRlQsIHVwZGF0ZUxpdmVUaW1lc2hpZnRTdGF0ZSk7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fVElNRV9TSElGVEVELCB1cGRhdGVMaXZlVGltZXNoaWZ0U3RhdGUpO1xyXG4gICAgICAgIHZhciBpbml0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvLyBSZXNldCBtaW4td2lkdGggd2hlbiBhIG5ldyBzb3VyY2UgaXMgcmVhZHkgKGVzcGVjaWFsbHkgZm9yIHN3aXRjaGluZyBWT0QvTGl2ZSBtb2RlcyB3aGVyZSB0aGUgbGFiZWwgY29udGVudFxyXG4gICAgICAgICAgICAvLyBjaGFuZ2VzKVxyXG4gICAgICAgICAgICBtaW5XaWR0aCA9IDA7XHJcbiAgICAgICAgICAgIF90aGlzLmdldERvbUVsZW1lbnQoKS5jc3Moe1xyXG4gICAgICAgICAgICAgICAgJ21pbi13aWR0aCc6IG51bGwsXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAvLyBTZXQgdGltZSBmb3JtYXQgZGVwZW5kaW5nIG9uIHNvdXJjZSBkdXJhdGlvblxyXG4gICAgICAgICAgICBfdGhpcy50aW1lRm9ybWF0ID0gTWF0aC5hYnMocGxheWVyLmlzTGl2ZSgpID8gcGxheWVyLmdldE1heFRpbWVTaGlmdCgpIDogcGxheWVyLmdldER1cmF0aW9uKCkpID49IDM2MDAgP1xyXG4gICAgICAgICAgICAgICAgc3RyaW5ndXRpbHNfMS5TdHJpbmdVdGlscy5GT1JNQVRfSEhNTVNTIDogc3RyaW5ndXRpbHNfMS5TdHJpbmdVdGlscy5GT1JNQVRfTU1TUztcclxuICAgICAgICAgICAgLy8gVXBkYXRlIHRpbWUgYWZ0ZXIgdGhlIGZvcm1hdCBoYXMgYmVlbiBzZXRcclxuICAgICAgICAgICAgcGxheWJhY2tUaW1lSGFuZGxlcigpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUkVBRFksIGluaXQpO1xyXG4gICAgICAgIGluaXQoKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIGN1cnJlbnQgcGxheWJhY2sgdGltZSBhbmQgdG90YWwgZHVyYXRpb24uXHJcbiAgICAgKiBAcGFyYW0gcGxheWJhY2tTZWNvbmRzIHRoZSBjdXJyZW50IHBsYXliYWNrIHRpbWUgaW4gc2Vjb25kc1xyXG4gICAgICogQHBhcmFtIGR1cmF0aW9uU2Vjb25kcyB0aGUgdG90YWwgZHVyYXRpb24gaW4gc2Vjb25kc1xyXG4gICAgICovXHJcbiAgICBQbGF5YmFja1RpbWVMYWJlbC5wcm90b3R5cGUuc2V0VGltZSA9IGZ1bmN0aW9uIChwbGF5YmFja1NlY29uZHMsIGR1cmF0aW9uU2Vjb25kcykge1xyXG4gICAgICAgIHZhciBjdXJyZW50VGltZSA9IHN0cmluZ3V0aWxzXzEuU3RyaW5nVXRpbHMuc2Vjb25kc1RvVGltZShwbGF5YmFja1NlY29uZHMsIHRoaXMudGltZUZvcm1hdCk7XHJcbiAgICAgICAgdmFyIHRvdGFsVGltZSA9IHN0cmluZ3V0aWxzXzEuU3RyaW5nVXRpbHMuc2Vjb25kc1RvVGltZShkdXJhdGlvblNlY29uZHMsIHRoaXMudGltZUZvcm1hdCk7XHJcbiAgICAgICAgc3dpdGNoICh0aGlzLmNvbmZpZy50aW1lTGFiZWxNb2RlKSB7XHJcbiAgICAgICAgICAgIGNhc2UgUGxheWJhY2tUaW1lTGFiZWxNb2RlLkN1cnJlbnRUaW1lOlxyXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRUZXh0KFwiXCIgKyBjdXJyZW50VGltZSk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSBQbGF5YmFja1RpbWVMYWJlbE1vZGUuVG90YWxUaW1lOlxyXG4gICAgICAgICAgICAgICAgdGhpcy5zZXRUZXh0KFwiXCIgKyB0b3RhbFRpbWUpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgUGxheWJhY2tUaW1lTGFiZWxNb2RlLkN1cnJlbnRBbmRUb3RhbFRpbWU6XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldFRleHQoY3VycmVudFRpbWUgKyBcIiAvIFwiICsgdG90YWxUaW1lKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIGN1cnJlbnQgdGltZSBmb3JtYXRcclxuICAgICAqIEBwYXJhbSB0aW1lRm9ybWF0IHRoZSB0aW1lIGZvcm1hdFxyXG4gICAgICovXHJcbiAgICBQbGF5YmFja1RpbWVMYWJlbC5wcm90b3R5cGUuc2V0VGltZUZvcm1hdCA9IGZ1bmN0aW9uICh0aW1lRm9ybWF0KSB7XHJcbiAgICAgICAgdGhpcy50aW1lRm9ybWF0ID0gdGltZUZvcm1hdDtcclxuICAgIH07XHJcbiAgICByZXR1cm4gUGxheWJhY2tUaW1lTGFiZWw7XHJcbn0obGFiZWxfMS5MYWJlbCkpO1xyXG5leHBvcnRzLlBsYXliYWNrVGltZUxhYmVsID0gUGxheWJhY2tUaW1lTGFiZWw7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9wbGF5YmFja3RpbWVsYWJlbC50c1xuLy8gbW9kdWxlIGlkID0gMThcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBjb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudFwiKTtcclxuLyoqXHJcbiAqIEEgZHVtbXkgY29tcG9uZW50IHRoYXQganVzdCByZXNlcnZlcyBzb21lIHNwYWNlIGFuZCBkb2VzIG5vdGhpbmcgZWxzZS5cclxuICovXHJcbnZhciBTcGFjZXIgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKFNwYWNlciwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFNwYWNlcihjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktc3BhY2VyJyxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIFNwYWNlci5wcm90b3R5cGUub25TaG93RXZlbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gZGlzYWJsZSBldmVudCBmaXJpbmcgYnkgb3ZlcndyaXRpbmcgYW5kIG5vdCBjYWxsaW5nIHN1cGVyXHJcbiAgICB9O1xyXG4gICAgU3BhY2VyLnByb3RvdHlwZS5vbkhpZGVFdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBkaXNhYmxlIGV2ZW50IGZpcmluZyBieSBvdmVyd3JpdGluZyBhbmQgbm90IGNhbGxpbmcgc3VwZXJcclxuICAgIH07XHJcbiAgICBTcGFjZXIucHJvdG90eXBlLm9uSG92ZXJDaGFuZ2VkRXZlbnQgPSBmdW5jdGlvbiAoaG92ZXJlZCkge1xyXG4gICAgICAgIC8vIGRpc2FibGUgZXZlbnQgZmlyaW5nIGJ5IG92ZXJ3cml0aW5nIGFuZCBub3QgY2FsbGluZyBzdXBlclxyXG4gICAgfTtcclxuICAgIHJldHVybiBTcGFjZXI7XHJcbn0oY29tcG9uZW50XzEuQ29tcG9uZW50KSk7XHJcbmV4cG9ydHMuU3BhY2VyID0gU3BhY2VyO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvc3BhY2VyLnRzXG4vLyBtb2R1bGUgaWQgPSAxOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGNvbnRhaW5lcl8xID0gcmVxdWlyZShcIi4vY29udGFpbmVyXCIpO1xyXG52YXIgbGFiZWxfMSA9IHJlcXVpcmUoXCIuL2xhYmVsXCIpO1xyXG52YXIgY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRcIik7XHJcbnZhciBzdHJpbmd1dGlsc18xID0gcmVxdWlyZShcIi4uL3N0cmluZ3V0aWxzXCIpO1xyXG52YXIgaW1hZ2Vsb2FkZXJfMSA9IHJlcXVpcmUoXCIuLi9pbWFnZWxvYWRlclwiKTtcclxuLyoqXHJcbiAqIEEgbGFiZWwgZm9yIGEge0BsaW5rIFNlZWtCYXJ9IHRoYXQgY2FuIGRpc3BsYXkgdGhlIHNlZWsgdGFyZ2V0IHRpbWUsIGEgdGh1bWJuYWlsLCBhbmQgdGl0bGUgKGUuZy4gY2hhcHRlciB0aXRsZSkuXHJcbiAqL1xyXG52YXIgU2Vla0JhckxhYmVsID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhTZWVrQmFyTGFiZWwsIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBTZWVrQmFyTGFiZWwoY29uZmlnKSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLnRpbWVMYWJlbCA9IG5ldyBsYWJlbF8xLkxhYmVsKHsgY3NzQ2xhc3NlczogWydzZWVrYmFyLWxhYmVsLXRpbWUnXSB9KTtcclxuICAgICAgICBfdGhpcy50aXRsZUxhYmVsID0gbmV3IGxhYmVsXzEuTGFiZWwoeyBjc3NDbGFzc2VzOiBbJ3NlZWtiYXItbGFiZWwtdGl0bGUnXSB9KTtcclxuICAgICAgICBfdGhpcy50aHVtYm5haWwgPSBuZXcgY29tcG9uZW50XzEuQ29tcG9uZW50KHsgY3NzQ2xhc3NlczogWydzZWVrYmFyLXRodW1ibmFpbCddIH0pO1xyXG4gICAgICAgIF90aGlzLnRodW1ibmFpbEltYWdlTG9hZGVyID0gbmV3IGltYWdlbG9hZGVyXzEuSW1hZ2VMb2FkZXIoKTtcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1zZWVrYmFyLWxhYmVsJyxcclxuICAgICAgICAgICAgY29tcG9uZW50czogW25ldyBjb250YWluZXJfMS5Db250YWluZXIoe1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudHM6IFtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdGhpcy50aHVtYm5haWwsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBjb250YWluZXJfMS5Db250YWluZXIoe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50czogW190aGlzLnRpdGxlTGFiZWwsIF90aGlzLnRpbWVMYWJlbF0sXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjc3NDbGFzczogJ3NlZWtiYXItbGFiZWwtbWV0YWRhdGEnLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgICAgIF0sXHJcbiAgICAgICAgICAgICAgICAgICAgY3NzQ2xhc3M6ICdzZWVrYmFyLWxhYmVsLWlubmVyJyxcclxuICAgICAgICAgICAgICAgIH0pXSxcclxuICAgICAgICAgICAgaGlkZGVuOiB0cnVlLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgU2Vla0JhckxhYmVsLnByb3RvdHlwZS5jb25maWd1cmUgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY29uZmlndXJlLmNhbGwodGhpcywgcGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIHVpbWFuYWdlci5vblNlZWtQcmV2aWV3LnN1YnNjcmliZVJhdGVMaW1pdGVkKGZ1bmN0aW9uIChzZW5kZXIsIGFyZ3MpIHtcclxuICAgICAgICAgICAgaWYgKHBsYXllci5pc0xpdmUoKSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIG1heFRpbWVTaGlmdCA9IHBsYXllci5nZXRNYXhUaW1lU2hpZnQoKTtcclxuICAgICAgICAgICAgICAgIHZhciB0aW1lID0gbWF4VGltZVNoaWZ0IC0gbWF4VGltZVNoaWZ0ICogKGFyZ3MucG9zaXRpb24gLyAxMDApO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0VGltZSh0aW1lKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHZhciBwZXJjZW50YWdlID0gMDtcclxuICAgICAgICAgICAgICAgIGlmIChhcmdzLm1hcmtlcikge1xyXG4gICAgICAgICAgICAgICAgICAgIHBlcmNlbnRhZ2UgPSBhcmdzLm1hcmtlci50aW1lO1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFRpdGxlVGV4dChhcmdzLm1hcmtlci50aXRsZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBwZXJjZW50YWdlID0gYXJncy5wb3NpdGlvbjtcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRUaXRsZVRleHQobnVsbCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB2YXIgdGltZSA9IHBsYXllci5nZXREdXJhdGlvbigpICogKHBlcmNlbnRhZ2UgLyAxMDApO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0VGltZSh0aW1lKTtcclxuICAgICAgICAgICAgICAgIF90aGlzLnNldFRodW1ibmFpbChwbGF5ZXIuZ2V0VGh1bWIodGltZSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSwgMTAwKTtcclxuICAgICAgICB2YXIgaW5pdCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgLy8gU2V0IHRpbWUgZm9ybWF0IGRlcGVuZGluZyBvbiBzb3VyY2UgZHVyYXRpb25cclxuICAgICAgICAgICAgX3RoaXMudGltZUZvcm1hdCA9IE1hdGguYWJzKHBsYXllci5pc0xpdmUoKSA/IHBsYXllci5nZXRNYXhUaW1lU2hpZnQoKSA6IHBsYXllci5nZXREdXJhdGlvbigpKSA+PSAzNjAwID9cclxuICAgICAgICAgICAgICAgIHN0cmluZ3V0aWxzXzEuU3RyaW5nVXRpbHMuRk9STUFUX0hITU1TUyA6IHN0cmluZ3V0aWxzXzEuU3RyaW5nVXRpbHMuRk9STUFUX01NU1M7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9SRUFEWSwgaW5pdCk7XHJcbiAgICAgICAgaW5pdCgpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogU2V0cyBhcmJpdHJhcnkgdGV4dCBvbiB0aGUgbGFiZWwuXHJcbiAgICAgKiBAcGFyYW0gdGV4dCB0aGUgdGV4dCB0byBzaG93IG9uIHRoZSBsYWJlbFxyXG4gICAgICovXHJcbiAgICBTZWVrQmFyTGFiZWwucHJvdG90eXBlLnNldFRleHQgPSBmdW5jdGlvbiAodGV4dCkge1xyXG4gICAgICAgIHRoaXMudGltZUxhYmVsLnNldFRleHQodGV4dCk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIGEgdGltZSB0byBiZSBkaXNwbGF5ZWQgb24gdGhlIGxhYmVsLlxyXG4gICAgICogQHBhcmFtIHNlY29uZHMgdGhlIHRpbWUgaW4gc2Vjb25kcyB0byBkaXNwbGF5IG9uIHRoZSBsYWJlbFxyXG4gICAgICovXHJcbiAgICBTZWVrQmFyTGFiZWwucHJvdG90eXBlLnNldFRpbWUgPSBmdW5jdGlvbiAoc2Vjb25kcykge1xyXG4gICAgICAgIHRoaXMuc2V0VGV4dChzdHJpbmd1dGlsc18xLlN0cmluZ1V0aWxzLnNlY29uZHNUb1RpbWUoc2Vjb25kcywgdGhpcy50aW1lRm9ybWF0KSk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIHRoZSB0ZXh0IG9uIHRoZSB0aXRsZSBsYWJlbC5cclxuICAgICAqIEBwYXJhbSB0ZXh0IHRoZSB0ZXh0IHRvIHNob3cgb24gdGhlIGxhYmVsXHJcbiAgICAgKi9cclxuICAgIFNlZWtCYXJMYWJlbC5wcm90b3R5cGUuc2V0VGl0bGVUZXh0ID0gZnVuY3Rpb24gKHRleHQpIHtcclxuICAgICAgICB0aGlzLnRpdGxlTGFiZWwuc2V0VGV4dCh0ZXh0KTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFNldHMgb3IgcmVtb3ZlcyBhIHRodW1ibmFpbCBvbiB0aGUgbGFiZWwuXHJcbiAgICAgKiBAcGFyYW0gdGh1bWJuYWlsIHRoZSB0aHVtYm5haWwgdG8gZGlzcGxheSBvbiB0aGUgbGFiZWwgb3IgbnVsbCB0byByZW1vdmUgYSBkaXNwbGF5ZWQgdGh1bWJuYWlsXHJcbiAgICAgKi9cclxuICAgIFNlZWtCYXJMYWJlbC5wcm90b3R5cGUuc2V0VGh1bWJuYWlsID0gZnVuY3Rpb24gKHRodW1ibmFpbCkge1xyXG4gICAgICAgIGlmICh0aHVtYm5haWwgPT09IHZvaWQgMCkgeyB0aHVtYm5haWwgPSBudWxsOyB9XHJcbiAgICAgICAgdmFyIHRodW1ibmFpbEVsZW1lbnQgPSB0aGlzLnRodW1ibmFpbC5nZXREb21FbGVtZW50KCk7XHJcbiAgICAgICAgaWYgKHRodW1ibmFpbCA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIHRodW1ibmFpbEVsZW1lbnQuY3NzKHtcclxuICAgICAgICAgICAgICAgICdiYWNrZ3JvdW5kLWltYWdlJzogbnVsbCxcclxuICAgICAgICAgICAgICAgICdkaXNwbGF5JzogbnVsbCxcclxuICAgICAgICAgICAgICAgICd3aWR0aCc6IG51bGwsXHJcbiAgICAgICAgICAgICAgICAnaGVpZ2h0JzogbnVsbCxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBXZSB1c2UgdGhlIHRodW1ibmFpbCBpbWFnZSBsb2FkZXIgdG8gbWFrZSBzdXJlIHRoZSB0aHVtYm5haWwgaXMgbG9hZGVkIGFuZCBpdCdzIHNpemUgaXMga25vd24gYmVmb3JlIGJlIGNhblxyXG4gICAgICAgICAgICAvLyBjYWxjdWxhdGUgdGhlIENTUyBwcm9wZXJ0aWVzIGFuZCBzZXQgdGhlbSBvbiB0aGUgZWxlbWVudC5cclxuICAgICAgICAgICAgdGhpcy50aHVtYm5haWxJbWFnZUxvYWRlci5sb2FkKHRodW1ibmFpbC51cmwsIGZ1bmN0aW9uICh1cmwsIHdpZHRoLCBoZWlnaHQpIHtcclxuICAgICAgICAgICAgICAgIHZhciB0aHVtYm5haWxDb3VudFggPSB3aWR0aCAvIHRodW1ibmFpbC53O1xyXG4gICAgICAgICAgICAgICAgdmFyIHRodW1ibmFpbENvdW50WSA9IGhlaWdodCAvIHRodW1ibmFpbC5oO1xyXG4gICAgICAgICAgICAgICAgdmFyIHRodW1ibmFpbEluZGV4WCA9IHRodW1ibmFpbC54IC8gdGh1bWJuYWlsLnc7XHJcbiAgICAgICAgICAgICAgICB2YXIgdGh1bWJuYWlsSW5kZXhZID0gdGh1bWJuYWlsLnkgLyB0aHVtYm5haWwuaDtcclxuICAgICAgICAgICAgICAgIHZhciBzaXplWCA9IDEwMCAqIHRodW1ibmFpbENvdW50WDtcclxuICAgICAgICAgICAgICAgIHZhciBzaXplWSA9IDEwMCAqIHRodW1ibmFpbENvdW50WTtcclxuICAgICAgICAgICAgICAgIHZhciBvZmZzZXRYID0gMTAwICogdGh1bWJuYWlsSW5kZXhYO1xyXG4gICAgICAgICAgICAgICAgdmFyIG9mZnNldFkgPSAxMDAgKiB0aHVtYm5haWxJbmRleFk7XHJcbiAgICAgICAgICAgICAgICB2YXIgYXNwZWN0UmF0aW8gPSAxIC8gdGh1bWJuYWlsLncgKiB0aHVtYm5haWwuaDtcclxuICAgICAgICAgICAgICAgIC8vIFRoZSB0aHVtYm5haWwgc2l6ZSBpcyBzZXQgYnkgc2V0dGluZyB0aGUgQ1NTICd3aWR0aCcgYW5kICdwYWRkaW5nLWJvdHRvbScgcHJvcGVydGllcy4gJ3BhZGRpbmctYm90dG9tJyBpc1xyXG4gICAgICAgICAgICAgICAgLy8gdXNlZCBiZWNhdXNlIGl0IGlzIHJlbGF0aXZlIHRvIHRoZSB3aWR0aCBhbmQgY2FuIGJlIHVzZWQgdG8gc2V0IHRoZSBhc3BlY3QgcmF0aW8gb2YgdGhlIHRodW1ibmFpbC5cclxuICAgICAgICAgICAgICAgIC8vIEEgZGVmYXVsdCB2YWx1ZSBmb3Igd2lkdGggaXMgc2V0IGluIHRoZSBzdHlsZXNoZWV0IGFuZCBjYW4gYmUgb3ZlcndyaXR0ZW4gZnJvbSB0aGVyZSBvciBhbnl3aGVyZSBlbHNlLlxyXG4gICAgICAgICAgICAgICAgdGh1bWJuYWlsRWxlbWVudC5jc3Moe1xyXG4gICAgICAgICAgICAgICAgICAgICdkaXNwbGF5JzogJ2luaGVyaXQnLFxyXG4gICAgICAgICAgICAgICAgICAgICdiYWNrZ3JvdW5kLWltYWdlJzogXCJ1cmwoXCIgKyB0aHVtYm5haWwudXJsICsgXCIpXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgJ3BhZGRpbmctYm90dG9tJzogMTAwICogYXNwZWN0UmF0aW8gKyBcIiVcIixcclxuICAgICAgICAgICAgICAgICAgICAnYmFja2dyb3VuZC1zaXplJzogc2l6ZVggKyBcIiUgXCIgKyBzaXplWSArIFwiJVwiLFxyXG4gICAgICAgICAgICAgICAgICAgICdiYWNrZ3JvdW5kLXBvc2l0aW9uJzogXCItXCIgKyBvZmZzZXRYICsgXCIlIC1cIiArIG9mZnNldFkgKyBcIiVcIixcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFNlZWtCYXJMYWJlbDtcclxufShjb250YWluZXJfMS5Db250YWluZXIpKTtcclxuZXhwb3J0cy5TZWVrQmFyTGFiZWwgPSBTZWVrQmFyTGFiZWw7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9zZWVrYmFybGFiZWwudHNcbi8vIG1vZHVsZSBpZCA9IDIwXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgbGlzdHNlbGVjdG9yXzEgPSByZXF1aXJlKFwiLi9saXN0c2VsZWN0b3JcIik7XHJcbnZhciBkb21fMSA9IHJlcXVpcmUoXCIuLi9kb21cIik7XHJcbi8qKlxyXG4gKiBBIHNpbXBsZSBzZWxlY3QgYm94IHByb3ZpZGluZyB0aGUgcG9zc2liaWxpdHkgdG8gc2VsZWN0IGEgc2luZ2xlIGl0ZW0gb3V0IG9mIGEgbGlzdCBvZiBhdmFpbGFibGUgaXRlbXMuXHJcbiAqXHJcbiAqIERPTSBleGFtcGxlOlxyXG4gKiA8Y29kZT5cclxuICogICAgIDxzZWxlY3QgY2xhc3M9J3VpLXNlbGVjdGJveCc+XHJcbiAqICAgICAgICAgPG9wdGlvbiB2YWx1ZT0na2V5Jz5sYWJlbDwvb3B0aW9uPlxyXG4gKiAgICAgICAgIC4uLlxyXG4gKiAgICAgPC9zZWxlY3Q+XHJcbiAqIDwvY29kZT5cclxuICovXHJcbnZhciBTZWxlY3RCb3ggPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKFNlbGVjdEJveCwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFNlbGVjdEJveChjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktc2VsZWN0Ym94JyxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIFNlbGVjdEJveC5wcm90b3R5cGUudG9Eb21FbGVtZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIHNlbGVjdEVsZW1lbnQgPSBuZXcgZG9tXzEuRE9NKCdzZWxlY3QnLCB7XHJcbiAgICAgICAgICAgICdpZCc6IHRoaXMuY29uZmlnLmlkLFxyXG4gICAgICAgICAgICAnY2xhc3MnOiB0aGlzLmdldENzc0NsYXNzZXMoKSxcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLnNlbGVjdEVsZW1lbnQgPSBzZWxlY3RFbGVtZW50O1xyXG4gICAgICAgIHRoaXMudXBkYXRlRG9tSXRlbXMoKTtcclxuICAgICAgICBzZWxlY3RFbGVtZW50Lm9uKCdjaGFuZ2UnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciB2YWx1ZSA9IHNlbGVjdEVsZW1lbnQudmFsKCk7XHJcbiAgICAgICAgICAgIF90aGlzLm9uSXRlbVNlbGVjdGVkRXZlbnQodmFsdWUsIGZhbHNlKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gc2VsZWN0RWxlbWVudDtcclxuICAgIH07XHJcbiAgICBTZWxlY3RCb3gucHJvdG90eXBlLnVwZGF0ZURvbUl0ZW1zID0gZnVuY3Rpb24gKHNlbGVjdGVkVmFsdWUpIHtcclxuICAgICAgICBpZiAoc2VsZWN0ZWRWYWx1ZSA9PT0gdm9pZCAwKSB7IHNlbGVjdGVkVmFsdWUgPSBudWxsOyB9XHJcbiAgICAgICAgLy8gRGVsZXRlIGFsbCBjaGlsZHJlblxyXG4gICAgICAgIHRoaXMuc2VsZWN0RWxlbWVudC5lbXB0eSgpO1xyXG4gICAgICAgIC8vIEFkZCB1cGRhdGVkIGNoaWxkcmVuXHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMuaXRlbXM7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgIHZhciBpdGVtID0gX2FbX2ldO1xyXG4gICAgICAgICAgICB2YXIgb3B0aW9uRWxlbWVudCA9IG5ldyBkb21fMS5ET00oJ29wdGlvbicsIHtcclxuICAgICAgICAgICAgICAgICd2YWx1ZSc6IGl0ZW0ua2V5LFxyXG4gICAgICAgICAgICB9KS5odG1sKGl0ZW0ubGFiZWwpO1xyXG4gICAgICAgICAgICBpZiAoaXRlbS5rZXkgPT09IFN0cmluZyhzZWxlY3RlZFZhbHVlKSkge1xyXG4gICAgICAgICAgICAgICAgb3B0aW9uRWxlbWVudC5hdHRyKCdzZWxlY3RlZCcsICdzZWxlY3RlZCcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0RWxlbWVudC5hcHBlbmQob3B0aW9uRWxlbWVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIFNlbGVjdEJveC5wcm90b3R5cGUub25JdGVtQWRkZWRFdmVudCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUub25JdGVtQWRkZWRFdmVudC5jYWxsKHRoaXMsIHZhbHVlKTtcclxuICAgICAgICB0aGlzLnVwZGF0ZURvbUl0ZW1zKHRoaXMuc2VsZWN0ZWRJdGVtKTtcclxuICAgIH07XHJcbiAgICBTZWxlY3RCb3gucHJvdG90eXBlLm9uSXRlbVJlbW92ZWRFdmVudCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUub25JdGVtUmVtb3ZlZEV2ZW50LmNhbGwodGhpcywgdmFsdWUpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlRG9tSXRlbXModGhpcy5zZWxlY3RlZEl0ZW0pO1xyXG4gICAgfTtcclxuICAgIFNlbGVjdEJveC5wcm90b3R5cGUub25JdGVtU2VsZWN0ZWRFdmVudCA9IGZ1bmN0aW9uICh2YWx1ZSwgdXBkYXRlRG9tSXRlbXMpIHtcclxuICAgICAgICBpZiAodXBkYXRlRG9tSXRlbXMgPT09IHZvaWQgMCkgeyB1cGRhdGVEb21JdGVtcyA9IHRydWU7IH1cclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLm9uSXRlbVNlbGVjdGVkRXZlbnQuY2FsbCh0aGlzLCB2YWx1ZSk7XHJcbiAgICAgICAgaWYgKHVwZGF0ZURvbUl0ZW1zKSB7XHJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlRG9tSXRlbXModmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICByZXR1cm4gU2VsZWN0Qm94O1xyXG59KGxpc3RzZWxlY3Rvcl8xLkxpc3RTZWxlY3RvcikpO1xyXG5leHBvcnRzLlNlbGVjdEJveCA9IFNlbGVjdEJveDtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3NlbGVjdGJveC50c1xuLy8gbW9kdWxlIGlkID0gMjFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBjb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudFwiKTtcclxudmFyIGV2ZW50ZGlzcGF0Y2hlcl8xID0gcmVxdWlyZShcIi4uL2V2ZW50ZGlzcGF0Y2hlclwiKTtcclxudmFyIGFycmF5dXRpbHNfMSA9IHJlcXVpcmUoXCIuLi9hcnJheXV0aWxzXCIpO1xyXG52YXIgTGlzdFNlbGVjdG9yID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhMaXN0U2VsZWN0b3IsIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBMaXN0U2VsZWN0b3IoY29uZmlnKSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLmxpc3RTZWxlY3RvckV2ZW50cyA9IHtcclxuICAgICAgICAgICAgb25JdGVtQWRkZWQ6IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKSxcclxuICAgICAgICAgICAgb25JdGVtUmVtb3ZlZDogbmV3IGV2ZW50ZGlzcGF0Y2hlcl8xLkV2ZW50RGlzcGF0Y2hlcigpLFxyXG4gICAgICAgICAgICBvbkl0ZW1TZWxlY3RlZDogbmV3IGV2ZW50ZGlzcGF0Y2hlcl8xLkV2ZW50RGlzcGF0Y2hlcigpLFxyXG4gICAgICAgIH07XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGl0ZW1zOiBbXSxcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1saXN0c2VsZWN0b3InLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgX3RoaXMuaXRlbXMgPSBfdGhpcy5jb25maWcuaXRlbXM7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgTGlzdFNlbGVjdG9yLnByb3RvdHlwZS5nZXRJdGVtSW5kZXggPSBmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgZm9yICh2YXIgaW5kZXggaW4gdGhpcy5pdGVtcykge1xyXG4gICAgICAgICAgICBpZiAoa2V5ID09PSB0aGlzLml0ZW1zW2luZGV4XS5rZXkpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBwYXJzZUludChpbmRleCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIC0xO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQ2hlY2tzIGlmIHRoZSBzcGVjaWZpZWQgaXRlbSBpcyBwYXJ0IG9mIHRoaXMgc2VsZWN0b3IuXHJcbiAgICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkgb2YgdGhlIGl0ZW0gdG8gY2hlY2tcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlIGlmIHRoZSBpdGVtIGlzIHBhcnQgb2YgdGhpcyBzZWxlY3RvciwgZWxzZSBmYWxzZVxyXG4gICAgICovXHJcbiAgICBMaXN0U2VsZWN0b3IucHJvdG90eXBlLmhhc0l0ZW0gPSBmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SXRlbUluZGV4KGtleSkgPiAtMTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEFkZHMgYW4gaXRlbSB0byB0aGlzIHNlbGVjdG9yIGJ5IGFwcGVuZGluZyBpdCB0byB0aGUgZW5kIG9mIHRoZSBsaXN0IG9mIGl0ZW1zLiBJZiBhbiBpdGVtIHdpdGggdGhlIHNwZWNpZmllZFxyXG4gICAgICoga2V5IGFscmVhZHkgZXhpc3RzLCBpdCBpcyByZXBsYWNlZC5cclxuICAgICAqIEBwYXJhbSBrZXkgdGhlIGtleSBvZiB0aGUgaXRlbSB0byBhZGRcclxuICAgICAqIEBwYXJhbSBsYWJlbCB0aGUgKGh1bWFuLXJlYWRhYmxlKSBsYWJlbCBvZiB0aGUgaXRlbSB0byBhZGRcclxuICAgICAqL1xyXG4gICAgTGlzdFNlbGVjdG9yLnByb3RvdHlwZS5hZGRJdGVtID0gZnVuY3Rpb24gKGtleSwgbGFiZWwpIHtcclxuICAgICAgICB0aGlzLnJlbW92ZUl0ZW0oa2V5KTsgLy8gVHJ5IHRvIHJlbW92ZSBrZXkgZmlyc3QgdG8gZ2V0IG92ZXJ3cml0ZSBiZWhhdmlvciBhbmQgYXZvaWQgZHVwbGljYXRlIGtleXNcclxuICAgICAgICB0aGlzLml0ZW1zLnB1c2goeyBrZXk6IGtleSwgbGFiZWw6IGxhYmVsIH0pO1xyXG4gICAgICAgIHRoaXMub25JdGVtQWRkZWRFdmVudChrZXkpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmVtb3ZlcyBhbiBpdGVtIGZyb20gdGhpcyBzZWxlY3Rvci5cclxuICAgICAqIEBwYXJhbSBrZXkgdGhlIGtleSBvZiB0aGUgaXRlbSB0byByZW1vdmVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlIGlmIHJlbW92YWwgd2FzIHN1Y2Nlc3NmdWwsIGZhbHNlIGlmIHRoZSBpdGVtIGlzIG5vdCBwYXJ0IG9mIHRoaXMgc2VsZWN0b3JcclxuICAgICAqL1xyXG4gICAgTGlzdFNlbGVjdG9yLnByb3RvdHlwZS5yZW1vdmVJdGVtID0gZnVuY3Rpb24gKGtleSkge1xyXG4gICAgICAgIHZhciBpbmRleCA9IHRoaXMuZ2V0SXRlbUluZGV4KGtleSk7XHJcbiAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgICAgICAgYXJyYXl1dGlsc18xLkFycmF5VXRpbHMucmVtb3ZlKHRoaXMuaXRlbXMsIHRoaXMuaXRlbXNbaW5kZXhdKTtcclxuICAgICAgICAgICAgdGhpcy5vbkl0ZW1SZW1vdmVkRXZlbnQoa2V5KTtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFNlbGVjdHMgYW4gaXRlbSBmcm9tIHRoZSBpdGVtcyBpbiB0aGlzIHNlbGVjdG9yLlxyXG4gICAgICogQHBhcmFtIGtleSB0aGUga2V5IG9mIHRoZSBpdGVtIHRvIHNlbGVjdFxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaXMgdGhlIHNlbGVjdGlvbiB3YXMgc3VjY2Vzc2Z1bCwgZmFsc2UgaWYgdGhlIHNlbGVjdGVkIGl0ZW0gaXMgbm90IHBhcnQgb2YgdGhlIHNlbGVjdG9yXHJcbiAgICAgKi9cclxuICAgIExpc3RTZWxlY3Rvci5wcm90b3R5cGUuc2VsZWN0SXRlbSA9IGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICBpZiAoa2V5ID09PSB0aGlzLnNlbGVjdGVkSXRlbSkge1xyXG4gICAgICAgICAgICAvLyBpdGVtQ29uZmlnIGlzIGFscmVhZHkgc2VsZWN0ZWQsIHN1cHByZXNzIGFueSBmdXJ0aGVyIGFjdGlvblxyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5nZXRJdGVtSW5kZXgoa2V5KTtcclxuICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xyXG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkSXRlbSA9IGtleTtcclxuICAgICAgICAgICAgdGhpcy5vbkl0ZW1TZWxlY3RlZEV2ZW50KGtleSk7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBrZXkgb2YgdGhlIHNlbGVjdGVkIGl0ZW0uXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSB0aGUga2V5IG9mIHRoZSBzZWxlY3RlZCBpdGVtIG9yIG51bGwgaWYgbm8gaXRlbSBpcyBzZWxlY3RlZFxyXG4gICAgICovXHJcbiAgICBMaXN0U2VsZWN0b3IucHJvdG90eXBlLmdldFNlbGVjdGVkSXRlbSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3RlZEl0ZW07XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIGFsbCBpdGVtcyBmcm9tIHRoaXMgc2VsZWN0b3IuXHJcbiAgICAgKi9cclxuICAgIExpc3RTZWxlY3Rvci5wcm90b3R5cGUuY2xlYXJJdGVtcyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBsb2NhbCBjb3B5IGZvciBpdGVyYXRpb24gYWZ0ZXIgY2xlYXJcclxuICAgICAgICB2YXIgaXRlbXMgPSB0aGlzLml0ZW1zO1xyXG4gICAgICAgIC8vIGNsZWFyIGl0ZW1zXHJcbiAgICAgICAgdGhpcy5pdGVtcyA9IFtdO1xyXG4gICAgICAgIC8vIGNsZWFyIHRoZSBzZWxlY3Rpb24gYXMgdGhlIHNlbGVjdGVkIGl0ZW0gaXMgYWxzbyByZW1vdmVkXHJcbiAgICAgICAgdGhpcy5zZWxlY3RlZEl0ZW0gPSBudWxsO1xyXG4gICAgICAgIC8vIGZpcmUgZXZlbnRzXHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBpdGVtc18xID0gaXRlbXM7IF9pIDwgaXRlbXNfMS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgdmFyIGl0ZW0gPSBpdGVtc18xW19pXTtcclxuICAgICAgICAgICAgdGhpcy5vbkl0ZW1SZW1vdmVkRXZlbnQoaXRlbS5rZXkpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBpdGVtcyBpbiB0aGlzIHNlbGVjdG9yLlxyXG4gICAgICogQHJldHVybnMge251bWJlcn1cclxuICAgICAqL1xyXG4gICAgTGlzdFNlbGVjdG9yLnByb3RvdHlwZS5pdGVtQ291bnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMuaXRlbXMpLmxlbmd0aDtcclxuICAgIH07XHJcbiAgICBMaXN0U2VsZWN0b3IucHJvdG90eXBlLm9uSXRlbUFkZGVkRXZlbnQgPSBmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgdGhpcy5saXN0U2VsZWN0b3JFdmVudHMub25JdGVtQWRkZWQuZGlzcGF0Y2godGhpcywga2V5KTtcclxuICAgIH07XHJcbiAgICBMaXN0U2VsZWN0b3IucHJvdG90eXBlLm9uSXRlbVJlbW92ZWRFdmVudCA9IGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICB0aGlzLmxpc3RTZWxlY3RvckV2ZW50cy5vbkl0ZW1SZW1vdmVkLmRpc3BhdGNoKHRoaXMsIGtleSk7XHJcbiAgICB9O1xyXG4gICAgTGlzdFNlbGVjdG9yLnByb3RvdHlwZS5vbkl0ZW1TZWxlY3RlZEV2ZW50ID0gZnVuY3Rpb24gKGtleSkge1xyXG4gICAgICAgIHRoaXMubGlzdFNlbGVjdG9yRXZlbnRzLm9uSXRlbVNlbGVjdGVkLmRpc3BhdGNoKHRoaXMsIGtleSk7XHJcbiAgICB9O1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KExpc3RTZWxlY3Rvci5wcm90b3R5cGUsIFwib25JdGVtQWRkZWRcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldHMgdGhlIGV2ZW50IHRoYXQgaXMgZmlyZWQgd2hlbiBhbiBpdGVtIGlzIGFkZGVkIHRvIHRoZSBsaXN0IG9mIGl0ZW1zLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtFdmVudDxMaXN0U2VsZWN0b3I8Q29uZmlnPiwgc3RyaW5nPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubGlzdFNlbGVjdG9yRXZlbnRzLm9uSXRlbUFkZGVkLmdldEV2ZW50KCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoTGlzdFNlbGVjdG9yLnByb3RvdHlwZSwgXCJvbkl0ZW1SZW1vdmVkXCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXRzIHRoZSBldmVudCB0aGF0IGlzIGZpcmVkIHdoZW4gYW4gaXRlbSBpcyByZW1vdmVkIGZyb20gdGhlIGxpc3Qgb2YgaXRlbXMuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50PExpc3RTZWxlY3RvcjxDb25maWc+LCBzdHJpbmc+fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5saXN0U2VsZWN0b3JFdmVudHMub25JdGVtUmVtb3ZlZC5nZXRFdmVudCgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KExpc3RTZWxlY3Rvci5wcm90b3R5cGUsIFwib25JdGVtU2VsZWN0ZWRcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldHMgdGhlIGV2ZW50IHRoYXQgaXMgZmlyZWQgd2hlbiBhbiBpdGVtIGlzIHNlbGVjdGVkIGZyb20gdGhlIGxpc3Qgb2YgaXRlbXMuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50PExpc3RTZWxlY3RvcjxDb25maWc+LCBzdHJpbmc+fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5saXN0U2VsZWN0b3JFdmVudHMub25JdGVtU2VsZWN0ZWQuZ2V0RXZlbnQoKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIHJldHVybiBMaXN0U2VsZWN0b3I7XHJcbn0oY29tcG9uZW50XzEuQ29tcG9uZW50KSk7XHJcbmV4cG9ydHMuTGlzdFNlbGVjdG9yID0gTGlzdFNlbGVjdG9yO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvbGlzdHNlbGVjdG9yLnRzXG4vLyBtb2R1bGUgaWQgPSAyMlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGNvbnRhaW5lcl8xID0gcmVxdWlyZShcIi4vY29udGFpbmVyXCIpO1xyXG52YXIgdm9sdW1lc2xpZGVyXzEgPSByZXF1aXJlKFwiLi92b2x1bWVzbGlkZXJcIik7XHJcbnZhciB2b2x1bWV0b2dnbGVidXR0b25fMSA9IHJlcXVpcmUoXCIuL3ZvbHVtZXRvZ2dsZWJ1dHRvblwiKTtcclxudmFyIHRpbWVvdXRfMSA9IHJlcXVpcmUoXCIuLi90aW1lb3V0XCIpO1xyXG4vKipcclxuICogQSBjb21wb3NpdGUgdm9sdW1lIGNvbnRyb2wgdGhhdCBjb25zaXN0cyBvZiBhbmQgaW50ZXJuYWxseSBtYW5hZ2VzIGEgdm9sdW1lIGNvbnRyb2wgYnV0dG9uIHRoYXQgY2FuIGJlIHVzZWRcclxuICogZm9yIG11dGluZywgYW5kIGEgKGRlcGVuZGluZyBvbiB0aGUgQ1NTIHN0eWxlLCBlLmcuIHNsaWRlLW91dCkgdm9sdW1lIGNvbnRyb2wgYmFyLlxyXG4gKi9cclxudmFyIFZvbHVtZUNvbnRyb2xCdXR0b24gPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKFZvbHVtZUNvbnRyb2xCdXR0b24sIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBWb2x1bWVDb250cm9sQnV0dG9uKGNvbmZpZykge1xyXG4gICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy52b2x1bWVUb2dnbGVCdXR0b24gPSBuZXcgdm9sdW1ldG9nZ2xlYnV0dG9uXzEuVm9sdW1lVG9nZ2xlQnV0dG9uKCk7XHJcbiAgICAgICAgX3RoaXMudm9sdW1lU2xpZGVyID0gbmV3IHZvbHVtZXNsaWRlcl8xLlZvbHVtZVNsaWRlcih7XHJcbiAgICAgICAgICAgIHZlcnRpY2FsOiBjb25maWcudmVydGljYWwgIT0gbnVsbCA/IGNvbmZpZy52ZXJ0aWNhbCA6IHRydWUsXHJcbiAgICAgICAgICAgIGhpZGRlbjogdHJ1ZSxcclxuICAgICAgICB9KTtcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS12b2x1bWVjb250cm9sYnV0dG9uJyxcclxuICAgICAgICAgICAgY29tcG9uZW50czogW190aGlzLnZvbHVtZVRvZ2dsZUJ1dHRvbiwgX3RoaXMudm9sdW1lU2xpZGVyXSxcclxuICAgICAgICAgICAgaGlkZURlbGF5OiA1MDAsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBWb2x1bWVDb250cm9sQnV0dG9uLnByb3RvdHlwZS5jb25maWd1cmUgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY29uZmlndXJlLmNhbGwodGhpcywgcGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIHZhciB2b2x1bWVUb2dnbGVCdXR0b24gPSB0aGlzLmdldFZvbHVtZVRvZ2dsZUJ1dHRvbigpO1xyXG4gICAgICAgIHZhciB2b2x1bWVTbGlkZXIgPSB0aGlzLmdldFZvbHVtZVNsaWRlcigpO1xyXG4gICAgICAgIHRoaXMudm9sdW1lU2xpZGVySGlkZVRpbWVvdXQgPSBuZXcgdGltZW91dF8xLlRpbWVvdXQodGhpcy5nZXRDb25maWcoKS5oaWRlRGVsYXksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdm9sdW1lU2xpZGVyLmhpZGUoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvKlxyXG4gICAgICAgICAqIFZvbHVtZSBTbGlkZXIgdmlzaWJpbGl0eSBoYW5kbGluZ1xyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogVGhlIHZvbHVtZSBzbGlkZXIgc2hhbGwgYmUgdmlzaWJsZSB3aGlsZSB0aGUgdXNlciBob3ZlcnMgdGhlIG11dGUgdG9nZ2xlIGJ1dHRvbiwgd2hpbGUgdGhlIHVzZXIgaG92ZXJzIHRoZVxyXG4gICAgICAgICAqIHZvbHVtZSBzbGlkZXIsIGFuZCB3aGlsZSB0aGUgdXNlciBzbGlkZXMgdGhlIHZvbHVtZSBzbGlkZXIuIElmIG5vbmUgb2YgdGhlc2Ugc2l0dWF0aW9ucyBhcmUgdHJ1ZSwgdGhlIHNsaWRlclxyXG4gICAgICAgICAqIHNoYWxsIGRpc2FwcGVhci5cclxuICAgICAgICAgKi9cclxuICAgICAgICB2YXIgdm9sdW1lU2xpZGVySG92ZXJlZCA9IGZhbHNlO1xyXG4gICAgICAgIHZvbHVtZVRvZ2dsZUJ1dHRvbi5nZXREb21FbGVtZW50KCkub24oJ21vdXNlZW50ZXInLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIC8vIFNob3cgdm9sdW1lIHNsaWRlciB3aGVuIG1vdXNlIGVudGVycyB0aGUgYnV0dG9uIGFyZWFcclxuICAgICAgICAgICAgaWYgKHZvbHVtZVNsaWRlci5pc0hpZGRlbigpKSB7XHJcbiAgICAgICAgICAgICAgICB2b2x1bWVTbGlkZXIuc2hvdygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIEF2b2lkIGhpZGluZyBvZiB0aGUgc2xpZGVyIHdoZW4gYnV0dG9uIGlzIGhvdmVyZWRcclxuICAgICAgICAgICAgX3RoaXMudm9sdW1lU2xpZGVySGlkZVRpbWVvdXQuY2xlYXIoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB2b2x1bWVUb2dnbGVCdXR0b24uZ2V0RG9tRWxlbWVudCgpLm9uKCdtb3VzZWxlYXZlJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvLyBIaWRlIHNsaWRlciBkZWxheWVkIHdoZW4gYnV0dG9uIGlzIGxlZnRcclxuICAgICAgICAgICAgX3RoaXMudm9sdW1lU2xpZGVySGlkZVRpbWVvdXQucmVzZXQoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB2b2x1bWVTbGlkZXIuZ2V0RG9tRWxlbWVudCgpLm9uKCdtb3VzZWVudGVyJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvLyBXaGVuIHRoZSBzbGlkZXIgaXMgZW50ZXJlZCwgY2FuY2VsIHRoZSBoaWRlIHRpbWVvdXQgYWN0aXZhdGVkIGJ5IGxlYXZpbmcgdGhlIGJ1dHRvblxyXG4gICAgICAgICAgICBfdGhpcy52b2x1bWVTbGlkZXJIaWRlVGltZW91dC5jbGVhcigpO1xyXG4gICAgICAgICAgICB2b2x1bWVTbGlkZXJIb3ZlcmVkID0gdHJ1ZTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB2b2x1bWVTbGlkZXIuZ2V0RG9tRWxlbWVudCgpLm9uKCdtb3VzZWxlYXZlJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvLyBXaGVuIG1vdXNlIGxlYXZlcyB0aGUgc2xpZGVyLCBvbmx5IGhpZGUgaXQgaWYgdGhlcmUgaXMgbm8gc2xpZGUgb3BlcmF0aW9uIGluIHByb2dyZXNzXHJcbiAgICAgICAgICAgIGlmICh2b2x1bWVTbGlkZXIuaXNTZWVraW5nKCkpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLnZvbHVtZVNsaWRlckhpZGVUaW1lb3V0LmNsZWFyKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy52b2x1bWVTbGlkZXJIaWRlVGltZW91dC5yZXNldCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZvbHVtZVNsaWRlckhvdmVyZWQgPSBmYWxzZTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB2b2x1bWVTbGlkZXIub25TZWVrZWQuc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgLy8gV2hlbiBhIHNsaWRlIG9wZXJhdGlvbiBpcyBkb25lIGFuZCB0aGUgc2xpZGVyIG5vdCBob3ZlcmVkIChtb3VzZSBvdXRzaWRlIHNsaWRlciksIGhpZGUgc2xpZGVyIGRlbGF5ZWRcclxuICAgICAgICAgICAgaWYgKCF2b2x1bWVTbGlkZXJIb3ZlcmVkKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy52b2x1bWVTbGlkZXJIaWRlVGltZW91dC5yZXNldCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgVm9sdW1lQ29udHJvbEJ1dHRvbi5wcm90b3R5cGUucmVsZWFzZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnJlbGVhc2UuY2FsbCh0aGlzKTtcclxuICAgICAgICB0aGlzLnZvbHVtZVNsaWRlckhpZGVUaW1lb3V0LmNsZWFyKCk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBQcm92aWRlcyBhY2Nlc3MgdG8gdGhlIGludGVybmFsbHkgbWFuYWdlZCB2b2x1bWUgdG9nZ2xlIGJ1dHRvbi5cclxuICAgICAqIEByZXR1cm5zIHtWb2x1bWVUb2dnbGVCdXR0b259XHJcbiAgICAgKi9cclxuICAgIFZvbHVtZUNvbnRyb2xCdXR0b24ucHJvdG90eXBlLmdldFZvbHVtZVRvZ2dsZUJ1dHRvbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy52b2x1bWVUb2dnbGVCdXR0b247XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBQcm92aWRlcyBhY2Nlc3MgdG8gdGhlIGludGVybmFsbHkgbWFuYWdlZCB2b2x1bWUgc2lsZGVyLlxyXG4gICAgICogQHJldHVybnMge1ZvbHVtZVNsaWRlcn1cclxuICAgICAqL1xyXG4gICAgVm9sdW1lQ29udHJvbEJ1dHRvbi5wcm90b3R5cGUuZ2V0Vm9sdW1lU2xpZGVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZvbHVtZVNsaWRlcjtcclxuICAgIH07XHJcbiAgICByZXR1cm4gVm9sdW1lQ29udHJvbEJ1dHRvbjtcclxufShjb250YWluZXJfMS5Db250YWluZXIpKTtcclxuZXhwb3J0cy5Wb2x1bWVDb250cm9sQnV0dG9uID0gVm9sdW1lQ29udHJvbEJ1dHRvbjtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3ZvbHVtZWNvbnRyb2xidXR0b24udHNcbi8vIG1vZHVsZSBpZCA9IDIzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgc2Vla2Jhcl8xID0gcmVxdWlyZShcIi4vc2Vla2JhclwiKTtcclxuLyoqXHJcbiAqIEEgc2ltcGxlIHZvbHVtZSBzbGlkZXIgY29tcG9uZW50IHRvIGFkanVzdCB0aGUgcGxheWVyJ3Mgdm9sdW1lIHNldHRpbmcuXHJcbiAqL1xyXG52YXIgVm9sdW1lU2xpZGVyID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhWb2x1bWVTbGlkZXIsIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBWb2x1bWVTbGlkZXIoY29uZmlnKSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLXZvbHVtZXNsaWRlcicsXHJcbiAgICAgICAgICAgIGhpZGVJZlZvbHVtZUNvbnRyb2xQcm9oaWJpdGVkOiB0cnVlLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgVm9sdW1lU2xpZGVyLnByb3RvdHlwZS5jb25maWd1cmUgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY29uZmlndXJlLmNhbGwodGhpcywgcGxheWVyLCB1aW1hbmFnZXIsIGZhbHNlKTtcclxuICAgICAgICB2YXIgY29uZmlnID0gdGhpcy5nZXRDb25maWcoKTtcclxuICAgICAgICBpZiAoY29uZmlnLmhpZGVJZlZvbHVtZUNvbnRyb2xQcm9oaWJpdGVkICYmICF0aGlzLmRldGVjdFZvbHVtZUNvbnRyb2xBdmFpbGFiaWxpdHkocGxheWVyKSkge1xyXG4gICAgICAgICAgICB0aGlzLmhpZGUoKTtcclxuICAgICAgICAgICAgLy8gV2UgY2FuIGp1c3QgcmV0dXJuIGZyb20gaGVyZSwgYmVjYXVzZSB0aGUgdXNlciB3aWxsIG5ldmVyIGludGVyYWN0IHdpdGggdGhlIGNvbnRyb2wgYW5kIGFueSBjb25maWd1cmVkXHJcbiAgICAgICAgICAgIC8vIGZ1bmN0aW9uYWxpdHkgd291bGQgb25seSBlYXQgcmVzb3VyY2VzIGZvciBubyByZWFzb24uXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHZvbHVtZUNoYW5nZUhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChwbGF5ZXIuaXNNdXRlZCgpKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRQbGF5YmFja1Bvc2l0aW9uKDApO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0QnVmZmVyUG9zaXRpb24oMCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRQbGF5YmFja1Bvc2l0aW9uKHBsYXllci5nZXRWb2x1bWUoKSk7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRCdWZmZXJQb3NpdGlvbihwbGF5ZXIuZ2V0Vm9sdW1lKCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9SRUFEWSwgdm9sdW1lQ2hhbmdlSGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fVk9MVU1FX0NIQU5HRUQsIHZvbHVtZUNoYW5nZUhhbmRsZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX01VVEVELCB2b2x1bWVDaGFuZ2VIYW5kbGVyKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9VTk1VVEVELCB2b2x1bWVDaGFuZ2VIYW5kbGVyKTtcclxuICAgICAgICB0aGlzLm9uU2Vla1ByZXZpZXcuc3Vic2NyaWJlUmF0ZUxpbWl0ZWQoZnVuY3Rpb24gKHNlbmRlciwgYXJncykge1xyXG4gICAgICAgICAgICBpZiAoYXJncy5zY3J1YmJpbmcpIHtcclxuICAgICAgICAgICAgICAgIHBsYXllci5zZXRWb2x1bWUoYXJncy5wb3NpdGlvbiwgVm9sdW1lU2xpZGVyLmlzc3Vlck5hbWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSwgNTApO1xyXG4gICAgICAgIHRoaXMub25TZWVrZWQuc3Vic2NyaWJlKGZ1bmN0aW9uIChzZW5kZXIsIHBlcmNlbnRhZ2UpIHtcclxuICAgICAgICAgICAgcGxheWVyLnNldFZvbHVtZShwZXJjZW50YWdlLCBWb2x1bWVTbGlkZXIuaXNzdWVyTmFtZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gVXBkYXRlIHRoZSB2b2x1bWUgc2xpZGVyIG1hcmtlciB3aGVuIHRoZSBwbGF5ZXIgcmVzaXplZCwgYSBzb3VyY2UgaXMgbG9hZGVkIGFuZCBwbGF5ZXIgaXMgcmVhZHksXHJcbiAgICAgICAgLy8gb3IgdGhlIFVJIGlzIGNvbmZpZ3VyZWQuIENoZWNrIHRoZSBzZWVrYmFyIGZvciBhIGRldGFpbGVkIGRlc2NyaXB0aW9uLlxyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BMQVlFUl9SRVNJWkUsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMucmVmcmVzaFBsYXliYWNrUG9zaXRpb24oKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9SRUFEWSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5yZWZyZXNoUGxheWJhY2tQb3NpdGlvbigpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHVpbWFuYWdlci5vbkNvbmZpZ3VyZWQuc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMucmVmcmVzaFBsYXliYWNrUG9zaXRpb24oKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBJbml0IHZvbHVtZSBiYXJcclxuICAgICAgICB2b2x1bWVDaGFuZ2VIYW5kbGVyKCk7XHJcbiAgICB9O1xyXG4gICAgVm9sdW1lU2xpZGVyLnByb3RvdHlwZS5kZXRlY3RWb2x1bWVDb250cm9sQXZhaWxhYmlsaXR5ID0gZnVuY3Rpb24gKHBsYXllcikge1xyXG4gICAgICAgIC8vIFN0b3JlIGN1cnJlbnQgcGxheWVyIHN0YXRlIHNvIHdlIGNhbiByZXN0b3JlIGl0IGxhdGVyXHJcbiAgICAgICAgdmFyIHZvbHVtZSA9IHBsYXllci5nZXRWb2x1bWUoKTtcclxuICAgICAgICB2YXIgbXV0ZWQgPSBwbGF5ZXIuaXNNdXRlZCgpO1xyXG4gICAgICAgIHZhciBwbGF5aW5nID0gcGxheWVyLmlzUGxheWluZygpO1xyXG4gICAgICAgIC8qXHJcbiAgICAgICAgICogXCJPbiBpT1MgZGV2aWNlcywgdGhlIGF1ZGlvIGxldmVsIGlzIGFsd2F5cyB1bmRlciB0aGUgdXNlcuKAmXMgcGh5c2ljYWwgY29udHJvbC4gVGhlIHZvbHVtZSBwcm9wZXJ0eSBpcyBub3RcclxuICAgICAgICAgKiBzZXR0YWJsZSBpbiBKYXZhU2NyaXB0LiBSZWFkaW5nIHRoZSB2b2x1bWUgcHJvcGVydHkgYWx3YXlzIHJldHVybnMgMS5cIlxyXG4gICAgICAgICAqIGh0dHBzOi8vZGV2ZWxvcGVyLmFwcGxlLmNvbS9saWJyYXJ5L2NvbnRlbnQvZG9jdW1lbnRhdGlvbi9BdWRpb1ZpZGVvL0NvbmNlcHR1YWwvVXNpbmdfSFRNTDVfQXVkaW9fVmlkZW8vRGV2aWNlLVNwZWNpZmljQ29uc2lkZXJhdGlvbnMvRGV2aWNlLVNwZWNpZmljQ29uc2lkZXJhdGlvbnMuaHRtbFxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogT3VyIHBsYXllciBBUEkgcmV0dXJucyBhIHZvbHVtZSByYW5nZSBvZiBbMCwgMTAwXSBzbyB3ZSBuZWVkIHRvIGNoZWNrIGZvciAxMDAgaW5zdGVhZCBvZiAxLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIC8vIE9ubHkgaWYgdGhlIHZvbHVtZSBpcyAxMDAsIHRoZXJlJ3MgdGhlIHBvc3NpYmlsaXR5IHdlIGFyZSBvbiBhIHZvbHVtZS1jb250cm9sLXJlc3RyaWN0ZWQgaU9TIGRldmljZVxyXG4gICAgICAgIGlmICh2b2x1bWUgPT09IDEwMCkge1xyXG4gICAgICAgICAgICAvLyBXZSBzZXQgdGhlIHZvbHVtZSB0byB6ZXJvICh0aGF0J3MgdGhlIG9ubHkgdmFsdWUgdGhhdCBkb2VzIG5vdCB1bm11dGUgYSBtdXRlZCBwbGF5ZXIhKVxyXG4gICAgICAgICAgICBwbGF5ZXIuc2V0Vm9sdW1lKDAsIFZvbHVtZVNsaWRlci5pc3N1ZXJOYW1lKTtcclxuICAgICAgICAgICAgLy8gVGhlbiB3ZSBjaGVjayBpZiB0aGUgdmFsdWUgaXMgc3RpbGwgMTAwXHJcbiAgICAgICAgICAgIGlmIChwbGF5ZXIuZ2V0Vm9sdW1lKCkgPT09IDEwMCkge1xyXG4gICAgICAgICAgICAgICAgLy8gSWYgdGhlIHZvbHVtZSBzdGF5ZWQgYXQgMTAwLCB3ZSdyZSBvbiBhIHZvbHVtZS1jb250cm9sLXJlc3RyaWN0ZWQgZGV2aWNlXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBXZSBjYW4gY29udHJvbCB2b2x1bWUsIHNvIHdlIG11c3QgcmVzdG9yZSB0aGUgcHJldmlvdXMgcGxheWVyIHN0YXRlXHJcbiAgICAgICAgICAgICAgICBwbGF5ZXIuc2V0Vm9sdW1lKHZvbHVtZSwgVm9sdW1lU2xpZGVyLmlzc3Vlck5hbWUpO1xyXG4gICAgICAgICAgICAgICAgaWYgKG11dGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGxheWVyLm11dGUoVm9sdW1lU2xpZGVyLmlzc3Vlck5hbWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHBsYXlpbmcpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBUaGUgdm9sdW1lIHJlc3RvcmUgYWJvdmUgcGF1c2VzIGF1dG9wbGF5IG9uIG1vYmlsZSBkZXZpY2VzIChlLmcuIEFuZHJvaWQpIHNvIHdlIG5lZWQgdG8gcmVzdW1lIHBsYXliYWNrXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gKFdlIGNhbm5vdCBjaGVjayBpc1BhdXNlZCgpIGhlcmUgYmVjYXVzZSBpdCBpcyBub3Qgc2V0IHdoZW4gcGxheWJhY2sgaXMgcHJvaGliaXRlZCBieSB0aGUgbW9iaWxlIHBsYXRmb3JtKVxyXG4gICAgICAgICAgICAgICAgICAgIHBsYXllci5wbGF5KFZvbHVtZVNsaWRlci5pc3N1ZXJOYW1lKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBWb2x1bWUgaXMgbm90IDEwMCwgc28gd2UncmUgZGVmaW5pdGVseSBub3Qgb24gYSB2b2x1bWUtY29udHJvbC1yZXN0cmljdGVkIGlPUyBkZXZpY2VcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHJldHVybiBWb2x1bWVTbGlkZXI7XHJcbn0oc2Vla2Jhcl8xLlNlZWtCYXIpKTtcclxuVm9sdW1lU2xpZGVyLmlzc3Vlck5hbWUgPSAndWknO1xyXG5leHBvcnRzLlZvbHVtZVNsaWRlciA9IFZvbHVtZVNsaWRlcjtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3ZvbHVtZXNsaWRlci50c1xuLy8gbW9kdWxlIGlkID0gMjRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciB0b2dnbGVidXR0b25fMSA9IHJlcXVpcmUoXCIuL3RvZ2dsZWJ1dHRvblwiKTtcclxuLyoqXHJcbiAqIEEgYnV0dG9uIHRoYXQgdG9nZ2xlcyBhdWRpbyBtdXRpbmcuXHJcbiAqL1xyXG52YXIgVm9sdW1lVG9nZ2xlQnV0dG9uID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhWb2x1bWVUb2dnbGVCdXR0b24sIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBWb2x1bWVUb2dnbGVCdXR0b24oY29uZmlnKSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLXZvbHVtZXRvZ2dsZWJ1dHRvbicsXHJcbiAgICAgICAgICAgIHRleHQ6ICdWb2x1bWUvTXV0ZScsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBWb2x1bWVUb2dnbGVCdXR0b24ucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jb25maWd1cmUuY2FsbCh0aGlzLCBwbGF5ZXIsIHVpbWFuYWdlcik7XHJcbiAgICAgICAgdmFyIG11dGVTdGF0ZUhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChwbGF5ZXIuaXNNdXRlZCgpKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5vbigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMub2ZmKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciB2b2x1bWVMZXZlbEhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIC8vIFRvZ2dsZSBsb3cgY2xhc3MgdG8gZGlzcGxheSBsb3cgdm9sdW1lIGljb24gYmVsb3cgNTAlIHZvbHVtZVxyXG4gICAgICAgICAgICBpZiAocGxheWVyLmdldFZvbHVtZSgpIDwgNTApIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmdldERvbUVsZW1lbnQoKS5hZGRDbGFzcyhfdGhpcy5wcmVmaXhDc3MoJ2xvdycpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmdldERvbUVsZW1lbnQoKS5yZW1vdmVDbGFzcyhfdGhpcy5wcmVmaXhDc3MoJ2xvdycpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fTVVURUQsIG11dGVTdGF0ZUhhbmRsZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1VOTVVURUQsIG11dGVTdGF0ZUhhbmRsZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1ZPTFVNRV9DSEFOR0VELCB2b2x1bWVMZXZlbEhhbmRsZXIpO1xyXG4gICAgICAgIHRoaXMub25DbGljay5zdWJzY3JpYmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAocGxheWVyLmlzTXV0ZWQoKSkge1xyXG4gICAgICAgICAgICAgICAgcGxheWVyLnVubXV0ZSgndWktdm9sdW1ldG9nZ2xlYnV0dG9uJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBwbGF5ZXIubXV0ZSgndWktdm9sdW1ldG9nZ2xlYnV0dG9uJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBTdGFydHVwIGluaXRcclxuICAgICAgICBtdXRlU3RhdGVIYW5kbGVyKCk7XHJcbiAgICAgICAgdm9sdW1lTGV2ZWxIYW5kbGVyKCk7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFZvbHVtZVRvZ2dsZUJ1dHRvbjtcclxufSh0b2dnbGVidXR0b25fMS5Ub2dnbGVCdXR0b24pKTtcclxuZXhwb3J0cy5Wb2x1bWVUb2dnbGVCdXR0b24gPSBWb2x1bWVUb2dnbGVCdXR0b247XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy92b2x1bWV0b2dnbGVidXR0b24udHNcbi8vIG1vZHVsZSBpZCA9IDI1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgY29udGFpbmVyXzEgPSByZXF1aXJlKFwiLi9jb250YWluZXJcIik7XHJcbnZhciBsYWJlbF8xID0gcmVxdWlyZShcIi4vbGFiZWxcIik7XHJcbnZhciB0dm5vaXNlY2FudmFzXzEgPSByZXF1aXJlKFwiLi90dm5vaXNlY2FudmFzXCIpO1xyXG4vKipcclxuICogT3ZlcmxheXMgdGhlIHBsYXllciBhbmQgZGlzcGxheXMgZXJyb3IgbWVzc2FnZXMuXHJcbiAqL1xyXG52YXIgRXJyb3JNZXNzYWdlT3ZlcmxheSA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoRXJyb3JNZXNzYWdlT3ZlcmxheSwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIEVycm9yTWVzc2FnZU92ZXJsYXkoY29uZmlnKSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLmVycm9yTGFiZWwgPSBuZXcgbGFiZWxfMS5MYWJlbCh7IGNzc0NsYXNzOiAndWktZXJyb3JtZXNzYWdlLWxhYmVsJyB9KTtcclxuICAgICAgICBfdGhpcy50dk5vaXNlQmFja2dyb3VuZCA9IG5ldyB0dm5vaXNlY2FudmFzXzEuVHZOb2lzZUNhbnZhcygpO1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLWVycm9ybWVzc2FnZS1vdmVybGF5JyxcclxuICAgICAgICAgICAgY29tcG9uZW50czogW190aGlzLnR2Tm9pc2VCYWNrZ3JvdW5kLCBfdGhpcy5lcnJvckxhYmVsXSxcclxuICAgICAgICAgICAgaGlkZGVuOiB0cnVlLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgRXJyb3JNZXNzYWdlT3ZlcmxheS5wcm90b3R5cGUuY29uZmlndXJlID0gZnVuY3Rpb24gKHBsYXllciwgdWltYW5hZ2VyKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNvbmZpZ3VyZS5jYWxsKHRoaXMsIHBsYXllciwgdWltYW5hZ2VyKTtcclxuICAgICAgICB2YXIgY29uZmlnID0gdGhpcy5nZXRDb25maWcoKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9FUlJPUiwgZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgIHZhciBtZXNzYWdlID0gZXZlbnQubWVzc2FnZTtcclxuICAgICAgICAgICAgLy8gUHJvY2VzcyBtZXNzYWdlIHRyYW5zbGF0aW9uc1xyXG4gICAgICAgICAgICBpZiAoY29uZmlnLm1lc3NhZ2VzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGNvbmZpZy5tZXNzYWdlcyA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIFRyYW5zbGF0aW9uIGZ1bmN0aW9uIGZvciBhbGwgZXJyb3JzXHJcbiAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IGNvbmZpZy5tZXNzYWdlcyhldmVudCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIGlmIChjb25maWcubWVzc2FnZXNbZXZlbnQuY29kZV0pIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBJdCdzIG5vdCBhIHRyYW5zbGF0aW9uIGZ1bmN0aW9uLCBzbyBpdCBtdXN0IGJlIGEgbWFwIG9mIHN0cmluZ3Mgb3IgdHJhbnNsYXRpb24gZnVuY3Rpb25zXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGN1c3RvbU1lc3NhZ2UgPSBjb25maWcubWVzc2FnZXNbZXZlbnQuY29kZV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBjdXN0b21NZXNzYWdlID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gY3VzdG9tTWVzc2FnZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBtZXNzYWdlIGlzIGEgdHJhbnNsYXRpb24gZnVuY3Rpb24sIHNvIHdlIGNhbGwgaXRcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9IGN1c3RvbU1lc3NhZ2UoZXZlbnQpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBfdGhpcy5lcnJvckxhYmVsLnNldFRleHQobWVzc2FnZSk7XHJcbiAgICAgICAgICAgIF90aGlzLnR2Tm9pc2VCYWNrZ3JvdW5kLnN0YXJ0KCk7XHJcbiAgICAgICAgICAgIF90aGlzLnNob3coKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TT1VSQ0VfTE9BREVELCBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgaWYgKF90aGlzLmlzU2hvd24oKSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMudHZOb2lzZUJhY2tncm91bmQuc3RvcCgpO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuaGlkZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgRXJyb3JNZXNzYWdlT3ZlcmxheS5wcm90b3R5cGUucmVsZWFzZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnJlbGVhc2UuY2FsbCh0aGlzKTtcclxuICAgICAgICAvLyBDYW52YXMgcmVuZGVyaW5nIG11c3QgYmUgZXhwbGljaXRseSBzdG9wcGVkLCBlbHNlIGl0IGp1c3QgY29udGludWVzIGZvcmV2ZXIgYW5kIGhvZ3MgcmVzb3VyY2VzXHJcbiAgICAgICAgdGhpcy50dk5vaXNlQmFja2dyb3VuZC5zdG9wKCk7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIEVycm9yTWVzc2FnZU92ZXJsYXk7XHJcbn0oY29udGFpbmVyXzEuQ29udGFpbmVyKSk7XHJcbmV4cG9ydHMuRXJyb3JNZXNzYWdlT3ZlcmxheSA9IEVycm9yTWVzc2FnZU92ZXJsYXk7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9lcnJvcm1lc3NhZ2VvdmVybGF5LnRzXG4vLyBtb2R1bGUgaWQgPSAyNlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGNvbnRhaW5lcl8xID0gcmVxdWlyZShcIi4vY29udGFpbmVyXCIpO1xyXG52YXIgaHVnZXBsYXliYWNrdG9nZ2xlYnV0dG9uXzEgPSByZXF1aXJlKFwiLi9odWdlcGxheWJhY2t0b2dnbGVidXR0b25cIik7XHJcbi8qKlxyXG4gKiBPdmVybGF5cyB0aGUgcGxheWVyIGFuZCBkaXNwbGF5cyBlcnJvciBtZXNzYWdlcy5cclxuICovXHJcbnZhciBQbGF5YmFja1RvZ2dsZU92ZXJsYXkgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKFBsYXliYWNrVG9nZ2xlT3ZlcmxheSwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFBsYXliYWNrVG9nZ2xlT3ZlcmxheShjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMucGxheWJhY2tUb2dnbGVCdXR0b24gPSBuZXcgaHVnZXBsYXliYWNrdG9nZ2xlYnV0dG9uXzEuSHVnZVBsYXliYWNrVG9nZ2xlQnV0dG9uKCk7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktcGxheWJhY2t0b2dnbGUtb3ZlcmxheScsXHJcbiAgICAgICAgICAgIGNvbXBvbmVudHM6IFtfdGhpcy5wbGF5YmFja1RvZ2dsZUJ1dHRvbl0sXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gUGxheWJhY2tUb2dnbGVPdmVybGF5O1xyXG59KGNvbnRhaW5lcl8xLkNvbnRhaW5lcikpO1xyXG5leHBvcnRzLlBsYXliYWNrVG9nZ2xlT3ZlcmxheSA9IFBsYXliYWNrVG9nZ2xlT3ZlcmxheTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3BsYXliYWNrdG9nZ2xlb3ZlcmxheS50c1xuLy8gbW9kdWxlIGlkID0gMjdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBwbGF5YmFja3RvZ2dsZWJ1dHRvbl8xID0gcmVxdWlyZShcIi4vcGxheWJhY2t0b2dnbGVidXR0b25cIik7XHJcbnZhciBkb21fMSA9IHJlcXVpcmUoXCIuLi9kb21cIik7XHJcbi8qKlxyXG4gKiBBIGJ1dHRvbiB0aGF0IG92ZXJsYXlzIHRoZSB2aWRlbyBhbmQgdG9nZ2xlcyBiZXR3ZWVuIHBsYXliYWNrIGFuZCBwYXVzZS5cclxuICovXHJcbnZhciBIdWdlUGxheWJhY2tUb2dnbGVCdXR0b24gPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKEh1Z2VQbGF5YmFja1RvZ2dsZUJ1dHRvbiwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIEh1Z2VQbGF5YmFja1RvZ2dsZUJ1dHRvbihjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktaHVnZXBsYXliYWNrdG9nZ2xlYnV0dG9uJyxcclxuICAgICAgICAgICAgdGV4dDogJ1BsYXkvUGF1c2UnLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgSHVnZVBsYXliYWNrVG9nZ2xlQnV0dG9uLnByb3RvdHlwZS5jb25maWd1cmUgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIC8vIFVwZGF0ZSBidXR0b24gc3RhdGUgdGhyb3VnaCBBUEkgZXZlbnRzXHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jb25maWd1cmUuY2FsbCh0aGlzLCBwbGF5ZXIsIHVpbWFuYWdlciwgZmFsc2UpO1xyXG4gICAgICAgIHZhciB0b2dnbGVQbGF5YmFjayA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKHBsYXllci5pc1BsYXlpbmcoKSkge1xyXG4gICAgICAgICAgICAgICAgcGxheWVyLnBhdXNlKCd1aScpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcGxheWVyLnBsYXkoJ3VpJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciB0b2dnbGVGdWxsc2NyZWVuID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAocGxheWVyLmlzRnVsbHNjcmVlbigpKSB7XHJcbiAgICAgICAgICAgICAgICBwbGF5ZXIuZXhpdEZ1bGxzY3JlZW4oKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHBsYXllci5lbnRlckZ1bGxzY3JlZW4oKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIGZpcnN0UGxheSA9IHRydWU7XHJcbiAgICAgICAgdmFyIGNsaWNrVGltZSA9IDA7XHJcbiAgICAgICAgdmFyIGRvdWJsZUNsaWNrVGltZSA9IDA7XHJcbiAgICAgICAgLypcclxuICAgICAgICAgKiBZb3VUdWJlLXN0eWxlIHRvZ2dsZSBidXR0b24gaGFuZGxpbmdcclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIFRoZSBnb2FsIGlzIHRvIHByZXZlbnQgYSBzaG9ydCBwYXVzZSBvciBwbGF5YmFjayBpbnRlcnZhbCBiZXR3ZWVuIGEgY2xpY2ssIHRoYXQgdG9nZ2xlcyBwbGF5YmFjaywgYW5kIGFcclxuICAgICAgICAgKiBkb3VibGUgY2xpY2ssIHRoYXQgdG9nZ2xlcyBmdWxsc2NyZWVuLiBJbiB0aGlzIG5haXZlIGFwcHJvYWNoLCB0aGUgZmlyc3QgY2xpY2sgd291bGQgZS5nLiBzdGFydCBwbGF5YmFjayxcclxuICAgICAgICAgKiB0aGUgc2Vjb25kIGNsaWNrIHdvdWxkIGJlIGRldGVjdGVkIGFzIGRvdWJsZSBjbGljayBhbmQgdG9nZ2xlIHRvIGZ1bGxzY3JlZW4sIGFuZCBhcyBzZWNvbmQgbm9ybWFsIGNsaWNrIHN0b3BcclxuICAgICAgICAgKiBwbGF5YmFjaywgd2hpY2ggcmVzdWx0cyBpcyBhIHNob3J0IHBsYXliYWNrIGludGVydmFsIHdpdGggbWF4IGxlbmd0aCBvZiB0aGUgZG91YmxlIGNsaWNrIGRldGVjdGlvblxyXG4gICAgICAgICAqIHBlcmlvZCAodXN1YWxseSA1MDBtcykuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBUbyBzb2x2ZSB0aGlzIGlzc3VlLCB3ZSBkZWZlciBoYW5kbGluZyBvZiB0aGUgZmlyc3QgY2xpY2sgZm9yIDIwMG1zLCB3aGljaCBpcyBhbG1vc3QgdW5ub3RpY2VhYmxlIHRvIHRoZSB1c2VyLFxyXG4gICAgICAgICAqIGFuZCBqdXN0IHRvZ2dsZSBwbGF5YmFjayBpZiBubyBzZWNvbmQgY2xpY2sgKGRvdWJsZSBjbGljaykgaGFzIGJlZW4gcmVnaXN0ZXJlZCBkdXJpbmcgdGhpcyBwZXJpb2QuIElmIGEgZG91YmxlXHJcbiAgICAgICAgICogY2xpY2sgaXMgcmVnaXN0ZXJlZCwgd2UganVzdCB0b2dnbGUgdGhlIGZ1bGxzY3JlZW4uIEluIHRoZSBmaXJzdCAyMDBtcywgdW5kZXNpcmVkIHBsYXliYWNrIGNoYW5nZXMgdGh1cyBjYW5ub3RcclxuICAgICAgICAgKiBoYXBwZW4uIElmIGEgZG91YmxlIGNsaWNrIGlzIHJlZ2lzdGVyZWQgd2l0aGluIDUwMG1zLCB3ZSB1bmRvIHRoZSBwbGF5YmFjayBjaGFuZ2UgYW5kIHN3aXRjaCBmdWxsc2NyZWVuIG1vZGUuXHJcbiAgICAgICAgICogSW4gdGhlIGVuZCwgdGhpcyBtZXRob2QgYmFzaWNhbGx5IGludHJvZHVjZXMgYSAyMDBtcyBvYnNlcnZpbmcgaW50ZXJ2YWwgaW4gd2hpY2ggcGxheWJhY2sgY2hhbmdlcyBhcmUgcHJldmVudGVkXHJcbiAgICAgICAgICogaWYgYSBkb3VibGUgY2xpY2sgaGFwcGVucy5cclxuICAgICAgICAgKi9cclxuICAgICAgICB0aGlzLm9uQ2xpY2suc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgLy8gRGlyZWN0bHkgc3RhcnQgcGxheWJhY2sgb24gZmlyc3QgY2xpY2sgb2YgdGhlIGJ1dHRvbi5cclxuICAgICAgICAgICAgLy8gVGhpcyBpcyBhIHJlcXVpcmVkIHdvcmthcm91bmQgZm9yIG1vYmlsZSBicm93c2VycyB3aGVyZSB2aWRlbyBwbGF5YmFjayBuZWVkcyB0byBiZSB0cmlnZ2VyZWQgZGlyZWN0bHlcclxuICAgICAgICAgICAgLy8gYnkgdGhlIHVzZXIuIEEgZGVmZXJyZWQgcGxheWJhY2sgc3RhcnQgdGhyb3VnaCB0aGUgdGltZW91dCBiZWxvdyBpcyBub3QgY29uc2lkZXJlZCBhcyB1c2VyIGFjdGlvbiBhbmRcclxuICAgICAgICAgICAgLy8gdGhlcmVmb3JlIGlnbm9yZWQgYnkgbW9iaWxlIGJyb3dzZXJzLlxyXG4gICAgICAgICAgICBpZiAoZmlyc3RQbGF5KSB7XHJcbiAgICAgICAgICAgICAgICAvLyBUcnkgdG8gc3RhcnQgcGxheWJhY2suIFRoZW4gd2Ugd2FpdCBmb3IgT05fUExBWSBhbmQgb25seSB3aGVuIGl0IGFycml2ZXMsIHdlIGRpc2FibGUgdGhlIGZpcnN0UGxheSBmbGFnLlxyXG4gICAgICAgICAgICAgICAgLy8gSWYgd2UgZGlzYWJsZSB0aGUgZmxhZyBoZXJlLCBvbkNsaWNrIHdhcyB0cmlnZ2VyZWQgcHJvZ3JhbW1hdGljYWxseSBpbnN0ZWFkIG9mIGJ5IGEgdXNlciBpbnRlcmFjdGlvbiwgYW5kXHJcbiAgICAgICAgICAgICAgICAvLyBwbGF5YmFjayBpcyBibG9ja2VkIChlLmcuIG9uIG1vYmlsZSBkZXZpY2VzIGR1ZSB0byB0aGUgcHJvZ3JhbW1hdGljIHBsYXkoKSBjYWxsKSwgd2UgbG9vc2UgdGhlIGNoYW5jZSB0b1xyXG4gICAgICAgICAgICAgICAgLy8gZXZlciBzdGFydCBwbGF5YmFjayB0aHJvdWdoIGEgdXNlciBpbnRlcmFjdGlvbiBhZ2FpbiB3aXRoIHRoaXMgYnV0dG9uLlxyXG4gICAgICAgICAgICAgICAgdG9nZ2xlUGxheWJhY2soKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgbm93ID0gRGF0ZS5ub3coKTtcclxuICAgICAgICAgICAgaWYgKG5vdyAtIGNsaWNrVGltZSA8IDIwMCkge1xyXG4gICAgICAgICAgICAgICAgLy8gV2UgaGF2ZSBhIGRvdWJsZSBjbGljayBpbnNpZGUgdGhlIDIwMG1zIGludGVydmFsLCBqdXN0IHRvZ2dsZSBmdWxsc2NyZWVuIG1vZGVcclxuICAgICAgICAgICAgICAgIHRvZ2dsZUZ1bGxzY3JlZW4oKTtcclxuICAgICAgICAgICAgICAgIGRvdWJsZUNsaWNrVGltZSA9IG5vdztcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmIChub3cgLSBjbGlja1RpbWUgPCA1MDApIHtcclxuICAgICAgICAgICAgICAgIC8vIFdlIGhhdmUgYSBkb3VibGUgY2xpY2sgaW5zaWRlIHRoZSA1MDBtcyBpbnRlcnZhbCwgdW5kbyBwbGF5YmFjayB0b2dnbGUgYW5kIHRvZ2dsZSBmdWxsc2NyZWVuIG1vZGVcclxuICAgICAgICAgICAgICAgIHRvZ2dsZUZ1bGxzY3JlZW4oKTtcclxuICAgICAgICAgICAgICAgIHRvZ2dsZVBsYXliYWNrKCk7XHJcbiAgICAgICAgICAgICAgICBkb3VibGVDbGlja1RpbWUgPSBub3c7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY2xpY2tUaW1lID0gbm93O1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGlmIChEYXRlLm5vdygpIC0gZG91YmxlQ2xpY2tUaW1lID4gMjAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gTm8gZG91YmxlIGNsaWNrIGRldGVjdGVkLCBzbyB3ZSB0b2dnbGUgcGxheWJhY2sgYW5kIHdhaXQgd2hhdCBoYXBwZW5zIG5leHRcclxuICAgICAgICAgICAgICAgICAgICB0b2dnbGVQbGF5YmFjaygpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LCAyMDApO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BMQVksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgLy8gUGxheWJhY2sgaGFzIHJlYWxseSBzdGFydGVkLCB3ZSBjYW4gZGlzYWJsZSB0aGUgZmxhZyB0byBzd2l0Y2ggdG8gbm9ybWFsIHRvZ2dsZSBidXR0b24gaGFuZGxpbmdcclxuICAgICAgICAgICAgZmlyc3RQbGF5ID0gZmFsc2U7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gSGlkZSBidXR0b24gd2hpbGUgaW5pdGlhbGl6aW5nIGEgQ2FzdCBzZXNzaW9uXHJcbiAgICAgICAgdmFyIGNhc3RJbml0aWFsaXphdGlvbkhhbmRsZXIgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IHBsYXllci5FVkVOVC5PTl9DQVNUX1NUQVJUKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBIaWRlIGJ1dHRvbiB3aGVuIHNlc3Npb24gaXMgYmVpbmcgaW5pdGlhbGl6ZWRcclxuICAgICAgICAgICAgICAgIF90aGlzLmhpZGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIFNob3cgYnV0dG9uIHdoZW4gc2Vzc2lvbiBpcyBlc3RhYmxpc2hlZCBvciBpbml0aWFsaXphdGlvbiB3YXMgYWJvcnRlZFxyXG4gICAgICAgICAgICAgICAgX3RoaXMuc2hvdygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9DQVNUX1NUQVJULCBjYXN0SW5pdGlhbGl6YXRpb25IYW5kbGVyKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9DQVNUX1NUQVJURUQsIGNhc3RJbml0aWFsaXphdGlvbkhhbmRsZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0NBU1RfU1RPUFBFRCwgY2FzdEluaXRpYWxpemF0aW9uSGFuZGxlcik7XHJcbiAgICB9O1xyXG4gICAgSHVnZVBsYXliYWNrVG9nZ2xlQnV0dG9uLnByb3RvdHlwZS50b0RvbUVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGJ1dHRvbkVsZW1lbnQgPSBfc3VwZXIucHJvdG90eXBlLnRvRG9tRWxlbWVudC5jYWxsKHRoaXMpO1xyXG4gICAgICAgIC8vIEFkZCBjaGlsZCB0aGF0IGNvbnRhaW5zIHRoZSBwbGF5IGJ1dHRvbiBpbWFnZVxyXG4gICAgICAgIC8vIFNldHRpbmcgdGhlIGltYWdlIGRpcmVjdGx5IG9uIHRoZSBidXR0b24gZG9lcyBub3Qgd29yayB0b2dldGhlciB3aXRoIHNjYWxpbmcgYW5pbWF0aW9ucywgYmVjYXVzZSB0aGUgYnV0dG9uXHJcbiAgICAgICAgLy8gY2FuIGNvdmVyIHRoZSB3aG9sZSB2aWRlbyBwbGF5ZXIgYXJlIGFuZCBzY2FsaW5nIHdvdWxkIGV4dGVuZCBpdCBiZXlvbmQuIEJ5IGFkZGluZyBhbiBpbm5lciBlbGVtZW50LCBjb25maW5lZFxyXG4gICAgICAgIC8vIHRvIHRoZSBzaXplIGlmIHRoZSBpbWFnZSwgaXQgY2FuIHNjYWxlIGluc2lkZSB0aGUgcGxheWVyIHdpdGhvdXQgb3ZlcnNob290aW5nLlxyXG4gICAgICAgIGJ1dHRvbkVsZW1lbnQuYXBwZW5kKG5ldyBkb21fMS5ET00oJ2RpdicsIHtcclxuICAgICAgICAgICAgJ2NsYXNzJzogdGhpcy5wcmVmaXhDc3MoJ2ltYWdlJyksXHJcbiAgICAgICAgfSkpO1xyXG4gICAgICAgIHJldHVybiBidXR0b25FbGVtZW50O1xyXG4gICAgfTtcclxuICAgIHJldHVybiBIdWdlUGxheWJhY2tUb2dnbGVCdXR0b247XHJcbn0ocGxheWJhY2t0b2dnbGVidXR0b25fMS5QbGF5YmFja1RvZ2dsZUJ1dHRvbikpO1xyXG5leHBvcnRzLkh1Z2VQbGF5YmFja1RvZ2dsZUJ1dHRvbiA9IEh1Z2VQbGF5YmFja1RvZ2dsZUJ1dHRvbjtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2h1Z2VwbGF5YmFja3RvZ2dsZWJ1dHRvbi50c1xuLy8gbW9kdWxlIGlkID0gMjhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBjb250YWluZXJfMSA9IHJlcXVpcmUoXCIuL2NvbnRhaW5lclwiKTtcclxudmFyIGNvbXBvbmVudF8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50XCIpO1xyXG4vLyBpbXBvcnQgUGxheWVyRXZlbnQgPSBiaXRtb3Zpbi5QbGF5ZXJBUEkuUGxheWVyRXZlbnQ7XHJcbi8qKlxyXG4gKiBPdmVybGF5cyB0aGUgcGxheWVyIGFuZCBkaXNwbGF5cyBhbiBhdWRpby1vbmx5IGluZGljYXRvci5cclxuICovXHJcbnZhciBBdWRpb09ubHlPdmVybGF5ID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhBdWRpb09ubHlPdmVybGF5LCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gQXVkaW9Pbmx5T3ZlcmxheShjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuYXVkaW9vbmx5ID0gW1xyXG4gICAgICAgICAgICBuZXcgY29tcG9uZW50XzEuQ29tcG9uZW50KHsgdGFnOiAnZGl2JywgY3NzQ2xhc3M6ICd1aS1hdWRpb29ubHktb3ZlcmxheS1pbmRpY2F0b3InIH0pLFxyXG4gICAgICAgIF07XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktYXVkaW9vbmx5LW92ZXJsYXknLFxyXG4gICAgICAgICAgICBjb21wb25lbnRzOiBfdGhpcy5hdWRpb29ubHksXHJcbiAgICAgICAgICAgIGhpZGRlbjogZmFsc2UsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBBdWRpb09ubHlPdmVybGF5LnByb3RvdHlwZS5jb25maWd1cmUgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNvbmZpZ3VyZS5jYWxsKHRoaXMsIHBsYXllciwgdWltYW5hZ2VyKTtcclxuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XHJcbiAgICAgICAgdmFyIGltYWdlID0gc2VsZi5nZXREb21FbGVtZW50KCkuY3NzKCdiYWNrZ3JvdW5kLWltYWdlJyk7XHJcbiAgICAgICAgLy8gSGlkZSBvdmVybGF5IHdoZW4gUGxheWVyIGlzIHBhdXNlZCwgc28gd2UgY2FuIHNlZSB0aGUgQmlnIFBsYXkgQnV0dG9uXHJcbiAgICAgICAgLy8gcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUEFVU0VELCAoZXZlbnQpID0+IHtcclxuICAgICAgICAvLyAgIHNlbGYuZ2V0RG9tRWxlbWVudCgpLmNzcygnYmFja2dyb3VuZC1pbWFnZScsICdub25lJyk7XHJcbiAgICAgICAgLy8gfSk7XHJcbiAgICAgICAgLy9cclxuICAgICAgICAvLyBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9QTEFZLCAoZXZlbnQpID0+IHtcclxuICAgICAgICAvLyAgIHNlbGYuZ2V0RG9tRWxlbWVudCgpLmNzcygnYmFja2dyb3VuZC1pbWFnZScsIGltYWdlKTtcclxuICAgICAgICAvLyB9KTtcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIC8vIEhpZGUgb3ZlcmxheSBpZiBwbGF5ZXIgaXMgIHBhdXNlZCBhdCBpbml0IChlLmcuIG9uIG1vYmlsZSBkZXZpY2VzKVxyXG4gICAgICAgIC8vIGlmICghcGxheWVyLmlzUGxheWluZygpKSB7XHJcbiAgICAgICAgLy8gICBzZWxmLmdldERvbUVsZW1lbnQoKS5jc3MoJ2JhY2tncm91bmQtaW1hZ2UnLCAnbm9uZScpO1xyXG4gICAgICAgIC8vIH1cclxuICAgIH07XHJcbiAgICByZXR1cm4gQXVkaW9Pbmx5T3ZlcmxheTtcclxufShjb250YWluZXJfMS5Db250YWluZXIpKTtcclxuZXhwb3J0cy5BdWRpb09ubHlPdmVybGF5ID0gQXVkaW9Pbmx5T3ZlcmxheTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2F1ZGlvb25seW92ZXJsYXkudHNcbi8vIG1vZHVsZSBpZCA9IDI5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBhbmd1bGFyID0gcmVxdWlyZShcImFuZ3VsYXJcIik7XHJcbnZhciBiaXRkYXNoX2NvbnRyb2xsZXJfMSA9IHJlcXVpcmUoXCIuL2JpdGRhc2gtY29udHJvbGxlclwiKTtcclxudmFyIGJpdGRhc2hfZGlyZWN0aXZlXzEgPSByZXF1aXJlKFwiLi9iaXRkYXNoLWRpcmVjdGl2ZVwiKTtcclxuZXhwb3J0cy5kZWZhdWx0ID0gYW5ndWxhci5tb2R1bGUoJ21pLkJpdGRhc2hQbGF5ZXInLCBbXSlcclxuICAgIC5jb250cm9sbGVyKCdNaUJpdGRhc2hDb250cm9sbGVyJywgYml0ZGFzaF9jb250cm9sbGVyXzEuZGVmYXVsdClcclxuICAgIC5kaXJlY3RpdmUoJ21pQml0ZGFzaFBsYXllcicsIGJpdGRhc2hfZGlyZWN0aXZlXzEuZGVmYXVsdCk7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4vaW5kZXgudHNcbi8vIG1vZHVsZSBpZCA9IDMxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBhbmd1bGFyID0gcmVxdWlyZShcImFuZ3VsYXJcIik7XHJcbnZhciBCaXRtb3ZpbkNvbnRyb2xsZXIgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gQml0bW92aW5Db250cm9sbGVyKCRzY29wZSwgJGxvZykge1xyXG4gICAgICAgIHRoaXMuJHNjb3BlID0gJHNjb3BlO1xyXG4gICAgICAgIHRoaXMuJGxvZyA9ICRsb2c7XHJcbiAgICAgICAgdGhpcy5jb25maWcgPSB7fTtcclxuICAgICAgICB0aGlzLm9wdGlvbnMgPSB7fTtcclxuICAgICAgICB0aGlzLiRzY29wZSA9ICRzY29wZTtcclxuICAgICAgICB0aGlzLiRsb2cgPSAkbG9nO1xyXG4gICAgfVxyXG4gICAgQml0bW92aW5Db250cm9sbGVyLnByb3RvdHlwZS4kb25Jbml0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmIChhbmd1bGFyLmlzRGVmaW5lZCh0aGlzLiRzY29wZS5jb25maWcpICYmIGFuZ3VsYXIuaXNEZWZpbmVkKHRoaXMuJHNjb3BlLmNvbmZpZy5rZXkpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29uZmlnID0gdGhpcy4kc2NvcGUuY29uZmlnO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy4kbG9nLmVycm9yKFwiYmFzaWMgY29uZmlnIGZvciBiaXRkYXNoIHBsYXllciBpcyBtaXNzaW5nIVwiKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGFuZ3VsYXIuaXNEZWZpbmVkKHRoaXMuJHNjb3BlLm9wdGlvbnMpKSB7XHJcbiAgICAgICAgICAgIHRoaXMub3B0aW9ucyA9IHRoaXMuJHNjb3BlLm9wdGlvbnM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChhbmd1bGFyLmlzRGVmaW5lZCh0aGlzLiRzY29wZS53ZWJjYXN0KSkge1xyXG4gICAgICAgICAgICB0aGlzLnByb2Nlc3NXZWJjYXN0KHRoaXMuJHNjb3BlLndlYmNhc3QpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBCaXRtb3ZpbkNvbnRyb2xsZXIucHJvdG90eXBlLnByb2Nlc3NXZWJjYXN0ID0gZnVuY3Rpb24gKHdlYmNhc3QpIHtcclxuICAgICAgICB2YXIgc3RhdGVQcm9wZXJ0eSA9IHdlYmNhc3Quc3RhdGUgKyBcIlN0YXRlRGF0YVwiO1xyXG4gICAgICAgIGlmIChhbmd1bGFyLmlzRGVmaW5lZCh0aGlzLm9wdGlvbnMuZm9yY2VkU3RhdGUpKSB7XHJcbiAgICAgICAgICAgIHN0YXRlUHJvcGVydHkgPSB0aGlzLm9wdGlvbnMuZm9yY2VkU3RhdGUgKyBcIlN0YXRlRGF0YVwiO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmNvbmZpZy5zb3VyY2UgPSB0aGlzLmdldFBsYXllckNvbmZpZ1NvdXJjZSh3ZWJjYXN0LCBzdGF0ZVByb3BlcnR5KTtcclxuICAgICAgICB0aGlzLmNvbmZpZy5zdHlsZSA9IHsgdXg6IGZhbHNlIH07XHJcbiAgICB9O1xyXG4gICAgQml0bW92aW5Db250cm9sbGVyLnByb3RvdHlwZS5nZXRQbGF5ZXJDb25maWdTb3VyY2UgPSBmdW5jdGlvbiAod2ViY2FzdCwgc3RhdGUpIHtcclxuICAgICAgICBpZiAoKHdlYmNhc3QudXNlRFZSUGxheWJhY2tJblBvc3RsaXZlID09PSB0cnVlKSAmJiAoc3RhdGUgPT09ICdwb3N0bGl2ZVN0YXRlRGF0YScpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmdldERWUlBsYXliYWNrVG9Qb3N0bGl2ZSh3ZWJjYXN0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGxheWVyQ29uZmlnU291cmNlQnlTdGF0ZSh3ZWJjYXN0LCBzdGF0ZSk7XHJcbiAgICB9O1xyXG4gICAgQml0bW92aW5Db250cm9sbGVyLnByb3RvdHlwZS5nZXREVlJQbGF5YmFja1RvUG9zdGxpdmUgPSBmdW5jdGlvbiAod2ViY2FzdCkge1xyXG4gICAgICAgIHZhciBobHMgPSB3ZWJjYXN0WydsaXZlU3RhdGVEYXRhJ10ucGxheW91dC5obHNEdnJVcmw7XHJcbiAgICAgICAgdmFyIHRpdGxlID0gd2ViY2FzdC5uYW1lO1xyXG4gICAgICAgIGlmIChhbmd1bGFyLmlzRGVmaW5lZCh3ZWJjYXN0Wydwb3N0bGl2ZVN0YXRlRGF0YSddLnBsYXlvdXQub2Zmc2V0KSkge1xyXG4gICAgICAgICAgICB2YXIgb2Zmc2V0ID0gcGFyc2VJbnQod2ViY2FzdFsncG9zdGxpdmVTdGF0ZURhdGEnXS5wbGF5b3V0Lm9mZnNldCwgMTApO1xyXG4gICAgICAgICAgICBpZiAob2Zmc2V0ID4gMCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIG9mZnNldFByZWZpeCA9IHZvaWQgMDtcclxuICAgICAgICAgICAgICAgIHZhciBwYXJzZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XHJcbiAgICAgICAgICAgICAgICBwYXJzZXIuaHJlZiA9IHdlYmNhc3RbJ2xpdmVTdGF0ZURhdGEnXS5wbGF5b3V0Lmhsc0R2clVybDtcclxuICAgICAgICAgICAgICAgIG9mZnNldFByZWZpeCA9IChwYXJzZXIuc2VhcmNoKSA/ICcmJyA6ICc/JztcclxuICAgICAgICAgICAgICAgIGhscyArPSBvZmZzZXRQcmVmaXggKyBcIndvd3phZHZycGxheWxpc3RzdGFydD1cIiArIG9mZnNldCArIFwiMDAwXCI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHsgaGxzOiBobHMsIHRpdGxlOiB0aXRsZSB9O1xyXG4gICAgfTtcclxuICAgIEJpdG1vdmluQ29udHJvbGxlci5wcm90b3R5cGUuZ2V0UGxheWVyQ29uZmlnU291cmNlQnlTdGF0ZSA9IGZ1bmN0aW9uICh3ZWJjYXN0LCBzdGF0ZSkge1xyXG4gICAgICAgIHZhciBobHMgPSB3ZWJjYXN0W3N0YXRlXS5wbGF5b3V0Lmhsc1VybDtcclxuICAgICAgICB2YXIgdGl0bGUgPSB3ZWJjYXN0Lm5hbWU7XHJcbiAgICAgICAgdmFyIGhpdmVTZXJ2aWNlVXJsID0gdGhpcy5nZXRIaXZlU2VydmljZVVybEJ5TGFuZyh3ZWJjYXN0KTtcclxuICAgICAgICBpZiAoYW5ndWxhci5pc0RlZmluZWQod2ViY2FzdFtzdGF0ZV0ucGxheW91dC52aWRlb01hbmFnZXJIbHNVcmwpICYmIHdlYmNhc3Rbc3RhdGVdLnBsYXlvdXQudmlkZW9NYW5hZ2VySGxzVXJsKSB7XHJcbiAgICAgICAgICAgIGhscyA9IHdlYmNhc3Rbc3RhdGVdLnBsYXlvdXQudmlkZW9NYW5hZ2VySGxzVXJsO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYW5ndWxhci5pc0RlZmluZWQod2ViY2FzdFtzdGF0ZV0ucGxheW91dC5vZmZzZXQpKSB7XHJcbiAgICAgICAgICAgIHZhciBvZmZzZXQgPSBwYXJzZUludCh3ZWJjYXN0W3N0YXRlXS5wbGF5b3V0Lm9mZnNldCwgMTApO1xyXG4gICAgICAgICAgICBpZiAob2Zmc2V0ID4gMCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIG9mZnNldFByZWZpeCA9IHZvaWQgMDtcclxuICAgICAgICAgICAgICAgIHZhciBwYXJzZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XHJcbiAgICAgICAgICAgICAgICBwYXJzZXIuaHJlZiA9IGhscztcclxuICAgICAgICAgICAgICAgIG9mZnNldFByZWZpeCA9IChwYXJzZXIuc2VhcmNoKSA/ICcmJyA6ICc/JztcclxuICAgICAgICAgICAgICAgIGhscyArPSBvZmZzZXRQcmVmaXggKyBcInN0YXJ0PVwiICsgb2Zmc2V0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB7IGhsczogaGxzLCB0aXRsZTogdGl0bGUsIGhpdmVTZXJ2aWNlVXJsOiBoaXZlU2VydmljZVVybCB9O1xyXG4gICAgfTtcclxuICAgIEJpdG1vdmluQ29udHJvbGxlci5wcm90b3R5cGUuZ2V0SGl2ZVNlcnZpY2VVcmxCeUxhbmcgPSBmdW5jdGlvbiAod2ViY2FzdCkge1xyXG4gICAgICAgIHZhciBoaXZlU2VydmljZVVybCA9IG51bGw7XHJcbiAgICAgICAgaWYgKHdlYmNhc3QubGFuZ3VhZ2VzICYmIHdlYmNhc3QubGFuZ3VhZ2UpIHtcclxuICAgICAgICAgICAgd2ViY2FzdC5sYW5ndWFnZXMuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGl0ZW0ubGFuZ3VhZ2UgPT09IHdlYmNhc3QubGFuZ3VhZ2UpIHtcclxuICAgICAgICAgICAgICAgICAgICBoaXZlU2VydmljZVVybCA9IGFuZ3VsYXIuY29weShpdGVtLmhpdmVTZXJ2aWNlVXJsKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBoaXZlU2VydmljZVVybDtcclxuICAgIH07XHJcbiAgICByZXR1cm4gQml0bW92aW5Db250cm9sbGVyO1xyXG59KCkpO1xyXG5CaXRtb3ZpbkNvbnRyb2xsZXIuJGluamVjdCA9IFsnJHNjb3BlJywgJyRsb2cnXTtcclxuZXhwb3J0cy5kZWZhdWx0ID0gQml0bW92aW5Db250cm9sbGVyO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL2JpdGRhc2gtY29udHJvbGxlci50c1xuLy8gbW9kdWxlIGlkID0gMzJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGFuZ3VsYXIgPSByZXF1aXJlKFwiYW5ndWxhclwiKTtcclxudmFyIEJpdGRhc2hEaXJlY3RpdmUgPSBmdW5jdGlvbiAoJHdpbmRvdywgJGxvZykgeyByZXR1cm4gKHtcclxuICAgIGNvbnRyb2xsZXI6ICdNaUJpdGRhc2hDb250cm9sbGVyJyxcclxuICAgIGNvbnRyb2xsZXJBczogJ2JpdGRhc2hWbScsXHJcbiAgICByZXBsYWNlOiB0cnVlLFxyXG4gICAgcmVzdHJpY3Q6ICdFQScsXHJcbiAgICBzY29wZToge1xyXG4gICAgICAgIGNvbmZpZzogJz0nLFxyXG4gICAgICAgIG9wdGlvbnM6ICc9PycsXHJcbiAgICAgICAgd2ViY2FzdDogJz0nLFxyXG4gICAgfSxcclxuICAgIHRlbXBsYXRlOiBcIjxkaXYgaWQ9XFxcIm1pLWJpdGRhc2gtcGxheWVyXFxcIiB3aWR0aD1cXFwiMTAwJVxcXCIgaGVpZ2h0PVxcXCJhdXRvXFxcIj48L2Rpdj5cIixcclxuICAgIGxpbms6IGZ1bmN0aW9uIChzY29wZSkge1xyXG4gICAgICAgIHZhciBiaXRtb3ZpblBsYXllcjtcclxuICAgICAgICB2YXIgYml0bW92aW5VSU1hbmFnZXI7XHJcbiAgICAgICAgdmFyIGJpdG1vdmluQ29udHJvbGJhcjtcclxuICAgICAgICB2YXIgY29uZmlnID0gc2NvcGUuY29uZmlnO1xyXG4gICAgICAgIHZhciB3ZWJjYXN0ID0gc2NvcGUud2ViY2FzdDtcclxuICAgICAgICB2YXIgc3RhdGUgPSBzY29wZS53ZWJjYXN0LnN0YXRlICsgXCJTdGF0ZURhdGFcIjtcclxuICAgICAgICBidWlsZFBsYXllcigpO1xyXG4gICAgICAgIGZ1bmN0aW9uIGJ1aWxkUGxheWVyKCkge1xyXG4gICAgICAgICAgICBiaXRtb3ZpblBsYXllciA9ICR3aW5kb3cud2luZG93LmJpdG1vdmluLnBsYXllcignbWktYml0ZGFzaC1wbGF5ZXInKTtcclxuICAgICAgICAgICAgaWYgKGFuZ3VsYXIuaXNEZWZpbmVkKGJpdG1vdmluUGxheWVyKSAmJiBiaXRtb3ZpblBsYXllci5pc1JlYWR5KCkgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgICAgIGJpdG1vdmluUGxheWVyLmRlc3Ryb3koKTtcclxuICAgICAgICAgICAgICAgIGJpdG1vdmluUGxheWVyID0gJHdpbmRvdy53aW5kb3cuYml0bW92aW4ucGxheWVyKCdtaS1iaXRkYXNoLXBsYXllcicpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICgoc3RhdGUgPT09ICdsaXZlU3RhdGVEYXRhJykgJiYgY29uZmlnLnNvdXJjZS5oaXZlU2VydmljZVVybCkge1xyXG4gICAgICAgICAgICAgICAgLy8gR2V0IGEgaGl2ZS1lbmFibGVkIHBsYXllciB0aHJvdWdoIGJpdGRhc2guaW5pdEhpdmVTRE5cclxuICAgICAgICAgICAgICAgICR3aW5kb3cud2luZG93LmJpdG1vdmluLmluaXRIaXZlU0ROKGJpdG1vdmluUGxheWVyLCB7IGRlYnVnTGV2ZWw6ICdvZmYnIH0pO1xyXG4gICAgICAgICAgICAgICAgLy8gQ29uZmlndXJlIGFuZCBTZXR1cCBiaXRtb3ZpbiBpbiBpbml0U2Vzc2lvbiBjYWxsYmFja1xyXG4gICAgICAgICAgICAgICAgYml0bW92aW5QbGF5ZXIuaW5pdFNlc3Npb24oY29uZmlnLnNvdXJjZS5oaXZlU2VydmljZVVybCkudGhlbihmdW5jdGlvbiAoc2Vzc2lvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBoaXZlQ29uZmlnID0gYW5ndWxhci5jb3B5KGNvbmZpZyk7XHJcbiAgICAgICAgICAgICAgICAgICAgaGl2ZUNvbmZpZy5zb3VyY2UuaGxzID0gc2Vzc2lvbi5tYW5pZmVzdDtcclxuICAgICAgICAgICAgICAgICAgICBsb2FkUGxheWVyKGhpdmVDb25maWcpO1xyXG4gICAgICAgICAgICAgICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIEhhbmRsZSB0aGUgY2FzZSBpZiBIaXZlIGluaXQgZmFpbHNcclxuICAgICAgICAgICAgICAgICAgICAkbG9nLndhcm4oXCJIaXZlIGluaXQgZmFpbHM6IFwiICsgcmVhc29uLmNvZGUgKyBcIiAtIFwiICsgcmVhc29uLm1lc3NhZ2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIGxvYWRQbGF5ZXIoY29uZmlnKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgbG9hZFBsYXllcihjb25maWcpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIGxvYWRQbGF5ZXIoY29uZikge1xyXG4gICAgICAgICAgICBiaXRtb3ZpblBsYXllclxyXG4gICAgICAgICAgICAgICAgLnNldHVwKGNvbmYpXHJcbiAgICAgICAgICAgICAgICAudGhlbihmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBiaXRtb3ZpblVJTWFuYWdlciA9ICR3aW5kb3cud2luZG93LmJpdG1vdmluLnBsYXllcnVpLlVJTWFuYWdlci5GYWN0b3J5O1xyXG4gICAgICAgICAgICAgICAgaWYgKGlzQXVkaW9Pbmx5KCkpIHtcclxuICAgICAgICAgICAgICAgICAgICBiaXRtb3ZpblVJTWFuYWdlci5idWlsZEF1ZGlvT25seVVJKGJpdG1vdmluUGxheWVyKTtcclxuICAgICAgICAgICAgICAgICAgICBzZXRBdWRpb09ubHlTdGlsbEltYWdlKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBiaXRtb3ZpblVJTWFuYWdlci5idWlsZEF1ZGlvVmlkZW9VSShiaXRtb3ZpblBsYXllcik7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBiaXRtb3ZpbkNvbnRyb2xiYXIgPSBnZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCdiaXRtb3ZpbnBsYXllci1jb250YWluZXInKTtcclxuICAgICAgICAgICAgICAgIGlmIChhbmd1bGFyLmlzRGVmaW5lZChiaXRtb3ZpbkNvbnRyb2xiYXIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYml0bW92aW5Db250cm9sYmFyLnN0eWxlLm1pbldpZHRoID0gJzE3NXB4JztcclxuICAgICAgICAgICAgICAgICAgICBiaXRtb3ZpbkNvbnRyb2xiYXIuc3R5bGUubWluSGVpZ2h0ID0gJzEwMXB4JztcclxuICAgICAgICAgICAgICAgICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnYml0bW92aW5wbGF5ZXItdmlkZW8tbWktYml0ZGFzaC1wbGF5ZXInKS5zZXRBdHRyaWJ1dGUoJ3RpdGxlJywgd2ViY2FzdC5uYW1lKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgZnVuY3Rpb24gKHJlYXNvbikge1xyXG4gICAgICAgICAgICAgICAgJGxvZy5sb2coXCJFcnJvcjogXCIgKyByZWFzb24uY29kZSArIFwiIC0gXCIgKyByZWFzb24ubWVzc2FnZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmdW5jdGlvbiBpc0F1ZGlvT25seSgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFuZ3VsYXIuaXNEZWZpbmVkKHNjb3BlLndlYmNhc3Rbc3RhdGVdLnBsYXlvdXQuYXVkaW9Pbmx5KSAmJlxyXG4gICAgICAgICAgICAgICAgc2NvcGUud2ViY2FzdFtzdGF0ZV0ucGxheW91dC5hdWRpb09ubHk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIHNldEF1ZGlvT25seVN0aWxsSW1hZ2UoKSB7XHJcbiAgICAgICAgICAgIGlmIChhbmd1bGFyLmlzRGVmaW5lZChzY29wZS53ZWJjYXN0W3N0YXRlXS5wbGF5b3V0LmF1ZGlvT25seVN0aWxsVXJsKSAmJlxyXG4gICAgICAgICAgICAgICAgc2NvcGUud2ViY2FzdFtzdGF0ZV0ucGxheW91dC5hdWRpb09ubHlTdGlsbFVybCAhPT0gJycpIHtcclxuICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnbWktd2JjLXVpLWF1ZGlvb25seS1vdmVybGF5Jyk7XHJcbiAgICAgICAgICAgICAgICBlbGVtZW50LnN0eWxlLmJhY2tncm91bmRJbWFnZSA9IFwidXJsKFwiICsgc2NvcGUud2ViY2FzdFtzdGF0ZV0ucGxheW91dC5hdWRpb09ubHlTdGlsbFVybCArIFwiKVwiO1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudC5zdHlsZS5iYWNrZ3JvdW5kU2l6ZSA9ICdjb250YWluJztcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZFBvc2l0aW9uID0gJ2NlbnRlcic7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZnVuY3Rpb24gZ2V0RWxlbWVudHNCeUNsYXNzTmFtZShjbGFzc05hbWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGRvY3VtZW50LmdldEVsZW1lbnRzQnlDbGFzc05hbWUoY2xhc3NOYW1lKVswXTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn0pOyB9O1xyXG5leHBvcnRzLmRlZmF1bHQgPSBCaXRkYXNoRGlyZWN0aXZlO1xyXG5CaXRkYXNoRGlyZWN0aXZlLiRpbmplY3QgPSBbJyR3aW5kb3cnLCAnJGxvZyddO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL2JpdGRhc2gtZGlyZWN0aXZlLnRzXG4vLyBtb2R1bGUgaWQgPSAzM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG4vLy8gPHJlZmVyZW5jZSBwYXRoPSdwbGF5ZXIuZC50cycgLz5cclxudmFyIHVpbWFuYWdlcl8xID0gcmVxdWlyZShcIi4vdWltYW5hZ2VyXCIpO1xyXG52YXIgYnV0dG9uXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL2J1dHRvblwiKTtcclxudmFyIGNvbnRyb2xiYXJfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvY29udHJvbGJhclwiKTtcclxudmFyIGh1Z2VwbGF5YmFja3RvZ2dsZWJ1dHRvbl8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9odWdlcGxheWJhY2t0b2dnbGVidXR0b25cIik7XHJcbnZhciBwbGF5YmFja3RpbWVsYWJlbF8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9wbGF5YmFja3RpbWVsYWJlbFwiKTtcclxudmFyIHBsYXliYWNrdG9nZ2xlYnV0dG9uXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL3BsYXliYWNrdG9nZ2xlYnV0dG9uXCIpO1xyXG52YXIgc2Vla2Jhcl8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9zZWVrYmFyXCIpO1xyXG52YXIgc2VsZWN0Ym94XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL3NlbGVjdGJveFwiKTtcclxudmFyIGl0ZW1zZWxlY3Rpb25saXN0XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL2l0ZW1zZWxlY3Rpb25saXN0XCIpO1xyXG4vLyBpbXBvcnQge1NldHRpbmdzUGFuZWwsIFNldHRpbmdzUGFuZWxJdGVtfSBmcm9tICcuL2NvbXBvbmVudHMvc2V0dGluZ3NwYW5lbCc7XHJcbi8vIGltcG9ydCB7U2V0dGluZ3NUb2dnbGVCdXR0b259IGZyb20gJy4vY29tcG9uZW50cy9zZXR0aW5nc3RvZ2dsZWJ1dHRvbic7XHJcbnZhciB0b2dnbGVidXR0b25fMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvdG9nZ2xlYnV0dG9uXCIpO1xyXG4vLyBpbXBvcnQge1ZpZGVvUXVhbGl0eVNlbGVjdEJveH0gZnJvbSAnLi9jb21wb25lbnRzL3ZpZGVvcXVhbGl0eXNlbGVjdGJveCc7XHJcbnZhciB2b2x1bWV0b2dnbGVidXR0b25fMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvdm9sdW1ldG9nZ2xlYnV0dG9uXCIpO1xyXG4vLyBpbXBvcnQge1dhdGVybWFya30gZnJvbSAnLi9jb21wb25lbnRzL3dhdGVybWFyayc7XHJcbnZhciB1aWNvbnRhaW5lcl8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy91aWNvbnRhaW5lclwiKTtcclxudmFyIGNvbnRhaW5lcl8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9jb250YWluZXJcIik7XHJcbnZhciBsYWJlbF8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9sYWJlbFwiKTtcclxudmFyIGNvbXBvbmVudF8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9jb21wb25lbnRcIik7XHJcbnZhciBlcnJvcm1lc3NhZ2VvdmVybGF5XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL2Vycm9ybWVzc2FnZW92ZXJsYXlcIik7XHJcbnZhciBzZWVrYmFybGFiZWxfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvc2Vla2JhcmxhYmVsXCIpO1xyXG4vLyBpbXBvcnQge1RpdGxlQmFyfSBmcm9tICcuL2NvbXBvbmVudHMvdGl0bGViYXInO1xyXG52YXIgdm9sdW1lY29udHJvbGJ1dHRvbl8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy92b2x1bWVjb250cm9sYnV0dG9uXCIpO1xyXG52YXIgY2xpY2tvdmVybGF5XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL2NsaWNrb3ZlcmxheVwiKTtcclxudmFyIGh1Z2VyZXBsYXlidXR0b25fMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvaHVnZXJlcGxheWJ1dHRvblwiKTtcclxuLy8gaW1wb3J0IHtCdWZmZXJpbmdPdmVybGF5fSBmcm9tICcuL2NvbXBvbmVudHMvYnVmZmVyaW5nb3ZlcmxheSc7XHJcbnZhciBwbGF5YmFja3RvZ2dsZW92ZXJsYXlfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvcGxheWJhY2t0b2dnbGVvdmVybGF5XCIpO1xyXG52YXIgY2xvc2VidXR0b25fMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvY2xvc2VidXR0b25cIik7XHJcbi8vIGltcG9ydCB7TWV0YWRhdGFMYWJlbCwgTWV0YWRhdGFMYWJlbENvbnRlbnR9IGZyb20gJy4vY29tcG9uZW50cy9tZXRhZGF0YWxhYmVsJztcclxudmFyIHZvbHVtZXNsaWRlcl8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy92b2x1bWVzbGlkZXJcIik7XHJcbnZhciBzcGFjZXJfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvc3BhY2VyXCIpO1xyXG52YXIgYXJyYXl1dGlsc18xID0gcmVxdWlyZShcIi4vYXJyYXl1dGlsc1wiKTtcclxudmFyIHN0cmluZ3V0aWxzXzEgPSByZXF1aXJlKFwiLi9zdHJpbmd1dGlsc1wiKTtcclxudmFyIHBsYXllcnV0aWxzXzEgPSByZXF1aXJlKFwiLi9wbGF5ZXJ1dGlsc1wiKTtcclxudmFyIHVpdXRpbHNfMSA9IHJlcXVpcmUoXCIuL3VpdXRpbHNcIik7XHJcbnZhciBicm93c2VydXRpbHNfMSA9IHJlcXVpcmUoXCIuL2Jyb3dzZXJ1dGlsc1wiKTtcclxudmFyIHN0b3JhZ2V1dGlsc18xID0gcmVxdWlyZShcIi4vc3RvcmFnZXV0aWxzXCIpO1xyXG52YXIgYXVkaW9vbmx5b3ZlcmxheV8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9hdWRpb29ubHlvdmVybGF5XCIpO1xyXG4vLyBPYmplY3QuYXNzaWduIHBvbHlmaWxsIGZvciBFUzUvSUU5XHJcbi8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2RlL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0dsb2JhbF9PYmplY3RzL09iamVjdC9hc3NpZ25cclxuaWYgKHR5cGVvZiBPYmplY3QuYXNzaWduICE9PSAnZnVuY3Rpb24nKSB7XHJcbiAgICBPYmplY3QuYXNzaWduID0gZnVuY3Rpb24gKHRhcmdldCkge1xyXG4gICAgICAgICd1c2Ugc3RyaWN0JztcclxuICAgICAgICBpZiAodGFyZ2V0ID09IG51bGwpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignQ2Fubm90IGNvbnZlcnQgdW5kZWZpbmVkIG9yIG51bGwgdG8gb2JqZWN0Jyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRhcmdldCA9IE9iamVjdCh0YXJnZXQpO1xyXG4gICAgICAgIGZvciAodmFyIGluZGV4ID0gMTsgaW5kZXggPCBhcmd1bWVudHMubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgICAgICAgIHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaW5kZXhdO1xyXG4gICAgICAgICAgICBpZiAoc291cmNlICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdGFyZ2V0O1xyXG4gICAgfTtcclxufVxyXG52YXIgcGxheWVydWkgPSB7XHJcbiAgICB2ZXJzaW9uOiAne3tWRVJTSU9OfX0nLFxyXG4gICAgLy8gTWFuYWdlbWVudFxyXG4gICAgVUlNYW5hZ2VyOiB1aW1hbmFnZXJfMS5VSU1hbmFnZXIsXHJcbiAgICBVSUluc3RhbmNlTWFuYWdlcjogdWltYW5hZ2VyXzEuVUlJbnN0YW5jZU1hbmFnZXIsXHJcbiAgICAvLyBVdGlsc1xyXG4gICAgQXJyYXlVdGlsczogYXJyYXl1dGlsc18xLkFycmF5VXRpbHMsXHJcbiAgICBTdHJpbmdVdGlsczogc3RyaW5ndXRpbHNfMS5TdHJpbmdVdGlscyxcclxuICAgIFBsYXllclV0aWxzOiBwbGF5ZXJ1dGlsc18xLlBsYXllclV0aWxzLFxyXG4gICAgVUlVdGlsczogdWl1dGlsc18xLlVJVXRpbHMsXHJcbiAgICBCcm93c2VyVXRpbHM6IGJyb3dzZXJ1dGlsc18xLkJyb3dzZXJVdGlscyxcclxuICAgIFN0b3JhZ2VVdGlsczogc3RvcmFnZXV0aWxzXzEuU3RvcmFnZVV0aWxzLFxyXG4gICAgLy8gQ29tcG9uZW50c1xyXG4gICAgQXVkaW9Pbmx5T3ZlcmxheTogYXVkaW9vbmx5b3ZlcmxheV8xLkF1ZGlvT25seU92ZXJsYXksXHJcbiAgICAvLyBCdWZmZXJpbmdPdmVybGF5LFxyXG4gICAgQnV0dG9uOiBidXR0b25fMS5CdXR0b24sXHJcbiAgICBDbGlja092ZXJsYXk6IGNsaWNrb3ZlcmxheV8xLkNsaWNrT3ZlcmxheSxcclxuICAgIENsb3NlQnV0dG9uOiBjbG9zZWJ1dHRvbl8xLkNsb3NlQnV0dG9uLFxyXG4gICAgQ29tcG9uZW50OiBjb21wb25lbnRfMS5Db21wb25lbnQsXHJcbiAgICBDb250YWluZXI6IGNvbnRhaW5lcl8xLkNvbnRhaW5lcixcclxuICAgIENvbnRyb2xCYXI6IGNvbnRyb2xiYXJfMS5Db250cm9sQmFyLFxyXG4gICAgRXJyb3JNZXNzYWdlT3ZlcmxheTogZXJyb3JtZXNzYWdlb3ZlcmxheV8xLkVycm9yTWVzc2FnZU92ZXJsYXksXHJcbiAgICBIdWdlUGxheWJhY2tUb2dnbGVCdXR0b246IGh1Z2VwbGF5YmFja3RvZ2dsZWJ1dHRvbl8xLkh1Z2VQbGF5YmFja1RvZ2dsZUJ1dHRvbixcclxuICAgIEh1Z2VSZXBsYXlCdXR0b246IGh1Z2VyZXBsYXlidXR0b25fMS5IdWdlUmVwbGF5QnV0dG9uLFxyXG4gICAgTGFiZWw6IGxhYmVsXzEuTGFiZWwsXHJcbiAgICAvLyBNZXRhZGF0YUxhYmVsLFxyXG4gICAgLy8gTWV0YWRhdGFMYWJlbENvbnRlbnQsXHJcbiAgICBQbGF5YmFja1RpbWVMYWJlbDogcGxheWJhY2t0aW1lbGFiZWxfMS5QbGF5YmFja1RpbWVMYWJlbCxcclxuICAgIFBsYXliYWNrVGltZUxhYmVsTW9kZTogcGxheWJhY2t0aW1lbGFiZWxfMS5QbGF5YmFja1RpbWVMYWJlbE1vZGUsXHJcbiAgICBQbGF5YmFja1RvZ2dsZUJ1dHRvbjogcGxheWJhY2t0b2dnbGVidXR0b25fMS5QbGF5YmFja1RvZ2dsZUJ1dHRvbixcclxuICAgIFBsYXliYWNrVG9nZ2xlT3ZlcmxheTogcGxheWJhY2t0b2dnbGVvdmVybGF5XzEuUGxheWJhY2tUb2dnbGVPdmVybGF5LFxyXG4gICAgU2Vla0Jhcjogc2Vla2Jhcl8xLlNlZWtCYXIsXHJcbiAgICBTZWVrQmFyTGFiZWw6IHNlZWtiYXJsYWJlbF8xLlNlZWtCYXJMYWJlbCxcclxuICAgIFNlbGVjdEJveDogc2VsZWN0Ym94XzEuU2VsZWN0Qm94LFxyXG4gICAgSXRlbVNlbGVjdGlvbkxpc3Q6IGl0ZW1zZWxlY3Rpb25saXN0XzEuSXRlbVNlbGVjdGlvbkxpc3QsXHJcbiAgICAvLyBTZXR0aW5nc1BhbmVsLFxyXG4gICAgLy8gU2V0dGluZ3NQYW5lbEl0ZW0sXHJcbiAgICAvLyBTZXR0aW5nc1RvZ2dsZUJ1dHRvbixcclxuICAgIFNwYWNlcjogc3BhY2VyXzEuU3BhY2VyLFxyXG4gICAgLy8gVGl0bGVCYXIsXHJcbiAgICBUb2dnbGVCdXR0b246IHRvZ2dsZWJ1dHRvbl8xLlRvZ2dsZUJ1dHRvbixcclxuICAgIFVJQ29udGFpbmVyOiB1aWNvbnRhaW5lcl8xLlVJQ29udGFpbmVyLFxyXG4gICAgLy8gVmlkZW9RdWFsaXR5U2VsZWN0Qm94LFxyXG4gICAgVm9sdW1lQ29udHJvbEJ1dHRvbjogdm9sdW1lY29udHJvbGJ1dHRvbl8xLlZvbHVtZUNvbnRyb2xCdXR0b24sXHJcbiAgICBWb2x1bWVTbGlkZXI6IHZvbHVtZXNsaWRlcl8xLlZvbHVtZVNsaWRlcixcclxuICAgIFZvbHVtZVRvZ2dsZUJ1dHRvbjogdm9sdW1ldG9nZ2xlYnV0dG9uXzEuVm9sdW1lVG9nZ2xlQnV0dG9uLFxyXG59O1xyXG53aW5kb3cuYml0bW92aW4ucGxheWVydWkgPSBwbGF5ZXJ1aTtcclxubW9kdWxlLmV4cG9ydHMgPSBwbGF5ZXJ1aTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9tYWluLnRzXG4vLyBtb2R1bGUgaWQgPSAzNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIHVpY29udGFpbmVyXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL3VpY29udGFpbmVyXCIpO1xyXG52YXIgZG9tXzEgPSByZXF1aXJlKFwiLi9kb21cIik7XHJcbnZhciBjb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvY29tcG9uZW50XCIpO1xyXG52YXIgY29udGFpbmVyXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL2NvbnRhaW5lclwiKTtcclxudmFyIHBsYXliYWNrdG9nZ2xlYnV0dG9uXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL3BsYXliYWNrdG9nZ2xlYnV0dG9uXCIpO1xyXG52YXIgZnVsbHNjcmVlbnRvZ2dsZWJ1dHRvbl8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9mdWxsc2NyZWVudG9nZ2xlYnV0dG9uXCIpO1xyXG4vLyBpbXBvcnQge1ZSVG9nZ2xlQnV0dG9ufSBmcm9tICcuL2NvbXBvbmVudHMvdnJ0b2dnbGVidXR0b24nO1xyXG4vLyBpbXBvcnQge1ZvbHVtZVRvZ2dsZUJ1dHRvbn0gZnJvbSAnLi9jb21wb25lbnRzL3ZvbHVtZXRvZ2dsZWJ1dHRvbic7XHJcbnZhciBzZWVrYmFyXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL3NlZWtiYXJcIik7XHJcbnZhciBwbGF5YmFja3RpbWVsYWJlbF8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9wbGF5YmFja3RpbWVsYWJlbFwiKTsgLy8gLCBQbGF5YmFja1RpbWVMYWJlbE1vZGVcclxudmFyIGNvbnRyb2xiYXJfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvY29udHJvbGJhclwiKTtcclxudmFyIGV2ZW50ZGlzcGF0Y2hlcl8xID0gcmVxdWlyZShcIi4vZXZlbnRkaXNwYXRjaGVyXCIpO1xyXG4vLyBpbXBvcnQge1NldHRpbmdzVG9nZ2xlQnV0dG9ufSBmcm9tICcuL2NvbXBvbmVudHMvc2V0dGluZ3N0b2dnbGVidXR0b24nO1xyXG4vLyBpbXBvcnQge1NldHRpbmdzUGFuZWwsIFNldHRpbmdzUGFuZWxJdGVtfSBmcm9tICcuL2NvbXBvbmVudHMvc2V0dGluZ3NwYW5lbCc7XHJcbi8vIGltcG9ydCB7VmlkZW9RdWFsaXR5U2VsZWN0Qm94fSBmcm9tICcuL2NvbXBvbmVudHMvdmlkZW9xdWFsaXR5c2VsZWN0Ym94JztcclxuLy8gaW1wb3J0IHtXYXRlcm1hcmt9IGZyb20gJy4vY29tcG9uZW50cy93YXRlcm1hcmsnO1xyXG4vLyBpbXBvcnQge0F1ZGlvUXVhbGl0eVNlbGVjdEJveH0gZnJvbSAnLi9jb21wb25lbnRzL2F1ZGlvcXVhbGl0eXNlbGVjdGJveCc7XHJcbi8vIGltcG9ydCB7QXVkaW9UcmFja1NlbGVjdEJveH0gZnJvbSAnLi9jb21wb25lbnRzL2F1ZGlvdHJhY2tzZWxlY3Rib3gnO1xyXG52YXIgc2Vla2JhcmxhYmVsXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL3NlZWtiYXJsYWJlbFwiKTtcclxuLy8gaW1wb3J0IHtWb2x1bWVTbGlkZXJ9IGZyb20gJy4vY29tcG9uZW50cy92b2x1bWVzbGlkZXInO1xyXG52YXIgc3VidGl0bGVzZWxlY3Rib3hfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvc3VidGl0bGVzZWxlY3Rib3hcIik7XHJcbnZhciBzdWJ0aXRsZW92ZXJsYXlfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvc3VidGl0bGVvdmVybGF5XCIpO1xyXG52YXIgdm9sdW1lY29udHJvbGJ1dHRvbl8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy92b2x1bWVjb250cm9sYnV0dG9uXCIpO1xyXG4vLyBpbXBvcnQge0Nhc3RUb2dnbGVCdXR0b259IGZyb20gJy4vY29tcG9uZW50cy9jYXN0dG9nZ2xlYnV0dG9uJztcclxuLy8gaW1wb3J0IHtDYXN0U3RhdHVzT3ZlcmxheX0gZnJvbSAnLi9jb21wb25lbnRzL2Nhc3RzdGF0dXNvdmVybGF5JztcclxudmFyIGVycm9ybWVzc2FnZW92ZXJsYXlfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvZXJyb3JtZXNzYWdlb3ZlcmxheVwiKTtcclxuLy8gaW1wb3J0IHtQbGF5YmFja1NwZWVkU2VsZWN0Qm94fSBmcm9tICcuL2NvbXBvbmVudHMvcGxheWJhY2tzcGVlZHNlbGVjdGJveCc7XHJcbi8vIGltcG9ydCB7QnVmZmVyaW5nT3ZlcmxheX0gZnJvbSAnLi9jb21wb25lbnRzL2J1ZmZlcmluZ292ZXJsYXknO1xyXG52YXIgcGxheWJhY2t0b2dnbGVvdmVybGF5XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL3BsYXliYWNrdG9nZ2xlb3ZlcmxheVwiKTtcclxuLy8gaW1wb3J0IHtBaXJQbGF5VG9nZ2xlQnV0dG9ufSBmcm9tICcuL2NvbXBvbmVudHMvYWlycGxheXRvZ2dsZWJ1dHRvbic7XHJcbi8vIGltcG9ydCB7UGljdHVyZUluUGljdHVyZVRvZ2dsZUJ1dHRvbn0gZnJvbSAnLi9jb21wb25lbnRzL3BpY3R1cmVpbnBpY3R1cmV0b2dnbGVidXR0b24nO1xyXG52YXIgYXVkaW9vbmx5b3ZlcmxheV8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9hdWRpb29ubHlvdmVybGF5XCIpO1xyXG4vLyBpbXBvcnQge1NwYWNlcn0gZnJvbSAnLi9jb21wb25lbnRzL3NwYWNlcic7XHJcbnZhciB1aXV0aWxzXzEgPSByZXF1aXJlKFwiLi91aXV0aWxzXCIpO1xyXG52YXIgYXJyYXl1dGlsc18xID0gcmVxdWlyZShcIi4vYXJyYXl1dGlsc1wiKTtcclxudmFyIGJyb3dzZXJ1dGlsc18xID0gcmVxdWlyZShcIi4vYnJvd3NlcnV0aWxzXCIpO1xyXG52YXIgVUlNYW5hZ2VyID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIFVJTWFuYWdlcihwbGF5ZXIsIHBsYXllclVpT3JVaVZhcmlhbnRzLCBjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIGlmIChwbGF5ZXJVaU9yVWlWYXJpYW50cyBpbnN0YW5jZW9mIHVpY29udGFpbmVyXzEuVUlDb250YWluZXIpIHtcclxuICAgICAgICAgICAgLy8gU2luZ2xlLVVJIGNvbnN0cnVjdG9yIGhhcyBiZWVuIGNhbGxlZCwgdHJhbnNmb3JtIGFyZ3VtZW50cyB0byBVSVZhcmlhbnRbXSBzaWduYXR1cmVcclxuICAgICAgICAgICAgdmFyIHBsYXllclVpID0gcGxheWVyVWlPclVpVmFyaWFudHM7XHJcbiAgICAgICAgICAgIHZhciBhZHNVaSA9IG51bGw7XHJcbiAgICAgICAgICAgIHZhciB1aVZhcmlhbnRzID0gW107XHJcbiAgICAgICAgICAgIC8vIEFkZCB0aGUgYWRzIFVJIGlmIGRlZmluZWRcclxuICAgICAgICAgICAgaWYgKGFkc1VpKSB7XHJcbiAgICAgICAgICAgICAgICB1aVZhcmlhbnRzLnB1c2goe1xyXG4gICAgICAgICAgICAgICAgICAgIHVpOiBhZHNVaSxcclxuICAgICAgICAgICAgICAgICAgICBjb25kaXRpb246IGZ1bmN0aW9uIChjb250ZXh0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBjb250ZXh0LmlzQWRXaXRoVUk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIEFkZCB0aGUgZGVmYXVsdCBwbGF5ZXIgVUlcclxuICAgICAgICAgICAgdWlWYXJpYW50cy5wdXNoKHsgdWk6IHBsYXllclVpIH0pO1xyXG4gICAgICAgICAgICB0aGlzLnVpVmFyaWFudHMgPSB1aVZhcmlhbnRzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgLy8gRGVmYXVsdCBjb25zdHJ1Y3RvciAoVUlWYXJpYW50W10pIGhhcyBiZWVuIGNhbGxlZFxyXG4gICAgICAgICAgICB0aGlzLnVpVmFyaWFudHMgPSBwbGF5ZXJVaU9yVWlWYXJpYW50cztcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5wbGF5ZXIgPSBwbGF5ZXI7XHJcbiAgICAgICAgdGhpcy5jb25maWcgPSBjb25maWc7XHJcbiAgICAgICAgdGhpcy5tYW5hZ2VyUGxheWVyV3JhcHBlciA9IG5ldyBQbGF5ZXJXcmFwcGVyKHBsYXllcik7XHJcbiAgICAgICAgaWYgKGNvbmZpZy5jb250YWluZXIpIHtcclxuICAgICAgICAgICAgLy8gVW5mb3J0dW5hdGVseSBcInVpQ29udGFpbmVyRWxlbWVudCA9IG5ldyBET00oY29uZmlnLmNvbnRhaW5lcilcIiB3aWxsIG5vdCBhY2NlcHQgdGhlIGNvbnRhaW5lciB3aXRoXHJcbiAgICAgICAgICAgIC8vIHN0cmluZ3xIVE1MRWxlbWVudCB0eXBlIGRpcmVjdGx5LCBhbHRob3VnaCBpdCBhY2NlcHRzIGJvdGggdHlwZXMsIHNvIHdlIG5lZWQgdG8gc3BpdCB0aGVzZSB0d28gY2FzZXMgdXAgaGVyZS5cclxuICAgICAgICAgICAgLy8gVE9ETyBjaGVjayBpbiB1cGNvbWluZyBUUyB2ZXJzaW9ucyBpZiB0aGUgY29udGFpbmVyIGNhbiBiZSBwYXNzZWQgaW4gZGlyZWN0bHksIG9yIGZpeCB0aGUgY29uc3RydWN0b3JcclxuICAgICAgICAgICAgdGhpcy51aUNvbnRhaW5lckVsZW1lbnQgPSBjb25maWcuY29udGFpbmVyIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQgP1xyXG4gICAgICAgICAgICAgICAgbmV3IGRvbV8xLkRPTShjb25maWcuY29udGFpbmVyKSA6IG5ldyBkb21fMS5ET00oY29uZmlnLmNvbnRhaW5lcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLnVpQ29udGFpbmVyRWxlbWVudCA9IG5ldyBkb21fMS5ET00ocGxheWVyLmdldEZpZ3VyZSgpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gQ3JlYXRlIFVJIGluc3RhbmNlIG1hbmFnZXJzIGZvciB0aGUgVUkgdmFyaWFudHNcclxuICAgICAgICAvLyBUaGUgaW5zdGFuY2UgbWFuYWdlcnMgbWFwIHRvIHRoZSBjb3JyZXNwb25kaW5nIFVJIHZhcmlhbnRzIGJ5IHRoZWlyIGFycmF5IGluZGV4XHJcbiAgICAgICAgdGhpcy51aUluc3RhbmNlTWFuYWdlcnMgPSBbXTtcclxuICAgICAgICB2YXIgdWlWYXJpYW50c1dpdGhvdXRDb25kaXRpb24gPSBbXTtcclxuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdGhpcy51aVZhcmlhbnRzOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICB2YXIgdWlWYXJpYW50ID0gX2FbX2ldO1xyXG4gICAgICAgICAgICBpZiAodWlWYXJpYW50LmNvbmRpdGlvbiA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBDb2xsZWN0IHZhcmlhbnRzIHdpdGhvdXQgY29uZGl0aW9ucyBmb3IgZXJyb3IgY2hlY2tpbmdcclxuICAgICAgICAgICAgICAgIHVpVmFyaWFudHNXaXRob3V0Q29uZGl0aW9uLnB1c2godWlWYXJpYW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBDcmVhdGUgdGhlIGluc3RhbmNlIG1hbmFnZXIgZm9yIGEgVUkgdmFyaWFudFxyXG4gICAgICAgICAgICB0aGlzLnVpSW5zdGFuY2VNYW5hZ2Vycy5wdXNoKG5ldyBJbnRlcm5hbFVJSW5zdGFuY2VNYW5hZ2VyKHBsYXllciwgdWlWYXJpYW50LnVpLCB0aGlzLmNvbmZpZykpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCB0aGVyZSBpcyBvbmx5IG9uZSBVSSB2YXJpYW50IHdpdGhvdXQgYSBjb25kaXRpb25cclxuICAgICAgICAvLyBJdCBkb2VzIG5vdCBtYWtlIHNlbnNlIHRvIGhhdmUgbXVsdGlwbGUgdmFyaWFudHMgd2l0aG91dCBjb25kaXRpb24sIGJlY2F1c2Ugb25seSB0aGUgZmlyc3Qgb25lIGluIHRoZSBsaXN0XHJcbiAgICAgICAgLy8gKHRoZSBvbmUgd2l0aCB0aGUgbG93ZXN0IGluZGV4KSB3aWxsIGV2ZXIgYmUgc2VsZWN0ZWQuXHJcbiAgICAgICAgaWYgKHVpVmFyaWFudHNXaXRob3V0Q29uZGl0aW9uLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ1RvbyBtYW55IFVJcyB3aXRob3V0IGEgY29uZGl0aW9uOiBZb3UgY2Fubm90IGhhdmUgbW9yZSB0aGFuIG9uZSBkZWZhdWx0IFVJJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBkZWZhdWx0IFVJIHZhcmlhbnQsIGlmIGRlZmluZWQsIGlzIGF0IHRoZSBlbmQgb2YgdGhlIGxpc3QgKGxhc3QgaW5kZXgpXHJcbiAgICAgICAgLy8gSWYgaXQgY29tZXMgZWFybGllciwgdGhlIHZhcmlhbnRzIHdpdGggY29uZGl0aW9ucyB0aGF0IGNvbWUgYWZ0ZXJ3YXJkcyB3aWxsIG5ldmVyIGJlIHNlbGVjdGVkIGJlY2F1c2UgdGhlXHJcbiAgICAgICAgLy8gZGVmYXVsdCB2YXJpYW50IHdpdGhvdXQgYSBjb25kaXRpb24gYWx3YXlzIGV2YWx1YXRlcyB0byAndHJ1ZSdcclxuICAgICAgICBpZiAodWlWYXJpYW50c1dpdGhvdXRDb25kaXRpb24ubGVuZ3RoID4gMFxyXG4gICAgICAgICAgICAmJiB1aVZhcmlhbnRzV2l0aG91dENvbmRpdGlvblswXSAhPT0gdGhpcy51aVZhcmlhbnRzW3RoaXMudWlWYXJpYW50cy5sZW5ndGggLSAxXSkge1xyXG4gICAgICAgICAgICB0aHJvdyBFcnJvcignSW52YWxpZCBVSSB2YXJpYW50IG9yZGVyOiB0aGUgZGVmYXVsdCBVSSAod2l0aG91dCBjb25kaXRpb24pIG11c3QgYmUgYXQgdGhlIGVuZCBvZiB0aGUgbGlzdCcpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgYWRTdGFydGVkRXZlbnQgPSBudWxsOyAvLyBrZWVwIHRoZSBldmVudCBzdG9yZWQgaGVyZSBkdXJpbmcgYWQgcGxheWJhY2tcclxuICAgICAgICB2YXIgaXNNb2JpbGUgPSBicm93c2VydXRpbHNfMS5Ccm93c2VyVXRpbHMuaXNNb2JpbGU7XHJcbiAgICAgICAgLy8gRHluYW1pY2FsbHkgc2VsZWN0IGEgVUkgdmFyaWFudCB0aGF0IG1hdGNoZXMgdGhlIGN1cnJlbnQgVUkgY29uZGl0aW9uLlxyXG4gICAgICAgIHZhciByZXNvbHZlVWlWYXJpYW50ID0gZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgIC8vIE1ha2Ugc3VyZSB0aGF0IHRoZSBPTl9BRF9TVEFSVEVEIGV2ZW50IGRhdGEgaXMgcGVyc2lzdGVkIHRocm91Z2ggYWQgcGxheWJhY2sgaW4gY2FzZSBvdGhlciBldmVudHMgaGFwcGVuXHJcbiAgICAgICAgICAgIC8vIGluIHRoZSBtZWFudGltZSwgZS5nLiBwbGF5ZXIgcmVzaXplLiBXZSBuZWVkIHRvIHN0b3JlIHRoaXMgZGF0YSBiZWNhdXNlIHRoZXJlIGlzIG5vIG90aGVyIHdheSB0byBmaW5kIG91dFxyXG4gICAgICAgICAgICAvLyBhZCBkZXRhaWxzIChlLmcuIHRoZSBhZCBjbGllbnQpIHdoaWxlIGFuIGFkIGlzIHBsYXlpbmcuXHJcbiAgICAgICAgICAgIC8vIEV4aXN0aW5nIGV2ZW50IGRhdGEgc2lnbmFscyB0aGF0IGFuIGFkIGlzIGN1cnJlbnRseSBhY3RpdmUuIFdlIGNhbm5vdCB1c2UgcGxheWVyLmlzQWQoKSBiZWNhdXNlIGl0IHJldHVybnNcclxuICAgICAgICAgICAgLy8gdHJ1ZSBvbiBhZCBzdGFydCBhbmQgYWxzbyBvbiBhZCBlbmQgZXZlbnRzLCB3aGljaCBpcyBwcm9ibGVtYXRpYy5cclxuICAgICAgICAgICAgaWYgKGV2ZW50ICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIHN3aXRjaCAoZXZlbnQudHlwZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gdGhlIGFkIHN0YXJ0cywgd2Ugc3RvcmUgdGhlIGV2ZW50IGRhdGFcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIHBsYXllci5FVkVOVC5PTl9BRF9TVEFSVEVEOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZFN0YXJ0ZWRFdmVudCA9IGV2ZW50O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHRoZSBhZCBlbmRzLCB3ZSBkZWxldGUgdGhlIGV2ZW50IGRhdGFcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIHBsYXllci5FVkVOVC5PTl9BRF9GSU5JU0hFRDpcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIHBsYXllci5FVkVOVC5PTl9BRF9TS0lQUEVEOlxyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgcGxheWVyLkVWRU5ULk9OX0FEX0VSUk9SOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBhZFN0YXJ0ZWRFdmVudCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIFdoZW4gYSBuZXcgc291cmNlIGlzIGxvYWRlZCBkdXJpbmcgYWQgcGxheWJhY2ssIHRoZXJlIHdpbGwgYmUgbm8gYWQgZW5kIGV2ZW50IHNvIHdlIGRldGVjdCB0aGUgZW5kXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gb2YgdGhlIGFkIHBsYXliYWNrIGJ5IGNoZWNraW5nIGlzQWQoKSBpbiBPTl9SRUFEWSwgYmVjYXVzZSBPTl9SRUFEWSBhbHdheXMgYXJyaXZlcyB3aGVuIHRoZSBzb3VyY2VcclxuICAgICAgICAgICAgICAgICAgICAvLyBjaGFuZ2VzLlxyXG4gICAgICAgICAgICAgICAgICAgIGNhc2UgcGxheWVyLkVWRU5ULk9OX1JFQURZOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWRTdGFydGVkRXZlbnQgJiYgIXBsYXllci5pc0FkKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFkU3RhcnRlZEV2ZW50ID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIERldGVjdCBpZiBhbiBhZCBoYXMgc3RhcnRlZFxyXG4gICAgICAgICAgICB2YXIgYWQgPSBhZFN0YXJ0ZWRFdmVudCAhPSBudWxsO1xyXG4gICAgICAgICAgICB2YXIgYWRXaXRoVUkgPSBhZCAmJiBhZFN0YXJ0ZWRFdmVudC5jbGllbnRUeXBlID09PSAndmFzdCc7XHJcbiAgICAgICAgICAgIC8vIERldGVybWluZSB0aGUgY3VycmVudCBjb250ZXh0IGZvciB3aGljaCB0aGUgVUkgdmFyaWFudCB3aWxsIGJlIHJlc29sdmVkXHJcbiAgICAgICAgICAgIHZhciBjb250ZXh0ID0ge1xyXG4gICAgICAgICAgICAgICAgaXNBZDogYWQsXHJcbiAgICAgICAgICAgICAgICBpc0FkV2l0aFVJOiBhZFdpdGhVSSxcclxuICAgICAgICAgICAgICAgIGFkQ2xpZW50VHlwZTogYWQgPyBhZFN0YXJ0ZWRFdmVudC5jbGllbnRUeXBlIDogbnVsbCxcclxuICAgICAgICAgICAgICAgIGlzRnVsbHNjcmVlbjogX3RoaXMucGxheWVyLmlzRnVsbHNjcmVlbigpLFxyXG4gICAgICAgICAgICAgICAgaXNNb2JpbGU6IGlzTW9iaWxlLFxyXG4gICAgICAgICAgICAgICAgaXNQbGF5aW5nOiBfdGhpcy5wbGF5ZXIuaXNQbGF5aW5nKCksXHJcbiAgICAgICAgICAgICAgICB3aWR0aDogX3RoaXMudWlDb250YWluZXJFbGVtZW50LndpZHRoKCksXHJcbiAgICAgICAgICAgICAgICBkb2N1bWVudFdpZHRoOiBkb2N1bWVudC5ib2R5LmNsaWVudFdpZHRoLFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB2YXIgbmV4dFVpID0gbnVsbDtcclxuICAgICAgICAgICAgdmFyIHVpVmFyaWFudENoYW5nZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgLy8gU2VsZWN0IG5ldyBVSSB2YXJpYW50XHJcbiAgICAgICAgICAgIC8vIElmIG5vIHZhcmlhbnQgY29uZGl0aW9uIGlzIGZ1bGZpbGxlZCwgd2Ugc3dpdGNoIHRvICpubyogVUlcclxuICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IF90aGlzLnVpVmFyaWFudHM7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgdWlWYXJpYW50ID0gX2FbX2ldO1xyXG4gICAgICAgICAgICAgICAgaWYgKHVpVmFyaWFudC5jb25kaXRpb24gPT0gbnVsbCB8fCB1aVZhcmlhbnQuY29uZGl0aW9uKGNvbnRleHQpID09PSB0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmV4dFVpID0gX3RoaXMudWlJbnN0YW5jZU1hbmFnZXJzW190aGlzLnVpVmFyaWFudHMuaW5kZXhPZih1aVZhcmlhbnQpXTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBEZXRlcm1pbmUgaWYgdGhlIFVJIHZhcmlhbnQgaXMgY2hhbmdpbmdcclxuICAgICAgICAgICAgaWYgKG5leHRVaSAhPT0gX3RoaXMuY3VycmVudFVpKSB7XHJcbiAgICAgICAgICAgICAgICB1aVZhcmlhbnRDaGFuZ2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdzd2l0Y2hlZCBmcm9tICcsIHRoaXMuY3VycmVudFVpID8gdGhpcy5jdXJyZW50VWkuZ2V0VUkoKSA6ICdub25lJyxcclxuICAgICAgICAgICAgICAgIC8vICAgJyB0byAnLCBuZXh0VWkgPyBuZXh0VWkuZ2V0VUkoKSA6ICdub25lJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gT25seSBpZiB0aGUgVUkgdmFyaWFudCBpcyBjaGFuZ2luZywgd2UgbmVlZCB0byBkbyBzb21lIHN0dWZmLiBFbHNlIHdlIGp1c3QgbGVhdmUgZXZlcnl0aGluZyBhcy1pcy5cclxuICAgICAgICAgICAgaWYgKHVpVmFyaWFudENoYW5nZWQpIHtcclxuICAgICAgICAgICAgICAgIC8vIEhpZGUgdGhlIGN1cnJlbnRseSBhY3RpdmUgVUkgdmFyaWFudFxyXG4gICAgICAgICAgICAgICAgaWYgKF90aGlzLmN1cnJlbnRVaSkge1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmN1cnJlbnRVaS5nZXRVSSgpLmhpZGUoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIEFzc2lnbiB0aGUgbmV3IFVJIHZhcmlhbnQgYXMgY3VycmVudCBVSVxyXG4gICAgICAgICAgICAgICAgX3RoaXMuY3VycmVudFVpID0gbmV4dFVpO1xyXG4gICAgICAgICAgICAgICAgLy8gV2hlbiB3ZSBzd2l0Y2ggdG8gYSBkaWZmZXJlbnQgVUkgaW5zdGFuY2UsIHRoZXJlJ3Mgc29tZSBhZGRpdGlvbmFsIHN0dWZmIHRvIG1hbmFnZS4gSWYgd2UgZG8gbm90IHN3aXRjaFxyXG4gICAgICAgICAgICAgICAgLy8gdG8gYW4gaW5zdGFuY2UsIHdlJ3JlIGRvbmUgaGVyZS5cclxuICAgICAgICAgICAgICAgIGlmIChfdGhpcy5jdXJyZW50VWkgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIEFkZCB0aGUgVUkgdG8gdGhlIERPTSAoYW5kIGNvbmZpZ3VyZSBpdCkgdGhlIGZpcnN0IHRpbWUgaXQgaXMgc2VsZWN0ZWRcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIV90aGlzLmN1cnJlbnRVaS5pc0NvbmZpZ3VyZWQoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5hZGRVaShfdGhpcy5jdXJyZW50VWkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAvLyBJZiB0aGlzIGlzIGFuIGFkIFVJLCB3ZSBuZWVkIHRvIHJlbGF5IHRoZSBzYXZlZCBPTl9BRF9TVEFSVEVEIGV2ZW50IGRhdGEgc28gYWQgY29tcG9uZW50cyBjYW4gY29uZmlndXJlXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gdGhlbXNlbHZlcyBmb3IgdGhlIGN1cnJlbnQgYWQuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbnRleHQuaXNBZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvKiBSZWxheSB0aGUgT05fQURfU1RBUlRFRCBldmVudCB0byB0aGUgYWRzIFVJXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAqXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAqIEJlY2F1c2UgdGhlIGFkcyBVSSBpcyBpbml0aWFsaXplZCBpbiB0aGUgT05fQURfU1RBUlRFRCBoYW5kbGVyLCBpLmUuIHdoZW4gdGhlIE9OX0FEX1NUQVJURUQgZXZlbnQgaGFzXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAqIGFscmVhZHkgYmVlbiBmaXJlZCwgY29tcG9uZW50cyBpbiB0aGUgYWRzIFVJIHRoYXQgbGlzdGVuIGZvciB0aGUgT05fQURfU1RBUlRFRCBldmVudCBuZXZlciByZWNlaXZlIGl0LlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgKiBTaW5jZSB0aGlzIGNhbiBicmVhayBmdW5jdGlvbmFsaXR5IG9mIGNvbXBvbmVudHMgdGhhdCByZWx5IG9uIHRoaXMgZXZlbnQsIHdlIHJlbGF5IHRoZSBldmVudCB0byB0aGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgICogYWRzIFVJIGNvbXBvbmVudHMgd2l0aCB0aGUgZm9sbG93aW5nIGNhbGwuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBfdGhpcy5jdXJyZW50VWkuZ2V0V3JhcHBlZFBsYXllcigpLmZpcmVFdmVudEluVUkoX3RoaXMucGxheWVyLkVWRU5ULk9OX0FEX1NUQVJURUQsIGFkU3RhcnRlZEV2ZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuY3VycmVudFVpLmdldFVJKCkuc2hvdygpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvLyBMaXN0ZW4gdG8gdGhlIGZvbGxvd2luZyBldmVudHMgdG8gdHJpZ2dlciBVSSB2YXJpYW50IHJlc29sdXRpb25cclxuICAgICAgICB0aGlzLm1hbmFnZXJQbGF5ZXJXcmFwcGVyLmdldFBsYXllcigpLmFkZEV2ZW50SGFuZGxlcih0aGlzLnBsYXllci5FVkVOVC5PTl9SRUFEWSwgcmVzb2x2ZVVpVmFyaWFudCk7XHJcbiAgICAgICAgdGhpcy5tYW5hZ2VyUGxheWVyV3JhcHBlci5nZXRQbGF5ZXIoKS5hZGRFdmVudEhhbmRsZXIodGhpcy5wbGF5ZXIuRVZFTlQuT05fUExBWSwgcmVzb2x2ZVVpVmFyaWFudCk7XHJcbiAgICAgICAgdGhpcy5tYW5hZ2VyUGxheWVyV3JhcHBlci5nZXRQbGF5ZXIoKS5hZGRFdmVudEhhbmRsZXIodGhpcy5wbGF5ZXIuRVZFTlQuT05fUEFVU0VELCByZXNvbHZlVWlWYXJpYW50KTtcclxuICAgICAgICB0aGlzLm1hbmFnZXJQbGF5ZXJXcmFwcGVyLmdldFBsYXllcigpLmFkZEV2ZW50SGFuZGxlcih0aGlzLnBsYXllci5FVkVOVC5PTl9BRF9TVEFSVEVELCByZXNvbHZlVWlWYXJpYW50KTtcclxuICAgICAgICB0aGlzLm1hbmFnZXJQbGF5ZXJXcmFwcGVyLmdldFBsYXllcigpLmFkZEV2ZW50SGFuZGxlcih0aGlzLnBsYXllci5FVkVOVC5PTl9BRF9GSU5JU0hFRCwgcmVzb2x2ZVVpVmFyaWFudCk7XHJcbiAgICAgICAgdGhpcy5tYW5hZ2VyUGxheWVyV3JhcHBlci5nZXRQbGF5ZXIoKS5hZGRFdmVudEhhbmRsZXIodGhpcy5wbGF5ZXIuRVZFTlQuT05fQURfU0tJUFBFRCwgcmVzb2x2ZVVpVmFyaWFudCk7XHJcbiAgICAgICAgdGhpcy5tYW5hZ2VyUGxheWVyV3JhcHBlci5nZXRQbGF5ZXIoKS5hZGRFdmVudEhhbmRsZXIodGhpcy5wbGF5ZXIuRVZFTlQuT05fQURfRVJST1IsIHJlc29sdmVVaVZhcmlhbnQpO1xyXG4gICAgICAgIHRoaXMubWFuYWdlclBsYXllcldyYXBwZXIuZ2V0UGxheWVyKCkuYWRkRXZlbnRIYW5kbGVyKHRoaXMucGxheWVyLkVWRU5ULk9OX1BMQVlFUl9SRVNJWkUsIHJlc29sdmVVaVZhcmlhbnQpO1xyXG4gICAgICAgIHRoaXMubWFuYWdlclBsYXllcldyYXBwZXIuZ2V0UGxheWVyKCkuYWRkRXZlbnRIYW5kbGVyKHRoaXMucGxheWVyLkVWRU5ULk9OX0ZVTExTQ1JFRU5fRU5URVIsIHJlc29sdmVVaVZhcmlhbnQpO1xyXG4gICAgICAgIHRoaXMubWFuYWdlclBsYXllcldyYXBwZXIuZ2V0UGxheWVyKCkuYWRkRXZlbnRIYW5kbGVyKHRoaXMucGxheWVyLkVWRU5ULk9OX0ZVTExTQ1JFRU5fRVhJVCwgcmVzb2x2ZVVpVmFyaWFudCk7XHJcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSB0aGUgVUlcclxuICAgICAgICByZXNvbHZlVWlWYXJpYW50KG51bGwpO1xyXG4gICAgfVxyXG4gICAgVUlNYW5hZ2VyLnByb3RvdHlwZS5nZXRDb25maWcgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnO1xyXG4gICAgfTtcclxuICAgIFVJTWFuYWdlci5wcm90b3R5cGUuYWRkVWkgPSBmdW5jdGlvbiAodWkpIHtcclxuICAgICAgICB2YXIgZG9tID0gdWkuZ2V0VUkoKS5nZXREb21FbGVtZW50KCk7XHJcbiAgICAgICAgdmFyIHBsYXllciA9IHVpLmdldFdyYXBwZWRQbGF5ZXIoKTtcclxuICAgICAgICB1aS5jb25maWd1cmVDb250cm9scygpO1xyXG4gICAgICAgIC8qIEFwcGVuZCB0aGUgVUkgRE9NIGFmdGVyIGNvbmZpZ3VyYXRpb24gdG8gYXZvaWQgQ1NTIHRyYW5zaXRpb25zIGF0IGluaXRpYWxpemF0aW9uXHJcbiAgICAgICAgICogRXhhbXBsZTogQ29tcG9uZW50cyBhcmUgaGlkZGVuIGR1cmluZyBjb25maWd1cmF0aW9uIGFuZCB0aGVzZSBoaWRlcyBtYXkgdHJpZ2dlciBDU1MgdHJhbnNpdGlvbnMgdGhhdCBhcmVcclxuICAgICAgICAgKiB1bmRlc2lyYWJsZSBhdCB0aGlzIHRpbWUuICovXHJcbiAgICAgICAgdGhpcy51aUNvbnRhaW5lckVsZW1lbnQuYXBwZW5kKGRvbSk7XHJcbiAgICAgICAgLy8gU29tZSBjb21wb25lbnRzIGluaXRpYWxpemUgdGhlaXIgc3RhdGUgb24gT05fUkVBRFkuIFdoZW4gdGhlIFVJIGlzIGxvYWRlZCBhZnRlciB0aGUgcGxheWVyIGlzIGFscmVhZHkgcmVhZHksXHJcbiAgICAgICAgLy8gdGhleSB3aWxsIG5ldmVyIHJlY2VpdmUgdGhlIGV2ZW50IHNvIHdlIGZpcmUgaXQgZnJvbSBoZXJlIGluIHN1Y2ggY2FzZXMuXHJcbiAgICAgICAgaWYgKHBsYXllci5pc1JlYWR5KCkpIHtcclxuICAgICAgICAgICAgcGxheWVyLmZpcmVFdmVudEluVUkocGxheWVyLkVWRU5ULk9OX1JFQURZLCB7fSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIEZpcmUgb25Db25maWd1cmVkIGFmdGVyIFVJIERPTSBlbGVtZW50cyBhcmUgc3VjY2Vzc2Z1bGx5IGFkZGVkLiBXaGVuIGZpcmVkIGltbWVkaWF0ZWx5LCB0aGUgRE9NIGVsZW1lbnRzXHJcbiAgICAgICAgLy8gbWlnaHQgbm90IGJlIGZ1bGx5IGNvbmZpZ3VyZWQgYW5kIGUuZy4gZG8gbm90IGhhdmUgYSBzaXplLlxyXG4gICAgICAgIC8vIGh0dHBzOi8vc3dpemVjLmNvbS9ibG9nL2hvdy10by1wcm9wZXJseS13YWl0LWZvci1kb20tZWxlbWVudHMtdG8tc2hvdy11cC1pbi1tb2Rlcm4tYnJvd3NlcnMvc3dpemVjLzY2NjNcclxuICAgICAgICBpZiAod2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSkge1xyXG4gICAgICAgICAgICByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoZnVuY3Rpb24gKCkgeyB1aS5vbkNvbmZpZ3VyZWQuZGlzcGF0Y2godWkuZ2V0VUkoKSk7IH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgLy8gSUU5IGZhbGxiYWNrXHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyB1aS5vbkNvbmZpZ3VyZWQuZGlzcGF0Y2godWkuZ2V0VUkoKSk7IH0sIDApO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBVSU1hbmFnZXIucHJvdG90eXBlLnJlbGVhc2VVaSA9IGZ1bmN0aW9uICh1aSkge1xyXG4gICAgICAgIHVpLnJlbGVhc2VDb250cm9scygpO1xyXG4gICAgICAgIHVpLmdldFVJKCkuZ2V0RG9tRWxlbWVudCgpLnJlbW92ZSgpO1xyXG4gICAgICAgIHVpLmNsZWFyRXZlbnRIYW5kbGVycygpO1xyXG4gICAgfTtcclxuICAgIFVJTWFuYWdlci5wcm90b3R5cGUucmVsZWFzZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdGhpcy51aUluc3RhbmNlTWFuYWdlcnM7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgIHZhciB1aUluc3RhbmNlTWFuYWdlciA9IF9hW19pXTtcclxuICAgICAgICAgICAgdGhpcy5yZWxlYXNlVWkodWlJbnN0YW5jZU1hbmFnZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLm1hbmFnZXJQbGF5ZXJXcmFwcGVyLmNsZWFyRXZlbnRIYW5kbGVycygpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBVSU1hbmFnZXI7XHJcbn0oKSk7XHJcbmV4cG9ydHMuVUlNYW5hZ2VyID0gVUlNYW5hZ2VyO1xyXG4oZnVuY3Rpb24gKFVJTWFuYWdlcikge1xyXG4gICAgdmFyIEZhY3Rvcnk7XHJcbiAgICAoZnVuY3Rpb24gKEZhY3RvcnkpIHtcclxuICAgICAgICBmdW5jdGlvbiBidWlsZEF1ZGlvVmlkZW9VSShwbGF5ZXIsIGNvbmZpZykge1xyXG4gICAgICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICAgICAgdmFyIGNvbnRyb2xCYXIgPSBuZXcgY29udHJvbGJhcl8xLkNvbnRyb2xCYXIoe1xyXG4gICAgICAgICAgICAgICAgY29tcG9uZW50czogW1xyXG4gICAgICAgICAgICAgICAgICAgIG5ldyBwbGF5YmFja3RvZ2dsZWJ1dHRvbl8xLlBsYXliYWNrVG9nZ2xlQnV0dG9uKCksXHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IHNlZWtiYXJfMS5TZWVrQmFyKHsgbGFiZWw6IG5ldyBzZWVrYmFybGFiZWxfMS5TZWVrQmFyTGFiZWwoKSB9KSxcclxuICAgICAgICAgICAgICAgICAgICBuZXcgcGxheWJhY2t0aW1lbGFiZWxfMS5QbGF5YmFja1RpbWVMYWJlbCgpLFxyXG4gICAgICAgICAgICAgICAgICAgIG5ldyB2b2x1bWVjb250cm9sYnV0dG9uXzEuVm9sdW1lQ29udHJvbEJ1dHRvbih7ICd2ZXJ0aWNhbCc6IHRydWUgfSksXHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IGZ1bGxzY3JlZW50b2dnbGVidXR0b25fMS5GdWxsc2NyZWVuVG9nZ2xlQnV0dG9uKCksXHJcbiAgICAgICAgICAgICAgICBdLFxyXG4gICAgICAgICAgICB9LCB0cnVlKTtcclxuICAgICAgICAgICAgdmFyIHVpID0gbmV3IHVpY29udGFpbmVyXzEuVUlDb250YWluZXIoe1xyXG4gICAgICAgICAgICAgICAgY29tcG9uZW50czogW1xyXG4gICAgICAgICAgICAgICAgICAgIG5ldyBwbGF5YmFja3RvZ2dsZW92ZXJsYXlfMS5QbGF5YmFja1RvZ2dsZU92ZXJsYXkoKSxcclxuICAgICAgICAgICAgICAgICAgICBjb250cm9sQmFyLFxyXG4gICAgICAgICAgICAgICAgICAgIG5ldyBlcnJvcm1lc3NhZ2VvdmVybGF5XzEuRXJyb3JNZXNzYWdlT3ZlcmxheSgpLFxyXG4gICAgICAgICAgICAgICAgXSwgY3NzQ2xhc3NlczogWyd1aS1za2luJ10sXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAvLyBKdXN0IGhlcmUgdG8gYXZvaWQgbGludGVyIGVycm9yc1xyXG4gICAgICAgICAgICB2YXIgc3NCb3ggPSBuZXcgc3VidGl0bGVzZWxlY3Rib3hfMS5TdWJ0aXRsZVNlbGVjdEJveCgpO1xyXG4gICAgICAgICAgICBzc0JveC5oaWRlKCk7XHJcbiAgICAgICAgICAgIHZhciBzc092ZXJsYXkgPSBuZXcgc3VidGl0bGVvdmVybGF5XzEuU3VidGl0bGVPdmVybGF5KCk7XHJcbiAgICAgICAgICAgIHNzT3ZlcmxheS5oaWRlKCk7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgVUlNYW5hZ2VyKHBsYXllciwgdWksIGNvbmZpZyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIEZhY3RvcnkuYnVpbGRBdWRpb1ZpZGVvVUkgPSBidWlsZEF1ZGlvVmlkZW9VSTtcclxuICAgICAgICBmdW5jdGlvbiBidWlsZEF1ZGlvT25seVVJKHBsYXllciwgY29uZmlnKSB7XHJcbiAgICAgICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgICAgICB2YXIgY29udHJvbEJhciA9IG5ldyBjb250cm9sYmFyXzEuQ29udHJvbEJhcih7XHJcbiAgICAgICAgICAgICAgICBjb21wb25lbnRzOiBbXHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IHBsYXliYWNrdG9nZ2xlYnV0dG9uXzEuUGxheWJhY2tUb2dnbGVCdXR0b24oKSxcclxuICAgICAgICAgICAgICAgICAgICBuZXcgc2Vla2Jhcl8xLlNlZWtCYXIoeyBsYWJlbDogbmV3IHNlZWtiYXJsYWJlbF8xLlNlZWtCYXJMYWJlbCgpLCBoaWRlSW5MaXZlUGxheWJhY2s6IHRydWUgfSksXHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IHBsYXliYWNrdGltZWxhYmVsXzEuUGxheWJhY2tUaW1lTGFiZWwoKSxcclxuICAgICAgICAgICAgICAgICAgICBuZXcgdm9sdW1lY29udHJvbGJ1dHRvbl8xLlZvbHVtZUNvbnRyb2xCdXR0b24oeyAndmVydGljYWwnOiB0cnVlIH0pLFxyXG4gICAgICAgICAgICAgICAgICAgIG5ldyBjb21wb25lbnRfMS5Db21wb25lbnQoeyBjc3NDbGFzczogJ3NwYWNlcicgfSksXHJcbiAgICAgICAgICAgICAgICBdLFxyXG4gICAgICAgICAgICB9LCBmYWxzZSk7XHJcbiAgICAgICAgICAgIHZhciB1aSA9IG5ldyB1aWNvbnRhaW5lcl8xLlVJQ29udGFpbmVyKHtcclxuICAgICAgICAgICAgICAgIGNvbXBvbmVudHM6IFtcclxuICAgICAgICAgICAgICAgICAgICBuZXcgYXVkaW9vbmx5b3ZlcmxheV8xLkF1ZGlvT25seU92ZXJsYXkoKSxcclxuICAgICAgICAgICAgICAgICAgICBuZXcgcGxheWJhY2t0b2dnbGVvdmVybGF5XzEuUGxheWJhY2tUb2dnbGVPdmVybGF5KCksXHJcbiAgICAgICAgICAgICAgICAgICAgY29udHJvbEJhcixcclxuICAgICAgICAgICAgICAgICAgICBuZXcgZXJyb3JtZXNzYWdlb3ZlcmxheV8xLkVycm9yTWVzc2FnZU92ZXJsYXkoKSxcclxuICAgICAgICAgICAgICAgIF0sIGNzc0NsYXNzZXM6IFsndWktc2tpbiddLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBVSU1hbmFnZXIocGxheWVyLCB1aSwgY29uZmlnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgRmFjdG9yeS5idWlsZEF1ZGlvT25seVVJID0gYnVpbGRBdWRpb09ubHlVSTtcclxuICAgIH0pKEZhY3RvcnkgPSBVSU1hbmFnZXIuRmFjdG9yeSB8fCAoVUlNYW5hZ2VyLkZhY3RvcnkgPSB7fSkpO1xyXG59KShVSU1hbmFnZXIgPSBleHBvcnRzLlVJTWFuYWdlciB8fCAoZXhwb3J0cy5VSU1hbmFnZXIgPSB7fSkpO1xyXG5leHBvcnRzLlVJTWFuYWdlciA9IFVJTWFuYWdlcjtcclxuLyoqXHJcbiAqIEVuY2Fwc3VsYXRlcyBmdW5jdGlvbmFsaXR5IHRvIG1hbmFnZSBhIFVJIGluc3RhbmNlLiBVc2VkIGJ5IHRoZSB7QGxpbmsgVUlNYW5hZ2VyfSB0byBtYW5hZ2UgbXVsdGlwbGUgVUkgaW5zdGFuY2VzLlxyXG4gKi9cclxudmFyIFVJSW5zdGFuY2VNYW5hZ2VyID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIFVJSW5zdGFuY2VNYW5hZ2VyKHBsYXllciwgdWksIGNvbmZpZykge1xyXG4gICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgIHRoaXMuZXZlbnRzID0ge1xyXG4gICAgICAgICAgICBvbkNvbmZpZ3VyZWQ6IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKSxcclxuICAgICAgICAgICAgb25TZWVrOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgICAgIG9uU2Vla1ByZXZpZXc6IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKSxcclxuICAgICAgICAgICAgb25TZWVrZWQ6IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKSxcclxuICAgICAgICAgICAgb25Db21wb25lbnRTaG93OiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgICAgIG9uQ29tcG9uZW50SGlkZTogbmV3IGV2ZW50ZGlzcGF0Y2hlcl8xLkV2ZW50RGlzcGF0Y2hlcigpLFxyXG4gICAgICAgICAgICBvbkNvbnRyb2xzU2hvdzogbmV3IGV2ZW50ZGlzcGF0Y2hlcl8xLkV2ZW50RGlzcGF0Y2hlcigpLFxyXG4gICAgICAgICAgICBvblByZXZpZXdDb250cm9sc0hpZGU6IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKSxcclxuICAgICAgICAgICAgb25Db250cm9sc0hpZGU6IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKSxcclxuICAgICAgICB9O1xyXG4gICAgICAgIHRoaXMucGxheWVyV3JhcHBlciA9IG5ldyBQbGF5ZXJXcmFwcGVyKHBsYXllcik7XHJcbiAgICAgICAgdGhpcy51aSA9IHVpO1xyXG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xyXG4gICAgfVxyXG4gICAgVUlJbnN0YW5jZU1hbmFnZXIucHJvdG90eXBlLmdldENvbmZpZyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb25maWc7XHJcbiAgICB9O1xyXG4gICAgVUlJbnN0YW5jZU1hbmFnZXIucHJvdG90eXBlLmdldFVJID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnVpO1xyXG4gICAgfTtcclxuICAgIFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZS5nZXRQbGF5ZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucGxheWVyV3JhcHBlci5nZXRQbGF5ZXIoKTtcclxuICAgIH07XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVUlJbnN0YW5jZU1hbmFnZXIucHJvdG90eXBlLCBcIm9uQ29uZmlndXJlZFwiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRmlyZXMgd2hlbiB0aGUgVUkgaXMgZnVsbHkgY29uZmlndXJlZCBhbmQgYWRkZWQgdG8gdGhlIERPTS5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnREaXNwYXRjaGVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudHMub25Db25maWd1cmVkO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZSwgXCJvblNlZWtcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEZpcmVzIHdoZW4gYSBzZWVrIHN0YXJ0cy5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnREaXNwYXRjaGVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudHMub25TZWVrO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZSwgXCJvblNlZWtQcmV2aWV3XCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBGaXJlcyB3aGVuIHRoZSBzZWVrIHRpbWVsaW5lIGlzIHNjcnViYmVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtFdmVudERpc3BhdGNoZXJ9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmV2ZW50cy5vblNlZWtQcmV2aWV3O1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZSwgXCJvblNlZWtlZFwiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRmlyZXMgd2hlbiBhIHNlZWsgaXMgZmluaXNoZWQuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50RGlzcGF0Y2hlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRzLm9uU2Vla2VkO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZSwgXCJvbkNvbXBvbmVudFNob3dcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEZpcmVzIHdoZW4gYSBjb21wb25lbnQgaXMgc2hvd2luZy5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnREaXNwYXRjaGVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudHMub25Db21wb25lbnRTaG93O1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZSwgXCJvbkNvbXBvbmVudEhpZGVcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEZpcmVzIHdoZW4gYSBjb21wb25lbnQgaXMgaGlkaW5nLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtFdmVudERpc3BhdGNoZXJ9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmV2ZW50cy5vbkNvbXBvbmVudEhpZGU7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVUlJbnN0YW5jZU1hbmFnZXIucHJvdG90eXBlLCBcIm9uQ29udHJvbHNTaG93XCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBGaXJlcyB3aGVuIHRoZSBVSSBjb250cm9scyBhcmUgc2hvd2luZy5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnREaXNwYXRjaGVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudHMub25Db250cm9sc1Nob3c7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVUlJbnN0YW5jZU1hbmFnZXIucHJvdG90eXBlLCBcIm9uUHJldmlld0NvbnRyb2xzSGlkZVwiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRmlyZXMgYmVmb3JlIHRoZSBVSSBjb250cm9scyBhcmUgaGlkaW5nIHRvIGNoZWNrIGlmIHRoZXkgYXJlIGFsbG93ZWQgdG8gaGlkZS5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnREaXNwYXRjaGVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudHMub25QcmV2aWV3Q29udHJvbHNIaWRlO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZSwgXCJvbkNvbnRyb2xzSGlkZVwiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRmlyZXMgd2hlbiB0aGUgVUkgY29udHJvbHMgYXJlIGhpZGluZy5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnREaXNwYXRjaGVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudHMub25Db250cm9sc0hpZGU7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICBVSUluc3RhbmNlTWFuYWdlci5wcm90b3R5cGUuY2xlYXJFdmVudEhhbmRsZXJzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMucGxheWVyV3JhcHBlci5jbGVhckV2ZW50SGFuZGxlcnMoKTtcclxuICAgICAgICB2YXIgZXZlbnRzID0gdGhpcy5ldmVudHM7IC8vIGF2b2lkIFRTNzAxN1xyXG4gICAgICAgIGZvciAodmFyIGV2ZW50XzEgaW4gZXZlbnRzKSB7XHJcbiAgICAgICAgICAgIHZhciBkaXNwYXRjaGVyID0gZXZlbnRzW2V2ZW50XzFdO1xyXG4gICAgICAgICAgICBkaXNwYXRjaGVyLnVuc3Vic2NyaWJlQWxsKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHJldHVybiBVSUluc3RhbmNlTWFuYWdlcjtcclxufSgpKTtcclxuZXhwb3J0cy5VSUluc3RhbmNlTWFuYWdlciA9IFVJSW5zdGFuY2VNYW5hZ2VyO1xyXG4vKipcclxuICogRXh0ZW5kcyB0aGUge0BsaW5rIFVJSW5zdGFuY2VNYW5hZ2VyfSBmb3IgaW50ZXJuYWwgdXNlIGluIHRoZSB7QGxpbmsgVUlNYW5hZ2VyfSBhbmQgcHJvdmlkZXMgYWNjZXNzIHRvIGZ1bmN0aW9uYWxpdHlcclxuICogdGhhdCBjb21wb25lbnRzIHJlY2VpdmluZyBhIHJlZmVyZW5jZSB0byB0aGUge0BsaW5rIFVJSW5zdGFuY2VNYW5hZ2VyfSBzaG91bGQgbm90IGhhdmUgYWNjZXNzIHRvLlxyXG4gKi9cclxudmFyIEludGVybmFsVUlJbnN0YW5jZU1hbmFnZXIgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKEludGVybmFsVUlJbnN0YW5jZU1hbmFnZXIsIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBJbnRlcm5hbFVJSW5zdGFuY2VNYW5hZ2VyKCkge1xyXG4gICAgICAgIHJldHVybiBfc3VwZXIgIT09IG51bGwgJiYgX3N1cGVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgdGhpcztcclxuICAgIH1cclxuICAgIEludGVybmFsVUlJbnN0YW5jZU1hbmFnZXIucHJvdG90eXBlLmdldFdyYXBwZWRQbGF5ZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gVE9ETyBmaW5kIGEgbm9uLWhhY2t5IHdheSB0byBwcm92aWRlIHRoZSBXcmFwcGVkUGxheWVyIHRvIHRoZSBVSU1hbmFnZXIgd2l0aG91dCBleHBvcnRpbmcgaXRcclxuICAgICAgICAvLyBnZXRQbGF5ZXIoKSBhY3R1YWxseSByZXR1cm5zIHRoZSBXcmFwcGVkUGxheWVyIGJ1dCBpdHMgcmV0dXJuIHR5cGUgaXMgc2V0IHRvIFBsYXllciBzbyB0aGUgV3JhcHBlZFBsYXllciBkb2VzXHJcbiAgICAgICAgLy8gbm90IG5lZWQgdG8gYmUgZXhwb3J0ZWRcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXRQbGF5ZXIoKTtcclxuICAgIH07XHJcbiAgICBJbnRlcm5hbFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZS5jb25maWd1cmVDb250cm9scyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmNvbmZpZ3VyZUNvbnRyb2xzVHJlZSh0aGlzLmdldFVJKCkpO1xyXG4gICAgICAgIHRoaXMuY29uZmlndXJlZCA9IHRydWU7XHJcbiAgICB9O1xyXG4gICAgSW50ZXJuYWxVSUluc3RhbmNlTWFuYWdlci5wcm90b3R5cGUuaXNDb25maWd1cmVkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZ3VyZWQ7XHJcbiAgICB9O1xyXG4gICAgSW50ZXJuYWxVSUluc3RhbmNlTWFuYWdlci5wcm90b3R5cGUuY29uZmlndXJlQ29udHJvbHNUcmVlID0gZnVuY3Rpb24gKGNvbXBvbmVudCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIGNvbmZpZ3VyZWRDb21wb25lbnRzID0gW107XHJcbiAgICAgICAgdWl1dGlsc18xLlVJVXRpbHMudHJhdmVyc2VUcmVlKGNvbXBvbmVudCwgZnVuY3Rpb24gKGNvbXBvbmVudCkge1xyXG4gICAgICAgICAgICAvLyBGaXJzdCwgY2hlY2sgaWYgd2UgaGF2ZSBhbHJlYWR5IGNvbmZpZ3VyZWQgYSBjb21wb25lbnQsIGFuZCB0aHJvdyBhbiBlcnJvciBpZiB3ZSBkaWQuIE11bHRpcGxlIGNvbmZpZ3VyYXRpb25cclxuICAgICAgICAgICAgLy8gb2YgdGhlIHNhbWUgY29tcG9uZW50IGxlYWRzIHRvIHVuZXhwZWN0ZWQgVUkgYmVoYXZpb3IuIEFsc28sIGEgY29tcG9uZW50IHRoYXQgaXMgaW4gdGhlIFVJIHRyZWUgbXVsdGlwbGVcclxuICAgICAgICAgICAgLy8gdGltZXMgaGludHMgYXQgYSB3cm9uZyBVSSBzdHJ1Y3R1cmUuXHJcbiAgICAgICAgICAgIC8vIFdlIGNvdWxkIGp1c3Qgc2tpcCBjb25maWd1cmF0aW9uIGluIHN1Y2ggYSBjYXNlIGFuZCBub3QgdGhyb3cgYW4gZXhjZXB0aW9uLCBidXQgZW5mb3JjaW5nIGEgY2xlYW4gVUkgdHJlZVxyXG4gICAgICAgICAgICAvLyBzZWVtcyBsaWtlIHRoZSBiZXR0ZXIgY2hvaWNlLlxyXG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIGNvbmZpZ3VyZWRDb21wb25lbnRzXzEgPSBjb25maWd1cmVkQ29tcG9uZW50czsgX2kgPCBjb25maWd1cmVkQ29tcG9uZW50c18xLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICAgICAgdmFyIGNvbmZpZ3VyZWRDb21wb25lbnQgPSBjb25maWd1cmVkQ29tcG9uZW50c18xW19pXTtcclxuICAgICAgICAgICAgICAgIGlmIChjb25maWd1cmVkQ29tcG9uZW50ID09PSBjb21wb25lbnQpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBXcml0ZSB0aGUgY29tcG9uZW50IHRvIHRoZSBjb25zb2xlIHRvIHNpbXBsaWZ5IGlkZW50aWZpY2F0aW9uIG9mIHRoZSBjdWxwcml0XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gKGUuZy4gYnkgaW5zcGVjdGluZyB0aGUgY29uZmlnKVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb25zb2xlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0NpcmN1bGFyIHJlZmVyZW5jZSBpbiBVSSB0cmVlJywgY29tcG9uZW50KTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gQWRkaXRpb25hbGx5IHRocm93IGFuIGVycm9yLCBiZWNhdXNlIHRoaXMgY2FzZSBtdXN0IG5vdCBoYXBwZW4gYW5kIGxlYWRzIHRvIHVuZXhwZWN0ZWQgVUkgYmVoYXZpb3IuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ0NpcmN1bGFyIHJlZmVyZW5jZSBpbiBVSSB0cmVlOiAnICsgY29tcG9uZW50LmNvbnN0cnVjdG9yLm5hbWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNvbXBvbmVudC5pbml0aWFsaXplKCk7XHJcbiAgICAgICAgICAgIGNvbXBvbmVudC5jb25maWd1cmUoX3RoaXMuZ2V0UGxheWVyKCksIF90aGlzKTtcclxuICAgICAgICAgICAgY29uZmlndXJlZENvbXBvbmVudHMucHVzaChjb21wb25lbnQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIEludGVybmFsVUlJbnN0YW5jZU1hbmFnZXIucHJvdG90eXBlLnJlbGVhc2VDb250cm9scyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBEbyBub3QgY2FsbCByZWxlYXNlIG1ldGhvZHMgaWYgdGhlIGNvbXBvbmVudHMgaGF2ZSBuZXZlciBiZWVuIGNvbmZpZ3VyZWQ7IHRoaXMgY2FuIHJlc3VsdCBpbiBleGNlcHRpb25zXHJcbiAgICAgICAgaWYgKHRoaXMuY29uZmlndXJlZCkge1xyXG4gICAgICAgICAgICB0aGlzLnJlbGVhc2VDb250cm9sc1RyZWUodGhpcy5nZXRVSSgpKTtcclxuICAgICAgICAgICAgdGhpcy5jb25maWd1cmVkID0gZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMucmVsZWFzZWQgPSB0cnVlO1xyXG4gICAgfTtcclxuICAgIEludGVybmFsVUlJbnN0YW5jZU1hbmFnZXIucHJvdG90eXBlLmlzUmVsZWFzZWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucmVsZWFzZWQ7XHJcbiAgICB9O1xyXG4gICAgSW50ZXJuYWxVSUluc3RhbmNlTWFuYWdlci5wcm90b3R5cGUucmVsZWFzZUNvbnRyb2xzVHJlZSA9IGZ1bmN0aW9uIChjb21wb25lbnQpIHtcclxuICAgICAgICBjb21wb25lbnQucmVsZWFzZSgpO1xyXG4gICAgICAgIGlmIChjb21wb25lbnQgaW5zdGFuY2VvZiBjb250YWluZXJfMS5Db250YWluZXIpIHtcclxuICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IGNvbXBvbmVudC5nZXRDb21wb25lbnRzKCk7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgY2hpbGRDb21wb25lbnQgPSBfYVtfaV07XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlbGVhc2VDb250cm9sc1RyZWUoY2hpbGRDb21wb25lbnQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIEludGVybmFsVUlJbnN0YW5jZU1hbmFnZXIucHJvdG90eXBlLmNsZWFyRXZlbnRIYW5kbGVycyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNsZWFyRXZlbnRIYW5kbGVycy5jYWxsKHRoaXMpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBJbnRlcm5hbFVJSW5zdGFuY2VNYW5hZ2VyO1xyXG59KFVJSW5zdGFuY2VNYW5hZ2VyKSk7XHJcbi8qKlxyXG4gKiBXcmFwcyB0aGUgcGxheWVyIHRvIHRyYWNrIGV2ZW50IGhhbmRsZXJzIGFuZCBwcm92aWRlIGEgc2ltcGxlIG1ldGhvZCB0byByZW1vdmUgYWxsIHJlZ2lzdGVyZWQgZXZlbnRcclxuICogaGFuZGxlcnMgZnJvbSB0aGUgcGxheWVyLlxyXG4gKi9cclxudmFyIFBsYXllcldyYXBwZXIgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gUGxheWVyV3JhcHBlcihwbGF5ZXIpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHRoaXMuZXZlbnRIYW5kbGVycyA9IHt9O1xyXG4gICAgICAgIHRoaXMucGxheWVyID0gcGxheWVyO1xyXG4gICAgICAgIC8vIENvbGxlY3QgYWxsIG1lbWJlcnMgb2YgdGhlIHBsYXllciAocHVibGljIEFQSSBtZXRob2RzIGFuZCBwcm9wZXJ0aWVzIG9mIHRoZSBwbGF5ZXIpXHJcbiAgICAgICAgLy8gKE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHBsYXllcikgZG9lcyBub3Qgd29yayB3aXRoIHRoZSBwbGF5ZXIgVHlwZVNjcmlwdCBjbGFzcyBzdGFydGluZyBpbiA3LjIpXHJcbiAgICAgICAgdmFyIG1lbWJlcnMgPSBbXTtcclxuICAgICAgICBmb3IgKHZhciBtZW1iZXIgaW4gcGxheWVyKSB7XHJcbiAgICAgICAgICAgIG1lbWJlcnMucHVzaChtZW1iZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBTcGxpdCB0aGUgbWVtYmVycyBpbnRvIG1ldGhvZHMgYW5kIHByb3BlcnRpZXNcclxuICAgICAgICB2YXIgbWV0aG9kcyA9IFtdO1xyXG4gICAgICAgIHZhciBwcm9wZXJ0aWVzID0gW107XHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBtZW1iZXJzXzEgPSBtZW1iZXJzOyBfaSA8IG1lbWJlcnNfMS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgdmFyIG1lbWJlciA9IG1lbWJlcnNfMVtfaV07XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgcGxheWVyW21lbWJlcl0gPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICAgICAgICAgIG1ldGhvZHMucHVzaChtZW1iZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcHJvcGVydGllcy5wdXNoKG1lbWJlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gQ3JlYXRlIHdyYXBwZXIgb2JqZWN0XHJcbiAgICAgICAgdmFyIHdyYXBwZXIgPSB7fTtcclxuICAgICAgICB2YXIgX2xvb3BfMSA9IGZ1bmN0aW9uIChtZXRob2QpIHtcclxuICAgICAgICAgICAgd3JhcHBlclttZXRob2RdID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ2NhbGxlZCAnICsgbWVtYmVyKTsgLy8gdHJhY2sgbWV0aG9kIGNhbGxzIG9uIHRoZSBwbGF5ZXJcclxuICAgICAgICAgICAgICAgIHJldHVybiBwbGF5ZXJbbWV0aG9kXS5hcHBseShwbGF5ZXIsIGFyZ3VtZW50cyk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvLyBBZGQgZnVuY3Rpb24gd3JhcHBlcnMgZm9yIGFsbCBBUEkgbWV0aG9kcyB0aGF0IGRvIG5vdGhpbmcgYnV0IGNhbGxpbmcgdGhlIGJhc2UgbWV0aG9kIG9uIHRoZSBwbGF5ZXJcclxuICAgICAgICBmb3IgKHZhciBfYSA9IDAsIG1ldGhvZHNfMSA9IG1ldGhvZHM7IF9hIDwgbWV0aG9kc18xLmxlbmd0aDsgX2ErKykge1xyXG4gICAgICAgICAgICB2YXIgbWV0aG9kID0gbWV0aG9kc18xW19hXTtcclxuICAgICAgICAgICAgX2xvb3BfMShtZXRob2QpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgX2xvb3BfMiA9IGZ1bmN0aW9uIChwcm9wZXJ0eSkge1xyXG4gICAgICAgICAgICAvLyBHZXQgYW4gZXZlbnR1YWxseSBleGlzdGluZyBwcm9wZXJ0eSBkZXNjcmlwdG9yIHRvIGRpZmZlcmVudGlhdGUgYmV0d2VlbiBwbGFpbiBwcm9wZXJ0aWVzIGFuZCBwcm9wZXJ0aWVzIHdpdGhcclxuICAgICAgICAgICAgLy8gZ2V0dGVycy9zZXR0ZXJzLlxyXG4gICAgICAgICAgICB2YXIgcHJvcGVydHlEZXNjcmlwdG9yID0gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihwbGF5ZXIsIHByb3BlcnR5KSB8fFxyXG4gICAgICAgICAgICAgICAgT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihPYmplY3QuZ2V0UHJvdG90eXBlT2YocGxheWVyKSwgcHJvcGVydHkpO1xyXG4gICAgICAgICAgICAvLyBJZiB0aGUgcHJvcGVydHkgaGFzIGdldHRlcnMvc2V0dGVycywgd3JhcCB0aGVtIGFjY29yZGluZ2x5Li4uXHJcbiAgICAgICAgICAgIGlmIChwcm9wZXJ0eURlc2NyaXB0b3IgJiYgKHByb3BlcnR5RGVzY3JpcHRvci5nZXQgfHwgcHJvcGVydHlEZXNjcmlwdG9yLnNldCkpIHtcclxuICAgICAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3cmFwcGVyLCBwcm9wZXJ0eSwge1xyXG4gICAgICAgICAgICAgICAgICAgIGdldDogZnVuY3Rpb24gKCkgeyByZXR1cm4gcHJvcGVydHlEZXNjcmlwdG9yLmdldC5jYWxsKHBsYXllcik7IH0sXHJcbiAgICAgICAgICAgICAgICAgICAgc2V0OiBmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIHByb3BlcnR5RGVzY3JpcHRvci5zZXQuY2FsbChwbGF5ZXIsIHZhbHVlKTsgfSxcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgd3JhcHBlcltwcm9wZXJ0eV0gPSBwbGF5ZXJbcHJvcGVydHldO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvLyBBZGQgYWxsIHB1YmxpYyBwcm9wZXJ0aWVzIG9mIHRoZSBwbGF5ZXIgdG8gdGhlIHdyYXBwZXJcclxuICAgICAgICBmb3IgKHZhciBfYiA9IDAsIHByb3BlcnRpZXNfMSA9IHByb3BlcnRpZXM7IF9iIDwgcHJvcGVydGllc18xLmxlbmd0aDsgX2IrKykge1xyXG4gICAgICAgICAgICB2YXIgcHJvcGVydHkgPSBwcm9wZXJ0aWVzXzFbX2JdO1xyXG4gICAgICAgICAgICBfbG9vcF8yKHByb3BlcnR5KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gRXhwbGljaXRseSBhZGQgYSB3cmFwcGVyIG1ldGhvZCBmb3IgJ2FkZEV2ZW50SGFuZGxlcicgdGhhdCBhZGRzIGFkZGVkIGV2ZW50IGhhbmRsZXJzIHRvIHRoZSBldmVudCBsaXN0XHJcbiAgICAgICAgd3JhcHBlci5hZGRFdmVudEhhbmRsZXIgPSBmdW5jdGlvbiAoZXZlbnRUeXBlLCBjYWxsYmFjaykge1xyXG4gICAgICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKGV2ZW50VHlwZSwgY2FsbGJhY2spO1xyXG4gICAgICAgICAgICBpZiAoIV90aGlzLmV2ZW50SGFuZGxlcnNbZXZlbnRUeXBlXSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZXZlbnRIYW5kbGVyc1tldmVudFR5cGVdID0gW107XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgX3RoaXMuZXZlbnRIYW5kbGVyc1tldmVudFR5cGVdLnB1c2goY2FsbGJhY2spO1xyXG4gICAgICAgICAgICByZXR1cm4gd3JhcHBlcjtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIEV4cGxpY2l0bHkgYWRkIGEgd3JhcHBlciBtZXRob2QgZm9yICdyZW1vdmVFdmVudEhhbmRsZXInIHRoYXQgcmVtb3ZlcyByZW1vdmVkIGV2ZW50IGhhbmRsZXJzIGZyb20gdGhlIGV2ZW50IGxpc3RcclxuICAgICAgICB3cmFwcGVyLnJlbW92ZUV2ZW50SGFuZGxlciA9IGZ1bmN0aW9uIChldmVudFR5cGUsIGNhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHBsYXllci5yZW1vdmVFdmVudEhhbmRsZXIoZXZlbnRUeXBlLCBjYWxsYmFjayk7XHJcbiAgICAgICAgICAgIGlmIChfdGhpcy5ldmVudEhhbmRsZXJzW2V2ZW50VHlwZV0pIHtcclxuICAgICAgICAgICAgICAgIGFycmF5dXRpbHNfMS5BcnJheVV0aWxzLnJlbW92ZShfdGhpcy5ldmVudEhhbmRsZXJzW2V2ZW50VHlwZV0sIGNhbGxiYWNrKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gd3JhcHBlcjtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHdyYXBwZXIuZmlyZUV2ZW50SW5VSSA9IGZ1bmN0aW9uIChldmVudCwgZGF0YSkge1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuZXZlbnRIYW5kbGVyc1tldmVudF0pIHtcclxuICAgICAgICAgICAgICAgIC8vIEV4dGVuZCB0aGUgZGF0YSBvYmplY3Qgd2l0aCBkZWZhdWx0IHZhbHVlcyB0byBjb252ZXJ0IGl0IHRvIGEge0BsaW5rIFBsYXllckV2ZW50fSBvYmplY3QuXHJcbiAgICAgICAgICAgICAgICB2YXIgcGxheWVyRXZlbnREYXRhID0gT2JqZWN0LmFzc2lnbih7fSwge1xyXG4gICAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcclxuICAgICAgICAgICAgICAgICAgICB0eXBlOiBldmVudCxcclxuICAgICAgICAgICAgICAgICAgICAvLyBBZGQgYSBtYXJrZXIgcHJvcGVydHkgc28gdGhlIFVJIGNhbiBkZXRlY3QgVUktaW50ZXJuYWwgcGxheWVyIGV2ZW50c1xyXG4gICAgICAgICAgICAgICAgICAgIHVpU291cmNlZDogdHJ1ZSxcclxuICAgICAgICAgICAgICAgIH0sIGRhdGEpO1xyXG4gICAgICAgICAgICAgICAgLy8gRXhlY3V0ZSB0aGUgcmVnaXN0ZXJlZCBjYWxsYmFja3NcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSBfdGhpcy5ldmVudEhhbmRsZXJzW2V2ZW50XTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY2FsbGJhY2sgPSBfYVtfaV07XHJcbiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2socGxheWVyRXZlbnREYXRhKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdGhpcy53cmFwcGVyID0gd3JhcHBlcjtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIHdyYXBwZWQgcGxheWVyIG9iamVjdCB0aGF0IGNhbiBiZSB1c2VkIG9uIHBsYWNlIG9mIHRoZSBub3JtYWwgcGxheWVyIG9iamVjdC5cclxuICAgICAqIEByZXR1cm5zIHtXcmFwcGVkUGxheWVyfSBhIHdyYXBwZWQgcGxheWVyXHJcbiAgICAgKi9cclxuICAgIFBsYXllcldyYXBwZXIucHJvdG90eXBlLmdldFBsYXllciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy53cmFwcGVyO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQ2xlYXJzIGFsbCByZWdpc3RlcmVkIGV2ZW50IGhhbmRsZXJzIGZyb20gdGhlIHBsYXllciB0aGF0IHdlcmUgYWRkZWQgdGhyb3VnaCB0aGUgd3JhcHBlZCBwbGF5ZXIuXHJcbiAgICAgKi9cclxuICAgIFBsYXllcldyYXBwZXIucHJvdG90eXBlLmNsZWFyRXZlbnRIYW5kbGVycyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBmb3IgKHZhciBldmVudFR5cGUgaW4gdGhpcy5ldmVudEhhbmRsZXJzKSB7XHJcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSB0aGlzLmV2ZW50SGFuZGxlcnNbZXZlbnRUeXBlXTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgICAgIHZhciBjYWxsYmFjayA9IF9hW19pXTtcclxuICAgICAgICAgICAgICAgIHRoaXMucGxheWVyLnJlbW92ZUV2ZW50SGFuZGxlcihldmVudFR5cGUsIGNhbGxiYWNrKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICByZXR1cm4gUGxheWVyV3JhcHBlcjtcclxufSgpKTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci91aW1hbmFnZXIudHNcbi8vIG1vZHVsZSBpZCA9IDM1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBHdWlkO1xyXG4oZnVuY3Rpb24gKEd1aWQpIHtcclxuICAgIHZhciBndWlkID0gMTtcclxuICAgIGZ1bmN0aW9uIG5leHQoKSB7XHJcbiAgICAgICAgcmV0dXJuIGd1aWQrKztcclxuICAgIH1cclxuICAgIEd1aWQubmV4dCA9IG5leHQ7XHJcbn0pKEd1aWQgPSBleHBvcnRzLkd1aWQgfHwgKGV4cG9ydHMuR3VpZCA9IHt9KSk7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvZ3VpZC50c1xuLy8gbW9kdWxlIGlkID0gMzZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciB0b2dnbGVidXR0b25fMSA9IHJlcXVpcmUoXCIuL3RvZ2dsZWJ1dHRvblwiKTtcclxuLyoqXHJcbiAqIEEgYnV0dG9uIHRoYXQgdG9nZ2xlcyB0aGUgcGxheWVyIGJldHdlZW4gd2luZG93ZWQgYW5kIGZ1bGxzY3JlZW4gdmlldy5cclxuICovXHJcbnZhciBGdWxsc2NyZWVuVG9nZ2xlQnV0dG9uID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhGdWxsc2NyZWVuVG9nZ2xlQnV0dG9uLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gRnVsbHNjcmVlblRvZ2dsZUJ1dHRvbihjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktZnVsbHNjcmVlbnRvZ2dsZWJ1dHRvbicsXHJcbiAgICAgICAgICAgIHRleHQ6ICdGdWxsc2NyZWVuJyxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIEZ1bGxzY3JlZW5Ub2dnbGVCdXR0b24ucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jb25maWd1cmUuY2FsbCh0aGlzLCBwbGF5ZXIsIHVpbWFuYWdlcik7XHJcbiAgICAgICAgdmFyIGZ1bGxzY3JlZW5TdGF0ZUhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChwbGF5ZXIuaXNGdWxsc2NyZWVuKCkpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLm9uKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5vZmYoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fRlVMTFNDUkVFTl9FTlRFUiwgZnVsbHNjcmVlblN0YXRlSGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fRlVMTFNDUkVFTl9FWElULCBmdWxsc2NyZWVuU3RhdGVIYW5kbGVyKTtcclxuICAgICAgICB0aGlzLm9uQ2xpY2suc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKHBsYXllci5pc0Z1bGxzY3JlZW4oKSkge1xyXG4gICAgICAgICAgICAgICAgcGxheWVyLmV4aXRGdWxsc2NyZWVuKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBwbGF5ZXIuZW50ZXJGdWxsc2NyZWVuKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBTdGFydHVwIGluaXRcclxuICAgICAgICBmdWxsc2NyZWVuU3RhdGVIYW5kbGVyKCk7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIEZ1bGxzY3JlZW5Ub2dnbGVCdXR0b247XHJcbn0odG9nZ2xlYnV0dG9uXzEuVG9nZ2xlQnV0dG9uKSk7XHJcbmV4cG9ydHMuRnVsbHNjcmVlblRvZ2dsZUJ1dHRvbiA9IEZ1bGxzY3JlZW5Ub2dnbGVCdXR0b247XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9mdWxsc2NyZWVudG9nZ2xlYnV0dG9uLnRzXG4vLyBtb2R1bGUgaWQgPSAzN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgZG9tXzEgPSByZXF1aXJlKFwiLi9kb21cIik7XHJcbi8qKlxyXG4gKiBUcmFja3MgdGhlIGxvYWRpbmcgc3RhdGUgb2YgaW1hZ2VzLlxyXG4gKi9cclxudmFyIEltYWdlTG9hZGVyID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIEltYWdlTG9hZGVyKCkge1xyXG4gICAgICAgIHRoaXMuc3RhdGUgPSB7fTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogTG9hZHMgYW4gaW1hZ2UgYW5kIGNhbGwgdGhlIGNhbGxiYWNrIG9uY2UgdGhlIGltYWdlIGlzIGxvYWRlZC4gSWYgdGhlIGltYWdlIGlzIGFscmVhZHkgbG9hZGVkLCB0aGUgY2FsbGJhY2tcclxuICAgICAqIGlzIGNhbGxlZCBpbW1lZGlhdGVseSwgZWxzZSBpdCBpcyBjYWxsZWQgb25jZSBsb2FkaW5nIGhhcyBmaW5pc2hlZC4gQ2FsbGluZyB0aGlzIG1ldGhvZCBtdWx0aXBsZSB0aW1lcyBmb3IgdGhlXHJcbiAgICAgKiBzYW1lIGltYWdlIHdoaWxlIGl0IGlzIGxvYWRpbmcgY2FsbHMgb25seSBsZXQgY2FsbGJhY2sgcGFzc2VkIGludG8gdGhlIGxhc3QgY2FsbC5cclxuICAgICAqIEBwYXJhbSB1cmwgVGhlIHVybCB0byB0aGUgaW1hZ2UgdG8gbG9hZFxyXG4gICAgICogQHBhcmFtIGxvYWRlZENhbGxiYWNrIFRoZSBjYWxsYmFjayB0aGF0IGlzIGNhbGxlZCB3aGVuIHRoZSBpbWFnZSBpcyBsb2FkZWRcclxuICAgICAqL1xyXG4gICAgSW1hZ2VMb2FkZXIucHJvdG90eXBlLmxvYWQgPSBmdW5jdGlvbiAodXJsLCBsb2FkZWRDYWxsYmFjaykge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgaWYgKCF0aGlzLnN0YXRlW3VybF0pIHtcclxuICAgICAgICAgICAgLy8gV2hlbiB0aGUgaW1hZ2Ugd2FzIG5ldmVyIGF0dGVtcHRlZCB0byBiZSBsb2FkZWQgYmVmb3JlLCB3ZSBjcmVhdGUgYSBzdGF0ZSBhbmQgc3RvcmUgaXQgaW4gdGhlIHN0YXRlIG1hcFxyXG4gICAgICAgICAgICAvLyBmb3IgbGF0ZXIgdXNlIHdoZW4gdGhlIHNhbWUgaW1hZ2UgaXMgcmVxdWVzdGVkIHRvIGJlIGxvYWRlZCBhZ2Fpbi5cclxuICAgICAgICAgICAgdmFyIHN0YXRlXzEgPSB7XHJcbiAgICAgICAgICAgICAgICB1cmw6IHVybCxcclxuICAgICAgICAgICAgICAgIGltYWdlOiBuZXcgZG9tXzEuRE9NKCdpbWcnLCB7fSksXHJcbiAgICAgICAgICAgICAgICBsb2FkZWRDYWxsYmFjazogbG9hZGVkQ2FsbGJhY2ssXHJcbiAgICAgICAgICAgICAgICBsb2FkZWQ6IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgd2lkdGg6IDAsXHJcbiAgICAgICAgICAgICAgICBoZWlnaHQ6IDAsXHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHRoaXMuc3RhdGVbdXJsXSA9IHN0YXRlXzE7XHJcbiAgICAgICAgICAgIC8vIExpc3RlbiB0byB0aGUgbG9hZCBldmVudCwgdXBkYXRlIHRoZSBzdGF0ZSBhbmQgY2FsbCB0aGUgY2FsbGJhY2sgb25jZSB0aGUgaW1hZ2UgaXMgbG9hZGVkXHJcbiAgICAgICAgICAgIHN0YXRlXzEuaW1hZ2Uub24oJ2xvYWQnLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgc3RhdGVfMS5sb2FkZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgc3RhdGVfMS53aWR0aCA9IHN0YXRlXzEuaW1hZ2UuZ2V0KDApLndpZHRoO1xyXG4gICAgICAgICAgICAgICAgc3RhdGVfMS5oZWlnaHQgPSBzdGF0ZV8xLmltYWdlLmdldCgwKS5oZWlnaHQ7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5jYWxsTG9hZGVkQ2FsbGJhY2soc3RhdGVfMSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAvLyBTZXQgdGhlIGltYWdlIFVSTCB0byBzdGFydCB0aGUgbG9hZGluZ1xyXG4gICAgICAgICAgICBzdGF0ZV8xLmltYWdlLmF0dHIoJ3NyYycsIHN0YXRlXzEudXJsKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIFdlIGhhdmUgYSBzdGF0ZSBmb3IgdGhlIHJlcXVlc3RlZCBpbWFnZSwgc28gaXQgaXMgZWl0aGVyIGFscmVhZHkgbG9hZGVkIG9yIGN1cnJlbnRseSBsb2FkaW5nXHJcbiAgICAgICAgICAgIHZhciBzdGF0ZSA9IHRoaXMuc3RhdGVbdXJsXTtcclxuICAgICAgICAgICAgLy8gV2Ugb3ZlcndyaXRlIHRoZSBjYWxsYmFjayB0byBtYWtlIHN1cmUgdGhhdCBvbmx5IHRoZSBjYWxsYmFjayBvZiB0aGUgbGF0ZXN0IGNhbGwgZ2V0cyBleGVjdXRlZC5cclxuICAgICAgICAgICAgLy8gRWFybGllciBjYWxsYmFja3MgYmVjb21lIGludmFsaWQgb25jZSBhIG5ldyBsb2FkIGNhbGwgYXJyaXZlcywgYW5kIHRoZXkgYXJlIG5vdCBjYWxsZWQgYXMgbG9uZyBhcyB0aGUgaW1hZ2VcclxuICAgICAgICAgICAgLy8gaXMgbm90IGxvYWRlZC5cclxuICAgICAgICAgICAgc3RhdGUubG9hZGVkQ2FsbGJhY2sgPSBsb2FkZWRDYWxsYmFjaztcclxuICAgICAgICAgICAgLy8gV2hlbiB0aGUgaW1hZ2UgaXMgYWxyZWFkeSBsb2FkZWQsIHdlIGRpcmVjdGx5IGV4ZWN1dGUgdGhlIGNhbGxiYWNrIGluc3RlYWQgb2Ygd2FpdGluZyBmb3IgdGhlIGxvYWQgZXZlbnRcclxuICAgICAgICAgICAgaWYgKHN0YXRlLmxvYWRlZCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jYWxsTG9hZGVkQ2FsbGJhY2soc3RhdGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIEltYWdlTG9hZGVyLnByb3RvdHlwZS5jYWxsTG9hZGVkQ2FsbGJhY2sgPSBmdW5jdGlvbiAoc3RhdGUpIHtcclxuICAgICAgICBzdGF0ZS5sb2FkZWRDYWxsYmFjayhzdGF0ZS51cmwsIHN0YXRlLndpZHRoLCBzdGF0ZS5oZWlnaHQpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBJbWFnZUxvYWRlcjtcclxufSgpKTtcclxuZXhwb3J0cy5JbWFnZUxvYWRlciA9IEltYWdlTG9hZGVyO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2ltYWdlbG9hZGVyLnRzXG4vLyBtb2R1bGUgaWQgPSAzOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIHNlbGVjdGJveF8xID0gcmVxdWlyZShcIi4vc2VsZWN0Ym94XCIpO1xyXG4vKipcclxuICogQSBzZWxlY3QgYm94IHByb3ZpZGluZyBhIHNlbGVjdGlvbiBiZXR3ZWVuIGF2YWlsYWJsZSBzdWJ0aXRsZSBhbmQgY2FwdGlvbiB0cmFja3MuXHJcbiAqL1xyXG52YXIgU3VidGl0bGVTZWxlY3RCb3ggPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKFN1YnRpdGxlU2VsZWN0Qm94LCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gU3VidGl0bGVTZWxlY3RCb3goY29uZmlnKSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgcmV0dXJuIF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgIH1cclxuICAgIFN1YnRpdGxlU2VsZWN0Qm94LnByb3RvdHlwZS5jb25maWd1cmUgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY29uZmlndXJlLmNhbGwodGhpcywgcGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIHZhciBzZWxlY3RDdXJyZW50U3VidGl0bGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBjdXJyZW50U3VidGl0bGUgPSBwbGF5ZXIuZ2V0U3VidGl0bGUoKTtcclxuICAgICAgICAgICAgaWYgKGN1cnJlbnRTdWJ0aXRsZSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuc2VsZWN0SXRlbShjdXJyZW50U3VidGl0bGUuaWQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICB2YXIgdXBkYXRlU3VidGl0bGVzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5jbGVhckl0ZW1zKCk7XHJcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSBwbGF5ZXIuZ2V0QXZhaWxhYmxlU3VidGl0bGVzKCk7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgc3VidGl0bGUgPSBfYVtfaV07XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5hZGRJdGVtKHN1YnRpdGxlLmlkLCBzdWJ0aXRsZS5sYWJlbCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gU2VsZWN0IHRoZSBjb3JyZWN0IHN1YnRpdGxlIGFmdGVyIHRoZSBzdWJ0aXRsZXMgaGF2ZSBiZWVuIGFkZGVkXHJcbiAgICAgICAgICAgIHNlbGVjdEN1cnJlbnRTdWJ0aXRsZSgpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgdGhpcy5vbkl0ZW1TZWxlY3RlZC5zdWJzY3JpYmUoZnVuY3Rpb24gKHNlbmRlciwgdmFsdWUpIHtcclxuICAgICAgICAgICAgcGxheWVyLnNldFN1YnRpdGxlKHZhbHVlID09PSAnbnVsbCcgPyBudWxsIDogdmFsdWUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIFJlYWN0IHRvIEFQSSBldmVudHNcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TVUJUSVRMRV9BRERFRCwgdXBkYXRlU3VidGl0bGVzKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TVUJUSVRMRV9DSEFOR0VELCBzZWxlY3RDdXJyZW50U3VidGl0bGUpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1NVQlRJVExFX1JFTU9WRUQsIHVwZGF0ZVN1YnRpdGxlcyk7XHJcbiAgICAgICAgLy8gVXBkYXRlIHN1YnRpdGxlcyB3aGVuIHNvdXJjZSBnb2VzIGF3YXlcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TT1VSQ0VfVU5MT0FERUQsIHVwZGF0ZVN1YnRpdGxlcyk7XHJcbiAgICAgICAgLy8gVXBkYXRlIHN1YnRpdGxlcyB3aGVuIGEgbmV3IHNvdXJjZSBpcyBsb2FkZWRcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9SRUFEWSwgdXBkYXRlU3VidGl0bGVzKTtcclxuICAgICAgICAvLyBVcGRhdGUgc3VidGl0bGVzIHdoZW4gdGhlIHBlcmlvZCB3aXRoaW4gYSBzb3VyY2UgY2hhbmdlc1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BFUklPRF9TV0lUQ0hFRCwgdXBkYXRlU3VidGl0bGVzKTtcclxuICAgICAgICAvLyBQb3B1bGF0ZSBzdWJ0aXRsZXMgYXQgc3RhcnR1cFxyXG4gICAgICAgIHVwZGF0ZVN1YnRpdGxlcygpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBTdWJ0aXRsZVNlbGVjdEJveDtcclxufShzZWxlY3Rib3hfMS5TZWxlY3RCb3gpKTtcclxuZXhwb3J0cy5TdWJ0aXRsZVNlbGVjdEJveCA9IFN1YnRpdGxlU2VsZWN0Qm94O1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvc3VidGl0bGVzZWxlY3Rib3gudHNcbi8vIG1vZHVsZSBpZCA9IDM5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgY29udGFpbmVyXzEgPSByZXF1aXJlKFwiLi9jb250YWluZXJcIik7XHJcbnZhciBsYWJlbF8xID0gcmVxdWlyZShcIi4vbGFiZWxcIik7XHJcbnZhciBjb250cm9sYmFyXzEgPSByZXF1aXJlKFwiLi9jb250cm9sYmFyXCIpO1xyXG4vKipcclxuICogT3ZlcmxheXMgdGhlIHBsYXllciB0byBkaXNwbGF5IHN1YnRpdGxlcy5cclxuICovXHJcbnZhciBTdWJ0aXRsZU92ZXJsYXkgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKFN1YnRpdGxlT3ZlcmxheSwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFN1YnRpdGxlT3ZlcmxheShjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMucHJldmlld1N1YnRpdGxlQWN0aXZlID0gZmFsc2U7XHJcbiAgICAgICAgX3RoaXMucHJldmlld1N1YnRpdGxlID0gbmV3IFN1YnRpdGxlTGFiZWwoeyB0ZXh0OiAnZXhhbXBsZSBzdWJ0aXRsZScgfSk7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktc3VidGl0bGUtb3ZlcmxheScsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBTdWJ0aXRsZU92ZXJsYXkucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jb25maWd1cmUuY2FsbCh0aGlzLCBwbGF5ZXIsIHVpbWFuYWdlcik7XHJcbiAgICAgICAgdmFyIHN1YnRpdGxlTWFuYWdlciA9IG5ldyBBY3RpdmVTdWJ0aXRsZU1hbmFnZXIoKTtcclxuICAgICAgICB0aGlzLnN1YnRpdGxlTWFuYWdlciA9IHN1YnRpdGxlTWFuYWdlcjtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9DVUVfRU5URVIsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAvLyBTYW5pdGl6ZSBjdWUgZGF0YSAobXVzdCBiZSBkb25lIGJlZm9yZSB0aGUgY3VlIElEIGlzIGdlbmVyYXRlZCBpbiBzdWJ0aXRsZU1hbmFnZXIuY3VlRW50ZXIpXHJcbiAgICAgICAgICAgIGlmIChldmVudC5wb3NpdGlvbikge1xyXG4gICAgICAgICAgICAgICAgLy8gU29tZXRpbWVzIHRoZSBwb3NpdGlvbnMgYXJlIHVuZGVmaW5lZCwgd2UgYXNzdW1lIHRoZW0gdG8gYmUgemVyb1xyXG4gICAgICAgICAgICAgICAgZXZlbnQucG9zaXRpb24ucm93ID0gZXZlbnQucG9zaXRpb24ucm93IHx8IDA7XHJcbiAgICAgICAgICAgICAgICBldmVudC5wb3NpdGlvbi5jb2x1bW4gPSBldmVudC5wb3NpdGlvbi5jb2x1bW4gfHwgMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgbGFiZWxUb0FkZCA9IHN1YnRpdGxlTWFuYWdlci5jdWVFbnRlcihldmVudCk7XHJcbiAgICAgICAgICAgIGlmIChfdGhpcy5wcmV2aWV3U3VidGl0bGVBY3RpdmUpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLnJlbW92ZUNvbXBvbmVudChfdGhpcy5wcmV2aWV3U3VidGl0bGUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF90aGlzLmFkZENvbXBvbmVudChsYWJlbFRvQWRkKTtcclxuICAgICAgICAgICAgX3RoaXMudXBkYXRlQ29tcG9uZW50cygpO1xyXG4gICAgICAgICAgICBfdGhpcy5zaG93KCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fQ1VFX0VYSVQsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICB2YXIgbGFiZWxUb1JlbW92ZSA9IHN1YnRpdGxlTWFuYWdlci5jdWVFeGl0KGV2ZW50KTtcclxuICAgICAgICAgICAgaWYgKGxhYmVsVG9SZW1vdmUpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLnJlbW92ZUNvbXBvbmVudChsYWJlbFRvUmVtb3ZlKTtcclxuICAgICAgICAgICAgICAgIF90aGlzLnVwZGF0ZUNvbXBvbmVudHMoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoIXN1YnRpdGxlTWFuYWdlci5oYXNDdWVzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIV90aGlzLnByZXZpZXdTdWJ0aXRsZUFjdGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmhpZGUoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmFkZENvbXBvbmVudChfdGhpcy5wcmV2aWV3U3VidGl0bGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnVwZGF0ZUNvbXBvbmVudHMoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZhciBzdWJ0aXRsZUNsZWFySGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMuaGlkZSgpO1xyXG4gICAgICAgICAgICBzdWJ0aXRsZU1hbmFnZXIuY2xlYXIoKTtcclxuICAgICAgICAgICAgX3RoaXMucmVtb3ZlQ29tcG9uZW50cygpO1xyXG4gICAgICAgICAgICBfdGhpcy51cGRhdGVDb21wb25lbnRzKCk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9BVURJT19DSEFOR0VELCBzdWJ0aXRsZUNsZWFySGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fU1VCVElUTEVfQ0hBTkdFRCwgc3VidGl0bGVDbGVhckhhbmRsZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1NFRUssIHN1YnRpdGxlQ2xlYXJIYW5kbGVyKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9USU1FX1NISUZULCBzdWJ0aXRsZUNsZWFySGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUExBWUJBQ0tfRklOSVNIRUQsIHN1YnRpdGxlQ2xlYXJIYW5kbGVyKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TT1VSQ0VfVU5MT0FERUQsIHN1YnRpdGxlQ2xlYXJIYW5kbGVyKTtcclxuICAgICAgICB1aW1hbmFnZXIub25Db21wb25lbnRTaG93LnN1YnNjcmliZShmdW5jdGlvbiAoY29tcG9uZW50KSB7XHJcbiAgICAgICAgICAgIGlmIChjb21wb25lbnQgaW5zdGFuY2VvZiBjb250cm9sYmFyXzEuQ29udHJvbEJhcikge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZ2V0RG9tRWxlbWVudCgpLmFkZENsYXNzKF90aGlzLnByZWZpeENzcyhTdWJ0aXRsZU92ZXJsYXkuQ0xBU1NfQ09OVFJPTEJBUl9WSVNJQkxFKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICB1aW1hbmFnZXIub25Db21wb25lbnRIaWRlLnN1YnNjcmliZShmdW5jdGlvbiAoY29tcG9uZW50KSB7XHJcbiAgICAgICAgICAgIGlmIChjb21wb25lbnQgaW5zdGFuY2VvZiBjb250cm9sYmFyXzEuQ29udHJvbEJhcikge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZ2V0RG9tRWxlbWVudCgpLnJlbW92ZUNsYXNzKF90aGlzLnByZWZpeENzcyhTdWJ0aXRsZU92ZXJsYXkuQ0xBU1NfQ09OVFJPTEJBUl9WSVNJQkxFKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLmNvbmZpZ3VyZUNlYTYwOENhcHRpb25zKHBsYXllciwgdWltYW5hZ2VyKTtcclxuICAgICAgICAvLyBJbml0XHJcbiAgICAgICAgc3VidGl0bGVDbGVhckhhbmRsZXIoKTtcclxuICAgIH07XHJcbiAgICBTdWJ0aXRsZU92ZXJsYXkucHJvdG90eXBlLmNvbmZpZ3VyZUNlYTYwOENhcHRpb25zID0gZnVuY3Rpb24gKHBsYXllciwgdWltYW5hZ2VyKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICAvLyBUaGUgY2FsY3VsYXRlZCBmb250IHNpemVcclxuICAgICAgICB2YXIgZm9udFNpemUgPSAwO1xyXG4gICAgICAgIC8vIFRoZSByZXF1aXJlZCBsZXR0ZXIgc3BhY2luZyBzcHJlYWQgdGhlIHRleHQgY2hhcmFjdGVycyBldmVubHkgYWNyb3NzIHRoZSBncmlkXHJcbiAgICAgICAgdmFyIGZvbnRMZXR0ZXJTcGFjaW5nID0gMDtcclxuICAgICAgICAvLyBGbGFnIHRlbGxpbmcgaWYgYSBmb250IHNpemUgY2FsY3VsYXRpb24gaXMgcmVxdWlyZWQgb2YgaWYgdGhlIGN1cnJlbnQgdmFsdWVzIGFyZSB2YWxpZFxyXG4gICAgICAgIHZhciBmb250U2l6ZUNhbGN1bGF0aW9uUmVxdWlyZWQgPSB0cnVlO1xyXG4gICAgICAgIC8vIEZsYWcgdGVsbGluZyBpZiB0aGUgQ0VBLTYwOCBtb2RlIGlzIGVuYWJsZWRcclxuICAgICAgICB2YXIgZW5hYmxlZCA9IGZhbHNlO1xyXG4gICAgICAgIHZhciB1cGRhdGVDRUE2MDhGb250U2l6ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIGR1bW15TGFiZWwgPSBuZXcgU3VidGl0bGVMYWJlbCh7IHRleHQ6ICdYJyB9KTtcclxuICAgICAgICAgICAgZHVtbXlMYWJlbC5nZXREb21FbGVtZW50KCkuY3NzKHtcclxuICAgICAgICAgICAgICAgIC8vIEJ5IHVzaW5nIGEgbGFyZ2UgZm9udCBzaXplIHdlIGRvIG5vdCBuZWVkIHRvIHVzZSBtdWx0aXBsZSBsZXR0ZXJzIGFuZCBjYW4gZ2V0IHN0aWxsIGFuXHJcbiAgICAgICAgICAgICAgICAvLyBhY2N1cmF0ZSBtZWFzdXJlbWVudCBldmVuIHRob3VnaCB0aGUgcmV0dXJuZWQgc2l6ZSBpcyBhbiBpbnRlZ2VyIHZhbHVlXHJcbiAgICAgICAgICAgICAgICAnZm9udC1zaXplJzogJzIwMHB4JyxcclxuICAgICAgICAgICAgICAgICdsaW5lLWhlaWdodCc6ICcyMDBweCcsXHJcbiAgICAgICAgICAgICAgICAndmlzaWJpbGl0eSc6ICdoaWRkZW4nLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgX3RoaXMuYWRkQ29tcG9uZW50KGR1bW15TGFiZWwpO1xyXG4gICAgICAgICAgICBfdGhpcy51cGRhdGVDb21wb25lbnRzKCk7XHJcbiAgICAgICAgICAgIF90aGlzLnNob3coKTtcclxuICAgICAgICAgICAgdmFyIGR1bW15TGFiZWxDaGFyV2lkdGggPSBkdW1teUxhYmVsLmdldERvbUVsZW1lbnQoKS53aWR0aCgpO1xyXG4gICAgICAgICAgICB2YXIgZHVtbXlMYWJlbENoYXJIZWlnaHQgPSBkdW1teUxhYmVsLmdldERvbUVsZW1lbnQoKS5oZWlnaHQoKTtcclxuICAgICAgICAgICAgdmFyIGZvbnRTaXplUmF0aW8gPSBkdW1teUxhYmVsQ2hhcldpZHRoIC8gZHVtbXlMYWJlbENoYXJIZWlnaHQ7XHJcbiAgICAgICAgICAgIF90aGlzLnJlbW92ZUNvbXBvbmVudChkdW1teUxhYmVsKTtcclxuICAgICAgICAgICAgX3RoaXMudXBkYXRlQ29tcG9uZW50cygpO1xyXG4gICAgICAgICAgICBpZiAoIV90aGlzLnN1YnRpdGxlTWFuYWdlci5oYXNDdWVzKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5oaWRlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gVGhlIHNpemUgcmF0aW8gb2YgdGhlIGxldHRlciBncmlkXHJcbiAgICAgICAgICAgIHZhciBmb250R3JpZFNpemVSYXRpbyA9IChkdW1teUxhYmVsQ2hhcldpZHRoICogU3VidGl0bGVPdmVybGF5LkNFQTYwOF9OVU1fQ09MVU1OUykgL1xyXG4gICAgICAgICAgICAgICAgKGR1bW15TGFiZWxDaGFySGVpZ2h0ICogU3VidGl0bGVPdmVybGF5LkNFQTYwOF9OVU1fUk9XUyk7XHJcbiAgICAgICAgICAgIC8vIFRoZSBzaXplIHJhdGlvIG9mIHRoZSBhdmFpbGFibGUgc3BhY2UgZm9yIHRoZSBncmlkXHJcbiAgICAgICAgICAgIHZhciBzdWJ0aXRsZU92ZXJsYXlTaXplUmF0aW8gPSBfdGhpcy5nZXREb21FbGVtZW50KCkud2lkdGgoKSAvIF90aGlzLmdldERvbUVsZW1lbnQoKS5oZWlnaHQoKTtcclxuICAgICAgICAgICAgaWYgKHN1YnRpdGxlT3ZlcmxheVNpemVSYXRpbyA+IGZvbnRHcmlkU2l6ZVJhdGlvKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBXaGVuIHRoZSBhdmFpbGFibGUgc3BhY2UgaXMgd2lkZXIgdGhhbiB0aGUgdGV4dCBncmlkLCB0aGUgZm9udCBzaXplIGlzIHNpbXBseVxyXG4gICAgICAgICAgICAgICAgLy8gZGV0ZXJtaW5lZCBieSB0aGUgaGVpZ2h0IG9mIHRoZSBhdmFpbGFibGUgc3BhY2UuXHJcbiAgICAgICAgICAgICAgICBmb250U2l6ZSA9IF90aGlzLmdldERvbUVsZW1lbnQoKS5oZWlnaHQoKSAvIFN1YnRpdGxlT3ZlcmxheS5DRUE2MDhfTlVNX1JPV1M7XHJcbiAgICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIGFkZGl0aW9uYWwgbGV0dGVyIHNwYWNpbmcgcmVxdWlyZWQgdG8gZXZlbmx5IHNwcmVhZCB0aGUgdGV4dCBhY3Jvc3MgdGhlIGdyaWQncyB3aWR0aFxyXG4gICAgICAgICAgICAgICAgdmFyIGdyaWRTbG90V2lkdGggPSBfdGhpcy5nZXREb21FbGVtZW50KCkud2lkdGgoKSAvIFN1YnRpdGxlT3ZlcmxheS5DRUE2MDhfTlVNX0NPTFVNTlM7XHJcbiAgICAgICAgICAgICAgICB2YXIgZm9udENoYXJXaWR0aCA9IGZvbnRTaXplICogZm9udFNpemVSYXRpbztcclxuICAgICAgICAgICAgICAgIGZvbnRMZXR0ZXJTcGFjaW5nID0gZ3JpZFNsb3RXaWR0aCAtIGZvbnRDaGFyV2lkdGg7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAvLyBXaGVuIHRoZSBhdmFpbGFibGUgc3BhY2UgaXMgbm90IHdpZGUgZW5vdWdoLCB0ZXh0cyB3b3VsZCB2ZXJ0aWNhbGx5IG92ZXJsYXAgaWYgd2UgdGFrZVxyXG4gICAgICAgICAgICAgICAgLy8gdGhlIGhlaWdodCBhcyBhIGJhc2UgZm9yIHRoZSBmb250IHNpemUsIHNvIHdlIG5lZWQgdG8gbGltaXQgdGhlIGhlaWdodC4gV2UgZG8gdGhhdFxyXG4gICAgICAgICAgICAgICAgLy8gYnkgZGV0ZXJtaW5pbmcgdGhlIGZvbnQgc2l6ZSBieSB0aGUgd2lkdGggb2YgdGhlIGF2YWlsYWJsZSBzcGFjZS5cclxuICAgICAgICAgICAgICAgIGZvbnRTaXplID0gX3RoaXMuZ2V0RG9tRWxlbWVudCgpLndpZHRoKCkgLyBTdWJ0aXRsZU92ZXJsYXkuQ0VBNjA4X05VTV9DT0xVTU5TIC8gZm9udFNpemVSYXRpbztcclxuICAgICAgICAgICAgICAgIGZvbnRMZXR0ZXJTcGFjaW5nID0gMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBVcGRhdGUgZm9udC1zaXplIG9mIGFsbCBhY3RpdmUgc3VidGl0bGUgbGFiZWxzXHJcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSBfdGhpcy5nZXRDb21wb25lbnRzKCk7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbGFiZWwgPSBfYVtfaV07XHJcbiAgICAgICAgICAgICAgICBpZiAobGFiZWwgaW5zdGFuY2VvZiBTdWJ0aXRsZUxhYmVsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGFiZWwuZ2V0RG9tRWxlbWVudCgpLmNzcyh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICdmb250LXNpemUnOiBmb250U2l6ZSArIFwicHhcIixcclxuICAgICAgICAgICAgICAgICAgICAgICAgJ2xldHRlci1zcGFjaW5nJzogZm9udExldHRlclNwYWNpbmcgKyBcInB4XCIsXHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BMQVlFUl9SRVNJWkUsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKGVuYWJsZWQpIHtcclxuICAgICAgICAgICAgICAgIHVwZGF0ZUNFQTYwOEZvbnRTaXplKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBmb250U2l6ZUNhbGN1bGF0aW9uUmVxdWlyZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fQ1VFX0VOVEVSLCBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgdmFyIGlzQ0VBNjA4ID0gZXZlbnQucG9zaXRpb24gIT0gbnVsbDtcclxuICAgICAgICAgICAgaWYgKCFpc0NFQTYwOCkge1xyXG4gICAgICAgICAgICAgICAgLy8gU2tpcCBhbGwgbm9uLUNFQTYwOCBjdWVzXHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIGxhYmVscyA9IF90aGlzLnN1YnRpdGxlTWFuYWdlci5nZXRDdWVzKGV2ZW50KTtcclxuICAgICAgICAgICAgaWYgKCFlbmFibGVkKSB7XHJcbiAgICAgICAgICAgICAgICBlbmFibGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIF90aGlzLmdldERvbUVsZW1lbnQoKS5hZGRDbGFzcyhfdGhpcy5wcmVmaXhDc3MoU3VidGl0bGVPdmVybGF5LkNMQVNTX0NFQV82MDgpKTtcclxuICAgICAgICAgICAgICAgIC8vIFdlIGNvbmRpdGlvbmFsbHkgdXBkYXRlIHRoZSBmb250IHNpemUgYnkgdGhpcyBmbGFnIGhlcmUgdG8gYXZvaWQgdXBkYXRpbmcgZXZlcnkgdGltZSBhIHN1YnRpdGxlXHJcbiAgICAgICAgICAgICAgICAvLyBpcyBhZGRlZCBpbnRvIGFuIGVtcHR5IG92ZXJsYXkuIEJlY2F1c2Ugd2UgcmVzZXQgdGhlIG92ZXJsYXkgd2hlbiBhbGwgc3VidGl0bGVzIGFyZSBnb25lLCB0aGlzXHJcbiAgICAgICAgICAgICAgICAvLyB3b3VsZCB0cmlnZ2VyIGFuIHVubmVjZXNzYXJ5IHVwZGF0ZSBldmVyeSB0aW1lLCBidXQgaXQncyBvbmx5IHJlcXVpcmVkIHVuZGVyIGNlcnRhaW4gY29uZGl0aW9ucyxcclxuICAgICAgICAgICAgICAgIC8vIGUuZy4gYWZ0ZXIgdGhlIHBsYXllciBzaXplIGhhcyBjaGFuZ2VkLlxyXG4gICAgICAgICAgICAgICAgaWYgKGZvbnRTaXplQ2FsY3VsYXRpb25SZXF1aXJlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHVwZGF0ZUNFQTYwOEZvbnRTaXplKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9udFNpemVDYWxjdWxhdGlvblJlcXVpcmVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBsYWJlbHNfMSA9IGxhYmVsczsgX2kgPCBsYWJlbHNfMS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgICAgIHZhciBsYWJlbCA9IGxhYmVsc18xW19pXTtcclxuICAgICAgICAgICAgICAgIGxhYmVsLmdldERvbUVsZW1lbnQoKS5jc3Moe1xyXG4gICAgICAgICAgICAgICAgICAgICdsZWZ0JzogZXZlbnQucG9zaXRpb24uY29sdW1uICogU3VidGl0bGVPdmVybGF5LkNFQTYwOF9DT0xVTU5fT0ZGU0VUICsgXCIlXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgJ3RvcCc6IGV2ZW50LnBvc2l0aW9uLnJvdyAqIFN1YnRpdGxlT3ZlcmxheS5DRUE2MDhfUk9XX09GRlNFVCArIFwiJVwiLFxyXG4gICAgICAgICAgICAgICAgICAgICdmb250LXNpemUnOiBmb250U2l6ZSArIFwicHhcIixcclxuICAgICAgICAgICAgICAgICAgICAnbGV0dGVyLXNwYWNpbmcnOiBmb250TGV0dGVyU3BhY2luZyArIFwicHhcIixcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdmFyIHJlc2V0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5nZXREb21FbGVtZW50KCkucmVtb3ZlQ2xhc3MoX3RoaXMucHJlZml4Q3NzKFN1YnRpdGxlT3ZlcmxheS5DTEFTU19DRUFfNjA4KSk7XHJcbiAgICAgICAgICAgIGVuYWJsZWQgPSBmYWxzZTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0NVRV9FWElULCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmICghX3RoaXMuc3VidGl0bGVNYW5hZ2VyLmhhc0N1ZXMpIHtcclxuICAgICAgICAgICAgICAgIC8vIERpc2FibGUgQ0VBLTYwOCBtb2RlIHdoZW4gYWxsIHN1YnRpdGxlcyBhcmUgZ29uZSAodG8gYWxsb3cgY29ycmVjdCBmb3JtYXR0aW5nIGFuZFxyXG4gICAgICAgICAgICAgICAgLy8gZGlzcGxheSBvZiBvdGhlciB0eXBlcyBvZiBzdWJ0aXRsZXMsIGUuZy4gdGhlIGZvcm1hdHRpbmcgcHJldmlldyBzdWJ0aXRsZSlcclxuICAgICAgICAgICAgICAgIHJlc2V0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TT1VSQ0VfVU5MT0FERUQsIHJlc2V0KTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TVUJUSVRMRV9DSEFOR0VELCByZXNldCk7XHJcbiAgICB9O1xyXG4gICAgU3VidGl0bGVPdmVybGF5LnByb3RvdHlwZS5lbmFibGVQcmV2aWV3U3VidGl0bGVMYWJlbCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLnByZXZpZXdTdWJ0aXRsZUFjdGl2ZSA9IHRydWU7XHJcbiAgICAgICAgaWYgKCF0aGlzLnN1YnRpdGxlTWFuYWdlci5oYXNDdWVzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuYWRkQ29tcG9uZW50KHRoaXMucHJldmlld1N1YnRpdGxlKTtcclxuICAgICAgICAgICAgdGhpcy51cGRhdGVDb21wb25lbnRzKCk7XHJcbiAgICAgICAgICAgIHRoaXMuc2hvdygpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBTdWJ0aXRsZU92ZXJsYXkucHJvdG90eXBlLnJlbW92ZVByZXZpZXdTdWJ0aXRsZUxhYmVsID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMucHJldmlld1N1YnRpdGxlQWN0aXZlID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5yZW1vdmVDb21wb25lbnQodGhpcy5wcmV2aWV3U3VidGl0bGUpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlQ29tcG9uZW50cygpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBTdWJ0aXRsZU92ZXJsYXk7XHJcbn0oY29udGFpbmVyXzEuQ29udGFpbmVyKSk7XHJcblN1YnRpdGxlT3ZlcmxheS5DTEFTU19DT05UUk9MQkFSX1ZJU0lCTEUgPSAnY29udHJvbGJhci12aXNpYmxlJztcclxuU3VidGl0bGVPdmVybGF5LkNMQVNTX0NFQV82MDggPSAnY2VhNjA4JztcclxuLy8gVGhlIG51bWJlciBvZiByb3dzIGluIGEgY2VhNjA4IGdyaWRcclxuU3VidGl0bGVPdmVybGF5LkNFQTYwOF9OVU1fUk9XUyA9IDE1O1xyXG4vLyBUaGUgbnVtYmVyIG9mIGNvbHVtbnMgaW4gYSBjZWE2MDggZ3JpZFxyXG5TdWJ0aXRsZU92ZXJsYXkuQ0VBNjA4X05VTV9DT0xVTU5TID0gMzI7XHJcbi8vIFRoZSBvZmZzZXQgaW4gcGVyY2VudCBmb3Igb25lIHJvdyAod2hpY2ggaXMgYWxzbyB0aGUgaGVpZ2h0IG9mIGEgcm93KVxyXG5TdWJ0aXRsZU92ZXJsYXkuQ0VBNjA4X1JPV19PRkZTRVQgPSAxMDAgLyBTdWJ0aXRsZU92ZXJsYXkuQ0VBNjA4X05VTV9ST1dTO1xyXG4vLyBUaGUgb2Zmc2V0IGluIHBlcmNlbnQgZm9yIG9uZSBjb2x1bW4gKHdoaWNoIGlzIGFsc28gdGhlIHdpZHRoIG9mIGEgY29sdW1uKVxyXG5TdWJ0aXRsZU92ZXJsYXkuQ0VBNjA4X0NPTFVNTl9PRkZTRVQgPSAxMDAgLyBTdWJ0aXRsZU92ZXJsYXkuQ0VBNjA4X05VTV9DT0xVTU5TO1xyXG5leHBvcnRzLlN1YnRpdGxlT3ZlcmxheSA9IFN1YnRpdGxlT3ZlcmxheTtcclxudmFyIFN1YnRpdGxlTGFiZWwgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKFN1YnRpdGxlTGFiZWwsIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBTdWJ0aXRsZUxhYmVsKGNvbmZpZykge1xyXG4gICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1zdWJ0aXRsZS1sYWJlbCcsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gU3VidGl0bGVMYWJlbDtcclxufShsYWJlbF8xLkxhYmVsKSk7XHJcbnZhciBBY3RpdmVTdWJ0aXRsZU1hbmFnZXIgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gQWN0aXZlU3VidGl0bGVNYW5hZ2VyKCkge1xyXG4gICAgICAgIHRoaXMuYWN0aXZlU3VidGl0bGVDdWVNYXAgPSB7fTtcclxuICAgICAgICB0aGlzLmFjdGl2ZVN1YnRpdGxlQ3VlQ291bnQgPSAwO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxjdWxhdGVzIGEgdW5pcXVlIElEIGZvciBhIHN1YnRpdGxlIGN1ZSwgd2hpY2ggaXMgbmVlZGVkIHRvIGFzc29jaWF0ZSBhbiBPTl9DVUVfRU5URVIgd2l0aCBpdHMgT05fQ1VFX0VYSVRcclxuICAgICAqIGV2ZW50IHNvIHdlIGNhbiByZW1vdmUgdGhlIGNvcnJlY3Qgc3VidGl0bGUgaW4gT05fQ1VFX0VYSVQgd2hlbiBtdWx0aXBsZSBzdWJ0aXRsZXMgYXJlIGFjdGl2ZSBhdCB0aGUgc2FtZSB0aW1lLlxyXG4gICAgICogVGhlIHN0YXJ0IHRpbWUgcGx1cyB0aGUgdGV4dCBzaG91bGQgbWFrZSBhIHVuaXF1ZSBpZGVudGlmaWVyLCBhbmQgaW4gdGhlIG9ubHkgY2FzZSB3aGVyZSBhIGNvbGxpc2lvblxyXG4gICAgICogY2FuIGhhcHBlbiwgdHdvIHNpbWlsYXIgdGV4dHMgd2lsbCBiZSBkaXNwbGF5ZWQgYXQgYSBzaW1pbGFyIHRpbWUgYW5kIGEgc2ltaWxhciBwb3NpdGlvbiAob3Igd2l0aG91dCBwb3NpdGlvbikuXHJcbiAgICAgKiBUaGUgc3RhcnQgdGltZSBzaG91bGQgYWx3YXlzIGJlIGtub3duLCBiZWNhdXNlIGl0IGlzIHJlcXVpcmVkIHRvIHNjaGVkdWxlIHRoZSBPTl9DVUVfRU5URVIgZXZlbnQuIFRoZSBlbmQgdGltZVxyXG4gICAgICogbXVzdCBub3QgbmVjZXNzYXJpbHkgYmUga25vd24gYW5kIHRoZXJlZm9yZSBjYW5ub3QgYmUgdXNlZCBmb3IgdGhlIElELlxyXG4gICAgICogQHBhcmFtIGV2ZW50XHJcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmd9XHJcbiAgICAgKi9cclxuICAgIEFjdGl2ZVN1YnRpdGxlTWFuYWdlci5jYWxjdWxhdGVJZCA9IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgIHZhciBpZCA9IGV2ZW50LnN0YXJ0ICsgJy0nICsgZXZlbnQudGV4dDtcclxuICAgICAgICBpZiAoZXZlbnQucG9zaXRpb24pIHtcclxuICAgICAgICAgICAgaWQgKz0gJy0nICsgZXZlbnQucG9zaXRpb24ucm93ICsgJy0nICsgZXZlbnQucG9zaXRpb24uY29sdW1uO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gaWQ7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBBZGRzIGEgc3VidGl0bGUgY3VlIHRvIHRoZSBtYW5hZ2VyIGFuZCByZXR1cm5zIHRoZSBsYWJlbCB0aGF0IHNob3VsZCBiZSBhZGRlZCB0byB0aGUgc3VidGl0bGUgb3ZlcmxheS5cclxuICAgICAqIEBwYXJhbSBldmVudFxyXG4gICAgICogQHJldHVybiB7U3VidGl0bGVMYWJlbH1cclxuICAgICAqL1xyXG4gICAgQWN0aXZlU3VidGl0bGVNYW5hZ2VyLnByb3RvdHlwZS5jdWVFbnRlciA9IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgIHZhciBpZCA9IEFjdGl2ZVN1YnRpdGxlTWFuYWdlci5jYWxjdWxhdGVJZChldmVudCk7XHJcbiAgICAgICAgdmFyIGxhYmVsID0gbmV3IFN1YnRpdGxlTGFiZWwoe1xyXG4gICAgICAgICAgICAvLyBQcmVmZXIgdGhlIEhUTUwgc3VidGl0bGUgdGV4dCBpZiBzZXQsIGVsc2UgdXNlIHRoZSBwbGFpbiB0ZXh0XHJcbiAgICAgICAgICAgIHRleHQ6IGV2ZW50Lmh0bWwgfHwgZXZlbnQudGV4dCxcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBDcmVhdGUgYXJyYXkgZm9yIGlkIGlmIGl0IGRvZXMgbm90IGV4aXN0XHJcbiAgICAgICAgdGhpcy5hY3RpdmVTdWJ0aXRsZUN1ZU1hcFtpZF0gPSB0aGlzLmFjdGl2ZVN1YnRpdGxlQ3VlTWFwW2lkXSB8fCBbXTtcclxuICAgICAgICAvLyBBZGQgY3VlXHJcbiAgICAgICAgdGhpcy5hY3RpdmVTdWJ0aXRsZUN1ZU1hcFtpZF0ucHVzaCh7IGV2ZW50OiBldmVudCwgbGFiZWw6IGxhYmVsIH0pO1xyXG4gICAgICAgIHRoaXMuYWN0aXZlU3VidGl0bGVDdWVDb3VudCsrO1xyXG4gICAgICAgIHJldHVybiBsYWJlbDtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGxhYmVsIGFzc29jaWF0ZWQgd2l0aCBhbiBhbHJlYWR5IGFkZGVkIGN1ZS5cclxuICAgICAqIEBwYXJhbSBldmVudFxyXG4gICAgICogQHJldHVybiB7U3VidGl0bGVMYWJlbH1cclxuICAgICAqL1xyXG4gICAgQWN0aXZlU3VidGl0bGVNYW5hZ2VyLnByb3RvdHlwZS5nZXRDdWVzID0gZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgdmFyIGlkID0gQWN0aXZlU3VidGl0bGVNYW5hZ2VyLmNhbGN1bGF0ZUlkKGV2ZW50KTtcclxuICAgICAgICB2YXIgYWN0aXZlU3VidGl0bGVDdWVzID0gdGhpcy5hY3RpdmVTdWJ0aXRsZUN1ZU1hcFtpZF07XHJcbiAgICAgICAgaWYgKGFjdGl2ZVN1YnRpdGxlQ3VlcyAmJiBhY3RpdmVTdWJ0aXRsZUN1ZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICByZXR1cm4gYWN0aXZlU3VidGl0bGVDdWVzLm1hcChmdW5jdGlvbiAoY3VlKSB7IHJldHVybiBjdWUubGFiZWw7IH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmVtb3ZlcyB0aGUgc3VidGl0bGUgY3VlIGZyb20gdGhlIG1hbmFnZXIgYW5kIHJldHVybnMgdGhlIGxhYmVsIHRoYXQgc2hvdWxkIGJlIHJlbW92ZWQgZnJvbSB0aGUgc3VidGl0bGUgb3ZlcmxheSxcclxuICAgICAqIG9yIG51bGwgaWYgdGhlcmUgaXMgbm8gYXNzb2NpYXRlZCBsYWJlbCBleGlzdGluZyAoZS5nLiBiZWNhdXNlIGFsbCBsYWJlbHMgaGF2ZSBiZWVuIHtAbGluayAjY2xlYXIgY2xlYXJlZH0uXHJcbiAgICAgKiBAcGFyYW0gZXZlbnRcclxuICAgICAqIEByZXR1cm4ge1N1YnRpdGxlTGFiZWx8bnVsbH1cclxuICAgICAqL1xyXG4gICAgQWN0aXZlU3VidGl0bGVNYW5hZ2VyLnByb3RvdHlwZS5jdWVFeGl0ID0gZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgdmFyIGlkID0gQWN0aXZlU3VidGl0bGVNYW5hZ2VyLmNhbGN1bGF0ZUlkKGV2ZW50KTtcclxuICAgICAgICB2YXIgYWN0aXZlU3VidGl0bGVDdWVzID0gdGhpcy5hY3RpdmVTdWJ0aXRsZUN1ZU1hcFtpZF07XHJcbiAgICAgICAgaWYgKGFjdGl2ZVN1YnRpdGxlQ3VlcyAmJiBhY3RpdmVTdWJ0aXRsZUN1ZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAvLyBSZW1vdmUgY3VlXHJcbiAgICAgICAgICAgIC8qIFdlIGFwcGx5IHRoZSBGSUZPIGFwcHJvYWNoIGhlcmUgYW5kIHJlbW92ZSB0aGUgb2xkZXN0IGN1ZSBmcm9tIHRoZSBhc3NvY2lhdGVkIGlkLiBXaGVuIHRoZXJlIGFyZSBtdWx0aXBsZSBjdWVzXHJcbiAgICAgICAgICAgICAqIHdpdGggdGhlIHNhbWUgaWQsIHRoZXJlIGlzIG5vIHdheSB0byBrbm93IHdoaWNoIG9uZSBvZiB0aGUgY3VlcyBpcyB0byBiZSBkZWxldGVkLCBzbyB3ZSBqdXN0IGhvcGUgdGhhdCBGSUZPXHJcbiAgICAgICAgICAgICAqIHdvcmtzIGZpbmUuIFRoZW9yZXRpY2FsbHkgaXQgY2FuIGhhcHBlbiB0aGF0IHR3byBjdWVzIHdpdGggY29sbGlkaW5nIGlkcyBhcmUgcmVtb3ZlZCBhdCBkaWZmZXJlbnQgdGltZXMsIGluXHJcbiAgICAgICAgICAgICAqIHRoZSB3cm9uZyBvcmRlci4gVGhpcyByYXJlIGNhc2UgaGFzIHlldCB0byBiZSBvYnNlcnZlZC4gSWYgaXQgZXZlciBnZXRzIGFuIGlzc3VlLCB3ZSBjYW4gdGFrZSB0aGUgdW5zdGFibGVcclxuICAgICAgICAgICAgICogY3VlIGVuZCB0aW1lICh3aGljaCBjYW4gY2hhbmdlIGJldHdlZW4gT05fQ1VFX0VOVEVSIGFuZCBPTl9DVUVfRVhJVCBJTiBPTl9DVUVfVVBEQVRFKSBhbmQgdXNlIGl0IGFzIGFuXHJcbiAgICAgICAgICAgICAqIGFkZGl0aW9uYWwgaGludCB0byB0cnkgYW5kIHJlbW92ZSB0aGUgY29ycmVjdCBvbmUgb2YgdGhlIGNvbGxpZGluZyBjdWVzLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgdmFyIGFjdGl2ZVN1YnRpdGxlQ3VlID0gYWN0aXZlU3VidGl0bGVDdWVzLnNoaWZ0KCk7XHJcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlU3VidGl0bGVDdWVDb3VudC0tO1xyXG4gICAgICAgICAgICByZXR1cm4gYWN0aXZlU3VidGl0bGVDdWUubGFiZWw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFjdGl2ZVN1YnRpdGxlTWFuYWdlci5wcm90b3R5cGUsIFwiY3VlQ291bnRcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJldHVybnMgdGhlIG51bWJlciBvZiBhY3RpdmUgc3VidGl0bGUgY3Vlcy5cclxuICAgICAgICAgKiBAcmV0dXJuIHtudW1iZXJ9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIC8vIFdlIGV4cGxpY2l0bHkgY291bnQgdGhlIGN1ZXMgdG8gc2F2ZSBhbiBBcnJheS5yZWR1Y2Ugb24gZXZlcnkgY3VlQ291bnQgY2FsbCAod2hpY2ggY2FuIGhhcHBlbiBmcmVxdWVudGx5KVxyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5hY3RpdmVTdWJ0aXRsZUN1ZUNvdW50O1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEFjdGl2ZVN1YnRpdGxlTWFuYWdlci5wcm90b3R5cGUsIFwiaGFzQ3Vlc1wiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmV0dXJucyB0cnVlIGlmIHRoZXJlIGFyZSBhY3RpdmUgc3VidGl0bGUgY3VlcywgZWxzZSBmYWxzZS5cclxuICAgICAgICAgKiBAcmV0dXJuIHtib29sZWFufVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jdWVDb3VudCA+IDA7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICAvKipcclxuICAgICAqIFJlbW92ZXMgYWxsIHN1YnRpdGxlIGN1ZXMgZnJvbSB0aGUgbWFuYWdlci5cclxuICAgICAqL1xyXG4gICAgQWN0aXZlU3VidGl0bGVNYW5hZ2VyLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmFjdGl2ZVN1YnRpdGxlQ3VlTWFwID0ge307XHJcbiAgICAgICAgdGhpcy5hY3RpdmVTdWJ0aXRsZUN1ZUNvdW50ID0gMDtcclxuICAgIH07XHJcbiAgICByZXR1cm4gQWN0aXZlU3VidGl0bGVNYW5hZ2VyO1xyXG59KCkpO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvc3VidGl0bGVvdmVybGF5LnRzXG4vLyBtb2R1bGUgaWQgPSA0MFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGNvbXBvbmVudF8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50XCIpO1xyXG52YXIgZG9tXzEgPSByZXF1aXJlKFwiLi4vZG9tXCIpO1xyXG4vKipcclxuICogQW5pbWF0ZWQgYW5hbG9nIFRWIHN0YXRpYyBub2lzZS5cclxuICovXHJcbnZhciBUdk5vaXNlQ2FudmFzID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhUdk5vaXNlQ2FudmFzLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gVHZOb2lzZUNhbnZhcyhjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuY2FudmFzV2lkdGggPSAxNjA7XHJcbiAgICAgICAgX3RoaXMuY2FudmFzSGVpZ2h0ID0gOTA7XHJcbiAgICAgICAgX3RoaXMuaW50ZXJmZXJlbmNlSGVpZ2h0ID0gNTA7XHJcbiAgICAgICAgX3RoaXMubGFzdEZyYW1lVXBkYXRlID0gMDtcclxuICAgICAgICBfdGhpcy5mcmFtZUludGVydmFsID0gNjA7XHJcbiAgICAgICAgX3RoaXMudXNlQW5pbWF0aW9uRnJhbWUgPSAhIXdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWU7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktdHZub2lzZWNhbnZhcycsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBUdk5vaXNlQ2FudmFzLnByb3RvdHlwZS50b0RvbUVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY2FudmFzID0gbmV3IGRvbV8xLkRPTSgnY2FudmFzJywgeyAnY2xhc3MnOiB0aGlzLmdldENzc0NsYXNzZXMoKSB9KTtcclxuICAgIH07XHJcbiAgICBUdk5vaXNlQ2FudmFzLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmNhbnZhc0VsZW1lbnQgPSB0aGlzLmNhbnZhcy5nZXQoMCk7XHJcbiAgICAgICAgdGhpcy5jYW52YXNDb250ZXh0ID0gdGhpcy5jYW52YXNFbGVtZW50LmdldENvbnRleHQoJzJkJyk7XHJcbiAgICAgICAgdGhpcy5ub2lzZUFuaW1hdGlvbldpbmRvd1BvcyA9IC10aGlzLmNhbnZhc0hlaWdodDtcclxuICAgICAgICB0aGlzLmxhc3RGcmFtZVVwZGF0ZSA9IDA7XHJcbiAgICAgICAgdGhpcy5jYW52YXNFbGVtZW50LndpZHRoID0gdGhpcy5jYW52YXNXaWR0aDtcclxuICAgICAgICB0aGlzLmNhbnZhc0VsZW1lbnQuaGVpZ2h0ID0gdGhpcy5jYW52YXNIZWlnaHQ7XHJcbiAgICAgICAgdGhpcy5yZW5kZXJGcmFtZSgpO1xyXG4gICAgfTtcclxuICAgIFR2Tm9pc2VDYW52YXMucHJvdG90eXBlLnN0b3AgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMudXNlQW5pbWF0aW9uRnJhbWUpIHtcclxuICAgICAgICAgICAgY2FuY2VsQW5pbWF0aW9uRnJhbWUodGhpcy5mcmFtZVVwZGF0ZUhhbmRsZXJJZCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5mcmFtZVVwZGF0ZUhhbmRsZXJJZCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIFR2Tm9pc2VDYW52YXMucHJvdG90eXBlLnJlbmRlckZyYW1lID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIFRoaXMgY29kZSBoYXMgYmVlbiBjb3BpZWQgZnJvbSB0aGUgcGxheWVyIGNvbnRyb2xzLmpzIGFuZCBzaW1wbGlmaWVkXHJcbiAgICAgICAgaWYgKHRoaXMubGFzdEZyYW1lVXBkYXRlICsgdGhpcy5mcmFtZUludGVydmFsID4gbmV3IERhdGUoKS5nZXRUaW1lKCkpIHtcclxuICAgICAgICAgICAgLy8gSXQncyB0b28gZWFybHkgdG8gcmVuZGVyIHRoZSBuZXh0IGZyYW1lXHJcbiAgICAgICAgICAgIHRoaXMuc2NoZWR1bGVOZXh0UmVuZGVyKCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGN1cnJlbnRQaXhlbE9mZnNldDtcclxuICAgICAgICB2YXIgY2FudmFzV2lkdGggPSB0aGlzLmNhbnZhc1dpZHRoO1xyXG4gICAgICAgIHZhciBjYW52YXNIZWlnaHQgPSB0aGlzLmNhbnZhc0hlaWdodDtcclxuICAgICAgICAvLyBDcmVhdGUgdGV4dHVyZVxyXG4gICAgICAgIHZhciBub2lzZUltYWdlID0gdGhpcy5jYW52YXNDb250ZXh0LmNyZWF0ZUltYWdlRGF0YShjYW52YXNXaWR0aCwgY2FudmFzSGVpZ2h0KTtcclxuICAgICAgICAvLyBGaWxsIHRleHR1cmUgd2l0aCBub2lzZVxyXG4gICAgICAgIGZvciAodmFyIHkgPSAwOyB5IDwgY2FudmFzSGVpZ2h0OyB5KyspIHtcclxuICAgICAgICAgICAgZm9yICh2YXIgeCA9IDA7IHggPCBjYW52YXNXaWR0aDsgeCsrKSB7XHJcbiAgICAgICAgICAgICAgICBjdXJyZW50UGl4ZWxPZmZzZXQgPSAoY2FudmFzV2lkdGggKiB5ICogNCkgKyB4ICogNDtcclxuICAgICAgICAgICAgICAgIG5vaXNlSW1hZ2UuZGF0YVtjdXJyZW50UGl4ZWxPZmZzZXRdID0gTWF0aC5yYW5kb20oKSAqIDI1NTtcclxuICAgICAgICAgICAgICAgIGlmICh5IDwgdGhpcy5ub2lzZUFuaW1hdGlvbldpbmRvd1BvcyB8fCB5ID4gdGhpcy5ub2lzZUFuaW1hdGlvbldpbmRvd1BvcyArIHRoaXMuaW50ZXJmZXJlbmNlSGVpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbm9pc2VJbWFnZS5kYXRhW2N1cnJlbnRQaXhlbE9mZnNldF0gKj0gMC44NTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG5vaXNlSW1hZ2UuZGF0YVtjdXJyZW50UGl4ZWxPZmZzZXQgKyAxXSA9IG5vaXNlSW1hZ2UuZGF0YVtjdXJyZW50UGl4ZWxPZmZzZXRdO1xyXG4gICAgICAgICAgICAgICAgbm9pc2VJbWFnZS5kYXRhW2N1cnJlbnRQaXhlbE9mZnNldCArIDJdID0gbm9pc2VJbWFnZS5kYXRhW2N1cnJlbnRQaXhlbE9mZnNldF07XHJcbiAgICAgICAgICAgICAgICBub2lzZUltYWdlLmRhdGFbY3VycmVudFBpeGVsT2Zmc2V0ICsgM10gPSA1MDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBQdXQgdGV4dHVyZSBvbnRvIGNhbnZhc1xyXG4gICAgICAgIHRoaXMuY2FudmFzQ29udGV4dC5wdXRJbWFnZURhdGEobm9pc2VJbWFnZSwgMCwgMCk7XHJcbiAgICAgICAgdGhpcy5sYXN0RnJhbWVVcGRhdGUgPSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcclxuICAgICAgICB0aGlzLm5vaXNlQW5pbWF0aW9uV2luZG93UG9zICs9IDc7XHJcbiAgICAgICAgaWYgKHRoaXMubm9pc2VBbmltYXRpb25XaW5kb3dQb3MgPiBjYW52YXNIZWlnaHQpIHtcclxuICAgICAgICAgICAgdGhpcy5ub2lzZUFuaW1hdGlvbldpbmRvd1BvcyA9IC1jYW52YXNIZWlnaHQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuc2NoZWR1bGVOZXh0UmVuZGVyKCk7XHJcbiAgICB9O1xyXG4gICAgVHZOb2lzZUNhbnZhcy5wcm90b3R5cGUuc2NoZWR1bGVOZXh0UmVuZGVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICh0aGlzLnVzZUFuaW1hdGlvbkZyYW1lKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZnJhbWVVcGRhdGVIYW5kbGVySWQgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lKHRoaXMucmVuZGVyRnJhbWUuYmluZCh0aGlzKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmZyYW1lVXBkYXRlSGFuZGxlcklkID0gc2V0VGltZW91dCh0aGlzLnJlbmRlckZyYW1lLmJpbmQodGhpcyksIHRoaXMuZnJhbWVJbnRlcnZhbCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHJldHVybiBUdk5vaXNlQ2FudmFzO1xyXG59KGNvbXBvbmVudF8xLkNvbXBvbmVudCkpO1xyXG5leHBvcnRzLlR2Tm9pc2VDYW52YXMgPSBUdk5vaXNlQ2FudmFzO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvdHZub2lzZWNhbnZhcy50c1xuLy8gbW9kdWxlIGlkID0gNDFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBsaXN0c2VsZWN0b3JfMSA9IHJlcXVpcmUoXCIuL2xpc3RzZWxlY3RvclwiKTtcclxudmFyIGRvbV8xID0gcmVxdWlyZShcIi4uL2RvbVwiKTtcclxudmFyIEl0ZW1TZWxlY3Rpb25MaXN0ID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhJdGVtU2VsZWN0aW9uTGlzdCwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIEl0ZW1TZWxlY3Rpb25MaXN0KGNvbmZpZykge1xyXG4gICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgdGFnOiAndWwnLFxyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLWl0ZW1zZWxlY3Rpb25saXN0JyxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIEl0ZW1TZWxlY3Rpb25MaXN0LnByb3RvdHlwZS5pc0FjdGl2ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5pdGVtcy5sZW5ndGggPiAxO1xyXG4gICAgfTtcclxuICAgIEl0ZW1TZWxlY3Rpb25MaXN0LnByb3RvdHlwZS50b0RvbUVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGxpc3RFbGVtZW50ID0gbmV3IGRvbV8xLkRPTSgndWwnLCB7XHJcbiAgICAgICAgICAgICdpZCc6IHRoaXMuY29uZmlnLmlkLFxyXG4gICAgICAgICAgICAnY2xhc3MnOiB0aGlzLmdldENzc0NsYXNzZXMoKSxcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLmxpc3RFbGVtZW50ID0gbGlzdEVsZW1lbnQ7XHJcbiAgICAgICAgdGhpcy51cGRhdGVEb21JdGVtcygpO1xyXG4gICAgICAgIHJldHVybiBsaXN0RWxlbWVudDtcclxuICAgIH07XHJcbiAgICBJdGVtU2VsZWN0aW9uTGlzdC5wcm90b3R5cGUudXBkYXRlRG9tSXRlbXMgPSBmdW5jdGlvbiAoc2VsZWN0ZWRWYWx1ZSkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgaWYgKHNlbGVjdGVkVmFsdWUgPT09IHZvaWQgMCkgeyBzZWxlY3RlZFZhbHVlID0gbnVsbDsgfVxyXG4gICAgICAgIC8vIERlbGV0ZSBhbGwgY2hpbGRyZW5cclxuICAgICAgICB0aGlzLmxpc3RFbGVtZW50LmVtcHR5KCk7XHJcbiAgICAgICAgdmFyIHNlbGVjdGVkTGlzdEl0ZW0gPSBudWxsO1xyXG4gICAgICAgIHZhciBzZWxlY3RJdGVtID0gZnVuY3Rpb24gKGxpc3RJdGVtKSB7XHJcbiAgICAgICAgICAgIGxpc3RJdGVtLmFkZENsYXNzKF90aGlzLnByZWZpeENzcyhJdGVtU2VsZWN0aW9uTGlzdC5DTEFTU19TRUxFQ1RFRCkpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIGRlc2VsZWN0SXRlbSA9IGZ1bmN0aW9uIChsaXN0SXRlbSkge1xyXG4gICAgICAgICAgICBsaXN0SXRlbS5yZW1vdmVDbGFzcyhfdGhpcy5wcmVmaXhDc3MoSXRlbVNlbGVjdGlvbkxpc3QuQ0xBU1NfU0VMRUNURUQpKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciBfbG9vcF8xID0gZnVuY3Rpb24gKGl0ZW0pIHtcclxuICAgICAgICAgICAgdmFyIGxpc3RJdGVtID0gbmV3IGRvbV8xLkRPTSgnbGknLCB7XHJcbiAgICAgICAgICAgICAgICAndHlwZSc6ICdsaScsXHJcbiAgICAgICAgICAgICAgICAnY2xhc3MnOiB0aGlzXzEucHJlZml4Q3NzKCd1aS1zZWxlY3Rpb25saXN0aXRlbScpLFxyXG4gICAgICAgICAgICB9KS5hcHBlbmQobmV3IGRvbV8xLkRPTSgnYScsIHt9KS5odG1sKGl0ZW0ubGFiZWwpKTtcclxuICAgICAgICAgICAgaWYgKCFzZWxlY3RlZExpc3RJdGVtKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWRWYWx1ZSA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRMaXN0SXRlbSA9IGxpc3RJdGVtO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoU3RyaW5nKHNlbGVjdGVkVmFsdWUpID09PSBpdGVtLmtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkTGlzdEl0ZW0gPSBsaXN0SXRlbTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBIYW5kbGUgbGlzdCBpdGVtIHNlbGVjdGlvbnNcclxuICAgICAgICAgICAgbGlzdEl0ZW0ub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgLy8gRGVzZWxlY3QgdGhlIHByZXZpb3VzIGl0ZW0gKGlmIHRoZXJlIHdhcyBhIHNlbGVjdGVkIGl0ZW0pXHJcbiAgICAgICAgICAgICAgICBpZiAoc2VsZWN0ZWRMaXN0SXRlbSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGRlc2VsZWN0SXRlbShzZWxlY3RlZExpc3RJdGVtKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIFNlbGVjdCB0aGUgY2xpY2tlZCBpdGVtXHJcbiAgICAgICAgICAgICAgICBzZWxlY3RlZExpc3RJdGVtID0gbGlzdEl0ZW07XHJcbiAgICAgICAgICAgICAgICBzZWxlY3RJdGVtKGxpc3RJdGVtKTtcclxuICAgICAgICAgICAgICAgIC8vIEZpcmUgdGhlIGV2ZW50XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5vbkl0ZW1TZWxlY3RlZEV2ZW50KGl0ZW0ua2V5LCBmYWxzZSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAvLyBTZWxlY3QgZGVmYXVsdCBpdGVtXHJcbiAgICAgICAgICAgIGlmIChzZWxlY3RlZExpc3RJdGVtKSB7XHJcbiAgICAgICAgICAgICAgICBzZWxlY3RJdGVtKHNlbGVjdGVkTGlzdEl0ZW0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXNfMS5saXN0RWxlbWVudC5hcHBlbmQobGlzdEl0ZW0pO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIHRoaXNfMSA9IHRoaXM7XHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMuaXRlbXM7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgIHZhciBpdGVtID0gX2FbX2ldO1xyXG4gICAgICAgICAgICBfbG9vcF8xKGl0ZW0pO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBJdGVtU2VsZWN0aW9uTGlzdC5wcm90b3R5cGUub25JdGVtQWRkZWRFdmVudCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUub25JdGVtQWRkZWRFdmVudC5jYWxsKHRoaXMsIHZhbHVlKTtcclxuICAgICAgICB0aGlzLnVwZGF0ZURvbUl0ZW1zKHRoaXMuc2VsZWN0ZWRJdGVtKTtcclxuICAgIH07XHJcbiAgICBJdGVtU2VsZWN0aW9uTGlzdC5wcm90b3R5cGUub25JdGVtUmVtb3ZlZEV2ZW50ID0gZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5vbkl0ZW1SZW1vdmVkRXZlbnQuY2FsbCh0aGlzLCB2YWx1ZSk7XHJcbiAgICAgICAgdGhpcy51cGRhdGVEb21JdGVtcyh0aGlzLnNlbGVjdGVkSXRlbSk7XHJcbiAgICB9O1xyXG4gICAgSXRlbVNlbGVjdGlvbkxpc3QucHJvdG90eXBlLm9uSXRlbVNlbGVjdGVkRXZlbnQgPSBmdW5jdGlvbiAodmFsdWUsIHVwZGF0ZURvbUl0ZW1zKSB7XHJcbiAgICAgICAgaWYgKHVwZGF0ZURvbUl0ZW1zID09PSB2b2lkIDApIHsgdXBkYXRlRG9tSXRlbXMgPSB0cnVlOyB9XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5vbkl0ZW1TZWxlY3RlZEV2ZW50LmNhbGwodGhpcywgdmFsdWUpO1xyXG4gICAgICAgIGlmICh1cGRhdGVEb21JdGVtcykge1xyXG4gICAgICAgICAgICB0aGlzLnVwZGF0ZURvbUl0ZW1zKHZhbHVlKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIEl0ZW1TZWxlY3Rpb25MaXN0O1xyXG59KGxpc3RzZWxlY3Rvcl8xLkxpc3RTZWxlY3RvcikpO1xyXG5JdGVtU2VsZWN0aW9uTGlzdC5DTEFTU19TRUxFQ1RFRCA9ICdzZWxlY3RlZCc7XHJcbmV4cG9ydHMuSXRlbVNlbGVjdGlvbkxpc3QgPSBJdGVtU2VsZWN0aW9uTGlzdDtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2l0ZW1zZWxlY3Rpb25saXN0LnRzXG4vLyBtb2R1bGUgaWQgPSA0MlxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGJ1dHRvbl8xID0gcmVxdWlyZShcIi4vYnV0dG9uXCIpO1xyXG4vKipcclxuICogQSBjbGljayBvdmVybGF5IHRoYXQgb3BlbnMgYW4gdXJsIGluIGEgbmV3IHRhYiBpZiBjbGlja2VkLlxyXG4gKi9cclxudmFyIENsaWNrT3ZlcmxheSA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoQ2xpY2tPdmVybGF5LCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gQ2xpY2tPdmVybGF5KGNvbmZpZykge1xyXG4gICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1jbGlja292ZXJsYXknLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgQ2xpY2tPdmVybGF5LnByb3RvdHlwZS5pbml0aWFsaXplID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuaW5pdGlhbGl6ZS5jYWxsKHRoaXMpO1xyXG4gICAgICAgIHRoaXMuc2V0VXJsKHRoaXMuY29uZmlnLnVybCk7XHJcbiAgICAgICAgdmFyIGVsZW1lbnQgPSB0aGlzLmdldERvbUVsZW1lbnQoKTtcclxuICAgICAgICBlbGVtZW50Lm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKGVsZW1lbnQuZGF0YSgndXJsJykpIHtcclxuICAgICAgICAgICAgICAgIHdpbmRvdy5vcGVuKGVsZW1lbnQuZGF0YSgndXJsJyksICdfYmxhbmsnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogR2V0cyB0aGUgVVJMIHRoYXQgc2hvdWxkIGJlIGZvbGxvd2VkIHdoZW4gdGhlIHdhdGVybWFyayBpcyBjbGlja2VkLlxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gdGhlIHdhdGVybWFyayBVUkxcclxuICAgICAqL1xyXG4gICAgQ2xpY2tPdmVybGF5LnByb3RvdHlwZS5nZXRVcmwgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0RG9tRWxlbWVudCgpLmRhdGEoJ3VybCcpO1xyXG4gICAgfTtcclxuICAgIENsaWNrT3ZlcmxheS5wcm90b3R5cGUuc2V0VXJsID0gZnVuY3Rpb24gKHVybCkge1xyXG4gICAgICAgIGlmICh1cmwgPT09IHVuZGVmaW5lZCB8fCB1cmwgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICB1cmwgPSAnJztcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5nZXREb21FbGVtZW50KCkuZGF0YSgndXJsJywgdXJsKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gQ2xpY2tPdmVybGF5O1xyXG59KGJ1dHRvbl8xLkJ1dHRvbikpO1xyXG5leHBvcnRzLkNsaWNrT3ZlcmxheSA9IENsaWNrT3ZlcmxheTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2NsaWNrb3ZlcmxheS50c1xuLy8gbW9kdWxlIGlkID0gNDNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBidXR0b25fMSA9IHJlcXVpcmUoXCIuL2J1dHRvblwiKTtcclxudmFyIGRvbV8xID0gcmVxdWlyZShcIi4uL2RvbVwiKTtcclxuLyoqXHJcbiAqIEEgYnV0dG9uIHRvIHBsYXkvcmVwbGF5IGEgdmlkZW8uXHJcbiAqL1xyXG52YXIgSHVnZVJlcGxheUJ1dHRvbiA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoSHVnZVJlcGxheUJ1dHRvbiwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIEh1Z2VSZXBsYXlCdXR0b24oY29uZmlnKSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLWh1Z2VyZXBsYXlidXR0b24nLFxyXG4gICAgICAgICAgICB0ZXh0OiAnUmVwbGF5JyxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIEh1Z2VSZXBsYXlCdXR0b24ucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY29uZmlndXJlLmNhbGwodGhpcywgcGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIHRoaXMub25DbGljay5zdWJzY3JpYmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBwbGF5ZXIucGxheSgndWknKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBIdWdlUmVwbGF5QnV0dG9uLnByb3RvdHlwZS50b0RvbUVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGJ1dHRvbkVsZW1lbnQgPSBfc3VwZXIucHJvdG90eXBlLnRvRG9tRWxlbWVudC5jYWxsKHRoaXMpO1xyXG4gICAgICAgIC8vIEFkZCBjaGlsZCB0aGF0IGNvbnRhaW5zIHRoZSBwbGF5IGJ1dHRvbiBpbWFnZVxyXG4gICAgICAgIC8vIFNldHRpbmcgdGhlIGltYWdlIGRpcmVjdGx5IG9uIHRoZSBidXR0b24gZG9lcyBub3Qgd29yayB0b2dldGhlciB3aXRoIHNjYWxpbmcgYW5pbWF0aW9ucywgYmVjYXVzZSB0aGUgYnV0dG9uXHJcbiAgICAgICAgLy8gY2FuIGNvdmVyIHRoZSB3aG9sZSB2aWRlbyBwbGF5ZXIgYXJlIGFuZCBzY2FsaW5nIHdvdWxkIGV4dGVuZCBpdCBiZXlvbmQuIEJ5IGFkZGluZyBhbiBpbm5lciBlbGVtZW50LCBjb25maW5lZFxyXG4gICAgICAgIC8vIHRvIHRoZSBzaXplIGlmIHRoZSBpbWFnZSwgaXQgY2FuIHNjYWxlIGluc2lkZSB0aGUgcGxheWVyIHdpdGhvdXQgb3ZlcnNob290aW5nLlxyXG4gICAgICAgIGJ1dHRvbkVsZW1lbnQuYXBwZW5kKG5ldyBkb21fMS5ET00oJ2RpdicsIHtcclxuICAgICAgICAgICAgJ2NsYXNzJzogdGhpcy5wcmVmaXhDc3MoJ2ltYWdlJyksXHJcbiAgICAgICAgfSkpO1xyXG4gICAgICAgIHJldHVybiBidXR0b25FbGVtZW50O1xyXG4gICAgfTtcclxuICAgIHJldHVybiBIdWdlUmVwbGF5QnV0dG9uO1xyXG59KGJ1dHRvbl8xLkJ1dHRvbikpO1xyXG5leHBvcnRzLkh1Z2VSZXBsYXlCdXR0b24gPSBIdWdlUmVwbGF5QnV0dG9uO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvaHVnZXJlcGxheWJ1dHRvbi50c1xuLy8gbW9kdWxlIGlkID0gNDRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBidXR0b25fMSA9IHJlcXVpcmUoXCIuL2J1dHRvblwiKTtcclxuLyoqXHJcbiAqIEEgYnV0dG9uIHRoYXQgY2xvc2VzIChoaWRlcykgYSBjb25maWd1cmVkIGNvbXBvbmVudC5cclxuICovXHJcbnZhciBDbG9zZUJ1dHRvbiA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoQ2xvc2VCdXR0b24sIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBDbG9zZUJ1dHRvbihjb25maWcpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktY2xvc2VidXR0b24nLFxyXG4gICAgICAgICAgICB0ZXh0OiAnQ2xvc2UnLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgQ2xvc2VCdXR0b24ucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY29uZmlndXJlLmNhbGwodGhpcywgcGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIHZhciBjb25maWcgPSB0aGlzLmdldENvbmZpZygpO1xyXG4gICAgICAgIHRoaXMub25DbGljay5zdWJzY3JpYmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjb25maWcudGFyZ2V0LmhpZGUoKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gQ2xvc2VCdXR0b247XHJcbn0oYnV0dG9uXzEuQnV0dG9uKSk7XHJcbmV4cG9ydHMuQ2xvc2VCdXR0b24gPSBDbG9zZUJ1dHRvbjtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2Nsb3NlYnV0dG9uLnRzXG4vLyBtb2R1bGUgaWQgPSA0NVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgU3RvcmFnZVV0aWxzO1xyXG4oZnVuY3Rpb24gKFN0b3JhZ2VVdGlscykge1xyXG4gICAgdmFyIGhhc0xvY2FsU3RvcmFnZUNhY2hlO1xyXG4gICAgZnVuY3Rpb24gaGFzTG9jYWxTdG9yYWdlKCkge1xyXG4gICAgICAgIGlmIChoYXNMb2NhbFN0b3JhZ2VDYWNoZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gaGFzTG9jYWxTdG9yYWdlQ2FjaGU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIGhhc0xvY2FsU3RvcmFnZSBpcyB1c2VkIHRvIHNhZmVseSBlbnN1cmUgd2UgY2FuIHVzZSBsb2NhbFN0b3JhZ2VcclxuICAgICAgICAvLyB0YWtlbiBmcm9tIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9XZWJfU3RvcmFnZV9BUEkvVXNpbmdfdGhlX1dlYl9TdG9yYWdlX0FQSSNGZWF0dXJlLWRldGVjdGluZ19sb2NhbFN0b3JhZ2VcclxuICAgICAgICB2YXIgc3RvcmFnZSA9IHdpbmRvd1snbG9jYWxTdG9yYWdlJ107XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgdmFyIHggPSAnX19zdG9yYWdlX3Rlc3RfXyc7XHJcbiAgICAgICAgICAgIHN0b3JhZ2Uuc2V0SXRlbSh4LCB4KTtcclxuICAgICAgICAgICAgc3RvcmFnZS5yZW1vdmVJdGVtKHgpO1xyXG4gICAgICAgICAgICBoYXNMb2NhbFN0b3JhZ2VDYWNoZSA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIGhhc0xvY2FsU3RvcmFnZUNhY2hlID0gZSBpbnN0YW5jZW9mIERPTUV4Y2VwdGlvbiAmJiAoXHJcbiAgICAgICAgICAgIC8vIGV2ZXJ5dGhpbmcgZXhjZXB0IEZpcmVmb3hcclxuICAgICAgICAgICAgZS5jb2RlID09PSAyMiB8fFxyXG4gICAgICAgICAgICAgICAgLy8gRmlyZWZveFxyXG4gICAgICAgICAgICAgICAgZS5jb2RlID09PSAxMDE0IHx8XHJcbiAgICAgICAgICAgICAgICAvLyB0ZXN0IG5hbWUgZmllbGQgdG9vLCBiZWNhdXNlIGNvZGUgbWlnaHQgbm90IGJlIHByZXNlbnRcclxuICAgICAgICAgICAgICAgIC8vIGV2ZXJ5dGhpbmcgZXhjZXB0IEZpcmVmb3hcclxuICAgICAgICAgICAgICAgIGUubmFtZSA9PT0gJ1F1b3RhRXhjZWVkZWRFcnJvcicgfHxcclxuICAgICAgICAgICAgICAgIC8vIEZpcmVmb3hcclxuICAgICAgICAgICAgICAgIGUubmFtZSA9PT0gJ05TX0VSUk9SX0RPTV9RVU9UQV9SRUFDSEVEJykgJiZcclxuICAgICAgICAgICAgICAgIC8vIGFja25vd2xlZGdlIFF1b3RhRXhjZWVkZWRFcnJvciBvbmx5IGlmIHRoZXJlJ3Mgc29tZXRoaW5nIGFscmVhZHkgc3RvcmVkXHJcbiAgICAgICAgICAgICAgICBzdG9yYWdlLmxlbmd0aCAhPT0gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGhhc0xvY2FsU3RvcmFnZUNhY2hlO1xyXG4gICAgfVxyXG4gICAgU3RvcmFnZVV0aWxzLmhhc0xvY2FsU3RvcmFnZSA9IGhhc0xvY2FsU3RvcmFnZTtcclxuICAgIC8qKlxyXG4gICAgICogU3RvcmVzIGEgc3RyaW5nIGl0ZW0gaW50byBsb2NhbFN0b3JhZ2UuXHJcbiAgICAgKiBAcGFyYW0ga2V5IHRoZSBpdGVtJ3Mga2V5XHJcbiAgICAgKiBAcGFyYW0gZGF0YSB0aGUgaXRlbSdzIGRhdGFcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gc2V0SXRlbShrZXksIGRhdGEpIHtcclxuICAgICAgICBpZiAoU3RvcmFnZVV0aWxzLmhhc0xvY2FsU3RvcmFnZSgpKSB7XHJcbiAgICAgICAgICAgIHdpbmRvdy5sb2NhbFN0b3JhZ2Uuc2V0SXRlbShrZXksIGRhdGEpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIFN0b3JhZ2VVdGlscy5zZXRJdGVtID0gc2V0SXRlbTtcclxuICAgIC8qKlxyXG4gICAgICogR2V0cyBhbiBpdGVtJ3Mgc3RyaW5nIHZhbHVlIGZyb20gdGhlIGxvY2FsU3RvcmFnZS5cclxuICAgICAqIEBwYXJhbSBrZXkgdGhlIGtleSB0byBsb29rIHVwIGl0cyBhc3NvY2lhdGVkIHZhbHVlXHJcbiAgICAgKiBAcmV0dXJuIHtzdHJpbmcgfCBudWxsfSBSZXR1cm5zIHRoZSBzdHJpbmcgaWYgZm91bmQsIG51bGwgaWYgdGhlcmUgaXMgbm8gZGF0YSBzdG9yZWQgZm9yIHRoZSBrZXlcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gZ2V0SXRlbShrZXkpIHtcclxuICAgICAgICBpZiAoU3RvcmFnZVV0aWxzLmhhc0xvY2FsU3RvcmFnZSgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB3aW5kb3cubG9jYWxTdG9yYWdlLmdldEl0ZW0oa2V5KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIFN0b3JhZ2VVdGlscy5nZXRJdGVtID0gZ2V0SXRlbTtcclxuICAgIC8qKlxyXG4gICAgICogU3RvcmVzIGFuIG9iamVjdCBpbnRvIGxvY2FsU3RvcmFnZS4gVGhlIG9iamVjdCB3aWxsIGJlIHNlcmlhbGl6ZWQgdG8gSlNPTi4gVGhlIGZvbGxvd2luZyB0eXBlcyBhcmUgc3VwcG9ydGVkXHJcbiAgICAgKiBpbiBhZGRpdGlvbiB0byB0aGUgZGVmYXVsdCB0eXBlczpcclxuICAgICAqICAtIENvbG9yVXRpbHMuQ29sb3JcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkgdG8gc3RvcmUgdGhlIGRhdGEgdG9cclxuICAgICAqIEBwYXJhbSBkYXRhIHRoZSBvYmplY3QgdG8gc3RvcmVcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gc2V0T2JqZWN0KGtleSwgZGF0YSkge1xyXG4gICAgICAgIGlmIChTdG9yYWdlVXRpbHMuaGFzTG9jYWxTdG9yYWdlKCkpIHtcclxuICAgICAgICAgICAgdmFyIGpzb24gPSBKU09OLnN0cmluZ2lmeShkYXRhKTtcclxuICAgICAgICAgICAgc2V0SXRlbShrZXksIGpzb24pO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIFN0b3JhZ2VVdGlscy5zZXRPYmplY3QgPSBzZXRPYmplY3Q7XHJcbiAgICAvKipcclxuICAgICAqIEdldHMgYW4gb2JqZWN0IGZvciB0aGUgZ2l2ZW4ga2V5IGZyb20gbG9jYWxTdG9yYWdlLiBUaGUgb2JqZWN0IHdpbGwgYmUgZGVzZXJpYWxpemVkIGZyb20gSlNPTi4gQmVzaWRlIHRoZVxyXG4gICAgICogZGVmYXVsdCB0eXBlcywgdGhlIGZvbGxvd2luZyB0eXBlcyBhcmUgc3VwcG9ydGVkOlxyXG4gICAgICogIC0gQ29sb3JVdGlscy5Db2xvclxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBrZXkgdGhlIGtleSB0byBsb29rIHVwIGl0cyBhc3NvY2lhdGVkIG9iamVjdFxyXG4gICAgICogQHJldHVybiB7YW55fSBSZXR1cm5zIHRoZSBvYmplY3QgaWYgZm91bmQsIG51bGwgb3RoZXJ3aXNlXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGdldE9iamVjdChrZXkpIHtcclxuICAgICAgICBpZiAoU3RvcmFnZVV0aWxzLmhhc0xvY2FsU3RvcmFnZSgpKSB7XHJcbiAgICAgICAgICAgIHZhciBqc29uID0gZ2V0SXRlbShrZXkpO1xyXG4gICAgICAgICAgICBpZiAoa2V5KSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgb2JqZWN0ID0gSlNPTi5wYXJzZShqc29uKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBvYmplY3Q7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICB9XHJcbiAgICBTdG9yYWdlVXRpbHMuZ2V0T2JqZWN0ID0gZ2V0T2JqZWN0O1xyXG59KShTdG9yYWdlVXRpbHMgPSBleHBvcnRzLlN0b3JhZ2VVdGlscyB8fCAoZXhwb3J0cy5TdG9yYWdlVXRpbHMgPSB7fSkpO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL3N0b3JhZ2V1dGlscy50c1xuLy8gbW9kdWxlIGlkID0gNDZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiLyohIEhpdmUgU3RhdHMgUGFjayBidWlsZCAzLjIuMCBDb3B5cmlnaHQoYykgMjAxNSBIaXZlU3RyZWFtaW5nIEFCLCBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICogQXV0aG9yczogbWlrYWVsLmhvZ3F2aXN0QGhpdmVzdHJlYW1pbmcuY29tIC0gcmljY2FyZG8ucmVhbGVAaGl2ZXN0cmVhbWluZy5jb20gLSByb2JlcnRvLnJvdmVyc29AaGl2ZXN0cmVhbWluZy5jb20gKi9cbi8qISBBdGF0dXNKcyAtIHYyLjMuMTIgLSAyMDE2LTA3LTAzXG4gKiBDb3B5cmlnaHQgKGMpIDIwMTYgQXRhdHVzICovXG4hZnVuY3Rpb24oYSl7ZnVuY3Rpb24gYihhLGIpe3JldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSxiKX1mdW5jdGlvbiBjKGEpe3JldHVyblwidW5kZWZpbmVkXCI9PXR5cGVvZiBhfWlmKGEpe3ZhciBkPXt9LGU9YS5UcmFjZUtpdCxmPVtdLnNsaWNlLGc9XCI/XCI7ZC5ub0NvbmZsaWN0PWZ1bmN0aW9uKCl7cmV0dXJuIGEuVHJhY2VLaXQ9ZSxkfSxkLndyYXA9ZnVuY3Rpb24oYSl7ZnVuY3Rpb24gYigpe3RyeXtyZXR1cm4gYS5hcHBseSh0aGlzLGFyZ3VtZW50cyl9Y2F0Y2goYil7dGhyb3cgZC5yZXBvcnQoYiksYn19cmV0dXJuIGJ9LGQucmVwb3J0PWZ1bmN0aW9uKCl7ZnVuY3Rpb24gYyhhKXtpKCksbS5wdXNoKGEpfWZ1bmN0aW9uIGUoYSl7Zm9yKHZhciBiPW0ubGVuZ3RoLTE7Yj49MDstLWIpbVtiXT09PWEmJm0uc3BsaWNlKGIsMSl9ZnVuY3Rpb24gZyhhLGMpe3ZhciBlPW51bGw7aWYoIWN8fGQuY29sbGVjdFdpbmRvd0Vycm9ycyl7Zm9yKHZhciBnIGluIG0paWYoYihtLGcpKXRyeXttW2ddLmFwcGx5KG51bGwsW2FdLmNvbmNhdChmLmNhbGwoYXJndW1lbnRzLDIpKSl9Y2F0Y2goaCl7ZT1ofWlmKGUpdGhyb3cgZX19ZnVuY3Rpb24gaChhLGIsYyxlLGYpe3ZhciBoPW51bGw7aWYoZiloPWQuY29tcHV0ZVN0YWNrVHJhY2UoZik7ZWxzZSBpZihvKWQuY29tcHV0ZVN0YWNrVHJhY2UuYXVnbWVudFN0YWNrVHJhY2VXaXRoSW5pdGlhbEVsZW1lbnQobyxiLGMsYSksaD1vLG89bnVsbCxuPW51bGw7ZWxzZXt2YXIgaT17dXJsOmIsbGluZTpjLGNvbHVtbjplfTtpLmZ1bmM9ZC5jb21wdXRlU3RhY2tUcmFjZS5ndWVzc0Z1bmN0aW9uTmFtZShpLnVybCxpLmxpbmUpLGkuY29udGV4dD1kLmNvbXB1dGVTdGFja1RyYWNlLmdhdGhlckNvbnRleHQoaS51cmwsaS5saW5lKSxoPXttb2RlOlwib25lcnJvclwiLG1lc3NhZ2U6YSx1cmw6ZG9jdW1lbnQubG9jYXRpb24uaHJlZixzdGFjazpbaV0sdXNlcmFnZW50Om5hdmlnYXRvci51c2VyQWdlbnR9fXJldHVybiBnKGgsXCJmcm9tIHdpbmRvdy5vbmVycm9yXCIpLGs/ay5hcHBseSh0aGlzLGFyZ3VtZW50cyk6ITF9ZnVuY3Rpb24gaSgpe2whPT0hMCYmKGs9YS5vbmVycm9yLGEub25lcnJvcj1oLGw9ITApfWZ1bmN0aW9uIGooYil7dmFyIGM9Zi5jYWxsKGFyZ3VtZW50cywxKTtpZihvKXtpZihuPT09YilyZXR1cm47dmFyIGU9bztvPW51bGwsbj1udWxsLGcuYXBwbHkobnVsbCxbZSxudWxsXS5jb25jYXQoYykpfXZhciBoPWQuY29tcHV0ZVN0YWNrVHJhY2UoYik7dGhyb3cgbz1oLG49YixhLnNldFRpbWVvdXQoZnVuY3Rpb24oKXtuPT09YiYmKG89bnVsbCxuPW51bGwsZy5hcHBseShudWxsLFtoLG51bGxdLmNvbmNhdChjKSkpfSxoLmluY29tcGxldGU/MmUzOjApLGJ9dmFyIGssbCxtPVtdLG49bnVsbCxvPW51bGw7cmV0dXJuIGouc3Vic2NyaWJlPWMsai51bnN1YnNjcmliZT1lLGp9KCksZC5jb21wdXRlU3RhY2tUcmFjZT1mdW5jdGlvbigpe2Z1bmN0aW9uIGUoYil7aWYoIWQucmVtb3RlRmV0Y2hpbmcpcmV0dXJuXCJcIjt0cnl7dmFyIGM9ZnVuY3Rpb24oKXt0cnl7cmV0dXJuIG5ldyBhLlhNTEh0dHBSZXF1ZXN0fWNhdGNoKGIpe3JldHVybiBuZXcgYS5BY3RpdmVYT2JqZWN0KFwiTWljcm9zb2Z0LlhNTEhUVFBcIil9fSxlPWMoKTtyZXR1cm4gZS5vcGVuKFwiR0VUXCIsYiwhMSksZS5zZW5kKFwiXCIpLGUucmVzcG9uc2VUZXh0fWNhdGNoKGYpe3JldHVyblwiXCJ9fWZ1bmN0aW9uIGYoYSl7aWYoXCJzdHJpbmdcIiE9dHlwZW9mIGEpcmV0dXJuW107aWYoIWIodyxhKSl7dmFyIGM9XCJcIixkPVwiXCI7dHJ5e2Q9ZG9jdW1lbnQuZG9tYWlufWNhdGNoKGYpe30tMSE9PWEuaW5kZXhPZihkKSYmKGM9ZShhKSksd1thXT1jP2Muc3BsaXQoXCJcXG5cIik6W119cmV0dXJuIHdbYV19ZnVuY3Rpb24gaChhLGIpe3ZhciBkLGU9L2Z1bmN0aW9uIChbXihdKilcXCgoW14pXSopXFwpLyxoPS9bJ1wiXT8oWzAtOUEtWmEteiRfXSspWydcIl0/XFxzKls6PV1cXHMqKGZ1bmN0aW9ufGV2YWx8bmV3IEZ1bmN0aW9uKS8saT1cIlwiLGo9MTAsaz1mKGEpO2lmKCFrLmxlbmd0aClyZXR1cm4gZztmb3IodmFyIGw9MDtqPmw7KytsKWlmKGk9a1tiLWxdK2ksIWMoaSkpe2lmKGQ9aC5leGVjKGkpKXJldHVybiBkWzFdO2lmKGQ9ZS5leGVjKGkpKXJldHVybiBkWzFdfXJldHVybiBnfWZ1bmN0aW9uIGkoYSxiKXt2YXIgZT1mKGEpO2lmKCFlLmxlbmd0aClyZXR1cm4gbnVsbDt2YXIgZz1bXSxoPU1hdGguZmxvb3IoZC5saW5lc09mQ29udGV4dC8yKSxpPWgrZC5saW5lc09mQ29udGV4dCUyLGo9TWF0aC5tYXgoMCxiLWgtMSksaz1NYXRoLm1pbihlLmxlbmd0aCxiK2ktMSk7Yi09MTtmb3IodmFyIGw9ajtrPmw7KytsKWMoZVtsXSl8fGcucHVzaChlW2xdKTtyZXR1cm4gZy5sZW5ndGg+MD9nOm51bGx9ZnVuY3Rpb24gaihhKXtyZXR1cm4gYS5yZXBsYWNlKC9bXFwtXFxbXFxde30oKSorPy4sXFxcXFxcXiR8I10vZyxcIlxcXFwkJlwiKX1mdW5jdGlvbiBrKGEpe3JldHVybiBqKGEpLnJlcGxhY2UoXCI8XCIsXCIoPzo8fCZsdDspXCIpLnJlcGxhY2UoXCI+XCIsXCIoPzo+fCZndDspXCIpLnJlcGxhY2UoXCImXCIsXCIoPzomfCZhbXA7KVwiKS5yZXBsYWNlKCdcIicsJyg/OlwifCZxdW90OyknKS5yZXBsYWNlKC9cXHMrL2csXCJcXFxccytcIil9ZnVuY3Rpb24gbChhLGIpe2Zvcih2YXIgYyxkLGU9MCxnPWIubGVuZ3RoO2c+ZTsrK2UpaWYoKGM9ZihiW2VdKSkubGVuZ3RoJiYoYz1jLmpvaW4oXCJcXG5cIiksZD1hLmV4ZWMoYykpKXJldHVybnt1cmw6YltlXSxsaW5lOmMuc3Vic3RyaW5nKDAsZC5pbmRleCkuc3BsaXQoXCJcXG5cIikubGVuZ3RoLGNvbHVtbjpkLmluZGV4LWMubGFzdEluZGV4T2YoXCJcXG5cIixkLmluZGV4KS0xfTtyZXR1cm4gbnVsbH1mdW5jdGlvbiBtKGEsYixjKXt2YXIgZCxlPWYoYiksZz1uZXcgUmVnRXhwKFwiXFxcXGJcIitqKGEpK1wiXFxcXGJcIik7cmV0dXJuIGMtPTEsZSYmZS5sZW5ndGg+YyYmKGQ9Zy5leGVjKGVbY10pKT9kLmluZGV4Om51bGx9ZnVuY3Rpb24gbihiKXtmb3IodmFyIGMsZCxlLGYsZz1bYS5sb2NhdGlvbi5ocmVmXSxoPWRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwic2NyaXB0XCIpLGk9XCJcIitiLG09L15mdW5jdGlvbig/OlxccysoW1xcdyRdKykpP1xccypcXCgoW1xcd1xccyxdKilcXClcXHMqXFx7XFxzKihcXFNbXFxzXFxTXSpcXFMpXFxzKlxcfVxccyokLyxuPS9eZnVuY3Rpb24gb24oW1xcdyRdKylcXHMqXFwoZXZlbnRcXClcXHMqXFx7XFxzKihcXFNbXFxzXFxTXSpcXFMpXFxzKlxcfVxccyokLyxvPTA7bzxoLmxlbmd0aDsrK28pe3ZhciBwPWhbb107cC5zcmMmJmcucHVzaChwLnNyYyl9aWYoZT1tLmV4ZWMoaSkpe3ZhciBxPWVbMV0/XCJcXFxccytcIitlWzFdOlwiXCIscj1lWzJdLnNwbGl0KFwiLFwiKS5qb2luKFwiXFxcXHMqLFxcXFxzKlwiKTtjPWooZVszXSkucmVwbGFjZSgvOyQvLFwiOz9cIiksZD1uZXcgUmVnRXhwKFwiZnVuY3Rpb25cIitxK1wiXFxcXHMqXFxcXChcXFxccypcIityK1wiXFxcXHMqXFxcXClcXFxccyp7XFxcXHMqXCIrYytcIlxcXFxzKn1cIil9ZWxzZSBkPW5ldyBSZWdFeHAoaihpKS5yZXBsYWNlKC9cXHMrL2csXCJcXFxccytcIikpO2lmKGY9bChkLGcpKXJldHVybiBmO2lmKGU9bi5leGVjKGkpKXt2YXIgcz1lWzFdO2lmKGM9ayhlWzJdKSxkPW5ldyBSZWdFeHAoXCJvblwiK3MrXCI9W1xcXFwnXFxcIl1cXFxccypcIitjK1wiXFxcXHMqW1xcXFwnXFxcIl1cIixcImlcIiksZj1sKGQsZ1swXSkpcmV0dXJuIGY7aWYoZD1uZXcgUmVnRXhwKGMpLGY9bChkLGcpKXJldHVybiBmfXJldHVybiBudWxsfWZ1bmN0aW9uIG8oYSl7aWYoIWEuc3RhY2spcmV0dXJuIG51bGw7Zm9yKHZhciBiLGQsZT0vXlxccyphdCAoLio/KSA/XFwoPygoPzpmaWxlfGh0dHBzP3xjaHJvbWUtZXh0ZW5zaW9uKTouKj8pOihcXGQrKSg/OjooXFxkKykpP1xcKT9cXHMqJC9pLGY9L15cXHMqKC4qPykoPzpcXCgoLio/KVxcKSk/QD8oKD86ZmlsZXxodHRwcz98Y2hyb21lKTouKj8pOihcXGQrKSg/OjooXFxkKykpP1xccyokL2ksaj0vXlxccyphdCAoPzooKD86XFxbb2JqZWN0IG9iamVjdFxcXSk/LispICk/XFwoPygoPzptcy1hcHB4fGh0dHB8aHR0cHMpOi4qPyk6KFxcZCspKD86OihcXGQrKSk/XFwpP1xccyokL2ksaz1hLnN0YWNrLnNwbGl0KFwiXFxuXCIpLGw9W10sbj0vXiguKikgaXMgdW5kZWZpbmVkJC8uZXhlYyhhLm1lc3NhZ2UpLG89MCxwPWsubGVuZ3RoO3A+bzsrK28pe2lmKGI9Zi5leGVjKGtbb10pKWQ9e3VybDpiWzNdLGZ1bmM6YlsxXXx8ZyxhcmdzOmJbMl0/YlsyXS5zcGxpdChcIixcIik6XCJcIixsaW5lOitiWzRdLGNvbHVtbjpiWzVdPytiWzVdOm51bGx9O2Vsc2UgaWYoYj1lLmV4ZWMoa1tvXSkpZD17dXJsOmJbMl0sZnVuYzpiWzFdfHxnLGxpbmU6K2JbM10sY29sdW1uOmJbNF0/K2JbNF06bnVsbH07ZWxzZXtpZighKGI9ai5leGVjKGtbb10pKSljb250aW51ZTtkPXt1cmw6YlsyXSxmdW5jOmJbMV18fGcsbGluZTorYlszXSxjb2x1bW46Yls0XT8rYls0XTpudWxsfX0hZC5mdW5jJiZkLmxpbmUmJihkLmZ1bmM9aChkLnVybCxkLmxpbmUpKSxkLmxpbmUmJihkLmNvbnRleHQ9aShkLnVybCxkLmxpbmUpKSxsLnB1c2goZCl9cmV0dXJuIGwubGVuZ3RoPyhsWzBdJiZsWzBdLmxpbmUmJiFsWzBdLmNvbHVtbiYmbj9sWzBdLmNvbHVtbj1tKG5bMV0sbFswXS51cmwsbFswXS5saW5lKTpsWzBdLmNvbHVtbnx8YyhhLmNvbHVtbk51bWJlcil8fChsWzBdLmNvbHVtbj1hLmNvbHVtbk51bWJlcisxKSx7bW9kZTpcInN0YWNrXCIsbmFtZTphLm5hbWUsbWVzc2FnZTphLm1lc3NhZ2UsdXJsOmRvY3VtZW50LmxvY2F0aW9uLmhyZWYsc3RhY2s6bCx1c2VyYWdlbnQ6bmF2aWdhdG9yLnVzZXJBZ2VudH0pOm51bGx9ZnVuY3Rpb24gcChhKXtmb3IodmFyIGIsYz1hLnN0YWNrdHJhY2UsZD0vIGxpbmUgKFxcZCspLCBjb2x1bW4gKFxcZCspIGluICg/Ojxhbm9ueW1vdXMgZnVuY3Rpb246IChbXj5dKyk+fChbXlxcKV0rKSlcXCgoLiopXFwpIGluICguKik6XFxzKiQvaSxlPWMuc3BsaXQoXCJcXG5cIiksZj1bXSxnPTAsaj1lLmxlbmd0aDtqPmc7Zys9MilpZihiPWQuZXhlYyhlW2ddKSl7dmFyIGs9e2xpbmU6K2JbMV0sY29sdW1uOitiWzJdLGZ1bmM6YlszXXx8Yls0XSxhcmdzOmJbNV0/Yls1XS5zcGxpdChcIixcIik6W10sdXJsOmJbNl19O2lmKCFrLmZ1bmMmJmsubGluZSYmKGsuZnVuYz1oKGsudXJsLGsubGluZSkpLGsubGluZSl0cnl7ay5jb250ZXh0PWkoay51cmwsay5saW5lKX1jYXRjaChsKXt9ay5jb250ZXh0fHwoay5jb250ZXh0PVtlW2crMV1dKSxmLnB1c2goayl9cmV0dXJuIGYubGVuZ3RoP3ttb2RlOlwic3RhY2t0cmFjZVwiLG5hbWU6YS5uYW1lLG1lc3NhZ2U6YS5tZXNzYWdlLHVybDpkb2N1bWVudC5sb2NhdGlvbi5ocmVmLHN0YWNrOmYsdXNlcmFnZW50Om5hdmlnYXRvci51c2VyQWdlbnR9Om51bGx9ZnVuY3Rpb24gcShjKXt2YXIgZD1jLm1lc3NhZ2Uuc3BsaXQoXCJcXG5cIik7aWYoZC5sZW5ndGg8NClyZXR1cm4gbnVsbDt2YXIgZSxnLGosbSxuPS9eXFxzKkxpbmUgKFxcZCspIG9mIGxpbmtlZCBzY3JpcHQgKCg/OmZpbGV8aHR0cHM/KVxcUyspKD86OiBpbiBmdW5jdGlvbiAoXFxTKykpP1xccyokL2ksbz0vXlxccypMaW5lIChcXGQrKSBvZiBpbmxpbmUjKFxcZCspIHNjcmlwdCBpbiAoKD86ZmlsZXxodHRwcz8pXFxTKykoPzo6IGluIGZ1bmN0aW9uIChcXFMrKSk/XFxzKiQvaSxwPS9eXFxzKkxpbmUgKFxcZCspIG9mIGZ1bmN0aW9uIHNjcmlwdFxccyokL2kscT1bXSxyPWRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwic2NyaXB0XCIpLHM9W107Zm9yKGcgaW4gciliKHIsZykmJiFyW2ddLnNyYyYmcy5wdXNoKHJbZ10pO2ZvcihnPTIsaj1kLmxlbmd0aDtqPmc7Zys9Mil7dmFyIHQ9bnVsbDtpZihlPW4uZXhlYyhkW2ddKSl0PXt1cmw6ZVsyXSxmdW5jOmVbM10sbGluZTorZVsxXX07ZWxzZSBpZihlPW8uZXhlYyhkW2ddKSl7dD17dXJsOmVbM10sZnVuYzplWzRdfTt2YXIgdT0rZVsxXSx2PXNbZVsyXS0xXTtpZih2JiYobT1mKHQudXJsKSkpe209bS5qb2luKFwiXFxuXCIpO3ZhciB3PW0uaW5kZXhPZih2LmlubmVyVGV4dCk7dz49MCYmKHQubGluZT11K20uc3Vic3RyaW5nKDAsdykuc3BsaXQoXCJcXG5cIikubGVuZ3RoKX19ZWxzZSBpZihlPXAuZXhlYyhkW2ddKSl7dmFyIHg9YS5sb2NhdGlvbi5ocmVmLnJlcGxhY2UoLyMuKiQvLFwiXCIpLHk9ZVsxXSx6PW5ldyBSZWdFeHAoayhkW2crMV0pKTttPWwoeixbeF0pLHQ9e3VybDp4LGxpbmU6bT9tLmxpbmU6eSxmdW5jOlwiXCJ9fWlmKHQpe3QuZnVuY3x8KHQuZnVuYz1oKHQudXJsLHQubGluZSkpO3ZhciBBPWkodC51cmwsdC5saW5lKSxCPUE/QVtNYXRoLmZsb29yKEEubGVuZ3RoLzIpXTpudWxsO3QuY29udGV4dD1BJiZCLnJlcGxhY2UoL15cXHMqLyxcIlwiKT09PWRbZysxXS5yZXBsYWNlKC9eXFxzKi8sXCJcIik/QTpbZFtnKzFdXSxxLnB1c2godCl9fXJldHVybiBxLmxlbmd0aD97bW9kZTpcIm11bHRpbGluZVwiLG5hbWU6Yy5uYW1lLG1lc3NhZ2U6ZFswXSx1cmw6ZG9jdW1lbnQubG9jYXRpb24uaHJlZixzdGFjazpxLHVzZXJhZ2VudDpuYXZpZ2F0b3IudXNlckFnZW50fTpudWxsfWZ1bmN0aW9uIHIoYSxiLGMsZCl7dmFyIGU9e3VybDpiLGxpbmU6Y307aWYoZS51cmwmJmUubGluZSl7YS5pbmNvbXBsZXRlPSExLGUuZnVuY3x8KGUuZnVuYz1oKGUudXJsLGUubGluZSkpLGUuY29udGV4dHx8KGUuY29udGV4dD1pKGUudXJsLGUubGluZSkpO3ZhciBmPS8gJyhbXiddKyknIC8uZXhlYyhkKTtpZihmJiYoZS5jb2x1bW49bShmWzFdLGUudXJsLGUubGluZSkpLGEuc3RhY2subGVuZ3RoPjAmJmEuc3RhY2tbMF0udXJsPT09ZS51cmwpe2lmKGEuc3RhY2tbMF0ubGluZT09PWUubGluZSlyZXR1cm4hMTtpZighYS5zdGFja1swXS5saW5lJiZhLnN0YWNrWzBdLmZ1bmM9PT1lLmZ1bmMpcmV0dXJuIGEuc3RhY2tbMF0ubGluZT1lLmxpbmUsYS5zdGFja1swXS5jb250ZXh0PWUuY29udGV4dCwhMX1yZXR1cm4gYS5zdGFjay51bnNoaWZ0KGUpLGEucGFydGlhbD0hMCwhMH1yZXR1cm4gYS5pbmNvbXBsZXRlPSEwLCExfWZ1bmN0aW9uIHMoYSxiKXtmb3IodmFyIGMsZSxmLGk9L2Z1bmN0aW9uXFxzKyhbXyRhLXpBLVpcXHhBMC1cXHVGRkZGXVtfJGEtekEtWjAtOVxceEEwLVxcdUZGRkZdKik/XFxzKlxcKC9pLGo9W10saz17fSxsPSExLG89cy5jYWxsZXI7byYmIWw7bz1vLmNhbGxlcilpZihvIT09dCYmbyE9PWQucmVwb3J0KXtpZihlPXt1cmw6bnVsbCxmdW5jOmcsbGluZTpudWxsLGNvbHVtbjpudWxsfSxvLm5hbWU/ZS5mdW5jPW8ubmFtZTooYz1pLmV4ZWMoby50b1N0cmluZygpKSkmJihlLmZ1bmM9Y1sxXSksXCJ1bmRlZmluZWRcIj09dHlwZW9mIGUuZnVuYyl0cnl7ZS5mdW5jPWMuaW5wdXQuc3Vic3RyaW5nKDAsYy5pbnB1dC5pbmRleE9mKFwie1wiKSl9Y2F0Y2gocCl7fWlmKGY9bihvKSl7ZS51cmw9Zi51cmwsZS5saW5lPWYubGluZSxlLmZ1bmM9PT1nJiYoZS5mdW5jPWgoZS51cmwsZS5saW5lKSk7dmFyIHE9LyAnKFteJ10rKScgLy5leGVjKGEubWVzc2FnZXx8YS5kZXNjcmlwdGlvbik7cSYmKGUuY29sdW1uPW0ocVsxXSxmLnVybCxmLmxpbmUpKX1rW1wiXCIrb10/bD0hMDprW1wiXCIrb109ITAsai5wdXNoKGUpfWImJmouc3BsaWNlKDAsYik7dmFyIHU9e21vZGU6XCJjYWxsZXJzXCIsbmFtZTphLm5hbWUsbWVzc2FnZTphLm1lc3NhZ2UsdXJsOmRvY3VtZW50LmxvY2F0aW9uLmhyZWYsc3RhY2s6aix1c2VyYWdlbnQ6bmF2aWdhdG9yLnVzZXJBZ2VudH07cmV0dXJuIHIodSxhLnNvdXJjZVVSTHx8YS5maWxlTmFtZSxhLmxpbmV8fGEubGluZU51bWJlcixhLm1lc3NhZ2V8fGEuZGVzY3JpcHRpb24pLHV9ZnVuY3Rpb24gdChhLGIpe3ZhciBjPW51bGw7Yj1udWxsPT1iPzA6K2I7dHJ5e2lmKGM9cChhKSlyZXR1cm4gY31jYXRjaChkKXtpZih2KXRocm93IGR9dHJ5e2lmKGM9byhhKSlyZXR1cm4gY31jYXRjaChkKXtpZih2KXRocm93IGR9dHJ5e2lmKGM9cShhKSlyZXR1cm4gY31jYXRjaChkKXtpZih2KXRocm93IGR9dHJ5e2lmKGM9cyhhLGIrMSkpcmV0dXJuIGN9Y2F0Y2goZCl7aWYodil0aHJvdyBkfXJldHVybnttb2RlOlwiZmFpbGVkXCJ9fWZ1bmN0aW9uIHUoYSl7YT0obnVsbD09YT8wOithKSsxO3RyeXt0aHJvdyBuZXcgRXJyb3J9Y2F0Y2goYil7cmV0dXJuIHQoYixhKzEpfX12YXIgdj0hMSx3PXt9O3JldHVybiB0LmF1Z21lbnRTdGFja1RyYWNlV2l0aEluaXRpYWxFbGVtZW50PXIsdC5ndWVzc0Z1bmN0aW9uTmFtZT1oLHQuZ2F0aGVyQ29udGV4dD1pLHQub2ZDYWxsZXI9dSx0LmdldFNvdXJjZT1mLHR9KCksZC5leHRlbmRUb0FzeW5jaHJvbm91c0NhbGxiYWNrcz1mdW5jdGlvbigpe3ZhciBiPWZ1bmN0aW9uKGIpe3ZhciBjPWFbYl07YVtiXT1mdW5jdGlvbigpe3ZhciBhPWYuY2FsbChhcmd1bWVudHMpLGI9YVswXTtyZXR1cm5cImZ1bmN0aW9uXCI9PXR5cGVvZiBiJiYoYVswXT1kLndyYXAoYikpLGMuYXBwbHk/Yy5hcHBseSh0aGlzLGEpOmMoYVswXSxhWzFdKX19O2IoXCJzZXRUaW1lb3V0XCIpLGIoXCJzZXRJbnRlcnZhbFwiKX0sZC5yZW1vdGVGZXRjaGluZ3x8KGQucmVtb3RlRmV0Y2hpbmc9ITApLGQuY29sbGVjdFdpbmRvd0Vycm9yc3x8KGQuY29sbGVjdFdpbmRvd0Vycm9ycz0hMCksKCFkLmxpbmVzT2ZDb250ZXh0fHxkLmxpbmVzT2ZDb250ZXh0PDEpJiYoZC5saW5lc09mQ29udGV4dD0xMSksYS5UcmFjZUtpdD1kfX0oXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvdz93aW5kb3c6Z2xvYmFsKSxmdW5jdGlvbihhLGIpe1widXNlIHN0cmljdFwiO2lmKGEpe3ZhciBjPWEuZXZlbnQuYWRkO2EuZXZlbnQuYWRkPWZ1bmN0aW9uKGQsZSxmLGcsaCl7aWYoXCJmdW5jdGlvblwiIT10eXBlb2YgZiYmXCJmdW5jdGlvblwiIT10eXBlb2YgZi5oYW5kbGVyKXJldHVybiBjLmNhbGwodGhpcyxkLGUsZixnLGgpO3ZhciBpO3JldHVybiBmLmhhbmRsZXI/KGk9Zi5oYW5kbGVyLGYuaGFuZGxlcj1iLndyYXAoZi5oYW5kbGVyKSk6KGk9ZixmPWIud3JhcChmKSksZi5ndWlkPWkuZ3VpZD9pLmd1aWQ6aS5ndWlkPWEuZ3VpZCsrLGMuY2FsbCh0aGlzLGQsZSxmLGcsaCl9O3ZhciBkPWEuZm4ucmVhZHk7YS5mbi5yZWFkeT1mdW5jdGlvbihhKXtyZXR1cm4gZC5jYWxsKHRoaXMsYi53cmFwKGEpKX07dmFyIGU9YS5hamF4O2EuYWpheD1mdW5jdGlvbihjLGQpe1wib2JqZWN0XCI9PXR5cGVvZiBjJiYoZD1jLGM9dm9pZCAwKSxkPWR8fHt9O2Zvcih2YXIgZixnPVtcImNvbXBsZXRlXCIsXCJlcnJvclwiLFwic3VjY2Vzc1wiXTtmPWcucG9wKCk7KWEuaXNGdW5jdGlvbihkW2ZdKSYmKGRbZl09Yi53cmFwKGRbZl0pKTt0cnl7cmV0dXJuIGM/ZS5jYWxsKHRoaXMsYyxkKTplLmNhbGwodGhpcyxkKX1jYXRjaChoKXt0aHJvdyBiLnJlcG9ydChoKSxofX19fSh3aW5kb3cualF1ZXJ5LHdpbmRvdy5UcmFjZUtpdCksZnVuY3Rpb24oYSxiLGMsZCl7ZnVuY3Rpb24gZShhKXt2YXIgYj1hLGM9YS5zcGxpdChcIi8vXCIpWzFdO2lmKGMpe3ZhciBkPWMuaW5kZXhPZihcIj9cIiksZT1jLnRvU3RyaW5nKCkuc3Vic3RyaW5nKDAsZCksZj1lLnNwbGl0KFwiL1wiKS5zbGljZSgwLDQpLmpvaW4oXCIvXCIpLGc9ZS5zdWJzdHJpbmcoMCw0OCk7Yj1mLmxlbmd0aDxnLmxlbmd0aD9mOmcsYiE9PWUmJihiKz1cIi4uXCIpfXJldHVybiBifWZ1bmN0aW9uIGYoYSxiLGMsZil7aWYoSyYmKEx8fGIuZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCkpKXt2YXIgZz1cIkFKQVggRXJyb3I6IFwiKyhiLnN0YXR1c1RleHR8fFwidW5rbm93blwiKStcIiBcIisoYy50eXBlfHxcInVua25vd25cIikrXCIgXCIrKGUoYy51cmwpfHxcInVua25vd25cIik7Vi5zZW5kKGZ8fGEudHlwZSx7c3RhdHVzOmIuc3RhdHVzLHN0YXR1c1RleHQ6Yi5zdGF0dXNUZXh0LHR5cGU6Yy50eXBlLHVybDpjLnVybCxhamF4RXJyb3JNZXNzYWdlOmcsY29udGVudFR5cGU6Yy5jb250ZW50VHlwZSxyZXF1ZXN0RGF0YTpjLmRhdGEmJmMuZGF0YS5zbGljZT9jLmRhdGEuc2xpY2UoMCwxMDI0MCk6ZCxyZXNwb25zZURhdGE6Yi5yZXNwb25zZVRleHQmJmIucmVzcG9uc2VUZXh0LnNsaWNlP2IucmVzcG9uc2VUZXh0LnNsaWNlKDAsMTAyNDApOmQsYWN0aXZlVGFyZ2V0OmEudGFyZ2V0JiZhLnRhcmdldC5hY3RpdmVFbGVtZW50P2EudGFyZ2V0LmFjdGl2ZUVsZW1lbnQub3V0ZXJIVE1MOmR9KX19ZnVuY3Rpb24gZygpe3JldHVybiBvJiZcIlwiIT09bz8hMDooUi5sb2coXCJBdGF0dXMgQVBJIGtleSBoYXMgbm90IGJlZW4gY29uZmlndXJlZCwgbWFrZSBzdXJlIHlvdSBjYWxsIGF0YXR1cy5jb25maWcoeW91ckFwaUtleSlcIiksITEpfWZ1bmN0aW9uIGgoKXt2YXIgYz1iLmRvY3VtZW50RWxlbWVudCxkPWIuZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCJib2R5XCIpWzBdLGU9YS5pbm5lcldpZHRofHxjLmNsaWVudFdpZHRofHxkLmNsaWVudFdpZHRoLGY9YS5pbm5lckhlaWdodHx8Yy5jbGllbnRIZWlnaHR8fGQuY2xpZW50SGVpZ2h0O3JldHVybnt3aWR0aDplLGhlaWdodDpmfX1mdW5jdGlvbiBpKGEpe3ZhciBiPShuZXcgRGF0ZSkudG9KU09OKCk7dHJ5e3ZhciBjPVwiYXRhdHVzanM9XCIrYitcIj1cIitSLmdldFJhbmRvbUludCgpO1widW5kZWZpbmVkXCI9PXR5cGVvZiBsb2NhbFN0b3JhZ2VbY10mJihsb2NhbFN0b3JhZ2VbY109YSl9Y2F0Y2goZCl7Ui5sb2coXCJBdGF0dXM6IExvY2FsU3RvcmFnZSBmdWxsLCBjYW5ub3Qgc2F2ZSBleGNlcHRpb25cIil9fWZ1bmN0aW9uIGooKXt0cnl7cmV0dXJuXCJsb2NhbFN0b3JhZ2VcImluIGEmJm51bGwhPT1hLmxvY2FsU3RvcmFnZX1jYXRjaChiKXtyZXR1cm4hMX19ZnVuY3Rpb24gaygpe2lmKGooKSYmbG9jYWxTdG9yYWdlLmxlbmd0aD4wKWZvcih2YXIgYSBpbiBsb2NhbFN0b3JhZ2UpaWYoXCJhdGF0dXNqcz1cIj09PWEuc3Vic3RyaW5nKDAsOSkpe3RyeXt2YXIgYj1KU09OLnBhcnNlKGxvY2FsU3RvcmFnZVthXSk7XCJhcGlrZXlcImluIGImJm0oTixiKX1jYXRjaChjKXtSLmxvZyhcIkF0YXR1czogSW52YWxpZCBKU09OIG9iamVjdCBpbiBMb2NhbFN0b3JhZ2VcIil9bG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oYSl9fWZ1bmN0aW9uIGwoYSxjKXtpZihjPWN8fHt9LCFhLnN0YWNrfHwhYS5zdGFjay5sZW5ndGgpcmV0dXJuIHZvaWQgUi5sb2coXCJBdGF0dXM6IENhbmNlbGluZyBzZW5kIGR1ZSB0byBubyBzdGFja3RyYWNlLlwiKTtSLmlzRW1wdHkoYy5jdXN0b21EYXRhKSYmKGMuY3VzdG9tRGF0YT1cImZ1bmN0aW9uXCI9PXR5cGVvZiBwP3AoKTpwKSxSLmlzRW1wdHkoYy50YWdzKSYmKGMudGFncz1FKTt2YXIgZD1jLmN1c3RvbURhdGEmJmMuY3VzdG9tRGF0YS5hamF4RXJyb3JNZXNzYWdlfHxhLm1lc3NhZ2U7aWYoZCYmMD09PWQuaW5kZXhPZihcIlVuY2F1Z2h0IFwiKSYmKGQ9YS5tZXNzYWdlLnN1YnN0cmluZyg5KSksZD1kfHxjLnN0YXR1c3x8XCJTY3JpcHQgZXJyb3IuXCIsdyYmdy50ZXN0KGQpKXJldHVybiB2b2lkIFIubG9nKFwiQXRhdHVzOiBjYW5jZWxpbmcgc2VuZCBkdWUgdG8gaWdub3JlIGVycm9yc1wiKTt2YXIgZT1bXTthLnN0YWNrJiZhLnN0YWNrLmxlbmd0aCYmUi5mb3JFYWNoKGEuc3RhY2ssZnVuY3Rpb24oYSxiKXtSLmVuZHNXaXRoKGIudXJsLFwiL2F0YXR1cy5qc1wiKXx8ZS5wdXNoKHtsbjpiLmxpbmV8fDAsY246Yi5jb2x1bW58fDAsZjpiLnVybHx8XCJhbm9ueW1vdXNcIixtOmIuZnVuY3x8XCJbYW5vbnltb3VzXVwifSl9KTt2YXIgZj1bYS5uYW1lLGQsSlNPTi5zdHJpbmdpZnkoZSldLmpvaW4oXCJ8XCIpO2lmKGY9PT14KXJldHVybiB2b2lkIFIubG9nKFwiQXRhdHVzOiBjYW5jZWxpbmcgc2VuZCBkdWUgdG8gZHVwbGljYXRlIGVycm9yc1wiKTt4PWY7dmFyIGc9Yy5jdXN0b21EYXRhO3RyeXtKU09OLnN0cmluZ2lmeShnKX1jYXRjaChoKXt2YXIgaT1cIkNhbm5vdCBhZGQgY3VzdG9tIGRhdGE7IG1heSBjb250YWluIGNpcmN1bGFyIHJlZmVyZW5jZVwiO2c9e2Vycm9yOml9LFIubG9nKFwiQXRhdHVzOiBcIitpKX12YXIgaj1VLmdldEFsbEV2ZW50cygpO1MuY2xlYXIoKTt2YXIgaz17XCJjbGFzc1wiOmEubmFtZSxuYW1lOmQsYmFja1RyYWNlczplLHVzZXJBY3Rpb25zOmosbmV0Om51bGwsY3VzdG9tRGF0YTpnfHxudWxsLHRhZ3M6Yy50YWdzLHNvdXJjZW1hcDpKLHJlcXVlc3Q6e3VybDpiLmxvY2F0aW9uLmhyZWYsdWE6bmF2aWdhdG9yLnVzZXJBZ2VudH19O2lmKFwiZnVuY3Rpb25cIj09dHlwZW9mIHkmJihrLmdyb3VwaW5nS2V5PXkoaykpLFwiZnVuY3Rpb25cIj09dHlwZW9mIHope3ZhciBsPXooayk7bCYmbShOLGspfWVsc2UgbShOLGspfWZ1bmN0aW9uIG0oYyxkKXtpZihHJiZHLmxlbmd0aCYmLTE9PT1HLmluZGV4T2YobG9jYXRpb24uaG9zdCkpcmV0dXJuIHZvaWQgUi5sb2coXCJBdGF0dXM6IGNhbmNlbGluZyBzZW5kIGR1ZSB0byBub3QgYSBhbGxvd2VkIGRvbWFpblwiKTtpZihnKCkpe2lmKCFkLnRzKXt2YXIgZT1hLnNjcmVlbnx8aCgpO2QudHM9KG5ldyBEYXRlKS5nZXRUaW1lKCksZC5hcGlrZXk9byxkLnJlcXVlc3Q9ZC5yZXF1ZXN0fHx7fSxkLnJlcXVlc3QudXJsPWQucmVxdWVzdC51cmx8fGIubG9jYXRpb24uaHJlZixkLnJlcXVlc3QudWE9ZC5yZXF1ZXN0LnVhfHxuYXZpZ2F0b3IudXNlckFnZW50LGQucmVxdWVzdC53PWUud2lkdGgsZC5yZXF1ZXN0Lmg9ZS5oZWlnaHQsZC52PXJ8fFwiXCIsZC5fdj1CfHxcIlwifXEmJihkLmNpZD1xLnVzZXJJZHx8bnVsbCksUi5sb2coXCJTZW5kaW5nIGRhdGEgdG8gQXRhdHVzIFJlY2VpdmVyOlwiLGQpLG4oYyxKU09OLnN0cmluZ2lmeShkKSl9fWZ1bmN0aW9uIG4oYSxiKXt2YXIgYz1uZXcgSW1hZ2UsZD1NK2ErXCI/ZGF0YT1cIitlbmNvZGVVUklDb21wb25lbnQoYik7Yy5jcm9zc09yaWdpbj1cImFub255bW91c1wiLGMub25sb2FkPWZ1bmN0aW9uKCl7aygpfSxjLm9uZXJyb3I9Yy5vbmFib3J0PWZ1bmN0aW9uKCl7SSYmYT09PU4mJmkoYil9LGMuc3JjPWR9dmFyIG8scCxxLHIscyx0LHUsdix3LHgseSx6LEEsQj1cIjIuMy4xMlwiLEM9VHJhY2VLaXQubm9Db25mbGljdCgpLEQ9YS5hdGF0dXMsRT1bXSxGPSExLEc9W10sSD0hMSxJPSExLEo9ITEsSz0hMSxMPSExLE09XCJodHRwczovL2JyLXJ4LmF0YXR1cy5jb21cIixOPVwiL3RyYWNrL2Jyb3dzZXIvZXJyb3JzXCIsTz1cIi90cmFjay9icm93c2VyL3BlcmZcIixQPVwiL3RyYWNrL2Jyb3dzZXIvcGVyZi9hamF4XCIsUT1cIi90cmFjay9icm93c2VyL3BlcmYvdHhuXCI7YyYmKEE9YyhiKSk7dmFyIFI9e2lzQm9vbGVhbjpmdW5jdGlvbihhKXtyZXR1cm5cInVuZGVmaW5lZFwiIT10eXBlb2YgYSYmXCJib29sZWFuXCI9PXR5cGVvZiBhfSxpc1N0cmluZzpmdW5jdGlvbihhKXtyZXR1cm5cInN0cmluZ1wiPT10eXBlb2YgYX0saXNBcnJheTpmdW5jdGlvbihhKXtyZXR1cm5cIltvYmplY3QgQXJyYXldXCI9PT1PYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYSl9LGVuZHNXaXRoOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGEmJmI/LTEhPT1hLmluZGV4T2YoYixhLmxlbmd0aC1iLmxlbmd0aCk6ITF9LGpvaW5SZWdFeHA6ZnVuY3Rpb24oYSl7Zm9yKHZhciBiLGM9W10sZD0wLGU9YS5sZW5ndGg7ZT5kO2QrKyliPWFbZF0sUi5pc1N0cmluZyhiKT9jLnB1c2goYi5yZXBsYWNlKC8oWy4qKz9cXF49IToke30oKXxcXFtcXF1cXC9cXFxcXSkvZyxcIlxcXFwkMVwiKSk6YiYmYi5zb3VyY2UmJmMucHVzaChiLnNvdXJjZSk7cmV0dXJuIG5ldyBSZWdFeHAoYy5qb2luKFwifFwiKSxcImlcIil9LGdldFRhcmdldFVybDpmdW5jdGlvbihiKXtyZXR1cm4gYS5YRG9tYWluUmVxdWVzdCYmSCYmKGI9Yi5zbGljZSg2KSksYn0sbm93OmZ1bmN0aW9uKCl7cmV0dXJuKG5ldyBEYXRlKS5nZXRUaW1lKCl9LHBhZDpmdW5jdGlvbihhKXtyZXR1cm4gYT1TdHJpbmcoYSksMT09PWEubGVuZ3RoJiYoYT1cIjBcIithKSxhfSxtZXJnZTpmdW5jdGlvbihhLGIpe3ZhciBjLGQ9e307Zm9yKGMgaW4gYSlkW2NdPWFbY107Zm9yKGMgaW4gYilkW2NdPWJbY107cmV0dXJuIGR9LG1lcmdlQXJyYXk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbnVsbCE9Yj9hLmNvbmNhdChiKTphfSxmb3JFYWNoOmZ1bmN0aW9uKGEsYil7Zm9yKHZhciBjPTA7YzxhLmxlbmd0aDtjKyspYi5jYWxsKG51bGwsYyxhW2NdKX0saXNFbXB0eTpmdW5jdGlvbihhKXtmb3IodmFyIGIgaW4gYSlpZihhLmhhc093blByb3BlcnR5KGIpKXJldHVybiExO3JldHVybiEwfSxnZXRSYW5kb21JbnQ6ZnVuY3Rpb24oKXtyZXR1cm4gTWF0aC5mbG9vcig5MDA3MTk5MjU0NzQwOTkyKk1hdGgucmFuZG9tKCkpfSxsb2c6ZnVuY3Rpb24oYixjKXtGJiZhLmNvbnNvbGUmJmEuY29uc29sZS5sb2cmJihhLmNvbnNvbGUubG9nKGIpLGMmJmEuY29uc29sZS5sb2coYykpfSxiaW5kOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGEuYXBwbHkoYixBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKX19LGNhbkFsbG93SW5zZWN1cmVTdWJtaXNzaW9uczpmdW5jdGlvbigpe3ZhciBiPWEubmF2aWdhdG9yLnVzZXJBZ2VudCxjPWIubWF0Y2goL1RyaWRlbnRcXC8oW1xcZC5dKykvKSxkPWMmJlwiNy4wXCI9PT1jWzFdPzExOihiPWIubWF0Y2goL01TSUUgKFtcXGQuXSspLykpP3BhcnNlSW50KGJbMV0sMTApOiExO3JldHVybiBkJiY5Pj1kfSx1dWlkNDpmdW5jdGlvbigpe3JldHVyblwieHh4eHh4eHh4eHh4NHh4eHl4eHh4eHh4eHh4eHh4eHhcIi5yZXBsYWNlKC9beHldL2csZnVuY3Rpb24oYSl7dmFyIGI9MTYqTWF0aC5yYW5kb20oKXwwLGM9XCJ4XCI9PT1hP2I6MyZifDg7cmV0dXJuIGMudG9TdHJpbmcoMTYpfSl9LGFkZEV2ZW50TGlzdGVuZXI6ZnVuY3Rpb24oYixjLGQpe3JldHVyblwidW5kZWZpbmVkXCIhPXR5cGVvZiBhLmF0dGFjaEV2ZW50P2EuYXR0YWNoRXZlbnQoXCJvblwiK2IsYyk6YS5hZGRFdmVudExpc3RlbmVyP2EuYWRkRXZlbnRMaXN0ZW5lcihiLGMsZCk6dm9pZCAwfSxhcnJheUZyb21PYmplY3Q6ZnVuY3Rpb24oYSl7dmFyIGI9W107Zm9yKHZhciBjIGluIGEpYS5oYXNPd25Qcm9wZXJ0eShjKSYmYi5wdXNoKGFbY10pO3JldHVybiBifX0sUz17ZXZlbnRPYmplY3Q6e30sYWxsOmZ1bmN0aW9uKGEpe2Zvcih2YXIgYj10aGlzLmdldEV2ZW50T2JqZWN0KGEpLGM9W10sZD0wO2Q8Yi5sZW5ndGg7ZCsrKWMucHVzaChiW2RdLnZhbHVlKTtyZXR1cm4gY30sY2xlYXI6ZnVuY3Rpb24oKXtmb3IodmFyIGEgaW4gdGhpcy5ldmVudE9iamVjdCl0aGlzLmV2ZW50T2JqZWN0Lmhhc093blByb3BlcnR5KGEpJiYodGhpcy5ldmVudE9iamVjdFthXS5sZW5ndGg9MCl9LGFkZDpmdW5jdGlvbihhLGIpe3ZhciBjPXRoaXMuZ2V0RXZlbnRPYmplY3QoYSksZD1SLnV1aWQ0KCk7cmV0dXJuIGMucHVzaCh7a2V5OmQsdmFsdWU6Yn0pLHRoaXMudHJ1bmNhdGVFdmVudE9iamVjdChhLDEwKSxkfSxnZXQ6ZnVuY3Rpb24oYSxiKXtmb3IodmFyIGM9dGhpcy5nZXRFdmVudE9iamVjdChhKSxkPTA7ZDxjLmxlbmd0aDtkKyspaWYoY1tkXS5rZXk9PT1iKXJldHVybiBjW2RdLnZhbHVlO3JldHVybiExfSxnZXRFdmVudE9iamVjdDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5ldmVudE9iamVjdFthXXx8KHRoaXMuZXZlbnRPYmplY3RbYV09W10pLHRoaXMuZXZlbnRPYmplY3RbYV19LHRydW5jYXRlRXZlbnRPYmplY3Q6ZnVuY3Rpb24oYSxiKXt2YXIgYz10aGlzLmdldEV2ZW50T2JqZWN0KGEpO2MubGVuZ3RoPmImJih0aGlzLmV2ZW50T2JqZWN0W2FdPWMuc2xpY2UoYy5sZW5ndGgtYikpfX0sVD17YXR0YWNoOmZ1bmN0aW9uKGIsYyxkLGUsZil7Yj1ifHxhLmNvbnNvbGV8fHt9O2Zvcih2YXIgZz1mfHxbXCJsb2dcIixcImRlYnVnXCIsXCJpbmZvXCIsXCJ3YXJuXCIsXCJlcnJvclwiXSxoPWcucG9wKCksaT1mdW5jdGlvbihhLGIsZCl7YyYmUy5hZGQoXCJ1c2VyXCIse3RzOlIubm93KCksYzpcImNvbnNvbGVcIixsOmEsbTpifSksXCJlcnJvclwiPT09YSYmZSYmVi5ub3RpZnkobmV3IEVycm9yKGIpLGQpfTtoOyl0aGlzLndyYXBDb25zb2xlTWV0aG9kKGIsaCxkLGkpLGg9Zy5wb3AoKX0sd3JhcENvbnNvbGVNZXRob2Q6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIGU9YVtiXSxmPWE7YiBpbiBhJiYoYVtiXT1mdW5jdGlvbigpe3ZhciBhPVtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKSxnPVwiXCIrYS5qb2luKFwiIFwiKSxoPXtsZXZlbDpiLGxvZ2dlcjpcImNvbnNvbGVcIn07ZCYmZChiLGcsaCksZSYmYyYmRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwoZSxmLGEpfSl9fSxVPXthdHRhY2g6ZnVuY3Rpb24oKXt2YXIgYT1SLmJpbmQodGhpcy5vbkRvY3VtZW50Q2xpY2tlZCx0aGlzKSxjPVIuYmluZCh0aGlzLm9uSW5wdXRDaGFuZ2VkLHRoaXMpO2IuYWRkRXZlbnRMaXN0ZW5lcj8oYi5hZGRFdmVudExpc3RlbmVyKFwiY2xpY2tcIixhLCEwKSxiLmFkZEV2ZW50TGlzdGVuZXIoXCJibHVyXCIsYywhMCkpOmIuYXR0YWNoRXZlbnQmJihiLmF0dGFjaEV2ZW50KFwib25jbGlja1wiLGEpLGIuYXR0YWNoRXZlbnQoXCJvbmZvY3Vzb3V0XCIsYykpfSx3cml0ZVVzZXJFdmVudDpmdW5jdGlvbihhLGIsYyxkKXtcInBhc3N3b3JkXCI9PT10aGlzLmdldEVsZW1lbnRUeXBlKGEpJiYoYz12b2lkIDApLFMuYWRkKFwidXNlclwiLHt0czpSLm5vdygpLGE6YixlOnRoaXMuZ2V0T3V0ZXJIVE1MKGEpLHY6dGhpcy5nZXRWYWx1ZUtpbmQoYyxkKX0pfSxvbkRvY3VtZW50Q2xpY2tlZDpmdW5jdGlvbihhKXt2YXIgYj10aGlzLmdldEVsZW1lbnRGcm9tRXZlbnQoYSk7YiYmYi50YWdOYW1lJiYodGhpcy5pc1RhcmdldChiLFwiYVwiKXx8dGhpcy5pc1RhcmdldChiLFwiYnV0dG9uXCIpfHx0aGlzLmlzVGFyZ2V0KGIsXCJpbnB1dFwiLFtcImJ1dHRvblwiLFwic3VibWl0XCJdKT90aGlzLndyaXRlVXNlckV2ZW50KGIsXCJjbGlja1wiKTp0aGlzLmlzVGFyZ2V0KGIsXCJpbnB1dFwiLFtcImNoZWNrYm94XCIsXCJyYWRpb1wiXSkmJnRoaXMud3JpdGVVc2VyRXZlbnQoYixcImNoZWNrXCIsYi52YWx1ZSxiLmNoZWNrZWQpKX0sb25JbnB1dENoYW5nZWQ6ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcy5nZXRFbGVtZW50RnJvbUV2ZW50KGEpO2ImJmIudGFnTmFtZSYmKHRoaXMuaXNUYXJnZXQoYixcInRleHRhcmVhXCIpP3RoaXMud3JpdGVVc2VyRXZlbnQoYixcImlucHV0XCIsYi52YWx1ZSk6dGhpcy5pc1RhcmdldChiLFwic2VsZWN0XCIpJiZiLm9wdGlvbnMmJmIub3B0aW9ucy5sZW5ndGg/dGhpcy5vblNlbGVjdElucHV0Q2hhbmdlZChiKTp0aGlzLmlzVGFyZ2V0KGIsXCJpbnB1dFwiKSYmIXRoaXMuaXNUYXJnZXQoYixcImlucHV0XCIsW1wiYnV0dG9uXCIsXCJzdWJtaXRcIixcImhpZGRlblwiLFwiY2hlY2tib3hcIixcInJhZGlvXCJdKSYmdGhpcy53cml0ZVVzZXJFdmVudChiLFwiaW5wdXRcIixiLnZhbHVlKSl9LG9uU2VsZWN0SW5wdXRDaGFuZ2VkOmZ1bmN0aW9uKGEpe2lmKGEubXVsdGlwbGUpe2Zvcih2YXIgYj0wO2I8YS5vcHRpb25zLmxlbmd0aDtiKyspaWYoYS5vcHRpb25zW2JdLnNlbGVjdGVkKXt0aGlzLndyaXRlVXNlckV2ZW50KGEsXCJzZWxlY3RcIixhLm9wdGlvbnNbYl0udmFsdWUpO2JyZWFrfX1lbHNlIDA8PWEuc2VsZWN0ZWRJbmRleCYmYS5vcHRpb25zW2Euc2VsZWN0ZWRJbmRleF0mJnRoaXMud3JpdGVVc2VyRXZlbnQoYSxcInNlbGVjdFwiLGEub3B0aW9uc1thLnNlbGVjdGVkSW5kZXhdLnZhbHVlKX0sZ2V0RWxlbWVudEZyb21FdmVudDpmdW5jdGlvbihhKXtyZXR1cm4gYS50YXJnZXR8fGIuZWxlbWVudEZyb21Qb2ludChhLmNsaWVudFgsYS5jbGllbnRZKX0saXNUYXJnZXQ6ZnVuY3Rpb24oYSxiLGMpe2lmKGEudGFnTmFtZS50b0xvd2VyQ2FzZSgpIT09Yi50b0xvd2VyQ2FzZSgpKXJldHVybiExO2lmKCFjKXJldHVybiEwO2Zvcih2YXIgZD10aGlzLmdldEVsZW1lbnRUeXBlKGEpLGU9MDtlPGMubGVuZ3RoO2UrKylpZihjW2VdPT09ZClyZXR1cm4hMDtyZXR1cm4hMX0sZ2V0RWxlbWVudFR5cGU6ZnVuY3Rpb24oYSl7cmV0dXJuKGEuZ2V0QXR0cmlidXRlKFwidHlwZVwiKXx8XCJcIikudG9Mb3dlckNhc2UoKX0sZ2V0T3V0ZXJIVE1MOmZ1bmN0aW9uKGEpe2Zvcih2YXIgYj1cIjxcIithLnRhZ05hbWUudG9Mb3dlckNhc2UoKSxjPWEuYXR0cmlidXRlcyxkPTAsZT1jLmxlbmd0aDtlPmQ7ZCsrKXt2YXIgZj1jW2RdLm5hbWU7XCJ2YWx1ZVwiIT09Zi50b0xvd2VyQ2FzZSgpJiYoYis9XCIgXCIrZisnPVwiJytjW2RdLnZhbHVlKydcIicpfXJldHVybiBiKz1cIiA+XCJ9LGdldFZhbHVlS2luZDpmdW5jdGlvbihhLGIpe3JldHVybiBudWxsPT1hP251bGw6e2xlbmd0aDphLmxlbmd0aCxjaGVja2VkOmIscGF0dGVybjp0aGlzLm1hdGNoSW5wdXRQYXR0ZXJuKGEpfX0sbWF0Y2hJbnB1dFBhdHRlcm46ZnVuY3Rpb24oYSl7cmV0dXJuXCJcIj09PWE/XCJlbXB0eVwiOi9eW2EtejAtOSEjJCUmJyorPT9cXF5fYHt8fX5cXC1dKyg/OlxcLlthLXowLTkhIyQlJicqKz0/XFxeX2B7fH1+XFwtXSspKkAoPzpbYS16MC05XSg/OlthLXowLTlcXC1dKlthLXowLTldKT9cXC4pK1thLXowLTldKD86W2EtejAtOVxcLV0qW2EtejAtOV0pPyQvLnRlc3QoYSk/XCJlbWFpbFwiOi9eKDA/WzEtOV18WzEyXVswLTldfDNbMDFdKVtcXC9cXC1dKDA/WzEtOV18MVswMTJdKVtcXC9cXC1dXFxkezR9JC8udGVzdChhKXx8L14oXFxkezR9W1xcL1xcLV0oMD9bMS05XXwxWzAxMl0pW1xcL1xcLV0wP1sxLTldfFsxMl1bMC05XXwzWzAxXSkkLy50ZXN0KGEpP1wiZGF0ZVwiOi9eKD86KD86XFwrPzFcXHMqKD86Wy5cXC1dXFxzKik/KT8oPzpcXChcXHMqKFsyLTldMVswMi05XXxbMi05XVswMi04XTF8WzItOV1bMDItOF1bMDItOV0pXFxzKlxcKXwoWzItOV0xWzAyLTldfFsyLTldWzAyLThdMXxbMi05XVswMi04XVswMi05XSkpXFxzKig/OlsuXFwtXVxccyopPyk/KFsyLTldMVswMi05XXxbMi05XVswMi05XTF8WzItOV1bMDItOV17Mn0pXFxzKig/OlsuXFwtXVxccyopPyhbMC05XXs0fSkoPzpcXHMqKD86I3x4XFwuP3xleHRcXC4/fGV4dGVuc2lvbilcXHMqKFxcZCspKT8kLy50ZXN0KGEpP1wicGhvbmVcIjovXlxccyokLy50ZXN0KGEpP1wid2hpdGVzcGFjZVwiOi9eXFxkKiQvLnRlc3QoYSk/XCJudW1lcmljXCI6XCJjaGFyYWN0ZXJcIn0sZ2V0QWxsRXZlbnRzOmZ1bmN0aW9uKCl7cmV0dXJuIFMuYWxsKFwidXNlclwiKX19LFY9e25vQ29uZmxpY3Q6ZnVuY3Rpb24oKXtyZXR1cm4gYS5hdGF0dXM9RCxWfSxpc0NvbmZpZ3VyZWQ6ZnVuY3Rpb24oKXtyZXR1cm4hIW99LGNvbmZpZzpmdW5jdGlvbihiLGMpe3JldHVybiBjPWN8fHt9LG89YixDLnJlbW90ZUZldGNoaW5nPSExLHc9W10sYyYmKHA9Yy5jdXN0b21EYXRhLEU9Yy50YWdzfHxbXSxKPSEoIWMuZW5hYmxlU291cmNlbWFwJiYhYy5zb3VyY2VtYXApLHM9ISFjLmRpc2FibGVVc2VyQWN0aW9ucyx0PSEhYy5kaXNhYmxlQWpheE1vbml0b3JpbmcsdT0hIWMuZGlzYWJsZVJVTSxGPSEhYy5kZWJ1Z01vZGUsYy5pZ25vcmVFcnJvcnMmJlIuaXNBcnJheShjLmlnbm9yZUVycm9ycykmJih3PWMuaWdub3JlRXJyb3JzKSxWLnNldEFsbG93ZWREb21haW5zKGMuYWxsb3dlZERvbWFpbnMpLFYuc2V0VmVyc2lvbihjLnZlcnNpb24pLFYuZW5hYmxlT2ZmbGluZShjLmVuYWJsZU9mZmxpbmV8fGMub2ZmbGluZSksVi5vbkJlZm9yZUVycm9yU2VuZChjLmJlZm9yZUVycm9yU2VuZCksVi5zZXRHcm91cGluZ0tleUNhbGxiYWNrKGMuZ3JvdXBpbmdLZXlDYWxsYmFjaykpLEg9Ui5jYW5BbGxvd0luc2VjdXJlU3VibWlzc2lvbnMoKSx3LnB1c2goL15TY3JpcHQgZXJyb3JcXC4/JC8pLHcucHVzaCgvXkphdmFzY3JpcHQgZXJyb3I6IFNjcmlwdCBlcnJvclxcLj8gb24gbGluZSAwJC8pLHc9Ui5qb2luUmVnRXhwKHcpLGsoKSx2PXtlbmFibGVkOiEwLHRpbWVsaW5lOiEwLGRpc3BsYXk6ITAsZXJyb3I6ITAsbGV2ZWxzOm51bGx9LFIuaXNCb29sZWFuKGMuY29uc29sZSkmJih2LmVuYWJsZWQ9Yy5jb25zb2xlKSxSLmlzQm9vbGVhbihjLmNvbnNvbGVUaW1lbGluZSkmJih2LnRpbWVsaW5lPWMuY29uc29sZVRpbWVsaW5lKSxSLmlzQm9vbGVhbihjLmNvbnNvbGVEaXNwbGF5KSYmKHYuZGlzcGxheT1jLmNvbnNvbGVEaXNwbGF5KSxSLmlzQm9vbGVhbihjLmNvbnNvbGVFcnJvck5vdGlmeSkmJih2LmVycm9yPWMuY29uc29sZUVycm9yTm90aWZ5KSxSLmlzQXJyYXkoYy5jb25zb2xlVGltZWxpbmVMZXZlbHMpJiYodi5sZXZlbHM9Yy5jb25zb2xlVGltZWxpbmVMZXZlbHMpLHYuZW5hYmxlZCYmXCJjb25zb2xlXCJpbiBhJiZhLmNvbnNvbGUubG9nJiZULmF0dGFjaChhLmNvbnNvbGUsdi50aW1lbGluZSx2LmRpc3BsYXksdi5lcnJvcix2LmxldmVscyksc3x8VS5hdHRhY2goKSx0fHx1fHxWLl9fYXR0YWNoQWpheEhvb2tzKCksVn0saW5zdGFsbDpmdW5jdGlvbigpe3JldHVybiBnKCk/KEMucmVwb3J0LnN1YnNjcmliZShsKSxDLmV4dGVuZFRvQXN5bmNocm9ub3VzQ2FsbGJhY2tzKCksQSYmSyYmQS5hamF4RXJyb3IoZiksVik6dm9pZCAwfSx1bmluc3RhbGw6ZnVuY3Rpb24oKXtyZXR1cm4gbz1udWxsLEMucmVwb3J0LnVuc3Vic2NyaWJlKGwpLEEmJksmJkEudW5iaW5kKFwiYWpheEVycm9yXCIsZiksVn0sc2V0Q3VzdG9tRGF0YTpmdW5jdGlvbihhKXtyZXR1cm4gcD1hLFZ9LHNldFRhZ3M6ZnVuY3Rpb24oYSl7cmV0dXJuIEU9YSxWfSxzZXRBbGxvd2VkRG9tYWluczpmdW5jdGlvbihhKXtyZXR1cm4gYSYmUi5pc0FycmF5KGEpJiYoRz1hKSxWfSxnZXRBbGxvd2VkRG9tYWluczpmdW5jdGlvbigpe3JldHVybiBHfSxzZXRVc2VyOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBxPXt9LGEmJihxLnVzZXJJZD1cIlwiK2EpLGImJihxLmVtYWlsPVwiXCIrYiksYyYmKHEuZmlyc3ROYW1lPVwiXCIrYyksZCYmKHEubGFzdE5hbWU9XCJcIitkKSxWfSxzZXRWZXJzaW9uOmZ1bmN0aW9uKGEpe3JldHVybiBhJiYocj1cIlwiK2EpLFZ9LGVuYWJsZU9mZmxpbmU6ZnVuY3Rpb24oYSl7cmV0dXJuIFIuaXNCb29sZWFuKGEpJiYoST1hKSxWfSxvbkJlZm9yZUVycm9yU2VuZDpmdW5jdGlvbihhKXtyZXR1cm5cImZ1bmN0aW9uXCI9PXR5cGVvZiBhJiYoej1hKSxWfSxzZXRHcm91cGluZ0tleUNhbGxiYWNrOmZ1bmN0aW9uKGEpe3JldHVyblwiZnVuY3Rpb25cIj09dHlwZW9mIGEmJih5PWEpLFZ9LHNldEFQSUVuZHBvaW50OmZ1bmN0aW9uKGEpe3JldHVybiBNPWEsVn0saW5pdDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIGMmJihiPWJ8fHt9LGIuY3VzdG9tRGF0YT1jKSxWLmNvbmZpZyhhLGIpfSx3aXRoQ3VzdG9tRGF0YTpmdW5jdGlvbihhKXtyZXR1cm4gVi5zZXRDdXN0b21EYXRhKGEpfSx3aXRoVGFnczpmdW5jdGlvbihhKXtyZXR1cm4gVi5zZXRUYWdzKGEpfSxhdHRhY2g6ZnVuY3Rpb24oKXtyZXR1cm4gVi5pbnN0YWxsKCl9LGRldGFjaDpmdW5jdGlvbigpe3JldHVybiBWLnVuaW5zdGFsbCgpfSxub3RpZnk6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBWLnNlbmQoYSxiLGMpfSxzZW5kUGVyZjpmdW5jdGlvbihhKXtyZXR1cm4gdT92b2lkIFIubG9nKFwiUlVNIGlzIGRpc2FibGVkLiBQbGVhc2UgZW5hYmxlIGl0IGluIHRoZSBjb25maWcgb3B0aW9ucy5cIik6bShPLGEpfSxzZW5kQWpheFBlcmY6ZnVuY3Rpb24oYSl7cmV0dXJuIHU/dm9pZCBSLmxvZyhcIlJVTSBpcyBkaXNhYmxlZC4gUGxlYXNlIGVuYWJsZSBpdCBpbiB0aGUgY29uZmlnIG9wdGlvbnMuXCIpOm0oUCxhKX0sc2VuZFR4blBlcmY6ZnVuY3Rpb24oYSl7cmV0dXJuIG0oUSxhKX0sc2VuZDpmdW5jdGlvbihhLGIsYyl7dHJ5e2woQy5jb21wdXRlU3RhY2tUcmFjZShhKSx7Y3VzdG9tRGF0YTpSLm1lcmdlKHAsYiksdGFnczpSLm1lcmdlQXJyYXkoRSxjKX0pfWNhdGNoKGQpe2lmKGEhPT1kKXRocm93IGR9cmV0dXJuIFZ9LF9oZWxwZXI6Un07YS5hdGF0dXM9Vn0od2luZG93LGRvY3VtZW50LHdpbmRvdy5qUXVlcnkpLGZ1bmN0aW9uKGEsYixjKXtmdW5jdGlvbiBkKGEpe2EucGw8PTB8fGF0YXR1cy5zZW5kUGVyZihhKX1mdW5jdGlvbiBlKCl7dmFyIGI9YS5wZXJmb3JtYW5jZXx8YS5tb3pQZXJmb3JtYW5jZXx8YS5tc1BlcmZvcm1hbmNlfHxhLndlYmtpdFBlcmZvcm1hbmNlLGM9Yi50aW1pbmcsZT1iLm5hdmlnYXRpb247aWYoMD09PWMubG9hZEV2ZW50RW5kKXJldHVybiExO2NsZWFySW50ZXJ2YWwoaSksaT1udWxsO3ZhciBmPWMubmF2aWdhdGlvblN0YXJ0OzA+PWYmJihmPWMuZmV0Y2hTdGFydCk7dmFyIGc9e307Zm9yKHZhciBoIGluIGopZ1tqW2hdXT0tMSxoIGluIGMmJihjW2hdPD0wfHwoZ1tqW2hdXT1jW2hdLWYpKTt2YXIgaz17bnR5OmUudHlwZSxyYzplLnJlZGlyZWN0Q291bnQsbnQ6Zy5ycHMtZy5ucyxkcDpnLmRjZS1nLnJwcyxwcjpnLmxlLWcuZGNlLGZlOmcubGUtZy5ycHMscGw6Zy5sZS1nLm5zfTtkKGspfWZ1bmN0aW9uIGYoKXtpZighaHx8IWguYkRvbmUpcmV0dXJuITE7Y2xlYXJJbnRlcnZhbChpKSxpPSExO3ZhciBhPWguZ2V0TWVhc3VyZXMoKTtpZihudWxsIT1hJiZudWxsIT1hLmJhY2tlbmQmJm51bGwhPWEuZnJvbnRlbmQmJm51bGwhPWFbXCJwYWdlIGxvYWQgdGltZVwiXSYmbnVsbCE9YVtcInRvdGFsIGxvYWQgdGltZVwiXSl7dmFyIGI9YS5iYWNrZW5kLGM9YS5iYWNrZW5kK2EuZnJvbnRlbmQsZT17bnR5OjAscmM6MCxudDpiLGRwOmMtYixwcjphW1widG90YWwgbG9hZCB0aW1lXCJdLWMsZmU6YVtcInRvdGFsIGxvYWQgdGltZVwiXS1iLHBsOmFbXCJ0b3RhbCBsb2FkIHRpbWVcIl19O2QoZSl9fXZhciBnPShuZXcgRGF0ZSkuZ2V0VGltZSgpLGg9aHx8e307aC5xPWgucXx8W10saC52ZXJzaW9uPVwiMC4zXCIsaC50YXJnZXRPcmlnaW49Yi5sb2NhdGlvbi5wcm90b2NvbCtcIi8vXCIrYi5sb2NhdGlvbi5ob3N0bmFtZSxoLmJQb3N0TWVzc2FnZT0hMSxoLmJlYWNvblVybD1oLmJlYWNvblVybHx8XCIvaW1hZ2VzL2JlYWNvbi5naWZcIixoLmF1dG9ydW49ITEsaC5pbml0PWZ1bmN0aW9uKCl7aWYoaC5iRG9uZT0hMSxoLmJVbmxvYWRlZD0hMSxoLm1hcmtzPXt9LGgubWVhc3VyZXM9e30saC5zdGFydHM9e30saC5maW5kU3RhcnRUaW1lKCksaC5hZGRFdmVudExpc3RlbmVyKFwiYmVmb3JldW5sb2FkXCIsaC5iZWZvcmVVbmxvYWQsITEpLGguYWRkRXZlbnRMaXN0ZW5lcihcInBhZ2VoaWRlXCIsaC5iZWZvcmVVbmxvYWQsITEpLGguYWRkRXZlbnRMaXN0ZW5lcihcInVubG9hZFwiLGguYmVmb3JlVW5sb2FkLCExKSxoLnByb2Nlc3NRKCksXCJjb21wbGV0ZVwiPT09Yi5yZWFkeVN0YXRlKXt2YXIgYz1hLnBlcmZvcm1hbmNlfHxhLm1velBlcmZvcm1hbmNlfHxhLm1zUGVyZm9ybWFuY2V8fGEud2Via2l0UGVyZm9ybWFuY2U7YyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGMudGltaW5nJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgYy50aW1pbmcubG9hZEV2ZW50RW5kJiYoaC5tYXJrKFwiZmlyc3RieXRlXCIsYy50aW1pbmcucmVzcG9uc2VTdGFydCksaC5tYXJrKFwib25sb2FkXCIsYy50aW1pbmcubG9hZEV2ZW50RW5kKSksaC5kb25lKCl9ZWxzZSBoLmFkZEV2ZW50TGlzdGVuZXIoXCJsb2FkXCIsaC5vbmxvYWQsITEpfSxoLnByb2Nlc3NRPWZ1bmN0aW9uKCl7Zm9yKHZhciBhPWgucS5sZW5ndGgsYj0wO2E+YjtiKyspe3ZhciBjPWgucVtiXSxkPWNbMF07XCJtYXJrXCI9PT1kP2gubWFyayhjWzFdLGNbMl0pOlwibWVhc3VyZVwiPT09ZD9oLm1lYXN1cmUoY1sxXSxjWzJdLGNbM10pOlwiZG9uZVwiPT09ZCYmaC5kb25lKGNbMV0pfX0saC5tYXJrPWZ1bmN0aW9uKGIsYyl7cmV0dXJuIGguZHByaW50KFwiUlVNX0VQSVNPREVTLm1hcms6IFwiK2IrXCIsIFwiK2MpLGI/KGgubWFya3NbYl09cGFyc2VJbnQoY3x8KG5ldyBEYXRlKS5nZXRUaW1lKCkpLGguYlBvc3RNZXNzYWdlJiZhLnBvc3RNZXNzYWdlKFwiUlVNX0VQSVNPREVTOm1hcms6XCIrYitcIjpcIitjLGgudGFyZ2V0T3JpZ2luKSx2b2lkKFwiZmlyc3RieXRlXCI9PT1iP2gubWVhc3VyZShcImJhY2tlbmRcIixcInN0YXJ0dGltZVwiLFwiZmlyc3RieXRlXCIpOlwib25sb2FkXCI9PT1iPyhoLm1lYXN1cmUoXCJmcm9udGVuZFwiLFwiZmlyc3RieXRlXCIsXCJvbmxvYWRcIiksaC5tZWFzdXJlKFwicGFnZSBsb2FkIHRpbWVcIixcInN0YXJ0dGltZVwiLFwib25sb2FkXCIpKTpcImRvbmVcIj09PWImJmgubWVhc3VyZShcInRvdGFsIGxvYWQgdGltZVwiLFwic3RhcnR0aW1lXCIsXCJkb25lXCIpKSk6dm9pZCBoLmRwcmludChcIkVycm9yOiBtYXJrTmFtZSBpcyB1bmRlZmluZWQgaW4gUlVNX0VQSVNPREVTLm1hcmsuXCIpfSxoLm1lYXN1cmU9ZnVuY3Rpb24oYixjLGQpe2lmKGguZHByaW50KFwiUlVNX0VQSVNPREVTLm1lYXN1cmU6IFwiK2IrXCIsIFwiK2MrXCIsIFwiK2QpLCFiKXJldHVybiB2b2lkIGguZHByaW50KFwiRXJyb3I6IGVwaXNvZGVOYW1lIGlzIHVuZGVmaW5lZCBpbiBSVU1fRVBJU09ERVMubWVhc3VyZS5cIik7dmFyIGU7aWYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIGMpZT1cIm51bWJlclwiPT10eXBlb2YgaC5tYXJrc1tiXT9oLm1hcmtzW2JdOihuZXcgRGF0ZSkuZ2V0VGltZSgpO2Vsc2UgaWYoXCJudW1iZXJcIj09dHlwZW9mIGgubWFya3NbY10pZT1oLm1hcmtzW2NdO2Vsc2V7aWYoXCJudW1iZXJcIiE9dHlwZW9mIGMpcmV0dXJuIHZvaWQgaC5kcHJpbnQoXCJFcnJvcjogdW5leHBlY3RlZCBzdGFydE5hbWVPclRpbWUgaW4gUlVNX0VQSVNPREVTLm1lYXN1cmU6IFwiK2MpO2U9Y312YXIgZjtpZihcInVuZGVmaW5lZFwiPT10eXBlb2YgZClmPShuZXcgRGF0ZSkuZ2V0VGltZSgpO2Vsc2UgaWYoXCJudW1iZXJcIj09dHlwZW9mIGgubWFya3NbZF0pZj1oLm1hcmtzW2RdO2Vsc2V7aWYoXCJudW1iZXJcIiE9dHlwZW9mIGQpcmV0dXJuIHZvaWQgaC5kcHJpbnQoXCJFcnJvcjogdW5leHBlY3RlZCBlbmROYW1lT3JUaW1lIGluIFJVTV9FUElTT0RFUy5tZWFzdXJlOiBcIitkKTtmPWR9aC5zdGFydHNbYl09cGFyc2VJbnQoZSksaC5tZWFzdXJlc1tiXT1wYXJzZUludChmLWUpLGguYlBvc3RNZXNzYWdlJiZhLnBvc3RNZXNzYWdlKFwiUlVNX0VQSVNPREVTOm1lYXN1cmU6XCIrYitcIjpcIitlK1wiOlwiK2YsaC50YXJnZXRPcmlnaW4pfSxoLmRvbmU9ZnVuY3Rpb24oYil7aC5iRG9uZT0hMCxoLm1hcmsoXCJkb25lXCIpLGguYlBvc3RNZXNzYWdlJiZhLnBvc3RNZXNzYWdlKFwiUlVNX0VQSVNPREVTOmRvbmVcIixoLnRhcmdldE9yaWdpbiksXCJmdW5jdGlvblwiPT10eXBlb2YgYiYmYigpfSxoLmdldE1hcmtzPWZ1bmN0aW9uKCl7cmV0dXJuIGgubWFya3N9LGguZ2V0TWVhc3VyZXM9ZnVuY3Rpb24oKXtyZXR1cm4gaC5tZWFzdXJlc30saC5nZXRTdGFydHM9ZnVuY3Rpb24oKXtyZXR1cm4gaC5zdGFydHN9LGguZmluZFN0YXJ0VGltZT1mdW5jdGlvbigpe3ZhciBhPWguZmluZFN0YXJ0V2ViVGltaW5nKCl8fGguZmluZFN0YXJ0Q29va2llKCk7YSYmaC5tYXJrKFwic3RhcnR0aW1lXCIsYSl9LGguZmluZFN0YXJ0V2ViVGltaW5nPWZ1bmN0aW9uKCl7dmFyIGIsYz1hLnBlcmZvcm1hbmNlfHxhLm1velBlcmZvcm1hbmNlfHxhLm1zUGVyZm9ybWFuY2V8fGEud2Via2l0UGVyZm9ybWFuY2U7cmV0dXJuIGMmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBjLnRpbWluZyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGMudGltaW5nLm5hdmlnYXRpb25TdGFydCYmKGI9Yy50aW1pbmcubmF2aWdhdGlvblN0YXJ0LGguZHByaW50KFwiUlVNX0VQSVNPREVTLmZpbmRTdGFydFdlYlRpbWluZzogc3RhcnRUaW1lID0gXCIrYikpLGJ9LGguZmluZFN0YXJ0Q29va2llPWZ1bmN0aW9uKCl7Zm9yKHZhciBkPWIuY29va2llLnNwbGl0KFwiIFwiKSxlPTA7ZTxkLmxlbmd0aDtlKyspaWYoMD09PWRbZV0uaW5kZXhPZihcIlJVTV9FUElTT0RFUz1cIikpe2Zvcih2YXIgZixnLGk9ZFtlXS5zdWJzdHJpbmcoXCJSVU1fRVBJU09ERVM9XCIubGVuZ3RoKS5zcGxpdChcIiZcIiksaj0wO2o8aS5sZW5ndGg7aisrKWlmKDA9PT1pW2pdLmluZGV4T2YoXCJzPVwiKSlmPWlbal0uc3Vic3RyaW5nKDIpO2Vsc2UgaWYoMD09PWlbal0uaW5kZXhPZihcInI9XCIpKXt2YXIgaz1pW2pdLnN1YnN0cmluZygyKTtrPWsucmVwbGFjZSgvOyQvLFwiXCIpLGc9YS5lc2NhcGUoYi5yZWZlcnJlcik9PT1rfWlmKGcmJmYpcmV0dXJuIGguZHByaW50KFwiUlVNX0VQSVNPREVTLmZpbmRTdGFydENvb2tpZTogc3RhcnRUaW1lID0gXCIrZiksZn1yZXR1cm4gY30saC5iZWZvcmVVbmxvYWQ9ZnVuY3Rpb24oKXtoLmJVbmxvYWRlZHx8KGIuY29va2llPVwiUlVNX0VQSVNPREVTPXM9XCIrTnVtYmVyKG5ldyBEYXRlKStcIiZyPVwiK2EuZXNjYXBlKGIubG9jYXRpb24pK1wiOyBwYXRoPS9cIixoLmJVbmxvYWRlZD0hMCl9LGgub25sb2FkPWZ1bmN0aW9uKCl7aC5tYXJrKFwib25sb2FkXCIpLGguZG9uZSgpfSxoLmFkZEV2ZW50TGlzdGVuZXI9ZnVuY3Rpb24oYixjLGQpe3JldHVyblwidW5kZWZpbmVkXCIhPXR5cGVvZiBhLmF0dGFjaEV2ZW50P2EuYXR0YWNoRXZlbnQoXCJvblwiK2IsYyk6YS5hZGRFdmVudExpc3RlbmVyP2EuYWRkRXZlbnRMaXN0ZW5lcihiLGMsZCk6dm9pZCAwfSxoLmRwcmludD1mdW5jdGlvbigpe30saC5pbml0KCk7dmFyIGk9bnVsbCxqPXtuYXZpZ2F0aW9uU3RhcnQ6XCJuc1wiLHJlZGlyZWN0U3RhcnQ6XCJyZHNcIixyZWRpcmVjdEVuZDpcInJkZVwiLHVubG9hZEV2ZW50U3RhcnQ6XCJ1c1wiLHVubG9hZEV2ZW50RW5kOlwidWVcIixmZXRjaFN0YXJ0OlwiZnNcIixkb21haW5Mb29rdXBTdGFydDpcImRsc1wiLGRvbWFpbkxvb2t1cEVuZDpcImRsZVwiLGNvbm5lY3RTdGFydDpcImNzXCIsc2VjdXJlQ29ubmVjdGlvblN0YXJ0Olwic2NzXCIsY29ubmVjdEVuZDpcImNlXCIsaGFuZHNoYWtlU3RhcnQ6XCJoc1wiLHJlcXVlc3RTdGFydDpcInJxc1wiLHJlc3BvbnNlU3RhcnQ6XCJycHNcIixyZXNwb25zZUVuZDpcInJwZVwiLGRvbUxvYWRpbmc6XCJkbFwiLGRvbUludGVyYWN0aXZlOlwiZGlcIixkb21Db250ZW50TG9hZGVkRXZlbnRTdGFydDpcImRjc1wiLGRvbUNvbnRlbnRMb2FkZWRFdmVudEVuZDpcImRjZVwiLGRvbUNvbXBsZXRlOlwiZGNcIixsb2FkRXZlbnRTdGFydDpcImxzXCIsbG9hZEV2ZW50RW5kOlwibGVcIn0saz1hLnBlcmZvcm1hbmNlfHxhLm1velBlcmZvcm1hbmNlfHxhLm1zUGVyZm9ybWFuY2V8fGEud2Via2l0UGVyZm9ybWFuY2U7ayYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGsudGltaW5nJiZcInVuZGVmaW5lZFwiIT10eXBlb2Ygay5uYXZpZ2F0aW9uP2k9c2V0SW50ZXJ2YWwoZSwxMDApOihoLm1hcmsoXCJmaXJzdGJ5dGVcIixnKSxpPXNldEludGVydmFsKGYsMTAwKSl9KHdpbmRvdyxkb2N1bWVudCksYXRhdHVzLl9fYXR0YWNoQWpheEhvb2tzPWZ1bmN0aW9uKCl7IWZ1bmN0aW9uKGEsYil7dmFyIGM9YXRhdHVzLl9oZWxwZXIsZD17cXVldWU6W10sYmF0Y2hTaXplOjI1LHByb2Nlc3Npbmc6ITEsYlVubG9hZGVkOiExLHB1c2g6ZnVuY3Rpb24oYSl7XCJzdHJpbmdcIj09dHlwZW9mIGEudXJsJiZhLnVybC5pbmRleE9mKFwiLmh0bWxcIik+MHx8KHRoaXMucXVldWUucHVzaChhKSx0aGlzLnF1ZXVlLmxlbmd0aD49dGhpcy5iYXRjaFNpemUmJnRoaXMuX3Byb2Nlc3NRdWV1ZSgpKX0sX3Byb2Nlc3NRdWV1ZTpmdW5jdGlvbigpe2lmKCF0aGlzLnByb2Nlc3NpbmcmJnRoaXMucXVldWUubGVuZ3RoKXt0aGlzLnByb2Nlc3Npbmc9ITA7dHJ5e2Zvcih2YXIgYT17fSxiPXt9LGQ9MDtkPHRoaXMucXVldWUubGVuZ3RoO2QrKyl7dmFyIGUsZj10aGlzLnF1ZXVlW2RdO2lmKGYuc3RhdHVzPDQwMCl7ZT1mLm1ldGhvZCtmLnVybDt2YXIgZz1mLnJlc3BBdmFpbFRpbWUtZi5zZW5kVGltZSxoPWYucmVzcFByb2NUaW1lLWYucmVzcEF2YWlsVGltZSxpPWYucmVjZWl2ZWRTaXplLGo9Zi5zZW5kU2l6ZSxrPWFbZV07aWYoayl7ay5jKys7dmFyIGw9ay5yZTtsLnQ9bC50K2csbC5sbz1sLmxvPGc/bC5sbzpnLGwuaGk9bC5oaT5nP2wuaGk6ZyxsLnNzcT1sLnNzcStnKmc7dmFyIG09ay5jYjttLnQ9bS50K2gsbS5sbz1tLmxvPGg/bS5sbzpoLG0uaGk9bS5oaT5oP20uaGk6aCxtLnNzcT1tLnNzcStoKmg7dmFyIG49ay5ycztuLnQ9bi50K2ksbi5sbz1uLmxvPGk/bi5sbzppLG4uaGk9bi5oaT5pP24uaGk6aSxuLnNzcT1uLnNzcStpKmk7dmFyIG89ay5zcztvLnQ9by50K2osby5sbz1vLmxvPGo/by5sbzpqLG8uaGk9by5oaT5qP28uaGk6aixvLnNzcT1vLnNzcStqKmp9ZWxzZSBhW2VdPXttOmYubWV0aG9kLHVybDpmLnVybCxjOjEscmU6e3Q6ZyxsbzpnLGhpOmcsc3NxOmcqZ30sY2I6e3Q6aCxsbzpoLGhpOmgsc3NxOmgqaH0scnM6e3Q6Zi5yZWNlaXZlZFNpemUsbG86Zi5yZWNlaXZlZFNpemUsaGk6Zi5yZWNlaXZlZFNpemUsc3NxOmYucmVjZWl2ZWRTaXplKmYucmVjZWl2ZWRTaXplfSxzczp7dDpmLnNlbmRTaXplLGxvOmYuc2VuZFNpemUsaGk6Zi5zZW5kU2l6ZSxzc3E6Zi5zZW5kU2l6ZSpmLnNlbmRTaXplfX19ZWxzZSBlPWYubWV0aG9kK2Yuc3RhdHVzK2YudXJsLGJbZV0/YltlXS5jKys6YltlXT17bTpmLm1ldGhvZCx1cmw6Zi51cmwsc3Q6Zi5zdGF0dXMsYzoxfX12YXIgcD17eGhyOmMuYXJyYXlGcm9tT2JqZWN0KGEpLHhockVycm9yOmMuYXJyYXlGcm9tT2JqZWN0KGIpfTthdGF0dXMuc2VuZEFqYXhQZXJmKHApfWNhdGNoKHEpe2MubG9nKFwiRXJyb3Igd2hpbGUgcHJvY2Vzc2luZyBxdWV1ZTogXCIscSl9ZmluYWxseXt0aGlzLnF1ZXVlPVtdLHRoaXMucHJvY2Vzc2luZz0hMX19fSxiZWZvcmVVbmxvYWQ6ZnVuY3Rpb24oKXtkLmJVbmxvYWRlZHx8KGQuX3Byb2Nlc3NRdWV1ZSgpLGQuYlVubG9hZGVkPSEwKX19O2MuYWRkRXZlbnRMaXN0ZW5lcihcImJlZm9yZXVubG9hZFwiLGQuYmVmb3JlVW5sb2FkLCExKTt2YXIgZT17c3VwcG9ydDpmdW5jdGlvbihhKXtyZXR1cm4hYXx8XCJhcHBseVwiaW4gYX0sYXJvdW5kOmZ1bmN0aW9uKGEsYixkLGUpe3JldHVybiBhPWF8fGZ1bmN0aW9uKCl7fSxmdW5jdGlvbigpe3ZhciBmLGc9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTt0cnl7YiYmKGY9Yi5hcHBseSh0aGlzLGcpKX1jYXRjaChoKXtjLmxvZyhlLGgpfXZhciBpO3RyeXtpPWEuYXBwbHkodGhpcyxmfHxnKX1maW5hbGx5e3RyeXtkJiZkLmFwcGx5KHRoaXMsZyl9Y2F0Y2goaCl7Yy5sb2coZSxoKX19cmV0dXJuIGl9fSxiZWZvcmU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gZS5hcm91bmQoYSxiKX0sYWZ0ZXI6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gZS5hcm91bmQoYSxudWxsLGIpfSx0aW1lb3V0OmZ1bmN0aW9uKGEpe3NldFRpbWVvdXQoYSwwKX0sd3JhcEFkZEV2ZW50TGlzdGVuZXI6ZnVuY3Rpb24oKXtyZXR1cm4gZnVuY3Rpb24oYSxiKXtpZigoXCJsb2FkXCI9PT1hfHxcImVycm9yXCI9PT1hKSYmYiYmdGhpcy5fYXRydW1YaHJEYXRhKXt2YXIgYztiLl9fYXRydW1JbnRlcmNlcHRvcj9jPWIuX19hdHJ1bUludGVyY2VwdG9yOmUuc3VwcG9ydChiKT8oYz1nLndyYXBYSFIoYix0aGlzLFwiWEhSLmludm9rZUV2ZW50TGlzdGVuZXJcIiksYi5fX2F0cnVtSW50ZXJjZXB0b3I9Yyk6Yz1udWxsO3ZhciBkO3JldHVybiBjJiYoZD1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpLGRbMV09YyksZH19fSx3cmFwUmVtb3ZlRXZlbnRMaXN0ZW5lcjpmdW5jdGlvbigpe3JldHVybiBmdW5jdGlvbihhLGIpe2lmKHRoaXMuX2F0cnVtWGhyRGF0YSl7dmFyIGM9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTtyZXR1cm4gYi5fX2F0cnVtSW50ZXJjZXB0b3ImJihjWzFdPWIuX19hdHJ1bUludGVyY2VwdG9yKSxjfX19LGFyb3VuZFdpdGhIYW5kbGVFdmVudDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgZj1hO3JldHVybiBhJiZcIm9iamVjdFwiPT10eXBlb2YgYSYmXCJ0b1N0cmluZ1wiaW4gYSYmXCJbeHBjb25uZWN0IHdyYXBwZWQgbnNJRE9NRXZlbnRMaXN0ZW5lcl1cIj09PWEudG9TdHJpbmcoKSYmXCJoYW5kbGVFdmVudFwiaW4gYSYmKGY9ZnVuY3Rpb24oKXthLmhhbmRsZUV2ZW50LmFwcGx5KHRoaXMsQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKSl9KSxlLmFyb3VuZChmLGIsYyxkKX0sZ2V0RnVsbHlRdWFsaWZpZWRVcmw6ZnVuY3Rpb24oYSl7dmFyIGM9Yi5jcmVhdGVFbGVtZW50KFwiYVwiKTtyZXR1cm4gYy5ocmVmPWEsYy5ocmVmfX07aWYoYS5YTUxIdHRwUmVxdWVzdCYmYS5YTUxIdHRwUmVxdWVzdC5wcm90b3R5cGUpe3ZhciBmPWEuWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlO2lmKCEoXCJvcGVuXCJpbiBmJiZcInNlbmRcImluIGYpKXJldHVybjtpZighZS5zdXBwb3J0KGYub3Blbil8fCFlLnN1cHBvcnQoZi5zZW5kKSlyZXR1cm47dmFyIGc9e307Zy5jYXB0dXJlQWpheFRpbWluZ3M9ZnVuY3Rpb24oYSl7dmFyIGI9YS5fYXRydW1YaHJEYXRhO2lmKGIpe3ZhciBjPShuZXcgRGF0ZSkuZ2V0VGltZSgpOzI9PT1hLnJlYWR5U3RhdGU/Yi5maXJzdEJ5dGVUaW1lPWIuZmlyc3RCeXRlVGltZXx8Yzo0PT09YS5yZWFkeVN0YXRlJiYoYi5yZXNwQXZhaWxUaW1lPWIucmVzcEF2YWlsVGltZXx8YyxiLmZpcnN0Qnl0ZVRpbWU9Yi5maXJzdEJ5dGVUaW1lfHxjKX19LGcuc2VuZFBheWxvYWQ9ZnVuY3Rpb24oYSxiKXtiLnJlY2VpdmVkU2l6ZT0wLGEucmVzcG9uc2VUeXBlJiZcInRleHRcIiE9PWEucmVzcG9uc2VUeXBlfHxcInN0cmluZ1wiPT10eXBlb2YgYS5yZXNwb25zZVRleHQmJihiLnJlY2VpdmVkU2l6ZT1hLnJlc3BvbnNlVGV4dC5sZW5ndGgpLGIuc3RhdHVzPWEuc3RhdHVzLGQucHVzaChiKX0sZy53cmFwWEhSPWZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gZS5hcm91bmRXaXRoSGFuZGxlRXZlbnQoYSxmdW5jdGlvbigpe2cuY2FwdHVyZUFqYXhUaW1pbmdzKHRoaXMpfSxmdW5jdGlvbigpe3ZhciBhPWIuX2F0cnVtWGhyRGF0YTtpZihhJiY0PT09Yi5yZWFkeVN0YXRlKXt2YXIgYz0obmV3IERhdGUpLmdldFRpbWUoKTthLnJlc3BQcm9jVGltZT1hLnJlc3BQcm9jVGltZXx8YyxnLnNlbmRQYXlsb2FkKGIsYSksZGVsZXRlIGIuX2F0cnVtWGhyRGF0YX19LGMpfSxnLmFqYXhEb25lPWZ1bmN0aW9uKGEpe2lmKGEuX2F0cnVtWGhyRGF0YSl7dmFyIGI9KG5ldyBEYXRlKS5nZXRUaW1lKCkrM2U0LGM9ZnVuY3Rpb24oKXtnLmNhcHR1cmVBamF4VGltaW5ncyhhKTt2YXIgZD1hLl9hdHJ1bVhockRhdGE7aWYoZCl7dmFyIGU9KG5ldyBEYXRlKS5nZXRUaW1lKCk7ND09PWEucmVhZHlTdGF0ZT8oZC5yZXNwUHJvY1RpbWU9ZC5yZXNwUHJvY1RpbWV8fGUsZy5zZW5kUGF5bG9hZChhLGQpLGRlbGV0ZSBhLl9hdHJ1bVhockRhdGEpOmI+ZT9zZXRUaW1lb3V0KGMsNTApOmRlbGV0ZSBhLl9hdHJ1bVhockRhdGF9fTtjKCl9fSxmLm9wZW49ZS5hcm91bmQoZi5vcGVuLGZ1bmN0aW9uKCl7dmFyIGE9MTw9YXJndW1lbnRzLmxlbmd0aD9TdHJpbmcoYXJndW1lbnRzWzBdKTpcIlwiLGI9Mjw9YXJndW1lbnRzLmxlbmd0aD9TdHJpbmcoYXJndW1lbnRzWzFdKTpcIlwiLGM9YXRhdHVzLmdldEFsbG93ZWREb21haW5zKCksZD0hMDtpZihiPWUuZ2V0RnVsbHlRdWFsaWZpZWRVcmwoYiksYiYmYyYmYy5sZW5ndGgpe2Q9ITE7Zm9yKHZhciBmPTA7ZjxjLmxlbmd0aDtmKyspe3ZhciBnPWNbZl07aWYoZyYmYi5pbmRleE9mKGcpPi0xKXtkPSEwO2JyZWFrfX19ZCYmKGI9YiYmYi5zcGxpdChcIj9cIilbMF0sdGhpcy5fYXRydW1YaHJEYXRhPXttZXRob2Q6YSx1cmw6YixzZW5kVGltZTpudWxsLHNlbmRTaXplOm51bGwsZmlyc3RCeXRlVGltZTpudWxsLHJlc3BBdmFpbFRpbWU6bnVsbCxyZXNwUHJvY1RpbWU6bnVsbCxyZWNlaXZlZFNpemU6bnVsbCxwYXJlbnRQaGFzZTpudWxsfSl9LG51bGwsXCJYSFIub3BlblwiKSxmLnNlbmQ9ZS5hcm91bmQoZi5zZW5kLGZ1bmN0aW9uKCl7dmFyIGE9dGhpcyxiPWEuX2F0cnVtWGhyRGF0YTtpZihiKXt2YXIgYz0obmV3IERhdGUpLmdldFRpbWUoKTtiLnNlbmRUaW1lPWIuc2VuZFRpbWV8fGMsYi5zZW5kU2l6ZT0xPD1hcmd1bWVudHMubGVuZ3RoJiZhcmd1bWVudHNbMF0/YXJndW1lbnRzWzBdLmxlbmd0aHx8MDowO3ZhciBkPTAsZj1mdW5jdGlvbigpe2lmKDQ9PT1hLnJlYWR5U3RhdGUpZy5hamF4RG9uZShhKTtlbHNle3ZhciBiPW51bGw7dHJ5e2I9YS5vbnJlYWR5c3RhdGVjaGFuZ2V9Y2F0Y2goYyl7cmV0dXJuIHZvaWQgZy5hamF4RG9uZShhKX1kKyssYj9lLnN1cHBvcnQoYik/YS5vbnJlYWR5c3RhdGVjaGFuZ2U9Zy53cmFwWEhSKGIsYSxcIlhIUi5vblJlYWR5U3RhdGVDaGFuZ2VcIik6Zy5hamF4RG9uZShhKTo1PmQ/ZS50aW1lb3V0KGYpOmcuYWpheERvbmUoYSl9fTtmKCl9fSxudWxsLFwiWEhSLnNlbmRcIiksXCJhZGRFdmVudExpc3RlbmVyXCJpbiBmJiZcInJlbW92ZUV2ZW50TGlzdGVuZXJcImluIGYmJmUuc3VwcG9ydChmLmFkZEV2ZW50TGlzdGVuZXIpJiZlLnN1cHBvcnQoZi5yZW1vdmVFdmVudExpc3RlbmVyKSYmKGYuYWRkRXZlbnRMaXN0ZW5lcj1lLmFyb3VuZChmLmFkZEV2ZW50TGlzdGVuZXIsZS53cmFwQWRkRXZlbnRMaXN0ZW5lcigpLG51bGwsXCJYSFIuYWRkRXZlbnRMaXN0ZW5lclwiKSxmLnJlbW92ZUV2ZW50TGlzdGVuZXI9ZS5hcm91bmQoZi5yZW1vdmVFdmVudExpc3RlbmVyLGUud3JhcFJlbW92ZUV2ZW50TGlzdGVuZXIoKSxudWxsLFwiWEhSLnJlbW92ZUV2ZW50TGlzdGVuZXJcIikpfX0od2luZG93LGRvY3VtZW50KX0sZnVuY3Rpb24oYSl7ZnVuY3Rpb24gYihhLGIsYyl7aWYoISgwPj1iKSl7dmFyIGQ9e25hbWU6YSxkdXI6YixzdDpjfTthdGF0dXMuc2VuZFR4blBlcmYoZCl9fWZ1bmN0aW9uIGMoYSl7cmV0dXJuIGgrXCIgXCIrYX1mdW5jdGlvbiBkKCl7dHJ5e3JldHVyblwibG9jYWxTdG9yYWdlXCJpbiBhJiZudWxsIT09YS5sb2NhbFN0b3JhZ2U7fWNhdGNoKGIpe3JldHVybiExfX1mdW5jdGlvbiBlKGEpe3ZhciBiPWkubm93KCk7dHJ5e2xvY2FsU3RvcmFnZS5zZXRJdGVtKGMoYSksYil9Y2F0Y2goZCl7fX1mdW5jdGlvbiBmKGEpe3ZhciBiPW51bGwsZD1jKGEpO3RyeXtiPWxvY2FsU3RvcmFnZS5nZXRJdGVtKGQpLGxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKGQpfWNhdGNoKGUpe312YXIgZj0wO3JldHVybiBiJiYoZj1pLm5vdygpLWIpLGZ9ZnVuY3Rpb24gZyhhKXt0cnl7dmFyIGI9YyhhKTtsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShiKX1jYXRjaChkKXt9fXZhciBoPVwiYXRhdHVzLmNvbS9cIixpPWF0YXR1cy5faGVscGVyLGo9MSxrPTA7YXRhdHVzLmJlZ2luVHJhbnNhY3Rpb249ZnVuY3Rpb24oYSl7ZCgpJiZlKGEpfSxhdGF0dXMuZW5kVHJhbnNhY3Rpb249ZnVuY3Rpb24oYSl7aWYoZCgpKXt2YXIgYz1mKGEpO2IoYSxjLGopfX0sYXRhdHVzLmZhaWxUcmFuc2FjdGlvbj1mdW5jdGlvbihhKXtpZihkKCkpe3ZhciBjPWYoYSk7YihhLGMsayl9fSxhdGF0dXMuY2FuY2VsVHJhbnNhY3Rpb249ZnVuY3Rpb24oYSl7ZCgpJiZnKGEpfX0od2luZG93LGRvY3VtZW50KTtcbi8qISBodHRwczovL2dpdGh1Yi5jb20vdHRhdWJlcnQvbm9kZS1hcnJheWJ1ZmZlci1zbGljZVxuICogKGMpIDIwMTQgVGltIFRhdWJlcnQgPHRpbUB0aW10YXViZXJ0LmRlPlxuICogYXJyYXlidWZmZXItc2xpY2UgbWF5IGJlIGZyZWVseSBkaXN0cmlidXRlZCB1bmRlciB0aGUgTUlUIGxpY2Vuc2UuKi9cbiFmdW5jdGlvbihyKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiB0KHIsdCl7cmV0dXJuIHI9MHxyfHwwLHI8MD9NYXRoLm1heChyK3QsMCk6TWF0aC5taW4ocix0KX1BcnJheUJ1ZmZlci5wcm90b3R5cGUuc2xpY2V8fChBcnJheUJ1ZmZlci5wcm90b3R5cGUuc2xpY2U9ZnVuY3Rpb24oZSxuKXt2YXIgZj10aGlzLmJ5dGVMZW5ndGgsaT10KGUsZiksYT1mO2lmKG4hPT1yJiYoYT10KG4sZikpLGk+YSlyZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO3ZhciB1PWEtaSx5PW5ldyBBcnJheUJ1ZmZlcih1KSxvPW5ldyBVaW50OEFycmF5KHkpLHM9bmV3IFVpbnQ4QXJyYXkodGhpcyxpLHUpO3JldHVybiBvLnNldChzKSx5fSl9KCk7XG4hZnVuY3Rpb24odCl7ZnVuY3Rpb24gZShyKXtpZihpW3JdKXJldHVybiBpW3JdLnQ7dmFyIG49aVtyXT17dDp7fSxpZDpyLGxvYWRlZDohMX07cmV0dXJuIHRbcl0uY2FsbChuLnQsbixuLnQsZSksbi5sb2FkZWQ9ITAsbi50fXZhciBpPXt9O3JldHVybiBlLmk9dCxlLmM9aSxlLm89XCJcIixlKDApfShbZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPXRoaXMmJnRoaXMuX19leHRlbmRzfHxmdW5jdGlvbih0LGUpe2Z1bmN0aW9uIGkoKXt0aGlzLmNvbnN0cnVjdG9yPXR9Zm9yKHZhciByIGluIGUpZS5oYXNPd25Qcm9wZXJ0eShyKSYmKHRbcl09ZVtyXSk7dC5wcm90b3R5cGU9bnVsbD09PWU/T2JqZWN0LmNyZWF0ZShlKTooaS5wcm90b3R5cGU9ZS5wcm90b3R5cGUsbmV3IGkpfSxuPWkoMjUpLG89aSg3KSxzPWkoOSksYT1pKDEpO2lmKFwidW5kZWZpbmVkXCI9PXR5cGVvZiBjKXZhciBjPTNlNDt2YXIgaD1mdW5jdGlvbih0KXtmdW5jdGlvbiBlKGUsaSl7dmFyIHI9dC5jYWxsKHRoaXMsaSl8fHRoaXM7cmV0dXJuIHIucGx1Z2luTmFtZT1cImJpdG1vdmluXCIsci5zPSExLHIucGxheWVyPWUsci5wbGF5ZXIuaW5pdFNlc3Npb249ZnVuY3Rpb24odCl7cmV0dXJuIHIuaCgpLHIucCh0KS50aW1lb3V0KGMsci51K1wiIEhpdmUgUGx1Z2luIGluaXRpYWxpemF0aW9uIHRpbWVvdXRcIikudGhlbihmdW5jdGlvbih0KXtyZXR1cm4gci5sKCksdC5nKCl9KVtcImNhdGNoXCJdKGZ1bmN0aW9uKHQpe3JldHVybiByLnYoKSxyLmgoKSxyLm0oKS5kZWJ1ZyhyLnUrXCIgZXJyb3Igb2NjdXJyZWQgcmVzb2x2aW5nIHRoZSB0aWNrZXQgLSBcIit0LnN0YWNrKSxhLnJlamVjdCh0KX0pfSxyLm0oKS5ub3RpY2Uoci51K1wicmVnaXN0ZXJlZCBwbHVnaW4gW25hbWU6XCIrci5UKCkrXCJdW2lkOiBcIityLlMoKStcIl1bdmVyc2lvbjogXCIrci5JKCkrXCJdXCIpLHJ9cmV0dXJuIHIoZSx0KSxlLnByb3RvdHlwZS5sPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpczt0aGlzLnN8fCh0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvblJlYWR5XCIsZnVuY3Rpb24oKXtpZih0Lm0oKS5kZWJ1ZyhcImJpdG1vdmluLnBsYXllci5FVkVOVC5PTl9SRUFEWVwiKSx0LlIoKSl7dmFyIGU9ISF0LnBsYXllci5nZXRDb25maWcoKS5wbGF5YmFjayYmdC5wbGF5ZXIuZ2V0Q29uZmlnKCkucGxheWJhY2suYXV0bztlJiZ0LmsoITEpLHQuQygpJiYodC5PPW5ldyBvLlApfX0pLHRoaXMucGxheWVyLmFkZEV2ZW50SGFuZGxlcihcIm9uUGxheVwiLGZ1bmN0aW9uKCl7dC5tKCkuZGVidWcoXCJiaXRtb3Zpbi5wbGF5ZXIuRVZFTlQuT05fUExBWVwiKSx0LkEocy5GLkIuTil9KSx0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvbkVycm9yXCIsZnVuY3Rpb24oZSl7dC5tKCkuZGVidWcoXCJiaXRtb3Zpbi5wbGF5ZXIuRVZFTlQuT05fRVJST1JcIik7dmFyIGk9LTEscj1udWxsO2lmKG51bGwhPWUpdHJ5e2k9ZS5jb2RlLHI9SlNPTi5zdHJpbmdpZnkoZSxudWxsKX1jYXRjaChuKXtyPWV9dC5vbkVycm9yKGkscil9KSx0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvblBsYXliYWNrRmluaXNoZWRcIixmdW5jdGlvbigpe3QubSgpLmRlYnVnKFwiYml0bW92aW4ucGxheWVyLkVWRU5ULk9OX1BMQVlCQUNLX0ZJTklTSEVEXCIpLHQuXyhzLkYuQi5ELHtjb2RlOjF9KX0pLHRoaXMucGxheWVyLmFkZEV2ZW50SGFuZGxlcihcIm9uU2Vla1wiLGZ1bmN0aW9uKCl7dC5tKCkuZGVidWcoXCJiaXRtb3Zpbi5wbGF5ZXIuRVZFTlQuT05fU0VFS1wiKSx0Ll8ocy5GLkIuSCl9KSx0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvbkZ1bGxzY3JlZW5FbnRlclwiLGZ1bmN0aW9uKCl7dC5tKCkuZGVidWcoXCJiaXRtb3Zpbi5wbGF5ZXIuRVZFTlQuT05fRlVMTFNDUkVFTl9FTlRFUlwiKSx0Ll8ocy5GLkIuTCx7dmFsdWU6ITB9KX0pLHRoaXMucGxheWVyLmFkZEV2ZW50SGFuZGxlcihcIm9uRnVsbHNjcmVlbkV4aXRcIixmdW5jdGlvbigpe3QubSgpLmRlYnVnKFwiYml0bW92aW4ucGxheWVyLkVWRU5ULk9OX0ZVTExTQ1JFRU5fRVhJVFwiKSx0Ll8ocy5GLkIuTCx7dmFsdWU6ITF9KX0pLHRoaXMucGxheWVyLmFkZEV2ZW50SGFuZGxlcihcIm9uU2VnbWVudFJlcXVlc3RGaW5pc2hlZFwiLGZ1bmN0aW9uKGUpe3ZhciBpPWUubWltZVR5cGUuaW5kZXhPZihcInZpZGVvXCIpPj0wO2lmKGUuc3VjY2Vzcyl7dmFyIHI9OCplLnNpemUvZS5kb3dubG9hZFRpbWU7dC5PLk0oaSx0LmosZS5zaXplKSx0Lk8uVShyKX1lbHNlIHQuTy5WKGksdC5qKX0pLDA9PT10aGlzLnEoKS5pbmRleE9mKFwiN1wiKT90aGlzLkooKTowPT09dGhpcy5xKCkuaW5kZXhPZihcIjZcIikmJnRoaXMuSygpLHRoaXMucz0hMCl9LGUucHJvdG90eXBlLks9ZnVuY3Rpb24oKXt2YXIgdD10aGlzO3RoaXMucGxheWVyLmFkZEV2ZW50SGFuZGxlcihcIm9uU3RhcnRCdWZmZXJpbmdcIixmdW5jdGlvbigpe3QubSgpLmRlYnVnKFwiYml0bW92aW4ucGxheWVyLkVWRU5ULk9OX1NUQVJUX0JVRkZFUklOR1wiKSx0LmsoKX0pLHRoaXMucGxheWVyLmFkZEV2ZW50SGFuZGxlcihcIm9uU3RvcEJ1ZmZlcmluZ1wiLGZ1bmN0aW9uKCl7dC5tKCkuZGVidWcoXCJiaXRtb3Zpbi5wbGF5ZXIuRVZFTlQuT05fU1RPUF9CVUZGRVJJTkdcIiksdC5HKCl9KSx0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvblBhdXNlXCIsZnVuY3Rpb24oKXt0Lm0oKS5kZWJ1ZyhcImJpdG1vdmluLnBsYXllci5FVkVOVC5PTl9QQVVTRVwiKSx0LkEocy5GLkIuVyl9KSx0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvblZpZGVvRG93bmxvYWRRdWFsaXR5Q2hhbmdlXCIsZnVuY3Rpb24oZSl7dmFyIGk9dC4kKCk7aT09PVN0cmVhbVByb3RvY29sLlk/dC5YKGUudGFyZ2V0UXVhbGl0eSk6dC5YKGUudGFyZ2V0UXVhbGl0eS5zcGxpdChcImJyXCIpWzFdKX0pfSxlLnByb3RvdHlwZS5KPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpczt0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvblN0YWxsU3RhcnRlZFwiLGZ1bmN0aW9uKCl7dC5tKCkuZGVidWcoXCJiaXRtb3Zpbi5wbGF5ZXIuRVZFTlQuT05fU1RBTExfU1RBUlRFRFwiKSx0LmsoKX0pLHRoaXMucGxheWVyLmFkZEV2ZW50SGFuZGxlcihcIm9uU3RhbGxFbmRlZFwiLGZ1bmN0aW9uKCl7dC5tKCkuZGVidWcoXCJiaXRtb3Zpbi5wbGF5ZXIuRVZFTlQuT05fU1RBTExfRU5ERURcIiksdC5HKCl9KSx0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvblBhdXNlZFwiLGZ1bmN0aW9uKCl7dC5tKCkuZGVidWcoXCJiaXRtb3Zpbi5wbGF5ZXIuRVZFTlQuT05fUEFVU0VEXCIpLHQuQShzLkYuQi5XKX0pLHRoaXMucGxheWVyLmFkZEV2ZW50SGFuZGxlcihcIm9uVmlkZW9Eb3dubG9hZFF1YWxpdHlDaGFuZ2VkXCIsZnVuY3Rpb24oZSl7dC5YKGUudGFyZ2V0UXVhbGl0eUlkLmJpdHJhdGUpfSl9LGUucHJvdG90eXBlLlg9ZnVuY3Rpb24odCl7dGhpcy5tKCkuZGVidWcoXCJuZXdCaXRyYXRlXCIsdCksdGhpcy5qJiZ0PnRoaXMuaj90aGlzLk8uWigpOnRoaXMuaiYmdGhpcy5qPnQmJnRoaXMuTy50dCgpLHRoaXMuaj10fSxlLnByb3RvdHlwZS5BPWZ1bmN0aW9uKHQpe1widW5kZWZpbmVkXCIhPXR5cGVvZiB0aGlzLmV0JiZ0aGlzLmV0IT09dCYmKHRoaXMuXyh0KSx0aGlzLmV0PXQpfSxlLnByb3RvdHlwZS5pdD1mdW5jdGlvbigpe3ZhciB0PXRoaXMuJCgpO3JldHVybiB0PT09U3RyZWFtUHJvdG9jb2wuWT90aGlzLnBsYXllci5nZXRDb25maWcoKS5zb3VyY2UuaGxzOnQ9PT1TdHJlYW1Qcm90b2NvbC5ydD90aGlzLnBsYXllci5nZXRDb25maWcoKS5zb3VyY2UuZGFzaDp2b2lkIDB9LGUucHJvdG90eXBlLmdldEN1cnJlbnRUaW1lPWZ1bmN0aW9uKCl7cmV0dXJuIG51bGwhPXRoaXMucGxheWVyP01hdGgucm91bmQoMWUzKnRoaXMucGxheWVyLmdldEN1cnJlbnRUaW1lKCkpOjB9LGUucHJvdG90eXBlLm50PWZ1bmN0aW9uKCl7cmV0dXJuIG51bGwhPXRoaXMucGxheWVyJiZudWxsIT10aGlzLnBsYXllci5nZXRWaWRlb0J1ZmZlckxlbmd0aCYmdGhpcy5wbGF5ZXIuZ2V0VmlkZW9CdWZmZXJMZW5ndGgoKT4wP01hdGgubWF4KDAsTWF0aC5yb3VuZCgxZTMqdGhpcy5wbGF5ZXIuZ2V0VmlkZW9CdWZmZXJMZW5ndGgoKSkpOjB9LGUucHJvdG90eXBlLm90PWZ1bmN0aW9uKCl7aWYodGhpcy5wbGF5ZXIpe3ZhciB0PXRoaXMucGxheWVyLmdldEZpZ3VyZSgpO3JldHVybnt3aWR0aDp0Lm9mZnNldFdpZHRoLGhlaWdodDp0Lm9mZnNldEhlaWdodH19fSxlLnByb3RvdHlwZS5pc0Z1bGxzY3JlZW49ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5wbGF5ZXIuaXNGdWxsc2NyZWVuKCl9LGUucHJvdG90eXBlLmlzTGl2ZT1mdW5jdGlvbigpe3JldHVybiB0aGlzLnBsYXllci5pc0xpdmUoKX0sZS5wcm90b3R5cGUuc3Q9ZnVuY3Rpb24oKXtyZXR1cm4hMH0sZS5wcm90b3R5cGUuJD1mdW5jdGlvbigpe2lmKHRoaXMucGxheWVyKXt2YXIgdD10aGlzLnBsYXllci5nZXRTdHJlYW1UeXBlKCk7aWYoXCJobHNcIj09PXQpcmV0dXJuIFN0cmVhbVByb3RvY29sLlk7aWYoXCJkYXNoXCI9PT10KXJldHVybiBTdHJlYW1Qcm90b2NvbC5ydH1yZXR1cm4gbnVsbH0sZS5wcm90b3R5cGUuYXQ9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLk87cmV0dXJuIHRoaXMuTz1uZXcgby5QLHR9LGUucHJvdG90eXBlLlQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5wbHVnaW5OYW1lfSxlLnByb3RvdHlwZS5JPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuY3QoKX0sZS5wcm90b3R5cGUuaHQ9ZnVuY3Rpb24oKXtpZih0aGlzLnBsYXllcilyZXR1cm4gdGhpcy5wbGF5ZXIuZ2V0UGxheWVyVHlwZSgpfSxlLnByb3RvdHlwZS5xPWZ1bmN0aW9uKCl7cmV0dXJuXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGJpdG1vdmluLnBsYXllci52ZXJzaW9uP2JpdG1vdmluLnBsYXllci52ZXJzaW9uOnRoaXMucGxheWVyLmdldFZlcnNpb24oKX0sZX0obi5wdC5QbHVnaW4pO2UudXQ9aDt2YXIgcD1mdW5jdGlvbih0LGUpe25ldyBoKHQsZSl9O2JpdG1vdmluLmluaXRIaXZlU0ROPXB9LGZ1bmN0aW9uKHQsZSxpKXsvKiFcbiAqXG4gKiBDb3B5cmlnaHQgMjAwOS0yMDE2IEtyaXMgS293YWwgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBNSVRcbiAqIGxpY2Vuc2UgZm91bmQgYXQgaHR0cHM6Ly9naXRodWIuY29tL2tyaXNrb3dhbC9xL2Jsb2IvdjEvTElDRU5TRVxuICpcbiAqIFdpdGggcGFydHMgYnkgVHlsZXIgQ2xvc2VcbiAqIENvcHlyaWdodCAyMDA3LTIwMDkgVHlsZXIgQ2xvc2UgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBNSVQgWCBsaWNlbnNlIGZvdW5kXG4gKiBhdCBodHRwOi8vd3d3Lm9wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLmh0bWxcbiAqIEZvcmtlZCBhdCByZWZfc2VuZC5qcyB2ZXJzaW9uOiAyMDA5LTA1LTExXG4gKlxuICogV2l0aCBwYXJ0cyBieSBNYXJrIE1pbGxlclxuICogQ29weXJpZ2h0IChDKSAyMDExIEdvb2dsZSBJbmMuXG4gKlxuICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlIFwiTGljZW5zZVwiKTtcbiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS5cbiAqIFlvdSBtYXkgb2J0YWluIGEgY29weSBvZiB0aGUgTGljZW5zZSBhdFxuICpcbiAqIGh0dHA6Ly93d3cuYXBhY2hlLm9yZy9saWNlbnNlcy9MSUNFTlNFLTIuMFxuICpcbiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmVcbiAqIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSBMaWNlbnNlIGlzIGRpc3RyaWJ1dGVkIG9uIGFuIFwiQVMgSVNcIiBCQVNJUyxcbiAqIFdJVEhPVVQgV0FSUkFOVElFUyBPUiBDT05ESVRJT05TIE9GIEFOWSBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLlxuICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZFxuICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKlxuICovXG4gICFmdW5jdGlvbihlKXtcInVzZSBzdHJpY3RcIjtpZihcImZ1bmN0aW9uXCI9PXR5cGVvZiBib290c3RyYXApYm9vdHN0cmFwKFwicHJvbWlzZVwiLGUpO2Vsc2V7dC50PWUoKX19KGZ1bmN0aW9uKCl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gdCh0KXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gei5hcHBseSh0LGFyZ3VtZW50cyl9fWZ1bmN0aW9uIGUodCl7cmV0dXJuIHQ9PT1PYmplY3QodCl9ZnVuY3Rpb24gaSh0KXtyZXR1cm5cIltvYmplY3QgU3RvcEl0ZXJhdGlvbl1cIj09PWl0KHQpfHx0IGluc3RhbmNlb2YgcX1mdW5jdGlvbiByKHQsZSl7aWYoVSYmZS5zdGFjayYmXCJvYmplY3RcIj09dHlwZW9mIHQmJm51bGwhPT10JiZ0LnN0YWNrJiZ0LnN0YWNrLmluZGV4T2YocnQpPT09LTEpe2Zvcih2YXIgaT1bXSxyPWU7cjtyPXIuc291cmNlKXIuc3RhY2smJmkudW5zaGlmdChyLnN0YWNrKTtpLnVuc2hpZnQodC5zdGFjayk7dmFyIG89aS5qb2luKFwiXFxuXCIrcnQrXCJcXG5cIik7dC5zdGFjaz1uKG8pfX1mdW5jdGlvbiBuKHQpe2Zvcih2YXIgZT10LnNwbGl0KFwiXFxuXCIpLGk9W10scj0wO3I8ZS5sZW5ndGg7KytyKXt2YXIgbj1lW3JdO2Eobil8fG8obil8fCFufHxpLnB1c2gobil9cmV0dXJuIGkuam9pbihcIlxcblwiKX1mdW5jdGlvbiBvKHQpe3JldHVybiB0LmluZGV4T2YoXCIobW9kdWxlLmpzOlwiKSE9PS0xfHx0LmluZGV4T2YoXCIobm9kZS5qczpcIikhPT0tMX1mdW5jdGlvbiBzKHQpe3ZhciBlPS9hdCAuKyBcXCgoLispOihcXGQrKTooPzpcXGQrKVxcKSQvLmV4ZWModCk7aWYoZSlyZXR1cm5bZVsxXSxOdW1iZXIoZVsyXSldO3ZhciBpPS9hdCAoW14gXSspOihcXGQrKTooPzpcXGQrKSQvLmV4ZWModCk7aWYoaSlyZXR1cm5baVsxXSxOdW1iZXIoaVsyXSldO3ZhciByPS8uKkAoLispOihcXGQrKSQvLmV4ZWModCk7cmV0dXJuIHI/W3JbMV0sTnVtYmVyKHJbMl0pXTp2b2lkIDB9ZnVuY3Rpb24gYSh0KXt2YXIgZT1zKHQpO2lmKCFlKXJldHVybiExO3ZhciBpPWVbMF0scj1lWzFdO3JldHVybiBpPT09USYmcj49SiYmcjw9Y3R9ZnVuY3Rpb24gYygpe2lmKFUpdHJ5e3Rocm93IG5ldyBFcnJvcn1jYXRjaCh0KXt2YXIgZT10LnN0YWNrLnNwbGl0KFwiXFxuXCIpLGk9ZVswXS5pbmRleE9mKFwiQFwiKT4wP2VbMV06ZVsyXSxyPXMoaSk7aWYoIXIpcmV0dXJuO3JldHVybiBRPXJbMF0sclsxXX19ZnVuY3Rpb24gaCh0LGUsaSl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGNvbnNvbGUmJlwiZnVuY3Rpb25cIj09dHlwZW9mIGNvbnNvbGUud2FybiYmY29uc29sZS53YXJuKGUrXCIgaXMgZGVwcmVjYXRlZCwgdXNlIFwiK2krXCIgaW5zdGVhZC5cIixuZXcgRXJyb3IoXCJcIikuc3RhY2spLHQuYXBwbHkodCxhcmd1bWVudHMpfX1mdW5jdGlvbiBwKHQpe3JldHVybiB0IGluc3RhbmNlb2YgZj90Om0odCk/Qyh0KTprKHQpfWZ1bmN0aW9uIHUoKXtmdW5jdGlvbiB0KHQpe2U9dCxwLmx0JiZVJiYoby5zb3VyY2U9dCksJChpLGZ1bmN0aW9uKGUsaSl7cC5kdChmdW5jdGlvbigpe3QuZnQuYXBwbHkodCxpKX0pfSx2b2lkIDApLGk9dm9pZCAwLHI9dm9pZCAwfXZhciBlLGk9W10scj1bXSxuPVoodS5wcm90b3R5cGUpLG89WihmLnByb3RvdHlwZSk7aWYoby5mdD1mdW5jdGlvbih0LG4sbyl7dmFyIHM9Vyhhcmd1bWVudHMpO2k/KGkucHVzaChzKSxcIndoZW5cIj09PW4mJm9bMV0mJnIucHVzaChvWzFdKSk6cC5kdChmdW5jdGlvbigpe2UuZnQuYXBwbHkoZSxzKX0pfSxvLnZhbHVlT2Y9ZnVuY3Rpb24oKXtpZihpKXJldHVybiBvO3ZhciB0PXYoZSk7cmV0dXJuIHkodCkmJihlPXQpLHR9LG8uZ3Q9ZnVuY3Rpb24oKXtyZXR1cm4gZT9lLmd0KCk6e3N0YXRlOlwicGVuZGluZ1wifX0scC5sdCYmVSl0cnl7dGhyb3cgbmV3IEVycm9yfWNhdGNoKHMpe28uc3RhY2s9cy5zdGFjay5zdWJzdHJpbmcocy5zdGFjay5pbmRleE9mKFwiXFxuXCIpKzEpfXJldHVybiBuLnZ0PW8sbi5yZXNvbHZlPWZ1bmN0aW9uKGkpe2V8fHQocChpKSl9LG4ueXQ9ZnVuY3Rpb24oaSl7ZXx8dChrKGkpKX0sbi5yZWplY3Q9ZnVuY3Rpb24oaSl7ZXx8dChSKGkpKX0sbi5ub3RpZnk9ZnVuY3Rpb24odCl7ZXx8JChyLGZ1bmN0aW9uKGUsaSl7cC5kdChmdW5jdGlvbigpe2kodCl9KX0sdm9pZCAwKX0sbn1mdW5jdGlvbiBsKHQpe2lmKFwiZnVuY3Rpb25cIiE9dHlwZW9mIHQpdGhyb3cgbmV3IFR5cGVFcnJvcihcInJlc29sdmVyIG11c3QgYmUgYSBmdW5jdGlvbi5cIik7dmFyIGU9dSgpO3RyeXt0KGUucmVzb2x2ZSxlLnJlamVjdCxlLm5vdGlmeSl9Y2F0Y2goaSl7ZS5yZWplY3QoaSl9cmV0dXJuIGUudnR9ZnVuY3Rpb24gZCh0KXtyZXR1cm4gbChmdW5jdGlvbihlLGkpe2Zvcih2YXIgcj0wLG49dC5sZW5ndGg7cjxuO3IrKylwKHRbcl0pLnRoZW4oZSxpKX0pfWZ1bmN0aW9uIGYodCxlLGkpe3ZvaWQgMD09PWUmJihlPWZ1bmN0aW9uKHQpe3JldHVybiBSKG5ldyBFcnJvcihcIlByb21pc2UgZG9lcyBub3Qgc3VwcG9ydCBvcGVyYXRpb246IFwiK3QpKX0pLHZvaWQgMD09PWkmJihpPWZ1bmN0aW9uKCl7cmV0dXJue3N0YXRlOlwidW5rbm93blwifX0pO3ZhciByPVooZi5wcm90b3R5cGUpO2lmKHIuZnQ9ZnVuY3Rpb24oaSxuLG8pe3ZhciBzO3RyeXtzPXRbbl0/dFtuXS5hcHBseShyLG8pOmUuY2FsbChyLG4sbyl9Y2F0Y2goYSl7cz1SKGEpfWkmJmkocyl9LHIuZ3Q9aSxpKXt2YXIgbj1pKCk7XCJyZWplY3RlZFwiPT09bi5zdGF0ZSYmKHIuZXhjZXB0aW9uPW4ucmVhc29uKSxyLnZhbHVlT2Y9ZnVuY3Rpb24oKXt2YXIgdD1pKCk7cmV0dXJuXCJwZW5kaW5nXCI9PT10LnN0YXRlfHxcInJlamVjdGVkXCI9PT10LnN0YXRlP3I6dC52YWx1ZX19cmV0dXJuIHJ9ZnVuY3Rpb24gZyh0LGUsaSxyKXtyZXR1cm4gcCh0KS50aGVuKGUsaSxyKX1mdW5jdGlvbiB2KHQpe2lmKHkodCkpe3ZhciBlPXQuZ3QoKTtpZihcImZ1bGZpbGxlZFwiPT09ZS5zdGF0ZSlyZXR1cm4gZS52YWx1ZX1yZXR1cm4gdH1mdW5jdGlvbiB5KHQpe3JldHVybiB0IGluc3RhbmNlb2YgZn1mdW5jdGlvbiBtKHQpe3JldHVybiBlKHQpJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiB0LnRoZW59ZnVuY3Rpb24gdyh0KXtyZXR1cm4geSh0KSYmXCJwZW5kaW5nXCI9PT10Lmd0KCkuc3RhdGV9ZnVuY3Rpb24gVCh0KXtyZXR1cm4heSh0KXx8XCJmdWxmaWxsZWRcIj09PXQuZ3QoKS5zdGF0ZX1mdW5jdGlvbiBTKHQpe3JldHVybiB5KHQpJiZcInJlamVjdGVkXCI9PT10Lmd0KCkuc3RhdGV9ZnVuY3Rpb24gYigpe250Lmxlbmd0aD0wLG90Lmxlbmd0aD0wLGF0fHwoYXQ9ITApfWZ1bmN0aW9uIEUodCxlKXthdCYmKFwib2JqZWN0XCI9PXR5cGVvZiBwcm9jZXNzJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBwcm9jZXNzLmVtaXQmJnAuZHQud3QoZnVuY3Rpb24oKXtZKG90LHQpIT09LTEmJihwcm9jZXNzLmVtaXQoXCJ1bmhhbmRsZWRSZWplY3Rpb25cIixlLHQpLHN0LnB1c2godCkpfSksb3QucHVzaCh0KSxlJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgZS5zdGFjaz9udC5wdXNoKGUuc3RhY2spOm50LnB1c2goXCIobm8gc3RhY2spIFwiK2UpKX1mdW5jdGlvbiBJKHQpe2lmKGF0KXt2YXIgZT1ZKG90LHQpO2UhPT0tMSYmKFwib2JqZWN0XCI9PXR5cGVvZiBwcm9jZXNzJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBwcm9jZXNzLmVtaXQmJnAuZHQud3QoZnVuY3Rpb24oKXt2YXIgaT1ZKHN0LHQpO2khPT0tMSYmKHByb2Nlc3MuZW1pdChcInJlamVjdGlvbkhhbmRsZWRcIixudFtlXSx0KSxzdC5zcGxpY2UoaSwxKSl9KSxvdC5zcGxpY2UoZSwxKSxudC5zcGxpY2UoZSwxKSl9fWZ1bmN0aW9uIFIodCl7dmFyIGU9Zih7d2hlbjpmdW5jdGlvbihlKXtyZXR1cm4gZSYmSSh0aGlzKSxlP2UodCk6dGhpc319LGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXN9LGZ1bmN0aW9uKCl7cmV0dXJue3N0YXRlOlwicmVqZWN0ZWRcIixyZWFzb246dH19KTtyZXR1cm4gRShlLHQpLGV9ZnVuY3Rpb24gayh0KXtyZXR1cm4gZih7d2hlbjpmdW5jdGlvbigpe3JldHVybiB0fSxnZXQ6ZnVuY3Rpb24oZSl7cmV0dXJuIHRbZV19LHNldDpmdW5jdGlvbihlLGkpe3RbZV09aX0sXCJkZWxldGVcIjpmdW5jdGlvbihlKXtkZWxldGUgdFtlXX0sVHQ6ZnVuY3Rpb24oZSxpKXtyZXR1cm4gbnVsbD09PWV8fHZvaWQgMD09PWU/dC5hcHBseSh2b2lkIDAsaSk6dFtlXS5hcHBseSh0LGkpfSxhcHBseTpmdW5jdGlvbihlLGkpe3JldHVybiB0LmFwcGx5KGUsaSl9LGtleXM6ZnVuY3Rpb24oKXtyZXR1cm4gZXQodCl9fSx2b2lkIDAsZnVuY3Rpb24oKXtyZXR1cm57c3RhdGU6XCJmdWxmaWxsZWRcIix2YWx1ZTp0fX0pfWZ1bmN0aW9uIEModCl7dmFyIGU9dSgpO3JldHVybiBwLmR0KGZ1bmN0aW9uKCl7dHJ5e3QudGhlbihlLnJlc29sdmUsZS5yZWplY3QsZS5ub3RpZnkpfWNhdGNoKGkpe2UucmVqZWN0KGkpfX0pLGUudnR9ZnVuY3Rpb24gTyh0KXtyZXR1cm4gZih7U3Q6ZnVuY3Rpb24oKXt9fSxmdW5jdGlvbihlLGkpe3JldHVybiBGKHQsZSxpKX0sZnVuY3Rpb24oKXtyZXR1cm4gcCh0KS5ndCgpfSl9ZnVuY3Rpb24gUCh0LGUsaSl7cmV0dXJuIHAodCkuYnQoZSxpKX1mdW5jdGlvbiBBKHQpe3JldHVybiBmdW5jdGlvbigpe2Z1bmN0aW9uIGUodCxlKXt2YXIgcztpZihcInVuZGVmaW5lZFwiPT10eXBlb2YgU3RvcEl0ZXJhdGlvbil7dHJ5e3M9clt0XShlKX1jYXRjaChhKXtyZXR1cm4gUihhKX1yZXR1cm4gcy5kb25lP3Aocy52YWx1ZSk6ZyhzLnZhbHVlLG4sbyl9dHJ5e3M9clt0XShlKX1jYXRjaChhKXtyZXR1cm4gaShhKT9wKGEudmFsdWUpOlIoYSl9cmV0dXJuIGcocyxuLG8pfXZhciByPXQuYXBwbHkodGhpcyxhcmd1bWVudHMpLG49ZS5iaW5kKGUsXCJuZXh0XCIpLG89ZS5iaW5kKGUsXCJ0aHJvd1wiKTtyZXR1cm4gbigpfX1mdW5jdGlvbiBOKHQpe3AuZG9uZShwLmFzeW5jKHQpKCkpfWZ1bmN0aW9uIHgodCl7dGhyb3cgbmV3IHEodCl9ZnVuY3Rpb24gQih0KXtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gUChbdGhpcyxfKGFyZ3VtZW50cyldLGZ1bmN0aW9uKGUsaSl7cmV0dXJuIHQuYXBwbHkoZSxpKX0pfX1mdW5jdGlvbiBGKHQsZSxpKXtyZXR1cm4gcCh0KS5FdChlLGkpfWZ1bmN0aW9uIF8odCl7cmV0dXJuIGcodCxmdW5jdGlvbih0KXt2YXIgZT0wLGk9dSgpO3JldHVybiAkKHQsZnVuY3Rpb24ocixuLG8pe3ZhciBzO3kobikmJlwiZnVsZmlsbGVkXCI9PT0ocz1uLmd0KCkpLnN0YXRlP3Rbb109cy52YWx1ZTooKytlLGcobixmdW5jdGlvbihyKXt0W29dPXIsMD09PS0tZSYmaS5yZXNvbHZlKHQpfSxpLnJlamVjdCxmdW5jdGlvbih0KXtpLm5vdGlmeSh7aW5kZXg6byx2YWx1ZTp0fSl9KSl9LHZvaWQgMCksMD09PWUmJmkucmVzb2x2ZSh0KSxpLnZ0fSl9ZnVuY3Rpb24gRCh0KXtpZigwPT09dC5sZW5ndGgpcmV0dXJuIHAucmVzb2x2ZSgpO3ZhciBlPXAuZGVmZXIoKSxpPTA7cmV0dXJuICQodCxmdW5jdGlvbihyLG4sbyl7ZnVuY3Rpb24gcyh0KXtlLnJlc29sdmUodCl9ZnVuY3Rpb24gYSh0KXtpLS0sMD09PWkmJih0Lm1lc3NhZ2U9XCJRIGNhbid0IGdldCBmdWxmaWxsbWVudCB2YWx1ZSBmcm9tIGFueSBwcm9taXNlLCBhbGwgcHJvbWlzZXMgd2VyZSByZWplY3RlZC4gTGFzdCBlcnJvciBtZXNzYWdlOiBcIit0Lm1lc3NhZ2UsZS5yZWplY3QodCkpfWZ1bmN0aW9uIGModCl7ZS5ub3RpZnkoe2luZGV4Om8sdmFsdWU6dH0pfXZhciBoPXRbb107aSsrLGcoaCxzLGEsYyl9LHZvaWQgMCksZS52dH1mdW5jdGlvbiBIKHQpe3JldHVybiBnKHQsZnVuY3Rpb24odCl7cmV0dXJuIHQ9WCh0LHApLGcoXyhYKHQsZnVuY3Rpb24odCl7cmV0dXJuIGcodCxLLEspfSkpLGZ1bmN0aW9uKCl7cmV0dXJuIHR9KX0pfWZ1bmN0aW9uIEwodCl7cmV0dXJuIHAodCkuSXQoKX1mdW5jdGlvbiBNKHQsZSl7cmV0dXJuIHAodCkudGhlbih2b2lkIDAsdm9pZCAwLGUpfWZ1bmN0aW9uIGoodCxlKXtyZXR1cm4gcCh0KS5SdChlKX12YXIgVT0hMTt0cnl7dGhyb3cgbmV3IEVycm9yfWNhdGNoKFYpe1U9ISFWLnN0YWNrfXZhciBRLHEsSj1jKCksSz1mdW5jdGlvbigpe30sRz1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXtmb3IodmFyIHQscjtpLm5leHQ7KWk9aS5uZXh0LHQ9aS5rdCxpLmt0PXZvaWQgMCxyPWkuZG9tYWluLHImJihpLmRvbWFpbj12b2lkIDAsci5lbnRlcigpKSxlKHQscik7Zm9yKDtoLmxlbmd0aDspdD1oLnBvcCgpLGUodCk7bj0hMX1mdW5jdGlvbiBlKGUsaSl7dHJ5e2UoKX1jYXRjaChyKXtpZihzKXRocm93IGkmJmkuZXhpdCgpLHNldFRpbWVvdXQodCwwKSxpJiZpLmVudGVyKCkscjtzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dGhyb3cgcn0sMCl9aSYmaS5leGl0KCl9dmFyIGk9e2t0OnZvaWQgMCxuZXh0Om51bGx9LHI9aSxuPSExLG89dm9pZCAwLHM9ITEsYT0hMTt0cnl7YT1uYXZpZ2F0b3ImJihcIk1pY3Jvc29mdCBJbnRlcm5ldCBFeHBsb3JlclwiPT09bmF2aWdhdG9yLmFwcE5hbWV8fG51bGwhPW5hdmlnYXRvci5hcHBWZXJzaW9uLm1hdGNoKC8odHJpZGVudCkuK3J2WzpcXHNdKFtcXHdcXC5dKykuK2xpa2VcXHNnZWNrby9pKSl9Y2F0Y2goYyl7fXZhciBoPVtdO2lmKEc9ZnVuY3Rpb24odCl7XCJ1bmRlZmluZWRcIiE9dHlwZW9mIEZyYW1ld29yayYmRnJhbWV3b3JrLkN0KCk/RnJhbWV3b3JrLnNldFRpbWVvdXQodCwwKToocj1yLm5leHQ9e2t0OnQsZG9tYWluOnMmJnByb2Nlc3MuZG9tYWluLG5leHQ6bnVsbH0sbnx8KG49ITAsbygpKSl9LFwib2JqZWN0XCI9PXR5cGVvZiBwcm9jZXNzJiZcIltvYmplY3QgcHJvY2Vzc11cIj09PXByb2Nlc3MudG9TdHJpbmcoKSYmcHJvY2Vzcy5kdClzPSEwLG89ZnVuY3Rpb24oKXtwcm9jZXNzLmR0KHQpfTtlbHNlIGlmKFwiZnVuY3Rpb25cIiE9dHlwZW9mIHNldEltbWVkaWF0ZXx8YSlpZihcInVuZGVmaW5lZFwiPT10eXBlb2YgTWVzc2FnZUNoYW5uZWx8fGEpbz1mdW5jdGlvbigpe3NldFRpbWVvdXQodCwwKX07ZWxzZXt2YXIgcD1uZXcgTWVzc2FnZUNoYW5uZWw7cC5wb3J0MS5vbm1lc3NhZ2U9ZnVuY3Rpb24oKXtvPXUscC5wb3J0MS5vbm1lc3NhZ2U9dCx0KCl9O3ZhciB1PWZ1bmN0aW9uKCl7cC5wb3J0Mi5wb3N0TWVzc2FnZSgwKX07bz1mdW5jdGlvbigpe3NldFRpbWVvdXQodCwwKSx1KCl9fWVsc2Ugbz1cInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93P3NldEltbWVkaWF0ZS5iaW5kKHdpbmRvdyx0KTpmdW5jdGlvbigpe3NldEltbWVkaWF0ZSh0KX07cmV0dXJuIEcud3Q9ZnVuY3Rpb24odCl7aC5wdXNoKHQpLG58fChuPSEwLG8oKSl9LEd9KCksej1GdW5jdGlvbi5jYWxsLFc9dChBcnJheS5wcm90b3R5cGUuc2xpY2UpLCQ9dChBcnJheS5wcm90b3R5cGUucmVkdWNlfHxmdW5jdGlvbih0LGUpe3ZhciBpPTAscj10aGlzLmxlbmd0aDtpZigxPT09YXJndW1lbnRzLmxlbmd0aClmb3IoOzspe2lmKGkgaW4gdGhpcyl7ZT10aGlzW2krK107YnJlYWt9aWYoKytpPj1yKXRocm93IG5ldyBUeXBlRXJyb3J9Zm9yKDtpPHI7aSsrKWkgaW4gdGhpcyYmKGU9dChlLHRoaXNbaV0saSkpO3JldHVybiBlfSksWT10KEFycmF5LnByb3RvdHlwZS5pbmRleE9mfHxmdW5jdGlvbih0KXtmb3IodmFyIGU9MDtlPHRoaXMubGVuZ3RoO2UrKylpZih0aGlzW2VdPT09dClyZXR1cm4gZTtyZXR1cm4tMX0pLFg9dChBcnJheS5wcm90b3R5cGUubWFwfHxmdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMscj1bXTtyZXR1cm4gJChpLGZ1bmN0aW9uKG4sbyxzKXtyLnB1c2godC5jYWxsKGUsbyxzLGkpKX0sdm9pZCAwKSxyfSksWj1PYmplY3QuY3JlYXRlfHxmdW5jdGlvbih0KXtmdW5jdGlvbiBlKCl7fXJldHVybiBlLnByb3RvdHlwZT10LG5ldyBlfSx0dD10KE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkpLGV0PU9iamVjdC5rZXlzfHxmdW5jdGlvbih0KXt2YXIgZT1bXTtmb3IodmFyIGkgaW4gdCl0dCh0LGkpJiZlLnB1c2goaSk7cmV0dXJuIGV9LGl0PXQoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZyk7cT1cInVuZGVmaW5lZFwiIT10eXBlb2YgUmV0dXJuVmFsdWU/UmV0dXJuVmFsdWU6ZnVuY3Rpb24odCl7dGhpcy52YWx1ZT10fTt2YXIgcnQ9XCJGcm9tIHByZXZpb3VzIGV2ZW50OlwiO3AucmVzb2x2ZT1wLHAuZHQ9RyxwLmx0PSExLFwib2JqZWN0XCI9PXR5cGVvZiBwcm9jZXNzJiZwcm9jZXNzJiZwcm9jZXNzLk90JiZwcm9jZXNzLk90LlFfREVCVUcmJihwLmx0PSEwKSxwLmRlZmVyPXUsdS5wcm90b3R5cGUuUHQ9ZnVuY3Rpb24oKXt2YXIgdD10aGlzO3JldHVybiBmdW5jdGlvbihlLGkpe2U/dC5yZWplY3QoZSk6YXJndW1lbnRzLmxlbmd0aD4yP3QucmVzb2x2ZShXKGFyZ3VtZW50cywxKSk6dC5yZXNvbHZlKGkpfX0scC5Qcm9taXNlPWwscC52dD1sLGwucmFjZT1kLGwuYWxsPV8sbC5yZWplY3Q9UixsLnJlc29sdmU9cCxwLkF0PWZ1bmN0aW9uKHQpe3JldHVybiB0fSxmLnByb3RvdHlwZS5BdD1mdW5jdGlvbigpe3JldHVybiB0aGlzfSxwLmpvaW49ZnVuY3Rpb24odCxlKXtyZXR1cm4gcCh0KS5qb2luKGUpfSxmLnByb3RvdHlwZS5qb2luPWZ1bmN0aW9uKHQpe3JldHVybiBwKFt0aGlzLHRdKS5idChmdW5jdGlvbih0LGUpe2lmKHQ9PT1lKXJldHVybiB0O3Rocm93IG5ldyBFcnJvcihcIlEgY2FuJ3Qgam9pbjogbm90IHRoZSBzYW1lOiBcIit0K1wiIFwiK2UpfSl9LHAucmFjZT1kLGYucHJvdG90eXBlLnJhY2U9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aGVuKHAucmFjZSl9LHAuTnQ9ZixmLnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVyblwiW29iamVjdCBQcm9taXNlXVwifSxmLnByb3RvdHlwZS50aGVuPWZ1bmN0aW9uKHQsZSxpKXtmdW5jdGlvbiBuKGUpe3RyeXtyZXR1cm5cImZ1bmN0aW9uXCI9PXR5cGVvZiB0P3QoZSk6ZX1jYXRjaChpKXtyZXR1cm4gUihpKX19ZnVuY3Rpb24gbyh0KXtpZihcImZ1bmN0aW9uXCI9PXR5cGVvZiBlKXtyKHQsYSk7dHJ5e3JldHVybiBlKHQpfWNhdGNoKGkpe3JldHVybiBSKGkpfX1yZXR1cm4gUih0KX1mdW5jdGlvbiBzKHQpe3JldHVyblwiZnVuY3Rpb25cIj09dHlwZW9mIGk/aSh0KTp0fXZhciBhPXRoaXMsYz11KCksaD0hMTtyZXR1cm4gcC5kdChmdW5jdGlvbigpe2EuZnQoZnVuY3Rpb24odCl7aHx8KGg9ITAsYy5yZXNvbHZlKG4odCkpKX0sXCJ3aGVuXCIsW2Z1bmN0aW9uKHQpe2h8fChoPSEwLGMucmVzb2x2ZShvKHQpKSl9XSl9KSxhLmZ0KHZvaWQgMCxcIndoZW5cIixbdm9pZCAwLGZ1bmN0aW9uKHQpe3ZhciBlLGk9ITE7dHJ5e2U9cyh0KX1jYXRjaChyKXtpZihpPSEwLCFwLm9uZXJyb3IpdGhyb3cgcjtwLm9uZXJyb3Iocil9aXx8Yy5ub3RpZnkoZSl9XSksYy52dH0scC54dD1mdW5jdGlvbih0LGUpe3JldHVybiBwKHQpLnh0KGUpfSxmLnByb3RvdHlwZS54dD1mdW5jdGlvbih0KXtyZXR1cm4gdD1wKHQpLHRoaXMudGhlbihmdW5jdGlvbihlKXtyZXR1cm4gdC5GdChlKS5CdChlKX0pfSxwLndoZW49ZyxmLnByb3RvdHlwZS5CdD1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIHR9KX0scC5CdD1mdW5jdGlvbih0LGUpe3JldHVybiBwKHQpLkJ0KGUpfSxmLnByb3RvdHlwZS5fdD1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uKCl7dGhyb3cgdH0pfSxwLl90PWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHAodCkuX3QoZSl9LHAuRHQ9dixwLkh0PXkscC5MdD1tLHAuTXQ9dyxmLnByb3RvdHlwZS5NdD1mdW5jdGlvbigpe3JldHVyblwicGVuZGluZ1wiPT09dGhpcy5ndCgpLnN0YXRlfSxwLmp0PVQsZi5wcm90b3R5cGUuanQ9ZnVuY3Rpb24oKXtyZXR1cm5cImZ1bGZpbGxlZFwiPT09dGhpcy5ndCgpLnN0YXRlfSxwLlV0PVMsZi5wcm90b3R5cGUuVXQ9ZnVuY3Rpb24oKXtyZXR1cm5cInJlamVjdGVkXCI9PT10aGlzLmd0KCkuc3RhdGV9O3ZhciBudD1bXSxvdD1bXSxzdD1bXSxhdD0hMDtwLlZ0PWIscC5RdD1mdW5jdGlvbigpe3JldHVybiBudC5zbGljZSgpfSxwLnF0PWZ1bmN0aW9uKCl7YigpLGF0PSExfSxiKCkscC5yZWplY3Q9UixwLnl0PWsscC5KdD1PLHAuYnQ9UCxmLnByb3RvdHlwZS5idD1mdW5jdGlvbih0LGUpe3JldHVybiB0aGlzLmFsbCgpLnRoZW4oZnVuY3Rpb24oZSl7cmV0dXJuIHQuYXBwbHkodm9pZCAwLGUpfSxlKX0scC5hc3luYz1BLHAuS3Q9TixwW1wiR3RcIl09eCxwLnp0PUIscC5FdD1GLGYucHJvdG90eXBlLkV0PWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcyxyPXUoKTtyZXR1cm4gcC5kdChmdW5jdGlvbigpe2kuZnQoci5yZXNvbHZlLHQsZSl9KSxyLnZ0fSxwLmdldD1mdW5jdGlvbih0LGUpe3JldHVybiBwKHQpLkV0KFwiZ2V0XCIsW2VdKX0sZi5wcm90b3R5cGUuZ2V0PWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLkV0KFwiZ2V0XCIsW3RdKX0scC5zZXQ9ZnVuY3Rpb24odCxlLGkpe3JldHVybiBwKHQpLkV0KFwic2V0XCIsW2UsaV0pfSxmLnByb3RvdHlwZS5zZXQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5FdChcInNldFwiLFt0LGVdKX0scC5XdD1wW1wiZGVsZXRlXCJdPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHAodCkuRXQoXCJkZWxldGVcIixbZV0pfSxmLnByb3RvdHlwZS5XdD1mLnByb3RvdHlwZVtcImRlbGV0ZVwiXT1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5FdChcImRlbGV0ZVwiLFt0XSl9LHAuJHQ9cC5UdD1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIHAodCkuRXQoXCJwb3N0XCIsW2UsaV0pfSxmLnByb3RvdHlwZS4kdD1mLnByb3RvdHlwZS5UdD1mdW5jdGlvbih0LGUpe3JldHVybiB0aGlzLkV0KFwicG9zdFwiLFt0LGVdKX0scC5zZW5kPXAuWXQ9cC5YdD1mdW5jdGlvbih0LGUpe3JldHVybiBwKHQpLkV0KFwicG9zdFwiLFtlLFcoYXJndW1lbnRzLDIpXSl9LGYucHJvdG90eXBlLnNlbmQ9Zi5wcm90b3R5cGUuWXQ9Zi5wcm90b3R5cGUuWHQ9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuRXQoXCJwb3N0XCIsW3QsVyhhcmd1bWVudHMsMSldKX0scC5adD1mdW5jdGlvbih0LGUpe3JldHVybiBwKHQpLkV0KFwiYXBwbHlcIixbdm9pZCAwLGVdKX0sZi5wcm90b3R5cGUuWnQ9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuRXQoXCJhcHBseVwiLFt2b2lkIDAsdF0pfSxwW1widGVcIl09cC5GdD1mdW5jdGlvbih0KXtyZXR1cm4gcCh0KS5FdChcImFwcGx5XCIsW3ZvaWQgMCxXKGFyZ3VtZW50cywxKV0pfSxmLnByb3RvdHlwZS5GdD1mdW5jdGlvbigpe3JldHVybiB0aGlzLkV0KFwiYXBwbHlcIixbdm9pZCAwLFcoYXJndW1lbnRzKV0pfSxwLmVlPWZ1bmN0aW9uKHQpe3ZhciBlPXAodCksaT1XKGFyZ3VtZW50cywxKTtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZS5FdChcImFwcGx5XCIsW3RoaXMsaS5jb25jYXQoVyhhcmd1bWVudHMpKV0pfX0sZi5wcm90b3R5cGUuZWU9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLGU9Vyhhcmd1bWVudHMpO3JldHVybiBmdW5jdGlvbigpe3JldHVybiB0LkV0KFwiYXBwbHlcIixbdGhpcyxlLmNvbmNhdChXKGFyZ3VtZW50cykpXSl9fSxwLmtleXM9ZnVuY3Rpb24odCl7cmV0dXJuIHAodCkuRXQoXCJrZXlzXCIsW10pfSxmLnByb3RvdHlwZS5rZXlzPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuRXQoXCJrZXlzXCIsW10pfSxwLmFsbD1fLGYucHJvdG90eXBlLmFsbD1mdW5jdGlvbigpe3JldHVybiBfKHRoaXMpfSxwLmllPUQsZi5wcm90b3R5cGUuaWU9ZnVuY3Rpb24oKXtyZXR1cm4gRCh0aGlzKX0scC5yZT1oKEgsXCJhbGxSZXNvbHZlZFwiLFwiYWxsU2V0dGxlZFwiKSxmLnByb3RvdHlwZS5yZT1mdW5jdGlvbigpe3JldHVybiBIKHRoaXMpfSxwLkl0PUwsZi5wcm90b3R5cGUuSXQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uKHQpe3JldHVybiBfKFgodCxmdW5jdGlvbih0KXtmdW5jdGlvbiBlKCl7cmV0dXJuIHQuZ3QoKX1yZXR1cm4gdD1wKHQpLHQudGhlbihlLGUpfSkpfSl9LHAuZmFpbD1wW1wiY2F0Y2hcIl09ZnVuY3Rpb24odCxlKXtyZXR1cm4gcCh0KS50aGVuKHZvaWQgMCxlKX0sZi5wcm90b3R5cGUuZmFpbD1mLnByb3RvdHlwZVtcImNhdGNoXCJdPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLnRoZW4odm9pZCAwLHQpfSxwLnByb2dyZXNzPU0sZi5wcm90b3R5cGUucHJvZ3Jlc3M9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMudGhlbih2b2lkIDAsdm9pZCAwLHQpfSxwLm5lPXBbXCJmaW5hbGx5XCJdPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHAodClbXCJmaW5hbGx5XCJdKGUpfSxmLnByb3RvdHlwZS5uZT1mLnByb3RvdHlwZVtcImZpbmFsbHlcIl09ZnVuY3Rpb24odCl7aWYoIXR8fFwiZnVuY3Rpb25cIiE9dHlwZW9mIHQuYXBwbHkpdGhyb3cgbmV3IEVycm9yKFwiUSBjYW4ndCBhcHBseSBmaW5hbGx5IGNhbGxiYWNrXCIpO3JldHVybiB0PXAodCksdGhpcy50aGVuKGZ1bmN0aW9uKGUpe3JldHVybiB0LkZ0KCkudGhlbihmdW5jdGlvbigpe3JldHVybiBlfSl9LGZ1bmN0aW9uKGUpe3JldHVybiB0LkZ0KCkudGhlbihmdW5jdGlvbigpe3Rocm93IGV9KX0pfSxwLmRvbmU9ZnVuY3Rpb24odCxlLGkscil7cmV0dXJuIHAodCkuZG9uZShlLGkscil9LGYucHJvdG90eXBlLmRvbmU9ZnVuY3Rpb24odCxlLGkpe3ZhciBuPWZ1bmN0aW9uKHQpe3AuZHQoZnVuY3Rpb24oKXtpZihyKHQsbyksIXAub25lcnJvcil0aHJvdyB0O3Aub25lcnJvcih0KX0pfSxvPXR8fGV8fGk/dGhpcy50aGVuKHQsZSxpKTp0aGlzO1wib2JqZWN0XCI9PXR5cGVvZiBwcm9jZXNzJiZwcm9jZXNzJiZwcm9jZXNzLmRvbWFpbiYmKG49cHJvY2Vzcy5kb21haW4uYmluZChuKSksby50aGVuKHZvaWQgMCxuKX0scC50aW1lb3V0PWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gcCh0KS50aW1lb3V0KGUsaSl9LGYucHJvdG90eXBlLnRpbWVvdXQ9ZnVuY3Rpb24odCxlKXt2YXIgaT11KCkscj1zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ZSYmXCJzdHJpbmdcIiE9dHlwZW9mIGV8fChlPW5ldyBFcnJvcihlfHxcIlRpbWVkIG91dCBhZnRlciBcIit0K1wiIG1zXCIpLGUuY29kZT1cIkVUSU1FRE9VVFwiKSxpLnJlamVjdChlKX0sdCk7cmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbih0KXtjbGVhclRpbWVvdXQociksaS5yZXNvbHZlKHQpfSxmdW5jdGlvbih0KXtjbGVhclRpbWVvdXQociksaS5yZWplY3QodCl9LGkubm90aWZ5KSxpLnZ0fSxwLmRlbGF5PWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHZvaWQgMD09PWUmJihlPXQsdD12b2lkIDApLHAodCkuZGVsYXkoZSl9LGYucHJvdG90eXBlLmRlbGF5PWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24oZSl7dmFyIGk9dSgpO3JldHVybiBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7aS5yZXNvbHZlKGUpfSx0KSxpLnZ0fSl9LHAub2U9ZnVuY3Rpb24odCxlKXtyZXR1cm4gcCh0KS5vZShlKX0sZi5wcm90b3R5cGUub2U9ZnVuY3Rpb24odCl7dmFyIGU9dSgpLGk9Vyh0KTtyZXR1cm4gaS5wdXNoKGUuUHQoKSksdGhpcy5adChpKS5mYWlsKGUucmVqZWN0KSxlLnZ0fSxwLnNlPWZ1bmN0aW9uKHQpe3ZhciBlPVcoYXJndW1lbnRzLDEpO3JldHVybiBwKHQpLm9lKGUpfSxmLnByb3RvdHlwZS5zZT1mdW5jdGlvbigpe3ZhciB0PVcoYXJndW1lbnRzKSxlPXUoKTtyZXR1cm4gdC5wdXNoKGUuUHQoKSksdGhpcy5adCh0KS5mYWlsKGUucmVqZWN0KSxlLnZ0fSxwLmFlPXAuY2U9ZnVuY3Rpb24odCl7aWYodm9pZCAwPT09dCl0aHJvdyBuZXcgRXJyb3IoXCJRIGNhbid0IHdyYXAgYW4gdW5kZWZpbmVkIGZ1bmN0aW9uXCIpO3ZhciBlPVcoYXJndW1lbnRzLDEpO3JldHVybiBmdW5jdGlvbigpe3ZhciBpPWUuY29uY2F0KFcoYXJndW1lbnRzKSkscj11KCk7cmV0dXJuIGkucHVzaChyLlB0KCkpLHAodCkuWnQoaSkuZmFpbChyLnJlamVjdCksci52dH19LGYucHJvdG90eXBlLmFlPWYucHJvdG90eXBlLmNlPWZ1bmN0aW9uKCl7dmFyIHQ9Vyhhcmd1bWVudHMpO3JldHVybiB0LnVuc2hpZnQodGhpcykscC5jZS5hcHBseSh2b2lkIDAsdCl9LHAuaGU9ZnVuY3Rpb24odCxlKXt2YXIgaT1XKGFyZ3VtZW50cywyKTtyZXR1cm4gZnVuY3Rpb24oKXtmdW5jdGlvbiByKCl7cmV0dXJuIHQuYXBwbHkoZSxhcmd1bWVudHMpfXZhciBuPWkuY29uY2F0KFcoYXJndW1lbnRzKSksbz11KCk7cmV0dXJuIG4ucHVzaChvLlB0KCkpLHAocikuWnQobikuZmFpbChvLnJlamVjdCksby52dH19LGYucHJvdG90eXBlLmhlPWZ1bmN0aW9uKCl7dmFyIHQ9Vyhhcmd1bWVudHMsMCk7cmV0dXJuIHQudW5zaGlmdCh0aGlzKSxwLmhlLmFwcGx5KHZvaWQgMCx0KX0scC5wZT1wLnVlPWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gcCh0KS51ZShlLGkpfSxmLnByb3RvdHlwZS5wZT1mLnByb3RvdHlwZS51ZT1mdW5jdGlvbih0LGUpe3ZhciBpPVcoZXx8W10pLHI9dSgpO3JldHVybiBpLnB1c2goci5QdCgpKSx0aGlzLkV0KFwicG9zdFwiLFt0LGldKS5mYWlsKHIucmVqZWN0KSxyLnZ0fSxwLmxlPXAuZGU9cC5mZT1mdW5jdGlvbih0LGUpe3ZhciBpPVcoYXJndW1lbnRzLDIpLHI9dSgpO3JldHVybiBpLnB1c2goci5QdCgpKSxwKHQpLkV0KFwicG9zdFwiLFtlLGldKS5mYWlsKHIucmVqZWN0KSxyLnZ0fSxmLnByb3RvdHlwZS5sZT1mLnByb3RvdHlwZS5kZT1mLnByb3RvdHlwZS5mZT1mdW5jdGlvbih0KXt2YXIgZT1XKGFyZ3VtZW50cywxKSxpPXUoKTtyZXR1cm4gZS5wdXNoKGkuUHQoKSksdGhpcy5FdChcInBvc3RcIixbdCxlXSkuZmFpbChpLnJlamVjdCksaS52dH0scC5SdD1qLGYucHJvdG90eXBlLlJ0PWZ1bmN0aW9uKHQpe3JldHVybiB0P3ZvaWQgdGhpcy50aGVuKGZ1bmN0aW9uKGUpe3AuZHQoZnVuY3Rpb24oKXt0KG51bGwsZSl9KX0sZnVuY3Rpb24oZSl7cC5kdChmdW5jdGlvbigpe3QoZSl9KX0pOnRoaXN9LHAuZ2U9ZnVuY3Rpb24oKXt0aHJvdyBuZXcgRXJyb3IoXCJRLm5vQ29uZmxpY3Qgb25seSB3b3JrcyB3aGVuIFEgaXMgdXNlZCBhcyBhIGdsb2JhbFwiKX07dmFyIGN0PWMoKTtyZXR1cm4gcH0pfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHIsbj1pKDE1KSxvPWkoNCkscz1vLnZlOyFmdW5jdGlvbih0KXtmdW5jdGlvbiBlKGUpe0ImJmNvbnNvbGUubG9nKFwiRnJhbWV3b3JrIGFscmVhZHkgaW5pdGlhbGl6ZWRcIiksdC55ZSgpLE49bmV3IERhdGUsZS5hcHBseShEKSxCPUQucmVzb2x2ZShrLm1lKSxfPUQucmVzb2x2ZShrLndlKSxMPUIuQ3QoKX1mdW5jdGlvbiBpKCl7Rj1ELnJlc29sdmUoay5UZSksRi5pbml0KCl9ZnVuY3Rpb24gcigpe3JldHVybiBGfWZ1bmN0aW9uIG8oKXtyZXR1cm4gRH1mdW5jdGlvbiBhKCl7cmV0dXJuIF99ZnVuY3Rpb24gYygpe3JldHVybiBCfWZ1bmN0aW9uIGgodCl7cmV0dXJuIEguZ2V0KHQpfWZ1bmN0aW9uIHAodCxlKXt2YXIgaT1uZXcgQyh0KTtyZXR1cm4gaS5hcHBseShlKSxILnNldCh0LGkpLGl9ZnVuY3Rpb24gdShlKXtBPXQuU2UoZSl9ZnVuY3Rpb24gbCh0KXtyZXR1cm4gbnVsbCE9QT9BLmNvbnRleHQucmVzb2x2ZSh0KTooY29uc29sZS53YXJuKFwidW5kZWZpbmVkIGNvbnRleHRcIiksbnVsbCl9ZnVuY3Rpb24gZCgpe3JldHVybiBBfWZ1bmN0aW9uIGYoKXtyZXR1cm4gQi50aW1lKCl9ZnVuY3Rpb24gZyh0LGUpe3JldHVybiBCLnNldFRpbWVvdXQodCxlKX1mdW5jdGlvbiB2KHQpe3JldHVybiBCLmNsZWFyVGltZW91dCh0KX1mdW5jdGlvbiB5KHQsZSl7cmV0dXJuIEIuc2V0SW50ZXJ2YWwodCxlKX1mdW5jdGlvbiBtKHQpe3JldHVybiBCLmNsZWFySW50ZXJ2YWwodCl9ZnVuY3Rpb24gdygpe0IuYmUoKX1mdW5jdGlvbiBUKCl7RC5FZSgpLEQ9bmV3IG4uSWUsSD1uZXcgcyxBPW51bGwsTj1udWxsLEw9ITEseD1udWxsLEI9bnVsbCxGPW51bGwsXz1udWxsfWZ1bmN0aW9uIFModCl7eD10fWZ1bmN0aW9uIGIoKXtyZXR1cm4geHx8KHg9KG5ldyBEYXRlKS5nZXRUaW1lKCkpLHg9KDkzMDEqeCs0OTI5NyklMjMzMjgwLHgvMjMzMjgwfWZ1bmN0aW9uIEUoKXtyZXR1cm4gTn1mdW5jdGlvbiBJKCl7cmV0dXJuIEx9dmFyIFI9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7fXJldHVybiB0fSgpO1IuUmU9XCJ3czovLzEyNy4wLjAuMTo4MDAwL2hpdmVcIix0LmtlPVI7dmFyIGs9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7fXJldHVybiB0fSgpO2subWU9XCJUaW1lclNjaGVkdWxlclwiLGsuQ2U9XCJpZGVudGl0eVByb3ZpZGVyXCIsay5UZT1cIk5ldHdvcmtDb21wb25lbnRcIixrLk9lPVwicnRjTWFuYWdlclwiLGsuUGU9XCJ0cmFuc3BvcnRcIixrLkFlPVwiaHR0cE1hbmFnZXJcIixrLk5lPVwiaHR0cFJlcXVlc3RcIixrLndlPVwibG9nZ2VyXCIsay54ZT1cInNlcnZlck1hbmFnZXJcIixrLkJlPVwic2VydmljZXNDbGllbnRcIix0LkZlPWs7dmFyIEM9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQpe3RoaXMuaWQ9dCx0aGlzLmNvbnRleHQ9bmV3IG4uSWV9cmV0dXJuIHQucHJvdG90eXBlLmFwcGx5PWZ1bmN0aW9uKHQpe3QuYXBwbHkodGhpcy5jb250ZXh0KX0sdH0oKTt0Ll9lPUM7dmFyIE87IWZ1bmN0aW9uKHQpe3RbdC5EZT0wXT1cIkhUVFBcIix0W3QuSGU9MV09XCJSVENcIix0W3QuTGU9Ml09XCJVRFBcIn0oTz10Lk1lfHwodC5NZT17fSkpO3ZhciBQOyFmdW5jdGlvbihlKXtmdW5jdGlvbiBpKCl7cmV0dXJuXCJbXCIrZigpK1wiXSBbXCIrdC5qZSgpLmlkK1wiXVwifWUuVWU9aX0oUD10LlZlfHwodC5WZT17fSkpO3ZhciBBLE4seCxCLEYsXyxEPW5ldyBuLkllLEg9bmV3IHMsTD0hMTt0LlFlPWUsdC5xZT1pLHQuSmU9cix0LnN5c3RlbT1vLHQubT1hLHQuS2U9Yyx0LlNlPWgsdC5HZT1wLHQuemU9dSx0LnJlc29sdmU9bCx0LmplPWQsdC50aW1lPWYsdC5zZXRUaW1lb3V0PWcsdC5jbGVhclRpbWVvdXQ9dix0LnNldEludGVydmFsPXksdC5jbGVhckludGVydmFsPW0sdC5iZT13LHQueWU9VCx0LldlPVMsdC5yYW5kb209Yix0LiRlPUUsdC5DdD1JfShyPWUuRnJhbWV3b3JrfHwoZS5GcmFtZXdvcms9e30pKSxcInVuZGVmaW5lZFwiIT10eXBlb2YgZ2xvYmFsJiYoZ2xvYmFsLkZyYW1ld29yaz1yKX0sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjt2YXIgaT0hMCxyPXtZZTpmdW5jdGlvbih0KXtyZXR1cm5cImJvb2xlYW5cIiE9dHlwZW9mIHQ/bmV3IEVycm9yKFwiQXJndW1lbnQgdHlwZTogXCIrdHlwZW9mIHQrXCIuIFBsZWFzZSB1c2UgYSBib29sZWFuLlwiKTooaT10LHQ/XCJhZGFwdGVyLmpzIGxvZ2dpbmcgZGlzYWJsZWRcIjpcImFkYXB0ZXIuanMgbG9nZ2luZyBlbmFibGVkXCIpfSxsb2c6ZnVuY3Rpb24oKXtpZihcIm9iamVjdFwiPT10eXBlb2Ygd2luZG93KXtpZihpKXJldHVybjtcInVuZGVmaW5lZFwiIT10eXBlb2YgY29uc29sZSYmXCJmdW5jdGlvblwiPT10eXBlb2YgY29uc29sZS5sb2cmJmNvbnNvbGUubG9nLmFwcGx5KGNvbnNvbGUsYXJndW1lbnRzKX19LFhlOmZ1bmN0aW9uKHQsZSxpKXt2YXIgcj10Lm1hdGNoKGUpO3JldHVybiByJiZyLmxlbmd0aD49aSYmcGFyc2VJbnQocltpXSwxMCl9LFplOmZ1bmN0aW9uKCl7dmFyIHQ9e307aWYodC50aT1udWxsLHQudmVyc2lvbj1udWxsLFwidW5kZWZpbmVkXCI9PXR5cGVvZiB3aW5kb3d8fCF3aW5kb3cubmF2aWdhdG9yKXJldHVybiB0LnRpPVwiTm90IGEgYnJvd3Nlci5cIix0O2lmKG5hdmlnYXRvci5tb3pHZXRVc2VyTWVkaWEpdC50aT1cImZpcmVmb3hcIix0LnZlcnNpb249dGhpcy5YZShuYXZpZ2F0b3IudXNlckFnZW50LC9GaXJlZm94XFwvKFxcZCspXFwuLywxKTtlbHNlIGlmKG5hdmlnYXRvci53ZWJraXRHZXRVc2VyTWVkaWEpaWYod2luZG93LndlYmtpdFJUQ1BlZXJDb25uZWN0aW9uKXQudGk9XCJjaHJvbWVcIix0LnZlcnNpb249dGhpcy5YZShuYXZpZ2F0b3IudXNlckFnZW50LC9DaHJvbShlfGl1bSlcXC8oXFxkKylcXC4vLDIpO2Vsc2V7aWYoIW5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL1ZlcnNpb25cXC8oXFxkKykuKFxcZCspLykpcmV0dXJuIHQudGk9XCJVbnN1cHBvcnRlZCB3ZWJraXQtYmFzZWQgYnJvd3NlciB3aXRoIEdVTSBzdXBwb3J0IGJ1dCBubyBXZWJSVEMgc3VwcG9ydC5cIix0O3QudGk9XCJzYWZhcmlcIix0LnZlcnNpb249dGhpcy5YZShuYXZpZ2F0b3IudXNlckFnZW50LC9BcHBsZVdlYktpdFxcLyhcXGQrKVxcLi8sMSl9ZWxzZSBpZihuYXZpZ2F0b3IubWVkaWFEZXZpY2VzJiZuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9FZGdlXFwvKFxcZCspLihcXGQrKSQvKSl0LnRpPVwiZWRnZVwiLHQudmVyc2lvbj10aGlzLlhlKG5hdmlnYXRvci51c2VyQWdlbnQsL0VkZ2VcXC8oXFxkKykuKFxcZCspJC8sMik7ZWxzZXtpZighbmF2aWdhdG9yLm1lZGlhRGV2aWNlc3x8IW5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FwcGxlV2ViS2l0XFwvKFxcZCspXFwuLykpcmV0dXJuIHQudGk9XCJOb3QgYSBzdXBwb3J0ZWQgYnJvd3Nlci5cIix0O3QudGk9XCJzYWZhcmlcIix0LnZlcnNpb249dGhpcy5YZShuYXZpZ2F0b3IudXNlckFnZW50LC9BcHBsZVdlYktpdFxcLyhcXGQrKVxcLi8sMSl9cmV0dXJuIHR9LGVpOmZ1bmN0aW9uKCl7aWYoXCJvYmplY3RcIj09dHlwZW9mIHdpbmRvdyYmd2luZG93LkhUTUxNZWRpYUVsZW1lbnQmJlwic3JjT2JqZWN0XCJpbiB3aW5kb3cuSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUpe3ZhciB0PVVSTC5jcmVhdGVPYmplY3RVUkwuYmluZChVUkwpLGU9VVJMLnJldm9rZU9iamVjdFVSTC5iaW5kKFVSTCksaT1uZXcgTWFwLHI9MDtVUkwuY3JlYXRlT2JqZWN0VVJMPWZ1bmN0aW9uKGUpe2lmKFwiZ2V0VHJhY2tzXCJpbiBlKXt2YXIgbj1cInBvbHlibG9iOlwiKyArK3I7cmV0dXJuIGkuc2V0KG4sZSksY29uc29sZS5sb2coXCJVUkwuY3JlYXRlT2JqZWN0VVJMKHN0cmVhbSkgaXMgZGVwcmVjYXRlZCEgVXNlIGVsZW0uc3JjT2JqZWN0ID0gc3RyZWFtIGluc3RlYWQhXCIpLG59cmV0dXJuIHQoZSl9LFVSTC5yZXZva2VPYmplY3RVUkw9ZnVuY3Rpb24odCl7ZSh0KSxpW1wiZGVsZXRlXCJdKHQpfTt2YXIgbj1PYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHdpbmRvdy5IVE1MTWVkaWFFbGVtZW50LnByb3RvdHlwZSxcInNyY1wiKTtPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LkhUTUxNZWRpYUVsZW1lbnQucHJvdG90eXBlLFwic3JjXCIse2dldDpmdW5jdGlvbigpe3JldHVybiBuLmdldC5hcHBseSh0aGlzKX0sc2V0OmZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLmlpPWkuZ2V0KHQpfHxudWxsLG4uc2V0LmFwcGx5KHRoaXMsW3RdKX19KTt2YXIgbz1IVE1MTWVkaWFFbGVtZW50LnByb3RvdHlwZS5zZXRBdHRyaWJ1dGU7SFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUuc2V0QXR0cmlidXRlPWZ1bmN0aW9uKCl7cmV0dXJuIDI9PT1hcmd1bWVudHMubGVuZ3RoJiZcInNyY1wiPT09KFwiXCIrYXJndW1lbnRzWzBdKS50b0xvd2VyQ2FzZSgpJiYodGhpcy5paT1pLmdldChhcmd1bWVudHNbMV0pfHxudWxsKSxvLmFwcGx5KHRoaXMsYXJndW1lbnRzKX19fX07dC50PXtsb2c6ci5sb2csWWU6ci5ZZSxyaTpyLlplKCksWGU6ci5YZSxlaTpyLmVpLFplOnIuWmUuYmluZChyKX19LGZ1bmN0aW9uKHQsZSxpKXt2YXIgcj1pKDMyKTt0LnQ9e3ZlOnIuTWFwLG5pOnIubmksb2k6ci5vaX19LGZ1bmN0aW9uKHQsZSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGk7IWZ1bmN0aW9uKHQpe3Quc2k9XCJzdGF0c0NsaWVudFwiLHQuQmU9XCJzZXJ2aWNlc0NsaWVudFwiLHQuYWk9XCJ0aWNrZXRSZXNvbHZlclwiLHQuQ2U9XCJpZGVudGl0eVByb3ZpZGVyXCIsdC5jaT1cImNvbm5JbmZvUHJvdmlkZXJcIix0LmhpPVwicGVlckluZm9cIix0LnBpPVwic3RyZWFtSW5mb1Byb3ZpZGVyXCIsdC51aT1cInJlcG9ydGluZ1wiLHQubGk9XCJzdGF0c1N0b3JlXCIsdC5kaT1cInRyYWNrTWFuYWdlclwiLHQuZmk9XCJ0cmFja0NsaWVudFwifShpPWUuZ2l8fChlLmdpPXt9KSl9LGZ1bmN0aW9uKHQsZSl7dC50PWZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBGdW5jdGlvbn19LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiByKHQsZSl7ZnVuY3Rpb24gaSgpe3JldHVybiB0KCk/dm9pZCB2LndoZW4oZSgpLGksci5yZWplY3QpOnIucmVzb2x2ZSghMCl9dmFyIHI9di5kZWZlcigpO3JldHVybiB2LmR0KGkpLHIudnR9ZnVuY3Rpb24gbih0LGUsaSl7cmV0dXJuIHZvaWQgMD09PWkmJihpPSEwKSxvKFwiR0VUXCIsdCxlLGkpfWZ1bmN0aW9uIG8odCxlLGkscil7dm9pZCAwPT09ciYmKHI9ITApO3ZhciBuPXYuZGVmZXIoKTt0cnl7dmFyIG89bmV3IFhNTEh0dHBSZXF1ZXN0O28ub3Blbih0LGUsciksdm9pZCAwIT1pJiZudWxsIT1pJiZvLnNldFJlcXVlc3RIZWFkZXIoXCJDb250ZW50LVR5cGVcIixpKSxvLm9ubG9hZD1mdW5jdGlvbigpezIwMD09by5zdGF0dXM/bi5yZXNvbHZlKG8ucmVzcG9uc2UpOm4ucmVqZWN0KHtzdGF0dXM6by5zdGF0dXMscmVhc29uOm8uc3RhdHVzVGV4dCxib2R5Om8ucmVzcG9uc2VUZXh0fSl9LG8ub25lcnJvcj1mdW5jdGlvbih0KXtuLnJlamVjdCh7c3RhdHVzOi0xLHJlYXNvbjpcIk5ldHdvcmsgRXJyb3JcIn0pfSxvLnNlbmQoKX1jYXRjaChzKXtuLnJlamVjdCh7c3RhdHVzOi0xLHJlYXNvbjpzfSl9cmV0dXJuIG4udnR9ZnVuY3Rpb24gcyh0LGUsaSxyKXt2b2lkIDA9PT1yJiYocj0hMCk7dmFyIG49di5kZWZlcigpO3RyeXt2YXIgbz1uZXcgWE1MSHR0cFJlcXVlc3Q7by5vcGVuKFwiUE9TVFwiLHQsciksdm9pZCAwIT1pJiZudWxsIT1pJiZvLnNldFJlcXVlc3RIZWFkZXIoXCJDb250ZW50LVR5cGVcIixpKSxvLm9ubG9hZD1mdW5jdGlvbigpezIwMD09by5zdGF0dXM/bi5yZXNvbHZlKG8ucmVzcG9uc2UpOm4ucmVqZWN0KHtzdGF0dXM6by5zdGF0dXMscmVhc29uOm8uc3RhdHVzVGV4dH0pfSxvLm9uZXJyb3I9ZnVuY3Rpb24odCl7bi5yZWplY3Qoe3N0YXR1czotMSxyZWFzb246XCJOZXR3b3JrIEVycm9yXCJ9KX0sby5zZW5kKGUpfWNhdGNoKHMpe24ucmVqZWN0KHtzdGF0dXM6LTEscmVhc29uOnN9KX1yZXR1cm4gbi52dH1mdW5jdGlvbiBhKHQsZSl7dmFyIGkscixuPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJiYXNlXCIpLG89ZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcImhlYWRcIikscz1kb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYVwiKSxhPW47cmV0dXJuIG4/aT1uLmhyZWY6YT1vLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJiYXNlXCIpKSxhLmhyZWY9dCxzLmhyZWY9ZSxyPXMuaHJlZixuP24uaHJlZj1pOm8ucmVtb3ZlQ2hpbGQoYSkscn1mdW5jdGlvbiBjKCl7Zm9yKHZhciB0PVtdLGU9MDtlPGFyZ3VtZW50cy5sZW5ndGg7ZSsrKXRbZV09YXJndW1lbnRzW2VdO2Zvcih2YXIgaT10WzBdLHI9MTtyPHQubGVuZ3RoO3IrKyl7dmFyIG49bmV3IFJlZ0V4cChcIlxcXFx7XCIrKHItMSkrXCJcXFxcfVwiLFwiZ21cIik7aT1pLnJlcGxhY2Uobix0W3JdKX1yZXR1cm4gaX1mdW5jdGlvbiBoKHQsZSl7Zm9yKHZhciBpIGluIHQpdC5oYXNPd25Qcm9wZXJ0eShpKSYmZS5oYXNPd25Qcm9wZXJ0eShpKSYmKGVbaV09dFtpXSl9ZnVuY3Rpb24gcCh0LGUsaSl7dmFyIHI9Zyh0KS52aSghMCk7Zm9yKHZhciBuIGluIHIpdHJ5e2lmKHIuaGFzT3duUHJvcGVydHkobikmJmUuaGFzT3duUHJvcGVydHkobikmJmkuaGFzT3duUHJvcGVydHkoZVtuXSkpe3ZhciBvPWVbbl0scz1yW25dO2lbb109dShzLGlbb10pfX1jYXRjaChhKXt9fWZ1bmN0aW9uIHUodCxlKXt2YXIgaTtzd2l0Y2godHlwZW9mIGUpe2Nhc2VcIm51bWJlclwiOmk9cGFyc2VJbnQodCk7YnJlYWs7Y2FzZVwiYm9vbGVhblwiOmk9XCJ0cnVlXCI9PT10O2JyZWFrO2RlZmF1bHQ6aT10fXJldHVybiBpfWZ1bmN0aW9uIGwodCxlLGkpe3ZhciByPW5ldyBtO3JldHVybiByLnRpY2tldFVybD10LHIuY29kZT1lLHIubWVzc2FnZT13KGUpLHIuZGV0YWlsZWRNZXNzYWdlPWkscn12YXIgZD1pKDQpLGY9ZC52ZSxnPWkoMjEpLHY9aSgxKSx5PWkoMTcpLG09eS5wdC5IaXZlU2Vzc2lvbkVycm9yLHc9eS5wdC5nZXRIaXZlU2Vzc2lvbkVycm9yTWVzc2FnZSxUPXkucHQuSGl2ZVNlc3Npb24sUz1pKDI2KSxiPWkoNDYpLEU9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KGUpe2lmKCFlKXtpZigwPT1PYmplY3Qua2V5cyh0Lm1hcHBpbmcpLmxlbmd0aCYmIXQueWkpcmV0dXJuIGNvbnNvbGUuZXJyb3IoXCJubyByZWdpc3RlcmVkIGRlZmF1bHQgSGl2ZVJlcXVlc3RGYWN0b3J5IHRlY2hcIiksdC55aT0hMCx0Lm1pKCk7ZT1PYmplY3Qua2V5cyh0Lm1hcHBpbmcpWzBdfWlmKCEoZSBpbiB0Lm1hcHBpbmcpKXJldHVybiB0LnlpfHwoY29uc29sZS5lcnJvcihcIm5vIHJlZ2lzdGVyZWQgSGl2ZVJlcXVlc3RGYWN0b3J5IHRlY2ggZm9yICBcIitlKSx0LnlpPSEwKSx0Lm1pKCk7dmFyIGk9dC5tYXBwaW5nW2VdO3N3aXRjaChpLnRlY2gpe2Nhc2VcIkhpdmVKU1wiOnJldHVybiB0Lm1pKCk7Y2FzZVwiSGl2ZUpzUHJveHlcIjpyZXR1cm4gaS53aT9uZXcgUy5UaShlKTooaS53aT0hMCxuZXcgYi5TaShlKSk7Y2FzZVwiSGl2ZUphdmFcIjpjYXNlXCJTdGF0c0pTXCI6cmV0dXJuIHQubWkoKX19cmV0dXJuIHQubWk9ZnVuY3Rpb24oKXtyZXR1cm5cInVuZGVmaW5lZFwiIT10eXBlb2YgT3JpZ2luYWxYTUxIdHRwUmVxdWVzdD9uZXcgT3JpZ2luYWxYTUxIdHRwUmVxdWVzdDpuZXcgWE1MSHR0cFJlcXVlc3R9LHQuY2xlYXI9ZnVuY3Rpb24oKXt0Lm1hcHBpbmc9e319LHQuYmk9ZnVuY3Rpb24oZSxpKXtlIGluIHQubWFwcGluZ3x8KHQubWFwcGluZ1tlXT17fSksdC5tYXBwaW5nW2VdLnRlY2g9aX0sdH0oKTtFLm1hcHBpbmc9e30sRS55aT0hMSxlLkhpdmVSZXF1ZXN0RmFjdG9yeT1FO3ZhciBJPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0LGUsaSxyKXt0aGlzLkVpPSExLHRoaXMudGlja2V0VXJsPXQsdGhpcy50aWNrZXQ9ZSx0aGlzLm1hbmlmZXN0PWksdGhpcy5JaT12LmRlZmVyKCksdGhpcy5SaT1yLHRoaXMuUmkmJnRoaXMuSWkucmVzb2x2ZSh0aGlzLlJpKX1yZXR1cm4gdC5wcm90b3R5cGUuc3Q9ZnVuY3Rpb24odCl7cmV0dXJuIG51bGwhPT10aGlzLnRlY2gmJnRoaXMudGVjaC5zdCh0LHRoaXMpfSx0LnByb3RvdHlwZS5raT1mdW5jdGlvbih0KXt0aGlzLkVpIT10JiYodGhpcy5FaT10LHRoaXMudGVjaCYmdGhpcy50ZWNoLkNpKHRoaXMsdCkpfSx0LnByb3RvdHlwZS5PaT1mdW5jdGlvbigpe3JldHVybiB0aGlzLkVpfSx0LnByb3RvdHlwZS5jbG9zZT1mdW5jdGlvbih0KXtpZihudWxsIT10aGlzLnRlY2gpcmV0dXJuIHRoaXMudGVjaC5QaSh0aGlzLHQpfSx0LnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLnRpY2tldC50b1N0cmluZygpfSx0LnByb3RvdHlwZS5nPWZ1bmN0aW9uKCl7dmFyIHQ9bmV3IFQ7cmV0dXJuIHQuaWQ9dGhpcy5pZCx0LnRpY2tldFVybD10aGlzLnRpY2tldFVybCx0Lm1hbmlmZXN0PXRoaXMubWFuaWZlc3QsdC50ZWNoPXRoaXMudGVjaC5BaSgpLHR9LHQucHJvdG90eXBlLk5pPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuSWkudnR9LHQucHJvdG90eXBlLnhpPWZ1bmN0aW9uKHQpe3RoaXMuUmk9dCx0aGlzLklpLnJlc29sdmUodGhpcy5SaSl9LHR9KCk7ZS5CaT1JO3ZhciBSPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTtlLkZpPVI7dmFyIGs9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7dGhpcy5zdWNjZXNzPTAsdGhpcy5faT0wLHRoaXMuRGk9MH1yZXR1cm4gdH0oKTtlLkhpPWs7dmFyIEM9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7dGhpcy5MaT0wLHRoaXMuTWk9MCx0aGlzLmppPW5ldyBmLHRoaXMuVWk9bmV3IGZ9cmV0dXJuIHQucHJvdG90eXBlLk09ZnVuY3Rpb24odCxlLGkscil7dm9pZCAwPT09ciYmKHI9ITApO3ZhciBuPXQ/dGhpcy5qaTp0aGlzLlVpO24uaGFzKGUpfHxuLnNldChlLG5ldyBrKTt2YXIgbz1uLmdldChlKTtvLkRpKz1pLHImJm8uc3VjY2VzcysrfSx0LnByb3RvdHlwZS5WPWZ1bmN0aW9uKHQsZSl7dmFyIGk9dD90aGlzLmppOnRoaXMuVWk7aS5oYXMoZSl8fGkuc2V0KGUsbmV3IGspLGkuZ2V0KGUpLl9pKyt9LHQucHJvdG90eXBlLlU9ZnVuY3Rpb24odCl7dGhpcy5iYW5kd2lkdGg9dH0sdC5wcm90b3R5cGUuWj1mdW5jdGlvbigpe3RoaXMuTGkrK30sdC5wcm90b3R5cGUudHQ9ZnVuY3Rpb24oKXt0aGlzLk1pKyt9LHQucHJvdG90eXBlLlZpPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYmFuZHdpZHRofSx0LnByb3RvdHlwZS5RaT1mdW5jdGlvbigpe3JldHVybiB0aGlzLmppfSx0LnByb3RvdHlwZS5xaT1mdW5jdGlvbigpe3JldHVybiB0aGlzLlVpfSx0LnByb3RvdHlwZS5KaT1mdW5jdGlvbigpe3JldHVybiB0aGlzLkxpfSx0LnByb3RvdHlwZS5LaT1mdW5jdGlvbigpe3JldHVybiB0aGlzLk1pfSx0fSgpO2UuUD1DO3ZhciBPPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3ZhciBlPXRoaXM7aWYodC5HaSl0aHJvdyBuZXcgRXJyb3IoXCJFcnJvcjogSW5zdGFudGlhdGlvbiBmYWlsZWQ6IFVzZSBWaXNpYmlsaXR5Q2hhbmdlTGlzdGVuZXIuZ2V0SW5zdGFuY2UoKSBpbnN0ZWFkIG9mIG5ldy5cIik7dmFyIGkscjtcInVuZGVmaW5lZFwiIT10eXBlb2YgZG9jdW1lbnQuaGlkZGVuPyhpPVwiaGlkZGVuXCIscj1cInZpc2liaWxpdHljaGFuZ2VcIik6XCJ1bmRlZmluZWRcIiE9dHlwZW9mIGRvY3VtZW50Lm1zSGlkZGVuPyhpPVwibXNIaWRkZW5cIixyPVwibXN2aXNpYmlsaXR5Y2hhbmdlXCIpOlwidW5kZWZpbmVkXCIhPXR5cGVvZiBkb2N1bWVudC53ZWJraXRIaWRkZW4mJihpPVwid2Via2l0SGlkZGVuXCIscj1cIndlYmtpdHZpc2liaWxpdHljaGFuZ2VcIiksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXImJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBkb2N1bWVudFtpXT9kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKHIsZnVuY3Rpb24oKXt2YXIgdD0hZG9jdW1lbnRbaV07ZS56aS5mb3JFYWNoKGZ1bmN0aW9uKGkpe2kuY2FsbChlLHQpfSl9LCExKTp0Lm0mJnQubS5kZWJ1ZyhcIndhcm4gLSB2aXNpYmlsaXR5Q2hhbmdlIGxpc3RlbmVyIG5vdCBzdXBwb3J0ZWRcIiksdGhpcy56aT1uZXcgQXJyYXl9cmV0dXJuIHQuV2k9ZnVuY3Rpb24oZSl7cmV0dXJuIGUmJih0aGlzLm09ZSksdm9pZCAwPT09dGhpcy5HaSYmKHRoaXMuR2k9bmV3IHQpLHRoaXMuR2l9LHQucHJvdG90eXBlLiRpPWZ1bmN0aW9uKHQpe3RoaXMuemkucHVzaCh0KX0sdH0oKTtlLllpPU8sZS5YaT1yLGUuWmk9bixlLnRyPW8sZS5lcj1zLGUuaXI9YSxlLnJyPWMsZS5ucj1oLGUub3I9cCxlLnNyPWw7dmFyIFA9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7fXJldHVybiB0LmdldEl0ZW09ZnVuY3Rpb24odCl7dHJ5e3JldHVybiB3aW5kb3cuc2Vzc2lvblN0b3JhZ2U/d2luZG93LnNlc3Npb25TdG9yYWdlLmdldEl0ZW0odCk6bnVsbH1jYXRjaChlKXtyZXR1cm4gbnVsbH19LHQuc2V0SXRlbT1mdW5jdGlvbih0LGUpe3RyeXtyZXR1cm4hIXdpbmRvdy5zZXNzaW9uU3RvcmFnZSYmKHdpbmRvdy5zZXNzaW9uU3RvcmFnZS5zZXRJdGVtKHQsZSksITApfWNhdGNoKGkpe3JldHVybiExfX0sdC5yZW1vdmVJdGVtPWZ1bmN0aW9uKHQpe3RyeXt3aW5kb3cuc2Vzc2lvblN0b3JhZ2UmJndpbmRvdy5zZXNzaW9uU3RvcmFnZS5yZW1vdmVJdGVtKHQpfWNhdGNoKGUpe3JldHVybiBudWxsfX0sdH0oKTtlLmFyPVA7dmFyIEE9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQpe3RoaXMuY3I9dH1yZXR1cm4gdC5wcm90b3R5cGUuaHI9ZnVuY3Rpb24odCl7dmFyIGU9RGF0ZS5ub3coKTtyZXR1cm4gdGhpcy5pc0VxdWFsKHRoaXMucHIsdCl8fCh0aGlzLnVyPWUpLHRoaXMucHI9dCxlLXRoaXMudXI+PXRoaXMuY3J9LHQucHJvdG90eXBlLmlzRXF1YWw9ZnVuY3Rpb24odCxlKXtpZih0JiZlKXt2YXIgaT1bZS5sci10LmxyLGUuZHItdC5kcixlLmdyLXQuZ3JdO3JldHVybiBpLnJlZHVjZShmdW5jdGlvbih0LGUpe3JldHVybiB0JiZNYXRoLmFicyhlKTwxMH0sITApfXJldHVybiExfSx0fSgpO2UudnI9QX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByLG49aSgxMSksbz1pKDE4KSxzPWkoMTIpOyFmdW5jdGlvbih0KXt2YXIgZTshZnVuY3Rpb24odCl7dmFyIGU9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7dGhpcy5tb25pdG9yUG9ydD1vLmtlLnlyP3Mud3IubXI6cy53ci5Ucix0aGlzLnBsYXllclBvcnQ9by5rZS55cj9zLndyLlNyOnMud3IuYnIsdGhpcy5mZWVkYmFja1BlcmlvZD0yZTMsdGhpcy5pZGxlVGltZVBlcmlvZD02ZTQsdGhpcy51c2VTZXNzaW9uQ2hlY2s9by5rZS5Fcix0aGlzLmRlYnVnTGV2ZWw9XCJub3RpY2VcIix0aGlzLmhpdmVUZWNoT3JkZXI9W10sdGhpcy50ZWxlbWV0cnlJZD1udWxsLHRoaXMuc2lsZW50PSExLHRoaXMubG9nZ2VyVGltZXN0YW1wPW4uSGl2ZUNvbmZpZy5GcmFtZXdvcmsuTG9nZ2VyVGltZXN0YW1wLHRoaXMub25Tb3VyY2VTZXRDb21wbGV0ZWQ9ZnVuY3Rpb24odCl7fSx0aGlzLm9uTG9hZGluZ0NvbXBsZXRlZD1mdW5jdGlvbih0KXt9fXJldHVybiB0fSgpO3QuSXI9ZTt2YXIgaT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt0aGlzLmluaXRUaW1lb3V0PTNlNCx0aGlzLm9uRXJyb3I9ZnVuY3Rpb24odCl7cmV0dXJuITB9LHRoaXMub25BY3RpdmVTZXNzaW9uPWZ1bmN0aW9uKHQpe319cmV0dXJuIHR9KCk7dC5Scj1pO3ZhciByPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMuaGl2ZVBsYXllclBvcnQ9XCJwbGF5ZXJQb3J0XCIsdGhpcy5oaXZlTW9uaXRvclBvcnQ9XCJtb25pdG9yUG9ydFwiLHRoaXMuaGl2ZVNpbGVudD1cInNpbGVudFwiLHRoaXMuaGl2ZURlYnVnTGV2ZWw9XCJkZWJ1Z0xldmVsXCIsdGhpcy5oaXZlRGVidWdUaW1lc3RhbXA9XCJsb2dnZXJUaW1lc3RhbXBcIix0aGlzLmhpdmVTZXR1cFRpbWVvdXQ9XCJzZXR1cFRpbWVvdXRcIix0aGlzLmhpdmVKYXZhVGltZW91dD1cImluaXRUaW1lb3V0XCIsdGhpcy5oaXZlV2FybkphdmFUaW1lb3V0PVwid2FyblNsb3dSZXNwVGltZW91dFwifXJldHVybiB0fSgpO3Qua3I9cn0oZT10LklyfHwodC5Jcj17fSkpfShyPWUucHR8fChlLnB0PXt9KSk7dmFyIGE7IWZ1bmN0aW9uKHQpe3ZhciBlPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTtlLmVuYWJsZWRSVU09ITEsZS5lbmFibGVLZXlDb21iaW5hdGlvbj0hMCxlLmVuYWJsZWRFcnJvckZpbHRlcj0hMCx0LkVycm9yTW9uaXRvcj1lfShhPWUuSGl2ZUNvbmZpZ3x8KGUuSGl2ZUNvbmZpZz17fSkpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3cmJihcInVuZGVmaW5lZFwiPT10eXBlb2Ygd2luZG93LkhpdmVDb25maWcmJih3aW5kb3cuSGl2ZUNvbmZpZz17fSksd2luZG93LkhpdmVDb25maWcuRXJyb3JNb25pdG9yPWEuRXJyb3JNb25pdG9yKX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByLG49dGhpcyYmdGhpcy5fX2V4dGVuZHN8fGZ1bmN0aW9uKHQsZSl7ZnVuY3Rpb24gaSgpe3RoaXMuY29uc3RydWN0b3I9dH1mb3IodmFyIHIgaW4gZSllLmhhc093blByb3BlcnR5KHIpJiYodFtyXT1lW3JdKTt0LnByb3RvdHlwZT1udWxsPT09ZT9PYmplY3QuY3JlYXRlKGUpOihpLnByb3RvdHlwZT1lLnByb3RvdHlwZSxuZXcgaSl9LG89aSgyOCkuQ3Iscz1pKDEpLGE9aSgyKSxjPWkoNSksaD1pKDEzKSxwPWkoMTApLHU9aSgyMyk7IWZ1bmN0aW9uKHQpe3ZhciBlPVwiW1RSQUNLXSBcIjt0Lk9yPVwiaGl2ZS1jbGllbnQtdHJhY2tcIix0LlByPVwidHJhY2tldmVudFwiLHQuQXI9XCJOVUxMSURcIix0Lk5yPVwiXCI7dmFyIGk9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7fXJldHVybiB0fSgpO2kueHI9MCxpLkJyPTEsaS5Gcj0yLGkuX3I9MTAwLGkuRHI9MjAwLHQuSHI9aTt2YXIgcjshZnVuY3Rpb24odCl7dFt0Lk49MF09XCJQTEFZSU5HXCIsdFt0LkxyPTFdPVwiQlVGRkVSSU5HXCIsdFt0Llc9Ml09XCJQQVVTRURcIix0W3QuSD0zXT1cIlNLSVBcIix0W3QuRD00XT1cIlNUT1BQRURcIix0W3QuRVJST1I9NV09XCJFUlJPUlwiLHRbdC5Ncj02XT1cIldJTkRPV19TSVpFXCIsdFt0Lkw9N109XCJGVUxMU0NSRUVOXCIsdFt0LmpyPThdPVwiVklTSUJMRVwiLHRbdC5ISURERU49OV09XCJISURERU5cIn0ocj10LkJ8fCh0LkI9e30pKTt2YXIgbDshZnVuY3Rpb24odCl7dFt0LlVyPTBdPVwiSkFWQV9OT1RfUkVBQ0hBQkxFXCIsdFt0LlZyPTFdPVwiSkFWQV9OT1RfUkVBRFlcIix0W3QuUXI9Ml09XCJKQVZBX1dST05HX1ZFUlNJT05cIix0W3QucXI9M109XCJKQVZBX1NFU1NJT05fQlVTWVwiLHRbdC5Kcj00XT1cIkpBVkFfU0VTU0lPTl9FUlJPUlwiLHRbdC5Lcj01XT1cIkpBVkFfVElDS0VUX1RJTUVPVVRcIn0obD10LkdyfHwodC5Hcj17fSkpO3ZhciBkPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTt0LnpyPWQ7dmFyIGY9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7fXJldHVybiB0fSgpO3QuV3I9Zjt2YXIgZz1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHR9KCk7dC4kcj1nO3ZhciB2PWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMudHlwZT1pLkZyfXJldHVybiB0fSgpLHk9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7dGhpcy5zZXNzaW9ucz1uZXcgQXJyYXl9cmV0dXJuIHQucHJvdG90eXBlLllyPWZ1bmN0aW9uKHQsZSl7dmFyIGk7dGhpcy5zZXNzaW9ucy5mb3JFYWNoKGZ1bmN0aW9uKGUpe2Uuc2Vzc2lvbklkPT10JiYoaT1lKX0pLGl8fChpPW5ldyBtLGkuc2Vzc2lvbklkPXQsdGhpcy5zZXNzaW9ucy5wdXNoKGkpKSxpLmV2ZW50cy5wdXNoKGUpfSx0fSgpO3QuWHI9eTt2YXIgbT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt0aGlzLmV2ZW50cz1uZXcgQXJyYXl9cmV0dXJuIHR9KCk7dC5acj1tO3ZhciB3PWZ1bmN0aW9uKCl7ZnVuY3Rpb24gaSgpe3RoaXMubT1hLkZyYW1ld29yay5yZXNvbHZlKGEuRnJhbWV3b3JrLkZlLndlKS5sb2coKSx0aGlzLnRuPWEuRnJhbWV3b3JrLnJlc29sdmUoYy5naS5jaSksdGhpcy5lbj1uZXcgQXJyYXksdGhpcy5pbj1uZXcgQXJyYXksdGhpcy5ybj1uZXcgQXJyYXl9cmV0dXJuIGkucHJvdG90eXBlLm5uPWZ1bmN0aW9uKHQpe3RoaXMuY2xpZW50PXR9LGkucHJvdG90eXBlLmluaXQ9ZnVuY3Rpb24odCxpKXt0aGlzLnNuPXQsdGhpcy5hbihpKSx0aGlzLm0uZGVidWcoZStcIklOSVQgSUQ6IFwiK3QpfSxpLnByb3RvdHlwZS5hbj1mdW5jdGlvbih0LGUpe3RoaXMuYXBwPXQsZSYmKHRoaXMuY249ZSl9LGkucHJvdG90eXBlLmhuPWZ1bmN0aW9uKHQpe3RoaXMucG49dH0saS5wcm90b3R5cGUudW49ZnVuY3Rpb24odCl7dmFyIGU9bmV3IFModCx0aGlzKTt0aGlzLmVuLnB1c2goZSksdGhpcy5sbj1udWxsLHRoaXMuY2xpZW50LmRuKCEwKX0saS5wcm90b3R5cGUud2k9ZnVuY3Rpb24odCxpLHIpe2lmKCF0aGlzLmxuKWZvcih2YXIgbj0wO248dGhpcy5lbi5sZW5ndGg7bisrKXt2YXIgbz10aGlzLmVuW25dO2lmKG8udGlja2V0LnNlc3Npb25JZD09PXQpe3RoaXMubS5kZWJ1ZyhlK1wiQWN0aXZhdGluZyBUcmFjayBmb3Igc2Vzc2lvbiBcIit0KSx0aGlzLmxuPW87YnJlYWt9fWlmKHRoaXMubG4pe2lmKHRoaXMubG4udGlja2V0LnNlc3Npb25JZCE9dClyZXR1cm4gdm9pZCB0aGlzLm0ud2FybihlK1wiaWdub3JpbmcgbWFuaWZlc3Qgbm90IG1hdGNoaW5nIGV2ZW50IFwiK3RoaXMubG4udGlja2V0LnNlc3Npb25JZCtcIiAhPSBcIit0KTtpZighdGhpcy5sbi5mbil7dmFyIHM9bmV3IGIodCxpLHIpO3RoaXMubG4uZ24ocyksdGhpcy5jbGllbnQuZG4oKX19fSxpLnByb3RvdHlwZS52bj1mdW5jdGlvbih0LGUsaSl7bnVsbCE9dGhpcy5sbiYmKHRoaXMubG4uZm58fHRoaXMubG4ueW4ucHVzaChuZXcgayh0LGUsaSkpKX0saS5wcm90b3R5cGUubW49ZnVuY3Rpb24odCxlLGkpe3RoaXMuaW4ucHVzaChuZXcgSSh0LGUsaSkpLHRoaXMuY2xpZW50LmRuKCl9LGkucHJvdG90eXBlLnduPWZ1bmN0aW9uKHQsZSxpKXt0aGlzLnJuLnB1c2gobmV3IFIodCxlLGkpKSx0aGlzLmNsaWVudC5kbigpfSxpLnByb3RvdHlwZS5Ubj1mdW5jdGlvbih0KXt2YXIgZT10aGlzO3QmJnQuZm9yRWFjaChmdW5jdGlvbih0KXtlLnJuLnB1c2godCl9KX0saS5wcm90b3R5cGUuU249ZnVuY3Rpb24oKXt2YXIgdD1uZXcgZjt0aGlzLmNuPyh0LnBhcnRuZXJJZD10aGlzLmNuLnBhcnRuZXJJZCx0LmN1c3RvbWVySWQ9dGhpcy5jbi5jdXN0b21lcklkKTp0aGlzLmxuJiYodC5wYXJ0bmVySWQ9dGhpcy5sbi50aWNrZXQuYm4oKSx0LmN1c3RvbWVySWQ9dGhpcy5sbi50aWNrZXQuRW4oKSksdC52ZXJzaW9uPXRoaXMuYXBwLmFwcCtcIl9cIisodGhpcy5jbj90aGlzLmNuLnZlcnNpb246dGhpcy5hcHAudmVyc2lvbiksdGhpcy5jbiYmKHQuaW5zdGFsbFZlcnNpb249dGhpcy5jbi5pbnN0YWxsVmVyc2lvbix0Lmluc3RhbGxUcz10aGlzLmNuLmluc3RhbGxUcyk7dmFyIGU9bmV3IG87cmV0dXJuIGUuSW4obmF2aWdhdG9yLnVzZXJBZ2VudCksdC5vcz1lLlJuKCkubmFtZStcIiBcIitlLlJuKCkudmVyc2lvbix0aGlzLnBuJiYodC5jb21tVmVyc2lvbj10aGlzLnBuLmNvbW1WZXJzaW9uLHQucGx1Z2luTmFtZT10aGlzLnBuLnBsdWdpbk5hbWUsdC5wbHVnaW5WZXJzaW9uPXRoaXMucG4ucGx1Z2luVmVyc2lvbix0LnBsYXllclRlY2g9dGhpcy5wbi5wbGF5ZXJUZWNoLHQucGxheWVyVmVyc2lvbj10aGlzLnBuLnBsYXllclZlcnNpb24sdGhpcy5wbi50ZWxlbWV0cnlJZCYmKHQudGVsZW1ldHJ5SWQ9dGhpcy5wbi50ZWxlbWV0cnlJZCkpLHR9LGkucHJvdG90eXBlLmtuPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubG4/dGhpcy5sbjp0aGlzLmVuJiZ0aGlzLmVuLmxlbmd0aD4wP3RoaXMuZW5bdGhpcy5lbi5sZW5ndGgtMV06dm9pZCAwfSxpLnByb3RvdHlwZS5Dbj1mdW5jdGlvbigpe3ZhciBlPXRoaXMsaT1zLmRlZmVyKCk7MD09dGhpcy5lbi5sZW5ndGgmJjA9PXRoaXMuaW4ubGVuZ3RoJiZpLnJlamVjdChcIm5vdGhpbmcgdG8gc2VuZFwiKTt2YXIgcj1uZXcgZDtyLmFwcD10Lk9yLHIuY3JlYXRlZEF0PWEuRnJhbWV3b3JrLnRpbWUoKSxyLmd1aWQ9dGhpcy5zbixyLm5hbWU9dC5Qcjt2YXIgbj10aGlzLmtuKCk7aWYobil7dmFyIG89bi50aWNrZXQuT24oKS5yZXBsYWNlKC9bXFxbXFxdXS9nLFwiXCIpO3IudGFncz1bb10sci50YWdzLnB1c2gobi50aWNrZXQuYm4oKSksci50YWdzLnB1c2gobi50aWNrZXQuRW4oKSl9ZWxzZSByLnRhZ3M9bmV3IEFycmF5O3ZhciBjPW5ldyB5O3JldHVybiBjLnBlZXI9dGhpcy5TbigpLHRoaXMuZW4uZm9yRWFjaChmdW5jdGlvbih0KXt0LmZufHxjLllyKHQudGlja2V0LnNlc3Npb25JZCx0KX0pLHRoaXMuaW4uZm9yRWFjaChmdW5jdGlvbih0KXtjLllyKHQuc2Vzc2lvbklkLHQpfSksdGhpcy5ybi5mb3JFYWNoKGZ1bmN0aW9uKHQpe2MuWXIodC5zZXNzaW9uSWQsdCl9KSxyLmRhdGE9Yyx0aGlzLnRuLlBuKCkudGhlbihmdW5jdGlvbih0KXt2YXIgaT1lLkFuKHQpO2MuWXIoXCJudWxsXCIsaSl9KS5mYWlsKGZ1bmN0aW9uKHQpe30pW1wiZmluYWxseVwiXShmdW5jdGlvbigpe3JldHVybiBpLnJlc29sdmUocil9KS5kb25lKCksaS52dH0saS5wcm90b3R5cGUuQW49ZnVuY3Rpb24odCl7dmFyIGU9bmV3IHY7ZS50cz1hLkZyYW1ld29yay50aW1lKCk7dmFyIGk9dC5ObigpO3JldHVybiBpLnhuKCkmJihlLnB1YklwPWkueG4oKSksaS5CbigpJiYoZS5wcml2SXA9aS5CbigpKSx0LkZuKCkmJihlLmhvc3RuYW1lPXQuRm4oKSksaS5fbigpJiYoZS5uZXRtYXNrPWkuX24oKSksaS5EbigpJiYoZS5uaWM9aS5EbigpKSxpLkhuKCkmJihlLm5pY05hbWU9aS5IbigpKSxpLkxuKCkmJihlLm1hYz1pLkxuKCkpLGV9LGkucHJvdG90eXBlLk1uPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuY24/dGhpcy5jbi51c2VyQWdlbnQ6bmF2aWdhdG9yLnVzZXJBZ2VudH0saS5wcm90b3R5cGUucmVzZXQ9ZnVuY3Rpb24oKXt0aGlzLmVuPW5ldyBBcnJheSx0aGlzLmluPW5ldyBBcnJheSx0aGlzLnJuPW5ldyBBcnJheX0saS5wcm90b3R5cGUuam49ZnVuY3Rpb24odCl7fSxpfSgpO3QuVW49dzt2YXIgVD1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCl7dGhpcy5Wbj1pc05hTih1LkhpdmVDb25maWcuRGVidWdMb2dzLlRyYWNrU25hcHNob3RMb2dzKT8wOnUuSGl2ZUNvbmZpZy5EZWJ1Z0xvZ3MuVHJhY2tTbmFwc2hvdExvZ3MsdGhpcy5Rbj10LHRoaXMubT1hLkZyYW1ld29yay5yZXNvbHZlKGEuRnJhbWV3b3JrLkZlLndlKS5sb2coKSx0aGlzLmNsaWVudD1hLkZyYW1ld29yay5yZXNvbHZlKGMuZ2kuQmUpLHRoaXMuUW4ubm4odGhpcyl9cmV0dXJuIHQucHJvdG90eXBlLmRuPWZ1bmN0aW9uKHQpe3ZvaWQgMD09PXQmJih0PSExKTt2YXIgZT10P2guS24uSm4ucW46aC5Lbi5Kbi5HbjtpZih0aGlzLnpuKXt2YXIgaT10aGlzLlduLShuZXcgRGF0ZSkuZ2V0VGltZSgpO2k+ZSYmKGEuRnJhbWV3b3JrLmNsZWFyVGltZW91dCh0aGlzLnpuKSx0aGlzLlduPW51bGwsdGhpcy4kbihlKSl9ZWxzZSB0aGlzLiRuKGUpfSx0LnByb3RvdHlwZS4kbj1mdW5jdGlvbih0KXt2YXIgZT10aGlzO3RoaXMuem49YS5GcmFtZXdvcmsuc2V0VGltZW91dChmdW5jdGlvbigpe2UuWW4oKX0sdCksdGhpcy5Xbj0obmV3IERhdGUpLmdldFRpbWUoKSt0fSx0LnByb3RvdHlwZS5Zbj1mdW5jdGlvbigpe3ZhciB0PXRoaXM7dGhpcy56bj1udWxsLHRoaXMuV249bnVsbCx0aGlzLm0uZGVidWcoZStcIlRBS0lORyBBIFRSQUNLIFNOQVBTSE9UXCIpLFxuICB0aGlzLlFuLkNuKCkudGhlbihmdW5jdGlvbihlKXtyZXR1cm4gdC5mb3J3YXJkKGUpfSlbXCJmaW5hbGx5XCJdKGZ1bmN0aW9uKCl7cmV0dXJuIHQuUW4ucmVzZXQoKX0pfSx0LnByb3RvdHlwZS5mb3J3YXJkPWZ1bmN0aW9uKHQpe2lmKHRoaXMuY2xpZW50JiZ0aGlzLmNsaWVudC5YbigpKXt2YXIgaT1KU09OLnN0cmluZ2lmeSh0KTtzd2l0Y2godGhpcy5Wbil7Y2FzZSAwOmRlZmF1bHQ6dGhpcy5tLmRlYnVnKGUrXCJUUkFDSyBFVkVOVFwiKTticmVhaztjYXNlIDE6dGhpcy5tLmRlYnVnKGUrXCJUUkFDSyBFVkVOVDpcIitpKX12YXIgcj1uZXcgcC5abihTZXJ2aWNlcy50bywyLGkpO3RoaXMuY2xpZW50LlhuKCkuc2VuZChyKX19LHR9KCk7dC5lbz1UO3ZhciBTPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0LGUpe3RoaXMuY3JlYXRlZEF0PShuZXcgRGF0ZSkuZ2V0VGltZSgpLHRoaXMuZm49ITEsdGhpcy50aWNrZXQ9dCx0aGlzLm1hbmlmZXN0cz1uZXcgQXJyYXksdGhpcy55bj1uZXcgQXJyYXksdGhpcy5Rbj1lfXJldHVybiB0LnByb3RvdHlwZS5nbj1mdW5jdGlvbih0KXt0aGlzLm1hbmlmZXN0cy5wdXNoKHQpfSx0LnByb3RvdHlwZS50b0pTT049ZnVuY3Rpb24oKXt2YXIgdD17fTt0LnR5cGU9aS54cix0LnRpY2tldD17fSx0LnRpY2tldC51cmw9dGhpcy50aWNrZXQudGlja2V0VXJsLHQudGlja2V0LnJlcVRzPXRoaXMudGlja2V0LmlvLHQudGlja2V0LnJlc3BUcz10aGlzLnRpY2tldC5ybyx0LnRpY2tldC51c2VyQWdlbnQ9dGhpcy5Rbi5NbigpLHQubWFuaWZlc3RzPVtdLHRoaXMubWFuaWZlc3RzLmZvckVhY2goZnVuY3Rpb24oZSl7dmFyIGk9e307aS51cmw9ZS51cmwsaS5yZXNwVHM9ZS5ybyxpLnJlc3BDb2RlPWUucmVzcENvZGUsdC5tYW5pZmVzdHMucHVzaChpKX0pO3ZhciBlPS0xLHI9LTEsbj0tMTtyZXR1cm4gdGhpcy55bi5mb3JFYWNoKGZ1bmN0aW9uKHQpe3Qubm8+MCYmKGU9PS0xJiYoZT10LnRzLHI9dC5ubyksbj10Lm5vKX0pLGUhPS0xJiYodC5wbGF5VHM9ZSksbiE9LTEmJih0LmJ1ZmZUaW1lPW4pLHIhPS0xJiYodC5pbml0QnVmZlRpbWU9ciksdH0sdH0oKTt0Lm9vPVM7dmFyIGI9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQsZSxpKXt0aGlzLmV2ZW50SWQ9dCx0aGlzLnVybD1lLHRoaXMucm89KG5ldyBEYXRlKS5nZXRUaW1lKCksdGhpcy5yZXNwQ29kZT1pfXJldHVybiB0fSgpO3Quc289Yjt2YXIgRT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlLGkscil7dGhpcy50cz0obmV3IERhdGUpLmdldFRpbWUoKSx0aGlzLnNlc3Npb25JZD10LHRoaXMuc2Vzc2lvbklkfHwodGhpcy5zZXNzaW9uSWQ9XCJudWxsXCIpLHRoaXMuZXZlbnQ9ZSx0aGlzLmFvPWksciYmKHRoaXMudHM9cil9cmV0dXJuIHQucHJvdG90eXBlLnRvSlNPTj1mdW5jdGlvbigpe3ZhciB0PXt9O3JldHVybiB0LnR5cGU9dGhpcy5jbyt0aGlzLmV2ZW50LHQudHM9dGhpcy50cyx0aGlzLmFvJiYodC5wYXJhbWV0ZXJzPXRoaXMuYW8pLHR9LHR9KCk7dC5obz1FO3ZhciBJPWZ1bmN0aW9uKHQpe2Z1bmN0aW9uIGUoZSxyLG4sbyl7dmFyIHM9dC5jYWxsKHRoaXMsZSxyLG4sbyl8fHRoaXM7cmV0dXJuIHMuY289aS5fcixzfXJldHVybiBuKGUsdCksZX0oRSk7dC5wbz1JO3ZhciBSPWZ1bmN0aW9uKHQpe2Z1bmN0aW9uIGUoZSxyLG4sbyl7dmFyIHM9dC5jYWxsKHRoaXMsZSxyLG4sbyl8fHRoaXM7cmV0dXJuIHMuY289aS5EcixzfXJldHVybiBuKGUsdCksZX0oRSk7dC51bz1SO3ZhciBrPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0LGUsaSl7dGhpcy50cz0obmV3IERhdGUpLmdldFRpbWUoKSx0aGlzLmxyPXQsdGhpcy5sbz1lLHRoaXMubm89aX1yZXR1cm4gdH0oKTt0LmRvPWt9KHI9ZS5GfHwoZS5GPXt9KSl9LGZ1bmN0aW9uKHQsZSl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gaSgpe2lmKHRoaXMuZm8pcmV0dXJuIHRoaXMuZm87dmFyIHQ9d2luZG93JiZ3aW5kb3cud2luZG93P3dpbmRvdy53aW5kb3cudm86dm9pZCAwO2lmKFwidW5kZWZpbmVkXCIhPXR5cGVvZiB0JiZ0LmxvZyYmdC5kZWJ1ZyYmdC5pbmZvJiZ0Lndhcm4mJnQuZXJyb3ImJih0aGlzLmZvPXQpLCF0aGlzLmZvKXt2YXIgZT0hKFwidW5kZWZpbmVkXCI9PXR5cGVvZiB3aW5kb3cuY29uc29sZSksaT1lP2NvbnNvbGUubG9nLmJpbmQoY29uc29sZSk6ZnVuY3Rpb24oKXt9O3RoaXMuZm89e2xvZzppLGRlYnVnOmUmJndpbmRvdy5jb25zb2xlLmRlYnVnP3dpbmRvdy5jb25zb2xlLmRlYnVnLmJpbmQoY29uc29sZSk6aSxpbmZvOmUmJndpbmRvdy5jb25zb2xlLmluZm8/d2luZG93LmNvbnNvbGUuaW5mby5iaW5kKGNvbnNvbGUpOmksd2FybjplJiZ3aW5kb3cuY29uc29sZS53YXJuP3dpbmRvdy5jb25zb2xlLndhcm4uYmluZChjb25zb2xlKTppLGVycm9yOmUmJndpbmRvdy5jb25zb2xlLmVycm9yP3dpbmRvdy5jb25zb2xlLmVycm9yLmJpbmQoY29uc29sZSk6aX19cmV0dXJuIHRoaXMuZm99ZS51PVwiW0hpdmVTZXJ2aWNlc10gXCI7dmFyIHI9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7fXJldHVybiB0fSgpO3IueW89MjUwLGUua2U9cjt2YXIgbj1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlLGkpe3RoaXMubXNnSWQ9ZSx0aGlzLnNlcnZpY2U9dCx0aGlzLm1zZz1pfXJldHVybiB0LnByb3RvdHlwZS5tbz1mdW5jdGlvbigpe3ZhciB0PW5ldyBVaW50OEFycmF5KFt0aGlzLnNlcnZpY2U+PjgsMjU1JnRoaXMuc2VydmljZV0pLGU9bmV3IFVpbnQ4QXJyYXkoW3RoaXMubXNnSWRdKSxpPVt0LGUsdGhpcy5tc2ddO3JldHVybiBuZXcgQmxvYihpLHt0eXBlOlwiYXBwbGljYXRpb24vb2N0ZXQtYmluYXJ5XCJ9KX0sdC53bz1mdW5jdGlvbihlKXt2YXIgaT0oU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLG5ldyBVaW50OEFycmF5KGUpKSxTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsbmV3IFVpbnQ4QXJyYXkoZS5zbGljZSgzKSkpKSxyPW5ldyBVaW50OEFycmF5KGUuc2xpY2UoMCwyKSksbj1uZXcgVWludDhBcnJheShlLnNsaWNlKDIsMykpLG89KHJbMF08PDgpK3JbMV07cmV0dXJuIG5ldyB0KG8sblswXSxpKX0sdH0oKTtlLlpuPW4sZS5tPWl9LGZ1bmN0aW9uKHQsZSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGk7IWZ1bmN0aW9uKHQpe3ZhciBlPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTtlLkxvZ2dlclRpbWVzdGFtcD0hMCx0LkZyYW1ld29yaz1lO3ZhciBpPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTtpLk1ldHJpY1NuYXBzaG90TG9ncz0wLGkuVHJhY2tTbmFwc2hvdExvZ3M9MCx0LkRlYnVnTG9ncz1pfShpPWUuSGl2ZUNvbmZpZ3x8KGUuSGl2ZUNvbmZpZz17fSkpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3cmJihcInVuZGVmaW5lZFwiPT10eXBlb2Ygd2luZG93LkhpdmVDb25maWcmJih3aW5kb3cuSGl2ZUNvbmZpZz17fSksd2luZG93LkhpdmVDb25maWcuRnJhbWV3b3JrPWkuRnJhbWV3b3JrLHdpbmRvdy5IaXZlQ29uZmlnLkRlYnVnTG9ncz1pLkRlYnVnTG9ncyl9LGZ1bmN0aW9uKHQsZSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGk9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7fXJldHVybiB0fSgpO2kuVG89XCIxMjcuMC4wLjFcIixpLmJyPTg5OTksaS5Tcj04OTk4LGkuVHI9ODg5OSxpLm1yPTg4OTgsaS5Tbz1cIi8vezB9OnsxfS8/Y2FsbGJhY2s9ezJ9ezN9aGl2ZVBsdWdpbklkPXs0fVwiLGkuYm89XCIvL3swfTp7MX0vP2NhbGxiYWNrPXsyfVwiLGkuRXI9ITAsaS5Fbz0vKChodHRwfGh0dHBzKTpcXC9cXC8oLiopOihbMC05XSopXFwvKFswLTlhLXotXSopLmlzbVxcLykoLiopLyxpLklvPVwiMjAxMy4xLjFcIixlLndyPWl9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcjshZnVuY3Rpb24odCl7dC5Sbz0hMDt2YXIgZT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHR9KCk7ZS5rbz1cIndzczovL2JlZS5oaXZlc3RyZWFtaW5nLmNvbTo0NDMvdjEvaGl2ZWpzXCIsZS5Dbz1cIndzczovL2JlZS10ZXN0LmhpdmVzdHJlYW1pbmcuY29tOjQ0My92MS9oaXZlanNcIixlLk9vPXtpY2VTZXJ2ZXJzOlt7dXJsOlwic3R1bjpzdHVuLmhpdmVzdHJlYW1pbmcuY29tOjM2NzhcIn1dfSxlLlBvPTNlNCxlLkduPTNlNSxlLnFuPThlNCxlLkFvPTNlNCxlLk5vPTEwMCxlLnhvPTFlNCx0LkpuPWV9KHI9ZS5Lbnx8KGUuS249e30pKX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByLG49aSg0KSxvPW4udmUscz1pKDEpLGE9aSgyKSxjPWkoOSksaD1pKDUpLHA9aSgyNyk7IWZ1bmN0aW9uKHQpe3RbdC5JRExFPTBdPVwiSURMRVwiLHRbdC5Cbz0xXT1cIlBMQVlcIn0ocj1lLkZvfHwoZS5Gbz17fSkpO3ZhciB1PWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0LGUsaSxyKXt0aGlzLnRpY2tldD10LHRoaXMuX289ZSx0aGlzLmFwcD1pLHRoaXMuaWRlbnRpdHk9cix0aGlzLkRvPWEuRnJhbWV3b3JrLnJlc29sdmUoaC5naS5saSksdGhpcy5Ibz1hLkZyYW1ld29yay5yZXNvbHZlKGguZ2kuc2kpLHRoaXMuUW49YS5GcmFtZXdvcmsucmVzb2x2ZShoLmdpLmRpKSx0aGlzLkxvPW5ldyBjLkYuZW8odGhpcy5Rbil9cmV0dXJuIHQucHJvdG90eXBlLmFuPWZ1bmN0aW9uKHQsZSxpKXt0aGlzLmFwcD1uZXcgbCh0LGUpLHRoaXMuRG8uYW4odGhpcy5hcHApLHRoaXMuUW4uYW4odGhpcy5hcHAsaSl9LHQucHJvdG90eXBlLkNpPWZ1bmN0aW9uKHQpe3RoaXMuSG8uQ2kodCl9LHR9KCk7ZS5Nbz11O3ZhciBsPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0LGUpe3RoaXMuYXBwPXQsdGhpcy52ZXJzaW9uPWV9cmV0dXJuIHR9KCk7ZS5qbz1sO3ZhciBkPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMuVW89bnVsbCx0aGlzLlZvPW51bGwsdGhpcy5Rbz1uZXcgbyx0aGlzLm09YS5GcmFtZXdvcmsucmVzb2x2ZShhLkZyYW1ld29yay5GZS53ZSkubG9nKCksdGhpcy5tLmRlYnVnKFwiSU5JVCBSRVBPUlRJTkdcIiksdGhpcy5fbz1hLkZyYW1ld29yay5yZXNvbHZlKGguZ2kuQmUpLHRoaXMucW89YS5GcmFtZXdvcmsucmVzb2x2ZShoLmdpLkNlKSx0aGlzLkpvPWEuRnJhbWV3b3JrLnJlc29sdmUoaC5naS5haSl9cmV0dXJuIHQucHJvdG90eXBlLmluaXRTZXNzaW9uPWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcyxyPXMuZGVmZXIoKSxuPXRoaXMucW8uS28oKSxvPXRoaXMuSm8uR28odCk7cmV0dXJuIG51bGwhPW8/bi50aGVuKGZ1bmN0aW9uKHQpe3JldHVybiBpLnpvKHQsbyxyLGUpfSkuZmFpbChyLnJlamVjdCk6ci5yZWplY3QoXCJUaWNrZXQgVVJMIG5vdCB2YWxpZFwiKSxyLnZ0fSx0LnByb3RvdHlwZS5jbG9zZT1mdW5jdGlvbigpe3RoaXMuX28uY2xvc2UoKX0sdC5wcm90b3R5cGUuem89ZnVuY3Rpb24odCxlLGkscil7dmFyIG49dGhpczt0aGlzLlVvPXQuV28oKSx0aGlzLlZvPXQuJG8oKTt2YXIgbz10aGlzLl9vLmluaXQodGhpcy5VbyxlKSxzPXRoaXMuSm8ucmVzb2x2ZShvLllvLGUscik7by52dC50aGVuKGZ1bmN0aW9uKGUpe3MudGhlbihmdW5jdGlvbihlKXt2YXIgcj1lLnNlc3Npb25JZDtpZihuLlFvLmhhcyhyKSl7dmFyIG89bi5Rby5nZXQocik7bi5tLndhcm4oXCJTRVNTSU9OIEFMUkVBRFkgRVhJU1RJTkcgXCIrby5Eby50aWNrZXQpfWVsc2V7dmFyIHM9bmV3IGwocC5IaXZlLlhvKCkscC5IaXZlLmdldFZlcnNpb24oKSksYT1uZXcgdShlLG4uX28scyx0KTthLkRvLmluaXQobi5WbyxlLHMsciksYS5Rbi5pbml0KG4uVm8scyksYS5Rbi51bihlKSxuLlFvLnNldChyLGEpLG4ubS5kZWJ1ZyhcIlNFU1NJT04gU0VUIFwiLHIpLGkucmVzb2x2ZShhKX19KS5mYWlsKGZ1bmN0aW9uKHQpe3JldHVybiBpLnJlamVjdCh0P3Q6XCJFcnJvciByZXNvbHZpbmcgdGhlIHRpY2tldFwiKX0pLGUub25lcnJvcihmdW5jdGlvbih0KXtpLnJlamVjdChcIkVycm9yIGVzdGFibGlzaGluZyBjb25uZWN0aW9uIHRvIEhpdmUgU2VydmljZXNcIil9KX0pLmZhaWwoZnVuY3Rpb24odCl7cmV0dXJuIGkucmVqZWN0KHQpfSksdGhpcy5fby5jb25uZWN0KCl9LHQucHJvdG90eXBlLlpvPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHQuZXMoKT09PWUuZXMoKSYmdC5FbigpPT09ZS5FbigpJiZ0LmJuKCk9PT1lLmJuKCl9LHR9KCk7ZS5ycz1kfSxmdW5jdGlvbih0LGUsaSl7dmFyIHIscjshZnVuY3Rpb24oZSl7dC50PWUoKX0oZnVuY3Rpb24oKXtyZXR1cm4gZnVuY3Rpb24gdChlLGksbil7ZnVuY3Rpb24gbyhhLGMpe2lmKCFpW2FdKXtpZighZVthXSl7dmFyIGg9XCJmdW5jdGlvblwiPT10eXBlb2YgciYmcjtpZighYyYmaClyZXR1cm4gcihhLCEwKTtpZihzKXJldHVybiBzKGEsITApO3ZhciBwPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrYStcIidcIik7dGhyb3cgcC5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLHB9dmFyIHU9aVthXT17dDp7fX07ZVthXVswXS5jYWxsKHUudCxmdW5jdGlvbih0KXt2YXIgaT1lW2FdWzFdW3RdO3JldHVybiBvKGk/aTp0KX0sdSx1LnQsdCxlLGksbil9cmV0dXJuIGlbYV0udH1mb3IodmFyIHM9XCJmdW5jdGlvblwiPT10eXBlb2YgciYmcixhPTA7YTxuLmxlbmd0aDthKyspbyhuW2FdKTtyZXR1cm4gb30oezE6W2Z1bmN0aW9uKHQsZSxpKXt2YXIgcj10KFwiLi9rZXJuZWxcIik7aS5JZT1yLkllO3ZhciBuPXQoXCIuL3R5cGVfYmluZGluZ1wiKTtpLm5zPW4ubnM7dmFyIG89dChcIi4vdHlwZV9iaW5kaW5nX3Njb3BlXCIpO2kuc3M9by5zc30se1wiLi9rZXJuZWxcIjoyLFwiLi90eXBlX2JpbmRpbmdcIjo0LFwiLi90eXBlX2JpbmRpbmdfc2NvcGVcIjo1fV0sMjpbZnVuY3Rpb24odCxlLGkpe3ZhciByPXQoXCIuL3R5cGVfYmluZGluZ19zY29wZVwiKSxuPXQoXCIuL2xvb2t1cFwiKSxvPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMuYXM9bmV3IG4uY3N9cmV0dXJuIHQucHJvdG90eXBlLmJpbmQ9ZnVuY3Rpb24odCl7dGhpcy5hcy5hZGQodC5ocyx0KX0sdC5wcm90b3R5cGUucHM9ZnVuY3Rpb24odCl7dHJ5e3RoaXMuYXMucmVtb3ZlKHQpfWNhdGNoKGUpe3Rocm93IG5ldyBFcnJvcihcIkNvdWxkIG5vdCByZXNvbHZlIHNlcnZpY2UgXCIrdCl9fSx0LnByb3RvdHlwZS5FZT1mdW5jdGlvbigpe3RoaXMuYXM9bmV3IG4uY3N9LHQucHJvdG90eXBlLnJlc29sdmU9ZnVuY3Rpb24odCl7dmFyIGU7aWYoIXRoaXMuYXMudXModCkpcmV0dXJuIG51bGw7ZT10aGlzLmFzLmdldCh0KTt2YXIgaT1lWzBdO2lmKGkuc2NvcGU9PT1yLnNzLmxzJiZudWxsIT09aS5kcylyZXR1cm4gaS5kczt2YXIgbj10aGlzLmZzKGkuZ3MpO3JldHVybiBpLmRzPW4sbn0sdC5wcm90b3R5cGUudnM9ZnVuY3Rpb24odCl7dmFyIGUsaSxyLG4sbyxzO3JldHVybiBvPS8oKFxcL1xcLy4qJCl8KFxcL1xcKltcXHNcXFNdKj9cXCpcXC8pKS9nbSxzPS8oW15cXHMsXSspL2csZT10LnRvU3RyaW5nKCkucmVwbGFjZShvLFwiXCIpLGk9ZS5pbmRleE9mKFwiKFwiKSsxLHI9ZS5pbmRleE9mKFwiKVwiKSxuPVwiZnVuY3Rpb25cIj09dHlwZW9mIE1hcCYmLTEhPT1lLmluZGV4T2YoXCJjbGFzc1wiKSYmLTE9PT1lLmluZGV4T2YoXCJjb25zdHJ1Y3RvclwiKT9udWxsOmUuc2xpY2UoaSxyKS5tYXRjaChzKSxudWxsPT09biYmKG49W10pLG59LHQucHJvdG90eXBlLmZzPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMudnModCk7aWYoMD09PWUubGVuZ3RoKXJldHVybiBuZXcgdDtmb3IodmFyIGk9W10scj1udWxsLG49MDtuPGUubGVuZ3RoO24rKyl7dmFyIG89ZVtuXTtyPXRoaXMucmVzb2x2ZShvKSxpLnB1c2gocil9cmV0dXJuIHRoaXMueXModCxpKX0sdC5wcm90b3R5cGUueXM9ZnVuY3Rpb24odCxlKXtyZXR1cm4gbmV3KEZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kLmFwcGx5KHQsW251bGxdLmNvbmNhdChlKSkpfSx0fSgpO2kuSWU9b30se1wiLi9sb29rdXBcIjozLFwiLi90eXBlX2JpbmRpbmdfc2NvcGVcIjo1fV0sMzpbZnVuY3Rpb24odCxlLGkpe3ZhciByPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0LGUpe3RoaXMua2V5PXQsdGhpcy52YWx1ZT1uZXcgQXJyYXksdGhpcy52YWx1ZS5wdXNoKGUpfXJldHVybiB0fSgpLG49ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7dGhpcy5tcz1uZXcgQXJyYXl9cmV0dXJuIHQucHJvdG90eXBlLndzPWZ1bmN0aW9uKHQpe2Zvcih2YXIgZT0tMSxpPTA7aTx0aGlzLm1zLmxlbmd0aDtpKyspe3ZhciByPXRoaXMubXNbaV07ci5rZXk9PT10JiYoZT1pKX1yZXR1cm4gZX0sdC5wcm90b3R5cGUuYWRkPWZ1bmN0aW9uKHQsZSl7aWYobnVsbD09PXR8fHZvaWQgMD09PXQpdGhyb3cgbmV3IEVycm9yKFwiQXJndW1lbnQgTnVsbFwiKTtpZihudWxsPT09ZXx8dm9pZCAwPT09ZSl0aHJvdyBuZXcgRXJyb3IoXCJBcmd1bWVudCBOdWxsXCIpO3ZhciBpPXRoaXMud3ModCk7aWYoLTEhPT1pKXt2YXIgbj10aGlzLm1zW2ldO24ua2V5PT09dCYmbi52YWx1ZS5wdXNoKGUpfWVsc2UgdGhpcy5tcy5wdXNoKG5ldyByKHQsZSkpfSx0LnByb3RvdHlwZS5nZXQ9ZnVuY3Rpb24odCl7aWYobnVsbD09PXR8fHZvaWQgMD09PXQpdGhyb3cgbmV3IEVycm9yKFwiQXJndW1lbnQgTnVsbFwiKTt2YXIgZT10aGlzLndzKHQpO2lmKC0xPT09ZSl0aHJvdyBuZXcgRXJyb3IoXCJLZXkgTm90IEZvdW5kXCIpO3ZhciBpPXRoaXMubXNbZV07cmV0dXJuIGkua2V5PT09dD9pLnZhbHVlOnZvaWQgMH0sdC5wcm90b3R5cGUucmVtb3ZlPWZ1bmN0aW9uKHQpe2lmKG51bGw9PT10fHx2b2lkIDA9PT10KXRocm93IG5ldyBFcnJvcihcIkFyZ3VtZW50IE51bGxcIik7dmFyIGU9dGhpcy53cyh0KTtpZigtMT09PWUpdGhyb3cgbmV3IEVycm9yKFwiS2V5IE5vdCBGb3VuZFwiKTt0aGlzLm1zLnNwbGljZShlLDEpfSx0LnByb3RvdHlwZS51cz1mdW5jdGlvbih0KXtpZihudWxsPT09dHx8dm9pZCAwPT09dCl0aHJvdyBuZXcgRXJyb3IoXCJBcmd1bWVudCBOdWxsXCIpO3ZhciBlPXRoaXMud3ModCk7cmV0dXJuLTEhPT1lfSx0fSgpO2kuY3M9bn0se31dLDQ6W2Z1bmN0aW9uKHQsZSxpKXt2YXIgcj10KFwiLi90eXBlX2JpbmRpbmdfc2NvcGVcIiksbj1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlLGkpe2lmKHRoaXMuaHM9dCx0aGlzLmdzPWUsdGhpcy5kcz1udWxsLFwidW5kZWZpbmVkXCI9PXR5cGVvZiBpKXRoaXMuc2NvcGU9ci5zcy5UcztlbHNle2lmKCFyLnNzW2ldKXt2YXIgbj1cIkludmFsaWQgc2NvcGUgdHlwZSBcIitpO3Rocm93IG5ldyBFcnJvcihuKX10aGlzLnNjb3BlPWl9fXJldHVybiB0fSgpO2kubnM9bn0se1wiLi90eXBlX2JpbmRpbmdfc2NvcGVcIjo1fV0sNTpbZnVuY3Rpb24odCxlLGkpe3ZhciByOyFmdW5jdGlvbih0KXt0W3QuVHM9MF09XCJUcmFuc2llbnRcIix0W3QubHM9MV09XCJTaW5nbGV0b25cIn0ocnx8KHI9e30pKSxpLnNzPXJ9LHt9XX0se30sWzFdKSgxKX0pfSxmdW5jdGlvbihtb2R1bGUsZXhwb3J0cyxfX3dlYnBhY2tfcmVxdWlyZV9fKXt2YXIgVGhyaWZ0PXtTczpcIjAuOS4yXCIsYnM6e0VzOjAsSXM6MSxCT09MOjIsQllURTozLFJzOjMsa3M6NCxDczo2LE9zOjgsUHM6MTAsQXM6MTEsTnM6MTEseHM6MTIsQnM6MTMsRnM6MTQsX3M6MTUsRHM6MTYsSHM6MTd9LExzOntNczoxLGpzOjIsVXM6MyxWczo0fSxRczpmdW5jdGlvbih0KXt2YXIgZT0wO2Zvcih2YXIgaSBpbiB0KXQuaGFzT3duUHJvcGVydHkoaSkmJmUrKztyZXR1cm4gZX0scXM6ZnVuY3Rpb24odCxlLGkpe2Z1bmN0aW9uIHIoKXt9ci5wcm90b3R5cGU9ZS5wcm90b3R5cGUsdC5wcm90b3R5cGU9bmV3IHIsdC5wcm90b3R5cGUubmFtZT1pfHxcIlwifX07VGhyaWZ0LkpzPWZ1bmN0aW9uKHQpe3RoaXMubWVzc2FnZT10fSxUaHJpZnQucXMoVGhyaWZ0LkpzLEVycm9yLFwiVEV4Y2VwdGlvblwiKSxUaHJpZnQuSnMucHJvdG90eXBlLktzPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubWVzc2FnZX0sVGhyaWZ0LkdzPXt6czowLFdzOjEsJHM6MixZczozLFhzOjQsWnM6NSx0YTo2LGVhOjcsaWE6OCxyYTo5LG5hOjEwfSxUaHJpZnQub2E9ZnVuY3Rpb24odCxlKXt0aGlzLm1lc3NhZ2U9dCx0aGlzLmNvZGU9XCJudW1iZXJcIj09dHlwZW9mIGU/ZTowfSxUaHJpZnQucXMoVGhyaWZ0Lm9hLFRocmlmdC5KcyxcIlRBcHBsaWNhdGlvbkV4Y2VwdGlvblwiKSxUaHJpZnQub2EucHJvdG90eXBlLnJlYWQ9ZnVuY3Rpb24odCl7Zm9yKDs7KXt2YXIgZT10LnNhKCk7aWYoZS5hYT09VGhyaWZ0LmJzLkVzKWJyZWFrO3ZhciBpPWUuY2E7c3dpdGNoKGkpe2Nhc2UgMTplLmFhPT1UaHJpZnQuYnMuQXM/KGU9dC5oYSgpLHRoaXMubWVzc2FnZT1lLnZhbHVlKTplPXQucGEoZS5hYSk7YnJlYWs7Y2FzZSAyOmUuYWE9PVRocmlmdC5icy5Pcz8oZT10LnVhKCksdGhpcy5jb2RlPWUudmFsdWUpOmU9dC5wYShlLmFhKTticmVhaztkZWZhdWx0OmU9dC5wYShlLmFhKX10LmxhKCl9dC5kYSgpfSxUaHJpZnQub2EucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKHQpe3QuZmEoXCJUQXBwbGljYXRpb25FeGNlcHRpb25cIiksdGhpcy5tZXNzYWdlJiYodC5nYShcIm1lc3NhZ2VcIixUaHJpZnQuYnMuQXMsMSksdC52YSh0aGlzLktzKCkpLHQueWEoKSksdGhpcy5jb2RlJiYodC5nYShcInR5cGVcIixUaHJpZnQuYnMuT3MsMiksdC5tYSh0aGlzLmNvZGUpLHQueWEoKSksdC53YSgpLHQuVGEoKX0sVGhyaWZ0Lm9hLnByb3RvdHlwZS5TYT1mdW5jdGlvbigpe3JldHVybiB0aGlzLmNvZGV9LFRocmlmdC5iYT1UaHJpZnQuRWE9ZnVuY3Rpb24odCxlKXt0aGlzLnVybD10LHRoaXMuSWE9MCx0aGlzLlJhPTAsdGhpcy5rYT1lJiZlLmthLHRoaXMuQ2E9XCJcIix0aGlzLk9hPVwiXCJ9LFRocmlmdC5FYS5wcm90b3R5cGU9e1BhOmZ1bmN0aW9uKCl7dHJ5e3JldHVybiBuZXcgWE1MSHR0cFJlcXVlc3R9Y2F0Y2godCl7fXRyeXtyZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoXCJNc3htbDIuWE1MSFRUUFwiKX1jYXRjaChlKXt9dHJ5e3JldHVybiBuZXcgQWN0aXZlWE9iamVjdChcIk1pY3Jvc29mdC5YTUxIVFRQXCIpfWNhdGNoKGkpe310aHJvd1wiWW91ciBicm93c2VyIGRvZXNuJ3Qgc3VwcG9ydCBYSFIuXCJ9LGZsdXNoOmZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcztpZih0JiYhZXx8dm9pZCAwPT09dGhpcy51cmx8fFwiXCI9PT10aGlzLnVybClyZXR1cm4gdGhpcy5DYTt2YXIgcj10aGlzLlBhKCk7aWYoci5vdmVycmlkZU1pbWVUeXBlJiZyLm92ZXJyaWRlTWltZVR5cGUoXCJhcHBsaWNhdGlvbi9qc29uXCIpLGUmJihyLm9ucmVhZHlzdGF0ZWNoYW5nZT1mdW5jdGlvbigpe3ZhciB0PWU7cmV0dXJuIGZ1bmN0aW9uKCl7ND09dGhpcy5yZWFkeVN0YXRlJiYyMDA9PXRoaXMuc3RhdHVzJiYoaS5BYSh0aGlzLnJlc3BvbnNlVGV4dCksdCgpKX19KCkpLHIub3BlbihcIlBPU1RcIix0aGlzLnVybCwhIXQpLHIuc2VuZCh0aGlzLkNhKSwhdHx8IWUpe2lmKDQhPXIucmVhZHlTdGF0ZSl0aHJvd1wiZW5jb3VudGVyZWQgYW4gdW5rbm93biBhamF4IHJlYWR5IHN0YXRlOiBcIityLnJlYWR5U3RhdGU7aWYoMjAwIT1yLnN0YXR1cyl0aHJvd1wiZW5jb3VudGVyZWQgYSB1bmtub3duIHJlcXVlc3Qgc3RhdHVzOiBcIityLnN0YXR1czt0aGlzLk9hPXIucmVzcG9uc2VUZXh0LHRoaXMuTmE9dGhpcy5PYS5sZW5ndGgsdGhpcy5JYT10aGlzLk9hLmxlbmd0aCx0aGlzLlJhPTB9fSx4YTpmdW5jdGlvbih0LGUsaSxyKXtpZihcInVuZGVmaW5lZFwiPT10eXBlb2YgalF1ZXJ5fHxcInVuZGVmaW5lZFwiPT10eXBlb2YgalF1ZXJ5LkRlZmVycmVkKXRocm93XCJUaHJpZnQuanMgcmVxdWlyZXMgalF1ZXJ5IDEuNSsgdG8gdXNlIGFzeW5jaHJvbm91cyByZXF1ZXN0c1wiO3ZhciBuPXRoaXMsbz1qUXVlcnkuYWpheCh7dXJsOnRoaXMudXJsLGRhdGE6ZSx0eXBlOlwiUE9TVFwiLGRzOiExLGNvbnRlbnRUeXBlOlwiYXBwbGljYXRpb24vanNvblwiLEJhOlwidGV4dCB0aHJpZnRcIixGYTp7X2E6ZnVuY3Rpb24oZSl7bi5BYShlKTt2YXIgaT1yLmNhbGwodCk7cmV0dXJuIGl9fSxjb250ZXh0OnQsc3VjY2VzczpqUXVlcnkubWFrZUFycmF5KGkpLnBvcCgpfSk7cmV0dXJuIG99LEFhOmZ1bmN0aW9uKHQpe3RoaXMuT2E9dCx0aGlzLk5hPXRoaXMuT2EubGVuZ3RoLHRoaXMuSWE9dGhpcy5PYS5sZW5ndGgsdGhpcy5SYT0wfSxpc09wZW46ZnVuY3Rpb24oKXtyZXR1cm4hMH0sb3BlbjpmdW5jdGlvbigpe30sY2xvc2U6ZnVuY3Rpb24oKXt9LHJlYWQ6ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5JYS10aGlzLlJhO2lmKDA9PT1lKXJldHVyblwiXCI7dmFyIGk9dDtlPHQmJihpPWUpO3ZhciByPXRoaXMucmVhZF9idWYuc3Vic3RyKHRoaXMuUmEsaSk7cmV0dXJuIHRoaXMuUmErPWkscn0sRGE6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5PYX0sd3JpdGU6ZnVuY3Rpb24odCl7dGhpcy5DYT10fSxIYTpmdW5jdGlvbigpe3JldHVybiB0aGlzLkNhfX0sVGhyaWZ0LkxhPWZ1bmN0aW9uKHQpe3RoaXMuTWEodCl9LFRocmlmdC5MYS5wcm90b3R5cGU9e01hOmZ1bmN0aW9uKHQpe3RoaXMudXJsPXQsdGhpcy5qYT1udWxsLHRoaXMuY2FsbGJhY2tzPVtdLHRoaXMuVWE9W10sdGhpcy5DYT1cIlwiLHRoaXMuT2E9XCJcIix0aGlzLlZhPTAsdGhpcy5RYT0wfSxmbHVzaDpmdW5jdGlvbih0LGUpe3ZhciBpPXRoaXM7dGhpcy5pc09wZW4oKT8odGhpcy5qYS5zZW5kKHRoaXMuQ2EpLHRoaXMuY2FsbGJhY2tzLnB1c2goZnVuY3Rpb24oKXt2YXIgdD1lO3JldHVybiBmdW5jdGlvbihlKXtpLkFhKGUpLHQoKX19KCkpKTp0aGlzLlVhLnB1c2goe3FhOnRoaXMuQ2EsSmE6ZX0pfSxLYTpmdW5jdGlvbigpe3ZhciB0PXRoaXM7dGhpcy5VYS5sZW5ndGg+MCYmKHRoaXMuVWEuZm9yRWFjaChmdW5jdGlvbihlKXt0aGlzLmphLnNlbmQoZS5xYSksdGhpcy5jYWxsYmFja3MucHVzaChmdW5jdGlvbigpe3ZhciBpPWUuSmE7cmV0dXJuIGZ1bmN0aW9uKGUpe3QuQWEoZSksaSgpfX0oKSl9KSx0aGlzLlVhPVtdKX0sR2E6ZnVuY3Rpb24odCl7dGhpcy5NYSh0aGlzLnVybCl9LHphOmZ1bmN0aW9uKHQpe3RoaXMuY2FsbGJhY2tzLmxlbmd0aCYmdGhpcy5jYWxsYmFja3Muc2hpZnQoKSh0LmRhdGEpfSxXYTpmdW5jdGlvbih0KXtjb25zb2xlLmxvZyhcIlRocmlmdCBXZWJTb2NrZXQgRXJyb3I6IFwiK3QudG9TdHJpbmcoKSksdGhpcy5qYS5jbG9zZSgpfSxBYTpmdW5jdGlvbih0KXt0aGlzLk9hPXQsdGhpcy5OYT10aGlzLk9hLmxlbmd0aCx0aGlzLklhPXRoaXMuT2EubGVuZ3RoLHRoaXMuUmE9MH0saXNPcGVuOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuamEmJnRoaXMuamEucmVhZHlTdGF0ZT09dGhpcy5qYS5PUEVOfSxvcGVuOmZ1bmN0aW9uKCl7dGhpcy5qYSYmdGhpcy5qYS5yZWFkeVN0YXRlIT10aGlzLmphLkNMT1NFRHx8KHRoaXMuamE9bmV3IFdlYlNvY2tldCh0aGlzLnVybCksdGhpcy5qYS5vbm9wZW49dGhpcy5LYS5iaW5kKHRoaXMpLHRoaXMuamEub25tZXNzYWdlPXRoaXMuemEuYmluZCh0aGlzKSx0aGlzLmphLm9uZXJyb3I9dGhpcy5XYS5iaW5kKHRoaXMpLHRoaXMuamEub25jbG9zZT10aGlzLkdhLmJpbmQodGhpcykpfSxjbG9zZTpmdW5jdGlvbigpe3RoaXMuamEuY2xvc2UoKX0scmVhZDpmdW5jdGlvbih0KXt2YXIgZT10aGlzLklhLXRoaXMuUmE7aWYoMD09PWUpcmV0dXJuXCJcIjt2YXIgaT10O2U8dCYmKGk9ZSk7dmFyIHI9dGhpcy5yZWFkX2J1Zi5zdWJzdHIodGhpcy5SYSxpKTtyZXR1cm4gdGhpcy5SYSs9aSxyfSxEYTpmdW5jdGlvbigpe3JldHVybiB0aGlzLk9hfSx3cml0ZTpmdW5jdGlvbih0KXt0aGlzLkNhPXR9LEhhOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuQ2F9fSxUaHJpZnQuJGE9VGhyaWZ0LllhPWZ1bmN0aW9uKHQpe3RoaXMuWGE9dH0sVGhyaWZ0LllhLmJzPXt9LFRocmlmdC5ZYS5ic1tUaHJpZnQuYnMuQk9PTF09J1widGZcIicsVGhyaWZ0LllhLmJzW1RocmlmdC5icy5CWVRFXT0nXCJpOFwiJyxUaHJpZnQuWWEuYnNbVGhyaWZ0LmJzLkNzXT0nXCJpMTZcIicsVGhyaWZ0LllhLmJzW1RocmlmdC5icy5Pc109J1wiaTMyXCInLFRocmlmdC5ZYS5ic1tUaHJpZnQuYnMuUHNdPSdcImk2NFwiJyxUaHJpZnQuWWEuYnNbVGhyaWZ0LmJzLmtzXT0nXCJkYmxcIicsVGhyaWZ0LllhLmJzW1RocmlmdC5icy54c109J1wicmVjXCInLFRocmlmdC5ZYS5ic1tUaHJpZnQuYnMuQXNdPSdcInN0clwiJyxUaHJpZnQuWWEuYnNbVGhyaWZ0LmJzLkJzXT0nXCJtYXBcIicsVGhyaWZ0LllhLmJzW1RocmlmdC5icy5fc109J1wibHN0XCInLFRocmlmdC5ZYS5ic1tUaHJpZnQuYnMuRnNdPSdcInNldFwiJyxUaHJpZnQuWWEuWmE9e30sVGhyaWZ0LllhLlphLnRjPVRocmlmdC5icy5CT09MLFRocmlmdC5ZYS5aYS5lYz1UaHJpZnQuYnMuQllURSxUaHJpZnQuWWEuWmEuaWM9VGhyaWZ0LmJzLkNzLFRocmlmdC5ZYS5aYS5yYz1UaHJpZnQuYnMuT3MsVGhyaWZ0LllhLlphLm5jPVRocmlmdC5icy5QcyxUaHJpZnQuWWEuWmEub2M9VGhyaWZ0LmJzLmtzLFRocmlmdC5ZYS5aYS5zYz1UaHJpZnQuYnMueHMsVGhyaWZ0LllhLlphLmFjPVRocmlmdC5icy5BcyxUaHJpZnQuWWEuWmEubWFwPVRocmlmdC5icy5CcyxUaHJpZnQuWWEuWmEuY2M9VGhyaWZ0LmJzLl9zLFRocmlmdC5ZYS5aYS5zZXQ9VGhyaWZ0LmJzLkZzLFRocmlmdC5ZYS5Tcz0xLFRocmlmdC5ZYS5wcm90b3R5cGU9e2hjOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuWGF9LHBjOmZ1bmN0aW9uKHQsZSxpKXt0aGlzLnVjPVtdLHRoaXMubGM9W10sdGhpcy51Yy5wdXNoKFtUaHJpZnQuWWEuU3MsJ1wiJyt0KydcIicsZSxpXSl9LGRjOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy51Yy5wb3AoKTt0aGlzLmZjPXRoaXMudWMucG9wKCksdGhpcy5mYy5wdXNoKHQpLHRoaXMuZ2M9XCJbXCIrdGhpcy5mYy5qb2luKFwiLFwiKStcIl1cIix0aGlzLlhhLndyaXRlKHRoaXMuZ2MpfSxmYTpmdW5jdGlvbih0KXt0aGlzLmxjLnB1c2godGhpcy51Yy5sZW5ndGgpLHRoaXMudWMucHVzaCh7fSl9LFRhOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5sYy5wb3AoKSxlPXRoaXMudWNbdF0saT1cIntcIixyPSEwO2Zvcih2YXIgbiBpbiBlKXI/cj0hMTppKz1cIixcIixpKz1uK1wiOlwiK2Vbbl07aSs9XCJ9XCIsdGhpcy51Y1t0XT1pfSxnYTpmdW5jdGlvbih0LGUsaSl7dGhpcy5sYy5wdXNoKHRoaXMudWMubGVuZ3RoKSx0aGlzLnVjLnB1c2goe3ZjOidcIicraSsnXCInLHljOlRocmlmdC5ZYS5ic1tlXX0pfSx5YTpmdW5jdGlvbigpe3ZhciB0PXRoaXMudWMucG9wKCksZT10aGlzLnVjLnBvcCgpO3RoaXMudWNbdGhpcy51Yy5sZW5ndGgtMV1bZS52Y109XCJ7XCIrZS55YytcIjpcIit0K1wifVwiLHRoaXMubGMucG9wKCl9LHdhOmZ1bmN0aW9uKCl7fSxtYzpmdW5jdGlvbih0LGUsaSl7dGhpcy5sYy5wdXNoKHRoaXMudWMubGVuZ3RoKSx0aGlzLnVjLnB1c2goW1RocmlmdC5ZYS5ic1t0XSxUaHJpZnQuWWEuYnNbZV0sMF0pfSx3YzpmdW5jdGlvbigpe3ZhciB0PXRoaXMubGMucG9wKCk7aWYodCE9dGhpcy51Yy5sZW5ndGgpeyh0aGlzLnVjLmxlbmd0aC10LTEpJTIhPT0wJiZ0aGlzLnVjLnB1c2goXCJcIik7dmFyIGU9KHRoaXMudWMubGVuZ3RoLXQtMSkvMjt0aGlzLnVjW3RdW3RoaXMudWNbdF0ubGVuZ3RoLTFdPWU7Zm9yKHZhciBpPVwifVwiLHI9ITA7dGhpcy51Yy5sZW5ndGg+dCsxOyl7dmFyIG49dGhpcy51Yy5wb3AoKSxvPXRoaXMudWMucG9wKCk7cj9yPSExOmk9XCIsXCIraSxpc05hTihvKXx8KG89J1wiJytvKydcIicpLGk9bytcIjpcIituK2l9aT1cIntcIitpLHRoaXMudWNbdF0ucHVzaChpKSx0aGlzLnVjW3RdPVwiW1wiK3RoaXMudWNbdF0uam9pbihcIixcIikrXCJdXCJ9fSxUYzpmdW5jdGlvbih0LGUpe3RoaXMubGMucHVzaCh0aGlzLnVjLmxlbmd0aCksdGhpcy51Yy5wdXNoKFtUaHJpZnQuWWEuYnNbdF0sZV0pfSxTYzpmdW5jdGlvbigpe2Zvcih2YXIgdD10aGlzLmxjLnBvcCgpO3RoaXMudWMubGVuZ3RoPnQrMTspe3ZhciBlPXRoaXMudWNbdCsxXTt0aGlzLnVjLnNwbGljZSh0KzEsMSksdGhpcy51Y1t0XS5wdXNoKGUpfXRoaXMudWNbdF09XCJbXCIrdGhpcy51Y1t0XS5qb2luKFwiLFwiKStcIl1cIn0sYmM6ZnVuY3Rpb24odCxlKXt0aGlzLmxjLnB1c2godGhpcy51Yy5sZW5ndGgpLHRoaXMudWMucHVzaChbVGhyaWZ0LllhLmJzW3RdLGVdKX0sRWM6ZnVuY3Rpb24oKXtmb3IodmFyIHQ9dGhpcy5sYy5wb3AoKTt0aGlzLnVjLmxlbmd0aD50KzE7KXt2YXIgZT10aGlzLnVjW3QrMV07dGhpcy51Yy5zcGxpY2UodCsxLDEpLHRoaXMudWNbdF0ucHVzaChlKX10aGlzLnVjW3RdPVwiW1wiK3RoaXMudWNbdF0uam9pbihcIixcIikrXCJdXCJ9LEljOmZ1bmN0aW9uKHQpe3RoaXMudWMucHVzaCh0PzE6MCl9LFJjOmZ1bmN0aW9uKHQpe3RoaXMudWMucHVzaCh0KX0sa2M6ZnVuY3Rpb24odCl7dGhpcy51Yy5wdXNoKHQpfSxtYTpmdW5jdGlvbih0KXt0aGlzLnVjLnB1c2godCl9LENjOmZ1bmN0aW9uKHQpe3RoaXMudWMucHVzaCh0KX0sT2M6ZnVuY3Rpb24odCl7dGhpcy51Yy5wdXNoKHQpfSx2YTpmdW5jdGlvbih0KXtpZihudWxsPT09dCl0aGlzLnVjLnB1c2gobnVsbCk7ZWxzZXtmb3IodmFyIGU9XCJcIixpPTA7aTx0Lmxlbmd0aDtpKyspe3ZhciByPXQuY2hhckF0KGkpO2UrPSdcIic9PT1yPydcXFxcXCInOlwiXFxcXFwiPT09cj9cIlxcXFxcXFxcXCI6XCJcXGJcIj09PXI/XCJcXFxcYlwiOlwiXFxmXCI9PT1yP1wiXFxcXGZcIjpcIlxcblwiPT09cj9cIlxcXFxuXCI6XCJcXHJcIj09PXI/XCJcXFxcclwiOlwiXFx0XCI9PT1yP1wiXFxcXHRcIjpyfXRoaXMudWMucHVzaCgnXCInK2UrJ1wiJyl9fSxQYzpmdW5jdGlvbih0KXt0aGlzLnZhKHQpfSxBYzpmdW5jdGlvbigpe3RoaXMuTmM9W10sdGhpcy5SYT1bXSxcInVuZGVmaW5lZFwiIT10eXBlb2YgSlNPTiYmXCJmdW5jdGlvblwiPT10eXBlb2YgSlNPTi5wYXJzZT90aGlzLnhjPUpTT04ucGFyc2UodGhpcy5YYS5EYSgpKTpcInVuZGVmaW5lZFwiIT10eXBlb2YgalF1ZXJ5P3RoaXMueGM9alF1ZXJ5LnBhcnNlSlNPTih0aGlzLlhhLkRhKCkpOnRoaXMueGM9ZXZhbCh0aGlzLlhhLkRhKCkpO3ZhciByPXt9LHZlcnNpb249dGhpcy54Yy5zaGlmdCgpO2lmKHZlcnNpb24hPVRocmlmdC5ZYS5Tcyl0aHJvd1wiV3JvbmcgdGhyaWZ0IHByb3RvY29sIHZlcnNpb246IFwiK3ZlcnNpb247cmV0dXJuIHIuQmM9dGhpcy54Yy5zaGlmdCgpLHIuRmM9dGhpcy54Yy5zaGlmdCgpLHIuX2M9dGhpcy54Yy5zaGlmdCgpLHRoaXMuTmMucHVzaCh0aGlzLnhjLnNoaWZ0KCkpLHJ9LERjOmZ1bmN0aW9uKCl7fSxIYzpmdW5jdGlvbih0KXt2YXIgZT17fTtyZXR1cm4gZS5CYz1cIlwiLHRoaXMuTmNbdGhpcy5OYy5sZW5ndGgtMV1pbnN0YW5jZW9mIEFycmF5JiZ0aGlzLk5jLnB1c2godGhpcy5OY1t0aGlzLk5jLmxlbmd0aC0xXS5zaGlmdCgpKSxlfSxkYTpmdW5jdGlvbigpe3RoaXMuTmNbdGhpcy5OYy5sZW5ndGgtMl1pbnN0YW5jZW9mIEFycmF5JiZ0aGlzLk5jLnBvcCgpfSxzYTpmdW5jdGlvbigpe3ZhciB0PXt9LGU9LTEsaT1UaHJpZnQuYnMuRXM7Zm9yKHZhciByIGluIHRoaXMuTmNbdGhpcy5OYy5sZW5ndGgtMV0paWYobnVsbCE9PXIpe2U9cGFyc2VJbnQociwxMCksdGhpcy5SYS5wdXNoKHRoaXMuTmMubGVuZ3RoKTt2YXIgbj10aGlzLk5jW3RoaXMuTmMubGVuZ3RoLTFdW2VdO2RlbGV0ZSB0aGlzLk5jW3RoaXMuTmMubGVuZ3RoLTFdW2VdLHRoaXMuTmMucHVzaChuKTticmVha31pZihlIT0tMSlmb3IodmFyIG8gaW4gdGhpcy5OY1t0aGlzLk5jLmxlbmd0aC0xXSludWxsIT09VGhyaWZ0LllhLlphW29dJiYoaT1UaHJpZnQuWWEuWmFbb10sdGhpcy5OY1t0aGlzLk5jLmxlbmd0aC0xXT10aGlzLk5jW3RoaXMuTmMubGVuZ3RoLTFdW29dKTtyZXR1cm4gdC5CYz1cIlwiLHQuYWE9aSx0LmNhPWUsdH0sbGE6ZnVuY3Rpb24oKXtmb3IodmFyIHQ9dGhpcy5SYS5wb3AoKTt0aGlzLk5jLmxlbmd0aD50Oyl0aGlzLk5jLnBvcCgpfSxMYzpmdW5jdGlvbigpe3ZhciB0PXRoaXMuTmMucG9wKCksZT10LnNoaWZ0KCk7ZSBpbnN0YW5jZW9mIEFycmF5JiYodGhpcy5OYy5wdXNoKHQpLHQ9ZSxlPXQuc2hpZnQoKSk7dmFyIGk9e307cmV0dXJuIGkuTWM9VGhyaWZ0LllhLlphW2VdLGkuamM9VGhyaWZ0LllhLlphW3Quc2hpZnQoKV0saS5zaXplPXQuc2hpZnQoKSx0aGlzLlJhLnB1c2godGhpcy5OYy5sZW5ndGgpLHRoaXMuTmMucHVzaCh0LnNoaWZ0KCkpLGl9LFVjOmZ1bmN0aW9uKCl7dGhpcy5sYSgpfSxWYzpmdW5jdGlvbigpe3ZhciB0PXRoaXMuTmNbdGhpcy5OYy5sZW5ndGgtMV0sZT17fTtyZXR1cm4gZS5RYz1UaHJpZnQuWWEuWmFbdC5zaGlmdCgpXSxlLnNpemU9dC5zaGlmdCgpLHRoaXMuUmEucHVzaCh0aGlzLk5jLmxlbmd0aCksdGhpcy5OYy5wdXNoKHQpLGV9LHFjOmZ1bmN0aW9uKCl7dGhpcy5sYSgpfSxKYzpmdW5jdGlvbih0LGUpe3JldHVybiB0aGlzLlZjKHQsZSl9LEtjOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucWMoKX0sR2M6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLnVhKCk7cmV0dXJuIG51bGwhPT10JiZcIjFcIj09dC52YWx1ZT90LnZhbHVlPSEwOnQudmFsdWU9ITEsdH0semM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy51YSgpfSxXYzpmdW5jdGlvbigpe3JldHVybiB0aGlzLnVhKCl9LHVhOmZ1bmN0aW9uKHQpe3ZvaWQgMD09PXQmJih0PXRoaXMuTmNbdGhpcy5OYy5sZW5ndGgtMV0pO3ZhciBlPXt9O2lmKHQgaW5zdGFuY2VvZiBBcnJheSkwPT09dC5sZW5ndGg/ZS52YWx1ZT12b2lkIDA6ZS52YWx1ZT10LnNoaWZ0KCk7ZWxzZSBpZih0IGluc3RhbmNlb2YgT2JqZWN0KXtmb3IodmFyIGkgaW4gdClpZihudWxsIT09aSl7dGhpcy5OYy5wdXNoKHRbaV0pLGRlbGV0ZSB0W2ldLGUudmFsdWU9aTticmVha319ZWxzZSBlLnZhbHVlPXQsdGhpcy5OYy5wb3AoKTtyZXR1cm4gZX0sJGM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy51YSgpfSxZYzpmdW5jdGlvbigpe3JldHVybiB0aGlzLnVhKCl9LGhhOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy51YSgpO3JldHVybiB0fSxYYzpmdW5jdGlvbigpe3JldHVybiB0aGlzLmhhKCl9LHBhOmZ1bmN0aW9uKHQpe3ZhciBlLGk7c3dpdGNoKHQpe2Nhc2UgVGhyaWZ0LmJzLkVzOnJldHVybiBudWxsO2Nhc2UgVGhyaWZ0LmJzLkJPT0w6cmV0dXJuIHRoaXMuR2MoKTtjYXNlIFRocmlmdC5icy5CWVRFOnJldHVybiB0aGlzLnpjKCk7Y2FzZSBUaHJpZnQuYnMuQ3M6cmV0dXJuIHRoaXMuV2MoKTtjYXNlIFRocmlmdC5icy5PczpyZXR1cm4gdGhpcy51YSgpO2Nhc2UgVGhyaWZ0LmJzLlBzOnJldHVybiB0aGlzLiRjKCk7Y2FzZSBUaHJpZnQuYnMua3M6cmV0dXJuIHRoaXMuWWMoKTtjYXNlIFRocmlmdC5icy5BczpyZXR1cm4gdGhpcy5oYSgpO2Nhc2UgVGhyaWZ0LmJzLnhzOmZvcih0aGlzLkhjKCk7Oyl7aWYoZT10aGlzLnNhKCksZS5hYT09VGhyaWZ0LmJzLkVzKWJyZWFrO3RoaXMucGEoZS5hYSksdGhpcy5sYSgpfXJldHVybiB0aGlzLmRhKCksbnVsbDtjYXNlIFRocmlmdC5icy5Cczpmb3IoZT10aGlzLkxjKCksaT0wO2k8ZS5zaXplO2krKylpPjAmJnRoaXMuTmMubGVuZ3RoPnRoaXMuUmFbdGhpcy5SYS5sZW5ndGgtMV0rMSYmdGhpcy5OYy5wb3AoKSx0aGlzLnBhKGUuTWMpLHRoaXMucGEoZS5qYyk7cmV0dXJuIHRoaXMuVWMoKSxudWxsO2Nhc2UgVGhyaWZ0LmJzLkZzOmZvcihlPXRoaXMuSmMoKSxpPTA7aTxlLnNpemU7aSsrKXRoaXMucGEoZS5RYyk7cmV0dXJuIHRoaXMuS2MoKSxudWxsO2Nhc2UgVGhyaWZ0LmJzLl9zOmZvcihlPXRoaXMuVmMoKSxpPTA7aTxlLnNpemU7aSsrKXRoaXMucGEoZS5RYyk7cmV0dXJuIHRoaXMucWMoKSxudWxsfX19LFRocmlmdC5aYz1mdW5jdGlvbih0LGUsaSxyKXtUaHJpZnQuWWEuY2FsbCh0aGlzLGUsaSxyKSx0aGlzLnRoPXR9LFRocmlmdC5xcyhUaHJpZnQuWmMsVGhyaWZ0LllhLFwibXVsdGlwbGV4UHJvdG9jb2xcIiksVGhyaWZ0LlpjLnByb3RvdHlwZS5wYz1mdW5jdGlvbih0LGUsaSl7ZT09PVRocmlmdC5Mcy5Nc3x8ZT09PVRocmlmdC5Mcy5Wcz9UaHJpZnQuWWEucHJvdG90eXBlLnBjLmNhbGwodGhpcyx0aGlzLnRoK1wiOlwiK3QsZSxpKTpUaHJpZnQuWWEucHJvdG90eXBlLnBjLmNhbGwodGhpcyx0LGUsaSl9LFRocmlmdC5laD1mdW5jdGlvbigpe3RoaXMuaWg9MH0sVGhyaWZ0LmVoLnByb3RvdHlwZS5yaD1mdW5jdGlvbih0LGUsaSl7ZS5lbyYmKGU9ZS5lbyk7dmFyIHI9dGhpcztlLnByb3RvdHlwZS5uaD1mdW5jdGlvbigpe3JldHVybiByLmloKz0xLHIuaWh9O3ZhciBuPW5ldyBlKG5ldyBUaHJpZnQuWmModCxpKSk7cmV0dXJuIG59LG1vZHVsZS50PVRocmlmdH0sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjt2YXIgaTshZnVuY3Rpb24odCl7ZnVuY3Rpb24gZSh0KXtyZXR1cm4gblt0XX12YXIgaT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHR9KCk7dC5IaXZlU2Vzc2lvbj1pO3ZhciByOyFmdW5jdGlvbih0KXt0W3Qub2g9MF09XCJHRU5FUklDX0VSUk9SXCIsdFt0LnNoPTFdPVwiTk9fVEVDSF9BVkFJTEFCTEVcIix0W3QuYWg9Ml09XCJOT19URUNIX1JFU09MVkVEXCIsdFt0LmhoPTNdPVwiVEVDSF9FUlJPUlwiLHRbdC5waD00XT1cIlRJQ0tFVF9FUlJPUlwifShyPXQudWh8fCh0LnVoPXt9KSk7dmFyIG47IWZ1bmN0aW9uKHQpe3RbdFtcImxoXCJdPTBdPVwiR2VuZXJpYyBVbmRlZmluZWQgRXJyb3JcIix0W3RbXCJkaFwiXT0xXT1cIk5vIFRlY2ggYXZhaWxhYmxlIHRvIHJlc29sdmUgdGhlIHRpY2tldFwiLHRbdFtcImZoXCJdPTJdPVwiTm8gYXZhaWxhYmxlIFRlY2ggY291bGQgcmVzb2x2ZWQgdGhlIHRpY2tldFwiLHRbdFtcImdoXCJdPTNdPVwiU3RvcHBlZCByZXNvbHZpbmcgc2Vzc2lvbiBvbiBsYXN0IHRlY2ggb25FcnJvclwiLHRbdFtcInZoXCJdPTRdPVwiVGhlIHRpY2tldCBjb3VsZCBub3QgYmUgcmVzb2x2ZWRcIn0obnx8KG49e30pKTt2YXIgbz1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHR9KCk7dC5IaXZlU2Vzc2lvbkVycm9yPW87dmFyIHM9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQsZSl7dGhpcy5jb2RlPXQsdGhpcy5tZXNzYWdlPWV9cmV0dXJuIHR9KCk7dC5IaXZlVGVjaEVycm9yPXM7dmFyIGE7IWZ1bmN0aW9uKHQpe3RbdC55aD0wXT1cIk5PVF9SRUFEWVwiLHRbdC5taD0xXT1cIlBMVUdJTl9FUlJPUlwiLHRbdC53aD0yXT1cIlNFU1NJT05fRVJST1JcIix0W3QucGg9M109XCJUSUNLRVRfRVJST1JcIix0W3QuVGg9NF09XCJWRVJTSU9OX0VSUk9SXCIsdFt0LlNoPTVdPVwiVElNRU9VVF9FUlJPUlwifShhPXQuYmh8fCh0LmJoPXt9KSk7dmFyIGM7IWZ1bmN0aW9uKHQpe3RbdC5FaD0wXT1cIk9LXCIsdFt0LkloPTFdPVwiSElWRV9OT1RfQUxMT1dFRFwiLHRbdC5SaD0yXT1cIlRJQ0tFVF9OT1RfUkVTT0xWRURcIix0W3Qua2g9M109XCJUSU1FT1VUX1JFU09MVklOR19USUNLRVRcIn0oYz10LkNofHwodC5DaD17fSkpLHQuZ2V0SGl2ZVNlc3Npb25FcnJvck1lc3NhZ2U9ZTt2YXIgaD1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCl7dGhpcy5PaD10fXJldHVybiB0LnByb3RvdHlwZS5nZXRQbHVnaW5TdGF0dXNDb2RlPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuT2guUGgoKX0sdH0oKTt0LkFoPWh9KGk9ZS5wdHx8KGUucHQ9e30pKSxcInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93JiYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIHdpbmRvdy5wdCYmKHdpbmRvdy5wdD17fSksd2luZG93LnB0LmdldEhpdmVTZXNzaW9uRXJyb3JNZXNzYWdlPWkuZ2V0SGl2ZVNlc3Npb25FcnJvck1lc3NhZ2UpfSxmdW5jdGlvbih0LGUpe1widXNlIHN0cmljdFwiO3ZhciBpPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTtpLnlyPVwiaHR0cHM6XCI9PT1sb2NhdGlvbi5wcm90b2NvbCxpLkVyPSEwLGkuTmg9MWU0LGkueGg9NmU0LGUua2U9aX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPWkoNDEpLG49aSg4KSxvPWkoMjUpO2lmKFwidW5kZWZpbmVkXCI9PXR5cGVvZiBzKXZhciBzPVwiNTkyODM1YTZiNDIwNGRkMTk3YzAwNDg4NjEwMDAzZTBcIjtpZihcInVuZGVmaW5lZFwiPT10eXBlb2YgYSl2YXIgYT1cIjAuOFwiO2lmKFwidW5kZWZpbmVkXCI9PXR5cGVvZiBjKXZhciBjPSEwO3ZhciBoPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe2lmKHRoaXMuc3Q9ITEsdC5HaSl0aHJvdyBuZXcgRXJyb3IoXCJFcnJvcjogSW5zdGFudGlhdGlvbiBmYWlsZWQ6IFVzZSBBdGF0dXNMb2dnZXIuZ2V0SW5zdGFuY2UoKSBpbnN0ZWFkIG9mIG5ldy5cIik7dmFyIGUsaT12b2lkIDAhPW4uSGl2ZUNvbmZpZy5FcnJvck1vbml0b3Iua2V5P24uSGl2ZUNvbmZpZy5FcnJvck1vbml0b3Iua2V5OnMscj0xPT1uLkhpdmVDb25maWcuRXJyb3JNb25pdG9yLmVuYWJsZWRSVU0sYT0xPT1uLkhpdmVDb25maWcuRXJyb3JNb25pdG9yLmVuYWJsZUtleUNvbWJpbmF0aW9uLGg9MT09bi5IaXZlQ29uZmlnLkVycm9yTW9uaXRvci5lbmFibGVkRXJyb3JGaWx0ZXI7aCYmKGU9dGhpcy5CaCgpKSxhdGF0dXMmJih2b2lkIDA9PW4uSGl2ZUNvbmZpZy5FcnJvck1vbml0b3IuZW5hYmxlZCYmY3x8dm9pZCAwIT1uLkhpdmVDb25maWcuRXJyb3JNb25pdG9yLmVuYWJsZWQmJjE9PW4uSGl2ZUNvbmZpZy5FcnJvck1vbml0b3IuZW5hYmxlZCkmJihhdGF0dXMuY29uZmlnKGkse2VuYWJsZVNvdXJjZW1hcDohMCxkaXNhYmxlUlVNOiFyLHZlcnNpb246by52ZXJzaW9uLGJlZm9yZUVycm9yU2VuZDpmdW5jdGlvbih0KXt2YXIgaT0hMTtpZih0JiZ0LmN1c3RvbURhdGEmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiB0LmN1c3RvbURhdGEuZm9yY2VTZW5kJiYoaT10LmN1c3RvbURhdGEuZm9yY2VTZW5kLGRlbGV0ZSB0LmN1c3RvbURhdGEuZm9yY2VTZW5kLDA9PT1PYmplY3Qua2V5cyh0LmN1c3RvbURhdGEpLmxlbmd0aCYmKHQuY3VzdG9tRGF0YT1udWxsKSksIWh8fGkpcmV0dXJuITA7aWYoIWUpcmV0dXJuITE7dHJ5e3ZhciByPSExO2lmKHQuYmFja1RyYWNlcyl7Zm9yKHZhciBuPTAsbz10LmJhY2tUcmFjZXM7bjxvLmxlbmd0aDtuKyspe3ZhciBzPW9bbl0sYT1zLmYuaW5kZXhPZihlKT4tMTtpZihhJiZzLmxuPjUpe3I9ITA7YnJlYWt9fXImJih0Lm5hbWU9dC5uYW1lLnJlcGxhY2UoLyVzIFxcW1swLTldezJ9OlswLTldezJ9OlswLTldezJ9OlswLTldK10gLyxcIlwiKSx0Lm5hbWUuaW5kZXhPZihcIlN0YXR1cyBDb2RlIEVycm9yOlwiKT49MCYmKHQudGFncz1bXCJQbHVnaW4gRXJyb3IgQ29kZVwiLHQubmFtZS5zcGxpdChcIjpcIilbMV0udHJpbSgpXSkpfXJldHVybiByfWNhdGNoKGMpe3JldHVybiExfX19KS5pbnN0YWxsKCksYSYmdGhpcy5GaCgpLHRoaXMuc3Q9ITAsd2luZG93LmNvbnNvbGUmJmNvbnNvbGUubG9nKFwiW0hpdmVDb21tXSBFcnJvciBNb25pdG9yIGluc3RhbGxlZCBbUlVNOlwiK3IrXCIsIEtleUhhbmRsZXI6XCIrYStcIl1cIiksaCYmIWUmJnRoaXMuX2goXCJDb3VsZCBub3QgZXh0cmFjdCBlcnJvciBmaWx0ZXJcIikpfXJldHVybiB0LldpPWZ1bmN0aW9uKCl7cmV0dXJuIHZvaWQgMD09PXRoaXMuR2kmJih0aGlzLkdpPW5ldyB0KSx0aGlzLkdpfSx0LnByb3RvdHlwZS5GaD1mdW5jdGlvbigpe3IuSGguV2koKS5EaChbMTYsMTcsODhdLGZ1bmN0aW9uKCl7dHJ5e3Rocm93IG5ldyBFcnJvcihcIlVwbG9hZCBjb25zb2xlIGxvZ3NcIil9Y2F0Y2godCl7YXRhdHVzLm5vdGlmeSh0KSx3aW5kb3cuY29uc29sZSYmY29uc29sZS5sb2coXCJbSGl2ZUNvbW1dIGNvbnNvbGUgbG9nIHVwbG9hZGVkIGZvciBkZWJ1Z2dpbmdcIil9fSl9LHQucHJvdG90eXBlLkJoPWZ1bmN0aW9uKCl7dHJ5e3Rocm93IG5ldyBFcnJvcihcInRlc3RcIil9Y2F0Y2godCl7dmFyIGU9dC5zdGFjay5tYXRjaCgvKFxcL1xcLy4qXFwuanMpL2kpO2lmKGUmJmUubGVuZ3RoPjApcmV0dXJuIGVbMF19fSx0LnByb3RvdHlwZS5zZXRVc2VyPWZ1bmN0aW9uKHQpe2F0YXR1cyYmdGhpcy5zdCYmYXRhdHVzLnNldFVzZXIodCl9LHQucHJvdG90eXBlLkxoPWZ1bmN0aW9uKHQpe3RoaXMubT10fSx0LnByb3RvdHlwZS5zZXRDdXN0b21EYXRhPWZ1bmN0aW9uKHQpe2F0YXR1cyYmdGhpcy5zdCYmYXRhdHVzLnNldEN1c3RvbURhdGEodCl9LHQucHJvdG90eXBlLl9oPWZ1bmN0aW9uKHQsZSl7aWYodGhpcy5tJiZ0aGlzLm0ud2Fybih0KSxhdGF0dXMmJnRoaXMuc3QpdHJ5e3Rocm93IG5ldyBFcnJvcih0KX1jYXRjaChpKXtlfHwoZT17fSksZS5mb3JjZVNlbmQ9ITAsYXRhdHVzLm5vdGlmeShpLGUpfX0sdC5wcm90b3R5cGUuc2V0VGFncz1mdW5jdGlvbih0KXthdGF0dXMmJnRoaXMuc3QmJmF0YXR1cy5zZXRUYWdzKHQpfSx0LnByb3RvdHlwZS5ub3RpZnk9ZnVuY3Rpb24odCxlKXthdGF0dXMmJnRoaXMuc3QmJihlfHwoZT17fSksZS5mb3JjZVNlbmQ9ITAsYXRhdHVzLm5vdGlmeSh0LGUpKX0sdH0oKTtlLkVycm9yTW9uaXRvcj1ofSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI9aSgyMSksbj1pKDM0KSxvPW4uTWgscz1uLmpoLGE9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7dGhpcy5Tb3VyY2VVUkxQYXJhbXM9e319cmV0dXJuIHQucHJvdG90eXBlLlVoPWZ1bmN0aW9uKHQpe2Zvcih2YXIgZSBpbiB0KWlmKFwiU291cmNlVVJMUGFyYW1zXCI9PT1lKWZvcih2YXIgaSBpbiB0W2VdKXRoaXNbZV1baV09dFtlXVtpXTtlbHNlIHRoaXNbZV09dFtlXTt0aGlzLlZoKCl9LHQucHJvdG90eXBlLlFoPWZ1bmN0aW9uKCl7dmFyIHQ9XCJiNjYxNGMzZTRjZDFkMTRlZWQ2YjM5ZWYyYmY2YjlhM2UzZDZkZmNkMjY2OTlkNzI3MGQ4ODc5MjNiY2JmODNlZmIzZGFkYjcxN2MwYmFmYjFkNDhkY2UzNjFlYjM2OWI3Y2M0NmU1NzQwNWViZmJkZDg2YzMxNzU1MzJmZTU2Y2M3N2Y0NzNkMzQ1YjJjYjZmZWFmYjVhYjBlMjRmMzY0YTNkMjU5ZjI3ZTRhMmZkOTc0NjgyNjViZGRmZDNkZGQzYWM2NDI1MWRiNjUwY2EwMjgwYWYyYjJjNDVlOGIxYzhmMDQwZjJjNDMzYWMwYTE1N2QyYjNmZDkxNTE3MjUzXCIsZT1cIjAxMDAwMVwiLGk9dGhpcy5Db250ZW50SWQrdGhpcy5TaXRlSWQrdGhpcy5DUk9JZCt0aGlzLlNvdXJjZVVSTCxyPW5ldyBvO3IucWgodCxlKTt2YXIgbj1zKHRoaXMuU2lnbmF0dXJlKTtyZXR1cm4gci5KaChpLG4pfSx0LnByb3RvdHlwZS5LaD1mdW5jdGlvbih0KXt0aGlzLnRpY2tldFVybD10O3ZhciBlPXIucGFyc2UodCksaT1lLnBhdGguc3BsaXQoXCIvXCIpLnNsaWNlKDMpO2lmKHRoaXMuU2l0ZUlkPWlbMF0sdGhpcy5DUk9JZD1pWzFdLHRoaXMuQ29udGVudElkPWlbMl0sdGhpcy5HaD1pWzNdLGUudmkpdHJ5e3ZhciBuPWUudmkuc3BsaXQoXCImXCIpO2Zvcih2YXIgbyBpbiBuKXt2YXIgcz1uW29dLnNwbGl0KC89KC4rKS8pO3RoaXMuU291cmNlVVJMUGFyYW1zW3NbMF1dPXNbMV19fWNhdGNoKGEpe310aGlzLnpoPXQuaW5kZXhPZihcImFwaS10ZXN0XCIpPi0xfSx0LnByb3RvdHlwZS5ibj1mdW5jdGlvbigpe3JldHVybiB0aGlzLlNpdGVJZH0sdC5wcm90b3R5cGUuRW49ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5DUk9JZH0sdC5wcm90b3R5cGUuZXM9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5Db250ZW50SWR9LHQucHJvdG90eXBlLldoPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuR2h9LHQucHJvdG90eXBlLiRoPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuU291cmNlVVJMfSx0LnByb3RvdHlwZS5ZaD1mdW5jdGlvbigpe2lmKHRoaXMuWGg9dGhpcy5Tb3VyY2VVUkwsdm9pZCAwIT10aGlzLlNvdXJjZVVSTFBhcmFtcyl7dmFyIHQ9bmV3IEFycmF5O2Zvcih2YXIgZSBpbiB0aGlzLlNvdXJjZVVSTFBhcmFtcyl0LnB1c2goZStcIj1cIit0aGlzLlNvdXJjZVVSTFBhcmFtc1tlXSk7dC5sZW5ndGg+MCYmdGhpcy5YaCYmKHRoaXMuWGgrPSh0aGlzLlhoLmluZGV4T2YoXCI/XCIpPjA/XCImXCI6XCI/XCIpK3Quam9pbihcIiZcIikpfX0sdC5wcm90b3R5cGUuVmg9ZnVuY3Rpb24oKXt2YXIgdD1pKDIyKTt0aGlzLnNlc3Npb25JZD10LlpoKCl9LHQucHJvdG90eXBlLnRwPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuWGh8fHRoaXMuWWgoKSx0aGlzLlhofSx0LnByb3RvdHlwZS5Pbj1mdW5jdGlvbigpe3JldHVyblwiW1wiK3RoaXMuU2l0ZUlkK1wiL1wiK3RoaXMuQ1JPSWQrXCIvXCIrdGhpcy5Db250ZW50SWQrXCJdXCJ9LHQucHJvdG90eXBlLmVwPWZ1bmN0aW9uKCl7cmV0dXJuW3RoaXMuU2l0ZUlkLHRoaXMuQ1JPSWQsdGhpcy5Db250ZW50SWRdfSx0LnByb3RvdHlwZS5pcD1mdW5jdGlvbigpe3JldHVybiB0aGlzLlNvdXJjZVVSTCtcIi1bXCIrdGhpcy5TaXRlSWQrXCIvXCIrdGhpcy5DUk9JZCtcIi9cIit0aGlzLkNvbnRlbnRJZCtcIl1cIn0sdC5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5PbigpfSx0fSgpO2EucnA9XCJeaHR0cHM/Oi8vYXBpKD86LXRlc3QpPy5oaXZlc3RyZWFtaW5nLmNvbS92MS9ldmVudHMvKD86d2lsZGNhcmQvKT9cIixhLm5wPVwiQ1JPSWRcIixhLm9wPVwiU2l0ZUlkXCIsYS5zcD1cIkNvbnRlbnRJZFwiLGUuYXA9YX0sZnVuY3Rpb24odCxlLGkpe3ZhciByLG4sbzsvKiFcbiAqIFVSSS5qcyAtIE11dGF0aW5nIFVSTHNcbiAqXG4gKiBWZXJzaW9uOiAxLjE4LjEwXG4gKlxuICogQXV0aG9yOiBSb2RuZXkgUmVobVxuICogV2ViOiBodHRwOi8vbWVkaWFsaXplLmdpdGh1Yi5pby9VUkkuanMvXG4gKlxuICogTGljZW5zZWQgdW5kZXJcbiAqICAgTUlUIExpY2Vuc2UgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZVxuICpcbiAqL1xuICAhZnVuY3Rpb24ocyxhKXtcInVzZSBzdHJpY3RcIjtcIm9iamVjdFwiPT10eXBlb2YgdCYmdC50P3QudD1hKGkoNiksaSg2KSxpKDYpKToobj1baSg2KSxpKDYpLGkoNildLHI9YSxvPVwiZnVuY3Rpb25cIj09dHlwZW9mIHI/ci5hcHBseShlLG4pOnIsISh2b2lkIDAhPT1vJiYodC50PW8pKSl9KHRoaXMsZnVuY3Rpb24odCxlLGkscil7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gbih0LGUpe3ZhciBpPWFyZ3VtZW50cy5sZW5ndGg+PTEscj1hcmd1bWVudHMubGVuZ3RoPj0yO2lmKCEodGhpcyBpbnN0YW5jZW9mIG4pKXJldHVybiBpP3I/bmV3IG4odCxlKTpuZXcgbih0KTpuZXcgbjtpZih2b2lkIDA9PT10KXtpZihpKXRocm93IG5ldyBUeXBlRXJyb3IoXCJ1bmRlZmluZWQgaXMgbm90IGEgdmFsaWQgYXJndW1lbnQgZm9yIFVSSVwiKTt0PVwidW5kZWZpbmVkXCIhPXR5cGVvZiBsb2NhdGlvbj9sb2NhdGlvbi5ocmVmK1wiXCI6XCJcIn1pZihudWxsPT09dCYmaSl0aHJvdyBuZXcgVHlwZUVycm9yKFwibnVsbCBpcyBub3QgYSB2YWxpZCBhcmd1bWVudCBmb3IgVVJJXCIpO3JldHVybiB0aGlzLmhyZWYodCksdm9pZCAwIT09ZT90aGlzLmNwKGUpOnRoaXN9ZnVuY3Rpb24gbyh0KXtyZXR1cm4gdC5yZXBsYWNlKC8oWy4qKz9ePSE6JHt9KCl8W1xcXVxcL1xcXFxdKS9nLFwiXFxcXCQxXCIpfWZ1bmN0aW9uIHModCl7cmV0dXJuIHZvaWQgMD09PXQ/XCJVbmRlZmluZWRcIjpTdHJpbmcoT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpKS5zbGljZSg4LC0xKX1mdW5jdGlvbiBhKHQpe3JldHVyblwiQXJyYXlcIj09PXModCl9ZnVuY3Rpb24gYyh0LGUpe3ZhciBpLHIsbj17fTtpZihcIlJlZ0V4cFwiPT09cyhlKSluPW51bGw7ZWxzZSBpZihhKGUpKWZvcihpPTAscj1lLmxlbmd0aDtpPHI7aSsrKW5bZVtpXV09ITA7ZWxzZSBuW2VdPSEwO2ZvcihpPTAscj10Lmxlbmd0aDtpPHI7aSsrKXt2YXIgbz1uJiZ2b2lkIDAhPT1uW3RbaV1dfHwhbiYmZS50ZXN0KHRbaV0pO28mJih0LnNwbGljZShpLDEpLHItLSxpLS0pfXJldHVybiB0fWZ1bmN0aW9uIGgodCxlKXt2YXIgaSxyO2lmKGEoZSkpe2ZvcihpPTAscj1lLmxlbmd0aDtpPHI7aSsrKWlmKCFoKHQsZVtpXSkpcmV0dXJuITE7cmV0dXJuITB9dmFyIG49cyhlKTtmb3IoaT0wLHI9dC5sZW5ndGg7aTxyO2krKylpZihcIlJlZ0V4cFwiPT09bil7aWYoXCJzdHJpbmdcIj09dHlwZW9mIHRbaV0mJnRbaV0ubWF0Y2goZSkpcmV0dXJuITB9ZWxzZSBpZih0W2ldPT09ZSlyZXR1cm4hMDtyZXR1cm4hMX1mdW5jdGlvbiBwKHQsZSl7aWYoIWEodCl8fCFhKGUpKXJldHVybiExO2lmKHQubGVuZ3RoIT09ZS5sZW5ndGgpcmV0dXJuITE7dC5zb3J0KCksZS5zb3J0KCk7Zm9yKHZhciBpPTAscj10Lmxlbmd0aDtpPHI7aSsrKWlmKHRbaV0hPT1lW2ldKXJldHVybiExO3JldHVybiEwfWZ1bmN0aW9uIHUodCl7dmFyIGU9L15cXC8rfFxcLyskL2c7cmV0dXJuIHQucmVwbGFjZShlLFwiXCIpfWZ1bmN0aW9uIGwodCl7cmV0dXJuIGVzY2FwZSh0KX1mdW5jdGlvbiBkKHQpe3JldHVybiBlbmNvZGVVUklDb21wb25lbnQodCkucmVwbGFjZSgvWyEnKCkqXS9nLGwpLnJlcGxhY2UoL1xcKi9nLFwiJTJBXCIpfWZ1bmN0aW9uIGYodCl7cmV0dXJuIGZ1bmN0aW9uKGUsaSl7cmV0dXJuIHZvaWQgMD09PWU/dGhpcy5ocFt0XXx8XCJcIjoodGhpcy5ocFt0XT1lfHxudWxsLHRoaXMucHAoIWkpLHRoaXMpfX1mdW5jdGlvbiBnKHQsZSl7cmV0dXJuIGZ1bmN0aW9uKGkscil7cmV0dXJuIHZvaWQgMD09PWk/dGhpcy5ocFt0XXx8XCJcIjoobnVsbCE9PWkmJihpKz1cIlwiLGkuY2hhckF0KDApPT09ZSYmKGk9aS5zdWJzdHJpbmcoMSkpKSx0aGlzLmhwW3RdPWksdGhpcy5wcCghciksdGhpcyl9fXZhciB2PXImJnIudXA7bi52ZXJzaW9uPVwiMS4xOC4xMFwiO3ZhciB5PW4ucHJvdG90eXBlLG09T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtuLmhwPWZ1bmN0aW9uKCl7cmV0dXJue3Byb3RvY29sOm51bGwsdXNlcm5hbWU6bnVsbCxwYXNzd29yZDpudWxsLGhvc3RuYW1lOm51bGwsdXJuOm51bGwscG9ydDpudWxsLHBhdGg6bnVsbCx2aTpudWxsLGxwOm51bGwsZHA6bi5kcCxmcDpuLmZwfX0sbi5kcD0hMSxuLmZwPSEwLG4uZ3A9L15bYS16XVthLXowLTkuKy1dKiQvaSxuLnZwPS9bXmEtejAtOVxcLi1dL2ksbi55cD0vKHhuLS0pL2ksbi5tcD0vXlxcZHsxLDN9XFwuXFxkezEsM31cXC5cXGR7MSwzfVxcLlxcZHsxLDN9JC8sbi53cD0vXlxccyooKChbMC05QS1GYS1mXXsxLDR9Oil7N30oWzAtOUEtRmEtZl17MSw0fXw6KSl8KChbMC05QS1GYS1mXXsxLDR9Oil7Nn0oOlswLTlBLUZhLWZdezEsNH18KCgyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkoXFwuKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKSl7M30pfDopKXwoKFswLTlBLUZhLWZdezEsNH06KXs1fSgoKDpbMC05QS1GYS1mXXsxLDR9KXsxLDJ9KXw6KCgyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkoXFwuKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKSl7M30pfDopKXwoKFswLTlBLUZhLWZdezEsNH06KXs0fSgoKDpbMC05QS1GYS1mXXsxLDR9KXsxLDN9KXwoKDpbMC05QS1GYS1mXXsxLDR9KT86KCgyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkoXFwuKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKSl7M30pKXw6KSl8KChbMC05QS1GYS1mXXsxLDR9Oil7M30oKCg6WzAtOUEtRmEtZl17MSw0fSl7MSw0fSl8KCg6WzAtOUEtRmEtZl17MSw0fSl7MCwyfTooKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKShcXC4oMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKXszfSkpfDopKXwoKFswLTlBLUZhLWZdezEsNH06KXsyfSgoKDpbMC05QS1GYS1mXXsxLDR9KXsxLDV9KXwoKDpbMC05QS1GYS1mXXsxLDR9KXswLDN9OigoMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKFxcLigyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkpezN9KSl8OikpfCgoWzAtOUEtRmEtZl17MSw0fTopezF9KCgoOlswLTlBLUZhLWZdezEsNH0pezEsNn0pfCgoOlswLTlBLUZhLWZdezEsNH0pezAsNH06KCgyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkoXFwuKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKSl7M30pKXw6KSl8KDooKCg6WzAtOUEtRmEtZl17MSw0fSl7MSw3fSl8KCg6WzAtOUEtRmEtZl17MSw0fSl7MCw1fTooKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKShcXC4oMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKXszfSkpfDopKSkoJS4rKT9cXHMqJC8sbi5UcD0vXFxiKCg/OlthLXpdW1xcdy1dKzooPzpcXC97MSwzfXxbYS16MC05JV0pfHd3d1xcZHswLDN9Wy5dfFthLXowLTkuXFwtXStbLl1bYS16XXsyLDR9XFwvKSg/OlteXFxzKCk8Pl0rfFxcKChbXlxccygpPD5dK3woXFwoW15cXHMoKTw+XStcXCkpKSpcXCkpKyg/OlxcKChbXlxccygpPD5dK3woXFwoW15cXHMoKTw+XStcXCkpKSpcXCl8W15cXHNgISgpXFxbXFxde307OidcIi4sPD4/wqvCu+KAnOKAneKAmOKAmV0pKS9naSxuLlNwPXtzdGFydDovXFxiKD86KFthLXpdW2EtejAtOS4rLV0qOlxcL1xcLyl8d3d3XFwuKS9naSxlbmQ6L1tcXHNcXHJcXG5dfCQvLHRyaW06L1tgISgpXFxbXFxde307OidcIi4sPD4/wqvCu+KAnOKAneKAnuKAmOKAmV0rJC8sYnA6LyhcXChbXlxcKV0qXFwpfFxcW1teXFxdXSpcXF18XFx7W159XSpcXH18PFtePl0qPikvZ30sbi5FcD17SXA6XCI4MFwiLFJwOlwiNDQzXCIsa3A6XCIyMVwiLENwOlwiNzBcIixPcDpcIjgwXCIsUHA6XCI0NDNcIn0sbi5BcD0vW15hLXpBLVowLTlcXC4tXS8sbi5OcD17YTpcImhyZWZcIix4cDpcImNpdGVcIixsaW5rOlwiaHJlZlwiLEJwOlwiaHJlZlwiLEZwOlwic3JjXCIsZm9ybTpcImFjdGlvblwiLF9wOlwic3JjXCIsRHA6XCJocmVmXCIsSHA6XCJzcmNcIixMcDpcInNyY1wiLHNvdXJjZTpcInNyY1wiLHRyYWNrOlwic3JjXCIsaW5wdXQ6XCJzcmNcIixNcDpcInNyY1wiLHZpZGVvOlwic3JjXCJ9LG4uanA9ZnVuY3Rpb24odCl7aWYodCYmdC5ub2RlTmFtZSl7dmFyIGU9dC5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO2lmKFwiaW5wdXRcIiE9PWV8fFwiaW1hZ2VcIj09PXQudHlwZSlyZXR1cm4gbi5OcFtlXX19LG4uZW5jb2RlPWQsbi5kZWNvZGU9ZGVjb2RlVVJJQ29tcG9uZW50LG4uVXA9ZnVuY3Rpb24oKXtuLmVuY29kZT1lc2NhcGUsbi5kZWNvZGU9dW5lc2NhcGV9LG4uVnA9ZnVuY3Rpb24oKXtuLmVuY29kZT1kLG4uZGVjb2RlPWRlY29kZVVSSUNvbXBvbmVudH0sbi5RcD17cGF0aG5hbWU6e2VuY29kZTp7cXA6LyUoMjR8MjZ8MkJ8MkN8M0J8M0R8M0F8NDApL2dpLG1hcDp7XCIlMjRcIjpcIiRcIixcIiUyNlwiOlwiJlwiLFwiJTJCXCI6XCIrXCIsXCIlMkNcIjpcIixcIixcIiUzQlwiOlwiO1wiLFwiJTNEXCI6XCI9XCIsXCIlM0FcIjpcIjpcIixcIiU0MFwiOlwiQFwifX0sZGVjb2RlOntxcDovW1xcL1xcPyNdL2csbWFwOntKcDpcIiUyRlwiLEtwOlwiJTNGXCIsR3A6XCIlMjNcIn19fSx6cDp7ZW5jb2RlOntxcDovJSgyMXwyM3wyNHwyNnwyN3wyOHwyOXwyQXwyQnwyQ3wyRnwzQXwzQnwzRHwzRnw0MHw1Qnw1RCkvZ2ksbWFwOntcIiUzQVwiOlwiOlwiLFdwOlwiL1wiLCRwOlwiP1wiLFlwOlwiI1wiLFhwOlwiW1wiLFpwOlwiXVwiLFwiJTQwXCI6XCJAXCIsdHU6XCIhXCIsXCIlMjRcIjpcIiRcIixcIiUyNlwiOlwiJlwiLGV1OlwiJ1wiLGl1OlwiKFwiLHJ1OlwiKVwiLG51OlwiKlwiLFwiJTJCXCI6XCIrXCIsXCIlMkNcIjpcIixcIixcIiUzQlwiOlwiO1wiLFwiJTNEXCI6XCI9XCJ9fX0sb3U6e2VuY29kZTp7cXA6LyUoMjF8MjR8Mjd8Mjh8Mjl8MkF8MkJ8MkN8M0J8M0R8NDApL2dpLG1hcDp7dHU6XCIhXCIsXCIlMjRcIjpcIiRcIixldTpcIidcIixpdTpcIihcIixydTpcIilcIixudTpcIipcIixcIiUyQlwiOlwiK1wiLFwiJTJDXCI6XCIsXCIsXCIlM0JcIjpcIjtcIixcIiUzRFwiOlwiPVwiLFwiJTQwXCI6XCJAXCJ9fSxkZWNvZGU6e3FwOi9bXFwvXFw/IzpdL2csbWFwOntKcDpcIiUyRlwiLEtwOlwiJTNGXCIsR3A6XCIlMjNcIixzdTpcIiUzQVwifX19fSxuLmF1PWZ1bmN0aW9uKHQsZSl7dmFyIGk9bi5lbmNvZGUodCtcIlwiKTtyZXR1cm4gdm9pZCAwPT09ZSYmKGU9bi5mcCksZT9pLnJlcGxhY2UoLyUyMC9nLFwiK1wiKTppfSxuLmN1PWZ1bmN0aW9uKHQsZSl7dCs9XCJcIix2b2lkIDA9PT1lJiYoZT1uLmZwKTt0cnl7cmV0dXJuIG4uZGVjb2RlKGU/dC5yZXBsYWNlKC9cXCsvZyxcIiUyMFwiKTp0KX1jYXRjaChpKXtyZXR1cm4gdH19O3ZhciB3LFQ9e2VuY29kZTpcImVuY29kZVwiLGRlY29kZTpcImRlY29kZVwifSxTPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIGZ1bmN0aW9uKGkpe3RyeXtyZXR1cm4gbltlXShpK1wiXCIpLnJlcGxhY2Uobi5RcFt0XVtlXS5xcCxmdW5jdGlvbihpKXtyZXR1cm4gbi5RcFt0XVtlXS5tYXBbaV19KX1jYXRjaChyKXtyZXR1cm4gaX19fTtmb3IodyBpbiBUKW5bdytcIlBhdGhTZWdtZW50XCJdPVMoXCJwYXRobmFtZVwiLFRbd10pLG5bdytcIlVyblBhdGhTZWdtZW50XCJdPVMoXCJ1cm5wYXRoXCIsVFt3XSk7dmFyIGI9ZnVuY3Rpb24odCxlLGkpe3JldHVybiBmdW5jdGlvbihyKXt2YXIgbztvPWk/ZnVuY3Rpb24odCl7cmV0dXJuIG5bZV0obltpXSh0KSl9Om5bZV07Zm9yKHZhciBzPShyK1wiXCIpLnNwbGl0KHQpLGE9MCxjPXMubGVuZ3RoO2E8YzthKyspc1thXT1vKHNbYV0pO3JldHVybiBzLmpvaW4odCl9fTtuLmh1PWIoXCIvXCIsXCJkZWNvZGVQYXRoU2VnbWVudFwiKSxuLnB1PWIoXCI6XCIsXCJkZWNvZGVVcm5QYXRoU2VnbWVudFwiKSxuLnV1PWIoXCIvXCIsXCJlbmNvZGVQYXRoU2VnbWVudFwiLFwiZGVjb2RlXCIpLG4ubHU9YihcIjpcIixcImVuY29kZVVyblBhdGhTZWdtZW50XCIsXCJkZWNvZGVcIiksbi5kdT1TKFwicmVzZXJ2ZWRcIixcImVuY29kZVwiKSxuLnBhcnNlPWZ1bmN0aW9uKHQsZSl7dmFyIGk7cmV0dXJuIGV8fChlPXt9KSxpPXQuaW5kZXhPZihcIiNcIiksaT4tMSYmKGUubHA9dC5zdWJzdHJpbmcoaSsxKXx8bnVsbCx0PXQuc3Vic3RyaW5nKDAsaSkpLGk9dC5pbmRleE9mKFwiP1wiKSxpPi0xJiYoZS52aT10LnN1YnN0cmluZyhpKzEpfHxudWxsLHQ9dC5zdWJzdHJpbmcoMCxpKSksXCIvL1wiPT09dC5zdWJzdHJpbmcoMCwyKT8oZS5wcm90b2NvbD1udWxsLHQ9dC5zdWJzdHJpbmcoMiksdD1uLmZ1KHQsZSkpOihpPXQuaW5kZXhPZihcIjpcIiksaT4tMSYmKGUucHJvdG9jb2w9dC5zdWJzdHJpbmcoMCxpKXx8bnVsbCxlLnByb3RvY29sJiYhZS5wcm90b2NvbC5tYXRjaChuLmdwKT9lLnByb3RvY29sPXZvaWQgMDpcIi8vXCI9PT10LnN1YnN0cmluZyhpKzEsaSszKT8odD10LnN1YnN0cmluZyhpKzMpLHQ9bi5mdSh0LGUpKToodD10LnN1YnN0cmluZyhpKzEpLGUudXJuPSEwKSkpLGUucGF0aD10LGV9LG4uZ3U9ZnVuY3Rpb24odCxlKXt0PXQucmVwbGFjZSgvXFxcXC9nLFwiL1wiKTt2YXIgaSxyLG49dC5pbmRleE9mKFwiL1wiKTtpZihuPT09LTEmJihuPXQubGVuZ3RoKSxcIltcIj09PXQuY2hhckF0KDApKWk9dC5pbmRleE9mKFwiXVwiKSxlLmhvc3RuYW1lPXQuc3Vic3RyaW5nKDEsaSl8fG51bGwsZS5wb3J0PXQuc3Vic3RyaW5nKGkrMixuKXx8bnVsbCxcIi9cIj09PWUucG9ydCYmKGUucG9ydD1udWxsKTtlbHNle3ZhciBvPXQuaW5kZXhPZihcIjpcIikscz10LmluZGV4T2YoXCIvXCIpLGE9dC5pbmRleE9mKFwiOlwiLG8rMSk7YSE9PS0xJiYocz09PS0xfHxhPHMpPyhlLmhvc3RuYW1lPXQuc3Vic3RyaW5nKDAsbil8fG51bGwsZS5wb3J0PW51bGwpOihyPXQuc3Vic3RyaW5nKDAsbikuc3BsaXQoXCI6XCIpLGUuaG9zdG5hbWU9clswXXx8bnVsbCxlLnBvcnQ9clsxXXx8bnVsbCl9cmV0dXJuIGUuaG9zdG5hbWUmJlwiL1wiIT09dC5zdWJzdHJpbmcobikuY2hhckF0KDApJiYobisrLHQ9XCIvXCIrdCksdC5zdWJzdHJpbmcobil8fFwiL1wifSxuLmZ1PWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHQ9bi52dSh0LGUpLG4uZ3UodCxlKX0sbi52dT1mdW5jdGlvbih0LGUpe3ZhciBpLHI9dC5pbmRleE9mKFwiL1wiKSxvPXQubGFzdEluZGV4T2YoXCJAXCIscj4tMT9yOnQubGVuZ3RoLTEpO3JldHVybiBvPi0xJiYocj09PS0xfHxvPHIpPyhpPXQuc3Vic3RyaW5nKDAsbykuc3BsaXQoXCI6XCIpLGUudXNlcm5hbWU9aVswXT9uLmRlY29kZShpWzBdKTpudWxsLGkuc2hpZnQoKSxlLnBhc3N3b3JkPWlbMF0/bi5kZWNvZGUoaS5qb2luKFwiOlwiKSk6bnVsbCx0PXQuc3Vic3RyaW5nKG8rMSkpOihlLnVzZXJuYW1lPW51bGwsZS5wYXNzd29yZD1udWxsKSx0fSxuLnl1PWZ1bmN0aW9uKHQsZSl7aWYoIXQpcmV0dXJue307aWYodD10LnJlcGxhY2UoLyYrL2csXCImXCIpLnJlcGxhY2UoL15cXD8qJip8JiskL2csXCJcIiksIXQpcmV0dXJue307Zm9yKHZhciBpLHIsbyxzPXt9LGE9dC5zcGxpdChcIiZcIiksYz1hLmxlbmd0aCxoPTA7aDxjO2grKylpPWFbaF0uc3BsaXQoXCI9XCIpLHI9bi5jdShpLnNoaWZ0KCksZSksbz1pLmxlbmd0aD9uLmN1KGkuam9pbihcIj1cIiksZSk6bnVsbCxtLmNhbGwocyxyKT8oXCJzdHJpbmdcIiE9dHlwZW9mIHNbcl0mJm51bGwhPT1zW3JdfHwoc1tyXT1bc1tyXV0pLHNbcl0ucHVzaChvKSk6c1tyXT1vO3JldHVybiBzfSxuLnBwPWZ1bmN0aW9uKHQpe3ZhciBlPVwiXCI7cmV0dXJuIHQucHJvdG9jb2wmJihlKz10LnByb3RvY29sK1wiOlwiKSx0LnVybnx8IWUmJiF0Lmhvc3RuYW1lfHwoZSs9XCIvL1wiKSxlKz1uLm11KHQpfHxcIlwiLFwic3RyaW5nXCI9PXR5cGVvZiB0LnBhdGgmJihcIi9cIiE9PXQucGF0aC5jaGFyQXQoMCkmJlwic3RyaW5nXCI9PXR5cGVvZiB0Lmhvc3RuYW1lJiYoZSs9XCIvXCIpLGUrPXQucGF0aCksXCJzdHJpbmdcIj09dHlwZW9mIHQudmkmJnQudmkmJihlKz1cIj9cIit0LnZpKSxcInN0cmluZ1wiPT10eXBlb2YgdC5scCYmdC5scCYmKGUrPVwiI1wiK3QubHApLGV9LG4ud3U9ZnVuY3Rpb24odCl7dmFyIGU9XCJcIjtyZXR1cm4gdC5ob3N0bmFtZT8oZSs9bi53cC50ZXN0KHQuaG9zdG5hbWUpP1wiW1wiK3QuaG9zdG5hbWUrXCJdXCI6dC5ob3N0bmFtZSx0LnBvcnQmJihlKz1cIjpcIit0LnBvcnQpLGUpOlwiXCJ9LG4ubXU9ZnVuY3Rpb24odCl7cmV0dXJuIG4uVHUodCkrbi53dSh0KX0sbi5UdT1mdW5jdGlvbih0KXt2YXIgZT1cIlwiO3JldHVybiB0LnVzZXJuYW1lJiYoZSs9bi5lbmNvZGUodC51c2VybmFtZSkpLHQucGFzc3dvcmQmJihlKz1cIjpcIituLmVuY29kZSh0LnBhc3N3b3JkKSksZSYmKGUrPVwiQFwiKSxlfSxuLlN1PWZ1bmN0aW9uKHQsZSxpKXt2YXIgcixvLHMsYyxoPVwiXCI7Zm9yKG8gaW4gdClpZihtLmNhbGwodCxvKSYmbylpZihhKHRbb10pKWZvcihyPXt9LHM9MCxjPXRbb10ubGVuZ3RoO3M8YztzKyspdm9pZCAwIT09dFtvXVtzXSYmdm9pZCAwPT09clt0W29dW3NdK1wiXCJdJiYoaCs9XCImXCIrbi5idShvLHRbb11bc10saSksZSE9PSEwJiYoclt0W29dW3NdK1wiXCJdPSEwKSk7ZWxzZSB2b2lkIDAhPT10W29dJiYoaCs9XCImXCIrbi5idShvLHRbb10saSkpO3JldHVybiBoLnN1YnN0cmluZygxKX0sbi5idT1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIG4uYXUodCxpKSsobnVsbCE9PWU/XCI9XCIrbi5hdShlLGkpOlwiXCIpfSxuLkV1PWZ1bmN0aW9uKHQsZSxpKXtpZihcIm9iamVjdFwiPT10eXBlb2YgZSlmb3IodmFyIHIgaW4gZSltLmNhbGwoZSxyKSYmbi5FdSh0LHIsZVtyXSk7ZWxzZXtpZihcInN0cmluZ1wiIT10eXBlb2YgZSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiVVJJLmFkZFF1ZXJ5KCkgYWNjZXB0cyBhbiBvYmplY3QsIHN0cmluZyBhcyB0aGUgbmFtZSBwYXJhbWV0ZXJcIik7aWYodm9pZCAwPT09dFtlXSlyZXR1cm4gdm9pZCh0W2VdPWkpO1wic3RyaW5nXCI9PXR5cGVvZiB0W2VdJiYodFtlXT1bdFtlXV0pLGEoaSl8fChpPVtpXSksdFtlXT0odFtlXXx8W10pLmNvbmNhdChpKX19LG4uSXU9ZnVuY3Rpb24odCxlLGkpe3ZhciByLG8saDtpZihhKGUpKWZvcihyPTAsbz1lLmxlbmd0aDtyPG87cisrKXRbZVtyXV09dm9pZCAwO2Vsc2UgaWYoXCJSZWdFeHBcIj09PXMoZSkpZm9yKGggaW4gdCllLnRlc3QoaCkmJih0W2hdPXZvaWQgMCk7ZWxzZSBpZihcIm9iamVjdFwiPT10eXBlb2YgZSlmb3IoaCBpbiBlKW0uY2FsbChlLGgpJiZuLkl1KHQsaCxlW2hdKTtlbHNle2lmKFwic3RyaW5nXCIhPXR5cGVvZiBlKXRocm93IG5ldyBUeXBlRXJyb3IoXCJVUkkucmVtb3ZlUXVlcnkoKSBhY2NlcHRzIGFuIG9iamVjdCwgc3RyaW5nLCBSZWdFeHAgYXMgdGhlIGZpcnN0IHBhcmFtZXRlclwiKTt2b2lkIDAhPT1pP1wiUmVnRXhwXCI9PT1zKGkpPyFhKHRbZV0pJiZpLnRlc3QodFtlXSk/dFtlXT12b2lkIDA6dFtlXT1jKHRbZV0saSk6dFtlXSE9PVN0cmluZyhpKXx8YShpKSYmMSE9PWkubGVuZ3RoP2EodFtlXSkmJih0W2VdPWModFtlXSxpKSk6dFtlXT12b2lkIDA6dFtlXT12b2lkIDB9fSxuLlJ1PWZ1bmN0aW9uKHQsZSxpLHIpe3N3aXRjaChzKGUpKXtjYXNlXCJTdHJpbmdcIjpicmVhaztjYXNlXCJSZWdFeHBcIjpmb3IodmFyIG8gaW4gdClpZihtLmNhbGwodCxvKSYmZS50ZXN0KG8pJiYodm9pZCAwPT09aXx8bi5SdSh0LG8saSkpKXJldHVybiEwO3JldHVybiExO2Nhc2VcIk9iamVjdFwiOmZvcih2YXIgYyBpbiBlKWlmKG0uY2FsbChlLGMpJiYhbi5SdSh0LGMsZVtjXSkpcmV0dXJuITE7cmV0dXJuITA7ZGVmYXVsdDp0aHJvdyBuZXcgVHlwZUVycm9yKFwiVVJJLmhhc1F1ZXJ5KCkgYWNjZXB0cyBhIHN0cmluZywgcmVndWxhciBleHByZXNzaW9uIG9yIG9iamVjdCBhcyB0aGUgbmFtZSBwYXJhbWV0ZXJcIil9c3dpdGNoKHMoaSkpe2Nhc2VcIlVuZGVmaW5lZFwiOnJldHVybiBlIGluIHQ7Y2FzZVwiQm9vbGVhblwiOnZhciB1PUJvb2xlYW4oYSh0W2VdKT90W2VdLmxlbmd0aDp0W2VdKTtyZXR1cm4gaT09PXU7Y2FzZVwiRnVuY3Rpb25cIjpyZXR1cm4hIWkodFtlXSxlLHQpO2Nhc2VcIkFycmF5XCI6aWYoIWEodFtlXSkpcmV0dXJuITE7dmFyIGw9cj9oOnA7cmV0dXJuIGwodFtlXSxpKTtjYXNlXCJSZWdFeHBcIjpyZXR1cm4gYSh0W2VdKT8hIXImJmgodFtlXSxpKTpCb29sZWFuKHRbZV0mJnRbZV0ubWF0Y2goaSkpO2Nhc2VcIk51bWJlclwiOmk9U3RyaW5nKGkpO2Nhc2VcIlN0cmluZ1wiOnJldHVybiBhKHRbZV0pPyEhciYmaCh0W2VdLGkpOnRbZV09PT1pO2RlZmF1bHQ6dGhyb3cgbmV3IFR5cGVFcnJvcihcIlVSSS5oYXNRdWVyeSgpIGFjY2VwdHMgdW5kZWZpbmVkLCBib29sZWFuLCBzdHJpbmcsIG51bWJlciwgUmVnRXhwLCBGdW5jdGlvbiBhcyB0aGUgdmFsdWUgcGFyYW1ldGVyXCIpfX0sbi5rdT1mdW5jdGlvbigpe2Zvcih2YXIgdD1bXSxlPVtdLGk9MCxyPTA7cjxhcmd1bWVudHMubGVuZ3RoO3IrKyl7dmFyIG89bmV3IG4oYXJndW1lbnRzW3JdKTt0LnB1c2gobyk7Zm9yKHZhciBzPW8uQ3UoKSxhPTA7YTxzLmxlbmd0aDthKyspXCJzdHJpbmdcIj09dHlwZW9mIHNbYV0mJmUucHVzaChzW2FdKSxzW2FdJiZpKyt9aWYoIWUubGVuZ3RofHwhaSlyZXR1cm4gbmV3IG4oXCJcIik7dmFyIGM9bmV3IG4oXCJcIikuQ3UoZSk7cmV0dXJuXCJcIiE9PXRbMF0ucGF0aCgpJiZcIi9cIiE9PXRbMF0ucGF0aCgpLnNsaWNlKDAsMSl8fGMucGF0aChcIi9cIitjLnBhdGgoKSksYy5ub3JtYWxpemUoKX0sbi5PdT1mdW5jdGlvbih0LGUpe3ZhciBpLHI9TWF0aC5taW4odC5sZW5ndGgsZS5sZW5ndGgpO2ZvcihpPTA7aTxyO2krKylpZih0LmNoYXJBdChpKSE9PWUuY2hhckF0KGkpKXtpLS07YnJlYWt9cmV0dXJuIGk8MT90LmNoYXJBdCgwKT09PWUuY2hhckF0KDApJiZcIi9cIj09PXQuY2hhckF0KDApP1wiL1wiOlwiXCI6KFwiL1wiPT09dC5jaGFyQXQoaSkmJlwiL1wiPT09ZS5jaGFyQXQoaSl8fChpPXQuc3Vic3RyaW5nKDAsaSkubGFzdEluZGV4T2YoXCIvXCIpKSx0LnN1YnN0cmluZygwLGkrMSkpfSxuLlB1PWZ1bmN0aW9uKHQsZSxpKXtpfHwoaT17fSk7dmFyIHI9aS5zdGFydHx8bi5TcC5zdGFydCxvPWkuZW5kfHxuLlNwLmVuZCxzPWkudHJpbXx8bi5TcC50cmltLGE9aS5icHx8bi5TcC5icCxjPS9bYS16MC05LV09W1wiJ10/JC9pO2ZvcihyLmxhc3RJbmRleD0wOzspe3ZhciBoPXIuZXhlYyh0KTtpZighaClicmVhazt2YXIgcD1oLmluZGV4O2lmKGkuaWdub3JlSHRtbCl7dmFyIHU9dC5zbGljZShNYXRoLm1heChwLTMsMCkscCk7aWYodSYmYy50ZXN0KHUpKWNvbnRpbnVlfWZvcih2YXIgbD1wK3Quc2xpY2UocCkuc2VhcmNoKG8pLGQ9dC5zbGljZShwLGwpLGY9LTE7Oyl7dmFyIGc9YS5leGVjKGQpO2lmKCFnKWJyZWFrO3ZhciB2PWcuaW5kZXgrZ1swXS5sZW5ndGg7Zj1NYXRoLm1heChmLHYpfWlmKGQ9Zj4tMT9kLnNsaWNlKDAsZikrZC5zbGljZShmKS5yZXBsYWNlKHMsXCJcIik6ZC5yZXBsYWNlKHMsXCJcIiksIShkLmxlbmd0aDw9aFswXS5sZW5ndGh8fGkuaWdub3JlJiZpLmlnbm9yZS50ZXN0KGQpKSl7bD1wK2QubGVuZ3RoO3ZhciB5PWUoZCxwLGwsdCk7dm9pZCAwIT09eT8oeT1TdHJpbmcoeSksdD10LnNsaWNlKDAscCkreSt0LnNsaWNlKGwpLHIubGFzdEluZGV4PXAreS5sZW5ndGgpOnIubGFzdEluZGV4PWx9fXJldHVybiByLmxhc3RJbmRleD0wLHR9LG4uQXU9ZnVuY3Rpb24oZSl7aWYoZS5tYXRjaChuLkFwKSl7aWYoIXQpdGhyb3cgbmV3IFR5cGVFcnJvcignSG9zdG5hbWUgXCInK2UrJ1wiIGNvbnRhaW5zIGNoYXJhY3RlcnMgb3RoZXIgdGhhbiBbQS1aMC05Li1dIGFuZCBQdW55Y29kZS5qcyBpcyBub3QgYXZhaWxhYmxlJyk7aWYodC50b0FTQ0lJKGUpLm1hdGNoKG4uQXApKXRocm93IG5ldyBUeXBlRXJyb3IoJ0hvc3RuYW1lIFwiJytlKydcIiBjb250YWlucyBjaGFyYWN0ZXJzIG90aGVyIHRoYW4gW0EtWjAtOS4tXScpfX0sbi5nZT1mdW5jdGlvbih0KXtpZih0KXt2YXIgZT17dXA6dGhpcy5nZSgpfTtyZXR1cm4gci5OdSYmXCJmdW5jdGlvblwiPT10eXBlb2Ygci5OdS5nZSYmKGUuTnU9ci5OdS5nZSgpKSxyLnh1JiZcImZ1bmN0aW9uXCI9PXR5cGVvZiByLnh1LmdlJiYoZS54dT1yLnh1LmdlKCkpLHIuQnUmJlwiZnVuY3Rpb25cIj09dHlwZW9mIHIuQnUuZ2UmJihlLkJ1PXIuQnUuZ2UoKSksZX1yZXR1cm4gci51cD09PXRoaXMmJihyLnVwPXYpLHRoaXN9LHkucHA9ZnVuY3Rpb24odCl7cmV0dXJuIHQ9PT0hMD90aGlzLkZ1PSEwOih2b2lkIDA9PT10fHx0aGlzLkZ1KSYmKHRoaXMuX3U9bi5wcCh0aGlzLmhwKSx0aGlzLkZ1PSExKSx0aGlzfSx5LmNsb25lPWZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBuKHRoaXMpfSx5LnZhbHVlT2Y9eS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzLnBwKCExKS5fdX0seS5wcm90b2NvbD1mKFwicHJvdG9jb2xcIikseS51c2VybmFtZT1mKFwidXNlcm5hbWVcIikseS5wYXNzd29yZD1mKFwicGFzc3dvcmRcIikseS5ob3N0bmFtZT1mKFwiaG9zdG5hbWVcIikseS5wb3J0PWYoXCJwb3J0XCIpLHkudmk9ZyhcInF1ZXJ5XCIsXCI/XCIpLHkubHA9ZyhcImZyYWdtZW50XCIsXCIjXCIpLHkuc2VhcmNoPWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcy52aSh0LGUpO3JldHVyblwic3RyaW5nXCI9PXR5cGVvZiBpJiZpLmxlbmd0aD9cIj9cIitpOml9LHkuaGFzaD1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMubHAodCxlKTtyZXR1cm5cInN0cmluZ1wiPT10eXBlb2YgaSYmaS5sZW5ndGg/XCIjXCIraTppfSx5LnBhdGhuYW1lPWZ1bmN0aW9uKHQsZSl7aWYodm9pZCAwPT09dHx8dD09PSEwKXt2YXIgaT10aGlzLmhwLnBhdGh8fCh0aGlzLmhwLmhvc3RuYW1lP1wiL1wiOlwiXCIpO3JldHVybiB0Pyh0aGlzLmhwLnVybj9uLnB1Om4uaHUpKGkpOml9cmV0dXJuIHRoaXMuaHAudXJuP3RoaXMuaHAucGF0aD10P24ubHUodCk6XCJcIjp0aGlzLmhwLnBhdGg9dD9uLnV1KHQpOlwiL1wiLHRoaXMucHAoIWUpLHRoaXN9LHkucGF0aD15LnBhdGhuYW1lLHkuaHJlZj1mdW5jdGlvbih0LGUpe3ZhciBpO2lmKHZvaWQgMD09PXQpcmV0dXJuIHRoaXMudG9TdHJpbmcoKTt0aGlzLl91PVwiXCIsdGhpcy5ocD1uLmhwKCk7dmFyIHI9dCBpbnN0YW5jZW9mIG4sbz1cIm9iamVjdFwiPT10eXBlb2YgdCYmKHQuaG9zdG5hbWV8fHQucGF0aHx8dC5wYXRobmFtZSk7aWYodC5ub2RlTmFtZSl7dmFyIHM9bi5qcCh0KTt0PXRbc118fFwiXCIsbz0hMX1pZighciYmbyYmdm9pZCAwIT09dC5wYXRobmFtZSYmKHQ9dC50b1N0cmluZygpKSxcInN0cmluZ1wiPT10eXBlb2YgdHx8dCBpbnN0YW5jZW9mIFN0cmluZyl0aGlzLmhwPW4ucGFyc2UoU3RyaW5nKHQpLHRoaXMuaHApO2Vsc2V7aWYoIXImJiFvKXRocm93IG5ldyBUeXBlRXJyb3IoXCJpbnZhbGlkIGlucHV0XCIpO3ZhciBhPXI/dC5ocDp0O2ZvcihpIGluIGEpbS5jYWxsKHRoaXMuaHAsaSkmJih0aGlzLmhwW2ldPWFbaV0pfXJldHVybiB0aGlzLnBwKCFlKSx0aGlzfSx5LmlzPWZ1bmN0aW9uKHQpe3ZhciBlPSExLHI9ITEsbz0hMSxzPSExLGE9ITEsYz0hMSxoPSExLHA9IXRoaXMuaHAudXJuO3N3aXRjaCh0aGlzLmhwLmhvc3RuYW1lJiYocD0hMSxyPW4ubXAudGVzdCh0aGlzLmhwLmhvc3RuYW1lKSxvPW4ud3AudGVzdCh0aGlzLmhwLmhvc3RuYW1lKSxlPXJ8fG8scz0hZSxhPXMmJmkmJmkuaGFzKHRoaXMuaHAuaG9zdG5hbWUpLGM9cyYmbi52cC50ZXN0KHRoaXMuaHAuaG9zdG5hbWUpLGg9cyYmbi55cC50ZXN0KHRoaXMuaHAuaG9zdG5hbWUpKSx0LnRvTG93ZXJDYXNlKCkpe2Nhc2VcInJlbGF0aXZlXCI6cmV0dXJuIHA7Y2FzZVwiYWJzb2x1dGVcIjpyZXR1cm4hcDtjYXNlXCJkb21haW5cIjpjYXNlXCJuYW1lXCI6cmV0dXJuIHM7Y2FzZVwic2xkXCI6cmV0dXJuIGE7Y2FzZVwiaXBcIjpyZXR1cm4gZTtjYXNlXCJpcDRcIjpjYXNlXCJpcHY0XCI6Y2FzZVwiaW5ldDRcIjpyZXR1cm4gcjtjYXNlXCJpcDZcIjpjYXNlXCJpcHY2XCI6Y2FzZVwiaW5ldDZcIjpyZXR1cm4gbztjYXNlXCJpZG5cIjpyZXR1cm4gYztjYXNlXCJ1cmxcIjpyZXR1cm4hdGhpcy5ocC51cm47Y2FzZVwidXJuXCI6cmV0dXJuISF0aGlzLmhwLnVybjtjYXNlXCJwdW55Y29kZVwiOnJldHVybiBofXJldHVybiBudWxsfTt2YXIgRT15LnByb3RvY29sLEk9eS5wb3J0LFI9eS5ob3N0bmFtZTt5LnByb3RvY29sPWZ1bmN0aW9uKHQsZSl7aWYodm9pZCAwIT09dCYmdCYmKHQ9dC5yZXBsYWNlKC86KFxcL1xcLyk/JC8sXCJcIiksIXQubWF0Y2gobi5ncCkpKXRocm93IG5ldyBUeXBlRXJyb3IoJ1Byb3RvY29sIFwiJyt0K1wiXFxcIiBjb250YWlucyBjaGFyYWN0ZXJzIG90aGVyIHRoYW4gW0EtWjAtOS4rLV0gb3IgZG9lc24ndCBzdGFydCB3aXRoIFtBLVpdXCIpO3JldHVybiBFLmNhbGwodGhpcyx0LGUpfSx5LnNjaGVtZT15LnByb3RvY29sLHkucG9ydD1mdW5jdGlvbih0LGUpe2lmKHRoaXMuaHAudXJuKXJldHVybiB2b2lkIDA9PT10P1wiXCI6dGhpcztpZih2b2lkIDAhPT10JiYoMD09PXQmJih0PW51bGwpLHQmJih0Kz1cIlwiLFwiOlwiPT09dC5jaGFyQXQoMCkmJih0PXQuc3Vic3RyaW5nKDEpKSx0Lm1hdGNoKC9bXjAtOV0vKSkpKXRocm93IG5ldyBUeXBlRXJyb3IoJ1BvcnQgXCInK3QrJ1wiIGNvbnRhaW5zIGNoYXJhY3RlcnMgb3RoZXIgdGhhbiBbMC05XScpO3JldHVybiBJLmNhbGwodGhpcyx0LGUpfSx5Lmhvc3RuYW1lPWZ1bmN0aW9uKHQsZSl7aWYodGhpcy5ocC51cm4pcmV0dXJuIHZvaWQgMD09PXQ/XCJcIjp0aGlzO2lmKHZvaWQgMCE9PXQpe3ZhciBpPXt9LHI9bi5ndSh0LGkpO2lmKFwiL1wiIT09cil0aHJvdyBuZXcgVHlwZUVycm9yKCdIb3N0bmFtZSBcIicrdCsnXCIgY29udGFpbnMgY2hhcmFjdGVycyBvdGhlciB0aGFuIFtBLVowLTkuLV0nKTt0PWkuaG9zdG5hbWV9cmV0dXJuIFIuY2FsbCh0aGlzLHQsZSl9LHkub3JpZ2luPWZ1bmN0aW9uKHQsZSl7aWYodGhpcy5ocC51cm4pcmV0dXJuIHZvaWQgMD09PXQ/XCJcIjp0aGlzO2lmKHZvaWQgMD09PXQpe3ZhciBpPXRoaXMucHJvdG9jb2woKSxyPXRoaXMuRHUoKTtyZXR1cm4gcj8oaT9pK1wiOi8vXCI6XCJcIikrdGhpcy5EdSgpOlwiXCJ9dmFyIG89bih0KTtyZXR1cm4gdGhpcy5wcm90b2NvbChvLnByb3RvY29sKCkpLkR1KG8uRHUoKSkucHAoIWUpLHRoaXN9LHkuaG9zdD1mdW5jdGlvbih0LGUpe2lmKHRoaXMuaHAudXJuKXJldHVybiB2b2lkIDA9PT10P1wiXCI6dGhpcztpZih2b2lkIDA9PT10KXJldHVybiB0aGlzLmhwLmhvc3RuYW1lP24ud3UodGhpcy5ocCk6XCJcIjt2YXIgaT1uLmd1KHQsdGhpcy5ocCk7aWYoXCIvXCIhPT1pKXRocm93IG5ldyBUeXBlRXJyb3IoJ0hvc3RuYW1lIFwiJyt0KydcIiBjb250YWlucyBjaGFyYWN0ZXJzIG90aGVyIHRoYW4gW0EtWjAtOS4tXScpO3JldHVybiB0aGlzLnBwKCFlKSx0aGlzfSx5LkR1PWZ1bmN0aW9uKHQsZSl7aWYodGhpcy5ocC51cm4pcmV0dXJuIHZvaWQgMD09PXQ/XCJcIjp0aGlzO2lmKHZvaWQgMD09PXQpcmV0dXJuIHRoaXMuaHAuaG9zdG5hbWU/bi5tdSh0aGlzLmhwKTpcIlwiO3ZhciBpPW4uZnUodCx0aGlzLmhwKTtpZihcIi9cIiE9PWkpdGhyb3cgbmV3IFR5cGVFcnJvcignSG9zdG5hbWUgXCInK3QrJ1wiIGNvbnRhaW5zIGNoYXJhY3RlcnMgb3RoZXIgdGhhbiBbQS1aMC05Li1dJyk7cmV0dXJuIHRoaXMucHAoIWUpLHRoaXN9LHkuSHU9ZnVuY3Rpb24odCxlKXtpZih0aGlzLmhwLnVybilyZXR1cm4gdm9pZCAwPT09dD9cIlwiOnRoaXM7aWYodm9pZCAwPT09dCl7dmFyIGk9bi5UdSh0aGlzLmhwKTtyZXR1cm4gaT9pLnN1YnN0cmluZygwLGkubGVuZ3RoLTEpOml9cmV0dXJuXCJAXCIhPT10W3QubGVuZ3RoLTFdJiYodCs9XCJAXCIpLG4udnUodCx0aGlzLmhwKSx0aGlzLnBwKCFlKSx0aGlzfSx5Lkx1PWZ1bmN0aW9uKHQsZSl7dmFyIGk7cmV0dXJuIHZvaWQgMD09PXQ/dGhpcy5wYXRoKCkrdGhpcy5zZWFyY2goKSt0aGlzLmhhc2goKTooaT1uLnBhcnNlKHQpLHRoaXMuaHAucGF0aD1pLnBhdGgsdGhpcy5ocC52aT1pLnZpLHRoaXMuaHAubHA9aS5scCx0aGlzLnBwKCFlKSx0aGlzKX0seS5NdT1mdW5jdGlvbih0LGUpe2lmKHRoaXMuaHAudXJuKXJldHVybiB2b2lkIDA9PT10P1wiXCI6dGhpcztpZih2b2lkIDA9PT10KXtpZighdGhpcy5ocC5ob3N0bmFtZXx8dGhpcy5pcyhcIklQXCIpKXJldHVyblwiXCI7dmFyIGk9dGhpcy5ocC5ob3N0bmFtZS5sZW5ndGgtdGhpcy5kb21haW4oKS5sZW5ndGgtMTtyZXR1cm4gdGhpcy5ocC5ob3N0bmFtZS5zdWJzdHJpbmcoMCxpKXx8XCJcIn12YXIgcj10aGlzLmhwLmhvc3RuYW1lLmxlbmd0aC10aGlzLmRvbWFpbigpLmxlbmd0aCxzPXRoaXMuaHAuaG9zdG5hbWUuc3Vic3RyaW5nKDAsciksYT1uZXcgUmVnRXhwKFwiXlwiK28ocykpO3JldHVybiB0JiZcIi5cIiE9PXQuY2hhckF0KHQubGVuZ3RoLTEpJiYodCs9XCIuXCIpLHQmJm4uQXUodCksdGhpcy5ocC5ob3N0bmFtZT10aGlzLmhwLmhvc3RuYW1lLnJlcGxhY2UoYSx0KSx0aGlzLnBwKCFlKSx0aGlzfSx5LmRvbWFpbj1mdW5jdGlvbih0LGUpe2lmKHRoaXMuaHAudXJuKXJldHVybiB2b2lkIDA9PT10P1wiXCI6dGhpcztpZihcImJvb2xlYW5cIj09dHlwZW9mIHQmJihlPXQsdD12b2lkIDApLHZvaWQgMD09PXQpe2lmKCF0aGlzLmhwLmhvc3RuYW1lfHx0aGlzLmlzKFwiSVBcIikpcmV0dXJuXCJcIjt2YXIgaT10aGlzLmhwLmhvc3RuYW1lLm1hdGNoKC9cXC4vZyk7aWYoaSYmaS5sZW5ndGg8MilyZXR1cm4gdGhpcy5ocC5ob3N0bmFtZTt2YXIgcj10aGlzLmhwLmhvc3RuYW1lLmxlbmd0aC10aGlzLmp1KGUpLmxlbmd0aC0xO3JldHVybiByPXRoaXMuaHAuaG9zdG5hbWUubGFzdEluZGV4T2YoXCIuXCIsci0xKSsxLHRoaXMuaHAuaG9zdG5hbWUuc3Vic3RyaW5nKHIpfHxcIlwifWlmKCF0KXRocm93IG5ldyBUeXBlRXJyb3IoXCJjYW5ub3Qgc2V0IGRvbWFpbiBlbXB0eVwiKTtpZihuLkF1KHQpLCF0aGlzLmhwLmhvc3RuYW1lfHx0aGlzLmlzKFwiSVBcIikpdGhpcy5ocC5ob3N0bmFtZT10O2Vsc2V7dmFyIHM9bmV3IFJlZ0V4cChvKHRoaXMuZG9tYWluKCkpK1wiJFwiKTt0aGlzLmhwLmhvc3RuYW1lPXRoaXMuaHAuaG9zdG5hbWUucmVwbGFjZShzLHQpfXJldHVybiB0aGlzLnBwKCFlKSx0aGlzfSx5Lmp1PWZ1bmN0aW9uKHQsZSl7aWYodGhpcy5ocC51cm4pcmV0dXJuIHZvaWQgMD09PXQ/XCJcIjp0aGlzO2lmKFwiYm9vbGVhblwiPT10eXBlb2YgdCYmKGU9dCx0PXZvaWQgMCksdm9pZCAwPT09dCl7aWYoIXRoaXMuaHAuaG9zdG5hbWV8fHRoaXMuaXMoXCJJUFwiKSlyZXR1cm5cIlwiO3ZhciByPXRoaXMuaHAuaG9zdG5hbWUubGFzdEluZGV4T2YoXCIuXCIpLG49dGhpcy5ocC5ob3N0bmFtZS5zdWJzdHJpbmcocisxKTtyZXR1cm4gZSE9PSEwJiZpJiZpLmxpc3Rbbi50b0xvd2VyQ2FzZSgpXT9pLmdldCh0aGlzLmhwLmhvc3RuYW1lKXx8bjpufXZhciBzO2lmKCF0KXRocm93IG5ldyBUeXBlRXJyb3IoXCJjYW5ub3Qgc2V0IFRMRCBlbXB0eVwiKTtpZih0Lm1hdGNoKC9bXmEtekEtWjAtOS1dLykpe2lmKCFpfHwhaS5pcyh0KSl0aHJvdyBuZXcgVHlwZUVycm9yKCdUTEQgXCInK3QrJ1wiIGNvbnRhaW5zIGNoYXJhY3RlcnMgb3RoZXIgdGhhbiBbQS1aMC05XScpO3M9bmV3IFJlZ0V4cChvKHRoaXMuanUoKSkrXCIkXCIpLHRoaXMuaHAuaG9zdG5hbWU9dGhpcy5ocC5ob3N0bmFtZS5yZXBsYWNlKHMsdCl9ZWxzZXtpZighdGhpcy5ocC5ob3N0bmFtZXx8dGhpcy5pcyhcIklQXCIpKXRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihcImNhbm5vdCBzZXQgVExEIG9uIG5vbi1kb21haW4gaG9zdFwiKTtzPW5ldyBSZWdFeHAobyh0aGlzLmp1KCkpK1wiJFwiKSx0aGlzLmhwLmhvc3RuYW1lPXRoaXMuaHAuaG9zdG5hbWUucmVwbGFjZShzLHQpfXJldHVybiB0aGlzLnBwKCFlKSx0aGlzfSx5LlV1PWZ1bmN0aW9uKHQsZSl7aWYodGhpcy5ocC51cm4pcmV0dXJuIHZvaWQgMD09PXQ/XCJcIjp0aGlzO2lmKHZvaWQgMD09PXR8fHQ9PT0hMCl7aWYoIXRoaXMuaHAucGF0aCYmIXRoaXMuaHAuaG9zdG5hbWUpcmV0dXJuXCJcIjtpZihcIi9cIj09PXRoaXMuaHAucGF0aClyZXR1cm5cIi9cIjt2YXIgaT10aGlzLmhwLnBhdGgubGVuZ3RoLXRoaXMuZmlsZW5hbWUoKS5sZW5ndGgtMSxyPXRoaXMuaHAucGF0aC5zdWJzdHJpbmcoMCxpKXx8KHRoaXMuaHAuaG9zdG5hbWU/XCIvXCI6XCJcIik7cmV0dXJuIHQ/bi5odShyKTpyfXZhciBzPXRoaXMuaHAucGF0aC5sZW5ndGgtdGhpcy5maWxlbmFtZSgpLmxlbmd0aCxhPXRoaXMuaHAucGF0aC5zdWJzdHJpbmcoMCxzKSxjPW5ldyBSZWdFeHAoXCJeXCIrbyhhKSk7cmV0dXJuIHRoaXMuaXMoXCJyZWxhdGl2ZVwiKXx8KHR8fCh0PVwiL1wiKSxcIi9cIiE9PXQuY2hhckF0KDApJiYodD1cIi9cIit0KSksdCYmXCIvXCIhPT10LmNoYXJBdCh0Lmxlbmd0aC0xKSYmKHQrPVwiL1wiKSx0PW4udXUodCksdGhpcy5ocC5wYXRoPXRoaXMuaHAucGF0aC5yZXBsYWNlKGMsdCksdGhpcy5wcCghZSksdGhpc30seS5maWxlbmFtZT1mdW5jdGlvbih0LGUpe2lmKHRoaXMuaHAudXJuKXJldHVybiB2b2lkIDA9PT10P1wiXCI6dGhpcztpZihcInN0cmluZ1wiIT10eXBlb2YgdCl7aWYoIXRoaXMuaHAucGF0aHx8XCIvXCI9PT10aGlzLmhwLnBhdGgpcmV0dXJuXCJcIjt2YXIgaT10aGlzLmhwLnBhdGgubGFzdEluZGV4T2YoXCIvXCIpLHI9dGhpcy5ocC5wYXRoLnN1YnN0cmluZyhpKzEpO3JldHVybiB0P24uZGVjb2RlUGF0aFNlZ21lbnQocik6cn12YXIgcz0hMTtcIi9cIj09PXQuY2hhckF0KDApJiYodD10LnN1YnN0cmluZygxKSksdC5tYXRjaCgvXFwuP1xcLy8pJiYocz0hMCk7dmFyIGE9bmV3IFJlZ0V4cChvKHRoaXMuZmlsZW5hbWUoKSkrXCIkXCIpO3JldHVybiB0PW4udXUodCksdGhpcy5ocC5wYXRoPXRoaXMuaHAucGF0aC5yZXBsYWNlKGEsdCkscz90aGlzLlZ1KGUpOnRoaXMucHAoIWUpLHRoaXN9LHkuc3VmZml4PWZ1bmN0aW9uKHQsZSl7aWYodGhpcy5ocC51cm4pcmV0dXJuIHZvaWQgMD09PXQ/XCJcIjp0aGlzO2lmKHZvaWQgMD09PXR8fHQ9PT0hMCl7aWYoIXRoaXMuaHAucGF0aHx8XCIvXCI9PT10aGlzLmhwLnBhdGgpcmV0dXJuXCJcIjt2YXIgaSxyLHM9dGhpcy5maWxlbmFtZSgpLGE9cy5sYXN0SW5kZXhPZihcIi5cIik7cmV0dXJuIGE9PT0tMT9cIlwiOihpPXMuc3Vic3RyaW5nKGErMSkscj0vXlthLXowLTklXSskL2kudGVzdChpKT9pOlwiXCIsdD9uLmRlY29kZVBhdGhTZWdtZW50KHIpOnIpfVwiLlwiPT09dC5jaGFyQXQoMCkmJih0PXQuc3Vic3RyaW5nKDEpKTt2YXIgYyxoPXRoaXMuc3VmZml4KCk7aWYoaCljPXQ/bmV3IFJlZ0V4cChvKGgpK1wiJFwiKTpuZXcgUmVnRXhwKG8oXCIuXCIraCkrXCIkXCIpO2Vsc2V7aWYoIXQpcmV0dXJuIHRoaXM7dGhpcy5ocC5wYXRoKz1cIi5cIituLnV1KHQpfXJldHVybiBjJiYodD1uLnV1KHQpLHRoaXMuaHAucGF0aD10aGlzLmhwLnBhdGgucmVwbGFjZShjLHQpKSx0aGlzLnBwKCFlKSx0aGlzfSx5LkN1PWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj10aGlzLmhwLnVybj9cIjpcIjpcIi9cIixuPXRoaXMucGF0aCgpLG89XCIvXCI9PT1uLnN1YnN0cmluZygwLDEpLHM9bi5zcGxpdChyKTtpZih2b2lkIDAhPT10JiZcIm51bWJlclwiIT10eXBlb2YgdCYmKGk9ZSxlPXQsdD12b2lkIDApLHZvaWQgMCE9PXQmJlwibnVtYmVyXCIhPXR5cGVvZiB0KXRocm93IG5ldyBFcnJvcignQmFkIHNlZ21lbnQgXCInK3QrJ1wiLCBtdXN0IGJlIDAtYmFzZWQgaW50ZWdlcicpO2lmKG8mJnMuc2hpZnQoKSx0PDAmJih0PU1hdGgubWF4KHMubGVuZ3RoK3QsMCkpLHZvaWQgMD09PWUpcmV0dXJuIHZvaWQgMD09PXQ/czpzW3RdO2lmKG51bGw9PT10fHx2b2lkIDA9PT1zW3RdKWlmKGEoZSkpe3M9W107Zm9yKHZhciBjPTAsaD1lLmxlbmd0aDtjPGg7YysrKShlW2NdLmxlbmd0aHx8cy5sZW5ndGgmJnNbcy5sZW5ndGgtMV0ubGVuZ3RoKSYmKHMubGVuZ3RoJiYhc1tzLmxlbmd0aC0xXS5sZW5ndGgmJnMucG9wKCkscy5wdXNoKHUoZVtjXSkpKX1lbHNlKGV8fFwic3RyaW5nXCI9PXR5cGVvZiBlKSYmKGU9dShlKSxcIlwiPT09c1tzLmxlbmd0aC0xXT9zW3MubGVuZ3RoLTFdPWU6cy5wdXNoKGUpKTtlbHNlIGU/c1t0XT11KGUpOnMuc3BsaWNlKHQsMSk7cmV0dXJuIG8mJnMudW5zaGlmdChcIlwiKSx0aGlzLnBhdGgocy5qb2luKHIpLGkpfSx5LlF1PWZ1bmN0aW9uKHQsZSxpKXt2YXIgcixvLHM7aWYoXCJudW1iZXJcIiE9dHlwZW9mIHQmJihpPWUsZT10LHQ9dm9pZCAwKSx2b2lkIDA9PT1lKXtpZihyPXRoaXMuQ3UodCxlLGkpLGEocikpZm9yKG89MCxzPXIubGVuZ3RoO288cztvKyspcltvXT1uLmRlY29kZShyW29dKTtlbHNlIHI9dm9pZCAwIT09cj9uLmRlY29kZShyKTp2b2lkIDA7cmV0dXJuIHJ9aWYoYShlKSlmb3Iobz0wLHM9ZS5sZW5ndGg7bzxzO28rKyllW29dPW4uZW5jb2RlKGVbb10pO2Vsc2UgZT1cInN0cmluZ1wiPT10eXBlb2YgZXx8ZSBpbnN0YW5jZW9mIFN0cmluZz9uLmVuY29kZShlKTplO3JldHVybiB0aGlzLkN1KHQsZSxpKX07dmFyIGs9eS52aTtyZXR1cm4geS52aT1mdW5jdGlvbih0LGUpe2lmKHQ9PT0hMClyZXR1cm4gbi55dSh0aGlzLmhwLnZpLHRoaXMuaHAuZnApO2lmKFwiZnVuY3Rpb25cIj09dHlwZW9mIHQpe3ZhciBpPW4ueXUodGhpcy5ocC52aSx0aGlzLmhwLmZwKSxyPXQuY2FsbCh0aGlzLGkpO3JldHVybiB0aGlzLmhwLnZpPW4uU3Uocnx8aSx0aGlzLmhwLmRwLHRoaXMuaHAuZnApLHRoaXMucHAoIWUpLHRoaXN9cmV0dXJuIHZvaWQgMCE9PXQmJlwic3RyaW5nXCIhPXR5cGVvZiB0Pyh0aGlzLmhwLnZpPW4uU3UodCx0aGlzLmhwLmRwLHRoaXMuaHAuZnApLHRoaXMucHAoIWUpLHRoaXMpOmsuY2FsbCh0aGlzLHQsZSl9LHkucXU9ZnVuY3Rpb24odCxlLGkpe3ZhciByPW4ueXUodGhpcy5ocC52aSx0aGlzLmhwLmZwKTtpZihcInN0cmluZ1wiPT10eXBlb2YgdHx8dCBpbnN0YW5jZW9mIFN0cmluZylyW3RdPXZvaWQgMCE9PWU/ZTpudWxsO2Vsc2V7aWYoXCJvYmplY3RcIiE9dHlwZW9mIHQpdGhyb3cgbmV3IFR5cGVFcnJvcihcIlVSSS5hZGRRdWVyeSgpIGFjY2VwdHMgYW4gb2JqZWN0LCBzdHJpbmcgYXMgdGhlIG5hbWUgcGFyYW1ldGVyXCIpO2Zvcih2YXIgbyBpbiB0KW0uY2FsbCh0LG8pJiYocltvXT10W29dKX1yZXR1cm4gdGhpcy5ocC52aT1uLlN1KHIsdGhpcy5ocC5kcCx0aGlzLmhwLmZwKSxcInN0cmluZ1wiIT10eXBlb2YgdCYmKGk9ZSksdGhpcy5wcCghaSksdGhpc30seS5FdT1mdW5jdGlvbih0LGUsaSl7dmFyIHI9bi55dSh0aGlzLmhwLnZpLHRoaXMuaHAuZnApO3JldHVybiBuLkV1KHIsdCx2b2lkIDA9PT1lP251bGw6ZSksdGhpcy5ocC52aT1uLlN1KHIsdGhpcy5ocC5kcCx0aGlzLmhwLmZwKSxcInN0cmluZ1wiIT10eXBlb2YgdCYmKGk9ZSksdGhpcy5wcCghaSksdGhpc30seS5JdT1mdW5jdGlvbih0LGUsaSl7dmFyIHI9bi55dSh0aGlzLmhwLnZpLHRoaXMuaHAuZnApO3JldHVybiBuLkl1KHIsdCxlKSx0aGlzLmhwLnZpPW4uU3Uocix0aGlzLmhwLmRwLHRoaXMuaHAuZnApLFwic3RyaW5nXCIhPXR5cGVvZiB0JiYoaT1lKSx0aGlzLnBwKCFpKSx0aGlzfSx5LlJ1PWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj1uLnl1KHRoaXMuaHAudmksdGhpcy5ocC5mcCk7cmV0dXJuIG4uUnUocix0LGUsaSl9LHkuSnU9eS5xdSx5Lkt1PXkuRXUseS5HdT15Lkl1LHkuenU9eS5SdSx5Lm5vcm1hbGl6ZT1mdW5jdGlvbigpe3JldHVybiB0aGlzLmhwLnVybj90aGlzLll1KCExKS5WdSghMSkuJHUoITEpLld1KCExKS5wcCgpOnRoaXMuWXUoITEpLlp1KCExKS5YdSghMSkuVnUoITEpLiR1KCExKS5XdSghMSkucHAoKX0seS5ZdT1mdW5jdGlvbih0KXtyZXR1cm5cInN0cmluZ1wiPT10eXBlb2YgdGhpcy5ocC5wcm90b2NvbCYmKHRoaXMuaHAucHJvdG9jb2w9dGhpcy5ocC5wcm90b2NvbC50b0xvd2VyQ2FzZSgpLHRoaXMucHAoIXQpKSx0aGlzfSx5Llp1PWZ1bmN0aW9uKGkpe3JldHVybiB0aGlzLmhwLmhvc3RuYW1lJiYodGhpcy5pcyhcIklETlwiKSYmdD90aGlzLmhwLmhvc3RuYW1lPXQudG9BU0NJSSh0aGlzLmhwLmhvc3RuYW1lKTp0aGlzLmlzKFwiSVB2NlwiKSYmZSYmKHRoaXMuaHAuaG9zdG5hbWU9ZS5iZXN0KHRoaXMuaHAuaG9zdG5hbWUpKSx0aGlzLmhwLmhvc3RuYW1lPXRoaXMuaHAuaG9zdG5hbWUudG9Mb3dlckNhc2UoKSx0aGlzLnBwKCFpKSksdGhpc30seS5YdT1mdW5jdGlvbih0KXtyZXR1cm5cInN0cmluZ1wiPT10eXBlb2YgdGhpcy5ocC5wcm90b2NvbCYmdGhpcy5ocC5wb3J0PT09bi5FcFt0aGlzLmhwLnByb3RvY29sXSYmKHRoaXMuaHAucG9ydD1udWxsLHRoaXMucHAoIXQpKSx0aGlzfSx5LlZ1PWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuaHAucGF0aDtpZighZSlyZXR1cm4gdGhpcztpZih0aGlzLmhwLnVybilyZXR1cm4gdGhpcy5ocC5wYXRoPW4ubHUodGhpcy5ocC5wYXRoKSx0aGlzLnBwKCF0KSx0aGlzO2lmKFwiL1wiPT09dGhpcy5ocC5wYXRoKXJldHVybiB0aGlzO2U9bi51dShlKTt2YXIgaSxyLG8scz1cIlwiO2ZvcihcIi9cIiE9PWUuY2hhckF0KDApJiYoaT0hMCxlPVwiL1wiK2UpLFwiLy4uXCIhPT1lLnNsaWNlKC0zKSYmXCIvLlwiIT09ZS5zbGljZSgtMil8fChlKz1cIi9cIiksZT1lLnJlcGxhY2UoLyhcXC8oXFwuXFwvKSspfChcXC9cXC4kKS9nLFwiL1wiKS5yZXBsYWNlKC9cXC97Mix9L2csXCIvXCIpLGkmJihzPWUuc3Vic3RyaW5nKDEpLm1hdGNoKC9eKFxcLlxcLlxcLykrLyl8fFwiXCIscyYmKHM9c1swXSkpOzspe2lmKHI9ZS5zZWFyY2goL1xcL1xcLlxcLihcXC98JCkvKSxyPT09LTEpYnJlYWs7MCE9PXI/KG89ZS5zdWJzdHJpbmcoMCxyKS5sYXN0SW5kZXhPZihcIi9cIiksbz09PS0xJiYobz1yKSxlPWUuc3Vic3RyaW5nKDAsbykrZS5zdWJzdHJpbmcociszKSk6ZT1lLnN1YnN0cmluZygzKX1yZXR1cm4gaSYmdGhpcy5pcyhcInJlbGF0aXZlXCIpJiYoZT1zK2Uuc3Vic3RyaW5nKDEpKSx0aGlzLmhwLnBhdGg9ZSx0aGlzLnBwKCF0KSx0aGlzfSx5LnRsPXkuVnUseS4kdT1mdW5jdGlvbih0KXtyZXR1cm5cInN0cmluZ1wiPT10eXBlb2YgdGhpcy5ocC52aSYmKHRoaXMuaHAudmkubGVuZ3RoP3RoaXMudmkobi55dSh0aGlzLmhwLnZpLHRoaXMuaHAuZnApKTp0aGlzLmhwLnZpPW51bGwsdGhpcy5wcCghdCkpLHRoaXN9LHkuV3U9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuaHAubHB8fCh0aGlzLmhwLmxwPW51bGwsdGhpcy5wcCghdCkpLHRoaXN9LHkuZWw9eS4kdSx5LmlsPXkuV3UseS5VcD1mdW5jdGlvbigpe3ZhciB0PW4uZW5jb2RlLGU9bi5kZWNvZGU7bi5lbmNvZGU9ZXNjYXBlLG4uZGVjb2RlPWRlY29kZVVSSUNvbXBvbmVudDt0cnl7dGhpcy5ub3JtYWxpemUoKX1maW5hbGx5e24uZW5jb2RlPXQsbi5kZWNvZGU9ZX1yZXR1cm4gdGhpc30seS5WcD1mdW5jdGlvbigpe3ZhciB0PW4uZW5jb2RlLGU9bi5kZWNvZGU7bi5lbmNvZGU9ZCxuLmRlY29kZT11bmVzY2FwZTt0cnl7dGhpcy5ub3JtYWxpemUoKX1maW5hbGx5e24uZW5jb2RlPXQsbi5kZWNvZGU9ZX1yZXR1cm4gdGhpc30seS5ybD1mdW5jdGlvbigpe3ZhciBlPXRoaXMuY2xvbmUoKTtlLnVzZXJuYW1lKFwiXCIpLnBhc3N3b3JkKFwiXCIpLm5vcm1hbGl6ZSgpO3ZhciBpPVwiXCI7aWYoZS5ocC5wcm90b2NvbCYmKGkrPWUuaHAucHJvdG9jb2wrXCI6Ly9cIiksZS5ocC5ob3N0bmFtZSYmKGUuaXMoXCJwdW55Y29kZVwiKSYmdD8oaSs9dC50b1VuaWNvZGUoZS5ocC5ob3N0bmFtZSksZS5ocC5wb3J0JiYoaSs9XCI6XCIrZS5ocC5wb3J0KSk6aSs9ZS5ob3N0KCkpLGUuaHAuaG9zdG5hbWUmJmUuaHAucGF0aCYmXCIvXCIhPT1lLmhwLnBhdGguY2hhckF0KDApJiYoaSs9XCIvXCIpLGkrPWUucGF0aCghMCksZS5ocC52aSl7Zm9yKHZhciByPVwiXCIsbz0wLHM9ZS5ocC52aS5zcGxpdChcIiZcIiksYT1zLmxlbmd0aDtvPGE7bysrKXt2YXIgYz0oc1tvXXx8XCJcIikuc3BsaXQoXCI9XCIpO3IrPVwiJlwiK24uY3UoY1swXSx0aGlzLmhwLmZwKS5yZXBsYWNlKC8mL2csXCIlMjZcIiksdm9pZCAwIT09Y1sxXSYmKHIrPVwiPVwiK24uY3UoY1sxXSx0aGlzLmhwLmZwKS5yZXBsYWNlKC8mL2csXCIlMjZcIikpfWkrPVwiP1wiK3Iuc3Vic3RyaW5nKDEpfXJldHVybiBpKz1uLmN1KGUuaGFzaCgpLCEwKX0seS5jcD1mdW5jdGlvbih0KXt2YXIgZSxpLHIsbz10aGlzLmNsb25lKCkscz1bXCJwcm90b2NvbFwiLFwidXNlcm5hbWVcIixcInBhc3N3b3JkXCIsXCJob3N0bmFtZVwiLFwicG9ydFwiXTtpZih0aGlzLmhwLnVybil0aHJvdyBuZXcgRXJyb3IoXCJVUk5zIGRvIG5vdCBoYXZlIGFueSBnZW5lcmFsbHkgZGVmaW5lZCBoaWVyYXJjaGljYWwgY29tcG9uZW50c1wiKTtpZih0IGluc3RhbmNlb2Ygbnx8KHQ9bmV3IG4odCkpLG8uaHAucHJvdG9jb2wpcmV0dXJuIG87aWYoby5ocC5wcm90b2NvbD10LmhwLnByb3RvY29sLHRoaXMuaHAuaG9zdG5hbWUpcmV0dXJuIG87Zm9yKGk9MDtyPXNbaV07aSsrKW8uaHBbcl09dC5ocFtyXTtyZXR1cm4gby5ocC5wYXRoPyhcIi4uXCI9PT1vLmhwLnBhdGguc3Vic3RyaW5nKC0yKSYmKG8uaHAucGF0aCs9XCIvXCIpLFwiL1wiIT09by5wYXRoKCkuY2hhckF0KDApJiYoZT10LlV1KCksZT1lP2U6MD09PXQucGF0aCgpLmluZGV4T2YoXCIvXCIpP1wiL1wiOlwiXCIsby5ocC5wYXRoPShlP2UrXCIvXCI6XCJcIikrby5ocC5wYXRoLG8uVnUoKSkpOihvLmhwLnBhdGg9dC5ocC5wYXRoLG8uaHAudml8fChvLmhwLnZpPXQuaHAudmkpKSxvLnBwKCksb30seS5ubD1mdW5jdGlvbih0KXt2YXIgZSxpLHIsbyxzLGE9dGhpcy5jbG9uZSgpLm5vcm1hbGl6ZSgpO2lmKGEuaHAudXJuKXRocm93IG5ldyBFcnJvcihcIlVSTnMgZG8gbm90IGhhdmUgYW55IGdlbmVyYWxseSBkZWZpbmVkIGhpZXJhcmNoaWNhbCBjb21wb25lbnRzXCIpO2lmKHQ9bmV3IG4odCkubm9ybWFsaXplKCksZT1hLmhwLGk9dC5ocCxvPWEucGF0aCgpLHM9dC5wYXRoKCksXCIvXCIhPT1vLmNoYXJBdCgwKSl0aHJvdyBuZXcgRXJyb3IoXCJVUkkgaXMgYWxyZWFkeSByZWxhdGl2ZVwiKTtpZihcIi9cIiE9PXMuY2hhckF0KDApKXRocm93IG5ldyBFcnJvcihcIkNhbm5vdCBjYWxjdWxhdGUgYSBVUkkgcmVsYXRpdmUgdG8gYW5vdGhlciByZWxhdGl2ZSBVUklcIik7aWYoZS5wcm90b2NvbD09PWkucHJvdG9jb2wmJihlLnByb3RvY29sPW51bGwpLGUudXNlcm5hbWUhPT1pLnVzZXJuYW1lfHxlLnBhc3N3b3JkIT09aS5wYXNzd29yZClyZXR1cm4gYS5wcCgpO2lmKG51bGwhPT1lLnByb3RvY29sfHxudWxsIT09ZS51c2VybmFtZXx8bnVsbCE9PWUucGFzc3dvcmQpcmV0dXJuIGEucHAoKTtpZihlLmhvc3RuYW1lIT09aS5ob3N0bmFtZXx8ZS5wb3J0IT09aS5wb3J0KXJldHVybiBhLnBwKCk7aWYoZS5ob3N0bmFtZT1udWxsLGUucG9ydD1udWxsLG89PT1zKXJldHVybiBlLnBhdGg9XCJcIixhLnBwKCk7aWYocj1uLk91KG8scyksIXIpcmV0dXJuIGEucHAoKTt2YXIgYz1pLnBhdGguc3Vic3RyaW5nKHIubGVuZ3RoKS5yZXBsYWNlKC9bXlxcL10qJC8sXCJcIikucmVwbGFjZSgvLio/XFwvL2csXCIuLi9cIik7cmV0dXJuIGUucGF0aD1jK2UucGF0aC5zdWJzdHJpbmcoci5sZW5ndGgpfHxcIi4vXCIsYS5wcCgpfSx5Lm9sPWZ1bmN0aW9uKHQpe3ZhciBlLGkscixvPXRoaXMuY2xvbmUoKSxzPW5ldyBuKHQpLGM9e30saD17fSx1PXt9O2lmKG8ubm9ybWFsaXplKCkscy5ub3JtYWxpemUoKSxvLnRvU3RyaW5nKCk9PT1zLnRvU3RyaW5nKCkpcmV0dXJuITA7aWYoZT1vLnZpKCksaT1zLnZpKCksby52aShcIlwiKSxzLnZpKFwiXCIpLG8udG9TdHJpbmcoKSE9PXMudG9TdHJpbmcoKSlyZXR1cm4hMTtpZihlLmxlbmd0aCE9PWkubGVuZ3RoKXJldHVybiExO2M9bi55dShlLHRoaXMuaHAuZnApLGg9bi55dShpLHRoaXMuaHAuZnApO2ZvcihyIGluIGMpaWYobS5jYWxsKGMscikpe2lmKGEoY1tyXSkpe2lmKCFwKGNbcl0saFtyXSkpcmV0dXJuITF9ZWxzZSBpZihjW3JdIT09aFtyXSlyZXR1cm4hMTt1W3JdPSEwfWZvcihyIGluIGgpaWYobS5jYWxsKGgscikmJiF1W3JdKXJldHVybiExO3JldHVybiEwfSx5LmRwPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLmhwLmRwPSEhdCx0aGlzfSx5LmZwPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLmhwLmZwPSEhdCx0aGlzfSxufSl9LGZ1bmN0aW9uKHQsZSxpKXsvKiEgdXVpZC5qc1xuICogQ29weXJpZ2h0IChjKSAyMDEwLTIwMTIgUm9iZXJ0IEtpZWZmZXJcbiAqIE1JVCBMaWNlbnNlIC0gaHR0cDovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL21pdC1saWNlbnNlLnBocFxuICovXG4gICFmdW5jdGlvbihlKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiByKCl7dmFyIHQ9ZS5jcnlwdG98fGUubXNDcnlwdG87aWYoIWgmJnQmJnQuZ2V0UmFuZG9tVmFsdWVzKXRyeXt2YXIgaT1uZXcgVWludDhBcnJheSgxNik7bD1oPWZ1bmN0aW9uKCl7cmV0dXJuIHQuZ2V0UmFuZG9tVmFsdWVzKGkpLGl9LGgoKX1jYXRjaChyKXt9aWYoIWgpe3ZhciBuPW5ldyBBcnJheSgxNik7cD1oPWZ1bmN0aW9uKCl7Zm9yKHZhciB0LGU9MDtlPDE2O2UrKykwPT09KDMmZSkmJih0PTQyOTQ5NjcyOTYqTWF0aC5yYW5kb20oKSksbltlXT10Pj4+KCgzJmUpPDwzKSYyNTU7cmV0dXJuIG59LFwidW5kZWZpbmVkXCIhPXR5cGVvZiBjb25zb2xlJiZjb25zb2xlLndhcm4mJmNvbnNvbGUud2FybihcIltTRUNVUklUWV0gbm9kZS11dWlkOiBjcnlwdG8gbm90IHVzYWJsZSwgZmFsbGluZyBiYWNrIHRvIGluc2VjdXJlIE1hdGgucmFuZG9tKClcIil9fWZ1bmN0aW9uIG4oKXt0cnl7dmFyIHQ9aSgzMykucmFuZG9tQnl0ZXM7dT1oPXQmJmZ1bmN0aW9uKCl7cmV0dXJuIHQoMTYpfSxoKCl9Y2F0Y2goZSl7fX1mdW5jdGlvbiBvKHQsZSxpKXt2YXIgcj1lJiZpfHwwLG49MDtmb3IoZT1lfHxbXSx0LnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvWzAtOWEtZl17Mn0vZyxmdW5jdGlvbih0KXtuPDE2JiYoZVtyK24rK109dlt0XSl9KTtuPDE2OyllW3IrbisrXT0wO3JldHVybiBlfWZ1bmN0aW9uIHModCxlKXt2YXIgaT1lfHwwLHI9ZztyZXR1cm4gclt0W2krK11dK3JbdFtpKytdXStyW3RbaSsrXV0rclt0W2krK11dK1wiLVwiK3JbdFtpKytdXStyW3RbaSsrXV0rXCItXCIrclt0W2krK11dK3JbdFtpKytdXStcIi1cIityW3RbaSsrXV0rclt0W2krK11dK1wiLVwiK3JbdFtpKytdXStyW3RbaSsrXV0rclt0W2krK11dK3JbdFtpKytdXStyW3RbaSsrXV0rclt0W2krK11dfWZ1bmN0aW9uIGEodCxlLGkpe3ZhciByPWUmJml8fDAsbj1lfHxbXTt0PXR8fHt9O3ZhciBvPW51bGwhPXQuY2xvY2tzZXE/dC5jbG9ja3NlcTpULGE9bnVsbCE9dC5tc2Vjcz90Lm1zZWNzOihuZXcgRGF0ZSkuZ2V0VGltZSgpLGM9bnVsbCE9dC5uc2Vjcz90Lm5zZWNzOmIrMSxoPWEtUysoYy1iKS8xZTQ7aWYoaDwwJiZudWxsPT10LmNsb2Nrc2VxJiYobz1vKzEmMTYzODMpLChoPDB8fGE+UykmJm51bGw9PXQubnNlY3MmJihjPTApLGM+PTFlNCl0aHJvdyBuZXcgRXJyb3IoXCJ1dWlkLnYxKCk6IENhbid0IGNyZWF0ZSBtb3JlIHRoYW4gMTBNIHV1aWRzL3NlY1wiKTtTPWEsYj1jLFQ9byxhKz0xMjIxOTI5MjhlNTt2YXIgcD0oMWU0KigyNjg0MzU0NTUmYSkrYyklNDI5NDk2NzI5NjtuW3IrK109cD4+PjI0JjI1NSxuW3IrK109cD4+PjE2JjI1NSxuW3IrK109cD4+PjgmMjU1LG5bcisrXT0yNTUmcDt2YXIgdT1hLzQyOTQ5NjcyOTYqMWU0JjI2ODQzNTQ1NTtuW3IrK109dT4+PjgmMjU1LG5bcisrXT0yNTUmdSxuW3IrK109dT4+PjI0JjE1fDE2LG5bcisrXT11Pj4+MTYmMjU1LG5bcisrXT1vPj4+OHwxMjgsbltyKytdPTI1NSZvO2Zvcih2YXIgbD10Lm5vZGV8fHcsZD0wO2Q8NjtkKyspbltyK2RdPWxbZF07cmV0dXJuIGU/ZTpzKG4pfWZ1bmN0aW9uIGModCxlLGkpe3ZhciByPWUmJml8fDA7XCJzdHJpbmdcIj09dHlwZW9mIHQmJihlPVwiYmluYXJ5XCI9PT10P25ldyBmKDE2KTpudWxsLHQ9bnVsbCksdD10fHx7fTt2YXIgbj10LnJhbmRvbXx8KHQucm5nfHxoKSgpO2lmKG5bNl09MTUmbls2XXw2NCxuWzhdPTYzJm5bOF18MTI4LGUpZm9yKHZhciBvPTA7bzwxNjtvKyspZVtyK29dPW5bb107cmV0dXJuIGV8fHMobil9dmFyIGgscCx1LGwsZDtlP3IoKTpuKCk7Zm9yKHZhciBmPVwiZnVuY3Rpb25cIj09dHlwZW9mIEJ1ZmZlcj9CdWZmZXI6QXJyYXksZz1bXSx2PXt9LHk9MDt5PDI1Njt5KyspZ1t5XT0oeSsyNTYpLnRvU3RyaW5nKDE2KS5zdWJzdHIoMSksdltnW3ldXT15O3ZhciBtPWgoKSx3PVsxfG1bMF0sbVsxXSxtWzJdLG1bM10sbVs0XSxtWzVdXSxUPTE2MzgzJihtWzZdPDw4fG1bN10pLFM9MCxiPTAsRT1jO0Uuc2w9YSxFLlpoPWMsRS5wYXJzZT1vLEUuYWw9cyxFLmNsPWYsRS5obD1oLEUucGw9cCxFLnVsPXUsRS5sbD1sLFwidW5kZWZpbmVkXCIhPXR5cGVvZiB0JiZ0LnQ/dC50PUU6KGQ9ZS5kbCxFLmdlPWZ1bmN0aW9uKCl7cmV0dXJuIGUuZGw9ZCxFfSxlLmRsPUUpfShcInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93P3dpbmRvdzpudWxsKX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByLG49dGhpcyYmdGhpcy5fX2V4dGVuZHN8fGZ1bmN0aW9uKHQsZSl7ZnVuY3Rpb24gaSgpe3RoaXMuY29uc3RydWN0b3I9dH1mb3IodmFyIHIgaW4gZSllLmhhc093blByb3BlcnR5KHIpJiYodFtyXT1lW3JdKTt0LnByb3RvdHlwZT1udWxsPT09ZT9PYmplY3QuY3JlYXRlKGUpOihpLnByb3RvdHlwZT1lLnByb3RvdHlwZSxuZXcgaSl9LG89aSgxMSk7IWZ1bmN0aW9uKHQpe3ZhciBlPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTtlLkRhc2hGaWx0ZXJCaXRyYXRlcz1udWxsLGUuRGFzaFJlbW92ZUJpdHJhdGVTaXplPSExLHQuRGFzaD1lO3ZhciBpPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTtpLmZsPSEwLHQuU3RhdHM9aTt2YXIgcj1mdW5jdGlvbih0KXtmdW5jdGlvbiBlKCl7cmV0dXJuIG51bGwhPT10JiZ0LmFwcGx5KHRoaXMsYXJndW1lbnRzKXx8dGhpc31yZXR1cm4gbihlLHQpLGV9KG8uSGl2ZUNvbmZpZy5EZWJ1Z0xvZ3MpO3IuZ2w9MCx0LkRlYnVnTG9ncz1yO3ZhciBzPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTtzLnVzaXo9bnVsbCx0LlVEUEJyb2FkY2FzdD1zfShyPWUuSGl2ZUNvbmZpZ3x8KGUuSGl2ZUNvbmZpZz17fSkpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3cmJihcInVuZGVmaW5lZFwiPT10eXBlb2Ygd2luZG93LkhpdmVDb25maWcmJih3aW5kb3cuSGl2ZUNvbmZpZz17fSksd2luZG93LkhpdmVDb25maWcuRGFzaD1yLkRhc2gsd2luZG93LkhpdmVDb25maWcuU3RhdHM9ci5TdGF0cyx3aW5kb3cuSGl2ZUNvbmZpZy5VRFBCcm9hZGNhc3Q9ci5VRFBCcm9hZGNhc3Qsd2luZG93LkhpdmVDb25maWcuRGVidWdMb2dzPXIuRGVidWdMb2dzKX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByLG49aSgxMSksbz1pKDQpLHM9by52ZTshZnVuY3Rpb24odCl7dmFyIGU7IWZ1bmN0aW9uKHQpe3RbdC5vZmY9MF09XCJvZmZcIix0W3QuZXJyb3I9MV09XCJlcnJvclwiLHRbdC53YXJuPTJdPVwid2FyblwiLHRbdC5ub3RpY2U9M109XCJub3RpY2VcIix0W3QuaW5mbz00XT1cImluZm9cIix0W3QuZGVidWc9NV09XCJkZWJ1Z1wiLHRbdC50cmFjZT02XT1cInRyYWNlXCJ9KGU9dC52bHx8KHQudmw9e30pKTt2YXIgaT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt0aGlzLnRpbWVzdGFtcD1mdW5jdGlvbigpe30sdGhpcy55bD1uZXcgcyx0aGlzLmxldmVsPWUuZGVidWcsdGhpcy50aW1lc3RhbXAudG9TdHJpbmc9ZnVuY3Rpb24oKXt2YXIgdD1uZXcgRGF0ZSxlPShcIjBcIit0LmdldFVUQ0hvdXJzKCkpLnNsaWNlKC0yKStcIjpcIisoXCIwXCIrdC5nZXRVVENNaW51dGVzKCkpLnNsaWNlKC0yKStcIjpcIisoXCIwXCIrdC5nZXRVVENTZWNvbmRzKCkpLnNsaWNlKC0yKStcIjpcIit0LmdldFVUQ01pbGxpc2Vjb25kcygpO3JldHVyblwiW1wiK2UrXCJdXCJ9LHRoaXMubT1cInVuZGVmaW5lZFwiPT10eXBlb2YgY29uc29sZT97bG9nOmZ1bmN0aW9uKCl7fX06Y29uc29sZSx0aGlzLm0udHJhY2V8fCh0aGlzLm0udHJhY2U9dGhpcy5tLmxvZyksdGhpcy5tLmRlYnVnfHwodGhpcy5tLmRlYnVnPXRoaXMubS5sb2cpLHRoaXMubS5pbmZvfHwodGhpcy5tLmluZm89dGhpcy5tLmxvZyksdGhpcy5tLndhcm58fCh0aGlzLm0ud2Fybj10aGlzLm0ubG9nKSx0aGlzLm0uZXJyb3J8fCh0aGlzLm0uZXJyb3I9dGhpcy5tLmxvZyksdGhpcy5tbChlW3RoaXMubGV2ZWxdKX1yZXR1cm4gdC5wcm90b3R5cGUubWw9ZnVuY3Rpb24odCxpKXtuLkhpdmVDb25maWcuRnJhbWV3b3JrLkhpdmVEZWJ1Z0xldmVsJiZ2b2lkIDAhPWVbbi5IaXZlQ29uZmlnLkZyYW1ld29yay5IaXZlRGVidWdMZXZlbF0/dGhpcy5sZXZlbD1lW24uSGl2ZUNvbmZpZy5GcmFtZXdvcmsuSGl2ZURlYnVnTGV2ZWxdOnZvaWQgMCE9ZVt0XT90aGlzLmxldmVsPWVbdF06Y29uc29sZS5sb2coXCJXcm9uZyBsb2dnaW5nIGxldmVsOiBcIit0LGUpLHRoaXMud2woaSl9LHQucHJvdG90eXBlLndsPWZ1bmN0aW9uKHQpe3ZhciBpPXtsb2c6dGhpcy5UbCh0aGlzLm0ubG9nLGUuZXJyb3IsdCksZXJyb3I6dGhpcy5UbCh0aGlzLm0uZXJyb3IsZS5lcnJvcix0KSx3YXJuOnRoaXMuVGwodGhpcy5tLndhcm4sZS53YXJuLHQpLG5vdGljZTp0aGlzLlRsKHRoaXMubS5pbmZvLGUubm90aWNlLHQpLGluZm86dGhpcy5UbCh0aGlzLm0uaW5mbyxlLmluZm8sdCksZGVidWc6dGhpcy5UbCh0aGlzLm0uZGVidWcsZS5kZWJ1Zyx0KSx0cmFjZTp0aGlzLlRsKHRoaXMubS50cmFjZSxlLnRyYWNlLHQpfTt0P3RoaXMueWwuc2V0KHQsaSk6dGhpcy5TbD1pfSx0LnByb3RvdHlwZS5UbD1mdW5jdGlvbih0LGUsaSl7aWYoISh0aGlzLmxldmVsPj1lKSlyZXR1cm4gZnVuY3Rpb24oKXt9O3RyeXtyZXR1cm4gbi5IaXZlQ29uZmlnLkZyYW1ld29yay5Mb2dnZXJUaW1lc3RhbXA/aT9GdW5jdGlvbi5wcm90b3R5cGUuYmluZC5jYWxsKHQsY29uc29sZSxcIiVzICVzXCIsdGhpcy50aW1lc3RhbXAsaSk6RnVuY3Rpb24ucHJvdG90eXBlLmJpbmQuY2FsbCh0LGNvbnNvbGUsXCIlc1wiLHRoaXMudGltZXN0YW1wKTpGdW5jdGlvbi5wcm90b3R5cGUuYmluZC5jYWxsKHQsY29uc29sZSl9Y2F0Y2gocil7fX0sdC5wcm90b3R5cGUubG9nPWZ1bmN0aW9uKHQpe3JldHVybiB0Pyh0aGlzLnlsLmhhcyh0KXx8dGhpcy5tbChlW3RoaXMubGV2ZWxdLHQpLHRoaXMueWwuZ2V0KHQpKTp0aGlzLlNsfSx0fSgpO3QuYmw9aX0ocj1lLkVsfHwoZS5FbD17fSkpfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI9aSg0KSxuPXIudmUsbz1pKDEpLHM9aSgyKSxhPWkoNDApLGM9aSg0OSksaD1pKDE3KSxwPWkoMTEpLHU9aSg3KSxsPWkoNDIpLGQ9aSg5KSxmPWkoMzcpLGc9aSg1KSx2PWkoNTApLHk9aSg0OCksbT1pKDI3KSx3PWkoMTkpLFQ9aSgyMCksUz1pKDE4KSxiPWEucHQuSXIsRT1jLnB0LklsLEk9aC5wdC51aCxSPWgucHQuQ2gsaz1oLnB0LkhpdmVUZWNoRXJyb3IsQz1oLnB0LmJoLE89aC5wdC5BaDtlLnZlcnNpb249XCIzLjIuMFwiO3ZhciBQOyFmdW5jdGlvbih0KXt2YXIgcj1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCl7dGhpcy5SbD1bRVtFLkhpdmVKYXZhXSxFW0UuSGl2ZUpzUHJveHldLEVbRS5IaXZlSlNdLEVbRS5TdGF0c0pTXV0sdGhpcy5rbD1uZXcgbix0aGlzLkNsPW5ldyBBcnJheSx0aGlzLk9sPW5ldyBBcnJheSx0aGlzLlBsPW51bGwsdGhpcy5BbD0wLHRoaXMuTmw9MCx0aGlzLnU9XCJbSGl2ZUNvbW1dIFwiLHRoaXMueGw9MCx0aGlzLkJsPXUuYXIuZ2V0SXRlbShcImhpdmVQbHVnaW5JZFwiKSx0aGlzLkJsfHwodGhpcy5CbD1NYXRoLmFicyhNYXRoLmZsb29yKDY4NzE5NDc2NzM2Kk1hdGgucmFuZG9tKCkpKS50b1N0cmluZygxNiksdS5hci5zZXRJdGVtKFwiaGl2ZVBsdWdpbklkXCIsdGhpcy5CbCkpLHcuRXJyb3JNb25pdG9yLldpKCksdGhpcy5vcHRpb25zXz1uZXcgYi5GbCx0aGlzLl9sKHQpLHUubnIodCx0aGlzLm9wdGlvbnNfKSx1Lm9yKHdpbmRvdy5sb2NhdGlvbi5ocmVmLG5ldyBiLkRsLHRoaXMub3B0aW9uc18pLGEuTGwuSGwodGhpcy5vcHRpb25zXyksdGhpcy5mbz1zLkZyYW1ld29yay5yZXNvbHZlKHMuRnJhbWV3b3JrLkZlLndlKSxwLkhpdmVDb25maWcuRnJhbWV3b3JrLkxvZ2dlclRpbWVzdGFtcD10aGlzLm9wdGlvbnMoKS5sb2dnZXJUaW1lc3RhbXAsdGhpcy5mby5tbCh0aGlzLm9wdGlvbnMoKS5kZWJ1Z0xldmVsKSx3LkVycm9yTW9uaXRvci5XaSgpLkxoKHRoaXMuZm8ubG9nKCkpO3ZhciBlPXMuRnJhbWV3b3JrLnJlc29sdmUoZy5naS5DZSksaT1zLkZyYW1ld29yay5yZXNvbHZlKGcuZ2kuY2kpO2UuS28oKS50aGVuKGZ1bmN0aW9uKHQpe3cuRXJyb3JNb25pdG9yLldpKCkuc2V0VXNlcih0LldvKCkpfSk7dmFyIHI9e307aS5QbigpLnRoZW4oZnVuY3Rpb24odCl7cj17cElQQWRkcjp0Lk5uKCkuQm4oKX0sdy5FcnJvck1vbml0b3IuV2koKS5zZXRDdXN0b21EYXRhKHIpfSksd2luZG93LnZvPXRoaXMuZm8ubG9nKCksdGhpcy5NbCgpLHRoaXMuamw9bmV3IE8odGhpcyksbmV3IGwuVWwodGhpcyk7dmFyIG89dGhpcy5vcHRpb25zKCkuaWRsZVRpbWVQZXJpb2Q+dGhpcy5vcHRpb25zKCkuZmVlZGJhY2tQZXJpb2Q/dGhpcy5vcHRpb25zKCkuaWRsZVRpbWVQZXJpb2Q6Uy5rZS54aDt0aGlzLlZsPW5ldyB1LnZyKG8pfXJldHVybiB0LnByb3RvdHlwZS5vcHRpb25zPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMub3B0aW9uc199LHQucHJvdG90eXBlLm09ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5mby5sb2coKX0sdC5wcm90b3R5cGUuUz1mdW5jdGlvbigpe3JldHVybiB0aGlzLkJsfSx0LnByb3RvdHlwZS5jdD1mdW5jdGlvbigpe3JldHVybiBlLnZlcnNpb259LHQucHJvdG90eXBlLlFsPWZ1bmN0aW9uKCl7Zm9yKHZhciB0PTAsZT10aGlzLk9sO3Q8ZS5sZW5ndGg7dCsrKXt2YXIgaT1lW3RdO2kudGVjaC5xbCh0aGlzKX19LHQucHJvdG90eXBlLl9sPWZ1bmN0aW9uKHQpe3ZhciBlPW5ldyB5LlN0YXRzSlModGhpcyx0KTt0aGlzLmtsLnNldCh5LlN0YXRzSlMuSmwsZSk7dmFyIHI9aSg0MykuSGl2ZUphdmE7dGhpcy5rbC5zZXQoci5KbCxuZXcgcih0aGlzLHQpKTt2YXIgbj10LmhpdmVUZWNoT3JkZXI7aWYoIW58fG4gaW5zdGFuY2VvZiBBcnJheSlpZihuJiZuLmxlbmd0aD4wKWZvcih2YXIgbz1uLmxlbmd0aDtvLS07KXt2YXIgcz1uW29dO1wic3RyaW5nXCIhPXR5cGVvZiBzfHx0aGlzLlJsLmluZGV4T2Yocyk9PS0xPyhjb25zb2xlLndhcm4odGhpcy51KydUaGUgXCInK3MrJ1wiIEhpdmUgdGVjaCBpcyB1bmRlZmluZWQnKSxuLnNwbGljZShvLDEpKTpcInN0cmluZ1wiPT10eXBlb2YgcyYmdGhpcy5rbC5oYXMocyl8fGNvbnNvbGUud2Fybih0aGlzLnUrJ1RoZSBcIicrcysnXCIgSGl2ZSB0ZWNoIGlzIG5vdCBlbmFibGVkIG9uIHRoaXMgcGx1Z2luJyl9ZWxzZSBuPXRoaXMuUmw7ZWxzZSBjb25zb2xlLndhcm4odGhpcy51K1wiaGl2ZVRlY2hPcmRlciB2YWx1ZSBub3QgYWNjZXB0ZWQuIEl0IG11c3QgYmUgYW4gYXJyYXkgb2Ygc3RyaW5nc1wiKSxuPXRoaXMuUmw7dC5oaXZlVGVjaE9yZGVyPW59LHQucHJvdG90eXBlLnA9ZnVuY3Rpb24odCl7dmFyIGU9dGhpczt0aGlzLm0oKS5ub3RpY2UodGhpcy51K1wicmVzb2x2aW5nIFwiK3QpLHRoaXMuS2wodCk7dmFyIGk9by5kZWZlcigpLHI9dGhpcy5HbCgpLnZhbHVlcygpOzA9PXIubGVuZ3RoJiZpLnJlamVjdCh1LnNyKHQsSS5zaCkpO3ZhciBuLHMsYT0hMSxjPSExLGg9MCxwPW51bGw7cmV0dXJuIHUuWGkoZnVuY3Rpb24oKXtyZXR1cm4hYSYmIWMmJmg8ci5sZW5ndGgmJiFufSxmdW5jdGlvbigpe3ZhciBpPXJbaCsrXTtpLnpsKCk7dmFyIHU7cmV0dXJuIHU9aS5XbCgpJiYhcz9lLiRsKHQpOm8ucmVzb2x2ZShudWxsKSx1LnRoZW4oZnVuY3Rpb24ocil7bnVsbCE9ciYmKHM9cik7dmFyIG49aS5ZbCgpO3JldHVybiBpLmluaXRTZXNzaW9uKHQscykudGltZW91dChuLFwiW1wiK2kuQWkoKStcIl0gRXJyb3I6IGluaXRpYWxpemF0aW9uIHRpbWVkIG91dCBhZnRlciBcIituK1wibXNcIikudGhlbihmdW5jdGlvbih0KXtwPXQsZS5YbChwLGkpLGE9ITAsIWkuV2woKSYmcyYmcy5Rbi5yZXNldCgpLGUubSgpLm5vdGljZShlLnUrXCJpbml0aWFsaXppbmcgU2Vzc2lvbjpbXCIrcC5pZCtcIl0gVGlja2V0OlwiK3AudGlja2V0LnRvU3RyaW5nKCkrXCIgSGl2ZVRlY2g6W1wiK3AudGVjaC5BaSgpK1wiXVwiKSxvLnJlc29sdmUoITApfSxmdW5jdGlvbihyKXtyIGluc3RhbmNlb2YgRXJyb3ImJihyPW5ldyBrKEMuU2gsci5tZXNzYWdlKSxpLlpsKHIpKSxyLnRpY2tldFVybD10LGM9IWkub25FcnJvcihyKSxlLm0oKS5kZWJ1ZyhlLnUrXCJ0ZWNoIFwiK2kuQWkoKStcIjogXCIrci5tZXNzYWdlKSxvLnJlc29sdmUoITApfSl9LGZ1bmN0aW9uKHQpe249dCxvLnJlc29sdmUoITApfSl9KS50aGVuKGZ1bmN0aW9uKCl7bj9pLnJlamVjdCh1LnNyKHQsSS5waCxuKSk6Yz9pLnJlamVjdCh1LnNyKHQsSS5oaCkpOmE/aS5yZXNvbHZlKHApOmkucmVqZWN0KHUuc3IodCxJLnNoKSl9KVtcImNhdGNoXCJdKGZ1bmN0aW9uKGUpe3cuRXJyb3JNb25pdG9yLldpKCkuX2goZSksaS5yZWplY3QodS5zcih0LEkub2gsZS50b1N0cmluZygpKSl9KS5kb25lKCksaS52dH0sdC5wcm90b3R5cGUuJGw9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcztyZXR1cm4gbS5IaXZlLlJlcG9ydGluZygpLmluaXRTZXNzaW9uKHQsITEpLnRoZW4oZnVuY3Rpb24oaSl7cmV0dXJuIGUubSgpLmRlYnVnKGUudStcInZlcmlmaWVkIHRpY2tldCBcIit0KSxlLmhuKGkpLGl9KVtcImNhdGNoXCJdKGZ1bmN0aW9uKHQpe3JldHVybiBvLnJlamVjdChcIlRpY2tldCBub3QgdmVyaWZpZWQsIGVycm9yOiBcIit0Lm1lc3NhZ2UpfSl9LHQucHJvdG90eXBlLkdsPWZ1bmN0aW9uKCl7dmFyIHQ9SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0aGlzLm9wdGlvbnMoKS5oaXZlVGVjaE9yZGVyKSksZT1uZXcgbjtmb3IodmFyIGkgaW4gdCl0aGlzLmtsLmhhcyh0W2ldKSYmZS5zZXQodFtpXSx0aGlzLmtsLmdldCh0W2ldKSk7cmV0dXJuIGV9LHQucHJvdG90eXBlLktsPWZ1bmN0aW9uKHQpe3ZhciBlPXcuRXJyb3JNb25pdG9yLldpKCk7dHJ5e3ZhciBpPW5ldyBULmFwO2kuS2godCksaS5ibigpJiZpLkVuKCkmJmkuZXMoKT9lLnNldFRhZ3MoW2kuYm4oKSxpLkVuKCksaS5lcygpXSk6ZS5faCh0aGlzLnUrXCIgVGlja2V0IG5vdCB2YWxpZCwgd2UgY291bGQgbm90IHJlc29sdmUgdGhlIHRyaXBsZSBwYXJ0bmVySWQvQ3VzdG9tZXJJZC9Db250ZW50SWQ6IFwiK2kuYm4oKStcIi9cIitpLkVuKCkrXCIvXCIraS5lcygpKX1jYXRjaChyKXt0aGlzLm0oKS53YXJuKHRoaXMudStcIiBcIityLm1lc3NhZ2UsciksZS5ub3RpZnkocil9fSx0LnByb3RvdHlwZS5obj1mdW5jdGlvbih0KXt2YXIgaT17Y29tbVZlcnNpb246ZS52ZXJzaW9uLHBsdWdpbk5hbWU6dGhpcy5UKCkscGx1Z2luVmVyc2lvbjp0aGlzLkkoKSxwbGF5ZXJUZWNoOnRoaXMuaHQoKSxwbGF5ZXJWZXJzaW9uOnRoaXMucSgpLHRlbGVtZXRyeUlkOnRoaXMudGQoKX07dC5Rbi5obihpKX0sdC5wcm90b3R5cGUudj1mdW5jdGlvbigpe3dpbmRvdy5IaXZlUmVxdWVzdD1YTUxIdHRwUmVxdWVzdCx1LkhpdmVSZXF1ZXN0RmFjdG9yeS5jbGVhcigpLG0uSGl2ZS5SZXBvcnRpbmcoKS5jbG9zZSgpfSx0LnByb3RvdHlwZS5lZD1mdW5jdGlvbih0KXt0aGlzLlBsJiZ0aGlzLlBsLnRlY2g/KHQuc2Vzc2lvbklkPXRoaXMuUGwuaWQsdGhpcy5QbC50ZWNoLnduKHRoaXMuUGwsdCkpOnRoaXMuQ2wucHVzaCh0KX0sdC5wcm90b3R5cGUucmQ9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLkNsO3JldHVybiB0aGlzLkNsPW5ldyBBcnJheSx0fSx0LnByb3RvdHlwZS5NbD1mdW5jdGlvbigpe3ZhciB0PXRoaXMsZT13aW5kb3c7ZS5hZGRFdmVudExpc3RlbmVyP2UuYWRkRXZlbnRMaXN0ZW5lcihcImJlZm9yZXVubG9hZFwiLGZ1bmN0aW9uKCl7dC5uZCghMCl9LCExKTplLmF0dGFjaEV2ZW50KFwib25iZWZvcmV1bmxvYWRcIixmdW5jdGlvbigpe3QubmQoITApfSl9LHQucHJvdG90eXBlLmg9ZnVuY3Rpb24odCl7dGhpcy5uZCh0KSx0aGlzLlBsPW51bGwsdGhpcy5PbD1uZXcgQXJyYXksdGhpcy5BbD0wLHRoaXMuTmw9MCx0aGlzLm9kKCl9LHQucHJvdG90eXBlLlhsPWZ1bmN0aW9uKHQsZSl7dC50ZWNoPWUsdGhpcy5PbC5wdXNoKHQpfSx0LnByb3RvdHlwZS5SPWZ1bmN0aW9uKHQpe2lmKG51bGw9PXRoaXMuUGwpe2Zvcih2YXIgZT10P3Q6dGhpcy5pdCgpLGk9MDtpPHRoaXMuT2wubGVuZ3RoO2krKyl7dmFyIHI9dGhpcy5PbFtpXTtpZihyLnN0KGUpKXJldHVybiB0aGlzLlBsPXIsdGhpcy5QbC5SaT90aGlzLlBsLlJpLl9vLnNkKHRoaXMuUGwudGlja2V0KTp0aGlzLmFkKCksdGhpcy5PbD1uZXcgQXJyYXksdGhpcy5QbC50ZWNoLm9uQWN0aXZlU2Vzc2lvbih0aGlzLlBsKSx0aGlzLm0oKS5ub3RpY2UodGhpcy51K1wiYWN0aXZhdGluZyBTZXNzaW9uOltcIit0aGlzLlBsLmlkK1wiXSBUaWNrZXQ6XCIrdGhpcy5QbC50aWNrZXQudG9TdHJpbmcoKStcIiBIaXZlVGVjaDpbXCIrdGhpcy5QbC50ZWNoLkFpKCkrXCJdXCIpLHRoaXMuaGQoKSwhMH10aGlzLm0oKS53YXJuKHRoaXMudStcIkNsb3Npbmcgc2Vzc2lvbnMgLSB0aGUgYWN0aXZlIHN0cmVhbSBkb2Vzbid0IG1hdGNoIGFueSBpbml0aWFsaXplZCBzZXNzaW9uc1wiKSx0aGlzLm0oKS53YXJuKHRoaXMudStcIkFjdGl2ZTpcIitlK1wiIC0gaW5pdGlhbGl6ZWQ6IFwiK3RoaXMuT2wubGVuZ3RoKSx0aGlzLmgoKX1yZXR1cm4hMX0sdC5wcm90b3R5cGUuQz1mdW5jdGlvbigpe2lmKHRoaXMuUGwpcmV0dXJuIHRoaXMuUGwuZygpfSx0LnByb3RvdHlwZS5hZD1mdW5jdGlvbigpe3ZhciB0PSExO3RoaXMuT2wuZm9yRWFjaChmdW5jdGlvbihlKXtlLlJpJiYodD0hMCl9KSx0JiZtLkhpdmUuUmVwb3J0aW5nKCkuY2xvc2UoKX0sdC5wcm90b3R5cGUucGQ9ZnVuY3Rpb24oKXtpZihudWxsIT10aGlzLlBsKXtpZih0aGlzLlBsLnN0KHRoaXMuaXQoKSkpcmV0dXJuITA7dGhpcy5tKCkud2Fybih0aGlzLnUrXCJTZXNzaW9uIHNyYyBtaXNtYXRjaDogXCIrdGhpcy5pdCgpK1wiICE9IFwiK3RoaXMuUGwubWFuaWZlc3QpLHRoaXMuaCgpfXJldHVybiExfSx0LnByb3RvdHlwZS5uZD1mdW5jdGlvbih0KXtpZihudWxsIT10aGlzLlBsKXRoaXMubSgpLm5vdGljZSh0aGlzLnUrXCJTdG9wcGluZyBzZXNzaW9uIFtcIit0aGlzLlBsLmlkK1wiXVwiKSx0aGlzLlBsLmNsb3NlKHQpO2Vsc2UgaWYodGhpcy5PbC5sZW5ndGg+MCl7dmFyIGU9dGhpcy5PbFswXTt0aGlzLm0oKS5ub3RpY2UodGhpcy51K1wiQXR0ZW1wdCB0byBzdG9wcGluZyBzZXNzaW9uIFtcIitlLmlkK1wiXVwiKSxlLmNsb3NlKHQpfX0sdC5wcm90b3R5cGUuaGQ9ZnVuY3Rpb24oKXt2YXIgdD10aGlzO251bGw9PXRoaXMudWQmJih0aGlzLnVkPXNldEludGVydmFsKGZ1bmN0aW9uKCl7dC5sZCgpfSx0aGlzLm9wdGlvbnMoKS5mZWVkYmFja1BlcmlvZCksdGhpcy5sZCgpKX0sdC5wcm90b3R5cGUub2Q9ZnVuY3Rpb24oKXtjbGVhckludGVydmFsKHRoaXMudWQpLHRoaXMudWQ9bnVsbH0sdC5wcm90b3R5cGUubGQ9ZnVuY3Rpb24oKXt2YXIgdD10aGlzO2lmKHRoaXMucGQoKSl7aWYoIXRoaXMuc3QoKSlyZXR1cm4gdm9pZCB0aGlzLmgoKTt2YXIgZT1uZXcgdS5GaTtlLmxyPXRoaXMuZ2V0Q3VycmVudFRpbWUoKSxlLmRyPXRoaXMubnQoKSxlLmdyPXRoaXMuQWwsZS53aWR0aD10aGlzLm90KCkud2lkdGgsZS5oZWlnaHQ9dGhpcy5vdCgpLmhlaWdodCxlLmRkPXRoaXMuaXNGdWxsc2NyZWVuKCksdGhpcy5QbC5raSh0aGlzLlZsLmhyKGUpKSx0aGlzLlBsLnRlY2guZmQodGhpcy5QbCxlKS5mYWlsKGZ1bmN0aW9uKGUpe3QubSgpLndhcm4odC51K1wic3RhdHMgaGFuZGxpbmcgZmFpbGVkXCIsZSksdC5vZCgpfSl9fSx0LnByb3RvdHlwZS5nZD1mdW5jdGlvbigpe3ZhciB0PXRoaXM7dHJ5e3UuWWkuV2kodGhpcy5tKCkpLiRpKGZ1bmN0aW9uKGUpe3ZhciBpPXQudmQoKTtpJiYhaS5PaSgpJiYodC5fKGU/ZC5GLkIuanI6ZC5GLkIuSElEREVOKSx0Lm0oKS5kZWJ1ZyhlP1widmlzaWJsZVwiOlwiaGlkZGVuXCIpKX0pfWNhdGNoKGUpe3cuRXJyb3JNb25pdG9yLldpKCkuX2goXCJlcnJvciBzZXR0aW5nIHVwIHRoZSB2aXNpYmlsaXR5Q2hhbmdlIGxpc3RlbmVyXCIse2Vycm9yOmV9KX19LHQucHJvdG90eXBlLms9ZnVuY3Rpb24odCl7dGhpcy5wZCgpJiZ0aGlzLk5sPD0wJiYodGhpcy5ObD1EYXRlLm5vdygpLCh2b2lkIDA9PXR8fHQpJiZ0aGlzLl8oZC5GLkIuTHIpKX0sdC5wcm90b3R5cGUuRz1mdW5jdGlvbigpe3ZhciB0PTA9PXRoaXMuQWw7aWYodGhpcy5ObD4wKXt2YXIgZT1EYXRlLm5vdygpLXRoaXMuTmw7cmV0dXJuIHRoaXMuQWwrPWUsdGhpcy5tKCkuZGVidWcodGhpcy51K1wicmVwb3J0aW5nIG5ldyBidWZmZXJpbmcgZXZlbnQgb2YgXCIrZSksdGhpcy5ObD0wLHQmJnRoaXMubGQoKSwhMH1yZXR1cm4hMX0sdC5wcm90b3R5cGUub25FcnJvcj1mdW5jdGlvbih0LGUsaSl7dm9pZCAwPT09aSYmKGk9ITApLHRoaXMuXyhkLkYuQi5FUlJPUix7Y29kZTotMSxcInBsYXllci1jb2RlXCI6dH0pLGkmJnRoaXMuaCgpfSx0LnByb3RvdHlwZS5fPWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcyxyPXRoaXMudmQoKTtudWxsPT1yfHxyIT10aGlzLlBsJiZyLnRlY2guQWkoKT09PUVbRS5IaXZlSmF2YV18fHIudGVjaC55ZChyLHQsZSkuZmFpbChmdW5jdGlvbih0KXtpLm0oKS53YXJuKGkudStcImVycm9yIGluIGZvcndhcmRpbmcgcGxheWVyIGV2ZW50IHRvIHRlY2hcIix0KX0pfSx0LnByb3RvdHlwZS52ZD1mdW5jdGlvbigpe3JldHVybiB0aGlzLlBsP3RoaXMuUGw6dGhpcy5PbCYmdGhpcy5PbC5sZW5ndGg+MD90aGlzLk9sWzBdOnZvaWQgMH0sdC5wcm90b3R5cGUubWQ9ZnVuY3Rpb24oKXt0aGlzLnhsPTB9LHQucHJvdG90eXBlLndkPWZ1bmN0aW9uKHQsZSl7dGhpcy5tZCgpO3ZhciBpPTcscj02O3RoaXMueGwrPXQ8PDQqaSxlJiYwPT09dCYmKHRoaXMueGwrPTE8PDQqKHItRVtlLkFpKCldKSksdD4wJiZ3LkVycm9yTW9uaXRvci5XaSgpLl9oKHRoaXMudStcIlN0YXR1cyBDb2RlIEVycm9yOiBcIitSW3RdKX0sdC5wcm90b3R5cGUuUGg9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy54bH0sdC5wcm90b3R5cGUudGQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5vcHRpb25zKCkudGVsZW1ldHJ5SWR9LHR9KCk7dC5QbHVnaW49cn0oUD1lLnB0fHwoZS5wdD17fSkpLHMuRnJhbWV3b3JrLlFlKG5ldyBmLlRkKSxzLkZyYW1ld29yay5HZShcInBlZXIwXCIsbmV3IHYuU2QpLHMuRnJhbWV3b3JrLnplKFwicGVlcjBcIiksd2luZG93LkhpdmVSZXF1ZXN0RmFjdG9yeT11LkhpdmVSZXF1ZXN0RmFjdG9yeX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPWkoNDUpLG49aSg3KSxvPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0KXt0aGlzLnJlYWR5U3RhdGU9Myx0aGlzLnN0YXR1cz0wLHQmJih0aGlzLnNlc3Npb25JZD10KX1yZXR1cm4gdC5MaD1mdW5jdGlvbihlKXt0Lm09ZX0sdC5yZWdpc3Rlcj1mdW5jdGlvbihlLGkpe3QuYmRbZV09aX0sdC5wcm90b3R5cGUuRWQ9ZnVuY3Rpb24oZSl7dGhpcy5zZXNzaW9uSWR8fCh0aGlzLnNlc3Npb25JZD10LmJkW2VdKX0sdC5wcm90b3R5cGUub3Blbj1mdW5jdGlvbih0LGUsaSl7dm9pZCAwPT09aSYmKGk9ITEpLHRoaXMubWV0aG9kPXQsdGhpcy51cmw9ZSx0aGlzLklkPWl9LHQucHJvdG90eXBlLmdldEFsbFJlc3BvbnNlSGVhZGVycz1mdW5jdGlvbigpe3JldHVybiB0aGlzLlJkfSx0LnByb3RvdHlwZS5nZXRSZXNwb25zZUhlYWRlcj1mdW5jdGlvbih0KXt2YXIgZT10aGlzLmdldEFsbFJlc3BvbnNlSGVhZGVycygpO2lmKGUpe3ZhciBpPVtdLHI9ZS5zcGxpdChcIlxcblwiKTtyZXR1cm4gci5mb3JFYWNoKGZ1bmN0aW9uKHQpe3ZhciBlPXQuc3BsaXQoXCI6XCIpO2lbZVswXV09ZVsxXX0pLGlbdF19fSx0LnByb3RvdHlwZS5zZW5kPWZ1bmN0aW9uKCl7aWYodC5tJiZ0Lm0uZGVidWcodGhpcy5tZXRob2QrXCIgXCIrdGhpcy51cmwpLCF0aGlzLnNlc3Npb25JZCl7dmFyIGU9T2JqZWN0LmtleXModC5iZCk7ZS5sZW5ndGg+MCYmKHRoaXMuc2Vzc2lvbklkPXQuYmRbZVswXV0pfXZhciBpPXRoaXMsbz1uZXcgWE1MSHR0cFJlcXVlc3Q7MD09PXRoaXMudXJsLmluZGV4T2YoXCIvL1wiKSYmKHRoaXMudXJsPWxvY2F0aW9uLnByb3RvY29sK3RoaXMudXJsKTt2YXIgcz1uLnJyKHIuQ2Qua2Qsci5DZC5UbyxyLkNkLk9kLHRoaXMuc2Vzc2lvbklkLGVuY29kZVVSSUNvbXBvbmVudCh0aGlzLnVybCkpO28ub3BlbihcIkdFVFwiLHMpLHRoaXMucmVzcG9uc2VUeXBlJiYoby5yZXNwb25zZVR5cGU9dGhpcy5yZXNwb25zZVR5cGUpLG8ub25yZWFkeXN0YXRlY2hhbmdlPWZ1bmN0aW9uKCl7fSxvLm9ubG9hZD1mdW5jdGlvbigpe2lmKDQ9PT1vLnJlYWR5U3RhdGUpdHJ5e2kuUmQ9by5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKSxpLnJlc3BvbnNlPW8ucmVzcG9uc2U7dmFyIGU9by5yZXNwb25zZS5ieXRlTGVuZ3RoO1wiYXJyYXlidWZmZXJcIiE9PW8ucmVzcG9uc2VUeXBlJiYoaS5yZXNwb25zZVRleHQ9by5yZXNwb25zZSksaS5yZWFkeVN0YXRlPTQsaS5zdGF0dXM9by5zdGF0dXMsaS5vbnByb2dyZXNzKHtsZW5ndGhDb21wdXRhYmxlOiEwLGxvYWRlZDplLHRvdGFsOmV9KSxpLm9ucmVhZHlzdGF0ZWNoYW5nZSh7dHlwZTpcImxvYWRlbmRcIix0YXJnZXQ6aSxjdXJyZW50VGFyZ2V0OmksYnViYmxlczohMSxjYW5jZWxhYmxlOiExLGxlbmd0aENvbXB1dGFibGU6ITEsbG9hZGVkOmUsdG90YWw6ZX0pLGkub25sb2FkKCksaS5vbmxvYWRlbmQoe3R5cGU6XCJsb2FkZW5kXCIsdGFyZ2V0OmksY3VycmVudFRhcmdldDppLGJ1YmJsZXM6ITEsY2FuY2VsYWJsZTohMSxsZW5ndGhDb21wdXRhYmxlOiExLGxvYWRlZDplLHRvdGFsOjB9KX1jYXRjaChyKXt0Lm0mJnQubS53YXJuKHIpfX0sby5vbmVycm9yPWZ1bmN0aW9uKGUpe3QubSYmdC5tLndhcm4oXCJvbkVycm9yOiBcIitKU09OLnN0cmluZ2lmeShlKSksaS5vbmVycm9yKGUpfSxvLm9uYWJvcnQ9ZnVuY3Rpb24oZSl7dC5tJiZ0Lm0ud2FybihcIm9uQWJvcnQ6IFwiK0pTT04uc3RyaW5naWZ5KGUpKX0sby5zZW5kKCl9LHQucHJvdG90eXBlLmFib3J0PWZ1bmN0aW9uKCl7fSx0LnByb3RvdHlwZS5vbmxvYWQ9ZnVuY3Rpb24oKXt9LHQucHJvdG90eXBlLm9ubG9hZGVuZD1mdW5jdGlvbih0KXt9LHQucHJvdG90eXBlLm9uZXJyb3I9ZnVuY3Rpb24odCl7fSx0LnByb3RvdHlwZS5vbnByb2dyZXNzPWZ1bmN0aW9uKHQpe30sdC5wcm90b3R5cGUub25yZWFkeXN0YXRlY2hhbmdlPWZ1bmN0aW9uKHQpe30sdH0oKTtvLmJkPXt9LGUuVGk9b30sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPWkoMiksbj1pKDUpLG89ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7fXJldHVybiB0LlJlcG9ydGluZz1mdW5jdGlvbigpe3JldHVybiB0LmFwcD1cIlNUQVRTXCIsci5GcmFtZXdvcmsucmVzb2x2ZShuLmdpLnVpKX0sdC5Ybz1mdW5jdGlvbigpe3JldHVybiB0aGlzLmFwcH0sdC5nZXRWZXJzaW9uPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudmVyc2lvbn0sdH0oKTtvLnZlcnNpb249XCIzLjIuMFwiLGUuSGl2ZT1vfSxmdW5jdGlvbih0LGUsaSl7dmFyIHI7IWZ1bmN0aW9uKG4sbyl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHM9XCIwLjcuMTJcIixhPVwiXCIsYz1cIj9cIixoPVwiZnVuY3Rpb25cIixwPVwidW5kZWZpbmVkXCIsdT1cIm9iamVjdFwiLGw9XCJzdHJpbmdcIixkPVwibWFqb3JcIixmPVwibW9kZWxcIixnPVwibmFtZVwiLHY9XCJ0eXBlXCIseT1cInZlbmRvclwiLG09XCJ2ZXJzaW9uXCIsdz1cImFyY2hpdGVjdHVyZVwiLFQ9XCJjb25zb2xlXCIsUz1cIm1vYmlsZVwiLGI9XCJ0YWJsZXRcIixFPVwic21hcnR0dlwiLEk9XCJ3ZWFyYWJsZVwiLFI9XCJlbWJlZGRlZFwiLGs9e2V4dGVuZDpmdW5jdGlvbih0LGUpe3ZhciBpPXt9O2Zvcih2YXIgciBpbiB0KWVbcl0mJmVbcl0ubGVuZ3RoJTI9PT0wP2lbcl09ZVtyXS5jb25jYXQodFtyXSk6aVtyXT10W3JdO3JldHVybiBpfSxoYXM6ZnVuY3Rpb24odCxlKXtyZXR1cm5cInN0cmluZ1wiPT10eXBlb2YgdCYmZS50b0xvd2VyQ2FzZSgpLmluZGV4T2YodC50b0xvd2VyQ2FzZSgpKSE9PS0xfSxQZDpmdW5jdGlvbih0KXtyZXR1cm4gdC50b0xvd2VyQ2FzZSgpfSxBZDpmdW5jdGlvbih0KXtyZXR1cm4gdHlwZW9mIHQ9PT1sP3QucmVwbGFjZSgvW15cXGRcXC5dL2csXCJcIikuc3BsaXQoXCIuXCIpWzBdOm99LHRyaW06ZnVuY3Rpb24odCl7cmV0dXJuIHQucmVwbGFjZSgvXltcXHNcXHVGRUZGXFx4QTBdK3xbXFxzXFx1RkVGRlxceEEwXSskL2csXCJcIil9fSxDPXtOZDpmdW5jdGlvbigpe2Zvcih2YXIgdCxlLGkscixuLHMsYSxjPTAsbD1hcmd1bWVudHM7YzxsLmxlbmd0aCYmIXM7KXt2YXIgZD1sW2NdLGY9bFtjKzFdO2lmKHR5cGVvZiB0PT09cCl7dD17fTtmb3IociBpbiBmKWYuaGFzT3duUHJvcGVydHkocikmJihuPWZbcl0sdHlwZW9mIG49PT11P3RbblswXV09bzp0W25dPW8pfWZvcihlPWk9MDtlPGQubGVuZ3RoJiYhczspaWYocz1kW2UrK10uZXhlYyh0aGlzLnhkKCkpKWZvcihyPTA7cjxmLmxlbmd0aDtyKyspYT1zWysraV0sbj1mW3JdLHR5cGVvZiBuPT09dSYmbi5sZW5ndGg+MD8yPT1uLmxlbmd0aD90eXBlb2YgblsxXT09aD90W25bMF1dPW5bMV0uY2FsbCh0aGlzLGEpOnRbblswXV09blsxXTozPT1uLmxlbmd0aD90eXBlb2YgblsxXSE9PWh8fG5bMV0uZXhlYyYmblsxXS50ZXN0P3RbblswXV09YT9hLnJlcGxhY2UoblsxXSxuWzJdKTpvOnRbblswXV09YT9uWzFdLmNhbGwodGhpcyxhLG5bMl0pOm86ND09bi5sZW5ndGgmJih0W25bMF1dPWE/blszXS5jYWxsKHRoaXMsYS5yZXBsYWNlKG5bMV0sblsyXSkpOm8pOnRbbl09YT9hOm87Yys9Mn1yZXR1cm4gdH0sYWM6ZnVuY3Rpb24odCxlKXtmb3IodmFyIGkgaW4gZSlpZih0eXBlb2YgZVtpXT09PXUmJmVbaV0ubGVuZ3RoPjApe2Zvcih2YXIgcj0wO3I8ZVtpXS5sZW5ndGg7cisrKWlmKGsuaGFzKGVbaV1bcl0sdCkpcmV0dXJuIGk9PT1jP286aX1lbHNlIGlmKGsuaGFzKGVbaV0sdCkpcmV0dXJuIGk9PT1jP286aTtyZXR1cm4gdH19LE89e3RpOntCZDp7dmVyc2lvbjp7XCIxLjBcIjpcIi84XCIsMS4yOlwiLzFcIiwxLjM6XCIvM1wiLFwiMi4wXCI6XCIvNDEyXCIsXCIyLjAuMlwiOlwiLzQxNlwiLFwiMi4wLjNcIjpcIi80MTdcIixcIjIuMC40XCI6XCIvNDE5XCIsS3A6XCIvXCJ9fX0sRmQ6e19kOntEZDp7SGQ6W1wiU0RcIixcIktGXCJdfX0sTGQ6e0RkOntNZDpcIjczNzNLVFwifSx2ZW5kb3I6e2pkOlwiQVBBXCIsVWQ6XCJTcHJpbnRcIn19fSxvczp7VmQ6e3ZlcnNpb246e1FkOlwiNC45MFwiLFwiTlQgMy4xMVwiOlwiTlQzLjUxXCIsXCJOVCA0LjBcIjpcIk5UNC4wXCIsMjAwMDpcIk5UIDUuMFwiLHFkOltcIk5UIDUuMVwiLFwiTlQgNS4yXCJdLEpkOlwiTlQgNi4wXCIsNzpcIk5UIDYuMVwiLDg6XCJOVCA2LjJcIiw4LjE6XCJOVCA2LjNcIiwxMDpbXCJOVCA2LjRcIixcIk5UIDEwLjBcIl0sS2Q6XCJBUk1cIn19fX0sUD17dGk6W1svKG9wZXJhXFxzbWluaSlcXC8oW1xcd1xcLi1dKykvaSwvKG9wZXJhXFxzW21vYmlsZXRhYl0rKS4rdmVyc2lvblxcLyhbXFx3XFwuLV0rKS9pLC8ob3BlcmEpLit2ZXJzaW9uXFwvKFtcXHdcXC5dKykvaSwvKG9wZXJhKVtcXC9cXHNdKyhbXFx3XFwuXSspL2ldLFtnLG1dLFsvKG9waW9zKVtcXC9cXHNdKyhbXFx3XFwuXSspL2ldLFtbZyxcIk9wZXJhIE1pbmlcIl0sbV0sWy9cXHMob3ByKVxcLyhbXFx3XFwuXSspL2ldLFtbZyxcIk9wZXJhXCJdLG1dLFsvKGtpbmRsZSlcXC8oW1xcd1xcLl0rKS9pLC8obHVuYXNjYXBlfG1heHRob258bmV0ZnJvbnR8amFzbWluZXxibGF6ZXIpW1xcL1xcc10/KFtcXHdcXC5dKykqL2ksLyhhdmFudFxcc3xpZW1vYmlsZXxzbGltfGJhaWR1KSg/OmJyb3dzZXIpP1tcXC9cXHNdPyhbXFx3XFwuXSopL2ksLyg/Om1zfFxcKCkoaWUpXFxzKFtcXHdcXC5dKykvaSwvKHJla29ucSlcXC8oW1xcd1xcLl0rKSovaSwvKGNocm9taXVtfGZsb2NrfHJvY2ttZWx0fG1pZG9yaXxlcGlwaGFueXxzaWxrfHNreWZpcmV8b3ZpYnJvd3Nlcnxib2x0fGlyb258dml2YWxkaXxpcmlkaXVtfHBoYW50b21qcylcXC8oW1xcd1xcLi1dKykvaV0sW2csbV0sWy8odHJpZGVudCkuK3J2WzpcXHNdKFtcXHdcXC5dKykuK2xpa2VcXHNnZWNrby9pXSxbW2csXCJJRVwiXSxtXSxbLyhlZGdlKVxcLygoXFxkKyk/W1xcd1xcLl0rKS9pXSxbZyxtXSxbLyh5YWJyb3dzZXIpXFwvKFtcXHdcXC5dKykvaV0sW1tnLFwiWWFuZGV4XCJdLG1dLFsvKGNvbW9kb19kcmFnb24pXFwvKFtcXHdcXC5dKykvaV0sW1tnLC9fL2csXCIgXCJdLG1dLFsvKG1pY3JvbWVzc2VuZ2VyKVxcLyhbXFx3XFwuXSspL2ldLFtbZyxcIldlQ2hhdFwiXSxtXSxbL3hpYW9taVxcL21pdWlicm93c2VyXFwvKFtcXHdcXC5dKykvaV0sW20sW2csXCJNSVVJIEJyb3dzZXJcIl1dLFsvXFxzd3ZcXCkuKyhjaHJvbWUpXFwvKFtcXHdcXC5dKykvaV0sW1tnLC8oLispLyxcIiQxIFdlYlZpZXdcIl0sbV0sWy9hbmRyb2lkLitzYW1zdW5nYnJvd3NlclxcLyhbXFx3XFwuXSspL2ksL2FuZHJvaWQuK3ZlcnNpb25cXC8oW1xcd1xcLl0rKVxccysoPzptb2JpbGVcXHM/c2FmYXJpfHNhZmFyaSkqL2ldLFttLFtnLFwiQW5kcm9pZCBCcm93c2VyXCJdXSxbLyhjaHJvbWV8b21uaXdlYnxhcm9yYXxbdGl6ZW5va2FdezV9XFxzP2Jyb3dzZXIpXFwvdj8oW1xcd1xcLl0rKS9pLC8ocXFicm93c2VyKVtcXC9cXHNdPyhbXFx3XFwuXSspL2ldLFtnLG1dLFsvKHVjXFxzP2Jyb3dzZXIpW1xcL1xcc10/KFtcXHdcXC5dKykvaSwvdWN3ZWIuKyh1Y2Jyb3dzZXIpW1xcL1xcc10/KFtcXHdcXC5dKykvaSwvanVjLisodWN3ZWIpW1xcL1xcc10/KFtcXHdcXC5dKykvaV0sW1tnLFwiVUNCcm93c2VyXCJdLG1dLFsvKGRvbGZpbilcXC8oW1xcd1xcLl0rKS9pXSxbW2csXCJEb2xwaGluXCJdLG1dLFsvKCg/OmFuZHJvaWQuKyljcm1vfGNyaW9zKVxcLyhbXFx3XFwuXSspL2ldLFtbZyxcIkNocm9tZVwiXSxtXSxbLztmYmF2XFwvKFtcXHdcXC5dKyk7L2ldLFttLFtnLFwiRmFjZWJvb2tcIl1dLFsvZnhpb3NcXC8oW1xcd1xcLi1dKykvaV0sW20sW2csXCJGaXJlZm94XCJdXSxbL3ZlcnNpb25cXC8oW1xcd1xcLl0rKS4rP21vYmlsZVxcL1xcdytcXHMoc2FmYXJpKS9pXSxbbSxbZyxcIk1vYmlsZSBTYWZhcmlcIl1dLFsvdmVyc2lvblxcLyhbXFx3XFwuXSspLis/KG1vYmlsZVxccz9zYWZhcml8c2FmYXJpKS9pXSxbbSxnXSxbL3dlYmtpdC4rPyhtb2JpbGVcXHM/c2FmYXJpfHNhZmFyaSkoXFwvW1xcd1xcLl0rKS9pXSxbZyxbbSxDLmFjLE8udGkuQmQudmVyc2lvbl1dLFsvKGtvbnF1ZXJvcilcXC8oW1xcd1xcLl0rKS9pLC8od2Via2l0fGtodG1sKVxcLyhbXFx3XFwuXSspL2ldLFtnLG1dLFsvKG5hdmlnYXRvcnxuZXRzY2FwZSlcXC8oW1xcd1xcLi1dKykvaV0sW1tnLFwiTmV0c2NhcGVcIl0sbV0sWy8oc3dpZnRmb3gpL2ksLyhpY2VkcmFnb258aWNld2Vhc2VsfGNhbWlub3xjaGltZXJhfGZlbm5lY3xtYWVtb1xcc2Jyb3dzZXJ8bWluaW1vfGNvbmtlcm9yKVtcXC9cXHNdPyhbXFx3XFwuXFwrXSspL2ksLyhmaXJlZm94fHNlYW1vbmtleXxrLW1lbGVvbnxpY2VjYXR8aWNlYXBlfGZpcmViaXJkfHBob2VuaXgpXFwvKFtcXHdcXC4tXSspL2ksLyhtb3ppbGxhKVxcLyhbXFx3XFwuXSspLitydlxcOi4rZ2Vja29cXC9cXGQrL2ksLyhwb2xhcmlzfGx5bnh8ZGlsbG98aWNhYnxkb3Jpc3xhbWF5YXx3M218bmV0c3VyZnxzbGVpcG5pcilbXFwvXFxzXT8oW1xcd1xcLl0rKS9pLC8obGlua3MpXFxzXFwoKFtcXHdcXC5dKykvaSwvKGdvYnJvd3NlcilcXC8/KFtcXHdcXC5dKykqL2ksLyhpY2VcXHM/YnJvd3NlcilcXC92PyhbXFx3XFwuX10rKS9pLC8obW9zYWljKVtcXC9cXHNdKFtcXHdcXC5dKykvaV0sW2csbV1dLEdkOltbLyg/OihhbWR8eCg/Oig/Ojg2fDY0KVtfLV0pP3x3b3d8d2luKTY0KVs7XFwpXS9pXSxbW3csXCJhbWQ2NFwiXV0sWy8oaWEzMig/PTspKS9pXSxbW3csay5QZF1dLFsvKCg/OmlbMzQ2XXx4KTg2KVs7XFwpXS9pXSxbW3csXCJpYTMyXCJdXSxbL3dpbmRvd3NcXHMoY2V8bW9iaWxlKTtcXHNwcGM7L2ldLFtbdyxcImFybVwiXV0sWy8oKD86cHBjfHBvd2VycGMpKD86NjQpPykoPzpcXHNtYWN8O3xcXCkpL2ldLFtbdywvb3dlci8sXCJcIixrLlBkXV0sWy8oc3VuNFxcdylbO1xcKV0vaV0sW1t3LFwic3BhcmNcIl1dLFsvKCg/OmF2cjMyfGlhNjQoPz07KSl8NjhrKD89XFwpKXxhcm0oPzo2NHwoPz12XFxkKzspKXwoPz1hdG1lbFxccylhdnJ8KD86aXJpeHxtaXBzfHNwYXJjKSg/OjY0KT8oPz07KXxwYS1yaXNjKS9pXSxbW3csay5QZF1dXSxGZDpbWy9cXCgoaXBhZHxwbGF5Ym9vayk7W1xcd1xcc1xcKTstXSsocmltfGFwcGxlKS9pXSxbZix5LFt2LGJdXSxbL2FwcGxlY29yZW1lZGlhXFwvW1xcd1xcLl0rIFxcKChpcGFkKS9dLFtmLFt5LFwiQXBwbGVcIl0sW3YsYl1dLFsvKGFwcGxlXFxzezAsMX10dikvaV0sW1tmLFwiQXBwbGUgVFZcIl0sW3ksXCJBcHBsZVwiXV0sWy8oYXJjaG9zKVxccyhnYW1lcGFkMj8pL2ksLyhocCkuKyh0b3VjaHBhZCkvaSwvKGhwKS4rKHRhYmxldCkvaSwvKGtpbmRsZSlcXC8oW1xcd1xcLl0rKS9pLC9cXHMobm9vaylbXFx3XFxzXStidWlsZFxcLyhcXHcrKS9pLC8oZGVsbClcXHMoc3RyZWFba3ByXFxzXFxkXSpbXFxka29dKS9pXSxbeSxmLFt2LGJdXSxbLyhrZltBLXpdKylcXHNidWlsZFxcL1tcXHdcXC5dKy4qc2lsa1xcLy9pXSxbZixbeSxcIkFtYXpvblwiXSxbdixiXV0sWy8oc2R8a2YpWzAzNDloaWpvcnN0dXddK1xcc2J1aWxkXFwvW1xcd1xcLl0rLipzaWxrXFwvL2ldLFtbZixDLmFjLE8uRmQuX2QuRGRdLFt5LFwiQW1hem9uXCJdLFt2LFNdXSxbL1xcKChpcFtob25lZHxcXHNcXHcqXSspOy4rKGFwcGxlKS9pXSxbZix5LFt2LFNdXSxbL1xcKChpcFtob25lZHxcXHNcXHcqXSspOy9pXSxbZixbeSxcIkFwcGxlXCJdLFt2LFNdXSxbLyhibGFja2JlcnJ5KVtcXHMtXT8oXFx3KykvaSwvKGJsYWNrYmVycnl8YmVucXxwYWxtKD89XFwtKXxzb255ZXJpY3Nzb258YWNlcnxhc3VzfGRlbGx8aHVhd2VpfG1laXp1fG1vdG9yb2xhfHBvbHl0cm9uKVtcXHNfLV0/KFtcXHctXSspKi9pLC8oaHApXFxzKFtcXHdcXHNdK1xcdykvaSwvKGFzdXMpLT8oXFx3KykvaV0sW3ksZixbdixTXV0sWy9cXChiYjEwO1xccyhcXHcrKS9pXSxbZixbeSxcIkJsYWNrQmVycnlcIl0sW3YsU11dLFsvYW5kcm9pZC4rKHRyYW5zZm9bcHJpbWVcXHNdezQsMTB9XFxzXFx3K3xlZWVwY3xzbGlkZXJcXHNcXHcrfG5leHVzIDd8cGFkZm9uZSkvaV0sW2YsW3ksXCJBc3VzXCJdLFt2LGJdXSxbLyhzb255KVxccyh0YWJsZXRcXHNbcHNdKVxcc2J1aWxkXFwvL2ksLyhzb255KT8oPzpzZ3AuKylcXHNidWlsZFxcLy9pXSxbW3ksXCJTb255XCJdLFtmLFwiWHBlcmlhIFRhYmxldFwiXSxbdixiXV0sWy8oPzpzb255KT8oPzooPzooPzpjfGQpXFxkezR9KXwoPzpzb1stbF0uKykpXFxzYnVpbGRcXC8vaV0sW1t5LFwiU29ueVwiXSxbZixcIlhwZXJpYSBQaG9uZVwiXSxbdixTXV0sWy9cXHMob3V5YSlcXHMvaSwvKG5pbnRlbmRvKVxccyhbd2lkczN1XSspL2ldLFt5LGYsW3YsVF1dLFsvYW5kcm9pZC4rO1xccyhzaGllbGQpXFxzYnVpbGQvaV0sW2YsW3ksXCJOdmlkaWFcIl0sW3YsVF1dLFsvKHBsYXlzdGF0aW9uXFxzWzM0cG9ydGFibGV2aV0rKS9pXSxbZixbeSxcIlNvbnlcIl0sW3YsVF1dLFsvKHNwcmludFxccyhcXHcrKSkvaV0sW1t5LEMuYWMsTy5GZC5MZC52ZW5kb3JdLFtmLEMuYWMsTy5GZC5MZC5EZF0sW3YsU11dLFsvKGxlbm92bylcXHM/KFMoPzo1MDAwfDYwMDApKyg/OlstXVtcXHcrXSkpL2ldLFt5LGYsW3YsYl1dLFsvKGh0YylbO19cXHMtXSsoW1xcd1xcc10rKD89XFwpKXxcXHcrKSovaSwvKHp0ZSktKFxcdyspKi9pLC8oYWxjYXRlbHxnZWVrc3Bob25lfGh1YXdlaXxsZW5vdm98bmV4aWFufHBhbmFzb25pY3woPz07XFxzKXNvbnkpW19cXHMtXT8oW1xcdy1dKykqL2ldLFt5LFtmLC9fL2csXCIgXCJdLFt2LFNdXSxbLyhuZXh1c1xcczkpL2ldLFtmLFt5LFwiSFRDXCJdLFt2LGJdXSxbLyhuZXh1c1xcczZwKS9pXSxbZixbeSxcIkh1YXdlaVwiXSxbdixTXV0sWy8obWljcm9zb2Z0KTtcXHMobHVtaWFbXFxzXFx3XSspL2ldLFt5LGYsW3YsU11dLFsvW1xcc1xcKDtdKHhib3goPzpcXHNvbmUpPylbXFxzXFwpO10vaV0sW2YsW3ksXCJNaWNyb3NvZnRcIl0sW3YsVF1dLFsvKGtpblxcLltvbmV0d117M30pL2ldLFtbZiwvXFwuL2csXCIgXCJdLFt5LFwiTWljcm9zb2Z0XCJdLFt2LFNdXSxbL1xccyhtaWxlc3RvbmV8ZHJvaWQoPzpbMi00eF18XFxzKD86YmlvbmljfHgyfHByb3xyYXpyKSk/KDo/XFxzNGcpPylbXFx3XFxzXStidWlsZFxcLy9pLC9tb3RbXFxzLV0/KFxcdyspKi9pLC8oWFRcXGR7Myw0fSkgYnVpbGRcXC8vaSwvKG5leHVzXFxzNikvaV0sW2YsW3ksXCJNb3Rvcm9sYVwiXSxbdixTXV0sWy9hbmRyb2lkLitcXHMobXo2MFxcZHx4b29tW1xcczJdezAsMn0pXFxzYnVpbGRcXC8vaV0sW2YsW3ksXCJNb3Rvcm9sYVwiXSxbdixiXV0sWy9oYmJ0dlxcL1xcZCtcXC5cXGQrXFwuXFxkK1xccytcXChbXFx3XFxzXSo7XFxzKihcXHdbXjtdKik7KFteO10qKS9pXSxbW3ksay50cmltXSxbZixrLnRyaW1dLFt2LEVdXSxbL2hiYnR2LittYXBsZTsoXFxkKykvaV0sW1tmLC9eLyxcIlNtYXJ0VFZcIl0sW3ksXCJTYW1zdW5nXCJdLFt2LEVdXSxbL1xcKGR0dltcXCk7XS4rKGFxdW9zKS9pXSxbZixbeSxcIlNoYXJwXCJdLFt2LEVdXSxbL2FuZHJvaWQuKygoc2NoLWlbODldMFxcZHxzaHctbTM4MHN8Z3QtcFxcZHs0fXxndC1uXFxkK3xzZ2gtdDhbNTZdOXxuZXh1cyAxMCkpL2ksLygoU00tVFxcdyspKS9pXSxbW3ksXCJTYW1zdW5nXCJdLGYsW3YsYl1dLFsvc21hcnQtdHYuKyhzYW1zdW5nKS9pXSxbeSxbdixFXSxmXSxbLygoc1tjZ3BdaC1cXHcrfGd0LVxcdyt8Z2FsYXh5XFxzbmV4dXN8c20tXFx3W1xcd1xcZF0rKSkvaSwvKHNhbVtzdW5nXSopW1xccy1dKihcXHcrLT9bXFx3LV0qKSovaSwvc2VjLSgoc2doXFx3KykpL2ldLFtbeSxcIlNhbXN1bmdcIl0sZixbdixTXV0sWy9zaWUtKFxcdyspKi9pXSxbZixbeSxcIlNpZW1lbnNcIl0sW3YsU11dLFsvKG1hZW1vfG5va2lhKS4qKG45MDB8bHVtaWFcXHNcXGQrKS9pLC8obm9raWEpW1xcc18tXT8oW1xcdy1dKykqL2ldLFtbeSxcIk5va2lhXCJdLGYsW3YsU11dLFsvYW5kcm9pZFxcczNcXC5bXFxzXFx3Oy1dezEwfShhXFxkezN9KS9pXSxbZixbeSxcIkFjZXJcIl0sW3YsYl1dLFsvYW5kcm9pZFxcczNcXC5bXFxzXFx3Oy1dezEwfShsZz8pLShbMDZjdjldezMsNH0pL2ldLFtbeSxcIkxHXCJdLGYsW3YsYl1dLFsvKGxnKSBuZXRjYXN0XFwudHYvaV0sW3ksZixbdixFXV0sWy8obmV4dXNcXHNbNDVdKS9pLC9sZ1tlO1xcc1xcLy1dKyhcXHcrKSovaV0sW2YsW3ksXCJMR1wiXSxbdixTXV0sWy9hbmRyb2lkLisoaWRlYXRhYlthLXowLTlcXC1cXHNdKykvaV0sW2YsW3ksXCJMZW5vdm9cIl0sW3YsYl1dLFsvbGludXg7LisoKGpvbGxhKSk7L2ldLFt5LGYsW3YsU11dLFsvKChwZWJibGUpKWFwcFxcL1tcXGRcXC5dK1xccy9pXSxbeSxmLFt2LEldXSxbL2FuZHJvaWQuKztcXHMoZ2xhc3MpXFxzXFxkL2ldLFtmLFt5LFwiR29vZ2xlXCJdLFt2LEldXSxbL2FuZHJvaWQuKyhcXHcrKVxccytidWlsZFxcL2htXFwxL2ksL2FuZHJvaWQuKyhobVtcXHNcXC1fXSpub3RlP1tcXHNfXSooPzpcXGRcXHcpPylcXHMrYnVpbGQvaSwvYW5kcm9pZC4rKG1pW1xcc1xcLV9dKig/Om9uZXxvbmVbXFxzX11wbHVzfG5vdGUgbHRlKT9bXFxzX10qKD86XFxkXFx3KT8pXFxzK2J1aWxkL2ldLFtbZiwvXy9nLFwiIFwiXSxbeSxcIlhpYW9taVwiXSxbdixTXV0sWy9hbmRyb2lkLithMDAwKDEpXFxzK2J1aWxkL2ldLFtmLFt5LFwiT25lUGx1c1wiXSxbdixTXV0sWy9cXHModGFibGV0KVs7XFwvXS9pLC9cXHMobW9iaWxlKSg/Ols7XFwvXXxcXHNzYWZhcmkpL2ldLFtbdixrLlBkXSx5LGZdXSx6ZDpbWy93aW5kb3dzLitcXHNlZGdlXFwvKFtcXHdcXC5dKykvaV0sW20sW2csXCJFZGdlSFRNTFwiXV0sWy8ocHJlc3RvKVxcLyhbXFx3XFwuXSspL2ksLyh3ZWJraXR8dHJpZGVudHxuZXRmcm9udHxuZXRzdXJmfGFtYXlhfGx5bnh8dzNtKVxcLyhbXFx3XFwuXSspL2ksLyhraHRtbHx0YXNtYW58bGlua3MpW1xcL1xcc11cXCg/KFtcXHdcXC5dKykvaSwvKGljYWIpW1xcL1xcc10oWzIzXVxcLltcXGRcXC5dKykvaV0sW2csbV0sWy9ydlxcOihbXFx3XFwuXSspLiooZ2Vja28pL2ldLFttLGddXSxvczpbWy9taWNyb3NvZnRcXHMod2luZG93cylcXHModmlzdGF8eHApL2ldLFtnLG1dLFsvKHdpbmRvd3MpXFxzbnRcXHM2XFwuMjtcXHMoYXJtKS9pLC8od2luZG93c1xcc3Bob25lKD86XFxzb3MpKilbXFxzXFwvXT8oW1xcZFxcLlxcc10rXFx3KSovaSwvKHdpbmRvd3NcXHNtb2JpbGV8d2luZG93cylbXFxzXFwvXT8oW250Y2VcXGRcXC5cXHNdK1xcdykvaV0sW2csW20sQy5hYyxPLm9zLlZkLnZlcnNpb25dXSxbLyh3aW4oPz0zfDl8bil8d2luXFxzOXhcXHMpKFtudFxcZFxcLl0rKS9pXSxbW2csXCJXaW5kb3dzXCJdLFttLEMuYWMsTy5vcy5WZC52ZXJzaW9uXV0sWy9cXCgoYmIpKDEwKTsvaV0sW1tnLFwiQmxhY2tCZXJyeVwiXSxtXSxbLyhibGFja2JlcnJ5KVxcdypcXC8/KFtcXHdcXC5dKykqL2ksLyh0aXplbilbXFwvXFxzXShbXFx3XFwuXSspL2ksLyhhbmRyb2lkfHdlYm9zfHBhbG1cXHNvc3xxbnh8YmFkYXxyaW1cXHN0YWJsZXRcXHNvc3xtZWVnb3xjb250aWtpKVtcXC9cXHMtXT8oW1xcd1xcLl0rKSovaSwvbGludXg7Lisoc2FpbGZpc2gpOy9pXSxbZyxtXSxbLyhzeW1iaWFuXFxzP29zfHN5bWJvc3xzNjAoPz07KSlbXFwvXFxzLV0/KFtcXHdcXC5dKykqL2ldLFtbZyxcIlN5bWJpYW5cIl0sbV0sWy9cXCgoc2VyaWVzNDApOy9pXSxbZ10sWy9tb3ppbGxhLitcXChtb2JpbGU7LitnZWNrby4rZmlyZWZveC9pXSxbW2csXCJGaXJlZm94IE9TXCJdLG1dLFsvKG5pbnRlbmRvfHBsYXlzdGF0aW9uKVxccyhbd2lkczM0cG9ydGFibGV2dV0rKS9pLC8obWludClbXFwvXFxzXFwoXT8oXFx3KykqL2ksLyhtYWdlaWF8dmVjdG9ybGludXgpWztcXHNdL2ksLyhqb2xpfFtreGxuXT91YnVudHV8ZGViaWFufFtvcGVuXSpzdXNlfGdlbnRvb3woPz1cXHMpYXJjaHxzbGFja3dhcmV8ZmVkb3JhfG1hbmRyaXZhfGNlbnRvc3xwY2xpbnV4b3N8cmVkaGF0fHplbndhbGt8bGlucHVzKVtcXC9cXHMtXT8oPyFjaHJvbSkoW1xcd1xcLi1dKykqL2ksLyhodXJkfGxpbnV4KVxccz8oW1xcd1xcLl0rKSovaSwvKGdudSlcXHM/KFtcXHdcXC5dKykqL2ldLFtnLG1dLFsvKGNyb3MpXFxzW1xcd10rXFxzKFtcXHdcXC5dK1xcdykvaV0sW1tnLFwiQ2hyb21pdW0gT1NcIl0sbV0sWy8oc3Vub3MpXFxzPyhbXFx3XFwuXStcXGQpKi9pXSxbW2csXCJTb2xhcmlzXCJdLG1dLFsvXFxzKFtmcmVudG9wYy1dezAsNH1ic2R8ZHJhZ29uZmx5KVxccz8oW1xcd1xcLl0rKSovaV0sW2csbV0sWy8oaGFpa3UpXFxzKFxcdyspL2ldLFtnLG1dLFsvKGlwW2hvbmVhZF0rKSg/Oi4qb3NcXHMoW1xcd10rKSpcXHNsaWtlXFxzbWFjfDtcXHNvcGVyYSkvaV0sW1tnLFwiaU9TXCJdLFttLC9fL2csXCIuXCJdXSxbLyhtYWNcXHNvc1xcc3gpXFxzPyhbXFx3XFxzXFwuXStcXHcpKi9pLC8obWFjaW50b3NofG1hYyg/PV9wb3dlcnBjKVxccykvaV0sW1tnLFwiTWFjIE9TXCJdLFttLC9fL2csXCIuXCJdXSxbLygoPzpvcGVuKT9zb2xhcmlzKVtcXC9cXHMtXT8oW1xcd1xcLl0rKSovaSwvKGFpeClcXHMoKFxcZCkoPz1cXC58XFwpfFxccylbXFx3XFwuXSopKi9pLC8ocGxhblxcczl8bWluaXh8YmVvc3xvc1xcLzJ8YW1pZ2Fvc3xtb3JwaG9zfHJpc2NcXHNvc3xvcGVudm1zKS9pLC8odW5peClcXHM/KFtcXHdcXC5dKykqL2ldLFtnLG1dXX0sQT1mdW5jdGlvbih0LGUpe2lmKCEodGhpcyBpbnN0YW5jZW9mIEEpKXJldHVybiBuZXcgQSh0LGUpLldkKCk7dmFyIGk9dHx8KG4mJm4ubmF2aWdhdG9yJiZuLm5hdmlnYXRvci51c2VyQWdlbnQ/bi5uYXZpZ2F0b3IudXNlckFnZW50OmEpLHI9ZT9rLmV4dGVuZChQLGUpOlA7cmV0dXJuIHRoaXMuJGQ9ZnVuY3Rpb24oKXt2YXIgdD1DLk5kLmFwcGx5KHRoaXMsci50aSk7cmV0dXJuIHQuQWQ9ay5BZCh0LnZlcnNpb24pLHR9LHRoaXMuWWQ9ZnVuY3Rpb24oKXtyZXR1cm4gQy5OZC5hcHBseSh0aGlzLHIuR2QpfSx0aGlzLlhkPWZ1bmN0aW9uKCl7cmV0dXJuIEMuTmQuYXBwbHkodGhpcyxyLkZkKX0sdGhpcy5aZD1mdW5jdGlvbigpe3JldHVybiBDLk5kLmFwcGx5KHRoaXMsci56ZCl9LHRoaXMuUm49ZnVuY3Rpb24oKXtyZXR1cm4gQy5OZC5hcHBseSh0aGlzLHIub3MpfSx0aGlzLldkPWZ1bmN0aW9uKCl7cmV0dXJue3RmOnRoaXMueGQoKSx0aTp0aGlzLiRkKCksemQ6dGhpcy5aZCgpLG9zOnRoaXMuUm4oKSxGZDp0aGlzLlhkKCksR2Q6dGhpcy5ZZCgpfX0sdGhpcy54ZD1mdW5jdGlvbigpe3JldHVybiBpfSx0aGlzLkluPWZ1bmN0aW9uKHQpe3JldHVybiBpPXQsdGhpc30sdGhpc307QS5WRVJTSU9OPXMsQS5lZj17XCJpZlwiOmcscmY6ZCxWRVJTSU9OOm19LEEubmY9e3NmOnd9LEEuYWY9e2NmOmYsVkVORE9SOnksaGY6dixwZjpULHVmOlMsbGY6RSxkZjpiLGZmOkksZ2Y6Un0sQS52Zj17XCJpZlwiOmcsVkVSU0lPTjptfSxBLnlmPXtcImlmXCI6ZyxWRVJTSU9OOm19LHR5cGVvZiBlIT09cD8odHlwZW9mIHQhPT1wJiZ0LnQmJihlPXQudD1BKSxlLkNyPUEpOlwiZnVuY3Rpb25cIj09PWgmJmkoNjQpPyhyPWZ1bmN0aW9uKCl7cmV0dXJuIEF9LmNhbGwoZSxpLGUsdCksIShyIT09byYmKHQudD1yKSkpOm4uQ3I9QTt2YXIgTj1uLmpRdWVyeXx8bi5aZXB0bztpZih0eXBlb2YgTiE9PXApe3ZhciB4PW5ldyBBO04udGY9eC5XZCgpLE4udGYuZ2V0PWZ1bmN0aW9uKCl7cmV0dXJuIHgueGQoKX0sTi50Zi5zZXQ9ZnVuY3Rpb24odCl7eC5Jbih0KTt2YXIgZT14LldkKCk7Zm9yKHZhciBpIGluIGUpTi50ZltpXT1lW2ldfX19KFwib2JqZWN0XCI9PXR5cGVvZiB3aW5kb3c/d2luZG93OnRoaXMpfSxmdW5jdGlvbih0LGUpe1NlcnZpY2VzPXsxOlwiUkVNT1RFX0VYRUNVVE9SXCIsbWY6MSwyOlwiUEVFUl9GT1JXQVJERVJcIix3ZjoyLDM6XCJQRUVSX0lOREVYXCIsVGY6Myw0OlwiUEVFUl9CUk9BRENBU1RcIixTZjo0LDU6XCJQRUVSX0ZJTFRFUlwiLGJmOjUsNjpcIlBFRVJfTE9HR0lOR1wiLEVmOjYsNzpcIkhJVkVKU19UUkFDS0VSXCIsSWY6Nyw4OlwiUEVFUl9TWVNURU1cIixSZjo4LDk6XCJISVZFSlNfU05BUFNIT1RTXCIsdG86OSwxMDpcIkhJVkVKU19USUNLRVRTXCIsa2Y6MTAsMTE6XCJISVZFSlNfS0VFUEFMSVZFXCIsQ2Y6MTEsMTI6XCJISVZFSlNfRk9SV0FSRElOR1wiLE9mOjEyfX0sZnVuY3Rpb24odCxlLGkpe3ZhciByPWkoMTYpO1N0cmVhbVR5cGU9ezE6XCJMSVZFXCIsTElWRToxLDI6XCJWT0RcIixQZjoyfSxTdHJlYW1Qcm90b2NvbD17MTpcIkRBU0hcIixydDoxLDI6XCJIRFNcIixBZjoyLDM6XCJITFNcIixZOjMsNDpcIlNTXCIsTmY6NH0sQ2xpZW50VHlwZT17MTpcIkpBVkFcIix4ZjoxLDI6XCJTVEFUU19PTkxZXCIsQmY6MiwzOlwiSlNfRElSRUNUXCIsRmY6Myw0OlwiSlNfUFJPWFlcIixfZjo0fSxFdmVudElkPWZ1bmN0aW9uKHQpe3RoaXMucGFydG5lcklkPW51bGwsdGhpcy5jdXN0b21lcklkPW51bGwsdGhpcy5jb250ZW50SWQ9bnVsbCx0aGlzLnRhZ3M9bnVsbCx0JiYodm9pZCAwIT09dC5wYXJ0bmVySWQmJih0aGlzLnBhcnRuZXJJZD10LnBhcnRuZXJJZCksdm9pZCAwIT09dC5jdXN0b21lcklkJiYodGhpcy5jdXN0b21lcklkPXQuY3VzdG9tZXJJZCksdm9pZCAwIT09dC5jb250ZW50SWQmJih0aGlzLmNvbnRlbnRJZD10LmNvbnRlbnRJZCksdm9pZCAwIT09dC50YWdzJiYodGhpcy50YWdzPXQudGFncykpfSxFdmVudElkLnByb3RvdHlwZT17fSxFdmVudElkLnByb3RvdHlwZS5yZWFkPWZ1bmN0aW9uKHQpe2Zvcih0LkhjKCk7Oyl7dmFyIGU9dC5zYSgpLGk9KGUuQmMsZS5hYSksbj1lLmNhO2lmKGk9PXIuYnMuRXMpYnJlYWs7c3dpdGNoKG4pe2Nhc2UgMTppPT1yLmJzLkFzP3RoaXMucGFydG5lcklkPXQuaGEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjppPT1yLmJzLkFzP3RoaXMuY3VzdG9tZXJJZD10LmhhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM6aT09ci5icy5Bcz90aGlzLmNvbnRlbnRJZD10LmhhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDQ6aWYoaT09ci5icy5fcyl7dmFyIG8scz0wO3RoaXMudGFncz1bXTt2YXIgYT0wO289dC5WYygpLGE9by5RYyxzPW8uc2l6ZTtmb3IodmFyIGM9MDtjPHM7KytjKXt2YXIgaD1udWxsO2g9dC5oYSgpLnZhbHVlLHRoaXMudGFncy5wdXNoKGgpfXQucWMoKX1lbHNlIHQucGEoaSk7YnJlYWs7ZGVmYXVsdDp0LnBhKGkpfXQubGEoKX10LmRhKCl9LEV2ZW50SWQucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKHQpe2lmKHQuZmEoXCJFdmVudElkXCIpLG51bGwhPT10aGlzLnBhcnRuZXJJZCYmdm9pZCAwIT09dGhpcy5wYXJ0bmVySWQmJih0LmdhKFwicGFydG5lcklkXCIsci5icy5BcywxKSx0LnZhKHRoaXMucGFydG5lcklkKSx0LnlhKCkpLG51bGwhPT10aGlzLmN1c3RvbWVySWQmJnZvaWQgMCE9PXRoaXMuY3VzdG9tZXJJZCYmKHQuZ2EoXCJjdXN0b21lcklkXCIsci5icy5BcywyKSx0LnZhKHRoaXMuY3VzdG9tZXJJZCksdC55YSgpKSxudWxsIT09dGhpcy5jb250ZW50SWQmJnZvaWQgMCE9PXRoaXMuY29udGVudElkJiYodC5nYShcImNvbnRlbnRJZFwiLHIuYnMuQXMsMyksdC52YSh0aGlzLmNvbnRlbnRJZCksdC55YSgpKSxudWxsIT09dGhpcy50YWdzJiZ2b2lkIDAhPT10aGlzLnRhZ3Mpe3QuZ2EoXCJ0YWdzXCIsci5icy5fcyw0KSx0LlRjKHIuYnMuQXMsdGhpcy50YWdzLmxlbmd0aCk7Zm9yKHZhciBlIGluIHRoaXMudGFncyl0aGlzLnRhZ3MuaGFzT3duUHJvcGVydHkoZSkmJihlPXRoaXMudGFnc1tlXSx0LnZhKGUpKTt0LlNjKCksdC55YSgpfXQud2EoKSx0LlRhKCl9LFNuYXBzaG90SW5mbz1mdW5jdGlvbih0KXt0aGlzLnRpbWVzdGFtcD1udWxsLHRoaXMuYXBpU2VydmVyPW51bGwsdGhpcy5jbGllbnRJcD1udWxsLHQmJih2b2lkIDAhPT10LnRpbWVzdGFtcCYmKHRoaXMudGltZXN0YW1wPXQudGltZXN0YW1wKSx2b2lkIDAhPT10LmFwaVNlcnZlciYmKHRoaXMuYXBpU2VydmVyPXQuYXBpU2VydmVyKSx2b2lkIDAhPT10LmNsaWVudElwJiYodGhpcy5jbGllbnRJcD10LmNsaWVudElwKSl9LFNuYXBzaG90SW5mby5wcm90b3R5cGU9e30sU25hcHNob3RJbmZvLnByb3RvdHlwZS5yZWFkPWZ1bmN0aW9uKHQpe2Zvcih0LkhjKCk7Oyl7dmFyIGU9dC5zYSgpLGk9KGUuQmMsZS5hYSksbj1lLmNhO2lmKGk9PXIuYnMuRXMpYnJlYWs7c3dpdGNoKG4pe2Nhc2UgMTppPT1yLmJzLlBzP3RoaXMudGltZXN0YW1wPXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjppPT1yLmJzLkFzP3RoaXMuYXBpU2VydmVyPXQuaGEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzppPT1yLmJzLkFzP3RoaXMuY2xpZW50SXA9dC5oYSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7ZGVmYXVsdDp0LnBhKGkpfXQubGEoKX10LmRhKCl9LFNuYXBzaG90SW5mby5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24odCl7dC5mYShcIlNuYXBzaG90SW5mb1wiKSxudWxsIT09dGhpcy50aW1lc3RhbXAmJnZvaWQgMCE9PXRoaXMudGltZXN0YW1wJiYodC5nYShcInRpbWVzdGFtcFwiLHIuYnMuUHMsMSksdC5DYyh0aGlzLnRpbWVzdGFtcCksdC55YSgpKSxudWxsIT09dGhpcy5hcGlTZXJ2ZXImJnZvaWQgMCE9PXRoaXMuYXBpU2VydmVyJiYodC5nYShcImFwaVNlcnZlclwiLHIuYnMuQXMsMiksdC52YSh0aGlzLmFwaVNlcnZlciksdC55YSgpKSxudWxsIT09dGhpcy5jbGllbnRJcCYmdm9pZCAwIT09dGhpcy5jbGllbnRJcCYmKHQuZ2EoXCJjbGllbnRJcFwiLHIuYnMuQXMsMyksdC52YSh0aGlzLmNsaWVudElwKSx0LnlhKCkpLHQud2EoKSx0LlRhKCl9LEluZXRBZGRyZXNzPWZ1bmN0aW9uKHQpe3RoaXMuYWRkcmVzcz1udWxsLHRoaXMucG9ydD1udWxsLHQmJih2b2lkIDAhPT10LmFkZHJlc3MmJih0aGlzLmFkZHJlc3M9dC5hZGRyZXNzKSx2b2lkIDAhPT10LnBvcnQmJih0aGlzLnBvcnQ9dC5wb3J0KSl9LEluZXRBZGRyZXNzLnByb3RvdHlwZT17fSxJbmV0QWRkcmVzcy5wcm90b3R5cGUucmVhZD1mdW5jdGlvbih0KXtmb3IodC5IYygpOzspe3ZhciBlPXQuc2EoKSxpPShlLkJjLGUuYWEpLG49ZS5jYTtpZihpPT1yLmJzLkVzKWJyZWFrO3N3aXRjaChuKXtjYXNlIDE6aT09ci5icy5Bcz90aGlzLmFkZHJlc3M9dC5YYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyOmk9PXIuYnMuT3M/dGhpcy5wb3J0PXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2RlZmF1bHQ6dC5wYShpKX10LmxhKCl9dC5kYSgpfSxJbmV0QWRkcmVzcy5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24odCl7dC5mYShcIkluZXRBZGRyZXNzXCIpLG51bGwhPT10aGlzLmFkZHJlc3MmJnZvaWQgMCE9PXRoaXMuYWRkcmVzcyYmKHQuZ2EoXCJhZGRyZXNzXCIsci5icy5BcywxKSx0LlBjKHRoaXMuYWRkcmVzcyksdC55YSgpKSxudWxsIT09dGhpcy5wb3J0JiZ2b2lkIDAhPT10aGlzLnBvcnQmJih0LmdhKFwicG9ydFwiLHIuYnMuT3MsMiksdC5tYSh0aGlzLnBvcnQpLHQueWEoKSksdC53YSgpLHQuVGEoKX19LGZ1bmN0aW9uKHQsZSxpKXt2YXIgcj1pKDE2KTtcInVuZGVmaW5lZFwiPT10eXBlb2YgaGl2ZSYmKGhpdmU9e30pLFwidW5kZWZpbmVkXCI9PXR5cGVvZiBoaXZlLnNuYXBzaG90cyYmKGhpdmUuc25hcHNob3RzPXt9KSxoaXZlLnNuYXBzaG90cy5UcmFmZmljPWZ1bmN0aW9uKHQpe3RoaXMucmVxTj1udWxsLHRoaXMucmVzcEZhbGxiYWNrTj1udWxsLHRoaXMucmVzcEZhbGxiYWNrRXJyTj1udWxsLHRoaXMucmVzcFAycE49bnVsbCx0aGlzLnJlcU90aGVyTj1udWxsLHRoaXMucmVzcEZhbGxiYWNrT3RoZXJOPW51bGwsdGhpcy5yZXNwRmFsbGJhY2tPdGhlcnRFcnJOPW51bGwsdGhpcy5zcmNSZXFOPW51bGwsdGhpcy5zcmNSZXNwTj1udWxsLHRoaXMuc3JjUmVzcEVyck49bnVsbCx0aGlzLnNyY1JlcVF0PW51bGwsdGhpcy5zcmNSZXNwUXQ9bnVsbCx0aGlzLnNyY092ZXJRdD1udWxsLHRoaXMuc3JjT3RoZXJSZXFOPW51bGwsdGhpcy5zcmNPdGhlclJlc3BOPW51bGwsdGhpcy5zcmNPdGhlclJlc3BFcnJOPW51bGwsdGhpcy5zcmNPdGhlclJlcVF0PW51bGwsdGhpcy5zcmNPdGhlclJlc3BRdD1udWxsLHRoaXMuc3JjT3RoZXJPdmVyUXQ9bnVsbCx0aGlzLnAycFN1YlJlcU49bnVsbCx0aGlzLnAycFN1YlJlc3BOPW51bGwsdGhpcy5wMnBTdWJSZXNwUGFydE49bnVsbCx0aGlzLnAycFN1YlJlc3BFcnJOPW51bGwsdGhpcy5wMnBTdWJSZXNwRXhwTj1udWxsLHRoaXMucDJwU3ViUmVxUXQ9bnVsbCx0aGlzLnAycFN1YlJlc3BRdD1udWxsLHRoaXMucDJwRGlyZWN0UXQ9bnVsbCx0aGlzLnAycFJlbGF5UXQ9bnVsbCx0aGlzLnAycE5hdFF0PW51bGwsdGhpcy5wMnBVZHBiUXQ9bnVsbCx0aGlzLmZhbGxBZ2VudFJlc3BOPW51bGwsdGhpcy5mYWxsQWdlbnRQcmVkSGl0Tj1udWxsLHRoaXMuZmFsbEFnZW50RmFpbGVkUmVzcE49bnVsbCx0aGlzLmZhbGxBZ2VudFByZWRNaXNzTj1udWxsLHRoaXMuZmFsbEFnZW50UHJlZFBhcnRpYWxIaXROPW51bGwsdGhpcy5mYWxsQWdlblRyYWZmaWNTdWNjZXNzUXQ9bnVsbCx0aGlzLmZhbGxBZ2VuVHJhZmZpY0ZhaWx1cmVRdD1udWxsLHRoaXMucDJwQWdlbnRQcmVkSGl0Tj1udWxsLHRoaXMucDJwQWdlbnRQcmVkTWlzc049bnVsbCx0aGlzLnAycEFnZW50UHJlZFBhcnRpYWxIaXROPW51bGwsdGhpcy5wMnBBZ2VuVHJhZmZpY1N1Y2Nlc3NRdD1udWxsLHRoaXMucDJwQWdlblRyYWZmaWNGYWlsdXJlUXQ9bnVsbCx0aGlzLnJlc3BQMnBPdGhlck49bnVsbCx0aGlzLmxDYWNoZVJlc3BOPW51bGwsdGhpcy5sQ2FjaGVSZXNwUXQ9bnVsbCx0aGlzLnAycE91dFNpdGVMb3dQcmlvPW51bGwsdCYmKHZvaWQgMCE9PXQucmVxTiYmKHRoaXMucmVxTj10LnJlcU4pLHZvaWQgMCE9PXQucmVzcEZhbGxiYWNrTiYmKHRoaXMucmVzcEZhbGxiYWNrTj10LnJlc3BGYWxsYmFja04pLHZvaWQgMCE9PXQucmVzcEZhbGxiYWNrRXJyTiYmKHRoaXMucmVzcEZhbGxiYWNrRXJyTj10LnJlc3BGYWxsYmFja0Vyck4pLHZvaWQgMCE9PXQucmVzcFAycE4mJih0aGlzLnJlc3BQMnBOPXQucmVzcFAycE4pLHZvaWQgMCE9PXQucmVxT3RoZXJOJiYodGhpcy5yZXFPdGhlck49dC5yZXFPdGhlck4pLHZvaWQgMCE9PXQucmVzcEZhbGxiYWNrT3RoZXJOJiYodGhpcy5yZXNwRmFsbGJhY2tPdGhlck49dC5yZXNwRmFsbGJhY2tPdGhlck4pLHZvaWQgMCE9PXQucmVzcEZhbGxiYWNrT3RoZXJ0RXJyTiYmKHRoaXMucmVzcEZhbGxiYWNrT3RoZXJ0RXJyTj10LnJlc3BGYWxsYmFja090aGVydEVyck4pLHZvaWQgMCE9PXQuc3JjUmVxTiYmKHRoaXMuc3JjUmVxTj10LnNyY1JlcU4pLHZvaWQgMCE9PXQuc3JjUmVzcE4mJih0aGlzLnNyY1Jlc3BOPXQuc3JjUmVzcE4pLHZvaWQgMCE9PXQuc3JjUmVzcEVyck4mJih0aGlzLnNyY1Jlc3BFcnJOPXQuc3JjUmVzcEVyck4pLHZvaWQgMCE9PXQuc3JjUmVxUXQmJih0aGlzLnNyY1JlcVF0PXQuc3JjUmVxUXQpLHZvaWQgMCE9PXQuc3JjUmVzcFF0JiYodGhpcy5zcmNSZXNwUXQ9dC5zcmNSZXNwUXQpLHZvaWQgMCE9PXQuc3JjT3ZlclF0JiYodGhpcy5zcmNPdmVyUXQ9dC5zcmNPdmVyUXQpLHZvaWQgMCE9PXQuc3JjT3RoZXJSZXFOJiYodGhpcy5zcmNPdGhlclJlcU49dC5zcmNPdGhlclJlcU4pLHZvaWQgMCE9PXQuc3JjT3RoZXJSZXNwTiYmKHRoaXMuc3JjT3RoZXJSZXNwTj10LnNyY090aGVyUmVzcE4pLHZvaWQgMCE9PXQuc3JjT3RoZXJSZXNwRXJyTiYmKHRoaXMuc3JjT3RoZXJSZXNwRXJyTj10LnNyY090aGVyUmVzcEVyck4pLHZvaWQgMCE9PXQuc3JjT3RoZXJSZXFRdCYmKHRoaXMuc3JjT3RoZXJSZXFRdD10LnNyY090aGVyUmVxUXQpLHZvaWQgMCE9PXQuc3JjT3RoZXJSZXNwUXQmJih0aGlzLnNyY090aGVyUmVzcFF0PXQuc3JjT3RoZXJSZXNwUXQpLHZvaWQgMCE9PXQuc3JjT3RoZXJPdmVyUXQmJih0aGlzLnNyY090aGVyT3ZlclF0PXQuc3JjT3RoZXJPdmVyUXQpLFxudm9pZCAwIT09dC5wMnBTdWJSZXFOJiYodGhpcy5wMnBTdWJSZXFOPXQucDJwU3ViUmVxTiksdm9pZCAwIT09dC5wMnBTdWJSZXNwTiYmKHRoaXMucDJwU3ViUmVzcE49dC5wMnBTdWJSZXNwTiksdm9pZCAwIT09dC5wMnBTdWJSZXNwUGFydE4mJih0aGlzLnAycFN1YlJlc3BQYXJ0Tj10LnAycFN1YlJlc3BQYXJ0Tiksdm9pZCAwIT09dC5wMnBTdWJSZXNwRXJyTiYmKHRoaXMucDJwU3ViUmVzcEVyck49dC5wMnBTdWJSZXNwRXJyTiksdm9pZCAwIT09dC5wMnBTdWJSZXNwRXhwTiYmKHRoaXMucDJwU3ViUmVzcEV4cE49dC5wMnBTdWJSZXNwRXhwTiksdm9pZCAwIT09dC5wMnBTdWJSZXFRdCYmKHRoaXMucDJwU3ViUmVxUXQ9dC5wMnBTdWJSZXFRdCksdm9pZCAwIT09dC5wMnBTdWJSZXNwUXQmJih0aGlzLnAycFN1YlJlc3BRdD10LnAycFN1YlJlc3BRdCksdm9pZCAwIT09dC5wMnBEaXJlY3RRdCYmKHRoaXMucDJwRGlyZWN0UXQ9dC5wMnBEaXJlY3RRdCksdm9pZCAwIT09dC5wMnBSZWxheVF0JiYodGhpcy5wMnBSZWxheVF0PXQucDJwUmVsYXlRdCksdm9pZCAwIT09dC5wMnBOYXRRdCYmKHRoaXMucDJwTmF0UXQ9dC5wMnBOYXRRdCksdm9pZCAwIT09dC5wMnBVZHBiUXQmJih0aGlzLnAycFVkcGJRdD10LnAycFVkcGJRdCksdm9pZCAwIT09dC5mYWxsQWdlbnRSZXNwTiYmKHRoaXMuZmFsbEFnZW50UmVzcE49dC5mYWxsQWdlbnRSZXNwTiksdm9pZCAwIT09dC5mYWxsQWdlbnRQcmVkSGl0TiYmKHRoaXMuZmFsbEFnZW50UHJlZEhpdE49dC5mYWxsQWdlbnRQcmVkSGl0Tiksdm9pZCAwIT09dC5mYWxsQWdlbnRGYWlsZWRSZXNwTiYmKHRoaXMuZmFsbEFnZW50RmFpbGVkUmVzcE49dC5mYWxsQWdlbnRGYWlsZWRSZXNwTiksdm9pZCAwIT09dC5mYWxsQWdlbnRQcmVkTWlzc04mJih0aGlzLmZhbGxBZ2VudFByZWRNaXNzTj10LmZhbGxBZ2VudFByZWRNaXNzTiksdm9pZCAwIT09dC5mYWxsQWdlbnRQcmVkUGFydGlhbEhpdE4mJih0aGlzLmZhbGxBZ2VudFByZWRQYXJ0aWFsSGl0Tj10LmZhbGxBZ2VudFByZWRQYXJ0aWFsSGl0Tiksdm9pZCAwIT09dC5mYWxsQWdlblRyYWZmaWNTdWNjZXNzUXQmJih0aGlzLmZhbGxBZ2VuVHJhZmZpY1N1Y2Nlc3NRdD10LmZhbGxBZ2VuVHJhZmZpY1N1Y2Nlc3NRdCksdm9pZCAwIT09dC5mYWxsQWdlblRyYWZmaWNGYWlsdXJlUXQmJih0aGlzLmZhbGxBZ2VuVHJhZmZpY0ZhaWx1cmVRdD10LmZhbGxBZ2VuVHJhZmZpY0ZhaWx1cmVRdCksdm9pZCAwIT09dC5wMnBBZ2VudFByZWRIaXROJiYodGhpcy5wMnBBZ2VudFByZWRIaXROPXQucDJwQWdlbnRQcmVkSGl0Tiksdm9pZCAwIT09dC5wMnBBZ2VudFByZWRNaXNzTiYmKHRoaXMucDJwQWdlbnRQcmVkTWlzc049dC5wMnBBZ2VudFByZWRNaXNzTiksdm9pZCAwIT09dC5wMnBBZ2VudFByZWRQYXJ0aWFsSGl0TiYmKHRoaXMucDJwQWdlbnRQcmVkUGFydGlhbEhpdE49dC5wMnBBZ2VudFByZWRQYXJ0aWFsSGl0Tiksdm9pZCAwIT09dC5wMnBBZ2VuVHJhZmZpY1N1Y2Nlc3NRdCYmKHRoaXMucDJwQWdlblRyYWZmaWNTdWNjZXNzUXQ9dC5wMnBBZ2VuVHJhZmZpY1N1Y2Nlc3NRdCksdm9pZCAwIT09dC5wMnBBZ2VuVHJhZmZpY0ZhaWx1cmVRdCYmKHRoaXMucDJwQWdlblRyYWZmaWNGYWlsdXJlUXQ9dC5wMnBBZ2VuVHJhZmZpY0ZhaWx1cmVRdCksdm9pZCAwIT09dC5yZXNwUDJwT3RoZXJOJiYodGhpcy5yZXNwUDJwT3RoZXJOPXQucmVzcFAycE90aGVyTiksdm9pZCAwIT09dC5sQ2FjaGVSZXNwTiYmKHRoaXMubENhY2hlUmVzcE49dC5sQ2FjaGVSZXNwTiksdm9pZCAwIT09dC5sQ2FjaGVSZXNwUXQmJih0aGlzLmxDYWNoZVJlc3BRdD10LmxDYWNoZVJlc3BRdCksdm9pZCAwIT09dC5wMnBPdXRTaXRlTG93UHJpbyYmKHRoaXMucDJwT3V0U2l0ZUxvd1ByaW89dC5wMnBPdXRTaXRlTG93UHJpbykpfSxoaXZlLnNuYXBzaG90cy5UcmFmZmljLnByb3RvdHlwZT17fSxoaXZlLnNuYXBzaG90cy5UcmFmZmljLnByb3RvdHlwZS5yZWFkPWZ1bmN0aW9uKHQpe2Zvcih0LkhjKCk7Oyl7dmFyIGU9dC5zYSgpLGk9KGUuQmMsZS5hYSksbj1lLmNhO2lmKGk9PXIuYnMuRXMpYnJlYWs7c3dpdGNoKG4pe2Nhc2UgMTppPT1yLmJzLk9zP3RoaXMucmVxTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI6aT09ci5icy5rcz90aGlzLnJlc3BGYWxsYmFja049dC5ZYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzOmk9PXIuYnMuT3M/dGhpcy5yZXNwRmFsbGJhY2tFcnJOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNDppPT1yLmJzLmtzP3RoaXMucmVzcFAycE49dC5ZYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA1Omk9PXIuYnMuT3M/dGhpcy5yZXFPdGhlck49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA2Omk9PXIuYnMuT3M/dGhpcy5yZXNwRmFsbGJhY2tPdGhlck49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA3Omk9PXIuYnMuT3M/dGhpcy5yZXNwRmFsbGJhY2tPdGhlcnRFcnJOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgODppPT1yLmJzLk9zP3RoaXMuc3JjUmVxTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDk6aT09ci5icy5Pcz90aGlzLnNyY1Jlc3BOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTA6aT09ci5icy5Pcz90aGlzLnNyY1Jlc3BFcnJOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTE6aT09ci5icy5Qcz90aGlzLnNyY1JlcVF0PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTI6aT09ci5icy5Qcz90aGlzLnNyY1Jlc3BRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDEzOmk9PXIuYnMuUHM/dGhpcy5zcmNPdmVyUXQ9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAxNDppPT1yLmJzLk9zP3RoaXMuc3JjT3RoZXJSZXFOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTU6aT09ci5icy5Pcz90aGlzLnNyY090aGVyUmVzcE49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAxNjppPT1yLmJzLk9zP3RoaXMuc3JjT3RoZXJSZXNwRXJyTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDE3Omk9PXIuYnMuUHM/dGhpcy5zcmNPdGhlclJlcVF0PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTg6aT09ci5icy5Qcz90aGlzLnNyY090aGVyUmVzcFF0PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTk6aT09ci5icy5Qcz90aGlzLnNyY090aGVyT3ZlclF0PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjA6aT09ci5icy5Pcz90aGlzLnAycFN1YlJlcU49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyMTppPT1yLmJzLk9zP3RoaXMucDJwU3ViUmVzcE49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyMjppPT1yLmJzLmtzP3RoaXMucDJwU3ViUmVzcFBhcnROPXQuWWMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjM6aT09ci5icy5rcz90aGlzLnAycFN1YlJlc3BFcnJOPXQuWWMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjQ6aT09ci5icy5Pcz90aGlzLnAycFN1YlJlc3BFeHBOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjU6aT09ci5icy5Qcz90aGlzLnAycFN1YlJlcVF0PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjY6aT09ci5icy5Qcz90aGlzLnAycFN1YlJlc3BRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI3Omk9PXIuYnMuUHM/dGhpcy5wMnBEaXJlY3RRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI4Omk9PXIuYnMuUHM/dGhpcy5wMnBSZWxheVF0PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjk6aT09ci5icy5Qcz90aGlzLnAycE5hdFF0PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzA6aT09ci5icy5Qcz90aGlzLnAycFVkcGJRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDMxOmk9PXIuYnMuT3M/dGhpcy5mYWxsQWdlbnRSZXNwTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDMyOmk9PXIuYnMuT3M/dGhpcy5mYWxsQWdlbnRQcmVkSGl0Tj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDMzOmk9PXIuYnMuT3M/dGhpcy5mYWxsQWdlbnRGYWlsZWRSZXNwTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM0Omk9PXIuYnMuT3M/dGhpcy5mYWxsQWdlbnRQcmVkTWlzc049dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzNTppPT1yLmJzLk9zP3RoaXMuZmFsbEFnZW50UHJlZFBhcnRpYWxIaXROPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzY6aT09ci5icy5Qcz90aGlzLmZhbGxBZ2VuVHJhZmZpY1N1Y2Nlc3NRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM3Omk9PXIuYnMuUHM/dGhpcy5mYWxsQWdlblRyYWZmaWNGYWlsdXJlUXQ9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzODppPT1yLmJzLk9zP3RoaXMucDJwQWdlbnRQcmVkSGl0Tj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM5Omk9PXIuYnMuT3M/dGhpcy5wMnBBZ2VudFByZWRNaXNzTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDQwOmk9PXIuYnMuT3M/dGhpcy5wMnBBZ2VudFByZWRQYXJ0aWFsSGl0Tj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDQxOmk9PXIuYnMuUHM/dGhpcy5wMnBBZ2VuVHJhZmZpY1N1Y2Nlc3NRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDQyOmk9PXIuYnMuUHM/dGhpcy5wMnBBZ2VuVHJhZmZpY0ZhaWx1cmVRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDQzOmk9PXIuYnMuT3M/dGhpcy5yZXNwUDJwT3RoZXJOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNDQ6aT09ci5icy5Pcz90aGlzLmxDYWNoZVJlc3BOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNDU6aT09ci5icy5Qcz90aGlzLmxDYWNoZVJlc3BRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDQ2Omk9PXIuYnMuUHM/dGhpcy5wMnBPdXRTaXRlTG93UHJpbz10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztkZWZhdWx0OnQucGEoaSl9dC5sYSgpfXQuZGEoKX0saGl2ZS5zbmFwc2hvdHMuVHJhZmZpYy5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24odCl7dC5mYShcIlRyYWZmaWNcIiksbnVsbCE9PXRoaXMucmVxTiYmdm9pZCAwIT09dGhpcy5yZXFOJiYodC5nYShcInJlcU5cIixyLmJzLk9zLDEpLHQubWEodGhpcy5yZXFOKSx0LnlhKCkpLG51bGwhPT10aGlzLnJlc3BGYWxsYmFja04mJnZvaWQgMCE9PXRoaXMucmVzcEZhbGxiYWNrTiYmKHQuZ2EoXCJyZXNwRmFsbGJhY2tOXCIsci5icy5rcywyKSx0Lk9jKHRoaXMucmVzcEZhbGxiYWNrTiksdC55YSgpKSxudWxsIT09dGhpcy5yZXNwRmFsbGJhY2tFcnJOJiZ2b2lkIDAhPT10aGlzLnJlc3BGYWxsYmFja0Vyck4mJih0LmdhKFwicmVzcEZhbGxiYWNrRXJyTlwiLHIuYnMuT3MsMyksdC5tYSh0aGlzLnJlc3BGYWxsYmFja0Vyck4pLHQueWEoKSksbnVsbCE9PXRoaXMucmVzcFAycE4mJnZvaWQgMCE9PXRoaXMucmVzcFAycE4mJih0LmdhKFwicmVzcFAycE5cIixyLmJzLmtzLDQpLHQuT2ModGhpcy5yZXNwUDJwTiksdC55YSgpKSxudWxsIT09dGhpcy5yZXFPdGhlck4mJnZvaWQgMCE9PXRoaXMucmVxT3RoZXJOJiYodC5nYShcInJlcU90aGVyTlwiLHIuYnMuT3MsNSksdC5tYSh0aGlzLnJlcU90aGVyTiksdC55YSgpKSxudWxsIT09dGhpcy5yZXNwRmFsbGJhY2tPdGhlck4mJnZvaWQgMCE9PXRoaXMucmVzcEZhbGxiYWNrT3RoZXJOJiYodC5nYShcInJlc3BGYWxsYmFja090aGVyTlwiLHIuYnMuT3MsNiksdC5tYSh0aGlzLnJlc3BGYWxsYmFja090aGVyTiksdC55YSgpKSxudWxsIT09dGhpcy5yZXNwRmFsbGJhY2tPdGhlcnRFcnJOJiZ2b2lkIDAhPT10aGlzLnJlc3BGYWxsYmFja090aGVydEVyck4mJih0LmdhKFwicmVzcEZhbGxiYWNrT3RoZXJ0RXJyTlwiLHIuYnMuT3MsNyksdC5tYSh0aGlzLnJlc3BGYWxsYmFja090aGVydEVyck4pLHQueWEoKSksbnVsbCE9PXRoaXMuc3JjUmVxTiYmdm9pZCAwIT09dGhpcy5zcmNSZXFOJiYodC5nYShcInNyY1JlcU5cIixyLmJzLk9zLDgpLHQubWEodGhpcy5zcmNSZXFOKSx0LnlhKCkpLG51bGwhPT10aGlzLnNyY1Jlc3BOJiZ2b2lkIDAhPT10aGlzLnNyY1Jlc3BOJiYodC5nYShcInNyY1Jlc3BOXCIsci5icy5Pcyw5KSx0Lm1hKHRoaXMuc3JjUmVzcE4pLHQueWEoKSksbnVsbCE9PXRoaXMuc3JjUmVzcEVyck4mJnZvaWQgMCE9PXRoaXMuc3JjUmVzcEVyck4mJih0LmdhKFwic3JjUmVzcEVyck5cIixyLmJzLk9zLDEwKSx0Lm1hKHRoaXMuc3JjUmVzcEVyck4pLHQueWEoKSksbnVsbCE9PXRoaXMuc3JjUmVxUXQmJnZvaWQgMCE9PXRoaXMuc3JjUmVxUXQmJih0LmdhKFwic3JjUmVxUXRcIixyLmJzLlBzLDExKSx0LkNjKHRoaXMuc3JjUmVxUXQpLHQueWEoKSksbnVsbCE9PXRoaXMuc3JjUmVzcFF0JiZ2b2lkIDAhPT10aGlzLnNyY1Jlc3BRdCYmKHQuZ2EoXCJzcmNSZXNwUXRcIixyLmJzLlBzLDEyKSx0LkNjKHRoaXMuc3JjUmVzcFF0KSx0LnlhKCkpLG51bGwhPT10aGlzLnNyY092ZXJRdCYmdm9pZCAwIT09dGhpcy5zcmNPdmVyUXQmJih0LmdhKFwic3JjT3ZlclF0XCIsci5icy5QcywxMyksdC5DYyh0aGlzLnNyY092ZXJRdCksdC55YSgpKSxudWxsIT09dGhpcy5zcmNPdGhlclJlcU4mJnZvaWQgMCE9PXRoaXMuc3JjT3RoZXJSZXFOJiYodC5nYShcInNyY090aGVyUmVxTlwiLHIuYnMuT3MsMTQpLHQubWEodGhpcy5zcmNPdGhlclJlcU4pLHQueWEoKSksbnVsbCE9PXRoaXMuc3JjT3RoZXJSZXNwTiYmdm9pZCAwIT09dGhpcy5zcmNPdGhlclJlc3BOJiYodC5nYShcInNyY090aGVyUmVzcE5cIixyLmJzLk9zLDE1KSx0Lm1hKHRoaXMuc3JjT3RoZXJSZXNwTiksdC55YSgpKSxudWxsIT09dGhpcy5zcmNPdGhlclJlc3BFcnJOJiZ2b2lkIDAhPT10aGlzLnNyY090aGVyUmVzcEVyck4mJih0LmdhKFwic3JjT3RoZXJSZXNwRXJyTlwiLHIuYnMuT3MsMTYpLHQubWEodGhpcy5zcmNPdGhlclJlc3BFcnJOKSx0LnlhKCkpLG51bGwhPT10aGlzLnNyY090aGVyUmVxUXQmJnZvaWQgMCE9PXRoaXMuc3JjT3RoZXJSZXFRdCYmKHQuZ2EoXCJzcmNPdGhlclJlcVF0XCIsci5icy5QcywxNyksdC5DYyh0aGlzLnNyY090aGVyUmVxUXQpLHQueWEoKSksbnVsbCE9PXRoaXMuc3JjT3RoZXJSZXNwUXQmJnZvaWQgMCE9PXRoaXMuc3JjT3RoZXJSZXNwUXQmJih0LmdhKFwic3JjT3RoZXJSZXNwUXRcIixyLmJzLlBzLDE4KSx0LkNjKHRoaXMuc3JjT3RoZXJSZXNwUXQpLHQueWEoKSksbnVsbCE9PXRoaXMuc3JjT3RoZXJPdmVyUXQmJnZvaWQgMCE9PXRoaXMuc3JjT3RoZXJPdmVyUXQmJih0LmdhKFwic3JjT3RoZXJPdmVyUXRcIixyLmJzLlBzLDE5KSx0LkNjKHRoaXMuc3JjT3RoZXJPdmVyUXQpLHQueWEoKSksbnVsbCE9PXRoaXMucDJwU3ViUmVxTiYmdm9pZCAwIT09dGhpcy5wMnBTdWJSZXFOJiYodC5nYShcInAycFN1YlJlcU5cIixyLmJzLk9zLDIwKSx0Lm1hKHRoaXMucDJwU3ViUmVxTiksdC55YSgpKSxudWxsIT09dGhpcy5wMnBTdWJSZXNwTiYmdm9pZCAwIT09dGhpcy5wMnBTdWJSZXNwTiYmKHQuZ2EoXCJwMnBTdWJSZXNwTlwiLHIuYnMuT3MsMjEpLHQubWEodGhpcy5wMnBTdWJSZXNwTiksdC55YSgpKSxudWxsIT09dGhpcy5wMnBTdWJSZXNwUGFydE4mJnZvaWQgMCE9PXRoaXMucDJwU3ViUmVzcFBhcnROJiYodC5nYShcInAycFN1YlJlc3BQYXJ0TlwiLHIuYnMua3MsMjIpLHQuT2ModGhpcy5wMnBTdWJSZXNwUGFydE4pLHQueWEoKSksbnVsbCE9PXRoaXMucDJwU3ViUmVzcEVyck4mJnZvaWQgMCE9PXRoaXMucDJwU3ViUmVzcEVyck4mJih0LmdhKFwicDJwU3ViUmVzcEVyck5cIixyLmJzLmtzLDIzKSx0Lk9jKHRoaXMucDJwU3ViUmVzcEVyck4pLHQueWEoKSksbnVsbCE9PXRoaXMucDJwU3ViUmVzcEV4cE4mJnZvaWQgMCE9PXRoaXMucDJwU3ViUmVzcEV4cE4mJih0LmdhKFwicDJwU3ViUmVzcEV4cE5cIixyLmJzLk9zLDI0KSx0Lm1hKHRoaXMucDJwU3ViUmVzcEV4cE4pLHQueWEoKSksbnVsbCE9PXRoaXMucDJwU3ViUmVxUXQmJnZvaWQgMCE9PXRoaXMucDJwU3ViUmVxUXQmJih0LmdhKFwicDJwU3ViUmVxUXRcIixyLmJzLlBzLDI1KSx0LkNjKHRoaXMucDJwU3ViUmVxUXQpLHQueWEoKSksbnVsbCE9PXRoaXMucDJwU3ViUmVzcFF0JiZ2b2lkIDAhPT10aGlzLnAycFN1YlJlc3BRdCYmKHQuZ2EoXCJwMnBTdWJSZXNwUXRcIixyLmJzLlBzLDI2KSx0LkNjKHRoaXMucDJwU3ViUmVzcFF0KSx0LnlhKCkpLG51bGwhPT10aGlzLnAycERpcmVjdFF0JiZ2b2lkIDAhPT10aGlzLnAycERpcmVjdFF0JiYodC5nYShcInAycERpcmVjdFF0XCIsci5icy5QcywyNyksdC5DYyh0aGlzLnAycERpcmVjdFF0KSx0LnlhKCkpLG51bGwhPT10aGlzLnAycFJlbGF5UXQmJnZvaWQgMCE9PXRoaXMucDJwUmVsYXlRdCYmKHQuZ2EoXCJwMnBSZWxheVF0XCIsci5icy5QcywyOCksdC5DYyh0aGlzLnAycFJlbGF5UXQpLHQueWEoKSksbnVsbCE9PXRoaXMucDJwTmF0UXQmJnZvaWQgMCE9PXRoaXMucDJwTmF0UXQmJih0LmdhKFwicDJwTmF0UXRcIixyLmJzLlBzLDI5KSx0LkNjKHRoaXMucDJwTmF0UXQpLHQueWEoKSksbnVsbCE9PXRoaXMucDJwVWRwYlF0JiZ2b2lkIDAhPT10aGlzLnAycFVkcGJRdCYmKHQuZ2EoXCJwMnBVZHBiUXRcIixyLmJzLlBzLDMwKSx0LkNjKHRoaXMucDJwVWRwYlF0KSx0LnlhKCkpLG51bGwhPT10aGlzLmZhbGxBZ2VudFJlc3BOJiZ2b2lkIDAhPT10aGlzLmZhbGxBZ2VudFJlc3BOJiYodC5nYShcImZhbGxBZ2VudFJlc3BOXCIsci5icy5PcywzMSksdC5tYSh0aGlzLmZhbGxBZ2VudFJlc3BOKSx0LnlhKCkpLG51bGwhPT10aGlzLmZhbGxBZ2VudFByZWRIaXROJiZ2b2lkIDAhPT10aGlzLmZhbGxBZ2VudFByZWRIaXROJiYodC5nYShcImZhbGxBZ2VudFByZWRIaXROXCIsci5icy5PcywzMiksdC5tYSh0aGlzLmZhbGxBZ2VudFByZWRIaXROKSx0LnlhKCkpLG51bGwhPT10aGlzLmZhbGxBZ2VudEZhaWxlZFJlc3BOJiZ2b2lkIDAhPT10aGlzLmZhbGxBZ2VudEZhaWxlZFJlc3BOJiYodC5nYShcImZhbGxBZ2VudEZhaWxlZFJlc3BOXCIsci5icy5PcywzMyksdC5tYSh0aGlzLmZhbGxBZ2VudEZhaWxlZFJlc3BOKSx0LnlhKCkpLG51bGwhPT10aGlzLmZhbGxBZ2VudFByZWRNaXNzTiYmdm9pZCAwIT09dGhpcy5mYWxsQWdlbnRQcmVkTWlzc04mJih0LmdhKFwiZmFsbEFnZW50UHJlZE1pc3NOXCIsci5icy5PcywzNCksdC5tYSh0aGlzLmZhbGxBZ2VudFByZWRNaXNzTiksdC55YSgpKSxudWxsIT09dGhpcy5mYWxsQWdlbnRQcmVkUGFydGlhbEhpdE4mJnZvaWQgMCE9PXRoaXMuZmFsbEFnZW50UHJlZFBhcnRpYWxIaXROJiYodC5nYShcImZhbGxBZ2VudFByZWRQYXJ0aWFsSGl0TlwiLHIuYnMuT3MsMzUpLHQubWEodGhpcy5mYWxsQWdlbnRQcmVkUGFydGlhbEhpdE4pLHQueWEoKSksbnVsbCE9PXRoaXMuZmFsbEFnZW5UcmFmZmljU3VjY2Vzc1F0JiZ2b2lkIDAhPT10aGlzLmZhbGxBZ2VuVHJhZmZpY1N1Y2Nlc3NRdCYmKHQuZ2EoXCJmYWxsQWdlblRyYWZmaWNTdWNjZXNzUXRcIixyLmJzLlBzLDM2KSx0LkNjKHRoaXMuZmFsbEFnZW5UcmFmZmljU3VjY2Vzc1F0KSx0LnlhKCkpLG51bGwhPT10aGlzLmZhbGxBZ2VuVHJhZmZpY0ZhaWx1cmVRdCYmdm9pZCAwIT09dGhpcy5mYWxsQWdlblRyYWZmaWNGYWlsdXJlUXQmJih0LmdhKFwiZmFsbEFnZW5UcmFmZmljRmFpbHVyZVF0XCIsci5icy5QcywzNyksdC5DYyh0aGlzLmZhbGxBZ2VuVHJhZmZpY0ZhaWx1cmVRdCksdC55YSgpKSxudWxsIT09dGhpcy5wMnBBZ2VudFByZWRIaXROJiZ2b2lkIDAhPT10aGlzLnAycEFnZW50UHJlZEhpdE4mJih0LmdhKFwicDJwQWdlbnRQcmVkSGl0TlwiLHIuYnMuT3MsMzgpLHQubWEodGhpcy5wMnBBZ2VudFByZWRIaXROKSx0LnlhKCkpLG51bGwhPT10aGlzLnAycEFnZW50UHJlZE1pc3NOJiZ2b2lkIDAhPT10aGlzLnAycEFnZW50UHJlZE1pc3NOJiYodC5nYShcInAycEFnZW50UHJlZE1pc3NOXCIsci5icy5PcywzOSksdC5tYSh0aGlzLnAycEFnZW50UHJlZE1pc3NOKSx0LnlhKCkpLG51bGwhPT10aGlzLnAycEFnZW50UHJlZFBhcnRpYWxIaXROJiZ2b2lkIDAhPT10aGlzLnAycEFnZW50UHJlZFBhcnRpYWxIaXROJiYodC5nYShcInAycEFnZW50UHJlZFBhcnRpYWxIaXROXCIsci5icy5Pcyw0MCksdC5tYSh0aGlzLnAycEFnZW50UHJlZFBhcnRpYWxIaXROKSx0LnlhKCkpLG51bGwhPT10aGlzLnAycEFnZW5UcmFmZmljU3VjY2Vzc1F0JiZ2b2lkIDAhPT10aGlzLnAycEFnZW5UcmFmZmljU3VjY2Vzc1F0JiYodC5nYShcInAycEFnZW5UcmFmZmljU3VjY2Vzc1F0XCIsci5icy5Qcyw0MSksdC5DYyh0aGlzLnAycEFnZW5UcmFmZmljU3VjY2Vzc1F0KSx0LnlhKCkpLG51bGwhPT10aGlzLnAycEFnZW5UcmFmZmljRmFpbHVyZVF0JiZ2b2lkIDAhPT10aGlzLnAycEFnZW5UcmFmZmljRmFpbHVyZVF0JiYodC5nYShcInAycEFnZW5UcmFmZmljRmFpbHVyZVF0XCIsci5icy5Qcyw0MiksdC5DYyh0aGlzLnAycEFnZW5UcmFmZmljRmFpbHVyZVF0KSx0LnlhKCkpLG51bGwhPT10aGlzLnJlc3BQMnBPdGhlck4mJnZvaWQgMCE9PXRoaXMucmVzcFAycE90aGVyTiYmKHQuZ2EoXCJyZXNwUDJwT3RoZXJOXCIsci5icy5Pcyw0MyksdC5tYSh0aGlzLnJlc3BQMnBPdGhlck4pLHQueWEoKSksbnVsbCE9PXRoaXMubENhY2hlUmVzcE4mJnZvaWQgMCE9PXRoaXMubENhY2hlUmVzcE4mJih0LmdhKFwibENhY2hlUmVzcE5cIixyLmJzLk9zLDQ0KSx0Lm1hKHRoaXMubENhY2hlUmVzcE4pLHQueWEoKSksbnVsbCE9PXRoaXMubENhY2hlUmVzcFF0JiZ2b2lkIDAhPT10aGlzLmxDYWNoZVJlc3BRdCYmKHQuZ2EoXCJsQ2FjaGVSZXNwUXRcIixyLmJzLlBzLDQ1KSx0LkNjKHRoaXMubENhY2hlUmVzcFF0KSx0LnlhKCkpLG51bGwhPT10aGlzLnAycE91dFNpdGVMb3dQcmlvJiZ2b2lkIDAhPT10aGlzLnAycE91dFNpdGVMb3dQcmlvJiYodC5nYShcInAycE91dFNpdGVMb3dQcmlvXCIsci5icy5Qcyw0NiksdC5DYyh0aGlzLnAycE91dFNpdGVMb3dQcmlvKSx0LnlhKCkpLHQud2EoKSx0LlRhKCl9LGhpdmUuc25hcHNob3RzLk1ldHJpY3M9ZnVuY3Rpb24odCl7dGhpcy51cEJXPW51bGwsdGhpcy5kb3duQlc9bnVsbCx0aGlzLm1lbU49bnVsbCx0aGlzLnBydEluTj1udWxsLHRoaXMucHJ0T3V0Tj1udWxsLHRoaXMuaW5pdFZpZGVvQnVmUXQ9bnVsbCx0aGlzLnZpZGVvQXZnQnVmUXQ9bnVsbCx0aGlzLnZpZGVvQnVmUXQ9bnVsbCx0aGlzLnZpZGVvQnVmTj1udWxsLHRoaXMuaW5pdEF1ZGlvQnVmUXQ9bnVsbCx0aGlzLmF1ZGlvQXZnQnVmUXQ9bnVsbCx0aGlzLmF1ZGlvQnVmUXQ9bnVsbCx0aGlzLmF1ZGlvQnVmTj1udWxsLHRoaXMuYml0cmF0ZVVwTj1udWxsLHRoaXMuYml0cmF0ZUR3bk49bnVsbCx0aGlzLmRlbGF5PW51bGwsdGhpcy5kZWxheUVuZm9yY2VtZW50PW51bGwsdGhpcy5sb29rdXBSZXFFc3RhYmxpc2hlZD1udWxsLHRoaXMubG9va3VwUmVxQWNjZXB0PW51bGwsdGhpcy5mYWxsYmFja0F2Z1RwPW51bGwsdGhpcy5zcmNUaHJvdWdocHV0PW51bGwsdGhpcy5kaXNrUmVhZFRpbWVvdXQ9bnVsbCx0aGlzLmRpc2tSZWFkUmF0ZT1udWxsLHRoaXMuZGlza1N0b3JlUmF0ZT1udWxsLHRoaXMuZGlza1JlbW92ZVJhdGU9bnVsbCx0aGlzLmRpc2tDYWNoZVNpemU9bnVsbCx0aGlzLmNsaWVudEJ1ZmZlck1zPW51bGwsdGhpcy5sb29rdXBUb3RhbD1udWxsLHRoaXMubG9va3VwTm90Rm91bmQ9bnVsbCx0aGlzLmxvb2t1cEZhaWxlZD1udWxsLHRoaXMubG9va3VwTGF0ZW5jeT1udWxsLHRoaXMudHJhY2tlckZhaWxlZD1udWxsLHRoaXMudHJhY2tlckxhdGVuY3k9bnVsbCx0aGlzLnNuYXBzaG90RmFpbGVkPW51bGwsdGhpcy5zbmFwc2hvdExhdGVuY3k9bnVsbCx0JiYodm9pZCAwIT09dC51cEJXJiYodGhpcy51cEJXPXQudXBCVyksdm9pZCAwIT09dC5kb3duQlcmJih0aGlzLmRvd25CVz10LmRvd25CVyksdm9pZCAwIT09dC5tZW1OJiYodGhpcy5tZW1OPXQubWVtTiksdm9pZCAwIT09dC5wcnRJbk4mJih0aGlzLnBydEluTj10LnBydEluTiksdm9pZCAwIT09dC5wcnRPdXROJiYodGhpcy5wcnRPdXROPXQucHJ0T3V0Tiksdm9pZCAwIT09dC5pbml0VmlkZW9CdWZRdCYmKHRoaXMuaW5pdFZpZGVvQnVmUXQ9dC5pbml0VmlkZW9CdWZRdCksdm9pZCAwIT09dC52aWRlb0F2Z0J1ZlF0JiYodGhpcy52aWRlb0F2Z0J1ZlF0PXQudmlkZW9BdmdCdWZRdCksdm9pZCAwIT09dC52aWRlb0J1ZlF0JiYodGhpcy52aWRlb0J1ZlF0PXQudmlkZW9CdWZRdCksdm9pZCAwIT09dC52aWRlb0J1Zk4mJih0aGlzLnZpZGVvQnVmTj10LnZpZGVvQnVmTiksdm9pZCAwIT09dC5pbml0QXVkaW9CdWZRdCYmKHRoaXMuaW5pdEF1ZGlvQnVmUXQ9dC5pbml0QXVkaW9CdWZRdCksdm9pZCAwIT09dC5hdWRpb0F2Z0J1ZlF0JiYodGhpcy5hdWRpb0F2Z0J1ZlF0PXQuYXVkaW9BdmdCdWZRdCksdm9pZCAwIT09dC5hdWRpb0J1ZlF0JiYodGhpcy5hdWRpb0J1ZlF0PXQuYXVkaW9CdWZRdCksdm9pZCAwIT09dC5hdWRpb0J1Zk4mJih0aGlzLmF1ZGlvQnVmTj10LmF1ZGlvQnVmTiksdm9pZCAwIT09dC5iaXRyYXRlVXBOJiYodGhpcy5iaXRyYXRlVXBOPXQuYml0cmF0ZVVwTiksdm9pZCAwIT09dC5iaXRyYXRlRHduTiYmKHRoaXMuYml0cmF0ZUR3bk49dC5iaXRyYXRlRHduTiksdm9pZCAwIT09dC5kZWxheSYmKHRoaXMuZGVsYXk9dC5kZWxheSksdm9pZCAwIT09dC5kZWxheUVuZm9yY2VtZW50JiYodGhpcy5kZWxheUVuZm9yY2VtZW50PXQuZGVsYXlFbmZvcmNlbWVudCksdm9pZCAwIT09dC5sb29rdXBSZXFFc3RhYmxpc2hlZCYmKHRoaXMubG9va3VwUmVxRXN0YWJsaXNoZWQ9dC5sb29rdXBSZXFFc3RhYmxpc2hlZCksdm9pZCAwIT09dC5sb29rdXBSZXFBY2NlcHQmJih0aGlzLmxvb2t1cFJlcUFjY2VwdD10Lmxvb2t1cFJlcUFjY2VwdCksdm9pZCAwIT09dC5mYWxsYmFja0F2Z1RwJiYodGhpcy5mYWxsYmFja0F2Z1RwPXQuZmFsbGJhY2tBdmdUcCksdm9pZCAwIT09dC5zcmNUaHJvdWdocHV0JiYodGhpcy5zcmNUaHJvdWdocHV0PXQuc3JjVGhyb3VnaHB1dCksdm9pZCAwIT09dC5kaXNrUmVhZFRpbWVvdXQmJih0aGlzLmRpc2tSZWFkVGltZW91dD10LmRpc2tSZWFkVGltZW91dCksdm9pZCAwIT09dC5kaXNrUmVhZFJhdGUmJih0aGlzLmRpc2tSZWFkUmF0ZT10LmRpc2tSZWFkUmF0ZSksdm9pZCAwIT09dC5kaXNrU3RvcmVSYXRlJiYodGhpcy5kaXNrU3RvcmVSYXRlPXQuZGlza1N0b3JlUmF0ZSksdm9pZCAwIT09dC5kaXNrUmVtb3ZlUmF0ZSYmKHRoaXMuZGlza1JlbW92ZVJhdGU9dC5kaXNrUmVtb3ZlUmF0ZSksdm9pZCAwIT09dC5kaXNrQ2FjaGVTaXplJiYodGhpcy5kaXNrQ2FjaGVTaXplPXQuZGlza0NhY2hlU2l6ZSksdm9pZCAwIT09dC5jbGllbnRCdWZmZXJNcyYmKHRoaXMuY2xpZW50QnVmZmVyTXM9dC5jbGllbnRCdWZmZXJNcyksdm9pZCAwIT09dC5sb29rdXBUb3RhbCYmKHRoaXMubG9va3VwVG90YWw9dC5sb29rdXBUb3RhbCksdm9pZCAwIT09dC5sb29rdXBOb3RGb3VuZCYmKHRoaXMubG9va3VwTm90Rm91bmQ9dC5sb29rdXBOb3RGb3VuZCksdm9pZCAwIT09dC5sb29rdXBGYWlsZWQmJih0aGlzLmxvb2t1cEZhaWxlZD10Lmxvb2t1cEZhaWxlZCksdm9pZCAwIT09dC5sb29rdXBMYXRlbmN5JiYodGhpcy5sb29rdXBMYXRlbmN5PXQubG9va3VwTGF0ZW5jeSksdm9pZCAwIT09dC50cmFja2VyRmFpbGVkJiYodGhpcy50cmFja2VyRmFpbGVkPXQudHJhY2tlckZhaWxlZCksdm9pZCAwIT09dC50cmFja2VyTGF0ZW5jeSYmKHRoaXMudHJhY2tlckxhdGVuY3k9dC50cmFja2VyTGF0ZW5jeSksdm9pZCAwIT09dC5zbmFwc2hvdEZhaWxlZCYmKHRoaXMuc25hcHNob3RGYWlsZWQ9dC5zbmFwc2hvdEZhaWxlZCksdm9pZCAwIT09dC5zbmFwc2hvdExhdGVuY3kmJih0aGlzLnNuYXBzaG90TGF0ZW5jeT10LnNuYXBzaG90TGF0ZW5jeSkpfSxoaXZlLnNuYXBzaG90cy5NZXRyaWNzLnByb3RvdHlwZT17fSxoaXZlLnNuYXBzaG90cy5NZXRyaWNzLnByb3RvdHlwZS5yZWFkPWZ1bmN0aW9uKHQpe2Zvcih0LkhjKCk7Oyl7dmFyIGU9dC5zYSgpLGk9KGUuQmMsZS5hYSksbj1lLmNhO2lmKGk9PXIuYnMuRXMpYnJlYWs7c3dpdGNoKG4pe2Nhc2UgMTppPT1yLmJzLk9zP3RoaXMudXBCVz10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI6aT09ci5icy5Pcz90aGlzLmRvd25CVz10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM6aT09ci5icy5Pcz90aGlzLm1lbU49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA0Omk9PXIuYnMuT3M/dGhpcy5wcnRJbk49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA1Omk9PXIuYnMuT3M/dGhpcy5wcnRPdXROPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNjppPT1yLmJzLlBzP3RoaXMuaW5pdFZpZGVvQnVmUXQ9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA3Omk9PXIuYnMua3M/dGhpcy52aWRlb0F2Z0J1ZlF0PXQuWWMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgODppPT1yLmJzLlBzP3RoaXMudmlkZW9CdWZRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDk6aT09ci5icy5Pcz90aGlzLnZpZGVvQnVmTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDEwOmk9PXIuYnMuT3M/dGhpcy5pbml0QXVkaW9CdWZRdD10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDExOmk9PXIuYnMua3M/dGhpcy5hdWRpb0F2Z0J1ZlF0PXQuWWMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTI6aT09ci5icy5Qcz90aGlzLmF1ZGlvQnVmUXQ9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAxMzppPT1yLmJzLk9zP3RoaXMuYXVkaW9CdWZOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTQ6aT09ci5icy5Pcz90aGlzLmJpdHJhdGVVcE49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAxNTppPT1yLmJzLk9zP3RoaXMuYml0cmF0ZUR3bk49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAxNjppPT1yLmJzLk9zP3RoaXMuZGVsYXk9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAxNzppPT1yLmJzLk9zP3RoaXMuZGVsYXlFbmZvcmNlbWVudD10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDE4Omk9PXIuYnMuT3M/dGhpcy5sb29rdXBSZXFFc3RhYmxpc2hlZD10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDE5Omk9PXIuYnMuT3M/dGhpcy5sb29rdXBSZXFBY2NlcHQ9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyMDppPT1yLmJzLmtzP3RoaXMuZmFsbGJhY2tBdmdUcD10LlljKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDIxOmk9PXIuYnMua3M/dGhpcy5zcmNUaHJvdWdocHV0PXQuWWMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjI6aT09ci5icy5Pcz90aGlzLmRpc2tSZWFkVGltZW91dD10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDIzOmk9PXIuYnMua3M/dGhpcy5kaXNrUmVhZFJhdGU9dC5ZYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyNDppPT1yLmJzLmtzP3RoaXMuZGlza1N0b3JlUmF0ZT10LlljKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI1Omk9PXIuYnMua3M/dGhpcy5kaXNrUmVtb3ZlUmF0ZT10LlljKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI2Omk9PXIuYnMuUHM/dGhpcy5kaXNrQ2FjaGVTaXplPXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjc6aT09ci5icy5Pcz90aGlzLmNsaWVudEJ1ZmZlck1zPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjg6aT09ci5icy5Pcz90aGlzLmxvb2t1cFRvdGFsPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjk6aT09ci5icy5Pcz90aGlzLmxvb2t1cE5vdEZvdW5kPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzA6aT09ci5icy5Pcz90aGlzLmxvb2t1cEZhaWxlZD10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDMxOmk9PXIuYnMuT3M/dGhpcy5sb29rdXBMYXRlbmN5PXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzI6aT09ci5icy5Pcz90aGlzLnRyYWNrZXJGYWlsZWQ9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzMzppPT1yLmJzLk9zP3RoaXMudHJhY2tlckxhdGVuY3k9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzNDppPT1yLmJzLk9zP3RoaXMuc25hcHNob3RGYWlsZWQ9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzNTppPT1yLmJzLk9zP3RoaXMuc25hcHNob3RMYXRlbmN5PXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2RlZmF1bHQ6dC5wYShpKX10LmxhKCl9dC5kYSgpfSxoaXZlLnNuYXBzaG90cy5NZXRyaWNzLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbih0KXt0LmZhKFwiTWV0cmljc1wiKSxudWxsIT09dGhpcy51cEJXJiZ2b2lkIDAhPT10aGlzLnVwQlcmJih0LmdhKFwidXBCV1wiLHIuYnMuT3MsMSksdC5tYSh0aGlzLnVwQlcpLHQueWEoKSksbnVsbCE9PXRoaXMuZG93bkJXJiZ2b2lkIDAhPT10aGlzLmRvd25CVyYmKHQuZ2EoXCJkb3duQldcIixyLmJzLk9zLDIpLHQubWEodGhpcy5kb3duQlcpLHQueWEoKSksbnVsbCE9PXRoaXMubWVtTiYmdm9pZCAwIT09dGhpcy5tZW1OJiYodC5nYShcIm1lbU5cIixyLmJzLk9zLDMpLHQubWEodGhpcy5tZW1OKSx0LnlhKCkpLG51bGwhPT10aGlzLnBydEluTiYmdm9pZCAwIT09dGhpcy5wcnRJbk4mJih0LmdhKFwicHJ0SW5OXCIsci5icy5Pcyw0KSx0Lm1hKHRoaXMucHJ0SW5OKSx0LnlhKCkpLG51bGwhPT10aGlzLnBydE91dE4mJnZvaWQgMCE9PXRoaXMucHJ0T3V0TiYmKHQuZ2EoXCJwcnRPdXROXCIsci5icy5Pcyw1KSx0Lm1hKHRoaXMucHJ0T3V0TiksdC55YSgpKSxudWxsIT09dGhpcy5pbml0VmlkZW9CdWZRdCYmdm9pZCAwIT09dGhpcy5pbml0VmlkZW9CdWZRdCYmKHQuZ2EoXCJpbml0VmlkZW9CdWZRdFwiLHIuYnMuUHMsNiksdC5DYyh0aGlzLmluaXRWaWRlb0J1ZlF0KSx0LnlhKCkpLG51bGwhPT10aGlzLnZpZGVvQXZnQnVmUXQmJnZvaWQgMCE9PXRoaXMudmlkZW9BdmdCdWZRdCYmKHQuZ2EoXCJ2aWRlb0F2Z0J1ZlF0XCIsci5icy5rcyw3KSx0Lk9jKHRoaXMudmlkZW9BdmdCdWZRdCksdC55YSgpKSxudWxsIT09dGhpcy52aWRlb0J1ZlF0JiZ2b2lkIDAhPT10aGlzLnZpZGVvQnVmUXQmJih0LmdhKFwidmlkZW9CdWZRdFwiLHIuYnMuUHMsOCksdC5DYyh0aGlzLnZpZGVvQnVmUXQpLHQueWEoKSksbnVsbCE9PXRoaXMudmlkZW9CdWZOJiZ2b2lkIDAhPT10aGlzLnZpZGVvQnVmTiYmKHQuZ2EoXCJ2aWRlb0J1Zk5cIixyLmJzLk9zLDkpLHQubWEodGhpcy52aWRlb0J1Zk4pLHQueWEoKSksbnVsbCE9PXRoaXMuaW5pdEF1ZGlvQnVmUXQmJnZvaWQgMCE9PXRoaXMuaW5pdEF1ZGlvQnVmUXQmJih0LmdhKFwiaW5pdEF1ZGlvQnVmUXRcIixyLmJzLk9zLDEwKSx0Lm1hKHRoaXMuaW5pdEF1ZGlvQnVmUXQpLHQueWEoKSksbnVsbCE9PXRoaXMuYXVkaW9BdmdCdWZRdCYmdm9pZCAwIT09dGhpcy5hdWRpb0F2Z0J1ZlF0JiYodC5nYShcImF1ZGlvQXZnQnVmUXRcIixyLmJzLmtzLDExKSx0Lk9jKHRoaXMuYXVkaW9BdmdCdWZRdCksdC55YSgpKSxudWxsIT09dGhpcy5hdWRpb0J1ZlF0JiZ2b2lkIDAhPT10aGlzLmF1ZGlvQnVmUXQmJih0LmdhKFwiYXVkaW9CdWZRdFwiLHIuYnMuUHMsMTIpLHQuQ2ModGhpcy5hdWRpb0J1ZlF0KSx0LnlhKCkpLG51bGwhPT10aGlzLmF1ZGlvQnVmTiYmdm9pZCAwIT09dGhpcy5hdWRpb0J1Zk4mJih0LmdhKFwiYXVkaW9CdWZOXCIsci5icy5PcywxMyksdC5tYSh0aGlzLmF1ZGlvQnVmTiksdC55YSgpKSxudWxsIT09dGhpcy5iaXRyYXRlVXBOJiZ2b2lkIDAhPT10aGlzLmJpdHJhdGVVcE4mJih0LmdhKFwiYml0cmF0ZVVwTlwiLHIuYnMuT3MsMTQpLHQubWEodGhpcy5iaXRyYXRlVXBOKSx0LnlhKCkpLG51bGwhPT10aGlzLmJpdHJhdGVEd25OJiZ2b2lkIDAhPT10aGlzLmJpdHJhdGVEd25OJiYodC5nYShcImJpdHJhdGVEd25OXCIsci5icy5PcywxNSksdC5tYSh0aGlzLmJpdHJhdGVEd25OKSx0LnlhKCkpLG51bGwhPT10aGlzLmRlbGF5JiZ2b2lkIDAhPT10aGlzLmRlbGF5JiYodC5nYShcImRlbGF5XCIsci5icy5PcywxNiksdC5tYSh0aGlzLmRlbGF5KSx0LnlhKCkpLG51bGwhPT10aGlzLmRlbGF5RW5mb3JjZW1lbnQmJnZvaWQgMCE9PXRoaXMuZGVsYXlFbmZvcmNlbWVudCYmKHQuZ2EoXCJkZWxheUVuZm9yY2VtZW50XCIsci5icy5PcywxNyksdC5tYSh0aGlzLmRlbGF5RW5mb3JjZW1lbnQpLHQueWEoKSksbnVsbCE9PXRoaXMubG9va3VwUmVxRXN0YWJsaXNoZWQmJnZvaWQgMCE9PXRoaXMubG9va3VwUmVxRXN0YWJsaXNoZWQmJih0LmdhKFwibG9va3VwUmVxRXN0YWJsaXNoZWRcIixyLmJzLk9zLDE4KSx0Lm1hKHRoaXMubG9va3VwUmVxRXN0YWJsaXNoZWQpLHQueWEoKSksbnVsbCE9PXRoaXMubG9va3VwUmVxQWNjZXB0JiZ2b2lkIDAhPT10aGlzLmxvb2t1cFJlcUFjY2VwdCYmKHQuZ2EoXCJsb29rdXBSZXFBY2NlcHRcIixyLmJzLk9zLDE5KSx0Lm1hKHRoaXMubG9va3VwUmVxQWNjZXB0KSx0LnlhKCkpLG51bGwhPT10aGlzLmZhbGxiYWNrQXZnVHAmJnZvaWQgMCE9PXRoaXMuZmFsbGJhY2tBdmdUcCYmKHQuZ2EoXCJmYWxsYmFja0F2Z1RwXCIsci5icy5rcywyMCksdC5PYyh0aGlzLmZhbGxiYWNrQXZnVHApLHQueWEoKSksbnVsbCE9PXRoaXMuc3JjVGhyb3VnaHB1dCYmdm9pZCAwIT09dGhpcy5zcmNUaHJvdWdocHV0JiYodC5nYShcInNyY1Rocm91Z2hwdXRcIixyLmJzLmtzLDIxKSx0Lk9jKHRoaXMuc3JjVGhyb3VnaHB1dCksdC55YSgpKSxudWxsIT09dGhpcy5kaXNrUmVhZFRpbWVvdXQmJnZvaWQgMCE9PXRoaXMuZGlza1JlYWRUaW1lb3V0JiYodC5nYShcImRpc2tSZWFkVGltZW91dFwiLHIuYnMuT3MsMjIpLHQubWEodGhpcy5kaXNrUmVhZFRpbWVvdXQpLHQueWEoKSksbnVsbCE9PXRoaXMuZGlza1JlYWRSYXRlJiZ2b2lkIDAhPT10aGlzLmRpc2tSZWFkUmF0ZSYmKHQuZ2EoXCJkaXNrUmVhZFJhdGVcIixyLmJzLmtzLDIzKSx0Lk9jKHRoaXMuZGlza1JlYWRSYXRlKSx0LnlhKCkpLG51bGwhPT10aGlzLmRpc2tTdG9yZVJhdGUmJnZvaWQgMCE9PXRoaXMuZGlza1N0b3JlUmF0ZSYmKHQuZ2EoXCJkaXNrU3RvcmVSYXRlXCIsci5icy5rcywyNCksdC5PYyh0aGlzLmRpc2tTdG9yZVJhdGUpLHQueWEoKSksbnVsbCE9PXRoaXMuZGlza1JlbW92ZVJhdGUmJnZvaWQgMCE9PXRoaXMuZGlza1JlbW92ZVJhdGUmJih0LmdhKFwiZGlza1JlbW92ZVJhdGVcIixyLmJzLmtzLDI1KSx0Lk9jKHRoaXMuZGlza1JlbW92ZVJhdGUpLHQueWEoKSksbnVsbCE9PXRoaXMuZGlza0NhY2hlU2l6ZSYmdm9pZCAwIT09dGhpcy5kaXNrQ2FjaGVTaXplJiYodC5nYShcImRpc2tDYWNoZVNpemVcIixyLmJzLlBzLDI2KSx0LkNjKHRoaXMuZGlza0NhY2hlU2l6ZSksdC55YSgpKSxudWxsIT09dGhpcy5jbGllbnRCdWZmZXJNcyYmdm9pZCAwIT09dGhpcy5jbGllbnRCdWZmZXJNcyYmKHQuZ2EoXCJjbGllbnRCdWZmZXJNc1wiLHIuYnMuT3MsMjcpLHQubWEodGhpcy5jbGllbnRCdWZmZXJNcyksdC55YSgpKSxudWxsIT09dGhpcy5sb29rdXBUb3RhbCYmdm9pZCAwIT09dGhpcy5sb29rdXBUb3RhbCYmKHQuZ2EoXCJsb29rdXBUb3RhbFwiLHIuYnMuT3MsMjgpLHQubWEodGhpcy5sb29rdXBUb3RhbCksdC55YSgpKSxudWxsIT09dGhpcy5sb29rdXBOb3RGb3VuZCYmdm9pZCAwIT09dGhpcy5sb29rdXBOb3RGb3VuZCYmKHQuZ2EoXCJsb29rdXBOb3RGb3VuZFwiLHIuYnMuT3MsMjkpLHQubWEodGhpcy5sb29rdXBOb3RGb3VuZCksdC55YSgpKSxudWxsIT09dGhpcy5sb29rdXBGYWlsZWQmJnZvaWQgMCE9PXRoaXMubG9va3VwRmFpbGVkJiYodC5nYShcImxvb2t1cEZhaWxlZFwiLHIuYnMuT3MsMzApLHQubWEodGhpcy5sb29rdXBGYWlsZWQpLHQueWEoKSksbnVsbCE9PXRoaXMubG9va3VwTGF0ZW5jeSYmdm9pZCAwIT09dGhpcy5sb29rdXBMYXRlbmN5JiYodC5nYShcImxvb2t1cExhdGVuY3lcIixyLmJzLk9zLDMxKSx0Lm1hKHRoaXMubG9va3VwTGF0ZW5jeSksdC55YSgpKSxudWxsIT09dGhpcy50cmFja2VyRmFpbGVkJiZ2b2lkIDAhPT10aGlzLnRyYWNrZXJGYWlsZWQmJih0LmdhKFwidHJhY2tlckZhaWxlZFwiLHIuYnMuT3MsMzIpLHQubWEodGhpcy50cmFja2VyRmFpbGVkKSx0LnlhKCkpLG51bGwhPT10aGlzLnRyYWNrZXJMYXRlbmN5JiZ2b2lkIDAhPT10aGlzLnRyYWNrZXJMYXRlbmN5JiYodC5nYShcInRyYWNrZXJMYXRlbmN5XCIsci5icy5PcywzMyksdC5tYSh0aGlzLnRyYWNrZXJMYXRlbmN5KSx0LnlhKCkpLG51bGwhPT10aGlzLnNuYXBzaG90RmFpbGVkJiZ2b2lkIDAhPT10aGlzLnNuYXBzaG90RmFpbGVkJiYodC5nYShcInNuYXBzaG90RmFpbGVkXCIsci5icy5PcywzNCksdC5tYSh0aGlzLnNuYXBzaG90RmFpbGVkKSx0LnlhKCkpLG51bGwhPT10aGlzLnNuYXBzaG90TGF0ZW5jeSYmdm9pZCAwIT09dGhpcy5zbmFwc2hvdExhdGVuY3kmJih0LmdhKFwic25hcHNob3RMYXRlbmN5XCIsci5icy5PcywzNSksdC5tYSh0aGlzLnNuYXBzaG90TGF0ZW5jeSksdC55YSgpKSx0LndhKCksdC5UYSgpfSxoaXZlLnNuYXBzaG90cy5QYXJ0bmVyVHJhZmZpYz1mdW5jdGlvbih0KXt0aGlzLnAycFN1Y2NSZXE9bnVsbCx0aGlzLnAycEZhaWxSZXE9bnVsbCx0aGlzLnAycFBhcnRSZXE9bnVsbCx0aGlzLnAycFN1Y2NSZWNlaXZlZD1udWxsLHRoaXMucDJwU3VjY1JlY2VpdmVkTG93PW51bGwsdGhpcy5wMnBGYWlsUmVjZWl2ZWQ9bnVsbCx0aGlzLnAycFN1Y2NSZXNwPW51bGwsdGhpcy5wMnBGYWlsUmVzcD1udWxsLHRoaXMucDJwUGFydFJlc3A9bnVsbCx0aGlzLnAycFN1Y2NTZW50PW51bGwsdGhpcy5wMnBTdWNjU2VudExvdz1udWxsLHRoaXMucDJwRmFpbFNlbnQ9bnVsbCx0JiYodm9pZCAwIT09dC5wMnBTdWNjUmVxJiYodGhpcy5wMnBTdWNjUmVxPXQucDJwU3VjY1JlcSksdm9pZCAwIT09dC5wMnBGYWlsUmVxJiYodGhpcy5wMnBGYWlsUmVxPXQucDJwRmFpbFJlcSksdm9pZCAwIT09dC5wMnBQYXJ0UmVxJiYodGhpcy5wMnBQYXJ0UmVxPXQucDJwUGFydFJlcSksdm9pZCAwIT09dC5wMnBTdWNjUmVjZWl2ZWQmJih0aGlzLnAycFN1Y2NSZWNlaXZlZD10LnAycFN1Y2NSZWNlaXZlZCksdm9pZCAwIT09dC5wMnBTdWNjUmVjZWl2ZWRMb3cmJih0aGlzLnAycFN1Y2NSZWNlaXZlZExvdz10LnAycFN1Y2NSZWNlaXZlZExvdyksdm9pZCAwIT09dC5wMnBGYWlsUmVjZWl2ZWQmJih0aGlzLnAycEZhaWxSZWNlaXZlZD10LnAycEZhaWxSZWNlaXZlZCksdm9pZCAwIT09dC5wMnBTdWNjUmVzcCYmKHRoaXMucDJwU3VjY1Jlc3A9dC5wMnBTdWNjUmVzcCksdm9pZCAwIT09dC5wMnBGYWlsUmVzcCYmKHRoaXMucDJwRmFpbFJlc3A9dC5wMnBGYWlsUmVzcCksdm9pZCAwIT09dC5wMnBQYXJ0UmVzcCYmKHRoaXMucDJwUGFydFJlc3A9dC5wMnBQYXJ0UmVzcCksdm9pZCAwIT09dC5wMnBTdWNjU2VudCYmKHRoaXMucDJwU3VjY1NlbnQ9dC5wMnBTdWNjU2VudCksdm9pZCAwIT09dC5wMnBTdWNjU2VudExvdyYmKHRoaXMucDJwU3VjY1NlbnRMb3c9dC5wMnBTdWNjU2VudExvdyksdm9pZCAwIT09dC5wMnBGYWlsU2VudCYmKHRoaXMucDJwRmFpbFNlbnQ9dC5wMnBGYWlsU2VudCkpfSxoaXZlLnNuYXBzaG90cy5QYXJ0bmVyVHJhZmZpYy5wcm90b3R5cGU9e30saGl2ZS5zbmFwc2hvdHMuUGFydG5lclRyYWZmaWMucHJvdG90eXBlLnJlYWQ9ZnVuY3Rpb24odCl7Zm9yKHQuSGMoKTs7KXt2YXIgZT10LnNhKCksaT0oZS5CYyxlLmFhKSxuPWUuY2E7aWYoaT09ci5icy5FcylicmVhaztzd2l0Y2gobil7Y2FzZSAxOmk9PXIuYnMuUHM/dGhpcy5wMnBTdWNjUmVxPXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjppPT1yLmJzLlBzP3RoaXMucDJwRmFpbFJlcT10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM6aT09ci5icy5Qcz90aGlzLnAycFBhcnRSZXE9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA0Omk9PXIuYnMuUHM/dGhpcy5wMnBTdWNjUmVjZWl2ZWQ9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA1Omk9PXIuYnMuUHM/dGhpcy5wMnBTdWNjUmVjZWl2ZWRMb3c9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAxMDppPT1yLmJzLlBzP3RoaXMucDJwRmFpbFJlY2VpdmVkPXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNjppPT1yLmJzLlBzP3RoaXMucDJwU3VjY1Jlc3A9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAxMTppPT1yLmJzLlBzP3RoaXMucDJwRmFpbFJlc3A9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA3Omk9PXIuYnMuUHM/dGhpcy5wMnBQYXJ0UmVzcD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDg6aT09ci5icy5Qcz90aGlzLnAycFN1Y2NTZW50PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgOTppPT1yLmJzLlBzP3RoaXMucDJwU3VjY1NlbnRMb3c9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAxMjppPT1yLmJzLlBzP3RoaXMucDJwRmFpbFNlbnQ9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7ZGVmYXVsdDp0LnBhKGkpfXQubGEoKX10LmRhKCl9LGhpdmUuc25hcHNob3RzLlBhcnRuZXJUcmFmZmljLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbih0KXt0LmZhKFwiUGFydG5lclRyYWZmaWNcIiksbnVsbCE9PXRoaXMucDJwU3VjY1JlcSYmdm9pZCAwIT09dGhpcy5wMnBTdWNjUmVxJiYodC5nYShcInAycFN1Y2NSZXFcIixyLmJzLlBzLDEpLHQuQ2ModGhpcy5wMnBTdWNjUmVxKSx0LnlhKCkpLG51bGwhPT10aGlzLnAycEZhaWxSZXEmJnZvaWQgMCE9PXRoaXMucDJwRmFpbFJlcSYmKHQuZ2EoXCJwMnBGYWlsUmVxXCIsci5icy5QcywyKSx0LkNjKHRoaXMucDJwRmFpbFJlcSksdC55YSgpKSxudWxsIT09dGhpcy5wMnBQYXJ0UmVxJiZ2b2lkIDAhPT10aGlzLnAycFBhcnRSZXEmJih0LmdhKFwicDJwUGFydFJlcVwiLHIuYnMuUHMsMyksdC5DYyh0aGlzLnAycFBhcnRSZXEpLHQueWEoKSksbnVsbCE9PXRoaXMucDJwU3VjY1JlY2VpdmVkJiZ2b2lkIDAhPT10aGlzLnAycFN1Y2NSZWNlaXZlZCYmKHQuZ2EoXCJwMnBTdWNjUmVjZWl2ZWRcIixyLmJzLlBzLDQpLHQuQ2ModGhpcy5wMnBTdWNjUmVjZWl2ZWQpLHQueWEoKSksbnVsbCE9PXRoaXMucDJwU3VjY1JlY2VpdmVkTG93JiZ2b2lkIDAhPT10aGlzLnAycFN1Y2NSZWNlaXZlZExvdyYmKHQuZ2EoXCJwMnBTdWNjUmVjZWl2ZWRMb3dcIixyLmJzLlBzLDUpLHQuQ2ModGhpcy5wMnBTdWNjUmVjZWl2ZWRMb3cpLHQueWEoKSksbnVsbCE9PXRoaXMucDJwRmFpbFJlY2VpdmVkJiZ2b2lkIDAhPT10aGlzLnAycEZhaWxSZWNlaXZlZCYmKHQuZ2EoXCJwMnBGYWlsUmVjZWl2ZWRcIixyLmJzLlBzLDEwKSx0LkNjKHRoaXMucDJwRmFpbFJlY2VpdmVkKSx0LnlhKCkpLG51bGwhPT10aGlzLnAycFN1Y2NSZXNwJiZ2b2lkIDAhPT10aGlzLnAycFN1Y2NSZXNwJiYodC5nYShcInAycFN1Y2NSZXNwXCIsci5icy5Qcyw2KSx0LkNjKHRoaXMucDJwU3VjY1Jlc3ApLHQueWEoKSksbnVsbCE9PXRoaXMucDJwRmFpbFJlc3AmJnZvaWQgMCE9PXRoaXMucDJwRmFpbFJlc3AmJih0LmdhKFwicDJwRmFpbFJlc3BcIixyLmJzLlBzLDExKSx0LkNjKHRoaXMucDJwRmFpbFJlc3ApLHQueWEoKSksbnVsbCE9PXRoaXMucDJwUGFydFJlc3AmJnZvaWQgMCE9PXRoaXMucDJwUGFydFJlc3AmJih0LmdhKFwicDJwUGFydFJlc3BcIixyLmJzLlBzLDcpLHQuQ2ModGhpcy5wMnBQYXJ0UmVzcCksdC55YSgpKSxudWxsIT09dGhpcy5wMnBTdWNjU2VudCYmdm9pZCAwIT09dGhpcy5wMnBTdWNjU2VudCYmKHQuZ2EoXCJwMnBTdWNjU2VudFwiLHIuYnMuUHMsOCksdC5DYyh0aGlzLnAycFN1Y2NTZW50KSx0LnlhKCkpLG51bGwhPT10aGlzLnAycFN1Y2NTZW50TG93JiZ2b2lkIDAhPT10aGlzLnAycFN1Y2NTZW50TG93JiYodC5nYShcInAycFN1Y2NTZW50TG93XCIsci5icy5Qcyw5KSx0LkNjKHRoaXMucDJwU3VjY1NlbnRMb3cpLHQueWEoKSksbnVsbCE9PXRoaXMucDJwRmFpbFNlbnQmJnZvaWQgMCE9PXRoaXMucDJwRmFpbFNlbnQmJih0LmdhKFwicDJwRmFpbFNlbnRcIixyLmJzLlBzLDEyKSx0LkNjKHRoaXMucDJwRmFpbFNlbnQpLHQueWEoKSksdC53YSgpLHQuVGEoKX0saGl2ZS5zbmFwc2hvdHMuUGFydG5lck1ldHJpY3M9ZnVuY3Rpb24odCl7dGhpcy5yYXRlUmVjZWl2ZWQ9bnVsbCx0aGlzLnJhdGVTZW50PW51bGwsdGhpcy5oYW5kc2hha2VEZWxheT1udWxsLHQmJih2b2lkIDAhPT10LnJhdGVSZWNlaXZlZCYmKHRoaXMucmF0ZVJlY2VpdmVkPXQucmF0ZVJlY2VpdmVkKSx2b2lkIDAhPT10LnJhdGVTZW50JiYodGhpcy5yYXRlU2VudD10LnJhdGVTZW50KSx2b2lkIDAhPT10LmhhbmRzaGFrZURlbGF5JiYodGhpcy5oYW5kc2hha2VEZWxheT10LmhhbmRzaGFrZURlbGF5KSl9LGhpdmUuc25hcHNob3RzLlBhcnRuZXJNZXRyaWNzLnByb3RvdHlwZT17fSxoaXZlLnNuYXBzaG90cy5QYXJ0bmVyTWV0cmljcy5wcm90b3R5cGUucmVhZD1mdW5jdGlvbih0KXtmb3IodC5IYygpOzspe3ZhciBlPXQuc2EoKSxpPShlLkJjLGUuYWEpLG49ZS5jYTtpZihpPT1yLmJzLkVzKWJyZWFrO3N3aXRjaChuKXtjYXNlIDE6aT09ci5icy5rcz90aGlzLnJhdGVSZWNlaXZlZD10LlljKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI6aT09ci5icy5rcz90aGlzLnJhdGVTZW50PXQuWWMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzppPT1yLmJzLlBzP3RoaXMuaGFuZHNoYWtlRGVsYXk9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7ZGVmYXVsdDp0LnBhKGkpfXQubGEoKX10LmRhKCl9LGhpdmUuc25hcHNob3RzLlBhcnRuZXJNZXRyaWNzLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbih0KXt0LmZhKFwiUGFydG5lck1ldHJpY3NcIiksbnVsbCE9PXRoaXMucmF0ZVJlY2VpdmVkJiZ2b2lkIDAhPT10aGlzLnJhdGVSZWNlaXZlZCYmKHQuZ2EoXCJyYXRlUmVjZWl2ZWRcIixyLmJzLmtzLDEpLHQuT2ModGhpcy5yYXRlUmVjZWl2ZWQpLHQueWEoKSksbnVsbCE9PXRoaXMucmF0ZVNlbnQmJnZvaWQgMCE9PXRoaXMucmF0ZVNlbnQmJih0LmdhKFwicmF0ZVNlbnRcIixyLmJzLmtzLDIpLHQuT2ModGhpcy5yYXRlU2VudCksdC55YSgpKSxudWxsIT09dGhpcy5oYW5kc2hha2VEZWxheSYmdm9pZCAwIT09dGhpcy5oYW5kc2hha2VEZWxheSYmKHQuZ2EoXCJoYW5kc2hha2VEZWxheVwiLHIuYnMuUHMsMyksdC5DYyh0aGlzLmhhbmRzaGFrZURlbGF5KSx0LnlhKCkpLHQud2EoKSx0LlRhKCl9LGhpdmUuc25hcHNob3RzLkNvbm5lY3Rpdml0eUluZm89ZnVuY3Rpb24odCl7dGhpcy51cEJXPW51bGwsdGhpcy5kb3duQlc9bnVsbCx0aGlzLmV4dGVybmFsQXM9bnVsbCx0aGlzLmludGVybmFsQXM9bnVsbCx0aGlzLnB1YmxpY0lwPW51bGwsdGhpcy5wcml2YXRlSXA9bnVsbCx0JiYodm9pZCAwIT09dC51cEJXJiYodGhpcy51cEJXPXQudXBCVyksdm9pZCAwIT09dC5kb3duQlcmJih0aGlzLmRvd25CVz10LmRvd25CVyksdm9pZCAwIT09dC5leHRlcm5hbEFzJiYodGhpcy5leHRlcm5hbEFzPXQuZXh0ZXJuYWxBcyksdm9pZCAwIT09dC5pbnRlcm5hbEFzJiYodGhpcy5pbnRlcm5hbEFzPXQuaW50ZXJuYWxBcyksdm9pZCAwIT09dC5wdWJsaWNJcCYmKHRoaXMucHVibGljSXA9dC5wdWJsaWNJcCksdm9pZCAwIT09dC5wcml2YXRlSXAmJih0aGlzLnByaXZhdGVJcD10LnByaXZhdGVJcCkpfSxoaXZlLnNuYXBzaG90cy5Db25uZWN0aXZpdHlJbmZvLnByb3RvdHlwZT17fSxoaXZlLnNuYXBzaG90cy5Db25uZWN0aXZpdHlJbmZvLnByb3RvdHlwZS5yZWFkPWZ1bmN0aW9uKHQpe2Zvcih0LkhjKCk7Oyl7dmFyIGU9dC5zYSgpLGk9KGUuQmMsZS5hYSksbj1lLmNhO2lmKGk9PXIuYnMuRXMpYnJlYWs7c3dpdGNoKG4pe2Nhc2UgMTppPT1yLmJzLk9zP3RoaXMudXBCVz10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI6aT09ci5icy5Pcz90aGlzLmRvd25CVz10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM6aT09ci5icy5Pcz90aGlzLmV4dGVybmFsQXM9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA0Omk9PXIuYnMuT3M/dGhpcy5pbnRlcm5hbEFzPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNTppPT1yLmJzLkFzP3RoaXMucHVibGljSXA9dC5oYSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA2Omk9PXIuYnMuQXM/dGhpcy5wcml2YXRlSXA9dC5oYSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7ZGVmYXVsdDp0LnBhKGkpfXQubGEoKX10LmRhKCl9LGhpdmUuc25hcHNob3RzLkNvbm5lY3Rpdml0eUluZm8ucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKHQpe3QuZmEoXCJDb25uZWN0aXZpdHlJbmZvXCIpLG51bGwhPT10aGlzLnVwQlcmJnZvaWQgMCE9PXRoaXMudXBCVyYmKHQuZ2EoXCJ1cEJXXCIsci5icy5PcywxKSx0Lm1hKHRoaXMudXBCVyksdC55YSgpKSxudWxsIT09dGhpcy5kb3duQlcmJnZvaWQgMCE9PXRoaXMuZG93bkJXJiYodC5nYShcImRvd25CV1wiLHIuYnMuT3MsMiksdC5tYSh0aGlzLmRvd25CVyksdC55YSgpKSxudWxsIT09dGhpcy5leHRlcm5hbEFzJiZ2b2lkIDAhPT10aGlzLmV4dGVybmFsQXMmJih0LmdhKFwiZXh0ZXJuYWxBc1wiLHIuYnMuT3MsMyksdC5tYSh0aGlzLmV4dGVybmFsQXMpLHQueWEoKSksbnVsbCE9PXRoaXMuaW50ZXJuYWxBcyYmdm9pZCAwIT09dGhpcy5pbnRlcm5hbEFzJiYodC5nYShcImludGVybmFsQXNcIixyLmJzLk9zLDQpLHQubWEodGhpcy5pbnRlcm5hbEFzKSx0LnlhKCkpLG51bGwhPT10aGlzLnB1YmxpY0lwJiZ2b2lkIDAhPT10aGlzLnB1YmxpY0lwJiYodC5nYShcInB1YmxpY0lwXCIsci5icy5Bcyw1KSx0LnZhKHRoaXMucHVibGljSXApLHQueWEoKSksbnVsbCE9PXRoaXMucHJpdmF0ZUlwJiZ2b2lkIDAhPT10aGlzLnByaXZhdGVJcCYmKHQuZ2EoXCJwcml2YXRlSXBcIixyLmJzLkFzLDYpLHQudmEodGhpcy5wcml2YXRlSXApLHQueWEoKSksdC53YSgpLHQuVGEoKX0saGl2ZS5zbmFwc2hvdHMuUGFydG5lcj1mdW5jdGlvbih0KXt0aGlzLmNvbm5JbmZvPW51bGwsdGhpcy50cmFmZmljPW51bGwsdGhpcy5tZXRyaWNzPW51bGwsdGhpcy5pblBhcnQ9bnVsbCx0aGlzLm91dFBhcnQ9bnVsbCx0aGlzLnVkcD1udWxsLHQmJih2b2lkIDAhPT10LmNvbm5JbmZvJiYodGhpcy5jb25uSW5mbz10LmNvbm5JbmZvKSx2b2lkIDAhPT10LnRyYWZmaWMmJih0aGlzLnRyYWZmaWM9dC50cmFmZmljKSx2b2lkIDAhPT10Lm1ldHJpY3MmJih0aGlzLm1ldHJpY3M9dC5tZXRyaWNzKSx2b2lkIDAhPT10LmluUGFydCYmKHRoaXMuaW5QYXJ0PXQuaW5QYXJ0KSx2b2lkIDAhPT10Lm91dFBhcnQmJih0aGlzLm91dFBhcnQ9dC5vdXRQYXJ0KSx2b2lkIDAhPT10LnVkcCYmKHRoaXMudWRwPXQudWRwKSl9LGhpdmUuc25hcHNob3RzLlBhcnRuZXIucHJvdG90eXBlPXt9LGhpdmUuc25hcHNob3RzLlBhcnRuZXIucHJvdG90eXBlLnJlYWQ9ZnVuY3Rpb24odCl7Zm9yKHQuSGMoKTs7KXt2YXIgZT10LnNhKCksaT0oZS5CYyxlLmFhKSxuPWUuY2E7aWYoaT09ci5icy5FcylicmVhaztzd2l0Y2gobil7Y2FzZSAxOmk9PXIuYnMueHM/KHRoaXMuY29ubkluZm89bmV3IGhpdmUuc25hcHNob3RzLkNvbm5lY3Rpdml0eUluZm8sdGhpcy5jb25uSW5mby5yZWFkKHQpKTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjppPT1yLmJzLnhzPyh0aGlzLnRyYWZmaWM9bmV3IGhpdmUuc25hcHNob3RzLlBhcnRuZXJUcmFmZmljLHRoaXMudHJhZmZpYy5yZWFkKHQpKTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzppPT1yLmJzLnhzPyh0aGlzLm1ldHJpY3M9bmV3IGhpdmUuc25hcHNob3RzLlBhcnRuZXJNZXRyaWNzLHRoaXMubWV0cmljcy5yZWFkKHQpKTp0LnBhKGkpO2JyZWFrO2Nhc2UgNDppPT1yLmJzLkJPT0w/dGhpcy5pblBhcnQ9dC5HYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA1Omk9PXIuYnMuQk9PTD90aGlzLm91dFBhcnQ9dC5HYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA2Omk9PXIuYnMuQk9PTD90aGlzLnVkcD10LkdjKCkudmFsdWU6dC5wYShpKTticmVhaztkZWZhdWx0OnQucGEoaSl9dC5sYSgpfXQuZGEoKX0saGl2ZS5zbmFwc2hvdHMuUGFydG5lci5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24odCl7dC5mYShcIlBhcnRuZXJcIiksbnVsbCE9PXRoaXMuY29ubkluZm8mJnZvaWQgMCE9PXRoaXMuY29ubkluZm8mJih0LmdhKFwiY29ubkluZm9cIixyLmJzLnhzLDEpLHRoaXMuY29ubkluZm8ud3JpdGUodCksdC55YSgpKSxudWxsIT09dGhpcy50cmFmZmljJiZ2b2lkIDAhPT10aGlzLnRyYWZmaWMmJih0LmdhKFwidHJhZmZpY1wiLHIuYnMueHMsMiksdGhpcy50cmFmZmljLndyaXRlKHQpLHQueWEoKSksbnVsbCE9PXRoaXMubWV0cmljcyYmdm9pZCAwIT09dGhpcy5tZXRyaWNzJiYodC5nYShcIm1ldHJpY3NcIixyLmJzLnhzLDMpLHRoaXMubWV0cmljcy53cml0ZSh0KSx0LnlhKCkpLG51bGwhPT10aGlzLmluUGFydCYmdm9pZCAwIT09dGhpcy5pblBhcnQmJih0LmdhKFwiaW5QYXJ0XCIsci5icy5CT09MLDQpLHQuSWModGhpcy5pblBhcnQpLHQueWEoKSksbnVsbCE9PXRoaXMub3V0UGFydCYmdm9pZCAwIT09dGhpcy5vdXRQYXJ0JiYodC5nYShcIm91dFBhcnRcIixyLmJzLkJPT0wsNSksdC5JYyh0aGlzLm91dFBhcnQpLHQueWEoKSksbnVsbCE9PXRoaXMudWRwJiZ2b2lkIDAhPT10aGlzLnVkcCYmKHQuZ2EoXCJ1ZHBcIixyLmJzLkJPT0wsNiksdC5JYyh0aGlzLnVkcCksdC55YSgpKSx0LndhKCksdC5UYSgpfSxoaXZlLnNuYXBzaG90cy5TdHJlYW1JbmZvPWZ1bmN0aW9uKHQpe3RoaXMudXJsPW51bGwsdGhpcy5zdHJlYW1UeXBlPW51bGwsdGhpcy5zdHJlYW1Qcm90b2NvbD1udWxsLHQmJih2b2lkIDAhPT10LnVybCYmKHRoaXMudXJsPXQudXJsKSx2b2lkIDAhPT10LnN0cmVhbVR5cGUmJih0aGlzLnN0cmVhbVR5cGU9dC5zdHJlYW1UeXBlKSx2b2lkIDAhPT10LnN0cmVhbVByb3RvY29sJiYodGhpcy5zdHJlYW1Qcm90b2NvbD10LnN0cmVhbVByb3RvY29sKSl9LGhpdmUuc25hcHNob3RzLlN0cmVhbUluZm8ucHJvdG90eXBlPXt9LGhpdmUuc25hcHNob3RzLlN0cmVhbUluZm8ucHJvdG90eXBlLnJlYWQ9ZnVuY3Rpb24odCl7Zm9yKHQuSGMoKTs7KXt2YXIgZT10LnNhKCksaT0oZS5CYyxlLmFhKSxuPWUuY2E7aWYoaT09ci5icy5FcylicmVhaztzd2l0Y2gobil7Y2FzZSAxOmk9PXIuYnMuQXM/dGhpcy51cmw9dC5oYSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyOmk9PXIuYnMuT3M/dGhpcy5zdHJlYW1UeXBlPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzppPT1yLmJzLk9zP3RoaXMuc3RyZWFtUHJvdG9jb2w9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7ZGVmYXVsdDp0LnBhKGkpfXQubGEoKX10LmRhKCl9LGhpdmUuc25hcHNob3RzLlN0cmVhbUluZm8ucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKHQpe3QuZmEoXCJTdHJlYW1JbmZvXCIpLG51bGwhPT10aGlzLnVybCYmdm9pZCAwIT09dGhpcy51cmwmJih0LmdhKFwidXJsXCIsci5icy5BcywxKSx0LnZhKHRoaXMudXJsKSx0LnlhKCkpLG51bGwhPT10aGlzLnN0cmVhbVR5cGUmJnZvaWQgMCE9PXRoaXMuc3RyZWFtVHlwZSYmKHQuZ2EoXCJzdHJlYW1UeXBlXCIsci5icy5PcywyKSx0Lm1hKHRoaXMuc3RyZWFtVHlwZSksdC55YSgpKSxudWxsIT09dGhpcy5zdHJlYW1Qcm90b2NvbCYmdm9pZCAwIT09dGhpcy5zdHJlYW1Qcm90b2NvbCYmKHQuZ2EoXCJzdHJlYW1Qcm90b2NvbFwiLHIuYnMuT3MsMyksdC5tYSh0aGlzLnN0cmVhbVByb3RvY29sKSx0LnlhKCkpLHQud2EoKSx0LlRhKCl9LGhpdmUuc25hcHNob3RzLkNsaWVudEluZm89ZnVuY3Rpb24odCl7dGhpcy5jbGllbnRUeXBlPW51bGwsdGhpcy5tYWpvclZlcnNpb249bnVsbCx0aGlzLm1pbm9yVmVyc2lvbj1udWxsLHRoaXMucGF0Y2hWZXJzaW9uPW51bGwsdCYmKHZvaWQgMCE9PXQuY2xpZW50VHlwZSYmKHRoaXMuY2xpZW50VHlwZT10LmNsaWVudFR5cGUpLHZvaWQgMCE9PXQubWFqb3JWZXJzaW9uJiYodGhpcy5tYWpvclZlcnNpb249dC5tYWpvclZlcnNpb24pLHZvaWQgMCE9PXQubWlub3JWZXJzaW9uJiYodGhpcy5taW5vclZlcnNpb249dC5taW5vclZlcnNpb24pLHZvaWQgMCE9PXQucGF0Y2hWZXJzaW9uJiYodGhpcy5wYXRjaFZlcnNpb249dC5wYXRjaFZlcnNpb24pKX0saGl2ZS5zbmFwc2hvdHMuQ2xpZW50SW5mby5wcm90b3R5cGU9e30saGl2ZS5zbmFwc2hvdHMuQ2xpZW50SW5mby5wcm90b3R5cGUucmVhZD1mdW5jdGlvbih0KXtmb3IodC5IYygpOzspe3ZhciBlPXQuc2EoKSxpPShlLkJjLGUuYWEpLG49ZS5jYTtpZihpPT1yLmJzLkVzKWJyZWFrO3N3aXRjaChuKXtjYXNlIDE6aT09ci5icy5Pcz90aGlzLmNsaWVudFR5cGU9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyOmk9PXIuYnMuQllURT90aGlzLm1ham9yVmVyc2lvbj10LnpjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM6aT09ci5icy5CWVRFP3RoaXMubWlub3JWZXJzaW9uPXQuemMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNDppPT1yLmJzLkNzP3RoaXMucGF0Y2hWZXJzaW9uPXQuV2MoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2RlZmF1bHQ6dC5wYShpKX10LmxhKCl9dC5kYSgpfSxoaXZlLnNuYXBzaG90cy5DbGllbnRJbmZvLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbih0KXt0LmZhKFwiQ2xpZW50SW5mb1wiKSxudWxsIT09dGhpcy5jbGllbnRUeXBlJiZ2b2lkIDAhPT10aGlzLmNsaWVudFR5cGUmJih0LmdhKFwiY2xpZW50VHlwZVwiLHIuYnMuT3MsMSksdC5tYSh0aGlzLmNsaWVudFR5cGUpLHQueWEoKSksbnVsbCE9PXRoaXMubWFqb3JWZXJzaW9uJiZ2b2lkIDAhPT10aGlzLm1ham9yVmVyc2lvbiYmKHQuZ2EoXCJtYWpvclZlcnNpb25cIixyLmJzLkJZVEUsMiksdC5SYyh0aGlzLm1ham9yVmVyc2lvbiksdC55YSgpKSxudWxsIT09dGhpcy5taW5vclZlcnNpb24mJnZvaWQgMCE9PXRoaXMubWlub3JWZXJzaW9uJiYodC5nYShcIm1pbm9yVmVyc2lvblwiLHIuYnMuQllURSwzKSx0LlJjKHRoaXMubWlub3JWZXJzaW9uKSx0LnlhKCkpLG51bGwhPT10aGlzLnBhdGNoVmVyc2lvbiYmdm9pZCAwIT09dGhpcy5wYXRjaFZlcnNpb24mJih0LmdhKFwicGF0Y2hWZXJzaW9uXCIsci5icy5Dcyw0KSx0LmtjKHRoaXMucGF0Y2hWZXJzaW9uKSx0LnlhKCkpLHQud2EoKSx0LlRhKCl9LGhpdmUuc25hcHNob3RzLkFnZW50SW5mbz1mdW5jdGlvbih0KXt0aGlzLmZpcnN0VGllckJpdHJhdGVzPW51bGwsdGhpcy5zZWNvbmRUaWVyQml0cmF0ZXM9bnVsbCx0JiYodm9pZCAwIT09dC5maXJzdFRpZXJCaXRyYXRlcyYmKHRoaXMuZmlyc3RUaWVyQml0cmF0ZXM9dC5maXJzdFRpZXJCaXRyYXRlcyksdm9pZCAwIT09dC5zZWNvbmRUaWVyQml0cmF0ZXMmJih0aGlzLnNlY29uZFRpZXJCaXRyYXRlcz10LnNlY29uZFRpZXJCaXRyYXRlcykpfSxoaXZlLnNuYXBzaG90cy5BZ2VudEluZm8ucHJvdG90eXBlPXt9LGhpdmUuc25hcHNob3RzLkFnZW50SW5mby5wcm90b3R5cGUucmVhZD1mdW5jdGlvbih0KXtmb3IodC5IYygpOzspe3ZhciBlPXQuc2EoKSxpPShlLkJjLGUuYWEpLG49ZS5jYTtpZihpPT1yLmJzLkVzKWJyZWFrO3N3aXRjaChuKXtjYXNlIDE6aWYoaT09ci5icy5Gcyl7dmFyIG8scz0wO3RoaXMuZmlyc3RUaWVyQml0cmF0ZXM9W107dmFyIGE9MDtvPXQuSmMoKSxhPW8uUWMscz1vLnNpemU7Zm9yKHZhciBjPTA7YzxzOysrYyl7dmFyIGg9bnVsbDtoPXQudWEoKS52YWx1ZSx0aGlzLmZpcnN0VGllckJpdHJhdGVzLnB1c2goaCl9dC5LYygpfWVsc2UgdC5wYShpKTticmVhaztjYXNlIDI6aWYoaT09ci5icy5Gcyl7dmFyIHAsdT0wO3RoaXMuc2Vjb25kVGllckJpdHJhdGVzPVtdO3ZhciBsPTA7cD10LkpjKCksbD1wLlFjLHU9cC5zaXplO2Zvcih2YXIgZD0wO2Q8dTsrK2Qpe3ZhciBmPW51bGw7Zj10LnVhKCkudmFsdWUsdGhpcy5zZWNvbmRUaWVyQml0cmF0ZXMucHVzaChmKX10LktjKCl9ZWxzZSB0LnBhKGkpO2JyZWFrO2RlZmF1bHQ6dC5wYShpKX10LmxhKCl9dC5kYSgpfSxoaXZlLnNuYXBzaG90cy5BZ2VudEluZm8ucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKHQpe1xuICBpZih0LmZhKFwiQWdlbnRJbmZvXCIpLG51bGwhPT10aGlzLmZpcnN0VGllckJpdHJhdGVzJiZ2b2lkIDAhPT10aGlzLmZpcnN0VGllckJpdHJhdGVzKXt0LmdhKFwiZmlyc3RUaWVyQml0cmF0ZXNcIixyLmJzLkZzLDEpLHQuYmMoci5icy5Pcyx0aGlzLmZpcnN0VGllckJpdHJhdGVzLmxlbmd0aCk7Zm9yKHZhciBlIGluIHRoaXMuZmlyc3RUaWVyQml0cmF0ZXMpdGhpcy5maXJzdFRpZXJCaXRyYXRlcy5oYXNPd25Qcm9wZXJ0eShlKSYmKGU9dGhpcy5maXJzdFRpZXJCaXRyYXRlc1tlXSx0Lm1hKGUpKTt0LkVjKCksdC55YSgpfWlmKG51bGwhPT10aGlzLnNlY29uZFRpZXJCaXRyYXRlcyYmdm9pZCAwIT09dGhpcy5zZWNvbmRUaWVyQml0cmF0ZXMpe3QuZ2EoXCJzZWNvbmRUaWVyQml0cmF0ZXNcIixyLmJzLkZzLDIpLHQuYmMoci5icy5Pcyx0aGlzLnNlY29uZFRpZXJCaXRyYXRlcy5sZW5ndGgpO2Zvcih2YXIgaSBpbiB0aGlzLnNlY29uZFRpZXJCaXRyYXRlcyl0aGlzLnNlY29uZFRpZXJCaXRyYXRlcy5oYXNPd25Qcm9wZXJ0eShpKSYmKGk9dGhpcy5zZWNvbmRUaWVyQml0cmF0ZXNbaV0sdC5tYShpKSk7dC5FYygpLHQueWEoKX10LndhKCksdC5UYSgpfSxoaXZlLnNuYXBzaG90cy5UcmFmZmljS2V5PWZ1bmN0aW9uKHQpe3RoaXMuYml0cmF0ZT1udWxsLHRoaXMuQVM9bnVsbCx0aGlzLnBhcnRuZXJHdWlkPW51bGwsdCYmKHZvaWQgMCE9PXQuYml0cmF0ZSYmKHRoaXMuYml0cmF0ZT10LmJpdHJhdGUpLHZvaWQgMCE9PXQuQVMmJih0aGlzLkFTPXQuQVMpLHZvaWQgMCE9PXQucGFydG5lckd1aWQmJih0aGlzLnBhcnRuZXJHdWlkPXQucGFydG5lckd1aWQpKX0saGl2ZS5zbmFwc2hvdHMuVHJhZmZpY0tleS5wcm90b3R5cGU9e30saGl2ZS5zbmFwc2hvdHMuVHJhZmZpY0tleS5wcm90b3R5cGUucmVhZD1mdW5jdGlvbih0KXtmb3IodC5IYygpOzspe3ZhciBlPXQuc2EoKSxpPShlLkJjLGUuYWEpLG49ZS5jYTtpZihpPT1yLmJzLkVzKWJyZWFrO3N3aXRjaChuKXtjYXNlIDE6aT09ci5icy5Pcz90aGlzLmJpdHJhdGU9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyOmk9PXIuYnMuT3M/dGhpcy5BUz10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM6aT09ci5icy5Bcz90aGlzLnBhcnRuZXJHdWlkPXQuaGEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2RlZmF1bHQ6dC5wYShpKX10LmxhKCl9dC5kYSgpfSxoaXZlLnNuYXBzaG90cy5UcmFmZmljS2V5LnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbih0KXt0LmZhKFwiVHJhZmZpY0tleVwiKSxudWxsIT09dGhpcy5iaXRyYXRlJiZ2b2lkIDAhPT10aGlzLmJpdHJhdGUmJih0LmdhKFwiYml0cmF0ZVwiLHIuYnMuT3MsMSksdC5tYSh0aGlzLmJpdHJhdGUpLHQueWEoKSksbnVsbCE9PXRoaXMuQVMmJnZvaWQgMCE9PXRoaXMuQVMmJih0LmdhKFwiQVNcIixyLmJzLk9zLDIpLHQubWEodGhpcy5BUyksdC55YSgpKSxudWxsIT09dGhpcy5wYXJ0bmVyR3VpZCYmdm9pZCAwIT09dGhpcy5wYXJ0bmVyR3VpZCYmKHQuZ2EoXCJwYXJ0bmVyR3VpZFwiLHIuYnMuQXMsMyksdC52YSh0aGlzLnBhcnRuZXJHdWlkKSx0LnlhKCkpLHQud2EoKSx0LlRhKCl9LGhpdmUuc25hcHNob3RzLlBhcnRuZXJLZXk9ZnVuY3Rpb24odCl7dGhpcy5iaXRyYXRlPW51bGwsdGhpcy5BUz1udWxsLHRoaXMucGFydG5lckd1aWQ9bnVsbCx0JiYodm9pZCAwIT09dC5iaXRyYXRlJiYodGhpcy5iaXRyYXRlPXQuYml0cmF0ZSksdm9pZCAwIT09dC5BUyYmKHRoaXMuQVM9dC5BUyksdm9pZCAwIT09dC5wYXJ0bmVyR3VpZCYmKHRoaXMucGFydG5lckd1aWQ9dC5wYXJ0bmVyR3VpZCkpfSxoaXZlLnNuYXBzaG90cy5QYXJ0bmVyS2V5LnByb3RvdHlwZT17fSxoaXZlLnNuYXBzaG90cy5QYXJ0bmVyS2V5LnByb3RvdHlwZS5yZWFkPWZ1bmN0aW9uKHQpe2Zvcih0LkhjKCk7Oyl7dmFyIGU9dC5zYSgpLGk9KGUuQmMsZS5hYSksbj1lLmNhO2lmKGk9PXIuYnMuRXMpYnJlYWs7c3dpdGNoKG4pe2Nhc2UgMTppPT1yLmJzLk9zP3RoaXMuYml0cmF0ZT10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI6aT09ci5icy5Pcz90aGlzLkFTPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzppPT1yLmJzLkFzP3RoaXMucGFydG5lckd1aWQ9dC5oYSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7ZGVmYXVsdDp0LnBhKGkpfXQubGEoKX10LmRhKCl9LGhpdmUuc25hcHNob3RzLlBhcnRuZXJLZXkucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKHQpe3QuZmEoXCJQYXJ0bmVyS2V5XCIpLG51bGwhPT10aGlzLmJpdHJhdGUmJnZvaWQgMCE9PXRoaXMuYml0cmF0ZSYmKHQuZ2EoXCJiaXRyYXRlXCIsci5icy5PcywxKSx0Lm1hKHRoaXMuYml0cmF0ZSksdC55YSgpKSxudWxsIT09dGhpcy5BUyYmdm9pZCAwIT09dGhpcy5BUyYmKHQuZ2EoXCJBU1wiLHIuYnMuT3MsMiksdC5tYSh0aGlzLkFTKSx0LnlhKCkpLG51bGwhPT10aGlzLnBhcnRuZXJHdWlkJiZ2b2lkIDAhPT10aGlzLnBhcnRuZXJHdWlkJiYodC5nYShcInBhcnRuZXJHdWlkXCIsci5icy5BcywzKSx0LnZhKHRoaXMucGFydG5lckd1aWQpLHQueWEoKSksdC53YSgpLHQuVGEoKX0saGl2ZS5zbmFwc2hvdHMuUGxheWVyPWZ1bmN0aW9uKHQpe3RoaXMuYnVmZmVyaW5nTj1udWxsLHRoaXMuYnVmZmVyaW5nTXM9bnVsbCx0aGlzLmluaXRCdWZmZXJpbmdOPW51bGwsdGhpcy5pbml0QnVmZmVyaW5nTXM9bnVsbCx0aGlzLnNlZWtCdWZmZXJpbmdOPW51bGwsdGhpcy5zZWVrQnVmZmVyaW5nTXM9bnVsbCx0aGlzLnBsYXllckJ1ZmZlck1zPW51bGwsdCYmKHZvaWQgMCE9PXQuYnVmZmVyaW5nTiYmKHRoaXMuYnVmZmVyaW5nTj10LmJ1ZmZlcmluZ04pLHZvaWQgMCE9PXQuYnVmZmVyaW5nTXMmJih0aGlzLmJ1ZmZlcmluZ01zPXQuYnVmZmVyaW5nTXMpLHZvaWQgMCE9PXQuaW5pdEJ1ZmZlcmluZ04mJih0aGlzLmluaXRCdWZmZXJpbmdOPXQuaW5pdEJ1ZmZlcmluZ04pLHZvaWQgMCE9PXQuaW5pdEJ1ZmZlcmluZ01zJiYodGhpcy5pbml0QnVmZmVyaW5nTXM9dC5pbml0QnVmZmVyaW5nTXMpLHZvaWQgMCE9PXQuc2Vla0J1ZmZlcmluZ04mJih0aGlzLnNlZWtCdWZmZXJpbmdOPXQuc2Vla0J1ZmZlcmluZ04pLHZvaWQgMCE9PXQuc2Vla0J1ZmZlcmluZ01zJiYodGhpcy5zZWVrQnVmZmVyaW5nTXM9dC5zZWVrQnVmZmVyaW5nTXMpLHZvaWQgMCE9PXQucGxheWVyQnVmZmVyTXMmJih0aGlzLnBsYXllckJ1ZmZlck1zPXQucGxheWVyQnVmZmVyTXMpKX0saGl2ZS5zbmFwc2hvdHMuUGxheWVyLnByb3RvdHlwZT17fSxoaXZlLnNuYXBzaG90cy5QbGF5ZXIucHJvdG90eXBlLnJlYWQ9ZnVuY3Rpb24odCl7Zm9yKHQuSGMoKTs7KXt2YXIgZT10LnNhKCksaT0oZS5CYyxlLmFhKSxuPWUuY2E7aWYoaT09ci5icy5FcylicmVhaztzd2l0Y2gobil7Y2FzZSAxOmk9PXIuYnMuQ3M/dGhpcy5idWZmZXJpbmdOPXQuV2MoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjppPT1yLmJzLk9zP3RoaXMuYnVmZmVyaW5nTXM9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzOmk9PXIuYnMuQ3M/dGhpcy5pbml0QnVmZmVyaW5nTj10LldjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDQ6aT09ci5icy5Pcz90aGlzLmluaXRCdWZmZXJpbmdNcz10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDU6aT09ci5icy5Dcz90aGlzLnNlZWtCdWZmZXJpbmdOPXQuV2MoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNjppPT1yLmJzLk9zP3RoaXMuc2Vla0J1ZmZlcmluZ01zPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzY6aT09ci5icy5Pcz90aGlzLnBsYXllckJ1ZmZlck1zPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2RlZmF1bHQ6dC5wYShpKX10LmxhKCl9dC5kYSgpfSxoaXZlLnNuYXBzaG90cy5QbGF5ZXIucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKHQpe3QuZmEoXCJQbGF5ZXJcIiksbnVsbCE9PXRoaXMuYnVmZmVyaW5nTiYmdm9pZCAwIT09dGhpcy5idWZmZXJpbmdOJiYodC5nYShcImJ1ZmZlcmluZ05cIixyLmJzLkNzLDEpLHQua2ModGhpcy5idWZmZXJpbmdOKSx0LnlhKCkpLG51bGwhPT10aGlzLmJ1ZmZlcmluZ01zJiZ2b2lkIDAhPT10aGlzLmJ1ZmZlcmluZ01zJiYodC5nYShcImJ1ZmZlcmluZ01zXCIsci5icy5PcywyKSx0Lm1hKHRoaXMuYnVmZmVyaW5nTXMpLHQueWEoKSksbnVsbCE9PXRoaXMuaW5pdEJ1ZmZlcmluZ04mJnZvaWQgMCE9PXRoaXMuaW5pdEJ1ZmZlcmluZ04mJih0LmdhKFwiaW5pdEJ1ZmZlcmluZ05cIixyLmJzLkNzLDMpLHQua2ModGhpcy5pbml0QnVmZmVyaW5nTiksdC55YSgpKSxudWxsIT09dGhpcy5pbml0QnVmZmVyaW5nTXMmJnZvaWQgMCE9PXRoaXMuaW5pdEJ1ZmZlcmluZ01zJiYodC5nYShcImluaXRCdWZmZXJpbmdNc1wiLHIuYnMuT3MsNCksdC5tYSh0aGlzLmluaXRCdWZmZXJpbmdNcyksdC55YSgpKSxudWxsIT09dGhpcy5zZWVrQnVmZmVyaW5nTiYmdm9pZCAwIT09dGhpcy5zZWVrQnVmZmVyaW5nTiYmKHQuZ2EoXCJzZWVrQnVmZmVyaW5nTlwiLHIuYnMuQ3MsNSksdC5rYyh0aGlzLnNlZWtCdWZmZXJpbmdOKSx0LnlhKCkpLG51bGwhPT10aGlzLnNlZWtCdWZmZXJpbmdNcyYmdm9pZCAwIT09dGhpcy5zZWVrQnVmZmVyaW5nTXMmJih0LmdhKFwic2Vla0J1ZmZlcmluZ01zXCIsci5icy5Pcyw2KSx0Lm1hKHRoaXMuc2Vla0J1ZmZlcmluZ01zKSx0LnlhKCkpLG51bGwhPT10aGlzLnBsYXllckJ1ZmZlck1zJiZ2b2lkIDAhPT10aGlzLnBsYXllckJ1ZmZlck1zJiYodC5nYShcInBsYXllckJ1ZmZlck1zXCIsci5icy5PcywzNiksdC5tYSh0aGlzLnBsYXllckJ1ZmZlck1zKSx0LnlhKCkpLHQud2EoKSx0LlRhKCl9LGhpdmUuc25hcHNob3RzLk1ldHJpY1NuYXBzaG90PWZ1bmN0aW9uKHQpe3RoaXMudGltZXN0YW1wPW51bGwsdGhpcy5ndWlkPW51bGwsdGhpcy5ldmVudElkPW51bGwsdGhpcy5zdHJlYW1JbmZvPW51bGwsdGhpcy5tZXRyaWNzPW51bGwsdGhpcy50cmFmZmljPW51bGwsdGhpcy5zbmFwc2hvdEluZm89bnVsbCx0aGlzLmFnZW50SW5mbz1udWxsLHRoaXMuY29ubkluZm89bnVsbCx0aGlzLnBhcnRuZXJzPW51bGwsdGhpcy5wbGF5ZXI9bnVsbCx0aGlzLmNsaWVudD1udWxsLHRoaXMuc2Vzc2lvbklkPW51bGwsdCYmKHZvaWQgMCE9PXQudGltZXN0YW1wJiYodGhpcy50aW1lc3RhbXA9dC50aW1lc3RhbXApLHZvaWQgMCE9PXQuZ3VpZCYmKHRoaXMuZ3VpZD10Lmd1aWQpLHZvaWQgMCE9PXQuZXZlbnRJZCYmKHRoaXMuZXZlbnRJZD10LmV2ZW50SWQpLHZvaWQgMCE9PXQuc3RyZWFtSW5mbyYmKHRoaXMuc3RyZWFtSW5mbz10LnN0cmVhbUluZm8pLHZvaWQgMCE9PXQubWV0cmljcyYmKHRoaXMubWV0cmljcz10Lm1ldHJpY3MpLHZvaWQgMCE9PXQudHJhZmZpYyYmKHRoaXMudHJhZmZpYz10LnRyYWZmaWMpLHZvaWQgMCE9PXQuc25hcHNob3RJbmZvJiYodGhpcy5zbmFwc2hvdEluZm89dC5zbmFwc2hvdEluZm8pLHZvaWQgMCE9PXQuYWdlbnRJbmZvJiYodGhpcy5hZ2VudEluZm89dC5hZ2VudEluZm8pLHZvaWQgMCE9PXQuY29ubkluZm8mJih0aGlzLmNvbm5JbmZvPXQuY29ubkluZm8pLHZvaWQgMCE9PXQucGFydG5lcnMmJih0aGlzLnBhcnRuZXJzPXQucGFydG5lcnMpLHZvaWQgMCE9PXQucGxheWVyJiYodGhpcy5wbGF5ZXI9dC5wbGF5ZXIpLHZvaWQgMCE9PXQuY2xpZW50JiYodGhpcy5jbGllbnQ9dC5jbGllbnQpLHZvaWQgMCE9PXQuc2Vzc2lvbklkJiYodGhpcy5zZXNzaW9uSWQ9dC5zZXNzaW9uSWQpKX0saGl2ZS5zbmFwc2hvdHMuTWV0cmljU25hcHNob3QucHJvdG90eXBlPXt9LGhpdmUuc25hcHNob3RzLk1ldHJpY1NuYXBzaG90LnByb3RvdHlwZS5yZWFkPWZ1bmN0aW9uKHQpe2Zvcih0LkhjKCk7Oyl7dmFyIGU9dC5zYSgpLGk9KGUuQmMsZS5hYSksbj1lLmNhO2lmKGk9PXIuYnMuRXMpYnJlYWs7c3dpdGNoKG4pe2Nhc2UgMTppPT1yLmJzLlBzP3RoaXMudGltZXN0YW1wPXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjppPT1yLmJzLkFzP3RoaXMuZ3VpZD10LmhhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM6aT09ci5icy54cz8odGhpcy5ldmVudElkPW5ldyBFdmVudElkLHRoaXMuZXZlbnRJZC5yZWFkKHQpKTp0LnBhKGkpO2JyZWFrO2Nhc2UgNDppPT1yLmJzLnhzPyh0aGlzLnN0cmVhbUluZm89bmV3IGhpdmUuc25hcHNob3RzLlN0cmVhbUluZm8sdGhpcy5zdHJlYW1JbmZvLnJlYWQodCkpOnQucGEoaSk7YnJlYWs7Y2FzZSA1Omk9PXIuYnMueHM/KHRoaXMubWV0cmljcz1uZXcgaGl2ZS5zbmFwc2hvdHMuTWV0cmljcyx0aGlzLm1ldHJpY3MucmVhZCh0KSk6dC5wYShpKTticmVhaztjYXNlIDY6aWYoaT09ci5icy5Ccyl7dmFyIG8scz0wO3RoaXMudHJhZmZpYz17fTt2YXIgYT0wLGM9MDtvPXQuTGMoKSxhPW8uTWMsYz1vLmpjLHM9by5zaXplO2Zvcih2YXIgaD0wO2g8czsrK2gpe2g+MCYmdC5OYy5sZW5ndGg+dC5SYVt0LlJhLmxlbmd0aC0xXSsxJiZ0Lk5jLnBvcCgpO3ZhciBwPW51bGwsdT1udWxsO3A9bmV3IGhpdmUuc25hcHNob3RzLlRyYWZmaWNLZXkscC5yZWFkKHQpLHU9bmV3IGhpdmUuc25hcHNob3RzLlRyYWZmaWMsdS5yZWFkKHQpLHRoaXMudHJhZmZpY1twXT11fXQuVWMoKX1lbHNlIHQucGEoaSk7YnJlYWs7Y2FzZSA3Omk9PXIuYnMueHM/KHRoaXMuc25hcHNob3RJbmZvPW5ldyBTbmFwc2hvdEluZm8sdGhpcy5zbmFwc2hvdEluZm8ucmVhZCh0KSk6dC5wYShpKTticmVhaztjYXNlIDg6aT09ci5icy54cz8odGhpcy5hZ2VudEluZm89bmV3IGhpdmUuc25hcHNob3RzLkFnZW50SW5mbyx0aGlzLmFnZW50SW5mby5yZWFkKHQpKTp0LnBhKGkpO2JyZWFrO2Nhc2UgOTppPT1yLmJzLnhzPyh0aGlzLmNvbm5JbmZvPW5ldyBoaXZlLnNuYXBzaG90cy5Db25uZWN0aXZpdHlJbmZvLHRoaXMuY29ubkluZm8ucmVhZCh0KSk6dC5wYShpKTticmVhaztjYXNlIDEwOmlmKGk9PXIuYnMuQnMpe3ZhciBsLGQ9MDt0aGlzLnBhcnRuZXJzPXt9O3ZhciBmPTAsZz0wO2w9dC5MYygpLGY9bC5NYyxnPWwuamMsZD1sLnNpemU7Zm9yKHZhciB2PTA7djxkOysrdil7dj4wJiZ0Lk5jLmxlbmd0aD50LlJhW3QuUmEubGVuZ3RoLTFdKzEmJnQuTmMucG9wKCk7dmFyIHk9bnVsbCxtPW51bGw7eT1uZXcgaGl2ZS5zbmFwc2hvdHMuUGFydG5lcktleSx5LnJlYWQodCksbT1uZXcgaGl2ZS5zbmFwc2hvdHMuUGFydG5lcixtLnJlYWQodCksdGhpcy5wYXJ0bmVyc1t5XT1tfXQuVWMoKX1lbHNlIHQucGEoaSk7YnJlYWs7Y2FzZSAxMTppPT1yLmJzLnhzPyh0aGlzLnBsYXllcj1uZXcgaGl2ZS5zbmFwc2hvdHMuUGxheWVyLHRoaXMucGxheWVyLnJlYWQodCkpOnQucGEoaSk7YnJlYWs7Y2FzZSAxMjppPT1yLmJzLnhzPyh0aGlzLmNsaWVudD1uZXcgaGl2ZS5zbmFwc2hvdHMuQ2xpZW50SW5mbyx0aGlzLmNsaWVudC5yZWFkKHQpKTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTM6aT09ci5icy5Bcz90aGlzLnNlc3Npb25JZD10LmhhKCkudmFsdWU6dC5wYShpKTticmVhaztkZWZhdWx0OnQucGEoaSl9dC5sYSgpfXQuZGEoKX0saGl2ZS5zbmFwc2hvdHMuTWV0cmljU25hcHNob3QucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKHQpe2lmKHQuZmEoXCJNZXRyaWNTbmFwc2hvdFwiKSxudWxsIT09dGhpcy50aW1lc3RhbXAmJnZvaWQgMCE9PXRoaXMudGltZXN0YW1wJiYodC5nYShcInRpbWVzdGFtcFwiLHIuYnMuUHMsMSksdC5DYyh0aGlzLnRpbWVzdGFtcCksdC55YSgpKSxudWxsIT09dGhpcy5ndWlkJiZ2b2lkIDAhPT10aGlzLmd1aWQmJih0LmdhKFwiZ3VpZFwiLHIuYnMuQXMsMiksdC52YSh0aGlzLmd1aWQpLHQueWEoKSksbnVsbCE9PXRoaXMuZXZlbnRJZCYmdm9pZCAwIT09dGhpcy5ldmVudElkJiYodC5nYShcImV2ZW50SWRcIixyLmJzLnhzLDMpLHRoaXMuZXZlbnRJZC53cml0ZSh0KSx0LnlhKCkpLG51bGwhPT10aGlzLnN0cmVhbUluZm8mJnZvaWQgMCE9PXRoaXMuc3RyZWFtSW5mbyYmKHQuZ2EoXCJzdHJlYW1JbmZvXCIsci5icy54cyw0KSx0aGlzLnN0cmVhbUluZm8ud3JpdGUodCksdC55YSgpKSxudWxsIT09dGhpcy5tZXRyaWNzJiZ2b2lkIDAhPT10aGlzLm1ldHJpY3MmJih0LmdhKFwibWV0cmljc1wiLHIuYnMueHMsNSksdGhpcy5tZXRyaWNzLndyaXRlKHQpLHQueWEoKSksbnVsbCE9PXRoaXMudHJhZmZpYyYmdm9pZCAwIT09dGhpcy50cmFmZmljKXt0LmdhKFwidHJhZmZpY1wiLHIuYnMuQnMsNiksdC5tYyhyLmJzLnhzLHIuYnMueHMsci5Rcyh0aGlzLnRyYWZmaWMpKTtmb3IodmFyIGU9MDtlPHRoaXMudHJhZmZpYy5sZW5ndGg7ZSsrKXt2YXIgaT10aGlzLnRyYWZmaWNbZV0sbj1pLmtleSxvPWkudmFsdWU7bi53cml0ZSh0KSxvLndyaXRlKHQpfXQud2MoKSx0LnlhKCl9aWYobnVsbCE9PXRoaXMuc25hcHNob3RJbmZvJiZ2b2lkIDAhPT10aGlzLnNuYXBzaG90SW5mbyYmKHQuZ2EoXCJzbmFwc2hvdEluZm9cIixyLmJzLnhzLDcpLHRoaXMuc25hcHNob3RJbmZvLndyaXRlKHQpLHQueWEoKSksbnVsbCE9PXRoaXMuYWdlbnRJbmZvJiZ2b2lkIDAhPT10aGlzLmFnZW50SW5mbyYmKHQuZ2EoXCJhZ2VudEluZm9cIixyLmJzLnhzLDgpLHRoaXMuYWdlbnRJbmZvLndyaXRlKHQpLHQueWEoKSksbnVsbCE9PXRoaXMuY29ubkluZm8mJnZvaWQgMCE9PXRoaXMuY29ubkluZm8mJih0LmdhKFwiY29ubkluZm9cIixyLmJzLnhzLDkpLHRoaXMuY29ubkluZm8ud3JpdGUodCksdC55YSgpKSxudWxsIT09dGhpcy5wYXJ0bmVycyYmdm9pZCAwIT09dGhpcy5wYXJ0bmVycyl7dC5nYShcInBhcnRuZXJzXCIsci5icy5CcywxMCksdC5tYyhyLmJzLnhzLHIuYnMueHMsci5Rcyh0aGlzLnBhcnRuZXJzKSk7Zm9yKHZhciBlPTA7ZTx0aGlzLnBhcnRuZXJzLmxlbmd0aDtlKyspe3ZhciBpPXRoaXMucGFydG5lcnNbZV0scz1pLmtleSxhPWkudmFsdWU7cy53cml0ZSh0KSxhLndyaXRlKHQpfXQud2MoKSx0LnlhKCl9bnVsbCE9PXRoaXMucGxheWVyJiZ2b2lkIDAhPT10aGlzLnBsYXllciYmKHQuZ2EoXCJwbGF5ZXJcIixyLmJzLnhzLDExKSx0aGlzLnBsYXllci53cml0ZSh0KSx0LnlhKCkpLG51bGwhPT10aGlzLmNsaWVudCYmdm9pZCAwIT09dGhpcy5jbGllbnQmJih0LmdhKFwiY2xpZW50XCIsci5icy54cywxMiksdGhpcy5jbGllbnQud3JpdGUodCksdC55YSgpKSxudWxsIT09dGhpcy5zZXNzaW9uSWQmJnZvaWQgMCE9PXRoaXMuc2Vzc2lvbklkJiYodC5nYShcInNlc3Npb25JZFwiLHIuYnMuQXMsMTMpLHQudmEodGhpcy5zZXNzaW9uSWQpLHQueWEoKSksdC53YSgpLHQuVGEoKX0saGl2ZS5zbmFwc2hvdHMuSnNvbk1ldHJpY1NuYXBzaG90PWZ1bmN0aW9uKHQpe3RoaXMudGltZXN0YW1wPW51bGwsdGhpcy5ndWlkPW51bGwsdGhpcy5ldmVudElkPW51bGwsdGhpcy5zdHJlYW1JbmZvPW51bGwsdGhpcy5tZXRyaWNzPW51bGwsdGhpcy50cmFmZmljPW51bGwsdGhpcy5zbmFwc2hvdEluZm89bnVsbCx0aGlzLmFnZW50SW5mbz1udWxsLHRoaXMuY29ubkluZm89bnVsbCx0aGlzLnBhcnRuZXJzPW51bGwsdGhpcy5wbGF5ZXI9bnVsbCx0aGlzLmNsaWVudD1udWxsLHRoaXMuc2Vzc2lvbklkPW51bGwsdCYmKHZvaWQgMCE9PXQudGltZXN0YW1wJiYodGhpcy50aW1lc3RhbXA9dC50aW1lc3RhbXApLHZvaWQgMCE9PXQuZ3VpZCYmKHRoaXMuZ3VpZD10Lmd1aWQpLHZvaWQgMCE9PXQuZXZlbnRJZCYmKHRoaXMuZXZlbnRJZD10LmV2ZW50SWQpLHZvaWQgMCE9PXQuc3RyZWFtSW5mbyYmKHRoaXMuc3RyZWFtSW5mbz10LnN0cmVhbUluZm8pLHZvaWQgMCE9PXQubWV0cmljcyYmKHRoaXMubWV0cmljcz10Lm1ldHJpY3MpLHZvaWQgMCE9PXQudHJhZmZpYyYmKHRoaXMudHJhZmZpYz10LnRyYWZmaWMpLHZvaWQgMCE9PXQuc25hcHNob3RJbmZvJiYodGhpcy5zbmFwc2hvdEluZm89dC5zbmFwc2hvdEluZm8pLHZvaWQgMCE9PXQuYWdlbnRJbmZvJiYodGhpcy5hZ2VudEluZm89dC5hZ2VudEluZm8pLHZvaWQgMCE9PXQuY29ubkluZm8mJih0aGlzLmNvbm5JbmZvPXQuY29ubkluZm8pLHZvaWQgMCE9PXQucGFydG5lcnMmJih0aGlzLnBhcnRuZXJzPXQucGFydG5lcnMpLHZvaWQgMCE9PXQucGxheWVyJiYodGhpcy5wbGF5ZXI9dC5wbGF5ZXIpLHZvaWQgMCE9PXQuY2xpZW50JiYodGhpcy5jbGllbnQ9dC5jbGllbnQpLHZvaWQgMCE9PXQuc2Vzc2lvbklkJiYodGhpcy5zZXNzaW9uSWQ9dC5zZXNzaW9uSWQpKX0saGl2ZS5zbmFwc2hvdHMuSnNvbk1ldHJpY1NuYXBzaG90LnByb3RvdHlwZT17fSxoaXZlLnNuYXBzaG90cy5Kc29uTWV0cmljU25hcHNob3QucHJvdG90eXBlLnJlYWQ9ZnVuY3Rpb24odCl7Zm9yKHQuSGMoKTs7KXt2YXIgZT10LnNhKCksaT0oZS5CYyxlLmFhKSxuPWUuY2E7aWYoaT09ci5icy5FcylicmVhaztzd2l0Y2gobil7Y2FzZSAxOmk9PXIuYnMuUHM/dGhpcy50aW1lc3RhbXA9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyOmk9PXIuYnMuQXM/dGhpcy5ndWlkPXQuaGEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzppPT1yLmJzLnhzPyh0aGlzLmV2ZW50SWQ9bmV3IEV2ZW50SWQsdGhpcy5ldmVudElkLnJlYWQodCkpOnQucGEoaSk7YnJlYWs7Y2FzZSA0Omk9PXIuYnMueHM/KHRoaXMuc3RyZWFtSW5mbz1uZXcgaGl2ZS5zbmFwc2hvdHMuU3RyZWFtSW5mbyx0aGlzLnN0cmVhbUluZm8ucmVhZCh0KSk6dC5wYShpKTticmVhaztjYXNlIDU6aT09ci5icy54cz8odGhpcy5tZXRyaWNzPW5ldyBoaXZlLnNuYXBzaG90cy5NZXRyaWNzLHRoaXMubWV0cmljcy5yZWFkKHQpKTp0LnBhKGkpO2JyZWFrO2Nhc2UgNjppZihpPT1yLmJzLkJzKXt2YXIgbyxzPTA7dGhpcy50cmFmZmljPXt9O3ZhciBhPTAsYz0wO289dC5MYygpLGE9by5NYyxjPW8uamMscz1vLnNpemU7Zm9yKHZhciBoPTA7aDxzOysraCl7aD4wJiZ0Lk5jLmxlbmd0aD50LlJhW3QuUmEubGVuZ3RoLTFdKzEmJnQuTmMucG9wKCk7dmFyIHA9bnVsbCx1PW51bGw7cD10LmhhKCkudmFsdWUsdT1uZXcgaGl2ZS5zbmFwc2hvdHMuVHJhZmZpYyx1LnJlYWQodCksdGhpcy50cmFmZmljW3BdPXV9dC5VYygpfWVsc2UgdC5wYShpKTticmVhaztjYXNlIDc6aT09ci5icy54cz8odGhpcy5zbmFwc2hvdEluZm89bmV3IFNuYXBzaG90SW5mbyx0aGlzLnNuYXBzaG90SW5mby5yZWFkKHQpKTp0LnBhKGkpO2JyZWFrO2Nhc2UgODppPT1yLmJzLnhzPyh0aGlzLmFnZW50SW5mbz1uZXcgaGl2ZS5zbmFwc2hvdHMuQWdlbnRJbmZvLHRoaXMuYWdlbnRJbmZvLnJlYWQodCkpOnQucGEoaSk7YnJlYWs7Y2FzZSA5Omk9PXIuYnMueHM/KHRoaXMuY29ubkluZm89bmV3IGhpdmUuc25hcHNob3RzLkNvbm5lY3Rpdml0eUluZm8sdGhpcy5jb25uSW5mby5yZWFkKHQpKTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTA6aWYoaT09ci5icy5Ccyl7dmFyIGwsZD0wO3RoaXMucGFydG5lcnM9e307dmFyIGY9MCxnPTA7bD10LkxjKCksZj1sLk1jLGc9bC5qYyxkPWwuc2l6ZTtmb3IodmFyIHY9MDt2PGQ7Kyt2KXt2PjAmJnQuTmMubGVuZ3RoPnQuUmFbdC5SYS5sZW5ndGgtMV0rMSYmdC5OYy5wb3AoKTt2YXIgeT1udWxsLG09bnVsbDt5PXQuaGEoKS52YWx1ZSxtPW5ldyBoaXZlLnNuYXBzaG90cy5QYXJ0bmVyLG0ucmVhZCh0KSx0aGlzLnBhcnRuZXJzW3ldPW19dC5VYygpfWVsc2UgdC5wYShpKTticmVhaztjYXNlIDExOmk9PXIuYnMueHM/KHRoaXMucGxheWVyPW5ldyBoaXZlLnNuYXBzaG90cy5QbGF5ZXIsdGhpcy5wbGF5ZXIucmVhZCh0KSk6dC5wYShpKTticmVhaztjYXNlIDEyOmk9PXIuYnMueHM/KHRoaXMuY2xpZW50PW5ldyBoaXZlLnNuYXBzaG90cy5DbGllbnRJbmZvLHRoaXMuY2xpZW50LnJlYWQodCkpOnQucGEoaSk7YnJlYWs7Y2FzZSAxMzppPT1yLmJzLkFzP3RoaXMuc2Vzc2lvbklkPXQuaGEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2RlZmF1bHQ6dC5wYShpKX10LmxhKCl9dC5kYSgpfSxoaXZlLnNuYXBzaG90cy5Kc29uTWV0cmljU25hcHNob3QucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKHQpe2lmKHQuZmEoXCJKc29uTWV0cmljU25hcHNob3RcIiksbnVsbCE9PXRoaXMudGltZXN0YW1wJiZ2b2lkIDAhPT10aGlzLnRpbWVzdGFtcCYmKHQuZ2EoXCJ0aW1lc3RhbXBcIixyLmJzLlBzLDEpLHQuQ2ModGhpcy50aW1lc3RhbXApLHQueWEoKSksbnVsbCE9PXRoaXMuZ3VpZCYmdm9pZCAwIT09dGhpcy5ndWlkJiYodC5nYShcImd1aWRcIixyLmJzLkFzLDIpLHQudmEodGhpcy5ndWlkKSx0LnlhKCkpLG51bGwhPT10aGlzLmV2ZW50SWQmJnZvaWQgMCE9PXRoaXMuZXZlbnRJZCYmKHQuZ2EoXCJldmVudElkXCIsci5icy54cywzKSx0aGlzLmV2ZW50SWQud3JpdGUodCksdC55YSgpKSxudWxsIT09dGhpcy5zdHJlYW1JbmZvJiZ2b2lkIDAhPT10aGlzLnN0cmVhbUluZm8mJih0LmdhKFwic3RyZWFtSW5mb1wiLHIuYnMueHMsNCksdGhpcy5zdHJlYW1JbmZvLndyaXRlKHQpLHQueWEoKSksbnVsbCE9PXRoaXMubWV0cmljcyYmdm9pZCAwIT09dGhpcy5tZXRyaWNzJiYodC5nYShcIm1ldHJpY3NcIixyLmJzLnhzLDUpLHRoaXMubWV0cmljcy53cml0ZSh0KSx0LnlhKCkpLG51bGwhPT10aGlzLnRyYWZmaWMmJnZvaWQgMCE9PXRoaXMudHJhZmZpYyl7dC5nYShcInRyYWZmaWNcIixyLmJzLkJzLDYpLHQubWMoci5icy5BcyxyLmJzLnhzLHIuUXModGhpcy50cmFmZmljKSk7Zm9yKHZhciBlIGluIHRoaXMudHJhZmZpYylpZih0aGlzLnRyYWZmaWMuaGFzT3duUHJvcGVydHkoZSkpe3ZhciBpPXRoaXMudHJhZmZpY1tlXTt0LnZhKGUpLGkud3JpdGUodCl9dC53YygpLHQueWEoKX1pZihudWxsIT09dGhpcy5zbmFwc2hvdEluZm8mJnZvaWQgMCE9PXRoaXMuc25hcHNob3RJbmZvJiYodC5nYShcInNuYXBzaG90SW5mb1wiLHIuYnMueHMsNyksdGhpcy5zbmFwc2hvdEluZm8ud3JpdGUodCksdC55YSgpKSxudWxsIT09dGhpcy5hZ2VudEluZm8mJnZvaWQgMCE9PXRoaXMuYWdlbnRJbmZvJiYodC5nYShcImFnZW50SW5mb1wiLHIuYnMueHMsOCksdGhpcy5hZ2VudEluZm8ud3JpdGUodCksdC55YSgpKSxudWxsIT09dGhpcy5jb25uSW5mbyYmdm9pZCAwIT09dGhpcy5jb25uSW5mbyYmKHQuZ2EoXCJjb25uSW5mb1wiLHIuYnMueHMsOSksdGhpcy5jb25uSW5mby53cml0ZSh0KSx0LnlhKCkpLG51bGwhPT10aGlzLnBhcnRuZXJzJiZ2b2lkIDAhPT10aGlzLnBhcnRuZXJzKXt0LmdhKFwicGFydG5lcnNcIixyLmJzLkJzLDEwKSx0Lm1jKHIuYnMuQXMsci5icy54cyxyLlFzKHRoaXMucGFydG5lcnMpKTtmb3IodmFyIG4gaW4gdGhpcy5wYXJ0bmVycylpZih0aGlzLnBhcnRuZXJzLmhhc093blByb3BlcnR5KG4pKXt2YXIgbz10aGlzLnBhcnRuZXJzW25dO3QudmEobiksby53cml0ZSh0KX10LndjKCksdC55YSgpfW51bGwhPT10aGlzLnBsYXllciYmdm9pZCAwIT09dGhpcy5wbGF5ZXImJih0LmdhKFwicGxheWVyXCIsci5icy54cywxMSksdGhpcy5wbGF5ZXIud3JpdGUodCksdC55YSgpKSxudWxsIT09dGhpcy5jbGllbnQmJnZvaWQgMCE9PXRoaXMuY2xpZW50JiYodC5nYShcImNsaWVudFwiLHIuYnMueHMsMTIpLHRoaXMuY2xpZW50LndyaXRlKHQpLHQueWEoKSksbnVsbCE9PXRoaXMuc2Vzc2lvbklkJiZ2b2lkIDAhPT10aGlzLnNlc3Npb25JZCYmKHQuZ2EoXCJzZXNzaW9uSWRcIixyLmJzLkFzLDEzKSx0LnZhKHRoaXMuc2Vzc2lvbklkKSx0LnlhKCkpLHQud2EoKSx0LlRhKCl9fSxmdW5jdGlvbih0LGUpey8qISBjb2xsZWN0aW9ucy5taW4uanMgdiAzLjAuMCBnaXRodWIuY29tL21vbnRhZ2Vqcy9jb2xsZWN0aW9ucyAqL1xuICAhZnVuY3Rpb24odCl7ZnVuY3Rpb24gZSgpe3Rocm93IEVycm9yKFwiQ2FuJ3QgY29uc3RydWN0LiBHZW5lcmljQ29sbGVjdGlvbiBpcyBhIG1peGluLlwiKX1mdW5jdGlvbiBpKCl7dGhyb3cgRXJyb3IoXCJDYW4ndCBjb25zdHJ1Y3QuIEdlbmVyaWNTZXQgaXMgYSBtaXhpbi5cIil9ZnVuY3Rpb24gcigpe31mdW5jdGlvbiBuKCl7dGhyb3cgRXJyb3IoXCJUaGlzIGlzIGFuIGFic3RyYWN0IGludGVyZmFjZS4gTWl4IGl0LiBEb24ndCBjb25zdHJ1Y3QgaXRcIil9ZnVuY3Rpb24gbygpe3Rocm93IEVycm9yKFwiQ2FuJ3QgY29uc3RydWN0LiBSYW5nZUNoYW5nZXMgaXMgYSBtaXhpbi5cIil9ZnVuY3Rpb24gcygpe3Rocm93IEVycm9yKFwiQ2FuJ3QgY29uc3RydWN0LiBHZW5lcmljT3JkZXIgaXMgYSBtaXhpbi5cIil9ZnVuY3Rpb24gYSh0KXtpZighKHRoaXMgaW5zdGFuY2VvZiBhKSlyZXR1cm4gbmV3IGEodCk7aWYoQXJyYXkuaXNBcnJheSh0KXx8XCJzdHJpbmdcIj09dHlwZW9mIHQpcmV0dXJuIGEuRGYodCk7aWYodD1sdCh0KSx0IGluc3RhbmNlb2YgYSlyZXR1cm4gdDtpZih0Lm5leHQpdGhpcy5uZXh0PWZ1bmN0aW9uKCl7cmV0dXJuIHQubmV4dCgpfTtlbHNlIGlmKHQuRGYpe3ZhciBlPXQuRGYoKTt0aGlzLm5leHQ9ZnVuY3Rpb24oKXtyZXR1cm4gZS5uZXh0KCl9fWVsc2V7aWYoXCJbb2JqZWN0IEZ1bmN0aW9uXVwiIT09bHQucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodCkpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkNhbm5vdCBpdGVyYXRlXCIpO3RoaXMubmV4dD10fX1mdW5jdGlvbiBjKHQsZSxpKXt0aGlzLkhmPXQsdGhpcy5zdGFydD1udWxsPT1lPzA6ZSx0aGlzLmVuZD1pfWZ1bmN0aW9uIGgodCxlLGkpe2lmKCEodGhpcyBpbnN0YW5jZW9mIGgpKXJldHVybiBuZXcgaCh0LGUsaSk7dmFyIHI9dGhpcy5oZWFkPW5ldyB0aGlzLk5vZGU7ci5uZXh0PXIsci5MZj1yLHRoaXMuTWY9ZXx8T2JqZWN0Lm9sLHRoaXMuY29udGVudD1pfHxGdW5jdGlvbi5qZix0aGlzLmxlbmd0aD0wLHRoaXMuYWRkRWFjaCh0KX1mdW5jdGlvbiBwKHQpe3RoaXMuaGVhZD10LHRoaXMuVWY9dC5uZXh0fWZ1bmN0aW9uIHUodCl7dGhpcy52YWx1ZT10LHRoaXMubmV4dD10aGlzLkxmPW51bGx9ZnVuY3Rpb24gbCgpe3Rocm93IEVycm9yKFwiQ2FuJ3QgY29uc3RydWN0LiBNYXBDaGFuZ2VzIGlzIGEgbWl4aW4uXCIpfWZ1bmN0aW9uIGQoKXt0aHJvdyBFcnJvcihcIkNhbid0IGNvbnN0cnVjdC4gR2VuZXJpY01hcCBpcyBhIG1peGluLlwiKX1mdW5jdGlvbiBmKHQsZSl7cmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBmPyh0aGlzLmNvbnRlbnQ9ZXx8RnVuY3Rpb24uamYsdGhpcy5WZj17fSx0aGlzLmxlbmd0aD0wLHZvaWQgdGhpcy5hZGRFYWNoKHQpKTpuZXcgZih0LGUpfWZ1bmN0aW9uIGcodCxlLGkscil7cmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBnPyhlPWV8fE9iamVjdC5vbCxpPWl8fE9iamVjdC5oYXNoLHI9cnx8RnVuY3Rpb24uamYsdGhpcy5NZj1lLHRoaXMuUWY9aSx0aGlzLmNvbnRlbnQ9cix0aGlzLnFmPW5ldyB0aGlzLkpmKG51bGwsdGhpcy5LZiksdGhpcy5sZW5ndGg9MCx2b2lkIHRoaXMuYWRkRWFjaCh0KSk6bmV3IGcodCxlLGkpfWZ1bmN0aW9uIHYodCxlLGkscil7cmV0dXJuIHRoaXMgaW5zdGFuY2VvZiB2PyhlPWV8fE9iamVjdC5vbCxpPWl8fE9iamVjdC5oYXNoLHI9cnx8RnVuY3Rpb24uamYsdGhpcy5NZj1lLHRoaXMuUWY9aSx0aGlzLmNvbnRlbnQ9cix0aGlzLlZmPW5ldyBNdCgodm9pZCAwKSxmdW5jdGlvbih0LGkpe3JldHVybiBlKHQua2V5LGkua2V5KX0sZnVuY3Rpb24odCl7cmV0dXJuIGkodC5rZXkpfSksdGhpcy5sZW5ndGg9MCx2b2lkIHRoaXMuYWRkRWFjaCh0KSk6bmV3IHYodCxlLGkpfWZ1bmN0aW9uIHkodCxlLGkscil7cmV0dXJuIHRoaXMgaW5zdGFuY2VvZiB5PyhlPWV8fE9iamVjdC5vbCxpPWl8fE9iamVjdC5oYXNoLHI9cnx8RnVuY3Rpb24uamYsdGhpcy5NZj1lLHRoaXMuUWY9aSx0aGlzLmNvbnRlbnQ9cix0aGlzLm9yZGVyPW5ldyB0aGlzLkdmKCh2b2lkIDApLGUpLHRoaXMuVmY9bmV3IHRoaXMuemYoKHZvaWQgMCksZnVuY3Rpb24odCxpKXtyZXR1cm4gZSh0LnZhbHVlLGkudmFsdWUpfSxmdW5jdGlvbih0KXtyZXR1cm4gaSh0LnZhbHVlKX0pLHRoaXMubGVuZ3RoPTAsdm9pZCB0aGlzLmFkZEVhY2godCkpOm5ldyB5KHQsZSxpKX1mdW5jdGlvbiBtKHQsZSxpLHIsbil7cmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBtPyhlPWV8fDEvMCxpPWl8fE9iamVjdC5vbCxyPXJ8fE9iamVjdC5oYXNoLG49bnx8RnVuY3Rpb24uamYsdGhpcy5WZj1uZXcgWXQoKHZvaWQgMCksaSxyKSx0aGlzLk1mPWksdGhpcy5RZj1yLHRoaXMuY29udGVudD1uLHRoaXMubWF4TGVuZ3RoPWUsdGhpcy5sZW5ndGg9MCx2b2lkIHRoaXMuYWRkRWFjaCh0KSk6bmV3IG0odCxlLGkscil9ZnVuY3Rpb24gdyh0LGUsaSxyLG4pe3JldHVybiB0aGlzIGluc3RhbmNlb2Ygdz8oaT1pfHxPYmplY3Qub2wscj1yfHxPYmplY3QuaGFzaCxuPW58fEZ1bmN0aW9uLmpmLHRoaXMuTWY9aSx0aGlzLlFmPXIsdGhpcy5jb250ZW50PW4sdGhpcy5WZj1uZXcgaWUoKHZvaWQgMCksZSxmdW5jdGlvbih0LGUpe3JldHVybiBpKHQua2V5LGUua2V5KX0sZnVuY3Rpb24odCl7cmV0dXJuIHIodC5rZXkpfSksdGhpcy5sZW5ndGg9MCx2b2lkIHRoaXMuYWRkRWFjaCh0KSk6bmV3IHcodCxlLGkscil9ZnVuY3Rpb24gVCh0LGUsaSxyKXtyZXR1cm4gdGhpcyBpbnN0YW5jZW9mIFQ/KGU9ZXx8T2JqZWN0Lm9sLGk9aXx8T2JqZWN0Lmhhc2gscj1yfHxGdW5jdGlvbi5qZix0aGlzLk1mPWUsdGhpcy5RZj1pLHRoaXMuY29udGVudD1yLHRoaXMuVmY9bmV3IGFlKCh2b2lkIDApLGZ1bmN0aW9uKHQsaSl7cmV0dXJuIGUodC5rZXksaS5rZXkpfSxmdW5jdGlvbih0KXtyZXR1cm4gaSh0LmtleSl9KSx0aGlzLmxlbmd0aD0wLHZvaWQgdGhpcy5hZGRFYWNoKHQpKTpuZXcgVCh0LGUsaSl9ZnVuY3Rpb24gUyh0LGUsaSxyKXtyZXR1cm4gdGhpcyBpbnN0YW5jZW9mIFM/KHRoaXMuV2Y9ZXx8dGhpcy5XZix2b2lkIGxlLmNhbGwodGhpcyx0LGkscixmdW5jdGlvbih0KXt2YXIgZT10aGlzLldmKCk7cmV0dXJuIGxlLnByb3RvdHlwZS5zZXQuY2FsbCh0aGlzLHQsZSksZX0pKTpuZXcgUyh0LGUsaSxyKX1mdW5jdGlvbiBiKHQsZSxpLHIpe3JldHVybiB0aGlzIGluc3RhbmNlb2YgYj8oQXJyYXkuaXNBcnJheSh0KT8odGhpcy5IZj10LHQ9dC5zcGxpY2UoMCx0Lmxlbmd0aCkpOnRoaXMuSGY9W10sdGhpcy5NZj1lfHxPYmplY3Qub2wsdGhpcy4kZj1pfHxPYmplY3QuWWYsdGhpcy5jb250ZW50PXJ8fEZ1bmN0aW9uLmpmLHRoaXMubGVuZ3RoPTAsdm9pZCB0aGlzLmFkZEVhY2godCkpOm5ldyBiKHQsZSxpLHIpfWZ1bmN0aW9uIEUodCxlLGkpe2Zvcih2YXIgcj0wLG49dC5sZW5ndGgtMTtyPD1uOyl7dmFyIG89cituPj4xLHM9aShlLHRbb10pO2lmKDA8cylyPW8rMTtlbHNle2lmKCEoMD5zKSlyZXR1cm4gbztuPW8tMX19cmV0dXJuLShyKzEpfWZ1bmN0aW9uIEkodCxlLGkscil7aWYoaT1FKHQsZSxpKSwwPmkpcmV0dXJuLTE7Zm9yKDswPGkmJnIoZSx0W2ktMV0pOylpLS07cmV0dXJuIHIoZSx0W2ldKT9pOi0xfWZ1bmN0aW9uIFIodCxlLGkscil7aWYoaT1FKHQsZSxpKSwwPmkpcmV0dXJuLTE7Zm9yKDtpPHQubGVuZ3RoLTEmJnIoZSx0W2krMV0pOylpKys7cmV0dXJuIHIoZSx0W2ldKT9pOi0xfWZ1bmN0aW9uIGsodCxlLGkscil7cmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBrP3ZvaWQgeWUuY2FsbCh0aGlzLHQsZSxpLHIpOm5ldyBrKHQsZSxpLHIpfWZ1bmN0aW9uIEModCxlLGkscil7cmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBDPyhlPWV8fE9iamVjdC5vbCxpPWl8fE9iamVjdC5ZZixyPXJ8fEZ1bmN0aW9uLmpmLHRoaXMuTWY9ZSx0aGlzLiRmPWksdGhpcy5jb250ZW50PXIsdGhpcy5WZj1uZXcgU2UobnVsbCxmdW5jdGlvbih0LGkpe3JldHVybiBlKHQua2V5LGkua2V5KX0sZnVuY3Rpb24odCxlKXtyZXR1cm4gaSh0LmtleSxlLmtleSl9KSx0aGlzLmxlbmd0aD0wLHZvaWQgdGhpcy5hZGRFYWNoKHQpKTpuZXcgQyh0LGUsaSxyKX1mdW5jdGlvbiBPKHQsZSxpLHIpe3JldHVybiB0aGlzIGluc3RhbmNlb2YgTz8odGhpcy5NZj1lfHxPYmplY3Qub2wsdGhpcy4kZj1pfHxPYmplY3QuWWYsdGhpcy5jb250ZW50PXJ8fEZ1bmN0aW9uLmpmLHRoaXMucm9vdD1udWxsLHRoaXMubGVuZ3RoPTAsdm9pZCB0aGlzLmFkZEVhY2godCkpOm5ldyBPKHQsZSxpLHIpfWZ1bmN0aW9uIFAodCl7dGhpcy52YWx1ZT10LHRoaXMucmlnaHQ9dGhpcy5sZWZ0PW51bGwsdGhpcy5sZW5ndGg9MX1mdW5jdGlvbiBBKHQsZSxpKXt0aGlzLnNldD10LHRoaXMuTGY9bnVsbCx0aGlzLmVuZD1pLGUmJih0PXRoaXMuc2V0LlhmKGUpKSYmKHRoaXMuc2V0LlpmKHQudmFsdWUpLHRoaXMuTGY9dC50ZygpKX1mdW5jdGlvbiBOKHQsZSxpLHIpe3JldHVybiB0aGlzIGluc3RhbmNlb2YgTj8oZT1lfHxPYmplY3Qub2wsaT1pfHxPYmplY3QuWWYscj1yfHxGdW5jdGlvbi5qZix0aGlzLk1mPWUsdGhpcy4kZj1pLHRoaXMuY29udGVudD1yLHRoaXMuVmY9bmV3IE5lKG51bGwsZnVuY3Rpb24odCxpKXtyZXR1cm4gZSh0LmtleSxpLmtleSl9LGZ1bmN0aW9uKHQsZSl7cmV0dXJuIGkodC5rZXksZS5rZXkpfSksdGhpcy5sZW5ndGg9MCx2b2lkIHRoaXMuYWRkRWFjaCh0KSk6bmV3IE4odCxlLGkscil9dmFyIHg9e307eC5lZz1lLGUucHJvdG90eXBlLmFkZEVhY2g9ZnVuY3Rpb24odCl7aWYodCYmT2JqZWN0KHQpPT09dClpZihcImZ1bmN0aW9uXCI9PXR5cGVvZiB0LmZvckVhY2gpdC5mb3JFYWNoKHRoaXMuYWRkLHRoaXMpO2Vsc2UgaWYoXCJudW1iZXJcIj09dHlwZW9mIHQubGVuZ3RoKWZvcih2YXIgZT0wO2U8dC5sZW5ndGg7ZSsrKXRoaXMuYWRkKHRbZV0sZSk7ZWxzZSBPYmplY3Qua2V5cyh0KS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3RoaXMuYWRkKHRbZV0sZSl9LHRoaXMpfSxlLnByb3RvdHlwZS5pZz1mdW5jdGlvbih0KXt0LmZvckVhY2goZnVuY3Rpb24odCl7dGhpc1tcImRlbGV0ZVwiXSh0KX0sdGhpcyl9LGUucHJvdG90eXBlLmZvckVhY2g9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5yZWR1Y2UoZnVuY3Rpb24oaSxyLG4sbyxzKXt0LmNhbGwoZSxyLG4sbyxzKX0sdm9pZCAwKX0sZS5wcm90b3R5cGUubWFwPWZ1bmN0aW9uKHQsZSl7dmFyIGk9W107cmV0dXJuIHRoaXMucmVkdWNlKGZ1bmN0aW9uKHIsbixvLHMsYSl7aS5wdXNoKHQuY2FsbChlLG4sbyxzLGEpKX0sdm9pZCAwKSxpfSxlLnByb3RvdHlwZS50b0FycmF5PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubWFwKEZ1bmN0aW9uLmlkZW50aXR5KX0sZS5wcm90b3R5cGUucmc9ZnVuY3Rpb24oKXt2YXIgdD17fTtyZXR1cm4gdGhpcy5yZWR1Y2UoZnVuY3Rpb24oZSxpLHIpe3Rbcl09aX0sdm9pZCAwKSx0fSxlLnByb3RvdHlwZS5maWx0ZXI9ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzLm5nKCk7cmV0dXJuIHRoaXMucmVkdWNlKGZ1bmN0aW9uKHIsbixvLHMsYSl7dC5jYWxsKGUsbixvLHMsYSkmJmkuYWRkKG4pfSx2b2lkIDApLGl9LGUucHJvdG90eXBlLmV2ZXJ5PWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMucmVkdWNlKGZ1bmN0aW9uKGkscixuLG8scyl7cmV0dXJuIGkmJnQuY2FsbChlLHIsbixvLHMpfSwhMCl9LGUucHJvdG90eXBlLnNvbWU9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5yZWR1Y2UoZnVuY3Rpb24oaSxyLG4sbyxzKXtyZXR1cm4gaXx8dC5jYWxsKGUscixuLG8scyl9LCExKX0sZS5wcm90b3R5cGUuYWxsPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZXZlcnkoQm9vbGVhbil9LGUucHJvdG90eXBlLmllPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuc29tZShCb29sZWFuKX0sZS5wcm90b3R5cGUubWluPWZ1bmN0aW9uKHQpe3JldHVybiB0PXRoaXMuJGZ8fE9iamVjdC5ZZix0aGlzLnJlZHVjZShmdW5jdGlvbihlLGkpe3JldHVybiAwPnQoaSxlKT9pOmV9LDEvMCl9LGUucHJvdG90eXBlLm1heD1mdW5jdGlvbih0KXtyZXR1cm4gdD10aGlzLiRmfHxPYmplY3QuWWYsdGhpcy5yZWR1Y2UoZnVuY3Rpb24oZSxpKXtyZXR1cm4gMDx0KGksZSk/aTplfSwtKDEvMCkpfSxlLnByb3RvdHlwZS5vZz1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5yZWR1Y2UoZnVuY3Rpb24odCxlKXtyZXR1cm4gdCtlfSx2b2lkIDA9PT10PzA6dCl9LGUucHJvdG90eXBlLnNnPWZ1bmN0aW9uKHQpe3ZhciBlPXZvaWQgMD09PXQ/MDp0LGk9dm9pZCAwPT09dD8wOnQ7cmV0dXJuIHRoaXMucmVkdWNlKGZ1bmN0aW9uKHQscil7ZSs9cixpKz0xfSx2b2lkIDApLGUvaX0sZS5wcm90b3R5cGUuY29uY2F0PWZ1bmN0aW9uKCl7Zm9yKHZhciB0PXRoaXMubmcodGhpcyksZT0wO2U8YXJndW1lbnRzLmxlbmd0aDtlKyspdC5hZGRFYWNoKGFyZ3VtZW50c1tlXSk7cmV0dXJuIHR9LGUucHJvdG90eXBlLmFnPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcztyZXR1cm4gdGhpcy5yZWR1Y2UoZnVuY3Rpb24oZSxpKXtyZXR1cm4gaS5mb3JFYWNoKGZ1bmN0aW9uKHQpe3RoaXMucHVzaCh0KX0sZSx0KSxlfSxbXSl9LGUucHJvdG90eXBlLmNnPWZ1bmN0aW9uKCl7dmFyIHQ9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKTt0LnVuc2hpZnQodGhpcyk7Zm9yKHZhciBlPVtdLGk9MS8wLHI9MDtyPHQubGVuZ3RoO3IrKyl7dmFyIG49dFtyXTt0W3JdPW4udG9BcnJheSgpLG4ubGVuZ3RoPGkmJihpPW4ubGVuZ3RoKX1mb3Iocj0wO3I8dC5sZW5ndGg7cisrKWZvcih2YXIgbj10W3JdLG89MDtvPG4ubGVuZ3RoO28rKylvPGkmJm8gaW4gbiYmKGVbb109ZVtvXXx8W10sZVtvXVtyXT1uW29dKTtyZXR1cm4gZX0sZS5wcm90b3R5cGUuaGc9ZnVuY3Rpb24odCxlLGkpe3JldHVybiB0PXR8fHRoaXMuJGZ8fE9iamVjdC5ZZix0LnBnPyhlPXQucGcsdD10LllmfHx0aGlzLiRmfHxPYmplY3QuWWYpOmU9ZXx8RnVuY3Rpb24uaWRlbnRpdHksdm9pZCAwPT09aSYmKGk9MSksdGhpcy5tYXAoZnVuY3Rpb24odCl7cmV0dXJue3BnOmUodCksdmFsdWU6dH19KS5zb3J0KGZ1bmN0aW9uKGUscil7cmV0dXJuIHQoZS5wZyxyLnBnKSppfSkubWFwKGZ1bmN0aW9uKHQpe3JldHVybiB0LnZhbHVlfSl9LGUucHJvdG90eXBlLnJldmVyc2VkPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubmcodGhpcykucmV2ZXJzZSgpfSxlLnByb3RvdHlwZS5jbG9uZT1mdW5jdGlvbih0LGUpe2lmKHZvaWQgMD09PXQpdD0xLzA7ZWxzZSBpZigwPT09dClyZXR1cm4gdGhpczt2YXIgaT10aGlzLm5nKCk7cmV0dXJuIHRoaXMuZm9yRWFjaChmdW5jdGlvbihyLG4pe2kuYWRkKE9iamVjdC5jbG9uZShyLHQtMSxlKSxuKX0sdGhpcyksaX0sZS5wcm90b3R5cGUub25seT1mdW5jdGlvbigpe2lmKDA9PT10aGlzLmxlbmd0aCl0aHJvdyBFcnJvcihcIkNhbid0IGdldCBvbmx5IHZhbHVlIGluIGVtcHR5IGNvbGxlY3Rpb24uXCIpO2lmKDE8dGhpcy5sZW5ndGgpdGhyb3cgRXJyb3IoXCJDYW4ndCBnZXQgb25seSB2YWx1ZSBpbiBjb2xsZWN0aW9uIHdpdGggbXVsdGlwbGUgdmFsdWVzLlwiKTtyZXR1cm4gdGhpcy51ZygpfSx4LmVnJiYoeD14LmVnKTt2YXIgQj17fTtCLmVnPWksaS5wcm90b3R5cGUubGc9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5uZyh0aGlzKTtyZXR1cm4gZS5hZGRFYWNoKHQpLGV9LGkucHJvdG90eXBlLmRnPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLm5nKHRoaXMuZmlsdGVyKGZ1bmN0aW9uKGUpe3JldHVybiB0LmhhcyhlKX0pKX0saS5wcm90b3R5cGUuZmc9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5uZyh0aGlzKTtyZXR1cm4gZS5pZyh0KSxlfSxpLnByb3RvdHlwZS5nZz1mdW5jdGlvbih0KXt2YXIgZT10aGlzLmxnKHQpLHQ9dGhpcy5kZyh0KTtyZXR1cm4gZS5mZyh0KX0saS5wcm90b3R5cGUub2w9ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzO3JldHVybiBPYmplY3QudmcodCxcInJlZHVjZVwiKSYmdGhpcy5sZW5ndGg9PT10Lmxlbmd0aCYmdC5yZWR1Y2UoZnVuY3Rpb24odCxyKXtyZXR1cm4gdCYmaS5oYXMocixlKX0sITApfSxCLmVnJiYoQj1CLmVnKTt2YXIgRj14LF89T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZztBcnJheS5pc0FycmF5fHwoQXJyYXkuaXNBcnJheT1mdW5jdGlvbih0KXtyZXR1cm5cIltvYmplY3QgQXJyYXldXCI9PV8uY2FsbCh0KX0pLEFycmF5LnByb3RvdHlwZS5mb3JFYWNofHwoQXJyYXkucHJvdG90eXBlLmZvckVhY2g9Ri5mb3JFYWNoKSxBcnJheS5wcm90b3R5cGUubWFwfHwoQXJyYXkucHJvdG90eXBlLm1hcD1GLm1hcCksQXJyYXkucHJvdG90eXBlLmZpbHRlcnx8KEFycmF5LnByb3RvdHlwZS5maWx0ZXI9Ri5maWx0ZXIpLEFycmF5LnByb3RvdHlwZS5ldmVyeXx8KEFycmF5LnByb3RvdHlwZS5ldmVyeT1GLmV2ZXJ5KSxBcnJheS5wcm90b3R5cGUuc29tZXx8KEFycmF5LnByb3RvdHlwZS5zb21lPUYuc29tZSksQXJyYXkucHJvdG90eXBlLnJlZHVjZXx8KEFycmF5LnByb3RvdHlwZS5yZWR1Y2U9ZnVuY3Rpb24odCl7dmFyIGU9dG9PYmplY3QodGhpcyksaT1lLmxlbmd0aD4+PjA7aWYoXCJbb2JqZWN0IEZ1bmN0aW9uXVwiIT1fLmNhbGwodCkpdGhyb3cgbmV3IFR5cGVFcnJvcih0K1wiIGlzIG5vdCBhIGZ1bmN0aW9uXCIpO2lmKCFpJiYxPT1hcmd1bWVudHMubGVuZ3RoKXRocm93IG5ldyBUeXBlRXJyb3IoXCJyZWR1Y2Ugb2YgZW1wdHkgYXJyYXkgd2l0aCBubyBpbml0aWFsIHZhbHVlXCIpO3ZhciByLG49MDtpZigyPD1hcmd1bWVudHMubGVuZ3RoKXI9YXJndW1lbnRzWzFdO2Vsc2UgZm9yKDs7KXtpZihuIGluIGUpe3I9ZVtuKytdO2JyZWFrfWlmKCsrbj49aSl0aHJvdyBuZXcgVHlwZUVycm9yKFwicmVkdWNlIG9mIGVtcHR5IGFycmF5IHdpdGggbm8gaW5pdGlhbCB2YWx1ZVwiKX1mb3IoO248aTtuKyspbiBpbiBlJiYocj10LmNhbGwodm9pZCAwLHIsZVtuXSxuLGUpKTtyZXR1cm4gcn0pLEFycmF5LnByb3RvdHlwZS5yZWR1Y2VSaWdodHx8KEFycmF5LnByb3RvdHlwZS5yZWR1Y2VSaWdodD1mdW5jdGlvbih0KXt2YXIgZT10b09iamVjdCh0aGlzKSxpPWUubGVuZ3RoPj4+MDtpZihcIltvYmplY3QgRnVuY3Rpb25dXCIhPV8uY2FsbCh0KSl0aHJvdyBuZXcgVHlwZUVycm9yKHQrXCIgaXMgbm90IGEgZnVuY3Rpb25cIik7aWYoIWkmJjE9PWFyZ3VtZW50cy5sZW5ndGgpdGhyb3cgbmV3IFR5cGVFcnJvcihcInJlZHVjZVJpZ2h0IG9mIGVtcHR5IGFycmF5IHdpdGggbm8gaW5pdGlhbCB2YWx1ZVwiKTt2YXIgcixpPWktMTtpZigyPD1hcmd1bWVudHMubGVuZ3RoKXI9YXJndW1lbnRzWzFdO2Vsc2UgZm9yKDs7KXtpZihpIGluIGUpe3I9ZVtpLS1dO2JyZWFrfWlmKDA+LS1pKXRocm93IG5ldyBUeXBlRXJyb3IoXCJyZWR1Y2VSaWdodCBvZiBlbXB0eSBhcnJheSB3aXRoIG5vIGluaXRpYWwgdmFsdWVcIil9ZG8gaSBpbiB0aGlzJiYocj10LmNhbGwodm9pZCAwLHIsZVtpXSxpLGUpKTt3aGlsZShpLS0pO3JldHVybiByfSksQXJyYXkucHJvdG90eXBlLmluZGV4T2Z8fChBcnJheS5wcm90b3R5cGUuaW5kZXhPZj1mdW5jdGlvbih0KXt2YXIgZT10b09iamVjdCh0aGlzKSxpPWUubGVuZ3RoPj4+MDtpZighaSlyZXR1cm4tMTt2YXIgcj0wO2ZvcigxPGFyZ3VtZW50cy5sZW5ndGgmJihyPXRvSW50ZWdlcihhcmd1bWVudHNbMV0pKSxyPTA8PXI/cjpNYXRoLm1heCgwLGkrcik7cjxpO3IrKylpZihyIGluIGUmJmVbcl09PT10KXJldHVybiByO3JldHVybi0xfSksQXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mfHwoQXJyYXkucHJvdG90eXBlLmxhc3RJbmRleE9mPWZ1bmN0aW9uKHQpe3ZhciBlPXRvT2JqZWN0KHRoaXMpLGk9ZS5sZW5ndGg+Pj4wO2lmKCFpKXJldHVybi0xO3ZhciByPWktMTtmb3IoMTxhcmd1bWVudHMubGVuZ3RoJiYocj1NYXRoLm1pbihyLHRvSW50ZWdlcihhcmd1bWVudHNbMV0pKSkscj0wPD1yP3I6aS1NYXRoLmFicyhyKTswPD1yO3ItLSlpZihyIGluIGUmJnQ9PT1lW3JdKXJldHVybiByO3JldHVybi0xfSk7dmFyIEQ9e307RC5lZz1GdW5jdGlvbixGdW5jdGlvbi5qZj1mdW5jdGlvbigpe30sRnVuY3Rpb24uaWRlbnRpdHk9ZnVuY3Rpb24odCl7cmV0dXJuIHR9LEZ1bmN0aW9uLnBnPWZ1bmN0aW9uKHQsZSl7dmFyIGU9ZXx8T2JqZWN0LllmLHQ9dHx8RnVuY3Rpb24uaWRlbnRpdHksaT1mdW5jdGlvbihpLHIpe3JldHVybiBlKHQoaSksdChyKSl9O3JldHVybiBpLllmPWUsaS5wZz10LGl9LEQuZWcmJihEPUQuZWcpO3ZhciBIPXt9O0guZWc9cixyLnlnPXtkZzpcIitcIixtZzpcIi1cIix3ZzpcIitcIixUZzpcIitcIixTZzpcIi5cIixiZzpcIidcIixFZzpcIitcIixJZzpcInxcIn0sci5SZz17ZGc6XCLilYtcIixtZzpcIuKUgVwiLHdnOlwi4pS7XCIsVGc6XCLilLNcIixTZzpcIuKVrVwiLGJnOlwi4pWwXCIsRWc6XCLilKNcIixJZzpcIuKUg1wifSxyLmtnPXtkZzpcIuKVi1wiLG1nOlwi4pSBXCIsd2c6XCLilLtcIixUZzpcIuKUs1wiLFNnOlwi4pSPXCIsYmc6XCLilJdcIixFZzpcIuKUo1wiLElnOlwi4pSDXCJ9LEguZWcmJihIPUguZWcpO3ZhciBMLE09e30saj1NO2lmKFwidW5kZWZpbmVkXCIhPXR5cGVvZiBXZWFrTWFwKUw9V2Vha01hcDtlbHNle3ZhciBVPWZ1bmN0aW9uKHQpe3JldHVybiB0LnByb3RvdHlwZT1udWxsLE9iamVjdC5mcmVlemUodCl9LFY9T2JqZWN0LmdldE93blByb3BlcnR5TmFtZXMsUT1PYmplY3QuZGVmaW5lUHJvcGVydHkscT17fTtWKE9iamVjdCkuZm9yRWFjaChmdW5jdGlvbih0KXtxW3RdPU9iamVjdFt0XX0pO3ZhciBKPVwiaWRlbnQ6XCIrTWF0aC5yYW5kb20oKStcIl9fX1wiO2lmKFwidW5kZWZpbmVkXCIhPXR5cGVvZiBjcnlwdG8mJlwiZnVuY3Rpb25cIj09dHlwZW9mIGNyeXB0by5nZXRSYW5kb21WYWx1ZXMmJlwiZnVuY3Rpb25cIj09dHlwZW9mIEFycmF5QnVmZmVyJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBVaW50OEFycmF5KXt2YXIgSz1uZXcgQXJyYXlCdWZmZXIoMjUpLEs9bmV3IFVpbnQ4QXJyYXkoSyk7Y3J5cHRvLmdldFJhbmRvbVZhbHVlcyhLKSxKPVwicmFuZDpcIitBcnJheS5wcm90b3R5cGUubWFwLmNhbGwoSyxmdW5jdGlvbih0KXtyZXR1cm4odCUzNikudG9TdHJpbmcoMzYpfSkuam9pbihcIlwiKStcIl9fX1wifVEoT2JqZWN0LFwiZ2V0T3duUHJvcGVydHlOYW1lc1wiLHt2YWx1ZTpmdW5jdGlvbih0KXtyZXR1cm4gVih0KS5maWx0ZXIoZnVuY3Rpb24odCl7cmV0dXJuIHQhPT1KfSl9fSksXCJnZXRQcm9wZXJ0eU5hbWVzXCJpbiBPYmplY3QmJlEoT2JqZWN0LFwiZ2V0UHJvcGVydHlOYW1lc1wiLHt2YWx1ZTpmdW5jdGlvbih0KXtyZXR1cm4gcS5nZXRQcm9wZXJ0eU5hbWVzKHQpLmZpbHRlcihmdW5jdGlvbih0KXtyZXR1cm4gdCE9PUp9KX19KTt2YXIgRz1mdW5jdGlvbih0KXtpZih0IT09T2JqZWN0KHQpKXRocm93IG5ldyBUeXBlRXJyb3IoXCJOb3QgYW4gb2JqZWN0OiBcIit0KTt2YXIgZT10W0pdO3JldHVybiBlJiZlLmtleT09PXQ/ZTpxLmlzRXh0ZW5zaWJsZSh0KT8oZT17a2V5OnQsQ2c6W10sT2c6W119LFEodCxKLHt2YWx1ZTplLFBnOiExLEFnOiExLE5nOiExfSksZSk6dm9pZCAwfSx6PU9iamVjdC5mcmVlemU7UShPYmplY3QsXCJmcmVlemVcIix7dmFsdWU6ZnVuY3Rpb24odCl7cmV0dXJuIEcodCkseih0KX19KTt2YXIgVz1PYmplY3Quc2VhbDtRKE9iamVjdCxcInNlYWxcIix7dmFsdWU6ZnVuY3Rpb24odCl7cmV0dXJuIEcodCksVyh0KX19KTt2YXIgJD1PYmplY3QucHJldmVudEV4dGVuc2lvbnM7UShPYmplY3QsXCJwcmV2ZW50RXh0ZW5zaW9uc1wiLHt2YWx1ZTpmdW5jdGlvbih0KXtyZXR1cm4gRyh0KSwkKHQpfX0pO3ZhciBZPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdChyLG4pe3ZhciBvLHM9RyhyKTtyZXR1cm4gcz8obz1zLkNnLmluZGV4T2YodCkscz1zLk9nKToobz1lLmluZGV4T2Yocikscz1pKSwwPD1vP3Nbb106bn12YXIgZT1bXSxpPVtdO3JldHVybiBPYmplY3QuY3JlYXRlKFkucHJvdG90eXBlLHt4Zzp7dmFsdWU6VSh0KX0sQmc6e3ZhbHVlOlUoZnVuY3Rpb24oaSl7dmFyIHI9RyhpKTtyZXR1cm4gMDw9KHI/ci5DZy5pbmRleE9mKHQpOmUuaW5kZXhPZihpKSl9KX0sRmc6e3ZhbHVlOlUoZnVuY3Rpb24ocixuKXt2YXIgbyxzPUcocik7cz8obz1zLkNnLmluZGV4T2YodCksMDw9bz9zLk9nW29dPW46KHMuQ2cucHVzaCh0KSxzLk9nLnB1c2gobikpKToobz1lLmluZGV4T2YociksMDw9bz9pW29dPW46KGUucHVzaChyKSxpLnB1c2gobikpKX0pfSxfZzp7dmFsdWU6VShmdW5jdGlvbihyKXt2YXIgbj1HKHIpO3JldHVybiBuPyhyPW4uQ2cuaW5kZXhPZih0KSwwPD1yJiYobi5DZy5zcGxpY2UociwxKSxuLk9nLnNwbGljZShyLDEpKSk6KHI9ZS5pbmRleE9mKHIpLDA8PXImJihlLnNwbGljZShyLDEpLGkuc3BsaWNlKHIsMSkpKSwhMH0pfX0pfTtZLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKE9iamVjdC5wcm90b3R5cGUse2dldDp7dmFsdWU6ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy54Zyh0LGUpfSxQZzohMCxOZzohMH0saGFzOnt2YWx1ZTpmdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5CZyh0KX0sUGc6ITAsTmc6ITB9LHNldDp7dmFsdWU6ZnVuY3Rpb24odCxlKXt0aGlzLkZnKHQsZSl9LFBnOiEwLE5nOiEwfSxcImRlbGV0ZVwiOnt2YWx1ZTpmdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5fZyh0KX0sUGc6ITAsTmc6ITB9fSksTD1ZfWouZWc9TCxNLmVnJiYoTT1NLmVnKTt2YXIgWD17fSxaPU0sdHQ9T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSxldD1uZXcgWixpdD1uZXcgWjtYLmVnPW4sbi5wcm90b3R5cGUuRGc9ZnVuY3Rpb24odCl7ZXQuaGFzKHRoaXMpfHxldC5zZXQodGhpcyx7fSk7dmFyIGU9ZXQuZ2V0KHRoaXMpO3JldHVybiB0dC5jYWxsKGUsdCl8fChlW3RdPXtIZzpbXSxMZzpbXX0pLGVbdF19LG4ucHJvdG90eXBlLk1nPWZ1bmN0aW9uKHQpe2lmKCFldC5oYXModGhpcykpcmV0dXJuITE7aWYoIXQpcmV0dXJuITA7dmFyIGU9ZXQuZ2V0KHRoaXMpO3JldHVybiEhdHQuY2FsbChlLHQpfSxuLnByb3RvdHlwZS5qZz1mdW5jdGlvbih0LGUsaSl7dGhpcy5tYWtlT2JzZXJ2YWJsZSYmIXRoaXMuaXNPYnNlcnZhYmxlJiZ0aGlzLm1ha2VPYnNlcnZhYmxlKCk7dmFyIHI9bi5EZyh0aGlzLHQpLGk9aT9yLkhnOnIuTGc7bi5VZyh0aGlzLHQpLGkucHVzaChlKX0sbi5wcm90b3R5cGUuVmc9ZnVuY3Rpb24odCxlKXtyZXR1cm4gbi5qZyh0aGlzLHQsZSwhMCl9LG4ucHJvdG90eXBlLlFnPWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj1uLkRnKHRoaXMsdCksaT1pP3IuSGc6ci5MZyxlPWkubGFzdEluZGV4T2YoZSk7aWYoLTE9PT1lKXRocm93IEVycm9yKFwiQ2FuJ3QgcmVtb3ZlIGxpc3RlbmVyOiBkb2VzIG5vdCBleGlzdC5cIik7aS5zcGxpY2UoZSwxKSwwPT09ci5MZy5sZW5ndGgrci5IZy5sZW5ndGgmJm4ucWcodGhpcyx0KX0sbi5wcm90b3R5cGUuSmc9ZnVuY3Rpb24odCxlKXtyZXR1cm4gbi5RZyh0aGlzLHQsZSwhMCl9LG4ucHJvdG90eXBlLktnPWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj1uLkRnKHRoaXMsdCkscj1pP3IuSGc6ci5MZyxpPShpP1wiV2lsbFwiOlwiXCIpK1wiQ2hhbmdlXCIsbz1cImhhbmRsZVByb3BlcnR5XCIraSxzPVN0cmluZyh0KSxzPXMmJnNbMF0udG9VcHBlckNhc2UoKStzLnNsaWNlKDEpLGE9XCJoYW5kbGVcIitzK2k7ci5mb3JFYWNoKGZ1bmN0aW9uKGkpe3ZhciByPWksaT1pW2FdfHxpW29dfHxpO2kuY2FsbCYmaS5jYWxsKHIsZSx0LHRoaXMpfSx0aGlzKX0sbi5wcm90b3R5cGUuR2c9ZnVuY3Rpb24odCxlKXtyZXR1cm4gbi5LZyh0aGlzLHQsZSwhMCl9LG4ucHJvdG90eXBlLlVnPWZ1bmN0aW9uKHQpe2lmKCFBcnJheS5pc0FycmF5KHRoaXMpKXtpdC5oYXModGhpcyl8fChlPXt9LGl0LnNldCh0aGlzLGUpKTt2YXIgZT1pdC5nZXQodGhpcyk7aWYoIXR0LmNhbGwoZSx0KSl7dmFyIGkscj10aGlzO09iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iocix0KTtkb3tpZihpPU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3Iocix0KSlicmVhaztyPU9iamVjdC5nZXRQcm90b3R5cGVPZihyKX13aGlsZShyKTtpZihpPWl8fHt2YWx1ZTp2b2lkIDAsQWc6ITAsUGc6ITAsTmc6ITB9LCFpLk5nKXRocm93IEVycm9yKFwiQ2FuJ3Qgb2JzZXJ2ZSBub24tY29uZmlndXJhYmxlIHByb3BlcnRpZXNcIik7ZVt0XT1pLChpLlBnfHxpLnNldCkmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLHQsXCJ2YWx1ZVwiaW4gaT97Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIGkudmFsdWV9LHNldDpmdW5jdGlvbihlKXtyZXR1cm4gZT09PWkudmFsdWU/ZToobi5HZyh0aGlzLHQsaS52YWx1ZSksaS52YWx1ZT1lLG4uS2codGhpcyx0LGUpLGUpfSxBZzppLkFnLE5nOiEwfTp7Z2V0OmZ1bmN0aW9uKCl7aWYoaS5nZXQpcmV0dXJuIGkuZ2V0LmFwcGx5KHRoaXMsYXJndW1lbnRzKX0sc2V0OmZ1bmN0aW9uKGUpe3ZhciByO3JldHVybiBpLmdldCYmKHI9aS5nZXQuYXBwbHkodGhpcyxhcmd1bWVudHMpKSxlPT09cj9lOihuLkdnKHRoaXMsdCxyKSxpLnNldCYmaS5zZXQuYXBwbHkodGhpcyxhcmd1bWVudHMpLGkuZ2V0JiYoZT1pLmdldC5hcHBseSh0aGlzLGFyZ3VtZW50cykpLG4uS2codGhpcyx0LGUpLGUpfSxBZzppLkFnLE5nOiEwfSl9fX0sbi5wcm90b3R5cGUucWc9ZnVuY3Rpb24odCl7aWYoIUFycmF5LmlzQXJyYXkodGhpcykpe2lmKCFpdC5oYXModGhpcykpdGhyb3cgRXJyb3IoXCJDYW4ndCB1bmluc3RhbGwgb2JzZXJ2ZXIgb24gcHJvcGVydHlcIik7dmFyIGU9aXQuZ2V0KHRoaXMpO2lmKCFlW3RdKXRocm93IEVycm9yKFwiQ2FuJ3QgdW5pbnN0YWxsIG9ic2VydmVyIG9uIHByb3BlcnR5XCIpO3ZhciBpPWVbdF07ZGVsZXRlIGVbdF0sT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsdCxpKX19LG4uRGc9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdC5EZz90LkRnKGUpOm4ucHJvdG90eXBlLkRnLmNhbGwodCxlKX0sbi5NZz1mdW5jdGlvbih0LGUpe3JldHVybiB0Lk1nP3QuTWcoZSk6bi5wcm90b3R5cGUuTWcuY2FsbCh0LGUpfSxuLmpnPWZ1bmN0aW9uKHQsZSxpLHIpe3JldHVybiB0LmpnP3QuamcoZSxpLHIpOm4ucHJvdG90eXBlLmpnLmNhbGwodCxlLGkscil9LG4uUWc9ZnVuY3Rpb24odCxlLGkscil7cmV0dXJuIHQuUWc/dC5RZyhlLGkscik6bi5wcm90b3R5cGUuUWcuY2FsbCh0LGUsaSxyKX0sbi5LZz1mdW5jdGlvbih0LGUsaSxyKXtyZXR1cm4gdC5LZz90LktnKGUsaSxyKTpuLnByb3RvdHlwZS5LZy5jYWxsKHQsZSxpLHIpfSxuLlZnPWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gbi5qZyh0LGUsaSwhMCl9LG4uSmc9ZnVuY3Rpb24odCxlLGkpe3JldHVybiBuLlFnKHQsZSxpLCEwKX0sbi5HZz1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIG4uS2codCxlLGksITApfSxuLlVnPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHQuVWc/dC5VZyhlKTpuLnByb3RvdHlwZS5VZy5jYWxsKHQsZSl9LG4ucWc9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdC5xZz90LnFnKGUpOm4ucHJvdG90eXBlLnFnLmNhbGwodCxlKX0sWC5lZyYmKFg9WC5lZyk7dmFyIHJ0PXt9LG50PW5ldyBNO3J0LmVnPW8sby5wcm90b3R5cGUuemc9ZnVuY3Rpb24oKXtyZXR1cm4gbnQuaGFzKHRoaXMpfHxudC5zZXQodGhpcyx7c3Q6ITEsTGc6W10sSGc6W119KSxudC5nZXQodGhpcyl9LG8ucHJvdG90eXBlLldnPWZ1bmN0aW9uKHQsZSl7IXRoaXMuaXNPYnNlcnZhYmxlJiZ0aGlzLm1ha2VPYnNlcnZhYmxlJiZ0aGlzLm1ha2VPYnNlcnZhYmxlKCk7dmFyIGk9dGhpcy56ZygpOyhlP2kuSGc6aS5MZykucHVzaCh0KSx0aGlzLiRnPSEhKGkuSGcubGVuZ3RoK2kuTGcubGVuZ3RoKX0sby5wcm90b3R5cGUuWWc9ZnVuY3Rpb24odCxlKXt2YXIgaSxyPXRoaXMuemcoKTtpPWU/ci5IZzpyLkxnO3ZhciBuPWkubGFzdEluZGV4T2YodCk7aWYoLTE9PT1uKXRocm93IEVycm9yKFwiQ2FuJ3QgcmVtb3ZlIGxpc3RlbmVyOiBkb2VzIG5vdCBleGlzdC5cIik7aS5zcGxpY2UobiwxKSx0aGlzLiRnPSEhKHIuSGcubGVuZ3RoK3IuTGcubGVuZ3RoKX0sby5wcm90b3R5cGUuWGc9ZnVuY3Rpb24odCxlLGkscil7dmFyIG49dGhpcy56ZygpO2lmKCFuLnN0KXtuLnN0PSEwO3ZhciBvO289cj9uLkhnOm4uTGc7dHJ5e28uZm9yRWFjaChmdW5jdGlvbihuKXtuLnlkP24ueWQoe1pnOnI/XCJiZWZvcmVcIjpcImFmdGVyXCIsY3VycmVudFRhcmdldDp0aGlzLHRhcmdldDp0aGlzLHR2OnQsZXY6ZSxpbmRleDppfSk6KG49cj9uLmhhbmRsZVJhbmdlV2lsbENoYW5nZXx8bjpuLmhhbmRsZVJhbmdlQ2hhbmdlfHxuLG4uY2FsbCYmbi5jYWxsKHRoaXMsdCxlLGkscikpfSx0aGlzKX1maW5hbGx5e24uc3Q9ITF9fX0sby5wcm90b3R5cGUuaXY9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuV2codCwhMCl9LG8ucHJvdG90eXBlLnJ2PWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLllnKHQsITApfSxvLnByb3RvdHlwZS5udj1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIHRoaXMuWGcodCxlLGksITApfSxydC5lZyYmKHJ0PXJ0LmVnKTt2YXIgb3Q9e30sc3Q9TTtvdC5lZz1PYmplY3QsT2JqZWN0LmVtcHR5PU9iamVjdC5mcmVlemUoT2JqZWN0LmNyZWF0ZShudWxsKSksT2JqZWN0Lm92PWZ1bmN0aW9uKHQpe3JldHVybiBPYmplY3QodCk9PT10fSxPYmplY3Quc3Y9ZnVuY3Rpb24odCl7cmV0dXJuIE9iamVjdC52Zyh0LFwidmFsdWVPZlwiKSYmKHQ9dC52YWx1ZU9mKCkpLHR9O3ZhciBhdD1uZXcgc3Q7T2JqZWN0Lmhhc2g9ZnVuY3Rpb24odCl7cmV0dXJuIE9iamVjdC52Zyh0LFwiaGFzaFwiKT9cIlwiK3QuaGFzaCgpOk9iamVjdCh0KT09PXQ/KGF0Lmhhcyh0KXx8YXQuc2V0KHQsTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc2xpY2UoMikpLGF0LmdldCh0KSk6XCJcIit0fTt2YXIgY3Q9T2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtPYmplY3QuYXY9ZnVuY3Rpb24odCxlKXtyZXR1cm4gY3QuY2FsbCh0LGUpfSxPYmplY3Qudmc9ZnVuY3Rpb24odCxlKXtyZXR1cm4gbnVsbCE9dCYmXCJmdW5jdGlvblwiPT10eXBlb2YgdFtlXSYmIWN0LmNhbGwodCxlKX0sT2JqZWN0Lmhhcz1mdW5jdGlvbih0LGUpe2lmKFwib2JqZWN0XCIhPXR5cGVvZiB0KXRocm93IEVycm9yKFwiT2JqZWN0LmhhcyBjYW4ndCBhY2NlcHQgbm9uLW9iamVjdDogXCIrdHlwZW9mIHQpO2lmKE9iamVjdC52Zyh0LFwiaGFzXCIpKXJldHVybiB0LmhhcyhlKTtpZihcInN0cmluZ1wiPT10eXBlb2YgZSlyZXR1cm4gZSBpbiB0JiZ0W2VdIT09T2JqZWN0LnByb3RvdHlwZVtlXTt0aHJvdyBFcnJvcihcIktleSBtdXN0IGJlIGEgc3RyaW5nIGZvciBPYmplY3QuaGFzIG9uIHBsYWluIG9iamVjdHNcIil9LE9iamVjdC5nZXQ9ZnVuY3Rpb24odCxlLGkpe2lmKFwib2JqZWN0XCIhPXR5cGVvZiB0KXRocm93IEVycm9yKFwiT2JqZWN0LmdldCBjYW4ndCBhY2NlcHQgbm9uLW9iamVjdDogXCIrdHlwZW9mIHQpO3JldHVybiBPYmplY3QudmcodCxcImdldFwiKT90LmdldChlLGkpOk9iamVjdC5oYXModCxlKT90W2VdOml9LE9iamVjdC5zZXQ9ZnVuY3Rpb24odCxlLGkpe09iamVjdC52Zyh0LFwic2V0XCIpP3Quc2V0KGUsaSk6dFtlXT1pfSxPYmplY3QuYWRkRWFjaD1mdW5jdGlvbih0LGUpe09iamVjdC52ZyhlLFwiZm9yRWFjaFwiKT9cImZ1bmN0aW9uXCI9PXR5cGVvZiBlLmtleXM/ZS5mb3JFYWNoKGZ1bmN0aW9uKGUsaSl7dFtpXT1lfSk6ZS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3RbZVswXV09ZVsxXX0pOk9iamVjdC5rZXlzKGUpLmZvckVhY2goZnVuY3Rpb24oaSl7dFtpXT1lW2ldfSl9LE9iamVjdC5mb3JFYWNoPWZ1bmN0aW9uKHQsZSxpKXtPYmplY3Qua2V5cyh0KS5mb3JFYWNoKGZ1bmN0aW9uKHIpe2UuY2FsbChpLHRbcl0scix0KX0pfSxPYmplY3QubWFwPWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gT2JqZWN0LmtleXModCkubWFwKGZ1bmN0aW9uKHIpe3JldHVybiBlLmNhbGwoaSx0W3JdLHIsdCl9KX0sT2JqZWN0LnZhbHVlcz1mdW5jdGlvbih0KXtyZXR1cm4gT2JqZWN0Lm1hcCh0LEZ1bmN0aW9uLmlkZW50aXR5KX0sT2JqZWN0LmlzPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHQ9PT1lPzAhPT10fHwxL3Q9PT0xL2U6dCE9PXQmJmUhPT1lfSxPYmplY3Qub2w9ZnVuY3Rpb24odCxlLGkpe2lmKGk9aXx8T2JqZWN0Lm9sLHQ9T2JqZWN0LnN2KHQpLGU9T2JqZWN0LnN2KGUpLHQ9PT1lKXJldHVybiAwIT09dHx8MS90PT09MS9lO2lmKE9iamVjdC52Zyh0LFwiZXF1YWxzXCIpKXJldHVybiB0Lm9sKGUsaSk7aWYoT2JqZWN0LnZnKGUsXCJlcXVhbHNcIikpcmV0dXJuIGUub2wodCxpKTtpZihcIm9iamVjdFwiPT10eXBlb2YgdCYmXCJvYmplY3RcIj09dHlwZW9mIGUpe3ZhciByPU9iamVjdC5nZXRQcm90b3R5cGVPZih0KSxuPU9iamVjdC5nZXRQcm90b3R5cGVPZihlKTtpZihyPT09biYmKHI9PT1PYmplY3QucHJvdG90eXBlfHxudWxsPT09cikpe2Zvcih2YXIgbyBpbiB0KWlmKCFpKHRbb10sZVtvXSkpcmV0dXJuITE7Zm9yKG8gaW4gZSlpZighaSh0W29dLGVbb10pKXJldHVybiExO3JldHVybiEwfX1yZXR1cm4gdCE9PXQmJmUhPT1lfSxPYmplY3QuWWY9ZnVuY3Rpb24odCxlKXt2YXIgdD1PYmplY3Quc3YodCksZT1PYmplY3Quc3YoZSksaT10eXBlb2YgdDtyZXR1cm4gdD09PWV8fGkhPT10eXBlb2YgZT8wOlwibnVtYmVyXCI9PT1pP3QtZTpcInN0cmluZ1wiPT09aT90PGU/LTE6MTpPYmplY3QudmcodCxcImNvbXBhcmVcIik/dC5ZZihlKTpPYmplY3QudmcoZSxcImNvbXBhcmVcIik/LWUuWWYodCk6MH0sT2JqZWN0LmNsb25lPWZ1bmN0aW9uKHQsZSxpKXtpZih0PU9iamVjdC5zdih0KSxpPWl8fG5ldyBzdCx2b2lkIDA9PT1lKWU9MS8wO2Vsc2UgaWYoMD09PWUpcmV0dXJuIHQ7aWYoT2JqZWN0Lm92KHQpKXtpZighaS5oYXModCkpaWYoT2JqZWN0LnZnKHQsXCJjbG9uZVwiKSlpLnNldCh0LHQuY2xvbmUoZSxpKSk7ZWxzZXt2YXIgcj1PYmplY3QuZ2V0UHJvdG90eXBlT2YodCk7aWYobnVsbCE9PXImJnIhPT1PYmplY3QucHJvdG90eXBlKXRocm93IEVycm9yKFwiQ2FuJ3QgY2xvbmUgXCIrdCk7cj1PYmplY3QuY3JlYXRlKHIpLGkuc2V0KHQscik7Zm9yKHZhciBuIGluIHQpcltuXT1PYmplY3QuY2xvbmUodFtuXSxlLTEsaSl9cmV0dXJuIGkuZ2V0KHQpfXJldHVybiB0fSxPYmplY3QuY2xlYXI9ZnVuY3Rpb24odCl7aWYoT2JqZWN0LnZnKHQsXCJjbGVhclwiKSl0LmNsZWFyKCk7ZWxzZSBmb3IodmFyIGU9T2JqZWN0LmtleXModCksaT1lLmxlbmd0aDtpOylpLS0sZGVsZXRlIHRbZVtpXV07cmV0dXJuIHR9LG90LmVnJiYob3Q9b3QuZWcpO3ZhciBodD17fSxwdD1vdDtodC5lZz1zLHMucHJvdG90eXBlLm9sPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIGU9ZXx8dGhpcy5NZnx8cHQub2wsdGhpcz09PXR8fCEhdCYmKHRoaXMubGVuZ3RoPT09dC5sZW5ndGgmJnRoaXMuY2codCkuZXZlcnkoZnVuY3Rpb24odCl7cmV0dXJuIGUodFswXSx0WzFdKX0pKX0scy5wcm90b3R5cGUuWWY9ZnVuY3Rpb24odCxlKXtpZihlPWV8fHRoaXMuJGZ8fHB0LllmLHRoaXM9PT10KXJldHVybiAwO2lmKCF0KXJldHVybiAxO3ZhciBpPU1hdGgubWluKHRoaXMubGVuZ3RoLHQubGVuZ3RoKSxyPXRoaXMuY2codCkucmVkdWNlKGZ1bmN0aW9uKHQscixuKXtyZXR1cm4gMD09PXQ/bj49aT90OmUoclswXSxyWzFdKTp0fSwwKTtyZXR1cm4gMD09PXI/dGhpcy5sZW5ndGgtdC5sZW5ndGg6cn0saHQuZWcmJihodD1odC5lZyk7dmFyIHV0PXt9O3V0LmVnPWE7dmFyIGx0PW90O2lmKGx0LmFkZEVhY2goYS5wcm90b3R5cGUseC5wcm90b3R5cGUpLGEucHJvdG90eXBlLm5nPWZ1bmN0aW9uKHQpe3ZhciBlPVtdO3JldHVybiBSZWR1Y2libGUuYWRkRWFjaC5jYWxsKGUsdCksZX0sYS5wcm90b3R5cGUuY3Y9ZnVuY3Rpb24odCxlKXt2YXIgaT1hKHRoaXMpLHI9MDtpZihcIltvYmplY3QgRnVuY3Rpb25dXCIhPWx0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpKXRocm93IG5ldyBUeXBlRXJyb3I7cmV0dXJuIG5ldyBpLmNvbnN0cnVjdG9yKGZ1bmN0aW9uKCl7cmV0dXJuIHQuY2FsbChlLGkubmV4dCgpLHIrKyxpKX0pfSxhLnByb3RvdHlwZS5odj1mdW5jdGlvbih0LGUpe3ZhciBpPWEodGhpcykscj0wO2lmKFwiW29iamVjdCBGdW5jdGlvbl1cIiE9bHQucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodCkpdGhyb3cgbmV3IFR5cGVFcnJvcjtyZXR1cm4gbmV3IGkuY29uc3RydWN0b3IoZnVuY3Rpb24oKXtmb3IodmFyIG47OylpZihuPWkubmV4dCgpLHQuY2FsbChlLG4scisrLGkpKXJldHVybiBufSl9LGEucHJvdG90eXBlLnJlZHVjZT1mdW5jdGlvbih0KXt2YXIgZSxpPWEodGhpcykscj1hcmd1bWVudHNbMV0sbj1hcmd1bWVudHNbMl0sbz0wO2lmKFwiW29iamVjdCBGdW5jdGlvbl1cIiE9bHQucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodCkpdGhyb3cgbmV3IFR5cGVFcnJvcjt0cnl7ZT1pLm5leHQoKSxyPTE8YXJndW1lbnRzLmxlbmd0aD90LmNhbGwobixyLGUsbyxpKTplLG8rK31jYXRjaChzKXtpZihpc1N0b3BJdGVyYXRpb24ocykpe2lmKDE8YXJndW1lbnRzLmxlbmd0aClyZXR1cm4gYXJndW1lbnRzWzFdO3Rocm93IFR5cGVFcnJvcihcImNhbm5vdCByZWR1Y2UgYSB2YWx1ZSBmcm9tIGFuIGVtcHR5IGl0ZXJhdG9yIHdpdGggbm8gaW5pdGlhbCB2YWx1ZVwiKX10aHJvdyBzfXRyeXtmb3IoOzspZT1pLm5leHQoKSxyPXQuY2FsbChuLHIsZSxvLGkpLG8rK31jYXRjaChjKXtpZihpc1N0b3BJdGVyYXRpb24oYykpcmV0dXJuIHI7dGhyb3cgY319LGEucHJvdG90eXBlLmV2ZXJ5PWZ1bmN0aW9uKHQpe3ZhciBlPWEodGhpcyksaT0hMDtpZihcIltvYmplY3QgRnVuY3Rpb25dXCIhPWx0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpKXRocm93IG5ldyBUeXBlRXJyb3I7cmV0dXJuIGUuY3YuYXBwbHkoZSxhcmd1bWVudHMpLmZvckVhY2goZnVuY3Rpb24odCl7aWYoIXQpdGhyb3cgaT0hMSxTdG9wSXRlcmF0aW9ufSksaX0sYS5wcm90b3R5cGUuc29tZT1mdW5jdGlvbih0KXt2YXIgZT1hKHRoaXMpLGk9ITE7aWYoXCJbb2JqZWN0IEZ1bmN0aW9uXVwiIT1sdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KSl0aHJvdyBuZXcgVHlwZUVycm9yO3JldHVybiBlLmN2LmFwcGx5KGUsYXJndW1lbnRzKS5mb3JFYWNoKGZ1bmN0aW9uKHQpe2lmKHQpdGhyb3cgaT0hMCxTdG9wSXRlcmF0aW9ufSksaX0sYS5wcm90b3R5cGUuY29uY2F0PWZ1bmN0aW9uKCl7cmV0dXJuIGEuY29uY2F0KEFycmF5LnByb3RvdHlwZS5jb25jYXQuYXBwbHkodGhpcyxhcmd1bWVudHMpKX0sYS5wcm90b3R5cGUucHY9ZnVuY3Rpb24odCxlKXt2YXIgaSxyPWEodGhpcyksbj0hMTtpZihcIltvYmplY3QgRnVuY3Rpb25dXCIhPWx0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpKXRocm93IG5ldyBUeXBlRXJyb3I7cmV0dXJuIHIuZm9yRWFjaChmdW5jdGlvbihvLHMpe2lmKCF0LmNhbGwoZSxvLHMscikpdGhyb3cgbj0hMCxpPW8sU3RvcEl0ZXJhdGlvbn0pLG4/ci5jb25zdHJ1Y3RvcihbaV0pLmNvbmNhdChyKTpyLmNvbnN0cnVjdG9yKFtdKX0sYS5wcm90b3R5cGUudXY9ZnVuY3Rpb24odCxlKXt2YXIgaT1hKHRoaXMpO2lmKFwiW29iamVjdCBGdW5jdGlvbl1cIiE9bHQucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodCkpdGhyb3cgbmV3IFR5cGVFcnJvcjtyZXR1cm4gaS5jdihmdW5jdGlvbihyLG4pe2lmKCF0LmNhbGwoZSxyLG4saSkpdGhyb3cgU3RvcEl0ZXJhdGlvbjtyZXR1cm4gcn0pfSxhLnByb3RvdHlwZS5odj1mdW5jdGlvbih0LGUpe3ZhciBpPWEodGhpcykscj0wO2lmKFwiW29iamVjdCBGdW5jdGlvbl1cIiE9bHQucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodCkpdGhyb3cgbmV3IFR5cGVFcnJvcjtyZXR1cm4gbmV3IGkuY29uc3RydWN0b3IoZnVuY3Rpb24oKXtmb3IodmFyIG47OylpZihuPWkubmV4dCgpLHQuY2FsbChlLG4scisrLGkpKXJldHVybiBufSl9LGEucHJvdG90eXBlLmNnPWZ1bmN0aW9uKCl7cmV0dXJuIGEubHYoQXJyYXkucHJvdG90eXBlLmNvbmNhdC5hcHBseSh0aGlzLGFyZ3VtZW50cykpfSxhLnByb3RvdHlwZS5lbnVtZXJhdGU9ZnVuY3Rpb24odCl7cmV0dXJuIGEuY291bnQodCkuY2codGhpcyl9LGEuRGY9ZnVuY3Rpb24odCl7dmFyIGU7cmV0dXJuIGU9MCxuZXcgYShmdW5jdGlvbigpe2lmKFwib2JqZWN0XCI9PXR5cGVvZiB0KWZvcig7IShlIGluIHQpOyl7aWYoZT49dC5sZW5ndGgpdGhyb3cgU3RvcEl0ZXJhdGlvbjtlKz0xfWVsc2UgaWYoZT49dC5sZW5ndGgpdGhyb3cgU3RvcEl0ZXJhdGlvbjt2YXIgaT10W2VdO3JldHVybiBlKz0xLGl9KX0sYS5kdj1mdW5jdGlvbih0LGUpezI+YXJndW1lbnRzLmxlbmd0aCYmKGU9MS8wKTt2YXIgaT1mdW5jdGlvbigpe3Rocm93IFN0b3BJdGVyYXRpb259O3JldHVybiBuZXcgYShmdW5jdGlvbigpe3ZhciByO3RyeXtyZXR1cm4gaSgpfWNhdGNoKG4pe2lmKGlzU3RvcEl0ZXJhdGlvbihuKSl7aWYoMD49ZSl0aHJvdyBuO3JldHVybiBlLS0scj1hLkRmKHQpLChpPXIubmV4dC5iaW5kKHIpKSgpfXRocm93IG59fSl9LGEuY29uY2F0PWZ1bmN0aW9uKHQpe3ZhciB0PWEodCksZT1mdW5jdGlvbigpe3Rocm93IFN0b3BJdGVyYXRpb259O3JldHVybiBuZXcgYShmdW5jdGlvbigpe3ZhciBpO3RyeXtyZXR1cm4gZSgpfWNhdGNoKHIpe2lmKGlzU3RvcEl0ZXJhdGlvbihyKSlyZXR1cm4gaT1hKHQubmV4dCgpKSwoZT1pLm5leHQuYmluZChpKSkoKTt0aHJvdyByfX0pfSxhLmx2PWZ1bmN0aW9uKHQpe3JldHVybiB0PWEodCkubWFwKGEpLG5ldyBhKDE+dC5sZW5ndGg/W106ZnVuY3Rpb24oKXt2YXIgZSxpPXQubWFwKGZ1bmN0aW9uKHQpe3RyeXtyZXR1cm4gdC5uZXh0KCl9Y2F0Y2goaSl7aWYoIWlzU3RvcEl0ZXJhdGlvbihpKSl0aHJvdyBpO2U9ITB9fSk7aWYoZSl0aHJvdyBTdG9wSXRlcmF0aW9uO3JldHVybiBpfSl9LGEuY2c9ZnVuY3Rpb24oKXtyZXR1cm4gYS5sdihBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKX0sYS5jaGFpbj1mdW5jdGlvbigpe3JldHVybiBhLmNvbmNhdChBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKX0sYS5yYW5nZT1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIDM+YXJndW1lbnRzLmxlbmd0aCYmKGk9MSksMj5hcmd1bWVudHMubGVuZ3RoJiYoZT10LHQ9MCksdD10fHwwLG5ldyBhKGZ1bmN0aW9uKCl7aWYodD49ZSl0aHJvdyBTdG9wSXRlcmF0aW9uO2lmKGlzTmFOKHQpKXRocm93XCJcIjt2YXIgcj10O3JldHVybiB0Kz1pLHJ9KX0sYS5jb3VudD1mdW5jdGlvbih0LGUpe3JldHVybiBhLnJhbmdlKHQsMS8wLGV8fDEpfSxhLnJlcGVhdD1mdW5jdGlvbih0LGUpe3JldHVybiAyPmFyZ3VtZW50cy5sZW5ndGgmJihlPTEvMCksbmV3IGEucmFuZ2UoKCtlKSkuY3YoZnVuY3Rpb24oKXtyZXR1cm4gdH0pfSxcInVuZGVmaW5lZFwiPT10eXBlb2YgaXNTdG9wSXRlcmF0aW9uJiYodC5mdj1mdW5jdGlvbih0KXtyZXR1cm5cIltvYmplY3QgU3RvcEl0ZXJhdGlvbl1cIj09PWx0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpfSksXCJ1bmRlZmluZWRcIj09dHlwZW9mIFN0b3BJdGVyYXRpb24pe3QuU3RvcEl0ZXJhdGlvbj17fTt2YXIgZHQ9bHQucHJvdG90eXBlLnRvU3RyaW5nO2x0LnByb3RvdHlwZS50b1N0cmluZz1mdW5jdGlvbigpe3JldHVybiB0aGlzPT09dC5TdG9wSXRlcmF0aW9ufHx0aGlzIGluc3RhbmNlb2YgdC5ndj9cIltvYmplY3QgU3RvcEl0ZXJhdGlvbl1cIjpkdC5jYWxsKHRoaXMsYXJndW1lbnRzKX19XCJ1bmRlZmluZWRcIj09dHlwZW9mIFJldHVyblZhbHVlJiYodC5ndj1mdW5jdGlvbihlKXtyZXR1cm4gdGhpcyBpbnN0YW5jZW9mIHQuZ3Y/dm9pZCh0aGlzLnZhbHVlPWUpOm5ldyB0Lmd2KGUpfSksdXQuZWcmJih1dD11dC5lZyk7dmFyIGZ0PXt9LGd0PXgsdnQ9aHQseXQ9TTtmdC5lZz1BcnJheSxBcnJheS5lbXB0eT1bXSxPYmplY3QuZnJlZXplJiZPYmplY3QuZnJlZXplKEFycmF5LmVtcHR5KSxBcnJheS5mcm9tPWZ1bmN0aW9uKHQpe3ZhciBlPVtdO3JldHVybiBlLmFkZEVhY2godCksZX0sQXJyYXkucHJvdG90eXBlLmFkZEVhY2g9Z3QucHJvdG90eXBlLmFkZEVhY2gsQXJyYXkucHJvdG90eXBlLmlnPWd0LnByb3RvdHlwZS5pZyxBcnJheS5wcm90b3R5cGUudG9BcnJheT1ndC5wcm90b3R5cGUudG9BcnJheSxBcnJheS5wcm90b3R5cGUucmc9Z3QucHJvdG90eXBlLnJnLEFycmF5LnByb3RvdHlwZS5hbGw9Z3QucHJvdG90eXBlLmFsbCxBcnJheS5wcm90b3R5cGUuaWU9Z3QucHJvdG90eXBlLmllLEFycmF5LnByb3RvdHlwZS5taW49Z3QucHJvdG90eXBlLm1pbixBcnJheS5wcm90b3R5cGUubWF4PWd0LnByb3RvdHlwZS5tYXgsQXJyYXkucHJvdG90eXBlLm9nPWd0LnByb3RvdHlwZS5vZyxBcnJheS5wcm90b3R5cGUuc2c9Z3QucHJvdG90eXBlLnNnLEFycmF5LnByb3RvdHlwZS5vbmx5PWd0LnByb3RvdHlwZS5vbmx5LEFycmF5LnByb3RvdHlwZS5hZz1ndC5wcm90b3R5cGUuYWcsQXJyYXkucHJvdG90eXBlLmNnPWd0LnByb3RvdHlwZS5jZyxBcnJheS5wcm90b3R5cGUuaGc9Z3QucHJvdG90eXBlLmhnLEFycmF5LnByb3RvdHlwZS5yZXZlcnNlZD1ndC5wcm90b3R5cGUucmV2ZXJzZWQsQXJyYXkucHJvdG90eXBlLm5nPWZ1bmN0aW9uKHQpe3ZhciBlPW5ldyB0aGlzLmNvbnN0cnVjdG9yO3JldHVybiBlLmFkZEVhY2godCksZX0sQXJyYXkucHJvdG90eXBlLmhhcz1mdW5jdGlvbih0LGUpe3JldHVybi0xIT09dGhpcy5maW5kKHQsZSl9LEFycmF5LnByb3RvdHlwZS5nZXQ9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXNbdF19LEFycmF5LnByb3RvdHlwZS5zZXQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5zcGxpY2UodCwxLGUpLCEwfSxBcnJheS5wcm90b3R5cGUuYWRkPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLnB1c2godCksITB9LEFycmF5LnByb3RvdHlwZVtcImRlbGV0ZVwiXT1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMuZmluZCh0LGUpO3JldHVybi0xIT09aSYmKHRoaXMuc3BsaWNlKGksMSksITApfSxBcnJheS5wcm90b3R5cGUuZmluZD1mdW5jdGlvbih0LGUpe2Zvcih2YXIgZT1lfHx0aGlzLk1mfHxPYmplY3Qub2wsaT0wO2k8dGhpcy5sZW5ndGg7aSsrKWlmKGkgaW4gdGhpcyYmZSh0aGlzW2ldLHQpKXJldHVybiBpO3JldHVybi0xfSxBcnJheS5wcm90b3R5cGUudnY9ZnVuY3Rpb24odCxlKXt2YXIgZT1lfHx0aGlzLk1mfHxPYmplY3Qub2wsaT10aGlzLmxlbmd0aDtkbyBpZihpLS0saSBpbiB0aGlzJiZlKHRoaXNbaV0sdCkpcmV0dXJuIGk7d2hpbGUoMDxpKTtyZXR1cm4tMX0sQXJyYXkucHJvdG90eXBlLnl2PWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj1BcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMCwyKTtyZXR1cm4gaSYmci5wdXNoLmFwcGx5KHIsaSksdGhpcy5zcGxpY2UuYXBwbHkodGhpcyxyKX0sQXJyYXkucHJvdG90eXBlLnVnPWZ1bmN0aW9uKCl7aWYoMD09PXRoaXMubGVuZ3RoKXRocm93IEVycm9yKFwiQ2FuJ3QgZ2V0IG9uZSBlbGVtZW50IGZyb20gZW1wdHkgYXJyYXkuXCIpO2Zvcih2YXIgdCBpbiB0aGlzKWlmKE9iamVjdC5hdih0aGlzLHQpKXJldHVybiB0aGlzW3RdfSxBcnJheS5wcm90b3R5cGUuY2xlYXI9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5sZW5ndGg9MCx0aGlzfSxBcnJheS5wcm90b3R5cGUuWWY9ZnVuY3Rpb24odCxlKXt2YXIgaSxyLG4sbyxlPWV8fE9iamVjdC5ZZjtpZih0aGlzPT09dClyZXR1cm4gMDtpZighdHx8IUFycmF5LmlzQXJyYXkodCkpcmV0dXJuIHZ0LnByb3RvdHlwZS5ZZi5jYWxsKHRoaXMsdCxlKTtmb3Iocj1NYXRoLm1pbih0aGlzLmxlbmd0aCx0Lmxlbmd0aCksaT0wO2k8cjtpKyspaWYoaSBpbiB0aGlzKXtpZighKGkgaW4gdCkpcmV0dXJuLTE7aWYobj10aGlzW2ldLG89dFtpXSxuPWUobixvKSlyZXR1cm4gbn1lbHNlIGlmKGkgaW4gdClyZXR1cm4gMTtyZXR1cm4gdGhpcy5sZW5ndGgtdC5sZW5ndGh9LEFycmF5LnByb3RvdHlwZS5vbD1mdW5jdGlvbih0KXt2YXIgZSxpLHI9cnx8T2JqZWN0Lm9sLG49MCxvPXRoaXMubGVuZ3RoO2lmKHRoaXM9PT10KXJldHVybiEwO2lmKCF0fHwhQXJyYXkuaXNBcnJheSh0KSlyZXR1cm4gdnQucHJvdG90eXBlLm9sLmNhbGwodGhpcyx0KTtpZihvIT09dC5sZW5ndGgpcmV0dXJuITE7Zm9yKDtuPG87KytuKWlmKG4gaW4gdGhpcyl7aWYoZT10aGlzW25dLGk9dFtuXSxlIT09aSYmZSYmaSYmIXIoZSxpKSlyZXR1cm4hMX1lbHNlIGlmKG4gaW4gdClyZXR1cm4hMTtyZXR1cm4hMH0sQXJyYXkucHJvdG90eXBlLmNsb25lPWZ1bmN0aW9uKHQsZSl7aWYodm9pZCAwPT09dCl0PTEvMDtlbHNlIGlmKDA9PT10KXJldHVybiB0aGlzO3ZhciBpLGU9ZXx8bmV3IHl0LHI9W107Zm9yKGkgaW4gdGhpcylPYmplY3QuYXYodGhpcyxpKSYmKHJbaV09T2JqZWN0LmNsb25lKHRoaXNbaV0sdC0xLGUpKTtyZXR1cm4gcn0sQXJyYXkucHJvdG90eXBlLkRmPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIG5ldyBjKHRoaXMsdCxlKX0sQXJyYXkucHJvdG90eXBlLkl0ZXJhdG9yPWMsYy5wcm90b3R5cGUubmV4dD1mdW5jdGlvbigpe2lmKHRoaXMuc3RhcnQ9PT0obnVsbD09dGhpcy5lbmQ/dGhpcy5IZi5sZW5ndGg6dGhpcy5lbmQpKXRocm93IFN0b3BJdGVyYXRpb247cmV0dXJuIHRoaXMuSGZbdGhpcy5zdGFydCsrXX0sZnQuZWcmJihmdD1mdC5lZyk7dmFyIG10PXt9O210LmVnPWg7dmFyIHd0PWh0LFR0PVg7T2JqZWN0LmFkZEVhY2goaC5wcm90b3R5cGUseC5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKGgucHJvdG90eXBlLHd0LnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2goaC5wcm90b3R5cGUsVHQucHJvdG90eXBlKSxoLnByb3RvdHlwZS5uZz1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodCx0aGlzLk1mLHRoaXMuY29udGVudCl9LGgucHJvdG90eXBlLmZpbmQ9ZnVuY3Rpb24odCxlKXtmb3IodmFyIGU9ZXx8dGhpcy5NZixpPXRoaXMuaGVhZCxyPWkubmV4dDtyIT09aTspe2lmKGUoci52YWx1ZSx0KSlyZXR1cm4gcjtyPXIubmV4dH19LGgucHJvdG90eXBlLnZ2PWZ1bmN0aW9uKHQsZSl7Zm9yKHZhciBlPWV8fHRoaXMuTWYsaT10aGlzLmhlYWQscj1pLkxmO3IhPT1pOyl7aWYoZShyLnZhbHVlLHQpKXJldHVybiByO3I9ci5MZn19LGgucHJvdG90eXBlLmhhcz1mdW5jdGlvbih0LGUpe3JldHVybiEhdGhpcy5maW5kKHQsZSl9LGgucHJvdG90eXBlLmdldD1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMuZmluZCh0LGUpO3JldHVybiBpP2kudmFsdWU6dGhpcy5jb250ZW50KCl9LGgucHJvdG90eXBlW1wiZGVsZXRlXCJdPWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcy52dih0LGUpO3JldHVybiEhaSYmKGlbXCJkZWxldGVcIl0oKSx0aGlzLmxlbmd0aC0tLCEwKX0saC5wcm90b3R5cGUuY2xlYXI9ZnVuY3Rpb24oKXt0aGlzLmhlYWQubmV4dD10aGlzLmhlYWQuTGY9dGhpcy5oZWFkLHRoaXMubGVuZ3RoPTB9LGgucHJvdG90eXBlLmFkZD1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5oZWFkLm12KG5ldyB0aGlzLk5vZGUodCkpLHRoaXMubGVuZ3RoKyssITB9LGgucHJvdG90eXBlLnB1c2g9ZnVuY3Rpb24oKXtmb3IodmFyIHQ9dGhpcy5oZWFkLGU9MDtlPGFyZ3VtZW50cy5sZW5ndGg7ZSsrKXt2YXIgaT1uZXcgdGhpcy5Ob2RlKGFyZ3VtZW50c1tlXSk7dC5tdihpKSx0aGlzLmxlbmd0aCsrfX0saC5wcm90b3R5cGUudW5zaGlmdD1mdW5jdGlvbigpe2Zvcih2YXIgdD10aGlzLmhlYWQsZT0wO2U8YXJndW1lbnRzLmxlbmd0aDtlKyspe3ZhciBpPW5ldyB0aGlzLk5vZGUoYXJndW1lbnRzW2VdKTt0Lnd2KGkpLHRoaXMubGVuZ3RoKyssdD1pfX0saC5wcm90b3R5cGUucG9wPWZ1bmN0aW9uKCl7dmFyIHQsZT10aGlzLmhlYWQ7cmV0dXJuIGUuTGYhPT1lJiYodD1lLkxmLnZhbHVlLGUuTGZbXCJkZWxldGVcIl0oKSx0aGlzLmxlbmd0aC0tKSx0fSxoLnByb3RvdHlwZS5zaGlmdD1mdW5jdGlvbigpe3ZhciB0LGU9dGhpcy5oZWFkO3JldHVybiBlLkxmIT09ZSYmKHQ9ZS5uZXh0LnZhbHVlLGUubmV4dFtcImRlbGV0ZVwiXSgpLHRoaXMubGVuZ3RoLS0pLHR9LGgucHJvdG90eXBlLlR2PWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcy5oZWFkO2lmKFwibnVtYmVyXCI9PXR5cGVvZiB0KXt2YXIgcj10O2lmKDA8PXIpZm9yKHQ9aS5uZXh0O3ImJihyLS0sdD10Lm5leHQsISh0PT1pKSk7KTtlbHNlIGZvcih0PWk7MD5yJiYocisrLHQ9dC5MZiwhKHQ9PWkpKTspO3JldHVybiB0fXJldHVybiB0fHxlfSxoLnByb3RvdHlwZS5zbGljZT1mdW5jdGlvbih0LGUpe2Zvcih2YXIgaT1bXSxyPXRoaXMuaGVhZCx0PXRoaXMuVHYodCxyLm5leHQpLGU9dGhpcy5UdihlLHIpO3QhPT1lJiZ0IT09cjspaS5wdXNoKHQudmFsdWUpLHQ9dC5uZXh0O3JldHVybiBpfSxoLnByb3RvdHlwZS5zcGxpY2U9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy55dih0LGUsQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDIpKX0saC5wcm90b3R5cGUueXY9ZnVuY3Rpb24odCxlLGkpe3ZhciByPVtdLG49dCx0PXRoaXMuVHYodCx0aGlzLmhlYWQpO2Zvcih2b2lkIDA9PT1lJiYoZT0xLzApO2UtLSYmMDw9ZSYmdCE9PXRoaXMuaGVhZDspci5wdXNoKHQudmFsdWUpLHRbXCJkZWxldGVcIl0oKSx0PXQubmV4dCx0aGlzLmxlbmd0aC0tO2lmKGkpe2ZvcihudWxsPT09biYmdD09PXRoaXMuaGVhZCYmKHQ9dGhpcy5oZWFkLm5leHQpLGU9MDtlPGkubGVuZ3RoO2UrKyluPW5ldyB0aGlzLk5vZGUoaVtlXSksdC5tdihuKTt0aGlzLmxlbmd0aCs9aS5sZW5ndGh9cmV0dXJuIHJ9LGgucHJvdG90eXBlLnJldmVyc2U9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmhlYWQ7ZG97dmFyIGU9dC5uZXh0O3QubmV4dD10LkxmLHQuTGY9ZSx0PXQubmV4dH13aGlsZSh0IT09dGhpcy5oZWFkKTtyZXR1cm4gdGhpc30saC5wcm90b3R5cGUucmVkdWNlPWZ1bmN0aW9uKHQsZSxpKXtmb3IodmFyIHI9dGhpcy5oZWFkLG49ci5uZXh0O24hPT1yOyllPXQuY2FsbChpLGUsbi52YWx1ZSxuLHRoaXMpLG49bi5uZXh0O3JldHVybiBlfSxoLnByb3RvdHlwZS5yZWR1Y2VSaWdodD1mdW5jdGlvbih0LGUsaSl7Zm9yKHZhciByPXRoaXMuaGVhZCxuPXIuTGY7biE9PXI7KWU9dC5jYWxsKGksZSxuLnZhbHVlLG4sdGhpcyksbj1uLkxmO3JldHVybiBlfSxoLnByb3RvdHlwZS51Zz1mdW5jdGlvbigpe2lmKHRoaXMuaGVhZD09PXRoaXMuaGVhZC5uZXh0KXRocm93IEVycm9yKFwiQ2FuJ3QgZ2V0IG9uZSB2YWx1ZSBmcm9tIGVtcHR5IGxpc3RcIik7cmV0dXJuIHRoaXMuaGVhZC5uZXh0LnZhbHVlfSxoLnByb3RvdHlwZS5EZj1mdW5jdGlvbigpe3JldHVybiBuZXcgcCh0aGlzLmhlYWQpfSxwLnByb3RvdHlwZS5uZXh0PWZ1bmN0aW9uKCl7aWYodGhpcy5VZj09PXRoaXMuaGVhZCl0aHJvdyBTdG9wSXRlcmF0aW9uO3ZhciB0PXRoaXMuVWYudmFsdWU7cmV0dXJuIHRoaXMuVWY9dGhpcy5VZi5uZXh0LHR9LGgucHJvdG90eXBlLk5vZGU9dSx1LnByb3RvdHlwZVtcImRlbGV0ZVwiXT1mdW5jdGlvbigpe3RoaXMuTGYubmV4dD10aGlzLm5leHQsdGhpcy5uZXh0LkxmPXRoaXMuTGZ9LHUucHJvdG90eXBlLm12PWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuTGY7dGhpcy5MZj10LHQuTGY9ZSxlLm5leHQ9dCx0Lm5leHQ9dGhpc30sdS5wcm90b3R5cGUud3Y9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5uZXh0O3RoaXMubmV4dD10LHQubmV4dD1lLGUuTGY9dCx0LkxmPXRoaXN9LG10LmVnJiYobXQ9bXQuZWcpO3ZhciBTdD17fSxidD1tdDtTdC5lZz1sLGwucHJvdG90eXBlLlN2PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYnZ8fCh0aGlzLmJ2PXtIZzpuZXcgYnQsTGc6bmV3IGJ0fSksdGhpcy5idn0sbC5wcm90b3R5cGUuRXY9ZnVuY3Rpb24odCxlKXt0aGlzLm1ha2VPYnNlcnZhYmxlJiYhdGhpcy5kaXNwYXRjaE1hcENoYW5nZXMmJnRoaXMubWFrZU9ic2VydmFibGUoKTt2YXIgaT10aGlzLlN2KCk7KGU/aS5IZzppLkxnKS5wdXNoKHQpLHRoaXMuSXY9ITB9LGwucHJvdG90eXBlLlJ2PWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcy5TdigpLGk9KGU/aS5IZzppLkxnKS52dih0KTtpZighaSl0aHJvdyBFcnJvcihcIkNhbid0IHJlbW92ZSBsaXN0ZW5lcjogZG9lcyBub3QgZXhpc3QuXCIpO2lbXCJkZWxldGVcIl0oKX0sbC5wcm90b3R5cGUua3Y9ZnVuY3Rpb24odCxlLGkpe3ZhciByPXRoaXMuU3YoKSxuPVwiaGFuZGxlTWFwXCIrKChpP1wiV2lsbFwiOlwiXCIpK1wiQ2hhbmdlXCIpOyhpP3IuSGc6ci5MZykuZm9yRWFjaChmdW5jdGlvbihpKXt2YXIgcj1pLGk9aVtuXXx8aTtpLmNhbGwmJmkuY2FsbChyLGUsdCx0aGlzKX0sdGhpcyl9LGwucHJvdG90eXBlLkN2PWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLkV2KHQsITApfSxsLnByb3RvdHlwZS5Pdj1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5Sdih0LCEwKX0sbC5wcm90b3R5cGUuUHY9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5rdih0LGUsITApfSxTdC5lZyYmKFN0PVN0LmVnKTt2YXIgRXQ9e30sSXQ9b3QsUnQ9U3Qsa3Q9WDtFdC5lZz1kLEl0LmFkZEVhY2goZC5wcm90b3R5cGUsUnQucHJvdG90eXBlKSxJdC5hZGRFYWNoKGQucHJvdG90eXBlLGt0LnByb3RvdHlwZSksZC5wcm90b3R5cGUuYWRkRWFjaD1mdW5jdGlvbih0KXt0JiZJdCh0KT09PXQmJihcImZ1bmN0aW9uXCI9PXR5cGVvZiB0LmZvckVhY2g/XCJmdW5jdGlvblwiPT10eXBlb2YgdC5rZXlzP3QuZm9yRWFjaChmdW5jdGlvbih0LGUpe3RoaXMuc2V0KGUsdCl9LHRoaXMpOnQuZm9yRWFjaChmdW5jdGlvbih0KXt0aGlzLnNldCh0WzBdLHRbMV0pfSx0aGlzKTpJdC5rZXlzKHQpLmZvckVhY2goZnVuY3Rpb24oZSl7dGhpcy5zZXQoZSx0W2VdKX0sdGhpcykpfSxkLnByb3RvdHlwZS5nZXQ9ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzLlZmLmdldChuZXcgdGhpcy5Bdih0KSk7cmV0dXJuIGk/aS52YWx1ZToxPGFyZ3VtZW50cy5sZW5ndGg/ZTp0aGlzLmNvbnRlbnQodCl9LGQucHJvdG90eXBlLnNldD1mdW5jdGlvbih0LGUpe3ZhciBpPW5ldyB0aGlzLkF2KHQsZSkscj10aGlzLlZmLmdldChpKSxuPSExO3JldHVybiByPyh0aGlzLkl2JiZ0aGlzLlB2KHQsci52YWx1ZSksci52YWx1ZT1lKToodGhpcy5JdiYmdGhpcy5Qdih0LHZvaWQgMCksdGhpcy5WZi5hZGQoaSkmJih0aGlzLmxlbmd0aCsrLG49ITApKSx0aGlzLkl2JiZ0aGlzLmt2KHQsZSksbn0sZC5wcm90b3R5cGUuYWRkPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMuc2V0KGUsdCl9LGQucHJvdG90eXBlLmhhcz1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5WZi5oYXMobmV3IHRoaXMuQXYodCkpfSxkLnByb3RvdHlwZVtcImRlbGV0ZVwiXT1mdW5jdGlvbih0KXt2YXIgZT1uZXcgdGhpcy5Bdih0KTtpZih0aGlzLlZmLmhhcyhlKSl7dmFyIGk9dGhpcy5WZi5nZXQoZSkudmFsdWU7cmV0dXJuIHRoaXMuSXYmJnRoaXMuUHYodCxpKSx0aGlzLlZmW1wiZGVsZXRlXCJdKGUpLHRoaXMubGVuZ3RoLS0sdGhpcy5JdiYmdGhpcy5rdih0LHZvaWQgMCksITB9cmV0dXJuITF9LGQucHJvdG90eXBlLmNsZWFyPWZ1bmN0aW9uKCl7dGhpcy5WZi5jbGVhcigpLHRoaXMubGVuZ3RoPTB9LGQucHJvdG90eXBlLnJlZHVjZT1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIHRoaXMuVmYucmVkdWNlKGZ1bmN0aW9uKGUscil7cmV0dXJuIHQuY2FsbChpLGUsci52YWx1ZSxyLmtleSx0aGlzKX0sZSx0aGlzKX0sZC5wcm90b3R5cGUucmVkdWNlUmlnaHQ9ZnVuY3Rpb24odCxlLGkpe3JldHVybiB0aGlzLlZmLnJlZHVjZVJpZ2h0KGZ1bmN0aW9uKGUscil7cmV0dXJuIHQuY2FsbChpLGUsci52YWx1ZSxyLmtleSx0aGlzKX0sZSx0aGlzKX0sZC5wcm90b3R5cGUua2V5cz1mdW5jdGlvbigpe3JldHVybiB0aGlzLm1hcChmdW5jdGlvbih0LGUpe3JldHVybiBlfSl9LGQucHJvdG90eXBlLnZhbHVlcz1mdW5jdGlvbigpe3JldHVybiB0aGlzLm1hcChGdW5jdGlvbi5pZGVudGl0eSl9LGQucHJvdG90eXBlLk52PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uKHQsZSl7cmV0dXJuW2UsdF19KX0sZC5wcm90b3R5cGUub2w9ZnVuY3Rpb24odCxlKXtyZXR1cm4gZT1lfHxJdC5vbCx0aGlzPT09dHx8KEl0LnZnKHQsXCJldmVyeVwiKT90Lmxlbmd0aD09PXRoaXMubGVuZ3RoJiZ0LmV2ZXJ5KGZ1bmN0aW9uKHQsaSl7cmV0dXJuIGUodGhpcy5nZXQoaSksdCl9LHRoaXMpOkl0LmtleXModCkubGVuZ3RoPT09dGhpcy5sZW5ndGgmJkl0LmtleXModCkuZXZlcnkoZnVuY3Rpb24oaSl7cmV0dXJuIGUodGhpcy5nZXQoaSksdFtpXSl9LHRoaXMpKX0sZC5wcm90b3R5cGUuQXY9ZnVuY3Rpb24odCxlKXt0aGlzLmtleT10LHRoaXMudmFsdWU9ZX0sRXQuZWcmJihFdD1FdC5lZyk7dmFyIEN0PXt9LE90PXgsUHQ9RXQsQXQ9WDtDdC5lZz1mLE9iamVjdC5hZGRFYWNoKGYucHJvdG90eXBlLE90LnByb3RvdHlwZSksXG4gICAgT2JqZWN0LmFkZEVhY2goZi5wcm90b3R5cGUsUHQucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaChmLnByb3RvdHlwZSxBdC5wcm90b3R5cGUpLGYucHJvdG90eXBlLm5nPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0LHRoaXMubWFuZ2xlLHRoaXMuY29udGVudCl9LGYucHJvdG90eXBlLnh2PWZ1bmN0aW9uKHQpe2lmKFwic3RyaW5nXCIhPXR5cGVvZiB0KXRocm93IG5ldyBUeXBlRXJyb3IoXCJrZXkgbXVzdCBiZSBhIHN0cmluZy5cIil9LGYucHJvdG90eXBlLmdldD1mdW5jdGlvbih0LGUpe3RoaXMueHYodCk7dmFyIGk9XCJ+XCIrdDtyZXR1cm4gaSBpbiB0aGlzLlZmP3RoaXMuVmZbaV06MTxhcmd1bWVudHMubGVuZ3RoP2U6dGhpcy5jb250ZW50KCl9LGYucHJvdG90eXBlLnNldD1mdW5jdGlvbih0LGUpe3RoaXMueHYodCk7dmFyIGk9XCJ+XCIrdDtyZXR1cm4gaSBpbiB0aGlzLlZmPyh0aGlzLlZmW2ldPWUsITEpOih0aGlzLmxlbmd0aCsrLHRoaXMuVmZbaV09ZSwhMCl9LGYucHJvdG90eXBlLmhhcz1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy54dih0KSxcIn5cIit0IGluIHRoaXMuVmZ9LGYucHJvdG90eXBlW1wiZGVsZXRlXCJdPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLnh2KHQpLFwiflwiK3QgaW4gdGhpcy5WZiYmKGRlbGV0ZSB0aGlzLlZmW1wiflwiK3RdLHRoaXMubGVuZ3RoLS0sITApfSxmLnByb3RvdHlwZS5jbGVhcj1mdW5jdGlvbigpe2Zvcih2YXIgdCBpbiB0aGlzLlZmKWRlbGV0ZSB0aGlzLlZmW3RdO3RoaXMubGVuZ3RoPTB9LGYucHJvdG90eXBlLnJlZHVjZT1mdW5jdGlvbih0LGUsaSl7Zm9yKHZhciByIGluIHRoaXMuVmYpZT10LmNhbGwoaSxlLHRoaXMuVmZbcl0sci5zbGljZSgxKSx0aGlzKTtyZXR1cm4gZX0sZi5wcm90b3R5cGUudWc9ZnVuY3Rpb24oKXtmb3IodmFyIHQgaW4gdGhpcy5WZilyZXR1cm4gdGhpcy5WZlt0XTt0aHJvdyBFcnJvcihcIkNhbid0IGdldCBvbmUgdmFsdWUgZnJvbSBlbXB0eSBkaWN0aW9uYXJ5LlwiKX0sQ3QuZWcmJihDdD1DdC5lZyk7dmFyIE50PXt9LHh0PUN0LEJ0PW10LEZ0PXgsX3Q9QixEdD1ILEh0PVg7TnQuZWc9ZyxPYmplY3QuYWRkRWFjaChnLnByb3RvdHlwZSxGdC5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKGcucHJvdG90eXBlLF90LnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2goZy5wcm90b3R5cGUsSHQucHJvdG90eXBlKSxnLnByb3RvdHlwZS5KZj14dCxnLnByb3RvdHlwZS5LZj1CdCxnLnByb3RvdHlwZS5uZz1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodCx0aGlzLk1mLHRoaXMuUWYsdGhpcy5jb250ZW50KX0sZy5wcm90b3R5cGUuaGFzPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuUWYodCk7cmV0dXJuIHRoaXMucWYuZ2V0KGUpLmhhcyh0KX0sZy5wcm90b3R5cGUuZ2V0PWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuUWYodCksaT10aGlzLnFmO3JldHVybiBpLmhhcyhlKT9pLmdldChlKS5nZXQodCk6dGhpcy5jb250ZW50KHQpfSxnLnByb3RvdHlwZVtcImRlbGV0ZVwiXT1mdW5jdGlvbih0KXt2YXIgZT10aGlzLlFmKHQpLGk9dGhpcy5xZjtpZihpLmhhcyhlKSl7dmFyIHI9aS5nZXQoZSk7aWYocltcImRlbGV0ZVwiXSh0KSlyZXR1cm4gdGhpcy5sZW5ndGgtLSwwPT09ci5sZW5ndGgmJmlbXCJkZWxldGVcIl0oZSksITB9cmV0dXJuITF9LGcucHJvdG90eXBlLmNsZWFyPWZ1bmN0aW9uKCl7dGhpcy5xZi5jbGVhcigpLHRoaXMubGVuZ3RoPTB9LGcucHJvdG90eXBlLmFkZD1mdW5jdGlvbih0KXt2YXIgZT10aGlzLlFmKHQpLGk9dGhpcy5xZjtyZXR1cm4gaS5oYXMoZSl8fGkuc2V0KGUsbmV3IHRoaXMuS2YobnVsbCx0aGlzLk1mKSksIWkuZ2V0KGUpLmhhcyh0KSYmKGkuZ2V0KGUpLmFkZCh0KSx0aGlzLmxlbmd0aCsrLCEwKX0sZy5wcm90b3R5cGUucmVkdWNlPWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gdGhpcy5xZi5yZWR1Y2UoZnVuY3Rpb24oZSxyKXtyZXR1cm4gci5yZWR1Y2UoZnVuY3Rpb24oZSxyKXtyZXR1cm4gdC5jYWxsKGksZSxyLHIsdGhpcyl9LGUsdGhpcyl9LGUsdGhpcyl9LGcucHJvdG90eXBlLnVnPWZ1bmN0aW9uKCl7aWYoMD09PXRoaXMubGVuZ3RoKXRocm93IEVycm9yKFwiQ2FuJ3QgZ2V0IG9uZSB2YWx1ZSBmcm9tIGVtcHR5IHNldC5cIik7cmV0dXJuIHRoaXMucWYudWcoKS51ZygpfSxnLnByb3RvdHlwZS5EZj1mdW5jdGlvbigpe3JldHVybiB0aGlzLnFmLnZhbHVlcygpLmFnKCkuRGYoKX0sZy5wcm90b3R5cGUubG9nPWZ1bmN0aW9uKHQsZSxpLHIpe3Q9dHx8RHQua2csZT1lfHx0aGlzLkJ2LGl8fChpPWNvbnNvbGUubG9nLHI9Y29uc29sZSk7dmFyIGk9aS5iaW5kKHIpLG49dGhpcy5xZixvPW4ua2V5cygpO28uZm9yRWFjaChmdW5jdGlvbihzLGEpe3ZhciBjLGg7YT09PW8ubGVuZ3RoLTE/KGM9dC5iZyxoPVwiIFwiKTooYz0wPT09YT90LlRnOnQuRWcsaD10LklnKTt2YXIgcD1uLmdldChzKTtpLmNhbGwocixjK3QubWcrdC5UZytcIiBcIitzKSxwLmZvckVhY2goZnVuY3Rpb24obixvKXt2YXIgcyxhO289PT1wLmhlYWQuTGY/KHM9dC5iZyxhPVwiIFwiKToocz10LkVnLGE9dC5JZyk7dmFyIGM7ZShvLGZ1bmN0aW9uKGUpe2M/aS5jYWxsKHIsaCtcIiBcIithK1wiICBcIitlKTooaS5jYWxsKHIsaCtcIiBcIitzK3QubWcrdC5tZytlKSxjPSEwKX0sZnVuY3Rpb24oZSl7aS5jYWxsKHIsaCtcIiBcIit0LklnK1wiICBcIitlKX0pfSl9KX0sZy5wcm90b3R5cGUuQnY9ZnVuY3Rpb24odCxlKXt2YXIgaT10LnZhbHVlO09iamVjdChpKT09PWk/SlNPTi5zdHJpbmdpZnkoaSxudWxsLDQpLnNwbGl0KFwiXFxuXCIpLmZvckVhY2goZnVuY3Rpb24odCl7ZShcIiBcIit0KX0pOmUoXCIgXCIraSl9LE50LmVnJiYoTnQ9TnQuZWcpO3ZhciBMdD17fSxNdD1OdCxqdD14LFV0PUV0LFZ0PVg7THQuZWc9dixPYmplY3QuYWRkRWFjaCh2LnByb3RvdHlwZSxqdC5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKHYucHJvdG90eXBlLFV0LnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2godi5wcm90b3R5cGUsVnQucHJvdG90eXBlKSx2LnByb3RvdHlwZS5uZz1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodCx0aGlzLk1mLHRoaXMuUWYsdGhpcy5jb250ZW50KX0sdi5wcm90b3R5cGUubG9nPWZ1bmN0aW9uKHQsZSl7ZT1lfHx0aGlzLnN0cmluZ2lmeSx0aGlzLlZmLmxvZyh0LGUpfSx2LnByb3RvdHlwZS5zdHJpbmdpZnk9ZnVuY3Rpb24odCxlKXtyZXR1cm4gZStKU09OLnN0cmluZ2lmeSh0LmtleSkrXCI6IFwiK0pTT04uc3RyaW5naWZ5KHQudmFsdWUpfSxMdC5lZyYmKEx0PUx0LmVnKTt2YXIgUXQ9e30scXQ9bXQsSnQ9TnQsS3Q9eCxHdD1CLHp0PVgsV3Q9cnQ7UXQuZWc9eSxPYmplY3QuYWRkRWFjaCh5LnByb3RvdHlwZSxLdC5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKHkucHJvdG90eXBlLEd0LnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2goeS5wcm90b3R5cGUsenQucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaCh5LnByb3RvdHlwZSxXdC5wcm90b3R5cGUpLHkucHJvdG90eXBlLkdmPXF0LHkucHJvdG90eXBlLnpmPUp0LHkucHJvdG90eXBlLm5nPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0LHRoaXMuTWYsdGhpcy5RZix0aGlzLmNvbnRlbnQpfSx5LnByb3RvdHlwZS5oYXM9ZnVuY3Rpb24odCl7cmV0dXJuIHQ9bmV3IHRoaXMub3JkZXIuTm9kZSh0KSx0aGlzLlZmLmhhcyh0KX0seS5wcm90b3R5cGUuZ2V0PWZ1bmN0aW9uKHQpe3ZhciBlPW5ldyB0aGlzLm9yZGVyLk5vZGUodCk7cmV0dXJuKGU9dGhpcy5WZi5nZXQoZSkpP2UudmFsdWU6dGhpcy5jb250ZW50KHQpfSx5LnByb3RvdHlwZS5hZGQ9ZnVuY3Rpb24odCl7dmFyIGU9bmV3IHRoaXMub3JkZXIuTm9kZSh0KTtyZXR1cm4hdGhpcy5WZi5oYXMoZSkmJih0aGlzLiRnJiZ0aGlzLm52KFt0XSxbXSwwKSx0aGlzLm9yZGVyLmFkZCh0KSxlPXRoaXMub3JkZXIuaGVhZC5MZix0aGlzLlZmLmFkZChlKSx0aGlzLmxlbmd0aCsrLHRoaXMuJGcmJnRoaXMuWGcoW3RdLFtdLDApLCEwKX0seS5wcm90b3R5cGVbXCJkZWxldGVcIl09ZnVuY3Rpb24odCl7dmFyIGU9bmV3IHRoaXMub3JkZXIuTm9kZSh0KTtyZXR1cm4hIXRoaXMuVmYuaGFzKGUpJiYodGhpcy4kZyYmdGhpcy5udihbXSxbdF0sMCksZT10aGlzLlZmLmdldChlKSx0aGlzLlZmW1wiZGVsZXRlXCJdKGUpLGVbXCJkZWxldGVcIl0oKSx0aGlzLmxlbmd0aC0tLHRoaXMuJGcmJnRoaXMuWGcoW10sW3RdLDApLCEwKX0seS5wcm90b3R5cGUudWc9ZnVuY3Rpb24oKXtpZigwPT09dGhpcy5sZW5ndGgpdGhyb3cgRXJyb3IoXCJDYW4ndCBnZXQgb25lIHZhbHVlIGZyb20gZW1wdHkgc2V0LlwiKTtyZXR1cm4gdGhpcy5WZi51ZygpLnZhbHVlfSx5LnByb3RvdHlwZS5jbGVhcj1mdW5jdGlvbigpe3RoaXMuVmYuY2xlYXIoKSx0aGlzLm9yZGVyLmNsZWFyKCksdGhpcy5sZW5ndGg9MH0seS5wcm90b3R5cGUucmVkdWNlPWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gdGhpcy5vcmRlci5yZWR1Y2UoZnVuY3Rpb24oZSxyKXtyZXR1cm4gdC5jYWxsKGksZSxyLHIsdGhpcyl9LGUsdGhpcyl9LHkucHJvdG90eXBlLnJlZHVjZVJpZ2h0PWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gdGhpcy5vcmRlci5yZWR1Y2VSaWdodChmdW5jdGlvbihlLHIpe3JldHVybiB0LmNhbGwoaSxlLHIscix0aGlzKX0sZSx0aGlzKX0seS5wcm90b3R5cGUuRGY9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5vcmRlci5EZigpfSx5LnByb3RvdHlwZS5sb2c9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLlZmO3JldHVybiB0LmxvZy5hcHBseSh0LGFyZ3VtZW50cyl9LFF0LmVnJiYoUXQ9UXQuZWcpO3ZhciAkdD17fSxZdD1RdCxYdD14LFp0PUIsdGU9WDskdC5lZz1tLE9iamVjdC5hZGRFYWNoKG0ucHJvdG90eXBlLFh0LnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2gobS5wcm90b3R5cGUsWnQucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaChtLnByb3RvdHlwZSx0ZS5wcm90b3R5cGUpLG0ucHJvdG90eXBlLm5nPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0LHRoaXMubWF4TGVuZ3RoLHRoaXMuTWYsdGhpcy5RZix0aGlzLmNvbnRlbnQpfSxtLnByb3RvdHlwZS5oYXM9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuVmYuaGFzKHQpfSxtLnByb3RvdHlwZS5nZXQ9ZnVuY3Rpb24odCl7cmV0dXJuIHQ9dGhpcy5WZi5nZXQodCksdm9pZCAwIT09dD8odGhpcy5WZltcImRlbGV0ZVwiXSh0KSx0aGlzLlZmLmFkZCh0KSk6dD10aGlzLmNvbnRlbnQoKSx0fSxtLnByb3RvdHlwZS5hZGQ9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuVmYuaGFzKHQpJiYodGhpcy5WZltcImRlbGV0ZVwiXSh0KSx0aGlzLmxlbmd0aC0tKSx0aGlzLlZmLmFkZCh0KSx0aGlzLmxlbmd0aCsrLCEodGhpcy5WZi5sZW5ndGg+dGhpcy5tYXhMZW5ndGgpfHwodGhpcy5WZltcImRlbGV0ZVwiXSh0aGlzLlZmLm9yZGVyLmhlYWQubmV4dC52YWx1ZSksdGhpcy5sZW5ndGgtLSwhMSl9LG0ucHJvdG90eXBlW1wiZGVsZXRlXCJdPWZ1bmN0aW9uKHQpe3JldHVybiEhdGhpcy5WZltcImRlbGV0ZVwiXSh0KSYmKHRoaXMubGVuZ3RoLS0sITApfSxtLnByb3RvdHlwZS51Zz1mdW5jdGlvbigpe2lmKDA9PT10aGlzLmxlbmd0aCl0aHJvdyBFcnJvcihcIkNhbid0IGdldCBvbmUgdmFsdWUgZnJvbSBlbXB0eSBjb2xsZWN0aW9uLlwiKTtyZXR1cm4gdGhpcy5WZi51ZygpfSxtLnByb3RvdHlwZS5jbGVhcj1mdW5jdGlvbigpe3RoaXMuVmYuY2xlYXIoKSx0aGlzLmxlbmd0aD0wfSxtLnByb3RvdHlwZS5yZWR1Y2U9ZnVuY3Rpb24odCxlLGkpe3JldHVybiB0aGlzLlZmLnJlZHVjZShmdW5jdGlvbihlLHIpe3JldHVybiB0LmNhbGwoaSxlLHIscix0aGlzKX0sZSx0aGlzKX0sbS5wcm90b3R5cGUucmVkdWNlUmlnaHQ9ZnVuY3Rpb24odCxlLGkpe3JldHVybiB0aGlzLlZmLnJlZHVjZVJpZ2h0KGZ1bmN0aW9uKHQsZSl7cmV0dXJuIGNhbGxiYWNrLmNhbGwoaSx0LGUsZSx0aGlzKX0sYmFzaXMsdGhpcyl9LG0ucHJvdG90eXBlLkRmPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuVmYuRGYoKX0sJHQuZWcmJigkdD0kdC5lZyk7dmFyIGVlPXt9LGllPSR0LHJlPXgsbmU9RXQsb2U9WDtlZS5lZz13LE9iamVjdC5hZGRFYWNoKHcucHJvdG90eXBlLHJlLnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2gody5wcm90b3R5cGUsbmUucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaCh3LnByb3RvdHlwZSxvZS5wcm90b3R5cGUpLHcucHJvdG90eXBlLm5nPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0LHRoaXMubWF4TGVuZ3RoLHRoaXMuTWYsdGhpcy5RZix0aGlzLmNvbnRlbnQpfSx3LnByb3RvdHlwZS5sb2c9ZnVuY3Rpb24odCxlKXtlPWV8fHRoaXMuc3RyaW5naWZ5LHRoaXMuVmYubG9nKHQsZSl9LHcucHJvdG90eXBlLnN0cmluZ2lmeT1mdW5jdGlvbih0LGUpe3JldHVybiBlK0pTT04uc3RyaW5naWZ5KHQua2V5KStcIjogXCIrSlNPTi5zdHJpbmdpZnkodC52YWx1ZSl9LGVlLmVnJiYoZWU9ZWUuZWcpO3ZhciBzZT17fSxhZT1RdCxjZT14LGhlPUV0LHBlPVg7c2UuZWc9VCxPYmplY3QuYWRkRWFjaChULnByb3RvdHlwZSxjZS5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKFQucHJvdG90eXBlLGhlLnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2goVC5wcm90b3R5cGUscGUucHJvdG90eXBlKSxULnByb3RvdHlwZS5uZz1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodCx0aGlzLk1mLHRoaXMuUWYsdGhpcy5jb250ZW50KX0sVC5wcm90b3R5cGUubG9nPWZ1bmN0aW9uKHQsZSl7ZT1lfHx0aGlzLnN0cmluZ2lmeSx0aGlzLlZmLmxvZyh0LGUpfSxULnByb3RvdHlwZS5zdHJpbmdpZnk9ZnVuY3Rpb24odCxlKXtyZXR1cm4gZStKU09OLnN0cmluZ2lmeSh0LmtleSkrXCI6IFwiK0pTT04uc3RyaW5naWZ5KHQudmFsdWUpfSxzZS5lZyYmKHNlPXNlLmVnKTt2YXIgdWU9e30sbGU9c2U7dWUuZWc9UyxTLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKGxlLnByb3RvdHlwZSksUy5wcm90b3R5cGUuY29uc3RydWN0b3I9UyxTLnByb3RvdHlwZS5uZz1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodCx0aGlzLldmLHRoaXMuTWYsdGhpcy5RZil9LFMucHJvdG90eXBlLnNldD1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMuZ2V0KHQpO2kueXYoMCxpLmxlbmd0aCxlKX0sUy5wcm90b3R5cGUuV2Y9ZnVuY3Rpb24oKXtyZXR1cm5bXX0sdWUuZWcmJih1ZT11ZS5lZyk7dmFyIGRlPXt9O2RlLmVnPWI7dmFyIGZlPVgsZ2U9cnQ7T2JqZWN0LmFkZEVhY2goYi5wcm90b3R5cGUseC5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKGIucHJvdG90eXBlLGZlLnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2goYi5wcm90b3R5cGUsZ2UucHJvdG90eXBlKSxiLnByb3RvdHlwZS5uZz1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodCx0aGlzLk1mLHRoaXMuJGYsdGhpcy5jb250ZW50KX0sYi5wcm90b3R5cGUuaGFzPWZ1bmN0aW9uKHQpe3ZhciBlPUUodGhpcy5IZix0LHRoaXMuJGYpO3JldHVybiAwPD1lJiZ0aGlzLk1mKHRoaXMuSGZbZV0sdCl9LGIucHJvdG90eXBlLmdldD1mdW5jdGlvbih0KXt2YXIgZT1JKHRoaXMuSGYsdCx0aGlzLiRmLHRoaXMuTWYpO3JldHVybi0xIT09ZT90aGlzLkhmW2VdOnRoaXMuY29udGVudCh0KX0sYi5wcm90b3R5cGUuYWRkPWZ1bmN0aW9uKHQpe3ZhciBlO2U9dGhpcy5IZjt2YXIgaT10aGlzLiRmLHI9RShlLHQsaSk7aWYoMD5yKWU9LXItMTtlbHNle2Zvcih2YXIgbj1lLmxlbmd0aC0xO3I8biYmMD09PWkodCxlW3IrMV0pOylyKys7ZT1yfXJldHVybiB0aGlzLiRnJiZ0aGlzLm52KFt0XSxbXSxlKSx0aGlzLkhmLnNwbGljZShlLDAsdCksdGhpcy5sZW5ndGgrKyx0aGlzLiRnJiZ0aGlzLlhnKFt0XSxbXSxlKSwhMH0sYi5wcm90b3R5cGVbXCJkZWxldGVcIl09ZnVuY3Rpb24odCl7dmFyIGU9SSh0aGlzLkhmLHQsdGhpcy4kZix0aGlzLk1mKTtyZXR1cm4tMSE9PWUmJih0aGlzLiRnJiZ0aGlzLm52KFtdLFt0XSxlKSx0aGlzLkhmLnNwbGljZShlLDEpLHRoaXMubGVuZ3RoLS0sdGhpcy4kZyYmdGhpcy5YZyhbXSxbdF0sZSksITApfSxiLnByb3RvdHlwZS5pbmRleE9mPWZ1bmN0aW9uKHQpe3JldHVybiBJKHRoaXMuSGYsdCx0aGlzLiRmLHRoaXMuTWYpfSxiLnByb3RvdHlwZS5sYXN0SW5kZXhPZj1mdW5jdGlvbih0KXtyZXR1cm4gUih0aGlzLkhmLHQsdGhpcy4kZix0aGlzLk1mKX0sYi5wcm90b3R5cGUuZmluZD1mdW5jdGlvbih0KXtyZXR1cm4gSSh0aGlzLkhmLHQsdGhpcy4kZix0aGlzLk1mKX0sYi5wcm90b3R5cGUudnY9ZnVuY3Rpb24odCl7cmV0dXJuIFIodGhpcy5IZix0LHRoaXMuJGYsdGhpcy5NZil9LGIucHJvdG90eXBlLnB1c2g9ZnVuY3Rpb24oKXt0aGlzLmFkZEVhY2goYXJndW1lbnRzKX0sYi5wcm90b3R5cGUudW5zaGlmdD1mdW5jdGlvbigpe3RoaXMuYWRkRWFjaChhcmd1bWVudHMpfSxiLnByb3RvdHlwZS5wb3A9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5IZi5wb3AoKX0sYi5wcm90b3R5cGUuc2hpZnQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5IZi5zaGlmdCgpfSxiLnByb3RvdHlwZS5zbGljZT1mdW5jdGlvbigpe3JldHVybiB0aGlzLkhmLnNsaWNlLmFwcGx5KHRoaXMuSGYsYXJndW1lbnRzKX0sYi5wcm90b3R5cGUuc3BsaWNlPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMueXYodCxlLEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywyKSl9LGIucHJvdG90eXBlLnl2PWZ1bmN0aW9uKHQsZSxpKXtpZih2b2lkIDA9PT10JiZ2b2lkIDA9PT1lKXJldHVybltdO3Q9dHx8MCwwPnQmJih0Kz10aGlzLmxlbmd0aCksdm9pZCAwPT09ZSYmKGU9MS8wKTt2YXIgcj10aGlzLnNsaWNlKHQsdCtlKTtyZXR1cm4gdGhpcy4kZyYmdGhpcy5udihpLHIsdCksdGhpcy5IZi5zcGxpY2UodCxlKSx0aGlzLmFkZEVhY2goaSksdGhpcy4kZyYmdGhpcy5YZyhpLHIsdCkscn0sYi5wcm90b3R5cGUucmVkdWNlPWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gdGhpcy5IZi5yZWR1Y2UoZnVuY3Rpb24oZSxyLG4pe3JldHVybiB0LmNhbGwoaSxlLHIsbix0aGlzKX0sZSx0aGlzKX0sYi5wcm90b3R5cGUucmVkdWNlUmlnaHQ9ZnVuY3Rpb24odCxlLGkpe3JldHVybiB0aGlzLkhmLnJlZHVjZVJpZ2h0KGZ1bmN0aW9uKHQsZSxyKXtyZXR1cm4gY2FsbGJhY2suY2FsbChpLHQsZSxyLHRoaXMpfSxiYXNpcyx0aGlzKX0sYi5wcm90b3R5cGUubWluPWZ1bmN0aW9uKCl7aWYodGhpcy5sZW5ndGgpcmV0dXJuIHRoaXMuSGZbMF19LGIucHJvdG90eXBlLm1heD1mdW5jdGlvbigpe2lmKHRoaXMubGVuZ3RoKXJldHVybiB0aGlzLkhmW3RoaXMubGVuZ3RoLTFdfSxiLnByb3RvdHlwZS51Zz1mdW5jdGlvbigpe3JldHVybiB0aGlzLkhmLnVnKCl9LGIucHJvdG90eXBlLmNsZWFyPWZ1bmN0aW9uKCl7dmFyIHQ7dGhpcy4kZyYmKHQ9dGhpcy5IZi5zbGljZSgpLHRoaXMubnYoW10sdCwwKSksdGhpcy5sZW5ndGg9MCx0aGlzLkhmLmNsZWFyKCksdGhpcy4kZyYmdGhpcy5YZyhbXSx0LDApfSxiLnByb3RvdHlwZS5vbD1mdW5jdGlvbih0LGUpe3JldHVybiB0aGlzLkhmLm9sKHQsZSl9LGIucHJvdG90eXBlLllmPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMuSGYuWWYodCxlKX0sYi5wcm90b3R5cGUuRGY9ZnVuY3Rpb24odCxlKXtyZXR1cm4gbmV3IHRoaXMuSXRlcmF0b3IodGhpcy5IZix0LGUpfSxiLnByb3RvdHlwZS5JdGVyYXRvcj1BcnJheS5wcm90b3R5cGUuSXRlcmF0b3IsZGUuZWcmJihkZT1kZS5lZyk7dmFyIHZlPXt9O3ZlLmVnPWs7dmFyIHllPWRlLG1lPUIsd2U9WDtrLnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKHllLnByb3RvdHlwZSksay5wcm90b3R5cGUuY29uc3RydWN0b3I9ayxPYmplY3QuYWRkRWFjaChrLnByb3RvdHlwZSxtZS5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKGsucHJvdG90eXBlLHdlLnByb3RvdHlwZSksay5wcm90b3R5cGUuYWRkPWZ1bmN0aW9uKHQpe3JldHVybiF0aGlzLmhhcyh0KSYmKHllLnByb3RvdHlwZS5hZGQuY2FsbCh0aGlzLHQpLCEwKX0say5wcm90b3R5cGUucmVkdWNlPWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj10aGlzO3JldHVybiB0aGlzLkhmLnJlZHVjZShmdW5jdGlvbihlLG4sbyl7cmV0dXJuIHQuY2FsbChpLGUsbixuLHIsbyl9LGUpfSxrLnByb3RvdHlwZS5yZWR1Y2VSaWdodD1mdW5jdGlvbih0LGUsaSl7dmFyIHI9dGhpcztyZXR1cm4gdGhpcy5IZi5yZWR1Y2VSaWdodChmdW5jdGlvbihlLG4sbyl7cmV0dXJuIHQuY2FsbChpLGUsbixuLHIsbyl9LGUpfSx2ZS5lZyYmKHZlPXZlLmVnKTt2YXIgVGU9e30sU2U9dmUsYmU9eCxFZT1FdCxJZT1YO1RlLmVnPUMsT2JqZWN0LmFkZEVhY2goQy5wcm90b3R5cGUsYmUucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaChDLnByb3RvdHlwZSxFZS5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKEMucHJvdG90eXBlLEllLnByb3RvdHlwZSksQy5wcm90b3R5cGUubmc9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHQsdGhpcy5NZix0aGlzLiRmLHRoaXMuY29udGVudCl9LFRlLmVnJiYoVGU9VGUuZWcpO3ZhciBSZT17fTtSZS5lZz1PO3ZhciBrZT1CLENlPVgsT2U9cnQsUGU9SDtPYmplY3QuYWRkRWFjaChPLnByb3RvdHlwZSx4LnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2goTy5wcm90b3R5cGUsa2UucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaChPLnByb3RvdHlwZSxDZS5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKE8ucHJvdG90eXBlLE9lLnByb3RvdHlwZSksTy5wcm90b3R5cGUubmc9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHQsdGhpcy5NZix0aGlzLiRmLHRoaXMuY29udGVudCl9LE8ucHJvdG90eXBlLmhhcz1mdW5jdGlvbih0KXtyZXR1cm4hIXRoaXMucm9vdCYmKHRoaXMuWmYodCksdGhpcy5NZih0LHRoaXMucm9vdC52YWx1ZSkpfSxPLnByb3RvdHlwZS5nZXQ9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMucm9vdCYmKHRoaXMuWmYodCksdGhpcy5NZih0LHRoaXMucm9vdC52YWx1ZSkpP3RoaXMucm9vdC52YWx1ZTp0aGlzLmNvbnRlbnQodCl9LE8ucHJvdG90eXBlLmFkZD1mdW5jdGlvbih0KXt2YXIgZT1uZXcgdGhpcy5Ob2RlKHQpO3JldHVybiB0aGlzLnJvb3Q/KHRoaXMuWmYodCksIXRoaXMuTWYodCx0aGlzLnJvb3QudmFsdWUpJiYodGhpcy4kZyYmdGhpcy5udihbdF0sW10sdGhpcy5yb290LmluZGV4KSwwPnRoaXMuJGYodCx0aGlzLnJvb3QudmFsdWUpPyhlLnJpZ2h0PXRoaXMucm9vdCxlLmxlZnQ9dGhpcy5yb290LmxlZnQsdGhpcy5yb290LmxlZnQ9bnVsbCk6KGUubGVmdD10aGlzLnJvb3QsZS5yaWdodD10aGlzLnJvb3QucmlnaHQsdGhpcy5yb290LnJpZ2h0PW51bGwpLHRoaXMucm9vdC5GdigpLGUuRnYoKSx0aGlzLnJvb3Q9ZSx0aGlzLmxlbmd0aCsrLHRoaXMuJGcmJnRoaXMuWGcoW3RdLFtdLHRoaXMucm9vdC5pbmRleCksITApKToodGhpcy4kZyYmdGhpcy5udihbdF0sW10sMCksdGhpcy5yb290PWUsdGhpcy5sZW5ndGgrKyx0aGlzLiRnJiZ0aGlzLlhnKFt0XSxbXSwwKSwhMCl9LE8ucHJvdG90eXBlW1wiZGVsZXRlXCJdPWZ1bmN0aW9uKHQpe2lmKHRoaXMucm9vdCYmKHRoaXMuWmYodCksdGhpcy5NZih0LHRoaXMucm9vdC52YWx1ZSkpKXt2YXIgZT10aGlzLnJvb3QuaW5kZXg7aWYodGhpcy4kZyYmdGhpcy5udihbXSxbdF0sZSksdGhpcy5yb290LmxlZnQpe3ZhciBpPXRoaXMucm9vdC5yaWdodDt0aGlzLnJvb3Q9dGhpcy5yb290LmxlZnQsdGhpcy5aZih0KSx0aGlzLnJvb3QucmlnaHQ9aX1lbHNlIHRoaXMucm9vdD10aGlzLnJvb3QucmlnaHQ7cmV0dXJuIHRoaXMubGVuZ3RoLS0sdGhpcy5yb290JiZ0aGlzLnJvb3QuRnYoKSx0aGlzLiRnJiZ0aGlzLlhnKFtdLFt0XSxlKSwhMH1yZXR1cm4hMX0sTy5wcm90b3R5cGUuaW5kZXhPZj1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5yb290JiYodGhpcy5aZih0KSx0aGlzLk1mKHQsdGhpcy5yb290LnZhbHVlKSk/dGhpcy5yb290LmluZGV4Oi0xfSxPLnByb3RvdHlwZS5maW5kPWZ1bmN0aW9uKHQpe2lmKHRoaXMucm9vdCYmKHRoaXMuWmYodCksdGhpcy5NZih0LHRoaXMucm9vdC52YWx1ZSkpKXJldHVybiB0aGlzLnJvb3R9LE8ucHJvdG90eXBlLl92PWZ1bmN0aW9uKHQpe2lmKHRoaXMucm9vdCl7Zm9yKHQ9dHx8dGhpcy5yb290O3QucmlnaHQ7KXQ9dC5yaWdodDtyZXR1cm4gdH19LE8ucHJvdG90eXBlLkR2PWZ1bmN0aW9uKHQpe2lmKHRoaXMucm9vdCl7Zm9yKHQ9dHx8dGhpcy5yb290O3QubGVmdDspdD10LmxlZnQ7cmV0dXJuIHR9fSxPLnByb3RvdHlwZS5Idj1mdW5jdGlvbih0KXtpZih0aGlzLnJvb3QpcmV0dXJuIHRoaXMuWmYodCksdGhpcy5yb290fSxPLnByb3RvdHlwZS5Mdj1mdW5jdGlvbih0KXtpZih0aGlzLnJvb3QpcmV0dXJuIHRoaXMuWmYodCksdGhpcy5yb290LnRnKCl9LE8ucHJvdG90eXBlLlhmPWZ1bmN0aW9uKHQpe2lmKHRoaXMucm9vdClyZXR1cm4gdGhpcy5aZih0KSwwPT09dGhpcy4kZih0LHRoaXMucm9vdC52YWx1ZSk/dGhpcy5yb290OnRoaXMucm9vdC5NdigpfSxPLnByb3RvdHlwZS5qdj1mdW5jdGlvbih0KXtpZih0aGlzLnJvb3QpcmV0dXJuIHRoaXMuWmYodCksdGhpcy4kZih0LHRoaXMucm9vdC52YWx1ZSksdGhpcy5yb290Lk12KCl9LE8ucHJvdG90eXBlLnBvcD1mdW5jdGlvbigpe2lmKHRoaXMucm9vdCl7dmFyIHQ9dGhpcy5fdigpO3JldHVybiB0aGlzW1wiZGVsZXRlXCJdKHQudmFsdWUpLHQudmFsdWV9fSxPLnByb3RvdHlwZS5zaGlmdD1mdW5jdGlvbigpe2lmKHRoaXMucm9vdCl7dmFyIHQ9dGhpcy5EdigpO3JldHVybiB0aGlzW1wiZGVsZXRlXCJdKHQudmFsdWUpLHQudmFsdWV9fSxPLnByb3RvdHlwZS5wdXNoPWZ1bmN0aW9uKCl7dGhpcy5hZGRFYWNoKGFyZ3VtZW50cyl9LE8ucHJvdG90eXBlLnVuc2hpZnQ9ZnVuY3Rpb24oKXt0aGlzLmFkZEVhY2goYXJndW1lbnRzKX0sTy5wcm90b3R5cGUuc2xpY2U9ZnVuY3Rpb24odCxlKXt0PXR8fDAsZT1lfHx0aGlzLmxlbmd0aCwwPnQmJih0Kz10aGlzLmxlbmd0aCksMD5lJiYoZSs9dGhpcy5sZW5ndGgpO3ZhciBpPVtdO2lmKHRoaXMucm9vdClmb3IodGhpcy5Vdih0KTt0aGlzLnJvb3QuaW5kZXg8ZSYmKGkucHVzaCh0aGlzLnJvb3QudmFsdWUpLHRoaXMucm9vdC5yaWdodCk7KXRoaXMuWmYodGhpcy5yb290Lk12KCkudmFsdWUpO3JldHVybiBpfSxPLnByb3RvdHlwZS5zcGxpY2U9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy55dih0LGUsQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDIpKX0sTy5wcm90b3R5cGUueXY9ZnVuY3Rpb24odCxlLGkpe2lmKHZvaWQgMD09PXQmJnZvaWQgMD09PWUpcmV0dXJuW107dD10fHwwLDA+dCYmKHQrPXRoaXMubGVuZ3RoKSx2b2lkIDA9PT1lJiYoZT0xLzApO3ZhciByPVtdO2lmKHRoaXMucm9vdClmb3IodGhpcy5Vdih0KSx0PTA7dDxlO3QrKyl7ci5wdXNoKHRoaXMucm9vdC52YWx1ZSk7dmFyIG49dGhpcy5yb290Lk12KCk7aWYodGhpc1tcImRlbGV0ZVwiXSh0aGlzLnJvb3QudmFsdWUpLCFuKWJyZWFrO3RoaXMuWmYobi52YWx1ZSl9cmV0dXJuIHRoaXMuYWRkRWFjaChpKSxyfSxPLnByb3RvdHlwZS5aZj1mdW5jdGlvbih0KXt2YXIgZSxpLHIsbixvLHM7aWYodGhpcy5yb290KXtmb3IoZT1pPXI9bmV3IHRoaXMuTm9kZSxzPW5ldyB0aGlzLk5vZGUsbz10aGlzLnJvb3Q7OylpZihuPXRoaXMuJGYodCxvLnZhbHVlKSwwPm4pe2lmKCFvLmxlZnQpYnJlYWs7aWYoMD50aGlzLiRmKHQsby5sZWZ0LnZhbHVlKSYmKG49by5sZWZ0LG8ubGVmdD1uLnJpZ2h0LG8uRnYoKSxuLnJpZ2h0PW8sbi5GdigpLG89biwhby5sZWZ0KSlicmVhaztuPW5ldyBQLG4ucmlnaHQ9byxuLmxlZnQ9cy5sZWZ0LHMubGVmdD1uLHIubGVmdD1vLHIuRnYoKSxyPW8sbz1vLmxlZnR9ZWxzZXtpZighKDA8bikpYnJlYWs7aWYoIW8ucmlnaHQpYnJlYWs7aWYoMDx0aGlzLiRmKHQsby5yaWdodC52YWx1ZSkmJihuPW8ucmlnaHQsby5yaWdodD1uLmxlZnQsby5GdigpLG4ubGVmdD1vLG4uRnYoKSxvPW4sIW8ucmlnaHQpKWJyZWFrO249bmV3IFAsbi5sZWZ0PW8sbi5yaWdodD1zLnJpZ2h0LHMucmlnaHQ9bixpLnJpZ2h0PW8saS5GdigpLGk9byxvPW8ucmlnaHR9Zm9yKGkucmlnaHQ9by5sZWZ0LGkuRnYoKSxyLmxlZnQ9by5yaWdodCxyLkZ2KCksby5sZWZ0PWUucmlnaHQsby5yaWdodD1lLmxlZnQ7cy5sZWZ0OylzLmxlZnQucmlnaHQuRnYoKSxzLmxlZnQ9cy5sZWZ0LmxlZnQ7Zm9yKDtzLnJpZ2h0OylzLnJpZ2h0LmxlZnQuRnYoKSxzLnJpZ2h0PXMucmlnaHQucmlnaHQ7by5GdigpLHRoaXMucm9vdD1vfX0sTy5wcm90b3R5cGUuVXY9ZnVuY3Rpb24odCl7aWYodGhpcy5yb290KXtmb3IodmFyIGU9dGhpcy5yb290LGk9dGhpcy5yb290LmluZGV4O2khPT10OylpZihpPnQmJmUubGVmdCllPWUubGVmdCxpLT0xKyhlLnJpZ2h0P2UucmlnaHQubGVuZ3RoOjApO2Vsc2V7aWYoIShpPHQmJmUucmlnaHQpKWJyZWFrO2U9ZS5yaWdodCxpKz0xKyhlLmxlZnQ/ZS5sZWZ0Lmxlbmd0aDowKX1yZXR1cm4gdGhpcy5aZihlLnZhbHVlKSx0aGlzLnJvb3QuaW5kZXg9PT10fXJldHVybiExfSxPLnByb3RvdHlwZS5yZWR1Y2U9ZnVuY3Rpb24odCxlLGkpe3JldHVybiB0aGlzLnJvb3QmJihlPXRoaXMucm9vdC5yZWR1Y2UodCxlLGksdGhpcykpLGV9LE8ucHJvdG90eXBlLnJlZHVjZVJpZ2h0PWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gdGhpcy5yb290JiYoZT10aGlzLnJvb3QucmVkdWNlUmlnaHQodCxlLGksdGhpcykpLGV9LE8ucHJvdG90eXBlLm1pbj1mdW5jdGlvbih0KXtpZih0PXRoaXMuRHYodCkpcmV0dXJuIHQudmFsdWV9LE8ucHJvdG90eXBlLm1heD1mdW5jdGlvbih0KXtpZih0PXRoaXMuX3YodCkpcmV0dXJuIHQudmFsdWV9LE8ucHJvdG90eXBlLnVnPWZ1bmN0aW9uKCl7aWYoIXRoaXMucm9vdCl0aHJvdyBFcnJvcihcIkNhbid0IGdldCBvbmUgdmFsdWUgZnJvbSBlbXB0eSBzZXRcIik7cmV0dXJuIHRoaXMucm9vdC52YWx1ZX0sTy5wcm90b3R5cGUuY2xlYXI9ZnVuY3Rpb24oKXt2YXIgdDt0aGlzLiRnJiYodD10aGlzLnRvQXJyYXkoKSx0aGlzLm52KFtdLHQsMCkpLHRoaXMucm9vdD1udWxsLHRoaXMubGVuZ3RoPTAsdGhpcy4kZyYmdGhpcy5YZyhbXSx0LDApfSxPLnByb3RvdHlwZS5EZj1mdW5jdGlvbih0LGUpe3JldHVybiBuZXcgdGhpcy5JdGVyYXRvcih0aGlzLHQsZSl9LE8ucHJvdG90eXBlLkl0ZXJhdG9yPUEsTy5wcm90b3R5cGUuc3VtbWFyeT1mdW5jdGlvbigpe3JldHVybiB0aGlzLnJvb3Q/dGhpcy5yb290LnN1bW1hcnkoKTpcIigpXCJ9LE8ucHJvdG90eXBlLmxvZz1mdW5jdGlvbih0LGUsaSxyKXt0PXR8fFBlLlJnLGU9ZXx8dGhpcy5CdixpfHwoaT1jb25zb2xlLmxvZyxyPWNvbnNvbGUpLGk9aS5iaW5kKHIpLHRoaXMucm9vdCYmdGhpcy5yb290LmxvZyh0LGUsaSxpKX0sTy5wcm90b3R5cGUuQnY9ZnVuY3Rpb24odCxlKXtlKFwiIFwiK3QudmFsdWUpfSxPLlZ2PVBlLE8ucHJvdG90eXBlLk5vZGU9UCxQLnByb3RvdHlwZS5yZWR1Y2U9ZnVuY3Rpb24odCxlLGkscixuKXtyZXR1cm4gbj1ufHwwLHRoaXMubGVmdCYmKGU9dGhpcy5sZWZ0LnJlZHVjZSh0LGUsaSxyLG4rMSkpLGU9dC5jYWxsKGksZSx0aGlzLnZhbHVlLHRoaXMudmFsdWUscix0aGlzLG4pLHRoaXMucmlnaHQmJihlPXRoaXMucmlnaHQucmVkdWNlKHQsZSxpLHIsbisxKSksZX0sUC5wcm90b3R5cGUucmVkdWNlUmlnaHQ9ZnVuY3Rpb24odCxlLGkscixuKXtyZXR1cm4gbj1ufHwwLHRoaXMucmlnaHQmJihlPXRoaXMucmlnaHQucmVkdWNlKHQsZSxpLHIsbisxKSksZT10LmNhbGwoaSxlLHRoaXMudmFsdWUsdGhpcy52YWx1ZSxyLHRoaXMsbiksdGhpcy5sZWZ0JiYoZT10aGlzLmxlZnQucmVkdWNlKHQsZSxpLHIsbisxKSksZX0sUC5wcm90b3R5cGUuRnY9ZnVuY3Rpb24oKXt0aGlzLmxlbmd0aD0xKyh0aGlzLmxlZnQ/dGhpcy5sZWZ0Lmxlbmd0aDowKSsodGhpcy5yaWdodD90aGlzLnJpZ2h0Lmxlbmd0aDowKSx0aGlzLmluZGV4PXRoaXMubGVmdD90aGlzLmxlZnQubGVuZ3RoOjB9LFAucHJvdG90eXBlLlF2PWZ1bmN0aW9uKCl7dmFyIHQ7aWYodD0xKyh0aGlzLmxlZnQ/dGhpcy5sZWZ0LlF2KCk6MCksdCs9dGhpcy5yaWdodD90aGlzLnJpZ2h0LlF2KCk6MCx0aGlzLmxlbmd0aCE9PXQpdGhyb3cgRXJyb3IoXCJJbnRlZ3JpdHkgY2hlY2sgZmFpbGVkOiBcIit0aGlzLnN1bW1hcnkoKSk7cmV0dXJuIHR9LFAucHJvdG90eXBlLk12PWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcztpZih0LnJpZ2h0KXtmb3IodD10LnJpZ2h0O3QubGVmdDspdD10LmxlZnQ7cmV0dXJuIHR9fSxQLnByb3RvdHlwZS50Zz1mdW5jdGlvbigpe3ZhciB0PXRoaXM7aWYodC5sZWZ0KXtmb3IodD10LmxlZnQ7dC5yaWdodDspdD10LnJpZ2h0O3JldHVybiB0fX0sUC5wcm90b3R5cGUuc3VtbWFyeT1mdW5jdGlvbigpe3ZhciB0PXRoaXMudmFsdWV8fFwiLVwiLHQ9dCsoXCIgPFwiK3RoaXMubGVuZ3RoKTtyZXR1cm4gdGhpcy5sZWZ0fHx0aGlzLnJpZ2h0P1wiKFwiK3QrXCIgXCIrKHRoaXMubGVmdD90aGlzLmxlZnQuc3VtbWFyeSgpOlwiKClcIikrXCIsIFwiKyh0aGlzLnJpZ2h0P3RoaXMucmlnaHQuc3VtbWFyeSgpOlwiKClcIikrXCIpXCI6XCIoXCIrdCtcIilcIn0sUC5wcm90b3R5cGUubG9nPWZ1bmN0aW9uKHQsZSxpLHIpe3ZhciBuLG89dGhpcztuPXRoaXMubGVmdCYmdGhpcy5yaWdodD90LmRnOnRoaXMubGVmdD90LndnOnRoaXMucmlnaHQ/dC5UZzp0Lm1nO3ZhciBzO3RoaXMubGVmdCYmdGhpcy5sZWZ0LmxvZyh0LGUsZnVuY3Rpb24oZSl7cz9yKHQuSWcrXCIgXCIrZSk6KHM9ITAscih0LlNnK3QubWcrZSkpfSxmdW5jdGlvbih0KXtyKFwiICBcIit0KX0pO3ZhciBhO2UodGhpcyxmdW5jdGlvbihlKXthP2koKG8ucmlnaHQ/dC5JZzpcIiBcIikrZSk6KGE9ITAsaShuK2UpKX0sZnVuY3Rpb24oZSl7cigoby5sZWZ0P3QuSWc6XCIgXCIpK2UpfSk7dmFyIGM7dGhpcy5yaWdodCYmdGhpcy5yaWdodC5sb2codCxlLGZ1bmN0aW9uKGUpe2M/aShcIiAgXCIrZSk6KGM9ITAsaSh0LmJnK3QubWcrZSkpfSxmdW5jdGlvbihlKXtpKHQuSWcrXCIgXCIrZSl9KX0sQS5wcm90b3R5cGUubmV4dD1mdW5jdGlvbigpe3ZhciB0O2lmKHQ9dGhpcy5MZj90aGlzLnNldC5qdih0aGlzLkxmLnZhbHVlKTp0aGlzLnNldC5EdigpLCF0KXRocm93IFN0b3BJdGVyYXRpb247aWYodm9pZCAwIT09dGhpcy5lbmQmJjA8PXRoaXMuc2V0LiRmKHQudmFsdWUsdGhpcy5lbmQpKXRocm93IFN0b3BJdGVyYXRpb247cmV0dXJuIHRoaXMuTGY9dCx0LnZhbHVlfSxSZS5lZyYmKFJlPVJlLmVnKTt2YXIgQWU9e30sTmU9UmUseGU9eCxCZT1FdCxGZT1YO0FlLmVnPU4sT2JqZWN0LmFkZEVhY2goTi5wcm90b3R5cGUseGUucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaChOLnByb3RvdHlwZSxCZS5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKE4ucHJvdG90eXBlLEZlLnByb3RvdHlwZSksTi5wcm90b3R5cGUubmc9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHQsdGhpcy5NZix0aGlzLiRmLHRoaXMuY29udGVudCl9LE4ucHJvdG90eXBlLmxvZz1mdW5jdGlvbih0LGUpe2U9ZXx8dGhpcy5zdHJpbmdpZnksdGhpcy5WZi5sb2codCxlKX0sTi5wcm90b3R5cGUucXY9ZnVuY3Rpb24odCxlLGkscil7cj1yfHx0aGlzLnN0cmluZ2lmeSx0aGlzLlZmLnF2KHQsZSxpLHIpfSxOLnByb3RvdHlwZS5zdHJpbmdpZnk9ZnVuY3Rpb24odCxlLGkscil7dC5jYWxsKGUscitcIiBcIitpLnZhbHVlLmtleStcIjogXCIraS52YWx1ZS52YWx1ZSl9LEFlLmVnJiYoQWU9QWUuZWcpLHQuSnY9bXQsdC5TZXQ9UXQsdC5NYXA9c2UsdC5Ldj11ZSx0LldlYWtNYXA9TSx0Lkd2PVJlLHQubmk9QWUsdC56dj0kdCx0Lld2PWVlLHQuJHY9ZGUsdC5vaT12ZSx0Lll2PVRlLHQuWHY9TnQsdC5adj1MdCx0LnR5PUN0LHQuSXRlcmF0b3I9dXR9KHRoaXMpfSxmdW5jdGlvbih0LGUpe3QudD1mdW5jdGlvbigpe3JldHVybiBuZXcgRnVuY3Rpb259fSxmdW5jdGlvbih0LGUpe2Z1bmN0aW9uIGkodCxlLGkpe251bGwhPXQmJihcIm51bWJlclwiPT10eXBlb2YgdD90aGlzLmZyb21OdW1iZXIodCxlLGkpOm51bGw9PWUmJlwic3RyaW5nXCIhPXR5cGVvZiB0P3RoaXMuZXkodCwyNTYpOnRoaXMuZXkodCxlKSl9ZnVuY3Rpb24gcigpe3JldHVybiBuZXcgaShudWxsKX1mdW5jdGlvbiBuKHQsZSxpLHIsbixvKXtmb3IoOy0tbz49MDspe3ZhciBzPWUqdGhpc1t0KytdK2lbcl0rbjtuPU1hdGguZmxvb3Iocy82NzEwODg2NCksaVtyKytdPTY3MTA4ODYzJnN9cmV0dXJuIG59ZnVuY3Rpb24gbyh0LGUsaSxyLG4sbyl7Zm9yKHZhciBzPTMyNzY3JmUsYT1lPj4xNTstLW8+PTA7KXt2YXIgYz0zMjc2NyZ0aGlzW3RdLGg9dGhpc1t0KytdPj4xNSxwPWEqYytoKnM7Yz1zKmMrKCgzMjc2NyZwKTw8MTUpK2lbcl0rKDEwNzM3NDE4MjMmbiksbj0oYz4+PjMwKSsocD4+PjE1KSthKmgrKG4+Pj4zMCksaVtyKytdPTEwNzM3NDE4MjMmY31yZXR1cm4gbn1mdW5jdGlvbiBzKHQsZSxpLHIsbixvKXtmb3IodmFyIHM9MTYzODMmZSxhPWU+PjE0Oy0tbz49MDspe3ZhciBjPTE2MzgzJnRoaXNbdF0saD10aGlzW3QrK10+PjE0LHA9YSpjK2gqcztjPXMqYysoKDE2MzgzJnApPDwxNCkraVtyXStuLG49KGM+PjI4KSsocD4+MTQpK2EqaCxpW3IrK109MjY4NDM1NDU1JmN9cmV0dXJuIG59ZnVuY3Rpb24gYSh0KXtyZXR1cm4gUHQuY2hhckF0KHQpfWZ1bmN0aW9uIGModCxlKXt2YXIgaT1BdFt0LmNoYXJDb2RlQXQoZSldO3JldHVybiBudWxsPT1pPy0xOml9ZnVuY3Rpb24gaCh0KXtmb3IodmFyIGU9dGhpcy5peS0xO2U+PTA7LS1lKXRbZV09dGhpc1tlXTt0Lml5PXRoaXMuaXksdC5ueT10aGlzLm55fWZ1bmN0aW9uIHAodCl7dGhpcy5peT0xLHRoaXMubnk9dDwwPy0xOjAsdD4wP3RoaXNbMF09dDp0PC0xP3RoaXNbMF09dCt0aGlzLm95OnRoaXMuaXk9MH1mdW5jdGlvbiB1KHQpe3ZhciBlPXIoKTtyZXR1cm4gZS5zeSh0KSxlfWZ1bmN0aW9uIGwodCxlKXt2YXIgcjtpZigxNj09ZSlyPTQ7ZWxzZSBpZig4PT1lKXI9MztlbHNlIGlmKDI1Nj09ZSlyPTg7ZWxzZSBpZigyPT1lKXI9MTtlbHNlIGlmKDMyPT1lKXI9NTtlbHNle2lmKDQhPWUpcmV0dXJuIHZvaWQgdGhpcy5mcm9tUmFkaXgodCxlKTtyPTJ9dGhpcy5peT0wLHRoaXMubnk9MDtmb3IodmFyIG49dC5sZW5ndGgsbz0hMSxzPTA7LS1uPj0wOyl7dmFyIGE9OD09cj8yNTUmdFtuXTpjKHQsbik7YTwwP1wiLVwiPT10LmNoYXJBdChuKSYmKG89ITApOihvPSExLDA9PXM/dGhpc1t0aGlzLml5KytdPWE6cytyPnRoaXMuYXk/KHRoaXNbdGhpcy5peS0xXXw9KGEmKDE8PHRoaXMuYXktcyktMSk8PHMsdGhpc1t0aGlzLml5KytdPWE+PnRoaXMuYXktcyk6dGhpc1t0aGlzLml5LTFdfD1hPDxzLHMrPXIscz49dGhpcy5heSYmKHMtPXRoaXMuYXkpKX04PT1yJiYwIT0oMTI4JnRbMF0pJiYodGhpcy5ueT0tMSxzPjAmJih0aGlzW3RoaXMuaXktMV18PSgxPDx0aGlzLmF5LXMpLTE8PHMpKSx0aGlzLmh5KCksbyYmaS5aRVJPLnB5KHRoaXMsdGhpcyl9ZnVuY3Rpb24gZCgpe2Zvcih2YXIgdD10aGlzLm55JnRoaXMudXk7dGhpcy5peT4wJiZ0aGlzW3RoaXMuaXktMV09PXQ7KS0tdGhpcy5peX1mdW5jdGlvbiBmKHQpe2lmKHRoaXMubnk8MClyZXR1cm5cIi1cIit0aGlzLmx5KCkudG9TdHJpbmcodCk7dmFyIGU7aWYoMTY9PXQpZT00O2Vsc2UgaWYoOD09dCllPTM7ZWxzZSBpZigyPT10KWU9MTtlbHNlIGlmKDMyPT10KWU9NTtlbHNle2lmKDQhPXQpcmV0dXJuIHRoaXMudG9SYWRpeCh0KTtlPTJ9dmFyIGkscj0oMTw8ZSktMSxuPSExLG89XCJcIixzPXRoaXMuaXksYz10aGlzLmF5LXMqdGhpcy5heSVlO2lmKHMtLSA+MClmb3IoYzx0aGlzLmF5JiYoaT10aGlzW3NdPj5jKT4wJiYobj0hMCxvPWEoaSkpO3M+PTA7KWM8ZT8oaT0odGhpc1tzXSYoMTw8YyktMSk8PGUtYyxpfD10aGlzWy0tc10+PihjKz10aGlzLmF5LWUpKTooaT10aGlzW3NdPj4oYy09ZSkmcixjPD0wJiYoYys9dGhpcy5heSwtLXMpKSxpPjAmJihuPSEwKSxuJiYobys9YShpKSk7cmV0dXJuIG4/bzpcIjBcIn1mdW5jdGlvbiBnKCl7dmFyIHQ9cigpO3JldHVybiBpLlpFUk8ucHkodGhpcyx0KSx0fWZ1bmN0aW9uIHYoKXtyZXR1cm4gdGhpcy5ueTwwP3RoaXMubHkoKTp0aGlzfWZ1bmN0aW9uIHkodCl7dmFyIGU9dGhpcy5ueS10Lm55O2lmKDAhPWUpcmV0dXJuIGU7dmFyIGk9dGhpcy5peTtpZihlPWktdC5peSwwIT1lKXJldHVybiB0aGlzLm55PDA/LWU6ZTtmb3IoOy0taT49MDspaWYoMCE9KGU9dGhpc1tpXS10W2ldKSlyZXR1cm4gZTtyZXR1cm4gMH1mdW5jdGlvbiBtKHQpe3ZhciBlLGk9MTtyZXR1cm4gMCE9KGU9dD4+PjE2KSYmKHQ9ZSxpKz0xNiksMCE9KGU9dD4+OCkmJih0PWUsaSs9OCksMCE9KGU9dD4+NCkmJih0PWUsaSs9NCksMCE9KGU9dD4+MikmJih0PWUsaSs9MiksMCE9KGU9dD4+MSkmJih0PWUsaSs9MSksaX1mdW5jdGlvbiB3KCl7cmV0dXJuIHRoaXMuaXk8PTA/MDp0aGlzLmF5Kih0aGlzLml5LTEpK20odGhpc1t0aGlzLml5LTFdXnRoaXMubnkmdGhpcy51eSl9ZnVuY3Rpb24gVCh0LGUpe3ZhciBpO2ZvcihpPXRoaXMuaXktMTtpPj0wOy0taSllW2krdF09dGhpc1tpXTtmb3IoaT10LTE7aT49MDstLWkpZVtpXT0wO2UuaXk9dGhpcy5peSt0LGUubnk9dGhpcy5ueX1mdW5jdGlvbiBTKHQsZSl7Zm9yKHZhciBpPXQ7aTx0aGlzLml5OysraSllW2ktdF09dGhpc1tpXTtlLml5PU1hdGgubWF4KHRoaXMuaXktdCwwKSxlLm55PXRoaXMubnl9ZnVuY3Rpb24gYih0LGUpe3ZhciBpLHI9dCV0aGlzLmF5LG49dGhpcy5heS1yLG89KDE8PG4pLTEscz1NYXRoLmZsb29yKHQvdGhpcy5heSksYT10aGlzLm55PDxyJnRoaXMudXk7Zm9yKGk9dGhpcy5peS0xO2k+PTA7LS1pKWVbaStzKzFdPXRoaXNbaV0+Pm58YSxhPSh0aGlzW2ldJm8pPDxyO2ZvcihpPXMtMTtpPj0wOy0taSllW2ldPTA7ZVtzXT1hLGUuaXk9dGhpcy5peStzKzEsZS5ueT10aGlzLm55LGUuaHkoKX1mdW5jdGlvbiBFKHQsZSl7ZS5ueT10aGlzLm55O3ZhciBpPU1hdGguZmxvb3IodC90aGlzLmF5KTtpZihpPj10aGlzLml5KXJldHVybiB2b2lkKGUuaXk9MCk7dmFyIHI9dCV0aGlzLmF5LG49dGhpcy5heS1yLG89KDE8PHIpLTE7ZVswXT10aGlzW2ldPj5yO2Zvcih2YXIgcz1pKzE7czx0aGlzLml5OysrcyllW3MtaS0xXXw9KHRoaXNbc10mbyk8PG4sZVtzLWldPXRoaXNbc10+PnI7cj4wJiYoZVt0aGlzLml5LWktMV18PSh0aGlzLm55Jm8pPDxuKSxlLml5PXRoaXMuaXktaSxlLmh5KCl9ZnVuY3Rpb24gSSh0LGUpe2Zvcih2YXIgaT0wLHI9MCxuPU1hdGgubWluKHQuaXksdGhpcy5peSk7aTxuOylyKz10aGlzW2ldLXRbaV0sZVtpKytdPXImdGhpcy51eSxyPj49dGhpcy5heTtpZih0Lml5PHRoaXMuaXkpe2ZvcihyLT10Lm55O2k8dGhpcy5peTspcis9dGhpc1tpXSxlW2krK109ciZ0aGlzLnV5LHI+Pj10aGlzLmF5O3IrPXRoaXMubnl9ZWxzZXtmb3Iocis9dGhpcy5ueTtpPHQuaXk7KXItPXRbaV0sZVtpKytdPXImdGhpcy51eSxyPj49dGhpcy5heTtyLT10Lm55fWUubnk9cjwwPy0xOjAscjwtMT9lW2krK109dGhpcy5veStyOnI+MCYmKGVbaSsrXT1yKSxlLml5PWksZS5oeSgpfWZ1bmN0aW9uIFIodCxlKXt2YXIgcj10aGlzLmFicygpLG49dC5hYnMoKSxvPXIuaXk7Zm9yKGUuaXk9bytuLml5Oy0tbz49MDspZVtvXT0wO2ZvcihvPTA7bzxuLml5OysrbyllW28rci5peV09ci5neSgwLG5bb10sZSxvLDAsci5peSk7ZS5ueT0wLGUuaHkoKSx0aGlzLm55IT10Lm55JiZpLlpFUk8ucHkoZSxlKX1mdW5jdGlvbiBrKHQpe2Zvcih2YXIgZT10aGlzLmFicygpLGk9dC5peT0yKmUuaXk7LS1pPj0wOyl0W2ldPTA7Zm9yKGk9MDtpPGUuaXktMTsrK2kpe3ZhciByPWUuZ3koaSxlW2ldLHQsMippLDAsMSk7KHRbaStlLml5XSs9ZS5neShpKzEsMiplW2ldLHQsMippKzEscixlLml5LWktMSkpPj1lLm95JiYodFtpK2UuaXldLT1lLm95LHRbaStlLml5KzFdPTEpfXQuaXk+MCYmKHRbdC5peS0xXSs9ZS5neShpLGVbaV0sdCwyKmksMCwxKSksdC5ueT0wLHQuaHkoKX1mdW5jdGlvbiBDKHQsZSxuKXt2YXIgbz10LmFicygpO2lmKCEoby5peTw9MCkpe3ZhciBzPXRoaXMuYWJzKCk7aWYocy5peTxvLml5KXJldHVybiBudWxsIT1lJiZlLnN5KDApLHZvaWQobnVsbCE9biYmdGhpcy52eShuKSk7bnVsbD09biYmKG49cigpKTt2YXIgYT1yKCksYz10aGlzLm55LGg9dC5ueSxwPXRoaXMuYXktbShvW28uaXktMV0pO3A+MD8oby55eShwLGEpLHMueXkocCxuKSk6KG8udnkoYSkscy52eShuKSk7dmFyIHU9YS5peSxsPWFbdS0xXTtpZigwIT1sKXt2YXIgZD1sKigxPDx0aGlzLm15KSsodT4xP2FbdS0yXT4+dGhpcy53eTowKSxmPXRoaXMuVHkvZCxnPSgxPDx0aGlzLm15KS9kLHY9MTw8dGhpcy53eSx5PW4uaXksdz15LXUsVD1udWxsPT1lP3IoKTplO2ZvcihhLlN5KHcsVCksbi5ieShUKT49MCYmKG5bbi5peSsrXT0xLG4ucHkoVCxuKSksaS5PTkUuU3kodSxUKSxULnB5KGEsYSk7YS5peTx1OylhW2EuaXkrK109MDtmb3IoOy0tdz49MDspe3ZhciBTPW5bLS15XT09bD90aGlzLnV5Ok1hdGguZmxvb3Ioblt5XSpmKyhuW3ktMV0rdikqZyk7aWYoKG5beV0rPWEuZ3koMCxTLG4sdywwLHUpKTxTKWZvcihhLlN5KHcsVCksbi5weShULG4pO25beV08LS1TOyluLnB5KFQsbil9bnVsbCE9ZSYmKG4uRXkodSxlKSxjIT1oJiZpLlpFUk8ucHkoZSxlKSksbi5peT11LG4uaHkoKSxwPjAmJm4uSXkocCxuKSxjPDAmJmkuWkVSTy5weShuLG4pfX19ZnVuY3Rpb24gTyh0KXt2YXIgZT1yKCk7cmV0dXJuIHRoaXMuYWJzKCkuUnkodCxudWxsLGUpLHRoaXMubnk8MCYmZS5ieShpLlpFUk8pPjAmJnQucHkoZSxlKSxlfWZ1bmN0aW9uIFAodCl7dGhpcy5pPXR9ZnVuY3Rpb24gQSh0KXtyZXR1cm4gdC5ueTwwfHx0LmJ5KHRoaXMuaSk+PTA/dC5reSh0aGlzLmkpOnR9ZnVuY3Rpb24gTih0KXtyZXR1cm4gdH1mdW5jdGlvbiB4KHQpe3QuUnkodGhpcy5pLG51bGwsdCl9ZnVuY3Rpb24gQih0LGUsaSl7dC5DeShlLGkpLHRoaXMucmVkdWNlKGkpfWZ1bmN0aW9uIEYodCxlKXt0Lk95KGUpLHRoaXMucmVkdWNlKGUpfWZ1bmN0aW9uIF8oKXtpZih0aGlzLml5PDEpcmV0dXJuIDA7dmFyIHQ9dGhpc1swXTtpZigwPT0oMSZ0KSlyZXR1cm4gMDt2YXIgZT0zJnQ7cmV0dXJuIGU9ZSooMi0oMTUmdCkqZSkmMTUsZT1lKigyLSgyNTUmdCkqZSkmMjU1LGU9ZSooMi0oKDY1NTM1JnQpKmUmNjU1MzUpKSY2NTUzNSxlPWUqKDItdCplJXRoaXMub3kpJXRoaXMub3ksZT4wP3RoaXMub3ktZTotZX1mdW5jdGlvbiBEKHQpe3RoaXMuaT10LHRoaXMuUHk9dC5BeSgpLHRoaXMuTnk9MzI3NjcmdGhpcy5QeSx0aGlzLnh5PXRoaXMuUHk+PjE1LHRoaXMuQnk9KDE8PHQuYXktMTUpLTEsdGhpcy5GeT0yKnQuaXl9ZnVuY3Rpb24gSCh0KXt2YXIgZT1yKCk7cmV0dXJuIHQuYWJzKCkuU3kodGhpcy5pLml5LGUpLGUuUnkodGhpcy5pLG51bGwsZSksdC5ueTwwJiZlLmJ5KGkuWkVSTyk+MCYmdGhpcy5pLnB5KGUsZSksZX1mdW5jdGlvbiBMKHQpe3ZhciBlPXIoKTtyZXR1cm4gdC52eShlKSx0aGlzLnJlZHVjZShlKSxlfWZ1bmN0aW9uIE0odCl7Zm9yKDt0Lml5PD10aGlzLkZ5Oyl0W3QuaXkrK109MDtmb3IodmFyIGU9MDtlPHRoaXMuaS5peTsrK2Upe3ZhciBpPTMyNzY3JnRbZV0scj1pKnRoaXMuTnkrKChpKnRoaXMueHkrKHRbZV0+PjE1KSp0aGlzLk55JnRoaXMuQnkpPDwxNSkmdC51eTtmb3IoaT1lK3RoaXMuaS5peSx0W2ldKz10aGlzLmkuZ3koMCxyLHQsZSwwLHRoaXMuaS5peSk7dFtpXT49dC5veTspdFtpXS09dC5veSx0WysraV0rK310Lmh5KCksdC5FeSh0aGlzLmkuaXksdCksdC5ieSh0aGlzLmkpPj0wJiZ0LnB5KHRoaXMuaSx0KX1mdW5jdGlvbiBqKHQsZSl7dC5PeShlKSx0aGlzLnJlZHVjZShlKX1mdW5jdGlvbiBVKHQsZSxpKXt0LkN5KGUsaSksdGhpcy5yZWR1Y2UoaSl9ZnVuY3Rpb24gVigpe3JldHVybiAwPT0odGhpcy5peT4wPzEmdGhpc1swXTp0aGlzLm55KX1mdW5jdGlvbiBRKHQsZSl7aWYodD40Mjk0OTY3Mjk1fHx0PDEpcmV0dXJuIGkuT05FO3ZhciBuPXIoKSxvPXIoKSxzPWUuX3kodGhpcyksYT1tKHQpLTE7Zm9yKHMudnkobik7LS1hPj0wOylpZihlLkR5KG4sbyksKHQmMTw8YSk+MCllLkh5KG8scyxuKTtlbHNle3ZhciBjPW47bj1vLG89Y31yZXR1cm4gZS5MeShuKX1mdW5jdGlvbiBxKHQsZSl7dmFyIGk7cmV0dXJuIGk9dDwyNTZ8fGUuTXkoKT9uZXcgUChlKTpuZXcgRChlKSx0aGlzLmV4cCh0LGkpfWZ1bmN0aW9uIEoodCl7dmFyIGUsaSxyLG49XCJcIixvPTA7Zm9yKGU9MDtlPHQubGVuZ3RoJiZ0LmNoYXJBdChlKSE9eHQ7KytlKXI9TnQuaW5kZXhPZih0LmNoYXJBdChlKSkscjwwfHwoMD09bz8obis9YShyPj4yKSxpPTMmcixvPTEpOjE9PW8/KG4rPWEoaTw8MnxyPj40KSxpPTE1JnIsbz0yKToyPT1vPyhuKz1hKGkpLG4rPWEocj4+MiksaT0zJnIsbz0zKToobis9YShpPDwyfHI+PjQpLG4rPWEoMTUmciksbz0wKSk7cmV0dXJuIDE9PW8mJihuKz1hKGk8PDIpKSxufWZ1bmN0aW9uIEsodCl7dmFyIGUsaT1KKHQpLHI9bmV3IEFycmF5O2ZvcihlPTA7MiplPGkubGVuZ3RoOysrZSlyW2VdPXBhcnNlSW50KGkuc3Vic3RyaW5nKDIqZSwyKmUrMiksMTYpO3JldHVybiByfS8qISAoYykgVG9tIFd1IHwgaHR0cDovL3d3dy1jcy1zdHVkZW50cy5zdGFuZm9yZC5lZHUvfnRqdy9qc2JuL1xuICovXG4gIGZ1bmN0aW9uIEcodCxlKXtyZXR1cm4gbmV3IGkodCxlKX1mdW5jdGlvbiB6KHQsZSl7aWYoZTx0Lmxlbmd0aCsxMSlyZXR1cm4gYWxlcnQoXCJNZXNzYWdlIHRvbyBsb25nIGZvciBSU0FcIiksbnVsbDtmb3IodmFyIHI9bmV3IEFycmF5LG49dC5sZW5ndGgtMTtuPj0wJiZlPjA7KXt2YXIgbz10LmNoYXJDb2RlQXQobi0tKTtvPDEyOD9yWy0tZV09bzpvPjEyNyYmbzwyMDQ4PyhyWy0tZV09NjMmb3wxMjgsclstLWVdPW8+PjZ8MTkyKTooclstLWVdPTYzJm98MTI4LHJbLS1lXT1vPj42JjYzfDEyOCxyWy0tZV09bz4+MTJ8MjI0KX1yWy0tZV09MDtmb3IodmFyIHM9bmV3IFNlY3VyZVJhbmRvbSxhPW5ldyBBcnJheTtlPjI7KXtmb3IoYVswXT0wOzA9PWFbMF07KXMubmV4dEJ5dGVzKGEpO3JbLS1lXT1hWzBdfXJldHVybiByWy0tZV09MixyWy0tZV09MCxuZXcgaShyKX1mdW5jdGlvbiBXKHQsZSxpKXtmb3IodmFyIHI9XCJcIixuPTA7ci5sZW5ndGg8ZTspcis9aShTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyx0LmNvbmNhdChbKDQyNzgxOTAwODAmbik+PjI0LCgxNjcxMTY4MCZuKT4+MTYsKDY1MjgwJm4pPj44LDI1NSZuXSkpKSxuKz0xO3JldHVybiByfWZ1bmN0aW9uICQodCxlLHIpe2lmKHQubGVuZ3RoKzIqQnQrMj5lKXRocm93XCJNZXNzYWdlIHRvbyBsb25nIGZvciBSU0FcIjt2YXIgbixvPVwiXCI7Zm9yKG49MDtuPGUtdC5sZW5ndGgtMipCdC0yO24rPTEpbys9XCJcXDBcIjt2YXIgcz1yc3RyX3NoYTEoXCJcIikrbytcIlx1MDAwMVwiK3QsYT1uZXcgQXJyYXkoQnQpOyhuZXcgU2VjdXJlUmFuZG9tKS5uZXh0Qnl0ZXMoYSk7dmFyIGM9VyhhLHMubGVuZ3RoLHJ8fHJzdHJfc2hhMSksaD1bXTtmb3Iobj0wO248cy5sZW5ndGg7bis9MSloW25dPXMuY2hhckNvZGVBdChuKV5jLmNoYXJDb2RlQXQobik7dmFyIHA9VyhoLGEubGVuZ3RoLHJzdHJfc2hhMSksdT1bMF07Zm9yKG49MDtuPGEubGVuZ3RoO24rPTEpdVtuKzFdPWFbbl1ecC5jaGFyQ29kZUF0KG4pO3JldHVybiBuZXcgaSh1LmNvbmNhdChoKSl9ZnVuY3Rpb24gWSgpe3RoaXMubj1udWxsLHRoaXMuZT0wLHRoaXMuZD1udWxsLHRoaXMubz1udWxsLHRoaXMuank9bnVsbCx0aGlzLlV5PW51bGwsdGhpcy5WeT1udWxsLHRoaXMuUXk9bnVsbH1mdW5jdGlvbiBYKHQsZSl7dGhpcy5xeT0hMCxcInN0cmluZ1wiIT10eXBlb2YgdD8odGhpcy5uPXQsdGhpcy5lPWUpOm51bGwhPXQmJm51bGwhPWUmJnQubGVuZ3RoPjAmJmUubGVuZ3RoPjA/KHRoaXMubj1HKHQsMTYpLHRoaXMuZT1wYXJzZUludChlLDE2KSk6YWxlcnQoXCJJbnZhbGlkIFJTQSBwdWJsaWMga2V5XCIpfWZ1bmN0aW9uIFoodCl7cmV0dXJuIHQuSnkodGhpcy5lLHRoaXMubil9ZnVuY3Rpb24gdHQodCl7dmFyIGU9eih0LHRoaXMubi5LeSgpKzc+PjMpO2lmKG51bGw9PWUpcmV0dXJuIG51bGw7dmFyIGk9dGhpcy5HeShlKTtpZihudWxsPT1pKXJldHVybiBudWxsO3ZhciByPWkudG9TdHJpbmcoMTYpO3JldHVybiAwPT0oMSZyLmxlbmd0aCk/cjpcIjBcIityfWZ1bmN0aW9uIGV0KHQsZSl7dmFyIGk9JCh0LHRoaXMubi5LeSgpKzc+PjMsZSk7aWYobnVsbD09aSlyZXR1cm4gbnVsbDt2YXIgcj10aGlzLkd5KGkpO2lmKG51bGw9PXIpcmV0dXJuIG51bGw7dmFyIG49ci50b1N0cmluZygxNik7cmV0dXJuIDA9PSgxJm4ubGVuZ3RoKT9uOlwiMFwiK259ZnVuY3Rpb24gaXQodCxlKXtmb3IodmFyIGk9XCJcIixyPWUvNC10Lmxlbmd0aCxuPTA7bjxyO24rKylpKz1cIjBcIjtyZXR1cm4gaSt0fWZ1bmN0aW9uIHJ0KHQsZSl7dmFyIGk9ZnVuY3Rpb24odCl7cmV0dXJuIEtKVVIuY3J5cHRvLld5Lnp5KHQsZSl9LHI9aSh0KTtyZXR1cm4gdGhpcy4keShyLGUpfWZ1bmN0aW9uIG50KHQsZSl7dmFyIGk9S0pVUi5jcnlwdG8uV3kuWXkodCxlLHRoaXMubi5LeSgpKSxyPUcoaSwxNiksbj10aGlzLmRvUHJpdmF0ZShyKSxvPW4udG9TdHJpbmcoMTYpO3JldHVybiBpdChvLHRoaXMubi5LeSgpKX1mdW5jdGlvbiBvdCh0KXtyZXR1cm4gcnQuY2FsbCh0aGlzLHQsXCJzaGExXCIpfWZ1bmN0aW9uIHN0KHQpe3JldHVybiBydC5jYWxsKHRoaXMsdCxcInNoYTI1NlwiKX1mdW5jdGlvbiBhdCh0LGUsaSl7Zm9yKHZhciByPVwiXCIsbj0wO3IubGVuZ3RoPGU7KXIrPWhleHRvcnN0cihpKHJzdHJ0b2hleCh0K1N0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLFsoNDI3ODE5MDA4MCZuKT4+MjQsKDE2NzExNjgwJm4pPj4xNiwoNjUyODAmbik+PjgsMjU1Jm5dKSkpKSxuKz0xO3JldHVybiByfWZ1bmN0aW9uIGN0KHQsZSxpKXt2YXIgcj1mdW5jdGlvbih0KXtyZXR1cm4gS0pVUi5jcnlwdG8uV3kuWHkodCxlKX0sbj1yKHJzdHJ0b2hleCh0KSk7cmV0dXJuIHZvaWQgMD09PWkmJihpPS0xKSx0aGlzLlp5KG4sZSxpKX1mdW5jdGlvbiBodCh0LGUscil7dmFyIG4sbz1oZXh0b3JzdHIodCkscz1vLmxlbmd0aCxhPXRoaXMubi5LeSgpLTEsYz1NYXRoLmNlaWwoYS84KSxoPWZ1bmN0aW9uKHQpe3JldHVybiBLSlVSLmNyeXB0by5XeS5YeSh0LGUpfTtpZihyPT09LTF8fHZvaWQgMD09PXIpcj1zO2Vsc2UgaWYocj09PS0yKXI9Yy1zLTI7ZWxzZSBpZihyPC0yKXRocm93XCJpbnZhbGlkIHNhbHQgbGVuZ3RoXCI7aWYoYzxzK3IrMil0aHJvd1wiZGF0YSB0b28gbG9uZ1wiO3ZhciBwPVwiXCI7cj4wJiYocD1uZXcgQXJyYXkociksKG5ldyBTZWN1cmVSYW5kb20pLm5leHRCeXRlcyhwKSxwPVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLHApKTt2YXIgdT1oZXh0b3JzdHIoaChyc3RydG9oZXgoXCJcXDBcXDBcXDBcXDBcXDBcXDBcXDBcXDBcIitvK3ApKSksbD1bXTtmb3Iobj0wO248Yy1yLXMtMjtuKz0xKWxbbl09MDt2YXIgZD1TdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyxsKStcIlx1MDAwMVwiK3AsZj1hdCh1LGQubGVuZ3RoLGgpLGc9W107Zm9yKG49MDtuPGQubGVuZ3RoO24rPTEpZ1tuXT1kLmNoYXJDb2RlQXQobileZi5jaGFyQ29kZUF0KG4pO3ZhciB2PTY1MjgwPj44KmMtYSYyNTU7Zm9yKGdbMF0mPX52LG49MDtuPHM7bisrKWcucHVzaCh1LmNoYXJDb2RlQXQobikpO3JldHVybiBnLnB1c2goMTg4KSxpdCh0aGlzLmRvUHJpdmF0ZShuZXcgaShnKSkudG9TdHJpbmcoMTYpLHRoaXMubi5LeSgpKX1mdW5jdGlvbiBwdCh0LGUsaSl7dmFyIHI9bmV3IFk7ci5xaChlLGkpO3ZhciBuPXIuR3kodCk7cmV0dXJuIG59ZnVuY3Rpb24gdXQodCxlLGkpe3ZhciByPXB0KHQsZSxpKSxuPXIudG9TdHJpbmcoMTYpLnJlcGxhY2UoL14xZiswMC8sXCJcIik7cmV0dXJuIG59ZnVuY3Rpb24gbHQodCl7Zm9yKHZhciBlIGluIEtKVVIuY3J5cHRvLld5LnRtKXt2YXIgaT1LSlVSLmNyeXB0by5XeS50bVtlXSxyPWkubGVuZ3RoO2lmKHQuc3Vic3RyaW5nKDAscik9PWkpe3ZhciBuPVtlLHQuc3Vic3RyaW5nKHIpXTtyZXR1cm4gbn19cmV0dXJuW119ZnVuY3Rpb24gZHQodCxlLGkscil7dmFyIG49dXQoZSxpLHIpLG89bHQobik7aWYoMD09by5sZW5ndGgpcmV0dXJuITE7dmFyIHM9b1swXSxhPW9bMV0sYz1mdW5jdGlvbih0KXtyZXR1cm4gS0pVUi5jcnlwdG8uV3kuenkodCxzKX0saD1jKHQpO3JldHVybiBhPT1ofWZ1bmN0aW9uIGZ0KHQsZSl7dmFyIGk9Ryh0LDE2KSxyPWR0KGUsaSx0aGlzLm4udG9TdHJpbmcoMTYpLHRoaXMuZS50b1N0cmluZygxNikpO3JldHVybiByfWZ1bmN0aW9uIGd0KHQsZSl7ZT1lLnJlcGxhY2UoRnQsXCJcIiksZT1lLnJlcGxhY2UoL1sgXFxuXSsvZyxcIlwiKTt2YXIgaT1HKGUsMTYpO2lmKGkuS3koKT50aGlzLm4uS3koKSlyZXR1cm4gMDt2YXIgcj10aGlzLkd5KGkpLG49ci50b1N0cmluZygxNikucmVwbGFjZSgvXjFmKzAwLyxcIlwiKSxvPWx0KG4pO2lmKDA9PW8ubGVuZ3RoKXJldHVybiExO3ZhciBzPW9bMF0sYT1vWzFdLGM9ZnVuY3Rpb24odCl7cmV0dXJuIEtKVVIuY3J5cHRvLld5Lnp5KHQscyl9LGg9Yyh0KTtyZXR1cm4gYT09aH1mdW5jdGlvbiB2dCh0LGUpe2U9ZS5yZXBsYWNlKEZ0LFwiXCIpLGU9ZS5yZXBsYWNlKC9bIFxcbl0rL2csXCJcIik7dmFyIGk9RyhlLDE2KTtpZihpLkt5KCk+dGhpcy5uLkt5KCkpcmV0dXJuIDA7dmFyIHI9dGhpcy5HeShpKSxuPXIudG9TdHJpbmcoMTYpLnJlcGxhY2UoL14xZiswMC8sXCJcIiksbz1sdChuKTtpZigwPT1vLmxlbmd0aClyZXR1cm4hMTt2YXIgcz0ob1swXSxvWzFdKTtyZXR1cm4gcz09dH1mdW5jdGlvbiB5dCh0LGUsaSxyKXt2YXIgbj1mdW5jdGlvbih0KXtyZXR1cm4gS0pVUi5jcnlwdG8uV3kuWHkodCxpKX0sbz1uKHJzdHJ0b2hleCh0KSk7cmV0dXJuIHZvaWQgMD09PXImJihyPS0xKSx0aGlzLmVtKG8sZSxpLHIpfWZ1bmN0aW9uIG10KHQsZSxyLG4pe3ZhciBvPW5ldyBpKGUsMTYpO2lmKG8uS3koKT50aGlzLm4uS3koKSlyZXR1cm4hMTt2YXIgcyxhPWZ1bmN0aW9uKHQpe3JldHVybiBLSlVSLmNyeXB0by5XeS5YeSh0LHIpfSxjPWhleHRvcnN0cih0KSxoPWMubGVuZ3RoLHA9dGhpcy5uLkt5KCktMSx1PU1hdGguY2VpbChwLzgpO2lmKG49PT0tMXx8dm9pZCAwPT09biluPWg7ZWxzZSBpZihuPT09LTIpbj11LWgtMjtlbHNlIGlmKG48LTIpdGhyb3dcImludmFsaWQgc2FsdCBsZW5ndGhcIjtpZih1PGgrbisyKXRocm93XCJkYXRhIHRvbyBsb25nXCI7dmFyIGw9dGhpcy5HeShvKS50b0J5dGVBcnJheSgpO2ZvcihzPTA7czxsLmxlbmd0aDtzKz0xKWxbc10mPTI1NTtmb3IoO2wubGVuZ3RoPHU7KWwudW5zaGlmdCgwKTtpZigxODghPT1sW3UtMV0pdGhyb3dcImVuY29kZWQgbWVzc2FnZSBkb2VzIG5vdCBlbmQgaW4gMHhiY1wiO2w9U3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsbCk7dmFyIGQ9bC5zdWJzdHIoMCx1LWgtMSksZj1sLnN1YnN0cihkLmxlbmd0aCxoKSxnPTY1MjgwPj44KnUtcCYyNTU7aWYoMCE9PShkLmNoYXJDb2RlQXQoMCkmZykpdGhyb3dcImJpdHMgYmV5b25kIGtleXNpemUgbm90IHplcm9cIjt2YXIgdj1hdChmLGQubGVuZ3RoLGEpLHk9W107Zm9yKHM9MDtzPGQubGVuZ3RoO3MrPTEpeVtzXT1kLmNoYXJDb2RlQXQocyledi5jaGFyQ29kZUF0KHMpO3lbMF0mPX5nO3ZhciBtPXUtaC1uLTI7Zm9yKHM9MDtzPG07cys9MSlpZigwIT09eVtzXSl0aHJvd1wibGVmdG1vc3Qgb2N0ZXRzIG5vdCB6ZXJvXCI7aWYoMSE9PXlbbV0pdGhyb3dcIjB4MDEgbWFya2VyIG5vdCBmb3VuZFwiO3JldHVybiBmPT09aGV4dG9yc3RyKGEocnN0cnRvaGV4KFwiXFwwXFwwXFwwXFwwXFwwXFwwXFwwXFwwXCIrYytTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyx5LnNsaWNlKC1uKSkpKSl9dmFyIHd0PXt9O3d0LnVzZXJBZ2VudD0hMTt2YXIgVHQ9e307aWYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIFN0fHwhU3QpdmFyIFN0PXt9O1N0LmltPWZ1bmN0aW9uKCl7dmFyIHQsZSxpLHI9YXJndW1lbnRzLG49bnVsbDtmb3IodD0wO3Q8ci5sZW5ndGg7dCs9MSlmb3IoaT0oXCJcIityW3RdKS5zcGxpdChcIi5cIiksbj1TdCxlPVwiWUFIT09cIj09aVswXT8xOjA7ZTxpLmxlbmd0aDtlKz0xKW5baVtlXV09bltpW2VdXXx8e30sbj1uW2lbZV1dO3JldHVybiBufSxTdC5sb2c9ZnVuY3Rpb24odCxlLGkpe3ZhciByPVN0LndpZGdldC5Mb2dnZXI7cmV0dXJuISghcnx8IXIubG9nKSYmci5sb2codCxlLGkpfSxTdC5yZWdpc3Rlcj1mdW5jdGlvbih0LGUsaSl7dmFyIHIsbixvLHMsYSxjPVN0Lk90LnJtO2ZvcihjW3RdfHwoY1t0XT17bm06W10sb206W119KSxyPWNbdF0sbj1pLnZlcnNpb24sbz1pLnBwLHM9U3QuT3Quemksci5uYW1lPXQsci52ZXJzaW9uPW4sci5wcD1vLHIubm0ucHVzaChuKSxyLm9tLnB1c2gobyksci5zbT1lLGE9MDthPHMubGVuZ3RoO2ErPTEpc1thXShyKTtlPyhlLlZFUlNJT049bixlLmFtPW8pOlN0LmxvZyhcIm1haW5DbGFzcyBpcyB1bmRlZmluZWQgZm9yIG1vZHVsZSBcIit0LFwid2FyblwiKX0sU3QuT3Q9U3QuT3R8fHtybTpbXSx6aTpbXX0sU3QuT3QuZ2V0VmVyc2lvbj1mdW5jdGlvbih0KXtyZXR1cm4gU3QuT3Qucm1bdF18fG51bGx9LFN0Lk90LmNtPWZ1bmN0aW9uKHQpe3ZhciBlLGk9ZnVuY3Rpb24odCl7dmFyIGU9MDtyZXR1cm4gcGFyc2VGbG9hdCh0LnJlcGxhY2UoL1xcLi9nLGZ1bmN0aW9uKCl7cmV0dXJuIDE9PWUrKz9cIlwiOlwiLlwifSkpfSxyPXd0LG49e2htOjAsb3BlcmE6MCxwbTowLHVtOjAsY2hyb21lOjAsbG06bnVsbCxkbTowLGZtOjAsZ206MCx2bTowLHltOm51bGwsbW06MCx3bTowLFRtOnImJnIuY2FqYVZlcnNpb24sU206ITEsb3M6bnVsbH0sbz10fHx3dCYmd3QudXNlckFnZW50LHM9VHQmJlR0LmxvY2F0aW9uLGE9cyYmcy5ocmVmO3JldHVybiBuLlNtPWEmJjA9PT1hLnRvTG93ZXJDYXNlKCkuaW5kZXhPZihcImh0dHBzXCIpLG8mJigvd2luZG93c3x3aW4zMi9pLnRlc3Qobyk/bi5vcz1cIndpbmRvd3NcIjovbWFjaW50b3NoL2kudGVzdChvKT9uLm9zPVwibWFjaW50b3NoXCI6L3JoaW5vL2kudGVzdChvKSYmKG4ub3M9XCJyaGlub1wiKSwvS0hUTUwvLnRlc3QobykmJihuLnVtPTEpLGU9by5tYXRjaCgvQXBwbGVXZWJLaXRcXC8oW15cXHNdKikvKSxlJiZlWzFdJiYobi51bT1pKGVbMV0pLC8gTW9iaWxlXFwvLy50ZXN0KG8pPyhuLmxtPVwiQXBwbGVcIixlPW8ubWF0Y2goL09TIChbXlxcc10qKS8pLGUmJmVbMV0mJihlPWkoZVsxXS5yZXBsYWNlKFwiX1wiLFwiLlwiKSkpLG4ueW09ZSxuLmZtPW4udm09bi5nbT0wLGU9by5tYXRjaCgvaVBhZHxpUG9kfGlQaG9uZS8pLGUmJmVbMF0mJihuW2VbMF0udG9Mb3dlckNhc2UoKV09bi55bSkpOihlPW8ubWF0Y2goL05va2lhTlteXFwvXSp8QW5kcm9pZCBcXGRcXC5cXGR8d2ViT1NcXC9cXGRcXC5cXGQvKSxlJiYobi5sbT1lWzBdKSwvd2ViT1MvLnRlc3QobykmJihuLmxtPVwiV2ViT1NcIixlPW8ubWF0Y2goL3dlYk9TXFwvKFteXFxzXSopOy8pLGUmJmVbMV0mJihuLndtPWkoZVsxXSkpKSwvIEFuZHJvaWQvLnRlc3QobykmJihuLmxtPVwiQW5kcm9pZFwiLGU9by5tYXRjaCgvQW5kcm9pZCAoW15cXHNdKik7LyksZSYmZVsxXSYmKG4ubW09aShlWzFdKSkpKSxlPW8ubWF0Y2goL0Nocm9tZVxcLyhbXlxcc10qKS8pLGUmJmVbMV0/bi5jaHJvbWU9aShlWzFdKTooZT1vLm1hdGNoKC9BZG9iZUFJUlxcLyhbXlxcc10qKS8pLGUmJihuLmRtPWVbMF0pKSksbi51bXx8KGU9by5tYXRjaCgvT3BlcmFbXFxzXFwvXShbXlxcc10qKS8pLGUmJmVbMV0/KG4ub3BlcmE9aShlWzFdKSxlPW8ubWF0Y2goL1ZlcnNpb25cXC8oW15cXHNdKikvKSxlJiZlWzFdJiYobi5vcGVyYT1pKGVbMV0pKSxlPW8ubWF0Y2goL09wZXJhIE1pbmlbXjtdKi8pLGUmJihuLmxtPWVbMF0pKTooZT1vLm1hdGNoKC9NU0lFXFxzKFteO10qKS8pLGUmJmVbMV0/bi5obT1pKGVbMV0pOihlPW8ubWF0Y2goL0dlY2tvXFwvKFteXFxzXSopLyksZSYmKG4ucG09MSxlPW8ubWF0Y2goL3J2OihbXlxcc1xcKV0qKS8pLGUmJmVbMV0mJihuLnBtPWkoZVsxXSkpKSkpKSksbn0sU3QuT3QudGY9U3QuT3QuY20oKSxmdW5jdGlvbigpe2lmKFN0LmltKFwidXRpbFwiLFwid2lkZ2V0XCIsXCJleGFtcGxlXCIpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiBZQUhPT19jb25maWcpe3ZhciB0LGU9WUFIT09fY29uZmlnLmxpc3RlbmVyLGk9U3QuT3Quemkscj0hMDtpZihlKXtmb3IodD0wO3Q8aS5sZW5ndGg7dCsrKWlmKGlbdF09PWUpe3I9ITE7YnJlYWt9ciYmaS5wdXNoKGUpfX19KCksU3QubGFuZz1TdC5sYW5nfHx7fSxmdW5jdGlvbigpe3ZhciB0PVN0LmxhbmcsZT1PYmplY3QucHJvdG90eXBlLGk9XCJbb2JqZWN0IEFycmF5XVwiLHI9XCJbb2JqZWN0IEZ1bmN0aW9uXVwiLG49XCJbb2JqZWN0IE9iamVjdF1cIixvPVtdLHM9e2JtOlwiJmFtcDtcIixFbTpcIiZsdDtcIixJbTpcIiZndDtcIixSbTpcIiZxdW90O1wiLGttOlwiJiN4Mjc7XCIsSnA6XCImI3gyRjtcIixDbTpcIiYjeDYwO1wifSxhPVtcInRvU3RyaW5nXCIsXCJ2YWx1ZU9mXCJdLGM9e2lzQXJyYXk6ZnVuY3Rpb24odCl7cmV0dXJuIGUudG9TdHJpbmcuYXBwbHkodCk9PT1pfSxPbTpmdW5jdGlvbih0KXtyZXR1cm5cImJvb2xlYW5cIj09dHlwZW9mIHR9LFBtOmZ1bmN0aW9uKHQpe3JldHVyblwiZnVuY3Rpb25cIj09dHlwZW9mIHR8fGUudG9TdHJpbmcuYXBwbHkodCk9PT1yfSxBbTpmdW5jdGlvbih0KXtyZXR1cm4gbnVsbD09PXR9LE5tOmZ1bmN0aW9uKHQpe3JldHVyblwibnVtYmVyXCI9PXR5cGVvZiB0JiZpc0Zpbml0ZSh0KX0sb3Y6ZnVuY3Rpb24oZSl7cmV0dXJuIGUmJihcIm9iamVjdFwiPT10eXBlb2YgZXx8dC5QbShlKSl8fCExfSx4bTpmdW5jdGlvbih0KXtyZXR1cm5cInN0cmluZ1wiPT10eXBlb2YgdH0sQm06ZnVuY3Rpb24odCl7cmV0dXJuXCJ1bmRlZmluZWRcIj09dHlwZW9mIHR9LEZtOlN0Lk90LnRmLmhtP2Z1bmN0aW9uKGkscil7dmFyIG4sbyxzO2ZvcihuPTA7bjxhLmxlbmd0aDtuKz0xKW89YVtuXSxzPXJbb10sdC5QbShzKSYmcyE9ZVtvXSYmKGlbb109cyl9OmZ1bmN0aW9uKCl7fSxfbTpmdW5jdGlvbih0KXtyZXR1cm4gdC5yZXBsYWNlKC9bJjw+XCInXFwvYF0vZyxmdW5jdGlvbih0KXtyZXR1cm4gc1t0XX0pfSxleHRlbmQ6ZnVuY3Rpb24oaSxyLG4pe2lmKCFyfHwhaSl0aHJvdyBuZXcgRXJyb3IoXCJleHRlbmQgZmFpbGVkLCBwbGVhc2UgY2hlY2sgdGhhdCBhbGwgZGVwZW5kZW5jaWVzIGFyZSBpbmNsdWRlZC5cIik7dmFyIG8scz1mdW5jdGlvbigpe307aWYocy5wcm90b3R5cGU9ci5wcm90b3R5cGUsaS5wcm90b3R5cGU9bmV3IHMsaS5wcm90b3R5cGUuY29uc3RydWN0b3I9aSxpLkRtPXIucHJvdG90eXBlLHIucHJvdG90eXBlLmNvbnN0cnVjdG9yPT1lLmNvbnN0cnVjdG9yJiYoci5wcm90b3R5cGUuY29uc3RydWN0b3I9ciksbil7Zm9yKG8gaW4gbil0Lmhhc093blByb3BlcnR5KG4sbykmJihpLnByb3RvdHlwZVtvXT1uW29dKTt0LkZtKGkucHJvdG90eXBlLG4pfX0sSG06ZnVuY3Rpb24oZSxpKXtpZighaXx8IWUpdGhyb3cgbmV3IEVycm9yKFwiQWJzb3JiIGZhaWxlZCwgdmVyaWZ5IGRlcGVuZGVuY2llcy5cIik7dmFyIHIsbixvPWFyZ3VtZW50cyxzPW9bMl07aWYocyYmcyE9PSEwKWZvcihyPTI7cjxvLmxlbmd0aDtyKz0xKWVbb1tyXV09aVtvW3JdXTtlbHNle2ZvcihuIGluIGkpIXMmJm4gaW4gZXx8KGVbbl09aVtuXSk7dC5GbShlLGkpfXJldHVybiBlfSxMbTpmdW5jdGlvbihlLGkpe2lmKCFpfHwhZSl0aHJvdyBuZXcgRXJyb3IoXCJBdWdtZW50IGZhaWxlZCwgdmVyaWZ5IGRlcGVuZGVuY2llcy5cIik7dmFyIHIsbj1bZS5wcm90b3R5cGUsaS5wcm90b3R5cGVdO2ZvcihyPTI7cjxhcmd1bWVudHMubGVuZ3RoO3IrPTEpbi5wdXNoKGFyZ3VtZW50c1tyXSk7cmV0dXJuIHQuSG0uYXBwbHkodGhpcyxuKSxlfSxkdW1wOmZ1bmN0aW9uKGUsaSl7dmFyIHIsbixvPVtdLHM9XCJ7Li4ufVwiLGE9XCJmKCl7Li4ufVwiLGM9XCIsIFwiLGg9XCIgPT4gXCI7aWYoIXQub3YoZSkpcmV0dXJuIGUrXCJcIjtpZihlIGluc3RhbmNlb2YgRGF0ZXx8XCJub2RlVHlwZVwiaW4gZSYmXCJ0YWdOYW1lXCJpbiBlKXJldHVybiBlO2lmKHQuUG0oZSkpcmV0dXJuIGE7aWYoaT10Lk5tKGkpP2k6Myx0LmlzQXJyYXkoZSkpe2ZvcihvLnB1c2goXCJbXCIpLHI9MCxuPWUubGVuZ3RoO3I8bjtyKz0xKXQub3YoZVtyXSk/by5wdXNoKGk+MD90LmR1bXAoZVtyXSxpLTEpOnMpOm8ucHVzaChlW3JdKSxvLnB1c2goYyk7by5sZW5ndGg+MSYmby5wb3AoKSxvLnB1c2goXCJdXCIpfWVsc2V7by5wdXNoKFwie1wiKTtmb3IociBpbiBlKXQuaGFzT3duUHJvcGVydHkoZSxyKSYmKG8ucHVzaChyK2gpLHQub3YoZVtyXSk/by5wdXNoKGk+MD90LmR1bXAoZVtyXSxpLTEpOnMpOm8ucHVzaChlW3JdKSxvLnB1c2goYykpO28ubGVuZ3RoPjEmJm8ucG9wKCksby5wdXNoKFwifVwiKX1yZXR1cm4gby5qb2luKFwiXCIpfSxNbTpmdW5jdGlvbihlLGkscixvKXtmb3IodmFyIHMsYSxjLGgscCx1LGwsZCxmLGc9W10sdj1lLmxlbmd0aCx5PVwiZHVtcFwiLG09XCIgXCIsdz1cIntcIixUPVwifVwiOyhzPWUubGFzdEluZGV4T2Yodyx2KSwhKHM8MCkpJiYoYT1lLmluZGV4T2YoVCxzKSwhKHMrMT5hKSk7KWw9ZS5zdWJzdHJpbmcocysxLGEpLGg9bCx1PW51bGwsYz1oLmluZGV4T2YobSksYz4tMSYmKHU9aC5zdWJzdHJpbmcoYysxKSxoPWguc3Vic3RyaW5nKDAsYykpLHA9aVtoXSxyJiYocD1yKGgscCx1KSksdC5vdihwKT90LmlzQXJyYXkocCk/cD10LmR1bXAocCxwYXJzZUludCh1LDEwKSk6KHU9dXx8XCJcIixkPXUuaW5kZXhPZih5KSxkPi0xJiYodT11LnN1YnN0cmluZyg0KSksZj1wLnRvU3RyaW5nKCkscD1mPT09bnx8ZD4tMT90LmR1bXAocCxwYXJzZUludCh1LDEwKSk6Zik6dC54bShwKXx8dC5ObShwKXx8KHA9XCJ+LVwiK2cubGVuZ3RoK1wiLX5cIixnW2cubGVuZ3RoXT1sKSxlPWUuc3Vic3RyaW5nKDAscykrcCtlLnN1YnN0cmluZyhhKzEpLG89PT0hMSYmKHY9cy0xKTtmb3Iocz1nLmxlbmd0aC0xO3M+PTA7cy09MSllPWUucmVwbGFjZShuZXcgUmVnRXhwKFwifi1cIitzK1wiLX5cIiksXCJ7XCIrZ1tzXStcIn1cIixcImdcIik7cmV0dXJuIGV9LHRyaW06ZnVuY3Rpb24odCl7dHJ5e3JldHVybiB0LnJlcGxhY2UoL15cXHMrfFxccyskL2csXCJcIil9Y2F0Y2goZSl7cmV0dXJuIHR9fSxqbTpmdW5jdGlvbigpe3ZhciBlLGk9e30scj1hcmd1bWVudHMsbj1yLmxlbmd0aDtmb3IoZT0wO2U8bjtlKz0xKXQuSG0oaSxyW2VdLCEwKTtyZXR1cm4gaX0sVW06ZnVuY3Rpb24oZSxpLHIsbixzKXtlPWV8fDAsaT1pfHx7fTt2YXIgYSxjLGg9cixwPW47aWYodC54bShyKSYmKGg9aVtyXSksIWgpdGhyb3cgbmV3IFR5cGVFcnJvcihcIm1ldGhvZCB1bmRlZmluZWRcIik7cmV0dXJuIHQuQm0obil8fHQuaXNBcnJheShwKXx8KHA9W25dKSxhPWZ1bmN0aW9uKCl7aC5hcHBseShpLHB8fG8pfSxjPXM/c2V0SW50ZXJ2YWwoYSxlKTpzZXRUaW1lb3V0KGEsZSkse2ludGVydmFsOnMsY2FuY2VsOmZ1bmN0aW9uKCl7dGhpcy5pbnRlcnZhbD9jbGVhckludGVydmFsKGMpOmNsZWFyVGltZW91dChjKX19fSxWbTpmdW5jdGlvbihlKXtyZXR1cm4gdC5vdihlKXx8dC54bShlKXx8dC5ObShlKXx8dC5PbShlKX19O3QuaGFzT3duUHJvcGVydHk9ZS5oYXNPd25Qcm9wZXJ0eT9mdW5jdGlvbih0LGUpe3JldHVybiB0JiZ0Lmhhc093blByb3BlcnR5JiZ0Lmhhc093blByb3BlcnR5KGUpfTpmdW5jdGlvbihlLGkpe3JldHVybiF0LkJtKGVbaV0pJiZlLmNvbnN0cnVjdG9yLnByb3RvdHlwZVtpXSE9PWVbaV19LGMuSG0odCxjLCEwKSxTdC51dGlsLkxhbmc9dCx0LlFtPXQuTG0sU3QuUW09dC5MbSxTdC5leHRlbmQ9dC5leHRlbmR9KCksU3QucmVnaXN0ZXIoXCJ5YWhvb1wiLFN0LHt2ZXJzaW9uOlwiMi45LjBcIixwcDpcIjI4MDBcIn0pOy8qISBDcnlwdG9KUyB2My4xLjIgY29yZS1maXguanNcbiAgICogY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzXG4gICAqIChjKSAyMDA5LTIwMTMgYnkgSmVmZiBNb3R0LiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICAgKiBjb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvd2lraS9MaWNlbnNlXG4gICAqIFRISVMgSVMgRklYIG9mICdjb3JlLmpzJyB0byBmaXggSG1hYyBpc3N1ZS5cbiAgICogaHR0cHM6Ly9jb2RlLmdvb2dsZS5jb20vcC9jcnlwdG8tanMvaXNzdWVzL2RldGFpbD9pZD04NFxuICAgKiBodHRwczovL2NyeXB0by1qcy5nb29nbGVjb2RlLmNvbS9zdm4taGlzdG9yeS9yNjY3L2JyYW5jaGVzLzMueC9zcmMvY29yZS5qc1xuICAgKi9cbiAgdmFyIGJ0PWJ0fHxmdW5jdGlvbih0LGUpe3ZhciBpPXt9LHI9aS5xbT17fSxuPXIuSm09ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7fXJldHVybntleHRlbmQ6ZnVuY3Rpb24oZSl7dC5wcm90b3R5cGU9dGhpczt2YXIgaT1uZXcgdDtyZXR1cm4gZSYmaS5LbShlKSxpLmhhc093blByb3BlcnR5KFwiaW5pdFwiKXx8KGkuaW5pdD1mdW5jdGlvbigpe2kuR20uaW5pdC5hcHBseSh0aGlzLGFyZ3VtZW50cyl9KSxpLmluaXQucHJvdG90eXBlPWksaS5HbT10aGlzLGl9LGNyZWF0ZTpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZXh0ZW5kKCk7cmV0dXJuIHQuaW5pdC5hcHBseSh0LGFyZ3VtZW50cyksdH0saW5pdDpmdW5jdGlvbigpe30sS206ZnVuY3Rpb24odCl7Zm9yKHZhciBlIGluIHQpdC5oYXNPd25Qcm9wZXJ0eShlKSYmKHRoaXNbZV09dFtlXSk7dC5oYXNPd25Qcm9wZXJ0eShcInRvU3RyaW5nXCIpJiYodGhpcy50b1N0cmluZz10LnRvU3RyaW5nKX0sY2xvbmU6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5pbml0LnByb3RvdHlwZS5leHRlbmQodGhpcyl9fX0oKSxvPXIuem09bi5leHRlbmQoe2luaXQ6ZnVuY3Rpb24odCxpKXt0PXRoaXMuV209dHx8W10saSE9ZT90aGlzLiRtPWk6dGhpcy4kbT00KnQubGVuZ3RofSx0b1N0cmluZzpmdW5jdGlvbih0KXtyZXR1cm4odHx8YSkuc3RyaW5naWZ5KHRoaXMpfSxjb25jYXQ6ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5XbSxpPXQuV20scj10aGlzLiRtLG49dC4kbTtpZih0aGlzLmh5KCksciU0KWZvcih2YXIgbz0wO288bjtvKyspe3ZhciBzPWlbbz4+PjJdPj4+MjQtbyU0KjgmMjU1O2VbcitvPj4+Ml18PXM8PDI0LShyK28pJTQqOH1lbHNlIGZvcih2YXIgbz0wO288bjtvKz00KWVbcitvPj4+Ml09aVtvPj4+Ml07cmV0dXJuIHRoaXMuJG0rPW4sdGhpc30saHk6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLldtLGk9dGhpcy4kbTtlW2k+Pj4yXSY9NDI5NDk2NzI5NTw8MzItaSU0KjgsZS5sZW5ndGg9dC5jZWlsKGkvNCl9LGNsb25lOmZ1bmN0aW9uKCl7dmFyIHQ9bi5jbG9uZS5jYWxsKHRoaXMpO3JldHVybiB0LldtPXRoaXMuV20uc2xpY2UoMCksdH0scmFuZG9tOmZ1bmN0aW9uKGUpe2Zvcih2YXIgaT1bXSxyPTA7cjxlO3IrPTQpaS5wdXNoKDQyOTQ5NjcyOTYqdC5yYW5kb20oKXwwKTtyZXR1cm4gbmV3IG8uaW5pdChpLGUpfX0pLHM9aS5ZbT17fSxhPXMuWG09e3N0cmluZ2lmeTpmdW5jdGlvbih0KXtmb3IodmFyIGU9dC5XbSxpPXQuJG0scj1bXSxuPTA7bjxpO24rKyl7dmFyIG89ZVtuPj4+Ml0+Pj4yNC1uJTQqOCYyNTU7ci5wdXNoKChvPj4+NCkudG9TdHJpbmcoMTYpKSxyLnB1c2goKDE1Jm8pLnRvU3RyaW5nKDE2KSl9cmV0dXJuIHIuam9pbihcIlwiKX0scGFyc2U6ZnVuY3Rpb24odCl7Zm9yKHZhciBlPXQubGVuZ3RoLGk9W10scj0wO3I8ZTtyKz0yKWlbcj4+PjNdfD1wYXJzZUludCh0LnN1YnN0cihyLDIpLDE2KTw8MjQtciU4KjQ7cmV0dXJuIG5ldyBvLmluaXQoaSxlLzIpfX0sYz1zLlptPXtzdHJpbmdpZnk6ZnVuY3Rpb24odCl7Zm9yKHZhciBlPXQuV20saT10LiRtLHI9W10sbj0wO248aTtuKyspe3ZhciBvPWVbbj4+PjJdPj4+MjQtbiU0KjgmMjU1O3IucHVzaChTdHJpbmcuZnJvbUNoYXJDb2RlKG8pKX1yZXR1cm4gci5qb2luKFwiXCIpfSxwYXJzZTpmdW5jdGlvbih0KXtmb3IodmFyIGU9dC5sZW5ndGgsaT1bXSxyPTA7cjxlO3IrKylpW3I+Pj4yXXw9KDI1NSZ0LmNoYXJDb2RlQXQocikpPDwyNC1yJTQqODtyZXR1cm4gbmV3IG8uaW5pdChpLGUpfX0saD1zLnR3PXtzdHJpbmdpZnk6ZnVuY3Rpb24odCl7dHJ5e3JldHVybiBkZWNvZGVVUklDb21wb25lbnQoZXNjYXBlKGMuc3RyaW5naWZ5KHQpKSl9Y2F0Y2goZSl7dGhyb3cgbmV3IEVycm9yKFwiTWFsZm9ybWVkIFVURi04IGRhdGFcIil9fSxwYXJzZTpmdW5jdGlvbih0KXtyZXR1cm4gYy5wYXJzZSh1bmVzY2FwZShlbmNvZGVVUklDb21wb25lbnQodCkpKX19LHA9ci5ldz1uLmV4dGVuZCh7cmVzZXQ6ZnVuY3Rpb24oKXt0aGlzLml3PW5ldyBvLmluaXQsdGhpcy5ydz0wfSxudzpmdW5jdGlvbih0KXtcInN0cmluZ1wiPT10eXBlb2YgdCYmKHQ9aC5wYXJzZSh0KSksdGhpcy5pdy5jb25jYXQodCksdGhpcy5ydys9dC4kbX0sb3c6ZnVuY3Rpb24oZSl7dmFyIGk9dGhpcy5pdyxyPWkuV20sbj1pLiRtLHM9dGhpcy5zdyxhPTQqcyxjPW4vYTtjPWU/dC5jZWlsKGMpOnQubWF4KCgwfGMpLXRoaXMuYXcsMCk7dmFyIGg9YypzLHA9dC5taW4oNCpoLG4pO2lmKGgpe2Zvcih2YXIgdT0wO3U8aDt1Kz1zKXRoaXMuY3cocix1KTt2YXIgbD1yLnNwbGljZSgwLGgpO2kuJG0tPXB9cmV0dXJuIG5ldyBvLmluaXQobCxwKX0sY2xvbmU6ZnVuY3Rpb24oKXt2YXIgdD1uLmNsb25lLmNhbGwodGhpcyk7cmV0dXJuIHQuaXc9dGhpcy5pdy5jbG9uZSgpLHR9LGF3OjB9KSx1PShyLmh3PXAuZXh0ZW5kKHtwdzpuLmV4dGVuZCgpLGluaXQ6ZnVuY3Rpb24odCl7dGhpcy5wdz10aGlzLnB3LmV4dGVuZCh0KSx0aGlzLnJlc2V0KCl9LHJlc2V0OmZ1bmN0aW9uKCl7cC5yZXNldC5jYWxsKHRoaXMpLHRoaXMudXcoKX0sdXBkYXRlOmZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLm53KHQpLHRoaXMub3coKSx0aGlzfSxsdzpmdW5jdGlvbih0KXt0JiZ0aGlzLm53KHQpO3ZhciBlPXRoaXMuZHcoKTtyZXR1cm4gZX0sc3c6MTYsZnc6ZnVuY3Rpb24odCl7cmV0dXJuIGZ1bmN0aW9uKGUsaSl7cmV0dXJuIG5ldyB0LmluaXQoaSkubHcoZSl9fSxndzpmdW5jdGlvbih0KXtyZXR1cm4gZnVuY3Rpb24oZSxpKXtyZXR1cm4gbmV3IHUuSE1BQy5pbml0KHQsaSkubHcoZSl9fX0pLGkudnc9e30pO3JldHVybiBpfShNYXRoKTshZnVuY3Rpb24odCl7ZnVuY3Rpb24gZSh0LGUsaSxyLG4sbyxzKXtyZXR1cm4gdD10KyhlJml8fmUmcikrbitzLCh0PDxvfHQ+Pj4zMi1vKStlfWZ1bmN0aW9uIGkodCxlLGkscixuLG8scyl7cmV0dXJuIHQ9dCsoZSZyfGkmfnIpK24rcywodDw8b3x0Pj4+MzItbykrZX1mdW5jdGlvbiByKHQsZSxpLHIsbixvLHMpe3JldHVybiB0PXQrKGVeaV5yKStuK3MsKHQ8PG98dD4+PjMyLW8pK2V9ZnVuY3Rpb24gbih0LGUsaSxyLG4sbyxzKXtyZXR1cm4gdD10KyhpXihlfH5yKSkrbitzLCh0PDxvfHQ+Pj4zMi1vKStlfWZvcih2YXIgbz1idCxzPW8ucW0sYT1zLnptLGM9cy5odyxzPW8udncsaD1bXSxwPTA7NjQ+cDtwKyspaFtwXT00Mjk0OTY3Mjk2KnQuYWJzKHQuc2luKHArMSkpfDA7cz1zLnl3PWMuZXh0ZW5kKHt1dzpmdW5jdGlvbigpe3RoaXMubXc9bmV3IGEuaW5pdChbMTczMjU4NDE5Myw0MDIzMjMzNDE3LDI1NjIzODMxMDIsMjcxNzMzODc4XSl9LGN3OmZ1bmN0aW9uKHQsbyl7Zm9yKHZhciBzPTA7MTY+cztzKyspe3ZhciBhPW8rcyxjPXRbYV07dFthXT0xNjcxMTkzNSYoYzw8OHxjPj4+MjQpfDQyNzgyNTUzNjAmKGM8PDI0fGM+Pj44KX12YXIgcz10aGlzLm13LldtLGE9dFtvKzBdLGM9dFtvKzFdLHA9dFtvKzJdLHU9dFtvKzNdLGw9dFtvKzRdLGQ9dFtvKzVdLGY9dFtvKzZdLGc9dFtvKzddLHY9dFtvKzhdLHk9dFtvKzldLG09dFtvKzEwXSx3PXRbbysxMV0sVD10W28rMTJdLFM9dFtvKzEzXSxiPXRbbysxNF0sRT10W28rMTVdLEk9c1swXSxSPXNbMV0saz1zWzJdLEM9c1szXSxJPWUoSSxSLGssQyxhLDcsaFswXSksQz1lKEMsSSxSLGssYywxMixoWzFdKSxrPWUoayxDLEksUixwLDE3LGhbMl0pLFI9ZShSLGssQyxJLHUsMjIsaFszXSksST1lKEksUixrLEMsbCw3LGhbNF0pLEM9ZShDLEksUixrLGQsMTIsaFs1XSksaz1lKGssQyxJLFIsZiwxNyxoWzZdKSxSPWUoUixrLEMsSSxnLDIyLGhbN10pLEk9ZShJLFIsayxDLHYsNyxoWzhdKSxDPWUoQyxJLFIsayx5LDEyLGhbOV0pLGs9ZShrLEMsSSxSLG0sMTcsaFsxMF0pLFI9ZShSLGssQyxJLHcsMjIsaFsxMV0pLEk9ZShJLFIsayxDLFQsNyxoWzEyXSksQz1lKEMsSSxSLGssUywxMixoWzEzXSksaz1lKGssQyxJLFIsYiwxNyxoWzE0XSksUj1lKFIsayxDLEksRSwyMixoWzE1XSksST1pKEksUixrLEMsYyw1LGhbMTZdKSxDPWkoQyxJLFIsayxmLDksaFsxN10pLGs9aShrLEMsSSxSLHcsMTQsaFsxOF0pLFI9aShSLGssQyxJLGEsMjAsaFsxOV0pLEk9aShJLFIsayxDLGQsNSxoWzIwXSksQz1pKEMsSSxSLGssbSw5LGhbMjFdKSxrPWkoayxDLEksUixFLDE0LGhbMjJdKSxSPWkoUixrLEMsSSxsLDIwLGhbMjNdKSxJPWkoSSxSLGssQyx5LDUsaFsyNF0pLEM9aShDLEksUixrLGIsOSxoWzI1XSksaz1pKGssQyxJLFIsdSwxNCxoWzI2XSksUj1pKFIsayxDLEksdiwyMCxoWzI3XSksST1pKEksUixrLEMsUyw1LGhbMjhdKSxDPWkoQyxJLFIsayxwLDksaFsyOV0pLGs9aShrLEMsSSxSLGcsMTQsaFszMF0pLFI9aShSLGssQyxJLFQsMjAsaFszMV0pLEk9cihJLFIsayxDLGQsNCxoWzMyXSksQz1yKEMsSSxSLGssdiwxMSxoWzMzXSksaz1yKGssQyxJLFIsdywxNixoWzM0XSksUj1yKFIsayxDLEksYiwyMyxoWzM1XSksST1yKEksUixrLEMsYyw0LGhbMzZdKSxDPXIoQyxJLFIsayxsLDExLGhbMzddKSxrPXIoayxDLEksUixnLDE2LGhbMzhdKSxSPXIoUixrLEMsSSxtLDIzLGhbMzldKSxJPXIoSSxSLGssQyxTLDQsaFs0MF0pLEM9cihDLEksUixrLGEsMTEsaFs0MV0pLGs9cihrLEMsSSxSLHUsMTYsaFs0Ml0pLFI9cihSLGssQyxJLGYsMjMsaFs0M10pLEk9cihJLFIsayxDLHksNCxoWzQ0XSksQz1yKEMsSSxSLGssVCwxMSxoWzQ1XSksaz1yKGssQyxJLFIsRSwxNixoWzQ2XSksUj1yKFIsayxDLEkscCwyMyxoWzQ3XSksST1uKEksUixrLEMsYSw2LGhbNDhdKSxDPW4oQyxJLFIsayxnLDEwLGhbNDldKSxrPW4oayxDLEksUixiLDE1LGhbNTBdKSxSPW4oUixrLEMsSSxkLDIxLGhbNTFdKSxJPW4oSSxSLGssQyxULDYsaFs1Ml0pLEM9bihDLEksUixrLHUsMTAsaFs1M10pLGs9bihrLEMsSSxSLG0sMTUsaFs1NF0pLFI9bihSLGssQyxJLGMsMjEsaFs1NV0pLEk9bihJLFIsayxDLHYsNixoWzU2XSksQz1uKEMsSSxSLGssRSwxMCxoWzU3XSksaz1uKGssQyxJLFIsZiwxNSxoWzU4XSksUj1uKFIsayxDLEksUywyMSxoWzU5XSksST1uKEksUixrLEMsbCw2LGhbNjBdKSxDPW4oQyxJLFIsayx3LDEwLGhbNjFdKSxrPW4oayxDLEksUixwLDE1LGhbNjJdKSxSPW4oUixrLEMsSSx5LDIxLGhbNjNdKTtzWzBdPXNbMF0rSXwwLHNbMV09c1sxXStSfDAsc1syXT1zWzJdK2t8MCxzWzNdPXNbM10rQ3wwfSxkdzpmdW5jdGlvbigpe3ZhciBlPXRoaXMuaXcsaT1lLldtLHI9OCp0aGlzLnJ3LG49OCplLiRtO2lbbj4+PjVdfD0xMjg8PDI0LW4lMzI7dmFyIG89dC5mbG9vcihyLzQyOTQ5NjcyOTYpO2ZvcihpWyhuKzY0Pj4+OTw8NCkrMTVdPTE2NzExOTM1JihvPDw4fG8+Pj4yNCl8NDI3ODI1NTM2MCYobzw8MjR8bz4+PjgpLGlbKG4rNjQ+Pj45PDw0KSsxNF09MTY3MTE5MzUmKHI8PDh8cj4+PjI0KXw0Mjc4MjU1MzYwJihyPDwyNHxyPj4+OCksZS4kbT00KihpLmxlbmd0aCsxKSx0aGlzLm93KCksZT10aGlzLm13LGk9ZS5XbSxyPTA7ND5yO3IrKyluPWlbcl0saVtyXT0xNjcxMTkzNSYobjw8OHxuPj4+MjQpfDQyNzgyNTUzNjAmKG48PDI0fG4+Pj44KTtyZXR1cm4gZX0sY2xvbmU6ZnVuY3Rpb24oKXt2YXIgdD1jLmNsb25lLmNhbGwodGhpcyk7cmV0dXJuIHQubXc9dGhpcy5tdy5jbG9uZSgpLHR9fSksby55dz1jLmZ3KHMpLG8ud3c9Yy5ndyhzKX0oTWF0aCksZnVuY3Rpb24oKXt2YXIgdD1idCxlPXQucW0saT1lLnptLHI9ZS5odyxuPVtdLGU9dC52dy5Udz1yLmV4dGVuZCh7dXc6ZnVuY3Rpb24oKXt0aGlzLm13PW5ldyBpLmluaXQoWzE3MzI1ODQxOTMsNDAyMzIzMzQxNywyNTYyMzgzMTAyLDI3MTczMzg3OCwzMjg1Mzc3NTIwXSl9LGN3OmZ1bmN0aW9uKHQsZSl7Zm9yKHZhciBpPXRoaXMubXcuV20scj1pWzBdLG89aVsxXSxzPWlbMl0sYT1pWzNdLGM9aVs0XSxoPTA7ODA+aDtoKyspe2lmKDE2PmgpbltoXT0wfHRbZStoXTtlbHNle3ZhciBwPW5baC0zXV5uW2gtOF1ebltoLTE0XV5uW2gtMTZdO25baF09cDw8MXxwPj4+MzF9cD0ocjw8NXxyPj4+MjcpK2MrbltoXSxwPTIwPmg/cCsoKG8mc3x+byZhKSsxNTE4NTAwMjQ5KTo0MD5oP3ArKChvXnNeYSkrMTg1OTc3NTM5Myk6NjA+aD9wKygobyZzfG8mYXxzJmEpLTE4OTQwMDc1ODgpOnArKChvXnNeYSktODk5NDk3NTE0KSxjPWEsYT1zLHM9bzw8MzB8bz4+PjIsbz1yLHI9cH1pWzBdPWlbMF0rcnwwLGlbMV09aVsxXStvfDAsaVsyXT1pWzJdK3N8MCxpWzNdPWlbM10rYXwwLGlbNF09aVs0XStjfDB9LGR3OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5pdyxlPXQuV20saT04KnRoaXMucncscj04KnQuJG07cmV0dXJuIGVbcj4+PjVdfD0xMjg8PDI0LXIlMzIsZVsocis2ND4+Pjk8PDQpKzE0XT1NYXRoLmZsb29yKGkvNDI5NDk2NzI5NiksZVsocis2ND4+Pjk8PDQpKzE1XT1pLHQuJG09NCplLmxlbmd0aCx0aGlzLm93KCksdGhpcy5td30sY2xvbmU6ZnVuY3Rpb24oKXt2YXIgdD1yLmNsb25lLmNhbGwodGhpcyk7cmV0dXJuIHQubXc9dGhpcy5tdy5jbG9uZSgpLHR9fSk7dC5Udz1yLmZ3KGUpLHQuU3c9ci5ndyhlKX0oKTsvKiEgKGMpIFRvbSBXdSB8IGh0dHA6Ly93d3ctY3Mtc3R1ZGVudHMuc3RhbmZvcmQuZWR1L350ancvanNibi8gKi9cbiAgdmFyIEV0LEl0PTB4ZGVhZGJlZWZjYWZlLFJ0PTE1NzE1MDcwPT0oMTY3NzcyMTUmSXQpO1J0JiZcIk1pY3Jvc29mdCBJbnRlcm5ldCBFeHBsb3JlclwiPT13dC5hcHBOYW1lPyhpLnByb3RvdHlwZS5neT1vLEV0PTMwKTpSdCYmXCJOZXRzY2FwZVwiIT13dC5hcHBOYW1lPyhpLnByb3RvdHlwZS5neT1uLEV0PTI2KTooaS5wcm90b3R5cGUuZ3k9cyxFdD0yOCksaS5wcm90b3R5cGUuYXk9RXQsaS5wcm90b3R5cGUudXk9KDE8PEV0KS0xLGkucHJvdG90eXBlLm95PTE8PEV0O3ZhciBrdD01MjtpLnByb3RvdHlwZS5UeT1NYXRoLnBvdygyLGt0KSxpLnByb3RvdHlwZS5teT1rdC1FdCxpLnByb3RvdHlwZS53eT0yKkV0LWt0O3ZhciBDdCxPdCxQdD1cIjAxMjM0NTY3ODlhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5elwiLEF0PW5ldyBBcnJheTtmb3IoQ3Q9XCIwXCIuY2hhckNvZGVBdCgwKSxPdD0wO090PD05OysrT3QpQXRbQ3QrK109T3Q7Zm9yKEN0PVwiYVwiLmNoYXJDb2RlQXQoMCksT3Q9MTA7T3Q8MzY7KytPdClBdFtDdCsrXT1PdDtmb3IoQ3Q9XCJBXCIuY2hhckNvZGVBdCgwKSxPdD0xMDtPdDwzNjsrK090KUF0W0N0KytdPU90O1AucHJvdG90eXBlLl95PUEsUC5wcm90b3R5cGUuTHk9TixQLnByb3RvdHlwZS5yZWR1Y2U9eCxQLnByb3RvdHlwZS5IeT1CLFAucHJvdG90eXBlLkR5PUYsRC5wcm90b3R5cGUuX3k9SCxELnByb3RvdHlwZS5MeT1MLEQucHJvdG90eXBlLnJlZHVjZT1NLEQucHJvdG90eXBlLkh5PVUsRC5wcm90b3R5cGUuRHk9aixpLnByb3RvdHlwZS52eT1oLGkucHJvdG90eXBlLnN5PXAsaS5wcm90b3R5cGUuZXk9bCxpLnByb3RvdHlwZS5oeT1kLGkucHJvdG90eXBlLlN5PVQsaS5wcm90b3R5cGUuRXk9UyxpLnByb3RvdHlwZS55eT1iLGkucHJvdG90eXBlLkl5PUUsaS5wcm90b3R5cGUucHk9SSxpLnByb3RvdHlwZS5DeT1SLGkucHJvdG90eXBlLk95PWssaS5wcm90b3R5cGUuUnk9QyxpLnByb3RvdHlwZS5BeT1fLGkucHJvdG90eXBlLk15PVYsaS5wcm90b3R5cGUuZXhwPVEsaS5wcm90b3R5cGUudG9TdHJpbmc9ZixpLnByb3RvdHlwZS5seT1nLGkucHJvdG90eXBlLmFicz12LGkucHJvdG90eXBlLmJ5PXksaS5wcm90b3R5cGUuS3k9dyxpLnByb3RvdHlwZS5reT1PLGkucHJvdG90eXBlLkp5PXEsaS5aRVJPPXUoMCksaS5PTkU9dSgxKSwvKiEgYXNuMS0xLjAuOS5qcyAoYykgMjAxMy0yMDE1IEtlbmppIFVydXNoaW1hIHwga2p1ci5naXRodWIuY29tL2pzcnNhc2lnbi9saWNlbnNlXG4gICAqL1xuICBcInVuZGVmaW5lZFwiIT10eXBlb2YgS0pVUiYmS0pVUnx8KEtKVVI9e30pLFwidW5kZWZpbmVkXCIhPXR5cGVvZiBLSlVSLmJ3JiZLSlVSLmJ3fHwoS0pVUi5idz17fSksS0pVUi5idy5Fdz1uZXcgZnVuY3Rpb24oKXt0aGlzLkl3PWZ1bmN0aW9uKHQpe3ZhciBlPXQudG9TdHJpbmcoMTYpO3JldHVybiBlLmxlbmd0aCUyPT0xJiYoZT1cIjBcIitlKSxlfSx0aGlzLlJ3PWZ1bmN0aW9uKHQpe3ZhciBlPXQudG9TdHJpbmcoMTYpO2lmKFwiLVwiIT1lLnN1YnN0cigwLDEpKWUubGVuZ3RoJTI9PTE/ZT1cIjBcIitlOmUubWF0Y2goL15bMC03XS8pfHwoZT1cIjAwXCIrZSk7ZWxzZXt2YXIgcj1lLnN1YnN0cigxKSxuPXIubGVuZ3RoO24lMj09MT9uKz0xOmUubWF0Y2goL15bMC03XS8pfHwobis9Mik7Zm9yKHZhciBvPVwiXCIscz0wO3M8bjtzKyspbys9XCJmXCI7dmFyIGE9bmV3IGkobywxNiksYz1hLnhvcih0KS5hZGQoaS5PTkUpO2U9Yy50b1N0cmluZygxNikucmVwbGFjZSgvXi0vLFwiXCIpfXJldHVybiBlfSx0aGlzLmt3PWZ1bmN0aW9uKHQsZSl7dmFyIGk9KEtKVVIuYncsYnQuWW0uWG0ucGFyc2UodCkpLHI9YnQuWW0uQmFzZTY0LnN0cmluZ2lmeShpKSxuPXIucmVwbGFjZSgvKC57NjR9KS9nLFwiJDFcXHJcXG5cIik7cmV0dXJuIG49bi5yZXBsYWNlKC9cXHJcXG4kLyxcIlwiKSxcIi0tLS0tQkVHSU4gXCIrZStcIi0tLS0tXFxyXFxuXCIrbitcIlxcclxcbi0tLS0tRU5EIFwiK2UrXCItLS0tLVxcclxcblwifSx0aGlzLkN3PWZ1bmN0aW9uKHQpe3ZhciBlPUtKVVIuYncsaT1PYmplY3Qua2V5cyh0KTtpZigxIT1pLmxlbmd0aCl0aHJvd1wia2V5IG9mIHBhcmFtIHNoYWxsIGJlIG9ubHkgb25lLlwiO3ZhciByPWlbMF07aWYoXCI6Ym9vbDppbnQ6Yml0c3RyOm9jdHN0cjpudWxsOm9pZDplbnVtOnV0ZjhzdHI6bnVtc3RyOnBybnN0cjp0ZWxzdHI6aWE1c3RyOnV0Y3RpbWU6Z2VudGltZTpzZXE6c2V0OnRhZzpcIi5pbmRleE9mKFwiOlwiK3IrXCI6XCIpPT0tMSl0aHJvd1widW5kZWZpbmVkIGtleTogXCIrcjtpZihcImJvb2xcIj09cilyZXR1cm4gbmV3IGUuT3codFtyXSk7aWYoXCJpbnRcIj09cilyZXR1cm4gbmV3IGUuUHcodFtyXSk7aWYoXCJiaXRzdHJcIj09cilyZXR1cm4gbmV3IGUuQXcodFtyXSk7aWYoXCJvY3RzdHJcIj09cilyZXR1cm4gbmV3IGUuTncodFtyXSk7aWYoXCJudWxsXCI9PXIpcmV0dXJuIG5ldyBlLnh3KHRbcl0pO2lmKFwib2lkXCI9PXIpcmV0dXJuIG5ldyBlLkJ3KHRbcl0pO2lmKFwiZW51bVwiPT1yKXJldHVybiBuZXcgZS5Gdyh0W3JdKTtpZihcInV0ZjhzdHJcIj09cilyZXR1cm4gbmV3IGUuX3codFtyXSk7aWYoXCJudW1zdHJcIj09cilyZXR1cm4gbmV3IGUuRHcodFtyXSk7aWYoXCJwcm5zdHJcIj09cilyZXR1cm4gbmV3IGUuSHcodFtyXSk7aWYoXCJ0ZWxzdHJcIj09cilyZXR1cm4gbmV3IGUuTHcodFtyXSk7aWYoXCJpYTVzdHJcIj09cilyZXR1cm4gbmV3IGUuTXcodFtyXSk7aWYoXCJ1dGN0aW1lXCI9PXIpcmV0dXJuIG5ldyBlLmp3KHRbcl0pO2lmKFwiZ2VudGltZVwiPT1yKXJldHVybiBuZXcgZS5Vdyh0W3JdKTtpZihcInNlcVwiPT1yKXtmb3IodmFyIG49dFtyXSxvPVtdLHM9MDtzPG4ubGVuZ3RoO3MrKyl7dmFyIGE9ZS5Fdy5DdyhuW3NdKTtvLnB1c2goYSl9cmV0dXJuIG5ldyBlLlZ3KHtIZjpvfSl9aWYoXCJzZXRcIj09cil7Zm9yKHZhciBuPXRbcl0sbz1bXSxzPTA7czxuLmxlbmd0aDtzKyspe3ZhciBhPWUuRXcuQ3cobltzXSk7by5wdXNoKGEpfXJldHVybiBuZXcgZS5Rdyh7SGY6b30pfWlmKFwidGFnXCI9PXIpe3ZhciBjPXRbcl07aWYoXCJbb2JqZWN0IEFycmF5XVwiPT09T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGMpJiYzPT1jLmxlbmd0aCl7dmFyIGg9ZS5Fdy5DdyhjWzJdKTtyZXR1cm4gbmV3IGUucXcoe3RhZzpjWzBdLEp3OmNbMV0sS3c6aH0pfXZhciBwPXt9O2lmKHZvaWQgMCE9PWMuSncmJihwLkp3PWMuSncpLHZvaWQgMCE9PWMudGFnJiYocC50YWc9Yy50YWcpLHZvaWQgMD09PWMuS3cpdGhyb3dcIm9iaiBzaGFsbCBiZSBzcGVjaWZpZWQgZm9yICd0YWcnLlwiO3JldHVybiBwLkt3PWUuRXcuQ3coYy5LdyksbmV3IGUucXcocCl9fSx0aGlzLkd3PWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuQ3codCk7cmV0dXJuIGUuencoKX19LEtKVVIuYncuRXcuV3c9ZnVuY3Rpb24odCl7Zm9yKHZhciBlPVwiXCIscj1wYXJzZUludCh0LnN1YnN0cigwLDIpLDE2KSxuPU1hdGguZmxvb3Ioci80MCksbz1yJTQwLGU9bitcIi5cIitvLHM9XCJcIixhPTI7YTx0Lmxlbmd0aDthKz0yKXt2YXIgYz1wYXJzZUludCh0LnN1YnN0cihhLDIpLDE2KSxoPShcIjAwMDAwMDAwXCIrYy50b1N0cmluZygyKSkuc2xpY2UoLTgpO2lmKHMrPWguc3Vic3RyKDEsNyksXCIwXCI9PWguc3Vic3RyKDAsMSkpe3ZhciBwPW5ldyBpKHMsMik7ZT1lK1wiLlwiK3AudG9TdHJpbmcoMTApLHM9XCJcIn19cmV0dXJuIGV9LEtKVVIuYncuRXcuJHc9ZnVuY3Rpb24odCl7dmFyIGU9ZnVuY3Rpb24odCl7dmFyIGU9dC50b1N0cmluZygxNik7cmV0dXJuIDE9PWUubGVuZ3RoJiYoZT1cIjBcIitlKSxlfSxyPWZ1bmN0aW9uKHQpe3ZhciByPVwiXCIsbj1uZXcgaSh0LDEwKSxvPW4udG9TdHJpbmcoMikscz03LW8ubGVuZ3RoJTc7Nz09cyYmKHM9MCk7Zm9yKHZhciBhPVwiXCIsYz0wO2M8cztjKyspYSs9XCIwXCI7bz1hK287Zm9yKHZhciBjPTA7YzxvLmxlbmd0aC0xO2MrPTcpe3ZhciBoPW8uc3Vic3RyKGMsNyk7YyE9by5sZW5ndGgtNyYmKGg9XCIxXCIraCkscis9ZShwYXJzZUludChoLDIpKX1yZXR1cm4gcn07aWYoIXQubWF0Y2goL15bMC05Ll0rJC8pKXRocm93XCJtYWxmb3JtZWQgb2lkIHN0cmluZzogXCIrdDt2YXIgbj1cIlwiLG89dC5zcGxpdChcIi5cIikscz00MCpwYXJzZUludChvWzBdKStwYXJzZUludChvWzFdKTtuKz1lKHMpLG8uc3BsaWNlKDAsMik7Zm9yKHZhciBhPTA7YTxvLmxlbmd0aDthKyspbis9cihvW2FdKTtyZXR1cm4gbn0sS0pVUi5idy5Zdz1mdW5jdGlvbigpe3ZhciB0PVwiXCI7dGhpcy5Ydz1mdW5jdGlvbigpe2lmKFwidW5kZWZpbmVkXCI9PXR5cGVvZiB0aGlzLlp3fHxudWxsPT10aGlzLlp3KXRocm93XCJ0aGlzLmhWIGlzIG51bGwgb3IgdW5kZWZpbmVkLlwiO2lmKHRoaXMuWncubGVuZ3RoJTI9PTEpdGhyb3dcInZhbHVlIGhleCBtdXN0IGJlIGV2ZW4gbGVuZ3RoOiBuPVwiK3QubGVuZ3RoK1wiLHY9XCIrdGhpcy5adzt2YXIgZT10aGlzLlp3Lmxlbmd0aC8yLGk9ZS50b1N0cmluZygxNik7aWYoaS5sZW5ndGglMj09MSYmKGk9XCIwXCIraSksZTwxMjgpcmV0dXJuIGk7dmFyIHI9aS5sZW5ndGgvMjtpZihyPjE1KXRocm93XCJBU04uMSBsZW5ndGggdG9vIGxvbmcgdG8gcmVwcmVzZW50IGJ5IDh4OiBuID0gXCIrZS50b1N0cmluZygxNik7dmFyIG49MTI4K3I7cmV0dXJuIG4udG9TdHJpbmcoMTYpK2l9LHRoaXMuenc9ZnVuY3Rpb24oKXtyZXR1cm4obnVsbD09dGhpcy50VHx8dGhpcy5lVCkmJih0aGlzLlp3PXRoaXMuaVQoKSx0aGlzLnJUPXRoaXMuWHcoKSx0aGlzLnRUPXRoaXMublQrdGhpcy5yVCt0aGlzLlp3LHRoaXMuZVQ9ITEpLHRoaXMudFR9LHRoaXMub1Q9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy56dygpLHRoaXMuWnd9LHRoaXMuaVQ9ZnVuY3Rpb24oKXtyZXR1cm5cIlwifX0sS0pVUi5idy5zVD1mdW5jdGlvbih0KXtLSlVSLmJ3LnNULkRtLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7dGhpcy5hVD1mdW5jdGlvbigpe3JldHVybiB0aGlzLm55fSx0aGlzLmNUPWZ1bmN0aW9uKHQpe3RoaXMudFQ9bnVsbCx0aGlzLmVUPSEwLHRoaXMubnk9dCx0aGlzLlp3PXN0b2hleCh0aGlzLm55KX0sdGhpcy5oVD1mdW5jdGlvbih0KXt0aGlzLnRUPW51bGwsdGhpcy5lVD0hMCx0aGlzLm55PW51bGwsdGhpcy5adz10fSx0aGlzLmlUPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuWnd9LFwidW5kZWZpbmVkXCIhPXR5cGVvZiB0JiYoXCJzdHJpbmdcIj09dHlwZW9mIHQ/dGhpcy5jVCh0KTpcInVuZGVmaW5lZFwiIT10eXBlb2YgdC5hYz90aGlzLmNUKHQuYWMpOlwidW5kZWZpbmVkXCIhPXR5cGVvZiB0LnBUJiZ0aGlzLmhUKHQucFQpKX0sU3QubGFuZy5leHRlbmQoS0pVUi5idy5zVCxLSlVSLmJ3Lll3KSxLSlVSLmJ3LnVUPWZ1bmN0aW9uKHQpe0tKVVIuYncudVQuRG0uY29uc3RydWN0b3IuY2FsbCh0aGlzKTt0aGlzLmxUPWZ1bmN0aW9uKHQpe3V0Yz10LmdldFRpbWUoKSs2ZTQqdC5nZXRUaW1lem9uZU9mZnNldCgpO3ZhciBlPW5ldyBEYXRlKHV0Yyk7cmV0dXJuIGV9LHRoaXMuZFQ9ZnVuY3Rpb24odCxlLGkpe3ZhciByPXRoaXMuZlQsbj10aGlzLmxUKHQpLG89U3RyaW5nKG4uZ2V0RnVsbFllYXIoKSk7XCJ1dGNcIj09ZSYmKG89by5zdWJzdHIoMiwyKSk7dmFyIHM9cihTdHJpbmcobi5nZXRNb250aCgpKzEpLDIpLGE9cihTdHJpbmcobi5nZXREYXRlKCkpLDIpLGM9cihTdHJpbmcobi5nZXRIb3VycygpKSwyKSxoPXIoU3RyaW5nKG4uZ2V0TWludXRlcygpKSwyKSxwPXIoU3RyaW5nKG4uZ2V0U2Vjb25kcygpKSwyKSx1PW8rcythK2MraCtwO2lmKGk9PT0hMCl7dmFyIGw9bi5nZXRNaWxsaXNlY29uZHMoKTtpZigwIT1sKXt2YXIgZD1yKFN0cmluZyhsKSwzKTtkPWQucmVwbGFjZSgvWzBdKyQvLFwiXCIpLHU9dStcIi5cIitkfX1yZXR1cm4gdStcIlpcIn0sdGhpcy5mVD1mdW5jdGlvbih0LGUpe3JldHVybiB0Lmxlbmd0aD49ZT90Om5ldyBBcnJheShlLXQubGVuZ3RoKzEpLmpvaW4oXCIwXCIpK3R9LHRoaXMuYVQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ueX0sdGhpcy5jVD1mdW5jdGlvbih0KXt0aGlzLnRUPW51bGwsdGhpcy5lVD0hMCx0aGlzLm55PXQsdGhpcy5adz1zdG9oZXgodCl9LHRoaXMuZ1Q9ZnVuY3Rpb24odCxlLGkscixuLG8pe3ZhciBzPW5ldyBEYXRlKERhdGUuVVRDKHQsZS0xLGkscixuLG8sMCkpO3RoaXMudlQocyl9LHRoaXMuaVQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ad319LFN0LmxhbmcuZXh0ZW5kKEtKVVIuYncudVQsS0pVUi5idy5ZdyksS0pVUi5idy55VD1mdW5jdGlvbih0KXtLSlVSLmJ3LnNULkRtLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7dGhpcy5tVD1mdW5jdGlvbih0KXt0aGlzLnRUPW51bGwsdGhpcy5lVD0hMCx0aGlzLndUPXR9LHRoaXMuVFQ9ZnVuY3Rpb24odCl7dGhpcy50VD1udWxsLHRoaXMuZVQ9ITAsdGhpcy53VC5wdXNoKHQpfSx0aGlzLndUPW5ldyBBcnJheSxcInVuZGVmaW5lZFwiIT10eXBlb2YgdCYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQuSGYmJih0aGlzLndUPXQuSGYpfSxTdC5sYW5nLmV4dGVuZChLSlVSLmJ3LnlULEtKVVIuYncuWXcpLEtKVVIuYncuT3c9ZnVuY3Rpb24oKXtLSlVSLmJ3Lk93LkRtLmNvbnN0cnVjdG9yLmNhbGwodGhpcyksdGhpcy5uVD1cIjAxXCIsdGhpcy50VD1cIjAxMDFmZlwifSxTdC5sYW5nLmV4dGVuZChLSlVSLmJ3Lk93LEtKVVIuYncuWXcpLEtKVVIuYncuUHc9ZnVuY3Rpb24odCl7S0pVUi5idy5Qdy5EbS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpLHRoaXMublQ9XCIwMlwiLHRoaXMuU1Q9ZnVuY3Rpb24odCl7dGhpcy50VD1udWxsLHRoaXMuZVQ9ITAsdGhpcy5adz1LSlVSLmJ3LkV3LlJ3KHQpfSx0aGlzLmJUPWZ1bmN0aW9uKHQpe3ZhciBlPW5ldyBpKFN0cmluZyh0KSwxMCk7dGhpcy5TVChlKX0sdGhpcy5FVD1mdW5jdGlvbih0KXt0aGlzLlp3PXR9LHRoaXMuaVQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ad30sXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQmJihcInVuZGVmaW5lZFwiIT10eXBlb2YgdC5iaWdpbnQ/dGhpcy5TVCh0LmJpZ2ludCk6XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHRbXCJpbnRcIl0/dGhpcy5iVCh0W1wiaW50XCJdKTpcIm51bWJlclwiPT10eXBlb2YgdD90aGlzLmJUKHQpOlwidW5kZWZpbmVkXCIhPXR5cGVvZiB0LnBUJiZ0aGlzLkVUKHQucFQpKX0sU3QubGFuZy5leHRlbmQoS0pVUi5idy5QdyxLSlVSLmJ3Lll3KSxLSlVSLmJ3LkF3PWZ1bmN0aW9uKHQpe0tKVVIuYncuQXcuRG0uY29uc3RydWN0b3IuY2FsbCh0aGlzKSx0aGlzLm5UPVwiMDNcIix0aGlzLklUPWZ1bmN0aW9uKHQpe3RoaXMudFQ9bnVsbCx0aGlzLmVUPSEwLHRoaXMuWnc9dH0sdGhpcy5SVD1mdW5jdGlvbih0LGUpe2lmKHQ8MHx8Nzx0KXRocm93XCJ1bnVzZWQgYml0cyBzaGFsbCBiZSBmcm9tIDAgdG8gNzogdSA9IFwiK3Q7dmFyIGk9XCIwXCIrdDt0aGlzLnRUPW51bGwsdGhpcy5lVD0hMCx0aGlzLlp3PWkrZX0sdGhpcy5rVD1mdW5jdGlvbih0KXt0PXQucmVwbGFjZSgvMCskLyxcIlwiKTt2YXIgZT04LXQubGVuZ3RoJTg7OD09ZSYmKGU9MCk7Zm9yKHZhciBpPTA7aTw9ZTtpKyspdCs9XCIwXCI7Zm9yKHZhciByPVwiXCIsaT0wO2k8dC5sZW5ndGgtMTtpKz04KXt2YXIgbj10LnN1YnN0cihpLDgpLG89cGFyc2VJbnQobiwyKS50b1N0cmluZygxNik7MT09by5sZW5ndGgmJihvPVwiMFwiK28pLHIrPW99dGhpcy50VD1udWxsLHRoaXMuZVQ9ITAsdGhpcy5adz1cIjBcIitlK3J9LHRoaXMuQ1Q9ZnVuY3Rpb24odCl7Zm9yKHZhciBlPVwiXCIsaT0wO2k8dC5sZW5ndGg7aSsrKWUrPTE9PXRbaV0/XCIxXCI6XCIwXCI7dGhpcy5rVChlKX0sdGhpcy5PVD1mdW5jdGlvbih0KXtmb3IodmFyIGU9bmV3IEFycmF5KHQpLGk9MDtpPHQ7aSsrKWVbaV09ITE7cmV0dXJuIGV9LHRoaXMuaVQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ad30sXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQmJihcInN0cmluZ1wiPT10eXBlb2YgdCYmdC50b0xvd2VyQ2FzZSgpLm1hdGNoKC9eWzAtOWEtZl0rJC8pP3RoaXMuSVQodCk6XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQucFQ/dGhpcy5JVCh0LnBUKTpcInVuZGVmaW5lZFwiIT10eXBlb2YgdC5iaW4/dGhpcy5rVCh0LmJpbik6XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQuSGYmJnRoaXMuQ1QodC5IZikpfSxTdC5sYW5nLmV4dGVuZChLSlVSLmJ3LkF3LEtKVVIuYncuWXcpLEtKVVIuYncuTnc9ZnVuY3Rpb24odCl7S0pVUi5idy5Ody5EbS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsdCksdGhpcy5uVD1cIjA0XCJ9LFN0LmxhbmcuZXh0ZW5kKEtKVVIuYncuTncsS0pVUi5idy5zVCksS0pVUi5idy54dz1mdW5jdGlvbigpe0tKVVIuYncueHcuRG0uY29uc3RydWN0b3IuY2FsbCh0aGlzKSx0aGlzLm5UPVwiMDVcIix0aGlzLnRUPVwiMDUwMFwifSxTdC5sYW5nLmV4dGVuZChLSlVSLmJ3Lnh3LEtKVVIuYncuWXcpLEtKVVIuYncuQnc9ZnVuY3Rpb24odCl7dmFyIGU9ZnVuY3Rpb24odCl7dmFyIGU9dC50b1N0cmluZygxNik7cmV0dXJuIDE9PWUubGVuZ3RoJiYoZT1cIjBcIitlKSxlfSxyPWZ1bmN0aW9uKHQpe3ZhciByPVwiXCIsbj1uZXcgaSh0LDEwKSxvPW4udG9TdHJpbmcoMikscz03LW8ubGVuZ3RoJTc7Nz09cyYmKHM9MCk7Zm9yKHZhciBhPVwiXCIsYz0wO2M8cztjKyspYSs9XCIwXCI7bz1hK287Zm9yKHZhciBjPTA7YzxvLmxlbmd0aC0xO2MrPTcpe3ZhciBoPW8uc3Vic3RyKGMsNyk7YyE9by5sZW5ndGgtNyYmKGg9XCIxXCIraCkscis9ZShwYXJzZUludChoLDIpKX1yZXR1cm4gcn07S0pVUi5idy5Cdy5EbS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpLHRoaXMublQ9XCIwNlwiLHRoaXMuRVQ9ZnVuY3Rpb24odCl7dGhpcy50VD1udWxsLHRoaXMuZVQ9ITAsdGhpcy5ueT1udWxsLHRoaXMuWnc9dH0sdGhpcy5QVD1mdW5jdGlvbih0KXtpZighdC5tYXRjaCgvXlswLTkuXSskLykpdGhyb3dcIm1hbGZvcm1lZCBvaWQgc3RyaW5nOiBcIit0O3ZhciBpPVwiXCIsbj10LnNwbGl0KFwiLlwiKSxvPTQwKnBhcnNlSW50KG5bMF0pK3BhcnNlSW50KG5bMV0pO2krPWUobyksbi5zcGxpY2UoMCwyKTtmb3IodmFyIHM9MDtzPG4ubGVuZ3RoO3MrKylpKz1yKG5bc10pO3RoaXMudFQ9bnVsbCx0aGlzLmVUPSEwLHRoaXMubnk9bnVsbCx0aGlzLlp3PWl9LHRoaXMuQVQ9ZnVuY3Rpb24odCl7aWYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIEtKVVIuYncueDUwOS5OVC5uYW1lMm9pZExpc3RbdF0pdGhyb3dcIkRFUk9iamVjdElkZW50aWZpZXIgb2lkTmFtZSB1bmRlZmluZWQ6IFwiK3Q7dmFyIGU9S0pVUi5idy54NTA5Lk5ULm5hbWUyb2lkTGlzdFt0XTt0aGlzLlBUKGUpfSx0aGlzLmlUPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuWnd9LFwidW5kZWZpbmVkXCIhPXR5cGVvZiB0JiYoXCJzdHJpbmdcIj09dHlwZW9mIHQmJnQubWF0Y2goL15bMC0yXS5bMC05Ll0rJC8pP3RoaXMuUFQodCk6dm9pZCAwIT09S0pVUi5idy54NTA5Lk5ULm5hbWUyb2lkTGlzdFt0XT90aGlzLlBUKEtKVVIuYncueDUwOS5OVC5uYW1lMm9pZExpc3RbdF0pOlwidW5kZWZpbmVkXCIhPXR5cGVvZiB0Lm9pZD90aGlzLlBUKHQub2lkKTpcInVuZGVmaW5lZFwiIT10eXBlb2YgdC5wVD90aGlzLkVUKHQucFQpOlwidW5kZWZpbmVkXCIhPXR5cGVvZiB0Lm5hbWUmJnRoaXMuQVQodC5uYW1lKSl9LFN0LmxhbmcuZXh0ZW5kKEtKVVIuYncuQncsS0pVUi5idy5ZdyksS0pVUi5idy5Gdz1mdW5jdGlvbih0KXtLSlVSLmJ3LkZ3LkRtLmNvbnN0cnVjdG9yLmNhbGwodGhpcyksdGhpcy5uVD1cIjBhXCIsdGhpcy5TVD1mdW5jdGlvbih0KXt0aGlzLnRUPW51bGwsdGhpcy5lVD0hMCx0aGlzLlp3PUtKVVIuYncuRXcuUncodCl9LHRoaXMuYlQ9ZnVuY3Rpb24odCl7dmFyIGU9bmV3IGkoU3RyaW5nKHQpLDEwKTt0aGlzLlNUKGUpfSx0aGlzLkVUPWZ1bmN0aW9uKHQpe3RoaXMuWnc9dH0sdGhpcy5pVD1mdW5jdGlvbigpe3JldHVybiB0aGlzLlp3fSxcInVuZGVmaW5lZFwiIT10eXBlb2YgdCYmKFwidW5kZWZpbmVkXCIhPXR5cGVvZiB0W1wiaW50XCJdP3RoaXMuYlQodFtcImludFwiXSk6XCJudW1iZXJcIj09dHlwZW9mIHQ/dGhpcy5iVCh0KTpcInVuZGVmaW5lZFwiIT10eXBlb2YgdC5wVCYmdGhpcy5FVCh0LnBUKSl9LFN0LmxhbmcuZXh0ZW5kKEtKVVIuYncuRncsS0pVUi5idy5ZdyksS0pVUi5idy5fdz1mdW5jdGlvbih0KXtLSlVSLmJ3Ll93LkRtLmNvbnN0cnVjdG9yLmNhbGwodGhpcyx0KSx0aGlzLm5UPVwiMGNcIn0sU3QubGFuZy5leHRlbmQoS0pVUi5idy5fdyxLSlVSLmJ3LnNUKSxLSlVSLmJ3LkR3PWZ1bmN0aW9uKHQpe0tKVVIuYncuRHcuRG0uY29uc3RydWN0b3IuY2FsbCh0aGlzLHQpLHRoaXMublQ9XCIxMlwifSxTdC5sYW5nLmV4dGVuZChLSlVSLmJ3LkR3LEtKVVIuYncuc1QpLEtKVVIuYncuSHc9ZnVuY3Rpb24odCl7S0pVUi5idy5Idy5EbS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsdCksdGhpcy5uVD1cIjEzXCJ9LFN0LmxhbmcuZXh0ZW5kKEtKVVIuYncuSHcsS0pVUi5idy5zVCksS0pVUi5idy5Mdz1mdW5jdGlvbih0KXtLSlVSLmJ3Lkx3LkRtLmNvbnN0cnVjdG9yLmNhbGwodGhpcyx0KSx0aGlzLm5UPVwiMTRcIn0sU3QubGFuZy5leHRlbmQoS0pVUi5idy5MdyxLSlVSLmJ3LnNUKSxLSlVSLmJ3Lk13PWZ1bmN0aW9uKHQpe0tKVVIuYncuTXcuRG0uY29uc3RydWN0b3IuY2FsbCh0aGlzLHQpLHRoaXMublQ9XCIxNlwifSxTdC5sYW5nLmV4dGVuZChLSlVSLmJ3Lk13LEtKVVIuYncuc1QpLEtKVVIuYncuanc9ZnVuY3Rpb24odCl7S0pVUi5idy5qdy5EbS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsdCksdGhpcy5uVD1cIjE3XCIsdGhpcy52VD1mdW5jdGlvbih0KXt0aGlzLnRUPW51bGwsdGhpcy5lVD0hMCx0aGlzLnhUPXQsdGhpcy5ueT10aGlzLmRUKHRoaXMueFQsXCJ1dGNcIiksdGhpcy5adz1zdG9oZXgodGhpcy5ueSl9LHRoaXMuaVQ9ZnVuY3Rpb24oKXtyZXR1cm5cInVuZGVmaW5lZFwiPT10eXBlb2YgdGhpcy54VCYmXCJ1bmRlZmluZWRcIj09dHlwZW9mIHRoaXMubnkmJih0aGlzLnhUPW5ldyBEYXRlLHRoaXMubnk9dGhpcy5kVCh0aGlzLnhULFwidXRjXCIpLHRoaXMuWnc9c3RvaGV4KHRoaXMubnkpKSx0aGlzLlp3fSx2b2lkIDAhPT10JiYodm9pZCAwIT09dC5hYz90aGlzLmNUKHQuYWMpOlwic3RyaW5nXCI9PXR5cGVvZiB0JiZ0Lm1hdGNoKC9eWzAtOV17MTJ9WiQvKT90aGlzLmNUKHQpOnZvaWQgMCE9PXQucFQ/dGhpcy5oVCh0LnBUKTp2b2lkIDAhPT10LnhUJiZ0aGlzLnZUKHQueFQpKX0sU3QubGFuZy5leHRlbmQoS0pVUi5idy5qdyxLSlVSLmJ3LnVUKSxLSlVSLmJ3LlV3PWZ1bmN0aW9uKHQpe0tKVVIuYncuVXcuRG0uY29uc3RydWN0b3IuY2FsbCh0aGlzLHQpLHRoaXMublQ9XCIxOFwiLHRoaXMuQlQ9ITEsdGhpcy52VD1mdW5jdGlvbih0KXt0aGlzLnRUPW51bGwsdGhpcy5lVD0hMCx0aGlzLnhUPXQsdGhpcy5ueT10aGlzLmRUKHRoaXMueFQsXCJnZW5cIix0aGlzLkJUKSx0aGlzLlp3PXN0b2hleCh0aGlzLm55KX0sdGhpcy5pVD1mdW5jdGlvbigpe3JldHVybiB2b2lkIDA9PT10aGlzLnhUJiZ2b2lkIDA9PT10aGlzLm55JiYodGhpcy54VD1uZXcgRGF0ZSx0aGlzLm55PXRoaXMuZFQodGhpcy54VCxcImdlblwiLHRoaXMuQlQpLHRoaXMuWnc9c3RvaGV4KHRoaXMubnkpKSx0aGlzLlp3fSx2b2lkIDAhPT10JiYodm9pZCAwIT09dC5hYz90aGlzLmNUKHQuYWMpOlwic3RyaW5nXCI9PXR5cGVvZiB0JiZ0Lm1hdGNoKC9eWzAtOV17MTR9WiQvKT90aGlzLmNUKHQpOnZvaWQgMCE9PXQucFQ/dGhpcy5oVCh0LnBUKTp2b2lkIDAhPT10LnhUJiZ0aGlzLnZUKHQueFQpLHQubWlsbGlzPT09ITAmJih0aGlzLkJUPSEwKSl9LFN0LmxhbmcuZXh0ZW5kKEtKVVIuYncuVXcsS0pVUi5idy51VCksS0pVUi5idy5Wdz1mdW5jdGlvbih0KXtLSlVSLmJ3LlZ3LkRtLmNvbnN0cnVjdG9yLmNhbGwodGhpcyx0KSx0aGlzLm5UPVwiMzBcIix0aGlzLmlUPWZ1bmN0aW9uKCl7Zm9yKHZhciB0PVwiXCIsZT0wO2U8dGhpcy53VC5sZW5ndGg7ZSsrKXt2YXIgaT10aGlzLndUW2VdO3QrPWkuencoKX1yZXR1cm4gdGhpcy5adz10LHRoaXMuWnd9fSxTdC5sYW5nLmV4dGVuZChLSlVSLmJ3LlZ3LEtKVVIuYncueVQpLEtKVVIuYncuUXc9ZnVuY3Rpb24odCl7S0pVUi5idy5Rdy5EbS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsdCksdGhpcy5uVD1cIjMxXCIsdGhpcy5GVD0hMCx0aGlzLmlUPWZ1bmN0aW9uKCl7Zm9yKHZhciB0PW5ldyBBcnJheSxlPTA7ZTx0aGlzLndULmxlbmd0aDtlKyspe3ZhciBpPXRoaXMud1RbZV07dC5wdXNoKGkuencoKSl9cmV0dXJuIDE9PXRoaXMuRlQmJnQuc29ydCgpLHRoaXMuWnc9dC5qb2luKFwiXCIpLHRoaXMuWnd9LFwidW5kZWZpbmVkXCIhPXR5cGVvZiB0JiZcInVuZGVmaW5lZFwiIT10eXBlb2YgdC5zb3J0ZmxhZyYmMD09dC5zb3J0ZmxhZyYmKHRoaXMuRlQ9ITEpfSxTdC5sYW5nLmV4dGVuZChLSlVSLmJ3LlF3LEtKVVIuYncueVQpLEtKVVIuYncucXc9ZnVuY3Rpb24odCl7S0pVUi5idy5xdy5EbS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpLHRoaXMublQ9XCJhMFwiLHRoaXMuWnc9XCJcIix0aGlzLl9UPSEwLHRoaXMuRFQ9bnVsbCx0aGlzLkhUPWZ1bmN0aW9uKHQsZSxpKXt0aGlzLm5UPWUsdGhpcy5fVD10LHRoaXMuRFQ9aSx0aGlzLl9UPyh0aGlzLlp3PXRoaXMuRFQuencoKSx0aGlzLnRUPW51bGwsdGhpcy5lVD0hMCk6KHRoaXMuWnc9bnVsbCx0aGlzLnRUPWkuencoKSx0aGlzLnRUPXRoaXMudFQucmVwbGFjZSgvXi4uLyxlKSx0aGlzLmVUPSExKX0sdGhpcy5pVD1mdW5jdGlvbigpe3JldHVybiB0aGlzLlp3fSxcInVuZGVmaW5lZFwiIT10eXBlb2YgdCYmKFwidW5kZWZpbmVkXCIhPXR5cGVvZiB0LnRhZyYmKHRoaXMublQ9dC50YWcpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiB0Lkp3JiYodGhpcy5fVD10Lkp3KSxcInVuZGVmaW5lZFwiIT10eXBlb2YgdC5LdyYmKHRoaXMuRFQ9dC5Ldyx0aGlzLkhUKHRoaXMuX1QsdGhpcy5uVCx0aGlzLkRUKSkpfSxTdC5sYW5nLmV4dGVuZChLSlVSLmJ3LnF3LEtKVVIuYncuWXcpOy8qISAoYykgVG9tIFd1IHwgaHR0cDovL3d3dy1jcy1zdHVkZW50cy5zdGFuZm9yZC5lZHUvfnRqdy9qc2JuLyAqL1xuICB2YXIgTnQ9XCJBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsvXCIseHQ9XCI9XCI7LyohIGNyeXB0by0xLjEuOC5qcyAoYykgMjAxMy0yMDE2IEtlbmppIFVydXNoaW1hIHwga2p1ci5naXRodWIuY29tL2pzcnNhc2lnbi9saWNlbnNlXG4gICAqL1xuICBcInVuZGVmaW5lZFwiIT10eXBlb2YgS0pVUiYmS0pVUnx8KEtKVVI9e30pLFwidW5kZWZpbmVkXCIhPXR5cGVvZiBLSlVSLmNyeXB0byYmS0pVUi5jcnlwdG98fChLSlVSLmNyeXB0bz17fSksS0pVUi5jcnlwdG8uV3k9bmV3IGZ1bmN0aW9uKCl7dGhpcy50bT17c2hhMTpcIjMwMjEzMDA5MDYwNTJiMGUwMzAyMWEwNTAwMDQxNFwiLExUOlwiMzAyZDMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjA0MDUwMDA0MWNcIixzaGEyNTY6XCIzMDMxMzAwZDA2MDk2MDg2NDgwMTY1MDMwNDAyMDEwNTAwMDQyMFwiLE1UOlwiMzA0MTMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjAyMDUwMDA0MzBcIixqVDpcIjMwNTEzMDBkMDYwOTYwODY0ODAxNjUwMzA0MDIwMzA1MDAwNDQwXCIsVVQ6XCIzMDIwMzAwYzA2MDgyYTg2NDg4NmY3MGQwMjAyMDUwMDA0MTBcIixWVDpcIjMwMjAzMDBjMDYwODJhODY0ODg2ZjcwZDAyMDUwNTAwMDQxMFwiLFFUOlwiMzAyMTMwMDkwNjA1MmIyNDAzMDIwMTA1MDAwNDE0XCJ9LHRoaXMucVQ9e1ZUOlwiY3J5cHRvanNcIixzaGExOlwiY3J5cHRvanNcIixMVDpcImNyeXB0b2pzXCIsc2hhMjU2OlwiY3J5cHRvanNcIixNVDpcImNyeXB0b2pzXCIsalQ6XCJjcnlwdG9qc1wiLFFUOlwiY3J5cHRvanNcIixKVDpcImNyeXB0b2pzXCIsS1Q6XCJjcnlwdG9qc1wiLEdUOlwiY3J5cHRvanNcIix6VDpcImNyeXB0b2pzXCIsV1Q6XCJjcnlwdG9qc1wiLCRUOlwiY3J5cHRvanNcIixZVDpcImNyeXB0b2pzXCIsWFQ6XCJjcnlwdG9qcy9qc3JzYVwiLFpUOlwiY3J5cHRvanMvanNyc2FcIix0UzpcImNyeXB0b2pzL2pzcnNhXCIsZVM6XCJjcnlwdG9qcy9qc3JzYVwiLGlTOlwiY3J5cHRvanMvanNyc2FcIixyUzpcImNyeXB0b2pzL2pzcnNhXCIsblM6XCJjcnlwdG9qcy9qc3JzYVwiLG9TOlwiY3J5cHRvanMvanNyc2FcIixzUzpcImNyeXB0b2pzL2pzcnNhXCIsYVM6XCJjcnlwdG9qcy9qc3JzYVwiLGNTOlwiY3J5cHRvanMvanNyc2FcIixoUzpcImNyeXB0b2pzL2pzcnNhXCIscFM6XCJjcnlwdG9qcy9qc3JzYVwiLHVTOlwiY3J5cHRvanMvanNyc2FcIixsUzpcImNyeXB0b2pzL2pzcnNhXCIsZFM6XCJjcnlwdG9qcy9qc3JzYVwiLGZTOlwiY3J5cHRvanMvanNyc2FcIixnUzpcImNyeXB0b2pzL2pzcnNhXCIsdlM6XCJjcnlwdG9qcy9qc3JzYVwiLHlTOlwiY3J5cHRvanMvanNyc2FcIixtUzpcImNyeXB0b2pzL2pzcnNhXCIsd1M6XCJjcnlwdG9qcy9qc3JzYVwiLFRTOlwiY3J5cHRvanMvanNyc2FcIixTUzpcImNyeXB0b2pzL2pzcnNhXCJ9LHRoaXMuYlM9e1ZUOmJ0LnZ3Lnl3LHNoYTE6YnQudncuVHcsTFQ6YnQudncuU0hBMjI0LHNoYTI1NjpidC52dy5TSEEyNTYsTVQ6YnQudncuU0hBMzg0LGpUOmJ0LnZ3LlNIQTUxMixRVDpidC52dy5SSVBFTUQxNjB9LHRoaXMuRVM9ZnVuY3Rpb24odCxlKXtpZihcInVuZGVmaW5lZFwiPT10eXBlb2YgdGhpcy50bVtlXSl0aHJvd1wiYWxnIG5vdCBzdXBwb3J0ZWQgaW4gVXRpbC5ESUdFU1RJTkZPSEVBRDogXCIrZTtyZXR1cm4gdGhpcy50bVtlXSt0fSx0aGlzLll5PWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj10aGlzLkVTKHQsZSksbj1pLzQ7aWYoci5sZW5ndGgrMjI+bil0aHJvd1wia2V5IGlzIHRvbyBzaG9ydCBmb3IgU2lnQWxnOiBrZXlsZW49XCIraStcIixcIitlO2Zvcih2YXIgbz1cIjAwMDFcIixzPVwiMDBcIityLGE9XCJcIixjPW4tby5sZW5ndGgtcy5sZW5ndGgsaD0wO2g8YztoKz0yKWErPVwiZmZcIjt2YXIgcD1vK2ErcztyZXR1cm4gcH0sdGhpcy56eT1mdW5jdGlvbih0LGUpe3ZhciBpPW5ldyBLSlVSLmNyeXB0by5JUyh7UlM6ZX0pO3JldHVybiBpLmtTKHQpfSx0aGlzLlh5PWZ1bmN0aW9uKHQsZSl7dmFyIGk9bmV3IEtKVVIuY3J5cHRvLklTKHtSUzplfSk7cmV0dXJuIGkuQ1ModCl9LHRoaXMuc2hhMT1mdW5jdGlvbih0KXt2YXIgZT1uZXcgS0pVUi5jcnlwdG8uSVMoe1JTOlwic2hhMVwiLE9TOlwiY3J5cHRvanNcIn0pO3JldHVybiBlLmtTKHQpfSx0aGlzLnNoYTI1Nj1mdW5jdGlvbih0KXt2YXIgZT1uZXcgS0pVUi5jcnlwdG8uSVMoe1JTOlwic2hhMjU2XCIsT1M6XCJjcnlwdG9qc1wifSk7cmV0dXJuIGUua1ModCl9LHRoaXMuUFM9ZnVuY3Rpb24odCl7dmFyIGU9bmV3IEtKVVIuY3J5cHRvLklTKHtSUzpcInNoYTI1NlwiLE9TOlwiY3J5cHRvanNcIn0pO3JldHVybiBlLkNTKHQpfSx0aGlzLmpUPWZ1bmN0aW9uKHQpe3ZhciBlPW5ldyBLSlVSLmNyeXB0by5JUyh7UlM6XCJzaGE1MTJcIixPUzpcImNyeXB0b2pzXCJ9KTtyZXR1cm4gZS5rUyh0KX0sdGhpcy5OUz1mdW5jdGlvbih0KXt2YXIgZT1uZXcgS0pVUi5jcnlwdG8uSVMoe1JTOlwic2hhNTEyXCIsT1M6XCJjcnlwdG9qc1wifSk7cmV0dXJuIGUuQ1ModCl9LHRoaXMuVlQ9ZnVuY3Rpb24odCl7dmFyIGU9bmV3IEtKVVIuY3J5cHRvLklTKHtSUzpcIm1kNVwiLE9TOlwiY3J5cHRvanNcIn0pO3JldHVybiBlLmtTKHQpfSx0aGlzLlFUPWZ1bmN0aW9uKHQpe3ZhciBlPW5ldyBLSlVSLmNyeXB0by5JUyh7UlM6XCJyaXBlbWQxNjBcIixPUzpcImNyeXB0b2pzXCJ9KTtyZXR1cm4gZS5rUyh0KX0sdGhpcy54Uz1mdW5jdGlvbih0KXt9fSxLSlVSLmNyeXB0by5JUz1mdW5jdGlvbih0KXt0aGlzLkJTPWZ1bmN0aW9uKHQsZSl7aWYobnVsbCE9dCYmdm9pZCAwPT09ZSYmKGU9S0pVUi5jcnlwdG8uV3kucVRbdF0pLFwiOm1kNTpzaGExOnNoYTIyNDpzaGEyNTY6c2hhMzg0OnNoYTUxMjpyaXBlbWQxNjA6XCIuaW5kZXhPZih0KSE9LTEmJlwiY3J5cHRvanNcIj09ZSl7dHJ5e3RoaXMuRlM9S0pVUi5jcnlwdG8uV3kuYlNbdF0uY3JlYXRlKCl9Y2F0Y2goaSl7dGhyb3dcInNldEFsZ0FuZFByb3ZpZGVyIGhhc2ggYWxnIHNldCBmYWlsIGFsZz1cIit0K1wiL1wiK2l9dGhpcy5fUz1mdW5jdGlvbih0KXt0aGlzLkZTLnVwZGF0ZSh0KX0sdGhpcy5EUz1mdW5jdGlvbih0KXt2YXIgZT1idC5ZbS5YbS5wYXJzZSh0KTt0aGlzLkZTLnVwZGF0ZShlKX0sdGhpcy5kaWdlc3Q9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLkZTLmx3KCk7cmV0dXJuIHQudG9TdHJpbmcoYnQuWW0uWG0pfSx0aGlzLmtTPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLl9TKHQpLHRoaXMuZGlnZXN0KCl9LHRoaXMuQ1M9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuRFModCksdGhpcy5kaWdlc3QoKX19aWYoXCI6c2hhMjU2OlwiLmluZGV4T2YodCkhPS0xJiZcInNqY2xcIj09ZSl7dHJ5e3RoaXMuRlM9bmV3IHNqY2wuaGFzaC5zaGEyNTZ9Y2F0Y2goaSl7dGhyb3dcInNldEFsZ0FuZFByb3ZpZGVyIGhhc2ggYWxnIHNldCBmYWlsIGFsZz1cIit0K1wiL1wiK2l9dGhpcy5fUz1mdW5jdGlvbih0KXt0aGlzLkZTLnVwZGF0ZSh0KX0sdGhpcy5EUz1mdW5jdGlvbih0KXt2YXIgZT1zamNsLmNvZGVjLnBULnRvQml0cyh0KTt0aGlzLkZTLnVwZGF0ZShlKX0sdGhpcy5kaWdlc3Q9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLkZTLmx3KCk7cmV0dXJuIHNqY2wuY29kZWMucFQuZnJvbUJpdHModCl9LHRoaXMua1M9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuX1ModCksdGhpcy5kaWdlc3QoKX0sdGhpcy5DUz1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5EUyh0KSx0aGlzLmRpZ2VzdCgpfX19LHRoaXMuX1M9ZnVuY3Rpb24odCl7dGhyb3dcInVwZGF0ZVN0cmluZyhzdHIpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMuSFMrXCIvXCIrdGhpcy5MU30sdGhpcy5EUz1mdW5jdGlvbih0KXt0aHJvd1widXBkYXRlSGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5IUytcIi9cIit0aGlzLkxTfSx0aGlzLmRpZ2VzdD1mdW5jdGlvbigpe3Rocm93XCJkaWdlc3QoKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZy9wcm92OiBcIit0aGlzLkhTK1wiL1wiK3RoaXMuTFN9LHRoaXMua1M9ZnVuY3Rpb24odCl7dGhyb3dcImRpZ2VzdFN0cmluZyhzdHIpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMuSFMrXCIvXCIrdGhpcy5MU30sdGhpcy5DUz1mdW5jdGlvbih0KXt0aHJvd1wiZGlnZXN0SGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5IUytcIi9cIit0aGlzLkxTfSx2b2lkIDAhPT10JiZ2b2lkIDAhPT10LlJTJiYodGhpcy5IUz10LlJTLHZvaWQgMD09PXQuT1MmJih0aGlzLkxTPUtKVVIuY3J5cHRvLld5LnFUW3RoaXMuSFNdKSx0aGlzLkJTKHRoaXMuSFMsdGhpcy5MUykpfSxLSlVSLmNyeXB0by5NUz1mdW5jdGlvbih0KXt0aGlzLkJTPWZ1bmN0aW9uKHQsZSl7aWYodD10LnRvTG93ZXJDYXNlKCksbnVsbD09dCYmKHQ9XCJobWFjc2hhMVwiKSx0PXQudG9Mb3dlckNhc2UoKSxcImhtYWNcIiE9dC5zdWJzdHIoMCw0KSl0aHJvd1wic2V0QWxnQW5kUHJvdmlkZXIgdW5zdXBwb3J0ZWQgSE1BQyBhbGc6IFwiK3Q7dm9pZCAwPT09ZSYmKGU9S0pVUi5jcnlwdG8uV3kucVRbdF0pLHRoaXMualM9dCtcIi9cIitlO3ZhciBpPXQuc3Vic3RyKDQpO2lmKFwiOm1kNTpzaGExOnNoYTIyNDpzaGEyNTY6c2hhMzg0OnNoYTUxMjpyaXBlbWQxNjA6XCIuaW5kZXhPZihpKSE9LTEmJlwiY3J5cHRvanNcIj09ZSl7dHJ5e3ZhciByPUtKVVIuY3J5cHRvLld5LmJTW2ldO3RoaXMubWFjPWJ0LnZ3LkhNQUMuY3JlYXRlKHIsdGhpcy5VUyl9Y2F0Y2gobil7dGhyb3dcInNldEFsZ0FuZFByb3ZpZGVyIGhhc2ggYWxnIHNldCBmYWlsIGhhc2hBbGc9XCIraStcIi9cIitufXRoaXMuX1M9ZnVuY3Rpb24odCl7dGhpcy5tYWMudXBkYXRlKHQpfSx0aGlzLkRTPWZ1bmN0aW9uKHQpe3ZhciBlPWJ0LlltLlhtLnBhcnNlKHQpO3RoaXMubWFjLnVwZGF0ZShlKX0sdGhpcy5WUz1mdW5jdGlvbigpe3ZhciB0PXRoaXMubWFjLmx3KCk7cmV0dXJuIHQudG9TdHJpbmcoYnQuWW0uWG0pfSx0aGlzLlFTPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLl9TKHQpLHRoaXMuVlMoKX0sdGhpcy5xUz1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5EUyh0KSx0aGlzLlZTKCl9fX0sdGhpcy5fUz1mdW5jdGlvbih0KXt0aHJvd1widXBkYXRlU3RyaW5nKHN0cikgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5qU30sdGhpcy5EUz1mdW5jdGlvbih0KXt0aHJvd1widXBkYXRlSGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5qU30sdGhpcy5WUz1mdW5jdGlvbigpe3Rocm93XCJkaWdlc3QoKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZy9wcm92OiBcIit0aGlzLmpTfSx0aGlzLlFTPWZ1bmN0aW9uKHQpe3Rocm93XCJkaWdlc3RTdHJpbmcoc3RyKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZy9wcm92OiBcIit0aGlzLmpTfSx0aGlzLnFTPWZ1bmN0aW9uKHQpe3Rocm93XCJkaWdlc3RIZXgoaGV4KSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZy9wcm92OiBcIit0aGlzLmpTfSx0aGlzLkpTPWZ1bmN0aW9uKHQpe2lmKFwic3RyaW5nXCI9PXR5cGVvZiB0KXt2YXIgZT10O3JldHVybiB0Lmxlbmd0aCUyIT0xJiZ0Lm1hdGNoKC9eWzAtOUEtRmEtZl0rJC8pfHwoZT1yc3RydG9oZXgodCkpLHZvaWQodGhpcy5VUz1idC5ZbS5YbS5wYXJzZShlKSl9aWYoXCJvYmplY3RcIiE9dHlwZW9mIHQpdGhyb3dcIktKVVIuY3J5cHRvLk1hYyB1bnN1cHBvcnRlZCBwYXNzd29yZCB0eXBlOiBcIit0O3ZhciBlPW51bGw7aWYodm9pZCAwIT09dC5wVCl7aWYodC5wVC5sZW5ndGglMiE9MHx8IXQucFQubWF0Y2goL15bMC05QS1GYS1mXSskLykpdGhyb3dcIk1hYzogd3JvbmcgaGV4IHBhc3N3b3JkOiBcIit0LnBUO2U9dC5wVH1pZih2b2lkIDAhPT10LnV0ZjgmJihlPXV0Zjh0b2hleCh0LnV0ZjgpKSx2b2lkIDAhPT10LnJzdHImJihlPXJzdHJ0b2hleCh0LnJzdHIpKSx2b2lkIDAhPT10LmI2NCYmKGU9Sih0LmI2NCkpLHZvaWQgMCE9PXQuYjY0dSYmKGU9YjY0dXRvaGV4KHQuYjY0dSkpLG51bGw9PWUpdGhyb3dcIktKVVIuY3J5cHRvLk1hYyB1bnN1cHBvcnRlZCBwYXNzd29yZCB0eXBlOiBcIit0O3RoaXMuVVM9YnQuWW0uWG0ucGFyc2UoZSl9LHZvaWQgMCE9PXQmJih2b2lkIDAhPT10LlVTJiZ0aGlzLkpTKHQuVVMpLHZvaWQgMCE9PXQuUlMmJih0aGlzLkhTPXQuUlMsdm9pZCAwPT09dC5PUyYmKHRoaXMuTFM9S0pVUi5jcnlwdG8uV3kucVRbdGhpcy5IU10pLHRoaXMuQlModGhpcy5IUyx0aGlzLkxTKSkpfSxLSlVSLmNyeXB0by5TaWduYXR1cmU9ZnVuY3Rpb24odCl7dmFyIGU9bnVsbDtpZih0aGlzLktTPWZ1bmN0aW9uKCl7dGhpcy5IUy5tYXRjaCgvXiguKyl3aXRoKC4rKSQvKSYmKHRoaXMuR1M9UmVnRXhwLiQxLnRvTG93ZXJDYXNlKCksdGhpcy56Uz1SZWdFeHAuJDIudG9Mb3dlckNhc2UoKSl9LHRoaXMuV1M9ZnVuY3Rpb24odCxlKXtmb3IodmFyIGk9XCJcIixyPWUvNC10Lmxlbmd0aCxuPTA7bjxyO24rKylpKz1cIjBcIjtyZXR1cm4gaSt0fSx0aGlzLkJTPWZ1bmN0aW9uKHQsZSl7aWYodGhpcy5LUygpLFwiY3J5cHRvanMvanNyc2FcIiE9ZSl0aHJvd1wicHJvdmlkZXIgbm90IHN1cHBvcnRlZDogXCIrZTtpZihcIjptZDU6c2hhMTpzaGEyMjQ6c2hhMjU2OnNoYTM4NDpzaGE1MTI6cmlwZW1kMTYwOlwiLmluZGV4T2YodGhpcy5HUykhPS0xKXt0cnl7dGhpcy5GUz1uZXcgS0pVUi5jcnlwdG8uSVMoe1JTOnRoaXMuR1N9KX1jYXRjaChpKXt0aHJvd1wic2V0QWxnQW5kUHJvdmlkZXIgaGFzaCBhbGcgc2V0IGZhaWwgYWxnPVwiK3RoaXMuR1MrXCIvXCIraX10aGlzLmluaXQ9ZnVuY3Rpb24odCxlKXt2YXIgaT1udWxsO3RyeXtpPXZvaWQgMD09PWU/S0VZVVRJTC5nZXRLZXkodCk6S0VZVVRJTC5nZXRLZXkodCxlKX1jYXRjaChyKXt0aHJvd1wiaW5pdCBmYWlsZWQ6XCIrcn1pZihpLmlzUHJpdmF0ZT09PSEwKXRoaXMuJFM9aSx0aGlzLnN0YXRlPVwiU0lHTlwiO2Vsc2V7aWYoaS5xeSE9PSEwKXRocm93XCJpbml0IGZhaWxlZC46XCIraTt0aGlzLllTPWksdGhpcy5zdGF0ZT1cIlZFUklGWVwifX0sdGhpcy5YUz1mdW5jdGlvbih0KXtcInN0cmluZ1wiPT10eXBlb2YgdC5aUyYmXCJzdHJpbmdcIj09dHlwZW9mIHQudGI/KHRoaXMuWlM9dC5aUyx0aGlzLnRiPXQudGIpOnRoaXMuJFM9dCx0aGlzLnN0YXRlPVwiU0lHTlwifSx0aGlzLmViPWZ1bmN0aW9uKHQpe1wic3RyaW5nXCI9PXR5cGVvZiB0LmliJiZcInN0cmluZ1wiPT10eXBlb2YgdC50Yj8odGhpcy5pYj10LmliLHRoaXMudGI9dC50Yik6dCBpbnN0YW5jZW9mIEtKVVIuY3J5cHRvLkVDRFNBP3RoaXMuWVM9dDp0IGluc3RhbmNlb2YgWSYmKHRoaXMuWVM9dCksdGhpcy5zdGF0ZT1cIlZFUklGWVwifSx0aGlzLnJiPWZ1bmN0aW9uKHQpe3ZhciBlPW5ldyBYNTA5O2UucmVhZENlcnRQRU0odCksdGhpcy5ZUz1lLm5iLHRoaXMuc3RhdGU9XCJWRVJJRllcIn0sdGhpcy5fUz1mdW5jdGlvbih0KXt0aGlzLkZTLl9TKHQpfSx0aGlzLkRTPWZ1bmN0aW9uKHQpe3RoaXMuRlMuRFModCl9LHRoaXMuc2lnbj1mdW5jdGlvbigpe2lmKHRoaXMub2I9dGhpcy5GUy5kaWdlc3QoKSxcInVuZGVmaW5lZFwiIT10eXBlb2YgdGhpcy5aUyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHRoaXMudGIpe3ZhciB0PW5ldyBLSlVSLmNyeXB0by5FQ0RTQSh7Y3VydmU6dGhpcy50Yn0pO3RoaXMuc2I9dC5hYih0aGlzLm9iLHRoaXMuWlMpfWVsc2UgaWYodGhpcy4kUyBpbnN0YW5jZW9mIFkmJlwicnNhYW5kbWdmMVwiPT10aGlzLnpTKXRoaXMuc2I9dGhpcy4kUy5aeSh0aGlzLm9iLHRoaXMuR1MsdGhpcy5jYik7ZWxzZSBpZih0aGlzLiRTIGluc3RhbmNlb2YgWSYmXCJyc2FcIj09dGhpcy56Uyl0aGlzLnNiPXRoaXMuJFMuJHkodGhpcy5vYix0aGlzLkdTKTtlbHNlIGlmKHRoaXMuJFMgaW5zdGFuY2VvZiBLSlVSLmNyeXB0by5FQ0RTQSl0aGlzLnNiPXRoaXMuJFMuJHkodGhpcy5vYik7ZWxzZXtpZighKHRoaXMuJFMgaW5zdGFuY2VvZiBLSlVSLmNyeXB0by5EU0EpKXRocm93XCJTaWduYXR1cmU6IHVuc3VwcG9ydGVkIHB1YmxpYyBrZXkgYWxnOiBcIit0aGlzLnpTO3RoaXMuc2I9dGhpcy4kUy4keSh0aGlzLm9iKX1yZXR1cm4gdGhpcy5zYn0sdGhpcy5oYj1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5fUyh0KSx0aGlzLnNpZ24oKX0sdGhpcy5hYj1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5EUyh0KSx0aGlzLnNpZ24oKX0sdGhpcy52ZXJpZnk9ZnVuY3Rpb24odCl7aWYodGhpcy5vYj10aGlzLkZTLmRpZ2VzdCgpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiB0aGlzLmliJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgdGhpcy50Yil7dmFyIGU9bmV3IEtKVVIuY3J5cHRvLkVDRFNBKHtjdXJ2ZTp0aGlzLnRifSk7cmV0dXJuIGUudmVyaWZ5SGV4KHRoaXMub2IsdCx0aGlzLmliKX1pZih0aGlzLllTIGluc3RhbmNlb2YgWSYmXCJyc2FhbmRtZ2YxXCI9PXRoaXMuelMpcmV0dXJuIHRoaXMuWVMuZW0odGhpcy5vYix0LHRoaXMuR1MsdGhpcy5jYik7aWYodGhpcy5ZUyBpbnN0YW5jZW9mIFkmJlwicnNhXCI9PXRoaXMuelMpcmV0dXJuIHRoaXMuWVMucGIodGhpcy5vYix0KTtpZih0aGlzLllTIGluc3RhbmNlb2YgS0pVUi5jcnlwdG8uRUNEU0EpcmV0dXJuIHRoaXMuWVMucGIodGhpcy5vYix0KTtpZih0aGlzLllTIGluc3RhbmNlb2YgS0pVUi5jcnlwdG8uRFNBKXJldHVybiB0aGlzLllTLnBiKHRoaXMub2IsdCk7dGhyb3dcIlNpZ25hdHVyZTogdW5zdXBwb3J0ZWQgcHVibGljIGtleSBhbGc6IFwiK3RoaXMuelN9fX0sdGhpcy5pbml0PWZ1bmN0aW9uKHQsZSl7dGhyb3dcImluaXQoa2V5LCBwYXNzKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZzpwcm92PVwiK3RoaXMudWJ9LHRoaXMuZWI9ZnVuY3Rpb24odCl7dGhyb3dcImluaXRWZXJpZnlCeVB1YmxpY0tleShyc2FQdWJLZXl5KSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZzpwcm92PVwiK3RoaXMudWJ9LHRoaXMucmI9ZnVuY3Rpb24odCl7dGhyb3dcImluaXRWZXJpZnlCeUNlcnRpZmljYXRlUEVNKGNlcnRQRU0pIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnOnByb3Y9XCIrdGhpcy51Yn0sdGhpcy5YUz1mdW5jdGlvbih0KXt0aHJvd1wiaW5pdFNpZ24ocHJ2S2V5KSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZzpwcm92PVwiK3RoaXMudWJ9LHRoaXMuX1M9ZnVuY3Rpb24odCl7dGhyb3dcInVwZGF0ZVN0cmluZyhzdHIpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnOnByb3Y9XCIrdGhpcy51Yn0sdGhpcy5EUz1mdW5jdGlvbih0KXt0aHJvd1widXBkYXRlSGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLnVifSx0aGlzLnNpZ249ZnVuY3Rpb24oKXt0aHJvd1wic2lnbigpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnOnByb3Y9XCIrdGhpcy51Yn0sdGhpcy5oYj1mdW5jdGlvbih0KXt0aHJvd1wiZGlnZXN0U3RyaW5nKHN0cikgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLnVifSx0aGlzLmFiPWZ1bmN0aW9uKHQpe3Rocm93XCJkaWdlc3RIZXgoaGV4KSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZzpwcm92PVwiK3RoaXMudWJ9LHRoaXMudmVyaWZ5PWZ1bmN0aW9uKHQpe3Rocm93XCJ2ZXJpZnkoaFNpZ1ZhbCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLnVifSx0aGlzLmxiPXQsdm9pZCAwIT09dCYmKHZvaWQgMCE9PXQuUlMmJih0aGlzLkhTPXQuUlMsdm9pZCAwPT09dC5PUz90aGlzLkxTPUtKVVIuY3J5cHRvLld5LnFUW3RoaXMuSFNdOnRoaXMuTFM9dC5PUyx0aGlzLnViPXRoaXMuSFMrXCI6XCIrdGhpcy5MUyx0aGlzLkJTKHRoaXMuSFMsdGhpcy5MUyksdGhpcy5LUygpKSx2b2lkIDAhPT10LmZiJiYodGhpcy5jYj10LmZiKSx2b2lkIDAhPT10LnBydmtleXBlbSkpe2lmKHZvaWQgMCE9PXQucHJ2a2V5cGFzKXRocm93XCJib3RoIHBydmtleXBlbSBhbmQgcHJ2a2V5cGFzIHBhcmFtZXRlcnMgbm90IHN1cHBvcnRlZFwiO3RyeXt2YXIgZT1uZXcgWTtlLnJlYWRQcml2YXRlS2V5RnJvbVBFTVN0cmluZyh0LnBydmtleXBlbSksdGhpcy5YUyhlKX1jYXRjaChpKXt0aHJvd1wiZmF0YWwgZXJyb3IgdG8gbG9hZCBwZW0gcHJpdmF0ZSBrZXk6IFwiK2l9fX0sS0pVUi5jcnlwdG8uTlQ9bmV3IGZ1bmN0aW9uKCl7dGhpcy5nYj17dmI6XCJyc2FFbmNyeXB0aW9uXCIseWI6XCJlY1B1YmxpY0tleVwiLG1iOlwiZHNhXCIsd2I6XCJzZWNwMjU2cjFcIixUYjpcInNlY3AxOTJrMVwiLFNiOlwic2VjcDIyNHIxXCIsYmI6XCJzZWNwMjU2azFcIixFYjpcInNlY3A1MjFyMVwiLEliOlwic2VjcDM4NHIxXCIsUmI6XCJTSEExd2l0aERTQVwiLFwiNjA4NjQ4MDE2NTAzMDQwMzAxXCI6XCJTSEEyMjR3aXRoRFNBXCIsXCI2MDg2NDgwMTY1MDMwNDAzMDJcIjpcIlNIQTI1NndpdGhEU0FcIn19O3ZhciBCdD0yMDtZLnByb3RvdHlwZS5HeT1aLFkucHJvdG90eXBlLnFoPVgsWS5wcm90b3R5cGUuZW5jcnlwdD10dCxZLnByb3RvdHlwZS5rYj1ldCxZLnByb3RvdHlwZS50eXBlPVwiUlNBXCI7LyohIHJzYXNpZ24tMS4yLjcuanMgKGMpIDIwMTIgS2VuamkgVXJ1c2hpbWEgfCBranVyLmdpdGh1Yi5jb20vanNyc2FzaWduL2xpY2Vuc2VcbiAgICovXG4gIHZhciBGdD1uZXcgUmVnRXhwKFwiXCIpO0Z0LmNvbXBpbGUoXCJbXjAtOWEtZl1cIixcImdpXCIpLFkucHJvdG90eXBlLiR5PW50LFkucHJvdG90eXBlLmhiPXJ0LFkucHJvdG90eXBlLkNiPW90LFkucHJvdG90eXBlLk9iPXN0LFkucHJvdG90eXBlLnNpZ249cnQsWS5wcm90b3R5cGUuUGI9b3QsWS5wcm90b3R5cGUuQWI9c3QsWS5wcm90b3R5cGUuWnk9aHQsWS5wcm90b3R5cGUuTmI9Y3QsWS5wcm90b3R5cGUueGI9Y3QsWS5CYj0tMSxZLkZiPS0yLFkucHJvdG90eXBlLnBiPXZ0LFkucHJvdG90eXBlLkpoPWd0LFkucHJvdG90eXBlLl9iPWZ0LFkucHJvdG90eXBlLnZlcmlmeT1ndCxZLnByb3RvdHlwZS5EYj1mdCxZLnByb3RvdHlwZS5lbT1tdCxZLnByb3RvdHlwZS5IYj15dCxZLnByb3RvdHlwZS5MYj15dCxZLk1iPS0yLGUuamI9aSxlLk1oPVksZS5TaWduYXR1cmU9S0pVUi5jcnlwdG8uU2lnbmF0dXJlLGUuSVM9S0pVUi5jcnlwdG8uSVMsZS5VYj1idCxlLmpoPUosZS5WYj1LfSxmdW5jdGlvbih0LGUpe1widXNlIHN0cmljdFwiO3ZhciBpPXt9O2kuUWI9ZnVuY3Rpb24oKXtyZXR1cm4gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyKDIsMTApfSxpLnFiPWkuUWIoKSxpLkpiPWZ1bmN0aW9uKHQpe3JldHVybiB0LnRyaW0oKS5zcGxpdChcIlxcblwiKS5tYXAoZnVuY3Rpb24odCl7cmV0dXJuIHQudHJpbSgpfSl9LGkuS2I9ZnVuY3Rpb24odCl7dmFyIGU9dC5zcGxpdChcIlxcbm09XCIpO3JldHVybiBlLm1hcChmdW5jdGlvbih0LGUpe3JldHVybihlPjA/XCJtPVwiK3Q6dCkudHJpbSgpK1wiXFxyXFxuXCJ9KX0saS5HYj1mdW5jdGlvbih0LGUpe3JldHVybiBpLkpiKHQpLmZpbHRlcihmdW5jdGlvbih0KXtyZXR1cm4gMD09PXQuaW5kZXhPZihlKX0pfSxpLnpiPWZ1bmN0aW9uKHQpe3ZhciBlO2U9MD09PXQuaW5kZXhPZihcImE9Y2FuZGlkYXRlOlwiKT90LnN1YnN0cmluZygxMikuc3BsaXQoXCIgXCIpOnQuc3Vic3RyaW5nKDEwKS5zcGxpdChcIiBcIik7Zm9yKHZhciBpPXtXYjplWzBdLCRiOmVbMV0scHJvdG9jb2w6ZVsyXS50b0xvd2VyQ2FzZSgpLFliOnBhcnNlSW50KGVbM10sMTApLFhiOmVbNF0scG9ydDpwYXJzZUludChlWzVdLDEwKSx0eXBlOmVbN119LHI9ODtyPGUubGVuZ3RoO3IrPTIpc3dpdGNoKGVbcl0pe2Nhc2VcInJhZGRyXCI6aS5aYj1lW3IrMV07YnJlYWs7Y2FzZVwicnBvcnRcIjppLnRFPXBhcnNlSW50KGVbcisxXSwxMCk7YnJlYWs7Y2FzZVwidGNwdHlwZVwiOmkuZUU9ZVtyKzFdO2JyZWFrO2RlZmF1bHQ6aVtlW3JdXT1lW3IrMV19cmV0dXJuIGl9LGkuaUU9ZnVuY3Rpb24odCl7dmFyIGU9W107ZS5wdXNoKHQuV2IpLGUucHVzaCh0LiRiKSxlLnB1c2godC5wcm90b2NvbC50b1VwcGVyQ2FzZSgpKSxlLnB1c2godC5ZYiksZS5wdXNoKHQuWGIpLGUucHVzaCh0LnBvcnQpO3ZhciBpPXQudHlwZTtyZXR1cm4gZS5wdXNoKFwidHlwXCIpLGUucHVzaChpKSxcImhvc3RcIiE9PWkmJnQuWmImJnQudEUmJihlLnB1c2goXCJyYWRkclwiKSxlLnB1c2godC5aYiksZS5wdXNoKFwicnBvcnRcIiksZS5wdXNoKHQudEUpKSx0LmVFJiZcInRjcFwiPT09dC5wcm90b2NvbC50b0xvd2VyQ2FzZSgpJiYoZS5wdXNoKFwidGNwdHlwZVwiKSxlLnB1c2godC5lRSkpLFwiY2FuZGlkYXRlOlwiK2Uuam9pbihcIiBcIil9LGkuckU9ZnVuY3Rpb24odCl7cmV0dXJuIHQuc3Vic3RyKDE0KS5zcGxpdChcIiBcIil9LGkubkU9ZnVuY3Rpb24odCl7dmFyIGU9dC5zdWJzdHIoOSkuc3BsaXQoXCIgXCIpLGk9e29FOnBhcnNlSW50KGUuc2hpZnQoKSwxMCl9O3JldHVybiBlPWVbMF0uc3BsaXQoXCIvXCIpLGkubmFtZT1lWzBdLGkuc0U9cGFyc2VJbnQoZVsxXSwxMCksaS5hRT0zPT09ZS5sZW5ndGg/cGFyc2VJbnQoZVsyXSwxMCk6MSxpfSxpLmNFPWZ1bmN0aW9uKHQpe3ZhciBlPXQub0U7cmV0dXJuIHZvaWQgMCE9PXQuaEUmJihlPXQuaEUpLFwiYT1ydHBtYXA6XCIrZStcIiBcIit0Lm5hbWUrXCIvXCIrdC5zRSsoMSE9PXQuYUU/XCIvXCIrdC5hRTpcIlwiKStcIlxcclxcblwifSxpLnBFPWZ1bmN0aW9uKHQpe3ZhciBlPXQuc3Vic3RyKDkpLnNwbGl0KFwiIFwiKTtyZXR1cm57aWQ6cGFyc2VJbnQoZVswXSwxMCksZGlyZWN0aW9uOmVbMF0uaW5kZXhPZihcIi9cIik+MD9lWzBdLnNwbGl0KFwiL1wiKVsxXTpcInNlbmRyZWN2XCIsdXJpOmVbMV19fSxpLnVFPWZ1bmN0aW9uKHQpe3JldHVyblwiYT1leHRtYXA6XCIrKHQuaWR8fHQucHJlZmVycmVkSWQpKyh0LmRpcmVjdGlvbiYmXCJzZW5kcmVjdlwiIT09dC5kaXJlY3Rpb24/XCIvXCIrdC5kaXJlY3Rpb246XCJcIikrXCIgXCIrdC51cmkrXCJcXHJcXG5cIn0saS5sRT1mdW5jdGlvbih0KXtmb3IodmFyIGUsaT17fSxyPXQuc3Vic3RyKHQuaW5kZXhPZihcIiBcIikrMSkuc3BsaXQoXCI7XCIpLG49MDtuPHIubGVuZ3RoO24rKyllPXJbbl0udHJpbSgpLnNwbGl0KFwiPVwiKSxpW2VbMF0udHJpbSgpXT1lWzFdO3JldHVybiBpfSxpLmRFPWZ1bmN0aW9uKHQpe3ZhciBlPVwiXCIsaT10Lm9FO2lmKHZvaWQgMCE9PXQuaEUmJihpPXQuaEUpLHQucGFyYW1ldGVycyYmT2JqZWN0LmtleXModC5wYXJhbWV0ZXJzKS5sZW5ndGgpe3ZhciByPVtdO09iamVjdC5rZXlzKHQucGFyYW1ldGVycykuZm9yRWFjaChmdW5jdGlvbihlKXtyLnB1c2goZStcIj1cIit0LnBhcmFtZXRlcnNbZV0pfSksZSs9XCJhPWZtdHA6XCIraStcIiBcIityLmpvaW4oXCI7XCIpK1wiXFxyXFxuXCJ9cmV0dXJuIGV9LGkuZkU9ZnVuY3Rpb24odCl7dmFyIGU9dC5zdWJzdHIodC5pbmRleE9mKFwiIFwiKSsxKS5zcGxpdChcIiBcIik7cmV0dXJue3R5cGU6ZS5zaGlmdCgpLGdFOmUuam9pbihcIiBcIil9fSxpLnZFPWZ1bmN0aW9uKHQpe3ZhciBlPVwiXCIsaT10Lm9FO3JldHVybiB2b2lkIDAhPT10LmhFJiYoaT10LmhFKSx0LnlFJiZ0LnlFLmxlbmd0aCYmdC55RS5mb3JFYWNoKGZ1bmN0aW9uKHQpe2UrPVwiYT1ydGNwLWZiOlwiK2krXCIgXCIrdC50eXBlKyh0LmdFJiZ0LmdFLmxlbmd0aD9cIiBcIit0LmdFOlwiXCIpK1wiXFxyXFxuXCJ9KSxlfSxpLm1FPWZ1bmN0aW9uKHQpe3ZhciBlPXQuaW5kZXhPZihcIiBcIiksaT17d0U6cGFyc2VJbnQodC5zdWJzdHIoNyxlLTcpLDEwKX0scj10LmluZGV4T2YoXCI6XCIsZSk7cmV0dXJuIHI+LTE/KGkuVEU9dC5zdWJzdHIoZSsxLHItZS0xKSxpLnZhbHVlPXQuc3Vic3RyKHIrMSkpOmkuVEU9dC5zdWJzdHIoZSsxKSxpfSxpLlNFPWZ1bmN0aW9uKHQpe3ZhciBlPWkuR2IodCxcImE9bWlkOlwiKVswXTtpZihlKXJldHVybiBlLnN1YnN0cig2KX0saS5iRT1mdW5jdGlvbih0KXt2YXIgZT10LnN1YnN0cigxNCkuc3BsaXQoXCIgXCIpO3JldHVybnthbGdvcml0aG06ZVswXS50b0xvd2VyQ2FzZSgpLHZhbHVlOmVbMV19fSxpLkVFPWZ1bmN0aW9uKHQsZSl7dmFyIHI9aS5HYih0K2UsXCJhPWZpbmdlcnByaW50OlwiKTtyZXR1cm57SUU6XCJhdXRvXCIsUkU6ci5tYXAoaS5iRSl9fSxpLmtFPWZ1bmN0aW9uKHQsZSl7dmFyIGk9XCJhPXNldHVwOlwiK2UrXCJcXHJcXG5cIjtyZXR1cm4gdC5SRS5mb3JFYWNoKGZ1bmN0aW9uKHQpe2krPVwiYT1maW5nZXJwcmludDpcIit0LmFsZ29yaXRobStcIiBcIit0LnZhbHVlK1wiXFxyXFxuXCJ9KSxpfSxpLkNFPWZ1bmN0aW9uKHQsZSl7dmFyIHI9aS5KYih0KTtyPXIuY29uY2F0KGkuSmIoZSkpO3ZhciBuPXtPRTpyLmZpbHRlcihmdW5jdGlvbih0KXtyZXR1cm4gMD09PXQuaW5kZXhPZihcImE9aWNlLXVmcmFnOlwiKX0pWzBdLnN1YnN0cigxMikscGFzc3dvcmQ6ci5maWx0ZXIoZnVuY3Rpb24odCl7cmV0dXJuIDA9PT10LmluZGV4T2YoXCJhPWljZS1wd2Q6XCIpfSlbMF0uc3Vic3RyKDEwKX07cmV0dXJuIG59LGkuUEU9ZnVuY3Rpb24odCl7cmV0dXJuXCJhPWljZS11ZnJhZzpcIit0Lk9FK1wiXFxyXFxuYT1pY2UtcHdkOlwiK3QucGFzc3dvcmQrXCJcXHJcXG5cIn0saS5BRT1mdW5jdGlvbih0KXtmb3IodmFyIGU9e05FOltdLHhFOltdLEJFOltdLEZFOltdfSxyPWkuSmIodCksbj1yWzBdLnNwbGl0KFwiIFwiKSxvPTM7bzxuLmxlbmd0aDtvKyspe3ZhciBzPW5bb10sYT1pLkdiKHQsXCJhPXJ0cG1hcDpcIitzK1wiIFwiKVswXTtpZihhKXt2YXIgYz1pLm5FKGEpLGg9aS5HYih0LFwiYT1mbXRwOlwiK3MrXCIgXCIpO3N3aXRjaChjLnBhcmFtZXRlcnM9aC5sZW5ndGg/aS5sRShoWzBdKTp7fSxjLnlFPWkuR2IodCxcImE9cnRjcC1mYjpcIitzK1wiIFwiKS5tYXAoaS5mRSksZS5ORS5wdXNoKGMpLGMubmFtZS50b1VwcGVyQ2FzZSgpKXtjYXNlXCJSRURcIjpjYXNlXCJVTFBGRUNcIjplLkJFLnB1c2goYy5uYW1lLnRvVXBwZXJDYXNlKCkpfX19cmV0dXJuIGkuR2IodCxcImE9ZXh0bWFwOlwiKS5mb3JFYWNoKGZ1bmN0aW9uKHQpe2UueEUucHVzaChpLnBFKHQpKX0pLGV9LGkuX0U9ZnVuY3Rpb24odCxlKXt2YXIgcj1cIlwiO3IrPVwibT1cIit0K1wiIFwiLHIrPWUuTkUubGVuZ3RoPjA/XCI5XCI6XCIwXCIscis9XCIgVURQL1RMUy9SVFAvU0FWUEYgXCIscis9ZS5ORS5tYXAoZnVuY3Rpb24odCl7cmV0dXJuIHZvaWQgMCE9PXQuaEU/dC5oRTp0Lm9FfSkuam9pbihcIiBcIikrXCJcXHJcXG5cIixyKz1cImM9SU4gSVA0IDAuMC4wLjBcXHJcXG5cIixyKz1cImE9cnRjcDo5IElOIElQNCAwLjAuMC4wXFxyXFxuXCIsZS5ORS5mb3JFYWNoKGZ1bmN0aW9uKHQpe3IrPWkuY0UodCkscis9aS5kRSh0KSxyKz1pLnZFKHQpfSk7dmFyIG49MDtyZXR1cm4gZS5ORS5mb3JFYWNoKGZ1bmN0aW9uKHQpe3QuREU+biYmKG49dC5ERSl9KSxuPjAmJihyKz1cImE9bWF4cHRpbWU6XCIrbitcIlxcclxcblwiKSxyKz1cImE9cnRjcC1tdXhcXHJcXG5cIixlLnhFLmZvckVhY2goZnVuY3Rpb24odCl7cis9aS51RSh0KX0pLHJ9LGkuSEU9ZnVuY3Rpb24odCl7dmFyIGUscj1bXSxuPWkuQUUodCksbz1uLkJFLmluZGV4T2YoXCJSRURcIikhPT0tMSxzPW4uQkUuaW5kZXhPZihcIlVMUEZFQ1wiKSE9PS0xLGE9aS5HYih0LFwiYT1zc3JjOlwiKS5tYXAoZnVuY3Rpb24odCl7cmV0dXJuIGkubUUodCl9KS5maWx0ZXIoZnVuY3Rpb24odCl7cmV0dXJuXCJjbmFtZVwiPT09dC5URX0pLGM9YS5sZW5ndGg+MCYmYVswXS53RSxoPWkuR2IodCxcImE9c3NyYy1ncm91cDpGSURcIikubWFwKGZ1bmN0aW9uKHQpe3ZhciBlPXQuc3BsaXQoXCIgXCIpO3JldHVybiBlLnNoaWZ0KCksZS5tYXAoZnVuY3Rpb24odCl7cmV0dXJuIHBhcnNlSW50KHQsMTApfSl9KTtoLmxlbmd0aD4wJiZoWzBdLmxlbmd0aD4xJiZoWzBdWzBdPT09YyYmKGU9aFswXVsxXSksbi5ORS5mb3JFYWNoKGZ1bmN0aW9uKHQpe2lmKFwiUlRYXCI9PT10Lm5hbWUudG9VcHBlckNhc2UoKSYmdC5wYXJhbWV0ZXJzLmFwdCl7dmFyIGk9e3dFOmMsTEU6cGFyc2VJbnQodC5wYXJhbWV0ZXJzLmFwdCwxMCksTUU6e3dFOmV9fTtyLnB1c2goaSksbyYmKGk9SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShpKSksaS5qRT17d0U6ZSxVRTpzP1wicmVkK3VscGZlY1wiOlwicmVkXCJ9LHIucHVzaChpKSl9fSksMD09PXIubGVuZ3RoJiZjJiZyLnB1c2goe3dFOmN9KTt2YXIgcD1pLkdiKHQsXCJiPVwiKTtyZXR1cm4gcC5sZW5ndGgmJigwPT09cFswXS5pbmRleE9mKFwiYj1USUFTOlwiKT9wPXBhcnNlSW50KHBbMF0uc3Vic3RyKDcpLDEwKTowPT09cFswXS5pbmRleE9mKFwiYj1BUzpcIikmJihwPXBhcnNlSW50KHBbMF0uc3Vic3RyKDUpLDEwKSksci5mb3JFYWNoKGZ1bmN0aW9uKHQpe3QuVkU9cH0pKSxyfSxpLlFFPWZ1bmN0aW9uKHQpe3ZhciBlPXt9LHI9aS5HYih0LFwiYT1zc3JjOlwiKS5tYXAoZnVuY3Rpb24odCl7cmV0dXJuIGkubUUodCl9KS5maWx0ZXIoZnVuY3Rpb24odCl7cmV0dXJuXCJjbmFtZVwiPT09dC5URX0pWzBdO3ImJihlLnFFPXIudmFsdWUsZS53RT1yLndFKTt2YXIgbj1pLkdiKHQsXCJhPXJ0Y3AtcnNpemVcIik7ZS5KRT1uLmxlbmd0aD4wLGUuS0U9MD09PW4ubGVuZ3RoO3ZhciBvPWkuR2IodCxcImE9cnRjcC1tdXhcIik7cmV0dXJuIGUuR0U9by5sZW5ndGg+MCxlfSxpLnpFPWZ1bmN0aW9uKHQpe3ZhciBlLHI9aS5HYih0LFwiYT1tc2lkOlwiKTtpZigxPT09ci5sZW5ndGgpcmV0dXJuIGU9clswXS5zdWJzdHIoNykuc3BsaXQoXCIgXCIpLHtzdHJlYW06ZVswXSx0cmFjazplWzFdfTt2YXIgbj1pLkdiKHQsXCJhPXNzcmM6XCIpLm1hcChmdW5jdGlvbih0KXtyZXR1cm4gaS5tRSh0KX0pLmZpbHRlcihmdW5jdGlvbih0KXtyZXR1cm5cIm1zaWRcIj09PXQuVEV9KTtyZXR1cm4gbi5sZW5ndGg+MD8oZT1uWzBdLnZhbHVlLnNwbGl0KFwiIFwiKSx7c3RyZWFtOmVbMF0sdHJhY2s6ZVsxXX0pOnZvaWQgMH0saS5XRT1mdW5jdGlvbigpe3JldHVyblwidj0wXFxyXFxubz10aGlzaXNhZGFwdGVyb3J0YyA4MTY5NjM5OTE1NjQ2OTQzMTM3IDIgSU4gSVA0IDEyNy4wLjAuMVxcclxcbnM9LVxcclxcbnQ9MCAwXFxyXFxuXCJ9LGkuJEU9ZnVuY3Rpb24odCxlLHIsbil7dmFyIG89aS5fRSh0LmtpbmQsZSk7aWYobys9aS5QRSh0LllFLmdldExvY2FsUGFyYW1ldGVycygpKSxvKz1pLmtFKHQuWEUuZ2V0TG9jYWxQYXJhbWV0ZXJzKCksXCJvZmZlclwiPT09cj9cImFjdHBhc3NcIjpcImFjdGl2ZVwiKSxvKz1cImE9bWlkOlwiK3QuWkUrXCJcXHJcXG5cIixvKz10LmRpcmVjdGlvbj9cImE9XCIrdC5kaXJlY3Rpb24rXCJcXHJcXG5cIjp0LnRJJiZ0LmVJP1wiYT1zZW5kcmVjdlxcclxcblwiOnQudEk/XCJhPXNlbmRvbmx5XFxyXFxuXCI6dC5lST9cImE9cmVjdm9ubHlcXHJcXG5cIjpcImE9aW5hY3RpdmVcXHJcXG5cIix0LnRJKXt2YXIgcz1cIm1zaWQ6XCIrbi5pZCtcIiBcIit0LnRJLnRyYWNrLmlkK1wiXFxyXFxuXCI7bys9XCJhPVwiK3Msbys9XCJhPXNzcmM6XCIrdC5pSVswXS53RStcIiBcIitzLHQuaUlbMF0uTUUmJihvKz1cImE9c3NyYzpcIit0LmlJWzBdLk1FLndFK1wiIFwiK3Msbys9XCJhPXNzcmMtZ3JvdXA6RklEIFwiK3QuaUlbMF0ud0UrXCIgXCIrdC5pSVswXS5NRS53RStcIlxcclxcblwiKX1yZXR1cm4gbys9XCJhPXNzcmM6XCIrdC5pSVswXS53RStcIiBjbmFtZTpcIitpLnFiK1wiXFxyXFxuXCIsdC50SSYmdC5pSVswXS5NRSYmKG8rPVwiYT1zc3JjOlwiK3QuaUlbMF0uTUUud0UrXCIgY25hbWU6XCIraS5xYitcIlxcclxcblwiKSxvfSxpLnJJPWZ1bmN0aW9uKHQsZSl7Zm9yKHZhciByPWkuSmIodCksbj0wO248ci5sZW5ndGg7bisrKXN3aXRjaChyW25dKXtjYXNlXCJhPXNlbmRyZWN2XCI6Y2FzZVwiYT1zZW5kb25seVwiOmNhc2VcImE9cmVjdm9ubHlcIjpjYXNlXCJhPWluYWN0aXZlXCI6cmV0dXJuIHJbbl0uc3Vic3RyKDIpfXJldHVybiBlP2kuckkoZSk6XCJzZW5kcmVjdlwifSxpLm5JPWZ1bmN0aW9uKHQpe3ZhciBlPWkuSmIodCkscj1lWzBdLnNwbGl0KFwiIFwiKTtyZXR1cm4gclswXS5zdWJzdHIoMil9LGkuVXQ9ZnVuY3Rpb24odCl7cmV0dXJuXCIwXCI9PT10LnNwbGl0KFwiIFwiLDIpWzFdfSx0LnQ9aX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPWkoMSksbj1pKDEwKSxvPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0LGUpe3RoaXMubXNnPXQsdGhpcy5vST1EYXRlLm5vdygpK2UsdGhpcy5zST1yLmRlZmVyKCl9cmV0dXJuIHQucHJvdG90eXBlLmFJPWZ1bmN0aW9uKCl7cmV0dXJuIERhdGUubm93KCk+PXRoaXMub0l9LHR9KCkscz1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlLGkscixuLG8scyl7dm9pZCAwPT09ZSYmKGU9M2U0KSx2b2lkIDA9PT1pJiYoaT0xMDApLHZvaWQgMD09PXImJihyPTNlNCksdm9pZCAwPT09biYmKG49MTVlMyksdm9pZCAwPT09byYmKG89RGF0ZSksdm9pZCAwPT09cyYmKHM9ITEpLHRoaXMuY0k9MSx0aGlzLmhJPS0xLHRoaXMucEk9LTEsdGhpcy51ST17fSx0aGlzLmxJPVtdLHRoaXMuZEk9W10sdGhpcy5mST0hMSx0aGlzLmdJPSEwLHRoaXMudkk9dCx0aGlzLnlJPUFycmF5KCksdGhpcy5Bbz1lLHRoaXMuTm89aSx0aGlzLnhvPXIsdGhpcy5tST1uLHRoaXMud0k9byx0aGlzLmZJPXN8fC9NU0lFIDEwL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KXx8L01TSUUgOS9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCl8fC9ydjoxMS4wL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KXx8L0VkZ2UuL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KX1yZXR1cm4gdC5wcm90b3R5cGUuRXQ9ZnVuY3Rpb24odCl7dmFyIGU9dC5zZXJ2aWNlK1wiX1wiK3QubXNnSWQsaT10aGlzLnVJW2VdO251bGwhPWk/aSh0KTpuLm0oKS5lcnJvcihuLnUrXCJDb3VsZCBub3QgZmluZCBhIGRpc3BhdGNoZXIgZm9yIFwiLHQsZSx0aGlzLnVJKX0sdC5wcm90b3R5cGUub249ZnVuY3Rpb24odCxlLGkpe3RoaXMudUlbdCtcIl9cIitlXT1pfSx0LnByb3RvdHlwZS5vbmVycm9yPWZ1bmN0aW9uKHQpe3RoaXMubEkucHVzaCh0KX0sdC5wcm90b3R5cGUuVEk9ZnVuY3Rpb24odCl7dGhpcy5kSS5wdXNoKHQpfSx0LnByb3RvdHlwZS5TST1mdW5jdGlvbigpe3ZhciB0PXRoaXM7aWYoIXdpbmRvdy5XZWJTb2NrZXQpcmV0dXJuIHZvaWQgdGhpcy5sSS5mb3JFYWNoKGZ1bmN0aW9uKHQpe3JldHVybiB0KFwiV2ViU29ja2V0IG5vdCBkZWZpbmVkXCIpfSk7dmFyIGU9bmV3IFdlYlNvY2tldCh0aGlzLnZJKTtyZXR1cm4gZS5iaW5hcnlUeXBlPVwiYXJyYXlidWZmZXJcIixlLm9ub3Blbj1mdW5jdGlvbihlKXt0LmJJKCksbi5tKCkuZGVidWcobi51K1wiSGl2ZVNlcnZpY2VzQ29ubmVjdGlvbiBlc3RhYmxpc2hlZCB0byBcIit0LnZJKSx0LnBJPShuZXcgdC53SSkuZ2V0VGltZSgpLHQuRUkoKSx0LmRJLmZvckVhY2goZnVuY3Rpb24oZSl7cmV0dXJuIGUodCl9KSx0LklJKCksdC5SSSgpfSxlLm9uY2xvc2U9ZnVuY3Rpb24oZSl7dC5jbG9zZSh0LmdJKSx0LmNvbm5lY3QoKX0sZS5vbm1lc3NhZ2U9ZnVuY3Rpb24oZSl7dC5FdChuLlpuLndvKGUuZGF0YSkpfSxlLm9uZXJyb3I9ZnVuY3Rpb24oZSl7dC5jbG9zZSghMCksdC5sSS5mb3JFYWNoKGZ1bmN0aW9uKHQpe3JldHVybiB0KGUudG9TdHJpbmcoKSl9KX0sZX0sdC5wcm90b3R5cGUuaXNPcGVuPWZ1bmN0aW9uKCl7cmV0dXJuIG51bGwhPXRoaXMuT3AmJnRoaXMuT3AucmVhZHlTdGF0ZT09dGhpcy5PcC5PUEVOfSx0LnByb3RvdHlwZS5jb25uZWN0PWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXM7dCYmKHRoaXMuZ0k9ITApLHRoaXMuZ0kmJjEhPXRoaXMuaXNPcGVuKCkmJih0aGlzLmhJPjB8fCh0aGlzLnBJPi0xJiYobmV3IHRoaXMud0kpLmdldFRpbWUoKS10aGlzLnBJPnRoaXMuQW8/KHRoaXMuY0k9bi5rZS55byx0aGlzLnBJPS0xKTp0aGlzLmNJPU1hdGgubWluKDIqdGhpcy5jSSx0aGlzLkFvKSx0aGlzLmhJPXdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ZS5oST0tMSxuLm0oKS5kZWJ1ZyhuLnUrXCJDb25uZWN0aW9uIGF0dGVtcHQgdG8gXCIrZS52SStcIiBbdDpcIitlLmNJK1wiIGhiOlwiK2UuZkkrXCJdXCIpLGUuT3A9ZS5TSSgpLGUuY0k9TWF0aC5tYXgoZS5jSSxuLmtlLnlvKX0sdGhpcy5jSSkpKX0sdC5wcm90b3R5cGUuYkk9ZnVuY3Rpb24oKXt0aGlzLmhJPi0xJiYoY2xlYXJUaW1lb3V0KHRoaXMuaEkpLHRoaXMuaEk9LTEpfSx0LnByb3RvdHlwZS5jbG9zZT1mdW5jdGlvbih0KXt0aGlzLmdJPXZvaWQgMCE9dCYmdCxuLm0oKS5kZWJ1ZyhuLnUrXCJDbG9zaW5nIGNvbm5lY3Rpb24gW3JlY29ubmVjdDpcIit0aGlzLmdJK1wiXVwiKSx0aGlzLmJJKCksbnVsbCE9dGhpcy5PcCYmKHRoaXMuT3AuY2xvc2UoKSx0aGlzLk9wPW51bGwpfSx0LnByb3RvdHlwZS5FST1mdW5jdGlvbigpe2Zvcig7dGhpcy55SS5sZW5ndGg+MDspe3ZhciB0PXRoaXMueUkucG9wKCk7dHJ5e3QuYUkoKT90LnNJLnJlamVjdChuZXcgRXJyb3IoXCJNZXNzYWdlIGV4cGlyZWRcIikpOih0aGlzLklJKCksdGhpcy5PcC5zZW5kKHQubXNnLm1vKCkpKX1jYXRjaChlKXtpZihlLmNvZGU9PT1ET01FeGNlcHRpb24uSU5WQUxJRF9TVEFURV9FUlIpe3RoaXMueUkucHVzaCh0KTticmVha31uLm0oKS5lcnJvcihuLnUrXCJGYWlsZWQgdG8gc2VuZCB0aGUgbWVzc2FnZSwgZHJvcHBlZDogXCIsZS5jb2RlLGUubmFtZSksdC5zSS5yZWplY3QoZSl9fXRoaXMuUkkoKX0sdC5wcm90b3R5cGUuSUk9ZnVuY3Rpb24oKXt0aGlzLmtJJiYoY2xlYXJUaW1lb3V0KHRoaXMua0kpLHRoaXMua0k9bnVsbCl9LHQucHJvdG90eXBlLlJJPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpczt0aGlzLmZJJiYhdGhpcy5rSSYmKHRoaXMua0k9d2luZG93LnNldEludGVydmFsKGZ1bmN0aW9uKCl7dC5zZW5kKG5ldyBuLlpuKFNlcnZpY2VzLkNmLDAsXCJcIikpfSx0aGlzLm1JKSl9LHQucHJvdG90eXBlLnNlbmQ9ZnVuY3Rpb24odCxlKXtpZih2b2lkIDA9PT1lJiYoZT10aGlzLnhvKSx0aGlzLnlJLmxlbmd0aD49dGhpcy5Obyl0aHJvdyBuZXcgRXJyb3IoXCJIaXZlU2VydmljZXMgY29ubmVjdGlvbiBjYW5ub3QgcXVldWUgbW9yZSBtZXNzYWdlc1wiKTt2YXIgaT1uZXcgbyh0LGUpO3JldHVybiB0aGlzLnlJLnB1c2goaSksdGhpcy5PcCYmdGhpcy5FSSgpLGkuc0kudnR9LHQucHJvdG90eXBlLkNJPWZ1bmN0aW9uKHQpe3RoaXMuZkk9dCx0aGlzLmZJJiZ0aGlzLlJJKCl9LHQucHJvdG90eXBlLk9JPWZ1bmN0aW9uKCl7cmV0dXJuIG51bGwhPXRoaXMuT3B9LHR9KCk7ZS5BST1zfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI9aSgxNSksbj1pKDM4KSxvPWkoMjQpLHM9aSgyKSxhPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdC5wcm90b3R5cGUuYXBwbHk9ZnVuY3Rpb24odCl7dC5iaW5kKG5ldyByLm5zKHMuRnJhbWV3b3JrLkZlLm1lLG4uTkksci5zcy5scykpLHQuYmluZChuZXcgci5ucyhzLkZyYW1ld29yay5GZS53ZSxvLkVsLmJsKSl9LHR9KCk7ZS5UZD1hfSxmdW5jdGlvbih0LGUpe1widXNlIHN0cmljdFwiO3ZhciBpPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe1widW5kZWZpbmVkXCIhPXR5cGVvZiBnbG9iYWw/dGhpcy54ST1nbG9iYWw6dGhpcy54ST13aW5kb3d9cmV0dXJuIHQucHJvdG90eXBlLkN0PWZ1bmN0aW9uKCl7cmV0dXJuITF9LHQucHJvdG90eXBlLkJJPWZ1bmN0aW9uKHQsZSxpKXt9LHQucHJvdG90eXBlLmJlPWZ1bmN0aW9uKCl7fSx0LnByb3RvdHlwZS50aW1lPWZ1bmN0aW9uKCl7cmV0dXJuK25ldyBEYXRlfSx0LnByb3RvdHlwZS5zZXRUaW1lb3V0PWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcy54SS5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dCgpfSxlKTtyZXR1cm4gaX0sdC5wcm90b3R5cGUuY2xlYXJUaW1lb3V0PWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLnhJLmNsZWFyVGltZW91dCh0KSwhMH0sdC5wcm90b3R5cGUuc2V0SW50ZXJ2YWw9ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzLnhJLnNldEludGVydmFsKGZ1bmN0aW9uKCl7dCgpfSxlKTtyZXR1cm4gaX0sdC5wcm90b3R5cGUuY2xlYXJJbnRlcnZhbD1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy54SS5jbGVhckludGVydmFsKHQpLCEwfSx0fSgpO2UuTkk9aX0sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjt2YXIgaT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlKXt0aGlzLlVvPXQsdGhpcy5Wbz1lfXJldHVybiB0LnByb3RvdHlwZS5Xbz1mdW5jdGlvbigpe3JldHVybiB0aGlzLlVvfSx0LnByb3RvdHlwZS4kbz1mdW5jdGlvbigpe3JldHVybiB0aGlzLlZvP3RoaXMuVm86dGhpcy5Vb30sdH0oKTtlLkZJPWl9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcixuPXRoaXMmJnRoaXMuX19leHRlbmRzfHxmdW5jdGlvbih0LGUpe2Z1bmN0aW9uIGkoKXt0aGlzLmNvbnN0cnVjdG9yPXR9Zm9yKHZhciByIGluIGUpZS5oYXNPd25Qcm9wZXJ0eShyKSYmKHRbcl09ZVtyXSk7dC5wcm90b3R5cGU9bnVsbD09PWU/T2JqZWN0LmNyZWF0ZShlKTooaS5wcm90b3R5cGU9ZS5wcm90b3R5cGUsbmV3IGkpfSxvPWkoOCkscz1vLnB0LklyLklyLGE9by5wdC5Jci5rcjshZnVuY3Rpb24odCl7dmFyIGU7IWZ1bmN0aW9uKHQpe3ZhciBlPWZ1bmN0aW9uKHQpe2Z1bmN0aW9uIGUoKXt2YXIgZT1udWxsIT09dCYmdC5hcHBseSh0aGlzLGFyZ3VtZW50cyl8fHRoaXM7cmV0dXJuIGUuYXV0aFRva2VuRW5hYmxlZD0hMCxlLmRhc2hSZW1vdmVCaXRyYXRlU2l6ZT0hMSxlLmRhc2hGaWx0ZXJCaXRyYXRlcz1udWxsLGUubG9nSnNvblNuYXBzaG90cz12b2lkIDAsZX1yZXR1cm4gbihlLHQpLGV9KHMpO3QuRmw9ZTt2YXIgaT1mdW5jdGlvbih0KXtmdW5jdGlvbiBlKCl7dmFyIGU9bnVsbCE9PXQmJnQuYXBwbHkodGhpcyxhcmd1bWVudHMpfHx0aGlzO3JldHVybiBlLmhpdmVBdXRoVG9rZW5FbmFibGVkPVwiYXV0aFRva2VuRW5hYmxlZFwiLGUuaGl2ZURhc2hSZW1vdmVCaXRyYXRlU2l6ZT1cImRhc2hSZW1vdmVCaXRyYXRlU2l6ZVwiLGUuaGl2ZURhc2hGaWx0ZXJCaXRyYXRlcz1cImRhc2hGaWx0ZXJCaXRyYXRlc1wiLGUuaGl2ZUxvZ0pzb25TbmFwc2hvdHM9XCJsb2dKc29uU25hcHNob3RzXCIsZX1yZXR1cm4gbihlLHQpLGV9KGEpO3QuRGw9aX0oZT10LklyfHwodC5Jcj17fSkpfShyPWUucHR8fChlLnB0PXt9KSk7dmFyIGM9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7fXJldHVybiB0LkhsPWZ1bmN0aW9uKHQpe1wiZGFzaFJlbW92ZUJpdHJhdGVTaXplXCJpbiB0JiZ0LmRhc2hSZW1vdmVCaXRyYXRlU2l6ZSYmd2luZG93LkhpdmVDb25maWcmJndpbmRvdy5IaXZlQ29uZmlnLkRhc2gmJih3aW5kb3cuSGl2ZUNvbmZpZy5EYXNoLkRhc2hSZW1vdmVCaXRyYXRlU2l6ZT10LmRhc2hSZW1vdmVCaXRyYXRlU2l6ZSksXCJkYXNoRmlsdGVyQml0cmF0ZXNcImluIHQmJnQuZGFzaEZpbHRlckJpdHJhdGVzJiZ3aW5kb3cuSGl2ZUNvbmZpZyYmd2luZG93LkhpdmVDb25maWcuRGFzaCYmKHdpbmRvdy5IaXZlQ29uZmlnLkRhc2guRGFzaEZpbHRlckJpdHJhdGVzPXQuZGFzaEZpbHRlckJpdHJhdGVzKSxcImxvZ0pzb25TbmFwc2hvdHNcImluIHQmJnQubG9nSnNvblNuYXBzaG90cyYmd2luZG93LkhpdmVDb25maWcmJndpbmRvdy5IaXZlQ29uZmlnLkRlYnVnTG9ncyYmKHdpbmRvdy5IaXZlQ29uZmlnLkRlYnVnTG9ncy5NZXRyaWNTbmFwc2hvdExvZ3M9MSx3aW5kb3cuSGl2ZUNvbmZpZy5EZWJ1Z0xvZ3MuVHJhY2tTbmFwc2hvdExvZ3M9MSx3aW5kb3cuSGl2ZUNvbmZpZy5EZWJ1Z0xvZ3MuZ2w9MSl9LHR9KCk7ZS5MbD1jfSxmdW5jdGlvbih0LGUpe1widXNlIHN0cmljdFwiO3ZhciBpPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3ZhciBlPXRoaXM7aWYodGhpcy5fST1uZXcgQXJyYXksdGhpcy5jYWxsYmFja3M9bmV3IEFycmF5LHQuR2kpdGhyb3cgbmV3IEVycm9yKFwiRXJyb3I6IEluc3RhbnRpYXRpb24gZmFpbGVkOiBVc2UgS2V5SGFuZGxlckhpdmVDb21tLmdldEluc3RhbmNlKCkgaW5zdGVhZCBvZiBuZXcuXCIpO3ZhciBpPXt9O2RvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoXCJrZXlkb3duXCIsZnVuY3Rpb24odCl7aVt0LmtleUNvZGVdPSEwLGUuREkoaSl9LCEwKSxkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwia2V5dXBcIixmdW5jdGlvbih0KXtpPXt9fSwhMCl9cmV0dXJuIHQuV2k9ZnVuY3Rpb24oKXtyZXR1cm4gdm9pZCAwPT09dGhpcy5HaSYmKHRoaXMuR2k9bmV3IHQpLHRoaXMuR2l9LHQucHJvdG90eXBlLkRoPWZ1bmN0aW9uKHQsZSl7dGhpcy5fSS5wdXNoKHQpLHRoaXMuY2FsbGJhY2tzLnB1c2goZSl9LHQucHJvdG90eXBlLkRJPWZ1bmN0aW9uKHQpe2Zvcih2YXIgZT1mdW5jdGlvbihlKXt2YXIgcj0hMDtpLl9JW2VdLmZvckVhY2goZnVuY3Rpb24oZSl7dm9pZCAwIT10W2VdJiZ0W2VdfHwocj0hMSl9KSxyJiZpLmNhbGxiYWNrc1tlXSgpfSxpPXRoaXMscj0wO3I8dGhpcy5fSS5sZW5ndGg7cisrKWUocil9LHR9KCk7ZS5IaD1pfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI9aSgxMiksbj1pKDE4KSxvPWkoNykscz1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCl7dGhpcy5IST1uLmtlLnlyPzk5ODk6OTk4OCx0aGlzLkxJPS0xLHRoaXMuTUk9dCx0aGlzLmpJKCl9cmV0dXJuIHQucHJvdG90eXBlLmpJPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpczt0aGlzLk1JLm9wdGlvbnMoKS5zaWxlbnQmJnZvaWQgMD09PXRoaXMuVUkmJih0aGlzLnVybD1cIi8vXCIrci53ci5UbytcIjpcIit0aGlzLkhJK1wiL2ZlZWRiYWNrXCIsdGhpcy5NSS5tKCkuaW5mbyhcInN0YXJ0aW5nIHBlcmlvZGljIGFsaXZlIHBpbmcgdG8gaGl2ZSB0ZXN0ZXIgW1wiK3RoaXMudXJsK1wiXVwiKSx0aGlzLlVJPXNldEludGVydmFsKGZ1bmN0aW9uKCl7dC5WSSgpfSxuLmtlLk5oKSl9LHQucHJvdG90eXBlLlZJPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxlPXRoaXMuTUkuZ2V0Q3VycmVudFRpbWUoKTtlPnRoaXMuTEk/KHRoaXMuTUkubSgpLmluZm8oXCJzZW5kaW5nIGhpdmUgdGVzdGVyIHBpbmcgW1wiK2UrXCIgPiBcIit0aGlzLkxJK1wiXVwiKSxvLlppKHRoaXMudXJsKS50aGVuKGZ1bmN0aW9uKHQpe30sZnVuY3Rpb24oZSl7dC5NSS5tKCkuZXJyb3IoXCJlcnJvciBzZW5kaW5nIGhpdmUgdGVzdGVyIHBpbmdcIixlKSxjbGVhckludGVydmFsKHQuVUkpfSkpOnRoaXMuTUkubSgpLndhcm4oXCJub3Qgc2VuZGluZyBoaXZlIHRlc3RlciBwaW5nIFtcIitlK1wiIDw9IFwiK3RoaXMuTEkrXCJdXCIpLHRoaXMuTEk9ZX0sdH0oKTtlLlVsPXN9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcj10aGlzJiZ0aGlzLl9fZXh0ZW5kc3x8ZnVuY3Rpb24odCxlKXtmdW5jdGlvbiBpKCl7dGhpcy5jb25zdHJ1Y3Rvcj10fWZvcih2YXIgciBpbiBlKWUuaGFzT3duUHJvcGVydHkocikmJih0W3JdPWVbcl0pO3QucHJvdG90eXBlPW51bGw9PT1lP09iamVjdC5jcmVhdGUoZSk6KGkucHJvdG90eXBlPWUucHJvdG90eXBlLG5ldyBpKX0sbj1pKDEpLG89aSg3KSxzPWkoOCksYT1pKDQ0KSxjPWkoMTcpLGg9aSgxMikscD1pKDE0KSx1PWkoOSksbD1pKDIwKSxkPWkoMTkpLGY9YS5wdC5JcixnPXMucHQuSXIua3Isdj1jLnB0LkhpdmVUZWNoRXJyb3IseT1jLnB0LmJoLG09aSgyOCk7ZS5RST1uYXZpZ2F0b3I7dmFyIHc9ZnVuY3Rpb24odCl7ZnVuY3Rpb24gZSgpe3JldHVybiBudWxsIT09dCYmdC5hcHBseSh0aGlzLGFyZ3VtZW50cyl8fHRoaXN9cmV0dXJuIHIoZSx0KSxlfShvLkJpKSxUPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0LGUpe3RoaXMucUk9MCx0aGlzLk1JPXQsdGhpcy5vcHRpb25zXz1uZXcgZi5KSSx0aGlzLktJKGUpLG8ub3Iod2luZG93LmxvY2F0aW9uLmhyZWYsbmV3IGcsdGhpcy5vcHRpb25zXyl9cmV0dXJuIHQucHJvdG90eXBlLkFpPWZ1bmN0aW9uKCl7cmV0dXJuIHQuSmx9LHQucHJvdG90eXBlLmdldFZlcnNpb249ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy52ZXJzaW9ufSx0LnByb3RvdHlwZS5XbD1mdW5jdGlvbigpe3JldHVybiExfSx0LnByb3RvdHlwZS5HST1mdW5jdGlvbigpe3ZhciB0PXRoaXM7aWYobnVsbD09dGhpcy56SXx8RGF0ZS5ub3coKS10aGlzLnFJPjFlNCl7dmFyIGU9bmV3IG07ZS5JbihuYXZpZ2F0b3IudXNlckFnZW50KTt2YXIgaT1lLiRkKCk7aWYoXCJJRVwiPT09aS5uYW1lJiZpLnZlcnNpb24mJnBhcnNlSW50KGkudmVyc2lvbik8MTApcmV0dXJuIG4ucmVqZWN0KG5ldyB2KHkueWgsXCJJbnRlcm5ldCBFeHBsb3JlciA8IHYuMTAgbm90IHN1cHBvcnRlZFwiKSk7dGhpcy5XST1EYXRlLm5vdygpLHRoaXMuJEk9MDt2YXIgcj1cIi8vXCIraC53ci5UbytcIjpcIit0aGlzLk1JLm9wdGlvbnMoKS5tb25pdG9yUG9ydCtcIi92ZXJzaW9uLmpzb25cIjt0aGlzLm0oKS5kZWJ1Zyh0aGlzLmlkKCkrXCJ2ZXJpZnlpbmcgSGl2ZSBDbGllbnQgdmVyc2lvblwiKSx0aGlzLnpJPW8uWmkocikudGhlbihmdW5jdGlvbihlKXt2YXIgaT1KU09OLnBhcnNlKGUpO3JldHVybiB0LnN0YXRlPWkuc3RhdGUsdC52ZXJzaW9uPWkudmVyc2lvbixcInJlYWR5XCI9PT10LnN0YXRlP1wiZGV2ZWxvcGVyXCI9PT10LnZlcnNpb258fHQudmVyc2lvbj49dC5vcHRpb25zXy5taW5WZXJzaW9uPyh0LiRJPURhdGUubm93KCksdC5tKCkuZGVidWcodC5pZCgpK1wiSGl2ZSBDbGllbnQgcmVhZHkgLSB2ZXJzaW9uIFwiK3QudmVyc2lvbitcIiBbXCIrKHQuJEktdC5XSSkrXCJdXCIpLFwicmVhZHlcIik6KGQuRXJyb3JNb25pdG9yLldpKCkuX2godC5pZCgpK1wiQ2xpZW50IHZlcnNpb24gcmVxdWlyZW1lbnQgbm90IHNhdGlzZmllZDogXCIrdC52ZXJzaW9uK1wiIDwgXCIrdC5vcHRpb25zXy5taW5WZXJzaW9uKSx0Lk1JLmVkKG5ldyB1LkYudW8obnVsbCx1LkYuR3IuUXIpKSxuLnJlamVjdChuZXcgdih5LlRoLFwidmVyc2lvbiBcIit0LnZlcnNpb24pKSk6KGQuRXJyb3JNb25pdG9yLldpKCkuX2godC5pZCgpK1wiQ2xpZW50IHN0YXRlOiBcIit0LnN0YXRlKSx0Lk1JLmVkKG5ldyB1LkYudW8obnVsbCx1LkYuR3IuVnIpKSxuLnJlamVjdChuZXcgdih5LnloLFwic3RhdGUgXCIrdC5zdGF0ZSkpKX0sZnVuY3Rpb24oZSl7dmFyIGk9XCJDbGllbnQgbm90IHJlYWNoYWJsZVwiO3JldHVybiB2b2lkIDAhPWUmJnZvaWQgMCE9ZS5zdGF0dXMmJmUuc3RhdHVzIT0tMSYmKGk9XCJDbGllbnQgY2hlY2sgcmV0dXJuZWQgXCIrZS5zdGF0dXMpLGQuRXJyb3JNb25pdG9yLldpKCkuX2godC5pZCgpK2kpLHQuTUkuZWQobmV3IHUuRi51byhudWxsLHUuRi5Hci5VcikpLG4ucmVqZWN0KG5ldyB2KHkueWgsaSkpfSlbXCJjYXRjaFwiXShmdW5jdGlvbihlKXtpZihlIGluc3RhbmNlb2YgdilyZXR1cm4gbi5yZWplY3QoZSk7dmFyIGk9XCJFcnJvciBmZXRjaGluZyBIaXZlIENsaWVudCB2ZXJzaW9uOiBcIitlO3JldHVybiBkLkVycm9yTW9uaXRvci5XaSgpLl9oKHQuaWQoKStpKSxuLnJlamVjdChuZXcgdih5LnloLGkpKX0pLHRoaXMucUk9RGF0ZS5ub3coKX1yZXR1cm4gdGhpcy56SX0sdC5wcm90b3R5cGUuaW5pdFNlc3Npb249ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzO3JldHVybiB0aGlzLm9wdGlvbnNfLm1pblZlcnNpb24hPWgud3IuSW8/dGhpcy5HSSgpLnRoZW4oZnVuY3Rpb24oKXtyZXR1cm4gaS5ZSSh0KVtcImNhdGNoXCJdKGZ1bmN0aW9uKHQpe3JldHVybiBuLnJlamVjdCh0KX0pfSk6dGhpcy5ZSSh0KVtcImNhdGNoXCJdKGZ1bmN0aW9uKHQpe3JldHVybiBuLnJlamVjdCh0KX0pfSx0LnByb3RvdHlwZS5ZbD1mdW5jdGlvbigpe3JldHVybiB0aGlzLm9wdGlvbnNfLmluaXRUaW1lb3V0fSx0LnByb3RvdHlwZS5zdD1mdW5jdGlvbih0LGUpe3JldHVybiB0LmluZGV4T2YoZS5YSSk+LTF9LHQucHJvdG90eXBlLlBpPWZ1bmN0aW9uKHQsaSl7dmFyIHI9dGhpczt0aGlzLm0oKS5kZWJ1Zyh0aGlzLmlkKCkrXCJTdG9wcGluZyBzZXNzaW9uIFwiK3QuaWQrXCIgW2NvbXBsZXRlIGNsb3NlOlwiK2krXCJdXCIpO3ZhciBuPVwiLy9cIitoLndyLlRvK1wiOlwiK3RoaXMuTUkub3B0aW9ucygpLnBsYXllclBvcnQrXCIvc2Vzc2lvbj9hY3Rpb249c3RvcFwiO24rPVwiJmN1cnJlbnRTZXNzaW9uPVwiK3QuaWQsaSYmKG4rPVwiJmNvbXBsZXRlU3RvcD10cnVlXCIpLGkmJmUuUUkuc2VuZEJlYWNvbj8oZS5RSS5zZW5kQmVhY29uKG4pLHRoaXMubSgpLmRlYnVnKHRoaXMuaWQoKStcInNlc3Npb24gc3RvcHBlZCBbXCIrdC5pZCtcIl1bYmVhY29uXVwiKSk6by5aaShuLG51bGwsIWkpLnRoZW4oZnVuY3Rpb24oKXtyLm0oKS5kZWJ1ZyhyLmlkKCkrXCJzZXNzaW9uIHN0b3BwZWQgW1wiK3QuaWQrXCJdXCIrKGk/XCJbc3luY11cIjpcIlwiKSl9LGZ1bmN0aW9uKGUpe3IubSgpLndhcm4oci5pZCgpK1wic2Vzc2lvbiBjbG9zZSBlcnJvciBbXCIrdC5pZCtcIl1cIisoaT9cIltzeW5jXVwiOlwiXCIpLGUpfSl9LHQucHJvdG90eXBlLkNpPWZ1bmN0aW9uKHQsZSl7dGhpcy5aST1lP3AuRm8uSURMRTpwLkZvLkJvLHRoaXMubSgpLm5vdGljZShcIltIaXZlQ29tbV0gY2xpZW50IHN0YXRlOiBcIitwLkZvW3RoaXMuWkldKX0sdC5wcm90b3R5cGUuZmQ9ZnVuY3Rpb24odCxlKXtpZih0aGlzLlpJPT1wLkZvLklETEUpcmV0dXJuIG4ucmVzb2x2ZSghMCk7dmFyIGk9XCJwbGF5aW5nLXBvaW50PVwiK2UubHI7aSs9XCImYnVmZmVyLWxlbmd0aD1cIitlLmRyLGkrPVwiJnRvdGFsLWJ1ZmZlcmluZz1cIitlLmdyLGkrPVwiJndpZHRoPVwiK2Uud2lkdGgsaSs9XCImaGVpZ2h0PVwiK2UuaGVpZ2h0LGkrPVwiJmZ1bGxzY3JlZW49XCIrZS5kZDt2YXIgcj10LlhJK1wic3RhdHM/XCIraTtyZXR1cm4gdGhpcy5tKCkudHJhY2Uociksby5aaShyKX0sdC5wcm90b3R5cGUueWQ9ZnVuY3Rpb24odCxlLGkpe3ZhciByPXRoaXM7aWYoIShlIT09dS5GLkIuanImJmUhPT11LkYuQi5ISURERU58fHRoaXMudmVyc2lvbiYmKFwiZGV2ZWxvcGVyXCI9PT10aGlzLnZlcnNpb258fHRoaXMudmVyc2lvbj49XCIyMDE3XCIpKSlyZXR1cm4gbi5yZXNvbHZlKCEwKTt2YXIgcz10LlhJK1wicGxheWVyLWV2ZW50P3R5cGU9XCIrdS5GLkJbZV07aWYodm9pZCAwIT1pKWZvcih2YXIgYSBpbiBpKXMrPVwiJlwiK2ErXCI9XCIraVthXTtyZXR1cm4gdGhpcy5tKCkuZGVidWcodGhpcy5pZCgpK1wiZXZlbnQgXCIrdS5GLkJbZV0sdm9pZCAwIT1pP2k6XCJcIiksby5aaShzKS5mYWlsKGZ1bmN0aW9uKHQpe3JldHVybiByLm0oKS53YXJuKHIuaWQoKStcImVycm9yIHNlbmRpbmcgZmVlZGJhY2sgZXZlbnQgdG8gSGl2ZSBDbGllbnRcIix0KSxuLnJlamVjdCh0KX0pfSx0LnByb3RvdHlwZS53bj1mdW5jdGlvbih0LGUpe3JldHVybiBuLnJlc29sdmUoITApfSx0LnByb3RvdHlwZS5obj1mdW5jdGlvbih0KXt2YXIgZT10aGlzO2lmKHRoaXMudFIoKSlyZXR1cm4gdGhpcy5tKCkud2FybihcIlBsYXllciBpbmZvIG5vdCBzdXBwb3J0ZWQgaW4gdGhpcyBKYXZhIGNsaWVudCB2ZXJzaW9uXCIpLG4ucmVzb2x2ZSghMCk7dmFyIGk9XCJjb21tLXZlcnNpb249XCIrdGhpcy5NSS5jdCgpO2krPVwiJnBsdWdpbi1uYW1lPVwiK3RoaXMuTUkuVCgpLGkrPVwiJnBsdWdpbi12ZXJzaW9uPVwiK3RoaXMuTUkuSSgpLGkrPVwiJnBsYXllci10ZWNoPVwiK3RoaXMuTUkuaHQoKSxpKz1cIiZwbGF5ZXItdmVyc2lvbj1cIit0aGlzLk1JLnEoKTt2YXIgcj10aGlzLk1JLnRkKCk7ciYmKGkrPVwiJnRlbGVtZXRyeS1pZD1cIit0aGlzLk1JLnRkKCkpO3ZhciBzPXQuWEkrXCJwbGF5ZXItaW5mbz9cIitpO3JldHVybiBvLlppKHMpLmZhaWwoZnVuY3Rpb24odCl7cmV0dXJuIGUubSgpLmRlYnVnKGUuaWQoKStcImVycm9yIHNlbmRpbmcgcGxheWVyIEluZm8gdG8gSGl2ZSBDbGllbnRcIix0KSxuLnJlamVjdCh0KX0pfSx0LnByb3RvdHlwZS5vbkVycm9yPWZ1bmN0aW9uKHQpe3ZhciBlPSEwO2lmKHZvaWQgMCE9dGhpcy5vcHRpb25zXy5vbkVycm9yKXRyeXtlPXRoaXMub3B0aW9uc18ub25FcnJvcih0KX1jYXRjaChpKXtkLkVycm9yTW9uaXRvci5XaSgpLl9oKHRoaXMuaWQoKStcImV4Y2VwdGlvbiBpbiB1c2VyLWRlZmluZWQgb25FcnJvciBjYWxsYmFjazogXCIraSl9cmV0dXJuIGV9LHQucHJvdG90eXBlLlpsPWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj17aXNSZWFkeUluOnRoaXMuV0ksaXNSZWFkeU91dDp0aGlzLiRJLGxlYXNlSW46dGhpcy5lUixsZWFzZU91dDp0aGlzLmlSLHJlc29sdmVJbjp0aGlzLnJSLHJlc29sdmVPdXQ6dGhpcy5uUn07XCJ1bmRlZmluZWRcIiE9dHlwZW9mIGUmJm51bGwhPWUmJihyLnNlc3Npb25JZD1lLmlkKSxcInVuZGVmaW5lZFwiIT10eXBlb2YgaSYmKHIudG90YWw9aSk7dmFyIG49SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShyKSk7ZC5FcnJvck1vbml0b3IuV2koKS5faCh0Lm1lc3NhZ2UsbiksdGhpcy5NSS5lZChuZXcgdS5GLnVvKG51bGwsdS5GLkdyLktyLHIpKSx0aGlzLm9SKCl9LHQucHJvdG90eXBlLm9uQWN0aXZlU2Vzc2lvbj1mdW5jdGlvbih0KXtpZih0aGlzLmhuKHQpLG8uYXIuc2V0SXRlbShcImhpdmVBY3RpdmVTZXNzaW9uSWRcIix0LmlkKSx2b2lkIDAhPXRoaXMub3B0aW9uc18ub25BY3RpdmVTZXNzaW9uKXRyeXt0aGlzLm9wdGlvbnNfLm9uQWN0aXZlU2Vzc2lvbih0LmcoKSl9Y2F0Y2goZSl7ZC5FcnJvck1vbml0b3IuV2koKS5faCh0aGlzLmlkKCkrXCJleGNlcHRpb24gaW4gdXNlci1kZWZpbmVkIG9uQWN0aXZlU2Vzc2lvbiBjYWxsYmFjazogXCIrZSl9fSx0LnByb3RvdHlwZS5xbD1mdW5jdGlvbih0KXt0aGlzLk1JPXR9LHQucHJvdG90eXBlLmlkPWZ1bmN0aW9uKCl7cmV0dXJuXCJbXCIrdC5KbCtcIl0gXCJ9LHQucHJvdG90eXBlLktJPWZ1bmN0aW9uKGUpe3ZvaWQgMCE9ZVt0LkpsXSYmby5ucihlW3QuSmxdLHRoaXMub3B0aW9uc18pfSx0LnByb3RvdHlwZS5ZST1mdW5jdGlvbih0KXt2YXIgZT10aGlzLGk9KG5ldyBEYXRlKS5nZXRUaW1lKCk7cmV0dXJuIHRoaXMuc1IodCkudGhlbihmdW5jdGlvbihyKXtyZXR1cm4gcj9lLmFSKHQscixpKTplLnAodCkudGhlbihmdW5jdGlvbihyKXtyZXR1cm4gZS5hUih0LHIsaSl9KX0pfSx0LnByb3RvdHlwZS5zUj1mdW5jdGlvbihlKXt2YXIgaT10aGlzO2lmKHRoaXMuZVI9RGF0ZS5ub3coKSx0aGlzLk1JLm9wdGlvbnMoKS51c2VTZXNzaW9uQ2hlY2spe3ZhciByPVwiLy9cIitoLndyLlRvK1wiOlwiK3RoaXMuTUkub3B0aW9ucygpLnBsYXllclBvcnQrXCIvc2Vzc2lvbj8mYWN0aW9uPWNoZWNrXCI7cis9XCImaGl2ZVBsdWdpbklkPVwiK3RoaXMuTUkuUygpLHIrPVwiJmNhbGxiYWNrPVwiK2U7dmFyIHM9by5hci5nZXRJdGVtKFwiaGl2ZUFjdGl2ZVNlc3Npb25JZFwiKTtyZXR1cm4gby5hci5yZW1vdmVJdGVtKFwiaGl2ZUFjdGl2ZVNlc3Npb25JZFwiKSxzJiYocis9XCImY3VycmVudFNlc3Npb249XCIrcyksdGhpcy5jUigpLG8uWmkocikudGhlbihmdW5jdGlvbih0KXtyZXR1cm4gaS5pUj1EYXRlLm5vdygpLHQ/aS5oUih0LHIsZSxpLmVSKTooaS5tKCkuZGVidWcoaS5pZCgpK1wic2Vzc2lvbiBhbGxvd2VkIFtcIisoaS5pUi1pLmVSKStcIl1cIiksITEpfSxmdW5jdGlvbihlKXtpZig0MDA9PWUuc3RhdHVzKXJldHVybiBpLnBSKFwiYmFkIHJlcXVlc3RcIixcImVycm9yIHJlc29sdmluZyB0aWNrZXRcIixlKTtpZig0MDE9PWUuc3RhdHVzKXJldHVybiBpLnBSKFwidW5hdXRob3JpemVkXCIsXCJlcnJvciB2ZXJpZnlpbmcgdGhlIHRpY2tldFwiLGUpO2lmKDQwMz09ZS5zdGF0dXMpe3ZhciByPXQudVIoZSx2b2lkIDAsXCJzZXNzaW9uXCIpLG89cj97bFI6cn06dm9pZCAwO3JldHVybiBkLkVycm9yTW9uaXRvci5XaSgpLl9oKGkuaWQoKStcInJlcG9ydHMgYW5vdGhlciBhY3RpdmUgc2Vzc2lvblwiLG8pLGkuTUkuZWQobmV3IHUuRi51byhudWxsLHUuRi5Hci5xcixvKSksbi5yZWplY3QobmV3IHYoeS53aCxcImFub3RoZXIgYWN0aXZlIHNlc3Npb25cIisobz9cIiBbXCIrby5sUitcIl1cIjpcIlwiKSkpfXJldHVybiA0MDQ9PWUuc3RhdHVzPyhpLm0oKS5kZWJ1ZyhpLmlkKCkrXCJpbnN0YWxsZWQgdmVyc2lvbiBkb2VzIG5vdCBzdXBwb3J0IGFjdGl2ZSBzZXNzaW9uIGNoZWNrXCIpLGkuaVI9RGF0ZS5ub3coKSwhMSk6ZS5zdGF0dXM9PS0xPyhjbGVhclRpbWVvdXQoaS5kUiksaS5mUigpKTooZC5FcnJvck1vbml0b3IuV2koKS5faChpLmlkKCkrXCIgdW5oYW5kbGVkIGVycm9yIGZyb20gSmF2YVwiLHtlcnJvcjplLnN0YXR1c30pLGkuTUkuZWQobmV3IHUuRi51byhudWxsLHUuRi5Hci5KcikpLG4ucmVqZWN0KG5ldyB2KHkubWgsZSkpKX0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24odCl7cmV0dXJuIHQgaW5zdGFuY2VvZiB2P24ucmVqZWN0KHQpOihkLkVycm9yTW9uaXRvci5XaSgpLl9oKGkuaWQoKStcIiB1bmhhbmRsZWQgZXJyb3Igb24gcmVxdWVzdExlYXNlRGlyZWN0XCIse2Vycm9yOnR9KSxpLk1JLmVkKG5ldyB1LkYudW8obnVsbCx1LkYuR3IuSnIpKSxuLnJlamVjdChuZXcgdih5Lm1oLHQpKSl9KVtcImZpbmFsbHlcIl0oZnVuY3Rpb24oKXtjbGVhclRpbWVvdXQoaS5kUil9KX1yZXR1cm4gdGhpcy5tKCkuZGVidWcodGhpcy5pZCgpK1wiSGl2ZSBzZXNzaW9uIGNoZWNrIGRpc2FibGVkIC0gd2lsbCBkaXJlY3RseSByZXNvbHZlIHRpY2tldCAob3RoZXIgYWN0aXZlIHNlc3Npb25zIG1heSBmYWlsKVwiKSxuLnJlc29sdmUoITEpfSx0LnByb3RvdHlwZS5wUj1mdW5jdGlvbihlLGkscil7dmFyIG89dC51UihyLGUpO3JldHVybiBkLkVycm9yTW9uaXRvci5XaSgpLl9oKFwiXCIrdGhpcy5pZCgpK2kpLHRoaXMublI9RGF0ZS5ub3coKSxuLnJlamVjdChuZXcgdih5LnBoLG8pKX0sdC51Uj1mdW5jdGlvbih0LGUsaSl7dm9pZCAwPT09aSYmKGk9XCJzdGF0dXNcIik7dmFyIHI9ZTtpZih0LmJvZHkpdHJ5e3ZhciBuPUpTT04ucGFyc2UodC5ib2R5KTtyPW5baV19Y2F0Y2gobyl7fXJldHVybiByfSx0LnByb3RvdHlwZS5wPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXM7dGhpcy5yUj1EYXRlLm5vdygpLHRoaXMubSgpLmRlYnVnKHRoaXMuaWQoKStcInJlc29sdmluZyB0aWNrZXQ6IFwiK3QpO3ZhciBpPXRoaXMuZ1IodCk7cmV0dXJuIG8uWmkoaSxcImFwcGxpY2F0aW9uL2pzb25cIikudGhlbihmdW5jdGlvbihyKXtyZXR1cm4gZS5oUihyLGksdCxlLnJSKX0sZnVuY3Rpb24oaSl7cmV0dXJuIGkmJmkuc3RhdHVzPT0tMT9lLmZSKCk6KGQuRXJyb3JNb25pdG9yLldpKCkuX2goZS5pZCgpK1wiZXJyb3IgcmVzb2x2aW5nIHRpY2tldFwiLHt0aWNrZXQ6dH0pLG4ucmVqZWN0KG5ldyB2KHkucGgsaSkpKX0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24odCl7cmV0dXJuIGQuRXJyb3JNb25pdG9yLldpKCkuX2goZS5pZCgpK1wiZXJyb3IgcGFyc2luZyB0aWNrZXQgcmVzcG9uc2U6IFwiK3QpLG4ucmVqZWN0KG5ldyB2KHkubWgsdCkpfSl9LHQucHJvdG90eXBlLmhSPWZ1bmN0aW9uKHQsZSxpLHIpe3ZhciBuPUpTT04ucGFyc2UodCkscz1vLmlyKGUsbi5sb2NhdGlvbik7cmV0dXJuIG4udmVyc2lvbiYmIXRoaXMudmVyc2lvbiYmKHRoaXMudmVyc2lvbj1uLnZlcnNpb24pLHRoaXMublI9RGF0ZS5ub3coKSx0aGlzLm0oKS5kZWJ1Zyh0aGlzLmlkKCkrXCJyZXNvbHZlZCB0aWNrZXQgXCIraStcIiAtPiBcIitzK1wiIFtcIisodGhpcy5uUi1yKStcIl1cIiksc30sdC5wcm90b3R5cGUuYVI9ZnVuY3Rpb24odCxlLGkpe3ZhciByPXRoaXMudlIodCxlKTtpZihudWxsIT1yKXt2YXIgbj0obmV3IERhdGUpLmdldFRpbWUoKSxzPW4taTtyZXR1cm4gcz49dGhpcy5vcHRpb25zXy53YXJuU2xvd1Jlc3BUaW1lb3V0JiZ0aGlzLlpsKG5ldyB2KHkuU2gsdGhpcy5pZCgpK1wiIFRoZSB0ZWNoIGluaXRpYWxpemF0aW9uIHRvb2sgbW9yZSB0aGFuIFwiK3RoaXMub3B0aW9uc18ud2FyblNsb3dSZXNwVGltZW91dCtcIiBtaWxsaXNlY29uZHNcIikscixzKSxvLkhpdmVSZXF1ZXN0RmFjdG9yeS5iaShyLmlkLHRoaXMuQWkoKSkscn10aHJvdyBuZXcgdih5LnBoLFwiZXJyb3IgZ2VuZXJhdGluZyBzZXNzaW9uXCIpfSx0LnByb3RvdHlwZS52Uj1mdW5jdGlvbih0LGUpe3ZhciBpPW5ldyBsLmFwO2kuS2godCk7dmFyIHI9bmV3IHcodCxpLGUsbnVsbCk7ci55Uj0hMDt2YXIgbj1oLndyLkVvLG89bi5leGVjKHIubWFuaWZlc3QpO3JldHVybiBudWxsIT1vPyhyLlhJPW9bMV0sci5pZD1vWzVdLHIpOm51bGx9LHQucHJvdG90eXBlLmdSPWZ1bmN0aW9uKHQpe3ZhciBlPXQuaW5kZXhPZihcIj9cIik9PS0xP1wiP1wiOlwiJlwiO3JldHVybiB0aGlzLnRSKCk/by5ycihoLndyLmJvLGgud3IuVG8sdGhpcy5NSS5vcHRpb25zKCkucGxheWVyUG9ydCx0KTpvLnJyKGgud3IuU28saC53ci5Ubyx0aGlzLk1JLm9wdGlvbnMoKS5wbGF5ZXJQb3J0LHQsZSx0aGlzLk1JLlMoKSl9LHQucHJvdG90eXBlLmNSPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpczt0aGlzLmRSJiZjbGVhclRpbWVvdXQodGhpcy5kUiksdGhpcy5kUj1zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ZC5FcnJvck1vbml0b3IuV2koKS5faCh0LmlkKCkrXCIgVGhlIExlYXNlIFJlcXVlc3QgaXMgdGFraW5nIG1vcmUgdGhhbiBcIit0Lm9wdGlvbnNfLndhcm5TbG93UmVzcFRpbWVvdXQrXCIgc2Vjc1wiKX0sdGhpcy5vcHRpb25zXy53YXJuU2xvd1Jlc3BUaW1lb3V0KX0sdC5wcm90b3R5cGUub1I9ZnVuY3Rpb24oKXt0aGlzLmVSPTAsdGhpcy5pUj0wLHRoaXMuclI9MCx0aGlzLm5SPTB9LHQucHJvdG90eXBlLm09ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5NSS5tKCl9LHQucHJvdG90eXBlLnpsPWZ1bmN0aW9uKCl7dGhpcy5vUigpfSx0LnByb3RvdHlwZS5mUj1mdW5jdGlvbigpe3ZhciB0PXRoaXMsZT1cIi8vXCIraC53ci5UbytcIjpcIit0aGlzLk1JLm9wdGlvbnMoKS5tb25pdG9yUG9ydCtcIi92ZXJzaW9uLmpzb25cIjtyZXR1cm4gdGhpcy5tKCkuZGVidWcodGhpcy5pZCgpK1wiY2hlY2tpbmcgaWYgdGhlIG1vbml0b3IgcG9ydCBpcyByZWFjaGFibGVcIiksby5aaShlKS50aGVuKGZ1bmN0aW9uKGUpe3ZhciBpPUpTT04ucGFyc2UoZSk7dGhyb3cgdC5zdGF0ZT1pLnN0YXRlLGQuRXJyb3JNb25pdG9yLldpKCkuX2godC5pZCgpK1wiQ2xpZW50IHN0YXRlOiBcIit0LnN0YXRlKSx0Lk1JLmVkKG5ldyB1LkYudW8obnVsbCx1LkYuR3IuVnIpKSxuZXcgdih5LnloLFwic3RhdGUgXCIrdC5zdGF0ZSl9KS5mYWlsKGZ1bmN0aW9uKGUpe2lmKGUgaW5zdGFuY2VvZiB2KXJldHVybiBuLnJlamVjdChlKTtpZihlJiZlLnN0YXR1cz09LTEpe3ZhciBpPVwiY2xpZW50IG5vdCByZWFjaGFibGVcIjtyZXR1cm4gdC5NSS5lZChuZXcgdS5GLnVvKG51bGwsdS5GLkdyLlVyKSksdC5tKCkud2Fybih0LmlkKCkraSksbi5yZWplY3QobmV3IHYoeS55aCxpKSl9dmFyIGk9XCJWZXJpZnlDbGllbnRTdGF0ZSBlcnJvclwiO3JldHVybiBkLkVycm9yTW9uaXRvci5XaSgpLl9oKHQuaWQoKStpLHtlcnJvcjplfSksdC5NSS5lZChuZXcgdS5GLnVvKG51bGwsdS5GLkdyLlZyKSksbi5yZWplY3QobmV3IHYoeS5taCxpKSl9KX0sdC5wcm90b3R5cGUudFI9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5vcHRpb25zXy5zdXBwb3J0TGVnYWN5Q2xpZW50JiYoIXRoaXMudmVyc2lvbnx8dGhpcy52ZXJzaW9uLnN1YnN0cigwLDQpPFwiMjAxNlwiKX0sdH0oKTtULkpsPVwiSGl2ZUphdmFcIixlLkhpdmVKYXZhPVR9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcixuPXRoaXMmJnRoaXMuX19leHRlbmRzfHxmdW5jdGlvbih0LGUpe2Z1bmN0aW9uIGkoKXt0aGlzLmNvbnN0cnVjdG9yPXR9Zm9yKHZhciByIGluIGUpZS5oYXNPd25Qcm9wZXJ0eShyKSYmKHRbcl09ZVtyXSk7dC5wcm90b3R5cGU9bnVsbD09PWU/T2JqZWN0LmNyZWF0ZShlKTooaS5wcm90b3R5cGU9ZS5wcm90b3R5cGUsbmV3IGkpfSxvPWkoOCkscz1pKDEyKTshZnVuY3Rpb24odCl7dmFyIGU7IWZ1bmN0aW9uKHQpe3ZhciBlPWZ1bmN0aW9uKHQpe2Z1bmN0aW9uIGUoKXt2YXIgZT1udWxsIT09dCYmdC5hcHBseSh0aGlzLGFyZ3VtZW50cyl8fHRoaXM7cmV0dXJuIGUubWluVmVyc2lvbj1zLndyLklvLGUuaW5pdFRpbWVvdXQ9NmU0LGUud2FyblNsb3dSZXNwVGltZW91dD01ZTMsZS5zdXBwb3J0TGVnYWN5Q2xpZW50PSExLGV9cmV0dXJuIG4oZSx0KSxlfShvLnB0LklyLlJyKTt0LkpJPWV9KGU9dC5Jcnx8KHQuSXI9e30pKX0ocj1lLnB0fHwoZS5wdD17fSkpfSxmdW5jdGlvbih0LGUpe1widXNlIHN0cmljdFwiO3ZhciBpPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTtpLlRvPVwiMTI3LjAuMC4xXCIsaS5PZD0xMTk4MyxpLlNvPVwiLy97MH06ezF9L3Byb3h5Lz9jYWxsYmFjaz17Mn17M31oaXZlUGx1Z2luSWQ9ezR9XCIsaS5tUj1cIi8vezB9OnsxfS9wcm94eS97Mn0vc2Vzc2lvbj9tYW5pZmVzdD17M31cIixpLmtkPVwiLy97MH06ezF9L3Byb3h5L3syfS9wbGF5ZXI/cmVxPXszfVwiLGkud1I9XCIvL3swfTp7MX0vcHJveHkvezJ9L2luZm8/ezN9XCIsZS5DZD1pfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI9dGhpcyYmdGhpcy5fX2V4dGVuZHN8fGZ1bmN0aW9uKHQsZSl7ZnVuY3Rpb24gaSgpe3RoaXMuY29uc3RydWN0b3I9dH1mb3IodmFyIHIgaW4gZSllLmhhc093blByb3BlcnR5KHIpJiYodFtyXT1lW3JdKTt0LnByb3RvdHlwZT1udWxsPT09ZT9PYmplY3QuY3JlYXRlKGUpOihpLnByb3RvdHlwZT1lLnByb3RvdHlwZSxuZXcgaSl9LG49aSgyNiksbz1mdW5jdGlvbih0KXtmdW5jdGlvbiBlKCl7cmV0dXJuIG51bGwhPT10JiZ0LmFwcGx5KHRoaXMsYXJndW1lbnRzKXx8dGhpc31yZXR1cm4gcihlLHQpLGUuYmk9ZnVuY3Rpb24odCxpKXtlLlRSW2ldPXR9LGUuU1I9ZnVuY3Rpb24odCxpKXtlLmJSW2ldPXR9LGUucHJvdG90eXBlLnNlbmQ9ZnVuY3Rpb24oKXtpZighdGhpcy5zZXNzaW9uSWQpe3ZhciB0PU9iamVjdC5rZXlzKGUuYlIpO3QubGVuZ3RoPjAmJih0aGlzLnNlc3Npb25JZD1lLmJSW3RbMF1dKX12YXIgaT1lLlRSW3RoaXMuc2Vzc2lvbklkXSxyPWUuYlJbdGhpcy5zZXNzaW9uSWRdO3IubSgpLmRlYnVnKFwiSW50ZXJjZXB0ZWQgTWFuaWZlc3QgUmVxdWVzdCBcIit0aGlzLnVybCksaS5zZXRNYW5pZmVzdFJlcXVlc3QodGhpcyksci5SKHRoaXMudXJsKX0sZS5wcm90b3R5cGUuRVI9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLGU9bmV3IFhNTEh0dHBSZXF1ZXN0O2Uub3BlbihcIkdFVFwiLHRoaXMudXJsKSxlLm9ucmVhZHlzdGF0ZWNoYW5nZT1mdW5jdGlvbigpezQ9PT1lLnJlYWR5U3RhdGUmJih0LnJlc3BvbnNlPWUucmVzcG9uc2VUZXh0LHQucmVzcG9uc2VUZXh0PWUucmVzcG9uc2VUZXh0LHQucmVhZHlTdGF0ZT00LHQuc3RhdHVzPWUuc3RhdHVzLHQub25yZWFkeXN0YXRlY2hhbmdlKCksdC5vbmxvYWQoKSxjb25zb2xlLmRlYnVnKFwiUmV0dXJuZWQgTWFuaWZlc3QgUmVxdWVzdCBcIit0LnVybCkpfSxlLnNlbmQoKX0sZS5wcm90b3R5cGUuSVI9ZnVuY3Rpb24oKXt0LnByb3RvdHlwZS5zZW5kLmNhbGwodGhpcyl9LGV9KG4uVGkpO28uYlI9e30sby5UUj17fSxlLlNpPW99LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcixuPXRoaXMmJnRoaXMuX19leHRlbmRzfHxmdW5jdGlvbih0LGUpe2Z1bmN0aW9uIGkoKXt0aGlzLmNvbnN0cnVjdG9yPXR9Zm9yKHZhciByIGluIGUpZS5oYXNPd25Qcm9wZXJ0eShyKSYmKHRbcl09ZVtyXSk7dC5wcm90b3R5cGU9bnVsbD09PWU/T2JqZWN0LmNyZWF0ZShlKTooaS5wcm90b3R5cGU9ZS5wcm90b3R5cGUsbmV3IGkpfSxvPWkoOCk7IWZ1bmN0aW9uKHQpe3ZhciBlOyFmdW5jdGlvbih0KXt2YXIgZT1mdW5jdGlvbih0KXtmdW5jdGlvbiBlKCl7cmV0dXJuIG51bGwhPT10JiZ0LmFwcGx5KHRoaXMsYXJndW1lbnRzKXx8dGhpc31yZXR1cm4gbihlLHQpLGV9KG8ucHQuSXIuUnIpO3QuUlI9ZX0oZT10LklyfHwodC5Jcj17fSkpfShyPWUucHR8fChlLnB0PXt9KSl9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcj1pKDEpLG49aSg3KSxvPWkoNDcpLHM9by5wdC5Jci5SUixhPWkoMTQpLGM9aSg1OSksaD1pKDE5KSxwPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdChlLGkpe3RoaXMuTUk9ZSx0aGlzLm9wdGlvbnNfPW5ldyBzLHZvaWQgMCE9PWlbdC5KbF0mJm4ubnIoaVt0LkpsXSx0aGlzLm9wdGlvbnNfKX1yZXR1cm4gdC5wcm90b3R5cGUuQWk9ZnVuY3Rpb24oKXtyZXR1cm4gdC5KbH0sdC5wcm90b3R5cGUuZ2V0VmVyc2lvbj1mdW5jdGlvbigpe3JldHVybiBudWxsfSx0LnByb3RvdHlwZS5XbD1mdW5jdGlvbigpe3JldHVybiEwfSx0LnByb3RvdHlwZS5HST1mdW5jdGlvbigpe3JldHVybiByLnJlc29sdmUoITApfSx0LnByb3RvdHlwZS5pbml0U2Vzc2lvbj1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMudlIodCxlLnRpY2tldCxlLnRpY2tldC50cCgpLGUpO3JldHVybiBuLkhpdmVSZXF1ZXN0RmFjdG9yeS5iaShpLmlkLHRoaXMuQWkoKSksci5yZXNvbHZlKGkpfSx0LnByb3RvdHlwZS5ZbD1mdW5jdGlvbigpe3JldHVybiB0aGlzLm9wdGlvbnMoKS5pbml0VGltZW91dH0sdC5wcm90b3R5cGUuc3Q9ZnVuY3Rpb24odCxlKXt2YXIgaT1lLm1hbmlmZXN0LnRvTG93ZXJDYXNlKCkuaW5kZXhPZihcIi9tYW5pZmVzdFwiKTtpZihpPi0xKXt2YXIgcj1lLm1hbmlmZXN0LnN1YnN0cmluZygwLGkpO2lmKHQuaW5kZXhPZihyKT4tMSlyZXR1cm4hMH1lbHNlIGlmKHQ9PWUubWFuaWZlc3QpcmV0dXJuITA7cmV0dXJuITF9LHQucHJvdG90eXBlLlBpPWZ1bmN0aW9uKHQpe3QuUmkmJih0aGlzLk1JLm0oKS5kZWJ1ZyhcIltTdGF0c0pTXSBzdG9wcGluZyBzZXNzaW9uIFtcIit0LmlkK1wiXVwiKSx0LlJpLkhvLnJlc2V0KCkpfSx0LnByb3RvdHlwZS5DaT1mdW5jdGlvbih0LGUpe3ZhciBpPWU/YS5Gby5JRExFOmEuRm8uQm87dGhpcy5NSS5tKCkubm90aWNlKFwiW0hpdmVDb21tXSBjbGllbnQgc3RhdGU6IFwiK2EuRm9baV0pLHQuUmkmJnQuUmkuQ2koaSl9LHQucHJvdG90eXBlLmZkPWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcyxuPTA7cmV0dXJuIHRoaXMua1I8ZS5nciYmKG49ZS5nci10aGlzLmtSLHRoaXMua1I9ZS5nciksdC5OaSgpLnRoZW4oZnVuY3Rpb24oKXt0LlJpLkRvLkNSKG4sZS5kciksdC5SaS5Rbi52bihlLmxyLGUuZHIsZS5nciksaS5PUigpfSkuZG9uZSgpLHIucmVzb2x2ZSghMCl9LHQucHJvdG90eXBlLnlkPWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gdC5OaSgpLnRoZW4oZnVuY3Rpb24oKXt0LlJpLlFuLm1uKHQudGlja2V0LnNlc3Npb25JZCxlLGkpfSkuZG9uZSgpLHIucmVzb2x2ZSghMCl9LHQucHJvdG90eXBlLnduPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHQuTmkoKS50aGVuKGZ1bmN0aW9uKCl7dC5SaS5Rbi5UbihbZV0pfSkuZG9uZSgpLHIucmVzb2x2ZSghMCl9LHQucHJvdG90eXBlLm9uRXJyb3I9ZnVuY3Rpb24odCl7dmFyIGU9ITA7aWYodm9pZCAwIT10aGlzLm9wdGlvbnMoKS5vbkVycm9yKXRyeXtlPXRoaXMub3B0aW9ucygpLm9uRXJyb3IodCl9Y2F0Y2goaSl7aC5FcnJvck1vbml0b3IuV2koKS5faChcIltTdGF0c0pTXSBleGNlcHRpb24gaW4gdXNlci1kZWZpbmVkIG9uRXJyb3IgY2FsbGJhY2s6IFwiK2kpfXJldHVybiBlfSx0LnByb3RvdHlwZS5vbkFjdGl2ZVNlc3Npb249ZnVuY3Rpb24odCl7dmFyIGU9dGhpczt0aGlzLlBSKCksdC5OaSgpLnRoZW4oZnVuY3Rpb24oaSl7ZS5BUj1pO3ZhciByPW5ldyBjLk5SKGUuTUkuaXNMaXZlKCksZS5NSS4kKCksdC50aWNrZXQudHAoKSk7ZS5BUi54Uj1yLGUuQVIuRG8ueFI9cixlLk1JLmhuKGUuQVIpLGUuQVIuSG8uaW5pdChlLkFSLkRvLG51bGwpLGUuQVIuUW4ud2kodC50aWNrZXQuc2Vzc2lvbklkLGUuTUkuaXQoKSwyMDApO3ZhciBuPWUuTUkucmQoKTtpZihuJiZuLmxlbmd0aD4wJiZlLkFSLlFuLlRuKG4pLHZvaWQgMCE9ZS5vcHRpb25zXy5vbkFjdGl2ZVNlc3Npb24pdHJ5e2Uub3B0aW9uc18ub25BY3RpdmVTZXNzaW9uKHQuZygpKX1jYXRjaChvKXtoLkVycm9yTW9uaXRvci5XaSgpLl9oKFwiW1N0YXRzSlNdIGV4Y2VwdGlvbiBpbiB1c2VyLWRlZmluZWQgb25BY3RpdmVTZXNzaW9uIGNhbGxiYWNrOiBcIitvKX19KS5kb25lKCl9LHQucHJvdG90eXBlLlpsPWZ1bmN0aW9uKCl7fSx0LnByb3RvdHlwZS56bD1mdW5jdGlvbigpe30sdC5wcm90b3R5cGUucWw9ZnVuY3Rpb24odCl7dGhpcy5NST10fSx0LnByb3RvdHlwZS5vcHRpb25zPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMub3B0aW9uc199LHQucHJvdG90eXBlLlBSPWZ1bmN0aW9uKCl7dGhpcy5rUj0wfSx0LnByb3RvdHlwZS52Uj1mdW5jdGlvbih0LGUsaSxyKXt2YXIgbz1uZXcgbi5CaSh0LGUsaSxyKTtyZXR1cm4gby55Uj0hMSxvLmlkPWUuc2Vzc2lvbklkLG99LHQucHJvdG90eXBlLk9SPWZ1bmN0aW9uKCl7dHJ5e3ZhciB0PXRoaXMuTUkuYXQoKTt2b2lkIDAhPXQmJih0aGlzLkFSLkRvLkJSLm1ldHJpY3MuYml0cmF0ZVVwTis9dC5KaSgpLHRoaXMuQVIuRG8uQlIubWV0cmljcy5iaXRyYXRlRHduTis9dC5LaSgpLG51bGwhPXQuVmkoKSYmKHRoaXMuQVIuRG8uQlIubWV0cmljcy5zcmNUaHJvdWdocHV0PXQuVmkoKSksbnVsbCE9dC5RaSgpJiZ0aGlzLkZSKCEwLHQuUWkoKSksbnVsbCE9dC5xaSgpJiZ0aGlzLkZSKCExLHQucWkoKSkpfWNhdGNoKGUpe2guRXJyb3JNb25pdG9yLldpKCkuX2goZSl9fSx0LnByb3RvdHlwZS5GUj1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMscj0wLG49MCxvPTAscz0wO2UuZm9yRWFjaChmdW5jdGlvbihlLGEpe3ZhciBjPWUuc3VjY2VzcytlLl9pO2lmKHIrPWMscys9ZS5EaSxuKz1lLnN1Y2Nlc3Msbys9ZS5faSx0KXt2YXIgaD1pLkFSLkRvLl9SKE51bWJlcihhKSk7aS5EUihoLGMsZS5zdWNjZXNzLGUuX2ksZS5EaSl9fSk7dmFyIGE9dGhpcy5BUi5Eby5IUigpO3RoaXMuRFIoYSxyLG4sbyxzKX0sdC5wcm90b3R5cGUuRFI9ZnVuY3Rpb24odCxlLGkscixuKXt0LnNyY1JlcU4rPWUsdC5zcmNSZXNwTis9aSx0LnNyY1Jlc3BFcnJOKz1yLHQuc3JjUmVzcFF0Kz1uLHQucmVzcEZhbGxiYWNrTis9aSx0LnJlc3BGYWxsYmFja0Vyck4rPXJ9LHR9KCk7cC5KbD1cIlN0YXRzSlNcIixlLlN0YXRzSlM9cH0sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjt2YXIgaTshZnVuY3Rpb24odCl7dmFyIGU7IWZ1bmN0aW9uKHQpe3RbdC5IaXZlSlM9MF09XCJIaXZlSlNcIix0W3QuSGl2ZUphdmE9MV09XCJIaXZlSmF2YVwiLHRbdC5TdGF0c0pTPTJdPVwiU3RhdHNKU1wiLHRbdC5IaXZlSnNQcm94eT0zXT1cIkhpdmVKc1Byb3h5XCJ9KGU9dC5JbHx8KHQuSWw9e30pKX0oaT1lLnB0fHwoZS5wdD17fSkpfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI9aSgxNSksbj1pKDIpLG89aSgyNCkscz1pKDE0KSxhPWkoNSksYz1pKDkpLGg9aSg1NikscD1pKDU1KSx1PWkoNjApLGw9aSg1MiksZD1pKDUxKTtpZihcInVuZGVmaW5lZFwiPT10eXBlb2YgZil2YXIgZj0hMTtpZihmKXZhciBnPWkoNTMpLkxSO2Vsc2UgdmFyIHY9aSg1NykuTVI7dmFyIHk9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7fXJldHVybiB0LnByb3RvdHlwZS5hcHBseT1mdW5jdGlvbih0KXt0LmJpbmQobmV3IHIubnMoYS5naS51aSxzLnJzLHIuc3MubHMpKSx0LmJpbmQobmV3IHIubnMoYS5naS5CZSxwLmpSLHIuc3MubHMpKSx0LmJpbmQobmV3IHIubnMoYS5naS5haSx1LlVSLHIuc3MubHMpKSx0LmJpbmQobmV3IHIubnMoYS5naS5DZSxsLlZSLHIuc3MubHMpKSx0LmJpbmQobmV3IHIubnMobi5GcmFtZXdvcmsuRmUud2Usby5FbC5ibCxyLnNzLmxzKSksZj90LmJpbmQobmV3IHIubnMoYS5naS5jaSxnLHIuc3MubHMpKTp0LmJpbmQobmV3IHIubnMoYS5naS5jaSx2LHIuc3MubHMpKSx0LmJpbmQobmV3IHIubnMoYS5naS5oaSxkLlFSLHIuc3MubHMpKSx0LmJpbmQobmV3IHIubnMoYS5naS5saSxoLlN0YXRzLnpmLHIuc3MuVHMpKSx0LmJpbmQobmV3IHIubnMoYS5naS5zaSxoLlN0YXRzLmVvLHIuc3MuVHMpKSx0LmJpbmQobmV3IHIubnMoYS5naS5kaSxjLkYuVW4sci5zcy5UcykpLHQuYmluZChuZXcgci5ucyhhLmdpLmZpLGMuRi5lbyxyLnNzLlRzKSl9LHR9KCk7ZS5TZD15fSxmdW5jdGlvbih0LGUpe1widXNlIHN0cmljdFwiO3ZhciBpPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdC5wcm90b3R5cGUucVI9ZnVuY3Rpb24odCl7dGhpcy5ob3N0bmFtZT10fSx0LnByb3RvdHlwZS5Gbj1mdW5jdGlvbigpe3JldHVybiB0aGlzLmhvc3RuYW1lfSx0LnByb3RvdHlwZS5KUj1mdW5jdGlvbih0KXt0aGlzLktSPXR9LHQucHJvdG90eXBlLk5uPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuS1J9LHR9KCk7ZS5RUj1pfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI9dGhpcyYmdGhpcy5fX2V4dGVuZHN8fGZ1bmN0aW9uKHQsZSl7ZnVuY3Rpb24gaSgpe3RoaXMuY29uc3RydWN0b3I9dH1mb3IodmFyIHIgaW4gZSllLmhhc093blByb3BlcnR5KHIpJiYodFtyXT1lW3JdKTt0LnByb3RvdHlwZT1udWxsPT09ZT9PYmplY3QuY3JlYXRlKGUpOihpLnByb3RvdHlwZT1lLnByb3RvdHlwZSxuZXcgaSl9LG49aSgxKSxvPWkoMjIpLHM9aSgyKSxhPWkoMTMpLGM9aSgzOSksaD1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt0aGlzLkdSPVwiSWRlbnRpdHlTdG9yZVwiLHRoaXMuelI9XCJJZGVudGl0eURCXCIsdGhpcy5zbj1udWxsLHRoaXMuaW5kZXhlZERCPXdpbmRvdy5pbmRleGVkREJ8fHdpbmRvdy5tb3pJbmRleGVkREJ8fHdpbmRvdy53ZWJraXRJbmRleGVkREJ8fHdpbmRvdy5tc0luZGV4ZWREQixzLkZyYW1ld29yayYmcy5GcmFtZXdvcmsucmVzb2x2ZShzLkZyYW1ld29yay5GZS53ZSk/dGhpcy5tPXMuRnJhbWV3b3JrLnJlc29sdmUocy5GcmFtZXdvcmsuRmUud2UpLmxvZygpOnRoaXMubT1jb25zb2xlfXJldHVybiB0LnByb3RvdHlwZS5XUj1mdW5jdGlvbigpe3ZhciB0PXRoaXMsZT1uLmRlZmVyKCksaT1pbmRleGVkREIub3Blbih0aGlzLnpSKTtyZXR1cm4gaS5vbnVwZ3JhZGVuZWVkZWQ9ZnVuY3Rpb24oKXt2YXIgZT1pLnJlc3VsdDtlLmNyZWF0ZU9iamVjdFN0b3JlKHQuR1Ise2tleVBhdGg6XCJpZFwifSl9LGkub25zdWNjZXNzPWZ1bmN0aW9uKCl7dmFyIHQ9aS5yZXN1bHQ7ZS5yZXNvbHZlKHQpfSxpLm9uZXJyb3I9ZnVuY3Rpb24odCl7ZS5yZWplY3QodCl9LGUudnR9LHQucHJvdG90eXBlLktvPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcztpZih0aGlzLiRSKXJldHVybiB0aGlzLiRSO3ZhciBlPW4uZGVmZXIoKTtpZih0aGlzLnNuKWUucmVzb2x2ZShuZXcgYy5GSSh0aGlzLnNuKSk7ZWxzZSBpZihhLktuLlJvJiZ0aGlzLmluZGV4ZWREQil7dmFyIGk9c2V0VGltZW91dChmdW5jdGlvbigpe3QubS53YXJuKFwiW0hpdmVDb21tXSB0aW1lb3V0IHJldHJpZXZpbmcgcGVyc2lzdGVudCBJRCAtIGdlbmVyYXRpbmcgcmFuZG9tIG9uZVwiKSxcbiAgdC5zbj10LllSKCksdC5tLmRlYnVnKFwiW0hpdmVDb21tXSBHZW5lcmF0ZWQgVVVJRDogXCIrdC5zbiksZS5yZXNvbHZlKG5ldyBjLkZJKHQuc24pKX0sNGUzKTt0cnl7dmFyIHI9dGhpcy5XUigpO3IudGhlbihmdW5jdGlvbihyKXt2YXIgbj1yLnRyYW5zYWN0aW9uKHQuR1IsXCJyZWFkd3JpdGVcIiksbz1uLm9iamVjdFN0b3JlKHQuR1IpLHM9by5nZXQoXCJNWUlEXCIpO3Mub25zdWNjZXNzPWZ1bmN0aW9uKCl7aWYoY2xlYXJUaW1lb3V0KGkpLHQuc24pZS5yZXNvbHZlKG5ldyBjLkZJKHQuc24pKTtlbHNlIGlmKG51bGwhPXMucmVzdWx0JiZhLktuLlJvKXt2YXIgbj1zLnJlc3VsdC52YWx1ZTt0Lm0uZGVidWcoXCJbSGl2ZUNvbW1dIFJldHJpZXZlZCBwZXJzaXN0ZW50IFVVSUQ6IFwiK24pLHQuc249bixyLmNsb3NlKCksZS5yZXNvbHZlKG5ldyBjLkZJKHQuc24pKX1lbHNle3ZhciBvPXQuWVIoKTt0LlhSKHIsbyksZS5yZXNvbHZlKG5ldyBjLkZJKHQuc24pKX19LHMub25lcnJvcj1mdW5jdGlvbihyKXtjbGVhclRpbWVvdXQoaSksdC5zbnx8KHQubS53YXJuKFwiW0hpdmVDb21tXSBlcnJvciByZXRyaWV2aW5nIHBlcnNpc3RlbnQgVVVJRDogXCIrciksdC5zbj10LllSKCksdC5tLmRlYnVnKFwiW0hpdmVDb21tXSBHZW5lcmF0ZWQgVVVJRDogXCIrdC5zbikpLGUucmVzb2x2ZShuZXcgYy5GSSh0LnNuKSl9fSkuZmFpbChmdW5jdGlvbihyKXtjbGVhclRpbWVvdXQoaSksdC5zbnx8KHQubS53YXJuKFwiW0hpdmVDb21tXSBlcnJvciBvcGVuaW5nIGluZGV4ZWREQiAtIGdlbmVyYXRpbmcgcmFuZG9tIGlkLiBFcnJvcjogXCIrciksdC5zbj10LllSKCksdC5tLmRlYnVnKFwiW0hpdmVDb21tXSBHZW5lcmF0ZWQgVVVJRDogXCIrdC5zbikpLGUucmVzb2x2ZShuZXcgYy5GSSh0LnNuKSl9KX1jYXRjaChvKXt0aGlzLnNuPXRoaXMuWVIoKSx0aGlzLm0uZGVidWcoXCJbSGl2ZUNvbW1dIFBlcnNpc3RlbmNlIGVycm9yIC0gR2VuZXJhdGUgVVVJRDogXCIrdGhpcy5zbixvKSxlLnJlc29sdmUobmV3IGMuRkkodGhpcy5zbikpfX1lbHNlIHRoaXMuc249dGhpcy5ZUigpLHRoaXMubS5kZWJ1ZyhcIltIaXZlQ29tbV0gUGVyc2lzdGVuY2UgZGlzYWJsZWQgLSBHZW5lcmF0ZSBVVUlEOiBcIit0aGlzLnNuKSxlLnJlc29sdmUobmV3IGMuRkkodGhpcy5zbikpO3JldHVybiB0aGlzLiRSPWUudnQsdGhpcy4kUn0sdC5wcm90b3R5cGUuWFI9ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzLHI9dC50cmFuc2FjdGlvbih0aGlzLkdSLFwicmVhZHdyaXRlXCIpLG49ci5vYmplY3RTdG9yZSh0aGlzLkdSKTtuLnB1dCh7aWQ6XCJNWUlEXCIsdmFsdWU6ZX0pLHIub25jb21wbGV0ZT1mdW5jdGlvbigpe2kubS5kZWJ1ZyhcIltIaXZlQ29tbV0gY29tcGxldGVkIFVVSUQgcGVyc2lzdGVuY2VcIiksdC5jbG9zZSgpfSx0aGlzLm0uZGVidWcoXCJbSGl2ZUNvbW1dIEdlbmVyYXRlZCBVVUlEOiBcIitlKSx0aGlzLnNuPWV9LHQucHJvdG90eXBlLllSPWZ1bmN0aW9uKCl7cmV0dXJuIG8uWmgoKX0sdH0oKTtlLlpSPWg7dmFyIHA9ZnVuY3Rpb24odCl7ZnVuY3Rpb24gZSgpe3JldHVybiB0LmNhbGwodGhpcyl8fHRoaXN9cmV0dXJuIHIoZSx0KSxlLnByb3RvdHlwZS5Lbz1mdW5jdGlvbigpe3ZhciBlPXRoaXM7aWYodGhpcy50aylyZXR1cm4gdGhpcy50azt2YXIgaT1uLmRlZmVyKCk7cmV0dXJuIHQucHJvdG90eXBlLktvLmNhbGwodGhpcykudGhlbihmdW5jdGlvbih0KXt2YXIgcj1lLllSKCksbj10LiRvKCksbz1uZXcgYy5GSShyLG4pO2kucmVzb2x2ZShvKX0pLmZhaWwoZnVuY3Rpb24odCl7dmFyIHI9ZS5ZUigpLG49bmV3IGMuRkkocik7aS5yZXNvbHZlKG4pfSksdGhpcy50az1pLnZ0LHRoaXMudGt9LGV9KGgpO2UuVlI9cH0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPWkoMSksbj1pKDIpLG89ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7dGhpcy51PVwiW1ByZWxvYWRDb25uZWN0aXZpdHlJbmZvUHJvdmlkZXJdIFwiLHRoaXMuY29ubkluZm89d2luZG93LmVrLHRoaXMubT1uLkZyYW1ld29yay5yZXNvbHZlKG4uRnJhbWV3b3JrLkZlLndlKS5sb2coKSx0aGlzLmNvbm5JbmZvfHx0aGlzLm0uZXJyb3IodGhpcy51K1wiIGhlbHBlciB1bmRlZmluZWRcIil9cmV0dXJuIHQucHJvdG90eXBlLlBuPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcztpZighdGhpcy5jb25uSW5mbylyZXR1cm4gci5yZWplY3QoXCJDb25uSW5mbyBoZWxwZXIgdW5kZWZpbmVkXCIpO3ZhciBlPXNldFRpbWVvdXQoZnVuY3Rpb24oKXtyZXR1cm4gdC5tLndhcm4odC51K1wiR2V0IGNvbm5lY3Rpdml0eSBpbmZvIGV4cGlyZWRcIiksdC5paz9yLnJlc29sdmUodC5payk6ci5yZWplY3QoXCJleHBpcmVkXCIpfSwyZTMpO3RyeXtyZXR1cm4gdGhpcy5jb25uSW5mby5QbigpLnRoZW4oZnVuY3Rpb24oaSl7cmV0dXJuIGNsZWFyVGltZW91dChlKSx0LmlrPWksaX0pLmZhaWwoZnVuY3Rpb24oZSl7cmV0dXJuIHQubS5kZWJ1Zyh0LnUrXCIgZ2V0IGNvbm5lY3Rpdml0eSBpbmZvIGZhaWxlZCB3aXRoIGVycm9yIDE6IFwiLGUpLHQuaWs/dC5pazpyLnJlamVjdChlKX0pfWNhdGNoKGkpe3JldHVybiB0aGlzLm0uZGVidWcodGhpcy51K1wiIGdldCBjb25uZWN0aXZpdHkgaW5mbyBmYWlsZWQgd2l0aCBlcnJvciAyOlwiLGkpLHIucmVqZWN0KGkpfX0sdC5wcm90b3R5cGUucms9ZnVuY3Rpb24odCxlLGkpe30sdH0oKTtlLkxSPW99LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcj1pKDYzKSxuPWkoMSksbz1pKDIpLHM9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7dGhpcy5pbmRleGVkREI9d2luZG93LmluZGV4ZWREQnx8d2luZG93Lm1vekluZGV4ZWREQnx8d2luZG93LndlYmtpdEluZGV4ZWREQnx8d2luZG93Lm1zSW5kZXhlZERCLHRoaXMubT1vLkZyYW1ld29yay5yZXNvbHZlKG8uRnJhbWV3b3JrLkZlLndlKS5sb2coKX1yZXR1cm4gdC5wcm90b3R5cGUuV1I9ZnVuY3Rpb24oKXt2YXIgdD1uLmRlZmVyKCksZT10aGlzLmluZGV4ZWREQi5vcGVuKFwiUHJpdmF0ZUlQREJcIik7cmV0dXJuIGUub251cGdyYWRlbmVlZGVkPWZ1bmN0aW9uKCl7dmFyIHQ9ZS5yZXN1bHQ7dC5jcmVhdGVPYmplY3RTdG9yZShcIlByaXZhdGVJUFN0b3JlXCIse2tleVBhdGg6XCJpZFwifSl9LGUub25zdWNjZXNzPWZ1bmN0aW9uKCl7dmFyIGk9ZS5yZXN1bHQ7dC5yZXNvbHZlKGkpfSxlLm9uZXJyb3I9ZnVuY3Rpb24oZSl7dC5yZWplY3QoZSl9LHQudnR9LHQucHJvdG90eXBlLm5rPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcztpZih0aGlzLnNrKXJldHVybiB0aGlzLnNrO3ZhciBlPXNldFRpbWVvdXQoZnVuY3Rpb24oKXt0Lm0ud2FybihcIlByaXZhdGUgbGlzdCByZXRyaWV2YWwgdGltZW91dFwiKSxpLnJlamVjdChcIlByaXZhdGUgbGlzdCB0aW1lb3V0XCIpfSw0ZTMpLGk9bi5kZWZlcigpLG89dGhpcy5XUigpO3JldHVybiBvLnRoZW4oZnVuY3Rpb24obil7dmFyIG89bi50cmFuc2FjdGlvbihcIlByaXZhdGVJUFN0b3JlXCIsXCJyZWFkd3JpdGVcIikscz1vLm9iamVjdFN0b3JlKFwiUHJpdmF0ZUlQU3RvcmVcIiksYT1zLmdldChcImlwbGlzdFwiKTthLm9uc3VjY2Vzcz1mdW5jdGlvbigpe2NsZWFyVGltZW91dChlKTt2YXIgdD1bXTtyLmFrKGEucmVzdWx0KXx8ci5hayhhLnJlc3VsdC52YWx1ZSl8fCh0PWEucmVzdWx0LnZhbHVlLnNwbGl0KFwifFwiKSksaS5yZXNvbHZlKHQpLG4uY2xvc2UoKX0sYS5vbmVycm9yPWZ1bmN0aW9uKHIpe2NsZWFyVGltZW91dChlKSx0Lm0ud2FybihcIkkgZ290IGFuIGVycm9yIG9uIGluZGV4ZWQgZGIgXCIrci5tZXNzYWdlKSxpLnJlamVjdChcIkVycm9yIG9uIGluZGV4ZWREQiBcIityLm1lc3NhZ2UpfX0pLmZhaWwoZnVuY3Rpb24ocil7Y2xlYXJUaW1lb3V0KGUpLHQubS53YXJuKFwiREIgaXMgbm90IG9wZW4gd2l0aCBlcnJvclwiK3IubWVzc2FnZSksaS5yZWplY3QoXCJEQiBpcyBub3Qgb3BlbiB3aXRoIGVycm9yIFwiK3IubWVzc2FnZSl9KSx0aGlzLnNrPWkudnQsdGhpcy5za30sdC5wcm90b3R5cGUuY2s9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcyxpPXQuam9pbihcInxcIikscj10aGlzLldSKCk7ci50aGVuKGZ1bmN0aW9uKHIpe3ZhciBuPXIudHJhbnNhY3Rpb24oXCJQcml2YXRlSVBTdG9yZVwiLFwicmVhZHdyaXRlXCIpLG89bi5vYmplY3RTdG9yZShcIlByaXZhdGVJUFN0b3JlXCIpO28ucHV0KHtpZDpcImlwbGlzdFwiLHZhbHVlOml9KSxuLm9uY29tcGxldGU9ZnVuY3Rpb24oKXtlLm0uZGVidWcoXCJTdG9yaW5nIHNpdGUgbWF0Y2hlZCBpcHMgW1wiK3Quam9pbihcIixcIikrXCJdXCIpLHIuY2xvc2UoKX19KS5mYWlsKGZ1bmN0aW9uKHQpe2UubS53YXJuKFwiREIgaXMgbm90IG9wZW4gd2l0aCBlcnJvciBcIit0Lm1lc3NhZ2UpfSl9LHR9KCk7ZS5oaz1zfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI9aSgxKSxuPWkoMjEpLG89aSgzNikscz1pKDIpLGE9aSgxMyksYz1pKDEwKSxoPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMubT1zLkZyYW1ld29yay5yZXNvbHZlKHMuRnJhbWV3b3JrLkZlLndlKS5sb2coKSx0aGlzLm0uZGVidWcoXCJJTklUIFNFUlZJQ0UgQ0xJRU5UXCIpfXJldHVybiB0LnByb3RvdHlwZS5pbml0PWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcztpZih0aGlzLnBrKXRoaXMucGsudGhlbihmdW5jdGlvbigpe3ZhciB0PXtwYXJ0bmVySWQ6ZS5ibigpLGN1c3RvbWVySWQ6ZS5FbigpLGNvbnRlbnRJZDplLmVzKCksc2VjcmV0OmUuV2goKX0scj1uZXcgYy5abihTZXJ2aWNlcy5rZiwxLEpTT04uc3RyaW5naWZ5KHQpKTtpLmNvbm5lY3Rpb24uc2VuZChyKX0pO2Vsc2V7dmFyIHM9ci5kZWZlcigpLGg9YS5Lbi5Kbi5rbztlLnpoJiYodGhpcy5tLndhcm4oXCJbSGl2ZUNvbW1dIEVycm9yIHRyeWluZyB0byByZXNvbHZlIHRlc3QgdGlja2V0IGFnYWluc3QgcHJvZHVjdGlvbiBzZXJ2aWNlcyAtIHVzZSBwcm9kdWN0aW9uIHRpY2tldCBvciB0ZXN0IHBsdWdpblwiKSxzLnJlamVjdChuZXcgRXJyb3IoXCJ0ZXN0IHRpY2tldCBpbiBwcm9kdWN0aW9uXCIpKSk7dmFyIHA9bmV3IG4oaCksdT1wLkV1KHtcImNvbm5lY3Rpb24taWRcIjp0LHBhcnRuZXJfaWQ6ZS5ibigpLGN1c3RvbWVyX2lkOmUuRW4oKSxjb250ZW50X2lkOmUuZXMoKSx0aWNrZXQ6ZS5XaCgpfSkudG9TdHJpbmcoKTt0aGlzLmNvbm5lY3Rpb249bmV3IG8uQUkodSxhLktuLkpuLkFvLGEuS24uSm4uTm8sYS5Lbi5Kbi54byksdGhpcy5jb25uZWN0aW9uLlRJKGZ1bmN0aW9uKCl7aS5tLmRlYnVnKFwiSElWRSBTRVJWSUNFUyBDT05ORUNURURcIikscy5yZXNvbHZlKGkuY29ubmVjdGlvbil9KSx0aGlzLmNvbm5lY3Rpb24ub25lcnJvcihmdW5jdGlvbigpe2kubS53YXJuKFwiSGl2ZSBTZXJ2aWNlcyBDb25uZWN0aW9uIGZhaWxlZFwiKSxzLnJlamVjdChpLmNvbm5lY3Rpb24pfSksdGhpcy5waz1zLnZ0fXJldHVybntZbzp0aGlzLmNvbm5lY3Rpb24sdnQ6dGhpcy5wa319LHQucHJvdG90eXBlLmNvbm5lY3Q9ZnVuY3Rpb24oKXt0aGlzLmNvbm5lY3Rpb24mJnRoaXMuY29ubmVjdGlvbi5jb25uZWN0KCEwKX0sdC5wcm90b3R5cGUuc2Q9ZnVuY3Rpb24odCl7fSx0LnByb3RvdHlwZS5Ybj1mdW5jdGlvbigpe3JldHVybiB0aGlzLmNvbm5lY3Rpb259LHQucHJvdG90eXBlLmNsb3NlPWZ1bmN0aW9uKCl7dGhpcy5jb25uZWN0aW9uJiZ0aGlzLmNvbm5lY3Rpb24uY2xvc2UoKX0sdH0oKTtlLmpSPWh9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcj1pKDQpLG49ci52ZSxvPWkoMTYpO2koMzEpLGkoMzApO3ZhciBzLGE9aSgyKSxjPWkoNSksaD1pKDEzKSxwPWkoMTApLHU9aSgxNCksbD1pKDIzKTshZnVuY3Rpb24odCl7dmFyIGU9XCJbU05BUF1cIixpPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMubWV0cmljcz1uZXcgaGl2ZS5zbmFwc2hvdHMuTWV0cmljcyx0aGlzLnVrPW5ldyBoaXZlLnNuYXBzaG90cy5UcmFmZmljLHRoaXMubGs9bmV3IG4sdGhpcy5kaz1uZXcgbix0aGlzLmZrPW5ldyBuLHRoaXMucGxheWVyPW5ldyBoaXZlLnNuYXBzaG90cy5QbGF5ZXJ9cmV0dXJuIHR9KCk7dC5naz1pO3ZhciByPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gaSgpe3RoaXMudGlja2V0PW51bGwsdGhpcy52az0wLHRoaXMueWs9MCx0aGlzLm1rKCl9cmV0dXJuIGkucHJvdG90eXBlLmluaXQ9ZnVuY3Rpb24odCxpLHIsbil7dGhpcy5tPWEuRnJhbWV3b3JrLnJlc29sdmUoYS5GcmFtZXdvcmsuRmUud2UpLmxvZyhuKSx0aGlzLnRuPWEuRnJhbWV3b3JrLnJlc29sdmUoYy5naS5jaSksdGhpcy5tLmRlYnVnKGUrXCIgSU5JVCBTVEFUUyBTVE9SRSAtIElEOiBcIit0KSx0aGlzLnNuPXQsdGhpcy50aWNrZXQ9aSx0aGlzLmFuKHIpfSxpLnByb3RvdHlwZS53az1mdW5jdGlvbih0KXt0aGlzLlRrPXR9LGkucHJvdG90eXBlLmFuPWZ1bmN0aW9uKHQpe3RoaXMuYXBwPXR9LGkucHJvdG90eXBlLm1rPWZ1bmN0aW9uKCl7dGhpcy5Taz1uZXcgdC5nayx0aGlzLnNuPW51bGwsdGhpcy50aWNrZXQ9bnVsbCx0aGlzLnJlc2V0KCl9LGkucHJvdG90eXBlLnJlc2V0PWZ1bmN0aW9uKCl7dGhpcy5CUj1uZXcgdC5nayx0aGlzLmJrKHRoaXMuQlIudWspLHRoaXMuRWsodGhpcy5CUil9LGkucHJvdG90eXBlLmJrPWZ1bmN0aW9uKHQpe3QucmVzcEZhbGxiYWNrTj0wLHQucmVzcEZhbGxiYWNrRXJyTj0wLHQuc3JjUmVxTj0wLHQuc3JjUmVzcEVyck49MCx0LnNyY1Jlc3BRdD0wLHQuc3JjT3RoZXJSZXNwTj0wLHQuc3JjUmVzcE49MCx0LnNyY092ZXJRdD0wLHQucDJwRGlyZWN0UXQ9MCx0LnAycE5hdFF0PTAsdC5wMnBVZHBiUXQ9MCx0LnAycFJlbGF5UXQ9MCx0LnAycE91dFNpdGVMb3dQcmlvPTAsdC5yZXNwUDJwTj0wLHQucDJwU3ViUmVxTj0wLHQucDJwU3ViUmVzcEVyck49MCx0LnAycFN1YlJlc3BRdD0wLHQucDJwU3ViUmVzcFBhcnROPTB9LGkucHJvdG90eXBlLkVrPWZ1bmN0aW9uKHQpe3QubWV0cmljcy52aWRlb0J1Zk49MCx0Lm1ldHJpY3MudmlkZW9CdWZRdD0wLHQubWV0cmljcy5jbGllbnRCdWZmZXJNcz0wLHQucGxheWVyLmJ1ZmZlcmluZ049MCx0LnBsYXllci5idWZmZXJpbmdNcz0wfSxpLnByb3RvdHlwZS5Jaz1mdW5jdGlvbigpe3ZhciB0PXRoaXMsaT1uZXcgaGl2ZS5zbmFwc2hvdHMuTWV0cmljU25hcHNob3Q7aS50aW1lc3RhbXA9YS5GcmFtZXdvcmsudGltZSgpLGkuZ3VpZD10aGlzLnNuLGkuc2Vzc2lvbklkPXRoaXMudGlja2V0LnNlc3Npb25JZCxpLmV2ZW50SWQ9bmV3IEV2ZW50SWQsaS5ldmVudElkLnBhcnRuZXJJZD10aGlzLnRpY2tldC5ibigpLGkuZXZlbnRJZC5jdXN0b21lcklkPXRoaXMudGlja2V0LkVuKCksaS5ldmVudElkLmNvbnRlbnRJZD10aGlzLnRpY2tldC5lcygpO3RyeXt2YXIgcj1uZXcgaGl2ZS5zbmFwc2hvdHMuQ2xpZW50SW5mbztyLmNsaWVudFR5cGU9dGhpcy5SaygpO3ZhciBuPXRoaXMuYXBwLnZlcnNpb24uc3BsaXQoXCIuXCIpO3IubWFqb3JWZXJzaW9uPXBhcnNlSW50KG5bMF0pLHIubWlub3JWZXJzaW9uPXBhcnNlSW50KG5bMV0pLHIucGF0Y2hWZXJzaW9uPXBhcnNlSW50KG5bMl0pLGkuY2xpZW50PXJ9Y2F0Y2gobyl7dGhpcy5tLndhcm4oZStcIiBlcnJvciBzZXR0aW5nIFNuYXBzaG90IENsaWVudEluZm9cIixvKX1pLnN0cmVhbUluZm89dGhpcy54Ui5raygpLGkudHJhZmZpYz1bXTt2YXIgcz1uZXcgaGl2ZS5zbmFwc2hvdHMuVHJhZmZpY0tleTtpZihpLnRyYWZmaWMucHVzaCh7a2V5OnMsdmFsdWU6dGhpcy5CUi51a30pLHRoaXMuQlIubGsuZm9yRWFjaChmdW5jdGlvbih0LGUpe3ZhciByPW5ldyBoaXZlLnNuYXBzaG90cy5UcmFmZmljS2V5O3IuYml0cmF0ZT1lLGkudHJhZmZpYy5wdXNoKHtrZXk6cix2YWx1ZTp0fSl9KSxpLm1ldHJpY3M9dGhpcy5CUi5tZXRyaWNzLHRoaXMuVGsmJihpLm1ldHJpY3MuY2xpZW50QnVmZmVyTXM9dGhpcy5Uay5taW4oKSksaS5wbGF5ZXI9dGhpcy5CUi5wbGF5ZXIsdGhpcy5Dayl7dmFyIGM9dGhpcy5Day5nZXRQYXJ0bmVyU25hcHNob3RzKCk7Yy5mb3JFYWNoKGZ1bmN0aW9uKGUscil7dC5PayhyLGUsaSl9KSx0aGlzLkJSLmZrLmZpbHRlcihmdW5jdGlvbih0LGUpe3JldHVybiFjLmhhcyhlKX0pLmZvckVhY2goZnVuY3Rpb24oZSxyKXt0Lk9rKHIsZSxpKX0pfXJldHVybiBpLmNvbm5JbmZvPW5ldyBoaXZlLnNuYXBzaG90cy5Db25uZWN0aXZpdHlJbmZvLHRoaXMudG4uUG4oKS50aGVuKGZ1bmN0aW9uKGUpe3JldHVybiBpLmNvbm5JbmZvLnByaXZhdGVJcD1lLk5uKCkuQm4oKSx0LlBrKGkpfSkuZmFpbChmdW5jdGlvbihlKXtyZXR1cm4gdC5QayhpKX0pfSxpLnByb3RvdHlwZS5Qaz1mdW5jdGlvbih0KXtyZXR1cm4gdC5jb25uSW5mby5pbnRlcm5hbEFzPXRoaXMudmssdC5jb25uSW5mby5leHRlcm5hbEFzPXRoaXMueWssdC5jb25uSW5mby5wdWJsaWNJcD10aGlzLkFrLHR9LGkucHJvdG90eXBlLlJrPWZ1bmN0aW9uKCl7dmFyIHQ7c3dpdGNoKHRoaXMuYXBwLmFwcCl7Y2FzZVwiSlNcIjp0PUNsaWVudFR5cGUuRmY7YnJlYWs7Y2FzZVwiUFJPWFlcIjp0PUNsaWVudFR5cGUuX2Y7YnJlYWs7ZGVmYXVsdDp0PUNsaWVudFR5cGUuQmZ9cmV0dXJuIHR9LGkucHJvdG90eXBlLk9rPWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj10aGlzLkJSLmRrLmdldCh0KTtlLnRyYWZmaWM9cixpLnBhcnRuZXJzfHwoaS5wYXJ0bmVycz1bXSk7dmFyIG49bmV3IGhpdmUuc25hcHNob3RzLlBhcnRuZXJLZXk7bi5wYXJ0bmVyR3VpZD10LGkucGFydG5lcnMucHVzaCh7a2V5Om4sdmFsdWU6ZX0pfSxpLnByb3RvdHlwZS5DUj1mdW5jdGlvbih0LGUpe3Q+MCYmKHRoaXMuQlIubWV0cmljcy52aWRlb0J1Zk4rKyx0aGlzLkJSLm1ldHJpY3MudmlkZW9CdWZRdCs9dCx0aGlzLkJSLnBsYXllci5idWZmZXJpbmdOKyssdGhpcy5CUi5wbGF5ZXIuYnVmZmVyaW5nTXMrPXQpLHRoaXMuQlIucGxheWVyLnBsYXllckJ1ZmZlck1zPWV9LGkucHJvdG90eXBlLkhSPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuQlIudWt9LGkucHJvdG90eXBlLk5rPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuU2sudWt9LGkucHJvdG90eXBlLnhrPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLlNrLmxrLmhhcyh0KXx8dGhpcy5Tay5say5zZXQodCxuZXcgaGl2ZS5zbmFwc2hvdHMuVHJhZmZpYyksdGhpcy5Tay5say5nZXQodCl9LGkucHJvdG90eXBlLl9SPWZ1bmN0aW9uKHQpe2lmKCF0aGlzLkJSLmxrLmhhcyh0KSl7dmFyIGU9bmV3IGhpdmUuc25hcHNob3RzLlRyYWZmaWM7dGhpcy5iayhlKSx0aGlzLkJSLmxrLnNldCh0LGUpfXJldHVybiB0aGlzLkJSLmxrLmdldCh0KX0saS5wcm90b3R5cGUuQms9ZnVuY3Rpb24odCxlKXtyZXR1cm4gZS5kay5oYXModCl8fGUuZGsuc2V0KHQsbmV3IGhpdmUuc25hcHNob3RzLlBhcnRuZXJUcmFmZmljKSxlLmRrLmdldCh0KX0saS5wcm90b3R5cGUuRms9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuQmsodCx0aGlzLkJSKX0saS5wcm90b3R5cGUuX2s9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuQmsodCx0aGlzLlNrKX0saS5wcm90b3R5cGUuRGs9ZnVuY3Rpb24odCl7dGhpcy50bj10fSxpLnByb3RvdHlwZS5Iaz1mdW5jdGlvbih0KXt0aGlzLkNrPXR9LGkucHJvdG90eXBlLmpuPWZ1bmN0aW9uKHQpe30saX0oKTt0LnpmPXI7dmFyIHM9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7dGhpcy5Maz1pc05hTihsLkhpdmVDb25maWcuRGVidWdMb2dzLk1ldHJpY1NuYXBzaG90TG9ncyk/MDpsLkhpdmVDb25maWcuRGVidWdMb2dzLk1ldHJpY1NuYXBzaG90TG9ncyx0aGlzLnN0YXRlPXUuRm8uQm8sdGhpcy5jbGllbnQ9YS5GcmFtZXdvcmsucmVzb2x2ZShjLmdpLkJlKSx0aGlzLlhhPW5ldyBvLkVhLHRoaXMucHJvdG9jb2w9bmV3IG8uJGEodGhpcy5YYSl9cmV0dXJuIHQucHJvdG90eXBlLmluaXQ9ZnVuY3Rpb24odCxpKXt0aGlzLm09YS5GcmFtZXdvcmsucmVzb2x2ZShhLkZyYW1ld29yay5GZS53ZSkubG9nKGkpLHRoaXMubS5kZWJ1ZyhlK1wiIElOSVQgQ0xJRU5UIFNUQVRTXCIpLHRoaXMuVmY9dCx0aGlzLk1rKCl9LHQucHJvdG90eXBlLk1rPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpczt0aGlzLmprPi0xJiZhLkZyYW1ld29yay5jbGVhckludGVydmFsKHRoaXMuamspLHRoaXMuams9YS5GcmFtZXdvcmsuc2V0SW50ZXJ2YWwoZnVuY3Rpb24oKXt0LlVrKCl9LGguS24uSm4uUG8pfSx0LnByb3RvdHlwZS5DaT1mdW5jdGlvbih0KXt0aGlzLnN0YXRlPXR9LHQucHJvdG90eXBlLnJlc2V0PWZ1bmN0aW9uKCl7YS5GcmFtZXdvcmsuY2xlYXJJbnRlcnZhbCh0aGlzLmprKSx0aGlzLlZmJiZ0aGlzLlZmLm1rKCl9LHQucHJvdG90eXBlLlVrPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpczt0aGlzLm0uZGVidWcoXCJbU05BUF0gVEFLSU5HIFNOQVBTSE9UXCIpO3ZhciBlPXRoaXMuVmYuSWsoKTtlLnRoZW4oZnVuY3Rpb24oZSl7cmV0dXJuIHQuZm9yd2FyZChlKX0pLmZhaWwoZnVuY3Rpb24oZSl7dC5tLndhcm4oXCJbU05BUF0gRVJST1IgRk9SV0FSRElORyBTTkFQU0hPVFwiLGUpfSlbXCJmaW5hbGx5XCJdKGZ1bmN0aW9uKCl7dC5WZi5yZXNldCgpfSl9LHQucHJvdG90eXBlLmZvcndhcmQ9ZnVuY3Rpb24odCl7dmFyIGk9dGhpcztpZih0aGlzLnN0YXRlPT09dS5Gby5JRExFKXJldHVybiB2b2lkIHRoaXMubS5kZWJ1ZyhlK1wiIG5vdCBzZW5kIC0gc3RhdGUgaWRsZVwiKTtpZih0aGlzLmNsaWVudCYmdGhpcy5jbGllbnQuWG4oKSl7c3dpdGNoKHRoaXMuTGspe2Nhc2UgMDpkZWZhdWx0OnRoaXMubS5kZWJ1ZyhlK1wiIFNFTkRJTkcgU05BUFNIT1RcIik7YnJlYWs7Y2FzZSAxOnRoaXMubS5kZWJ1ZyhlK1wiIFNFTkRJTkcgU05BUFNIT1QgXCIrSlNPTi5zdHJpbmdpZnkodCkpO2JyZWFrO2Nhc2UgMjp0aGlzLm0uZGVidWcoZStcIiBTRU5ESU5HIFNOQVBTSE9UXCIsdCk7YnJlYWs7Y2FzZSAzOnRoaXMubS5kZWJ1ZyhlK1wiIFNFTkRJTkcgU05BUFNIT1QgXCIrSlNPTi5zdHJpbmdpZnkodCksdCl9dGhpcy5wcm90b2NvbC5wYyhcIlNOQVBTSE9UXCIsby5Mcy5WcywwKSx0LndyaXRlKHRoaXMucHJvdG9jb2wpLHRoaXMucHJvdG9jb2wuZGMoKTt2YXIgcj10aGlzLlhhLkhhKCksbj10aGlzLlZrKHIsXCIsXCIsNCkscz1yLnNsaWNlKG4rMSxyLmxlbmd0aC0xKSxhPW5ldyBwLlpuKFNlcnZpY2VzLnRvLDEscyk7dGhpcy5jbGllbnQuWG4oKS5zZW5kKGEpLmZhaWwoZnVuY3Rpb24odCl7aS5tLndhcm4oZStcIiBQUk9CTEVNOiBcIix0KX0pfX0sdC5wcm90b3R5cGUuVms9ZnVuY3Rpb24odCxlLGkpe3JldHVybiB0LnNwbGl0KGUsaSkuam9pbihlKS5sZW5ndGh9LHR9KCk7dC5lbz1zfShzPWUuU3RhdHN8fChlLlN0YXRzPXt9KSl9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcj1pKDEpLG49aSg0KSxvPWkoMikscz1pKDUpLGE9aSg1OCksYz1pKDU0KSxoPWkoNjUpLHA9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7dGhpcy5Raz1udWxsLHRoaXMucWs9bnVsbCx0aGlzLkprPW51bGwsdGhpcy5Laz1udWxsLHRoaXMuR2s9bmV3IG4udmUsdGhpcy5wdWJsaWNJcD1udWxsLHRoaXMuems9W10sdGhpcy5faT0hMSx0aGlzLldrPW51bGwsdGhpcy5tPW8uRnJhbWV3b3JrLnJlc29sdmUoby5GcmFtZXdvcmsuRmUud2UpLmxvZygpLHRoaXMuaWs9by5GcmFtZXdvcmsucmVzb2x2ZShzLmdpLmhpKSx0aGlzLiRrPW5ldyBjLmhrLHRoaXMuWWs9W10sdGhpcy5YaygpfXJldHVybiB0LnByb3RvdHlwZS5Yaz1mdW5jdGlvbigpe3ZhciB0PXRoaXM7by5GcmFtZXdvcmsuc2V0SW50ZXJ2YWwoZnVuY3Rpb24oKXt0LnprPVtdLHQuWWs9W10sdC5Haz1uZXcgbi52ZSx0LnB1YmxpY0lwPW51bGwsdC5aaz1udWxsfSwxMmU0KX0sdC5wcm90b3R5cGUuUG49ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5aa3x8KHRoaXMuWms9dGhpcy50QygpKSx0aGlzLlprfSx0LnByb3RvdHlwZS50Qz1mdW5jdGlvbigpe3ZhciB0PXRoaXMsZT1yLmRlZmVyKCk7aWYodGhpcy5Xaz1vLkZyYW1ld29yay5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ZS5yZWplY3Qoe2VDOiEwLG1lc3NhZ2U6XCJleHBpcmVkXCJ9KX0sNGUzKSx0aGlzLmlDKCkpdHJ5e3RoaXMuUWs9bmV3IFJUQ1BlZXJDb25uZWN0aW9uKG51bGwpLHRoaXMuSms9dGhpcy5Ray5jcmVhdGVEYXRhQ2hhbm5lbChcInNlbmRDaGFubmVsXCIse3JlbGlhYmxlOiExfSksdGhpcy5xaz1uZXcgUlRDUGVlckNvbm5lY3Rpb24obnVsbCksdGhpcy5xay5vbmRhdGFjaGFubmVsPWZ1bmN0aW9uKGkpe3QuS2s9aS5jaGFubmVsLHQuS2sub25vcGVuPWZ1bmN0aW9uKGkpe1wib3BlblwiPT09dC5Lay5yZWFkeVN0YXRlJiYodC5tLmRlYnVnKFwiQ29sbGVjdGVkIGlwcyBbXCIrdC5Hay5rZXlzKCkuam9pbihcIiwgXCIpK1wiXVwiKSx0LnFrLmNsb3NlKCksdC4kay5uaygpLnRoZW4oZnVuY3Rpb24oZSl7dC5Zaz1lLHQubS5kZWJ1ZyhcIkFscmVhZHkga25vd24gbWF0Y2hpbmcgaXBzIFtcIit0LllrLmpvaW4oXCIsXCIpK1wiXVwiKTt2YXIgaT10LkdrLmtleXMoKTt0LllrLmZvckVhY2goZnVuY3Rpb24oZSl7aS5pbmRleE9mKGUpPjAmJih0LnprLnB1c2goZSksdC5Ha1tcImRlbGV0ZVwiXShlKSl9KSx0LkdrLmtleXMoKS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3QuemsucHVzaChlKX0pfSkuZmFpbChmdW5jdGlvbihlKXt0Lm0ud2FybihcIkdldCBQcmV2aW91cyB3b3JraW5nIGlwcyBmYWlsZWQgd2l0aCBlcnJvciBcIitlLm1lc3NhZ2UpLHQuR2sua2V5cygpLmZvckVhY2goZnVuY3Rpb24oZSl7dC56ay5wdXNoKGUpfSl9KVtcImZpbmFsbHlcIl0oZnVuY3Rpb24oKXt0Lm0uZGVidWcoXCJGaW5hbCBwcml2YXRlIGlwIGxpc3QgW1wiK3Quemsuam9pbihcIixcIikrXCJdXCIpLGUucmVzb2x2ZSh0LnJDKCkpfSkpfX0sdGhpcy5Ray5vbmljZWNhbmRpZGF0ZT1mdW5jdGlvbihpKXtpLmNhbmRpZGF0ZSYmdC56YihpLmNhbmRpZGF0ZS5jYW5kaWRhdGUpLCFpLmNhbmRpZGF0ZXx8dC5xay5hZGRJY2VDYW5kaWRhdGUoaS5jYW5kaWRhdGUpW1wiY2F0Y2hcIl0oZnVuY3Rpb24oaSl7ZS5yZWplY3Qoe2VDOiEwLG1lc3NhZ2U6aS5tZXNzYWdlfSksby5GcmFtZXdvcmsuY2xlYXJUaW1lb3V0KHQuV2spLGNvbnNvbGUubG9nKFwiRXJyb3I6IEZhaWx1cmUgZHVyaW5nIGFkZEljZUNhbmRpZGF0ZSgpXCIpfSl9LHRoaXMucWsub25pY2VjYW5kaWRhdGU9ZnVuY3Rpb24oaSl7aS5jYW5kaWRhdGUmJnQuemIoaS5jYW5kaWRhdGUuY2FuZGlkYXRlKSwhaS5jYW5kaWRhdGV8fHQuUWsuYWRkSWNlQ2FuZGlkYXRlKGkuY2FuZGlkYXRlKVtcImNhdGNoXCJdKGZ1bmN0aW9uKGkpe2UucmVqZWN0KHtlQzohMCxtZXNzYWdlOmkubWVzc2FnZX0pLG8uRnJhbWV3b3JrLmNsZWFyVGltZW91dCh0LldrKSxjb25zb2xlLmxvZyhcIkVycm9yOiBGYWlsdXJlIGR1cmluZyBhZGRJY2VDYW5kaWRhdGUoKVwiKX0pfSx0aGlzLlFrLmNyZWF0ZU9mZmVyKCkudGhlbihmdW5jdGlvbihlKXtyZXR1cm4gdC5Ray5zZXRMb2NhbERlc2NyaXB0aW9uKGUpfSkudGhlbihmdW5jdGlvbigpe3JldHVybiB0LnFrLnNldFJlbW90ZURlc2NyaXB0aW9uKHQuUWsubG9jYWxEZXNjcmlwdGlvbil9KS50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIHQucWsuY3JlYXRlQW5zd2VyKCl9KS50aGVuKGZ1bmN0aW9uKGUpe3JldHVybiB0LnFrLnNldExvY2FsRGVzY3JpcHRpb24oZSl9KS50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIHQuUWsuc2V0UmVtb3RlRGVzY3JpcHRpb24odC5xay5sb2NhbERlc2NyaXB0aW9uKX0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24oaSl7ZS5yZWplY3Qoe2VDOiEwLG1lc3NhZ2U6aS5tZXNzYWdlfSksby5GcmFtZXdvcmsuY2xlYXJUaW1lb3V0KHQuV2spLGNvbnNvbGUubG9nKFwiRXJyb3I6IEZhaWx1cmUgY3JlYXRpbmcgb2ZmZXJcIil9KX1jYXRjaChpKXtlLnJlamVjdCh7ZUM6ITAsbWVzc2FnZTppLm1lc3NhZ2V9KX1lbHNlIG8uRnJhbWV3b3JrLmNsZWFyVGltZW91dCh0aGlzLldrKSxlLnJlamVjdCh7ZUM6ITEsbWVzc2FnZTpcIndlYnJ0YyBkYXRhY2hhbm5lbCBub3Qgc3VwcG9ydGVkXCJ9KTtyZXR1cm4gZS52dH0sdC5wcm90b3R5cGUuaUM9ZnVuY3Rpb24oKXt0cnl7cmV0dXJuIG51bGwhPWguWGUmJm51bGwhPWgubkMmJlwiZnVuY3Rpb25cIj09dHlwZW9mIG5ldyBSVENQZWVyQ29ubmVjdGlvbihudWxsLG51bGwpLmNyZWF0ZURhdGFDaGFubmVsfWNhdGNoKHQpe3JldHVybiExfX0sdC5wcm90b3R5cGUuemI9ZnVuY3Rpb24odCl7dmFyIGU9LyhbMC05XXsxLDN9KFxcLlswLTldezEsM30pezN9KS8saT1lLmV4ZWModCk7aWYoaSl7dmFyIHI9aVswXTt0aGlzLkdrLnNldChyLCEwKX19LHQucHJvdG90eXBlLnJDPWZ1bmN0aW9uKCl7dmFyIHQ9bmV3IGEub0M7cmV0dXJuIHRoaXMuemsubGVuZ3RoPjAmJnQuc0ModGhpcy56a1swXSksdGhpcy5wdWJsaWNJcCYmdC5hQyh0aGlzLnB1YmxpY0lwKSx0aGlzLmlrLkpSKHQpLHRoaXMuaWt9LHQucHJvdG90eXBlLnJrPWZ1bmN0aW9uKHQsZSxpKXtpZih0aGlzLnB1YmxpY0lwPXQsdGhpcy5jQygpLDA9PT1pJiZ0aGlzLnprLmxlbmd0aD4xKXRoaXMuemsuc2hpZnQoKTtlbHNlIGlmKDAhPT1pJiZ0aGlzLllrLmluZGV4T2YodGhpcy56a1swXSk9PS0xKXRoaXMuWWsudW5zaGlmdCh0aGlzLnprWzBdKSx0aGlzLiRrLmNrKHRoaXMuWWsuc2xpY2UoMCwyKSk7ZWxzZSBpZigwIT09aSYmdGhpcy5Zay5pbmRleE9mKHRoaXMuemtbMF0pPjApe3ZhciByPXRoaXMuWWsuaW5kZXhPZih0aGlzLnprWzBdKTt0aGlzLllrPXRoaXMuWWsuc3BsaWNlKHIsMSksdGhpcy5Zay51bnNoaWZ0KHRoaXMuemtbMF0pLHRoaXMuJGsuY2sodGhpcy5Zay5zbGljZSgwLDIpKX10aGlzLnJDKCl9LHQucHJvdG90eXBlLmNDPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy56ay5pbmRleE9mKHRoaXMucHVibGljSXApO3Q+LTEmJnRoaXMuemsuc3BsaWNlKHQsMSl9LHR9KCk7ZS5NUj1wfSxmdW5jdGlvbih0LGUpe1widXNlIHN0cmljdFwiO3ZhciBpPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdC5wcm90b3R5cGUuYUM9ZnVuY3Rpb24odCl7dGhpcy5wdWJsaWNJcD10fSx0LnByb3RvdHlwZS54bj1mdW5jdGlvbigpe3JldHVybiB0aGlzLnB1YmxpY0lwfSx0LnByb3RvdHlwZS5oQz1mdW5jdGlvbih0KXt0aGlzLnBDPXR9LHQucHJvdG90eXBlLkxuPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucEN9LHQucHJvdG90eXBlLnVDPWZ1bmN0aW9uKHQpe3RoaXMubmljPXR9LHQucHJvdG90eXBlLkRuPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubmljfSx0LnByb3RvdHlwZS5sQz1mdW5jdGlvbih0KXt0aGlzLm5pY05hbWU9dH0sdC5wcm90b3R5cGUuSG49ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5uaWNOYW1lfSx0LnByb3RvdHlwZS5zQz1mdW5jdGlvbih0KXt0aGlzLnByaXZhdGVJcD10fSx0LnByb3RvdHlwZS5Cbj1mdW5jdGlvbigpe3JldHVybiB0aGlzLnByaXZhdGVJcH0sdC5wcm90b3R5cGUuZEM9ZnVuY3Rpb24odCl7dGhpcy5uZXRtYXNrPXR9LHQucHJvdG90eXBlLmZDPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubmV0bWFza30sdC5wcm90b3R5cGUuZ0M9ZnVuY3Rpb24odCl7dGhpcy52Qz10fSx0LnByb3RvdHlwZS5fbj1mdW5jdGlvbigpe3JldHVybiBudWxsfSx0fSgpO2Uub0M9aX0sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjt2YXIgaT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlLGkpe3RoaXMuaXNMaXZlPXQsdGhpcy5wcm90b2NvbD1lLHRoaXMueUM9aX1yZXR1cm4gdC5wcm90b3R5cGUua2s9ZnVuY3Rpb24oKXt2YXIgdD1uZXcgaGl2ZS5zbmFwc2hvdHMuU3RyZWFtSW5mbztyZXR1cm4gdC5zdHJlYW1UeXBlPXRoaXMuaXNMaXZlP1N0cmVhbVR5cGUuTElWRTpTdHJlYW1UeXBlLlBmLHQuc3RyZWFtUHJvdG9jb2w9dGhpcy5wcm90b2NvbCx0LnVybD10aGlzLnlDLHR9LHR9KCk7ZS5OUj1pfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7aSgyOSk7dmFyIHI9aSgxKSxuPWkoNCksbz1uLnZlLHM9aSgyKSxhPWkoMjApLGM9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQpe3RoaXMuaW89KG5ldyBEYXRlKS5nZXRUaW1lKCksdGhpcy5tQz10fXJldHVybiB0fSgpLGg9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7dGhpcy53Qz1uZXcgbyx0aGlzLm09KHMuRnJhbWV3b3JrLnJlc29sdmUocy5GcmFtZXdvcmsuRmUud2UpfHxjb25zb2xlKS5sb2coKSx0aGlzLm0uZGVidWcoXCJJTklUIFRJQ0tFVCBSRVNPTFZFUlwiKX1yZXR1cm4gdC5wcm90b3R5cGUucmVzb2x2ZT1mdW5jdGlvbih0LGUsaSl7dmFyIG49dGhpcyxvPXIuZGVmZXIoKTtyZXR1cm4gdCYmKHQub24oU2VydmljZXMua2YsMCxmdW5jdGlvbih0KXtuLlRDKHQpfSksdC5vbihTZXJ2aWNlcy5rZiwyLGZ1bmN0aW9uKHQpe24uVEModCl9KSx0aGlzLndDLnNldChlLG5ldyBjKG8pKSksby52dH0sdC5wcm90b3R5cGUuVEM9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcyxpPShuZXcgRGF0ZSkuZ2V0VGltZSgpLHI9SlNPTi5wYXJzZSh0Lm1zZyksbj0hMTt0aGlzLndDLmZvckVhY2goZnVuY3Rpb24odCxvKXtpZihlLlNDKG8scikpe249ITA7dmFyIHM9ZS4kbChvLHIpO3M/KHMuaW89dC5pbyxzLnJvPWksdC5tQy5yZXNvbHZlKHMpKTp0Lm1DLnJlamVjdChcIlRpY2tldCB2ZXJpZmljYXRpb24gZmFpbGVkXCIpLGUud0NbXCJkZWxldGVcIl0ocyl9fSksbnx8dGhpcy5tLndhcm4oXCJubyBwZW5kaW5nIHRpY2tldCBtYXRjaGluZzogXCIrdC5tc2cpfSx0LnByb3RvdHlwZS5Hbz1mdW5jdGlvbih0KXt2YXIgZT1uZXcgUmVnRXhwKFwiXmh0dHBzPzovL2FwaSg/Oi10ZXN0KT8uaGl2ZXN0cmVhbWluZy5jb20vdjEvZXZlbnRzLyg/OndpbGRjYXJkLyk/XCIpO2lmKGUudGVzdCh0KSl7dmFyIGk9dGhpcy5iQygpO3JldHVybiBpLktoKHQpLGl9cmV0dXJuIG51bGx9LHQucHJvdG90eXBlLmJDPWZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBhLmFwfSx0LnByb3RvdHlwZS5TQz1mdW5jdGlvbih0LGUpe3JldHVybiB0LmJuKCk9PT1lW2EuYXAub3BdJiZ0LkVuKCk9PT1lW2EuYXAubnBdJiZ0LmVzKCk9PT1lW2EuYXAuc3BdfSx0LnByb3RvdHlwZS4kbD1mdW5jdGlvbih0LGUpe3JldHVybiB0LlVoKGUpLHQuUWgoKT90Om51bGx9LHR9KCk7ZS5VUj1ofSxmdW5jdGlvbih0LGUpe1wiZnVuY3Rpb25cIj09dHlwZW9mIE9iamVjdC5jcmVhdGU/dC50PWZ1bmN0aW9uKHQsZSl7dC5FQz1lLHQucHJvdG90eXBlPU9iamVjdC5jcmVhdGUoZS5wcm90b3R5cGUse2NvbnN0cnVjdG9yOnt2YWx1ZTp0LEFnOiExLFBnOiEwLE5nOiEwfX0pfTp0LnQ9ZnVuY3Rpb24odCxlKXt0LkVDPWU7dmFyIGk9ZnVuY3Rpb24oKXt9O2kucHJvdG90eXBlPWUucHJvdG90eXBlLHQucHJvdG90eXBlPW5ldyBpLHQucHJvdG90eXBlLmNvbnN0cnVjdG9yPXR9fSxmdW5jdGlvbih0LGUpe3QudD1mdW5jdGlvbih0KXtyZXR1cm4gdCYmXCJvYmplY3RcIj09dHlwZW9mIHQmJlwiZnVuY3Rpb25cIj09dHlwZW9mIHQuY29weSYmXCJmdW5jdGlvblwiPT10eXBlb2YgdC5maWxsJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiB0LnJlYWRVSW50OH19LGZ1bmN0aW9uKHQsZSxpKXtmdW5jdGlvbiByKHQsaSl7dmFyIHI9e0lDOltdLFJDOm99O3JldHVybiBhcmd1bWVudHMubGVuZ3RoPj0zJiYoci5rQz1hcmd1bWVudHNbMl0pLGFyZ3VtZW50cy5sZW5ndGg+PTQmJihyLkNDPWFyZ3VtZW50c1szXSksZihpKT9yLk9DPWk6aSYmZS5QQyhyLGkpLFQoci5PQykmJihyLk9DPSExKSxUKHIua0MpJiYoci5rQz0yKSxUKHIuQ0MpJiYoci5DQz0hMSksVChyLkFDKSYmKHIuQUM9ITApLHIuQ0MmJihyLlJDPW4pLGEocix0LHIua0MpfWZ1bmN0aW9uIG4odCxlKXt2YXIgaT1yLk5DW2VdO3JldHVybiBpP1wiXHUwMDFiW1wiK3IuQ0NbaV1bMF0rXCJtXCIrdCtcIlx1MDAxYltcIityLkNDW2ldWzFdK1wibVwiOnR9ZnVuY3Rpb24gbyh0LGUpe3JldHVybiB0fWZ1bmN0aW9uIHModCl7dmFyIGU9e307cmV0dXJuIHQuZm9yRWFjaChmdW5jdGlvbih0LGkpe2VbdF09ITB9KSxlfWZ1bmN0aW9uIGEodCxpLHIpe2lmKHQuQUMmJmkmJlIoaS5ndCkmJmkuZ3QhPT1lLmd0JiYoIWkuY29uc3RydWN0b3J8fGkuY29uc3RydWN0b3IucHJvdG90eXBlIT09aSkpe3ZhciBuPWkuZ3Qocix0KTtyZXR1cm4gbShuKXx8KG49YSh0LG4scikpLG59dmFyIG89Yyh0LGkpO2lmKG8pcmV0dXJuIG87dmFyIGY9T2JqZWN0LmtleXMoaSksZz1zKGYpO2lmKHQuT0MmJihmPU9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGkpKSxJKGkpJiYoZi5pbmRleE9mKFwibWVzc2FnZVwiKT49MHx8Zi5pbmRleE9mKFwiZGVzY3JpcHRpb25cIik+PTApKXJldHVybiBoKGkpO2lmKDA9PT1mLmxlbmd0aCl7aWYoUihpKSl7dmFyIHY9aS5uYW1lP1wiOiBcIitpLm5hbWU6XCJcIjtyZXR1cm4gdC5SQyhcIltGdW5jdGlvblwiK3YrXCJdXCIsXCJzcGVjaWFsXCIpfWlmKFMoaSkpcmV0dXJuIHQuUkMoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGkpLFwicmVnZXhwXCIpO2lmKEUoaSkpcmV0dXJuIHQuUkMoRGF0ZS5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpKSxcImRhdGVcIik7aWYoSShpKSlyZXR1cm4gaChpKX12YXIgeT1cIlwiLHc9ITEsVD1bXCJ7XCIsXCJ9XCJdO2lmKGQoaSkmJih3PSEwLFQ9W1wiW1wiLFwiXVwiXSksUihpKSl7dmFyIGI9aS5uYW1lP1wiOiBcIitpLm5hbWU6XCJcIjt5PVwiIFtGdW5jdGlvblwiK2IrXCJdXCJ9aWYoUyhpKSYmKHk9XCIgXCIrUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGkpKSxFKGkpJiYoeT1cIiBcIitEYXRlLnByb3RvdHlwZS50b1VUQ1N0cmluZy5jYWxsKGkpKSxJKGkpJiYoeT1cIiBcIitoKGkpKSwwPT09Zi5sZW5ndGgmJighd3x8MD09aS5sZW5ndGgpKXJldHVybiBUWzBdK3krVFsxXTtpZihyPDApcmV0dXJuIFMoaSk/dC5SQyhSZWdFeHAucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaSksXCJyZWdleHBcIik6dC5SQyhcIltPYmplY3RdXCIsXCJzcGVjaWFsXCIpO3QuSUMucHVzaChpKTt2YXIgaztyZXR1cm4gaz13P3AodCxpLHIsZyxmKTpmLm1hcChmdW5jdGlvbihlKXtyZXR1cm4gdSh0LGkscixnLGUsdyl9KSx0LklDLnBvcCgpLGwoayx5LFQpfWZ1bmN0aW9uIGModCxlKXtpZihUKGUpKXJldHVybiB0LlJDKFwidW5kZWZpbmVkXCIsXCJ1bmRlZmluZWRcIik7aWYobShlKSl7dmFyIGk9XCInXCIrSlNPTi5zdHJpbmdpZnkoZSkucmVwbGFjZSgvXlwifFwiJC9nLFwiXCIpLnJlcGxhY2UoLycvZyxcIlxcXFwnXCIpLnJlcGxhY2UoL1xcXFxcIi9nLCdcIicpK1wiJ1wiO3JldHVybiB0LlJDKGksXCJzdHJpbmdcIil9cmV0dXJuIHkoZSk/dC5SQyhcIlwiK2UsXCJudW1iZXJcIik6ZihlKT90LlJDKFwiXCIrZSxcImJvb2xlYW5cIik6ZyhlKT90LlJDKFwibnVsbFwiLFwibnVsbFwiKTp2b2lkIDB9ZnVuY3Rpb24gaCh0KXtyZXR1cm5cIltcIitFcnJvci5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KStcIl1cIn1mdW5jdGlvbiBwKHQsZSxpLHIsbil7Zm9yKHZhciBvPVtdLHM9MCxhPWUubGVuZ3RoO3M8YTsrK3MpQShlLFN0cmluZyhzKSk/by5wdXNoKHUodCxlLGkscixTdHJpbmcocyksITApKTpvLnB1c2goXCJcIik7cmV0dXJuIG4uZm9yRWFjaChmdW5jdGlvbihuKXtuLm1hdGNoKC9eXFxkKyQvKXx8by5wdXNoKHUodCxlLGkscixuLCEwKSl9KSxvfWZ1bmN0aW9uIHUodCxlLGkscixuLG8pe3ZhciBzLGMsaDtpZihoPU9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZSxuKXx8e3ZhbHVlOmVbbl19LGguZ2V0P2M9aC5zZXQ/dC5SQyhcIltHZXR0ZXIvU2V0dGVyXVwiLFwic3BlY2lhbFwiKTp0LlJDKFwiW0dldHRlcl1cIixcInNwZWNpYWxcIik6aC5zZXQmJihjPXQuUkMoXCJbU2V0dGVyXVwiLFwic3BlY2lhbFwiKSksQShyLG4pfHwocz1cIltcIituK1wiXVwiKSxjfHwodC5JQy5pbmRleE9mKGgudmFsdWUpPDA/KGM9ZyhpKT9hKHQsaC52YWx1ZSxudWxsKTphKHQsaC52YWx1ZSxpLTEpLGMuaW5kZXhPZihcIlxcblwiKT4tMSYmKGM9bz9jLnNwbGl0KFwiXFxuXCIpLm1hcChmdW5jdGlvbih0KXtyZXR1cm5cIiAgXCIrdH0pLmpvaW4oXCJcXG5cIikuc3Vic3RyKDIpOlwiXFxuXCIrYy5zcGxpdChcIlxcblwiKS5tYXAoZnVuY3Rpb24odCl7cmV0dXJuXCIgICBcIit0fSkuam9pbihcIlxcblwiKSkpOmM9dC5SQyhcIltDaXJjdWxhcl1cIixcInNwZWNpYWxcIikpLFQocykpe2lmKG8mJm4ubWF0Y2goL15cXGQrJC8pKXJldHVybiBjO3M9SlNPTi5zdHJpbmdpZnkoXCJcIituKSxzLm1hdGNoKC9eXCIoW2EtekEtWl9dW2EtekEtWl8wLTldKilcIiQvKT8ocz1zLnN1YnN0cigxLHMubGVuZ3RoLTIpLHM9dC5SQyhzLFwibmFtZVwiKSk6KHM9cy5yZXBsYWNlKC8nL2csXCJcXFxcJ1wiKS5yZXBsYWNlKC9cXFxcXCIvZywnXCInKS5yZXBsYWNlKC8oXlwifFwiJCkvZyxcIidcIikscz10LlJDKHMsXCJzdHJpbmdcIikpfXJldHVybiBzK1wiOiBcIitjfWZ1bmN0aW9uIGwodCxlLGkpe3ZhciByPTAsbj10LnJlZHVjZShmdW5jdGlvbih0LGUpe3JldHVybiByKyssZS5pbmRleE9mKFwiXFxuXCIpPj0wJiZyKyssdCtlLnJlcGxhY2UoL1xcdTAwMWJcXFtcXGRcXGQ/bS9nLFwiXCIpLmxlbmd0aCsxfSwwKTtyZXR1cm4gbj42MD9pWzBdKyhcIlwiPT09ZT9cIlwiOmUrXCJcXG4gXCIpK1wiIFwiK3Quam9pbihcIixcXG4gIFwiKStcIiBcIitpWzFdOmlbMF0rZStcIiBcIit0LmpvaW4oXCIsIFwiKStcIiBcIitpWzFdfWZ1bmN0aW9uIGQodCl7cmV0dXJuIEFycmF5LmlzQXJyYXkodCl9ZnVuY3Rpb24gZih0KXtyZXR1cm5cImJvb2xlYW5cIj09dHlwZW9mIHR9ZnVuY3Rpb24gZyh0KXtyZXR1cm4gbnVsbD09PXR9ZnVuY3Rpb24gdih0KXtyZXR1cm4gbnVsbD09dH1mdW5jdGlvbiB5KHQpe3JldHVyblwibnVtYmVyXCI9PXR5cGVvZiB0fWZ1bmN0aW9uIG0odCl7cmV0dXJuXCJzdHJpbmdcIj09dHlwZW9mIHR9ZnVuY3Rpb24gdyh0KXtyZXR1cm5cInN5bWJvbFwiPT10eXBlb2YgdH1mdW5jdGlvbiBUKHQpe3JldHVybiB2b2lkIDA9PT10fWZ1bmN0aW9uIFModCl7cmV0dXJuIGIodCkmJlwiW29iamVjdCBSZWdFeHBdXCI9PT1DKHQpfWZ1bmN0aW9uIGIodCl7cmV0dXJuXCJvYmplY3RcIj09dHlwZW9mIHQmJm51bGwhPT10fWZ1bmN0aW9uIEUodCl7cmV0dXJuIGIodCkmJlwiW29iamVjdCBEYXRlXVwiPT09Qyh0KX1mdW5jdGlvbiBJKHQpe3JldHVybiBiKHQpJiYoXCJbb2JqZWN0IEVycm9yXVwiPT09Qyh0KXx8dCBpbnN0YW5jZW9mIEVycm9yKX1mdW5jdGlvbiBSKHQpe3JldHVyblwiZnVuY3Rpb25cIj09dHlwZW9mIHR9ZnVuY3Rpb24gayh0KXtyZXR1cm4gbnVsbD09PXR8fFwiYm9vbGVhblwiPT10eXBlb2YgdHx8XCJudW1iZXJcIj09dHlwZW9mIHR8fFwic3RyaW5nXCI9PXR5cGVvZiB0fHxcInN5bWJvbFwiPT10eXBlb2YgdHx8XCJ1bmRlZmluZWRcIj09dHlwZW9mIHR9ZnVuY3Rpb24gQyh0KXtyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpfWZ1bmN0aW9uIE8odCl7cmV0dXJuIHQ8MTA/XCIwXCIrdC50b1N0cmluZygxMCk6dC50b1N0cmluZygxMCl9ZnVuY3Rpb24gUCgpe3ZhciB0PW5ldyBEYXRlLGU9W08odC5nZXRIb3VycygpKSxPKHQuZ2V0TWludXRlcygpKSxPKHQuZ2V0U2Vjb25kcygpKV0uam9pbihcIjpcIik7cmV0dXJuW3QuZ2V0RGF0ZSgpLEZbdC5nZXRNb250aCgpXSxlXS5qb2luKFwiIFwiKX1mdW5jdGlvbiBBKHQsZSl7cmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh0LGUpfXZhciBOPS8lW3NkaiVdL2c7ZS5mb3JtYXQ9ZnVuY3Rpb24odCl7aWYoIW0odCkpe2Zvcih2YXIgZT1bXSxpPTA7aTxhcmd1bWVudHMubGVuZ3RoO2krKyllLnB1c2gocihhcmd1bWVudHNbaV0pKTtyZXR1cm4gZS5qb2luKFwiIFwiKX1mb3IodmFyIGk9MSxuPWFyZ3VtZW50cyxvPW4ubGVuZ3RoLHM9U3RyaW5nKHQpLnJlcGxhY2UoTixmdW5jdGlvbih0KXtpZihcIiUlXCI9PT10KXJldHVyblwiJVwiO2lmKGk+PW8pcmV0dXJuIHQ7c3dpdGNoKHQpe2Nhc2VcIiVzXCI6cmV0dXJuIFN0cmluZyhuW2krK10pO2Nhc2VcIiVkXCI6cmV0dXJuIE51bWJlcihuW2krK10pO2Nhc2VcIiVqXCI6dHJ5e3JldHVybiBKU09OLnN0cmluZ2lmeShuW2krK10pfWNhdGNoKGUpe3JldHVyblwiW0NpcmN1bGFyXVwifWRlZmF1bHQ6cmV0dXJuIHR9fSksYT1uW2ldO2k8bzthPW5bKytpXSlzKz1nKGEpfHwhYihhKT9cIiBcIithOlwiIFwiK3IoYSk7cmV0dXJuIHN9LGUueEM9ZnVuY3Rpb24odCxpKXtmdW5jdGlvbiByKCl7aWYoIW4pe2lmKHByb2Nlc3MudGhyb3dEZXByZWNhdGlvbil0aHJvdyBuZXcgRXJyb3IoaSk7cHJvY2Vzcy50cmFjZURlcHJlY2F0aW9uP2NvbnNvbGUudHJhY2UoaSk6Y29uc29sZS5lcnJvcihpKSxuPSEwfXJldHVybiB0LmFwcGx5KHRoaXMsYXJndW1lbnRzKX1pZihUKGdsb2JhbC5wcm9jZXNzKSlyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZS54Qyh0LGkpLmFwcGx5KHRoaXMsYXJndW1lbnRzKX07aWYocHJvY2Vzcy5ub0RlcHJlY2F0aW9uPT09ITApcmV0dXJuIHQ7dmFyIG49ITE7cmV0dXJuIHJ9O3ZhciB4LEI9e307ZS5CQz1mdW5jdGlvbih0KXtpZihUKHgpJiYoeD1wcm9jZXNzLk90Lk5PREVfREVCVUd8fFwiXCIpLHQ9dC50b1VwcGVyQ2FzZSgpLCFCW3RdKWlmKG5ldyBSZWdFeHAoXCJcXFxcYlwiK3QrXCJcXFxcYlwiLFwiaVwiKS50ZXN0KHgpKXt2YXIgaT1wcm9jZXNzLnBpZDtCW3RdPWZ1bmN0aW9uKCl7dmFyIHI9ZS5mb3JtYXQuYXBwbHkoZSxhcmd1bWVudHMpO2NvbnNvbGUuZXJyb3IoXCIlcyAlZDogJXNcIix0LGkscil9fWVsc2UgQlt0XT1mdW5jdGlvbigpe307cmV0dXJuIEJbdF19LGUuZ3Q9cixyLkNDPXtib2xkOlsxLDIyXSxGQzpbMywyM10sX0M6WzQsMjRdLGludmVyc2U6WzcsMjddLERDOlszNywzOV0sSEM6WzkwLDM5XSxMQzpbMzAsMzldLGJsdWU6WzM0LDM5XSxNQzpbMzYsMzldLGdyZWVuOlszMiwzOV0sakM6WzM1LDM5XSxyZWQ6WzMxLDM5XSxVQzpbMzMsMzldfSxyLk5DPXtWQzpcImN5YW5cIixudW1iZXI6XCJ5ZWxsb3dcIixRQzpcInllbGxvd1wiLHVuZGVmaW5lZDpcImdyZXlcIixxQzpcImJvbGRcIixKQzpcImdyZWVuXCIseFQ6XCJtYWdlbnRhXCIsS0M6XCJyZWRcIn0sZS5pc0FycmF5PWQsZS5PbT1mLGUuQW09ZyxlLmFrPXYsZS5ObT15LGUueG09bSxlLkdDPXcsZS5CbT1ULGUuekM9UyxlLm92PWIsZS5XQz1FLGUuJEM9SSxlLlBtPVIsZS5ZQz1rLGUuaXNCdWZmZXI9aSg2Mik7dmFyIEY9W1wiSmFuXCIsXCJGZWJcIixcIk1hclwiLFwiQXByXCIsXCJNYXlcIixcIkp1blwiLFwiSnVsXCIsXCJBdWdcIixcIlNlcFwiLFwiT2N0XCIsXCJOb3ZcIixcIkRlY1wiXTtlLmxvZz1mdW5jdGlvbigpe2NvbnNvbGUubG9nKFwiJXMgLSAlc1wiLFAoKSxlLmZvcm1hdC5hcHBseShlLGFyZ3VtZW50cykpfSxlLnFzPWkoNjEpLGUuUEM9ZnVuY3Rpb24odCxlKXtpZighZXx8IWIoZSkpcmV0dXJuIHQ7Zm9yKHZhciBpPU9iamVjdC5rZXlzKGUpLHI9aS5sZW5ndGg7ci0tOyl0W2lbcl1dPWVbaVtyXV07cmV0dXJuIHR9fSxmdW5jdGlvbih0LGUpeyhmdW5jdGlvbihlKXt0LnQ9ZX0pLmNhbGwoZSx7fSl9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjshZnVuY3Rpb24oKXt2YXIgZT1pKDMpLHI9ZS5sb2csbj1lLnJpO3QudC5yaT1uLHQudC5YZT1lLlhlLHQudC5ZZT1lLlllO3ZhciBvPWkoNjYpfHxudWxsLHM9aSg2OCl8fG51bGwsYT1pKDcwKXx8bnVsbCxjPWkoNzIpfHxudWxsO3N3aXRjaChuLnRpKXtjYXNlXCJjaHJvbWVcIjppZighb3x8IW8uWEMpcmV0dXJuIHZvaWQgcihcIkNocm9tZSBzaGltIGlzIG5vdCBpbmNsdWRlZCBpbiB0aGlzIGFkYXB0ZXIgcmVsZWFzZS5cIik7cihcImFkYXB0ZXIuanMgc2hpbW1pbmcgY2hyb21lLlwiKSx0LnQubkM9byxvLlpDKCksby50TygpLGUuZWkoKSxvLmVPKCksby5YQygpLG8uaU8oKSxvLnJPKCk7YnJlYWs7Y2FzZVwiZmlyZWZveFwiOmlmKCFhfHwhYS5YQylyZXR1cm4gdm9pZCByKFwiRmlyZWZveCBzaGltIGlzIG5vdCBpbmNsdWRlZCBpbiB0aGlzIGFkYXB0ZXIgcmVsZWFzZS5cIik7cihcImFkYXB0ZXIuanMgc2hpbW1pbmcgZmlyZWZveC5cIiksdC50Lm5DPWEsYS5aQygpLGUuZWkoKSxhLmVPKCksYS5YQygpLGEuaU8oKTticmVhaztjYXNlXCJlZGdlXCI6aWYoIXN8fCFzLlhDKXJldHVybiB2b2lkIHIoXCJNUyBlZGdlIHNoaW0gaXMgbm90IGluY2x1ZGVkIGluIHRoaXMgYWRhcHRlciByZWxlYXNlLlwiKTtyKFwiYWRhcHRlci5qcyBzaGltbWluZyBlZGdlLlwiKSx0LnQubkM9cyxzLlpDKCksZS5laSgpLHMuWEMoKTticmVhaztjYXNlXCJzYWZhcmlcIjppZighYylyZXR1cm4gdm9pZCByKFwiU2FmYXJpIHNoaW0gaXMgbm90IGluY2x1ZGVkIGluIHRoaXMgYWRhcHRlciByZWxlYXNlLlwiKTtyKFwiYWRhcHRlci5qcyBzaGltbWluZyBzYWZhcmkuXCIpLHQudC5uQz1jLGMuWkMoKTticmVhaztkZWZhdWx0OnIoXCJVbnN1cHBvcnRlZCBicm93c2VyIVwiKX19KCl9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcj1pKDMpLmxvZyxuPWkoMykucmksbz17dE86ZnVuY3Rpb24oKXt3aW5kb3cuTWVkaWFTdHJlYW09d2luZG93Lk1lZGlhU3RyZWFtfHx3aW5kb3cud2Via2l0TWVkaWFTdHJlYW19LGlPOmZ1bmN0aW9uKCl7XCJvYmplY3RcIiE9dHlwZW9mIHdpbmRvd3x8IXdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbnx8XCJvbnRyYWNrXCJpbiB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlfHxPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZSxcIm9udHJhY2tcIix7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubk99LHNldDpmdW5jdGlvbih0KXt2YXIgZT10aGlzO3RoaXMubk8mJih0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJ0cmFja1wiLHRoaXMubk8pLHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImFkZHN0cmVhbVwiLHRoaXMub08pKSx0aGlzLmFkZEV2ZW50TGlzdGVuZXIoXCJ0cmFja1wiLHRoaXMubk89dCksdGhpcy5hZGRFdmVudExpc3RlbmVyKFwiYWRkc3RyZWFtXCIsdGhpcy5vTz1mdW5jdGlvbih0KXt0LnN0cmVhbS5hZGRFdmVudExpc3RlbmVyKFwiYWRkdHJhY2tcIixmdW5jdGlvbihpKXt2YXIgcj1uZXcgRXZlbnQoXCJ0cmFja1wiKTtyLnRyYWNrPWkudHJhY2ssci5yZWNlaXZlcj17dHJhY2s6aS50cmFja30sci5zTz1bdC5zdHJlYW1dLGUuZGlzcGF0Y2hFdmVudChyKX0pLHQuc3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goZnVuY3Rpb24oZSl7dmFyIGk9bmV3IEV2ZW50KFwidHJhY2tcIik7aS50cmFjaz1lLGkucmVjZWl2ZXI9e3RyYWNrOmV9LGkuc089W3Quc3RyZWFtXSx0aGlzLmRpc3BhdGNoRXZlbnQoaSl9LmJpbmQodGhpcykpfS5iaW5kKHRoaXMpKX19KX0sck86ZnVuY3Rpb24oKXtpZihcIm9iamVjdFwiPT10eXBlb2Ygd2luZG93JiZ3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24mJiEoXCJnZXRTZW5kZXJzXCJpbiBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUpJiZcImNyZWF0ZURUTUZTZW5kZXJcImluIFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZSl7UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldFNlbmRlcnM9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hT307dmFyIHQ9UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmFkZFN0cmVhbSxlPVJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5yZW1vdmVTdHJlYW07UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmFkZFN0cmVhbT1mdW5jdGlvbihlKXt2YXIgaT10aGlzO2kuYU89aS5hT3x8W10sdC5hcHBseShpLFtlXSksZS5nZXRUcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uKHQpe2kuYU8ucHVzaCh7dHJhY2s6dCxnZXQgY08oKXtyZXR1cm4gdm9pZCAwPT09dGhpcy5oTyYmKFwiYXVkaW9cIj09PXQua2luZD90aGlzLmhPPWkuY3JlYXRlRFRNRlNlbmRlcih0KTp0aGlzLmhPPW51bGwpLHRoaXMuaE99fSl9KX0sUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLnJlbW92ZVN0cmVhbT1mdW5jdGlvbih0KXt2YXIgaT10aGlzO2kuYU89aS5hT3x8W10sZS5hcHBseShpLFt0XSksdC5nZXRUcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uKHQpe3ZhciBlPWkuYU8uZmluZChmdW5jdGlvbihlKXtyZXR1cm4gZS50cmFjaz09PXR9KTtlJiZpLmFPLnNwbGljZShpLmFPLmluZGV4T2YoZSksMSl9KX19fSxlTzpmdW5jdGlvbigpe1wib2JqZWN0XCI9PXR5cGVvZiB3aW5kb3cmJighd2luZG93LkhUTUxNZWRpYUVsZW1lbnR8fFwic3JjT2JqZWN0XCJpbiB3aW5kb3cuSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGV8fE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUsXCJzcmNPYmplY3RcIix7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucE99LHNldDpmdW5jdGlvbih0KXt2YXIgZT10aGlzO3JldHVybiB0aGlzLnBPPXQsdGhpcy5zcmMmJlVSTC5yZXZva2VPYmplY3RVUkwodGhpcy5zcmMpLHQ/KHRoaXMuc3JjPVVSTC5jcmVhdGVPYmplY3RVUkwodCksdC5hZGRFdmVudExpc3RlbmVyKFwiYWRkdHJhY2tcIixmdW5jdGlvbigpe2Uuc3JjJiZVUkwucmV2b2tlT2JqZWN0VVJMKGUuc3JjKSxlLnNyYz1VUkwuY3JlYXRlT2JqZWN0VVJMKHQpfSksdm9pZCB0LmFkZEV2ZW50TGlzdGVuZXIoXCJyZW1vdmV0cmFja1wiLGZ1bmN0aW9uKCl7ZS5zcmMmJlVSTC5yZXZva2VPYmplY3RVUkwoZS5zcmMpLGUuc3JjPVVSTC5jcmVhdGVPYmplY3RVUkwodCl9KSk6dm9pZCh0aGlzLnNyYz1cIlwiKX19KSl9LFhDOmZ1bmN0aW9uKCl7d2luZG93LlJUQ1BlZXJDb25uZWN0aW9ufHwod2luZG93LlJUQ1BlZXJDb25uZWN0aW9uPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHIoXCJQZWVyQ29ubmVjdGlvblwiKSx0JiZ0LnVPJiYodC5sTz10LnVPKSxuZXcgd2Via2l0UlRDUGVlckNvbm5lY3Rpb24odCxlKX0sd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZT13ZWJraXRSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUsd2Via2l0UlRDUGVlckNvbm5lY3Rpb24uZ2VuZXJhdGVDZXJ0aWZpY2F0ZSYmT2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbixcImdlbmVyYXRlQ2VydGlmaWNhdGVcIix7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHdlYmtpdFJUQ1BlZXJDb25uZWN0aW9uLmdlbmVyYXRlQ2VydGlmaWNhdGV9fSkpO3ZhciB0PVJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5nZXRTdGF0cztSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0U3RhdHM9ZnVuY3Rpb24oZSxpLHIpe3ZhciBuPXRoaXMsbz1hcmd1bWVudHM7aWYoYXJndW1lbnRzLmxlbmd0aD4wJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBlKXJldHVybiB0LmFwcGx5KHRoaXMsYXJndW1lbnRzKTtpZigwPT09dC5sZW5ndGgmJigwPT09YXJndW1lbnRzLmxlbmd0aHx8XCJmdW5jdGlvblwiIT10eXBlb2YgYXJndW1lbnRzWzBdKSlyZXR1cm4gdC5hcHBseSh0aGlzLFtdKTt2YXIgcz1mdW5jdGlvbih0KXt2YXIgZT17fSxpPXQucmVzdWx0KCk7cmV0dXJuIGkuZm9yRWFjaChmdW5jdGlvbih0KXt2YXIgaT17aWQ6dC5pZCx0aW1lc3RhbXA6dC50aW1lc3RhbXAsdHlwZTp7ZE86XCJsb2NhbC1jYW5kaWRhdGVcIixmTzpcInJlbW90ZS1jYW5kaWRhdGVcIn1bdC50eXBlXXx8dC50eXBlfTt0Lm5hbWVzKCkuZm9yRWFjaChmdW5jdGlvbihlKXtpW2VdPXQuc3RhdChlKX0pLGVbaS5pZF09aX0pLGV9LGE9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBNYXAoT2JqZWN0LmtleXModCkubWFwKGZ1bmN0aW9uKGUpe3JldHVybltlLHRbZV1dfSkpfTtpZihhcmd1bWVudHMubGVuZ3RoPj0yKXt2YXIgYz1mdW5jdGlvbih0KXtvWzFdKGEocyh0KSkpfTtyZXR1cm4gdC5hcHBseSh0aGlzLFtjLGFyZ3VtZW50c1swXV0pfXJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihlLGkpe3QuYXBwbHkobixbZnVuY3Rpb24odCl7ZShhKHModCkpKX0saV0pfSkudGhlbihpLHIpfSxuLnZlcnNpb248NTEmJltcInNldExvY2FsRGVzY3JpcHRpb25cIixcInNldFJlbW90ZURlc2NyaXB0aW9uXCIsXCJhZGRJY2VDYW5kaWRhdGVcIl0uZm9yRWFjaChmdW5jdGlvbih0KXt2YXIgZT1SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGVbdF07UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW3RdPWZ1bmN0aW9uKCl7dmFyIHQ9YXJndW1lbnRzLGk9dGhpcyxyPW5ldyBQcm9taXNlKGZ1bmN0aW9uKHIsbil7ZS5hcHBseShpLFt0WzBdLHIsbl0pfSk7cmV0dXJuIHQubGVuZ3RoPDI/cjpyLnRoZW4oZnVuY3Rpb24oKXt0WzFdLmFwcGx5KG51bGwsW10pfSxmdW5jdGlvbihlKXt0Lmxlbmd0aD49MyYmdFsyXS5hcHBseShudWxsLFtlXSl9KX19KSxuLnZlcnNpb248NTImJltcImNyZWF0ZU9mZmVyXCIsXCJjcmVhdGVBbnN3ZXJcIl0uZm9yRWFjaChmdW5jdGlvbih0KXt2YXIgZT1SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGVbdF07UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW3RdPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcztpZihhcmd1bWVudHMubGVuZ3RoPDF8fDE9PT1hcmd1bWVudHMubGVuZ3RoJiZcIm9iamVjdFwiPT10eXBlb2YgYXJndW1lbnRzWzBdKXt2YXIgaT0xPT09YXJndW1lbnRzLmxlbmd0aD9hcmd1bWVudHNbMF06dm9pZCAwO3JldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyLG4pe2UuYXBwbHkodCxbcixuLGldKX0pfXJldHVybiBlLmFwcGx5KHRoaXMsYXJndW1lbnRzKX19KSxbXCJzZXRMb2NhbERlc2NyaXB0aW9uXCIsXCJzZXRSZW1vdGVEZXNjcmlwdGlvblwiLFwiYWRkSWNlQ2FuZGlkYXRlXCJdLmZvckVhY2goZnVuY3Rpb24odCl7dmFyIGU9UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW3RdO1JUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZVt0XT1mdW5jdGlvbigpe3JldHVybiBhcmd1bWVudHNbMF09bmV3KFwiYWRkSWNlQ2FuZGlkYXRlXCI9PT10P1JUQ0ljZUNhbmRpZGF0ZTpSVENTZXNzaW9uRGVzY3JpcHRpb24pKGFyZ3VtZW50c1swXSksZS5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fSk7dmFyIGU9UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmFkZEljZUNhbmRpZGF0ZTtSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuYWRkSWNlQ2FuZGlkYXRlPWZ1bmN0aW9uKCl7cmV0dXJuIGFyZ3VtZW50c1swXT9lLmFwcGx5KHRoaXMsYXJndW1lbnRzKTooYXJndW1lbnRzWzFdJiZhcmd1bWVudHNbMV0uYXBwbHkobnVsbCksUHJvbWlzZS5yZXNvbHZlKCkpfX19O3QudD17dE86by50TyxpTzpvLmlPLHJPOm8uck8sZU86by5lTyxYQzpvLlhDLFpDOmkoNjcpfX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPWkoMykubG9nLG49aSgzKS5yaTt0LnQ9ZnVuY3Rpb24oKXt2YXIgdD1mdW5jdGlvbih0KXtpZihcIm9iamVjdFwiIT10eXBlb2YgdHx8dC5nT3x8dC5vcHRpb25hbClyZXR1cm4gdDt2YXIgZT17fTtyZXR1cm4gT2JqZWN0LmtleXModCkuZm9yRWFjaChmdW5jdGlvbihpKXtpZihcInJlcXVpcmVcIiE9PWkmJlwiYWR2YW5jZWRcIiE9PWkmJlwibWVkaWFTb3VyY2VcIiE9PWkpe3ZhciByPVwib2JqZWN0XCI9PXR5cGVvZiB0W2ldP3RbaV06e3ZPOnRbaV19O3ZvaWQgMCE9PXIueU8mJlwibnVtYmVyXCI9PXR5cGVvZiByLnlPJiYoci5taW49ci5tYXg9ci55Tyk7dmFyIG49ZnVuY3Rpb24odCxlKXtyZXR1cm4gdD90K2UuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkrZS5zbGljZSgxKTpcImRldmljZUlkXCI9PT1lP1wic291cmNlSWRcIjplfTtpZih2b2lkIDAhPT1yLnZPKXtlLm9wdGlvbmFsPWUub3B0aW9uYWx8fFtdO3ZhciBvPXt9O1wibnVtYmVyXCI9PXR5cGVvZiByLnZPPyhvW24oXCJtaW5cIixpKV09ci52TyxlLm9wdGlvbmFsLnB1c2gobyksbz17fSxvW24oXCJtYXhcIixpKV09ci52TyxlLm9wdGlvbmFsLnB1c2gobykpOihvW24oXCJcIixpKV09ci52TyxlLm9wdGlvbmFsLnB1c2gobykpfXZvaWQgMCE9PXIueU8mJlwibnVtYmVyXCIhPXR5cGVvZiByLnlPPyhlLmdPPWUuZ098fHt9LGUuZ09bbihcIlwiLGkpXT1yLnlPKTpbXCJtaW5cIixcIm1heFwiXS5mb3JFYWNoKGZ1bmN0aW9uKHQpe3ZvaWQgMCE9PXJbdF0mJihlLmdPPWUuZ098fHt9LGUuZ09bbih0LGkpXT1yW3RdKX0pfX0pLHQubU8mJihlLm9wdGlvbmFsPShlLm9wdGlvbmFsfHxbXSkuY29uY2F0KHQubU8pKSxlfSxlPWZ1bmN0aW9uKGUsaSl7aWYoZT1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGUpKSxlJiZlLk1wJiYoZS5NcD10KGUuTXApKSxlJiZcIm9iamVjdFwiPT10eXBlb2YgZS52aWRlbyl7dmFyIG89ZS52aWRlby53TztvPW8mJihcIm9iamVjdFwiPT10eXBlb2Ygbz9vOnt2TzpvfSk7dmFyIHM9bi52ZXJzaW9uPDU5O2lmKG8mJihcInVzZXJcIj09PW8ueU98fFwiZW52aXJvbm1lbnRcIj09PW8ueU98fFwidXNlclwiPT09by52T3x8XCJlbnZpcm9ubWVudFwiPT09by52TykmJighbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5UT3x8IW5hdmlnYXRvci5tZWRpYURldmljZXMuVE8oKS53T3x8cykmJihkZWxldGUgZS52aWRlby53TyxcImVudmlyb25tZW50XCI9PT1vLnlPfHxcImVudmlyb25tZW50XCI9PT1vLnZPKSlyZXR1cm4gbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5TTygpLnRoZW4oZnVuY3Rpb24obil7bj1uLmZpbHRlcihmdW5jdGlvbih0KXtyZXR1cm5cInZpZGVvaW5wdXRcIj09PXQua2luZH0pO3ZhciBzPW4uZmluZChmdW5jdGlvbih0KXtyZXR1cm4gdC5sYWJlbC50b0xvd2VyQ2FzZSgpLmluZGV4T2YoXCJiYWNrXCIpIT09LTF9KXx8bi5sZW5ndGgmJm5bbi5sZW5ndGgtMV07cmV0dXJuIHMmJihlLnZpZGVvLmJPPW8ueU8/e3lPOnMuYk99Ont2TzpzLmJPfSksZS52aWRlbz10KGUudmlkZW8pLHIoXCJjaHJvbWU6IFwiK0pTT04uc3RyaW5naWZ5KGUpKSxpKGUpfSk7ZS52aWRlbz10KGUudmlkZW8pfXJldHVybiByKFwiY2hyb21lOiBcIitKU09OLnN0cmluZ2lmeShlKSksaShlKX0saT1mdW5jdGlvbih0KXtyZXR1cm57bmFtZTp7RU86XCJOb3RBbGxvd2VkRXJyb3JcIixJTzpcIk92ZXJjb25zdHJhaW5lZEVycm9yXCJ9W3QubmFtZV18fHQubmFtZSxtZXNzYWdlOnQubWVzc2FnZSxSTzp0LmNvbnN0cmFpbnROYW1lLHRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubmFtZSsodGhpcy5tZXNzYWdlJiZcIjogXCIpK3RoaXMubWVzc2FnZX19fSxvPWZ1bmN0aW9uKHQscixuKXtlKHQsZnVuY3Rpb24odCl7bmF2aWdhdG9yLndlYmtpdEdldFVzZXJNZWRpYSh0LHIsZnVuY3Rpb24odCl7bihpKHQpKX0pfSl9O25hdmlnYXRvci5nZXRVc2VyTWVkaWE9bzt2YXIgcz1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24oZSxpKXtuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhKHQsZSxpKX0pfTtpZihuYXZpZ2F0b3IubWVkaWFEZXZpY2VzfHwobmF2aWdhdG9yLm1lZGlhRGV2aWNlcz17Z2V0VXNlck1lZGlhOnMsU086ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24odCl7dmFyIGU9e01wOlwiYXVkaW9pbnB1dFwiLHZpZGVvOlwidmlkZW9pbnB1dFwifTtyZXR1cm4gTWVkaWFTdHJlYW1UcmFjay5nZXRTb3VyY2VzKGZ1bmN0aW9uKGkpe3QoaS5tYXAoZnVuY3Rpb24odCl7cmV0dXJue2xhYmVsOnQubGFiZWwsa2luZDplW3Qua2luZF0sYk86dC5pZCxrTzpcIlwifX0pKX0pfSl9LFRPOmZ1bmN0aW9uKCl7cmV0dXJue2JPOiEwLENPOiEwLHdPOiEwLE9POiEwLGhlaWdodDohMCx3aWR0aDohMH19fSksbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEpe3ZhciBhPW5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhLmJpbmQobmF2aWdhdG9yLm1lZGlhRGV2aWNlcyk7bmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWE9ZnVuY3Rpb24odCl7cmV0dXJuIGUodCxmdW5jdGlvbih0KXtyZXR1cm4gYSh0KS50aGVuKGZ1bmN0aW9uKGUpe2lmKHQuTXAmJiFlLmdldEF1ZGlvVHJhY2tzKCkubGVuZ3RofHx0LnZpZGVvJiYhZS5nZXRWaWRlb1RyYWNrcygpLmxlbmd0aCl0aHJvdyBlLmdldFRyYWNrcygpLmZvckVhY2goZnVuY3Rpb24odCl7dC5zdG9wKCl9KSxuZXcgRE9NRXhjZXB0aW9uKFwiXCIsXCJOb3RGb3VuZEVycm9yXCIpO3JldHVybiBlfSxmdW5jdGlvbih0KXtyZXR1cm4gUHJvbWlzZS5yZWplY3QoaSh0KSl9KX0pfX1lbHNlIG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhPWZ1bmN0aW9uKHQpe3JldHVybiBzKHQpfTtcInVuZGVmaW5lZFwiPT10eXBlb2YgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5hZGRFdmVudExpc3RlbmVyJiYobmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5hZGRFdmVudExpc3RlbmVyPWZ1bmN0aW9uKCl7cihcIkR1bW15IG1lZGlhRGV2aWNlcy5hZGRFdmVudExpc3RlbmVyIGNhbGxlZC5cIil9KSxcInVuZGVmaW5lZFwiPT10eXBlb2YgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5yZW1vdmVFdmVudExpc3RlbmVyJiYobmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5yZW1vdmVFdmVudExpc3RlbmVyPWZ1bmN0aW9uKCl7cihcIkR1bW15IG1lZGlhRGV2aWNlcy5yZW1vdmVFdmVudExpc3RlbmVyIGNhbGxlZC5cIil9KX19LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjtmdW5jdGlvbiByKHQpe3ZhciBlPXQuZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVyblwiYXVkaW9cIj09PXQua2luZH0pLGk9dC5maWx0ZXIoZnVuY3Rpb24odCl7cmV0dXJuXCJ2aWRlb1wiPT09dC5raW5kfSk7Zm9yKHQ9W107ZS5sZW5ndGh8fGkubGVuZ3RoOyllLmxlbmd0aCYmdC5wdXNoKGUuc2hpZnQoKSksXG5pLmxlbmd0aCYmdC5wdXNoKGkuc2hpZnQoKSk7cmV0dXJuIHR9ZnVuY3Rpb24gbih0KXt2YXIgZT0hMTtyZXR1cm4gdD1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHQpKSx0LmZpbHRlcihmdW5jdGlvbih0KXtpZih0JiYodC5QT3x8dC51cmwpKXt2YXIgaT10LlBPfHx0LnVybCxyPVwic3RyaW5nXCI9PXR5cGVvZiBpO3JldHVybiByJiYoaT1baV0pLGk9aS5maWx0ZXIoZnVuY3Rpb24odCl7dmFyIGk9MD09PXQuaW5kZXhPZihcInR1cm46XCIpJiZ0LmluZGV4T2YoXCJ0cmFuc3BvcnQ9dWRwXCIpIT09LTEmJnQuaW5kZXhPZihcInR1cm46W1wiKT09PS0xJiYhZTtyZXR1cm4gaT8oZT0hMCwhMCk6MD09PXQuaW5kZXhPZihcInN0dW46XCIpJiZzLnZlcnNpb24+PTE0MzkzfSksZGVsZXRlIHQudXJsLHQuUE89cj9pWzBdOmksISFpLmxlbmd0aH1yZXR1cm4hMX0pfXZhciBvPWkoMzUpLHM9aSgzKS5yaSxhPXtYQzpmdW5jdGlvbigpe2lmKHdpbmRvdy5SVENJY2VHYXRoZXJlciYmKHdpbmRvdy5SVENJY2VDYW5kaWRhdGV8fCh3aW5kb3cuUlRDSWNlQ2FuZGlkYXRlPWZ1bmN0aW9uKHQpe3JldHVybiB0fSksd2luZG93LlJUQ1Nlc3Npb25EZXNjcmlwdGlvbnx8KHdpbmRvdy5SVENTZXNzaW9uRGVzY3JpcHRpb249ZnVuY3Rpb24odCl7cmV0dXJuIHR9KSxzLnZlcnNpb248MTUwMjUpKXt2YXIgdD1PYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKE1lZGlhU3RyZWFtVHJhY2sucHJvdG90eXBlLFwiZW5hYmxlZFwiKTtPYmplY3QuZGVmaW5lUHJvcGVydHkoTWVkaWFTdHJlYW1UcmFjay5wcm90b3R5cGUsXCJlbmFibGVkXCIse3NldDpmdW5jdGlvbihlKXt0LnNldC5jYWxsKHRoaXMsZSk7dmFyIGk9bmV3IEV2ZW50KFwiZW5hYmxlZFwiKTtpLmVuYWJsZWQ9ZSx0aGlzLmRpc3BhdGNoRXZlbnQoaSl9fSl9d2luZG93LlJUQ1BlZXJDb25uZWN0aW9uPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMsaT1kb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7aWYoW1wiYWRkRXZlbnRMaXN0ZW5lclwiLFwicmVtb3ZlRXZlbnRMaXN0ZW5lclwiLFwiZGlzcGF0Y2hFdmVudFwiXS5mb3JFYWNoKGZ1bmN0aW9uKHQpe2VbdF09aVt0XS5iaW5kKGkpfSksdGhpcy5vbmljZWNhbmRpZGF0ZT1udWxsLHRoaXMub25hZGRzdHJlYW09bnVsbCx0aGlzLkFPPW51bGwsdGhpcy5vbnJlbW92ZXN0cmVhbT1udWxsLHRoaXMub25zaWduYWxpbmdzdGF0ZWNoYW5nZT1udWxsLHRoaXMub25pY2Vjb25uZWN0aW9uc3RhdGVjaGFuZ2U9bnVsbCx0aGlzLk5PPW51bGwsdGhpcy5vbm5lZ290aWF0aW9ubmVlZGVkPW51bGwsdGhpcy5vbmRhdGFjaGFubmVsPW51bGwsdGhpcy54Tz1bXSx0aGlzLkJPPVtdLHRoaXMuZ2V0TG9jYWxTdHJlYW1zPWZ1bmN0aW9uKCl7cmV0dXJuIGUueE99LHRoaXMuZ2V0UmVtb3RlU3RyZWFtcz1mdW5jdGlvbigpe3JldHVybiBlLkJPfSx0aGlzLmxvY2FsRGVzY3JpcHRpb249bmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbih7dHlwZTpcIlwiLHNkcDpcIlwifSksdGhpcy5yZW1vdGVEZXNjcmlwdGlvbj1uZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKHt0eXBlOlwiXCIsc2RwOlwiXCJ9KSx0aGlzLnNpZ25hbGluZ1N0YXRlPVwic3RhYmxlXCIsdGhpcy5pY2VDb25uZWN0aW9uU3RhdGU9XCJuZXdcIix0aGlzLmljZUdhdGhlcmluZ1N0YXRlPVwibmV3XCIsdGhpcy5GTz17X086XCJhbGxcIixpY2VTZXJ2ZXJzOltdfSx0JiZ0LnVPKXN3aXRjaCh0LnVPKXtjYXNlXCJhbGxcIjpjYXNlXCJyZWxheVwiOnRoaXMuRk8uX089dC51T310aGlzLkRPPXQmJlwibWF4LWJ1bmRsZVwiPT09dC5idW5kbGVQb2xpY3ksdCYmdC5pY2VTZXJ2ZXJzJiYodGhpcy5GTy5pY2VTZXJ2ZXJzPW4odC5pY2VTZXJ2ZXJzKSksdGhpcy5ITz10LHRoaXMuTE89W10sdGhpcy5NTz1bXX0sd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5qTz1mdW5jdGlvbigpe3ZhciB0PW5ldyBFdmVudChcImljZWdhdGhlcmluZ3N0YXRlY2hhbmdlXCIpO3RoaXMuZGlzcGF0Y2hFdmVudCh0KSxudWxsIT09dGhpcy5OTyYmdGhpcy5OTyh0KX0sd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5VTz1mdW5jdGlvbigpe3ZhciB0PXRoaXMsZT1vLktiKHQubG9jYWxEZXNjcmlwdGlvbi5zZHApO3RoaXMuTU8uZm9yRWFjaChmdW5jdGlvbihpKXt2YXIgcj0haS5jYW5kaWRhdGV8fDA9PT1PYmplY3Qua2V5cyhpLmNhbmRpZGF0ZSkubGVuZ3RoO2lmKHIpZm9yKHZhciBuPTE7bjxlLmxlbmd0aDtuKyspZVtuXS5pbmRleE9mKFwiXFxyXFxuYT1lbmQtb2YtY2FuZGlkYXRlc1xcclxcblwiKT09PS0xJiYoZVtuXSs9XCJhPWVuZC1vZi1jYW5kaWRhdGVzXFxyXFxuXCIpO2Vsc2UgZVtpLmNhbmRpZGF0ZS5zZHBNTGluZUluZGV4KzFdKz1cImE9XCIraS5jYW5kaWRhdGUuY2FuZGlkYXRlK1wiXFxyXFxuXCI7aWYodC5sb2NhbERlc2NyaXB0aW9uLnNkcD1lLmpvaW4oXCJcIiksdC5kaXNwYXRjaEV2ZW50KGkpLG51bGwhPT10Lm9uaWNlY2FuZGlkYXRlJiZ0Lm9uaWNlY2FuZGlkYXRlKGkpLCFpLmNhbmRpZGF0ZSYmXCJjb21wbGV0ZVwiIT09dC5pY2VHYXRoZXJpbmdTdGF0ZSl7dmFyIG89dC5MTy5ldmVyeShmdW5jdGlvbih0KXtyZXR1cm4gdC5ZRSYmXCJjb21wbGV0ZWRcIj09PXQuWUUuc3RhdGV9KTtvJiZcImNvbXBsZXRlXCIhPT10LmljZUdhdGhlcmluZ1N0YXRlQ2hhbmdlJiYodC5pY2VHYXRoZXJpbmdTdGF0ZT1cImNvbXBsZXRlXCIsdC5qTygpKX19KSx0aGlzLk1PPVtdfSx3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldENvbmZpZ3VyYXRpb249ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5IT30sd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5hZGRTdHJlYW09ZnVuY3Rpb24odCl7aWYocy52ZXJzaW9uPj0xNTAyNSl0aGlzLnhPLnB1c2godCk7ZWxzZXt2YXIgZT10LmNsb25lKCk7dC5nZXRUcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uKHQsaSl7dmFyIHI9ZS5nZXRUcmFja3MoKVtpXTt0LmFkZEV2ZW50TGlzdGVuZXIoXCJlbmFibGVkXCIsZnVuY3Rpb24odCl7ci5lbmFibGVkPXQuZW5hYmxlZH0pfSksdGhpcy54Ty5wdXNoKGUpfXRoaXMuVk8oKX0sd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5yZW1vdmVTdHJlYW09ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy54Ty5pbmRleE9mKHQpO2U+LTEmJih0aGlzLnhPLnNwbGljZShlLDEpLHRoaXMuVk8oKSl9LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0U2VuZGVycz1mdW5jdGlvbigpe3JldHVybiB0aGlzLkxPLmZpbHRlcihmdW5jdGlvbih0KXtyZXR1cm4hIXQudEl9KS5tYXAoZnVuY3Rpb24odCl7cmV0dXJuIHQudEl9KX0sd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5nZXRSZWNlaXZlcnM9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5MTy5maWx0ZXIoZnVuY3Rpb24odCl7cmV0dXJuISF0LmVJfSkubWFwKGZ1bmN0aW9uKHQpe3JldHVybiB0LmVJfSl9LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuUU89ZnVuY3Rpb24odCxlKXt2YXIgaT17TkU6W10seEU6W10sQkU6W119LHI9ZnVuY3Rpb24odCxlKXt0PXBhcnNlSW50KHQsMTApO2Zvcih2YXIgaT0wO2k8ZS5sZW5ndGg7aSsrKWlmKGVbaV0ub0U9PT10fHxlW2ldLmhFPT09dClyZXR1cm4gZVtpXX0sbj1mdW5jdGlvbih0LGUsaSxuKXt2YXIgbz1yKHQucGFyYW1ldGVycy5hcHQsaSkscz1yKGUucGFyYW1ldGVycy5hcHQsbik7cmV0dXJuIG8mJnMmJm8ubmFtZS50b0xvd2VyQ2FzZSgpPT09cy5uYW1lLnRvTG93ZXJDYXNlKCl9O3JldHVybiB0Lk5FLmZvckVhY2goZnVuY3Rpb24ocil7Zm9yKHZhciBvPTA7bzxlLk5FLmxlbmd0aDtvKyspe3ZhciBzPWUuTkVbb107aWYoci5uYW1lLnRvTG93ZXJDYXNlKCk9PT1zLm5hbWUudG9Mb3dlckNhc2UoKSYmci5zRT09PXMuc0Upe2lmKFwicnR4XCI9PT1yLm5hbWUudG9Mb3dlckNhc2UoKSYmci5wYXJhbWV0ZXJzJiZzLnBhcmFtZXRlcnMuYXB0JiYhbihyLHMsdC5ORSxlLk5FKSljb250aW51ZTtzPUpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkocykpLHMuYUU9TWF0aC5taW4oci5hRSxzLmFFKSxpLk5FLnB1c2gocykscy55RT1zLnlFLmZpbHRlcihmdW5jdGlvbih0KXtmb3IodmFyIGU9MDtlPHIueUUubGVuZ3RoO2UrKylpZihyLnlFW2VdLnR5cGU9PT10LnR5cGUmJnIueUVbZV0uZ0U9PT10LmdFKXJldHVybiEwO3JldHVybiExfSk7YnJlYWt9fX0pLHQueEUuZm9yRWFjaChmdW5jdGlvbih0KXtmb3IodmFyIHI9MDtyPGUueEUubGVuZ3RoO3IrKyl7dmFyIG49ZS54RVtyXTtpZih0LnVyaT09PW4udXJpKXtpLnhFLnB1c2gobik7YnJlYWt9fX0pLGl9LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUucU89ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzLHI9bmV3IFJUQ0ljZUdhdGhlcmVyKGkuRk8pLG49bmV3IFJUQ0ljZVRyYW5zcG9ydChyKTtyLkpPPWZ1bmN0aW9uKHMpe3ZhciBhPW5ldyBFdmVudChcImljZWNhbmRpZGF0ZVwiKTthLmNhbmRpZGF0ZT17c2RwTWlkOnQsc2RwTUxpbmVJbmRleDplfTt2YXIgYz1zLmNhbmRpZGF0ZSxoPSFjfHwwPT09T2JqZWN0LmtleXMoYykubGVuZ3RoO2g/dm9pZCAwPT09ci5zdGF0ZSYmKHIuc3RhdGU9XCJjb21wbGV0ZWRcIik6KGMuJGI9XCJSVENQXCI9PT1uLiRiPzI6MSxhLmNhbmRpZGF0ZS5jYW5kaWRhdGU9by5pRShjKSk7dmFyIHA9by5LYihpLmxvY2FsRGVzY3JpcHRpb24uc2RwKTtoP3BbYS5jYW5kaWRhdGUuc2RwTUxpbmVJbmRleCsxXSs9XCJhPWVuZC1vZi1jYW5kaWRhdGVzXFxyXFxuXCI6cFthLmNhbmRpZGF0ZS5zZHBNTGluZUluZGV4KzFdKz1cImE9XCIrYS5jYW5kaWRhdGUuY2FuZGlkYXRlK1wiXFxyXFxuXCIsaS5sb2NhbERlc2NyaXB0aW9uLnNkcD1wLmpvaW4oXCJcIik7dmFyIHU9aS5LTz9pLktPOmkuTE8sbD11LmV2ZXJ5KGZ1bmN0aW9uKHQpe3JldHVybiB0LllFJiZcImNvbXBsZXRlZFwiPT09dC5ZRS5zdGF0ZX0pO3N3aXRjaChpLmljZUdhdGhlcmluZ1N0YXRlKXtjYXNlXCJuZXdcIjpofHxpLk1PLnB1c2goYSksaCYmbCYmaS5NTy5wdXNoKG5ldyBFdmVudChcImljZWNhbmRpZGF0ZVwiKSk7YnJlYWs7Y2FzZVwiZ2F0aGVyaW5nXCI6aS5VTygpLGh8fChpLmRpc3BhdGNoRXZlbnQoYSksbnVsbCE9PWkub25pY2VjYW5kaWRhdGUmJmkub25pY2VjYW5kaWRhdGUoYSkpLGwmJihpLmRpc3BhdGNoRXZlbnQobmV3IEV2ZW50KFwiaWNlY2FuZGlkYXRlXCIpKSxudWxsIT09aS5vbmljZWNhbmRpZGF0ZSYmaS5vbmljZWNhbmRpZGF0ZShuZXcgRXZlbnQoXCJpY2VjYW5kaWRhdGVcIikpLGkuaWNlR2F0aGVyaW5nU3RhdGU9XCJjb21wbGV0ZVwiLGkuak8oKSk7YnJlYWs7Y2FzZVwiY29tcGxldGVcIjp9fSxuLkdPPWZ1bmN0aW9uKCl7aS56TygpfTt2YXIgcz1uZXcgUlRDRHRsc1RyYW5zcG9ydChuKTtyZXR1cm4gcy5XTz1mdW5jdGlvbigpe2kuek8oKX0scy5vbmVycm9yPWZ1bmN0aW9uKCl7cy5zdGF0ZT1cImZhaWxlZFwiLGkuek8oKX0se1lFOnIsJE86bixYRTpzfX0sd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5ZTz1mdW5jdGlvbih0LGUsaSl7dmFyIHI9dGhpcy5RTyh0LlhPLHQuWk8pO2UmJnQudEkmJihyLnRQPXQuaUksci5GRT17cUU6by5xYn0sdC5lUC5sZW5ndGgmJihyLkZFLndFPXQuZVBbMF0ud0UpLHQudEkuc2VuZChyKSksaSYmdC5lSSYmKFwidmlkZW9cIj09PXQua2luZCYmdC5lUCYmcy52ZXJzaW9uPDE1MDE5JiZ0LmVQLmZvckVhY2goZnVuY3Rpb24odCl7ZGVsZXRlIHQuTUV9KSxyLnRQPXQuZVAsci5GRT17cUU6dC5xRX0sdC5pSS5sZW5ndGgmJihyLkZFLndFPXQuaUlbMF0ud0UpLHQuZUkucmVjZWl2ZShyKSl9LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuc2V0TG9jYWxEZXNjcmlwdGlvbj1mdW5jdGlvbih0KXt2YXIgZSxpLHI9dGhpcztpZihcIm9mZmVyXCI9PT10LnR5cGUpdGhpcy5LTyYmKGU9by5LYih0LnNkcCksaT1lLnNoaWZ0KCksZS5mb3JFYWNoKGZ1bmN0aW9uKHQsZSl7dmFyIGk9by5BRSh0KTtyLktPW2VdLlhPPWl9KSx0aGlzLkxPPXRoaXMuS08sZGVsZXRlIHRoaXMuS08pO2Vsc2UgaWYoXCJhbnN3ZXJcIj09PXQudHlwZSl7ZT1vLktiKHIucmVtb3RlRGVzY3JpcHRpb24uc2RwKSxpPWUuc2hpZnQoKTt2YXIgbj1vLkdiKGksXCJhPWljZS1saXRlXCIpLmxlbmd0aD4wO2UuZm9yRWFjaChmdW5jdGlvbih0LGUpe3ZhciBzPXIuTE9bZV0sYT1zLllFLGM9cy4kTyxoPXMuWEUscD1zLlhPLHU9cy5aTyxsPVwiMFwiPT09dC5zcGxpdChcIlxcblwiLDEpWzBdLnNwbGl0KFwiIFwiLDIpWzFdO2lmKCFsJiYhcy5pUCl7dmFyIGQ9by5DRSh0LGkpLGY9by5FRSh0LGkpO24mJihmLklFPVwic2VydmVyXCIpLHIuRE8mJjAhPT1lfHwoYy5zdGFydChhLGQsbj9cImNvbnRyb2xsaW5nXCI6XCJjb250cm9sbGVkXCIpLGguc3RhcnQoZikpO3ZhciBnPXIuUU8ocCx1KTtyLllPKHMsZy5ORS5sZW5ndGg+MCwhMSl9fSl9c3dpdGNoKHRoaXMubG9jYWxEZXNjcmlwdGlvbj17dHlwZTp0LnR5cGUsc2RwOnQuc2RwfSx0LnR5cGUpe2Nhc2VcIm9mZmVyXCI6dGhpcy5yUChcImhhdmUtbG9jYWwtb2ZmZXJcIik7YnJlYWs7Y2FzZVwiYW5zd2VyXCI6dGhpcy5yUChcInN0YWJsZVwiKTticmVhaztkZWZhdWx0OnRocm93IG5ldyBUeXBlRXJyb3IoJ3Vuc3VwcG9ydGVkIHR5cGUgXCInK3QudHlwZSsnXCInKX12YXIgcz1hcmd1bWVudHMubGVuZ3RoPjEmJlwiZnVuY3Rpb25cIj09dHlwZW9mIGFyZ3VtZW50c1sxXTtpZihzKXt2YXIgYT1hcmd1bWVudHNbMV07d2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKXthKCksXCJuZXdcIj09PXIuaWNlR2F0aGVyaW5nU3RhdGUmJihyLmljZUdhdGhlcmluZ1N0YXRlPVwiZ2F0aGVyaW5nXCIsci5qTygpKSxyLlVPKCl9LDApfXZhciBjPVByb21pc2UucmVzb2x2ZSgpO3JldHVybiBjLnRoZW4oZnVuY3Rpb24oKXtzfHwoXCJuZXdcIj09PXIuaWNlR2F0aGVyaW5nU3RhdGUmJihyLmljZUdhdGhlcmluZ1N0YXRlPVwiZ2F0aGVyaW5nXCIsci5qTygpKSx3aW5kb3cuc2V0VGltZW91dChyLlVPLmJpbmQociksNTAwKSl9KSxjfSx3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLnNldFJlbW90ZURlc2NyaXB0aW9uPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMsaT1uZXcgTWVkaWFTdHJlYW0scj1bXSxuPW8uS2IodC5zZHApLGE9bi5zaGlmdCgpLGM9by5HYihhLFwiYT1pY2UtbGl0ZVwiKS5sZW5ndGg+MDtzd2l0Y2godGhpcy5ETz1vLkdiKGEsXCJhPWdyb3VwOkJVTkRMRSBcIikubGVuZ3RoPjAsbi5mb3JFYWNoKGZ1bmN0aW9uKG4saCl7dmFyIHA9by5KYihuKSx1PXBbMF0uc3Vic3RyKDIpLnNwbGl0KFwiIFwiKSxsPXVbMF0sZD1cIjBcIj09PXVbMV0sZj1vLnJJKG4sYSksZz1vLkdiKG4sXCJhPW1pZDpcIik7aWYoZz1nLmxlbmd0aD9nWzBdLnN1YnN0cig2KTpvLlFiKCksXCJhcHBsaWNhdGlvblwiPT09bCYmXCJEVExTL1NDVFBcIj09PXVbMl0pcmV0dXJuIHZvaWQoZS5MT1toXT17WkU6ZyxpUDohMH0pO3ZhciB2LHksbSx3LFQsUyxiLEUsSSxSLGssQyxPPW8uQUUobik7ZHx8KGs9by5DRShuLGEpLEM9by5FRShuLGEpLEMuSUU9XCJjbGllbnRcIiksRT1vLkhFKG4pO3ZhciBQLEE9by5HYihuLFwiYT1zc3JjOlwiKS5tYXAoZnVuY3Rpb24odCl7cmV0dXJuIG8ubUUodCl9KS5maWx0ZXIoZnVuY3Rpb24odCl7cmV0dXJuXCJjbmFtZVwiPT09dC5URX0pWzBdO0EmJihQPUEudmFsdWUpO3ZhciBOPW8uR2IobixcImE9ZW5kLW9mLWNhbmRpZGF0ZXNcIixhKS5sZW5ndGg+MCx4PW8uR2IobixcImE9Y2FuZGlkYXRlOlwiKS5tYXAoZnVuY3Rpb24odCl7cmV0dXJuIG8uemIodCl9KS5maWx0ZXIoZnVuY3Rpb24odCl7cmV0dXJuXCIxXCI9PT10LiRifSk7aWYoXCJvZmZlclwiIT09dC50eXBlfHxkKVwiYW5zd2VyXCIhPT10LnR5cGV8fGR8fCh2PWUuTE9baF0seT12LllFLG09di4kTyx3PXYuWEUsVD12LnRJLFM9di5lSSxiPXYuaUksST12LlhPLGUuTE9baF0uZVA9RSxlLkxPW2hdLlpPPU8sZS5MT1toXS5xRT1QLChjfHxOKSYmeC5sZW5ndGgmJm0uc2V0UmVtb3RlQ2FuZGlkYXRlcyh4KSxlLkRPJiYwIT09aHx8KG0uc3RhcnQoeSxrLFwiY29udHJvbGxpbmdcIiksdy5zdGFydChDKSksZS5ZTyh2LFwic2VuZHJlY3ZcIj09PWZ8fFwicmVjdm9ubHlcIj09PWYsXCJzZW5kcmVjdlwiPT09Znx8XCJzZW5kb25seVwiPT09ZiksIVN8fFwic2VuZHJlY3ZcIiE9PWYmJlwic2VuZG9ubHlcIiE9PWY/ZGVsZXRlIHYuZUk6KFI9Uy50cmFjayxyLnB1c2goW1IsU10pLGkuYWRkVHJhY2soUikpKTtlbHNle3ZhciBCPWUuRE8mJmg+MD97WUU6ZS5MT1swXS5ZRSwkTzplLkxPWzBdLiRPLFhFOmUuTE9bMF0uWEV9OmUucU8oZyxoKTtpZighTnx8ZS5ETyYmMCE9PWh8fEIuJE8uc2V0UmVtb3RlQ2FuZGlkYXRlcyh4KSxJPVJUQ1J0cFJlY2VpdmVyLmdldENhcGFiaWxpdGllcyhsKSxzLnZlcnNpb248MTUwMTkmJihJLk5FPUkuTkUuZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVyblwicnR4XCIhPT10Lm5hbWV9KSksYj1be3dFOjEwMDEqKDIqaCsyKX1dLFwic2VuZHJlY3ZcIiE9PWYmJlwic2VuZG9ubHlcIiE9PWZ8fChTPW5ldyBSVENSdHBSZWNlaXZlcihCLlhFLGwpLFI9Uy50cmFjayxyLnB1c2goW1IsU10pLGkuYWRkVHJhY2soUikpLGUueE8ubGVuZ3RoPjAmJmUueE9bMF0uZ2V0VHJhY2tzKCkubGVuZ3RoPj1oKXt2YXIgRjtcImF1ZGlvXCI9PT1sP0Y9ZS54T1swXS5nZXRBdWRpb1RyYWNrcygpWzBdOlwidmlkZW9cIj09PWwmJihGPWUueE9bMF0uZ2V0VmlkZW9UcmFja3MoKVswXSksRiYmKHMudmVyc2lvbj49MTUwMTkmJlwidmlkZW9cIj09PWwmJihiWzBdLk1FPXt3RToxMDAxKigyKmgrMikrMX0pLFQ9bmV3IFJUQ1J0cFNlbmRlcihGLEIuWEUpKX1lLkxPW2hdPXtZRTpCLllFLCRPOkIuJE8sWEU6Qi5YRSxYTzpJLFpPOk8sdEk6VCxlSTpTLGtpbmQ6bCxaRTpnLHFFOlAsaUk6YixlUDpFfSxlLllPKGUuTE9baF0sITEsXCJzZW5kcmVjdlwiPT09Znx8XCJzZW5kb25seVwiPT09Zil9fSksdGhpcy5yZW1vdGVEZXNjcmlwdGlvbj17dHlwZTp0LnR5cGUsc2RwOnQuc2RwfSx0LnR5cGUpe2Nhc2VcIm9mZmVyXCI6dGhpcy5yUChcImhhdmUtcmVtb3RlLW9mZmVyXCIpO2JyZWFrO2Nhc2VcImFuc3dlclwiOnRoaXMuclAoXCJzdGFibGVcIik7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgVHlwZUVycm9yKCd1bnN1cHBvcnRlZCB0eXBlIFwiJyt0LnR5cGUrJ1wiJyl9cmV0dXJuIGkuZ2V0VHJhY2tzKCkubGVuZ3RoJiYoZS5CTy5wdXNoKGkpLHdpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dmFyIHQ9bmV3IEV2ZW50KFwiYWRkc3RyZWFtXCIpO3Quc3RyZWFtPWksZS5kaXNwYXRjaEV2ZW50KHQpLG51bGwhPT1lLm9uYWRkc3RyZWFtJiZ3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpe2Uub25hZGRzdHJlYW0odCl9LDApLHIuZm9yRWFjaChmdW5jdGlvbih0KXt2YXIgcj10WzBdLG49dFsxXSxvPW5ldyBFdmVudChcInRyYWNrXCIpO28udHJhY2s9cixvLnJlY2VpdmVyPW4sby5zTz1baV0sZS5kaXNwYXRjaEV2ZW50KG8pLG51bGwhPT1lLkFPJiZ3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpe2UuQU8obyl9LDApfSl9LDApKSxhcmd1bWVudHMubGVuZ3RoPjEmJlwiZnVuY3Rpb25cIj09dHlwZW9mIGFyZ3VtZW50c1sxXSYmd2luZG93LnNldFRpbWVvdXQoYXJndW1lbnRzWzFdLDApLFByb21pc2UucmVzb2x2ZSgpfSx3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmNsb3NlPWZ1bmN0aW9uKCl7dGhpcy5MTy5mb3JFYWNoKGZ1bmN0aW9uKHQpe3QuJE8mJnQuJE8uc3RvcCgpLHQuWEUmJnQuWEUuc3RvcCgpLHQudEkmJnQudEkuc3RvcCgpLHQuZUkmJnQuZUkuc3RvcCgpfSksdGhpcy5yUChcImNsb3NlZFwiKX0sd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5yUD1mdW5jdGlvbih0KXt0aGlzLnNpZ25hbGluZ1N0YXRlPXQ7dmFyIGU9bmV3IEV2ZW50KFwic2lnbmFsaW5nc3RhdGVjaGFuZ2VcIik7dGhpcy5kaXNwYXRjaEV2ZW50KGUpLG51bGwhPT10aGlzLm9uc2lnbmFsaW5nc3RhdGVjaGFuZ2UmJnRoaXMub25zaWduYWxpbmdzdGF0ZWNoYW5nZShlKX0sd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5WTz1mdW5jdGlvbigpe3ZhciB0PW5ldyBFdmVudChcIm5lZ290aWF0aW9ubmVlZGVkXCIpO3RoaXMuZGlzcGF0Y2hFdmVudCh0KSxudWxsIT09dGhpcy5vbm5lZ290aWF0aW9ubmVlZGVkJiZ0aGlzLm9ubmVnb3RpYXRpb25uZWVkZWQodCl9LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuek89ZnVuY3Rpb24oKXt2YXIgdCxlPXRoaXMsaT17blA6MCxjbG9zZWQ6MCxvUDowLHNQOjAsY29ubmVjdGVkOjAsYVA6MCxfaTowfTtpZih0aGlzLkxPLmZvckVhY2goZnVuY3Rpb24odCl7aVt0LiRPLnN0YXRlXSsrLGlbdC5YRS5zdGF0ZV0rK30pLGkuY29ubmVjdGVkKz1pLmFQLHQ9XCJuZXdcIixpLl9pPjA/dD1cImZhaWxlZFwiOmkub1A+MHx8aS5zUD4wP3Q9XCJjb25uZWN0aW5nXCI6aS5kaXNjb25uZWN0ZWQ+MD90PVwiZGlzY29ubmVjdGVkXCI6aVtcIm5QXCJdPjA/dD1cIm5ld1wiOihpLmNvbm5lY3RlZD4wfHxpLmFQPjApJiYodD1cImNvbm5lY3RlZFwiKSx0IT09ZS5pY2VDb25uZWN0aW9uU3RhdGUpe2UuaWNlQ29ubmVjdGlvblN0YXRlPXQ7dmFyIHI9bmV3IEV2ZW50KFwiaWNlY29ubmVjdGlvbnN0YXRlY2hhbmdlXCIpO3RoaXMuZGlzcGF0Y2hFdmVudChyKSxudWxsIT09dGhpcy5vbmljZWNvbm5lY3Rpb25zdGF0ZWNoYW5nZSYmdGhpcy5vbmljZWNvbm5lY3Rpb25zdGF0ZWNoYW5nZShyKX19LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuY3JlYXRlT2ZmZXI9ZnVuY3Rpb24oKXt2YXIgdD10aGlzO2lmKHRoaXMuS08pdGhyb3cgbmV3IEVycm9yKFwiY3JlYXRlT2ZmZXIgY2FsbGVkIHdoaWxlIHRoZXJlIGlzIGEgcGVuZGluZyBvZmZlci5cIik7dmFyIGU7MT09PWFyZ3VtZW50cy5sZW5ndGgmJlwiZnVuY3Rpb25cIiE9dHlwZW9mIGFyZ3VtZW50c1swXT9lPWFyZ3VtZW50c1swXTozPT09YXJndW1lbnRzLmxlbmd0aCYmKGU9YXJndW1lbnRzWzJdKTt2YXIgaT1bXSxuPTAsYT0wO2lmKHRoaXMueE8ubGVuZ3RoJiYobj10aGlzLnhPWzBdLmdldEF1ZGlvVHJhY2tzKCkubGVuZ3RoLGE9dGhpcy54T1swXS5nZXRWaWRlb1RyYWNrcygpLmxlbmd0aCksZSl7aWYoZS5nT3x8ZS5vcHRpb25hbCl0aHJvdyBuZXcgVHlwZUVycm9yKFwiTGVnYWN5IG1hbmRhdG9yeS9vcHRpb25hbCBjb25zdHJhaW50cyBub3Qgc3VwcG9ydGVkLlwiKTt2b2lkIDAhPT1lLmNQJiYobj1lLmNQKSx2b2lkIDAhPT1lLmhQJiYoYT1lLmhQKX1mb3IodGhpcy54Ty5sZW5ndGgmJnRoaXMueE9bMF0uZ2V0VHJhY2tzKCkuZm9yRWFjaChmdW5jdGlvbih0KXtpLnB1c2goe2tpbmQ6dC5raW5kLHRyYWNrOnQscFA6XCJhdWRpb1wiPT09dC5raW5kP24+MDphPjB9KSxcImF1ZGlvXCI9PT10LmtpbmQ/bi0tOlwidmlkZW9cIj09PXQua2luZCYmYS0tfSk7bj4wfHxhPjA7KW4+MCYmKGkucHVzaCh7a2luZDpcImF1ZGlvXCIscFA6ITB9KSxuLS0pLGE+MCYmKGkucHVzaCh7a2luZDpcInZpZGVvXCIscFA6ITB9KSxhLS0pO2k9cihpKTt2YXIgYz1vLldFKCksaD1bXTtpLmZvckVhY2goZnVuY3Rpb24oZSxpKXt2YXIgcj1lLnRyYWNrLG49ZS5raW5kLGE9by5RYigpLGM9dC5ETyYmaT4wP3tZRTpoWzBdLllFLCRPOmhbMF0uJE8sWEU6aFswXS5YRX06dC5xTyhhLGkpLHA9UlRDUnRwU2VuZGVyLmdldENhcGFiaWxpdGllcyhuKTtzLnZlcnNpb248MTUwMTkmJihwLk5FPXAuTkUuZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVyblwicnR4XCIhPT10Lm5hbWV9KSkscC5ORS5mb3JFYWNoKGZ1bmN0aW9uKHQpe1wiSDI2NFwiPT09dC5uYW1lJiZ2b2lkIDA9PT10LnBhcmFtZXRlcnNbXCJ1UFwiXSYmKHQucGFyYW1ldGVyc1tcInVQXCJdPVwiMVwiKX0pO3ZhciB1LGwsZD1be3dFOjEwMDEqKDIqaSsxKX1dO3ImJihzLnZlcnNpb24+PTE1MDE5JiZcInZpZGVvXCI9PT1uJiYoZFswXS5NRT17d0U6MTAwMSooMippKzEpKzF9KSx1PW5ldyBSVENSdHBTZW5kZXIocixjLlhFKSksZS5wUCYmKGw9bmV3IFJUQ1J0cFJlY2VpdmVyKGMuWEUsbikpLGhbaV09e1lFOmMuWUUsJE86Yy4kTyxYRTpjLlhFLFhPOnAsWk86bnVsbCx0STp1LGVJOmwsa2luZDpuLFpFOmEsaUk6ZCxlUDpudWxsfX0pLHRoaXMuRE8mJihjKz1cImE9Z3JvdXA6QlVORExFIFwiK2gubWFwKGZ1bmN0aW9uKHQpe3JldHVybiB0LlpFfSkuam9pbihcIiBcIikrXCJcXHJcXG5cIiksaS5mb3JFYWNoKGZ1bmN0aW9uKGUsaSl7dmFyIHI9aFtpXTtjKz1vLiRFKHIsci5YTyxcIm9mZmVyXCIsdC54T1swXSl9KSx0aGlzLktPPWg7dmFyIHA9bmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbih7dHlwZTpcIm9mZmVyXCIsc2RwOmN9KTtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aCYmXCJmdW5jdGlvblwiPT10eXBlb2YgYXJndW1lbnRzWzBdJiZ3aW5kb3cuc2V0VGltZW91dChhcmd1bWVudHNbMF0sMCxwKSxQcm9taXNlLnJlc29sdmUocCl9LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuY3JlYXRlQW5zd2VyPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxlPW8uV0UoKTt0aGlzLkRPJiYoZSs9XCJhPWdyb3VwOkJVTkRMRSBcIit0aGlzLkxPLm1hcChmdW5jdGlvbih0KXtyZXR1cm4gdC5aRX0pLmpvaW4oXCIgXCIpK1wiXFxyXFxuXCIpLHRoaXMuTE8uZm9yRWFjaChmdW5jdGlvbihpKXtpZihpLmlQKXJldHVybiB2b2lkKGUrPVwibT1hcHBsaWNhdGlvbiAwIERUTFMvU0NUUCA1MDAwXFxyXFxuYz1JTiBJUDQgMC4wLjAuMFxcclxcbmE9bWlkOlwiK2kuWkUrXCJcXHJcXG5cIik7dmFyIHI9dC5RTyhpLlhPLGkuWk8pO2UrPW8uJEUoaSxyLFwiYW5zd2VyXCIsdC54T1swXSl9KTt2YXIgaT1uZXcgUlRDU2Vzc2lvbkRlc2NyaXB0aW9uKHt0eXBlOlwiYW5zd2VyXCIsc2RwOmV9KTtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aCYmXCJmdW5jdGlvblwiPT10eXBlb2YgYXJndW1lbnRzWzBdJiZ3aW5kb3cuc2V0VGltZW91dChhcmd1bWVudHNbMF0sMCxpKSxQcm9taXNlLnJlc29sdmUoaSl9LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuYWRkSWNlQ2FuZGlkYXRlPWZ1bmN0aW9uKHQpe2lmKHQpe3ZhciBlPXQuc2RwTUxpbmVJbmRleDtpZih0LnNkcE1pZClmb3IodmFyIGk9MDtpPHRoaXMuTE8ubGVuZ3RoO2krKylpZih0aGlzLkxPW2ldLlpFPT09dC5zZHBNaWQpe2U9aTticmVha312YXIgcj10aGlzLkxPW2VdO2lmKHIpe3ZhciBuPU9iamVjdC5rZXlzKHQuY2FuZGlkYXRlKS5sZW5ndGg+MD9vLnpiKHQuY2FuZGlkYXRlKTp7fTtpZihcInRjcFwiPT09bi5wcm90b2NvbCYmKDA9PT1uLnBvcnR8fDk9PT1uLnBvcnQpKXJldHVybiBQcm9taXNlLnJlc29sdmUoKTtpZihcIjFcIiE9PW4uJGIpcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO3IuJE8uYWRkUmVtb3RlQ2FuZGlkYXRlKG4pO3ZhciBzPW8uS2IodGhpcy5yZW1vdGVEZXNjcmlwdGlvbi5zZHApO3NbZSsxXSs9KG4udHlwZT90LmNhbmRpZGF0ZS50cmltKCk6XCJhPWVuZC1vZi1jYW5kaWRhdGVzXCIpK1wiXFxyXFxuXCIsdGhpcy5yZW1vdGVEZXNjcmlwdGlvbi5zZHA9cy5qb2luKFwiXCIpfX1lbHNlIGZvcih2YXIgYT0wO2E8dGhpcy5MTy5sZW5ndGg7YSsrKWlmKHRoaXMuTE9bYV0uJE8uYWRkUmVtb3RlQ2FuZGlkYXRlKHt9KSx0aGlzLkRPKXJldHVybiBQcm9taXNlLnJlc29sdmUoKTtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD4xJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBhcmd1bWVudHNbMV0mJndpbmRvdy5zZXRUaW1lb3V0KGFyZ3VtZW50c1sxXSwwKSxQcm9taXNlLnJlc29sdmUoKX0sd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5nZXRTdGF0cz1mdW5jdGlvbigpe3ZhciB0PVtdO3RoaXMuTE8uZm9yRWFjaChmdW5jdGlvbihlKXtbXCJydHBTZW5kZXJcIixcInJ0cFJlY2VpdmVyXCIsXCJpY2VHYXRoZXJlclwiLFwiaWNlVHJhbnNwb3J0XCIsXCJkdGxzVHJhbnNwb3J0XCJdLmZvckVhY2goZnVuY3Rpb24oaSl7ZVtpXSYmdC5wdXNoKGVbaV0uZ2V0U3RhdHMoKSl9KX0pO3ZhciBlPWFyZ3VtZW50cy5sZW5ndGg+MSYmXCJmdW5jdGlvblwiPT10eXBlb2YgYXJndW1lbnRzWzFdJiZhcmd1bWVudHNbMV0saT1mdW5jdGlvbih0KXtyZXR1cm57bFA6XCJpbmJvdW5kLXJ0cFwiLGRQOlwib3V0Ym91bmQtcnRwXCIsZlA6XCJjYW5kaWRhdGUtcGFpclwiLGRPOlwibG9jYWwtY2FuZGlkYXRlXCIsZk86XCJyZW1vdGUtY2FuZGlkYXRlXCJ9W3QudHlwZV18fHQudHlwZX07cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHIpe3ZhciBuPW5ldyBNYXA7UHJvbWlzZS5hbGwodCkudGhlbihmdW5jdGlvbih0KXt0LmZvckVhY2goZnVuY3Rpb24odCl7T2JqZWN0LmtleXModCkuZm9yRWFjaChmdW5jdGlvbihlKXt0W2VdLnR5cGU9aSh0W2VdKSxuLnNldChlLHRbZV0pfSl9KSxlJiZ3aW5kb3cuc2V0VGltZW91dChlLDAsbikscihuKX0pfSl9fX07dC50PXtYQzphLlhDLFpDOmkoNjkpfX0sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjt0LnQ9ZnVuY3Rpb24oKXt2YXIgdD1mdW5jdGlvbih0KXtyZXR1cm57bmFtZTp7RU86XCJOb3RBbGxvd2VkRXJyb3JcIn1bdC5uYW1lXXx8dC5uYW1lLG1lc3NhZ2U6dC5tZXNzYWdlLFJPOnQuUk8sdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5uYW1lfX19LGU9bmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEuYmluZChuYXZpZ2F0b3IubWVkaWFEZXZpY2VzKTtuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYT1mdW5jdGlvbihpKXtyZXR1cm4gZShpKVtcImNhdGNoXCJdKGZ1bmN0aW9uKGUpe3JldHVybiBQcm9taXNlLnJlamVjdCh0KGUpKX0pfX19LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcj1pKDMpLnJpLG49e2lPOmZ1bmN0aW9uKCl7XCJvYmplY3RcIiE9dHlwZW9mIHdpbmRvd3x8IXdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbnx8XCJvbnRyYWNrXCJpbiB3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlfHxPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZSxcIm9udHJhY2tcIix7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubk99LHNldDpmdW5jdGlvbih0KXt0aGlzLm5PJiYodGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKFwidHJhY2tcIix0aGlzLm5PKSx0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJhZGRzdHJlYW1cIix0aGlzLm9PKSksdGhpcy5hZGRFdmVudExpc3RlbmVyKFwidHJhY2tcIix0aGlzLm5PPXQpLHRoaXMuYWRkRXZlbnRMaXN0ZW5lcihcImFkZHN0cmVhbVwiLHRoaXMub089ZnVuY3Rpb24odCl7dC5zdHJlYW0uZ2V0VHJhY2tzKCkuZm9yRWFjaChmdW5jdGlvbihlKXt2YXIgaT1uZXcgRXZlbnQoXCJ0cmFja1wiKTtpLnRyYWNrPWUsaS5yZWNlaXZlcj17dHJhY2s6ZX0saS5zTz1bdC5zdHJlYW1dLHRoaXMuZGlzcGF0Y2hFdmVudChpKX0uYmluZCh0aGlzKSl9LmJpbmQodGhpcykpfX0pfSxlTzpmdW5jdGlvbigpe1wib2JqZWN0XCI9PXR5cGVvZiB3aW5kb3cmJighd2luZG93LkhUTUxNZWRpYUVsZW1lbnR8fFwic3JjT2JqZWN0XCJpbiB3aW5kb3cuSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGV8fE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUsXCJzcmNPYmplY3RcIix7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubW96U3JjT2JqZWN0fSxzZXQ6ZnVuY3Rpb24odCl7dGhpcy5tb3pTcmNPYmplY3Q9dH19KSl9LFhDOmZ1bmN0aW9uKCl7aWYoXCJvYmplY3RcIj09dHlwZW9mIHdpbmRvdyYmKHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbnx8d2luZG93Lm1velJUQ1BlZXJDb25uZWN0aW9uKSl7d2luZG93LlJUQ1BlZXJDb25uZWN0aW9ufHwod2luZG93LlJUQ1BlZXJDb25uZWN0aW9uPWZ1bmN0aW9uKHQsZSl7aWYoci52ZXJzaW9uPDM4JiZ0JiZ0LmljZVNlcnZlcnMpe2Zvcih2YXIgaT1bXSxuPTA7bjx0LmljZVNlcnZlcnMubGVuZ3RoO24rKyl7dmFyIG89dC5pY2VTZXJ2ZXJzW25dO2lmKG8uaGFzT3duUHJvcGVydHkoXCJ1cmxzXCIpKWZvcih2YXIgcz0wO3M8by5QTy5sZW5ndGg7cysrKXt2YXIgYT17dXJsOm8uUE9bc119OzA9PT1vLlBPW3NdLmluZGV4T2YoXCJ0dXJuXCIpJiYoYS51c2VybmFtZT1vLnVzZXJuYW1lLGEuZ1A9by5nUCksaS5wdXNoKGEpfWVsc2UgaS5wdXNoKHQuaWNlU2VydmVyc1tuXSl9dC5pY2VTZXJ2ZXJzPWl9cmV0dXJuIG5ldyBtb3pSVENQZWVyQ29ubmVjdGlvbih0LGUpfSx3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlPW1velJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZSxtb3pSVENQZWVyQ29ubmVjdGlvbi5nZW5lcmF0ZUNlcnRpZmljYXRlJiZPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLFwiZ2VuZXJhdGVDZXJ0aWZpY2F0ZVwiLHtnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gbW96UlRDUGVlckNvbm5lY3Rpb24uZ2VuZXJhdGVDZXJ0aWZpY2F0ZX19KSx3aW5kb3cuUlRDU2Vzc2lvbkRlc2NyaXB0aW9uPW1velJUQ1Nlc3Npb25EZXNjcmlwdGlvbix3aW5kb3cuUlRDSWNlQ2FuZGlkYXRlPW1velJUQ0ljZUNhbmRpZGF0ZSksW1wic2V0TG9jYWxEZXNjcmlwdGlvblwiLFwic2V0UmVtb3RlRGVzY3JpcHRpb25cIixcImFkZEljZUNhbmRpZGF0ZVwiXS5mb3JFYWNoKGZ1bmN0aW9uKHQpe3ZhciBlPVJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZVt0XTtSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGVbdF09ZnVuY3Rpb24oKXtyZXR1cm4gYXJndW1lbnRzWzBdPW5ldyhcImFkZEljZUNhbmRpZGF0ZVwiPT09dD9SVENJY2VDYW5kaWRhdGU6UlRDU2Vzc2lvbkRlc2NyaXB0aW9uKShhcmd1bWVudHNbMF0pLGUuYXBwbHkodGhpcyxhcmd1bWVudHMpfX0pO3ZhciB0PVJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5hZGRJY2VDYW5kaWRhdGU7UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmFkZEljZUNhbmRpZGF0ZT1mdW5jdGlvbigpe3JldHVybiBhcmd1bWVudHNbMF0/dC5hcHBseSh0aGlzLGFyZ3VtZW50cyk6KGFyZ3VtZW50c1sxXSYmYXJndW1lbnRzWzFdLmFwcGx5KG51bGwpLFByb21pc2UucmVzb2x2ZSgpKX07dmFyIGU9ZnVuY3Rpb24odCl7dmFyIGU9bmV3IE1hcDtyZXR1cm4gT2JqZWN0LmtleXModCkuZm9yRWFjaChmdW5jdGlvbihpKXtlLnNldChpLHRbaV0pLGVbaV09dFtpXX0pLGV9LGk9e2xQOlwiaW5ib3VuZC1ydHBcIixkUDpcIm91dGJvdW5kLXJ0cFwiLGZQOlwiY2FuZGlkYXRlLXBhaXJcIixkTzpcImxvY2FsLWNhbmRpZGF0ZVwiLGZPOlwicmVtb3RlLWNhbmRpZGF0ZVwifSxuPVJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5nZXRTdGF0cztSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0U3RhdHM9ZnVuY3Rpb24odCxvLHMpe3JldHVybiBuLmFwcGx5KHRoaXMsW3R8fG51bGxdKS50aGVuKGZ1bmN0aW9uKHQpe2lmKHIudmVyc2lvbjw0OCYmKHQ9ZSh0KSksci52ZXJzaW9uPDUzJiYhbyl0cnl7dC5mb3JFYWNoKGZ1bmN0aW9uKHQpe3QudHlwZT1pW3QudHlwZV18fHQudHlwZX0pfWNhdGNoKG4pe2lmKFwiVHlwZUVycm9yXCIhPT1uLm5hbWUpdGhyb3cgbjt0LmZvckVhY2goZnVuY3Rpb24oZSxyKXt0LnNldChyLE9iamVjdC5hc3NpZ24oe30sZSx7dHlwZTppW2UudHlwZV18fGUudHlwZX0pKX0pfXJldHVybiB0fSkudGhlbihvLHMpfX19fTt0LnQ9e2lPOm4uaU8sZU86bi5lTyxYQzpuLlhDLFpDOmkoNzEpfX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPWkoMykubG9nLG49aSgzKS5yaTt0LnQ9ZnVuY3Rpb24oKXt2YXIgdD1mdW5jdGlvbih0KXtyZXR1cm57bmFtZTp7dlA6XCJOb3RBbGxvd2VkRXJyb3JcIixFTzpcIk5vdEFsbG93ZWRFcnJvclwifVt0Lm5hbWVdfHx0Lm5hbWUsbWVzc2FnZTp7XCJUaGUgb3BlcmF0aW9uIGlzIGluc2VjdXJlLlwiOlwiVGhlIHJlcXVlc3QgaXMgbm90IGFsbG93ZWQgYnkgdGhlIHVzZXIgYWdlbnQgb3IgdGhlIHBsYXRmb3JtIGluIHRoZSBjdXJyZW50IGNvbnRleHQuXCJ9W3QubWVzc2FnZV18fHQubWVzc2FnZSxSTzp0LlJPLHRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubmFtZSsodGhpcy5tZXNzYWdlJiZcIjogXCIpK3RoaXMubWVzc2FnZX19fSxlPWZ1bmN0aW9uKGUsaSxvKXt2YXIgcz1mdW5jdGlvbih0KXtpZihcIm9iamVjdFwiIT10eXBlb2YgdHx8dC55UClyZXR1cm4gdDt2YXIgZT1bXTtyZXR1cm4gT2JqZWN0LmtleXModCkuZm9yRWFjaChmdW5jdGlvbihpKXtpZihcInJlcXVpcmVcIiE9PWkmJlwiYWR2YW5jZWRcIiE9PWkmJlwibWVkaWFTb3VyY2VcIiE9PWkpe3ZhciByPXRbaV09XCJvYmplY3RcIj09dHlwZW9mIHRbaV0/dFtpXTp7dk86dFtpXX07aWYodm9pZCAwPT09ci5taW4mJnZvaWQgMD09PXIubWF4JiZ2b2lkIDA9PT1yLnlPfHxlLnB1c2goaSksdm9pZCAwIT09ci55TyYmKFwibnVtYmVyXCI9PXR5cGVvZiByLnlPP3IubWluPXIubWF4PXIueU86dFtpXT1yLnlPLGRlbGV0ZSByLnlPKSx2b2lkIDAhPT1yLnZPKXt0Lm1PPXQubU98fFtdO3ZhciBuPXt9O1wibnVtYmVyXCI9PXR5cGVvZiByLnZPP25baV09e21pbjpyLnZPLG1heDpyLnZPfTpuW2ldPXIudk8sdC5tTy5wdXNoKG4pLGRlbGV0ZSByLnZPLE9iamVjdC5rZXlzKHIpLmxlbmd0aHx8ZGVsZXRlIHRbaV19fX0pLGUubGVuZ3RoJiYodC55UD1lKSx0fTtyZXR1cm4gZT1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KGUpKSxuLnZlcnNpb248MzgmJihyKFwic3BlYzogXCIrSlNPTi5zdHJpbmdpZnkoZSkpLGUuTXAmJihlLk1wPXMoZS5NcCkpLGUudmlkZW8mJihlLnZpZGVvPXMoZS52aWRlbykpLHIoXCJmZjM3OiBcIitKU09OLnN0cmluZ2lmeShlKSkpLG5hdmlnYXRvci5tb3pHZXRVc2VyTWVkaWEoZSxpLGZ1bmN0aW9uKGUpe28odChlKSl9KX0saT1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24oaSxyKXtlKHQsaSxyKX0pfTtpZihuYXZpZ2F0b3IubWVkaWFEZXZpY2VzfHwobmF2aWdhdG9yLm1lZGlhRGV2aWNlcz17Z2V0VXNlck1lZGlhOmksYWRkRXZlbnRMaXN0ZW5lcjpmdW5jdGlvbigpe30scmVtb3ZlRXZlbnRMaXN0ZW5lcjpmdW5jdGlvbigpe319KSxuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLlNPPW5hdmlnYXRvci5tZWRpYURldmljZXMuU098fGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHQpe3ZhciBlPVt7a2luZDpcImF1ZGlvaW5wdXRcIixiTzpcImRlZmF1bHRcIixsYWJlbDpcIlwiLGtPOlwiXCJ9LHtraW5kOlwidmlkZW9pbnB1dFwiLGJPOlwiZGVmYXVsdFwiLGxhYmVsOlwiXCIsa086XCJcIn1dO3QoZSl9KX0sbi52ZXJzaW9uPDQxKXt2YXIgbz1uYXZpZ2F0b3IubWVkaWFEZXZpY2VzLlNPLmJpbmQobmF2aWdhdG9yLm1lZGlhRGV2aWNlcyk7bmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5TTz1mdW5jdGlvbigpe3JldHVybiBvKCkudGhlbih2b2lkIDAsZnVuY3Rpb24odCl7aWYoXCJOb3RGb3VuZEVycm9yXCI9PT10Lm5hbWUpcmV0dXJuW107dGhyb3cgdH0pfX1pZihuLnZlcnNpb248NDkpe3ZhciBzPW5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhLmJpbmQobmF2aWdhdG9yLm1lZGlhRGV2aWNlcyk7bmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWE9ZnVuY3Rpb24oZSl7cmV0dXJuIHMoZSkudGhlbihmdW5jdGlvbih0KXtpZihlLk1wJiYhdC5nZXRBdWRpb1RyYWNrcygpLmxlbmd0aHx8ZS52aWRlbyYmIXQuZ2V0VmlkZW9UcmFja3MoKS5sZW5ndGgpdGhyb3cgdC5nZXRUcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uKHQpe3Quc3RvcCgpfSksbmV3IERPTUV4Y2VwdGlvbihcIlRoZSBvYmplY3QgY2FuIG5vdCBiZSBmb3VuZCBoZXJlLlwiLFwiTm90Rm91bmRFcnJvclwiKTtyZXR1cm4gdH0sZnVuY3Rpb24oZSl7cmV0dXJuIFByb21pc2UucmVqZWN0KHQoZSkpfSl9fW5hdmlnYXRvci5nZXRVc2VyTWVkaWE9ZnVuY3Rpb24odCxpLHIpe3JldHVybiBuLnZlcnNpb248NDQ/ZSh0LGkscik6KGNvbnNvbGUud2FybihcIm5hdmlnYXRvci5nZXRVc2VyTWVkaWEgaGFzIGJlZW4gcmVwbGFjZWQgYnkgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWFcIiksdm9pZCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh0KS50aGVuKGkscikpfX19LGZ1bmN0aW9uKHQsZSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGk9e1pDOmZ1bmN0aW9uKCl7bmF2aWdhdG9yLmdldFVzZXJNZWRpYXx8KG5hdmlnYXRvci53ZWJraXRHZXRVc2VyTWVkaWE/bmF2aWdhdG9yLmdldFVzZXJNZWRpYT1uYXZpZ2F0b3Iud2Via2l0R2V0VXNlck1lZGlhLmJpbmQobmF2aWdhdG9yKTpuYXZpZ2F0b3IubWVkaWFEZXZpY2VzJiZuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSYmKG5hdmlnYXRvci5nZXRVc2VyTWVkaWE9ZnVuY3Rpb24odCxlLGkpe25hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKHQpLnRoZW4oZSxpKX0uYmluZChuYXZpZ2F0b3IpKSl9fTt0LnQ9e1pDOmkuWkN9fV0pO1xuXG4vLyMgc291cmNlTWFwcGluZ1VSTD1iaXRtb3Zpbi5oaXZlLm1pbi5qcy5tYXBcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi9oaXZlL2JpdG1vdmluLmhpdmUubWluLmpzXG4vLyBtb2R1bGUgaWQgPSA0N1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiXSwic291cmNlUm9vdCI6IiJ9 \ No newline at end of file +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly8vd2VicGFjay9ib290c3RyYXAgN2Q4MWQxYjgxZjUxMTQ1YjQ1MzMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvZG9tLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvY29udGFpbmVyLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvY29tcG9uZW50LnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2V2ZW50ZGlzcGF0Y2hlci50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9hcnJheXV0aWxzLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL3BsYXllcnV0aWxzLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvYnV0dG9uLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvbGFiZWwudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy90b2dnbGVidXR0b24udHMiLCJ3ZWJwYWNrOi8vL2V4dGVybmFsIFwiYW5ndWxhclwiIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL3RpbWVvdXQudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvYnJvd3NlcnV0aWxzLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvcGxheWJhY2t0b2dnbGVidXR0b24udHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9zZWVrYmFyLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL3N0cmluZ3V0aWxzLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvY29udHJvbGJhci50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci91aXV0aWxzLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvdWljb250YWluZXIudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9wbGF5YmFja3RpbWVsYWJlbC50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3NwYWNlci50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3NlZWtiYXJsYWJlbC50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3NlbGVjdGJveC50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2xpc3RzZWxlY3Rvci50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3ZvbHVtZWNvbnRyb2xidXR0b24udHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy92b2x1bWVzbGlkZXIudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy92b2x1bWV0b2dnbGVidXR0b24udHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9lcnJvcm1lc3NhZ2VvdmVybGF5LnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvcGxheWJhY2t0b2dnbGVvdmVybGF5LnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvaHVnZXBsYXliYWNrdG9nZ2xlYnV0dG9uLnRzIiwid2VicGFjazovLy8uLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvYXVkaW9vbmx5b3ZlcmxheS50cyIsIndlYnBhY2s6Ly8vLi9pbmRleC50cyIsIndlYnBhY2s6Ly8vLi9iaXRkYXNoLWNvbnRyb2xsZXIudHMiLCJ3ZWJwYWNrOi8vLy4vYml0ZGFzaC1kaXJlY3RpdmUudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvbWFpbi50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci91aW1hbmFnZXIudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvZ3VpZC50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2Z1bGxzY3JlZW50b2dnbGVidXR0b24udHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvaW1hZ2Vsb2FkZXIudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9zdWJ0aXRsZXNlbGVjdGJveC50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3N1YnRpdGxlb3ZlcmxheS50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3R2bm9pc2VjYW52YXMudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9pdGVtc2VsZWN0aW9ubGlzdC50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2NsaWNrb3ZlcmxheS50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2h1Z2VyZXBsYXlidXR0b24udHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9jbG9zZWJ1dHRvbi50cyIsIndlYnBhY2s6Ly8vLi4vbGliL3VpbWFuYWdlci9zdG9yYWdldXRpbHMudHMiLCJ3ZWJwYWNrOi8vLy4uL2xpYi9oaXZlL2JpdG1vdmluLmhpdmUubWluLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7O0FBR0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBSztBQUNMO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsbUNBQTJCLDBCQUEwQixFQUFFO0FBQ3ZELHlDQUFpQyxlQUFlO0FBQ2hEO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDhEQUFzRCwrREFBK0Q7O0FBRXJIO0FBQ0E7O0FBRUE7QUFDQTs7Ozs7Ozs7QUM3REE7QUFDQSw4Q0FBOEMsY0FBYztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlDQUFpQztBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUIsT0FBTztBQUM1QjtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0EsaUJBQWlCLGNBQWM7QUFDL0Isd0JBQXdCLGFBQWE7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLElBQUk7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQSx3QkFBd0IsdUJBQXVCO0FBQy9DO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQixhQUFhO0FBQ2IsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixPQUFPO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLE9BQU87QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7Ozs7Ozs7O0FDbFpBO0FBQ0E7QUFDQTtBQUNBLFVBQVUsZ0JBQWdCLHNDQUFzQyxpQkFBaUIsRUFBRTtBQUNuRix5QkFBeUIsdURBQXVEO0FBQ2hGO0FBQ0E7QUFDQSx1QkFBdUIsc0JBQXNCO0FBQzdDO0FBQ0E7QUFDQSxDQUFDO0FBQ0QsOENBQThDLGNBQWM7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZEQUE2RCxpQ0FBaUM7QUFDOUYsZ0JBQWdCLDZCQUE2QjtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDJEQUEyRCxnQkFBZ0I7QUFDM0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLHFEQUFxRCxnQkFBZ0I7QUFDckU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDs7Ozs7Ozs7QUMzSEE7QUFDQSw4Q0FBOEMsY0FBYztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLGFBQWE7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQix1QkFBdUI7QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsOEJBQThCO0FBQzlDO0FBQ0E7QUFDQSw2RUFBNkUsd0NBQXdDO0FBQ3JIO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCLGNBQWM7QUFDOUI7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCLFlBQVksZ0RBQWdELCtCQUErQjtBQUN4SCxnQkFBZ0IsY0FBYztBQUM5QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLElBQUk7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsbURBQW1ELHdCQUF3QjtBQUMzRTtBQUNBLGlFQUFpRSxrQkFBa0I7QUFDbkY7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBLHFDQUFxQztBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0VBQWtFLG1DQUFtQztBQUNyRztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRUFBa0UsbUNBQW1DO0FBQ3JHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtFQUFrRSxtQ0FBbUM7QUFDckc7QUFDQTtBQUNBO0FBQ0EsNERBQTRELG1CQUFtQjtBQUMvRTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHNFQUFzRSxtQ0FBbUM7QUFDekcscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLHNFQUFzRSxtQ0FBbUM7QUFDekcscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTs7Ozs7Ozs7QUN2VUE7QUFDQTtBQUNBO0FBQ0EsVUFBVSxnQkFBZ0Isc0NBQXNDLGlCQUFpQixFQUFFO0FBQ25GLHlCQUF5Qix1REFBdUQ7QUFDaEY7QUFDQTtBQUNBLHVCQUF1QixzQkFBc0I7QUFDN0M7QUFDQTtBQUNBLENBQUM7QUFDRCw4Q0FBOEMsY0FBYztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCLDJCQUEyQjtBQUNsRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsOEJBQThCLGFBQWE7QUFDM0M7QUFDQTtBQUNBLDZDQUE2QyxnQkFBZ0I7QUFDN0Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpRUFBaUUsaUNBQWlDO0FBQ2xHO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQjtBQUNqQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0Esa0VBQWtFLHNCQUFzQjtBQUN4RjtBQUNBO0FBQ0E7QUFDQTtBQUNBLDhCQUE4QixjQUFjO0FBQzVDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGlCQUFpQixRQUFRO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQSxzQkFBc0IsMkJBQTJCO0FBQ2pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7Ozs7Ozs7O0FDL0pEO0FBQ0EsOENBQThDLGNBQWM7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLElBQUk7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUMsNkRBQTZEOzs7Ozs7OztBQ3BCOUQ7QUFDQSw4Q0FBOEMsY0FBYztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSyx3RUFBd0U7QUFDN0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrRkFBa0YsNENBQTRDO0FBQzlIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDZEQUE2RCxnQkFBZ0I7QUFDN0U7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQSxLQUFLO0FBQ0w7QUFDQSxDQUFDLGdFQUFnRTs7Ozs7Ozs7QUM5SGpFO0FBQ0E7QUFDQTtBQUNBLFVBQVUsZ0JBQWdCLHNDQUFzQyxpQkFBaUIsRUFBRTtBQUNuRix5QkFBeUIsdURBQXVEO0FBQ2hGO0FBQ0E7QUFDQSx1QkFBdUIsc0JBQXNCO0FBQzdDO0FBQ0E7QUFDQSxDQUFDO0FBQ0QsOENBQThDLGNBQWM7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0EsQ0FBQztBQUNEOzs7Ozs7OztBQ3JFQTtBQUNBO0FBQ0E7QUFDQSxVQUFVLGdCQUFnQixzQ0FBc0MsaUJBQWlCLEVBQUU7QUFDbkYseUJBQXlCLHVEQUF1RDtBQUNoRjtBQUNBO0FBQ0EsdUJBQXVCLHNCQUFzQjtBQUM3QztBQUNBO0FBQ0EsQ0FBQztBQUNELDhDQUE4QyxjQUFjO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQ0FBZ0MsYUFBYTtBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxnQkFBZ0IsT0FBTztBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQixRQUFRO0FBQ3hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsZUFBZTtBQUNqQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQixlQUFlO0FBQ2pDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQSxDQUFDO0FBQ0Q7Ozs7Ozs7O0FDdkhBO0FBQ0E7QUFDQTtBQUNBLFVBQVUsZ0JBQWdCLHNDQUFzQyxpQkFBaUIsRUFBRTtBQUNuRix5QkFBeUIsdURBQXVEO0FBQ2hGO0FBQ0E7QUFDQSx1QkFBdUIsc0JBQXNCO0FBQzdDO0FBQ0E7QUFDQSxDQUFDO0FBQ0QsOENBQThDLGNBQWM7QUFDNUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCLFFBQVE7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxLQUFLO0FBQ0w7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsS0FBSztBQUNMO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLENBQUM7QUFDRDtBQUNBO0FBQ0E7Ozs7Ozs7QUNwSUEseUI7Ozs7Ozs7QUNBQTtBQUNBLDhDQUE4QyxjQUFjO0FBQzVEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdDQUFnQyxnQkFBZ0I7QUFDaEQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsUUFBUTtBQUN6QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLENBQUM7QUFDRDs7Ozs7Ozs7QUM3REE7QUFDQSw4Q0FBOEMsY0FBYztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDLG1FQUFtRTs7Ozs7Ozs7QUNYcEU7QUFDQTtBQUNBO0FBQ0EsVUFBVSxnQkFBZ0Isc0NBQXNDLGlCQUFpQixFQUFFO0FBQ25GLHlCQUF5Qix1REFBdUQ7QUFDaEY7QUFDQTtBQUNBLHVCQUF1QixzQkFBc0I7QUFDN0M7QUFDQTtBQUNBLENBQUM7QUFDRCw4Q0FBOEMsY0FBYztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLGFBQWE7QUFDN0M7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSwwQ0FBMEMseUJBQXlCO0FBQ25FO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULG1DQUFtQztBQUNuQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxDQUFDO0FBQ0Q7QUFDQTs7Ozs7Ozs7QUM3RkE7QUFDQTtBQUNBO0FBQ0EsVUFBVSxnQkFBZ0Isc0NBQXNDLGlCQUFpQixFQUFFO0FBQ25GLHlCQUF5Qix1REFBdUQ7QUFDaEY7QUFDQTtBQUNBLHVCQUF1QixzQkFBc0I7QUFDN0M7QUFDQTtBQUNBLENBQUM7QUFDRCw4Q0FBOEMsY0FBYztBQUM1RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLGFBQWE7QUFDN0M7QUFDQTtBQUNBO0FBQ0EsdUNBQXVDLCtCQUErQjtBQUN0RSxrQkFBa0I7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1Q0FBdUMsc0JBQXNCO0FBQzdEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxtQ0FBbUMsY0FBYztBQUNqRCx5Q0FBeUMscUJBQXFCO0FBQzlEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsNkJBQTZCO0FBQzdCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0Esa0NBQWtDO0FBQ2xDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxREFBcUQsdUJBQXVCO0FBQzVFO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtB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LHdDQUF3QyxxREFBcUQsZ0RBQWdELCtDQUErQyxzQkFBc0IseUJBQXlCLEVBQUUsU0FBUyxnQ0FBZ0Msd0JBQXdCLHdCQUF3QixJQUFJLHVCQUF1QixHQUFHLEVBQUUsU0FBUyxnQkFBZ0IsS0FBSyxrQ0FBa0MsaUJBQWlCLGFBQWEseUJBQXlCLGVBQWUsa0JBQWtCLE9BQU8sTUFBTSwwQ0FBMEMsMEJBQTBCLG9IQUFvSCxtREFBbUQscURBQXFELG1CQUFtQixrQkFBa0IscUNBQXFDLFNBQVMsMENBQTBDLHFEQUFxRCx1Q0FBdUMsU0FBUyx5SkFBeUosY0FBYyxTQUFTLDRCQUE0QixrQkFBa0IseUVBQXlFLHdCQUF3QixnTkFBZ04sUUFBUSxFQUFFLGVBQWUsaUNBQWlDLFNBQVMsR0FBRyxvREFBb0QsNENBQTRDLGtDQUFrQyxrRUFBa0UsK0JBQStCLFFBQVEsOENBQThDLEVBQUUsOENBQThDLEVBQUUsS0FBSyxFQUFFLGVBQWUsNkRBQTZELHFDQUFxQyxtQ0FBbUMscUNBQXFDLFFBQVEsR0FBRyxpQkFBaUIsdUVBQXVFLGdEQUFnRCw2QkFBNkIsaUhBQWlILFNBQVMsd0VBQXdFLFNBQVMsYUFBYSw0QkFBNEIsR0FBRyx1Q0FBdUMsdUxBQXVMLGVBQWUsYUFBYSxPQUFPLGNBQWMsK05BQStOLGlEQUFpRCxxQkFBcUIsS0FBSyxTQUFTOztBQUUxdW5CIiwiZmlsZSI6Im1pLWFuZ3VsYXItYml0ZGFzaC1wbGF5ZXIuanMiLCJzb3VyY2VzQ29udGVudCI6WyIgXHQvLyBUaGUgbW9kdWxlIGNhY2hlXG4gXHR2YXIgaW5zdGFsbGVkTW9kdWxlcyA9IHt9O1xuXG4gXHQvLyBUaGUgcmVxdWlyZSBmdW5jdGlvblxuIFx0ZnVuY3Rpb24gX193ZWJwYWNrX3JlcXVpcmVfXyhtb2R1bGVJZCkge1xuXG4gXHRcdC8vIENoZWNrIGlmIG1vZHVsZSBpcyBpbiBjYWNoZVxuIFx0XHRpZihpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSkge1xuIFx0XHRcdHJldHVybiBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXS5leHBvcnRzO1xuIFx0XHR9XG4gXHRcdC8vIENyZWF0ZSBhIG5ldyBtb2R1bGUgKGFuZCBwdXQgaXQgaW50byB0aGUgY2FjaGUpXG4gXHRcdHZhciBtb2R1bGUgPSBpbnN0YWxsZWRNb2R1bGVzW21vZHVsZUlkXSA9IHtcbiBcdFx0XHRpOiBtb2R1bGVJZCxcbiBcdFx0XHRsOiBmYWxzZSxcbiBcdFx0XHRleHBvcnRzOiB7fVxuIFx0XHR9O1xuXG4gXHRcdC8vIEV4ZWN1dGUgdGhlIG1vZHVsZSBmdW5jdGlvblxuIFx0XHRtb2R1bGVzW21vZHVsZUlkXS5jYWxsKG1vZHVsZS5leHBvcnRzLCBtb2R1bGUsIG1vZHVsZS5leHBvcnRzLCBfX3dlYnBhY2tfcmVxdWlyZV9fKTtcblxuIFx0XHQvLyBGbGFnIHRoZSBtb2R1bGUgYXMgbG9hZGVkXG4gXHRcdG1vZHVsZS5sID0gdHJ1ZTtcblxuIFx0XHQvLyBSZXR1cm4gdGhlIGV4cG9ydHMgb2YgdGhlIG1vZHVsZVxuIFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHM7XG4gXHR9XG5cblxuIFx0Ly8gZXhwb3NlIHRoZSBtb2R1bGVzIG9iamVjdCAoX193ZWJwYWNrX21vZHVsZXNfXylcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubSA9IG1vZHVsZXM7XG5cbiBcdC8vIGV4cG9zZSB0aGUgbW9kdWxlIGNhY2hlXG4gXHRfX3dlYnBhY2tfcmVxdWlyZV9fLmMgPSBpbnN0YWxsZWRNb2R1bGVzO1xuXG4gXHQvLyBkZWZpbmUgZ2V0dGVyIGZ1bmN0aW9uIGZvciBoYXJtb255IGV4cG9ydHNcbiBcdF9fd2VicGFja19yZXF1aXJlX18uZCA9IGZ1bmN0aW9uKGV4cG9ydHMsIG5hbWUsIGdldHRlcikge1xuIFx0XHRpZighX193ZWJwYWNrX3JlcXVpcmVfXy5vKGV4cG9ydHMsIG5hbWUpKSB7XG4gXHRcdFx0T2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIG5hbWUsIHtcbiBcdFx0XHRcdGNvbmZpZ3VyYWJsZTogZmFsc2UsXG4gXHRcdFx0XHRlbnVtZXJhYmxlOiB0cnVlLFxuIFx0XHRcdFx0Z2V0OiBnZXR0ZXJcbiBcdFx0XHR9KTtcbiBcdFx0fVxuIFx0fTtcblxuIFx0Ly8gZ2V0RGVmYXVsdEV4cG9ydCBmdW5jdGlvbiBmb3IgY29tcGF0aWJpbGl0eSB3aXRoIG5vbi1oYXJtb255IG1vZHVsZXNcbiBcdF9fd2VicGFja19yZXF1aXJlX18ubiA9IGZ1bmN0aW9uKG1vZHVsZSkge1xuIFx0XHR2YXIgZ2V0dGVyID0gbW9kdWxlICYmIG1vZHVsZS5fX2VzTW9kdWxlID9cbiBcdFx0XHRmdW5jdGlvbiBnZXREZWZhdWx0KCkgeyByZXR1cm4gbW9kdWxlWydkZWZhdWx0J107IH0gOlxuIFx0XHRcdGZ1bmN0aW9uIGdldE1vZHVsZUV4cG9ydHMoKSB7IHJldHVybiBtb2R1bGU7IH07XG4gXHRcdF9fd2VicGFja19yZXF1aXJlX18uZChnZXR0ZXIsICdhJywgZ2V0dGVyKTtcbiBcdFx0cmV0dXJuIGdldHRlcjtcbiBcdH07XG5cbiBcdC8vIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbFxuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5vID0gZnVuY3Rpb24ob2JqZWN0LCBwcm9wZXJ0eSkgeyByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpOyB9O1xuXG4gXHQvLyBfX3dlYnBhY2tfcHVibGljX3BhdGhfX1xuIFx0X193ZWJwYWNrX3JlcXVpcmVfXy5wID0gXCJcIjtcblxuIFx0Ly8gTG9hZCBlbnRyeSBtb2R1bGUgYW5kIHJldHVybiBleHBvcnRzXG4gXHRyZXR1cm4gX193ZWJwYWNrX3JlcXVpcmVfXyhfX3dlYnBhY2tfcmVxdWlyZV9fLnMgPSAzMCk7XG5cblxuXG4vLyBXRUJQQUNLIEZPT1RFUiAvL1xuLy8gd2VicGFjay9ib290c3RyYXAgN2Q4MWQxYjgxZjUxMTQ1YjQ1MzMiLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG4vKipcclxuICogU2ltcGxlIERPTSBtYW5pcHVsYXRpb24gYW5kIERPTSBlbGVtZW50IGV2ZW50IGhhbmRsaW5nIG1vZGVsZWQgYWZ0ZXIgalF1ZXJ5IChhcyByZXBsYWNlbWVudCBmb3IgalF1ZXJ5KS5cclxuICpcclxuICogTGlrZSBqUXVlcnksIERPTSBvcGVyYXRlcyBvbiBzaW5nbGUgZWxlbWVudHMgYW5kIGxpc3RzIG9mIGVsZW1lbnRzLiBGb3IgZXhhbXBsZTogY3JlYXRpbmcgYW4gZWxlbWVudCByZXR1cm5zIGEgRE9NXHJcbiAqIGluc3RhbmNlIHdpdGggYSBzaW5nbGUgZWxlbWVudCwgc2VsZWN0aW5nIGVsZW1lbnRzIHJldHVybnMgYSBET00gaW5zdGFuY2Ugd2l0aCB6ZXJvLCBvbmUsIG9yIG1hbnkgZWxlbWVudHMuIFNpbWlsYXJcclxuICogdG8galF1ZXJ5LCBzZXR0ZXJzIHVzdWFsbHkgYWZmZWN0IGFsbCBlbGVtZW50cywgd2hpbGUgZ2V0dGVycyBvcGVyYXRlIG9uIG9ubHkgdGhlIGZpcnN0IGVsZW1lbnQuXHJcbiAqIEFsc28gc2ltaWxhciB0byBqUXVlcnksIG1vc3QgbWV0aG9kcyAoZXhjZXB0IGdldHRlcnMpIHJldHVybiB0aGUgRE9NIGluc3RhbmNlIGZhY2lsaXRhdGluZyBlYXN5IGNoYWluaW5nIG9mIG1ldGhvZFxyXG4gKiBjYWxscy5cclxuICpcclxuICogQnVpbHQgd2l0aCB0aGUgaGVscCBvZjogaHR0cDovL3lvdW1pZ2h0bm90bmVlZGpxdWVyeS5jb20vXHJcbiAqL1xyXG52YXIgRE9NID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIERPTShzb21ldGhpbmcsIGF0dHJpYnV0ZXMpIHtcclxuICAgICAgICB0aGlzLmRvY3VtZW50ID0gZG9jdW1lbnQ7IC8vIFNldCB0aGUgZ2xvYmFsIGRvY3VtZW50IHRvIHRoZSBsb2NhbCBkb2N1bWVudCBmaWVsZFxyXG4gICAgICAgIGlmIChzb21ldGhpbmcgaW5zdGFuY2VvZiBBcnJheSkge1xyXG4gICAgICAgICAgICBpZiAoc29tZXRoaW5nLmxlbmd0aCA+IDAgJiYgc29tZXRoaW5nWzBdIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgIHZhciBlbGVtZW50cyA9IHNvbWV0aGluZztcclxuICAgICAgICAgICAgICAgIHRoaXMuZWxlbWVudHMgPSBlbGVtZW50cztcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChzb21ldGhpbmcgaW5zdGFuY2VvZiBIVE1MRWxlbWVudCkge1xyXG4gICAgICAgICAgICB2YXIgZWxlbWVudCA9IHNvbWV0aGluZztcclxuICAgICAgICAgICAgdGhpcy5lbGVtZW50cyA9IFtlbGVtZW50XTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoc29tZXRoaW5nIGluc3RhbmNlb2YgRG9jdW1lbnQpIHtcclxuICAgICAgICAgICAgLy8gV2hlbiBhIGRvY3VtZW50IGlzIHBhc3NlZCBpbiwgd2UgZG8gbm90IGRvIGFueXRoaW5nIHdpdGggaXQsIGJ1dCBieSBzZXR0aW5nIHRoaXMuZWxlbWVudHMgdG8gbnVsbFxyXG4gICAgICAgICAgICAvLyB3ZSBnaXZlIHRoZSBldmVudCBoYW5kbGluZyBtZXRob2QgYSBtZWFucyB0byBkZXRlY3QgaWYgdGhlIGV2ZW50cyBzaG91bGQgYmUgcmVnaXN0ZXJlZCBvbiB0aGUgZG9jdW1lbnRcclxuICAgICAgICAgICAgLy8gaW5zdGVhZCBvZiBlbGVtZW50cy5cclxuICAgICAgICAgICAgdGhpcy5lbGVtZW50cyA9IG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKGF0dHJpYnV0ZXMpIHtcclxuICAgICAgICAgICAgdmFyIHRhZ05hbWUgPSBzb21ldGhpbmc7XHJcbiAgICAgICAgICAgIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWdOYW1lKTtcclxuICAgICAgICAgICAgZm9yICh2YXIgYXR0cmlidXRlTmFtZSBpbiBhdHRyaWJ1dGVzKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgYXR0cmlidXRlVmFsdWUgPSBhdHRyaWJ1dGVzW2F0dHJpYnV0ZU5hbWVdO1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudC5zZXRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSwgYXR0cmlidXRlVmFsdWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudHMgPSBbZWxlbWVudF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB2YXIgc2VsZWN0b3IgPSBzb21ldGhpbmc7XHJcbiAgICAgICAgICAgIHRoaXMuZWxlbWVudHMgPSB0aGlzLmZpbmRDaGlsZEVsZW1lbnRzKHNlbGVjdG9yKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoRE9NLnByb3RvdHlwZSwgXCJsZW5ndGhcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldHMgdGhlIG51bWJlciBvZiBlbGVtZW50cyB0aGF0IHRoaXMgRE9NIGluc3RhbmNlIGN1cnJlbnRseSBob2xkcy5cclxuICAgICAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRzID8gdGhpcy5lbGVtZW50cy5sZW5ndGggOiAwO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBIVE1MIGVsZW1lbnRzIHRoYXQgdGhpcyBET00gaW5zdGFuY2UgY3VycmVudGx5IGhvbGRzLlxyXG4gICAgICogQHJldHVybnMge0hUTUxFbGVtZW50W119IHRoZSByYXcgSFRNTCBlbGVtZW50c1xyXG4gICAgICogQGRlcHJlY2F0ZWQgdXNlIHtAbGluayAjZ2V0KCl9IGluc3RlYWRcclxuICAgICAqL1xyXG4gICAgRE9NLnByb3RvdHlwZS5nZXRFbGVtZW50cyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXQoKTtcclxuICAgIH07XHJcbiAgICBET00ucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChpbmRleCkge1xyXG4gICAgICAgIGlmIChpbmRleCA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRzO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmICghdGhpcy5lbGVtZW50cyB8fCBpbmRleCA+PSB0aGlzLmVsZW1lbnRzLmxlbmd0aCB8fCBpbmRleCA8IC10aGlzLmVsZW1lbnRzLmxlbmd0aCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChpbmRleCA8IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudHNbdGhpcy5lbGVtZW50cy5sZW5ndGggLSBpbmRleF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50c1tpbmRleF07XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQSBzaG9ydGN1dCBtZXRob2QgZm9yIGl0ZXJhdGluZyBhbGwgZWxlbWVudHMuIFNob3J0cyB0aGlzLmVsZW1lbnRzLmZvckVhY2goLi4uKSB0byB0aGlzLmZvckVhY2goLi4uKS5cclxuICAgICAqIEBwYXJhbSBoYW5kbGVyIHRoZSBoYW5kbGVyIHRvIGV4ZWN1dGUgYW4gb3BlcmF0aW9uIG9uIGFuIGVsZW1lbnRcclxuICAgICAqL1xyXG4gICAgRE9NLnByb3RvdHlwZS5mb3JFYWNoID0gZnVuY3Rpb24gKGhhbmRsZXIpIHtcclxuICAgICAgICBpZiAoIXRoaXMuZWxlbWVudHMpIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgaGFuZGxlcihlbGVtZW50KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBET00ucHJvdG90eXBlLmZpbmRDaGlsZEVsZW1lbnRzT2ZFbGVtZW50ID0gZnVuY3Rpb24gKGVsZW1lbnQsIHNlbGVjdG9yKSB7XHJcbiAgICAgICAgdmFyIGNoaWxkRWxlbWVudHMgPSBlbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpO1xyXG4gICAgICAgIC8vIENvbnZlcnQgTm9kZUxpc3QgdG8gQXJyYXlcclxuICAgICAgICAvLyBodHRwczovL3RvZGRtb3R0by5jb20vYS1jb21wcmVoZW5zaXZlLWRpdmUtaW50by1ub2RlbGlzdHMtYXJyYXlzLWNvbnZlcnRpbmctbm9kZWxpc3RzLWFuZC11bmRlcnN0YW5kaW5nLXRoZS1kb20vXHJcbiAgICAgICAgcmV0dXJuIFtdLnNsaWNlLmNhbGwoY2hpbGRFbGVtZW50cyk7XHJcbiAgICB9O1xyXG4gICAgRE9NLnByb3RvdHlwZS5maW5kQ2hpbGRFbGVtZW50cyA9IGZ1bmN0aW9uIChzZWxlY3Rvcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIGFsbENoaWxkRWxlbWVudHMgPSBbXTtcclxuICAgICAgICBpZiAodGhpcy5lbGVtZW50cykge1xyXG4gICAgICAgICAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgICAgIGFsbENoaWxkRWxlbWVudHMgPSBhbGxDaGlsZEVsZW1lbnRzLmNvbmNhdChfdGhpcy5maW5kQ2hpbGRFbGVtZW50c09mRWxlbWVudChlbGVtZW50LCBzZWxlY3RvcikpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmZpbmRDaGlsZEVsZW1lbnRzT2ZFbGVtZW50KGRvY3VtZW50LCBzZWxlY3Rvcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBhbGxDaGlsZEVsZW1lbnRzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogRmluZHMgYWxsIGNoaWxkIGVsZW1lbnRzIG9mIGFsbCBlbGVtZW50cyBtYXRjaGluZyB0aGUgc3VwcGxpZWQgc2VsZWN0b3IuXHJcbiAgICAgKiBAcGFyYW0gc2VsZWN0b3IgdGhlIHNlbGVjdG9yIHRvIG1hdGNoIHdpdGggY2hpbGQgZWxlbWVudHNcclxuICAgICAqIEByZXR1cm5zIHtET019IGEgbmV3IERPTSBpbnN0YW5jZSByZXByZXNlbnRpbmcgYWxsIG1hdGNoZWQgY2hpbGRyZW5cclxuICAgICAqL1xyXG4gICAgRE9NLnByb3RvdHlwZS5maW5kID0gZnVuY3Rpb24gKHNlbGVjdG9yKSB7XHJcbiAgICAgICAgdmFyIGFsbENoaWxkRWxlbWVudHMgPSB0aGlzLmZpbmRDaGlsZEVsZW1lbnRzKHNlbGVjdG9yKTtcclxuICAgICAgICByZXR1cm4gbmV3IERPTShhbGxDaGlsZEVsZW1lbnRzKTtcclxuICAgIH07XHJcbiAgICBET00ucHJvdG90eXBlLmh0bWwgPSBmdW5jdGlvbiAoY29udGVudCkge1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zZXRIdG1sKGNvbnRlbnQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZ2V0SHRtbCgpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBET00ucHJvdG90eXBlLmdldEh0bWwgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudHNbMF0uaW5uZXJIVE1MO1xyXG4gICAgfTtcclxuICAgIERPTS5wcm90b3R5cGUuc2V0SHRtbCA9IGZ1bmN0aW9uIChjb250ZW50KSB7XHJcbiAgICAgICAgaWYgKGNvbnRlbnQgPT09IHVuZGVmaW5lZCB8fCBjb250ZW50ID09IG51bGwpIHtcclxuICAgICAgICAgICAgLy8gU2V0IHRvIGVtcHR5IHN0cmluZyB0byBhdm9pZCBpbm5lckhUTUwgZ2V0dGluZyBzZXQgdG8gJ3VuZGVmaW5lZCcgKGFsbCBicm93c2Vycykgb3IgJ251bGwnIChJRTkpXHJcbiAgICAgICAgICAgIGNvbnRlbnQgPSAnJztcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gY29udGVudDtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIENsZWFycyB0aGUgaW5uZXIgSFRNTCBvZiBhbGwgZWxlbWVudHMgKGRlbGV0ZXMgYWxsIGNoaWxkcmVuKS5cclxuICAgICAqIEByZXR1cm5zIHtET019XHJcbiAgICAgKi9cclxuICAgIERPTS5wcm90b3R5cGUuZW1wdHkgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gJyc7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBjdXJyZW50IHZhbHVlIG9mIHRoZSBmaXJzdCBmb3JtIGVsZW1lbnQsIGUuZy4gdGhlIHNlbGVjdGVkIHZhbHVlIG9mIGEgc2VsZWN0IGJveCBvciB0aGUgdGV4dCBpZiBhblxyXG4gICAgICogaW5wdXQgZmllbGQuXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSB0aGUgdmFsdWUgb2YgYSBmb3JtIGVsZW1lbnRcclxuICAgICAqL1xyXG4gICAgRE9NLnByb3RvdHlwZS52YWwgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGVsZW1lbnQgPSB0aGlzLmVsZW1lbnRzWzBdO1xyXG4gICAgICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgSFRNTFNlbGVjdEVsZW1lbnQgfHwgZWxlbWVudCBpbnN0YW5jZW9mIEhUTUxJbnB1dEVsZW1lbnQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGVsZW1lbnQudmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBUT0RPIGFkZCBzdXBwb3J0IGZvciBtaXNzaW5nIGZvcm0gZWxlbWVudHNcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidmFsKCkgbm90IHN1cHBvcnRlZCBmb3IgXCIgKyB0eXBlb2YgZWxlbWVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIERPTS5wcm90b3R5cGUuYXR0ciA9IGZ1bmN0aW9uIChhdHRyaWJ1dGUsIHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNldEF0dHIoYXR0cmlidXRlLCB2YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRBdHRyKGF0dHJpYnV0ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIERPTS5wcm90b3R5cGUuZ2V0QXR0ciA9IGZ1bmN0aW9uIChhdHRyaWJ1dGUpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50c1swXS5nZXRBdHRyaWJ1dGUoYXR0cmlidXRlKTtcclxuICAgIH07XHJcbiAgICBET00ucHJvdG90eXBlLnNldEF0dHIgPSBmdW5jdGlvbiAoYXR0cmlidXRlLCB2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZShhdHRyaWJ1dGUsIHZhbHVlKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICBET00ucHJvdG90eXBlLmRhdGEgPSBmdW5jdGlvbiAoZGF0YUF0dHJpYnV0ZSwgdmFsdWUpIHtcclxuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2V0RGF0YShkYXRhQXR0cmlidXRlLCB2YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5nZXREYXRhKGRhdGFBdHRyaWJ1dGUpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBET00ucHJvdG90eXBlLmdldERhdGEgPSBmdW5jdGlvbiAoZGF0YUF0dHJpYnV0ZSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRzWzBdLmdldEF0dHJpYnV0ZSgnZGF0YS0nICsgZGF0YUF0dHJpYnV0ZSk7XHJcbiAgICB9O1xyXG4gICAgRE9NLnByb3RvdHlwZS5zZXREYXRhID0gZnVuY3Rpb24gKGRhdGFBdHRyaWJ1dGUsIHZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdkYXRhLScgKyBkYXRhQXR0cmlidXRlLCB2YWx1ZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBBcHBlbmRzIG9uZSBvciBtb3JlIERPTSBlbGVtZW50cyBhcyBjaGlsZHJlbiB0byBhbGwgZWxlbWVudHMuXHJcbiAgICAgKiBAcGFyYW0gY2hpbGRFbGVtZW50cyB0aGUgY2hyaWxkIGVsZW1lbnRzIHRvIGFwcGVuZFxyXG4gICAgICogQHJldHVybnMge0RPTX1cclxuICAgICAqL1xyXG4gICAgRE9NLnByb3RvdHlwZS5hcHBlbmQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGNoaWxkRWxlbWVudHMgPSBbXTtcclxuICAgICAgICBmb3IgKHZhciBfaSA9IDA7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICBjaGlsZEVsZW1lbnRzW19pXSA9IGFyZ3VtZW50c1tfaV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICBjaGlsZEVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkRWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgY2hpbGRFbGVtZW50LmVsZW1lbnRzLmZvckVhY2goZnVuY3Rpb24gKF8sIGluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZWxlbWVudC5hcHBlbmRDaGlsZChjaGlsZEVsZW1lbnQuZWxlbWVudHNbaW5kZXhdKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJlbW92ZXMgYWxsIGVsZW1lbnRzIGZyb20gdGhlIERPTS5cclxuICAgICAqL1xyXG4gICAgRE9NLnByb3RvdHlwZS5yZW1vdmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIHZhciBwYXJlbnQgPSBlbGVtZW50LnBhcmVudE5vZGU7XHJcbiAgICAgICAgICAgIGlmIChwYXJlbnQpIHtcclxuICAgICAgICAgICAgICAgIHBhcmVudC5yZW1vdmVDaGlsZChlbGVtZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgb2Zmc2V0IG9mIHRoZSBmaXJzdCBlbGVtZW50IGZyb20gdGhlIGRvY3VtZW50J3MgdG9wIGxlZnQgY29ybmVyLlxyXG4gICAgICogQHJldHVybnMge09mZnNldH1cclxuICAgICAqL1xyXG4gICAgRE9NLnByb3RvdHlwZS5vZmZzZXQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGVsZW1lbnQgPSB0aGlzLmVsZW1lbnRzWzBdO1xyXG4gICAgICAgIHZhciBlbGVtZW50UmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICAgICAgdmFyIGh0bWxSZWN0ID0gZG9jdW1lbnQuYm9keS5wYXJlbnRFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xyXG4gICAgICAgIC8vIFZpcnR1YWwgdmlld3BvcnQgc2Nyb2xsIGhhbmRsaW5nIChlLmcuIHBpbmNoIHpvb21lZCB2aWV3cG9ydHMgaW4gbW9iaWxlIGJyb3dzZXJzIG9yIGRlc2t0b3AgQ2hyb21lL0VkZ2UpXHJcbiAgICAgICAgLy8gJ25vcm1hbCcgem9vbXMgYW5kIHZpcnR1YWwgdmlld3BvcnQgem9vbXMgKGFrYSBsYXlvdXQgdmlld3BvcnQpIHJlc3VsdCBpbiBkaWZmZXJlbnRcclxuICAgICAgICAvLyBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIHJlc3VsdHM6XHJcbiAgICAgICAgLy8gIC0gd2l0aCBub3JtYWwgc2Nyb2xscywgdGhlIGNsaWVudFJlY3QgZGVjcmVhc2VzIHdpdGggYW4gaW5jcmVhc2UgaW4gc2Nyb2xsKFRvcHxMZWZ0KS9wYWdlKFh8WSlPZmZzZXRcclxuICAgICAgICAvLyAgLSB3aXRoIHBpbmNoIHpvb20gc2Nyb2xscywgdGhlIGNsaWVudFJlY3Qgc3RheXMgdGhlIHNhbWUgd2hpbGUgc2Nyb2xsL3BhZ2VPZmZzZXQgY2hhbmdlc1xyXG4gICAgICAgIC8vIFRoaXMgbWVhbnMsIHRoYXQgdGhlIGNvbWJpbmF0aW9uIG9mIGNsaWVudFJlY3QgKyBzY3JvbGwvcGFnZU9mZnNldCBkb2VzIG5vdCB3b3JrIHRvIGNhbGN1bGF0ZSB0aGUgb2Zmc2V0XHJcbiAgICAgICAgLy8gZnJvbSB0aGUgZG9jdW1lbnQncyB1cHBlciBsZWZ0IG9yaWdpbiB3aGVuIHBpbmNoIHpvb20gaXMgdXNlZC5cclxuICAgICAgICAvLyBUbyB3b3JrIGFyb3VuZCB0aGlzIGlzc3VlLCB3ZSBkbyBub3QgdXNlIHNjcm9sbC9wYWdlT2Zmc2V0IGJ1dCBnZXQgdGhlIGNsaWVudFJlY3Qgb2YgdGhlIGh0bWwgZWxlbWVudCBhbmRcclxuICAgICAgICAvLyBzdWJ0cmFjdCBpdCBmcm9tIHRoZSBlbGVtZW50J3MgcmVjdCwgd2hpY2ggYWx3YXlzIHJlc3VsdHMgaW4gdGhlIG9mZnNldCBmcm9tIHRoZSBkb2N1bWVudCBvcmlnaW4uXHJcbiAgICAgICAgLy8gTk9URTogdGhlIGN1cnJlbnQgd2F5IG9mIG9mZnNldCBjYWxjdWxhdGlvbiB3YXMgaW1wbGVtZW50ZWQgc3BlY2lmaWNhbGx5IHRvIHRyYWNrIGV2ZW50IHBvc2l0aW9ucyBvbiB0aGVcclxuICAgICAgICAvLyBzZWVrIGJhciwgYW5kIGl0IG1pZ2h0IGJyZWFrIGNvbXBhdGliaWxpdHkgd2l0aCBqUXVlcnkncyBvZmZzZXQoKSBtZXRob2QuIElmIHRoaXMgZXZlciB0dXJucyBvdXQgdG8gYmUgYVxyXG4gICAgICAgIC8vIHByb2JsZW0sIHRoaXMgbWV0aG9kIHNob3VsZCBiZSByZXZlcnRlZCB0byB0aGUgb2xkIHZlcnNpb24gYW5kIHRoZSBvZmZzZXQgY2FsY3VsYXRpb24gbW92ZWQgdG8gdGhlIHNlZWsgYmFyLlxyXG4gICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgIHRvcDogZWxlbWVudFJlY3QudG9wIC0gaHRtbFJlY3QudG9wLFxyXG4gICAgICAgICAgICBsZWZ0OiBlbGVtZW50UmVjdC5sZWZ0IC0gaHRtbFJlY3QubGVmdCxcclxuICAgICAgICB9O1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgd2lkdGggb2YgdGhlIGZpcnN0IGVsZW1lbnQuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSB0aGUgd2lkdGggb2YgdGhlIGZpcnN0IGVsZW1lbnRcclxuICAgICAqL1xyXG4gICAgRE9NLnByb3RvdHlwZS53aWR0aCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBUT0RPIGNoZWNrIGlmIHRoaXMgaXMgdGhlIHNhbWUgYXMgalF1ZXJ5J3Mgd2lkdGgoKSAocHJvYmFibHkgbm90KVxyXG4gICAgICAgIHJldHVybiB0aGlzLmVsZW1lbnRzWzBdLm9mZnNldFdpZHRoO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgaGVpZ2h0IG9mIHRoZSBmaXJzdCBlbGVtZW50LlxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gdGhlIGhlaWdodCBvZiB0aGUgZmlyc3QgZWxlbWVudFxyXG4gICAgICovXHJcbiAgICBET00ucHJvdG90eXBlLmhlaWdodCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBUT0RPIGNoZWNrIGlmIHRoaXMgaXMgdGhlIHNhbWUgYXMgalF1ZXJ5J3MgaGVpZ2h0KCkgKHByb2JhYmx5IG5vdClcclxuICAgICAgICByZXR1cm4gdGhpcy5lbGVtZW50c1swXS5vZmZzZXRIZWlnaHQ7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBBdHRhY2hlcyBhbiBldmVudCBoYW5kbGVyIHRvIG9uZSBvciBtb3JlIGV2ZW50cyBvbiBhbGwgZWxlbWVudHMuXHJcbiAgICAgKiBAcGFyYW0gZXZlbnROYW1lIHRoZSBldmVudCBuYW1lIChvciBtdWx0aXBsZSBuYW1lcyBzZXBhcmF0ZWQgYnkgc3BhY2UpIHRvIGxpc3RlbiB0b1xyXG4gICAgICogQHBhcmFtIGV2ZW50SGFuZGxlciB0aGUgZXZlbnQgaGFuZGxlciB0byBjYWxsIHdoZW4gdGhlIGV2ZW50IGZpcmVzXHJcbiAgICAgKiBAcmV0dXJucyB7RE9NfVxyXG4gICAgICovXHJcbiAgICBET00ucHJvdG90eXBlLm9uID0gZnVuY3Rpb24gKGV2ZW50TmFtZSwgZXZlbnRIYW5kbGVyKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2YXIgZXZlbnRzID0gZXZlbnROYW1lLnNwbGl0KCcgJyk7XHJcbiAgICAgICAgZXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgIGlmIChfdGhpcy5lbGVtZW50cyA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBldmVudEhhbmRsZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgZXZlbnRIYW5kbGVyKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIGFuIGV2ZW50IGhhbmRsZXIgZnJvbSBvbmUgb3IgbW9yZSBldmVudHMgb24gYWxsIGVsZW1lbnRzLlxyXG4gICAgICogQHBhcmFtIGV2ZW50TmFtZSB0aGUgZXZlbnQgbmFtZSAob3IgbXVsdGlwbGUgbmFtZXMgc2VwYXJhdGVkIGJ5IHNwYWNlKSB0byByZW1vdmUgdGhlIGhhbmRsZXIgZnJvbVxyXG4gICAgICogQHBhcmFtIGV2ZW50SGFuZGxlciB0aGUgZXZlbnQgaGFuZGxlciB0byByZW1vdmVcclxuICAgICAqIEByZXR1cm5zIHtET019XHJcbiAgICAgKi9cclxuICAgIERPTS5wcm90b3R5cGUub2ZmID0gZnVuY3Rpb24gKGV2ZW50TmFtZSwgZXZlbnRIYW5kbGVyKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2YXIgZXZlbnRzID0gZXZlbnROYW1lLnNwbGl0KCcgJyk7XHJcbiAgICAgICAgZXZlbnRzLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgIGlmIChfdGhpcy5lbGVtZW50cyA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBldmVudEhhbmRsZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgZXZlbnRIYW5kbGVyKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBBZGRzIHRoZSBzcGVjaWZpZWQgY2xhc3MoZXMpIHRvIGFsbCBlbGVtZW50cy5cclxuICAgICAqIEBwYXJhbSBjbGFzc05hbWUgdGhlIGNsYXNzKGVzKSB0byBhZGQsIG11bHRpcGxlIGNsYXNzZXMgc2VwYXJhdGVkIGJ5IHNwYWNlXHJcbiAgICAgKiBAcmV0dXJucyB7RE9NfVxyXG4gICAgICovXHJcbiAgICBET00ucHJvdG90eXBlLmFkZENsYXNzID0gZnVuY3Rpb24gKGNsYXNzTmFtZSkge1xyXG4gICAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICBpZiAoZWxlbWVudC5jbGFzc0xpc3QpIHtcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQuY2xhc3NMaXN0LmFkZChjbGFzc05hbWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudC5jbGFzc05hbWUgKz0gJyAnICsgY2xhc3NOYW1lO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIHRoaXM7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVkIHRoZSBzcGVjaWZpZWQgY2xhc3MoZXMpIGZyb20gYWxsIGVsZW1lbnRzLlxyXG4gICAgICogQHBhcmFtIGNsYXNzTmFtZSB0aGUgY2xhc3MoZXMpIHRvIHJlbW92ZSwgbXVsdGlwbGUgY2xhc3NlcyBzZXBhcmF0ZWQgYnkgc3BhY2VcclxuICAgICAqIEByZXR1cm5zIHtET019XHJcbiAgICAgKi9cclxuICAgIERPTS5wcm90b3R5cGUucmVtb3ZlQ2xhc3MgPSBmdW5jdGlvbiAoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIGlmIChlbGVtZW50LmNsYXNzTGlzdCkge1xyXG4gICAgICAgICAgICAgICAgZWxlbWVudC5jbGFzc0xpc3QucmVtb3ZlKGNsYXNzTmFtZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBlbGVtZW50LmNsYXNzTmFtZSA9IGVsZW1lbnQuY2xhc3NOYW1lLnJlcGxhY2UobmV3IFJlZ0V4cCgnKF58XFxcXGIpJyArIGNsYXNzTmFtZS5zcGxpdCgnICcpLmpvaW4oJ3wnKSArICcoXFxcXGJ8JCknLCAnZ2knKSwgJyAnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiB0aGlzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQ2hlY2tzIGlmIGFueSBvZiB0aGUgZWxlbWVudHMgaGFzIHRoZSBzcGVjaWZpZWQgY2xhc3MuXHJcbiAgICAgKiBAcGFyYW0gY2xhc3NOYW1lIHRoZSBjbGFzcyBuYW1lIHRvIGNoZWNrXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiBvbmUgb2YgdGhlIGVsZW1lbnRzIGhhcyB0aGUgY2xhc3MgYXR0YWNoZWQsIGVsc2UgaWYgbm8gZWxlbWVudCBoYXMgaXQgYXR0YWNoZWRcclxuICAgICAqL1xyXG4gICAgRE9NLnByb3RvdHlwZS5oYXNDbGFzcyA9IGZ1bmN0aW9uIChjbGFzc05hbWUpIHtcclxuICAgICAgICB2YXIgaGFzQ2xhc3MgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLmZvckVhY2goZnVuY3Rpb24gKGVsZW1lbnQpIHtcclxuICAgICAgICAgICAgaWYgKGVsZW1lbnQuY2xhc3NMaXN0KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoZWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoY2xhc3NOYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIFNpbmNlIHdlIGFyZSBpbnNpZGUgYSBoYW5kbGVyLCB3ZSBjYW4ndCBqdXN0ICdyZXR1cm4gdHJ1ZScuIEluc3RlYWQsIHdlIHNhdmUgaXQgdG8gYSB2YXJpYWJsZVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGFuZCByZXR1cm4gaXQgYXQgdGhlIGVuZCBvZiB0aGUgZnVuY3Rpb24gYm9keS5cclxuICAgICAgICAgICAgICAgICAgICBoYXNDbGFzcyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBpZiAobmV3IFJlZ0V4cCgnKF58ICknICsgY2xhc3NOYW1lICsgJyggfCQpJywgJ2dpJykudGVzdChlbGVtZW50LmNsYXNzTmFtZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBTZWUgY29tbWVudCBhYm92ZVxyXG4gICAgICAgICAgICAgICAgICAgIGhhc0NsYXNzID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiBoYXNDbGFzcztcclxuICAgIH07XHJcbiAgICBET00ucHJvdG90eXBlLmNzcyA9IGZ1bmN0aW9uIChwcm9wZXJ0eU5hbWVPckNvbGxlY3Rpb24sIHZhbHVlKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBwcm9wZXJ0eU5hbWVPckNvbGxlY3Rpb24gPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgIHZhciBwcm9wZXJ0eU5hbWUgPSBwcm9wZXJ0eU5hbWVPckNvbGxlY3Rpb247XHJcbiAgICAgICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5zZXRDc3MocHJvcGVydHlOYW1lLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRDc3MocHJvcGVydHlOYW1lKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdmFyIHByb3BlcnR5VmFsdWVDb2xsZWN0aW9uID0gcHJvcGVydHlOYW1lT3JDb2xsZWN0aW9uO1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zZXRDc3NDb2xsZWN0aW9uKHByb3BlcnR5VmFsdWVDb2xsZWN0aW9uKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgRE9NLnByb3RvdHlwZS5nZXRDc3MgPSBmdW5jdGlvbiAocHJvcGVydHlOYW1lKSB7XHJcbiAgICAgICAgcmV0dXJuIGdldENvbXB1dGVkU3R5bGUodGhpcy5lbGVtZW50c1swXSlbcHJvcGVydHlOYW1lXTtcclxuICAgIH07XHJcbiAgICBET00ucHJvdG90eXBlLnNldENzcyA9IGZ1bmN0aW9uIChwcm9wZXJ0eU5hbWUsIHZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy5mb3JFYWNoKGZ1bmN0aW9uIChlbGVtZW50KSB7XHJcbiAgICAgICAgICAgIC8vIDxhbnk+IGNhc3QgdG8gcmVzb2x2ZSBUUzcwMTU6IGh0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9hLzM2NjI3MTE0LzM3MDI1MlxyXG4gICAgICAgICAgICBlbGVtZW50LnN0eWxlW3Byb3BlcnR5TmFtZV0gPSB2YWx1ZTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICBET00ucHJvdG90eXBlLnNldENzc0NvbGxlY3Rpb24gPSBmdW5jdGlvbiAocnVsZVZhbHVlQ29sbGVjdGlvbikge1xyXG4gICAgICAgIHRoaXMuZm9yRWFjaChmdW5jdGlvbiAoZWxlbWVudCkge1xyXG4gICAgICAgICAgICAvLyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8zNDQ5MDU3My8zNzAyNTJcclxuICAgICAgICAgICAgT2JqZWN0LmFzc2lnbihlbGVtZW50LnN0eWxlLCBydWxlVmFsdWVDb2xsZWN0aW9uKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICByZXR1cm4gRE9NO1xyXG59KCkpO1xyXG5leHBvcnRzLkRPTSA9IERPTTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9kb20udHNcbi8vIG1vZHVsZSBpZCA9IDBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBjb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudFwiKTtcclxudmFyIGRvbV8xID0gcmVxdWlyZShcIi4uL2RvbVwiKTtcclxudmFyIGFycmF5dXRpbHNfMSA9IHJlcXVpcmUoXCIuLi9hcnJheXV0aWxzXCIpO1xyXG4vKipcclxuICogQSBjb250YWluZXIgY29tcG9uZW50IHRoYXQgY2FuIGNvbnRhaW4gYSBjb2xsZWN0aW9uIG9mIGNoaWxkIGNvbXBvbmVudHMuXHJcbiAqIENvbXBvbmVudHMgY2FuIGJlIGFkZGVkIGF0IGNvbnN0cnVjdGlvbiB0aW1lIHRocm91Z2ggdGhlIHtAbGluayBDb250YWluZXJDb25maWcjY29tcG9uZW50c30gc2V0dGluZywgb3IgbGF0ZXJcclxuICogdGhyb3VnaCB0aGUge0BsaW5rIENvbnRhaW5lciNhZGRDb21wb25lbnR9IG1ldGhvZC4gVGhlIFVJTWFuYWdlciBhdXRvbWF0aWNhbGx5IHRha2VzIGNhcmUgb2YgYWxsIGNvbXBvbmVudHMsIGkuZS4gaXRcclxuICogaW5pdGlhbGl6ZXMgYW5kIGNvbmZpZ3VyZXMgdGhlbSBhdXRvbWF0aWNhbGx5LlxyXG4gKlxyXG4gKiBJbiB0aGUgRE9NLCB0aGUgY29udGFpbmVyIGNvbnNpc3RzIG9mIGFuIG91dGVyIDxkaXY+ICh0aGF0IGNhbiBiZSBjb25maWd1cmVkIGJ5IHRoZSBjb25maWcpIGFuZCBhbiBpbm5lciB3cmFwcGVyXHJcbiAqIDxkaXY+IHRoYXQgY29udGFpbnMgdGhlIGNvbXBvbmVudHMuIFRoaXMgZG91YmxlLTxkaXY+LXN0cnVjdHVyZSBpcyBvZnRlbiByZXF1aXJlZCB0byBhY2hpZXZlIG1hbnkgYWR2YW5jZWQgZWZmZWN0c1xyXG4gKiBpbiBDU1MgYW5kL29yIEpTLCBlLmcuIGFuaW1hdGlvbnMgYW5kIGNlcnRhaW4gZm9ybWF0dGluZyB3aXRoIGFic29sdXRlIHBvc2l0aW9uaW5nLlxyXG4gKlxyXG4gKiBET00gZXhhbXBsZTpcclxuICogPGNvZGU+XHJcbiAqICAgICA8ZGl2IGNsYXNzPSd1aS1jb250YWluZXInPlxyXG4gKiAgICAgICAgIDxkaXYgY2xhc3M9J2NvbnRhaW5lci13cmFwcGVyJz5cclxuICogICAgICAgICAgICAgLi4uIGNoaWxkIGNvbXBvbmVudHMgLi4uXHJcbiAqICAgICAgICAgPC9kaXY+XHJcbiAqICAgICA8L2Rpdj5cclxuICogPC9jb2RlPlxyXG4gKi9cclxudmFyIENvbnRhaW5lciA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoQ29udGFpbmVyLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gQ29udGFpbmVyKGNvbmZpZykge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1jb250YWluZXInLFxyXG4gICAgICAgICAgICBjb21wb25lbnRzOiBbXSxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIF90aGlzLmNvbXBvbmVudHNUb0FkZCA9IFtdO1xyXG4gICAgICAgIF90aGlzLmNvbXBvbmVudHNUb1JlbW92ZSA9IFtdO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBhIGNoaWxkIGNvbXBvbmVudCB0byB0aGUgY29udGFpbmVyLlxyXG4gICAgICogQHBhcmFtIGNvbXBvbmVudCB0aGUgY29tcG9uZW50IHRvIGFkZFxyXG4gICAgICovXHJcbiAgICBDb250YWluZXIucHJvdG90eXBlLmFkZENvbXBvbmVudCA9IGZ1bmN0aW9uIChjb21wb25lbnQpIHtcclxuICAgICAgICB0aGlzLmNvbmZpZy5jb21wb25lbnRzLnB1c2goY29tcG9uZW50KTtcclxuICAgICAgICB0aGlzLmNvbXBvbmVudHNUb0FkZC5wdXNoKGNvbXBvbmVudCk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIGEgY2hpbGQgY29tcG9uZW50IGZyb20gdGhlIGNvbnRhaW5lci5cclxuICAgICAqIEBwYXJhbSBjb21wb25lbnQgdGhlIGNvbXBvbmVudCB0byByZW1vdmVcclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlIGlmIHRoZSBjb21wb25lbnQgaGFzIGJlZW4gcmVtb3ZlZCwgZmFsc2UgaWYgaXQgaXMgbm90IGNvbnRhaW5lZCBpbiB0aGlzIGNvbnRhaW5lclxyXG4gICAgICovXHJcbiAgICBDb250YWluZXIucHJvdG90eXBlLnJlbW92ZUNvbXBvbmVudCA9IGZ1bmN0aW9uIChjb21wb25lbnQpIHtcclxuICAgICAgICBpZiAoYXJyYXl1dGlsc18xLkFycmF5VXRpbHMucmVtb3ZlKHRoaXMuY29uZmlnLmNvbXBvbmVudHMsIGNvbXBvbmVudCkgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICB0aGlzLmNvbXBvbmVudHNUb1JlbW92ZS5wdXNoKGNvbXBvbmVudCk7XHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEdldHMgYW4gYXJyYXkgb2YgYWxsIGNoaWxkIGNvbXBvbmVudHMgaW4gdGhpcyBjb250YWluZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7Q29tcG9uZW50PENvbXBvbmVudENvbmZpZz5bXX1cclxuICAgICAqL1xyXG4gICAgQ29udGFpbmVyLnByb3RvdHlwZS5nZXRDb21wb25lbnRzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5jb21wb25lbnRzO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmVtb3ZlcyBhbGwgY2hpbGQgY29tcG9uZW50cyBmcm9tIHRoZSBjb250YWluZXIuXHJcbiAgICAgKi9cclxuICAgIENvbnRhaW5lci5wcm90b3R5cGUucmVtb3ZlQ29tcG9uZW50cyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdGhpcy5nZXRDb21wb25lbnRzKCkuc2xpY2UoKTsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgdmFyIGNvbXBvbmVudCA9IF9hW19pXTtcclxuICAgICAgICAgICAgdGhpcy5yZW1vdmVDb21wb25lbnQoY29tcG9uZW50KTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBVcGRhdGVzIHRoZSBET00gb2YgdGhlIGNvbnRhaW5lciB3aXRoIHRoZSBjdXJyZW50IGNvbXBvbmVudHMuXHJcbiAgICAgKi9cclxuICAgIENvbnRhaW5lci5wcm90b3R5cGUudXBkYXRlQ29tcG9uZW50cyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvKiBXZSBjYW5ub3QganVzdCBjbGVhciB0aGUgY29udGFpbmVyIHRvIHJlbW92ZSBhbGwgZWxlbWVudHMgYW5kIHRoZW4gcmUtYWRkIHRob3NlIHRoYXQgc2hvdWxkIHN0YXksIGJlY2F1c2VcclxuICAgICAgICAgKiBJRSBsb29zZXMgdGhlIGlubmVySFRNTCBvZiB1bmF0dGFjaGVkIGVsZW1lbnRzLCBsZWFkaW5nIHRvIGVtcHR5IGVsZW1lbnRzIHdpdGhpbiB0aGUgY29udGFpbmVyIChlLmcuIG1pc3NpbmdcclxuICAgICAgICAgKiBzdWJ0aXRsZSB0ZXh0IGluIFN1YnRpdGxlTGFiZWwpLlxyXG4gICAgICAgICAqIEluc3RlYWQsIHdlIGtlZXAgYSBsaXN0IG9mIGVsZW1lbnRzIHRvIGFkZCBhbmQgcmVtb3ZlLCBsZWF2aW5nIHJlbWFpbmluZyBlbGVtZW50cyBhbG9uZS4gQnkga2VlcGluZyB0aGVtIGluXHJcbiAgICAgICAgICogdGhlIERPTSwgdGhlaXIgY29udGVudCBnZXRzIHByZXNlcnZlZCBpbiBhbGwgYnJvd3NlcnMuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgdmFyIGNvbXBvbmVudDtcclxuICAgICAgICB3aGlsZSAoY29tcG9uZW50ID0gdGhpcy5jb21wb25lbnRzVG9SZW1vdmUuc2hpZnQoKSkge1xyXG4gICAgICAgICAgICBjb21wb25lbnQuZ2V0RG9tRWxlbWVudCgpLnJlbW92ZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB3aGlsZSAoY29tcG9uZW50ID0gdGhpcy5jb21wb25lbnRzVG9BZGQuc2hpZnQoKSkge1xyXG4gICAgICAgICAgICB0aGlzLmlubmVyQ29udGFpbmVyRWxlbWVudC5hcHBlbmQoY29tcG9uZW50LmdldERvbUVsZW1lbnQoKSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIENvbnRhaW5lci5wcm90b3R5cGUudG9Eb21FbGVtZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIENyZWF0ZSB0aGUgY29udGFpbmVyIGVsZW1lbnQgKHRoZSBvdXRlciA8ZGl2PilcclxuICAgICAgICB2YXIgY29udGFpbmVyRWxlbWVudCA9IG5ldyBkb21fMS5ET00odGhpcy5jb25maWcudGFnLCB7XHJcbiAgICAgICAgICAgICdpZCc6IHRoaXMuY29uZmlnLmlkLFxyXG4gICAgICAgICAgICAnY2xhc3MnOiB0aGlzLmdldENzc0NsYXNzZXMoKSxcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBDcmVhdGUgdGhlIGlubmVyIGNvbnRhaW5lciBlbGVtZW50ICh0aGUgaW5uZXIgPGRpdj4pIHRoYXQgd2lsbCBjb250YWluIHRoZSBjb21wb25lbnRzXHJcbiAgICAgICAgdmFyIGlubmVyQ29udGFpbmVyID0gbmV3IGRvbV8xLkRPTSh0aGlzLmNvbmZpZy50YWcsIHtcclxuICAgICAgICAgICAgJ2NsYXNzJzogdGhpcy5wcmVmaXhDc3MoJ2NvbnRhaW5lci13cmFwcGVyJyksXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5pbm5lckNvbnRhaW5lckVsZW1lbnQgPSBpbm5lckNvbnRhaW5lcjtcclxuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdGhpcy5jb25maWcuY29tcG9uZW50czsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgdmFyIGluaXRpYWxDb21wb25lbnQgPSBfYVtfaV07XHJcbiAgICAgICAgICAgIHRoaXMuY29tcG9uZW50c1RvQWRkLnB1c2goaW5pdGlhbENvbXBvbmVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMudXBkYXRlQ29tcG9uZW50cygpO1xyXG4gICAgICAgIGNvbnRhaW5lckVsZW1lbnQuYXBwZW5kKGlubmVyQ29udGFpbmVyKTtcclxuICAgICAgICByZXR1cm4gY29udGFpbmVyRWxlbWVudDtcclxuICAgIH07XHJcbiAgICByZXR1cm4gQ29udGFpbmVyO1xyXG59KGNvbXBvbmVudF8xLkNvbXBvbmVudCkpO1xyXG5leHBvcnRzLkNvbnRhaW5lciA9IENvbnRhaW5lcjtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2NvbnRhaW5lci50c1xuLy8gbW9kdWxlIGlkID0gMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgZ3VpZF8xID0gcmVxdWlyZShcIi4uL2d1aWRcIik7XHJcbnZhciBkb21fMSA9IHJlcXVpcmUoXCIuLi9kb21cIik7XHJcbnZhciBldmVudGRpc3BhdGNoZXJfMSA9IHJlcXVpcmUoXCIuLi9ldmVudGRpc3BhdGNoZXJcIik7XHJcbi8qKlxyXG4gKiBUaGUgYmFzZSBjbGFzcyBvZiB0aGUgVUkgZnJhbWV3b3JrLlxyXG4gKiBFYWNoIGNvbXBvbmVudCBtdXN0IGV4dGVuZCB0aGlzIGNsYXNzIGFuZCBvcHRpb25hbGx5IHRoZSBjb25maWcgaW50ZXJmYWNlLlxyXG4gKi9cclxudmFyIENvbXBvbmVudCA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAvKipcclxuICAgICAqIENvbnN0cnVjdHMgYSBjb21wb25lbnQgd2l0aCBhbiBvcHRpb25hbGx5IHN1cHBsaWVkIGNvbmZpZy4gQWxsIHN1YmNsYXNzZXMgbXVzdCBjYWxsIHRoZSBjb25zdHJ1Y3RvciBvZiB0aGVpclxyXG4gICAgICogc3VwZXJjbGFzcyBhbmQgdGhlbiBtZXJnZSB0aGVpciBjb25maWd1cmF0aW9uIGludG8gdGhlIGNvbXBvbmVudCdzIGNvbmZpZ3VyYXRpb24uXHJcbiAgICAgKiBAcGFyYW0gY29uZmlnIHRoZSBjb25maWd1cmF0aW9uIGZvciB0aGUgY29tcG9uZW50XHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIENvbXBvbmVudChjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBUaGUgbGlzdCBvZiBldmVudHMgdGhhdCB0aGlzIGNvbXBvbmVudCBvZmZlcnMuIFRoZXNlIGV2ZW50cyBzaG91bGQgYWx3YXlzIGJlIHByaXZhdGUgYW5kIG9ubHkgZGlyZWN0bHlcclxuICAgICAgICAgKiBhY2Nlc3NlZCBmcm9tIHdpdGhpbiB0aGUgaW1wbGVtZW50aW5nIGNvbXBvbmVudC5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIEJlY2F1c2UgVHlwZVNjcmlwdCBkb2VzIG5vdCBzdXBwb3J0IHByaXZhdGUgcHJvcGVydGllcyB3aXRoIHRoZSBzYW1lIG5hbWUgb24gZGlmZmVyZW50IGNsYXNzIGhpZXJhcmNoeSBsZXZlbHNcclxuICAgICAgICAgKiAoaS5lLiBzdXBlcmNsYXNzIGFuZCBzdWJjbGFzcyBjYW5ub3QgY29udGFpbiBhIHByaXZhdGUgcHJvcGVydHkgd2l0aCB0aGUgc2FtZSBuYW1lKSwgdGhlIGRlZmF1bHQgbmFtaW5nXHJcbiAgICAgICAgICogY29udmVudGlvbiBmb3IgdGhlIGV2ZW50IGxpc3Qgb2YgYSBjb21wb25lbnQgdGhhdCBzaG91bGQgYmUgZm9sbG93ZWQgYnkgc3ViY2xhc3NlcyBpcyB0aGUgY29uY2F0ZW5hdGlvbiBvZiB0aGVcclxuICAgICAgICAgKiBjYW1lbC1jYXNlZCBjbGFzcyBuYW1lICsgJ0V2ZW50cycgKGUuZy4gU3ViQ2xhc3MgZXh0ZW5kcyBDb21wb25lbnQgPT4gc3ViQ2xhc3NFdmVudHMpLlxyXG4gICAgICAgICAqIFNlZSB7QGxpbmsgI2NvbXBvbmVudEV2ZW50c30gZm9yIGFuIGV4YW1wbGUuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBFdmVudCBwcm9wZXJ0aWVzIHNob3VsZCBiZSBuYW1lZCBpbiBjYW1lbCBjYXNlIHdpdGggYW4gJ29uJyBwcmVmaXggYW5kIGluIHRoZSBwcmVzZW50IHRlbnNlLiBBc3luYyBldmVudHMgbWF5XHJcbiAgICAgICAgICogaGF2ZSBhIHN0YXJ0IGV2ZW50ICh3aGVuIHRoZSBvcGVyYXRpb24gc3RhcnRzKSBpbiB0aGUgcHJlc2VudCB0ZW5zZSwgYW5kIG11c3QgaGF2ZSBhbiBlbmQgZXZlbnQgKHdoZW4gdGhlXHJcbiAgICAgICAgICogb3BlcmF0aW9uIGVuZHMpIGluIHRoZSBwYXN0IHRlbnNlIChvciBwcmVzZW50IHRlbnNlIGluIHNwZWNpYWwgY2FzZXMgKGUuZy4gb25TdGFydC9vblN0YXJ0ZWQgb3Igb25QbGF5L29uUGxheWluZykuXHJcbiAgICAgICAgICogU2VlIHtAbGluayAjY29tcG9uZW50RXZlbnRzI29uU2hvd30gZm9yIGFuIGV4YW1wbGUuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBFYWNoIGV2ZW50IHNob3VsZCBiZSBhY2NvbXBhbmllZCB3aXRoIGEgcHJvdGVjdGVkIG1ldGhvZCBuYW1lZCBieSB0aGUgY29udmVudGlvbiBldmVudE5hbWUgKyAnRXZlbnQnXHJcbiAgICAgICAgICogKGUuZy4gb25TdGFydEV2ZW50KSwgdGhhdCBhY3R1YWxseSB0cmlnZ2VycyB0aGUgZXZlbnQgYnkgY2FsbGluZyB7QGxpbmsgRXZlbnREaXNwYXRjaGVyI2Rpc3BhdGNoIGRpc3BhdGNofSBhbmRcclxuICAgICAgICAgKiBwYXNzaW5nIGEgcmVmZXJlbmNlIHRvIHRoZSBjb21wb25lbnQgYXMgZmlyc3QgcGFyYW1ldGVyLiBDb21wb25lbnRzIHNob3VsZCBhbHdheXMgdHJpZ2dlciB0aGVpciBldmVudHMgd2l0aCB0aGVzZVxyXG4gICAgICAgICAqIG1ldGhvZHMuIEltcGxlbWVudGluZyB0aGlzIHBhdHRlcm4gZ2l2ZXMgc3ViY2xhc3NlcyBtZWFucyB0byBkaXJlY3RseSBsaXN0ZW4gdG8gdGhlIGV2ZW50cyBieSBvdmVycmlkaW5nIHRoZVxyXG4gICAgICAgICAqIG1ldGhvZCAoYW5kIHNhdmluZyB0aGUgb3ZlcmhlYWQgb2YgcGFzc2luZyBhIGhhbmRsZXIgdG8gdGhlIGV2ZW50IGRpc3BhdGNoZXIpIGFuZCBtb3JlIGltcG9ydGFudGx5IHRvIHRyaWdnZXJcclxuICAgICAgICAgKiB0aGVzZSBldmVudHMgd2l0aG91dCBoYXZpbmcgYWNjZXNzIHRvIHRoZSBwcml2YXRlIGV2ZW50IGxpc3QuXHJcbiAgICAgICAgICogU2VlIHtAbGluayAjb25TaG93fSBmb3IgYW4gZXhhbXBsZS5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIFRvIHByb3ZpZGUgZXh0ZXJuYWwgY29kZSB0aGUgcG9zc2liaWxpdHkgdG8gbGlzdGVuIHRvIHRoaXMgY29tcG9uZW50J3MgZXZlbnRzIChzdWJzY3JpYmUsIHVuc3Vic2NyaWJlLCBldGMuKSxcclxuICAgICAgICAgKiBlYWNoIGV2ZW50IHNob3VsZCBhbHNvIGJlIGFjY29tcGFuaWVkIGJ5IGEgcHVibGljIGdldHRlciBmdW5jdGlvbiB3aXRoIHRoZSBzYW1lIG5hbWUgYXMgdGhlIGV2ZW50J3MgcHJvcGVydHksXHJcbiAgICAgICAgICogdGhhdCByZXR1cm5zIHRoZSB7QGxpbmsgRXZlbnR9IG9idGFpbmVkIGZyb20gdGhlIGV2ZW50IGRpc3BhdGNoZXIgYnkgY2FsbGluZyB7QGxpbmsgRXZlbnREaXNwYXRjaGVyI2dldEV2ZW50fS5cclxuICAgICAgICAgKiBTZWUge0BsaW5rICNvblNob3d9IGZvciBhbiBleGFtcGxlLlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogRnVsbCBleGFtcGxlIGZvciBhbiBldmVudCByZXByZXNlbnRpbmcgYW4gZXhhbXBsZSBhY3Rpb24gaW4gYSBleGFtcGxlIGNvbXBvbmVudDpcclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIDxjb2RlPlxyXG4gICAgICAgICAqIC8vIERlZmluZSBhbiBleGFtcGxlIGNvbXBvbmVudCBjbGFzcyB3aXRoIGFuIGV4YW1wbGUgZXZlbnRcclxuICAgICAgICAgKiBjbGFzcyBFeGFtcGxlQ29tcG9uZW50IGV4dGVuZHMgQ29tcG9uZW50PENvbXBvbmVudENvbmZpZz4ge1xyXG4gICAgICAgICAgICpcclxuICAgICAgICAgICAqICAgICBwcml2YXRlIGV4YW1wbGVDb21wb25lbnRFdmVudHMgPSB7XHJcbiAgICAgICAgICAgKiAgICAgICAgIG9uRXhhbXBsZUFjdGlvbjogbmV3IEV2ZW50RGlzcGF0Y2hlcjxFeGFtcGxlQ29tcG9uZW50LCBOb0FyZ3M+KClcclxuICAgICAgICAgICAqICAgICB9XHJcbiAgICAgICAgICAgKlxyXG4gICAgICAgICAgICogICAgIC8vIGNvbnN0cnVjdG9yIGFuZCBvdGhlciBzdHVmZi4uLlxyXG4gICAgICAgICAgICpcclxuICAgICAgICAgICAqICAgICBwcm90ZWN0ZWQgb25FeGFtcGxlQWN0aW9uRXZlbnQoKSB7XHJcbiAgICAgICAgICAgKiAgICAgICAgdGhpcy5leGFtcGxlQ29tcG9uZW50RXZlbnRzLm9uRXhhbXBsZUFjdGlvbi5kaXNwYXRjaCh0aGlzKTtcclxuICAgICAgICAgICAqICAgIH1cclxuICAgICAgICAgICAqXHJcbiAgICAgICAgICAgKiAgICBnZXQgb25FeGFtcGxlQWN0aW9uKCk6IEV2ZW50PEV4YW1wbGVDb21wb25lbnQsIE5vQXJncz4ge1xyXG4gICAgICAgICAgICogICAgICAgIHJldHVybiB0aGlzLmV4YW1wbGVDb21wb25lbnRFdmVudHMub25FeGFtcGxlQWN0aW9uLmdldEV2ZW50KCk7XHJcbiAgICAgICAgICAgKiAgICB9XHJcbiAgICAgICAgICAgKiB9XHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiAvLyBDcmVhdGUgYW4gaW5zdGFuY2Ugb2YgdGhlIGNvbXBvbmVudCBzb21ld2hlcmVcclxuICAgICAgICAgKiB2YXIgZXhhbXBsZUNvbXBvbmVudEluc3RhbmNlID0gbmV3IEV4YW1wbGVDb21wb25lbnQoKTtcclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIC8vIFN1YnNjcmliZSB0byB0aGUgZXhhbXBsZSBldmVudCBvbiB0aGUgY29tcG9uZW50XHJcbiAgICAgICAgICogZXhhbXBsZUNvbXBvbmVudEluc3RhbmNlLm9uRXhhbXBsZUFjdGlvbi5zdWJzY3JpYmUoZnVuY3Rpb24gKHNlbmRlcjogRXhhbXBsZUNvbXBvbmVudCkge1xyXG4gICAgICAgICAgICogICAgIGNvbnNvbGUubG9nKCdvbkV4YW1wbGVBY3Rpb24gb2YgJyArIHNlbmRlciArICcgaGFzIGZpcmVkIScpO1xyXG4gICAgICAgICAgICogfSk7XHJcbiAgICAgICAgICogPC9jb2RlPlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMuY29tcG9uZW50RXZlbnRzID0ge1xyXG4gICAgICAgICAgICBvblNob3c6IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKSxcclxuICAgICAgICAgICAgb25IaWRlOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgICAgIG9uSG92ZXJDaGFuZ2VkOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgfTtcclxuICAgICAgICAvLyBDcmVhdGUgdGhlIGNvbmZpZ3VyYXRpb24gZm9yIHRoaXMgY29tcG9uZW50XHJcbiAgICAgICAgdGhpcy5jb25maWcgPSB0aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICB0YWc6ICdkaXYnLFxyXG4gICAgICAgICAgICBpZDogJ21pLXdiYy1pZC0nICsgZ3VpZF8xLkd1aWQubmV4dCgpLFxyXG4gICAgICAgICAgICBjc3NQcmVmaXg6ICdtaS13YmMnLFxyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLWNvbXBvbmVudCcsXHJcbiAgICAgICAgICAgIGNzc0NsYXNzZXM6IFtdLFxyXG4gICAgICAgICAgICBoaWRkZW46IGZhbHNlLFxyXG4gICAgICAgIH0sIHt9KTtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogSW5pdGlhbGl6ZXMgdGhlIGNvbXBvbmVudCwgZS5nLiBieSBhcHBseWluZyBjb25maWcgc2V0dGluZ3MuXHJcbiAgICAgKiBUaGlzIG1ldGhvZCBtdXN0IG5vdCBiZSBjYWxsZWQgZnJvbSBvdXRzaWRlIHRoZSBVSSBmcmFtZXdvcmsuXHJcbiAgICAgKlxyXG4gICAgICogVGhpcyBtZXRob2QgaXMgYXV0b21hdGljYWxseSBjYWxsZWQgYnkgdGhlIHtAbGluayBVSUluc3RhbmNlTWFuYWdlcn0uIElmIHRoZSBjb21wb25lbnQgaXMgYW4gaW5uZXIgY29tcG9uZW50IG9mXHJcbiAgICAgKiBzb21lIGNvbXBvbmVudCwgYW5kIHRodXMgZW5jYXBzdWxhdGVkIGFiZCBtYW5hZ2VkIGludGVybmFsbHkgYW5kIG5ldmVyIGRpcmVjdGx5IGV4cG9zZWQgdG8gdGhlIFVJTWFuYWdlcixcclxuICAgICAqIHRoaXMgbWV0aG9kIG11c3QgYmUgY2FsbGVkIGZyb20gdGhlIG1hbmFnaW5nIGNvbXBvbmVudCdzIHtAbGluayAjaW5pdGlhbGl6ZX0gbWV0aG9kLlxyXG4gICAgICovXHJcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmluaXRpYWxpemUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5oaWRkZW4gPSB0aGlzLmNvbmZpZy5oaWRkZW47XHJcbiAgICAgICAgLy8gSGlkZSB0aGUgY29tcG9uZW50IGF0IGluaXRpYWxpemF0aW9uIGlmIGl0IGlzIGNvbmZpZ3VyZWQgdG8gYmUgaGlkZGVuXHJcbiAgICAgICAgaWYgKHRoaXMuaXNIaWRkZW4oKSkge1xyXG4gICAgICAgICAgICB0aGlzLmhpZGRlbiA9IGZhbHNlOyAvLyBTZXQgZmxhZyB0byBmYWxzZSBmb3IgdGhlIGZvbGxvd2luZyBoaWRlKCkgY2FsbCB0byB3b3JrIChoaWRlKCkgY2hlY2tzIHRoZSBmbGFnKVxyXG4gICAgICAgICAgICB0aGlzLmhpZGUoKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBDb25maWd1cmVzIHRoZSBjb21wb25lbnQgZm9yIHRoZSBzdXBwbGllZCBQbGF5ZXIgYW5kIFVJSW5zdGFuY2VNYW5hZ2VyLiBUaGlzIGlzIHRoZSBwbGFjZSB3aGVyZSBhbGwgdGhlIG1hZ2ljXHJcbiAgICAgKiBoYXBwZW5zLCB3aGVyZSBjb21wb25lbnRzIHR5cGljYWxseSBzdWJzY3JpYmUgYW5kIHJlYWN0IHRvIGV2ZW50cyAob24gdGhlaXIgRE9NIGVsZW1lbnQsIHRoZSBQbGF5ZXIsIG9yIHRoZVxyXG4gICAgICogVUlJbnN0YW5jZU1hbmFnZXIpLCBhbmQgYmFzaWNhbGx5IGV2ZXJ5dGhpbmcgdGhhdCBtYWtlcyB0aGVtIGludGVyYWN0aXZlLlxyXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIG9ubHkgb25jZSwgd2hlbiB0aGUgVUlNYW5hZ2VyIGluaXRpYWxpemVzIHRoZSBVSS5cclxuICAgICAqXHJcbiAgICAgKiBTdWJjbGFzc2VzIHVzdWFsbHkgb3ZlcndyaXRlIHRoaXMgbWV0aG9kIHRvIGFkZCB0aGVpciBvd24gZnVuY3Rpb25hbGl0eS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gcGxheWVyIHRoZSBwbGF5ZXIgd2hpY2ggdGhpcyBjb21wb25lbnQgY29udHJvbHNcclxuICAgICAqIEBwYXJhbSB1aW1hbmFnZXIgdGhlIFVJSW5zdGFuY2VNYW5hZ2VyIHRoYXQgbWFuYWdlcyB0aGlzIGNvbXBvbmVudFxyXG4gICAgICovXHJcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdGhpcy5vblNob3cuc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdWltYW5hZ2VyLm9uQ29tcG9uZW50U2hvdy5kaXNwYXRjaChfdGhpcyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5vbkhpZGUuc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdWltYW5hZ2VyLm9uQ29tcG9uZW50SGlkZS5kaXNwYXRjaChfdGhpcyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gVHJhY2sgdGhlIGhvdmVyZWQgc3RhdGUgb2YgdGhlIGVsZW1lbnRcclxuICAgICAgICB0aGlzLmdldERvbUVsZW1lbnQoKS5vbignbW91c2VlbnRlcicsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMub25Ib3ZlckNoYW5nZWRFdmVudCh0cnVlKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLmdldERvbUVsZW1lbnQoKS5vbignbW91c2VsZWF2ZScsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMub25Ib3ZlckNoYW5nZWRFdmVudChmYWxzZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZWxlYXNlcyBhbGwgcmVzb3VyY2VzIGFuZCBkZXBlbmRlbmNpZXMgdGhhdCB0aGUgY29tcG9uZW50IGhvbGRzLiBQbGF5ZXIsIERPTSwgYW5kIFVJTWFuYWdlciBldmVudHMgYXJlXHJcbiAgICAgKiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQgZHVyaW5nIHJlbGVhc2UgYW5kIGRvIG5vdCBleHBsaWNpdGx5IG5lZWQgdG8gYmUgcmVtb3ZlZCBoZXJlLlxyXG4gICAgICogVGhpcyBtZXRob2QgaXMgY2FsbGVkIGJ5IHRoZSBVSU1hbmFnZXIgd2hlbiBpdCByZWxlYXNlcyB0aGUgVUkuXHJcbiAgICAgKlxyXG4gICAgICogU3ViY2xhc3NlcyB0aGF0IG5lZWQgdG8gcmVsZWFzZSByZXNvdXJjZXMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIGFuZCBjYWxsIHN1cGVyLnJlbGVhc2UoKS5cclxuICAgICAqL1xyXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5yZWxlYXNlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIE5vdGhpbmcgdG8gZG8gaGVyZSwgb3ZlcnJpZGUgd2hlcmUgbmVjZXNzYXJ5XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBHZW5lcmF0ZSB0aGUgRE9NIGVsZW1lbnQgZm9yIHRoaXMgY29tcG9uZW50LlxyXG4gICAgICpcclxuICAgICAqIFN1YmNsYXNzZXMgdXN1YWxseSBvdmVyd3JpdGUgdGhpcyBtZXRob2QgdG8gZXh0ZW5kIG9yIHJlcGxhY2UgdGhlIERPTSBlbGVtZW50IHdpdGggdGhlaXIgb3duIGRlc2lnbi5cclxuICAgICAqL1xyXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS50b0RvbUVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGVsZW1lbnQgPSBuZXcgZG9tXzEuRE9NKHRoaXMuY29uZmlnLnRhZywge1xyXG4gICAgICAgICAgICAnaWQnOiB0aGlzLmNvbmZpZy5pZCxcclxuICAgICAgICAgICAgJ2NsYXNzJzogdGhpcy5nZXRDc3NDbGFzc2VzKCksXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQ7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBET00gZWxlbWVudCBvZiB0aGlzIGNvbXBvbmVudC4gQ3JlYXRlcyB0aGUgRE9NIGVsZW1lbnQgaWYgaXQgZG9lcyBub3QgeWV0IGV4aXN0LlxyXG4gICAgICpcclxuICAgICAqIFNob3VsZCBub3QgYmUgb3ZlcndyaXR0ZW4gYnkgc3ViY2xhc3Nlcy5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7RE9NfVxyXG4gICAgICovXHJcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmdldERvbUVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmVsZW1lbnQpIHtcclxuICAgICAgICAgICAgdGhpcy5lbGVtZW50ID0gdGhpcy50b0RvbUVsZW1lbnQoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZWxlbWVudDtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIE1lcmdlcyBhIGNvbmZpZ3VyYXRpb24gd2l0aCBhIGRlZmF1bHQgY29uZmlndXJhdGlvbiBhbmQgYSBiYXNlIGNvbmZpZ3VyYXRpb24gZnJvbSB0aGUgc3VwZXJjbGFzcy5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gY29uZmlnIHRoZSBjb25maWd1cmF0aW9uIHNldHRpbmdzIGZvciB0aGUgY29tcG9uZW50cywgYXMgdXN1YWxseSBwYXNzZWQgdG8gdGhlIGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0gZGVmYXVsdHMgYSBkZWZhdWx0IGNvbmZpZ3VyYXRpb24gZm9yIHNldHRpbmdzIHRoYXQgYXJlIG5vdCBwYXNzZWQgd2l0aCB0aGUgY29uZmlndXJhdGlvblxyXG4gICAgICogQHBhcmFtIGJhc2UgY29uZmlndXJhdGlvbiBpbmhlcml0ZWQgZnJvbSBhIHN1cGVyY2xhc3NcclxuICAgICAqIEByZXR1cm5zIHtDb25maWd9XHJcbiAgICAgKi9cclxuICAgIENvbXBvbmVudC5wcm90b3R5cGUubWVyZ2VDb25maWcgPSBmdW5jdGlvbiAoY29uZmlnLCBkZWZhdWx0cywgYmFzZSkge1xyXG4gICAgICAgIC8vIEV4dGVuZCBkZWZhdWx0IGNvbmZpZyB3aXRoIHN1cHBsaWVkIGNvbmZpZ1xyXG4gICAgICAgIHZhciBtZXJnZWQgPSBPYmplY3QuYXNzaWduKHt9LCBiYXNlLCBkZWZhdWx0cywgY29uZmlnKTtcclxuICAgICAgICAvLyBSZXR1cm4gdGhlIGV4dGVuZGVkIGNvbmZpZ1xyXG4gICAgICAgIHJldHVybiBtZXJnZWQ7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBIZWxwZXIgbWV0aG9kIHRoYXQgcmV0dXJucyBhIHN0cmluZyBvZiBhbGwgQ1NTIGNsYXNzZXMgb2YgdGhlIGNvbXBvbmVudC5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfVxyXG4gICAgICovXHJcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmdldENzc0NsYXNzZXMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICAvLyBNZXJnZSBhbGwgQ1NTIGNsYXNzZXMgaW50byBzaW5nbGUgYXJyYXlcclxuICAgICAgICB2YXIgZmxhdHRlbmVkQXJyYXkgPSBbdGhpcy5jb25maWcuY3NzQ2xhc3NdLmNvbmNhdCh0aGlzLmNvbmZpZy5jc3NDbGFzc2VzKTtcclxuICAgICAgICAvLyBQcmVmaXggY2xhc3Nlc1xyXG4gICAgICAgIGZsYXR0ZW5lZEFycmF5ID0gZmxhdHRlbmVkQXJyYXkubWFwKGZ1bmN0aW9uIChjc3MpIHtcclxuICAgICAgICAgICAgcmV0dXJuIF90aGlzLnByZWZpeENzcyhjc3MpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIEpvaW4gYXJyYXkgdmFsdWVzIGludG8gYSBzdHJpbmdcclxuICAgICAgICB2YXIgZmxhdHRlbmVkU3RyaW5nID0gZmxhdHRlbmVkQXJyYXkuam9pbignICcpO1xyXG4gICAgICAgIC8vIFJldHVybiB0cmltbWVkIHN0cmluZyB0byBwcmV2ZW50IHdoaXRlc3BhY2UgYXQgdGhlIGVuZCBmcm9tIHRoZSBqb2luIG9wZXJhdGlvblxyXG4gICAgICAgIHJldHVybiBmbGF0dGVuZWRTdHJpbmcudHJpbSgpO1xyXG4gICAgfTtcclxuICAgIENvbXBvbmVudC5wcm90b3R5cGUucHJlZml4Q3NzID0gZnVuY3Rpb24gKGNzc0NsYXNzT3JJZCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZy5jc3NQcmVmaXggKyAnLScgKyBjc3NDbGFzc09ySWQ7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBjb25maWd1cmF0aW9uIG9iamVjdCBvZiB0aGUgY29tcG9uZW50LlxyXG4gICAgICogQHJldHVybnMge0NvbmZpZ31cclxuICAgICAqL1xyXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5nZXRDb25maWcgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogSGlkZXMgdGhlIGNvbXBvbmVudCBpZiBzaG93bi5cclxuICAgICAqIFRoaXMgbWV0aG9kIGJhc2ljYWxseSB0cmFuc2ZlcnMgdGhlIGNvbXBvbmVudCBpbnRvIHRoZSBoaWRkZW4gc3RhdGUuIEFjdHVhbCBoaWRpbmcgaXMgZG9uZSB2aWEgQ1NTLlxyXG4gICAgICovXHJcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmhpZGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLmhpZGRlbikge1xyXG4gICAgICAgICAgICB0aGlzLmhpZGRlbiA9IHRydWU7XHJcbiAgICAgICAgICAgIHRoaXMuZ2V0RG9tRWxlbWVudCgpLmFkZENsYXNzKHRoaXMucHJlZml4Q3NzKENvbXBvbmVudC5DTEFTU19ISURERU4pKTtcclxuICAgICAgICAgICAgdGhpcy5vbkhpZGVFdmVudCgpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFNob3dzIHRoZSBjb21wb25lbnQgaWYgaGlkZGVuLlxyXG4gICAgICovXHJcbiAgICBDb21wb25lbnQucHJvdG90eXBlLnNob3cgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuaGlkZGVuKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZ2V0RG9tRWxlbWVudCgpLnJlbW92ZUNsYXNzKHRoaXMucHJlZml4Q3NzKENvbXBvbmVudC5DTEFTU19ISURERU4pKTtcclxuICAgICAgICAgICAgdGhpcy5oaWRkZW4gPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5vblNob3dFdmVudCgpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIERldGVybWluZXMgaWYgdGhlIGNvbXBvbmVudCBpcyBoaWRkZW4uXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgY29tcG9uZW50IGlzIGhpZGRlbiwgZWxzZSBmYWxzZVxyXG4gICAgICovXHJcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmlzSGlkZGVuID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmhpZGRlbjtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIERldGVybWluZXMgaWYgdGhlIGNvbXBvbmVudCBpcyBzaG93bi5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlIGlmIHRoZSBjb21wb25lbnQgaXMgdmlzaWJsZSwgZWxzZSBmYWxzZVxyXG4gICAgICovXHJcbiAgICBDb21wb25lbnQucHJvdG90eXBlLmlzU2hvd24gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuICF0aGlzLmlzSGlkZGVuKCk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBUb2dnbGVzIHRoZSBoaWRkZW4gc3RhdGUgYnkgaGlkaW5nIHRoZSBjb21wb25lbnQgaWYgaXQgaXMgc2hvd24sIG9yIHNob3dpbmcgaXQgaWYgaGlkZGVuLlxyXG4gICAgICovXHJcbiAgICBDb21wb25lbnQucHJvdG90eXBlLnRvZ2dsZUhpZGRlbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAodGhpcy5pc0hpZGRlbigpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2hvdygpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5oaWRlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogRGV0ZXJtaW5lcyBpZiB0aGUgY29tcG9uZW50IGlzIGN1cnJlbnRseSBob3ZlcmVkLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWYgdGhlIGNvbXBvbmVudCBpcyBob3ZlcmVkLCBlbHNlIGZhbHNlXHJcbiAgICAgKi9cclxuICAgIENvbXBvbmVudC5wcm90b3R5cGUuaXNIb3ZlcmVkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmhvdmVyZWQ7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlcyB0aGUgb25TaG93IGV2ZW50LlxyXG4gICAgICogU2VlIHRoZSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvbiBldmVudCBhcmNoaXRlY3R1cmUgb24gdGhlIHtAbGluayAjY29tcG9uZW50RXZlbnRzIGV2ZW50cyBsaXN0fS5cclxuICAgICAqL1xyXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5vblNob3dFdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmNvbXBvbmVudEV2ZW50cy5vblNob3cuZGlzcGF0Y2godGhpcyk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlcyB0aGUgb25IaWRlIGV2ZW50LlxyXG4gICAgICogU2VlIHRoZSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvbiBldmVudCBhcmNoaXRlY3R1cmUgb24gdGhlIHtAbGluayAjY29tcG9uZW50RXZlbnRzIGV2ZW50cyBsaXN0fS5cclxuICAgICAqL1xyXG4gICAgQ29tcG9uZW50LnByb3RvdHlwZS5vbkhpZGVFdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmNvbXBvbmVudEV2ZW50cy5vbkhpZGUuZGlzcGF0Y2godGhpcyk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlcyB0aGUgb25Ib3ZlckNoYW5nZWQgZXZlbnQuXHJcbiAgICAgKiBTZWUgdGhlIGRldGFpbGVkIGV4cGxhbmF0aW9uIG9uIGV2ZW50IGFyY2hpdGVjdHVyZSBvbiB0aGUge0BsaW5rICNjb21wb25lbnRFdmVudHMgZXZlbnRzIGxpc3R9LlxyXG4gICAgICovXHJcbiAgICBDb21wb25lbnQucHJvdG90eXBlLm9uSG92ZXJDaGFuZ2VkRXZlbnQgPSBmdW5jdGlvbiAoaG92ZXJlZCkge1xyXG4gICAgICAgIHRoaXMuaG92ZXJlZCA9IGhvdmVyZWQ7XHJcbiAgICAgICAgdGhpcy5jb21wb25lbnRFdmVudHMub25Ib3ZlckNoYW5nZWQuZGlzcGF0Y2godGhpcywgeyBob3ZlcmVkOiBob3ZlcmVkIH0pO1xyXG4gICAgfTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShDb21wb25lbnQucHJvdG90eXBlLCBcIm9uU2hvd1wiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogR2V0cyB0aGUgZXZlbnQgdGhhdCBpcyBmaXJlZCB3aGVuIHRoZSBjb21wb25lbnQgaXMgc2hvd2luZy5cclxuICAgICAgICAgKiBTZWUgdGhlIGRldGFpbGVkIGV4cGxhbmF0aW9uIG9uIGV2ZW50IGFyY2hpdGVjdHVyZSBvbiB0aGUge0BsaW5rICNjb21wb25lbnRFdmVudHMgZXZlbnRzIGxpc3R9LlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtFdmVudDxDb21wb25lbnQ8Q29uZmlnPiwgTm9BcmdzPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcG9uZW50RXZlbnRzLm9uU2hvdy5nZXRFdmVudCgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KENvbXBvbmVudC5wcm90b3R5cGUsIFwib25IaWRlXCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXRzIHRoZSBldmVudCB0aGF0IGlzIGZpcmVkIHdoZW4gdGhlIGNvbXBvbmVudCBpcyBoaWRpbmcuXHJcbiAgICAgICAgICogU2VlIHRoZSBkZXRhaWxlZCBleHBsYW5hdGlvbiBvbiBldmVudCBhcmNoaXRlY3R1cmUgb24gdGhlIHtAbGluayAjY29tcG9uZW50RXZlbnRzIGV2ZW50cyBsaXN0fS5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnQ8Q29tcG9uZW50PENvbmZpZz4sIE5vQXJncz59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbXBvbmVudEV2ZW50cy5vbkhpZGUuZ2V0RXZlbnQoKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShDb21wb25lbnQucHJvdG90eXBlLCBcIm9uSG92ZXJDaGFuZ2VkXCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXRzIHRoZSBldmVudCB0aGF0IGlzIGZpcmVkIHdoZW4gdGhlIGNvbXBvbmVudCdzIGhvdmVyLXN0YXRlIGlzIGNoYW5naW5nLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtFdmVudDxDb21wb25lbnQ8Q29uZmlnPiwgQ29tcG9uZW50SG92ZXJDaGFuZ2VkRXZlbnRBcmdzPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY29tcG9uZW50RXZlbnRzLm9uSG92ZXJDaGFuZ2VkLmdldEV2ZW50KCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICByZXR1cm4gQ29tcG9uZW50O1xyXG59KCkpO1xyXG4vKipcclxuICogVGhlIGNsYXNzbmFtZSB0aGF0IGlzIGF0dGFjaGVkIHRvIHRoZSBlbGVtZW50IHdoZW4gaXQgaXMgaW4gdGhlIGhpZGRlbiBzdGF0ZS5cclxuICogQHR5cGUge3N0cmluZ31cclxuICovXHJcbkNvbXBvbmVudC5DTEFTU19ISURERU4gPSAnaGlkZGVuJztcclxuZXhwb3J0cy5Db21wb25lbnQgPSBDb21wb25lbnQ7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9jb21wb25lbnQudHNcbi8vIG1vZHVsZSBpZCA9IDJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBhcnJheXV0aWxzXzEgPSByZXF1aXJlKFwiLi9hcnJheXV0aWxzXCIpO1xyXG4vKipcclxuICogRXZlbnQgZGlzcGF0Y2hlciB0byBzdWJzY3JpYmUgYW5kIHRyaWdnZXIgZXZlbnRzLiBFYWNoIGV2ZW50IHNob3VsZCBoYXZlIGl0cyBvd24gZGlzcGF0Y2hlci5cclxuICovXHJcbnZhciBFdmVudERpc3BhdGNoZXIgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgZnVuY3Rpb24gRXZlbnREaXNwYXRjaGVyKCkge1xyXG4gICAgICAgIHRoaXMubGlzdGVuZXJzID0gW107XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIHtAaW5oZXJpdERvY31cclxuICAgICAqL1xyXG4gICAgRXZlbnREaXNwYXRjaGVyLnByb3RvdHlwZS5zdWJzY3JpYmUgPSBmdW5jdGlvbiAobGlzdGVuZXIpIHtcclxuICAgICAgICB0aGlzLmxpc3RlbmVycy5wdXNoKG5ldyBFdmVudExpc3RlbmVyV3JhcHBlcihsaXN0ZW5lcikpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICoge0Bpbmhlcml0RG9jfVxyXG4gICAgICovXHJcbiAgICBFdmVudERpc3BhdGNoZXIucHJvdG90eXBlLnN1YnNjcmliZU9uY2UgPSBmdW5jdGlvbiAobGlzdGVuZXIpIHtcclxuICAgICAgICB0aGlzLmxpc3RlbmVycy5wdXNoKG5ldyBFdmVudExpc3RlbmVyV3JhcHBlcihsaXN0ZW5lciwgdHJ1ZSkpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICoge0Bpbmhlcml0RG9jfVxyXG4gICAgICovXHJcbiAgICBFdmVudERpc3BhdGNoZXIucHJvdG90eXBlLnN1YnNjcmliZVJhdGVMaW1pdGVkID0gZnVuY3Rpb24gKGxpc3RlbmVyLCByYXRlTXMpIHtcclxuICAgICAgICB0aGlzLmxpc3RlbmVycy5wdXNoKG5ldyBSYXRlTGltaXRlZEV2ZW50TGlzdGVuZXJXcmFwcGVyKGxpc3RlbmVyLCByYXRlTXMpKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIHtAaW5oZXJpdERvY31cclxuICAgICAqL1xyXG4gICAgRXZlbnREaXNwYXRjaGVyLnByb3RvdHlwZS51bnN1YnNjcmliZSA9IGZ1bmN0aW9uIChsaXN0ZW5lcikge1xyXG4gICAgICAgIC8vIEl0ZXJhdGUgdGhyb3VnaCBsaXN0ZW5lcnMsIGNvbXBhcmUgd2l0aCBwYXJhbWV0ZXIsIGFuZCByZW1vdmUgaWYgZm91bmRcclxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubGlzdGVuZXJzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIHZhciBzdWJzY3JpYmVkTGlzdGVuZXIgPSB0aGlzLmxpc3RlbmVyc1tpXTtcclxuICAgICAgICAgICAgaWYgKHN1YnNjcmliZWRMaXN0ZW5lci5saXN0ZW5lciA9PT0gbGlzdGVuZXIpIHtcclxuICAgICAgICAgICAgICAgIGFycmF5dXRpbHNfMS5BcnJheVV0aWxzLnJlbW92ZSh0aGlzLmxpc3RlbmVycywgc3Vic2NyaWJlZExpc3RlbmVyKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJlbW92ZXMgYWxsIGxpc3RlbmVycyBmcm9tIHRoaXMgZGlzcGF0Y2hlci5cclxuICAgICAqL1xyXG4gICAgRXZlbnREaXNwYXRjaGVyLnByb3RvdHlwZS51bnN1YnNjcmliZUFsbCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmxpc3RlbmVycyA9IFtdO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogRGlzcGF0Y2hlcyBhbiBldmVudCB0byBhbGwgc3Vic2NyaWJlZCBsaXN0ZW5lcnMuXHJcbiAgICAgKiBAcGFyYW0gc2VuZGVyIHRoZSBzb3VyY2Ugb2YgdGhlIGV2ZW50XHJcbiAgICAgKiBAcGFyYW0gYXJncyB0aGUgYXJndW1lbnRzIGZvciB0aGUgZXZlbnRcclxuICAgICAqL1xyXG4gICAgRXZlbnREaXNwYXRjaGVyLnByb3RvdHlwZS5kaXNwYXRjaCA9IGZ1bmN0aW9uIChzZW5kZXIsIGFyZ3MpIHtcclxuICAgICAgICBpZiAoYXJncyA9PT0gdm9pZCAwKSB7IGFyZ3MgPSBudWxsOyB9XHJcbiAgICAgICAgdmFyIGxpc3RlbmVyc1RvUmVtb3ZlID0gW107XHJcbiAgICAgICAgLy8gQ2FsbCBldmVyeSBsaXN0ZW5lclxyXG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSB0aGlzLmxpc3RlbmVyczsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgdmFyIGxpc3RlbmVyID0gX2FbX2ldO1xyXG4gICAgICAgICAgICBsaXN0ZW5lci5maXJlKHNlbmRlciwgYXJncyk7XHJcbiAgICAgICAgICAgIGlmIChsaXN0ZW5lci5pc09uY2UoKSkge1xyXG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzVG9SZW1vdmUucHVzaChsaXN0ZW5lcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gUmVtb3ZlIG9uZS10aW1lIGxpc3RlbmVyXHJcbiAgICAgICAgZm9yICh2YXIgX2IgPSAwLCBsaXN0ZW5lcnNUb1JlbW92ZV8xID0gbGlzdGVuZXJzVG9SZW1vdmU7IF9iIDwgbGlzdGVuZXJzVG9SZW1vdmVfMS5sZW5ndGg7IF9iKyspIHtcclxuICAgICAgICAgICAgdmFyIGxpc3RlbmVyVG9SZW1vdmUgPSBsaXN0ZW5lcnNUb1JlbW92ZV8xW19iXTtcclxuICAgICAgICAgICAgYXJyYXl1dGlsc18xLkFycmF5VXRpbHMucmVtb3ZlKHRoaXMubGlzdGVuZXJzLCBsaXN0ZW5lclRvUmVtb3ZlKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBldmVudCB0aGF0IHRoaXMgZGlzcGF0Y2hlciBtYW5hZ2VzIGFuZCBvbiB3aGljaCBsaXN0ZW5lcnMgY2FuIHN1YnNjcmliZSBhbmQgdW5zdWJzY3JpYmUgZXZlbnQgaGFuZGxlcnMuXHJcbiAgICAgKiBAcmV0dXJucyB7RXZlbnR9XHJcbiAgICAgKi9cclxuICAgIEV2ZW50RGlzcGF0Y2hlci5wcm90b3R5cGUuZ2V0RXZlbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gRm9yIG5vdywganVzdCBjYXN0IHRoZSBldmVudCBkaXNwYXRjaGVyIHRvIHRoZSBldmVudCBpbnRlcmZhY2UuIEF0IHNvbWUgcG9pbnQgaW4gdGhlIGZ1dHVyZSB3aGVuIHRoZVxyXG4gICAgICAgIC8vIGNvZGViYXNlIGdyb3dzLCBpdCBtaWdodCBtYWtlIHNlbnNlIHRvIHNwbGl0IHRoZSBkaXNwYXRjaGVyIGludG8gc2VwYXJhdGUgZGlzcGF0Y2hlciBhbmQgZXZlbnQgY2xhc3Nlcy5cclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICByZXR1cm4gRXZlbnREaXNwYXRjaGVyO1xyXG59KCkpO1xyXG5leHBvcnRzLkV2ZW50RGlzcGF0Y2hlciA9IEV2ZW50RGlzcGF0Y2hlcjtcclxuLyoqXHJcbiAqIEEgYmFzaWMgZXZlbnQgbGlzdGVuZXIgd3JhcHBlciB0byBtYW5hZ2UgbGlzdGVuZXJzIHdpdGhpbiB0aGUge0BsaW5rIEV2ZW50RGlzcGF0Y2hlcn0uIFRoaXMgaXMgYSAncHJpdmF0ZScgY2xhc3NcclxuICogZm9yIGludGVybmFsIGRpc3BhdGNoZXIgdXNlIGFuZCBpdCBpcyB0aGVyZWZvcmUgbm90IGV4cG9ydGVkLlxyXG4gKi9cclxudmFyIEV2ZW50TGlzdGVuZXJXcmFwcGVyID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIEV2ZW50TGlzdGVuZXJXcmFwcGVyKGxpc3RlbmVyLCBvbmNlKSB7XHJcbiAgICAgICAgaWYgKG9uY2UgPT09IHZvaWQgMCkgeyBvbmNlID0gZmFsc2U7IH1cclxuICAgICAgICB0aGlzLmV2ZW50TGlzdGVuZXIgPSBsaXN0ZW5lcjtcclxuICAgICAgICB0aGlzLm9uY2UgPSBvbmNlO1xyXG4gICAgfVxyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KEV2ZW50TGlzdGVuZXJXcmFwcGVyLnByb3RvdHlwZSwgXCJsaXN0ZW5lclwiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmV0dXJucyB0aGUgd3JhcHBlZCBldmVudCBsaXN0ZW5lci5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnRMaXN0ZW5lcjxTZW5kZXIsIEFyZ3M+fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudExpc3RlbmVyO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlcyB0aGUgd3JhcHBlZCBldmVudCBsaXN0ZW5lciB3aXRoIHRoZSBnaXZlbiBhcmd1bWVudHMuXHJcbiAgICAgKiBAcGFyYW0gc2VuZGVyXHJcbiAgICAgKiBAcGFyYW0gYXJnc1xyXG4gICAgICovXHJcbiAgICBFdmVudExpc3RlbmVyV3JhcHBlci5wcm90b3R5cGUuZmlyZSA9IGZ1bmN0aW9uIChzZW5kZXIsIGFyZ3MpIHtcclxuICAgICAgICB0aGlzLmV2ZW50TGlzdGVuZXIoc2VuZGVyLCBhcmdzKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIENoZWNrcyBpZiB0aGlzIGxpc3RlbmVyIGlzIHNjaGVkdWxlZCB0byBiZSBjYWxsZWQgb25seSBvbmNlLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IG9uY2UgaWYgdHJ1ZVxyXG4gICAgICovXHJcbiAgICBFdmVudExpc3RlbmVyV3JhcHBlci5wcm90b3R5cGUuaXNPbmNlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm9uY2U7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIEV2ZW50TGlzdGVuZXJXcmFwcGVyO1xyXG59KCkpO1xyXG4vKipcclxuICogRXh0ZW5kcyB0aGUgYmFzaWMge0BsaW5rIEV2ZW50TGlzdGVuZXJXcmFwcGVyfSB3aXRoIHJhdGUtbGltaXRpbmcgZnVuY3Rpb25hbGl0eS5cclxuICovXHJcbnZhciBSYXRlTGltaXRlZEV2ZW50TGlzdGVuZXJXcmFwcGVyID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhSYXRlTGltaXRlZEV2ZW50TGlzdGVuZXJXcmFwcGVyLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gUmF0ZUxpbWl0ZWRFdmVudExpc3RlbmVyV3JhcHBlcihsaXN0ZW5lciwgcmF0ZU1zKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgbGlzdGVuZXIpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMucmF0ZU1zID0gcmF0ZU1zO1xyXG4gICAgICAgIF90aGlzLmxhc3RGaXJlVGltZSA9IDA7XHJcbiAgICAgICAgLy8gV3JhcCB0aGUgZXZlbnQgbGlzdGVuZXIgd2l0aCBhbiBldmVudCBsaXN0ZW5lciB0aGF0IGRvZXMgdGhlIHJhdGUtbGltaXRpbmdcclxuICAgICAgICBfdGhpcy5yYXRlTGltaXRpbmdFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gKHNlbmRlciwgYXJncykge1xyXG4gICAgICAgICAgICBpZiAoRGF0ZS5ub3coKSAtIF90aGlzLmxhc3RGaXJlVGltZSA+IF90aGlzLnJhdGVNcykge1xyXG4gICAgICAgICAgICAgICAgLy8gT25seSBpZiBlbm91Z2ggdGltZSBzaW5jZSB0aGUgcHJldmlvdXMgY2FsbCBoYXMgcGFzc2VkLCBjYWxsIHRoZVxyXG4gICAgICAgICAgICAgICAgLy8gYWN0dWFsIGV2ZW50IGxpc3RlbmVyIGFuZCByZWNvcmQgdGhlIGN1cnJlbnQgdGltZVxyXG4gICAgICAgICAgICAgICAgX3RoaXMuZmlyZVN1cGVyKHNlbmRlciwgYXJncyk7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5sYXN0RmlyZVRpbWUgPSBEYXRlLm5vdygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBSYXRlTGltaXRlZEV2ZW50TGlzdGVuZXJXcmFwcGVyLnByb3RvdHlwZS5maXJlU3VwZXIgPSBmdW5jdGlvbiAoc2VuZGVyLCBhcmdzKSB7XHJcbiAgICAgICAgLy8gRmlyZSB0aGUgYWN0dWFsIGV4dGVybmFsIGV2ZW50IGxpc3RlbmVyXHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5maXJlLmNhbGwodGhpcywgc2VuZGVyLCBhcmdzKTtcclxuICAgIH07XHJcbiAgICBSYXRlTGltaXRlZEV2ZW50TGlzdGVuZXJXcmFwcGVyLnByb3RvdHlwZS5maXJlID0gZnVuY3Rpb24gKHNlbmRlciwgYXJncykge1xyXG4gICAgICAgIC8vIEZpcmUgdGhlIGludGVybmFsIHJhdGUtbGltaXRpbmcgbGlzdGVuZXIgaW5zdGVhZCBvZiB0aGUgZXh0ZXJuYWwgZXZlbnQgbGlzdGVuZXJcclxuICAgICAgICB0aGlzLnJhdGVMaW1pdGluZ0V2ZW50TGlzdGVuZXIoc2VuZGVyLCBhcmdzKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gUmF0ZUxpbWl0ZWRFdmVudExpc3RlbmVyV3JhcHBlcjtcclxufShFdmVudExpc3RlbmVyV3JhcHBlcikpO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2V2ZW50ZGlzcGF0Y2hlci50c1xuLy8gbW9kdWxlIGlkID0gM1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgQXJyYXlVdGlscztcclxuKGZ1bmN0aW9uIChBcnJheVV0aWxzKSB7XHJcbiAgICAvKipcclxuICAgICAqIFJlbW92ZXMgYW4gaXRlbSBmcm9tIGFuIGFycmF5LlxyXG4gICAgICogQHBhcmFtIGFycmF5IHRoZSBhcnJheSB0aGF0IG1heSBjb250YWluIHRoZSBpdGVtIHRvIHJlbW92ZVxyXG4gICAgICogQHBhcmFtIGl0ZW0gdGhlIGl0ZW0gdG8gcmVtb3ZlIGZyb20gdGhlIGFycmF5XHJcbiAgICAgKiBAcmV0dXJucyB7YW55fSB0aGUgcmVtb3ZlZCBpdGVtIG9yIG51bGwgaWYgaXQgd2Fzbid0IHBhcnQgb2YgdGhlIGFycmF5XHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIHJlbW92ZShhcnJheSwgaXRlbSkge1xyXG4gICAgICAgIHZhciBpbmRleCA9IGFycmF5LmluZGV4T2YoaXRlbSk7XHJcbiAgICAgICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFycmF5LnNwbGljZShpbmRleCwgMSlbMF07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBBcnJheVV0aWxzLnJlbW92ZSA9IHJlbW92ZTtcclxufSkoQXJyYXlVdGlscyA9IGV4cG9ydHMuQXJyYXlVdGlscyB8fCAoZXhwb3J0cy5BcnJheVV0aWxzID0ge30pKTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9hcnJheXV0aWxzLnRzXG4vLyBtb2R1bGUgaWQgPSA0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBldmVudGRpc3BhdGNoZXJfMSA9IHJlcXVpcmUoXCIuL2V2ZW50ZGlzcGF0Y2hlclwiKTtcclxudmFyIGJyb3dzZXJ1dGlsc18xID0gcmVxdWlyZShcIi4vYnJvd3NlcnV0aWxzXCIpO1xyXG52YXIgUGxheWVyVXRpbHM7XHJcbihmdW5jdGlvbiAoUGxheWVyVXRpbHMpIHtcclxuICAgIHZhciBQbGF5ZXJTdGF0ZTtcclxuICAgIChmdW5jdGlvbiAoUGxheWVyU3RhdGUpIHtcclxuICAgICAgICBQbGF5ZXJTdGF0ZVtQbGF5ZXJTdGF0ZVtcIklETEVcIl0gPSAwXSA9IFwiSURMRVwiO1xyXG4gICAgICAgIFBsYXllclN0YXRlW1BsYXllclN0YXRlW1wiUFJFUEFSRURcIl0gPSAxXSA9IFwiUFJFUEFSRURcIjtcclxuICAgICAgICBQbGF5ZXJTdGF0ZVtQbGF5ZXJTdGF0ZVtcIlBMQVlJTkdcIl0gPSAyXSA9IFwiUExBWUlOR1wiO1xyXG4gICAgICAgIFBsYXllclN0YXRlW1BsYXllclN0YXRlW1wiUEFVU0VEXCJdID0gM10gPSBcIlBBVVNFRFwiO1xyXG4gICAgICAgIFBsYXllclN0YXRlW1BsYXllclN0YXRlW1wiRklOSVNIRURcIl0gPSA0XSA9IFwiRklOSVNIRURcIjtcclxuICAgIH0pKFBsYXllclN0YXRlID0gUGxheWVyVXRpbHMuUGxheWVyU3RhdGUgfHwgKFBsYXllclV0aWxzLlBsYXllclN0YXRlID0ge30pKTtcclxuICAgIGZ1bmN0aW9uIGlzU291cmNlTG9hZGVkKHBsYXllcikge1xyXG4gICAgICAgIHJldHVybiBwbGF5ZXIuZ2V0Q29uZmlnKCkuc291cmNlICE9PSB1bmRlZmluZWQ7XHJcbiAgICB9XHJcbiAgICBQbGF5ZXJVdGlscy5pc1NvdXJjZUxvYWRlZCA9IGlzU291cmNlTG9hZGVkO1xyXG4gICAgZnVuY3Rpb24gaXNUaW1lU2hpZnRBdmFpbGFibGUocGxheWVyKSB7XHJcbiAgICAgICAgcmV0dXJuIHBsYXllci5pc0xpdmUoKSAmJiBwbGF5ZXIuZ2V0TWF4VGltZVNoaWZ0KCkgIT09IDA7XHJcbiAgICB9XHJcbiAgICBQbGF5ZXJVdGlscy5pc1RpbWVTaGlmdEF2YWlsYWJsZSA9IGlzVGltZVNoaWZ0QXZhaWxhYmxlO1xyXG4gICAgZnVuY3Rpb24gZ2V0U3RhdGUocGxheWVyKSB7XHJcbiAgICAgICAgaWYgKHBsYXllci5oYXNFbmRlZCgpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQbGF5ZXJTdGF0ZS5GSU5JU0hFRDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAocGxheWVyLmlzUGxheWluZygpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQbGF5ZXJTdGF0ZS5QTEFZSU5HO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChwbGF5ZXIuaXNQYXVzZWQoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gUGxheWVyU3RhdGUuUEFVU0VEO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChpc1NvdXJjZUxvYWRlZChwbGF5ZXIpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQbGF5ZXJTdGF0ZS5QUkVQQVJFRDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBQbGF5ZXJTdGF0ZS5JRExFO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuICAgIFBsYXllclV0aWxzLmdldFN0YXRlID0gZ2V0U3RhdGU7XHJcbiAgICB2YXIgVGltZVNoaWZ0QXZhaWxhYmlsaXR5RGV0ZWN0b3IgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIFRpbWVTaGlmdEF2YWlsYWJpbGl0eURldGVjdG9yKHBsYXllcikge1xyXG4gICAgICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgICAgICB0aGlzLnRpbWVTaGlmdEF2YWlsYWJpbGl0eUNoYW5nZWRFdmVudCA9IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKTtcclxuICAgICAgICAgICAgdGhpcy5wbGF5ZXIgPSBwbGF5ZXI7XHJcbiAgICAgICAgICAgIHRoaXMudGltZVNoaWZ0QXZhaWxhYmxlID0gdW5kZWZpbmVkO1xyXG4gICAgICAgICAgICB2YXIgdGltZVNoaWZ0RGV0ZWN0b3IgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5kZXRlY3QoKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgLy8gVHJ5IHRvIGRldGVjdCB0aW1lc2hpZnQgYXZhaWxhYmlsaXR5IGluIE9OX1JFQURZLCB3aGljaCB3b3JrcyBmb3IgREFTSCBzdHJlYW1zXHJcbiAgICAgICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1JFQURZLCB0aW1lU2hpZnREZXRlY3Rvcik7XHJcbiAgICAgICAgICAgIC8vIFdpdGggSExTL05hdGl2ZVBsYXllciBzdHJlYW1zLCBnZXRNYXhUaW1lU2hpZnQgY2FuIGJlIDAgYmVmb3JlIHRoZSBidWZmZXIgZmlsbHMsIHNvIHdlIG5lZWQgdG8gYWRkaXRpb25hbGx5XHJcbiAgICAgICAgICAgIC8vIGNoZWNrIHRpbWVzaGlmdCBhdmFpbGFiaWxpdHkgaW4gT05fVElNRV9DSEFOR0VEXHJcbiAgICAgICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1RJTUVfQ0hBTkdFRCwgdGltZVNoaWZ0RGV0ZWN0b3IpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBUaW1lU2hpZnRBdmFpbGFiaWxpdHlEZXRlY3Rvci5wcm90b3R5cGUuZGV0ZWN0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5wbGF5ZXIuaXNMaXZlKCkpIHtcclxuICAgICAgICAgICAgICAgIHZhciB0aW1lU2hpZnRBdmFpbGFibGVOb3cgPSBQbGF5ZXJVdGlscy5pc1RpbWVTaGlmdEF2YWlsYWJsZSh0aGlzLnBsYXllcik7XHJcbiAgICAgICAgICAgICAgICAvLyBXaGVuIHRoZSBhdmFpbGFiaWxpdHkgY2hhbmdlcywgd2UgZmlyZSB0aGUgZXZlbnRcclxuICAgICAgICAgICAgICAgIGlmICh0aW1lU2hpZnRBdmFpbGFibGVOb3cgIT09IHRoaXMudGltZVNoaWZ0QXZhaWxhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50aW1lU2hpZnRBdmFpbGFiaWxpdHlDaGFuZ2VkRXZlbnQuZGlzcGF0Y2godGhpcy5wbGF5ZXIsIHsgdGltZVNoaWZ0QXZhaWxhYmxlOiB0aW1lU2hpZnRBdmFpbGFibGVOb3cgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy50aW1lU2hpZnRBdmFpbGFibGUgPSB0aW1lU2hpZnRBdmFpbGFibGVOb3c7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUaW1lU2hpZnRBdmFpbGFiaWxpdHlEZXRlY3Rvci5wcm90b3R5cGUsIFwib25UaW1lU2hpZnRBdmFpbGFiaWxpdHlDaGFuZ2VkXCIsIHtcclxuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy50aW1lU2hpZnRBdmFpbGFiaWxpdHlDaGFuZ2VkRXZlbnQuZ2V0RXZlbnQoKTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIFRpbWVTaGlmdEF2YWlsYWJpbGl0eURldGVjdG9yO1xyXG4gICAgfSgpKTtcclxuICAgIFBsYXllclV0aWxzLlRpbWVTaGlmdEF2YWlsYWJpbGl0eURldGVjdG9yID0gVGltZVNoaWZ0QXZhaWxhYmlsaXR5RGV0ZWN0b3I7XHJcbiAgICAvKipcclxuICAgICAqIERldGVjdHMgY2hhbmdlcyBvZiB0aGUgc3RyZWFtIHR5cGUsIGkuZS4gY2hhbmdlcyBvZiB0aGUgcmV0dXJuIHZhbHVlIG9mIHRoZSBwbGF5ZXIjaXNMaXZlIG1ldGhvZC5cclxuICAgICAqIE5vcm1hbGx5LCBhIHN0cmVhbSBjYW5ub3QgY2hhbmdlIGl0cyB0eXBlIGR1cmluZyBwbGF5YmFjaywgaXQncyBlaXRoZXIgVk9EIG9yIGxpdmUuIER1ZSB0byBidWdzIG9uIHNvbWVcclxuICAgICAqIHBsYXRmb3JtcyBvciBicm93c2VycywgaXQgY2FuIHN0aWxsIGNoYW5nZS4gSXQgaXMgdGhlcmVmb3JlIHVucmVsaWFibGUgdG8ganVzdCBjaGVjayAjaXNMaXZlIGFuZCB0aGlzIGRldGVjdG9yXHJcbiAgICAgKiBzaG91bGQgYmUgdXNlZCBhcyBhIHdvcmthcm91bmQgaW5zdGVhZC5cclxuICAgICAqXHJcbiAgICAgKiBLbm93biBjYXNlczpcclxuICAgICAqXHJcbiAgICAgKiAtIEhMUyBWT0Qgb24gQW5kcm9pZCA0LjNcclxuICAgICAqIFZpZGVvIGR1cmF0aW9uIGlzIGluaXRpYWxseSAnSW5maW5pdHknIGFuZCBvbmx5IGdldHMgYXZhaWxhYmxlIGFmdGVyIHBsYXliYWNrIHN0YXJ0cywgc28gc3RyZWFtcyBhcmUgd3JvbmdseVxyXG4gICAgICogcmVwb3J0ZWQgYXMgJ2xpdmUnIGJlZm9yZSBwbGF5YmFjayAodGhlIGxpdmUtY2hlY2sgaW4gdGhlIHBsYXllciBjaGVja3MgZm9yIGluZmluaXRlIGR1cmF0aW9uKS5cclxuICAgICAqL1xyXG4gICAgdmFyIExpdmVTdHJlYW1EZXRlY3RvciA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZnVuY3Rpb24gTGl2ZVN0cmVhbURldGVjdG9yKHBsYXllcikge1xyXG4gICAgICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgICAgICB0aGlzLmxpdmVDaGFuZ2VkRXZlbnQgPSBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCk7XHJcbiAgICAgICAgICAgIHRoaXMucGxheWVyID0gcGxheWVyO1xyXG4gICAgICAgICAgICB0aGlzLmxpdmUgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgIHZhciBsaXZlRGV0ZWN0b3IgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5kZXRlY3QoKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgLy8gSW5pdGlhbGl6ZSB3aGVuIHBsYXllciBpcyByZWFkeVxyXG4gICAgICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9SRUFEWSwgbGl2ZURldGVjdG9yKTtcclxuICAgICAgICAgICAgLy8gUmUtZXZhbHVhdGUgd2hlbiBwbGF5YmFjayBzdGFydHNcclxuICAgICAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUExBWSwgbGl2ZURldGVjdG9yKTtcclxuICAgICAgICAgICAgLy8gSExTIGxpdmUgZGV0ZWN0aW9uIHdvcmthcm91bmQgZm9yIEFuZHJvaWQ6XHJcbiAgICAgICAgICAgIC8vIEFsc28gcmUtZXZhbHVhdGUgZHVyaW5nIHBsYXliYWNrLCBiZWNhdXNlIHRoYXQgaXMgd2hlbiB0aGUgbGl2ZSBmbGFnIG1pZ2h0IGNoYW5nZS5cclxuICAgICAgICAgICAgLy8gKERvaW5nIGl0IG9ubHkgaW4gQW5kcm9pZCBDaHJvbWUgc2F2ZXMgdW5uZWNlc3Nhcnkgb3ZlcmhlYWQgb24gb3RoZXIgcGxhdHRmb3JtcylcclxuICAgICAgICAgICAgaWYgKGJyb3dzZXJ1dGlsc18xLkJyb3dzZXJVdGlscy5pc0FuZHJvaWQgJiYgYnJvd3NlcnV0aWxzXzEuQnJvd3NlclV0aWxzLmlzQ2hyb21lKSB7XHJcbiAgICAgICAgICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9USU1FX0NIQU5HRUQsIGxpdmVEZXRlY3Rvcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgTGl2ZVN0cmVhbURldGVjdG9yLnByb3RvdHlwZS5kZXRlY3QgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBsaXZlTm93ID0gdGhpcy5wbGF5ZXIuaXNMaXZlKCk7XHJcbiAgICAgICAgICAgIC8vIENvbXBhcmUgY3VycmVudCB0byBwcmV2aW91cyBsaXZlIHN0YXRlIGZsYWcgYW5kIGZpcmUgZXZlbnQgd2hlbiBpdCBjaGFuZ2VzLiBTaW5jZSB3ZSBpbml0aWFsaXplIHRoZSBmbGFnXHJcbiAgICAgICAgICAgIC8vIHdpdGggdW5kZWZpbmVkLCB0aGVyZSBpcyBhbHdheXMgYXQgbGVhc3QgYW4gaW5pdGlhbCBldmVudCBmaXJlZCB0aGF0IHRlbGxzIGxpc3RlbmVycyB0aGUgbGl2ZSBzdGF0ZS5cclxuICAgICAgICAgICAgaWYgKGxpdmVOb3cgIT09IHRoaXMubGl2ZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5saXZlQ2hhbmdlZEV2ZW50LmRpc3BhdGNoKHRoaXMucGxheWVyLCB7IGxpdmU6IGxpdmVOb3cgfSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmxpdmUgPSBsaXZlTm93O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoTGl2ZVN0cmVhbURldGVjdG9yLnByb3RvdHlwZSwgXCJvbkxpdmVDaGFuZ2VkXCIsIHtcclxuICAgICAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5saXZlQ2hhbmdlZEV2ZW50LmdldEV2ZW50KCk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiBMaXZlU3RyZWFtRGV0ZWN0b3I7XHJcbiAgICB9KCkpO1xyXG4gICAgUGxheWVyVXRpbHMuTGl2ZVN0cmVhbURldGVjdG9yID0gTGl2ZVN0cmVhbURldGVjdG9yO1xyXG59KShQbGF5ZXJVdGlscyA9IGV4cG9ydHMuUGxheWVyVXRpbHMgfHwgKGV4cG9ydHMuUGxheWVyVXRpbHMgPSB7fSkpO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL3BsYXllcnV0aWxzLnRzXG4vLyBtb2R1bGUgaWQgPSA1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRcIik7XHJcbnZhciBkb21fMSA9IHJlcXVpcmUoXCIuLi9kb21cIik7XHJcbnZhciBldmVudGRpc3BhdGNoZXJfMSA9IHJlcXVpcmUoXCIuLi9ldmVudGRpc3BhdGNoZXJcIik7XHJcbi8qKlxyXG4gKiBBIHNpbXBsZSBjbGlja2FibGUgYnV0dG9uLlxyXG4gKi9cclxudmFyIEJ1dHRvbiA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoQnV0dG9uLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gQnV0dG9uKGNvbmZpZykge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5idXR0b25FdmVudHMgPSB7XHJcbiAgICAgICAgICAgIG9uQ2xpY2s6IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKSxcclxuICAgICAgICB9O1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLWJ1dHRvbicsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBCdXR0b24ucHJvdG90eXBlLnRvRG9tRWxlbWVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIC8vIENyZWF0ZSB0aGUgYnV0dG9uIGVsZW1lbnQgd2l0aCB0aGUgdGV4dCBsYWJlbFxyXG4gICAgICAgIHZhciBidXR0b25FbGVtZW50ID0gbmV3IGRvbV8xLkRPTSgnYnV0dG9uJywge1xyXG4gICAgICAgICAgICAndHlwZSc6ICdidXR0b24nLFxyXG4gICAgICAgICAgICAnaWQnOiB0aGlzLmNvbmZpZy5pZCxcclxuICAgICAgICAgICAgJ2NsYXNzJzogdGhpcy5nZXRDc3NDbGFzc2VzKCksXHJcbiAgICAgICAgfSkuYXBwZW5kKG5ldyBkb21fMS5ET00oJ3NwYW4nLCB7XHJcbiAgICAgICAgICAgICdjbGFzcyc6IHRoaXMucHJlZml4Q3NzKCdsYWJlbCcpLFxyXG4gICAgICAgIH0pLmh0bWwodGhpcy5jb25maWcudGV4dCkpO1xyXG4gICAgICAgIC8vIExpc3RlbiBmb3IgdGhlIGNsaWNrIGV2ZW50IG9uIHRoZSBidXR0b24gZWxlbWVudCBhbmQgdHJpZ2dlciB0aGUgY29ycmVzcG9uZGluZyBldmVudCBvbiB0aGUgYnV0dG9uIGNvbXBvbmVudFxyXG4gICAgICAgIGJ1dHRvbkVsZW1lbnQub24oJ2NsaWNrJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5vbkNsaWNrRXZlbnQoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICByZXR1cm4gYnV0dG9uRWxlbWVudDtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGV4dCBvbiB0aGUgbGFiZWwgb2YgdGhlIGJ1dHRvbi5cclxuICAgICAqIEBwYXJhbSB0ZXh0IHRoZSB0ZXh0IHRvIHB1dCBpbnRvIHRoZSBsYWJlbCBvZiB0aGUgYnV0dG9uXHJcbiAgICAgKi9cclxuICAgIEJ1dHRvbi5wcm90b3R5cGUuc2V0VGV4dCA9IGZ1bmN0aW9uICh0ZXh0KSB7XHJcbiAgICAgICAgdGhpcy5nZXREb21FbGVtZW50KCkuZmluZCgnLicgKyB0aGlzLnByZWZpeENzcygnbGFiZWwnKSkuaHRtbCh0ZXh0KTtcclxuICAgIH07XHJcbiAgICBCdXR0b24ucHJvdG90eXBlLm9uQ2xpY2tFdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmJ1dHRvbkV2ZW50cy5vbkNsaWNrLmRpc3BhdGNoKHRoaXMpO1xyXG4gICAgfTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShCdXR0b24ucHJvdG90eXBlLCBcIm9uQ2xpY2tcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldHMgdGhlIGV2ZW50IHRoYXQgaXMgZmlyZWQgd2hlbiB0aGUgYnV0dG9uIGlzIGNsaWNrZWQuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50PEJ1dHRvbjxDb25maWc+LCBOb0FyZ3M+fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5idXR0b25FdmVudHMub25DbGljay5nZXRFdmVudCgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIEJ1dHRvbjtcclxufShjb21wb25lbnRfMS5Db21wb25lbnQpKTtcclxuZXhwb3J0cy5CdXR0b24gPSBCdXR0b247XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9idXR0b24udHNcbi8vIG1vZHVsZSBpZCA9IDZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBjb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudFwiKTtcclxudmFyIGRvbV8xID0gcmVxdWlyZShcIi4uL2RvbVwiKTtcclxudmFyIGV2ZW50ZGlzcGF0Y2hlcl8xID0gcmVxdWlyZShcIi4uL2V2ZW50ZGlzcGF0Y2hlclwiKTtcclxuLyoqXHJcbiAqIEEgc2ltcGxlIHRleHQgbGFiZWwuXHJcbiAqXHJcbiAqIERPTSBleGFtcGxlOlxyXG4gKiA8Y29kZT5cclxuICogICAgIDxzcGFuIGNsYXNzPSd1aS1sYWJlbCc+Li4uc29tZSB0ZXh0Li4uPC9zcGFuPlxyXG4gKiA8L2NvZGU+XHJcbiAqL1xyXG52YXIgTGFiZWwgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKExhYmVsLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gTGFiZWwoY29uZmlnKSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLmxhYmVsRXZlbnRzID0ge1xyXG4gICAgICAgICAgICBvbkNsaWNrOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgICAgIG9uVGV4dENoYW5nZWQ6IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKSxcclxuICAgICAgICB9O1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLWxhYmVsJyxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIF90aGlzLnRleHQgPSBfdGhpcy5jb25maWcudGV4dDtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBMYWJlbC5wcm90b3R5cGUudG9Eb21FbGVtZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIGxhYmVsRWxlbWVudCA9IG5ldyBkb21fMS5ET00oJ3NwYW4nLCB7XHJcbiAgICAgICAgICAgICdpZCc6IHRoaXMuY29uZmlnLmlkLFxyXG4gICAgICAgICAgICAnY2xhc3MnOiB0aGlzLmdldENzc0NsYXNzZXMoKSxcclxuICAgICAgICB9KS5odG1sKHRoaXMudGV4dCk7XHJcbiAgICAgICAgbGFiZWxFbGVtZW50Lm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMub25DbGlja0V2ZW50KCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIGxhYmVsRWxlbWVudDtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFNldCB0aGUgdGV4dCBvbiB0aGlzIGxhYmVsLlxyXG4gICAgICogQHBhcmFtIHRleHRcclxuICAgICAqL1xyXG4gICAgTGFiZWwucHJvdG90eXBlLnNldFRleHQgPSBmdW5jdGlvbiAodGV4dCkge1xyXG4gICAgICAgIHRoaXMudGV4dCA9IHRleHQ7XHJcbiAgICAgICAgdGhpcy5nZXREb21FbGVtZW50KCkuaHRtbCh0ZXh0KTtcclxuICAgICAgICB0aGlzLm9uVGV4dENoYW5nZWRFdmVudCh0ZXh0KTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIHRleHQgb24gdGhpcyBsYWJlbC5cclxuICAgICAqIEByZXR1cm4ge3N0cmluZ30gVGhlIHRleHQgb24gdGhlIGxhYmVsXHJcbiAgICAgKi9cclxuICAgIExhYmVsLnByb3RvdHlwZS5nZXRUZXh0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnRleHQ7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBDbGVhcnMgdGhlIHRleHQgb24gdGhpcyBsYWJlbC5cclxuICAgICAqL1xyXG4gICAgTGFiZWwucHJvdG90eXBlLmNsZWFyVGV4dCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmdldERvbUVsZW1lbnQoKS5odG1sKCcnKTtcclxuICAgICAgICB0aGlzLm9uVGV4dENoYW5nZWRFdmVudChudWxsKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFRlc3RzIGlmIHRoZSBsYWJlbCBpcyBlbXB0eSBhbmQgZG9lcyBub3QgY29udGFpbiBhbnkgdGV4dC5cclxuICAgICAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIGxhYmVsIGlzIGVtcHR5LCBlbHNlIGZhbHNlXHJcbiAgICAgKi9cclxuICAgIExhYmVsLnByb3RvdHlwZS5pc0VtcHR5ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiAhdGhpcy50ZXh0O1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogRmlyZXMgdGhlIHtAbGluayAjb25DbGlja30gZXZlbnQuXHJcbiAgICAgKiBDYW4gYmUgdXNlZCBieSBzdWJjbGFzc2VzIHRvIGxpc3RlbiB0byB0aGlzIGV2ZW50IHdpdGhvdXQgc3Vic2NyaWJpbmcgYW4gZXZlbnQgbGlzdGVuZXIgYnkgb3ZlcndyaXRpbmcgdGhlIG1ldGhvZFxyXG4gICAgICogYW5kIGNhbGxpbmcgdGhlIHN1cGVyIG1ldGhvZC5cclxuICAgICAqL1xyXG4gICAgTGFiZWwucHJvdG90eXBlLm9uQ2xpY2tFdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmxhYmVsRXZlbnRzLm9uQ2xpY2suZGlzcGF0Y2godGhpcyk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBGaXJlcyB0aGUge0BsaW5rICNvbkNsaWNrfSBldmVudC5cclxuICAgICAqIENhbiBiZSB1c2VkIGJ5IHN1YmNsYXNzZXMgdG8gbGlzdGVuIHRvIHRoaXMgZXZlbnQgd2l0aG91dCBzdWJzY3JpYmluZyBhbiBldmVudCBsaXN0ZW5lciBieSBvdmVyd3JpdGluZyB0aGUgbWV0aG9kXHJcbiAgICAgKiBhbmQgY2FsbGluZyB0aGUgc3VwZXIgbWV0aG9kLlxyXG4gICAgICovXHJcbiAgICBMYWJlbC5wcm90b3R5cGUub25UZXh0Q2hhbmdlZEV2ZW50ID0gZnVuY3Rpb24gKHRleHQpIHtcclxuICAgICAgICB0aGlzLmxhYmVsRXZlbnRzLm9uVGV4dENoYW5nZWQuZGlzcGF0Y2godGhpcywgdGV4dCk7XHJcbiAgICB9O1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KExhYmVsLnByb3RvdHlwZSwgXCJvbkNsaWNrXCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXRzIHRoZSBldmVudCB0aGF0IGlzIGZpcmVkIHdoZW4gdGhlIGxhYmVsIGlzIGNsaWNrZWQuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50PExhYmVsPExhYmVsQ29uZmlnPiwgTm9BcmdzPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubGFiZWxFdmVudHMub25DbGljay5nZXRFdmVudCgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KExhYmVsLnByb3RvdHlwZSwgXCJvblRleHRDaGFuZ2VkXCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXRzIHRoZSBldmVudCB0aGF0IGlzIGZpcmVkIHdoZW4gdGhlIHRleHQgb24gdGhlIGxhYmVsIGlzIGNoYW5nZWQuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50PExhYmVsPExhYmVsQ29uZmlnPiwgc3RyaW5nPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMubGFiZWxFdmVudHMub25UZXh0Q2hhbmdlZC5nZXRFdmVudCgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIExhYmVsO1xyXG59KGNvbXBvbmVudF8xLkNvbXBvbmVudCkpO1xyXG5leHBvcnRzLkxhYmVsID0gTGFiZWw7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9sYWJlbC50c1xuLy8gbW9kdWxlIGlkID0gN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGJ1dHRvbl8xID0gcmVxdWlyZShcIi4vYnV0dG9uXCIpO1xyXG52YXIgZXZlbnRkaXNwYXRjaGVyXzEgPSByZXF1aXJlKFwiLi4vZXZlbnRkaXNwYXRjaGVyXCIpO1xyXG4vKipcclxuICogQSBidXR0b24gdGhhdCBjYW4gYmUgdG9nZ2xlZCBiZXR3ZWVuICdvbicgYW5kICdvZmYnIHN0YXRlcy5cclxuICovXHJcbnZhciBUb2dnbGVCdXR0b24gPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKFRvZ2dsZUJ1dHRvbiwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFRvZ2dsZUJ1dHRvbihjb25maWcpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMudG9nZ2xlQnV0dG9uRXZlbnRzID0ge1xyXG4gICAgICAgICAgICBvblRvZ2dsZTogbmV3IGV2ZW50ZGlzcGF0Y2hlcl8xLkV2ZW50RGlzcGF0Y2hlcigpLFxyXG4gICAgICAgICAgICBvblRvZ2dsZU9uOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgICAgIG9uVG9nZ2xlT2ZmOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgfTtcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS10b2dnbGVidXR0b24nLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBUb2dnbGVzIHRoZSBidXR0b24gdG8gdGhlICdvbicgc3RhdGUuXHJcbiAgICAgKi9cclxuICAgIFRvZ2dsZUJ1dHRvbi5wcm90b3R5cGUub24gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuaXNPZmYoKSkge1xyXG4gICAgICAgICAgICB0aGlzLm9uU3RhdGUgPSB0cnVlO1xyXG4gICAgICAgICAgICB0aGlzLmdldERvbUVsZW1lbnQoKS5yZW1vdmVDbGFzcyh0aGlzLnByZWZpeENzcyhUb2dnbGVCdXR0b24uQ0xBU1NfT0ZGKSk7XHJcbiAgICAgICAgICAgIHRoaXMuZ2V0RG9tRWxlbWVudCgpLmFkZENsYXNzKHRoaXMucHJlZml4Q3NzKFRvZ2dsZUJ1dHRvbi5DTEFTU19PTikpO1xyXG4gICAgICAgICAgICB0aGlzLm9uVG9nZ2xlRXZlbnQoKTtcclxuICAgICAgICAgICAgdGhpcy5vblRvZ2dsZU9uRXZlbnQoKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBUb2dnbGVzIHRoZSBidXR0b24gdG8gdGhlICdvZmYnIHN0YXRlLlxyXG4gICAgICovXHJcbiAgICBUb2dnbGVCdXR0b24ucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAodGhpcy5pc09uKCkpIHtcclxuICAgICAgICAgICAgdGhpcy5vblN0YXRlID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHRoaXMuZ2V0RG9tRWxlbWVudCgpLnJlbW92ZUNsYXNzKHRoaXMucHJlZml4Q3NzKFRvZ2dsZUJ1dHRvbi5DTEFTU19PTikpO1xyXG4gICAgICAgICAgICB0aGlzLmdldERvbUVsZW1lbnQoKS5hZGRDbGFzcyh0aGlzLnByZWZpeENzcyhUb2dnbGVCdXR0b24uQ0xBU1NfT0ZGKSk7XHJcbiAgICAgICAgICAgIHRoaXMub25Ub2dnbGVFdmVudCgpO1xyXG4gICAgICAgICAgICB0aGlzLm9uVG9nZ2xlT2ZmRXZlbnQoKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBUb2dnbGUgdGhlIGJ1dHRvbiAnb24nIGlmIGl0IGlzICdvZmYnLCBvciAnb2ZmJyBpZiBpdCBpcyAnb24nLlxyXG4gICAgICovXHJcbiAgICBUb2dnbGVCdXR0b24ucHJvdG90eXBlLnRvZ2dsZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAodGhpcy5pc09uKCkpIHtcclxuICAgICAgICAgICAgdGhpcy5vZmYoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMub24oKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBDaGVja3MgaWYgdGhlIHRvZ2dsZSBidXR0b24gaXMgaW4gdGhlICdvbicgc3RhdGUuXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiBidXR0b24gaXMgJ29uJywgZmFsc2UgaWYgJ29mZidcclxuICAgICAqL1xyXG4gICAgVG9nZ2xlQnV0dG9uLnByb3RvdHlwZS5pc09uID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm9uU3RhdGU7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBDaGVja3MgaWYgdGhlIHRvZ2dsZSBidXR0b24gaXMgaW4gdGhlICdvZmYnIHN0YXRlLlxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWYgYnV0dG9uIGlzICdvZmYnLCBmYWxzZSBpZiAnb24nXHJcbiAgICAgKi9cclxuICAgIFRvZ2dsZUJ1dHRvbi5wcm90b3R5cGUuaXNPZmYgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuICF0aGlzLmlzT24oKTtcclxuICAgIH07XHJcbiAgICBUb2dnbGVCdXR0b24ucHJvdG90eXBlLm9uQ2xpY2tFdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLm9uQ2xpY2tFdmVudC5jYWxsKHRoaXMpO1xyXG4gICAgICAgIC8vIEZpcmUgdGhlIHRvZ2dsZSBldmVudCB0b2dldGhlciB3aXRoIHRoZSBjbGljayBldmVudFxyXG4gICAgICAgIC8vICh0aGV5IGFyZSB0ZWNobmljYWxseSB0aGUgc2FtZSwgb25seSB0aGUgc2VtYW50aWNzIGFyZSBkaWZmZXJlbnQpXHJcbiAgICAgICAgdGhpcy5vblRvZ2dsZUV2ZW50KCk7XHJcbiAgICB9O1xyXG4gICAgVG9nZ2xlQnV0dG9uLnByb3RvdHlwZS5vblRvZ2dsZUV2ZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMudG9nZ2xlQnV0dG9uRXZlbnRzLm9uVG9nZ2xlLmRpc3BhdGNoKHRoaXMpO1xyXG4gICAgfTtcclxuICAgIFRvZ2dsZUJ1dHRvbi5wcm90b3R5cGUub25Ub2dnbGVPbkV2ZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMudG9nZ2xlQnV0dG9uRXZlbnRzLm9uVG9nZ2xlT24uZGlzcGF0Y2godGhpcyk7XHJcbiAgICB9O1xyXG4gICAgVG9nZ2xlQnV0dG9uLnByb3RvdHlwZS5vblRvZ2dsZU9mZkV2ZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMudG9nZ2xlQnV0dG9uRXZlbnRzLm9uVG9nZ2xlT2ZmLmRpc3BhdGNoKHRoaXMpO1xyXG4gICAgfTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShUb2dnbGVCdXR0b24ucHJvdG90eXBlLCBcIm9uVG9nZ2xlXCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXRzIHRoZSBldmVudCB0aGF0IGlzIGZpcmVkIHdoZW4gdGhlIGJ1dHRvbiBpcyB0b2dnbGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtFdmVudDxUb2dnbGVCdXR0b248Q29uZmlnPiwgTm9BcmdzPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9nZ2xlQnV0dG9uRXZlbnRzLm9uVG9nZ2xlLmdldEV2ZW50KCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoVG9nZ2xlQnV0dG9uLnByb3RvdHlwZSwgXCJvblRvZ2dsZU9uXCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXRzIHRoZSBldmVudCB0aGF0IGlzIGZpcmVkIHdoZW4gdGhlIGJ1dHRvbiBpcyB0b2dnbGVkICdvbicuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50PFRvZ2dsZUJ1dHRvbjxDb25maWc+LCBOb0FyZ3M+fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy50b2dnbGVCdXR0b25FdmVudHMub25Ub2dnbGVPbi5nZXRFdmVudCgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFRvZ2dsZUJ1dHRvbi5wcm90b3R5cGUsIFwib25Ub2dnbGVPZmZcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldHMgdGhlIGV2ZW50IHRoYXQgaXMgZmlyZWQgd2hlbiB0aGUgYnV0dG9uIGlzIHRvZ2dsZWQgJ29mZicuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50PFRvZ2dsZUJ1dHRvbjxDb25maWc+LCBOb0FyZ3M+fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy50b2dnbGVCdXR0b25FdmVudHMub25Ub2dnbGVPZmYuZ2V0RXZlbnQoKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIHJldHVybiBUb2dnbGVCdXR0b247XHJcbn0oYnV0dG9uXzEuQnV0dG9uKSk7XHJcblRvZ2dsZUJ1dHRvbi5DTEFTU19PTiA9ICdvbic7XHJcblRvZ2dsZUJ1dHRvbi5DTEFTU19PRkYgPSAnb2ZmJztcclxuZXhwb3J0cy5Ub2dnbGVCdXR0b24gPSBUb2dnbGVCdXR0b247XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy90b2dnbGVidXR0b24udHNcbi8vIG1vZHVsZSBpZCA9IDhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwibW9kdWxlLmV4cG9ydHMgPSBhbmd1bGFyO1xuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIGV4dGVybmFsIFwiYW5ndWxhclwiXG4vLyBtb2R1bGUgaWQgPSA5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbi8vIFRPRE8gY2hhbmdlIHRvIGludGVybmFsIChub3QgZXhwb3J0ZWQpIGNsYXNzLCBob3cgdG8gdXNlIGluIG90aGVyIGZpbGVzP1xyXG4vKipcclxuICogRXhlY3V0ZXMgYSBjYWxsYmFjayBhZnRlciBhIHNwZWNpZmllZCBhbW91bnQgb2YgdGltZSwgb3B0aW9uYWxseSByZXBlYXRlZGx5IHVudGlsIHN0b3BwZWQuXHJcbiAqL1xyXG52YXIgVGltZW91dCA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBuZXcgdGltZW91dCBjYWxsYmFjayBoYW5kbGVyLlxyXG4gICAgICogQHBhcmFtIGRlbGF5IHRoZSBkZWxheSBpbiBtaWxsaXNlY29uZHMgYWZ0ZXIgd2hpY2ggdGhlIGNhbGxiYWNrIHNob3VsZCBiZSBleGVjdXRlZFxyXG4gICAgICogQHBhcmFtIGNhbGxiYWNrIHRoZSBjYWxsYmFjayB0byBleGVjdXRlIGFmdGVyIHRoZSBkZWxheSB0aW1lXHJcbiAgICAgKiBAcGFyYW0gcmVwZWF0IGlmIHRydWUsIGNhbGwgdGhlIGNhbGxiYWNrIHJlcGVhdGVkbHkgaW4gZGVsYXkgaW50ZXJ2YWxzXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIFRpbWVvdXQoZGVsYXksIGNhbGxiYWNrLCByZXBlYXQpIHtcclxuICAgICAgICBpZiAocmVwZWF0ID09PSB2b2lkIDApIHsgcmVwZWF0ID0gZmFsc2U7IH1cclxuICAgICAgICB0aGlzLmRlbGF5ID0gZGVsYXk7XHJcbiAgICAgICAgdGhpcy5jYWxsYmFjayA9IGNhbGxiYWNrO1xyXG4gICAgICAgIHRoaXMucmVwZWF0ID0gcmVwZWF0O1xyXG4gICAgICAgIHRoaXMudGltZW91dEhhbmRsZSA9IDA7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIFN0YXJ0cyB0aGUgdGltZW91dCBhbmQgY2FsbHMgdGhlIGNhbGxiYWNrIHdoZW4gdGhlIHRpbWVvdXQgZGVsYXkgaGFzIHBhc3NlZC5cclxuICAgICAqIEByZXR1cm5zIHtUaW1lb3V0fSB0aGUgY3VycmVudCB0aW1lb3V0IChzbyB0aGUgc3RhcnQgY2FsbCBjYW4gYmUgY2hhaW5lZCB0byB0aGUgY29uc3RydWN0b3IpXHJcbiAgICAgKi9cclxuICAgIFRpbWVvdXQucHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMucmVzZXQoKTtcclxuICAgICAgICByZXR1cm4gdGhpcztcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIENsZWFycyB0aGUgdGltZW91dC4gVGhlIGNhbGxiYWNrIHdpbGwgbm90IGJlIGNhbGxlZCBpZiBjbGVhciBpcyBjYWxsZWQgZHVyaW5nIHRoZSB0aW1lb3V0LlxyXG4gICAgICovXHJcbiAgICBUaW1lb3V0LnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBjbGVhclRpbWVvdXQodGhpcy50aW1lb3V0SGFuZGxlKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJlc2V0cyB0aGUgcGFzc2VkIHRpbWVvdXQgZGVsYXkgdG8gemVyby4gQ2FuIGJlIHVzZWQgdG8gZGVmZXIgdGhlIGNhbGxpbmcgb2YgdGhlIGNhbGxiYWNrLlxyXG4gICAgICovXHJcbiAgICBUaW1lb3V0LnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciBsYXN0U2NoZWR1bGVUaW1lID0gMDtcclxuICAgICAgICB2YXIgZGVsYXlBZGp1c3QgPSAwO1xyXG4gICAgICAgIHRoaXMuY2xlYXIoKTtcclxuICAgICAgICB2YXIgaW50ZXJuYWxDYWxsYmFjayA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMuY2FsbGJhY2soKTtcclxuICAgICAgICAgICAgaWYgKF90aGlzLnJlcGVhdCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIG5vdyA9IERhdGUubm93KCk7XHJcbiAgICAgICAgICAgICAgICAvLyBUaGUgdGltZSBvZiBvbmUgaXRlcmF0aW9uIGZyb20gc2NoZWR1bGluZyB0byBleGVjdXRpbmcgdGhlIGNhbGxiYWNrICh1c3VhbGx5IGEgYml0IGxvbmdlciB0aGFuIHRoZSBkZWxheVxyXG4gICAgICAgICAgICAgICAgLy8gdGltZSlcclxuICAgICAgICAgICAgICAgIHZhciBkZWx0YSA9IG5vdyAtIGxhc3RTY2hlZHVsZVRpbWU7XHJcbiAgICAgICAgICAgICAgICAvLyBDYWxjdWxhdGUgdGhlIGRlbGF5IGFkanVzdG1lbnQgZm9yIHRoZSBuZXh0IHNjaGVkdWxlIHRvIGtlZXAgYSBzdGVhZHkgZGVsYXkgaW50ZXJ2YWwgb3ZlciB0aW1lXHJcbiAgICAgICAgICAgICAgICBkZWxheUFkanVzdCA9IF90aGlzLmRlbGF5IC0gZGVsdGEgKyBkZWxheUFkanVzdDtcclxuICAgICAgICAgICAgICAgIGxhc3RTY2hlZHVsZVRpbWUgPSBub3c7XHJcbiAgICAgICAgICAgICAgICAvLyBTY2hlZHVsZSBuZXh0IGV4ZWN1dGlvbiBieSB0aGUgYWRqdXN0ZWQgZGVsYXlcclxuICAgICAgICAgICAgICAgIF90aGlzLnRpbWVvdXRIYW5kbGUgPSB3aW5kb3cuc2V0VGltZW91dChpbnRlcm5hbENhbGxiYWNrLCBfdGhpcy5kZWxheSArIGRlbGF5QWRqdXN0KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgbGFzdFNjaGVkdWxlVGltZSA9IERhdGUubm93KCk7XHJcbiAgICAgICAgdGhpcy50aW1lb3V0SGFuZGxlID0gd2luZG93LnNldFRpbWVvdXQoaW50ZXJuYWxDYWxsYmFjaywgdGhpcy5kZWxheSk7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFRpbWVvdXQ7XHJcbn0oKSk7XHJcbmV4cG9ydHMuVGltZW91dCA9IFRpbWVvdXQ7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvdGltZW91dC50c1xuLy8gbW9kdWxlIGlkID0gMTBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIEJyb3dzZXJVdGlscztcclxuKGZ1bmN0aW9uIChCcm93c2VyVXRpbHMpIHtcclxuICAgIC8vIGlzTW9iaWxlIG9ubHkgbmVlZHMgdG8gYmUgZXZhbHVhdGVkIG9uY2UgKGl0IGNhbm5vdCBjaGFuZ2UgZHVyaW5nIGEgYnJvd3NlciBzZXNzaW9uKVxyXG4gICAgLy8gTW9iaWxlIGRldGVjdGlvbiBhY2NvcmRpbmcgdG8gTW96aWxsYSByZWNvbW1lbmRhdGlvbjogXCJJbiBzdW1tYXJ5LCB3ZSByZWNvbW1lbmQgbG9va2luZyBmb3IgdGhlIHN0cmluZyDigJxNb2Jp4oCdXHJcbiAgICAvLyBhbnl3aGVyZSBpbiB0aGUgVXNlciBBZ2VudCB0byBkZXRlY3QgYSBtb2JpbGUgZGV2aWNlLlwiXHJcbiAgICAvLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9IVFRQL0Jyb3dzZXJfZGV0ZWN0aW9uX3VzaW5nX3RoZV91c2VyX2FnZW50XHJcbiAgICBCcm93c2VyVXRpbHMuaXNNb2JpbGUgPSBuYXZpZ2F0b3IgJiYgbmF2aWdhdG9yLnVzZXJBZ2VudCAmJiAvTW9iaS8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcclxuICAgIEJyb3dzZXJVdGlscy5pc0Nocm9tZSA9IG5hdmlnYXRvciAmJiBuYXZpZ2F0b3IudXNlckFnZW50ICYmIC9DaHJvbWUvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XHJcbiAgICBCcm93c2VyVXRpbHMuaXNBbmRyb2lkID0gbmF2aWdhdG9yICYmIG5hdmlnYXRvci51c2VyQWdlbnQgJiYgL0FuZHJvaWQvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XHJcbn0pKEJyb3dzZXJVdGlscyA9IGV4cG9ydHMuQnJvd3NlclV0aWxzIHx8IChleHBvcnRzLkJyb3dzZXJVdGlscyA9IHt9KSk7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvYnJvd3NlcnV0aWxzLnRzXG4vLyBtb2R1bGUgaWQgPSAxMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIHRvZ2dsZWJ1dHRvbl8xID0gcmVxdWlyZShcIi4vdG9nZ2xlYnV0dG9uXCIpO1xyXG52YXIgcGxheWVydXRpbHNfMSA9IHJlcXVpcmUoXCIuLi9wbGF5ZXJ1dGlsc1wiKTtcclxuLyoqXHJcbiAqIEEgYnV0dG9uIHRoYXQgdG9nZ2xlcyBiZXR3ZWVuIHBsYXliYWNrIGFuZCBwYXVzZS5cclxuICovXHJcbnZhciBQbGF5YmFja1RvZ2dsZUJ1dHRvbiA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoUGxheWJhY2tUb2dnbGVCdXR0b24sIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBQbGF5YmFja1RvZ2dsZUJ1dHRvbihjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktcGxheWJhY2t0b2dnbGVidXR0b24nLFxyXG4gICAgICAgICAgICB0ZXh0OiAnUGxheS9QYXVzZScsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBQbGF5YmFja1RvZ2dsZUJ1dHRvbi5wcm90b3R5cGUuY29uZmlndXJlID0gZnVuY3Rpb24gKHBsYXllciwgdWltYW5hZ2VyLCBoYW5kbGVDbGlja0V2ZW50KSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICBpZiAoaGFuZGxlQ2xpY2tFdmVudCA9PT0gdm9pZCAwKSB7IGhhbmRsZUNsaWNrRXZlbnQgPSB0cnVlOyB9XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jb25maWd1cmUuY2FsbCh0aGlzLCBwbGF5ZXIsIHVpbWFuYWdlcik7XHJcbiAgICAgICAgdmFyIGlzU2Vla2luZyA9IGZhbHNlO1xyXG4gICAgICAgIC8vIEhhbmRsZXIgdG8gdXBkYXRlIGJ1dHRvbiBzdGF0ZSBiYXNlZCBvbiBwbGF5ZXIgc3RhdGVcclxuICAgICAgICB2YXIgcGxheWJhY2tTdGF0ZUhhbmRsZXIgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgLy8gSWYgdGhlIFVJIGlzIGN1cnJlbnRseSBzZWVraW5nLCBwbGF5YmFjayBpcyB0ZW1wb3JhcmlseSBzdG9wcGVkIGJ1dCB0aGUgYnV0dG9ucyBzaG91bGRcclxuICAgICAgICAgICAgLy8gbm90IHJlZmxlY3QgdGhhdCBhbmQgc3RheSBhcy1pcyAoZS5nIGluZGljYXRlIHBsYXliYWNrIHdoaWxlIHNlZWtpbmcpLlxyXG4gICAgICAgICAgICBpZiAoaXNTZWVraW5nKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHBsYXllci5pc1BsYXlpbmcoKSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMub24oKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLm9mZigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvLyBDYWxsIGhhbmRsZXIgdXBvbiB0aGVzZSBldmVudHNcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9QTEFZLCBwbGF5YmFja1N0YXRlSGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUEFVU0VELCBwbGF5YmFja1N0YXRlSGFuZGxlcik7XHJcbiAgICAgICAgLy8gd2hlbiBwbGF5YmFjayBmaW5pc2hlcywgcGxheWVyIHR1cm5zIHRvIHBhdXNlZCBtb2RlXHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUExBWUJBQ0tfRklOSVNIRUQsIHBsYXliYWNrU3RhdGVIYW5kbGVyKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9DQVNUX1NUQVJURUQsIHBsYXliYWNrU3RhdGVIYW5kbGVyKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9DQVNUX1BMQVlJTkcsIHBsYXliYWNrU3RhdGVIYW5kbGVyKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9DQVNUX1BBVVNFRCwgcGxheWJhY2tTdGF0ZUhhbmRsZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0NBU1RfUExBWUJBQ0tfRklOSVNIRUQsIHBsYXliYWNrU3RhdGVIYW5kbGVyKTtcclxuICAgICAgICAvLyBEZXRlY3QgYWJzZW5jZSBvZiB0aW1lc2hpZnRpbmcgb24gbGl2ZSBzdHJlYW1zIGFuZCBhZGQgdGFnZ2luZyBjbGFzcyB0byBjb252ZXJ0IGJ1dHRvbiBpY29ucyB0byBwbGF5L3N0b3BcclxuICAgICAgICB2YXIgdGltZVNoaWZ0RGV0ZWN0b3IgPSBuZXcgcGxheWVydXRpbHNfMS5QbGF5ZXJVdGlscy5UaW1lU2hpZnRBdmFpbGFiaWxpdHlEZXRlY3RvcihwbGF5ZXIpO1xyXG4gICAgICAgIHRpbWVTaGlmdERldGVjdG9yLm9uVGltZVNoaWZ0QXZhaWxhYmlsaXR5Q2hhbmdlZC5zdWJzY3JpYmUoZnVuY3Rpb24gKHNlbmRlciwgYXJncykge1xyXG4gICAgICAgICAgICBpZiAoIWFyZ3MudGltZVNoaWZ0QXZhaWxhYmxlKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5nZXREb21FbGVtZW50KCkuYWRkQ2xhc3MoX3RoaXMucHJlZml4Q3NzKFBsYXliYWNrVG9nZ2xlQnV0dG9uLkNMQVNTX1NUT1BUT0dHTEUpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmdldERvbUVsZW1lbnQoKS5yZW1vdmVDbGFzcyhfdGhpcy5wcmVmaXhDc3MoUGxheWJhY2tUb2dnbGVCdXR0b24uQ0xBU1NfU1RPUFRPR0dMRSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGltZVNoaWZ0RGV0ZWN0b3IuZGV0ZWN0KCk7IC8vIEluaXRpYWwgZGV0ZWN0aW9uXHJcbiAgICAgICAgaWYgKGhhbmRsZUNsaWNrRXZlbnQpIHtcclxuICAgICAgICAgICAgLy8gQ29udHJvbCBwbGF5ZXIgYnkgYnV0dG9uIGV2ZW50c1xyXG4gICAgICAgICAgICAvLyBXaGVuIGEgYnV0dG9uIGV2ZW50IHRyaWdnZXJzIGEgcGxheWVyIEFQSSBjYWxsLCBldmVudHMgYXJlIGZpcmVkIHdoaWNoIGluIHR1cm4gY2FsbCB0aGUgZXZlbnQgaGFuZGxlclxyXG4gICAgICAgICAgICAvLyBhYm92ZSB0aGF0IHVwZGF0ZWQgdGhlIGJ1dHRvbiBzdGF0ZS5cclxuICAgICAgICAgICAgdGhpcy5vbkNsaWNrLnN1YnNjcmliZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocGxheWVyLmlzUGxheWluZygpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGxheWVyLnBhdXNlKCd1aScpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGxheWVyLnBsYXkoJ3VpJyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBUcmFjayBVSSBzZWVraW5nIHN0YXR1c1xyXG4gICAgICAgIHVpbWFuYWdlci5vblNlZWsuc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaXNTZWVraW5nID0gdHJ1ZTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB1aW1hbmFnZXIub25TZWVrZWQuc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaXNTZWVraW5nID0gZmFsc2U7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gU3RhcnR1cCBpbml0XHJcbiAgICAgICAgcGxheWJhY2tTdGF0ZUhhbmRsZXIobnVsbCk7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFBsYXliYWNrVG9nZ2xlQnV0dG9uO1xyXG59KHRvZ2dsZWJ1dHRvbl8xLlRvZ2dsZUJ1dHRvbikpO1xyXG5QbGF5YmFja1RvZ2dsZUJ1dHRvbi5DTEFTU19TVE9QVE9HR0xFID0gJ3N0b3B0b2dnbGUnO1xyXG5leHBvcnRzLlBsYXliYWNrVG9nZ2xlQnV0dG9uID0gUGxheWJhY2tUb2dnbGVCdXR0b247XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9wbGF5YmFja3RvZ2dsZWJ1dHRvbi50c1xuLy8gbW9kdWxlIGlkID0gMTJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBjb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudFwiKTtcclxudmFyIGRvbV8xID0gcmVxdWlyZShcIi4uL2RvbVwiKTtcclxudmFyIGV2ZW50ZGlzcGF0Y2hlcl8xID0gcmVxdWlyZShcIi4uL2V2ZW50ZGlzcGF0Y2hlclwiKTtcclxudmFyIHRpbWVvdXRfMSA9IHJlcXVpcmUoXCIuLi90aW1lb3V0XCIpO1xyXG52YXIgcGxheWVydXRpbHNfMSA9IHJlcXVpcmUoXCIuLi9wbGF5ZXJ1dGlsc1wiKTtcclxuLyoqXHJcbiAqIEEgc2VlayBiYXIgdG8gc2VlayB3aXRoaW4gdGhlIHBsYXllcidzIG1lZGlhLiBJdCBkaXNwbGF5cyB0aGUgY3VycmVudCBwbGF5YmFjayBwb3NpdGlvbiwgYW1vdW50IG9mIGJ1ZmZlZCBkYXRhLCBzZWVrXHJcbiAqIHRhcmdldCwgYW5kIGtlZXBzIHN0YXR1cyBhYm91dCBhbiBvbmdvaW5nIHNlZWsuXHJcbiAqXHJcbiAqIFRoZSBzZWVrIGJhciBkaXNwbGF5cyBkaWZmZXJlbnQgJ2JhcnMnOlxyXG4gKiAgLSB0aGUgcGxheWJhY2sgcG9zaXRpb24sIGkuZS4gdGhlIHBvc2l0aW9uIGluIHRoZSBtZWRpYSBhdCB3aGljaCB0aGUgcGxheWVyIGN1cnJlbnQgcGxheWJhY2sgcG9pbnRlciBpcyBwb3NpdGlvbmVkXHJcbiAqICAtIHRoZSBidWZmZXIgcG9zaXRpb24sIHdoaWNoIHVzdWFsbHkgaXMgdGhlIHBsYXliYWNrIHBvc2l0aW9uIHBsdXMgdGhlIHRpbWUgc3BhbiB0aGF0IGlzIGFscmVhZHkgYnVmZmVyZWQgYWhlYWRcclxuICogIC0gdGhlIHNlZWsgcG9zaXRpb24sIHVzZWQgdG8gcHJldmlldyB0byB3aGVyZSBpbiB0aGUgdGltZWxpbmUgYSBzZWVrIHdpbGwganVtcCB0b1xyXG4gKi9cclxudmFyIFNlZWtCYXIgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKFNlZWtCYXIsIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBTZWVrQmFyKGNvbmZpZykge1xyXG4gICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBCdWZmZXIgb2YgdGhlIHRoZSBjdXJyZW50IHBsYXliYWNrIHBvc2l0aW9uLiBUaGUgcG9zaXRpb24gbXVzdCBiZSBidWZmZXJlZCBpbiBjYXNlIHRoZSBlbGVtZW50XHJcbiAgICAgICAgICogbmVlZHMgdG8gYmUgcmVmcmVzaGVkIHdpdGgge0BsaW5rICNyZWZyZXNoUGxheWJhY2tQb3NpdGlvbn0uXHJcbiAgICAgICAgICogQHR5cGUge251bWJlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBfdGhpcy5wbGF5YmFja1Bvc2l0aW9uUGVyY2VudGFnZSA9IDA7XHJcbiAgICAgICAgLy8gaHR0cHM6Ly9oYWNrcy5tb3ppbGxhLm9yZy8yMDEzLzA0L2RldGVjdGluZy10b3VjaC1pdHMtdGhlLXdoeS1ub3QtdGhlLWhvdy9cclxuICAgICAgICBfdGhpcy50b3VjaFN1cHBvcnRlZCA9ICgnb250b3VjaHN0YXJ0JyBpbiB3aW5kb3cpO1xyXG4gICAgICAgIF90aGlzLnNlZWtCYXJFdmVudHMgPSB7XHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBGaXJlZCB3aGVuIGEgc2NydWJiaW5nIHNlZWsgb3BlcmF0aW9uIGlzIHN0YXJ0ZWQuXHJcbiAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICBvblNlZWs6IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKSxcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEZpcmVkIGR1cmluZyBhIHNjcnViYmluZyBzZWVrIHRvIGluZGljYXRlIHRoYXQgdGhlIHNlZWsgcHJldmlldyAoaS5lLiB0aGUgdmlkZW8gZnJhbWUpIHNob3VsZCBiZSB1cGRhdGVkLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgb25TZWVrUHJldmlldzogbmV3IGV2ZW50ZGlzcGF0Y2hlcl8xLkV2ZW50RGlzcGF0Y2hlcigpLFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogRmlyZWQgd2hlbiBhIHNjcnViYmluZyBzZWVrIGhhcyBmaW5pc2hlZCBvciB3aGVuIGEgZGlyZWN0IHNlZWsgaXMgaXNzdWVkLlxyXG4gICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgb25TZWVrZWQ6IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKSxcclxuICAgICAgICB9O1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLXNlZWtiYXInLFxyXG4gICAgICAgICAgICB2ZXJ0aWNhbDogZmFsc2UsXHJcbiAgICAgICAgICAgIHNtb290aFBsYXliYWNrUG9zaXRpb25VcGRhdGVJbnRlcnZhbE1zOiA1MCxcclxuICAgICAgICAgICAgaGlkZUluTGl2ZVBsYXliYWNrOiB0cnVlLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgX3RoaXMubGFiZWwgPSBfdGhpcy5jb25maWcubGFiZWw7XHJcbiAgICAgICAgX3RoaXMudGltZWxpbmVNYXJrZXJzID0gW107XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmluaXRpYWxpemUuY2FsbCh0aGlzKTtcclxuICAgICAgICBpZiAodGhpcy5oYXNMYWJlbCgpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZ2V0TGFiZWwoKS5pbml0aWFsaXplKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIFNlZWtCYXIucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlciwgY29uZmlndXJlU2Vlaykge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgaWYgKGNvbmZpZ3VyZVNlZWsgPT09IHZvaWQgMCkgeyBjb25maWd1cmVTZWVrID0gdHJ1ZTsgfVxyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY29uZmlndXJlLmNhbGwodGhpcywgcGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIC8vIGxldCBjb25maWcgPSA8U2Vla0JhckNvbmZpZz50aGlzLmdldENvbmZpZygpO1xyXG4gICAgICAgIGlmICghY29uZmlndXJlU2Vlaykge1xyXG4gICAgICAgICAgICAvLyBUaGUgY29uZmlndXJlU2VlayBmbGFnIGNhbiBiZSB1c2VkIGJ5IHN1YmNsYXNzZXMgdG8gZGlzYWJsZSBjb25maWd1cmF0aW9uIGFzIHNlZWsgYmFyLiBFLmcuIHRoZSB2b2x1bWVcclxuICAgICAgICAgICAgLy8gc2xpZGVyIGlzIHJldXNpbmcgdGhpcyBjb21wb25lbnQgYnV0IGFkZHMgaXRzIG93biBmdW5jdGlvbmFsaXR5LCBhbmQgZG9lcyBub3QgbmVlZCB0aGUgc2VlayBmdW5jdGlvbmFsaXR5LlxyXG4gICAgICAgICAgICAvLyBUaGlzIGlzIGFjdHVhbGx5IGEgaGFjaywgdGhlIHByb3BlciBzb2x1dGlvbiB3b3VsZCBiZSBmb3IgYm90aCBzZWVrIGJhciBhbmQgdm9sdW1lIHNsaWRlcnMgdG8gZXh0ZW5kXHJcbiAgICAgICAgICAgIC8vIGEgY29tbW9uIGJhc2Ugc2xpZGVyIGNvbXBvbmVudCBhbmQgaW1wbGVtZW50IHRoZWlyIGZ1bmN0aW9uYWxpdHkgdGhlcmUuXHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIHBsYXliYWNrTm90SW5pdGlhbGl6ZWQgPSB0cnVlO1xyXG4gICAgICAgIHZhciBpc1BsYXlpbmcgPSBmYWxzZTtcclxuICAgICAgICB2YXIgaXNTZWVraW5nID0gZmFsc2U7XHJcbiAgICAgICAgLy8gVXBkYXRlIHBsYXliYWNrIGFuZCBidWZmZXIgcG9zaXRpb25zXHJcbiAgICAgICAgdmFyIHBsYXliYWNrUG9zaXRpb25IYW5kbGVyID0gZnVuY3Rpb24gKGV2ZW50LCBmb3JjZVVwZGF0ZSkge1xyXG4gICAgICAgICAgICBpZiAoZXZlbnQgPT09IHZvaWQgMCkgeyBldmVudCA9IG51bGw7IH1cclxuICAgICAgICAgICAgaWYgKGZvcmNlVXBkYXRlID09PSB2b2lkIDApIHsgZm9yY2VVcGRhdGUgPSBmYWxzZTsgfVxyXG4gICAgICAgICAgICAvLyBPbmNlIHRoaXMgaGFuZGxlciBvcyBjYWxsZWQsIHBsYXliYWNrIGhhcyBiZWVuIHN0YXJ0ZWQgYW5kIHdlIHNldCB0aGUgZmxhZyB0byBmYWxzZVxyXG4gICAgICAgICAgICBwbGF5YmFja05vdEluaXRpYWxpemVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGlmIChpc1NlZWtpbmcpIHtcclxuICAgICAgICAgICAgICAgIC8vIFdlIGNhdWdodCBhIHNlZWsgcHJldmlldyBzZWVrLCBkbyBub3QgdXBkYXRlIHRoZSBzZWVrYmFyXHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHBsYXllci5pc0xpdmUoKSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHBsYXllci5nZXRNYXhUaW1lU2hpZnQoKSA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoaXMgY2FzZSBtdXN0IGJlIGV4cGxpY2l0bHkgaGFuZGxlZCB0byBhdm9pZCBkaXZpc2lvbiBieSB6ZXJvXHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0UGxheWJhY2tQb3NpdGlvbigxMDApO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHBsYXliYWNrUG9zaXRpb25QZXJjZW50YWdlID0gMTAwIC0gKDEwMCAvIHBsYXllci5nZXRNYXhUaW1lU2hpZnQoKSAqIHBsYXllci5nZXRUaW1lU2hpZnQoKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0UGxheWJhY2tQb3NpdGlvbihwbGF5YmFja1Bvc2l0aW9uUGVyY2VudGFnZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBBbHdheXMgc2hvdyBmdWxsIGJ1ZmZlciBmb3IgbGl2ZSBzdHJlYW1zXHJcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRCdWZmZXJQb3NpdGlvbigxMDApO1xyXG4gICAgICAgICAgICAgICAgLy8gSGlkZSBTZWVrQmFyIGlmIHJlcXVpcmVkLlxyXG4gICAgICAgICAgICAgICAgLy8gaWYgKGNvbmZpZy5oaWRlSW5MaXZlUGxheWJhY2spIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmhpZGUoKTtcclxuICAgICAgICAgICAgICAgIC8vIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHZhciBwbGF5YmFja1Bvc2l0aW9uUGVyY2VudGFnZSA9IDEwMCAvIHBsYXllci5nZXREdXJhdGlvbigpICogcGxheWVyLmdldEN1cnJlbnRUaW1lKCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgdmlkZW9CdWZmZXJMZW5ndGggPSBwbGF5ZXIuZ2V0VmlkZW9CdWZmZXJMZW5ndGgoKTtcclxuICAgICAgICAgICAgICAgIHZhciBhdWRpb0J1ZmZlckxlbmd0aCA9IHBsYXllci5nZXRBdWRpb0J1ZmZlckxlbmd0aCgpO1xyXG4gICAgICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBidWZmZXIgbGVuZ3RoIHdoaWNoIGlzIHRoZSBzbWFsbGVyIGxlbmd0aCBvZiB0aGUgYXVkaW8gYW5kIHZpZGVvIGJ1ZmZlcnMuIElmIG9uZSBvZiB0aGVzZVxyXG4gICAgICAgICAgICAgICAgLy8gYnVmZmVycyBpcyBub3QgYXZhaWxhYmxlLCB3ZSBzZXQgaXQncyB2YWx1ZSB0byBNQVhfVkFMVUUgdG8gbWFrZSBzdXJlIHRoYXQgdGhlIG90aGVyIHJlYWwgdmFsdWUgaXMgdGFrZW5cclxuICAgICAgICAgICAgICAgIC8vIGFzIHRoZSBidWZmZXIgbGVuZ3RoLlxyXG4gICAgICAgICAgICAgICAgdmFyIGJ1ZmZlckxlbmd0aCA9IE1hdGgubWluKHZpZGVvQnVmZmVyTGVuZ3RoICE9IG51bGwgPyB2aWRlb0J1ZmZlckxlbmd0aCA6IE51bWJlci5NQVhfVkFMVUUsIGF1ZGlvQnVmZmVyTGVuZ3RoICE9IG51bGwgPyBhdWRpb0J1ZmZlckxlbmd0aCA6IE51bWJlci5NQVhfVkFMVUUpO1xyXG4gICAgICAgICAgICAgICAgLy8gSWYgYm90aCBidWZmZXIgbGVuZ3RocyBhcmUgbWlzc2luZywgd2Ugc2V0IHRoZSBidWZmZXIgbGVuZ3RoIHRvIHplcm9cclxuICAgICAgICAgICAgICAgIGlmIChidWZmZXJMZW5ndGggPT09IE51bWJlci5NQVhfVkFMVUUpIHtcclxuICAgICAgICAgICAgICAgICAgICBidWZmZXJMZW5ndGggPSAwO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdmFyIGJ1ZmZlclBlcmNlbnRhZ2UgPSAxMDAgLyBwbGF5ZXIuZ2V0RHVyYXRpb24oKSAqIGJ1ZmZlckxlbmd0aDtcclxuICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSBwbGF5YmFjayBwb3NpdGlvbiBvbmx5IGluIHBhdXNlZCBzdGF0ZSBvciBpbiB0aGUgaW5pdGlhbCBzdGFydHVwIHN0YXRlIHdoZXJlIHBsYXllciBpcyBuZWl0aGVyXHJcbiAgICAgICAgICAgICAgICAvLyBwYXVzZWQgbm9yIHBsYXlpbmcuIFBsYXliYWNrIHVwZGF0ZXMgYXJlIGhhbmRsZWQgaW4gdGhlIFRpbWVvdXQgYmVsb3cuXHJcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMuY29uZmlnLnNtb290aFBsYXliYWNrUG9zaXRpb25VcGRhdGVJbnRlcnZhbE1zID09PSBTZWVrQmFyLlNNT09USF9QTEFZQkFDS19QT1NJVElPTl9VUERBVEVfRElTQUJMRURcclxuICAgICAgICAgICAgICAgICAgICB8fCBmb3JjZVVwZGF0ZSB8fCBwbGF5ZXIuaXNQYXVzZWQoKSB8fCAocGxheWVyLmlzUGF1c2VkKCkgPT09IHBsYXllci5pc1BsYXlpbmcoKSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy5zZXRQbGF5YmFja1Bvc2l0aW9uKHBsYXliYWNrUG9zaXRpb25QZXJjZW50YWdlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIF90aGlzLnNldEJ1ZmZlclBvc2l0aW9uKHBsYXliYWNrUG9zaXRpb25QZXJjZW50YWdlICsgYnVmZmVyUGVyY2VudGFnZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIFVwZGF0ZSBzZWVrYmFyIHVwb24gdGhlc2UgZXZlbnRzXHJcbiAgICAgICAgLy8gaW5pdCBwbGF5YmFjayBwb3NpdGlvbiB3aGVuIHRoZSBwbGF5ZXIgaXMgcmVhZHlcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9SRUFEWSwgcGxheWJhY2tQb3NpdGlvbkhhbmRsZXIpO1xyXG4gICAgICAgIC8vIHVwZGF0ZSBwbGF5YmFjayBwb3NpdGlvbiB3aGVuIGl0IGNoYW5nZXNcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9USU1FX0NIQU5HRUQsIHBsYXliYWNrUG9zaXRpb25IYW5kbGVyKTtcclxuICAgICAgICAvLyB1cGRhdGUgYnVmZmVybGV2ZWwgd2hlbiBidWZmZXJpbmcgaXMgY29tcGxldGVcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TVEFMTF9FTkRFRCwgcGxheWJhY2tQb3NpdGlvbkhhbmRsZXIpO1xyXG4gICAgICAgIC8vIHVwZGF0ZSBwbGF5YmFjayBwb3NpdGlvbiB3aGVuIGEgc2VlayBoYXMgZmluaXNoZWRcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TRUVLRUQsIHBsYXliYWNrUG9zaXRpb25IYW5kbGVyKTtcclxuICAgICAgICAvLyB1cGRhdGUgcGxheWJhY2sgcG9zaXRpb24gd2hlbiBhIHRpbWVzaGlmdCBoYXMgZmluaXNoZWRcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9USU1FX1NISUZURUQsIHBsYXliYWNrUG9zaXRpb25IYW5kbGVyKTtcclxuICAgICAgICAvLyB1cGRhdGUgYnVmZmVybGV2ZWwgd2hlbiBhIHNlZ21lbnQgaGFzIGJlZW4gZG93bmxvYWRlZFxyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1NFR01FTlRfUkVRVUVTVF9GSU5JU0hFRCwgcGxheWJhY2tQb3NpdGlvbkhhbmRsZXIpO1xyXG4gICAgICAgIC8vIHVwZGF0ZSBwbGF5YmFjayBwb3NpdGlvbiBvZiBDYXN0IHBsYXliYWNrXHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fQ0FTVF9USU1FX1VQREFURUQsIHBsYXliYWNrUG9zaXRpb25IYW5kbGVyKTtcclxuICAgICAgICAvLyBTZWVrIGhhbmRsaW5nXHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fU0VFSywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5zZXRTZWVraW5nKHRydWUpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1NFRUtFRCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5zZXRTZWVraW5nKGZhbHNlKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9USU1FX1NISUZULCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLnNldFNlZWtpbmcodHJ1ZSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fVElNRV9TSElGVEVELCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLnNldFNlZWtpbmcoZmFsc2UpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZhciBzZWVrID0gZnVuY3Rpb24gKHBlcmNlbnRhZ2UpIHtcclxuICAgICAgICAgICAgaWYgKHBsYXllci5pc0xpdmUoKSkge1xyXG4gICAgICAgICAgICAgICAgcGxheWVyLnRpbWVTaGlmdChwbGF5ZXIuZ2V0TWF4VGltZVNoaWZ0KCkgLSAocGxheWVyLmdldE1heFRpbWVTaGlmdCgpICogKHBlcmNlbnRhZ2UgLyAxMDApKSwgJ3VpJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBwbGF5ZXIuc2VlayhwbGF5ZXIuZ2V0RHVyYXRpb24oKSAqIChwZXJjZW50YWdlIC8gMTAwKSwgJ3VpJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHRoaXMub25TZWVrLnN1YnNjcmliZShmdW5jdGlvbiAoc2VuZGVyKSB7XHJcbiAgICAgICAgICAgIGlzU2Vla2luZyA9IHRydWU7IC8vIHRyYWNrIHNlZWtpbmcgc3RhdHVzIHNvIHdlIGNhbiBjYXRjaCBldmVudHMgZnJvbSBzZWVrIHByZXZpZXcgc2Vla3NcclxuICAgICAgICAgICAgLy8gTm90aWZ5IFVJIG1hbmFnZXIgb2Ygc3RhcnRlZCBzZWVrXHJcbiAgICAgICAgICAgIHVpbWFuYWdlci5vblNlZWsuZGlzcGF0Y2goc2VuZGVyKTtcclxuICAgICAgICAgICAgLy8gU2F2ZSBjdXJyZW50IHBsYXliYWNrIHN0YXRlXHJcbiAgICAgICAgICAgIGlzUGxheWluZyA9IHBsYXllci5pc1BsYXlpbmcoKTtcclxuICAgICAgICAgICAgLy8gUGF1c2UgcGxheWJhY2sgd2hpbGUgc2Vla2luZ1xyXG4gICAgICAgICAgICBpZiAoaXNQbGF5aW5nKSB7XHJcbiAgICAgICAgICAgICAgICBwbGF5ZXIucGF1c2UoJ3VpJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLm9uU2Vla1ByZXZpZXcuc3Vic2NyaWJlKGZ1bmN0aW9uIChzZW5kZXIsIGFyZ3MpIHtcclxuICAgICAgICAgICAgLy8gTm90aWZ5IFVJIG1hbmFnZXIgb2Ygc2VlayBwcmV2aWV3XHJcbiAgICAgICAgICAgIHVpbWFuYWdlci5vblNlZWtQcmV2aWV3LmRpc3BhdGNoKHNlbmRlciwgYXJncyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5vblNlZWtQcmV2aWV3LnN1YnNjcmliZVJhdGVMaW1pdGVkKGZ1bmN0aW9uIChzZW5kZXIsIGFyZ3MpIHtcclxuICAgICAgICAgICAgLy8gUmF0ZS1saW1pdGVkIHNjcnViYmluZyBzZWVrXHJcbiAgICAgICAgICAgIGlmIChhcmdzLnNjcnViYmluZykge1xyXG4gICAgICAgICAgICAgICAgc2VlayhhcmdzLnBvc2l0aW9uKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0sIDIwMCk7XHJcbiAgICAgICAgdGhpcy5vblNlZWtlZC5zdWJzY3JpYmUoZnVuY3Rpb24gKHNlbmRlciwgcGVyY2VudGFnZSkge1xyXG4gICAgICAgICAgICBpc1NlZWtpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgLy8gRG8gdGhlIHNlZWtcclxuICAgICAgICAgICAgc2VlayhwZXJjZW50YWdlKTtcclxuICAgICAgICAgICAgLy8gQ29udGludWUgcGxheWJhY2sgYWZ0ZXIgc2VlayBpZiBwbGF5ZXIgd2FzIHBsYXlpbmcgd2hlbiBzZWVrIHN0YXJ0ZWRcclxuICAgICAgICAgICAgaWYgKGlzUGxheWluZykge1xyXG4gICAgICAgICAgICAgICAgcGxheWVyLnBsYXkoJ3VpJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gTm90aWZ5IFVJIG1hbmFnZXIgb2YgZmluaXNoZWQgc2Vla1xyXG4gICAgICAgICAgICB1aW1hbmFnZXIub25TZWVrZWQuZGlzcGF0Y2goc2VuZGVyKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBpZiAodGhpcy5oYXNMYWJlbCgpKSB7XHJcbiAgICAgICAgICAgIC8vIENvbmZpZ3VyZSBhIHNlZWtiYXIgbGFiZWwgdGhhdCBpcyBpbnRlcm5hbCB0byB0aGUgc2Vla2JhcilcclxuICAgICAgICAgICAgdGhpcy5nZXRMYWJlbCgpLmNvbmZpZ3VyZShwbGF5ZXIsIHVpbWFuYWdlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIEhpZGUgc2Vla2JhciBmb3IgbGl2ZSBzb3VyY2VzIHdpdGhvdXQgdGltZXNoaWZ0XHJcbiAgICAgICAgdmFyIGlzTGl2ZSA9IGZhbHNlO1xyXG4gICAgICAgIHZhciBoYXNUaW1lU2hpZnQgPSBmYWxzZTtcclxuICAgICAgICB2YXIgc3dpdGNoVmlzaWJpbGl0eSA9IGZ1bmN0aW9uIChpc0xpdmUsIGhhc1RpbWVTaGlmdCkge1xyXG4gICAgICAgICAgICBpZiAoaXNMaXZlICYmICFoYXNUaW1lU2hpZnQpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmhpZGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLnNob3coKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBwbGF5YmFja1Bvc2l0aW9uSGFuZGxlcihudWxsLCB0cnVlKTtcclxuICAgICAgICAgICAgX3RoaXMucmVmcmVzaFBsYXliYWNrUG9zaXRpb24oKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciBsaXZlU3RyZWFtRGV0ZWN0b3IgPSBuZXcgcGxheWVydXRpbHNfMS5QbGF5ZXJVdGlscy5MaXZlU3RyZWFtRGV0ZWN0b3IocGxheWVyKTtcclxuICAgICAgICBsaXZlU3RyZWFtRGV0ZWN0b3Iub25MaXZlQ2hhbmdlZC5zdWJzY3JpYmUoZnVuY3Rpb24gKHNlbmRlciwgYXJncykge1xyXG4gICAgICAgICAgICBpc0xpdmUgPSBhcmdzLmxpdmU7XHJcbiAgICAgICAgICAgIHN3aXRjaFZpc2liaWxpdHkoaXNMaXZlLCBoYXNUaW1lU2hpZnQpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZhciB0aW1lU2hpZnREZXRlY3RvciA9IG5ldyBwbGF5ZXJ1dGlsc18xLlBsYXllclV0aWxzLlRpbWVTaGlmdEF2YWlsYWJpbGl0eURldGVjdG9yKHBsYXllcik7XHJcbiAgICAgICAgdGltZVNoaWZ0RGV0ZWN0b3Iub25UaW1lU2hpZnRBdmFpbGFiaWxpdHlDaGFuZ2VkLnN1YnNjcmliZShmdW5jdGlvbiAoc2VuZGVyLCBhcmdzKSB7XHJcbiAgICAgICAgICAgIGhhc1RpbWVTaGlmdCA9IGFyZ3MudGltZVNoaWZ0QXZhaWxhYmxlO1xyXG4gICAgICAgICAgICBzd2l0Y2hWaXNpYmlsaXR5KGlzTGl2ZSwgaGFzVGltZVNoaWZ0KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBJbml0aWFsIGRldGVjdGlvblxyXG4gICAgICAgIGxpdmVTdHJlYW1EZXRlY3Rvci5kZXRlY3QoKTtcclxuICAgICAgICB0aW1lU2hpZnREZXRlY3Rvci5kZXRlY3QoKTtcclxuICAgICAgICAvLyBSZWZyZXNoIHRoZSBwbGF5YmFjayBwb3NpdGlvbiB3aGVuIHRoZSBwbGF5ZXIgcmVzaXplZCBvciB0aGUgVUkgaXMgY29uZmlndXJlZC4gVGhlIHBsYXliYWNrIHBvc2l0aW9uIG1hcmtlclxyXG4gICAgICAgIC8vIGlzIHBvc2l0aW9uZWQgYWJzb2x1dGVseSBhbmQgbXVzdCB0aGVyZWZvcmUgYmUgdXBkYXRlZCB3aGVuIHRoZSBzaXplIG9mIHRoZSBzZWVrYmFyIGNoYW5nZXMuXHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUExBWUVSX1JFU0laRSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5yZWZyZXNoUGxheWJhY2tQb3NpdGlvbigpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIEFkZGl0aW9uYWxseSwgd2hlbiB0aGlzIGNvZGUgaXMgY2FsbGVkLCB0aGUgc2Vla2JhciBpcyBub3QgcGFydCBvZiB0aGUgVUkgeWV0IGFuZCB0aGVyZWZvcmUgZG9lcyBub3QgaGF2ZSBhIHNpemUsXHJcbiAgICAgICAgLy8gcmVzdWx0aW5nIGluIGEgd3JvbmcgaW5pdGlhbCBwb3NpdGlvbiBvZiB0aGUgbWFya2VyLiBSZWZyZXNoaW5nIGl0IG9uY2UgdGhlIFVJIGlzIGNvbmZpZ3VyZWQgc29sdmVkIHRoaXMgaXNzdWUuXHJcbiAgICAgICAgdWltYW5hZ2VyLm9uQ29uZmlndXJlZC5zdWJzY3JpYmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5yZWZyZXNoUGxheWJhY2tQb3NpdGlvbigpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIEl0IGNhbiBhbHNvIGhhcHBlbiB0aGF0IHRoZSB2YWx1ZSBjaGFuZ2VzIG9uY2UgdGhlIHBsYXllciBpcyByZWFkeSwgb3Igd2hlbiBhIG5ldyBzb3VyY2UgaXMgbG9hZGVkLCBzbyB3ZSBuZWVkXHJcbiAgICAgICAgLy8gdG8gdXBkYXRlIG9uIE9OX1JFQURZIHRvb1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1JFQURZLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLnJlZnJlc2hQbGF5YmFja1Bvc2l0aW9uKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gSW5pdGlhbGl6ZSBzZWVrYmFyXHJcbiAgICAgICAgcGxheWJhY2tQb3NpdGlvbkhhbmRsZXIoKTsgLy8gU2V0IHRoZSBwbGF5YmFjayBwb3NpdGlvblxyXG4gICAgICAgIHRoaXMuc2V0QnVmZmVyUG9zaXRpb24oMCk7XHJcbiAgICAgICAgdGhpcy5zZXRTZWVrUG9zaXRpb24oMCk7XHJcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLnNtb290aFBsYXliYWNrUG9zaXRpb25VcGRhdGVJbnRlcnZhbE1zICE9PSBTZWVrQmFyLlNNT09USF9QTEFZQkFDS19QT1NJVElPTl9VUERBVEVfRElTQUJMRUQpIHtcclxuICAgICAgICAgICAgdGhpcy5jb25maWd1cmVTbW9vdGhQbGF5YmFja1Bvc2l0aW9uVXBkYXRlcihwbGF5ZXIsIHVpbWFuYWdlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuY29uZmlndXJlTWFya2VycyhwbGF5ZXIsIHVpbWFuYWdlcik7XHJcbiAgICB9O1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUuY29uZmlndXJlU21vb3RoUGxheWJhY2tQb3NpdGlvblVwZGF0ZXIgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIC8qXHJcbiAgICAgICAgICogUGxheWJhY2sgcG9zaXRpb24gdXBkYXRlXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBXZSBkbyBub3QgdXBkYXRlIHRoZSBwb3NpdGlvbiBkaXJlY3RseSBmcm9tIHRoZSBPTl9USU1FX0NIQU5HRUQgZXZlbnQsIGJlY2F1c2UgaXQgYXJyaXZlcyB2ZXJ5IGppdHRlcnkgYW5kXHJcbiAgICAgICAgICogcmVzdWx0cyBpbiBhIGppdHRlcnkgcG9zaXRpb24gaW5kaWNhdG9yIHNpbmNlIHRoZSBDU1MgdHJhbnNpdGlvbiB0aW1lIGlzIHN0YXRpY2FsbHkgc2V0LlxyXG4gICAgICAgICAqIFRvIHdvcmsgYXJvdW5kIHRoaXMgaXNzdWUsIHdlIG1haW50YWluIGEgbG9jYWwgcGxheWJhY2sgcG9zaXRpb24gdGhhdCBpcyB1cGRhdGVkIGluIGEgc3RhYmxlIHJlZ3VsYXIgaW50ZXJ2YWxcclxuICAgICAgICAgKiBhbmQga2VwdCBpbiBzeW5jIHdpdGggdGhlIHBsYXllci5cclxuICAgICAgICAgKi9cclxuICAgICAgICB2YXIgY3VycmVudFRpbWVTZWVrQmFyID0gMDtcclxuICAgICAgICB2YXIgY3VycmVudFRpbWVQbGF5ZXIgPSAwO1xyXG4gICAgICAgIHZhciB1cGRhdGVJbnRlcnZhbE1zID0gNTA7XHJcbiAgICAgICAgdmFyIGN1cnJlbnRUaW1lVXBkYXRlRGVsdGFTZWNzID0gdXBkYXRlSW50ZXJ2YWxNcyAvIDEwMDA7XHJcbiAgICAgICAgdGhpcy5zbW9vdGhQbGF5YmFja1Bvc2l0aW9uVXBkYXRlciA9IG5ldyB0aW1lb3V0XzEuVGltZW91dCh1cGRhdGVJbnRlcnZhbE1zLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGN1cnJlbnRUaW1lU2Vla0JhciArPSBjdXJyZW50VGltZVVwZGF0ZURlbHRhU2VjcztcclxuICAgICAgICAgICAgY3VycmVudFRpbWVQbGF5ZXIgPSBwbGF5ZXIuZ2V0Q3VycmVudFRpbWUoKTtcclxuICAgICAgICAgICAgLy8gU3luYyBjdXJyZW50VGltZSBvZiBzZWVrYmFyIHRvIHBsYXllclxyXG4gICAgICAgICAgICB2YXIgY3VycmVudFRpbWVEZWx0YSA9IGN1cnJlbnRUaW1lU2Vla0JhciAtIGN1cnJlbnRUaW1lUGxheWVyO1xyXG4gICAgICAgICAgICAvLyBJZiB0aGUgZGVsdGEgaXMgbGFyZ2VyIHRoYXQgMiBzZWNzLCBkaXJlY3RseSBqdW1wIHRoZSBzZWVrYmFyIHRvIHRoZVxyXG4gICAgICAgICAgICAvLyBwbGF5ZXIgdGltZSBpbnN0ZWFkIG9mIHNtb290aGx5IGZhc3QgZm9yd2FyZGluZy9yZXdpbmRpbmcuXHJcbiAgICAgICAgICAgIGlmIChNYXRoLmFicyhjdXJyZW50VGltZURlbHRhKSA+IDIpIHtcclxuICAgICAgICAgICAgICAgIGN1cnJlbnRUaW1lU2Vla0JhciA9IGN1cnJlbnRUaW1lUGxheWVyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKGN1cnJlbnRUaW1lRGVsdGEgPD0gLWN1cnJlbnRUaW1lVXBkYXRlRGVsdGFTZWNzKSB7XHJcbiAgICAgICAgICAgICAgICBjdXJyZW50VGltZVNlZWtCYXIgKz0gY3VycmVudFRpbWVVcGRhdGVEZWx0YVNlY3M7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoY3VycmVudFRpbWVEZWx0YSA+PSBjdXJyZW50VGltZVVwZGF0ZURlbHRhU2Vjcykge1xyXG4gICAgICAgICAgICAgICAgY3VycmVudFRpbWVTZWVrQmFyIC09IGN1cnJlbnRUaW1lVXBkYXRlRGVsdGFTZWNzO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciBwbGF5YmFja1Bvc2l0aW9uUGVyY2VudGFnZSA9IDEwMCAvIHBsYXllci5nZXREdXJhdGlvbigpICogY3VycmVudFRpbWVTZWVrQmFyO1xyXG4gICAgICAgICAgICBfdGhpcy5zZXRQbGF5YmFja1Bvc2l0aW9uKHBsYXliYWNrUG9zaXRpb25QZXJjZW50YWdlKTtcclxuICAgICAgICB9LCB0cnVlKTtcclxuICAgICAgICB2YXIgc3RhcnRTbW9vdGhQbGF5YmFja1Bvc2l0aW9uVXBkYXRlciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKCFwbGF5ZXIuaXNMaXZlKCkpIHtcclxuICAgICAgICAgICAgICAgIGN1cnJlbnRUaW1lU2Vla0JhciA9IHBsYXllci5nZXRDdXJyZW50VGltZSgpO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuc21vb3RoUGxheWJhY2tQb3NpdGlvblVwZGF0ZXIuc3RhcnQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIHN0b3BTbW9vdGhQbGF5YmFja1Bvc2l0aW9uVXBkYXRlciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMuc21vb3RoUGxheWJhY2tQb3NpdGlvblVwZGF0ZXIuY2xlYXIoKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BMQVksIHN0YXJ0U21vb3RoUGxheWJhY2tQb3NpdGlvblVwZGF0ZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0NBU1RfUExBWUlORywgc3RhcnRTbW9vdGhQbGF5YmFja1Bvc2l0aW9uVXBkYXRlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUEFVU0VELCBzdG9wU21vb3RoUGxheWJhY2tQb3NpdGlvblVwZGF0ZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0NBU1RfUEFVU0VELCBzdG9wU21vb3RoUGxheWJhY2tQb3NpdGlvblVwZGF0ZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1NFRUtFRCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjdXJyZW50VGltZVNlZWtCYXIgPSBwbGF5ZXIuZ2V0Q3VycmVudFRpbWUoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBpZiAocGxheWVyLmlzUGxheWluZygpKSB7XHJcbiAgICAgICAgICAgIHN0YXJ0U21vb3RoUGxheWJhY2tQb3NpdGlvblVwZGF0ZXIoKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUuY29uZmlndXJlTWFya2VycyA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgdmFyIGNsZWFyTWFya2VycyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMudGltZWxpbmVNYXJrZXJzID0gW107XHJcbiAgICAgICAgICAgIF90aGlzLnVwZGF0ZU1hcmtlcnMoKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciBzZXR1cE1hcmtlcnMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNsZWFyTWFya2VycygpO1xyXG4gICAgICAgICAgICB2YXIgaGFzTWFya2Vyc0luVWlDb25maWcgPSB1aW1hbmFnZXIuZ2V0Q29uZmlnKCkubWV0YWRhdGEgJiYgdWltYW5hZ2VyLmdldENvbmZpZygpLm1ldGFkYXRhLm1hcmtlcnNcclxuICAgICAgICAgICAgICAgICYmIHVpbWFuYWdlci5nZXRDb25maWcoKS5tZXRhZGF0YS5tYXJrZXJzLmxlbmd0aCA+IDA7XHJcbiAgICAgICAgICAgIHZhciBoYXNNYXJrZXJzSW5QbGF5ZXJDb25maWcgPSBwbGF5ZXIuZ2V0Q29uZmlnKCkuc291cmNlICYmIHBsYXllci5nZXRDb25maWcoKS5zb3VyY2UubWFya2Vyc1xyXG4gICAgICAgICAgICAgICAgJiYgcGxheWVyLmdldENvbmZpZygpLnNvdXJjZS5tYXJrZXJzLmxlbmd0aCA+IDA7XHJcbiAgICAgICAgICAgIC8vIFRha2UgbWFya2VycyBmcm9tIHRoZSBVSSBjb25maWcuIElmIG5vIG1hcmtlcnMgZGVmaW5lZCwgdHJ5IHRvIHRha2UgdGhlbSBmcm9tIHRoZSBwbGF5ZXIncyBzb3VyY2UgY29uZmlnLlxyXG4gICAgICAgICAgICB2YXIgbWFya2VycyA9IGhhc01hcmtlcnNJblVpQ29uZmlnID8gdWltYW5hZ2VyLmdldENvbmZpZygpLm1ldGFkYXRhLm1hcmtlcnMgOlxyXG4gICAgICAgICAgICAgICAgaGFzTWFya2Vyc0luUGxheWVyQ29uZmlnID8gcGxheWVyLmdldENvbmZpZygpLnNvdXJjZS5tYXJrZXJzIDogbnVsbDtcclxuICAgICAgICAgICAgLy8gR2VuZXJhdGUgdGltZWxpbmUgbWFya2VycyBmcm9tIHRoZSBjb25maWcgaWYgd2UgaGF2ZSBtYXJrZXJzIGFuZCBpZiB3ZSBoYXZlIGEgZHVyYXRpb25cclxuICAgICAgICAgICAgLy8gVGhlIGR1cmF0aW9uIGNoZWNrIGlzIGZvciBidWdneSBwbGF0Zm9ybXMgd2hlcmUgdGhlIGR1cmF0aW9uIGlzIG5vdCBhdmFpbGFibGUgaW5zdGFudGx5IChDaHJvbWUgb24gQW5kcm9pZCA0LjMpXHJcbiAgICAgICAgICAgIGlmIChtYXJrZXJzICYmIHBsYXllci5nZXREdXJhdGlvbigpICE9PSBJbmZpbml0eSkge1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBtYXJrZXJzXzEgPSBtYXJrZXJzOyBfaSA8IG1hcmtlcnNfMS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbWFya2VyID0gbWFya2Vyc18xW19pXTtcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy50aW1lbGluZU1hcmtlcnMucHVzaCh7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpbWU6IDEwMCAvIHBsYXllci5nZXREdXJhdGlvbigpICogbWFya2VyLnRpbWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiBtYXJrZXIudGl0bGUsXHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gUG9wdWxhdGUgdGhlIHRpbWVsaW5lIHdpdGggdGhlIG1hcmtlcnNcclxuICAgICAgICAgICAgX3RoaXMudXBkYXRlTWFya2VycygpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgLy8gQWRkIG1hcmtlcnMgd2hlbiBhIHNvdXJjZSBpcyBsb2FkZWRcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9SRUFEWSwgc2V0dXBNYXJrZXJzKTtcclxuICAgICAgICAvLyBSZW1vdmUgbWFya2VycyB3aGVuIHVubG9hZGVkXHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fU09VUkNFX1VOTE9BREVELCBjbGVhck1hcmtlcnMpO1xyXG4gICAgICAgIC8vIEluaXQgbWFya2VycyBhdCBzdGFydHVwXHJcbiAgICAgICAgc2V0dXBNYXJrZXJzKCk7XHJcbiAgICB9O1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUucmVsZWFzZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLnJlbGVhc2UuY2FsbCh0aGlzKTtcclxuICAgICAgICBpZiAodGhpcy5zbW9vdGhQbGF5YmFja1Bvc2l0aW9uVXBkYXRlcikge1xyXG4gICAgICAgICAgICB0aGlzLnNtb290aFBsYXliYWNrUG9zaXRpb25VcGRhdGVyLmNsZWFyKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIFNlZWtCYXIucHJvdG90eXBlLnRvRG9tRWxlbWVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZy52ZXJ0aWNhbCkge1xyXG4gICAgICAgICAgICB0aGlzLmNvbmZpZy5jc3NDbGFzc2VzLnB1c2goJ3ZlcnRpY2FsJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzZWVrQmFyQ29udGFpbmVyID0gbmV3IGRvbV8xLkRPTSgnZGl2Jywge1xyXG4gICAgICAgICAgICAnaWQnOiB0aGlzLmNvbmZpZy5pZCxcclxuICAgICAgICAgICAgJ2NsYXNzJzogdGhpcy5nZXRDc3NDbGFzc2VzKCksXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdmFyIHNlZWtCYXIgPSBuZXcgZG9tXzEuRE9NKCdkaXYnLCB7XHJcbiAgICAgICAgICAgICdjbGFzcyc6IHRoaXMucHJlZml4Q3NzKCdzZWVrYmFyJyksXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5zZWVrQmFyID0gc2Vla0JhcjtcclxuICAgICAgICAvLyBJbmRpY2F0b3IgdGhhdCBzaG93cyB0aGUgYnVmZmVyIGZpbGwgbGV2ZWxcclxuICAgICAgICB2YXIgc2Vla0JhckJ1ZmZlckxldmVsID0gbmV3IGRvbV8xLkRPTSgnZGl2Jywge1xyXG4gICAgICAgICAgICAnY2xhc3MnOiB0aGlzLnByZWZpeENzcygnc2Vla2Jhci1idWZmZXJsZXZlbCcpLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuc2Vla0JhckJ1ZmZlclBvc2l0aW9uID0gc2Vla0JhckJ1ZmZlckxldmVsO1xyXG4gICAgICAgIC8vIEluZGljYXRvciB0aGF0IHNob3dzIHRoZSBjdXJyZW50IHBsYXliYWNrIHBvc2l0aW9uXHJcbiAgICAgICAgdmFyIHNlZWtCYXJQbGF5YmFja1Bvc2l0aW9uID0gbmV3IGRvbV8xLkRPTSgnZGl2Jywge1xyXG4gICAgICAgICAgICAnY2xhc3MnOiB0aGlzLnByZWZpeENzcygnc2Vla2Jhci1wbGF5YmFja3Bvc2l0aW9uJyksXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5zZWVrQmFyUGxheWJhY2tQb3NpdGlvbiA9IHNlZWtCYXJQbGF5YmFja1Bvc2l0aW9uO1xyXG4gICAgICAgIC8vIEEgbWFya2VyIG9mIHRoZSBjdXJyZW50IHBsYXliYWNrIHBvc2l0aW9uLCBlLmcuIGEgZG90IG9yIGxpbmVcclxuICAgICAgICB2YXIgc2Vla0JhclBsYXliYWNrUG9zaXRpb25NYXJrZXIgPSBuZXcgZG9tXzEuRE9NKCdkaXYnLCB7XHJcbiAgICAgICAgICAgICdjbGFzcyc6IHRoaXMucHJlZml4Q3NzKCdzZWVrYmFyLXBsYXliYWNrcG9zaXRpb24tbWFya2VyJyksXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5zZWVrQmFyUGxheWJhY2tQb3NpdGlvbk1hcmtlciA9IHNlZWtCYXJQbGF5YmFja1Bvc2l0aW9uTWFya2VyO1xyXG4gICAgICAgIC8vIEluZGljYXRvciB0aGF0IHNob3cgd2hlcmUgYSBzZWVrIHdpbGwgZ28gdG9cclxuICAgICAgICB2YXIgc2Vla0JhclNlZWtQb3NpdGlvbiA9IG5ldyBkb21fMS5ET00oJ2RpdicsIHtcclxuICAgICAgICAgICAgJ2NsYXNzJzogdGhpcy5wcmVmaXhDc3MoJ3NlZWtiYXItc2Vla3Bvc2l0aW9uJyksXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5zZWVrQmFyU2Vla1Bvc2l0aW9uID0gc2Vla0JhclNlZWtQb3NpdGlvbjtcclxuICAgICAgICAvLyBJbmRpY2F0b3IgdGhhdCBzaG93cyB0aGUgZnVsbCBzZWVrYmFyXHJcbiAgICAgICAgdmFyIHNlZWtCYXJCYWNrZHJvcCA9IG5ldyBkb21fMS5ET00oJ2RpdicsIHtcclxuICAgICAgICAgICAgJ2NsYXNzJzogdGhpcy5wcmVmaXhDc3MoJ3NlZWtiYXItYmFja2Ryb3AnKSxcclxuICAgICAgICB9KTtcclxuICAgICAgICB0aGlzLnNlZWtCYXJCYWNrZHJvcCA9IHNlZWtCYXJCYWNrZHJvcDtcclxuICAgICAgICB2YXIgc2Vla0JhckNoYXB0ZXJNYXJrZXJzQ29udGFpbmVyID0gbmV3IGRvbV8xLkRPTSgnZGl2Jywge1xyXG4gICAgICAgICAgICAnY2xhc3MnOiB0aGlzLnByZWZpeENzcygnc2Vla2Jhci1tYXJrZXJzJyksXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5zZWVrQmFyTWFya2Vyc0NvbnRhaW5lciA9IHNlZWtCYXJDaGFwdGVyTWFya2Vyc0NvbnRhaW5lcjtcclxuICAgICAgICBzZWVrQmFyLmFwcGVuZChzZWVrQmFyQmFja2Ryb3AsIHNlZWtCYXJCdWZmZXJMZXZlbCwgc2Vla0JhclNlZWtQb3NpdGlvbiwgc2Vla0JhclBsYXliYWNrUG9zaXRpb24sIHNlZWtCYXJDaGFwdGVyTWFya2Vyc0NvbnRhaW5lciwgc2Vla0JhclBsYXliYWNrUG9zaXRpb25NYXJrZXIpO1xyXG4gICAgICAgIHZhciBzZWVraW5nID0gZmFsc2U7XHJcbiAgICAgICAgLy8gRGVmaW5lIGhhbmRsZXIgZnVuY3Rpb25zIHNvIHdlIGNhbiBhdHRhY2gvcmVtb3ZlIHRoZW0gbGF0ZXJcclxuICAgICAgICB2YXIgbW91c2VUb3VjaE1vdmVIYW5kbGVyID0gZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAvLyBBdm9pZCBwcm9wYWdhdGlvbiB0byBWUiBoYW5kbGVyXHJcbiAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgIHZhciB0YXJnZXRQZXJjZW50YWdlID0gMTAwICogX3RoaXMuZ2V0T2Zmc2V0KGUpO1xyXG4gICAgICAgICAgICBfdGhpcy5zZXRTZWVrUG9zaXRpb24odGFyZ2V0UGVyY2VudGFnZSk7XHJcbiAgICAgICAgICAgIF90aGlzLnNldFBsYXliYWNrUG9zaXRpb24odGFyZ2V0UGVyY2VudGFnZSk7XHJcbiAgICAgICAgICAgIF90aGlzLm9uU2Vla1ByZXZpZXdFdmVudCh0YXJnZXRQZXJjZW50YWdlLCB0cnVlKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciBtb3VzZVRvdWNoVXBIYW5kbGVyID0gZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAvLyBSZW1vdmUgaGFuZGxlcnMsIHNlZWsgb3BlcmF0aW9uIGlzIGZpbmlzaGVkXHJcbiAgICAgICAgICAgIG5ldyBkb21fMS5ET00oZG9jdW1lbnQpLm9mZigndG91Y2htb3ZlIG1vdXNlbW92ZScsIG1vdXNlVG91Y2hNb3ZlSGFuZGxlcik7XHJcbiAgICAgICAgICAgIG5ldyBkb21fMS5ET00oZG9jdW1lbnQpLm9mZigndG91Y2hlbmQgbW91c2V1cCcsIG1vdXNlVG91Y2hVcEhhbmRsZXIpO1xyXG4gICAgICAgICAgICB2YXIgdGFyZ2V0UGVyY2VudGFnZSA9IDEwMCAqIF90aGlzLmdldE9mZnNldChlKTtcclxuICAgICAgICAgICAgdmFyIHNuYXBwZWRDaGFwdGVyID0gX3RoaXMuZ2V0TWFya2VyQXRQb3NpdGlvbih0YXJnZXRQZXJjZW50YWdlKTtcclxuICAgICAgICAgICAgX3RoaXMuc2V0U2Vla2luZyhmYWxzZSk7XHJcbiAgICAgICAgICAgIHNlZWtpbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgLy8gRmlyZSBzZWVrZWQgZXZlbnRcclxuICAgICAgICAgICAgX3RoaXMub25TZWVrZWRFdmVudChzbmFwcGVkQ2hhcHRlciA/IHNuYXBwZWRDaGFwdGVyLnRpbWUgOiB0YXJnZXRQZXJjZW50YWdlKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8vIEEgc2VlayBhbHdheXMgc3RhcnQgd2l0aCBhIHRvdWNoc3RhcnQgb3IgbW91c2Vkb3duIGRpcmVjdGx5IG9uIHRoZSBzZWVrYmFyLlxyXG4gICAgICAgIC8vIFRvIHRyYWNrIGEgbW91c2Ugc2VlayBhbHNvIG91dHNpZGUgdGhlIHNlZWtiYXIgKGZvciB0b3VjaCBldmVudHMgdGhpcyB3b3JrcyBhdXRvbWF0aWNhbGx5KSxcclxuICAgICAgICAvLyBzbyB0aGUgdXNlciBkb2VzIG5vdCBuZWVkIHRvIHRha2UgY2FyZSB0aGF0IHRoZSBtb3VzZSBhbHdheXMgc3RheXMgb24gdGhlIHNlZWtiYXIsIHdlIGF0dGFjaCB0aGUgbW91c2Vtb3ZlXHJcbiAgICAgICAgLy8gYW5kIG1vdXNldXAgaGFuZGxlcnMgdG8gdGhlIHdob2xlIGRvY3VtZW50LiBBIHNlZWsgaXMgdHJpZ2dlcmVkIHdoZW4gdGhlIHVzZXIgbGlmdHMgdGhlIG1vdXNlIGtleS5cclxuICAgICAgICAvLyBBIHNlZWsgbW91c2UgZ2VzdHVyZSBpcyB0aHVzIGJhc2ljYWxseSBhIGNsaWNrIHdpdGggYSBsb25nIHRpbWUgZnJhbWUgYmV0d2VlbiBkb3duIGFuZCB1cCBldmVudHMuXHJcbiAgICAgICAgc2Vla0Jhci5vbigndG91Y2hzdGFydCBtb3VzZWRvd24nLCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICB2YXIgaXNUb3VjaEV2ZW50ID0gX3RoaXMudG91Y2hTdXBwb3J0ZWQgJiYgZSBpbnN0YW5jZW9mIFRvdWNoRXZlbnQ7XHJcbiAgICAgICAgICAgIC8vIFByZXZlbnQgc2VsZWN0aW9uIG9mIERPTSBlbGVtZW50cyAoYWxzbyBwcmV2ZW50cyBtb3VzZWRvd24gaWYgY3VycmVudCBldmVudCBpcyB0b3VjaHN0YXJ0KVxyXG4gICAgICAgICAgICBlLnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgICAgICAgIC8vIEF2b2lkIHByb3BhZ2F0aW9uIHRvIFZSIGhhbmRsZXJcclxuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcclxuICAgICAgICAgICAgX3RoaXMuc2V0U2Vla2luZyh0cnVlKTsgLy8gU2V0IHNlZWtpbmcgY2xhc3Mgb24gRE9NIGVsZW1lbnRcclxuICAgICAgICAgICAgc2Vla2luZyA9IHRydWU7IC8vIFNldCBzZWVrIHRyYWNraW5nIGZsYWdcclxuICAgICAgICAgICAgLy8gRmlyZSBzZWVrZWQgZXZlbnRcclxuICAgICAgICAgICAgX3RoaXMub25TZWVrRXZlbnQoKTtcclxuICAgICAgICAgICAgLy8gQWRkIGhhbmRsZXIgdG8gdHJhY2sgdGhlIHNlZWsgb3BlcmF0aW9uIG92ZXIgdGhlIHdob2xlIGRvY3VtZW50XHJcbiAgICAgICAgICAgIG5ldyBkb21fMS5ET00oZG9jdW1lbnQpLm9uKGlzVG91Y2hFdmVudCA/ICd0b3VjaG1vdmUnIDogJ21vdXNlbW92ZScsIG1vdXNlVG91Y2hNb3ZlSGFuZGxlcik7XHJcbiAgICAgICAgICAgIG5ldyBkb21fMS5ET00oZG9jdW1lbnQpLm9uKGlzVG91Y2hFdmVudCA/ICd0b3VjaGVuZCcgOiAnbW91c2V1cCcsIG1vdXNlVG91Y2hVcEhhbmRsZXIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIERpc3BsYXkgc2VlayB0YXJnZXQgaW5kaWNhdG9yIHdoZW4gbW91c2UgaG92ZXJzIG9yIGZpbmdlciBzbGlkZXMgb3ZlciBzZWVrYmFyXHJcbiAgICAgICAgc2Vla0Jhci5vbigndG91Y2htb3ZlIG1vdXNlbW92ZScsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgaWYgKHNlZWtpbmcpIHtcclxuICAgICAgICAgICAgICAgIC8vIER1cmluZyBhIHNlZWsgKHdoZW4gbW91c2UgaXMgZG93biBvciB0b3VjaCBtb3ZlIGFjdGl2ZSksIHdlIG5lZWQgdG8gc3RvcCBwcm9wYWdhdGlvbiB0byBhdm9pZFxyXG4gICAgICAgICAgICAgICAgLy8gdGhlIFZSIHZpZXdwb3J0IHJlYWN0aW5nIHRvIHRoZSBtb3Zlcy5cclxuICAgICAgICAgICAgICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XHJcbiAgICAgICAgICAgICAgICAvLyBCZWNhdXNlIHRoZSBzdG9wcGVkIHByb3BhZ2F0aW9uIGluaGliaXRzIHRoZSBldmVudCBvbiB0aGUgZG9jdW1lbnQsIHdlIG5lZWQgdG8gY2FsbCBpdCBmcm9tIGhlcmVcclxuICAgICAgICAgICAgICAgIG1vdXNlVG91Y2hNb3ZlSGFuZGxlcihlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB2YXIgcG9zaXRpb24gPSAxMDAgKiBfdGhpcy5nZXRPZmZzZXQoZSk7XHJcbiAgICAgICAgICAgIF90aGlzLnNldFNlZWtQb3NpdGlvbihwb3NpdGlvbik7XHJcbiAgICAgICAgICAgIF90aGlzLm9uU2Vla1ByZXZpZXdFdmVudChwb3NpdGlvbiwgZmFsc2UpO1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuaGFzTGFiZWwoKSAmJiBfdGhpcy5nZXRMYWJlbCgpLmlzSGlkZGVuKCkpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmdldExhYmVsKCkuc2hvdygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gSGlkZSBzZWVrIHRhcmdldCBpbmRpY2F0b3Igd2hlbiBtb3VzZSBvciBmaW5nZXIgbGVhdmVzIHNlZWtiYXJcclxuICAgICAgICBzZWVrQmFyLm9uKCd0b3VjaGVuZCBtb3VzZWxlYXZlJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICBfdGhpcy5zZXRTZWVrUG9zaXRpb24oMCk7XHJcbiAgICAgICAgICAgIGlmIChfdGhpcy5oYXNMYWJlbCgpKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5nZXRMYWJlbCgpLmhpZGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHNlZWtCYXJDb250YWluZXIuYXBwZW5kKHNlZWtCYXIpO1xyXG4gICAgICAgIGlmICh0aGlzLmxhYmVsKSB7XHJcbiAgICAgICAgICAgIHNlZWtCYXJDb250YWluZXIuYXBwZW5kKHRoaXMubGFiZWwuZ2V0RG9tRWxlbWVudCgpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHNlZWtCYXJDb250YWluZXI7XHJcbiAgICB9O1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUudXBkYXRlTWFya2VycyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLnNlZWtCYXJNYXJrZXJzQ29udGFpbmVyLmVtcHR5KCk7XHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMudGltZWxpbmVNYXJrZXJzOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICB2YXIgbWFya2VyID0gX2FbX2ldO1xyXG4gICAgICAgICAgICB0aGlzLnNlZWtCYXJNYXJrZXJzQ29udGFpbmVyLmFwcGVuZChuZXcgZG9tXzEuRE9NKCdkaXYnLCB7XHJcbiAgICAgICAgICAgICAgICAnY2xhc3MnOiB0aGlzLnByZWZpeENzcygnc2Vla2Jhci1tYXJrZXInKSxcclxuICAgICAgICAgICAgICAgICdkYXRhLW1hcmtlci10aW1lJzogU3RyaW5nKG1hcmtlci50aW1lKSxcclxuICAgICAgICAgICAgICAgICdkYXRhLW1hcmtlci10aXRsZSc6IFN0cmluZyhtYXJrZXIudGl0bGUpLFxyXG4gICAgICAgICAgICB9KS5jc3Moe1xyXG4gICAgICAgICAgICAgICAgJ3dpZHRoJzogbWFya2VyLnRpbWUgKyAnJScsXHJcbiAgICAgICAgICAgIH0pKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUuZ2V0TWFya2VyQXRQb3NpdGlvbiA9IGZ1bmN0aW9uIChwZXJjZW50YWdlKSB7XHJcbiAgICAgICAgdmFyIHNuYXBwZWRNYXJrZXIgPSBudWxsO1xyXG4gICAgICAgIHZhciBzbmFwcGluZ1JhbmdlID0gMTtcclxuICAgICAgICBpZiAodGhpcy50aW1lbGluZU1hcmtlcnMubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdGhpcy50aW1lbGluZU1hcmtlcnM7IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbWFya2VyID0gX2FbX2ldO1xyXG4gICAgICAgICAgICAgICAgaWYgKHBlcmNlbnRhZ2UgPj0gbWFya2VyLnRpbWUgLSBzbmFwcGluZ1JhbmdlICYmIHBlcmNlbnRhZ2UgPD0gbWFya2VyLnRpbWUgKyBzbmFwcGluZ1JhbmdlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc25hcHBlZE1hcmtlciA9IG1hcmtlcjtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc25hcHBlZE1hcmtlcjtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGhvcml6b250YWwgb2Zmc2V0IG9mIGEgbW91c2UvdG91Y2ggZXZlbnQgcG9pbnQgZnJvbSB0aGUgbGVmdCBlZGdlIG9mIHRoZSBzZWVrIGJhci5cclxuICAgICAqIEBwYXJhbSBldmVudFBhZ2VYIHRoZSBwYWdlWCBjb29yZGluYXRlIG9mIGFuIGV2ZW50IHRvIGNhbGN1bGF0ZSB0aGUgb2Zmc2V0IGZyb21cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IGEgbnVtYmVyIGluIHRoZSByYW5nZSBvZiBbMCwgMV0sIHdoZXJlIDAgaXMgdGhlIGxlZnQgZWRnZSBhbmQgMSBpcyB0aGUgcmlnaHQgZWRnZVxyXG4gICAgICovXHJcbiAgICBTZWVrQmFyLnByb3RvdHlwZS5nZXRIb3Jpem9udGFsT2Zmc2V0ID0gZnVuY3Rpb24gKGV2ZW50UGFnZVgpIHtcclxuICAgICAgICB2YXIgZWxlbWVudE9mZnNldFB4ID0gdGhpcy5zZWVrQmFyLm9mZnNldCgpLmxlZnQ7XHJcbiAgICAgICAgdmFyIHdpZHRoUHggPSB0aGlzLnNlZWtCYXIud2lkdGgoKTtcclxuICAgICAgICB2YXIgb2Zmc2V0UHggPSBldmVudFBhZ2VYIC0gZWxlbWVudE9mZnNldFB4O1xyXG4gICAgICAgIHZhciBvZmZzZXQgPSAxIC8gd2lkdGhQeCAqIG9mZnNldFB4O1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNhbml0aXplT2Zmc2V0KG9mZnNldCk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSB2ZXJ0aWNhbCBvZmZzZXQgb2YgYSBtb3VzZS90b3VjaCBldmVudCBwb2ludCBmcm9tIHRoZSBib3R0b20gZWRnZSBvZiB0aGUgc2VlayBiYXIuXHJcbiAgICAgKiBAcGFyYW0gZXZlbnRQYWdlWSB0aGUgcGFnZVggY29vcmRpbmF0ZSBvZiBhbiBldmVudCB0byBjYWxjdWxhdGUgdGhlIG9mZnNldCBmcm9tXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfSBhIG51bWJlciBpbiB0aGUgcmFuZ2Ugb2YgWzAsIDFdLCB3aGVyZSAwIGlzIHRoZSBib3R0b20gZWRnZSBhbmQgMSBpcyB0aGUgdG9wIGVkZ2VcclxuICAgICAqL1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUuZ2V0VmVydGljYWxPZmZzZXQgPSBmdW5jdGlvbiAoZXZlbnRQYWdlWSkge1xyXG4gICAgICAgIHZhciBlbGVtZW50T2Zmc2V0UHggPSB0aGlzLnNlZWtCYXIub2Zmc2V0KCkudG9wO1xyXG4gICAgICAgIHZhciB3aWR0aFB4ID0gdGhpcy5zZWVrQmFyLmhlaWdodCgpO1xyXG4gICAgICAgIHZhciBvZmZzZXRQeCA9IGV2ZW50UGFnZVkgLSBlbGVtZW50T2Zmc2V0UHg7XHJcbiAgICAgICAgdmFyIG9mZnNldCA9IDEgLyB3aWR0aFB4ICogb2Zmc2V0UHg7XHJcbiAgICAgICAgcmV0dXJuIDEgLSB0aGlzLnNhbml0aXplT2Zmc2V0KG9mZnNldCk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIHRoZSBtb3VzZSBvciB0b3VjaCBldmVudCBvZmZzZXQgZm9yIHRoZSBjdXJyZW50IGNvbmZpZ3VyYXRpb24gKGhvcml6b250YWwgb3IgdmVydGljYWwpLlxyXG4gICAgICogQHBhcmFtIGUgdGhlIGV2ZW50IHRvIGNhbGN1bGF0ZSB0aGUgb2Zmc2V0IGZyb21cclxuICAgICAqIEByZXR1cm5zIHtudW1iZXJ9IGEgbnVtYmVyIGluIHRoZSByYW5nZSBvZiBbMCwgMV1cclxuICAgICAqIEBzZWUgI2dldEhvcml6b250YWxPZmZzZXRcclxuICAgICAqIEBzZWUgI2dldFZlcnRpY2FsT2Zmc2V0XHJcbiAgICAgKi9cclxuICAgIFNlZWtCYXIucHJvdG90eXBlLmdldE9mZnNldCA9IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgaWYgKHRoaXMudG91Y2hTdXBwb3J0ZWQgJiYgZSBpbnN0YW5jZW9mIFRvdWNoRXZlbnQpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLnZlcnRpY2FsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRWZXJ0aWNhbE9mZnNldChlLnR5cGUgPT09ICd0b3VjaGVuZCcgPyBlLmNoYW5nZWRUb3VjaGVzWzBdLnBhZ2VZIDogZS50b3VjaGVzWzBdLnBhZ2VZKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEhvcml6b250YWxPZmZzZXQoZS50eXBlID09PSAndG91Y2hlbmQnID8gZS5jaGFuZ2VkVG91Y2hlc1swXS5wYWdlWCA6IGUudG91Y2hlc1swXS5wYWdlWCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAoZSBpbnN0YW5jZW9mIE1vdXNlRXZlbnQpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuY29uZmlnLnZlcnRpY2FsKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5nZXRWZXJ0aWNhbE9mZnNldChlLnBhZ2VZKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLmdldEhvcml6b250YWxPZmZzZXQoZS5wYWdlWCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGlmIChjb25zb2xlKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ2ludmFsaWQgZXZlbnQnKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gMDtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBTYW5pdGl6ZXMgdGhlIG1vdXNlIG9mZnNldCB0byB0aGUgcmFuZ2Ugb2YgWzAsIDFdLlxyXG4gICAgICpcclxuICAgICAqIFdoZW4gdHJhY2tpbmcgdGhlIG1vdXNlIG91dHNpZGUgdGhlIHNlZWsgYmFyLCB0aGUgb2Zmc2V0IGNhbiBiZSBvdXRzaWRlIHRoZSBkZXNpcmVkIHJhbmdlIGFuZCB0aGlzIG1ldGhvZFxyXG4gICAgICogbGltaXRzIGl0IHRvIHRoZSBkZXNpcmVkIHJhbmdlLiBFLmcuIGEgbW91c2UgZXZlbnQgbGVmdCBvZiB0aGUgbGVmdCBlZGdlIG9mIGEgc2VlayBiYXIgeWllbGRzIGFuIG9mZnNldCBiZWxvd1xyXG4gICAgICogemVybywgYnV0IHRvIGRpc3BsYXkgdGhlIHNlZWsgdGFyZ2V0IG9uIHRoZSBzZWVrIGJhciwgd2UgbmVlZCB0byBsaW1pdCBpdCB0byB6ZXJvLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBvZmZzZXQgdGhlIG9mZnNldCB0byBzYW5pdGl6ZVxyXG4gICAgICogQHJldHVybnMge251bWJlcn0gdGhlIHNhbml0aXplZCBvZmZzZXQuXHJcbiAgICAgKi9cclxuICAgIFNlZWtCYXIucHJvdG90eXBlLnNhbml0aXplT2Zmc2V0ID0gZnVuY3Rpb24gKG9mZnNldCkge1xyXG4gICAgICAgIC8vIFNpbmNlIHdlIHRyYWNrIG1vdXNlIG1vdmVzIG92ZXIgdGhlIHdob2xlIGRvY3VtZW50LCB0aGUgdGFyZ2V0IGNhbiBiZSBvdXRzaWRlIHRoZSBzZWVrIHJhbmdlLFxyXG4gICAgICAgIC8vIGFuZCB3ZSBuZWVkIHRvIGxpbWl0IGl0IHRvIHRoZSBbMCwgMV0gcmFuZ2UuXHJcbiAgICAgICAgaWYgKG9mZnNldCA8IDApIHtcclxuICAgICAgICAgICAgb2Zmc2V0ID0gMDtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSBpZiAob2Zmc2V0ID4gMSkge1xyXG4gICAgICAgICAgICBvZmZzZXQgPSAxO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gb2Zmc2V0O1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgcG9zaXRpb24gb2YgdGhlIHBsYXliYWNrIHBvc2l0aW9uIGluZGljYXRvci5cclxuICAgICAqIEBwYXJhbSBwZXJjZW50IGEgbnVtYmVyIGJldHdlZW4gMCBhbmQgMTAwIGFzIHJldHVybmVkIGJ5IHRoZSBwbGF5ZXJcclxuICAgICAqL1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUuc2V0UGxheWJhY2tQb3NpdGlvbiA9IGZ1bmN0aW9uIChwZXJjZW50KSB7XHJcbiAgICAgICAgdGhpcy5wbGF5YmFja1Bvc2l0aW9uUGVyY2VudGFnZSA9IHBlcmNlbnQ7XHJcbiAgICAgICAgLy8gU2V0IHBvc2l0aW9uIG9mIHRoZSBiYXJcclxuICAgICAgICB0aGlzLnNldFBvc2l0aW9uKHRoaXMuc2Vla0JhclBsYXliYWNrUG9zaXRpb24sIHBlcmNlbnQpO1xyXG4gICAgICAgIC8vIFNldCBwb3NpdGlvbiBvZiB0aGUgbWFya2VyXHJcbiAgICAgICAgdmFyIHRvdGFsU2l6ZSA9ICh0aGlzLmNvbmZpZy52ZXJ0aWNhbCA/ICh0aGlzLnNlZWtCYXIuaGVpZ2h0KCkgLSB0aGlzLnNlZWtCYXJQbGF5YmFja1Bvc2l0aW9uTWFya2VyLmhlaWdodCgpKSA6IHRoaXMuc2Vla0Jhci53aWR0aCgpKTtcclxuICAgICAgICB2YXIgcHggPSAodG90YWxTaXplKSAvIDEwMCAqIHBlcmNlbnQ7XHJcbiAgICAgICAgaWYgKHRoaXMuY29uZmlnLnZlcnRpY2FsKSB7XHJcbiAgICAgICAgICAgIHB4ID0gdGhpcy5zZWVrQmFyLmhlaWdodCgpIC0gcHggLSB0aGlzLnNlZWtCYXJQbGF5YmFja1Bvc2l0aW9uTWFya2VyLmhlaWdodCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc3R5bGUgPSB0aGlzLmNvbmZpZy52ZXJ0aWNhbCA/XHJcbiAgICAgICAgICAgIC8vIC1tcy10cmFuc2Zvcm0gcmVxdWlyZWQgZm9yIElFOVxyXG4gICAgICAgICAgICB7ICd0cmFuc2Zvcm0nOiAndHJhbnNsYXRlWSgnICsgcHggKyAncHgpJywgJy1tcy10cmFuc2Zvcm0nOiAndHJhbnNsYXRlWSgnICsgcHggKyAncHgpJyB9IDpcclxuICAgICAgICAgICAgeyAndHJhbnNmb3JtJzogJ3RyYW5zbGF0ZVgoJyArIHB4ICsgJ3B4KScsICctbXMtdHJhbnNmb3JtJzogJ3RyYW5zbGF0ZVgoJyArIHB4ICsgJ3B4KScgfTtcclxuICAgICAgICB0aGlzLnNlZWtCYXJQbGF5YmFja1Bvc2l0aW9uTWFya2VyLmNzcyhzdHlsZSk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZWZyZXNoZXMgdGhlIHBsYXliYWNrIHBvc2l0aW9uLiBDYW4gYmUgdXNlZCBieSBzdWJjbGFzc2VzIHRvIHJlZnJlc2ggdGhlIHBvc2l0aW9uIHdoZW5cclxuICAgICAqIHRoZSBzaXplIG9mIHRoZSBjb21wb25lbnQgY2hhbmdlcy5cclxuICAgICAqL1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUucmVmcmVzaFBsYXliYWNrUG9zaXRpb24gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5zZXRQbGF5YmFja1Bvc2l0aW9uKHRoaXMucGxheWJhY2tQb3NpdGlvblBlcmNlbnRhZ2UpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgcG9zaXRpb24gdW50aWwgd2hpY2ggbWVkaWEgaXMgYnVmZmVyZWQuXHJcbiAgICAgKiBAcGFyYW0gcGVyY2VudCBhIG51bWJlciBiZXR3ZWVuIDAgYW5kIDEwMFxyXG4gICAgICovXHJcbiAgICBTZWVrQmFyLnByb3RvdHlwZS5zZXRCdWZmZXJQb3NpdGlvbiA9IGZ1bmN0aW9uIChwZXJjZW50KSB7XHJcbiAgICAgICAgdGhpcy5zZXRQb3NpdGlvbih0aGlzLnNlZWtCYXJCdWZmZXJQb3NpdGlvbiwgcGVyY2VudCk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIHRoZSBwb3NpdGlvbiB3aGVyZSBhIHNlZWssIGlmIGV4ZWN1dGVkLCB3b3VsZCBqdW1wIHRvLlxyXG4gICAgICogQHBhcmFtIHBlcmNlbnQgYSBudW1iZXIgYmV0d2VlbiAwIGFuZCAxMDBcclxuICAgICAqL1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUuc2V0U2Vla1Bvc2l0aW9uID0gZnVuY3Rpb24gKHBlcmNlbnQpIHtcclxuICAgICAgICB0aGlzLnNldFBvc2l0aW9uKHRoaXMuc2Vla0JhclNlZWtQb3NpdGlvbiwgcGVyY2VudCk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBTZXQgdGhlIGFjdHVhbCBwb3NpdGlvbiAod2lkdGggb3IgaGVpZ2h0KSBvZiBhIERPTSBlbGVtZW50IHRoYXQgcmVwcmVzZW50IGEgYmFyIGluIHRoZSBzZWVrIGJhci5cclxuICAgICAqIEBwYXJhbSBlbGVtZW50IHRoZSBlbGVtZW50IHRvIHNldCB0aGUgcG9zaXRpb24gZm9yXHJcbiAgICAgKiBAcGFyYW0gcGVyY2VudCBhIG51bWJlciBiZXR3ZWVuIDAgYW5kIDEwMFxyXG4gICAgICovXHJcbiAgICBTZWVrQmFyLnByb3RvdHlwZS5zZXRQb3NpdGlvbiA9IGZ1bmN0aW9uIChlbGVtZW50LCBwZXJjZW50KSB7XHJcbiAgICAgICAgdmFyIHNjYWxlID0gcGVyY2VudCAvIDEwMDtcclxuICAgICAgICB2YXIgc3R5bGUgPSB0aGlzLmNvbmZpZy52ZXJ0aWNhbCA/XHJcbiAgICAgICAgICAgIC8vIC1tcy10cmFuc2Zvcm0gcmVxdWlyZWQgZm9yIElFOVxyXG4gICAgICAgICAgICB7ICd0cmFuc2Zvcm0nOiAnc2NhbGVZKCcgKyBzY2FsZSArICcpJywgJy1tcy10cmFuc2Zvcm0nOiAnc2NhbGVZKCcgKyBzY2FsZSArICcpJyB9IDpcclxuICAgICAgICAgICAgeyAndHJhbnNmb3JtJzogJ3NjYWxlWCgnICsgc2NhbGUgKyAnKScsICctbXMtdHJhbnNmb3JtJzogJ3NjYWxlWCgnICsgc2NhbGUgKyAnKScgfTtcclxuICAgICAgICBlbGVtZW50LmNzcyhzdHlsZSk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBQdXRzIHRoZSBzZWVrIGJhciBpbnRvIG9yIG91dCBvZiBzZWVraW5nIHN0YXRlIGJ5IGFkZGluZy9yZW1vdmluZyBhIGNsYXNzIHRvIHRoZSBET00gZWxlbWVudC4gVGhpcyBjYW4gYmUgdXNlZFxyXG4gICAgICogdG8gYWRqdXN0IHRoZSBzdHlsaW5nIHdoaWxlIHNlZWtpbmcuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHNlZWtpbmcgc2hvdWxkIGJlIHRydWUgd2hlbiBlbnRlcmluZyBzZWVrIHN0YXRlLCBmYWxzZSB3aGVuIGV4aXRpbmcgdGhlIHNlZWsgc3RhdGVcclxuICAgICAqL1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUuc2V0U2Vla2luZyA9IGZ1bmN0aW9uIChzZWVraW5nKSB7XHJcbiAgICAgICAgaWYgKHNlZWtpbmcpIHtcclxuICAgICAgICAgICAgdGhpcy5nZXREb21FbGVtZW50KCkuYWRkQ2xhc3ModGhpcy5wcmVmaXhDc3MoU2Vla0Jhci5DTEFTU19TRUVLSU5HKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aGlzLmdldERvbUVsZW1lbnQoKS5yZW1vdmVDbGFzcyh0aGlzLnByZWZpeENzcyhTZWVrQmFyLkNMQVNTX1NFRUtJTkcpKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBDaGVja3MgaWYgdGhlIHNlZWsgYmFyIGlzIGN1cnJlbnRseSBpbiB0aGUgc2VlayBzdGF0ZS5cclxuICAgICAqIEByZXR1cm5zIHtib29sZWFufSB0cnVlIGlmIGluIHNlZWsgc3RhdGUsIGVsc2UgZmFsc2VcclxuICAgICAqL1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUuaXNTZWVraW5nID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmdldERvbUVsZW1lbnQoKS5oYXNDbGFzcyh0aGlzLnByZWZpeENzcyhTZWVrQmFyLkNMQVNTX1NFRUtJTkcpKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIENoZWNrcyBpZiB0aGUgc2VlayBiYXIgaGFzIGEge0BsaW5rIFNlZWtCYXJMYWJlbH0uXHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpZiB0aGUgc2VlayBiYXIgaGFzIGEgbGFiZWwsIGVsc2UgZmFsc2VcclxuICAgICAqL1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUuaGFzTGFiZWwgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMubGFiZWwgIT0gbnVsbDtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIGxhYmVsIG9mIHRoaXMgc2VlayBiYXIuXHJcbiAgICAgKiBAcmV0dXJucyB7U2Vla0JhckxhYmVsfSB0aGUgbGFiZWwgaWYgdGhpcyBzZWVrIGJhciBoYXMgYSBsYWJlbCwgZWxzZSBudWxsXHJcbiAgICAgKi9cclxuICAgIFNlZWtCYXIucHJvdG90eXBlLmdldExhYmVsID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmxhYmVsO1xyXG4gICAgfTtcclxuICAgIFNlZWtCYXIucHJvdG90eXBlLm9uU2Vla0V2ZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRoaXMuc2Vla0JhckV2ZW50cy5vblNlZWsuZGlzcGF0Y2godGhpcyk7XHJcbiAgICB9O1xyXG4gICAgU2Vla0Jhci5wcm90b3R5cGUub25TZWVrUHJldmlld0V2ZW50ID0gZnVuY3Rpb24gKHBlcmNlbnRhZ2UsIHNjcnViYmluZykge1xyXG4gICAgICAgIHZhciBzbmFwcGVkTWFya2VyID0gdGhpcy5nZXRNYXJrZXJBdFBvc2l0aW9uKHBlcmNlbnRhZ2UpO1xyXG4gICAgICAgIGlmICh0aGlzLmxhYmVsKSB7XHJcbiAgICAgICAgICAgIHRoaXMubGFiZWwuZ2V0RG9tRWxlbWVudCgpLmNzcyh7XHJcbiAgICAgICAgICAgICAgICAnbGVmdCc6IChzbmFwcGVkTWFya2VyID8gc25hcHBlZE1hcmtlci50aW1lIDogcGVyY2VudGFnZSkgKyAnJScsXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnNlZWtCYXJFdmVudHMub25TZWVrUHJldmlldy5kaXNwYXRjaCh0aGlzLCB7XHJcbiAgICAgICAgICAgIHNjcnViYmluZzogc2NydWJiaW5nLFxyXG4gICAgICAgICAgICBwb3NpdGlvbjogcGVyY2VudGFnZSxcclxuICAgICAgICAgICAgbWFya2VyOiBzbmFwcGVkTWFya2VyLFxyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAgIFNlZWtCYXIucHJvdG90eXBlLm9uU2Vla2VkRXZlbnQgPSBmdW5jdGlvbiAocGVyY2VudGFnZSkge1xyXG4gICAgICAgIHRoaXMuc2Vla0JhckV2ZW50cy5vblNlZWtlZC5kaXNwYXRjaCh0aGlzLCBwZXJjZW50YWdlKTtcclxuICAgIH07XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoU2Vla0Jhci5wcm90b3R5cGUsIFwib25TZWVrXCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXRzIHRoZSBldmVudCB0aGF0IGlzIGZpcmVkIHdoZW4gYSBzY3J1YmJpbmcgc2VlayBvcGVyYXRpb24gaXMgc3RhcnRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnQ8U2Vla0JhciwgTm9BcmdzPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2Vla0JhckV2ZW50cy5vblNlZWsuZ2V0RXZlbnQoKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShTZWVrQmFyLnByb3RvdHlwZSwgXCJvblNlZWtQcmV2aWV3XCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBHZXRzIHRoZSBldmVudCB0aGF0IGlzIGZpcmVkIGR1cmluZyBhIHNjcnViYmluZyBzZWVrICh0byBpbmRpY2F0ZSB0aGF0IHRoZSBzZWVrIHByZXZpZXcsIGkuZS4gdGhlIHZpZGVvIGZyYW1lLFxyXG4gICAgICAgICAqIHNob3VsZCBiZSB1cGRhdGVkKSwgb3IgZHVyaW5nIGEgbm9ybWFsIHNlZWsgcHJldmlldyB3aGVuIHRoZSBzZWVrIGJhciBpcyBob3ZlcmVkIChhbmQgdGhlIHNlZWsgdGFyZ2V0LFxyXG4gICAgICAgICAqIGkuZS4gdGhlIHNlZWsgYmFyIGxhYmVsLCBzaG91bGQgYmUgdXBkYXRlZCkuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50PFNlZWtCYXIsIFNlZWtQcmV2aWV3RXZlbnRBcmdzPn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2Vla0JhckV2ZW50cy5vblNlZWtQcmV2aWV3LmdldEV2ZW50KCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoU2Vla0Jhci5wcm90b3R5cGUsIFwib25TZWVrZWRcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldHMgdGhlIGV2ZW50IHRoYXQgaXMgZmlyZWQgd2hlbiBhIHNjcnViYmluZyBzZWVrIGhhcyBmaW5pc2hlZCBvciB3aGVuIGEgZGlyZWN0IHNlZWsgaXMgaXNzdWVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtFdmVudDxTZWVrQmFyLCBudW1iZXI+fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zZWVrQmFyRXZlbnRzLm9uU2Vla2VkLmdldEV2ZW50KCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICBTZWVrQmFyLnByb3RvdHlwZS5vblNob3dFdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLm9uU2hvd0V2ZW50LmNhbGwodGhpcyk7XHJcbiAgICAgICAgLy8gUmVmcmVzaCB0aGUgcG9zaXRpb24gb2YgdGhlIHBsYXliYWNrIHBvc2l0aW9uIHdoZW4gdGhlIHNlZWsgYmFyIGJlY29tZXMgdmlzaWJsZS4gVG8gY29ycmVjdGx5IHNldCB0aGUgcG9zaXRpb24sXHJcbiAgICAgICAgLy8gdGhlIERPTSBlbGVtZW50IG11c3QgYmUgZnVsbHkgaW5pdGlhbGl6ZWQgYW4gaGF2ZSBpdHMgc2l6ZSBjYWxjdWxhdGVkLCBiZWNhdXNlIHRoZSBwb3NpdGlvbiBpcyBzZXQgYXMgYW4gYWJzb2x1dGVcclxuICAgICAgICAvLyB2YWx1ZSBjYWxjdWxhdGVkIGZyb20gdGhlIHNpemUuIFRoaXMgcmVxdWlyZWQgc2l6ZSBpcyBub3Qga25vd24gd2hlbiBpdCBpcyBoaWRkZW4uXHJcbiAgICAgICAgLy8gRm9yIHN1Y2ggY2FzZXMsIHdlIHJlZnJlc2ggdGhlIHBvc2l0aW9uIGhlcmUgaW4gb25TaG93IGJlY2F1c2UgaGVyZSBpdCBpcyBndWFyYW50ZWVkIHRoYXQgdGhlIGNvbXBvbmVudCBrbm93c1xyXG4gICAgICAgIC8vIGl0cyBzaXplIGFuZCBjYW4gc2V0IHRoZSBwb3NpdGlvbiBjb3JyZWN0bHkuXHJcbiAgICAgICAgdGhpcy5yZWZyZXNoUGxheWJhY2tQb3NpdGlvbigpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBTZWVrQmFyO1xyXG59KGNvbXBvbmVudF8xLkNvbXBvbmVudCkpO1xyXG5TZWVrQmFyLlNNT09USF9QTEFZQkFDS19QT1NJVElPTl9VUERBVEVfRElTQUJMRUQgPSAtMTtcclxuLyoqXHJcbiAqIFRoZSBDU1MgY2xhc3MgdGhhdCBpcyBhZGRlZCB0byB0aGUgRE9NIGVsZW1lbnQgd2hpbGUgdGhlIHNlZWsgYmFyIGlzIGluICdzZWVraW5nJyBzdGF0ZS5cclxuICovXHJcblNlZWtCYXIuQ0xBU1NfU0VFS0lORyA9ICdzZWVraW5nJztcclxuZXhwb3J0cy5TZWVrQmFyID0gU2Vla0JhcjtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3NlZWtiYXIudHNcbi8vIG1vZHVsZSBpZCA9IDEzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBTdHJpbmdVdGlscztcclxuKGZ1bmN0aW9uIChTdHJpbmdVdGlscykge1xyXG4gICAgU3RyaW5nVXRpbHMuRk9STUFUX0hITU1TUyA9ICdoaDptbTpzcyc7XHJcbiAgICBTdHJpbmdVdGlscy5GT1JNQVRfTU1TUyA9ICdtbTpzcyc7XHJcbiAgICAvKipcclxuICAgICAqIEZvcm1hdHMgYSBudW1iZXIgb2Ygc2Vjb25kcyBpbnRvIGEgdGltZSBzdHJpbmcgd2l0aCB0aGUgcGF0dGVybiBoaDptbTpzcy5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gdG90YWxTZWNvbmRzIHRoZSB0b3RhbCBudW1iZXIgb2Ygc2Vjb25kcyB0byBmb3JtYXQgdG8gc3RyaW5nXHJcbiAgICAgKiBAcGFyYW0gZm9ybWF0IHRoZSB0aW1lIGZvcm1hdCB0byBvdXRwdXQgKGRlZmF1bHQ6IGhoOm1tOnNzKVxyXG4gICAgICogQHJldHVybnMge3N0cmluZ30gdGhlIGZvcm1hdHRlZCB0aW1lIHN0cmluZ1xyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBzZWNvbmRzVG9UaW1lKHRvdGFsU2Vjb25kcywgZm9ybWF0KSB7XHJcbiAgICAgICAgaWYgKGZvcm1hdCA9PT0gdm9pZCAwKSB7IGZvcm1hdCA9IFN0cmluZ1V0aWxzLkZPUk1BVF9ISE1NU1M7IH1cclxuICAgICAgICB2YXIgaXNOZWdhdGl2ZSA9IHRvdGFsU2Vjb25kcyA8IDA7XHJcbiAgICAgICAgaWYgKGlzTmVnYXRpdmUpIHtcclxuICAgICAgICAgICAgLy8gSWYgdGhlIHRpbWUgaXMgbmVnYXRpdmUsIHdlIG1ha2UgaXQgcG9zaXRpdmUgZm9yIHRoZSBjYWxjdWxhdGlvbiBiZWxvd1xyXG4gICAgICAgICAgICAvLyAoZWxzZSB3ZSdkIGdldCBhbGwgbmVnYXRpdmUgbnVtYmVycykgYW5kIHJlYXR0YWNoIHRoZSBuZWdhdGl2ZSBzaWduIGxhdGVyLlxyXG4gICAgICAgICAgICB0b3RhbFNlY29uZHMgPSAtdG90YWxTZWNvbmRzO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBTcGxpdCBpbnRvIHNlcGFyYXRlIHRpbWUgcGFydHNcclxuICAgICAgICB2YXIgaG91cnMgPSBNYXRoLmZsb29yKHRvdGFsU2Vjb25kcyAvIDM2MDApO1xyXG4gICAgICAgIHZhciBtaW51dGVzID0gTWF0aC5mbG9vcih0b3RhbFNlY29uZHMgLyA2MCkgLSBob3VycyAqIDYwO1xyXG4gICAgICAgIHZhciBzZWNvbmRzID0gTWF0aC5mbG9vcih0b3RhbFNlY29uZHMpICUgNjA7XHJcbiAgICAgICAgcmV0dXJuIChpc05lZ2F0aXZlID8gJy0nIDogJycpICsgZm9ybWF0XHJcbiAgICAgICAgICAgIC5yZXBsYWNlKCdoaCcsIGxlZnRQYWRXaXRoWmVyb3MoaG91cnMsIDIpKVxyXG4gICAgICAgICAgICAucmVwbGFjZSgnbW0nLCBsZWZ0UGFkV2l0aFplcm9zKG1pbnV0ZXMsIDIpKVxyXG4gICAgICAgICAgICAucmVwbGFjZSgnc3MnLCBsZWZ0UGFkV2l0aFplcm9zKHNlY29uZHMsIDIpKTtcclxuICAgIH1cclxuICAgIFN0cmluZ1V0aWxzLnNlY29uZHNUb1RpbWUgPSBzZWNvbmRzVG9UaW1lO1xyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0cyBhIG51bWJlciB0byBhIHN0cmluZyBhbmQgbGVmdC1wYWRzIGl0IHdpdGggemVyb3MgdG8gdGhlIHNwZWNpZmllZCBsZW5ndGguXHJcbiAgICAgKiBFeGFtcGxlOiBsZWZ0UGFkV2l0aFplcm9zKDEyMywgNSkgPT4gJzAwMTIzJ1xyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBudW0gdGhlIG51bWJlciB0byBjb252ZXJ0IHRvIHN0cmluZyBhbmQgcGFkIHdpdGggemVyb3NcclxuICAgICAqIEBwYXJhbSBsZW5ndGggdGhlIGRlc2lyZWQgbGVuZ3RoIG9mIHRoZSBwYWRkZWQgc3RyaW5nXHJcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSB0aGUgcGFkZGVkIG51bWJlciBhcyBzdHJpbmdcclxuICAgICAqL1xyXG4gICAgZnVuY3Rpb24gbGVmdFBhZFdpdGhaZXJvcyhudW0sIGxlbmd0aCkge1xyXG4gICAgICAgIHZhciB0ZXh0ID0gbnVtICsgJyc7XHJcbiAgICAgICAgdmFyIHBhZGRpbmcgPSAnMDAwMDAwMDAwMCcuc3Vic3RyKDAsIGxlbmd0aCAtIHRleHQubGVuZ3RoKTtcclxuICAgICAgICByZXR1cm4gcGFkZGluZyArIHRleHQ7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIEZpbGxzIG91dCBwbGFjZWhvbGRlcnMgaW4gYW4gYWQgbWVzc2FnZS5cclxuICAgICAqXHJcbiAgICAgKiBIYXMgdGhlIHBsYWNlaG9sZGVycyAne3JlbWFpbmluZ1RpbWVbZm9ybWF0U3RyaW5nXX0nLCAne3BsYXllZFRpbWVbZm9ybWF0U3RyaW5nXX0nIGFuZFxyXG4gICAgICogJ3thZER1cmF0aW9uW2Zvcm1hdFN0cmluZ119Jywgd2hpY2ggYXJlIHJlcGxhY2VkIGJ5IHRoZSByZW1haW5pbmcgdGltZSB1bnRpbCB0aGUgYWQgY2FuIGJlIHNraXBwZWQsIHRoZSBjdXJyZW50XHJcbiAgICAgKiB0aW1lIG9yIHRoZSBhZCBkdXJhdGlvbi4gVGhlIGZvcm1hdCBzdHJpbmcgaXMgb3B0aW9uYWwuIElmIG5vdCBzcGVjaWZpZWQsIHRoZSBwbGFjZWhvbGRlciBpcyByZXBsYWNlZCBieSB0aGUgdGltZVxyXG4gICAgICogaW4gc2Vjb25kcy4gSWYgc3BlY2lmaWVkLCBpdCBtdXN0IGJlIG9mIHRoZSBmb2xsb3dpbmcgZm9ybWF0OlxyXG4gICAgICogLSAlZCAtIEluc2VydHMgdGhlIHRpbWUgYXMgYW4gaW50ZWdlci5cclxuICAgICAqIC0gJTBOZCAtIEluc2VydHMgdGhlIHRpbWUgYXMgYW4gaW50ZWdlciB3aXRoIGxlYWRpbmcgemVyb2VzLCBpZiB0aGUgbGVuZ3RoIG9mIHRoZSB0aW1lIHN0cmluZyBpcyBzbWFsbGVyIHRoYW4gTi5cclxuICAgICAqIC0gJWYgLSBJbnNlcnRzIHRoZSB0aW1lIGFzIGEgZmxvYXQuXHJcbiAgICAgKiAtICUwTmYgLSBJbnNlcnRzIHRoZSB0aW1lIGFzIGEgZmxvYXQgd2l0aCBsZWFkaW5nIHplcm9lcy5cclxuICAgICAqIC0gJS5NZiAtIEluc2VydHMgdGhlIHRpbWUgYXMgYSBmbG9hdCB3aXRoIE0gZGVjaW1hbCBwbGFjZXMuIENhbiBiZSBjb21iaW5lZCB3aXRoICUwTmYsIGUuZy4gJTA0LjJmICh0aGUgdGltZVxyXG4gICAgICogMTAuMTIzXHJcbiAgICAgKiB3b3VsZCBiZSBwcmludGVkIGFzIDAwMTAuMTIpLlxyXG4gICAgICogLSAlaGg6bW06c3NcclxuICAgICAqIC0gJW1tOnNzXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIGFkTWVzc2FnZSBhbiBhZCBtZXNzYWdlIHdpdGggb3B0aW9uYWwgcGxhY2Vob2xkZXJzIHRvIGZpbGxcclxuICAgICAqIEBwYXJhbSBza2lwT2Zmc2V0IGlmIHNwZWNpZmllZCwge3JlbWFpbmluZ1RpbWV9IHdpbGwgYmUgZmlsbGVkIHdpdGggdGhlIHJlbWFpbmluZyB0aW1lIHVudGlsIHRoZSBhZCBjYW4gYmUgc2tpcHBlZFxyXG4gICAgICogQHBhcmFtIHBsYXllciB0aGUgcGxheWVyIHRvIGdldCB0aGUgdGltZSBkYXRhIGZyb21cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IHRoZSBhZCBtZXNzYWdlIHdpdGggZmlsbGVkIHBsYWNlaG9sZGVyc1xyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiByZXBsYWNlQWRNZXNzYWdlUGxhY2Vob2xkZXJzKGFkTWVzc2FnZSwgc2tpcE9mZnNldCwgcGxheWVyKSB7XHJcbiAgICAgICAgdmFyIGFkTWVzc2FnZVBsYWNlaG9sZGVyUmVnZXggPSBuZXcgUmVnRXhwKCdcXFxceyhyZW1haW5pbmdUaW1lfHBsYXllZFRpbWV8YWREdXJhdGlvbikofXwlKCgwWzEtOV1cXFxcZCooXFxcXC5cXFxcZCsoZHxmKXxkfGYpfFxcXFwuXFxcXGQrZnxkfGYpfGhoOm1tOnNzfG1tOnNzKX0pJywgJ2cnKTtcclxuICAgICAgICByZXR1cm4gYWRNZXNzYWdlLnJlcGxhY2UoYWRNZXNzYWdlUGxhY2Vob2xkZXJSZWdleCwgZnVuY3Rpb24gKGZvcm1hdFN0cmluZykge1xyXG4gICAgICAgICAgICB2YXIgdGltZSA9IDA7XHJcbiAgICAgICAgICAgIGlmIChmb3JtYXRTdHJpbmcuaW5kZXhPZigncmVtYWluaW5nVGltZScpID4gLTEpIHtcclxuICAgICAgICAgICAgICAgIGlmIChza2lwT2Zmc2V0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGltZSA9IE1hdGguY2VpbChza2lwT2Zmc2V0IC0gcGxheWVyLmdldEN1cnJlbnRUaW1lKCkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGltZSA9IHBsYXllci5nZXREdXJhdGlvbigpIC0gcGxheWVyLmdldEN1cnJlbnRUaW1lKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoZm9ybWF0U3RyaW5nLmluZGV4T2YoJ3BsYXllZFRpbWUnKSA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgICB0aW1lID0gcGxheWVyLmdldEN1cnJlbnRUaW1lKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAoZm9ybWF0U3RyaW5nLmluZGV4T2YoJ2FkRHVyYXRpb24nKSA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgICB0aW1lID0gcGxheWVyLmdldER1cmF0aW9uKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGZvcm1hdE51bWJlcih0aW1lLCBmb3JtYXRTdHJpbmcpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgU3RyaW5nVXRpbHMucmVwbGFjZUFkTWVzc2FnZVBsYWNlaG9sZGVycyA9IHJlcGxhY2VBZE1lc3NhZ2VQbGFjZWhvbGRlcnM7XHJcbiAgICBmdW5jdGlvbiBmb3JtYXROdW1iZXIodGltZSwgZm9ybWF0KSB7XHJcbiAgICAgICAgdmFyIGZvcm1hdFN0cmluZ1ZhbGlkYXRpb25SZWdleCA9IC8lKCgwWzEtOV1cXGQqKFxcLlxcZCsoZHxmKXxkfGYpfFxcLlxcZCtmfGR8Zil8aGg6bW06c3N8bW06c3MpLztcclxuICAgICAgICB2YXIgbGVhZGluZ1plcm9lc1JlZ2V4ID0gLyglMFsxLTldXFxkKikoPz0oXFwuXFxkK2Z8ZnxkKSkvO1xyXG4gICAgICAgIHZhciBkZWNpbWFsUGxhY2VzUmVnZXggPSAvXFwuXFxkKig/PWYpLztcclxuICAgICAgICBpZiAoIWZvcm1hdFN0cmluZ1ZhbGlkYXRpb25SZWdleC50ZXN0KGZvcm1hdCkpIHtcclxuICAgICAgICAgICAgLy8gSWYgdGhlIGZvcm1hdCBpcyBpbnZhbGlkLCB3ZSBzZXQgYSBkZWZhdWx0IGZhbGxiYWNrIGZvcm1hdFxyXG4gICAgICAgICAgICBmb3JtYXQgPSAnJWQnO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBEZXRlcm1pbmUgdGhlIG51bWJlciBvZiBsZWFkaW5nIHplcm9zXHJcbiAgICAgICAgdmFyIGxlYWRpbmdaZXJvZXMgPSAwO1xyXG4gICAgICAgIHZhciBsZWFkaW5nWmVyb2VzTWF0Y2hlcyA9IGZvcm1hdC5tYXRjaChsZWFkaW5nWmVyb2VzUmVnZXgpO1xyXG4gICAgICAgIGlmIChsZWFkaW5nWmVyb2VzTWF0Y2hlcykge1xyXG4gICAgICAgICAgICBsZWFkaW5nWmVyb2VzID0gcGFyc2VJbnQobGVhZGluZ1plcm9lc01hdGNoZXNbMF0uc3Vic3RyaW5nKDIpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gRGV0ZXJtaW5lIHRoZSBudW1iZXIgb2YgZGVjaW1hbCBwbGFjZXNcclxuICAgICAgICB2YXIgbnVtRGVjaW1hbFBsYWNlcyA9IG51bGw7XHJcbiAgICAgICAgdmFyIGRlY2ltYWxQbGFjZXNNYXRjaGVzID0gZm9ybWF0Lm1hdGNoKGRlY2ltYWxQbGFjZXNSZWdleCk7XHJcbiAgICAgICAgaWYgKGRlY2ltYWxQbGFjZXNNYXRjaGVzICYmICFpc05hTihwYXJzZUludChkZWNpbWFsUGxhY2VzTWF0Y2hlc1swXS5zdWJzdHJpbmcoMSkpKSkge1xyXG4gICAgICAgICAgICBudW1EZWNpbWFsUGxhY2VzID0gcGFyc2VJbnQoZGVjaW1hbFBsYWNlc01hdGNoZXNbMF0uc3Vic3RyaW5nKDEpKTtcclxuICAgICAgICAgICAgaWYgKG51bURlY2ltYWxQbGFjZXMgPiAyMCkge1xyXG4gICAgICAgICAgICAgICAgbnVtRGVjaW1hbFBsYWNlcyA9IDIwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIEZsb2F0IGZvcm1hdFxyXG4gICAgICAgIGlmIChmb3JtYXQuaW5kZXhPZignZicpID4gLTEpIHtcclxuICAgICAgICAgICAgdmFyIHRpbWVTdHJpbmcgPSAnJztcclxuICAgICAgICAgICAgaWYgKG51bURlY2ltYWxQbGFjZXMgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgIC8vIEFwcGx5IGZpeGVkIG51bWJlciBvZiBkZWNpbWFsIHBsYWNlc1xyXG4gICAgICAgICAgICAgICAgdGltZVN0cmluZyA9IHRpbWUudG9GaXhlZChudW1EZWNpbWFsUGxhY2VzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRpbWVTdHJpbmcgPSAnJyArIHRpbWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gQXBwbHkgbGVhZGluZyB6ZXJvc1xyXG4gICAgICAgICAgICBpZiAodGltZVN0cmluZy5pbmRleE9mKCcuJykgPiAtMSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGxlZnRQYWRXaXRoWmVyb3ModGltZVN0cmluZywgdGltZVN0cmluZy5sZW5ndGggKyAobGVhZGluZ1plcm9lcyAtIHRpbWVTdHJpbmcuaW5kZXhPZignLicpKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbGVmdFBhZFdpdGhaZXJvcyh0aW1lU3RyaW5nLCBsZWFkaW5nWmVyb2VzKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChmb3JtYXQuaW5kZXhPZignOicpID4gLTEpIHtcclxuICAgICAgICAgICAgdmFyIHRvdGFsU2Vjb25kcyA9IE1hdGguY2VpbCh0aW1lKTtcclxuICAgICAgICAgICAgLy8gaGg6bW06c3MgZm9ybWF0XHJcbiAgICAgICAgICAgIGlmIChmb3JtYXQuaW5kZXhPZignaGgnKSA+IC0xKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc2Vjb25kc1RvVGltZSh0b3RhbFNlY29uZHMpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdmFyIG1pbnV0ZXMgPSBNYXRoLmZsb29yKHRvdGFsU2Vjb25kcyAvIDYwKTtcclxuICAgICAgICAgICAgICAgIHZhciBzZWNvbmRzID0gdG90YWxTZWNvbmRzICUgNjA7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbGVmdFBhZFdpdGhaZXJvcyhtaW51dGVzLCAyKSArICc6JyArIGxlZnRQYWRXaXRoWmVyb3Moc2Vjb25kcywgMik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBsZWZ0UGFkV2l0aFplcm9zKE1hdGguY2VpbCh0aW1lKSwgbGVhZGluZ1plcm9lcyk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59KShTdHJpbmdVdGlscyA9IGV4cG9ydHMuU3RyaW5nVXRpbHMgfHwgKGV4cG9ydHMuU3RyaW5nVXRpbHMgPSB7fSkpO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL3N0cmluZ3V0aWxzLnRzXG4vLyBtb2R1bGUgaWQgPSAxNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGNvbnRhaW5lcl8xID0gcmVxdWlyZShcIi4vY29udGFpbmVyXCIpO1xyXG52YXIgdWl1dGlsc18xID0gcmVxdWlyZShcIi4uL3VpdXRpbHNcIik7XHJcbnZhciBzcGFjZXJfMSA9IHJlcXVpcmUoXCIuL3NwYWNlclwiKTtcclxuLyoqXHJcbiAqIEEgY29udGFpbmVyIGZvciBtYWluIHBsYXllciBjb250cm9sIGNvbXBvbmVudHMsIGUuZy4gcGxheSB0b2dnbGUgYnV0dG9uLCBzZWVrIGJhciwgdm9sdW1lIGNvbnRyb2wsIGZ1bGxzY3JlZW4gdG9nZ2xlXHJcbiAqIGJ1dHRvbi5cclxuICovXHJcbnZhciBDb250cm9sQmFyID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhDb250cm9sQmFyLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gQ29udHJvbEJhcihjb25maWcsIGF1dG9IaWRlKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLWNvbnRyb2xiYXInLFxyXG4gICAgICAgICAgICBoaWRkZW46IGF1dG9IaWRlLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgQ29udHJvbEJhci5wcm90b3R5cGUuY29uZmlndXJlID0gZnVuY3Rpb24gKHBsYXllciwgdWltYW5hZ2VyKSB7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jb25maWd1cmUuY2FsbCh0aGlzLCBwbGF5ZXIsIHVpbWFuYWdlcik7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIC8vIENvdW50cyBob3cgbWFueSBjb21wb25lbnRzIGFyZSBob3ZlcmVkIGFuZCBibG9jayBoaWRpbmcgb2YgdGhlIGNvbnRyb2wgYmFyXHJcbiAgICAgICAgdmFyIGhvdmVyU3RhY2tDb3VudCA9IDA7XHJcbiAgICAgICAgLy8gVHJhY2sgaG92ZXIgc3RhdHVzIG9mIGNoaWxkIGNvbXBvbmVudHNcclxuICAgICAgICB1aXV0aWxzXzEuVUlVdGlscy50cmF2ZXJzZVRyZWUodGhpcywgZnVuY3Rpb24gKGNvbXBvbmVudCkge1xyXG4gICAgICAgICAgICAvLyBEbyBub3QgdHJhY2sgaG92ZXIgc3RhdHVzIG9mIGNoaWxkIGNvbnRhaW5lcnMgb3Igc3BhY2Vycywgb25seSBvZiAncmVhbCcgY29udHJvbHNcclxuICAgICAgICAgICAgaWYgKGNvbXBvbmVudCBpbnN0YW5jZW9mIGNvbnRhaW5lcl8xLkNvbnRhaW5lciB8fCBjb21wb25lbnQgaW5zdGFuY2VvZiBzcGFjZXJfMS5TcGFjZXIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBTdWJzY3JpYmUgaG92ZXIgZXZlbnQgYW5kIGtlZXAgYSBjb3VudCBvZiB0aGUgbnVtYmVyIG9mIGhvdmVyZWQgY2hpbGRyZW5cclxuICAgICAgICAgICAgY29tcG9uZW50Lm9uSG92ZXJDaGFuZ2VkLnN1YnNjcmliZShmdW5jdGlvbiAoc2VuZGVyLCBhcmdzKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYXJncy5ob3ZlcmVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaG92ZXJTdGFja0NvdW50Kys7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBob3ZlclN0YWNrQ291bnQtLTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdWltYW5hZ2VyLm9uQ29udHJvbHNTaG93LnN1YnNjcmliZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChzZWxmLmNvbmZpZy5oaWRkZW4pIHtcclxuICAgICAgICAgICAgICAgIHNlbGYuc2hvdygpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdWltYW5hZ2VyLm9uUHJldmlld0NvbnRyb2xzSGlkZS5zdWJzY3JpYmUoZnVuY3Rpb24gKHNlbmRlciwgYXJncykge1xyXG4gICAgICAgICAgICAvLyBDYW5jZWwgdGhlIGhpZGUgZXZlbnQgaWYgaG92ZXJlZCBjaGlsZCBjb21wb25lbnRzIGJsb2NrIGhpZGluZ1xyXG4gICAgICAgICAgICBhcmdzLmNhbmNlbCA9IChob3ZlclN0YWNrQ291bnQgPiAwKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB1aW1hbmFnZXIub25Db250cm9sc0hpZGUuc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKHNlbGYuY29uZmlnLmhpZGRlbikge1xyXG4gICAgICAgICAgICAgICAgc2VsZi5oaWRlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gQ29udHJvbEJhcjtcclxufShjb250YWluZXJfMS5Db250YWluZXIpKTtcclxuZXhwb3J0cy5Db250cm9sQmFyID0gQ29udHJvbEJhcjtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2NvbnRyb2xiYXIudHNcbi8vIG1vZHVsZSBpZCA9IDE1XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBjb250YWluZXJfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvY29udGFpbmVyXCIpO1xyXG52YXIgVUlVdGlscztcclxuKGZ1bmN0aW9uIChVSVV0aWxzKSB7XHJcbiAgICBmdW5jdGlvbiB0cmF2ZXJzZVRyZWUoY29tcG9uZW50LCB2aXNpdCkge1xyXG4gICAgICAgIHZhciByZWN1cnNpdmVUcmVlV2Fsa2VyID0gZnVuY3Rpb24gKGNvbXBvbmVudCwgcGFyZW50KSB7XHJcbiAgICAgICAgICAgIHZpc2l0KGNvbXBvbmVudCwgcGFyZW50KTtcclxuICAgICAgICAgICAgLy8gSWYgdGhlIGN1cnJlbnQgY29tcG9uZW50IGlzIGEgY29udGFpbmVyLCB2aXNpdCBpdCdzIGNoaWxkcmVuXHJcbiAgICAgICAgICAgIGlmIChjb21wb25lbnQgaW5zdGFuY2VvZiBjb250YWluZXJfMS5Db250YWluZXIpIHtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSBjb21wb25lbnQuZ2V0Q29tcG9uZW50cygpOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBjaGlsZENvbXBvbmVudCA9IF9hW19pXTtcclxuICAgICAgICAgICAgICAgICAgICByZWN1cnNpdmVUcmVlV2Fsa2VyKGNoaWxkQ29tcG9uZW50LCBjb21wb25lbnQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvLyBXYWxrIGFuZCBjb25maWd1cmUgdGhlIGNvbXBvbmVudCB0cmVlXHJcbiAgICAgICAgcmVjdXJzaXZlVHJlZVdhbGtlcihjb21wb25lbnQpO1xyXG4gICAgfVxyXG4gICAgVUlVdGlscy50cmF2ZXJzZVRyZWUgPSB0cmF2ZXJzZVRyZWU7XHJcbn0pKFVJVXRpbHMgPSBleHBvcnRzLlVJVXRpbHMgfHwgKGV4cG9ydHMuVUlVdGlscyA9IHt9KSk7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvdWl1dGlscy50c1xuLy8gbW9kdWxlIGlkID0gMTZcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBjb250YWluZXJfMSA9IHJlcXVpcmUoXCIuL2NvbnRhaW5lclwiKTtcclxudmFyIGRvbV8xID0gcmVxdWlyZShcIi4uL2RvbVwiKTtcclxudmFyIHRpbWVvdXRfMSA9IHJlcXVpcmUoXCIuLi90aW1lb3V0XCIpO1xyXG52YXIgcGxheWVydXRpbHNfMSA9IHJlcXVpcmUoXCIuLi9wbGF5ZXJ1dGlsc1wiKTtcclxuLyoqXHJcbiAqIFRoZSBiYXNlIGNvbnRhaW5lciB0aGF0IGNvbnRhaW5zIGFsbCBvZiB0aGUgVUkuIFRoZSBVSUNvbnRhaW5lciBpcyBwYXNzZWQgdG8gdGhlIHtAbGluayBVSU1hbmFnZXJ9IHRvIGJ1aWxkIGFuZFxyXG4gKiBzZXR1cCB0aGUgVUkuXHJcbiAqL1xyXG52YXIgVUlDb250YWluZXIgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKFVJQ29udGFpbmVyLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gVUlDb250YWluZXIoY29uZmlnKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLXVpY29udGFpbmVyJyxcclxuICAgICAgICAgICAgaGlkZURlbGF5OiAyNTAwLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgVUlDb250YWluZXIucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY29uZmlndXJlLmNhbGwodGhpcywgcGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIHRoaXMuY29uZmlndXJlVUlTaG93SGlkZShwbGF5ZXIsIHVpbWFuYWdlcik7XHJcbiAgICAgICAgdGhpcy5jb25maWd1cmVQbGF5ZXJTdGF0ZXMocGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgfTtcclxuICAgIFVJQ29udGFpbmVyLnByb3RvdHlwZS5jb25maWd1cmVVSVNob3dIaWRlID0gZnVuY3Rpb24gKHBsYXllciwgdWltYW5hZ2VyKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5nZXREb21FbGVtZW50KCk7XHJcbiAgICAgICAgdmFyIGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XHJcbiAgICAgICAgaWYgKGNvbmZpZy5oaWRlRGVsYXkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgIHVpbWFuYWdlci5vbkNvbmZpZ3VyZWQuc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHsgcmV0dXJuIHVpbWFuYWdlci5vbkNvbnRyb2xzU2hvdy5kaXNwYXRjaChfdGhpcyk7IH0pO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBpc1VpU2hvd24gPSBmYWxzZTtcclxuICAgICAgICB2YXIgaXNTZWVraW5nID0gZmFsc2U7XHJcbiAgICAgICAgdmFyIGlzRmlyc3RUb3VjaCA9IHRydWU7XHJcbiAgICAgICAgdmFyIHNob3dVaSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKCFpc1VpU2hvd24pIHtcclxuICAgICAgICAgICAgICAgIC8vIExldCBzdWJzY3JpYmVycyBrbm93IHRoYXQgdGhleSBzaG91bGQgcmV2ZWFsIHRoZW1zZWx2ZXNcclxuICAgICAgICAgICAgICAgIHVpbWFuYWdlci5vbkNvbnRyb2xzU2hvdy5kaXNwYXRjaChfdGhpcyk7XHJcbiAgICAgICAgICAgICAgICBpc1VpU2hvd24gPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIERvbid0IHRyaWdnZXIgdGltZW91dCB3aGlsZSBzZWVraW5nIChpdCB3aWxsIGJlIHRyaWdnZXJlZCBvbmNlIHRoZSBzZWVrIGlzIGZpbmlzaGVkKSBvciBjYXN0aW5nXHJcbiAgICAgICAgICAgIGlmICghaXNTZWVraW5nICYmICFwbGF5ZXIuaXNDYXN0aW5nKCkpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLnVpSGlkZVRpbWVvdXQuc3RhcnQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIGhpZGVVaSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgLy8gSGlkZSB0aGUgVUkgb25seSBpZiBpdCBpcyBzaG93biwgYW5kIGlmIG5vdCBjYXN0aW5nXHJcbiAgICAgICAgICAgIGlmIChpc1VpU2hvd24gJiYgIXBsYXllci5pc0Nhc3RpbmcoKSkge1xyXG4gICAgICAgICAgICAgICAgLy8gSXNzdWUgYSBwcmV2aWV3IGV2ZW50IHRvIGNoZWNrIGlmIHdlIGFyZSBnb29kIHRvIGhpZGUgdGhlIGNvbnRyb2xzXHJcbiAgICAgICAgICAgICAgICB2YXIgcHJldmlld0hpZGVFdmVudEFyZ3MgPSB7fTtcclxuICAgICAgICAgICAgICAgIHVpbWFuYWdlci5vblByZXZpZXdDb250cm9sc0hpZGUuZGlzcGF0Y2goX3RoaXMsIHByZXZpZXdIaWRlRXZlbnRBcmdzKTtcclxuICAgICAgICAgICAgICAgIGlmICghcHJldmlld0hpZGVFdmVudEFyZ3MuY2FuY2VsKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIHByZXZpZXcgd2Fzbid0IGNhbmNlbGVkLCBsZXQgc3Vic2NyaWJlcnMga25vdyB0aGF0IHRoZXkgc2hvdWxkIG5vdyBoaWRlIHRoZW1zZWx2ZXNcclxuICAgICAgICAgICAgICAgICAgICB1aW1hbmFnZXIub25Db250cm9sc0hpZGUuZGlzcGF0Y2goX3RoaXMpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlzVWlTaG93biA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhlIGhpZGUgcHJldmlldyB3YXMgY2FuY2VsZWQsIGNvbnRpbnVlIHRvIHNob3cgVUlcclxuICAgICAgICAgICAgICAgICAgICBzaG93VWkoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgLy8gVGltZW91dCB0byBkZWZlciBVSSBoaWRpbmcgYnkgdGhlIGNvbmZpZ3VyZWQgZGVsYXkgdGltZVxyXG4gICAgICAgIHRoaXMudWlIaWRlVGltZW91dCA9IG5ldyB0aW1lb3V0XzEuVGltZW91dChjb25maWcuaGlkZURlbGF5LCBoaWRlVWkpO1xyXG4gICAgICAgIC8vIE9uIHRvdWNoIGRpc3BsYXlzLCB0aGUgZmlyc3QgdG91Y2ggcmV2ZWFscyB0aGUgVUlcclxuICAgICAgICBjb250YWluZXIub24oJ3RvdWNoZW5kJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgaWYgKCFpc1VpU2hvd24pIHtcclxuICAgICAgICAgICAgICAgIC8vIE9ubHkgaWYgdGhlIFVJIGlzIGhpZGRlbiwgd2UgcHJldmVudCBvdGhlciBhY3Rpb25zIChleGNlcHQgZm9yIHRoZSBmaXJzdCB0b3VjaCkgYW5kIHJldmVhbCB0aGUgVUkgaW5zdGVhZC5cclxuICAgICAgICAgICAgICAgIC8vIFRoZSBmaXJzdCB0b3VjaCBpcyBub3QgcHJldmVudGVkIHRvIGxldCBvdGhlciBsaXN0ZW5lcnMgcmVjZWl2ZSB0aGUgZXZlbnQgYW5kIHRyaWdnZXIgYW4gaW5pdGlhbCBhY3Rpb24sIGUuZy5cclxuICAgICAgICAgICAgICAgIC8vIHRoZSBodWdlIHBsYXliYWNrIGJ1dHRvbiBjYW4gZGlyZWN0bHkgc3RhcnQgcGxheWJhY2sgaW5zdGVhZCBvZiByZXF1aXJpbmcgYSBkb3VibGUgdGFwIHdoaWNoIDEuIHJldmVhbHNcclxuICAgICAgICAgICAgICAgIC8vIHRoZSBVSSBhbmQgMi4gc3RhcnRzIHBsYXliYWNrLlxyXG4gICAgICAgICAgICAgICAgaWYgKGlzRmlyc3RUb3VjaCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlzRmlyc3RUb3VjaCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgc2hvd1VpKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBXaGVuIHRoZSBtb3VzZSBlbnRlcnMsIHdlIHNob3cgdGhlIFVJXHJcbiAgICAgICAgY29udGFpbmVyLm9uKCdtb3VzZWVudGVyJywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBzaG93VWkoKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBXaGVuIHRoZSBtb3VzZSBtb3ZlcyB3aXRoaW4sIHdlIHNob3cgdGhlIFVJXHJcbiAgICAgICAgY29udGFpbmVyLm9uKCdtb3VzZW1vdmUnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHNob3dVaSgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIFdoZW4gdGhlIG1vdXNlIGxlYXZlcywgd2UgY2FuIHByZXBhcmUgdG8gaGlkZSB0aGUgVUksIGV4Y2VwdCBhIHNlZWsgaXMgZ29pbmcgb25cclxuICAgICAgICBjb250YWluZXIub24oJ21vdXNlbGVhdmUnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIC8vIFdoZW4gYSBzZWVrIGlzIGdvaW5nIG9uLCB0aGUgc2VlayBzY3J1YiBwb2ludGVyIG1heSBleGl0IHRoZSBVSSBhcmVhIHdoaWxlIHN0aWxsIHNlZWtpbmcsIGFuZCB3ZSBkbyBub3QgaGlkZVxyXG4gICAgICAgICAgICAvLyB0aGUgVUkgaW4gc3VjaCBjYXNlc1xyXG4gICAgICAgICAgICBpZiAoIWlzU2Vla2luZykge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMudWlIaWRlVGltZW91dC5zdGFydCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdWltYW5hZ2VyLm9uU2Vlay5zdWJzY3JpYmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy51aUhpZGVUaW1lb3V0LmNsZWFyKCk7IC8vIERvbid0IGhpZGUgVUkgd2hpbGUgYSBzZWVrIGlzIGluIHByb2dyZXNzXHJcbiAgICAgICAgICAgIGlzU2Vla2luZyA9IHRydWU7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdWltYW5hZ2VyLm9uU2Vla2VkLnN1YnNjcmliZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlzU2Vla2luZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICBfdGhpcy51aUhpZGVUaW1lb3V0LnN0YXJ0KCk7IC8vIFJlLWVuYWJsZSBVSSBoaWRlIHRpbWVvdXQgYWZ0ZXIgYSBzZWVrXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fQ0FTVF9TVEFSVEVELCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHNob3dVaSgpOyAvLyBTaG93IFVJIHdoZW4gYSBDYXN0IHNlc3Npb24gaGFzIHN0YXJ0ZWQgKFVJIHdpbGwgdGhlbiBzdGF5IHBlcm1hbmVudGx5IG9uIGR1cmluZyB0aGUgc2Vzc2lvbilcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBVSUNvbnRhaW5lci5wcm90b3R5cGUuY29uZmlndXJlUGxheWVyU3RhdGVzID0gZnVuY3Rpb24gKHBsYXllciwgdWltYW5hZ2VyKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2YXIgY29udGFpbmVyID0gdGhpcy5nZXREb21FbGVtZW50KCk7XHJcbiAgICAgICAgLy8gQ29udmVydCBwbGF5ZXIgc3RhdGVzIGludG8gQ1NTIGNsYXNzIG5hbWVzXHJcbiAgICAgICAgdmFyIHN0YXRlQ2xhc3NOYW1lcyA9IFtdO1xyXG4gICAgICAgIGZvciAodmFyIHN0YXRlIGluIHBsYXllcnV0aWxzXzEuUGxheWVyVXRpbHMuUGxheWVyU3RhdGUpIHtcclxuICAgICAgICAgICAgaWYgKGlzTmFOKE51bWJlcihzdGF0ZSkpKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZW51bU5hbWUgPSBwbGF5ZXJ1dGlsc18xLlBsYXllclV0aWxzLlBsYXllclN0YXRlW3BsYXllcnV0aWxzXzEuUGxheWVyVXRpbHMuUGxheWVyU3RhdGVbc3RhdGVdXTtcclxuICAgICAgICAgICAgICAgIHN0YXRlQ2xhc3NOYW1lc1twbGF5ZXJ1dGlsc18xLlBsYXllclV0aWxzLlBsYXllclN0YXRlW3N0YXRlXV0gPVxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJlZml4Q3NzKFVJQ29udGFpbmVyLlNUQVRFX1BSRUZJWCArIGVudW1OYW1lLnRvTG93ZXJDYXNlKCkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciByZW1vdmVTdGF0ZXMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDbGFzcyhzdGF0ZUNsYXNzTmFtZXNbcGxheWVydXRpbHNfMS5QbGF5ZXJVdGlscy5QbGF5ZXJTdGF0ZS5JRExFXSk7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDbGFzcyhzdGF0ZUNsYXNzTmFtZXNbcGxheWVydXRpbHNfMS5QbGF5ZXJVdGlscy5QbGF5ZXJTdGF0ZS5QUkVQQVJFRF0pO1xyXG4gICAgICAgICAgICBjb250YWluZXIucmVtb3ZlQ2xhc3Moc3RhdGVDbGFzc05hbWVzW3BsYXllcnV0aWxzXzEuUGxheWVyVXRpbHMuUGxheWVyU3RhdGUuUExBWUlOR10pO1xyXG4gICAgICAgICAgICBjb250YWluZXIucmVtb3ZlQ2xhc3Moc3RhdGVDbGFzc05hbWVzW3BsYXllcnV0aWxzXzEuUGxheWVyVXRpbHMuUGxheWVyU3RhdGUuUEFVU0VEXSk7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDbGFzcyhzdGF0ZUNsYXNzTmFtZXNbcGxheWVydXRpbHNfMS5QbGF5ZXJVdGlscy5QbGF5ZXJTdGF0ZS5GSU5JU0hFRF0pO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUkVBRFksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmVtb3ZlU3RhdGVzKCk7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyhzdGF0ZUNsYXNzTmFtZXNbcGxheWVydXRpbHNfMS5QbGF5ZXJVdGlscy5QbGF5ZXJTdGF0ZS5QUkVQQVJFRF0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BMQVksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmVtb3ZlU3RhdGVzKCk7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyhzdGF0ZUNsYXNzTmFtZXNbcGxheWVydXRpbHNfMS5QbGF5ZXJVdGlscy5QbGF5ZXJTdGF0ZS5QTEFZSU5HXSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUEFVU0VELCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJlbW92ZVN0YXRlcygpO1xyXG4gICAgICAgICAgICBjb250YWluZXIuYWRkQ2xhc3Moc3RhdGVDbGFzc05hbWVzW3BsYXllcnV0aWxzXzEuUGxheWVyVXRpbHMuUGxheWVyU3RhdGUuUEFVU0VEXSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUExBWUJBQ0tfRklOSVNIRUQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmVtb3ZlU3RhdGVzKCk7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyhzdGF0ZUNsYXNzTmFtZXNbcGxheWVydXRpbHNfMS5QbGF5ZXJVdGlscy5QbGF5ZXJTdGF0ZS5GSU5JU0hFRF0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1NPVVJDRV9VTkxPQURFRCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZW1vdmVTdGF0ZXMoKTtcclxuICAgICAgICAgICAgY29udGFpbmVyLmFkZENsYXNzKHN0YXRlQ2xhc3NOYW1lc1twbGF5ZXJ1dGlsc18xLlBsYXllclV0aWxzLlBsYXllclN0YXRlLklETEVdKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBJbml0IGluIGN1cnJlbnQgcGxheWVyIHN0YXRlXHJcbiAgICAgICAgY29udGFpbmVyLmFkZENsYXNzKHN0YXRlQ2xhc3NOYW1lc1twbGF5ZXJ1dGlsc18xLlBsYXllclV0aWxzLmdldFN0YXRlKHBsYXllcildKTtcclxuICAgICAgICAvLyBGdWxsc2NyZWVuIG1hcmtlciBjbGFzc1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0ZVTExTQ1JFRU5fRU5URVIsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY29udGFpbmVyLmFkZENsYXNzKF90aGlzLnByZWZpeENzcyhVSUNvbnRhaW5lci5GVUxMU0NSRUVOKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fRlVMTFNDUkVFTl9FWElULCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDbGFzcyhfdGhpcy5wcmVmaXhDc3MoVUlDb250YWluZXIuRlVMTFNDUkVFTikpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIEluaXQgZnVsbHNjcmVlbiBzdGF0ZVxyXG4gICAgICAgIGlmIChwbGF5ZXIuaXNGdWxsc2NyZWVuKCkpIHtcclxuICAgICAgICAgICAgY29udGFpbmVyLmFkZENsYXNzKHRoaXMucHJlZml4Q3NzKFVJQ29udGFpbmVyLkZVTExTQ1JFRU4pKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gQnVmZmVyaW5nIG1hcmtlciBjbGFzc1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1NUQUxMX1NUQVJURUQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY29udGFpbmVyLmFkZENsYXNzKF90aGlzLnByZWZpeENzcyhVSUNvbnRhaW5lci5CVUZGRVJJTkcpKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TVEFMTF9FTkRFRCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBjb250YWluZXIucmVtb3ZlQ2xhc3MoX3RoaXMucHJlZml4Q3NzKFVJQ29udGFpbmVyLkJVRkZFUklORykpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIEluaXQgYnVmZmVyaW5nIHN0YXRlXHJcbiAgICAgICAgaWYgKHBsYXllci5pc1N0YWxsZWQoKSkge1xyXG4gICAgICAgICAgICBjb250YWluZXIuYWRkQ2xhc3ModGhpcy5wcmVmaXhDc3MoVUlDb250YWluZXIuQlVGRkVSSU5HKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIFJlbW90ZUNvbnRyb2wgbWFya2VyIGNsYXNzXHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fQ0FTVF9TVEFSVEVELCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyhfdGhpcy5wcmVmaXhDc3MoVUlDb250YWluZXIuUkVNT1RFX0NPTlRST0wpKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9DQVNUX1NUT1BQRUQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY29udGFpbmVyLnJlbW92ZUNsYXNzKF90aGlzLnByZWZpeENzcyhVSUNvbnRhaW5lci5SRU1PVEVfQ09OVFJPTCkpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIEluaXQgUmVtb3RlQ29udHJvbCBzdGF0ZVxyXG4gICAgICAgIGlmIChwbGF5ZXIuaXNDYXN0aW5nKCkpIHtcclxuICAgICAgICAgICAgY29udGFpbmVyLmFkZENsYXNzKHRoaXMucHJlZml4Q3NzKFVJQ29udGFpbmVyLlJFTU9URV9DT05UUk9MKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIENvbnRyb2xzIHZpc2liaWxpdHkgbWFya2VyIGNsYXNzXHJcbiAgICAgICAgdWltYW5hZ2VyLm9uQ29udHJvbHNTaG93LnN1YnNjcmliZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDbGFzcyhfdGhpcy5wcmVmaXhDc3MoVUlDb250YWluZXIuQ09OVFJPTFNfSElEREVOKSk7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyhfdGhpcy5wcmVmaXhDc3MoVUlDb250YWluZXIuQ09OVFJPTFNfU0hPV04pKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICB1aW1hbmFnZXIub25Db250cm9sc0hpZGUuc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY29udGFpbmVyLnJlbW92ZUNsYXNzKF90aGlzLnByZWZpeENzcyhVSUNvbnRhaW5lci5DT05UUk9MU19TSE9XTikpO1xyXG4gICAgICAgICAgICBjb250YWluZXIuYWRkQ2xhc3MoX3RoaXMucHJlZml4Q3NzKFVJQ29udGFpbmVyLkNPTlRST0xTX0hJRERFTikpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIExheW91dCBzaXplIGNsYXNzZXNcclxuICAgICAgICB2YXIgdXBkYXRlTGF5b3V0U2l6ZUNsYXNzZXMgPSBmdW5jdGlvbiAod2lkdGgsIGhlaWdodCkge1xyXG4gICAgICAgICAgICBjb250YWluZXIucmVtb3ZlQ2xhc3MoX3RoaXMucHJlZml4Q3NzKCdsYXlvdXQtbWF4LXdpZHRoLTQwMCcpKTtcclxuICAgICAgICAgICAgY29udGFpbmVyLnJlbW92ZUNsYXNzKF90aGlzLnByZWZpeENzcygnbGF5b3V0LW1heC13aWR0aC02MDAnKSk7XHJcbiAgICAgICAgICAgIGNvbnRhaW5lci5yZW1vdmVDbGFzcyhfdGhpcy5wcmVmaXhDc3MoJ2xheW91dC1tYXgtd2lkdGgtODAwJykpO1xyXG4gICAgICAgICAgICBjb250YWluZXIucmVtb3ZlQ2xhc3MoX3RoaXMucHJlZml4Q3NzKCdsYXlvdXQtbWF4LXdpZHRoLTEyMDAnKSk7XHJcbiAgICAgICAgICAgIGlmICh3aWR0aCA8PSA0MDApIHtcclxuICAgICAgICAgICAgICAgIGNvbnRhaW5lci5hZGRDbGFzcyhfdGhpcy5wcmVmaXhDc3MoJ2xheW91dC1tYXgtd2lkdGgtNDAwJykpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKHdpZHRoIDw9IDYwMCkge1xyXG4gICAgICAgICAgICAgICAgY29udGFpbmVyLmFkZENsYXNzKF90aGlzLnByZWZpeENzcygnbGF5b3V0LW1heC13aWR0aC02MDAnKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSBpZiAod2lkdGggPD0gODAwKSB7XHJcbiAgICAgICAgICAgICAgICBjb250YWluZXIuYWRkQ2xhc3MoX3RoaXMucHJlZml4Q3NzKCdsYXlvdXQtbWF4LXdpZHRoLTgwMCcpKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIGlmICh3aWR0aCA8PSAxMjAwKSB7XHJcbiAgICAgICAgICAgICAgICBjb250YWluZXIuYWRkQ2xhc3MoX3RoaXMucHJlZml4Q3NzKCdsYXlvdXQtbWF4LXdpZHRoLTEyMDAnKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BMQVlFUl9SRVNJWkUsIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIC8vIENvbnZlcnQgc3RyaW5ncyAod2l0aCBcInB4XCIgc3VmZml4KSB0byBpbnRzXHJcbiAgICAgICAgICAgIHZhciB3aWR0aCA9IE1hdGgucm91bmQoTnVtYmVyKGUud2lkdGguc3Vic3RyaW5nKDAsIGUud2lkdGgubGVuZ3RoIC0gMikpKTtcclxuICAgICAgICAgICAgdmFyIGhlaWdodCA9IE1hdGgucm91bmQoTnVtYmVyKGUuaGVpZ2h0LnN1YnN0cmluZygwLCBlLmhlaWdodC5sZW5ndGggLSAyKSkpO1xyXG4gICAgICAgICAgICB1cGRhdGVMYXlvdXRTaXplQ2xhc3Nlcyh3aWR0aCwgaGVpZ2h0KTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBJbml0IGxheW91dCBzdGF0ZVxyXG4gICAgICAgIHVwZGF0ZUxheW91dFNpemVDbGFzc2VzKG5ldyBkb21fMS5ET00ocGxheWVyLmdldEZpZ3VyZSgpKS53aWR0aCgpLCBuZXcgZG9tXzEuRE9NKHBsYXllci5nZXRGaWd1cmUoKSkuaGVpZ2h0KCkpO1xyXG4gICAgfTtcclxuICAgIFVJQ29udGFpbmVyLnByb3RvdHlwZS5yZWxlYXNlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUucmVsZWFzZS5jYWxsKHRoaXMpO1xyXG4gICAgICAgIHRoaXMudWlIaWRlVGltZW91dC5jbGVhcigpO1xyXG4gICAgfTtcclxuICAgIFVJQ29udGFpbmVyLnByb3RvdHlwZS50b0RvbUVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGNvbnRhaW5lciA9IF9zdXBlci5wcm90b3R5cGUudG9Eb21FbGVtZW50LmNhbGwodGhpcyk7XHJcbiAgICAgICAgLy8gRGV0ZWN0IGZsZXhib3ggc3VwcG9ydCAobm90IHN1cHBvcnRlZCBpbiBJRTkpXHJcbiAgICAgICAgaWYgKGRvY3VtZW50ICYmIHR5cGVvZiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdwJykuc3R5bGUuZmxleCAhPT0gJ3VuZGVmaW5lZCcpIHtcclxuICAgICAgICAgICAgY29udGFpbmVyLmFkZENsYXNzKHRoaXMucHJlZml4Q3NzKCdmbGV4Ym94JykpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgY29udGFpbmVyLmFkZENsYXNzKHRoaXMucHJlZml4Q3NzKCduby1mbGV4Ym94JykpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gY29udGFpbmVyO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBVSUNvbnRhaW5lcjtcclxufShjb250YWluZXJfMS5Db250YWluZXIpKTtcclxuVUlDb250YWluZXIuU1RBVEVfUFJFRklYID0gJ3BsYXllci1zdGF0ZS0nO1xyXG5VSUNvbnRhaW5lci5GVUxMU0NSRUVOID0gJ2Z1bGxzY3JlZW4nO1xyXG5VSUNvbnRhaW5lci5CVUZGRVJJTkcgPSAnYnVmZmVyaW5nJztcclxuVUlDb250YWluZXIuUkVNT1RFX0NPTlRST0wgPSAncmVtb3RlLWNvbnRyb2wnO1xyXG5VSUNvbnRhaW5lci5DT05UUk9MU19TSE9XTiA9ICdjb250cm9scy1zaG93bic7XHJcblVJQ29udGFpbmVyLkNPTlRST0xTX0hJRERFTiA9ICdjb250cm9scy1oaWRkZW4nO1xyXG5leHBvcnRzLlVJQ29udGFpbmVyID0gVUlDb250YWluZXI7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy91aWNvbnRhaW5lci50c1xuLy8gbW9kdWxlIGlkID0gMTdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBsYWJlbF8xID0gcmVxdWlyZShcIi4vbGFiZWxcIik7XHJcbnZhciBwbGF5ZXJ1dGlsc18xID0gcmVxdWlyZShcIi4uL3BsYXllcnV0aWxzXCIpO1xyXG52YXIgc3RyaW5ndXRpbHNfMSA9IHJlcXVpcmUoXCIuLi9zdHJpbmd1dGlsc1wiKTtcclxudmFyIFBsYXliYWNrVGltZUxhYmVsTW9kZTtcclxuKGZ1bmN0aW9uIChQbGF5YmFja1RpbWVMYWJlbE1vZGUpIHtcclxuICAgIFBsYXliYWNrVGltZUxhYmVsTW9kZVtQbGF5YmFja1RpbWVMYWJlbE1vZGVbXCJDdXJyZW50VGltZVwiXSA9IDBdID0gXCJDdXJyZW50VGltZVwiO1xyXG4gICAgUGxheWJhY2tUaW1lTGFiZWxNb2RlW1BsYXliYWNrVGltZUxhYmVsTW9kZVtcIlRvdGFsVGltZVwiXSA9IDFdID0gXCJUb3RhbFRpbWVcIjtcclxuICAgIFBsYXliYWNrVGltZUxhYmVsTW9kZVtQbGF5YmFja1RpbWVMYWJlbE1vZGVbXCJDdXJyZW50QW5kVG90YWxUaW1lXCJdID0gMl0gPSBcIkN1cnJlbnRBbmRUb3RhbFRpbWVcIjtcclxufSkoUGxheWJhY2tUaW1lTGFiZWxNb2RlID0gZXhwb3J0cy5QbGF5YmFja1RpbWVMYWJlbE1vZGUgfHwgKGV4cG9ydHMuUGxheWJhY2tUaW1lTGFiZWxNb2RlID0ge30pKTtcclxuLyoqXHJcbiAqIEEgbGFiZWwgdGhhdCBkaXNwbGF5IHRoZSBjdXJyZW50IHBsYXliYWNrIHRpbWUgYW5kIHRoZSB0b3RhbCB0aW1lIHRocm91Z2gge0BsaW5rIFBsYXliYWNrVGltZUxhYmVsI3NldFRpbWUgc2V0VGltZX1cclxuICogb3IgYW55IHN0cmluZyB0aHJvdWdoIHtAbGluayBQbGF5YmFja1RpbWVMYWJlbCNzZXRUZXh0IHNldFRleHR9LlxyXG4gKi9cclxudmFyIFBsYXliYWNrVGltZUxhYmVsID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhQbGF5YmFja1RpbWVMYWJlbCwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFBsYXliYWNrVGltZUxhYmVsKGNvbmZpZykge1xyXG4gICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1wbGF5YmFja3RpbWVsYWJlbCcsXHJcbiAgICAgICAgICAgIHRpbWVMYWJlbE1vZGU6IFBsYXliYWNrVGltZUxhYmVsTW9kZS5DdXJyZW50QW5kVG90YWxUaW1lLFxyXG4gICAgICAgICAgICBoaWRlSW5MaXZlUGxheWJhY2s6IGZhbHNlLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgUGxheWJhY2tUaW1lTGFiZWwucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jb25maWd1cmUuY2FsbCh0aGlzLCBwbGF5ZXIsIHVpbWFuYWdlcik7XHJcbiAgICAgICAgdmFyIGNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlnKCk7XHJcbiAgICAgICAgdmFyIGxpdmUgPSBmYWxzZTtcclxuICAgICAgICB2YXIgbGl2ZUNzc0NsYXNzID0gdGhpcy5wcmVmaXhDc3MoJ3VpLXBsYXliYWNrdGltZWxhYmVsLWxpdmUnKTtcclxuICAgICAgICB2YXIgbGl2ZUVkZ2VDc3NDbGFzcyA9IHRoaXMucHJlZml4Q3NzKCd1aS1wbGF5YmFja3RpbWVsYWJlbC1saXZlLWVkZ2UnKTtcclxuICAgICAgICB2YXIgbWluV2lkdGggPSAwO1xyXG4gICAgICAgIHZhciBsaXZlQ2xpY2tIYW5kbGVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBwbGF5ZXIudGltZVNoaWZ0KDApO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIHVwZGF0ZUxpdmVTdGF0ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgLy8gUGxheWVyIGlzIHBsYXlpbmcgYSBsaXZlIHN0cmVhbSB3aGVuIHRoZSBkdXJhdGlvbiBpcyBpbmZpbml0ZVxyXG4gICAgICAgICAgICBsaXZlID0gcGxheWVyLmlzTGl2ZSgpO1xyXG4gICAgICAgICAgICAvLyBBdHRhY2gvZGV0YWNoIGxpdmUgbWFya2VyIGNsYXNzXHJcbiAgICAgICAgICAgIGlmIChsaXZlKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5nZXREb21FbGVtZW50KCkuYWRkQ2xhc3MobGl2ZUNzc0NsYXNzKTtcclxuICAgICAgICAgICAgICAgIF90aGlzLnNldFRleHQoJ0xpdmUnKTtcclxuICAgICAgICAgICAgICAgIGlmIChjb25maWcuaGlkZUluTGl2ZVBsYXliYWNrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuaGlkZSgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgX3RoaXMub25DbGljay5zdWJzY3JpYmUobGl2ZUNsaWNrSGFuZGxlcik7XHJcbiAgICAgICAgICAgICAgICB1cGRhdGVMaXZlVGltZXNoaWZ0U3RhdGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmdldERvbUVsZW1lbnQoKS5yZW1vdmVDbGFzcyhsaXZlQ3NzQ2xhc3MpO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZ2V0RG9tRWxlbWVudCgpLnJlbW92ZUNsYXNzKGxpdmVFZGdlQ3NzQ2xhc3MpO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuc2hvdygpO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMub25DbGljay51bnN1YnNjcmliZShsaXZlQ2xpY2tIYW5kbGVyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIHVwZGF0ZUxpdmVUaW1lc2hpZnRTdGF0ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKHBsYXllci5nZXRUaW1lU2hpZnQoKSA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZ2V0RG9tRWxlbWVudCgpLmFkZENsYXNzKGxpdmVFZGdlQ3NzQ2xhc3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZ2V0RG9tRWxlbWVudCgpLnJlbW92ZUNsYXNzKGxpdmVFZGdlQ3NzQ2xhc3MpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICB2YXIgbGl2ZVN0cmVhbURldGVjdG9yID0gbmV3IHBsYXllcnV0aWxzXzEuUGxheWVyVXRpbHMuTGl2ZVN0cmVhbURldGVjdG9yKHBsYXllcik7XHJcbiAgICAgICAgbGl2ZVN0cmVhbURldGVjdG9yLm9uTGl2ZUNoYW5nZWQuc3Vic2NyaWJlKGZ1bmN0aW9uIChzZW5kZXIsIGFyZ3MpIHtcclxuICAgICAgICAgICAgbGl2ZSA9IGFyZ3MubGl2ZTtcclxuICAgICAgICAgICAgdXBkYXRlTGl2ZVN0YXRlKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgbGl2ZVN0cmVhbURldGVjdG9yLmRldGVjdCgpOyAvLyBJbml0aWFsIGRldGVjdGlvblxyXG4gICAgICAgIHZhciBwbGF5YmFja1RpbWVIYW5kbGVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoIWxpdmUgJiYgcGxheWVyLmdldER1cmF0aW9uKCkgIT09IEluZmluaXR5KSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRUaW1lKHBsYXllci5nZXRDdXJyZW50VGltZSgpLCBwbGF5ZXIuZ2V0RHVyYXRpb24oKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gVG8gYXZvaWQgJ2p1bXBpbmcnIGluIHRoZSBVSSBieSB2YXJ5aW5nIGxhYmVsIHNpemVzIGR1ZSB0byBub24tbW9ub3NwYWNlZCBmb250cyxcclxuICAgICAgICAgICAgLy8gd2UgZ3JhZHVhbGx5IGluY3JlYXNlIHRoZSBtaW4td2lkdGggd2l0aCB0aGUgY29udGVudCB0byByZWFjaCBhIHN0YWJsZSBzaXplLlxyXG4gICAgICAgICAgICB2YXIgd2lkdGggPSBfdGhpcy5nZXREb21FbGVtZW50KCkud2lkdGgoKTtcclxuICAgICAgICAgICAgaWYgKHdpZHRoID4gbWluV2lkdGgpIHtcclxuICAgICAgICAgICAgICAgIG1pbldpZHRoID0gd2lkdGg7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5nZXREb21FbGVtZW50KCkuY3NzKHtcclxuICAgICAgICAgICAgICAgICAgICAnbWluLXdpZHRoJzogbWluV2lkdGggKyAncHgnLFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1RJTUVfQ0hBTkdFRCwgcGxheWJhY2tUaW1lSGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fU0VFS0VELCBwbGF5YmFja1RpbWVIYW5kbGVyKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9DQVNUX1RJTUVfVVBEQVRFRCwgcGxheWJhY2tUaW1lSGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fVElNRV9TSElGVCwgdXBkYXRlTGl2ZVRpbWVzaGlmdFN0YXRlKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9USU1FX1NISUZURUQsIHVwZGF0ZUxpdmVUaW1lc2hpZnRTdGF0ZSk7XHJcbiAgICAgICAgdmFyIGluaXQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIC8vIFJlc2V0IG1pbi13aWR0aCB3aGVuIGEgbmV3IHNvdXJjZSBpcyByZWFkeSAoZXNwZWNpYWxseSBmb3Igc3dpdGNoaW5nIFZPRC9MaXZlIG1vZGVzIHdoZXJlIHRoZSBsYWJlbCBjb250ZW50XHJcbiAgICAgICAgICAgIC8vIGNoYW5nZXMpXHJcbiAgICAgICAgICAgIG1pbldpZHRoID0gMDtcclxuICAgICAgICAgICAgX3RoaXMuZ2V0RG9tRWxlbWVudCgpLmNzcyh7XHJcbiAgICAgICAgICAgICAgICAnbWluLXdpZHRoJzogbnVsbCxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIC8vIFNldCB0aW1lIGZvcm1hdCBkZXBlbmRpbmcgb24gc291cmNlIGR1cmF0aW9uXHJcbiAgICAgICAgICAgIF90aGlzLnRpbWVGb3JtYXQgPSBNYXRoLmFicyhwbGF5ZXIuaXNMaXZlKCkgPyBwbGF5ZXIuZ2V0TWF4VGltZVNoaWZ0KCkgOiBwbGF5ZXIuZ2V0RHVyYXRpb24oKSkgPj0gMzYwMCA/XHJcbiAgICAgICAgICAgICAgICBzdHJpbmd1dGlsc18xLlN0cmluZ1V0aWxzLkZPUk1BVF9ISE1NU1MgOiBzdHJpbmd1dGlsc18xLlN0cmluZ1V0aWxzLkZPUk1BVF9NTVNTO1xyXG4gICAgICAgICAgICAvLyBVcGRhdGUgdGltZSBhZnRlciB0aGUgZm9ybWF0IGhhcyBiZWVuIHNldFxyXG4gICAgICAgICAgICBwbGF5YmFja1RpbWVIYW5kbGVyKCk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9SRUFEWSwgaW5pdCk7XHJcbiAgICAgICAgaW5pdCgpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgY3VycmVudCBwbGF5YmFjayB0aW1lIGFuZCB0b3RhbCBkdXJhdGlvbi5cclxuICAgICAqIEBwYXJhbSBwbGF5YmFja1NlY29uZHMgdGhlIGN1cnJlbnQgcGxheWJhY2sgdGltZSBpbiBzZWNvbmRzXHJcbiAgICAgKiBAcGFyYW0gZHVyYXRpb25TZWNvbmRzIHRoZSB0b3RhbCBkdXJhdGlvbiBpbiBzZWNvbmRzXHJcbiAgICAgKi9cclxuICAgIFBsYXliYWNrVGltZUxhYmVsLnByb3RvdHlwZS5zZXRUaW1lID0gZnVuY3Rpb24gKHBsYXliYWNrU2Vjb25kcywgZHVyYXRpb25TZWNvbmRzKSB7XHJcbiAgICAgICAgdmFyIGN1cnJlbnRUaW1lID0gc3RyaW5ndXRpbHNfMS5TdHJpbmdVdGlscy5zZWNvbmRzVG9UaW1lKHBsYXliYWNrU2Vjb25kcywgdGhpcy50aW1lRm9ybWF0KTtcclxuICAgICAgICB2YXIgdG90YWxUaW1lID0gc3RyaW5ndXRpbHNfMS5TdHJpbmdVdGlscy5zZWNvbmRzVG9UaW1lKGR1cmF0aW9uU2Vjb25kcywgdGhpcy50aW1lRm9ybWF0KTtcclxuICAgICAgICBzd2l0Y2ggKHRoaXMuY29uZmlnLnRpbWVMYWJlbE1vZGUpIHtcclxuICAgICAgICAgICAgY2FzZSBQbGF5YmFja1RpbWVMYWJlbE1vZGUuQ3VycmVudFRpbWU6XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldFRleHQoXCJcIiArIGN1cnJlbnRUaW1lKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICBjYXNlIFBsYXliYWNrVGltZUxhYmVsTW9kZS5Ub3RhbFRpbWU6XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNldFRleHQoXCJcIiArIHRvdGFsVGltZSk7XHJcbiAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgY2FzZSBQbGF5YmFja1RpbWVMYWJlbE1vZGUuQ3VycmVudEFuZFRvdGFsVGltZTpcclxuICAgICAgICAgICAgICAgIHRoaXMuc2V0VGV4dChjdXJyZW50VGltZSArIFwiIC8gXCIgKyB0b3RhbFRpbWUpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogU2V0cyB0aGUgY3VycmVudCB0aW1lIGZvcm1hdFxyXG4gICAgICogQHBhcmFtIHRpbWVGb3JtYXQgdGhlIHRpbWUgZm9ybWF0XHJcbiAgICAgKi9cclxuICAgIFBsYXliYWNrVGltZUxhYmVsLnByb3RvdHlwZS5zZXRUaW1lRm9ybWF0ID0gZnVuY3Rpb24gKHRpbWVGb3JtYXQpIHtcclxuICAgICAgICB0aGlzLnRpbWVGb3JtYXQgPSB0aW1lRm9ybWF0O1xyXG4gICAgfTtcclxuICAgIHJldHVybiBQbGF5YmFja1RpbWVMYWJlbDtcclxufShsYWJlbF8xLkxhYmVsKSk7XHJcbmV4cG9ydHMuUGxheWJhY2tUaW1lTGFiZWwgPSBQbGF5YmFja1RpbWVMYWJlbDtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3BsYXliYWNrdGltZWxhYmVsLnRzXG4vLyBtb2R1bGUgaWQgPSAxOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGNvbXBvbmVudF8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50XCIpO1xyXG4vKipcclxuICogQSBkdW1teSBjb21wb25lbnQgdGhhdCBqdXN0IHJlc2VydmVzIHNvbWUgc3BhY2UgYW5kIGRvZXMgbm90aGluZyBlbHNlLlxyXG4gKi9cclxudmFyIFNwYWNlciA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoU3BhY2VyLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gU3BhY2VyKGNvbmZpZykge1xyXG4gICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1zcGFjZXInLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgU3BhY2VyLnByb3RvdHlwZS5vblNob3dFdmVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBkaXNhYmxlIGV2ZW50IGZpcmluZyBieSBvdmVyd3JpdGluZyBhbmQgbm90IGNhbGxpbmcgc3VwZXJcclxuICAgIH07XHJcbiAgICBTcGFjZXIucHJvdG90eXBlLm9uSGlkZUV2ZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIGRpc2FibGUgZXZlbnQgZmlyaW5nIGJ5IG92ZXJ3cml0aW5nIGFuZCBub3QgY2FsbGluZyBzdXBlclxyXG4gICAgfTtcclxuICAgIFNwYWNlci5wcm90b3R5cGUub25Ib3ZlckNoYW5nZWRFdmVudCA9IGZ1bmN0aW9uIChob3ZlcmVkKSB7XHJcbiAgICAgICAgLy8gZGlzYWJsZSBldmVudCBmaXJpbmcgYnkgb3ZlcndyaXRpbmcgYW5kIG5vdCBjYWxsaW5nIHN1cGVyXHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFNwYWNlcjtcclxufShjb21wb25lbnRfMS5Db21wb25lbnQpKTtcclxuZXhwb3J0cy5TcGFjZXIgPSBTcGFjZXI7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9zcGFjZXIudHNcbi8vIG1vZHVsZSBpZCA9IDE5XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgY29udGFpbmVyXzEgPSByZXF1aXJlKFwiLi9jb250YWluZXJcIik7XHJcbnZhciBsYWJlbF8xID0gcmVxdWlyZShcIi4vbGFiZWxcIik7XHJcbnZhciBjb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudFwiKTtcclxudmFyIHN0cmluZ3V0aWxzXzEgPSByZXF1aXJlKFwiLi4vc3RyaW5ndXRpbHNcIik7XHJcbnZhciBpbWFnZWxvYWRlcl8xID0gcmVxdWlyZShcIi4uL2ltYWdlbG9hZGVyXCIpO1xyXG4vKipcclxuICogQSBsYWJlbCBmb3IgYSB7QGxpbmsgU2Vla0Jhcn0gdGhhdCBjYW4gZGlzcGxheSB0aGUgc2VlayB0YXJnZXQgdGltZSwgYSB0aHVtYm5haWwsIGFuZCB0aXRsZSAoZS5nLiBjaGFwdGVyIHRpdGxlKS5cclxuICovXHJcbnZhciBTZWVrQmFyTGFiZWwgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKFNlZWtCYXJMYWJlbCwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFNlZWtCYXJMYWJlbChjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMudGltZUxhYmVsID0gbmV3IGxhYmVsXzEuTGFiZWwoeyBjc3NDbGFzc2VzOiBbJ3NlZWtiYXItbGFiZWwtdGltZSddIH0pO1xyXG4gICAgICAgIF90aGlzLnRpdGxlTGFiZWwgPSBuZXcgbGFiZWxfMS5MYWJlbCh7IGNzc0NsYXNzZXM6IFsnc2Vla2Jhci1sYWJlbC10aXRsZSddIH0pO1xyXG4gICAgICAgIF90aGlzLnRodW1ibmFpbCA9IG5ldyBjb21wb25lbnRfMS5Db21wb25lbnQoeyBjc3NDbGFzc2VzOiBbJ3NlZWtiYXItdGh1bWJuYWlsJ10gfSk7XHJcbiAgICAgICAgX3RoaXMudGh1bWJuYWlsSW1hZ2VMb2FkZXIgPSBuZXcgaW1hZ2Vsb2FkZXJfMS5JbWFnZUxvYWRlcigpO1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLXNlZWtiYXItbGFiZWwnLFxyXG4gICAgICAgICAgICBjb21wb25lbnRzOiBbbmV3IGNvbnRhaW5lcl8xLkNvbnRhaW5lcih7XHJcbiAgICAgICAgICAgICAgICAgICAgY29tcG9uZW50czogW1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzLnRodW1ibmFpbCxcclxuICAgICAgICAgICAgICAgICAgICAgICAgbmV3IGNvbnRhaW5lcl8xLkNvbnRhaW5lcih7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21wb25lbnRzOiBbX3RoaXMudGl0bGVMYWJlbCwgX3RoaXMudGltZUxhYmVsXSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNzc0NsYXNzOiAnc2Vla2Jhci1sYWJlbC1tZXRhZGF0YScsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgICAgICAgICAgXSxcclxuICAgICAgICAgICAgICAgICAgICBjc3NDbGFzczogJ3NlZWtiYXItbGFiZWwtaW5uZXInLFxyXG4gICAgICAgICAgICAgICAgfSldLFxyXG4gICAgICAgICAgICBoaWRkZW46IHRydWUsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBTZWVrQmFyTGFiZWwucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jb25maWd1cmUuY2FsbCh0aGlzLCBwbGF5ZXIsIHVpbWFuYWdlcik7XHJcbiAgICAgICAgdWltYW5hZ2VyLm9uU2Vla1ByZXZpZXcuc3Vic2NyaWJlUmF0ZUxpbWl0ZWQoZnVuY3Rpb24gKHNlbmRlciwgYXJncykge1xyXG4gICAgICAgICAgICBpZiAocGxheWVyLmlzTGl2ZSgpKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbWF4VGltZVNoaWZ0ID0gcGxheWVyLmdldE1heFRpbWVTaGlmdCgpO1xyXG4gICAgICAgICAgICAgICAgdmFyIHRpbWUgPSBtYXhUaW1lU2hpZnQgLSBtYXhUaW1lU2hpZnQgKiAoYXJncy5wb3NpdGlvbiAvIDEwMCk7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRUaW1lKHRpbWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdmFyIHBlcmNlbnRhZ2UgPSAwO1xyXG4gICAgICAgICAgICAgICAgaWYgKGFyZ3MubWFya2VyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGVyY2VudGFnZSA9IGFyZ3MubWFya2VyLnRpbWU7XHJcbiAgICAgICAgICAgICAgICAgICAgX3RoaXMuc2V0VGl0bGVUZXh0KGFyZ3MubWFya2VyLnRpdGxlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHBlcmNlbnRhZ2UgPSBhcmdzLnBvc2l0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLnNldFRpdGxlVGV4dChudWxsKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHZhciB0aW1lID0gcGxheWVyLmdldER1cmF0aW9uKCkgKiAocGVyY2VudGFnZSAvIDEwMCk7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRUaW1lKHRpbWUpO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuc2V0VGh1bWJuYWlsKHBsYXllci5nZXRUaHVtYih0aW1lKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LCAxMDApO1xyXG4gICAgICAgIHZhciBpbml0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvLyBTZXQgdGltZSBmb3JtYXQgZGVwZW5kaW5nIG9uIHNvdXJjZSBkdXJhdGlvblxyXG4gICAgICAgICAgICBfdGhpcy50aW1lRm9ybWF0ID0gTWF0aC5hYnMocGxheWVyLmlzTGl2ZSgpID8gcGxheWVyLmdldE1heFRpbWVTaGlmdCgpIDogcGxheWVyLmdldER1cmF0aW9uKCkpID49IDM2MDAgP1xyXG4gICAgICAgICAgICAgICAgc3RyaW5ndXRpbHNfMS5TdHJpbmdVdGlscy5GT1JNQVRfSEhNTVNTIDogc3RyaW5ndXRpbHNfMS5TdHJpbmdVdGlscy5GT1JNQVRfTU1TUztcclxuICAgICAgICB9O1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1JFQURZLCBpbml0KTtcclxuICAgICAgICBpbml0KCk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBTZXRzIGFyYml0cmFyeSB0ZXh0IG9uIHRoZSBsYWJlbC5cclxuICAgICAqIEBwYXJhbSB0ZXh0IHRoZSB0ZXh0IHRvIHNob3cgb24gdGhlIGxhYmVsXHJcbiAgICAgKi9cclxuICAgIFNlZWtCYXJMYWJlbC5wcm90b3R5cGUuc2V0VGV4dCA9IGZ1bmN0aW9uICh0ZXh0KSB7XHJcbiAgICAgICAgdGhpcy50aW1lTGFiZWwuc2V0VGV4dCh0ZXh0KTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFNldHMgYSB0aW1lIHRvIGJlIGRpc3BsYXllZCBvbiB0aGUgbGFiZWwuXHJcbiAgICAgKiBAcGFyYW0gc2Vjb25kcyB0aGUgdGltZSBpbiBzZWNvbmRzIHRvIGRpc3BsYXkgb24gdGhlIGxhYmVsXHJcbiAgICAgKi9cclxuICAgIFNlZWtCYXJMYWJlbC5wcm90b3R5cGUuc2V0VGltZSA9IGZ1bmN0aW9uIChzZWNvbmRzKSB7XHJcbiAgICAgICAgdGhpcy5zZXRUZXh0KHN0cmluZ3V0aWxzXzEuU3RyaW5nVXRpbHMuc2Vjb25kc1RvVGltZShzZWNvbmRzLCB0aGlzLnRpbWVGb3JtYXQpKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFNldHMgdGhlIHRleHQgb24gdGhlIHRpdGxlIGxhYmVsLlxyXG4gICAgICogQHBhcmFtIHRleHQgdGhlIHRleHQgdG8gc2hvdyBvbiB0aGUgbGFiZWxcclxuICAgICAqL1xyXG4gICAgU2Vla0JhckxhYmVsLnByb3RvdHlwZS5zZXRUaXRsZVRleHQgPSBmdW5jdGlvbiAodGV4dCkge1xyXG4gICAgICAgIHRoaXMudGl0bGVMYWJlbC5zZXRUZXh0KHRleHQpO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogU2V0cyBvciByZW1vdmVzIGEgdGh1bWJuYWlsIG9uIHRoZSBsYWJlbC5cclxuICAgICAqIEBwYXJhbSB0aHVtYm5haWwgdGhlIHRodW1ibmFpbCB0byBkaXNwbGF5IG9uIHRoZSBsYWJlbCBvciBudWxsIHRvIHJlbW92ZSBhIGRpc3BsYXllZCB0aHVtYm5haWxcclxuICAgICAqL1xyXG4gICAgU2Vla0JhckxhYmVsLnByb3RvdHlwZS5zZXRUaHVtYm5haWwgPSBmdW5jdGlvbiAodGh1bWJuYWlsKSB7XHJcbiAgICAgICAgaWYgKHRodW1ibmFpbCA9PT0gdm9pZCAwKSB7IHRodW1ibmFpbCA9IG51bGw7IH1cclxuICAgICAgICB2YXIgdGh1bWJuYWlsRWxlbWVudCA9IHRoaXMudGh1bWJuYWlsLmdldERvbUVsZW1lbnQoKTtcclxuICAgICAgICBpZiAodGh1bWJuYWlsID09IG51bGwpIHtcclxuICAgICAgICAgICAgdGh1bWJuYWlsRWxlbWVudC5jc3Moe1xyXG4gICAgICAgICAgICAgICAgJ2JhY2tncm91bmQtaW1hZ2UnOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgJ2Rpc3BsYXknOiBudWxsLFxyXG4gICAgICAgICAgICAgICAgJ3dpZHRoJzogbnVsbCxcclxuICAgICAgICAgICAgICAgICdoZWlnaHQnOiBudWxsLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIFdlIHVzZSB0aGUgdGh1bWJuYWlsIGltYWdlIGxvYWRlciB0byBtYWtlIHN1cmUgdGhlIHRodW1ibmFpbCBpcyBsb2FkZWQgYW5kIGl0J3Mgc2l6ZSBpcyBrbm93biBiZWZvcmUgYmUgY2FuXHJcbiAgICAgICAgICAgIC8vIGNhbGN1bGF0ZSB0aGUgQ1NTIHByb3BlcnRpZXMgYW5kIHNldCB0aGVtIG9uIHRoZSBlbGVtZW50LlxyXG4gICAgICAgICAgICB0aGlzLnRodW1ibmFpbEltYWdlTG9hZGVyLmxvYWQodGh1bWJuYWlsLnVybCwgZnVuY3Rpb24gKHVybCwgd2lkdGgsIGhlaWdodCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHRodW1ibmFpbENvdW50WCA9IHdpZHRoIC8gdGh1bWJuYWlsLnc7XHJcbiAgICAgICAgICAgICAgICB2YXIgdGh1bWJuYWlsQ291bnRZID0gaGVpZ2h0IC8gdGh1bWJuYWlsLmg7XHJcbiAgICAgICAgICAgICAgICB2YXIgdGh1bWJuYWlsSW5kZXhYID0gdGh1bWJuYWlsLnggLyB0aHVtYm5haWwudztcclxuICAgICAgICAgICAgICAgIHZhciB0aHVtYm5haWxJbmRleFkgPSB0aHVtYm5haWwueSAvIHRodW1ibmFpbC5oO1xyXG4gICAgICAgICAgICAgICAgdmFyIHNpemVYID0gMTAwICogdGh1bWJuYWlsQ291bnRYO1xyXG4gICAgICAgICAgICAgICAgdmFyIHNpemVZID0gMTAwICogdGh1bWJuYWlsQ291bnRZO1xyXG4gICAgICAgICAgICAgICAgdmFyIG9mZnNldFggPSAxMDAgKiB0aHVtYm5haWxJbmRleFg7XHJcbiAgICAgICAgICAgICAgICB2YXIgb2Zmc2V0WSA9IDEwMCAqIHRodW1ibmFpbEluZGV4WTtcclxuICAgICAgICAgICAgICAgIHZhciBhc3BlY3RSYXRpbyA9IDEgLyB0aHVtYm5haWwudyAqIHRodW1ibmFpbC5oO1xyXG4gICAgICAgICAgICAgICAgLy8gVGhlIHRodW1ibmFpbCBzaXplIGlzIHNldCBieSBzZXR0aW5nIHRoZSBDU1MgJ3dpZHRoJyBhbmQgJ3BhZGRpbmctYm90dG9tJyBwcm9wZXJ0aWVzLiAncGFkZGluZy1ib3R0b20nIGlzXHJcbiAgICAgICAgICAgICAgICAvLyB1c2VkIGJlY2F1c2UgaXQgaXMgcmVsYXRpdmUgdG8gdGhlIHdpZHRoIGFuZCBjYW4gYmUgdXNlZCB0byBzZXQgdGhlIGFzcGVjdCByYXRpbyBvZiB0aGUgdGh1bWJuYWlsLlxyXG4gICAgICAgICAgICAgICAgLy8gQSBkZWZhdWx0IHZhbHVlIGZvciB3aWR0aCBpcyBzZXQgaW4gdGhlIHN0eWxlc2hlZXQgYW5kIGNhbiBiZSBvdmVyd3JpdHRlbiBmcm9tIHRoZXJlIG9yIGFueXdoZXJlIGVsc2UuXHJcbiAgICAgICAgICAgICAgICB0aHVtYm5haWxFbGVtZW50LmNzcyh7XHJcbiAgICAgICAgICAgICAgICAgICAgJ2Rpc3BsYXknOiAnaW5oZXJpdCcsXHJcbiAgICAgICAgICAgICAgICAgICAgJ2JhY2tncm91bmQtaW1hZ2UnOiBcInVybChcIiArIHRodW1ibmFpbC51cmwgKyBcIilcIixcclxuICAgICAgICAgICAgICAgICAgICAncGFkZGluZy1ib3R0b20nOiAxMDAgKiBhc3BlY3RSYXRpbyArIFwiJVwiLFxyXG4gICAgICAgICAgICAgICAgICAgICdiYWNrZ3JvdW5kLXNpemUnOiBzaXplWCArIFwiJSBcIiArIHNpemVZICsgXCIlXCIsXHJcbiAgICAgICAgICAgICAgICAgICAgJ2JhY2tncm91bmQtcG9zaXRpb24nOiBcIi1cIiArIG9mZnNldFggKyBcIiUgLVwiICsgb2Zmc2V0WSArIFwiJVwiLFxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICByZXR1cm4gU2Vla0JhckxhYmVsO1xyXG59KGNvbnRhaW5lcl8xLkNvbnRhaW5lcikpO1xyXG5leHBvcnRzLlNlZWtCYXJMYWJlbCA9IFNlZWtCYXJMYWJlbDtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3NlZWtiYXJsYWJlbC50c1xuLy8gbW9kdWxlIGlkID0gMjBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBsaXN0c2VsZWN0b3JfMSA9IHJlcXVpcmUoXCIuL2xpc3RzZWxlY3RvclwiKTtcclxudmFyIGRvbV8xID0gcmVxdWlyZShcIi4uL2RvbVwiKTtcclxuLyoqXHJcbiAqIEEgc2ltcGxlIHNlbGVjdCBib3ggcHJvdmlkaW5nIHRoZSBwb3NzaWJpbGl0eSB0byBzZWxlY3QgYSBzaW5nbGUgaXRlbSBvdXQgb2YgYSBsaXN0IG9mIGF2YWlsYWJsZSBpdGVtcy5cclxuICpcclxuICogRE9NIGV4YW1wbGU6XHJcbiAqIDxjb2RlPlxyXG4gKiAgICAgPHNlbGVjdCBjbGFzcz0ndWktc2VsZWN0Ym94Jz5cclxuICogICAgICAgICA8b3B0aW9uIHZhbHVlPSdrZXknPmxhYmVsPC9vcHRpb24+XHJcbiAqICAgICAgICAgLi4uXHJcbiAqICAgICA8L3NlbGVjdD5cclxuICogPC9jb2RlPlxyXG4gKi9cclxudmFyIFNlbGVjdEJveCA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoU2VsZWN0Qm94LCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gU2VsZWN0Qm94KGNvbmZpZykge1xyXG4gICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1zZWxlY3Rib3gnLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgU2VsZWN0Qm94LnByb3RvdHlwZS50b0RvbUVsZW1lbnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB2YXIgc2VsZWN0RWxlbWVudCA9IG5ldyBkb21fMS5ET00oJ3NlbGVjdCcsIHtcclxuICAgICAgICAgICAgJ2lkJzogdGhpcy5jb25maWcuaWQsXHJcbiAgICAgICAgICAgICdjbGFzcyc6IHRoaXMuZ2V0Q3NzQ2xhc3NlcygpLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHRoaXMuc2VsZWN0RWxlbWVudCA9IHNlbGVjdEVsZW1lbnQ7XHJcbiAgICAgICAgdGhpcy51cGRhdGVEb21JdGVtcygpO1xyXG4gICAgICAgIHNlbGVjdEVsZW1lbnQub24oJ2NoYW5nZScsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIHZhbHVlID0gc2VsZWN0RWxlbWVudC52YWwoKTtcclxuICAgICAgICAgICAgX3RoaXMub25JdGVtU2VsZWN0ZWRFdmVudCh2YWx1ZSwgZmFsc2UpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiBzZWxlY3RFbGVtZW50O1xyXG4gICAgfTtcclxuICAgIFNlbGVjdEJveC5wcm90b3R5cGUudXBkYXRlRG9tSXRlbXMgPSBmdW5jdGlvbiAoc2VsZWN0ZWRWYWx1ZSkge1xyXG4gICAgICAgIGlmIChzZWxlY3RlZFZhbHVlID09PSB2b2lkIDApIHsgc2VsZWN0ZWRWYWx1ZSA9IG51bGw7IH1cclxuICAgICAgICAvLyBEZWxldGUgYWxsIGNoaWxkcmVuXHJcbiAgICAgICAgdGhpcy5zZWxlY3RFbGVtZW50LmVtcHR5KCk7XHJcbiAgICAgICAgLy8gQWRkIHVwZGF0ZWQgY2hpbGRyZW5cclxuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdGhpcy5pdGVtczsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgdmFyIGl0ZW0gPSBfYVtfaV07XHJcbiAgICAgICAgICAgIHZhciBvcHRpb25FbGVtZW50ID0gbmV3IGRvbV8xLkRPTSgnb3B0aW9uJywge1xyXG4gICAgICAgICAgICAgICAgJ3ZhbHVlJzogaXRlbS5rZXksXHJcbiAgICAgICAgICAgIH0pLmh0bWwoaXRlbS5sYWJlbCk7XHJcbiAgICAgICAgICAgIGlmIChpdGVtLmtleSA9PT0gU3RyaW5nKHNlbGVjdGVkVmFsdWUpKSB7XHJcbiAgICAgICAgICAgICAgICBvcHRpb25FbGVtZW50LmF0dHIoJ3NlbGVjdGVkJywgJ3NlbGVjdGVkJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdGhpcy5zZWxlY3RFbGVtZW50LmFwcGVuZChvcHRpb25FbGVtZW50KTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgU2VsZWN0Qm94LnByb3RvdHlwZS5vbkl0ZW1BZGRlZEV2ZW50ID0gZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5vbkl0ZW1BZGRlZEV2ZW50LmNhbGwodGhpcywgdmFsdWUpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlRG9tSXRlbXModGhpcy5zZWxlY3RlZEl0ZW0pO1xyXG4gICAgfTtcclxuICAgIFNlbGVjdEJveC5wcm90b3R5cGUub25JdGVtUmVtb3ZlZEV2ZW50ID0gZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5vbkl0ZW1SZW1vdmVkRXZlbnQuY2FsbCh0aGlzLCB2YWx1ZSk7XHJcbiAgICAgICAgdGhpcy51cGRhdGVEb21JdGVtcyh0aGlzLnNlbGVjdGVkSXRlbSk7XHJcbiAgICB9O1xyXG4gICAgU2VsZWN0Qm94LnByb3RvdHlwZS5vbkl0ZW1TZWxlY3RlZEV2ZW50ID0gZnVuY3Rpb24gKHZhbHVlLCB1cGRhdGVEb21JdGVtcykge1xyXG4gICAgICAgIGlmICh1cGRhdGVEb21JdGVtcyA9PT0gdm9pZCAwKSB7IHVwZGF0ZURvbUl0ZW1zID0gdHJ1ZTsgfVxyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUub25JdGVtU2VsZWN0ZWRFdmVudC5jYWxsKHRoaXMsIHZhbHVlKTtcclxuICAgICAgICBpZiAodXBkYXRlRG9tSXRlbXMpIHtcclxuICAgICAgICAgICAgdGhpcy51cGRhdGVEb21JdGVtcyh2YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHJldHVybiBTZWxlY3RCb3g7XHJcbn0obGlzdHNlbGVjdG9yXzEuTGlzdFNlbGVjdG9yKSk7XHJcbmV4cG9ydHMuU2VsZWN0Qm94ID0gU2VsZWN0Qm94O1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvc2VsZWN0Ym94LnRzXG4vLyBtb2R1bGUgaWQgPSAyMVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGNvbXBvbmVudF8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50XCIpO1xyXG52YXIgZXZlbnRkaXNwYXRjaGVyXzEgPSByZXF1aXJlKFwiLi4vZXZlbnRkaXNwYXRjaGVyXCIpO1xyXG52YXIgYXJyYXl1dGlsc18xID0gcmVxdWlyZShcIi4uL2FycmF5dXRpbHNcIik7XHJcbnZhciBMaXN0U2VsZWN0b3IgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKExpc3RTZWxlY3RvciwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIExpc3RTZWxlY3Rvcihjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMubGlzdFNlbGVjdG9yRXZlbnRzID0ge1xyXG4gICAgICAgICAgICBvbkl0ZW1BZGRlZDogbmV3IGV2ZW50ZGlzcGF0Y2hlcl8xLkV2ZW50RGlzcGF0Y2hlcigpLFxyXG4gICAgICAgICAgICBvbkl0ZW1SZW1vdmVkOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgICAgIG9uSXRlbVNlbGVjdGVkOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgfTtcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgaXRlbXM6IFtdLFxyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLWxpc3RzZWxlY3RvcicsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICBfdGhpcy5pdGVtcyA9IF90aGlzLmNvbmZpZy5pdGVtcztcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBMaXN0U2VsZWN0b3IucHJvdG90eXBlLmdldEl0ZW1JbmRleCA9IGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICBmb3IgKHZhciBpbmRleCBpbiB0aGlzLml0ZW1zKSB7XHJcbiAgICAgICAgICAgIGlmIChrZXkgPT09IHRoaXMuaXRlbXNbaW5kZXhdLmtleSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHBhcnNlSW50KGluZGV4KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gLTE7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBDaGVja3MgaWYgdGhlIHNwZWNpZmllZCBpdGVtIGlzIHBhcnQgb2YgdGhpcyBzZWxlY3Rvci5cclxuICAgICAqIEBwYXJhbSBrZXkgdGhlIGtleSBvZiB0aGUgaXRlbSB0byBjaGVja1xyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWYgdGhlIGl0ZW0gaXMgcGFydCBvZiB0aGlzIHNlbGVjdG9yLCBlbHNlIGZhbHNlXHJcbiAgICAgKi9cclxuICAgIExpc3RTZWxlY3Rvci5wcm90b3R5cGUuaGFzSXRlbSA9IGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5nZXRJdGVtSW5kZXgoa2V5KSA+IC0xO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBhbiBpdGVtIHRvIHRoaXMgc2VsZWN0b3IgYnkgYXBwZW5kaW5nIGl0IHRvIHRoZSBlbmQgb2YgdGhlIGxpc3Qgb2YgaXRlbXMuIElmIGFuIGl0ZW0gd2l0aCB0aGUgc3BlY2lmaWVkXHJcbiAgICAgKiBrZXkgYWxyZWFkeSBleGlzdHMsIGl0IGlzIHJlcGxhY2VkLlxyXG4gICAgICogQHBhcmFtIGtleSB0aGUga2V5IG9mIHRoZSBpdGVtIHRvIGFkZFxyXG4gICAgICogQHBhcmFtIGxhYmVsIHRoZSAoaHVtYW4tcmVhZGFibGUpIGxhYmVsIG9mIHRoZSBpdGVtIHRvIGFkZFxyXG4gICAgICovXHJcbiAgICBMaXN0U2VsZWN0b3IucHJvdG90eXBlLmFkZEl0ZW0gPSBmdW5jdGlvbiAoa2V5LCBsYWJlbCkge1xyXG4gICAgICAgIHRoaXMucmVtb3ZlSXRlbShrZXkpOyAvLyBUcnkgdG8gcmVtb3ZlIGtleSBmaXJzdCB0byBnZXQgb3ZlcndyaXRlIGJlaGF2aW9yIGFuZCBhdm9pZCBkdXBsaWNhdGUga2V5c1xyXG4gICAgICAgIHRoaXMuaXRlbXMucHVzaCh7IGtleToga2V5LCBsYWJlbDogbGFiZWwgfSk7XHJcbiAgICAgICAgdGhpcy5vbkl0ZW1BZGRlZEV2ZW50KGtleSk7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIGFuIGl0ZW0gZnJvbSB0aGlzIHNlbGVjdG9yLlxyXG4gICAgICogQHBhcmFtIGtleSB0aGUga2V5IG9mIHRoZSBpdGVtIHRvIHJlbW92ZVxyXG4gICAgICogQHJldHVybnMge2Jvb2xlYW59IHRydWUgaWYgcmVtb3ZhbCB3YXMgc3VjY2Vzc2Z1bCwgZmFsc2UgaWYgdGhlIGl0ZW0gaXMgbm90IHBhcnQgb2YgdGhpcyBzZWxlY3RvclxyXG4gICAgICovXHJcbiAgICBMaXN0U2VsZWN0b3IucHJvdG90eXBlLnJlbW92ZUl0ZW0gPSBmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5nZXRJdGVtSW5kZXgoa2V5KTtcclxuICAgICAgICBpZiAoaW5kZXggPiAtMSkge1xyXG4gICAgICAgICAgICBhcnJheXV0aWxzXzEuQXJyYXlVdGlscy5yZW1vdmUodGhpcy5pdGVtcywgdGhpcy5pdGVtc1tpbmRleF0pO1xyXG4gICAgICAgICAgICB0aGlzLm9uSXRlbVJlbW92ZWRFdmVudChrZXkpO1xyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogU2VsZWN0cyBhbiBpdGVtIGZyb20gdGhlIGl0ZW1zIGluIHRoaXMgc2VsZWN0b3IuXHJcbiAgICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkgb2YgdGhlIGl0ZW0gdG8gc2VsZWN0XHJcbiAgICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gdHJ1ZSBpcyB0aGUgc2VsZWN0aW9uIHdhcyBzdWNjZXNzZnVsLCBmYWxzZSBpZiB0aGUgc2VsZWN0ZWQgaXRlbSBpcyBub3QgcGFydCBvZiB0aGUgc2VsZWN0b3JcclxuICAgICAqL1xyXG4gICAgTGlzdFNlbGVjdG9yLnByb3RvdHlwZS5zZWxlY3RJdGVtID0gZnVuY3Rpb24gKGtleSkge1xyXG4gICAgICAgIGlmIChrZXkgPT09IHRoaXMuc2VsZWN0ZWRJdGVtKSB7XHJcbiAgICAgICAgICAgIC8vIGl0ZW1Db25maWcgaXMgYWxyZWFkeSBzZWxlY3RlZCwgc3VwcHJlc3MgYW55IGZ1cnRoZXIgYWN0aW9uXHJcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgaW5kZXggPSB0aGlzLmdldEl0ZW1JbmRleChrZXkpO1xyXG4gICAgICAgIGlmIChpbmRleCA+IC0xKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRJdGVtID0ga2V5O1xyXG4gICAgICAgICAgICB0aGlzLm9uSXRlbVNlbGVjdGVkRXZlbnQoa2V5KTtcclxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGtleSBvZiB0aGUgc2VsZWN0ZWQgaXRlbS5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IHRoZSBrZXkgb2YgdGhlIHNlbGVjdGVkIGl0ZW0gb3IgbnVsbCBpZiBubyBpdGVtIGlzIHNlbGVjdGVkXHJcbiAgICAgKi9cclxuICAgIExpc3RTZWxlY3Rvci5wcm90b3R5cGUuZ2V0U2VsZWN0ZWRJdGVtID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNlbGVjdGVkSXRlbTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJlbW92ZXMgYWxsIGl0ZW1zIGZyb20gdGhpcyBzZWxlY3Rvci5cclxuICAgICAqL1xyXG4gICAgTGlzdFNlbGVjdG9yLnByb3RvdHlwZS5jbGVhckl0ZW1zID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIGxvY2FsIGNvcHkgZm9yIGl0ZXJhdGlvbiBhZnRlciBjbGVhclxyXG4gICAgICAgIHZhciBpdGVtcyA9IHRoaXMuaXRlbXM7XHJcbiAgICAgICAgLy8gY2xlYXIgaXRlbXNcclxuICAgICAgICB0aGlzLml0ZW1zID0gW107XHJcbiAgICAgICAgLy8gY2xlYXIgdGhlIHNlbGVjdGlvbiBhcyB0aGUgc2VsZWN0ZWQgaXRlbSBpcyBhbHNvIHJlbW92ZWRcclxuICAgICAgICB0aGlzLnNlbGVjdGVkSXRlbSA9IG51bGw7XHJcbiAgICAgICAgLy8gZmlyZSBldmVudHNcclxuICAgICAgICBmb3IgKHZhciBfaSA9IDAsIGl0ZW1zXzEgPSBpdGVtczsgX2kgPCBpdGVtc18xLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICB2YXIgaXRlbSA9IGl0ZW1zXzFbX2ldO1xyXG4gICAgICAgICAgICB0aGlzLm9uSXRlbVJlbW92ZWRFdmVudChpdGVtLmtleSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGl0ZW1zIGluIHRoaXMgc2VsZWN0b3IuXHJcbiAgICAgKiBAcmV0dXJucyB7bnVtYmVyfVxyXG4gICAgICovXHJcbiAgICBMaXN0U2VsZWN0b3IucHJvdG90eXBlLml0ZW1Db3VudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gT2JqZWN0LmtleXModGhpcy5pdGVtcykubGVuZ3RoO1xyXG4gICAgfTtcclxuICAgIExpc3RTZWxlY3Rvci5wcm90b3R5cGUub25JdGVtQWRkZWRFdmVudCA9IGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICB0aGlzLmxpc3RTZWxlY3RvckV2ZW50cy5vbkl0ZW1BZGRlZC5kaXNwYXRjaCh0aGlzLCBrZXkpO1xyXG4gICAgfTtcclxuICAgIExpc3RTZWxlY3Rvci5wcm90b3R5cGUub25JdGVtUmVtb3ZlZEV2ZW50ID0gZnVuY3Rpb24gKGtleSkge1xyXG4gICAgICAgIHRoaXMubGlzdFNlbGVjdG9yRXZlbnRzLm9uSXRlbVJlbW92ZWQuZGlzcGF0Y2godGhpcywga2V5KTtcclxuICAgIH07XHJcbiAgICBMaXN0U2VsZWN0b3IucHJvdG90eXBlLm9uSXRlbVNlbGVjdGVkRXZlbnQgPSBmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgdGhpcy5saXN0U2VsZWN0b3JFdmVudHMub25JdGVtU2VsZWN0ZWQuZGlzcGF0Y2godGhpcywga2V5KTtcclxuICAgIH07XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoTGlzdFNlbGVjdG9yLnByb3RvdHlwZSwgXCJvbkl0ZW1BZGRlZFwiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogR2V0cyB0aGUgZXZlbnQgdGhhdCBpcyBmaXJlZCB3aGVuIGFuIGl0ZW0gaXMgYWRkZWQgdG8gdGhlIGxpc3Qgb2YgaXRlbXMuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50PExpc3RTZWxlY3RvcjxDb25maWc+LCBzdHJpbmc+fVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5saXN0U2VsZWN0b3JFdmVudHMub25JdGVtQWRkZWQuZ2V0RXZlbnQoKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShMaXN0U2VsZWN0b3IucHJvdG90eXBlLCBcIm9uSXRlbVJlbW92ZWRcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldHMgdGhlIGV2ZW50IHRoYXQgaXMgZmlyZWQgd2hlbiBhbiBpdGVtIGlzIHJlbW92ZWQgZnJvbSB0aGUgbGlzdCBvZiBpdGVtcy5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnQ8TGlzdFNlbGVjdG9yPENvbmZpZz4sIHN0cmluZz59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxpc3RTZWxlY3RvckV2ZW50cy5vbkl0ZW1SZW1vdmVkLmdldEV2ZW50KCk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxyXG4gICAgICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZVxyXG4gICAgfSk7XHJcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkoTGlzdFNlbGVjdG9yLnByb3RvdHlwZSwgXCJvbkl0ZW1TZWxlY3RlZFwiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogR2V0cyB0aGUgZXZlbnQgdGhhdCBpcyBmaXJlZCB3aGVuIGFuIGl0ZW0gaXMgc2VsZWN0ZWQgZnJvbSB0aGUgbGlzdCBvZiBpdGVtcy5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnQ8TGlzdFNlbGVjdG9yPENvbmZpZz4sIHN0cmluZz59XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmxpc3RTZWxlY3RvckV2ZW50cy5vbkl0ZW1TZWxlY3RlZC5nZXRFdmVudCgpO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgcmV0dXJuIExpc3RTZWxlY3RvcjtcclxufShjb21wb25lbnRfMS5Db21wb25lbnQpKTtcclxuZXhwb3J0cy5MaXN0U2VsZWN0b3IgPSBMaXN0U2VsZWN0b3I7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9saXN0c2VsZWN0b3IudHNcbi8vIG1vZHVsZSBpZCA9IDIyXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgY29udGFpbmVyXzEgPSByZXF1aXJlKFwiLi9jb250YWluZXJcIik7XHJcbnZhciB2b2x1bWVzbGlkZXJfMSA9IHJlcXVpcmUoXCIuL3ZvbHVtZXNsaWRlclwiKTtcclxudmFyIHZvbHVtZXRvZ2dsZWJ1dHRvbl8xID0gcmVxdWlyZShcIi4vdm9sdW1ldG9nZ2xlYnV0dG9uXCIpO1xyXG52YXIgdGltZW91dF8xID0gcmVxdWlyZShcIi4uL3RpbWVvdXRcIik7XHJcbi8qKlxyXG4gKiBBIGNvbXBvc2l0ZSB2b2x1bWUgY29udHJvbCB0aGF0IGNvbnNpc3RzIG9mIGFuZCBpbnRlcm5hbGx5IG1hbmFnZXMgYSB2b2x1bWUgY29udHJvbCBidXR0b24gdGhhdCBjYW4gYmUgdXNlZFxyXG4gKiBmb3IgbXV0aW5nLCBhbmQgYSAoZGVwZW5kaW5nIG9uIHRoZSBDU1Mgc3R5bGUsIGUuZy4gc2xpZGUtb3V0KSB2b2x1bWUgY29udHJvbCBiYXIuXHJcbiAqL1xyXG52YXIgVm9sdW1lQ29udHJvbEJ1dHRvbiA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoVm9sdW1lQ29udHJvbEJ1dHRvbiwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFZvbHVtZUNvbnRyb2xCdXR0b24oY29uZmlnKSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLnZvbHVtZVRvZ2dsZUJ1dHRvbiA9IG5ldyB2b2x1bWV0b2dnbGVidXR0b25fMS5Wb2x1bWVUb2dnbGVCdXR0b24oKTtcclxuICAgICAgICBfdGhpcy52b2x1bWVTbGlkZXIgPSBuZXcgdm9sdW1lc2xpZGVyXzEuVm9sdW1lU2xpZGVyKHtcclxuICAgICAgICAgICAgdmVydGljYWw6IGNvbmZpZy52ZXJ0aWNhbCAhPSBudWxsID8gY29uZmlnLnZlcnRpY2FsIDogdHJ1ZSxcclxuICAgICAgICAgICAgaGlkZGVuOiB0cnVlLFxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLXZvbHVtZWNvbnRyb2xidXR0b24nLFxyXG4gICAgICAgICAgICBjb21wb25lbnRzOiBbX3RoaXMudm9sdW1lVG9nZ2xlQnV0dG9uLCBfdGhpcy52b2x1bWVTbGlkZXJdLFxyXG4gICAgICAgICAgICBoaWRlRGVsYXk6IDUwMCxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIFZvbHVtZUNvbnRyb2xCdXR0b24ucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jb25maWd1cmUuY2FsbCh0aGlzLCBwbGF5ZXIsIHVpbWFuYWdlcik7XHJcbiAgICAgICAgdmFyIHZvbHVtZVRvZ2dsZUJ1dHRvbiA9IHRoaXMuZ2V0Vm9sdW1lVG9nZ2xlQnV0dG9uKCk7XHJcbiAgICAgICAgdmFyIHZvbHVtZVNsaWRlciA9IHRoaXMuZ2V0Vm9sdW1lU2xpZGVyKCk7XHJcbiAgICAgICAgdGhpcy52b2x1bWVTbGlkZXJIaWRlVGltZW91dCA9IG5ldyB0aW1lb3V0XzEuVGltZW91dCh0aGlzLmdldENvbmZpZygpLmhpZGVEZWxheSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2b2x1bWVTbGlkZXIuaGlkZSgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8qXHJcbiAgICAgICAgICogVm9sdW1lIFNsaWRlciB2aXNpYmlsaXR5IGhhbmRsaW5nXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBUaGUgdm9sdW1lIHNsaWRlciBzaGFsbCBiZSB2aXNpYmxlIHdoaWxlIHRoZSB1c2VyIGhvdmVycyB0aGUgbXV0ZSB0b2dnbGUgYnV0dG9uLCB3aGlsZSB0aGUgdXNlciBob3ZlcnMgdGhlXHJcbiAgICAgICAgICogdm9sdW1lIHNsaWRlciwgYW5kIHdoaWxlIHRoZSB1c2VyIHNsaWRlcyB0aGUgdm9sdW1lIHNsaWRlci4gSWYgbm9uZSBvZiB0aGVzZSBzaXR1YXRpb25zIGFyZSB0cnVlLCB0aGUgc2xpZGVyXHJcbiAgICAgICAgICogc2hhbGwgZGlzYXBwZWFyLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHZhciB2b2x1bWVTbGlkZXJIb3ZlcmVkID0gZmFsc2U7XHJcbiAgICAgICAgdm9sdW1lVG9nZ2xlQnV0dG9uLmdldERvbUVsZW1lbnQoKS5vbignbW91c2VlbnRlcicsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgLy8gU2hvdyB2b2x1bWUgc2xpZGVyIHdoZW4gbW91c2UgZW50ZXJzIHRoZSBidXR0b24gYXJlYVxyXG4gICAgICAgICAgICBpZiAodm9sdW1lU2xpZGVyLmlzSGlkZGVuKCkpIHtcclxuICAgICAgICAgICAgICAgIHZvbHVtZVNsaWRlci5zaG93KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gQXZvaWQgaGlkaW5nIG9mIHRoZSBzbGlkZXIgd2hlbiBidXR0b24gaXMgaG92ZXJlZFxyXG4gICAgICAgICAgICBfdGhpcy52b2x1bWVTbGlkZXJIaWRlVGltZW91dC5jbGVhcigpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZvbHVtZVRvZ2dsZUJ1dHRvbi5nZXREb21FbGVtZW50KCkub24oJ21vdXNlbGVhdmUnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIC8vIEhpZGUgc2xpZGVyIGRlbGF5ZWQgd2hlbiBidXR0b24gaXMgbGVmdFxyXG4gICAgICAgICAgICBfdGhpcy52b2x1bWVTbGlkZXJIaWRlVGltZW91dC5yZXNldCgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZvbHVtZVNsaWRlci5nZXREb21FbGVtZW50KCkub24oJ21vdXNlZW50ZXInLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIC8vIFdoZW4gdGhlIHNsaWRlciBpcyBlbnRlcmVkLCBjYW5jZWwgdGhlIGhpZGUgdGltZW91dCBhY3RpdmF0ZWQgYnkgbGVhdmluZyB0aGUgYnV0dG9uXHJcbiAgICAgICAgICAgIF90aGlzLnZvbHVtZVNsaWRlckhpZGVUaW1lb3V0LmNsZWFyKCk7XHJcbiAgICAgICAgICAgIHZvbHVtZVNsaWRlckhvdmVyZWQgPSB0cnVlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZvbHVtZVNsaWRlci5nZXREb21FbGVtZW50KCkub24oJ21vdXNlbGVhdmUnLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIC8vIFdoZW4gbW91c2UgbGVhdmVzIHRoZSBzbGlkZXIsIG9ubHkgaGlkZSBpdCBpZiB0aGVyZSBpcyBubyBzbGlkZSBvcGVyYXRpb24gaW4gcHJvZ3Jlc3NcclxuICAgICAgICAgICAgaWYgKHZvbHVtZVNsaWRlci5pc1NlZWtpbmcoKSkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMudm9sdW1lU2xpZGVySGlkZVRpbWVvdXQuY2xlYXIoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLnZvbHVtZVNsaWRlckhpZGVUaW1lb3V0LnJlc2V0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdm9sdW1lU2xpZGVySG92ZXJlZCA9IGZhbHNlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZvbHVtZVNsaWRlci5vblNlZWtlZC5zdWJzY3JpYmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvLyBXaGVuIGEgc2xpZGUgb3BlcmF0aW9uIGlzIGRvbmUgYW5kIHRoZSBzbGlkZXIgbm90IGhvdmVyZWQgKG1vdXNlIG91dHNpZGUgc2xpZGVyKSwgaGlkZSBzbGlkZXIgZGVsYXllZFxyXG4gICAgICAgICAgICBpZiAoIXZvbHVtZVNsaWRlckhvdmVyZWQpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLnZvbHVtZVNsaWRlckhpZGVUaW1lb3V0LnJlc2V0KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBWb2x1bWVDb250cm9sQnV0dG9uLnByb3RvdHlwZS5yZWxlYXNlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUucmVsZWFzZS5jYWxsKHRoaXMpO1xyXG4gICAgICAgIHRoaXMudm9sdW1lU2xpZGVySGlkZVRpbWVvdXQuY2xlYXIoKTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgaW50ZXJuYWxseSBtYW5hZ2VkIHZvbHVtZSB0b2dnbGUgYnV0dG9uLlxyXG4gICAgICogQHJldHVybnMge1ZvbHVtZVRvZ2dsZUJ1dHRvbn1cclxuICAgICAqL1xyXG4gICAgVm9sdW1lQ29udHJvbEJ1dHRvbi5wcm90b3R5cGUuZ2V0Vm9sdW1lVG9nZ2xlQnV0dG9uID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnZvbHVtZVRvZ2dsZUJ1dHRvbjtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFByb3ZpZGVzIGFjY2VzcyB0byB0aGUgaW50ZXJuYWxseSBtYW5hZ2VkIHZvbHVtZSBzaWxkZXIuXHJcbiAgICAgKiBAcmV0dXJucyB7Vm9sdW1lU2xpZGVyfVxyXG4gICAgICovXHJcbiAgICBWb2x1bWVDb250cm9sQnV0dG9uLnByb3RvdHlwZS5nZXRWb2x1bWVTbGlkZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudm9sdW1lU2xpZGVyO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBWb2x1bWVDb250cm9sQnV0dG9uO1xyXG59KGNvbnRhaW5lcl8xLkNvbnRhaW5lcikpO1xyXG5leHBvcnRzLlZvbHVtZUNvbnRyb2xCdXR0b24gPSBWb2x1bWVDb250cm9sQnV0dG9uO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvdm9sdW1lY29udHJvbGJ1dHRvbi50c1xuLy8gbW9kdWxlIGlkID0gMjNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBzZWVrYmFyXzEgPSByZXF1aXJlKFwiLi9zZWVrYmFyXCIpO1xyXG4vKipcclxuICogQSBzaW1wbGUgdm9sdW1lIHNsaWRlciBjb21wb25lbnQgdG8gYWRqdXN0IHRoZSBwbGF5ZXIncyB2b2x1bWUgc2V0dGluZy5cclxuICovXHJcbnZhciBWb2x1bWVTbGlkZXIgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKFZvbHVtZVNsaWRlciwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFZvbHVtZVNsaWRlcihjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktdm9sdW1lc2xpZGVyJyxcclxuICAgICAgICAgICAgaGlkZUlmVm9sdW1lQ29udHJvbFByb2hpYml0ZWQ6IHRydWUsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBWb2x1bWVTbGlkZXIucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jb25maWd1cmUuY2FsbCh0aGlzLCBwbGF5ZXIsIHVpbWFuYWdlciwgZmFsc2UpO1xyXG4gICAgICAgIHZhciBjb25maWcgPSB0aGlzLmdldENvbmZpZygpO1xyXG4gICAgICAgIGlmIChjb25maWcuaGlkZUlmVm9sdW1lQ29udHJvbFByb2hpYml0ZWQgJiYgIXRoaXMuZGV0ZWN0Vm9sdW1lQ29udHJvbEF2YWlsYWJpbGl0eShwbGF5ZXIpKSB7XHJcbiAgICAgICAgICAgIHRoaXMuaGlkZSgpO1xyXG4gICAgICAgICAgICAvLyBXZSBjYW4ganVzdCByZXR1cm4gZnJvbSBoZXJlLCBiZWNhdXNlIHRoZSB1c2VyIHdpbGwgbmV2ZXIgaW50ZXJhY3Qgd2l0aCB0aGUgY29udHJvbCBhbmQgYW55IGNvbmZpZ3VyZWRcclxuICAgICAgICAgICAgLy8gZnVuY3Rpb25hbGl0eSB3b3VsZCBvbmx5IGVhdCByZXNvdXJjZXMgZm9yIG5vIHJlYXNvbi5cclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgdm9sdW1lQ2hhbmdlSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKHBsYXllci5pc011dGVkKCkpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLnNldFBsYXliYWNrUG9zaXRpb24oMCk7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5zZXRCdWZmZXJQb3NpdGlvbigwKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLnNldFBsYXliYWNrUG9zaXRpb24ocGxheWVyLmdldFZvbHVtZSgpKTtcclxuICAgICAgICAgICAgICAgIF90aGlzLnNldEJ1ZmZlclBvc2l0aW9uKHBsYXllci5nZXRWb2x1bWUoKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1JFQURZLCB2b2x1bWVDaGFuZ2VIYW5kbGVyKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9WT0xVTUVfQ0hBTkdFRCwgdm9sdW1lQ2hhbmdlSGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fTVVURUQsIHZvbHVtZUNoYW5nZUhhbmRsZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1VOTVVURUQsIHZvbHVtZUNoYW5nZUhhbmRsZXIpO1xyXG4gICAgICAgIHRoaXMub25TZWVrUHJldmlldy5zdWJzY3JpYmVSYXRlTGltaXRlZChmdW5jdGlvbiAoc2VuZGVyLCBhcmdzKSB7XHJcbiAgICAgICAgICAgIGlmIChhcmdzLnNjcnViYmluZykge1xyXG4gICAgICAgICAgICAgICAgcGxheWVyLnNldFZvbHVtZShhcmdzLnBvc2l0aW9uLCBWb2x1bWVTbGlkZXIuaXNzdWVyTmFtZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9LCA1MCk7XHJcbiAgICAgICAgdGhpcy5vblNlZWtlZC5zdWJzY3JpYmUoZnVuY3Rpb24gKHNlbmRlciwgcGVyY2VudGFnZSkge1xyXG4gICAgICAgICAgICBwbGF5ZXIuc2V0Vm9sdW1lKHBlcmNlbnRhZ2UsIFZvbHVtZVNsaWRlci5pc3N1ZXJOYW1lKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBVcGRhdGUgdGhlIHZvbHVtZSBzbGlkZXIgbWFya2VyIHdoZW4gdGhlIHBsYXllciByZXNpemVkLCBhIHNvdXJjZSBpcyBsb2FkZWQgYW5kIHBsYXllciBpcyByZWFkeSxcclxuICAgICAgICAvLyBvciB0aGUgVUkgaXMgY29uZmlndXJlZC4gQ2hlY2sgdGhlIHNlZWtiYXIgZm9yIGEgZGV0YWlsZWQgZGVzY3JpcHRpb24uXHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUExBWUVSX1JFU0laRSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5yZWZyZXNoUGxheWJhY2tQb3NpdGlvbigpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1JFQURZLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLnJlZnJlc2hQbGF5YmFja1Bvc2l0aW9uKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdWltYW5hZ2VyLm9uQ29uZmlndXJlZC5zdWJzY3JpYmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfdGhpcy5yZWZyZXNoUGxheWJhY2tQb3NpdGlvbigpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIEluaXQgdm9sdW1lIGJhclxyXG4gICAgICAgIHZvbHVtZUNoYW5nZUhhbmRsZXIoKTtcclxuICAgIH07XHJcbiAgICBWb2x1bWVTbGlkZXIucHJvdG90eXBlLmRldGVjdFZvbHVtZUNvbnRyb2xBdmFpbGFiaWxpdHkgPSBmdW5jdGlvbiAocGxheWVyKSB7XHJcbiAgICAgICAgLy8gU3RvcmUgY3VycmVudCBwbGF5ZXIgc3RhdGUgc28gd2UgY2FuIHJlc3RvcmUgaXQgbGF0ZXJcclxuICAgICAgICB2YXIgdm9sdW1lID0gcGxheWVyLmdldFZvbHVtZSgpO1xyXG4gICAgICAgIHZhciBtdXRlZCA9IHBsYXllci5pc011dGVkKCk7XHJcbiAgICAgICAgdmFyIHBsYXlpbmcgPSBwbGF5ZXIuaXNQbGF5aW5nKCk7XHJcbiAgICAgICAgLypcclxuICAgICAgICAgKiBcIk9uIGlPUyBkZXZpY2VzLCB0aGUgYXVkaW8gbGV2ZWwgaXMgYWx3YXlzIHVuZGVyIHRoZSB1c2Vy4oCZcyBwaHlzaWNhbCBjb250cm9sLiBUaGUgdm9sdW1lIHByb3BlcnR5IGlzIG5vdFxyXG4gICAgICAgICAqIHNldHRhYmxlIGluIEphdmFTY3JpcHQuIFJlYWRpbmcgdGhlIHZvbHVtZSBwcm9wZXJ0eSBhbHdheXMgcmV0dXJucyAxLlwiXHJcbiAgICAgICAgICogaHR0cHM6Ly9kZXZlbG9wZXIuYXBwbGUuY29tL2xpYnJhcnkvY29udGVudC9kb2N1bWVudGF0aW9uL0F1ZGlvVmlkZW8vQ29uY2VwdHVhbC9Vc2luZ19IVE1MNV9BdWRpb19WaWRlby9EZXZpY2UtU3BlY2lmaWNDb25zaWRlcmF0aW9ucy9EZXZpY2UtU3BlY2lmaWNDb25zaWRlcmF0aW9ucy5odG1sXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBPdXIgcGxheWVyIEFQSSByZXR1cm5zIGEgdm9sdW1lIHJhbmdlIG9mIFswLCAxMDBdIHNvIHdlIG5lZWQgdG8gY2hlY2sgZm9yIDEwMCBpbnN0ZWFkIG9mIDEuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgLy8gT25seSBpZiB0aGUgdm9sdW1lIGlzIDEwMCwgdGhlcmUncyB0aGUgcG9zc2liaWxpdHkgd2UgYXJlIG9uIGEgdm9sdW1lLWNvbnRyb2wtcmVzdHJpY3RlZCBpT1MgZGV2aWNlXHJcbiAgICAgICAgaWYgKHZvbHVtZSA9PT0gMTAwKSB7XHJcbiAgICAgICAgICAgIC8vIFdlIHNldCB0aGUgdm9sdW1lIHRvIHplcm8gKHRoYXQncyB0aGUgb25seSB2YWx1ZSB0aGF0IGRvZXMgbm90IHVubXV0ZSBhIG11dGVkIHBsYXllciEpXHJcbiAgICAgICAgICAgIHBsYXllci5zZXRWb2x1bWUoMCwgVm9sdW1lU2xpZGVyLmlzc3Vlck5hbWUpO1xyXG4gICAgICAgICAgICAvLyBUaGVuIHdlIGNoZWNrIGlmIHRoZSB2YWx1ZSBpcyBzdGlsbCAxMDBcclxuICAgICAgICAgICAgaWYgKHBsYXllci5nZXRWb2x1bWUoKSA9PT0gMTAwKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBJZiB0aGUgdm9sdW1lIHN0YXllZCBhdCAxMDAsIHdlJ3JlIG9uIGEgdm9sdW1lLWNvbnRyb2wtcmVzdHJpY3RlZCBkZXZpY2VcclxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIFdlIGNhbiBjb250cm9sIHZvbHVtZSwgc28gd2UgbXVzdCByZXN0b3JlIHRoZSBwcmV2aW91cyBwbGF5ZXIgc3RhdGVcclxuICAgICAgICAgICAgICAgIHBsYXllci5zZXRWb2x1bWUodm9sdW1lLCBWb2x1bWVTbGlkZXIuaXNzdWVyTmFtZSk7XHJcbiAgICAgICAgICAgICAgICBpZiAobXV0ZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICBwbGF5ZXIubXV0ZShWb2x1bWVTbGlkZXIuaXNzdWVyTmFtZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAocGxheWluZykge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIFRoZSB2b2x1bWUgcmVzdG9yZSBhYm92ZSBwYXVzZXMgYXV0b3BsYXkgb24gbW9iaWxlIGRldmljZXMgKGUuZy4gQW5kcm9pZCkgc28gd2UgbmVlZCB0byByZXN1bWUgcGxheWJhY2tcclxuICAgICAgICAgICAgICAgICAgICAvLyAoV2UgY2Fubm90IGNoZWNrIGlzUGF1c2VkKCkgaGVyZSBiZWNhdXNlIGl0IGlzIG5vdCBzZXQgd2hlbiBwbGF5YmFjayBpcyBwcm9oaWJpdGVkIGJ5IHRoZSBtb2JpbGUgcGxhdGZvcm0pXHJcbiAgICAgICAgICAgICAgICAgICAgcGxheWVyLnBsYXkoVm9sdW1lU2xpZGVyLmlzc3Vlck5hbWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIFZvbHVtZSBpcyBub3QgMTAwLCBzbyB3ZSdyZSBkZWZpbml0ZWx5IG5vdCBvbiBhIHZvbHVtZS1jb250cm9sLXJlc3RyaWN0ZWQgaU9TIGRldmljZVxyXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFZvbHVtZVNsaWRlcjtcclxufShzZWVrYmFyXzEuU2Vla0JhcikpO1xyXG5Wb2x1bWVTbGlkZXIuaXNzdWVyTmFtZSA9ICd1aSc7XHJcbmV4cG9ydHMuVm9sdW1lU2xpZGVyID0gVm9sdW1lU2xpZGVyO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvdm9sdW1lc2xpZGVyLnRzXG4vLyBtb2R1bGUgaWQgPSAyNFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIHRvZ2dsZWJ1dHRvbl8xID0gcmVxdWlyZShcIi4vdG9nZ2xlYnV0dG9uXCIpO1xyXG4vKipcclxuICogQSBidXR0b24gdGhhdCB0b2dnbGVzIGF1ZGlvIG11dGluZy5cclxuICovXHJcbnZhciBWb2x1bWVUb2dnbGVCdXR0b24gPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKFZvbHVtZVRvZ2dsZUJ1dHRvbiwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFZvbHVtZVRvZ2dsZUJ1dHRvbihjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktdm9sdW1ldG9nZ2xlYnV0dG9uJyxcclxuICAgICAgICAgICAgdGV4dDogJ1ZvbHVtZS9NdXRlJyxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIFZvbHVtZVRvZ2dsZUJ1dHRvbi5wcm90b3R5cGUuY29uZmlndXJlID0gZnVuY3Rpb24gKHBsYXllciwgdWltYW5hZ2VyKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNvbmZpZ3VyZS5jYWxsKHRoaXMsIHBsYXllciwgdWltYW5hZ2VyKTtcclxuICAgICAgICB2YXIgbXV0ZVN0YXRlSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgaWYgKHBsYXllci5pc011dGVkKCkpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLm9uKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5vZmYoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIHZvbHVtZUxldmVsSGFuZGxlciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgLy8gVG9nZ2xlIGxvdyBjbGFzcyB0byBkaXNwbGF5IGxvdyB2b2x1bWUgaWNvbiBiZWxvdyA1MCUgdm9sdW1lXHJcbiAgICAgICAgICAgIGlmIChwbGF5ZXIuZ2V0Vm9sdW1lKCkgPCA1MCkge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZ2V0RG9tRWxlbWVudCgpLmFkZENsYXNzKF90aGlzLnByZWZpeENzcygnbG93JykpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuZ2V0RG9tRWxlbWVudCgpLnJlbW92ZUNsYXNzKF90aGlzLnByZWZpeENzcygnbG93JykpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9NVVRFRCwgbXV0ZVN0YXRlSGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fVU5NVVRFRCwgbXV0ZVN0YXRlSGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fVk9MVU1FX0NIQU5HRUQsIHZvbHVtZUxldmVsSGFuZGxlcik7XHJcbiAgICAgICAgdGhpcy5vbkNsaWNrLnN1YnNjcmliZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChwbGF5ZXIuaXNNdXRlZCgpKSB7XHJcbiAgICAgICAgICAgICAgICBwbGF5ZXIudW5tdXRlKCd1aS12b2x1bWV0b2dnbGVidXR0b24nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHBsYXllci5tdXRlKCd1aS12b2x1bWV0b2dnbGVidXR0b24nKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIC8vIFN0YXJ0dXAgaW5pdFxyXG4gICAgICAgIG11dGVTdGF0ZUhhbmRsZXIoKTtcclxuICAgICAgICB2b2x1bWVMZXZlbEhhbmRsZXIoKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gVm9sdW1lVG9nZ2xlQnV0dG9uO1xyXG59KHRvZ2dsZWJ1dHRvbl8xLlRvZ2dsZUJ1dHRvbikpO1xyXG5leHBvcnRzLlZvbHVtZVRvZ2dsZUJ1dHRvbiA9IFZvbHVtZVRvZ2dsZUJ1dHRvbjtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3ZvbHVtZXRvZ2dsZWJ1dHRvbi50c1xuLy8gbW9kdWxlIGlkID0gMjVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBjb250YWluZXJfMSA9IHJlcXVpcmUoXCIuL2NvbnRhaW5lclwiKTtcclxudmFyIGxhYmVsXzEgPSByZXF1aXJlKFwiLi9sYWJlbFwiKTtcclxudmFyIHR2bm9pc2VjYW52YXNfMSA9IHJlcXVpcmUoXCIuL3R2bm9pc2VjYW52YXNcIik7XHJcbi8qKlxyXG4gKiBPdmVybGF5cyB0aGUgcGxheWVyIGFuZCBkaXNwbGF5cyBlcnJvciBtZXNzYWdlcy5cclxuICovXHJcbnZhciBFcnJvck1lc3NhZ2VPdmVybGF5ID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhFcnJvck1lc3NhZ2VPdmVybGF5LCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gRXJyb3JNZXNzYWdlT3ZlcmxheShjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuZXJyb3JMYWJlbCA9IG5ldyBsYWJlbF8xLkxhYmVsKHsgY3NzQ2xhc3M6ICd1aS1lcnJvcm1lc3NhZ2UtbGFiZWwnIH0pO1xyXG4gICAgICAgIF90aGlzLnR2Tm9pc2VCYWNrZ3JvdW5kID0gbmV3IHR2bm9pc2VjYW52YXNfMS5Udk5vaXNlQ2FudmFzKCk7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktZXJyb3JtZXNzYWdlLW92ZXJsYXknLFxyXG4gICAgICAgICAgICBjb21wb25lbnRzOiBbX3RoaXMudHZOb2lzZUJhY2tncm91bmQsIF90aGlzLmVycm9yTGFiZWxdLFxyXG4gICAgICAgICAgICBoaWRkZW46IHRydWUsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBFcnJvck1lc3NhZ2VPdmVybGF5LnByb3RvdHlwZS5jb25maWd1cmUgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY29uZmlndXJlLmNhbGwodGhpcywgcGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIHZhciBjb25maWcgPSB0aGlzLmdldENvbmZpZygpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0VSUk9SLCBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSBldmVudC5tZXNzYWdlO1xyXG4gICAgICAgICAgICAvLyBQcm9jZXNzIG1lc3NhZ2UgdHJhbnNsYXRpb25zXHJcbiAgICAgICAgICAgIGlmIChjb25maWcubWVzc2FnZXMpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgY29uZmlnLm1lc3NhZ2VzID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gVHJhbnNsYXRpb24gZnVuY3Rpb24gZm9yIGFsbCBlcnJvcnNcclxuICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gY29uZmlnLm1lc3NhZ2VzKGV2ZW50KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKGNvbmZpZy5tZXNzYWdlc1tldmVudC5jb2RlXSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vIEl0J3Mgbm90IGEgdHJhbnNsYXRpb24gZnVuY3Rpb24sIHNvIGl0IG11c3QgYmUgYSBtYXAgb2Ygc3RyaW5ncyBvciB0cmFuc2xhdGlvbiBmdW5jdGlvbnNcclxuICAgICAgICAgICAgICAgICAgICB2YXIgY3VzdG9tTWVzc2FnZSA9IGNvbmZpZy5tZXNzYWdlc1tldmVudC5jb2RlXTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGN1c3RvbU1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBjdXN0b21NZXNzYWdlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gVGhlIG1lc3NhZ2UgaXMgYSB0cmFuc2xhdGlvbiBmdW5jdGlvbiwgc28gd2UgY2FsbCBpdFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBtZXNzYWdlID0gY3VzdG9tTWVzc2FnZShldmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF90aGlzLmVycm9yTGFiZWwuc2V0VGV4dChtZXNzYWdlKTtcclxuICAgICAgICAgICAgX3RoaXMudHZOb2lzZUJhY2tncm91bmQuc3RhcnQoKTtcclxuICAgICAgICAgICAgX3RoaXMuc2hvdygpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1NPVVJDRV9MT0FERUQsIGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuaXNTaG93bigpKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy50dk5vaXNlQmFja2dyb3VuZC5zdG9wKCk7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5oaWRlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBFcnJvck1lc3NhZ2VPdmVybGF5LnByb3RvdHlwZS5yZWxlYXNlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUucmVsZWFzZS5jYWxsKHRoaXMpO1xyXG4gICAgICAgIC8vIENhbnZhcyByZW5kZXJpbmcgbXVzdCBiZSBleHBsaWNpdGx5IHN0b3BwZWQsIGVsc2UgaXQganVzdCBjb250aW51ZXMgZm9yZXZlciBhbmQgaG9ncyByZXNvdXJjZXNcclxuICAgICAgICB0aGlzLnR2Tm9pc2VCYWNrZ3JvdW5kLnN0b3AoKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gRXJyb3JNZXNzYWdlT3ZlcmxheTtcclxufShjb250YWluZXJfMS5Db250YWluZXIpKTtcclxuZXhwb3J0cy5FcnJvck1lc3NhZ2VPdmVybGF5ID0gRXJyb3JNZXNzYWdlT3ZlcmxheTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2Vycm9ybWVzc2FnZW92ZXJsYXkudHNcbi8vIG1vZHVsZSBpZCA9IDI2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgY29udGFpbmVyXzEgPSByZXF1aXJlKFwiLi9jb250YWluZXJcIik7XHJcbnZhciBodWdlcGxheWJhY2t0b2dnbGVidXR0b25fMSA9IHJlcXVpcmUoXCIuL2h1Z2VwbGF5YmFja3RvZ2dsZWJ1dHRvblwiKTtcclxuLyoqXHJcbiAqIE92ZXJsYXlzIHRoZSBwbGF5ZXIgYW5kIGRpc3BsYXlzIGVycm9yIG1lc3NhZ2VzLlxyXG4gKi9cclxudmFyIFBsYXliYWNrVG9nZ2xlT3ZlcmxheSA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoUGxheWJhY2tUb2dnbGVPdmVybGF5LCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gUGxheWJhY2tUb2dnbGVPdmVybGF5KGNvbmZpZykge1xyXG4gICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5wbGF5YmFja1RvZ2dsZUJ1dHRvbiA9IG5ldyBodWdlcGxheWJhY2t0b2dnbGVidXR0b25fMS5IdWdlUGxheWJhY2tUb2dnbGVCdXR0b24oKTtcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1wbGF5YmFja3RvZ2dsZS1vdmVybGF5JyxcclxuICAgICAgICAgICAgY29tcG9uZW50czogW190aGlzLnBsYXliYWNrVG9nZ2xlQnV0dG9uXSxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIHJldHVybiBQbGF5YmFja1RvZ2dsZU92ZXJsYXk7XHJcbn0oY29udGFpbmVyXzEuQ29udGFpbmVyKSk7XHJcbmV4cG9ydHMuUGxheWJhY2tUb2dnbGVPdmVybGF5ID0gUGxheWJhY2tUb2dnbGVPdmVybGF5O1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvcGxheWJhY2t0b2dnbGVvdmVybGF5LnRzXG4vLyBtb2R1bGUgaWQgPSAyN1xuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIHBsYXliYWNrdG9nZ2xlYnV0dG9uXzEgPSByZXF1aXJlKFwiLi9wbGF5YmFja3RvZ2dsZWJ1dHRvblwiKTtcclxudmFyIGRvbV8xID0gcmVxdWlyZShcIi4uL2RvbVwiKTtcclxuLyoqXHJcbiAqIEEgYnV0dG9uIHRoYXQgb3ZlcmxheXMgdGhlIHZpZGVvIGFuZCB0b2dnbGVzIGJldHdlZW4gcGxheWJhY2sgYW5kIHBhdXNlLlxyXG4gKi9cclxudmFyIEh1Z2VQbGF5YmFja1RvZ2dsZUJ1dHRvbiA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoSHVnZVBsYXliYWNrVG9nZ2xlQnV0dG9uLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gSHVnZVBsYXliYWNrVG9nZ2xlQnV0dG9uKGNvbmZpZykge1xyXG4gICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1odWdlcGxheWJhY2t0b2dnbGVidXR0b24nLFxyXG4gICAgICAgICAgICB0ZXh0OiAnUGxheS9QYXVzZScsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBIdWdlUGxheWJhY2tUb2dnbGVCdXR0b24ucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgLy8gVXBkYXRlIGJ1dHRvbiBzdGF0ZSB0aHJvdWdoIEFQSSBldmVudHNcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNvbmZpZ3VyZS5jYWxsKHRoaXMsIHBsYXllciwgdWltYW5hZ2VyLCBmYWxzZSk7XHJcbiAgICAgICAgdmFyIHRvZ2dsZVBsYXliYWNrID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAocGxheWVyLmlzUGxheWluZygpKSB7XHJcbiAgICAgICAgICAgICAgICBwbGF5ZXIucGF1c2UoJ3VpJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBwbGF5ZXIucGxheSgndWknKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIHRvZ2dsZUZ1bGxzY3JlZW4gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChwbGF5ZXIuaXNGdWxsc2NyZWVuKCkpIHtcclxuICAgICAgICAgICAgICAgIHBsYXllci5leGl0RnVsbHNjcmVlbigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcGxheWVyLmVudGVyRnVsbHNjcmVlbigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICB2YXIgZmlyc3RQbGF5ID0gdHJ1ZTtcclxuICAgICAgICB2YXIgY2xpY2tUaW1lID0gMDtcclxuICAgICAgICB2YXIgZG91YmxlQ2xpY2tUaW1lID0gMDtcclxuICAgICAgICAvKlxyXG4gICAgICAgICAqIFlvdVR1YmUtc3R5bGUgdG9nZ2xlIGJ1dHRvbiBoYW5kbGluZ1xyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogVGhlIGdvYWwgaXMgdG8gcHJldmVudCBhIHNob3J0IHBhdXNlIG9yIHBsYXliYWNrIGludGVydmFsIGJldHdlZW4gYSBjbGljaywgdGhhdCB0b2dnbGVzIHBsYXliYWNrLCBhbmQgYVxyXG4gICAgICAgICAqIGRvdWJsZSBjbGljaywgdGhhdCB0b2dnbGVzIGZ1bGxzY3JlZW4uIEluIHRoaXMgbmFpdmUgYXBwcm9hY2gsIHRoZSBmaXJzdCBjbGljayB3b3VsZCBlLmcuIHN0YXJ0IHBsYXliYWNrLFxyXG4gICAgICAgICAqIHRoZSBzZWNvbmQgY2xpY2sgd291bGQgYmUgZGV0ZWN0ZWQgYXMgZG91YmxlIGNsaWNrIGFuZCB0b2dnbGUgdG8gZnVsbHNjcmVlbiwgYW5kIGFzIHNlY29uZCBub3JtYWwgY2xpY2sgc3RvcFxyXG4gICAgICAgICAqIHBsYXliYWNrLCB3aGljaCByZXN1bHRzIGlzIGEgc2hvcnQgcGxheWJhY2sgaW50ZXJ2YWwgd2l0aCBtYXggbGVuZ3RoIG9mIHRoZSBkb3VibGUgY2xpY2sgZGV0ZWN0aW9uXHJcbiAgICAgICAgICogcGVyaW9kICh1c3VhbGx5IDUwMG1zKS5cclxuICAgICAgICAgKlxyXG4gICAgICAgICAqIFRvIHNvbHZlIHRoaXMgaXNzdWUsIHdlIGRlZmVyIGhhbmRsaW5nIG9mIHRoZSBmaXJzdCBjbGljayBmb3IgMjAwbXMsIHdoaWNoIGlzIGFsbW9zdCB1bm5vdGljZWFibGUgdG8gdGhlIHVzZXIsXHJcbiAgICAgICAgICogYW5kIGp1c3QgdG9nZ2xlIHBsYXliYWNrIGlmIG5vIHNlY29uZCBjbGljayAoZG91YmxlIGNsaWNrKSBoYXMgYmVlbiByZWdpc3RlcmVkIGR1cmluZyB0aGlzIHBlcmlvZC4gSWYgYSBkb3VibGVcclxuICAgICAgICAgKiBjbGljayBpcyByZWdpc3RlcmVkLCB3ZSBqdXN0IHRvZ2dsZSB0aGUgZnVsbHNjcmVlbi4gSW4gdGhlIGZpcnN0IDIwMG1zLCB1bmRlc2lyZWQgcGxheWJhY2sgY2hhbmdlcyB0aHVzIGNhbm5vdFxyXG4gICAgICAgICAqIGhhcHBlbi4gSWYgYSBkb3VibGUgY2xpY2sgaXMgcmVnaXN0ZXJlZCB3aXRoaW4gNTAwbXMsIHdlIHVuZG8gdGhlIHBsYXliYWNrIGNoYW5nZSBhbmQgc3dpdGNoIGZ1bGxzY3JlZW4gbW9kZS5cclxuICAgICAgICAgKiBJbiB0aGUgZW5kLCB0aGlzIG1ldGhvZCBiYXNpY2FsbHkgaW50cm9kdWNlcyBhIDIwMG1zIG9ic2VydmluZyBpbnRlcnZhbCBpbiB3aGljaCBwbGF5YmFjayBjaGFuZ2VzIGFyZSBwcmV2ZW50ZWRcclxuICAgICAgICAgKiBpZiBhIGRvdWJsZSBjbGljayBoYXBwZW5zLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHRoaXMub25DbGljay5zdWJzY3JpYmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvLyBEaXJlY3RseSBzdGFydCBwbGF5YmFjayBvbiBmaXJzdCBjbGljayBvZiB0aGUgYnV0dG9uLlxyXG4gICAgICAgICAgICAvLyBUaGlzIGlzIGEgcmVxdWlyZWQgd29ya2Fyb3VuZCBmb3IgbW9iaWxlIGJyb3dzZXJzIHdoZXJlIHZpZGVvIHBsYXliYWNrIG5lZWRzIHRvIGJlIHRyaWdnZXJlZCBkaXJlY3RseVxyXG4gICAgICAgICAgICAvLyBieSB0aGUgdXNlci4gQSBkZWZlcnJlZCBwbGF5YmFjayBzdGFydCB0aHJvdWdoIHRoZSB0aW1lb3V0IGJlbG93IGlzIG5vdCBjb25zaWRlcmVkIGFzIHVzZXIgYWN0aW9uIGFuZFxyXG4gICAgICAgICAgICAvLyB0aGVyZWZvcmUgaWdub3JlZCBieSBtb2JpbGUgYnJvd3NlcnMuXHJcbiAgICAgICAgICAgIGlmIChmaXJzdFBsYXkpIHtcclxuICAgICAgICAgICAgICAgIC8vIFRyeSB0byBzdGFydCBwbGF5YmFjay4gVGhlbiB3ZSB3YWl0IGZvciBPTl9QTEFZIGFuZCBvbmx5IHdoZW4gaXQgYXJyaXZlcywgd2UgZGlzYWJsZSB0aGUgZmlyc3RQbGF5IGZsYWcuXHJcbiAgICAgICAgICAgICAgICAvLyBJZiB3ZSBkaXNhYmxlIHRoZSBmbGFnIGhlcmUsIG9uQ2xpY2sgd2FzIHRyaWdnZXJlZCBwcm9ncmFtbWF0aWNhbGx5IGluc3RlYWQgb2YgYnkgYSB1c2VyIGludGVyYWN0aW9uLCBhbmRcclxuICAgICAgICAgICAgICAgIC8vIHBsYXliYWNrIGlzIGJsb2NrZWQgKGUuZy4gb24gbW9iaWxlIGRldmljZXMgZHVlIHRvIHRoZSBwcm9ncmFtbWF0aWMgcGxheSgpIGNhbGwpLCB3ZSBsb29zZSB0aGUgY2hhbmNlIHRvXHJcbiAgICAgICAgICAgICAgICAvLyBldmVyIHN0YXJ0IHBsYXliYWNrIHRocm91Z2ggYSB1c2VyIGludGVyYWN0aW9uIGFnYWluIHdpdGggdGhpcyBidXR0b24uXHJcbiAgICAgICAgICAgICAgICB0b2dnbGVQbGF5YmFjaygpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciBub3cgPSBEYXRlLm5vdygpO1xyXG4gICAgICAgICAgICBpZiAobm93IC0gY2xpY2tUaW1lIDwgMjAwKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBXZSBoYXZlIGEgZG91YmxlIGNsaWNrIGluc2lkZSB0aGUgMjAwbXMgaW50ZXJ2YWwsIGp1c3QgdG9nZ2xlIGZ1bGxzY3JlZW4gbW9kZVxyXG4gICAgICAgICAgICAgICAgdG9nZ2xlRnVsbHNjcmVlbigpO1xyXG4gICAgICAgICAgICAgICAgZG91YmxlQ2xpY2tUaW1lID0gbm93O1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2UgaWYgKG5vdyAtIGNsaWNrVGltZSA8IDUwMCkge1xyXG4gICAgICAgICAgICAgICAgLy8gV2UgaGF2ZSBhIGRvdWJsZSBjbGljayBpbnNpZGUgdGhlIDUwMG1zIGludGVydmFsLCB1bmRvIHBsYXliYWNrIHRvZ2dsZSBhbmQgdG9nZ2xlIGZ1bGxzY3JlZW4gbW9kZVxyXG4gICAgICAgICAgICAgICAgdG9nZ2xlRnVsbHNjcmVlbigpO1xyXG4gICAgICAgICAgICAgICAgdG9nZ2xlUGxheWJhY2soKTtcclxuICAgICAgICAgICAgICAgIGRvdWJsZUNsaWNrVGltZSA9IG5vdztcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjbGlja1RpbWUgPSBub3c7XHJcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKERhdGUubm93KCkgLSBkb3VibGVDbGlja1RpbWUgPiAyMDApIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBObyBkb3VibGUgY2xpY2sgZGV0ZWN0ZWQsIHNvIHdlIHRvZ2dsZSBwbGF5YmFjayBhbmQgd2FpdCB3aGF0IGhhcHBlbnMgbmV4dFxyXG4gICAgICAgICAgICAgICAgICAgIHRvZ2dsZVBsYXliYWNrKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sIDIwMCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUExBWSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvLyBQbGF5YmFjayBoYXMgcmVhbGx5IHN0YXJ0ZWQsIHdlIGNhbiBkaXNhYmxlIHRoZSBmbGFnIHRvIHN3aXRjaCB0byBub3JtYWwgdG9nZ2xlIGJ1dHRvbiBoYW5kbGluZ1xyXG4gICAgICAgICAgICBmaXJzdFBsYXkgPSBmYWxzZTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBIaWRlIGJ1dHRvbiB3aGlsZSBpbml0aWFsaXppbmcgYSBDYXN0IHNlc3Npb25cclxuICAgICAgICB2YXIgY2FzdEluaXRpYWxpemF0aW9uSGFuZGxlciA9IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICBpZiAoZXZlbnQudHlwZSA9PT0gcGxheWVyLkVWRU5ULk9OX0NBU1RfU1RBUlQpIHtcclxuICAgICAgICAgICAgICAgIC8vIEhpZGUgYnV0dG9uIHdoZW4gc2Vzc2lvbiBpcyBiZWluZyBpbml0aWFsaXplZFxyXG4gICAgICAgICAgICAgICAgX3RoaXMuaGlkZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gU2hvdyBidXR0b24gd2hlbiBzZXNzaW9uIGlzIGVzdGFibGlzaGVkIG9yIGluaXRpYWxpemF0aW9uIHdhcyBhYm9ydGVkXHJcbiAgICAgICAgICAgICAgICBfdGhpcy5zaG93KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0NBU1RfU1RBUlQsIGNhc3RJbml0aWFsaXphdGlvbkhhbmRsZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0NBU1RfU1RBUlRFRCwgY2FzdEluaXRpYWxpemF0aW9uSGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fQ0FTVF9TVE9QUEVELCBjYXN0SW5pdGlhbGl6YXRpb25IYW5kbGVyKTtcclxuICAgIH07XHJcbiAgICBIdWdlUGxheWJhY2tUb2dnbGVCdXR0b24ucHJvdG90eXBlLnRvRG9tRWxlbWVudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgYnV0dG9uRWxlbWVudCA9IF9zdXBlci5wcm90b3R5cGUudG9Eb21FbGVtZW50LmNhbGwodGhpcyk7XHJcbiAgICAgICAgLy8gQWRkIGNoaWxkIHRoYXQgY29udGFpbnMgdGhlIHBsYXkgYnV0dG9uIGltYWdlXHJcbiAgICAgICAgLy8gU2V0dGluZyB0aGUgaW1hZ2UgZGlyZWN0bHkgb24gdGhlIGJ1dHRvbiBkb2VzIG5vdCB3b3JrIHRvZ2V0aGVyIHdpdGggc2NhbGluZyBhbmltYXRpb25zLCBiZWNhdXNlIHRoZSBidXR0b25cclxuICAgICAgICAvLyBjYW4gY292ZXIgdGhlIHdob2xlIHZpZGVvIHBsYXllciBhcmUgYW5kIHNjYWxpbmcgd291bGQgZXh0ZW5kIGl0IGJleW9uZC4gQnkgYWRkaW5nIGFuIGlubmVyIGVsZW1lbnQsIGNvbmZpbmVkXHJcbiAgICAgICAgLy8gdG8gdGhlIHNpemUgaWYgdGhlIGltYWdlLCBpdCBjYW4gc2NhbGUgaW5zaWRlIHRoZSBwbGF5ZXIgd2l0aG91dCBvdmVyc2hvb3RpbmcuXHJcbiAgICAgICAgYnV0dG9uRWxlbWVudC5hcHBlbmQobmV3IGRvbV8xLkRPTSgnZGl2Jywge1xyXG4gICAgICAgICAgICAnY2xhc3MnOiB0aGlzLnByZWZpeENzcygnaW1hZ2UnKSxcclxuICAgICAgICB9KSk7XHJcbiAgICAgICAgcmV0dXJuIGJ1dHRvbkVsZW1lbnQ7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIEh1Z2VQbGF5YmFja1RvZ2dsZUJ1dHRvbjtcclxufShwbGF5YmFja3RvZ2dsZWJ1dHRvbl8xLlBsYXliYWNrVG9nZ2xlQnV0dG9uKSk7XHJcbmV4cG9ydHMuSHVnZVBsYXliYWNrVG9nZ2xlQnV0dG9uID0gSHVnZVBsYXliYWNrVG9nZ2xlQnV0dG9uO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvaHVnZXBsYXliYWNrdG9nZ2xlYnV0dG9uLnRzXG4vLyBtb2R1bGUgaWQgPSAyOFxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGNvbnRhaW5lcl8xID0gcmVxdWlyZShcIi4vY29udGFpbmVyXCIpO1xyXG52YXIgY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRcIik7XHJcbi8vIGltcG9ydCBQbGF5ZXJFdmVudCA9IGJpdG1vdmluLlBsYXllckFQSS5QbGF5ZXJFdmVudDtcclxuLyoqXHJcbiAqIE92ZXJsYXlzIHRoZSBwbGF5ZXIgYW5kIGRpc3BsYXlzIGFuIGF1ZGlvLW9ubHkgaW5kaWNhdG9yLlxyXG4gKi9cclxudmFyIEF1ZGlvT25seU92ZXJsYXkgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKEF1ZGlvT25seU92ZXJsYXksIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBBdWRpb09ubHlPdmVybGF5KGNvbmZpZykge1xyXG4gICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5hdWRpb29ubHkgPSBbXHJcbiAgICAgICAgICAgIG5ldyBjb21wb25lbnRfMS5Db21wb25lbnQoeyB0YWc6ICdkaXYnLCBjc3NDbGFzczogJ3VpLWF1ZGlvb25seS1vdmVybGF5LWluZGljYXRvcicgfSksXHJcbiAgICAgICAgXTtcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1hdWRpb29ubHktb3ZlcmxheScsXHJcbiAgICAgICAgICAgIGNvbXBvbmVudHM6IF90aGlzLmF1ZGlvb25seSxcclxuICAgICAgICAgICAgaGlkZGVuOiBmYWxzZSxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIEF1ZGlvT25seU92ZXJsYXkucHJvdG90eXBlLmNvbmZpZ3VyZSA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY29uZmlndXJlLmNhbGwodGhpcywgcGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICB2YXIgaW1hZ2UgPSBzZWxmLmdldERvbUVsZW1lbnQoKS5jc3MoJ2JhY2tncm91bmQtaW1hZ2UnKTtcclxuICAgICAgICAvLyBIaWRlIG92ZXJsYXkgd2hlbiBQbGF5ZXIgaXMgcGF1c2VkLCBzbyB3ZSBjYW4gc2VlIHRoZSBCaWcgUGxheSBCdXR0b25cclxuICAgICAgICAvLyBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9QQVVTRUQsIChldmVudCkgPT4ge1xyXG4gICAgICAgIC8vICAgc2VsZi5nZXREb21FbGVtZW50KCkuY3NzKCdiYWNrZ3JvdW5kLWltYWdlJywgJ25vbmUnKTtcclxuICAgICAgICAvLyB9KTtcclxuICAgICAgICAvL1xyXG4gICAgICAgIC8vIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BMQVksIChldmVudCkgPT4ge1xyXG4gICAgICAgIC8vICAgc2VsZi5nZXREb21FbGVtZW50KCkuY3NzKCdiYWNrZ3JvdW5kLWltYWdlJywgaW1hZ2UpO1xyXG4gICAgICAgIC8vIH0pO1xyXG4gICAgICAgIC8vXHJcbiAgICAgICAgLy8gLy8gSGlkZSBvdmVybGF5IGlmIHBsYXllciBpcyAgcGF1c2VkIGF0IGluaXQgKGUuZy4gb24gbW9iaWxlIGRldmljZXMpXHJcbiAgICAgICAgLy8gaWYgKCFwbGF5ZXIuaXNQbGF5aW5nKCkpIHtcclxuICAgICAgICAvLyAgIHNlbGYuZ2V0RG9tRWxlbWVudCgpLmNzcygnYmFja2dyb3VuZC1pbWFnZScsICdub25lJyk7XHJcbiAgICAgICAgLy8gfVxyXG4gICAgfTtcclxuICAgIHJldHVybiBBdWRpb09ubHlPdmVybGF5O1xyXG59KGNvbnRhaW5lcl8xLkNvbnRhaW5lcikpO1xyXG5leHBvcnRzLkF1ZGlvT25seU92ZXJsYXkgPSBBdWRpb09ubHlPdmVybGF5O1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvYXVkaW9vbmx5b3ZlcmxheS50c1xuLy8gbW9kdWxlIGlkID0gMjlcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGFuZ3VsYXIgPSByZXF1aXJlKFwiYW5ndWxhclwiKTtcclxudmFyIGJpdGRhc2hfY29udHJvbGxlcl8xID0gcmVxdWlyZShcIi4vYml0ZGFzaC1jb250cm9sbGVyXCIpO1xyXG52YXIgYml0ZGFzaF9kaXJlY3RpdmVfMSA9IHJlcXVpcmUoXCIuL2JpdGRhc2gtZGlyZWN0aXZlXCIpO1xyXG5leHBvcnRzLmRlZmF1bHQgPSBhbmd1bGFyLm1vZHVsZSgnbWkuQml0ZGFzaFBsYXllcicsIFtdKVxyXG4gICAgLmNvbnRyb2xsZXIoJ01pQml0ZGFzaENvbnRyb2xsZXInLCBiaXRkYXNoX2NvbnRyb2xsZXJfMS5kZWZhdWx0KVxyXG4gICAgLmRpcmVjdGl2ZSgnbWlCaXRkYXNoUGxheWVyJywgYml0ZGFzaF9kaXJlY3RpdmVfMS5kZWZhdWx0KTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9pbmRleC50c1xuLy8gbW9kdWxlIGlkID0gMzFcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGFuZ3VsYXIgPSByZXF1aXJlKFwiYW5ndWxhclwiKTtcclxudmFyIEJpdG1vdmluQ29udHJvbGxlciA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBCaXRtb3ZpbkNvbnRyb2xsZXIoJHNjb3BlLCAkbG9nKSB7XHJcbiAgICAgICAgdGhpcy4kc2NvcGUgPSAkc2NvcGU7XHJcbiAgICAgICAgdGhpcy4kbG9nID0gJGxvZztcclxuICAgICAgICB0aGlzLnN0YXRlID0ge307XHJcbiAgICAgICAgdGhpcy5jb25maWcgPSB7fTtcclxuICAgICAgICB0aGlzLm9wdGlvbnMgPSB7fTtcclxuICAgIH1cclxuICAgIEJpdG1vdmluQ29udHJvbGxlci5wcm90b3R5cGUuJG9uSW5pdCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLnN0YXRlID0gdGhpcy4kc2NvcGUuc3RhdGUgPSB7fTtcclxuICAgICAgICBpZiAoYW5ndWxhci5pc0RlZmluZWQodGhpcy4kc2NvcGUuY29uZmlnKSAmJiBhbmd1bGFyLmlzRGVmaW5lZCh0aGlzLiRzY29wZS5jb25maWcua2V5KSkge1xyXG4gICAgICAgICAgICB0aGlzLmNvbmZpZyA9IHRoaXMuJHNjb3BlLmNvbmZpZztcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuJGxvZy5lcnJvcihcImJhc2ljIGNvbmZpZyBmb3IgYml0ZGFzaCBwbGF5ZXIgaXMgbWlzc2luZyFcIik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChhbmd1bGFyLmlzRGVmaW5lZCh0aGlzLiRzY29wZS5vcHRpb25zKSkge1xyXG4gICAgICAgICAgICB0aGlzLm9wdGlvbnMgPSB0aGlzLiRzY29wZS5vcHRpb25zO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYW5ndWxhci5pc0RlZmluZWQodGhpcy4kc2NvcGUud2ViY2FzdCkpIHtcclxuICAgICAgICAgICAgdGhpcy5wcm9jZXNzV2ViY2FzdCh0aGlzLiRzY29wZS53ZWJjYXN0KTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgQml0bW92aW5Db250cm9sbGVyLnByb3RvdHlwZS5wcm9jZXNzV2ViY2FzdCA9IGZ1bmN0aW9uICh3ZWJjYXN0KSB7XHJcbiAgICAgICAgdmFyIHN0YXRlUHJvcGVydHkgPSB3ZWJjYXN0LnN0YXRlICsgXCJTdGF0ZURhdGFcIjtcclxuICAgICAgICBpZiAoYW5ndWxhci5pc0RlZmluZWQodGhpcy5vcHRpb25zLmZvcmNlZFN0YXRlKSkge1xyXG4gICAgICAgICAgICBzdGF0ZVByb3BlcnR5ID0gdGhpcy5vcHRpb25zLmZvcmNlZFN0YXRlICsgXCJTdGF0ZURhdGFcIjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHdlYmNhc3Quc3RhdGUgPT09ICdvbmRlbWFuZCcpIHtcclxuICAgICAgICAgICAgdmFyIGxhbmd1YWdlSW5kZXhfMSA9IDA7XHJcbiAgICAgICAgICAgIHdlYmNhc3QubGFuZ3VhZ2VzLnNvbWUoZnVuY3Rpb24gKGxhbmcsIGluZGV4KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAod2ViY2FzdC5sYW5ndWFnZSA9PT0gbGFuZy5sYW5ndWFnZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxhbmd1YWdlSW5kZXhfMSA9IGluZGV4O1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy5zdGF0ZS5kYXRhID0gd2ViY2FzdC5sYW5ndWFnZXNbbGFuZ3VhZ2VJbmRleF8xXS5vbmRlbWFuZFN0YXRlRGF0YTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3RhdGUuZGF0YSA9IHdlYmNhc3Rbc3RhdGVQcm9wZXJ0eV07XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuY29uZmlnLnNvdXJjZSA9IHRoaXMuZ2V0UGxheWVyQ29uZmlnU291cmNlKHdlYmNhc3QpO1xyXG4gICAgICAgIHRoaXMuY29uZmlnLnN0eWxlID0geyB1eDogZmFsc2UgfTtcclxuICAgIH07XHJcbiAgICBCaXRtb3ZpbkNvbnRyb2xsZXIucHJvdG90eXBlLmdldFBsYXllckNvbmZpZ1NvdXJjZSA9IGZ1bmN0aW9uICh3ZWJjYXN0KSB7XHJcbiAgICAgICAgcmV0dXJuIHdlYmNhc3QudXNlRFZSUGxheWJhY2tJblBvc3RsaXZlICYmIHdlYmNhc3Quc3RhdGUgPT09ICdwb3N0bGl2ZScgP1xyXG4gICAgICAgICAgICB0aGlzLmdldERWUlBsYXliYWNrVG9Qb3N0bGl2ZSh3ZWJjYXN0KVxyXG4gICAgICAgICAgICA6IHRoaXMuZ2V0UGxheWVyQ29uZmlnU291cmNlQnlTdGF0ZSh3ZWJjYXN0KTtcclxuICAgIH07XHJcbiAgICBCaXRtb3ZpbkNvbnRyb2xsZXIucHJvdG90eXBlLmdldERWUlBsYXliYWNrVG9Qb3N0bGl2ZSA9IGZ1bmN0aW9uICh3ZWJjYXN0KSB7XHJcbiAgICAgICAgdmFyIGhscyA9IHdlYmNhc3RbJ2xpdmVTdGF0ZURhdGEnXS5wbGF5b3V0Lmhsc0R2clVybDtcclxuICAgICAgICB2YXIgdGl0bGUgPSB3ZWJjYXN0Lm5hbWU7XHJcbiAgICAgICAgaWYgKGFuZ3VsYXIuaXNEZWZpbmVkKHdlYmNhc3RbJ3Bvc3RsaXZlU3RhdGVEYXRhJ10ucGxheW91dC5vZmZzZXQpKSB7XHJcbiAgICAgICAgICAgIHZhciBvZmZzZXQgPSBwYXJzZUludCh3ZWJjYXN0Wydwb3N0bGl2ZVN0YXRlRGF0YSddLnBsYXlvdXQub2Zmc2V0LCAxMCk7XHJcbiAgICAgICAgICAgIGlmIChvZmZzZXQpIHtcclxuICAgICAgICAgICAgICAgIHZhciBvZmZzZXRQcmVmaXggPSB2b2lkIDA7XHJcbiAgICAgICAgICAgICAgICB2YXIgcGFyc2VyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnYScpO1xyXG4gICAgICAgICAgICAgICAgcGFyc2VyLmhyZWYgPSB3ZWJjYXN0WydsaXZlU3RhdGVEYXRhJ10ucGxheW91dC5obHNEdnJVcmw7XHJcbiAgICAgICAgICAgICAgICBvZmZzZXRQcmVmaXggPSAocGFyc2VyLnNlYXJjaCkgPyAnJicgOiAnPyc7XHJcbiAgICAgICAgICAgICAgICBobHMgKz0gb2Zmc2V0UHJlZml4ICsgXCJ3b3d6YWR2cnBsYXlsaXN0c3RhcnQ9XCIgKyBvZmZzZXQgKyBcIjAwMFwiO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB7IGhsczogaGxzLCB0aXRsZTogdGl0bGUgfTtcclxuICAgIH07XHJcbiAgICBCaXRtb3ZpbkNvbnRyb2xsZXIucHJvdG90eXBlLmdldFBsYXllckNvbmZpZ1NvdXJjZUJ5U3RhdGUgPSBmdW5jdGlvbiAod2ViY2FzdCkge1xyXG4gICAgICAgIHZhciBobHMgPSB0aGlzLnN0YXRlLmRhdGEucGxheW91dC5obHNVcmw7XHJcbiAgICAgICAgdmFyIHRpdGxlID0gd2ViY2FzdC5uYW1lO1xyXG4gICAgICAgIHZhciBoaXZlU2VydmljZVVybCA9IHRoaXMuZ2V0SGl2ZVNlcnZpY2VVcmxCeUxhbmcod2ViY2FzdCk7XHJcbiAgICAgICAgaWYgKGFuZ3VsYXIuaXNEZWZpbmVkKHRoaXMuc3RhdGUuZGF0YS5wbGF5b3V0LnZpZGVvTWFuYWdlckhsc1VybCkgJiYgdGhpcy5zdGF0ZS5kYXRhLnBsYXlvdXQudmlkZW9NYW5hZ2VySGxzVXJsKSB7XHJcbiAgICAgICAgICAgIGhscyA9IHRoaXMuc3RhdGUuZGF0YS5wbGF5b3V0LnZpZGVvTWFuYWdlckhsc1VybDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGFuZ3VsYXIuaXNEZWZpbmVkKHRoaXMuc3RhdGUuZGF0YS5wbGF5b3V0Lm9mZnNldCkpIHtcclxuICAgICAgICAgICAgdmFyIG9mZnNldCA9IHBhcnNlSW50KHRoaXMuc3RhdGUuZGF0YS5wbGF5b3V0Lm9mZnNldCwgMTApO1xyXG4gICAgICAgICAgICBpZiAob2Zmc2V0ID4gMCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIG9mZnNldFByZWZpeCA9IHZvaWQgMDtcclxuICAgICAgICAgICAgICAgIHZhciBwYXJzZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdhJyk7XHJcbiAgICAgICAgICAgICAgICBwYXJzZXIuaHJlZiA9IGhscztcclxuICAgICAgICAgICAgICAgIG9mZnNldFByZWZpeCA9IChwYXJzZXIuc2VhcmNoKSA/ICcmJyA6ICc/JztcclxuICAgICAgICAgICAgICAgIGhscyArPSBvZmZzZXRQcmVmaXggKyBcInN0YXJ0PVwiICsgb2Zmc2V0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiB7IGhsczogaGxzLCB0aXRsZTogdGl0bGUsIGhpdmVTZXJ2aWNlVXJsOiBoaXZlU2VydmljZVVybCB9O1xyXG4gICAgfTtcclxuICAgIEJpdG1vdmluQ29udHJvbGxlci5wcm90b3R5cGUuZ2V0SGl2ZVNlcnZpY2VVcmxCeUxhbmcgPSBmdW5jdGlvbiAod2ViY2FzdCkge1xyXG4gICAgICAgIHZhciBoaXZlU2VydmljZVVybCA9IG51bGw7XHJcbiAgICAgICAgaWYgKHdlYmNhc3QubGFuZ3VhZ2VzICYmIHdlYmNhc3QubGFuZ3VhZ2UpIHtcclxuICAgICAgICAgICAgd2ViY2FzdC5sYW5ndWFnZXMuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGl0ZW0ubGFuZ3VhZ2UgPT09IHdlYmNhc3QubGFuZ3VhZ2UpIHtcclxuICAgICAgICAgICAgICAgICAgICBoaXZlU2VydmljZVVybCA9IGFuZ3VsYXIuY29weShpdGVtLmhpdmVTZXJ2aWNlVXJsKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBoaXZlU2VydmljZVVybDtcclxuICAgIH07XHJcbiAgICByZXR1cm4gQml0bW92aW5Db250cm9sbGVyO1xyXG59KCkpO1xyXG5CaXRtb3ZpbkNvbnRyb2xsZXIuJGluamVjdCA9IFsnJHNjb3BlJywgJyRsb2cnXTtcclxuZXhwb3J0cy5kZWZhdWx0ID0gQml0bW92aW5Db250cm9sbGVyO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuL2JpdGRhc2gtY29udHJvbGxlci50c1xuLy8gbW9kdWxlIGlkID0gMzJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGFuZ3VsYXIgPSByZXF1aXJlKFwiYW5ndWxhclwiKTtcclxudmFyIEJpdGRhc2hEaXJlY3RpdmUgPSBmdW5jdGlvbiAoJHdpbmRvdywgJGxvZykgeyByZXR1cm4gKHtcclxuICAgIGNvbnRyb2xsZXI6ICdNaUJpdGRhc2hDb250cm9sbGVyJyxcclxuICAgIGNvbnRyb2xsZXJBczogJ2JpdGRhc2hWbScsXHJcbiAgICByZXBsYWNlOiB0cnVlLFxyXG4gICAgcmVzdHJpY3Q6ICdFQScsXHJcbiAgICBzY29wZToge1xyXG4gICAgICAgIGNvbmZpZzogJz0nLFxyXG4gICAgICAgIG9wdGlvbnM6ICc9PycsXHJcbiAgICAgICAgd2ViY2FzdDogJz0nLFxyXG4gICAgfSxcclxuICAgIHRlbXBsYXRlOiBcIjxkaXYgaWQ9XFxcIm1pLWJpdGRhc2gtcGxheWVyXFxcIiB3aWR0aD1cXFwiMTAwJVxcXCIgaGVpZ2h0PVxcXCJhdXRvXFxcIj48L2Rpdj5cIixcclxuICAgIGxpbms6IGZ1bmN0aW9uIChzY29wZSkge1xyXG4gICAgICAgIHZhciBiaXRtb3ZpblBsYXllcjtcclxuICAgICAgICB2YXIgYml0bW92aW5VSU1hbmFnZXI7XHJcbiAgICAgICAgdmFyIGJpdG1vdmluQ29udHJvbGJhcjtcclxuICAgICAgICB2YXIgY29uZmlnID0gc2NvcGUuY29uZmlnO1xyXG4gICAgICAgIHZhciB3ZWJjYXN0ID0gc2NvcGUud2ViY2FzdDtcclxuICAgICAgICB2YXIgc3RhdGVEYXRhID0gc2NvcGUuc3RhdGUuZGF0YTtcclxuICAgICAgICBidWlsZFBsYXllcigpO1xyXG4gICAgICAgIGZ1bmN0aW9uIGJ1aWxkUGxheWVyKCkge1xyXG4gICAgICAgICAgICBiaXRtb3ZpblBsYXllciA9ICR3aW5kb3cud2luZG93LmJpdG1vdmluLnBsYXllcignbWktYml0ZGFzaC1wbGF5ZXInKTtcclxuICAgICAgICAgICAgaWYgKGFuZ3VsYXIuaXNEZWZpbmVkKGJpdG1vdmluUGxheWVyKSAmJiBiaXRtb3ZpblBsYXllci5pc1JlYWR5KCkgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgICAgIGJpdG1vdmluUGxheWVyLmRlc3Ryb3koKTtcclxuICAgICAgICAgICAgICAgIGJpdG1vdmluUGxheWVyID0gJHdpbmRvdy53aW5kb3cuYml0bW92aW4ucGxheWVyKCdtaS1iaXRkYXNoLXBsYXllcicpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICgod2ViY2FzdC5zdGF0ZSA9PT0gJ2xpdmUnKSAmJiBjb25maWcuc291cmNlLmhpdmVTZXJ2aWNlVXJsKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBHZXQgYSBoaXZlLWVuYWJsZWQgcGxheWVyIHRocm91Z2ggYml0ZGFzaC5pbml0SGl2ZVNETlxyXG4gICAgICAgICAgICAgICAgJHdpbmRvdy53aW5kb3cuYml0bW92aW4uaW5pdEhpdmVTRE4oYml0bW92aW5QbGF5ZXIsIHsgZGVidWdMZXZlbDogJ29mZicgfSk7XHJcbiAgICAgICAgICAgICAgICAvLyBDb25maWd1cmUgYW5kIFNldHVwIGJpdG1vdmluIGluIGluaXRTZXNzaW9uIGNhbGxiYWNrXHJcbiAgICAgICAgICAgICAgICBiaXRtb3ZpblBsYXllci5pbml0U2Vzc2lvbihjb25maWcuc291cmNlLmhpdmVTZXJ2aWNlVXJsKS50aGVuKGZ1bmN0aW9uIChzZXNzaW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGhpdmVDb25maWcgPSBhbmd1bGFyLmNvcHkoY29uZmlnKTtcclxuICAgICAgICAgICAgICAgICAgICBoaXZlQ29uZmlnLnNvdXJjZS5obHMgPSBzZXNzaW9uLm1hbmlmZXN0O1xyXG4gICAgICAgICAgICAgICAgICAgIGxvYWRQbGF5ZXIoaGl2ZUNvbmZpZyk7XHJcbiAgICAgICAgICAgICAgICB9LCBmdW5jdGlvbiAocmVhc29uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gSGFuZGxlIHRoZSBjYXNlIGlmIEhpdmUgaW5pdCBmYWlsc1xyXG4gICAgICAgICAgICAgICAgICAgICRsb2cud2FybihcIkhpdmUgaW5pdCBmYWlsczogXCIgKyByZWFzb24uY29kZSArIFwiIC0gXCIgKyByZWFzb24ubWVzc2FnZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgbG9hZFBsYXllcihjb25maWcpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBsb2FkUGxheWVyKGNvbmZpZyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgZnVuY3Rpb24gbG9hZFBsYXllcihjb25mKSB7XHJcbiAgICAgICAgICAgIGJpdG1vdmluUGxheWVyXHJcbiAgICAgICAgICAgICAgICAuc2V0dXAoY29uZilcclxuICAgICAgICAgICAgICAgIC50aGVuKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGJpdG1vdmluVUlNYW5hZ2VyID0gJHdpbmRvdy53aW5kb3cuYml0bW92aW4ucGxheWVydWkuVUlNYW5hZ2VyLkZhY3Rvcnk7XHJcbiAgICAgICAgICAgICAgICBpZiAoaXNBdWRpb09ubHkoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGJpdG1vdmluVUlNYW5hZ2VyLmJ1aWxkQXVkaW9Pbmx5VUkoYml0bW92aW5QbGF5ZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNldEF1ZGlvT25seVN0aWxsSW1hZ2UoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGJpdG1vdmluVUlNYW5hZ2VyLmJ1aWxkQXVkaW9WaWRlb1VJKGJpdG1vdmluUGxheWVyKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGJpdG1vdmluQ29udHJvbGJhciA9IGdldEVsZW1lbnRzQnlDbGFzc05hbWUoJ2JpdG1vdmlucGxheWVyLWNvbnRhaW5lcicpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGFuZ3VsYXIuaXNEZWZpbmVkKGJpdG1vdmluQ29udHJvbGJhcikpIHtcclxuICAgICAgICAgICAgICAgICAgICBiaXRtb3ZpbkNvbnRyb2xiYXIuc3R5bGUubWluV2lkdGggPSAnMTc1cHgnO1xyXG4gICAgICAgICAgICAgICAgICAgIGJpdG1vdmluQ29udHJvbGJhci5zdHlsZS5taW5IZWlnaHQgPSAnMTAxcHgnO1xyXG4gICAgICAgICAgICAgICAgICAgIGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdiaXRtb3ZpbnBsYXllci12aWRlby1taS1iaXRkYXNoLXBsYXllcicpLnNldEF0dHJpYnV0ZSgndGl0bGUnLCB3ZWJjYXN0Lm5hbWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAocmVhc29uKSB7XHJcbiAgICAgICAgICAgICAgICAkbG9nLmxvZyhcIkVycm9yOiBcIiArIHJlYXNvbi5jb2RlICsgXCIgLSBcIiArIHJlYXNvbi5tZXNzYWdlKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIGlzQXVkaW9Pbmx5KCkge1xyXG4gICAgICAgICAgICByZXR1cm4gYW5ndWxhci5pc0RlZmluZWQoc3RhdGVEYXRhLnBsYXlvdXQuYXVkaW9Pbmx5KSAmJlxyXG4gICAgICAgICAgICAgICAgc3RhdGVEYXRhLnBsYXlvdXQuYXVkaW9Pbmx5O1xyXG4gICAgICAgIH1cclxuICAgICAgICBmdW5jdGlvbiBzZXRBdWRpb09ubHlTdGlsbEltYWdlKCkge1xyXG4gICAgICAgICAgICBpZiAoYW5ndWxhci5pc0RlZmluZWQoc3RhdGVEYXRhLnBsYXlvdXQuYXVkaW9Pbmx5U3RpbGxVcmwpICYmXHJcbiAgICAgICAgICAgICAgICBzdGF0ZURhdGEucGxheW91dC5hdWRpb09ubHlTdGlsbFVybCAhPT0gJycpIHtcclxuICAgICAgICAgICAgICAgIHZhciBlbGVtZW50ID0gZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSgnbWktd2JjLXVpLWF1ZGlvb25seS1vdmVybGF5Jyk7XHJcbiAgICAgICAgICAgICAgICBlbGVtZW50LnN0eWxlLmJhY2tncm91bmRJbWFnZSA9IFwidXJsKFwiICsgc3RhdGVEYXRhLnBsYXlvdXQuYXVkaW9Pbmx5U3RpbGxVcmwgKyBcIilcIjtcclxuICAgICAgICAgICAgICAgIGVsZW1lbnQuc3R5bGUuYmFja2dyb3VuZFNpemUgPSAnY29udGFpbic7XHJcbiAgICAgICAgICAgICAgICBlbGVtZW50LnN0eWxlLmJhY2tncm91bmRQb3NpdGlvbiA9ICdjZW50ZXInO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZ1bmN0aW9uIGdldEVsZW1lbnRzQnlDbGFzc05hbWUoY2xhc3NOYW1lKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBkb2N1bWVudC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKGNsYXNzTmFtZSlbMF07XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG59KTsgfTtcclxuZXhwb3J0cy5kZWZhdWx0ID0gQml0ZGFzaERpcmVjdGl2ZTtcclxuQml0ZGFzaERpcmVjdGl2ZS4kaW5qZWN0ID0gWyckd2luZG93JywgJyRsb2cnXTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi9iaXRkYXNoLWRpcmVjdGl2ZS50c1xuLy8gbW9kdWxlIGlkID0gMzNcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxuLy8vIDxyZWZlcmVuY2UgcGF0aD0ncGxheWVyLmQudHMnIC8+XHJcbnZhciB1aW1hbmFnZXJfMSA9IHJlcXVpcmUoXCIuL3VpbWFuYWdlclwiKTtcclxudmFyIGJ1dHRvbl8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9idXR0b25cIik7XHJcbnZhciBjb250cm9sYmFyXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL2NvbnRyb2xiYXJcIik7XHJcbnZhciBodWdlcGxheWJhY2t0b2dnbGVidXR0b25fMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvaHVnZXBsYXliYWNrdG9nZ2xlYnV0dG9uXCIpO1xyXG52YXIgcGxheWJhY2t0aW1lbGFiZWxfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvcGxheWJhY2t0aW1lbGFiZWxcIik7XHJcbnZhciBwbGF5YmFja3RvZ2dsZWJ1dHRvbl8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9wbGF5YmFja3RvZ2dsZWJ1dHRvblwiKTtcclxudmFyIHNlZWtiYXJfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvc2Vla2JhclwiKTtcclxudmFyIHNlbGVjdGJveF8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9zZWxlY3Rib3hcIik7XHJcbnZhciBpdGVtc2VsZWN0aW9ubGlzdF8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9pdGVtc2VsZWN0aW9ubGlzdFwiKTtcclxuLy8gaW1wb3J0IHtTZXR0aW5nc1BhbmVsLCBTZXR0aW5nc1BhbmVsSXRlbX0gZnJvbSAnLi9jb21wb25lbnRzL3NldHRpbmdzcGFuZWwnO1xyXG4vLyBpbXBvcnQge1NldHRpbmdzVG9nZ2xlQnV0dG9ufSBmcm9tICcuL2NvbXBvbmVudHMvc2V0dGluZ3N0b2dnbGVidXR0b24nO1xyXG52YXIgdG9nZ2xlYnV0dG9uXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL3RvZ2dsZWJ1dHRvblwiKTtcclxuLy8gaW1wb3J0IHtWaWRlb1F1YWxpdHlTZWxlY3RCb3h9IGZyb20gJy4vY29tcG9uZW50cy92aWRlb3F1YWxpdHlzZWxlY3Rib3gnO1xyXG52YXIgdm9sdW1ldG9nZ2xlYnV0dG9uXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL3ZvbHVtZXRvZ2dsZWJ1dHRvblwiKTtcclxuLy8gaW1wb3J0IHtXYXRlcm1hcmt9IGZyb20gJy4vY29tcG9uZW50cy93YXRlcm1hcmsnO1xyXG52YXIgdWljb250YWluZXJfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvdWljb250YWluZXJcIik7XHJcbnZhciBjb250YWluZXJfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvY29udGFpbmVyXCIpO1xyXG52YXIgbGFiZWxfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvbGFiZWxcIik7XHJcbnZhciBjb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvY29tcG9uZW50XCIpO1xyXG52YXIgZXJyb3JtZXNzYWdlb3ZlcmxheV8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9lcnJvcm1lc3NhZ2VvdmVybGF5XCIpO1xyXG52YXIgc2Vla2JhcmxhYmVsXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL3NlZWtiYXJsYWJlbFwiKTtcclxuLy8gaW1wb3J0IHtUaXRsZUJhcn0gZnJvbSAnLi9jb21wb25lbnRzL3RpdGxlYmFyJztcclxudmFyIHZvbHVtZWNvbnRyb2xidXR0b25fMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvdm9sdW1lY29udHJvbGJ1dHRvblwiKTtcclxudmFyIGNsaWNrb3ZlcmxheV8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9jbGlja292ZXJsYXlcIik7XHJcbnZhciBodWdlcmVwbGF5YnV0dG9uXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL2h1Z2VyZXBsYXlidXR0b25cIik7XHJcbi8vIGltcG9ydCB7QnVmZmVyaW5nT3ZlcmxheX0gZnJvbSAnLi9jb21wb25lbnRzL2J1ZmZlcmluZ292ZXJsYXknO1xyXG52YXIgcGxheWJhY2t0b2dnbGVvdmVybGF5XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL3BsYXliYWNrdG9nZ2xlb3ZlcmxheVwiKTtcclxudmFyIGNsb3NlYnV0dG9uXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL2Nsb3NlYnV0dG9uXCIpO1xyXG4vLyBpbXBvcnQge01ldGFkYXRhTGFiZWwsIE1ldGFkYXRhTGFiZWxDb250ZW50fSBmcm9tICcuL2NvbXBvbmVudHMvbWV0YWRhdGFsYWJlbCc7XHJcbnZhciB2b2x1bWVzbGlkZXJfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvdm9sdW1lc2xpZGVyXCIpO1xyXG52YXIgc3BhY2VyXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL3NwYWNlclwiKTtcclxudmFyIGFycmF5dXRpbHNfMSA9IHJlcXVpcmUoXCIuL2FycmF5dXRpbHNcIik7XHJcbnZhciBzdHJpbmd1dGlsc18xID0gcmVxdWlyZShcIi4vc3RyaW5ndXRpbHNcIik7XHJcbnZhciBwbGF5ZXJ1dGlsc18xID0gcmVxdWlyZShcIi4vcGxheWVydXRpbHNcIik7XHJcbnZhciB1aXV0aWxzXzEgPSByZXF1aXJlKFwiLi91aXV0aWxzXCIpO1xyXG52YXIgYnJvd3NlcnV0aWxzXzEgPSByZXF1aXJlKFwiLi9icm93c2VydXRpbHNcIik7XHJcbnZhciBzdG9yYWdldXRpbHNfMSA9IHJlcXVpcmUoXCIuL3N0b3JhZ2V1dGlsc1wiKTtcclxudmFyIGF1ZGlvb25seW92ZXJsYXlfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvYXVkaW9vbmx5b3ZlcmxheVwiKTtcclxuLy8gT2JqZWN0LmFzc2lnbiBwb2x5ZmlsbCBmb3IgRVM1L0lFOVxyXG4vLyBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9kZS9kb2NzL1dlYi9KYXZhU2NyaXB0L1JlZmVyZW5jZS9HbG9iYWxfT2JqZWN0cy9PYmplY3QvYXNzaWduXHJcbmlmICh0eXBlb2YgT2JqZWN0LmFzc2lnbiAhPT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgT2JqZWN0LmFzc2lnbiA9IGZ1bmN0aW9uICh0YXJnZXQpIHtcclxuICAgICAgICAndXNlIHN0cmljdCc7XHJcbiAgICAgICAgaWYgKHRhcmdldCA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoJ0Nhbm5vdCBjb252ZXJ0IHVuZGVmaW5lZCBvciBudWxsIHRvIG9iamVjdCcpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0YXJnZXQgPSBPYmplY3QodGFyZ2V0KTtcclxuICAgICAgICBmb3IgKHZhciBpbmRleCA9IDE7IGluZGV4IDwgYXJndW1lbnRzLmxlbmd0aDsgaW5kZXgrKykge1xyXG4gICAgICAgICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2luZGV4XTtcclxuICAgICAgICAgICAgaWYgKHNvdXJjZSAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHRhcmdldDtcclxuICAgIH07XHJcbn1cclxudmFyIHBsYXllcnVpID0ge1xyXG4gICAgdmVyc2lvbjogJ3t7VkVSU0lPTn19JyxcclxuICAgIC8vIE1hbmFnZW1lbnRcclxuICAgIFVJTWFuYWdlcjogdWltYW5hZ2VyXzEuVUlNYW5hZ2VyLFxyXG4gICAgVUlJbnN0YW5jZU1hbmFnZXI6IHVpbWFuYWdlcl8xLlVJSW5zdGFuY2VNYW5hZ2VyLFxyXG4gICAgLy8gVXRpbHNcclxuICAgIEFycmF5VXRpbHM6IGFycmF5dXRpbHNfMS5BcnJheVV0aWxzLFxyXG4gICAgU3RyaW5nVXRpbHM6IHN0cmluZ3V0aWxzXzEuU3RyaW5nVXRpbHMsXHJcbiAgICBQbGF5ZXJVdGlsczogcGxheWVydXRpbHNfMS5QbGF5ZXJVdGlscyxcclxuICAgIFVJVXRpbHM6IHVpdXRpbHNfMS5VSVV0aWxzLFxyXG4gICAgQnJvd3NlclV0aWxzOiBicm93c2VydXRpbHNfMS5Ccm93c2VyVXRpbHMsXHJcbiAgICBTdG9yYWdlVXRpbHM6IHN0b3JhZ2V1dGlsc18xLlN0b3JhZ2VVdGlscyxcclxuICAgIC8vIENvbXBvbmVudHNcclxuICAgIEF1ZGlvT25seU92ZXJsYXk6IGF1ZGlvb25seW92ZXJsYXlfMS5BdWRpb09ubHlPdmVybGF5LFxyXG4gICAgLy8gQnVmZmVyaW5nT3ZlcmxheSxcclxuICAgIEJ1dHRvbjogYnV0dG9uXzEuQnV0dG9uLFxyXG4gICAgQ2xpY2tPdmVybGF5OiBjbGlja292ZXJsYXlfMS5DbGlja092ZXJsYXksXHJcbiAgICBDbG9zZUJ1dHRvbjogY2xvc2VidXR0b25fMS5DbG9zZUJ1dHRvbixcclxuICAgIENvbXBvbmVudDogY29tcG9uZW50XzEuQ29tcG9uZW50LFxyXG4gICAgQ29udGFpbmVyOiBjb250YWluZXJfMS5Db250YWluZXIsXHJcbiAgICBDb250cm9sQmFyOiBjb250cm9sYmFyXzEuQ29udHJvbEJhcixcclxuICAgIEVycm9yTWVzc2FnZU92ZXJsYXk6IGVycm9ybWVzc2FnZW92ZXJsYXlfMS5FcnJvck1lc3NhZ2VPdmVybGF5LFxyXG4gICAgSHVnZVBsYXliYWNrVG9nZ2xlQnV0dG9uOiBodWdlcGxheWJhY2t0b2dnbGVidXR0b25fMS5IdWdlUGxheWJhY2tUb2dnbGVCdXR0b24sXHJcbiAgICBIdWdlUmVwbGF5QnV0dG9uOiBodWdlcmVwbGF5YnV0dG9uXzEuSHVnZVJlcGxheUJ1dHRvbixcclxuICAgIExhYmVsOiBsYWJlbF8xLkxhYmVsLFxyXG4gICAgLy8gTWV0YWRhdGFMYWJlbCxcclxuICAgIC8vIE1ldGFkYXRhTGFiZWxDb250ZW50LFxyXG4gICAgUGxheWJhY2tUaW1lTGFiZWw6IHBsYXliYWNrdGltZWxhYmVsXzEuUGxheWJhY2tUaW1lTGFiZWwsXHJcbiAgICBQbGF5YmFja1RpbWVMYWJlbE1vZGU6IHBsYXliYWNrdGltZWxhYmVsXzEuUGxheWJhY2tUaW1lTGFiZWxNb2RlLFxyXG4gICAgUGxheWJhY2tUb2dnbGVCdXR0b246IHBsYXliYWNrdG9nZ2xlYnV0dG9uXzEuUGxheWJhY2tUb2dnbGVCdXR0b24sXHJcbiAgICBQbGF5YmFja1RvZ2dsZU92ZXJsYXk6IHBsYXliYWNrdG9nZ2xlb3ZlcmxheV8xLlBsYXliYWNrVG9nZ2xlT3ZlcmxheSxcclxuICAgIFNlZWtCYXI6IHNlZWtiYXJfMS5TZWVrQmFyLFxyXG4gICAgU2Vla0JhckxhYmVsOiBzZWVrYmFybGFiZWxfMS5TZWVrQmFyTGFiZWwsXHJcbiAgICBTZWxlY3RCb3g6IHNlbGVjdGJveF8xLlNlbGVjdEJveCxcclxuICAgIEl0ZW1TZWxlY3Rpb25MaXN0OiBpdGVtc2VsZWN0aW9ubGlzdF8xLkl0ZW1TZWxlY3Rpb25MaXN0LFxyXG4gICAgLy8gU2V0dGluZ3NQYW5lbCxcclxuICAgIC8vIFNldHRpbmdzUGFuZWxJdGVtLFxyXG4gICAgLy8gU2V0dGluZ3NUb2dnbGVCdXR0b24sXHJcbiAgICBTcGFjZXI6IHNwYWNlcl8xLlNwYWNlcixcclxuICAgIC8vIFRpdGxlQmFyLFxyXG4gICAgVG9nZ2xlQnV0dG9uOiB0b2dnbGVidXR0b25fMS5Ub2dnbGVCdXR0b24sXHJcbiAgICBVSUNvbnRhaW5lcjogdWljb250YWluZXJfMS5VSUNvbnRhaW5lcixcclxuICAgIC8vIFZpZGVvUXVhbGl0eVNlbGVjdEJveCxcclxuICAgIFZvbHVtZUNvbnRyb2xCdXR0b246IHZvbHVtZWNvbnRyb2xidXR0b25fMS5Wb2x1bWVDb250cm9sQnV0dG9uLFxyXG4gICAgVm9sdW1lU2xpZGVyOiB2b2x1bWVzbGlkZXJfMS5Wb2x1bWVTbGlkZXIsXHJcbiAgICBWb2x1bWVUb2dnbGVCdXR0b246IHZvbHVtZXRvZ2dsZWJ1dHRvbl8xLlZvbHVtZVRvZ2dsZUJ1dHRvbixcclxufTtcclxud2luZG93LmJpdG1vdmluLnBsYXllcnVpID0gcGxheWVydWk7XHJcbm1vZHVsZS5leHBvcnRzID0gcGxheWVydWk7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvbWFpbi50c1xuLy8gbW9kdWxlIGlkID0gMzRcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciB1aWNvbnRhaW5lcl8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy91aWNvbnRhaW5lclwiKTtcclxudmFyIGRvbV8xID0gcmVxdWlyZShcIi4vZG9tXCIpO1xyXG52YXIgY29tcG9uZW50XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL2NvbXBvbmVudFwiKTtcclxudmFyIGNvbnRhaW5lcl8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9jb250YWluZXJcIik7XHJcbnZhciBwbGF5YmFja3RvZ2dsZWJ1dHRvbl8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9wbGF5YmFja3RvZ2dsZWJ1dHRvblwiKTtcclxudmFyIGZ1bGxzY3JlZW50b2dnbGVidXR0b25fMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvZnVsbHNjcmVlbnRvZ2dsZWJ1dHRvblwiKTtcclxuLy8gaW1wb3J0IHtWUlRvZ2dsZUJ1dHRvbn0gZnJvbSAnLi9jb21wb25lbnRzL3ZydG9nZ2xlYnV0dG9uJztcclxuLy8gaW1wb3J0IHtWb2x1bWVUb2dnbGVCdXR0b259IGZyb20gJy4vY29tcG9uZW50cy92b2x1bWV0b2dnbGVidXR0b24nO1xyXG52YXIgc2Vla2Jhcl8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9zZWVrYmFyXCIpO1xyXG52YXIgcGxheWJhY2t0aW1lbGFiZWxfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvcGxheWJhY2t0aW1lbGFiZWxcIik7IC8vICwgUGxheWJhY2tUaW1lTGFiZWxNb2RlXHJcbnZhciBjb250cm9sYmFyXzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL2NvbnRyb2xiYXJcIik7XHJcbnZhciBldmVudGRpc3BhdGNoZXJfMSA9IHJlcXVpcmUoXCIuL2V2ZW50ZGlzcGF0Y2hlclwiKTtcclxuLy8gaW1wb3J0IHtTZXR0aW5nc1RvZ2dsZUJ1dHRvbn0gZnJvbSAnLi9jb21wb25lbnRzL3NldHRpbmdzdG9nZ2xlYnV0dG9uJztcclxuLy8gaW1wb3J0IHtTZXR0aW5nc1BhbmVsLCBTZXR0aW5nc1BhbmVsSXRlbX0gZnJvbSAnLi9jb21wb25lbnRzL3NldHRpbmdzcGFuZWwnO1xyXG4vLyBpbXBvcnQge1ZpZGVvUXVhbGl0eVNlbGVjdEJveH0gZnJvbSAnLi9jb21wb25lbnRzL3ZpZGVvcXVhbGl0eXNlbGVjdGJveCc7XHJcbi8vIGltcG9ydCB7V2F0ZXJtYXJrfSBmcm9tICcuL2NvbXBvbmVudHMvd2F0ZXJtYXJrJztcclxuLy8gaW1wb3J0IHtBdWRpb1F1YWxpdHlTZWxlY3RCb3h9IGZyb20gJy4vY29tcG9uZW50cy9hdWRpb3F1YWxpdHlzZWxlY3Rib3gnO1xyXG4vLyBpbXBvcnQge0F1ZGlvVHJhY2tTZWxlY3RCb3h9IGZyb20gJy4vY29tcG9uZW50cy9hdWRpb3RyYWNrc2VsZWN0Ym94JztcclxudmFyIHNlZWtiYXJsYWJlbF8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9zZWVrYmFybGFiZWxcIik7XHJcbi8vIGltcG9ydCB7Vm9sdW1lU2xpZGVyfSBmcm9tICcuL2NvbXBvbmVudHMvdm9sdW1lc2xpZGVyJztcclxudmFyIHN1YnRpdGxlc2VsZWN0Ym94XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL3N1YnRpdGxlc2VsZWN0Ym94XCIpO1xyXG52YXIgc3VidGl0bGVvdmVybGF5XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL3N1YnRpdGxlb3ZlcmxheVwiKTtcclxudmFyIHZvbHVtZWNvbnRyb2xidXR0b25fMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvdm9sdW1lY29udHJvbGJ1dHRvblwiKTtcclxuLy8gaW1wb3J0IHtDYXN0VG9nZ2xlQnV0dG9ufSBmcm9tICcuL2NvbXBvbmVudHMvY2FzdHRvZ2dsZWJ1dHRvbic7XHJcbi8vIGltcG9ydCB7Q2FzdFN0YXR1c092ZXJsYXl9IGZyb20gJy4vY29tcG9uZW50cy9jYXN0c3RhdHVzb3ZlcmxheSc7XHJcbnZhciBlcnJvcm1lc3NhZ2VvdmVybGF5XzEgPSByZXF1aXJlKFwiLi9jb21wb25lbnRzL2Vycm9ybWVzc2FnZW92ZXJsYXlcIik7XHJcbi8vIGltcG9ydCB7UGxheWJhY2tTcGVlZFNlbGVjdEJveH0gZnJvbSAnLi9jb21wb25lbnRzL3BsYXliYWNrc3BlZWRzZWxlY3Rib3gnO1xyXG4vLyBpbXBvcnQge0J1ZmZlcmluZ092ZXJsYXl9IGZyb20gJy4vY29tcG9uZW50cy9idWZmZXJpbmdvdmVybGF5JztcclxudmFyIHBsYXliYWNrdG9nZ2xlb3ZlcmxheV8xID0gcmVxdWlyZShcIi4vY29tcG9uZW50cy9wbGF5YmFja3RvZ2dsZW92ZXJsYXlcIik7XHJcbi8vIGltcG9ydCB7QWlyUGxheVRvZ2dsZUJ1dHRvbn0gZnJvbSAnLi9jb21wb25lbnRzL2FpcnBsYXl0b2dnbGVidXR0b24nO1xyXG4vLyBpbXBvcnQge1BpY3R1cmVJblBpY3R1cmVUb2dnbGVCdXR0b259IGZyb20gJy4vY29tcG9uZW50cy9waWN0dXJlaW5waWN0dXJldG9nZ2xlYnV0dG9uJztcclxudmFyIGF1ZGlvb25seW92ZXJsYXlfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudHMvYXVkaW9vbmx5b3ZlcmxheVwiKTtcclxuLy8gaW1wb3J0IHtTcGFjZXJ9IGZyb20gJy4vY29tcG9uZW50cy9zcGFjZXInO1xyXG52YXIgdWl1dGlsc18xID0gcmVxdWlyZShcIi4vdWl1dGlsc1wiKTtcclxudmFyIGFycmF5dXRpbHNfMSA9IHJlcXVpcmUoXCIuL2FycmF5dXRpbHNcIik7XHJcbnZhciBicm93c2VydXRpbHNfMSA9IHJlcXVpcmUoXCIuL2Jyb3dzZXJ1dGlsc1wiKTtcclxudmFyIFVJTWFuYWdlciA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBVSU1hbmFnZXIocGxheWVyLCBwbGF5ZXJVaU9yVWlWYXJpYW50cywgY29uZmlnKSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICBpZiAocGxheWVyVWlPclVpVmFyaWFudHMgaW5zdGFuY2VvZiB1aWNvbnRhaW5lcl8xLlVJQ29udGFpbmVyKSB7XHJcbiAgICAgICAgICAgIC8vIFNpbmdsZS1VSSBjb25zdHJ1Y3RvciBoYXMgYmVlbiBjYWxsZWQsIHRyYW5zZm9ybSBhcmd1bWVudHMgdG8gVUlWYXJpYW50W10gc2lnbmF0dXJlXHJcbiAgICAgICAgICAgIHZhciBwbGF5ZXJVaSA9IHBsYXllclVpT3JVaVZhcmlhbnRzO1xyXG4gICAgICAgICAgICB2YXIgYWRzVWkgPSBudWxsO1xyXG4gICAgICAgICAgICB2YXIgdWlWYXJpYW50cyA9IFtdO1xyXG4gICAgICAgICAgICAvLyBBZGQgdGhlIGFkcyBVSSBpZiBkZWZpbmVkXHJcbiAgICAgICAgICAgIGlmIChhZHNVaSkge1xyXG4gICAgICAgICAgICAgICAgdWlWYXJpYW50cy5wdXNoKHtcclxuICAgICAgICAgICAgICAgICAgICB1aTogYWRzVWksXHJcbiAgICAgICAgICAgICAgICAgICAgY29uZGl0aW9uOiBmdW5jdGlvbiAoY29udGV4dCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gY29udGV4dC5pc0FkV2l0aFVJO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBBZGQgdGhlIGRlZmF1bHQgcGxheWVyIFVJXHJcbiAgICAgICAgICAgIHVpVmFyaWFudHMucHVzaCh7IHVpOiBwbGF5ZXJVaSB9KTtcclxuICAgICAgICAgICAgdGhpcy51aVZhcmlhbnRzID0gdWlWYXJpYW50cztcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIERlZmF1bHQgY29uc3RydWN0b3IgKFVJVmFyaWFudFtdKSBoYXMgYmVlbiBjYWxsZWRcclxuICAgICAgICAgICAgdGhpcy51aVZhcmlhbnRzID0gcGxheWVyVWlPclVpVmFyaWFudHM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMucGxheWVyID0gcGxheWVyO1xyXG4gICAgICAgIHRoaXMuY29uZmlnID0gY29uZmlnO1xyXG4gICAgICAgIHRoaXMubWFuYWdlclBsYXllcldyYXBwZXIgPSBuZXcgUGxheWVyV3JhcHBlcihwbGF5ZXIpO1xyXG4gICAgICAgIGlmIChjb25maWcuY29udGFpbmVyKSB7XHJcbiAgICAgICAgICAgIC8vIFVuZm9ydHVuYXRlbHkgXCJ1aUNvbnRhaW5lckVsZW1lbnQgPSBuZXcgRE9NKGNvbmZpZy5jb250YWluZXIpXCIgd2lsbCBub3QgYWNjZXB0IHRoZSBjb250YWluZXIgd2l0aFxyXG4gICAgICAgICAgICAvLyBzdHJpbmd8SFRNTEVsZW1lbnQgdHlwZSBkaXJlY3RseSwgYWx0aG91Z2ggaXQgYWNjZXB0cyBib3RoIHR5cGVzLCBzbyB3ZSBuZWVkIHRvIHNwaXQgdGhlc2UgdHdvIGNhc2VzIHVwIGhlcmUuXHJcbiAgICAgICAgICAgIC8vIFRPRE8gY2hlY2sgaW4gdXBjb21pbmcgVFMgdmVyc2lvbnMgaWYgdGhlIGNvbnRhaW5lciBjYW4gYmUgcGFzc2VkIGluIGRpcmVjdGx5LCBvciBmaXggdGhlIGNvbnN0cnVjdG9yXHJcbiAgICAgICAgICAgIHRoaXMudWlDb250YWluZXJFbGVtZW50ID0gY29uZmlnLmNvbnRhaW5lciBpbnN0YW5jZW9mIEhUTUxFbGVtZW50ID9cclxuICAgICAgICAgICAgICAgIG5ldyBkb21fMS5ET00oY29uZmlnLmNvbnRhaW5lcikgOiBuZXcgZG9tXzEuRE9NKGNvbmZpZy5jb250YWluZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy51aUNvbnRhaW5lckVsZW1lbnQgPSBuZXcgZG9tXzEuRE9NKHBsYXllci5nZXRGaWd1cmUoKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIENyZWF0ZSBVSSBpbnN0YW5jZSBtYW5hZ2VycyBmb3IgdGhlIFVJIHZhcmlhbnRzXHJcbiAgICAgICAgLy8gVGhlIGluc3RhbmNlIG1hbmFnZXJzIG1hcCB0byB0aGUgY29ycmVzcG9uZGluZyBVSSB2YXJpYW50cyBieSB0aGVpciBhcnJheSBpbmRleFxyXG4gICAgICAgIHRoaXMudWlJbnN0YW5jZU1hbmFnZXJzID0gW107XHJcbiAgICAgICAgdmFyIHVpVmFyaWFudHNXaXRob3V0Q29uZGl0aW9uID0gW107XHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMudWlWYXJpYW50czsgX2kgPCBfYS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgdmFyIHVpVmFyaWFudCA9IF9hW19pXTtcclxuICAgICAgICAgICAgaWYgKHVpVmFyaWFudC5jb25kaXRpb24gPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgLy8gQ29sbGVjdCB2YXJpYW50cyB3aXRob3V0IGNvbmRpdGlvbnMgZm9yIGVycm9yIGNoZWNraW5nXHJcbiAgICAgICAgICAgICAgICB1aVZhcmlhbnRzV2l0aG91dENvbmRpdGlvbi5wdXNoKHVpVmFyaWFudCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gQ3JlYXRlIHRoZSBpbnN0YW5jZSBtYW5hZ2VyIGZvciBhIFVJIHZhcmlhbnRcclxuICAgICAgICAgICAgdGhpcy51aUluc3RhbmNlTWFuYWdlcnMucHVzaChuZXcgSW50ZXJuYWxVSUluc3RhbmNlTWFuYWdlcihwbGF5ZXIsIHVpVmFyaWFudC51aSwgdGhpcy5jb25maWcpKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgdGhlcmUgaXMgb25seSBvbmUgVUkgdmFyaWFudCB3aXRob3V0IGEgY29uZGl0aW9uXHJcbiAgICAgICAgLy8gSXQgZG9lcyBub3QgbWFrZSBzZW5zZSB0byBoYXZlIG11bHRpcGxlIHZhcmlhbnRzIHdpdGhvdXQgY29uZGl0aW9uLCBiZWNhdXNlIG9ubHkgdGhlIGZpcnN0IG9uZSBpbiB0aGUgbGlzdFxyXG4gICAgICAgIC8vICh0aGUgb25lIHdpdGggdGhlIGxvd2VzdCBpbmRleCkgd2lsbCBldmVyIGJlIHNlbGVjdGVkLlxyXG4gICAgICAgIGlmICh1aVZhcmlhbnRzV2l0aG91dENvbmRpdGlvbi5sZW5ndGggPiAxKSB7XHJcbiAgICAgICAgICAgIHRocm93IEVycm9yKCdUb28gbWFueSBVSXMgd2l0aG91dCBhIGNvbmRpdGlvbjogWW91IGNhbm5vdCBoYXZlIG1vcmUgdGhhbiBvbmUgZGVmYXVsdCBVSScpO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgZGVmYXVsdCBVSSB2YXJpYW50LCBpZiBkZWZpbmVkLCBpcyBhdCB0aGUgZW5kIG9mIHRoZSBsaXN0IChsYXN0IGluZGV4KVxyXG4gICAgICAgIC8vIElmIGl0IGNvbWVzIGVhcmxpZXIsIHRoZSB2YXJpYW50cyB3aXRoIGNvbmRpdGlvbnMgdGhhdCBjb21lIGFmdGVyd2FyZHMgd2lsbCBuZXZlciBiZSBzZWxlY3RlZCBiZWNhdXNlIHRoZVxyXG4gICAgICAgIC8vIGRlZmF1bHQgdmFyaWFudCB3aXRob3V0IGEgY29uZGl0aW9uIGFsd2F5cyBldmFsdWF0ZXMgdG8gJ3RydWUnXHJcbiAgICAgICAgaWYgKHVpVmFyaWFudHNXaXRob3V0Q29uZGl0aW9uLmxlbmd0aCA+IDBcclxuICAgICAgICAgICAgJiYgdWlWYXJpYW50c1dpdGhvdXRDb25kaXRpb25bMF0gIT09IHRoaXMudWlWYXJpYW50c1t0aGlzLnVpVmFyaWFudHMubGVuZ3RoIC0gMV0pIHtcclxuICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ0ludmFsaWQgVUkgdmFyaWFudCBvcmRlcjogdGhlIGRlZmF1bHQgVUkgKHdpdGhvdXQgY29uZGl0aW9uKSBtdXN0IGJlIGF0IHRoZSBlbmQgb2YgdGhlIGxpc3QnKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIGFkU3RhcnRlZEV2ZW50ID0gbnVsbDsgLy8ga2VlcCB0aGUgZXZlbnQgc3RvcmVkIGhlcmUgZHVyaW5nIGFkIHBsYXliYWNrXHJcbiAgICAgICAgdmFyIGlzTW9iaWxlID0gYnJvd3NlcnV0aWxzXzEuQnJvd3NlclV0aWxzLmlzTW9iaWxlO1xyXG4gICAgICAgIC8vIER5bmFtaWNhbGx5IHNlbGVjdCBhIFVJIHZhcmlhbnQgdGhhdCBtYXRjaGVzIHRoZSBjdXJyZW50IFVJIGNvbmRpdGlvbi5cclxuICAgICAgICB2YXIgcmVzb2x2ZVVpVmFyaWFudCA9IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgICAgICAvLyBNYWtlIHN1cmUgdGhhdCB0aGUgT05fQURfU1RBUlRFRCBldmVudCBkYXRhIGlzIHBlcnNpc3RlZCB0aHJvdWdoIGFkIHBsYXliYWNrIGluIGNhc2Ugb3RoZXIgZXZlbnRzIGhhcHBlblxyXG4gICAgICAgICAgICAvLyBpbiB0aGUgbWVhbnRpbWUsIGUuZy4gcGxheWVyIHJlc2l6ZS4gV2UgbmVlZCB0byBzdG9yZSB0aGlzIGRhdGEgYmVjYXVzZSB0aGVyZSBpcyBubyBvdGhlciB3YXkgdG8gZmluZCBvdXRcclxuICAgICAgICAgICAgLy8gYWQgZGV0YWlscyAoZS5nLiB0aGUgYWQgY2xpZW50KSB3aGlsZSBhbiBhZCBpcyBwbGF5aW5nLlxyXG4gICAgICAgICAgICAvLyBFeGlzdGluZyBldmVudCBkYXRhIHNpZ25hbHMgdGhhdCBhbiBhZCBpcyBjdXJyZW50bHkgYWN0aXZlLiBXZSBjYW5ub3QgdXNlIHBsYXllci5pc0FkKCkgYmVjYXVzZSBpdCByZXR1cm5zXHJcbiAgICAgICAgICAgIC8vIHRydWUgb24gYWQgc3RhcnQgYW5kIGFsc28gb24gYWQgZW5kIGV2ZW50cywgd2hpY2ggaXMgcHJvYmxlbWF0aWMuXHJcbiAgICAgICAgICAgIGlmIChldmVudCAhPSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIHRoZSBhZCBzdGFydHMsIHdlIHN0b3JlIHRoZSBldmVudCBkYXRhXHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBwbGF5ZXIuRVZFTlQuT05fQURfU1RBUlRFRDpcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRTdGFydGVkRXZlbnQgPSBldmVudDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gV2hlbiB0aGUgYWQgZW5kcywgd2UgZGVsZXRlIHRoZSBldmVudCBkYXRhXHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBwbGF5ZXIuRVZFTlQuT05fQURfRklOSVNIRUQ6XHJcbiAgICAgICAgICAgICAgICAgICAgY2FzZSBwbGF5ZXIuRVZFTlQuT05fQURfU0tJUFBFRDpcclxuICAgICAgICAgICAgICAgICAgICBjYXNlIHBsYXllci5FVkVOVC5PTl9BRF9FUlJPUjpcclxuICAgICAgICAgICAgICAgICAgICAgICAgYWRTdGFydGVkRXZlbnQgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAvLyBXaGVuIGEgbmV3IHNvdXJjZSBpcyBsb2FkZWQgZHVyaW5nIGFkIHBsYXliYWNrLCB0aGVyZSB3aWxsIGJlIG5vIGFkIGVuZCBldmVudCBzbyB3ZSBkZXRlY3QgdGhlIGVuZFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIG9mIHRoZSBhZCBwbGF5YmFjayBieSBjaGVja2luZyBpc0FkKCkgaW4gT05fUkVBRFksIGJlY2F1c2UgT05fUkVBRFkgYWx3YXlzIGFycml2ZXMgd2hlbiB0aGUgc291cmNlXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gY2hhbmdlcy5cclxuICAgICAgICAgICAgICAgICAgICBjYXNlIHBsYXllci5FVkVOVC5PTl9SRUFEWTpcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFkU3RhcnRlZEV2ZW50ICYmICFwbGF5ZXIuaXNBZCgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZFN0YXJ0ZWRFdmVudCA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBEZXRlY3QgaWYgYW4gYWQgaGFzIHN0YXJ0ZWRcclxuICAgICAgICAgICAgdmFyIGFkID0gYWRTdGFydGVkRXZlbnQgIT0gbnVsbDtcclxuICAgICAgICAgICAgdmFyIGFkV2l0aFVJID0gYWQgJiYgYWRTdGFydGVkRXZlbnQuY2xpZW50VHlwZSA9PT0gJ3Zhc3QnO1xyXG4gICAgICAgICAgICAvLyBEZXRlcm1pbmUgdGhlIGN1cnJlbnQgY29udGV4dCBmb3Igd2hpY2ggdGhlIFVJIHZhcmlhbnQgd2lsbCBiZSByZXNvbHZlZFxyXG4gICAgICAgICAgICB2YXIgY29udGV4dCA9IHtcclxuICAgICAgICAgICAgICAgIGlzQWQ6IGFkLFxyXG4gICAgICAgICAgICAgICAgaXNBZFdpdGhVSTogYWRXaXRoVUksXHJcbiAgICAgICAgICAgICAgICBhZENsaWVudFR5cGU6IGFkID8gYWRTdGFydGVkRXZlbnQuY2xpZW50VHlwZSA6IG51bGwsXHJcbiAgICAgICAgICAgICAgICBpc0Z1bGxzY3JlZW46IF90aGlzLnBsYXllci5pc0Z1bGxzY3JlZW4oKSxcclxuICAgICAgICAgICAgICAgIGlzTW9iaWxlOiBpc01vYmlsZSxcclxuICAgICAgICAgICAgICAgIGlzUGxheWluZzogX3RoaXMucGxheWVyLmlzUGxheWluZygpLFxyXG4gICAgICAgICAgICAgICAgd2lkdGg6IF90aGlzLnVpQ29udGFpbmVyRWxlbWVudC53aWR0aCgpLFxyXG4gICAgICAgICAgICAgICAgZG9jdW1lbnRXaWR0aDogZG9jdW1lbnQuYm9keS5jbGllbnRXaWR0aCxcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgdmFyIG5leHRVaSA9IG51bGw7XHJcbiAgICAgICAgICAgIHZhciB1aVZhcmlhbnRDaGFuZ2VkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIC8vIFNlbGVjdCBuZXcgVUkgdmFyaWFudFxyXG4gICAgICAgICAgICAvLyBJZiBubyB2YXJpYW50IGNvbmRpdGlvbiBpcyBmdWxmaWxsZWQsIHdlIHN3aXRjaCB0byAqbm8qIFVJXHJcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSBfdGhpcy51aVZhcmlhbnRzOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICAgICAgdmFyIHVpVmFyaWFudCA9IF9hW19pXTtcclxuICAgICAgICAgICAgICAgIGlmICh1aVZhcmlhbnQuY29uZGl0aW9uID09IG51bGwgfHwgdWlWYXJpYW50LmNvbmRpdGlvbihjb250ZXh0KSA9PT0gdHJ1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIG5leHRVaSA9IF90aGlzLnVpSW5zdGFuY2VNYW5hZ2Vyc1tfdGhpcy51aVZhcmlhbnRzLmluZGV4T2YodWlWYXJpYW50KV07XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gRGV0ZXJtaW5lIGlmIHRoZSBVSSB2YXJpYW50IGlzIGNoYW5naW5nXHJcbiAgICAgICAgICAgIGlmIChuZXh0VWkgIT09IF90aGlzLmN1cnJlbnRVaSkge1xyXG4gICAgICAgICAgICAgICAgdWlWYXJpYW50Q2hhbmdlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnc3dpdGNoZWQgZnJvbSAnLCB0aGlzLmN1cnJlbnRVaSA/IHRoaXMuY3VycmVudFVpLmdldFVJKCkgOiAnbm9uZScsXHJcbiAgICAgICAgICAgICAgICAvLyAgICcgdG8gJywgbmV4dFVpID8gbmV4dFVpLmdldFVJKCkgOiAnbm9uZScpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIE9ubHkgaWYgdGhlIFVJIHZhcmlhbnQgaXMgY2hhbmdpbmcsIHdlIG5lZWQgdG8gZG8gc29tZSBzdHVmZi4gRWxzZSB3ZSBqdXN0IGxlYXZlIGV2ZXJ5dGhpbmcgYXMtaXMuXHJcbiAgICAgICAgICAgIGlmICh1aVZhcmlhbnRDaGFuZ2VkKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBIaWRlIHRoZSBjdXJyZW50bHkgYWN0aXZlIFVJIHZhcmlhbnRcclxuICAgICAgICAgICAgICAgIGlmIChfdGhpcy5jdXJyZW50VWkpIHtcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy5jdXJyZW50VWkuZ2V0VUkoKS5oaWRlKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBBc3NpZ24gdGhlIG5ldyBVSSB2YXJpYW50IGFzIGN1cnJlbnQgVUlcclxuICAgICAgICAgICAgICAgIF90aGlzLmN1cnJlbnRVaSA9IG5leHRVaTtcclxuICAgICAgICAgICAgICAgIC8vIFdoZW4gd2Ugc3dpdGNoIHRvIGEgZGlmZmVyZW50IFVJIGluc3RhbmNlLCB0aGVyZSdzIHNvbWUgYWRkaXRpb25hbCBzdHVmZiB0byBtYW5hZ2UuIElmIHdlIGRvIG5vdCBzd2l0Y2hcclxuICAgICAgICAgICAgICAgIC8vIHRvIGFuIGluc3RhbmNlLCB3ZSdyZSBkb25lIGhlcmUuXHJcbiAgICAgICAgICAgICAgICBpZiAoX3RoaXMuY3VycmVudFVpICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBBZGQgdGhlIFVJIHRvIHRoZSBET00gKGFuZCBjb25maWd1cmUgaXQpIHRoZSBmaXJzdCB0aW1lIGl0IGlzIHNlbGVjdGVkXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFfdGhpcy5jdXJyZW50VWkuaXNDb25maWd1cmVkKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuYWRkVWkoX3RoaXMuY3VycmVudFVpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gSWYgdGhpcyBpcyBhbiBhZCBVSSwgd2UgbmVlZCB0byByZWxheSB0aGUgc2F2ZWQgT05fQURfU1RBUlRFRCBldmVudCBkYXRhIHNvIGFkIGNvbXBvbmVudHMgY2FuIGNvbmZpZ3VyZVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIHRoZW1zZWx2ZXMgZm9yIHRoZSBjdXJyZW50IGFkLlxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChjb250ZXh0LmlzQWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLyogUmVsYXkgdGhlIE9OX0FEX1NUQVJURUQgZXZlbnQgdG8gdGhlIGFkcyBVSVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgKlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgKiBCZWNhdXNlIHRoZSBhZHMgVUkgaXMgaW5pdGlhbGl6ZWQgaW4gdGhlIE9OX0FEX1NUQVJURUQgaGFuZGxlciwgaS5lLiB3aGVuIHRoZSBPTl9BRF9TVEFSVEVEIGV2ZW50IGhhc1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgKiBhbHJlYWR5IGJlZW4gZmlyZWQsIGNvbXBvbmVudHMgaW4gdGhlIGFkcyBVSSB0aGF0IGxpc3RlbiBmb3IgdGhlIE9OX0FEX1NUQVJURUQgZXZlbnQgbmV2ZXIgcmVjZWl2ZSBpdC5cclxuICAgICAgICAgICAgICAgICAgICAgICAgICogU2luY2UgdGhpcyBjYW4gYnJlYWsgZnVuY3Rpb25hbGl0eSBvZiBjb21wb25lbnRzIHRoYXQgcmVseSBvbiB0aGlzIGV2ZW50LCB3ZSByZWxheSB0aGUgZXZlbnQgdG8gdGhlXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAqIGFkcyBVSSBjb21wb25lbnRzIHdpdGggdGhlIGZvbGxvd2luZyBjYWxsLlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgICAgICAgICAgX3RoaXMuY3VycmVudFVpLmdldFdyYXBwZWRQbGF5ZXIoKS5maXJlRXZlbnRJblVJKF90aGlzLnBsYXllci5FVkVOVC5PTl9BRF9TVEFSVEVELCBhZFN0YXJ0ZWRFdmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIF90aGlzLmN1cnJlbnRVaS5nZXRVSSgpLnNob3coKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgLy8gTGlzdGVuIHRvIHRoZSBmb2xsb3dpbmcgZXZlbnRzIHRvIHRyaWdnZXIgVUkgdmFyaWFudCByZXNvbHV0aW9uXHJcbiAgICAgICAgdGhpcy5tYW5hZ2VyUGxheWVyV3JhcHBlci5nZXRQbGF5ZXIoKS5hZGRFdmVudEhhbmRsZXIodGhpcy5wbGF5ZXIuRVZFTlQuT05fUkVBRFksIHJlc29sdmVVaVZhcmlhbnQpO1xyXG4gICAgICAgIHRoaXMubWFuYWdlclBsYXllcldyYXBwZXIuZ2V0UGxheWVyKCkuYWRkRXZlbnRIYW5kbGVyKHRoaXMucGxheWVyLkVWRU5ULk9OX1BMQVksIHJlc29sdmVVaVZhcmlhbnQpO1xyXG4gICAgICAgIHRoaXMubWFuYWdlclBsYXllcldyYXBwZXIuZ2V0UGxheWVyKCkuYWRkRXZlbnRIYW5kbGVyKHRoaXMucGxheWVyLkVWRU5ULk9OX1BBVVNFRCwgcmVzb2x2ZVVpVmFyaWFudCk7XHJcbiAgICAgICAgdGhpcy5tYW5hZ2VyUGxheWVyV3JhcHBlci5nZXRQbGF5ZXIoKS5hZGRFdmVudEhhbmRsZXIodGhpcy5wbGF5ZXIuRVZFTlQuT05fQURfU1RBUlRFRCwgcmVzb2x2ZVVpVmFyaWFudCk7XHJcbiAgICAgICAgdGhpcy5tYW5hZ2VyUGxheWVyV3JhcHBlci5nZXRQbGF5ZXIoKS5hZGRFdmVudEhhbmRsZXIodGhpcy5wbGF5ZXIuRVZFTlQuT05fQURfRklOSVNIRUQsIHJlc29sdmVVaVZhcmlhbnQpO1xyXG4gICAgICAgIHRoaXMubWFuYWdlclBsYXllcldyYXBwZXIuZ2V0UGxheWVyKCkuYWRkRXZlbnRIYW5kbGVyKHRoaXMucGxheWVyLkVWRU5ULk9OX0FEX1NLSVBQRUQsIHJlc29sdmVVaVZhcmlhbnQpO1xyXG4gICAgICAgIHRoaXMubWFuYWdlclBsYXllcldyYXBwZXIuZ2V0UGxheWVyKCkuYWRkRXZlbnRIYW5kbGVyKHRoaXMucGxheWVyLkVWRU5ULk9OX0FEX0VSUk9SLCByZXNvbHZlVWlWYXJpYW50KTtcclxuICAgICAgICB0aGlzLm1hbmFnZXJQbGF5ZXJXcmFwcGVyLmdldFBsYXllcigpLmFkZEV2ZW50SGFuZGxlcih0aGlzLnBsYXllci5FVkVOVC5PTl9QTEFZRVJfUkVTSVpFLCByZXNvbHZlVWlWYXJpYW50KTtcclxuICAgICAgICB0aGlzLm1hbmFnZXJQbGF5ZXJXcmFwcGVyLmdldFBsYXllcigpLmFkZEV2ZW50SGFuZGxlcih0aGlzLnBsYXllci5FVkVOVC5PTl9GVUxMU0NSRUVOX0VOVEVSLCByZXNvbHZlVWlWYXJpYW50KTtcclxuICAgICAgICB0aGlzLm1hbmFnZXJQbGF5ZXJXcmFwcGVyLmdldFBsYXllcigpLmFkZEV2ZW50SGFuZGxlcih0aGlzLnBsYXllci5FVkVOVC5PTl9GVUxMU0NSRUVOX0VYSVQsIHJlc29sdmVVaVZhcmlhbnQpO1xyXG4gICAgICAgIC8vIEluaXRpYWxpemUgdGhlIFVJXHJcbiAgICAgICAgcmVzb2x2ZVVpVmFyaWFudChudWxsKTtcclxuICAgIH1cclxuICAgIFVJTWFuYWdlci5wcm90b3R5cGUuZ2V0Q29uZmlnID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbmZpZztcclxuICAgIH07XHJcbiAgICBVSU1hbmFnZXIucHJvdG90eXBlLmFkZFVpID0gZnVuY3Rpb24gKHVpKSB7XHJcbiAgICAgICAgdmFyIGRvbSA9IHVpLmdldFVJKCkuZ2V0RG9tRWxlbWVudCgpO1xyXG4gICAgICAgIHZhciBwbGF5ZXIgPSB1aS5nZXRXcmFwcGVkUGxheWVyKCk7XHJcbiAgICAgICAgdWkuY29uZmlndXJlQ29udHJvbHMoKTtcclxuICAgICAgICAvKiBBcHBlbmQgdGhlIFVJIERPTSBhZnRlciBjb25maWd1cmF0aW9uIHRvIGF2b2lkIENTUyB0cmFuc2l0aW9ucyBhdCBpbml0aWFsaXphdGlvblxyXG4gICAgICAgICAqIEV4YW1wbGU6IENvbXBvbmVudHMgYXJlIGhpZGRlbiBkdXJpbmcgY29uZmlndXJhdGlvbiBhbmQgdGhlc2UgaGlkZXMgbWF5IHRyaWdnZXIgQ1NTIHRyYW5zaXRpb25zIHRoYXQgYXJlXHJcbiAgICAgICAgICogdW5kZXNpcmFibGUgYXQgdGhpcyB0aW1lLiAqL1xyXG4gICAgICAgIHRoaXMudWlDb250YWluZXJFbGVtZW50LmFwcGVuZChkb20pO1xyXG4gICAgICAgIC8vIFNvbWUgY29tcG9uZW50cyBpbml0aWFsaXplIHRoZWlyIHN0YXRlIG9uIE9OX1JFQURZLiBXaGVuIHRoZSBVSSBpcyBsb2FkZWQgYWZ0ZXIgdGhlIHBsYXllciBpcyBhbHJlYWR5IHJlYWR5LFxyXG4gICAgICAgIC8vIHRoZXkgd2lsbCBuZXZlciByZWNlaXZlIHRoZSBldmVudCBzbyB3ZSBmaXJlIGl0IGZyb20gaGVyZSBpbiBzdWNoIGNhc2VzLlxyXG4gICAgICAgIGlmIChwbGF5ZXIuaXNSZWFkeSgpKSB7XHJcbiAgICAgICAgICAgIHBsYXllci5maXJlRXZlbnRJblVJKHBsYXllci5FVkVOVC5PTl9SRUFEWSwge30pO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBGaXJlIG9uQ29uZmlndXJlZCBhZnRlciBVSSBET00gZWxlbWVudHMgYXJlIHN1Y2Nlc3NmdWxseSBhZGRlZC4gV2hlbiBmaXJlZCBpbW1lZGlhdGVseSwgdGhlIERPTSBlbGVtZW50c1xyXG4gICAgICAgIC8vIG1pZ2h0IG5vdCBiZSBmdWxseSBjb25maWd1cmVkIGFuZCBlLmcuIGRvIG5vdCBoYXZlIGEgc2l6ZS5cclxuICAgICAgICAvLyBodHRwczovL3N3aXplYy5jb20vYmxvZy9ob3ctdG8tcHJvcGVybHktd2FpdC1mb3ItZG9tLWVsZW1lbnRzLXRvLXNob3ctdXAtaW4tbW9kZXJuLWJyb3dzZXJzL3N3aXplYy82NjYzXHJcbiAgICAgICAgaWYgKHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUpIHtcclxuICAgICAgICAgICAgcmVxdWVzdEFuaW1hdGlvbkZyYW1lKGZ1bmN0aW9uICgpIHsgdWkub25Db25maWd1cmVkLmRpc3BhdGNoKHVpLmdldFVJKCkpOyB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIElFOSBmYWxsYmFja1xyXG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsgdWkub25Db25maWd1cmVkLmRpc3BhdGNoKHVpLmdldFVJKCkpOyB9LCAwKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgVUlNYW5hZ2VyLnByb3RvdHlwZS5yZWxlYXNlVWkgPSBmdW5jdGlvbiAodWkpIHtcclxuICAgICAgICB1aS5yZWxlYXNlQ29udHJvbHMoKTtcclxuICAgICAgICB1aS5nZXRVSSgpLmdldERvbUVsZW1lbnQoKS5yZW1vdmUoKTtcclxuICAgICAgICB1aS5jbGVhckV2ZW50SGFuZGxlcnMoKTtcclxuICAgIH07XHJcbiAgICBVSU1hbmFnZXIucHJvdG90eXBlLnJlbGVhc2UgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBfYSA9IHRoaXMudWlJbnN0YW5jZU1hbmFnZXJzOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICB2YXIgdWlJbnN0YW5jZU1hbmFnZXIgPSBfYVtfaV07XHJcbiAgICAgICAgICAgIHRoaXMucmVsZWFzZVVpKHVpSW5zdGFuY2VNYW5hZ2VyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5tYW5hZ2VyUGxheWVyV3JhcHBlci5jbGVhckV2ZW50SGFuZGxlcnMoKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gVUlNYW5hZ2VyO1xyXG59KCkpO1xyXG5leHBvcnRzLlVJTWFuYWdlciA9IFVJTWFuYWdlcjtcclxuKGZ1bmN0aW9uIChVSU1hbmFnZXIpIHtcclxuICAgIHZhciBGYWN0b3J5O1xyXG4gICAgKGZ1bmN0aW9uIChGYWN0b3J5KSB7XHJcbiAgICAgICAgZnVuY3Rpb24gYnVpbGRBdWRpb1ZpZGVvVUkocGxheWVyLCBjb25maWcpIHtcclxuICAgICAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgICAgIHZhciBjb250cm9sQmFyID0gbmV3IGNvbnRyb2xiYXJfMS5Db250cm9sQmFyKHtcclxuICAgICAgICAgICAgICAgIGNvbXBvbmVudHM6IFtcclxuICAgICAgICAgICAgICAgICAgICBuZXcgcGxheWJhY2t0b2dnbGVidXR0b25fMS5QbGF5YmFja1RvZ2dsZUJ1dHRvbigpLFxyXG4gICAgICAgICAgICAgICAgICAgIG5ldyBzZWVrYmFyXzEuU2Vla0Jhcih7IGxhYmVsOiBuZXcgc2Vla2JhcmxhYmVsXzEuU2Vla0JhckxhYmVsKCkgfSksXHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IHBsYXliYWNrdGltZWxhYmVsXzEuUGxheWJhY2tUaW1lTGFiZWwoKSxcclxuICAgICAgICAgICAgICAgICAgICBuZXcgdm9sdW1lY29udHJvbGJ1dHRvbl8xLlZvbHVtZUNvbnRyb2xCdXR0b24oeyAndmVydGljYWwnOiB0cnVlIH0pLFxyXG4gICAgICAgICAgICAgICAgICAgIG5ldyBmdWxsc2NyZWVudG9nZ2xlYnV0dG9uXzEuRnVsbHNjcmVlblRvZ2dsZUJ1dHRvbigpLFxyXG4gICAgICAgICAgICAgICAgXSxcclxuICAgICAgICAgICAgfSwgdHJ1ZSk7XHJcbiAgICAgICAgICAgIHZhciB1aSA9IG5ldyB1aWNvbnRhaW5lcl8xLlVJQ29udGFpbmVyKHtcclxuICAgICAgICAgICAgICAgIGNvbXBvbmVudHM6IFtcclxuICAgICAgICAgICAgICAgICAgICBuZXcgcGxheWJhY2t0b2dnbGVvdmVybGF5XzEuUGxheWJhY2tUb2dnbGVPdmVybGF5KCksXHJcbiAgICAgICAgICAgICAgICAgICAgY29udHJvbEJhcixcclxuICAgICAgICAgICAgICAgICAgICBuZXcgZXJyb3JtZXNzYWdlb3ZlcmxheV8xLkVycm9yTWVzc2FnZU92ZXJsYXkoKSxcclxuICAgICAgICAgICAgICAgIF0sIGNzc0NsYXNzZXM6IFsndWktc2tpbiddLFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgLy8gSnVzdCBoZXJlIHRvIGF2b2lkIGxpbnRlciBlcnJvcnNcclxuICAgICAgICAgICAgdmFyIHNzQm94ID0gbmV3IHN1YnRpdGxlc2VsZWN0Ym94XzEuU3VidGl0bGVTZWxlY3RCb3goKTtcclxuICAgICAgICAgICAgc3NCb3guaGlkZSgpO1xyXG4gICAgICAgICAgICB2YXIgc3NPdmVybGF5ID0gbmV3IHN1YnRpdGxlb3ZlcmxheV8xLlN1YnRpdGxlT3ZlcmxheSgpO1xyXG4gICAgICAgICAgICBzc092ZXJsYXkuaGlkZSgpO1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IFVJTWFuYWdlcihwbGF5ZXIsIHVpLCBjb25maWcpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBGYWN0b3J5LmJ1aWxkQXVkaW9WaWRlb1VJID0gYnVpbGRBdWRpb1ZpZGVvVUk7XHJcbiAgICAgICAgZnVuY3Rpb24gYnVpbGRBdWRpb09ubHlVSShwbGF5ZXIsIGNvbmZpZykge1xyXG4gICAgICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICAgICAgdmFyIGNvbnRyb2xCYXIgPSBuZXcgY29udHJvbGJhcl8xLkNvbnRyb2xCYXIoe1xyXG4gICAgICAgICAgICAgICAgY29tcG9uZW50czogW1xyXG4gICAgICAgICAgICAgICAgICAgIG5ldyBwbGF5YmFja3RvZ2dsZWJ1dHRvbl8xLlBsYXliYWNrVG9nZ2xlQnV0dG9uKCksXHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IHNlZWtiYXJfMS5TZWVrQmFyKHsgbGFiZWw6IG5ldyBzZWVrYmFybGFiZWxfMS5TZWVrQmFyTGFiZWwoKSwgaGlkZUluTGl2ZVBsYXliYWNrOiB0cnVlIH0pLFxyXG4gICAgICAgICAgICAgICAgICAgIG5ldyBwbGF5YmFja3RpbWVsYWJlbF8xLlBsYXliYWNrVGltZUxhYmVsKCksXHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IHZvbHVtZWNvbnRyb2xidXR0b25fMS5Wb2x1bWVDb250cm9sQnV0dG9uKHsgJ3ZlcnRpY2FsJzogdHJ1ZSB9KSxcclxuICAgICAgICAgICAgICAgICAgICBuZXcgY29tcG9uZW50XzEuQ29tcG9uZW50KHsgY3NzQ2xhc3M6ICdzcGFjZXInIH0pLFxyXG4gICAgICAgICAgICAgICAgXSxcclxuICAgICAgICAgICAgfSwgZmFsc2UpO1xyXG4gICAgICAgICAgICB2YXIgdWkgPSBuZXcgdWljb250YWluZXJfMS5VSUNvbnRhaW5lcih7XHJcbiAgICAgICAgICAgICAgICBjb21wb25lbnRzOiBbXHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IGF1ZGlvb25seW92ZXJsYXlfMS5BdWRpb09ubHlPdmVybGF5KCksXHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IHBsYXliYWNrdG9nZ2xlb3ZlcmxheV8xLlBsYXliYWNrVG9nZ2xlT3ZlcmxheSgpLFxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnRyb2xCYXIsXHJcbiAgICAgICAgICAgICAgICAgICAgbmV3IGVycm9ybWVzc2FnZW92ZXJsYXlfMS5FcnJvck1lc3NhZ2VPdmVybGF5KCksXHJcbiAgICAgICAgICAgICAgICBdLCBjc3NDbGFzc2VzOiBbJ3VpLXNraW4nXSxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgVUlNYW5hZ2VyKHBsYXllciwgdWksIGNvbmZpZyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIEZhY3RvcnkuYnVpbGRBdWRpb09ubHlVSSA9IGJ1aWxkQXVkaW9Pbmx5VUk7XHJcbiAgICB9KShGYWN0b3J5ID0gVUlNYW5hZ2VyLkZhY3RvcnkgfHwgKFVJTWFuYWdlci5GYWN0b3J5ID0ge30pKTtcclxufSkoVUlNYW5hZ2VyID0gZXhwb3J0cy5VSU1hbmFnZXIgfHwgKGV4cG9ydHMuVUlNYW5hZ2VyID0ge30pKTtcclxuZXhwb3J0cy5VSU1hbmFnZXIgPSBVSU1hbmFnZXI7XHJcbi8qKlxyXG4gKiBFbmNhcHN1bGF0ZXMgZnVuY3Rpb25hbGl0eSB0byBtYW5hZ2UgYSBVSSBpbnN0YW5jZS4gVXNlZCBieSB0aGUge0BsaW5rIFVJTWFuYWdlcn0gdG8gbWFuYWdlIG11bHRpcGxlIFVJIGluc3RhbmNlcy5cclxuICovXHJcbnZhciBVSUluc3RhbmNlTWFuYWdlciA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBVSUluc3RhbmNlTWFuYWdlcihwbGF5ZXIsIHVpLCBjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB0aGlzLmV2ZW50cyA9IHtcclxuICAgICAgICAgICAgb25Db25maWd1cmVkOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgICAgIG9uU2VlazogbmV3IGV2ZW50ZGlzcGF0Y2hlcl8xLkV2ZW50RGlzcGF0Y2hlcigpLFxyXG4gICAgICAgICAgICBvblNlZWtQcmV2aWV3OiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgICAgIG9uU2Vla2VkOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgICAgIG9uQ29tcG9uZW50U2hvdzogbmV3IGV2ZW50ZGlzcGF0Y2hlcl8xLkV2ZW50RGlzcGF0Y2hlcigpLFxyXG4gICAgICAgICAgICBvbkNvbXBvbmVudEhpZGU6IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKSxcclxuICAgICAgICAgICAgb25Db250cm9sc1Nob3c6IG5ldyBldmVudGRpc3BhdGNoZXJfMS5FdmVudERpc3BhdGNoZXIoKSxcclxuICAgICAgICAgICAgb25QcmV2aWV3Q29udHJvbHNIaWRlOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgICAgIG9uQ29udHJvbHNIaWRlOiBuZXcgZXZlbnRkaXNwYXRjaGVyXzEuRXZlbnREaXNwYXRjaGVyKCksXHJcbiAgICAgICAgfTtcclxuICAgICAgICB0aGlzLnBsYXllcldyYXBwZXIgPSBuZXcgUGxheWVyV3JhcHBlcihwbGF5ZXIpO1xyXG4gICAgICAgIHRoaXMudWkgPSB1aTtcclxuICAgICAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcclxuICAgIH1cclxuICAgIFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZS5nZXRDb25maWcgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuY29uZmlnO1xyXG4gICAgfTtcclxuICAgIFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZS5nZXRVSSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy51aTtcclxuICAgIH07XHJcbiAgICBVSUluc3RhbmNlTWFuYWdlci5wcm90b3R5cGUuZ2V0UGxheWVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnBsYXllcldyYXBwZXIuZ2V0UGxheWVyKCk7XHJcbiAgICB9O1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZSwgXCJvbkNvbmZpZ3VyZWRcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEZpcmVzIHdoZW4gdGhlIFVJIGlzIGZ1bGx5IGNvbmZpZ3VyZWQgYW5kIGFkZGVkIHRvIHRoZSBET00uXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50RGlzcGF0Y2hlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRzLm9uQ29uZmlndXJlZDtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShVSUluc3RhbmNlTWFuYWdlci5wcm90b3R5cGUsIFwib25TZWVrXCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBGaXJlcyB3aGVuIGEgc2VlayBzdGFydHMuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50RGlzcGF0Y2hlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRzLm9uU2VlaztcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShVSUluc3RhbmNlTWFuYWdlci5wcm90b3R5cGUsIFwib25TZWVrUHJldmlld1wiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRmlyZXMgd2hlbiB0aGUgc2VlayB0aW1lbGluZSBpcyBzY3J1YmJlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnREaXNwYXRjaGVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudHMub25TZWVrUHJldmlldztcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShVSUluc3RhbmNlTWFuYWdlci5wcm90b3R5cGUsIFwib25TZWVrZWRcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEZpcmVzIHdoZW4gYSBzZWVrIGlzIGZpbmlzaGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtFdmVudERpc3BhdGNoZXJ9XHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZ2V0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmV2ZW50cy5vblNlZWtlZDtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShVSUluc3RhbmNlTWFuYWdlci5wcm90b3R5cGUsIFwib25Db21wb25lbnRTaG93XCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBGaXJlcyB3aGVuIGEgY29tcG9uZW50IGlzIHNob3dpbmcuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50RGlzcGF0Y2hlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRzLm9uQ29tcG9uZW50U2hvdztcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShVSUluc3RhbmNlTWFuYWdlci5wcm90b3R5cGUsIFwib25Db21wb25lbnRIaWRlXCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBGaXJlcyB3aGVuIGEgY29tcG9uZW50IGlzIGhpZGluZy5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RXZlbnREaXNwYXRjaGVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5ldmVudHMub25Db21wb25lbnRIaWRlO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZSwgXCJvbkNvbnRyb2xzU2hvd1wiLCB7XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogRmlyZXMgd2hlbiB0aGUgVUkgY29udHJvbHMgYXJlIHNob3dpbmcuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50RGlzcGF0Y2hlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRzLm9uQ29udHJvbHNTaG93O1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZSwgXCJvblByZXZpZXdDb250cm9sc0hpZGVcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEZpcmVzIGJlZm9yZSB0aGUgVUkgY29udHJvbHMgYXJlIGhpZGluZyB0byBjaGVjayBpZiB0aGV5IGFyZSBhbGxvd2VkIHRvIGhpZGUuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50RGlzcGF0Y2hlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRzLm9uUHJldmlld0NvbnRyb2xzSGlkZTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShVSUluc3RhbmNlTWFuYWdlci5wcm90b3R5cGUsIFwib25Db250cm9sc0hpZGVcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEZpcmVzIHdoZW4gdGhlIFVJIGNvbnRyb2xzIGFyZSBoaWRpbmcuXHJcbiAgICAgICAgICogQHJldHVybnMge0V2ZW50RGlzcGF0Y2hlcn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZXZlbnRzLm9uQ29udHJvbHNIaWRlO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgVUlJbnN0YW5jZU1hbmFnZXIucHJvdG90eXBlLmNsZWFyRXZlbnRIYW5kbGVycyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLnBsYXllcldyYXBwZXIuY2xlYXJFdmVudEhhbmRsZXJzKCk7XHJcbiAgICAgICAgdmFyIGV2ZW50cyA9IHRoaXMuZXZlbnRzOyAvLyBhdm9pZCBUUzcwMTdcclxuICAgICAgICBmb3IgKHZhciBldmVudF8xIGluIGV2ZW50cykge1xyXG4gICAgICAgICAgICB2YXIgZGlzcGF0Y2hlciA9IGV2ZW50c1tldmVudF8xXTtcclxuICAgICAgICAgICAgZGlzcGF0Y2hlci51bnN1YnNjcmliZUFsbCgpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICByZXR1cm4gVUlJbnN0YW5jZU1hbmFnZXI7XHJcbn0oKSk7XHJcbmV4cG9ydHMuVUlJbnN0YW5jZU1hbmFnZXIgPSBVSUluc3RhbmNlTWFuYWdlcjtcclxuLyoqXHJcbiAqIEV4dGVuZHMgdGhlIHtAbGluayBVSUluc3RhbmNlTWFuYWdlcn0gZm9yIGludGVybmFsIHVzZSBpbiB0aGUge0BsaW5rIFVJTWFuYWdlcn0gYW5kIHByb3ZpZGVzIGFjY2VzcyB0byBmdW5jdGlvbmFsaXR5XHJcbiAqIHRoYXQgY29tcG9uZW50cyByZWNlaXZpbmcgYSByZWZlcmVuY2UgdG8gdGhlIHtAbGluayBVSUluc3RhbmNlTWFuYWdlcn0gc2hvdWxkIG5vdCBoYXZlIGFjY2VzcyB0by5cclxuICovXHJcbnZhciBJbnRlcm5hbFVJSW5zdGFuY2VNYW5hZ2VyID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhJbnRlcm5hbFVJSW5zdGFuY2VNYW5hZ2VyLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gSW50ZXJuYWxVSUluc3RhbmNlTWFuYWdlcigpIHtcclxuICAgICAgICByZXR1cm4gX3N1cGVyICE9PSBudWxsICYmIF9zdXBlci5hcHBseSh0aGlzLCBhcmd1bWVudHMpIHx8IHRoaXM7XHJcbiAgICB9XHJcbiAgICBJbnRlcm5hbFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZS5nZXRXcmFwcGVkUGxheWVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIFRPRE8gZmluZCBhIG5vbi1oYWNreSB3YXkgdG8gcHJvdmlkZSB0aGUgV3JhcHBlZFBsYXllciB0byB0aGUgVUlNYW5hZ2VyIHdpdGhvdXQgZXhwb3J0aW5nIGl0XHJcbiAgICAgICAgLy8gZ2V0UGxheWVyKCkgYWN0dWFsbHkgcmV0dXJucyB0aGUgV3JhcHBlZFBsYXllciBidXQgaXRzIHJldHVybiB0eXBlIGlzIHNldCB0byBQbGF5ZXIgc28gdGhlIFdyYXBwZWRQbGF5ZXIgZG9lc1xyXG4gICAgICAgIC8vIG5vdCBuZWVkIHRvIGJlIGV4cG9ydGVkXHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZ2V0UGxheWVyKCk7XHJcbiAgICB9O1xyXG4gICAgSW50ZXJuYWxVSUluc3RhbmNlTWFuYWdlci5wcm90b3R5cGUuY29uZmlndXJlQ29udHJvbHMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5jb25maWd1cmVDb250cm9sc1RyZWUodGhpcy5nZXRVSSgpKTtcclxuICAgICAgICB0aGlzLmNvbmZpZ3VyZWQgPSB0cnVlO1xyXG4gICAgfTtcclxuICAgIEludGVybmFsVUlJbnN0YW5jZU1hbmFnZXIucHJvdG90eXBlLmlzQ29uZmlndXJlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5jb25maWd1cmVkO1xyXG4gICAgfTtcclxuICAgIEludGVybmFsVUlJbnN0YW5jZU1hbmFnZXIucHJvdG90eXBlLmNvbmZpZ3VyZUNvbnRyb2xzVHJlZSA9IGZ1bmN0aW9uIChjb21wb25lbnQpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIHZhciBjb25maWd1cmVkQ29tcG9uZW50cyA9IFtdO1xyXG4gICAgICAgIHVpdXRpbHNfMS5VSVV0aWxzLnRyYXZlcnNlVHJlZShjb21wb25lbnQsIGZ1bmN0aW9uIChjb21wb25lbnQpIHtcclxuICAgICAgICAgICAgLy8gRmlyc3QsIGNoZWNrIGlmIHdlIGhhdmUgYWxyZWFkeSBjb25maWd1cmVkIGEgY29tcG9uZW50LCBhbmQgdGhyb3cgYW4gZXJyb3IgaWYgd2UgZGlkLiBNdWx0aXBsZSBjb25maWd1cmF0aW9uXHJcbiAgICAgICAgICAgIC8vIG9mIHRoZSBzYW1lIGNvbXBvbmVudCBsZWFkcyB0byB1bmV4cGVjdGVkIFVJIGJlaGF2aW9yLiBBbHNvLCBhIGNvbXBvbmVudCB0aGF0IGlzIGluIHRoZSBVSSB0cmVlIG11bHRpcGxlXHJcbiAgICAgICAgICAgIC8vIHRpbWVzIGhpbnRzIGF0IGEgd3JvbmcgVUkgc3RydWN0dXJlLlxyXG4gICAgICAgICAgICAvLyBXZSBjb3VsZCBqdXN0IHNraXAgY29uZmlndXJhdGlvbiBpbiBzdWNoIGEgY2FzZSBhbmQgbm90IHRocm93IGFuIGV4Y2VwdGlvbiwgYnV0IGVuZm9yY2luZyBhIGNsZWFuIFVJIHRyZWVcclxuICAgICAgICAgICAgLy8gc2VlbXMgbGlrZSB0aGUgYmV0dGVyIGNob2ljZS5cclxuICAgICAgICAgICAgZm9yICh2YXIgX2kgPSAwLCBjb25maWd1cmVkQ29tcG9uZW50c18xID0gY29uZmlndXJlZENvbXBvbmVudHM7IF9pIDwgY29uZmlndXJlZENvbXBvbmVudHNfMS5sZW5ndGg7IF9pKyspIHtcclxuICAgICAgICAgICAgICAgIHZhciBjb25maWd1cmVkQ29tcG9uZW50ID0gY29uZmlndXJlZENvbXBvbmVudHNfMVtfaV07XHJcbiAgICAgICAgICAgICAgICBpZiAoY29uZmlndXJlZENvbXBvbmVudCA9PT0gY29tcG9uZW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgLy8gV3JpdGUgdGhlIGNvbXBvbmVudCB0byB0aGUgY29uc29sZSB0byBzaW1wbGlmeSBpZGVudGlmaWNhdGlvbiBvZiB0aGUgY3VscHJpdFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIChlLmcuIGJ5IGluc3BlY3RpbmcgdGhlIGNvbmZpZylcclxuICAgICAgICAgICAgICAgICAgICBpZiAoY29uc29sZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKCdDaXJjdWxhciByZWZlcmVuY2UgaW4gVUkgdHJlZScsIGNvbXBvbmVudCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIEFkZGl0aW9uYWxseSB0aHJvdyBhbiBlcnJvciwgYmVjYXVzZSB0aGlzIGNhc2UgbXVzdCBub3QgaGFwcGVuIGFuZCBsZWFkcyB0byB1bmV4cGVjdGVkIFVJIGJlaGF2aW9yLlxyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IEVycm9yKCdDaXJjdWxhciByZWZlcmVuY2UgaW4gVUkgdHJlZTogJyArIGNvbXBvbmVudC5jb25zdHJ1Y3Rvci5uYW1lKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBjb21wb25lbnQuaW5pdGlhbGl6ZSgpO1xyXG4gICAgICAgICAgICBjb21wb25lbnQuY29uZmlndXJlKF90aGlzLmdldFBsYXllcigpLCBfdGhpcyk7XHJcbiAgICAgICAgICAgIGNvbmZpZ3VyZWRDb21wb25lbnRzLnB1c2goY29tcG9uZW50KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICBJbnRlcm5hbFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZS5yZWxlYXNlQ29udHJvbHMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgLy8gRG8gbm90IGNhbGwgcmVsZWFzZSBtZXRob2RzIGlmIHRoZSBjb21wb25lbnRzIGhhdmUgbmV2ZXIgYmVlbiBjb25maWd1cmVkOyB0aGlzIGNhbiByZXN1bHQgaW4gZXhjZXB0aW9uc1xyXG4gICAgICAgIGlmICh0aGlzLmNvbmZpZ3VyZWQpIHtcclxuICAgICAgICAgICAgdGhpcy5yZWxlYXNlQ29udHJvbHNUcmVlKHRoaXMuZ2V0VUkoKSk7XHJcbiAgICAgICAgICAgIHRoaXMuY29uZmlndXJlZCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnJlbGVhc2VkID0gdHJ1ZTtcclxuICAgIH07XHJcbiAgICBJbnRlcm5hbFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZS5pc1JlbGVhc2VkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnJlbGVhc2VkO1xyXG4gICAgfTtcclxuICAgIEludGVybmFsVUlJbnN0YW5jZU1hbmFnZXIucHJvdG90eXBlLnJlbGVhc2VDb250cm9sc1RyZWUgPSBmdW5jdGlvbiAoY29tcG9uZW50KSB7XHJcbiAgICAgICAgY29tcG9uZW50LnJlbGVhc2UoKTtcclxuICAgICAgICBpZiAoY29tcG9uZW50IGluc3RhbmNlb2YgY29udGFpbmVyXzEuQ29udGFpbmVyKSB7XHJcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSBjb21wb25lbnQuZ2V0Q29tcG9uZW50cygpOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICAgICAgdmFyIGNoaWxkQ29tcG9uZW50ID0gX2FbX2ldO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5yZWxlYXNlQ29udHJvbHNUcmVlKGNoaWxkQ29tcG9uZW50KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBJbnRlcm5hbFVJSW5zdGFuY2VNYW5hZ2VyLnByb3RvdHlwZS5jbGVhckV2ZW50SGFuZGxlcnMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jbGVhckV2ZW50SGFuZGxlcnMuY2FsbCh0aGlzKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gSW50ZXJuYWxVSUluc3RhbmNlTWFuYWdlcjtcclxufShVSUluc3RhbmNlTWFuYWdlcikpO1xyXG4vKipcclxuICogV3JhcHMgdGhlIHBsYXllciB0byB0cmFjayBldmVudCBoYW5kbGVycyBhbmQgcHJvdmlkZSBhIHNpbXBsZSBtZXRob2QgdG8gcmVtb3ZlIGFsbCByZWdpc3RlcmVkIGV2ZW50XHJcbiAqIGhhbmRsZXJzIGZyb20gdGhlIHBsYXllci5cclxuICovXHJcbnZhciBQbGF5ZXJXcmFwcGVyID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIFBsYXllcldyYXBwZXIocGxheWVyKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICB0aGlzLmV2ZW50SGFuZGxlcnMgPSB7fTtcclxuICAgICAgICB0aGlzLnBsYXllciA9IHBsYXllcjtcclxuICAgICAgICAvLyBDb2xsZWN0IGFsbCBtZW1iZXJzIG9mIHRoZSBwbGF5ZXIgKHB1YmxpYyBBUEkgbWV0aG9kcyBhbmQgcHJvcGVydGllcyBvZiB0aGUgcGxheWVyKVxyXG4gICAgICAgIC8vIChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhwbGF5ZXIpIGRvZXMgbm90IHdvcmsgd2l0aCB0aGUgcGxheWVyIFR5cGVTY3JpcHQgY2xhc3Mgc3RhcnRpbmcgaW4gNy4yKVxyXG4gICAgICAgIHZhciBtZW1iZXJzID0gW107XHJcbiAgICAgICAgZm9yICh2YXIgbWVtYmVyIGluIHBsYXllcikge1xyXG4gICAgICAgICAgICBtZW1iZXJzLnB1c2gobWVtYmVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gU3BsaXQgdGhlIG1lbWJlcnMgaW50byBtZXRob2RzIGFuZCBwcm9wZXJ0aWVzXHJcbiAgICAgICAgdmFyIG1ldGhvZHMgPSBbXTtcclxuICAgICAgICB2YXIgcHJvcGVydGllcyA9IFtdO1xyXG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgbWVtYmVyc18xID0gbWVtYmVyczsgX2kgPCBtZW1iZXJzXzEubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgIHZhciBtZW1iZXIgPSBtZW1iZXJzXzFbX2ldO1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIHBsYXllclttZW1iZXJdID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgICAgICAgICBtZXRob2RzLnB1c2gobWVtYmVyKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHByb3BlcnRpZXMucHVzaChtZW1iZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIENyZWF0ZSB3cmFwcGVyIG9iamVjdFxyXG4gICAgICAgIHZhciB3cmFwcGVyID0ge307XHJcbiAgICAgICAgdmFyIF9sb29wXzEgPSBmdW5jdGlvbiAobWV0aG9kKSB7XHJcbiAgICAgICAgICAgIHdyYXBwZXJbbWV0aG9kXSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdjYWxsZWQgJyArIG1lbWJlcik7IC8vIHRyYWNrIG1ldGhvZCBjYWxscyBvbiB0aGUgcGxheWVyXHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcGxheWVyW21ldGhvZF0uYXBwbHkocGxheWVyLCBhcmd1bWVudHMpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgLy8gQWRkIGZ1bmN0aW9uIHdyYXBwZXJzIGZvciBhbGwgQVBJIG1ldGhvZHMgdGhhdCBkbyBub3RoaW5nIGJ1dCBjYWxsaW5nIHRoZSBiYXNlIG1ldGhvZCBvbiB0aGUgcGxheWVyXHJcbiAgICAgICAgZm9yICh2YXIgX2EgPSAwLCBtZXRob2RzXzEgPSBtZXRob2RzOyBfYSA8IG1ldGhvZHNfMS5sZW5ndGg7IF9hKyspIHtcclxuICAgICAgICAgICAgdmFyIG1ldGhvZCA9IG1ldGhvZHNfMVtfYV07XHJcbiAgICAgICAgICAgIF9sb29wXzEobWV0aG9kKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIF9sb29wXzIgPSBmdW5jdGlvbiAocHJvcGVydHkpIHtcclxuICAgICAgICAgICAgLy8gR2V0IGFuIGV2ZW50dWFsbHkgZXhpc3RpbmcgcHJvcGVydHkgZGVzY3JpcHRvciB0byBkaWZmZXJlbnRpYXRlIGJldHdlZW4gcGxhaW4gcHJvcGVydGllcyBhbmQgcHJvcGVydGllcyB3aXRoXHJcbiAgICAgICAgICAgIC8vIGdldHRlcnMvc2V0dGVycy5cclxuICAgICAgICAgICAgdmFyIHByb3BlcnR5RGVzY3JpcHRvciA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IocGxheWVyLCBwcm9wZXJ0eSkgfHxcclxuICAgICAgICAgICAgICAgIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoT2JqZWN0LmdldFByb3RvdHlwZU9mKHBsYXllciksIHByb3BlcnR5KTtcclxuICAgICAgICAgICAgLy8gSWYgdGhlIHByb3BlcnR5IGhhcyBnZXR0ZXJzL3NldHRlcnMsIHdyYXAgdGhlbSBhY2NvcmRpbmdseS4uLlxyXG4gICAgICAgICAgICBpZiAocHJvcGVydHlEZXNjcmlwdG9yICYmIChwcm9wZXJ0eURlc2NyaXB0b3IuZ2V0IHx8IHByb3BlcnR5RGVzY3JpcHRvci5zZXQpKSB7XHJcbiAgICAgICAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkod3JhcHBlciwgcHJvcGVydHksIHtcclxuICAgICAgICAgICAgICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHByb3BlcnR5RGVzY3JpcHRvci5nZXQuY2FsbChwbGF5ZXIpOyB9LFxyXG4gICAgICAgICAgICAgICAgICAgIHNldDogZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiBwcm9wZXJ0eURlc2NyaXB0b3Iuc2V0LmNhbGwocGxheWVyLCB2YWx1ZSk7IH0sXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHdyYXBwZXJbcHJvcGVydHldID0gcGxheWVyW3Byb3BlcnR5XTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgLy8gQWRkIGFsbCBwdWJsaWMgcHJvcGVydGllcyBvZiB0aGUgcGxheWVyIHRvIHRoZSB3cmFwcGVyXHJcbiAgICAgICAgZm9yICh2YXIgX2IgPSAwLCBwcm9wZXJ0aWVzXzEgPSBwcm9wZXJ0aWVzOyBfYiA8IHByb3BlcnRpZXNfMS5sZW5ndGg7IF9iKyspIHtcclxuICAgICAgICAgICAgdmFyIHByb3BlcnR5ID0gcHJvcGVydGllc18xW19iXTtcclxuICAgICAgICAgICAgX2xvb3BfMihwcm9wZXJ0eSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIEV4cGxpY2l0bHkgYWRkIGEgd3JhcHBlciBtZXRob2QgZm9yICdhZGRFdmVudEhhbmRsZXInIHRoYXQgYWRkcyBhZGRlZCBldmVudCBoYW5kbGVycyB0byB0aGUgZXZlbnQgbGlzdFxyXG4gICAgICAgIHdyYXBwZXIuYWRkRXZlbnRIYW5kbGVyID0gZnVuY3Rpb24gKGV2ZW50VHlwZSwgY2FsbGJhY2spIHtcclxuICAgICAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihldmVudFR5cGUsIGNhbGxiYWNrKTtcclxuICAgICAgICAgICAgaWYgKCFfdGhpcy5ldmVudEhhbmRsZXJzW2V2ZW50VHlwZV0pIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmV2ZW50SGFuZGxlcnNbZXZlbnRUeXBlXSA9IFtdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIF90aGlzLmV2ZW50SGFuZGxlcnNbZXZlbnRUeXBlXS5wdXNoKGNhbGxiYWNrKTtcclxuICAgICAgICAgICAgcmV0dXJuIHdyYXBwZXI7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvLyBFeHBsaWNpdGx5IGFkZCBhIHdyYXBwZXIgbWV0aG9kIGZvciAncmVtb3ZlRXZlbnRIYW5kbGVyJyB0aGF0IHJlbW92ZXMgcmVtb3ZlZCBldmVudCBoYW5kbGVycyBmcm9tIHRoZSBldmVudCBsaXN0XHJcbiAgICAgICAgd3JhcHBlci5yZW1vdmVFdmVudEhhbmRsZXIgPSBmdW5jdGlvbiAoZXZlbnRUeXBlLCBjYWxsYmFjaykge1xyXG4gICAgICAgICAgICBwbGF5ZXIucmVtb3ZlRXZlbnRIYW5kbGVyKGV2ZW50VHlwZSwgY2FsbGJhY2spO1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMuZXZlbnRIYW5kbGVyc1tldmVudFR5cGVdKSB7XHJcbiAgICAgICAgICAgICAgICBhcnJheXV0aWxzXzEuQXJyYXlVdGlscy5yZW1vdmUoX3RoaXMuZXZlbnRIYW5kbGVyc1tldmVudFR5cGVdLCBjYWxsYmFjayk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHdyYXBwZXI7XHJcbiAgICAgICAgfTtcclxuICAgICAgICB3cmFwcGVyLmZpcmVFdmVudEluVUkgPSBmdW5jdGlvbiAoZXZlbnQsIGRhdGEpIHtcclxuICAgICAgICAgICAgaWYgKF90aGlzLmV2ZW50SGFuZGxlcnNbZXZlbnRdKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBFeHRlbmQgdGhlIGRhdGEgb2JqZWN0IHdpdGggZGVmYXVsdCB2YWx1ZXMgdG8gY29udmVydCBpdCB0byBhIHtAbGluayBQbGF5ZXJFdmVudH0gb2JqZWN0LlxyXG4gICAgICAgICAgICAgICAgdmFyIHBsYXllckV2ZW50RGF0YSA9IE9iamVjdC5hc3NpZ24oe30sIHtcclxuICAgICAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXHJcbiAgICAgICAgICAgICAgICAgICAgdHlwZTogZXZlbnQsXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gQWRkIGEgbWFya2VyIHByb3BlcnR5IHNvIHRoZSBVSSBjYW4gZGV0ZWN0IFVJLWludGVybmFsIHBsYXllciBldmVudHNcclxuICAgICAgICAgICAgICAgICAgICB1aVNvdXJjZWQ6IHRydWUsXHJcbiAgICAgICAgICAgICAgICB9LCBkYXRhKTtcclxuICAgICAgICAgICAgICAgIC8vIEV4ZWN1dGUgdGhlIHJlZ2lzdGVyZWQgY2FsbGJhY2tzXHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gX3RoaXMuZXZlbnRIYW5kbGVyc1tldmVudF07IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGNhbGxiYWNrID0gX2FbX2ldO1xyXG4gICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHBsYXllckV2ZW50RGF0YSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHRoaXMud3JhcHBlciA9IHdyYXBwZXI7XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgYSB3cmFwcGVkIHBsYXllciBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCBvbiBwbGFjZSBvZiB0aGUgbm9ybWFsIHBsYXllciBvYmplY3QuXHJcbiAgICAgKiBAcmV0dXJucyB7V3JhcHBlZFBsYXllcn0gYSB3cmFwcGVkIHBsYXllclxyXG4gICAgICovXHJcbiAgICBQbGF5ZXJXcmFwcGVyLnByb3RvdHlwZS5nZXRQbGF5ZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMud3JhcHBlcjtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIENsZWFycyBhbGwgcmVnaXN0ZXJlZCBldmVudCBoYW5kbGVycyBmcm9tIHRoZSBwbGF5ZXIgdGhhdCB3ZXJlIGFkZGVkIHRocm91Z2ggdGhlIHdyYXBwZWQgcGxheWVyLlxyXG4gICAgICovXHJcbiAgICBQbGF5ZXJXcmFwcGVyLnByb3RvdHlwZS5jbGVhckV2ZW50SGFuZGxlcnMgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZm9yICh2YXIgZXZlbnRUeXBlIGluIHRoaXMuZXZlbnRIYW5kbGVycykge1xyXG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gdGhpcy5ldmVudEhhbmRsZXJzW2V2ZW50VHlwZV07IF9pIDwgX2EubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgY2FsbGJhY2sgPSBfYVtfaV07XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBsYXllci5yZW1vdmVFdmVudEhhbmRsZXIoZXZlbnRUeXBlLCBjYWxsYmFjayk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIFBsYXllcldyYXBwZXI7XHJcbn0oKSk7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvdWltYW5hZ2VyLnRzXG4vLyBtb2R1bGUgaWQgPSAzNVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgR3VpZDtcclxuKGZ1bmN0aW9uIChHdWlkKSB7XHJcbiAgICB2YXIgZ3VpZCA9IDE7XHJcbiAgICBmdW5jdGlvbiBuZXh0KCkge1xyXG4gICAgICAgIHJldHVybiBndWlkKys7XHJcbiAgICB9XHJcbiAgICBHdWlkLm5leHQgPSBuZXh0O1xyXG59KShHdWlkID0gZXhwb3J0cy5HdWlkIHx8IChleHBvcnRzLkd1aWQgPSB7fSkpO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2d1aWQudHNcbi8vIG1vZHVsZSBpZCA9IDM2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgdG9nZ2xlYnV0dG9uXzEgPSByZXF1aXJlKFwiLi90b2dnbGVidXR0b25cIik7XHJcbi8qKlxyXG4gKiBBIGJ1dHRvbiB0aGF0IHRvZ2dsZXMgdGhlIHBsYXllciBiZXR3ZWVuIHdpbmRvd2VkIGFuZCBmdWxsc2NyZWVuIHZpZXcuXHJcbiAqL1xyXG52YXIgRnVsbHNjcmVlblRvZ2dsZUJ1dHRvbiA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoRnVsbHNjcmVlblRvZ2dsZUJ1dHRvbiwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIEZ1bGxzY3JlZW5Ub2dnbGVCdXR0b24oY29uZmlnKSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLWZ1bGxzY3JlZW50b2dnbGVidXR0b24nLFxyXG4gICAgICAgICAgICB0ZXh0OiAnRnVsbHNjcmVlbicsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBGdWxsc2NyZWVuVG9nZ2xlQnV0dG9uLnByb3RvdHlwZS5jb25maWd1cmUgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY29uZmlndXJlLmNhbGwodGhpcywgcGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIHZhciBmdWxsc2NyZWVuU3RhdGVIYW5kbGVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAocGxheWVyLmlzRnVsbHNjcmVlbigpKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5vbigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMub2ZmKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0ZVTExTQ1JFRU5fRU5URVIsIGZ1bGxzY3JlZW5TdGF0ZUhhbmRsZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0ZVTExTQ1JFRU5fRVhJVCwgZnVsbHNjcmVlblN0YXRlSGFuZGxlcik7XHJcbiAgICAgICAgdGhpcy5vbkNsaWNrLnN1YnNjcmliZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChwbGF5ZXIuaXNGdWxsc2NyZWVuKCkpIHtcclxuICAgICAgICAgICAgICAgIHBsYXllci5leGl0RnVsbHNjcmVlbigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcGxheWVyLmVudGVyRnVsbHNjcmVlbigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gU3RhcnR1cCBpbml0XHJcbiAgICAgICAgZnVsbHNjcmVlblN0YXRlSGFuZGxlcigpO1xyXG4gICAgfTtcclxuICAgIHJldHVybiBGdWxsc2NyZWVuVG9nZ2xlQnV0dG9uO1xyXG59KHRvZ2dsZWJ1dHRvbl8xLlRvZ2dsZUJ1dHRvbikpO1xyXG5leHBvcnRzLkZ1bGxzY3JlZW5Ub2dnbGVCdXR0b24gPSBGdWxsc2NyZWVuVG9nZ2xlQnV0dG9uO1xyXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvdWltYW5hZ2VyL2NvbXBvbmVudHMvZnVsbHNjcmVlbnRvZ2dsZWJ1dHRvbi50c1xuLy8gbW9kdWxlIGlkID0gMzdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGRvbV8xID0gcmVxdWlyZShcIi4vZG9tXCIpO1xyXG4vKipcclxuICogVHJhY2tzIHRoZSBsb2FkaW5nIHN0YXRlIG9mIGltYWdlcy5cclxuICovXHJcbnZhciBJbWFnZUxvYWRlciA9IChmdW5jdGlvbiAoKSB7XHJcbiAgICBmdW5jdGlvbiBJbWFnZUxvYWRlcigpIHtcclxuICAgICAgICB0aGlzLnN0YXRlID0ge307XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIExvYWRzIGFuIGltYWdlIGFuZCBjYWxsIHRoZSBjYWxsYmFjayBvbmNlIHRoZSBpbWFnZSBpcyBsb2FkZWQuIElmIHRoZSBpbWFnZSBpcyBhbHJlYWR5IGxvYWRlZCwgdGhlIGNhbGxiYWNrXHJcbiAgICAgKiBpcyBjYWxsZWQgaW1tZWRpYXRlbHksIGVsc2UgaXQgaXMgY2FsbGVkIG9uY2UgbG9hZGluZyBoYXMgZmluaXNoZWQuIENhbGxpbmcgdGhpcyBtZXRob2QgbXVsdGlwbGUgdGltZXMgZm9yIHRoZVxyXG4gICAgICogc2FtZSBpbWFnZSB3aGlsZSBpdCBpcyBsb2FkaW5nIGNhbGxzIG9ubHkgbGV0IGNhbGxiYWNrIHBhc3NlZCBpbnRvIHRoZSBsYXN0IGNhbGwuXHJcbiAgICAgKiBAcGFyYW0gdXJsIFRoZSB1cmwgdG8gdGhlIGltYWdlIHRvIGxvYWRcclxuICAgICAqIEBwYXJhbSBsb2FkZWRDYWxsYmFjayBUaGUgY2FsbGJhY2sgdGhhdCBpcyBjYWxsZWQgd2hlbiB0aGUgaW1hZ2UgaXMgbG9hZGVkXHJcbiAgICAgKi9cclxuICAgIEltYWdlTG9hZGVyLnByb3RvdHlwZS5sb2FkID0gZnVuY3Rpb24gKHVybCwgbG9hZGVkQ2FsbGJhY2spIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIGlmICghdGhpcy5zdGF0ZVt1cmxdKSB7XHJcbiAgICAgICAgICAgIC8vIFdoZW4gdGhlIGltYWdlIHdhcyBuZXZlciBhdHRlbXB0ZWQgdG8gYmUgbG9hZGVkIGJlZm9yZSwgd2UgY3JlYXRlIGEgc3RhdGUgYW5kIHN0b3JlIGl0IGluIHRoZSBzdGF0ZSBtYXBcclxuICAgICAgICAgICAgLy8gZm9yIGxhdGVyIHVzZSB3aGVuIHRoZSBzYW1lIGltYWdlIGlzIHJlcXVlc3RlZCB0byBiZSBsb2FkZWQgYWdhaW4uXHJcbiAgICAgICAgICAgIHZhciBzdGF0ZV8xID0ge1xyXG4gICAgICAgICAgICAgICAgdXJsOiB1cmwsXHJcbiAgICAgICAgICAgICAgICBpbWFnZTogbmV3IGRvbV8xLkRPTSgnaW1nJywge30pLFxyXG4gICAgICAgICAgICAgICAgbG9hZGVkQ2FsbGJhY2s6IGxvYWRlZENhbGxiYWNrLFxyXG4gICAgICAgICAgICAgICAgbG9hZGVkOiBmYWxzZSxcclxuICAgICAgICAgICAgICAgIHdpZHRoOiAwLFxyXG4gICAgICAgICAgICAgICAgaGVpZ2h0OiAwLFxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICB0aGlzLnN0YXRlW3VybF0gPSBzdGF0ZV8xO1xyXG4gICAgICAgICAgICAvLyBMaXN0ZW4gdG8gdGhlIGxvYWQgZXZlbnQsIHVwZGF0ZSB0aGUgc3RhdGUgYW5kIGNhbGwgdGhlIGNhbGxiYWNrIG9uY2UgdGhlIGltYWdlIGlzIGxvYWRlZFxyXG4gICAgICAgICAgICBzdGF0ZV8xLmltYWdlLm9uKCdsb2FkJywgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICAgIHN0YXRlXzEubG9hZGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHN0YXRlXzEud2lkdGggPSBzdGF0ZV8xLmltYWdlLmdldCgwKS53aWR0aDtcclxuICAgICAgICAgICAgICAgIHN0YXRlXzEuaGVpZ2h0ID0gc3RhdGVfMS5pbWFnZS5nZXQoMCkuaGVpZ2h0O1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuY2FsbExvYWRlZENhbGxiYWNrKHN0YXRlXzEpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgLy8gU2V0IHRoZSBpbWFnZSBVUkwgdG8gc3RhcnQgdGhlIGxvYWRpbmdcclxuICAgICAgICAgICAgc3RhdGVfMS5pbWFnZS5hdHRyKCdzcmMnLCBzdGF0ZV8xLnVybCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBXZSBoYXZlIGEgc3RhdGUgZm9yIHRoZSByZXF1ZXN0ZWQgaW1hZ2UsIHNvIGl0IGlzIGVpdGhlciBhbHJlYWR5IGxvYWRlZCBvciBjdXJyZW50bHkgbG9hZGluZ1xyXG4gICAgICAgICAgICB2YXIgc3RhdGUgPSB0aGlzLnN0YXRlW3VybF07XHJcbiAgICAgICAgICAgIC8vIFdlIG92ZXJ3cml0ZSB0aGUgY2FsbGJhY2sgdG8gbWFrZSBzdXJlIHRoYXQgb25seSB0aGUgY2FsbGJhY2sgb2YgdGhlIGxhdGVzdCBjYWxsIGdldHMgZXhlY3V0ZWQuXHJcbiAgICAgICAgICAgIC8vIEVhcmxpZXIgY2FsbGJhY2tzIGJlY29tZSBpbnZhbGlkIG9uY2UgYSBuZXcgbG9hZCBjYWxsIGFycml2ZXMsIGFuZCB0aGV5IGFyZSBub3QgY2FsbGVkIGFzIGxvbmcgYXMgdGhlIGltYWdlXHJcbiAgICAgICAgICAgIC8vIGlzIG5vdCBsb2FkZWQuXHJcbiAgICAgICAgICAgIHN0YXRlLmxvYWRlZENhbGxiYWNrID0gbG9hZGVkQ2FsbGJhY2s7XHJcbiAgICAgICAgICAgIC8vIFdoZW4gdGhlIGltYWdlIGlzIGFscmVhZHkgbG9hZGVkLCB3ZSBkaXJlY3RseSBleGVjdXRlIHRoZSBjYWxsYmFjayBpbnN0ZWFkIG9mIHdhaXRpbmcgZm9yIHRoZSBsb2FkIGV2ZW50XHJcbiAgICAgICAgICAgIGlmIChzdGF0ZS5sb2FkZWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuY2FsbExvYWRlZENhbGxiYWNrKHN0YXRlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBJbWFnZUxvYWRlci5wcm90b3R5cGUuY2FsbExvYWRlZENhbGxiYWNrID0gZnVuY3Rpb24gKHN0YXRlKSB7XHJcbiAgICAgICAgc3RhdGUubG9hZGVkQ2FsbGJhY2soc3RhdGUudXJsLCBzdGF0ZS53aWR0aCwgc3RhdGUuaGVpZ2h0KTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gSW1hZ2VMb2FkZXI7XHJcbn0oKSk7XHJcbmV4cG9ydHMuSW1hZ2VMb2FkZXIgPSBJbWFnZUxvYWRlcjtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9pbWFnZWxvYWRlci50c1xuLy8gbW9kdWxlIGlkID0gMzhcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBzZWxlY3Rib3hfMSA9IHJlcXVpcmUoXCIuL3NlbGVjdGJveFwiKTtcclxuLyoqXHJcbiAqIEEgc2VsZWN0IGJveCBwcm92aWRpbmcgYSBzZWxlY3Rpb24gYmV0d2VlbiBhdmFpbGFibGUgc3VidGl0bGUgYW5kIGNhcHRpb24gdHJhY2tzLlxyXG4gKi9cclxudmFyIFN1YnRpdGxlU2VsZWN0Qm94ID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhTdWJ0aXRsZVNlbGVjdEJveCwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFN1YnRpdGxlU2VsZWN0Qm94KGNvbmZpZykge1xyXG4gICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgIHJldHVybiBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICB9XHJcbiAgICBTdWJ0aXRsZVNlbGVjdEJveC5wcm90b3R5cGUuY29uZmlndXJlID0gZnVuY3Rpb24gKHBsYXllciwgdWltYW5hZ2VyKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gdGhpcztcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNvbmZpZ3VyZS5jYWxsKHRoaXMsIHBsYXllciwgdWltYW5hZ2VyKTtcclxuICAgICAgICB2YXIgc2VsZWN0Q3VycmVudFN1YnRpdGxlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgY3VycmVudFN1YnRpdGxlID0gcGxheWVyLmdldFN1YnRpdGxlKCk7XHJcbiAgICAgICAgICAgIGlmIChjdXJyZW50U3VidGl0bGUpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLnNlbGVjdEl0ZW0oY3VycmVudFN1YnRpdGxlLmlkKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcbiAgICAgICAgdmFyIHVwZGF0ZVN1YnRpdGxlcyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMuY2xlYXJJdGVtcygpO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gcGxheWVyLmdldEF2YWlsYWJsZVN1YnRpdGxlcygpOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICAgICAgdmFyIHN1YnRpdGxlID0gX2FbX2ldO1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuYWRkSXRlbShzdWJ0aXRsZS5pZCwgc3VidGl0bGUubGFiZWwpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIFNlbGVjdCB0aGUgY29ycmVjdCBzdWJ0aXRsZSBhZnRlciB0aGUgc3VidGl0bGVzIGhhdmUgYmVlbiBhZGRlZFxyXG4gICAgICAgICAgICBzZWxlY3RDdXJyZW50U3VidGl0bGUoKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHRoaXMub25JdGVtU2VsZWN0ZWQuc3Vic2NyaWJlKGZ1bmN0aW9uIChzZW5kZXIsIHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHBsYXllci5zZXRTdWJ0aXRsZSh2YWx1ZSA9PT0gJ251bGwnID8gbnVsbCA6IHZhbHVlKTtcclxuICAgICAgICB9KTtcclxuICAgICAgICAvLyBSZWFjdCB0byBBUEkgZXZlbnRzXHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fU1VCVElUTEVfQURERUQsIHVwZGF0ZVN1YnRpdGxlcyk7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fU1VCVElUTEVfQ0hBTkdFRCwgc2VsZWN0Q3VycmVudFN1YnRpdGxlKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TVUJUSVRMRV9SRU1PVkVELCB1cGRhdGVTdWJ0aXRsZXMpO1xyXG4gICAgICAgIC8vIFVwZGF0ZSBzdWJ0aXRsZXMgd2hlbiBzb3VyY2UgZ29lcyBhd2F5XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fU09VUkNFX1VOTE9BREVELCB1cGRhdGVTdWJ0aXRsZXMpO1xyXG4gICAgICAgIC8vIFVwZGF0ZSBzdWJ0aXRsZXMgd2hlbiBhIG5ldyBzb3VyY2UgaXMgbG9hZGVkXHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fUkVBRFksIHVwZGF0ZVN1YnRpdGxlcyk7XHJcbiAgICAgICAgLy8gVXBkYXRlIHN1YnRpdGxlcyB3aGVuIHRoZSBwZXJpb2Qgd2l0aGluIGEgc291cmNlIGNoYW5nZXNcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9QRVJJT0RfU1dJVENIRUQsIHVwZGF0ZVN1YnRpdGxlcyk7XHJcbiAgICAgICAgLy8gUG9wdWxhdGUgc3VidGl0bGVzIGF0IHN0YXJ0dXBcclxuICAgICAgICB1cGRhdGVTdWJ0aXRsZXMoKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gU3VidGl0bGVTZWxlY3RCb3g7XHJcbn0oc2VsZWN0Ym94XzEuU2VsZWN0Qm94KSk7XHJcbmV4cG9ydHMuU3VidGl0bGVTZWxlY3RCb3ggPSBTdWJ0aXRsZVNlbGVjdEJveDtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3N1YnRpdGxlc2VsZWN0Ym94LnRzXG4vLyBtb2R1bGUgaWQgPSAzOVxuLy8gbW9kdWxlIGNodW5rcyA9IDAiLCJcInVzZSBzdHJpY3RcIjtcclxudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGV4dGVuZFN0YXRpY3MgPSBPYmplY3Quc2V0UHJvdG90eXBlT2YgfHxcclxuICAgICAgICAoeyBfX3Byb3RvX186IFtdIH0gaW5zdGFuY2VvZiBBcnJheSAmJiBmdW5jdGlvbiAoZCwgYikgeyBkLl9fcHJvdG9fXyA9IGI7IH0pIHx8XHJcbiAgICAgICAgZnVuY3Rpb24gKGQsIGIpIHsgZm9yICh2YXIgcCBpbiBiKSBpZiAoYi5oYXNPd25Qcm9wZXJ0eShwKSkgZFtwXSA9IGJbcF07IH07XHJcbiAgICByZXR1cm4gZnVuY3Rpb24gKGQsIGIpIHtcclxuICAgICAgICBleHRlbmRTdGF0aWNzKGQsIGIpO1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxyXG4gICAgICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcclxuICAgIH07XHJcbn0pKCk7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIGNvbnRhaW5lcl8xID0gcmVxdWlyZShcIi4vY29udGFpbmVyXCIpO1xyXG52YXIgbGFiZWxfMSA9IHJlcXVpcmUoXCIuL2xhYmVsXCIpO1xyXG52YXIgY29udHJvbGJhcl8xID0gcmVxdWlyZShcIi4vY29udHJvbGJhclwiKTtcclxuLyoqXHJcbiAqIE92ZXJsYXlzIHRoZSBwbGF5ZXIgdG8gZGlzcGxheSBzdWJ0aXRsZXMuXHJcbiAqL1xyXG52YXIgU3VidGl0bGVPdmVybGF5ID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhTdWJ0aXRsZU92ZXJsYXksIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBTdWJ0aXRsZU92ZXJsYXkoY29uZmlnKSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLnByZXZpZXdTdWJ0aXRsZUFjdGl2ZSA9IGZhbHNlO1xyXG4gICAgICAgIF90aGlzLnByZXZpZXdTdWJ0aXRsZSA9IG5ldyBTdWJ0aXRsZUxhYmVsKHsgdGV4dDogJ2V4YW1wbGUgc3VidGl0bGUnIH0pO1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLXN1YnRpdGxlLW92ZXJsYXknLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgU3VidGl0bGVPdmVybGF5LnByb3RvdHlwZS5jb25maWd1cmUgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuY29uZmlndXJlLmNhbGwodGhpcywgcGxheWVyLCB1aW1hbmFnZXIpO1xyXG4gICAgICAgIHZhciBzdWJ0aXRsZU1hbmFnZXIgPSBuZXcgQWN0aXZlU3VidGl0bGVNYW5hZ2VyKCk7XHJcbiAgICAgICAgdGhpcy5zdWJ0aXRsZU1hbmFnZXIgPSBzdWJ0aXRsZU1hbmFnZXI7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fQ1VFX0VOVEVSLCBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgLy8gU2FuaXRpemUgY3VlIGRhdGEgKG11c3QgYmUgZG9uZSBiZWZvcmUgdGhlIGN1ZSBJRCBpcyBnZW5lcmF0ZWQgaW4gc3VidGl0bGVNYW5hZ2VyLmN1ZUVudGVyKVxyXG4gICAgICAgICAgICBpZiAoZXZlbnQucG9zaXRpb24pIHtcclxuICAgICAgICAgICAgICAgIC8vIFNvbWV0aW1lcyB0aGUgcG9zaXRpb25zIGFyZSB1bmRlZmluZWQsIHdlIGFzc3VtZSB0aGVtIHRvIGJlIHplcm9cclxuICAgICAgICAgICAgICAgIGV2ZW50LnBvc2l0aW9uLnJvdyA9IGV2ZW50LnBvc2l0aW9uLnJvdyB8fCAwO1xyXG4gICAgICAgICAgICAgICAgZXZlbnQucG9zaXRpb24uY29sdW1uID0gZXZlbnQucG9zaXRpb24uY29sdW1uIHx8IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIGxhYmVsVG9BZGQgPSBzdWJ0aXRsZU1hbmFnZXIuY3VlRW50ZXIoZXZlbnQpO1xyXG4gICAgICAgICAgICBpZiAoX3RoaXMucHJldmlld1N1YnRpdGxlQWN0aXZlKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5yZW1vdmVDb21wb25lbnQoX3RoaXMucHJldmlld1N1YnRpdGxlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBfdGhpcy5hZGRDb21wb25lbnQobGFiZWxUb0FkZCk7XHJcbiAgICAgICAgICAgIF90aGlzLnVwZGF0ZUNvbXBvbmVudHMoKTtcclxuICAgICAgICAgICAgX3RoaXMuc2hvdygpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0NVRV9FWElULCBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgdmFyIGxhYmVsVG9SZW1vdmUgPSBzdWJ0aXRsZU1hbmFnZXIuY3VlRXhpdChldmVudCk7XHJcbiAgICAgICAgICAgIGlmIChsYWJlbFRvUmVtb3ZlKSB7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5yZW1vdmVDb21wb25lbnQobGFiZWxUb1JlbW92ZSk7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy51cGRhdGVDb21wb25lbnRzKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKCFzdWJ0aXRsZU1hbmFnZXIuaGFzQ3Vlcykge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFfdGhpcy5wcmV2aWV3U3VidGl0bGVBY3RpdmUpIHtcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy5oaWRlKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy5hZGRDb21wb25lbnQoX3RoaXMucHJldmlld1N1YnRpdGxlKTtcclxuICAgICAgICAgICAgICAgICAgICBfdGhpcy51cGRhdGVDb21wb25lbnRzKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgICAgICB2YXIgc3VidGl0bGVDbGVhckhhbmRsZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIF90aGlzLmhpZGUoKTtcclxuICAgICAgICAgICAgc3VidGl0bGVNYW5hZ2VyLmNsZWFyKCk7XHJcbiAgICAgICAgICAgIF90aGlzLnJlbW92ZUNvbXBvbmVudHMoKTtcclxuICAgICAgICAgICAgX3RoaXMudXBkYXRlQ29tcG9uZW50cygpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fQVVESU9fQ0hBTkdFRCwgc3VidGl0bGVDbGVhckhhbmRsZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1NVQlRJVExFX0NIQU5HRUQsIHN1YnRpdGxlQ2xlYXJIYW5kbGVyKTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9TRUVLLCBzdWJ0aXRsZUNsZWFySGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fVElNRV9TSElGVCwgc3VidGl0bGVDbGVhckhhbmRsZXIpO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX1BMQVlCQUNLX0ZJTklTSEVELCBzdWJ0aXRsZUNsZWFySGFuZGxlcik7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fU09VUkNFX1VOTE9BREVELCBzdWJ0aXRsZUNsZWFySGFuZGxlcik7XHJcbiAgICAgICAgdWltYW5hZ2VyLm9uQ29tcG9uZW50U2hvdy5zdWJzY3JpYmUoZnVuY3Rpb24gKGNvbXBvbmVudCkge1xyXG4gICAgICAgICAgICBpZiAoY29tcG9uZW50IGluc3RhbmNlb2YgY29udHJvbGJhcl8xLkNvbnRyb2xCYXIpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmdldERvbUVsZW1lbnQoKS5hZGRDbGFzcyhfdGhpcy5wcmVmaXhDc3MoU3VidGl0bGVPdmVybGF5LkNMQVNTX0NPTlRST0xCQVJfVklTSUJMRSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdWltYW5hZ2VyLm9uQ29tcG9uZW50SGlkZS5zdWJzY3JpYmUoZnVuY3Rpb24gKGNvbXBvbmVudCkge1xyXG4gICAgICAgICAgICBpZiAoY29tcG9uZW50IGluc3RhbmNlb2YgY29udHJvbGJhcl8xLkNvbnRyb2xCYXIpIHtcclxuICAgICAgICAgICAgICAgIF90aGlzLmdldERvbUVsZW1lbnQoKS5yZW1vdmVDbGFzcyhfdGhpcy5wcmVmaXhDc3MoU3VidGl0bGVPdmVybGF5LkNMQVNTX0NPTlRST0xCQVJfVklTSUJMRSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5jb25maWd1cmVDZWE2MDhDYXB0aW9ucyhwbGF5ZXIsIHVpbWFuYWdlcik7XHJcbiAgICAgICAgLy8gSW5pdFxyXG4gICAgICAgIHN1YnRpdGxlQ2xlYXJIYW5kbGVyKCk7XHJcbiAgICB9O1xyXG4gICAgU3VidGl0bGVPdmVybGF5LnByb3RvdHlwZS5jb25maWd1cmVDZWE2MDhDYXB0aW9ucyA9IGZ1bmN0aW9uIChwbGF5ZXIsIHVpbWFuYWdlcikge1xyXG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XHJcbiAgICAgICAgLy8gVGhlIGNhbGN1bGF0ZWQgZm9udCBzaXplXHJcbiAgICAgICAgdmFyIGZvbnRTaXplID0gMDtcclxuICAgICAgICAvLyBUaGUgcmVxdWlyZWQgbGV0dGVyIHNwYWNpbmcgc3ByZWFkIHRoZSB0ZXh0IGNoYXJhY3RlcnMgZXZlbmx5IGFjcm9zcyB0aGUgZ3JpZFxyXG4gICAgICAgIHZhciBmb250TGV0dGVyU3BhY2luZyA9IDA7XHJcbiAgICAgICAgLy8gRmxhZyB0ZWxsaW5nIGlmIGEgZm9udCBzaXplIGNhbGN1bGF0aW9uIGlzIHJlcXVpcmVkIG9mIGlmIHRoZSBjdXJyZW50IHZhbHVlcyBhcmUgdmFsaWRcclxuICAgICAgICB2YXIgZm9udFNpemVDYWxjdWxhdGlvblJlcXVpcmVkID0gdHJ1ZTtcclxuICAgICAgICAvLyBGbGFnIHRlbGxpbmcgaWYgdGhlIENFQS02MDggbW9kZSBpcyBlbmFibGVkXHJcbiAgICAgICAgdmFyIGVuYWJsZWQgPSBmYWxzZTtcclxuICAgICAgICB2YXIgdXBkYXRlQ0VBNjA4Rm9udFNpemUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBkdW1teUxhYmVsID0gbmV3IFN1YnRpdGxlTGFiZWwoeyB0ZXh0OiAnWCcgfSk7XHJcbiAgICAgICAgICAgIGR1bW15TGFiZWwuZ2V0RG9tRWxlbWVudCgpLmNzcyh7XHJcbiAgICAgICAgICAgICAgICAvLyBCeSB1c2luZyBhIGxhcmdlIGZvbnQgc2l6ZSB3ZSBkbyBub3QgbmVlZCB0byB1c2UgbXVsdGlwbGUgbGV0dGVycyBhbmQgY2FuIGdldCBzdGlsbCBhblxyXG4gICAgICAgICAgICAgICAgLy8gYWNjdXJhdGUgbWVhc3VyZW1lbnQgZXZlbiB0aG91Z2ggdGhlIHJldHVybmVkIHNpemUgaXMgYW4gaW50ZWdlciB2YWx1ZVxyXG4gICAgICAgICAgICAgICAgJ2ZvbnQtc2l6ZSc6ICcyMDBweCcsXHJcbiAgICAgICAgICAgICAgICAnbGluZS1oZWlnaHQnOiAnMjAwcHgnLFxyXG4gICAgICAgICAgICAgICAgJ3Zpc2liaWxpdHknOiAnaGlkZGVuJyxcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIF90aGlzLmFkZENvbXBvbmVudChkdW1teUxhYmVsKTtcclxuICAgICAgICAgICAgX3RoaXMudXBkYXRlQ29tcG9uZW50cygpO1xyXG4gICAgICAgICAgICBfdGhpcy5zaG93KCk7XHJcbiAgICAgICAgICAgIHZhciBkdW1teUxhYmVsQ2hhcldpZHRoID0gZHVtbXlMYWJlbC5nZXREb21FbGVtZW50KCkud2lkdGgoKTtcclxuICAgICAgICAgICAgdmFyIGR1bW15TGFiZWxDaGFySGVpZ2h0ID0gZHVtbXlMYWJlbC5nZXREb21FbGVtZW50KCkuaGVpZ2h0KCk7XHJcbiAgICAgICAgICAgIHZhciBmb250U2l6ZVJhdGlvID0gZHVtbXlMYWJlbENoYXJXaWR0aCAvIGR1bW15TGFiZWxDaGFySGVpZ2h0O1xyXG4gICAgICAgICAgICBfdGhpcy5yZW1vdmVDb21wb25lbnQoZHVtbXlMYWJlbCk7XHJcbiAgICAgICAgICAgIF90aGlzLnVwZGF0ZUNvbXBvbmVudHMoKTtcclxuICAgICAgICAgICAgaWYgKCFfdGhpcy5zdWJ0aXRsZU1hbmFnZXIuaGFzQ3Vlcykge1xyXG4gICAgICAgICAgICAgICAgX3RoaXMuaGlkZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIFRoZSBzaXplIHJhdGlvIG9mIHRoZSBsZXR0ZXIgZ3JpZFxyXG4gICAgICAgICAgICB2YXIgZm9udEdyaWRTaXplUmF0aW8gPSAoZHVtbXlMYWJlbENoYXJXaWR0aCAqIFN1YnRpdGxlT3ZlcmxheS5DRUE2MDhfTlVNX0NPTFVNTlMpIC9cclxuICAgICAgICAgICAgICAgIChkdW1teUxhYmVsQ2hhckhlaWdodCAqIFN1YnRpdGxlT3ZlcmxheS5DRUE2MDhfTlVNX1JPV1MpO1xyXG4gICAgICAgICAgICAvLyBUaGUgc2l6ZSByYXRpbyBvZiB0aGUgYXZhaWxhYmxlIHNwYWNlIGZvciB0aGUgZ3JpZFxyXG4gICAgICAgICAgICB2YXIgc3VidGl0bGVPdmVybGF5U2l6ZVJhdGlvID0gX3RoaXMuZ2V0RG9tRWxlbWVudCgpLndpZHRoKCkgLyBfdGhpcy5nZXREb21FbGVtZW50KCkuaGVpZ2h0KCk7XHJcbiAgICAgICAgICAgIGlmIChzdWJ0aXRsZU92ZXJsYXlTaXplUmF0aW8gPiBmb250R3JpZFNpemVSYXRpbykge1xyXG4gICAgICAgICAgICAgICAgLy8gV2hlbiB0aGUgYXZhaWxhYmxlIHNwYWNlIGlzIHdpZGVyIHRoYW4gdGhlIHRleHQgZ3JpZCwgdGhlIGZvbnQgc2l6ZSBpcyBzaW1wbHlcclxuICAgICAgICAgICAgICAgIC8vIGRldGVybWluZWQgYnkgdGhlIGhlaWdodCBvZiB0aGUgYXZhaWxhYmxlIHNwYWNlLlxyXG4gICAgICAgICAgICAgICAgZm9udFNpemUgPSBfdGhpcy5nZXREb21FbGVtZW50KCkuaGVpZ2h0KCkgLyBTdWJ0aXRsZU92ZXJsYXkuQ0VBNjA4X05VTV9ST1dTO1xyXG4gICAgICAgICAgICAgICAgLy8gQ2FsY3VsYXRlIHRoZSBhZGRpdGlvbmFsIGxldHRlciBzcGFjaW5nIHJlcXVpcmVkIHRvIGV2ZW5seSBzcHJlYWQgdGhlIHRleHQgYWNyb3NzIHRoZSBncmlkJ3Mgd2lkdGhcclxuICAgICAgICAgICAgICAgIHZhciBncmlkU2xvdFdpZHRoID0gX3RoaXMuZ2V0RG9tRWxlbWVudCgpLndpZHRoKCkgLyBTdWJ0aXRsZU92ZXJsYXkuQ0VBNjA4X05VTV9DT0xVTU5TO1xyXG4gICAgICAgICAgICAgICAgdmFyIGZvbnRDaGFyV2lkdGggPSBmb250U2l6ZSAqIGZvbnRTaXplUmF0aW87XHJcbiAgICAgICAgICAgICAgICBmb250TGV0dGVyU3BhY2luZyA9IGdyaWRTbG90V2lkdGggLSBmb250Q2hhcldpZHRoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gV2hlbiB0aGUgYXZhaWxhYmxlIHNwYWNlIGlzIG5vdCB3aWRlIGVub3VnaCwgdGV4dHMgd291bGQgdmVydGljYWxseSBvdmVybGFwIGlmIHdlIHRha2VcclxuICAgICAgICAgICAgICAgIC8vIHRoZSBoZWlnaHQgYXMgYSBiYXNlIGZvciB0aGUgZm9udCBzaXplLCBzbyB3ZSBuZWVkIHRvIGxpbWl0IHRoZSBoZWlnaHQuIFdlIGRvIHRoYXRcclxuICAgICAgICAgICAgICAgIC8vIGJ5IGRldGVybWluaW5nIHRoZSBmb250IHNpemUgYnkgdGhlIHdpZHRoIG9mIHRoZSBhdmFpbGFibGUgc3BhY2UuXHJcbiAgICAgICAgICAgICAgICBmb250U2l6ZSA9IF90aGlzLmdldERvbUVsZW1lbnQoKS53aWR0aCgpIC8gU3VidGl0bGVPdmVybGF5LkNFQTYwOF9OVU1fQ09MVU1OUyAvIGZvbnRTaXplUmF0aW87XHJcbiAgICAgICAgICAgICAgICBmb250TGV0dGVyU3BhY2luZyA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gVXBkYXRlIGZvbnQtc2l6ZSBvZiBhbGwgYWN0aXZlIHN1YnRpdGxlIGxhYmVsc1xyXG4gICAgICAgICAgICBmb3IgKHZhciBfaSA9IDAsIF9hID0gX3RoaXMuZ2V0Q29tcG9uZW50cygpOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICAgICAgdmFyIGxhYmVsID0gX2FbX2ldO1xyXG4gICAgICAgICAgICAgICAgaWYgKGxhYmVsIGluc3RhbmNlb2YgU3VidGl0bGVMYWJlbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsLmdldERvbUVsZW1lbnQoKS5jc3Moe1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAnZm9udC1zaXplJzogZm9udFNpemUgKyBcInB4XCIsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICdsZXR0ZXItc3BhY2luZyc6IGZvbnRMZXR0ZXJTcGFjaW5nICsgXCJweFwiLFxyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9QTEFZRVJfUkVTSVpFLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChlbmFibGVkKSB7XHJcbiAgICAgICAgICAgICAgICB1cGRhdGVDRUE2MDhGb250U2l6ZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZm9udFNpemVDYWxjdWxhdGlvblJlcXVpcmVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHBsYXllci5hZGRFdmVudEhhbmRsZXIocGxheWVyLkVWRU5ULk9OX0NVRV9FTlRFUiwgZnVuY3Rpb24gKGV2ZW50KSB7XHJcbiAgICAgICAgICAgIHZhciBpc0NFQTYwOCA9IGV2ZW50LnBvc2l0aW9uICE9IG51bGw7XHJcbiAgICAgICAgICAgIGlmICghaXNDRUE2MDgpIHtcclxuICAgICAgICAgICAgICAgIC8vIFNraXAgYWxsIG5vbi1DRUE2MDggY3Vlc1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHZhciBsYWJlbHMgPSBfdGhpcy5zdWJ0aXRsZU1hbmFnZXIuZ2V0Q3VlcyhldmVudCk7XHJcbiAgICAgICAgICAgIGlmICghZW5hYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgZW5hYmxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBfdGhpcy5nZXREb21FbGVtZW50KCkuYWRkQ2xhc3MoX3RoaXMucHJlZml4Q3NzKFN1YnRpdGxlT3ZlcmxheS5DTEFTU19DRUFfNjA4KSk7XHJcbiAgICAgICAgICAgICAgICAvLyBXZSBjb25kaXRpb25hbGx5IHVwZGF0ZSB0aGUgZm9udCBzaXplIGJ5IHRoaXMgZmxhZyBoZXJlIHRvIGF2b2lkIHVwZGF0aW5nIGV2ZXJ5IHRpbWUgYSBzdWJ0aXRsZVxyXG4gICAgICAgICAgICAgICAgLy8gaXMgYWRkZWQgaW50byBhbiBlbXB0eSBvdmVybGF5LiBCZWNhdXNlIHdlIHJlc2V0IHRoZSBvdmVybGF5IHdoZW4gYWxsIHN1YnRpdGxlcyBhcmUgZ29uZSwgdGhpc1xyXG4gICAgICAgICAgICAgICAgLy8gd291bGQgdHJpZ2dlciBhbiB1bm5lY2Vzc2FyeSB1cGRhdGUgZXZlcnkgdGltZSwgYnV0IGl0J3Mgb25seSByZXF1aXJlZCB1bmRlciBjZXJ0YWluIGNvbmRpdGlvbnMsXHJcbiAgICAgICAgICAgICAgICAvLyBlLmcuIGFmdGVyIHRoZSBwbGF5ZXIgc2l6ZSBoYXMgY2hhbmdlZC5cclxuICAgICAgICAgICAgICAgIGlmIChmb250U2l6ZUNhbGN1bGF0aW9uUmVxdWlyZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICB1cGRhdGVDRUE2MDhGb250U2l6ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvbnRTaXplQ2FsY3VsYXRpb25SZXF1aXJlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGZvciAodmFyIF9pID0gMCwgbGFiZWxzXzEgPSBsYWJlbHM7IF9pIDwgbGFiZWxzXzEubGVuZ3RoOyBfaSsrKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbGFiZWwgPSBsYWJlbHNfMVtfaV07XHJcbiAgICAgICAgICAgICAgICBsYWJlbC5nZXREb21FbGVtZW50KCkuY3NzKHtcclxuICAgICAgICAgICAgICAgICAgICAnbGVmdCc6IGV2ZW50LnBvc2l0aW9uLmNvbHVtbiAqIFN1YnRpdGxlT3ZlcmxheS5DRUE2MDhfQ09MVU1OX09GRlNFVCArIFwiJVwiLFxyXG4gICAgICAgICAgICAgICAgICAgICd0b3AnOiBldmVudC5wb3NpdGlvbi5yb3cgKiBTdWJ0aXRsZU92ZXJsYXkuQ0VBNjA4X1JPV19PRkZTRVQgKyBcIiVcIixcclxuICAgICAgICAgICAgICAgICAgICAnZm9udC1zaXplJzogZm9udFNpemUgKyBcInB4XCIsXHJcbiAgICAgICAgICAgICAgICAgICAgJ2xldHRlci1zcGFjaW5nJzogZm9udExldHRlclNwYWNpbmcgKyBcInB4XCIsXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHZhciByZXNldCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3RoaXMuZ2V0RG9tRWxlbWVudCgpLnJlbW92ZUNsYXNzKF90aGlzLnByZWZpeENzcyhTdWJ0aXRsZU92ZXJsYXkuQ0xBU1NfQ0VBXzYwOCkpO1xyXG4gICAgICAgICAgICBlbmFibGVkID0gZmFsc2U7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBwbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKHBsYXllci5FVkVOVC5PTl9DVUVfRVhJVCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoIV90aGlzLnN1YnRpdGxlTWFuYWdlci5oYXNDdWVzKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBEaXNhYmxlIENFQS02MDggbW9kZSB3aGVuIGFsbCBzdWJ0aXRsZXMgYXJlIGdvbmUgKHRvIGFsbG93IGNvcnJlY3QgZm9ybWF0dGluZyBhbmRcclxuICAgICAgICAgICAgICAgIC8vIGRpc3BsYXkgb2Ygb3RoZXIgdHlwZXMgb2Ygc3VidGl0bGVzLCBlLmcuIHRoZSBmb3JtYXR0aW5nIHByZXZpZXcgc3VidGl0bGUpXHJcbiAgICAgICAgICAgICAgICByZXNldCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fU09VUkNFX1VOTE9BREVELCByZXNldCk7XHJcbiAgICAgICAgcGxheWVyLmFkZEV2ZW50SGFuZGxlcihwbGF5ZXIuRVZFTlQuT05fU1VCVElUTEVfQ0hBTkdFRCwgcmVzZXQpO1xyXG4gICAgfTtcclxuICAgIFN1YnRpdGxlT3ZlcmxheS5wcm90b3R5cGUuZW5hYmxlUHJldmlld1N1YnRpdGxlTGFiZWwgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5wcmV2aWV3U3VidGl0bGVBY3RpdmUgPSB0cnVlO1xyXG4gICAgICAgIGlmICghdGhpcy5zdWJ0aXRsZU1hbmFnZXIuaGFzQ3Vlcykge1xyXG4gICAgICAgICAgICB0aGlzLmFkZENvbXBvbmVudCh0aGlzLnByZXZpZXdTdWJ0aXRsZSk7XHJcbiAgICAgICAgICAgIHRoaXMudXBkYXRlQ29tcG9uZW50cygpO1xyXG4gICAgICAgICAgICB0aGlzLnNob3coKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgU3VidGl0bGVPdmVybGF5LnByb3RvdHlwZS5yZW1vdmVQcmV2aWV3U3VidGl0bGVMYWJlbCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLnByZXZpZXdTdWJ0aXRsZUFjdGl2ZSA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMucmVtb3ZlQ29tcG9uZW50KHRoaXMucHJldmlld1N1YnRpdGxlKTtcclxuICAgICAgICB0aGlzLnVwZGF0ZUNvbXBvbmVudHMoKTtcclxuICAgIH07XHJcbiAgICByZXR1cm4gU3VidGl0bGVPdmVybGF5O1xyXG59KGNvbnRhaW5lcl8xLkNvbnRhaW5lcikpO1xyXG5TdWJ0aXRsZU92ZXJsYXkuQ0xBU1NfQ09OVFJPTEJBUl9WSVNJQkxFID0gJ2NvbnRyb2xiYXItdmlzaWJsZSc7XHJcblN1YnRpdGxlT3ZlcmxheS5DTEFTU19DRUFfNjA4ID0gJ2NlYTYwOCc7XHJcbi8vIFRoZSBudW1iZXIgb2Ygcm93cyBpbiBhIGNlYTYwOCBncmlkXHJcblN1YnRpdGxlT3ZlcmxheS5DRUE2MDhfTlVNX1JPV1MgPSAxNTtcclxuLy8gVGhlIG51bWJlciBvZiBjb2x1bW5zIGluIGEgY2VhNjA4IGdyaWRcclxuU3VidGl0bGVPdmVybGF5LkNFQTYwOF9OVU1fQ09MVU1OUyA9IDMyO1xyXG4vLyBUaGUgb2Zmc2V0IGluIHBlcmNlbnQgZm9yIG9uZSByb3cgKHdoaWNoIGlzIGFsc28gdGhlIGhlaWdodCBvZiBhIHJvdylcclxuU3VidGl0bGVPdmVybGF5LkNFQTYwOF9ST1dfT0ZGU0VUID0gMTAwIC8gU3VidGl0bGVPdmVybGF5LkNFQTYwOF9OVU1fUk9XUztcclxuLy8gVGhlIG9mZnNldCBpbiBwZXJjZW50IGZvciBvbmUgY29sdW1uICh3aGljaCBpcyBhbHNvIHRoZSB3aWR0aCBvZiBhIGNvbHVtbilcclxuU3VidGl0bGVPdmVybGF5LkNFQTYwOF9DT0xVTU5fT0ZGU0VUID0gMTAwIC8gU3VidGl0bGVPdmVybGF5LkNFQTYwOF9OVU1fQ09MVU1OUztcclxuZXhwb3J0cy5TdWJ0aXRsZU92ZXJsYXkgPSBTdWJ0aXRsZU92ZXJsYXk7XHJcbnZhciBTdWJ0aXRsZUxhYmVsID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIF9fZXh0ZW5kcyhTdWJ0aXRsZUxhYmVsLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gU3VidGl0bGVMYWJlbChjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktc3VidGl0bGUtbGFiZWwnLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIFN1YnRpdGxlTGFiZWw7XHJcbn0obGFiZWxfMS5MYWJlbCkpO1xyXG52YXIgQWN0aXZlU3VidGl0bGVNYW5hZ2VyID0gKGZ1bmN0aW9uICgpIHtcclxuICAgIGZ1bmN0aW9uIEFjdGl2ZVN1YnRpdGxlTWFuYWdlcigpIHtcclxuICAgICAgICB0aGlzLmFjdGl2ZVN1YnRpdGxlQ3VlTWFwID0ge307XHJcbiAgICAgICAgdGhpcy5hY3RpdmVTdWJ0aXRsZUN1ZUNvdW50ID0gMDtcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogQ2FsY3VsYXRlcyBhIHVuaXF1ZSBJRCBmb3IgYSBzdWJ0aXRsZSBjdWUsIHdoaWNoIGlzIG5lZWRlZCB0byBhc3NvY2lhdGUgYW4gT05fQ1VFX0VOVEVSIHdpdGggaXRzIE9OX0NVRV9FWElUXHJcbiAgICAgKiBldmVudCBzbyB3ZSBjYW4gcmVtb3ZlIHRoZSBjb3JyZWN0IHN1YnRpdGxlIGluIE9OX0NVRV9FWElUIHdoZW4gbXVsdGlwbGUgc3VidGl0bGVzIGFyZSBhY3RpdmUgYXQgdGhlIHNhbWUgdGltZS5cclxuICAgICAqIFRoZSBzdGFydCB0aW1lIHBsdXMgdGhlIHRleHQgc2hvdWxkIG1ha2UgYSB1bmlxdWUgaWRlbnRpZmllciwgYW5kIGluIHRoZSBvbmx5IGNhc2Ugd2hlcmUgYSBjb2xsaXNpb25cclxuICAgICAqIGNhbiBoYXBwZW4sIHR3byBzaW1pbGFyIHRleHRzIHdpbGwgYmUgZGlzcGxheWVkIGF0IGEgc2ltaWxhciB0aW1lIGFuZCBhIHNpbWlsYXIgcG9zaXRpb24gKG9yIHdpdGhvdXQgcG9zaXRpb24pLlxyXG4gICAgICogVGhlIHN0YXJ0IHRpbWUgc2hvdWxkIGFsd2F5cyBiZSBrbm93biwgYmVjYXVzZSBpdCBpcyByZXF1aXJlZCB0byBzY2hlZHVsZSB0aGUgT05fQ1VFX0VOVEVSIGV2ZW50LiBUaGUgZW5kIHRpbWVcclxuICAgICAqIG11c3Qgbm90IG5lY2Vzc2FyaWx5IGJlIGtub3duIGFuZCB0aGVyZWZvcmUgY2Fubm90IGJlIHVzZWQgZm9yIHRoZSBJRC5cclxuICAgICAqIEBwYXJhbSBldmVudFxyXG4gICAgICogQHJldHVybiB7c3RyaW5nfVxyXG4gICAgICovXHJcbiAgICBBY3RpdmVTdWJ0aXRsZU1hbmFnZXIuY2FsY3VsYXRlSWQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICB2YXIgaWQgPSBldmVudC5zdGFydCArICctJyArIGV2ZW50LnRleHQ7XHJcbiAgICAgICAgaWYgKGV2ZW50LnBvc2l0aW9uKSB7XHJcbiAgICAgICAgICAgIGlkICs9ICctJyArIGV2ZW50LnBvc2l0aW9uLnJvdyArICctJyArIGV2ZW50LnBvc2l0aW9uLmNvbHVtbjtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGlkO1xyXG4gICAgfTtcclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBhIHN1YnRpdGxlIGN1ZSB0byB0aGUgbWFuYWdlciBhbmQgcmV0dXJucyB0aGUgbGFiZWwgdGhhdCBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIHN1YnRpdGxlIG92ZXJsYXkuXHJcbiAgICAgKiBAcGFyYW0gZXZlbnRcclxuICAgICAqIEByZXR1cm4ge1N1YnRpdGxlTGFiZWx9XHJcbiAgICAgKi9cclxuICAgIEFjdGl2ZVN1YnRpdGxlTWFuYWdlci5wcm90b3R5cGUuY3VlRW50ZXIgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICB2YXIgaWQgPSBBY3RpdmVTdWJ0aXRsZU1hbmFnZXIuY2FsY3VsYXRlSWQoZXZlbnQpO1xyXG4gICAgICAgIHZhciBsYWJlbCA9IG5ldyBTdWJ0aXRsZUxhYmVsKHtcclxuICAgICAgICAgICAgLy8gUHJlZmVyIHRoZSBIVE1MIHN1YnRpdGxlIHRleHQgaWYgc2V0LCBlbHNlIHVzZSB0aGUgcGxhaW4gdGV4dFxyXG4gICAgICAgICAgICB0ZXh0OiBldmVudC5odG1sIHx8IGV2ZW50LnRleHQsXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgLy8gQ3JlYXRlIGFycmF5IGZvciBpZCBpZiBpdCBkb2VzIG5vdCBleGlzdFxyXG4gICAgICAgIHRoaXMuYWN0aXZlU3VidGl0bGVDdWVNYXBbaWRdID0gdGhpcy5hY3RpdmVTdWJ0aXRsZUN1ZU1hcFtpZF0gfHwgW107XHJcbiAgICAgICAgLy8gQWRkIGN1ZVxyXG4gICAgICAgIHRoaXMuYWN0aXZlU3VidGl0bGVDdWVNYXBbaWRdLnB1c2goeyBldmVudDogZXZlbnQsIGxhYmVsOiBsYWJlbCB9KTtcclxuICAgICAgICB0aGlzLmFjdGl2ZVN1YnRpdGxlQ3VlQ291bnQrKztcclxuICAgICAgICByZXR1cm4gbGFiZWw7XHJcbiAgICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBsYWJlbCBhc3NvY2lhdGVkIHdpdGggYW4gYWxyZWFkeSBhZGRlZCBjdWUuXHJcbiAgICAgKiBAcGFyYW0gZXZlbnRcclxuICAgICAqIEByZXR1cm4ge1N1YnRpdGxlTGFiZWx9XHJcbiAgICAgKi9cclxuICAgIEFjdGl2ZVN1YnRpdGxlTWFuYWdlci5wcm90b3R5cGUuZ2V0Q3VlcyA9IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgIHZhciBpZCA9IEFjdGl2ZVN1YnRpdGxlTWFuYWdlci5jYWxjdWxhdGVJZChldmVudCk7XHJcbiAgICAgICAgdmFyIGFjdGl2ZVN1YnRpdGxlQ3VlcyA9IHRoaXMuYWN0aXZlU3VidGl0bGVDdWVNYXBbaWRdO1xyXG4gICAgICAgIGlmIChhY3RpdmVTdWJ0aXRsZUN1ZXMgJiYgYWN0aXZlU3VidGl0bGVDdWVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFjdGl2ZVN1YnRpdGxlQ3Vlcy5tYXAoZnVuY3Rpb24gKGN1ZSkgeyByZXR1cm4gY3VlLmxhYmVsOyB9KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIFJlbW92ZXMgdGhlIHN1YnRpdGxlIGN1ZSBmcm9tIHRoZSBtYW5hZ2VyIGFuZCByZXR1cm5zIHRoZSBsYWJlbCB0aGF0IHNob3VsZCBiZSByZW1vdmVkIGZyb20gdGhlIHN1YnRpdGxlIG92ZXJsYXksXHJcbiAgICAgKiBvciBudWxsIGlmIHRoZXJlIGlzIG5vIGFzc29jaWF0ZWQgbGFiZWwgZXhpc3RpbmcgKGUuZy4gYmVjYXVzZSBhbGwgbGFiZWxzIGhhdmUgYmVlbiB7QGxpbmsgI2NsZWFyIGNsZWFyZWR9LlxyXG4gICAgICogQHBhcmFtIGV2ZW50XHJcbiAgICAgKiBAcmV0dXJuIHtTdWJ0aXRsZUxhYmVsfG51bGx9XHJcbiAgICAgKi9cclxuICAgIEFjdGl2ZVN1YnRpdGxlTWFuYWdlci5wcm90b3R5cGUuY3VlRXhpdCA9IGZ1bmN0aW9uIChldmVudCkge1xyXG4gICAgICAgIHZhciBpZCA9IEFjdGl2ZVN1YnRpdGxlTWFuYWdlci5jYWxjdWxhdGVJZChldmVudCk7XHJcbiAgICAgICAgdmFyIGFjdGl2ZVN1YnRpdGxlQ3VlcyA9IHRoaXMuYWN0aXZlU3VidGl0bGVDdWVNYXBbaWRdO1xyXG4gICAgICAgIGlmIChhY3RpdmVTdWJ0aXRsZUN1ZXMgJiYgYWN0aXZlU3VidGl0bGVDdWVzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgLy8gUmVtb3ZlIGN1ZVxyXG4gICAgICAgICAgICAvKiBXZSBhcHBseSB0aGUgRklGTyBhcHByb2FjaCBoZXJlIGFuZCByZW1vdmUgdGhlIG9sZGVzdCBjdWUgZnJvbSB0aGUgYXNzb2NpYXRlZCBpZC4gV2hlbiB0aGVyZSBhcmUgbXVsdGlwbGUgY3Vlc1xyXG4gICAgICAgICAgICAgKiB3aXRoIHRoZSBzYW1lIGlkLCB0aGVyZSBpcyBubyB3YXkgdG8ga25vdyB3aGljaCBvbmUgb2YgdGhlIGN1ZXMgaXMgdG8gYmUgZGVsZXRlZCwgc28gd2UganVzdCBob3BlIHRoYXQgRklGT1xyXG4gICAgICAgICAgICAgKiB3b3JrcyBmaW5lLiBUaGVvcmV0aWNhbGx5IGl0IGNhbiBoYXBwZW4gdGhhdCB0d28gY3VlcyB3aXRoIGNvbGxpZGluZyBpZHMgYXJlIHJlbW92ZWQgYXQgZGlmZmVyZW50IHRpbWVzLCBpblxyXG4gICAgICAgICAgICAgKiB0aGUgd3Jvbmcgb3JkZXIuIFRoaXMgcmFyZSBjYXNlIGhhcyB5ZXQgdG8gYmUgb2JzZXJ2ZWQuIElmIGl0IGV2ZXIgZ2V0cyBhbiBpc3N1ZSwgd2UgY2FuIHRha2UgdGhlIHVuc3RhYmxlXHJcbiAgICAgICAgICAgICAqIGN1ZSBlbmQgdGltZSAod2hpY2ggY2FuIGNoYW5nZSBiZXR3ZWVuIE9OX0NVRV9FTlRFUiBhbmQgT05fQ1VFX0VYSVQgSU4gT05fQ1VFX1VQREFURSkgYW5kIHVzZSBpdCBhcyBhblxyXG4gICAgICAgICAgICAgKiBhZGRpdGlvbmFsIGhpbnQgdG8gdHJ5IGFuZCByZW1vdmUgdGhlIGNvcnJlY3Qgb25lIG9mIHRoZSBjb2xsaWRpbmcgY3Vlcy5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIHZhciBhY3RpdmVTdWJ0aXRsZUN1ZSA9IGFjdGl2ZVN1YnRpdGxlQ3Vlcy5zaGlmdCgpO1xyXG4gICAgICAgICAgICB0aGlzLmFjdGl2ZVN1YnRpdGxlQ3VlQ291bnQtLTtcclxuICAgICAgICAgICAgcmV0dXJuIGFjdGl2ZVN1YnRpdGxlQ3VlLmxhYmVsO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShBY3RpdmVTdWJ0aXRsZU1hbmFnZXIucHJvdG90eXBlLCBcImN1ZUNvdW50XCIsIHtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgYWN0aXZlIHN1YnRpdGxlIGN1ZXMuXHJcbiAgICAgICAgICogQHJldHVybiB7bnVtYmVyfVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAvLyBXZSBleHBsaWNpdGx5IGNvdW50IHRoZSBjdWVzIHRvIHNhdmUgYW4gQXJyYXkucmVkdWNlIG9uIGV2ZXJ5IGN1ZUNvdW50IGNhbGwgKHdoaWNoIGNhbiBoYXBwZW4gZnJlcXVlbnRseSlcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuYWN0aXZlU3VidGl0bGVDdWVDb3VudDtcclxuICAgICAgICB9LFxyXG4gICAgICAgIGVudW1lcmFibGU6IHRydWUsXHJcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXHJcbiAgICB9KTtcclxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShBY3RpdmVTdWJ0aXRsZU1hbmFnZXIucHJvdG90eXBlLCBcImhhc0N1ZXNcIiwge1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiB0aGVyZSBhcmUgYWN0aXZlIHN1YnRpdGxlIGN1ZXMsIGVsc2UgZmFsc2UuXHJcbiAgICAgICAgICogQHJldHVybiB7Ym9vbGVhbn1cclxuICAgICAgICAgKi9cclxuICAgICAgICBnZXQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3VlQ291bnQgPiAwO1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcclxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcclxuICAgIH0pO1xyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIGFsbCBzdWJ0aXRsZSBjdWVzIGZyb20gdGhlIG1hbmFnZXIuXHJcbiAgICAgKi9cclxuICAgIEFjdGl2ZVN1YnRpdGxlTWFuYWdlci5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5hY3RpdmVTdWJ0aXRsZUN1ZU1hcCA9IHt9O1xyXG4gICAgICAgIHRoaXMuYWN0aXZlU3VidGl0bGVDdWVDb3VudCA9IDA7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIEFjdGl2ZVN1YnRpdGxlTWFuYWdlcjtcclxufSgpKTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3N1YnRpdGxlb3ZlcmxheS50c1xuLy8gbW9kdWxlIGlkID0gNDBcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBjb21wb25lbnRfMSA9IHJlcXVpcmUoXCIuL2NvbXBvbmVudFwiKTtcclxudmFyIGRvbV8xID0gcmVxdWlyZShcIi4uL2RvbVwiKTtcclxuLyoqXHJcbiAqIEFuaW1hdGVkIGFuYWxvZyBUViBzdGF0aWMgbm9pc2UuXHJcbiAqL1xyXG52YXIgVHZOb2lzZUNhbnZhcyA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoVHZOb2lzZUNhbnZhcywgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIFR2Tm9pc2VDYW52YXMoY29uZmlnKSB7XHJcbiAgICAgICAgaWYgKGNvbmZpZyA9PT0gdm9pZCAwKSB7IGNvbmZpZyA9IHt9OyB9XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLmNhbnZhc1dpZHRoID0gMTYwO1xyXG4gICAgICAgIF90aGlzLmNhbnZhc0hlaWdodCA9IDkwO1xyXG4gICAgICAgIF90aGlzLmludGVyZmVyZW5jZUhlaWdodCA9IDUwO1xyXG4gICAgICAgIF90aGlzLmxhc3RGcmFtZVVwZGF0ZSA9IDA7XHJcbiAgICAgICAgX3RoaXMuZnJhbWVJbnRlcnZhbCA9IDYwO1xyXG4gICAgICAgIF90aGlzLnVzZUFuaW1hdGlvbkZyYW1lID0gISF3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lO1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLXR2bm9pc2VjYW52YXMnLFxyXG4gICAgICAgIH0sIF90aGlzLmNvbmZpZyk7XHJcbiAgICAgICAgcmV0dXJuIF90aGlzO1xyXG4gICAgfVxyXG4gICAgVHZOb2lzZUNhbnZhcy5wcm90b3R5cGUudG9Eb21FbGVtZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNhbnZhcyA9IG5ldyBkb21fMS5ET00oJ2NhbnZhcycsIHsgJ2NsYXNzJzogdGhpcy5nZXRDc3NDbGFzc2VzKCkgfSk7XHJcbiAgICB9O1xyXG4gICAgVHZOb2lzZUNhbnZhcy5wcm90b3R5cGUuc3RhcnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5jYW52YXNFbGVtZW50ID0gdGhpcy5jYW52YXMuZ2V0KDApO1xyXG4gICAgICAgIHRoaXMuY2FudmFzQ29udGV4dCA9IHRoaXMuY2FudmFzRWxlbWVudC5nZXRDb250ZXh0KCcyZCcpO1xyXG4gICAgICAgIHRoaXMubm9pc2VBbmltYXRpb25XaW5kb3dQb3MgPSAtdGhpcy5jYW52YXNIZWlnaHQ7XHJcbiAgICAgICAgdGhpcy5sYXN0RnJhbWVVcGRhdGUgPSAwO1xyXG4gICAgICAgIHRoaXMuY2FudmFzRWxlbWVudC53aWR0aCA9IHRoaXMuY2FudmFzV2lkdGg7XHJcbiAgICAgICAgdGhpcy5jYW52YXNFbGVtZW50LmhlaWdodCA9IHRoaXMuY2FudmFzSGVpZ2h0O1xyXG4gICAgICAgIHRoaXMucmVuZGVyRnJhbWUoKTtcclxuICAgIH07XHJcbiAgICBUdk5vaXNlQ2FudmFzLnByb3RvdHlwZS5zdG9wID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmICh0aGlzLnVzZUFuaW1hdGlvbkZyYW1lKSB7XHJcbiAgICAgICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKHRoaXMuZnJhbWVVcGRhdGVIYW5kbGVySWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuZnJhbWVVcGRhdGVIYW5kbGVySWQpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICBUdk5vaXNlQ2FudmFzLnByb3RvdHlwZS5yZW5kZXJGcmFtZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAvLyBUaGlzIGNvZGUgaGFzIGJlZW4gY29waWVkIGZyb20gdGhlIHBsYXllciBjb250cm9scy5qcyBhbmQgc2ltcGxpZmllZFxyXG4gICAgICAgIGlmICh0aGlzLmxhc3RGcmFtZVVwZGF0ZSArIHRoaXMuZnJhbWVJbnRlcnZhbCA+IG5ldyBEYXRlKCkuZ2V0VGltZSgpKSB7XHJcbiAgICAgICAgICAgIC8vIEl0J3MgdG9vIGVhcmx5IHRvIHJlbmRlciB0aGUgbmV4dCBmcmFtZVxyXG4gICAgICAgICAgICB0aGlzLnNjaGVkdWxlTmV4dFJlbmRlcigpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBjdXJyZW50UGl4ZWxPZmZzZXQ7XHJcbiAgICAgICAgdmFyIGNhbnZhc1dpZHRoID0gdGhpcy5jYW52YXNXaWR0aDtcclxuICAgICAgICB2YXIgY2FudmFzSGVpZ2h0ID0gdGhpcy5jYW52YXNIZWlnaHQ7XHJcbiAgICAgICAgLy8gQ3JlYXRlIHRleHR1cmVcclxuICAgICAgICB2YXIgbm9pc2VJbWFnZSA9IHRoaXMuY2FudmFzQ29udGV4dC5jcmVhdGVJbWFnZURhdGEoY2FudmFzV2lkdGgsIGNhbnZhc0hlaWdodCk7XHJcbiAgICAgICAgLy8gRmlsbCB0ZXh0dXJlIHdpdGggbm9pc2VcclxuICAgICAgICBmb3IgKHZhciB5ID0gMDsgeSA8IGNhbnZhc0hlaWdodDsgeSsrKSB7XHJcbiAgICAgICAgICAgIGZvciAodmFyIHggPSAwOyB4IDwgY2FudmFzV2lkdGg7IHgrKykge1xyXG4gICAgICAgICAgICAgICAgY3VycmVudFBpeGVsT2Zmc2V0ID0gKGNhbnZhc1dpZHRoICogeSAqIDQpICsgeCAqIDQ7XHJcbiAgICAgICAgICAgICAgICBub2lzZUltYWdlLmRhdGFbY3VycmVudFBpeGVsT2Zmc2V0XSA9IE1hdGgucmFuZG9tKCkgKiAyNTU7XHJcbiAgICAgICAgICAgICAgICBpZiAoeSA8IHRoaXMubm9pc2VBbmltYXRpb25XaW5kb3dQb3MgfHwgeSA+IHRoaXMubm9pc2VBbmltYXRpb25XaW5kb3dQb3MgKyB0aGlzLmludGVyZmVyZW5jZUhlaWdodCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG5vaXNlSW1hZ2UuZGF0YVtjdXJyZW50UGl4ZWxPZmZzZXRdICo9IDAuODU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBub2lzZUltYWdlLmRhdGFbY3VycmVudFBpeGVsT2Zmc2V0ICsgMV0gPSBub2lzZUltYWdlLmRhdGFbY3VycmVudFBpeGVsT2Zmc2V0XTtcclxuICAgICAgICAgICAgICAgIG5vaXNlSW1hZ2UuZGF0YVtjdXJyZW50UGl4ZWxPZmZzZXQgKyAyXSA9IG5vaXNlSW1hZ2UuZGF0YVtjdXJyZW50UGl4ZWxPZmZzZXRdO1xyXG4gICAgICAgICAgICAgICAgbm9pc2VJbWFnZS5kYXRhW2N1cnJlbnRQaXhlbE9mZnNldCArIDNdID0gNTA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gUHV0IHRleHR1cmUgb250byBjYW52YXNcclxuICAgICAgICB0aGlzLmNhbnZhc0NvbnRleHQucHV0SW1hZ2VEYXRhKG5vaXNlSW1hZ2UsIDAsIDApO1xyXG4gICAgICAgIHRoaXMubGFzdEZyYW1lVXBkYXRlID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XHJcbiAgICAgICAgdGhpcy5ub2lzZUFuaW1hdGlvbldpbmRvd1BvcyArPSA3O1xyXG4gICAgICAgIGlmICh0aGlzLm5vaXNlQW5pbWF0aW9uV2luZG93UG9zID4gY2FudmFzSGVpZ2h0KSB7XHJcbiAgICAgICAgICAgIHRoaXMubm9pc2VBbmltYXRpb25XaW5kb3dQb3MgPSAtY2FudmFzSGVpZ2h0O1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLnNjaGVkdWxlTmV4dFJlbmRlcigpO1xyXG4gICAgfTtcclxuICAgIFR2Tm9pc2VDYW52YXMucHJvdG90eXBlLnNjaGVkdWxlTmV4dFJlbmRlciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAodGhpcy51c2VBbmltYXRpb25GcmFtZSkge1xyXG4gICAgICAgICAgICB0aGlzLmZyYW1lVXBkYXRlSGFuZGxlcklkID0gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSh0aGlzLnJlbmRlckZyYW1lLmJpbmQodGhpcykpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5mcmFtZVVwZGF0ZUhhbmRsZXJJZCA9IHNldFRpbWVvdXQodGhpcy5yZW5kZXJGcmFtZS5iaW5kKHRoaXMpLCB0aGlzLmZyYW1lSW50ZXJ2YWwpO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcbiAgICByZXR1cm4gVHZOb2lzZUNhbnZhcztcclxufShjb21wb25lbnRfMS5Db21wb25lbnQpKTtcclxuZXhwb3J0cy5Udk5vaXNlQ2FudmFzID0gVHZOb2lzZUNhbnZhcztcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL3R2bm9pc2VjYW52YXMudHNcbi8vIG1vZHVsZSBpZCA9IDQxXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgbGlzdHNlbGVjdG9yXzEgPSByZXF1aXJlKFwiLi9saXN0c2VsZWN0b3JcIik7XHJcbnZhciBkb21fMSA9IHJlcXVpcmUoXCIuLi9kb21cIik7XHJcbnZhciBJdGVtU2VsZWN0aW9uTGlzdCA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICBfX2V4dGVuZHMoSXRlbVNlbGVjdGlvbkxpc3QsIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBJdGVtU2VsZWN0aW9uTGlzdChjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIHRhZzogJ3VsJyxcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1pdGVtc2VsZWN0aW9ubGlzdCcsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBJdGVtU2VsZWN0aW9uTGlzdC5wcm90b3R5cGUuaXNBY3RpdmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuaXRlbXMubGVuZ3RoID4gMTtcclxuICAgIH07XHJcbiAgICBJdGVtU2VsZWN0aW9uTGlzdC5wcm90b3R5cGUudG9Eb21FbGVtZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBsaXN0RWxlbWVudCA9IG5ldyBkb21fMS5ET00oJ3VsJywge1xyXG4gICAgICAgICAgICAnaWQnOiB0aGlzLmNvbmZpZy5pZCxcclxuICAgICAgICAgICAgJ2NsYXNzJzogdGhpcy5nZXRDc3NDbGFzc2VzKCksXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgdGhpcy5saXN0RWxlbWVudCA9IGxpc3RFbGVtZW50O1xyXG4gICAgICAgIHRoaXMudXBkYXRlRG9tSXRlbXMoKTtcclxuICAgICAgICByZXR1cm4gbGlzdEVsZW1lbnQ7XHJcbiAgICB9O1xyXG4gICAgSXRlbVNlbGVjdGlvbkxpc3QucHJvdG90eXBlLnVwZGF0ZURvbUl0ZW1zID0gZnVuY3Rpb24gKHNlbGVjdGVkVmFsdWUpIHtcclxuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xyXG4gICAgICAgIGlmIChzZWxlY3RlZFZhbHVlID09PSB2b2lkIDApIHsgc2VsZWN0ZWRWYWx1ZSA9IG51bGw7IH1cclxuICAgICAgICAvLyBEZWxldGUgYWxsIGNoaWxkcmVuXHJcbiAgICAgICAgdGhpcy5saXN0RWxlbWVudC5lbXB0eSgpO1xyXG4gICAgICAgIHZhciBzZWxlY3RlZExpc3RJdGVtID0gbnVsbDtcclxuICAgICAgICB2YXIgc2VsZWN0SXRlbSA9IGZ1bmN0aW9uIChsaXN0SXRlbSkge1xyXG4gICAgICAgICAgICBsaXN0SXRlbS5hZGRDbGFzcyhfdGhpcy5wcmVmaXhDc3MoSXRlbVNlbGVjdGlvbkxpc3QuQ0xBU1NfU0VMRUNURUQpKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciBkZXNlbGVjdEl0ZW0gPSBmdW5jdGlvbiAobGlzdEl0ZW0pIHtcclxuICAgICAgICAgICAgbGlzdEl0ZW0ucmVtb3ZlQ2xhc3MoX3RoaXMucHJlZml4Q3NzKEl0ZW1TZWxlY3Rpb25MaXN0LkNMQVNTX1NFTEVDVEVEKSk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICB2YXIgX2xvb3BfMSA9IGZ1bmN0aW9uIChpdGVtKSB7XHJcbiAgICAgICAgICAgIHZhciBsaXN0SXRlbSA9IG5ldyBkb21fMS5ET00oJ2xpJywge1xyXG4gICAgICAgICAgICAgICAgJ3R5cGUnOiAnbGknLFxyXG4gICAgICAgICAgICAgICAgJ2NsYXNzJzogdGhpc18xLnByZWZpeENzcygndWktc2VsZWN0aW9ubGlzdGl0ZW0nKSxcclxuICAgICAgICAgICAgfSkuYXBwZW5kKG5ldyBkb21fMS5ET00oJ2EnLCB7fSkuaHRtbChpdGVtLmxhYmVsKSk7XHJcbiAgICAgICAgICAgIGlmICghc2VsZWN0ZWRMaXN0SXRlbSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkVmFsdWUgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkTGlzdEl0ZW0gPSBsaXN0SXRlbTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKFN0cmluZyhzZWxlY3RlZFZhbHVlKSA9PT0gaXRlbS5rZXkpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxlY3RlZExpc3RJdGVtID0gbGlzdEl0ZW07XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgLy8gSGFuZGxlIGxpc3QgaXRlbSBzZWxlY3Rpb25zXHJcbiAgICAgICAgICAgIGxpc3RJdGVtLm9uKCdjbGljaycsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIC8vIERlc2VsZWN0IHRoZSBwcmV2aW91cyBpdGVtIChpZiB0aGVyZSB3YXMgYSBzZWxlY3RlZCBpdGVtKVxyXG4gICAgICAgICAgICAgICAgaWYgKHNlbGVjdGVkTGlzdEl0ZW0pIHtcclxuICAgICAgICAgICAgICAgICAgICBkZXNlbGVjdEl0ZW0oc2VsZWN0ZWRMaXN0SXRlbSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAvLyBTZWxlY3QgdGhlIGNsaWNrZWQgaXRlbVxyXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRMaXN0SXRlbSA9IGxpc3RJdGVtO1xyXG4gICAgICAgICAgICAgICAgc2VsZWN0SXRlbShsaXN0SXRlbSk7XHJcbiAgICAgICAgICAgICAgICAvLyBGaXJlIHRoZSBldmVudFxyXG4gICAgICAgICAgICAgICAgX3RoaXMub25JdGVtU2VsZWN0ZWRFdmVudChpdGVtLmtleSwgZmFsc2UpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgLy8gU2VsZWN0IGRlZmF1bHQgaXRlbVxyXG4gICAgICAgICAgICBpZiAoc2VsZWN0ZWRMaXN0SXRlbSkge1xyXG4gICAgICAgICAgICAgICAgc2VsZWN0SXRlbShzZWxlY3RlZExpc3RJdGVtKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzXzEubGlzdEVsZW1lbnQuYXBwZW5kKGxpc3RJdGVtKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIHZhciB0aGlzXzEgPSB0aGlzO1xyXG4gICAgICAgIGZvciAodmFyIF9pID0gMCwgX2EgPSB0aGlzLml0ZW1zOyBfaSA8IF9hLmxlbmd0aDsgX2krKykge1xyXG4gICAgICAgICAgICB2YXIgaXRlbSA9IF9hW19pXTtcclxuICAgICAgICAgICAgX2xvb3BfMShpdGVtKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgSXRlbVNlbGVjdGlvbkxpc3QucHJvdG90eXBlLm9uSXRlbUFkZGVkRXZlbnQgPSBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLm9uSXRlbUFkZGVkRXZlbnQuY2FsbCh0aGlzLCB2YWx1ZSk7XHJcbiAgICAgICAgdGhpcy51cGRhdGVEb21JdGVtcyh0aGlzLnNlbGVjdGVkSXRlbSk7XHJcbiAgICB9O1xyXG4gICAgSXRlbVNlbGVjdGlvbkxpc3QucHJvdG90eXBlLm9uSXRlbVJlbW92ZWRFdmVudCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUub25JdGVtUmVtb3ZlZEV2ZW50LmNhbGwodGhpcywgdmFsdWUpO1xyXG4gICAgICAgIHRoaXMudXBkYXRlRG9tSXRlbXModGhpcy5zZWxlY3RlZEl0ZW0pO1xyXG4gICAgfTtcclxuICAgIEl0ZW1TZWxlY3Rpb25MaXN0LnByb3RvdHlwZS5vbkl0ZW1TZWxlY3RlZEV2ZW50ID0gZnVuY3Rpb24gKHZhbHVlLCB1cGRhdGVEb21JdGVtcykge1xyXG4gICAgICAgIGlmICh1cGRhdGVEb21JdGVtcyA9PT0gdm9pZCAwKSB7IHVwZGF0ZURvbUl0ZW1zID0gdHJ1ZTsgfVxyXG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUub25JdGVtU2VsZWN0ZWRFdmVudC5jYWxsKHRoaXMsIHZhbHVlKTtcclxuICAgICAgICBpZiAodXBkYXRlRG9tSXRlbXMpIHtcclxuICAgICAgICAgICAgdGhpcy51cGRhdGVEb21JdGVtcyh2YWx1ZSk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuICAgIHJldHVybiBJdGVtU2VsZWN0aW9uTGlzdDtcclxufShsaXN0c2VsZWN0b3JfMS5MaXN0U2VsZWN0b3IpKTtcclxuSXRlbVNlbGVjdGlvbkxpc3QuQ0xBU1NfU0VMRUNURUQgPSAnc2VsZWN0ZWQnO1xyXG5leHBvcnRzLkl0ZW1TZWxlY3Rpb25MaXN0ID0gSXRlbVNlbGVjdGlvbkxpc3Q7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9pdGVtc2VsZWN0aW9ubGlzdC50c1xuLy8gbW9kdWxlIGlkID0gNDJcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgKGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBleHRlbmRTdGF0aWNzID0gT2JqZWN0LnNldFByb3RvdHlwZU9mIHx8XHJcbiAgICAgICAgKHsgX19wcm90b19fOiBbXSB9IGluc3RhbmNlb2YgQXJyYXkgJiYgZnVuY3Rpb24gKGQsIGIpIHsgZC5fX3Byb3RvX18gPSBiOyB9KSB8fFxyXG4gICAgICAgIGZ1bmN0aW9uIChkLCBiKSB7IGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdOyB9O1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChkLCBiKSB7XHJcbiAgICAgICAgZXh0ZW5kU3RhdGljcyhkLCBiKTtcclxuICAgICAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cclxuICAgICAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XHJcbiAgICB9O1xyXG59KSgpO1xyXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XHJcbnZhciBidXR0b25fMSA9IHJlcXVpcmUoXCIuL2J1dHRvblwiKTtcclxuLyoqXHJcbiAqIEEgY2xpY2sgb3ZlcmxheSB0aGF0IG9wZW5zIGFuIHVybCBpbiBhIG5ldyB0YWIgaWYgY2xpY2tlZC5cclxuICovXHJcbnZhciBDbGlja092ZXJsYXkgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKENsaWNrT3ZlcmxheSwgX3N1cGVyKTtcclxuICAgIGZ1bmN0aW9uIENsaWNrT3ZlcmxheShjb25maWcpIHtcclxuICAgICAgICBpZiAoY29uZmlnID09PSB2b2lkIDApIHsgY29uZmlnID0ge307IH1cclxuICAgICAgICB2YXIgX3RoaXMgPSBfc3VwZXIuY2FsbCh0aGlzLCBjb25maWcpIHx8IHRoaXM7XHJcbiAgICAgICAgX3RoaXMuY29uZmlnID0gX3RoaXMubWVyZ2VDb25maWcoY29uZmlnLCB7XHJcbiAgICAgICAgICAgIGNzc0NsYXNzOiAndWktY2xpY2tvdmVybGF5JyxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIENsaWNrT3ZlcmxheS5wcm90b3R5cGUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmluaXRpYWxpemUuY2FsbCh0aGlzKTtcclxuICAgICAgICB0aGlzLnNldFVybCh0aGlzLmNvbmZpZy51cmwpO1xyXG4gICAgICAgIHZhciBlbGVtZW50ID0gdGhpcy5nZXREb21FbGVtZW50KCk7XHJcbiAgICAgICAgZWxlbWVudC5vbignY2xpY2snLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmIChlbGVtZW50LmRhdGEoJ3VybCcpKSB7XHJcbiAgICAgICAgICAgICAgICB3aW5kb3cub3BlbihlbGVtZW50LmRhdGEoJ3VybCcpLCAnX2JsYW5rJyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH07XHJcbiAgICAvKipcclxuICAgICAqIEdldHMgdGhlIFVSTCB0aGF0IHNob3VsZCBiZSBmb2xsb3dlZCB3aGVuIHRoZSB3YXRlcm1hcmsgaXMgY2xpY2tlZC5cclxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IHRoZSB3YXRlcm1hcmsgVVJMXHJcbiAgICAgKi9cclxuICAgIENsaWNrT3ZlcmxheS5wcm90b3R5cGUuZ2V0VXJsID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmdldERvbUVsZW1lbnQoKS5kYXRhKCd1cmwnKTtcclxuICAgIH07XHJcbiAgICBDbGlja092ZXJsYXkucHJvdG90eXBlLnNldFVybCA9IGZ1bmN0aW9uICh1cmwpIHtcclxuICAgICAgICBpZiAodXJsID09PSB1bmRlZmluZWQgfHwgdXJsID09IG51bGwpIHtcclxuICAgICAgICAgICAgdXJsID0gJyc7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZ2V0RG9tRWxlbWVudCgpLmRhdGEoJ3VybCcsIHVybCk7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIENsaWNrT3ZlcmxheTtcclxufShidXR0b25fMS5CdXR0b24pKTtcclxuZXhwb3J0cy5DbGlja092ZXJsYXkgPSBDbGlja092ZXJsYXk7XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9jbGlja292ZXJsYXkudHNcbi8vIG1vZHVsZSBpZCA9IDQzXG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgYnV0dG9uXzEgPSByZXF1aXJlKFwiLi9idXR0b25cIik7XHJcbnZhciBkb21fMSA9IHJlcXVpcmUoXCIuLi9kb21cIik7XHJcbi8qKlxyXG4gKiBBIGJ1dHRvbiB0byBwbGF5L3JlcGxheSBhIHZpZGVvLlxyXG4gKi9cclxudmFyIEh1Z2VSZXBsYXlCdXR0b24gPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKEh1Z2VSZXBsYXlCdXR0b24sIF9zdXBlcik7XHJcbiAgICBmdW5jdGlvbiBIdWdlUmVwbGF5QnV0dG9uKGNvbmZpZykge1xyXG4gICAgICAgIGlmIChjb25maWcgPT09IHZvaWQgMCkgeyBjb25maWcgPSB7fTsgfVxyXG4gICAgICAgIHZhciBfdGhpcyA9IF9zdXBlci5jYWxsKHRoaXMsIGNvbmZpZykgfHwgdGhpcztcclxuICAgICAgICBfdGhpcy5jb25maWcgPSBfdGhpcy5tZXJnZUNvbmZpZyhjb25maWcsIHtcclxuICAgICAgICAgICAgY3NzQ2xhc3M6ICd1aS1odWdlcmVwbGF5YnV0dG9uJyxcclxuICAgICAgICAgICAgdGV4dDogJ1JlcGxheScsXHJcbiAgICAgICAgfSwgX3RoaXMuY29uZmlnKTtcclxuICAgICAgICByZXR1cm4gX3RoaXM7XHJcbiAgICB9XHJcbiAgICBIdWdlUmVwbGF5QnV0dG9uLnByb3RvdHlwZS5jb25maWd1cmUgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNvbmZpZ3VyZS5jYWxsKHRoaXMsIHBsYXllciwgdWltYW5hZ2VyKTtcclxuICAgICAgICB0aGlzLm9uQ2xpY2suc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcGxheWVyLnBsYXkoJ3VpJyk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgSHVnZVJlcGxheUJ1dHRvbi5wcm90b3R5cGUudG9Eb21FbGVtZW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBidXR0b25FbGVtZW50ID0gX3N1cGVyLnByb3RvdHlwZS50b0RvbUVsZW1lbnQuY2FsbCh0aGlzKTtcclxuICAgICAgICAvLyBBZGQgY2hpbGQgdGhhdCBjb250YWlucyB0aGUgcGxheSBidXR0b24gaW1hZ2VcclxuICAgICAgICAvLyBTZXR0aW5nIHRoZSBpbWFnZSBkaXJlY3RseSBvbiB0aGUgYnV0dG9uIGRvZXMgbm90IHdvcmsgdG9nZXRoZXIgd2l0aCBzY2FsaW5nIGFuaW1hdGlvbnMsIGJlY2F1c2UgdGhlIGJ1dHRvblxyXG4gICAgICAgIC8vIGNhbiBjb3ZlciB0aGUgd2hvbGUgdmlkZW8gcGxheWVyIGFyZSBhbmQgc2NhbGluZyB3b3VsZCBleHRlbmQgaXQgYmV5b25kLiBCeSBhZGRpbmcgYW4gaW5uZXIgZWxlbWVudCwgY29uZmluZWRcclxuICAgICAgICAvLyB0byB0aGUgc2l6ZSBpZiB0aGUgaW1hZ2UsIGl0IGNhbiBzY2FsZSBpbnNpZGUgdGhlIHBsYXllciB3aXRob3V0IG92ZXJzaG9vdGluZy5cclxuICAgICAgICBidXR0b25FbGVtZW50LmFwcGVuZChuZXcgZG9tXzEuRE9NKCdkaXYnLCB7XHJcbiAgICAgICAgICAgICdjbGFzcyc6IHRoaXMucHJlZml4Q3NzKCdpbWFnZScpLFxyXG4gICAgICAgIH0pKTtcclxuICAgICAgICByZXR1cm4gYnV0dG9uRWxlbWVudDtcclxuICAgIH07XHJcbiAgICByZXR1cm4gSHVnZVJlcGxheUJ1dHRvbjtcclxufShidXR0b25fMS5CdXR0b24pKTtcclxuZXhwb3J0cy5IdWdlUmVwbGF5QnV0dG9uID0gSHVnZVJlcGxheUJ1dHRvbjtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9jb21wb25lbnRzL2h1Z2VyZXBsYXlidXR0b24udHNcbi8vIG1vZHVsZSBpZCA9IDQ0XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIlwidXNlIHN0cmljdFwiO1xyXG52YXIgX19leHRlbmRzID0gKHRoaXMgJiYgdGhpcy5fX2V4dGVuZHMpIHx8IChmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgZXh0ZW5kU3RhdGljcyA9IE9iamVjdC5zZXRQcm90b3R5cGVPZiB8fFxyXG4gICAgICAgICh7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5ICYmIGZ1bmN0aW9uIChkLCBiKSB7IGQuX19wcm90b19fID0gYjsgfSkgfHxcclxuICAgICAgICBmdW5jdGlvbiAoZCwgYikgeyBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTsgfTtcclxuICAgIHJldHVybiBmdW5jdGlvbiAoZCwgYikge1xyXG4gICAgICAgIGV4dGVuZFN0YXRpY3MoZCwgYik7XHJcbiAgICAgICAgZnVuY3Rpb24gX18oKSB7IHRoaXMuY29uc3RydWN0b3IgPSBkOyB9XHJcbiAgICAgICAgZC5wcm90b3R5cGUgPSBiID09PSBudWxsID8gT2JqZWN0LmNyZWF0ZShiKSA6IChfXy5wcm90b3R5cGUgPSBiLnByb3RvdHlwZSwgbmV3IF9fKCkpO1xyXG4gICAgfTtcclxufSkoKTtcclxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xyXG52YXIgYnV0dG9uXzEgPSByZXF1aXJlKFwiLi9idXR0b25cIik7XHJcbi8qKlxyXG4gKiBBIGJ1dHRvbiB0aGF0IGNsb3NlcyAoaGlkZXMpIGEgY29uZmlndXJlZCBjb21wb25lbnQuXHJcbiAqL1xyXG52YXIgQ2xvc2VCdXR0b24gPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgX19leHRlbmRzKENsb3NlQnV0dG9uLCBfc3VwZXIpO1xyXG4gICAgZnVuY3Rpb24gQ2xvc2VCdXR0b24oY29uZmlnKSB7XHJcbiAgICAgICAgdmFyIF90aGlzID0gX3N1cGVyLmNhbGwodGhpcywgY29uZmlnKSB8fCB0aGlzO1xyXG4gICAgICAgIF90aGlzLmNvbmZpZyA9IF90aGlzLm1lcmdlQ29uZmlnKGNvbmZpZywge1xyXG4gICAgICAgICAgICBjc3NDbGFzczogJ3VpLWNsb3NlYnV0dG9uJyxcclxuICAgICAgICAgICAgdGV4dDogJ0Nsb3NlJyxcclxuICAgICAgICB9LCBfdGhpcy5jb25maWcpO1xyXG4gICAgICAgIHJldHVybiBfdGhpcztcclxuICAgIH1cclxuICAgIENsb3NlQnV0dG9uLnByb3RvdHlwZS5jb25maWd1cmUgPSBmdW5jdGlvbiAocGxheWVyLCB1aW1hbmFnZXIpIHtcclxuICAgICAgICBfc3VwZXIucHJvdG90eXBlLmNvbmZpZ3VyZS5jYWxsKHRoaXMsIHBsYXllciwgdWltYW5hZ2VyKTtcclxuICAgICAgICB2YXIgY29uZmlnID0gdGhpcy5nZXRDb25maWcoKTtcclxuICAgICAgICB0aGlzLm9uQ2xpY2suc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgY29uZmlnLnRhcmdldC5oaWRlKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG4gICAgcmV0dXJuIENsb3NlQnV0dG9uO1xyXG59KGJ1dHRvbl8xLkJ1dHRvbikpO1xyXG5leHBvcnRzLkNsb3NlQnV0dG9uID0gQ2xvc2VCdXR0b247XHJcblxuXG5cbi8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV0VCUEFDSyBGT09URVJcbi8vIC4uL2xpYi91aW1hbmFnZXIvY29tcG9uZW50cy9jbG9zZWJ1dHRvbi50c1xuLy8gbW9kdWxlIGlkID0gNDVcbi8vIG1vZHVsZSBjaHVua3MgPSAwIiwiXCJ1c2Ugc3RyaWN0XCI7XHJcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcclxudmFyIFN0b3JhZ2VVdGlscztcclxuKGZ1bmN0aW9uIChTdG9yYWdlVXRpbHMpIHtcclxuICAgIHZhciBoYXNMb2NhbFN0b3JhZ2VDYWNoZTtcclxuICAgIGZ1bmN0aW9uIGhhc0xvY2FsU3RvcmFnZSgpIHtcclxuICAgICAgICBpZiAoaGFzTG9jYWxTdG9yYWdlQ2FjaGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGhhc0xvY2FsU3RvcmFnZUNhY2hlO1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBoYXNMb2NhbFN0b3JhZ2UgaXMgdXNlZCB0byBzYWZlbHkgZW5zdXJlIHdlIGNhbiB1c2UgbG9jYWxTdG9yYWdlXHJcbiAgICAgICAgLy8gdGFrZW4gZnJvbSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvV2ViX1N0b3JhZ2VfQVBJL1VzaW5nX3RoZV9XZWJfU3RvcmFnZV9BUEkjRmVhdHVyZS1kZXRlY3RpbmdfbG9jYWxTdG9yYWdlXHJcbiAgICAgICAgdmFyIHN0b3JhZ2UgPSB3aW5kb3dbJ2xvY2FsU3RvcmFnZSddO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHZhciB4ID0gJ19fc3RvcmFnZV90ZXN0X18nO1xyXG4gICAgICAgICAgICBzdG9yYWdlLnNldEl0ZW0oeCwgeCk7XHJcbiAgICAgICAgICAgIHN0b3JhZ2UucmVtb3ZlSXRlbSh4KTtcclxuICAgICAgICAgICAgaGFzTG9jYWxTdG9yYWdlQ2FjaGUgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBoYXNMb2NhbFN0b3JhZ2VDYWNoZSA9IGUgaW5zdGFuY2VvZiBET01FeGNlcHRpb24gJiYgKFxyXG4gICAgICAgICAgICAvLyBldmVyeXRoaW5nIGV4Y2VwdCBGaXJlZm94XHJcbiAgICAgICAgICAgIGUuY29kZSA9PT0gMjIgfHxcclxuICAgICAgICAgICAgICAgIC8vIEZpcmVmb3hcclxuICAgICAgICAgICAgICAgIGUuY29kZSA9PT0gMTAxNCB8fFxyXG4gICAgICAgICAgICAgICAgLy8gdGVzdCBuYW1lIGZpZWxkIHRvbywgYmVjYXVzZSBjb2RlIG1pZ2h0IG5vdCBiZSBwcmVzZW50XHJcbiAgICAgICAgICAgICAgICAvLyBldmVyeXRoaW5nIGV4Y2VwdCBGaXJlZm94XHJcbiAgICAgICAgICAgICAgICBlLm5hbWUgPT09ICdRdW90YUV4Y2VlZGVkRXJyb3InIHx8XHJcbiAgICAgICAgICAgICAgICAvLyBGaXJlZm94XHJcbiAgICAgICAgICAgICAgICBlLm5hbWUgPT09ICdOU19FUlJPUl9ET01fUVVPVEFfUkVBQ0hFRCcpICYmXHJcbiAgICAgICAgICAgICAgICAvLyBhY2tub3dsZWRnZSBRdW90YUV4Y2VlZGVkRXJyb3Igb25seSBpZiB0aGVyZSdzIHNvbWV0aGluZyBhbHJlYWR5IHN0b3JlZFxyXG4gICAgICAgICAgICAgICAgc3RvcmFnZS5sZW5ndGggIT09IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBoYXNMb2NhbFN0b3JhZ2VDYWNoZTtcclxuICAgIH1cclxuICAgIFN0b3JhZ2VVdGlscy5oYXNMb2NhbFN0b3JhZ2UgPSBoYXNMb2NhbFN0b3JhZ2U7XHJcbiAgICAvKipcclxuICAgICAqIFN0b3JlcyBhIHN0cmluZyBpdGVtIGludG8gbG9jYWxTdG9yYWdlLlxyXG4gICAgICogQHBhcmFtIGtleSB0aGUgaXRlbSdzIGtleVxyXG4gICAgICogQHBhcmFtIGRhdGEgdGhlIGl0ZW0ncyBkYXRhXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIHNldEl0ZW0oa2V5LCBkYXRhKSB7XHJcbiAgICAgICAgaWYgKFN0b3JhZ2VVdGlscy5oYXNMb2NhbFN0b3JhZ2UoKSkge1xyXG4gICAgICAgICAgICB3aW5kb3cubG9jYWxTdG9yYWdlLnNldEl0ZW0oa2V5LCBkYXRhKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBTdG9yYWdlVXRpbHMuc2V0SXRlbSA9IHNldEl0ZW07XHJcbiAgICAvKipcclxuICAgICAqIEdldHMgYW4gaXRlbSdzIHN0cmluZyB2YWx1ZSBmcm9tIHRoZSBsb2NhbFN0b3JhZ2UuXHJcbiAgICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkgdG8gbG9vayB1cCBpdHMgYXNzb2NpYXRlZCB2YWx1ZVxyXG4gICAgICogQHJldHVybiB7c3RyaW5nIHwgbnVsbH0gUmV0dXJucyB0aGUgc3RyaW5nIGlmIGZvdW5kLCBudWxsIGlmIHRoZXJlIGlzIG5vIGRhdGEgc3RvcmVkIGZvciB0aGUga2V5XHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIGdldEl0ZW0oa2V5KSB7XHJcbiAgICAgICAgaWYgKFN0b3JhZ2VVdGlscy5oYXNMb2NhbFN0b3JhZ2UoKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gd2luZG93LmxvY2FsU3RvcmFnZS5nZXRJdGVtKGtleSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBTdG9yYWdlVXRpbHMuZ2V0SXRlbSA9IGdldEl0ZW07XHJcbiAgICAvKipcclxuICAgICAqIFN0b3JlcyBhbiBvYmplY3QgaW50byBsb2NhbFN0b3JhZ2UuIFRoZSBvYmplY3Qgd2lsbCBiZSBzZXJpYWxpemVkIHRvIEpTT04uIFRoZSBmb2xsb3dpbmcgdHlwZXMgYXJlIHN1cHBvcnRlZFxyXG4gICAgICogaW4gYWRkaXRpb24gdG8gdGhlIGRlZmF1bHQgdHlwZXM6XHJcbiAgICAgKiAgLSBDb2xvclV0aWxzLkNvbG9yXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIGtleSB0aGUga2V5IHRvIHN0b3JlIHRoZSBkYXRhIHRvXHJcbiAgICAgKiBAcGFyYW0gZGF0YSB0aGUgb2JqZWN0IHRvIHN0b3JlXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIHNldE9iamVjdChrZXksIGRhdGEpIHtcclxuICAgICAgICBpZiAoU3RvcmFnZVV0aWxzLmhhc0xvY2FsU3RvcmFnZSgpKSB7XHJcbiAgICAgICAgICAgIHZhciBqc29uID0gSlNPTi5zdHJpbmdpZnkoZGF0YSk7XHJcbiAgICAgICAgICAgIHNldEl0ZW0oa2V5LCBqc29uKTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbiAgICBTdG9yYWdlVXRpbHMuc2V0T2JqZWN0ID0gc2V0T2JqZWN0O1xyXG4gICAgLyoqXHJcbiAgICAgKiBHZXRzIGFuIG9iamVjdCBmb3IgdGhlIGdpdmVuIGtleSBmcm9tIGxvY2FsU3RvcmFnZS4gVGhlIG9iamVjdCB3aWxsIGJlIGRlc2VyaWFsaXplZCBmcm9tIEpTT04uIEJlc2lkZSB0aGVcclxuICAgICAqIGRlZmF1bHQgdHlwZXMsIHRoZSBmb2xsb3dpbmcgdHlwZXMgYXJlIHN1cHBvcnRlZDpcclxuICAgICAqICAtIENvbG9yVXRpbHMuQ29sb3JcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ga2V5IHRoZSBrZXkgdG8gbG9vayB1cCBpdHMgYXNzb2NpYXRlZCBvYmplY3RcclxuICAgICAqIEByZXR1cm4ge2FueX0gUmV0dXJucyB0aGUgb2JqZWN0IGlmIGZvdW5kLCBudWxsIG90aGVyd2lzZVxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBnZXRPYmplY3Qoa2V5KSB7XHJcbiAgICAgICAgaWYgKFN0b3JhZ2VVdGlscy5oYXNMb2NhbFN0b3JhZ2UoKSkge1xyXG4gICAgICAgICAgICB2YXIganNvbiA9IGdldEl0ZW0oa2V5KTtcclxuICAgICAgICAgICAgaWYgKGtleSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIG9iamVjdCA9IEpTT04ucGFyc2UoanNvbik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gb2JqZWN0O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgfVxyXG4gICAgU3RvcmFnZVV0aWxzLmdldE9iamVjdCA9IGdldE9iamVjdDtcclxufSkoU3RvcmFnZVV0aWxzID0gZXhwb3J0cy5TdG9yYWdlVXRpbHMgfHwgKGV4cG9ydHMuU3RvcmFnZVV0aWxzID0ge30pKTtcclxuXG5cblxuLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXRUJQQUNLIEZPT1RFUlxuLy8gLi4vbGliL3VpbWFuYWdlci9zdG9yYWdldXRpbHMudHNcbi8vIG1vZHVsZSBpZCA9IDQ2XG4vLyBtb2R1bGUgY2h1bmtzID0gMCIsIi8qISBIaXZlIFN0YXRzIFBhY2sgYnVpbGQgMy4yLjAgQ29weXJpZ2h0KGMpIDIwMTUgSGl2ZVN0cmVhbWluZyBBQiwgQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAqIEF1dGhvcnM6IG1pa2FlbC5ob2dxdmlzdEBoaXZlc3RyZWFtaW5nLmNvbSAtIHJpY2NhcmRvLnJlYWxlQGhpdmVzdHJlYW1pbmcuY29tIC0gcm9iZXJ0by5yb3ZlcnNvQGhpdmVzdHJlYW1pbmcuY29tICovXG4vKiEgQXRhdHVzSnMgLSB2Mi4zLjEyIC0gMjAxNi0wNy0wM1xuICogQ29weXJpZ2h0IChjKSAyMDE2IEF0YXR1cyAqL1xuIWZ1bmN0aW9uKGEpe2Z1bmN0aW9uIGIoYSxiKXtyZXR1cm4gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGEsYil9ZnVuY3Rpb24gYyhhKXtyZXR1cm5cInVuZGVmaW5lZFwiPT10eXBlb2YgYX1pZihhKXt2YXIgZD17fSxlPWEuVHJhY2VLaXQsZj1bXS5zbGljZSxnPVwiP1wiO2Qubm9Db25mbGljdD1mdW5jdGlvbigpe3JldHVybiBhLlRyYWNlS2l0PWUsZH0sZC53cmFwPWZ1bmN0aW9uKGEpe2Z1bmN0aW9uIGIoKXt0cnl7cmV0dXJuIGEuYXBwbHkodGhpcyxhcmd1bWVudHMpfWNhdGNoKGIpe3Rocm93IGQucmVwb3J0KGIpLGJ9fXJldHVybiBifSxkLnJlcG9ydD1mdW5jdGlvbigpe2Z1bmN0aW9uIGMoYSl7aSgpLG0ucHVzaChhKX1mdW5jdGlvbiBlKGEpe2Zvcih2YXIgYj1tLmxlbmd0aC0xO2I+PTA7LS1iKW1bYl09PT1hJiZtLnNwbGljZShiLDEpfWZ1bmN0aW9uIGcoYSxjKXt2YXIgZT1udWxsO2lmKCFjfHxkLmNvbGxlY3RXaW5kb3dFcnJvcnMpe2Zvcih2YXIgZyBpbiBtKWlmKGIobSxnKSl0cnl7bVtnXS5hcHBseShudWxsLFthXS5jb25jYXQoZi5jYWxsKGFyZ3VtZW50cywyKSkpfWNhdGNoKGgpe2U9aH1pZihlKXRocm93IGV9fWZ1bmN0aW9uIGgoYSxiLGMsZSxmKXt2YXIgaD1udWxsO2lmKGYpaD1kLmNvbXB1dGVTdGFja1RyYWNlKGYpO2Vsc2UgaWYobylkLmNvbXB1dGVTdGFja1RyYWNlLmF1Z21lbnRTdGFja1RyYWNlV2l0aEluaXRpYWxFbGVtZW50KG8sYixjLGEpLGg9byxvPW51bGwsbj1udWxsO2Vsc2V7dmFyIGk9e3VybDpiLGxpbmU6Yyxjb2x1bW46ZX07aS5mdW5jPWQuY29tcHV0ZVN0YWNrVHJhY2UuZ3Vlc3NGdW5jdGlvbk5hbWUoaS51cmwsaS5saW5lKSxpLmNvbnRleHQ9ZC5jb21wdXRlU3RhY2tUcmFjZS5nYXRoZXJDb250ZXh0KGkudXJsLGkubGluZSksaD17bW9kZTpcIm9uZXJyb3JcIixtZXNzYWdlOmEsdXJsOmRvY3VtZW50LmxvY2F0aW9uLmhyZWYsc3RhY2s6W2ldLHVzZXJhZ2VudDpuYXZpZ2F0b3IudXNlckFnZW50fX1yZXR1cm4gZyhoLFwiZnJvbSB3aW5kb3cub25lcnJvclwiKSxrP2suYXBwbHkodGhpcyxhcmd1bWVudHMpOiExfWZ1bmN0aW9uIGkoKXtsIT09ITAmJihrPWEub25lcnJvcixhLm9uZXJyb3I9aCxsPSEwKX1mdW5jdGlvbiBqKGIpe3ZhciBjPWYuY2FsbChhcmd1bWVudHMsMSk7aWYobyl7aWYobj09PWIpcmV0dXJuO3ZhciBlPW87bz1udWxsLG49bnVsbCxnLmFwcGx5KG51bGwsW2UsbnVsbF0uY29uY2F0KGMpKX12YXIgaD1kLmNvbXB1dGVTdGFja1RyYWNlKGIpO3Rocm93IG89aCxuPWIsYS5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7bj09PWImJihvPW51bGwsbj1udWxsLGcuYXBwbHkobnVsbCxbaCxudWxsXS5jb25jYXQoYykpKX0saC5pbmNvbXBsZXRlPzJlMzowKSxifXZhciBrLGwsbT1bXSxuPW51bGwsbz1udWxsO3JldHVybiBqLnN1YnNjcmliZT1jLGoudW5zdWJzY3JpYmU9ZSxqfSgpLGQuY29tcHV0ZVN0YWNrVHJhY2U9ZnVuY3Rpb24oKXtmdW5jdGlvbiBlKGIpe2lmKCFkLnJlbW90ZUZldGNoaW5nKXJldHVyblwiXCI7dHJ5e3ZhciBjPWZ1bmN0aW9uKCl7dHJ5e3JldHVybiBuZXcgYS5YTUxIdHRwUmVxdWVzdH1jYXRjaChiKXtyZXR1cm4gbmV3IGEuQWN0aXZlWE9iamVjdChcIk1pY3Jvc29mdC5YTUxIVFRQXCIpfX0sZT1jKCk7cmV0dXJuIGUub3BlbihcIkdFVFwiLGIsITEpLGUuc2VuZChcIlwiKSxlLnJlc3BvbnNlVGV4dH1jYXRjaChmKXtyZXR1cm5cIlwifX1mdW5jdGlvbiBmKGEpe2lmKFwic3RyaW5nXCIhPXR5cGVvZiBhKXJldHVybltdO2lmKCFiKHcsYSkpe3ZhciBjPVwiXCIsZD1cIlwiO3RyeXtkPWRvY3VtZW50LmRvbWFpbn1jYXRjaChmKXt9LTEhPT1hLmluZGV4T2YoZCkmJihjPWUoYSkpLHdbYV09Yz9jLnNwbGl0KFwiXFxuXCIpOltdfXJldHVybiB3W2FdfWZ1bmN0aW9uIGgoYSxiKXt2YXIgZCxlPS9mdW5jdGlvbiAoW14oXSopXFwoKFteKV0qKVxcKS8saD0vWydcIl0/KFswLTlBLVphLXokX10rKVsnXCJdP1xccypbOj1dXFxzKihmdW5jdGlvbnxldmFsfG5ldyBGdW5jdGlvbikvLGk9XCJcIixqPTEwLGs9ZihhKTtpZighay5sZW5ndGgpcmV0dXJuIGc7Zm9yKHZhciBsPTA7aj5sOysrbClpZihpPWtbYi1sXStpLCFjKGkpKXtpZihkPWguZXhlYyhpKSlyZXR1cm4gZFsxXTtpZihkPWUuZXhlYyhpKSlyZXR1cm4gZFsxXX1yZXR1cm4gZ31mdW5jdGlvbiBpKGEsYil7dmFyIGU9ZihhKTtpZighZS5sZW5ndGgpcmV0dXJuIG51bGw7dmFyIGc9W10saD1NYXRoLmZsb29yKGQubGluZXNPZkNvbnRleHQvMiksaT1oK2QubGluZXNPZkNvbnRleHQlMixqPU1hdGgubWF4KDAsYi1oLTEpLGs9TWF0aC5taW4oZS5sZW5ndGgsYitpLTEpO2ItPTE7Zm9yKHZhciBsPWo7az5sOysrbCljKGVbbF0pfHxnLnB1c2goZVtsXSk7cmV0dXJuIGcubGVuZ3RoPjA/ZzpudWxsfWZ1bmN0aW9uIGooYSl7cmV0dXJuIGEucmVwbGFjZSgvW1xcLVxcW1xcXXt9KCkqKz8uLFxcXFxcXF4kfCNdL2csXCJcXFxcJCZcIil9ZnVuY3Rpb24gayhhKXtyZXR1cm4gaihhKS5yZXBsYWNlKFwiPFwiLFwiKD86PHwmbHQ7KVwiKS5yZXBsYWNlKFwiPlwiLFwiKD86PnwmZ3Q7KVwiKS5yZXBsYWNlKFwiJlwiLFwiKD86JnwmYW1wOylcIikucmVwbGFjZSgnXCInLCcoPzpcInwmcXVvdDspJykucmVwbGFjZSgvXFxzKy9nLFwiXFxcXHMrXCIpfWZ1bmN0aW9uIGwoYSxiKXtmb3IodmFyIGMsZCxlPTAsZz1iLmxlbmd0aDtnPmU7KytlKWlmKChjPWYoYltlXSkpLmxlbmd0aCYmKGM9Yy5qb2luKFwiXFxuXCIpLGQ9YS5leGVjKGMpKSlyZXR1cm57dXJsOmJbZV0sbGluZTpjLnN1YnN0cmluZygwLGQuaW5kZXgpLnNwbGl0KFwiXFxuXCIpLmxlbmd0aCxjb2x1bW46ZC5pbmRleC1jLmxhc3RJbmRleE9mKFwiXFxuXCIsZC5pbmRleCktMX07cmV0dXJuIG51bGx9ZnVuY3Rpb24gbShhLGIsYyl7dmFyIGQsZT1mKGIpLGc9bmV3IFJlZ0V4cChcIlxcXFxiXCIraihhKStcIlxcXFxiXCIpO3JldHVybiBjLT0xLGUmJmUubGVuZ3RoPmMmJihkPWcuZXhlYyhlW2NdKSk/ZC5pbmRleDpudWxsfWZ1bmN0aW9uIG4oYil7Zm9yKHZhciBjLGQsZSxmLGc9W2EubG9jYXRpb24uaHJlZl0saD1kb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcInNjcmlwdFwiKSxpPVwiXCIrYixtPS9eZnVuY3Rpb24oPzpcXHMrKFtcXHckXSspKT9cXHMqXFwoKFtcXHdcXHMsXSopXFwpXFxzKlxce1xccyooXFxTW1xcc1xcU10qXFxTKVxccypcXH1cXHMqJC8sbj0vXmZ1bmN0aW9uIG9uKFtcXHckXSspXFxzKlxcKGV2ZW50XFwpXFxzKlxce1xccyooXFxTW1xcc1xcU10qXFxTKVxccypcXH1cXHMqJC8sbz0wO288aC5sZW5ndGg7KytvKXt2YXIgcD1oW29dO3Auc3JjJiZnLnB1c2gocC5zcmMpfWlmKGU9bS5leGVjKGkpKXt2YXIgcT1lWzFdP1wiXFxcXHMrXCIrZVsxXTpcIlwiLHI9ZVsyXS5zcGxpdChcIixcIikuam9pbihcIlxcXFxzKixcXFxccypcIik7Yz1qKGVbM10pLnJlcGxhY2UoLzskLyxcIjs/XCIpLGQ9bmV3IFJlZ0V4cChcImZ1bmN0aW9uXCIrcStcIlxcXFxzKlxcXFwoXFxcXHMqXCIrcitcIlxcXFxzKlxcXFwpXFxcXHMqe1xcXFxzKlwiK2MrXCJcXFxccyp9XCIpfWVsc2UgZD1uZXcgUmVnRXhwKGooaSkucmVwbGFjZSgvXFxzKy9nLFwiXFxcXHMrXCIpKTtpZihmPWwoZCxnKSlyZXR1cm4gZjtpZihlPW4uZXhlYyhpKSl7dmFyIHM9ZVsxXTtpZihjPWsoZVsyXSksZD1uZXcgUmVnRXhwKFwib25cIitzK1wiPVtcXFxcJ1xcXCJdXFxcXHMqXCIrYytcIlxcXFxzKltcXFxcJ1xcXCJdXCIsXCJpXCIpLGY9bChkLGdbMF0pKXJldHVybiBmO2lmKGQ9bmV3IFJlZ0V4cChjKSxmPWwoZCxnKSlyZXR1cm4gZn1yZXR1cm4gbnVsbH1mdW5jdGlvbiBvKGEpe2lmKCFhLnN0YWNrKXJldHVybiBudWxsO2Zvcih2YXIgYixkLGU9L15cXHMqYXQgKC4qPykgP1xcKD8oKD86ZmlsZXxodHRwcz98Y2hyb21lLWV4dGVuc2lvbik6Lio/KTooXFxkKykoPzo6KFxcZCspKT9cXCk/XFxzKiQvaSxmPS9eXFxzKiguKj8pKD86XFwoKC4qPylcXCkpP0A/KCg/OmZpbGV8aHR0cHM/fGNocm9tZSk6Lio/KTooXFxkKykoPzo6KFxcZCspKT9cXHMqJC9pLGo9L15cXHMqYXQgKD86KCg/OlxcW29iamVjdCBvYmplY3RcXF0pPy4rKSApP1xcKD8oKD86bXMtYXBweHxodHRwfGh0dHBzKTouKj8pOihcXGQrKSg/OjooXFxkKykpP1xcKT9cXHMqJC9pLGs9YS5zdGFjay5zcGxpdChcIlxcblwiKSxsPVtdLG49L14oLiopIGlzIHVuZGVmaW5lZCQvLmV4ZWMoYS5tZXNzYWdlKSxvPTAscD1rLmxlbmd0aDtwPm87KytvKXtpZihiPWYuZXhlYyhrW29dKSlkPXt1cmw6YlszXSxmdW5jOmJbMV18fGcsYXJnczpiWzJdP2JbMl0uc3BsaXQoXCIsXCIpOlwiXCIsbGluZTorYls0XSxjb2x1bW46Yls1XT8rYls1XTpudWxsfTtlbHNlIGlmKGI9ZS5leGVjKGtbb10pKWQ9e3VybDpiWzJdLGZ1bmM6YlsxXXx8ZyxsaW5lOitiWzNdLGNvbHVtbjpiWzRdPytiWzRdOm51bGx9O2Vsc2V7aWYoIShiPWouZXhlYyhrW29dKSkpY29udGludWU7ZD17dXJsOmJbMl0sZnVuYzpiWzFdfHxnLGxpbmU6K2JbM10sY29sdW1uOmJbNF0/K2JbNF06bnVsbH19IWQuZnVuYyYmZC5saW5lJiYoZC5mdW5jPWgoZC51cmwsZC5saW5lKSksZC5saW5lJiYoZC5jb250ZXh0PWkoZC51cmwsZC5saW5lKSksbC5wdXNoKGQpfXJldHVybiBsLmxlbmd0aD8obFswXSYmbFswXS5saW5lJiYhbFswXS5jb2x1bW4mJm4/bFswXS5jb2x1bW49bShuWzFdLGxbMF0udXJsLGxbMF0ubGluZSk6bFswXS5jb2x1bW58fGMoYS5jb2x1bW5OdW1iZXIpfHwobFswXS5jb2x1bW49YS5jb2x1bW5OdW1iZXIrMSkse21vZGU6XCJzdGFja1wiLG5hbWU6YS5uYW1lLG1lc3NhZ2U6YS5tZXNzYWdlLHVybDpkb2N1bWVudC5sb2NhdGlvbi5ocmVmLHN0YWNrOmwsdXNlcmFnZW50Om5hdmlnYXRvci51c2VyQWdlbnR9KTpudWxsfWZ1bmN0aW9uIHAoYSl7Zm9yKHZhciBiLGM9YS5zdGFja3RyYWNlLGQ9LyBsaW5lIChcXGQrKSwgY29sdW1uIChcXGQrKSBpbiAoPzo8YW5vbnltb3VzIGZ1bmN0aW9uOiAoW14+XSspPnwoW15cXCldKykpXFwoKC4qKVxcKSBpbiAoLiopOlxccyokL2ksZT1jLnNwbGl0KFwiXFxuXCIpLGY9W10sZz0wLGo9ZS5sZW5ndGg7aj5nO2crPTIpaWYoYj1kLmV4ZWMoZVtnXSkpe3ZhciBrPXtsaW5lOitiWzFdLGNvbHVtbjorYlsyXSxmdW5jOmJbM118fGJbNF0sYXJnczpiWzVdP2JbNV0uc3BsaXQoXCIsXCIpOltdLHVybDpiWzZdfTtpZighay5mdW5jJiZrLmxpbmUmJihrLmZ1bmM9aChrLnVybCxrLmxpbmUpKSxrLmxpbmUpdHJ5e2suY29udGV4dD1pKGsudXJsLGsubGluZSl9Y2F0Y2gobCl7fWsuY29udGV4dHx8KGsuY29udGV4dD1bZVtnKzFdXSksZi5wdXNoKGspfXJldHVybiBmLmxlbmd0aD97bW9kZTpcInN0YWNrdHJhY2VcIixuYW1lOmEubmFtZSxtZXNzYWdlOmEubWVzc2FnZSx1cmw6ZG9jdW1lbnQubG9jYXRpb24uaHJlZixzdGFjazpmLHVzZXJhZ2VudDpuYXZpZ2F0b3IudXNlckFnZW50fTpudWxsfWZ1bmN0aW9uIHEoYyl7dmFyIGQ9Yy5tZXNzYWdlLnNwbGl0KFwiXFxuXCIpO2lmKGQubGVuZ3RoPDQpcmV0dXJuIG51bGw7dmFyIGUsZyxqLG0sbj0vXlxccypMaW5lIChcXGQrKSBvZiBsaW5rZWQgc2NyaXB0ICgoPzpmaWxlfGh0dHBzPylcXFMrKSg/OjogaW4gZnVuY3Rpb24gKFxcUyspKT9cXHMqJC9pLG89L15cXHMqTGluZSAoXFxkKykgb2YgaW5saW5lIyhcXGQrKSBzY3JpcHQgaW4gKCg/OmZpbGV8aHR0cHM/KVxcUyspKD86OiBpbiBmdW5jdGlvbiAoXFxTKykpP1xccyokL2kscD0vXlxccypMaW5lIChcXGQrKSBvZiBmdW5jdGlvbiBzY3JpcHRcXHMqJC9pLHE9W10scj1kb2N1bWVudC5nZXRFbGVtZW50c0J5VGFnTmFtZShcInNjcmlwdFwiKSxzPVtdO2ZvcihnIGluIHIpYihyLGcpJiYhcltnXS5zcmMmJnMucHVzaChyW2ddKTtmb3IoZz0yLGo9ZC5sZW5ndGg7aj5nO2crPTIpe3ZhciB0PW51bGw7aWYoZT1uLmV4ZWMoZFtnXSkpdD17dXJsOmVbMl0sZnVuYzplWzNdLGxpbmU6K2VbMV19O2Vsc2UgaWYoZT1vLmV4ZWMoZFtnXSkpe3Q9e3VybDplWzNdLGZ1bmM6ZVs0XX07dmFyIHU9K2VbMV0sdj1zW2VbMl0tMV07aWYodiYmKG09Zih0LnVybCkpKXttPW0uam9pbihcIlxcblwiKTt2YXIgdz1tLmluZGV4T2Yodi5pbm5lclRleHQpO3c+PTAmJih0LmxpbmU9dSttLnN1YnN0cmluZygwLHcpLnNwbGl0KFwiXFxuXCIpLmxlbmd0aCl9fWVsc2UgaWYoZT1wLmV4ZWMoZFtnXSkpe3ZhciB4PWEubG9jYXRpb24uaHJlZi5yZXBsYWNlKC8jLiokLyxcIlwiKSx5PWVbMV0sej1uZXcgUmVnRXhwKGsoZFtnKzFdKSk7bT1sKHosW3hdKSx0PXt1cmw6eCxsaW5lOm0/bS5saW5lOnksZnVuYzpcIlwifX1pZih0KXt0LmZ1bmN8fCh0LmZ1bmM9aCh0LnVybCx0LmxpbmUpKTt2YXIgQT1pKHQudXJsLHQubGluZSksQj1BP0FbTWF0aC5mbG9vcihBLmxlbmd0aC8yKV06bnVsbDt0LmNvbnRleHQ9QSYmQi5yZXBsYWNlKC9eXFxzKi8sXCJcIik9PT1kW2crMV0ucmVwbGFjZSgvXlxccyovLFwiXCIpP0E6W2RbZysxXV0scS5wdXNoKHQpfX1yZXR1cm4gcS5sZW5ndGg/e21vZGU6XCJtdWx0aWxpbmVcIixuYW1lOmMubmFtZSxtZXNzYWdlOmRbMF0sdXJsOmRvY3VtZW50LmxvY2F0aW9uLmhyZWYsc3RhY2s6cSx1c2VyYWdlbnQ6bmF2aWdhdG9yLnVzZXJBZ2VudH06bnVsbH1mdW5jdGlvbiByKGEsYixjLGQpe3ZhciBlPXt1cmw6YixsaW5lOmN9O2lmKGUudXJsJiZlLmxpbmUpe2EuaW5jb21wbGV0ZT0hMSxlLmZ1bmN8fChlLmZ1bmM9aChlLnVybCxlLmxpbmUpKSxlLmNvbnRleHR8fChlLmNvbnRleHQ9aShlLnVybCxlLmxpbmUpKTt2YXIgZj0vICcoW14nXSspJyAvLmV4ZWMoZCk7aWYoZiYmKGUuY29sdW1uPW0oZlsxXSxlLnVybCxlLmxpbmUpKSxhLnN0YWNrLmxlbmd0aD4wJiZhLnN0YWNrWzBdLnVybD09PWUudXJsKXtpZihhLnN0YWNrWzBdLmxpbmU9PT1lLmxpbmUpcmV0dXJuITE7aWYoIWEuc3RhY2tbMF0ubGluZSYmYS5zdGFja1swXS5mdW5jPT09ZS5mdW5jKXJldHVybiBhLnN0YWNrWzBdLmxpbmU9ZS5saW5lLGEuc3RhY2tbMF0uY29udGV4dD1lLmNvbnRleHQsITF9cmV0dXJuIGEuc3RhY2sudW5zaGlmdChlKSxhLnBhcnRpYWw9ITAsITB9cmV0dXJuIGEuaW5jb21wbGV0ZT0hMCwhMX1mdW5jdGlvbiBzKGEsYil7Zm9yKHZhciBjLGUsZixpPS9mdW5jdGlvblxccysoW18kYS16QS1aXFx4QTAtXFx1RkZGRl1bXyRhLXpBLVowLTlcXHhBMC1cXHVGRkZGXSopP1xccypcXCgvaSxqPVtdLGs9e30sbD0hMSxvPXMuY2FsbGVyO28mJiFsO289by5jYWxsZXIpaWYobyE9PXQmJm8hPT1kLnJlcG9ydCl7aWYoZT17dXJsOm51bGwsZnVuYzpnLGxpbmU6bnVsbCxjb2x1bW46bnVsbH0sby5uYW1lP2UuZnVuYz1vLm5hbWU6KGM9aS5leGVjKG8udG9TdHJpbmcoKSkpJiYoZS5mdW5jPWNbMV0pLFwidW5kZWZpbmVkXCI9PXR5cGVvZiBlLmZ1bmMpdHJ5e2UuZnVuYz1jLmlucHV0LnN1YnN0cmluZygwLGMuaW5wdXQuaW5kZXhPZihcIntcIikpfWNhdGNoKHApe31pZihmPW4obykpe2UudXJsPWYudXJsLGUubGluZT1mLmxpbmUsZS5mdW5jPT09ZyYmKGUuZnVuYz1oKGUudXJsLGUubGluZSkpO3ZhciBxPS8gJyhbXiddKyknIC8uZXhlYyhhLm1lc3NhZ2V8fGEuZGVzY3JpcHRpb24pO3EmJihlLmNvbHVtbj1tKHFbMV0sZi51cmwsZi5saW5lKSl9a1tcIlwiK29dP2w9ITA6a1tcIlwiK29dPSEwLGoucHVzaChlKX1iJiZqLnNwbGljZSgwLGIpO3ZhciB1PXttb2RlOlwiY2FsbGVyc1wiLG5hbWU6YS5uYW1lLG1lc3NhZ2U6YS5tZXNzYWdlLHVybDpkb2N1bWVudC5sb2NhdGlvbi5ocmVmLHN0YWNrOmosdXNlcmFnZW50Om5hdmlnYXRvci51c2VyQWdlbnR9O3JldHVybiByKHUsYS5zb3VyY2VVUkx8fGEuZmlsZU5hbWUsYS5saW5lfHxhLmxpbmVOdW1iZXIsYS5tZXNzYWdlfHxhLmRlc2NyaXB0aW9uKSx1fWZ1bmN0aW9uIHQoYSxiKXt2YXIgYz1udWxsO2I9bnVsbD09Yj8wOitiO3RyeXtpZihjPXAoYSkpcmV0dXJuIGN9Y2F0Y2goZCl7aWYodil0aHJvdyBkfXRyeXtpZihjPW8oYSkpcmV0dXJuIGN9Y2F0Y2goZCl7aWYodil0aHJvdyBkfXRyeXtpZihjPXEoYSkpcmV0dXJuIGN9Y2F0Y2goZCl7aWYodil0aHJvdyBkfXRyeXtpZihjPXMoYSxiKzEpKXJldHVybiBjfWNhdGNoKGQpe2lmKHYpdGhyb3cgZH1yZXR1cm57bW9kZTpcImZhaWxlZFwifX1mdW5jdGlvbiB1KGEpe2E9KG51bGw9PWE/MDorYSkrMTt0cnl7dGhyb3cgbmV3IEVycm9yfWNhdGNoKGIpe3JldHVybiB0KGIsYSsxKX19dmFyIHY9ITEsdz17fTtyZXR1cm4gdC5hdWdtZW50U3RhY2tUcmFjZVdpdGhJbml0aWFsRWxlbWVudD1yLHQuZ3Vlc3NGdW5jdGlvbk5hbWU9aCx0LmdhdGhlckNvbnRleHQ9aSx0Lm9mQ2FsbGVyPXUsdC5nZXRTb3VyY2U9Zix0fSgpLGQuZXh0ZW5kVG9Bc3luY2hyb25vdXNDYWxsYmFja3M9ZnVuY3Rpb24oKXt2YXIgYj1mdW5jdGlvbihiKXt2YXIgYz1hW2JdO2FbYl09ZnVuY3Rpb24oKXt2YXIgYT1mLmNhbGwoYXJndW1lbnRzKSxiPWFbMF07cmV0dXJuXCJmdW5jdGlvblwiPT10eXBlb2YgYiYmKGFbMF09ZC53cmFwKGIpKSxjLmFwcGx5P2MuYXBwbHkodGhpcyxhKTpjKGFbMF0sYVsxXSl9fTtiKFwic2V0VGltZW91dFwiKSxiKFwic2V0SW50ZXJ2YWxcIil9LGQucmVtb3RlRmV0Y2hpbmd8fChkLnJlbW90ZUZldGNoaW5nPSEwKSxkLmNvbGxlY3RXaW5kb3dFcnJvcnN8fChkLmNvbGxlY3RXaW5kb3dFcnJvcnM9ITApLCghZC5saW5lc09mQ29udGV4dHx8ZC5saW5lc09mQ29udGV4dDwxKSYmKGQubGluZXNPZkNvbnRleHQ9MTEpLGEuVHJhY2VLaXQ9ZH19KFwidW5kZWZpbmVkXCIhPXR5cGVvZiB3aW5kb3c/d2luZG93Omdsb2JhbCksZnVuY3Rpb24oYSxiKXtcInVzZSBzdHJpY3RcIjtpZihhKXt2YXIgYz1hLmV2ZW50LmFkZDthLmV2ZW50LmFkZD1mdW5jdGlvbihkLGUsZixnLGgpe2lmKFwiZnVuY3Rpb25cIiE9dHlwZW9mIGYmJlwiZnVuY3Rpb25cIiE9dHlwZW9mIGYuaGFuZGxlcilyZXR1cm4gYy5jYWxsKHRoaXMsZCxlLGYsZyxoKTt2YXIgaTtyZXR1cm4gZi5oYW5kbGVyPyhpPWYuaGFuZGxlcixmLmhhbmRsZXI9Yi53cmFwKGYuaGFuZGxlcikpOihpPWYsZj1iLndyYXAoZikpLGYuZ3VpZD1pLmd1aWQ/aS5ndWlkOmkuZ3VpZD1hLmd1aWQrKyxjLmNhbGwodGhpcyxkLGUsZixnLGgpfTt2YXIgZD1hLmZuLnJlYWR5O2EuZm4ucmVhZHk9ZnVuY3Rpb24oYSl7cmV0dXJuIGQuY2FsbCh0aGlzLGIud3JhcChhKSl9O3ZhciBlPWEuYWpheDthLmFqYXg9ZnVuY3Rpb24oYyxkKXtcIm9iamVjdFwiPT10eXBlb2YgYyYmKGQ9YyxjPXZvaWQgMCksZD1kfHx7fTtmb3IodmFyIGYsZz1bXCJjb21wbGV0ZVwiLFwiZXJyb3JcIixcInN1Y2Nlc3NcIl07Zj1nLnBvcCgpOylhLmlzRnVuY3Rpb24oZFtmXSkmJihkW2ZdPWIud3JhcChkW2ZdKSk7dHJ5e3JldHVybiBjP2UuY2FsbCh0aGlzLGMsZCk6ZS5jYWxsKHRoaXMsZCl9Y2F0Y2goaCl7dGhyb3cgYi5yZXBvcnQoaCksaH19fX0od2luZG93LmpRdWVyeSx3aW5kb3cuVHJhY2VLaXQpLGZ1bmN0aW9uKGEsYixjLGQpe2Z1bmN0aW9uIGUoYSl7dmFyIGI9YSxjPWEuc3BsaXQoXCIvL1wiKVsxXTtpZihjKXt2YXIgZD1jLmluZGV4T2YoXCI/XCIpLGU9Yy50b1N0cmluZygpLnN1YnN0cmluZygwLGQpLGY9ZS5zcGxpdChcIi9cIikuc2xpY2UoMCw0KS5qb2luKFwiL1wiKSxnPWUuc3Vic3RyaW5nKDAsNDgpO2I9Zi5sZW5ndGg8Zy5sZW5ndGg/ZjpnLGIhPT1lJiYoYis9XCIuLlwiKX1yZXR1cm4gYn1mdW5jdGlvbiBmKGEsYixjLGYpe2lmKEsmJihMfHxiLmdldEFsbFJlc3BvbnNlSGVhZGVycygpKSl7dmFyIGc9XCJBSkFYIEVycm9yOiBcIisoYi5zdGF0dXNUZXh0fHxcInVua25vd25cIikrXCIgXCIrKGMudHlwZXx8XCJ1bmtub3duXCIpK1wiIFwiKyhlKGMudXJsKXx8XCJ1bmtub3duXCIpO1Yuc2VuZChmfHxhLnR5cGUse3N0YXR1czpiLnN0YXR1cyxzdGF0dXNUZXh0OmIuc3RhdHVzVGV4dCx0eXBlOmMudHlwZSx1cmw6Yy51cmwsYWpheEVycm9yTWVzc2FnZTpnLGNvbnRlbnRUeXBlOmMuY29udGVudFR5cGUscmVxdWVzdERhdGE6Yy5kYXRhJiZjLmRhdGEuc2xpY2U/Yy5kYXRhLnNsaWNlKDAsMTAyNDApOmQscmVzcG9uc2VEYXRhOmIucmVzcG9uc2VUZXh0JiZiLnJlc3BvbnNlVGV4dC5zbGljZT9iLnJlc3BvbnNlVGV4dC5zbGljZSgwLDEwMjQwKTpkLGFjdGl2ZVRhcmdldDphLnRhcmdldCYmYS50YXJnZXQuYWN0aXZlRWxlbWVudD9hLnRhcmdldC5hY3RpdmVFbGVtZW50Lm91dGVySFRNTDpkfSl9fWZ1bmN0aW9uIGcoKXtyZXR1cm4gbyYmXCJcIiE9PW8/ITA6KFIubG9nKFwiQXRhdHVzIEFQSSBrZXkgaGFzIG5vdCBiZWVuIGNvbmZpZ3VyZWQsIG1ha2Ugc3VyZSB5b3UgY2FsbCBhdGF0dXMuY29uZmlnKHlvdXJBcGlLZXkpXCIpLCExKX1mdW5jdGlvbiBoKCl7dmFyIGM9Yi5kb2N1bWVudEVsZW1lbnQsZD1iLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiYm9keVwiKVswXSxlPWEuaW5uZXJXaWR0aHx8Yy5jbGllbnRXaWR0aHx8ZC5jbGllbnRXaWR0aCxmPWEuaW5uZXJIZWlnaHR8fGMuY2xpZW50SGVpZ2h0fHxkLmNsaWVudEhlaWdodDtyZXR1cm57d2lkdGg6ZSxoZWlnaHQ6Zn19ZnVuY3Rpb24gaShhKXt2YXIgYj0obmV3IERhdGUpLnRvSlNPTigpO3RyeXt2YXIgYz1cImF0YXR1c2pzPVwiK2IrXCI9XCIrUi5nZXRSYW5kb21JbnQoKTtcInVuZGVmaW5lZFwiPT10eXBlb2YgbG9jYWxTdG9yYWdlW2NdJiYobG9jYWxTdG9yYWdlW2NdPWEpfWNhdGNoKGQpe1IubG9nKFwiQXRhdHVzOiBMb2NhbFN0b3JhZ2UgZnVsbCwgY2Fubm90IHNhdmUgZXhjZXB0aW9uXCIpfX1mdW5jdGlvbiBqKCl7dHJ5e3JldHVyblwibG9jYWxTdG9yYWdlXCJpbiBhJiZudWxsIT09YS5sb2NhbFN0b3JhZ2V9Y2F0Y2goYil7cmV0dXJuITF9fWZ1bmN0aW9uIGsoKXtpZihqKCkmJmxvY2FsU3RvcmFnZS5sZW5ndGg+MClmb3IodmFyIGEgaW4gbG9jYWxTdG9yYWdlKWlmKFwiYXRhdHVzanM9XCI9PT1hLnN1YnN0cmluZygwLDkpKXt0cnl7dmFyIGI9SlNPTi5wYXJzZShsb2NhbFN0b3JhZ2VbYV0pO1wiYXBpa2V5XCJpbiBiJiZtKE4sYil9Y2F0Y2goYyl7Ui5sb2coXCJBdGF0dXM6IEludmFsaWQgSlNPTiBvYmplY3QgaW4gTG9jYWxTdG9yYWdlXCIpfWxvY2FsU3RvcmFnZS5yZW1vdmVJdGVtKGEpfX1mdW5jdGlvbiBsKGEsYyl7aWYoYz1jfHx7fSwhYS5zdGFja3x8IWEuc3RhY2subGVuZ3RoKXJldHVybiB2b2lkIFIubG9nKFwiQXRhdHVzOiBDYW5jZWxpbmcgc2VuZCBkdWUgdG8gbm8gc3RhY2t0cmFjZS5cIik7Ui5pc0VtcHR5KGMuY3VzdG9tRGF0YSkmJihjLmN1c3RvbURhdGE9XCJmdW5jdGlvblwiPT10eXBlb2YgcD9wKCk6cCksUi5pc0VtcHR5KGMudGFncykmJihjLnRhZ3M9RSk7dmFyIGQ9Yy5jdXN0b21EYXRhJiZjLmN1c3RvbURhdGEuYWpheEVycm9yTWVzc2FnZXx8YS5tZXNzYWdlO2lmKGQmJjA9PT1kLmluZGV4T2YoXCJVbmNhdWdodCBcIikmJihkPWEubWVzc2FnZS5zdWJzdHJpbmcoOSkpLGQ9ZHx8Yy5zdGF0dXN8fFwiU2NyaXB0IGVycm9yLlwiLHcmJncudGVzdChkKSlyZXR1cm4gdm9pZCBSLmxvZyhcIkF0YXR1czogY2FuY2VsaW5nIHNlbmQgZHVlIHRvIGlnbm9yZSBlcnJvcnNcIik7dmFyIGU9W107YS5zdGFjayYmYS5zdGFjay5sZW5ndGgmJlIuZm9yRWFjaChhLnN0YWNrLGZ1bmN0aW9uKGEsYil7Ui5lbmRzV2l0aChiLnVybCxcIi9hdGF0dXMuanNcIil8fGUucHVzaCh7bG46Yi5saW5lfHwwLGNuOmIuY29sdW1ufHwwLGY6Yi51cmx8fFwiYW5vbnltb3VzXCIsbTpiLmZ1bmN8fFwiW2Fub255bW91c11cIn0pfSk7dmFyIGY9W2EubmFtZSxkLEpTT04uc3RyaW5naWZ5KGUpXS5qb2luKFwifFwiKTtpZihmPT09eClyZXR1cm4gdm9pZCBSLmxvZyhcIkF0YXR1czogY2FuY2VsaW5nIHNlbmQgZHVlIHRvIGR1cGxpY2F0ZSBlcnJvcnNcIik7eD1mO3ZhciBnPWMuY3VzdG9tRGF0YTt0cnl7SlNPTi5zdHJpbmdpZnkoZyl9Y2F0Y2goaCl7dmFyIGk9XCJDYW5ub3QgYWRkIGN1c3RvbSBkYXRhOyBtYXkgY29udGFpbiBjaXJjdWxhciByZWZlcmVuY2VcIjtnPXtlcnJvcjppfSxSLmxvZyhcIkF0YXR1czogXCIraSl9dmFyIGo9VS5nZXRBbGxFdmVudHMoKTtTLmNsZWFyKCk7dmFyIGs9e1wiY2xhc3NcIjphLm5hbWUsbmFtZTpkLGJhY2tUcmFjZXM6ZSx1c2VyQWN0aW9uczpqLG5ldDpudWxsLGN1c3RvbURhdGE6Z3x8bnVsbCx0YWdzOmMudGFncyxzb3VyY2VtYXA6SixyZXF1ZXN0Ont1cmw6Yi5sb2NhdGlvbi5ocmVmLHVhOm5hdmlnYXRvci51c2VyQWdlbnR9fTtpZihcImZ1bmN0aW9uXCI9PXR5cGVvZiB5JiYoay5ncm91cGluZ0tleT15KGspKSxcImZ1bmN0aW9uXCI9PXR5cGVvZiB6KXt2YXIgbD16KGspO2wmJm0oTixrKX1lbHNlIG0oTixrKX1mdW5jdGlvbiBtKGMsZCl7aWYoRyYmRy5sZW5ndGgmJi0xPT09Ry5pbmRleE9mKGxvY2F0aW9uLmhvc3QpKXJldHVybiB2b2lkIFIubG9nKFwiQXRhdHVzOiBjYW5jZWxpbmcgc2VuZCBkdWUgdG8gbm90IGEgYWxsb3dlZCBkb21haW5cIik7aWYoZygpKXtpZighZC50cyl7dmFyIGU9YS5zY3JlZW58fGgoKTtkLnRzPShuZXcgRGF0ZSkuZ2V0VGltZSgpLGQuYXBpa2V5PW8sZC5yZXF1ZXN0PWQucmVxdWVzdHx8e30sZC5yZXF1ZXN0LnVybD1kLnJlcXVlc3QudXJsfHxiLmxvY2F0aW9uLmhyZWYsZC5yZXF1ZXN0LnVhPWQucmVxdWVzdC51YXx8bmF2aWdhdG9yLnVzZXJBZ2VudCxkLnJlcXVlc3Qudz1lLndpZHRoLGQucmVxdWVzdC5oPWUuaGVpZ2h0LGQudj1yfHxcIlwiLGQuX3Y9Qnx8XCJcIn1xJiYoZC5jaWQ9cS51c2VySWR8fG51bGwpLFIubG9nKFwiU2VuZGluZyBkYXRhIHRvIEF0YXR1cyBSZWNlaXZlcjpcIixkKSxuKGMsSlNPTi5zdHJpbmdpZnkoZCkpfX1mdW5jdGlvbiBuKGEsYil7dmFyIGM9bmV3IEltYWdlLGQ9TSthK1wiP2RhdGE9XCIrZW5jb2RlVVJJQ29tcG9uZW50KGIpO2MuY3Jvc3NPcmlnaW49XCJhbm9ueW1vdXNcIixjLm9ubG9hZD1mdW5jdGlvbigpe2soKX0sYy5vbmVycm9yPWMub25hYm9ydD1mdW5jdGlvbigpe0kmJmE9PT1OJiZpKGIpfSxjLnNyYz1kfXZhciBvLHAscSxyLHMsdCx1LHYsdyx4LHkseixBLEI9XCIyLjMuMTJcIixDPVRyYWNlS2l0Lm5vQ29uZmxpY3QoKSxEPWEuYXRhdHVzLEU9W10sRj0hMSxHPVtdLEg9ITEsST0hMSxKPSExLEs9ITEsTD0hMSxNPVwiaHR0cHM6Ly9ici1yeC5hdGF0dXMuY29tXCIsTj1cIi90cmFjay9icm93c2VyL2Vycm9yc1wiLE89XCIvdHJhY2svYnJvd3Nlci9wZXJmXCIsUD1cIi90cmFjay9icm93c2VyL3BlcmYvYWpheFwiLFE9XCIvdHJhY2svYnJvd3Nlci9wZXJmL3R4blwiO2MmJihBPWMoYikpO3ZhciBSPXtpc0Jvb2xlYW46ZnVuY3Rpb24oYSl7cmV0dXJuXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGEmJlwiYm9vbGVhblwiPT10eXBlb2YgYX0saXNTdHJpbmc6ZnVuY3Rpb24oYSl7cmV0dXJuXCJzdHJpbmdcIj09dHlwZW9mIGF9LGlzQXJyYXk6ZnVuY3Rpb24oYSl7cmV0dXJuXCJbb2JqZWN0IEFycmF5XVwiPT09T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGEpfSxlbmRzV2l0aDpmdW5jdGlvbihhLGIpe3JldHVybiBhJiZiPy0xIT09YS5pbmRleE9mKGIsYS5sZW5ndGgtYi5sZW5ndGgpOiExfSxqb2luUmVnRXhwOmZ1bmN0aW9uKGEpe2Zvcih2YXIgYixjPVtdLGQ9MCxlPWEubGVuZ3RoO2U+ZDtkKyspYj1hW2RdLFIuaXNTdHJpbmcoYik/Yy5wdXNoKGIucmVwbGFjZSgvKFsuKis/XFxePSE6JHt9KCl8XFxbXFxdXFwvXFxcXF0pL2csXCJcXFxcJDFcIikpOmImJmIuc291cmNlJiZjLnB1c2goYi5zb3VyY2UpO3JldHVybiBuZXcgUmVnRXhwKGMuam9pbihcInxcIiksXCJpXCIpfSxnZXRUYXJnZXRVcmw6ZnVuY3Rpb24oYil7cmV0dXJuIGEuWERvbWFpblJlcXVlc3QmJkgmJihiPWIuc2xpY2UoNikpLGJ9LG5vdzpmdW5jdGlvbigpe3JldHVybihuZXcgRGF0ZSkuZ2V0VGltZSgpfSxwYWQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGE9U3RyaW5nKGEpLDE9PT1hLmxlbmd0aCYmKGE9XCIwXCIrYSksYX0sbWVyZ2U6ZnVuY3Rpb24oYSxiKXt2YXIgYyxkPXt9O2ZvcihjIGluIGEpZFtjXT1hW2NdO2ZvcihjIGluIGIpZFtjXT1iW2NdO3JldHVybiBkfSxtZXJnZUFycmF5OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG51bGwhPWI/YS5jb25jYXQoYik6YX0sZm9yRWFjaDpmdW5jdGlvbihhLGIpe2Zvcih2YXIgYz0wO2M8YS5sZW5ndGg7YysrKWIuY2FsbChudWxsLGMsYVtjXSl9LGlzRW1wdHk6ZnVuY3Rpb24oYSl7Zm9yKHZhciBiIGluIGEpaWYoYS5oYXNPd25Qcm9wZXJ0eShiKSlyZXR1cm4hMTtyZXR1cm4hMH0sZ2V0UmFuZG9tSW50OmZ1bmN0aW9uKCl7cmV0dXJuIE1hdGguZmxvb3IoOTAwNzE5OTI1NDc0MDk5MipNYXRoLnJhbmRvbSgpKX0sbG9nOmZ1bmN0aW9uKGIsYyl7RiYmYS5jb25zb2xlJiZhLmNvbnNvbGUubG9nJiYoYS5jb25zb2xlLmxvZyhiKSxjJiZhLmNvbnNvbGUubG9nKGMpKX0sYmluZDpmdW5jdGlvbihhLGIpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBhLmFwcGx5KGIsQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKSl9fSxjYW5BbGxvd0luc2VjdXJlU3VibWlzc2lvbnM6ZnVuY3Rpb24oKXt2YXIgYj1hLm5hdmlnYXRvci51c2VyQWdlbnQsYz1iLm1hdGNoKC9UcmlkZW50XFwvKFtcXGQuXSspLyksZD1jJiZcIjcuMFwiPT09Y1sxXT8xMTooYj1iLm1hdGNoKC9NU0lFIChbXFxkLl0rKS8pKT9wYXJzZUludChiWzFdLDEwKTohMTtyZXR1cm4gZCYmOT49ZH0sdXVpZDQ6ZnVuY3Rpb24oKXtyZXR1cm5cInh4eHh4eHh4eHh4eDR4eHh5eHh4eHh4eHh4eHh4eHh4XCIucmVwbGFjZSgvW3h5XS9nLGZ1bmN0aW9uKGEpe3ZhciBiPTE2Kk1hdGgucmFuZG9tKCl8MCxjPVwieFwiPT09YT9iOjMmYnw4O3JldHVybiBjLnRvU3RyaW5nKDE2KX0pfSxhZGRFdmVudExpc3RlbmVyOmZ1bmN0aW9uKGIsYyxkKXtyZXR1cm5cInVuZGVmaW5lZFwiIT10eXBlb2YgYS5hdHRhY2hFdmVudD9hLmF0dGFjaEV2ZW50KFwib25cIitiLGMpOmEuYWRkRXZlbnRMaXN0ZW5lcj9hLmFkZEV2ZW50TGlzdGVuZXIoYixjLGQpOnZvaWQgMH0sYXJyYXlGcm9tT2JqZWN0OmZ1bmN0aW9uKGEpe3ZhciBiPVtdO2Zvcih2YXIgYyBpbiBhKWEuaGFzT3duUHJvcGVydHkoYykmJmIucHVzaChhW2NdKTtyZXR1cm4gYn19LFM9e2V2ZW50T2JqZWN0Ont9LGFsbDpmdW5jdGlvbihhKXtmb3IodmFyIGI9dGhpcy5nZXRFdmVudE9iamVjdChhKSxjPVtdLGQ9MDtkPGIubGVuZ3RoO2QrKyljLnB1c2goYltkXS52YWx1ZSk7cmV0dXJuIGN9LGNsZWFyOmZ1bmN0aW9uKCl7Zm9yKHZhciBhIGluIHRoaXMuZXZlbnRPYmplY3QpdGhpcy5ldmVudE9iamVjdC5oYXNPd25Qcm9wZXJ0eShhKSYmKHRoaXMuZXZlbnRPYmplY3RbYV0ubGVuZ3RoPTApfSxhZGQ6ZnVuY3Rpb24oYSxiKXt2YXIgYz10aGlzLmdldEV2ZW50T2JqZWN0KGEpLGQ9Ui51dWlkNCgpO3JldHVybiBjLnB1c2goe2tleTpkLHZhbHVlOmJ9KSx0aGlzLnRydW5jYXRlRXZlbnRPYmplY3QoYSwxMCksZH0sZ2V0OmZ1bmN0aW9uKGEsYil7Zm9yKHZhciBjPXRoaXMuZ2V0RXZlbnRPYmplY3QoYSksZD0wO2Q8Yy5sZW5ndGg7ZCsrKWlmKGNbZF0ua2V5PT09YilyZXR1cm4gY1tkXS52YWx1ZTtyZXR1cm4hMX0sZ2V0RXZlbnRPYmplY3Q6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZXZlbnRPYmplY3RbYV18fCh0aGlzLmV2ZW50T2JqZWN0W2FdPVtdKSx0aGlzLmV2ZW50T2JqZWN0W2FdfSx0cnVuY2F0ZUV2ZW50T2JqZWN0OmZ1bmN0aW9uKGEsYil7dmFyIGM9dGhpcy5nZXRFdmVudE9iamVjdChhKTtjLmxlbmd0aD5iJiYodGhpcy5ldmVudE9iamVjdFthXT1jLnNsaWNlKGMubGVuZ3RoLWIpKX19LFQ9e2F0dGFjaDpmdW5jdGlvbihiLGMsZCxlLGYpe2I9Ynx8YS5jb25zb2xlfHx7fTtmb3IodmFyIGc9Znx8W1wibG9nXCIsXCJkZWJ1Z1wiLFwiaW5mb1wiLFwid2FyblwiLFwiZXJyb3JcIl0saD1nLnBvcCgpLGk9ZnVuY3Rpb24oYSxiLGQpe2MmJlMuYWRkKFwidXNlclwiLHt0czpSLm5vdygpLGM6XCJjb25zb2xlXCIsbDphLG06Yn0pLFwiZXJyb3JcIj09PWEmJmUmJlYubm90aWZ5KG5ldyBFcnJvcihiKSxkKX07aDspdGhpcy53cmFwQ29uc29sZU1ldGhvZChiLGgsZCxpKSxoPWcucG9wKCl9LHdyYXBDb25zb2xlTWV0aG9kOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciBlPWFbYl0sZj1hO2IgaW4gYSYmKGFbYl09ZnVuY3Rpb24oKXt2YXIgYT1bXS5zbGljZS5jYWxsKGFyZ3VtZW50cyksZz1cIlwiK2Euam9pbihcIiBcIiksaD17bGV2ZWw6Yixsb2dnZXI6XCJjb25zb2xlXCJ9O2QmJmQoYixnLGgpLGUmJmMmJkZ1bmN0aW9uLnByb3RvdHlwZS5hcHBseS5jYWxsKGUsZixhKX0pfX0sVT17YXR0YWNoOmZ1bmN0aW9uKCl7dmFyIGE9Ui5iaW5kKHRoaXMub25Eb2N1bWVudENsaWNrZWQsdGhpcyksYz1SLmJpbmQodGhpcy5vbklucHV0Q2hhbmdlZCx0aGlzKTtiLmFkZEV2ZW50TGlzdGVuZXI/KGIuYWRkRXZlbnRMaXN0ZW5lcihcImNsaWNrXCIsYSwhMCksYi5hZGRFdmVudExpc3RlbmVyKFwiYmx1clwiLGMsITApKTpiLmF0dGFjaEV2ZW50JiYoYi5hdHRhY2hFdmVudChcIm9uY2xpY2tcIixhKSxiLmF0dGFjaEV2ZW50KFwib25mb2N1c291dFwiLGMpKX0sd3JpdGVVc2VyRXZlbnQ6ZnVuY3Rpb24oYSxiLGMsZCl7XCJwYXNzd29yZFwiPT09dGhpcy5nZXRFbGVtZW50VHlwZShhKSYmKGM9dm9pZCAwKSxTLmFkZChcInVzZXJcIix7dHM6Ui5ub3coKSxhOmIsZTp0aGlzLmdldE91dGVySFRNTChhKSx2OnRoaXMuZ2V0VmFsdWVLaW5kKGMsZCl9KX0sb25Eb2N1bWVudENsaWNrZWQ6ZnVuY3Rpb24oYSl7dmFyIGI9dGhpcy5nZXRFbGVtZW50RnJvbUV2ZW50KGEpO2ImJmIudGFnTmFtZSYmKHRoaXMuaXNUYXJnZXQoYixcImFcIil8fHRoaXMuaXNUYXJnZXQoYixcImJ1dHRvblwiKXx8dGhpcy5pc1RhcmdldChiLFwiaW5wdXRcIixbXCJidXR0b25cIixcInN1Ym1pdFwiXSk/dGhpcy53cml0ZVVzZXJFdmVudChiLFwiY2xpY2tcIik6dGhpcy5pc1RhcmdldChiLFwiaW5wdXRcIixbXCJjaGVja2JveFwiLFwicmFkaW9cIl0pJiZ0aGlzLndyaXRlVXNlckV2ZW50KGIsXCJjaGVja1wiLGIudmFsdWUsYi5jaGVja2VkKSl9LG9uSW5wdXRDaGFuZ2VkOmZ1bmN0aW9uKGEpe3ZhciBiPXRoaXMuZ2V0RWxlbWVudEZyb21FdmVudChhKTtiJiZiLnRhZ05hbWUmJih0aGlzLmlzVGFyZ2V0KGIsXCJ0ZXh0YXJlYVwiKT90aGlzLndyaXRlVXNlckV2ZW50KGIsXCJpbnB1dFwiLGIudmFsdWUpOnRoaXMuaXNUYXJnZXQoYixcInNlbGVjdFwiKSYmYi5vcHRpb25zJiZiLm9wdGlvbnMubGVuZ3RoP3RoaXMub25TZWxlY3RJbnB1dENoYW5nZWQoYik6dGhpcy5pc1RhcmdldChiLFwiaW5wdXRcIikmJiF0aGlzLmlzVGFyZ2V0KGIsXCJpbnB1dFwiLFtcImJ1dHRvblwiLFwic3VibWl0XCIsXCJoaWRkZW5cIixcImNoZWNrYm94XCIsXCJyYWRpb1wiXSkmJnRoaXMud3JpdGVVc2VyRXZlbnQoYixcImlucHV0XCIsYi52YWx1ZSkpfSxvblNlbGVjdElucHV0Q2hhbmdlZDpmdW5jdGlvbihhKXtpZihhLm11bHRpcGxlKXtmb3IodmFyIGI9MDtiPGEub3B0aW9ucy5sZW5ndGg7YisrKWlmKGEub3B0aW9uc1tiXS5zZWxlY3RlZCl7dGhpcy53cml0ZVVzZXJFdmVudChhLFwic2VsZWN0XCIsYS5vcHRpb25zW2JdLnZhbHVlKTticmVha319ZWxzZSAwPD1hLnNlbGVjdGVkSW5kZXgmJmEub3B0aW9uc1thLnNlbGVjdGVkSW5kZXhdJiZ0aGlzLndyaXRlVXNlckV2ZW50KGEsXCJzZWxlY3RcIixhLm9wdGlvbnNbYS5zZWxlY3RlZEluZGV4XS52YWx1ZSl9LGdldEVsZW1lbnRGcm9tRXZlbnQ6ZnVuY3Rpb24oYSl7cmV0dXJuIGEudGFyZ2V0fHxiLmVsZW1lbnRGcm9tUG9pbnQoYS5jbGllbnRYLGEuY2xpZW50WSl9LGlzVGFyZ2V0OmZ1bmN0aW9uKGEsYixjKXtpZihhLnRhZ05hbWUudG9Mb3dlckNhc2UoKSE9PWIudG9Mb3dlckNhc2UoKSlyZXR1cm4hMTtpZighYylyZXR1cm4hMDtmb3IodmFyIGQ9dGhpcy5nZXRFbGVtZW50VHlwZShhKSxlPTA7ZTxjLmxlbmd0aDtlKyspaWYoY1tlXT09PWQpcmV0dXJuITA7cmV0dXJuITF9LGdldEVsZW1lbnRUeXBlOmZ1bmN0aW9uKGEpe3JldHVybihhLmdldEF0dHJpYnV0ZShcInR5cGVcIil8fFwiXCIpLnRvTG93ZXJDYXNlKCl9LGdldE91dGVySFRNTDpmdW5jdGlvbihhKXtmb3IodmFyIGI9XCI8XCIrYS50YWdOYW1lLnRvTG93ZXJDYXNlKCksYz1hLmF0dHJpYnV0ZXMsZD0wLGU9Yy5sZW5ndGg7ZT5kO2QrKyl7dmFyIGY9Y1tkXS5uYW1lO1widmFsdWVcIiE9PWYudG9Mb3dlckNhc2UoKSYmKGIrPVwiIFwiK2YrJz1cIicrY1tkXS52YWx1ZSsnXCInKX1yZXR1cm4gYis9XCIgPlwifSxnZXRWYWx1ZUtpbmQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbnVsbD09YT9udWxsOntsZW5ndGg6YS5sZW5ndGgsY2hlY2tlZDpiLHBhdHRlcm46dGhpcy5tYXRjaElucHV0UGF0dGVybihhKX19LG1hdGNoSW5wdXRQYXR0ZXJuOmZ1bmN0aW9uKGEpe3JldHVyblwiXCI9PT1hP1wiZW1wdHlcIjovXlthLXowLTkhIyQlJicqKz0/XFxeX2B7fH1+XFwtXSsoPzpcXC5bYS16MC05ISMkJSYnKis9P1xcXl9ge3x9flxcLV0rKSpAKD86W2EtejAtOV0oPzpbYS16MC05XFwtXSpbYS16MC05XSk/XFwuKStbYS16MC05XSg/OlthLXowLTlcXC1dKlthLXowLTldKT8kLy50ZXN0KGEpP1wiZW1haWxcIjovXigwP1sxLTldfFsxMl1bMC05XXwzWzAxXSlbXFwvXFwtXSgwP1sxLTldfDFbMDEyXSlbXFwvXFwtXVxcZHs0fSQvLnRlc3QoYSl8fC9eKFxcZHs0fVtcXC9cXC1dKDA/WzEtOV18MVswMTJdKVtcXC9cXC1dMD9bMS05XXxbMTJdWzAtOV18M1swMV0pJC8udGVzdChhKT9cImRhdGVcIjovXig/Oig/OlxcKz8xXFxzKig/OlsuXFwtXVxccyopPyk/KD86XFwoXFxzKihbMi05XTFbMDItOV18WzItOV1bMDItOF0xfFsyLTldWzAyLThdWzAyLTldKVxccypcXCl8KFsyLTldMVswMi05XXxbMi05XVswMi04XTF8WzItOV1bMDItOF1bMDItOV0pKVxccyooPzpbLlxcLV1cXHMqKT8pPyhbMi05XTFbMDItOV18WzItOV1bMDItOV0xfFsyLTldWzAyLTldezJ9KVxccyooPzpbLlxcLV1cXHMqKT8oWzAtOV17NH0pKD86XFxzKig/OiN8eFxcLj98ZXh0XFwuP3xleHRlbnNpb24pXFxzKihcXGQrKSk/JC8udGVzdChhKT9cInBob25lXCI6L15cXHMqJC8udGVzdChhKT9cIndoaXRlc3BhY2VcIjovXlxcZCokLy50ZXN0KGEpP1wibnVtZXJpY1wiOlwiY2hhcmFjdGVyXCJ9LGdldEFsbEV2ZW50czpmdW5jdGlvbigpe3JldHVybiBTLmFsbChcInVzZXJcIil9fSxWPXtub0NvbmZsaWN0OmZ1bmN0aW9uKCl7cmV0dXJuIGEuYXRhdHVzPUQsVn0saXNDb25maWd1cmVkOmZ1bmN0aW9uKCl7cmV0dXJuISFvfSxjb25maWc6ZnVuY3Rpb24oYixjKXtyZXR1cm4gYz1jfHx7fSxvPWIsQy5yZW1vdGVGZXRjaGluZz0hMSx3PVtdLGMmJihwPWMuY3VzdG9tRGF0YSxFPWMudGFnc3x8W10sSj0hKCFjLmVuYWJsZVNvdXJjZW1hcCYmIWMuc291cmNlbWFwKSxzPSEhYy5kaXNhYmxlVXNlckFjdGlvbnMsdD0hIWMuZGlzYWJsZUFqYXhNb25pdG9yaW5nLHU9ISFjLmRpc2FibGVSVU0sRj0hIWMuZGVidWdNb2RlLGMuaWdub3JlRXJyb3JzJiZSLmlzQXJyYXkoYy5pZ25vcmVFcnJvcnMpJiYodz1jLmlnbm9yZUVycm9ycyksVi5zZXRBbGxvd2VkRG9tYWlucyhjLmFsbG93ZWREb21haW5zKSxWLnNldFZlcnNpb24oYy52ZXJzaW9uKSxWLmVuYWJsZU9mZmxpbmUoYy5lbmFibGVPZmZsaW5lfHxjLm9mZmxpbmUpLFYub25CZWZvcmVFcnJvclNlbmQoYy5iZWZvcmVFcnJvclNlbmQpLFYuc2V0R3JvdXBpbmdLZXlDYWxsYmFjayhjLmdyb3VwaW5nS2V5Q2FsbGJhY2spKSxIPVIuY2FuQWxsb3dJbnNlY3VyZVN1Ym1pc3Npb25zKCksdy5wdXNoKC9eU2NyaXB0IGVycm9yXFwuPyQvKSx3LnB1c2goL15KYXZhc2NyaXB0IGVycm9yOiBTY3JpcHQgZXJyb3JcXC4/IG9uIGxpbmUgMCQvKSx3PVIuam9pblJlZ0V4cCh3KSxrKCksdj17ZW5hYmxlZDohMCx0aW1lbGluZTohMCxkaXNwbGF5OiEwLGVycm9yOiEwLGxldmVsczpudWxsfSxSLmlzQm9vbGVhbihjLmNvbnNvbGUpJiYodi5lbmFibGVkPWMuY29uc29sZSksUi5pc0Jvb2xlYW4oYy5jb25zb2xlVGltZWxpbmUpJiYodi50aW1lbGluZT1jLmNvbnNvbGVUaW1lbGluZSksUi5pc0Jvb2xlYW4oYy5jb25zb2xlRGlzcGxheSkmJih2LmRpc3BsYXk9Yy5jb25zb2xlRGlzcGxheSksUi5pc0Jvb2xlYW4oYy5jb25zb2xlRXJyb3JOb3RpZnkpJiYodi5lcnJvcj1jLmNvbnNvbGVFcnJvck5vdGlmeSksUi5pc0FycmF5KGMuY29uc29sZVRpbWVsaW5lTGV2ZWxzKSYmKHYubGV2ZWxzPWMuY29uc29sZVRpbWVsaW5lTGV2ZWxzKSx2LmVuYWJsZWQmJlwiY29uc29sZVwiaW4gYSYmYS5jb25zb2xlLmxvZyYmVC5hdHRhY2goYS5jb25zb2xlLHYudGltZWxpbmUsdi5kaXNwbGF5LHYuZXJyb3Isdi5sZXZlbHMpLHN8fFUuYXR0YWNoKCksdHx8dXx8Vi5fX2F0dGFjaEFqYXhIb29rcygpLFZ9LGluc3RhbGw6ZnVuY3Rpb24oKXtyZXR1cm4gZygpPyhDLnJlcG9ydC5zdWJzY3JpYmUobCksQy5leHRlbmRUb0FzeW5jaHJvbm91c0NhbGxiYWNrcygpLEEmJksmJkEuYWpheEVycm9yKGYpLFYpOnZvaWQgMH0sdW5pbnN0YWxsOmZ1bmN0aW9uKCl7cmV0dXJuIG89bnVsbCxDLnJlcG9ydC51bnN1YnNjcmliZShsKSxBJiZLJiZBLnVuYmluZChcImFqYXhFcnJvclwiLGYpLFZ9LHNldEN1c3RvbURhdGE6ZnVuY3Rpb24oYSl7cmV0dXJuIHA9YSxWfSxzZXRUYWdzOmZ1bmN0aW9uKGEpe3JldHVybiBFPWEsVn0sc2V0QWxsb3dlZERvbWFpbnM6ZnVuY3Rpb24oYSl7cmV0dXJuIGEmJlIuaXNBcnJheShhKSYmKEc9YSksVn0sZ2V0QWxsb3dlZERvbWFpbnM6ZnVuY3Rpb24oKXtyZXR1cm4gR30sc2V0VXNlcjpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gcT17fSxhJiYocS51c2VySWQ9XCJcIithKSxiJiYocS5lbWFpbD1cIlwiK2IpLGMmJihxLmZpcnN0TmFtZT1cIlwiK2MpLGQmJihxLmxhc3ROYW1lPVwiXCIrZCksVn0sc2V0VmVyc2lvbjpmdW5jdGlvbihhKXtyZXR1cm4gYSYmKHI9XCJcIithKSxWfSxlbmFibGVPZmZsaW5lOmZ1bmN0aW9uKGEpe3JldHVybiBSLmlzQm9vbGVhbihhKSYmKEk9YSksVn0sb25CZWZvcmVFcnJvclNlbmQ6ZnVuY3Rpb24oYSl7cmV0dXJuXCJmdW5jdGlvblwiPT10eXBlb2YgYSYmKHo9YSksVn0sc2V0R3JvdXBpbmdLZXlDYWxsYmFjazpmdW5jdGlvbihhKXtyZXR1cm5cImZ1bmN0aW9uXCI9PXR5cGVvZiBhJiYoeT1hKSxWfSxzZXRBUElFbmRwb2ludDpmdW5jdGlvbihhKXtyZXR1cm4gTT1hLFZ9LGluaXQ6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBjJiYoYj1ifHx7fSxiLmN1c3RvbURhdGE9YyksVi5jb25maWcoYSxiKX0sd2l0aEN1c3RvbURhdGE6ZnVuY3Rpb24oYSl7cmV0dXJuIFYuc2V0Q3VzdG9tRGF0YShhKX0sd2l0aFRhZ3M6ZnVuY3Rpb24oYSl7cmV0dXJuIFYuc2V0VGFncyhhKX0sYXR0YWNoOmZ1bmN0aW9uKCl7cmV0dXJuIFYuaW5zdGFsbCgpfSxkZXRhY2g6ZnVuY3Rpb24oKXtyZXR1cm4gVi51bmluc3RhbGwoKX0sbm90aWZ5OmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gVi5zZW5kKGEsYixjKX0sc2VuZFBlcmY6ZnVuY3Rpb24oYSl7cmV0dXJuIHU/dm9pZCBSLmxvZyhcIlJVTSBpcyBkaXNhYmxlZC4gUGxlYXNlIGVuYWJsZSBpdCBpbiB0aGUgY29uZmlnIG9wdGlvbnMuXCIpOm0oTyxhKX0sc2VuZEFqYXhQZXJmOmZ1bmN0aW9uKGEpe3JldHVybiB1P3ZvaWQgUi5sb2coXCJSVU0gaXMgZGlzYWJsZWQuIFBsZWFzZSBlbmFibGUgaXQgaW4gdGhlIGNvbmZpZyBvcHRpb25zLlwiKTptKFAsYSl9LHNlbmRUeG5QZXJmOmZ1bmN0aW9uKGEpe3JldHVybiBtKFEsYSl9LHNlbmQ6ZnVuY3Rpb24oYSxiLGMpe3RyeXtsKEMuY29tcHV0ZVN0YWNrVHJhY2UoYSkse2N1c3RvbURhdGE6Ui5tZXJnZShwLGIpLHRhZ3M6Ui5tZXJnZUFycmF5KEUsYyl9KX1jYXRjaChkKXtpZihhIT09ZCl0aHJvdyBkfXJldHVybiBWfSxfaGVscGVyOlJ9O2EuYXRhdHVzPVZ9KHdpbmRvdyxkb2N1bWVudCx3aW5kb3cualF1ZXJ5KSxmdW5jdGlvbihhLGIsYyl7ZnVuY3Rpb24gZChhKXthLnBsPD0wfHxhdGF0dXMuc2VuZFBlcmYoYSl9ZnVuY3Rpb24gZSgpe3ZhciBiPWEucGVyZm9ybWFuY2V8fGEubW96UGVyZm9ybWFuY2V8fGEubXNQZXJmb3JtYW5jZXx8YS53ZWJraXRQZXJmb3JtYW5jZSxjPWIudGltaW5nLGU9Yi5uYXZpZ2F0aW9uO2lmKDA9PT1jLmxvYWRFdmVudEVuZClyZXR1cm4hMTtjbGVhckludGVydmFsKGkpLGk9bnVsbDt2YXIgZj1jLm5hdmlnYXRpb25TdGFydDswPj1mJiYoZj1jLmZldGNoU3RhcnQpO3ZhciBnPXt9O2Zvcih2YXIgaCBpbiBqKWdbaltoXV09LTEsaCBpbiBjJiYoY1toXTw9MHx8KGdbaltoXV09Y1toXS1mKSk7dmFyIGs9e250eTplLnR5cGUscmM6ZS5yZWRpcmVjdENvdW50LG50OmcucnBzLWcubnMsZHA6Zy5kY2UtZy5ycHMscHI6Zy5sZS1nLmRjZSxmZTpnLmxlLWcucnBzLHBsOmcubGUtZy5uc307ZChrKX1mdW5jdGlvbiBmKCl7aWYoIWh8fCFoLmJEb25lKXJldHVybiExO2NsZWFySW50ZXJ2YWwoaSksaT0hMTt2YXIgYT1oLmdldE1lYXN1cmVzKCk7aWYobnVsbCE9YSYmbnVsbCE9YS5iYWNrZW5kJiZudWxsIT1hLmZyb250ZW5kJiZudWxsIT1hW1wicGFnZSBsb2FkIHRpbWVcIl0mJm51bGwhPWFbXCJ0b3RhbCBsb2FkIHRpbWVcIl0pe3ZhciBiPWEuYmFja2VuZCxjPWEuYmFja2VuZCthLmZyb250ZW5kLGU9e250eTowLHJjOjAsbnQ6YixkcDpjLWIscHI6YVtcInRvdGFsIGxvYWQgdGltZVwiXS1jLGZlOmFbXCJ0b3RhbCBsb2FkIHRpbWVcIl0tYixwbDphW1widG90YWwgbG9hZCB0aW1lXCJdfTtkKGUpfX12YXIgZz0obmV3IERhdGUpLmdldFRpbWUoKSxoPWh8fHt9O2gucT1oLnF8fFtdLGgudmVyc2lvbj1cIjAuM1wiLGgudGFyZ2V0T3JpZ2luPWIubG9jYXRpb24ucHJvdG9jb2wrXCIvL1wiK2IubG9jYXRpb24uaG9zdG5hbWUsaC5iUG9zdE1lc3NhZ2U9ITEsaC5iZWFjb25Vcmw9aC5iZWFjb25Vcmx8fFwiL2ltYWdlcy9iZWFjb24uZ2lmXCIsaC5hdXRvcnVuPSExLGguaW5pdD1mdW5jdGlvbigpe2lmKGguYkRvbmU9ITEsaC5iVW5sb2FkZWQ9ITEsaC5tYXJrcz17fSxoLm1lYXN1cmVzPXt9LGguc3RhcnRzPXt9LGguZmluZFN0YXJ0VGltZSgpLGguYWRkRXZlbnRMaXN0ZW5lcihcImJlZm9yZXVubG9hZFwiLGguYmVmb3JlVW5sb2FkLCExKSxoLmFkZEV2ZW50TGlzdGVuZXIoXCJwYWdlaGlkZVwiLGguYmVmb3JlVW5sb2FkLCExKSxoLmFkZEV2ZW50TGlzdGVuZXIoXCJ1bmxvYWRcIixoLmJlZm9yZVVubG9hZCwhMSksaC5wcm9jZXNzUSgpLFwiY29tcGxldGVcIj09PWIucmVhZHlTdGF0ZSl7dmFyIGM9YS5wZXJmb3JtYW5jZXx8YS5tb3pQZXJmb3JtYW5jZXx8YS5tc1BlcmZvcm1hbmNlfHxhLndlYmtpdFBlcmZvcm1hbmNlO2MmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBjLnRpbWluZyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGMudGltaW5nLmxvYWRFdmVudEVuZCYmKGgubWFyayhcImZpcnN0Ynl0ZVwiLGMudGltaW5nLnJlc3BvbnNlU3RhcnQpLGgubWFyayhcIm9ubG9hZFwiLGMudGltaW5nLmxvYWRFdmVudEVuZCkpLGguZG9uZSgpfWVsc2UgaC5hZGRFdmVudExpc3RlbmVyKFwibG9hZFwiLGgub25sb2FkLCExKX0saC5wcm9jZXNzUT1mdW5jdGlvbigpe2Zvcih2YXIgYT1oLnEubGVuZ3RoLGI9MDthPmI7YisrKXt2YXIgYz1oLnFbYl0sZD1jWzBdO1wibWFya1wiPT09ZD9oLm1hcmsoY1sxXSxjWzJdKTpcIm1lYXN1cmVcIj09PWQ/aC5tZWFzdXJlKGNbMV0sY1syXSxjWzNdKTpcImRvbmVcIj09PWQmJmguZG9uZShjWzFdKX19LGgubWFyaz1mdW5jdGlvbihiLGMpe3JldHVybiBoLmRwcmludChcIlJVTV9FUElTT0RFUy5tYXJrOiBcIitiK1wiLCBcIitjKSxiPyhoLm1hcmtzW2JdPXBhcnNlSW50KGN8fChuZXcgRGF0ZSkuZ2V0VGltZSgpKSxoLmJQb3N0TWVzc2FnZSYmYS5wb3N0TWVzc2FnZShcIlJVTV9FUElTT0RFUzptYXJrOlwiK2IrXCI6XCIrYyxoLnRhcmdldE9yaWdpbiksdm9pZChcImZpcnN0Ynl0ZVwiPT09Yj9oLm1lYXN1cmUoXCJiYWNrZW5kXCIsXCJzdGFydHRpbWVcIixcImZpcnN0Ynl0ZVwiKTpcIm9ubG9hZFwiPT09Yj8oaC5tZWFzdXJlKFwiZnJvbnRlbmRcIixcImZpcnN0Ynl0ZVwiLFwib25sb2FkXCIpLGgubWVhc3VyZShcInBhZ2UgbG9hZCB0aW1lXCIsXCJzdGFydHRpbWVcIixcIm9ubG9hZFwiKSk6XCJkb25lXCI9PT1iJiZoLm1lYXN1cmUoXCJ0b3RhbCBsb2FkIHRpbWVcIixcInN0YXJ0dGltZVwiLFwiZG9uZVwiKSkpOnZvaWQgaC5kcHJpbnQoXCJFcnJvcjogbWFya05hbWUgaXMgdW5kZWZpbmVkIGluIFJVTV9FUElTT0RFUy5tYXJrLlwiKX0saC5tZWFzdXJlPWZ1bmN0aW9uKGIsYyxkKXtpZihoLmRwcmludChcIlJVTV9FUElTT0RFUy5tZWFzdXJlOiBcIitiK1wiLCBcIitjK1wiLCBcIitkKSwhYilyZXR1cm4gdm9pZCBoLmRwcmludChcIkVycm9yOiBlcGlzb2RlTmFtZSBpcyB1bmRlZmluZWQgaW4gUlVNX0VQSVNPREVTLm1lYXN1cmUuXCIpO3ZhciBlO2lmKFwidW5kZWZpbmVkXCI9PXR5cGVvZiBjKWU9XCJudW1iZXJcIj09dHlwZW9mIGgubWFya3NbYl0/aC5tYXJrc1tiXToobmV3IERhdGUpLmdldFRpbWUoKTtlbHNlIGlmKFwibnVtYmVyXCI9PXR5cGVvZiBoLm1hcmtzW2NdKWU9aC5tYXJrc1tjXTtlbHNle2lmKFwibnVtYmVyXCIhPXR5cGVvZiBjKXJldHVybiB2b2lkIGguZHByaW50KFwiRXJyb3I6IHVuZXhwZWN0ZWQgc3RhcnROYW1lT3JUaW1lIGluIFJVTV9FUElTT0RFUy5tZWFzdXJlOiBcIitjKTtlPWN9dmFyIGY7aWYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIGQpZj0obmV3IERhdGUpLmdldFRpbWUoKTtlbHNlIGlmKFwibnVtYmVyXCI9PXR5cGVvZiBoLm1hcmtzW2RdKWY9aC5tYXJrc1tkXTtlbHNle2lmKFwibnVtYmVyXCIhPXR5cGVvZiBkKXJldHVybiB2b2lkIGguZHByaW50KFwiRXJyb3I6IHVuZXhwZWN0ZWQgZW5kTmFtZU9yVGltZSBpbiBSVU1fRVBJU09ERVMubWVhc3VyZTogXCIrZCk7Zj1kfWguc3RhcnRzW2JdPXBhcnNlSW50KGUpLGgubWVhc3VyZXNbYl09cGFyc2VJbnQoZi1lKSxoLmJQb3N0TWVzc2FnZSYmYS5wb3N0TWVzc2FnZShcIlJVTV9FUElTT0RFUzptZWFzdXJlOlwiK2IrXCI6XCIrZStcIjpcIitmLGgudGFyZ2V0T3JpZ2luKX0saC5kb25lPWZ1bmN0aW9uKGIpe2guYkRvbmU9ITAsaC5tYXJrKFwiZG9uZVwiKSxoLmJQb3N0TWVzc2FnZSYmYS5wb3N0TWVzc2FnZShcIlJVTV9FUElTT0RFUzpkb25lXCIsaC50YXJnZXRPcmlnaW4pLFwiZnVuY3Rpb25cIj09dHlwZW9mIGImJmIoKX0saC5nZXRNYXJrcz1mdW5jdGlvbigpe3JldHVybiBoLm1hcmtzfSxoLmdldE1lYXN1cmVzPWZ1bmN0aW9uKCl7cmV0dXJuIGgubWVhc3VyZXN9LGguZ2V0U3RhcnRzPWZ1bmN0aW9uKCl7cmV0dXJuIGguc3RhcnRzfSxoLmZpbmRTdGFydFRpbWU9ZnVuY3Rpb24oKXt2YXIgYT1oLmZpbmRTdGFydFdlYlRpbWluZygpfHxoLmZpbmRTdGFydENvb2tpZSgpO2EmJmgubWFyayhcInN0YXJ0dGltZVwiLGEpfSxoLmZpbmRTdGFydFdlYlRpbWluZz1mdW5jdGlvbigpe3ZhciBiLGM9YS5wZXJmb3JtYW5jZXx8YS5tb3pQZXJmb3JtYW5jZXx8YS5tc1BlcmZvcm1hbmNlfHxhLndlYmtpdFBlcmZvcm1hbmNlO3JldHVybiBjJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgYy50aW1pbmcmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBjLnRpbWluZy5uYXZpZ2F0aW9uU3RhcnQmJihiPWMudGltaW5nLm5hdmlnYXRpb25TdGFydCxoLmRwcmludChcIlJVTV9FUElTT0RFUy5maW5kU3RhcnRXZWJUaW1pbmc6IHN0YXJ0VGltZSA9IFwiK2IpKSxifSxoLmZpbmRTdGFydENvb2tpZT1mdW5jdGlvbigpe2Zvcih2YXIgZD1iLmNvb2tpZS5zcGxpdChcIiBcIiksZT0wO2U8ZC5sZW5ndGg7ZSsrKWlmKDA9PT1kW2VdLmluZGV4T2YoXCJSVU1fRVBJU09ERVM9XCIpKXtmb3IodmFyIGYsZyxpPWRbZV0uc3Vic3RyaW5nKFwiUlVNX0VQSVNPREVTPVwiLmxlbmd0aCkuc3BsaXQoXCImXCIpLGo9MDtqPGkubGVuZ3RoO2orKylpZigwPT09aVtqXS5pbmRleE9mKFwicz1cIikpZj1pW2pdLnN1YnN0cmluZygyKTtlbHNlIGlmKDA9PT1pW2pdLmluZGV4T2YoXCJyPVwiKSl7dmFyIGs9aVtqXS5zdWJzdHJpbmcoMik7az1rLnJlcGxhY2UoLzskLyxcIlwiKSxnPWEuZXNjYXBlKGIucmVmZXJyZXIpPT09a31pZihnJiZmKXJldHVybiBoLmRwcmludChcIlJVTV9FUElTT0RFUy5maW5kU3RhcnRDb29raWU6IHN0YXJ0VGltZSA9IFwiK2YpLGZ9cmV0dXJuIGN9LGguYmVmb3JlVW5sb2FkPWZ1bmN0aW9uKCl7aC5iVW5sb2FkZWR8fChiLmNvb2tpZT1cIlJVTV9FUElTT0RFUz1zPVwiK051bWJlcihuZXcgRGF0ZSkrXCImcj1cIithLmVzY2FwZShiLmxvY2F0aW9uKStcIjsgcGF0aD0vXCIsaC5iVW5sb2FkZWQ9ITApfSxoLm9ubG9hZD1mdW5jdGlvbigpe2gubWFyayhcIm9ubG9hZFwiKSxoLmRvbmUoKX0saC5hZGRFdmVudExpc3RlbmVyPWZ1bmN0aW9uKGIsYyxkKXtyZXR1cm5cInVuZGVmaW5lZFwiIT10eXBlb2YgYS5hdHRhY2hFdmVudD9hLmF0dGFjaEV2ZW50KFwib25cIitiLGMpOmEuYWRkRXZlbnRMaXN0ZW5lcj9hLmFkZEV2ZW50TGlzdGVuZXIoYixjLGQpOnZvaWQgMH0saC5kcHJpbnQ9ZnVuY3Rpb24oKXt9LGguaW5pdCgpO3ZhciBpPW51bGwsaj17bmF2aWdhdGlvblN0YXJ0OlwibnNcIixyZWRpcmVjdFN0YXJ0OlwicmRzXCIscmVkaXJlY3RFbmQ6XCJyZGVcIix1bmxvYWRFdmVudFN0YXJ0OlwidXNcIix1bmxvYWRFdmVudEVuZDpcInVlXCIsZmV0Y2hTdGFydDpcImZzXCIsZG9tYWluTG9va3VwU3RhcnQ6XCJkbHNcIixkb21haW5Mb29rdXBFbmQ6XCJkbGVcIixjb25uZWN0U3RhcnQ6XCJjc1wiLHNlY3VyZUNvbm5lY3Rpb25TdGFydDpcInNjc1wiLGNvbm5lY3RFbmQ6XCJjZVwiLGhhbmRzaGFrZVN0YXJ0OlwiaHNcIixyZXF1ZXN0U3RhcnQ6XCJycXNcIixyZXNwb25zZVN0YXJ0OlwicnBzXCIscmVzcG9uc2VFbmQ6XCJycGVcIixkb21Mb2FkaW5nOlwiZGxcIixkb21JbnRlcmFjdGl2ZTpcImRpXCIsZG9tQ29udGVudExvYWRlZEV2ZW50U3RhcnQ6XCJkY3NcIixkb21Db250ZW50TG9hZGVkRXZlbnRFbmQ6XCJkY2VcIixkb21Db21wbGV0ZTpcImRjXCIsbG9hZEV2ZW50U3RhcnQ6XCJsc1wiLGxvYWRFdmVudEVuZDpcImxlXCJ9LGs9YS5wZXJmb3JtYW5jZXx8YS5tb3pQZXJmb3JtYW5jZXx8YS5tc1BlcmZvcm1hbmNlfHxhLndlYmtpdFBlcmZvcm1hbmNlO2smJlwidW5kZWZpbmVkXCIhPXR5cGVvZiBrLnRpbWluZyYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGsubmF2aWdhdGlvbj9pPXNldEludGVydmFsKGUsMTAwKTooaC5tYXJrKFwiZmlyc3RieXRlXCIsZyksaT1zZXRJbnRlcnZhbChmLDEwMCkpfSh3aW5kb3csZG9jdW1lbnQpLGF0YXR1cy5fX2F0dGFjaEFqYXhIb29rcz1mdW5jdGlvbigpeyFmdW5jdGlvbihhLGIpe3ZhciBjPWF0YXR1cy5faGVscGVyLGQ9e3F1ZXVlOltdLGJhdGNoU2l6ZToyNSxwcm9jZXNzaW5nOiExLGJVbmxvYWRlZDohMSxwdXNoOmZ1bmN0aW9uKGEpe1wic3RyaW5nXCI9PXR5cGVvZiBhLnVybCYmYS51cmwuaW5kZXhPZihcIi5odG1sXCIpPjB8fCh0aGlzLnF1ZXVlLnB1c2goYSksdGhpcy5xdWV1ZS5sZW5ndGg+PXRoaXMuYmF0Y2hTaXplJiZ0aGlzLl9wcm9jZXNzUXVldWUoKSl9LF9wcm9jZXNzUXVldWU6ZnVuY3Rpb24oKXtpZighdGhpcy5wcm9jZXNzaW5nJiZ0aGlzLnF1ZXVlLmxlbmd0aCl7dGhpcy5wcm9jZXNzaW5nPSEwO3RyeXtmb3IodmFyIGE9e30sYj17fSxkPTA7ZDx0aGlzLnF1ZXVlLmxlbmd0aDtkKyspe3ZhciBlLGY9dGhpcy5xdWV1ZVtkXTtpZihmLnN0YXR1czw0MDApe2U9Zi5tZXRob2QrZi51cmw7dmFyIGc9Zi5yZXNwQXZhaWxUaW1lLWYuc2VuZFRpbWUsaD1mLnJlc3BQcm9jVGltZS1mLnJlc3BBdmFpbFRpbWUsaT1mLnJlY2VpdmVkU2l6ZSxqPWYuc2VuZFNpemUsaz1hW2VdO2lmKGspe2suYysrO3ZhciBsPWsucmU7bC50PWwudCtnLGwubG89bC5sbzxnP2wubG86ZyxsLmhpPWwuaGk+Zz9sLmhpOmcsbC5zc3E9bC5zc3ErZypnO3ZhciBtPWsuY2I7bS50PW0udCtoLG0ubG89bS5sbzxoP20ubG86aCxtLmhpPW0uaGk+aD9tLmhpOmgsbS5zc3E9bS5zc3EraCpoO3ZhciBuPWsucnM7bi50PW4udCtpLG4ubG89bi5sbzxpP24ubG86aSxuLmhpPW4uaGk+aT9uLmhpOmksbi5zc3E9bi5zc3EraSppO3ZhciBvPWsuc3M7by50PW8udCtqLG8ubG89by5sbzxqP28ubG86aixvLmhpPW8uaGk+aj9vLmhpOmosby5zc3E9by5zc3EraipqfWVsc2UgYVtlXT17bTpmLm1ldGhvZCx1cmw6Zi51cmwsYzoxLHJlOnt0OmcsbG86ZyxoaTpnLHNzcTpnKmd9LGNiOnt0OmgsbG86aCxoaTpoLHNzcTpoKmh9LHJzOnt0OmYucmVjZWl2ZWRTaXplLGxvOmYucmVjZWl2ZWRTaXplLGhpOmYucmVjZWl2ZWRTaXplLHNzcTpmLnJlY2VpdmVkU2l6ZSpmLnJlY2VpdmVkU2l6ZX0sc3M6e3Q6Zi5zZW5kU2l6ZSxsbzpmLnNlbmRTaXplLGhpOmYuc2VuZFNpemUsc3NxOmYuc2VuZFNpemUqZi5zZW5kU2l6ZX19fWVsc2UgZT1mLm1ldGhvZCtmLnN0YXR1cytmLnVybCxiW2VdP2JbZV0uYysrOmJbZV09e206Zi5tZXRob2QsdXJsOmYudXJsLHN0OmYuc3RhdHVzLGM6MX19dmFyIHA9e3hocjpjLmFycmF5RnJvbU9iamVjdChhKSx4aHJFcnJvcjpjLmFycmF5RnJvbU9iamVjdChiKX07YXRhdHVzLnNlbmRBamF4UGVyZihwKX1jYXRjaChxKXtjLmxvZyhcIkVycm9yIHdoaWxlIHByb2Nlc3NpbmcgcXVldWU6IFwiLHEpfWZpbmFsbHl7dGhpcy5xdWV1ZT1bXSx0aGlzLnByb2Nlc3Npbmc9ITF9fX0sYmVmb3JlVW5sb2FkOmZ1bmN0aW9uKCl7ZC5iVW5sb2FkZWR8fChkLl9wcm9jZXNzUXVldWUoKSxkLmJVbmxvYWRlZD0hMCl9fTtjLmFkZEV2ZW50TGlzdGVuZXIoXCJiZWZvcmV1bmxvYWRcIixkLmJlZm9yZVVubG9hZCwhMSk7dmFyIGU9e3N1cHBvcnQ6ZnVuY3Rpb24oYSl7cmV0dXJuIWF8fFwiYXBwbHlcImluIGF9LGFyb3VuZDpmdW5jdGlvbihhLGIsZCxlKXtyZXR1cm4gYT1hfHxmdW5jdGlvbigpe30sZnVuY3Rpb24oKXt2YXIgZixnPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7dHJ5e2ImJihmPWIuYXBwbHkodGhpcyxnKSl9Y2F0Y2goaCl7Yy5sb2coZSxoKX12YXIgaTt0cnl7aT1hLmFwcGx5KHRoaXMsZnx8Zyl9ZmluYWxseXt0cnl7ZCYmZC5hcHBseSh0aGlzLGcpfWNhdGNoKGgpe2MubG9nKGUsaCl9fXJldHVybiBpfX0sYmVmb3JlOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGUuYXJvdW5kKGEsYil9LGFmdGVyOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGUuYXJvdW5kKGEsbnVsbCxiKX0sdGltZW91dDpmdW5jdGlvbihhKXtzZXRUaW1lb3V0KGEsMCl9LHdyYXBBZGRFdmVudExpc3RlbmVyOmZ1bmN0aW9uKCl7cmV0dXJuIGZ1bmN0aW9uKGEsYil7aWYoKFwibG9hZFwiPT09YXx8XCJlcnJvclwiPT09YSkmJmImJnRoaXMuX2F0cnVtWGhyRGF0YSl7dmFyIGM7Yi5fX2F0cnVtSW50ZXJjZXB0b3I/Yz1iLl9fYXRydW1JbnRlcmNlcHRvcjplLnN1cHBvcnQoYik/KGM9Zy53cmFwWEhSKGIsdGhpcyxcIlhIUi5pbnZva2VFdmVudExpc3RlbmVyXCIpLGIuX19hdHJ1bUludGVyY2VwdG9yPWMpOmM9bnVsbDt2YXIgZDtyZXR1cm4gYyYmKGQ9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKSxkWzFdPWMpLGR9fX0sd3JhcFJlbW92ZUV2ZW50TGlzdGVuZXI6ZnVuY3Rpb24oKXtyZXR1cm4gZnVuY3Rpb24oYSxiKXtpZih0aGlzLl9hdHJ1bVhockRhdGEpe3ZhciBjPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7cmV0dXJuIGIuX19hdHJ1bUludGVyY2VwdG9yJiYoY1sxXT1iLl9fYXRydW1JbnRlcmNlcHRvciksY319fSxhcm91bmRXaXRoSGFuZGxlRXZlbnQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIGY9YTtyZXR1cm4gYSYmXCJvYmplY3RcIj09dHlwZW9mIGEmJlwidG9TdHJpbmdcImluIGEmJlwiW3hwY29ubmVjdCB3cmFwcGVkIG5zSURPTUV2ZW50TGlzdGVuZXJdXCI9PT1hLnRvU3RyaW5nKCkmJlwiaGFuZGxlRXZlbnRcImluIGEmJihmPWZ1bmN0aW9uKCl7YS5oYW5kbGVFdmVudC5hcHBseSh0aGlzLEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cykpfSksZS5hcm91bmQoZixiLGMsZCl9LGdldEZ1bGx5UXVhbGlmaWVkVXJsOmZ1bmN0aW9uKGEpe3ZhciBjPWIuY3JlYXRlRWxlbWVudChcImFcIik7cmV0dXJuIGMuaHJlZj1hLGMuaHJlZn19O2lmKGEuWE1MSHR0cFJlcXVlc3QmJmEuWE1MSHR0cFJlcXVlc3QucHJvdG90eXBlKXt2YXIgZj1hLlhNTEh0dHBSZXF1ZXN0LnByb3RvdHlwZTtpZighKFwib3BlblwiaW4gZiYmXCJzZW5kXCJpbiBmKSlyZXR1cm47aWYoIWUuc3VwcG9ydChmLm9wZW4pfHwhZS5zdXBwb3J0KGYuc2VuZCkpcmV0dXJuO3ZhciBnPXt9O2cuY2FwdHVyZUFqYXhUaW1pbmdzPWZ1bmN0aW9uKGEpe3ZhciBiPWEuX2F0cnVtWGhyRGF0YTtpZihiKXt2YXIgYz0obmV3IERhdGUpLmdldFRpbWUoKTsyPT09YS5yZWFkeVN0YXRlP2IuZmlyc3RCeXRlVGltZT1iLmZpcnN0Qnl0ZVRpbWV8fGM6ND09PWEucmVhZHlTdGF0ZSYmKGIucmVzcEF2YWlsVGltZT1iLnJlc3BBdmFpbFRpbWV8fGMsYi5maXJzdEJ5dGVUaW1lPWIuZmlyc3RCeXRlVGltZXx8Yyl9fSxnLnNlbmRQYXlsb2FkPWZ1bmN0aW9uKGEsYil7Yi5yZWNlaXZlZFNpemU9MCxhLnJlc3BvbnNlVHlwZSYmXCJ0ZXh0XCIhPT1hLnJlc3BvbnNlVHlwZXx8XCJzdHJpbmdcIj09dHlwZW9mIGEucmVzcG9uc2VUZXh0JiYoYi5yZWNlaXZlZFNpemU9YS5yZXNwb25zZVRleHQubGVuZ3RoKSxiLnN0YXR1cz1hLnN0YXR1cyxkLnB1c2goYil9LGcud3JhcFhIUj1mdW5jdGlvbihhLGIsYyl7cmV0dXJuIGUuYXJvdW5kV2l0aEhhbmRsZUV2ZW50KGEsZnVuY3Rpb24oKXtnLmNhcHR1cmVBamF4VGltaW5ncyh0aGlzKX0sZnVuY3Rpb24oKXt2YXIgYT1iLl9hdHJ1bVhockRhdGE7aWYoYSYmND09PWIucmVhZHlTdGF0ZSl7dmFyIGM9KG5ldyBEYXRlKS5nZXRUaW1lKCk7YS5yZXNwUHJvY1RpbWU9YS5yZXNwUHJvY1RpbWV8fGMsZy5zZW5kUGF5bG9hZChiLGEpLGRlbGV0ZSBiLl9hdHJ1bVhockRhdGF9fSxjKX0sZy5hamF4RG9uZT1mdW5jdGlvbihhKXtpZihhLl9hdHJ1bVhockRhdGEpe3ZhciBiPShuZXcgRGF0ZSkuZ2V0VGltZSgpKzNlNCxjPWZ1bmN0aW9uKCl7Zy5jYXB0dXJlQWpheFRpbWluZ3MoYSk7dmFyIGQ9YS5fYXRydW1YaHJEYXRhO2lmKGQpe3ZhciBlPShuZXcgRGF0ZSkuZ2V0VGltZSgpOzQ9PT1hLnJlYWR5U3RhdGU/KGQucmVzcFByb2NUaW1lPWQucmVzcFByb2NUaW1lfHxlLGcuc2VuZFBheWxvYWQoYSxkKSxkZWxldGUgYS5fYXRydW1YaHJEYXRhKTpiPmU/c2V0VGltZW91dChjLDUwKTpkZWxldGUgYS5fYXRydW1YaHJEYXRhfX07YygpfX0sZi5vcGVuPWUuYXJvdW5kKGYub3BlbixmdW5jdGlvbigpe3ZhciBhPTE8PWFyZ3VtZW50cy5sZW5ndGg/U3RyaW5nKGFyZ3VtZW50c1swXSk6XCJcIixiPTI8PWFyZ3VtZW50cy5sZW5ndGg/U3RyaW5nKGFyZ3VtZW50c1sxXSk6XCJcIixjPWF0YXR1cy5nZXRBbGxvd2VkRG9tYWlucygpLGQ9ITA7aWYoYj1lLmdldEZ1bGx5UXVhbGlmaWVkVXJsKGIpLGImJmMmJmMubGVuZ3RoKXtkPSExO2Zvcih2YXIgZj0wO2Y8Yy5sZW5ndGg7ZisrKXt2YXIgZz1jW2ZdO2lmKGcmJmIuaW5kZXhPZihnKT4tMSl7ZD0hMDticmVha319fWQmJihiPWImJmIuc3BsaXQoXCI/XCIpWzBdLHRoaXMuX2F0cnVtWGhyRGF0YT17bWV0aG9kOmEsdXJsOmIsc2VuZFRpbWU6bnVsbCxzZW5kU2l6ZTpudWxsLGZpcnN0Qnl0ZVRpbWU6bnVsbCxyZXNwQXZhaWxUaW1lOm51bGwscmVzcFByb2NUaW1lOm51bGwscmVjZWl2ZWRTaXplOm51bGwscGFyZW50UGhhc2U6bnVsbH0pfSxudWxsLFwiWEhSLm9wZW5cIiksZi5zZW5kPWUuYXJvdW5kKGYuc2VuZCxmdW5jdGlvbigpe3ZhciBhPXRoaXMsYj1hLl9hdHJ1bVhockRhdGE7aWYoYil7dmFyIGM9KG5ldyBEYXRlKS5nZXRUaW1lKCk7Yi5zZW5kVGltZT1iLnNlbmRUaW1lfHxjLGIuc2VuZFNpemU9MTw9YXJndW1lbnRzLmxlbmd0aCYmYXJndW1lbnRzWzBdP2FyZ3VtZW50c1swXS5sZW5ndGh8fDA6MDt2YXIgZD0wLGY9ZnVuY3Rpb24oKXtpZig0PT09YS5yZWFkeVN0YXRlKWcuYWpheERvbmUoYSk7ZWxzZXt2YXIgYj1udWxsO3RyeXtiPWEub25yZWFkeXN0YXRlY2hhbmdlfWNhdGNoKGMpe3JldHVybiB2b2lkIGcuYWpheERvbmUoYSl9ZCsrLGI/ZS5zdXBwb3J0KGIpP2Eub25yZWFkeXN0YXRlY2hhbmdlPWcud3JhcFhIUihiLGEsXCJYSFIub25SZWFkeVN0YXRlQ2hhbmdlXCIpOmcuYWpheERvbmUoYSk6NT5kP2UudGltZW91dChmKTpnLmFqYXhEb25lKGEpfX07ZigpfX0sbnVsbCxcIlhIUi5zZW5kXCIpLFwiYWRkRXZlbnRMaXN0ZW5lclwiaW4gZiYmXCJyZW1vdmVFdmVudExpc3RlbmVyXCJpbiBmJiZlLnN1cHBvcnQoZi5hZGRFdmVudExpc3RlbmVyKSYmZS5zdXBwb3J0KGYucmVtb3ZlRXZlbnRMaXN0ZW5lcikmJihmLmFkZEV2ZW50TGlzdGVuZXI9ZS5hcm91bmQoZi5hZGRFdmVudExpc3RlbmVyLGUud3JhcEFkZEV2ZW50TGlzdGVuZXIoKSxudWxsLFwiWEhSLmFkZEV2ZW50TGlzdGVuZXJcIiksZi5yZW1vdmVFdmVudExpc3RlbmVyPWUuYXJvdW5kKGYucmVtb3ZlRXZlbnRMaXN0ZW5lcixlLndyYXBSZW1vdmVFdmVudExpc3RlbmVyKCksbnVsbCxcIlhIUi5yZW1vdmVFdmVudExpc3RlbmVyXCIpKX19KHdpbmRvdyxkb2N1bWVudCl9LGZ1bmN0aW9uKGEpe2Z1bmN0aW9uIGIoYSxiLGMpe2lmKCEoMD49Yikpe3ZhciBkPXtuYW1lOmEsZHVyOmIsc3Q6Y307YXRhdHVzLnNlbmRUeG5QZXJmKGQpfX1mdW5jdGlvbiBjKGEpe3JldHVybiBoK1wiIFwiK2F9ZnVuY3Rpb24gZCgpe3RyeXtyZXR1cm5cImxvY2FsU3RvcmFnZVwiaW4gYSYmbnVsbCE9PWEubG9jYWxTdG9yYWdlO31jYXRjaChiKXtyZXR1cm4hMX19ZnVuY3Rpb24gZShhKXt2YXIgYj1pLm5vdygpO3RyeXtsb2NhbFN0b3JhZ2Uuc2V0SXRlbShjKGEpLGIpfWNhdGNoKGQpe319ZnVuY3Rpb24gZihhKXt2YXIgYj1udWxsLGQ9YyhhKTt0cnl7Yj1sb2NhbFN0b3JhZ2UuZ2V0SXRlbShkKSxsb2NhbFN0b3JhZ2UucmVtb3ZlSXRlbShkKX1jYXRjaChlKXt9dmFyIGY9MDtyZXR1cm4gYiYmKGY9aS5ub3coKS1iKSxmfWZ1bmN0aW9uIGcoYSl7dHJ5e3ZhciBiPWMoYSk7bG9jYWxTdG9yYWdlLnJlbW92ZUl0ZW0oYil9Y2F0Y2goZCl7fX12YXIgaD1cImF0YXR1cy5jb20vXCIsaT1hdGF0dXMuX2hlbHBlcixqPTEsaz0wO2F0YXR1cy5iZWdpblRyYW5zYWN0aW9uPWZ1bmN0aW9uKGEpe2QoKSYmZShhKX0sYXRhdHVzLmVuZFRyYW5zYWN0aW9uPWZ1bmN0aW9uKGEpe2lmKGQoKSl7dmFyIGM9ZihhKTtiKGEsYyxqKX19LGF0YXR1cy5mYWlsVHJhbnNhY3Rpb249ZnVuY3Rpb24oYSl7aWYoZCgpKXt2YXIgYz1mKGEpO2IoYSxjLGspfX0sYXRhdHVzLmNhbmNlbFRyYW5zYWN0aW9uPWZ1bmN0aW9uKGEpe2QoKSYmZyhhKX19KHdpbmRvdyxkb2N1bWVudCk7XG4vKiEgaHR0cHM6Ly9naXRodWIuY29tL3R0YXViZXJ0L25vZGUtYXJyYXlidWZmZXItc2xpY2VcbiAqIChjKSAyMDE0IFRpbSBUYXViZXJ0IDx0aW1AdGltdGF1YmVydC5kZT5cbiAqIGFycmF5YnVmZmVyLXNsaWNlIG1heSBiZSBmcmVlbHkgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLiovXG4hZnVuY3Rpb24ocil7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gdChyLHQpe3JldHVybiByPTB8cnx8MCxyPDA/TWF0aC5tYXgocit0LDApOk1hdGgubWluKHIsdCl9QXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlfHwoQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlPWZ1bmN0aW9uKGUsbil7dmFyIGY9dGhpcy5ieXRlTGVuZ3RoLGk9dChlLGYpLGE9ZjtpZihuIT09ciYmKGE9dChuLGYpKSxpPmEpcmV0dXJuIG5ldyBBcnJheUJ1ZmZlcigwKTt2YXIgdT1hLWkseT1uZXcgQXJyYXlCdWZmZXIodSksbz1uZXcgVWludDhBcnJheSh5KSxzPW5ldyBVaW50OEFycmF5KHRoaXMsaSx1KTtyZXR1cm4gby5zZXQocykseX0pfSgpO1xuIWZ1bmN0aW9uKHQpe2Z1bmN0aW9uIGUocil7aWYoaVtyXSlyZXR1cm4gaVtyXS50O3ZhciBuPWlbcl09e3Q6e30saWQ6cixsb2FkZWQ6ITF9O3JldHVybiB0W3JdLmNhbGwobi50LG4sbi50LGUpLG4ubG9hZGVkPSEwLG4udH12YXIgaT17fTtyZXR1cm4gZS5pPXQsZS5jPWksZS5vPVwiXCIsZSgwKX0oW2Z1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcj10aGlzJiZ0aGlzLl9fZXh0ZW5kc3x8ZnVuY3Rpb24odCxlKXtmdW5jdGlvbiBpKCl7dGhpcy5jb25zdHJ1Y3Rvcj10fWZvcih2YXIgciBpbiBlKWUuaGFzT3duUHJvcGVydHkocikmJih0W3JdPWVbcl0pO3QucHJvdG90eXBlPW51bGw9PT1lP09iamVjdC5jcmVhdGUoZSk6KGkucHJvdG90eXBlPWUucHJvdG90eXBlLG5ldyBpKX0sbj1pKDI1KSxvPWkoNykscz1pKDkpLGE9aSgxKTtpZihcInVuZGVmaW5lZFwiPT10eXBlb2YgYyl2YXIgYz0zZTQ7dmFyIGg9ZnVuY3Rpb24odCl7ZnVuY3Rpb24gZShlLGkpe3ZhciByPXQuY2FsbCh0aGlzLGkpfHx0aGlzO3JldHVybiByLnBsdWdpbk5hbWU9XCJiaXRtb3ZpblwiLHIucz0hMSxyLnBsYXllcj1lLHIucGxheWVyLmluaXRTZXNzaW9uPWZ1bmN0aW9uKHQpe3JldHVybiByLmgoKSxyLnAodCkudGltZW91dChjLHIudStcIiBIaXZlIFBsdWdpbiBpbml0aWFsaXphdGlvbiB0aW1lb3V0XCIpLnRoZW4oZnVuY3Rpb24odCl7cmV0dXJuIHIubCgpLHQuZygpfSlbXCJjYXRjaFwiXShmdW5jdGlvbih0KXtyZXR1cm4gci52KCksci5oKCksci5tKCkuZGVidWcoci51K1wiIGVycm9yIG9jY3VycmVkIHJlc29sdmluZyB0aGUgdGlja2V0IC0gXCIrdC5zdGFjayksYS5yZWplY3QodCl9KX0sci5tKCkubm90aWNlKHIudStcInJlZ2lzdGVyZWQgcGx1Z2luIFtuYW1lOlwiK3IuVCgpK1wiXVtpZDogXCIrci5TKCkrXCJdW3ZlcnNpb246IFwiK3IuSSgpK1wiXVwiKSxyfXJldHVybiByKGUsdCksZS5wcm90b3R5cGUubD1mdW5jdGlvbigpe3ZhciB0PXRoaXM7dGhpcy5zfHwodGhpcy5wbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKFwib25SZWFkeVwiLGZ1bmN0aW9uKCl7aWYodC5tKCkuZGVidWcoXCJiaXRtb3Zpbi5wbGF5ZXIuRVZFTlQuT05fUkVBRFlcIiksdC5SKCkpe3ZhciBlPSEhdC5wbGF5ZXIuZ2V0Q29uZmlnKCkucGxheWJhY2smJnQucGxheWVyLmdldENvbmZpZygpLnBsYXliYWNrLmF1dG87ZSYmdC5rKCExKSx0LkMoKSYmKHQuTz1uZXcgby5QKX19KSx0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvblBsYXlcIixmdW5jdGlvbigpe3QubSgpLmRlYnVnKFwiYml0bW92aW4ucGxheWVyLkVWRU5ULk9OX1BMQVlcIiksdC5BKHMuRi5CLk4pfSksdGhpcy5wbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKFwib25FcnJvclwiLGZ1bmN0aW9uKGUpe3QubSgpLmRlYnVnKFwiYml0bW92aW4ucGxheWVyLkVWRU5ULk9OX0VSUk9SXCIpO3ZhciBpPS0xLHI9bnVsbDtpZihudWxsIT1lKXRyeXtpPWUuY29kZSxyPUpTT04uc3RyaW5naWZ5KGUsbnVsbCl9Y2F0Y2gobil7cj1lfXQub25FcnJvcihpLHIpfSksdGhpcy5wbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKFwib25QbGF5YmFja0ZpbmlzaGVkXCIsZnVuY3Rpb24oKXt0Lm0oKS5kZWJ1ZyhcImJpdG1vdmluLnBsYXllci5FVkVOVC5PTl9QTEFZQkFDS19GSU5JU0hFRFwiKSx0Ll8ocy5GLkIuRCx7Y29kZToxfSl9KSx0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvblNlZWtcIixmdW5jdGlvbigpe3QubSgpLmRlYnVnKFwiYml0bW92aW4ucGxheWVyLkVWRU5ULk9OX1NFRUtcIiksdC5fKHMuRi5CLkgpfSksdGhpcy5wbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKFwib25GdWxsc2NyZWVuRW50ZXJcIixmdW5jdGlvbigpe3QubSgpLmRlYnVnKFwiYml0bW92aW4ucGxheWVyLkVWRU5ULk9OX0ZVTExTQ1JFRU5fRU5URVJcIiksdC5fKHMuRi5CLkwse3ZhbHVlOiEwfSl9KSx0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvbkZ1bGxzY3JlZW5FeGl0XCIsZnVuY3Rpb24oKXt0Lm0oKS5kZWJ1ZyhcImJpdG1vdmluLnBsYXllci5FVkVOVC5PTl9GVUxMU0NSRUVOX0VYSVRcIiksdC5fKHMuRi5CLkwse3ZhbHVlOiExfSl9KSx0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvblNlZ21lbnRSZXF1ZXN0RmluaXNoZWRcIixmdW5jdGlvbihlKXt2YXIgaT1lLm1pbWVUeXBlLmluZGV4T2YoXCJ2aWRlb1wiKT49MDtpZihlLnN1Y2Nlc3Mpe3ZhciByPTgqZS5zaXplL2UuZG93bmxvYWRUaW1lO3QuTy5NKGksdC5qLGUuc2l6ZSksdC5PLlUocil9ZWxzZSB0Lk8uVihpLHQuail9KSwwPT09dGhpcy5xKCkuaW5kZXhPZihcIjdcIik/dGhpcy5KKCk6MD09PXRoaXMucSgpLmluZGV4T2YoXCI2XCIpJiZ0aGlzLksoKSx0aGlzLnM9ITApfSxlLnByb3RvdHlwZS5LPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpczt0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvblN0YXJ0QnVmZmVyaW5nXCIsZnVuY3Rpb24oKXt0Lm0oKS5kZWJ1ZyhcImJpdG1vdmluLnBsYXllci5FVkVOVC5PTl9TVEFSVF9CVUZGRVJJTkdcIiksdC5rKCl9KSx0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvblN0b3BCdWZmZXJpbmdcIixmdW5jdGlvbigpe3QubSgpLmRlYnVnKFwiYml0bW92aW4ucGxheWVyLkVWRU5ULk9OX1NUT1BfQlVGRkVSSU5HXCIpLHQuRygpfSksdGhpcy5wbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKFwib25QYXVzZVwiLGZ1bmN0aW9uKCl7dC5tKCkuZGVidWcoXCJiaXRtb3Zpbi5wbGF5ZXIuRVZFTlQuT05fUEFVU0VcIiksdC5BKHMuRi5CLlcpfSksdGhpcy5wbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKFwib25WaWRlb0Rvd25sb2FkUXVhbGl0eUNoYW5nZVwiLGZ1bmN0aW9uKGUpe3ZhciBpPXQuJCgpO2k9PT1TdHJlYW1Qcm90b2NvbC5ZP3QuWChlLnRhcmdldFF1YWxpdHkpOnQuWChlLnRhcmdldFF1YWxpdHkuc3BsaXQoXCJiclwiKVsxXSl9KX0sZS5wcm90b3R5cGUuSj1mdW5jdGlvbigpe3ZhciB0PXRoaXM7dGhpcy5wbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKFwib25TdGFsbFN0YXJ0ZWRcIixmdW5jdGlvbigpe3QubSgpLmRlYnVnKFwiYml0bW92aW4ucGxheWVyLkVWRU5ULk9OX1NUQUxMX1NUQVJURURcIiksdC5rKCl9KSx0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvblN0YWxsRW5kZWRcIixmdW5jdGlvbigpe3QubSgpLmRlYnVnKFwiYml0bW92aW4ucGxheWVyLkVWRU5ULk9OX1NUQUxMX0VOREVEXCIpLHQuRygpfSksdGhpcy5wbGF5ZXIuYWRkRXZlbnRIYW5kbGVyKFwib25QYXVzZWRcIixmdW5jdGlvbigpe3QubSgpLmRlYnVnKFwiYml0bW92aW4ucGxheWVyLkVWRU5ULk9OX1BBVVNFRFwiKSx0LkEocy5GLkIuVyl9KSx0aGlzLnBsYXllci5hZGRFdmVudEhhbmRsZXIoXCJvblZpZGVvRG93bmxvYWRRdWFsaXR5Q2hhbmdlZFwiLGZ1bmN0aW9uKGUpe3QuWChlLnRhcmdldFF1YWxpdHlJZC5iaXRyYXRlKX0pfSxlLnByb3RvdHlwZS5YPWZ1bmN0aW9uKHQpe3RoaXMubSgpLmRlYnVnKFwibmV3Qml0cmF0ZVwiLHQpLHRoaXMuaiYmdD50aGlzLmo/dGhpcy5PLlooKTp0aGlzLmomJnRoaXMuaj50JiZ0aGlzLk8udHQoKSx0aGlzLmo9dH0sZS5wcm90b3R5cGUuQT1mdW5jdGlvbih0KXtcInVuZGVmaW5lZFwiIT10eXBlb2YgdGhpcy5ldCYmdGhpcy5ldCE9PXQmJih0aGlzLl8odCksdGhpcy5ldD10KX0sZS5wcm90b3R5cGUuaXQ9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLiQoKTtyZXR1cm4gdD09PVN0cmVhbVByb3RvY29sLlk/dGhpcy5wbGF5ZXIuZ2V0Q29uZmlnKCkuc291cmNlLmhsczp0PT09U3RyZWFtUHJvdG9jb2wucnQ/dGhpcy5wbGF5ZXIuZ2V0Q29uZmlnKCkuc291cmNlLmRhc2g6dm9pZCAwfSxlLnByb3RvdHlwZS5nZXRDdXJyZW50VGltZT1mdW5jdGlvbigpe3JldHVybiBudWxsIT10aGlzLnBsYXllcj9NYXRoLnJvdW5kKDFlMyp0aGlzLnBsYXllci5nZXRDdXJyZW50VGltZSgpKTowfSxlLnByb3RvdHlwZS5udD1mdW5jdGlvbigpe3JldHVybiBudWxsIT10aGlzLnBsYXllciYmbnVsbCE9dGhpcy5wbGF5ZXIuZ2V0VmlkZW9CdWZmZXJMZW5ndGgmJnRoaXMucGxheWVyLmdldFZpZGVvQnVmZmVyTGVuZ3RoKCk+MD9NYXRoLm1heCgwLE1hdGgucm91bmQoMWUzKnRoaXMucGxheWVyLmdldFZpZGVvQnVmZmVyTGVuZ3RoKCkpKTowfSxlLnByb3RvdHlwZS5vdD1mdW5jdGlvbigpe2lmKHRoaXMucGxheWVyKXt2YXIgdD10aGlzLnBsYXllci5nZXRGaWd1cmUoKTtyZXR1cm57d2lkdGg6dC5vZmZzZXRXaWR0aCxoZWlnaHQ6dC5vZmZzZXRIZWlnaHR9fX0sZS5wcm90b3R5cGUuaXNGdWxsc2NyZWVuPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucGxheWVyLmlzRnVsbHNjcmVlbigpfSxlLnByb3RvdHlwZS5pc0xpdmU9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5wbGF5ZXIuaXNMaXZlKCl9LGUucHJvdG90eXBlLnN0PWZ1bmN0aW9uKCl7cmV0dXJuITB9LGUucHJvdG90eXBlLiQ9ZnVuY3Rpb24oKXtpZih0aGlzLnBsYXllcil7dmFyIHQ9dGhpcy5wbGF5ZXIuZ2V0U3RyZWFtVHlwZSgpO2lmKFwiaGxzXCI9PT10KXJldHVybiBTdHJlYW1Qcm90b2NvbC5ZO2lmKFwiZGFzaFwiPT09dClyZXR1cm4gU3RyZWFtUHJvdG9jb2wucnR9cmV0dXJuIG51bGx9LGUucHJvdG90eXBlLmF0PWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5PO3JldHVybiB0aGlzLk89bmV3IG8uUCx0fSxlLnByb3RvdHlwZS5UPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMucGx1Z2luTmFtZX0sZS5wcm90b3R5cGUuST1mdW5jdGlvbigpe3JldHVybiB0aGlzLmN0KCl9LGUucHJvdG90eXBlLmh0PWZ1bmN0aW9uKCl7aWYodGhpcy5wbGF5ZXIpcmV0dXJuIHRoaXMucGxheWVyLmdldFBsYXllclR5cGUoKX0sZS5wcm90b3R5cGUucT1mdW5jdGlvbigpe3JldHVyblwidW5kZWZpbmVkXCIhPXR5cGVvZiBiaXRtb3Zpbi5wbGF5ZXIudmVyc2lvbj9iaXRtb3Zpbi5wbGF5ZXIudmVyc2lvbjp0aGlzLnBsYXllci5nZXRWZXJzaW9uKCl9LGV9KG4ucHQuUGx1Z2luKTtlLnV0PWg7dmFyIHA9ZnVuY3Rpb24odCxlKXtuZXcgaCh0LGUpfTtiaXRtb3Zpbi5pbml0SGl2ZVNETj1wfSxmdW5jdGlvbih0LGUsaSl7LyohXG4gKlxuICogQ29weXJpZ2h0IDIwMDktMjAxNiBLcmlzIEtvd2FsIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgTUlUXG4gKiBsaWNlbnNlIGZvdW5kIGF0IGh0dHBzOi8vZ2l0aHViLmNvbS9rcmlza293YWwvcS9ibG9iL3YxL0xJQ0VOU0VcbiAqXG4gKiBXaXRoIHBhcnRzIGJ5IFR5bGVyIENsb3NlXG4gKiBDb3B5cmlnaHQgMjAwNy0yMDA5IFR5bGVyIENsb3NlIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgTUlUIFggbGljZW5zZSBmb3VuZFxuICogYXQgaHR0cDovL3d3dy5vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5odG1sXG4gKiBGb3JrZWQgYXQgcmVmX3NlbmQuanMgdmVyc2lvbjogMjAwOS0wNS0xMVxuICpcbiAqIFdpdGggcGFydHMgYnkgTWFyayBNaWxsZXJcbiAqIENvcHlyaWdodCAoQykgMjAxMSBHb29nbGUgSW5jLlxuICpcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIik7XG4gKiB5b3UgbWF5IG5vdCB1c2UgdGhpcyBmaWxlIGV4Y2VwdCBpbiBjb21wbGlhbmNlIHdpdGggdGhlIExpY2Vuc2UuXG4gKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXRcbiAqXG4gKiBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjBcbiAqXG4gKiBVbmxlc3MgcmVxdWlyZWQgYnkgYXBwbGljYWJsZSBsYXcgb3IgYWdyZWVkIHRvIGluIHdyaXRpbmcsIHNvZnR3YXJlXG4gKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiBcIkFTIElTXCIgQkFTSVMsXG4gKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC5cbiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmRcbiAqIGxpbWl0YXRpb25zIHVuZGVyIHRoZSBMaWNlbnNlLlxuICpcbiAqL1xuICAhZnVuY3Rpb24oZSl7XCJ1c2Ugc3RyaWN0XCI7aWYoXCJmdW5jdGlvblwiPT10eXBlb2YgYm9vdHN0cmFwKWJvb3RzdHJhcChcInByb21pc2VcIixlKTtlbHNle3QudD1lKCl9fShmdW5jdGlvbigpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIHQodCl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIHouYXBwbHkodCxhcmd1bWVudHMpfX1mdW5jdGlvbiBlKHQpe3JldHVybiB0PT09T2JqZWN0KHQpfWZ1bmN0aW9uIGkodCl7cmV0dXJuXCJbb2JqZWN0IFN0b3BJdGVyYXRpb25dXCI9PT1pdCh0KXx8dCBpbnN0YW5jZW9mIHF9ZnVuY3Rpb24gcih0LGUpe2lmKFUmJmUuc3RhY2smJlwib2JqZWN0XCI9PXR5cGVvZiB0JiZudWxsIT09dCYmdC5zdGFjayYmdC5zdGFjay5pbmRleE9mKHJ0KT09PS0xKXtmb3IodmFyIGk9W10scj1lO3I7cj1yLnNvdXJjZSlyLnN0YWNrJiZpLnVuc2hpZnQoci5zdGFjayk7aS51bnNoaWZ0KHQuc3RhY2spO3ZhciBvPWkuam9pbihcIlxcblwiK3J0K1wiXFxuXCIpO3Quc3RhY2s9bihvKX19ZnVuY3Rpb24gbih0KXtmb3IodmFyIGU9dC5zcGxpdChcIlxcblwiKSxpPVtdLHI9MDtyPGUubGVuZ3RoOysrcil7dmFyIG49ZVtyXTthKG4pfHxvKG4pfHwhbnx8aS5wdXNoKG4pfXJldHVybiBpLmpvaW4oXCJcXG5cIil9ZnVuY3Rpb24gbyh0KXtyZXR1cm4gdC5pbmRleE9mKFwiKG1vZHVsZS5qczpcIikhPT0tMXx8dC5pbmRleE9mKFwiKG5vZGUuanM6XCIpIT09LTF9ZnVuY3Rpb24gcyh0KXt2YXIgZT0vYXQgLisgXFwoKC4rKTooXFxkKyk6KD86XFxkKylcXCkkLy5leGVjKHQpO2lmKGUpcmV0dXJuW2VbMV0sTnVtYmVyKGVbMl0pXTt2YXIgaT0vYXQgKFteIF0rKTooXFxkKyk6KD86XFxkKykkLy5leGVjKHQpO2lmKGkpcmV0dXJuW2lbMV0sTnVtYmVyKGlbMl0pXTt2YXIgcj0vLipAKC4rKTooXFxkKykkLy5leGVjKHQpO3JldHVybiByP1tyWzFdLE51bWJlcihyWzJdKV06dm9pZCAwfWZ1bmN0aW9uIGEodCl7dmFyIGU9cyh0KTtpZighZSlyZXR1cm4hMTt2YXIgaT1lWzBdLHI9ZVsxXTtyZXR1cm4gaT09PVEmJnI+PUomJnI8PWN0fWZ1bmN0aW9uIGMoKXtpZihVKXRyeXt0aHJvdyBuZXcgRXJyb3J9Y2F0Y2godCl7dmFyIGU9dC5zdGFjay5zcGxpdChcIlxcblwiKSxpPWVbMF0uaW5kZXhPZihcIkBcIik+MD9lWzFdOmVbMl0scj1zKGkpO2lmKCFyKXJldHVybjtyZXR1cm4gUT1yWzBdLHJbMV19fWZ1bmN0aW9uIGgodCxlLGkpe3JldHVybiBmdW5jdGlvbigpe3JldHVyblwidW5kZWZpbmVkXCIhPXR5cGVvZiBjb25zb2xlJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBjb25zb2xlLndhcm4mJmNvbnNvbGUud2FybihlK1wiIGlzIGRlcHJlY2F0ZWQsIHVzZSBcIitpK1wiIGluc3RlYWQuXCIsbmV3IEVycm9yKFwiXCIpLnN0YWNrKSx0LmFwcGx5KHQsYXJndW1lbnRzKX19ZnVuY3Rpb24gcCh0KXtyZXR1cm4gdCBpbnN0YW5jZW9mIGY/dDptKHQpP0ModCk6ayh0KX1mdW5jdGlvbiB1KCl7ZnVuY3Rpb24gdCh0KXtlPXQscC5sdCYmVSYmKG8uc291cmNlPXQpLCQoaSxmdW5jdGlvbihlLGkpe3AuZHQoZnVuY3Rpb24oKXt0LmZ0LmFwcGx5KHQsaSl9KX0sdm9pZCAwKSxpPXZvaWQgMCxyPXZvaWQgMH12YXIgZSxpPVtdLHI9W10sbj1aKHUucHJvdG90eXBlKSxvPVooZi5wcm90b3R5cGUpO2lmKG8uZnQ9ZnVuY3Rpb24odCxuLG8pe3ZhciBzPVcoYXJndW1lbnRzKTtpPyhpLnB1c2gocyksXCJ3aGVuXCI9PT1uJiZvWzFdJiZyLnB1c2gob1sxXSkpOnAuZHQoZnVuY3Rpb24oKXtlLmZ0LmFwcGx5KGUscyl9KX0sby52YWx1ZU9mPWZ1bmN0aW9uKCl7aWYoaSlyZXR1cm4gbzt2YXIgdD12KGUpO3JldHVybiB5KHQpJiYoZT10KSx0fSxvLmd0PWZ1bmN0aW9uKCl7cmV0dXJuIGU/ZS5ndCgpOntzdGF0ZTpcInBlbmRpbmdcIn19LHAubHQmJlUpdHJ5e3Rocm93IG5ldyBFcnJvcn1jYXRjaChzKXtvLnN0YWNrPXMuc3RhY2suc3Vic3RyaW5nKHMuc3RhY2suaW5kZXhPZihcIlxcblwiKSsxKX1yZXR1cm4gbi52dD1vLG4ucmVzb2x2ZT1mdW5jdGlvbihpKXtlfHx0KHAoaSkpfSxuLnl0PWZ1bmN0aW9uKGkpe2V8fHQoayhpKSl9LG4ucmVqZWN0PWZ1bmN0aW9uKGkpe2V8fHQoUihpKSl9LG4ubm90aWZ5PWZ1bmN0aW9uKHQpe2V8fCQocixmdW5jdGlvbihlLGkpe3AuZHQoZnVuY3Rpb24oKXtpKHQpfSl9LHZvaWQgMCl9LG59ZnVuY3Rpb24gbCh0KXtpZihcImZ1bmN0aW9uXCIhPXR5cGVvZiB0KXRocm93IG5ldyBUeXBlRXJyb3IoXCJyZXNvbHZlciBtdXN0IGJlIGEgZnVuY3Rpb24uXCIpO3ZhciBlPXUoKTt0cnl7dChlLnJlc29sdmUsZS5yZWplY3QsZS5ub3RpZnkpfWNhdGNoKGkpe2UucmVqZWN0KGkpfXJldHVybiBlLnZ0fWZ1bmN0aW9uIGQodCl7cmV0dXJuIGwoZnVuY3Rpb24oZSxpKXtmb3IodmFyIHI9MCxuPXQubGVuZ3RoO3I8bjtyKyspcCh0W3JdKS50aGVuKGUsaSl9KX1mdW5jdGlvbiBmKHQsZSxpKXt2b2lkIDA9PT1lJiYoZT1mdW5jdGlvbih0KXtyZXR1cm4gUihuZXcgRXJyb3IoXCJQcm9taXNlIGRvZXMgbm90IHN1cHBvcnQgb3BlcmF0aW9uOiBcIit0KSl9KSx2b2lkIDA9PT1pJiYoaT1mdW5jdGlvbigpe3JldHVybntzdGF0ZTpcInVua25vd25cIn19KTt2YXIgcj1aKGYucHJvdG90eXBlKTtpZihyLmZ0PWZ1bmN0aW9uKGksbixvKXt2YXIgczt0cnl7cz10W25dP3Rbbl0uYXBwbHkocixvKTplLmNhbGwocixuLG8pfWNhdGNoKGEpe3M9UihhKX1pJiZpKHMpfSxyLmd0PWksaSl7dmFyIG49aSgpO1wicmVqZWN0ZWRcIj09PW4uc3RhdGUmJihyLmV4Y2VwdGlvbj1uLnJlYXNvbiksci52YWx1ZU9mPWZ1bmN0aW9uKCl7dmFyIHQ9aSgpO3JldHVyblwicGVuZGluZ1wiPT09dC5zdGF0ZXx8XCJyZWplY3RlZFwiPT09dC5zdGF0ZT9yOnQudmFsdWV9fXJldHVybiByfWZ1bmN0aW9uIGcodCxlLGkscil7cmV0dXJuIHAodCkudGhlbihlLGkscil9ZnVuY3Rpb24gdih0KXtpZih5KHQpKXt2YXIgZT10Lmd0KCk7aWYoXCJmdWxmaWxsZWRcIj09PWUuc3RhdGUpcmV0dXJuIGUudmFsdWV9cmV0dXJuIHR9ZnVuY3Rpb24geSh0KXtyZXR1cm4gdCBpbnN0YW5jZW9mIGZ9ZnVuY3Rpb24gbSh0KXtyZXR1cm4gZSh0KSYmXCJmdW5jdGlvblwiPT10eXBlb2YgdC50aGVufWZ1bmN0aW9uIHcodCl7cmV0dXJuIHkodCkmJlwicGVuZGluZ1wiPT09dC5ndCgpLnN0YXRlfWZ1bmN0aW9uIFQodCl7cmV0dXJuIXkodCl8fFwiZnVsZmlsbGVkXCI9PT10Lmd0KCkuc3RhdGV9ZnVuY3Rpb24gUyh0KXtyZXR1cm4geSh0KSYmXCJyZWplY3RlZFwiPT09dC5ndCgpLnN0YXRlfWZ1bmN0aW9uIGIoKXtudC5sZW5ndGg9MCxvdC5sZW5ndGg9MCxhdHx8KGF0PSEwKX1mdW5jdGlvbiBFKHQsZSl7YXQmJihcIm9iamVjdFwiPT10eXBlb2YgcHJvY2VzcyYmXCJmdW5jdGlvblwiPT10eXBlb2YgcHJvY2Vzcy5lbWl0JiZwLmR0Lnd0KGZ1bmN0aW9uKCl7WShvdCx0KSE9PS0xJiYocHJvY2Vzcy5lbWl0KFwidW5oYW5kbGVkUmVqZWN0aW9uXCIsZSx0KSxzdC5wdXNoKHQpKX0pLG90LnB1c2godCksZSYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGUuc3RhY2s/bnQucHVzaChlLnN0YWNrKTpudC5wdXNoKFwiKG5vIHN0YWNrKSBcIitlKSl9ZnVuY3Rpb24gSSh0KXtpZihhdCl7dmFyIGU9WShvdCx0KTtlIT09LTEmJihcIm9iamVjdFwiPT10eXBlb2YgcHJvY2VzcyYmXCJmdW5jdGlvblwiPT10eXBlb2YgcHJvY2Vzcy5lbWl0JiZwLmR0Lnd0KGZ1bmN0aW9uKCl7dmFyIGk9WShzdCx0KTtpIT09LTEmJihwcm9jZXNzLmVtaXQoXCJyZWplY3Rpb25IYW5kbGVkXCIsbnRbZV0sdCksc3Quc3BsaWNlKGksMSkpfSksb3Quc3BsaWNlKGUsMSksbnQuc3BsaWNlKGUsMSkpfX1mdW5jdGlvbiBSKHQpe3ZhciBlPWYoe3doZW46ZnVuY3Rpb24oZSl7cmV0dXJuIGUmJkkodGhpcyksZT9lKHQpOnRoaXN9fSxmdW5jdGlvbigpe3JldHVybiB0aGlzfSxmdW5jdGlvbigpe3JldHVybntzdGF0ZTpcInJlamVjdGVkXCIscmVhc29uOnR9fSk7cmV0dXJuIEUoZSx0KSxlfWZ1bmN0aW9uIGsodCl7cmV0dXJuIGYoe3doZW46ZnVuY3Rpb24oKXtyZXR1cm4gdH0sZ2V0OmZ1bmN0aW9uKGUpe3JldHVybiB0W2VdfSxzZXQ6ZnVuY3Rpb24oZSxpKXt0W2VdPWl9LFwiZGVsZXRlXCI6ZnVuY3Rpb24oZSl7ZGVsZXRlIHRbZV19LFR0OmZ1bmN0aW9uKGUsaSl7cmV0dXJuIG51bGw9PT1lfHx2b2lkIDA9PT1lP3QuYXBwbHkodm9pZCAwLGkpOnRbZV0uYXBwbHkodCxpKX0sYXBwbHk6ZnVuY3Rpb24oZSxpKXtyZXR1cm4gdC5hcHBseShlLGkpfSxrZXlzOmZ1bmN0aW9uKCl7cmV0dXJuIGV0KHQpfX0sdm9pZCAwLGZ1bmN0aW9uKCl7cmV0dXJue3N0YXRlOlwiZnVsZmlsbGVkXCIsdmFsdWU6dH19KX1mdW5jdGlvbiBDKHQpe3ZhciBlPXUoKTtyZXR1cm4gcC5kdChmdW5jdGlvbigpe3RyeXt0LnRoZW4oZS5yZXNvbHZlLGUucmVqZWN0LGUubm90aWZ5KX1jYXRjaChpKXtlLnJlamVjdChpKX19KSxlLnZ0fWZ1bmN0aW9uIE8odCl7cmV0dXJuIGYoe1N0OmZ1bmN0aW9uKCl7fX0sZnVuY3Rpb24oZSxpKXtyZXR1cm4gRih0LGUsaSl9LGZ1bmN0aW9uKCl7cmV0dXJuIHAodCkuZ3QoKX0pfWZ1bmN0aW9uIFAodCxlLGkpe3JldHVybiBwKHQpLmJ0KGUsaSl9ZnVuY3Rpb24gQSh0KXtyZXR1cm4gZnVuY3Rpb24oKXtmdW5jdGlvbiBlKHQsZSl7dmFyIHM7aWYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIFN0b3BJdGVyYXRpb24pe3RyeXtzPXJbdF0oZSl9Y2F0Y2goYSl7cmV0dXJuIFIoYSl9cmV0dXJuIHMuZG9uZT9wKHMudmFsdWUpOmcocy52YWx1ZSxuLG8pfXRyeXtzPXJbdF0oZSl9Y2F0Y2goYSl7cmV0dXJuIGkoYSk/cChhLnZhbHVlKTpSKGEpfXJldHVybiBnKHMsbixvKX12YXIgcj10LmFwcGx5KHRoaXMsYXJndW1lbnRzKSxuPWUuYmluZChlLFwibmV4dFwiKSxvPWUuYmluZChlLFwidGhyb3dcIik7cmV0dXJuIG4oKX19ZnVuY3Rpb24gTih0KXtwLmRvbmUocC5hc3luYyh0KSgpKX1mdW5jdGlvbiB4KHQpe3Rocm93IG5ldyBxKHQpfWZ1bmN0aW9uIEIodCl7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIFAoW3RoaXMsXyhhcmd1bWVudHMpXSxmdW5jdGlvbihlLGkpe3JldHVybiB0LmFwcGx5KGUsaSl9KX19ZnVuY3Rpb24gRih0LGUsaSl7cmV0dXJuIHAodCkuRXQoZSxpKX1mdW5jdGlvbiBfKHQpe3JldHVybiBnKHQsZnVuY3Rpb24odCl7dmFyIGU9MCxpPXUoKTtyZXR1cm4gJCh0LGZ1bmN0aW9uKHIsbixvKXt2YXIgczt5KG4pJiZcImZ1bGZpbGxlZFwiPT09KHM9bi5ndCgpKS5zdGF0ZT90W29dPXMudmFsdWU6KCsrZSxnKG4sZnVuY3Rpb24ocil7dFtvXT1yLDA9PT0tLWUmJmkucmVzb2x2ZSh0KX0saS5yZWplY3QsZnVuY3Rpb24odCl7aS5ub3RpZnkoe2luZGV4Om8sdmFsdWU6dH0pfSkpfSx2b2lkIDApLDA9PT1lJiZpLnJlc29sdmUodCksaS52dH0pfWZ1bmN0aW9uIEQodCl7aWYoMD09PXQubGVuZ3RoKXJldHVybiBwLnJlc29sdmUoKTt2YXIgZT1wLmRlZmVyKCksaT0wO3JldHVybiAkKHQsZnVuY3Rpb24ocixuLG8pe2Z1bmN0aW9uIHModCl7ZS5yZXNvbHZlKHQpfWZ1bmN0aW9uIGEodCl7aS0tLDA9PT1pJiYodC5tZXNzYWdlPVwiUSBjYW4ndCBnZXQgZnVsZmlsbG1lbnQgdmFsdWUgZnJvbSBhbnkgcHJvbWlzZSwgYWxsIHByb21pc2VzIHdlcmUgcmVqZWN0ZWQuIExhc3QgZXJyb3IgbWVzc2FnZTogXCIrdC5tZXNzYWdlLGUucmVqZWN0KHQpKX1mdW5jdGlvbiBjKHQpe2Uubm90aWZ5KHtpbmRleDpvLHZhbHVlOnR9KX12YXIgaD10W29dO2krKyxnKGgscyxhLGMpfSx2b2lkIDApLGUudnR9ZnVuY3Rpb24gSCh0KXtyZXR1cm4gZyh0LGZ1bmN0aW9uKHQpe3JldHVybiB0PVgodCxwKSxnKF8oWCh0LGZ1bmN0aW9uKHQpe3JldHVybiBnKHQsSyxLKX0pKSxmdW5jdGlvbigpe3JldHVybiB0fSl9KX1mdW5jdGlvbiBMKHQpe3JldHVybiBwKHQpLkl0KCl9ZnVuY3Rpb24gTSh0LGUpe3JldHVybiBwKHQpLnRoZW4odm9pZCAwLHZvaWQgMCxlKX1mdW5jdGlvbiBqKHQsZSl7cmV0dXJuIHAodCkuUnQoZSl9dmFyIFU9ITE7dHJ5e3Rocm93IG5ldyBFcnJvcn1jYXRjaChWKXtVPSEhVi5zdGFja312YXIgUSxxLEo9YygpLEs9ZnVuY3Rpb24oKXt9LEc9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7Zm9yKHZhciB0LHI7aS5uZXh0OylpPWkubmV4dCx0PWkua3QsaS5rdD12b2lkIDAscj1pLmRvbWFpbixyJiYoaS5kb21haW49dm9pZCAwLHIuZW50ZXIoKSksZSh0LHIpO2Zvcig7aC5sZW5ndGg7KXQ9aC5wb3AoKSxlKHQpO249ITF9ZnVuY3Rpb24gZShlLGkpe3RyeXtlKCl9Y2F0Y2gocil7aWYocyl0aHJvdyBpJiZpLmV4aXQoKSxzZXRUaW1lb3V0KHQsMCksaSYmaS5lbnRlcigpLHI7c2V0VGltZW91dChmdW5jdGlvbigpe3Rocm93IHJ9LDApfWkmJmkuZXhpdCgpfXZhciBpPXtrdDp2b2lkIDAsbmV4dDpudWxsfSxyPWksbj0hMSxvPXZvaWQgMCxzPSExLGE9ITE7dHJ5e2E9bmF2aWdhdG9yJiYoXCJNaWNyb3NvZnQgSW50ZXJuZXQgRXhwbG9yZXJcIj09PW5hdmlnYXRvci5hcHBOYW1lfHxudWxsIT1uYXZpZ2F0b3IuYXBwVmVyc2lvbi5tYXRjaCgvKHRyaWRlbnQpLitydls6XFxzXShbXFx3XFwuXSspLitsaWtlXFxzZ2Vja28vaSkpfWNhdGNoKGMpe312YXIgaD1bXTtpZihHPWZ1bmN0aW9uKHQpe1widW5kZWZpbmVkXCIhPXR5cGVvZiBGcmFtZXdvcmsmJkZyYW1ld29yay5DdCgpP0ZyYW1ld29yay5zZXRUaW1lb3V0KHQsMCk6KHI9ci5uZXh0PXtrdDp0LGRvbWFpbjpzJiZwcm9jZXNzLmRvbWFpbixuZXh0Om51bGx9LG58fChuPSEwLG8oKSkpfSxcIm9iamVjdFwiPT10eXBlb2YgcHJvY2VzcyYmXCJbb2JqZWN0IHByb2Nlc3NdXCI9PT1wcm9jZXNzLnRvU3RyaW5nKCkmJnByb2Nlc3MuZHQpcz0hMCxvPWZ1bmN0aW9uKCl7cHJvY2Vzcy5kdCh0KX07ZWxzZSBpZihcImZ1bmN0aW9uXCIhPXR5cGVvZiBzZXRJbW1lZGlhdGV8fGEpaWYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIE1lc3NhZ2VDaGFubmVsfHxhKW89ZnVuY3Rpb24oKXtzZXRUaW1lb3V0KHQsMCl9O2Vsc2V7dmFyIHA9bmV3IE1lc3NhZ2VDaGFubmVsO3AucG9ydDEub25tZXNzYWdlPWZ1bmN0aW9uKCl7bz11LHAucG9ydDEub25tZXNzYWdlPXQsdCgpfTt2YXIgdT1mdW5jdGlvbigpe3AucG9ydDIucG9zdE1lc3NhZ2UoMCl9O289ZnVuY3Rpb24oKXtzZXRUaW1lb3V0KHQsMCksdSgpfX1lbHNlIG89XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvdz9zZXRJbW1lZGlhdGUuYmluZCh3aW5kb3csdCk6ZnVuY3Rpb24oKXtzZXRJbW1lZGlhdGUodCl9O3JldHVybiBHLnd0PWZ1bmN0aW9uKHQpe2gucHVzaCh0KSxufHwobj0hMCxvKCkpfSxHfSgpLHo9RnVuY3Rpb24uY2FsbCxXPXQoQXJyYXkucHJvdG90eXBlLnNsaWNlKSwkPXQoQXJyYXkucHJvdG90eXBlLnJlZHVjZXx8ZnVuY3Rpb24odCxlKXt2YXIgaT0wLHI9dGhpcy5sZW5ndGg7aWYoMT09PWFyZ3VtZW50cy5sZW5ndGgpZm9yKDs7KXtpZihpIGluIHRoaXMpe2U9dGhpc1tpKytdO2JyZWFrfWlmKCsraT49cil0aHJvdyBuZXcgVHlwZUVycm9yfWZvcig7aTxyO2krKylpIGluIHRoaXMmJihlPXQoZSx0aGlzW2ldLGkpKTtyZXR1cm4gZX0pLFk9dChBcnJheS5wcm90b3R5cGUuaW5kZXhPZnx8ZnVuY3Rpb24odCl7Zm9yKHZhciBlPTA7ZTx0aGlzLmxlbmd0aDtlKyspaWYodGhpc1tlXT09PXQpcmV0dXJuIGU7cmV0dXJuLTF9KSxYPXQoQXJyYXkucHJvdG90eXBlLm1hcHx8ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzLHI9W107cmV0dXJuICQoaSxmdW5jdGlvbihuLG8scyl7ci5wdXNoKHQuY2FsbChlLG8scyxpKSl9LHZvaWQgMCkscn0pLFo9T2JqZWN0LmNyZWF0ZXx8ZnVuY3Rpb24odCl7ZnVuY3Rpb24gZSgpe31yZXR1cm4gZS5wcm90b3R5cGU9dCxuZXcgZX0sdHQ9dChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5KSxldD1PYmplY3Qua2V5c3x8ZnVuY3Rpb24odCl7dmFyIGU9W107Zm9yKHZhciBpIGluIHQpdHQodCxpKSYmZS5wdXNoKGkpO3JldHVybiBlfSxpdD10KE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcpO3E9XCJ1bmRlZmluZWRcIiE9dHlwZW9mIFJldHVyblZhbHVlP1JldHVyblZhbHVlOmZ1bmN0aW9uKHQpe3RoaXMudmFsdWU9dH07dmFyIHJ0PVwiRnJvbSBwcmV2aW91cyBldmVudDpcIjtwLnJlc29sdmU9cCxwLmR0PUcscC5sdD0hMSxcIm9iamVjdFwiPT10eXBlb2YgcHJvY2VzcyYmcHJvY2VzcyYmcHJvY2Vzcy5PdCYmcHJvY2Vzcy5PdC5RX0RFQlVHJiYocC5sdD0hMCkscC5kZWZlcj11LHUucHJvdG90eXBlLlB0PWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcztyZXR1cm4gZnVuY3Rpb24oZSxpKXtlP3QucmVqZWN0KGUpOmFyZ3VtZW50cy5sZW5ndGg+Mj90LnJlc29sdmUoVyhhcmd1bWVudHMsMSkpOnQucmVzb2x2ZShpKX19LHAuUHJvbWlzZT1sLHAudnQ9bCxsLnJhY2U9ZCxsLmFsbD1fLGwucmVqZWN0PVIsbC5yZXNvbHZlPXAscC5BdD1mdW5jdGlvbih0KXtyZXR1cm4gdH0sZi5wcm90b3R5cGUuQXQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpc30scC5qb2luPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHAodCkuam9pbihlKX0sZi5wcm90b3R5cGUuam9pbj1mdW5jdGlvbih0KXtyZXR1cm4gcChbdGhpcyx0XSkuYnQoZnVuY3Rpb24odCxlKXtpZih0PT09ZSlyZXR1cm4gdDt0aHJvdyBuZXcgRXJyb3IoXCJRIGNhbid0IGpvaW46IG5vdCB0aGUgc2FtZTogXCIrdCtcIiBcIitlKX0pfSxwLnJhY2U9ZCxmLnByb3RvdHlwZS5yYWNlPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhlbihwLnJhY2UpfSxwLk50PWYsZi5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm5cIltvYmplY3QgUHJvbWlzZV1cIn0sZi5wcm90b3R5cGUudGhlbj1mdW5jdGlvbih0LGUsaSl7ZnVuY3Rpb24gbihlKXt0cnl7cmV0dXJuXCJmdW5jdGlvblwiPT10eXBlb2YgdD90KGUpOmV9Y2F0Y2goaSl7cmV0dXJuIFIoaSl9fWZ1bmN0aW9uIG8odCl7aWYoXCJmdW5jdGlvblwiPT10eXBlb2YgZSl7cih0LGEpO3RyeXtyZXR1cm4gZSh0KX1jYXRjaChpKXtyZXR1cm4gUihpKX19cmV0dXJuIFIodCl9ZnVuY3Rpb24gcyh0KXtyZXR1cm5cImZ1bmN0aW9uXCI9PXR5cGVvZiBpP2kodCk6dH12YXIgYT10aGlzLGM9dSgpLGg9ITE7cmV0dXJuIHAuZHQoZnVuY3Rpb24oKXthLmZ0KGZ1bmN0aW9uKHQpe2h8fChoPSEwLGMucmVzb2x2ZShuKHQpKSl9LFwid2hlblwiLFtmdW5jdGlvbih0KXtofHwoaD0hMCxjLnJlc29sdmUobyh0KSkpfV0pfSksYS5mdCh2b2lkIDAsXCJ3aGVuXCIsW3ZvaWQgMCxmdW5jdGlvbih0KXt2YXIgZSxpPSExO3RyeXtlPXModCl9Y2F0Y2gocil7aWYoaT0hMCwhcC5vbmVycm9yKXRocm93IHI7cC5vbmVycm9yKHIpfWl8fGMubm90aWZ5KGUpfV0pLGMudnR9LHAueHQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gcCh0KS54dChlKX0sZi5wcm90b3R5cGUueHQ9ZnVuY3Rpb24odCl7cmV0dXJuIHQ9cCh0KSx0aGlzLnRoZW4oZnVuY3Rpb24oZSl7cmV0dXJuIHQuRnQoZSkuQnQoZSl9KX0scC53aGVuPWcsZi5wcm90b3R5cGUuQnQ9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbigpe3JldHVybiB0fSl9LHAuQnQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gcCh0KS5CdChlKX0sZi5wcm90b3R5cGUuX3Q9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbigpe3Rocm93IHR9KX0scC5fdD1mdW5jdGlvbih0LGUpe3JldHVybiBwKHQpLl90KGUpfSxwLkR0PXYscC5IdD15LHAuTHQ9bSxwLk10PXcsZi5wcm90b3R5cGUuTXQ9ZnVuY3Rpb24oKXtyZXR1cm5cInBlbmRpbmdcIj09PXRoaXMuZ3QoKS5zdGF0ZX0scC5qdD1ULGYucHJvdG90eXBlLmp0PWZ1bmN0aW9uKCl7cmV0dXJuXCJmdWxmaWxsZWRcIj09PXRoaXMuZ3QoKS5zdGF0ZX0scC5VdD1TLGYucHJvdG90eXBlLlV0PWZ1bmN0aW9uKCl7cmV0dXJuXCJyZWplY3RlZFwiPT09dGhpcy5ndCgpLnN0YXRlfTt2YXIgbnQ9W10sb3Q9W10sc3Q9W10sYXQ9ITA7cC5WdD1iLHAuUXQ9ZnVuY3Rpb24oKXtyZXR1cm4gbnQuc2xpY2UoKX0scC5xdD1mdW5jdGlvbigpe2IoKSxhdD0hMX0sYigpLHAucmVqZWN0PVIscC55dD1rLHAuSnQ9TyxwLmJ0PVAsZi5wcm90b3R5cGUuYnQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5hbGwoKS50aGVuKGZ1bmN0aW9uKGUpe3JldHVybiB0LmFwcGx5KHZvaWQgMCxlKX0sZSl9LHAuYXN5bmM9QSxwLkt0PU4scFtcIkd0XCJdPXgscC56dD1CLHAuRXQ9RixmLnByb3RvdHlwZS5FdD1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMscj11KCk7cmV0dXJuIHAuZHQoZnVuY3Rpb24oKXtpLmZ0KHIucmVzb2x2ZSx0LGUpfSksci52dH0scC5nZXQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gcCh0KS5FdChcImdldFwiLFtlXSl9LGYucHJvdG90eXBlLmdldD1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5FdChcImdldFwiLFt0XSl9LHAuc2V0PWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gcCh0KS5FdChcInNldFwiLFtlLGldKX0sZi5wcm90b3R5cGUuc2V0PWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMuRXQoXCJzZXRcIixbdCxlXSl9LHAuV3Q9cFtcImRlbGV0ZVwiXT1mdW5jdGlvbih0LGUpe3JldHVybiBwKHQpLkV0KFwiZGVsZXRlXCIsW2VdKX0sZi5wcm90b3R5cGUuV3Q9Zi5wcm90b3R5cGVbXCJkZWxldGVcIl09ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuRXQoXCJkZWxldGVcIixbdF0pfSxwLiR0PXAuVHQ9ZnVuY3Rpb24odCxlLGkpe3JldHVybiBwKHQpLkV0KFwicG9zdFwiLFtlLGldKX0sZi5wcm90b3R5cGUuJHQ9Zi5wcm90b3R5cGUuVHQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5FdChcInBvc3RcIixbdCxlXSl9LHAuc2VuZD1wLll0PXAuWHQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gcCh0KS5FdChcInBvc3RcIixbZSxXKGFyZ3VtZW50cywyKV0pfSxmLnByb3RvdHlwZS5zZW5kPWYucHJvdG90eXBlLll0PWYucHJvdG90eXBlLlh0PWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLkV0KFwicG9zdFwiLFt0LFcoYXJndW1lbnRzLDEpXSl9LHAuWnQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gcCh0KS5FdChcImFwcGx5XCIsW3ZvaWQgMCxlXSl9LGYucHJvdG90eXBlLlp0PWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLkV0KFwiYXBwbHlcIixbdm9pZCAwLHRdKX0scFtcInRlXCJdPXAuRnQ9ZnVuY3Rpb24odCl7cmV0dXJuIHAodCkuRXQoXCJhcHBseVwiLFt2b2lkIDAsVyhhcmd1bWVudHMsMSldKX0sZi5wcm90b3R5cGUuRnQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5FdChcImFwcGx5XCIsW3ZvaWQgMCxXKGFyZ3VtZW50cyldKX0scC5lZT1mdW5jdGlvbih0KXt2YXIgZT1wKHQpLGk9Vyhhcmd1bWVudHMsMSk7cmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGUuRXQoXCJhcHBseVwiLFt0aGlzLGkuY29uY2F0KFcoYXJndW1lbnRzKSldKX19LGYucHJvdG90eXBlLmVlPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxlPVcoYXJndW1lbnRzKTtyZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gdC5FdChcImFwcGx5XCIsW3RoaXMsZS5jb25jYXQoVyhhcmd1bWVudHMpKV0pfX0scC5rZXlzPWZ1bmN0aW9uKHQpe3JldHVybiBwKHQpLkV0KFwia2V5c1wiLFtdKX0sZi5wcm90b3R5cGUua2V5cz1mdW5jdGlvbigpe3JldHVybiB0aGlzLkV0KFwia2V5c1wiLFtdKX0scC5hbGw9XyxmLnByb3RvdHlwZS5hbGw9ZnVuY3Rpb24oKXtyZXR1cm4gXyh0aGlzKX0scC5pZT1ELGYucHJvdG90eXBlLmllPWZ1bmN0aW9uKCl7cmV0dXJuIEQodGhpcyl9LHAucmU9aChILFwiYWxsUmVzb2x2ZWRcIixcImFsbFNldHRsZWRcIiksZi5wcm90b3R5cGUucmU9ZnVuY3Rpb24oKXtyZXR1cm4gSCh0aGlzKX0scC5JdD1MLGYucHJvdG90eXBlLkl0PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudGhlbihmdW5jdGlvbih0KXtyZXR1cm4gXyhYKHQsZnVuY3Rpb24odCl7ZnVuY3Rpb24gZSgpe3JldHVybiB0Lmd0KCl9cmV0dXJuIHQ9cCh0KSx0LnRoZW4oZSxlKX0pKX0pfSxwLmZhaWw9cFtcImNhdGNoXCJdPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHAodCkudGhlbih2b2lkIDAsZSl9LGYucHJvdG90eXBlLmZhaWw9Zi5wcm90b3R5cGVbXCJjYXRjaFwiXT1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy50aGVuKHZvaWQgMCx0KX0scC5wcm9ncmVzcz1NLGYucHJvdG90eXBlLnByb2dyZXNzPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLnRoZW4odm9pZCAwLHZvaWQgMCx0KX0scC5uZT1wW1wiZmluYWxseVwiXT1mdW5jdGlvbih0LGUpe3JldHVybiBwKHQpW1wiZmluYWxseVwiXShlKX0sZi5wcm90b3R5cGUubmU9Zi5wcm90b3R5cGVbXCJmaW5hbGx5XCJdPWZ1bmN0aW9uKHQpe2lmKCF0fHxcImZ1bmN0aW9uXCIhPXR5cGVvZiB0LmFwcGx5KXRocm93IG5ldyBFcnJvcihcIlEgY2FuJ3QgYXBwbHkgZmluYWxseSBjYWxsYmFja1wiKTtyZXR1cm4gdD1wKHQpLHRoaXMudGhlbihmdW5jdGlvbihlKXtyZXR1cm4gdC5GdCgpLnRoZW4oZnVuY3Rpb24oKXtyZXR1cm4gZX0pfSxmdW5jdGlvbihlKXtyZXR1cm4gdC5GdCgpLnRoZW4oZnVuY3Rpb24oKXt0aHJvdyBlfSl9KX0scC5kb25lPWZ1bmN0aW9uKHQsZSxpLHIpe3JldHVybiBwKHQpLmRvbmUoZSxpLHIpfSxmLnByb3RvdHlwZS5kb25lPWZ1bmN0aW9uKHQsZSxpKXt2YXIgbj1mdW5jdGlvbih0KXtwLmR0KGZ1bmN0aW9uKCl7aWYocih0LG8pLCFwLm9uZXJyb3IpdGhyb3cgdDtwLm9uZXJyb3IodCl9KX0sbz10fHxlfHxpP3RoaXMudGhlbih0LGUsaSk6dGhpcztcIm9iamVjdFwiPT10eXBlb2YgcHJvY2VzcyYmcHJvY2VzcyYmcHJvY2Vzcy5kb21haW4mJihuPXByb2Nlc3MuZG9tYWluLmJpbmQobikpLG8udGhlbih2b2lkIDAsbil9LHAudGltZW91dD1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIHAodCkudGltZW91dChlLGkpfSxmLnByb3RvdHlwZS50aW1lb3V0PWZ1bmN0aW9uKHQsZSl7dmFyIGk9dSgpLHI9c2V0VGltZW91dChmdW5jdGlvbigpe2UmJlwic3RyaW5nXCIhPXR5cGVvZiBlfHwoZT1uZXcgRXJyb3IoZXx8XCJUaW1lZCBvdXQgYWZ0ZXIgXCIrdCtcIiBtc1wiKSxlLmNvZGU9XCJFVElNRURPVVRcIiksaS5yZWplY3QoZSl9LHQpO3JldHVybiB0aGlzLnRoZW4oZnVuY3Rpb24odCl7Y2xlYXJUaW1lb3V0KHIpLGkucmVzb2x2ZSh0KX0sZnVuY3Rpb24odCl7Y2xlYXJUaW1lb3V0KHIpLGkucmVqZWN0KHQpfSxpLm5vdGlmeSksaS52dH0scC5kZWxheT1mdW5jdGlvbih0LGUpe3JldHVybiB2b2lkIDA9PT1lJiYoZT10LHQ9dm9pZCAwKSxwKHQpLmRlbGF5KGUpfSxmLnByb3RvdHlwZS5kZWxheT1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy50aGVuKGZ1bmN0aW9uKGUpe3ZhciBpPXUoKTtyZXR1cm4gc2V0VGltZW91dChmdW5jdGlvbigpe2kucmVzb2x2ZShlKX0sdCksaS52dH0pfSxwLm9lPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHAodCkub2UoZSl9LGYucHJvdG90eXBlLm9lPWZ1bmN0aW9uKHQpe3ZhciBlPXUoKSxpPVcodCk7cmV0dXJuIGkucHVzaChlLlB0KCkpLHRoaXMuWnQoaSkuZmFpbChlLnJlamVjdCksZS52dH0scC5zZT1mdW5jdGlvbih0KXt2YXIgZT1XKGFyZ3VtZW50cywxKTtyZXR1cm4gcCh0KS5vZShlKX0sZi5wcm90b3R5cGUuc2U9ZnVuY3Rpb24oKXt2YXIgdD1XKGFyZ3VtZW50cyksZT11KCk7cmV0dXJuIHQucHVzaChlLlB0KCkpLHRoaXMuWnQodCkuZmFpbChlLnJlamVjdCksZS52dH0scC5hZT1wLmNlPWZ1bmN0aW9uKHQpe2lmKHZvaWQgMD09PXQpdGhyb3cgbmV3IEVycm9yKFwiUSBjYW4ndCB3cmFwIGFuIHVuZGVmaW5lZCBmdW5jdGlvblwiKTt2YXIgZT1XKGFyZ3VtZW50cywxKTtyZXR1cm4gZnVuY3Rpb24oKXt2YXIgaT1lLmNvbmNhdChXKGFyZ3VtZW50cykpLHI9dSgpO3JldHVybiBpLnB1c2goci5QdCgpKSxwKHQpLlp0KGkpLmZhaWwoci5yZWplY3QpLHIudnR9fSxmLnByb3RvdHlwZS5hZT1mLnByb3RvdHlwZS5jZT1mdW5jdGlvbigpe3ZhciB0PVcoYXJndW1lbnRzKTtyZXR1cm4gdC51bnNoaWZ0KHRoaXMpLHAuY2UuYXBwbHkodm9pZCAwLHQpfSxwLmhlPWZ1bmN0aW9uKHQsZSl7dmFyIGk9Vyhhcmd1bWVudHMsMik7cmV0dXJuIGZ1bmN0aW9uKCl7ZnVuY3Rpb24gcigpe3JldHVybiB0LmFwcGx5KGUsYXJndW1lbnRzKX12YXIgbj1pLmNvbmNhdChXKGFyZ3VtZW50cykpLG89dSgpO3JldHVybiBuLnB1c2goby5QdCgpKSxwKHIpLlp0KG4pLmZhaWwoby5yZWplY3QpLG8udnR9fSxmLnByb3RvdHlwZS5oZT1mdW5jdGlvbigpe3ZhciB0PVcoYXJndW1lbnRzLDApO3JldHVybiB0LnVuc2hpZnQodGhpcykscC5oZS5hcHBseSh2b2lkIDAsdCl9LHAucGU9cC51ZT1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIHAodCkudWUoZSxpKX0sZi5wcm90b3R5cGUucGU9Zi5wcm90b3R5cGUudWU9ZnVuY3Rpb24odCxlKXt2YXIgaT1XKGV8fFtdKSxyPXUoKTtyZXR1cm4gaS5wdXNoKHIuUHQoKSksdGhpcy5FdChcInBvc3RcIixbdCxpXSkuZmFpbChyLnJlamVjdCksci52dH0scC5sZT1wLmRlPXAuZmU9ZnVuY3Rpb24odCxlKXt2YXIgaT1XKGFyZ3VtZW50cywyKSxyPXUoKTtyZXR1cm4gaS5wdXNoKHIuUHQoKSkscCh0KS5FdChcInBvc3RcIixbZSxpXSkuZmFpbChyLnJlamVjdCksci52dH0sZi5wcm90b3R5cGUubGU9Zi5wcm90b3R5cGUuZGU9Zi5wcm90b3R5cGUuZmU9ZnVuY3Rpb24odCl7dmFyIGU9Vyhhcmd1bWVudHMsMSksaT11KCk7cmV0dXJuIGUucHVzaChpLlB0KCkpLHRoaXMuRXQoXCJwb3N0XCIsW3QsZV0pLmZhaWwoaS5yZWplY3QpLGkudnR9LHAuUnQ9aixmLnByb3RvdHlwZS5SdD1mdW5jdGlvbih0KXtyZXR1cm4gdD92b2lkIHRoaXMudGhlbihmdW5jdGlvbihlKXtwLmR0KGZ1bmN0aW9uKCl7dChudWxsLGUpfSl9LGZ1bmN0aW9uKGUpe3AuZHQoZnVuY3Rpb24oKXt0KGUpfSl9KTp0aGlzfSxwLmdlPWZ1bmN0aW9uKCl7dGhyb3cgbmV3IEVycm9yKFwiUS5ub0NvbmZsaWN0IG9ubHkgd29ya3Mgd2hlbiBRIGlzIHVzZWQgYXMgYSBnbG9iYWxcIil9O3ZhciBjdD1jKCk7cmV0dXJuIHB9KX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByLG49aSgxNSksbz1pKDQpLHM9by52ZTshZnVuY3Rpb24odCl7ZnVuY3Rpb24gZShlKXtCJiZjb25zb2xlLmxvZyhcIkZyYW1ld29yayBhbHJlYWR5IGluaXRpYWxpemVkXCIpLHQueWUoKSxOPW5ldyBEYXRlLGUuYXBwbHkoRCksQj1ELnJlc29sdmUoay5tZSksXz1ELnJlc29sdmUoay53ZSksTD1CLkN0KCl9ZnVuY3Rpb24gaSgpe0Y9RC5yZXNvbHZlKGsuVGUpLEYuaW5pdCgpfWZ1bmN0aW9uIHIoKXtyZXR1cm4gRn1mdW5jdGlvbiBvKCl7cmV0dXJuIER9ZnVuY3Rpb24gYSgpe3JldHVybiBffWZ1bmN0aW9uIGMoKXtyZXR1cm4gQn1mdW5jdGlvbiBoKHQpe3JldHVybiBILmdldCh0KX1mdW5jdGlvbiBwKHQsZSl7dmFyIGk9bmV3IEModCk7cmV0dXJuIGkuYXBwbHkoZSksSC5zZXQodCxpKSxpfWZ1bmN0aW9uIHUoZSl7QT10LlNlKGUpfWZ1bmN0aW9uIGwodCl7cmV0dXJuIG51bGwhPUE/QS5jb250ZXh0LnJlc29sdmUodCk6KGNvbnNvbGUud2FybihcInVuZGVmaW5lZCBjb250ZXh0XCIpLG51bGwpfWZ1bmN0aW9uIGQoKXtyZXR1cm4gQX1mdW5jdGlvbiBmKCl7cmV0dXJuIEIudGltZSgpfWZ1bmN0aW9uIGcodCxlKXtyZXR1cm4gQi5zZXRUaW1lb3V0KHQsZSl9ZnVuY3Rpb24gdih0KXtyZXR1cm4gQi5jbGVhclRpbWVvdXQodCl9ZnVuY3Rpb24geSh0LGUpe3JldHVybiBCLnNldEludGVydmFsKHQsZSl9ZnVuY3Rpb24gbSh0KXtyZXR1cm4gQi5jbGVhckludGVydmFsKHQpfWZ1bmN0aW9uIHcoKXtCLmJlKCl9ZnVuY3Rpb24gVCgpe0QuRWUoKSxEPW5ldyBuLkllLEg9bmV3IHMsQT1udWxsLE49bnVsbCxMPSExLHg9bnVsbCxCPW51bGwsRj1udWxsLF89bnVsbH1mdW5jdGlvbiBTKHQpe3g9dH1mdW5jdGlvbiBiKCl7cmV0dXJuIHh8fCh4PShuZXcgRGF0ZSkuZ2V0VGltZSgpKSx4PSg5MzAxKngrNDkyOTcpJTIzMzI4MCx4LzIzMzI4MH1mdW5jdGlvbiBFKCl7cmV0dXJuIE59ZnVuY3Rpb24gSSgpe3JldHVybiBMfXZhciBSPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTtSLlJlPVwid3M6Ly8xMjcuMC4wLjE6ODAwMC9oaXZlXCIsdC5rZT1SO3ZhciBrPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTtrLm1lPVwiVGltZXJTY2hlZHVsZXJcIixrLkNlPVwiaWRlbnRpdHlQcm92aWRlclwiLGsuVGU9XCJOZXR3b3JrQ29tcG9uZW50XCIsay5PZT1cInJ0Y01hbmFnZXJcIixrLlBlPVwidHJhbnNwb3J0XCIsay5BZT1cImh0dHBNYW5hZ2VyXCIsay5OZT1cImh0dHBSZXF1ZXN0XCIsay53ZT1cImxvZ2dlclwiLGsueGU9XCJzZXJ2ZXJNYW5hZ2VyXCIsay5CZT1cInNlcnZpY2VzQ2xpZW50XCIsdC5GZT1rO3ZhciBDPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0KXt0aGlzLmlkPXQsdGhpcy5jb250ZXh0PW5ldyBuLkllfXJldHVybiB0LnByb3RvdHlwZS5hcHBseT1mdW5jdGlvbih0KXt0LmFwcGx5KHRoaXMuY29udGV4dCl9LHR9KCk7dC5fZT1DO3ZhciBPOyFmdW5jdGlvbih0KXt0W3QuRGU9MF09XCJIVFRQXCIsdFt0LkhlPTFdPVwiUlRDXCIsdFt0LkxlPTJdPVwiVURQXCJ9KE89dC5NZXx8KHQuTWU9e30pKTt2YXIgUDshZnVuY3Rpb24oZSl7ZnVuY3Rpb24gaSgpe3JldHVyblwiW1wiK2YoKStcIl0gW1wiK3QuamUoKS5pZCtcIl1cIn1lLlVlPWl9KFA9dC5WZXx8KHQuVmU9e30pKTt2YXIgQSxOLHgsQixGLF8sRD1uZXcgbi5JZSxIPW5ldyBzLEw9ITE7dC5RZT1lLHQucWU9aSx0LkplPXIsdC5zeXN0ZW09byx0Lm09YSx0LktlPWMsdC5TZT1oLHQuR2U9cCx0LnplPXUsdC5yZXNvbHZlPWwsdC5qZT1kLHQudGltZT1mLHQuc2V0VGltZW91dD1nLHQuY2xlYXJUaW1lb3V0PXYsdC5zZXRJbnRlcnZhbD15LHQuY2xlYXJJbnRlcnZhbD1tLHQuYmU9dyx0LnllPVQsdC5XZT1TLHQucmFuZG9tPWIsdC4kZT1FLHQuQ3Q9SX0ocj1lLkZyYW1ld29ya3x8KGUuRnJhbWV3b3JrPXt9KSksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGdsb2JhbCYmKGdsb2JhbC5GcmFtZXdvcms9cil9LGZ1bmN0aW9uKHQsZSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGk9ITAscj17WWU6ZnVuY3Rpb24odCl7cmV0dXJuXCJib29sZWFuXCIhPXR5cGVvZiB0P25ldyBFcnJvcihcIkFyZ3VtZW50IHR5cGU6IFwiK3R5cGVvZiB0K1wiLiBQbGVhc2UgdXNlIGEgYm9vbGVhbi5cIik6KGk9dCx0P1wiYWRhcHRlci5qcyBsb2dnaW5nIGRpc2FibGVkXCI6XCJhZGFwdGVyLmpzIGxvZ2dpbmcgZW5hYmxlZFwiKX0sbG9nOmZ1bmN0aW9uKCl7aWYoXCJvYmplY3RcIj09dHlwZW9mIHdpbmRvdyl7aWYoaSlyZXR1cm47XCJ1bmRlZmluZWRcIiE9dHlwZW9mIGNvbnNvbGUmJlwiZnVuY3Rpb25cIj09dHlwZW9mIGNvbnNvbGUubG9nJiZjb25zb2xlLmxvZy5hcHBseShjb25zb2xlLGFyZ3VtZW50cyl9fSxYZTpmdW5jdGlvbih0LGUsaSl7dmFyIHI9dC5tYXRjaChlKTtyZXR1cm4gciYmci5sZW5ndGg+PWkmJnBhcnNlSW50KHJbaV0sMTApfSxaZTpmdW5jdGlvbigpe3ZhciB0PXt9O2lmKHQudGk9bnVsbCx0LnZlcnNpb249bnVsbCxcInVuZGVmaW5lZFwiPT10eXBlb2Ygd2luZG93fHwhd2luZG93Lm5hdmlnYXRvcilyZXR1cm4gdC50aT1cIk5vdCBhIGJyb3dzZXIuXCIsdDtpZihuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKXQudGk9XCJmaXJlZm94XCIsdC52ZXJzaW9uPXRoaXMuWGUobmF2aWdhdG9yLnVzZXJBZ2VudCwvRmlyZWZveFxcLyhcXGQrKVxcLi8sMSk7ZWxzZSBpZihuYXZpZ2F0b3Iud2Via2l0R2V0VXNlck1lZGlhKWlmKHdpbmRvdy53ZWJraXRSVENQZWVyQ29ubmVjdGlvbil0LnRpPVwiY2hyb21lXCIsdC52ZXJzaW9uPXRoaXMuWGUobmF2aWdhdG9yLnVzZXJBZ2VudCwvQ2hyb20oZXxpdW0pXFwvKFxcZCspXFwuLywyKTtlbHNle2lmKCFuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9WZXJzaW9uXFwvKFxcZCspLihcXGQrKS8pKXJldHVybiB0LnRpPVwiVW5zdXBwb3J0ZWQgd2Via2l0LWJhc2VkIGJyb3dzZXIgd2l0aCBHVU0gc3VwcG9ydCBidXQgbm8gV2ViUlRDIHN1cHBvcnQuXCIsdDt0LnRpPVwic2FmYXJpXCIsdC52ZXJzaW9uPXRoaXMuWGUobmF2aWdhdG9yLnVzZXJBZ2VudCwvQXBwbGVXZWJLaXRcXC8oXFxkKylcXC4vLDEpfWVsc2UgaWYobmF2aWdhdG9yLm1lZGlhRGV2aWNlcyYmbmF2aWdhdG9yLnVzZXJBZ2VudC5tYXRjaCgvRWRnZVxcLyhcXGQrKS4oXFxkKykkLykpdC50aT1cImVkZ2VcIix0LnZlcnNpb249dGhpcy5YZShuYXZpZ2F0b3IudXNlckFnZW50LC9FZGdlXFwvKFxcZCspLihcXGQrKSQvLDIpO2Vsc2V7aWYoIW5hdmlnYXRvci5tZWRpYURldmljZXN8fCFuYXZpZ2F0b3IudXNlckFnZW50Lm1hdGNoKC9BcHBsZVdlYktpdFxcLyhcXGQrKVxcLi8pKXJldHVybiB0LnRpPVwiTm90IGEgc3VwcG9ydGVkIGJyb3dzZXIuXCIsdDt0LnRpPVwic2FmYXJpXCIsdC52ZXJzaW9uPXRoaXMuWGUobmF2aWdhdG9yLnVzZXJBZ2VudCwvQXBwbGVXZWJLaXRcXC8oXFxkKylcXC4vLDEpfXJldHVybiB0fSxlaTpmdW5jdGlvbigpe2lmKFwib2JqZWN0XCI9PXR5cGVvZiB3aW5kb3cmJndpbmRvdy5IVE1MTWVkaWFFbGVtZW50JiZcInNyY09iamVjdFwiaW4gd2luZG93LkhUTUxNZWRpYUVsZW1lbnQucHJvdG90eXBlKXt2YXIgdD1VUkwuY3JlYXRlT2JqZWN0VVJMLmJpbmQoVVJMKSxlPVVSTC5yZXZva2VPYmplY3RVUkwuYmluZChVUkwpLGk9bmV3IE1hcCxyPTA7VVJMLmNyZWF0ZU9iamVjdFVSTD1mdW5jdGlvbihlKXtpZihcImdldFRyYWNrc1wiaW4gZSl7dmFyIG49XCJwb2x5YmxvYjpcIisgKytyO3JldHVybiBpLnNldChuLGUpLGNvbnNvbGUubG9nKFwiVVJMLmNyZWF0ZU9iamVjdFVSTChzdHJlYW0pIGlzIGRlcHJlY2F0ZWQhIFVzZSBlbGVtLnNyY09iamVjdCA9IHN0cmVhbSBpbnN0ZWFkIVwiKSxufXJldHVybiB0KGUpfSxVUkwucmV2b2tlT2JqZWN0VVJMPWZ1bmN0aW9uKHQpe2UodCksaVtcImRlbGV0ZVwiXSh0KX07dmFyIG49T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcih3aW5kb3cuSFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUsXCJzcmNcIik7T2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdy5IVE1MTWVkaWFFbGVtZW50LnByb3RvdHlwZSxcInNyY1wiLHtnZXQ6ZnVuY3Rpb24oKXtyZXR1cm4gbi5nZXQuYXBwbHkodGhpcyl9LHNldDpmdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5paT1pLmdldCh0KXx8bnVsbCxuLnNldC5hcHBseSh0aGlzLFt0XSl9fSk7dmFyIG89SFRNTE1lZGlhRWxlbWVudC5wcm90b3R5cGUuc2V0QXR0cmlidXRlO0hUTUxNZWRpYUVsZW1lbnQucHJvdG90eXBlLnNldEF0dHJpYnV0ZT1mdW5jdGlvbigpe3JldHVybiAyPT09YXJndW1lbnRzLmxlbmd0aCYmXCJzcmNcIj09PShcIlwiK2FyZ3VtZW50c1swXSkudG9Mb3dlckNhc2UoKSYmKHRoaXMuaWk9aS5nZXQoYXJndW1lbnRzWzFdKXx8bnVsbCksby5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fX19O3QudD17bG9nOnIubG9nLFllOnIuWWUscmk6ci5aZSgpLFhlOnIuWGUsZWk6ci5laSxaZTpyLlplLmJpbmQocil9fSxmdW5jdGlvbih0LGUsaSl7dmFyIHI9aSgzMik7dC50PXt2ZTpyLk1hcCxuaTpyLm5pLG9pOnIub2l9fSxmdW5jdGlvbih0LGUpe1widXNlIHN0cmljdFwiO3ZhciBpOyFmdW5jdGlvbih0KXt0LnNpPVwic3RhdHNDbGllbnRcIix0LkJlPVwic2VydmljZXNDbGllbnRcIix0LmFpPVwidGlja2V0UmVzb2x2ZXJcIix0LkNlPVwiaWRlbnRpdHlQcm92aWRlclwiLHQuY2k9XCJjb25uSW5mb1Byb3ZpZGVyXCIsdC5oaT1cInBlZXJJbmZvXCIsdC5waT1cInN0cmVhbUluZm9Qcm92aWRlclwiLHQudWk9XCJyZXBvcnRpbmdcIix0LmxpPVwic3RhdHNTdG9yZVwiLHQuZGk9XCJ0cmFja01hbmFnZXJcIix0LmZpPVwidHJhY2tDbGllbnRcIn0oaT1lLmdpfHwoZS5naT17fSkpfSxmdW5jdGlvbih0LGUpe3QudD1mdW5jdGlvbigpe3JldHVybiBuZXcgRnVuY3Rpb259fSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gcih0LGUpe2Z1bmN0aW9uIGkoKXtyZXR1cm4gdCgpP3ZvaWQgdi53aGVuKGUoKSxpLHIucmVqZWN0KTpyLnJlc29sdmUoITApfXZhciByPXYuZGVmZXIoKTtyZXR1cm4gdi5kdChpKSxyLnZ0fWZ1bmN0aW9uIG4odCxlLGkpe3JldHVybiB2b2lkIDA9PT1pJiYoaT0hMCksbyhcIkdFVFwiLHQsZSxpKX1mdW5jdGlvbiBvKHQsZSxpLHIpe3ZvaWQgMD09PXImJihyPSEwKTt2YXIgbj12LmRlZmVyKCk7dHJ5e3ZhciBvPW5ldyBYTUxIdHRwUmVxdWVzdDtvLm9wZW4odCxlLHIpLHZvaWQgMCE9aSYmbnVsbCE9aSYmby5zZXRSZXF1ZXN0SGVhZGVyKFwiQ29udGVudC1UeXBlXCIsaSksby5vbmxvYWQ9ZnVuY3Rpb24oKXsyMDA9PW8uc3RhdHVzP24ucmVzb2x2ZShvLnJlc3BvbnNlKTpuLnJlamVjdCh7c3RhdHVzOm8uc3RhdHVzLHJlYXNvbjpvLnN0YXR1c1RleHQsYm9keTpvLnJlc3BvbnNlVGV4dH0pfSxvLm9uZXJyb3I9ZnVuY3Rpb24odCl7bi5yZWplY3Qoe3N0YXR1czotMSxyZWFzb246XCJOZXR3b3JrIEVycm9yXCJ9KX0sby5zZW5kKCl9Y2F0Y2gocyl7bi5yZWplY3Qoe3N0YXR1czotMSxyZWFzb246c30pfXJldHVybiBuLnZ0fWZ1bmN0aW9uIHModCxlLGkscil7dm9pZCAwPT09ciYmKHI9ITApO3ZhciBuPXYuZGVmZXIoKTt0cnl7dmFyIG89bmV3IFhNTEh0dHBSZXF1ZXN0O28ub3BlbihcIlBPU1RcIix0LHIpLHZvaWQgMCE9aSYmbnVsbCE9aSYmby5zZXRSZXF1ZXN0SGVhZGVyKFwiQ29udGVudC1UeXBlXCIsaSksby5vbmxvYWQ9ZnVuY3Rpb24oKXsyMDA9PW8uc3RhdHVzP24ucmVzb2x2ZShvLnJlc3BvbnNlKTpuLnJlamVjdCh7c3RhdHVzOm8uc3RhdHVzLHJlYXNvbjpvLnN0YXR1c1RleHR9KX0sby5vbmVycm9yPWZ1bmN0aW9uKHQpe24ucmVqZWN0KHtzdGF0dXM6LTEscmVhc29uOlwiTmV0d29yayBFcnJvclwifSl9LG8uc2VuZChlKX1jYXRjaChzKXtuLnJlamVjdCh7c3RhdHVzOi0xLHJlYXNvbjpzfSl9cmV0dXJuIG4udnR9ZnVuY3Rpb24gYSh0LGUpe3ZhciBpLHIsbj1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiYmFzZVwiKSxvPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCJoZWFkXCIpLHM9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImFcIiksYT1uO3JldHVybiBuP2k9bi5ocmVmOmE9by5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiYmFzZVwiKSksYS5ocmVmPXQscy5ocmVmPWUscj1zLmhyZWYsbj9uLmhyZWY9aTpvLnJlbW92ZUNoaWxkKGEpLHJ9ZnVuY3Rpb24gYygpe2Zvcih2YXIgdD1bXSxlPTA7ZTxhcmd1bWVudHMubGVuZ3RoO2UrKyl0W2VdPWFyZ3VtZW50c1tlXTtmb3IodmFyIGk9dFswXSxyPTE7cjx0Lmxlbmd0aDtyKyspe3ZhciBuPW5ldyBSZWdFeHAoXCJcXFxce1wiKyhyLTEpK1wiXFxcXH1cIixcImdtXCIpO2k9aS5yZXBsYWNlKG4sdFtyXSl9cmV0dXJuIGl9ZnVuY3Rpb24gaCh0LGUpe2Zvcih2YXIgaSBpbiB0KXQuaGFzT3duUHJvcGVydHkoaSkmJmUuaGFzT3duUHJvcGVydHkoaSkmJihlW2ldPXRbaV0pfWZ1bmN0aW9uIHAodCxlLGkpe3ZhciByPWcodCkudmkoITApO2Zvcih2YXIgbiBpbiByKXRyeXtpZihyLmhhc093blByb3BlcnR5KG4pJiZlLmhhc093blByb3BlcnR5KG4pJiZpLmhhc093blByb3BlcnR5KGVbbl0pKXt2YXIgbz1lW25dLHM9cltuXTtpW29dPXUocyxpW29dKX19Y2F0Y2goYSl7fX1mdW5jdGlvbiB1KHQsZSl7dmFyIGk7c3dpdGNoKHR5cGVvZiBlKXtjYXNlXCJudW1iZXJcIjppPXBhcnNlSW50KHQpO2JyZWFrO2Nhc2VcImJvb2xlYW5cIjppPVwidHJ1ZVwiPT09dDticmVhaztkZWZhdWx0Omk9dH1yZXR1cm4gaX1mdW5jdGlvbiBsKHQsZSxpKXt2YXIgcj1uZXcgbTtyZXR1cm4gci50aWNrZXRVcmw9dCxyLmNvZGU9ZSxyLm1lc3NhZ2U9dyhlKSxyLmRldGFpbGVkTWVzc2FnZT1pLHJ9dmFyIGQ9aSg0KSxmPWQudmUsZz1pKDIxKSx2PWkoMSkseT1pKDE3KSxtPXkucHQuSGl2ZVNlc3Npb25FcnJvcix3PXkucHQuZ2V0SGl2ZVNlc3Npb25FcnJvck1lc3NhZ2UsVD15LnB0LkhpdmVTZXNzaW9uLFM9aSgyNiksYj1pKDQ2KSxFPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdChlKXtpZighZSl7aWYoMD09T2JqZWN0LmtleXModC5tYXBwaW5nKS5sZW5ndGgmJiF0LnlpKXJldHVybiBjb25zb2xlLmVycm9yKFwibm8gcmVnaXN0ZXJlZCBkZWZhdWx0IEhpdmVSZXF1ZXN0RmFjdG9yeSB0ZWNoXCIpLHQueWk9ITAsdC5taSgpO2U9T2JqZWN0LmtleXModC5tYXBwaW5nKVswXX1pZighKGUgaW4gdC5tYXBwaW5nKSlyZXR1cm4gdC55aXx8KGNvbnNvbGUuZXJyb3IoXCJubyByZWdpc3RlcmVkIEhpdmVSZXF1ZXN0RmFjdG9yeSB0ZWNoIGZvciAgXCIrZSksdC55aT0hMCksdC5taSgpO3ZhciBpPXQubWFwcGluZ1tlXTtzd2l0Y2goaS50ZWNoKXtjYXNlXCJIaXZlSlNcIjpyZXR1cm4gdC5taSgpO2Nhc2VcIkhpdmVKc1Byb3h5XCI6cmV0dXJuIGkud2k/bmV3IFMuVGkoZSk6KGkud2k9ITAsbmV3IGIuU2koZSkpO2Nhc2VcIkhpdmVKYXZhXCI6Y2FzZVwiU3RhdHNKU1wiOnJldHVybiB0Lm1pKCl9fXJldHVybiB0Lm1pPWZ1bmN0aW9uKCl7cmV0dXJuXCJ1bmRlZmluZWRcIiE9dHlwZW9mIE9yaWdpbmFsWE1MSHR0cFJlcXVlc3Q/bmV3IE9yaWdpbmFsWE1MSHR0cFJlcXVlc3Q6bmV3IFhNTEh0dHBSZXF1ZXN0fSx0LmNsZWFyPWZ1bmN0aW9uKCl7dC5tYXBwaW5nPXt9fSx0LmJpPWZ1bmN0aW9uKGUsaSl7ZSBpbiB0Lm1hcHBpbmd8fCh0Lm1hcHBpbmdbZV09e30pLHQubWFwcGluZ1tlXS50ZWNoPWl9LHR9KCk7RS5tYXBwaW5nPXt9LEUueWk9ITEsZS5IaXZlUmVxdWVzdEZhY3Rvcnk9RTt2YXIgST1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlLGkscil7dGhpcy5FaT0hMSx0aGlzLnRpY2tldFVybD10LHRoaXMudGlja2V0PWUsdGhpcy5tYW5pZmVzdD1pLHRoaXMuSWk9di5kZWZlcigpLHRoaXMuUmk9cix0aGlzLlJpJiZ0aGlzLklpLnJlc29sdmUodGhpcy5SaSl9cmV0dXJuIHQucHJvdG90eXBlLnN0PWZ1bmN0aW9uKHQpe3JldHVybiBudWxsIT09dGhpcy50ZWNoJiZ0aGlzLnRlY2guc3QodCx0aGlzKX0sdC5wcm90b3R5cGUua2k9ZnVuY3Rpb24odCl7dGhpcy5FaSE9dCYmKHRoaXMuRWk9dCx0aGlzLnRlY2gmJnRoaXMudGVjaC5DaSh0aGlzLHQpKX0sdC5wcm90b3R5cGUuT2k9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5FaX0sdC5wcm90b3R5cGUuY2xvc2U9ZnVuY3Rpb24odCl7aWYobnVsbCE9dGhpcy50ZWNoKXJldHVybiB0aGlzLnRlY2guUGkodGhpcyx0KX0sdC5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy50aWNrZXQudG9TdHJpbmcoKX0sdC5wcm90b3R5cGUuZz1mdW5jdGlvbigpe3ZhciB0PW5ldyBUO3JldHVybiB0LmlkPXRoaXMuaWQsdC50aWNrZXRVcmw9dGhpcy50aWNrZXRVcmwsdC5tYW5pZmVzdD10aGlzLm1hbmlmZXN0LHQudGVjaD10aGlzLnRlY2guQWkoKSx0fSx0LnByb3RvdHlwZS5OaT1mdW5jdGlvbigpe3JldHVybiB0aGlzLklpLnZ0fSx0LnByb3RvdHlwZS54aT1mdW5jdGlvbih0KXt0aGlzLlJpPXQsdGhpcy5JaS5yZXNvbHZlKHRoaXMuUmkpfSx0fSgpO2UuQmk9STt2YXIgUj1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHR9KCk7ZS5GaT1SO3ZhciBrPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMuc3VjY2Vzcz0wLHRoaXMuX2k9MCx0aGlzLkRpPTB9cmV0dXJuIHR9KCk7ZS5IaT1rO3ZhciBDPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMuTGk9MCx0aGlzLk1pPTAsdGhpcy5qaT1uZXcgZix0aGlzLlVpPW5ldyBmfXJldHVybiB0LnByb3RvdHlwZS5NPWZ1bmN0aW9uKHQsZSxpLHIpe3ZvaWQgMD09PXImJihyPSEwKTt2YXIgbj10P3RoaXMuamk6dGhpcy5VaTtuLmhhcyhlKXx8bi5zZXQoZSxuZXcgayk7dmFyIG89bi5nZXQoZSk7by5EaSs9aSxyJiZvLnN1Y2Nlc3MrK30sdC5wcm90b3R5cGUuVj1mdW5jdGlvbih0LGUpe3ZhciBpPXQ/dGhpcy5qaTp0aGlzLlVpO2kuaGFzKGUpfHxpLnNldChlLG5ldyBrKSxpLmdldChlKS5faSsrfSx0LnByb3RvdHlwZS5VPWZ1bmN0aW9uKHQpe3RoaXMuYmFuZHdpZHRoPXR9LHQucHJvdG90eXBlLlo9ZnVuY3Rpb24oKXt0aGlzLkxpKyt9LHQucHJvdG90eXBlLnR0PWZ1bmN0aW9uKCl7dGhpcy5NaSsrfSx0LnByb3RvdHlwZS5WaT1mdW5jdGlvbigpe3JldHVybiB0aGlzLmJhbmR3aWR0aH0sdC5wcm90b3R5cGUuUWk9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5qaX0sdC5wcm90b3R5cGUucWk9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5VaX0sdC5wcm90b3R5cGUuSmk9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5MaX0sdC5wcm90b3R5cGUuS2k9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5NaX0sdH0oKTtlLlA9Qzt2YXIgTz1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt2YXIgZT10aGlzO2lmKHQuR2kpdGhyb3cgbmV3IEVycm9yKFwiRXJyb3I6IEluc3RhbnRpYXRpb24gZmFpbGVkOiBVc2UgVmlzaWJpbGl0eUNoYW5nZUxpc3RlbmVyLmdldEluc3RhbmNlKCkgaW5zdGVhZCBvZiBuZXcuXCIpO3ZhciBpLHI7XCJ1bmRlZmluZWRcIiE9dHlwZW9mIGRvY3VtZW50LmhpZGRlbj8oaT1cImhpZGRlblwiLHI9XCJ2aXNpYmlsaXR5Y2hhbmdlXCIpOlwidW5kZWZpbmVkXCIhPXR5cGVvZiBkb2N1bWVudC5tc0hpZGRlbj8oaT1cIm1zSGlkZGVuXCIscj1cIm1zdmlzaWJpbGl0eWNoYW5nZVwiKTpcInVuZGVmaW5lZFwiIT10eXBlb2YgZG9jdW1lbnQud2Via2l0SGlkZGVuJiYoaT1cIndlYmtpdEhpZGRlblwiLHI9XCJ3ZWJraXR2aXNpYmlsaXR5Y2hhbmdlXCIpLFwidW5kZWZpbmVkXCIhPXR5cGVvZiBkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgZG9jdW1lbnRbaV0/ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihyLGZ1bmN0aW9uKCl7dmFyIHQ9IWRvY3VtZW50W2ldO2UuemkuZm9yRWFjaChmdW5jdGlvbihpKXtpLmNhbGwoZSx0KX0pfSwhMSk6dC5tJiZ0Lm0uZGVidWcoXCJ3YXJuIC0gdmlzaWJpbGl0eUNoYW5nZSBsaXN0ZW5lciBub3Qgc3VwcG9ydGVkXCIpLHRoaXMuemk9bmV3IEFycmF5fXJldHVybiB0LldpPWZ1bmN0aW9uKGUpe3JldHVybiBlJiYodGhpcy5tPWUpLHZvaWQgMD09PXRoaXMuR2kmJih0aGlzLkdpPW5ldyB0KSx0aGlzLkdpfSx0LnByb3RvdHlwZS4kaT1mdW5jdGlvbih0KXt0aGlzLnppLnB1c2godCl9LHR9KCk7ZS5ZaT1PLGUuWGk9cixlLlppPW4sZS50cj1vLGUuZXI9cyxlLmlyPWEsZS5ycj1jLGUubnI9aCxlLm9yPXAsZS5zcj1sO3ZhciBQPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdC5nZXRJdGVtPWZ1bmN0aW9uKHQpe3RyeXtyZXR1cm4gd2luZG93LnNlc3Npb25TdG9yYWdlP3dpbmRvdy5zZXNzaW9uU3RvcmFnZS5nZXRJdGVtKHQpOm51bGx9Y2F0Y2goZSl7cmV0dXJuIG51bGx9fSx0LnNldEl0ZW09ZnVuY3Rpb24odCxlKXt0cnl7cmV0dXJuISF3aW5kb3cuc2Vzc2lvblN0b3JhZ2UmJih3aW5kb3cuc2Vzc2lvblN0b3JhZ2Uuc2V0SXRlbSh0LGUpLCEwKX1jYXRjaChpKXtyZXR1cm4hMX19LHQucmVtb3ZlSXRlbT1mdW5jdGlvbih0KXt0cnl7d2luZG93LnNlc3Npb25TdG9yYWdlJiZ3aW5kb3cuc2Vzc2lvblN0b3JhZ2UucmVtb3ZlSXRlbSh0KX1jYXRjaChlKXtyZXR1cm4gbnVsbH19LHR9KCk7ZS5hcj1QO3ZhciBBPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0KXt0aGlzLmNyPXR9cmV0dXJuIHQucHJvdG90eXBlLmhyPWZ1bmN0aW9uKHQpe3ZhciBlPURhdGUubm93KCk7cmV0dXJuIHRoaXMuaXNFcXVhbCh0aGlzLnByLHQpfHwodGhpcy51cj1lKSx0aGlzLnByPXQsZS10aGlzLnVyPj10aGlzLmNyfSx0LnByb3RvdHlwZS5pc0VxdWFsPWZ1bmN0aW9uKHQsZSl7aWYodCYmZSl7dmFyIGk9W2UubHItdC5scixlLmRyLXQuZHIsZS5nci10LmdyXTtyZXR1cm4gaS5yZWR1Y2UoZnVuY3Rpb24odCxlKXtyZXR1cm4gdCYmTWF0aC5hYnMoZSk8MTB9LCEwKX1yZXR1cm4hMX0sdH0oKTtlLnZyPUF9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcixuPWkoMTEpLG89aSgxOCkscz1pKDEyKTshZnVuY3Rpb24odCl7dmFyIGU7IWZ1bmN0aW9uKHQpe3ZhciBlPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMubW9uaXRvclBvcnQ9by5rZS55cj9zLndyLm1yOnMud3IuVHIsdGhpcy5wbGF5ZXJQb3J0PW8ua2UueXI/cy53ci5TcjpzLndyLmJyLHRoaXMuZmVlZGJhY2tQZXJpb2Q9MmUzLHRoaXMuaWRsZVRpbWVQZXJpb2Q9NmU0LHRoaXMudXNlU2Vzc2lvbkNoZWNrPW8ua2UuRXIsdGhpcy5kZWJ1Z0xldmVsPVwibm90aWNlXCIsdGhpcy5oaXZlVGVjaE9yZGVyPVtdLHRoaXMudGVsZW1ldHJ5SWQ9bnVsbCx0aGlzLnNpbGVudD0hMSx0aGlzLmxvZ2dlclRpbWVzdGFtcD1uLkhpdmVDb25maWcuRnJhbWV3b3JrLkxvZ2dlclRpbWVzdGFtcCx0aGlzLm9uU291cmNlU2V0Q29tcGxldGVkPWZ1bmN0aW9uKHQpe30sdGhpcy5vbkxvYWRpbmdDb21wbGV0ZWQ9ZnVuY3Rpb24odCl7fX1yZXR1cm4gdH0oKTt0LklyPWU7dmFyIGk9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7dGhpcy5pbml0VGltZW91dD0zZTQsdGhpcy5vbkVycm9yPWZ1bmN0aW9uKHQpe3JldHVybiEwfSx0aGlzLm9uQWN0aXZlU2Vzc2lvbj1mdW5jdGlvbih0KXt9fXJldHVybiB0fSgpO3QuUnI9aTt2YXIgcj1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt0aGlzLmhpdmVQbGF5ZXJQb3J0PVwicGxheWVyUG9ydFwiLHRoaXMuaGl2ZU1vbml0b3JQb3J0PVwibW9uaXRvclBvcnRcIix0aGlzLmhpdmVTaWxlbnQ9XCJzaWxlbnRcIix0aGlzLmhpdmVEZWJ1Z0xldmVsPVwiZGVidWdMZXZlbFwiLHRoaXMuaGl2ZURlYnVnVGltZXN0YW1wPVwibG9nZ2VyVGltZXN0YW1wXCIsdGhpcy5oaXZlU2V0dXBUaW1lb3V0PVwic2V0dXBUaW1lb3V0XCIsdGhpcy5oaXZlSmF2YVRpbWVvdXQ9XCJpbml0VGltZW91dFwiLHRoaXMuaGl2ZVdhcm5KYXZhVGltZW91dD1cIndhcm5TbG93UmVzcFRpbWVvdXRcIn1yZXR1cm4gdH0oKTt0LmtyPXJ9KGU9dC5Jcnx8KHQuSXI9e30pKX0ocj1lLnB0fHwoZS5wdD17fSkpO3ZhciBhOyFmdW5jdGlvbih0KXt2YXIgZT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHR9KCk7ZS5lbmFibGVkUlVNPSExLGUuZW5hYmxlS2V5Q29tYmluYXRpb249ITAsZS5lbmFibGVkRXJyb3JGaWx0ZXI9ITAsdC5FcnJvck1vbml0b3I9ZX0oYT1lLkhpdmVDb25maWd8fChlLkhpdmVDb25maWc9e30pKSxcInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93JiYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIHdpbmRvdy5IaXZlQ29uZmlnJiYod2luZG93LkhpdmVDb25maWc9e30pLHdpbmRvdy5IaXZlQ29uZmlnLkVycm9yTW9uaXRvcj1hLkVycm9yTW9uaXRvcil9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcixuPXRoaXMmJnRoaXMuX19leHRlbmRzfHxmdW5jdGlvbih0LGUpe2Z1bmN0aW9uIGkoKXt0aGlzLmNvbnN0cnVjdG9yPXR9Zm9yKHZhciByIGluIGUpZS5oYXNPd25Qcm9wZXJ0eShyKSYmKHRbcl09ZVtyXSk7dC5wcm90b3R5cGU9bnVsbD09PWU/T2JqZWN0LmNyZWF0ZShlKTooaS5wcm90b3R5cGU9ZS5wcm90b3R5cGUsbmV3IGkpfSxvPWkoMjgpLkNyLHM9aSgxKSxhPWkoMiksYz1pKDUpLGg9aSgxMykscD1pKDEwKSx1PWkoMjMpOyFmdW5jdGlvbih0KXt2YXIgZT1cIltUUkFDS10gXCI7dC5Pcj1cImhpdmUtY2xpZW50LXRyYWNrXCIsdC5Qcj1cInRyYWNrZXZlbnRcIix0LkFyPVwiTlVMTElEXCIsdC5Ocj1cIlwiO3ZhciBpPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTtpLnhyPTAsaS5Ccj0xLGkuRnI9MixpLl9yPTEwMCxpLkRyPTIwMCx0LkhyPWk7dmFyIHI7IWZ1bmN0aW9uKHQpe3RbdC5OPTBdPVwiUExBWUlOR1wiLHRbdC5Mcj0xXT1cIkJVRkZFUklOR1wiLHRbdC5XPTJdPVwiUEFVU0VEXCIsdFt0Lkg9M109XCJTS0lQXCIsdFt0LkQ9NF09XCJTVE9QUEVEXCIsdFt0LkVSUk9SPTVdPVwiRVJST1JcIix0W3QuTXI9Nl09XCJXSU5ET1dfU0laRVwiLHRbdC5MPTddPVwiRlVMTFNDUkVFTlwiLHRbdC5qcj04XT1cIlZJU0lCTEVcIix0W3QuSElEREVOPTldPVwiSElEREVOXCJ9KHI9dC5CfHwodC5CPXt9KSk7dmFyIGw7IWZ1bmN0aW9uKHQpe3RbdC5Vcj0wXT1cIkpBVkFfTk9UX1JFQUNIQUJMRVwiLHRbdC5Wcj0xXT1cIkpBVkFfTk9UX1JFQURZXCIsdFt0LlFyPTJdPVwiSkFWQV9XUk9OR19WRVJTSU9OXCIsdFt0LnFyPTNdPVwiSkFWQV9TRVNTSU9OX0JVU1lcIix0W3QuSnI9NF09XCJKQVZBX1NFU1NJT05fRVJST1JcIix0W3QuS3I9NV09XCJKQVZBX1RJQ0tFVF9USU1FT1VUXCJ9KGw9dC5Hcnx8KHQuR3I9e30pKTt2YXIgZD1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHR9KCk7dC56cj1kO3ZhciBmPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTt0LldyPWY7dmFyIGc9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7fXJldHVybiB0fSgpO3QuJHI9Zzt2YXIgdj1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt0aGlzLnR5cGU9aS5Gcn1yZXR1cm4gdH0oKSx5PWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMuc2Vzc2lvbnM9bmV3IEFycmF5fXJldHVybiB0LnByb3RvdHlwZS5Zcj1mdW5jdGlvbih0LGUpe3ZhciBpO3RoaXMuc2Vzc2lvbnMuZm9yRWFjaChmdW5jdGlvbihlKXtlLnNlc3Npb25JZD09dCYmKGk9ZSl9KSxpfHwoaT1uZXcgbSxpLnNlc3Npb25JZD10LHRoaXMuc2Vzc2lvbnMucHVzaChpKSksaS5ldmVudHMucHVzaChlKX0sdH0oKTt0LlhyPXk7dmFyIG09ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7dGhpcy5ldmVudHM9bmV3IEFycmF5fXJldHVybiB0fSgpO3QuWnI9bTt2YXIgdz1mdW5jdGlvbigpe2Z1bmN0aW9uIGkoKXt0aGlzLm09YS5GcmFtZXdvcmsucmVzb2x2ZShhLkZyYW1ld29yay5GZS53ZSkubG9nKCksdGhpcy50bj1hLkZyYW1ld29yay5yZXNvbHZlKGMuZ2kuY2kpLHRoaXMuZW49bmV3IEFycmF5LHRoaXMuaW49bmV3IEFycmF5LHRoaXMucm49bmV3IEFycmF5fXJldHVybiBpLnByb3RvdHlwZS5ubj1mdW5jdGlvbih0KXt0aGlzLmNsaWVudD10fSxpLnByb3RvdHlwZS5pbml0PWZ1bmN0aW9uKHQsaSl7dGhpcy5zbj10LHRoaXMuYW4oaSksdGhpcy5tLmRlYnVnKGUrXCJJTklUIElEOiBcIit0KX0saS5wcm90b3R5cGUuYW49ZnVuY3Rpb24odCxlKXt0aGlzLmFwcD10LGUmJih0aGlzLmNuPWUpfSxpLnByb3RvdHlwZS5obj1mdW5jdGlvbih0KXt0aGlzLnBuPXR9LGkucHJvdG90eXBlLnVuPWZ1bmN0aW9uKHQpe3ZhciBlPW5ldyBTKHQsdGhpcyk7dGhpcy5lbi5wdXNoKGUpLHRoaXMubG49bnVsbCx0aGlzLmNsaWVudC5kbighMCl9LGkucHJvdG90eXBlLndpPWZ1bmN0aW9uKHQsaSxyKXtpZighdGhpcy5sbilmb3IodmFyIG49MDtuPHRoaXMuZW4ubGVuZ3RoO24rKyl7dmFyIG89dGhpcy5lbltuXTtpZihvLnRpY2tldC5zZXNzaW9uSWQ9PT10KXt0aGlzLm0uZGVidWcoZStcIkFjdGl2YXRpbmcgVHJhY2sgZm9yIHNlc3Npb24gXCIrdCksdGhpcy5sbj1vO2JyZWFrfX1pZih0aGlzLmxuKXtpZih0aGlzLmxuLnRpY2tldC5zZXNzaW9uSWQhPXQpcmV0dXJuIHZvaWQgdGhpcy5tLndhcm4oZStcImlnbm9yaW5nIG1hbmlmZXN0IG5vdCBtYXRjaGluZyBldmVudCBcIit0aGlzLmxuLnRpY2tldC5zZXNzaW9uSWQrXCIgIT0gXCIrdCk7aWYoIXRoaXMubG4uZm4pe3ZhciBzPW5ldyBiKHQsaSxyKTt0aGlzLmxuLmduKHMpLHRoaXMuY2xpZW50LmRuKCl9fX0saS5wcm90b3R5cGUudm49ZnVuY3Rpb24odCxlLGkpe251bGwhPXRoaXMubG4mJih0aGlzLmxuLmZufHx0aGlzLmxuLnluLnB1c2gobmV3IGsodCxlLGkpKSl9LGkucHJvdG90eXBlLm1uPWZ1bmN0aW9uKHQsZSxpKXt0aGlzLmluLnB1c2gobmV3IEkodCxlLGkpKSx0aGlzLmNsaWVudC5kbigpfSxpLnByb3RvdHlwZS53bj1mdW5jdGlvbih0LGUsaSl7dGhpcy5ybi5wdXNoKG5ldyBSKHQsZSxpKSksdGhpcy5jbGllbnQuZG4oKX0saS5wcm90b3R5cGUuVG49ZnVuY3Rpb24odCl7dmFyIGU9dGhpczt0JiZ0LmZvckVhY2goZnVuY3Rpb24odCl7ZS5ybi5wdXNoKHQpfSl9LGkucHJvdG90eXBlLlNuPWZ1bmN0aW9uKCl7dmFyIHQ9bmV3IGY7dGhpcy5jbj8odC5wYXJ0bmVySWQ9dGhpcy5jbi5wYXJ0bmVySWQsdC5jdXN0b21lcklkPXRoaXMuY24uY3VzdG9tZXJJZCk6dGhpcy5sbiYmKHQucGFydG5lcklkPXRoaXMubG4udGlja2V0LmJuKCksdC5jdXN0b21lcklkPXRoaXMubG4udGlja2V0LkVuKCkpLHQudmVyc2lvbj10aGlzLmFwcC5hcHArXCJfXCIrKHRoaXMuY24/dGhpcy5jbi52ZXJzaW9uOnRoaXMuYXBwLnZlcnNpb24pLHRoaXMuY24mJih0Lmluc3RhbGxWZXJzaW9uPXRoaXMuY24uaW5zdGFsbFZlcnNpb24sdC5pbnN0YWxsVHM9dGhpcy5jbi5pbnN0YWxsVHMpO3ZhciBlPW5ldyBvO3JldHVybiBlLkluKG5hdmlnYXRvci51c2VyQWdlbnQpLHQub3M9ZS5SbigpLm5hbWUrXCIgXCIrZS5SbigpLnZlcnNpb24sdGhpcy5wbiYmKHQuY29tbVZlcnNpb249dGhpcy5wbi5jb21tVmVyc2lvbix0LnBsdWdpbk5hbWU9dGhpcy5wbi5wbHVnaW5OYW1lLHQucGx1Z2luVmVyc2lvbj10aGlzLnBuLnBsdWdpblZlcnNpb24sdC5wbGF5ZXJUZWNoPXRoaXMucG4ucGxheWVyVGVjaCx0LnBsYXllclZlcnNpb249dGhpcy5wbi5wbGF5ZXJWZXJzaW9uLHRoaXMucG4udGVsZW1ldHJ5SWQmJih0LnRlbGVtZXRyeUlkPXRoaXMucG4udGVsZW1ldHJ5SWQpKSx0fSxpLnByb3RvdHlwZS5rbj1mdW5jdGlvbigpe3JldHVybiB0aGlzLmxuP3RoaXMubG46dGhpcy5lbiYmdGhpcy5lbi5sZW5ndGg+MD90aGlzLmVuW3RoaXMuZW4ubGVuZ3RoLTFdOnZvaWQgMH0saS5wcm90b3R5cGUuQ249ZnVuY3Rpb24oKXt2YXIgZT10aGlzLGk9cy5kZWZlcigpOzA9PXRoaXMuZW4ubGVuZ3RoJiYwPT10aGlzLmluLmxlbmd0aCYmaS5yZWplY3QoXCJub3RoaW5nIHRvIHNlbmRcIik7dmFyIHI9bmV3IGQ7ci5hcHA9dC5PcixyLmNyZWF0ZWRBdD1hLkZyYW1ld29yay50aW1lKCksci5ndWlkPXRoaXMuc24sci5uYW1lPXQuUHI7dmFyIG49dGhpcy5rbigpO2lmKG4pe3ZhciBvPW4udGlja2V0Lk9uKCkucmVwbGFjZSgvW1xcW1xcXV0vZyxcIlwiKTtyLnRhZ3M9W29dLHIudGFncy5wdXNoKG4udGlja2V0LmJuKCkpLHIudGFncy5wdXNoKG4udGlja2V0LkVuKCkpfWVsc2Ugci50YWdzPW5ldyBBcnJheTt2YXIgYz1uZXcgeTtyZXR1cm4gYy5wZWVyPXRoaXMuU24oKSx0aGlzLmVuLmZvckVhY2goZnVuY3Rpb24odCl7dC5mbnx8Yy5Zcih0LnRpY2tldC5zZXNzaW9uSWQsdCl9KSx0aGlzLmluLmZvckVhY2goZnVuY3Rpb24odCl7Yy5Zcih0LnNlc3Npb25JZCx0KX0pLHRoaXMucm4uZm9yRWFjaChmdW5jdGlvbih0KXtjLllyKHQuc2Vzc2lvbklkLHQpfSksci5kYXRhPWMsdGhpcy50bi5QbigpLnRoZW4oZnVuY3Rpb24odCl7dmFyIGk9ZS5Bbih0KTtjLllyKFwibnVsbFwiLGkpfSkuZmFpbChmdW5jdGlvbih0KXt9KVtcImZpbmFsbHlcIl0oZnVuY3Rpb24oKXtyZXR1cm4gaS5yZXNvbHZlKHIpfSkuZG9uZSgpLGkudnR9LGkucHJvdG90eXBlLkFuPWZ1bmN0aW9uKHQpe3ZhciBlPW5ldyB2O2UudHM9YS5GcmFtZXdvcmsudGltZSgpO3ZhciBpPXQuTm4oKTtyZXR1cm4gaS54bigpJiYoZS5wdWJJcD1pLnhuKCkpLGkuQm4oKSYmKGUucHJpdklwPWkuQm4oKSksdC5GbigpJiYoZS5ob3N0bmFtZT10LkZuKCkpLGkuX24oKSYmKGUubmV0bWFzaz1pLl9uKCkpLGkuRG4oKSYmKGUubmljPWkuRG4oKSksaS5IbigpJiYoZS5uaWNOYW1lPWkuSG4oKSksaS5MbigpJiYoZS5tYWM9aS5MbigpKSxlfSxpLnByb3RvdHlwZS5Nbj1mdW5jdGlvbigpe3JldHVybiB0aGlzLmNuP3RoaXMuY24udXNlckFnZW50Om5hdmlnYXRvci51c2VyQWdlbnR9LGkucHJvdG90eXBlLnJlc2V0PWZ1bmN0aW9uKCl7dGhpcy5lbj1uZXcgQXJyYXksdGhpcy5pbj1uZXcgQXJyYXksdGhpcy5ybj1uZXcgQXJyYXl9LGkucHJvdG90eXBlLmpuPWZ1bmN0aW9uKHQpe30saX0oKTt0LlVuPXc7dmFyIFQ9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQpe3RoaXMuVm49aXNOYU4odS5IaXZlQ29uZmlnLkRlYnVnTG9ncy5UcmFja1NuYXBzaG90TG9ncyk/MDp1LkhpdmVDb25maWcuRGVidWdMb2dzLlRyYWNrU25hcHNob3RMb2dzLHRoaXMuUW49dCx0aGlzLm09YS5GcmFtZXdvcmsucmVzb2x2ZShhLkZyYW1ld29yay5GZS53ZSkubG9nKCksdGhpcy5jbGllbnQ9YS5GcmFtZXdvcmsucmVzb2x2ZShjLmdpLkJlKSx0aGlzLlFuLm5uKHRoaXMpfXJldHVybiB0LnByb3RvdHlwZS5kbj1mdW5jdGlvbih0KXt2b2lkIDA9PT10JiYodD0hMSk7dmFyIGU9dD9oLktuLkpuLnFuOmguS24uSm4uR247aWYodGhpcy56bil7dmFyIGk9dGhpcy5Xbi0obmV3IERhdGUpLmdldFRpbWUoKTtpPmUmJihhLkZyYW1ld29yay5jbGVhclRpbWVvdXQodGhpcy56biksdGhpcy5Xbj1udWxsLHRoaXMuJG4oZSkpfWVsc2UgdGhpcy4kbihlKX0sdC5wcm90b3R5cGUuJG49ZnVuY3Rpb24odCl7dmFyIGU9dGhpczt0aGlzLnpuPWEuRnJhbWV3b3JrLnNldFRpbWVvdXQoZnVuY3Rpb24oKXtlLlluKCl9LHQpLHRoaXMuV249KG5ldyBEYXRlKS5nZXRUaW1lKCkrdH0sdC5wcm90b3R5cGUuWW49ZnVuY3Rpb24oKXt2YXIgdD10aGlzO3RoaXMuem49bnVsbCx0aGlzLlduPW51bGwsdGhpcy5tLmRlYnVnKGUrXCJUQUtJTkcgQSBUUkFDSyBTTkFQU0hPVFwiKSxcbiAgdGhpcy5Rbi5DbigpLnRoZW4oZnVuY3Rpb24oZSl7cmV0dXJuIHQuZm9yd2FyZChlKX0pW1wiZmluYWxseVwiXShmdW5jdGlvbigpe3JldHVybiB0LlFuLnJlc2V0KCl9KX0sdC5wcm90b3R5cGUuZm9yd2FyZD1mdW5jdGlvbih0KXtpZih0aGlzLmNsaWVudCYmdGhpcy5jbGllbnQuWG4oKSl7dmFyIGk9SlNPTi5zdHJpbmdpZnkodCk7c3dpdGNoKHRoaXMuVm4pe2Nhc2UgMDpkZWZhdWx0OnRoaXMubS5kZWJ1ZyhlK1wiVFJBQ0sgRVZFTlRcIik7YnJlYWs7Y2FzZSAxOnRoaXMubS5kZWJ1ZyhlK1wiVFJBQ0sgRVZFTlQ6XCIraSl9dmFyIHI9bmV3IHAuWm4oU2VydmljZXMudG8sMixpKTt0aGlzLmNsaWVudC5YbigpLnNlbmQocil9fSx0fSgpO3QuZW89VDt2YXIgUz1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlKXt0aGlzLmNyZWF0ZWRBdD0obmV3IERhdGUpLmdldFRpbWUoKSx0aGlzLmZuPSExLHRoaXMudGlja2V0PXQsdGhpcy5tYW5pZmVzdHM9bmV3IEFycmF5LHRoaXMueW49bmV3IEFycmF5LHRoaXMuUW49ZX1yZXR1cm4gdC5wcm90b3R5cGUuZ249ZnVuY3Rpb24odCl7dGhpcy5tYW5pZmVzdHMucHVzaCh0KX0sdC5wcm90b3R5cGUudG9KU09OPWZ1bmN0aW9uKCl7dmFyIHQ9e307dC50eXBlPWkueHIsdC50aWNrZXQ9e30sdC50aWNrZXQudXJsPXRoaXMudGlja2V0LnRpY2tldFVybCx0LnRpY2tldC5yZXFUcz10aGlzLnRpY2tldC5pbyx0LnRpY2tldC5yZXNwVHM9dGhpcy50aWNrZXQucm8sdC50aWNrZXQudXNlckFnZW50PXRoaXMuUW4uTW4oKSx0Lm1hbmlmZXN0cz1bXSx0aGlzLm1hbmlmZXN0cy5mb3JFYWNoKGZ1bmN0aW9uKGUpe3ZhciBpPXt9O2kudXJsPWUudXJsLGkucmVzcFRzPWUucm8saS5yZXNwQ29kZT1lLnJlc3BDb2RlLHQubWFuaWZlc3RzLnB1c2goaSl9KTt2YXIgZT0tMSxyPS0xLG49LTE7cmV0dXJuIHRoaXMueW4uZm9yRWFjaChmdW5jdGlvbih0KXt0Lm5vPjAmJihlPT0tMSYmKGU9dC50cyxyPXQubm8pLG49dC5ubyl9KSxlIT0tMSYmKHQucGxheVRzPWUpLG4hPS0xJiYodC5idWZmVGltZT1uKSxyIT0tMSYmKHQuaW5pdEJ1ZmZUaW1lPXIpLHR9LHR9KCk7dC5vbz1TO3ZhciBiPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0LGUsaSl7dGhpcy5ldmVudElkPXQsdGhpcy51cmw9ZSx0aGlzLnJvPShuZXcgRGF0ZSkuZ2V0VGltZSgpLHRoaXMucmVzcENvZGU9aX1yZXR1cm4gdH0oKTt0LnNvPWI7dmFyIEU9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQsZSxpLHIpe3RoaXMudHM9KG5ldyBEYXRlKS5nZXRUaW1lKCksdGhpcy5zZXNzaW9uSWQ9dCx0aGlzLnNlc3Npb25JZHx8KHRoaXMuc2Vzc2lvbklkPVwibnVsbFwiKSx0aGlzLmV2ZW50PWUsdGhpcy5hbz1pLHImJih0aGlzLnRzPXIpfXJldHVybiB0LnByb3RvdHlwZS50b0pTT049ZnVuY3Rpb24oKXt2YXIgdD17fTtyZXR1cm4gdC50eXBlPXRoaXMuY28rdGhpcy5ldmVudCx0LnRzPXRoaXMudHMsdGhpcy5hbyYmKHQucGFyYW1ldGVycz10aGlzLmFvKSx0fSx0fSgpO3QuaG89RTt2YXIgST1mdW5jdGlvbih0KXtmdW5jdGlvbiBlKGUscixuLG8pe3ZhciBzPXQuY2FsbCh0aGlzLGUscixuLG8pfHx0aGlzO3JldHVybiBzLmNvPWkuX3Isc31yZXR1cm4gbihlLHQpLGV9KEUpO3QucG89STt2YXIgUj1mdW5jdGlvbih0KXtmdW5jdGlvbiBlKGUscixuLG8pe3ZhciBzPXQuY2FsbCh0aGlzLGUscixuLG8pfHx0aGlzO3JldHVybiBzLmNvPWkuRHIsc31yZXR1cm4gbihlLHQpLGV9KEUpO3QudW89Ujt2YXIgaz1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlLGkpe3RoaXMudHM9KG5ldyBEYXRlKS5nZXRUaW1lKCksdGhpcy5scj10LHRoaXMubG89ZSx0aGlzLm5vPWl9cmV0dXJuIHR9KCk7dC5kbz1rfShyPWUuRnx8KGUuRj17fSkpfSxmdW5jdGlvbih0LGUpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIGkoKXtpZih0aGlzLmZvKXJldHVybiB0aGlzLmZvO3ZhciB0PXdpbmRvdyYmd2luZG93LndpbmRvdz93aW5kb3cud2luZG93LnZvOnZvaWQgMDtpZihcInVuZGVmaW5lZFwiIT10eXBlb2YgdCYmdC5sb2cmJnQuZGVidWcmJnQuaW5mbyYmdC53YXJuJiZ0LmVycm9yJiYodGhpcy5mbz10KSwhdGhpcy5mbyl7dmFyIGU9IShcInVuZGVmaW5lZFwiPT10eXBlb2Ygd2luZG93LmNvbnNvbGUpLGk9ZT9jb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUpOmZ1bmN0aW9uKCl7fTt0aGlzLmZvPXtsb2c6aSxkZWJ1ZzplJiZ3aW5kb3cuY29uc29sZS5kZWJ1Zz93aW5kb3cuY29uc29sZS5kZWJ1Zy5iaW5kKGNvbnNvbGUpOmksaW5mbzplJiZ3aW5kb3cuY29uc29sZS5pbmZvP3dpbmRvdy5jb25zb2xlLmluZm8uYmluZChjb25zb2xlKTppLHdhcm46ZSYmd2luZG93LmNvbnNvbGUud2Fybj93aW5kb3cuY29uc29sZS53YXJuLmJpbmQoY29uc29sZSk6aSxlcnJvcjplJiZ3aW5kb3cuY29uc29sZS5lcnJvcj93aW5kb3cuY29uc29sZS5lcnJvci5iaW5kKGNvbnNvbGUpOml9fXJldHVybiB0aGlzLmZvfWUudT1cIltIaXZlU2VydmljZXNdIFwiO3ZhciByPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTtyLnlvPTI1MCxlLmtlPXI7dmFyIG49ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQsZSxpKXt0aGlzLm1zZ0lkPWUsdGhpcy5zZXJ2aWNlPXQsdGhpcy5tc2c9aX1yZXR1cm4gdC5wcm90b3R5cGUubW89ZnVuY3Rpb24oKXt2YXIgdD1uZXcgVWludDhBcnJheShbdGhpcy5zZXJ2aWNlPj44LDI1NSZ0aGlzLnNlcnZpY2VdKSxlPW5ldyBVaW50OEFycmF5KFt0aGlzLm1zZ0lkXSksaT1bdCxlLHRoaXMubXNnXTtyZXR1cm4gbmV3IEJsb2IoaSx7dHlwZTpcImFwcGxpY2F0aW9uL29jdGV0LWJpbmFyeVwifSl9LHQud289ZnVuY3Rpb24oZSl7dmFyIGk9KFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxuZXcgVWludDhBcnJheShlKSksU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLG5ldyBVaW50OEFycmF5KGUuc2xpY2UoMykpKSkscj1uZXcgVWludDhBcnJheShlLnNsaWNlKDAsMikpLG49bmV3IFVpbnQ4QXJyYXkoZS5zbGljZSgyLDMpKSxvPShyWzBdPDw4KStyWzFdO3JldHVybiBuZXcgdChvLG5bMF0saSl9LHR9KCk7ZS5abj1uLGUubT1pfSxmdW5jdGlvbih0LGUpe1widXNlIHN0cmljdFwiO3ZhciBpOyFmdW5jdGlvbih0KXt2YXIgZT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHR9KCk7ZS5Mb2dnZXJUaW1lc3RhbXA9ITAsdC5GcmFtZXdvcms9ZTt2YXIgaT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHR9KCk7aS5NZXRyaWNTbmFwc2hvdExvZ3M9MCxpLlRyYWNrU25hcHNob3RMb2dzPTAsdC5EZWJ1Z0xvZ3M9aX0oaT1lLkhpdmVDb25maWd8fChlLkhpdmVDb25maWc9e30pKSxcInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93JiYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIHdpbmRvdy5IaXZlQ29uZmlnJiYod2luZG93LkhpdmVDb25maWc9e30pLHdpbmRvdy5IaXZlQ29uZmlnLkZyYW1ld29yaz1pLkZyYW1ld29yayx3aW5kb3cuSGl2ZUNvbmZpZy5EZWJ1Z0xvZ3M9aS5EZWJ1Z0xvZ3MpfSxmdW5jdGlvbih0LGUpe1widXNlIHN0cmljdFwiO3ZhciBpPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdH0oKTtpLlRvPVwiMTI3LjAuMC4xXCIsaS5icj04OTk5LGkuU3I9ODk5OCxpLlRyPTg4OTksaS5tcj04ODk4LGkuU289XCIvL3swfTp7MX0vP2NhbGxiYWNrPXsyfXszfWhpdmVQbHVnaW5JZD17NH1cIixpLmJvPVwiLy97MH06ezF9Lz9jYWxsYmFjaz17Mn1cIixpLkVyPSEwLGkuRW89LygoaHR0cHxodHRwcyk6XFwvXFwvKC4qKTooWzAtOV0qKVxcLyhbMC05YS16LV0qKS5pc21cXC8pKC4qKS8saS5Jbz1cIjIwMTMuMS4xXCIsZS53cj1pfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI7IWZ1bmN0aW9uKHQpe3QuUm89ITA7dmFyIGU9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7fXJldHVybiB0fSgpO2Uua289XCJ3c3M6Ly9iZWUuaGl2ZXN0cmVhbWluZy5jb206NDQzL3YxL2hpdmVqc1wiLGUuQ289XCJ3c3M6Ly9iZWUtdGVzdC5oaXZlc3RyZWFtaW5nLmNvbTo0NDMvdjEvaGl2ZWpzXCIsZS5Pbz17aWNlU2VydmVyczpbe3VybDpcInN0dW46c3R1bi5oaXZlc3RyZWFtaW5nLmNvbTozNjc4XCJ9XX0sZS5Qbz0zZTQsZS5Hbj0zZTUsZS5xbj04ZTQsZS5Bbz0zZTQsZS5Obz0xMDAsZS54bz0xZTQsdC5Kbj1lfShyPWUuS258fChlLktuPXt9KSl9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcixuPWkoNCksbz1uLnZlLHM9aSgxKSxhPWkoMiksYz1pKDkpLGg9aSg1KSxwPWkoMjcpOyFmdW5jdGlvbih0KXt0W3QuSURMRT0wXT1cIklETEVcIix0W3QuQm89MV09XCJQTEFZXCJ9KHI9ZS5Gb3x8KGUuRm89e30pKTt2YXIgdT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlLGkscil7dGhpcy50aWNrZXQ9dCx0aGlzLl9vPWUsdGhpcy5hcHA9aSx0aGlzLmlkZW50aXR5PXIsdGhpcy5Ebz1hLkZyYW1ld29yay5yZXNvbHZlKGguZ2kubGkpLHRoaXMuSG89YS5GcmFtZXdvcmsucmVzb2x2ZShoLmdpLnNpKSx0aGlzLlFuPWEuRnJhbWV3b3JrLnJlc29sdmUoaC5naS5kaSksdGhpcy5Mbz1uZXcgYy5GLmVvKHRoaXMuUW4pfXJldHVybiB0LnByb3RvdHlwZS5hbj1mdW5jdGlvbih0LGUsaSl7dGhpcy5hcHA9bmV3IGwodCxlKSx0aGlzLkRvLmFuKHRoaXMuYXBwKSx0aGlzLlFuLmFuKHRoaXMuYXBwLGkpfSx0LnByb3RvdHlwZS5DaT1mdW5jdGlvbih0KXt0aGlzLkhvLkNpKHQpfSx0fSgpO2UuTW89dTt2YXIgbD1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlKXt0aGlzLmFwcD10LHRoaXMudmVyc2lvbj1lfXJldHVybiB0fSgpO2Uuam89bDt2YXIgZD1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt0aGlzLlVvPW51bGwsdGhpcy5Wbz1udWxsLHRoaXMuUW89bmV3IG8sdGhpcy5tPWEuRnJhbWV3b3JrLnJlc29sdmUoYS5GcmFtZXdvcmsuRmUud2UpLmxvZygpLHRoaXMubS5kZWJ1ZyhcIklOSVQgUkVQT1JUSU5HXCIpLHRoaXMuX289YS5GcmFtZXdvcmsucmVzb2x2ZShoLmdpLkJlKSx0aGlzLnFvPWEuRnJhbWV3b3JrLnJlc29sdmUoaC5naS5DZSksdGhpcy5Kbz1hLkZyYW1ld29yay5yZXNvbHZlKGguZ2kuYWkpfXJldHVybiB0LnByb3RvdHlwZS5pbml0U2Vzc2lvbj1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMscj1zLmRlZmVyKCksbj10aGlzLnFvLktvKCksbz10aGlzLkpvLkdvKHQpO3JldHVybiBudWxsIT1vP24udGhlbihmdW5jdGlvbih0KXtyZXR1cm4gaS56byh0LG8scixlKX0pLmZhaWwoci5yZWplY3QpOnIucmVqZWN0KFwiVGlja2V0IFVSTCBub3QgdmFsaWRcIiksci52dH0sdC5wcm90b3R5cGUuY2xvc2U9ZnVuY3Rpb24oKXt0aGlzLl9vLmNsb3NlKCl9LHQucHJvdG90eXBlLnpvPWZ1bmN0aW9uKHQsZSxpLHIpe3ZhciBuPXRoaXM7dGhpcy5Vbz10LldvKCksdGhpcy5Wbz10LiRvKCk7dmFyIG89dGhpcy5fby5pbml0KHRoaXMuVW8sZSkscz10aGlzLkpvLnJlc29sdmUoby5ZbyxlLHIpO28udnQudGhlbihmdW5jdGlvbihlKXtzLnRoZW4oZnVuY3Rpb24oZSl7dmFyIHI9ZS5zZXNzaW9uSWQ7aWYobi5Rby5oYXMocikpe3ZhciBvPW4uUW8uZ2V0KHIpO24ubS53YXJuKFwiU0VTU0lPTiBBTFJFQURZIEVYSVNUSU5HIFwiK28uRG8udGlja2V0KX1lbHNle3ZhciBzPW5ldyBsKHAuSGl2ZS5YbygpLHAuSGl2ZS5nZXRWZXJzaW9uKCkpLGE9bmV3IHUoZSxuLl9vLHMsdCk7YS5Eby5pbml0KG4uVm8sZSxzLHIpLGEuUW4uaW5pdChuLlZvLHMpLGEuUW4udW4oZSksbi5Rby5zZXQocixhKSxuLm0uZGVidWcoXCJTRVNTSU9OIFNFVCBcIixyKSxpLnJlc29sdmUoYSl9fSkuZmFpbChmdW5jdGlvbih0KXtyZXR1cm4gaS5yZWplY3QodD90OlwiRXJyb3IgcmVzb2x2aW5nIHRoZSB0aWNrZXRcIil9KSxlLm9uZXJyb3IoZnVuY3Rpb24odCl7aS5yZWplY3QoXCJFcnJvciBlc3RhYmxpc2hpbmcgY29ubmVjdGlvbiB0byBIaXZlIFNlcnZpY2VzXCIpfSl9KS5mYWlsKGZ1bmN0aW9uKHQpe3JldHVybiBpLnJlamVjdCh0KX0pLHRoaXMuX28uY29ubmVjdCgpfSx0LnByb3RvdHlwZS5abz1mdW5jdGlvbih0LGUpe3JldHVybiB0LmVzKCk9PT1lLmVzKCkmJnQuRW4oKT09PWUuRW4oKSYmdC5ibigpPT09ZS5ibigpfSx0fSgpO2UucnM9ZH0sZnVuY3Rpb24odCxlLGkpe3ZhciByLHI7IWZ1bmN0aW9uKGUpe3QudD1lKCl9KGZ1bmN0aW9uKCl7cmV0dXJuIGZ1bmN0aW9uIHQoZSxpLG4pe2Z1bmN0aW9uIG8oYSxjKXtpZighaVthXSl7aWYoIWVbYV0pe3ZhciBoPVwiZnVuY3Rpb25cIj09dHlwZW9mIHImJnI7aWYoIWMmJmgpcmV0dXJuIHIoYSwhMCk7aWYocylyZXR1cm4gcyhhLCEwKTt2YXIgcD1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK2ErXCInXCIpO3Rocm93IHAuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixwfXZhciB1PWlbYV09e3Q6e319O2VbYV1bMF0uY2FsbCh1LnQsZnVuY3Rpb24odCl7dmFyIGk9ZVthXVsxXVt0XTtyZXR1cm4gbyhpP2k6dCl9LHUsdS50LHQsZSxpLG4pfXJldHVybiBpW2FdLnR9Zm9yKHZhciBzPVwiZnVuY3Rpb25cIj09dHlwZW9mIHImJnIsYT0wO2E8bi5sZW5ndGg7YSsrKW8oblthXSk7cmV0dXJuIG99KHsxOltmdW5jdGlvbih0LGUsaSl7dmFyIHI9dChcIi4va2VybmVsXCIpO2kuSWU9ci5JZTt2YXIgbj10KFwiLi90eXBlX2JpbmRpbmdcIik7aS5ucz1uLm5zO3ZhciBvPXQoXCIuL3R5cGVfYmluZGluZ19zY29wZVwiKTtpLnNzPW8uc3N9LHtcIi4va2VybmVsXCI6MixcIi4vdHlwZV9iaW5kaW5nXCI6NCxcIi4vdHlwZV9iaW5kaW5nX3Njb3BlXCI6NX1dLDI6W2Z1bmN0aW9uKHQsZSxpKXt2YXIgcj10KFwiLi90eXBlX2JpbmRpbmdfc2NvcGVcIiksbj10KFwiLi9sb29rdXBcIiksbz1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt0aGlzLmFzPW5ldyBuLmNzfXJldHVybiB0LnByb3RvdHlwZS5iaW5kPWZ1bmN0aW9uKHQpe3RoaXMuYXMuYWRkKHQuaHMsdCl9LHQucHJvdG90eXBlLnBzPWZ1bmN0aW9uKHQpe3RyeXt0aGlzLmFzLnJlbW92ZSh0KX1jYXRjaChlKXt0aHJvdyBuZXcgRXJyb3IoXCJDb3VsZCBub3QgcmVzb2x2ZSBzZXJ2aWNlIFwiK3QpfX0sdC5wcm90b3R5cGUuRWU9ZnVuY3Rpb24oKXt0aGlzLmFzPW5ldyBuLmNzfSx0LnByb3RvdHlwZS5yZXNvbHZlPWZ1bmN0aW9uKHQpe3ZhciBlO2lmKCF0aGlzLmFzLnVzKHQpKXJldHVybiBudWxsO2U9dGhpcy5hcy5nZXQodCk7dmFyIGk9ZVswXTtpZihpLnNjb3BlPT09ci5zcy5scyYmbnVsbCE9PWkuZHMpcmV0dXJuIGkuZHM7dmFyIG49dGhpcy5mcyhpLmdzKTtyZXR1cm4gaS5kcz1uLG59LHQucHJvdG90eXBlLnZzPWZ1bmN0aW9uKHQpe3ZhciBlLGkscixuLG8scztyZXR1cm4gbz0vKChcXC9cXC8uKiQpfChcXC9cXCpbXFxzXFxTXSo/XFwqXFwvKSkvZ20scz0vKFteXFxzLF0rKS9nLGU9dC50b1N0cmluZygpLnJlcGxhY2UobyxcIlwiKSxpPWUuaW5kZXhPZihcIihcIikrMSxyPWUuaW5kZXhPZihcIilcIiksbj1cImZ1bmN0aW9uXCI9PXR5cGVvZiBNYXAmJi0xIT09ZS5pbmRleE9mKFwiY2xhc3NcIikmJi0xPT09ZS5pbmRleE9mKFwiY29uc3RydWN0b3JcIik/bnVsbDplLnNsaWNlKGkscikubWF0Y2gocyksbnVsbD09PW4mJihuPVtdKSxufSx0LnByb3RvdHlwZS5mcz1mdW5jdGlvbih0KXt2YXIgZT10aGlzLnZzKHQpO2lmKDA9PT1lLmxlbmd0aClyZXR1cm4gbmV3IHQ7Zm9yKHZhciBpPVtdLHI9bnVsbCxuPTA7bjxlLmxlbmd0aDtuKyspe3ZhciBvPWVbbl07cj10aGlzLnJlc29sdmUobyksaS5wdXNoKHIpfXJldHVybiB0aGlzLnlzKHQsaSl9LHQucHJvdG90eXBlLnlzPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIG5ldyhGdW5jdGlvbi5wcm90b3R5cGUuYmluZC5hcHBseSh0LFtudWxsXS5jb25jYXQoZSkpKX0sdH0oKTtpLkllPW99LHtcIi4vbG9va3VwXCI6MyxcIi4vdHlwZV9iaW5kaW5nX3Njb3BlXCI6NX1dLDM6W2Z1bmN0aW9uKHQsZSxpKXt2YXIgcj1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlKXt0aGlzLmtleT10LHRoaXMudmFsdWU9bmV3IEFycmF5LHRoaXMudmFsdWUucHVzaChlKX1yZXR1cm4gdH0oKSxuPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMubXM9bmV3IEFycmF5fXJldHVybiB0LnByb3RvdHlwZS53cz1mdW5jdGlvbih0KXtmb3IodmFyIGU9LTEsaT0wO2k8dGhpcy5tcy5sZW5ndGg7aSsrKXt2YXIgcj10aGlzLm1zW2ldO3Iua2V5PT09dCYmKGU9aSl9cmV0dXJuIGV9LHQucHJvdG90eXBlLmFkZD1mdW5jdGlvbih0LGUpe2lmKG51bGw9PT10fHx2b2lkIDA9PT10KXRocm93IG5ldyBFcnJvcihcIkFyZ3VtZW50IE51bGxcIik7aWYobnVsbD09PWV8fHZvaWQgMD09PWUpdGhyb3cgbmV3IEVycm9yKFwiQXJndW1lbnQgTnVsbFwiKTt2YXIgaT10aGlzLndzKHQpO2lmKC0xIT09aSl7dmFyIG49dGhpcy5tc1tpXTtuLmtleT09PXQmJm4udmFsdWUucHVzaChlKX1lbHNlIHRoaXMubXMucHVzaChuZXcgcih0LGUpKX0sdC5wcm90b3R5cGUuZ2V0PWZ1bmN0aW9uKHQpe2lmKG51bGw9PT10fHx2b2lkIDA9PT10KXRocm93IG5ldyBFcnJvcihcIkFyZ3VtZW50IE51bGxcIik7dmFyIGU9dGhpcy53cyh0KTtpZigtMT09PWUpdGhyb3cgbmV3IEVycm9yKFwiS2V5IE5vdCBGb3VuZFwiKTt2YXIgaT10aGlzLm1zW2VdO3JldHVybiBpLmtleT09PXQ/aS52YWx1ZTp2b2lkIDB9LHQucHJvdG90eXBlLnJlbW92ZT1mdW5jdGlvbih0KXtpZihudWxsPT09dHx8dm9pZCAwPT09dCl0aHJvdyBuZXcgRXJyb3IoXCJBcmd1bWVudCBOdWxsXCIpO3ZhciBlPXRoaXMud3ModCk7aWYoLTE9PT1lKXRocm93IG5ldyBFcnJvcihcIktleSBOb3QgRm91bmRcIik7dGhpcy5tcy5zcGxpY2UoZSwxKX0sdC5wcm90b3R5cGUudXM9ZnVuY3Rpb24odCl7aWYobnVsbD09PXR8fHZvaWQgMD09PXQpdGhyb3cgbmV3IEVycm9yKFwiQXJndW1lbnQgTnVsbFwiKTt2YXIgZT10aGlzLndzKHQpO3JldHVybi0xIT09ZX0sdH0oKTtpLmNzPW59LHt9XSw0OltmdW5jdGlvbih0LGUsaSl7dmFyIHI9dChcIi4vdHlwZV9iaW5kaW5nX3Njb3BlXCIpLG49ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQsZSxpKXtpZih0aGlzLmhzPXQsdGhpcy5ncz1lLHRoaXMuZHM9bnVsbCxcInVuZGVmaW5lZFwiPT10eXBlb2YgaSl0aGlzLnNjb3BlPXIuc3MuVHM7ZWxzZXtpZighci5zc1tpXSl7dmFyIG49XCJJbnZhbGlkIHNjb3BlIHR5cGUgXCIraTt0aHJvdyBuZXcgRXJyb3Iobil9dGhpcy5zY29wZT1pfX1yZXR1cm4gdH0oKTtpLm5zPW59LHtcIi4vdHlwZV9iaW5kaW5nX3Njb3BlXCI6NX1dLDU6W2Z1bmN0aW9uKHQsZSxpKXt2YXIgcjshZnVuY3Rpb24odCl7dFt0LlRzPTBdPVwiVHJhbnNpZW50XCIsdFt0LmxzPTFdPVwiU2luZ2xldG9uXCJ9KHJ8fChyPXt9KSksaS5zcz1yfSx7fV19LHt9LFsxXSkoMSl9KX0sZnVuY3Rpb24obW9kdWxlLGV4cG9ydHMsX193ZWJwYWNrX3JlcXVpcmVfXyl7dmFyIFRocmlmdD17U3M6XCIwLjkuMlwiLGJzOntFczowLElzOjEsQk9PTDoyLEJZVEU6MyxSczozLGtzOjQsQ3M6NixPczo4LFBzOjEwLEFzOjExLE5zOjExLHhzOjEyLEJzOjEzLEZzOjE0LF9zOjE1LERzOjE2LEhzOjE3fSxMczp7TXM6MSxqczoyLFVzOjMsVnM6NH0sUXM6ZnVuY3Rpb24odCl7dmFyIGU9MDtmb3IodmFyIGkgaW4gdCl0Lmhhc093blByb3BlcnR5KGkpJiZlKys7cmV0dXJuIGV9LHFzOmZ1bmN0aW9uKHQsZSxpKXtmdW5jdGlvbiByKCl7fXIucHJvdG90eXBlPWUucHJvdG90eXBlLHQucHJvdG90eXBlPW5ldyByLHQucHJvdG90eXBlLm5hbWU9aXx8XCJcIn19O1RocmlmdC5Kcz1mdW5jdGlvbih0KXt0aGlzLm1lc3NhZ2U9dH0sVGhyaWZ0LnFzKFRocmlmdC5KcyxFcnJvcixcIlRFeGNlcHRpb25cIiksVGhyaWZ0LkpzLnByb3RvdHlwZS5Lcz1mdW5jdGlvbigpe3JldHVybiB0aGlzLm1lc3NhZ2V9LFRocmlmdC5Hcz17enM6MCxXczoxLCRzOjIsWXM6MyxYczo0LFpzOjUsdGE6NixlYTo3LGlhOjgscmE6OSxuYToxMH0sVGhyaWZ0Lm9hPWZ1bmN0aW9uKHQsZSl7dGhpcy5tZXNzYWdlPXQsdGhpcy5jb2RlPVwibnVtYmVyXCI9PXR5cGVvZiBlP2U6MH0sVGhyaWZ0LnFzKFRocmlmdC5vYSxUaHJpZnQuSnMsXCJUQXBwbGljYXRpb25FeGNlcHRpb25cIiksVGhyaWZ0Lm9hLnByb3RvdHlwZS5yZWFkPWZ1bmN0aW9uKHQpe2Zvcig7Oyl7dmFyIGU9dC5zYSgpO2lmKGUuYWE9PVRocmlmdC5icy5FcylicmVhazt2YXIgaT1lLmNhO3N3aXRjaChpKXtjYXNlIDE6ZS5hYT09VGhyaWZ0LmJzLkFzPyhlPXQuaGEoKSx0aGlzLm1lc3NhZ2U9ZS52YWx1ZSk6ZT10LnBhKGUuYWEpO2JyZWFrO2Nhc2UgMjplLmFhPT1UaHJpZnQuYnMuT3M/KGU9dC51YSgpLHRoaXMuY29kZT1lLnZhbHVlKTplPXQucGEoZS5hYSk7YnJlYWs7ZGVmYXVsdDplPXQucGEoZS5hYSl9dC5sYSgpfXQuZGEoKX0sVGhyaWZ0Lm9hLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbih0KXt0LmZhKFwiVEFwcGxpY2F0aW9uRXhjZXB0aW9uXCIpLHRoaXMubWVzc2FnZSYmKHQuZ2EoXCJtZXNzYWdlXCIsVGhyaWZ0LmJzLkFzLDEpLHQudmEodGhpcy5LcygpKSx0LnlhKCkpLHRoaXMuY29kZSYmKHQuZ2EoXCJ0eXBlXCIsVGhyaWZ0LmJzLk9zLDIpLHQubWEodGhpcy5jb2RlKSx0LnlhKCkpLHQud2EoKSx0LlRhKCl9LFRocmlmdC5vYS5wcm90b3R5cGUuU2E9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jb2RlfSxUaHJpZnQuYmE9VGhyaWZ0LkVhPWZ1bmN0aW9uKHQsZSl7dGhpcy51cmw9dCx0aGlzLklhPTAsdGhpcy5SYT0wLHRoaXMua2E9ZSYmZS5rYSx0aGlzLkNhPVwiXCIsdGhpcy5PYT1cIlwifSxUaHJpZnQuRWEucHJvdG90eXBlPXtQYTpmdW5jdGlvbigpe3RyeXtyZXR1cm4gbmV3IFhNTEh0dHBSZXF1ZXN0fWNhdGNoKHQpe310cnl7cmV0dXJuIG5ldyBBY3RpdmVYT2JqZWN0KFwiTXN4bWwyLlhNTEhUVFBcIil9Y2F0Y2goZSl7fXRyeXtyZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoXCJNaWNyb3NvZnQuWE1MSFRUUFwiKX1jYXRjaChpKXt9dGhyb3dcIllvdXIgYnJvd3NlciBkb2Vzbid0IHN1cHBvcnQgWEhSLlwifSxmbHVzaDpmdW5jdGlvbih0LGUpe3ZhciBpPXRoaXM7aWYodCYmIWV8fHZvaWQgMD09PXRoaXMudXJsfHxcIlwiPT09dGhpcy51cmwpcmV0dXJuIHRoaXMuQ2E7dmFyIHI9dGhpcy5QYSgpO2lmKHIub3ZlcnJpZGVNaW1lVHlwZSYmci5vdmVycmlkZU1pbWVUeXBlKFwiYXBwbGljYXRpb24vanNvblwiKSxlJiYoci5vbnJlYWR5c3RhdGVjaGFuZ2U9ZnVuY3Rpb24oKXt2YXIgdD1lO3JldHVybiBmdW5jdGlvbigpezQ9PXRoaXMucmVhZHlTdGF0ZSYmMjAwPT10aGlzLnN0YXR1cyYmKGkuQWEodGhpcy5yZXNwb25zZVRleHQpLHQoKSl9fSgpKSxyLm9wZW4oXCJQT1NUXCIsdGhpcy51cmwsISF0KSxyLnNlbmQodGhpcy5DYSksIXR8fCFlKXtpZig0IT1yLnJlYWR5U3RhdGUpdGhyb3dcImVuY291bnRlcmVkIGFuIHVua25vd24gYWpheCByZWFkeSBzdGF0ZTogXCIrci5yZWFkeVN0YXRlO2lmKDIwMCE9ci5zdGF0dXMpdGhyb3dcImVuY291bnRlcmVkIGEgdW5rbm93biByZXF1ZXN0IHN0YXR1czogXCIrci5zdGF0dXM7dGhpcy5PYT1yLnJlc3BvbnNlVGV4dCx0aGlzLk5hPXRoaXMuT2EubGVuZ3RoLHRoaXMuSWE9dGhpcy5PYS5sZW5ndGgsdGhpcy5SYT0wfX0seGE6ZnVuY3Rpb24odCxlLGkscil7aWYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIGpRdWVyeXx8XCJ1bmRlZmluZWRcIj09dHlwZW9mIGpRdWVyeS5EZWZlcnJlZCl0aHJvd1wiVGhyaWZ0LmpzIHJlcXVpcmVzIGpRdWVyeSAxLjUrIHRvIHVzZSBhc3luY2hyb25vdXMgcmVxdWVzdHNcIjt2YXIgbj10aGlzLG89alF1ZXJ5LmFqYXgoe3VybDp0aGlzLnVybCxkYXRhOmUsdHlwZTpcIlBPU1RcIixkczohMSxjb250ZW50VHlwZTpcImFwcGxpY2F0aW9uL2pzb25cIixCYTpcInRleHQgdGhyaWZ0XCIsRmE6e19hOmZ1bmN0aW9uKGUpe24uQWEoZSk7dmFyIGk9ci5jYWxsKHQpO3JldHVybiBpfX0sY29udGV4dDp0LHN1Y2Nlc3M6alF1ZXJ5Lm1ha2VBcnJheShpKS5wb3AoKX0pO3JldHVybiBvfSxBYTpmdW5jdGlvbih0KXt0aGlzLk9hPXQsdGhpcy5OYT10aGlzLk9hLmxlbmd0aCx0aGlzLklhPXRoaXMuT2EubGVuZ3RoLHRoaXMuUmE9MH0saXNPcGVuOmZ1bmN0aW9uKCl7cmV0dXJuITB9LG9wZW46ZnVuY3Rpb24oKXt9LGNsb3NlOmZ1bmN0aW9uKCl7fSxyZWFkOmZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuSWEtdGhpcy5SYTtpZigwPT09ZSlyZXR1cm5cIlwiO3ZhciBpPXQ7ZTx0JiYoaT1lKTt2YXIgcj10aGlzLnJlYWRfYnVmLnN1YnN0cih0aGlzLlJhLGkpO3JldHVybiB0aGlzLlJhKz1pLHJ9LERhOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuT2F9LHdyaXRlOmZ1bmN0aW9uKHQpe3RoaXMuQ2E9dH0sSGE6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5DYX19LFRocmlmdC5MYT1mdW5jdGlvbih0KXt0aGlzLk1hKHQpfSxUaHJpZnQuTGEucHJvdG90eXBlPXtNYTpmdW5jdGlvbih0KXt0aGlzLnVybD10LHRoaXMuamE9bnVsbCx0aGlzLmNhbGxiYWNrcz1bXSx0aGlzLlVhPVtdLHRoaXMuQ2E9XCJcIix0aGlzLk9hPVwiXCIsdGhpcy5WYT0wLHRoaXMuUWE9MH0sZmx1c2g6ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzO3RoaXMuaXNPcGVuKCk/KHRoaXMuamEuc2VuZCh0aGlzLkNhKSx0aGlzLmNhbGxiYWNrcy5wdXNoKGZ1bmN0aW9uKCl7dmFyIHQ9ZTtyZXR1cm4gZnVuY3Rpb24oZSl7aS5BYShlKSx0KCl9fSgpKSk6dGhpcy5VYS5wdXNoKHtxYTp0aGlzLkNhLEphOmV9KX0sS2E6ZnVuY3Rpb24oKXt2YXIgdD10aGlzO3RoaXMuVWEubGVuZ3RoPjAmJih0aGlzLlVhLmZvckVhY2goZnVuY3Rpb24oZSl7dGhpcy5qYS5zZW5kKGUucWEpLHRoaXMuY2FsbGJhY2tzLnB1c2goZnVuY3Rpb24oKXt2YXIgaT1lLkphO3JldHVybiBmdW5jdGlvbihlKXt0LkFhKGUpLGkoKX19KCkpfSksdGhpcy5VYT1bXSl9LEdhOmZ1bmN0aW9uKHQpe3RoaXMuTWEodGhpcy51cmwpfSx6YTpmdW5jdGlvbih0KXt0aGlzLmNhbGxiYWNrcy5sZW5ndGgmJnRoaXMuY2FsbGJhY2tzLnNoaWZ0KCkodC5kYXRhKX0sV2E6ZnVuY3Rpb24odCl7Y29uc29sZS5sb2coXCJUaHJpZnQgV2ViU29ja2V0IEVycm9yOiBcIit0LnRvU3RyaW5nKCkpLHRoaXMuamEuY2xvc2UoKX0sQWE6ZnVuY3Rpb24odCl7dGhpcy5PYT10LHRoaXMuTmE9dGhpcy5PYS5sZW5ndGgsdGhpcy5JYT10aGlzLk9hLmxlbmd0aCx0aGlzLlJhPTB9LGlzT3BlbjpmdW5jdGlvbigpe3JldHVybiB0aGlzLmphJiZ0aGlzLmphLnJlYWR5U3RhdGU9PXRoaXMuamEuT1BFTn0sb3BlbjpmdW5jdGlvbigpe3RoaXMuamEmJnRoaXMuamEucmVhZHlTdGF0ZSE9dGhpcy5qYS5DTE9TRUR8fCh0aGlzLmphPW5ldyBXZWJTb2NrZXQodGhpcy51cmwpLHRoaXMuamEub25vcGVuPXRoaXMuS2EuYmluZCh0aGlzKSx0aGlzLmphLm9ubWVzc2FnZT10aGlzLnphLmJpbmQodGhpcyksdGhpcy5qYS5vbmVycm9yPXRoaXMuV2EuYmluZCh0aGlzKSx0aGlzLmphLm9uY2xvc2U9dGhpcy5HYS5iaW5kKHRoaXMpKX0sY2xvc2U6ZnVuY3Rpb24oKXt0aGlzLmphLmNsb3NlKCl9LHJlYWQ6ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5JYS10aGlzLlJhO2lmKDA9PT1lKXJldHVyblwiXCI7dmFyIGk9dDtlPHQmJihpPWUpO3ZhciByPXRoaXMucmVhZF9idWYuc3Vic3RyKHRoaXMuUmEsaSk7cmV0dXJuIHRoaXMuUmErPWkscn0sRGE6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5PYX0sd3JpdGU6ZnVuY3Rpb24odCl7dGhpcy5DYT10fSxIYTpmdW5jdGlvbigpe3JldHVybiB0aGlzLkNhfX0sVGhyaWZ0LiRhPVRocmlmdC5ZYT1mdW5jdGlvbih0KXt0aGlzLlhhPXR9LFRocmlmdC5ZYS5icz17fSxUaHJpZnQuWWEuYnNbVGhyaWZ0LmJzLkJPT0xdPSdcInRmXCInLFRocmlmdC5ZYS5ic1tUaHJpZnQuYnMuQllURV09J1wiaThcIicsVGhyaWZ0LllhLmJzW1RocmlmdC5icy5Dc109J1wiaTE2XCInLFRocmlmdC5ZYS5ic1tUaHJpZnQuYnMuT3NdPSdcImkzMlwiJyxUaHJpZnQuWWEuYnNbVGhyaWZ0LmJzLlBzXT0nXCJpNjRcIicsVGhyaWZ0LllhLmJzW1RocmlmdC5icy5rc109J1wiZGJsXCInLFRocmlmdC5ZYS5ic1tUaHJpZnQuYnMueHNdPSdcInJlY1wiJyxUaHJpZnQuWWEuYnNbVGhyaWZ0LmJzLkFzXT0nXCJzdHJcIicsVGhyaWZ0LllhLmJzW1RocmlmdC5icy5Cc109J1wibWFwXCInLFRocmlmdC5ZYS5ic1tUaHJpZnQuYnMuX3NdPSdcImxzdFwiJyxUaHJpZnQuWWEuYnNbVGhyaWZ0LmJzLkZzXT0nXCJzZXRcIicsVGhyaWZ0LllhLlphPXt9LFRocmlmdC5ZYS5aYS50Yz1UaHJpZnQuYnMuQk9PTCxUaHJpZnQuWWEuWmEuZWM9VGhyaWZ0LmJzLkJZVEUsVGhyaWZ0LllhLlphLmljPVRocmlmdC5icy5DcyxUaHJpZnQuWWEuWmEucmM9VGhyaWZ0LmJzLk9zLFRocmlmdC5ZYS5aYS5uYz1UaHJpZnQuYnMuUHMsVGhyaWZ0LllhLlphLm9jPVRocmlmdC5icy5rcyxUaHJpZnQuWWEuWmEuc2M9VGhyaWZ0LmJzLnhzLFRocmlmdC5ZYS5aYS5hYz1UaHJpZnQuYnMuQXMsVGhyaWZ0LllhLlphLm1hcD1UaHJpZnQuYnMuQnMsVGhyaWZ0LllhLlphLmNjPVRocmlmdC5icy5fcyxUaHJpZnQuWWEuWmEuc2V0PVRocmlmdC5icy5GcyxUaHJpZnQuWWEuU3M9MSxUaHJpZnQuWWEucHJvdG90eXBlPXtoYzpmdW5jdGlvbigpe3JldHVybiB0aGlzLlhhfSxwYzpmdW5jdGlvbih0LGUsaSl7dGhpcy51Yz1bXSx0aGlzLmxjPVtdLHRoaXMudWMucHVzaChbVGhyaWZ0LllhLlNzLCdcIicrdCsnXCInLGUsaV0pfSxkYzpmdW5jdGlvbigpe3ZhciB0PXRoaXMudWMucG9wKCk7dGhpcy5mYz10aGlzLnVjLnBvcCgpLHRoaXMuZmMucHVzaCh0KSx0aGlzLmdjPVwiW1wiK3RoaXMuZmMuam9pbihcIixcIikrXCJdXCIsdGhpcy5YYS53cml0ZSh0aGlzLmdjKX0sZmE6ZnVuY3Rpb24odCl7dGhpcy5sYy5wdXNoKHRoaXMudWMubGVuZ3RoKSx0aGlzLnVjLnB1c2goe30pfSxUYTpmdW5jdGlvbigpe3ZhciB0PXRoaXMubGMucG9wKCksZT10aGlzLnVjW3RdLGk9XCJ7XCIscj0hMDtmb3IodmFyIG4gaW4gZSlyP3I9ITE6aSs9XCIsXCIsaSs9bitcIjpcIitlW25dO2krPVwifVwiLHRoaXMudWNbdF09aX0sZ2E6ZnVuY3Rpb24odCxlLGkpe3RoaXMubGMucHVzaCh0aGlzLnVjLmxlbmd0aCksdGhpcy51Yy5wdXNoKHt2YzonXCInK2krJ1wiJyx5YzpUaHJpZnQuWWEuYnNbZV19KX0seWE6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLnVjLnBvcCgpLGU9dGhpcy51Yy5wb3AoKTt0aGlzLnVjW3RoaXMudWMubGVuZ3RoLTFdW2UudmNdPVwie1wiK2UueWMrXCI6XCIrdCtcIn1cIix0aGlzLmxjLnBvcCgpfSx3YTpmdW5jdGlvbigpe30sbWM6ZnVuY3Rpb24odCxlLGkpe3RoaXMubGMucHVzaCh0aGlzLnVjLmxlbmd0aCksdGhpcy51Yy5wdXNoKFtUaHJpZnQuWWEuYnNbdF0sVGhyaWZ0LllhLmJzW2VdLDBdKX0sd2M6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmxjLnBvcCgpO2lmKHQhPXRoaXMudWMubGVuZ3RoKXsodGhpcy51Yy5sZW5ndGgtdC0xKSUyIT09MCYmdGhpcy51Yy5wdXNoKFwiXCIpO3ZhciBlPSh0aGlzLnVjLmxlbmd0aC10LTEpLzI7dGhpcy51Y1t0XVt0aGlzLnVjW3RdLmxlbmd0aC0xXT1lO2Zvcih2YXIgaT1cIn1cIixyPSEwO3RoaXMudWMubGVuZ3RoPnQrMTspe3ZhciBuPXRoaXMudWMucG9wKCksbz10aGlzLnVjLnBvcCgpO3I/cj0hMTppPVwiLFwiK2ksaXNOYU4obyl8fChvPSdcIicrbysnXCInKSxpPW8rXCI6XCIrbitpfWk9XCJ7XCIraSx0aGlzLnVjW3RdLnB1c2goaSksdGhpcy51Y1t0XT1cIltcIit0aGlzLnVjW3RdLmpvaW4oXCIsXCIpK1wiXVwifX0sVGM6ZnVuY3Rpb24odCxlKXt0aGlzLmxjLnB1c2godGhpcy51Yy5sZW5ndGgpLHRoaXMudWMucHVzaChbVGhyaWZ0LllhLmJzW3RdLGVdKX0sU2M6ZnVuY3Rpb24oKXtmb3IodmFyIHQ9dGhpcy5sYy5wb3AoKTt0aGlzLnVjLmxlbmd0aD50KzE7KXt2YXIgZT10aGlzLnVjW3QrMV07dGhpcy51Yy5zcGxpY2UodCsxLDEpLHRoaXMudWNbdF0ucHVzaChlKX10aGlzLnVjW3RdPVwiW1wiK3RoaXMudWNbdF0uam9pbihcIixcIikrXCJdXCJ9LGJjOmZ1bmN0aW9uKHQsZSl7dGhpcy5sYy5wdXNoKHRoaXMudWMubGVuZ3RoKSx0aGlzLnVjLnB1c2goW1RocmlmdC5ZYS5ic1t0XSxlXSl9LEVjOmZ1bmN0aW9uKCl7Zm9yKHZhciB0PXRoaXMubGMucG9wKCk7dGhpcy51Yy5sZW5ndGg+dCsxOyl7dmFyIGU9dGhpcy51Y1t0KzFdO3RoaXMudWMuc3BsaWNlKHQrMSwxKSx0aGlzLnVjW3RdLnB1c2goZSl9dGhpcy51Y1t0XT1cIltcIit0aGlzLnVjW3RdLmpvaW4oXCIsXCIpK1wiXVwifSxJYzpmdW5jdGlvbih0KXt0aGlzLnVjLnB1c2godD8xOjApfSxSYzpmdW5jdGlvbih0KXt0aGlzLnVjLnB1c2godCl9LGtjOmZ1bmN0aW9uKHQpe3RoaXMudWMucHVzaCh0KX0sbWE6ZnVuY3Rpb24odCl7dGhpcy51Yy5wdXNoKHQpfSxDYzpmdW5jdGlvbih0KXt0aGlzLnVjLnB1c2godCl9LE9jOmZ1bmN0aW9uKHQpe3RoaXMudWMucHVzaCh0KX0sdmE6ZnVuY3Rpb24odCl7aWYobnVsbD09PXQpdGhpcy51Yy5wdXNoKG51bGwpO2Vsc2V7Zm9yKHZhciBlPVwiXCIsaT0wO2k8dC5sZW5ndGg7aSsrKXt2YXIgcj10LmNoYXJBdChpKTtlKz0nXCInPT09cj8nXFxcXFwiJzpcIlxcXFxcIj09PXI/XCJcXFxcXFxcXFwiOlwiXFxiXCI9PT1yP1wiXFxcXGJcIjpcIlxcZlwiPT09cj9cIlxcXFxmXCI6XCJcXG5cIj09PXI/XCJcXFxcblwiOlwiXFxyXCI9PT1yP1wiXFxcXHJcIjpcIlxcdFwiPT09cj9cIlxcXFx0XCI6cn10aGlzLnVjLnB1c2goJ1wiJytlKydcIicpfX0sUGM6ZnVuY3Rpb24odCl7dGhpcy52YSh0KX0sQWM6ZnVuY3Rpb24oKXt0aGlzLk5jPVtdLHRoaXMuUmE9W10sXCJ1bmRlZmluZWRcIiE9dHlwZW9mIEpTT04mJlwiZnVuY3Rpb25cIj09dHlwZW9mIEpTT04ucGFyc2U/dGhpcy54Yz1KU09OLnBhcnNlKHRoaXMuWGEuRGEoKSk6XCJ1bmRlZmluZWRcIiE9dHlwZW9mIGpRdWVyeT90aGlzLnhjPWpRdWVyeS5wYXJzZUpTT04odGhpcy5YYS5EYSgpKTp0aGlzLnhjPWV2YWwodGhpcy5YYS5EYSgpKTt2YXIgcj17fSx2ZXJzaW9uPXRoaXMueGMuc2hpZnQoKTtpZih2ZXJzaW9uIT1UaHJpZnQuWWEuU3MpdGhyb3dcIldyb25nIHRocmlmdCBwcm90b2NvbCB2ZXJzaW9uOiBcIit2ZXJzaW9uO3JldHVybiByLkJjPXRoaXMueGMuc2hpZnQoKSxyLkZjPXRoaXMueGMuc2hpZnQoKSxyLl9jPXRoaXMueGMuc2hpZnQoKSx0aGlzLk5jLnB1c2godGhpcy54Yy5zaGlmdCgpKSxyfSxEYzpmdW5jdGlvbigpe30sSGM6ZnVuY3Rpb24odCl7dmFyIGU9e307cmV0dXJuIGUuQmM9XCJcIix0aGlzLk5jW3RoaXMuTmMubGVuZ3RoLTFdaW5zdGFuY2VvZiBBcnJheSYmdGhpcy5OYy5wdXNoKHRoaXMuTmNbdGhpcy5OYy5sZW5ndGgtMV0uc2hpZnQoKSksZX0sZGE6ZnVuY3Rpb24oKXt0aGlzLk5jW3RoaXMuTmMubGVuZ3RoLTJdaW5zdGFuY2VvZiBBcnJheSYmdGhpcy5OYy5wb3AoKX0sc2E6ZnVuY3Rpb24oKXt2YXIgdD17fSxlPS0xLGk9VGhyaWZ0LmJzLkVzO2Zvcih2YXIgciBpbiB0aGlzLk5jW3RoaXMuTmMubGVuZ3RoLTFdKWlmKG51bGwhPT1yKXtlPXBhcnNlSW50KHIsMTApLHRoaXMuUmEucHVzaCh0aGlzLk5jLmxlbmd0aCk7dmFyIG49dGhpcy5OY1t0aGlzLk5jLmxlbmd0aC0xXVtlXTtkZWxldGUgdGhpcy5OY1t0aGlzLk5jLmxlbmd0aC0xXVtlXSx0aGlzLk5jLnB1c2gobik7YnJlYWt9aWYoZSE9LTEpZm9yKHZhciBvIGluIHRoaXMuTmNbdGhpcy5OYy5sZW5ndGgtMV0pbnVsbCE9PVRocmlmdC5ZYS5aYVtvXSYmKGk9VGhyaWZ0LllhLlphW29dLHRoaXMuTmNbdGhpcy5OYy5sZW5ndGgtMV09dGhpcy5OY1t0aGlzLk5jLmxlbmd0aC0xXVtvXSk7cmV0dXJuIHQuQmM9XCJcIix0LmFhPWksdC5jYT1lLHR9LGxhOmZ1bmN0aW9uKCl7Zm9yKHZhciB0PXRoaXMuUmEucG9wKCk7dGhpcy5OYy5sZW5ndGg+dDspdGhpcy5OYy5wb3AoKX0sTGM6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLk5jLnBvcCgpLGU9dC5zaGlmdCgpO2UgaW5zdGFuY2VvZiBBcnJheSYmKHRoaXMuTmMucHVzaCh0KSx0PWUsZT10LnNoaWZ0KCkpO3ZhciBpPXt9O3JldHVybiBpLk1jPVRocmlmdC5ZYS5aYVtlXSxpLmpjPVRocmlmdC5ZYS5aYVt0LnNoaWZ0KCldLGkuc2l6ZT10LnNoaWZ0KCksdGhpcy5SYS5wdXNoKHRoaXMuTmMubGVuZ3RoKSx0aGlzLk5jLnB1c2godC5zaGlmdCgpKSxpfSxVYzpmdW5jdGlvbigpe3RoaXMubGEoKX0sVmM6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLk5jW3RoaXMuTmMubGVuZ3RoLTFdLGU9e307cmV0dXJuIGUuUWM9VGhyaWZ0LllhLlphW3Quc2hpZnQoKV0sZS5zaXplPXQuc2hpZnQoKSx0aGlzLlJhLnB1c2godGhpcy5OYy5sZW5ndGgpLHRoaXMuTmMucHVzaCh0KSxlfSxxYzpmdW5jdGlvbigpe3RoaXMubGEoKX0sSmM6ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5WYyh0LGUpfSxLYzpmdW5jdGlvbigpe3JldHVybiB0aGlzLnFjKCl9LEdjOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy51YSgpO3JldHVybiBudWxsIT09dCYmXCIxXCI9PXQudmFsdWU/dC52YWx1ZT0hMDp0LnZhbHVlPSExLHR9LHpjOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudWEoKX0sV2M6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy51YSgpfSx1YTpmdW5jdGlvbih0KXt2b2lkIDA9PT10JiYodD10aGlzLk5jW3RoaXMuTmMubGVuZ3RoLTFdKTt2YXIgZT17fTtpZih0IGluc3RhbmNlb2YgQXJyYXkpMD09PXQubGVuZ3RoP2UudmFsdWU9dm9pZCAwOmUudmFsdWU9dC5zaGlmdCgpO2Vsc2UgaWYodCBpbnN0YW5jZW9mIE9iamVjdCl7Zm9yKHZhciBpIGluIHQpaWYobnVsbCE9PWkpe3RoaXMuTmMucHVzaCh0W2ldKSxkZWxldGUgdFtpXSxlLnZhbHVlPWk7YnJlYWt9fWVsc2UgZS52YWx1ZT10LHRoaXMuTmMucG9wKCk7cmV0dXJuIGV9LCRjOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudWEoKX0sWWM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy51YSgpfSxoYTpmdW5jdGlvbigpe3ZhciB0PXRoaXMudWEoKTtyZXR1cm4gdH0sWGM6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5oYSgpfSxwYTpmdW5jdGlvbih0KXt2YXIgZSxpO3N3aXRjaCh0KXtjYXNlIFRocmlmdC5icy5FczpyZXR1cm4gbnVsbDtjYXNlIFRocmlmdC5icy5CT09MOnJldHVybiB0aGlzLkdjKCk7Y2FzZSBUaHJpZnQuYnMuQllURTpyZXR1cm4gdGhpcy56YygpO2Nhc2UgVGhyaWZ0LmJzLkNzOnJldHVybiB0aGlzLldjKCk7Y2FzZSBUaHJpZnQuYnMuT3M6cmV0dXJuIHRoaXMudWEoKTtjYXNlIFRocmlmdC5icy5QczpyZXR1cm4gdGhpcy4kYygpO2Nhc2UgVGhyaWZ0LmJzLmtzOnJldHVybiB0aGlzLlljKCk7Y2FzZSBUaHJpZnQuYnMuQXM6cmV0dXJuIHRoaXMuaGEoKTtjYXNlIFRocmlmdC5icy54czpmb3IodGhpcy5IYygpOzspe2lmKGU9dGhpcy5zYSgpLGUuYWE9PVRocmlmdC5icy5FcylicmVhazt0aGlzLnBhKGUuYWEpLHRoaXMubGEoKX1yZXR1cm4gdGhpcy5kYSgpLG51bGw7Y2FzZSBUaHJpZnQuYnMuQnM6Zm9yKGU9dGhpcy5MYygpLGk9MDtpPGUuc2l6ZTtpKyspaT4wJiZ0aGlzLk5jLmxlbmd0aD50aGlzLlJhW3RoaXMuUmEubGVuZ3RoLTFdKzEmJnRoaXMuTmMucG9wKCksdGhpcy5wYShlLk1jKSx0aGlzLnBhKGUuamMpO3JldHVybiB0aGlzLlVjKCksbnVsbDtjYXNlIFRocmlmdC5icy5Gczpmb3IoZT10aGlzLkpjKCksaT0wO2k8ZS5zaXplO2krKyl0aGlzLnBhKGUuUWMpO3JldHVybiB0aGlzLktjKCksbnVsbDtjYXNlIFRocmlmdC5icy5fczpmb3IoZT10aGlzLlZjKCksaT0wO2k8ZS5zaXplO2krKyl0aGlzLnBhKGUuUWMpO3JldHVybiB0aGlzLnFjKCksbnVsbH19fSxUaHJpZnQuWmM9ZnVuY3Rpb24odCxlLGkscil7VGhyaWZ0LllhLmNhbGwodGhpcyxlLGksciksdGhpcy50aD10fSxUaHJpZnQucXMoVGhyaWZ0LlpjLFRocmlmdC5ZYSxcIm11bHRpcGxleFByb3RvY29sXCIpLFRocmlmdC5aYy5wcm90b3R5cGUucGM9ZnVuY3Rpb24odCxlLGkpe2U9PT1UaHJpZnQuTHMuTXN8fGU9PT1UaHJpZnQuTHMuVnM/VGhyaWZ0LllhLnByb3RvdHlwZS5wYy5jYWxsKHRoaXMsdGhpcy50aCtcIjpcIit0LGUsaSk6VGhyaWZ0LllhLnByb3RvdHlwZS5wYy5jYWxsKHRoaXMsdCxlLGkpfSxUaHJpZnQuZWg9ZnVuY3Rpb24oKXt0aGlzLmloPTB9LFRocmlmdC5laC5wcm90b3R5cGUucmg9ZnVuY3Rpb24odCxlLGkpe2UuZW8mJihlPWUuZW8pO3ZhciByPXRoaXM7ZS5wcm90b3R5cGUubmg9ZnVuY3Rpb24oKXtyZXR1cm4gci5paCs9MSxyLmlofTt2YXIgbj1uZXcgZShuZXcgVGhyaWZ0LlpjKHQsaSkpO3JldHVybiBufSxtb2R1bGUudD1UaHJpZnR9LGZ1bmN0aW9uKHQsZSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGk7IWZ1bmN0aW9uKHQpe2Z1bmN0aW9uIGUodCl7cmV0dXJuIG5bdF19dmFyIGk9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7fXJldHVybiB0fSgpO3QuSGl2ZVNlc3Npb249aTt2YXIgcjshZnVuY3Rpb24odCl7dFt0Lm9oPTBdPVwiR0VORVJJQ19FUlJPUlwiLHRbdC5zaD0xXT1cIk5PX1RFQ0hfQVZBSUxBQkxFXCIsdFt0LmFoPTJdPVwiTk9fVEVDSF9SRVNPTFZFRFwiLHRbdC5oaD0zXT1cIlRFQ0hfRVJST1JcIix0W3QucGg9NF09XCJUSUNLRVRfRVJST1JcIn0ocj10LnVofHwodC51aD17fSkpO3ZhciBuOyFmdW5jdGlvbih0KXt0W3RbXCJsaFwiXT0wXT1cIkdlbmVyaWMgVW5kZWZpbmVkIEVycm9yXCIsdFt0W1wiZGhcIl09MV09XCJObyBUZWNoIGF2YWlsYWJsZSB0byByZXNvbHZlIHRoZSB0aWNrZXRcIix0W3RbXCJmaFwiXT0yXT1cIk5vIGF2YWlsYWJsZSBUZWNoIGNvdWxkIHJlc29sdmVkIHRoZSB0aWNrZXRcIix0W3RbXCJnaFwiXT0zXT1cIlN0b3BwZWQgcmVzb2x2aW5nIHNlc3Npb24gb24gbGFzdCB0ZWNoIG9uRXJyb3JcIix0W3RbXCJ2aFwiXT00XT1cIlRoZSB0aWNrZXQgY291bGQgbm90IGJlIHJlc29sdmVkXCJ9KG58fChuPXt9KSk7dmFyIG89ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7fXJldHVybiB0fSgpO3QuSGl2ZVNlc3Npb25FcnJvcj1vO3ZhciBzPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0LGUpe3RoaXMuY29kZT10LHRoaXMubWVzc2FnZT1lfXJldHVybiB0fSgpO3QuSGl2ZVRlY2hFcnJvcj1zO3ZhciBhOyFmdW5jdGlvbih0KXt0W3QueWg9MF09XCJOT1RfUkVBRFlcIix0W3QubWg9MV09XCJQTFVHSU5fRVJST1JcIix0W3Qud2g9Ml09XCJTRVNTSU9OX0VSUk9SXCIsdFt0LnBoPTNdPVwiVElDS0VUX0VSUk9SXCIsdFt0LlRoPTRdPVwiVkVSU0lPTl9FUlJPUlwiLHRbdC5TaD01XT1cIlRJTUVPVVRfRVJST1JcIn0oYT10LmJofHwodC5iaD17fSkpO3ZhciBjOyFmdW5jdGlvbih0KXt0W3QuRWg9MF09XCJPS1wiLHRbdC5JaD0xXT1cIkhJVkVfTk9UX0FMTE9XRURcIix0W3QuUmg9Ml09XCJUSUNLRVRfTk9UX1JFU09MVkVEXCIsdFt0LmtoPTNdPVwiVElNRU9VVF9SRVNPTFZJTkdfVElDS0VUXCJ9KGM9dC5DaHx8KHQuQ2g9e30pKSx0LmdldEhpdmVTZXNzaW9uRXJyb3JNZXNzYWdlPWU7dmFyIGg9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQpe3RoaXMuT2g9dH1yZXR1cm4gdC5wcm90b3R5cGUuZ2V0UGx1Z2luU3RhdHVzQ29kZT1mdW5jdGlvbigpe3JldHVybiB0aGlzLk9oLlBoKCl9LHR9KCk7dC5BaD1ofShpPWUucHR8fChlLnB0PXt9KSksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvdyYmKFwidW5kZWZpbmVkXCI9PXR5cGVvZiB3aW5kb3cucHQmJih3aW5kb3cucHQ9e30pLHdpbmRvdy5wdC5nZXRIaXZlU2Vzc2lvbkVycm9yTWVzc2FnZT1pLmdldEhpdmVTZXNzaW9uRXJyb3JNZXNzYWdlKX0sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjt2YXIgaT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHR9KCk7aS55cj1cImh0dHBzOlwiPT09bG9jYXRpb24ucHJvdG9jb2wsaS5Fcj0hMCxpLk5oPTFlNCxpLnhoPTZlNCxlLmtlPWl9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcj1pKDQxKSxuPWkoOCksbz1pKDI1KTtpZihcInVuZGVmaW5lZFwiPT10eXBlb2Ygcyl2YXIgcz1cIjU5MjgzNWE2YjQyMDRkZDE5N2MwMDQ4ODYxMDAwM2UwXCI7aWYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIGEpdmFyIGE9XCIwLjhcIjtpZihcInVuZGVmaW5lZFwiPT10eXBlb2YgYyl2YXIgYz0hMDt2YXIgaD1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXtpZih0aGlzLnN0PSExLHQuR2kpdGhyb3cgbmV3IEVycm9yKFwiRXJyb3I6IEluc3RhbnRpYXRpb24gZmFpbGVkOiBVc2UgQXRhdHVzTG9nZ2VyLmdldEluc3RhbmNlKCkgaW5zdGVhZCBvZiBuZXcuXCIpO3ZhciBlLGk9dm9pZCAwIT1uLkhpdmVDb25maWcuRXJyb3JNb25pdG9yLmtleT9uLkhpdmVDb25maWcuRXJyb3JNb25pdG9yLmtleTpzLHI9MT09bi5IaXZlQ29uZmlnLkVycm9yTW9uaXRvci5lbmFibGVkUlVNLGE9MT09bi5IaXZlQ29uZmlnLkVycm9yTW9uaXRvci5lbmFibGVLZXlDb21iaW5hdGlvbixoPTE9PW4uSGl2ZUNvbmZpZy5FcnJvck1vbml0b3IuZW5hYmxlZEVycm9yRmlsdGVyO2gmJihlPXRoaXMuQmgoKSksYXRhdHVzJiYodm9pZCAwPT1uLkhpdmVDb25maWcuRXJyb3JNb25pdG9yLmVuYWJsZWQmJmN8fHZvaWQgMCE9bi5IaXZlQ29uZmlnLkVycm9yTW9uaXRvci5lbmFibGVkJiYxPT1uLkhpdmVDb25maWcuRXJyb3JNb25pdG9yLmVuYWJsZWQpJiYoYXRhdHVzLmNvbmZpZyhpLHtlbmFibGVTb3VyY2VtYXA6ITAsZGlzYWJsZVJVTTohcix2ZXJzaW9uOm8udmVyc2lvbixiZWZvcmVFcnJvclNlbmQ6ZnVuY3Rpb24odCl7dmFyIGk9ITE7aWYodCYmdC5jdXN0b21EYXRhJiZcInVuZGVmaW5lZFwiIT10eXBlb2YgdC5jdXN0b21EYXRhLmZvcmNlU2VuZCYmKGk9dC5jdXN0b21EYXRhLmZvcmNlU2VuZCxkZWxldGUgdC5jdXN0b21EYXRhLmZvcmNlU2VuZCwwPT09T2JqZWN0LmtleXModC5jdXN0b21EYXRhKS5sZW5ndGgmJih0LmN1c3RvbURhdGE9bnVsbCkpLCFofHxpKXJldHVybiEwO2lmKCFlKXJldHVybiExO3RyeXt2YXIgcj0hMTtpZih0LmJhY2tUcmFjZXMpe2Zvcih2YXIgbj0wLG89dC5iYWNrVHJhY2VzO248by5sZW5ndGg7bisrKXt2YXIgcz1vW25dLGE9cy5mLmluZGV4T2YoZSk+LTE7aWYoYSYmcy5sbj41KXtyPSEwO2JyZWFrfX1yJiYodC5uYW1lPXQubmFtZS5yZXBsYWNlKC8lcyBcXFtbMC05XXsyfTpbMC05XXsyfTpbMC05XXsyfTpbMC05XStdIC8sXCJcIiksdC5uYW1lLmluZGV4T2YoXCJTdGF0dXMgQ29kZSBFcnJvcjpcIik+PTAmJih0LnRhZ3M9W1wiUGx1Z2luIEVycm9yIENvZGVcIix0Lm5hbWUuc3BsaXQoXCI6XCIpWzFdLnRyaW0oKV0pKX1yZXR1cm4gcn1jYXRjaChjKXtyZXR1cm4hMX19fSkuaW5zdGFsbCgpLGEmJnRoaXMuRmgoKSx0aGlzLnN0PSEwLHdpbmRvdy5jb25zb2xlJiZjb25zb2xlLmxvZyhcIltIaXZlQ29tbV0gRXJyb3IgTW9uaXRvciBpbnN0YWxsZWQgW1JVTTpcIityK1wiLCBLZXlIYW5kbGVyOlwiK2ErXCJdXCIpLGgmJiFlJiZ0aGlzLl9oKFwiQ291bGQgbm90IGV4dHJhY3QgZXJyb3IgZmlsdGVyXCIpKX1yZXR1cm4gdC5XaT1mdW5jdGlvbigpe3JldHVybiB2b2lkIDA9PT10aGlzLkdpJiYodGhpcy5HaT1uZXcgdCksdGhpcy5HaX0sdC5wcm90b3R5cGUuRmg9ZnVuY3Rpb24oKXtyLkhoLldpKCkuRGgoWzE2LDE3LDg4XSxmdW5jdGlvbigpe3RyeXt0aHJvdyBuZXcgRXJyb3IoXCJVcGxvYWQgY29uc29sZSBsb2dzXCIpfWNhdGNoKHQpe2F0YXR1cy5ub3RpZnkodCksd2luZG93LmNvbnNvbGUmJmNvbnNvbGUubG9nKFwiW0hpdmVDb21tXSBjb25zb2xlIGxvZyB1cGxvYWRlZCBmb3IgZGVidWdnaW5nXCIpfX0pfSx0LnByb3RvdHlwZS5CaD1mdW5jdGlvbigpe3RyeXt0aHJvdyBuZXcgRXJyb3IoXCJ0ZXN0XCIpfWNhdGNoKHQpe3ZhciBlPXQuc3RhY2subWF0Y2goLyhcXC9cXC8uKlxcLmpzKS9pKTtpZihlJiZlLmxlbmd0aD4wKXJldHVybiBlWzBdfX0sdC5wcm90b3R5cGUuc2V0VXNlcj1mdW5jdGlvbih0KXthdGF0dXMmJnRoaXMuc3QmJmF0YXR1cy5zZXRVc2VyKHQpfSx0LnByb3RvdHlwZS5MaD1mdW5jdGlvbih0KXt0aGlzLm09dH0sdC5wcm90b3R5cGUuc2V0Q3VzdG9tRGF0YT1mdW5jdGlvbih0KXthdGF0dXMmJnRoaXMuc3QmJmF0YXR1cy5zZXRDdXN0b21EYXRhKHQpfSx0LnByb3RvdHlwZS5faD1mdW5jdGlvbih0LGUpe2lmKHRoaXMubSYmdGhpcy5tLndhcm4odCksYXRhdHVzJiZ0aGlzLnN0KXRyeXt0aHJvdyBuZXcgRXJyb3IodCl9Y2F0Y2goaSl7ZXx8KGU9e30pLGUuZm9yY2VTZW5kPSEwLGF0YXR1cy5ub3RpZnkoaSxlKX19LHQucHJvdG90eXBlLnNldFRhZ3M9ZnVuY3Rpb24odCl7YXRhdHVzJiZ0aGlzLnN0JiZhdGF0dXMuc2V0VGFncyh0KX0sdC5wcm90b3R5cGUubm90aWZ5PWZ1bmN0aW9uKHQsZSl7YXRhdHVzJiZ0aGlzLnN0JiYoZXx8KGU9e30pLGUuZm9yY2VTZW5kPSEwLGF0YXR1cy5ub3RpZnkodCxlKSl9LHR9KCk7ZS5FcnJvck1vbml0b3I9aH0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPWkoMjEpLG49aSgzNCksbz1uLk1oLHM9bi5qaCxhPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMuU291cmNlVVJMUGFyYW1zPXt9fXJldHVybiB0LnByb3RvdHlwZS5VaD1mdW5jdGlvbih0KXtmb3IodmFyIGUgaW4gdClpZihcIlNvdXJjZVVSTFBhcmFtc1wiPT09ZSlmb3IodmFyIGkgaW4gdFtlXSl0aGlzW2VdW2ldPXRbZV1baV07ZWxzZSB0aGlzW2VdPXRbZV07dGhpcy5WaCgpfSx0LnByb3RvdHlwZS5RaD1mdW5jdGlvbigpe3ZhciB0PVwiYjY2MTRjM2U0Y2QxZDE0ZWVkNmIzOWVmMmJmNmI5YTNlM2Q2ZGZjZDI2Njk5ZDcyNzBkODg3OTIzYmNiZjgzZWZiM2RhZGI3MTdjMGJhZmIxZDQ4ZGNlMzYxZWIzNjliN2NjNDZlNTc0MDVlYmZiZGQ4NmMzMTc1NTMyZmU1NmNjNzdmNDczZDM0NWIyY2I2ZmVhZmI1YWIwZTI0ZjM2NGEzZDI1OWYyN2U0YTJmZDk3NDY4MjY1YmRkZmQzZGRkM2FjNjQyNTFkYjY1MGNhMDI4MGFmMmIyYzQ1ZThiMWM4ZjA0MGYyYzQzM2FjMGExNTdkMmIzZmQ5MTUxNzI1M1wiLGU9XCIwMTAwMDFcIixpPXRoaXMuQ29udGVudElkK3RoaXMuU2l0ZUlkK3RoaXMuQ1JPSWQrdGhpcy5Tb3VyY2VVUkwscj1uZXcgbztyLnFoKHQsZSk7dmFyIG49cyh0aGlzLlNpZ25hdHVyZSk7cmV0dXJuIHIuSmgoaSxuKX0sdC5wcm90b3R5cGUuS2g9ZnVuY3Rpb24odCl7dGhpcy50aWNrZXRVcmw9dDt2YXIgZT1yLnBhcnNlKHQpLGk9ZS5wYXRoLnNwbGl0KFwiL1wiKS5zbGljZSgzKTtpZih0aGlzLlNpdGVJZD1pWzBdLHRoaXMuQ1JPSWQ9aVsxXSx0aGlzLkNvbnRlbnRJZD1pWzJdLHRoaXMuR2g9aVszXSxlLnZpKXRyeXt2YXIgbj1lLnZpLnNwbGl0KFwiJlwiKTtmb3IodmFyIG8gaW4gbil7dmFyIHM9bltvXS5zcGxpdCgvPSguKykvKTt0aGlzLlNvdXJjZVVSTFBhcmFtc1tzWzBdXT1zWzFdfX1jYXRjaChhKXt9dGhpcy56aD10LmluZGV4T2YoXCJhcGktdGVzdFwiKT4tMX0sdC5wcm90b3R5cGUuYm49ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5TaXRlSWR9LHQucHJvdG90eXBlLkVuPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuQ1JPSWR9LHQucHJvdG90eXBlLmVzPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuQ29udGVudElkfSx0LnByb3RvdHlwZS5XaD1mdW5jdGlvbigpe3JldHVybiB0aGlzLkdofSx0LnByb3RvdHlwZS4kaD1mdW5jdGlvbigpe3JldHVybiB0aGlzLlNvdXJjZVVSTH0sdC5wcm90b3R5cGUuWWg9ZnVuY3Rpb24oKXtpZih0aGlzLlhoPXRoaXMuU291cmNlVVJMLHZvaWQgMCE9dGhpcy5Tb3VyY2VVUkxQYXJhbXMpe3ZhciB0PW5ldyBBcnJheTtmb3IodmFyIGUgaW4gdGhpcy5Tb3VyY2VVUkxQYXJhbXMpdC5wdXNoKGUrXCI9XCIrdGhpcy5Tb3VyY2VVUkxQYXJhbXNbZV0pO3QubGVuZ3RoPjAmJnRoaXMuWGgmJih0aGlzLlhoKz0odGhpcy5YaC5pbmRleE9mKFwiP1wiKT4wP1wiJlwiOlwiP1wiKSt0LmpvaW4oXCImXCIpKX19LHQucHJvdG90eXBlLlZoPWZ1bmN0aW9uKCl7dmFyIHQ9aSgyMik7dGhpcy5zZXNzaW9uSWQ9dC5aaCgpfSx0LnByb3RvdHlwZS50cD1mdW5jdGlvbigpe3JldHVybiB0aGlzLlhofHx0aGlzLlloKCksdGhpcy5YaH0sdC5wcm90b3R5cGUuT249ZnVuY3Rpb24oKXtyZXR1cm5cIltcIit0aGlzLlNpdGVJZCtcIi9cIit0aGlzLkNST0lkK1wiL1wiK3RoaXMuQ29udGVudElkK1wiXVwifSx0LnByb3RvdHlwZS5lcD1mdW5jdGlvbigpe3JldHVyblt0aGlzLlNpdGVJZCx0aGlzLkNST0lkLHRoaXMuQ29udGVudElkXX0sdC5wcm90b3R5cGUuaXA9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5Tb3VyY2VVUkwrXCItW1wiK3RoaXMuU2l0ZUlkK1wiL1wiK3RoaXMuQ1JPSWQrXCIvXCIrdGhpcy5Db250ZW50SWQrXCJdXCJ9LHQucHJvdG90eXBlLnRvU3RyaW5nPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuT24oKX0sdH0oKTthLnJwPVwiXmh0dHBzPzovL2FwaSg/Oi10ZXN0KT8uaGl2ZXN0cmVhbWluZy5jb20vdjEvZXZlbnRzLyg/OndpbGRjYXJkLyk/XCIsYS5ucD1cIkNST0lkXCIsYS5vcD1cIlNpdGVJZFwiLGEuc3A9XCJDb250ZW50SWRcIixlLmFwPWF9LGZ1bmN0aW9uKHQsZSxpKXt2YXIgcixuLG87LyohXG4gKiBVUkkuanMgLSBNdXRhdGluZyBVUkxzXG4gKlxuICogVmVyc2lvbjogMS4xOC4xMFxuICpcbiAqIEF1dGhvcjogUm9kbmV5IFJlaG1cbiAqIFdlYjogaHR0cDovL21lZGlhbGl6ZS5naXRodWIuaW8vVVJJLmpzL1xuICpcbiAqIExpY2Vuc2VkIHVuZGVyXG4gKiAgIE1JVCBMaWNlbnNlIGh0dHA6Ly93d3cub3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvbWl0LWxpY2Vuc2VcbiAqXG4gKi9cbiAgIWZ1bmN0aW9uKHMsYSl7XCJ1c2Ugc3RyaWN0XCI7XCJvYmplY3RcIj09dHlwZW9mIHQmJnQudD90LnQ9YShpKDYpLGkoNiksaSg2KSk6KG49W2koNiksaSg2KSxpKDYpXSxyPWEsbz1cImZ1bmN0aW9uXCI9PXR5cGVvZiByP3IuYXBwbHkoZSxuKTpyLCEodm9pZCAwIT09byYmKHQudD1vKSkpfSh0aGlzLGZ1bmN0aW9uKHQsZSxpLHIpe1widXNlIHN0cmljdFwiO2Z1bmN0aW9uIG4odCxlKXt2YXIgaT1hcmd1bWVudHMubGVuZ3RoPj0xLHI9YXJndW1lbnRzLmxlbmd0aD49MjtpZighKHRoaXMgaW5zdGFuY2VvZiBuKSlyZXR1cm4gaT9yP25ldyBuKHQsZSk6bmV3IG4odCk6bmV3IG47aWYodm9pZCAwPT09dCl7aWYoaSl0aHJvdyBuZXcgVHlwZUVycm9yKFwidW5kZWZpbmVkIGlzIG5vdCBhIHZhbGlkIGFyZ3VtZW50IGZvciBVUklcIik7dD1cInVuZGVmaW5lZFwiIT10eXBlb2YgbG9jYXRpb24/bG9jYXRpb24uaHJlZitcIlwiOlwiXCJ9aWYobnVsbD09PXQmJmkpdGhyb3cgbmV3IFR5cGVFcnJvcihcIm51bGwgaXMgbm90IGEgdmFsaWQgYXJndW1lbnQgZm9yIFVSSVwiKTtyZXR1cm4gdGhpcy5ocmVmKHQpLHZvaWQgMCE9PWU/dGhpcy5jcChlKTp0aGlzfWZ1bmN0aW9uIG8odCl7cmV0dXJuIHQucmVwbGFjZSgvKFsuKis/Xj0hOiR7fSgpfFtcXF1cXC9cXFxcXSkvZyxcIlxcXFwkMVwiKX1mdW5jdGlvbiBzKHQpe3JldHVybiB2b2lkIDA9PT10P1wiVW5kZWZpbmVkXCI6U3RyaW5nKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KSkuc2xpY2UoOCwtMSl9ZnVuY3Rpb24gYSh0KXtyZXR1cm5cIkFycmF5XCI9PT1zKHQpfWZ1bmN0aW9uIGModCxlKXt2YXIgaSxyLG49e307aWYoXCJSZWdFeHBcIj09PXMoZSkpbj1udWxsO2Vsc2UgaWYoYShlKSlmb3IoaT0wLHI9ZS5sZW5ndGg7aTxyO2krKyluW2VbaV1dPSEwO2Vsc2UgbltlXT0hMDtmb3IoaT0wLHI9dC5sZW5ndGg7aTxyO2krKyl7dmFyIG89biYmdm9pZCAwIT09blt0W2ldXXx8IW4mJmUudGVzdCh0W2ldKTtvJiYodC5zcGxpY2UoaSwxKSxyLS0saS0tKX1yZXR1cm4gdH1mdW5jdGlvbiBoKHQsZSl7dmFyIGkscjtpZihhKGUpKXtmb3IoaT0wLHI9ZS5sZW5ndGg7aTxyO2krKylpZighaCh0LGVbaV0pKXJldHVybiExO3JldHVybiEwfXZhciBuPXMoZSk7Zm9yKGk9MCxyPXQubGVuZ3RoO2k8cjtpKyspaWYoXCJSZWdFeHBcIj09PW4pe2lmKFwic3RyaW5nXCI9PXR5cGVvZiB0W2ldJiZ0W2ldLm1hdGNoKGUpKXJldHVybiEwfWVsc2UgaWYodFtpXT09PWUpcmV0dXJuITA7cmV0dXJuITF9ZnVuY3Rpb24gcCh0LGUpe2lmKCFhKHQpfHwhYShlKSlyZXR1cm4hMTtpZih0Lmxlbmd0aCE9PWUubGVuZ3RoKXJldHVybiExO3Quc29ydCgpLGUuc29ydCgpO2Zvcih2YXIgaT0wLHI9dC5sZW5ndGg7aTxyO2krKylpZih0W2ldIT09ZVtpXSlyZXR1cm4hMTtyZXR1cm4hMH1mdW5jdGlvbiB1KHQpe3ZhciBlPS9eXFwvK3xcXC8rJC9nO3JldHVybiB0LnJlcGxhY2UoZSxcIlwiKX1mdW5jdGlvbiBsKHQpe3JldHVybiBlc2NhcGUodCl9ZnVuY3Rpb24gZCh0KXtyZXR1cm4gZW5jb2RlVVJJQ29tcG9uZW50KHQpLnJlcGxhY2UoL1shJygpKl0vZyxsKS5yZXBsYWNlKC9cXCovZyxcIiUyQVwiKX1mdW5jdGlvbiBmKHQpe3JldHVybiBmdW5jdGlvbihlLGkpe3JldHVybiB2b2lkIDA9PT1lP3RoaXMuaHBbdF18fFwiXCI6KHRoaXMuaHBbdF09ZXx8bnVsbCx0aGlzLnBwKCFpKSx0aGlzKX19ZnVuY3Rpb24gZyh0LGUpe3JldHVybiBmdW5jdGlvbihpLHIpe3JldHVybiB2b2lkIDA9PT1pP3RoaXMuaHBbdF18fFwiXCI6KG51bGwhPT1pJiYoaSs9XCJcIixpLmNoYXJBdCgwKT09PWUmJihpPWkuc3Vic3RyaW5nKDEpKSksdGhpcy5ocFt0XT1pLHRoaXMucHAoIXIpLHRoaXMpfX12YXIgdj1yJiZyLnVwO24udmVyc2lvbj1cIjEuMTguMTBcIjt2YXIgeT1uLnByb3RvdHlwZSxtPU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7bi5ocD1mdW5jdGlvbigpe3JldHVybntwcm90b2NvbDpudWxsLHVzZXJuYW1lOm51bGwscGFzc3dvcmQ6bnVsbCxob3N0bmFtZTpudWxsLHVybjpudWxsLHBvcnQ6bnVsbCxwYXRoOm51bGwsdmk6bnVsbCxscDpudWxsLGRwOm4uZHAsZnA6bi5mcH19LG4uZHA9ITEsbi5mcD0hMCxuLmdwPS9eW2Etel1bYS16MC05ListXSokL2ksbi52cD0vW15hLXowLTlcXC4tXS9pLG4ueXA9Lyh4bi0tKS9pLG4ubXA9L15cXGR7MSwzfVxcLlxcZHsxLDN9XFwuXFxkezEsM31cXC5cXGR7MSwzfSQvLG4ud3A9L15cXHMqKCgoWzAtOUEtRmEtZl17MSw0fTopezd9KFswLTlBLUZhLWZdezEsNH18OikpfCgoWzAtOUEtRmEtZl17MSw0fTopezZ9KDpbMC05QS1GYS1mXXsxLDR9fCgoMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKFxcLigyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkpezN9KXw6KSl8KChbMC05QS1GYS1mXXsxLDR9Oil7NX0oKCg6WzAtOUEtRmEtZl17MSw0fSl7MSwyfSl8OigoMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKFxcLigyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkpezN9KXw6KSl8KChbMC05QS1GYS1mXXsxLDR9Oil7NH0oKCg6WzAtOUEtRmEtZl17MSw0fSl7MSwzfSl8KCg6WzAtOUEtRmEtZl17MSw0fSk/OigoMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKFxcLigyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkpezN9KSl8OikpfCgoWzAtOUEtRmEtZl17MSw0fTopezN9KCgoOlswLTlBLUZhLWZdezEsNH0pezEsNH0pfCgoOlswLTlBLUZhLWZdezEsNH0pezAsMn06KCgyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkoXFwuKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKSl7M30pKXw6KSl8KChbMC05QS1GYS1mXXsxLDR9Oil7Mn0oKCg6WzAtOUEtRmEtZl17MSw0fSl7MSw1fSl8KCg6WzAtOUEtRmEtZl17MSw0fSl7MCwzfTooKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKShcXC4oMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKXszfSkpfDopKXwoKFswLTlBLUZhLWZdezEsNH06KXsxfSgoKDpbMC05QS1GYS1mXXsxLDR9KXsxLDZ9KXwoKDpbMC05QS1GYS1mXXsxLDR9KXswLDR9OigoMjVbMC01XXwyWzAtNF1cXGR8MVxcZFxcZHxbMS05XT9cXGQpKFxcLigyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkpezN9KSl8OikpfCg6KCgoOlswLTlBLUZhLWZdezEsNH0pezEsN30pfCgoOlswLTlBLUZhLWZdezEsNH0pezAsNX06KCgyNVswLTVdfDJbMC00XVxcZHwxXFxkXFxkfFsxLTldP1xcZCkoXFwuKDI1WzAtNV18MlswLTRdXFxkfDFcXGRcXGR8WzEtOV0/XFxkKSl7M30pKXw6KSkpKCUuKyk/XFxzKiQvLG4uVHA9L1xcYigoPzpbYS16XVtcXHctXSs6KD86XFwvezEsM318W2EtejAtOSVdKXx3d3dcXGR7MCwzfVsuXXxbYS16MC05LlxcLV0rWy5dW2Etel17Miw0fVxcLykoPzpbXlxccygpPD5dK3xcXCgoW15cXHMoKTw+XSt8KFxcKFteXFxzKCk8Pl0rXFwpKSkqXFwpKSsoPzpcXCgoW15cXHMoKTw+XSt8KFxcKFteXFxzKCk8Pl0rXFwpKSkqXFwpfFteXFxzYCEoKVxcW1xcXXt9OzonXCIuLDw+P8KrwrvigJzigJ3igJjigJldKSkvZ2ksbi5TcD17c3RhcnQ6L1xcYig/OihbYS16XVthLXowLTkuKy1dKjpcXC9cXC8pfHd3d1xcLikvZ2ksZW5kOi9bXFxzXFxyXFxuXXwkLyx0cmltOi9bYCEoKVxcW1xcXXt9OzonXCIuLDw+P8KrwrvigJzigJ3igJ7igJjigJldKyQvLGJwOi8oXFwoW15cXCldKlxcKXxcXFtbXlxcXV0qXFxdfFxce1tefV0qXFx9fDxbXj5dKj4pL2d9LG4uRXA9e0lwOlwiODBcIixScDpcIjQ0M1wiLGtwOlwiMjFcIixDcDpcIjcwXCIsT3A6XCI4MFwiLFBwOlwiNDQzXCJ9LG4uQXA9L1teYS16QS1aMC05XFwuLV0vLG4uTnA9e2E6XCJocmVmXCIseHA6XCJjaXRlXCIsbGluazpcImhyZWZcIixCcDpcImhyZWZcIixGcDpcInNyY1wiLGZvcm06XCJhY3Rpb25cIixfcDpcInNyY1wiLERwOlwiaHJlZlwiLEhwOlwic3JjXCIsTHA6XCJzcmNcIixzb3VyY2U6XCJzcmNcIix0cmFjazpcInNyY1wiLGlucHV0Olwic3JjXCIsTXA6XCJzcmNcIix2aWRlbzpcInNyY1wifSxuLmpwPWZ1bmN0aW9uKHQpe2lmKHQmJnQubm9kZU5hbWUpe3ZhciBlPXQubm9kZU5hbWUudG9Mb3dlckNhc2UoKTtpZihcImlucHV0XCIhPT1lfHxcImltYWdlXCI9PT10LnR5cGUpcmV0dXJuIG4uTnBbZV19fSxuLmVuY29kZT1kLG4uZGVjb2RlPWRlY29kZVVSSUNvbXBvbmVudCxuLlVwPWZ1bmN0aW9uKCl7bi5lbmNvZGU9ZXNjYXBlLG4uZGVjb2RlPXVuZXNjYXBlfSxuLlZwPWZ1bmN0aW9uKCl7bi5lbmNvZGU9ZCxuLmRlY29kZT1kZWNvZGVVUklDb21wb25lbnR9LG4uUXA9e3BhdGhuYW1lOntlbmNvZGU6e3FwOi8lKDI0fDI2fDJCfDJDfDNCfDNEfDNBfDQwKS9naSxtYXA6e1wiJTI0XCI6XCIkXCIsXCIlMjZcIjpcIiZcIixcIiUyQlwiOlwiK1wiLFwiJTJDXCI6XCIsXCIsXCIlM0JcIjpcIjtcIixcIiUzRFwiOlwiPVwiLFwiJTNBXCI6XCI6XCIsXCIlNDBcIjpcIkBcIn19LGRlY29kZTp7cXA6L1tcXC9cXD8jXS9nLG1hcDp7SnA6XCIlMkZcIixLcDpcIiUzRlwiLEdwOlwiJTIzXCJ9fX0senA6e2VuY29kZTp7cXA6LyUoMjF8MjN8MjR8MjZ8Mjd8Mjh8Mjl8MkF8MkJ8MkN8MkZ8M0F8M0J8M0R8M0Z8NDB8NUJ8NUQpL2dpLG1hcDp7XCIlM0FcIjpcIjpcIixXcDpcIi9cIiwkcDpcIj9cIixZcDpcIiNcIixYcDpcIltcIixacDpcIl1cIixcIiU0MFwiOlwiQFwiLHR1OlwiIVwiLFwiJTI0XCI6XCIkXCIsXCIlMjZcIjpcIiZcIixldTpcIidcIixpdTpcIihcIixydTpcIilcIixudTpcIipcIixcIiUyQlwiOlwiK1wiLFwiJTJDXCI6XCIsXCIsXCIlM0JcIjpcIjtcIixcIiUzRFwiOlwiPVwifX19LG91OntlbmNvZGU6e3FwOi8lKDIxfDI0fDI3fDI4fDI5fDJBfDJCfDJDfDNCfDNEfDQwKS9naSxtYXA6e3R1OlwiIVwiLFwiJTI0XCI6XCIkXCIsZXU6XCInXCIsaXU6XCIoXCIscnU6XCIpXCIsbnU6XCIqXCIsXCIlMkJcIjpcIitcIixcIiUyQ1wiOlwiLFwiLFwiJTNCXCI6XCI7XCIsXCIlM0RcIjpcIj1cIixcIiU0MFwiOlwiQFwifX0sZGVjb2RlOntxcDovW1xcL1xcPyM6XS9nLG1hcDp7SnA6XCIlMkZcIixLcDpcIiUzRlwiLEdwOlwiJTIzXCIsc3U6XCIlM0FcIn19fX0sbi5hdT1mdW5jdGlvbih0LGUpe3ZhciBpPW4uZW5jb2RlKHQrXCJcIik7cmV0dXJuIHZvaWQgMD09PWUmJihlPW4uZnApLGU/aS5yZXBsYWNlKC8lMjAvZyxcIitcIik6aX0sbi5jdT1mdW5jdGlvbih0LGUpe3QrPVwiXCIsdm9pZCAwPT09ZSYmKGU9bi5mcCk7dHJ5e3JldHVybiBuLmRlY29kZShlP3QucmVwbGFjZSgvXFwrL2csXCIlMjBcIik6dCl9Y2F0Y2goaSl7cmV0dXJuIHR9fTt2YXIgdyxUPXtlbmNvZGU6XCJlbmNvZGVcIixkZWNvZGU6XCJkZWNvZGVcIn0sUz1mdW5jdGlvbih0LGUpe3JldHVybiBmdW5jdGlvbihpKXt0cnl7cmV0dXJuIG5bZV0oaStcIlwiKS5yZXBsYWNlKG4uUXBbdF1bZV0ucXAsZnVuY3Rpb24oaSl7cmV0dXJuIG4uUXBbdF1bZV0ubWFwW2ldfSl9Y2F0Y2gocil7cmV0dXJuIGl9fX07Zm9yKHcgaW4gVCluW3crXCJQYXRoU2VnbWVudFwiXT1TKFwicGF0aG5hbWVcIixUW3ddKSxuW3crXCJVcm5QYXRoU2VnbWVudFwiXT1TKFwidXJucGF0aFwiLFRbd10pO3ZhciBiPWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gZnVuY3Rpb24ocil7dmFyIG87bz1pP2Z1bmN0aW9uKHQpe3JldHVybiBuW2VdKG5baV0odCkpfTpuW2VdO2Zvcih2YXIgcz0ocitcIlwiKS5zcGxpdCh0KSxhPTAsYz1zLmxlbmd0aDthPGM7YSsrKXNbYV09byhzW2FdKTtyZXR1cm4gcy5qb2luKHQpfX07bi5odT1iKFwiL1wiLFwiZGVjb2RlUGF0aFNlZ21lbnRcIiksbi5wdT1iKFwiOlwiLFwiZGVjb2RlVXJuUGF0aFNlZ21lbnRcIiksbi51dT1iKFwiL1wiLFwiZW5jb2RlUGF0aFNlZ21lbnRcIixcImRlY29kZVwiKSxuLmx1PWIoXCI6XCIsXCJlbmNvZGVVcm5QYXRoU2VnbWVudFwiLFwiZGVjb2RlXCIpLG4uZHU9UyhcInJlc2VydmVkXCIsXCJlbmNvZGVcIiksbi5wYXJzZT1mdW5jdGlvbih0LGUpe3ZhciBpO3JldHVybiBlfHwoZT17fSksaT10LmluZGV4T2YoXCIjXCIpLGk+LTEmJihlLmxwPXQuc3Vic3RyaW5nKGkrMSl8fG51bGwsdD10LnN1YnN0cmluZygwLGkpKSxpPXQuaW5kZXhPZihcIj9cIiksaT4tMSYmKGUudmk9dC5zdWJzdHJpbmcoaSsxKXx8bnVsbCx0PXQuc3Vic3RyaW5nKDAsaSkpLFwiLy9cIj09PXQuc3Vic3RyaW5nKDAsMik/KGUucHJvdG9jb2w9bnVsbCx0PXQuc3Vic3RyaW5nKDIpLHQ9bi5mdSh0LGUpKTooaT10LmluZGV4T2YoXCI6XCIpLGk+LTEmJihlLnByb3RvY29sPXQuc3Vic3RyaW5nKDAsaSl8fG51bGwsZS5wcm90b2NvbCYmIWUucHJvdG9jb2wubWF0Y2gobi5ncCk/ZS5wcm90b2NvbD12b2lkIDA6XCIvL1wiPT09dC5zdWJzdHJpbmcoaSsxLGkrMyk/KHQ9dC5zdWJzdHJpbmcoaSszKSx0PW4uZnUodCxlKSk6KHQ9dC5zdWJzdHJpbmcoaSsxKSxlLnVybj0hMCkpKSxlLnBhdGg9dCxlfSxuLmd1PWZ1bmN0aW9uKHQsZSl7dD10LnJlcGxhY2UoL1xcXFwvZyxcIi9cIik7dmFyIGkscixuPXQuaW5kZXhPZihcIi9cIik7aWYobj09PS0xJiYobj10Lmxlbmd0aCksXCJbXCI9PT10LmNoYXJBdCgwKSlpPXQuaW5kZXhPZihcIl1cIiksZS5ob3N0bmFtZT10LnN1YnN0cmluZygxLGkpfHxudWxsLGUucG9ydD10LnN1YnN0cmluZyhpKzIsbil8fG51bGwsXCIvXCI9PT1lLnBvcnQmJihlLnBvcnQ9bnVsbCk7ZWxzZXt2YXIgbz10LmluZGV4T2YoXCI6XCIpLHM9dC5pbmRleE9mKFwiL1wiKSxhPXQuaW5kZXhPZihcIjpcIixvKzEpO2EhPT0tMSYmKHM9PT0tMXx8YTxzKT8oZS5ob3N0bmFtZT10LnN1YnN0cmluZygwLG4pfHxudWxsLGUucG9ydD1udWxsKToocj10LnN1YnN0cmluZygwLG4pLnNwbGl0KFwiOlwiKSxlLmhvc3RuYW1lPXJbMF18fG51bGwsZS5wb3J0PXJbMV18fG51bGwpfXJldHVybiBlLmhvc3RuYW1lJiZcIi9cIiE9PXQuc3Vic3RyaW5nKG4pLmNoYXJBdCgwKSYmKG4rKyx0PVwiL1wiK3QpLHQuc3Vic3RyaW5nKG4pfHxcIi9cIn0sbi5mdT1mdW5jdGlvbih0LGUpe3JldHVybiB0PW4udnUodCxlKSxuLmd1KHQsZSl9LG4udnU9ZnVuY3Rpb24odCxlKXt2YXIgaSxyPXQuaW5kZXhPZihcIi9cIiksbz10Lmxhc3RJbmRleE9mKFwiQFwiLHI+LTE/cjp0Lmxlbmd0aC0xKTtyZXR1cm4gbz4tMSYmKHI9PT0tMXx8bzxyKT8oaT10LnN1YnN0cmluZygwLG8pLnNwbGl0KFwiOlwiKSxlLnVzZXJuYW1lPWlbMF0/bi5kZWNvZGUoaVswXSk6bnVsbCxpLnNoaWZ0KCksZS5wYXNzd29yZD1pWzBdP24uZGVjb2RlKGkuam9pbihcIjpcIikpOm51bGwsdD10LnN1YnN0cmluZyhvKzEpKTooZS51c2VybmFtZT1udWxsLGUucGFzc3dvcmQ9bnVsbCksdH0sbi55dT1mdW5jdGlvbih0LGUpe2lmKCF0KXJldHVybnt9O2lmKHQ9dC5yZXBsYWNlKC8mKy9nLFwiJlwiKS5yZXBsYWNlKC9eXFw/KiYqfCYrJC9nLFwiXCIpLCF0KXJldHVybnt9O2Zvcih2YXIgaSxyLG8scz17fSxhPXQuc3BsaXQoXCImXCIpLGM9YS5sZW5ndGgsaD0wO2g8YztoKyspaT1hW2hdLnNwbGl0KFwiPVwiKSxyPW4uY3UoaS5zaGlmdCgpLGUpLG89aS5sZW5ndGg/bi5jdShpLmpvaW4oXCI9XCIpLGUpOm51bGwsbS5jYWxsKHMscik/KFwic3RyaW5nXCIhPXR5cGVvZiBzW3JdJiZudWxsIT09c1tyXXx8KHNbcl09W3Nbcl1dKSxzW3JdLnB1c2gobykpOnNbcl09bztyZXR1cm4gc30sbi5wcD1mdW5jdGlvbih0KXt2YXIgZT1cIlwiO3JldHVybiB0LnByb3RvY29sJiYoZSs9dC5wcm90b2NvbCtcIjpcIiksdC51cm58fCFlJiYhdC5ob3N0bmFtZXx8KGUrPVwiLy9cIiksZSs9bi5tdSh0KXx8XCJcIixcInN0cmluZ1wiPT10eXBlb2YgdC5wYXRoJiYoXCIvXCIhPT10LnBhdGguY2hhckF0KDApJiZcInN0cmluZ1wiPT10eXBlb2YgdC5ob3N0bmFtZSYmKGUrPVwiL1wiKSxlKz10LnBhdGgpLFwic3RyaW5nXCI9PXR5cGVvZiB0LnZpJiZ0LnZpJiYoZSs9XCI/XCIrdC52aSksXCJzdHJpbmdcIj09dHlwZW9mIHQubHAmJnQubHAmJihlKz1cIiNcIit0LmxwKSxlfSxuLnd1PWZ1bmN0aW9uKHQpe3ZhciBlPVwiXCI7cmV0dXJuIHQuaG9zdG5hbWU/KGUrPW4ud3AudGVzdCh0Lmhvc3RuYW1lKT9cIltcIit0Lmhvc3RuYW1lK1wiXVwiOnQuaG9zdG5hbWUsdC5wb3J0JiYoZSs9XCI6XCIrdC5wb3J0KSxlKTpcIlwifSxuLm11PWZ1bmN0aW9uKHQpe3JldHVybiBuLlR1KHQpK24ud3UodCl9LG4uVHU9ZnVuY3Rpb24odCl7dmFyIGU9XCJcIjtyZXR1cm4gdC51c2VybmFtZSYmKGUrPW4uZW5jb2RlKHQudXNlcm5hbWUpKSx0LnBhc3N3b3JkJiYoZSs9XCI6XCIrbi5lbmNvZGUodC5wYXNzd29yZCkpLGUmJihlKz1cIkBcIiksZX0sbi5TdT1mdW5jdGlvbih0LGUsaSl7dmFyIHIsbyxzLGMsaD1cIlwiO2ZvcihvIGluIHQpaWYobS5jYWxsKHQsbykmJm8paWYoYSh0W29dKSlmb3Iocj17fSxzPTAsYz10W29dLmxlbmd0aDtzPGM7cysrKXZvaWQgMCE9PXRbb11bc10mJnZvaWQgMD09PXJbdFtvXVtzXStcIlwiXSYmKGgrPVwiJlwiK24uYnUobyx0W29dW3NdLGkpLGUhPT0hMCYmKHJbdFtvXVtzXStcIlwiXT0hMCkpO2Vsc2Ugdm9pZCAwIT09dFtvXSYmKGgrPVwiJlwiK24uYnUobyx0W29dLGkpKTtyZXR1cm4gaC5zdWJzdHJpbmcoMSl9LG4uYnU9ZnVuY3Rpb24odCxlLGkpe3JldHVybiBuLmF1KHQsaSkrKG51bGwhPT1lP1wiPVwiK24uYXUoZSxpKTpcIlwiKX0sbi5FdT1mdW5jdGlvbih0LGUsaSl7aWYoXCJvYmplY3RcIj09dHlwZW9mIGUpZm9yKHZhciByIGluIGUpbS5jYWxsKGUscikmJm4uRXUodCxyLGVbcl0pO2Vsc2V7aWYoXCJzdHJpbmdcIiE9dHlwZW9mIGUpdGhyb3cgbmV3IFR5cGVFcnJvcihcIlVSSS5hZGRRdWVyeSgpIGFjY2VwdHMgYW4gb2JqZWN0LCBzdHJpbmcgYXMgdGhlIG5hbWUgcGFyYW1ldGVyXCIpO2lmKHZvaWQgMD09PXRbZV0pcmV0dXJuIHZvaWQodFtlXT1pKTtcInN0cmluZ1wiPT10eXBlb2YgdFtlXSYmKHRbZV09W3RbZV1dKSxhKGkpfHwoaT1baV0pLHRbZV09KHRbZV18fFtdKS5jb25jYXQoaSl9fSxuLkl1PWZ1bmN0aW9uKHQsZSxpKXt2YXIgcixvLGg7aWYoYShlKSlmb3Iocj0wLG89ZS5sZW5ndGg7cjxvO3IrKyl0W2Vbcl1dPXZvaWQgMDtlbHNlIGlmKFwiUmVnRXhwXCI9PT1zKGUpKWZvcihoIGluIHQpZS50ZXN0KGgpJiYodFtoXT12b2lkIDApO2Vsc2UgaWYoXCJvYmplY3RcIj09dHlwZW9mIGUpZm9yKGggaW4gZSltLmNhbGwoZSxoKSYmbi5JdSh0LGgsZVtoXSk7ZWxzZXtpZihcInN0cmluZ1wiIT10eXBlb2YgZSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiVVJJLnJlbW92ZVF1ZXJ5KCkgYWNjZXB0cyBhbiBvYmplY3QsIHN0cmluZywgUmVnRXhwIGFzIHRoZSBmaXJzdCBwYXJhbWV0ZXJcIik7dm9pZCAwIT09aT9cIlJlZ0V4cFwiPT09cyhpKT8hYSh0W2VdKSYmaS50ZXN0KHRbZV0pP3RbZV09dm9pZCAwOnRbZV09Yyh0W2VdLGkpOnRbZV0hPT1TdHJpbmcoaSl8fGEoaSkmJjEhPT1pLmxlbmd0aD9hKHRbZV0pJiYodFtlXT1jKHRbZV0saSkpOnRbZV09dm9pZCAwOnRbZV09dm9pZCAwfX0sbi5SdT1mdW5jdGlvbih0LGUsaSxyKXtzd2l0Y2gocyhlKSl7Y2FzZVwiU3RyaW5nXCI6YnJlYWs7Y2FzZVwiUmVnRXhwXCI6Zm9yKHZhciBvIGluIHQpaWYobS5jYWxsKHQsbykmJmUudGVzdChvKSYmKHZvaWQgMD09PWl8fG4uUnUodCxvLGkpKSlyZXR1cm4hMDtyZXR1cm4hMTtjYXNlXCJPYmplY3RcIjpmb3IodmFyIGMgaW4gZSlpZihtLmNhbGwoZSxjKSYmIW4uUnUodCxjLGVbY10pKXJldHVybiExO3JldHVybiEwO2RlZmF1bHQ6dGhyb3cgbmV3IFR5cGVFcnJvcihcIlVSSS5oYXNRdWVyeSgpIGFjY2VwdHMgYSBzdHJpbmcsIHJlZ3VsYXIgZXhwcmVzc2lvbiBvciBvYmplY3QgYXMgdGhlIG5hbWUgcGFyYW1ldGVyXCIpfXN3aXRjaChzKGkpKXtjYXNlXCJVbmRlZmluZWRcIjpyZXR1cm4gZSBpbiB0O2Nhc2VcIkJvb2xlYW5cIjp2YXIgdT1Cb29sZWFuKGEodFtlXSk/dFtlXS5sZW5ndGg6dFtlXSk7cmV0dXJuIGk9PT11O2Nhc2VcIkZ1bmN0aW9uXCI6cmV0dXJuISFpKHRbZV0sZSx0KTtjYXNlXCJBcnJheVwiOmlmKCFhKHRbZV0pKXJldHVybiExO3ZhciBsPXI/aDpwO3JldHVybiBsKHRbZV0saSk7Y2FzZVwiUmVnRXhwXCI6cmV0dXJuIGEodFtlXSk/ISFyJiZoKHRbZV0saSk6Qm9vbGVhbih0W2VdJiZ0W2VdLm1hdGNoKGkpKTtjYXNlXCJOdW1iZXJcIjppPVN0cmluZyhpKTtjYXNlXCJTdHJpbmdcIjpyZXR1cm4gYSh0W2VdKT8hIXImJmgodFtlXSxpKTp0W2VdPT09aTtkZWZhdWx0OnRocm93IG5ldyBUeXBlRXJyb3IoXCJVUkkuaGFzUXVlcnkoKSBhY2NlcHRzIHVuZGVmaW5lZCwgYm9vbGVhbiwgc3RyaW5nLCBudW1iZXIsIFJlZ0V4cCwgRnVuY3Rpb24gYXMgdGhlIHZhbHVlIHBhcmFtZXRlclwiKX19LG4ua3U9ZnVuY3Rpb24oKXtmb3IodmFyIHQ9W10sZT1bXSxpPTAscj0wO3I8YXJndW1lbnRzLmxlbmd0aDtyKyspe3ZhciBvPW5ldyBuKGFyZ3VtZW50c1tyXSk7dC5wdXNoKG8pO2Zvcih2YXIgcz1vLkN1KCksYT0wO2E8cy5sZW5ndGg7YSsrKVwic3RyaW5nXCI9PXR5cGVvZiBzW2FdJiZlLnB1c2goc1thXSksc1thXSYmaSsrfWlmKCFlLmxlbmd0aHx8IWkpcmV0dXJuIG5ldyBuKFwiXCIpO3ZhciBjPW5ldyBuKFwiXCIpLkN1KGUpO3JldHVyblwiXCIhPT10WzBdLnBhdGgoKSYmXCIvXCIhPT10WzBdLnBhdGgoKS5zbGljZSgwLDEpfHxjLnBhdGgoXCIvXCIrYy5wYXRoKCkpLGMubm9ybWFsaXplKCl9LG4uT3U9ZnVuY3Rpb24odCxlKXt2YXIgaSxyPU1hdGgubWluKHQubGVuZ3RoLGUubGVuZ3RoKTtmb3IoaT0wO2k8cjtpKyspaWYodC5jaGFyQXQoaSkhPT1lLmNoYXJBdChpKSl7aS0tO2JyZWFrfXJldHVybiBpPDE/dC5jaGFyQXQoMCk9PT1lLmNoYXJBdCgwKSYmXCIvXCI9PT10LmNoYXJBdCgwKT9cIi9cIjpcIlwiOihcIi9cIj09PXQuY2hhckF0KGkpJiZcIi9cIj09PWUuY2hhckF0KGkpfHwoaT10LnN1YnN0cmluZygwLGkpLmxhc3RJbmRleE9mKFwiL1wiKSksdC5zdWJzdHJpbmcoMCxpKzEpKX0sbi5QdT1mdW5jdGlvbih0LGUsaSl7aXx8KGk9e30pO3ZhciByPWkuc3RhcnR8fG4uU3Auc3RhcnQsbz1pLmVuZHx8bi5TcC5lbmQscz1pLnRyaW18fG4uU3AudHJpbSxhPWkuYnB8fG4uU3AuYnAsYz0vW2EtejAtOS1dPVtcIiddPyQvaTtmb3Ioci5sYXN0SW5kZXg9MDs7KXt2YXIgaD1yLmV4ZWModCk7aWYoIWgpYnJlYWs7dmFyIHA9aC5pbmRleDtpZihpLmlnbm9yZUh0bWwpe3ZhciB1PXQuc2xpY2UoTWF0aC5tYXgocC0zLDApLHApO2lmKHUmJmMudGVzdCh1KSljb250aW51ZX1mb3IodmFyIGw9cCt0LnNsaWNlKHApLnNlYXJjaChvKSxkPXQuc2xpY2UocCxsKSxmPS0xOzspe3ZhciBnPWEuZXhlYyhkKTtpZighZylicmVhazt2YXIgdj1nLmluZGV4K2dbMF0ubGVuZ3RoO2Y9TWF0aC5tYXgoZix2KX1pZihkPWY+LTE/ZC5zbGljZSgwLGYpK2Quc2xpY2UoZikucmVwbGFjZShzLFwiXCIpOmQucmVwbGFjZShzLFwiXCIpLCEoZC5sZW5ndGg8PWhbMF0ubGVuZ3RofHxpLmlnbm9yZSYmaS5pZ25vcmUudGVzdChkKSkpe2w9cCtkLmxlbmd0aDt2YXIgeT1lKGQscCxsLHQpO3ZvaWQgMCE9PXk/KHk9U3RyaW5nKHkpLHQ9dC5zbGljZSgwLHApK3krdC5zbGljZShsKSxyLmxhc3RJbmRleD1wK3kubGVuZ3RoKTpyLmxhc3RJbmRleD1sfX1yZXR1cm4gci5sYXN0SW5kZXg9MCx0fSxuLkF1PWZ1bmN0aW9uKGUpe2lmKGUubWF0Y2gobi5BcCkpe2lmKCF0KXRocm93IG5ldyBUeXBlRXJyb3IoJ0hvc3RuYW1lIFwiJytlKydcIiBjb250YWlucyBjaGFyYWN0ZXJzIG90aGVyIHRoYW4gW0EtWjAtOS4tXSBhbmQgUHVueWNvZGUuanMgaXMgbm90IGF2YWlsYWJsZScpO2lmKHQudG9BU0NJSShlKS5tYXRjaChuLkFwKSl0aHJvdyBuZXcgVHlwZUVycm9yKCdIb3N0bmFtZSBcIicrZSsnXCIgY29udGFpbnMgY2hhcmFjdGVycyBvdGhlciB0aGFuIFtBLVowLTkuLV0nKX19LG4uZ2U9ZnVuY3Rpb24odCl7aWYodCl7dmFyIGU9e3VwOnRoaXMuZ2UoKX07cmV0dXJuIHIuTnUmJlwiZnVuY3Rpb25cIj09dHlwZW9mIHIuTnUuZ2UmJihlLk51PXIuTnUuZ2UoKSksci54dSYmXCJmdW5jdGlvblwiPT10eXBlb2Ygci54dS5nZSYmKGUueHU9ci54dS5nZSgpKSxyLkJ1JiZcImZ1bmN0aW9uXCI9PXR5cGVvZiByLkJ1LmdlJiYoZS5CdT1yLkJ1LmdlKCkpLGV9cmV0dXJuIHIudXA9PT10aGlzJiYoci51cD12KSx0aGlzfSx5LnBwPWZ1bmN0aW9uKHQpe3JldHVybiB0PT09ITA/dGhpcy5GdT0hMDoodm9pZCAwPT09dHx8dGhpcy5GdSkmJih0aGlzLl91PW4ucHAodGhpcy5ocCksdGhpcy5GdT0hMSksdGhpc30seS5jbG9uZT1mdW5jdGlvbigpe3JldHVybiBuZXcgbih0aGlzKX0seS52YWx1ZU9mPXkudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5wcCghMSkuX3V9LHkucHJvdG9jb2w9ZihcInByb3RvY29sXCIpLHkudXNlcm5hbWU9ZihcInVzZXJuYW1lXCIpLHkucGFzc3dvcmQ9ZihcInBhc3N3b3JkXCIpLHkuaG9zdG5hbWU9ZihcImhvc3RuYW1lXCIpLHkucG9ydD1mKFwicG9ydFwiKSx5LnZpPWcoXCJxdWVyeVwiLFwiP1wiKSx5LmxwPWcoXCJmcmFnbWVudFwiLFwiI1wiKSx5LnNlYXJjaD1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMudmkodCxlKTtyZXR1cm5cInN0cmluZ1wiPT10eXBlb2YgaSYmaS5sZW5ndGg/XCI/XCIraTppfSx5Lmhhc2g9ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzLmxwKHQsZSk7cmV0dXJuXCJzdHJpbmdcIj09dHlwZW9mIGkmJmkubGVuZ3RoP1wiI1wiK2k6aX0seS5wYXRobmFtZT1mdW5jdGlvbih0LGUpe2lmKHZvaWQgMD09PXR8fHQ9PT0hMCl7dmFyIGk9dGhpcy5ocC5wYXRofHwodGhpcy5ocC5ob3N0bmFtZT9cIi9cIjpcIlwiKTtyZXR1cm4gdD8odGhpcy5ocC51cm4/bi5wdTpuLmh1KShpKTppfXJldHVybiB0aGlzLmhwLnVybj90aGlzLmhwLnBhdGg9dD9uLmx1KHQpOlwiXCI6dGhpcy5ocC5wYXRoPXQ/bi51dSh0KTpcIi9cIix0aGlzLnBwKCFlKSx0aGlzfSx5LnBhdGg9eS5wYXRobmFtZSx5LmhyZWY9ZnVuY3Rpb24odCxlKXt2YXIgaTtpZih2b2lkIDA9PT10KXJldHVybiB0aGlzLnRvU3RyaW5nKCk7dGhpcy5fdT1cIlwiLHRoaXMuaHA9bi5ocCgpO3ZhciByPXQgaW5zdGFuY2VvZiBuLG89XCJvYmplY3RcIj09dHlwZW9mIHQmJih0Lmhvc3RuYW1lfHx0LnBhdGh8fHQucGF0aG5hbWUpO2lmKHQubm9kZU5hbWUpe3ZhciBzPW4uanAodCk7dD10W3NdfHxcIlwiLG89ITF9aWYoIXImJm8mJnZvaWQgMCE9PXQucGF0aG5hbWUmJih0PXQudG9TdHJpbmcoKSksXCJzdHJpbmdcIj09dHlwZW9mIHR8fHQgaW5zdGFuY2VvZiBTdHJpbmcpdGhpcy5ocD1uLnBhcnNlKFN0cmluZyh0KSx0aGlzLmhwKTtlbHNle2lmKCFyJiYhbyl0aHJvdyBuZXcgVHlwZUVycm9yKFwiaW52YWxpZCBpbnB1dFwiKTt2YXIgYT1yP3QuaHA6dDtmb3IoaSBpbiBhKW0uY2FsbCh0aGlzLmhwLGkpJiYodGhpcy5ocFtpXT1hW2ldKX1yZXR1cm4gdGhpcy5wcCghZSksdGhpc30seS5pcz1mdW5jdGlvbih0KXt2YXIgZT0hMSxyPSExLG89ITEscz0hMSxhPSExLGM9ITEsaD0hMSxwPSF0aGlzLmhwLnVybjtzd2l0Y2godGhpcy5ocC5ob3N0bmFtZSYmKHA9ITEscj1uLm1wLnRlc3QodGhpcy5ocC5ob3N0bmFtZSksbz1uLndwLnRlc3QodGhpcy5ocC5ob3N0bmFtZSksZT1yfHxvLHM9IWUsYT1zJiZpJiZpLmhhcyh0aGlzLmhwLmhvc3RuYW1lKSxjPXMmJm4udnAudGVzdCh0aGlzLmhwLmhvc3RuYW1lKSxoPXMmJm4ueXAudGVzdCh0aGlzLmhwLmhvc3RuYW1lKSksdC50b0xvd2VyQ2FzZSgpKXtjYXNlXCJyZWxhdGl2ZVwiOnJldHVybiBwO2Nhc2VcImFic29sdXRlXCI6cmV0dXJuIXA7Y2FzZVwiZG9tYWluXCI6Y2FzZVwibmFtZVwiOnJldHVybiBzO2Nhc2VcInNsZFwiOnJldHVybiBhO2Nhc2VcImlwXCI6cmV0dXJuIGU7Y2FzZVwiaXA0XCI6Y2FzZVwiaXB2NFwiOmNhc2VcImluZXQ0XCI6cmV0dXJuIHI7Y2FzZVwiaXA2XCI6Y2FzZVwiaXB2NlwiOmNhc2VcImluZXQ2XCI6cmV0dXJuIG87Y2FzZVwiaWRuXCI6cmV0dXJuIGM7Y2FzZVwidXJsXCI6cmV0dXJuIXRoaXMuaHAudXJuO2Nhc2VcInVyblwiOnJldHVybiEhdGhpcy5ocC51cm47Y2FzZVwicHVueWNvZGVcIjpyZXR1cm4gaH1yZXR1cm4gbnVsbH07dmFyIEU9eS5wcm90b2NvbCxJPXkucG9ydCxSPXkuaG9zdG5hbWU7eS5wcm90b2NvbD1mdW5jdGlvbih0LGUpe2lmKHZvaWQgMCE9PXQmJnQmJih0PXQucmVwbGFjZSgvOihcXC9cXC8pPyQvLFwiXCIpLCF0Lm1hdGNoKG4uZ3ApKSl0aHJvdyBuZXcgVHlwZUVycm9yKCdQcm90b2NvbCBcIicrdCtcIlxcXCIgY29udGFpbnMgY2hhcmFjdGVycyBvdGhlciB0aGFuIFtBLVowLTkuKy1dIG9yIGRvZXNuJ3Qgc3RhcnQgd2l0aCBbQS1aXVwiKTtyZXR1cm4gRS5jYWxsKHRoaXMsdCxlKX0seS5zY2hlbWU9eS5wcm90b2NvbCx5LnBvcnQ9ZnVuY3Rpb24odCxlKXtpZih0aGlzLmhwLnVybilyZXR1cm4gdm9pZCAwPT09dD9cIlwiOnRoaXM7aWYodm9pZCAwIT09dCYmKDA9PT10JiYodD1udWxsKSx0JiYodCs9XCJcIixcIjpcIj09PXQuY2hhckF0KDApJiYodD10LnN1YnN0cmluZygxKSksdC5tYXRjaCgvW14wLTldLykpKSl0aHJvdyBuZXcgVHlwZUVycm9yKCdQb3J0IFwiJyt0KydcIiBjb250YWlucyBjaGFyYWN0ZXJzIG90aGVyIHRoYW4gWzAtOV0nKTtyZXR1cm4gSS5jYWxsKHRoaXMsdCxlKX0seS5ob3N0bmFtZT1mdW5jdGlvbih0LGUpe2lmKHRoaXMuaHAudXJuKXJldHVybiB2b2lkIDA9PT10P1wiXCI6dGhpcztpZih2b2lkIDAhPT10KXt2YXIgaT17fSxyPW4uZ3UodCxpKTtpZihcIi9cIiE9PXIpdGhyb3cgbmV3IFR5cGVFcnJvcignSG9zdG5hbWUgXCInK3QrJ1wiIGNvbnRhaW5zIGNoYXJhY3RlcnMgb3RoZXIgdGhhbiBbQS1aMC05Li1dJyk7dD1pLmhvc3RuYW1lfXJldHVybiBSLmNhbGwodGhpcyx0LGUpfSx5Lm9yaWdpbj1mdW5jdGlvbih0LGUpe2lmKHRoaXMuaHAudXJuKXJldHVybiB2b2lkIDA9PT10P1wiXCI6dGhpcztpZih2b2lkIDA9PT10KXt2YXIgaT10aGlzLnByb3RvY29sKCkscj10aGlzLkR1KCk7cmV0dXJuIHI/KGk/aStcIjovL1wiOlwiXCIpK3RoaXMuRHUoKTpcIlwifXZhciBvPW4odCk7cmV0dXJuIHRoaXMucHJvdG9jb2woby5wcm90b2NvbCgpKS5EdShvLkR1KCkpLnBwKCFlKSx0aGlzfSx5Lmhvc3Q9ZnVuY3Rpb24odCxlKXtpZih0aGlzLmhwLnVybilyZXR1cm4gdm9pZCAwPT09dD9cIlwiOnRoaXM7aWYodm9pZCAwPT09dClyZXR1cm4gdGhpcy5ocC5ob3N0bmFtZT9uLnd1KHRoaXMuaHApOlwiXCI7dmFyIGk9bi5ndSh0LHRoaXMuaHApO2lmKFwiL1wiIT09aSl0aHJvdyBuZXcgVHlwZUVycm9yKCdIb3N0bmFtZSBcIicrdCsnXCIgY29udGFpbnMgY2hhcmFjdGVycyBvdGhlciB0aGFuIFtBLVowLTkuLV0nKTtyZXR1cm4gdGhpcy5wcCghZSksdGhpc30seS5EdT1mdW5jdGlvbih0LGUpe2lmKHRoaXMuaHAudXJuKXJldHVybiB2b2lkIDA9PT10P1wiXCI6dGhpcztpZih2b2lkIDA9PT10KXJldHVybiB0aGlzLmhwLmhvc3RuYW1lP24ubXUodGhpcy5ocCk6XCJcIjt2YXIgaT1uLmZ1KHQsdGhpcy5ocCk7aWYoXCIvXCIhPT1pKXRocm93IG5ldyBUeXBlRXJyb3IoJ0hvc3RuYW1lIFwiJyt0KydcIiBjb250YWlucyBjaGFyYWN0ZXJzIG90aGVyIHRoYW4gW0EtWjAtOS4tXScpO3JldHVybiB0aGlzLnBwKCFlKSx0aGlzfSx5Lkh1PWZ1bmN0aW9uKHQsZSl7aWYodGhpcy5ocC51cm4pcmV0dXJuIHZvaWQgMD09PXQ/XCJcIjp0aGlzO2lmKHZvaWQgMD09PXQpe3ZhciBpPW4uVHUodGhpcy5ocCk7cmV0dXJuIGk/aS5zdWJzdHJpbmcoMCxpLmxlbmd0aC0xKTppfXJldHVyblwiQFwiIT09dFt0Lmxlbmd0aC0xXSYmKHQrPVwiQFwiKSxuLnZ1KHQsdGhpcy5ocCksdGhpcy5wcCghZSksdGhpc30seS5MdT1mdW5jdGlvbih0LGUpe3ZhciBpO3JldHVybiB2b2lkIDA9PT10P3RoaXMucGF0aCgpK3RoaXMuc2VhcmNoKCkrdGhpcy5oYXNoKCk6KGk9bi5wYXJzZSh0KSx0aGlzLmhwLnBhdGg9aS5wYXRoLHRoaXMuaHAudmk9aS52aSx0aGlzLmhwLmxwPWkubHAsdGhpcy5wcCghZSksdGhpcyl9LHkuTXU9ZnVuY3Rpb24odCxlKXtpZih0aGlzLmhwLnVybilyZXR1cm4gdm9pZCAwPT09dD9cIlwiOnRoaXM7aWYodm9pZCAwPT09dCl7aWYoIXRoaXMuaHAuaG9zdG5hbWV8fHRoaXMuaXMoXCJJUFwiKSlyZXR1cm5cIlwiO3ZhciBpPXRoaXMuaHAuaG9zdG5hbWUubGVuZ3RoLXRoaXMuZG9tYWluKCkubGVuZ3RoLTE7cmV0dXJuIHRoaXMuaHAuaG9zdG5hbWUuc3Vic3RyaW5nKDAsaSl8fFwiXCJ9dmFyIHI9dGhpcy5ocC5ob3N0bmFtZS5sZW5ndGgtdGhpcy5kb21haW4oKS5sZW5ndGgscz10aGlzLmhwLmhvc3RuYW1lLnN1YnN0cmluZygwLHIpLGE9bmV3IFJlZ0V4cChcIl5cIitvKHMpKTtyZXR1cm4gdCYmXCIuXCIhPT10LmNoYXJBdCh0Lmxlbmd0aC0xKSYmKHQrPVwiLlwiKSx0JiZuLkF1KHQpLHRoaXMuaHAuaG9zdG5hbWU9dGhpcy5ocC5ob3N0bmFtZS5yZXBsYWNlKGEsdCksdGhpcy5wcCghZSksdGhpc30seS5kb21haW49ZnVuY3Rpb24odCxlKXtpZih0aGlzLmhwLnVybilyZXR1cm4gdm9pZCAwPT09dD9cIlwiOnRoaXM7aWYoXCJib29sZWFuXCI9PXR5cGVvZiB0JiYoZT10LHQ9dm9pZCAwKSx2b2lkIDA9PT10KXtpZighdGhpcy5ocC5ob3N0bmFtZXx8dGhpcy5pcyhcIklQXCIpKXJldHVyblwiXCI7dmFyIGk9dGhpcy5ocC5ob3N0bmFtZS5tYXRjaCgvXFwuL2cpO2lmKGkmJmkubGVuZ3RoPDIpcmV0dXJuIHRoaXMuaHAuaG9zdG5hbWU7dmFyIHI9dGhpcy5ocC5ob3N0bmFtZS5sZW5ndGgtdGhpcy5qdShlKS5sZW5ndGgtMTtyZXR1cm4gcj10aGlzLmhwLmhvc3RuYW1lLmxhc3RJbmRleE9mKFwiLlwiLHItMSkrMSx0aGlzLmhwLmhvc3RuYW1lLnN1YnN0cmluZyhyKXx8XCJcIn1pZighdCl0aHJvdyBuZXcgVHlwZUVycm9yKFwiY2Fubm90IHNldCBkb21haW4gZW1wdHlcIik7aWYobi5BdSh0KSwhdGhpcy5ocC5ob3N0bmFtZXx8dGhpcy5pcyhcIklQXCIpKXRoaXMuaHAuaG9zdG5hbWU9dDtlbHNle3ZhciBzPW5ldyBSZWdFeHAobyh0aGlzLmRvbWFpbigpKStcIiRcIik7dGhpcy5ocC5ob3N0bmFtZT10aGlzLmhwLmhvc3RuYW1lLnJlcGxhY2Uocyx0KX1yZXR1cm4gdGhpcy5wcCghZSksdGhpc30seS5qdT1mdW5jdGlvbih0LGUpe2lmKHRoaXMuaHAudXJuKXJldHVybiB2b2lkIDA9PT10P1wiXCI6dGhpcztpZihcImJvb2xlYW5cIj09dHlwZW9mIHQmJihlPXQsdD12b2lkIDApLHZvaWQgMD09PXQpe2lmKCF0aGlzLmhwLmhvc3RuYW1lfHx0aGlzLmlzKFwiSVBcIikpcmV0dXJuXCJcIjt2YXIgcj10aGlzLmhwLmhvc3RuYW1lLmxhc3RJbmRleE9mKFwiLlwiKSxuPXRoaXMuaHAuaG9zdG5hbWUuc3Vic3RyaW5nKHIrMSk7cmV0dXJuIGUhPT0hMCYmaSYmaS5saXN0W24udG9Mb3dlckNhc2UoKV0/aS5nZXQodGhpcy5ocC5ob3N0bmFtZSl8fG46bn12YXIgcztpZighdCl0aHJvdyBuZXcgVHlwZUVycm9yKFwiY2Fubm90IHNldCBUTEQgZW1wdHlcIik7aWYodC5tYXRjaCgvW15hLXpBLVowLTktXS8pKXtpZighaXx8IWkuaXModCkpdGhyb3cgbmV3IFR5cGVFcnJvcignVExEIFwiJyt0KydcIiBjb250YWlucyBjaGFyYWN0ZXJzIG90aGVyIHRoYW4gW0EtWjAtOV0nKTtzPW5ldyBSZWdFeHAobyh0aGlzLmp1KCkpK1wiJFwiKSx0aGlzLmhwLmhvc3RuYW1lPXRoaXMuaHAuaG9zdG5hbWUucmVwbGFjZShzLHQpfWVsc2V7aWYoIXRoaXMuaHAuaG9zdG5hbWV8fHRoaXMuaXMoXCJJUFwiKSl0aHJvdyBuZXcgUmVmZXJlbmNlRXJyb3IoXCJjYW5ub3Qgc2V0IFRMRCBvbiBub24tZG9tYWluIGhvc3RcIik7cz1uZXcgUmVnRXhwKG8odGhpcy5qdSgpKStcIiRcIiksdGhpcy5ocC5ob3N0bmFtZT10aGlzLmhwLmhvc3RuYW1lLnJlcGxhY2Uocyx0KX1yZXR1cm4gdGhpcy5wcCghZSksdGhpc30seS5VdT1mdW5jdGlvbih0LGUpe2lmKHRoaXMuaHAudXJuKXJldHVybiB2b2lkIDA9PT10P1wiXCI6dGhpcztpZih2b2lkIDA9PT10fHx0PT09ITApe2lmKCF0aGlzLmhwLnBhdGgmJiF0aGlzLmhwLmhvc3RuYW1lKXJldHVyblwiXCI7aWYoXCIvXCI9PT10aGlzLmhwLnBhdGgpcmV0dXJuXCIvXCI7dmFyIGk9dGhpcy5ocC5wYXRoLmxlbmd0aC10aGlzLmZpbGVuYW1lKCkubGVuZ3RoLTEscj10aGlzLmhwLnBhdGguc3Vic3RyaW5nKDAsaSl8fCh0aGlzLmhwLmhvc3RuYW1lP1wiL1wiOlwiXCIpO3JldHVybiB0P24uaHUocik6cn12YXIgcz10aGlzLmhwLnBhdGgubGVuZ3RoLXRoaXMuZmlsZW5hbWUoKS5sZW5ndGgsYT10aGlzLmhwLnBhdGguc3Vic3RyaW5nKDAscyksYz1uZXcgUmVnRXhwKFwiXlwiK28oYSkpO3JldHVybiB0aGlzLmlzKFwicmVsYXRpdmVcIil8fCh0fHwodD1cIi9cIiksXCIvXCIhPT10LmNoYXJBdCgwKSYmKHQ9XCIvXCIrdCkpLHQmJlwiL1wiIT09dC5jaGFyQXQodC5sZW5ndGgtMSkmJih0Kz1cIi9cIiksdD1uLnV1KHQpLHRoaXMuaHAucGF0aD10aGlzLmhwLnBhdGgucmVwbGFjZShjLHQpLHRoaXMucHAoIWUpLHRoaXN9LHkuZmlsZW5hbWU9ZnVuY3Rpb24odCxlKXtpZih0aGlzLmhwLnVybilyZXR1cm4gdm9pZCAwPT09dD9cIlwiOnRoaXM7aWYoXCJzdHJpbmdcIiE9dHlwZW9mIHQpe2lmKCF0aGlzLmhwLnBhdGh8fFwiL1wiPT09dGhpcy5ocC5wYXRoKXJldHVyblwiXCI7dmFyIGk9dGhpcy5ocC5wYXRoLmxhc3RJbmRleE9mKFwiL1wiKSxyPXRoaXMuaHAucGF0aC5zdWJzdHJpbmcoaSsxKTtyZXR1cm4gdD9uLmRlY29kZVBhdGhTZWdtZW50KHIpOnJ9dmFyIHM9ITE7XCIvXCI9PT10LmNoYXJBdCgwKSYmKHQ9dC5zdWJzdHJpbmcoMSkpLHQubWF0Y2goL1xcLj9cXC8vKSYmKHM9ITApO3ZhciBhPW5ldyBSZWdFeHAobyh0aGlzLmZpbGVuYW1lKCkpK1wiJFwiKTtyZXR1cm4gdD1uLnV1KHQpLHRoaXMuaHAucGF0aD10aGlzLmhwLnBhdGgucmVwbGFjZShhLHQpLHM/dGhpcy5WdShlKTp0aGlzLnBwKCFlKSx0aGlzfSx5LnN1ZmZpeD1mdW5jdGlvbih0LGUpe2lmKHRoaXMuaHAudXJuKXJldHVybiB2b2lkIDA9PT10P1wiXCI6dGhpcztpZih2b2lkIDA9PT10fHx0PT09ITApe2lmKCF0aGlzLmhwLnBhdGh8fFwiL1wiPT09dGhpcy5ocC5wYXRoKXJldHVyblwiXCI7dmFyIGkscixzPXRoaXMuZmlsZW5hbWUoKSxhPXMubGFzdEluZGV4T2YoXCIuXCIpO3JldHVybiBhPT09LTE/XCJcIjooaT1zLnN1YnN0cmluZyhhKzEpLHI9L15bYS16MC05JV0rJC9pLnRlc3QoaSk/aTpcIlwiLHQ/bi5kZWNvZGVQYXRoU2VnbWVudChyKTpyKX1cIi5cIj09PXQuY2hhckF0KDApJiYodD10LnN1YnN0cmluZygxKSk7dmFyIGMsaD10aGlzLnN1ZmZpeCgpO2lmKGgpYz10P25ldyBSZWdFeHAobyhoKStcIiRcIik6bmV3IFJlZ0V4cChvKFwiLlwiK2gpK1wiJFwiKTtlbHNle2lmKCF0KXJldHVybiB0aGlzO3RoaXMuaHAucGF0aCs9XCIuXCIrbi51dSh0KX1yZXR1cm4gYyYmKHQ9bi51dSh0KSx0aGlzLmhwLnBhdGg9dGhpcy5ocC5wYXRoLnJlcGxhY2UoYyx0KSksdGhpcy5wcCghZSksdGhpc30seS5DdT1mdW5jdGlvbih0LGUsaSl7dmFyIHI9dGhpcy5ocC51cm4/XCI6XCI6XCIvXCIsbj10aGlzLnBhdGgoKSxvPVwiL1wiPT09bi5zdWJzdHJpbmcoMCwxKSxzPW4uc3BsaXQocik7aWYodm9pZCAwIT09dCYmXCJudW1iZXJcIiE9dHlwZW9mIHQmJihpPWUsZT10LHQ9dm9pZCAwKSx2b2lkIDAhPT10JiZcIm51bWJlclwiIT10eXBlb2YgdCl0aHJvdyBuZXcgRXJyb3IoJ0JhZCBzZWdtZW50IFwiJyt0KydcIiwgbXVzdCBiZSAwLWJhc2VkIGludGVnZXInKTtpZihvJiZzLnNoaWZ0KCksdDwwJiYodD1NYXRoLm1heChzLmxlbmd0aCt0LDApKSx2b2lkIDA9PT1lKXJldHVybiB2b2lkIDA9PT10P3M6c1t0XTtpZihudWxsPT09dHx8dm9pZCAwPT09c1t0XSlpZihhKGUpKXtzPVtdO2Zvcih2YXIgYz0wLGg9ZS5sZW5ndGg7YzxoO2MrKykoZVtjXS5sZW5ndGh8fHMubGVuZ3RoJiZzW3MubGVuZ3RoLTFdLmxlbmd0aCkmJihzLmxlbmd0aCYmIXNbcy5sZW5ndGgtMV0ubGVuZ3RoJiZzLnBvcCgpLHMucHVzaCh1KGVbY10pKSl9ZWxzZShlfHxcInN0cmluZ1wiPT10eXBlb2YgZSkmJihlPXUoZSksXCJcIj09PXNbcy5sZW5ndGgtMV0/c1tzLmxlbmd0aC0xXT1lOnMucHVzaChlKSk7ZWxzZSBlP3NbdF09dShlKTpzLnNwbGljZSh0LDEpO3JldHVybiBvJiZzLnVuc2hpZnQoXCJcIiksdGhpcy5wYXRoKHMuam9pbihyKSxpKX0seS5RdT1mdW5jdGlvbih0LGUsaSl7dmFyIHIsbyxzO2lmKFwibnVtYmVyXCIhPXR5cGVvZiB0JiYoaT1lLGU9dCx0PXZvaWQgMCksdm9pZCAwPT09ZSl7aWYocj10aGlzLkN1KHQsZSxpKSxhKHIpKWZvcihvPTAscz1yLmxlbmd0aDtvPHM7bysrKXJbb109bi5kZWNvZGUocltvXSk7ZWxzZSByPXZvaWQgMCE9PXI/bi5kZWNvZGUocik6dm9pZCAwO3JldHVybiByfWlmKGEoZSkpZm9yKG89MCxzPWUubGVuZ3RoO288cztvKyspZVtvXT1uLmVuY29kZShlW29dKTtlbHNlIGU9XCJzdHJpbmdcIj09dHlwZW9mIGV8fGUgaW5zdGFuY2VvZiBTdHJpbmc/bi5lbmNvZGUoZSk6ZTtyZXR1cm4gdGhpcy5DdSh0LGUsaSl9O3ZhciBrPXkudmk7cmV0dXJuIHkudmk9ZnVuY3Rpb24odCxlKXtpZih0PT09ITApcmV0dXJuIG4ueXUodGhpcy5ocC52aSx0aGlzLmhwLmZwKTtpZihcImZ1bmN0aW9uXCI9PXR5cGVvZiB0KXt2YXIgaT1uLnl1KHRoaXMuaHAudmksdGhpcy5ocC5mcCkscj10LmNhbGwodGhpcyxpKTtyZXR1cm4gdGhpcy5ocC52aT1uLlN1KHJ8fGksdGhpcy5ocC5kcCx0aGlzLmhwLmZwKSx0aGlzLnBwKCFlKSx0aGlzfXJldHVybiB2b2lkIDAhPT10JiZcInN0cmluZ1wiIT10eXBlb2YgdD8odGhpcy5ocC52aT1uLlN1KHQsdGhpcy5ocC5kcCx0aGlzLmhwLmZwKSx0aGlzLnBwKCFlKSx0aGlzKTprLmNhbGwodGhpcyx0LGUpfSx5LnF1PWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj1uLnl1KHRoaXMuaHAudmksdGhpcy5ocC5mcCk7aWYoXCJzdHJpbmdcIj09dHlwZW9mIHR8fHQgaW5zdGFuY2VvZiBTdHJpbmcpclt0XT12b2lkIDAhPT1lP2U6bnVsbDtlbHNle2lmKFwib2JqZWN0XCIhPXR5cGVvZiB0KXRocm93IG5ldyBUeXBlRXJyb3IoXCJVUkkuYWRkUXVlcnkoKSBhY2NlcHRzIGFuIG9iamVjdCwgc3RyaW5nIGFzIHRoZSBuYW1lIHBhcmFtZXRlclwiKTtmb3IodmFyIG8gaW4gdCltLmNhbGwodCxvKSYmKHJbb109dFtvXSl9cmV0dXJuIHRoaXMuaHAudmk9bi5TdShyLHRoaXMuaHAuZHAsdGhpcy5ocC5mcCksXCJzdHJpbmdcIiE9dHlwZW9mIHQmJihpPWUpLHRoaXMucHAoIWkpLHRoaXN9LHkuRXU9ZnVuY3Rpb24odCxlLGkpe3ZhciByPW4ueXUodGhpcy5ocC52aSx0aGlzLmhwLmZwKTtyZXR1cm4gbi5FdShyLHQsdm9pZCAwPT09ZT9udWxsOmUpLHRoaXMuaHAudmk9bi5TdShyLHRoaXMuaHAuZHAsdGhpcy5ocC5mcCksXCJzdHJpbmdcIiE9dHlwZW9mIHQmJihpPWUpLHRoaXMucHAoIWkpLHRoaXN9LHkuSXU9ZnVuY3Rpb24odCxlLGkpe3ZhciByPW4ueXUodGhpcy5ocC52aSx0aGlzLmhwLmZwKTtyZXR1cm4gbi5JdShyLHQsZSksdGhpcy5ocC52aT1uLlN1KHIsdGhpcy5ocC5kcCx0aGlzLmhwLmZwKSxcInN0cmluZ1wiIT10eXBlb2YgdCYmKGk9ZSksdGhpcy5wcCghaSksdGhpc30seS5SdT1mdW5jdGlvbih0LGUsaSl7dmFyIHI9bi55dSh0aGlzLmhwLnZpLHRoaXMuaHAuZnApO3JldHVybiBuLlJ1KHIsdCxlLGkpfSx5Lkp1PXkucXUseS5LdT15LkV1LHkuR3U9eS5JdSx5Lnp1PXkuUnUseS5ub3JtYWxpemU9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ocC51cm4/dGhpcy5ZdSghMSkuVnUoITEpLiR1KCExKS5XdSghMSkucHAoKTp0aGlzLll1KCExKS5adSghMSkuWHUoITEpLlZ1KCExKS4kdSghMSkuV3UoITEpLnBwKCl9LHkuWXU9ZnVuY3Rpb24odCl7cmV0dXJuXCJzdHJpbmdcIj09dHlwZW9mIHRoaXMuaHAucHJvdG9jb2wmJih0aGlzLmhwLnByb3RvY29sPXRoaXMuaHAucHJvdG9jb2wudG9Mb3dlckNhc2UoKSx0aGlzLnBwKCF0KSksdGhpc30seS5adT1mdW5jdGlvbihpKXtyZXR1cm4gdGhpcy5ocC5ob3N0bmFtZSYmKHRoaXMuaXMoXCJJRE5cIikmJnQ/dGhpcy5ocC5ob3N0bmFtZT10LnRvQVNDSUkodGhpcy5ocC5ob3N0bmFtZSk6dGhpcy5pcyhcIklQdjZcIikmJmUmJih0aGlzLmhwLmhvc3RuYW1lPWUuYmVzdCh0aGlzLmhwLmhvc3RuYW1lKSksdGhpcy5ocC5ob3N0bmFtZT10aGlzLmhwLmhvc3RuYW1lLnRvTG93ZXJDYXNlKCksdGhpcy5wcCghaSkpLHRoaXN9LHkuWHU9ZnVuY3Rpb24odCl7cmV0dXJuXCJzdHJpbmdcIj09dHlwZW9mIHRoaXMuaHAucHJvdG9jb2wmJnRoaXMuaHAucG9ydD09PW4uRXBbdGhpcy5ocC5wcm90b2NvbF0mJih0aGlzLmhwLnBvcnQ9bnVsbCx0aGlzLnBwKCF0KSksdGhpc30seS5WdT1mdW5jdGlvbih0KXt2YXIgZT10aGlzLmhwLnBhdGg7aWYoIWUpcmV0dXJuIHRoaXM7aWYodGhpcy5ocC51cm4pcmV0dXJuIHRoaXMuaHAucGF0aD1uLmx1KHRoaXMuaHAucGF0aCksdGhpcy5wcCghdCksdGhpcztpZihcIi9cIj09PXRoaXMuaHAucGF0aClyZXR1cm4gdGhpcztlPW4udXUoZSk7dmFyIGkscixvLHM9XCJcIjtmb3IoXCIvXCIhPT1lLmNoYXJBdCgwKSYmKGk9ITAsZT1cIi9cIitlKSxcIi8uLlwiIT09ZS5zbGljZSgtMykmJlwiLy5cIiE9PWUuc2xpY2UoLTIpfHwoZSs9XCIvXCIpLGU9ZS5yZXBsYWNlKC8oXFwvKFxcLlxcLykrKXwoXFwvXFwuJCkvZyxcIi9cIikucmVwbGFjZSgvXFwvezIsfS9nLFwiL1wiKSxpJiYocz1lLnN1YnN0cmluZygxKS5tYXRjaCgvXihcXC5cXC5cXC8pKy8pfHxcIlwiLHMmJihzPXNbMF0pKTs7KXtpZihyPWUuc2VhcmNoKC9cXC9cXC5cXC4oXFwvfCQpLykscj09PS0xKWJyZWFrOzAhPT1yPyhvPWUuc3Vic3RyaW5nKDAscikubGFzdEluZGV4T2YoXCIvXCIpLG89PT0tMSYmKG89ciksZT1lLnN1YnN0cmluZygwLG8pK2Uuc3Vic3RyaW5nKHIrMykpOmU9ZS5zdWJzdHJpbmcoMyl9cmV0dXJuIGkmJnRoaXMuaXMoXCJyZWxhdGl2ZVwiKSYmKGU9cytlLnN1YnN0cmluZygxKSksdGhpcy5ocC5wYXRoPWUsdGhpcy5wcCghdCksdGhpc30seS50bD15LlZ1LHkuJHU9ZnVuY3Rpb24odCl7cmV0dXJuXCJzdHJpbmdcIj09dHlwZW9mIHRoaXMuaHAudmkmJih0aGlzLmhwLnZpLmxlbmd0aD90aGlzLnZpKG4ueXUodGhpcy5ocC52aSx0aGlzLmhwLmZwKSk6dGhpcy5ocC52aT1udWxsLHRoaXMucHAoIXQpKSx0aGlzfSx5Lld1PWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLmhwLmxwfHwodGhpcy5ocC5scD1udWxsLHRoaXMucHAoIXQpKSx0aGlzfSx5LmVsPXkuJHUseS5pbD15Lld1LHkuVXA9ZnVuY3Rpb24oKXt2YXIgdD1uLmVuY29kZSxlPW4uZGVjb2RlO24uZW5jb2RlPWVzY2FwZSxuLmRlY29kZT1kZWNvZGVVUklDb21wb25lbnQ7dHJ5e3RoaXMubm9ybWFsaXplKCl9ZmluYWxseXtuLmVuY29kZT10LG4uZGVjb2RlPWV9cmV0dXJuIHRoaXN9LHkuVnA9ZnVuY3Rpb24oKXt2YXIgdD1uLmVuY29kZSxlPW4uZGVjb2RlO24uZW5jb2RlPWQsbi5kZWNvZGU9dW5lc2NhcGU7dHJ5e3RoaXMubm9ybWFsaXplKCl9ZmluYWxseXtuLmVuY29kZT10LG4uZGVjb2RlPWV9cmV0dXJuIHRoaXN9LHkucmw9ZnVuY3Rpb24oKXt2YXIgZT10aGlzLmNsb25lKCk7ZS51c2VybmFtZShcIlwiKS5wYXNzd29yZChcIlwiKS5ub3JtYWxpemUoKTt2YXIgaT1cIlwiO2lmKGUuaHAucHJvdG9jb2wmJihpKz1lLmhwLnByb3RvY29sK1wiOi8vXCIpLGUuaHAuaG9zdG5hbWUmJihlLmlzKFwicHVueWNvZGVcIikmJnQ/KGkrPXQudG9Vbmljb2RlKGUuaHAuaG9zdG5hbWUpLGUuaHAucG9ydCYmKGkrPVwiOlwiK2UuaHAucG9ydCkpOmkrPWUuaG9zdCgpKSxlLmhwLmhvc3RuYW1lJiZlLmhwLnBhdGgmJlwiL1wiIT09ZS5ocC5wYXRoLmNoYXJBdCgwKSYmKGkrPVwiL1wiKSxpKz1lLnBhdGgoITApLGUuaHAudmkpe2Zvcih2YXIgcj1cIlwiLG89MCxzPWUuaHAudmkuc3BsaXQoXCImXCIpLGE9cy5sZW5ndGg7bzxhO28rKyl7dmFyIGM9KHNbb118fFwiXCIpLnNwbGl0KFwiPVwiKTtyKz1cIiZcIituLmN1KGNbMF0sdGhpcy5ocC5mcCkucmVwbGFjZSgvJi9nLFwiJTI2XCIpLHZvaWQgMCE9PWNbMV0mJihyKz1cIj1cIituLmN1KGNbMV0sdGhpcy5ocC5mcCkucmVwbGFjZSgvJi9nLFwiJTI2XCIpKX1pKz1cIj9cIityLnN1YnN0cmluZygxKX1yZXR1cm4gaSs9bi5jdShlLmhhc2goKSwhMCl9LHkuY3A9ZnVuY3Rpb24odCl7dmFyIGUsaSxyLG89dGhpcy5jbG9uZSgpLHM9W1wicHJvdG9jb2xcIixcInVzZXJuYW1lXCIsXCJwYXNzd29yZFwiLFwiaG9zdG5hbWVcIixcInBvcnRcIl07aWYodGhpcy5ocC51cm4pdGhyb3cgbmV3IEVycm9yKFwiVVJOcyBkbyBub3QgaGF2ZSBhbnkgZ2VuZXJhbGx5IGRlZmluZWQgaGllcmFyY2hpY2FsIGNvbXBvbmVudHNcIik7aWYodCBpbnN0YW5jZW9mIG58fCh0PW5ldyBuKHQpKSxvLmhwLnByb3RvY29sKXJldHVybiBvO2lmKG8uaHAucHJvdG9jb2w9dC5ocC5wcm90b2NvbCx0aGlzLmhwLmhvc3RuYW1lKXJldHVybiBvO2ZvcihpPTA7cj1zW2ldO2krKylvLmhwW3JdPXQuaHBbcl07cmV0dXJuIG8uaHAucGF0aD8oXCIuLlwiPT09by5ocC5wYXRoLnN1YnN0cmluZygtMikmJihvLmhwLnBhdGgrPVwiL1wiKSxcIi9cIiE9PW8ucGF0aCgpLmNoYXJBdCgwKSYmKGU9dC5VdSgpLGU9ZT9lOjA9PT10LnBhdGgoKS5pbmRleE9mKFwiL1wiKT9cIi9cIjpcIlwiLG8uaHAucGF0aD0oZT9lK1wiL1wiOlwiXCIpK28uaHAucGF0aCxvLlZ1KCkpKTooby5ocC5wYXRoPXQuaHAucGF0aCxvLmhwLnZpfHwoby5ocC52aT10LmhwLnZpKSksby5wcCgpLG99LHkubmw9ZnVuY3Rpb24odCl7dmFyIGUsaSxyLG8scyxhPXRoaXMuY2xvbmUoKS5ub3JtYWxpemUoKTtpZihhLmhwLnVybil0aHJvdyBuZXcgRXJyb3IoXCJVUk5zIGRvIG5vdCBoYXZlIGFueSBnZW5lcmFsbHkgZGVmaW5lZCBoaWVyYXJjaGljYWwgY29tcG9uZW50c1wiKTtpZih0PW5ldyBuKHQpLm5vcm1hbGl6ZSgpLGU9YS5ocCxpPXQuaHAsbz1hLnBhdGgoKSxzPXQucGF0aCgpLFwiL1wiIT09by5jaGFyQXQoMCkpdGhyb3cgbmV3IEVycm9yKFwiVVJJIGlzIGFscmVhZHkgcmVsYXRpdmVcIik7aWYoXCIvXCIhPT1zLmNoYXJBdCgwKSl0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgY2FsY3VsYXRlIGEgVVJJIHJlbGF0aXZlIHRvIGFub3RoZXIgcmVsYXRpdmUgVVJJXCIpO2lmKGUucHJvdG9jb2w9PT1pLnByb3RvY29sJiYoZS5wcm90b2NvbD1udWxsKSxlLnVzZXJuYW1lIT09aS51c2VybmFtZXx8ZS5wYXNzd29yZCE9PWkucGFzc3dvcmQpcmV0dXJuIGEucHAoKTtpZihudWxsIT09ZS5wcm90b2NvbHx8bnVsbCE9PWUudXNlcm5hbWV8fG51bGwhPT1lLnBhc3N3b3JkKXJldHVybiBhLnBwKCk7aWYoZS5ob3N0bmFtZSE9PWkuaG9zdG5hbWV8fGUucG9ydCE9PWkucG9ydClyZXR1cm4gYS5wcCgpO2lmKGUuaG9zdG5hbWU9bnVsbCxlLnBvcnQ9bnVsbCxvPT09cylyZXR1cm4gZS5wYXRoPVwiXCIsYS5wcCgpO2lmKHI9bi5PdShvLHMpLCFyKXJldHVybiBhLnBwKCk7dmFyIGM9aS5wYXRoLnN1YnN0cmluZyhyLmxlbmd0aCkucmVwbGFjZSgvW15cXC9dKiQvLFwiXCIpLnJlcGxhY2UoLy4qP1xcLy9nLFwiLi4vXCIpO3JldHVybiBlLnBhdGg9YytlLnBhdGguc3Vic3RyaW5nKHIubGVuZ3RoKXx8XCIuL1wiLGEucHAoKX0seS5vbD1mdW5jdGlvbih0KXt2YXIgZSxpLHIsbz10aGlzLmNsb25lKCkscz1uZXcgbih0KSxjPXt9LGg9e30sdT17fTtpZihvLm5vcm1hbGl6ZSgpLHMubm9ybWFsaXplKCksby50b1N0cmluZygpPT09cy50b1N0cmluZygpKXJldHVybiEwO2lmKGU9by52aSgpLGk9cy52aSgpLG8udmkoXCJcIikscy52aShcIlwiKSxvLnRvU3RyaW5nKCkhPT1zLnRvU3RyaW5nKCkpcmV0dXJuITE7aWYoZS5sZW5ndGghPT1pLmxlbmd0aClyZXR1cm4hMTtjPW4ueXUoZSx0aGlzLmhwLmZwKSxoPW4ueXUoaSx0aGlzLmhwLmZwKTtmb3IociBpbiBjKWlmKG0uY2FsbChjLHIpKXtpZihhKGNbcl0pKXtpZighcChjW3JdLGhbcl0pKXJldHVybiExfWVsc2UgaWYoY1tyXSE9PWhbcl0pcmV0dXJuITE7dVtyXT0hMH1mb3IociBpbiBoKWlmKG0uY2FsbChoLHIpJiYhdVtyXSlyZXR1cm4hMTtyZXR1cm4hMH0seS5kcD1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5ocC5kcD0hIXQsdGhpc30seS5mcD1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5ocC5mcD0hIXQsdGhpc30sbn0pfSxmdW5jdGlvbih0LGUsaSl7LyohIHV1aWQuanNcbiAqIENvcHlyaWdodCAoYykgMjAxMC0yMDEyIFJvYmVydCBLaWVmZmVyXG4gKiBNSVQgTGljZW5zZSAtIGh0dHA6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9taXQtbGljZW5zZS5waHBcbiAqL1xuICAhZnVuY3Rpb24oZSl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gcigpe3ZhciB0PWUuY3J5cHRvfHxlLm1zQ3J5cHRvO2lmKCFoJiZ0JiZ0LmdldFJhbmRvbVZhbHVlcyl0cnl7dmFyIGk9bmV3IFVpbnQ4QXJyYXkoMTYpO2w9aD1mdW5jdGlvbigpe3JldHVybiB0LmdldFJhbmRvbVZhbHVlcyhpKSxpfSxoKCl9Y2F0Y2gocil7fWlmKCFoKXt2YXIgbj1uZXcgQXJyYXkoMTYpO3A9aD1mdW5jdGlvbigpe2Zvcih2YXIgdCxlPTA7ZTwxNjtlKyspMD09PSgzJmUpJiYodD00Mjk0OTY3Mjk2Kk1hdGgucmFuZG9tKCkpLG5bZV09dD4+PigoMyZlKTw8MykmMjU1O3JldHVybiBufSxcInVuZGVmaW5lZFwiIT10eXBlb2YgY29uc29sZSYmY29uc29sZS53YXJuJiZjb25zb2xlLndhcm4oXCJbU0VDVVJJVFldIG5vZGUtdXVpZDogY3J5cHRvIG5vdCB1c2FibGUsIGZhbGxpbmcgYmFjayB0byBpbnNlY3VyZSBNYXRoLnJhbmRvbSgpXCIpfX1mdW5jdGlvbiBuKCl7dHJ5e3ZhciB0PWkoMzMpLnJhbmRvbUJ5dGVzO3U9aD10JiZmdW5jdGlvbigpe3JldHVybiB0KDE2KX0saCgpfWNhdGNoKGUpe319ZnVuY3Rpb24gbyh0LGUsaSl7dmFyIHI9ZSYmaXx8MCxuPTA7Zm9yKGU9ZXx8W10sdC50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1swLTlhLWZdezJ9L2csZnVuY3Rpb24odCl7bjwxNiYmKGVbcituKytdPXZbdF0pfSk7bjwxNjspZVtyK24rK109MDtyZXR1cm4gZX1mdW5jdGlvbiBzKHQsZSl7dmFyIGk9ZXx8MCxyPWc7cmV0dXJuIHJbdFtpKytdXStyW3RbaSsrXV0rclt0W2krK11dK3JbdFtpKytdXStcIi1cIityW3RbaSsrXV0rclt0W2krK11dK1wiLVwiK3JbdFtpKytdXStyW3RbaSsrXV0rXCItXCIrclt0W2krK11dK3JbdFtpKytdXStcIi1cIityW3RbaSsrXV0rclt0W2krK11dK3JbdFtpKytdXStyW3RbaSsrXV0rclt0W2krK11dK3JbdFtpKytdXX1mdW5jdGlvbiBhKHQsZSxpKXt2YXIgcj1lJiZpfHwwLG49ZXx8W107dD10fHx7fTt2YXIgbz1udWxsIT10LmNsb2Nrc2VxP3QuY2xvY2tzZXE6VCxhPW51bGwhPXQubXNlY3M/dC5tc2VjczoobmV3IERhdGUpLmdldFRpbWUoKSxjPW51bGwhPXQubnNlY3M/dC5uc2VjczpiKzEsaD1hLVMrKGMtYikvMWU0O2lmKGg8MCYmbnVsbD09dC5jbG9ja3NlcSYmKG89bysxJjE2MzgzKSwoaDwwfHxhPlMpJiZudWxsPT10Lm5zZWNzJiYoYz0wKSxjPj0xZTQpdGhyb3cgbmV3IEVycm9yKFwidXVpZC52MSgpOiBDYW4ndCBjcmVhdGUgbW9yZSB0aGFuIDEwTSB1dWlkcy9zZWNcIik7Uz1hLGI9YyxUPW8sYSs9MTIyMTkyOTI4ZTU7dmFyIHA9KDFlNCooMjY4NDM1NDU1JmEpK2MpJTQyOTQ5NjcyOTY7bltyKytdPXA+Pj4yNCYyNTUsbltyKytdPXA+Pj4xNiYyNTUsbltyKytdPXA+Pj44JjI1NSxuW3IrK109MjU1JnA7dmFyIHU9YS80Mjk0OTY3Mjk2KjFlNCYyNjg0MzU0NTU7bltyKytdPXU+Pj44JjI1NSxuW3IrK109MjU1JnUsbltyKytdPXU+Pj4yNCYxNXwxNixuW3IrK109dT4+PjE2JjI1NSxuW3IrK109bz4+Pjh8MTI4LG5bcisrXT0yNTUmbztmb3IodmFyIGw9dC5ub2RlfHx3LGQ9MDtkPDY7ZCsrKW5bcitkXT1sW2RdO3JldHVybiBlP2U6cyhuKX1mdW5jdGlvbiBjKHQsZSxpKXt2YXIgcj1lJiZpfHwwO1wic3RyaW5nXCI9PXR5cGVvZiB0JiYoZT1cImJpbmFyeVwiPT09dD9uZXcgZigxNik6bnVsbCx0PW51bGwpLHQ9dHx8e307dmFyIG49dC5yYW5kb218fCh0LnJuZ3x8aCkoKTtpZihuWzZdPTE1Jm5bNl18NjQsbls4XT02MyZuWzhdfDEyOCxlKWZvcih2YXIgbz0wO288MTY7bysrKWVbcitvXT1uW29dO3JldHVybiBlfHxzKG4pfXZhciBoLHAsdSxsLGQ7ZT9yKCk6bigpO2Zvcih2YXIgZj1cImZ1bmN0aW9uXCI9PXR5cGVvZiBCdWZmZXI/QnVmZmVyOkFycmF5LGc9W10sdj17fSx5PTA7eTwyNTY7eSsrKWdbeV09KHkrMjU2KS50b1N0cmluZygxNikuc3Vic3RyKDEpLHZbZ1t5XV09eTt2YXIgbT1oKCksdz1bMXxtWzBdLG1bMV0sbVsyXSxtWzNdLG1bNF0sbVs1XV0sVD0xNjM4MyYobVs2XTw8OHxtWzddKSxTPTAsYj0wLEU9YztFLnNsPWEsRS5aaD1jLEUucGFyc2U9byxFLmFsPXMsRS5jbD1mLEUuaGw9aCxFLnBsPXAsRS51bD11LEUubGw9bCxcInVuZGVmaW5lZFwiIT10eXBlb2YgdCYmdC50P3QudD1FOihkPWUuZGwsRS5nZT1mdW5jdGlvbigpe3JldHVybiBlLmRsPWQsRX0sZS5kbD1FKX0oXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHdpbmRvdz93aW5kb3c6bnVsbCl9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcixuPXRoaXMmJnRoaXMuX19leHRlbmRzfHxmdW5jdGlvbih0LGUpe2Z1bmN0aW9uIGkoKXt0aGlzLmNvbnN0cnVjdG9yPXR9Zm9yKHZhciByIGluIGUpZS5oYXNPd25Qcm9wZXJ0eShyKSYmKHRbcl09ZVtyXSk7dC5wcm90b3R5cGU9bnVsbD09PWU/T2JqZWN0LmNyZWF0ZShlKTooaS5wcm90b3R5cGU9ZS5wcm90b3R5cGUsbmV3IGkpfSxvPWkoMTEpOyFmdW5jdGlvbih0KXt2YXIgZT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHR9KCk7ZS5EYXNoRmlsdGVyQml0cmF0ZXM9bnVsbCxlLkRhc2hSZW1vdmVCaXRyYXRlU2l6ZT0hMSx0LkRhc2g9ZTt2YXIgaT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHR9KCk7aS5mbD0hMCx0LlN0YXRzPWk7dmFyIHI9ZnVuY3Rpb24odCl7ZnVuY3Rpb24gZSgpe3JldHVybiBudWxsIT09dCYmdC5hcHBseSh0aGlzLGFyZ3VtZW50cyl8fHRoaXN9cmV0dXJuIG4oZSx0KSxlfShvLkhpdmVDb25maWcuRGVidWdMb2dzKTtyLmdsPTAsdC5EZWJ1Z0xvZ3M9cjt2YXIgcz1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHR9KCk7cy51c2l6PW51bGwsdC5VRFBCcm9hZGNhc3Q9c30ocj1lLkhpdmVDb25maWd8fChlLkhpdmVDb25maWc9e30pKSxcInVuZGVmaW5lZFwiIT10eXBlb2Ygd2luZG93JiYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIHdpbmRvdy5IaXZlQ29uZmlnJiYod2luZG93LkhpdmVDb25maWc9e30pLHdpbmRvdy5IaXZlQ29uZmlnLkRhc2g9ci5EYXNoLHdpbmRvdy5IaXZlQ29uZmlnLlN0YXRzPXIuU3RhdHMsd2luZG93LkhpdmVDb25maWcuVURQQnJvYWRjYXN0PXIuVURQQnJvYWRjYXN0LHdpbmRvdy5IaXZlQ29uZmlnLkRlYnVnTG9ncz1yLkRlYnVnTG9ncyl9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcixuPWkoMTEpLG89aSg0KSxzPW8udmU7IWZ1bmN0aW9uKHQpe3ZhciBlOyFmdW5jdGlvbih0KXt0W3Qub2ZmPTBdPVwib2ZmXCIsdFt0LmVycm9yPTFdPVwiZXJyb3JcIix0W3Qud2Fybj0yXT1cIndhcm5cIix0W3Qubm90aWNlPTNdPVwibm90aWNlXCIsdFt0LmluZm89NF09XCJpbmZvXCIsdFt0LmRlYnVnPTVdPVwiZGVidWdcIix0W3QudHJhY2U9Nl09XCJ0cmFjZVwifShlPXQudmx8fCh0LnZsPXt9KSk7dmFyIGk9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7dGhpcy50aW1lc3RhbXA9ZnVuY3Rpb24oKXt9LHRoaXMueWw9bmV3IHMsdGhpcy5sZXZlbD1lLmRlYnVnLHRoaXMudGltZXN0YW1wLnRvU3RyaW5nPWZ1bmN0aW9uKCl7dmFyIHQ9bmV3IERhdGUsZT0oXCIwXCIrdC5nZXRVVENIb3VycygpKS5zbGljZSgtMikrXCI6XCIrKFwiMFwiK3QuZ2V0VVRDTWludXRlcygpKS5zbGljZSgtMikrXCI6XCIrKFwiMFwiK3QuZ2V0VVRDU2Vjb25kcygpKS5zbGljZSgtMikrXCI6XCIrdC5nZXRVVENNaWxsaXNlY29uZHMoKTtyZXR1cm5cIltcIitlK1wiXVwifSx0aGlzLm09XCJ1bmRlZmluZWRcIj09dHlwZW9mIGNvbnNvbGU/e2xvZzpmdW5jdGlvbigpe319OmNvbnNvbGUsdGhpcy5tLnRyYWNlfHwodGhpcy5tLnRyYWNlPXRoaXMubS5sb2cpLHRoaXMubS5kZWJ1Z3x8KHRoaXMubS5kZWJ1Zz10aGlzLm0ubG9nKSx0aGlzLm0uaW5mb3x8KHRoaXMubS5pbmZvPXRoaXMubS5sb2cpLHRoaXMubS53YXJufHwodGhpcy5tLndhcm49dGhpcy5tLmxvZyksdGhpcy5tLmVycm9yfHwodGhpcy5tLmVycm9yPXRoaXMubS5sb2cpLHRoaXMubWwoZVt0aGlzLmxldmVsXSl9cmV0dXJuIHQucHJvdG90eXBlLm1sPWZ1bmN0aW9uKHQsaSl7bi5IaXZlQ29uZmlnLkZyYW1ld29yay5IaXZlRGVidWdMZXZlbCYmdm9pZCAwIT1lW24uSGl2ZUNvbmZpZy5GcmFtZXdvcmsuSGl2ZURlYnVnTGV2ZWxdP3RoaXMubGV2ZWw9ZVtuLkhpdmVDb25maWcuRnJhbWV3b3JrLkhpdmVEZWJ1Z0xldmVsXTp2b2lkIDAhPWVbdF0/dGhpcy5sZXZlbD1lW3RdOmNvbnNvbGUubG9nKFwiV3JvbmcgbG9nZ2luZyBsZXZlbDogXCIrdCxlKSx0aGlzLndsKGkpfSx0LnByb3RvdHlwZS53bD1mdW5jdGlvbih0KXt2YXIgaT17bG9nOnRoaXMuVGwodGhpcy5tLmxvZyxlLmVycm9yLHQpLGVycm9yOnRoaXMuVGwodGhpcy5tLmVycm9yLGUuZXJyb3IsdCksd2Fybjp0aGlzLlRsKHRoaXMubS53YXJuLGUud2Fybix0KSxub3RpY2U6dGhpcy5UbCh0aGlzLm0uaW5mbyxlLm5vdGljZSx0KSxpbmZvOnRoaXMuVGwodGhpcy5tLmluZm8sZS5pbmZvLHQpLGRlYnVnOnRoaXMuVGwodGhpcy5tLmRlYnVnLGUuZGVidWcsdCksdHJhY2U6dGhpcy5UbCh0aGlzLm0udHJhY2UsZS50cmFjZSx0KX07dD90aGlzLnlsLnNldCh0LGkpOnRoaXMuU2w9aX0sdC5wcm90b3R5cGUuVGw9ZnVuY3Rpb24odCxlLGkpe2lmKCEodGhpcy5sZXZlbD49ZSkpcmV0dXJuIGZ1bmN0aW9uKCl7fTt0cnl7cmV0dXJuIG4uSGl2ZUNvbmZpZy5GcmFtZXdvcmsuTG9nZ2VyVGltZXN0YW1wP2k/RnVuY3Rpb24ucHJvdG90eXBlLmJpbmQuY2FsbCh0LGNvbnNvbGUsXCIlcyAlc1wiLHRoaXMudGltZXN0YW1wLGkpOkZ1bmN0aW9uLnByb3RvdHlwZS5iaW5kLmNhbGwodCxjb25zb2xlLFwiJXNcIix0aGlzLnRpbWVzdGFtcCk6RnVuY3Rpb24ucHJvdG90eXBlLmJpbmQuY2FsbCh0LGNvbnNvbGUpfWNhdGNoKHIpe319LHQucHJvdG90eXBlLmxvZz1mdW5jdGlvbih0KXtyZXR1cm4gdD8odGhpcy55bC5oYXModCl8fHRoaXMubWwoZVt0aGlzLmxldmVsXSx0KSx0aGlzLnlsLmdldCh0KSk6dGhpcy5TbH0sdH0oKTt0LmJsPWl9KHI9ZS5FbHx8KGUuRWw9e30pKX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPWkoNCksbj1yLnZlLG89aSgxKSxzPWkoMiksYT1pKDQwKSxjPWkoNDkpLGg9aSgxNykscD1pKDExKSx1PWkoNyksbD1pKDQyKSxkPWkoOSksZj1pKDM3KSxnPWkoNSksdj1pKDUwKSx5PWkoNDgpLG09aSgyNyksdz1pKDE5KSxUPWkoMjApLFM9aSgxOCksYj1hLnB0LklyLEU9Yy5wdC5JbCxJPWgucHQudWgsUj1oLnB0LkNoLGs9aC5wdC5IaXZlVGVjaEVycm9yLEM9aC5wdC5iaCxPPWgucHQuQWg7ZS52ZXJzaW9uPVwiMy4yLjBcIjt2YXIgUDshZnVuY3Rpb24odCl7dmFyIHI9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQpe3RoaXMuUmw9W0VbRS5IaXZlSmF2YV0sRVtFLkhpdmVKc1Byb3h5XSxFW0UuSGl2ZUpTXSxFW0UuU3RhdHNKU11dLHRoaXMua2w9bmV3IG4sdGhpcy5DbD1uZXcgQXJyYXksdGhpcy5PbD1uZXcgQXJyYXksdGhpcy5QbD1udWxsLHRoaXMuQWw9MCx0aGlzLk5sPTAsdGhpcy51PVwiW0hpdmVDb21tXSBcIix0aGlzLnhsPTAsdGhpcy5CbD11LmFyLmdldEl0ZW0oXCJoaXZlUGx1Z2luSWRcIiksdGhpcy5CbHx8KHRoaXMuQmw9TWF0aC5hYnMoTWF0aC5mbG9vcig2ODcxOTQ3NjczNipNYXRoLnJhbmRvbSgpKSkudG9TdHJpbmcoMTYpLHUuYXIuc2V0SXRlbShcImhpdmVQbHVnaW5JZFwiLHRoaXMuQmwpKSx3LkVycm9yTW9uaXRvci5XaSgpLHRoaXMub3B0aW9uc189bmV3IGIuRmwsdGhpcy5fbCh0KSx1Lm5yKHQsdGhpcy5vcHRpb25zXyksdS5vcih3aW5kb3cubG9jYXRpb24uaHJlZixuZXcgYi5EbCx0aGlzLm9wdGlvbnNfKSxhLkxsLkhsKHRoaXMub3B0aW9uc18pLHRoaXMuZm89cy5GcmFtZXdvcmsucmVzb2x2ZShzLkZyYW1ld29yay5GZS53ZSkscC5IaXZlQ29uZmlnLkZyYW1ld29yay5Mb2dnZXJUaW1lc3RhbXA9dGhpcy5vcHRpb25zKCkubG9nZ2VyVGltZXN0YW1wLHRoaXMuZm8ubWwodGhpcy5vcHRpb25zKCkuZGVidWdMZXZlbCksdy5FcnJvck1vbml0b3IuV2koKS5MaCh0aGlzLmZvLmxvZygpKTt2YXIgZT1zLkZyYW1ld29yay5yZXNvbHZlKGcuZ2kuQ2UpLGk9cy5GcmFtZXdvcmsucmVzb2x2ZShnLmdpLmNpKTtlLktvKCkudGhlbihmdW5jdGlvbih0KXt3LkVycm9yTW9uaXRvci5XaSgpLnNldFVzZXIodC5XbygpKX0pO3ZhciByPXt9O2kuUG4oKS50aGVuKGZ1bmN0aW9uKHQpe3I9e3BJUEFkZHI6dC5ObigpLkJuKCl9LHcuRXJyb3JNb25pdG9yLldpKCkuc2V0Q3VzdG9tRGF0YShyKX0pLHdpbmRvdy52bz10aGlzLmZvLmxvZygpLHRoaXMuTWwoKSx0aGlzLmpsPW5ldyBPKHRoaXMpLG5ldyBsLlVsKHRoaXMpO3ZhciBvPXRoaXMub3B0aW9ucygpLmlkbGVUaW1lUGVyaW9kPnRoaXMub3B0aW9ucygpLmZlZWRiYWNrUGVyaW9kP3RoaXMub3B0aW9ucygpLmlkbGVUaW1lUGVyaW9kOlMua2UueGg7dGhpcy5WbD1uZXcgdS52cihvKX1yZXR1cm4gdC5wcm90b3R5cGUub3B0aW9ucz1mdW5jdGlvbigpe3JldHVybiB0aGlzLm9wdGlvbnNffSx0LnByb3RvdHlwZS5tPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZm8ubG9nKCl9LHQucHJvdG90eXBlLlM9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5CbH0sdC5wcm90b3R5cGUuY3Q9ZnVuY3Rpb24oKXtyZXR1cm4gZS52ZXJzaW9ufSx0LnByb3RvdHlwZS5RbD1mdW5jdGlvbigpe2Zvcih2YXIgdD0wLGU9dGhpcy5PbDt0PGUubGVuZ3RoO3QrKyl7dmFyIGk9ZVt0XTtpLnRlY2gucWwodGhpcyl9fSx0LnByb3RvdHlwZS5fbD1mdW5jdGlvbih0KXt2YXIgZT1uZXcgeS5TdGF0c0pTKHRoaXMsdCk7dGhpcy5rbC5zZXQoeS5TdGF0c0pTLkpsLGUpO3ZhciByPWkoNDMpLkhpdmVKYXZhO3RoaXMua2wuc2V0KHIuSmwsbmV3IHIodGhpcyx0KSk7dmFyIG49dC5oaXZlVGVjaE9yZGVyO2lmKCFufHxuIGluc3RhbmNlb2YgQXJyYXkpaWYobiYmbi5sZW5ndGg+MClmb3IodmFyIG89bi5sZW5ndGg7by0tOyl7dmFyIHM9bltvXTtcInN0cmluZ1wiIT10eXBlb2Ygc3x8dGhpcy5SbC5pbmRleE9mKHMpPT0tMT8oY29uc29sZS53YXJuKHRoaXMudSsnVGhlIFwiJytzKydcIiBIaXZlIHRlY2ggaXMgdW5kZWZpbmVkJyksbi5zcGxpY2UobywxKSk6XCJzdHJpbmdcIj09dHlwZW9mIHMmJnRoaXMua2wuaGFzKHMpfHxjb25zb2xlLndhcm4odGhpcy51KydUaGUgXCInK3MrJ1wiIEhpdmUgdGVjaCBpcyBub3QgZW5hYmxlZCBvbiB0aGlzIHBsdWdpbicpfWVsc2Ugbj10aGlzLlJsO2Vsc2UgY29uc29sZS53YXJuKHRoaXMudStcImhpdmVUZWNoT3JkZXIgdmFsdWUgbm90IGFjY2VwdGVkLiBJdCBtdXN0IGJlIGFuIGFycmF5IG9mIHN0cmluZ3NcIiksbj10aGlzLlJsO3QuaGl2ZVRlY2hPcmRlcj1ufSx0LnByb3RvdHlwZS5wPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXM7dGhpcy5tKCkubm90aWNlKHRoaXMudStcInJlc29sdmluZyBcIit0KSx0aGlzLktsKHQpO3ZhciBpPW8uZGVmZXIoKSxyPXRoaXMuR2woKS52YWx1ZXMoKTswPT1yLmxlbmd0aCYmaS5yZWplY3QodS5zcih0LEkuc2gpKTt2YXIgbixzLGE9ITEsYz0hMSxoPTAscD1udWxsO3JldHVybiB1LlhpKGZ1bmN0aW9uKCl7cmV0dXJuIWEmJiFjJiZoPHIubGVuZ3RoJiYhbn0sZnVuY3Rpb24oKXt2YXIgaT1yW2grK107aS56bCgpO3ZhciB1O3JldHVybiB1PWkuV2woKSYmIXM/ZS4kbCh0KTpvLnJlc29sdmUobnVsbCksdS50aGVuKGZ1bmN0aW9uKHIpe251bGwhPXImJihzPXIpO3ZhciBuPWkuWWwoKTtyZXR1cm4gaS5pbml0U2Vzc2lvbih0LHMpLnRpbWVvdXQobixcIltcIitpLkFpKCkrXCJdIEVycm9yOiBpbml0aWFsaXphdGlvbiB0aW1lZCBvdXQgYWZ0ZXIgXCIrbitcIm1zXCIpLnRoZW4oZnVuY3Rpb24odCl7cD10LGUuWGwocCxpKSxhPSEwLCFpLldsKCkmJnMmJnMuUW4ucmVzZXQoKSxlLm0oKS5ub3RpY2UoZS51K1wiaW5pdGlhbGl6aW5nIFNlc3Npb246W1wiK3AuaWQrXCJdIFRpY2tldDpcIitwLnRpY2tldC50b1N0cmluZygpK1wiIEhpdmVUZWNoOltcIitwLnRlY2guQWkoKStcIl1cIiksby5yZXNvbHZlKCEwKX0sZnVuY3Rpb24ocil7ciBpbnN0YW5jZW9mIEVycm9yJiYocj1uZXcgayhDLlNoLHIubWVzc2FnZSksaS5abChyKSksci50aWNrZXRVcmw9dCxjPSFpLm9uRXJyb3IociksZS5tKCkuZGVidWcoZS51K1widGVjaCBcIitpLkFpKCkrXCI6IFwiK3IubWVzc2FnZSksby5yZXNvbHZlKCEwKX0pfSxmdW5jdGlvbih0KXtuPXQsby5yZXNvbHZlKCEwKX0pfSkudGhlbihmdW5jdGlvbigpe24/aS5yZWplY3QodS5zcih0LEkucGgsbikpOmM/aS5yZWplY3QodS5zcih0LEkuaGgpKTphP2kucmVzb2x2ZShwKTppLnJlamVjdCh1LnNyKHQsSS5zaCkpfSlbXCJjYXRjaFwiXShmdW5jdGlvbihlKXt3LkVycm9yTW9uaXRvci5XaSgpLl9oKGUpLGkucmVqZWN0KHUuc3IodCxJLm9oLGUudG9TdHJpbmcoKSkpfSkuZG9uZSgpLGkudnR9LHQucHJvdG90eXBlLiRsPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXM7cmV0dXJuIG0uSGl2ZS5SZXBvcnRpbmcoKS5pbml0U2Vzc2lvbih0LCExKS50aGVuKGZ1bmN0aW9uKGkpe3JldHVybiBlLm0oKS5kZWJ1ZyhlLnUrXCJ2ZXJpZmllZCB0aWNrZXQgXCIrdCksZS5obihpKSxpfSlbXCJjYXRjaFwiXShmdW5jdGlvbih0KXtyZXR1cm4gby5yZWplY3QoXCJUaWNrZXQgbm90IHZlcmlmaWVkLCBlcnJvcjogXCIrdC5tZXNzYWdlKX0pfSx0LnByb3RvdHlwZS5HbD1mdW5jdGlvbigpe3ZhciB0PUpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkodGhpcy5vcHRpb25zKCkuaGl2ZVRlY2hPcmRlcikpLGU9bmV3IG47Zm9yKHZhciBpIGluIHQpdGhpcy5rbC5oYXModFtpXSkmJmUuc2V0KHRbaV0sdGhpcy5rbC5nZXQodFtpXSkpO3JldHVybiBlfSx0LnByb3RvdHlwZS5LbD1mdW5jdGlvbih0KXt2YXIgZT13LkVycm9yTW9uaXRvci5XaSgpO3RyeXt2YXIgaT1uZXcgVC5hcDtpLktoKHQpLGkuYm4oKSYmaS5FbigpJiZpLmVzKCk/ZS5zZXRUYWdzKFtpLmJuKCksaS5FbigpLGkuZXMoKV0pOmUuX2godGhpcy51K1wiIFRpY2tldCBub3QgdmFsaWQsIHdlIGNvdWxkIG5vdCByZXNvbHZlIHRoZSB0cmlwbGUgcGFydG5lcklkL0N1c3RvbWVySWQvQ29udGVudElkOiBcIitpLmJuKCkrXCIvXCIraS5FbigpK1wiL1wiK2kuZXMoKSl9Y2F0Y2gocil7dGhpcy5tKCkud2Fybih0aGlzLnUrXCIgXCIrci5tZXNzYWdlLHIpLGUubm90aWZ5KHIpfX0sdC5wcm90b3R5cGUuaG49ZnVuY3Rpb24odCl7dmFyIGk9e2NvbW1WZXJzaW9uOmUudmVyc2lvbixwbHVnaW5OYW1lOnRoaXMuVCgpLHBsdWdpblZlcnNpb246dGhpcy5JKCkscGxheWVyVGVjaDp0aGlzLmh0KCkscGxheWVyVmVyc2lvbjp0aGlzLnEoKSx0ZWxlbWV0cnlJZDp0aGlzLnRkKCl9O3QuUW4uaG4oaSl9LHQucHJvdG90eXBlLnY9ZnVuY3Rpb24oKXt3aW5kb3cuSGl2ZVJlcXVlc3Q9WE1MSHR0cFJlcXVlc3QsdS5IaXZlUmVxdWVzdEZhY3RvcnkuY2xlYXIoKSxtLkhpdmUuUmVwb3J0aW5nKCkuY2xvc2UoKX0sdC5wcm90b3R5cGUuZWQ9ZnVuY3Rpb24odCl7dGhpcy5QbCYmdGhpcy5QbC50ZWNoPyh0LnNlc3Npb25JZD10aGlzLlBsLmlkLHRoaXMuUGwudGVjaC53bih0aGlzLlBsLHQpKTp0aGlzLkNsLnB1c2godCl9LHQucHJvdG90eXBlLnJkPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5DbDtyZXR1cm4gdGhpcy5DbD1uZXcgQXJyYXksdH0sdC5wcm90b3R5cGUuTWw9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLGU9d2luZG93O2UuYWRkRXZlbnRMaXN0ZW5lcj9lLmFkZEV2ZW50TGlzdGVuZXIoXCJiZWZvcmV1bmxvYWRcIixmdW5jdGlvbigpe3QubmQoITApfSwhMSk6ZS5hdHRhY2hFdmVudChcIm9uYmVmb3JldW5sb2FkXCIsZnVuY3Rpb24oKXt0Lm5kKCEwKX0pfSx0LnByb3RvdHlwZS5oPWZ1bmN0aW9uKHQpe3RoaXMubmQodCksdGhpcy5QbD1udWxsLHRoaXMuT2w9bmV3IEFycmF5LHRoaXMuQWw9MCx0aGlzLk5sPTAsdGhpcy5vZCgpfSx0LnByb3RvdHlwZS5YbD1mdW5jdGlvbih0LGUpe3QudGVjaD1lLHRoaXMuT2wucHVzaCh0KX0sdC5wcm90b3R5cGUuUj1mdW5jdGlvbih0KXtpZihudWxsPT10aGlzLlBsKXtmb3IodmFyIGU9dD90OnRoaXMuaXQoKSxpPTA7aTx0aGlzLk9sLmxlbmd0aDtpKyspe3ZhciByPXRoaXMuT2xbaV07aWYoci5zdChlKSlyZXR1cm4gdGhpcy5QbD1yLHRoaXMuUGwuUmk/dGhpcy5QbC5SaS5fby5zZCh0aGlzLlBsLnRpY2tldCk6dGhpcy5hZCgpLHRoaXMuT2w9bmV3IEFycmF5LHRoaXMuUGwudGVjaC5vbkFjdGl2ZVNlc3Npb24odGhpcy5QbCksdGhpcy5tKCkubm90aWNlKHRoaXMudStcImFjdGl2YXRpbmcgU2Vzc2lvbjpbXCIrdGhpcy5QbC5pZCtcIl0gVGlja2V0OlwiK3RoaXMuUGwudGlja2V0LnRvU3RyaW5nKCkrXCIgSGl2ZVRlY2g6W1wiK3RoaXMuUGwudGVjaC5BaSgpK1wiXVwiKSx0aGlzLmhkKCksITB9dGhpcy5tKCkud2Fybih0aGlzLnUrXCJDbG9zaW5nIHNlc3Npb25zIC0gdGhlIGFjdGl2ZSBzdHJlYW0gZG9lc24ndCBtYXRjaCBhbnkgaW5pdGlhbGl6ZWQgc2Vzc2lvbnNcIiksdGhpcy5tKCkud2Fybih0aGlzLnUrXCJBY3RpdmU6XCIrZStcIiAtIGluaXRpYWxpemVkOiBcIit0aGlzLk9sLmxlbmd0aCksdGhpcy5oKCl9cmV0dXJuITF9LHQucHJvdG90eXBlLkM9ZnVuY3Rpb24oKXtpZih0aGlzLlBsKXJldHVybiB0aGlzLlBsLmcoKX0sdC5wcm90b3R5cGUuYWQ9ZnVuY3Rpb24oKXt2YXIgdD0hMTt0aGlzLk9sLmZvckVhY2goZnVuY3Rpb24oZSl7ZS5SaSYmKHQ9ITApfSksdCYmbS5IaXZlLlJlcG9ydGluZygpLmNsb3NlKCl9LHQucHJvdG90eXBlLnBkPWZ1bmN0aW9uKCl7aWYobnVsbCE9dGhpcy5QbCl7aWYodGhpcy5QbC5zdCh0aGlzLml0KCkpKXJldHVybiEwO3RoaXMubSgpLndhcm4odGhpcy51K1wiU2Vzc2lvbiBzcmMgbWlzbWF0Y2g6IFwiK3RoaXMuaXQoKStcIiAhPSBcIit0aGlzLlBsLm1hbmlmZXN0KSx0aGlzLmgoKX1yZXR1cm4hMX0sdC5wcm90b3R5cGUubmQ9ZnVuY3Rpb24odCl7aWYobnVsbCE9dGhpcy5QbCl0aGlzLm0oKS5ub3RpY2UodGhpcy51K1wiU3RvcHBpbmcgc2Vzc2lvbiBbXCIrdGhpcy5QbC5pZCtcIl1cIiksdGhpcy5QbC5jbG9zZSh0KTtlbHNlIGlmKHRoaXMuT2wubGVuZ3RoPjApe3ZhciBlPXRoaXMuT2xbMF07dGhpcy5tKCkubm90aWNlKHRoaXMudStcIkF0dGVtcHQgdG8gc3RvcHBpbmcgc2Vzc2lvbiBbXCIrZS5pZCtcIl1cIiksZS5jbG9zZSh0KX19LHQucHJvdG90eXBlLmhkPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcztudWxsPT10aGlzLnVkJiYodGhpcy51ZD1zZXRJbnRlcnZhbChmdW5jdGlvbigpe3QubGQoKX0sdGhpcy5vcHRpb25zKCkuZmVlZGJhY2tQZXJpb2QpLHRoaXMubGQoKSl9LHQucHJvdG90eXBlLm9kPWZ1bmN0aW9uKCl7Y2xlYXJJbnRlcnZhbCh0aGlzLnVkKSx0aGlzLnVkPW51bGx9LHQucHJvdG90eXBlLmxkPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcztpZih0aGlzLnBkKCkpe2lmKCF0aGlzLnN0KCkpcmV0dXJuIHZvaWQgdGhpcy5oKCk7dmFyIGU9bmV3IHUuRmk7ZS5scj10aGlzLmdldEN1cnJlbnRUaW1lKCksZS5kcj10aGlzLm50KCksZS5ncj10aGlzLkFsLGUud2lkdGg9dGhpcy5vdCgpLndpZHRoLGUuaGVpZ2h0PXRoaXMub3QoKS5oZWlnaHQsZS5kZD10aGlzLmlzRnVsbHNjcmVlbigpLHRoaXMuUGwua2kodGhpcy5WbC5ocihlKSksdGhpcy5QbC50ZWNoLmZkKHRoaXMuUGwsZSkuZmFpbChmdW5jdGlvbihlKXt0Lm0oKS53YXJuKHQudStcInN0YXRzIGhhbmRsaW5nIGZhaWxlZFwiLGUpLHQub2QoKX0pfX0sdC5wcm90b3R5cGUuZ2Q9ZnVuY3Rpb24oKXt2YXIgdD10aGlzO3RyeXt1LllpLldpKHRoaXMubSgpKS4kaShmdW5jdGlvbihlKXt2YXIgaT10LnZkKCk7aSYmIWkuT2koKSYmKHQuXyhlP2QuRi5CLmpyOmQuRi5CLkhJRERFTiksdC5tKCkuZGVidWcoZT9cInZpc2libGVcIjpcImhpZGRlblwiKSl9KX1jYXRjaChlKXt3LkVycm9yTW9uaXRvci5XaSgpLl9oKFwiZXJyb3Igc2V0dGluZyB1cCB0aGUgdmlzaWJpbGl0eUNoYW5nZSBsaXN0ZW5lclwiLHtlcnJvcjplfSl9fSx0LnByb3RvdHlwZS5rPWZ1bmN0aW9uKHQpe3RoaXMucGQoKSYmdGhpcy5ObDw9MCYmKHRoaXMuTmw9RGF0ZS5ub3coKSwodm9pZCAwPT10fHx0KSYmdGhpcy5fKGQuRi5CLkxyKSl9LHQucHJvdG90eXBlLkc9ZnVuY3Rpb24oKXt2YXIgdD0wPT10aGlzLkFsO2lmKHRoaXMuTmw+MCl7dmFyIGU9RGF0ZS5ub3coKS10aGlzLk5sO3JldHVybiB0aGlzLkFsKz1lLHRoaXMubSgpLmRlYnVnKHRoaXMudStcInJlcG9ydGluZyBuZXcgYnVmZmVyaW5nIGV2ZW50IG9mIFwiK2UpLHRoaXMuTmw9MCx0JiZ0aGlzLmxkKCksITB9cmV0dXJuITF9LHQucHJvdG90eXBlLm9uRXJyb3I9ZnVuY3Rpb24odCxlLGkpe3ZvaWQgMD09PWkmJihpPSEwKSx0aGlzLl8oZC5GLkIuRVJST1Ise2NvZGU6LTEsXCJwbGF5ZXItY29kZVwiOnR9KSxpJiZ0aGlzLmgoKX0sdC5wcm90b3R5cGUuXz1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMscj10aGlzLnZkKCk7bnVsbD09cnx8ciE9dGhpcy5QbCYmci50ZWNoLkFpKCk9PT1FW0UuSGl2ZUphdmFdfHxyLnRlY2gueWQocix0LGUpLmZhaWwoZnVuY3Rpb24odCl7aS5tKCkud2FybihpLnUrXCJlcnJvciBpbiBmb3J3YXJkaW5nIHBsYXllciBldmVudCB0byB0ZWNoXCIsdCl9KX0sdC5wcm90b3R5cGUudmQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5QbD90aGlzLlBsOnRoaXMuT2wmJnRoaXMuT2wubGVuZ3RoPjA/dGhpcy5PbFswXTp2b2lkIDB9LHQucHJvdG90eXBlLm1kPWZ1bmN0aW9uKCl7dGhpcy54bD0wfSx0LnByb3RvdHlwZS53ZD1mdW5jdGlvbih0LGUpe3RoaXMubWQoKTt2YXIgaT03LHI9Njt0aGlzLnhsKz10PDw0KmksZSYmMD09PXQmJih0aGlzLnhsKz0xPDw0KihyLUVbZS5BaSgpXSkpLHQ+MCYmdy5FcnJvck1vbml0b3IuV2koKS5faCh0aGlzLnUrXCJTdGF0dXMgQ29kZSBFcnJvcjogXCIrUlt0XSl9LHQucHJvdG90eXBlLlBoPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMueGx9LHQucHJvdG90eXBlLnRkPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMub3B0aW9ucygpLnRlbGVtZXRyeUlkfSx0fSgpO3QuUGx1Z2luPXJ9KFA9ZS5wdHx8KGUucHQ9e30pKSxzLkZyYW1ld29yay5RZShuZXcgZi5UZCkscy5GcmFtZXdvcmsuR2UoXCJwZWVyMFwiLG5ldyB2LlNkKSxzLkZyYW1ld29yay56ZShcInBlZXIwXCIpLHdpbmRvdy5IaXZlUmVxdWVzdEZhY3Rvcnk9dS5IaXZlUmVxdWVzdEZhY3Rvcnl9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcj1pKDQ1KSxuPWkoNyksbz1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCl7dGhpcy5yZWFkeVN0YXRlPTMsdGhpcy5zdGF0dXM9MCx0JiYodGhpcy5zZXNzaW9uSWQ9dCl9cmV0dXJuIHQuTGg9ZnVuY3Rpb24oZSl7dC5tPWV9LHQucmVnaXN0ZXI9ZnVuY3Rpb24oZSxpKXt0LmJkW2VdPWl9LHQucHJvdG90eXBlLkVkPWZ1bmN0aW9uKGUpe3RoaXMuc2Vzc2lvbklkfHwodGhpcy5zZXNzaW9uSWQ9dC5iZFtlXSl9LHQucHJvdG90eXBlLm9wZW49ZnVuY3Rpb24odCxlLGkpe3ZvaWQgMD09PWkmJihpPSExKSx0aGlzLm1ldGhvZD10LHRoaXMudXJsPWUsdGhpcy5JZD1pfSx0LnByb3RvdHlwZS5nZXRBbGxSZXNwb25zZUhlYWRlcnM9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5SZH0sdC5wcm90b3R5cGUuZ2V0UmVzcG9uc2VIZWFkZXI9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5nZXRBbGxSZXNwb25zZUhlYWRlcnMoKTtpZihlKXt2YXIgaT1bXSxyPWUuc3BsaXQoXCJcXG5cIik7cmV0dXJuIHIuZm9yRWFjaChmdW5jdGlvbih0KXt2YXIgZT10LnNwbGl0KFwiOlwiKTtpW2VbMF1dPWVbMV19KSxpW3RdfX0sdC5wcm90b3R5cGUuc2VuZD1mdW5jdGlvbigpe2lmKHQubSYmdC5tLmRlYnVnKHRoaXMubWV0aG9kK1wiIFwiK3RoaXMudXJsKSwhdGhpcy5zZXNzaW9uSWQpe3ZhciBlPU9iamVjdC5rZXlzKHQuYmQpO2UubGVuZ3RoPjAmJih0aGlzLnNlc3Npb25JZD10LmJkW2VbMF1dKX12YXIgaT10aGlzLG89bmV3IFhNTEh0dHBSZXF1ZXN0OzA9PT10aGlzLnVybC5pbmRleE9mKFwiLy9cIikmJih0aGlzLnVybD1sb2NhdGlvbi5wcm90b2NvbCt0aGlzLnVybCk7dmFyIHM9bi5ycihyLkNkLmtkLHIuQ2QuVG8sci5DZC5PZCx0aGlzLnNlc3Npb25JZCxlbmNvZGVVUklDb21wb25lbnQodGhpcy51cmwpKTtvLm9wZW4oXCJHRVRcIixzKSx0aGlzLnJlc3BvbnNlVHlwZSYmKG8ucmVzcG9uc2VUeXBlPXRoaXMucmVzcG9uc2VUeXBlKSxvLm9ucmVhZHlzdGF0ZWNoYW5nZT1mdW5jdGlvbigpe30sby5vbmxvYWQ9ZnVuY3Rpb24oKXtpZig0PT09by5yZWFkeVN0YXRlKXRyeXtpLlJkPW8uZ2V0QWxsUmVzcG9uc2VIZWFkZXJzKCksaS5yZXNwb25zZT1vLnJlc3BvbnNlO3ZhciBlPW8ucmVzcG9uc2UuYnl0ZUxlbmd0aDtcImFycmF5YnVmZmVyXCIhPT1vLnJlc3BvbnNlVHlwZSYmKGkucmVzcG9uc2VUZXh0PW8ucmVzcG9uc2UpLGkucmVhZHlTdGF0ZT00LGkuc3RhdHVzPW8uc3RhdHVzLGkub25wcm9ncmVzcyh7bGVuZ3RoQ29tcHV0YWJsZTohMCxsb2FkZWQ6ZSx0b3RhbDplfSksaS5vbnJlYWR5c3RhdGVjaGFuZ2Uoe3R5cGU6XCJsb2FkZW5kXCIsdGFyZ2V0OmksY3VycmVudFRhcmdldDppLGJ1YmJsZXM6ITEsY2FuY2VsYWJsZTohMSxsZW5ndGhDb21wdXRhYmxlOiExLGxvYWRlZDplLHRvdGFsOmV9KSxpLm9ubG9hZCgpLGkub25sb2FkZW5kKHt0eXBlOlwibG9hZGVuZFwiLHRhcmdldDppLGN1cnJlbnRUYXJnZXQ6aSxidWJibGVzOiExLGNhbmNlbGFibGU6ITEsbGVuZ3RoQ29tcHV0YWJsZTohMSxsb2FkZWQ6ZSx0b3RhbDowfSl9Y2F0Y2gocil7dC5tJiZ0Lm0ud2FybihyKX19LG8ub25lcnJvcj1mdW5jdGlvbihlKXt0Lm0mJnQubS53YXJuKFwib25FcnJvcjogXCIrSlNPTi5zdHJpbmdpZnkoZSkpLGkub25lcnJvcihlKX0sby5vbmFib3J0PWZ1bmN0aW9uKGUpe3QubSYmdC5tLndhcm4oXCJvbkFib3J0OiBcIitKU09OLnN0cmluZ2lmeShlKSl9LG8uc2VuZCgpfSx0LnByb3RvdHlwZS5hYm9ydD1mdW5jdGlvbigpe30sdC5wcm90b3R5cGUub25sb2FkPWZ1bmN0aW9uKCl7fSx0LnByb3RvdHlwZS5vbmxvYWRlbmQ9ZnVuY3Rpb24odCl7fSx0LnByb3RvdHlwZS5vbmVycm9yPWZ1bmN0aW9uKHQpe30sdC5wcm90b3R5cGUub25wcm9ncmVzcz1mdW5jdGlvbih0KXt9LHQucHJvdG90eXBlLm9ucmVhZHlzdGF0ZWNoYW5nZT1mdW5jdGlvbih0KXt9LHR9KCk7by5iZD17fSxlLlRpPW99LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcj1pKDIpLG49aSg1KSxvPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdC5SZXBvcnRpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdC5hcHA9XCJTVEFUU1wiLHIuRnJhbWV3b3JrLnJlc29sdmUobi5naS51aSl9LHQuWG89ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hcHB9LHQuZ2V0VmVyc2lvbj1mdW5jdGlvbigpe3JldHVybiB0aGlzLnZlcnNpb259LHR9KCk7by52ZXJzaW9uPVwiMy4yLjBcIixlLkhpdmU9b30sZnVuY3Rpb24odCxlLGkpe3ZhciByOyFmdW5jdGlvbihuLG8pe1widXNlIHN0cmljdFwiO3ZhciBzPVwiMC43LjEyXCIsYT1cIlwiLGM9XCI/XCIsaD1cImZ1bmN0aW9uXCIscD1cInVuZGVmaW5lZFwiLHU9XCJvYmplY3RcIixsPVwic3RyaW5nXCIsZD1cIm1ham9yXCIsZj1cIm1vZGVsXCIsZz1cIm5hbWVcIix2PVwidHlwZVwiLHk9XCJ2ZW5kb3JcIixtPVwidmVyc2lvblwiLHc9XCJhcmNoaXRlY3R1cmVcIixUPVwiY29uc29sZVwiLFM9XCJtb2JpbGVcIixiPVwidGFibGV0XCIsRT1cInNtYXJ0dHZcIixJPVwid2VhcmFibGVcIixSPVwiZW1iZWRkZWRcIixrPXtleHRlbmQ6ZnVuY3Rpb24odCxlKXt2YXIgaT17fTtmb3IodmFyIHIgaW4gdCllW3JdJiZlW3JdLmxlbmd0aCUyPT09MD9pW3JdPWVbcl0uY29uY2F0KHRbcl0pOmlbcl09dFtyXTtyZXR1cm4gaX0saGFzOmZ1bmN0aW9uKHQsZSl7cmV0dXJuXCJzdHJpbmdcIj09dHlwZW9mIHQmJmUudG9Mb3dlckNhc2UoKS5pbmRleE9mKHQudG9Mb3dlckNhc2UoKSkhPT0tMX0sUGQ6ZnVuY3Rpb24odCl7cmV0dXJuIHQudG9Mb3dlckNhc2UoKX0sQWQ6ZnVuY3Rpb24odCl7cmV0dXJuIHR5cGVvZiB0PT09bD90LnJlcGxhY2UoL1teXFxkXFwuXS9nLFwiXCIpLnNwbGl0KFwiLlwiKVswXTpvfSx0cmltOmZ1bmN0aW9uKHQpe3JldHVybiB0LnJlcGxhY2UoL15bXFxzXFx1RkVGRlxceEEwXSt8W1xcc1xcdUZFRkZcXHhBMF0rJC9nLFwiXCIpfX0sQz17TmQ6ZnVuY3Rpb24oKXtmb3IodmFyIHQsZSxpLHIsbixzLGEsYz0wLGw9YXJndW1lbnRzO2M8bC5sZW5ndGgmJiFzOyl7dmFyIGQ9bFtjXSxmPWxbYysxXTtpZih0eXBlb2YgdD09PXApe3Q9e307Zm9yKHIgaW4gZilmLmhhc093blByb3BlcnR5KHIpJiYobj1mW3JdLHR5cGVvZiBuPT09dT90W25bMF1dPW86dFtuXT1vKX1mb3IoZT1pPTA7ZTxkLmxlbmd0aCYmIXM7KWlmKHM9ZFtlKytdLmV4ZWModGhpcy54ZCgpKSlmb3Iocj0wO3I8Zi5sZW5ndGg7cisrKWE9c1srK2ldLG49ZltyXSx0eXBlb2Ygbj09PXUmJm4ubGVuZ3RoPjA/Mj09bi5sZW5ndGg/dHlwZW9mIG5bMV09PWg/dFtuWzBdXT1uWzFdLmNhbGwodGhpcyxhKTp0W25bMF1dPW5bMV06Mz09bi5sZW5ndGg/dHlwZW9mIG5bMV0hPT1ofHxuWzFdLmV4ZWMmJm5bMV0udGVzdD90W25bMF1dPWE/YS5yZXBsYWNlKG5bMV0sblsyXSk6bzp0W25bMF1dPWE/blsxXS5jYWxsKHRoaXMsYSxuWzJdKTpvOjQ9PW4ubGVuZ3RoJiYodFtuWzBdXT1hP25bM10uY2FsbCh0aGlzLGEucmVwbGFjZShuWzFdLG5bMl0pKTpvKTp0W25dPWE/YTpvO2MrPTJ9cmV0dXJuIHR9LGFjOmZ1bmN0aW9uKHQsZSl7Zm9yKHZhciBpIGluIGUpaWYodHlwZW9mIGVbaV09PT11JiZlW2ldLmxlbmd0aD4wKXtmb3IodmFyIHI9MDtyPGVbaV0ubGVuZ3RoO3IrKylpZihrLmhhcyhlW2ldW3JdLHQpKXJldHVybiBpPT09Yz9vOml9ZWxzZSBpZihrLmhhcyhlW2ldLHQpKXJldHVybiBpPT09Yz9vOmk7cmV0dXJuIHR9fSxPPXt0aTp7QmQ6e3ZlcnNpb246e1wiMS4wXCI6XCIvOFwiLDEuMjpcIi8xXCIsMS4zOlwiLzNcIixcIjIuMFwiOlwiLzQxMlwiLFwiMi4wLjJcIjpcIi80MTZcIixcIjIuMC4zXCI6XCIvNDE3XCIsXCIyLjAuNFwiOlwiLzQxOVwiLEtwOlwiL1wifX19LEZkOntfZDp7RGQ6e0hkOltcIlNEXCIsXCJLRlwiXX19LExkOntEZDp7TWQ6XCI3MzczS1RcIn0sdmVuZG9yOntqZDpcIkFQQVwiLFVkOlwiU3ByaW50XCJ9fX0sb3M6e1ZkOnt2ZXJzaW9uOntRZDpcIjQuOTBcIixcIk5UIDMuMTFcIjpcIk5UMy41MVwiLFwiTlQgNC4wXCI6XCJOVDQuMFwiLDIwMDA6XCJOVCA1LjBcIixxZDpbXCJOVCA1LjFcIixcIk5UIDUuMlwiXSxKZDpcIk5UIDYuMFwiLDc6XCJOVCA2LjFcIiw4OlwiTlQgNi4yXCIsOC4xOlwiTlQgNi4zXCIsMTA6W1wiTlQgNi40XCIsXCJOVCAxMC4wXCJdLEtkOlwiQVJNXCJ9fX19LFA9e3RpOltbLyhvcGVyYVxcc21pbmkpXFwvKFtcXHdcXC4tXSspL2ksLyhvcGVyYVxcc1ttb2JpbGV0YWJdKykuK3ZlcnNpb25cXC8oW1xcd1xcLi1dKykvaSwvKG9wZXJhKS4rdmVyc2lvblxcLyhbXFx3XFwuXSspL2ksLyhvcGVyYSlbXFwvXFxzXSsoW1xcd1xcLl0rKS9pXSxbZyxtXSxbLyhvcGlvcylbXFwvXFxzXSsoW1xcd1xcLl0rKS9pXSxbW2csXCJPcGVyYSBNaW5pXCJdLG1dLFsvXFxzKG9wcilcXC8oW1xcd1xcLl0rKS9pXSxbW2csXCJPcGVyYVwiXSxtXSxbLyhraW5kbGUpXFwvKFtcXHdcXC5dKykvaSwvKGx1bmFzY2FwZXxtYXh0aG9ufG5ldGZyb250fGphc21pbmV8YmxhemVyKVtcXC9cXHNdPyhbXFx3XFwuXSspKi9pLC8oYXZhbnRcXHN8aWVtb2JpbGV8c2xpbXxiYWlkdSkoPzpicm93c2VyKT9bXFwvXFxzXT8oW1xcd1xcLl0qKS9pLC8oPzptc3xcXCgpKGllKVxccyhbXFx3XFwuXSspL2ksLyhyZWtvbnEpXFwvKFtcXHdcXC5dKykqL2ksLyhjaHJvbWl1bXxmbG9ja3xyb2NrbWVsdHxtaWRvcml8ZXBpcGhhbnl8c2lsa3xza3lmaXJlfG92aWJyb3dzZXJ8Ym9sdHxpcm9ufHZpdmFsZGl8aXJpZGl1bXxwaGFudG9tanMpXFwvKFtcXHdcXC4tXSspL2ldLFtnLG1dLFsvKHRyaWRlbnQpLitydls6XFxzXShbXFx3XFwuXSspLitsaWtlXFxzZ2Vja28vaV0sW1tnLFwiSUVcIl0sbV0sWy8oZWRnZSlcXC8oKFxcZCspP1tcXHdcXC5dKykvaV0sW2csbV0sWy8oeWFicm93c2VyKVxcLyhbXFx3XFwuXSspL2ldLFtbZyxcIllhbmRleFwiXSxtXSxbLyhjb21vZG9fZHJhZ29uKVxcLyhbXFx3XFwuXSspL2ldLFtbZywvXy9nLFwiIFwiXSxtXSxbLyhtaWNyb21lc3NlbmdlcilcXC8oW1xcd1xcLl0rKS9pXSxbW2csXCJXZUNoYXRcIl0sbV0sWy94aWFvbWlcXC9taXVpYnJvd3NlclxcLyhbXFx3XFwuXSspL2ldLFttLFtnLFwiTUlVSSBCcm93c2VyXCJdXSxbL1xcc3d2XFwpLisoY2hyb21lKVxcLyhbXFx3XFwuXSspL2ldLFtbZywvKC4rKS8sXCIkMSBXZWJWaWV3XCJdLG1dLFsvYW5kcm9pZC4rc2Ftc3VuZ2Jyb3dzZXJcXC8oW1xcd1xcLl0rKS9pLC9hbmRyb2lkLit2ZXJzaW9uXFwvKFtcXHdcXC5dKylcXHMrKD86bW9iaWxlXFxzP3NhZmFyaXxzYWZhcmkpKi9pXSxbbSxbZyxcIkFuZHJvaWQgQnJvd3NlclwiXV0sWy8oY2hyb21lfG9tbml3ZWJ8YXJvcmF8W3RpemVub2thXXs1fVxccz9icm93c2VyKVxcL3Y/KFtcXHdcXC5dKykvaSwvKHFxYnJvd3NlcilbXFwvXFxzXT8oW1xcd1xcLl0rKS9pXSxbZyxtXSxbLyh1Y1xccz9icm93c2VyKVtcXC9cXHNdPyhbXFx3XFwuXSspL2ksL3Vjd2ViLisodWNicm93c2VyKVtcXC9cXHNdPyhbXFx3XFwuXSspL2ksL2p1Yy4rKHVjd2ViKVtcXC9cXHNdPyhbXFx3XFwuXSspL2ldLFtbZyxcIlVDQnJvd3NlclwiXSxtXSxbLyhkb2xmaW4pXFwvKFtcXHdcXC5dKykvaV0sW1tnLFwiRG9scGhpblwiXSxtXSxbLygoPzphbmRyb2lkLispY3Jtb3xjcmlvcylcXC8oW1xcd1xcLl0rKS9pXSxbW2csXCJDaHJvbWVcIl0sbV0sWy87ZmJhdlxcLyhbXFx3XFwuXSspOy9pXSxbbSxbZyxcIkZhY2Vib29rXCJdXSxbL2Z4aW9zXFwvKFtcXHdcXC4tXSspL2ldLFttLFtnLFwiRmlyZWZveFwiXV0sWy92ZXJzaW9uXFwvKFtcXHdcXC5dKykuKz9tb2JpbGVcXC9cXHcrXFxzKHNhZmFyaSkvaV0sW20sW2csXCJNb2JpbGUgU2FmYXJpXCJdXSxbL3ZlcnNpb25cXC8oW1xcd1xcLl0rKS4rPyhtb2JpbGVcXHM/c2FmYXJpfHNhZmFyaSkvaV0sW20sZ10sWy93ZWJraXQuKz8obW9iaWxlXFxzP3NhZmFyaXxzYWZhcmkpKFxcL1tcXHdcXC5dKykvaV0sW2csW20sQy5hYyxPLnRpLkJkLnZlcnNpb25dXSxbLyhrb25xdWVyb3IpXFwvKFtcXHdcXC5dKykvaSwvKHdlYmtpdHxraHRtbClcXC8oW1xcd1xcLl0rKS9pXSxbZyxtXSxbLyhuYXZpZ2F0b3J8bmV0c2NhcGUpXFwvKFtcXHdcXC4tXSspL2ldLFtbZyxcIk5ldHNjYXBlXCJdLG1dLFsvKHN3aWZ0Zm94KS9pLC8oaWNlZHJhZ29ufGljZXdlYXNlbHxjYW1pbm98Y2hpbWVyYXxmZW5uZWN8bWFlbW9cXHNicm93c2VyfG1pbmltb3xjb25rZXJvcilbXFwvXFxzXT8oW1xcd1xcLlxcK10rKS9pLC8oZmlyZWZveHxzZWFtb25rZXl8ay1tZWxlb258aWNlY2F0fGljZWFwZXxmaXJlYmlyZHxwaG9lbml4KVxcLyhbXFx3XFwuLV0rKS9pLC8obW96aWxsYSlcXC8oW1xcd1xcLl0rKS4rcnZcXDouK2dlY2tvXFwvXFxkKy9pLC8ocG9sYXJpc3xseW54fGRpbGxvfGljYWJ8ZG9yaXN8YW1heWF8dzNtfG5ldHN1cmZ8c2xlaXBuaXIpW1xcL1xcc10/KFtcXHdcXC5dKykvaSwvKGxpbmtzKVxcc1xcKChbXFx3XFwuXSspL2ksLyhnb2Jyb3dzZXIpXFwvPyhbXFx3XFwuXSspKi9pLC8oaWNlXFxzP2Jyb3dzZXIpXFwvdj8oW1xcd1xcLl9dKykvaSwvKG1vc2FpYylbXFwvXFxzXShbXFx3XFwuXSspL2ldLFtnLG1dXSxHZDpbWy8oPzooYW1kfHgoPzooPzo4Nnw2NClbXy1dKT98d293fHdpbik2NClbO1xcKV0vaV0sW1t3LFwiYW1kNjRcIl1dLFsvKGlhMzIoPz07KSkvaV0sW1t3LGsuUGRdXSxbLygoPzppWzM0Nl18eCk4NilbO1xcKV0vaV0sW1t3LFwiaWEzMlwiXV0sWy93aW5kb3dzXFxzKGNlfG1vYmlsZSk7XFxzcHBjOy9pXSxbW3csXCJhcm1cIl1dLFsvKCg/OnBwY3xwb3dlcnBjKSg/OjY0KT8pKD86XFxzbWFjfDt8XFwpKS9pXSxbW3csL293ZXIvLFwiXCIsay5QZF1dLFsvKHN1bjRcXHcpWztcXCldL2ldLFtbdyxcInNwYXJjXCJdXSxbLygoPzphdnIzMnxpYTY0KD89OykpfDY4ayg/PVxcKSl8YXJtKD86NjR8KD89dlxcZCs7KSl8KD89YXRtZWxcXHMpYXZyfCg/OmlyaXh8bWlwc3xzcGFyYykoPzo2NCk/KD89Oyl8cGEtcmlzYykvaV0sW1t3LGsuUGRdXV0sRmQ6W1svXFwoKGlwYWR8cGxheWJvb2spO1tcXHdcXHNcXCk7LV0rKHJpbXxhcHBsZSkvaV0sW2YseSxbdixiXV0sWy9hcHBsZWNvcmVtZWRpYVxcL1tcXHdcXC5dKyBcXCgoaXBhZCkvXSxbZixbeSxcIkFwcGxlXCJdLFt2LGJdXSxbLyhhcHBsZVxcc3swLDF9dHYpL2ldLFtbZixcIkFwcGxlIFRWXCJdLFt5LFwiQXBwbGVcIl1dLFsvKGFyY2hvcylcXHMoZ2FtZXBhZDI/KS9pLC8oaHApLisodG91Y2hwYWQpL2ksLyhocCkuKyh0YWJsZXQpL2ksLyhraW5kbGUpXFwvKFtcXHdcXC5dKykvaSwvXFxzKG5vb2spW1xcd1xcc10rYnVpbGRcXC8oXFx3KykvaSwvKGRlbGwpXFxzKHN0cmVhW2twclxcc1xcZF0qW1xcZGtvXSkvaV0sW3ksZixbdixiXV0sWy8oa2ZbQS16XSspXFxzYnVpbGRcXC9bXFx3XFwuXSsuKnNpbGtcXC8vaV0sW2YsW3ksXCJBbWF6b25cIl0sW3YsYl1dLFsvKHNkfGtmKVswMzQ5aGlqb3JzdHV3XStcXHNidWlsZFxcL1tcXHdcXC5dKy4qc2lsa1xcLy9pXSxbW2YsQy5hYyxPLkZkLl9kLkRkXSxbeSxcIkFtYXpvblwiXSxbdixTXV0sWy9cXCgoaXBbaG9uZWR8XFxzXFx3Kl0rKTsuKyhhcHBsZSkvaV0sW2YseSxbdixTXV0sWy9cXCgoaXBbaG9uZWR8XFxzXFx3Kl0rKTsvaV0sW2YsW3ksXCJBcHBsZVwiXSxbdixTXV0sWy8oYmxhY2tiZXJyeSlbXFxzLV0/KFxcdyspL2ksLyhibGFja2JlcnJ5fGJlbnF8cGFsbSg/PVxcLSl8c29ueWVyaWNzc29ufGFjZXJ8YXN1c3xkZWxsfGh1YXdlaXxtZWl6dXxtb3Rvcm9sYXxwb2x5dHJvbilbXFxzXy1dPyhbXFx3LV0rKSovaSwvKGhwKVxccyhbXFx3XFxzXStcXHcpL2ksLyhhc3VzKS0/KFxcdyspL2ldLFt5LGYsW3YsU11dLFsvXFwoYmIxMDtcXHMoXFx3KykvaV0sW2YsW3ksXCJCbGFja0JlcnJ5XCJdLFt2LFNdXSxbL2FuZHJvaWQuKyh0cmFuc2ZvW3ByaW1lXFxzXXs0LDEwfVxcc1xcdyt8ZWVlcGN8c2xpZGVyXFxzXFx3K3xuZXh1cyA3fHBhZGZvbmUpL2ldLFtmLFt5LFwiQXN1c1wiXSxbdixiXV0sWy8oc29ueSlcXHModGFibGV0XFxzW3BzXSlcXHNidWlsZFxcLy9pLC8oc29ueSk/KD86c2dwLispXFxzYnVpbGRcXC8vaV0sW1t5LFwiU29ueVwiXSxbZixcIlhwZXJpYSBUYWJsZXRcIl0sW3YsYl1dLFsvKD86c29ueSk/KD86KD86KD86Y3xkKVxcZHs0fSl8KD86c29bLWxdLispKVxcc2J1aWxkXFwvL2ldLFtbeSxcIlNvbnlcIl0sW2YsXCJYcGVyaWEgUGhvbmVcIl0sW3YsU11dLFsvXFxzKG91eWEpXFxzL2ksLyhuaW50ZW5kbylcXHMoW3dpZHMzdV0rKS9pXSxbeSxmLFt2LFRdXSxbL2FuZHJvaWQuKztcXHMoc2hpZWxkKVxcc2J1aWxkL2ldLFtmLFt5LFwiTnZpZGlhXCJdLFt2LFRdXSxbLyhwbGF5c3RhdGlvblxcc1szNHBvcnRhYmxldmldKykvaV0sW2YsW3ksXCJTb255XCJdLFt2LFRdXSxbLyhzcHJpbnRcXHMoXFx3KykpL2ldLFtbeSxDLmFjLE8uRmQuTGQudmVuZG9yXSxbZixDLmFjLE8uRmQuTGQuRGRdLFt2LFNdXSxbLyhsZW5vdm8pXFxzPyhTKD86NTAwMHw2MDAwKSsoPzpbLV1bXFx3K10pKS9pXSxbeSxmLFt2LGJdXSxbLyhodGMpWztfXFxzLV0rKFtcXHdcXHNdKyg/PVxcKSl8XFx3KykqL2ksLyh6dGUpLShcXHcrKSovaSwvKGFsY2F0ZWx8Z2Vla3NwaG9uZXxodWF3ZWl8bGVub3ZvfG5leGlhbnxwYW5hc29uaWN8KD89O1xccylzb255KVtfXFxzLV0/KFtcXHctXSspKi9pXSxbeSxbZiwvXy9nLFwiIFwiXSxbdixTXV0sWy8obmV4dXNcXHM5KS9pXSxbZixbeSxcIkhUQ1wiXSxbdixiXV0sWy8obmV4dXNcXHM2cCkvaV0sW2YsW3ksXCJIdWF3ZWlcIl0sW3YsU11dLFsvKG1pY3Jvc29mdCk7XFxzKGx1bWlhW1xcc1xcd10rKS9pXSxbeSxmLFt2LFNdXSxbL1tcXHNcXCg7XSh4Ym94KD86XFxzb25lKT8pW1xcc1xcKTtdL2ldLFtmLFt5LFwiTWljcm9zb2Z0XCJdLFt2LFRdXSxbLyhraW5cXC5bb25ldHddezN9KS9pXSxbW2YsL1xcLi9nLFwiIFwiXSxbeSxcIk1pY3Jvc29mdFwiXSxbdixTXV0sWy9cXHMobWlsZXN0b25lfGRyb2lkKD86WzItNHhdfFxccyg/OmJpb25pY3x4Mnxwcm98cmF6cikpPyg6P1xcczRnKT8pW1xcd1xcc10rYnVpbGRcXC8vaSwvbW90W1xccy1dPyhcXHcrKSovaSwvKFhUXFxkezMsNH0pIGJ1aWxkXFwvL2ksLyhuZXh1c1xcczYpL2ldLFtmLFt5LFwiTW90b3JvbGFcIl0sW3YsU11dLFsvYW5kcm9pZC4rXFxzKG16NjBcXGR8eG9vbVtcXHMyXXswLDJ9KVxcc2J1aWxkXFwvL2ldLFtmLFt5LFwiTW90b3JvbGFcIl0sW3YsYl1dLFsvaGJidHZcXC9cXGQrXFwuXFxkK1xcLlxcZCtcXHMrXFwoW1xcd1xcc10qO1xccyooXFx3W147XSopOyhbXjtdKikvaV0sW1t5LGsudHJpbV0sW2Ysay50cmltXSxbdixFXV0sWy9oYmJ0di4rbWFwbGU7KFxcZCspL2ldLFtbZiwvXi8sXCJTbWFydFRWXCJdLFt5LFwiU2Ftc3VuZ1wiXSxbdixFXV0sWy9cXChkdHZbXFwpO10uKyhhcXVvcykvaV0sW2YsW3ksXCJTaGFycFwiXSxbdixFXV0sWy9hbmRyb2lkLisoKHNjaC1pWzg5XTBcXGR8c2h3LW0zODBzfGd0LXBcXGR7NH18Z3QtblxcZCt8c2doLXQ4WzU2XTl8bmV4dXMgMTApKS9pLC8oKFNNLVRcXHcrKSkvaV0sW1t5LFwiU2Ftc3VuZ1wiXSxmLFt2LGJdXSxbL3NtYXJ0LXR2Lisoc2Ftc3VuZykvaV0sW3ksW3YsRV0sZl0sWy8oKHNbY2dwXWgtXFx3K3xndC1cXHcrfGdhbGF4eVxcc25leHVzfHNtLVxcd1tcXHdcXGRdKykpL2ksLyhzYW1bc3VuZ10qKVtcXHMtXSooXFx3Ky0/W1xcdy1dKikqL2ksL3NlYy0oKHNnaFxcdyspKS9pXSxbW3ksXCJTYW1zdW5nXCJdLGYsW3YsU11dLFsvc2llLShcXHcrKSovaV0sW2YsW3ksXCJTaWVtZW5zXCJdLFt2LFNdXSxbLyhtYWVtb3xub2tpYSkuKihuOTAwfGx1bWlhXFxzXFxkKykvaSwvKG5va2lhKVtcXHNfLV0/KFtcXHctXSspKi9pXSxbW3ksXCJOb2tpYVwiXSxmLFt2LFNdXSxbL2FuZHJvaWRcXHMzXFwuW1xcc1xcdzstXXsxMH0oYVxcZHszfSkvaV0sW2YsW3ksXCJBY2VyXCJdLFt2LGJdXSxbL2FuZHJvaWRcXHMzXFwuW1xcc1xcdzstXXsxMH0obGc/KS0oWzA2Y3Y5XXszLDR9KS9pXSxbW3ksXCJMR1wiXSxmLFt2LGJdXSxbLyhsZykgbmV0Y2FzdFxcLnR2L2ldLFt5LGYsW3YsRV1dLFsvKG5leHVzXFxzWzQ1XSkvaSwvbGdbZTtcXHNcXC8tXSsoXFx3KykqL2ldLFtmLFt5LFwiTEdcIl0sW3YsU11dLFsvYW5kcm9pZC4rKGlkZWF0YWJbYS16MC05XFwtXFxzXSspL2ldLFtmLFt5LFwiTGVub3ZvXCJdLFt2LGJdXSxbL2xpbnV4Oy4rKChqb2xsYSkpOy9pXSxbeSxmLFt2LFNdXSxbLygocGViYmxlKSlhcHBcXC9bXFxkXFwuXStcXHMvaV0sW3ksZixbdixJXV0sWy9hbmRyb2lkLis7XFxzKGdsYXNzKVxcc1xcZC9pXSxbZixbeSxcIkdvb2dsZVwiXSxbdixJXV0sWy9hbmRyb2lkLisoXFx3KylcXHMrYnVpbGRcXC9obVxcMS9pLC9hbmRyb2lkLisoaG1bXFxzXFwtX10qbm90ZT9bXFxzX10qKD86XFxkXFx3KT8pXFxzK2J1aWxkL2ksL2FuZHJvaWQuKyhtaVtcXHNcXC1fXSooPzpvbmV8b25lW1xcc19dcGx1c3xub3RlIGx0ZSk/W1xcc19dKig/OlxcZFxcdyk/KVxccytidWlsZC9pXSxbW2YsL18vZyxcIiBcIl0sW3ksXCJYaWFvbWlcIl0sW3YsU11dLFsvYW5kcm9pZC4rYTAwMCgxKVxccytidWlsZC9pXSxbZixbeSxcIk9uZVBsdXNcIl0sW3YsU11dLFsvXFxzKHRhYmxldClbO1xcL10vaSwvXFxzKG1vYmlsZSkoPzpbO1xcL118XFxzc2FmYXJpKS9pXSxbW3Ysay5QZF0seSxmXV0semQ6W1svd2luZG93cy4rXFxzZWRnZVxcLyhbXFx3XFwuXSspL2ldLFttLFtnLFwiRWRnZUhUTUxcIl1dLFsvKHByZXN0bylcXC8oW1xcd1xcLl0rKS9pLC8od2Via2l0fHRyaWRlbnR8bmV0ZnJvbnR8bmV0c3VyZnxhbWF5YXxseW54fHczbSlcXC8oW1xcd1xcLl0rKS9pLC8oa2h0bWx8dGFzbWFufGxpbmtzKVtcXC9cXHNdXFwoPyhbXFx3XFwuXSspL2ksLyhpY2FiKVtcXC9cXHNdKFsyM11cXC5bXFxkXFwuXSspL2ldLFtnLG1dLFsvcnZcXDooW1xcd1xcLl0rKS4qKGdlY2tvKS9pXSxbbSxnXV0sb3M6W1svbWljcm9zb2Z0XFxzKHdpbmRvd3MpXFxzKHZpc3RhfHhwKS9pXSxbZyxtXSxbLyh3aW5kb3dzKVxcc250XFxzNlxcLjI7XFxzKGFybSkvaSwvKHdpbmRvd3NcXHNwaG9uZSg/Olxcc29zKSopW1xcc1xcL10/KFtcXGRcXC5cXHNdK1xcdykqL2ksLyh3aW5kb3dzXFxzbW9iaWxlfHdpbmRvd3MpW1xcc1xcL10/KFtudGNlXFxkXFwuXFxzXStcXHcpL2ldLFtnLFttLEMuYWMsTy5vcy5WZC52ZXJzaW9uXV0sWy8od2luKD89M3w5fG4pfHdpblxcczl4XFxzKShbbnRcXGRcXC5dKykvaV0sW1tnLFwiV2luZG93c1wiXSxbbSxDLmFjLE8ub3MuVmQudmVyc2lvbl1dLFsvXFwoKGJiKSgxMCk7L2ldLFtbZyxcIkJsYWNrQmVycnlcIl0sbV0sWy8oYmxhY2tiZXJyeSlcXHcqXFwvPyhbXFx3XFwuXSspKi9pLC8odGl6ZW4pW1xcL1xcc10oW1xcd1xcLl0rKS9pLC8oYW5kcm9pZHx3ZWJvc3xwYWxtXFxzb3N8cW54fGJhZGF8cmltXFxzdGFibGV0XFxzb3N8bWVlZ298Y29udGlraSlbXFwvXFxzLV0/KFtcXHdcXC5dKykqL2ksL2xpbnV4Oy4rKHNhaWxmaXNoKTsvaV0sW2csbV0sWy8oc3ltYmlhblxccz9vc3xzeW1ib3N8czYwKD89OykpW1xcL1xccy1dPyhbXFx3XFwuXSspKi9pXSxbW2csXCJTeW1iaWFuXCJdLG1dLFsvXFwoKHNlcmllczQwKTsvaV0sW2ddLFsvbW96aWxsYS4rXFwobW9iaWxlOy4rZ2Vja28uK2ZpcmVmb3gvaV0sW1tnLFwiRmlyZWZveCBPU1wiXSxtXSxbLyhuaW50ZW5kb3xwbGF5c3RhdGlvbilcXHMoW3dpZHMzNHBvcnRhYmxldnVdKykvaSwvKG1pbnQpW1xcL1xcc1xcKF0/KFxcdyspKi9pLC8obWFnZWlhfHZlY3RvcmxpbnV4KVs7XFxzXS9pLC8oam9saXxba3hsbl0/dWJ1bnR1fGRlYmlhbnxbb3Blbl0qc3VzZXxnZW50b298KD89XFxzKWFyY2h8c2xhY2t3YXJlfGZlZG9yYXxtYW5kcml2YXxjZW50b3N8cGNsaW51eG9zfHJlZGhhdHx6ZW53YWxrfGxpbnB1cylbXFwvXFxzLV0/KD8hY2hyb20pKFtcXHdcXC4tXSspKi9pLC8oaHVyZHxsaW51eClcXHM/KFtcXHdcXC5dKykqL2ksLyhnbnUpXFxzPyhbXFx3XFwuXSspKi9pXSxbZyxtXSxbLyhjcm9zKVxcc1tcXHddK1xccyhbXFx3XFwuXStcXHcpL2ldLFtbZyxcIkNocm9taXVtIE9TXCJdLG1dLFsvKHN1bm9zKVxccz8oW1xcd1xcLl0rXFxkKSovaV0sW1tnLFwiU29sYXJpc1wiXSxtXSxbL1xccyhbZnJlbnRvcGMtXXswLDR9YnNkfGRyYWdvbmZseSlcXHM/KFtcXHdcXC5dKykqL2ldLFtnLG1dLFsvKGhhaWt1KVxccyhcXHcrKS9pXSxbZyxtXSxbLyhpcFtob25lYWRdKykoPzouKm9zXFxzKFtcXHddKykqXFxzbGlrZVxcc21hY3w7XFxzb3BlcmEpL2ldLFtbZyxcImlPU1wiXSxbbSwvXy9nLFwiLlwiXV0sWy8obWFjXFxzb3NcXHN4KVxccz8oW1xcd1xcc1xcLl0rXFx3KSovaSwvKG1hY2ludG9zaHxtYWMoPz1fcG93ZXJwYylcXHMpL2ldLFtbZyxcIk1hYyBPU1wiXSxbbSwvXy9nLFwiLlwiXV0sWy8oKD86b3Blbik/c29sYXJpcylbXFwvXFxzLV0/KFtcXHdcXC5dKykqL2ksLyhhaXgpXFxzKChcXGQpKD89XFwufFxcKXxcXHMpW1xcd1xcLl0qKSovaSwvKHBsYW5cXHM5fG1pbml4fGJlb3N8b3NcXC8yfGFtaWdhb3N8bW9ycGhvc3xyaXNjXFxzb3N8b3BlbnZtcykvaSwvKHVuaXgpXFxzPyhbXFx3XFwuXSspKi9pXSxbZyxtXV19LEE9ZnVuY3Rpb24odCxlKXtpZighKHRoaXMgaW5zdGFuY2VvZiBBKSlyZXR1cm4gbmV3IEEodCxlKS5XZCgpO3ZhciBpPXR8fChuJiZuLm5hdmlnYXRvciYmbi5uYXZpZ2F0b3IudXNlckFnZW50P24ubmF2aWdhdG9yLnVzZXJBZ2VudDphKSxyPWU/ay5leHRlbmQoUCxlKTpQO3JldHVybiB0aGlzLiRkPWZ1bmN0aW9uKCl7dmFyIHQ9Qy5OZC5hcHBseSh0aGlzLHIudGkpO3JldHVybiB0LkFkPWsuQWQodC52ZXJzaW9uKSx0fSx0aGlzLllkPWZ1bmN0aW9uKCl7cmV0dXJuIEMuTmQuYXBwbHkodGhpcyxyLkdkKX0sdGhpcy5YZD1mdW5jdGlvbigpe3JldHVybiBDLk5kLmFwcGx5KHRoaXMsci5GZCl9LHRoaXMuWmQ9ZnVuY3Rpb24oKXtyZXR1cm4gQy5OZC5hcHBseSh0aGlzLHIuemQpfSx0aGlzLlJuPWZ1bmN0aW9uKCl7cmV0dXJuIEMuTmQuYXBwbHkodGhpcyxyLm9zKX0sdGhpcy5XZD1mdW5jdGlvbigpe3JldHVybnt0Zjp0aGlzLnhkKCksdGk6dGhpcy4kZCgpLHpkOnRoaXMuWmQoKSxvczp0aGlzLlJuKCksRmQ6dGhpcy5YZCgpLEdkOnRoaXMuWWQoKX19LHRoaXMueGQ9ZnVuY3Rpb24oKXtyZXR1cm4gaX0sdGhpcy5Jbj1mdW5jdGlvbih0KXtyZXR1cm4gaT10LHRoaXN9LHRoaXN9O0EuVkVSU0lPTj1zLEEuZWY9e1wiaWZcIjpnLHJmOmQsVkVSU0lPTjptfSxBLm5mPXtzZjp3fSxBLmFmPXtjZjpmLFZFTkRPUjp5LGhmOnYscGY6VCx1ZjpTLGxmOkUsZGY6YixmZjpJLGdmOlJ9LEEudmY9e1wiaWZcIjpnLFZFUlNJT046bX0sQS55Zj17XCJpZlwiOmcsVkVSU0lPTjptfSx0eXBlb2YgZSE9PXA/KHR5cGVvZiB0IT09cCYmdC50JiYoZT10LnQ9QSksZS5Dcj1BKTpcImZ1bmN0aW9uXCI9PT1oJiZpKDY0KT8ocj1mdW5jdGlvbigpe3JldHVybiBBfS5jYWxsKGUsaSxlLHQpLCEociE9PW8mJih0LnQ9cikpKTpuLkNyPUE7dmFyIE49bi5qUXVlcnl8fG4uWmVwdG87aWYodHlwZW9mIE4hPT1wKXt2YXIgeD1uZXcgQTtOLnRmPXguV2QoKSxOLnRmLmdldD1mdW5jdGlvbigpe3JldHVybiB4LnhkKCl9LE4udGYuc2V0PWZ1bmN0aW9uKHQpe3guSW4odCk7dmFyIGU9eC5XZCgpO2Zvcih2YXIgaSBpbiBlKU4udGZbaV09ZVtpXX19fShcIm9iamVjdFwiPT10eXBlb2Ygd2luZG93P3dpbmRvdzp0aGlzKX0sZnVuY3Rpb24odCxlKXtTZXJ2aWNlcz17MTpcIlJFTU9URV9FWEVDVVRPUlwiLG1mOjEsMjpcIlBFRVJfRk9SV0FSREVSXCIsd2Y6MiwzOlwiUEVFUl9JTkRFWFwiLFRmOjMsNDpcIlBFRVJfQlJPQURDQVNUXCIsU2Y6NCw1OlwiUEVFUl9GSUxURVJcIixiZjo1LDY6XCJQRUVSX0xPR0dJTkdcIixFZjo2LDc6XCJISVZFSlNfVFJBQ0tFUlwiLElmOjcsODpcIlBFRVJfU1lTVEVNXCIsUmY6OCw5OlwiSElWRUpTX1NOQVBTSE9UU1wiLHRvOjksMTA6XCJISVZFSlNfVElDS0VUU1wiLGtmOjEwLDExOlwiSElWRUpTX0tFRVBBTElWRVwiLENmOjExLDEyOlwiSElWRUpTX0ZPUldBUkRJTkdcIixPZjoxMn19LGZ1bmN0aW9uKHQsZSxpKXt2YXIgcj1pKDE2KTtTdHJlYW1UeXBlPXsxOlwiTElWRVwiLExJVkU6MSwyOlwiVk9EXCIsUGY6Mn0sU3RyZWFtUHJvdG9jb2w9ezE6XCJEQVNIXCIscnQ6MSwyOlwiSERTXCIsQWY6MiwzOlwiSExTXCIsWTozLDQ6XCJTU1wiLE5mOjR9LENsaWVudFR5cGU9ezE6XCJKQVZBXCIseGY6MSwyOlwiU1RBVFNfT05MWVwiLEJmOjIsMzpcIkpTX0RJUkVDVFwiLEZmOjMsNDpcIkpTX1BST1hZXCIsX2Y6NH0sRXZlbnRJZD1mdW5jdGlvbih0KXt0aGlzLnBhcnRuZXJJZD1udWxsLHRoaXMuY3VzdG9tZXJJZD1udWxsLHRoaXMuY29udGVudElkPW51bGwsdGhpcy50YWdzPW51bGwsdCYmKHZvaWQgMCE9PXQucGFydG5lcklkJiYodGhpcy5wYXJ0bmVySWQ9dC5wYXJ0bmVySWQpLHZvaWQgMCE9PXQuY3VzdG9tZXJJZCYmKHRoaXMuY3VzdG9tZXJJZD10LmN1c3RvbWVySWQpLHZvaWQgMCE9PXQuY29udGVudElkJiYodGhpcy5jb250ZW50SWQ9dC5jb250ZW50SWQpLHZvaWQgMCE9PXQudGFncyYmKHRoaXMudGFncz10LnRhZ3MpKX0sRXZlbnRJZC5wcm90b3R5cGU9e30sRXZlbnRJZC5wcm90b3R5cGUucmVhZD1mdW5jdGlvbih0KXtmb3IodC5IYygpOzspe3ZhciBlPXQuc2EoKSxpPShlLkJjLGUuYWEpLG49ZS5jYTtpZihpPT1yLmJzLkVzKWJyZWFrO3N3aXRjaChuKXtjYXNlIDE6aT09ci5icy5Bcz90aGlzLnBhcnRuZXJJZD10LmhhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI6aT09ci5icy5Bcz90aGlzLmN1c3RvbWVySWQ9dC5oYSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzOmk9PXIuYnMuQXM/dGhpcy5jb250ZW50SWQ9dC5oYSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA0OmlmKGk9PXIuYnMuX3Mpe3ZhciBvLHM9MDt0aGlzLnRhZ3M9W107dmFyIGE9MDtvPXQuVmMoKSxhPW8uUWMscz1vLnNpemU7Zm9yKHZhciBjPTA7YzxzOysrYyl7dmFyIGg9bnVsbDtoPXQuaGEoKS52YWx1ZSx0aGlzLnRhZ3MucHVzaChoKX10LnFjKCl9ZWxzZSB0LnBhKGkpO2JyZWFrO2RlZmF1bHQ6dC5wYShpKX10LmxhKCl9dC5kYSgpfSxFdmVudElkLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbih0KXtpZih0LmZhKFwiRXZlbnRJZFwiKSxudWxsIT09dGhpcy5wYXJ0bmVySWQmJnZvaWQgMCE9PXRoaXMucGFydG5lcklkJiYodC5nYShcInBhcnRuZXJJZFwiLHIuYnMuQXMsMSksdC52YSh0aGlzLnBhcnRuZXJJZCksdC55YSgpKSxudWxsIT09dGhpcy5jdXN0b21lcklkJiZ2b2lkIDAhPT10aGlzLmN1c3RvbWVySWQmJih0LmdhKFwiY3VzdG9tZXJJZFwiLHIuYnMuQXMsMiksdC52YSh0aGlzLmN1c3RvbWVySWQpLHQueWEoKSksbnVsbCE9PXRoaXMuY29udGVudElkJiZ2b2lkIDAhPT10aGlzLmNvbnRlbnRJZCYmKHQuZ2EoXCJjb250ZW50SWRcIixyLmJzLkFzLDMpLHQudmEodGhpcy5jb250ZW50SWQpLHQueWEoKSksbnVsbCE9PXRoaXMudGFncyYmdm9pZCAwIT09dGhpcy50YWdzKXt0LmdhKFwidGFnc1wiLHIuYnMuX3MsNCksdC5UYyhyLmJzLkFzLHRoaXMudGFncy5sZW5ndGgpO2Zvcih2YXIgZSBpbiB0aGlzLnRhZ3MpdGhpcy50YWdzLmhhc093blByb3BlcnR5KGUpJiYoZT10aGlzLnRhZ3NbZV0sdC52YShlKSk7dC5TYygpLHQueWEoKX10LndhKCksdC5UYSgpfSxTbmFwc2hvdEluZm89ZnVuY3Rpb24odCl7dGhpcy50aW1lc3RhbXA9bnVsbCx0aGlzLmFwaVNlcnZlcj1udWxsLHRoaXMuY2xpZW50SXA9bnVsbCx0JiYodm9pZCAwIT09dC50aW1lc3RhbXAmJih0aGlzLnRpbWVzdGFtcD10LnRpbWVzdGFtcCksdm9pZCAwIT09dC5hcGlTZXJ2ZXImJih0aGlzLmFwaVNlcnZlcj10LmFwaVNlcnZlciksdm9pZCAwIT09dC5jbGllbnRJcCYmKHRoaXMuY2xpZW50SXA9dC5jbGllbnRJcCkpfSxTbmFwc2hvdEluZm8ucHJvdG90eXBlPXt9LFNuYXBzaG90SW5mby5wcm90b3R5cGUucmVhZD1mdW5jdGlvbih0KXtmb3IodC5IYygpOzspe3ZhciBlPXQuc2EoKSxpPShlLkJjLGUuYWEpLG49ZS5jYTtpZihpPT1yLmJzLkVzKWJyZWFrO3N3aXRjaChuKXtjYXNlIDE6aT09ci5icy5Qcz90aGlzLnRpbWVzdGFtcD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI6aT09ci5icy5Bcz90aGlzLmFwaVNlcnZlcj10LmhhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM6aT09ci5icy5Bcz90aGlzLmNsaWVudElwPXQuaGEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2RlZmF1bHQ6dC5wYShpKX10LmxhKCl9dC5kYSgpfSxTbmFwc2hvdEluZm8ucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKHQpe3QuZmEoXCJTbmFwc2hvdEluZm9cIiksbnVsbCE9PXRoaXMudGltZXN0YW1wJiZ2b2lkIDAhPT10aGlzLnRpbWVzdGFtcCYmKHQuZ2EoXCJ0aW1lc3RhbXBcIixyLmJzLlBzLDEpLHQuQ2ModGhpcy50aW1lc3RhbXApLHQueWEoKSksbnVsbCE9PXRoaXMuYXBpU2VydmVyJiZ2b2lkIDAhPT10aGlzLmFwaVNlcnZlciYmKHQuZ2EoXCJhcGlTZXJ2ZXJcIixyLmJzLkFzLDIpLHQudmEodGhpcy5hcGlTZXJ2ZXIpLHQueWEoKSksbnVsbCE9PXRoaXMuY2xpZW50SXAmJnZvaWQgMCE9PXRoaXMuY2xpZW50SXAmJih0LmdhKFwiY2xpZW50SXBcIixyLmJzLkFzLDMpLHQudmEodGhpcy5jbGllbnRJcCksdC55YSgpKSx0LndhKCksdC5UYSgpfSxJbmV0QWRkcmVzcz1mdW5jdGlvbih0KXt0aGlzLmFkZHJlc3M9bnVsbCx0aGlzLnBvcnQ9bnVsbCx0JiYodm9pZCAwIT09dC5hZGRyZXNzJiYodGhpcy5hZGRyZXNzPXQuYWRkcmVzcyksdm9pZCAwIT09dC5wb3J0JiYodGhpcy5wb3J0PXQucG9ydCkpfSxJbmV0QWRkcmVzcy5wcm90b3R5cGU9e30sSW5ldEFkZHJlc3MucHJvdG90eXBlLnJlYWQ9ZnVuY3Rpb24odCl7Zm9yKHQuSGMoKTs7KXt2YXIgZT10LnNhKCksaT0oZS5CYyxlLmFhKSxuPWUuY2E7aWYoaT09ci5icy5FcylicmVhaztzd2l0Y2gobil7Y2FzZSAxOmk9PXIuYnMuQXM/dGhpcy5hZGRyZXNzPXQuWGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjppPT1yLmJzLk9zP3RoaXMucG9ydD10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztkZWZhdWx0OnQucGEoaSl9dC5sYSgpfXQuZGEoKX0sSW5ldEFkZHJlc3MucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKHQpe3QuZmEoXCJJbmV0QWRkcmVzc1wiKSxudWxsIT09dGhpcy5hZGRyZXNzJiZ2b2lkIDAhPT10aGlzLmFkZHJlc3MmJih0LmdhKFwiYWRkcmVzc1wiLHIuYnMuQXMsMSksdC5QYyh0aGlzLmFkZHJlc3MpLHQueWEoKSksbnVsbCE9PXRoaXMucG9ydCYmdm9pZCAwIT09dGhpcy5wb3J0JiYodC5nYShcInBvcnRcIixyLmJzLk9zLDIpLHQubWEodGhpcy5wb3J0KSx0LnlhKCkpLHQud2EoKSx0LlRhKCl9fSxmdW5jdGlvbih0LGUsaSl7dmFyIHI9aSgxNik7XCJ1bmRlZmluZWRcIj09dHlwZW9mIGhpdmUmJihoaXZlPXt9KSxcInVuZGVmaW5lZFwiPT10eXBlb2YgaGl2ZS5zbmFwc2hvdHMmJihoaXZlLnNuYXBzaG90cz17fSksaGl2ZS5zbmFwc2hvdHMuVHJhZmZpYz1mdW5jdGlvbih0KXt0aGlzLnJlcU49bnVsbCx0aGlzLnJlc3BGYWxsYmFja049bnVsbCx0aGlzLnJlc3BGYWxsYmFja0Vyck49bnVsbCx0aGlzLnJlc3BQMnBOPW51bGwsdGhpcy5yZXFPdGhlck49bnVsbCx0aGlzLnJlc3BGYWxsYmFja090aGVyTj1udWxsLHRoaXMucmVzcEZhbGxiYWNrT3RoZXJ0RXJyTj1udWxsLHRoaXMuc3JjUmVxTj1udWxsLHRoaXMuc3JjUmVzcE49bnVsbCx0aGlzLnNyY1Jlc3BFcnJOPW51bGwsdGhpcy5zcmNSZXFRdD1udWxsLHRoaXMuc3JjUmVzcFF0PW51bGwsdGhpcy5zcmNPdmVyUXQ9bnVsbCx0aGlzLnNyY090aGVyUmVxTj1udWxsLHRoaXMuc3JjT3RoZXJSZXNwTj1udWxsLHRoaXMuc3JjT3RoZXJSZXNwRXJyTj1udWxsLHRoaXMuc3JjT3RoZXJSZXFRdD1udWxsLHRoaXMuc3JjT3RoZXJSZXNwUXQ9bnVsbCx0aGlzLnNyY090aGVyT3ZlclF0PW51bGwsdGhpcy5wMnBTdWJSZXFOPW51bGwsdGhpcy5wMnBTdWJSZXNwTj1udWxsLHRoaXMucDJwU3ViUmVzcFBhcnROPW51bGwsdGhpcy5wMnBTdWJSZXNwRXJyTj1udWxsLHRoaXMucDJwU3ViUmVzcEV4cE49bnVsbCx0aGlzLnAycFN1YlJlcVF0PW51bGwsdGhpcy5wMnBTdWJSZXNwUXQ9bnVsbCx0aGlzLnAycERpcmVjdFF0PW51bGwsdGhpcy5wMnBSZWxheVF0PW51bGwsdGhpcy5wMnBOYXRRdD1udWxsLHRoaXMucDJwVWRwYlF0PW51bGwsdGhpcy5mYWxsQWdlbnRSZXNwTj1udWxsLHRoaXMuZmFsbEFnZW50UHJlZEhpdE49bnVsbCx0aGlzLmZhbGxBZ2VudEZhaWxlZFJlc3BOPW51bGwsdGhpcy5mYWxsQWdlbnRQcmVkTWlzc049bnVsbCx0aGlzLmZhbGxBZ2VudFByZWRQYXJ0aWFsSGl0Tj1udWxsLHRoaXMuZmFsbEFnZW5UcmFmZmljU3VjY2Vzc1F0PW51bGwsdGhpcy5mYWxsQWdlblRyYWZmaWNGYWlsdXJlUXQ9bnVsbCx0aGlzLnAycEFnZW50UHJlZEhpdE49bnVsbCx0aGlzLnAycEFnZW50UHJlZE1pc3NOPW51bGwsdGhpcy5wMnBBZ2VudFByZWRQYXJ0aWFsSGl0Tj1udWxsLHRoaXMucDJwQWdlblRyYWZmaWNTdWNjZXNzUXQ9bnVsbCx0aGlzLnAycEFnZW5UcmFmZmljRmFpbHVyZVF0PW51bGwsdGhpcy5yZXNwUDJwT3RoZXJOPW51bGwsdGhpcy5sQ2FjaGVSZXNwTj1udWxsLHRoaXMubENhY2hlUmVzcFF0PW51bGwsdGhpcy5wMnBPdXRTaXRlTG93UHJpbz1udWxsLHQmJih2b2lkIDAhPT10LnJlcU4mJih0aGlzLnJlcU49dC5yZXFOKSx2b2lkIDAhPT10LnJlc3BGYWxsYmFja04mJih0aGlzLnJlc3BGYWxsYmFja049dC5yZXNwRmFsbGJhY2tOKSx2b2lkIDAhPT10LnJlc3BGYWxsYmFja0Vyck4mJih0aGlzLnJlc3BGYWxsYmFja0Vyck49dC5yZXNwRmFsbGJhY2tFcnJOKSx2b2lkIDAhPT10LnJlc3BQMnBOJiYodGhpcy5yZXNwUDJwTj10LnJlc3BQMnBOKSx2b2lkIDAhPT10LnJlcU90aGVyTiYmKHRoaXMucmVxT3RoZXJOPXQucmVxT3RoZXJOKSx2b2lkIDAhPT10LnJlc3BGYWxsYmFja090aGVyTiYmKHRoaXMucmVzcEZhbGxiYWNrT3RoZXJOPXQucmVzcEZhbGxiYWNrT3RoZXJOKSx2b2lkIDAhPT10LnJlc3BGYWxsYmFja090aGVydEVyck4mJih0aGlzLnJlc3BGYWxsYmFja090aGVydEVyck49dC5yZXNwRmFsbGJhY2tPdGhlcnRFcnJOKSx2b2lkIDAhPT10LnNyY1JlcU4mJih0aGlzLnNyY1JlcU49dC5zcmNSZXFOKSx2b2lkIDAhPT10LnNyY1Jlc3BOJiYodGhpcy5zcmNSZXNwTj10LnNyY1Jlc3BOKSx2b2lkIDAhPT10LnNyY1Jlc3BFcnJOJiYodGhpcy5zcmNSZXNwRXJyTj10LnNyY1Jlc3BFcnJOKSx2b2lkIDAhPT10LnNyY1JlcVF0JiYodGhpcy5zcmNSZXFRdD10LnNyY1JlcVF0KSx2b2lkIDAhPT10LnNyY1Jlc3BRdCYmKHRoaXMuc3JjUmVzcFF0PXQuc3JjUmVzcFF0KSx2b2lkIDAhPT10LnNyY092ZXJRdCYmKHRoaXMuc3JjT3ZlclF0PXQuc3JjT3ZlclF0KSx2b2lkIDAhPT10LnNyY090aGVyUmVxTiYmKHRoaXMuc3JjT3RoZXJSZXFOPXQuc3JjT3RoZXJSZXFOKSx2b2lkIDAhPT10LnNyY090aGVyUmVzcE4mJih0aGlzLnNyY090aGVyUmVzcE49dC5zcmNPdGhlclJlc3BOKSx2b2lkIDAhPT10LnNyY090aGVyUmVzcEVyck4mJih0aGlzLnNyY090aGVyUmVzcEVyck49dC5zcmNPdGhlclJlc3BFcnJOKSx2b2lkIDAhPT10LnNyY090aGVyUmVxUXQmJih0aGlzLnNyY090aGVyUmVxUXQ9dC5zcmNPdGhlclJlcVF0KSx2b2lkIDAhPT10LnNyY090aGVyUmVzcFF0JiYodGhpcy5zcmNPdGhlclJlc3BRdD10LnNyY090aGVyUmVzcFF0KSx2b2lkIDAhPT10LnNyY090aGVyT3ZlclF0JiYodGhpcy5zcmNPdGhlck92ZXJRdD10LnNyY090aGVyT3ZlclF0KSxcbnZvaWQgMCE9PXQucDJwU3ViUmVxTiYmKHRoaXMucDJwU3ViUmVxTj10LnAycFN1YlJlcU4pLHZvaWQgMCE9PXQucDJwU3ViUmVzcE4mJih0aGlzLnAycFN1YlJlc3BOPXQucDJwU3ViUmVzcE4pLHZvaWQgMCE9PXQucDJwU3ViUmVzcFBhcnROJiYodGhpcy5wMnBTdWJSZXNwUGFydE49dC5wMnBTdWJSZXNwUGFydE4pLHZvaWQgMCE9PXQucDJwU3ViUmVzcEVyck4mJih0aGlzLnAycFN1YlJlc3BFcnJOPXQucDJwU3ViUmVzcEVyck4pLHZvaWQgMCE9PXQucDJwU3ViUmVzcEV4cE4mJih0aGlzLnAycFN1YlJlc3BFeHBOPXQucDJwU3ViUmVzcEV4cE4pLHZvaWQgMCE9PXQucDJwU3ViUmVxUXQmJih0aGlzLnAycFN1YlJlcVF0PXQucDJwU3ViUmVxUXQpLHZvaWQgMCE9PXQucDJwU3ViUmVzcFF0JiYodGhpcy5wMnBTdWJSZXNwUXQ9dC5wMnBTdWJSZXNwUXQpLHZvaWQgMCE9PXQucDJwRGlyZWN0UXQmJih0aGlzLnAycERpcmVjdFF0PXQucDJwRGlyZWN0UXQpLHZvaWQgMCE9PXQucDJwUmVsYXlRdCYmKHRoaXMucDJwUmVsYXlRdD10LnAycFJlbGF5UXQpLHZvaWQgMCE9PXQucDJwTmF0UXQmJih0aGlzLnAycE5hdFF0PXQucDJwTmF0UXQpLHZvaWQgMCE9PXQucDJwVWRwYlF0JiYodGhpcy5wMnBVZHBiUXQ9dC5wMnBVZHBiUXQpLHZvaWQgMCE9PXQuZmFsbEFnZW50UmVzcE4mJih0aGlzLmZhbGxBZ2VudFJlc3BOPXQuZmFsbEFnZW50UmVzcE4pLHZvaWQgMCE9PXQuZmFsbEFnZW50UHJlZEhpdE4mJih0aGlzLmZhbGxBZ2VudFByZWRIaXROPXQuZmFsbEFnZW50UHJlZEhpdE4pLHZvaWQgMCE9PXQuZmFsbEFnZW50RmFpbGVkUmVzcE4mJih0aGlzLmZhbGxBZ2VudEZhaWxlZFJlc3BOPXQuZmFsbEFnZW50RmFpbGVkUmVzcE4pLHZvaWQgMCE9PXQuZmFsbEFnZW50UHJlZE1pc3NOJiYodGhpcy5mYWxsQWdlbnRQcmVkTWlzc049dC5mYWxsQWdlbnRQcmVkTWlzc04pLHZvaWQgMCE9PXQuZmFsbEFnZW50UHJlZFBhcnRpYWxIaXROJiYodGhpcy5mYWxsQWdlbnRQcmVkUGFydGlhbEhpdE49dC5mYWxsQWdlbnRQcmVkUGFydGlhbEhpdE4pLHZvaWQgMCE9PXQuZmFsbEFnZW5UcmFmZmljU3VjY2Vzc1F0JiYodGhpcy5mYWxsQWdlblRyYWZmaWNTdWNjZXNzUXQ9dC5mYWxsQWdlblRyYWZmaWNTdWNjZXNzUXQpLHZvaWQgMCE9PXQuZmFsbEFnZW5UcmFmZmljRmFpbHVyZVF0JiYodGhpcy5mYWxsQWdlblRyYWZmaWNGYWlsdXJlUXQ9dC5mYWxsQWdlblRyYWZmaWNGYWlsdXJlUXQpLHZvaWQgMCE9PXQucDJwQWdlbnRQcmVkSGl0TiYmKHRoaXMucDJwQWdlbnRQcmVkSGl0Tj10LnAycEFnZW50UHJlZEhpdE4pLHZvaWQgMCE9PXQucDJwQWdlbnRQcmVkTWlzc04mJih0aGlzLnAycEFnZW50UHJlZE1pc3NOPXQucDJwQWdlbnRQcmVkTWlzc04pLHZvaWQgMCE9PXQucDJwQWdlbnRQcmVkUGFydGlhbEhpdE4mJih0aGlzLnAycEFnZW50UHJlZFBhcnRpYWxIaXROPXQucDJwQWdlbnRQcmVkUGFydGlhbEhpdE4pLHZvaWQgMCE9PXQucDJwQWdlblRyYWZmaWNTdWNjZXNzUXQmJih0aGlzLnAycEFnZW5UcmFmZmljU3VjY2Vzc1F0PXQucDJwQWdlblRyYWZmaWNTdWNjZXNzUXQpLHZvaWQgMCE9PXQucDJwQWdlblRyYWZmaWNGYWlsdXJlUXQmJih0aGlzLnAycEFnZW5UcmFmZmljRmFpbHVyZVF0PXQucDJwQWdlblRyYWZmaWNGYWlsdXJlUXQpLHZvaWQgMCE9PXQucmVzcFAycE90aGVyTiYmKHRoaXMucmVzcFAycE90aGVyTj10LnJlc3BQMnBPdGhlck4pLHZvaWQgMCE9PXQubENhY2hlUmVzcE4mJih0aGlzLmxDYWNoZVJlc3BOPXQubENhY2hlUmVzcE4pLHZvaWQgMCE9PXQubENhY2hlUmVzcFF0JiYodGhpcy5sQ2FjaGVSZXNwUXQ9dC5sQ2FjaGVSZXNwUXQpLHZvaWQgMCE9PXQucDJwT3V0U2l0ZUxvd1ByaW8mJih0aGlzLnAycE91dFNpdGVMb3dQcmlvPXQucDJwT3V0U2l0ZUxvd1ByaW8pKX0saGl2ZS5zbmFwc2hvdHMuVHJhZmZpYy5wcm90b3R5cGU9e30saGl2ZS5zbmFwc2hvdHMuVHJhZmZpYy5wcm90b3R5cGUucmVhZD1mdW5jdGlvbih0KXtmb3IodC5IYygpOzspe3ZhciBlPXQuc2EoKSxpPShlLkJjLGUuYWEpLG49ZS5jYTtpZihpPT1yLmJzLkVzKWJyZWFrO3N3aXRjaChuKXtjYXNlIDE6aT09ci5icy5Pcz90aGlzLnJlcU49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyOmk9PXIuYnMua3M/dGhpcy5yZXNwRmFsbGJhY2tOPXQuWWMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzppPT1yLmJzLk9zP3RoaXMucmVzcEZhbGxiYWNrRXJyTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDQ6aT09ci5icy5rcz90aGlzLnJlc3BQMnBOPXQuWWMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNTppPT1yLmJzLk9zP3RoaXMucmVxT3RoZXJOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNjppPT1yLmJzLk9zP3RoaXMucmVzcEZhbGxiYWNrT3RoZXJOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNzppPT1yLmJzLk9zP3RoaXMucmVzcEZhbGxiYWNrT3RoZXJ0RXJyTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDg6aT09ci5icy5Pcz90aGlzLnNyY1JlcU49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA5Omk9PXIuYnMuT3M/dGhpcy5zcmNSZXNwTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDEwOmk9PXIuYnMuT3M/dGhpcy5zcmNSZXNwRXJyTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDExOmk9PXIuYnMuUHM/dGhpcy5zcmNSZXFRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDEyOmk9PXIuYnMuUHM/dGhpcy5zcmNSZXNwUXQ9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAxMzppPT1yLmJzLlBzP3RoaXMuc3JjT3ZlclF0PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTQ6aT09ci5icy5Pcz90aGlzLnNyY090aGVyUmVxTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDE1Omk9PXIuYnMuT3M/dGhpcy5zcmNPdGhlclJlc3BOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTY6aT09ci5icy5Pcz90aGlzLnNyY090aGVyUmVzcEVyck49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAxNzppPT1yLmJzLlBzP3RoaXMuc3JjT3RoZXJSZXFRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDE4Omk9PXIuYnMuUHM/dGhpcy5zcmNPdGhlclJlc3BRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDE5Omk9PXIuYnMuUHM/dGhpcy5zcmNPdGhlck92ZXJRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDIwOmk9PXIuYnMuT3M/dGhpcy5wMnBTdWJSZXFOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjE6aT09ci5icy5Pcz90aGlzLnAycFN1YlJlc3BOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjI6aT09ci5icy5rcz90aGlzLnAycFN1YlJlc3BQYXJ0Tj10LlljKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDIzOmk9PXIuYnMua3M/dGhpcy5wMnBTdWJSZXNwRXJyTj10LlljKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI0Omk9PXIuYnMuT3M/dGhpcy5wMnBTdWJSZXNwRXhwTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI1Omk9PXIuYnMuUHM/dGhpcy5wMnBTdWJSZXFRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI2Omk9PXIuYnMuUHM/dGhpcy5wMnBTdWJSZXNwUXQ9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyNzppPT1yLmJzLlBzP3RoaXMucDJwRGlyZWN0UXQ9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyODppPT1yLmJzLlBzP3RoaXMucDJwUmVsYXlRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI5Omk9PXIuYnMuUHM/dGhpcy5wMnBOYXRRdD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDMwOmk9PXIuYnMuUHM/dGhpcy5wMnBVZHBiUXQ9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzMTppPT1yLmJzLk9zP3RoaXMuZmFsbEFnZW50UmVzcE49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzMjppPT1yLmJzLk9zP3RoaXMuZmFsbEFnZW50UHJlZEhpdE49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzMzppPT1yLmJzLk9zP3RoaXMuZmFsbEFnZW50RmFpbGVkUmVzcE49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzNDppPT1yLmJzLk9zP3RoaXMuZmFsbEFnZW50UHJlZE1pc3NOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzU6aT09ci5icy5Pcz90aGlzLmZhbGxBZ2VudFByZWRQYXJ0aWFsSGl0Tj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM2Omk9PXIuYnMuUHM/dGhpcy5mYWxsQWdlblRyYWZmaWNTdWNjZXNzUXQ9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzNzppPT1yLmJzLlBzP3RoaXMuZmFsbEFnZW5UcmFmZmljRmFpbHVyZVF0PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzg6aT09ci5icy5Pcz90aGlzLnAycEFnZW50UHJlZEhpdE49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzOTppPT1yLmJzLk9zP3RoaXMucDJwQWdlbnRQcmVkTWlzc049dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA0MDppPT1yLmJzLk9zP3RoaXMucDJwQWdlbnRQcmVkUGFydGlhbEhpdE49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA0MTppPT1yLmJzLlBzP3RoaXMucDJwQWdlblRyYWZmaWNTdWNjZXNzUXQ9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA0MjppPT1yLmJzLlBzP3RoaXMucDJwQWdlblRyYWZmaWNGYWlsdXJlUXQ9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA0MzppPT1yLmJzLk9zP3RoaXMucmVzcFAycE90aGVyTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDQ0Omk9PXIuYnMuT3M/dGhpcy5sQ2FjaGVSZXNwTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDQ1Omk9PXIuYnMuUHM/dGhpcy5sQ2FjaGVSZXNwUXQ9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA0NjppPT1yLmJzLlBzP3RoaXMucDJwT3V0U2l0ZUxvd1ByaW89dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7ZGVmYXVsdDp0LnBhKGkpfXQubGEoKX10LmRhKCl9LGhpdmUuc25hcHNob3RzLlRyYWZmaWMucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKHQpe3QuZmEoXCJUcmFmZmljXCIpLG51bGwhPT10aGlzLnJlcU4mJnZvaWQgMCE9PXRoaXMucmVxTiYmKHQuZ2EoXCJyZXFOXCIsci5icy5PcywxKSx0Lm1hKHRoaXMucmVxTiksdC55YSgpKSxudWxsIT09dGhpcy5yZXNwRmFsbGJhY2tOJiZ2b2lkIDAhPT10aGlzLnJlc3BGYWxsYmFja04mJih0LmdhKFwicmVzcEZhbGxiYWNrTlwiLHIuYnMua3MsMiksdC5PYyh0aGlzLnJlc3BGYWxsYmFja04pLHQueWEoKSksbnVsbCE9PXRoaXMucmVzcEZhbGxiYWNrRXJyTiYmdm9pZCAwIT09dGhpcy5yZXNwRmFsbGJhY2tFcnJOJiYodC5nYShcInJlc3BGYWxsYmFja0Vyck5cIixyLmJzLk9zLDMpLHQubWEodGhpcy5yZXNwRmFsbGJhY2tFcnJOKSx0LnlhKCkpLG51bGwhPT10aGlzLnJlc3BQMnBOJiZ2b2lkIDAhPT10aGlzLnJlc3BQMnBOJiYodC5nYShcInJlc3BQMnBOXCIsci5icy5rcyw0KSx0Lk9jKHRoaXMucmVzcFAycE4pLHQueWEoKSksbnVsbCE9PXRoaXMucmVxT3RoZXJOJiZ2b2lkIDAhPT10aGlzLnJlcU90aGVyTiYmKHQuZ2EoXCJyZXFPdGhlck5cIixyLmJzLk9zLDUpLHQubWEodGhpcy5yZXFPdGhlck4pLHQueWEoKSksbnVsbCE9PXRoaXMucmVzcEZhbGxiYWNrT3RoZXJOJiZ2b2lkIDAhPT10aGlzLnJlc3BGYWxsYmFja090aGVyTiYmKHQuZ2EoXCJyZXNwRmFsbGJhY2tPdGhlck5cIixyLmJzLk9zLDYpLHQubWEodGhpcy5yZXNwRmFsbGJhY2tPdGhlck4pLHQueWEoKSksbnVsbCE9PXRoaXMucmVzcEZhbGxiYWNrT3RoZXJ0RXJyTiYmdm9pZCAwIT09dGhpcy5yZXNwRmFsbGJhY2tPdGhlcnRFcnJOJiYodC5nYShcInJlc3BGYWxsYmFja090aGVydEVyck5cIixyLmJzLk9zLDcpLHQubWEodGhpcy5yZXNwRmFsbGJhY2tPdGhlcnRFcnJOKSx0LnlhKCkpLG51bGwhPT10aGlzLnNyY1JlcU4mJnZvaWQgMCE9PXRoaXMuc3JjUmVxTiYmKHQuZ2EoXCJzcmNSZXFOXCIsci5icy5Pcyw4KSx0Lm1hKHRoaXMuc3JjUmVxTiksdC55YSgpKSxudWxsIT09dGhpcy5zcmNSZXNwTiYmdm9pZCAwIT09dGhpcy5zcmNSZXNwTiYmKHQuZ2EoXCJzcmNSZXNwTlwiLHIuYnMuT3MsOSksdC5tYSh0aGlzLnNyY1Jlc3BOKSx0LnlhKCkpLG51bGwhPT10aGlzLnNyY1Jlc3BFcnJOJiZ2b2lkIDAhPT10aGlzLnNyY1Jlc3BFcnJOJiYodC5nYShcInNyY1Jlc3BFcnJOXCIsci5icy5PcywxMCksdC5tYSh0aGlzLnNyY1Jlc3BFcnJOKSx0LnlhKCkpLG51bGwhPT10aGlzLnNyY1JlcVF0JiZ2b2lkIDAhPT10aGlzLnNyY1JlcVF0JiYodC5nYShcInNyY1JlcVF0XCIsci5icy5QcywxMSksdC5DYyh0aGlzLnNyY1JlcVF0KSx0LnlhKCkpLG51bGwhPT10aGlzLnNyY1Jlc3BRdCYmdm9pZCAwIT09dGhpcy5zcmNSZXNwUXQmJih0LmdhKFwic3JjUmVzcFF0XCIsci5icy5QcywxMiksdC5DYyh0aGlzLnNyY1Jlc3BRdCksdC55YSgpKSxudWxsIT09dGhpcy5zcmNPdmVyUXQmJnZvaWQgMCE9PXRoaXMuc3JjT3ZlclF0JiYodC5nYShcInNyY092ZXJRdFwiLHIuYnMuUHMsMTMpLHQuQ2ModGhpcy5zcmNPdmVyUXQpLHQueWEoKSksbnVsbCE9PXRoaXMuc3JjT3RoZXJSZXFOJiZ2b2lkIDAhPT10aGlzLnNyY090aGVyUmVxTiYmKHQuZ2EoXCJzcmNPdGhlclJlcU5cIixyLmJzLk9zLDE0KSx0Lm1hKHRoaXMuc3JjT3RoZXJSZXFOKSx0LnlhKCkpLG51bGwhPT10aGlzLnNyY090aGVyUmVzcE4mJnZvaWQgMCE9PXRoaXMuc3JjT3RoZXJSZXNwTiYmKHQuZ2EoXCJzcmNPdGhlclJlc3BOXCIsci5icy5PcywxNSksdC5tYSh0aGlzLnNyY090aGVyUmVzcE4pLHQueWEoKSksbnVsbCE9PXRoaXMuc3JjT3RoZXJSZXNwRXJyTiYmdm9pZCAwIT09dGhpcy5zcmNPdGhlclJlc3BFcnJOJiYodC5nYShcInNyY090aGVyUmVzcEVyck5cIixyLmJzLk9zLDE2KSx0Lm1hKHRoaXMuc3JjT3RoZXJSZXNwRXJyTiksdC55YSgpKSxudWxsIT09dGhpcy5zcmNPdGhlclJlcVF0JiZ2b2lkIDAhPT10aGlzLnNyY090aGVyUmVxUXQmJih0LmdhKFwic3JjT3RoZXJSZXFRdFwiLHIuYnMuUHMsMTcpLHQuQ2ModGhpcy5zcmNPdGhlclJlcVF0KSx0LnlhKCkpLG51bGwhPT10aGlzLnNyY090aGVyUmVzcFF0JiZ2b2lkIDAhPT10aGlzLnNyY090aGVyUmVzcFF0JiYodC5nYShcInNyY090aGVyUmVzcFF0XCIsci5icy5QcywxOCksdC5DYyh0aGlzLnNyY090aGVyUmVzcFF0KSx0LnlhKCkpLG51bGwhPT10aGlzLnNyY090aGVyT3ZlclF0JiZ2b2lkIDAhPT10aGlzLnNyY090aGVyT3ZlclF0JiYodC5nYShcInNyY090aGVyT3ZlclF0XCIsci5icy5QcywxOSksdC5DYyh0aGlzLnNyY090aGVyT3ZlclF0KSx0LnlhKCkpLG51bGwhPT10aGlzLnAycFN1YlJlcU4mJnZvaWQgMCE9PXRoaXMucDJwU3ViUmVxTiYmKHQuZ2EoXCJwMnBTdWJSZXFOXCIsci5icy5PcywyMCksdC5tYSh0aGlzLnAycFN1YlJlcU4pLHQueWEoKSksbnVsbCE9PXRoaXMucDJwU3ViUmVzcE4mJnZvaWQgMCE9PXRoaXMucDJwU3ViUmVzcE4mJih0LmdhKFwicDJwU3ViUmVzcE5cIixyLmJzLk9zLDIxKSx0Lm1hKHRoaXMucDJwU3ViUmVzcE4pLHQueWEoKSksbnVsbCE9PXRoaXMucDJwU3ViUmVzcFBhcnROJiZ2b2lkIDAhPT10aGlzLnAycFN1YlJlc3BQYXJ0TiYmKHQuZ2EoXCJwMnBTdWJSZXNwUGFydE5cIixyLmJzLmtzLDIyKSx0Lk9jKHRoaXMucDJwU3ViUmVzcFBhcnROKSx0LnlhKCkpLG51bGwhPT10aGlzLnAycFN1YlJlc3BFcnJOJiZ2b2lkIDAhPT10aGlzLnAycFN1YlJlc3BFcnJOJiYodC5nYShcInAycFN1YlJlc3BFcnJOXCIsci5icy5rcywyMyksdC5PYyh0aGlzLnAycFN1YlJlc3BFcnJOKSx0LnlhKCkpLG51bGwhPT10aGlzLnAycFN1YlJlc3BFeHBOJiZ2b2lkIDAhPT10aGlzLnAycFN1YlJlc3BFeHBOJiYodC5nYShcInAycFN1YlJlc3BFeHBOXCIsci5icy5PcywyNCksdC5tYSh0aGlzLnAycFN1YlJlc3BFeHBOKSx0LnlhKCkpLG51bGwhPT10aGlzLnAycFN1YlJlcVF0JiZ2b2lkIDAhPT10aGlzLnAycFN1YlJlcVF0JiYodC5nYShcInAycFN1YlJlcVF0XCIsci5icy5QcywyNSksdC5DYyh0aGlzLnAycFN1YlJlcVF0KSx0LnlhKCkpLG51bGwhPT10aGlzLnAycFN1YlJlc3BRdCYmdm9pZCAwIT09dGhpcy5wMnBTdWJSZXNwUXQmJih0LmdhKFwicDJwU3ViUmVzcFF0XCIsci5icy5QcywyNiksdC5DYyh0aGlzLnAycFN1YlJlc3BRdCksdC55YSgpKSxudWxsIT09dGhpcy5wMnBEaXJlY3RRdCYmdm9pZCAwIT09dGhpcy5wMnBEaXJlY3RRdCYmKHQuZ2EoXCJwMnBEaXJlY3RRdFwiLHIuYnMuUHMsMjcpLHQuQ2ModGhpcy5wMnBEaXJlY3RRdCksdC55YSgpKSxudWxsIT09dGhpcy5wMnBSZWxheVF0JiZ2b2lkIDAhPT10aGlzLnAycFJlbGF5UXQmJih0LmdhKFwicDJwUmVsYXlRdFwiLHIuYnMuUHMsMjgpLHQuQ2ModGhpcy5wMnBSZWxheVF0KSx0LnlhKCkpLG51bGwhPT10aGlzLnAycE5hdFF0JiZ2b2lkIDAhPT10aGlzLnAycE5hdFF0JiYodC5nYShcInAycE5hdFF0XCIsci5icy5QcywyOSksdC5DYyh0aGlzLnAycE5hdFF0KSx0LnlhKCkpLG51bGwhPT10aGlzLnAycFVkcGJRdCYmdm9pZCAwIT09dGhpcy5wMnBVZHBiUXQmJih0LmdhKFwicDJwVWRwYlF0XCIsci5icy5QcywzMCksdC5DYyh0aGlzLnAycFVkcGJRdCksdC55YSgpKSxudWxsIT09dGhpcy5mYWxsQWdlbnRSZXNwTiYmdm9pZCAwIT09dGhpcy5mYWxsQWdlbnRSZXNwTiYmKHQuZ2EoXCJmYWxsQWdlbnRSZXNwTlwiLHIuYnMuT3MsMzEpLHQubWEodGhpcy5mYWxsQWdlbnRSZXNwTiksdC55YSgpKSxudWxsIT09dGhpcy5mYWxsQWdlbnRQcmVkSGl0TiYmdm9pZCAwIT09dGhpcy5mYWxsQWdlbnRQcmVkSGl0TiYmKHQuZ2EoXCJmYWxsQWdlbnRQcmVkSGl0TlwiLHIuYnMuT3MsMzIpLHQubWEodGhpcy5mYWxsQWdlbnRQcmVkSGl0TiksdC55YSgpKSxudWxsIT09dGhpcy5mYWxsQWdlbnRGYWlsZWRSZXNwTiYmdm9pZCAwIT09dGhpcy5mYWxsQWdlbnRGYWlsZWRSZXNwTiYmKHQuZ2EoXCJmYWxsQWdlbnRGYWlsZWRSZXNwTlwiLHIuYnMuT3MsMzMpLHQubWEodGhpcy5mYWxsQWdlbnRGYWlsZWRSZXNwTiksdC55YSgpKSxudWxsIT09dGhpcy5mYWxsQWdlbnRQcmVkTWlzc04mJnZvaWQgMCE9PXRoaXMuZmFsbEFnZW50UHJlZE1pc3NOJiYodC5nYShcImZhbGxBZ2VudFByZWRNaXNzTlwiLHIuYnMuT3MsMzQpLHQubWEodGhpcy5mYWxsQWdlbnRQcmVkTWlzc04pLHQueWEoKSksbnVsbCE9PXRoaXMuZmFsbEFnZW50UHJlZFBhcnRpYWxIaXROJiZ2b2lkIDAhPT10aGlzLmZhbGxBZ2VudFByZWRQYXJ0aWFsSGl0TiYmKHQuZ2EoXCJmYWxsQWdlbnRQcmVkUGFydGlhbEhpdE5cIixyLmJzLk9zLDM1KSx0Lm1hKHRoaXMuZmFsbEFnZW50UHJlZFBhcnRpYWxIaXROKSx0LnlhKCkpLG51bGwhPT10aGlzLmZhbGxBZ2VuVHJhZmZpY1N1Y2Nlc3NRdCYmdm9pZCAwIT09dGhpcy5mYWxsQWdlblRyYWZmaWNTdWNjZXNzUXQmJih0LmdhKFwiZmFsbEFnZW5UcmFmZmljU3VjY2Vzc1F0XCIsci5icy5QcywzNiksdC5DYyh0aGlzLmZhbGxBZ2VuVHJhZmZpY1N1Y2Nlc3NRdCksdC55YSgpKSxudWxsIT09dGhpcy5mYWxsQWdlblRyYWZmaWNGYWlsdXJlUXQmJnZvaWQgMCE9PXRoaXMuZmFsbEFnZW5UcmFmZmljRmFpbHVyZVF0JiYodC5nYShcImZhbGxBZ2VuVHJhZmZpY0ZhaWx1cmVRdFwiLHIuYnMuUHMsMzcpLHQuQ2ModGhpcy5mYWxsQWdlblRyYWZmaWNGYWlsdXJlUXQpLHQueWEoKSksbnVsbCE9PXRoaXMucDJwQWdlbnRQcmVkSGl0TiYmdm9pZCAwIT09dGhpcy5wMnBBZ2VudFByZWRIaXROJiYodC5nYShcInAycEFnZW50UHJlZEhpdE5cIixyLmJzLk9zLDM4KSx0Lm1hKHRoaXMucDJwQWdlbnRQcmVkSGl0TiksdC55YSgpKSxudWxsIT09dGhpcy5wMnBBZ2VudFByZWRNaXNzTiYmdm9pZCAwIT09dGhpcy5wMnBBZ2VudFByZWRNaXNzTiYmKHQuZ2EoXCJwMnBBZ2VudFByZWRNaXNzTlwiLHIuYnMuT3MsMzkpLHQubWEodGhpcy5wMnBBZ2VudFByZWRNaXNzTiksdC55YSgpKSxudWxsIT09dGhpcy5wMnBBZ2VudFByZWRQYXJ0aWFsSGl0TiYmdm9pZCAwIT09dGhpcy5wMnBBZ2VudFByZWRQYXJ0aWFsSGl0TiYmKHQuZ2EoXCJwMnBBZ2VudFByZWRQYXJ0aWFsSGl0TlwiLHIuYnMuT3MsNDApLHQubWEodGhpcy5wMnBBZ2VudFByZWRQYXJ0aWFsSGl0TiksdC55YSgpKSxudWxsIT09dGhpcy5wMnBBZ2VuVHJhZmZpY1N1Y2Nlc3NRdCYmdm9pZCAwIT09dGhpcy5wMnBBZ2VuVHJhZmZpY1N1Y2Nlc3NRdCYmKHQuZ2EoXCJwMnBBZ2VuVHJhZmZpY1N1Y2Nlc3NRdFwiLHIuYnMuUHMsNDEpLHQuQ2ModGhpcy5wMnBBZ2VuVHJhZmZpY1N1Y2Nlc3NRdCksdC55YSgpKSxudWxsIT09dGhpcy5wMnBBZ2VuVHJhZmZpY0ZhaWx1cmVRdCYmdm9pZCAwIT09dGhpcy5wMnBBZ2VuVHJhZmZpY0ZhaWx1cmVRdCYmKHQuZ2EoXCJwMnBBZ2VuVHJhZmZpY0ZhaWx1cmVRdFwiLHIuYnMuUHMsNDIpLHQuQ2ModGhpcy5wMnBBZ2VuVHJhZmZpY0ZhaWx1cmVRdCksdC55YSgpKSxudWxsIT09dGhpcy5yZXNwUDJwT3RoZXJOJiZ2b2lkIDAhPT10aGlzLnJlc3BQMnBPdGhlck4mJih0LmdhKFwicmVzcFAycE90aGVyTlwiLHIuYnMuT3MsNDMpLHQubWEodGhpcy5yZXNwUDJwT3RoZXJOKSx0LnlhKCkpLG51bGwhPT10aGlzLmxDYWNoZVJlc3BOJiZ2b2lkIDAhPT10aGlzLmxDYWNoZVJlc3BOJiYodC5nYShcImxDYWNoZVJlc3BOXCIsci5icy5Pcyw0NCksdC5tYSh0aGlzLmxDYWNoZVJlc3BOKSx0LnlhKCkpLG51bGwhPT10aGlzLmxDYWNoZVJlc3BRdCYmdm9pZCAwIT09dGhpcy5sQ2FjaGVSZXNwUXQmJih0LmdhKFwibENhY2hlUmVzcFF0XCIsci5icy5Qcyw0NSksdC5DYyh0aGlzLmxDYWNoZVJlc3BRdCksdC55YSgpKSxudWxsIT09dGhpcy5wMnBPdXRTaXRlTG93UHJpbyYmdm9pZCAwIT09dGhpcy5wMnBPdXRTaXRlTG93UHJpbyYmKHQuZ2EoXCJwMnBPdXRTaXRlTG93UHJpb1wiLHIuYnMuUHMsNDYpLHQuQ2ModGhpcy5wMnBPdXRTaXRlTG93UHJpbyksdC55YSgpKSx0LndhKCksdC5UYSgpfSxoaXZlLnNuYXBzaG90cy5NZXRyaWNzPWZ1bmN0aW9uKHQpe3RoaXMudXBCVz1udWxsLHRoaXMuZG93bkJXPW51bGwsdGhpcy5tZW1OPW51bGwsdGhpcy5wcnRJbk49bnVsbCx0aGlzLnBydE91dE49bnVsbCx0aGlzLmluaXRWaWRlb0J1ZlF0PW51bGwsdGhpcy52aWRlb0F2Z0J1ZlF0PW51bGwsdGhpcy52aWRlb0J1ZlF0PW51bGwsdGhpcy52aWRlb0J1Zk49bnVsbCx0aGlzLmluaXRBdWRpb0J1ZlF0PW51bGwsdGhpcy5hdWRpb0F2Z0J1ZlF0PW51bGwsdGhpcy5hdWRpb0J1ZlF0PW51bGwsdGhpcy5hdWRpb0J1Zk49bnVsbCx0aGlzLmJpdHJhdGVVcE49bnVsbCx0aGlzLmJpdHJhdGVEd25OPW51bGwsdGhpcy5kZWxheT1udWxsLHRoaXMuZGVsYXlFbmZvcmNlbWVudD1udWxsLHRoaXMubG9va3VwUmVxRXN0YWJsaXNoZWQ9bnVsbCx0aGlzLmxvb2t1cFJlcUFjY2VwdD1udWxsLHRoaXMuZmFsbGJhY2tBdmdUcD1udWxsLHRoaXMuc3JjVGhyb3VnaHB1dD1udWxsLHRoaXMuZGlza1JlYWRUaW1lb3V0PW51bGwsdGhpcy5kaXNrUmVhZFJhdGU9bnVsbCx0aGlzLmRpc2tTdG9yZVJhdGU9bnVsbCx0aGlzLmRpc2tSZW1vdmVSYXRlPW51bGwsdGhpcy5kaXNrQ2FjaGVTaXplPW51bGwsdGhpcy5jbGllbnRCdWZmZXJNcz1udWxsLHRoaXMubG9va3VwVG90YWw9bnVsbCx0aGlzLmxvb2t1cE5vdEZvdW5kPW51bGwsdGhpcy5sb29rdXBGYWlsZWQ9bnVsbCx0aGlzLmxvb2t1cExhdGVuY3k9bnVsbCx0aGlzLnRyYWNrZXJGYWlsZWQ9bnVsbCx0aGlzLnRyYWNrZXJMYXRlbmN5PW51bGwsdGhpcy5zbmFwc2hvdEZhaWxlZD1udWxsLHRoaXMuc25hcHNob3RMYXRlbmN5PW51bGwsdCYmKHZvaWQgMCE9PXQudXBCVyYmKHRoaXMudXBCVz10LnVwQlcpLHZvaWQgMCE9PXQuZG93bkJXJiYodGhpcy5kb3duQlc9dC5kb3duQlcpLHZvaWQgMCE9PXQubWVtTiYmKHRoaXMubWVtTj10Lm1lbU4pLHZvaWQgMCE9PXQucHJ0SW5OJiYodGhpcy5wcnRJbk49dC5wcnRJbk4pLHZvaWQgMCE9PXQucHJ0T3V0TiYmKHRoaXMucHJ0T3V0Tj10LnBydE91dE4pLHZvaWQgMCE9PXQuaW5pdFZpZGVvQnVmUXQmJih0aGlzLmluaXRWaWRlb0J1ZlF0PXQuaW5pdFZpZGVvQnVmUXQpLHZvaWQgMCE9PXQudmlkZW9BdmdCdWZRdCYmKHRoaXMudmlkZW9BdmdCdWZRdD10LnZpZGVvQXZnQnVmUXQpLHZvaWQgMCE9PXQudmlkZW9CdWZRdCYmKHRoaXMudmlkZW9CdWZRdD10LnZpZGVvQnVmUXQpLHZvaWQgMCE9PXQudmlkZW9CdWZOJiYodGhpcy52aWRlb0J1Zk49dC52aWRlb0J1Zk4pLHZvaWQgMCE9PXQuaW5pdEF1ZGlvQnVmUXQmJih0aGlzLmluaXRBdWRpb0J1ZlF0PXQuaW5pdEF1ZGlvQnVmUXQpLHZvaWQgMCE9PXQuYXVkaW9BdmdCdWZRdCYmKHRoaXMuYXVkaW9BdmdCdWZRdD10LmF1ZGlvQXZnQnVmUXQpLHZvaWQgMCE9PXQuYXVkaW9CdWZRdCYmKHRoaXMuYXVkaW9CdWZRdD10LmF1ZGlvQnVmUXQpLHZvaWQgMCE9PXQuYXVkaW9CdWZOJiYodGhpcy5hdWRpb0J1Zk49dC5hdWRpb0J1Zk4pLHZvaWQgMCE9PXQuYml0cmF0ZVVwTiYmKHRoaXMuYml0cmF0ZVVwTj10LmJpdHJhdGVVcE4pLHZvaWQgMCE9PXQuYml0cmF0ZUR3bk4mJih0aGlzLmJpdHJhdGVEd25OPXQuYml0cmF0ZUR3bk4pLHZvaWQgMCE9PXQuZGVsYXkmJih0aGlzLmRlbGF5PXQuZGVsYXkpLHZvaWQgMCE9PXQuZGVsYXlFbmZvcmNlbWVudCYmKHRoaXMuZGVsYXlFbmZvcmNlbWVudD10LmRlbGF5RW5mb3JjZW1lbnQpLHZvaWQgMCE9PXQubG9va3VwUmVxRXN0YWJsaXNoZWQmJih0aGlzLmxvb2t1cFJlcUVzdGFibGlzaGVkPXQubG9va3VwUmVxRXN0YWJsaXNoZWQpLHZvaWQgMCE9PXQubG9va3VwUmVxQWNjZXB0JiYodGhpcy5sb29rdXBSZXFBY2NlcHQ9dC5sb29rdXBSZXFBY2NlcHQpLHZvaWQgMCE9PXQuZmFsbGJhY2tBdmdUcCYmKHRoaXMuZmFsbGJhY2tBdmdUcD10LmZhbGxiYWNrQXZnVHApLHZvaWQgMCE9PXQuc3JjVGhyb3VnaHB1dCYmKHRoaXMuc3JjVGhyb3VnaHB1dD10LnNyY1Rocm91Z2hwdXQpLHZvaWQgMCE9PXQuZGlza1JlYWRUaW1lb3V0JiYodGhpcy5kaXNrUmVhZFRpbWVvdXQ9dC5kaXNrUmVhZFRpbWVvdXQpLHZvaWQgMCE9PXQuZGlza1JlYWRSYXRlJiYodGhpcy5kaXNrUmVhZFJhdGU9dC5kaXNrUmVhZFJhdGUpLHZvaWQgMCE9PXQuZGlza1N0b3JlUmF0ZSYmKHRoaXMuZGlza1N0b3JlUmF0ZT10LmRpc2tTdG9yZVJhdGUpLHZvaWQgMCE9PXQuZGlza1JlbW92ZVJhdGUmJih0aGlzLmRpc2tSZW1vdmVSYXRlPXQuZGlza1JlbW92ZVJhdGUpLHZvaWQgMCE9PXQuZGlza0NhY2hlU2l6ZSYmKHRoaXMuZGlza0NhY2hlU2l6ZT10LmRpc2tDYWNoZVNpemUpLHZvaWQgMCE9PXQuY2xpZW50QnVmZmVyTXMmJih0aGlzLmNsaWVudEJ1ZmZlck1zPXQuY2xpZW50QnVmZmVyTXMpLHZvaWQgMCE9PXQubG9va3VwVG90YWwmJih0aGlzLmxvb2t1cFRvdGFsPXQubG9va3VwVG90YWwpLHZvaWQgMCE9PXQubG9va3VwTm90Rm91bmQmJih0aGlzLmxvb2t1cE5vdEZvdW5kPXQubG9va3VwTm90Rm91bmQpLHZvaWQgMCE9PXQubG9va3VwRmFpbGVkJiYodGhpcy5sb29rdXBGYWlsZWQ9dC5sb29rdXBGYWlsZWQpLHZvaWQgMCE9PXQubG9va3VwTGF0ZW5jeSYmKHRoaXMubG9va3VwTGF0ZW5jeT10Lmxvb2t1cExhdGVuY3kpLHZvaWQgMCE9PXQudHJhY2tlckZhaWxlZCYmKHRoaXMudHJhY2tlckZhaWxlZD10LnRyYWNrZXJGYWlsZWQpLHZvaWQgMCE9PXQudHJhY2tlckxhdGVuY3kmJih0aGlzLnRyYWNrZXJMYXRlbmN5PXQudHJhY2tlckxhdGVuY3kpLHZvaWQgMCE9PXQuc25hcHNob3RGYWlsZWQmJih0aGlzLnNuYXBzaG90RmFpbGVkPXQuc25hcHNob3RGYWlsZWQpLHZvaWQgMCE9PXQuc25hcHNob3RMYXRlbmN5JiYodGhpcy5zbmFwc2hvdExhdGVuY3k9dC5zbmFwc2hvdExhdGVuY3kpKX0saGl2ZS5zbmFwc2hvdHMuTWV0cmljcy5wcm90b3R5cGU9e30saGl2ZS5zbmFwc2hvdHMuTWV0cmljcy5wcm90b3R5cGUucmVhZD1mdW5jdGlvbih0KXtmb3IodC5IYygpOzspe3ZhciBlPXQuc2EoKSxpPShlLkJjLGUuYWEpLG49ZS5jYTtpZihpPT1yLmJzLkVzKWJyZWFrO3N3aXRjaChuKXtjYXNlIDE6aT09ci5icy5Pcz90aGlzLnVwQlc9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyOmk9PXIuYnMuT3M/dGhpcy5kb3duQlc9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzOmk9PXIuYnMuT3M/dGhpcy5tZW1OPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNDppPT1yLmJzLk9zP3RoaXMucHJ0SW5OPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNTppPT1yLmJzLk9zP3RoaXMucHJ0T3V0Tj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDY6aT09ci5icy5Qcz90aGlzLmluaXRWaWRlb0J1ZlF0PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNzppPT1yLmJzLmtzP3RoaXMudmlkZW9BdmdCdWZRdD10LlljKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDg6aT09ci5icy5Qcz90aGlzLnZpZGVvQnVmUXQ9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA5Omk9PXIuYnMuT3M/dGhpcy52aWRlb0J1Zk49dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAxMDppPT1yLmJzLk9zP3RoaXMuaW5pdEF1ZGlvQnVmUXQ9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAxMTppPT1yLmJzLmtzP3RoaXMuYXVkaW9BdmdCdWZRdD10LlljKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDEyOmk9PXIuYnMuUHM/dGhpcy5hdWRpb0J1ZlF0PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTM6aT09ci5icy5Pcz90aGlzLmF1ZGlvQnVmTj10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDE0Omk9PXIuYnMuT3M/dGhpcy5iaXRyYXRlVXBOPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTU6aT09ci5icy5Pcz90aGlzLmJpdHJhdGVEd25OPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTY6aT09ci5icy5Pcz90aGlzLmRlbGF5PXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTc6aT09ci5icy5Pcz90aGlzLmRlbGF5RW5mb3JjZW1lbnQ9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAxODppPT1yLmJzLk9zP3RoaXMubG9va3VwUmVxRXN0YWJsaXNoZWQ9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAxOTppPT1yLmJzLk9zP3RoaXMubG9va3VwUmVxQWNjZXB0PXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjA6aT09ci5icy5rcz90aGlzLmZhbGxiYWNrQXZnVHA9dC5ZYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyMTppPT1yLmJzLmtzP3RoaXMuc3JjVGhyb3VnaHB1dD10LlljKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDIyOmk9PXIuYnMuT3M/dGhpcy5kaXNrUmVhZFRpbWVvdXQ9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyMzppPT1yLmJzLmtzP3RoaXMuZGlza1JlYWRSYXRlPXQuWWMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjQ6aT09ci5icy5rcz90aGlzLmRpc2tTdG9yZVJhdGU9dC5ZYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyNTppPT1yLmJzLmtzP3RoaXMuZGlza1JlbW92ZVJhdGU9dC5ZYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyNjppPT1yLmJzLlBzP3RoaXMuZGlza0NhY2hlU2l6ZT10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI3Omk9PXIuYnMuT3M/dGhpcy5jbGllbnRCdWZmZXJNcz10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI4Omk9PXIuYnMuT3M/dGhpcy5sb29rdXBUb3RhbD10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI5Omk9PXIuYnMuT3M/dGhpcy5sb29rdXBOb3RGb3VuZD10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDMwOmk9PXIuYnMuT3M/dGhpcy5sb29rdXBGYWlsZWQ9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzMTppPT1yLmJzLk9zP3RoaXMubG9va3VwTGF0ZW5jeT10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDMyOmk9PXIuYnMuT3M/dGhpcy50cmFja2VyRmFpbGVkPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzM6aT09ci5icy5Pcz90aGlzLnRyYWNrZXJMYXRlbmN5PXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzQ6aT09ci5icy5Pcz90aGlzLnNuYXBzaG90RmFpbGVkPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzU6aT09ci5icy5Pcz90aGlzLnNuYXBzaG90TGF0ZW5jeT10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztkZWZhdWx0OnQucGEoaSl9dC5sYSgpfXQuZGEoKX0saGl2ZS5zbmFwc2hvdHMuTWV0cmljcy5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24odCl7dC5mYShcIk1ldHJpY3NcIiksbnVsbCE9PXRoaXMudXBCVyYmdm9pZCAwIT09dGhpcy51cEJXJiYodC5nYShcInVwQldcIixyLmJzLk9zLDEpLHQubWEodGhpcy51cEJXKSx0LnlhKCkpLG51bGwhPT10aGlzLmRvd25CVyYmdm9pZCAwIT09dGhpcy5kb3duQlcmJih0LmdhKFwiZG93bkJXXCIsci5icy5PcywyKSx0Lm1hKHRoaXMuZG93bkJXKSx0LnlhKCkpLG51bGwhPT10aGlzLm1lbU4mJnZvaWQgMCE9PXRoaXMubWVtTiYmKHQuZ2EoXCJtZW1OXCIsci5icy5PcywzKSx0Lm1hKHRoaXMubWVtTiksdC55YSgpKSxudWxsIT09dGhpcy5wcnRJbk4mJnZvaWQgMCE9PXRoaXMucHJ0SW5OJiYodC5nYShcInBydEluTlwiLHIuYnMuT3MsNCksdC5tYSh0aGlzLnBydEluTiksdC55YSgpKSxudWxsIT09dGhpcy5wcnRPdXROJiZ2b2lkIDAhPT10aGlzLnBydE91dE4mJih0LmdhKFwicHJ0T3V0TlwiLHIuYnMuT3MsNSksdC5tYSh0aGlzLnBydE91dE4pLHQueWEoKSksbnVsbCE9PXRoaXMuaW5pdFZpZGVvQnVmUXQmJnZvaWQgMCE9PXRoaXMuaW5pdFZpZGVvQnVmUXQmJih0LmdhKFwiaW5pdFZpZGVvQnVmUXRcIixyLmJzLlBzLDYpLHQuQ2ModGhpcy5pbml0VmlkZW9CdWZRdCksdC55YSgpKSxudWxsIT09dGhpcy52aWRlb0F2Z0J1ZlF0JiZ2b2lkIDAhPT10aGlzLnZpZGVvQXZnQnVmUXQmJih0LmdhKFwidmlkZW9BdmdCdWZRdFwiLHIuYnMua3MsNyksdC5PYyh0aGlzLnZpZGVvQXZnQnVmUXQpLHQueWEoKSksbnVsbCE9PXRoaXMudmlkZW9CdWZRdCYmdm9pZCAwIT09dGhpcy52aWRlb0J1ZlF0JiYodC5nYShcInZpZGVvQnVmUXRcIixyLmJzLlBzLDgpLHQuQ2ModGhpcy52aWRlb0J1ZlF0KSx0LnlhKCkpLG51bGwhPT10aGlzLnZpZGVvQnVmTiYmdm9pZCAwIT09dGhpcy52aWRlb0J1Zk4mJih0LmdhKFwidmlkZW9CdWZOXCIsci5icy5Pcyw5KSx0Lm1hKHRoaXMudmlkZW9CdWZOKSx0LnlhKCkpLG51bGwhPT10aGlzLmluaXRBdWRpb0J1ZlF0JiZ2b2lkIDAhPT10aGlzLmluaXRBdWRpb0J1ZlF0JiYodC5nYShcImluaXRBdWRpb0J1ZlF0XCIsci5icy5PcywxMCksdC5tYSh0aGlzLmluaXRBdWRpb0J1ZlF0KSx0LnlhKCkpLG51bGwhPT10aGlzLmF1ZGlvQXZnQnVmUXQmJnZvaWQgMCE9PXRoaXMuYXVkaW9BdmdCdWZRdCYmKHQuZ2EoXCJhdWRpb0F2Z0J1ZlF0XCIsci5icy5rcywxMSksdC5PYyh0aGlzLmF1ZGlvQXZnQnVmUXQpLHQueWEoKSksbnVsbCE9PXRoaXMuYXVkaW9CdWZRdCYmdm9pZCAwIT09dGhpcy5hdWRpb0J1ZlF0JiYodC5nYShcImF1ZGlvQnVmUXRcIixyLmJzLlBzLDEyKSx0LkNjKHRoaXMuYXVkaW9CdWZRdCksdC55YSgpKSxudWxsIT09dGhpcy5hdWRpb0J1Zk4mJnZvaWQgMCE9PXRoaXMuYXVkaW9CdWZOJiYodC5nYShcImF1ZGlvQnVmTlwiLHIuYnMuT3MsMTMpLHQubWEodGhpcy5hdWRpb0J1Zk4pLHQueWEoKSksbnVsbCE9PXRoaXMuYml0cmF0ZVVwTiYmdm9pZCAwIT09dGhpcy5iaXRyYXRlVXBOJiYodC5nYShcImJpdHJhdGVVcE5cIixyLmJzLk9zLDE0KSx0Lm1hKHRoaXMuYml0cmF0ZVVwTiksdC55YSgpKSxudWxsIT09dGhpcy5iaXRyYXRlRHduTiYmdm9pZCAwIT09dGhpcy5iaXRyYXRlRHduTiYmKHQuZ2EoXCJiaXRyYXRlRHduTlwiLHIuYnMuT3MsMTUpLHQubWEodGhpcy5iaXRyYXRlRHduTiksdC55YSgpKSxudWxsIT09dGhpcy5kZWxheSYmdm9pZCAwIT09dGhpcy5kZWxheSYmKHQuZ2EoXCJkZWxheVwiLHIuYnMuT3MsMTYpLHQubWEodGhpcy5kZWxheSksdC55YSgpKSxudWxsIT09dGhpcy5kZWxheUVuZm9yY2VtZW50JiZ2b2lkIDAhPT10aGlzLmRlbGF5RW5mb3JjZW1lbnQmJih0LmdhKFwiZGVsYXlFbmZvcmNlbWVudFwiLHIuYnMuT3MsMTcpLHQubWEodGhpcy5kZWxheUVuZm9yY2VtZW50KSx0LnlhKCkpLG51bGwhPT10aGlzLmxvb2t1cFJlcUVzdGFibGlzaGVkJiZ2b2lkIDAhPT10aGlzLmxvb2t1cFJlcUVzdGFibGlzaGVkJiYodC5nYShcImxvb2t1cFJlcUVzdGFibGlzaGVkXCIsci5icy5PcywxOCksdC5tYSh0aGlzLmxvb2t1cFJlcUVzdGFibGlzaGVkKSx0LnlhKCkpLG51bGwhPT10aGlzLmxvb2t1cFJlcUFjY2VwdCYmdm9pZCAwIT09dGhpcy5sb29rdXBSZXFBY2NlcHQmJih0LmdhKFwibG9va3VwUmVxQWNjZXB0XCIsci5icy5PcywxOSksdC5tYSh0aGlzLmxvb2t1cFJlcUFjY2VwdCksdC55YSgpKSxudWxsIT09dGhpcy5mYWxsYmFja0F2Z1RwJiZ2b2lkIDAhPT10aGlzLmZhbGxiYWNrQXZnVHAmJih0LmdhKFwiZmFsbGJhY2tBdmdUcFwiLHIuYnMua3MsMjApLHQuT2ModGhpcy5mYWxsYmFja0F2Z1RwKSx0LnlhKCkpLG51bGwhPT10aGlzLnNyY1Rocm91Z2hwdXQmJnZvaWQgMCE9PXRoaXMuc3JjVGhyb3VnaHB1dCYmKHQuZ2EoXCJzcmNUaHJvdWdocHV0XCIsci5icy5rcywyMSksdC5PYyh0aGlzLnNyY1Rocm91Z2hwdXQpLHQueWEoKSksbnVsbCE9PXRoaXMuZGlza1JlYWRUaW1lb3V0JiZ2b2lkIDAhPT10aGlzLmRpc2tSZWFkVGltZW91dCYmKHQuZ2EoXCJkaXNrUmVhZFRpbWVvdXRcIixyLmJzLk9zLDIyKSx0Lm1hKHRoaXMuZGlza1JlYWRUaW1lb3V0KSx0LnlhKCkpLG51bGwhPT10aGlzLmRpc2tSZWFkUmF0ZSYmdm9pZCAwIT09dGhpcy5kaXNrUmVhZFJhdGUmJih0LmdhKFwiZGlza1JlYWRSYXRlXCIsci5icy5rcywyMyksdC5PYyh0aGlzLmRpc2tSZWFkUmF0ZSksdC55YSgpKSxudWxsIT09dGhpcy5kaXNrU3RvcmVSYXRlJiZ2b2lkIDAhPT10aGlzLmRpc2tTdG9yZVJhdGUmJih0LmdhKFwiZGlza1N0b3JlUmF0ZVwiLHIuYnMua3MsMjQpLHQuT2ModGhpcy5kaXNrU3RvcmVSYXRlKSx0LnlhKCkpLG51bGwhPT10aGlzLmRpc2tSZW1vdmVSYXRlJiZ2b2lkIDAhPT10aGlzLmRpc2tSZW1vdmVSYXRlJiYodC5nYShcImRpc2tSZW1vdmVSYXRlXCIsci5icy5rcywyNSksdC5PYyh0aGlzLmRpc2tSZW1vdmVSYXRlKSx0LnlhKCkpLG51bGwhPT10aGlzLmRpc2tDYWNoZVNpemUmJnZvaWQgMCE9PXRoaXMuZGlza0NhY2hlU2l6ZSYmKHQuZ2EoXCJkaXNrQ2FjaGVTaXplXCIsci5icy5QcywyNiksdC5DYyh0aGlzLmRpc2tDYWNoZVNpemUpLHQueWEoKSksbnVsbCE9PXRoaXMuY2xpZW50QnVmZmVyTXMmJnZvaWQgMCE9PXRoaXMuY2xpZW50QnVmZmVyTXMmJih0LmdhKFwiY2xpZW50QnVmZmVyTXNcIixyLmJzLk9zLDI3KSx0Lm1hKHRoaXMuY2xpZW50QnVmZmVyTXMpLHQueWEoKSksbnVsbCE9PXRoaXMubG9va3VwVG90YWwmJnZvaWQgMCE9PXRoaXMubG9va3VwVG90YWwmJih0LmdhKFwibG9va3VwVG90YWxcIixyLmJzLk9zLDI4KSx0Lm1hKHRoaXMubG9va3VwVG90YWwpLHQueWEoKSksbnVsbCE9PXRoaXMubG9va3VwTm90Rm91bmQmJnZvaWQgMCE9PXRoaXMubG9va3VwTm90Rm91bmQmJih0LmdhKFwibG9va3VwTm90Rm91bmRcIixyLmJzLk9zLDI5KSx0Lm1hKHRoaXMubG9va3VwTm90Rm91bmQpLHQueWEoKSksbnVsbCE9PXRoaXMubG9va3VwRmFpbGVkJiZ2b2lkIDAhPT10aGlzLmxvb2t1cEZhaWxlZCYmKHQuZ2EoXCJsb29rdXBGYWlsZWRcIixyLmJzLk9zLDMwKSx0Lm1hKHRoaXMubG9va3VwRmFpbGVkKSx0LnlhKCkpLG51bGwhPT10aGlzLmxvb2t1cExhdGVuY3kmJnZvaWQgMCE9PXRoaXMubG9va3VwTGF0ZW5jeSYmKHQuZ2EoXCJsb29rdXBMYXRlbmN5XCIsci5icy5PcywzMSksdC5tYSh0aGlzLmxvb2t1cExhdGVuY3kpLHQueWEoKSksbnVsbCE9PXRoaXMudHJhY2tlckZhaWxlZCYmdm9pZCAwIT09dGhpcy50cmFja2VyRmFpbGVkJiYodC5nYShcInRyYWNrZXJGYWlsZWRcIixyLmJzLk9zLDMyKSx0Lm1hKHRoaXMudHJhY2tlckZhaWxlZCksdC55YSgpKSxudWxsIT09dGhpcy50cmFja2VyTGF0ZW5jeSYmdm9pZCAwIT09dGhpcy50cmFja2VyTGF0ZW5jeSYmKHQuZ2EoXCJ0cmFja2VyTGF0ZW5jeVwiLHIuYnMuT3MsMzMpLHQubWEodGhpcy50cmFja2VyTGF0ZW5jeSksdC55YSgpKSxudWxsIT09dGhpcy5zbmFwc2hvdEZhaWxlZCYmdm9pZCAwIT09dGhpcy5zbmFwc2hvdEZhaWxlZCYmKHQuZ2EoXCJzbmFwc2hvdEZhaWxlZFwiLHIuYnMuT3MsMzQpLHQubWEodGhpcy5zbmFwc2hvdEZhaWxlZCksdC55YSgpKSxudWxsIT09dGhpcy5zbmFwc2hvdExhdGVuY3kmJnZvaWQgMCE9PXRoaXMuc25hcHNob3RMYXRlbmN5JiYodC5nYShcInNuYXBzaG90TGF0ZW5jeVwiLHIuYnMuT3MsMzUpLHQubWEodGhpcy5zbmFwc2hvdExhdGVuY3kpLHQueWEoKSksdC53YSgpLHQuVGEoKX0saGl2ZS5zbmFwc2hvdHMuUGFydG5lclRyYWZmaWM9ZnVuY3Rpb24odCl7dGhpcy5wMnBTdWNjUmVxPW51bGwsdGhpcy5wMnBGYWlsUmVxPW51bGwsdGhpcy5wMnBQYXJ0UmVxPW51bGwsdGhpcy5wMnBTdWNjUmVjZWl2ZWQ9bnVsbCx0aGlzLnAycFN1Y2NSZWNlaXZlZExvdz1udWxsLHRoaXMucDJwRmFpbFJlY2VpdmVkPW51bGwsdGhpcy5wMnBTdWNjUmVzcD1udWxsLHRoaXMucDJwRmFpbFJlc3A9bnVsbCx0aGlzLnAycFBhcnRSZXNwPW51bGwsdGhpcy5wMnBTdWNjU2VudD1udWxsLHRoaXMucDJwU3VjY1NlbnRMb3c9bnVsbCx0aGlzLnAycEZhaWxTZW50PW51bGwsdCYmKHZvaWQgMCE9PXQucDJwU3VjY1JlcSYmKHRoaXMucDJwU3VjY1JlcT10LnAycFN1Y2NSZXEpLHZvaWQgMCE9PXQucDJwRmFpbFJlcSYmKHRoaXMucDJwRmFpbFJlcT10LnAycEZhaWxSZXEpLHZvaWQgMCE9PXQucDJwUGFydFJlcSYmKHRoaXMucDJwUGFydFJlcT10LnAycFBhcnRSZXEpLHZvaWQgMCE9PXQucDJwU3VjY1JlY2VpdmVkJiYodGhpcy5wMnBTdWNjUmVjZWl2ZWQ9dC5wMnBTdWNjUmVjZWl2ZWQpLHZvaWQgMCE9PXQucDJwU3VjY1JlY2VpdmVkTG93JiYodGhpcy5wMnBTdWNjUmVjZWl2ZWRMb3c9dC5wMnBTdWNjUmVjZWl2ZWRMb3cpLHZvaWQgMCE9PXQucDJwRmFpbFJlY2VpdmVkJiYodGhpcy5wMnBGYWlsUmVjZWl2ZWQ9dC5wMnBGYWlsUmVjZWl2ZWQpLHZvaWQgMCE9PXQucDJwU3VjY1Jlc3AmJih0aGlzLnAycFN1Y2NSZXNwPXQucDJwU3VjY1Jlc3ApLHZvaWQgMCE9PXQucDJwRmFpbFJlc3AmJih0aGlzLnAycEZhaWxSZXNwPXQucDJwRmFpbFJlc3ApLHZvaWQgMCE9PXQucDJwUGFydFJlc3AmJih0aGlzLnAycFBhcnRSZXNwPXQucDJwUGFydFJlc3ApLHZvaWQgMCE9PXQucDJwU3VjY1NlbnQmJih0aGlzLnAycFN1Y2NTZW50PXQucDJwU3VjY1NlbnQpLHZvaWQgMCE9PXQucDJwU3VjY1NlbnRMb3cmJih0aGlzLnAycFN1Y2NTZW50TG93PXQucDJwU3VjY1NlbnRMb3cpLHZvaWQgMCE9PXQucDJwRmFpbFNlbnQmJih0aGlzLnAycEZhaWxTZW50PXQucDJwRmFpbFNlbnQpKX0saGl2ZS5zbmFwc2hvdHMuUGFydG5lclRyYWZmaWMucHJvdG90eXBlPXt9LGhpdmUuc25hcHNob3RzLlBhcnRuZXJUcmFmZmljLnByb3RvdHlwZS5yZWFkPWZ1bmN0aW9uKHQpe2Zvcih0LkhjKCk7Oyl7dmFyIGU9dC5zYSgpLGk9KGUuQmMsZS5hYSksbj1lLmNhO2lmKGk9PXIuYnMuRXMpYnJlYWs7c3dpdGNoKG4pe2Nhc2UgMTppPT1yLmJzLlBzP3RoaXMucDJwU3VjY1JlcT10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI6aT09ci5icy5Qcz90aGlzLnAycEZhaWxSZXE9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzOmk9PXIuYnMuUHM/dGhpcy5wMnBQYXJ0UmVxPXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNDppPT1yLmJzLlBzP3RoaXMucDJwU3VjY1JlY2VpdmVkPXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNTppPT1yLmJzLlBzP3RoaXMucDJwU3VjY1JlY2VpdmVkTG93PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTA6aT09ci5icy5Qcz90aGlzLnAycEZhaWxSZWNlaXZlZD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDY6aT09ci5icy5Qcz90aGlzLnAycFN1Y2NSZXNwPXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTE6aT09ci5icy5Qcz90aGlzLnAycEZhaWxSZXNwPXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNzppPT1yLmJzLlBzP3RoaXMucDJwUGFydFJlc3A9dC4kYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA4Omk9PXIuYnMuUHM/dGhpcy5wMnBTdWNjU2VudD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDk6aT09ci5icy5Qcz90aGlzLnAycFN1Y2NTZW50TG93PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTI6aT09ci5icy5Qcz90aGlzLnAycEZhaWxTZW50PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2RlZmF1bHQ6dC5wYShpKX10LmxhKCl9dC5kYSgpfSxoaXZlLnNuYXBzaG90cy5QYXJ0bmVyVHJhZmZpYy5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24odCl7dC5mYShcIlBhcnRuZXJUcmFmZmljXCIpLG51bGwhPT10aGlzLnAycFN1Y2NSZXEmJnZvaWQgMCE9PXRoaXMucDJwU3VjY1JlcSYmKHQuZ2EoXCJwMnBTdWNjUmVxXCIsci5icy5QcywxKSx0LkNjKHRoaXMucDJwU3VjY1JlcSksdC55YSgpKSxudWxsIT09dGhpcy5wMnBGYWlsUmVxJiZ2b2lkIDAhPT10aGlzLnAycEZhaWxSZXEmJih0LmdhKFwicDJwRmFpbFJlcVwiLHIuYnMuUHMsMiksdC5DYyh0aGlzLnAycEZhaWxSZXEpLHQueWEoKSksbnVsbCE9PXRoaXMucDJwUGFydFJlcSYmdm9pZCAwIT09dGhpcy5wMnBQYXJ0UmVxJiYodC5nYShcInAycFBhcnRSZXFcIixyLmJzLlBzLDMpLHQuQ2ModGhpcy5wMnBQYXJ0UmVxKSx0LnlhKCkpLG51bGwhPT10aGlzLnAycFN1Y2NSZWNlaXZlZCYmdm9pZCAwIT09dGhpcy5wMnBTdWNjUmVjZWl2ZWQmJih0LmdhKFwicDJwU3VjY1JlY2VpdmVkXCIsci5icy5Qcyw0KSx0LkNjKHRoaXMucDJwU3VjY1JlY2VpdmVkKSx0LnlhKCkpLG51bGwhPT10aGlzLnAycFN1Y2NSZWNlaXZlZExvdyYmdm9pZCAwIT09dGhpcy5wMnBTdWNjUmVjZWl2ZWRMb3cmJih0LmdhKFwicDJwU3VjY1JlY2VpdmVkTG93XCIsci5icy5Qcyw1KSx0LkNjKHRoaXMucDJwU3VjY1JlY2VpdmVkTG93KSx0LnlhKCkpLG51bGwhPT10aGlzLnAycEZhaWxSZWNlaXZlZCYmdm9pZCAwIT09dGhpcy5wMnBGYWlsUmVjZWl2ZWQmJih0LmdhKFwicDJwRmFpbFJlY2VpdmVkXCIsci5icy5QcywxMCksdC5DYyh0aGlzLnAycEZhaWxSZWNlaXZlZCksdC55YSgpKSxudWxsIT09dGhpcy5wMnBTdWNjUmVzcCYmdm9pZCAwIT09dGhpcy5wMnBTdWNjUmVzcCYmKHQuZ2EoXCJwMnBTdWNjUmVzcFwiLHIuYnMuUHMsNiksdC5DYyh0aGlzLnAycFN1Y2NSZXNwKSx0LnlhKCkpLG51bGwhPT10aGlzLnAycEZhaWxSZXNwJiZ2b2lkIDAhPT10aGlzLnAycEZhaWxSZXNwJiYodC5nYShcInAycEZhaWxSZXNwXCIsci5icy5QcywxMSksdC5DYyh0aGlzLnAycEZhaWxSZXNwKSx0LnlhKCkpLG51bGwhPT10aGlzLnAycFBhcnRSZXNwJiZ2b2lkIDAhPT10aGlzLnAycFBhcnRSZXNwJiYodC5nYShcInAycFBhcnRSZXNwXCIsci5icy5Qcyw3KSx0LkNjKHRoaXMucDJwUGFydFJlc3ApLHQueWEoKSksbnVsbCE9PXRoaXMucDJwU3VjY1NlbnQmJnZvaWQgMCE9PXRoaXMucDJwU3VjY1NlbnQmJih0LmdhKFwicDJwU3VjY1NlbnRcIixyLmJzLlBzLDgpLHQuQ2ModGhpcy5wMnBTdWNjU2VudCksdC55YSgpKSxudWxsIT09dGhpcy5wMnBTdWNjU2VudExvdyYmdm9pZCAwIT09dGhpcy5wMnBTdWNjU2VudExvdyYmKHQuZ2EoXCJwMnBTdWNjU2VudExvd1wiLHIuYnMuUHMsOSksdC5DYyh0aGlzLnAycFN1Y2NTZW50TG93KSx0LnlhKCkpLG51bGwhPT10aGlzLnAycEZhaWxTZW50JiZ2b2lkIDAhPT10aGlzLnAycEZhaWxTZW50JiYodC5nYShcInAycEZhaWxTZW50XCIsci5icy5QcywxMiksdC5DYyh0aGlzLnAycEZhaWxTZW50KSx0LnlhKCkpLHQud2EoKSx0LlRhKCl9LGhpdmUuc25hcHNob3RzLlBhcnRuZXJNZXRyaWNzPWZ1bmN0aW9uKHQpe3RoaXMucmF0ZVJlY2VpdmVkPW51bGwsdGhpcy5yYXRlU2VudD1udWxsLHRoaXMuaGFuZHNoYWtlRGVsYXk9bnVsbCx0JiYodm9pZCAwIT09dC5yYXRlUmVjZWl2ZWQmJih0aGlzLnJhdGVSZWNlaXZlZD10LnJhdGVSZWNlaXZlZCksdm9pZCAwIT09dC5yYXRlU2VudCYmKHRoaXMucmF0ZVNlbnQ9dC5yYXRlU2VudCksdm9pZCAwIT09dC5oYW5kc2hha2VEZWxheSYmKHRoaXMuaGFuZHNoYWtlRGVsYXk9dC5oYW5kc2hha2VEZWxheSkpfSxoaXZlLnNuYXBzaG90cy5QYXJ0bmVyTWV0cmljcy5wcm90b3R5cGU9e30saGl2ZS5zbmFwc2hvdHMuUGFydG5lck1ldHJpY3MucHJvdG90eXBlLnJlYWQ9ZnVuY3Rpb24odCl7Zm9yKHQuSGMoKTs7KXt2YXIgZT10LnNhKCksaT0oZS5CYyxlLmFhKSxuPWUuY2E7aWYoaT09ci5icy5FcylicmVhaztzd2l0Y2gobil7Y2FzZSAxOmk9PXIuYnMua3M/dGhpcy5yYXRlUmVjZWl2ZWQ9dC5ZYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyOmk9PXIuYnMua3M/dGhpcy5yYXRlU2VudD10LlljKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM6aT09ci5icy5Qcz90aGlzLmhhbmRzaGFrZURlbGF5PXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2RlZmF1bHQ6dC5wYShpKX10LmxhKCl9dC5kYSgpfSxoaXZlLnNuYXBzaG90cy5QYXJ0bmVyTWV0cmljcy5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24odCl7dC5mYShcIlBhcnRuZXJNZXRyaWNzXCIpLG51bGwhPT10aGlzLnJhdGVSZWNlaXZlZCYmdm9pZCAwIT09dGhpcy5yYXRlUmVjZWl2ZWQmJih0LmdhKFwicmF0ZVJlY2VpdmVkXCIsci5icy5rcywxKSx0Lk9jKHRoaXMucmF0ZVJlY2VpdmVkKSx0LnlhKCkpLG51bGwhPT10aGlzLnJhdGVTZW50JiZ2b2lkIDAhPT10aGlzLnJhdGVTZW50JiYodC5nYShcInJhdGVTZW50XCIsci5icy5rcywyKSx0Lk9jKHRoaXMucmF0ZVNlbnQpLHQueWEoKSksbnVsbCE9PXRoaXMuaGFuZHNoYWtlRGVsYXkmJnZvaWQgMCE9PXRoaXMuaGFuZHNoYWtlRGVsYXkmJih0LmdhKFwiaGFuZHNoYWtlRGVsYXlcIixyLmJzLlBzLDMpLHQuQ2ModGhpcy5oYW5kc2hha2VEZWxheSksdC55YSgpKSx0LndhKCksdC5UYSgpfSxoaXZlLnNuYXBzaG90cy5Db25uZWN0aXZpdHlJbmZvPWZ1bmN0aW9uKHQpe3RoaXMudXBCVz1udWxsLHRoaXMuZG93bkJXPW51bGwsdGhpcy5leHRlcm5hbEFzPW51bGwsdGhpcy5pbnRlcm5hbEFzPW51bGwsdGhpcy5wdWJsaWNJcD1udWxsLHRoaXMucHJpdmF0ZUlwPW51bGwsdCYmKHZvaWQgMCE9PXQudXBCVyYmKHRoaXMudXBCVz10LnVwQlcpLHZvaWQgMCE9PXQuZG93bkJXJiYodGhpcy5kb3duQlc9dC5kb3duQlcpLHZvaWQgMCE9PXQuZXh0ZXJuYWxBcyYmKHRoaXMuZXh0ZXJuYWxBcz10LmV4dGVybmFsQXMpLHZvaWQgMCE9PXQuaW50ZXJuYWxBcyYmKHRoaXMuaW50ZXJuYWxBcz10LmludGVybmFsQXMpLHZvaWQgMCE9PXQucHVibGljSXAmJih0aGlzLnB1YmxpY0lwPXQucHVibGljSXApLHZvaWQgMCE9PXQucHJpdmF0ZUlwJiYodGhpcy5wcml2YXRlSXA9dC5wcml2YXRlSXApKX0saGl2ZS5zbmFwc2hvdHMuQ29ubmVjdGl2aXR5SW5mby5wcm90b3R5cGU9e30saGl2ZS5zbmFwc2hvdHMuQ29ubmVjdGl2aXR5SW5mby5wcm90b3R5cGUucmVhZD1mdW5jdGlvbih0KXtmb3IodC5IYygpOzspe3ZhciBlPXQuc2EoKSxpPShlLkJjLGUuYWEpLG49ZS5jYTtpZihpPT1yLmJzLkVzKWJyZWFrO3N3aXRjaChuKXtjYXNlIDE6aT09ci5icy5Pcz90aGlzLnVwQlc9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyOmk9PXIuYnMuT3M/dGhpcy5kb3duQlc9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzOmk9PXIuYnMuT3M/dGhpcy5leHRlcm5hbEFzPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNDppPT1yLmJzLk9zP3RoaXMuaW50ZXJuYWxBcz10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDU6aT09ci5icy5Bcz90aGlzLnB1YmxpY0lwPXQuaGEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNjppPT1yLmJzLkFzP3RoaXMucHJpdmF0ZUlwPXQuaGEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2RlZmF1bHQ6dC5wYShpKX10LmxhKCl9dC5kYSgpfSxoaXZlLnNuYXBzaG90cy5Db25uZWN0aXZpdHlJbmZvLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbih0KXt0LmZhKFwiQ29ubmVjdGl2aXR5SW5mb1wiKSxudWxsIT09dGhpcy51cEJXJiZ2b2lkIDAhPT10aGlzLnVwQlcmJih0LmdhKFwidXBCV1wiLHIuYnMuT3MsMSksdC5tYSh0aGlzLnVwQlcpLHQueWEoKSksbnVsbCE9PXRoaXMuZG93bkJXJiZ2b2lkIDAhPT10aGlzLmRvd25CVyYmKHQuZ2EoXCJkb3duQldcIixyLmJzLk9zLDIpLHQubWEodGhpcy5kb3duQlcpLHQueWEoKSksbnVsbCE9PXRoaXMuZXh0ZXJuYWxBcyYmdm9pZCAwIT09dGhpcy5leHRlcm5hbEFzJiYodC5nYShcImV4dGVybmFsQXNcIixyLmJzLk9zLDMpLHQubWEodGhpcy5leHRlcm5hbEFzKSx0LnlhKCkpLG51bGwhPT10aGlzLmludGVybmFsQXMmJnZvaWQgMCE9PXRoaXMuaW50ZXJuYWxBcyYmKHQuZ2EoXCJpbnRlcm5hbEFzXCIsci5icy5Pcyw0KSx0Lm1hKHRoaXMuaW50ZXJuYWxBcyksdC55YSgpKSxudWxsIT09dGhpcy5wdWJsaWNJcCYmdm9pZCAwIT09dGhpcy5wdWJsaWNJcCYmKHQuZ2EoXCJwdWJsaWNJcFwiLHIuYnMuQXMsNSksdC52YSh0aGlzLnB1YmxpY0lwKSx0LnlhKCkpLG51bGwhPT10aGlzLnByaXZhdGVJcCYmdm9pZCAwIT09dGhpcy5wcml2YXRlSXAmJih0LmdhKFwicHJpdmF0ZUlwXCIsci5icy5Bcyw2KSx0LnZhKHRoaXMucHJpdmF0ZUlwKSx0LnlhKCkpLHQud2EoKSx0LlRhKCl9LGhpdmUuc25hcHNob3RzLlBhcnRuZXI9ZnVuY3Rpb24odCl7dGhpcy5jb25uSW5mbz1udWxsLHRoaXMudHJhZmZpYz1udWxsLHRoaXMubWV0cmljcz1udWxsLHRoaXMuaW5QYXJ0PW51bGwsdGhpcy5vdXRQYXJ0PW51bGwsdGhpcy51ZHA9bnVsbCx0JiYodm9pZCAwIT09dC5jb25uSW5mbyYmKHRoaXMuY29ubkluZm89dC5jb25uSW5mbyksdm9pZCAwIT09dC50cmFmZmljJiYodGhpcy50cmFmZmljPXQudHJhZmZpYyksdm9pZCAwIT09dC5tZXRyaWNzJiYodGhpcy5tZXRyaWNzPXQubWV0cmljcyksdm9pZCAwIT09dC5pblBhcnQmJih0aGlzLmluUGFydD10LmluUGFydCksdm9pZCAwIT09dC5vdXRQYXJ0JiYodGhpcy5vdXRQYXJ0PXQub3V0UGFydCksdm9pZCAwIT09dC51ZHAmJih0aGlzLnVkcD10LnVkcCkpfSxoaXZlLnNuYXBzaG90cy5QYXJ0bmVyLnByb3RvdHlwZT17fSxoaXZlLnNuYXBzaG90cy5QYXJ0bmVyLnByb3RvdHlwZS5yZWFkPWZ1bmN0aW9uKHQpe2Zvcih0LkhjKCk7Oyl7dmFyIGU9dC5zYSgpLGk9KGUuQmMsZS5hYSksbj1lLmNhO2lmKGk9PXIuYnMuRXMpYnJlYWs7c3dpdGNoKG4pe2Nhc2UgMTppPT1yLmJzLnhzPyh0aGlzLmNvbm5JbmZvPW5ldyBoaXZlLnNuYXBzaG90cy5Db25uZWN0aXZpdHlJbmZvLHRoaXMuY29ubkluZm8ucmVhZCh0KSk6dC5wYShpKTticmVhaztjYXNlIDI6aT09ci5icy54cz8odGhpcy50cmFmZmljPW5ldyBoaXZlLnNuYXBzaG90cy5QYXJ0bmVyVHJhZmZpYyx0aGlzLnRyYWZmaWMucmVhZCh0KSk6dC5wYShpKTticmVhaztjYXNlIDM6aT09ci5icy54cz8odGhpcy5tZXRyaWNzPW5ldyBoaXZlLnNuYXBzaG90cy5QYXJ0bmVyTWV0cmljcyx0aGlzLm1ldHJpY3MucmVhZCh0KSk6dC5wYShpKTticmVhaztjYXNlIDQ6aT09ci5icy5CT09MP3RoaXMuaW5QYXJ0PXQuR2MoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNTppPT1yLmJzLkJPT0w/dGhpcy5vdXRQYXJ0PXQuR2MoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgNjppPT1yLmJzLkJPT0w/dGhpcy51ZHA9dC5HYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7ZGVmYXVsdDp0LnBhKGkpfXQubGEoKX10LmRhKCl9LGhpdmUuc25hcHNob3RzLlBhcnRuZXIucHJvdG90eXBlLndyaXRlPWZ1bmN0aW9uKHQpe3QuZmEoXCJQYXJ0bmVyXCIpLG51bGwhPT10aGlzLmNvbm5JbmZvJiZ2b2lkIDAhPT10aGlzLmNvbm5JbmZvJiYodC5nYShcImNvbm5JbmZvXCIsci5icy54cywxKSx0aGlzLmNvbm5JbmZvLndyaXRlKHQpLHQueWEoKSksbnVsbCE9PXRoaXMudHJhZmZpYyYmdm9pZCAwIT09dGhpcy50cmFmZmljJiYodC5nYShcInRyYWZmaWNcIixyLmJzLnhzLDIpLHRoaXMudHJhZmZpYy53cml0ZSh0KSx0LnlhKCkpLG51bGwhPT10aGlzLm1ldHJpY3MmJnZvaWQgMCE9PXRoaXMubWV0cmljcyYmKHQuZ2EoXCJtZXRyaWNzXCIsci5icy54cywzKSx0aGlzLm1ldHJpY3Mud3JpdGUodCksdC55YSgpKSxudWxsIT09dGhpcy5pblBhcnQmJnZvaWQgMCE9PXRoaXMuaW5QYXJ0JiYodC5nYShcImluUGFydFwiLHIuYnMuQk9PTCw0KSx0LkljKHRoaXMuaW5QYXJ0KSx0LnlhKCkpLG51bGwhPT10aGlzLm91dFBhcnQmJnZvaWQgMCE9PXRoaXMub3V0UGFydCYmKHQuZ2EoXCJvdXRQYXJ0XCIsci5icy5CT09MLDUpLHQuSWModGhpcy5vdXRQYXJ0KSx0LnlhKCkpLG51bGwhPT10aGlzLnVkcCYmdm9pZCAwIT09dGhpcy51ZHAmJih0LmdhKFwidWRwXCIsci5icy5CT09MLDYpLHQuSWModGhpcy51ZHApLHQueWEoKSksdC53YSgpLHQuVGEoKX0saGl2ZS5zbmFwc2hvdHMuU3RyZWFtSW5mbz1mdW5jdGlvbih0KXt0aGlzLnVybD1udWxsLHRoaXMuc3RyZWFtVHlwZT1udWxsLHRoaXMuc3RyZWFtUHJvdG9jb2w9bnVsbCx0JiYodm9pZCAwIT09dC51cmwmJih0aGlzLnVybD10LnVybCksdm9pZCAwIT09dC5zdHJlYW1UeXBlJiYodGhpcy5zdHJlYW1UeXBlPXQuc3RyZWFtVHlwZSksdm9pZCAwIT09dC5zdHJlYW1Qcm90b2NvbCYmKHRoaXMuc3RyZWFtUHJvdG9jb2w9dC5zdHJlYW1Qcm90b2NvbCkpfSxoaXZlLnNuYXBzaG90cy5TdHJlYW1JbmZvLnByb3RvdHlwZT17fSxoaXZlLnNuYXBzaG90cy5TdHJlYW1JbmZvLnByb3RvdHlwZS5yZWFkPWZ1bmN0aW9uKHQpe2Zvcih0LkhjKCk7Oyl7dmFyIGU9dC5zYSgpLGk9KGUuQmMsZS5hYSksbj1lLmNhO2lmKGk9PXIuYnMuRXMpYnJlYWs7c3dpdGNoKG4pe2Nhc2UgMTppPT1yLmJzLkFzP3RoaXMudXJsPXQuaGEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjppPT1yLmJzLk9zP3RoaXMuc3RyZWFtVHlwZT10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM6aT09ci5icy5Pcz90aGlzLnN0cmVhbVByb3RvY29sPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2RlZmF1bHQ6dC5wYShpKX10LmxhKCl9dC5kYSgpfSxoaXZlLnNuYXBzaG90cy5TdHJlYW1JbmZvLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbih0KXt0LmZhKFwiU3RyZWFtSW5mb1wiKSxudWxsIT09dGhpcy51cmwmJnZvaWQgMCE9PXRoaXMudXJsJiYodC5nYShcInVybFwiLHIuYnMuQXMsMSksdC52YSh0aGlzLnVybCksdC55YSgpKSxudWxsIT09dGhpcy5zdHJlYW1UeXBlJiZ2b2lkIDAhPT10aGlzLnN0cmVhbVR5cGUmJih0LmdhKFwic3RyZWFtVHlwZVwiLHIuYnMuT3MsMiksdC5tYSh0aGlzLnN0cmVhbVR5cGUpLHQueWEoKSksbnVsbCE9PXRoaXMuc3RyZWFtUHJvdG9jb2wmJnZvaWQgMCE9PXRoaXMuc3RyZWFtUHJvdG9jb2wmJih0LmdhKFwic3RyZWFtUHJvdG9jb2xcIixyLmJzLk9zLDMpLHQubWEodGhpcy5zdHJlYW1Qcm90b2NvbCksdC55YSgpKSx0LndhKCksdC5UYSgpfSxoaXZlLnNuYXBzaG90cy5DbGllbnRJbmZvPWZ1bmN0aW9uKHQpe3RoaXMuY2xpZW50VHlwZT1udWxsLHRoaXMubWFqb3JWZXJzaW9uPW51bGwsdGhpcy5taW5vclZlcnNpb249bnVsbCx0aGlzLnBhdGNoVmVyc2lvbj1udWxsLHQmJih2b2lkIDAhPT10LmNsaWVudFR5cGUmJih0aGlzLmNsaWVudFR5cGU9dC5jbGllbnRUeXBlKSx2b2lkIDAhPT10Lm1ham9yVmVyc2lvbiYmKHRoaXMubWFqb3JWZXJzaW9uPXQubWFqb3JWZXJzaW9uKSx2b2lkIDAhPT10Lm1pbm9yVmVyc2lvbiYmKHRoaXMubWlub3JWZXJzaW9uPXQubWlub3JWZXJzaW9uKSx2b2lkIDAhPT10LnBhdGNoVmVyc2lvbiYmKHRoaXMucGF0Y2hWZXJzaW9uPXQucGF0Y2hWZXJzaW9uKSl9LGhpdmUuc25hcHNob3RzLkNsaWVudEluZm8ucHJvdG90eXBlPXt9LGhpdmUuc25hcHNob3RzLkNsaWVudEluZm8ucHJvdG90eXBlLnJlYWQ9ZnVuY3Rpb24odCl7Zm9yKHQuSGMoKTs7KXt2YXIgZT10LnNhKCksaT0oZS5CYyxlLmFhKSxuPWUuY2E7aWYoaT09ci5icy5FcylicmVhaztzd2l0Y2gobil7Y2FzZSAxOmk9PXIuYnMuT3M/dGhpcy5jbGllbnRUeXBlPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjppPT1yLmJzLkJZVEU/dGhpcy5tYWpvclZlcnNpb249dC56YygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzOmk9PXIuYnMuQllURT90aGlzLm1pbm9yVmVyc2lvbj10LnpjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDQ6aT09ci5icy5Dcz90aGlzLnBhdGNoVmVyc2lvbj10LldjKCkudmFsdWU6dC5wYShpKTticmVhaztkZWZhdWx0OnQucGEoaSl9dC5sYSgpfXQuZGEoKX0saGl2ZS5zbmFwc2hvdHMuQ2xpZW50SW5mby5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24odCl7dC5mYShcIkNsaWVudEluZm9cIiksbnVsbCE9PXRoaXMuY2xpZW50VHlwZSYmdm9pZCAwIT09dGhpcy5jbGllbnRUeXBlJiYodC5nYShcImNsaWVudFR5cGVcIixyLmJzLk9zLDEpLHQubWEodGhpcy5jbGllbnRUeXBlKSx0LnlhKCkpLG51bGwhPT10aGlzLm1ham9yVmVyc2lvbiYmdm9pZCAwIT09dGhpcy5tYWpvclZlcnNpb24mJih0LmdhKFwibWFqb3JWZXJzaW9uXCIsci5icy5CWVRFLDIpLHQuUmModGhpcy5tYWpvclZlcnNpb24pLHQueWEoKSksbnVsbCE9PXRoaXMubWlub3JWZXJzaW9uJiZ2b2lkIDAhPT10aGlzLm1pbm9yVmVyc2lvbiYmKHQuZ2EoXCJtaW5vclZlcnNpb25cIixyLmJzLkJZVEUsMyksdC5SYyh0aGlzLm1pbm9yVmVyc2lvbiksdC55YSgpKSxudWxsIT09dGhpcy5wYXRjaFZlcnNpb24mJnZvaWQgMCE9PXRoaXMucGF0Y2hWZXJzaW9uJiYodC5nYShcInBhdGNoVmVyc2lvblwiLHIuYnMuQ3MsNCksdC5rYyh0aGlzLnBhdGNoVmVyc2lvbiksdC55YSgpKSx0LndhKCksdC5UYSgpfSxoaXZlLnNuYXBzaG90cy5BZ2VudEluZm89ZnVuY3Rpb24odCl7dGhpcy5maXJzdFRpZXJCaXRyYXRlcz1udWxsLHRoaXMuc2Vjb25kVGllckJpdHJhdGVzPW51bGwsdCYmKHZvaWQgMCE9PXQuZmlyc3RUaWVyQml0cmF0ZXMmJih0aGlzLmZpcnN0VGllckJpdHJhdGVzPXQuZmlyc3RUaWVyQml0cmF0ZXMpLHZvaWQgMCE9PXQuc2Vjb25kVGllckJpdHJhdGVzJiYodGhpcy5zZWNvbmRUaWVyQml0cmF0ZXM9dC5zZWNvbmRUaWVyQml0cmF0ZXMpKX0saGl2ZS5zbmFwc2hvdHMuQWdlbnRJbmZvLnByb3RvdHlwZT17fSxoaXZlLnNuYXBzaG90cy5BZ2VudEluZm8ucHJvdG90eXBlLnJlYWQ9ZnVuY3Rpb24odCl7Zm9yKHQuSGMoKTs7KXt2YXIgZT10LnNhKCksaT0oZS5CYyxlLmFhKSxuPWUuY2E7aWYoaT09ci5icy5FcylicmVhaztzd2l0Y2gobil7Y2FzZSAxOmlmKGk9PXIuYnMuRnMpe3ZhciBvLHM9MDt0aGlzLmZpcnN0VGllckJpdHJhdGVzPVtdO3ZhciBhPTA7bz10LkpjKCksYT1vLlFjLHM9by5zaXplO2Zvcih2YXIgYz0wO2M8czsrK2Mpe3ZhciBoPW51bGw7aD10LnVhKCkudmFsdWUsdGhpcy5maXJzdFRpZXJCaXRyYXRlcy5wdXNoKGgpfXQuS2MoKX1lbHNlIHQucGEoaSk7YnJlYWs7Y2FzZSAyOmlmKGk9PXIuYnMuRnMpe3ZhciBwLHU9MDt0aGlzLnNlY29uZFRpZXJCaXRyYXRlcz1bXTt2YXIgbD0wO3A9dC5KYygpLGw9cC5RYyx1PXAuc2l6ZTtmb3IodmFyIGQ9MDtkPHU7KytkKXt2YXIgZj1udWxsO2Y9dC51YSgpLnZhbHVlLHRoaXMuc2Vjb25kVGllckJpdHJhdGVzLnB1c2goZil9dC5LYygpfWVsc2UgdC5wYShpKTticmVhaztkZWZhdWx0OnQucGEoaSl9dC5sYSgpfXQuZGEoKX0saGl2ZS5zbmFwc2hvdHMuQWdlbnRJbmZvLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbih0KXtcbiAgaWYodC5mYShcIkFnZW50SW5mb1wiKSxudWxsIT09dGhpcy5maXJzdFRpZXJCaXRyYXRlcyYmdm9pZCAwIT09dGhpcy5maXJzdFRpZXJCaXRyYXRlcyl7dC5nYShcImZpcnN0VGllckJpdHJhdGVzXCIsci5icy5GcywxKSx0LmJjKHIuYnMuT3MsdGhpcy5maXJzdFRpZXJCaXRyYXRlcy5sZW5ndGgpO2Zvcih2YXIgZSBpbiB0aGlzLmZpcnN0VGllckJpdHJhdGVzKXRoaXMuZmlyc3RUaWVyQml0cmF0ZXMuaGFzT3duUHJvcGVydHkoZSkmJihlPXRoaXMuZmlyc3RUaWVyQml0cmF0ZXNbZV0sdC5tYShlKSk7dC5FYygpLHQueWEoKX1pZihudWxsIT09dGhpcy5zZWNvbmRUaWVyQml0cmF0ZXMmJnZvaWQgMCE9PXRoaXMuc2Vjb25kVGllckJpdHJhdGVzKXt0LmdhKFwic2Vjb25kVGllckJpdHJhdGVzXCIsci5icy5GcywyKSx0LmJjKHIuYnMuT3MsdGhpcy5zZWNvbmRUaWVyQml0cmF0ZXMubGVuZ3RoKTtmb3IodmFyIGkgaW4gdGhpcy5zZWNvbmRUaWVyQml0cmF0ZXMpdGhpcy5zZWNvbmRUaWVyQml0cmF0ZXMuaGFzT3duUHJvcGVydHkoaSkmJihpPXRoaXMuc2Vjb25kVGllckJpdHJhdGVzW2ldLHQubWEoaSkpO3QuRWMoKSx0LnlhKCl9dC53YSgpLHQuVGEoKX0saGl2ZS5zbmFwc2hvdHMuVHJhZmZpY0tleT1mdW5jdGlvbih0KXt0aGlzLmJpdHJhdGU9bnVsbCx0aGlzLkFTPW51bGwsdGhpcy5wYXJ0bmVyR3VpZD1udWxsLHQmJih2b2lkIDAhPT10LmJpdHJhdGUmJih0aGlzLmJpdHJhdGU9dC5iaXRyYXRlKSx2b2lkIDAhPT10LkFTJiYodGhpcy5BUz10LkFTKSx2b2lkIDAhPT10LnBhcnRuZXJHdWlkJiYodGhpcy5wYXJ0bmVyR3VpZD10LnBhcnRuZXJHdWlkKSl9LGhpdmUuc25hcHNob3RzLlRyYWZmaWNLZXkucHJvdG90eXBlPXt9LGhpdmUuc25hcHNob3RzLlRyYWZmaWNLZXkucHJvdG90eXBlLnJlYWQ9ZnVuY3Rpb24odCl7Zm9yKHQuSGMoKTs7KXt2YXIgZT10LnNhKCksaT0oZS5CYyxlLmFhKSxuPWUuY2E7aWYoaT09ci5icy5FcylicmVhaztzd2l0Y2gobil7Y2FzZSAxOmk9PXIuYnMuT3M/dGhpcy5iaXRyYXRlPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjppPT1yLmJzLk9zP3RoaXMuQVM9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzOmk9PXIuYnMuQXM/dGhpcy5wYXJ0bmVyR3VpZD10LmhhKCkudmFsdWU6dC5wYShpKTticmVhaztkZWZhdWx0OnQucGEoaSl9dC5sYSgpfXQuZGEoKX0saGl2ZS5zbmFwc2hvdHMuVHJhZmZpY0tleS5wcm90b3R5cGUud3JpdGU9ZnVuY3Rpb24odCl7dC5mYShcIlRyYWZmaWNLZXlcIiksbnVsbCE9PXRoaXMuYml0cmF0ZSYmdm9pZCAwIT09dGhpcy5iaXRyYXRlJiYodC5nYShcImJpdHJhdGVcIixyLmJzLk9zLDEpLHQubWEodGhpcy5iaXRyYXRlKSx0LnlhKCkpLG51bGwhPT10aGlzLkFTJiZ2b2lkIDAhPT10aGlzLkFTJiYodC5nYShcIkFTXCIsci5icy5PcywyKSx0Lm1hKHRoaXMuQVMpLHQueWEoKSksbnVsbCE9PXRoaXMucGFydG5lckd1aWQmJnZvaWQgMCE9PXRoaXMucGFydG5lckd1aWQmJih0LmdhKFwicGFydG5lckd1aWRcIixyLmJzLkFzLDMpLHQudmEodGhpcy5wYXJ0bmVyR3VpZCksdC55YSgpKSx0LndhKCksdC5UYSgpfSxoaXZlLnNuYXBzaG90cy5QYXJ0bmVyS2V5PWZ1bmN0aW9uKHQpe3RoaXMuYml0cmF0ZT1udWxsLHRoaXMuQVM9bnVsbCx0aGlzLnBhcnRuZXJHdWlkPW51bGwsdCYmKHZvaWQgMCE9PXQuYml0cmF0ZSYmKHRoaXMuYml0cmF0ZT10LmJpdHJhdGUpLHZvaWQgMCE9PXQuQVMmJih0aGlzLkFTPXQuQVMpLHZvaWQgMCE9PXQucGFydG5lckd1aWQmJih0aGlzLnBhcnRuZXJHdWlkPXQucGFydG5lckd1aWQpKX0saGl2ZS5zbmFwc2hvdHMuUGFydG5lcktleS5wcm90b3R5cGU9e30saGl2ZS5zbmFwc2hvdHMuUGFydG5lcktleS5wcm90b3R5cGUucmVhZD1mdW5jdGlvbih0KXtmb3IodC5IYygpOzspe3ZhciBlPXQuc2EoKSxpPShlLkJjLGUuYWEpLG49ZS5jYTtpZihpPT1yLmJzLkVzKWJyZWFrO3N3aXRjaChuKXtjYXNlIDE6aT09ci5icy5Pcz90aGlzLmJpdHJhdGU9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAyOmk9PXIuYnMuT3M/dGhpcy5BUz10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM6aT09ci5icy5Bcz90aGlzLnBhcnRuZXJHdWlkPXQuaGEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2RlZmF1bHQ6dC5wYShpKX10LmxhKCl9dC5kYSgpfSxoaXZlLnNuYXBzaG90cy5QYXJ0bmVyS2V5LnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbih0KXt0LmZhKFwiUGFydG5lcktleVwiKSxudWxsIT09dGhpcy5iaXRyYXRlJiZ2b2lkIDAhPT10aGlzLmJpdHJhdGUmJih0LmdhKFwiYml0cmF0ZVwiLHIuYnMuT3MsMSksdC5tYSh0aGlzLmJpdHJhdGUpLHQueWEoKSksbnVsbCE9PXRoaXMuQVMmJnZvaWQgMCE9PXRoaXMuQVMmJih0LmdhKFwiQVNcIixyLmJzLk9zLDIpLHQubWEodGhpcy5BUyksdC55YSgpKSxudWxsIT09dGhpcy5wYXJ0bmVyR3VpZCYmdm9pZCAwIT09dGhpcy5wYXJ0bmVyR3VpZCYmKHQuZ2EoXCJwYXJ0bmVyR3VpZFwiLHIuYnMuQXMsMyksdC52YSh0aGlzLnBhcnRuZXJHdWlkKSx0LnlhKCkpLHQud2EoKSx0LlRhKCl9LGhpdmUuc25hcHNob3RzLlBsYXllcj1mdW5jdGlvbih0KXt0aGlzLmJ1ZmZlcmluZ049bnVsbCx0aGlzLmJ1ZmZlcmluZ01zPW51bGwsdGhpcy5pbml0QnVmZmVyaW5nTj1udWxsLHRoaXMuaW5pdEJ1ZmZlcmluZ01zPW51bGwsdGhpcy5zZWVrQnVmZmVyaW5nTj1udWxsLHRoaXMuc2Vla0J1ZmZlcmluZ01zPW51bGwsdGhpcy5wbGF5ZXJCdWZmZXJNcz1udWxsLHQmJih2b2lkIDAhPT10LmJ1ZmZlcmluZ04mJih0aGlzLmJ1ZmZlcmluZ049dC5idWZmZXJpbmdOKSx2b2lkIDAhPT10LmJ1ZmZlcmluZ01zJiYodGhpcy5idWZmZXJpbmdNcz10LmJ1ZmZlcmluZ01zKSx2b2lkIDAhPT10LmluaXRCdWZmZXJpbmdOJiYodGhpcy5pbml0QnVmZmVyaW5nTj10LmluaXRCdWZmZXJpbmdOKSx2b2lkIDAhPT10LmluaXRCdWZmZXJpbmdNcyYmKHRoaXMuaW5pdEJ1ZmZlcmluZ01zPXQuaW5pdEJ1ZmZlcmluZ01zKSx2b2lkIDAhPT10LnNlZWtCdWZmZXJpbmdOJiYodGhpcy5zZWVrQnVmZmVyaW5nTj10LnNlZWtCdWZmZXJpbmdOKSx2b2lkIDAhPT10LnNlZWtCdWZmZXJpbmdNcyYmKHRoaXMuc2Vla0J1ZmZlcmluZ01zPXQuc2Vla0J1ZmZlcmluZ01zKSx2b2lkIDAhPT10LnBsYXllckJ1ZmZlck1zJiYodGhpcy5wbGF5ZXJCdWZmZXJNcz10LnBsYXllckJ1ZmZlck1zKSl9LGhpdmUuc25hcHNob3RzLlBsYXllci5wcm90b3R5cGU9e30saGl2ZS5zbmFwc2hvdHMuUGxheWVyLnByb3RvdHlwZS5yZWFkPWZ1bmN0aW9uKHQpe2Zvcih0LkhjKCk7Oyl7dmFyIGU9dC5zYSgpLGk9KGUuQmMsZS5hYSksbj1lLmNhO2lmKGk9PXIuYnMuRXMpYnJlYWs7c3dpdGNoKG4pe2Nhc2UgMTppPT1yLmJzLkNzP3RoaXMuYnVmZmVyaW5nTj10LldjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI6aT09ci5icy5Pcz90aGlzLmJ1ZmZlcmluZ01zPXQudWEoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMzppPT1yLmJzLkNzP3RoaXMuaW5pdEJ1ZmZlcmluZ049dC5XYygpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA0Omk9PXIuYnMuT3M/dGhpcy5pbml0QnVmZmVyaW5nTXM9dC51YSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSA1Omk9PXIuYnMuQ3M/dGhpcy5zZWVrQnVmZmVyaW5nTj10LldjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDY6aT09ci5icy5Pcz90aGlzLnNlZWtCdWZmZXJpbmdNcz10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM2Omk9PXIuYnMuT3M/dGhpcy5wbGF5ZXJCdWZmZXJNcz10LnVhKCkudmFsdWU6dC5wYShpKTticmVhaztkZWZhdWx0OnQucGEoaSl9dC5sYSgpfXQuZGEoKX0saGl2ZS5zbmFwc2hvdHMuUGxheWVyLnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbih0KXt0LmZhKFwiUGxheWVyXCIpLG51bGwhPT10aGlzLmJ1ZmZlcmluZ04mJnZvaWQgMCE9PXRoaXMuYnVmZmVyaW5nTiYmKHQuZ2EoXCJidWZmZXJpbmdOXCIsci5icy5DcywxKSx0LmtjKHRoaXMuYnVmZmVyaW5nTiksdC55YSgpKSxudWxsIT09dGhpcy5idWZmZXJpbmdNcyYmdm9pZCAwIT09dGhpcy5idWZmZXJpbmdNcyYmKHQuZ2EoXCJidWZmZXJpbmdNc1wiLHIuYnMuT3MsMiksdC5tYSh0aGlzLmJ1ZmZlcmluZ01zKSx0LnlhKCkpLG51bGwhPT10aGlzLmluaXRCdWZmZXJpbmdOJiZ2b2lkIDAhPT10aGlzLmluaXRCdWZmZXJpbmdOJiYodC5nYShcImluaXRCdWZmZXJpbmdOXCIsci5icy5DcywzKSx0LmtjKHRoaXMuaW5pdEJ1ZmZlcmluZ04pLHQueWEoKSksbnVsbCE9PXRoaXMuaW5pdEJ1ZmZlcmluZ01zJiZ2b2lkIDAhPT10aGlzLmluaXRCdWZmZXJpbmdNcyYmKHQuZ2EoXCJpbml0QnVmZmVyaW5nTXNcIixyLmJzLk9zLDQpLHQubWEodGhpcy5pbml0QnVmZmVyaW5nTXMpLHQueWEoKSksbnVsbCE9PXRoaXMuc2Vla0J1ZmZlcmluZ04mJnZvaWQgMCE9PXRoaXMuc2Vla0J1ZmZlcmluZ04mJih0LmdhKFwic2Vla0J1ZmZlcmluZ05cIixyLmJzLkNzLDUpLHQua2ModGhpcy5zZWVrQnVmZmVyaW5nTiksdC55YSgpKSxudWxsIT09dGhpcy5zZWVrQnVmZmVyaW5nTXMmJnZvaWQgMCE9PXRoaXMuc2Vla0J1ZmZlcmluZ01zJiYodC5nYShcInNlZWtCdWZmZXJpbmdNc1wiLHIuYnMuT3MsNiksdC5tYSh0aGlzLnNlZWtCdWZmZXJpbmdNcyksdC55YSgpKSxudWxsIT09dGhpcy5wbGF5ZXJCdWZmZXJNcyYmdm9pZCAwIT09dGhpcy5wbGF5ZXJCdWZmZXJNcyYmKHQuZ2EoXCJwbGF5ZXJCdWZmZXJNc1wiLHIuYnMuT3MsMzYpLHQubWEodGhpcy5wbGF5ZXJCdWZmZXJNcyksdC55YSgpKSx0LndhKCksdC5UYSgpfSxoaXZlLnNuYXBzaG90cy5NZXRyaWNTbmFwc2hvdD1mdW5jdGlvbih0KXt0aGlzLnRpbWVzdGFtcD1udWxsLHRoaXMuZ3VpZD1udWxsLHRoaXMuZXZlbnRJZD1udWxsLHRoaXMuc3RyZWFtSW5mbz1udWxsLHRoaXMubWV0cmljcz1udWxsLHRoaXMudHJhZmZpYz1udWxsLHRoaXMuc25hcHNob3RJbmZvPW51bGwsdGhpcy5hZ2VudEluZm89bnVsbCx0aGlzLmNvbm5JbmZvPW51bGwsdGhpcy5wYXJ0bmVycz1udWxsLHRoaXMucGxheWVyPW51bGwsdGhpcy5jbGllbnQ9bnVsbCx0aGlzLnNlc3Npb25JZD1udWxsLHQmJih2b2lkIDAhPT10LnRpbWVzdGFtcCYmKHRoaXMudGltZXN0YW1wPXQudGltZXN0YW1wKSx2b2lkIDAhPT10Lmd1aWQmJih0aGlzLmd1aWQ9dC5ndWlkKSx2b2lkIDAhPT10LmV2ZW50SWQmJih0aGlzLmV2ZW50SWQ9dC5ldmVudElkKSx2b2lkIDAhPT10LnN0cmVhbUluZm8mJih0aGlzLnN0cmVhbUluZm89dC5zdHJlYW1JbmZvKSx2b2lkIDAhPT10Lm1ldHJpY3MmJih0aGlzLm1ldHJpY3M9dC5tZXRyaWNzKSx2b2lkIDAhPT10LnRyYWZmaWMmJih0aGlzLnRyYWZmaWM9dC50cmFmZmljKSx2b2lkIDAhPT10LnNuYXBzaG90SW5mbyYmKHRoaXMuc25hcHNob3RJbmZvPXQuc25hcHNob3RJbmZvKSx2b2lkIDAhPT10LmFnZW50SW5mbyYmKHRoaXMuYWdlbnRJbmZvPXQuYWdlbnRJbmZvKSx2b2lkIDAhPT10LmNvbm5JbmZvJiYodGhpcy5jb25uSW5mbz10LmNvbm5JbmZvKSx2b2lkIDAhPT10LnBhcnRuZXJzJiYodGhpcy5wYXJ0bmVycz10LnBhcnRuZXJzKSx2b2lkIDAhPT10LnBsYXllciYmKHRoaXMucGxheWVyPXQucGxheWVyKSx2b2lkIDAhPT10LmNsaWVudCYmKHRoaXMuY2xpZW50PXQuY2xpZW50KSx2b2lkIDAhPT10LnNlc3Npb25JZCYmKHRoaXMuc2Vzc2lvbklkPXQuc2Vzc2lvbklkKSl9LGhpdmUuc25hcHNob3RzLk1ldHJpY1NuYXBzaG90LnByb3RvdHlwZT17fSxoaXZlLnNuYXBzaG90cy5NZXRyaWNTbmFwc2hvdC5wcm90b3R5cGUucmVhZD1mdW5jdGlvbih0KXtmb3IodC5IYygpOzspe3ZhciBlPXQuc2EoKSxpPShlLkJjLGUuYWEpLG49ZS5jYTtpZihpPT1yLmJzLkVzKWJyZWFrO3N3aXRjaChuKXtjYXNlIDE6aT09ci5icy5Qcz90aGlzLnRpbWVzdGFtcD10LiRjKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDI6aT09ci5icy5Bcz90aGlzLmd1aWQ9dC5oYSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7Y2FzZSAzOmk9PXIuYnMueHM/KHRoaXMuZXZlbnRJZD1uZXcgRXZlbnRJZCx0aGlzLmV2ZW50SWQucmVhZCh0KSk6dC5wYShpKTticmVhaztjYXNlIDQ6aT09ci5icy54cz8odGhpcy5zdHJlYW1JbmZvPW5ldyBoaXZlLnNuYXBzaG90cy5TdHJlYW1JbmZvLHRoaXMuc3RyZWFtSW5mby5yZWFkKHQpKTp0LnBhKGkpO2JyZWFrO2Nhc2UgNTppPT1yLmJzLnhzPyh0aGlzLm1ldHJpY3M9bmV3IGhpdmUuc25hcHNob3RzLk1ldHJpY3MsdGhpcy5tZXRyaWNzLnJlYWQodCkpOnQucGEoaSk7YnJlYWs7Y2FzZSA2OmlmKGk9PXIuYnMuQnMpe3ZhciBvLHM9MDt0aGlzLnRyYWZmaWM9e307dmFyIGE9MCxjPTA7bz10LkxjKCksYT1vLk1jLGM9by5qYyxzPW8uc2l6ZTtmb3IodmFyIGg9MDtoPHM7KytoKXtoPjAmJnQuTmMubGVuZ3RoPnQuUmFbdC5SYS5sZW5ndGgtMV0rMSYmdC5OYy5wb3AoKTt2YXIgcD1udWxsLHU9bnVsbDtwPW5ldyBoaXZlLnNuYXBzaG90cy5UcmFmZmljS2V5LHAucmVhZCh0KSx1PW5ldyBoaXZlLnNuYXBzaG90cy5UcmFmZmljLHUucmVhZCh0KSx0aGlzLnRyYWZmaWNbcF09dX10LlVjKCl9ZWxzZSB0LnBhKGkpO2JyZWFrO2Nhc2UgNzppPT1yLmJzLnhzPyh0aGlzLnNuYXBzaG90SW5mbz1uZXcgU25hcHNob3RJbmZvLHRoaXMuc25hcHNob3RJbmZvLnJlYWQodCkpOnQucGEoaSk7YnJlYWs7Y2FzZSA4Omk9PXIuYnMueHM/KHRoaXMuYWdlbnRJbmZvPW5ldyBoaXZlLnNuYXBzaG90cy5BZ2VudEluZm8sdGhpcy5hZ2VudEluZm8ucmVhZCh0KSk6dC5wYShpKTticmVhaztjYXNlIDk6aT09ci5icy54cz8odGhpcy5jb25uSW5mbz1uZXcgaGl2ZS5zbmFwc2hvdHMuQ29ubmVjdGl2aXR5SW5mbyx0aGlzLmNvbm5JbmZvLnJlYWQodCkpOnQucGEoaSk7YnJlYWs7Y2FzZSAxMDppZihpPT1yLmJzLkJzKXt2YXIgbCxkPTA7dGhpcy5wYXJ0bmVycz17fTt2YXIgZj0wLGc9MDtsPXQuTGMoKSxmPWwuTWMsZz1sLmpjLGQ9bC5zaXplO2Zvcih2YXIgdj0wO3Y8ZDsrK3Ype3Y+MCYmdC5OYy5sZW5ndGg+dC5SYVt0LlJhLmxlbmd0aC0xXSsxJiZ0Lk5jLnBvcCgpO3ZhciB5PW51bGwsbT1udWxsO3k9bmV3IGhpdmUuc25hcHNob3RzLlBhcnRuZXJLZXkseS5yZWFkKHQpLG09bmV3IGhpdmUuc25hcHNob3RzLlBhcnRuZXIsbS5yZWFkKHQpLHRoaXMucGFydG5lcnNbeV09bX10LlVjKCl9ZWxzZSB0LnBhKGkpO2JyZWFrO2Nhc2UgMTE6aT09ci5icy54cz8odGhpcy5wbGF5ZXI9bmV3IGhpdmUuc25hcHNob3RzLlBsYXllcix0aGlzLnBsYXllci5yZWFkKHQpKTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTI6aT09ci5icy54cz8odGhpcy5jbGllbnQ9bmV3IGhpdmUuc25hcHNob3RzLkNsaWVudEluZm8sdGhpcy5jbGllbnQucmVhZCh0KSk6dC5wYShpKTticmVhaztjYXNlIDEzOmk9PXIuYnMuQXM/dGhpcy5zZXNzaW9uSWQ9dC5oYSgpLnZhbHVlOnQucGEoaSk7YnJlYWs7ZGVmYXVsdDp0LnBhKGkpfXQubGEoKX10LmRhKCl9LGhpdmUuc25hcHNob3RzLk1ldHJpY1NuYXBzaG90LnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbih0KXtpZih0LmZhKFwiTWV0cmljU25hcHNob3RcIiksbnVsbCE9PXRoaXMudGltZXN0YW1wJiZ2b2lkIDAhPT10aGlzLnRpbWVzdGFtcCYmKHQuZ2EoXCJ0aW1lc3RhbXBcIixyLmJzLlBzLDEpLHQuQ2ModGhpcy50aW1lc3RhbXApLHQueWEoKSksbnVsbCE9PXRoaXMuZ3VpZCYmdm9pZCAwIT09dGhpcy5ndWlkJiYodC5nYShcImd1aWRcIixyLmJzLkFzLDIpLHQudmEodGhpcy5ndWlkKSx0LnlhKCkpLG51bGwhPT10aGlzLmV2ZW50SWQmJnZvaWQgMCE9PXRoaXMuZXZlbnRJZCYmKHQuZ2EoXCJldmVudElkXCIsci5icy54cywzKSx0aGlzLmV2ZW50SWQud3JpdGUodCksdC55YSgpKSxudWxsIT09dGhpcy5zdHJlYW1JbmZvJiZ2b2lkIDAhPT10aGlzLnN0cmVhbUluZm8mJih0LmdhKFwic3RyZWFtSW5mb1wiLHIuYnMueHMsNCksdGhpcy5zdHJlYW1JbmZvLndyaXRlKHQpLHQueWEoKSksbnVsbCE9PXRoaXMubWV0cmljcyYmdm9pZCAwIT09dGhpcy5tZXRyaWNzJiYodC5nYShcIm1ldHJpY3NcIixyLmJzLnhzLDUpLHRoaXMubWV0cmljcy53cml0ZSh0KSx0LnlhKCkpLG51bGwhPT10aGlzLnRyYWZmaWMmJnZvaWQgMCE9PXRoaXMudHJhZmZpYyl7dC5nYShcInRyYWZmaWNcIixyLmJzLkJzLDYpLHQubWMoci5icy54cyxyLmJzLnhzLHIuUXModGhpcy50cmFmZmljKSk7Zm9yKHZhciBlPTA7ZTx0aGlzLnRyYWZmaWMubGVuZ3RoO2UrKyl7dmFyIGk9dGhpcy50cmFmZmljW2VdLG49aS5rZXksbz1pLnZhbHVlO24ud3JpdGUodCksby53cml0ZSh0KX10LndjKCksdC55YSgpfWlmKG51bGwhPT10aGlzLnNuYXBzaG90SW5mbyYmdm9pZCAwIT09dGhpcy5zbmFwc2hvdEluZm8mJih0LmdhKFwic25hcHNob3RJbmZvXCIsci5icy54cyw3KSx0aGlzLnNuYXBzaG90SW5mby53cml0ZSh0KSx0LnlhKCkpLG51bGwhPT10aGlzLmFnZW50SW5mbyYmdm9pZCAwIT09dGhpcy5hZ2VudEluZm8mJih0LmdhKFwiYWdlbnRJbmZvXCIsci5icy54cyw4KSx0aGlzLmFnZW50SW5mby53cml0ZSh0KSx0LnlhKCkpLG51bGwhPT10aGlzLmNvbm5JbmZvJiZ2b2lkIDAhPT10aGlzLmNvbm5JbmZvJiYodC5nYShcImNvbm5JbmZvXCIsci5icy54cyw5KSx0aGlzLmNvbm5JbmZvLndyaXRlKHQpLHQueWEoKSksbnVsbCE9PXRoaXMucGFydG5lcnMmJnZvaWQgMCE9PXRoaXMucGFydG5lcnMpe3QuZ2EoXCJwYXJ0bmVyc1wiLHIuYnMuQnMsMTApLHQubWMoci5icy54cyxyLmJzLnhzLHIuUXModGhpcy5wYXJ0bmVycykpO2Zvcih2YXIgZT0wO2U8dGhpcy5wYXJ0bmVycy5sZW5ndGg7ZSsrKXt2YXIgaT10aGlzLnBhcnRuZXJzW2VdLHM9aS5rZXksYT1pLnZhbHVlO3Mud3JpdGUodCksYS53cml0ZSh0KX10LndjKCksdC55YSgpfW51bGwhPT10aGlzLnBsYXllciYmdm9pZCAwIT09dGhpcy5wbGF5ZXImJih0LmdhKFwicGxheWVyXCIsci5icy54cywxMSksdGhpcy5wbGF5ZXIud3JpdGUodCksdC55YSgpKSxudWxsIT09dGhpcy5jbGllbnQmJnZvaWQgMCE9PXRoaXMuY2xpZW50JiYodC5nYShcImNsaWVudFwiLHIuYnMueHMsMTIpLHRoaXMuY2xpZW50LndyaXRlKHQpLHQueWEoKSksbnVsbCE9PXRoaXMuc2Vzc2lvbklkJiZ2b2lkIDAhPT10aGlzLnNlc3Npb25JZCYmKHQuZ2EoXCJzZXNzaW9uSWRcIixyLmJzLkFzLDEzKSx0LnZhKHRoaXMuc2Vzc2lvbklkKSx0LnlhKCkpLHQud2EoKSx0LlRhKCl9LGhpdmUuc25hcHNob3RzLkpzb25NZXRyaWNTbmFwc2hvdD1mdW5jdGlvbih0KXt0aGlzLnRpbWVzdGFtcD1udWxsLHRoaXMuZ3VpZD1udWxsLHRoaXMuZXZlbnRJZD1udWxsLHRoaXMuc3RyZWFtSW5mbz1udWxsLHRoaXMubWV0cmljcz1udWxsLHRoaXMudHJhZmZpYz1udWxsLHRoaXMuc25hcHNob3RJbmZvPW51bGwsdGhpcy5hZ2VudEluZm89bnVsbCx0aGlzLmNvbm5JbmZvPW51bGwsdGhpcy5wYXJ0bmVycz1udWxsLHRoaXMucGxheWVyPW51bGwsdGhpcy5jbGllbnQ9bnVsbCx0aGlzLnNlc3Npb25JZD1udWxsLHQmJih2b2lkIDAhPT10LnRpbWVzdGFtcCYmKHRoaXMudGltZXN0YW1wPXQudGltZXN0YW1wKSx2b2lkIDAhPT10Lmd1aWQmJih0aGlzLmd1aWQ9dC5ndWlkKSx2b2lkIDAhPT10LmV2ZW50SWQmJih0aGlzLmV2ZW50SWQ9dC5ldmVudElkKSx2b2lkIDAhPT10LnN0cmVhbUluZm8mJih0aGlzLnN0cmVhbUluZm89dC5zdHJlYW1JbmZvKSx2b2lkIDAhPT10Lm1ldHJpY3MmJih0aGlzLm1ldHJpY3M9dC5tZXRyaWNzKSx2b2lkIDAhPT10LnRyYWZmaWMmJih0aGlzLnRyYWZmaWM9dC50cmFmZmljKSx2b2lkIDAhPT10LnNuYXBzaG90SW5mbyYmKHRoaXMuc25hcHNob3RJbmZvPXQuc25hcHNob3RJbmZvKSx2b2lkIDAhPT10LmFnZW50SW5mbyYmKHRoaXMuYWdlbnRJbmZvPXQuYWdlbnRJbmZvKSx2b2lkIDAhPT10LmNvbm5JbmZvJiYodGhpcy5jb25uSW5mbz10LmNvbm5JbmZvKSx2b2lkIDAhPT10LnBhcnRuZXJzJiYodGhpcy5wYXJ0bmVycz10LnBhcnRuZXJzKSx2b2lkIDAhPT10LnBsYXllciYmKHRoaXMucGxheWVyPXQucGxheWVyKSx2b2lkIDAhPT10LmNsaWVudCYmKHRoaXMuY2xpZW50PXQuY2xpZW50KSx2b2lkIDAhPT10LnNlc3Npb25JZCYmKHRoaXMuc2Vzc2lvbklkPXQuc2Vzc2lvbklkKSl9LGhpdmUuc25hcHNob3RzLkpzb25NZXRyaWNTbmFwc2hvdC5wcm90b3R5cGU9e30saGl2ZS5zbmFwc2hvdHMuSnNvbk1ldHJpY1NuYXBzaG90LnByb3RvdHlwZS5yZWFkPWZ1bmN0aW9uKHQpe2Zvcih0LkhjKCk7Oyl7dmFyIGU9dC5zYSgpLGk9KGUuQmMsZS5hYSksbj1lLmNhO2lmKGk9PXIuYnMuRXMpYnJlYWs7c3dpdGNoKG4pe2Nhc2UgMTppPT1yLmJzLlBzP3RoaXMudGltZXN0YW1wPXQuJGMoKS52YWx1ZTp0LnBhKGkpO2JyZWFrO2Nhc2UgMjppPT1yLmJzLkFzP3RoaXMuZ3VpZD10LmhhKCkudmFsdWU6dC5wYShpKTticmVhaztjYXNlIDM6aT09ci5icy54cz8odGhpcy5ldmVudElkPW5ldyBFdmVudElkLHRoaXMuZXZlbnRJZC5yZWFkKHQpKTp0LnBhKGkpO2JyZWFrO2Nhc2UgNDppPT1yLmJzLnhzPyh0aGlzLnN0cmVhbUluZm89bmV3IGhpdmUuc25hcHNob3RzLlN0cmVhbUluZm8sdGhpcy5zdHJlYW1JbmZvLnJlYWQodCkpOnQucGEoaSk7YnJlYWs7Y2FzZSA1Omk9PXIuYnMueHM/KHRoaXMubWV0cmljcz1uZXcgaGl2ZS5zbmFwc2hvdHMuTWV0cmljcyx0aGlzLm1ldHJpY3MucmVhZCh0KSk6dC5wYShpKTticmVhaztjYXNlIDY6aWYoaT09ci5icy5Ccyl7dmFyIG8scz0wO3RoaXMudHJhZmZpYz17fTt2YXIgYT0wLGM9MDtvPXQuTGMoKSxhPW8uTWMsYz1vLmpjLHM9by5zaXplO2Zvcih2YXIgaD0wO2g8czsrK2gpe2g+MCYmdC5OYy5sZW5ndGg+dC5SYVt0LlJhLmxlbmd0aC0xXSsxJiZ0Lk5jLnBvcCgpO3ZhciBwPW51bGwsdT1udWxsO3A9dC5oYSgpLnZhbHVlLHU9bmV3IGhpdmUuc25hcHNob3RzLlRyYWZmaWMsdS5yZWFkKHQpLHRoaXMudHJhZmZpY1twXT11fXQuVWMoKX1lbHNlIHQucGEoaSk7YnJlYWs7Y2FzZSA3Omk9PXIuYnMueHM/KHRoaXMuc25hcHNob3RJbmZvPW5ldyBTbmFwc2hvdEluZm8sdGhpcy5zbmFwc2hvdEluZm8ucmVhZCh0KSk6dC5wYShpKTticmVhaztjYXNlIDg6aT09ci5icy54cz8odGhpcy5hZ2VudEluZm89bmV3IGhpdmUuc25hcHNob3RzLkFnZW50SW5mbyx0aGlzLmFnZW50SW5mby5yZWFkKHQpKTp0LnBhKGkpO2JyZWFrO2Nhc2UgOTppPT1yLmJzLnhzPyh0aGlzLmNvbm5JbmZvPW5ldyBoaXZlLnNuYXBzaG90cy5Db25uZWN0aXZpdHlJbmZvLHRoaXMuY29ubkluZm8ucmVhZCh0KSk6dC5wYShpKTticmVhaztjYXNlIDEwOmlmKGk9PXIuYnMuQnMpe3ZhciBsLGQ9MDt0aGlzLnBhcnRuZXJzPXt9O3ZhciBmPTAsZz0wO2w9dC5MYygpLGY9bC5NYyxnPWwuamMsZD1sLnNpemU7Zm9yKHZhciB2PTA7djxkOysrdil7dj4wJiZ0Lk5jLmxlbmd0aD50LlJhW3QuUmEubGVuZ3RoLTFdKzEmJnQuTmMucG9wKCk7dmFyIHk9bnVsbCxtPW51bGw7eT10LmhhKCkudmFsdWUsbT1uZXcgaGl2ZS5zbmFwc2hvdHMuUGFydG5lcixtLnJlYWQodCksdGhpcy5wYXJ0bmVyc1t5XT1tfXQuVWMoKX1lbHNlIHQucGEoaSk7YnJlYWs7Y2FzZSAxMTppPT1yLmJzLnhzPyh0aGlzLnBsYXllcj1uZXcgaGl2ZS5zbmFwc2hvdHMuUGxheWVyLHRoaXMucGxheWVyLnJlYWQodCkpOnQucGEoaSk7YnJlYWs7Y2FzZSAxMjppPT1yLmJzLnhzPyh0aGlzLmNsaWVudD1uZXcgaGl2ZS5zbmFwc2hvdHMuQ2xpZW50SW5mbyx0aGlzLmNsaWVudC5yZWFkKHQpKTp0LnBhKGkpO2JyZWFrO2Nhc2UgMTM6aT09ci5icy5Bcz90aGlzLnNlc3Npb25JZD10LmhhKCkudmFsdWU6dC5wYShpKTticmVhaztkZWZhdWx0OnQucGEoaSl9dC5sYSgpfXQuZGEoKX0saGl2ZS5zbmFwc2hvdHMuSnNvbk1ldHJpY1NuYXBzaG90LnByb3RvdHlwZS53cml0ZT1mdW5jdGlvbih0KXtpZih0LmZhKFwiSnNvbk1ldHJpY1NuYXBzaG90XCIpLG51bGwhPT10aGlzLnRpbWVzdGFtcCYmdm9pZCAwIT09dGhpcy50aW1lc3RhbXAmJih0LmdhKFwidGltZXN0YW1wXCIsci5icy5QcywxKSx0LkNjKHRoaXMudGltZXN0YW1wKSx0LnlhKCkpLG51bGwhPT10aGlzLmd1aWQmJnZvaWQgMCE9PXRoaXMuZ3VpZCYmKHQuZ2EoXCJndWlkXCIsci5icy5BcywyKSx0LnZhKHRoaXMuZ3VpZCksdC55YSgpKSxudWxsIT09dGhpcy5ldmVudElkJiZ2b2lkIDAhPT10aGlzLmV2ZW50SWQmJih0LmdhKFwiZXZlbnRJZFwiLHIuYnMueHMsMyksdGhpcy5ldmVudElkLndyaXRlKHQpLHQueWEoKSksbnVsbCE9PXRoaXMuc3RyZWFtSW5mbyYmdm9pZCAwIT09dGhpcy5zdHJlYW1JbmZvJiYodC5nYShcInN0cmVhbUluZm9cIixyLmJzLnhzLDQpLHRoaXMuc3RyZWFtSW5mby53cml0ZSh0KSx0LnlhKCkpLG51bGwhPT10aGlzLm1ldHJpY3MmJnZvaWQgMCE9PXRoaXMubWV0cmljcyYmKHQuZ2EoXCJtZXRyaWNzXCIsci5icy54cyw1KSx0aGlzLm1ldHJpY3Mud3JpdGUodCksdC55YSgpKSxudWxsIT09dGhpcy50cmFmZmljJiZ2b2lkIDAhPT10aGlzLnRyYWZmaWMpe3QuZ2EoXCJ0cmFmZmljXCIsci5icy5Ccyw2KSx0Lm1jKHIuYnMuQXMsci5icy54cyxyLlFzKHRoaXMudHJhZmZpYykpO2Zvcih2YXIgZSBpbiB0aGlzLnRyYWZmaWMpaWYodGhpcy50cmFmZmljLmhhc093blByb3BlcnR5KGUpKXt2YXIgaT10aGlzLnRyYWZmaWNbZV07dC52YShlKSxpLndyaXRlKHQpfXQud2MoKSx0LnlhKCl9aWYobnVsbCE9PXRoaXMuc25hcHNob3RJbmZvJiZ2b2lkIDAhPT10aGlzLnNuYXBzaG90SW5mbyYmKHQuZ2EoXCJzbmFwc2hvdEluZm9cIixyLmJzLnhzLDcpLHRoaXMuc25hcHNob3RJbmZvLndyaXRlKHQpLHQueWEoKSksbnVsbCE9PXRoaXMuYWdlbnRJbmZvJiZ2b2lkIDAhPT10aGlzLmFnZW50SW5mbyYmKHQuZ2EoXCJhZ2VudEluZm9cIixyLmJzLnhzLDgpLHRoaXMuYWdlbnRJbmZvLndyaXRlKHQpLHQueWEoKSksbnVsbCE9PXRoaXMuY29ubkluZm8mJnZvaWQgMCE9PXRoaXMuY29ubkluZm8mJih0LmdhKFwiY29ubkluZm9cIixyLmJzLnhzLDkpLHRoaXMuY29ubkluZm8ud3JpdGUodCksdC55YSgpKSxudWxsIT09dGhpcy5wYXJ0bmVycyYmdm9pZCAwIT09dGhpcy5wYXJ0bmVycyl7dC5nYShcInBhcnRuZXJzXCIsci5icy5CcywxMCksdC5tYyhyLmJzLkFzLHIuYnMueHMsci5Rcyh0aGlzLnBhcnRuZXJzKSk7Zm9yKHZhciBuIGluIHRoaXMucGFydG5lcnMpaWYodGhpcy5wYXJ0bmVycy5oYXNPd25Qcm9wZXJ0eShuKSl7dmFyIG89dGhpcy5wYXJ0bmVyc1tuXTt0LnZhKG4pLG8ud3JpdGUodCl9dC53YygpLHQueWEoKX1udWxsIT09dGhpcy5wbGF5ZXImJnZvaWQgMCE9PXRoaXMucGxheWVyJiYodC5nYShcInBsYXllclwiLHIuYnMueHMsMTEpLHRoaXMucGxheWVyLndyaXRlKHQpLHQueWEoKSksbnVsbCE9PXRoaXMuY2xpZW50JiZ2b2lkIDAhPT10aGlzLmNsaWVudCYmKHQuZ2EoXCJjbGllbnRcIixyLmJzLnhzLDEyKSx0aGlzLmNsaWVudC53cml0ZSh0KSx0LnlhKCkpLG51bGwhPT10aGlzLnNlc3Npb25JZCYmdm9pZCAwIT09dGhpcy5zZXNzaW9uSWQmJih0LmdhKFwic2Vzc2lvbklkXCIsci5icy5BcywxMyksdC52YSh0aGlzLnNlc3Npb25JZCksdC55YSgpKSx0LndhKCksdC5UYSgpfX0sZnVuY3Rpb24odCxlKXsvKiEgY29sbGVjdGlvbnMubWluLmpzIHYgMy4wLjAgZ2l0aHViLmNvbS9tb250YWdlanMvY29sbGVjdGlvbnMgKi9cbiAgIWZ1bmN0aW9uKHQpe2Z1bmN0aW9uIGUoKXt0aHJvdyBFcnJvcihcIkNhbid0IGNvbnN0cnVjdC4gR2VuZXJpY0NvbGxlY3Rpb24gaXMgYSBtaXhpbi5cIil9ZnVuY3Rpb24gaSgpe3Rocm93IEVycm9yKFwiQ2FuJ3QgY29uc3RydWN0LiBHZW5lcmljU2V0IGlzIGEgbWl4aW4uXCIpfWZ1bmN0aW9uIHIoKXt9ZnVuY3Rpb24gbigpe3Rocm93IEVycm9yKFwiVGhpcyBpcyBhbiBhYnN0cmFjdCBpbnRlcmZhY2UuIE1peCBpdC4gRG9uJ3QgY29uc3RydWN0IGl0XCIpfWZ1bmN0aW9uIG8oKXt0aHJvdyBFcnJvcihcIkNhbid0IGNvbnN0cnVjdC4gUmFuZ2VDaGFuZ2VzIGlzIGEgbWl4aW4uXCIpfWZ1bmN0aW9uIHMoKXt0aHJvdyBFcnJvcihcIkNhbid0IGNvbnN0cnVjdC4gR2VuZXJpY09yZGVyIGlzIGEgbWl4aW4uXCIpfWZ1bmN0aW9uIGEodCl7aWYoISh0aGlzIGluc3RhbmNlb2YgYSkpcmV0dXJuIG5ldyBhKHQpO2lmKEFycmF5LmlzQXJyYXkodCl8fFwic3RyaW5nXCI9PXR5cGVvZiB0KXJldHVybiBhLkRmKHQpO2lmKHQ9bHQodCksdCBpbnN0YW5jZW9mIGEpcmV0dXJuIHQ7aWYodC5uZXh0KXRoaXMubmV4dD1mdW5jdGlvbigpe3JldHVybiB0Lm5leHQoKX07ZWxzZSBpZih0LkRmKXt2YXIgZT10LkRmKCk7dGhpcy5uZXh0PWZ1bmN0aW9uKCl7cmV0dXJuIGUubmV4dCgpfX1lbHNle2lmKFwiW29iamVjdCBGdW5jdGlvbl1cIiE9PWx0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpKXRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgaXRlcmF0ZVwiKTt0aGlzLm5leHQ9dH19ZnVuY3Rpb24gYyh0LGUsaSl7dGhpcy5IZj10LHRoaXMuc3RhcnQ9bnVsbD09ZT8wOmUsdGhpcy5lbmQ9aX1mdW5jdGlvbiBoKHQsZSxpKXtpZighKHRoaXMgaW5zdGFuY2VvZiBoKSlyZXR1cm4gbmV3IGgodCxlLGkpO3ZhciByPXRoaXMuaGVhZD1uZXcgdGhpcy5Ob2RlO3IubmV4dD1yLHIuTGY9cix0aGlzLk1mPWV8fE9iamVjdC5vbCx0aGlzLmNvbnRlbnQ9aXx8RnVuY3Rpb24uamYsdGhpcy5sZW5ndGg9MCx0aGlzLmFkZEVhY2godCl9ZnVuY3Rpb24gcCh0KXt0aGlzLmhlYWQ9dCx0aGlzLlVmPXQubmV4dH1mdW5jdGlvbiB1KHQpe3RoaXMudmFsdWU9dCx0aGlzLm5leHQ9dGhpcy5MZj1udWxsfWZ1bmN0aW9uIGwoKXt0aHJvdyBFcnJvcihcIkNhbid0IGNvbnN0cnVjdC4gTWFwQ2hhbmdlcyBpcyBhIG1peGluLlwiKX1mdW5jdGlvbiBkKCl7dGhyb3cgRXJyb3IoXCJDYW4ndCBjb25zdHJ1Y3QuIEdlbmVyaWNNYXAgaXMgYSBtaXhpbi5cIil9ZnVuY3Rpb24gZih0LGUpe3JldHVybiB0aGlzIGluc3RhbmNlb2YgZj8odGhpcy5jb250ZW50PWV8fEZ1bmN0aW9uLmpmLHRoaXMuVmY9e30sdGhpcy5sZW5ndGg9MCx2b2lkIHRoaXMuYWRkRWFjaCh0KSk6bmV3IGYodCxlKX1mdW5jdGlvbiBnKHQsZSxpLHIpe3JldHVybiB0aGlzIGluc3RhbmNlb2YgZz8oZT1lfHxPYmplY3Qub2wsaT1pfHxPYmplY3QuaGFzaCxyPXJ8fEZ1bmN0aW9uLmpmLHRoaXMuTWY9ZSx0aGlzLlFmPWksdGhpcy5jb250ZW50PXIsdGhpcy5xZj1uZXcgdGhpcy5KZihudWxsLHRoaXMuS2YpLHRoaXMubGVuZ3RoPTAsdm9pZCB0aGlzLmFkZEVhY2godCkpOm5ldyBnKHQsZSxpKX1mdW5jdGlvbiB2KHQsZSxpLHIpe3JldHVybiB0aGlzIGluc3RhbmNlb2Ygdj8oZT1lfHxPYmplY3Qub2wsaT1pfHxPYmplY3QuaGFzaCxyPXJ8fEZ1bmN0aW9uLmpmLHRoaXMuTWY9ZSx0aGlzLlFmPWksdGhpcy5jb250ZW50PXIsdGhpcy5WZj1uZXcgTXQoKHZvaWQgMCksZnVuY3Rpb24odCxpKXtyZXR1cm4gZSh0LmtleSxpLmtleSl9LGZ1bmN0aW9uKHQpe3JldHVybiBpKHQua2V5KX0pLHRoaXMubGVuZ3RoPTAsdm9pZCB0aGlzLmFkZEVhY2godCkpOm5ldyB2KHQsZSxpKX1mdW5jdGlvbiB5KHQsZSxpLHIpe3JldHVybiB0aGlzIGluc3RhbmNlb2YgeT8oZT1lfHxPYmplY3Qub2wsaT1pfHxPYmplY3QuaGFzaCxyPXJ8fEZ1bmN0aW9uLmpmLHRoaXMuTWY9ZSx0aGlzLlFmPWksdGhpcy5jb250ZW50PXIsdGhpcy5vcmRlcj1uZXcgdGhpcy5HZigodm9pZCAwKSxlKSx0aGlzLlZmPW5ldyB0aGlzLnpmKCh2b2lkIDApLGZ1bmN0aW9uKHQsaSl7cmV0dXJuIGUodC52YWx1ZSxpLnZhbHVlKX0sZnVuY3Rpb24odCl7cmV0dXJuIGkodC52YWx1ZSl9KSx0aGlzLmxlbmd0aD0wLHZvaWQgdGhpcy5hZGRFYWNoKHQpKTpuZXcgeSh0LGUsaSl9ZnVuY3Rpb24gbSh0LGUsaSxyLG4pe3JldHVybiB0aGlzIGluc3RhbmNlb2YgbT8oZT1lfHwxLzAsaT1pfHxPYmplY3Qub2wscj1yfHxPYmplY3QuaGFzaCxuPW58fEZ1bmN0aW9uLmpmLHRoaXMuVmY9bmV3IFl0KCh2b2lkIDApLGksciksdGhpcy5NZj1pLHRoaXMuUWY9cix0aGlzLmNvbnRlbnQ9bix0aGlzLm1heExlbmd0aD1lLHRoaXMubGVuZ3RoPTAsdm9pZCB0aGlzLmFkZEVhY2godCkpOm5ldyBtKHQsZSxpLHIpfWZ1bmN0aW9uIHcodCxlLGkscixuKXtyZXR1cm4gdGhpcyBpbnN0YW5jZW9mIHc/KGk9aXx8T2JqZWN0Lm9sLHI9cnx8T2JqZWN0Lmhhc2gsbj1ufHxGdW5jdGlvbi5qZix0aGlzLk1mPWksdGhpcy5RZj1yLHRoaXMuY29udGVudD1uLHRoaXMuVmY9bmV3IGllKCh2b2lkIDApLGUsZnVuY3Rpb24odCxlKXtyZXR1cm4gaSh0LmtleSxlLmtleSl9LGZ1bmN0aW9uKHQpe3JldHVybiByKHQua2V5KX0pLHRoaXMubGVuZ3RoPTAsdm9pZCB0aGlzLmFkZEVhY2godCkpOm5ldyB3KHQsZSxpLHIpfWZ1bmN0aW9uIFQodCxlLGkscil7cmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBUPyhlPWV8fE9iamVjdC5vbCxpPWl8fE9iamVjdC5oYXNoLHI9cnx8RnVuY3Rpb24uamYsdGhpcy5NZj1lLHRoaXMuUWY9aSx0aGlzLmNvbnRlbnQ9cix0aGlzLlZmPW5ldyBhZSgodm9pZCAwKSxmdW5jdGlvbih0LGkpe3JldHVybiBlKHQua2V5LGkua2V5KX0sZnVuY3Rpb24odCl7cmV0dXJuIGkodC5rZXkpfSksdGhpcy5sZW5ndGg9MCx2b2lkIHRoaXMuYWRkRWFjaCh0KSk6bmV3IFQodCxlLGkpfWZ1bmN0aW9uIFModCxlLGkscil7cmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBTPyh0aGlzLldmPWV8fHRoaXMuV2Ysdm9pZCBsZS5jYWxsKHRoaXMsdCxpLHIsZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5XZigpO3JldHVybiBsZS5wcm90b3R5cGUuc2V0LmNhbGwodGhpcyx0LGUpLGV9KSk6bmV3IFModCxlLGkscil9ZnVuY3Rpb24gYih0LGUsaSxyKXtyZXR1cm4gdGhpcyBpbnN0YW5jZW9mIGI/KEFycmF5LmlzQXJyYXkodCk/KHRoaXMuSGY9dCx0PXQuc3BsaWNlKDAsdC5sZW5ndGgpKTp0aGlzLkhmPVtdLHRoaXMuTWY9ZXx8T2JqZWN0Lm9sLHRoaXMuJGY9aXx8T2JqZWN0LllmLHRoaXMuY29udGVudD1yfHxGdW5jdGlvbi5qZix0aGlzLmxlbmd0aD0wLHZvaWQgdGhpcy5hZGRFYWNoKHQpKTpuZXcgYih0LGUsaSxyKX1mdW5jdGlvbiBFKHQsZSxpKXtmb3IodmFyIHI9MCxuPXQubGVuZ3RoLTE7cjw9bjspe3ZhciBvPXIrbj4+MSxzPWkoZSx0W29dKTtpZigwPHMpcj1vKzE7ZWxzZXtpZighKDA+cykpcmV0dXJuIG87bj1vLTF9fXJldHVybi0ocisxKX1mdW5jdGlvbiBJKHQsZSxpLHIpe2lmKGk9RSh0LGUsaSksMD5pKXJldHVybi0xO2Zvcig7MDxpJiZyKGUsdFtpLTFdKTspaS0tO3JldHVybiByKGUsdFtpXSk/aTotMX1mdW5jdGlvbiBSKHQsZSxpLHIpe2lmKGk9RSh0LGUsaSksMD5pKXJldHVybi0xO2Zvcig7aTx0Lmxlbmd0aC0xJiZyKGUsdFtpKzFdKTspaSsrO3JldHVybiByKGUsdFtpXSk/aTotMX1mdW5jdGlvbiBrKHQsZSxpLHIpe3JldHVybiB0aGlzIGluc3RhbmNlb2Ygaz92b2lkIHllLmNhbGwodGhpcyx0LGUsaSxyKTpuZXcgayh0LGUsaSxyKX1mdW5jdGlvbiBDKHQsZSxpLHIpe3JldHVybiB0aGlzIGluc3RhbmNlb2YgQz8oZT1lfHxPYmplY3Qub2wsaT1pfHxPYmplY3QuWWYscj1yfHxGdW5jdGlvbi5qZix0aGlzLk1mPWUsdGhpcy4kZj1pLHRoaXMuY29udGVudD1yLHRoaXMuVmY9bmV3IFNlKG51bGwsZnVuY3Rpb24odCxpKXtyZXR1cm4gZSh0LmtleSxpLmtleSl9LGZ1bmN0aW9uKHQsZSl7cmV0dXJuIGkodC5rZXksZS5rZXkpfSksdGhpcy5sZW5ndGg9MCx2b2lkIHRoaXMuYWRkRWFjaCh0KSk6bmV3IEModCxlLGkscil9ZnVuY3Rpb24gTyh0LGUsaSxyKXtyZXR1cm4gdGhpcyBpbnN0YW5jZW9mIE8/KHRoaXMuTWY9ZXx8T2JqZWN0Lm9sLHRoaXMuJGY9aXx8T2JqZWN0LllmLHRoaXMuY29udGVudD1yfHxGdW5jdGlvbi5qZix0aGlzLnJvb3Q9bnVsbCx0aGlzLmxlbmd0aD0wLHZvaWQgdGhpcy5hZGRFYWNoKHQpKTpuZXcgTyh0LGUsaSxyKX1mdW5jdGlvbiBQKHQpe3RoaXMudmFsdWU9dCx0aGlzLnJpZ2h0PXRoaXMubGVmdD1udWxsLHRoaXMubGVuZ3RoPTF9ZnVuY3Rpb24gQSh0LGUsaSl7dGhpcy5zZXQ9dCx0aGlzLkxmPW51bGwsdGhpcy5lbmQ9aSxlJiYodD10aGlzLnNldC5YZihlKSkmJih0aGlzLnNldC5aZih0LnZhbHVlKSx0aGlzLkxmPXQudGcoKSl9ZnVuY3Rpb24gTih0LGUsaSxyKXtyZXR1cm4gdGhpcyBpbnN0YW5jZW9mIE4/KGU9ZXx8T2JqZWN0Lm9sLGk9aXx8T2JqZWN0LllmLHI9cnx8RnVuY3Rpb24uamYsdGhpcy5NZj1lLHRoaXMuJGY9aSx0aGlzLmNvbnRlbnQ9cix0aGlzLlZmPW5ldyBOZShudWxsLGZ1bmN0aW9uKHQsaSl7cmV0dXJuIGUodC5rZXksaS5rZXkpfSxmdW5jdGlvbih0LGUpe3JldHVybiBpKHQua2V5LGUua2V5KX0pLHRoaXMubGVuZ3RoPTAsdm9pZCB0aGlzLmFkZEVhY2godCkpOm5ldyBOKHQsZSxpLHIpfXZhciB4PXt9O3guZWc9ZSxlLnByb3RvdHlwZS5hZGRFYWNoPWZ1bmN0aW9uKHQpe2lmKHQmJk9iamVjdCh0KT09PXQpaWYoXCJmdW5jdGlvblwiPT10eXBlb2YgdC5mb3JFYWNoKXQuZm9yRWFjaCh0aGlzLmFkZCx0aGlzKTtlbHNlIGlmKFwibnVtYmVyXCI9PXR5cGVvZiB0Lmxlbmd0aClmb3IodmFyIGU9MDtlPHQubGVuZ3RoO2UrKyl0aGlzLmFkZCh0W2VdLGUpO2Vsc2UgT2JqZWN0LmtleXModCkuZm9yRWFjaChmdW5jdGlvbihlKXt0aGlzLmFkZCh0W2VdLGUpfSx0aGlzKX0sZS5wcm90b3R5cGUuaWc9ZnVuY3Rpb24odCl7dC5mb3JFYWNoKGZ1bmN0aW9uKHQpe3RoaXNbXCJkZWxldGVcIl0odCl9LHRoaXMpfSxlLnByb3RvdHlwZS5mb3JFYWNoPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMucmVkdWNlKGZ1bmN0aW9uKGkscixuLG8scyl7dC5jYWxsKGUscixuLG8scyl9LHZvaWQgMCl9LGUucHJvdG90eXBlLm1hcD1mdW5jdGlvbih0LGUpe3ZhciBpPVtdO3JldHVybiB0aGlzLnJlZHVjZShmdW5jdGlvbihyLG4sbyxzLGEpe2kucHVzaCh0LmNhbGwoZSxuLG8scyxhKSl9LHZvaWQgMCksaX0sZS5wcm90b3R5cGUudG9BcnJheT1mdW5jdGlvbigpe3JldHVybiB0aGlzLm1hcChGdW5jdGlvbi5pZGVudGl0eSl9LGUucHJvdG90eXBlLnJnPWZ1bmN0aW9uKCl7dmFyIHQ9e307cmV0dXJuIHRoaXMucmVkdWNlKGZ1bmN0aW9uKGUsaSxyKXt0W3JdPWl9LHZvaWQgMCksdH0sZS5wcm90b3R5cGUuZmlsdGVyPWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcy5uZygpO3JldHVybiB0aGlzLnJlZHVjZShmdW5jdGlvbihyLG4sbyxzLGEpe3QuY2FsbChlLG4sbyxzLGEpJiZpLmFkZChuKX0sdm9pZCAwKSxpfSxlLnByb3RvdHlwZS5ldmVyeT1mdW5jdGlvbih0LGUpe3JldHVybiB0aGlzLnJlZHVjZShmdW5jdGlvbihpLHIsbixvLHMpe3JldHVybiBpJiZ0LmNhbGwoZSxyLG4sbyxzKX0sITApfSxlLnByb3RvdHlwZS5zb21lPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMucmVkdWNlKGZ1bmN0aW9uKGkscixuLG8scyl7cmV0dXJuIGl8fHQuY2FsbChlLHIsbixvLHMpfSwhMSl9LGUucHJvdG90eXBlLmFsbD1mdW5jdGlvbigpe3JldHVybiB0aGlzLmV2ZXJ5KEJvb2xlYW4pfSxlLnByb3RvdHlwZS5pZT1mdW5jdGlvbigpe3JldHVybiB0aGlzLnNvbWUoQm9vbGVhbil9LGUucHJvdG90eXBlLm1pbj1mdW5jdGlvbih0KXtyZXR1cm4gdD10aGlzLiRmfHxPYmplY3QuWWYsdGhpcy5yZWR1Y2UoZnVuY3Rpb24oZSxpKXtyZXR1cm4gMD50KGksZSk/aTplfSwxLzApfSxlLnByb3RvdHlwZS5tYXg9ZnVuY3Rpb24odCl7cmV0dXJuIHQ9dGhpcy4kZnx8T2JqZWN0LllmLHRoaXMucmVkdWNlKGZ1bmN0aW9uKGUsaSl7cmV0dXJuIDA8dChpLGUpP2k6ZX0sLSgxLzApKX0sZS5wcm90b3R5cGUub2c9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMucmVkdWNlKGZ1bmN0aW9uKHQsZSl7cmV0dXJuIHQrZX0sdm9pZCAwPT09dD8wOnQpfSxlLnByb3RvdHlwZS5zZz1mdW5jdGlvbih0KXt2YXIgZT12b2lkIDA9PT10PzA6dCxpPXZvaWQgMD09PXQ/MDp0O3JldHVybiB0aGlzLnJlZHVjZShmdW5jdGlvbih0LHIpe2UrPXIsaSs9MX0sdm9pZCAwKSxlL2l9LGUucHJvdG90eXBlLmNvbmNhdD1mdW5jdGlvbigpe2Zvcih2YXIgdD10aGlzLm5nKHRoaXMpLGU9MDtlPGFyZ3VtZW50cy5sZW5ndGg7ZSsrKXQuYWRkRWFjaChhcmd1bWVudHNbZV0pO3JldHVybiB0fSxlLnByb3RvdHlwZS5hZz1mdW5jdGlvbigpe3ZhciB0PXRoaXM7cmV0dXJuIHRoaXMucmVkdWNlKGZ1bmN0aW9uKGUsaSl7cmV0dXJuIGkuZm9yRWFjaChmdW5jdGlvbih0KXt0aGlzLnB1c2godCl9LGUsdCksZX0sW10pfSxlLnByb3RvdHlwZS5jZz1mdW5jdGlvbigpe3ZhciB0PUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7dC51bnNoaWZ0KHRoaXMpO2Zvcih2YXIgZT1bXSxpPTEvMCxyPTA7cjx0Lmxlbmd0aDtyKyspe3ZhciBuPXRbcl07dFtyXT1uLnRvQXJyYXkoKSxuLmxlbmd0aDxpJiYoaT1uLmxlbmd0aCl9Zm9yKHI9MDtyPHQubGVuZ3RoO3IrKylmb3IodmFyIG49dFtyXSxvPTA7bzxuLmxlbmd0aDtvKyspbzxpJiZvIGluIG4mJihlW29dPWVbb118fFtdLGVbb11bcl09bltvXSk7cmV0dXJuIGV9LGUucHJvdG90eXBlLmhnPWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gdD10fHx0aGlzLiRmfHxPYmplY3QuWWYsdC5wZz8oZT10LnBnLHQ9dC5ZZnx8dGhpcy4kZnx8T2JqZWN0LllmKTplPWV8fEZ1bmN0aW9uLmlkZW50aXR5LHZvaWQgMD09PWkmJihpPTEpLHRoaXMubWFwKGZ1bmN0aW9uKHQpe3JldHVybntwZzplKHQpLHZhbHVlOnR9fSkuc29ydChmdW5jdGlvbihlLHIpe3JldHVybiB0KGUucGcsci5wZykqaX0pLm1hcChmdW5jdGlvbih0KXtyZXR1cm4gdC52YWx1ZX0pfSxlLnByb3RvdHlwZS5yZXZlcnNlZD1mdW5jdGlvbigpe3JldHVybiB0aGlzLm5nKHRoaXMpLnJldmVyc2UoKX0sZS5wcm90b3R5cGUuY2xvbmU9ZnVuY3Rpb24odCxlKXtpZih2b2lkIDA9PT10KXQ9MS8wO2Vsc2UgaWYoMD09PXQpcmV0dXJuIHRoaXM7dmFyIGk9dGhpcy5uZygpO3JldHVybiB0aGlzLmZvckVhY2goZnVuY3Rpb24ocixuKXtpLmFkZChPYmplY3QuY2xvbmUocix0LTEsZSksbil9LHRoaXMpLGl9LGUucHJvdG90eXBlLm9ubHk9ZnVuY3Rpb24oKXtpZigwPT09dGhpcy5sZW5ndGgpdGhyb3cgRXJyb3IoXCJDYW4ndCBnZXQgb25seSB2YWx1ZSBpbiBlbXB0eSBjb2xsZWN0aW9uLlwiKTtpZigxPHRoaXMubGVuZ3RoKXRocm93IEVycm9yKFwiQ2FuJ3QgZ2V0IG9ubHkgdmFsdWUgaW4gY29sbGVjdGlvbiB3aXRoIG11bHRpcGxlIHZhbHVlcy5cIik7cmV0dXJuIHRoaXMudWcoKX0seC5lZyYmKHg9eC5lZyk7dmFyIEI9e307Qi5lZz1pLGkucHJvdG90eXBlLmxnPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMubmcodGhpcyk7cmV0dXJuIGUuYWRkRWFjaCh0KSxlfSxpLnByb3RvdHlwZS5kZz1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5uZyh0aGlzLmZpbHRlcihmdW5jdGlvbihlKXtyZXR1cm4gdC5oYXMoZSl9KSl9LGkucHJvdG90eXBlLmZnPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMubmcodGhpcyk7cmV0dXJuIGUuaWcodCksZX0saS5wcm90b3R5cGUuZ2c9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5sZyh0KSx0PXRoaXMuZGcodCk7cmV0dXJuIGUuZmcodCl9LGkucHJvdG90eXBlLm9sPWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcztyZXR1cm4gT2JqZWN0LnZnKHQsXCJyZWR1Y2VcIikmJnRoaXMubGVuZ3RoPT09dC5sZW5ndGgmJnQucmVkdWNlKGZ1bmN0aW9uKHQscil7cmV0dXJuIHQmJmkuaGFzKHIsZSl9LCEwKX0sQi5lZyYmKEI9Qi5lZyk7dmFyIEY9eCxfPU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7QXJyYXkuaXNBcnJheXx8KEFycmF5LmlzQXJyYXk9ZnVuY3Rpb24odCl7cmV0dXJuXCJbb2JqZWN0IEFycmF5XVwiPT1fLmNhbGwodCl9KSxBcnJheS5wcm90b3R5cGUuZm9yRWFjaHx8KEFycmF5LnByb3RvdHlwZS5mb3JFYWNoPUYuZm9yRWFjaCksQXJyYXkucHJvdG90eXBlLm1hcHx8KEFycmF5LnByb3RvdHlwZS5tYXA9Ri5tYXApLEFycmF5LnByb3RvdHlwZS5maWx0ZXJ8fChBcnJheS5wcm90b3R5cGUuZmlsdGVyPUYuZmlsdGVyKSxBcnJheS5wcm90b3R5cGUuZXZlcnl8fChBcnJheS5wcm90b3R5cGUuZXZlcnk9Ri5ldmVyeSksQXJyYXkucHJvdG90eXBlLnNvbWV8fChBcnJheS5wcm90b3R5cGUuc29tZT1GLnNvbWUpLEFycmF5LnByb3RvdHlwZS5yZWR1Y2V8fChBcnJheS5wcm90b3R5cGUucmVkdWNlPWZ1bmN0aW9uKHQpe3ZhciBlPXRvT2JqZWN0KHRoaXMpLGk9ZS5sZW5ndGg+Pj4wO2lmKFwiW29iamVjdCBGdW5jdGlvbl1cIiE9Xy5jYWxsKHQpKXRocm93IG5ldyBUeXBlRXJyb3IodCtcIiBpcyBub3QgYSBmdW5jdGlvblwiKTtpZighaSYmMT09YXJndW1lbnRzLmxlbmd0aCl0aHJvdyBuZXcgVHlwZUVycm9yKFwicmVkdWNlIG9mIGVtcHR5IGFycmF5IHdpdGggbm8gaW5pdGlhbCB2YWx1ZVwiKTt2YXIgcixuPTA7aWYoMjw9YXJndW1lbnRzLmxlbmd0aClyPWFyZ3VtZW50c1sxXTtlbHNlIGZvcig7Oyl7aWYobiBpbiBlKXtyPWVbbisrXTticmVha31pZigrK24+PWkpdGhyb3cgbmV3IFR5cGVFcnJvcihcInJlZHVjZSBvZiBlbXB0eSBhcnJheSB3aXRoIG5vIGluaXRpYWwgdmFsdWVcIil9Zm9yKDtuPGk7bisrKW4gaW4gZSYmKHI9dC5jYWxsKHZvaWQgMCxyLGVbbl0sbixlKSk7cmV0dXJuIHJ9KSxBcnJheS5wcm90b3R5cGUucmVkdWNlUmlnaHR8fChBcnJheS5wcm90b3R5cGUucmVkdWNlUmlnaHQ9ZnVuY3Rpb24odCl7dmFyIGU9dG9PYmplY3QodGhpcyksaT1lLmxlbmd0aD4+PjA7aWYoXCJbb2JqZWN0IEZ1bmN0aW9uXVwiIT1fLmNhbGwodCkpdGhyb3cgbmV3IFR5cGVFcnJvcih0K1wiIGlzIG5vdCBhIGZ1bmN0aW9uXCIpO2lmKCFpJiYxPT1hcmd1bWVudHMubGVuZ3RoKXRocm93IG5ldyBUeXBlRXJyb3IoXCJyZWR1Y2VSaWdodCBvZiBlbXB0eSBhcnJheSB3aXRoIG5vIGluaXRpYWwgdmFsdWVcIik7dmFyIHIsaT1pLTE7aWYoMjw9YXJndW1lbnRzLmxlbmd0aClyPWFyZ3VtZW50c1sxXTtlbHNlIGZvcig7Oyl7aWYoaSBpbiBlKXtyPWVbaS0tXTticmVha31pZigwPi0taSl0aHJvdyBuZXcgVHlwZUVycm9yKFwicmVkdWNlUmlnaHQgb2YgZW1wdHkgYXJyYXkgd2l0aCBubyBpbml0aWFsIHZhbHVlXCIpfWRvIGkgaW4gdGhpcyYmKHI9dC5jYWxsKHZvaWQgMCxyLGVbaV0saSxlKSk7d2hpbGUoaS0tKTtyZXR1cm4gcn0pLEFycmF5LnByb3RvdHlwZS5pbmRleE9mfHwoQXJyYXkucHJvdG90eXBlLmluZGV4T2Y9ZnVuY3Rpb24odCl7dmFyIGU9dG9PYmplY3QodGhpcyksaT1lLmxlbmd0aD4+PjA7aWYoIWkpcmV0dXJuLTE7dmFyIHI9MDtmb3IoMTxhcmd1bWVudHMubGVuZ3RoJiYocj10b0ludGVnZXIoYXJndW1lbnRzWzFdKSkscj0wPD1yP3I6TWF0aC5tYXgoMCxpK3IpO3I8aTtyKyspaWYociBpbiBlJiZlW3JdPT09dClyZXR1cm4gcjtyZXR1cm4tMX0pLEFycmF5LnByb3RvdHlwZS5sYXN0SW5kZXhPZnx8KEFycmF5LnByb3RvdHlwZS5sYXN0SW5kZXhPZj1mdW5jdGlvbih0KXt2YXIgZT10b09iamVjdCh0aGlzKSxpPWUubGVuZ3RoPj4+MDtpZighaSlyZXR1cm4tMTt2YXIgcj1pLTE7Zm9yKDE8YXJndW1lbnRzLmxlbmd0aCYmKHI9TWF0aC5taW4ocix0b0ludGVnZXIoYXJndW1lbnRzWzFdKSkpLHI9MDw9cj9yOmktTWF0aC5hYnMocik7MDw9cjtyLS0paWYociBpbiBlJiZ0PT09ZVtyXSlyZXR1cm4gcjtyZXR1cm4tMX0pO3ZhciBEPXt9O0QuZWc9RnVuY3Rpb24sRnVuY3Rpb24uamY9ZnVuY3Rpb24oKXt9LEZ1bmN0aW9uLmlkZW50aXR5PWZ1bmN0aW9uKHQpe3JldHVybiB0fSxGdW5jdGlvbi5wZz1mdW5jdGlvbih0LGUpe3ZhciBlPWV8fE9iamVjdC5ZZix0PXR8fEZ1bmN0aW9uLmlkZW50aXR5LGk9ZnVuY3Rpb24oaSxyKXtyZXR1cm4gZSh0KGkpLHQocikpfTtyZXR1cm4gaS5ZZj1lLGkucGc9dCxpfSxELmVnJiYoRD1ELmVnKTt2YXIgSD17fTtILmVnPXIsci55Zz17ZGc6XCIrXCIsbWc6XCItXCIsd2c6XCIrXCIsVGc6XCIrXCIsU2c6XCIuXCIsYmc6XCInXCIsRWc6XCIrXCIsSWc6XCJ8XCJ9LHIuUmc9e2RnOlwi4pWLXCIsbWc6XCLilIFcIix3ZzpcIuKUu1wiLFRnOlwi4pSzXCIsU2c6XCLila1cIixiZzpcIuKVsFwiLEVnOlwi4pSjXCIsSWc6XCLilINcIn0sci5rZz17ZGc6XCLilYtcIixtZzpcIuKUgVwiLHdnOlwi4pS7XCIsVGc6XCLilLNcIixTZzpcIuKUj1wiLGJnOlwi4pSXXCIsRWc6XCLilKNcIixJZzpcIuKUg1wifSxILmVnJiYoSD1ILmVnKTt2YXIgTCxNPXt9LGo9TTtpZihcInVuZGVmaW5lZFwiIT10eXBlb2YgV2Vha01hcClMPVdlYWtNYXA7ZWxzZXt2YXIgVT1mdW5jdGlvbih0KXtyZXR1cm4gdC5wcm90b3R5cGU9bnVsbCxPYmplY3QuZnJlZXplKHQpfSxWPU9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzLFE9T2JqZWN0LmRlZmluZVByb3BlcnR5LHE9e307VihPYmplY3QpLmZvckVhY2goZnVuY3Rpb24odCl7cVt0XT1PYmplY3RbdF19KTt2YXIgSj1cImlkZW50OlwiK01hdGgucmFuZG9tKCkrXCJfX19cIjtpZihcInVuZGVmaW5lZFwiIT10eXBlb2YgY3J5cHRvJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBjcnlwdG8uZ2V0UmFuZG9tVmFsdWVzJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBBcnJheUJ1ZmZlciYmXCJmdW5jdGlvblwiPT10eXBlb2YgVWludDhBcnJheSl7dmFyIEs9bmV3IEFycmF5QnVmZmVyKDI1KSxLPW5ldyBVaW50OEFycmF5KEspO2NyeXB0by5nZXRSYW5kb21WYWx1ZXMoSyksSj1cInJhbmQ6XCIrQXJyYXkucHJvdG90eXBlLm1hcC5jYWxsKEssZnVuY3Rpb24odCl7cmV0dXJuKHQlMzYpLnRvU3RyaW5nKDM2KX0pLmpvaW4oXCJcIikrXCJfX19cIn1RKE9iamVjdCxcImdldE93blByb3BlcnR5TmFtZXNcIix7dmFsdWU6ZnVuY3Rpb24odCl7cmV0dXJuIFYodCkuZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVybiB0IT09Sn0pfX0pLFwiZ2V0UHJvcGVydHlOYW1lc1wiaW4gT2JqZWN0JiZRKE9iamVjdCxcImdldFByb3BlcnR5TmFtZXNcIix7dmFsdWU6ZnVuY3Rpb24odCl7cmV0dXJuIHEuZ2V0UHJvcGVydHlOYW1lcyh0KS5maWx0ZXIoZnVuY3Rpb24odCl7cmV0dXJuIHQhPT1KfSl9fSk7dmFyIEc9ZnVuY3Rpb24odCl7aWYodCE9PU9iamVjdCh0KSl0aHJvdyBuZXcgVHlwZUVycm9yKFwiTm90IGFuIG9iamVjdDogXCIrdCk7dmFyIGU9dFtKXTtyZXR1cm4gZSYmZS5rZXk9PT10P2U6cS5pc0V4dGVuc2libGUodCk/KGU9e2tleTp0LENnOltdLE9nOltdfSxRKHQsSix7dmFsdWU6ZSxQZzohMSxBZzohMSxOZzohMX0pLGUpOnZvaWQgMH0sej1PYmplY3QuZnJlZXplO1EoT2JqZWN0LFwiZnJlZXplXCIse3ZhbHVlOmZ1bmN0aW9uKHQpe3JldHVybiBHKHQpLHoodCl9fSk7dmFyIFc9T2JqZWN0LnNlYWw7UShPYmplY3QsXCJzZWFsXCIse3ZhbHVlOmZ1bmN0aW9uKHQpe3JldHVybiBHKHQpLFcodCl9fSk7dmFyICQ9T2JqZWN0LnByZXZlbnRFeHRlbnNpb25zO1EoT2JqZWN0LFwicHJldmVudEV4dGVuc2lvbnNcIix7dmFsdWU6ZnVuY3Rpb24odCl7cmV0dXJuIEcodCksJCh0KX19KTt2YXIgWT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQocixuKXt2YXIgbyxzPUcocik7cmV0dXJuIHM/KG89cy5DZy5pbmRleE9mKHQpLHM9cy5PZyk6KG89ZS5pbmRleE9mKHIpLHM9aSksMDw9bz9zW29dOm59dmFyIGU9W10saT1bXTtyZXR1cm4gT2JqZWN0LmNyZWF0ZShZLnByb3RvdHlwZSx7eGc6e3ZhbHVlOlUodCl9LEJnOnt2YWx1ZTpVKGZ1bmN0aW9uKGkpe3ZhciByPUcoaSk7cmV0dXJuIDA8PShyP3IuQ2cuaW5kZXhPZih0KTplLmluZGV4T2YoaSkpfSl9LEZnOnt2YWx1ZTpVKGZ1bmN0aW9uKHIsbil7dmFyIG8scz1HKHIpO3M/KG89cy5DZy5pbmRleE9mKHQpLDA8PW8/cy5PZ1tvXT1uOihzLkNnLnB1c2godCkscy5PZy5wdXNoKG4pKSk6KG89ZS5pbmRleE9mKHIpLDA8PW8/aVtvXT1uOihlLnB1c2gociksaS5wdXNoKG4pKSl9KX0sX2c6e3ZhbHVlOlUoZnVuY3Rpb24ocil7dmFyIG49RyhyKTtyZXR1cm4gbj8ocj1uLkNnLmluZGV4T2YodCksMDw9ciYmKG4uQ2cuc3BsaWNlKHIsMSksbi5PZy5zcGxpY2UociwxKSkpOihyPWUuaW5kZXhPZihyKSwwPD1yJiYoZS5zcGxpY2UociwxKSxpLnNwbGljZShyLDEpKSksITB9KX19KX07WS5wcm90b3R5cGU9T2JqZWN0LmNyZWF0ZShPYmplY3QucHJvdG90eXBlLHtnZXQ6e3ZhbHVlOmZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMueGcodCxlKX0sUGc6ITAsTmc6ITB9LGhhczp7dmFsdWU6ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuQmcodCl9LFBnOiEwLE5nOiEwfSxzZXQ6e3ZhbHVlOmZ1bmN0aW9uKHQsZSl7dGhpcy5GZyh0LGUpfSxQZzohMCxOZzohMH0sXCJkZWxldGVcIjp7dmFsdWU6ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuX2codCl9LFBnOiEwLE5nOiEwfX0pLEw9WX1qLmVnPUwsTS5lZyYmKE09TS5lZyk7dmFyIFg9e30sWj1NLHR0PU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksZXQ9bmV3IFosaXQ9bmV3IFo7WC5lZz1uLG4ucHJvdG90eXBlLkRnPWZ1bmN0aW9uKHQpe2V0Lmhhcyh0aGlzKXx8ZXQuc2V0KHRoaXMse30pO3ZhciBlPWV0LmdldCh0aGlzKTtyZXR1cm4gdHQuY2FsbChlLHQpfHwoZVt0XT17SGc6W10sTGc6W119KSxlW3RdfSxuLnByb3RvdHlwZS5NZz1mdW5jdGlvbih0KXtpZighZXQuaGFzKHRoaXMpKXJldHVybiExO2lmKCF0KXJldHVybiEwO3ZhciBlPWV0LmdldCh0aGlzKTtyZXR1cm4hIXR0LmNhbGwoZSx0KX0sbi5wcm90b3R5cGUuamc9ZnVuY3Rpb24odCxlLGkpe3RoaXMubWFrZU9ic2VydmFibGUmJiF0aGlzLmlzT2JzZXJ2YWJsZSYmdGhpcy5tYWtlT2JzZXJ2YWJsZSgpO3ZhciByPW4uRGcodGhpcyx0KSxpPWk/ci5IZzpyLkxnO24uVWcodGhpcyx0KSxpLnB1c2goZSl9LG4ucHJvdG90eXBlLlZnPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIG4uamcodGhpcyx0LGUsITApfSxuLnByb3RvdHlwZS5RZz1mdW5jdGlvbih0LGUsaSl7dmFyIHI9bi5EZyh0aGlzLHQpLGk9aT9yLkhnOnIuTGcsZT1pLmxhc3RJbmRleE9mKGUpO2lmKC0xPT09ZSl0aHJvdyBFcnJvcihcIkNhbid0IHJlbW92ZSBsaXN0ZW5lcjogZG9lcyBub3QgZXhpc3QuXCIpO2kuc3BsaWNlKGUsMSksMD09PXIuTGcubGVuZ3RoK3IuSGcubGVuZ3RoJiZuLnFnKHRoaXMsdCl9LG4ucHJvdG90eXBlLkpnPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIG4uUWcodGhpcyx0LGUsITApfSxuLnByb3RvdHlwZS5LZz1mdW5jdGlvbih0LGUsaSl7dmFyIHI9bi5EZyh0aGlzLHQpLHI9aT9yLkhnOnIuTGcsaT0oaT9cIldpbGxcIjpcIlwiKStcIkNoYW5nZVwiLG89XCJoYW5kbGVQcm9wZXJ0eVwiK2kscz1TdHJpbmcodCkscz1zJiZzWzBdLnRvVXBwZXJDYXNlKCkrcy5zbGljZSgxKSxhPVwiaGFuZGxlXCIrcytpO3IuZm9yRWFjaChmdW5jdGlvbihpKXt2YXIgcj1pLGk9aVthXXx8aVtvXXx8aTtpLmNhbGwmJmkuY2FsbChyLGUsdCx0aGlzKX0sdGhpcyl9LG4ucHJvdG90eXBlLkdnPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIG4uS2codGhpcyx0LGUsITApfSxuLnByb3RvdHlwZS5VZz1mdW5jdGlvbih0KXtpZighQXJyYXkuaXNBcnJheSh0aGlzKSl7aXQuaGFzKHRoaXMpfHwoZT17fSxpdC5zZXQodGhpcyxlKSk7dmFyIGU9aXQuZ2V0KHRoaXMpO2lmKCF0dC5jYWxsKGUsdCkpe3ZhciBpLHI9dGhpcztPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHIsdCk7ZG97aWYoaT1PYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHIsdCkpYnJlYWs7cj1PYmplY3QuZ2V0UHJvdG90eXBlT2Yocil9d2hpbGUocik7aWYoaT1pfHx7dmFsdWU6dm9pZCAwLEFnOiEwLFBnOiEwLE5nOiEwfSwhaS5OZyl0aHJvdyBFcnJvcihcIkNhbid0IG9ic2VydmUgbm9uLWNvbmZpZ3VyYWJsZSBwcm9wZXJ0aWVzXCIpO2VbdF09aSwoaS5QZ3x8aS5zZXQpJiZPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcyx0LFwidmFsdWVcImluIGk/e2dldDpmdW5jdGlvbigpe3JldHVybiBpLnZhbHVlfSxzZXQ6ZnVuY3Rpb24oZSl7cmV0dXJuIGU9PT1pLnZhbHVlP2U6KG4uR2codGhpcyx0LGkudmFsdWUpLGkudmFsdWU9ZSxuLktnKHRoaXMsdCxlKSxlKX0sQWc6aS5BZyxOZzohMH06e2dldDpmdW5jdGlvbigpe2lmKGkuZ2V0KXJldHVybiBpLmdldC5hcHBseSh0aGlzLGFyZ3VtZW50cyl9LHNldDpmdW5jdGlvbihlKXt2YXIgcjtyZXR1cm4gaS5nZXQmJihyPWkuZ2V0LmFwcGx5KHRoaXMsYXJndW1lbnRzKSksZT09PXI/ZToobi5HZyh0aGlzLHQsciksaS5zZXQmJmkuc2V0LmFwcGx5KHRoaXMsYXJndW1lbnRzKSxpLmdldCYmKGU9aS5nZXQuYXBwbHkodGhpcyxhcmd1bWVudHMpKSxuLktnKHRoaXMsdCxlKSxlKX0sQWc6aS5BZyxOZzohMH0pfX19LG4ucHJvdG90eXBlLnFnPWZ1bmN0aW9uKHQpe2lmKCFBcnJheS5pc0FycmF5KHRoaXMpKXtpZighaXQuaGFzKHRoaXMpKXRocm93IEVycm9yKFwiQ2FuJ3QgdW5pbnN0YWxsIG9ic2VydmVyIG9uIHByb3BlcnR5XCIpO3ZhciBlPWl0LmdldCh0aGlzKTtpZighZVt0XSl0aHJvdyBFcnJvcihcIkNhbid0IHVuaW5zdGFsbCBvYnNlcnZlciBvbiBwcm9wZXJ0eVwiKTt2YXIgaT1lW3RdO2RlbGV0ZSBlW3RdLE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLHQsaSl9fSxuLkRnPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHQuRGc/dC5EZyhlKTpuLnByb3RvdHlwZS5EZy5jYWxsKHQsZSl9LG4uTWc9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdC5NZz90Lk1nKGUpOm4ucHJvdG90eXBlLk1nLmNhbGwodCxlKX0sbi5qZz1mdW5jdGlvbih0LGUsaSxyKXtyZXR1cm4gdC5qZz90LmpnKGUsaSxyKTpuLnByb3RvdHlwZS5qZy5jYWxsKHQsZSxpLHIpfSxuLlFnPWZ1bmN0aW9uKHQsZSxpLHIpe3JldHVybiB0LlFnP3QuUWcoZSxpLHIpOm4ucHJvdG90eXBlLlFnLmNhbGwodCxlLGkscil9LG4uS2c9ZnVuY3Rpb24odCxlLGkscil7cmV0dXJuIHQuS2c/dC5LZyhlLGkscik6bi5wcm90b3R5cGUuS2cuY2FsbCh0LGUsaSxyKX0sbi5WZz1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIG4uamcodCxlLGksITApfSxuLkpnPWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gbi5RZyh0LGUsaSwhMCl9LG4uR2c9ZnVuY3Rpb24odCxlLGkpe3JldHVybiBuLktnKHQsZSxpLCEwKX0sbi5VZz1mdW5jdGlvbih0LGUpe3JldHVybiB0LlVnP3QuVWcoZSk6bi5wcm90b3R5cGUuVWcuY2FsbCh0LGUpfSxuLnFnPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHQucWc/dC5xZyhlKTpuLnByb3RvdHlwZS5xZy5jYWxsKHQsZSl9LFguZWcmJihYPVguZWcpO3ZhciBydD17fSxudD1uZXcgTTtydC5lZz1vLG8ucHJvdG90eXBlLnpnPWZ1bmN0aW9uKCl7cmV0dXJuIG50Lmhhcyh0aGlzKXx8bnQuc2V0KHRoaXMse3N0OiExLExnOltdLEhnOltdfSksbnQuZ2V0KHRoaXMpfSxvLnByb3RvdHlwZS5XZz1mdW5jdGlvbih0LGUpeyF0aGlzLmlzT2JzZXJ2YWJsZSYmdGhpcy5tYWtlT2JzZXJ2YWJsZSYmdGhpcy5tYWtlT2JzZXJ2YWJsZSgpO3ZhciBpPXRoaXMuemcoKTsoZT9pLkhnOmkuTGcpLnB1c2godCksdGhpcy4kZz0hIShpLkhnLmxlbmd0aCtpLkxnLmxlbmd0aCl9LG8ucHJvdG90eXBlLllnPWZ1bmN0aW9uKHQsZSl7dmFyIGkscj10aGlzLnpnKCk7aT1lP3IuSGc6ci5MZzt2YXIgbj1pLmxhc3RJbmRleE9mKHQpO2lmKC0xPT09bil0aHJvdyBFcnJvcihcIkNhbid0IHJlbW92ZSBsaXN0ZW5lcjogZG9lcyBub3QgZXhpc3QuXCIpO2kuc3BsaWNlKG4sMSksdGhpcy4kZz0hIShyLkhnLmxlbmd0aCtyLkxnLmxlbmd0aCl9LG8ucHJvdG90eXBlLlhnPWZ1bmN0aW9uKHQsZSxpLHIpe3ZhciBuPXRoaXMuemcoKTtpZighbi5zdCl7bi5zdD0hMDt2YXIgbztvPXI/bi5IZzpuLkxnO3RyeXtvLmZvckVhY2goZnVuY3Rpb24obil7bi55ZD9uLnlkKHtaZzpyP1wiYmVmb3JlXCI6XCJhZnRlclwiLGN1cnJlbnRUYXJnZXQ6dGhpcyx0YXJnZXQ6dGhpcyx0djp0LGV2OmUsaW5kZXg6aX0pOihuPXI/bi5oYW5kbGVSYW5nZVdpbGxDaGFuZ2V8fG46bi5oYW5kbGVSYW5nZUNoYW5nZXx8bixuLmNhbGwmJm4uY2FsbCh0aGlzLHQsZSxpLHIpKX0sdGhpcyl9ZmluYWxseXtuLnN0PSExfX19LG8ucHJvdG90eXBlLml2PWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLldnKHQsITApfSxvLnByb3RvdHlwZS5ydj1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5ZZyh0LCEwKX0sby5wcm90b3R5cGUubnY9ZnVuY3Rpb24odCxlLGkpe3JldHVybiB0aGlzLlhnKHQsZSxpLCEwKX0scnQuZWcmJihydD1ydC5lZyk7dmFyIG90PXt9LHN0PU07b3QuZWc9T2JqZWN0LE9iamVjdC5lbXB0eT1PYmplY3QuZnJlZXplKE9iamVjdC5jcmVhdGUobnVsbCkpLE9iamVjdC5vdj1mdW5jdGlvbih0KXtyZXR1cm4gT2JqZWN0KHQpPT09dH0sT2JqZWN0LnN2PWZ1bmN0aW9uKHQpe3JldHVybiBPYmplY3QudmcodCxcInZhbHVlT2ZcIikmJih0PXQudmFsdWVPZigpKSx0fTt2YXIgYXQ9bmV3IHN0O09iamVjdC5oYXNoPWZ1bmN0aW9uKHQpe3JldHVybiBPYmplY3QudmcodCxcImhhc2hcIik/XCJcIit0Lmhhc2goKTpPYmplY3QodCk9PT10PyhhdC5oYXModCl8fGF0LnNldCh0LE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnNsaWNlKDIpKSxhdC5nZXQodCkpOlwiXCIrdH07dmFyIGN0PU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7T2JqZWN0LmF2PWZ1bmN0aW9uKHQsZSl7cmV0dXJuIGN0LmNhbGwodCxlKX0sT2JqZWN0LnZnPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIG51bGwhPXQmJlwiZnVuY3Rpb25cIj09dHlwZW9mIHRbZV0mJiFjdC5jYWxsKHQsZSl9LE9iamVjdC5oYXM9ZnVuY3Rpb24odCxlKXtpZihcIm9iamVjdFwiIT10eXBlb2YgdCl0aHJvdyBFcnJvcihcIk9iamVjdC5oYXMgY2FuJ3QgYWNjZXB0IG5vbi1vYmplY3Q6IFwiK3R5cGVvZiB0KTtpZihPYmplY3QudmcodCxcImhhc1wiKSlyZXR1cm4gdC5oYXMoZSk7aWYoXCJzdHJpbmdcIj09dHlwZW9mIGUpcmV0dXJuIGUgaW4gdCYmdFtlXSE9PU9iamVjdC5wcm90b3R5cGVbZV07dGhyb3cgRXJyb3IoXCJLZXkgbXVzdCBiZSBhIHN0cmluZyBmb3IgT2JqZWN0LmhhcyBvbiBwbGFpbiBvYmplY3RzXCIpfSxPYmplY3QuZ2V0PWZ1bmN0aW9uKHQsZSxpKXtpZihcIm9iamVjdFwiIT10eXBlb2YgdCl0aHJvdyBFcnJvcihcIk9iamVjdC5nZXQgY2FuJ3QgYWNjZXB0IG5vbi1vYmplY3Q6IFwiK3R5cGVvZiB0KTtyZXR1cm4gT2JqZWN0LnZnKHQsXCJnZXRcIik/dC5nZXQoZSxpKTpPYmplY3QuaGFzKHQsZSk/dFtlXTppfSxPYmplY3Quc2V0PWZ1bmN0aW9uKHQsZSxpKXtPYmplY3QudmcodCxcInNldFwiKT90LnNldChlLGkpOnRbZV09aX0sT2JqZWN0LmFkZEVhY2g9ZnVuY3Rpb24odCxlKXtPYmplY3QudmcoZSxcImZvckVhY2hcIik/XCJmdW5jdGlvblwiPT10eXBlb2YgZS5rZXlzP2UuZm9yRWFjaChmdW5jdGlvbihlLGkpe3RbaV09ZX0pOmUuZm9yRWFjaChmdW5jdGlvbihlKXt0W2VbMF1dPWVbMV19KTpPYmplY3Qua2V5cyhlKS5mb3JFYWNoKGZ1bmN0aW9uKGkpe3RbaV09ZVtpXX0pfSxPYmplY3QuZm9yRWFjaD1mdW5jdGlvbih0LGUsaSl7T2JqZWN0LmtleXModCkuZm9yRWFjaChmdW5jdGlvbihyKXtlLmNhbGwoaSx0W3JdLHIsdCl9KX0sT2JqZWN0Lm1hcD1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIE9iamVjdC5rZXlzKHQpLm1hcChmdW5jdGlvbihyKXtyZXR1cm4gZS5jYWxsKGksdFtyXSxyLHQpfSl9LE9iamVjdC52YWx1ZXM9ZnVuY3Rpb24odCl7cmV0dXJuIE9iamVjdC5tYXAodCxGdW5jdGlvbi5pZGVudGl0eSl9LE9iamVjdC5pcz1mdW5jdGlvbih0LGUpe3JldHVybiB0PT09ZT8wIT09dHx8MS90PT09MS9lOnQhPT10JiZlIT09ZX0sT2JqZWN0Lm9sPWZ1bmN0aW9uKHQsZSxpKXtpZihpPWl8fE9iamVjdC5vbCx0PU9iamVjdC5zdih0KSxlPU9iamVjdC5zdihlKSx0PT09ZSlyZXR1cm4gMCE9PXR8fDEvdD09PTEvZTtpZihPYmplY3QudmcodCxcImVxdWFsc1wiKSlyZXR1cm4gdC5vbChlLGkpO2lmKE9iamVjdC52ZyhlLFwiZXF1YWxzXCIpKXJldHVybiBlLm9sKHQsaSk7aWYoXCJvYmplY3RcIj09dHlwZW9mIHQmJlwib2JqZWN0XCI9PXR5cGVvZiBlKXt2YXIgcj1PYmplY3QuZ2V0UHJvdG90eXBlT2YodCksbj1PYmplY3QuZ2V0UHJvdG90eXBlT2YoZSk7aWYocj09PW4mJihyPT09T2JqZWN0LnByb3RvdHlwZXx8bnVsbD09PXIpKXtmb3IodmFyIG8gaW4gdClpZighaSh0W29dLGVbb10pKXJldHVybiExO2ZvcihvIGluIGUpaWYoIWkodFtvXSxlW29dKSlyZXR1cm4hMTtyZXR1cm4hMH19cmV0dXJuIHQhPT10JiZlIT09ZX0sT2JqZWN0LllmPWZ1bmN0aW9uKHQsZSl7dmFyIHQ9T2JqZWN0LnN2KHQpLGU9T2JqZWN0LnN2KGUpLGk9dHlwZW9mIHQ7cmV0dXJuIHQ9PT1lfHxpIT09dHlwZW9mIGU/MDpcIm51bWJlclwiPT09aT90LWU6XCJzdHJpbmdcIj09PWk/dDxlPy0xOjE6T2JqZWN0LnZnKHQsXCJjb21wYXJlXCIpP3QuWWYoZSk6T2JqZWN0LnZnKGUsXCJjb21wYXJlXCIpPy1lLllmKHQpOjB9LE9iamVjdC5jbG9uZT1mdW5jdGlvbih0LGUsaSl7aWYodD1PYmplY3Quc3YodCksaT1pfHxuZXcgc3Qsdm9pZCAwPT09ZSllPTEvMDtlbHNlIGlmKDA9PT1lKXJldHVybiB0O2lmKE9iamVjdC5vdih0KSl7aWYoIWkuaGFzKHQpKWlmKE9iamVjdC52Zyh0LFwiY2xvbmVcIikpaS5zZXQodCx0LmNsb25lKGUsaSkpO2Vsc2V7dmFyIHI9T2JqZWN0LmdldFByb3RvdHlwZU9mKHQpO2lmKG51bGwhPT1yJiZyIT09T2JqZWN0LnByb3RvdHlwZSl0aHJvdyBFcnJvcihcIkNhbid0IGNsb25lIFwiK3QpO3I9T2JqZWN0LmNyZWF0ZShyKSxpLnNldCh0LHIpO2Zvcih2YXIgbiBpbiB0KXJbbl09T2JqZWN0LmNsb25lKHRbbl0sZS0xLGkpfXJldHVybiBpLmdldCh0KX1yZXR1cm4gdH0sT2JqZWN0LmNsZWFyPWZ1bmN0aW9uKHQpe2lmKE9iamVjdC52Zyh0LFwiY2xlYXJcIikpdC5jbGVhcigpO2Vsc2UgZm9yKHZhciBlPU9iamVjdC5rZXlzKHQpLGk9ZS5sZW5ndGg7aTspaS0tLGRlbGV0ZSB0W2VbaV1dO3JldHVybiB0fSxvdC5lZyYmKG90PW90LmVnKTt2YXIgaHQ9e30scHQ9b3Q7aHQuZWc9cyxzLnByb3RvdHlwZS5vbD1mdW5jdGlvbih0LGUpe3JldHVybiBlPWV8fHRoaXMuTWZ8fHB0Lm9sLHRoaXM9PT10fHwhIXQmJih0aGlzLmxlbmd0aD09PXQubGVuZ3RoJiZ0aGlzLmNnKHQpLmV2ZXJ5KGZ1bmN0aW9uKHQpe3JldHVybiBlKHRbMF0sdFsxXSl9KSl9LHMucHJvdG90eXBlLllmPWZ1bmN0aW9uKHQsZSl7aWYoZT1lfHx0aGlzLiRmfHxwdC5ZZix0aGlzPT09dClyZXR1cm4gMDtpZighdClyZXR1cm4gMTt2YXIgaT1NYXRoLm1pbih0aGlzLmxlbmd0aCx0Lmxlbmd0aCkscj10aGlzLmNnKHQpLnJlZHVjZShmdW5jdGlvbih0LHIsbil7cmV0dXJuIDA9PT10P24+PWk/dDplKHJbMF0sclsxXSk6dH0sMCk7cmV0dXJuIDA9PT1yP3RoaXMubGVuZ3RoLXQubGVuZ3RoOnJ9LGh0LmVnJiYoaHQ9aHQuZWcpO3ZhciB1dD17fTt1dC5lZz1hO3ZhciBsdD1vdDtpZihsdC5hZGRFYWNoKGEucHJvdG90eXBlLHgucHJvdG90eXBlKSxhLnByb3RvdHlwZS5uZz1mdW5jdGlvbih0KXt2YXIgZT1bXTtyZXR1cm4gUmVkdWNpYmxlLmFkZEVhY2guY2FsbChlLHQpLGV9LGEucHJvdG90eXBlLmN2PWZ1bmN0aW9uKHQsZSl7dmFyIGk9YSh0aGlzKSxyPTA7aWYoXCJbb2JqZWN0IEZ1bmN0aW9uXVwiIT1sdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KSl0aHJvdyBuZXcgVHlwZUVycm9yO3JldHVybiBuZXcgaS5jb25zdHJ1Y3RvcihmdW5jdGlvbigpe3JldHVybiB0LmNhbGwoZSxpLm5leHQoKSxyKyssaSl9KX0sYS5wcm90b3R5cGUuaHY9ZnVuY3Rpb24odCxlKXt2YXIgaT1hKHRoaXMpLHI9MDtpZihcIltvYmplY3QgRnVuY3Rpb25dXCIhPWx0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpKXRocm93IG5ldyBUeXBlRXJyb3I7cmV0dXJuIG5ldyBpLmNvbnN0cnVjdG9yKGZ1bmN0aW9uKCl7Zm9yKHZhciBuOzspaWYobj1pLm5leHQoKSx0LmNhbGwoZSxuLHIrKyxpKSlyZXR1cm4gbn0pfSxhLnByb3RvdHlwZS5yZWR1Y2U9ZnVuY3Rpb24odCl7dmFyIGUsaT1hKHRoaXMpLHI9YXJndW1lbnRzWzFdLG49YXJndW1lbnRzWzJdLG89MDtpZihcIltvYmplY3QgRnVuY3Rpb25dXCIhPWx0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpKXRocm93IG5ldyBUeXBlRXJyb3I7dHJ5e2U9aS5uZXh0KCkscj0xPGFyZ3VtZW50cy5sZW5ndGg/dC5jYWxsKG4scixlLG8saSk6ZSxvKyt9Y2F0Y2gocyl7aWYoaXNTdG9wSXRlcmF0aW9uKHMpKXtpZigxPGFyZ3VtZW50cy5sZW5ndGgpcmV0dXJuIGFyZ3VtZW50c1sxXTt0aHJvdyBUeXBlRXJyb3IoXCJjYW5ub3QgcmVkdWNlIGEgdmFsdWUgZnJvbSBhbiBlbXB0eSBpdGVyYXRvciB3aXRoIG5vIGluaXRpYWwgdmFsdWVcIil9dGhyb3cgc310cnl7Zm9yKDs7KWU9aS5uZXh0KCkscj10LmNhbGwobixyLGUsbyxpKSxvKyt9Y2F0Y2goYyl7aWYoaXNTdG9wSXRlcmF0aW9uKGMpKXJldHVybiByO3Rocm93IGN9fSxhLnByb3RvdHlwZS5ldmVyeT1mdW5jdGlvbih0KXt2YXIgZT1hKHRoaXMpLGk9ITA7aWYoXCJbb2JqZWN0IEZ1bmN0aW9uXVwiIT1sdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KSl0aHJvdyBuZXcgVHlwZUVycm9yO3JldHVybiBlLmN2LmFwcGx5KGUsYXJndW1lbnRzKS5mb3JFYWNoKGZ1bmN0aW9uKHQpe2lmKCF0KXRocm93IGk9ITEsU3RvcEl0ZXJhdGlvbn0pLGl9LGEucHJvdG90eXBlLnNvbWU9ZnVuY3Rpb24odCl7dmFyIGU9YSh0aGlzKSxpPSExO2lmKFwiW29iamVjdCBGdW5jdGlvbl1cIiE9bHQucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodCkpdGhyb3cgbmV3IFR5cGVFcnJvcjtyZXR1cm4gZS5jdi5hcHBseShlLGFyZ3VtZW50cykuZm9yRWFjaChmdW5jdGlvbih0KXtpZih0KXRocm93IGk9ITAsU3RvcEl0ZXJhdGlvbn0pLGl9LGEucHJvdG90eXBlLmNvbmNhdD1mdW5jdGlvbigpe3JldHVybiBhLmNvbmNhdChBcnJheS5wcm90b3R5cGUuY29uY2F0LmFwcGx5KHRoaXMsYXJndW1lbnRzKSl9LGEucHJvdG90eXBlLnB2PWZ1bmN0aW9uKHQsZSl7dmFyIGkscj1hKHRoaXMpLG49ITE7aWYoXCJbb2JqZWN0IEZ1bmN0aW9uXVwiIT1sdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KSl0aHJvdyBuZXcgVHlwZUVycm9yO3JldHVybiByLmZvckVhY2goZnVuY3Rpb24obyxzKXtpZighdC5jYWxsKGUsbyxzLHIpKXRocm93IG49ITAsaT1vLFN0b3BJdGVyYXRpb259KSxuP3IuY29uc3RydWN0b3IoW2ldKS5jb25jYXQocik6ci5jb25zdHJ1Y3RvcihbXSl9LGEucHJvdG90eXBlLnV2PWZ1bmN0aW9uKHQsZSl7dmFyIGk9YSh0aGlzKTtpZihcIltvYmplY3QgRnVuY3Rpb25dXCIhPWx0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpKXRocm93IG5ldyBUeXBlRXJyb3I7cmV0dXJuIGkuY3YoZnVuY3Rpb24ocixuKXtpZighdC5jYWxsKGUscixuLGkpKXRocm93IFN0b3BJdGVyYXRpb247cmV0dXJuIHJ9KX0sYS5wcm90b3R5cGUuaHY9ZnVuY3Rpb24odCxlKXt2YXIgaT1hKHRoaXMpLHI9MDtpZihcIltvYmplY3QgRnVuY3Rpb25dXCIhPWx0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHQpKXRocm93IG5ldyBUeXBlRXJyb3I7cmV0dXJuIG5ldyBpLmNvbnN0cnVjdG9yKGZ1bmN0aW9uKCl7Zm9yKHZhciBuOzspaWYobj1pLm5leHQoKSx0LmNhbGwoZSxuLHIrKyxpKSlyZXR1cm4gbn0pfSxhLnByb3RvdHlwZS5jZz1mdW5jdGlvbigpe3JldHVybiBhLmx2KEFycmF5LnByb3RvdHlwZS5jb25jYXQuYXBwbHkodGhpcyxhcmd1bWVudHMpKX0sYS5wcm90b3R5cGUuZW51bWVyYXRlPWZ1bmN0aW9uKHQpe3JldHVybiBhLmNvdW50KHQpLmNnKHRoaXMpfSxhLkRmPWZ1bmN0aW9uKHQpe3ZhciBlO3JldHVybiBlPTAsbmV3IGEoZnVuY3Rpb24oKXtpZihcIm9iamVjdFwiPT10eXBlb2YgdClmb3IoOyEoZSBpbiB0KTspe2lmKGU+PXQubGVuZ3RoKXRocm93IFN0b3BJdGVyYXRpb247ZSs9MX1lbHNlIGlmKGU+PXQubGVuZ3RoKXRocm93IFN0b3BJdGVyYXRpb247dmFyIGk9dFtlXTtyZXR1cm4gZSs9MSxpfSl9LGEuZHY9ZnVuY3Rpb24odCxlKXsyPmFyZ3VtZW50cy5sZW5ndGgmJihlPTEvMCk7dmFyIGk9ZnVuY3Rpb24oKXt0aHJvdyBTdG9wSXRlcmF0aW9ufTtyZXR1cm4gbmV3IGEoZnVuY3Rpb24oKXt2YXIgcjt0cnl7cmV0dXJuIGkoKX1jYXRjaChuKXtpZihpc1N0b3BJdGVyYXRpb24obikpe2lmKDA+PWUpdGhyb3cgbjtyZXR1cm4gZS0tLHI9YS5EZih0KSwoaT1yLm5leHQuYmluZChyKSkoKX10aHJvdyBufX0pfSxhLmNvbmNhdD1mdW5jdGlvbih0KXt2YXIgdD1hKHQpLGU9ZnVuY3Rpb24oKXt0aHJvdyBTdG9wSXRlcmF0aW9ufTtyZXR1cm4gbmV3IGEoZnVuY3Rpb24oKXt2YXIgaTt0cnl7cmV0dXJuIGUoKX1jYXRjaChyKXtpZihpc1N0b3BJdGVyYXRpb24ocikpcmV0dXJuIGk9YSh0Lm5leHQoKSksKGU9aS5uZXh0LmJpbmQoaSkpKCk7dGhyb3cgcn19KX0sYS5sdj1mdW5jdGlvbih0KXtyZXR1cm4gdD1hKHQpLm1hcChhKSxuZXcgYSgxPnQubGVuZ3RoP1tdOmZ1bmN0aW9uKCl7dmFyIGUsaT10Lm1hcChmdW5jdGlvbih0KXt0cnl7cmV0dXJuIHQubmV4dCgpfWNhdGNoKGkpe2lmKCFpc1N0b3BJdGVyYXRpb24oaSkpdGhyb3cgaTtlPSEwfX0pO2lmKGUpdGhyb3cgU3RvcEl0ZXJhdGlvbjtyZXR1cm4gaX0pfSxhLmNnPWZ1bmN0aW9uKCl7cmV0dXJuIGEubHYoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKSl9LGEuY2hhaW49ZnVuY3Rpb24oKXtyZXR1cm4gYS5jb25jYXQoQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKSl9LGEucmFuZ2U9ZnVuY3Rpb24odCxlLGkpe3JldHVybiAzPmFyZ3VtZW50cy5sZW5ndGgmJihpPTEpLDI+YXJndW1lbnRzLmxlbmd0aCYmKGU9dCx0PTApLHQ9dHx8MCxuZXcgYShmdW5jdGlvbigpe2lmKHQ+PWUpdGhyb3cgU3RvcEl0ZXJhdGlvbjtpZihpc05hTih0KSl0aHJvd1wiXCI7dmFyIHI9dDtyZXR1cm4gdCs9aSxyfSl9LGEuY291bnQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gYS5yYW5nZSh0LDEvMCxlfHwxKX0sYS5yZXBlYXQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gMj5hcmd1bWVudHMubGVuZ3RoJiYoZT0xLzApLG5ldyBhLnJhbmdlKCgrZSkpLmN2KGZ1bmN0aW9uKCl7cmV0dXJuIHR9KX0sXCJ1bmRlZmluZWRcIj09dHlwZW9mIGlzU3RvcEl0ZXJhdGlvbiYmKHQuZnY9ZnVuY3Rpb24odCl7cmV0dXJuXCJbb2JqZWN0IFN0b3BJdGVyYXRpb25dXCI9PT1sdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KX0pLFwidW5kZWZpbmVkXCI9PXR5cGVvZiBTdG9wSXRlcmF0aW9uKXt0LlN0b3BJdGVyYXRpb249e307dmFyIGR0PWx0LnByb3RvdHlwZS50b1N0cmluZztsdC5wcm90b3R5cGUudG9TdHJpbmc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcz09PXQuU3RvcEl0ZXJhdGlvbnx8dGhpcyBpbnN0YW5jZW9mIHQuZ3Y/XCJbb2JqZWN0IFN0b3BJdGVyYXRpb25dXCI6ZHQuY2FsbCh0aGlzLGFyZ3VtZW50cyl9fVwidW5kZWZpbmVkXCI9PXR5cGVvZiBSZXR1cm5WYWx1ZSYmKHQuZ3Y9ZnVuY3Rpb24oZSl7cmV0dXJuIHRoaXMgaW5zdGFuY2VvZiB0Lmd2P3ZvaWQodGhpcy52YWx1ZT1lKTpuZXcgdC5ndihlKX0pLHV0LmVnJiYodXQ9dXQuZWcpO3ZhciBmdD17fSxndD14LHZ0PWh0LHl0PU07ZnQuZWc9QXJyYXksQXJyYXkuZW1wdHk9W10sT2JqZWN0LmZyZWV6ZSYmT2JqZWN0LmZyZWV6ZShBcnJheS5lbXB0eSksQXJyYXkuZnJvbT1mdW5jdGlvbih0KXt2YXIgZT1bXTtyZXR1cm4gZS5hZGRFYWNoKHQpLGV9LEFycmF5LnByb3RvdHlwZS5hZGRFYWNoPWd0LnByb3RvdHlwZS5hZGRFYWNoLEFycmF5LnByb3RvdHlwZS5pZz1ndC5wcm90b3R5cGUuaWcsQXJyYXkucHJvdG90eXBlLnRvQXJyYXk9Z3QucHJvdG90eXBlLnRvQXJyYXksQXJyYXkucHJvdG90eXBlLnJnPWd0LnByb3RvdHlwZS5yZyxBcnJheS5wcm90b3R5cGUuYWxsPWd0LnByb3RvdHlwZS5hbGwsQXJyYXkucHJvdG90eXBlLmllPWd0LnByb3RvdHlwZS5pZSxBcnJheS5wcm90b3R5cGUubWluPWd0LnByb3RvdHlwZS5taW4sQXJyYXkucHJvdG90eXBlLm1heD1ndC5wcm90b3R5cGUubWF4LEFycmF5LnByb3RvdHlwZS5vZz1ndC5wcm90b3R5cGUub2csQXJyYXkucHJvdG90eXBlLnNnPWd0LnByb3RvdHlwZS5zZyxBcnJheS5wcm90b3R5cGUub25seT1ndC5wcm90b3R5cGUub25seSxBcnJheS5wcm90b3R5cGUuYWc9Z3QucHJvdG90eXBlLmFnLEFycmF5LnByb3RvdHlwZS5jZz1ndC5wcm90b3R5cGUuY2csQXJyYXkucHJvdG90eXBlLmhnPWd0LnByb3RvdHlwZS5oZyxBcnJheS5wcm90b3R5cGUucmV2ZXJzZWQ9Z3QucHJvdG90eXBlLnJldmVyc2VkLEFycmF5LnByb3RvdHlwZS5uZz1mdW5jdGlvbih0KXt2YXIgZT1uZXcgdGhpcy5jb25zdHJ1Y3RvcjtyZXR1cm4gZS5hZGRFYWNoKHQpLGV9LEFycmF5LnByb3RvdHlwZS5oYXM9ZnVuY3Rpb24odCxlKXtyZXR1cm4tMSE9PXRoaXMuZmluZCh0LGUpfSxBcnJheS5wcm90b3R5cGUuZ2V0PWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzW3RdfSxBcnJheS5wcm90b3R5cGUuc2V0PWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMuc3BsaWNlKHQsMSxlKSwhMH0sQXJyYXkucHJvdG90eXBlLmFkZD1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5wdXNoKHQpLCEwfSxBcnJheS5wcm90b3R5cGVbXCJkZWxldGVcIl09ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzLmZpbmQodCxlKTtyZXR1cm4tMSE9PWkmJih0aGlzLnNwbGljZShpLDEpLCEwKX0sQXJyYXkucHJvdG90eXBlLmZpbmQ9ZnVuY3Rpb24odCxlKXtmb3IodmFyIGU9ZXx8dGhpcy5NZnx8T2JqZWN0Lm9sLGk9MDtpPHRoaXMubGVuZ3RoO2krKylpZihpIGluIHRoaXMmJmUodGhpc1tpXSx0KSlyZXR1cm4gaTtyZXR1cm4tMX0sQXJyYXkucHJvdG90eXBlLnZ2PWZ1bmN0aW9uKHQsZSl7dmFyIGU9ZXx8dGhpcy5NZnx8T2JqZWN0Lm9sLGk9dGhpcy5sZW5ndGg7ZG8gaWYoaS0tLGkgaW4gdGhpcyYmZSh0aGlzW2ldLHQpKXJldHVybiBpO3doaWxlKDA8aSk7cmV0dXJuLTF9LEFycmF5LnByb3RvdHlwZS55dj1mdW5jdGlvbih0LGUsaSl7dmFyIHI9QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLDAsMik7cmV0dXJuIGkmJnIucHVzaC5hcHBseShyLGkpLHRoaXMuc3BsaWNlLmFwcGx5KHRoaXMscil9LEFycmF5LnByb3RvdHlwZS51Zz1mdW5jdGlvbigpe2lmKDA9PT10aGlzLmxlbmd0aCl0aHJvdyBFcnJvcihcIkNhbid0IGdldCBvbmUgZWxlbWVudCBmcm9tIGVtcHR5IGFycmF5LlwiKTtmb3IodmFyIHQgaW4gdGhpcylpZihPYmplY3QuYXYodGhpcyx0KSlyZXR1cm4gdGhpc1t0XX0sQXJyYXkucHJvdG90eXBlLmNsZWFyPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubGVuZ3RoPTAsdGhpc30sQXJyYXkucHJvdG90eXBlLllmPWZ1bmN0aW9uKHQsZSl7dmFyIGkscixuLG8sZT1lfHxPYmplY3QuWWY7aWYodGhpcz09PXQpcmV0dXJuIDA7aWYoIXR8fCFBcnJheS5pc0FycmF5KHQpKXJldHVybiB2dC5wcm90b3R5cGUuWWYuY2FsbCh0aGlzLHQsZSk7Zm9yKHI9TWF0aC5taW4odGhpcy5sZW5ndGgsdC5sZW5ndGgpLGk9MDtpPHI7aSsrKWlmKGkgaW4gdGhpcyl7aWYoIShpIGluIHQpKXJldHVybi0xO2lmKG49dGhpc1tpXSxvPXRbaV0sbj1lKG4sbykpcmV0dXJuIG59ZWxzZSBpZihpIGluIHQpcmV0dXJuIDE7cmV0dXJuIHRoaXMubGVuZ3RoLXQubGVuZ3RofSxBcnJheS5wcm90b3R5cGUub2w9ZnVuY3Rpb24odCl7dmFyIGUsaSxyPXJ8fE9iamVjdC5vbCxuPTAsbz10aGlzLmxlbmd0aDtpZih0aGlzPT09dClyZXR1cm4hMDtpZighdHx8IUFycmF5LmlzQXJyYXkodCkpcmV0dXJuIHZ0LnByb3RvdHlwZS5vbC5jYWxsKHRoaXMsdCk7aWYobyE9PXQubGVuZ3RoKXJldHVybiExO2Zvcig7bjxvOysrbilpZihuIGluIHRoaXMpe2lmKGU9dGhpc1tuXSxpPXRbbl0sZSE9PWkmJmUmJmkmJiFyKGUsaSkpcmV0dXJuITF9ZWxzZSBpZihuIGluIHQpcmV0dXJuITE7cmV0dXJuITB9LEFycmF5LnByb3RvdHlwZS5jbG9uZT1mdW5jdGlvbih0LGUpe2lmKHZvaWQgMD09PXQpdD0xLzA7ZWxzZSBpZigwPT09dClyZXR1cm4gdGhpczt2YXIgaSxlPWV8fG5ldyB5dCxyPVtdO2ZvcihpIGluIHRoaXMpT2JqZWN0LmF2KHRoaXMsaSkmJihyW2ldPU9iamVjdC5jbG9uZSh0aGlzW2ldLHQtMSxlKSk7cmV0dXJuIHJ9LEFycmF5LnByb3RvdHlwZS5EZj1mdW5jdGlvbih0LGUpe3JldHVybiBuZXcgYyh0aGlzLHQsZSl9LEFycmF5LnByb3RvdHlwZS5JdGVyYXRvcj1jLGMucHJvdG90eXBlLm5leHQ9ZnVuY3Rpb24oKXtpZih0aGlzLnN0YXJ0PT09KG51bGw9PXRoaXMuZW5kP3RoaXMuSGYubGVuZ3RoOnRoaXMuZW5kKSl0aHJvdyBTdG9wSXRlcmF0aW9uO3JldHVybiB0aGlzLkhmW3RoaXMuc3RhcnQrK119LGZ0LmVnJiYoZnQ9ZnQuZWcpO3ZhciBtdD17fTttdC5lZz1oO3ZhciB3dD1odCxUdD1YO09iamVjdC5hZGRFYWNoKGgucHJvdG90eXBlLHgucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaChoLnByb3RvdHlwZSx3dC5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKGgucHJvdG90eXBlLFR0LnByb3RvdHlwZSksaC5wcm90b3R5cGUubmc9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHQsdGhpcy5NZix0aGlzLmNvbnRlbnQpfSxoLnByb3RvdHlwZS5maW5kPWZ1bmN0aW9uKHQsZSl7Zm9yKHZhciBlPWV8fHRoaXMuTWYsaT10aGlzLmhlYWQscj1pLm5leHQ7ciE9PWk7KXtpZihlKHIudmFsdWUsdCkpcmV0dXJuIHI7cj1yLm5leHR9fSxoLnByb3RvdHlwZS52dj1mdW5jdGlvbih0LGUpe2Zvcih2YXIgZT1lfHx0aGlzLk1mLGk9dGhpcy5oZWFkLHI9aS5MZjtyIT09aTspe2lmKGUoci52YWx1ZSx0KSlyZXR1cm4gcjtyPXIuTGZ9fSxoLnByb3RvdHlwZS5oYXM9ZnVuY3Rpb24odCxlKXtyZXR1cm4hIXRoaXMuZmluZCh0LGUpfSxoLnByb3RvdHlwZS5nZXQ9ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzLmZpbmQodCxlKTtyZXR1cm4gaT9pLnZhbHVlOnRoaXMuY29udGVudCgpfSxoLnByb3RvdHlwZVtcImRlbGV0ZVwiXT1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMudnYodCxlKTtyZXR1cm4hIWkmJihpW1wiZGVsZXRlXCJdKCksdGhpcy5sZW5ndGgtLSwhMCl9LGgucHJvdG90eXBlLmNsZWFyPWZ1bmN0aW9uKCl7dGhpcy5oZWFkLm5leHQ9dGhpcy5oZWFkLkxmPXRoaXMuaGVhZCx0aGlzLmxlbmd0aD0wfSxoLnByb3RvdHlwZS5hZGQ9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuaGVhZC5tdihuZXcgdGhpcy5Ob2RlKHQpKSx0aGlzLmxlbmd0aCsrLCEwfSxoLnByb3RvdHlwZS5wdXNoPWZ1bmN0aW9uKCl7Zm9yKHZhciB0PXRoaXMuaGVhZCxlPTA7ZTxhcmd1bWVudHMubGVuZ3RoO2UrKyl7dmFyIGk9bmV3IHRoaXMuTm9kZShhcmd1bWVudHNbZV0pO3QubXYoaSksdGhpcy5sZW5ndGgrK319LGgucHJvdG90eXBlLnVuc2hpZnQ9ZnVuY3Rpb24oKXtmb3IodmFyIHQ9dGhpcy5oZWFkLGU9MDtlPGFyZ3VtZW50cy5sZW5ndGg7ZSsrKXt2YXIgaT1uZXcgdGhpcy5Ob2RlKGFyZ3VtZW50c1tlXSk7dC53dihpKSx0aGlzLmxlbmd0aCsrLHQ9aX19LGgucHJvdG90eXBlLnBvcD1mdW5jdGlvbigpe3ZhciB0LGU9dGhpcy5oZWFkO3JldHVybiBlLkxmIT09ZSYmKHQ9ZS5MZi52YWx1ZSxlLkxmW1wiZGVsZXRlXCJdKCksdGhpcy5sZW5ndGgtLSksdH0saC5wcm90b3R5cGUuc2hpZnQ9ZnVuY3Rpb24oKXt2YXIgdCxlPXRoaXMuaGVhZDtyZXR1cm4gZS5MZiE9PWUmJih0PWUubmV4dC52YWx1ZSxlLm5leHRbXCJkZWxldGVcIl0oKSx0aGlzLmxlbmd0aC0tKSx0fSxoLnByb3RvdHlwZS5Udj1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMuaGVhZDtpZihcIm51bWJlclwiPT10eXBlb2YgdCl7dmFyIHI9dDtpZigwPD1yKWZvcih0PWkubmV4dDtyJiYoci0tLHQ9dC5uZXh0LCEodD09aSkpOyk7ZWxzZSBmb3IodD1pOzA+ciYmKHIrKyx0PXQuTGYsISh0PT1pKSk7KTtyZXR1cm4gdH1yZXR1cm4gdHx8ZX0saC5wcm90b3R5cGUuc2xpY2U9ZnVuY3Rpb24odCxlKXtmb3IodmFyIGk9W10scj10aGlzLmhlYWQsdD10aGlzLlR2KHQsci5uZXh0KSxlPXRoaXMuVHYoZSxyKTt0IT09ZSYmdCE9PXI7KWkucHVzaCh0LnZhbHVlKSx0PXQubmV4dDtyZXR1cm4gaX0saC5wcm90b3R5cGUuc3BsaWNlPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMueXYodCxlLEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywyKSl9LGgucHJvdG90eXBlLnl2PWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj1bXSxuPXQsdD10aGlzLlR2KHQsdGhpcy5oZWFkKTtmb3Iodm9pZCAwPT09ZSYmKGU9MS8wKTtlLS0mJjA8PWUmJnQhPT10aGlzLmhlYWQ7KXIucHVzaCh0LnZhbHVlKSx0W1wiZGVsZXRlXCJdKCksdD10Lm5leHQsdGhpcy5sZW5ndGgtLTtpZihpKXtmb3IobnVsbD09PW4mJnQ9PT10aGlzLmhlYWQmJih0PXRoaXMuaGVhZC5uZXh0KSxlPTA7ZTxpLmxlbmd0aDtlKyspbj1uZXcgdGhpcy5Ob2RlKGlbZV0pLHQubXYobik7dGhpcy5sZW5ndGgrPWkubGVuZ3RofXJldHVybiByfSxoLnByb3RvdHlwZS5yZXZlcnNlPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5oZWFkO2Rve3ZhciBlPXQubmV4dDt0Lm5leHQ9dC5MZix0LkxmPWUsdD10Lm5leHR9d2hpbGUodCE9PXRoaXMuaGVhZCk7cmV0dXJuIHRoaXN9LGgucHJvdG90eXBlLnJlZHVjZT1mdW5jdGlvbih0LGUsaSl7Zm9yKHZhciByPXRoaXMuaGVhZCxuPXIubmV4dDtuIT09cjspZT10LmNhbGwoaSxlLG4udmFsdWUsbix0aGlzKSxuPW4ubmV4dDtyZXR1cm4gZX0saC5wcm90b3R5cGUucmVkdWNlUmlnaHQ9ZnVuY3Rpb24odCxlLGkpe2Zvcih2YXIgcj10aGlzLmhlYWQsbj1yLkxmO24hPT1yOyllPXQuY2FsbChpLGUsbi52YWx1ZSxuLHRoaXMpLG49bi5MZjtyZXR1cm4gZX0saC5wcm90b3R5cGUudWc9ZnVuY3Rpb24oKXtpZih0aGlzLmhlYWQ9PT10aGlzLmhlYWQubmV4dCl0aHJvdyBFcnJvcihcIkNhbid0IGdldCBvbmUgdmFsdWUgZnJvbSBlbXB0eSBsaXN0XCIpO3JldHVybiB0aGlzLmhlYWQubmV4dC52YWx1ZX0saC5wcm90b3R5cGUuRGY9ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IHAodGhpcy5oZWFkKX0scC5wcm90b3R5cGUubmV4dD1mdW5jdGlvbigpe2lmKHRoaXMuVWY9PT10aGlzLmhlYWQpdGhyb3cgU3RvcEl0ZXJhdGlvbjt2YXIgdD10aGlzLlVmLnZhbHVlO3JldHVybiB0aGlzLlVmPXRoaXMuVWYubmV4dCx0fSxoLnByb3RvdHlwZS5Ob2RlPXUsdS5wcm90b3R5cGVbXCJkZWxldGVcIl09ZnVuY3Rpb24oKXt0aGlzLkxmLm5leHQ9dGhpcy5uZXh0LHRoaXMubmV4dC5MZj10aGlzLkxmfSx1LnByb3RvdHlwZS5tdj1mdW5jdGlvbih0KXt2YXIgZT10aGlzLkxmO3RoaXMuTGY9dCx0LkxmPWUsZS5uZXh0PXQsdC5uZXh0PXRoaXN9LHUucHJvdG90eXBlLnd2PWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMubmV4dDt0aGlzLm5leHQ9dCx0Lm5leHQ9ZSxlLkxmPXQsdC5MZj10aGlzfSxtdC5lZyYmKG10PW10LmVnKTt2YXIgU3Q9e30sYnQ9bXQ7U3QuZWc9bCxsLnByb3RvdHlwZS5Tdj1mdW5jdGlvbigpe3JldHVybiB0aGlzLmJ2fHwodGhpcy5idj17SGc6bmV3IGJ0LExnOm5ldyBidH0pLHRoaXMuYnZ9LGwucHJvdG90eXBlLkV2PWZ1bmN0aW9uKHQsZSl7dGhpcy5tYWtlT2JzZXJ2YWJsZSYmIXRoaXMuZGlzcGF0Y2hNYXBDaGFuZ2VzJiZ0aGlzLm1ha2VPYnNlcnZhYmxlKCk7dmFyIGk9dGhpcy5TdigpOyhlP2kuSGc6aS5MZykucHVzaCh0KSx0aGlzLkl2PSEwfSxsLnByb3RvdHlwZS5Sdj1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMuU3YoKSxpPShlP2kuSGc6aS5MZykudnYodCk7aWYoIWkpdGhyb3cgRXJyb3IoXCJDYW4ndCByZW1vdmUgbGlzdGVuZXI6IGRvZXMgbm90IGV4aXN0LlwiKTtpW1wiZGVsZXRlXCJdKCl9LGwucHJvdG90eXBlLmt2PWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj10aGlzLlN2KCksbj1cImhhbmRsZU1hcFwiKygoaT9cIldpbGxcIjpcIlwiKStcIkNoYW5nZVwiKTsoaT9yLkhnOnIuTGcpLmZvckVhY2goZnVuY3Rpb24oaSl7dmFyIHI9aSxpPWlbbl18fGk7aS5jYWxsJiZpLmNhbGwocixlLHQsdGhpcyl9LHRoaXMpfSxsLnByb3RvdHlwZS5Ddj1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5Fdih0LCEwKX0sbC5wcm90b3R5cGUuT3Y9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuUnYodCwhMCl9LGwucHJvdG90eXBlLlB2PWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMua3YodCxlLCEwKX0sU3QuZWcmJihTdD1TdC5lZyk7dmFyIEV0PXt9LEl0PW90LFJ0PVN0LGt0PVg7RXQuZWc9ZCxJdC5hZGRFYWNoKGQucHJvdG90eXBlLFJ0LnByb3RvdHlwZSksSXQuYWRkRWFjaChkLnByb3RvdHlwZSxrdC5wcm90b3R5cGUpLGQucHJvdG90eXBlLmFkZEVhY2g9ZnVuY3Rpb24odCl7dCYmSXQodCk9PT10JiYoXCJmdW5jdGlvblwiPT10eXBlb2YgdC5mb3JFYWNoP1wiZnVuY3Rpb25cIj09dHlwZW9mIHQua2V5cz90LmZvckVhY2goZnVuY3Rpb24odCxlKXt0aGlzLnNldChlLHQpfSx0aGlzKTp0LmZvckVhY2goZnVuY3Rpb24odCl7dGhpcy5zZXQodFswXSx0WzFdKX0sdGhpcyk6SXQua2V5cyh0KS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3RoaXMuc2V0KGUsdFtlXSl9LHRoaXMpKX0sZC5wcm90b3R5cGUuZ2V0PWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcy5WZi5nZXQobmV3IHRoaXMuQXYodCkpO3JldHVybiBpP2kudmFsdWU6MTxhcmd1bWVudHMubGVuZ3RoP2U6dGhpcy5jb250ZW50KHQpfSxkLnByb3RvdHlwZS5zZXQ9ZnVuY3Rpb24odCxlKXt2YXIgaT1uZXcgdGhpcy5Bdih0LGUpLHI9dGhpcy5WZi5nZXQoaSksbj0hMTtyZXR1cm4gcj8odGhpcy5JdiYmdGhpcy5Qdih0LHIudmFsdWUpLHIudmFsdWU9ZSk6KHRoaXMuSXYmJnRoaXMuUHYodCx2b2lkIDApLHRoaXMuVmYuYWRkKGkpJiYodGhpcy5sZW5ndGgrKyxuPSEwKSksdGhpcy5JdiYmdGhpcy5rdih0LGUpLG59LGQucHJvdG90eXBlLmFkZD1mdW5jdGlvbih0LGUpe3JldHVybiB0aGlzLnNldChlLHQpfSxkLnByb3RvdHlwZS5oYXM9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuVmYuaGFzKG5ldyB0aGlzLkF2KHQpKX0sZC5wcm90b3R5cGVbXCJkZWxldGVcIl09ZnVuY3Rpb24odCl7dmFyIGU9bmV3IHRoaXMuQXYodCk7aWYodGhpcy5WZi5oYXMoZSkpe3ZhciBpPXRoaXMuVmYuZ2V0KGUpLnZhbHVlO3JldHVybiB0aGlzLkl2JiZ0aGlzLlB2KHQsaSksdGhpcy5WZltcImRlbGV0ZVwiXShlKSx0aGlzLmxlbmd0aC0tLHRoaXMuSXYmJnRoaXMua3YodCx2b2lkIDApLCEwfXJldHVybiExfSxkLnByb3RvdHlwZS5jbGVhcj1mdW5jdGlvbigpe3RoaXMuVmYuY2xlYXIoKSx0aGlzLmxlbmd0aD0wfSxkLnByb3RvdHlwZS5yZWR1Y2U9ZnVuY3Rpb24odCxlLGkpe3JldHVybiB0aGlzLlZmLnJlZHVjZShmdW5jdGlvbihlLHIpe3JldHVybiB0LmNhbGwoaSxlLHIudmFsdWUsci5rZXksdGhpcyl9LGUsdGhpcyl9LGQucHJvdG90eXBlLnJlZHVjZVJpZ2h0PWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gdGhpcy5WZi5yZWR1Y2VSaWdodChmdW5jdGlvbihlLHIpe3JldHVybiB0LmNhbGwoaSxlLHIudmFsdWUsci5rZXksdGhpcyl9LGUsdGhpcyl9LGQucHJvdG90eXBlLmtleXM9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24odCxlKXtyZXR1cm4gZX0pfSxkLnByb3RvdHlwZS52YWx1ZXM9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5tYXAoRnVuY3Rpb24uaWRlbnRpdHkpfSxkLnByb3RvdHlwZS5Odj1mdW5jdGlvbigpe3JldHVybiB0aGlzLm1hcChmdW5jdGlvbih0LGUpe3JldHVybltlLHRdfSl9LGQucHJvdG90eXBlLm9sPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIGU9ZXx8SXQub2wsdGhpcz09PXR8fChJdC52Zyh0LFwiZXZlcnlcIik/dC5sZW5ndGg9PT10aGlzLmxlbmd0aCYmdC5ldmVyeShmdW5jdGlvbih0LGkpe3JldHVybiBlKHRoaXMuZ2V0KGkpLHQpfSx0aGlzKTpJdC5rZXlzKHQpLmxlbmd0aD09PXRoaXMubGVuZ3RoJiZJdC5rZXlzKHQpLmV2ZXJ5KGZ1bmN0aW9uKGkpe3JldHVybiBlKHRoaXMuZ2V0KGkpLHRbaV0pfSx0aGlzKSl9LGQucHJvdG90eXBlLkF2PWZ1bmN0aW9uKHQsZSl7dGhpcy5rZXk9dCx0aGlzLnZhbHVlPWV9LEV0LmVnJiYoRXQ9RXQuZWcpO3ZhciBDdD17fSxPdD14LFB0PUV0LEF0PVg7Q3QuZWc9ZixPYmplY3QuYWRkRWFjaChmLnByb3RvdHlwZSxPdC5wcm90b3R5cGUpLFxuICAgIE9iamVjdC5hZGRFYWNoKGYucHJvdG90eXBlLFB0LnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2goZi5wcm90b3R5cGUsQXQucHJvdG90eXBlKSxmLnByb3RvdHlwZS5uZz1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodCx0aGlzLm1hbmdsZSx0aGlzLmNvbnRlbnQpfSxmLnByb3RvdHlwZS54dj1mdW5jdGlvbih0KXtpZihcInN0cmluZ1wiIT10eXBlb2YgdCl0aHJvdyBuZXcgVHlwZUVycm9yKFwia2V5IG11c3QgYmUgYSBzdHJpbmcuXCIpfSxmLnByb3RvdHlwZS5nZXQ9ZnVuY3Rpb24odCxlKXt0aGlzLnh2KHQpO3ZhciBpPVwiflwiK3Q7cmV0dXJuIGkgaW4gdGhpcy5WZj90aGlzLlZmW2ldOjE8YXJndW1lbnRzLmxlbmd0aD9lOnRoaXMuY29udGVudCgpfSxmLnByb3RvdHlwZS5zZXQ9ZnVuY3Rpb24odCxlKXt0aGlzLnh2KHQpO3ZhciBpPVwiflwiK3Q7cmV0dXJuIGkgaW4gdGhpcy5WZj8odGhpcy5WZltpXT1lLCExKToodGhpcy5sZW5ndGgrKyx0aGlzLlZmW2ldPWUsITApfSxmLnByb3RvdHlwZS5oYXM9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMueHYodCksXCJ+XCIrdCBpbiB0aGlzLlZmfSxmLnByb3RvdHlwZVtcImRlbGV0ZVwiXT1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy54dih0KSxcIn5cIit0IGluIHRoaXMuVmYmJihkZWxldGUgdGhpcy5WZltcIn5cIit0XSx0aGlzLmxlbmd0aC0tLCEwKX0sZi5wcm90b3R5cGUuY2xlYXI9ZnVuY3Rpb24oKXtmb3IodmFyIHQgaW4gdGhpcy5WZilkZWxldGUgdGhpcy5WZlt0XTt0aGlzLmxlbmd0aD0wfSxmLnByb3RvdHlwZS5yZWR1Y2U9ZnVuY3Rpb24odCxlLGkpe2Zvcih2YXIgciBpbiB0aGlzLlZmKWU9dC5jYWxsKGksZSx0aGlzLlZmW3JdLHIuc2xpY2UoMSksdGhpcyk7cmV0dXJuIGV9LGYucHJvdG90eXBlLnVnPWZ1bmN0aW9uKCl7Zm9yKHZhciB0IGluIHRoaXMuVmYpcmV0dXJuIHRoaXMuVmZbdF07dGhyb3cgRXJyb3IoXCJDYW4ndCBnZXQgb25lIHZhbHVlIGZyb20gZW1wdHkgZGljdGlvbmFyeS5cIil9LEN0LmVnJiYoQ3Q9Q3QuZWcpO3ZhciBOdD17fSx4dD1DdCxCdD1tdCxGdD14LF90PUIsRHQ9SCxIdD1YO050LmVnPWcsT2JqZWN0LmFkZEVhY2goZy5wcm90b3R5cGUsRnQucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaChnLnByb3RvdHlwZSxfdC5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKGcucHJvdG90eXBlLEh0LnByb3RvdHlwZSksZy5wcm90b3R5cGUuSmY9eHQsZy5wcm90b3R5cGUuS2Y9QnQsZy5wcm90b3R5cGUubmc9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHQsdGhpcy5NZix0aGlzLlFmLHRoaXMuY29udGVudCl9LGcucHJvdG90eXBlLmhhcz1mdW5jdGlvbih0KXt2YXIgZT10aGlzLlFmKHQpO3JldHVybiB0aGlzLnFmLmdldChlKS5oYXModCl9LGcucHJvdG90eXBlLmdldD1mdW5jdGlvbih0KXt2YXIgZT10aGlzLlFmKHQpLGk9dGhpcy5xZjtyZXR1cm4gaS5oYXMoZSk/aS5nZXQoZSkuZ2V0KHQpOnRoaXMuY29udGVudCh0KX0sZy5wcm90b3R5cGVbXCJkZWxldGVcIl09ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5RZih0KSxpPXRoaXMucWY7aWYoaS5oYXMoZSkpe3ZhciByPWkuZ2V0KGUpO2lmKHJbXCJkZWxldGVcIl0odCkpcmV0dXJuIHRoaXMubGVuZ3RoLS0sMD09PXIubGVuZ3RoJiZpW1wiZGVsZXRlXCJdKGUpLCEwfXJldHVybiExfSxnLnByb3RvdHlwZS5jbGVhcj1mdW5jdGlvbigpe3RoaXMucWYuY2xlYXIoKSx0aGlzLmxlbmd0aD0wfSxnLnByb3RvdHlwZS5hZGQ9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcy5RZih0KSxpPXRoaXMucWY7cmV0dXJuIGkuaGFzKGUpfHxpLnNldChlLG5ldyB0aGlzLktmKG51bGwsdGhpcy5NZikpLCFpLmdldChlKS5oYXModCkmJihpLmdldChlKS5hZGQodCksdGhpcy5sZW5ndGgrKywhMCl9LGcucHJvdG90eXBlLnJlZHVjZT1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIHRoaXMucWYucmVkdWNlKGZ1bmN0aW9uKGUscil7cmV0dXJuIHIucmVkdWNlKGZ1bmN0aW9uKGUscil7cmV0dXJuIHQuY2FsbChpLGUscixyLHRoaXMpfSxlLHRoaXMpfSxlLHRoaXMpfSxnLnByb3RvdHlwZS51Zz1mdW5jdGlvbigpe2lmKDA9PT10aGlzLmxlbmd0aCl0aHJvdyBFcnJvcihcIkNhbid0IGdldCBvbmUgdmFsdWUgZnJvbSBlbXB0eSBzZXQuXCIpO3JldHVybiB0aGlzLnFmLnVnKCkudWcoKX0sZy5wcm90b3R5cGUuRGY9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5xZi52YWx1ZXMoKS5hZygpLkRmKCl9LGcucHJvdG90eXBlLmxvZz1mdW5jdGlvbih0LGUsaSxyKXt0PXR8fER0LmtnLGU9ZXx8dGhpcy5CdixpfHwoaT1jb25zb2xlLmxvZyxyPWNvbnNvbGUpO3ZhciBpPWkuYmluZChyKSxuPXRoaXMucWYsbz1uLmtleXMoKTtvLmZvckVhY2goZnVuY3Rpb24ocyxhKXt2YXIgYyxoO2E9PT1vLmxlbmd0aC0xPyhjPXQuYmcsaD1cIiBcIik6KGM9MD09PWE/dC5UZzp0LkVnLGg9dC5JZyk7dmFyIHA9bi5nZXQocyk7aS5jYWxsKHIsYyt0Lm1nK3QuVGcrXCIgXCIrcykscC5mb3JFYWNoKGZ1bmN0aW9uKG4sbyl7dmFyIHMsYTtvPT09cC5oZWFkLkxmPyhzPXQuYmcsYT1cIiBcIik6KHM9dC5FZyxhPXQuSWcpO3ZhciBjO2UobyxmdW5jdGlvbihlKXtjP2kuY2FsbChyLGgrXCIgXCIrYStcIiAgXCIrZSk6KGkuY2FsbChyLGgrXCIgXCIrcyt0Lm1nK3QubWcrZSksYz0hMCl9LGZ1bmN0aW9uKGUpe2kuY2FsbChyLGgrXCIgXCIrdC5JZytcIiAgXCIrZSl9KX0pfSl9LGcucHJvdG90eXBlLkJ2PWZ1bmN0aW9uKHQsZSl7dmFyIGk9dC52YWx1ZTtPYmplY3QoaSk9PT1pP0pTT04uc3RyaW5naWZ5KGksbnVsbCw0KS5zcGxpdChcIlxcblwiKS5mb3JFYWNoKGZ1bmN0aW9uKHQpe2UoXCIgXCIrdCl9KTplKFwiIFwiK2kpfSxOdC5lZyYmKE50PU50LmVnKTt2YXIgTHQ9e30sTXQ9TnQsanQ9eCxVdD1FdCxWdD1YO0x0LmVnPXYsT2JqZWN0LmFkZEVhY2godi5wcm90b3R5cGUsanQucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaCh2LnByb3RvdHlwZSxVdC5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKHYucHJvdG90eXBlLFZ0LnByb3RvdHlwZSksdi5wcm90b3R5cGUubmc9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHQsdGhpcy5NZix0aGlzLlFmLHRoaXMuY29udGVudCl9LHYucHJvdG90eXBlLmxvZz1mdW5jdGlvbih0LGUpe2U9ZXx8dGhpcy5zdHJpbmdpZnksdGhpcy5WZi5sb2codCxlKX0sdi5wcm90b3R5cGUuc3RyaW5naWZ5PWZ1bmN0aW9uKHQsZSl7cmV0dXJuIGUrSlNPTi5zdHJpbmdpZnkodC5rZXkpK1wiOiBcIitKU09OLnN0cmluZ2lmeSh0LnZhbHVlKX0sTHQuZWcmJihMdD1MdC5lZyk7dmFyIFF0PXt9LHF0PW10LEp0PU50LEt0PXgsR3Q9Qix6dD1YLFd0PXJ0O1F0LmVnPXksT2JqZWN0LmFkZEVhY2goeS5wcm90b3R5cGUsS3QucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaCh5LnByb3RvdHlwZSxHdC5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKHkucHJvdG90eXBlLHp0LnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2goeS5wcm90b3R5cGUsV3QucHJvdG90eXBlKSx5LnByb3RvdHlwZS5HZj1xdCx5LnByb3RvdHlwZS56Zj1KdCx5LnByb3RvdHlwZS5uZz1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodCx0aGlzLk1mLHRoaXMuUWYsdGhpcy5jb250ZW50KX0seS5wcm90b3R5cGUuaGFzPWZ1bmN0aW9uKHQpe3JldHVybiB0PW5ldyB0aGlzLm9yZGVyLk5vZGUodCksdGhpcy5WZi5oYXModCl9LHkucHJvdG90eXBlLmdldD1mdW5jdGlvbih0KXt2YXIgZT1uZXcgdGhpcy5vcmRlci5Ob2RlKHQpO3JldHVybihlPXRoaXMuVmYuZ2V0KGUpKT9lLnZhbHVlOnRoaXMuY29udGVudCh0KX0seS5wcm90b3R5cGUuYWRkPWZ1bmN0aW9uKHQpe3ZhciBlPW5ldyB0aGlzLm9yZGVyLk5vZGUodCk7cmV0dXJuIXRoaXMuVmYuaGFzKGUpJiYodGhpcy4kZyYmdGhpcy5udihbdF0sW10sMCksdGhpcy5vcmRlci5hZGQodCksZT10aGlzLm9yZGVyLmhlYWQuTGYsdGhpcy5WZi5hZGQoZSksdGhpcy5sZW5ndGgrKyx0aGlzLiRnJiZ0aGlzLlhnKFt0XSxbXSwwKSwhMCl9LHkucHJvdG90eXBlW1wiZGVsZXRlXCJdPWZ1bmN0aW9uKHQpe3ZhciBlPW5ldyB0aGlzLm9yZGVyLk5vZGUodCk7cmV0dXJuISF0aGlzLlZmLmhhcyhlKSYmKHRoaXMuJGcmJnRoaXMubnYoW10sW3RdLDApLGU9dGhpcy5WZi5nZXQoZSksdGhpcy5WZltcImRlbGV0ZVwiXShlKSxlW1wiZGVsZXRlXCJdKCksdGhpcy5sZW5ndGgtLSx0aGlzLiRnJiZ0aGlzLlhnKFtdLFt0XSwwKSwhMCl9LHkucHJvdG90eXBlLnVnPWZ1bmN0aW9uKCl7aWYoMD09PXRoaXMubGVuZ3RoKXRocm93IEVycm9yKFwiQ2FuJ3QgZ2V0IG9uZSB2YWx1ZSBmcm9tIGVtcHR5IHNldC5cIik7cmV0dXJuIHRoaXMuVmYudWcoKS52YWx1ZX0seS5wcm90b3R5cGUuY2xlYXI9ZnVuY3Rpb24oKXt0aGlzLlZmLmNsZWFyKCksdGhpcy5vcmRlci5jbGVhcigpLHRoaXMubGVuZ3RoPTB9LHkucHJvdG90eXBlLnJlZHVjZT1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIHRoaXMub3JkZXIucmVkdWNlKGZ1bmN0aW9uKGUscil7cmV0dXJuIHQuY2FsbChpLGUscixyLHRoaXMpfSxlLHRoaXMpfSx5LnByb3RvdHlwZS5yZWR1Y2VSaWdodD1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIHRoaXMub3JkZXIucmVkdWNlUmlnaHQoZnVuY3Rpb24oZSxyKXtyZXR1cm4gdC5jYWxsKGksZSxyLHIsdGhpcyl9LGUsdGhpcyl9LHkucHJvdG90eXBlLkRmPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMub3JkZXIuRGYoKX0seS5wcm90b3R5cGUubG9nPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5WZjtyZXR1cm4gdC5sb2cuYXBwbHkodCxhcmd1bWVudHMpfSxRdC5lZyYmKFF0PVF0LmVnKTt2YXIgJHQ9e30sWXQ9UXQsWHQ9eCxadD1CLHRlPVg7JHQuZWc9bSxPYmplY3QuYWRkRWFjaChtLnByb3RvdHlwZSxYdC5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKG0ucHJvdG90eXBlLFp0LnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2gobS5wcm90b3R5cGUsdGUucHJvdG90eXBlKSxtLnByb3RvdHlwZS5uZz1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodCx0aGlzLm1heExlbmd0aCx0aGlzLk1mLHRoaXMuUWYsdGhpcy5jb250ZW50KX0sbS5wcm90b3R5cGUuaGFzPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLlZmLmhhcyh0KX0sbS5wcm90b3R5cGUuZ2V0PWZ1bmN0aW9uKHQpe3JldHVybiB0PXRoaXMuVmYuZ2V0KHQpLHZvaWQgMCE9PXQ/KHRoaXMuVmZbXCJkZWxldGVcIl0odCksdGhpcy5WZi5hZGQodCkpOnQ9dGhpcy5jb250ZW50KCksdH0sbS5wcm90b3R5cGUuYWRkPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLlZmLmhhcyh0KSYmKHRoaXMuVmZbXCJkZWxldGVcIl0odCksdGhpcy5sZW5ndGgtLSksdGhpcy5WZi5hZGQodCksdGhpcy5sZW5ndGgrKywhKHRoaXMuVmYubGVuZ3RoPnRoaXMubWF4TGVuZ3RoKXx8KHRoaXMuVmZbXCJkZWxldGVcIl0odGhpcy5WZi5vcmRlci5oZWFkLm5leHQudmFsdWUpLHRoaXMubGVuZ3RoLS0sITEpfSxtLnByb3RvdHlwZVtcImRlbGV0ZVwiXT1mdW5jdGlvbih0KXtyZXR1cm4hIXRoaXMuVmZbXCJkZWxldGVcIl0odCkmJih0aGlzLmxlbmd0aC0tLCEwKX0sbS5wcm90b3R5cGUudWc9ZnVuY3Rpb24oKXtpZigwPT09dGhpcy5sZW5ndGgpdGhyb3cgRXJyb3IoXCJDYW4ndCBnZXQgb25lIHZhbHVlIGZyb20gZW1wdHkgY29sbGVjdGlvbi5cIik7cmV0dXJuIHRoaXMuVmYudWcoKX0sbS5wcm90b3R5cGUuY2xlYXI9ZnVuY3Rpb24oKXt0aGlzLlZmLmNsZWFyKCksdGhpcy5sZW5ndGg9MH0sbS5wcm90b3R5cGUucmVkdWNlPWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gdGhpcy5WZi5yZWR1Y2UoZnVuY3Rpb24oZSxyKXtyZXR1cm4gdC5jYWxsKGksZSxyLHIsdGhpcyl9LGUsdGhpcyl9LG0ucHJvdG90eXBlLnJlZHVjZVJpZ2h0PWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gdGhpcy5WZi5yZWR1Y2VSaWdodChmdW5jdGlvbih0LGUpe3JldHVybiBjYWxsYmFjay5jYWxsKGksdCxlLGUsdGhpcyl9LGJhc2lzLHRoaXMpfSxtLnByb3RvdHlwZS5EZj1mdW5jdGlvbigpe3JldHVybiB0aGlzLlZmLkRmKCl9LCR0LmVnJiYoJHQ9JHQuZWcpO3ZhciBlZT17fSxpZT0kdCxyZT14LG5lPUV0LG9lPVg7ZWUuZWc9dyxPYmplY3QuYWRkRWFjaCh3LnByb3RvdHlwZSxyZS5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKHcucHJvdG90eXBlLG5lLnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2gody5wcm90b3R5cGUsb2UucHJvdG90eXBlKSx3LnByb3RvdHlwZS5uZz1mdW5jdGlvbih0KXtyZXR1cm4gbmV3IHRoaXMuY29uc3RydWN0b3IodCx0aGlzLm1heExlbmd0aCx0aGlzLk1mLHRoaXMuUWYsdGhpcy5jb250ZW50KX0sdy5wcm90b3R5cGUubG9nPWZ1bmN0aW9uKHQsZSl7ZT1lfHx0aGlzLnN0cmluZ2lmeSx0aGlzLlZmLmxvZyh0LGUpfSx3LnByb3RvdHlwZS5zdHJpbmdpZnk9ZnVuY3Rpb24odCxlKXtyZXR1cm4gZStKU09OLnN0cmluZ2lmeSh0LmtleSkrXCI6IFwiK0pTT04uc3RyaW5naWZ5KHQudmFsdWUpfSxlZS5lZyYmKGVlPWVlLmVnKTt2YXIgc2U9e30sYWU9UXQsY2U9eCxoZT1FdCxwZT1YO3NlLmVnPVQsT2JqZWN0LmFkZEVhY2goVC5wcm90b3R5cGUsY2UucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaChULnByb3RvdHlwZSxoZS5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKFQucHJvdG90eXBlLHBlLnByb3RvdHlwZSksVC5wcm90b3R5cGUubmc9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHQsdGhpcy5NZix0aGlzLlFmLHRoaXMuY29udGVudCl9LFQucHJvdG90eXBlLmxvZz1mdW5jdGlvbih0LGUpe2U9ZXx8dGhpcy5zdHJpbmdpZnksdGhpcy5WZi5sb2codCxlKX0sVC5wcm90b3R5cGUuc3RyaW5naWZ5PWZ1bmN0aW9uKHQsZSl7cmV0dXJuIGUrSlNPTi5zdHJpbmdpZnkodC5rZXkpK1wiOiBcIitKU09OLnN0cmluZ2lmeSh0LnZhbHVlKX0sc2UuZWcmJihzZT1zZS5lZyk7dmFyIHVlPXt9LGxlPXNlO3VlLmVnPVMsUy5wcm90b3R5cGU9T2JqZWN0LmNyZWF0ZShsZS5wcm90b3R5cGUpLFMucHJvdG90eXBlLmNvbnN0cnVjdG9yPVMsUy5wcm90b3R5cGUubmc9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHQsdGhpcy5XZix0aGlzLk1mLHRoaXMuUWYpfSxTLnByb3RvdHlwZS5zZXQ9ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzLmdldCh0KTtpLnl2KDAsaS5sZW5ndGgsZSl9LFMucHJvdG90eXBlLldmPWZ1bmN0aW9uKCl7cmV0dXJuW119LHVlLmVnJiYodWU9dWUuZWcpO3ZhciBkZT17fTtkZS5lZz1iO3ZhciBmZT1YLGdlPXJ0O09iamVjdC5hZGRFYWNoKGIucHJvdG90eXBlLHgucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaChiLnByb3RvdHlwZSxmZS5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKGIucHJvdG90eXBlLGdlLnByb3RvdHlwZSksYi5wcm90b3R5cGUubmc9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyB0aGlzLmNvbnN0cnVjdG9yKHQsdGhpcy5NZix0aGlzLiRmLHRoaXMuY29udGVudCl9LGIucHJvdG90eXBlLmhhcz1mdW5jdGlvbih0KXt2YXIgZT1FKHRoaXMuSGYsdCx0aGlzLiRmKTtyZXR1cm4gMDw9ZSYmdGhpcy5NZih0aGlzLkhmW2VdLHQpfSxiLnByb3RvdHlwZS5nZXQ9ZnVuY3Rpb24odCl7dmFyIGU9SSh0aGlzLkhmLHQsdGhpcy4kZix0aGlzLk1mKTtyZXR1cm4tMSE9PWU/dGhpcy5IZltlXTp0aGlzLmNvbnRlbnQodCl9LGIucHJvdG90eXBlLmFkZD1mdW5jdGlvbih0KXt2YXIgZTtlPXRoaXMuSGY7dmFyIGk9dGhpcy4kZixyPUUoZSx0LGkpO2lmKDA+cillPS1yLTE7ZWxzZXtmb3IodmFyIG49ZS5sZW5ndGgtMTtyPG4mJjA9PT1pKHQsZVtyKzFdKTspcisrO2U9cn1yZXR1cm4gdGhpcy4kZyYmdGhpcy5udihbdF0sW10sZSksdGhpcy5IZi5zcGxpY2UoZSwwLHQpLHRoaXMubGVuZ3RoKyssdGhpcy4kZyYmdGhpcy5YZyhbdF0sW10sZSksITB9LGIucHJvdG90eXBlW1wiZGVsZXRlXCJdPWZ1bmN0aW9uKHQpe3ZhciBlPUkodGhpcy5IZix0LHRoaXMuJGYsdGhpcy5NZik7cmV0dXJuLTEhPT1lJiYodGhpcy4kZyYmdGhpcy5udihbXSxbdF0sZSksdGhpcy5IZi5zcGxpY2UoZSwxKSx0aGlzLmxlbmd0aC0tLHRoaXMuJGcmJnRoaXMuWGcoW10sW3RdLGUpLCEwKX0sYi5wcm90b3R5cGUuaW5kZXhPZj1mdW5jdGlvbih0KXtyZXR1cm4gSSh0aGlzLkhmLHQsdGhpcy4kZix0aGlzLk1mKX0sYi5wcm90b3R5cGUubGFzdEluZGV4T2Y9ZnVuY3Rpb24odCl7cmV0dXJuIFIodGhpcy5IZix0LHRoaXMuJGYsdGhpcy5NZil9LGIucHJvdG90eXBlLmZpbmQ9ZnVuY3Rpb24odCl7cmV0dXJuIEkodGhpcy5IZix0LHRoaXMuJGYsdGhpcy5NZil9LGIucHJvdG90eXBlLnZ2PWZ1bmN0aW9uKHQpe3JldHVybiBSKHRoaXMuSGYsdCx0aGlzLiRmLHRoaXMuTWYpfSxiLnByb3RvdHlwZS5wdXNoPWZ1bmN0aW9uKCl7dGhpcy5hZGRFYWNoKGFyZ3VtZW50cyl9LGIucHJvdG90eXBlLnVuc2hpZnQ9ZnVuY3Rpb24oKXt0aGlzLmFkZEVhY2goYXJndW1lbnRzKX0sYi5wcm90b3R5cGUucG9wPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuSGYucG9wKCl9LGIucHJvdG90eXBlLnNoaWZ0PWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuSGYuc2hpZnQoKX0sYi5wcm90b3R5cGUuc2xpY2U9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5IZi5zbGljZS5hcHBseSh0aGlzLkhmLGFyZ3VtZW50cyl9LGIucHJvdG90eXBlLnNwbGljZT1mdW5jdGlvbih0LGUpe3JldHVybiB0aGlzLnl2KHQsZSxBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsMikpfSxiLnByb3RvdHlwZS55dj1mdW5jdGlvbih0LGUsaSl7aWYodm9pZCAwPT09dCYmdm9pZCAwPT09ZSlyZXR1cm5bXTt0PXR8fDAsMD50JiYodCs9dGhpcy5sZW5ndGgpLHZvaWQgMD09PWUmJihlPTEvMCk7dmFyIHI9dGhpcy5zbGljZSh0LHQrZSk7cmV0dXJuIHRoaXMuJGcmJnRoaXMubnYoaSxyLHQpLHRoaXMuSGYuc3BsaWNlKHQsZSksdGhpcy5hZGRFYWNoKGkpLHRoaXMuJGcmJnRoaXMuWGcoaSxyLHQpLHJ9LGIucHJvdG90eXBlLnJlZHVjZT1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIHRoaXMuSGYucmVkdWNlKGZ1bmN0aW9uKGUscixuKXtyZXR1cm4gdC5jYWxsKGksZSxyLG4sdGhpcyl9LGUsdGhpcyl9LGIucHJvdG90eXBlLnJlZHVjZVJpZ2h0PWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gdGhpcy5IZi5yZWR1Y2VSaWdodChmdW5jdGlvbih0LGUscil7cmV0dXJuIGNhbGxiYWNrLmNhbGwoaSx0LGUscix0aGlzKX0sYmFzaXMsdGhpcyl9LGIucHJvdG90eXBlLm1pbj1mdW5jdGlvbigpe2lmKHRoaXMubGVuZ3RoKXJldHVybiB0aGlzLkhmWzBdfSxiLnByb3RvdHlwZS5tYXg9ZnVuY3Rpb24oKXtpZih0aGlzLmxlbmd0aClyZXR1cm4gdGhpcy5IZlt0aGlzLmxlbmd0aC0xXX0sYi5wcm90b3R5cGUudWc9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5IZi51ZygpfSxiLnByb3RvdHlwZS5jbGVhcj1mdW5jdGlvbigpe3ZhciB0O3RoaXMuJGcmJih0PXRoaXMuSGYuc2xpY2UoKSx0aGlzLm52KFtdLHQsMCkpLHRoaXMubGVuZ3RoPTAsdGhpcy5IZi5jbGVhcigpLHRoaXMuJGcmJnRoaXMuWGcoW10sdCwwKX0sYi5wcm90b3R5cGUub2w9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdGhpcy5IZi5vbCh0LGUpfSxiLnByb3RvdHlwZS5ZZj1mdW5jdGlvbih0LGUpe3JldHVybiB0aGlzLkhmLllmKHQsZSl9LGIucHJvdG90eXBlLkRmPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIG5ldyB0aGlzLkl0ZXJhdG9yKHRoaXMuSGYsdCxlKX0sYi5wcm90b3R5cGUuSXRlcmF0b3I9QXJyYXkucHJvdG90eXBlLkl0ZXJhdG9yLGRlLmVnJiYoZGU9ZGUuZWcpO3ZhciB2ZT17fTt2ZS5lZz1rO3ZhciB5ZT1kZSxtZT1CLHdlPVg7ay5wcm90b3R5cGU9T2JqZWN0LmNyZWF0ZSh5ZS5wcm90b3R5cGUpLGsucHJvdG90eXBlLmNvbnN0cnVjdG9yPWssT2JqZWN0LmFkZEVhY2goay5wcm90b3R5cGUsbWUucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaChrLnByb3RvdHlwZSx3ZS5wcm90b3R5cGUpLGsucHJvdG90eXBlLmFkZD1mdW5jdGlvbih0KXtyZXR1cm4hdGhpcy5oYXModCkmJih5ZS5wcm90b3R5cGUuYWRkLmNhbGwodGhpcyx0KSwhMCl9LGsucHJvdG90eXBlLnJlZHVjZT1mdW5jdGlvbih0LGUsaSl7dmFyIHI9dGhpcztyZXR1cm4gdGhpcy5IZi5yZWR1Y2UoZnVuY3Rpb24oZSxuLG8pe3JldHVybiB0LmNhbGwoaSxlLG4sbixyLG8pfSxlKX0say5wcm90b3R5cGUucmVkdWNlUmlnaHQ9ZnVuY3Rpb24odCxlLGkpe3ZhciByPXRoaXM7cmV0dXJuIHRoaXMuSGYucmVkdWNlUmlnaHQoZnVuY3Rpb24oZSxuLG8pe3JldHVybiB0LmNhbGwoaSxlLG4sbixyLG8pfSxlKX0sdmUuZWcmJih2ZT12ZS5lZyk7dmFyIFRlPXt9LFNlPXZlLGJlPXgsRWU9RXQsSWU9WDtUZS5lZz1DLE9iamVjdC5hZGRFYWNoKEMucHJvdG90eXBlLGJlLnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2goQy5wcm90b3R5cGUsRWUucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaChDLnByb3RvdHlwZSxJZS5wcm90b3R5cGUpLEMucHJvdG90eXBlLm5nPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0LHRoaXMuTWYsdGhpcy4kZix0aGlzLmNvbnRlbnQpfSxUZS5lZyYmKFRlPVRlLmVnKTt2YXIgUmU9e307UmUuZWc9Tzt2YXIga2U9QixDZT1YLE9lPXJ0LFBlPUg7T2JqZWN0LmFkZEVhY2goTy5wcm90b3R5cGUseC5wcm90b3R5cGUpLE9iamVjdC5hZGRFYWNoKE8ucHJvdG90eXBlLGtlLnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2goTy5wcm90b3R5cGUsQ2UucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaChPLnByb3RvdHlwZSxPZS5wcm90b3R5cGUpLE8ucHJvdG90eXBlLm5nPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0LHRoaXMuTWYsdGhpcy4kZix0aGlzLmNvbnRlbnQpfSxPLnByb3RvdHlwZS5oYXM9ZnVuY3Rpb24odCl7cmV0dXJuISF0aGlzLnJvb3QmJih0aGlzLlpmKHQpLHRoaXMuTWYodCx0aGlzLnJvb3QudmFsdWUpKX0sTy5wcm90b3R5cGUuZ2V0PWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLnJvb3QmJih0aGlzLlpmKHQpLHRoaXMuTWYodCx0aGlzLnJvb3QudmFsdWUpKT90aGlzLnJvb3QudmFsdWU6dGhpcy5jb250ZW50KHQpfSxPLnByb3RvdHlwZS5hZGQ9ZnVuY3Rpb24odCl7dmFyIGU9bmV3IHRoaXMuTm9kZSh0KTtyZXR1cm4gdGhpcy5yb290Pyh0aGlzLlpmKHQpLCF0aGlzLk1mKHQsdGhpcy5yb290LnZhbHVlKSYmKHRoaXMuJGcmJnRoaXMubnYoW3RdLFtdLHRoaXMucm9vdC5pbmRleCksMD50aGlzLiRmKHQsdGhpcy5yb290LnZhbHVlKT8oZS5yaWdodD10aGlzLnJvb3QsZS5sZWZ0PXRoaXMucm9vdC5sZWZ0LHRoaXMucm9vdC5sZWZ0PW51bGwpOihlLmxlZnQ9dGhpcy5yb290LGUucmlnaHQ9dGhpcy5yb290LnJpZ2h0LHRoaXMucm9vdC5yaWdodD1udWxsKSx0aGlzLnJvb3QuRnYoKSxlLkZ2KCksdGhpcy5yb290PWUsdGhpcy5sZW5ndGgrKyx0aGlzLiRnJiZ0aGlzLlhnKFt0XSxbXSx0aGlzLnJvb3QuaW5kZXgpLCEwKSk6KHRoaXMuJGcmJnRoaXMubnYoW3RdLFtdLDApLHRoaXMucm9vdD1lLHRoaXMubGVuZ3RoKyssdGhpcy4kZyYmdGhpcy5YZyhbdF0sW10sMCksITApfSxPLnByb3RvdHlwZVtcImRlbGV0ZVwiXT1mdW5jdGlvbih0KXtpZih0aGlzLnJvb3QmJih0aGlzLlpmKHQpLHRoaXMuTWYodCx0aGlzLnJvb3QudmFsdWUpKSl7dmFyIGU9dGhpcy5yb290LmluZGV4O2lmKHRoaXMuJGcmJnRoaXMubnYoW10sW3RdLGUpLHRoaXMucm9vdC5sZWZ0KXt2YXIgaT10aGlzLnJvb3QucmlnaHQ7dGhpcy5yb290PXRoaXMucm9vdC5sZWZ0LHRoaXMuWmYodCksdGhpcy5yb290LnJpZ2h0PWl9ZWxzZSB0aGlzLnJvb3Q9dGhpcy5yb290LnJpZ2h0O3JldHVybiB0aGlzLmxlbmd0aC0tLHRoaXMucm9vdCYmdGhpcy5yb290LkZ2KCksdGhpcy4kZyYmdGhpcy5YZyhbXSxbdF0sZSksITB9cmV0dXJuITF9LE8ucHJvdG90eXBlLmluZGV4T2Y9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMucm9vdCYmKHRoaXMuWmYodCksdGhpcy5NZih0LHRoaXMucm9vdC52YWx1ZSkpP3RoaXMucm9vdC5pbmRleDotMX0sTy5wcm90b3R5cGUuZmluZD1mdW5jdGlvbih0KXtpZih0aGlzLnJvb3QmJih0aGlzLlpmKHQpLHRoaXMuTWYodCx0aGlzLnJvb3QudmFsdWUpKSlyZXR1cm4gdGhpcy5yb290fSxPLnByb3RvdHlwZS5fdj1mdW5jdGlvbih0KXtpZih0aGlzLnJvb3Qpe2Zvcih0PXR8fHRoaXMucm9vdDt0LnJpZ2h0Oyl0PXQucmlnaHQ7cmV0dXJuIHR9fSxPLnByb3RvdHlwZS5Edj1mdW5jdGlvbih0KXtpZih0aGlzLnJvb3Qpe2Zvcih0PXR8fHRoaXMucm9vdDt0LmxlZnQ7KXQ9dC5sZWZ0O3JldHVybiB0fX0sTy5wcm90b3R5cGUuSHY9ZnVuY3Rpb24odCl7aWYodGhpcy5yb290KXJldHVybiB0aGlzLlpmKHQpLHRoaXMucm9vdH0sTy5wcm90b3R5cGUuTHY9ZnVuY3Rpb24odCl7aWYodGhpcy5yb290KXJldHVybiB0aGlzLlpmKHQpLHRoaXMucm9vdC50ZygpfSxPLnByb3RvdHlwZS5YZj1mdW5jdGlvbih0KXtpZih0aGlzLnJvb3QpcmV0dXJuIHRoaXMuWmYodCksMD09PXRoaXMuJGYodCx0aGlzLnJvb3QudmFsdWUpP3RoaXMucm9vdDp0aGlzLnJvb3QuTXYoKX0sTy5wcm90b3R5cGUuanY9ZnVuY3Rpb24odCl7aWYodGhpcy5yb290KXJldHVybiB0aGlzLlpmKHQpLHRoaXMuJGYodCx0aGlzLnJvb3QudmFsdWUpLHRoaXMucm9vdC5NdigpfSxPLnByb3RvdHlwZS5wb3A9ZnVuY3Rpb24oKXtpZih0aGlzLnJvb3Qpe3ZhciB0PXRoaXMuX3YoKTtyZXR1cm4gdGhpc1tcImRlbGV0ZVwiXSh0LnZhbHVlKSx0LnZhbHVlfX0sTy5wcm90b3R5cGUuc2hpZnQ9ZnVuY3Rpb24oKXtpZih0aGlzLnJvb3Qpe3ZhciB0PXRoaXMuRHYoKTtyZXR1cm4gdGhpc1tcImRlbGV0ZVwiXSh0LnZhbHVlKSx0LnZhbHVlfX0sTy5wcm90b3R5cGUucHVzaD1mdW5jdGlvbigpe3RoaXMuYWRkRWFjaChhcmd1bWVudHMpfSxPLnByb3RvdHlwZS51bnNoaWZ0PWZ1bmN0aW9uKCl7dGhpcy5hZGRFYWNoKGFyZ3VtZW50cyl9LE8ucHJvdG90eXBlLnNsaWNlPWZ1bmN0aW9uKHQsZSl7dD10fHwwLGU9ZXx8dGhpcy5sZW5ndGgsMD50JiYodCs9dGhpcy5sZW5ndGgpLDA+ZSYmKGUrPXRoaXMubGVuZ3RoKTt2YXIgaT1bXTtpZih0aGlzLnJvb3QpZm9yKHRoaXMuVXYodCk7dGhpcy5yb290LmluZGV4PGUmJihpLnB1c2godGhpcy5yb290LnZhbHVlKSx0aGlzLnJvb3QucmlnaHQpOyl0aGlzLlpmKHRoaXMucm9vdC5NdigpLnZhbHVlKTtyZXR1cm4gaX0sTy5wcm90b3R5cGUuc3BsaWNlPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHRoaXMueXYodCxlLEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywyKSl9LE8ucHJvdG90eXBlLnl2PWZ1bmN0aW9uKHQsZSxpKXtpZih2b2lkIDA9PT10JiZ2b2lkIDA9PT1lKXJldHVybltdO3Q9dHx8MCwwPnQmJih0Kz10aGlzLmxlbmd0aCksdm9pZCAwPT09ZSYmKGU9MS8wKTt2YXIgcj1bXTtpZih0aGlzLnJvb3QpZm9yKHRoaXMuVXYodCksdD0wO3Q8ZTt0Kyspe3IucHVzaCh0aGlzLnJvb3QudmFsdWUpO3ZhciBuPXRoaXMucm9vdC5NdigpO2lmKHRoaXNbXCJkZWxldGVcIl0odGhpcy5yb290LnZhbHVlKSwhbilicmVhazt0aGlzLlpmKG4udmFsdWUpfXJldHVybiB0aGlzLmFkZEVhY2goaSkscn0sTy5wcm90b3R5cGUuWmY9ZnVuY3Rpb24odCl7dmFyIGUsaSxyLG4sbyxzO2lmKHRoaXMucm9vdCl7Zm9yKGU9aT1yPW5ldyB0aGlzLk5vZGUscz1uZXcgdGhpcy5Ob2RlLG89dGhpcy5yb290OzspaWYobj10aGlzLiRmKHQsby52YWx1ZSksMD5uKXtpZighby5sZWZ0KWJyZWFrO2lmKDA+dGhpcy4kZih0LG8ubGVmdC52YWx1ZSkmJihuPW8ubGVmdCxvLmxlZnQ9bi5yaWdodCxvLkZ2KCksbi5yaWdodD1vLG4uRnYoKSxvPW4sIW8ubGVmdCkpYnJlYWs7bj1uZXcgUCxuLnJpZ2h0PW8sbi5sZWZ0PXMubGVmdCxzLmxlZnQ9bixyLmxlZnQ9byxyLkZ2KCkscj1vLG89by5sZWZ0fWVsc2V7aWYoISgwPG4pKWJyZWFrO2lmKCFvLnJpZ2h0KWJyZWFrO2lmKDA8dGhpcy4kZih0LG8ucmlnaHQudmFsdWUpJiYobj1vLnJpZ2h0LG8ucmlnaHQ9bi5sZWZ0LG8uRnYoKSxuLmxlZnQ9byxuLkZ2KCksbz1uLCFvLnJpZ2h0KSlicmVhaztuPW5ldyBQLG4ubGVmdD1vLG4ucmlnaHQ9cy5yaWdodCxzLnJpZ2h0PW4saS5yaWdodD1vLGkuRnYoKSxpPW8sbz1vLnJpZ2h0fWZvcihpLnJpZ2h0PW8ubGVmdCxpLkZ2KCksci5sZWZ0PW8ucmlnaHQsci5GdigpLG8ubGVmdD1lLnJpZ2h0LG8ucmlnaHQ9ZS5sZWZ0O3MubGVmdDspcy5sZWZ0LnJpZ2h0LkZ2KCkscy5sZWZ0PXMubGVmdC5sZWZ0O2Zvcig7cy5yaWdodDspcy5yaWdodC5sZWZ0LkZ2KCkscy5yaWdodD1zLnJpZ2h0LnJpZ2h0O28uRnYoKSx0aGlzLnJvb3Q9b319LE8ucHJvdG90eXBlLlV2PWZ1bmN0aW9uKHQpe2lmKHRoaXMucm9vdCl7Zm9yKHZhciBlPXRoaXMucm9vdCxpPXRoaXMucm9vdC5pbmRleDtpIT09dDspaWYoaT50JiZlLmxlZnQpZT1lLmxlZnQsaS09MSsoZS5yaWdodD9lLnJpZ2h0Lmxlbmd0aDowKTtlbHNle2lmKCEoaTx0JiZlLnJpZ2h0KSlicmVhaztlPWUucmlnaHQsaSs9MSsoZS5sZWZ0P2UubGVmdC5sZW5ndGg6MCl9cmV0dXJuIHRoaXMuWmYoZS52YWx1ZSksdGhpcy5yb290LmluZGV4PT09dH1yZXR1cm4hMX0sTy5wcm90b3R5cGUucmVkdWNlPWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gdGhpcy5yb290JiYoZT10aGlzLnJvb3QucmVkdWNlKHQsZSxpLHRoaXMpKSxlfSxPLnByb3RvdHlwZS5yZWR1Y2VSaWdodD1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIHRoaXMucm9vdCYmKGU9dGhpcy5yb290LnJlZHVjZVJpZ2h0KHQsZSxpLHRoaXMpKSxlfSxPLnByb3RvdHlwZS5taW49ZnVuY3Rpb24odCl7aWYodD10aGlzLkR2KHQpKXJldHVybiB0LnZhbHVlfSxPLnByb3RvdHlwZS5tYXg9ZnVuY3Rpb24odCl7aWYodD10aGlzLl92KHQpKXJldHVybiB0LnZhbHVlfSxPLnByb3RvdHlwZS51Zz1mdW5jdGlvbigpe2lmKCF0aGlzLnJvb3QpdGhyb3cgRXJyb3IoXCJDYW4ndCBnZXQgb25lIHZhbHVlIGZyb20gZW1wdHkgc2V0XCIpO3JldHVybiB0aGlzLnJvb3QudmFsdWV9LE8ucHJvdG90eXBlLmNsZWFyPWZ1bmN0aW9uKCl7dmFyIHQ7dGhpcy4kZyYmKHQ9dGhpcy50b0FycmF5KCksdGhpcy5udihbXSx0LDApKSx0aGlzLnJvb3Q9bnVsbCx0aGlzLmxlbmd0aD0wLHRoaXMuJGcmJnRoaXMuWGcoW10sdCwwKX0sTy5wcm90b3R5cGUuRGY9ZnVuY3Rpb24odCxlKXtyZXR1cm4gbmV3IHRoaXMuSXRlcmF0b3IodGhpcyx0LGUpfSxPLnByb3RvdHlwZS5JdGVyYXRvcj1BLE8ucHJvdG90eXBlLnN1bW1hcnk9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5yb290P3RoaXMucm9vdC5zdW1tYXJ5KCk6XCIoKVwifSxPLnByb3RvdHlwZS5sb2c9ZnVuY3Rpb24odCxlLGkscil7dD10fHxQZS5SZyxlPWV8fHRoaXMuQnYsaXx8KGk9Y29uc29sZS5sb2cscj1jb25zb2xlKSxpPWkuYmluZChyKSx0aGlzLnJvb3QmJnRoaXMucm9vdC5sb2codCxlLGksaSl9LE8ucHJvdG90eXBlLkJ2PWZ1bmN0aW9uKHQsZSl7ZShcIiBcIit0LnZhbHVlKX0sTy5Wdj1QZSxPLnByb3RvdHlwZS5Ob2RlPVAsUC5wcm90b3R5cGUucmVkdWNlPWZ1bmN0aW9uKHQsZSxpLHIsbil7cmV0dXJuIG49bnx8MCx0aGlzLmxlZnQmJihlPXRoaXMubGVmdC5yZWR1Y2UodCxlLGkscixuKzEpKSxlPXQuY2FsbChpLGUsdGhpcy52YWx1ZSx0aGlzLnZhbHVlLHIsdGhpcyxuKSx0aGlzLnJpZ2h0JiYoZT10aGlzLnJpZ2h0LnJlZHVjZSh0LGUsaSxyLG4rMSkpLGV9LFAucHJvdG90eXBlLnJlZHVjZVJpZ2h0PWZ1bmN0aW9uKHQsZSxpLHIsbil7cmV0dXJuIG49bnx8MCx0aGlzLnJpZ2h0JiYoZT10aGlzLnJpZ2h0LnJlZHVjZSh0LGUsaSxyLG4rMSkpLGU9dC5jYWxsKGksZSx0aGlzLnZhbHVlLHRoaXMudmFsdWUscix0aGlzLG4pLHRoaXMubGVmdCYmKGU9dGhpcy5sZWZ0LnJlZHVjZSh0LGUsaSxyLG4rMSkpLGV9LFAucHJvdG90eXBlLkZ2PWZ1bmN0aW9uKCl7dGhpcy5sZW5ndGg9MSsodGhpcy5sZWZ0P3RoaXMubGVmdC5sZW5ndGg6MCkrKHRoaXMucmlnaHQ/dGhpcy5yaWdodC5sZW5ndGg6MCksdGhpcy5pbmRleD10aGlzLmxlZnQ/dGhpcy5sZWZ0Lmxlbmd0aDowfSxQLnByb3RvdHlwZS5Rdj1mdW5jdGlvbigpe3ZhciB0O2lmKHQ9MSsodGhpcy5sZWZ0P3RoaXMubGVmdC5RdigpOjApLHQrPXRoaXMucmlnaHQ/dGhpcy5yaWdodC5RdigpOjAsdGhpcy5sZW5ndGghPT10KXRocm93IEVycm9yKFwiSW50ZWdyaXR5IGNoZWNrIGZhaWxlZDogXCIrdGhpcy5zdW1tYXJ5KCkpO3JldHVybiB0fSxQLnByb3RvdHlwZS5Ndj1mdW5jdGlvbigpe3ZhciB0PXRoaXM7aWYodC5yaWdodCl7Zm9yKHQ9dC5yaWdodDt0LmxlZnQ7KXQ9dC5sZWZ0O3JldHVybiB0fX0sUC5wcm90b3R5cGUudGc9ZnVuY3Rpb24oKXt2YXIgdD10aGlzO2lmKHQubGVmdCl7Zm9yKHQ9dC5sZWZ0O3QucmlnaHQ7KXQ9dC5yaWdodDtyZXR1cm4gdH19LFAucHJvdG90eXBlLnN1bW1hcnk9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLnZhbHVlfHxcIi1cIix0PXQrKFwiIDxcIit0aGlzLmxlbmd0aCk7cmV0dXJuIHRoaXMubGVmdHx8dGhpcy5yaWdodD9cIihcIit0K1wiIFwiKyh0aGlzLmxlZnQ/dGhpcy5sZWZ0LnN1bW1hcnkoKTpcIigpXCIpK1wiLCBcIisodGhpcy5yaWdodD90aGlzLnJpZ2h0LnN1bW1hcnkoKTpcIigpXCIpK1wiKVwiOlwiKFwiK3QrXCIpXCJ9LFAucHJvdG90eXBlLmxvZz1mdW5jdGlvbih0LGUsaSxyKXt2YXIgbixvPXRoaXM7bj10aGlzLmxlZnQmJnRoaXMucmlnaHQ/dC5kZzp0aGlzLmxlZnQ/dC53Zzp0aGlzLnJpZ2h0P3QuVGc6dC5tZzt2YXIgczt0aGlzLmxlZnQmJnRoaXMubGVmdC5sb2codCxlLGZ1bmN0aW9uKGUpe3M/cih0LklnK1wiIFwiK2UpOihzPSEwLHIodC5TZyt0Lm1nK2UpKX0sZnVuY3Rpb24odCl7cihcIiAgXCIrdCl9KTt2YXIgYTtlKHRoaXMsZnVuY3Rpb24oZSl7YT9pKChvLnJpZ2h0P3QuSWc6XCIgXCIpK2UpOihhPSEwLGkobitlKSl9LGZ1bmN0aW9uKGUpe3IoKG8ubGVmdD90LklnOlwiIFwiKStlKX0pO3ZhciBjO3RoaXMucmlnaHQmJnRoaXMucmlnaHQubG9nKHQsZSxmdW5jdGlvbihlKXtjP2koXCIgIFwiK2UpOihjPSEwLGkodC5iZyt0Lm1nK2UpKX0sZnVuY3Rpb24oZSl7aSh0LklnK1wiIFwiK2UpfSl9LEEucHJvdG90eXBlLm5leHQ9ZnVuY3Rpb24oKXt2YXIgdDtpZih0PXRoaXMuTGY/dGhpcy5zZXQuanYodGhpcy5MZi52YWx1ZSk6dGhpcy5zZXQuRHYoKSwhdCl0aHJvdyBTdG9wSXRlcmF0aW9uO2lmKHZvaWQgMCE9PXRoaXMuZW5kJiYwPD10aGlzLnNldC4kZih0LnZhbHVlLHRoaXMuZW5kKSl0aHJvdyBTdG9wSXRlcmF0aW9uO3JldHVybiB0aGlzLkxmPXQsdC52YWx1ZX0sUmUuZWcmJihSZT1SZS5lZyk7dmFyIEFlPXt9LE5lPVJlLHhlPXgsQmU9RXQsRmU9WDtBZS5lZz1OLE9iamVjdC5hZGRFYWNoKE4ucHJvdG90eXBlLHhlLnByb3RvdHlwZSksT2JqZWN0LmFkZEVhY2goTi5wcm90b3R5cGUsQmUucHJvdG90eXBlKSxPYmplY3QuYWRkRWFjaChOLnByb3RvdHlwZSxGZS5wcm90b3R5cGUpLE4ucHJvdG90eXBlLm5nPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgdGhpcy5jb25zdHJ1Y3Rvcih0LHRoaXMuTWYsdGhpcy4kZix0aGlzLmNvbnRlbnQpfSxOLnByb3RvdHlwZS5sb2c9ZnVuY3Rpb24odCxlKXtlPWV8fHRoaXMuc3RyaW5naWZ5LHRoaXMuVmYubG9nKHQsZSl9LE4ucHJvdG90eXBlLnF2PWZ1bmN0aW9uKHQsZSxpLHIpe3I9cnx8dGhpcy5zdHJpbmdpZnksdGhpcy5WZi5xdih0LGUsaSxyKX0sTi5wcm90b3R5cGUuc3RyaW5naWZ5PWZ1bmN0aW9uKHQsZSxpLHIpe3QuY2FsbChlLHIrXCIgXCIraS52YWx1ZS5rZXkrXCI6IFwiK2kudmFsdWUudmFsdWUpfSxBZS5lZyYmKEFlPUFlLmVnKSx0Lkp2PW10LHQuU2V0PVF0LHQuTWFwPXNlLHQuS3Y9dWUsdC5XZWFrTWFwPU0sdC5Hdj1SZSx0Lm5pPUFlLHQuenY9JHQsdC5Xdj1lZSx0LiR2PWRlLHQub2k9dmUsdC5Zdj1UZSx0Llh2PU50LHQuWnY9THQsdC50eT1DdCx0Lkl0ZXJhdG9yPXV0fSh0aGlzKX0sZnVuY3Rpb24odCxlKXt0LnQ9ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEZ1bmN0aW9ufX0sZnVuY3Rpb24odCxlKXtmdW5jdGlvbiBpKHQsZSxpKXtudWxsIT10JiYoXCJudW1iZXJcIj09dHlwZW9mIHQ/dGhpcy5mcm9tTnVtYmVyKHQsZSxpKTpudWxsPT1lJiZcInN0cmluZ1wiIT10eXBlb2YgdD90aGlzLmV5KHQsMjU2KTp0aGlzLmV5KHQsZSkpfWZ1bmN0aW9uIHIoKXtyZXR1cm4gbmV3IGkobnVsbCl9ZnVuY3Rpb24gbih0LGUsaSxyLG4sbyl7Zm9yKDstLW8+PTA7KXt2YXIgcz1lKnRoaXNbdCsrXStpW3JdK247bj1NYXRoLmZsb29yKHMvNjcxMDg4NjQpLGlbcisrXT02NzEwODg2MyZzfXJldHVybiBufWZ1bmN0aW9uIG8odCxlLGkscixuLG8pe2Zvcih2YXIgcz0zMjc2NyZlLGE9ZT4+MTU7LS1vPj0wOyl7dmFyIGM9MzI3NjcmdGhpc1t0XSxoPXRoaXNbdCsrXT4+MTUscD1hKmMraCpzO2M9cypjKygoMzI3NjcmcCk8PDE1KStpW3JdKygxMDczNzQxODIzJm4pLG49KGM+Pj4zMCkrKHA+Pj4xNSkrYSpoKyhuPj4+MzApLGlbcisrXT0xMDczNzQxODIzJmN9cmV0dXJuIG59ZnVuY3Rpb24gcyh0LGUsaSxyLG4sbyl7Zm9yKHZhciBzPTE2MzgzJmUsYT1lPj4xNDstLW8+PTA7KXt2YXIgYz0xNjM4MyZ0aGlzW3RdLGg9dGhpc1t0KytdPj4xNCxwPWEqYytoKnM7Yz1zKmMrKCgxNjM4MyZwKTw8MTQpK2lbcl0rbixuPShjPj4yOCkrKHA+PjE0KSthKmgsaVtyKytdPTI2ODQzNTQ1NSZjfXJldHVybiBufWZ1bmN0aW9uIGEodCl7cmV0dXJuIFB0LmNoYXJBdCh0KX1mdW5jdGlvbiBjKHQsZSl7dmFyIGk9QXRbdC5jaGFyQ29kZUF0KGUpXTtyZXR1cm4gbnVsbD09aT8tMTppfWZ1bmN0aW9uIGgodCl7Zm9yKHZhciBlPXRoaXMuaXktMTtlPj0wOy0tZSl0W2VdPXRoaXNbZV07dC5peT10aGlzLml5LHQubnk9dGhpcy5ueX1mdW5jdGlvbiBwKHQpe3RoaXMuaXk9MSx0aGlzLm55PXQ8MD8tMTowLHQ+MD90aGlzWzBdPXQ6dDwtMT90aGlzWzBdPXQrdGhpcy5veTp0aGlzLml5PTB9ZnVuY3Rpb24gdSh0KXt2YXIgZT1yKCk7cmV0dXJuIGUuc3kodCksZX1mdW5jdGlvbiBsKHQsZSl7dmFyIHI7aWYoMTY9PWUpcj00O2Vsc2UgaWYoOD09ZSlyPTM7ZWxzZSBpZigyNTY9PWUpcj04O2Vsc2UgaWYoMj09ZSlyPTE7ZWxzZSBpZigzMj09ZSlyPTU7ZWxzZXtpZig0IT1lKXJldHVybiB2b2lkIHRoaXMuZnJvbVJhZGl4KHQsZSk7cj0yfXRoaXMuaXk9MCx0aGlzLm55PTA7Zm9yKHZhciBuPXQubGVuZ3RoLG89ITEscz0wOy0tbj49MDspe3ZhciBhPTg9PXI/MjU1JnRbbl06Yyh0LG4pO2E8MD9cIi1cIj09dC5jaGFyQXQobikmJihvPSEwKToobz0hMSwwPT1zP3RoaXNbdGhpcy5peSsrXT1hOnMrcj50aGlzLmF5Pyh0aGlzW3RoaXMuaXktMV18PShhJigxPDx0aGlzLmF5LXMpLTEpPDxzLHRoaXNbdGhpcy5peSsrXT1hPj50aGlzLmF5LXMpOnRoaXNbdGhpcy5peS0xXXw9YTw8cyxzKz1yLHM+PXRoaXMuYXkmJihzLT10aGlzLmF5KSl9OD09ciYmMCE9KDEyOCZ0WzBdKSYmKHRoaXMubnk9LTEscz4wJiYodGhpc1t0aGlzLml5LTFdfD0oMTw8dGhpcy5heS1zKS0xPDxzKSksdGhpcy5oeSgpLG8mJmkuWkVSTy5weSh0aGlzLHRoaXMpfWZ1bmN0aW9uIGQoKXtmb3IodmFyIHQ9dGhpcy5ueSZ0aGlzLnV5O3RoaXMuaXk+MCYmdGhpc1t0aGlzLml5LTFdPT10OyktLXRoaXMuaXl9ZnVuY3Rpb24gZih0KXtpZih0aGlzLm55PDApcmV0dXJuXCItXCIrdGhpcy5seSgpLnRvU3RyaW5nKHQpO3ZhciBlO2lmKDE2PT10KWU9NDtlbHNlIGlmKDg9PXQpZT0zO2Vsc2UgaWYoMj09dCllPTE7ZWxzZSBpZigzMj09dCllPTU7ZWxzZXtpZig0IT10KXJldHVybiB0aGlzLnRvUmFkaXgodCk7ZT0yfXZhciBpLHI9KDE8PGUpLTEsbj0hMSxvPVwiXCIscz10aGlzLml5LGM9dGhpcy5heS1zKnRoaXMuYXklZTtpZihzLS0gPjApZm9yKGM8dGhpcy5heSYmKGk9dGhpc1tzXT4+Yyk+MCYmKG49ITAsbz1hKGkpKTtzPj0wOyljPGU/KGk9KHRoaXNbc10mKDE8PGMpLTEpPDxlLWMsaXw9dGhpc1stLXNdPj4oYys9dGhpcy5heS1lKSk6KGk9dGhpc1tzXT4+KGMtPWUpJnIsYzw9MCYmKGMrPXRoaXMuYXksLS1zKSksaT4wJiYobj0hMCksbiYmKG8rPWEoaSkpO3JldHVybiBuP286XCIwXCJ9ZnVuY3Rpb24gZygpe3ZhciB0PXIoKTtyZXR1cm4gaS5aRVJPLnB5KHRoaXMsdCksdH1mdW5jdGlvbiB2KCl7cmV0dXJuIHRoaXMubnk8MD90aGlzLmx5KCk6dGhpc31mdW5jdGlvbiB5KHQpe3ZhciBlPXRoaXMubnktdC5ueTtpZigwIT1lKXJldHVybiBlO3ZhciBpPXRoaXMuaXk7aWYoZT1pLXQuaXksMCE9ZSlyZXR1cm4gdGhpcy5ueTwwPy1lOmU7Zm9yKDstLWk+PTA7KWlmKDAhPShlPXRoaXNbaV0tdFtpXSkpcmV0dXJuIGU7cmV0dXJuIDB9ZnVuY3Rpb24gbSh0KXt2YXIgZSxpPTE7cmV0dXJuIDAhPShlPXQ+Pj4xNikmJih0PWUsaSs9MTYpLDAhPShlPXQ+PjgpJiYodD1lLGkrPTgpLDAhPShlPXQ+PjQpJiYodD1lLGkrPTQpLDAhPShlPXQ+PjIpJiYodD1lLGkrPTIpLDAhPShlPXQ+PjEpJiYodD1lLGkrPTEpLGl9ZnVuY3Rpb24gdygpe3JldHVybiB0aGlzLml5PD0wPzA6dGhpcy5heSoodGhpcy5peS0xKSttKHRoaXNbdGhpcy5peS0xXV50aGlzLm55JnRoaXMudXkpfWZ1bmN0aW9uIFQodCxlKXt2YXIgaTtmb3IoaT10aGlzLml5LTE7aT49MDstLWkpZVtpK3RdPXRoaXNbaV07Zm9yKGk9dC0xO2k+PTA7LS1pKWVbaV09MDtlLml5PXRoaXMuaXkrdCxlLm55PXRoaXMubnl9ZnVuY3Rpb24gUyh0LGUpe2Zvcih2YXIgaT10O2k8dGhpcy5peTsrK2kpZVtpLXRdPXRoaXNbaV07ZS5peT1NYXRoLm1heCh0aGlzLml5LXQsMCksZS5ueT10aGlzLm55fWZ1bmN0aW9uIGIodCxlKXt2YXIgaSxyPXQldGhpcy5heSxuPXRoaXMuYXktcixvPSgxPDxuKS0xLHM9TWF0aC5mbG9vcih0L3RoaXMuYXkpLGE9dGhpcy5ueTw8ciZ0aGlzLnV5O2ZvcihpPXRoaXMuaXktMTtpPj0wOy0taSllW2krcysxXT10aGlzW2ldPj5ufGEsYT0odGhpc1tpXSZvKTw8cjtmb3IoaT1zLTE7aT49MDstLWkpZVtpXT0wO2Vbc109YSxlLml5PXRoaXMuaXkrcysxLGUubnk9dGhpcy5ueSxlLmh5KCl9ZnVuY3Rpb24gRSh0LGUpe2Uubnk9dGhpcy5ueTt2YXIgaT1NYXRoLmZsb29yKHQvdGhpcy5heSk7aWYoaT49dGhpcy5peSlyZXR1cm4gdm9pZChlLml5PTApO3ZhciByPXQldGhpcy5heSxuPXRoaXMuYXktcixvPSgxPDxyKS0xO2VbMF09dGhpc1tpXT4+cjtmb3IodmFyIHM9aSsxO3M8dGhpcy5peTsrK3MpZVtzLWktMV18PSh0aGlzW3NdJm8pPDxuLGVbcy1pXT10aGlzW3NdPj5yO3I+MCYmKGVbdGhpcy5peS1pLTFdfD0odGhpcy5ueSZvKTw8biksZS5peT10aGlzLml5LWksZS5oeSgpfWZ1bmN0aW9uIEkodCxlKXtmb3IodmFyIGk9MCxyPTAsbj1NYXRoLm1pbih0Lml5LHRoaXMuaXkpO2k8bjspcis9dGhpc1tpXS10W2ldLGVbaSsrXT1yJnRoaXMudXkscj4+PXRoaXMuYXk7aWYodC5peTx0aGlzLml5KXtmb3Ioci09dC5ueTtpPHRoaXMuaXk7KXIrPXRoaXNbaV0sZVtpKytdPXImdGhpcy51eSxyPj49dGhpcy5heTtyKz10aGlzLm55fWVsc2V7Zm9yKHIrPXRoaXMubnk7aTx0Lml5OylyLT10W2ldLGVbaSsrXT1yJnRoaXMudXkscj4+PXRoaXMuYXk7ci09dC5ueX1lLm55PXI8MD8tMTowLHI8LTE/ZVtpKytdPXRoaXMub3krcjpyPjAmJihlW2krK109ciksZS5peT1pLGUuaHkoKX1mdW5jdGlvbiBSKHQsZSl7dmFyIHI9dGhpcy5hYnMoKSxuPXQuYWJzKCksbz1yLml5O2ZvcihlLml5PW8rbi5peTstLW8+PTA7KWVbb109MDtmb3Iobz0wO288bi5peTsrK28pZVtvK3IuaXldPXIuZ3koMCxuW29dLGUsbywwLHIuaXkpO2Uubnk9MCxlLmh5KCksdGhpcy5ueSE9dC5ueSYmaS5aRVJPLnB5KGUsZSl9ZnVuY3Rpb24gayh0KXtmb3IodmFyIGU9dGhpcy5hYnMoKSxpPXQuaXk9MiplLml5Oy0taT49MDspdFtpXT0wO2ZvcihpPTA7aTxlLml5LTE7KytpKXt2YXIgcj1lLmd5KGksZVtpXSx0LDIqaSwwLDEpOyh0W2krZS5peV0rPWUuZ3koaSsxLDIqZVtpXSx0LDIqaSsxLHIsZS5peS1pLTEpKT49ZS5veSYmKHRbaStlLml5XS09ZS5veSx0W2krZS5peSsxXT0xKX10Lml5PjAmJih0W3QuaXktMV0rPWUuZ3koaSxlW2ldLHQsMippLDAsMSkpLHQubnk9MCx0Lmh5KCl9ZnVuY3Rpb24gQyh0LGUsbil7dmFyIG89dC5hYnMoKTtpZighKG8uaXk8PTApKXt2YXIgcz10aGlzLmFicygpO2lmKHMuaXk8by5peSlyZXR1cm4gbnVsbCE9ZSYmZS5zeSgwKSx2b2lkKG51bGwhPW4mJnRoaXMudnkobikpO251bGw9PW4mJihuPXIoKSk7dmFyIGE9cigpLGM9dGhpcy5ueSxoPXQubnkscD10aGlzLmF5LW0ob1tvLml5LTFdKTtwPjA/KG8ueXkocCxhKSxzLnl5KHAsbikpOihvLnZ5KGEpLHMudnkobikpO3ZhciB1PWEuaXksbD1hW3UtMV07aWYoMCE9bCl7dmFyIGQ9bCooMTw8dGhpcy5teSkrKHU+MT9hW3UtMl0+PnRoaXMud3k6MCksZj10aGlzLlR5L2QsZz0oMTw8dGhpcy5teSkvZCx2PTE8PHRoaXMud3kseT1uLml5LHc9eS11LFQ9bnVsbD09ZT9yKCk6ZTtmb3IoYS5TeSh3LFQpLG4uYnkoVCk+PTAmJihuW24uaXkrK109MSxuLnB5KFQsbikpLGkuT05FLlN5KHUsVCksVC5weShhLGEpO2EuaXk8dTspYVthLml5KytdPTA7Zm9yKDstLXc+PTA7KXt2YXIgUz1uWy0teV09PWw/dGhpcy51eTpNYXRoLmZsb29yKG5beV0qZisoblt5LTFdK3YpKmcpO2lmKChuW3ldKz1hLmd5KDAsUyxuLHcsMCx1KSk8Uylmb3IoYS5TeSh3LFQpLG4ucHkoVCxuKTtuW3ldPC0tUzspbi5weShULG4pfW51bGwhPWUmJihuLkV5KHUsZSksYyE9aCYmaS5aRVJPLnB5KGUsZSkpLG4uaXk9dSxuLmh5KCkscD4wJiZuLkl5KHAsbiksYzwwJiZpLlpFUk8ucHkobixuKX19fWZ1bmN0aW9uIE8odCl7dmFyIGU9cigpO3JldHVybiB0aGlzLmFicygpLlJ5KHQsbnVsbCxlKSx0aGlzLm55PDAmJmUuYnkoaS5aRVJPKT4wJiZ0LnB5KGUsZSksZX1mdW5jdGlvbiBQKHQpe3RoaXMuaT10fWZ1bmN0aW9uIEEodCl7cmV0dXJuIHQubnk8MHx8dC5ieSh0aGlzLmkpPj0wP3Qua3kodGhpcy5pKTp0fWZ1bmN0aW9uIE4odCl7cmV0dXJuIHR9ZnVuY3Rpb24geCh0KXt0LlJ5KHRoaXMuaSxudWxsLHQpfWZ1bmN0aW9uIEIodCxlLGkpe3QuQ3koZSxpKSx0aGlzLnJlZHVjZShpKX1mdW5jdGlvbiBGKHQsZSl7dC5PeShlKSx0aGlzLnJlZHVjZShlKX1mdW5jdGlvbiBfKCl7aWYodGhpcy5peTwxKXJldHVybiAwO3ZhciB0PXRoaXNbMF07aWYoMD09KDEmdCkpcmV0dXJuIDA7dmFyIGU9MyZ0O3JldHVybiBlPWUqKDItKDE1JnQpKmUpJjE1LGU9ZSooMi0oMjU1JnQpKmUpJjI1NSxlPWUqKDItKCg2NTUzNSZ0KSplJjY1NTM1KSkmNjU1MzUsZT1lKigyLXQqZSV0aGlzLm95KSV0aGlzLm95LGU+MD90aGlzLm95LWU6LWV9ZnVuY3Rpb24gRCh0KXt0aGlzLmk9dCx0aGlzLlB5PXQuQXkoKSx0aGlzLk55PTMyNzY3JnRoaXMuUHksdGhpcy54eT10aGlzLlB5Pj4xNSx0aGlzLkJ5PSgxPDx0LmF5LTE1KS0xLHRoaXMuRnk9Mip0Lml5fWZ1bmN0aW9uIEgodCl7dmFyIGU9cigpO3JldHVybiB0LmFicygpLlN5KHRoaXMuaS5peSxlKSxlLlJ5KHRoaXMuaSxudWxsLGUpLHQubnk8MCYmZS5ieShpLlpFUk8pPjAmJnRoaXMuaS5weShlLGUpLGV9ZnVuY3Rpb24gTCh0KXt2YXIgZT1yKCk7cmV0dXJuIHQudnkoZSksdGhpcy5yZWR1Y2UoZSksZX1mdW5jdGlvbiBNKHQpe2Zvcig7dC5peTw9dGhpcy5GeTspdFt0Lml5KytdPTA7Zm9yKHZhciBlPTA7ZTx0aGlzLmkuaXk7KytlKXt2YXIgaT0zMjc2NyZ0W2VdLHI9aSp0aGlzLk55KygoaSp0aGlzLnh5Kyh0W2VdPj4xNSkqdGhpcy5OeSZ0aGlzLkJ5KTw8MTUpJnQudXk7Zm9yKGk9ZSt0aGlzLmkuaXksdFtpXSs9dGhpcy5pLmd5KDAscix0LGUsMCx0aGlzLmkuaXkpO3RbaV0+PXQub3k7KXRbaV0tPXQub3ksdFsrK2ldKyt9dC5oeSgpLHQuRXkodGhpcy5pLml5LHQpLHQuYnkodGhpcy5pKT49MCYmdC5weSh0aGlzLmksdCl9ZnVuY3Rpb24gaih0LGUpe3QuT3koZSksdGhpcy5yZWR1Y2UoZSl9ZnVuY3Rpb24gVSh0LGUsaSl7dC5DeShlLGkpLHRoaXMucmVkdWNlKGkpfWZ1bmN0aW9uIFYoKXtyZXR1cm4gMD09KHRoaXMuaXk+MD8xJnRoaXNbMF06dGhpcy5ueSl9ZnVuY3Rpb24gUSh0LGUpe2lmKHQ+NDI5NDk2NzI5NXx8dDwxKXJldHVybiBpLk9ORTt2YXIgbj1yKCksbz1yKCkscz1lLl95KHRoaXMpLGE9bSh0KS0xO2ZvcihzLnZ5KG4pOy0tYT49MDspaWYoZS5EeShuLG8pLCh0JjE8PGEpPjApZS5IeShvLHMsbik7ZWxzZXt2YXIgYz1uO249byxvPWN9cmV0dXJuIGUuTHkobil9ZnVuY3Rpb24gcSh0LGUpe3ZhciBpO3JldHVybiBpPXQ8MjU2fHxlLk15KCk/bmV3IFAoZSk6bmV3IEQoZSksdGhpcy5leHAodCxpKX1mdW5jdGlvbiBKKHQpe3ZhciBlLGkscixuPVwiXCIsbz0wO2ZvcihlPTA7ZTx0Lmxlbmd0aCYmdC5jaGFyQXQoZSkhPXh0OysrZSlyPU50LmluZGV4T2YodC5jaGFyQXQoZSkpLHI8MHx8KDA9PW8/KG4rPWEocj4+MiksaT0zJnIsbz0xKToxPT1vPyhuKz1hKGk8PDJ8cj4+NCksaT0xNSZyLG89Mik6Mj09bz8obis9YShpKSxuKz1hKHI+PjIpLGk9MyZyLG89Myk6KG4rPWEoaTw8MnxyPj40KSxuKz1hKDE1JnIpLG89MCkpO3JldHVybiAxPT1vJiYobis9YShpPDwyKSksbn1mdW5jdGlvbiBLKHQpe3ZhciBlLGk9Sih0KSxyPW5ldyBBcnJheTtmb3IoZT0wOzIqZTxpLmxlbmd0aDsrK2UpcltlXT1wYXJzZUludChpLnN1YnN0cmluZygyKmUsMiplKzIpLDE2KTtyZXR1cm4gcn0vKiEgKGMpIFRvbSBXdSB8IGh0dHA6Ly93d3ctY3Mtc3R1ZGVudHMuc3RhbmZvcmQuZWR1L350ancvanNibi9cbiAqL1xuICBmdW5jdGlvbiBHKHQsZSl7cmV0dXJuIG5ldyBpKHQsZSl9ZnVuY3Rpb24geih0LGUpe2lmKGU8dC5sZW5ndGgrMTEpcmV0dXJuIGFsZXJ0KFwiTWVzc2FnZSB0b28gbG9uZyBmb3IgUlNBXCIpLG51bGw7Zm9yKHZhciByPW5ldyBBcnJheSxuPXQubGVuZ3RoLTE7bj49MCYmZT4wOyl7dmFyIG89dC5jaGFyQ29kZUF0KG4tLSk7bzwxMjg/clstLWVdPW86bz4xMjcmJm88MjA0OD8oclstLWVdPTYzJm98MTI4LHJbLS1lXT1vPj42fDE5Mik6KHJbLS1lXT02MyZvfDEyOCxyWy0tZV09bz4+NiY2M3wxMjgsclstLWVdPW8+PjEyfDIyNCl9clstLWVdPTA7Zm9yKHZhciBzPW5ldyBTZWN1cmVSYW5kb20sYT1uZXcgQXJyYXk7ZT4yOyl7Zm9yKGFbMF09MDswPT1hWzBdOylzLm5leHRCeXRlcyhhKTtyWy0tZV09YVswXX1yZXR1cm4gclstLWVdPTIsclstLWVdPTAsbmV3IGkocil9ZnVuY3Rpb24gVyh0LGUsaSl7Zm9yKHZhciByPVwiXCIsbj0wO3IubGVuZ3RoPGU7KXIrPWkoU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsdC5jb25jYXQoWyg0Mjc4MTkwMDgwJm4pPj4yNCwoMTY3MTE2ODAmbik+PjE2LCg2NTI4MCZuKT4+OCwyNTUmbl0pKSksbis9MTtyZXR1cm4gcn1mdW5jdGlvbiAkKHQsZSxyKXtpZih0Lmxlbmd0aCsyKkJ0KzI+ZSl0aHJvd1wiTWVzc2FnZSB0b28gbG9uZyBmb3IgUlNBXCI7dmFyIG4sbz1cIlwiO2ZvcihuPTA7bjxlLXQubGVuZ3RoLTIqQnQtMjtuKz0xKW8rPVwiXFwwXCI7dmFyIHM9cnN0cl9zaGExKFwiXCIpK28rXCJcdTAwMDFcIit0LGE9bmV3IEFycmF5KEJ0KTsobmV3IFNlY3VyZVJhbmRvbSkubmV4dEJ5dGVzKGEpO3ZhciBjPVcoYSxzLmxlbmd0aCxyfHxyc3RyX3NoYTEpLGg9W107Zm9yKG49MDtuPHMubGVuZ3RoO24rPTEpaFtuXT1zLmNoYXJDb2RlQXQobileYy5jaGFyQ29kZUF0KG4pO3ZhciBwPVcoaCxhLmxlbmd0aCxyc3RyX3NoYTEpLHU9WzBdO2ZvcihuPTA7bjxhLmxlbmd0aDtuKz0xKXVbbisxXT1hW25dXnAuY2hhckNvZGVBdChuKTtyZXR1cm4gbmV3IGkodS5jb25jYXQoaCkpfWZ1bmN0aW9uIFkoKXt0aGlzLm49bnVsbCx0aGlzLmU9MCx0aGlzLmQ9bnVsbCx0aGlzLm89bnVsbCx0aGlzLmp5PW51bGwsdGhpcy5VeT1udWxsLHRoaXMuVnk9bnVsbCx0aGlzLlF5PW51bGx9ZnVuY3Rpb24gWCh0LGUpe3RoaXMucXk9ITAsXCJzdHJpbmdcIiE9dHlwZW9mIHQ/KHRoaXMubj10LHRoaXMuZT1lKTpudWxsIT10JiZudWxsIT1lJiZ0Lmxlbmd0aD4wJiZlLmxlbmd0aD4wPyh0aGlzLm49Ryh0LDE2KSx0aGlzLmU9cGFyc2VJbnQoZSwxNikpOmFsZXJ0KFwiSW52YWxpZCBSU0EgcHVibGljIGtleVwiKX1mdW5jdGlvbiBaKHQpe3JldHVybiB0Lkp5KHRoaXMuZSx0aGlzLm4pfWZ1bmN0aW9uIHR0KHQpe3ZhciBlPXoodCx0aGlzLm4uS3koKSs3Pj4zKTtpZihudWxsPT1lKXJldHVybiBudWxsO3ZhciBpPXRoaXMuR3koZSk7aWYobnVsbD09aSlyZXR1cm4gbnVsbDt2YXIgcj1pLnRvU3RyaW5nKDE2KTtyZXR1cm4gMD09KDEmci5sZW5ndGgpP3I6XCIwXCIrcn1mdW5jdGlvbiBldCh0LGUpe3ZhciBpPSQodCx0aGlzLm4uS3koKSs3Pj4zLGUpO2lmKG51bGw9PWkpcmV0dXJuIG51bGw7dmFyIHI9dGhpcy5HeShpKTtpZihudWxsPT1yKXJldHVybiBudWxsO3ZhciBuPXIudG9TdHJpbmcoMTYpO3JldHVybiAwPT0oMSZuLmxlbmd0aCk/bjpcIjBcIitufWZ1bmN0aW9uIGl0KHQsZSl7Zm9yKHZhciBpPVwiXCIscj1lLzQtdC5sZW5ndGgsbj0wO248cjtuKyspaSs9XCIwXCI7cmV0dXJuIGkrdH1mdW5jdGlvbiBydCh0LGUpe3ZhciBpPWZ1bmN0aW9uKHQpe3JldHVybiBLSlVSLmNyeXB0by5XeS56eSh0LGUpfSxyPWkodCk7cmV0dXJuIHRoaXMuJHkocixlKX1mdW5jdGlvbiBudCh0LGUpe3ZhciBpPUtKVVIuY3J5cHRvLld5Lll5KHQsZSx0aGlzLm4uS3koKSkscj1HKGksMTYpLG49dGhpcy5kb1ByaXZhdGUociksbz1uLnRvU3RyaW5nKDE2KTtyZXR1cm4gaXQobyx0aGlzLm4uS3koKSl9ZnVuY3Rpb24gb3QodCl7cmV0dXJuIHJ0LmNhbGwodGhpcyx0LFwic2hhMVwiKX1mdW5jdGlvbiBzdCh0KXtyZXR1cm4gcnQuY2FsbCh0aGlzLHQsXCJzaGEyNTZcIil9ZnVuY3Rpb24gYXQodCxlLGkpe2Zvcih2YXIgcj1cIlwiLG49MDtyLmxlbmd0aDxlOylyKz1oZXh0b3JzdHIoaShyc3RydG9oZXgodCtTdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyxbKDQyNzgxOTAwODAmbik+PjI0LCgxNjcxMTY4MCZuKT4+MTYsKDY1MjgwJm4pPj44LDI1NSZuXSkpKSksbis9MTtyZXR1cm4gcn1mdW5jdGlvbiBjdCh0LGUsaSl7dmFyIHI9ZnVuY3Rpb24odCl7cmV0dXJuIEtKVVIuY3J5cHRvLld5Llh5KHQsZSl9LG49cihyc3RydG9oZXgodCkpO3JldHVybiB2b2lkIDA9PT1pJiYoaT0tMSksdGhpcy5aeShuLGUsaSl9ZnVuY3Rpb24gaHQodCxlLHIpe3ZhciBuLG89aGV4dG9yc3RyKHQpLHM9by5sZW5ndGgsYT10aGlzLm4uS3koKS0xLGM9TWF0aC5jZWlsKGEvOCksaD1mdW5jdGlvbih0KXtyZXR1cm4gS0pVUi5jcnlwdG8uV3kuWHkodCxlKX07aWYocj09PS0xfHx2b2lkIDA9PT1yKXI9cztlbHNlIGlmKHI9PT0tMilyPWMtcy0yO2Vsc2UgaWYocjwtMil0aHJvd1wiaW52YWxpZCBzYWx0IGxlbmd0aFwiO2lmKGM8cytyKzIpdGhyb3dcImRhdGEgdG9vIGxvbmdcIjt2YXIgcD1cIlwiO3I+MCYmKHA9bmV3IEFycmF5KHIpLChuZXcgU2VjdXJlUmFuZG9tKS5uZXh0Qnl0ZXMocCkscD1TdHJpbmcuZnJvbUNoYXJDb2RlLmFwcGx5KFN0cmluZyxwKSk7dmFyIHU9aGV4dG9yc3RyKGgocnN0cnRvaGV4KFwiXFwwXFwwXFwwXFwwXFwwXFwwXFwwXFwwXCIrbytwKSkpLGw9W107Zm9yKG49MDtuPGMtci1zLTI7bis9MSlsW25dPTA7dmFyIGQ9U3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcsbCkrXCJcdTAwMDFcIitwLGY9YXQodSxkLmxlbmd0aCxoKSxnPVtdO2ZvcihuPTA7bjxkLmxlbmd0aDtuKz0xKWdbbl09ZC5jaGFyQ29kZUF0KG4pXmYuY2hhckNvZGVBdChuKTt2YXIgdj02NTI4MD4+OCpjLWEmMjU1O2ZvcihnWzBdJj1+dixuPTA7bjxzO24rKylnLnB1c2godS5jaGFyQ29kZUF0KG4pKTtyZXR1cm4gZy5wdXNoKDE4OCksaXQodGhpcy5kb1ByaXZhdGUobmV3IGkoZykpLnRvU3RyaW5nKDE2KSx0aGlzLm4uS3koKSl9ZnVuY3Rpb24gcHQodCxlLGkpe3ZhciByPW5ldyBZO3IucWgoZSxpKTt2YXIgbj1yLkd5KHQpO3JldHVybiBufWZ1bmN0aW9uIHV0KHQsZSxpKXt2YXIgcj1wdCh0LGUsaSksbj1yLnRvU3RyaW5nKDE2KS5yZXBsYWNlKC9eMWYrMDAvLFwiXCIpO3JldHVybiBufWZ1bmN0aW9uIGx0KHQpe2Zvcih2YXIgZSBpbiBLSlVSLmNyeXB0by5XeS50bSl7dmFyIGk9S0pVUi5jcnlwdG8uV3kudG1bZV0scj1pLmxlbmd0aDtpZih0LnN1YnN0cmluZygwLHIpPT1pKXt2YXIgbj1bZSx0LnN1YnN0cmluZyhyKV07cmV0dXJuIG59fXJldHVybltdfWZ1bmN0aW9uIGR0KHQsZSxpLHIpe3ZhciBuPXV0KGUsaSxyKSxvPWx0KG4pO2lmKDA9PW8ubGVuZ3RoKXJldHVybiExO3ZhciBzPW9bMF0sYT1vWzFdLGM9ZnVuY3Rpb24odCl7cmV0dXJuIEtKVVIuY3J5cHRvLld5Lnp5KHQscyl9LGg9Yyh0KTtyZXR1cm4gYT09aH1mdW5jdGlvbiBmdCh0LGUpe3ZhciBpPUcodCwxNikscj1kdChlLGksdGhpcy5uLnRvU3RyaW5nKDE2KSx0aGlzLmUudG9TdHJpbmcoMTYpKTtyZXR1cm4gcn1mdW5jdGlvbiBndCh0LGUpe2U9ZS5yZXBsYWNlKEZ0LFwiXCIpLGU9ZS5yZXBsYWNlKC9bIFxcbl0rL2csXCJcIik7dmFyIGk9RyhlLDE2KTtpZihpLkt5KCk+dGhpcy5uLkt5KCkpcmV0dXJuIDA7dmFyIHI9dGhpcy5HeShpKSxuPXIudG9TdHJpbmcoMTYpLnJlcGxhY2UoL14xZiswMC8sXCJcIiksbz1sdChuKTtpZigwPT1vLmxlbmd0aClyZXR1cm4hMTt2YXIgcz1vWzBdLGE9b1sxXSxjPWZ1bmN0aW9uKHQpe3JldHVybiBLSlVSLmNyeXB0by5XeS56eSh0LHMpfSxoPWModCk7cmV0dXJuIGE9PWh9ZnVuY3Rpb24gdnQodCxlKXtlPWUucmVwbGFjZShGdCxcIlwiKSxlPWUucmVwbGFjZSgvWyBcXG5dKy9nLFwiXCIpO3ZhciBpPUcoZSwxNik7aWYoaS5LeSgpPnRoaXMubi5LeSgpKXJldHVybiAwO3ZhciByPXRoaXMuR3koaSksbj1yLnRvU3RyaW5nKDE2KS5yZXBsYWNlKC9eMWYrMDAvLFwiXCIpLG89bHQobik7aWYoMD09by5sZW5ndGgpcmV0dXJuITE7dmFyIHM9KG9bMF0sb1sxXSk7cmV0dXJuIHM9PXR9ZnVuY3Rpb24geXQodCxlLGkscil7dmFyIG49ZnVuY3Rpb24odCl7cmV0dXJuIEtKVVIuY3J5cHRvLld5Llh5KHQsaSl9LG89bihyc3RydG9oZXgodCkpO3JldHVybiB2b2lkIDA9PT1yJiYocj0tMSksdGhpcy5lbShvLGUsaSxyKX1mdW5jdGlvbiBtdCh0LGUscixuKXt2YXIgbz1uZXcgaShlLDE2KTtpZihvLkt5KCk+dGhpcy5uLkt5KCkpcmV0dXJuITE7dmFyIHMsYT1mdW5jdGlvbih0KXtyZXR1cm4gS0pVUi5jcnlwdG8uV3kuWHkodCxyKX0sYz1oZXh0b3JzdHIodCksaD1jLmxlbmd0aCxwPXRoaXMubi5LeSgpLTEsdT1NYXRoLmNlaWwocC84KTtpZihuPT09LTF8fHZvaWQgMD09PW4pbj1oO2Vsc2UgaWYobj09PS0yKW49dS1oLTI7ZWxzZSBpZihuPC0yKXRocm93XCJpbnZhbGlkIHNhbHQgbGVuZ3RoXCI7aWYodTxoK24rMil0aHJvd1wiZGF0YSB0b28gbG9uZ1wiO3ZhciBsPXRoaXMuR3kobykudG9CeXRlQXJyYXkoKTtmb3Iocz0wO3M8bC5sZW5ndGg7cys9MSlsW3NdJj0yNTU7Zm9yKDtsLmxlbmd0aDx1OylsLnVuc2hpZnQoMCk7aWYoMTg4IT09bFt1LTFdKXRocm93XCJlbmNvZGVkIG1lc3NhZ2UgZG9lcyBub3QgZW5kIGluIDB4YmNcIjtsPVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkoU3RyaW5nLGwpO3ZhciBkPWwuc3Vic3RyKDAsdS1oLTEpLGY9bC5zdWJzdHIoZC5sZW5ndGgsaCksZz02NTI4MD4+OCp1LXAmMjU1O2lmKDAhPT0oZC5jaGFyQ29kZUF0KDApJmcpKXRocm93XCJiaXRzIGJleW9uZCBrZXlzaXplIG5vdCB6ZXJvXCI7dmFyIHY9YXQoZixkLmxlbmd0aCxhKSx5PVtdO2ZvcihzPTA7czxkLmxlbmd0aDtzKz0xKXlbc109ZC5jaGFyQ29kZUF0KHMpXnYuY2hhckNvZGVBdChzKTt5WzBdJj1+Zzt2YXIgbT11LWgtbi0yO2ZvcihzPTA7czxtO3MrPTEpaWYoMCE9PXlbc10pdGhyb3dcImxlZnRtb3N0IG9jdGV0cyBub3QgemVyb1wiO2lmKDEhPT15W21dKXRocm93XCIweDAxIG1hcmtlciBub3QgZm91bmRcIjtyZXR1cm4gZj09PWhleHRvcnN0cihhKHJzdHJ0b2hleChcIlxcMFxcMFxcMFxcMFxcMFxcMFxcMFxcMFwiK2MrU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShTdHJpbmcseS5zbGljZSgtbikpKSkpfXZhciB3dD17fTt3dC51c2VyQWdlbnQ9ITE7dmFyIFR0PXt9O2lmKFwidW5kZWZpbmVkXCI9PXR5cGVvZiBTdHx8IVN0KXZhciBTdD17fTtTdC5pbT1mdW5jdGlvbigpe3ZhciB0LGUsaSxyPWFyZ3VtZW50cyxuPW51bGw7Zm9yKHQ9MDt0PHIubGVuZ3RoO3QrPTEpZm9yKGk9KFwiXCIrclt0XSkuc3BsaXQoXCIuXCIpLG49U3QsZT1cIllBSE9PXCI9PWlbMF0/MTowO2U8aS5sZW5ndGg7ZSs9MSluW2lbZV1dPW5baVtlXV18fHt9LG49bltpW2VdXTtyZXR1cm4gbn0sU3QubG9nPWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj1TdC53aWRnZXQuTG9nZ2VyO3JldHVybiEoIXJ8fCFyLmxvZykmJnIubG9nKHQsZSxpKX0sU3QucmVnaXN0ZXI9ZnVuY3Rpb24odCxlLGkpe3ZhciByLG4sbyxzLGEsYz1TdC5PdC5ybTtmb3IoY1t0XXx8KGNbdF09e25tOltdLG9tOltdfSkscj1jW3RdLG49aS52ZXJzaW9uLG89aS5wcCxzPVN0Lk90LnppLHIubmFtZT10LHIudmVyc2lvbj1uLHIucHA9byxyLm5tLnB1c2gobiksci5vbS5wdXNoKG8pLHIuc209ZSxhPTA7YTxzLmxlbmd0aDthKz0xKXNbYV0ocik7ZT8oZS5WRVJTSU9OPW4sZS5hbT1vKTpTdC5sb2coXCJtYWluQ2xhc3MgaXMgdW5kZWZpbmVkIGZvciBtb2R1bGUgXCIrdCxcIndhcm5cIil9LFN0Lk90PVN0Lk90fHx7cm06W10semk6W119LFN0Lk90LmdldFZlcnNpb249ZnVuY3Rpb24odCl7cmV0dXJuIFN0Lk90LnJtW3RdfHxudWxsfSxTdC5PdC5jbT1mdW5jdGlvbih0KXt2YXIgZSxpPWZ1bmN0aW9uKHQpe3ZhciBlPTA7cmV0dXJuIHBhcnNlRmxvYXQodC5yZXBsYWNlKC9cXC4vZyxmdW5jdGlvbigpe3JldHVybiAxPT1lKys/XCJcIjpcIi5cIn0pKX0scj13dCxuPXtobTowLG9wZXJhOjAscG06MCx1bTowLGNocm9tZTowLGxtOm51bGwsZG06MCxmbTowLGdtOjAsdm06MCx5bTpudWxsLG1tOjAsd206MCxUbTpyJiZyLmNhamFWZXJzaW9uLFNtOiExLG9zOm51bGx9LG89dHx8d3QmJnd0LnVzZXJBZ2VudCxzPVR0JiZUdC5sb2NhdGlvbixhPXMmJnMuaHJlZjtyZXR1cm4gbi5TbT1hJiYwPT09YS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoXCJodHRwc1wiKSxvJiYoL3dpbmRvd3N8d2luMzIvaS50ZXN0KG8pP24ub3M9XCJ3aW5kb3dzXCI6L21hY2ludG9zaC9pLnRlc3Qobyk/bi5vcz1cIm1hY2ludG9zaFwiOi9yaGluby9pLnRlc3QobykmJihuLm9zPVwicmhpbm9cIiksL0tIVE1MLy50ZXN0KG8pJiYobi51bT0xKSxlPW8ubWF0Y2goL0FwcGxlV2ViS2l0XFwvKFteXFxzXSopLyksZSYmZVsxXSYmKG4udW09aShlWzFdKSwvIE1vYmlsZVxcLy8udGVzdChvKT8obi5sbT1cIkFwcGxlXCIsZT1vLm1hdGNoKC9PUyAoW15cXHNdKikvKSxlJiZlWzFdJiYoZT1pKGVbMV0ucmVwbGFjZShcIl9cIixcIi5cIikpKSxuLnltPWUsbi5mbT1uLnZtPW4uZ209MCxlPW8ubWF0Y2goL2lQYWR8aVBvZHxpUGhvbmUvKSxlJiZlWzBdJiYobltlWzBdLnRvTG93ZXJDYXNlKCldPW4ueW0pKTooZT1vLm1hdGNoKC9Ob2tpYU5bXlxcL10qfEFuZHJvaWQgXFxkXFwuXFxkfHdlYk9TXFwvXFxkXFwuXFxkLyksZSYmKG4ubG09ZVswXSksL3dlYk9TLy50ZXN0KG8pJiYobi5sbT1cIldlYk9TXCIsZT1vLm1hdGNoKC93ZWJPU1xcLyhbXlxcc10qKTsvKSxlJiZlWzFdJiYobi53bT1pKGVbMV0pKSksLyBBbmRyb2lkLy50ZXN0KG8pJiYobi5sbT1cIkFuZHJvaWRcIixlPW8ubWF0Y2goL0FuZHJvaWQgKFteXFxzXSopOy8pLGUmJmVbMV0mJihuLm1tPWkoZVsxXSkpKSksZT1vLm1hdGNoKC9DaHJvbWVcXC8oW15cXHNdKikvKSxlJiZlWzFdP24uY2hyb21lPWkoZVsxXSk6KGU9by5tYXRjaCgvQWRvYmVBSVJcXC8oW15cXHNdKikvKSxlJiYobi5kbT1lWzBdKSkpLG4udW18fChlPW8ubWF0Y2goL09wZXJhW1xcc1xcL10oW15cXHNdKikvKSxlJiZlWzFdPyhuLm9wZXJhPWkoZVsxXSksZT1vLm1hdGNoKC9WZXJzaW9uXFwvKFteXFxzXSopLyksZSYmZVsxXSYmKG4ub3BlcmE9aShlWzFdKSksZT1vLm1hdGNoKC9PcGVyYSBNaW5pW147XSovKSxlJiYobi5sbT1lWzBdKSk6KGU9by5tYXRjaCgvTVNJRVxccyhbXjtdKikvKSxlJiZlWzFdP24uaG09aShlWzFdKTooZT1vLm1hdGNoKC9HZWNrb1xcLyhbXlxcc10qKS8pLGUmJihuLnBtPTEsZT1vLm1hdGNoKC9ydjooW15cXHNcXCldKikvKSxlJiZlWzFdJiYobi5wbT1pKGVbMV0pKSkpKSkpLG59LFN0Lk90LnRmPVN0Lk90LmNtKCksZnVuY3Rpb24oKXtpZihTdC5pbShcInV0aWxcIixcIndpZGdldFwiLFwiZXhhbXBsZVwiKSxcInVuZGVmaW5lZFwiIT10eXBlb2YgWUFIT09fY29uZmlnKXt2YXIgdCxlPVlBSE9PX2NvbmZpZy5saXN0ZW5lcixpPVN0Lk90LnppLHI9ITA7aWYoZSl7Zm9yKHQ9MDt0PGkubGVuZ3RoO3QrKylpZihpW3RdPT1lKXtyPSExO2JyZWFrfXImJmkucHVzaChlKX19fSgpLFN0Lmxhbmc9U3QubGFuZ3x8e30sZnVuY3Rpb24oKXt2YXIgdD1TdC5sYW5nLGU9T2JqZWN0LnByb3RvdHlwZSxpPVwiW29iamVjdCBBcnJheV1cIixyPVwiW29iamVjdCBGdW5jdGlvbl1cIixuPVwiW29iamVjdCBPYmplY3RdXCIsbz1bXSxzPXtibTpcIiZhbXA7XCIsRW06XCImbHQ7XCIsSW06XCImZ3Q7XCIsUm06XCImcXVvdDtcIixrbTpcIiYjeDI3O1wiLEpwOlwiJiN4MkY7XCIsQ206XCImI3g2MDtcIn0sYT1bXCJ0b1N0cmluZ1wiLFwidmFsdWVPZlwiXSxjPXtpc0FycmF5OmZ1bmN0aW9uKHQpe3JldHVybiBlLnRvU3RyaW5nLmFwcGx5KHQpPT09aX0sT206ZnVuY3Rpb24odCl7cmV0dXJuXCJib29sZWFuXCI9PXR5cGVvZiB0fSxQbTpmdW5jdGlvbih0KXtyZXR1cm5cImZ1bmN0aW9uXCI9PXR5cGVvZiB0fHxlLnRvU3RyaW5nLmFwcGx5KHQpPT09cn0sQW06ZnVuY3Rpb24odCl7cmV0dXJuIG51bGw9PT10fSxObTpmdW5jdGlvbih0KXtyZXR1cm5cIm51bWJlclwiPT10eXBlb2YgdCYmaXNGaW5pdGUodCl9LG92OmZ1bmN0aW9uKGUpe3JldHVybiBlJiYoXCJvYmplY3RcIj09dHlwZW9mIGV8fHQuUG0oZSkpfHwhMX0seG06ZnVuY3Rpb24odCl7cmV0dXJuXCJzdHJpbmdcIj09dHlwZW9mIHR9LEJtOmZ1bmN0aW9uKHQpe3JldHVyblwidW5kZWZpbmVkXCI9PXR5cGVvZiB0fSxGbTpTdC5PdC50Zi5obT9mdW5jdGlvbihpLHIpe3ZhciBuLG8scztmb3Iobj0wO248YS5sZW5ndGg7bis9MSlvPWFbbl0scz1yW29dLHQuUG0ocykmJnMhPWVbb10mJihpW29dPXMpfTpmdW5jdGlvbigpe30sX206ZnVuY3Rpb24odCl7cmV0dXJuIHQucmVwbGFjZSgvWyY8PlwiJ1xcL2BdL2csZnVuY3Rpb24odCl7cmV0dXJuIHNbdF19KX0sZXh0ZW5kOmZ1bmN0aW9uKGkscixuKXtpZighcnx8IWkpdGhyb3cgbmV3IEVycm9yKFwiZXh0ZW5kIGZhaWxlZCwgcGxlYXNlIGNoZWNrIHRoYXQgYWxsIGRlcGVuZGVuY2llcyBhcmUgaW5jbHVkZWQuXCIpO3ZhciBvLHM9ZnVuY3Rpb24oKXt9O2lmKHMucHJvdG90eXBlPXIucHJvdG90eXBlLGkucHJvdG90eXBlPW5ldyBzLGkucHJvdG90eXBlLmNvbnN0cnVjdG9yPWksaS5EbT1yLnByb3RvdHlwZSxyLnByb3RvdHlwZS5jb25zdHJ1Y3Rvcj09ZS5jb25zdHJ1Y3RvciYmKHIucHJvdG90eXBlLmNvbnN0cnVjdG9yPXIpLG4pe2ZvcihvIGluIG4pdC5oYXNPd25Qcm9wZXJ0eShuLG8pJiYoaS5wcm90b3R5cGVbb109bltvXSk7dC5GbShpLnByb3RvdHlwZSxuKX19LEhtOmZ1bmN0aW9uKGUsaSl7aWYoIWl8fCFlKXRocm93IG5ldyBFcnJvcihcIkFic29yYiBmYWlsZWQsIHZlcmlmeSBkZXBlbmRlbmNpZXMuXCIpO3ZhciByLG4sbz1hcmd1bWVudHMscz1vWzJdO2lmKHMmJnMhPT0hMClmb3Iocj0yO3I8by5sZW5ndGg7cis9MSllW29bcl1dPWlbb1tyXV07ZWxzZXtmb3IobiBpbiBpKSFzJiZuIGluIGV8fChlW25dPWlbbl0pO3QuRm0oZSxpKX1yZXR1cm4gZX0sTG06ZnVuY3Rpb24oZSxpKXtpZighaXx8IWUpdGhyb3cgbmV3IEVycm9yKFwiQXVnbWVudCBmYWlsZWQsIHZlcmlmeSBkZXBlbmRlbmNpZXMuXCIpO3ZhciByLG49W2UucHJvdG90eXBlLGkucHJvdG90eXBlXTtmb3Iocj0yO3I8YXJndW1lbnRzLmxlbmd0aDtyKz0xKW4ucHVzaChhcmd1bWVudHNbcl0pO3JldHVybiB0LkhtLmFwcGx5KHRoaXMsbiksZX0sZHVtcDpmdW5jdGlvbihlLGkpe3ZhciByLG4sbz1bXSxzPVwiey4uLn1cIixhPVwiZigpey4uLn1cIixjPVwiLCBcIixoPVwiID0+IFwiO2lmKCF0Lm92KGUpKXJldHVybiBlK1wiXCI7aWYoZSBpbnN0YW5jZW9mIERhdGV8fFwibm9kZVR5cGVcImluIGUmJlwidGFnTmFtZVwiaW4gZSlyZXR1cm4gZTtpZih0LlBtKGUpKXJldHVybiBhO2lmKGk9dC5ObShpKT9pOjMsdC5pc0FycmF5KGUpKXtmb3Ioby5wdXNoKFwiW1wiKSxyPTAsbj1lLmxlbmd0aDtyPG47cis9MSl0Lm92KGVbcl0pP28ucHVzaChpPjA/dC5kdW1wKGVbcl0saS0xKTpzKTpvLnB1c2goZVtyXSksby5wdXNoKGMpO28ubGVuZ3RoPjEmJm8ucG9wKCksby5wdXNoKFwiXVwiKX1lbHNle28ucHVzaChcIntcIik7Zm9yKHIgaW4gZSl0Lmhhc093blByb3BlcnR5KGUscikmJihvLnB1c2gocitoKSx0Lm92KGVbcl0pP28ucHVzaChpPjA/dC5kdW1wKGVbcl0saS0xKTpzKTpvLnB1c2goZVtyXSksby5wdXNoKGMpKTtvLmxlbmd0aD4xJiZvLnBvcCgpLG8ucHVzaChcIn1cIil9cmV0dXJuIG8uam9pbihcIlwiKX0sTW06ZnVuY3Rpb24oZSxpLHIsbyl7Zm9yKHZhciBzLGEsYyxoLHAsdSxsLGQsZixnPVtdLHY9ZS5sZW5ndGgseT1cImR1bXBcIixtPVwiIFwiLHc9XCJ7XCIsVD1cIn1cIjsocz1lLmxhc3RJbmRleE9mKHcsdiksIShzPDApKSYmKGE9ZS5pbmRleE9mKFQscyksIShzKzE+YSkpOylsPWUuc3Vic3RyaW5nKHMrMSxhKSxoPWwsdT1udWxsLGM9aC5pbmRleE9mKG0pLGM+LTEmJih1PWguc3Vic3RyaW5nKGMrMSksaD1oLnN1YnN0cmluZygwLGMpKSxwPWlbaF0sciYmKHA9cihoLHAsdSkpLHQub3YocCk/dC5pc0FycmF5KHApP3A9dC5kdW1wKHAscGFyc2VJbnQodSwxMCkpOih1PXV8fFwiXCIsZD11LmluZGV4T2YoeSksZD4tMSYmKHU9dS5zdWJzdHJpbmcoNCkpLGY9cC50b1N0cmluZygpLHA9Zj09PW58fGQ+LTE/dC5kdW1wKHAscGFyc2VJbnQodSwxMCkpOmYpOnQueG0ocCl8fHQuTm0ocCl8fChwPVwifi1cIitnLmxlbmd0aCtcIi1+XCIsZ1tnLmxlbmd0aF09bCksZT1lLnN1YnN0cmluZygwLHMpK3ArZS5zdWJzdHJpbmcoYSsxKSxvPT09ITEmJih2PXMtMSk7Zm9yKHM9Zy5sZW5ndGgtMTtzPj0wO3MtPTEpZT1lLnJlcGxhY2UobmV3IFJlZ0V4cChcIn4tXCIrcytcIi1+XCIpLFwie1wiK2dbc10rXCJ9XCIsXCJnXCIpO3JldHVybiBlfSx0cmltOmZ1bmN0aW9uKHQpe3RyeXtyZXR1cm4gdC5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLFwiXCIpfWNhdGNoKGUpe3JldHVybiB0fX0sam06ZnVuY3Rpb24oKXt2YXIgZSxpPXt9LHI9YXJndW1lbnRzLG49ci5sZW5ndGg7Zm9yKGU9MDtlPG47ZSs9MSl0LkhtKGkscltlXSwhMCk7cmV0dXJuIGl9LFVtOmZ1bmN0aW9uKGUsaSxyLG4scyl7ZT1lfHwwLGk9aXx8e307dmFyIGEsYyxoPXIscD1uO2lmKHQueG0ocikmJihoPWlbcl0pLCFoKXRocm93IG5ldyBUeXBlRXJyb3IoXCJtZXRob2QgdW5kZWZpbmVkXCIpO3JldHVybiB0LkJtKG4pfHx0LmlzQXJyYXkocCl8fChwPVtuXSksYT1mdW5jdGlvbigpe2guYXBwbHkoaSxwfHxvKX0sYz1zP3NldEludGVydmFsKGEsZSk6c2V0VGltZW91dChhLGUpLHtpbnRlcnZhbDpzLGNhbmNlbDpmdW5jdGlvbigpe3RoaXMuaW50ZXJ2YWw/Y2xlYXJJbnRlcnZhbChjKTpjbGVhclRpbWVvdXQoYyl9fX0sVm06ZnVuY3Rpb24oZSl7cmV0dXJuIHQub3YoZSl8fHQueG0oZSl8fHQuTm0oZSl8fHQuT20oZSl9fTt0Lmhhc093blByb3BlcnR5PWUuaGFzT3duUHJvcGVydHk/ZnVuY3Rpb24odCxlKXtyZXR1cm4gdCYmdC5oYXNPd25Qcm9wZXJ0eSYmdC5oYXNPd25Qcm9wZXJ0eShlKX06ZnVuY3Rpb24oZSxpKXtyZXR1cm4hdC5CbShlW2ldKSYmZS5jb25zdHJ1Y3Rvci5wcm90b3R5cGVbaV0hPT1lW2ldfSxjLkhtKHQsYywhMCksU3QudXRpbC5MYW5nPXQsdC5RbT10LkxtLFN0LlFtPXQuTG0sU3QuZXh0ZW5kPXQuZXh0ZW5kfSgpLFN0LnJlZ2lzdGVyKFwieWFob29cIixTdCx7dmVyc2lvbjpcIjIuOS4wXCIscHA6XCIyODAwXCJ9KTsvKiEgQ3J5cHRvSlMgdjMuMS4yIGNvcmUtZml4LmpzXG4gICAqIGNvZGUuZ29vZ2xlLmNvbS9wL2NyeXB0by1qc1xuICAgKiAoYykgMjAwOS0yMDEzIGJ5IEplZmYgTW90dC4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbiAgICogY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL3dpa2kvTGljZW5zZVxuICAgKiBUSElTIElTIEZJWCBvZiAnY29yZS5qcycgdG8gZml4IEhtYWMgaXNzdWUuXG4gICAqIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvY3J5cHRvLWpzL2lzc3Vlcy9kZXRhaWw/aWQ9ODRcbiAgICogaHR0cHM6Ly9jcnlwdG8tanMuZ29vZ2xlY29kZS5jb20vc3ZuLWhpc3RvcnkvcjY2Ny9icmFuY2hlcy8zLngvc3JjL2NvcmUuanNcbiAgICovXG4gIHZhciBidD1idHx8ZnVuY3Rpb24odCxlKXt2YXIgaT17fSxyPWkucW09e30sbj1yLkptPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm57ZXh0ZW5kOmZ1bmN0aW9uKGUpe3QucHJvdG90eXBlPXRoaXM7dmFyIGk9bmV3IHQ7cmV0dXJuIGUmJmkuS20oZSksaS5oYXNPd25Qcm9wZXJ0eShcImluaXRcIil8fChpLmluaXQ9ZnVuY3Rpb24oKXtpLkdtLmluaXQuYXBwbHkodGhpcyxhcmd1bWVudHMpfSksaS5pbml0LnByb3RvdHlwZT1pLGkuR209dGhpcyxpfSxjcmVhdGU6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmV4dGVuZCgpO3JldHVybiB0LmluaXQuYXBwbHkodCxhcmd1bWVudHMpLHR9LGluaXQ6ZnVuY3Rpb24oKXt9LEttOmZ1bmN0aW9uKHQpe2Zvcih2YXIgZSBpbiB0KXQuaGFzT3duUHJvcGVydHkoZSkmJih0aGlzW2VdPXRbZV0pO3QuaGFzT3duUHJvcGVydHkoXCJ0b1N0cmluZ1wiKSYmKHRoaXMudG9TdHJpbmc9dC50b1N0cmluZyl9LGNsb25lOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuaW5pdC5wcm90b3R5cGUuZXh0ZW5kKHRoaXMpfX19KCksbz1yLnptPW4uZXh0ZW5kKHtpbml0OmZ1bmN0aW9uKHQsaSl7dD10aGlzLldtPXR8fFtdLGkhPWU/dGhpcy4kbT1pOnRoaXMuJG09NCp0Lmxlbmd0aH0sdG9TdHJpbmc6ZnVuY3Rpb24odCl7cmV0dXJuKHR8fGEpLnN0cmluZ2lmeSh0aGlzKX0sY29uY2F0OmZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMuV20saT10LldtLHI9dGhpcy4kbSxuPXQuJG07aWYodGhpcy5oeSgpLHIlNClmb3IodmFyIG89MDtvPG47bysrKXt2YXIgcz1pW28+Pj4yXT4+PjI0LW8lNCo4JjI1NTtlW3Irbz4+PjJdfD1zPDwyNC0ocitvKSU0Kjh9ZWxzZSBmb3IodmFyIG89MDtvPG47bys9NCllW3Irbz4+PjJdPWlbbz4+PjJdO3JldHVybiB0aGlzLiRtKz1uLHRoaXN9LGh5OmZ1bmN0aW9uKCl7dmFyIGU9dGhpcy5XbSxpPXRoaXMuJG07ZVtpPj4+Ml0mPTQyOTQ5NjcyOTU8PDMyLWklNCo4LGUubGVuZ3RoPXQuY2VpbChpLzQpfSxjbG9uZTpmdW5jdGlvbigpe3ZhciB0PW4uY2xvbmUuY2FsbCh0aGlzKTtyZXR1cm4gdC5XbT10aGlzLldtLnNsaWNlKDApLHR9LHJhbmRvbTpmdW5jdGlvbihlKXtmb3IodmFyIGk9W10scj0wO3I8ZTtyKz00KWkucHVzaCg0Mjk0OTY3Mjk2KnQucmFuZG9tKCl8MCk7cmV0dXJuIG5ldyBvLmluaXQoaSxlKX19KSxzPWkuWW09e30sYT1zLlhtPXtzdHJpbmdpZnk6ZnVuY3Rpb24odCl7Zm9yKHZhciBlPXQuV20saT10LiRtLHI9W10sbj0wO248aTtuKyspe3ZhciBvPWVbbj4+PjJdPj4+MjQtbiU0KjgmMjU1O3IucHVzaCgobz4+PjQpLnRvU3RyaW5nKDE2KSksci5wdXNoKCgxNSZvKS50b1N0cmluZygxNikpfXJldHVybiByLmpvaW4oXCJcIil9LHBhcnNlOmZ1bmN0aW9uKHQpe2Zvcih2YXIgZT10Lmxlbmd0aCxpPVtdLHI9MDtyPGU7cis9MilpW3I+Pj4zXXw9cGFyc2VJbnQodC5zdWJzdHIociwyKSwxNik8PDI0LXIlOCo0O3JldHVybiBuZXcgby5pbml0KGksZS8yKX19LGM9cy5abT17c3RyaW5naWZ5OmZ1bmN0aW9uKHQpe2Zvcih2YXIgZT10LldtLGk9dC4kbSxyPVtdLG49MDtuPGk7bisrKXt2YXIgbz1lW24+Pj4yXT4+PjI0LW4lNCo4JjI1NTtyLnB1c2goU3RyaW5nLmZyb21DaGFyQ29kZShvKSl9cmV0dXJuIHIuam9pbihcIlwiKX0scGFyc2U6ZnVuY3Rpb24odCl7Zm9yKHZhciBlPXQubGVuZ3RoLGk9W10scj0wO3I8ZTtyKyspaVtyPj4+Ml18PSgyNTUmdC5jaGFyQ29kZUF0KHIpKTw8MjQtciU0Kjg7cmV0dXJuIG5ldyBvLmluaXQoaSxlKX19LGg9cy50dz17c3RyaW5naWZ5OmZ1bmN0aW9uKHQpe3RyeXtyZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KGVzY2FwZShjLnN0cmluZ2lmeSh0KSkpfWNhdGNoKGUpe3Rocm93IG5ldyBFcnJvcihcIk1hbGZvcm1lZCBVVEYtOCBkYXRhXCIpfX0scGFyc2U6ZnVuY3Rpb24odCl7cmV0dXJuIGMucGFyc2UodW5lc2NhcGUoZW5jb2RlVVJJQ29tcG9uZW50KHQpKSl9fSxwPXIuZXc9bi5leHRlbmQoe3Jlc2V0OmZ1bmN0aW9uKCl7dGhpcy5pdz1uZXcgby5pbml0LHRoaXMucnc9MH0sbnc6ZnVuY3Rpb24odCl7XCJzdHJpbmdcIj09dHlwZW9mIHQmJih0PWgucGFyc2UodCkpLHRoaXMuaXcuY29uY2F0KHQpLHRoaXMucncrPXQuJG19LG93OmZ1bmN0aW9uKGUpe3ZhciBpPXRoaXMuaXcscj1pLldtLG49aS4kbSxzPXRoaXMuc3csYT00KnMsYz1uL2E7Yz1lP3QuY2VpbChjKTp0Lm1heCgoMHxjKS10aGlzLmF3LDApO3ZhciBoPWMqcyxwPXQubWluKDQqaCxuKTtpZihoKXtmb3IodmFyIHU9MDt1PGg7dSs9cyl0aGlzLmN3KHIsdSk7dmFyIGw9ci5zcGxpY2UoMCxoKTtpLiRtLT1wfXJldHVybiBuZXcgby5pbml0KGwscCl9LGNsb25lOmZ1bmN0aW9uKCl7dmFyIHQ9bi5jbG9uZS5jYWxsKHRoaXMpO3JldHVybiB0Lml3PXRoaXMuaXcuY2xvbmUoKSx0fSxhdzowfSksdT0oci5odz1wLmV4dGVuZCh7cHc6bi5leHRlbmQoKSxpbml0OmZ1bmN0aW9uKHQpe3RoaXMucHc9dGhpcy5wdy5leHRlbmQodCksdGhpcy5yZXNldCgpfSxyZXNldDpmdW5jdGlvbigpe3AucmVzZXQuY2FsbCh0aGlzKSx0aGlzLnV3KCl9LHVwZGF0ZTpmdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5udyh0KSx0aGlzLm93KCksdGhpc30sbHc6ZnVuY3Rpb24odCl7dCYmdGhpcy5udyh0KTt2YXIgZT10aGlzLmR3KCk7cmV0dXJuIGV9LHN3OjE2LGZ3OmZ1bmN0aW9uKHQpe3JldHVybiBmdW5jdGlvbihlLGkpe3JldHVybiBuZXcgdC5pbml0KGkpLmx3KGUpfX0sZ3c6ZnVuY3Rpb24odCl7cmV0dXJuIGZ1bmN0aW9uKGUsaSl7cmV0dXJuIG5ldyB1LkhNQUMuaW5pdCh0LGkpLmx3KGUpfX19KSxpLnZ3PXt9KTtyZXR1cm4gaX0oTWF0aCk7IWZ1bmN0aW9uKHQpe2Z1bmN0aW9uIGUodCxlLGkscixuLG8scyl7cmV0dXJuIHQ9dCsoZSZpfH5lJnIpK24rcywodDw8b3x0Pj4+MzItbykrZX1mdW5jdGlvbiBpKHQsZSxpLHIsbixvLHMpe3JldHVybiB0PXQrKGUmcnxpJn5yKStuK3MsKHQ8PG98dD4+PjMyLW8pK2V9ZnVuY3Rpb24gcih0LGUsaSxyLG4sbyxzKXtyZXR1cm4gdD10KyhlXmlecikrbitzLCh0PDxvfHQ+Pj4zMi1vKStlfWZ1bmN0aW9uIG4odCxlLGkscixuLG8scyl7cmV0dXJuIHQ9dCsoaV4oZXx+cikpK24rcywodDw8b3x0Pj4+MzItbykrZX1mb3IodmFyIG89YnQscz1vLnFtLGE9cy56bSxjPXMuaHcscz1vLnZ3LGg9W10scD0wOzY0PnA7cCsrKWhbcF09NDI5NDk2NzI5Nip0LmFicyh0LnNpbihwKzEpKXwwO3M9cy55dz1jLmV4dGVuZCh7dXc6ZnVuY3Rpb24oKXt0aGlzLm13PW5ldyBhLmluaXQoWzE3MzI1ODQxOTMsNDAyMzIzMzQxNywyNTYyMzgzMTAyLDI3MTczMzg3OF0pfSxjdzpmdW5jdGlvbih0LG8pe2Zvcih2YXIgcz0wOzE2PnM7cysrKXt2YXIgYT1vK3MsYz10W2FdO3RbYV09MTY3MTE5MzUmKGM8PDh8Yz4+PjI0KXw0Mjc4MjU1MzYwJihjPDwyNHxjPj4+OCl9dmFyIHM9dGhpcy5tdy5XbSxhPXRbbyswXSxjPXRbbysxXSxwPXRbbysyXSx1PXRbbyszXSxsPXRbbys0XSxkPXRbbys1XSxmPXRbbys2XSxnPXRbbys3XSx2PXRbbys4XSx5PXRbbys5XSxtPXRbbysxMF0sdz10W28rMTFdLFQ9dFtvKzEyXSxTPXRbbysxM10sYj10W28rMTRdLEU9dFtvKzE1XSxJPXNbMF0sUj1zWzFdLGs9c1syXSxDPXNbM10sST1lKEksUixrLEMsYSw3LGhbMF0pLEM9ZShDLEksUixrLGMsMTIsaFsxXSksaz1lKGssQyxJLFIscCwxNyxoWzJdKSxSPWUoUixrLEMsSSx1LDIyLGhbM10pLEk9ZShJLFIsayxDLGwsNyxoWzRdKSxDPWUoQyxJLFIsayxkLDEyLGhbNV0pLGs9ZShrLEMsSSxSLGYsMTcsaFs2XSksUj1lKFIsayxDLEksZywyMixoWzddKSxJPWUoSSxSLGssQyx2LDcsaFs4XSksQz1lKEMsSSxSLGsseSwxMixoWzldKSxrPWUoayxDLEksUixtLDE3LGhbMTBdKSxSPWUoUixrLEMsSSx3LDIyLGhbMTFdKSxJPWUoSSxSLGssQyxULDcsaFsxMl0pLEM9ZShDLEksUixrLFMsMTIsaFsxM10pLGs9ZShrLEMsSSxSLGIsMTcsaFsxNF0pLFI9ZShSLGssQyxJLEUsMjIsaFsxNV0pLEk9aShJLFIsayxDLGMsNSxoWzE2XSksQz1pKEMsSSxSLGssZiw5LGhbMTddKSxrPWkoayxDLEksUix3LDE0LGhbMThdKSxSPWkoUixrLEMsSSxhLDIwLGhbMTldKSxJPWkoSSxSLGssQyxkLDUsaFsyMF0pLEM9aShDLEksUixrLG0sOSxoWzIxXSksaz1pKGssQyxJLFIsRSwxNCxoWzIyXSksUj1pKFIsayxDLEksbCwyMCxoWzIzXSksST1pKEksUixrLEMseSw1LGhbMjRdKSxDPWkoQyxJLFIsayxiLDksaFsyNV0pLGs9aShrLEMsSSxSLHUsMTQsaFsyNl0pLFI9aShSLGssQyxJLHYsMjAsaFsyN10pLEk9aShJLFIsayxDLFMsNSxoWzI4XSksQz1pKEMsSSxSLGsscCw5LGhbMjldKSxrPWkoayxDLEksUixnLDE0LGhbMzBdKSxSPWkoUixrLEMsSSxULDIwLGhbMzFdKSxJPXIoSSxSLGssQyxkLDQsaFszMl0pLEM9cihDLEksUixrLHYsMTEsaFszM10pLGs9cihrLEMsSSxSLHcsMTYsaFszNF0pLFI9cihSLGssQyxJLGIsMjMsaFszNV0pLEk9cihJLFIsayxDLGMsNCxoWzM2XSksQz1yKEMsSSxSLGssbCwxMSxoWzM3XSksaz1yKGssQyxJLFIsZywxNixoWzM4XSksUj1yKFIsayxDLEksbSwyMyxoWzM5XSksST1yKEksUixrLEMsUyw0LGhbNDBdKSxDPXIoQyxJLFIsayxhLDExLGhbNDFdKSxrPXIoayxDLEksUix1LDE2LGhbNDJdKSxSPXIoUixrLEMsSSxmLDIzLGhbNDNdKSxJPXIoSSxSLGssQyx5LDQsaFs0NF0pLEM9cihDLEksUixrLFQsMTEsaFs0NV0pLGs9cihrLEMsSSxSLEUsMTYsaFs0Nl0pLFI9cihSLGssQyxJLHAsMjMsaFs0N10pLEk9bihJLFIsayxDLGEsNixoWzQ4XSksQz1uKEMsSSxSLGssZywxMCxoWzQ5XSksaz1uKGssQyxJLFIsYiwxNSxoWzUwXSksUj1uKFIsayxDLEksZCwyMSxoWzUxXSksST1uKEksUixrLEMsVCw2LGhbNTJdKSxDPW4oQyxJLFIsayx1LDEwLGhbNTNdKSxrPW4oayxDLEksUixtLDE1LGhbNTRdKSxSPW4oUixrLEMsSSxjLDIxLGhbNTVdKSxJPW4oSSxSLGssQyx2LDYsaFs1Nl0pLEM9bihDLEksUixrLEUsMTAsaFs1N10pLGs9bihrLEMsSSxSLGYsMTUsaFs1OF0pLFI9bihSLGssQyxJLFMsMjEsaFs1OV0pLEk9bihJLFIsayxDLGwsNixoWzYwXSksQz1uKEMsSSxSLGssdywxMCxoWzYxXSksaz1uKGssQyxJLFIscCwxNSxoWzYyXSksUj1uKFIsayxDLEkseSwyMSxoWzYzXSk7c1swXT1zWzBdK0l8MCxzWzFdPXNbMV0rUnwwLHNbMl09c1syXStrfDAsc1szXT1zWzNdK0N8MH0sZHc6ZnVuY3Rpb24oKXt2YXIgZT10aGlzLml3LGk9ZS5XbSxyPTgqdGhpcy5ydyxuPTgqZS4kbTtpW24+Pj41XXw9MTI4PDwyNC1uJTMyO3ZhciBvPXQuZmxvb3Ioci80Mjk0OTY3Mjk2KTtmb3IoaVsobis2ND4+Pjk8PDQpKzE1XT0xNjcxMTkzNSYobzw8OHxvPj4+MjQpfDQyNzgyNTUzNjAmKG88PDI0fG8+Pj44KSxpWyhuKzY0Pj4+OTw8NCkrMTRdPTE2NzExOTM1JihyPDw4fHI+Pj4yNCl8NDI3ODI1NTM2MCYocjw8MjR8cj4+PjgpLGUuJG09NCooaS5sZW5ndGgrMSksdGhpcy5vdygpLGU9dGhpcy5tdyxpPWUuV20scj0wOzQ+cjtyKyspbj1pW3JdLGlbcl09MTY3MTE5MzUmKG48PDh8bj4+PjI0KXw0Mjc4MjU1MzYwJihuPDwyNHxuPj4+OCk7cmV0dXJuIGV9LGNsb25lOmZ1bmN0aW9uKCl7dmFyIHQ9Yy5jbG9uZS5jYWxsKHRoaXMpO3JldHVybiB0Lm13PXRoaXMubXcuY2xvbmUoKSx0fX0pLG8ueXc9Yy5mdyhzKSxvLnd3PWMuZ3cocyl9KE1hdGgpLGZ1bmN0aW9uKCl7dmFyIHQ9YnQsZT10LnFtLGk9ZS56bSxyPWUuaHcsbj1bXSxlPXQudncuVHc9ci5leHRlbmQoe3V3OmZ1bmN0aW9uKCl7dGhpcy5tdz1uZXcgaS5pbml0KFsxNzMyNTg0MTkzLDQwMjMyMzM0MTcsMjU2MjM4MzEwMiwyNzE3MzM4NzgsMzI4NTM3NzUyMF0pfSxjdzpmdW5jdGlvbih0LGUpe2Zvcih2YXIgaT10aGlzLm13LldtLHI9aVswXSxvPWlbMV0scz1pWzJdLGE9aVszXSxjPWlbNF0saD0wOzgwPmg7aCsrKXtpZigxNj5oKW5baF09MHx0W2UraF07ZWxzZXt2YXIgcD1uW2gtM11ebltoLThdXm5baC0xNF1ebltoLTE2XTtuW2hdPXA8PDF8cD4+PjMxfXA9KHI8PDV8cj4+PjI3KStjK25baF0scD0yMD5oP3ArKChvJnN8fm8mYSkrMTUxODUwMDI0OSk6NDA+aD9wKygob15zXmEpKzE4NTk3NzUzOTMpOjYwPmg/cCsoKG8mc3xvJmF8cyZhKS0xODk0MDA3NTg4KTpwKygob15zXmEpLTg5OTQ5NzUxNCksYz1hLGE9cyxzPW88PDMwfG8+Pj4yLG89cixyPXB9aVswXT1pWzBdK3J8MCxpWzFdPWlbMV0rb3wwLGlbMl09aVsyXStzfDAsaVszXT1pWzNdK2F8MCxpWzRdPWlbNF0rY3wwfSxkdzpmdW5jdGlvbigpe3ZhciB0PXRoaXMuaXcsZT10LldtLGk9OCp0aGlzLnJ3LHI9OCp0LiRtO3JldHVybiBlW3I+Pj41XXw9MTI4PDwyNC1yJTMyLGVbKHIrNjQ+Pj45PDw0KSsxNF09TWF0aC5mbG9vcihpLzQyOTQ5NjcyOTYpLGVbKHIrNjQ+Pj45PDw0KSsxNV09aSx0LiRtPTQqZS5sZW5ndGgsdGhpcy5vdygpLHRoaXMubXd9LGNsb25lOmZ1bmN0aW9uKCl7dmFyIHQ9ci5jbG9uZS5jYWxsKHRoaXMpO3JldHVybiB0Lm13PXRoaXMubXcuY2xvbmUoKSx0fX0pO3QuVHc9ci5mdyhlKSx0LlN3PXIuZ3coZSl9KCk7LyohIChjKSBUb20gV3UgfCBodHRwOi8vd3d3LWNzLXN0dWRlbnRzLnN0YW5mb3JkLmVkdS9+dGp3L2pzYm4vICovXG4gIHZhciBFdCxJdD0weGRlYWRiZWVmY2FmZSxSdD0xNTcxNTA3MD09KDE2Nzc3MjE1Jkl0KTtSdCYmXCJNaWNyb3NvZnQgSW50ZXJuZXQgRXhwbG9yZXJcIj09d3QuYXBwTmFtZT8oaS5wcm90b3R5cGUuZ3k9byxFdD0zMCk6UnQmJlwiTmV0c2NhcGVcIiE9d3QuYXBwTmFtZT8oaS5wcm90b3R5cGUuZ3k9bixFdD0yNik6KGkucHJvdG90eXBlLmd5PXMsRXQ9MjgpLGkucHJvdG90eXBlLmF5PUV0LGkucHJvdG90eXBlLnV5PSgxPDxFdCktMSxpLnByb3RvdHlwZS5veT0xPDxFdDt2YXIga3Q9NTI7aS5wcm90b3R5cGUuVHk9TWF0aC5wb3coMixrdCksaS5wcm90b3R5cGUubXk9a3QtRXQsaS5wcm90b3R5cGUud3k9MipFdC1rdDt2YXIgQ3QsT3QsUHQ9XCIwMTIzNDU2Nzg5YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXpcIixBdD1uZXcgQXJyYXk7Zm9yKEN0PVwiMFwiLmNoYXJDb2RlQXQoMCksT3Q9MDtPdDw9OTsrK090KUF0W0N0KytdPU90O2ZvcihDdD1cImFcIi5jaGFyQ29kZUF0KDApLE90PTEwO090PDM2OysrT3QpQXRbQ3QrK109T3Q7Zm9yKEN0PVwiQVwiLmNoYXJDb2RlQXQoMCksT3Q9MTA7T3Q8MzY7KytPdClBdFtDdCsrXT1PdDtQLnByb3RvdHlwZS5feT1BLFAucHJvdG90eXBlLkx5PU4sUC5wcm90b3R5cGUucmVkdWNlPXgsUC5wcm90b3R5cGUuSHk9QixQLnByb3RvdHlwZS5EeT1GLEQucHJvdG90eXBlLl95PUgsRC5wcm90b3R5cGUuTHk9TCxELnByb3RvdHlwZS5yZWR1Y2U9TSxELnByb3RvdHlwZS5IeT1VLEQucHJvdG90eXBlLkR5PWosaS5wcm90b3R5cGUudnk9aCxpLnByb3RvdHlwZS5zeT1wLGkucHJvdG90eXBlLmV5PWwsaS5wcm90b3R5cGUuaHk9ZCxpLnByb3RvdHlwZS5TeT1ULGkucHJvdG90eXBlLkV5PVMsaS5wcm90b3R5cGUueXk9YixpLnByb3RvdHlwZS5JeT1FLGkucHJvdG90eXBlLnB5PUksaS5wcm90b3R5cGUuQ3k9UixpLnByb3RvdHlwZS5PeT1rLGkucHJvdG90eXBlLlJ5PUMsaS5wcm90b3R5cGUuQXk9XyxpLnByb3RvdHlwZS5NeT1WLGkucHJvdG90eXBlLmV4cD1RLGkucHJvdG90eXBlLnRvU3RyaW5nPWYsaS5wcm90b3R5cGUubHk9ZyxpLnByb3RvdHlwZS5hYnM9dixpLnByb3RvdHlwZS5ieT15LGkucHJvdG90eXBlLkt5PXcsaS5wcm90b3R5cGUua3k9TyxpLnByb3RvdHlwZS5KeT1xLGkuWkVSTz11KDApLGkuT05FPXUoMSksLyohIGFzbjEtMS4wLjkuanMgKGMpIDIwMTMtMjAxNSBLZW5qaSBVcnVzaGltYSB8IGtqdXIuZ2l0aHViLmNvbS9qc3JzYXNpZ24vbGljZW5zZVxuICAgKi9cbiAgXCJ1bmRlZmluZWRcIiE9dHlwZW9mIEtKVVImJktKVVJ8fChLSlVSPXt9KSxcInVuZGVmaW5lZFwiIT10eXBlb2YgS0pVUi5idyYmS0pVUi5id3x8KEtKVVIuYnc9e30pLEtKVVIuYncuRXc9bmV3IGZ1bmN0aW9uKCl7dGhpcy5Jdz1mdW5jdGlvbih0KXt2YXIgZT10LnRvU3RyaW5nKDE2KTtyZXR1cm4gZS5sZW5ndGglMj09MSYmKGU9XCIwXCIrZSksZX0sdGhpcy5Sdz1mdW5jdGlvbih0KXt2YXIgZT10LnRvU3RyaW5nKDE2KTtpZihcIi1cIiE9ZS5zdWJzdHIoMCwxKSllLmxlbmd0aCUyPT0xP2U9XCIwXCIrZTplLm1hdGNoKC9eWzAtN10vKXx8KGU9XCIwMFwiK2UpO2Vsc2V7dmFyIHI9ZS5zdWJzdHIoMSksbj1yLmxlbmd0aDtuJTI9PTE/bis9MTplLm1hdGNoKC9eWzAtN10vKXx8KG4rPTIpO2Zvcih2YXIgbz1cIlwiLHM9MDtzPG47cysrKW8rPVwiZlwiO3ZhciBhPW5ldyBpKG8sMTYpLGM9YS54b3IodCkuYWRkKGkuT05FKTtlPWMudG9TdHJpbmcoMTYpLnJlcGxhY2UoL14tLyxcIlwiKX1yZXR1cm4gZX0sdGhpcy5rdz1mdW5jdGlvbih0LGUpe3ZhciBpPShLSlVSLmJ3LGJ0LlltLlhtLnBhcnNlKHQpKSxyPWJ0LlltLkJhc2U2NC5zdHJpbmdpZnkoaSksbj1yLnJlcGxhY2UoLyguezY0fSkvZyxcIiQxXFxyXFxuXCIpO3JldHVybiBuPW4ucmVwbGFjZSgvXFxyXFxuJC8sXCJcIiksXCItLS0tLUJFR0lOIFwiK2UrXCItLS0tLVxcclxcblwiK24rXCJcXHJcXG4tLS0tLUVORCBcIitlK1wiLS0tLS1cXHJcXG5cIn0sdGhpcy5Ddz1mdW5jdGlvbih0KXt2YXIgZT1LSlVSLmJ3LGk9T2JqZWN0LmtleXModCk7aWYoMSE9aS5sZW5ndGgpdGhyb3dcImtleSBvZiBwYXJhbSBzaGFsbCBiZSBvbmx5IG9uZS5cIjt2YXIgcj1pWzBdO2lmKFwiOmJvb2w6aW50OmJpdHN0cjpvY3RzdHI6bnVsbDpvaWQ6ZW51bTp1dGY4c3RyOm51bXN0cjpwcm5zdHI6dGVsc3RyOmlhNXN0cjp1dGN0aW1lOmdlbnRpbWU6c2VxOnNldDp0YWc6XCIuaW5kZXhPZihcIjpcIityK1wiOlwiKT09LTEpdGhyb3dcInVuZGVmaW5lZCBrZXk6IFwiK3I7aWYoXCJib29sXCI9PXIpcmV0dXJuIG5ldyBlLk93KHRbcl0pO2lmKFwiaW50XCI9PXIpcmV0dXJuIG5ldyBlLlB3KHRbcl0pO2lmKFwiYml0c3RyXCI9PXIpcmV0dXJuIG5ldyBlLkF3KHRbcl0pO2lmKFwib2N0c3RyXCI9PXIpcmV0dXJuIG5ldyBlLk53KHRbcl0pO2lmKFwibnVsbFwiPT1yKXJldHVybiBuZXcgZS54dyh0W3JdKTtpZihcIm9pZFwiPT1yKXJldHVybiBuZXcgZS5Cdyh0W3JdKTtpZihcImVudW1cIj09cilyZXR1cm4gbmV3IGUuRncodFtyXSk7aWYoXCJ1dGY4c3RyXCI9PXIpcmV0dXJuIG5ldyBlLl93KHRbcl0pO2lmKFwibnVtc3RyXCI9PXIpcmV0dXJuIG5ldyBlLkR3KHRbcl0pO2lmKFwicHJuc3RyXCI9PXIpcmV0dXJuIG5ldyBlLkh3KHRbcl0pO2lmKFwidGVsc3RyXCI9PXIpcmV0dXJuIG5ldyBlLkx3KHRbcl0pO2lmKFwiaWE1c3RyXCI9PXIpcmV0dXJuIG5ldyBlLk13KHRbcl0pO2lmKFwidXRjdGltZVwiPT1yKXJldHVybiBuZXcgZS5qdyh0W3JdKTtpZihcImdlbnRpbWVcIj09cilyZXR1cm4gbmV3IGUuVXcodFtyXSk7aWYoXCJzZXFcIj09cil7Zm9yKHZhciBuPXRbcl0sbz1bXSxzPTA7czxuLmxlbmd0aDtzKyspe3ZhciBhPWUuRXcuQ3cobltzXSk7by5wdXNoKGEpfXJldHVybiBuZXcgZS5Wdyh7SGY6b30pfWlmKFwic2V0XCI9PXIpe2Zvcih2YXIgbj10W3JdLG89W10scz0wO3M8bi5sZW5ndGg7cysrKXt2YXIgYT1lLkV3LkN3KG5bc10pO28ucHVzaChhKX1yZXR1cm4gbmV3IGUuUXcoe0hmOm99KX1pZihcInRhZ1wiPT1yKXt2YXIgYz10W3JdO2lmKFwiW29iamVjdCBBcnJheV1cIj09PU9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChjKSYmMz09Yy5sZW5ndGgpe3ZhciBoPWUuRXcuQ3coY1syXSk7cmV0dXJuIG5ldyBlLnF3KHt0YWc6Y1swXSxKdzpjWzFdLEt3Omh9KX12YXIgcD17fTtpZih2b2lkIDAhPT1jLkp3JiYocC5Kdz1jLkp3KSx2b2lkIDAhPT1jLnRhZyYmKHAudGFnPWMudGFnKSx2b2lkIDA9PT1jLkt3KXRocm93XCJvYmogc2hhbGwgYmUgc3BlY2lmaWVkIGZvciAndGFnJy5cIjtyZXR1cm4gcC5Ldz1lLkV3LkN3KGMuS3cpLG5ldyBlLnF3KHApfX0sdGhpcy5Hdz1mdW5jdGlvbih0KXt2YXIgZT10aGlzLkN3KHQpO3JldHVybiBlLnp3KCl9fSxLSlVSLmJ3LkV3Lld3PWZ1bmN0aW9uKHQpe2Zvcih2YXIgZT1cIlwiLHI9cGFyc2VJbnQodC5zdWJzdHIoMCwyKSwxNiksbj1NYXRoLmZsb29yKHIvNDApLG89ciU0MCxlPW4rXCIuXCIrbyxzPVwiXCIsYT0yO2E8dC5sZW5ndGg7YSs9Mil7dmFyIGM9cGFyc2VJbnQodC5zdWJzdHIoYSwyKSwxNiksaD0oXCIwMDAwMDAwMFwiK2MudG9TdHJpbmcoMikpLnNsaWNlKC04KTtpZihzKz1oLnN1YnN0cigxLDcpLFwiMFwiPT1oLnN1YnN0cigwLDEpKXt2YXIgcD1uZXcgaShzLDIpO2U9ZStcIi5cIitwLnRvU3RyaW5nKDEwKSxzPVwiXCJ9fXJldHVybiBlfSxLSlVSLmJ3LkV3LiR3PWZ1bmN0aW9uKHQpe3ZhciBlPWZ1bmN0aW9uKHQpe3ZhciBlPXQudG9TdHJpbmcoMTYpO3JldHVybiAxPT1lLmxlbmd0aCYmKGU9XCIwXCIrZSksZX0scj1mdW5jdGlvbih0KXt2YXIgcj1cIlwiLG49bmV3IGkodCwxMCksbz1uLnRvU3RyaW5nKDIpLHM9Ny1vLmxlbmd0aCU3Ozc9PXMmJihzPTApO2Zvcih2YXIgYT1cIlwiLGM9MDtjPHM7YysrKWErPVwiMFwiO289YStvO2Zvcih2YXIgYz0wO2M8by5sZW5ndGgtMTtjKz03KXt2YXIgaD1vLnN1YnN0cihjLDcpO2MhPW8ubGVuZ3RoLTcmJihoPVwiMVwiK2gpLHIrPWUocGFyc2VJbnQoaCwyKSl9cmV0dXJuIHJ9O2lmKCF0Lm1hdGNoKC9eWzAtOS5dKyQvKSl0aHJvd1wibWFsZm9ybWVkIG9pZCBzdHJpbmc6IFwiK3Q7dmFyIG49XCJcIixvPXQuc3BsaXQoXCIuXCIpLHM9NDAqcGFyc2VJbnQob1swXSkrcGFyc2VJbnQob1sxXSk7bis9ZShzKSxvLnNwbGljZSgwLDIpO2Zvcih2YXIgYT0wO2E8by5sZW5ndGg7YSsrKW4rPXIob1thXSk7cmV0dXJuIG59LEtKVVIuYncuWXc9ZnVuY3Rpb24oKXt2YXIgdD1cIlwiO3RoaXMuWHc9ZnVuY3Rpb24oKXtpZihcInVuZGVmaW5lZFwiPT10eXBlb2YgdGhpcy5ad3x8bnVsbD09dGhpcy5adyl0aHJvd1widGhpcy5oViBpcyBudWxsIG9yIHVuZGVmaW5lZC5cIjtpZih0aGlzLlp3Lmxlbmd0aCUyPT0xKXRocm93XCJ2YWx1ZSBoZXggbXVzdCBiZSBldmVuIGxlbmd0aDogbj1cIit0Lmxlbmd0aCtcIix2PVwiK3RoaXMuWnc7dmFyIGU9dGhpcy5ady5sZW5ndGgvMixpPWUudG9TdHJpbmcoMTYpO2lmKGkubGVuZ3RoJTI9PTEmJihpPVwiMFwiK2kpLGU8MTI4KXJldHVybiBpO3ZhciByPWkubGVuZ3RoLzI7aWYocj4xNSl0aHJvd1wiQVNOLjEgbGVuZ3RoIHRvbyBsb25nIHRvIHJlcHJlc2VudCBieSA4eDogbiA9IFwiK2UudG9TdHJpbmcoMTYpO3ZhciBuPTEyOCtyO3JldHVybiBuLnRvU3RyaW5nKDE2KStpfSx0aGlzLnp3PWZ1bmN0aW9uKCl7cmV0dXJuKG51bGw9PXRoaXMudFR8fHRoaXMuZVQpJiYodGhpcy5adz10aGlzLmlUKCksdGhpcy5yVD10aGlzLlh3KCksdGhpcy50VD10aGlzLm5UK3RoaXMuclQrdGhpcy5adyx0aGlzLmVUPSExKSx0aGlzLnRUfSx0aGlzLm9UPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuencoKSx0aGlzLlp3fSx0aGlzLmlUPWZ1bmN0aW9uKCl7cmV0dXJuXCJcIn19LEtKVVIuYncuc1Q9ZnVuY3Rpb24odCl7S0pVUi5idy5zVC5EbS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpO3RoaXMuYVQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ueX0sdGhpcy5jVD1mdW5jdGlvbih0KXt0aGlzLnRUPW51bGwsdGhpcy5lVD0hMCx0aGlzLm55PXQsdGhpcy5adz1zdG9oZXgodGhpcy5ueSl9LHRoaXMuaFQ9ZnVuY3Rpb24odCl7dGhpcy50VD1udWxsLHRoaXMuZVQ9ITAsdGhpcy5ueT1udWxsLHRoaXMuWnc9dH0sdGhpcy5pVD1mdW5jdGlvbigpe3JldHVybiB0aGlzLlp3fSxcInVuZGVmaW5lZFwiIT10eXBlb2YgdCYmKFwic3RyaW5nXCI9PXR5cGVvZiB0P3RoaXMuY1QodCk6XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQuYWM/dGhpcy5jVCh0LmFjKTpcInVuZGVmaW5lZFwiIT10eXBlb2YgdC5wVCYmdGhpcy5oVCh0LnBUKSl9LFN0LmxhbmcuZXh0ZW5kKEtKVVIuYncuc1QsS0pVUi5idy5ZdyksS0pVUi5idy51VD1mdW5jdGlvbih0KXtLSlVSLmJ3LnVULkRtLmNvbnN0cnVjdG9yLmNhbGwodGhpcyk7dGhpcy5sVD1mdW5jdGlvbih0KXt1dGM9dC5nZXRUaW1lKCkrNmU0KnQuZ2V0VGltZXpvbmVPZmZzZXQoKTt2YXIgZT1uZXcgRGF0ZSh1dGMpO3JldHVybiBlfSx0aGlzLmRUPWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj10aGlzLmZULG49dGhpcy5sVCh0KSxvPVN0cmluZyhuLmdldEZ1bGxZZWFyKCkpO1widXRjXCI9PWUmJihvPW8uc3Vic3RyKDIsMikpO3ZhciBzPXIoU3RyaW5nKG4uZ2V0TW9udGgoKSsxKSwyKSxhPXIoU3RyaW5nKG4uZ2V0RGF0ZSgpKSwyKSxjPXIoU3RyaW5nKG4uZ2V0SG91cnMoKSksMiksaD1yKFN0cmluZyhuLmdldE1pbnV0ZXMoKSksMikscD1yKFN0cmluZyhuLmdldFNlY29uZHMoKSksMiksdT1vK3MrYStjK2grcDtpZihpPT09ITApe3ZhciBsPW4uZ2V0TWlsbGlzZWNvbmRzKCk7aWYoMCE9bCl7dmFyIGQ9cihTdHJpbmcobCksMyk7ZD1kLnJlcGxhY2UoL1swXSskLyxcIlwiKSx1PXUrXCIuXCIrZH19cmV0dXJuIHUrXCJaXCJ9LHRoaXMuZlQ9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdC5sZW5ndGg+PWU/dDpuZXcgQXJyYXkoZS10Lmxlbmd0aCsxKS5qb2luKFwiMFwiKSt0fSx0aGlzLmFUPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubnl9LHRoaXMuY1Q9ZnVuY3Rpb24odCl7dGhpcy50VD1udWxsLHRoaXMuZVQ9ITAsdGhpcy5ueT10LHRoaXMuWnc9c3RvaGV4KHQpfSx0aGlzLmdUPWZ1bmN0aW9uKHQsZSxpLHIsbixvKXt2YXIgcz1uZXcgRGF0ZShEYXRlLlVUQyh0LGUtMSxpLHIsbixvLDApKTt0aGlzLnZUKHMpfSx0aGlzLmlUPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuWnd9fSxTdC5sYW5nLmV4dGVuZChLSlVSLmJ3LnVULEtKVVIuYncuWXcpLEtKVVIuYncueVQ9ZnVuY3Rpb24odCl7S0pVUi5idy5zVC5EbS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpO3RoaXMubVQ9ZnVuY3Rpb24odCl7dGhpcy50VD1udWxsLHRoaXMuZVQ9ITAsdGhpcy53VD10fSx0aGlzLlRUPWZ1bmN0aW9uKHQpe3RoaXMudFQ9bnVsbCx0aGlzLmVUPSEwLHRoaXMud1QucHVzaCh0KX0sdGhpcy53VD1uZXcgQXJyYXksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiB0LkhmJiYodGhpcy53VD10LkhmKX0sU3QubGFuZy5leHRlbmQoS0pVUi5idy55VCxLSlVSLmJ3Lll3KSxLSlVSLmJ3Lk93PWZ1bmN0aW9uKCl7S0pVUi5idy5Pdy5EbS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpLHRoaXMublQ9XCIwMVwiLHRoaXMudFQ9XCIwMTAxZmZcIn0sU3QubGFuZy5leHRlbmQoS0pVUi5idy5PdyxLSlVSLmJ3Lll3KSxLSlVSLmJ3LlB3PWZ1bmN0aW9uKHQpe0tKVVIuYncuUHcuRG0uY29uc3RydWN0b3IuY2FsbCh0aGlzKSx0aGlzLm5UPVwiMDJcIix0aGlzLlNUPWZ1bmN0aW9uKHQpe3RoaXMudFQ9bnVsbCx0aGlzLmVUPSEwLHRoaXMuWnc9S0pVUi5idy5Fdy5Sdyh0KX0sdGhpcy5iVD1mdW5jdGlvbih0KXt2YXIgZT1uZXcgaShTdHJpbmcodCksMTApO3RoaXMuU1QoZSl9LHRoaXMuRVQ9ZnVuY3Rpb24odCl7dGhpcy5adz10fSx0aGlzLmlUPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuWnd9LFwidW5kZWZpbmVkXCIhPXR5cGVvZiB0JiYoXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQuYmlnaW50P3RoaXMuU1QodC5iaWdpbnQpOlwidW5kZWZpbmVkXCIhPXR5cGVvZiB0W1wiaW50XCJdP3RoaXMuYlQodFtcImludFwiXSk6XCJudW1iZXJcIj09dHlwZW9mIHQ/dGhpcy5iVCh0KTpcInVuZGVmaW5lZFwiIT10eXBlb2YgdC5wVCYmdGhpcy5FVCh0LnBUKSl9LFN0LmxhbmcuZXh0ZW5kKEtKVVIuYncuUHcsS0pVUi5idy5ZdyksS0pVUi5idy5Bdz1mdW5jdGlvbih0KXtLSlVSLmJ3LkF3LkRtLmNvbnN0cnVjdG9yLmNhbGwodGhpcyksdGhpcy5uVD1cIjAzXCIsdGhpcy5JVD1mdW5jdGlvbih0KXt0aGlzLnRUPW51bGwsdGhpcy5lVD0hMCx0aGlzLlp3PXR9LHRoaXMuUlQ9ZnVuY3Rpb24odCxlKXtpZih0PDB8fDc8dCl0aHJvd1widW51c2VkIGJpdHMgc2hhbGwgYmUgZnJvbSAwIHRvIDc6IHUgPSBcIit0O3ZhciBpPVwiMFwiK3Q7dGhpcy50VD1udWxsLHRoaXMuZVQ9ITAsdGhpcy5adz1pK2V9LHRoaXMua1Q9ZnVuY3Rpb24odCl7dD10LnJlcGxhY2UoLzArJC8sXCJcIik7dmFyIGU9OC10Lmxlbmd0aCU4Ozg9PWUmJihlPTApO2Zvcih2YXIgaT0wO2k8PWU7aSsrKXQrPVwiMFwiO2Zvcih2YXIgcj1cIlwiLGk9MDtpPHQubGVuZ3RoLTE7aSs9OCl7dmFyIG49dC5zdWJzdHIoaSw4KSxvPXBhcnNlSW50KG4sMikudG9TdHJpbmcoMTYpOzE9PW8ubGVuZ3RoJiYobz1cIjBcIitvKSxyKz1vfXRoaXMudFQ9bnVsbCx0aGlzLmVUPSEwLHRoaXMuWnc9XCIwXCIrZStyfSx0aGlzLkNUPWZ1bmN0aW9uKHQpe2Zvcih2YXIgZT1cIlwiLGk9MDtpPHQubGVuZ3RoO2krKyllKz0xPT10W2ldP1wiMVwiOlwiMFwiO3RoaXMua1QoZSl9LHRoaXMuT1Q9ZnVuY3Rpb24odCl7Zm9yKHZhciBlPW5ldyBBcnJheSh0KSxpPTA7aTx0O2krKyllW2ldPSExO3JldHVybiBlfSx0aGlzLmlUPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuWnd9LFwidW5kZWZpbmVkXCIhPXR5cGVvZiB0JiYoXCJzdHJpbmdcIj09dHlwZW9mIHQmJnQudG9Mb3dlckNhc2UoKS5tYXRjaCgvXlswLTlhLWZdKyQvKT90aGlzLklUKHQpOlwidW5kZWZpbmVkXCIhPXR5cGVvZiB0LnBUP3RoaXMuSVQodC5wVCk6XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQuYmluP3RoaXMua1QodC5iaW4pOlwidW5kZWZpbmVkXCIhPXR5cGVvZiB0LkhmJiZ0aGlzLkNUKHQuSGYpKX0sU3QubGFuZy5leHRlbmQoS0pVUi5idy5BdyxLSlVSLmJ3Lll3KSxLSlVSLmJ3Lk53PWZ1bmN0aW9uKHQpe0tKVVIuYncuTncuRG0uY29uc3RydWN0b3IuY2FsbCh0aGlzLHQpLHRoaXMublQ9XCIwNFwifSxTdC5sYW5nLmV4dGVuZChLSlVSLmJ3Lk53LEtKVVIuYncuc1QpLEtKVVIuYncueHc9ZnVuY3Rpb24oKXtLSlVSLmJ3Lnh3LkRtLmNvbnN0cnVjdG9yLmNhbGwodGhpcyksdGhpcy5uVD1cIjA1XCIsdGhpcy50VD1cIjA1MDBcIn0sU3QubGFuZy5leHRlbmQoS0pVUi5idy54dyxLSlVSLmJ3Lll3KSxLSlVSLmJ3LkJ3PWZ1bmN0aW9uKHQpe3ZhciBlPWZ1bmN0aW9uKHQpe3ZhciBlPXQudG9TdHJpbmcoMTYpO3JldHVybiAxPT1lLmxlbmd0aCYmKGU9XCIwXCIrZSksZX0scj1mdW5jdGlvbih0KXt2YXIgcj1cIlwiLG49bmV3IGkodCwxMCksbz1uLnRvU3RyaW5nKDIpLHM9Ny1vLmxlbmd0aCU3Ozc9PXMmJihzPTApO2Zvcih2YXIgYT1cIlwiLGM9MDtjPHM7YysrKWErPVwiMFwiO289YStvO2Zvcih2YXIgYz0wO2M8by5sZW5ndGgtMTtjKz03KXt2YXIgaD1vLnN1YnN0cihjLDcpO2MhPW8ubGVuZ3RoLTcmJihoPVwiMVwiK2gpLHIrPWUocGFyc2VJbnQoaCwyKSl9cmV0dXJuIHJ9O0tKVVIuYncuQncuRG0uY29uc3RydWN0b3IuY2FsbCh0aGlzKSx0aGlzLm5UPVwiMDZcIix0aGlzLkVUPWZ1bmN0aW9uKHQpe3RoaXMudFQ9bnVsbCx0aGlzLmVUPSEwLHRoaXMubnk9bnVsbCx0aGlzLlp3PXR9LHRoaXMuUFQ9ZnVuY3Rpb24odCl7aWYoIXQubWF0Y2goL15bMC05Ll0rJC8pKXRocm93XCJtYWxmb3JtZWQgb2lkIHN0cmluZzogXCIrdDt2YXIgaT1cIlwiLG49dC5zcGxpdChcIi5cIiksbz00MCpwYXJzZUludChuWzBdKStwYXJzZUludChuWzFdKTtpKz1lKG8pLG4uc3BsaWNlKDAsMik7Zm9yKHZhciBzPTA7czxuLmxlbmd0aDtzKyspaSs9cihuW3NdKTt0aGlzLnRUPW51bGwsdGhpcy5lVD0hMCx0aGlzLm55PW51bGwsdGhpcy5adz1pfSx0aGlzLkFUPWZ1bmN0aW9uKHQpe2lmKFwidW5kZWZpbmVkXCI9PXR5cGVvZiBLSlVSLmJ3Lng1MDkuTlQubmFtZTJvaWRMaXN0W3RdKXRocm93XCJERVJPYmplY3RJZGVudGlmaWVyIG9pZE5hbWUgdW5kZWZpbmVkOiBcIit0O3ZhciBlPUtKVVIuYncueDUwOS5OVC5uYW1lMm9pZExpc3RbdF07dGhpcy5QVChlKX0sdGhpcy5pVD1mdW5jdGlvbigpe3JldHVybiB0aGlzLlp3fSxcInVuZGVmaW5lZFwiIT10eXBlb2YgdCYmKFwic3RyaW5nXCI9PXR5cGVvZiB0JiZ0Lm1hdGNoKC9eWzAtMl0uWzAtOS5dKyQvKT90aGlzLlBUKHQpOnZvaWQgMCE9PUtKVVIuYncueDUwOS5OVC5uYW1lMm9pZExpc3RbdF0/dGhpcy5QVChLSlVSLmJ3Lng1MDkuTlQubmFtZTJvaWRMaXN0W3RdKTpcInVuZGVmaW5lZFwiIT10eXBlb2YgdC5vaWQ/dGhpcy5QVCh0Lm9pZCk6XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQucFQ/dGhpcy5FVCh0LnBUKTpcInVuZGVmaW5lZFwiIT10eXBlb2YgdC5uYW1lJiZ0aGlzLkFUKHQubmFtZSkpfSxTdC5sYW5nLmV4dGVuZChLSlVSLmJ3LkJ3LEtKVVIuYncuWXcpLEtKVVIuYncuRnc9ZnVuY3Rpb24odCl7S0pVUi5idy5Gdy5EbS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMpLHRoaXMublQ9XCIwYVwiLHRoaXMuU1Q9ZnVuY3Rpb24odCl7dGhpcy50VD1udWxsLHRoaXMuZVQ9ITAsdGhpcy5adz1LSlVSLmJ3LkV3LlJ3KHQpfSx0aGlzLmJUPWZ1bmN0aW9uKHQpe3ZhciBlPW5ldyBpKFN0cmluZyh0KSwxMCk7dGhpcy5TVChlKX0sdGhpcy5FVD1mdW5jdGlvbih0KXt0aGlzLlp3PXR9LHRoaXMuaVQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ad30sXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQmJihcInVuZGVmaW5lZFwiIT10eXBlb2YgdFtcImludFwiXT90aGlzLmJUKHRbXCJpbnRcIl0pOlwibnVtYmVyXCI9PXR5cGVvZiB0P3RoaXMuYlQodCk6XCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQucFQmJnRoaXMuRVQodC5wVCkpfSxTdC5sYW5nLmV4dGVuZChLSlVSLmJ3LkZ3LEtKVVIuYncuWXcpLEtKVVIuYncuX3c9ZnVuY3Rpb24odCl7S0pVUi5idy5fdy5EbS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsdCksdGhpcy5uVD1cIjBjXCJ9LFN0LmxhbmcuZXh0ZW5kKEtKVVIuYncuX3csS0pVUi5idy5zVCksS0pVUi5idy5Edz1mdW5jdGlvbih0KXtLSlVSLmJ3LkR3LkRtLmNvbnN0cnVjdG9yLmNhbGwodGhpcyx0KSx0aGlzLm5UPVwiMTJcIn0sU3QubGFuZy5leHRlbmQoS0pVUi5idy5EdyxLSlVSLmJ3LnNUKSxLSlVSLmJ3Lkh3PWZ1bmN0aW9uKHQpe0tKVVIuYncuSHcuRG0uY29uc3RydWN0b3IuY2FsbCh0aGlzLHQpLHRoaXMublQ9XCIxM1wifSxTdC5sYW5nLmV4dGVuZChLSlVSLmJ3Lkh3LEtKVVIuYncuc1QpLEtKVVIuYncuTHc9ZnVuY3Rpb24odCl7S0pVUi5idy5Mdy5EbS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsdCksdGhpcy5uVD1cIjE0XCJ9LFN0LmxhbmcuZXh0ZW5kKEtKVVIuYncuTHcsS0pVUi5idy5zVCksS0pVUi5idy5Ndz1mdW5jdGlvbih0KXtLSlVSLmJ3Lk13LkRtLmNvbnN0cnVjdG9yLmNhbGwodGhpcyx0KSx0aGlzLm5UPVwiMTZcIn0sU3QubGFuZy5leHRlbmQoS0pVUi5idy5NdyxLSlVSLmJ3LnNUKSxLSlVSLmJ3Lmp3PWZ1bmN0aW9uKHQpe0tKVVIuYncuancuRG0uY29uc3RydWN0b3IuY2FsbCh0aGlzLHQpLHRoaXMublQ9XCIxN1wiLHRoaXMudlQ9ZnVuY3Rpb24odCl7dGhpcy50VD1udWxsLHRoaXMuZVQ9ITAsdGhpcy54VD10LHRoaXMubnk9dGhpcy5kVCh0aGlzLnhULFwidXRjXCIpLHRoaXMuWnc9c3RvaGV4KHRoaXMubnkpfSx0aGlzLmlUPWZ1bmN0aW9uKCl7cmV0dXJuXCJ1bmRlZmluZWRcIj09dHlwZW9mIHRoaXMueFQmJlwidW5kZWZpbmVkXCI9PXR5cGVvZiB0aGlzLm55JiYodGhpcy54VD1uZXcgRGF0ZSx0aGlzLm55PXRoaXMuZFQodGhpcy54VCxcInV0Y1wiKSx0aGlzLlp3PXN0b2hleCh0aGlzLm55KSksdGhpcy5ad30sdm9pZCAwIT09dCYmKHZvaWQgMCE9PXQuYWM/dGhpcy5jVCh0LmFjKTpcInN0cmluZ1wiPT10eXBlb2YgdCYmdC5tYXRjaCgvXlswLTldezEyfVokLyk/dGhpcy5jVCh0KTp2b2lkIDAhPT10LnBUP3RoaXMuaFQodC5wVCk6dm9pZCAwIT09dC54VCYmdGhpcy52VCh0LnhUKSl9LFN0LmxhbmcuZXh0ZW5kKEtKVVIuYncuancsS0pVUi5idy51VCksS0pVUi5idy5Vdz1mdW5jdGlvbih0KXtLSlVSLmJ3LlV3LkRtLmNvbnN0cnVjdG9yLmNhbGwodGhpcyx0KSx0aGlzLm5UPVwiMThcIix0aGlzLkJUPSExLHRoaXMudlQ9ZnVuY3Rpb24odCl7dGhpcy50VD1udWxsLHRoaXMuZVQ9ITAsdGhpcy54VD10LHRoaXMubnk9dGhpcy5kVCh0aGlzLnhULFwiZ2VuXCIsdGhpcy5CVCksdGhpcy5adz1zdG9oZXgodGhpcy5ueSl9LHRoaXMuaVQ9ZnVuY3Rpb24oKXtyZXR1cm4gdm9pZCAwPT09dGhpcy54VCYmdm9pZCAwPT09dGhpcy5ueSYmKHRoaXMueFQ9bmV3IERhdGUsdGhpcy5ueT10aGlzLmRUKHRoaXMueFQsXCJnZW5cIix0aGlzLkJUKSx0aGlzLlp3PXN0b2hleCh0aGlzLm55KSksdGhpcy5ad30sdm9pZCAwIT09dCYmKHZvaWQgMCE9PXQuYWM/dGhpcy5jVCh0LmFjKTpcInN0cmluZ1wiPT10eXBlb2YgdCYmdC5tYXRjaCgvXlswLTldezE0fVokLyk/dGhpcy5jVCh0KTp2b2lkIDAhPT10LnBUP3RoaXMuaFQodC5wVCk6dm9pZCAwIT09dC54VCYmdGhpcy52VCh0LnhUKSx0Lm1pbGxpcz09PSEwJiYodGhpcy5CVD0hMCkpfSxTdC5sYW5nLmV4dGVuZChLSlVSLmJ3LlV3LEtKVVIuYncudVQpLEtKVVIuYncuVnc9ZnVuY3Rpb24odCl7S0pVUi5idy5Wdy5EbS5jb25zdHJ1Y3Rvci5jYWxsKHRoaXMsdCksdGhpcy5uVD1cIjMwXCIsdGhpcy5pVD1mdW5jdGlvbigpe2Zvcih2YXIgdD1cIlwiLGU9MDtlPHRoaXMud1QubGVuZ3RoO2UrKyl7dmFyIGk9dGhpcy53VFtlXTt0Kz1pLnp3KCl9cmV0dXJuIHRoaXMuWnc9dCx0aGlzLlp3fX0sU3QubGFuZy5leHRlbmQoS0pVUi5idy5WdyxLSlVSLmJ3LnlUKSxLSlVSLmJ3LlF3PWZ1bmN0aW9uKHQpe0tKVVIuYncuUXcuRG0uY29uc3RydWN0b3IuY2FsbCh0aGlzLHQpLHRoaXMublQ9XCIzMVwiLHRoaXMuRlQ9ITAsdGhpcy5pVD1mdW5jdGlvbigpe2Zvcih2YXIgdD1uZXcgQXJyYXksZT0wO2U8dGhpcy53VC5sZW5ndGg7ZSsrKXt2YXIgaT10aGlzLndUW2VdO3QucHVzaChpLnp3KCkpfXJldHVybiAxPT10aGlzLkZUJiZ0LnNvcnQoKSx0aGlzLlp3PXQuam9pbihcIlwiKSx0aGlzLlp3fSxcInVuZGVmaW5lZFwiIT10eXBlb2YgdCYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQuc29ydGZsYWcmJjA9PXQuc29ydGZsYWcmJih0aGlzLkZUPSExKX0sU3QubGFuZy5leHRlbmQoS0pVUi5idy5RdyxLSlVSLmJ3LnlUKSxLSlVSLmJ3LnF3PWZ1bmN0aW9uKHQpe0tKVVIuYncucXcuRG0uY29uc3RydWN0b3IuY2FsbCh0aGlzKSx0aGlzLm5UPVwiYTBcIix0aGlzLlp3PVwiXCIsdGhpcy5fVD0hMCx0aGlzLkRUPW51bGwsdGhpcy5IVD1mdW5jdGlvbih0LGUsaSl7dGhpcy5uVD1lLHRoaXMuX1Q9dCx0aGlzLkRUPWksdGhpcy5fVD8odGhpcy5adz10aGlzLkRULnp3KCksdGhpcy50VD1udWxsLHRoaXMuZVQ9ITApOih0aGlzLlp3PW51bGwsdGhpcy50VD1pLnp3KCksdGhpcy50VD10aGlzLnRULnJlcGxhY2UoL14uLi8sZSksdGhpcy5lVD0hMSl9LHRoaXMuaVQ9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ad30sXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQmJihcInVuZGVmaW5lZFwiIT10eXBlb2YgdC50YWcmJih0aGlzLm5UPXQudGFnKSxcInVuZGVmaW5lZFwiIT10eXBlb2YgdC5KdyYmKHRoaXMuX1Q9dC5KdyksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHQuS3cmJih0aGlzLkRUPXQuS3csdGhpcy5IVCh0aGlzLl9ULHRoaXMublQsdGhpcy5EVCkpKX0sU3QubGFuZy5leHRlbmQoS0pVUi5idy5xdyxLSlVSLmJ3Lll3KTsvKiEgKGMpIFRvbSBXdSB8IGh0dHA6Ly93d3ctY3Mtc3R1ZGVudHMuc3RhbmZvcmQuZWR1L350ancvanNibi8gKi9cbiAgdmFyIE50PVwiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrL1wiLHh0PVwiPVwiOy8qISBjcnlwdG8tMS4xLjguanMgKGMpIDIwMTMtMjAxNiBLZW5qaSBVcnVzaGltYSB8IGtqdXIuZ2l0aHViLmNvbS9qc3JzYXNpZ24vbGljZW5zZVxuICAgKi9cbiAgXCJ1bmRlZmluZWRcIiE9dHlwZW9mIEtKVVImJktKVVJ8fChLSlVSPXt9KSxcInVuZGVmaW5lZFwiIT10eXBlb2YgS0pVUi5jcnlwdG8mJktKVVIuY3J5cHRvfHwoS0pVUi5jcnlwdG89e30pLEtKVVIuY3J5cHRvLld5PW5ldyBmdW5jdGlvbigpe3RoaXMudG09e3NoYTE6XCIzMDIxMzAwOTA2MDUyYjBlMDMwMjFhMDUwMDA0MTRcIixMVDpcIjMwMmQzMDBkMDYwOTYwODY0ODAxNjUwMzA0MDIwNDA1MDAwNDFjXCIsc2hhMjU2OlwiMzAzMTMwMGQwNjA5NjA4NjQ4MDE2NTAzMDQwMjAxMDUwMDA0MjBcIixNVDpcIjMwNDEzMDBkMDYwOTYwODY0ODAxNjUwMzA0MDIwMjA1MDAwNDMwXCIsalQ6XCIzMDUxMzAwZDA2MDk2MDg2NDgwMTY1MDMwNDAyMDMwNTAwMDQ0MFwiLFVUOlwiMzAyMDMwMGMwNjA4MmE4NjQ4ODZmNzBkMDIwMjA1MDAwNDEwXCIsVlQ6XCIzMDIwMzAwYzA2MDgyYTg2NDg4NmY3MGQwMjA1MDUwMDA0MTBcIixRVDpcIjMwMjEzMDA5MDYwNTJiMjQwMzAyMDEwNTAwMDQxNFwifSx0aGlzLnFUPXtWVDpcImNyeXB0b2pzXCIsc2hhMTpcImNyeXB0b2pzXCIsTFQ6XCJjcnlwdG9qc1wiLHNoYTI1NjpcImNyeXB0b2pzXCIsTVQ6XCJjcnlwdG9qc1wiLGpUOlwiY3J5cHRvanNcIixRVDpcImNyeXB0b2pzXCIsSlQ6XCJjcnlwdG9qc1wiLEtUOlwiY3J5cHRvanNcIixHVDpcImNyeXB0b2pzXCIselQ6XCJjcnlwdG9qc1wiLFdUOlwiY3J5cHRvanNcIiwkVDpcImNyeXB0b2pzXCIsWVQ6XCJjcnlwdG9qc1wiLFhUOlwiY3J5cHRvanMvanNyc2FcIixaVDpcImNyeXB0b2pzL2pzcnNhXCIsdFM6XCJjcnlwdG9qcy9qc3JzYVwiLGVTOlwiY3J5cHRvanMvanNyc2FcIixpUzpcImNyeXB0b2pzL2pzcnNhXCIsclM6XCJjcnlwdG9qcy9qc3JzYVwiLG5TOlwiY3J5cHRvanMvanNyc2FcIixvUzpcImNyeXB0b2pzL2pzcnNhXCIsc1M6XCJjcnlwdG9qcy9qc3JzYVwiLGFTOlwiY3J5cHRvanMvanNyc2FcIixjUzpcImNyeXB0b2pzL2pzcnNhXCIsaFM6XCJjcnlwdG9qcy9qc3JzYVwiLHBTOlwiY3J5cHRvanMvanNyc2FcIix1UzpcImNyeXB0b2pzL2pzcnNhXCIsbFM6XCJjcnlwdG9qcy9qc3JzYVwiLGRTOlwiY3J5cHRvanMvanNyc2FcIixmUzpcImNyeXB0b2pzL2pzcnNhXCIsZ1M6XCJjcnlwdG9qcy9qc3JzYVwiLHZTOlwiY3J5cHRvanMvanNyc2FcIix5UzpcImNyeXB0b2pzL2pzcnNhXCIsbVM6XCJjcnlwdG9qcy9qc3JzYVwiLHdTOlwiY3J5cHRvanMvanNyc2FcIixUUzpcImNyeXB0b2pzL2pzcnNhXCIsU1M6XCJjcnlwdG9qcy9qc3JzYVwifSx0aGlzLmJTPXtWVDpidC52dy55dyxzaGExOmJ0LnZ3LlR3LExUOmJ0LnZ3LlNIQTIyNCxzaGEyNTY6YnQudncuU0hBMjU2LE1UOmJ0LnZ3LlNIQTM4NCxqVDpidC52dy5TSEE1MTIsUVQ6YnQudncuUklQRU1EMTYwfSx0aGlzLkVTPWZ1bmN0aW9uKHQsZSl7aWYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIHRoaXMudG1bZV0pdGhyb3dcImFsZyBub3Qgc3VwcG9ydGVkIGluIFV0aWwuRElHRVNUSU5GT0hFQUQ6IFwiK2U7cmV0dXJuIHRoaXMudG1bZV0rdH0sdGhpcy5ZeT1mdW5jdGlvbih0LGUsaSl7dmFyIHI9dGhpcy5FUyh0LGUpLG49aS80O2lmKHIubGVuZ3RoKzIyPm4pdGhyb3dcImtleSBpcyB0b28gc2hvcnQgZm9yIFNpZ0FsZzoga2V5bGVuPVwiK2krXCIsXCIrZTtmb3IodmFyIG89XCIwMDAxXCIscz1cIjAwXCIrcixhPVwiXCIsYz1uLW8ubGVuZ3RoLXMubGVuZ3RoLGg9MDtoPGM7aCs9MilhKz1cImZmXCI7dmFyIHA9bythK3M7cmV0dXJuIHB9LHRoaXMuenk9ZnVuY3Rpb24odCxlKXt2YXIgaT1uZXcgS0pVUi5jcnlwdG8uSVMoe1JTOmV9KTtyZXR1cm4gaS5rUyh0KX0sdGhpcy5YeT1mdW5jdGlvbih0LGUpe3ZhciBpPW5ldyBLSlVSLmNyeXB0by5JUyh7UlM6ZX0pO3JldHVybiBpLkNTKHQpfSx0aGlzLnNoYTE9ZnVuY3Rpb24odCl7dmFyIGU9bmV3IEtKVVIuY3J5cHRvLklTKHtSUzpcInNoYTFcIixPUzpcImNyeXB0b2pzXCJ9KTtyZXR1cm4gZS5rUyh0KX0sdGhpcy5zaGEyNTY9ZnVuY3Rpb24odCl7dmFyIGU9bmV3IEtKVVIuY3J5cHRvLklTKHtSUzpcInNoYTI1NlwiLE9TOlwiY3J5cHRvanNcIn0pO3JldHVybiBlLmtTKHQpfSx0aGlzLlBTPWZ1bmN0aW9uKHQpe3ZhciBlPW5ldyBLSlVSLmNyeXB0by5JUyh7UlM6XCJzaGEyNTZcIixPUzpcImNyeXB0b2pzXCJ9KTtyZXR1cm4gZS5DUyh0KX0sdGhpcy5qVD1mdW5jdGlvbih0KXt2YXIgZT1uZXcgS0pVUi5jcnlwdG8uSVMoe1JTOlwic2hhNTEyXCIsT1M6XCJjcnlwdG9qc1wifSk7cmV0dXJuIGUua1ModCl9LHRoaXMuTlM9ZnVuY3Rpb24odCl7dmFyIGU9bmV3IEtKVVIuY3J5cHRvLklTKHtSUzpcInNoYTUxMlwiLE9TOlwiY3J5cHRvanNcIn0pO3JldHVybiBlLkNTKHQpfSx0aGlzLlZUPWZ1bmN0aW9uKHQpe3ZhciBlPW5ldyBLSlVSLmNyeXB0by5JUyh7UlM6XCJtZDVcIixPUzpcImNyeXB0b2pzXCJ9KTtyZXR1cm4gZS5rUyh0KX0sdGhpcy5RVD1mdW5jdGlvbih0KXt2YXIgZT1uZXcgS0pVUi5jcnlwdG8uSVMoe1JTOlwicmlwZW1kMTYwXCIsT1M6XCJjcnlwdG9qc1wifSk7cmV0dXJuIGUua1ModCl9LHRoaXMueFM9ZnVuY3Rpb24odCl7fX0sS0pVUi5jcnlwdG8uSVM9ZnVuY3Rpb24odCl7dGhpcy5CUz1mdW5jdGlvbih0LGUpe2lmKG51bGwhPXQmJnZvaWQgMD09PWUmJihlPUtKVVIuY3J5cHRvLld5LnFUW3RdKSxcIjptZDU6c2hhMTpzaGEyMjQ6c2hhMjU2OnNoYTM4NDpzaGE1MTI6cmlwZW1kMTYwOlwiLmluZGV4T2YodCkhPS0xJiZcImNyeXB0b2pzXCI9PWUpe3RyeXt0aGlzLkZTPUtKVVIuY3J5cHRvLld5LmJTW3RdLmNyZWF0ZSgpfWNhdGNoKGkpe3Rocm93XCJzZXRBbGdBbmRQcm92aWRlciBoYXNoIGFsZyBzZXQgZmFpbCBhbGc9XCIrdCtcIi9cIitpfXRoaXMuX1M9ZnVuY3Rpb24odCl7dGhpcy5GUy51cGRhdGUodCl9LHRoaXMuRFM9ZnVuY3Rpb24odCl7dmFyIGU9YnQuWW0uWG0ucGFyc2UodCk7dGhpcy5GUy51cGRhdGUoZSl9LHRoaXMuZGlnZXN0PWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5GUy5sdygpO3JldHVybiB0LnRvU3RyaW5nKGJ0LlltLlhtKX0sdGhpcy5rUz1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5fUyh0KSx0aGlzLmRpZ2VzdCgpfSx0aGlzLkNTPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLkRTKHQpLHRoaXMuZGlnZXN0KCl9fWlmKFwiOnNoYTI1NjpcIi5pbmRleE9mKHQpIT0tMSYmXCJzamNsXCI9PWUpe3RyeXt0aGlzLkZTPW5ldyBzamNsLmhhc2guc2hhMjU2fWNhdGNoKGkpe3Rocm93XCJzZXRBbGdBbmRQcm92aWRlciBoYXNoIGFsZyBzZXQgZmFpbCBhbGc9XCIrdCtcIi9cIitpfXRoaXMuX1M9ZnVuY3Rpb24odCl7dGhpcy5GUy51cGRhdGUodCl9LHRoaXMuRFM9ZnVuY3Rpb24odCl7dmFyIGU9c2pjbC5jb2RlYy5wVC50b0JpdHModCk7dGhpcy5GUy51cGRhdGUoZSl9LHRoaXMuZGlnZXN0PWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5GUy5sdygpO3JldHVybiBzamNsLmNvZGVjLnBULmZyb21CaXRzKHQpfSx0aGlzLmtTPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLl9TKHQpLHRoaXMuZGlnZXN0KCl9LHRoaXMuQ1M9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuRFModCksdGhpcy5kaWdlc3QoKX19fSx0aGlzLl9TPWZ1bmN0aW9uKHQpe3Rocm93XCJ1cGRhdGVTdHJpbmcoc3RyKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZy9wcm92OiBcIit0aGlzLkhTK1wiL1wiK3RoaXMuTFN9LHRoaXMuRFM9ZnVuY3Rpb24odCl7dGhyb3dcInVwZGF0ZUhleChoZXgpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMuSFMrXCIvXCIrdGhpcy5MU30sdGhpcy5kaWdlc3Q9ZnVuY3Rpb24oKXt0aHJvd1wiZGlnZXN0KCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5IUytcIi9cIit0aGlzLkxTfSx0aGlzLmtTPWZ1bmN0aW9uKHQpe3Rocm93XCJkaWdlc3RTdHJpbmcoc3RyKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZy9wcm92OiBcIit0aGlzLkhTK1wiL1wiK3RoaXMuTFN9LHRoaXMuQ1M9ZnVuY3Rpb24odCl7dGhyb3dcImRpZ2VzdEhleChoZXgpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMuSFMrXCIvXCIrdGhpcy5MU30sdm9pZCAwIT09dCYmdm9pZCAwIT09dC5SUyYmKHRoaXMuSFM9dC5SUyx2b2lkIDA9PT10Lk9TJiYodGhpcy5MUz1LSlVSLmNyeXB0by5XeS5xVFt0aGlzLkhTXSksdGhpcy5CUyh0aGlzLkhTLHRoaXMuTFMpKX0sS0pVUi5jcnlwdG8uTVM9ZnVuY3Rpb24odCl7dGhpcy5CUz1mdW5jdGlvbih0LGUpe2lmKHQ9dC50b0xvd2VyQ2FzZSgpLG51bGw9PXQmJih0PVwiaG1hY3NoYTFcIiksdD10LnRvTG93ZXJDYXNlKCksXCJobWFjXCIhPXQuc3Vic3RyKDAsNCkpdGhyb3dcInNldEFsZ0FuZFByb3ZpZGVyIHVuc3VwcG9ydGVkIEhNQUMgYWxnOiBcIit0O3ZvaWQgMD09PWUmJihlPUtKVVIuY3J5cHRvLld5LnFUW3RdKSx0aGlzLmpTPXQrXCIvXCIrZTt2YXIgaT10LnN1YnN0cig0KTtpZihcIjptZDU6c2hhMTpzaGEyMjQ6c2hhMjU2OnNoYTM4NDpzaGE1MTI6cmlwZW1kMTYwOlwiLmluZGV4T2YoaSkhPS0xJiZcImNyeXB0b2pzXCI9PWUpe3RyeXt2YXIgcj1LSlVSLmNyeXB0by5XeS5iU1tpXTt0aGlzLm1hYz1idC52dy5ITUFDLmNyZWF0ZShyLHRoaXMuVVMpfWNhdGNoKG4pe3Rocm93XCJzZXRBbGdBbmRQcm92aWRlciBoYXNoIGFsZyBzZXQgZmFpbCBoYXNoQWxnPVwiK2krXCIvXCIrbn10aGlzLl9TPWZ1bmN0aW9uKHQpe3RoaXMubWFjLnVwZGF0ZSh0KX0sdGhpcy5EUz1mdW5jdGlvbih0KXt2YXIgZT1idC5ZbS5YbS5wYXJzZSh0KTt0aGlzLm1hYy51cGRhdGUoZSl9LHRoaXMuVlM9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLm1hYy5sdygpO3JldHVybiB0LnRvU3RyaW5nKGJ0LlltLlhtKX0sdGhpcy5RUz1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5fUyh0KSx0aGlzLlZTKCl9LHRoaXMucVM9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuRFModCksdGhpcy5WUygpfX19LHRoaXMuX1M9ZnVuY3Rpb24odCl7dGhyb3dcInVwZGF0ZVN0cmluZyhzdHIpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMualN9LHRoaXMuRFM9ZnVuY3Rpb24odCl7dGhyb3dcInVwZGF0ZUhleChoZXgpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnL3Byb3Y6IFwiK3RoaXMualN9LHRoaXMuVlM9ZnVuY3Rpb24oKXt0aHJvd1wiZGlnZXN0KCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5qU30sdGhpcy5RUz1mdW5jdGlvbih0KXt0aHJvd1wiZGlnZXN0U3RyaW5nKHN0cikgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5qU30sdGhpcy5xUz1mdW5jdGlvbih0KXt0aHJvd1wiZGlnZXN0SGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGcvcHJvdjogXCIrdGhpcy5qU30sdGhpcy5KUz1mdW5jdGlvbih0KXtpZihcInN0cmluZ1wiPT10eXBlb2YgdCl7dmFyIGU9dDtyZXR1cm4gdC5sZW5ndGglMiE9MSYmdC5tYXRjaCgvXlswLTlBLUZhLWZdKyQvKXx8KGU9cnN0cnRvaGV4KHQpKSx2b2lkKHRoaXMuVVM9YnQuWW0uWG0ucGFyc2UoZSkpfWlmKFwib2JqZWN0XCIhPXR5cGVvZiB0KXRocm93XCJLSlVSLmNyeXB0by5NYWMgdW5zdXBwb3J0ZWQgcGFzc3dvcmQgdHlwZTogXCIrdDt2YXIgZT1udWxsO2lmKHZvaWQgMCE9PXQucFQpe2lmKHQucFQubGVuZ3RoJTIhPTB8fCF0LnBULm1hdGNoKC9eWzAtOUEtRmEtZl0rJC8pKXRocm93XCJNYWM6IHdyb25nIGhleCBwYXNzd29yZDogXCIrdC5wVDtlPXQucFR9aWYodm9pZCAwIT09dC51dGY4JiYoZT11dGY4dG9oZXgodC51dGY4KSksdm9pZCAwIT09dC5yc3RyJiYoZT1yc3RydG9oZXgodC5yc3RyKSksdm9pZCAwIT09dC5iNjQmJihlPUoodC5iNjQpKSx2b2lkIDAhPT10LmI2NHUmJihlPWI2NHV0b2hleCh0LmI2NHUpKSxudWxsPT1lKXRocm93XCJLSlVSLmNyeXB0by5NYWMgdW5zdXBwb3J0ZWQgcGFzc3dvcmQgdHlwZTogXCIrdDt0aGlzLlVTPWJ0LlltLlhtLnBhcnNlKGUpfSx2b2lkIDAhPT10JiYodm9pZCAwIT09dC5VUyYmdGhpcy5KUyh0LlVTKSx2b2lkIDAhPT10LlJTJiYodGhpcy5IUz10LlJTLHZvaWQgMD09PXQuT1MmJih0aGlzLkxTPUtKVVIuY3J5cHRvLld5LnFUW3RoaXMuSFNdKSx0aGlzLkJTKHRoaXMuSFMsdGhpcy5MUykpKX0sS0pVUi5jcnlwdG8uU2lnbmF0dXJlPWZ1bmN0aW9uKHQpe3ZhciBlPW51bGw7aWYodGhpcy5LUz1mdW5jdGlvbigpe3RoaXMuSFMubWF0Y2goL14oLispd2l0aCguKykkLykmJih0aGlzLkdTPVJlZ0V4cC4kMS50b0xvd2VyQ2FzZSgpLHRoaXMuelM9UmVnRXhwLiQyLnRvTG93ZXJDYXNlKCkpfSx0aGlzLldTPWZ1bmN0aW9uKHQsZSl7Zm9yKHZhciBpPVwiXCIscj1lLzQtdC5sZW5ndGgsbj0wO248cjtuKyspaSs9XCIwXCI7cmV0dXJuIGkrdH0sdGhpcy5CUz1mdW5jdGlvbih0LGUpe2lmKHRoaXMuS1MoKSxcImNyeXB0b2pzL2pzcnNhXCIhPWUpdGhyb3dcInByb3ZpZGVyIG5vdCBzdXBwb3J0ZWQ6IFwiK2U7aWYoXCI6bWQ1OnNoYTE6c2hhMjI0OnNoYTI1NjpzaGEzODQ6c2hhNTEyOnJpcGVtZDE2MDpcIi5pbmRleE9mKHRoaXMuR1MpIT0tMSl7dHJ5e3RoaXMuRlM9bmV3IEtKVVIuY3J5cHRvLklTKHtSUzp0aGlzLkdTfSl9Y2F0Y2goaSl7dGhyb3dcInNldEFsZ0FuZFByb3ZpZGVyIGhhc2ggYWxnIHNldCBmYWlsIGFsZz1cIit0aGlzLkdTK1wiL1wiK2l9dGhpcy5pbml0PWZ1bmN0aW9uKHQsZSl7dmFyIGk9bnVsbDt0cnl7aT12b2lkIDA9PT1lP0tFWVVUSUwuZ2V0S2V5KHQpOktFWVVUSUwuZ2V0S2V5KHQsZSl9Y2F0Y2gocil7dGhyb3dcImluaXQgZmFpbGVkOlwiK3J9aWYoaS5pc1ByaXZhdGU9PT0hMCl0aGlzLiRTPWksdGhpcy5zdGF0ZT1cIlNJR05cIjtlbHNle2lmKGkucXkhPT0hMCl0aHJvd1wiaW5pdCBmYWlsZWQuOlwiK2k7dGhpcy5ZUz1pLHRoaXMuc3RhdGU9XCJWRVJJRllcIn19LHRoaXMuWFM9ZnVuY3Rpb24odCl7XCJzdHJpbmdcIj09dHlwZW9mIHQuWlMmJlwic3RyaW5nXCI9PXR5cGVvZiB0LnRiPyh0aGlzLlpTPXQuWlMsdGhpcy50Yj10LnRiKTp0aGlzLiRTPXQsdGhpcy5zdGF0ZT1cIlNJR05cIn0sdGhpcy5lYj1mdW5jdGlvbih0KXtcInN0cmluZ1wiPT10eXBlb2YgdC5pYiYmXCJzdHJpbmdcIj09dHlwZW9mIHQudGI/KHRoaXMuaWI9dC5pYix0aGlzLnRiPXQudGIpOnQgaW5zdGFuY2VvZiBLSlVSLmNyeXB0by5FQ0RTQT90aGlzLllTPXQ6dCBpbnN0YW5jZW9mIFkmJih0aGlzLllTPXQpLHRoaXMuc3RhdGU9XCJWRVJJRllcIn0sdGhpcy5yYj1mdW5jdGlvbih0KXt2YXIgZT1uZXcgWDUwOTtlLnJlYWRDZXJ0UEVNKHQpLHRoaXMuWVM9ZS5uYix0aGlzLnN0YXRlPVwiVkVSSUZZXCJ9LHRoaXMuX1M9ZnVuY3Rpb24odCl7dGhpcy5GUy5fUyh0KX0sdGhpcy5EUz1mdW5jdGlvbih0KXt0aGlzLkZTLkRTKHQpfSx0aGlzLnNpZ249ZnVuY3Rpb24oKXtpZih0aGlzLm9iPXRoaXMuRlMuZGlnZXN0KCksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHRoaXMuWlMmJlwidW5kZWZpbmVkXCIhPXR5cGVvZiB0aGlzLnRiKXt2YXIgdD1uZXcgS0pVUi5jcnlwdG8uRUNEU0Eoe2N1cnZlOnRoaXMudGJ9KTt0aGlzLnNiPXQuYWIodGhpcy5vYix0aGlzLlpTKX1lbHNlIGlmKHRoaXMuJFMgaW5zdGFuY2VvZiBZJiZcInJzYWFuZG1nZjFcIj09dGhpcy56Uyl0aGlzLnNiPXRoaXMuJFMuWnkodGhpcy5vYix0aGlzLkdTLHRoaXMuY2IpO2Vsc2UgaWYodGhpcy4kUyBpbnN0YW5jZW9mIFkmJlwicnNhXCI9PXRoaXMuelMpdGhpcy5zYj10aGlzLiRTLiR5KHRoaXMub2IsdGhpcy5HUyk7ZWxzZSBpZih0aGlzLiRTIGluc3RhbmNlb2YgS0pVUi5jcnlwdG8uRUNEU0EpdGhpcy5zYj10aGlzLiRTLiR5KHRoaXMub2IpO2Vsc2V7aWYoISh0aGlzLiRTIGluc3RhbmNlb2YgS0pVUi5jcnlwdG8uRFNBKSl0aHJvd1wiU2lnbmF0dXJlOiB1bnN1cHBvcnRlZCBwdWJsaWMga2V5IGFsZzogXCIrdGhpcy56Uzt0aGlzLnNiPXRoaXMuJFMuJHkodGhpcy5vYil9cmV0dXJuIHRoaXMuc2J9LHRoaXMuaGI9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuX1ModCksdGhpcy5zaWduKCl9LHRoaXMuYWI9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMuRFModCksdGhpcy5zaWduKCl9LHRoaXMudmVyaWZ5PWZ1bmN0aW9uKHQpe2lmKHRoaXMub2I9dGhpcy5GUy5kaWdlc3QoKSxcInVuZGVmaW5lZFwiIT10eXBlb2YgdGhpcy5pYiYmXCJ1bmRlZmluZWRcIiE9dHlwZW9mIHRoaXMudGIpe3ZhciBlPW5ldyBLSlVSLmNyeXB0by5FQ0RTQSh7Y3VydmU6dGhpcy50Yn0pO3JldHVybiBlLnZlcmlmeUhleCh0aGlzLm9iLHQsdGhpcy5pYil9aWYodGhpcy5ZUyBpbnN0YW5jZW9mIFkmJlwicnNhYW5kbWdmMVwiPT10aGlzLnpTKXJldHVybiB0aGlzLllTLmVtKHRoaXMub2IsdCx0aGlzLkdTLHRoaXMuY2IpO2lmKHRoaXMuWVMgaW5zdGFuY2VvZiBZJiZcInJzYVwiPT10aGlzLnpTKXJldHVybiB0aGlzLllTLnBiKHRoaXMub2IsdCk7aWYodGhpcy5ZUyBpbnN0YW5jZW9mIEtKVVIuY3J5cHRvLkVDRFNBKXJldHVybiB0aGlzLllTLnBiKHRoaXMub2IsdCk7aWYodGhpcy5ZUyBpbnN0YW5jZW9mIEtKVVIuY3J5cHRvLkRTQSlyZXR1cm4gdGhpcy5ZUy5wYih0aGlzLm9iLHQpO3Rocm93XCJTaWduYXR1cmU6IHVuc3VwcG9ydGVkIHB1YmxpYyBrZXkgYWxnOiBcIit0aGlzLnpTfX19LHRoaXMuaW5pdD1mdW5jdGlvbih0LGUpe3Rocm93XCJpbml0KGtleSwgcGFzcykgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLnVifSx0aGlzLmViPWZ1bmN0aW9uKHQpe3Rocm93XCJpbml0VmVyaWZ5QnlQdWJsaWNLZXkocnNhUHViS2V5eSkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLnVifSx0aGlzLnJiPWZ1bmN0aW9uKHQpe3Rocm93XCJpbml0VmVyaWZ5QnlDZXJ0aWZpY2F0ZVBFTShjZXJ0UEVNKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZzpwcm92PVwiK3RoaXMudWJ9LHRoaXMuWFM9ZnVuY3Rpb24odCl7dGhyb3dcImluaXRTaWduKHBydktleSkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLnVifSx0aGlzLl9TPWZ1bmN0aW9uKHQpe3Rocm93XCJ1cGRhdGVTdHJpbmcoc3RyKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZzpwcm92PVwiK3RoaXMudWJ9LHRoaXMuRFM9ZnVuY3Rpb24odCl7dGhyb3dcInVwZGF0ZUhleChoZXgpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnOnByb3Y9XCIrdGhpcy51Yn0sdGhpcy5zaWduPWZ1bmN0aW9uKCl7dGhyb3dcInNpZ24oKSBub3Qgc3VwcG9ydGVkIGZvciB0aGlzIGFsZzpwcm92PVwiK3RoaXMudWJ9LHRoaXMuaGI9ZnVuY3Rpb24odCl7dGhyb3dcImRpZ2VzdFN0cmluZyhzdHIpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnOnByb3Y9XCIrdGhpcy51Yn0sdGhpcy5hYj1mdW5jdGlvbih0KXt0aHJvd1wiZGlnZXN0SGV4KGhleCkgbm90IHN1cHBvcnRlZCBmb3IgdGhpcyBhbGc6cHJvdj1cIit0aGlzLnVifSx0aGlzLnZlcmlmeT1mdW5jdGlvbih0KXt0aHJvd1widmVyaWZ5KGhTaWdWYWwpIG5vdCBzdXBwb3J0ZWQgZm9yIHRoaXMgYWxnOnByb3Y9XCIrdGhpcy51Yn0sdGhpcy5sYj10LHZvaWQgMCE9PXQmJih2b2lkIDAhPT10LlJTJiYodGhpcy5IUz10LlJTLHZvaWQgMD09PXQuT1M/dGhpcy5MUz1LSlVSLmNyeXB0by5XeS5xVFt0aGlzLkhTXTp0aGlzLkxTPXQuT1MsdGhpcy51Yj10aGlzLkhTK1wiOlwiK3RoaXMuTFMsdGhpcy5CUyh0aGlzLkhTLHRoaXMuTFMpLHRoaXMuS1MoKSksdm9pZCAwIT09dC5mYiYmKHRoaXMuY2I9dC5mYiksdm9pZCAwIT09dC5wcnZrZXlwZW0pKXtpZih2b2lkIDAhPT10LnBydmtleXBhcyl0aHJvd1wiYm90aCBwcnZrZXlwZW0gYW5kIHBydmtleXBhcyBwYXJhbWV0ZXJzIG5vdCBzdXBwb3J0ZWRcIjt0cnl7dmFyIGU9bmV3IFk7ZS5yZWFkUHJpdmF0ZUtleUZyb21QRU1TdHJpbmcodC5wcnZrZXlwZW0pLHRoaXMuWFMoZSl9Y2F0Y2goaSl7dGhyb3dcImZhdGFsIGVycm9yIHRvIGxvYWQgcGVtIHByaXZhdGUga2V5OiBcIitpfX19LEtKVVIuY3J5cHRvLk5UPW5ldyBmdW5jdGlvbigpe3RoaXMuZ2I9e3ZiOlwicnNhRW5jcnlwdGlvblwiLHliOlwiZWNQdWJsaWNLZXlcIixtYjpcImRzYVwiLHdiOlwic2VjcDI1NnIxXCIsVGI6XCJzZWNwMTkyazFcIixTYjpcInNlY3AyMjRyMVwiLGJiOlwic2VjcDI1NmsxXCIsRWI6XCJzZWNwNTIxcjFcIixJYjpcInNlY3AzODRyMVwiLFJiOlwiU0hBMXdpdGhEU0FcIixcIjYwODY0ODAxNjUwMzA0MDMwMVwiOlwiU0hBMjI0d2l0aERTQVwiLFwiNjA4NjQ4MDE2NTAzMDQwMzAyXCI6XCJTSEEyNTZ3aXRoRFNBXCJ9fTt2YXIgQnQ9MjA7WS5wcm90b3R5cGUuR3k9WixZLnByb3RvdHlwZS5xaD1YLFkucHJvdG90eXBlLmVuY3J5cHQ9dHQsWS5wcm90b3R5cGUua2I9ZXQsWS5wcm90b3R5cGUudHlwZT1cIlJTQVwiOy8qISByc2FzaWduLTEuMi43LmpzIChjKSAyMDEyIEtlbmppIFVydXNoaW1hIHwga2p1ci5naXRodWIuY29tL2pzcnNhc2lnbi9saWNlbnNlXG4gICAqL1xuICB2YXIgRnQ9bmV3IFJlZ0V4cChcIlwiKTtGdC5jb21waWxlKFwiW14wLTlhLWZdXCIsXCJnaVwiKSxZLnByb3RvdHlwZS4keT1udCxZLnByb3RvdHlwZS5oYj1ydCxZLnByb3RvdHlwZS5DYj1vdCxZLnByb3RvdHlwZS5PYj1zdCxZLnByb3RvdHlwZS5zaWduPXJ0LFkucHJvdG90eXBlLlBiPW90LFkucHJvdG90eXBlLkFiPXN0LFkucHJvdG90eXBlLlp5PWh0LFkucHJvdG90eXBlLk5iPWN0LFkucHJvdG90eXBlLnhiPWN0LFkuQmI9LTEsWS5GYj0tMixZLnByb3RvdHlwZS5wYj12dCxZLnByb3RvdHlwZS5KaD1ndCxZLnByb3RvdHlwZS5fYj1mdCxZLnByb3RvdHlwZS52ZXJpZnk9Z3QsWS5wcm90b3R5cGUuRGI9ZnQsWS5wcm90b3R5cGUuZW09bXQsWS5wcm90b3R5cGUuSGI9eXQsWS5wcm90b3R5cGUuTGI9eXQsWS5NYj0tMixlLmpiPWksZS5NaD1ZLGUuU2lnbmF0dXJlPUtKVVIuY3J5cHRvLlNpZ25hdHVyZSxlLklTPUtKVVIuY3J5cHRvLklTLGUuVWI9YnQsZS5qaD1KLGUuVmI9S30sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjt2YXIgaT17fTtpLlFiPWZ1bmN0aW9uKCl7cmV0dXJuIE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnN1YnN0cigyLDEwKX0saS5xYj1pLlFiKCksaS5KYj1mdW5jdGlvbih0KXtyZXR1cm4gdC50cmltKCkuc3BsaXQoXCJcXG5cIikubWFwKGZ1bmN0aW9uKHQpe3JldHVybiB0LnRyaW0oKX0pfSxpLktiPWZ1bmN0aW9uKHQpe3ZhciBlPXQuc3BsaXQoXCJcXG5tPVwiKTtyZXR1cm4gZS5tYXAoZnVuY3Rpb24odCxlKXtyZXR1cm4oZT4wP1wibT1cIit0OnQpLnRyaW0oKStcIlxcclxcblwifSl9LGkuR2I9ZnVuY3Rpb24odCxlKXtyZXR1cm4gaS5KYih0KS5maWx0ZXIoZnVuY3Rpb24odCl7cmV0dXJuIDA9PT10LmluZGV4T2YoZSl9KX0saS56Yj1mdW5jdGlvbih0KXt2YXIgZTtlPTA9PT10LmluZGV4T2YoXCJhPWNhbmRpZGF0ZTpcIik/dC5zdWJzdHJpbmcoMTIpLnNwbGl0KFwiIFwiKTp0LnN1YnN0cmluZygxMCkuc3BsaXQoXCIgXCIpO2Zvcih2YXIgaT17V2I6ZVswXSwkYjplWzFdLHByb3RvY29sOmVbMl0udG9Mb3dlckNhc2UoKSxZYjpwYXJzZUludChlWzNdLDEwKSxYYjplWzRdLHBvcnQ6cGFyc2VJbnQoZVs1XSwxMCksdHlwZTplWzddfSxyPTg7cjxlLmxlbmd0aDtyKz0yKXN3aXRjaChlW3JdKXtjYXNlXCJyYWRkclwiOmkuWmI9ZVtyKzFdO2JyZWFrO2Nhc2VcInJwb3J0XCI6aS50RT1wYXJzZUludChlW3IrMV0sMTApO2JyZWFrO2Nhc2VcInRjcHR5cGVcIjppLmVFPWVbcisxXTticmVhaztkZWZhdWx0OmlbZVtyXV09ZVtyKzFdfXJldHVybiBpfSxpLmlFPWZ1bmN0aW9uKHQpe3ZhciBlPVtdO2UucHVzaCh0LldiKSxlLnB1c2godC4kYiksZS5wdXNoKHQucHJvdG9jb2wudG9VcHBlckNhc2UoKSksZS5wdXNoKHQuWWIpLGUucHVzaCh0LlhiKSxlLnB1c2godC5wb3J0KTt2YXIgaT10LnR5cGU7cmV0dXJuIGUucHVzaChcInR5cFwiKSxlLnB1c2goaSksXCJob3N0XCIhPT1pJiZ0LlpiJiZ0LnRFJiYoZS5wdXNoKFwicmFkZHJcIiksZS5wdXNoKHQuWmIpLGUucHVzaChcInJwb3J0XCIpLGUucHVzaCh0LnRFKSksdC5lRSYmXCJ0Y3BcIj09PXQucHJvdG9jb2wudG9Mb3dlckNhc2UoKSYmKGUucHVzaChcInRjcHR5cGVcIiksZS5wdXNoKHQuZUUpKSxcImNhbmRpZGF0ZTpcIitlLmpvaW4oXCIgXCIpfSxpLnJFPWZ1bmN0aW9uKHQpe3JldHVybiB0LnN1YnN0cigxNCkuc3BsaXQoXCIgXCIpfSxpLm5FPWZ1bmN0aW9uKHQpe3ZhciBlPXQuc3Vic3RyKDkpLnNwbGl0KFwiIFwiKSxpPXtvRTpwYXJzZUludChlLnNoaWZ0KCksMTApfTtyZXR1cm4gZT1lWzBdLnNwbGl0KFwiL1wiKSxpLm5hbWU9ZVswXSxpLnNFPXBhcnNlSW50KGVbMV0sMTApLGkuYUU9Mz09PWUubGVuZ3RoP3BhcnNlSW50KGVbMl0sMTApOjEsaX0saS5jRT1mdW5jdGlvbih0KXt2YXIgZT10Lm9FO3JldHVybiB2b2lkIDAhPT10LmhFJiYoZT10LmhFKSxcImE9cnRwbWFwOlwiK2UrXCIgXCIrdC5uYW1lK1wiL1wiK3Quc0UrKDEhPT10LmFFP1wiL1wiK3QuYUU6XCJcIikrXCJcXHJcXG5cIn0saS5wRT1mdW5jdGlvbih0KXt2YXIgZT10LnN1YnN0cig5KS5zcGxpdChcIiBcIik7cmV0dXJue2lkOnBhcnNlSW50KGVbMF0sMTApLGRpcmVjdGlvbjplWzBdLmluZGV4T2YoXCIvXCIpPjA/ZVswXS5zcGxpdChcIi9cIilbMV06XCJzZW5kcmVjdlwiLHVyaTplWzFdfX0saS51RT1mdW5jdGlvbih0KXtyZXR1cm5cImE9ZXh0bWFwOlwiKyh0LmlkfHx0LnByZWZlcnJlZElkKSsodC5kaXJlY3Rpb24mJlwic2VuZHJlY3ZcIiE9PXQuZGlyZWN0aW9uP1wiL1wiK3QuZGlyZWN0aW9uOlwiXCIpK1wiIFwiK3QudXJpK1wiXFxyXFxuXCJ9LGkubEU9ZnVuY3Rpb24odCl7Zm9yKHZhciBlLGk9e30scj10LnN1YnN0cih0LmluZGV4T2YoXCIgXCIpKzEpLnNwbGl0KFwiO1wiKSxuPTA7bjxyLmxlbmd0aDtuKyspZT1yW25dLnRyaW0oKS5zcGxpdChcIj1cIiksaVtlWzBdLnRyaW0oKV09ZVsxXTtyZXR1cm4gaX0saS5kRT1mdW5jdGlvbih0KXt2YXIgZT1cIlwiLGk9dC5vRTtpZih2b2lkIDAhPT10LmhFJiYoaT10LmhFKSx0LnBhcmFtZXRlcnMmJk9iamVjdC5rZXlzKHQucGFyYW1ldGVycykubGVuZ3RoKXt2YXIgcj1bXTtPYmplY3Qua2V5cyh0LnBhcmFtZXRlcnMpLmZvckVhY2goZnVuY3Rpb24oZSl7ci5wdXNoKGUrXCI9XCIrdC5wYXJhbWV0ZXJzW2VdKX0pLGUrPVwiYT1mbXRwOlwiK2krXCIgXCIrci5qb2luKFwiO1wiKStcIlxcclxcblwifXJldHVybiBlfSxpLmZFPWZ1bmN0aW9uKHQpe3ZhciBlPXQuc3Vic3RyKHQuaW5kZXhPZihcIiBcIikrMSkuc3BsaXQoXCIgXCIpO3JldHVybnt0eXBlOmUuc2hpZnQoKSxnRTplLmpvaW4oXCIgXCIpfX0saS52RT1mdW5jdGlvbih0KXt2YXIgZT1cIlwiLGk9dC5vRTtyZXR1cm4gdm9pZCAwIT09dC5oRSYmKGk9dC5oRSksdC55RSYmdC55RS5sZW5ndGgmJnQueUUuZm9yRWFjaChmdW5jdGlvbih0KXtlKz1cImE9cnRjcC1mYjpcIitpK1wiIFwiK3QudHlwZSsodC5nRSYmdC5nRS5sZW5ndGg/XCIgXCIrdC5nRTpcIlwiKStcIlxcclxcblwifSksZX0saS5tRT1mdW5jdGlvbih0KXt2YXIgZT10LmluZGV4T2YoXCIgXCIpLGk9e3dFOnBhcnNlSW50KHQuc3Vic3RyKDcsZS03KSwxMCl9LHI9dC5pbmRleE9mKFwiOlwiLGUpO3JldHVybiByPi0xPyhpLlRFPXQuc3Vic3RyKGUrMSxyLWUtMSksaS52YWx1ZT10LnN1YnN0cihyKzEpKTppLlRFPXQuc3Vic3RyKGUrMSksaX0saS5TRT1mdW5jdGlvbih0KXt2YXIgZT1pLkdiKHQsXCJhPW1pZDpcIilbMF07aWYoZSlyZXR1cm4gZS5zdWJzdHIoNil9LGkuYkU9ZnVuY3Rpb24odCl7dmFyIGU9dC5zdWJzdHIoMTQpLnNwbGl0KFwiIFwiKTtyZXR1cm57YWxnb3JpdGhtOmVbMF0udG9Mb3dlckNhc2UoKSx2YWx1ZTplWzFdfX0saS5FRT1mdW5jdGlvbih0LGUpe3ZhciByPWkuR2IodCtlLFwiYT1maW5nZXJwcmludDpcIik7cmV0dXJue0lFOlwiYXV0b1wiLFJFOnIubWFwKGkuYkUpfX0saS5rRT1mdW5jdGlvbih0LGUpe3ZhciBpPVwiYT1zZXR1cDpcIitlK1wiXFxyXFxuXCI7cmV0dXJuIHQuUkUuZm9yRWFjaChmdW5jdGlvbih0KXtpKz1cImE9ZmluZ2VycHJpbnQ6XCIrdC5hbGdvcml0aG0rXCIgXCIrdC52YWx1ZStcIlxcclxcblwifSksaX0saS5DRT1mdW5jdGlvbih0LGUpe3ZhciByPWkuSmIodCk7cj1yLmNvbmNhdChpLkpiKGUpKTt2YXIgbj17T0U6ci5maWx0ZXIoZnVuY3Rpb24odCl7cmV0dXJuIDA9PT10LmluZGV4T2YoXCJhPWljZS11ZnJhZzpcIil9KVswXS5zdWJzdHIoMTIpLHBhc3N3b3JkOnIuZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVybiAwPT09dC5pbmRleE9mKFwiYT1pY2UtcHdkOlwiKX0pWzBdLnN1YnN0cigxMCl9O3JldHVybiBufSxpLlBFPWZ1bmN0aW9uKHQpe3JldHVyblwiYT1pY2UtdWZyYWc6XCIrdC5PRStcIlxcclxcbmE9aWNlLXB3ZDpcIit0LnBhc3N3b3JkK1wiXFxyXFxuXCJ9LGkuQUU9ZnVuY3Rpb24odCl7Zm9yKHZhciBlPXtORTpbXSx4RTpbXSxCRTpbXSxGRTpbXX0scj1pLkpiKHQpLG49clswXS5zcGxpdChcIiBcIiksbz0zO288bi5sZW5ndGg7bysrKXt2YXIgcz1uW29dLGE9aS5HYih0LFwiYT1ydHBtYXA6XCIrcytcIiBcIilbMF07aWYoYSl7dmFyIGM9aS5uRShhKSxoPWkuR2IodCxcImE9Zm10cDpcIitzK1wiIFwiKTtzd2l0Y2goYy5wYXJhbWV0ZXJzPWgubGVuZ3RoP2kubEUoaFswXSk6e30sYy55RT1pLkdiKHQsXCJhPXJ0Y3AtZmI6XCIrcytcIiBcIikubWFwKGkuZkUpLGUuTkUucHVzaChjKSxjLm5hbWUudG9VcHBlckNhc2UoKSl7Y2FzZVwiUkVEXCI6Y2FzZVwiVUxQRkVDXCI6ZS5CRS5wdXNoKGMubmFtZS50b1VwcGVyQ2FzZSgpKX19fXJldHVybiBpLkdiKHQsXCJhPWV4dG1hcDpcIikuZm9yRWFjaChmdW5jdGlvbih0KXtlLnhFLnB1c2goaS5wRSh0KSl9KSxlfSxpLl9FPWZ1bmN0aW9uKHQsZSl7dmFyIHI9XCJcIjtyKz1cIm09XCIrdCtcIiBcIixyKz1lLk5FLmxlbmd0aD4wP1wiOVwiOlwiMFwiLHIrPVwiIFVEUC9UTFMvUlRQL1NBVlBGIFwiLHIrPWUuTkUubWFwKGZ1bmN0aW9uKHQpe3JldHVybiB2b2lkIDAhPT10LmhFP3QuaEU6dC5vRX0pLmpvaW4oXCIgXCIpK1wiXFxyXFxuXCIscis9XCJjPUlOIElQNCAwLjAuMC4wXFxyXFxuXCIscis9XCJhPXJ0Y3A6OSBJTiBJUDQgMC4wLjAuMFxcclxcblwiLGUuTkUuZm9yRWFjaChmdW5jdGlvbih0KXtyKz1pLmNFKHQpLHIrPWkuZEUodCkscis9aS52RSh0KX0pO3ZhciBuPTA7cmV0dXJuIGUuTkUuZm9yRWFjaChmdW5jdGlvbih0KXt0LkRFPm4mJihuPXQuREUpfSksbj4wJiYocis9XCJhPW1heHB0aW1lOlwiK24rXCJcXHJcXG5cIikscis9XCJhPXJ0Y3AtbXV4XFxyXFxuXCIsZS54RS5mb3JFYWNoKGZ1bmN0aW9uKHQpe3IrPWkudUUodCl9KSxyfSxpLkhFPWZ1bmN0aW9uKHQpe3ZhciBlLHI9W10sbj1pLkFFKHQpLG89bi5CRS5pbmRleE9mKFwiUkVEXCIpIT09LTEscz1uLkJFLmluZGV4T2YoXCJVTFBGRUNcIikhPT0tMSxhPWkuR2IodCxcImE9c3NyYzpcIikubWFwKGZ1bmN0aW9uKHQpe3JldHVybiBpLm1FKHQpfSkuZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVyblwiY25hbWVcIj09PXQuVEV9KSxjPWEubGVuZ3RoPjAmJmFbMF0ud0UsaD1pLkdiKHQsXCJhPXNzcmMtZ3JvdXA6RklEXCIpLm1hcChmdW5jdGlvbih0KXt2YXIgZT10LnNwbGl0KFwiIFwiKTtyZXR1cm4gZS5zaGlmdCgpLGUubWFwKGZ1bmN0aW9uKHQpe3JldHVybiBwYXJzZUludCh0LDEwKX0pfSk7aC5sZW5ndGg+MCYmaFswXS5sZW5ndGg+MSYmaFswXVswXT09PWMmJihlPWhbMF1bMV0pLG4uTkUuZm9yRWFjaChmdW5jdGlvbih0KXtpZihcIlJUWFwiPT09dC5uYW1lLnRvVXBwZXJDYXNlKCkmJnQucGFyYW1ldGVycy5hcHQpe3ZhciBpPXt3RTpjLExFOnBhcnNlSW50KHQucGFyYW1ldGVycy5hcHQsMTApLE1FOnt3RTplfX07ci5wdXNoKGkpLG8mJihpPUpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoaSkpLGkuakU9e3dFOmUsVUU6cz9cInJlZCt1bHBmZWNcIjpcInJlZFwifSxyLnB1c2goaSkpfX0pLDA9PT1yLmxlbmd0aCYmYyYmci5wdXNoKHt3RTpjfSk7dmFyIHA9aS5HYih0LFwiYj1cIik7cmV0dXJuIHAubGVuZ3RoJiYoMD09PXBbMF0uaW5kZXhPZihcImI9VElBUzpcIik/cD1wYXJzZUludChwWzBdLnN1YnN0cig3KSwxMCk6MD09PXBbMF0uaW5kZXhPZihcImI9QVM6XCIpJiYocD1wYXJzZUludChwWzBdLnN1YnN0cig1KSwxMCkpLHIuZm9yRWFjaChmdW5jdGlvbih0KXt0LlZFPXB9KSkscn0saS5RRT1mdW5jdGlvbih0KXt2YXIgZT17fSxyPWkuR2IodCxcImE9c3NyYzpcIikubWFwKGZ1bmN0aW9uKHQpe3JldHVybiBpLm1FKHQpfSkuZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVyblwiY25hbWVcIj09PXQuVEV9KVswXTtyJiYoZS5xRT1yLnZhbHVlLGUud0U9ci53RSk7dmFyIG49aS5HYih0LFwiYT1ydGNwLXJzaXplXCIpO2UuSkU9bi5sZW5ndGg+MCxlLktFPTA9PT1uLmxlbmd0aDt2YXIgbz1pLkdiKHQsXCJhPXJ0Y3AtbXV4XCIpO3JldHVybiBlLkdFPW8ubGVuZ3RoPjAsZX0saS56RT1mdW5jdGlvbih0KXt2YXIgZSxyPWkuR2IodCxcImE9bXNpZDpcIik7aWYoMT09PXIubGVuZ3RoKXJldHVybiBlPXJbMF0uc3Vic3RyKDcpLnNwbGl0KFwiIFwiKSx7c3RyZWFtOmVbMF0sdHJhY2s6ZVsxXX07dmFyIG49aS5HYih0LFwiYT1zc3JjOlwiKS5tYXAoZnVuY3Rpb24odCl7cmV0dXJuIGkubUUodCl9KS5maWx0ZXIoZnVuY3Rpb24odCl7cmV0dXJuXCJtc2lkXCI9PT10LlRFfSk7cmV0dXJuIG4ubGVuZ3RoPjA/KGU9blswXS52YWx1ZS5zcGxpdChcIiBcIikse3N0cmVhbTplWzBdLHRyYWNrOmVbMV19KTp2b2lkIDB9LGkuV0U9ZnVuY3Rpb24oKXtyZXR1cm5cInY9MFxcclxcbm89dGhpc2lzYWRhcHRlcm9ydGMgODE2OTYzOTkxNTY0Njk0MzEzNyAyIElOIElQNCAxMjcuMC4wLjFcXHJcXG5zPS1cXHJcXG50PTAgMFxcclxcblwifSxpLiRFPWZ1bmN0aW9uKHQsZSxyLG4pe3ZhciBvPWkuX0UodC5raW5kLGUpO2lmKG8rPWkuUEUodC5ZRS5nZXRMb2NhbFBhcmFtZXRlcnMoKSksbys9aS5rRSh0LlhFLmdldExvY2FsUGFyYW1ldGVycygpLFwib2ZmZXJcIj09PXI/XCJhY3RwYXNzXCI6XCJhY3RpdmVcIiksbys9XCJhPW1pZDpcIit0LlpFK1wiXFxyXFxuXCIsbys9dC5kaXJlY3Rpb24/XCJhPVwiK3QuZGlyZWN0aW9uK1wiXFxyXFxuXCI6dC50SSYmdC5lST9cImE9c2VuZHJlY3ZcXHJcXG5cIjp0LnRJP1wiYT1zZW5kb25seVxcclxcblwiOnQuZUk/XCJhPXJlY3Zvbmx5XFxyXFxuXCI6XCJhPWluYWN0aXZlXFxyXFxuXCIsdC50SSl7dmFyIHM9XCJtc2lkOlwiK24uaWQrXCIgXCIrdC50SS50cmFjay5pZCtcIlxcclxcblwiO28rPVwiYT1cIitzLG8rPVwiYT1zc3JjOlwiK3QuaUlbMF0ud0UrXCIgXCIrcyx0LmlJWzBdLk1FJiYobys9XCJhPXNzcmM6XCIrdC5pSVswXS5NRS53RStcIiBcIitzLG8rPVwiYT1zc3JjLWdyb3VwOkZJRCBcIit0LmlJWzBdLndFK1wiIFwiK3QuaUlbMF0uTUUud0UrXCJcXHJcXG5cIil9cmV0dXJuIG8rPVwiYT1zc3JjOlwiK3QuaUlbMF0ud0UrXCIgY25hbWU6XCIraS5xYitcIlxcclxcblwiLHQudEkmJnQuaUlbMF0uTUUmJihvKz1cImE9c3NyYzpcIit0LmlJWzBdLk1FLndFK1wiIGNuYW1lOlwiK2kucWIrXCJcXHJcXG5cIiksb30saS5yST1mdW5jdGlvbih0LGUpe2Zvcih2YXIgcj1pLkpiKHQpLG49MDtuPHIubGVuZ3RoO24rKylzd2l0Y2gocltuXSl7Y2FzZVwiYT1zZW5kcmVjdlwiOmNhc2VcImE9c2VuZG9ubHlcIjpjYXNlXCJhPXJlY3Zvbmx5XCI6Y2FzZVwiYT1pbmFjdGl2ZVwiOnJldHVybiByW25dLnN1YnN0cigyKX1yZXR1cm4gZT9pLnJJKGUpOlwic2VuZHJlY3ZcIn0saS5uST1mdW5jdGlvbih0KXt2YXIgZT1pLkpiKHQpLHI9ZVswXS5zcGxpdChcIiBcIik7cmV0dXJuIHJbMF0uc3Vic3RyKDIpfSxpLlV0PWZ1bmN0aW9uKHQpe3JldHVyblwiMFwiPT09dC5zcGxpdChcIiBcIiwyKVsxXX0sdC50PWl9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcj1pKDEpLG49aSgxMCksbz1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlKXt0aGlzLm1zZz10LHRoaXMub0k9RGF0ZS5ub3coKStlLHRoaXMuc0k9ci5kZWZlcigpfXJldHVybiB0LnByb3RvdHlwZS5hST1mdW5jdGlvbigpe3JldHVybiBEYXRlLm5vdygpPj10aGlzLm9JfSx0fSgpLHM9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQsZSxpLHIsbixvLHMpe3ZvaWQgMD09PWUmJihlPTNlNCksdm9pZCAwPT09aSYmKGk9MTAwKSx2b2lkIDA9PT1yJiYocj0zZTQpLHZvaWQgMD09PW4mJihuPTE1ZTMpLHZvaWQgMD09PW8mJihvPURhdGUpLHZvaWQgMD09PXMmJihzPSExKSx0aGlzLmNJPTEsdGhpcy5oST0tMSx0aGlzLnBJPS0xLHRoaXMudUk9e30sdGhpcy5sST1bXSx0aGlzLmRJPVtdLHRoaXMuZkk9ITEsdGhpcy5nST0hMCx0aGlzLnZJPXQsdGhpcy55ST1BcnJheSgpLHRoaXMuQW89ZSx0aGlzLk5vPWksdGhpcy54bz1yLHRoaXMubUk9bix0aGlzLndJPW8sdGhpcy5mST1zfHwvTVNJRSAxMC9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCl8fC9NU0lFIDkvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpfHwvcnY6MTEuMC9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCl8fC9FZGdlLi9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCl9cmV0dXJuIHQucHJvdG90eXBlLkV0PWZ1bmN0aW9uKHQpe3ZhciBlPXQuc2VydmljZStcIl9cIit0Lm1zZ0lkLGk9dGhpcy51SVtlXTtudWxsIT1pP2kodCk6bi5tKCkuZXJyb3Iobi51K1wiQ291bGQgbm90IGZpbmQgYSBkaXNwYXRjaGVyIGZvciBcIix0LGUsdGhpcy51SSl9LHQucHJvdG90eXBlLm9uPWZ1bmN0aW9uKHQsZSxpKXt0aGlzLnVJW3QrXCJfXCIrZV09aX0sdC5wcm90b3R5cGUub25lcnJvcj1mdW5jdGlvbih0KXt0aGlzLmxJLnB1c2godCl9LHQucHJvdG90eXBlLlRJPWZ1bmN0aW9uKHQpe3RoaXMuZEkucHVzaCh0KX0sdC5wcm90b3R5cGUuU0k9ZnVuY3Rpb24oKXt2YXIgdD10aGlzO2lmKCF3aW5kb3cuV2ViU29ja2V0KXJldHVybiB2b2lkIHRoaXMubEkuZm9yRWFjaChmdW5jdGlvbih0KXtyZXR1cm4gdChcIldlYlNvY2tldCBub3QgZGVmaW5lZFwiKX0pO3ZhciBlPW5ldyBXZWJTb2NrZXQodGhpcy52SSk7cmV0dXJuIGUuYmluYXJ5VHlwZT1cImFycmF5YnVmZmVyXCIsZS5vbm9wZW49ZnVuY3Rpb24oZSl7dC5iSSgpLG4ubSgpLmRlYnVnKG4udStcIkhpdmVTZXJ2aWNlc0Nvbm5lY3Rpb24gZXN0YWJsaXNoZWQgdG8gXCIrdC52SSksdC5wST0obmV3IHQud0kpLmdldFRpbWUoKSx0LkVJKCksdC5kSS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3JldHVybiBlKHQpfSksdC5JSSgpLHQuUkkoKX0sZS5vbmNsb3NlPWZ1bmN0aW9uKGUpe3QuY2xvc2UodC5nSSksdC5jb25uZWN0KCl9LGUub25tZXNzYWdlPWZ1bmN0aW9uKGUpe3QuRXQobi5abi53byhlLmRhdGEpKX0sZS5vbmVycm9yPWZ1bmN0aW9uKGUpe3QuY2xvc2UoITApLHQubEkuZm9yRWFjaChmdW5jdGlvbih0KXtyZXR1cm4gdChlLnRvU3RyaW5nKCkpfSl9LGV9LHQucHJvdG90eXBlLmlzT3Blbj1mdW5jdGlvbigpe3JldHVybiBudWxsIT10aGlzLk9wJiZ0aGlzLk9wLnJlYWR5U3RhdGU9PXRoaXMuT3AuT1BFTn0sdC5wcm90b3R5cGUuY29ubmVjdD1mdW5jdGlvbih0KXt2YXIgZT10aGlzO3QmJih0aGlzLmdJPSEwKSx0aGlzLmdJJiYxIT10aGlzLmlzT3BlbigpJiYodGhpcy5oST4wfHwodGhpcy5wST4tMSYmKG5ldyB0aGlzLndJKS5nZXRUaW1lKCktdGhpcy5wST50aGlzLkFvPyh0aGlzLmNJPW4ua2UueW8sdGhpcy5wST0tMSk6dGhpcy5jST1NYXRoLm1pbigyKnRoaXMuY0ksdGhpcy5BbyksdGhpcy5oST13aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpe2UuaEk9LTEsbi5tKCkuZGVidWcobi51K1wiQ29ubmVjdGlvbiBhdHRlbXB0IHRvIFwiK2UudkkrXCIgW3Q6XCIrZS5jSStcIiBoYjpcIitlLmZJK1wiXVwiKSxlLk9wPWUuU0koKSxlLmNJPU1hdGgubWF4KGUuY0ksbi5rZS55byl9LHRoaXMuY0kpKSl9LHQucHJvdG90eXBlLmJJPWZ1bmN0aW9uKCl7dGhpcy5oST4tMSYmKGNsZWFyVGltZW91dCh0aGlzLmhJKSx0aGlzLmhJPS0xKX0sdC5wcm90b3R5cGUuY2xvc2U9ZnVuY3Rpb24odCl7dGhpcy5nST12b2lkIDAhPXQmJnQsbi5tKCkuZGVidWcobi51K1wiQ2xvc2luZyBjb25uZWN0aW9uIFtyZWNvbm5lY3Q6XCIrdGhpcy5nSStcIl1cIiksdGhpcy5iSSgpLG51bGwhPXRoaXMuT3AmJih0aGlzLk9wLmNsb3NlKCksdGhpcy5PcD1udWxsKX0sdC5wcm90b3R5cGUuRUk9ZnVuY3Rpb24oKXtmb3IoO3RoaXMueUkubGVuZ3RoPjA7KXt2YXIgdD10aGlzLnlJLnBvcCgpO3RyeXt0LmFJKCk/dC5zSS5yZWplY3QobmV3IEVycm9yKFwiTWVzc2FnZSBleHBpcmVkXCIpKToodGhpcy5JSSgpLHRoaXMuT3Auc2VuZCh0Lm1zZy5tbygpKSl9Y2F0Y2goZSl7aWYoZS5jb2RlPT09RE9NRXhjZXB0aW9uLklOVkFMSURfU1RBVEVfRVJSKXt0aGlzLnlJLnB1c2godCk7YnJlYWt9bi5tKCkuZXJyb3Iobi51K1wiRmFpbGVkIHRvIHNlbmQgdGhlIG1lc3NhZ2UsIGRyb3BwZWQ6IFwiLGUuY29kZSxlLm5hbWUpLHQuc0kucmVqZWN0KGUpfX10aGlzLlJJKCl9LHQucHJvdG90eXBlLklJPWZ1bmN0aW9uKCl7dGhpcy5rSSYmKGNsZWFyVGltZW91dCh0aGlzLmtJKSx0aGlzLmtJPW51bGwpfSx0LnByb3RvdHlwZS5SST1mdW5jdGlvbigpe3ZhciB0PXRoaXM7dGhpcy5mSSYmIXRoaXMua0kmJih0aGlzLmtJPXdpbmRvdy5zZXRJbnRlcnZhbChmdW5jdGlvbigpe3Quc2VuZChuZXcgbi5abihTZXJ2aWNlcy5DZiwwLFwiXCIpKX0sdGhpcy5tSSkpfSx0LnByb3RvdHlwZS5zZW5kPWZ1bmN0aW9uKHQsZSl7aWYodm9pZCAwPT09ZSYmKGU9dGhpcy54byksdGhpcy55SS5sZW5ndGg+PXRoaXMuTm8pdGhyb3cgbmV3IEVycm9yKFwiSGl2ZVNlcnZpY2VzIGNvbm5lY3Rpb24gY2Fubm90IHF1ZXVlIG1vcmUgbWVzc2FnZXNcIik7dmFyIGk9bmV3IG8odCxlKTtyZXR1cm4gdGhpcy55SS5wdXNoKGkpLHRoaXMuT3AmJnRoaXMuRUkoKSxpLnNJLnZ0fSx0LnByb3RvdHlwZS5DST1mdW5jdGlvbih0KXt0aGlzLmZJPXQsdGhpcy5mSSYmdGhpcy5SSSgpfSx0LnByb3RvdHlwZS5PST1mdW5jdGlvbigpe3JldHVybiBudWxsIT10aGlzLk9wfSx0fSgpO2UuQUk9c30sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPWkoMTUpLG49aSgzOCksbz1pKDI0KSxzPWkoMiksYT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHQucHJvdG90eXBlLmFwcGx5PWZ1bmN0aW9uKHQpe3QuYmluZChuZXcgci5ucyhzLkZyYW1ld29yay5GZS5tZSxuLk5JLHIuc3MubHMpKSx0LmJpbmQobmV3IHIubnMocy5GcmFtZXdvcmsuRmUud2Usby5FbC5ibCkpfSx0fSgpO2UuVGQ9YX0sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjt2YXIgaT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXtcInVuZGVmaW5lZFwiIT10eXBlb2YgZ2xvYmFsP3RoaXMueEk9Z2xvYmFsOnRoaXMueEk9d2luZG93fXJldHVybiB0LnByb3RvdHlwZS5DdD1mdW5jdGlvbigpe3JldHVybiExfSx0LnByb3RvdHlwZS5CST1mdW5jdGlvbih0LGUsaSl7fSx0LnByb3RvdHlwZS5iZT1mdW5jdGlvbigpe30sdC5wcm90b3R5cGUudGltZT1mdW5jdGlvbigpe3JldHVybituZXcgRGF0ZX0sdC5wcm90b3R5cGUuc2V0VGltZW91dD1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMueEkuc2V0VGltZW91dChmdW5jdGlvbigpe3QoKX0sZSk7cmV0dXJuIGl9LHQucHJvdG90eXBlLmNsZWFyVGltZW91dD1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy54SS5jbGVhclRpbWVvdXQodCksITB9LHQucHJvdG90eXBlLnNldEludGVydmFsPWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcy54SS5zZXRJbnRlcnZhbChmdW5jdGlvbigpe3QoKX0sZSk7cmV0dXJuIGl9LHQucHJvdG90eXBlLmNsZWFySW50ZXJ2YWw9ZnVuY3Rpb24odCl7cmV0dXJuIHRoaXMueEkuY2xlYXJJbnRlcnZhbCh0KSwhMH0sdH0oKTtlLk5JPWl9LGZ1bmN0aW9uKHQsZSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGk9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQsZSl7dGhpcy5Vbz10LHRoaXMuVm89ZX1yZXR1cm4gdC5wcm90b3R5cGUuV289ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5Vb30sdC5wcm90b3R5cGUuJG89ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5Wbz90aGlzLlZvOnRoaXMuVW99LHR9KCk7ZS5GST1pfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHIsbj10aGlzJiZ0aGlzLl9fZXh0ZW5kc3x8ZnVuY3Rpb24odCxlKXtmdW5jdGlvbiBpKCl7dGhpcy5jb25zdHJ1Y3Rvcj10fWZvcih2YXIgciBpbiBlKWUuaGFzT3duUHJvcGVydHkocikmJih0W3JdPWVbcl0pO3QucHJvdG90eXBlPW51bGw9PT1lP09iamVjdC5jcmVhdGUoZSk6KGkucHJvdG90eXBlPWUucHJvdG90eXBlLG5ldyBpKX0sbz1pKDgpLHM9by5wdC5Jci5JcixhPW8ucHQuSXIua3I7IWZ1bmN0aW9uKHQpe3ZhciBlOyFmdW5jdGlvbih0KXt2YXIgZT1mdW5jdGlvbih0KXtmdW5jdGlvbiBlKCl7dmFyIGU9bnVsbCE9PXQmJnQuYXBwbHkodGhpcyxhcmd1bWVudHMpfHx0aGlzO3JldHVybiBlLmF1dGhUb2tlbkVuYWJsZWQ9ITAsZS5kYXNoUmVtb3ZlQml0cmF0ZVNpemU9ITEsZS5kYXNoRmlsdGVyQml0cmF0ZXM9bnVsbCxlLmxvZ0pzb25TbmFwc2hvdHM9dm9pZCAwLGV9cmV0dXJuIG4oZSx0KSxlfShzKTt0LkZsPWU7dmFyIGk9ZnVuY3Rpb24odCl7ZnVuY3Rpb24gZSgpe3ZhciBlPW51bGwhPT10JiZ0LmFwcGx5KHRoaXMsYXJndW1lbnRzKXx8dGhpcztyZXR1cm4gZS5oaXZlQXV0aFRva2VuRW5hYmxlZD1cImF1dGhUb2tlbkVuYWJsZWRcIixlLmhpdmVEYXNoUmVtb3ZlQml0cmF0ZVNpemU9XCJkYXNoUmVtb3ZlQml0cmF0ZVNpemVcIixlLmhpdmVEYXNoRmlsdGVyQml0cmF0ZXM9XCJkYXNoRmlsdGVyQml0cmF0ZXNcIixlLmhpdmVMb2dKc29uU25hcHNob3RzPVwibG9nSnNvblNuYXBzaG90c1wiLGV9cmV0dXJuIG4oZSx0KSxlfShhKTt0LkRsPWl9KGU9dC5Jcnx8KHQuSXI9e30pKX0ocj1lLnB0fHwoZS5wdD17fSkpO3ZhciBjPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdC5IbD1mdW5jdGlvbih0KXtcImRhc2hSZW1vdmVCaXRyYXRlU2l6ZVwiaW4gdCYmdC5kYXNoUmVtb3ZlQml0cmF0ZVNpemUmJndpbmRvdy5IaXZlQ29uZmlnJiZ3aW5kb3cuSGl2ZUNvbmZpZy5EYXNoJiYod2luZG93LkhpdmVDb25maWcuRGFzaC5EYXNoUmVtb3ZlQml0cmF0ZVNpemU9dC5kYXNoUmVtb3ZlQml0cmF0ZVNpemUpLFwiZGFzaEZpbHRlckJpdHJhdGVzXCJpbiB0JiZ0LmRhc2hGaWx0ZXJCaXRyYXRlcyYmd2luZG93LkhpdmVDb25maWcmJndpbmRvdy5IaXZlQ29uZmlnLkRhc2gmJih3aW5kb3cuSGl2ZUNvbmZpZy5EYXNoLkRhc2hGaWx0ZXJCaXRyYXRlcz10LmRhc2hGaWx0ZXJCaXRyYXRlcyksXCJsb2dKc29uU25hcHNob3RzXCJpbiB0JiZ0LmxvZ0pzb25TbmFwc2hvdHMmJndpbmRvdy5IaXZlQ29uZmlnJiZ3aW5kb3cuSGl2ZUNvbmZpZy5EZWJ1Z0xvZ3MmJih3aW5kb3cuSGl2ZUNvbmZpZy5EZWJ1Z0xvZ3MuTWV0cmljU25hcHNob3RMb2dzPTEsd2luZG93LkhpdmVDb25maWcuRGVidWdMb2dzLlRyYWNrU25hcHNob3RMb2dzPTEsd2luZG93LkhpdmVDb25maWcuRGVidWdMb2dzLmdsPTEpfSx0fSgpO2UuTGw9Y30sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjt2YXIgaT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt2YXIgZT10aGlzO2lmKHRoaXMuX0k9bmV3IEFycmF5LHRoaXMuY2FsbGJhY2tzPW5ldyBBcnJheSx0LkdpKXRocm93IG5ldyBFcnJvcihcIkVycm9yOiBJbnN0YW50aWF0aW9uIGZhaWxlZDogVXNlIEtleUhhbmRsZXJIaXZlQ29tbS5nZXRJbnN0YW5jZSgpIGluc3RlYWQgb2YgbmV3LlwiKTt2YXIgaT17fTtkb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKFwia2V5ZG93blwiLGZ1bmN0aW9uKHQpe2lbdC5rZXlDb2RlXT0hMCxlLkRJKGkpfSwhMCksZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihcImtleXVwXCIsZnVuY3Rpb24odCl7aT17fX0sITApfXJldHVybiB0LldpPWZ1bmN0aW9uKCl7cmV0dXJuIHZvaWQgMD09PXRoaXMuR2kmJih0aGlzLkdpPW5ldyB0KSx0aGlzLkdpfSx0LnByb3RvdHlwZS5EaD1mdW5jdGlvbih0LGUpe3RoaXMuX0kucHVzaCh0KSx0aGlzLmNhbGxiYWNrcy5wdXNoKGUpfSx0LnByb3RvdHlwZS5EST1mdW5jdGlvbih0KXtmb3IodmFyIGU9ZnVuY3Rpb24oZSl7dmFyIHI9ITA7aS5fSVtlXS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3ZvaWQgMCE9dFtlXSYmdFtlXXx8KHI9ITEpfSksciYmaS5jYWxsYmFja3NbZV0oKX0saT10aGlzLHI9MDtyPHRoaXMuX0kubGVuZ3RoO3IrKyllKHIpfSx0fSgpO2UuSGg9aX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPWkoMTIpLG49aSgxOCksbz1pKDcpLHM9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQpe3RoaXMuSEk9bi5rZS55cj85OTg5Ojk5ODgsdGhpcy5MST0tMSx0aGlzLk1JPXQsdGhpcy5qSSgpfXJldHVybiB0LnByb3RvdHlwZS5qST1mdW5jdGlvbigpe3ZhciB0PXRoaXM7dGhpcy5NSS5vcHRpb25zKCkuc2lsZW50JiZ2b2lkIDA9PT10aGlzLlVJJiYodGhpcy51cmw9XCIvL1wiK3Iud3IuVG8rXCI6XCIrdGhpcy5ISStcIi9mZWVkYmFja1wiLHRoaXMuTUkubSgpLmluZm8oXCJzdGFydGluZyBwZXJpb2RpYyBhbGl2ZSBwaW5nIHRvIGhpdmUgdGVzdGVyIFtcIit0aGlzLnVybCtcIl1cIiksdGhpcy5VST1zZXRJbnRlcnZhbChmdW5jdGlvbigpe3QuVkkoKX0sbi5rZS5OaCkpfSx0LnByb3RvdHlwZS5WST1mdW5jdGlvbigpe3ZhciB0PXRoaXMsZT10aGlzLk1JLmdldEN1cnJlbnRUaW1lKCk7ZT50aGlzLkxJPyh0aGlzLk1JLm0oKS5pbmZvKFwic2VuZGluZyBoaXZlIHRlc3RlciBwaW5nIFtcIitlK1wiID4gXCIrdGhpcy5MSStcIl1cIiksby5aaSh0aGlzLnVybCkudGhlbihmdW5jdGlvbih0KXt9LGZ1bmN0aW9uKGUpe3QuTUkubSgpLmVycm9yKFwiZXJyb3Igc2VuZGluZyBoaXZlIHRlc3RlciBwaW5nXCIsZSksY2xlYXJJbnRlcnZhbCh0LlVJKX0pKTp0aGlzLk1JLm0oKS53YXJuKFwibm90IHNlbmRpbmcgaGl2ZSB0ZXN0ZXIgcGluZyBbXCIrZStcIiA8PSBcIit0aGlzLkxJK1wiXVwiKSx0aGlzLkxJPWV9LHR9KCk7ZS5VbD1zfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI9dGhpcyYmdGhpcy5fX2V4dGVuZHN8fGZ1bmN0aW9uKHQsZSl7ZnVuY3Rpb24gaSgpe3RoaXMuY29uc3RydWN0b3I9dH1mb3IodmFyIHIgaW4gZSllLmhhc093blByb3BlcnR5KHIpJiYodFtyXT1lW3JdKTt0LnByb3RvdHlwZT1udWxsPT09ZT9PYmplY3QuY3JlYXRlKGUpOihpLnByb3RvdHlwZT1lLnByb3RvdHlwZSxuZXcgaSl9LG49aSgxKSxvPWkoNykscz1pKDgpLGE9aSg0NCksYz1pKDE3KSxoPWkoMTIpLHA9aSgxNCksdT1pKDkpLGw9aSgyMCksZD1pKDE5KSxmPWEucHQuSXIsZz1zLnB0LklyLmtyLHY9Yy5wdC5IaXZlVGVjaEVycm9yLHk9Yy5wdC5iaCxtPWkoMjgpO2UuUUk9bmF2aWdhdG9yO3ZhciB3PWZ1bmN0aW9uKHQpe2Z1bmN0aW9uIGUoKXtyZXR1cm4gbnVsbCE9PXQmJnQuYXBwbHkodGhpcyxhcmd1bWVudHMpfHx0aGlzfXJldHVybiByKGUsdCksZX0oby5CaSksVD1mdW5jdGlvbigpe2Z1bmN0aW9uIHQodCxlKXt0aGlzLnFJPTAsdGhpcy5NST10LHRoaXMub3B0aW9uc189bmV3IGYuSkksdGhpcy5LSShlKSxvLm9yKHdpbmRvdy5sb2NhdGlvbi5ocmVmLG5ldyBnLHRoaXMub3B0aW9uc18pfXJldHVybiB0LnByb3RvdHlwZS5BaT1mdW5jdGlvbigpe3JldHVybiB0LkpsfSx0LnByb3RvdHlwZS5nZXRWZXJzaW9uPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMudmVyc2lvbn0sdC5wcm90b3R5cGUuV2w9ZnVuY3Rpb24oKXtyZXR1cm4hMX0sdC5wcm90b3R5cGUuR0k9ZnVuY3Rpb24oKXt2YXIgdD10aGlzO2lmKG51bGw9PXRoaXMuekl8fERhdGUubm93KCktdGhpcy5xST4xZTQpe3ZhciBlPW5ldyBtO2UuSW4obmF2aWdhdG9yLnVzZXJBZ2VudCk7dmFyIGk9ZS4kZCgpO2lmKFwiSUVcIj09PWkubmFtZSYmaS52ZXJzaW9uJiZwYXJzZUludChpLnZlcnNpb24pPDEwKXJldHVybiBuLnJlamVjdChuZXcgdih5LnloLFwiSW50ZXJuZXQgRXhwbG9yZXIgPCB2LjEwIG5vdCBzdXBwb3J0ZWRcIikpO3RoaXMuV0k9RGF0ZS5ub3coKSx0aGlzLiRJPTA7dmFyIHI9XCIvL1wiK2gud3IuVG8rXCI6XCIrdGhpcy5NSS5vcHRpb25zKCkubW9uaXRvclBvcnQrXCIvdmVyc2lvbi5qc29uXCI7dGhpcy5tKCkuZGVidWcodGhpcy5pZCgpK1widmVyaWZ5aW5nIEhpdmUgQ2xpZW50IHZlcnNpb25cIiksdGhpcy56ST1vLlppKHIpLnRoZW4oZnVuY3Rpb24oZSl7dmFyIGk9SlNPTi5wYXJzZShlKTtyZXR1cm4gdC5zdGF0ZT1pLnN0YXRlLHQudmVyc2lvbj1pLnZlcnNpb24sXCJyZWFkeVwiPT09dC5zdGF0ZT9cImRldmVsb3BlclwiPT09dC52ZXJzaW9ufHx0LnZlcnNpb24+PXQub3B0aW9uc18ubWluVmVyc2lvbj8odC4kST1EYXRlLm5vdygpLHQubSgpLmRlYnVnKHQuaWQoKStcIkhpdmUgQ2xpZW50IHJlYWR5IC0gdmVyc2lvbiBcIit0LnZlcnNpb24rXCIgW1wiKyh0LiRJLXQuV0kpK1wiXVwiKSxcInJlYWR5XCIpOihkLkVycm9yTW9uaXRvci5XaSgpLl9oKHQuaWQoKStcIkNsaWVudCB2ZXJzaW9uIHJlcXVpcmVtZW50IG5vdCBzYXRpc2ZpZWQ6IFwiK3QudmVyc2lvbitcIiA8IFwiK3Qub3B0aW9uc18ubWluVmVyc2lvbiksdC5NSS5lZChuZXcgdS5GLnVvKG51bGwsdS5GLkdyLlFyKSksbi5yZWplY3QobmV3IHYoeS5UaCxcInZlcnNpb24gXCIrdC52ZXJzaW9uKSkpOihkLkVycm9yTW9uaXRvci5XaSgpLl9oKHQuaWQoKStcIkNsaWVudCBzdGF0ZTogXCIrdC5zdGF0ZSksdC5NSS5lZChuZXcgdS5GLnVvKG51bGwsdS5GLkdyLlZyKSksbi5yZWplY3QobmV3IHYoeS55aCxcInN0YXRlIFwiK3Quc3RhdGUpKSl9LGZ1bmN0aW9uKGUpe3ZhciBpPVwiQ2xpZW50IG5vdCByZWFjaGFibGVcIjtyZXR1cm4gdm9pZCAwIT1lJiZ2b2lkIDAhPWUuc3RhdHVzJiZlLnN0YXR1cyE9LTEmJihpPVwiQ2xpZW50IGNoZWNrIHJldHVybmVkIFwiK2Uuc3RhdHVzKSxkLkVycm9yTW9uaXRvci5XaSgpLl9oKHQuaWQoKStpKSx0Lk1JLmVkKG5ldyB1LkYudW8obnVsbCx1LkYuR3IuVXIpKSxuLnJlamVjdChuZXcgdih5LnloLGkpKX0pW1wiY2F0Y2hcIl0oZnVuY3Rpb24oZSl7aWYoZSBpbnN0YW5jZW9mIHYpcmV0dXJuIG4ucmVqZWN0KGUpO3ZhciBpPVwiRXJyb3IgZmV0Y2hpbmcgSGl2ZSBDbGllbnQgdmVyc2lvbjogXCIrZTtyZXR1cm4gZC5FcnJvck1vbml0b3IuV2koKS5faCh0LmlkKCkraSksbi5yZWplY3QobmV3IHYoeS55aCxpKSl9KSx0aGlzLnFJPURhdGUubm93KCl9cmV0dXJuIHRoaXMuekl9LHQucHJvdG90eXBlLmluaXRTZXNzaW9uPWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcztyZXR1cm4gdGhpcy5vcHRpb25zXy5taW5WZXJzaW9uIT1oLndyLklvP3RoaXMuR0koKS50aGVuKGZ1bmN0aW9uKCl7cmV0dXJuIGkuWUkodClbXCJjYXRjaFwiXShmdW5jdGlvbih0KXtyZXR1cm4gbi5yZWplY3QodCl9KX0pOnRoaXMuWUkodClbXCJjYXRjaFwiXShmdW5jdGlvbih0KXtyZXR1cm4gbi5yZWplY3QodCl9KX0sdC5wcm90b3R5cGUuWWw9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5vcHRpb25zXy5pbml0VGltZW91dH0sdC5wcm90b3R5cGUuc3Q9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdC5pbmRleE9mKGUuWEkpPi0xfSx0LnByb3RvdHlwZS5QaT1mdW5jdGlvbih0LGkpe3ZhciByPXRoaXM7dGhpcy5tKCkuZGVidWcodGhpcy5pZCgpK1wiU3RvcHBpbmcgc2Vzc2lvbiBcIit0LmlkK1wiIFtjb21wbGV0ZSBjbG9zZTpcIitpK1wiXVwiKTt2YXIgbj1cIi8vXCIraC53ci5UbytcIjpcIit0aGlzLk1JLm9wdGlvbnMoKS5wbGF5ZXJQb3J0K1wiL3Nlc3Npb24/YWN0aW9uPXN0b3BcIjtuKz1cIiZjdXJyZW50U2Vzc2lvbj1cIit0LmlkLGkmJihuKz1cIiZjb21wbGV0ZVN0b3A9dHJ1ZVwiKSxpJiZlLlFJLnNlbmRCZWFjb24/KGUuUUkuc2VuZEJlYWNvbihuKSx0aGlzLm0oKS5kZWJ1Zyh0aGlzLmlkKCkrXCJzZXNzaW9uIHN0b3BwZWQgW1wiK3QuaWQrXCJdW2JlYWNvbl1cIikpOm8uWmkobixudWxsLCFpKS50aGVuKGZ1bmN0aW9uKCl7ci5tKCkuZGVidWcoci5pZCgpK1wic2Vzc2lvbiBzdG9wcGVkIFtcIit0LmlkK1wiXVwiKyhpP1wiW3N5bmNdXCI6XCJcIikpfSxmdW5jdGlvbihlKXtyLm0oKS53YXJuKHIuaWQoKStcInNlc3Npb24gY2xvc2UgZXJyb3IgW1wiK3QuaWQrXCJdXCIrKGk/XCJbc3luY11cIjpcIlwiKSxlKX0pfSx0LnByb3RvdHlwZS5DaT1mdW5jdGlvbih0LGUpe3RoaXMuWkk9ZT9wLkZvLklETEU6cC5Gby5Cbyx0aGlzLm0oKS5ub3RpY2UoXCJbSGl2ZUNvbW1dIGNsaWVudCBzdGF0ZTogXCIrcC5Gb1t0aGlzLlpJXSl9LHQucHJvdG90eXBlLmZkPWZ1bmN0aW9uKHQsZSl7aWYodGhpcy5aST09cC5Gby5JRExFKXJldHVybiBuLnJlc29sdmUoITApO3ZhciBpPVwicGxheWluZy1wb2ludD1cIitlLmxyO2krPVwiJmJ1ZmZlci1sZW5ndGg9XCIrZS5kcixpKz1cIiZ0b3RhbC1idWZmZXJpbmc9XCIrZS5ncixpKz1cIiZ3aWR0aD1cIitlLndpZHRoLGkrPVwiJmhlaWdodD1cIitlLmhlaWdodCxpKz1cIiZmdWxsc2NyZWVuPVwiK2UuZGQ7dmFyIHI9dC5YSStcInN0YXRzP1wiK2k7cmV0dXJuIHRoaXMubSgpLnRyYWNlKHIpLG8uWmkocil9LHQucHJvdG90eXBlLnlkPWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj10aGlzO2lmKCEoZSE9PXUuRi5CLmpyJiZlIT09dS5GLkIuSElEREVOfHx0aGlzLnZlcnNpb24mJihcImRldmVsb3BlclwiPT09dGhpcy52ZXJzaW9ufHx0aGlzLnZlcnNpb24+PVwiMjAxN1wiKSkpcmV0dXJuIG4ucmVzb2x2ZSghMCk7dmFyIHM9dC5YSStcInBsYXllci1ldmVudD90eXBlPVwiK3UuRi5CW2VdO2lmKHZvaWQgMCE9aSlmb3IodmFyIGEgaW4gaSlzKz1cIiZcIithK1wiPVwiK2lbYV07cmV0dXJuIHRoaXMubSgpLmRlYnVnKHRoaXMuaWQoKStcImV2ZW50IFwiK3UuRi5CW2VdLHZvaWQgMCE9aT9pOlwiXCIpLG8uWmkocykuZmFpbChmdW5jdGlvbih0KXtyZXR1cm4gci5tKCkud2FybihyLmlkKCkrXCJlcnJvciBzZW5kaW5nIGZlZWRiYWNrIGV2ZW50IHRvIEhpdmUgQ2xpZW50XCIsdCksbi5yZWplY3QodCl9KX0sdC5wcm90b3R5cGUud249ZnVuY3Rpb24odCxlKXtyZXR1cm4gbi5yZXNvbHZlKCEwKX0sdC5wcm90b3R5cGUuaG49ZnVuY3Rpb24odCl7dmFyIGU9dGhpcztpZih0aGlzLnRSKCkpcmV0dXJuIHRoaXMubSgpLndhcm4oXCJQbGF5ZXIgaW5mbyBub3Qgc3VwcG9ydGVkIGluIHRoaXMgSmF2YSBjbGllbnQgdmVyc2lvblwiKSxuLnJlc29sdmUoITApO3ZhciBpPVwiY29tbS12ZXJzaW9uPVwiK3RoaXMuTUkuY3QoKTtpKz1cIiZwbHVnaW4tbmFtZT1cIit0aGlzLk1JLlQoKSxpKz1cIiZwbHVnaW4tdmVyc2lvbj1cIit0aGlzLk1JLkkoKSxpKz1cIiZwbGF5ZXItdGVjaD1cIit0aGlzLk1JLmh0KCksaSs9XCImcGxheWVyLXZlcnNpb249XCIrdGhpcy5NSS5xKCk7dmFyIHI9dGhpcy5NSS50ZCgpO3ImJihpKz1cIiZ0ZWxlbWV0cnktaWQ9XCIrdGhpcy5NSS50ZCgpKTt2YXIgcz10LlhJK1wicGxheWVyLWluZm8/XCIraTtyZXR1cm4gby5aaShzKS5mYWlsKGZ1bmN0aW9uKHQpe3JldHVybiBlLm0oKS5kZWJ1ZyhlLmlkKCkrXCJlcnJvciBzZW5kaW5nIHBsYXllciBJbmZvIHRvIEhpdmUgQ2xpZW50XCIsdCksbi5yZWplY3QodCl9KX0sdC5wcm90b3R5cGUub25FcnJvcj1mdW5jdGlvbih0KXt2YXIgZT0hMDtpZih2b2lkIDAhPXRoaXMub3B0aW9uc18ub25FcnJvcil0cnl7ZT10aGlzLm9wdGlvbnNfLm9uRXJyb3IodCl9Y2F0Y2goaSl7ZC5FcnJvck1vbml0b3IuV2koKS5faCh0aGlzLmlkKCkrXCJleGNlcHRpb24gaW4gdXNlci1kZWZpbmVkIG9uRXJyb3IgY2FsbGJhY2s6IFwiK2kpfXJldHVybiBlfSx0LnByb3RvdHlwZS5abD1mdW5jdGlvbih0LGUsaSl7dmFyIHI9e2lzUmVhZHlJbjp0aGlzLldJLGlzUmVhZHlPdXQ6dGhpcy4kSSxsZWFzZUluOnRoaXMuZVIsbGVhc2VPdXQ6dGhpcy5pUixyZXNvbHZlSW46dGhpcy5yUixyZXNvbHZlT3V0OnRoaXMublJ9O1widW5kZWZpbmVkXCIhPXR5cGVvZiBlJiZudWxsIT1lJiYoci5zZXNzaW9uSWQ9ZS5pZCksXCJ1bmRlZmluZWRcIiE9dHlwZW9mIGkmJihyLnRvdGFsPWkpO3ZhciBuPUpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkocikpO2QuRXJyb3JNb25pdG9yLldpKCkuX2godC5tZXNzYWdlLG4pLHRoaXMuTUkuZWQobmV3IHUuRi51byhudWxsLHUuRi5Hci5LcixyKSksdGhpcy5vUigpfSx0LnByb3RvdHlwZS5vbkFjdGl2ZVNlc3Npb249ZnVuY3Rpb24odCl7aWYodGhpcy5obih0KSxvLmFyLnNldEl0ZW0oXCJoaXZlQWN0aXZlU2Vzc2lvbklkXCIsdC5pZCksdm9pZCAwIT10aGlzLm9wdGlvbnNfLm9uQWN0aXZlU2Vzc2lvbil0cnl7dGhpcy5vcHRpb25zXy5vbkFjdGl2ZVNlc3Npb24odC5nKCkpfWNhdGNoKGUpe2QuRXJyb3JNb25pdG9yLldpKCkuX2godGhpcy5pZCgpK1wiZXhjZXB0aW9uIGluIHVzZXItZGVmaW5lZCBvbkFjdGl2ZVNlc3Npb24gY2FsbGJhY2s6IFwiK2UpfX0sdC5wcm90b3R5cGUucWw9ZnVuY3Rpb24odCl7dGhpcy5NST10fSx0LnByb3RvdHlwZS5pZD1mdW5jdGlvbigpe3JldHVyblwiW1wiK3QuSmwrXCJdIFwifSx0LnByb3RvdHlwZS5LST1mdW5jdGlvbihlKXt2b2lkIDAhPWVbdC5KbF0mJm8ubnIoZVt0LkpsXSx0aGlzLm9wdGlvbnNfKX0sdC5wcm90b3R5cGUuWUk9ZnVuY3Rpb24odCl7dmFyIGU9dGhpcyxpPShuZXcgRGF0ZSkuZ2V0VGltZSgpO3JldHVybiB0aGlzLnNSKHQpLnRoZW4oZnVuY3Rpb24ocil7cmV0dXJuIHI/ZS5hUih0LHIsaSk6ZS5wKHQpLnRoZW4oZnVuY3Rpb24ocil7cmV0dXJuIGUuYVIodCxyLGkpfSl9KX0sdC5wcm90b3R5cGUuc1I9ZnVuY3Rpb24oZSl7dmFyIGk9dGhpcztpZih0aGlzLmVSPURhdGUubm93KCksdGhpcy5NSS5vcHRpb25zKCkudXNlU2Vzc2lvbkNoZWNrKXt2YXIgcj1cIi8vXCIraC53ci5UbytcIjpcIit0aGlzLk1JLm9wdGlvbnMoKS5wbGF5ZXJQb3J0K1wiL3Nlc3Npb24/JmFjdGlvbj1jaGVja1wiO3IrPVwiJmhpdmVQbHVnaW5JZD1cIit0aGlzLk1JLlMoKSxyKz1cIiZjYWxsYmFjaz1cIitlO3ZhciBzPW8uYXIuZ2V0SXRlbShcImhpdmVBY3RpdmVTZXNzaW9uSWRcIik7cmV0dXJuIG8uYXIucmVtb3ZlSXRlbShcImhpdmVBY3RpdmVTZXNzaW9uSWRcIikscyYmKHIrPVwiJmN1cnJlbnRTZXNzaW9uPVwiK3MpLHRoaXMuY1IoKSxvLlppKHIpLnRoZW4oZnVuY3Rpb24odCl7cmV0dXJuIGkuaVI9RGF0ZS5ub3coKSx0P2kuaFIodCxyLGUsaS5lUik6KGkubSgpLmRlYnVnKGkuaWQoKStcInNlc3Npb24gYWxsb3dlZCBbXCIrKGkuaVItaS5lUikrXCJdXCIpLCExKX0sZnVuY3Rpb24oZSl7aWYoNDAwPT1lLnN0YXR1cylyZXR1cm4gaS5wUihcImJhZCByZXF1ZXN0XCIsXCJlcnJvciByZXNvbHZpbmcgdGlja2V0XCIsZSk7aWYoNDAxPT1lLnN0YXR1cylyZXR1cm4gaS5wUihcInVuYXV0aG9yaXplZFwiLFwiZXJyb3IgdmVyaWZ5aW5nIHRoZSB0aWNrZXRcIixlKTtpZig0MDM9PWUuc3RhdHVzKXt2YXIgcj10LnVSKGUsdm9pZCAwLFwic2Vzc2lvblwiKSxvPXI/e2xSOnJ9OnZvaWQgMDtyZXR1cm4gZC5FcnJvck1vbml0b3IuV2koKS5faChpLmlkKCkrXCJyZXBvcnRzIGFub3RoZXIgYWN0aXZlIHNlc3Npb25cIixvKSxpLk1JLmVkKG5ldyB1LkYudW8obnVsbCx1LkYuR3IucXIsbykpLG4ucmVqZWN0KG5ldyB2KHkud2gsXCJhbm90aGVyIGFjdGl2ZSBzZXNzaW9uXCIrKG8/XCIgW1wiK28ubFIrXCJdXCI6XCJcIikpKX1yZXR1cm4gNDA0PT1lLnN0YXR1cz8oaS5tKCkuZGVidWcoaS5pZCgpK1wiaW5zdGFsbGVkIHZlcnNpb24gZG9lcyBub3Qgc3VwcG9ydCBhY3RpdmUgc2Vzc2lvbiBjaGVja1wiKSxpLmlSPURhdGUubm93KCksITEpOmUuc3RhdHVzPT0tMT8oY2xlYXJUaW1lb3V0KGkuZFIpLGkuZlIoKSk6KGQuRXJyb3JNb25pdG9yLldpKCkuX2goaS5pZCgpK1wiIHVuaGFuZGxlZCBlcnJvciBmcm9tIEphdmFcIix7ZXJyb3I6ZS5zdGF0dXN9KSxpLk1JLmVkKG5ldyB1LkYudW8obnVsbCx1LkYuR3IuSnIpKSxuLnJlamVjdChuZXcgdih5Lm1oLGUpKSl9KVtcImNhdGNoXCJdKGZ1bmN0aW9uKHQpe3JldHVybiB0IGluc3RhbmNlb2Ygdj9uLnJlamVjdCh0KTooZC5FcnJvck1vbml0b3IuV2koKS5faChpLmlkKCkrXCIgdW5oYW5kbGVkIGVycm9yIG9uIHJlcXVlc3RMZWFzZURpcmVjdFwiLHtlcnJvcjp0fSksaS5NSS5lZChuZXcgdS5GLnVvKG51bGwsdS5GLkdyLkpyKSksbi5yZWplY3QobmV3IHYoeS5taCx0KSkpfSlbXCJmaW5hbGx5XCJdKGZ1bmN0aW9uKCl7Y2xlYXJUaW1lb3V0KGkuZFIpfSl9cmV0dXJuIHRoaXMubSgpLmRlYnVnKHRoaXMuaWQoKStcIkhpdmUgc2Vzc2lvbiBjaGVjayBkaXNhYmxlZCAtIHdpbGwgZGlyZWN0bHkgcmVzb2x2ZSB0aWNrZXQgKG90aGVyIGFjdGl2ZSBzZXNzaW9ucyBtYXkgZmFpbClcIiksbi5yZXNvbHZlKCExKX0sdC5wcm90b3R5cGUucFI9ZnVuY3Rpb24oZSxpLHIpe3ZhciBvPXQudVIocixlKTtyZXR1cm4gZC5FcnJvck1vbml0b3IuV2koKS5faChcIlwiK3RoaXMuaWQoKStpKSx0aGlzLm5SPURhdGUubm93KCksbi5yZWplY3QobmV3IHYoeS5waCxvKSl9LHQudVI9ZnVuY3Rpb24odCxlLGkpe3ZvaWQgMD09PWkmJihpPVwic3RhdHVzXCIpO3ZhciByPWU7aWYodC5ib2R5KXRyeXt2YXIgbj1KU09OLnBhcnNlKHQuYm9keSk7cj1uW2ldfWNhdGNoKG8pe31yZXR1cm4gcn0sdC5wcm90b3R5cGUucD1mdW5jdGlvbih0KXt2YXIgZT10aGlzO3RoaXMuclI9RGF0ZS5ub3coKSx0aGlzLm0oKS5kZWJ1Zyh0aGlzLmlkKCkrXCJyZXNvbHZpbmcgdGlja2V0OiBcIit0KTt2YXIgaT10aGlzLmdSKHQpO3JldHVybiBvLlppKGksXCJhcHBsaWNhdGlvbi9qc29uXCIpLnRoZW4oZnVuY3Rpb24ocil7cmV0dXJuIGUuaFIocixpLHQsZS5yUil9LGZ1bmN0aW9uKGkpe3JldHVybiBpJiZpLnN0YXR1cz09LTE/ZS5mUigpOihkLkVycm9yTW9uaXRvci5XaSgpLl9oKGUuaWQoKStcImVycm9yIHJlc29sdmluZyB0aWNrZXRcIix7dGlja2V0OnR9KSxuLnJlamVjdChuZXcgdih5LnBoLGkpKSl9KVtcImNhdGNoXCJdKGZ1bmN0aW9uKHQpe3JldHVybiBkLkVycm9yTW9uaXRvci5XaSgpLl9oKGUuaWQoKStcImVycm9yIHBhcnNpbmcgdGlja2V0IHJlc3BvbnNlOiBcIit0KSxuLnJlamVjdChuZXcgdih5Lm1oLHQpKX0pfSx0LnByb3RvdHlwZS5oUj1mdW5jdGlvbih0LGUsaSxyKXt2YXIgbj1KU09OLnBhcnNlKHQpLHM9by5pcihlLG4ubG9jYXRpb24pO3JldHVybiBuLnZlcnNpb24mJiF0aGlzLnZlcnNpb24mJih0aGlzLnZlcnNpb249bi52ZXJzaW9uKSx0aGlzLm5SPURhdGUubm93KCksdGhpcy5tKCkuZGVidWcodGhpcy5pZCgpK1wicmVzb2x2ZWQgdGlja2V0IFwiK2krXCIgLT4gXCIrcytcIiBbXCIrKHRoaXMublItcikrXCJdXCIpLHN9LHQucHJvdG90eXBlLmFSPWZ1bmN0aW9uKHQsZSxpKXt2YXIgcj10aGlzLnZSKHQsZSk7aWYobnVsbCE9cil7dmFyIG49KG5ldyBEYXRlKS5nZXRUaW1lKCkscz1uLWk7cmV0dXJuIHM+PXRoaXMub3B0aW9uc18ud2FyblNsb3dSZXNwVGltZW91dCYmdGhpcy5abChuZXcgdih5LlNoLHRoaXMuaWQoKStcIiBUaGUgdGVjaCBpbml0aWFsaXphdGlvbiB0b29rIG1vcmUgdGhhbiBcIit0aGlzLm9wdGlvbnNfLndhcm5TbG93UmVzcFRpbWVvdXQrXCIgbWlsbGlzZWNvbmRzXCIpLHIscyksby5IaXZlUmVxdWVzdEZhY3RvcnkuYmkoci5pZCx0aGlzLkFpKCkpLHJ9dGhyb3cgbmV3IHYoeS5waCxcImVycm9yIGdlbmVyYXRpbmcgc2Vzc2lvblwiKX0sdC5wcm90b3R5cGUudlI9ZnVuY3Rpb24odCxlKXt2YXIgaT1uZXcgbC5hcDtpLktoKHQpO3ZhciByPW5ldyB3KHQsaSxlLG51bGwpO3IueVI9ITA7dmFyIG49aC53ci5FbyxvPW4uZXhlYyhyLm1hbmlmZXN0KTtyZXR1cm4gbnVsbCE9bz8oci5YST1vWzFdLHIuaWQ9b1s1XSxyKTpudWxsfSx0LnByb3RvdHlwZS5nUj1mdW5jdGlvbih0KXt2YXIgZT10LmluZGV4T2YoXCI/XCIpPT0tMT9cIj9cIjpcIiZcIjtyZXR1cm4gdGhpcy50UigpP28ucnIoaC53ci5ibyxoLndyLlRvLHRoaXMuTUkub3B0aW9ucygpLnBsYXllclBvcnQsdCk6by5ycihoLndyLlNvLGgud3IuVG8sdGhpcy5NSS5vcHRpb25zKCkucGxheWVyUG9ydCx0LGUsdGhpcy5NSS5TKCkpfSx0LnByb3RvdHlwZS5jUj1mdW5jdGlvbigpe3ZhciB0PXRoaXM7dGhpcy5kUiYmY2xlYXJUaW1lb3V0KHRoaXMuZFIpLHRoaXMuZFI9c2V0VGltZW91dChmdW5jdGlvbigpe2QuRXJyb3JNb25pdG9yLldpKCkuX2godC5pZCgpK1wiIFRoZSBMZWFzZSBSZXF1ZXN0IGlzIHRha2luZyBtb3JlIHRoYW4gXCIrdC5vcHRpb25zXy53YXJuU2xvd1Jlc3BUaW1lb3V0K1wiIHNlY3NcIil9LHRoaXMub3B0aW9uc18ud2FyblNsb3dSZXNwVGltZW91dCl9LHQucHJvdG90eXBlLm9SPWZ1bmN0aW9uKCl7dGhpcy5lUj0wLHRoaXMuaVI9MCx0aGlzLnJSPTAsdGhpcy5uUj0wfSx0LnByb3RvdHlwZS5tPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuTUkubSgpfSx0LnByb3RvdHlwZS56bD1mdW5jdGlvbigpe3RoaXMub1IoKX0sdC5wcm90b3R5cGUuZlI9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLGU9XCIvL1wiK2gud3IuVG8rXCI6XCIrdGhpcy5NSS5vcHRpb25zKCkubW9uaXRvclBvcnQrXCIvdmVyc2lvbi5qc29uXCI7cmV0dXJuIHRoaXMubSgpLmRlYnVnKHRoaXMuaWQoKStcImNoZWNraW5nIGlmIHRoZSBtb25pdG9yIHBvcnQgaXMgcmVhY2hhYmxlXCIpLG8uWmkoZSkudGhlbihmdW5jdGlvbihlKXt2YXIgaT1KU09OLnBhcnNlKGUpO3Rocm93IHQuc3RhdGU9aS5zdGF0ZSxkLkVycm9yTW9uaXRvci5XaSgpLl9oKHQuaWQoKStcIkNsaWVudCBzdGF0ZTogXCIrdC5zdGF0ZSksdC5NSS5lZChuZXcgdS5GLnVvKG51bGwsdS5GLkdyLlZyKSksbmV3IHYoeS55aCxcInN0YXRlIFwiK3Quc3RhdGUpfSkuZmFpbChmdW5jdGlvbihlKXtpZihlIGluc3RhbmNlb2YgdilyZXR1cm4gbi5yZWplY3QoZSk7aWYoZSYmZS5zdGF0dXM9PS0xKXt2YXIgaT1cImNsaWVudCBub3QgcmVhY2hhYmxlXCI7cmV0dXJuIHQuTUkuZWQobmV3IHUuRi51byhudWxsLHUuRi5Hci5VcikpLHQubSgpLndhcm4odC5pZCgpK2kpLG4ucmVqZWN0KG5ldyB2KHkueWgsaSkpfXZhciBpPVwiVmVyaWZ5Q2xpZW50U3RhdGUgZXJyb3JcIjtyZXR1cm4gZC5FcnJvck1vbml0b3IuV2koKS5faCh0LmlkKCkraSx7ZXJyb3I6ZX0pLHQuTUkuZWQobmV3IHUuRi51byhudWxsLHUuRi5Hci5WcikpLG4ucmVqZWN0KG5ldyB2KHkubWgsaSkpfSl9LHQucHJvdG90eXBlLnRSPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMub3B0aW9uc18uc3VwcG9ydExlZ2FjeUNsaWVudCYmKCF0aGlzLnZlcnNpb258fHRoaXMudmVyc2lvbi5zdWJzdHIoMCw0KTxcIjIwMTZcIil9LHR9KCk7VC5KbD1cIkhpdmVKYXZhXCIsZS5IaXZlSmF2YT1UfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHIsbj10aGlzJiZ0aGlzLl9fZXh0ZW5kc3x8ZnVuY3Rpb24odCxlKXtmdW5jdGlvbiBpKCl7dGhpcy5jb25zdHJ1Y3Rvcj10fWZvcih2YXIgciBpbiBlKWUuaGFzT3duUHJvcGVydHkocikmJih0W3JdPWVbcl0pO3QucHJvdG90eXBlPW51bGw9PT1lP09iamVjdC5jcmVhdGUoZSk6KGkucHJvdG90eXBlPWUucHJvdG90eXBlLG5ldyBpKX0sbz1pKDgpLHM9aSgxMik7IWZ1bmN0aW9uKHQpe3ZhciBlOyFmdW5jdGlvbih0KXt2YXIgZT1mdW5jdGlvbih0KXtmdW5jdGlvbiBlKCl7dmFyIGU9bnVsbCE9PXQmJnQuYXBwbHkodGhpcyxhcmd1bWVudHMpfHx0aGlzO3JldHVybiBlLm1pblZlcnNpb249cy53ci5JbyxlLmluaXRUaW1lb3V0PTZlNCxlLndhcm5TbG93UmVzcFRpbWVvdXQ9NWUzLGUuc3VwcG9ydExlZ2FjeUNsaWVudD0hMSxlfXJldHVybiBuKGUsdCksZX0oby5wdC5Jci5Scik7dC5KST1lfShlPXQuSXJ8fCh0LklyPXt9KSl9KHI9ZS5wdHx8KGUucHQ9e30pKX0sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjt2YXIgaT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHR9KCk7aS5Ubz1cIjEyNy4wLjAuMVwiLGkuT2Q9MTE5ODMsaS5Tbz1cIi8vezB9OnsxfS9wcm94eS8/Y2FsbGJhY2s9ezJ9ezN9aGl2ZVBsdWdpbklkPXs0fVwiLGkubVI9XCIvL3swfTp7MX0vcHJveHkvezJ9L3Nlc3Npb24/bWFuaWZlc3Q9ezN9XCIsaS5rZD1cIi8vezB9OnsxfS9wcm94eS97Mn0vcGxheWVyP3JlcT17M31cIixpLndSPVwiLy97MH06ezF9L3Byb3h5L3syfS9pbmZvP3szfVwiLGUuQ2Q9aX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPXRoaXMmJnRoaXMuX19leHRlbmRzfHxmdW5jdGlvbih0LGUpe2Z1bmN0aW9uIGkoKXt0aGlzLmNvbnN0cnVjdG9yPXR9Zm9yKHZhciByIGluIGUpZS5oYXNPd25Qcm9wZXJ0eShyKSYmKHRbcl09ZVtyXSk7dC5wcm90b3R5cGU9bnVsbD09PWU/T2JqZWN0LmNyZWF0ZShlKTooaS5wcm90b3R5cGU9ZS5wcm90b3R5cGUsbmV3IGkpfSxuPWkoMjYpLG89ZnVuY3Rpb24odCl7ZnVuY3Rpb24gZSgpe3JldHVybiBudWxsIT09dCYmdC5hcHBseSh0aGlzLGFyZ3VtZW50cyl8fHRoaXN9cmV0dXJuIHIoZSx0KSxlLmJpPWZ1bmN0aW9uKHQsaSl7ZS5UUltpXT10fSxlLlNSPWZ1bmN0aW9uKHQsaSl7ZS5iUltpXT10fSxlLnByb3RvdHlwZS5zZW5kPWZ1bmN0aW9uKCl7aWYoIXRoaXMuc2Vzc2lvbklkKXt2YXIgdD1PYmplY3Qua2V5cyhlLmJSKTt0Lmxlbmd0aD4wJiYodGhpcy5zZXNzaW9uSWQ9ZS5iUlt0WzBdXSl9dmFyIGk9ZS5UUlt0aGlzLnNlc3Npb25JZF0scj1lLmJSW3RoaXMuc2Vzc2lvbklkXTtyLm0oKS5kZWJ1ZyhcIkludGVyY2VwdGVkIE1hbmlmZXN0IFJlcXVlc3QgXCIrdGhpcy51cmwpLGkuc2V0TWFuaWZlc3RSZXF1ZXN0KHRoaXMpLHIuUih0aGlzLnVybCl9LGUucHJvdG90eXBlLkVSPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxlPW5ldyBYTUxIdHRwUmVxdWVzdDtlLm9wZW4oXCJHRVRcIix0aGlzLnVybCksZS5vbnJlYWR5c3RhdGVjaGFuZ2U9ZnVuY3Rpb24oKXs0PT09ZS5yZWFkeVN0YXRlJiYodC5yZXNwb25zZT1lLnJlc3BvbnNlVGV4dCx0LnJlc3BvbnNlVGV4dD1lLnJlc3BvbnNlVGV4dCx0LnJlYWR5U3RhdGU9NCx0LnN0YXR1cz1lLnN0YXR1cyx0Lm9ucmVhZHlzdGF0ZWNoYW5nZSgpLHQub25sb2FkKCksY29uc29sZS5kZWJ1ZyhcIlJldHVybmVkIE1hbmlmZXN0IFJlcXVlc3QgXCIrdC51cmwpKX0sZS5zZW5kKCl9LGUucHJvdG90eXBlLklSPWZ1bmN0aW9uKCl7dC5wcm90b3R5cGUuc2VuZC5jYWxsKHRoaXMpfSxlfShuLlRpKTtvLmJSPXt9LG8uVFI9e30sZS5TaT1vfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHIsbj10aGlzJiZ0aGlzLl9fZXh0ZW5kc3x8ZnVuY3Rpb24odCxlKXtmdW5jdGlvbiBpKCl7dGhpcy5jb25zdHJ1Y3Rvcj10fWZvcih2YXIgciBpbiBlKWUuaGFzT3duUHJvcGVydHkocikmJih0W3JdPWVbcl0pO3QucHJvdG90eXBlPW51bGw9PT1lP09iamVjdC5jcmVhdGUoZSk6KGkucHJvdG90eXBlPWUucHJvdG90eXBlLG5ldyBpKX0sbz1pKDgpOyFmdW5jdGlvbih0KXt2YXIgZTshZnVuY3Rpb24odCl7dmFyIGU9ZnVuY3Rpb24odCl7ZnVuY3Rpb24gZSgpe3JldHVybiBudWxsIT09dCYmdC5hcHBseSh0aGlzLGFyZ3VtZW50cyl8fHRoaXN9cmV0dXJuIG4oZSx0KSxlfShvLnB0LklyLlJyKTt0LlJSPWV9KGU9dC5Jcnx8KHQuSXI9e30pKX0ocj1lLnB0fHwoZS5wdD17fSkpfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI9aSgxKSxuPWkoNyksbz1pKDQ3KSxzPW8ucHQuSXIuUlIsYT1pKDE0KSxjPWkoNTkpLGg9aSgxOSkscD1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoZSxpKXt0aGlzLk1JPWUsdGhpcy5vcHRpb25zXz1uZXcgcyx2b2lkIDAhPT1pW3QuSmxdJiZuLm5yKGlbdC5KbF0sdGhpcy5vcHRpb25zXyl9cmV0dXJuIHQucHJvdG90eXBlLkFpPWZ1bmN0aW9uKCl7cmV0dXJuIHQuSmx9LHQucHJvdG90eXBlLmdldFZlcnNpb249ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH0sdC5wcm90b3R5cGUuV2w9ZnVuY3Rpb24oKXtyZXR1cm4hMH0sdC5wcm90b3R5cGUuR0k9ZnVuY3Rpb24oKXtyZXR1cm4gci5yZXNvbHZlKCEwKX0sdC5wcm90b3R5cGUuaW5pdFNlc3Npb249ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzLnZSKHQsZS50aWNrZXQsZS50aWNrZXQudHAoKSxlKTtyZXR1cm4gbi5IaXZlUmVxdWVzdEZhY3RvcnkuYmkoaS5pZCx0aGlzLkFpKCkpLHIucmVzb2x2ZShpKX0sdC5wcm90b3R5cGUuWWw9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5vcHRpb25zKCkuaW5pdFRpbWVvdXR9LHQucHJvdG90eXBlLnN0PWZ1bmN0aW9uKHQsZSl7dmFyIGk9ZS5tYW5pZmVzdC50b0xvd2VyQ2FzZSgpLmluZGV4T2YoXCIvbWFuaWZlc3RcIik7aWYoaT4tMSl7dmFyIHI9ZS5tYW5pZmVzdC5zdWJzdHJpbmcoMCxpKTtpZih0LmluZGV4T2Yocik+LTEpcmV0dXJuITB9ZWxzZSBpZih0PT1lLm1hbmlmZXN0KXJldHVybiEwO3JldHVybiExfSx0LnByb3RvdHlwZS5QaT1mdW5jdGlvbih0KXt0LlJpJiYodGhpcy5NSS5tKCkuZGVidWcoXCJbU3RhdHNKU10gc3RvcHBpbmcgc2Vzc2lvbiBbXCIrdC5pZCtcIl1cIiksdC5SaS5Iby5yZXNldCgpKX0sdC5wcm90b3R5cGUuQ2k9ZnVuY3Rpb24odCxlKXt2YXIgaT1lP2EuRm8uSURMRTphLkZvLkJvO3RoaXMuTUkubSgpLm5vdGljZShcIltIaXZlQ29tbV0gY2xpZW50IHN0YXRlOiBcIithLkZvW2ldKSx0LlJpJiZ0LlJpLkNpKGkpfSx0LnByb3RvdHlwZS5mZD1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXMsbj0wO3JldHVybiB0aGlzLmtSPGUuZ3ImJihuPWUuZ3ItdGhpcy5rUix0aGlzLmtSPWUuZ3IpLHQuTmkoKS50aGVuKGZ1bmN0aW9uKCl7dC5SaS5Eby5DUihuLGUuZHIpLHQuUmkuUW4udm4oZS5scixlLmRyLGUuZ3IpLGkuT1IoKX0pLmRvbmUoKSxyLnJlc29sdmUoITApfSx0LnByb3RvdHlwZS55ZD1mdW5jdGlvbih0LGUsaSl7cmV0dXJuIHQuTmkoKS50aGVuKGZ1bmN0aW9uKCl7dC5SaS5Rbi5tbih0LnRpY2tldC5zZXNzaW9uSWQsZSxpKX0pLmRvbmUoKSxyLnJlc29sdmUoITApfSx0LnByb3RvdHlwZS53bj1mdW5jdGlvbih0LGUpe3JldHVybiB0Lk5pKCkudGhlbihmdW5jdGlvbigpe3QuUmkuUW4uVG4oW2VdKX0pLmRvbmUoKSxyLnJlc29sdmUoITApfSx0LnByb3RvdHlwZS5vbkVycm9yPWZ1bmN0aW9uKHQpe3ZhciBlPSEwO2lmKHZvaWQgMCE9dGhpcy5vcHRpb25zKCkub25FcnJvcil0cnl7ZT10aGlzLm9wdGlvbnMoKS5vbkVycm9yKHQpfWNhdGNoKGkpe2guRXJyb3JNb25pdG9yLldpKCkuX2goXCJbU3RhdHNKU10gZXhjZXB0aW9uIGluIHVzZXItZGVmaW5lZCBvbkVycm9yIGNhbGxiYWNrOiBcIitpKX1yZXR1cm4gZX0sdC5wcm90b3R5cGUub25BY3RpdmVTZXNzaW9uPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXM7dGhpcy5QUigpLHQuTmkoKS50aGVuKGZ1bmN0aW9uKGkpe2UuQVI9aTt2YXIgcj1uZXcgYy5OUihlLk1JLmlzTGl2ZSgpLGUuTUkuJCgpLHQudGlja2V0LnRwKCkpO2UuQVIueFI9cixlLkFSLkRvLnhSPXIsZS5NSS5obihlLkFSKSxlLkFSLkhvLmluaXQoZS5BUi5EbyxudWxsKSxlLkFSLlFuLndpKHQudGlja2V0LnNlc3Npb25JZCxlLk1JLml0KCksMjAwKTt2YXIgbj1lLk1JLnJkKCk7aWYobiYmbi5sZW5ndGg+MCYmZS5BUi5Rbi5UbihuKSx2b2lkIDAhPWUub3B0aW9uc18ub25BY3RpdmVTZXNzaW9uKXRyeXtlLm9wdGlvbnNfLm9uQWN0aXZlU2Vzc2lvbih0LmcoKSl9Y2F0Y2gobyl7aC5FcnJvck1vbml0b3IuV2koKS5faChcIltTdGF0c0pTXSBleGNlcHRpb24gaW4gdXNlci1kZWZpbmVkIG9uQWN0aXZlU2Vzc2lvbiBjYWxsYmFjazogXCIrbyl9fSkuZG9uZSgpfSx0LnByb3RvdHlwZS5abD1mdW5jdGlvbigpe30sdC5wcm90b3R5cGUuemw9ZnVuY3Rpb24oKXt9LHQucHJvdG90eXBlLnFsPWZ1bmN0aW9uKHQpe3RoaXMuTUk9dH0sdC5wcm90b3R5cGUub3B0aW9ucz1mdW5jdGlvbigpe3JldHVybiB0aGlzLm9wdGlvbnNffSx0LnByb3RvdHlwZS5QUj1mdW5jdGlvbigpe3RoaXMua1I9MH0sdC5wcm90b3R5cGUudlI9ZnVuY3Rpb24odCxlLGkscil7dmFyIG89bmV3IG4uQmkodCxlLGkscik7cmV0dXJuIG8ueVI9ITEsby5pZD1lLnNlc3Npb25JZCxvfSx0LnByb3RvdHlwZS5PUj1mdW5jdGlvbigpe3RyeXt2YXIgdD10aGlzLk1JLmF0KCk7dm9pZCAwIT10JiYodGhpcy5BUi5Eby5CUi5tZXRyaWNzLmJpdHJhdGVVcE4rPXQuSmkoKSx0aGlzLkFSLkRvLkJSLm1ldHJpY3MuYml0cmF0ZUR3bk4rPXQuS2koKSxudWxsIT10LlZpKCkmJih0aGlzLkFSLkRvLkJSLm1ldHJpY3Muc3JjVGhyb3VnaHB1dD10LlZpKCkpLG51bGwhPXQuUWkoKSYmdGhpcy5GUighMCx0LlFpKCkpLG51bGwhPXQucWkoKSYmdGhpcy5GUighMSx0LnFpKCkpKX1jYXRjaChlKXtoLkVycm9yTW9uaXRvci5XaSgpLl9oKGUpfX0sdC5wcm90b3R5cGUuRlI9ZnVuY3Rpb24odCxlKXt2YXIgaT10aGlzLHI9MCxuPTAsbz0wLHM9MDtlLmZvckVhY2goZnVuY3Rpb24oZSxhKXt2YXIgYz1lLnN1Y2Nlc3MrZS5faTtpZihyKz1jLHMrPWUuRGksbis9ZS5zdWNjZXNzLG8rPWUuX2ksdCl7dmFyIGg9aS5BUi5Eby5fUihOdW1iZXIoYSkpO2kuRFIoaCxjLGUuc3VjY2VzcyxlLl9pLGUuRGkpfX0pO3ZhciBhPXRoaXMuQVIuRG8uSFIoKTt0aGlzLkRSKGEscixuLG8scyl9LHQucHJvdG90eXBlLkRSPWZ1bmN0aW9uKHQsZSxpLHIsbil7dC5zcmNSZXFOKz1lLHQuc3JjUmVzcE4rPWksdC5zcmNSZXNwRXJyTis9cix0LnNyY1Jlc3BRdCs9bix0LnJlc3BGYWxsYmFja04rPWksdC5yZXNwRmFsbGJhY2tFcnJOKz1yfSx0fSgpO3AuSmw9XCJTdGF0c0pTXCIsZS5TdGF0c0pTPXB9LGZ1bmN0aW9uKHQsZSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGk7IWZ1bmN0aW9uKHQpe3ZhciBlOyFmdW5jdGlvbih0KXt0W3QuSGl2ZUpTPTBdPVwiSGl2ZUpTXCIsdFt0LkhpdmVKYXZhPTFdPVwiSGl2ZUphdmFcIix0W3QuU3RhdHNKUz0yXT1cIlN0YXRzSlNcIix0W3QuSGl2ZUpzUHJveHk9M109XCJIaXZlSnNQcm94eVwifShlPXQuSWx8fCh0LklsPXt9KSl9KGk9ZS5wdHx8KGUucHQ9e30pKX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPWkoMTUpLG49aSgyKSxvPWkoMjQpLHM9aSgxNCksYT1pKDUpLGM9aSg5KSxoPWkoNTYpLHA9aSg1NSksdT1pKDYwKSxsPWkoNTIpLGQ9aSg1MSk7aWYoXCJ1bmRlZmluZWRcIj09dHlwZW9mIGYpdmFyIGY9ITE7aWYoZil2YXIgZz1pKDUzKS5MUjtlbHNlIHZhciB2PWkoNTcpLk1SO3ZhciB5PWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe31yZXR1cm4gdC5wcm90b3R5cGUuYXBwbHk9ZnVuY3Rpb24odCl7dC5iaW5kKG5ldyByLm5zKGEuZ2kudWkscy5ycyxyLnNzLmxzKSksdC5iaW5kKG5ldyByLm5zKGEuZ2kuQmUscC5qUixyLnNzLmxzKSksdC5iaW5kKG5ldyByLm5zKGEuZ2kuYWksdS5VUixyLnNzLmxzKSksdC5iaW5kKG5ldyByLm5zKGEuZ2kuQ2UsbC5WUixyLnNzLmxzKSksdC5iaW5kKG5ldyByLm5zKG4uRnJhbWV3b3JrLkZlLndlLG8uRWwuYmwsci5zcy5scykpLGY/dC5iaW5kKG5ldyByLm5zKGEuZ2kuY2ksZyxyLnNzLmxzKSk6dC5iaW5kKG5ldyByLm5zKGEuZ2kuY2ksdixyLnNzLmxzKSksdC5iaW5kKG5ldyByLm5zKGEuZ2kuaGksZC5RUixyLnNzLmxzKSksdC5iaW5kKG5ldyByLm5zKGEuZ2kubGksaC5TdGF0cy56ZixyLnNzLlRzKSksdC5iaW5kKG5ldyByLm5zKGEuZ2kuc2ksaC5TdGF0cy5lbyxyLnNzLlRzKSksdC5iaW5kKG5ldyByLm5zKGEuZ2kuZGksYy5GLlVuLHIuc3MuVHMpKSx0LmJpbmQobmV3IHIubnMoYS5naS5maSxjLkYuZW8sci5zcy5UcykpfSx0fSgpO2UuU2Q9eX0sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjt2YXIgaT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHQucHJvdG90eXBlLnFSPWZ1bmN0aW9uKHQpe3RoaXMuaG9zdG5hbWU9dH0sdC5wcm90b3R5cGUuRm49ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5ob3N0bmFtZX0sdC5wcm90b3R5cGUuSlI9ZnVuY3Rpb24odCl7dGhpcy5LUj10fSx0LnByb3RvdHlwZS5Obj1mdW5jdGlvbigpe3JldHVybiB0aGlzLktSfSx0fSgpO2UuUVI9aX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPXRoaXMmJnRoaXMuX19leHRlbmRzfHxmdW5jdGlvbih0LGUpe2Z1bmN0aW9uIGkoKXt0aGlzLmNvbnN0cnVjdG9yPXR9Zm9yKHZhciByIGluIGUpZS5oYXNPd25Qcm9wZXJ0eShyKSYmKHRbcl09ZVtyXSk7dC5wcm90b3R5cGU9bnVsbD09PWU/T2JqZWN0LmNyZWF0ZShlKTooaS5wcm90b3R5cGU9ZS5wcm90b3R5cGUsbmV3IGkpfSxuPWkoMSksbz1pKDIyKSxzPWkoMiksYT1pKDEzKSxjPWkoMzkpLGg9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KCl7dGhpcy5HUj1cIklkZW50aXR5U3RvcmVcIix0aGlzLnpSPVwiSWRlbnRpdHlEQlwiLHRoaXMuc249bnVsbCx0aGlzLmluZGV4ZWREQj13aW5kb3cuaW5kZXhlZERCfHx3aW5kb3cubW96SW5kZXhlZERCfHx3aW5kb3cud2Via2l0SW5kZXhlZERCfHx3aW5kb3cubXNJbmRleGVkREIscy5GcmFtZXdvcmsmJnMuRnJhbWV3b3JrLnJlc29sdmUocy5GcmFtZXdvcmsuRmUud2UpP3RoaXMubT1zLkZyYW1ld29yay5yZXNvbHZlKHMuRnJhbWV3b3JrLkZlLndlKS5sb2coKTp0aGlzLm09Y29uc29sZX1yZXR1cm4gdC5wcm90b3R5cGUuV1I9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLGU9bi5kZWZlcigpLGk9aW5kZXhlZERCLm9wZW4odGhpcy56Uik7cmV0dXJuIGkub251cGdyYWRlbmVlZGVkPWZ1bmN0aW9uKCl7dmFyIGU9aS5yZXN1bHQ7ZS5jcmVhdGVPYmplY3RTdG9yZSh0LkdSLHtrZXlQYXRoOlwiaWRcIn0pfSxpLm9uc3VjY2Vzcz1mdW5jdGlvbigpe3ZhciB0PWkucmVzdWx0O2UucmVzb2x2ZSh0KX0saS5vbmVycm9yPWZ1bmN0aW9uKHQpe2UucmVqZWN0KHQpfSxlLnZ0fSx0LnByb3RvdHlwZS5Lbz1mdW5jdGlvbigpe3ZhciB0PXRoaXM7aWYodGhpcy4kUilyZXR1cm4gdGhpcy4kUjt2YXIgZT1uLmRlZmVyKCk7aWYodGhpcy5zbillLnJlc29sdmUobmV3IGMuRkkodGhpcy5zbikpO2Vsc2UgaWYoYS5Lbi5SbyYmdGhpcy5pbmRleGVkREIpe3ZhciBpPXNldFRpbWVvdXQoZnVuY3Rpb24oKXt0Lm0ud2FybihcIltIaXZlQ29tbV0gdGltZW91dCByZXRyaWV2aW5nIHBlcnNpc3RlbnQgSUQgLSBnZW5lcmF0aW5nIHJhbmRvbSBvbmVcIiksXG4gIHQuc249dC5ZUigpLHQubS5kZWJ1ZyhcIltIaXZlQ29tbV0gR2VuZXJhdGVkIFVVSUQ6IFwiK3Quc24pLGUucmVzb2x2ZShuZXcgYy5GSSh0LnNuKSl9LDRlMyk7dHJ5e3ZhciByPXRoaXMuV1IoKTtyLnRoZW4oZnVuY3Rpb24ocil7dmFyIG49ci50cmFuc2FjdGlvbih0LkdSLFwicmVhZHdyaXRlXCIpLG89bi5vYmplY3RTdG9yZSh0LkdSKSxzPW8uZ2V0KFwiTVlJRFwiKTtzLm9uc3VjY2Vzcz1mdW5jdGlvbigpe2lmKGNsZWFyVGltZW91dChpKSx0LnNuKWUucmVzb2x2ZShuZXcgYy5GSSh0LnNuKSk7ZWxzZSBpZihudWxsIT1zLnJlc3VsdCYmYS5Lbi5Sbyl7dmFyIG49cy5yZXN1bHQudmFsdWU7dC5tLmRlYnVnKFwiW0hpdmVDb21tXSBSZXRyaWV2ZWQgcGVyc2lzdGVudCBVVUlEOiBcIituKSx0LnNuPW4sci5jbG9zZSgpLGUucmVzb2x2ZShuZXcgYy5GSSh0LnNuKSl9ZWxzZXt2YXIgbz10LllSKCk7dC5YUihyLG8pLGUucmVzb2x2ZShuZXcgYy5GSSh0LnNuKSl9fSxzLm9uZXJyb3I9ZnVuY3Rpb24ocil7Y2xlYXJUaW1lb3V0KGkpLHQuc258fCh0Lm0ud2FybihcIltIaXZlQ29tbV0gZXJyb3IgcmV0cmlldmluZyBwZXJzaXN0ZW50IFVVSUQ6IFwiK3IpLHQuc249dC5ZUigpLHQubS5kZWJ1ZyhcIltIaXZlQ29tbV0gR2VuZXJhdGVkIFVVSUQ6IFwiK3Quc24pKSxlLnJlc29sdmUobmV3IGMuRkkodC5zbikpfX0pLmZhaWwoZnVuY3Rpb24ocil7Y2xlYXJUaW1lb3V0KGkpLHQuc258fCh0Lm0ud2FybihcIltIaXZlQ29tbV0gZXJyb3Igb3BlbmluZyBpbmRleGVkREIgLSBnZW5lcmF0aW5nIHJhbmRvbSBpZC4gRXJyb3I6IFwiK3IpLHQuc249dC5ZUigpLHQubS5kZWJ1ZyhcIltIaXZlQ29tbV0gR2VuZXJhdGVkIFVVSUQ6IFwiK3Quc24pKSxlLnJlc29sdmUobmV3IGMuRkkodC5zbikpfSl9Y2F0Y2gobyl7dGhpcy5zbj10aGlzLllSKCksdGhpcy5tLmRlYnVnKFwiW0hpdmVDb21tXSBQZXJzaXN0ZW5jZSBlcnJvciAtIEdlbmVyYXRlIFVVSUQ6IFwiK3RoaXMuc24sbyksZS5yZXNvbHZlKG5ldyBjLkZJKHRoaXMuc24pKX19ZWxzZSB0aGlzLnNuPXRoaXMuWVIoKSx0aGlzLm0uZGVidWcoXCJbSGl2ZUNvbW1dIFBlcnNpc3RlbmNlIGRpc2FibGVkIC0gR2VuZXJhdGUgVVVJRDogXCIrdGhpcy5zbiksZS5yZXNvbHZlKG5ldyBjLkZJKHRoaXMuc24pKTtyZXR1cm4gdGhpcy4kUj1lLnZ0LHRoaXMuJFJ9LHQucHJvdG90eXBlLlhSPWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcyxyPXQudHJhbnNhY3Rpb24odGhpcy5HUixcInJlYWR3cml0ZVwiKSxuPXIub2JqZWN0U3RvcmUodGhpcy5HUik7bi5wdXQoe2lkOlwiTVlJRFwiLHZhbHVlOmV9KSxyLm9uY29tcGxldGU9ZnVuY3Rpb24oKXtpLm0uZGVidWcoXCJbSGl2ZUNvbW1dIGNvbXBsZXRlZCBVVUlEIHBlcnNpc3RlbmNlXCIpLHQuY2xvc2UoKX0sdGhpcy5tLmRlYnVnKFwiW0hpdmVDb21tXSBHZW5lcmF0ZWQgVVVJRDogXCIrZSksdGhpcy5zbj1lfSx0LnByb3RvdHlwZS5ZUj1mdW5jdGlvbigpe3JldHVybiBvLlpoKCl9LHR9KCk7ZS5aUj1oO3ZhciBwPWZ1bmN0aW9uKHQpe2Z1bmN0aW9uIGUoKXtyZXR1cm4gdC5jYWxsKHRoaXMpfHx0aGlzfXJldHVybiByKGUsdCksZS5wcm90b3R5cGUuS289ZnVuY3Rpb24oKXt2YXIgZT10aGlzO2lmKHRoaXMudGspcmV0dXJuIHRoaXMudGs7dmFyIGk9bi5kZWZlcigpO3JldHVybiB0LnByb3RvdHlwZS5Lby5jYWxsKHRoaXMpLnRoZW4oZnVuY3Rpb24odCl7dmFyIHI9ZS5ZUigpLG49dC4kbygpLG89bmV3IGMuRkkocixuKTtpLnJlc29sdmUobyl9KS5mYWlsKGZ1bmN0aW9uKHQpe3ZhciByPWUuWVIoKSxuPW5ldyBjLkZJKHIpO2kucmVzb2x2ZShuKX0pLHRoaXMudGs9aS52dCx0aGlzLnRrfSxlfShoKTtlLlZSPXB9LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcj1pKDEpLG49aSgyKSxvPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMudT1cIltQcmVsb2FkQ29ubmVjdGl2aXR5SW5mb1Byb3ZpZGVyXSBcIix0aGlzLmNvbm5JbmZvPXdpbmRvdy5layx0aGlzLm09bi5GcmFtZXdvcmsucmVzb2x2ZShuLkZyYW1ld29yay5GZS53ZSkubG9nKCksdGhpcy5jb25uSW5mb3x8dGhpcy5tLmVycm9yKHRoaXMudStcIiBoZWxwZXIgdW5kZWZpbmVkXCIpfXJldHVybiB0LnByb3RvdHlwZS5Qbj1mdW5jdGlvbigpe3ZhciB0PXRoaXM7aWYoIXRoaXMuY29ubkluZm8pcmV0dXJuIHIucmVqZWN0KFwiQ29ubkluZm8gaGVscGVyIHVuZGVmaW5lZFwiKTt2YXIgZT1zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7cmV0dXJuIHQubS53YXJuKHQudStcIkdldCBjb25uZWN0aXZpdHkgaW5mbyBleHBpcmVkXCIpLHQuaWs/ci5yZXNvbHZlKHQuaWspOnIucmVqZWN0KFwiZXhwaXJlZFwiKX0sMmUzKTt0cnl7cmV0dXJuIHRoaXMuY29ubkluZm8uUG4oKS50aGVuKGZ1bmN0aW9uKGkpe3JldHVybiBjbGVhclRpbWVvdXQoZSksdC5paz1pLGl9KS5mYWlsKGZ1bmN0aW9uKGUpe3JldHVybiB0Lm0uZGVidWcodC51K1wiIGdldCBjb25uZWN0aXZpdHkgaW5mbyBmYWlsZWQgd2l0aCBlcnJvciAxOiBcIixlKSx0LmlrP3QuaWs6ci5yZWplY3QoZSl9KX1jYXRjaChpKXtyZXR1cm4gdGhpcy5tLmRlYnVnKHRoaXMudStcIiBnZXQgY29ubmVjdGl2aXR5IGluZm8gZmFpbGVkIHdpdGggZXJyb3IgMjpcIixpKSxyLnJlamVjdChpKX19LHQucHJvdG90eXBlLnJrPWZ1bmN0aW9uKHQsZSxpKXt9LHR9KCk7ZS5MUj1vfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI9aSg2Myksbj1pKDEpLG89aSgyKSxzPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMuaW5kZXhlZERCPXdpbmRvdy5pbmRleGVkREJ8fHdpbmRvdy5tb3pJbmRleGVkREJ8fHdpbmRvdy53ZWJraXRJbmRleGVkREJ8fHdpbmRvdy5tc0luZGV4ZWREQix0aGlzLm09by5GcmFtZXdvcmsucmVzb2x2ZShvLkZyYW1ld29yay5GZS53ZSkubG9nKCl9cmV0dXJuIHQucHJvdG90eXBlLldSPWZ1bmN0aW9uKCl7dmFyIHQ9bi5kZWZlcigpLGU9dGhpcy5pbmRleGVkREIub3BlbihcIlByaXZhdGVJUERCXCIpO3JldHVybiBlLm9udXBncmFkZW5lZWRlZD1mdW5jdGlvbigpe3ZhciB0PWUucmVzdWx0O3QuY3JlYXRlT2JqZWN0U3RvcmUoXCJQcml2YXRlSVBTdG9yZVwiLHtrZXlQYXRoOlwiaWRcIn0pfSxlLm9uc3VjY2Vzcz1mdW5jdGlvbigpe3ZhciBpPWUucmVzdWx0O3QucmVzb2x2ZShpKX0sZS5vbmVycm9yPWZ1bmN0aW9uKGUpe3QucmVqZWN0KGUpfSx0LnZ0fSx0LnByb3RvdHlwZS5uaz1mdW5jdGlvbigpe3ZhciB0PXRoaXM7aWYodGhpcy5zaylyZXR1cm4gdGhpcy5zazt2YXIgZT1zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dC5tLndhcm4oXCJQcml2YXRlIGxpc3QgcmV0cmlldmFsIHRpbWVvdXRcIiksaS5yZWplY3QoXCJQcml2YXRlIGxpc3QgdGltZW91dFwiKX0sNGUzKSxpPW4uZGVmZXIoKSxvPXRoaXMuV1IoKTtyZXR1cm4gby50aGVuKGZ1bmN0aW9uKG4pe3ZhciBvPW4udHJhbnNhY3Rpb24oXCJQcml2YXRlSVBTdG9yZVwiLFwicmVhZHdyaXRlXCIpLHM9by5vYmplY3RTdG9yZShcIlByaXZhdGVJUFN0b3JlXCIpLGE9cy5nZXQoXCJpcGxpc3RcIik7YS5vbnN1Y2Nlc3M9ZnVuY3Rpb24oKXtjbGVhclRpbWVvdXQoZSk7dmFyIHQ9W107ci5hayhhLnJlc3VsdCl8fHIuYWsoYS5yZXN1bHQudmFsdWUpfHwodD1hLnJlc3VsdC52YWx1ZS5zcGxpdChcInxcIikpLGkucmVzb2x2ZSh0KSxuLmNsb3NlKCl9LGEub25lcnJvcj1mdW5jdGlvbihyKXtjbGVhclRpbWVvdXQoZSksdC5tLndhcm4oXCJJIGdvdCBhbiBlcnJvciBvbiBpbmRleGVkIGRiIFwiK3IubWVzc2FnZSksaS5yZWplY3QoXCJFcnJvciBvbiBpbmRleGVkREIgXCIrci5tZXNzYWdlKX19KS5mYWlsKGZ1bmN0aW9uKHIpe2NsZWFyVGltZW91dChlKSx0Lm0ud2FybihcIkRCIGlzIG5vdCBvcGVuIHdpdGggZXJyb3JcIityLm1lc3NhZ2UpLGkucmVqZWN0KFwiREIgaXMgbm90IG9wZW4gd2l0aCBlcnJvciBcIityLm1lc3NhZ2UpfSksdGhpcy5zaz1pLnZ0LHRoaXMuc2t9LHQucHJvdG90eXBlLmNrPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMsaT10LmpvaW4oXCJ8XCIpLHI9dGhpcy5XUigpO3IudGhlbihmdW5jdGlvbihyKXt2YXIgbj1yLnRyYW5zYWN0aW9uKFwiUHJpdmF0ZUlQU3RvcmVcIixcInJlYWR3cml0ZVwiKSxvPW4ub2JqZWN0U3RvcmUoXCJQcml2YXRlSVBTdG9yZVwiKTtvLnB1dCh7aWQ6XCJpcGxpc3RcIix2YWx1ZTppfSksbi5vbmNvbXBsZXRlPWZ1bmN0aW9uKCl7ZS5tLmRlYnVnKFwiU3RvcmluZyBzaXRlIG1hdGNoZWQgaXBzIFtcIit0LmpvaW4oXCIsXCIpK1wiXVwiKSxyLmNsb3NlKCl9fSkuZmFpbChmdW5jdGlvbih0KXtlLm0ud2FybihcIkRCIGlzIG5vdCBvcGVuIHdpdGggZXJyb3IgXCIrdC5tZXNzYWdlKX0pfSx0fSgpO2UuaGs9c30sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO3ZhciByPWkoMSksbj1pKDIxKSxvPWkoMzYpLHM9aSgyKSxhPWkoMTMpLGM9aSgxMCksaD1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt0aGlzLm09cy5GcmFtZXdvcmsucmVzb2x2ZShzLkZyYW1ld29yay5GZS53ZSkubG9nKCksdGhpcy5tLmRlYnVnKFwiSU5JVCBTRVJWSUNFIENMSUVOVFwiKX1yZXR1cm4gdC5wcm90b3R5cGUuaW5pdD1mdW5jdGlvbih0LGUpe3ZhciBpPXRoaXM7aWYodGhpcy5wayl0aGlzLnBrLnRoZW4oZnVuY3Rpb24oKXt2YXIgdD17cGFydG5lcklkOmUuYm4oKSxjdXN0b21lcklkOmUuRW4oKSxjb250ZW50SWQ6ZS5lcygpLHNlY3JldDplLldoKCl9LHI9bmV3IGMuWm4oU2VydmljZXMua2YsMSxKU09OLnN0cmluZ2lmeSh0KSk7aS5jb25uZWN0aW9uLnNlbmQocil9KTtlbHNle3ZhciBzPXIuZGVmZXIoKSxoPWEuS24uSm4ua287ZS56aCYmKHRoaXMubS53YXJuKFwiW0hpdmVDb21tXSBFcnJvciB0cnlpbmcgdG8gcmVzb2x2ZSB0ZXN0IHRpY2tldCBhZ2FpbnN0IHByb2R1Y3Rpb24gc2VydmljZXMgLSB1c2UgcHJvZHVjdGlvbiB0aWNrZXQgb3IgdGVzdCBwbHVnaW5cIikscy5yZWplY3QobmV3IEVycm9yKFwidGVzdCB0aWNrZXQgaW4gcHJvZHVjdGlvblwiKSkpO3ZhciBwPW5ldyBuKGgpLHU9cC5FdSh7XCJjb25uZWN0aW9uLWlkXCI6dCxwYXJ0bmVyX2lkOmUuYm4oKSxjdXN0b21lcl9pZDplLkVuKCksY29udGVudF9pZDplLmVzKCksdGlja2V0OmUuV2goKX0pLnRvU3RyaW5nKCk7dGhpcy5jb25uZWN0aW9uPW5ldyBvLkFJKHUsYS5Lbi5Kbi5BbyxhLktuLkpuLk5vLGEuS24uSm4ueG8pLHRoaXMuY29ubmVjdGlvbi5USShmdW5jdGlvbigpe2kubS5kZWJ1ZyhcIkhJVkUgU0VSVklDRVMgQ09OTkVDVEVEXCIpLHMucmVzb2x2ZShpLmNvbm5lY3Rpb24pfSksdGhpcy5jb25uZWN0aW9uLm9uZXJyb3IoZnVuY3Rpb24oKXtpLm0ud2FybihcIkhpdmUgU2VydmljZXMgQ29ubmVjdGlvbiBmYWlsZWRcIikscy5yZWplY3QoaS5jb25uZWN0aW9uKX0pLHRoaXMucGs9cy52dH1yZXR1cm57WW86dGhpcy5jb25uZWN0aW9uLHZ0OnRoaXMucGt9fSx0LnByb3RvdHlwZS5jb25uZWN0PWZ1bmN0aW9uKCl7dGhpcy5jb25uZWN0aW9uJiZ0aGlzLmNvbm5lY3Rpb24uY29ubmVjdCghMCl9LHQucHJvdG90eXBlLnNkPWZ1bmN0aW9uKHQpe30sdC5wcm90b3R5cGUuWG49ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jb25uZWN0aW9ufSx0LnByb3RvdHlwZS5jbG9zZT1mdW5jdGlvbigpe3RoaXMuY29ubmVjdGlvbiYmdGhpcy5jb25uZWN0aW9uLmNsb3NlKCl9LHR9KCk7ZS5qUj1ofSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI9aSg0KSxuPXIudmUsbz1pKDE2KTtpKDMxKSxpKDMwKTt2YXIgcyxhPWkoMiksYz1pKDUpLGg9aSgxMykscD1pKDEwKSx1PWkoMTQpLGw9aSgyMyk7IWZ1bmN0aW9uKHQpe3ZhciBlPVwiW1NOQVBdXCIsaT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt0aGlzLm1ldHJpY3M9bmV3IGhpdmUuc25hcHNob3RzLk1ldHJpY3MsdGhpcy51az1uZXcgaGl2ZS5zbmFwc2hvdHMuVHJhZmZpYyx0aGlzLmxrPW5ldyBuLHRoaXMuZGs9bmV3IG4sdGhpcy5maz1uZXcgbix0aGlzLnBsYXllcj1uZXcgaGl2ZS5zbmFwc2hvdHMuUGxheWVyfXJldHVybiB0fSgpO3QuZ2s9aTt2YXIgcj1mdW5jdGlvbigpe2Z1bmN0aW9uIGkoKXt0aGlzLnRpY2tldD1udWxsLHRoaXMudms9MCx0aGlzLnlrPTAsdGhpcy5taygpfXJldHVybiBpLnByb3RvdHlwZS5pbml0PWZ1bmN0aW9uKHQsaSxyLG4pe3RoaXMubT1hLkZyYW1ld29yay5yZXNvbHZlKGEuRnJhbWV3b3JrLkZlLndlKS5sb2cobiksdGhpcy50bj1hLkZyYW1ld29yay5yZXNvbHZlKGMuZ2kuY2kpLHRoaXMubS5kZWJ1ZyhlK1wiIElOSVQgU1RBVFMgU1RPUkUgLSBJRDogXCIrdCksdGhpcy5zbj10LHRoaXMudGlja2V0PWksdGhpcy5hbihyKX0saS5wcm90b3R5cGUud2s9ZnVuY3Rpb24odCl7dGhpcy5Uaz10fSxpLnByb3RvdHlwZS5hbj1mdW5jdGlvbih0KXt0aGlzLmFwcD10fSxpLnByb3RvdHlwZS5taz1mdW5jdGlvbigpe3RoaXMuU2s9bmV3IHQuZ2ssdGhpcy5zbj1udWxsLHRoaXMudGlja2V0PW51bGwsdGhpcy5yZXNldCgpfSxpLnByb3RvdHlwZS5yZXNldD1mdW5jdGlvbigpe3RoaXMuQlI9bmV3IHQuZ2ssdGhpcy5iayh0aGlzLkJSLnVrKSx0aGlzLkVrKHRoaXMuQlIpfSxpLnByb3RvdHlwZS5iaz1mdW5jdGlvbih0KXt0LnJlc3BGYWxsYmFja049MCx0LnJlc3BGYWxsYmFja0Vyck49MCx0LnNyY1JlcU49MCx0LnNyY1Jlc3BFcnJOPTAsdC5zcmNSZXNwUXQ9MCx0LnNyY090aGVyUmVzcE49MCx0LnNyY1Jlc3BOPTAsdC5zcmNPdmVyUXQ9MCx0LnAycERpcmVjdFF0PTAsdC5wMnBOYXRRdD0wLHQucDJwVWRwYlF0PTAsdC5wMnBSZWxheVF0PTAsdC5wMnBPdXRTaXRlTG93UHJpbz0wLHQucmVzcFAycE49MCx0LnAycFN1YlJlcU49MCx0LnAycFN1YlJlc3BFcnJOPTAsdC5wMnBTdWJSZXNwUXQ9MCx0LnAycFN1YlJlc3BQYXJ0Tj0wfSxpLnByb3RvdHlwZS5Faz1mdW5jdGlvbih0KXt0Lm1ldHJpY3MudmlkZW9CdWZOPTAsdC5tZXRyaWNzLnZpZGVvQnVmUXQ9MCx0Lm1ldHJpY3MuY2xpZW50QnVmZmVyTXM9MCx0LnBsYXllci5idWZmZXJpbmdOPTAsdC5wbGF5ZXIuYnVmZmVyaW5nTXM9MH0saS5wcm90b3R5cGUuSWs9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLGk9bmV3IGhpdmUuc25hcHNob3RzLk1ldHJpY1NuYXBzaG90O2kudGltZXN0YW1wPWEuRnJhbWV3b3JrLnRpbWUoKSxpLmd1aWQ9dGhpcy5zbixpLnNlc3Npb25JZD10aGlzLnRpY2tldC5zZXNzaW9uSWQsaS5ldmVudElkPW5ldyBFdmVudElkLGkuZXZlbnRJZC5wYXJ0bmVySWQ9dGhpcy50aWNrZXQuYm4oKSxpLmV2ZW50SWQuY3VzdG9tZXJJZD10aGlzLnRpY2tldC5FbigpLGkuZXZlbnRJZC5jb250ZW50SWQ9dGhpcy50aWNrZXQuZXMoKTt0cnl7dmFyIHI9bmV3IGhpdmUuc25hcHNob3RzLkNsaWVudEluZm87ci5jbGllbnRUeXBlPXRoaXMuUmsoKTt2YXIgbj10aGlzLmFwcC52ZXJzaW9uLnNwbGl0KFwiLlwiKTtyLm1ham9yVmVyc2lvbj1wYXJzZUludChuWzBdKSxyLm1pbm9yVmVyc2lvbj1wYXJzZUludChuWzFdKSxyLnBhdGNoVmVyc2lvbj1wYXJzZUludChuWzJdKSxpLmNsaWVudD1yfWNhdGNoKG8pe3RoaXMubS53YXJuKGUrXCIgZXJyb3Igc2V0dGluZyBTbmFwc2hvdCBDbGllbnRJbmZvXCIsbyl9aS5zdHJlYW1JbmZvPXRoaXMueFIua2soKSxpLnRyYWZmaWM9W107dmFyIHM9bmV3IGhpdmUuc25hcHNob3RzLlRyYWZmaWNLZXk7aWYoaS50cmFmZmljLnB1c2goe2tleTpzLHZhbHVlOnRoaXMuQlIudWt9KSx0aGlzLkJSLmxrLmZvckVhY2goZnVuY3Rpb24odCxlKXt2YXIgcj1uZXcgaGl2ZS5zbmFwc2hvdHMuVHJhZmZpY0tleTtyLmJpdHJhdGU9ZSxpLnRyYWZmaWMucHVzaCh7a2V5OnIsdmFsdWU6dH0pfSksaS5tZXRyaWNzPXRoaXMuQlIubWV0cmljcyx0aGlzLlRrJiYoaS5tZXRyaWNzLmNsaWVudEJ1ZmZlck1zPXRoaXMuVGsubWluKCkpLGkucGxheWVyPXRoaXMuQlIucGxheWVyLHRoaXMuQ2spe3ZhciBjPXRoaXMuQ2suZ2V0UGFydG5lclNuYXBzaG90cygpO2MuZm9yRWFjaChmdW5jdGlvbihlLHIpe3QuT2socixlLGkpfSksdGhpcy5CUi5may5maWx0ZXIoZnVuY3Rpb24odCxlKXtyZXR1cm4hYy5oYXMoZSl9KS5mb3JFYWNoKGZ1bmN0aW9uKGUscil7dC5PayhyLGUsaSl9KX1yZXR1cm4gaS5jb25uSW5mbz1uZXcgaGl2ZS5zbmFwc2hvdHMuQ29ubmVjdGl2aXR5SW5mbyx0aGlzLnRuLlBuKCkudGhlbihmdW5jdGlvbihlKXtyZXR1cm4gaS5jb25uSW5mby5wcml2YXRlSXA9ZS5ObigpLkJuKCksdC5QayhpKX0pLmZhaWwoZnVuY3Rpb24oZSl7cmV0dXJuIHQuUGsoaSl9KX0saS5wcm90b3R5cGUuUGs9ZnVuY3Rpb24odCl7cmV0dXJuIHQuY29ubkluZm8uaW50ZXJuYWxBcz10aGlzLnZrLHQuY29ubkluZm8uZXh0ZXJuYWxBcz10aGlzLnlrLHQuY29ubkluZm8ucHVibGljSXA9dGhpcy5Bayx0fSxpLnByb3RvdHlwZS5Saz1mdW5jdGlvbigpe3ZhciB0O3N3aXRjaCh0aGlzLmFwcC5hcHApe2Nhc2VcIkpTXCI6dD1DbGllbnRUeXBlLkZmO2JyZWFrO2Nhc2VcIlBST1hZXCI6dD1DbGllbnRUeXBlLl9mO2JyZWFrO2RlZmF1bHQ6dD1DbGllbnRUeXBlLkJmfXJldHVybiB0fSxpLnByb3RvdHlwZS5Paz1mdW5jdGlvbih0LGUsaSl7dmFyIHI9dGhpcy5CUi5kay5nZXQodCk7ZS50cmFmZmljPXIsaS5wYXJ0bmVyc3x8KGkucGFydG5lcnM9W10pO3ZhciBuPW5ldyBoaXZlLnNuYXBzaG90cy5QYXJ0bmVyS2V5O24ucGFydG5lckd1aWQ9dCxpLnBhcnRuZXJzLnB1c2goe2tleTpuLHZhbHVlOmV9KX0saS5wcm90b3R5cGUuQ1I9ZnVuY3Rpb24odCxlKXt0PjAmJih0aGlzLkJSLm1ldHJpY3MudmlkZW9CdWZOKyssdGhpcy5CUi5tZXRyaWNzLnZpZGVvQnVmUXQrPXQsdGhpcy5CUi5wbGF5ZXIuYnVmZmVyaW5nTisrLHRoaXMuQlIucGxheWVyLmJ1ZmZlcmluZ01zKz10KSx0aGlzLkJSLnBsYXllci5wbGF5ZXJCdWZmZXJNcz1lfSxpLnByb3RvdHlwZS5IUj1mdW5jdGlvbigpe3JldHVybiB0aGlzLkJSLnVrfSxpLnByb3RvdHlwZS5Oaz1mdW5jdGlvbigpe3JldHVybiB0aGlzLlNrLnVrfSxpLnByb3RvdHlwZS54az1mdW5jdGlvbih0KXtyZXR1cm4gdGhpcy5Tay5say5oYXModCl8fHRoaXMuU2subGsuc2V0KHQsbmV3IGhpdmUuc25hcHNob3RzLlRyYWZmaWMpLHRoaXMuU2subGsuZ2V0KHQpfSxpLnByb3RvdHlwZS5fUj1mdW5jdGlvbih0KXtpZighdGhpcy5CUi5say5oYXModCkpe3ZhciBlPW5ldyBoaXZlLnNuYXBzaG90cy5UcmFmZmljO3RoaXMuYmsoZSksdGhpcy5CUi5say5zZXQodCxlKX1yZXR1cm4gdGhpcy5CUi5say5nZXQodCl9LGkucHJvdG90eXBlLkJrPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIGUuZGsuaGFzKHQpfHxlLmRrLnNldCh0LG5ldyBoaXZlLnNuYXBzaG90cy5QYXJ0bmVyVHJhZmZpYyksZS5kay5nZXQodCl9LGkucHJvdG90eXBlLkZrPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLkJrKHQsdGhpcy5CUil9LGkucHJvdG90eXBlLl9rPWZ1bmN0aW9uKHQpe3JldHVybiB0aGlzLkJrKHQsdGhpcy5Tayl9LGkucHJvdG90eXBlLkRrPWZ1bmN0aW9uKHQpe3RoaXMudG49dH0saS5wcm90b3R5cGUuSGs9ZnVuY3Rpb24odCl7dGhpcy5Daz10fSxpLnByb3RvdHlwZS5qbj1mdW5jdGlvbih0KXt9LGl9KCk7dC56Zj1yO3ZhciBzPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMuTGs9aXNOYU4obC5IaXZlQ29uZmlnLkRlYnVnTG9ncy5NZXRyaWNTbmFwc2hvdExvZ3MpPzA6bC5IaXZlQ29uZmlnLkRlYnVnTG9ncy5NZXRyaWNTbmFwc2hvdExvZ3MsdGhpcy5zdGF0ZT11LkZvLkJvLHRoaXMuY2xpZW50PWEuRnJhbWV3b3JrLnJlc29sdmUoYy5naS5CZSksdGhpcy5YYT1uZXcgby5FYSx0aGlzLnByb3RvY29sPW5ldyBvLiRhKHRoaXMuWGEpfXJldHVybiB0LnByb3RvdHlwZS5pbml0PWZ1bmN0aW9uKHQsaSl7dGhpcy5tPWEuRnJhbWV3b3JrLnJlc29sdmUoYS5GcmFtZXdvcmsuRmUud2UpLmxvZyhpKSx0aGlzLm0uZGVidWcoZStcIiBJTklUIENMSUVOVCBTVEFUU1wiKSx0aGlzLlZmPXQsdGhpcy5NaygpfSx0LnByb3RvdHlwZS5Naz1mdW5jdGlvbigpe3ZhciB0PXRoaXM7dGhpcy5qaz4tMSYmYS5GcmFtZXdvcmsuY2xlYXJJbnRlcnZhbCh0aGlzLmprKSx0aGlzLmprPWEuRnJhbWV3b3JrLnNldEludGVydmFsKGZ1bmN0aW9uKCl7dC5VaygpfSxoLktuLkpuLlBvKX0sdC5wcm90b3R5cGUuQ2k9ZnVuY3Rpb24odCl7dGhpcy5zdGF0ZT10fSx0LnByb3RvdHlwZS5yZXNldD1mdW5jdGlvbigpe2EuRnJhbWV3b3JrLmNsZWFySW50ZXJ2YWwodGhpcy5qayksdGhpcy5WZiYmdGhpcy5WZi5taygpfSx0LnByb3RvdHlwZS5Vaz1mdW5jdGlvbigpe3ZhciB0PXRoaXM7dGhpcy5tLmRlYnVnKFwiW1NOQVBdIFRBS0lORyBTTkFQU0hPVFwiKTt2YXIgZT10aGlzLlZmLklrKCk7ZS50aGVuKGZ1bmN0aW9uKGUpe3JldHVybiB0LmZvcndhcmQoZSl9KS5mYWlsKGZ1bmN0aW9uKGUpe3QubS53YXJuKFwiW1NOQVBdIEVSUk9SIEZPUldBUkRJTkcgU05BUFNIT1RcIixlKX0pW1wiZmluYWxseVwiXShmdW5jdGlvbigpe3QuVmYucmVzZXQoKX0pfSx0LnByb3RvdHlwZS5mb3J3YXJkPWZ1bmN0aW9uKHQpe3ZhciBpPXRoaXM7aWYodGhpcy5zdGF0ZT09PXUuRm8uSURMRSlyZXR1cm4gdm9pZCB0aGlzLm0uZGVidWcoZStcIiBub3Qgc2VuZCAtIHN0YXRlIGlkbGVcIik7aWYodGhpcy5jbGllbnQmJnRoaXMuY2xpZW50LlhuKCkpe3N3aXRjaCh0aGlzLkxrKXtjYXNlIDA6ZGVmYXVsdDp0aGlzLm0uZGVidWcoZStcIiBTRU5ESU5HIFNOQVBTSE9UXCIpO2JyZWFrO2Nhc2UgMTp0aGlzLm0uZGVidWcoZStcIiBTRU5ESU5HIFNOQVBTSE9UIFwiK0pTT04uc3RyaW5naWZ5KHQpKTticmVhaztjYXNlIDI6dGhpcy5tLmRlYnVnKGUrXCIgU0VORElORyBTTkFQU0hPVFwiLHQpO2JyZWFrO2Nhc2UgMzp0aGlzLm0uZGVidWcoZStcIiBTRU5ESU5HIFNOQVBTSE9UIFwiK0pTT04uc3RyaW5naWZ5KHQpLHQpfXRoaXMucHJvdG9jb2wucGMoXCJTTkFQU0hPVFwiLG8uTHMuVnMsMCksdC53cml0ZSh0aGlzLnByb3RvY29sKSx0aGlzLnByb3RvY29sLmRjKCk7dmFyIHI9dGhpcy5YYS5IYSgpLG49dGhpcy5WayhyLFwiLFwiLDQpLHM9ci5zbGljZShuKzEsci5sZW5ndGgtMSksYT1uZXcgcC5abihTZXJ2aWNlcy50bywxLHMpO3RoaXMuY2xpZW50LlhuKCkuc2VuZChhKS5mYWlsKGZ1bmN0aW9uKHQpe2kubS53YXJuKGUrXCIgUFJPQkxFTTogXCIsdCl9KX19LHQucHJvdG90eXBlLlZrPWZ1bmN0aW9uKHQsZSxpKXtyZXR1cm4gdC5zcGxpdChlLGkpLmpvaW4oZSkubGVuZ3RofSx0fSgpO3QuZW89c30ocz1lLlN0YXRzfHwoZS5TdGF0cz17fSkpfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI9aSgxKSxuPWkoNCksbz1pKDIpLHM9aSg1KSxhPWkoNTgpLGM9aSg1NCksaD1pKDY1KSxwPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMuUWs9bnVsbCx0aGlzLnFrPW51bGwsdGhpcy5Kaz1udWxsLHRoaXMuS2s9bnVsbCx0aGlzLkdrPW5ldyBuLnZlLHRoaXMucHVibGljSXA9bnVsbCx0aGlzLnprPVtdLHRoaXMuX2k9ITEsdGhpcy5Xaz1udWxsLHRoaXMubT1vLkZyYW1ld29yay5yZXNvbHZlKG8uRnJhbWV3b3JrLkZlLndlKS5sb2coKSx0aGlzLmlrPW8uRnJhbWV3b3JrLnJlc29sdmUocy5naS5oaSksdGhpcy4kaz1uZXcgYy5oayx0aGlzLllrPVtdLHRoaXMuWGsoKX1yZXR1cm4gdC5wcm90b3R5cGUuWGs9ZnVuY3Rpb24oKXt2YXIgdD10aGlzO28uRnJhbWV3b3JrLnNldEludGVydmFsKGZ1bmN0aW9uKCl7dC56az1bXSx0LllrPVtdLHQuR2s9bmV3IG4udmUsdC5wdWJsaWNJcD1udWxsLHQuWms9bnVsbH0sMTJlNCl9LHQucHJvdG90eXBlLlBuPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuWmt8fCh0aGlzLlprPXRoaXMudEMoKSksdGhpcy5aa30sdC5wcm90b3R5cGUudEM9ZnVuY3Rpb24oKXt2YXIgdD10aGlzLGU9ci5kZWZlcigpO2lmKHRoaXMuV2s9by5GcmFtZXdvcmsuc2V0VGltZW91dChmdW5jdGlvbigpe2UucmVqZWN0KHtlQzohMCxtZXNzYWdlOlwiZXhwaXJlZFwifSl9LDRlMyksdGhpcy5pQygpKXRyeXt0aGlzLlFrPW5ldyBSVENQZWVyQ29ubmVjdGlvbihudWxsKSx0aGlzLkprPXRoaXMuUWsuY3JlYXRlRGF0YUNoYW5uZWwoXCJzZW5kQ2hhbm5lbFwiLHtyZWxpYWJsZTohMX0pLHRoaXMucWs9bmV3IFJUQ1BlZXJDb25uZWN0aW9uKG51bGwpLHRoaXMucWsub25kYXRhY2hhbm5lbD1mdW5jdGlvbihpKXt0LktrPWkuY2hhbm5lbCx0LktrLm9ub3Blbj1mdW5jdGlvbihpKXtcIm9wZW5cIj09PXQuS2sucmVhZHlTdGF0ZSYmKHQubS5kZWJ1ZyhcIkNvbGxlY3RlZCBpcHMgW1wiK3QuR2sua2V5cygpLmpvaW4oXCIsIFwiKStcIl1cIiksdC5xay5jbG9zZSgpLHQuJGsubmsoKS50aGVuKGZ1bmN0aW9uKGUpe3QuWWs9ZSx0Lm0uZGVidWcoXCJBbHJlYWR5IGtub3duIG1hdGNoaW5nIGlwcyBbXCIrdC5Zay5qb2luKFwiLFwiKStcIl1cIik7dmFyIGk9dC5Hay5rZXlzKCk7dC5Zay5mb3JFYWNoKGZ1bmN0aW9uKGUpe2kuaW5kZXhPZihlKT4wJiYodC56ay5wdXNoKGUpLHQuR2tbXCJkZWxldGVcIl0oZSkpfSksdC5Hay5rZXlzKCkuZm9yRWFjaChmdW5jdGlvbihlKXt0LnprLnB1c2goZSl9KX0pLmZhaWwoZnVuY3Rpb24oZSl7dC5tLndhcm4oXCJHZXQgUHJldmlvdXMgd29ya2luZyBpcHMgZmFpbGVkIHdpdGggZXJyb3IgXCIrZS5tZXNzYWdlKSx0LkdrLmtleXMoKS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3QuemsucHVzaChlKX0pfSlbXCJmaW5hbGx5XCJdKGZ1bmN0aW9uKCl7dC5tLmRlYnVnKFwiRmluYWwgcHJpdmF0ZSBpcCBsaXN0IFtcIit0LnprLmpvaW4oXCIsXCIpK1wiXVwiKSxlLnJlc29sdmUodC5yQygpKX0pKX19LHRoaXMuUWsub25pY2VjYW5kaWRhdGU9ZnVuY3Rpb24oaSl7aS5jYW5kaWRhdGUmJnQuemIoaS5jYW5kaWRhdGUuY2FuZGlkYXRlKSwhaS5jYW5kaWRhdGV8fHQucWsuYWRkSWNlQ2FuZGlkYXRlKGkuY2FuZGlkYXRlKVtcImNhdGNoXCJdKGZ1bmN0aW9uKGkpe2UucmVqZWN0KHtlQzohMCxtZXNzYWdlOmkubWVzc2FnZX0pLG8uRnJhbWV3b3JrLmNsZWFyVGltZW91dCh0LldrKSxjb25zb2xlLmxvZyhcIkVycm9yOiBGYWlsdXJlIGR1cmluZyBhZGRJY2VDYW5kaWRhdGUoKVwiKX0pfSx0aGlzLnFrLm9uaWNlY2FuZGlkYXRlPWZ1bmN0aW9uKGkpe2kuY2FuZGlkYXRlJiZ0LnpiKGkuY2FuZGlkYXRlLmNhbmRpZGF0ZSksIWkuY2FuZGlkYXRlfHx0LlFrLmFkZEljZUNhbmRpZGF0ZShpLmNhbmRpZGF0ZSlbXCJjYXRjaFwiXShmdW5jdGlvbihpKXtlLnJlamVjdCh7ZUM6ITAsbWVzc2FnZTppLm1lc3NhZ2V9KSxvLkZyYW1ld29yay5jbGVhclRpbWVvdXQodC5XayksY29uc29sZS5sb2coXCJFcnJvcjogRmFpbHVyZSBkdXJpbmcgYWRkSWNlQ2FuZGlkYXRlKClcIil9KX0sdGhpcy5Ray5jcmVhdGVPZmZlcigpLnRoZW4oZnVuY3Rpb24oZSl7cmV0dXJuIHQuUWsuc2V0TG9jYWxEZXNjcmlwdGlvbihlKX0pLnRoZW4oZnVuY3Rpb24oKXtyZXR1cm4gdC5xay5zZXRSZW1vdGVEZXNjcmlwdGlvbih0LlFrLmxvY2FsRGVzY3JpcHRpb24pfSkudGhlbihmdW5jdGlvbigpe3JldHVybiB0LnFrLmNyZWF0ZUFuc3dlcigpfSkudGhlbihmdW5jdGlvbihlKXtyZXR1cm4gdC5xay5zZXRMb2NhbERlc2NyaXB0aW9uKGUpfSkudGhlbihmdW5jdGlvbigpe3JldHVybiB0LlFrLnNldFJlbW90ZURlc2NyaXB0aW9uKHQucWsubG9jYWxEZXNjcmlwdGlvbil9KVtcImNhdGNoXCJdKGZ1bmN0aW9uKGkpe2UucmVqZWN0KHtlQzohMCxtZXNzYWdlOmkubWVzc2FnZX0pLG8uRnJhbWV3b3JrLmNsZWFyVGltZW91dCh0LldrKSxjb25zb2xlLmxvZyhcIkVycm9yOiBGYWlsdXJlIGNyZWF0aW5nIG9mZmVyXCIpfSl9Y2F0Y2goaSl7ZS5yZWplY3Qoe2VDOiEwLG1lc3NhZ2U6aS5tZXNzYWdlfSl9ZWxzZSBvLkZyYW1ld29yay5jbGVhclRpbWVvdXQodGhpcy5XayksZS5yZWplY3Qoe2VDOiExLG1lc3NhZ2U6XCJ3ZWJydGMgZGF0YWNoYW5uZWwgbm90IHN1cHBvcnRlZFwifSk7cmV0dXJuIGUudnR9LHQucHJvdG90eXBlLmlDPWZ1bmN0aW9uKCl7dHJ5e3JldHVybiBudWxsIT1oLlhlJiZudWxsIT1oLm5DJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBuZXcgUlRDUGVlckNvbm5lY3Rpb24obnVsbCxudWxsKS5jcmVhdGVEYXRhQ2hhbm5lbH1jYXRjaCh0KXtyZXR1cm4hMX19LHQucHJvdG90eXBlLnpiPWZ1bmN0aW9uKHQpe3ZhciBlPS8oWzAtOV17MSwzfShcXC5bMC05XXsxLDN9KXszfSkvLGk9ZS5leGVjKHQpO2lmKGkpe3ZhciByPWlbMF07dGhpcy5Hay5zZXQociwhMCl9fSx0LnByb3RvdHlwZS5yQz1mdW5jdGlvbigpe3ZhciB0PW5ldyBhLm9DO3JldHVybiB0aGlzLnprLmxlbmd0aD4wJiZ0LnNDKHRoaXMuemtbMF0pLHRoaXMucHVibGljSXAmJnQuYUModGhpcy5wdWJsaWNJcCksdGhpcy5pay5KUih0KSx0aGlzLmlrfSx0LnByb3RvdHlwZS5yaz1mdW5jdGlvbih0LGUsaSl7aWYodGhpcy5wdWJsaWNJcD10LHRoaXMuY0MoKSwwPT09aSYmdGhpcy56ay5sZW5ndGg+MSl0aGlzLnprLnNoaWZ0KCk7ZWxzZSBpZigwIT09aSYmdGhpcy5Zay5pbmRleE9mKHRoaXMuemtbMF0pPT0tMSl0aGlzLllrLnVuc2hpZnQodGhpcy56a1swXSksdGhpcy4kay5jayh0aGlzLllrLnNsaWNlKDAsMikpO2Vsc2UgaWYoMCE9PWkmJnRoaXMuWWsuaW5kZXhPZih0aGlzLnprWzBdKT4wKXt2YXIgcj10aGlzLllrLmluZGV4T2YodGhpcy56a1swXSk7dGhpcy5Zaz10aGlzLllrLnNwbGljZShyLDEpLHRoaXMuWWsudW5zaGlmdCh0aGlzLnprWzBdKSx0aGlzLiRrLmNrKHRoaXMuWWsuc2xpY2UoMCwyKSl9dGhpcy5yQygpfSx0LnByb3RvdHlwZS5jQz1mdW5jdGlvbigpe3ZhciB0PXRoaXMuemsuaW5kZXhPZih0aGlzLnB1YmxpY0lwKTt0Pi0xJiZ0aGlzLnprLnNwbGljZSh0LDEpfSx0fSgpO2UuTVI9cH0sZnVuY3Rpb24odCxlKXtcInVzZSBzdHJpY3RcIjt2YXIgaT1mdW5jdGlvbigpe2Z1bmN0aW9uIHQoKXt9cmV0dXJuIHQucHJvdG90eXBlLmFDPWZ1bmN0aW9uKHQpe3RoaXMucHVibGljSXA9dH0sdC5wcm90b3R5cGUueG49ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5wdWJsaWNJcH0sdC5wcm90b3R5cGUuaEM9ZnVuY3Rpb24odCl7dGhpcy5wQz10fSx0LnByb3RvdHlwZS5Mbj1mdW5jdGlvbigpe3JldHVybiB0aGlzLnBDfSx0LnByb3RvdHlwZS51Qz1mdW5jdGlvbih0KXt0aGlzLm5pYz10fSx0LnByb3RvdHlwZS5Ebj1mdW5jdGlvbigpe3JldHVybiB0aGlzLm5pY30sdC5wcm90b3R5cGUubEM9ZnVuY3Rpb24odCl7dGhpcy5uaWNOYW1lPXR9LHQucHJvdG90eXBlLkhuPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubmljTmFtZX0sdC5wcm90b3R5cGUuc0M9ZnVuY3Rpb24odCl7dGhpcy5wcml2YXRlSXA9dH0sdC5wcm90b3R5cGUuQm49ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5wcml2YXRlSXB9LHQucHJvdG90eXBlLmRDPWZ1bmN0aW9uKHQpe3RoaXMubmV0bWFzaz10fSx0LnByb3RvdHlwZS5mQz1mdW5jdGlvbigpe3JldHVybiB0aGlzLm5ldG1hc2t9LHQucHJvdG90eXBlLmdDPWZ1bmN0aW9uKHQpe3RoaXMudkM9dH0sdC5wcm90b3R5cGUuX249ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH0sdH0oKTtlLm9DPWl9LGZ1bmN0aW9uKHQsZSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIGk9ZnVuY3Rpb24oKXtmdW5jdGlvbiB0KHQsZSxpKXt0aGlzLmlzTGl2ZT10LHRoaXMucHJvdG9jb2w9ZSx0aGlzLnlDPWl9cmV0dXJuIHQucHJvdG90eXBlLmtrPWZ1bmN0aW9uKCl7dmFyIHQ9bmV3IGhpdmUuc25hcHNob3RzLlN0cmVhbUluZm87cmV0dXJuIHQuc3RyZWFtVHlwZT10aGlzLmlzTGl2ZT9TdHJlYW1UeXBlLkxJVkU6U3RyZWFtVHlwZS5QZix0LnN0cmVhbVByb3RvY29sPXRoaXMucHJvdG9jb2wsdC51cmw9dGhpcy55Qyx0fSx0fSgpO2UuTlI9aX0sZnVuY3Rpb24odCxlLGkpe1widXNlIHN0cmljdFwiO2koMjkpO3ZhciByPWkoMSksbj1pKDQpLG89bi52ZSxzPWkoMiksYT1pKDIwKSxjPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCh0KXt0aGlzLmlvPShuZXcgRGF0ZSkuZ2V0VGltZSgpLHRoaXMubUM9dH1yZXR1cm4gdH0oKSxoPWZ1bmN0aW9uKCl7ZnVuY3Rpb24gdCgpe3RoaXMud0M9bmV3IG8sdGhpcy5tPShzLkZyYW1ld29yay5yZXNvbHZlKHMuRnJhbWV3b3JrLkZlLndlKXx8Y29uc29sZSkubG9nKCksdGhpcy5tLmRlYnVnKFwiSU5JVCBUSUNLRVQgUkVTT0xWRVJcIil9cmV0dXJuIHQucHJvdG90eXBlLnJlc29sdmU9ZnVuY3Rpb24odCxlLGkpe3ZhciBuPXRoaXMsbz1yLmRlZmVyKCk7cmV0dXJuIHQmJih0Lm9uKFNlcnZpY2VzLmtmLDAsZnVuY3Rpb24odCl7bi5UQyh0KX0pLHQub24oU2VydmljZXMua2YsMixmdW5jdGlvbih0KXtuLlRDKHQpfSksdGhpcy53Qy5zZXQoZSxuZXcgYyhvKSkpLG8udnR9LHQucHJvdG90eXBlLlRDPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMsaT0obmV3IERhdGUpLmdldFRpbWUoKSxyPUpTT04ucGFyc2UodC5tc2cpLG49ITE7dGhpcy53Qy5mb3JFYWNoKGZ1bmN0aW9uKHQsbyl7aWYoZS5TQyhvLHIpKXtuPSEwO3ZhciBzPWUuJGwobyxyKTtzPyhzLmlvPXQuaW8scy5ybz1pLHQubUMucmVzb2x2ZShzKSk6dC5tQy5yZWplY3QoXCJUaWNrZXQgdmVyaWZpY2F0aW9uIGZhaWxlZFwiKSxlLndDW1wiZGVsZXRlXCJdKHMpfX0pLG58fHRoaXMubS53YXJuKFwibm8gcGVuZGluZyB0aWNrZXQgbWF0Y2hpbmc6IFwiK3QubXNnKX0sdC5wcm90b3R5cGUuR289ZnVuY3Rpb24odCl7dmFyIGU9bmV3IFJlZ0V4cChcIl5odHRwcz86Ly9hcGkoPzotdGVzdCk/LmhpdmVzdHJlYW1pbmcuY29tL3YxL2V2ZW50cy8oPzp3aWxkY2FyZC8pP1wiKTtpZihlLnRlc3QodCkpe3ZhciBpPXRoaXMuYkMoKTtyZXR1cm4gaS5LaCh0KSxpfXJldHVybiBudWxsfSx0LnByb3RvdHlwZS5iQz1mdW5jdGlvbigpe3JldHVybiBuZXcgYS5hcH0sdC5wcm90b3R5cGUuU0M9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdC5ibigpPT09ZVthLmFwLm9wXSYmdC5FbigpPT09ZVthLmFwLm5wXSYmdC5lcygpPT09ZVthLmFwLnNwXX0sdC5wcm90b3R5cGUuJGw9ZnVuY3Rpb24odCxlKXtyZXR1cm4gdC5VaChlKSx0LlFoKCk/dDpudWxsfSx0fSgpO2UuVVI9aH0sZnVuY3Rpb24odCxlKXtcImZ1bmN0aW9uXCI9PXR5cGVvZiBPYmplY3QuY3JlYXRlP3QudD1mdW5jdGlvbih0LGUpe3QuRUM9ZSx0LnByb3RvdHlwZT1PYmplY3QuY3JlYXRlKGUucHJvdG90eXBlLHtjb25zdHJ1Y3Rvcjp7dmFsdWU6dCxBZzohMSxQZzohMCxOZzohMH19KX06dC50PWZ1bmN0aW9uKHQsZSl7dC5FQz1lO3ZhciBpPWZ1bmN0aW9uKCl7fTtpLnByb3RvdHlwZT1lLnByb3RvdHlwZSx0LnByb3RvdHlwZT1uZXcgaSx0LnByb3RvdHlwZS5jb25zdHJ1Y3Rvcj10fX0sZnVuY3Rpb24odCxlKXt0LnQ9ZnVuY3Rpb24odCl7cmV0dXJuIHQmJlwib2JqZWN0XCI9PXR5cGVvZiB0JiZcImZ1bmN0aW9uXCI9PXR5cGVvZiB0LmNvcHkmJlwiZnVuY3Rpb25cIj09dHlwZW9mIHQuZmlsbCYmXCJmdW5jdGlvblwiPT10eXBlb2YgdC5yZWFkVUludDh9fSxmdW5jdGlvbih0LGUsaSl7ZnVuY3Rpb24gcih0LGkpe3ZhciByPXtJQzpbXSxSQzpvfTtyZXR1cm4gYXJndW1lbnRzLmxlbmd0aD49MyYmKHIua0M9YXJndW1lbnRzWzJdKSxhcmd1bWVudHMubGVuZ3RoPj00JiYoci5DQz1hcmd1bWVudHNbM10pLGYoaSk/ci5PQz1pOmkmJmUuUEMocixpKSxUKHIuT0MpJiYoci5PQz0hMSksVChyLmtDKSYmKHIua0M9MiksVChyLkNDKSYmKHIuQ0M9ITEpLFQoci5BQykmJihyLkFDPSEwKSxyLkNDJiYoci5SQz1uKSxhKHIsdCxyLmtDKX1mdW5jdGlvbiBuKHQsZSl7dmFyIGk9ci5OQ1tlXTtyZXR1cm4gaT9cIlx1MDAxYltcIityLkNDW2ldWzBdK1wibVwiK3QrXCJcdTAwMWJbXCIrci5DQ1tpXVsxXStcIm1cIjp0fWZ1bmN0aW9uIG8odCxlKXtyZXR1cm4gdH1mdW5jdGlvbiBzKHQpe3ZhciBlPXt9O3JldHVybiB0LmZvckVhY2goZnVuY3Rpb24odCxpKXtlW3RdPSEwfSksZX1mdW5jdGlvbiBhKHQsaSxyKXtpZih0LkFDJiZpJiZSKGkuZ3QpJiZpLmd0IT09ZS5ndCYmKCFpLmNvbnN0cnVjdG9yfHxpLmNvbnN0cnVjdG9yLnByb3RvdHlwZSE9PWkpKXt2YXIgbj1pLmd0KHIsdCk7cmV0dXJuIG0obil8fChuPWEodCxuLHIpKSxufXZhciBvPWModCxpKTtpZihvKXJldHVybiBvO3ZhciBmPU9iamVjdC5rZXlzKGkpLGc9cyhmKTtpZih0Lk9DJiYoZj1PYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhpKSksSShpKSYmKGYuaW5kZXhPZihcIm1lc3NhZ2VcIik+PTB8fGYuaW5kZXhPZihcImRlc2NyaXB0aW9uXCIpPj0wKSlyZXR1cm4gaChpKTtpZigwPT09Zi5sZW5ndGgpe2lmKFIoaSkpe3ZhciB2PWkubmFtZT9cIjogXCIraS5uYW1lOlwiXCI7cmV0dXJuIHQuUkMoXCJbRnVuY3Rpb25cIit2K1wiXVwiLFwic3BlY2lhbFwiKX1pZihTKGkpKXJldHVybiB0LlJDKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpKSxcInJlZ2V4cFwiKTtpZihFKGkpKXJldHVybiB0LlJDKERhdGUucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoaSksXCJkYXRlXCIpO2lmKEkoaSkpcmV0dXJuIGgoaSl9dmFyIHk9XCJcIix3PSExLFQ9W1wie1wiLFwifVwiXTtpZihkKGkpJiYodz0hMCxUPVtcIltcIixcIl1cIl0pLFIoaSkpe3ZhciBiPWkubmFtZT9cIjogXCIraS5uYW1lOlwiXCI7eT1cIiBbRnVuY3Rpb25cIitiK1wiXVwifWlmKFMoaSkmJih5PVwiIFwiK1JlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChpKSksRShpKSYmKHk9XCIgXCIrRGF0ZS5wcm90b3R5cGUudG9VVENTdHJpbmcuY2FsbChpKSksSShpKSYmKHk9XCIgXCIraChpKSksMD09PWYubGVuZ3RoJiYoIXd8fDA9PWkubGVuZ3RoKSlyZXR1cm4gVFswXSt5K1RbMV07aWYocjwwKXJldHVybiBTKGkpP3QuUkMoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKGkpLFwicmVnZXhwXCIpOnQuUkMoXCJbT2JqZWN0XVwiLFwic3BlY2lhbFwiKTt0LklDLnB1c2goaSk7dmFyIGs7cmV0dXJuIGs9dz9wKHQsaSxyLGcsZik6Zi5tYXAoZnVuY3Rpb24oZSl7cmV0dXJuIHUodCxpLHIsZyxlLHcpfSksdC5JQy5wb3AoKSxsKGsseSxUKX1mdW5jdGlvbiBjKHQsZSl7aWYoVChlKSlyZXR1cm4gdC5SQyhcInVuZGVmaW5lZFwiLFwidW5kZWZpbmVkXCIpO2lmKG0oZSkpe3ZhciBpPVwiJ1wiK0pTT04uc3RyaW5naWZ5KGUpLnJlcGxhY2UoL15cInxcIiQvZyxcIlwiKS5yZXBsYWNlKC8nL2csXCJcXFxcJ1wiKS5yZXBsYWNlKC9cXFxcXCIvZywnXCInKStcIidcIjtyZXR1cm4gdC5SQyhpLFwic3RyaW5nXCIpfXJldHVybiB5KGUpP3QuUkMoXCJcIitlLFwibnVtYmVyXCIpOmYoZSk/dC5SQyhcIlwiK2UsXCJib29sZWFuXCIpOmcoZSk/dC5SQyhcIm51bGxcIixcIm51bGxcIik6dm9pZCAwfWZ1bmN0aW9uIGgodCl7cmV0dXJuXCJbXCIrRXJyb3IucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodCkrXCJdXCJ9ZnVuY3Rpb24gcCh0LGUsaSxyLG4pe2Zvcih2YXIgbz1bXSxzPTAsYT1lLmxlbmd0aDtzPGE7KytzKUEoZSxTdHJpbmcocykpP28ucHVzaCh1KHQsZSxpLHIsU3RyaW5nKHMpLCEwKSk6by5wdXNoKFwiXCIpO3JldHVybiBuLmZvckVhY2goZnVuY3Rpb24obil7bi5tYXRjaCgvXlxcZCskLyl8fG8ucHVzaCh1KHQsZSxpLHIsbiwhMCkpfSksb31mdW5jdGlvbiB1KHQsZSxpLHIsbixvKXt2YXIgcyxjLGg7aWYoaD1PYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKGUsbil8fHt2YWx1ZTplW25dfSxoLmdldD9jPWguc2V0P3QuUkMoXCJbR2V0dGVyL1NldHRlcl1cIixcInNwZWNpYWxcIik6dC5SQyhcIltHZXR0ZXJdXCIsXCJzcGVjaWFsXCIpOmguc2V0JiYoYz10LlJDKFwiW1NldHRlcl1cIixcInNwZWNpYWxcIikpLEEocixuKXx8KHM9XCJbXCIrbitcIl1cIiksY3x8KHQuSUMuaW5kZXhPZihoLnZhbHVlKTwwPyhjPWcoaSk/YSh0LGgudmFsdWUsbnVsbCk6YSh0LGgudmFsdWUsaS0xKSxjLmluZGV4T2YoXCJcXG5cIik+LTEmJihjPW8/Yy5zcGxpdChcIlxcblwiKS5tYXAoZnVuY3Rpb24odCl7cmV0dXJuXCIgIFwiK3R9KS5qb2luKFwiXFxuXCIpLnN1YnN0cigyKTpcIlxcblwiK2Muc3BsaXQoXCJcXG5cIikubWFwKGZ1bmN0aW9uKHQpe3JldHVyblwiICAgXCIrdH0pLmpvaW4oXCJcXG5cIikpKTpjPXQuUkMoXCJbQ2lyY3VsYXJdXCIsXCJzcGVjaWFsXCIpKSxUKHMpKXtpZihvJiZuLm1hdGNoKC9eXFxkKyQvKSlyZXR1cm4gYztzPUpTT04uc3RyaW5naWZ5KFwiXCIrbikscy5tYXRjaCgvXlwiKFthLXpBLVpfXVthLXpBLVpfMC05XSopXCIkLyk/KHM9cy5zdWJzdHIoMSxzLmxlbmd0aC0yKSxzPXQuUkMocyxcIm5hbWVcIikpOihzPXMucmVwbGFjZSgvJy9nLFwiXFxcXCdcIikucmVwbGFjZSgvXFxcXFwiL2csJ1wiJykucmVwbGFjZSgvKF5cInxcIiQpL2csXCInXCIpLHM9dC5SQyhzLFwic3RyaW5nXCIpKX1yZXR1cm4gcytcIjogXCIrY31mdW5jdGlvbiBsKHQsZSxpKXt2YXIgcj0wLG49dC5yZWR1Y2UoZnVuY3Rpb24odCxlKXtyZXR1cm4gcisrLGUuaW5kZXhPZihcIlxcblwiKT49MCYmcisrLHQrZS5yZXBsYWNlKC9cXHUwMDFiXFxbXFxkXFxkP20vZyxcIlwiKS5sZW5ndGgrMX0sMCk7cmV0dXJuIG4+NjA/aVswXSsoXCJcIj09PWU/XCJcIjplK1wiXFxuIFwiKStcIiBcIit0LmpvaW4oXCIsXFxuICBcIikrXCIgXCIraVsxXTppWzBdK2UrXCIgXCIrdC5qb2luKFwiLCBcIikrXCIgXCIraVsxXX1mdW5jdGlvbiBkKHQpe3JldHVybiBBcnJheS5pc0FycmF5KHQpfWZ1bmN0aW9uIGYodCl7cmV0dXJuXCJib29sZWFuXCI9PXR5cGVvZiB0fWZ1bmN0aW9uIGcodCl7cmV0dXJuIG51bGw9PT10fWZ1bmN0aW9uIHYodCl7cmV0dXJuIG51bGw9PXR9ZnVuY3Rpb24geSh0KXtyZXR1cm5cIm51bWJlclwiPT10eXBlb2YgdH1mdW5jdGlvbiBtKHQpe3JldHVyblwic3RyaW5nXCI9PXR5cGVvZiB0fWZ1bmN0aW9uIHcodCl7cmV0dXJuXCJzeW1ib2xcIj09dHlwZW9mIHR9ZnVuY3Rpb24gVCh0KXtyZXR1cm4gdm9pZCAwPT09dH1mdW5jdGlvbiBTKHQpe3JldHVybiBiKHQpJiZcIltvYmplY3QgUmVnRXhwXVwiPT09Qyh0KX1mdW5jdGlvbiBiKHQpe3JldHVyblwib2JqZWN0XCI9PXR5cGVvZiB0JiZudWxsIT09dH1mdW5jdGlvbiBFKHQpe3JldHVybiBiKHQpJiZcIltvYmplY3QgRGF0ZV1cIj09PUModCl9ZnVuY3Rpb24gSSh0KXtyZXR1cm4gYih0KSYmKFwiW29iamVjdCBFcnJvcl1cIj09PUModCl8fHQgaW5zdGFuY2VvZiBFcnJvcil9ZnVuY3Rpb24gUih0KXtyZXR1cm5cImZ1bmN0aW9uXCI9PXR5cGVvZiB0fWZ1bmN0aW9uIGsodCl7cmV0dXJuIG51bGw9PT10fHxcImJvb2xlYW5cIj09dHlwZW9mIHR8fFwibnVtYmVyXCI9PXR5cGVvZiB0fHxcInN0cmluZ1wiPT10eXBlb2YgdHx8XCJzeW1ib2xcIj09dHlwZW9mIHR8fFwidW5kZWZpbmVkXCI9PXR5cGVvZiB0fWZ1bmN0aW9uIEModCl7cmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh0KX1mdW5jdGlvbiBPKHQpe3JldHVybiB0PDEwP1wiMFwiK3QudG9TdHJpbmcoMTApOnQudG9TdHJpbmcoMTApfWZ1bmN0aW9uIFAoKXt2YXIgdD1uZXcgRGF0ZSxlPVtPKHQuZ2V0SG91cnMoKSksTyh0LmdldE1pbnV0ZXMoKSksTyh0LmdldFNlY29uZHMoKSldLmpvaW4oXCI6XCIpO3JldHVyblt0LmdldERhdGUoKSxGW3QuZ2V0TW9udGgoKV0sZV0uam9pbihcIiBcIil9ZnVuY3Rpb24gQSh0LGUpe3JldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodCxlKX12YXIgTj0vJVtzZGolXS9nO2UuZm9ybWF0PWZ1bmN0aW9uKHQpe2lmKCFtKHQpKXtmb3IodmFyIGU9W10saT0wO2k8YXJndW1lbnRzLmxlbmd0aDtpKyspZS5wdXNoKHIoYXJndW1lbnRzW2ldKSk7cmV0dXJuIGUuam9pbihcIiBcIil9Zm9yKHZhciBpPTEsbj1hcmd1bWVudHMsbz1uLmxlbmd0aCxzPVN0cmluZyh0KS5yZXBsYWNlKE4sZnVuY3Rpb24odCl7aWYoXCIlJVwiPT09dClyZXR1cm5cIiVcIjtpZihpPj1vKXJldHVybiB0O3N3aXRjaCh0KXtjYXNlXCIlc1wiOnJldHVybiBTdHJpbmcobltpKytdKTtjYXNlXCIlZFwiOnJldHVybiBOdW1iZXIobltpKytdKTtjYXNlXCIlalwiOnRyeXtyZXR1cm4gSlNPTi5zdHJpbmdpZnkobltpKytdKX1jYXRjaChlKXtyZXR1cm5cIltDaXJjdWxhcl1cIn1kZWZhdWx0OnJldHVybiB0fX0pLGE9bltpXTtpPG87YT1uWysraV0pcys9ZyhhKXx8IWIoYSk/XCIgXCIrYTpcIiBcIityKGEpO3JldHVybiBzfSxlLnhDPWZ1bmN0aW9uKHQsaSl7ZnVuY3Rpb24gcigpe2lmKCFuKXtpZihwcm9jZXNzLnRocm93RGVwcmVjYXRpb24pdGhyb3cgbmV3IEVycm9yKGkpO3Byb2Nlc3MudHJhY2VEZXByZWNhdGlvbj9jb25zb2xlLnRyYWNlKGkpOmNvbnNvbGUuZXJyb3IoaSksbj0hMH1yZXR1cm4gdC5hcHBseSh0aGlzLGFyZ3VtZW50cyl9aWYoVChnbG9iYWwucHJvY2VzcykpcmV0dXJuIGZ1bmN0aW9uKCl7cmV0dXJuIGUueEModCxpKS5hcHBseSh0aGlzLGFyZ3VtZW50cyl9O2lmKHByb2Nlc3Mubm9EZXByZWNhdGlvbj09PSEwKXJldHVybiB0O3ZhciBuPSExO3JldHVybiByfTt2YXIgeCxCPXt9O2UuQkM9ZnVuY3Rpb24odCl7aWYoVCh4KSYmKHg9cHJvY2Vzcy5PdC5OT0RFX0RFQlVHfHxcIlwiKSx0PXQudG9VcHBlckNhc2UoKSwhQlt0XSlpZihuZXcgUmVnRXhwKFwiXFxcXGJcIit0K1wiXFxcXGJcIixcImlcIikudGVzdCh4KSl7dmFyIGk9cHJvY2Vzcy5waWQ7Qlt0XT1mdW5jdGlvbigpe3ZhciByPWUuZm9ybWF0LmFwcGx5KGUsYXJndW1lbnRzKTtjb25zb2xlLmVycm9yKFwiJXMgJWQ6ICVzXCIsdCxpLHIpfX1lbHNlIEJbdF09ZnVuY3Rpb24oKXt9O3JldHVybiBCW3RdfSxlLmd0PXIsci5DQz17Ym9sZDpbMSwyMl0sRkM6WzMsMjNdLF9DOls0LDI0XSxpbnZlcnNlOls3LDI3XSxEQzpbMzcsMzldLEhDOls5MCwzOV0sTEM6WzMwLDM5XSxibHVlOlszNCwzOV0sTUM6WzM2LDM5XSxncmVlbjpbMzIsMzldLGpDOlszNSwzOV0scmVkOlszMSwzOV0sVUM6WzMzLDM5XX0sci5OQz17VkM6XCJjeWFuXCIsbnVtYmVyOlwieWVsbG93XCIsUUM6XCJ5ZWxsb3dcIix1bmRlZmluZWQ6XCJncmV5XCIscUM6XCJib2xkXCIsSkM6XCJncmVlblwiLHhUOlwibWFnZW50YVwiLEtDOlwicmVkXCJ9LGUuaXNBcnJheT1kLGUuT209ZixlLkFtPWcsZS5haz12LGUuTm09eSxlLnhtPW0sZS5HQz13LGUuQm09VCxlLnpDPVMsZS5vdj1iLGUuV0M9RSxlLiRDPUksZS5QbT1SLGUuWUM9ayxlLmlzQnVmZmVyPWkoNjIpO3ZhciBGPVtcIkphblwiLFwiRmViXCIsXCJNYXJcIixcIkFwclwiLFwiTWF5XCIsXCJKdW5cIixcIkp1bFwiLFwiQXVnXCIsXCJTZXBcIixcIk9jdFwiLFwiTm92XCIsXCJEZWNcIl07ZS5sb2c9ZnVuY3Rpb24oKXtjb25zb2xlLmxvZyhcIiVzIC0gJXNcIixQKCksZS5mb3JtYXQuYXBwbHkoZSxhcmd1bWVudHMpKX0sZS5xcz1pKDYxKSxlLlBDPWZ1bmN0aW9uKHQsZSl7aWYoIWV8fCFiKGUpKXJldHVybiB0O2Zvcih2YXIgaT1PYmplY3Qua2V5cyhlKSxyPWkubGVuZ3RoO3ItLTspdFtpW3JdXT1lW2lbcl1dO3JldHVybiB0fX0sZnVuY3Rpb24odCxlKXsoZnVuY3Rpb24oZSl7dC50PWV9KS5jYWxsKGUse30pfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7IWZ1bmN0aW9uKCl7dmFyIGU9aSgzKSxyPWUubG9nLG49ZS5yaTt0LnQucmk9bix0LnQuWGU9ZS5YZSx0LnQuWWU9ZS5ZZTt2YXIgbz1pKDY2KXx8bnVsbCxzPWkoNjgpfHxudWxsLGE9aSg3MCl8fG51bGwsYz1pKDcyKXx8bnVsbDtzd2l0Y2gobi50aSl7Y2FzZVwiY2hyb21lXCI6aWYoIW98fCFvLlhDKXJldHVybiB2b2lkIHIoXCJDaHJvbWUgc2hpbSBpcyBub3QgaW5jbHVkZWQgaW4gdGhpcyBhZGFwdGVyIHJlbGVhc2UuXCIpO3IoXCJhZGFwdGVyLmpzIHNoaW1taW5nIGNocm9tZS5cIiksdC50Lm5DPW8sby5aQygpLG8udE8oKSxlLmVpKCksby5lTygpLG8uWEMoKSxvLmlPKCksby5yTygpO2JyZWFrO2Nhc2VcImZpcmVmb3hcIjppZighYXx8IWEuWEMpcmV0dXJuIHZvaWQgcihcIkZpcmVmb3ggc2hpbSBpcyBub3QgaW5jbHVkZWQgaW4gdGhpcyBhZGFwdGVyIHJlbGVhc2UuXCIpO3IoXCJhZGFwdGVyLmpzIHNoaW1taW5nIGZpcmVmb3guXCIpLHQudC5uQz1hLGEuWkMoKSxlLmVpKCksYS5lTygpLGEuWEMoKSxhLmlPKCk7YnJlYWs7Y2FzZVwiZWRnZVwiOmlmKCFzfHwhcy5YQylyZXR1cm4gdm9pZCByKFwiTVMgZWRnZSBzaGltIGlzIG5vdCBpbmNsdWRlZCBpbiB0aGlzIGFkYXB0ZXIgcmVsZWFzZS5cIik7cihcImFkYXB0ZXIuanMgc2hpbW1pbmcgZWRnZS5cIiksdC50Lm5DPXMscy5aQygpLGUuZWkoKSxzLlhDKCk7YnJlYWs7Y2FzZVwic2FmYXJpXCI6aWYoIWMpcmV0dXJuIHZvaWQgcihcIlNhZmFyaSBzaGltIGlzIG5vdCBpbmNsdWRlZCBpbiB0aGlzIGFkYXB0ZXIgcmVsZWFzZS5cIik7cihcImFkYXB0ZXIuanMgc2hpbW1pbmcgc2FmYXJpLlwiKSx0LnQubkM9YyxjLlpDKCk7YnJlYWs7ZGVmYXVsdDpyKFwiVW5zdXBwb3J0ZWQgYnJvd3NlciFcIil9fSgpfSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI9aSgzKS5sb2csbj1pKDMpLnJpLG89e3RPOmZ1bmN0aW9uKCl7d2luZG93Lk1lZGlhU3RyZWFtPXdpbmRvdy5NZWRpYVN0cmVhbXx8d2luZG93LndlYmtpdE1lZGlhU3RyZWFtfSxpTzpmdW5jdGlvbigpe1wib2JqZWN0XCIhPXR5cGVvZiB3aW5kb3d8fCF3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb258fFwib250cmFja1wiaW4gd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZXx8T2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUsXCJvbnRyYWNrXCIse2dldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLm5PfSxzZXQ6ZnVuY3Rpb24odCl7dmFyIGU9dGhpczt0aGlzLm5PJiYodGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKFwidHJhY2tcIix0aGlzLm5PKSx0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoXCJhZGRzdHJlYW1cIix0aGlzLm9PKSksdGhpcy5hZGRFdmVudExpc3RlbmVyKFwidHJhY2tcIix0aGlzLm5PPXQpLHRoaXMuYWRkRXZlbnRMaXN0ZW5lcihcImFkZHN0cmVhbVwiLHRoaXMub089ZnVuY3Rpb24odCl7dC5zdHJlYW0uYWRkRXZlbnRMaXN0ZW5lcihcImFkZHRyYWNrXCIsZnVuY3Rpb24oaSl7dmFyIHI9bmV3IEV2ZW50KFwidHJhY2tcIik7ci50cmFjaz1pLnRyYWNrLHIucmVjZWl2ZXI9e3RyYWNrOmkudHJhY2t9LHIuc089W3Quc3RyZWFtXSxlLmRpc3BhdGNoRXZlbnQocil9KSx0LnN0cmVhbS5nZXRUcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3ZhciBpPW5ldyBFdmVudChcInRyYWNrXCIpO2kudHJhY2s9ZSxpLnJlY2VpdmVyPXt0cmFjazplfSxpLnNPPVt0LnN0cmVhbV0sdGhpcy5kaXNwYXRjaEV2ZW50KGkpfS5iaW5kKHRoaXMpKX0uYmluZCh0aGlzKSl9fSl9LHJPOmZ1bmN0aW9uKCl7aWYoXCJvYmplY3RcIj09dHlwZW9mIHdpbmRvdyYmd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uJiYhKFwiZ2V0U2VuZGVyc1wiaW4gUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlKSYmXCJjcmVhdGVEVE1GU2VuZGVyXCJpbiBSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUpe1JUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5nZXRTZW5kZXJzPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYU99O3ZhciB0PVJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5hZGRTdHJlYW0sZT1SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUucmVtb3ZlU3RyZWFtO1JUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5hZGRTdHJlYW09ZnVuY3Rpb24oZSl7dmFyIGk9dGhpcztpLmFPPWkuYU98fFtdLHQuYXBwbHkoaSxbZV0pLGUuZ2V0VHJhY2tzKCkuZm9yRWFjaChmdW5jdGlvbih0KXtpLmFPLnB1c2goe3RyYWNrOnQsZ2V0IGNPKCl7cmV0dXJuIHZvaWQgMD09PXRoaXMuaE8mJihcImF1ZGlvXCI9PT10LmtpbmQ/dGhpcy5oTz1pLmNyZWF0ZURUTUZTZW5kZXIodCk6dGhpcy5oTz1udWxsKSx0aGlzLmhPfX0pfSl9LFJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5yZW1vdmVTdHJlYW09ZnVuY3Rpb24odCl7dmFyIGk9dGhpcztpLmFPPWkuYU98fFtdLGUuYXBwbHkoaSxbdF0pLHQuZ2V0VHJhY2tzKCkuZm9yRWFjaChmdW5jdGlvbih0KXt2YXIgZT1pLmFPLmZpbmQoZnVuY3Rpb24oZSl7cmV0dXJuIGUudHJhY2s9PT10fSk7ZSYmaS5hTy5zcGxpY2UoaS5hTy5pbmRleE9mKGUpLDEpfSl9fX0sZU86ZnVuY3Rpb24oKXtcIm9iamVjdFwiPT10eXBlb2Ygd2luZG93JiYoIXdpbmRvdy5IVE1MTWVkaWFFbGVtZW50fHxcInNyY09iamVjdFwiaW4gd2luZG93LkhUTUxNZWRpYUVsZW1lbnQucHJvdG90eXBlfHxPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LkhUTUxNZWRpYUVsZW1lbnQucHJvdG90eXBlLFwic3JjT2JqZWN0XCIse2dldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLnBPfSxzZXQ6ZnVuY3Rpb24odCl7dmFyIGU9dGhpcztyZXR1cm4gdGhpcy5wTz10LHRoaXMuc3JjJiZVUkwucmV2b2tlT2JqZWN0VVJMKHRoaXMuc3JjKSx0Pyh0aGlzLnNyYz1VUkwuY3JlYXRlT2JqZWN0VVJMKHQpLHQuYWRkRXZlbnRMaXN0ZW5lcihcImFkZHRyYWNrXCIsZnVuY3Rpb24oKXtlLnNyYyYmVVJMLnJldm9rZU9iamVjdFVSTChlLnNyYyksZS5zcmM9VVJMLmNyZWF0ZU9iamVjdFVSTCh0KX0pLHZvaWQgdC5hZGRFdmVudExpc3RlbmVyKFwicmVtb3ZldHJhY2tcIixmdW5jdGlvbigpe2Uuc3JjJiZVUkwucmV2b2tlT2JqZWN0VVJMKGUuc3JjKSxlLnNyYz1VUkwuY3JlYXRlT2JqZWN0VVJMKHQpfSkpOnZvaWQodGhpcy5zcmM9XCJcIil9fSkpfSxYQzpmdW5jdGlvbigpe3dpbmRvdy5SVENQZWVyQ29ubmVjdGlvbnx8KHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbj1mdW5jdGlvbih0LGUpe3JldHVybiByKFwiUGVlckNvbm5lY3Rpb25cIiksdCYmdC51TyYmKHQubE89dC51TyksbmV3IHdlYmtpdFJUQ1BlZXJDb25uZWN0aW9uKHQsZSl9LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGU9d2Via2l0UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLHdlYmtpdFJUQ1BlZXJDb25uZWN0aW9uLmdlbmVyYXRlQ2VydGlmaWNhdGUmJk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24sXCJnZW5lcmF0ZUNlcnRpZmljYXRlXCIse2dldDpmdW5jdGlvbigpe3JldHVybiB3ZWJraXRSVENQZWVyQ29ubmVjdGlvbi5nZW5lcmF0ZUNlcnRpZmljYXRlfX0pKTt2YXIgdD1SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0U3RhdHM7UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldFN0YXRzPWZ1bmN0aW9uKGUsaSxyKXt2YXIgbj10aGlzLG89YXJndW1lbnRzO2lmKGFyZ3VtZW50cy5sZW5ndGg+MCYmXCJmdW5jdGlvblwiPT10eXBlb2YgZSlyZXR1cm4gdC5hcHBseSh0aGlzLGFyZ3VtZW50cyk7aWYoMD09PXQubGVuZ3RoJiYoMD09PWFyZ3VtZW50cy5sZW5ndGh8fFwiZnVuY3Rpb25cIiE9dHlwZW9mIGFyZ3VtZW50c1swXSkpcmV0dXJuIHQuYXBwbHkodGhpcyxbXSk7dmFyIHM9ZnVuY3Rpb24odCl7dmFyIGU9e30saT10LnJlc3VsdCgpO3JldHVybiBpLmZvckVhY2goZnVuY3Rpb24odCl7dmFyIGk9e2lkOnQuaWQsdGltZXN0YW1wOnQudGltZXN0YW1wLHR5cGU6e2RPOlwibG9jYWwtY2FuZGlkYXRlXCIsZk86XCJyZW1vdGUtY2FuZGlkYXRlXCJ9W3QudHlwZV18fHQudHlwZX07dC5uYW1lcygpLmZvckVhY2goZnVuY3Rpb24oZSl7aVtlXT10LnN0YXQoZSl9KSxlW2kuaWRdPWl9KSxlfSxhPWZ1bmN0aW9uKHQpe3JldHVybiBuZXcgTWFwKE9iamVjdC5rZXlzKHQpLm1hcChmdW5jdGlvbihlKXtyZXR1cm5bZSx0W2VdXX0pKX07aWYoYXJndW1lbnRzLmxlbmd0aD49Mil7dmFyIGM9ZnVuY3Rpb24odCl7b1sxXShhKHModCkpKX07cmV0dXJuIHQuYXBwbHkodGhpcyxbYyxhcmd1bWVudHNbMF1dKX1yZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24oZSxpKXt0LmFwcGx5KG4sW2Z1bmN0aW9uKHQpe2UoYShzKHQpKSl9LGldKX0pLnRoZW4oaSxyKX0sbi52ZXJzaW9uPDUxJiZbXCJzZXRMb2NhbERlc2NyaXB0aW9uXCIsXCJzZXRSZW1vdGVEZXNjcmlwdGlvblwiLFwiYWRkSWNlQ2FuZGlkYXRlXCJdLmZvckVhY2goZnVuY3Rpb24odCl7dmFyIGU9UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW3RdO1JUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZVt0XT1mdW5jdGlvbigpe3ZhciB0PWFyZ3VtZW50cyxpPXRoaXMscj1uZXcgUHJvbWlzZShmdW5jdGlvbihyLG4pe2UuYXBwbHkoaSxbdFswXSxyLG5dKX0pO3JldHVybiB0Lmxlbmd0aDwyP3I6ci50aGVuKGZ1bmN0aW9uKCl7dFsxXS5hcHBseShudWxsLFtdKX0sZnVuY3Rpb24oZSl7dC5sZW5ndGg+PTMmJnRbMl0uYXBwbHkobnVsbCxbZV0pfSl9fSksbi52ZXJzaW9uPDUyJiZbXCJjcmVhdGVPZmZlclwiLFwiY3JlYXRlQW5zd2VyXCJdLmZvckVhY2goZnVuY3Rpb24odCl7dmFyIGU9UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW3RdO1JUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZVt0XT1mdW5jdGlvbigpe3ZhciB0PXRoaXM7aWYoYXJndW1lbnRzLmxlbmd0aDwxfHwxPT09YXJndW1lbnRzLmxlbmd0aCYmXCJvYmplY3RcIj09dHlwZW9mIGFyZ3VtZW50c1swXSl7dmFyIGk9MT09PWFyZ3VtZW50cy5sZW5ndGg/YXJndW1lbnRzWzBdOnZvaWQgMDtyZXR1cm4gbmV3IFByb21pc2UoZnVuY3Rpb24ocixuKXtlLmFwcGx5KHQsW3IsbixpXSl9KX1yZXR1cm4gZS5hcHBseSh0aGlzLGFyZ3VtZW50cyl9fSksW1wic2V0TG9jYWxEZXNjcmlwdGlvblwiLFwic2V0UmVtb3RlRGVzY3JpcHRpb25cIixcImFkZEljZUNhbmRpZGF0ZVwiXS5mb3JFYWNoKGZ1bmN0aW9uKHQpe3ZhciBlPVJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZVt0XTtSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGVbdF09ZnVuY3Rpb24oKXtyZXR1cm4gYXJndW1lbnRzWzBdPW5ldyhcImFkZEljZUNhbmRpZGF0ZVwiPT09dD9SVENJY2VDYW5kaWRhdGU6UlRDU2Vzc2lvbkRlc2NyaXB0aW9uKShhcmd1bWVudHNbMF0pLGUuYXBwbHkodGhpcyxhcmd1bWVudHMpfX0pO3ZhciBlPVJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5hZGRJY2VDYW5kaWRhdGU7UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmFkZEljZUNhbmRpZGF0ZT1mdW5jdGlvbigpe3JldHVybiBhcmd1bWVudHNbMF0/ZS5hcHBseSh0aGlzLGFyZ3VtZW50cyk6KGFyZ3VtZW50c1sxXSYmYXJndW1lbnRzWzFdLmFwcGx5KG51bGwpLFByb21pc2UucmVzb2x2ZSgpKX19fTt0LnQ9e3RPOm8udE8saU86by5pTyxyTzpvLnJPLGVPOm8uZU8sWEM6by5YQyxaQzppKDY3KX19LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcj1pKDMpLmxvZyxuPWkoMykucmk7dC50PWZ1bmN0aW9uKCl7dmFyIHQ9ZnVuY3Rpb24odCl7aWYoXCJvYmplY3RcIiE9dHlwZW9mIHR8fHQuZ098fHQub3B0aW9uYWwpcmV0dXJuIHQ7dmFyIGU9e307cmV0dXJuIE9iamVjdC5rZXlzKHQpLmZvckVhY2goZnVuY3Rpb24oaSl7aWYoXCJyZXF1aXJlXCIhPT1pJiZcImFkdmFuY2VkXCIhPT1pJiZcIm1lZGlhU291cmNlXCIhPT1pKXt2YXIgcj1cIm9iamVjdFwiPT10eXBlb2YgdFtpXT90W2ldOnt2Tzp0W2ldfTt2b2lkIDAhPT1yLnlPJiZcIm51bWJlclwiPT10eXBlb2Ygci55TyYmKHIubWluPXIubWF4PXIueU8pO3ZhciBuPWZ1bmN0aW9uKHQsZSl7cmV0dXJuIHQ/dCtlLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpK2Uuc2xpY2UoMSk6XCJkZXZpY2VJZFwiPT09ZT9cInNvdXJjZUlkXCI6ZX07aWYodm9pZCAwIT09ci52Tyl7ZS5vcHRpb25hbD1lLm9wdGlvbmFsfHxbXTt2YXIgbz17fTtcIm51bWJlclwiPT10eXBlb2Ygci52Tz8ob1tuKFwibWluXCIsaSldPXIudk8sZS5vcHRpb25hbC5wdXNoKG8pLG89e30sb1tuKFwibWF4XCIsaSldPXIudk8sZS5vcHRpb25hbC5wdXNoKG8pKToob1tuKFwiXCIsaSldPXIudk8sZS5vcHRpb25hbC5wdXNoKG8pKX12b2lkIDAhPT1yLnlPJiZcIm51bWJlclwiIT10eXBlb2Ygci55Tz8oZS5nTz1lLmdPfHx7fSxlLmdPW24oXCJcIixpKV09ci55Tyk6W1wibWluXCIsXCJtYXhcIl0uZm9yRWFjaChmdW5jdGlvbih0KXt2b2lkIDAhPT1yW3RdJiYoZS5nTz1lLmdPfHx7fSxlLmdPW24odCxpKV09clt0XSl9KX19KSx0Lm1PJiYoZS5vcHRpb25hbD0oZS5vcHRpb25hbHx8W10pLmNvbmNhdCh0Lm1PKSksZX0sZT1mdW5jdGlvbihlLGkpe2lmKGU9SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShlKSksZSYmZS5NcCYmKGUuTXA9dChlLk1wKSksZSYmXCJvYmplY3RcIj09dHlwZW9mIGUudmlkZW8pe3ZhciBvPWUudmlkZW8ud087bz1vJiYoXCJvYmplY3RcIj09dHlwZW9mIG8/bzp7dk86b30pO3ZhciBzPW4udmVyc2lvbjw1OTtpZihvJiYoXCJ1c2VyXCI9PT1vLnlPfHxcImVudmlyb25tZW50XCI9PT1vLnlPfHxcInVzZXJcIj09PW8udk98fFwiZW52aXJvbm1lbnRcIj09PW8udk8pJiYoIW5hdmlnYXRvci5tZWRpYURldmljZXMuVE98fCFuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLlRPKCkud098fHMpJiYoZGVsZXRlIGUudmlkZW8ud08sXCJlbnZpcm9ubWVudFwiPT09by55T3x8XCJlbnZpcm9ubWVudFwiPT09by52TykpcmV0dXJuIG5hdmlnYXRvci5tZWRpYURldmljZXMuU08oKS50aGVuKGZ1bmN0aW9uKG4pe249bi5maWx0ZXIoZnVuY3Rpb24odCl7cmV0dXJuXCJ2aWRlb2lucHV0XCI9PT10LmtpbmR9KTt2YXIgcz1uLmZpbmQoZnVuY3Rpb24odCl7cmV0dXJuIHQubGFiZWwudG9Mb3dlckNhc2UoKS5pbmRleE9mKFwiYmFja1wiKSE9PS0xfSl8fG4ubGVuZ3RoJiZuW24ubGVuZ3RoLTFdO3JldHVybiBzJiYoZS52aWRlby5iTz1vLnlPP3t5TzpzLmJPfTp7dk86cy5iT30pLGUudmlkZW89dChlLnZpZGVvKSxyKFwiY2hyb21lOiBcIitKU09OLnN0cmluZ2lmeShlKSksaShlKX0pO2UudmlkZW89dChlLnZpZGVvKX1yZXR1cm4gcihcImNocm9tZTogXCIrSlNPTi5zdHJpbmdpZnkoZSkpLGkoZSl9LGk9ZnVuY3Rpb24odCl7cmV0dXJue25hbWU6e0VPOlwiTm90QWxsb3dlZEVycm9yXCIsSU86XCJPdmVyY29uc3RyYWluZWRFcnJvclwifVt0Lm5hbWVdfHx0Lm5hbWUsbWVzc2FnZTp0Lm1lc3NhZ2UsUk86dC5jb25zdHJhaW50TmFtZSx0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiB0aGlzLm5hbWUrKHRoaXMubWVzc2FnZSYmXCI6IFwiKSt0aGlzLm1lc3NhZ2V9fX0sbz1mdW5jdGlvbih0LHIsbil7ZSh0LGZ1bmN0aW9uKHQpe25hdmlnYXRvci53ZWJraXRHZXRVc2VyTWVkaWEodCxyLGZ1bmN0aW9uKHQpe24oaSh0KSl9KX0pfTtuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhPW87dmFyIHM9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKGUsaSl7bmF2aWdhdG9yLmdldFVzZXJNZWRpYSh0LGUsaSl9KX07aWYobmF2aWdhdG9yLm1lZGlhRGV2aWNlc3x8KG5hdmlnYXRvci5tZWRpYURldmljZXM9e2dldFVzZXJNZWRpYTpzLFNPOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKHQpe3ZhciBlPXtNcDpcImF1ZGlvaW5wdXRcIix2aWRlbzpcInZpZGVvaW5wdXRcIn07cmV0dXJuIE1lZGlhU3RyZWFtVHJhY2suZ2V0U291cmNlcyhmdW5jdGlvbihpKXt0KGkubWFwKGZ1bmN0aW9uKHQpe3JldHVybntsYWJlbDp0LmxhYmVsLGtpbmQ6ZVt0LmtpbmRdLGJPOnQuaWQsa086XCJcIn19KSl9KX0pfSxUTzpmdW5jdGlvbigpe3JldHVybntiTzohMCxDTzohMCx3TzohMCxPTzohMCxoZWlnaHQ6ITAsd2lkdGg6ITB9fX0pLG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhKXt2YXIgYT1uYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYS5iaW5kKG5hdmlnYXRvci5tZWRpYURldmljZXMpO25hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhPWZ1bmN0aW9uKHQpe3JldHVybiBlKHQsZnVuY3Rpb24odCl7cmV0dXJuIGEodCkudGhlbihmdW5jdGlvbihlKXtpZih0Lk1wJiYhZS5nZXRBdWRpb1RyYWNrcygpLmxlbmd0aHx8dC52aWRlbyYmIWUuZ2V0VmlkZW9UcmFja3MoKS5sZW5ndGgpdGhyb3cgZS5nZXRUcmFja3MoKS5mb3JFYWNoKGZ1bmN0aW9uKHQpe3Quc3RvcCgpfSksbmV3IERPTUV4Y2VwdGlvbihcIlwiLFwiTm90Rm91bmRFcnJvclwiKTtyZXR1cm4gZX0sZnVuY3Rpb24odCl7cmV0dXJuIFByb21pc2UucmVqZWN0KGkodCkpfSl9KX19ZWxzZSBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYT1mdW5jdGlvbih0KXtyZXR1cm4gcyh0KX07XCJ1bmRlZmluZWRcIj09dHlwZW9mIG5hdmlnYXRvci5tZWRpYURldmljZXMuYWRkRXZlbnRMaXN0ZW5lciYmKG5hdmlnYXRvci5tZWRpYURldmljZXMuYWRkRXZlbnRMaXN0ZW5lcj1mdW5jdGlvbigpe3IoXCJEdW1teSBtZWRpYURldmljZXMuYWRkRXZlbnRMaXN0ZW5lciBjYWxsZWQuXCIpfSksXCJ1bmRlZmluZWRcIj09dHlwZW9mIG5hdmlnYXRvci5tZWRpYURldmljZXMucmVtb3ZlRXZlbnRMaXN0ZW5lciYmKG5hdmlnYXRvci5tZWRpYURldmljZXMucmVtb3ZlRXZlbnRMaXN0ZW5lcj1mdW5jdGlvbigpe3IoXCJEdW1teSBtZWRpYURldmljZXMucmVtb3ZlRXZlbnRMaXN0ZW5lciBjYWxsZWQuXCIpfSl9fSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7ZnVuY3Rpb24gcih0KXt2YXIgZT10LmZpbHRlcihmdW5jdGlvbih0KXtyZXR1cm5cImF1ZGlvXCI9PT10LmtpbmR9KSxpPXQuZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVyblwidmlkZW9cIj09PXQua2luZH0pO2Zvcih0PVtdO2UubGVuZ3RofHxpLmxlbmd0aDspZS5sZW5ndGgmJnQucHVzaChlLnNoaWZ0KCkpLFxuaS5sZW5ndGgmJnQucHVzaChpLnNoaWZ0KCkpO3JldHVybiB0fWZ1bmN0aW9uIG4odCl7dmFyIGU9ITE7cmV0dXJuIHQ9SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeSh0KSksdC5maWx0ZXIoZnVuY3Rpb24odCl7aWYodCYmKHQuUE98fHQudXJsKSl7dmFyIGk9dC5QT3x8dC51cmwscj1cInN0cmluZ1wiPT10eXBlb2YgaTtyZXR1cm4gciYmKGk9W2ldKSxpPWkuZmlsdGVyKGZ1bmN0aW9uKHQpe3ZhciBpPTA9PT10LmluZGV4T2YoXCJ0dXJuOlwiKSYmdC5pbmRleE9mKFwidHJhbnNwb3J0PXVkcFwiKSE9PS0xJiZ0LmluZGV4T2YoXCJ0dXJuOltcIik9PT0tMSYmIWU7cmV0dXJuIGk/KGU9ITAsITApOjA9PT10LmluZGV4T2YoXCJzdHVuOlwiKSYmcy52ZXJzaW9uPj0xNDM5M30pLGRlbGV0ZSB0LnVybCx0LlBPPXI/aVswXTppLCEhaS5sZW5ndGh9cmV0dXJuITF9KX12YXIgbz1pKDM1KSxzPWkoMykucmksYT17WEM6ZnVuY3Rpb24oKXtpZih3aW5kb3cuUlRDSWNlR2F0aGVyZXImJih3aW5kb3cuUlRDSWNlQ2FuZGlkYXRlfHwod2luZG93LlJUQ0ljZUNhbmRpZGF0ZT1mdW5jdGlvbih0KXtyZXR1cm4gdH0pLHdpbmRvdy5SVENTZXNzaW9uRGVzY3JpcHRpb258fCh3aW5kb3cuUlRDU2Vzc2lvbkRlc2NyaXB0aW9uPWZ1bmN0aW9uKHQpe3JldHVybiB0fSkscy52ZXJzaW9uPDE1MDI1KSl7dmFyIHQ9T2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihNZWRpYVN0cmVhbVRyYWNrLnByb3RvdHlwZSxcImVuYWJsZWRcIik7T2JqZWN0LmRlZmluZVByb3BlcnR5KE1lZGlhU3RyZWFtVHJhY2sucHJvdG90eXBlLFwiZW5hYmxlZFwiLHtzZXQ6ZnVuY3Rpb24oZSl7dC5zZXQuY2FsbCh0aGlzLGUpO3ZhciBpPW5ldyBFdmVudChcImVuYWJsZWRcIik7aS5lbmFibGVkPWUsdGhpcy5kaXNwYXRjaEV2ZW50KGkpfX0pfXdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbj1mdW5jdGlvbih0KXt2YXIgZT10aGlzLGk9ZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO2lmKFtcImFkZEV2ZW50TGlzdGVuZXJcIixcInJlbW92ZUV2ZW50TGlzdGVuZXJcIixcImRpc3BhdGNoRXZlbnRcIl0uZm9yRWFjaChmdW5jdGlvbih0KXtlW3RdPWlbdF0uYmluZChpKX0pLHRoaXMub25pY2VjYW5kaWRhdGU9bnVsbCx0aGlzLm9uYWRkc3RyZWFtPW51bGwsdGhpcy5BTz1udWxsLHRoaXMub25yZW1vdmVzdHJlYW09bnVsbCx0aGlzLm9uc2lnbmFsaW5nc3RhdGVjaGFuZ2U9bnVsbCx0aGlzLm9uaWNlY29ubmVjdGlvbnN0YXRlY2hhbmdlPW51bGwsdGhpcy5OTz1udWxsLHRoaXMub25uZWdvdGlhdGlvbm5lZWRlZD1udWxsLHRoaXMub25kYXRhY2hhbm5lbD1udWxsLHRoaXMueE89W10sdGhpcy5CTz1bXSx0aGlzLmdldExvY2FsU3RyZWFtcz1mdW5jdGlvbigpe3JldHVybiBlLnhPfSx0aGlzLmdldFJlbW90ZVN0cmVhbXM9ZnVuY3Rpb24oKXtyZXR1cm4gZS5CT30sdGhpcy5sb2NhbERlc2NyaXB0aW9uPW5ldyBSVENTZXNzaW9uRGVzY3JpcHRpb24oe3R5cGU6XCJcIixzZHA6XCJcIn0pLHRoaXMucmVtb3RlRGVzY3JpcHRpb249bmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbih7dHlwZTpcIlwiLHNkcDpcIlwifSksdGhpcy5zaWduYWxpbmdTdGF0ZT1cInN0YWJsZVwiLHRoaXMuaWNlQ29ubmVjdGlvblN0YXRlPVwibmV3XCIsdGhpcy5pY2VHYXRoZXJpbmdTdGF0ZT1cIm5ld1wiLHRoaXMuRk89e19POlwiYWxsXCIsaWNlU2VydmVyczpbXX0sdCYmdC51Tylzd2l0Y2godC51Tyl7Y2FzZVwiYWxsXCI6Y2FzZVwicmVsYXlcIjp0aGlzLkZPLl9PPXQudU99dGhpcy5ETz10JiZcIm1heC1idW5kbGVcIj09PXQuYnVuZGxlUG9saWN5LHQmJnQuaWNlU2VydmVycyYmKHRoaXMuRk8uaWNlU2VydmVycz1uKHQuaWNlU2VydmVycykpLHRoaXMuSE89dCx0aGlzLkxPPVtdLHRoaXMuTU89W119LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuak89ZnVuY3Rpb24oKXt2YXIgdD1uZXcgRXZlbnQoXCJpY2VnYXRoZXJpbmdzdGF0ZWNoYW5nZVwiKTt0aGlzLmRpc3BhdGNoRXZlbnQodCksbnVsbCE9PXRoaXMuTk8mJnRoaXMuTk8odCl9LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuVU89ZnVuY3Rpb24oKXt2YXIgdD10aGlzLGU9by5LYih0LmxvY2FsRGVzY3JpcHRpb24uc2RwKTt0aGlzLk1PLmZvckVhY2goZnVuY3Rpb24oaSl7dmFyIHI9IWkuY2FuZGlkYXRlfHwwPT09T2JqZWN0LmtleXMoaS5jYW5kaWRhdGUpLmxlbmd0aDtpZihyKWZvcih2YXIgbj0xO248ZS5sZW5ndGg7bisrKWVbbl0uaW5kZXhPZihcIlxcclxcbmE9ZW5kLW9mLWNhbmRpZGF0ZXNcXHJcXG5cIik9PT0tMSYmKGVbbl0rPVwiYT1lbmQtb2YtY2FuZGlkYXRlc1xcclxcblwiKTtlbHNlIGVbaS5jYW5kaWRhdGUuc2RwTUxpbmVJbmRleCsxXSs9XCJhPVwiK2kuY2FuZGlkYXRlLmNhbmRpZGF0ZStcIlxcclxcblwiO2lmKHQubG9jYWxEZXNjcmlwdGlvbi5zZHA9ZS5qb2luKFwiXCIpLHQuZGlzcGF0Y2hFdmVudChpKSxudWxsIT09dC5vbmljZWNhbmRpZGF0ZSYmdC5vbmljZWNhbmRpZGF0ZShpKSwhaS5jYW5kaWRhdGUmJlwiY29tcGxldGVcIiE9PXQuaWNlR2F0aGVyaW5nU3RhdGUpe3ZhciBvPXQuTE8uZXZlcnkoZnVuY3Rpb24odCl7cmV0dXJuIHQuWUUmJlwiY29tcGxldGVkXCI9PT10LllFLnN0YXRlfSk7byYmXCJjb21wbGV0ZVwiIT09dC5pY2VHYXRoZXJpbmdTdGF0ZUNoYW5nZSYmKHQuaWNlR2F0aGVyaW5nU3RhdGU9XCJjb21wbGV0ZVwiLHQuak8oKSl9fSksdGhpcy5NTz1bXX0sd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5nZXRDb25maWd1cmF0aW9uPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuSE99LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuYWRkU3RyZWFtPWZ1bmN0aW9uKHQpe2lmKHMudmVyc2lvbj49MTUwMjUpdGhpcy54Ty5wdXNoKHQpO2Vsc2V7dmFyIGU9dC5jbG9uZSgpO3QuZ2V0VHJhY2tzKCkuZm9yRWFjaChmdW5jdGlvbih0LGkpe3ZhciByPWUuZ2V0VHJhY2tzKClbaV07dC5hZGRFdmVudExpc3RlbmVyKFwiZW5hYmxlZFwiLGZ1bmN0aW9uKHQpe3IuZW5hYmxlZD10LmVuYWJsZWR9KX0pLHRoaXMueE8ucHVzaChlKX10aGlzLlZPKCl9LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUucmVtb3ZlU3RyZWFtPWZ1bmN0aW9uKHQpe3ZhciBlPXRoaXMueE8uaW5kZXhPZih0KTtlPi0xJiYodGhpcy54Ty5zcGxpY2UoZSwxKSx0aGlzLlZPKCkpfSx3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldFNlbmRlcnM9ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5MTy5maWx0ZXIoZnVuY3Rpb24odCl7cmV0dXJuISF0LnRJfSkubWFwKGZ1bmN0aW9uKHQpe3JldHVybiB0LnRJfSl9LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0UmVjZWl2ZXJzPWZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuTE8uZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVybiEhdC5lSX0pLm1hcChmdW5jdGlvbih0KXtyZXR1cm4gdC5lSX0pfSx3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLlFPPWZ1bmN0aW9uKHQsZSl7dmFyIGk9e05FOltdLHhFOltdLEJFOltdfSxyPWZ1bmN0aW9uKHQsZSl7dD1wYXJzZUludCh0LDEwKTtmb3IodmFyIGk9MDtpPGUubGVuZ3RoO2krKylpZihlW2ldLm9FPT09dHx8ZVtpXS5oRT09PXQpcmV0dXJuIGVbaV19LG49ZnVuY3Rpb24odCxlLGksbil7dmFyIG89cih0LnBhcmFtZXRlcnMuYXB0LGkpLHM9cihlLnBhcmFtZXRlcnMuYXB0LG4pO3JldHVybiBvJiZzJiZvLm5hbWUudG9Mb3dlckNhc2UoKT09PXMubmFtZS50b0xvd2VyQ2FzZSgpfTtyZXR1cm4gdC5ORS5mb3JFYWNoKGZ1bmN0aW9uKHIpe2Zvcih2YXIgbz0wO288ZS5ORS5sZW5ndGg7bysrKXt2YXIgcz1lLk5FW29dO2lmKHIubmFtZS50b0xvd2VyQ2FzZSgpPT09cy5uYW1lLnRvTG93ZXJDYXNlKCkmJnIuc0U9PT1zLnNFKXtpZihcInJ0eFwiPT09ci5uYW1lLnRvTG93ZXJDYXNlKCkmJnIucGFyYW1ldGVycyYmcy5wYXJhbWV0ZXJzLmFwdCYmIW4ocixzLHQuTkUsZS5ORSkpY29udGludWU7cz1KU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHMpKSxzLmFFPU1hdGgubWluKHIuYUUscy5hRSksaS5ORS5wdXNoKHMpLHMueUU9cy55RS5maWx0ZXIoZnVuY3Rpb24odCl7Zm9yKHZhciBlPTA7ZTxyLnlFLmxlbmd0aDtlKyspaWYoci55RVtlXS50eXBlPT09dC50eXBlJiZyLnlFW2VdLmdFPT09dC5nRSlyZXR1cm4hMDtyZXR1cm4hMX0pO2JyZWFrfX19KSx0LnhFLmZvckVhY2goZnVuY3Rpb24odCl7Zm9yKHZhciByPTA7cjxlLnhFLmxlbmd0aDtyKyspe3ZhciBuPWUueEVbcl07aWYodC51cmk9PT1uLnVyaSl7aS54RS5wdXNoKG4pO2JyZWFrfX19KSxpfSx3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLnFPPWZ1bmN0aW9uKHQsZSl7dmFyIGk9dGhpcyxyPW5ldyBSVENJY2VHYXRoZXJlcihpLkZPKSxuPW5ldyBSVENJY2VUcmFuc3BvcnQocik7ci5KTz1mdW5jdGlvbihzKXt2YXIgYT1uZXcgRXZlbnQoXCJpY2VjYW5kaWRhdGVcIik7YS5jYW5kaWRhdGU9e3NkcE1pZDp0LHNkcE1MaW5lSW5kZXg6ZX07dmFyIGM9cy5jYW5kaWRhdGUsaD0hY3x8MD09PU9iamVjdC5rZXlzKGMpLmxlbmd0aDtoP3ZvaWQgMD09PXIuc3RhdGUmJihyLnN0YXRlPVwiY29tcGxldGVkXCIpOihjLiRiPVwiUlRDUFwiPT09bi4kYj8yOjEsYS5jYW5kaWRhdGUuY2FuZGlkYXRlPW8uaUUoYykpO3ZhciBwPW8uS2IoaS5sb2NhbERlc2NyaXB0aW9uLnNkcCk7aD9wW2EuY2FuZGlkYXRlLnNkcE1MaW5lSW5kZXgrMV0rPVwiYT1lbmQtb2YtY2FuZGlkYXRlc1xcclxcblwiOnBbYS5jYW5kaWRhdGUuc2RwTUxpbmVJbmRleCsxXSs9XCJhPVwiK2EuY2FuZGlkYXRlLmNhbmRpZGF0ZStcIlxcclxcblwiLGkubG9jYWxEZXNjcmlwdGlvbi5zZHA9cC5qb2luKFwiXCIpO3ZhciB1PWkuS08/aS5LTzppLkxPLGw9dS5ldmVyeShmdW5jdGlvbih0KXtyZXR1cm4gdC5ZRSYmXCJjb21wbGV0ZWRcIj09PXQuWUUuc3RhdGV9KTtzd2l0Y2goaS5pY2VHYXRoZXJpbmdTdGF0ZSl7Y2FzZVwibmV3XCI6aHx8aS5NTy5wdXNoKGEpLGgmJmwmJmkuTU8ucHVzaChuZXcgRXZlbnQoXCJpY2VjYW5kaWRhdGVcIikpO2JyZWFrO2Nhc2VcImdhdGhlcmluZ1wiOmkuVU8oKSxofHwoaS5kaXNwYXRjaEV2ZW50KGEpLG51bGwhPT1pLm9uaWNlY2FuZGlkYXRlJiZpLm9uaWNlY2FuZGlkYXRlKGEpKSxsJiYoaS5kaXNwYXRjaEV2ZW50KG5ldyBFdmVudChcImljZWNhbmRpZGF0ZVwiKSksbnVsbCE9PWkub25pY2VjYW5kaWRhdGUmJmkub25pY2VjYW5kaWRhdGUobmV3IEV2ZW50KFwiaWNlY2FuZGlkYXRlXCIpKSxpLmljZUdhdGhlcmluZ1N0YXRlPVwiY29tcGxldGVcIixpLmpPKCkpO2JyZWFrO2Nhc2VcImNvbXBsZXRlXCI6fX0sbi5HTz1mdW5jdGlvbigpe2kuek8oKX07dmFyIHM9bmV3IFJUQ0R0bHNUcmFuc3BvcnQobik7cmV0dXJuIHMuV089ZnVuY3Rpb24oKXtpLnpPKCl9LHMub25lcnJvcj1mdW5jdGlvbigpe3Muc3RhdGU9XCJmYWlsZWRcIixpLnpPKCl9LHtZRTpyLCRPOm4sWEU6c319LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuWU89ZnVuY3Rpb24odCxlLGkpe3ZhciByPXRoaXMuUU8odC5YTyx0LlpPKTtlJiZ0LnRJJiYoci50UD10LmlJLHIuRkU9e3FFOm8ucWJ9LHQuZVAubGVuZ3RoJiYoci5GRS53RT10LmVQWzBdLndFKSx0LnRJLnNlbmQocikpLGkmJnQuZUkmJihcInZpZGVvXCI9PT10LmtpbmQmJnQuZVAmJnMudmVyc2lvbjwxNTAxOSYmdC5lUC5mb3JFYWNoKGZ1bmN0aW9uKHQpe2RlbGV0ZSB0Lk1FfSksci50UD10LmVQLHIuRkU9e3FFOnQucUV9LHQuaUkubGVuZ3RoJiYoci5GRS53RT10LmlJWzBdLndFKSx0LmVJLnJlY2VpdmUocikpfSx3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLnNldExvY2FsRGVzY3JpcHRpb249ZnVuY3Rpb24odCl7dmFyIGUsaSxyPXRoaXM7aWYoXCJvZmZlclwiPT09dC50eXBlKXRoaXMuS08mJihlPW8uS2IodC5zZHApLGk9ZS5zaGlmdCgpLGUuZm9yRWFjaChmdW5jdGlvbih0LGUpe3ZhciBpPW8uQUUodCk7ci5LT1tlXS5YTz1pfSksdGhpcy5MTz10aGlzLktPLGRlbGV0ZSB0aGlzLktPKTtlbHNlIGlmKFwiYW5zd2VyXCI9PT10LnR5cGUpe2U9by5LYihyLnJlbW90ZURlc2NyaXB0aW9uLnNkcCksaT1lLnNoaWZ0KCk7dmFyIG49by5HYihpLFwiYT1pY2UtbGl0ZVwiKS5sZW5ndGg+MDtlLmZvckVhY2goZnVuY3Rpb24odCxlKXt2YXIgcz1yLkxPW2VdLGE9cy5ZRSxjPXMuJE8saD1zLlhFLHA9cy5YTyx1PXMuWk8sbD1cIjBcIj09PXQuc3BsaXQoXCJcXG5cIiwxKVswXS5zcGxpdChcIiBcIiwyKVsxXTtpZighbCYmIXMuaVApe3ZhciBkPW8uQ0UodCxpKSxmPW8uRUUodCxpKTtuJiYoZi5JRT1cInNlcnZlclwiKSxyLkRPJiYwIT09ZXx8KGMuc3RhcnQoYSxkLG4/XCJjb250cm9sbGluZ1wiOlwiY29udHJvbGxlZFwiKSxoLnN0YXJ0KGYpKTt2YXIgZz1yLlFPKHAsdSk7ci5ZTyhzLGcuTkUubGVuZ3RoPjAsITEpfX0pfXN3aXRjaCh0aGlzLmxvY2FsRGVzY3JpcHRpb249e3R5cGU6dC50eXBlLHNkcDp0LnNkcH0sdC50eXBlKXtjYXNlXCJvZmZlclwiOnRoaXMuclAoXCJoYXZlLWxvY2FsLW9mZmVyXCIpO2JyZWFrO2Nhc2VcImFuc3dlclwiOnRoaXMuclAoXCJzdGFibGVcIik7YnJlYWs7ZGVmYXVsdDp0aHJvdyBuZXcgVHlwZUVycm9yKCd1bnN1cHBvcnRlZCB0eXBlIFwiJyt0LnR5cGUrJ1wiJyl9dmFyIHM9YXJndW1lbnRzLmxlbmd0aD4xJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBhcmd1bWVudHNbMV07aWYocyl7dmFyIGE9YXJndW1lbnRzWzFdO3dpbmRvdy5zZXRUaW1lb3V0KGZ1bmN0aW9uKCl7YSgpLFwibmV3XCI9PT1yLmljZUdhdGhlcmluZ1N0YXRlJiYoci5pY2VHYXRoZXJpbmdTdGF0ZT1cImdhdGhlcmluZ1wiLHIuak8oKSksci5VTygpfSwwKX12YXIgYz1Qcm9taXNlLnJlc29sdmUoKTtyZXR1cm4gYy50aGVuKGZ1bmN0aW9uKCl7c3x8KFwibmV3XCI9PT1yLmljZUdhdGhlcmluZ1N0YXRlJiYoci5pY2VHYXRoZXJpbmdTdGF0ZT1cImdhdGhlcmluZ1wiLHIuak8oKSksd2luZG93LnNldFRpbWVvdXQoci5VTy5iaW5kKHIpLDUwMCkpfSksY30sd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5zZXRSZW1vdGVEZXNjcmlwdGlvbj1mdW5jdGlvbih0KXt2YXIgZT10aGlzLGk9bmV3IE1lZGlhU3RyZWFtLHI9W10sbj1vLktiKHQuc2RwKSxhPW4uc2hpZnQoKSxjPW8uR2IoYSxcImE9aWNlLWxpdGVcIikubGVuZ3RoPjA7c3dpdGNoKHRoaXMuRE89by5HYihhLFwiYT1ncm91cDpCVU5ETEUgXCIpLmxlbmd0aD4wLG4uZm9yRWFjaChmdW5jdGlvbihuLGgpe3ZhciBwPW8uSmIobiksdT1wWzBdLnN1YnN0cigyKS5zcGxpdChcIiBcIiksbD11WzBdLGQ9XCIwXCI9PT11WzFdLGY9by5ySShuLGEpLGc9by5HYihuLFwiYT1taWQ6XCIpO2lmKGc9Zy5sZW5ndGg/Z1swXS5zdWJzdHIoNik6by5RYigpLFwiYXBwbGljYXRpb25cIj09PWwmJlwiRFRMUy9TQ1RQXCI9PT11WzJdKXJldHVybiB2b2lkKGUuTE9baF09e1pFOmcsaVA6ITB9KTt2YXIgdix5LG0sdyxULFMsYixFLEksUixrLEMsTz1vLkFFKG4pO2R8fChrPW8uQ0UobixhKSxDPW8uRUUobixhKSxDLklFPVwiY2xpZW50XCIpLEU9by5IRShuKTt2YXIgUCxBPW8uR2IobixcImE9c3NyYzpcIikubWFwKGZ1bmN0aW9uKHQpe3JldHVybiBvLm1FKHQpfSkuZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVyblwiY25hbWVcIj09PXQuVEV9KVswXTtBJiYoUD1BLnZhbHVlKTt2YXIgTj1vLkdiKG4sXCJhPWVuZC1vZi1jYW5kaWRhdGVzXCIsYSkubGVuZ3RoPjAseD1vLkdiKG4sXCJhPWNhbmRpZGF0ZTpcIikubWFwKGZ1bmN0aW9uKHQpe3JldHVybiBvLnpiKHQpfSkuZmlsdGVyKGZ1bmN0aW9uKHQpe3JldHVyblwiMVwiPT09dC4kYn0pO2lmKFwib2ZmZXJcIiE9PXQudHlwZXx8ZClcImFuc3dlclwiIT09dC50eXBlfHxkfHwodj1lLkxPW2hdLHk9di5ZRSxtPXYuJE8sdz12LlhFLFQ9di50SSxTPXYuZUksYj12LmlJLEk9di5YTyxlLkxPW2hdLmVQPUUsZS5MT1toXS5aTz1PLGUuTE9baF0ucUU9UCwoY3x8TikmJngubGVuZ3RoJiZtLnNldFJlbW90ZUNhbmRpZGF0ZXMoeCksZS5ETyYmMCE9PWh8fChtLnN0YXJ0KHksayxcImNvbnRyb2xsaW5nXCIpLHcuc3RhcnQoQykpLGUuWU8odixcInNlbmRyZWN2XCI9PT1mfHxcInJlY3Zvbmx5XCI9PT1mLFwic2VuZHJlY3ZcIj09PWZ8fFwic2VuZG9ubHlcIj09PWYpLCFTfHxcInNlbmRyZWN2XCIhPT1mJiZcInNlbmRvbmx5XCIhPT1mP2RlbGV0ZSB2LmVJOihSPVMudHJhY2ssci5wdXNoKFtSLFNdKSxpLmFkZFRyYWNrKFIpKSk7ZWxzZXt2YXIgQj1lLkRPJiZoPjA/e1lFOmUuTE9bMF0uWUUsJE86ZS5MT1swXS4kTyxYRTplLkxPWzBdLlhFfTplLnFPKGcsaCk7aWYoIU58fGUuRE8mJjAhPT1ofHxCLiRPLnNldFJlbW90ZUNhbmRpZGF0ZXMoeCksST1SVENSdHBSZWNlaXZlci5nZXRDYXBhYmlsaXRpZXMobCkscy52ZXJzaW9uPDE1MDE5JiYoSS5ORT1JLk5FLmZpbHRlcihmdW5jdGlvbih0KXtyZXR1cm5cInJ0eFwiIT09dC5uYW1lfSkpLGI9W3t3RToxMDAxKigyKmgrMil9XSxcInNlbmRyZWN2XCIhPT1mJiZcInNlbmRvbmx5XCIhPT1mfHwoUz1uZXcgUlRDUnRwUmVjZWl2ZXIoQi5YRSxsKSxSPVMudHJhY2ssci5wdXNoKFtSLFNdKSxpLmFkZFRyYWNrKFIpKSxlLnhPLmxlbmd0aD4wJiZlLnhPWzBdLmdldFRyYWNrcygpLmxlbmd0aD49aCl7dmFyIEY7XCJhdWRpb1wiPT09bD9GPWUueE9bMF0uZ2V0QXVkaW9UcmFja3MoKVswXTpcInZpZGVvXCI9PT1sJiYoRj1lLnhPWzBdLmdldFZpZGVvVHJhY2tzKClbMF0pLEYmJihzLnZlcnNpb24+PTE1MDE5JiZcInZpZGVvXCI9PT1sJiYoYlswXS5NRT17d0U6MTAwMSooMipoKzIpKzF9KSxUPW5ldyBSVENSdHBTZW5kZXIoRixCLlhFKSl9ZS5MT1toXT17WUU6Qi5ZRSwkTzpCLiRPLFhFOkIuWEUsWE86SSxaTzpPLHRJOlQsZUk6UyxraW5kOmwsWkU6ZyxxRTpQLGlJOmIsZVA6RX0sZS5ZTyhlLkxPW2hdLCExLFwic2VuZHJlY3ZcIj09PWZ8fFwic2VuZG9ubHlcIj09PWYpfX0pLHRoaXMucmVtb3RlRGVzY3JpcHRpb249e3R5cGU6dC50eXBlLHNkcDp0LnNkcH0sdC50eXBlKXtjYXNlXCJvZmZlclwiOnRoaXMuclAoXCJoYXZlLXJlbW90ZS1vZmZlclwiKTticmVhaztjYXNlXCJhbnN3ZXJcIjp0aGlzLnJQKFwic3RhYmxlXCIpO2JyZWFrO2RlZmF1bHQ6dGhyb3cgbmV3IFR5cGVFcnJvcigndW5zdXBwb3J0ZWQgdHlwZSBcIicrdC50eXBlKydcIicpfXJldHVybiBpLmdldFRyYWNrcygpLmxlbmd0aCYmKGUuQk8ucHVzaChpKSx3aW5kb3cuc2V0VGltZW91dChmdW5jdGlvbigpe3ZhciB0PW5ldyBFdmVudChcImFkZHN0cmVhbVwiKTt0LnN0cmVhbT1pLGUuZGlzcGF0Y2hFdmVudCh0KSxudWxsIT09ZS5vbmFkZHN0cmVhbSYmd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKXtlLm9uYWRkc3RyZWFtKHQpfSwwKSxyLmZvckVhY2goZnVuY3Rpb24odCl7dmFyIHI9dFswXSxuPXRbMV0sbz1uZXcgRXZlbnQoXCJ0cmFja1wiKTtvLnRyYWNrPXIsby5yZWNlaXZlcj1uLG8uc089W2ldLGUuZGlzcGF0Y2hFdmVudChvKSxudWxsIT09ZS5BTyYmd2luZG93LnNldFRpbWVvdXQoZnVuY3Rpb24oKXtlLkFPKG8pfSwwKX0pfSwwKSksYXJndW1lbnRzLmxlbmd0aD4xJiZcImZ1bmN0aW9uXCI9PXR5cGVvZiBhcmd1bWVudHNbMV0mJndpbmRvdy5zZXRUaW1lb3V0KGFyZ3VtZW50c1sxXSwwKSxQcm9taXNlLnJlc29sdmUoKX0sd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5jbG9zZT1mdW5jdGlvbigpe3RoaXMuTE8uZm9yRWFjaChmdW5jdGlvbih0KXt0LiRPJiZ0LiRPLnN0b3AoKSx0LlhFJiZ0LlhFLnN0b3AoKSx0LnRJJiZ0LnRJLnN0b3AoKSx0LmVJJiZ0LmVJLnN0b3AoKX0pLHRoaXMuclAoXCJjbG9zZWRcIil9LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuclA9ZnVuY3Rpb24odCl7dGhpcy5zaWduYWxpbmdTdGF0ZT10O3ZhciBlPW5ldyBFdmVudChcInNpZ25hbGluZ3N0YXRlY2hhbmdlXCIpO3RoaXMuZGlzcGF0Y2hFdmVudChlKSxudWxsIT09dGhpcy5vbnNpZ25hbGluZ3N0YXRlY2hhbmdlJiZ0aGlzLm9uc2lnbmFsaW5nc3RhdGVjaGFuZ2UoZSl9LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuVk89ZnVuY3Rpb24oKXt2YXIgdD1uZXcgRXZlbnQoXCJuZWdvdGlhdGlvbm5lZWRlZFwiKTt0aGlzLmRpc3BhdGNoRXZlbnQodCksbnVsbCE9PXRoaXMub25uZWdvdGlhdGlvbm5lZWRlZCYmdGhpcy5vbm5lZ290aWF0aW9ubmVlZGVkKHQpfSx3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLnpPPWZ1bmN0aW9uKCl7dmFyIHQsZT10aGlzLGk9e25QOjAsY2xvc2VkOjAsb1A6MCxzUDowLGNvbm5lY3RlZDowLGFQOjAsX2k6MH07aWYodGhpcy5MTy5mb3JFYWNoKGZ1bmN0aW9uKHQpe2lbdC4kTy5zdGF0ZV0rKyxpW3QuWEUuc3RhdGVdKyt9KSxpLmNvbm5lY3RlZCs9aS5hUCx0PVwibmV3XCIsaS5faT4wP3Q9XCJmYWlsZWRcIjppLm9QPjB8fGkuc1A+MD90PVwiY29ubmVjdGluZ1wiOmkuZGlzY29ubmVjdGVkPjA/dD1cImRpc2Nvbm5lY3RlZFwiOmlbXCJuUFwiXT4wP3Q9XCJuZXdcIjooaS5jb25uZWN0ZWQ+MHx8aS5hUD4wKSYmKHQ9XCJjb25uZWN0ZWRcIiksdCE9PWUuaWNlQ29ubmVjdGlvblN0YXRlKXtlLmljZUNvbm5lY3Rpb25TdGF0ZT10O3ZhciByPW5ldyBFdmVudChcImljZWNvbm5lY3Rpb25zdGF0ZWNoYW5nZVwiKTt0aGlzLmRpc3BhdGNoRXZlbnQociksbnVsbCE9PXRoaXMub25pY2Vjb25uZWN0aW9uc3RhdGVjaGFuZ2UmJnRoaXMub25pY2Vjb25uZWN0aW9uc3RhdGVjaGFuZ2Uocil9fSx3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmNyZWF0ZU9mZmVyPWZ1bmN0aW9uKCl7dmFyIHQ9dGhpcztpZih0aGlzLktPKXRocm93IG5ldyBFcnJvcihcImNyZWF0ZU9mZmVyIGNhbGxlZCB3aGlsZSB0aGVyZSBpcyBhIHBlbmRpbmcgb2ZmZXIuXCIpO3ZhciBlOzE9PT1hcmd1bWVudHMubGVuZ3RoJiZcImZ1bmN0aW9uXCIhPXR5cGVvZiBhcmd1bWVudHNbMF0/ZT1hcmd1bWVudHNbMF06Mz09PWFyZ3VtZW50cy5sZW5ndGgmJihlPWFyZ3VtZW50c1syXSk7dmFyIGk9W10sbj0wLGE9MDtpZih0aGlzLnhPLmxlbmd0aCYmKG49dGhpcy54T1swXS5nZXRBdWRpb1RyYWNrcygpLmxlbmd0aCxhPXRoaXMueE9bMF0uZ2V0VmlkZW9UcmFja3MoKS5sZW5ndGgpLGUpe2lmKGUuZ098fGUub3B0aW9uYWwpdGhyb3cgbmV3IFR5cGVFcnJvcihcIkxlZ2FjeSBtYW5kYXRvcnkvb3B0aW9uYWwgY29uc3RyYWludHMgbm90IHN1cHBvcnRlZC5cIik7dm9pZCAwIT09ZS5jUCYmKG49ZS5jUCksdm9pZCAwIT09ZS5oUCYmKGE9ZS5oUCl9Zm9yKHRoaXMueE8ubGVuZ3RoJiZ0aGlzLnhPWzBdLmdldFRyYWNrcygpLmZvckVhY2goZnVuY3Rpb24odCl7aS5wdXNoKHtraW5kOnQua2luZCx0cmFjazp0LHBQOlwiYXVkaW9cIj09PXQua2luZD9uPjA6YT4wfSksXCJhdWRpb1wiPT09dC5raW5kP24tLTpcInZpZGVvXCI9PT10LmtpbmQmJmEtLX0pO24+MHx8YT4wOyluPjAmJihpLnB1c2goe2tpbmQ6XCJhdWRpb1wiLHBQOiEwfSksbi0tKSxhPjAmJihpLnB1c2goe2tpbmQ6XCJ2aWRlb1wiLHBQOiEwfSksYS0tKTtpPXIoaSk7dmFyIGM9by5XRSgpLGg9W107aS5mb3JFYWNoKGZ1bmN0aW9uKGUsaSl7dmFyIHI9ZS50cmFjayxuPWUua2luZCxhPW8uUWIoKSxjPXQuRE8mJmk+MD97WUU6aFswXS5ZRSwkTzpoWzBdLiRPLFhFOmhbMF0uWEV9OnQucU8oYSxpKSxwPVJUQ1J0cFNlbmRlci5nZXRDYXBhYmlsaXRpZXMobik7cy52ZXJzaW9uPDE1MDE5JiYocC5ORT1wLk5FLmZpbHRlcihmdW5jdGlvbih0KXtyZXR1cm5cInJ0eFwiIT09dC5uYW1lfSkpLHAuTkUuZm9yRWFjaChmdW5jdGlvbih0KXtcIkgyNjRcIj09PXQubmFtZSYmdm9pZCAwPT09dC5wYXJhbWV0ZXJzW1widVBcIl0mJih0LnBhcmFtZXRlcnNbXCJ1UFwiXT1cIjFcIil9KTt2YXIgdSxsLGQ9W3t3RToxMDAxKigyKmkrMSl9XTtyJiYocy52ZXJzaW9uPj0xNTAxOSYmXCJ2aWRlb1wiPT09biYmKGRbMF0uTUU9e3dFOjEwMDEqKDIqaSsxKSsxfSksdT1uZXcgUlRDUnRwU2VuZGVyKHIsYy5YRSkpLGUucFAmJihsPW5ldyBSVENSdHBSZWNlaXZlcihjLlhFLG4pKSxoW2ldPXtZRTpjLllFLCRPOmMuJE8sWEU6Yy5YRSxYTzpwLFpPOm51bGwsdEk6dSxlSTpsLGtpbmQ6bixaRTphLGlJOmQsZVA6bnVsbH19KSx0aGlzLkRPJiYoYys9XCJhPWdyb3VwOkJVTkRMRSBcIitoLm1hcChmdW5jdGlvbih0KXtyZXR1cm4gdC5aRX0pLmpvaW4oXCIgXCIpK1wiXFxyXFxuXCIpLGkuZm9yRWFjaChmdW5jdGlvbihlLGkpe3ZhciByPWhbaV07Yys9by4kRShyLHIuWE8sXCJvZmZlclwiLHQueE9bMF0pfSksdGhpcy5LTz1oO3ZhciBwPW5ldyBSVENTZXNzaW9uRGVzY3JpcHRpb24oe3R5cGU6XCJvZmZlclwiLHNkcDpjfSk7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGgmJlwiZnVuY3Rpb25cIj09dHlwZW9mIGFyZ3VtZW50c1swXSYmd2luZG93LnNldFRpbWVvdXQoYXJndW1lbnRzWzBdLDAscCksUHJvbWlzZS5yZXNvbHZlKHApfSx3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmNyZWF0ZUFuc3dlcj1mdW5jdGlvbigpe3ZhciB0PXRoaXMsZT1vLldFKCk7dGhpcy5ETyYmKGUrPVwiYT1ncm91cDpCVU5ETEUgXCIrdGhpcy5MTy5tYXAoZnVuY3Rpb24odCl7cmV0dXJuIHQuWkV9KS5qb2luKFwiIFwiKStcIlxcclxcblwiKSx0aGlzLkxPLmZvckVhY2goZnVuY3Rpb24oaSl7aWYoaS5pUClyZXR1cm4gdm9pZChlKz1cIm09YXBwbGljYXRpb24gMCBEVExTL1NDVFAgNTAwMFxcclxcbmM9SU4gSVA0IDAuMC4wLjBcXHJcXG5hPW1pZDpcIitpLlpFK1wiXFxyXFxuXCIpO3ZhciByPXQuUU8oaS5YTyxpLlpPKTtlKz1vLiRFKGkscixcImFuc3dlclwiLHQueE9bMF0pfSk7dmFyIGk9bmV3IFJUQ1Nlc3Npb25EZXNjcmlwdGlvbih7dHlwZTpcImFuc3dlclwiLHNkcDplfSk7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGgmJlwiZnVuY3Rpb25cIj09dHlwZW9mIGFyZ3VtZW50c1swXSYmd2luZG93LnNldFRpbWVvdXQoYXJndW1lbnRzWzBdLDAsaSksUHJvbWlzZS5yZXNvbHZlKGkpfSx3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmFkZEljZUNhbmRpZGF0ZT1mdW5jdGlvbih0KXtpZih0KXt2YXIgZT10LnNkcE1MaW5lSW5kZXg7aWYodC5zZHBNaWQpZm9yKHZhciBpPTA7aTx0aGlzLkxPLmxlbmd0aDtpKyspaWYodGhpcy5MT1tpXS5aRT09PXQuc2RwTWlkKXtlPWk7YnJlYWt9dmFyIHI9dGhpcy5MT1tlXTtpZihyKXt2YXIgbj1PYmplY3Qua2V5cyh0LmNhbmRpZGF0ZSkubGVuZ3RoPjA/by56Yih0LmNhbmRpZGF0ZSk6e307aWYoXCJ0Y3BcIj09PW4ucHJvdG9jb2wmJigwPT09bi5wb3J0fHw5PT09bi5wb3J0KSlyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7aWYoXCIxXCIhPT1uLiRiKXJldHVybiBQcm9taXNlLnJlc29sdmUoKTtyLiRPLmFkZFJlbW90ZUNhbmRpZGF0ZShuKTt2YXIgcz1vLktiKHRoaXMucmVtb3RlRGVzY3JpcHRpb24uc2RwKTtzW2UrMV0rPShuLnR5cGU/dC5jYW5kaWRhdGUudHJpbSgpOlwiYT1lbmQtb2YtY2FuZGlkYXRlc1wiKStcIlxcclxcblwiLHRoaXMucmVtb3RlRGVzY3JpcHRpb24uc2RwPXMuam9pbihcIlwiKX19ZWxzZSBmb3IodmFyIGE9MDthPHRoaXMuTE8ubGVuZ3RoO2ErKylpZih0aGlzLkxPW2FdLiRPLmFkZFJlbW90ZUNhbmRpZGF0ZSh7fSksdGhpcy5ETylyZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGg+MSYmXCJmdW5jdGlvblwiPT10eXBlb2YgYXJndW1lbnRzWzFdJiZ3aW5kb3cuc2V0VGltZW91dChhcmd1bWVudHNbMV0sMCksUHJvbWlzZS5yZXNvbHZlKCl9LHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0U3RhdHM9ZnVuY3Rpb24oKXt2YXIgdD1bXTt0aGlzLkxPLmZvckVhY2goZnVuY3Rpb24oZSl7W1wicnRwU2VuZGVyXCIsXCJydHBSZWNlaXZlclwiLFwiaWNlR2F0aGVyZXJcIixcImljZVRyYW5zcG9ydFwiLFwiZHRsc1RyYW5zcG9ydFwiXS5mb3JFYWNoKGZ1bmN0aW9uKGkpe2VbaV0mJnQucHVzaChlW2ldLmdldFN0YXRzKCkpfSl9KTt2YXIgZT1hcmd1bWVudHMubGVuZ3RoPjEmJlwiZnVuY3Rpb25cIj09dHlwZW9mIGFyZ3VtZW50c1sxXSYmYXJndW1lbnRzWzFdLGk9ZnVuY3Rpb24odCl7cmV0dXJue2xQOlwiaW5ib3VuZC1ydHBcIixkUDpcIm91dGJvdW5kLXJ0cFwiLGZQOlwiY2FuZGlkYXRlLXBhaXJcIixkTzpcImxvY2FsLWNhbmRpZGF0ZVwiLGZPOlwicmVtb3RlLWNhbmRpZGF0ZVwifVt0LnR5cGVdfHx0LnR5cGV9O3JldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihyKXt2YXIgbj1uZXcgTWFwO1Byb21pc2UuYWxsKHQpLnRoZW4oZnVuY3Rpb24odCl7dC5mb3JFYWNoKGZ1bmN0aW9uKHQpe09iamVjdC5rZXlzKHQpLmZvckVhY2goZnVuY3Rpb24oZSl7dFtlXS50eXBlPWkodFtlXSksbi5zZXQoZSx0W2VdKX0pfSksZSYmd2luZG93LnNldFRpbWVvdXQoZSwwLG4pLHIobil9KX0pfX19O3QudD17WEM6YS5YQyxaQzppKDY5KX19LGZ1bmN0aW9uKHQsZSl7XCJ1c2Ugc3RyaWN0XCI7dC50PWZ1bmN0aW9uKCl7dmFyIHQ9ZnVuY3Rpb24odCl7cmV0dXJue25hbWU6e0VPOlwiTm90QWxsb3dlZEVycm9yXCJ9W3QubmFtZV18fHQubmFtZSxtZXNzYWdlOnQubWVzc2FnZSxSTzp0LlJPLHRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMubmFtZX19fSxlPW5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhLmJpbmQobmF2aWdhdG9yLm1lZGlhRGV2aWNlcyk7bmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWE9ZnVuY3Rpb24oaSl7cmV0dXJuIGUoaSlbXCJjYXRjaFwiXShmdW5jdGlvbihlKXtyZXR1cm4gUHJvbWlzZS5yZWplY3QodChlKSl9KX19fSxmdW5jdGlvbih0LGUsaSl7XCJ1c2Ugc3RyaWN0XCI7dmFyIHI9aSgzKS5yaSxuPXtpTzpmdW5jdGlvbigpe1wib2JqZWN0XCIhPXR5cGVvZiB3aW5kb3d8fCF3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb258fFwib250cmFja1wiaW4gd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZXx8T2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUsXCJvbnRyYWNrXCIse2dldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLm5PfSxzZXQ6ZnVuY3Rpb24odCl7dGhpcy5uTyYmKHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcihcInRyYWNrXCIsdGhpcy5uTyksdGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKFwiYWRkc3RyZWFtXCIsdGhpcy5vTykpLHRoaXMuYWRkRXZlbnRMaXN0ZW5lcihcInRyYWNrXCIsdGhpcy5uTz10KSx0aGlzLmFkZEV2ZW50TGlzdGVuZXIoXCJhZGRzdHJlYW1cIix0aGlzLm9PPWZ1bmN0aW9uKHQpe3Quc3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goZnVuY3Rpb24oZSl7dmFyIGk9bmV3IEV2ZW50KFwidHJhY2tcIik7aS50cmFjaz1lLGkucmVjZWl2ZXI9e3RyYWNrOmV9LGkuc089W3Quc3RyZWFtXSx0aGlzLmRpc3BhdGNoRXZlbnQoaSl9LmJpbmQodGhpcykpfS5iaW5kKHRoaXMpKX19KX0sZU86ZnVuY3Rpb24oKXtcIm9iamVjdFwiPT10eXBlb2Ygd2luZG93JiYoIXdpbmRvdy5IVE1MTWVkaWFFbGVtZW50fHxcInNyY09iamVjdFwiaW4gd2luZG93LkhUTUxNZWRpYUVsZW1lbnQucHJvdG90eXBlfHxPYmplY3QuZGVmaW5lUHJvcGVydHkod2luZG93LkhUTUxNZWRpYUVsZW1lbnQucHJvdG90eXBlLFwic3JjT2JqZWN0XCIse2dldDpmdW5jdGlvbigpe3JldHVybiB0aGlzLm1velNyY09iamVjdH0sc2V0OmZ1bmN0aW9uKHQpe3RoaXMubW96U3JjT2JqZWN0PXR9fSkpfSxYQzpmdW5jdGlvbigpe2lmKFwib2JqZWN0XCI9PXR5cGVvZiB3aW5kb3cmJih3aW5kb3cuUlRDUGVlckNvbm5lY3Rpb258fHdpbmRvdy5tb3pSVENQZWVyQ29ubmVjdGlvbikpe3dpbmRvdy5SVENQZWVyQ29ubmVjdGlvbnx8KHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbj1mdW5jdGlvbih0LGUpe2lmKHIudmVyc2lvbjwzOCYmdCYmdC5pY2VTZXJ2ZXJzKXtmb3IodmFyIGk9W10sbj0wO248dC5pY2VTZXJ2ZXJzLmxlbmd0aDtuKyspe3ZhciBvPXQuaWNlU2VydmVyc1tuXTtpZihvLmhhc093blByb3BlcnR5KFwidXJsc1wiKSlmb3IodmFyIHM9MDtzPG8uUE8ubGVuZ3RoO3MrKyl7dmFyIGE9e3VybDpvLlBPW3NdfTswPT09by5QT1tzXS5pbmRleE9mKFwidHVyblwiKSYmKGEudXNlcm5hbWU9by51c2VybmFtZSxhLmdQPW8uZ1ApLGkucHVzaChhKX1lbHNlIGkucHVzaCh0LmljZVNlcnZlcnNbbl0pfXQuaWNlU2VydmVycz1pfXJldHVybiBuZXcgbW96UlRDUGVlckNvbm5lY3Rpb24odCxlKX0sd2luZG93LlJUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZT1tb3pSVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUsbW96UlRDUGVlckNvbm5lY3Rpb24uZ2VuZXJhdGVDZXJ0aWZpY2F0ZSYmT2JqZWN0LmRlZmluZVByb3BlcnR5KHdpbmRvdy5SVENQZWVyQ29ubmVjdGlvbixcImdlbmVyYXRlQ2VydGlmaWNhdGVcIix7Z2V0OmZ1bmN0aW9uKCl7cmV0dXJuIG1velJUQ1BlZXJDb25uZWN0aW9uLmdlbmVyYXRlQ2VydGlmaWNhdGV9fSksd2luZG93LlJUQ1Nlc3Npb25EZXNjcmlwdGlvbj1tb3pSVENTZXNzaW9uRGVzY3JpcHRpb24sd2luZG93LlJUQ0ljZUNhbmRpZGF0ZT1tb3pSVENJY2VDYW5kaWRhdGUpLFtcInNldExvY2FsRGVzY3JpcHRpb25cIixcInNldFJlbW90ZURlc2NyaXB0aW9uXCIsXCJhZGRJY2VDYW5kaWRhdGVcIl0uZm9yRWFjaChmdW5jdGlvbih0KXt2YXIgZT1SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGVbdF07UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlW3RdPWZ1bmN0aW9uKCl7cmV0dXJuIGFyZ3VtZW50c1swXT1uZXcoXCJhZGRJY2VDYW5kaWRhdGVcIj09PXQ/UlRDSWNlQ2FuZGlkYXRlOlJUQ1Nlc3Npb25EZXNjcmlwdGlvbikoYXJndW1lbnRzWzBdKSxlLmFwcGx5KHRoaXMsYXJndW1lbnRzKX19KTt2YXIgdD1SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuYWRkSWNlQ2FuZGlkYXRlO1JUQ1BlZXJDb25uZWN0aW9uLnByb3RvdHlwZS5hZGRJY2VDYW5kaWRhdGU9ZnVuY3Rpb24oKXtyZXR1cm4gYXJndW1lbnRzWzBdP3QuYXBwbHkodGhpcyxhcmd1bWVudHMpOihhcmd1bWVudHNbMV0mJmFyZ3VtZW50c1sxXS5hcHBseShudWxsKSxQcm9taXNlLnJlc29sdmUoKSl9O3ZhciBlPWZ1bmN0aW9uKHQpe3ZhciBlPW5ldyBNYXA7cmV0dXJuIE9iamVjdC5rZXlzKHQpLmZvckVhY2goZnVuY3Rpb24oaSl7ZS5zZXQoaSx0W2ldKSxlW2ldPXRbaV19KSxlfSxpPXtsUDpcImluYm91bmQtcnRwXCIsZFA6XCJvdXRib3VuZC1ydHBcIixmUDpcImNhbmRpZGF0ZS1wYWlyXCIsZE86XCJsb2NhbC1jYW5kaWRhdGVcIixmTzpcInJlbW90ZS1jYW5kaWRhdGVcIn0sbj1SVENQZWVyQ29ubmVjdGlvbi5wcm90b3R5cGUuZ2V0U3RhdHM7UlRDUGVlckNvbm5lY3Rpb24ucHJvdG90eXBlLmdldFN0YXRzPWZ1bmN0aW9uKHQsbyxzKXtyZXR1cm4gbi5hcHBseSh0aGlzLFt0fHxudWxsXSkudGhlbihmdW5jdGlvbih0KXtpZihyLnZlcnNpb248NDgmJih0PWUodCkpLHIudmVyc2lvbjw1MyYmIW8pdHJ5e3QuZm9yRWFjaChmdW5jdGlvbih0KXt0LnR5cGU9aVt0LnR5cGVdfHx0LnR5cGV9KX1jYXRjaChuKXtpZihcIlR5cGVFcnJvclwiIT09bi5uYW1lKXRocm93IG47dC5mb3JFYWNoKGZ1bmN0aW9uKGUscil7dC5zZXQocixPYmplY3QuYXNzaWduKHt9LGUse3R5cGU6aVtlLnR5cGVdfHxlLnR5cGV9KSl9KX1yZXR1cm4gdH0pLnRoZW4obyxzKX19fX07dC50PXtpTzpuLmlPLGVPOm4uZU8sWEM6bi5YQyxaQzppKDcxKX19LGZ1bmN0aW9uKHQsZSxpKXtcInVzZSBzdHJpY3RcIjt2YXIgcj1pKDMpLmxvZyxuPWkoMykucmk7dC50PWZ1bmN0aW9uKCl7dmFyIHQ9ZnVuY3Rpb24odCl7cmV0dXJue25hbWU6e3ZQOlwiTm90QWxsb3dlZEVycm9yXCIsRU86XCJOb3RBbGxvd2VkRXJyb3JcIn1bdC5uYW1lXXx8dC5uYW1lLG1lc3NhZ2U6e1wiVGhlIG9wZXJhdGlvbiBpcyBpbnNlY3VyZS5cIjpcIlRoZSByZXF1ZXN0IGlzIG5vdCBhbGxvd2VkIGJ5IHRoZSB1c2VyIGFnZW50IG9yIHRoZSBwbGF0Zm9ybSBpbiB0aGUgY3VycmVudCBjb250ZXh0LlwifVt0Lm1lc3NhZ2VdfHx0Lm1lc3NhZ2UsUk86dC5STyx0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiB0aGlzLm5hbWUrKHRoaXMubWVzc2FnZSYmXCI6IFwiKSt0aGlzLm1lc3NhZ2V9fX0sZT1mdW5jdGlvbihlLGksbyl7dmFyIHM9ZnVuY3Rpb24odCl7aWYoXCJvYmplY3RcIiE9dHlwZW9mIHR8fHQueVApcmV0dXJuIHQ7dmFyIGU9W107cmV0dXJuIE9iamVjdC5rZXlzKHQpLmZvckVhY2goZnVuY3Rpb24oaSl7aWYoXCJyZXF1aXJlXCIhPT1pJiZcImFkdmFuY2VkXCIhPT1pJiZcIm1lZGlhU291cmNlXCIhPT1pKXt2YXIgcj10W2ldPVwib2JqZWN0XCI9PXR5cGVvZiB0W2ldP3RbaV06e3ZPOnRbaV19O2lmKHZvaWQgMD09PXIubWluJiZ2b2lkIDA9PT1yLm1heCYmdm9pZCAwPT09ci55T3x8ZS5wdXNoKGkpLHZvaWQgMCE9PXIueU8mJihcIm51bWJlclwiPT10eXBlb2Ygci55Tz9yLm1pbj1yLm1heD1yLnlPOnRbaV09ci55TyxkZWxldGUgci55Tyksdm9pZCAwIT09ci52Tyl7dC5tTz10Lm1PfHxbXTt2YXIgbj17fTtcIm51bWJlclwiPT10eXBlb2Ygci52Tz9uW2ldPXttaW46ci52TyxtYXg6ci52T306bltpXT1yLnZPLHQubU8ucHVzaChuKSxkZWxldGUgci52TyxPYmplY3Qua2V5cyhyKS5sZW5ndGh8fGRlbGV0ZSB0W2ldfX19KSxlLmxlbmd0aCYmKHQueVA9ZSksdH07cmV0dXJuIGU9SlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShlKSksbi52ZXJzaW9uPDM4JiYocihcInNwZWM6IFwiK0pTT04uc3RyaW5naWZ5KGUpKSxlLk1wJiYoZS5NcD1zKGUuTXApKSxlLnZpZGVvJiYoZS52aWRlbz1zKGUudmlkZW8pKSxyKFwiZmYzNzogXCIrSlNPTi5zdHJpbmdpZnkoZSkpKSxuYXZpZ2F0b3IubW96R2V0VXNlck1lZGlhKGUsaSxmdW5jdGlvbihlKXtvKHQoZSkpfSl9LGk9ZnVuY3Rpb24odCl7cmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKGkscil7ZSh0LGkscil9KX07aWYobmF2aWdhdG9yLm1lZGlhRGV2aWNlc3x8KG5hdmlnYXRvci5tZWRpYURldmljZXM9e2dldFVzZXJNZWRpYTppLGFkZEV2ZW50TGlzdGVuZXI6ZnVuY3Rpb24oKXt9LHJlbW92ZUV2ZW50TGlzdGVuZXI6ZnVuY3Rpb24oKXt9fSksbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5TTz1uYXZpZ2F0b3IubWVkaWFEZXZpY2VzLlNPfHxmdW5jdGlvbigpe3JldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbih0KXt2YXIgZT1be2tpbmQ6XCJhdWRpb2lucHV0XCIsYk86XCJkZWZhdWx0XCIsbGFiZWw6XCJcIixrTzpcIlwifSx7a2luZDpcInZpZGVvaW5wdXRcIixiTzpcImRlZmF1bHRcIixsYWJlbDpcIlwiLGtPOlwiXCJ9XTt0KGUpfSl9LG4udmVyc2lvbjw0MSl7dmFyIG89bmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5TTy5iaW5kKG5hdmlnYXRvci5tZWRpYURldmljZXMpO25hdmlnYXRvci5tZWRpYURldmljZXMuU089ZnVuY3Rpb24oKXtyZXR1cm4gbygpLnRoZW4odm9pZCAwLGZ1bmN0aW9uKHQpe2lmKFwiTm90Rm91bmRFcnJvclwiPT09dC5uYW1lKXJldHVybltdO3Rocm93IHR9KX19aWYobi52ZXJzaW9uPDQ5KXt2YXIgcz1uYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYS5iaW5kKG5hdmlnYXRvci5tZWRpYURldmljZXMpO25hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhPWZ1bmN0aW9uKGUpe3JldHVybiBzKGUpLnRoZW4oZnVuY3Rpb24odCl7aWYoZS5NcCYmIXQuZ2V0QXVkaW9UcmFja3MoKS5sZW5ndGh8fGUudmlkZW8mJiF0LmdldFZpZGVvVHJhY2tzKCkubGVuZ3RoKXRocm93IHQuZ2V0VHJhY2tzKCkuZm9yRWFjaChmdW5jdGlvbih0KXt0LnN0b3AoKX0pLG5ldyBET01FeGNlcHRpb24oXCJUaGUgb2JqZWN0IGNhbiBub3QgYmUgZm91bmQgaGVyZS5cIixcIk5vdEZvdW5kRXJyb3JcIik7cmV0dXJuIHR9LGZ1bmN0aW9uKGUpe3JldHVybiBQcm9taXNlLnJlamVjdCh0KGUpKX0pfX1uYXZpZ2F0b3IuZ2V0VXNlck1lZGlhPWZ1bmN0aW9uKHQsaSxyKXtyZXR1cm4gbi52ZXJzaW9uPDQ0P2UodCxpLHIpOihjb25zb2xlLndhcm4oXCJuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhIGhhcyBiZWVuIHJlcGxhY2VkIGJ5IG5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhXCIpLHZvaWQgbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEodCkudGhlbihpLHIpKX19fSxmdW5jdGlvbih0LGUpe1widXNlIHN0cmljdFwiO3ZhciBpPXtaQzpmdW5jdGlvbigpe25hdmlnYXRvci5nZXRVc2VyTWVkaWF8fChuYXZpZ2F0b3Iud2Via2l0R2V0VXNlck1lZGlhP25hdmlnYXRvci5nZXRVc2VyTWVkaWE9bmF2aWdhdG9yLndlYmtpdEdldFVzZXJNZWRpYS5iaW5kKG5hdmlnYXRvcik6bmF2aWdhdG9yLm1lZGlhRGV2aWNlcyYmbmF2aWdhdG9yLm1lZGlhRGV2aWNlcy5nZXRVc2VyTWVkaWEmJihuYXZpZ2F0b3IuZ2V0VXNlck1lZGlhPWZ1bmN0aW9uKHQsZSxpKXtuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh0KS50aGVuKGUsaSl9LmJpbmQobmF2aWdhdG9yKSkpfX07dC50PXtaQzppLlpDfX1dKTtcblxuLy8jIHNvdXJjZU1hcHBpbmdVUkw9Yml0bW92aW4uaGl2ZS5taW4uanMubWFwXG5cblxuXG4vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIFdFQlBBQ0sgRk9PVEVSXG4vLyAuLi9saWIvaGl2ZS9iaXRtb3Zpbi5oaXZlLm1pbi5qc1xuLy8gbW9kdWxlIGlkID0gNDdcbi8vIG1vZHVsZSBjaHVua3MgPSAwIl0sInNvdXJjZVJvb3QiOiIifQ== \ No newline at end of file diff --git a/dist/mi-angular-bitdash-player.min.js b/dist/mi-angular-bitdash-player.min.js index 2b798de..6838174 100644 --- a/dist/mi-angular-bitdash-player.min.js +++ b/dist/mi-angular-bitdash-player.min.js @@ -1,4 +1,4 @@ -!function(t){function e(i){if(n[i])return n[i].exports;var r=n[i]={i:i,l:!1,exports:{}};return t[i].call(r.exports,r,r.exports,e),r.l=!0,r.exports}var n={};e.m=t,e.c=n,e.d=function(t,n,i){e.o(t,n)||Object.defineProperty(t,n,{configurable:!1,enumerable:!0,get:i})},e.n=function(t){var n=t&&t.__esModule?function(){return t.default}:function(){return t};return e.d(n,"a",n),n},e.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},e.p="",e(e.s=30)}([function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=function(){function t(t,e){if(this.document=document,t instanceof Array){if(t.length>0&&t[0]instanceof HTMLElement){var n=t;this.elements=n}}else if(t instanceof HTMLElement){var i=t;this.elements=[i]}else if(t instanceof Document)this.elements=null;else if(e){var r=t,i=document.createElement(r);for(var o in e){var s=e[o];i.setAttribute(o,s)}this.elements=[i]}else{var a=t;this.elements=this.findChildElements(a)}}return Object.defineProperty(t.prototype,"length",{get:function(){return this.elements?this.elements.length:0},enumerable:!0,configurable:!0}),t.prototype.getElements=function(){return this.get()},t.prototype.get=function(t){return void 0===t?this.elements:!this.elements||t>=this.elements.length||t<-this.elements.length?void 0:t<0?this.elements[this.elements.length-t]:this.elements[t]},t.prototype.forEach=function(t){this.elements&&this.elements.forEach(function(e){t(e)})},t.prototype.findChildElementsOfElement=function(t,e){var n=t.querySelectorAll(e);return[].slice.call(n)},t.prototype.findChildElements=function(t){var e=this,n=[];return this.elements?(this.forEach(function(i){n=n.concat(e.findChildElementsOfElement(i,t))}),n):this.findChildElementsOfElement(document,t)},t.prototype.find=function(e){return new t(this.findChildElements(e))},t.prototype.html=function(t){return arguments.length>0?this.setHtml(t):this.getHtml()},t.prototype.getHtml=function(){return this.elements[0].innerHTML},t.prototype.setHtml=function(t){return void 0!==t&&null!=t||(t=""),this.forEach(function(e){e.innerHTML=t}),this},t.prototype.empty=function(){return this.forEach(function(t){t.innerHTML=""}),this},t.prototype.val=function(){var t=this.elements[0];if(t instanceof HTMLSelectElement||t instanceof HTMLInputElement)return t.value;throw new Error("val() not supported for "+typeof t)},t.prototype.attr=function(t,e){return arguments.length>1?this.setAttr(t,e):this.getAttr(t)},t.prototype.getAttr=function(t){return this.elements[0].getAttribute(t)},t.prototype.setAttr=function(t,e){return this.forEach(function(n){n.setAttribute(t,e)}),this},t.prototype.data=function(t,e){return arguments.length>1?this.setData(t,e):this.getData(t)},t.prototype.getData=function(t){return this.elements[0].getAttribute("data-"+t)},t.prototype.setData=function(t,e){return this.forEach(function(n){n.setAttribute("data-"+t,e)}),this},t.prototype.append=function(){for(var t=[],e=0;ei.rateMs&&(i.fireSuper(t,e),i.lastFireTime=Date.now())},i}return i(e,t),e.prototype.fireSuper=function(e,n){t.prototype.fire.call(this,e,n)},e.prototype.fire=function(t,e){this.rateLimitingEventListener(t,e)},e}(s)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});!function(t){function e(t,e){var n=t.indexOf(e);return n>-1?t.splice(n,1)[0]:null}t.remove=e}(e.ArrayUtils||(e.ArrayUtils={}))},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(3),r=n(11);!function(t){function e(t){return void 0!==t.getConfig().source}function n(t){return t.isLive()&&0!==t.getMaxTimeShift()}function o(t){return t.hasEnded()?s.FINISHED:t.isPlaying()?s.PLAYING:t.isPaused()?s.PAUSED:e(t)?s.PREPARED:s.IDLE}var s;!function(t){t[t.IDLE=0]="IDLE",t[t.PREPARED=1]="PREPARED",t[t.PLAYING=2]="PLAYING",t[t.PAUSED=3]="PAUSED",t[t.FINISHED=4]="FINISHED"}(s=t.PlayerState||(t.PlayerState={})),t.isSourceLoaded=e,t.isTimeShiftAvailable=n,t.getState=o;var a=function(){function e(t){var e=this;this.timeShiftAvailabilityChangedEvent=new i.EventDispatcher,this.player=t,this.timeShiftAvailable=void 0;var n=function(){e.detect()};t.addEventHandler(t.EVENT.ON_READY,n),t.addEventHandler(t.EVENT.ON_TIME_CHANGED,n)}return e.prototype.detect=function(){if(this.player.isLive()){var e=t.isTimeShiftAvailable(this.player);e!==this.timeShiftAvailable&&(this.timeShiftAvailabilityChangedEvent.dispatch(this.player,{timeShiftAvailable:e}),this.timeShiftAvailable=e)}},Object.defineProperty(e.prototype,"onTimeShiftAvailabilityChanged",{get:function(){return this.timeShiftAvailabilityChangedEvent.getEvent()},enumerable:!0,configurable:!0}),e}();t.TimeShiftAvailabilityDetector=a;var u=function(){function t(t){var e=this;this.liveChangedEvent=new i.EventDispatcher,this.player=t,this.live=void 0;var n=function(){e.detect()};t.addEventHandler(t.EVENT.ON_READY,n),t.addEventHandler(t.EVENT.ON_PLAY,n),r.BrowserUtils.isAndroid&&r.BrowserUtils.isChrome&&t.addEventHandler(t.EVENT.ON_TIME_CHANGED,n)}return t.prototype.detect=function(){var t=this.player.isLive();t!==this.live&&(this.liveChangedEvent.dispatch(this.player,{live:t}),this.live=t)},Object.defineProperty(t.prototype,"onLiveChanged",{get:function(){return this.liveChangedEvent.getEvent()},enumerable:!0,configurable:!0}),t}();t.LiveStreamDetector=u}(e.PlayerUtils||(e.PlayerUtils={}))},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),o=n(0),s=n(3),a=function(t){function e(e){var n=t.call(this,e)||this;return n.buttonEvents={onClick:new s.EventDispatcher},n.config=n.mergeConfig(e,{cssClass:"ui-button"},n.config),n}return i(e,t),e.prototype.toDomElement=function(){var t=this,e=new o.DOM("button",{type:"button",id:this.config.id,class:this.getCssClasses()}).append(new o.DOM("span",{class:this.prefixCss("label")}).html(this.config.text));return e.on("click",function(){t.onClickEvent()}),e},e.prototype.setText=function(t){this.getDomElement().find("."+this.prefixCss("label")).html(t)},e.prototype.onClickEvent=function(){this.buttonEvents.onClick.dispatch(this)},Object.defineProperty(e.prototype,"onClick",{get:function(){return this.buttonEvents.onClick.getEvent()},enumerable:!0,configurable:!0}),e}(r.Component);e.Button=a},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),o=n(0),s=n(3),a=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.labelEvents={onClick:new s.EventDispatcher,onTextChanged:new s.EventDispatcher},n.config=n.mergeConfig(e,{cssClass:"ui-label"},n.config),n.text=n.config.text,n}return i(e,t),e.prototype.toDomElement=function(){var t=this,e=new o.DOM("span",{id:this.config.id,class:this.getCssClasses()}).html(this.text);return e.on("click",function(){t.onClickEvent()}),e},e.prototype.setText=function(t){this.text=t,this.getDomElement().html(t),this.onTextChangedEvent(t)},e.prototype.getText=function(){return this.text},e.prototype.clearText=function(){this.getDomElement().html(""),this.onTextChangedEvent(null)},e.prototype.isEmpty=function(){return!this.text},e.prototype.onClickEvent=function(){this.labelEvents.onClick.dispatch(this)},e.prototype.onTextChangedEvent=function(t){this.labelEvents.onTextChanged.dispatch(this,t)},Object.defineProperty(e.prototype,"onClick",{get:function(){return this.labelEvents.onClick.getEvent()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"onTextChanged",{get:function(){return this.labelEvents.onTextChanged.getEvent()},enumerable:!0,configurable:!0}),e}(r.Component);e.Label=a},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(6),o=n(3),s=function(t){function e(e){var n=t.call(this,e)||this;return n.toggleButtonEvents={onToggle:new o.EventDispatcher,onToggleOn:new o.EventDispatcher,onToggleOff:new o.EventDispatcher},n.config=n.mergeConfig(e,{cssClass:"ui-togglebutton"},n.config),n}return i(e,t),e.prototype.on=function(){this.isOff()&&(this.onState=!0,this.getDomElement().removeClass(this.prefixCss(e.CLASS_OFF)),this.getDomElement().addClass(this.prefixCss(e.CLASS_ON)),this.onToggleEvent(),this.onToggleOnEvent())},e.prototype.off=function(){this.isOn()&&(this.onState=!1,this.getDomElement().removeClass(this.prefixCss(e.CLASS_ON)),this.getDomElement().addClass(this.prefixCss(e.CLASS_OFF)),this.onToggleEvent(),this.onToggleOffEvent())},e.prototype.toggle=function(){this.isOn()?this.off():this.on()},e.prototype.isOn=function(){return this.onState},e.prototype.isOff=function(){return!this.isOn()},e.prototype.onClickEvent=function(){t.prototype.onClickEvent.call(this),this.onToggleEvent()},e.prototype.onToggleEvent=function(){this.toggleButtonEvents.onToggle.dispatch(this)},e.prototype.onToggleOnEvent=function(){this.toggleButtonEvents.onToggleOn.dispatch(this)},e.prototype.onToggleOffEvent=function(){this.toggleButtonEvents.onToggleOff.dispatch(this)},Object.defineProperty(e.prototype,"onToggle",{get:function(){return this.toggleButtonEvents.onToggle.getEvent()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"onToggleOn",{get:function(){return this.toggleButtonEvents.onToggleOn.getEvent()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"onToggleOff",{get:function(){return this.toggleButtonEvents.onToggleOff.getEvent()},enumerable:!0,configurable:!0}),e}(r.Button);s.CLASS_ON="on",s.CLASS_OFF="off",e.ToggleButton=s},function(t,e){t.exports=angular},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=function(){function t(t,e,n){void 0===n&&(n=!1),this.delay=t,this.callback=e,this.repeat=n,this.timeoutHandle=0}return t.prototype.start=function(){return this.reset(),this},t.prototype.clear=function(){clearTimeout(this.timeoutHandle)},t.prototype.reset=function(){var t=this,e=0,n=0;this.clear();var i=function(){if(t.callback(),t.repeat){var r=Date.now(),o=r-e;n=t.delay-o+n,e=r,t.timeoutHandle=window.setTimeout(i,t.delay+n)}};e=Date.now(),this.timeoutHandle=window.setTimeout(i,this.delay)},t}();e.Timeout=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});!function(t){t.isMobile=navigator&&navigator.userAgent&&/Mobi/.test(navigator.userAgent),t.isChrome=navigator&&navigator.userAgent&&/Chrome/.test(navigator.userAgent),t.isAndroid=navigator&&navigator.userAgent&&/Android/.test(navigator.userAgent)}(e.BrowserUtils||(e.BrowserUtils={}))},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(8),o=n(5),s=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.config=n.mergeConfig(e,{cssClass:"ui-playbacktogglebutton",text:"Play/Pause"},n.config),n}return i(e,t),e.prototype.configure=function(n,i,r){var s=this;void 0===r&&(r=!0),t.prototype.configure.call(this,n,i);var a=!1,u=function(t){a||(n.isPlaying()?s.on():s.off())};n.addEventHandler(n.EVENT.ON_PLAY,u),n.addEventHandler(n.EVENT.ON_PAUSED,u),n.addEventHandler(n.EVENT.ON_PLAYBACK_FINISHED,u),n.addEventHandler(n.EVENT.ON_CAST_STARTED,u),n.addEventHandler(n.EVENT.ON_CAST_PLAYING,u),n.addEventHandler(n.EVENT.ON_CAST_PAUSED,u),n.addEventHandler(n.EVENT.ON_CAST_PLAYBACK_FINISHED,u);var c=new o.PlayerUtils.TimeShiftAvailabilityDetector(n);c.onTimeShiftAvailabilityChanged.subscribe(function(t,n){n.timeShiftAvailable?s.getDomElement().removeClass(s.prefixCss(e.CLASS_STOPTOGGLE)):s.getDomElement().addClass(s.prefixCss(e.CLASS_STOPTOGGLE))}),c.detect(),r&&this.onClick.subscribe(function(){n.isPlaying()?n.pause("ui"):n.play("ui")}),i.onSeek.subscribe(function(){a=!0}),i.onSeeked.subscribe(function(){a=!1}),u()},e}(r.ToggleButton);s.CLASS_STOPTOGGLE="stoptoggle",e.PlaybackToggleButton=s},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),o=n(0),s=n(3),a=n(10),u=n(5),c=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.playbackPositionPercentage=0,n.touchSupported="ontouchstart"in window,n.seekBarEvents={onSeek:new s.EventDispatcher,onSeekPreview:new s.EventDispatcher,onSeeked:new s.EventDispatcher},n.config=n.mergeConfig(e,{cssClass:"ui-seekbar",vertical:!1,smoothPlaybackPositionUpdateIntervalMs:50,hideInLivePlayback:!0},n.config),n.label=n.config.label,n.timelineMarkers=[],n}return i(e,t),e.prototype.initialize=function(){t.prototype.initialize.call(this),this.hasLabel()&&this.getLabel().initialize()},e.prototype.configure=function(n,i,r){var o=this;if(void 0===r&&(r=!0),t.prototype.configure.call(this,n,i),r){var s=!0,a=!1,c=!1,h=function(t,i){if(void 0===t&&(t=null),void 0===i&&(i=!1),s=!1,!c)if(n.isLive()){if(0===n.getMaxTimeShift())o.setPlaybackPosition(100);else{var r=100-100/n.getMaxTimeShift()*n.getTimeShift();o.setPlaybackPosition(r)}o.setBufferPosition(100),o.hide()}else{var r=100/n.getDuration()*n.getCurrentTime(),a=n.getVideoBufferLength(),u=n.getAudioBufferLength(),h=Math.min(null!=a?a:Number.MAX_VALUE,null!=u?u:Number.MAX_VALUE);h===Number.MAX_VALUE&&(h=0);var l=100/n.getDuration()*h;(o.config.smoothPlaybackPositionUpdateIntervalMs===e.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED||i||n.isPaused()||n.isPaused()===n.isPlaying())&&o.setPlaybackPosition(r),o.setBufferPosition(r+l)}};n.addEventHandler(n.EVENT.ON_READY,h),n.addEventHandler(n.EVENT.ON_TIME_CHANGED,h),n.addEventHandler(n.EVENT.ON_STALL_ENDED,h),n.addEventHandler(n.EVENT.ON_SEEKED,h),n.addEventHandler(n.EVENT.ON_TIME_SHIFTED,h),n.addEventHandler(n.EVENT.ON_SEGMENT_REQUEST_FINISHED,h),n.addEventHandler(n.EVENT.ON_CAST_TIME_UPDATED,h),n.addEventHandler(n.EVENT.ON_SEEK,function(){o.setSeeking(!0)}),n.addEventHandler(n.EVENT.ON_SEEKED,function(){o.setSeeking(!1)}),n.addEventHandler(n.EVENT.ON_TIME_SHIFT,function(){o.setSeeking(!0)}),n.addEventHandler(n.EVENT.ON_TIME_SHIFTED,function(){o.setSeeking(!1)});var l=function(t){n.isLive()?n.timeShift(n.getMaxTimeShift()-n.getMaxTimeShift()*(t/100),"ui"):n.seek(n.getDuration()*(t/100),"ui")};this.onSeek.subscribe(function(t){c=!0,i.onSeek.dispatch(t),(a=n.isPlaying())&&n.pause("ui")}),this.onSeekPreview.subscribe(function(t,e){i.onSeekPreview.dispatch(t,e)}),this.onSeekPreview.subscribeRateLimited(function(t,e){e.scrubbing&&l(e.position)},200),this.onSeeked.subscribe(function(t,e){c=!1,l(e),a&&n.play("ui"),i.onSeeked.dispatch(t)}),this.hasLabel()&&this.getLabel().configure(n,i);var p=!1,f=!1,d=function(t,e){t&&!e?o.hide():o.show(),h(null,!0),o.refreshPlaybackPosition()},v=new u.PlayerUtils.LiveStreamDetector(n);v.onLiveChanged.subscribe(function(t,e){p=e.live,d(p,f)});var g=new u.PlayerUtils.TimeShiftAvailabilityDetector(n);g.onTimeShiftAvailabilityChanged.subscribe(function(t,e){f=e.timeShiftAvailable,d(p,f)}),v.detect(),g.detect(),n.addEventHandler(n.EVENT.ON_PLAYER_RESIZE,function(){o.refreshPlaybackPosition()}),i.onConfigured.subscribe(function(){o.refreshPlaybackPosition()}),n.addEventHandler(n.EVENT.ON_READY,function(){o.refreshPlaybackPosition()}),h(),this.setBufferPosition(0),this.setSeekPosition(0),this.config.smoothPlaybackPositionUpdateIntervalMs!==e.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED&&this.configureSmoothPlaybackPositionUpdater(n,i),this.configureMarkers(n,i)}},e.prototype.configureSmoothPlaybackPositionUpdater=function(t,e){var n=this,i=0,r=0;this.smoothPlaybackPositionUpdater=new a.Timeout(50,function(){i+=.05,r=t.getCurrentTime();var e=i-r;Math.abs(e)>2?i=r:e<=-.05?i+=.05:e>=.05&&(i-=.05);var o=100/t.getDuration()*i;n.setPlaybackPosition(o)},!0);var o=function(){t.isLive()||(i=t.getCurrentTime(),n.smoothPlaybackPositionUpdater.start())},s=function(){n.smoothPlaybackPositionUpdater.clear()};t.addEventHandler(t.EVENT.ON_PLAY,o),t.addEventHandler(t.EVENT.ON_CAST_PLAYING,o),t.addEventHandler(t.EVENT.ON_PAUSED,s),t.addEventHandler(t.EVENT.ON_CAST_PAUSED,s),t.addEventHandler(t.EVENT.ON_SEEKED,function(){i=t.getCurrentTime()}),t.isPlaying()&&o()},e.prototype.configureMarkers=function(t,e){var n=this,i=function(){n.timelineMarkers=[],n.updateMarkers()},r=function(){i();var r=e.getConfig().metadata&&e.getConfig().metadata.markers&&e.getConfig().metadata.markers.length>0,o=t.getConfig().source&&t.getConfig().source.markers&&t.getConfig().source.markers.length>0,s=r?e.getConfig().metadata.markers:o?t.getConfig().source.markers:null;if(s&&t.getDuration()!==1/0)for(var a=0,u=s;a0)for(var n=0,i=this.timelineMarkers;n=r.time-1&&t<=r.time+1){e=r;break}}return e},e.prototype.getHorizontalOffset=function(t){var e=this.seekBar.offset().left,n=this.seekBar.width(),i=t-e,r=1/n*i;return this.sanitizeOffset(r)},e.prototype.getVerticalOffset=function(t){var e=this.seekBar.offset().top,n=this.seekBar.height(),i=t-e,r=1/n*i;return 1-this.sanitizeOffset(r)},e.prototype.getOffset=function(t){return this.touchSupported&&t instanceof TouchEvent?this.config.vertical?this.getVerticalOffset("touchend"===t.type?t.changedTouches[0].pageY:t.touches[0].pageY):this.getHorizontalOffset("touchend"===t.type?t.changedTouches[0].pageX:t.touches[0].pageX):t instanceof MouseEvent?this.config.vertical?this.getVerticalOffset(t.pageY):this.getHorizontalOffset(t.pageX):(console&&console.warn("invalid event"),0)},e.prototype.sanitizeOffset=function(t){return t<0?t=0:t>1&&(t=1),t},e.prototype.setPlaybackPosition=function(t){this.playbackPositionPercentage=t,this.setPosition(this.seekBarPlaybackPosition,t);var e=this.config.vertical?this.seekBar.height()-this.seekBarPlaybackPositionMarker.height():this.seekBar.width(),n=e/100*t;this.config.vertical&&(n=this.seekBar.height()-n-this.seekBarPlaybackPositionMarker.height());var i=this.config.vertical?{transform:"translateY("+n+"px)","-ms-transform":"translateY("+n+"px)"}:{transform:"translateX("+n+"px)","-ms-transform":"translateX("+n+"px)"};this.seekBarPlaybackPositionMarker.css(i)},e.prototype.refreshPlaybackPosition=function(){this.setPlaybackPosition(this.playbackPositionPercentage)},e.prototype.setBufferPosition=function(t){this.setPosition(this.seekBarBufferPosition,t)},e.prototype.setSeekPosition=function(t){this.setPosition(this.seekBarSeekPosition,t)},e.prototype.setPosition=function(t,e){var n=e/100,i=this.config.vertical?{transform:"scaleY("+n+")","-ms-transform":"scaleY("+n+")"}:{transform:"scaleX("+n+")","-ms-transform":"scaleX("+n+")"};t.css(i)},e.prototype.setSeeking=function(t){t?this.getDomElement().addClass(this.prefixCss(e.CLASS_SEEKING)):this.getDomElement().removeClass(this.prefixCss(e.CLASS_SEEKING))},e.prototype.isSeeking=function(){return this.getDomElement().hasClass(this.prefixCss(e.CLASS_SEEKING))},e.prototype.hasLabel=function(){return null!=this.label},e.prototype.getLabel=function(){return this.label},e.prototype.onSeekEvent=function(){this.seekBarEvents.onSeek.dispatch(this)},e.prototype.onSeekPreviewEvent=function(t,e){var n=this.getMarkerAtPosition(t);this.label&&this.label.getDomElement().css({left:(n?n.time:t)+"%"}),this.seekBarEvents.onSeekPreview.dispatch(this,{scrubbing:e,position:t,marker:n})},e.prototype.onSeekedEvent=function(t){this.seekBarEvents.onSeeked.dispatch(this,t)},Object.defineProperty(e.prototype,"onSeek",{get:function(){return this.seekBarEvents.onSeek.getEvent()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"onSeekPreview",{get:function(){return this.seekBarEvents.onSeekPreview.getEvent()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"onSeeked",{get:function(){return this.seekBarEvents.onSeeked.getEvent()},enumerable:!0,configurable:!0}),e.prototype.onShowEvent=function(){t.prototype.onShowEvent.call(this),this.refreshPlaybackPosition()},e}(r.Component);c.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED=-1,c.CLASS_SEEKING="seeking",e.SeekBar=c},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});!function(t){function e(e,i){void 0===i&&(i=t.FORMAT_HHMMSS);var r=e<0;r&&(e=-e);var o=Math.floor(e/3600),s=Math.floor(e/60)-60*o,a=Math.floor(e)%60;return(r?"-":"")+i.replace("hh",n(o,2)).replace("mm",n(s,2)).replace("ss",n(a,2))}function n(t,e){var n=t+"";return"0000000000".substr(0,e-n.length)+n}function i(t,e,n){var i=new RegExp("\\{(remainingTime|playedTime|adDuration)(}|%((0[1-9]\\d*(\\.\\d+(d|f)|d|f)|\\.\\d+f|d|f)|hh:mm:ss|mm:ss)})","g");return t.replace(i,function(t){var i=0;return t.indexOf("remainingTime")>-1?i=e?Math.ceil(e-n.getCurrentTime()):n.getDuration()-n.getCurrentTime():t.indexOf("playedTime")>-1?i=n.getCurrentTime():t.indexOf("adDuration")>-1&&(i=n.getDuration()),r(i,t)})}function r(t,i){var r=/%((0[1-9]\d*(\.\d+(d|f)|d|f)|\.\d+f|d|f)|hh:mm:ss|mm:ss)/,o=/(%0[1-9]\d*)(?=(\.\d+f|f|d))/,s=/\.\d*(?=f)/;r.test(i)||(i="%d");var a=0,u=i.match(o);u&&(a=parseInt(u[0].substring(2)));var c=null,h=i.match(s);if(h&&!isNaN(parseInt(h[0].substring(1)))&&(c=parseInt(h[0].substring(1)))>20&&(c=20),i.indexOf("f")>-1){var l="";return l=null!==c?t.toFixed(c):""+t,l.indexOf(".")>-1?n(l,l.length+(a-l.indexOf("."))):n(l,a)}if(i.indexOf(":")>-1){var p=Math.ceil(t);if(i.indexOf("hh")>-1)return e(p);var f=Math.floor(p/60),d=p%60;return n(f,2)+":"+n(d,2)}return n(Math.ceil(t),a)}t.FORMAT_HHMMSS="hh:mm:ss",t.FORMAT_MMSS="mm:ss",t.secondsToTime=e,t.replaceAdMessagePlaceholders=i}(e.StringUtils||(e.StringUtils={}))},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(1),o=n(16),s=n(19),a=function(t){function e(e,n){var i=t.call(this,e)||this;return i.config=i.mergeConfig(e,{cssClass:"ui-controlbar",hidden:n},i.config),i}return i(e,t),e.prototype.configure=function(e,n){t.prototype.configure.call(this,e,n);var i=this,a=0;o.UIUtils.traverseTree(this,function(t){t instanceof r.Container||t instanceof s.Spacer||t.onHoverChanged.subscribe(function(t,e){e.hovered?a++:a--})}),n.onControlsShow.subscribe(function(){i.config.hidden&&i.show()}),n.onPreviewControlsHide.subscribe(function(t,e){e.cancel=a>0}),n.onControlsHide.subscribe(function(){i.config.hidden&&i.hide()})},e}(r.Container);e.ControlBar=a},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(1);!function(t){function e(t,e){var n=function(t,r){if(e(t,r),t instanceof i.Container)for(var o=0,s=t.getComponents();oh&&(h=t,i.getDomElement().css({"min-width":h+"px"}))};e.addEventHandler(e.EVENT.ON_TIME_CHANGED,v),e.addEventHandler(e.EVENT.ON_SEEKED,v),e.addEventHandler(e.EVENT.ON_CAST_TIME_UPDATED,v),e.addEventHandler(e.EVENT.ON_TIME_SHIFT,f),e.addEventHandler(e.EVENT.ON_TIME_SHIFTED,f);var g=function(){h=0,i.getDomElement().css({"min-width":null}),i.timeFormat=Math.abs(e.isLive()?e.getMaxTimeShift():e.getDuration())>=3600?a.StringUtils.FORMAT_HHMMSS:a.StringUtils.FORMAT_MMSS,v()};e.addEventHandler(e.EVENT.ON_READY,g),g()},e.prototype.setTime=function(t,e){var n=a.StringUtils.secondsToTime(t,this.timeFormat),i=a.StringUtils.secondsToTime(e,this.timeFormat);switch(this.config.timeLabelMode){case r.CurrentTime:this.setText(""+n);break;case r.TotalTime:this.setText(""+i);break;case r.CurrentAndTotalTime:this.setText(n+" / "+i)}},e.prototype.setTimeFormat=function(t){this.timeFormat=t},e}(o.Label);e.PlaybackTimeLabel=u},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),o=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.config=n.mergeConfig(e,{cssClass:"ui-spacer"},n.config),n}return i(e,t),e.prototype.onShowEvent=function(){},e.prototype.onHideEvent=function(){},e.prototype.onHoverChangedEvent=function(t){},e}(r.Component);e.Spacer=o},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(1),o=n(7),s=n(2),a=n(14),u=n(38),c=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.timeLabel=new o.Label({cssClasses:["seekbar-label-time"]}),n.titleLabel=new o.Label({cssClasses:["seekbar-label-title"]}),n.thumbnail=new s.Component({cssClasses:["seekbar-thumbnail"]}),n.thumbnailImageLoader=new u.ImageLoader,n.config=n.mergeConfig(e,{cssClass:"ui-seekbar-label",components:[new r.Container({components:[new r.Container({components:[n.titleLabel,n.timeLabel],cssClass:"seekbar-label-metadata"})],cssClass:"seekbar-label-inner"})],hidden:!0},n.config),n}return i(e,t),e.prototype.configure=function(e,n){var i=this;t.prototype.configure.call(this,e,n),n.onSeekPreview.subscribeRateLimited(function(t,n){if(e.isLive()){var r=e.getMaxTimeShift(),o=r-r*(n.position/100);i.setTime(o)}else{var s=0;n.marker?(s=n.marker.time,i.setTitleText(n.marker.title)):(s=n.position,i.setTitleText(null));var o=e.getDuration()*(s/100);i.setTime(o),i.setThumbnail(e.getThumb(o))}},100);var r=function(){i.timeFormat=Math.abs(e.isLive()?e.getMaxTimeShift():e.getDuration())>=3600?a.StringUtils.FORMAT_HHMMSS:a.StringUtils.FORMAT_MMSS};e.addEventHandler(e.EVENT.ON_READY,r),r()},e.prototype.setText=function(t){this.timeLabel.setText(t)},e.prototype.setTime=function(t){this.setText(a.StringUtils.secondsToTime(t,this.timeFormat))},e.prototype.setTitleText=function(t){this.titleLabel.setText(t)},e.prototype.setThumbnail=function(t){void 0===t&&(t=null);var e=this.thumbnail.getDomElement();null==t?e.css({"background-image":null,display:null,width:null,height:null}):this.thumbnailImageLoader.load(t.url,function(n,i,r){var o=i/t.w,s=r/t.h,a=t.x/t.w,u=t.y/t.h,c=100*o,h=100*s,l=100*a,p=100*u,f=1/t.w*t.h;e.css({display:"inherit","background-image":"url("+t.url+")","padding-bottom":100*f+"%","background-size":c+"% "+h+"%","background-position":"-"+l+"% -"+p+"%"})})},e}(r.Container);e.SeekBarLabel=c},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(22),o=n(0),s=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.config=n.mergeConfig(e,{cssClass:"ui-selectbox"},n.config),n}return i(e,t),e.prototype.toDomElement=function(){var t=this,e=new o.DOM("select",{id:this.config.id,class:this.getCssClasses()});return this.selectElement=e,this.updateDomItems(),e.on("change",function(){var n=e.val();t.onItemSelectedEvent(n,!1)}),e},e.prototype.updateDomItems=function(t){void 0===t&&(t=null),this.selectElement.empty();for(var e=0,n=this.items;e-1},e.prototype.addItem=function(t,e){this.removeItem(t),this.items.push({key:t,label:e}),this.onItemAddedEvent(t)},e.prototype.removeItem=function(t){var e=this.getItemIndex(t);return e>-1&&(s.ArrayUtils.remove(this.items,this.items[e]),this.onItemRemovedEvent(t),!0)},e.prototype.selectItem=function(t){return t===this.selectedItem||this.getItemIndex(t)>-1&&(this.selectedItem=t,this.onItemSelectedEvent(t),!0)},e.prototype.getSelectedItem=function(){return this.selectedItem},e.prototype.clearItems=function(){var t=this.items;this.items=[],this.selectedItem=null;for(var e=0,n=t;e200&&r()},200))}),e.addEventHandler(e.EVENT.ON_PLAY,function(){s=!1});var c=function(t){t.type===e.EVENT.ON_CAST_START?i.hide():i.show()};e.addEventHandler(e.EVENT.ON_CAST_START,c),e.addEventHandler(e.EVENT.ON_CAST_STARTED,c),e.addEventHandler(e.EVENT.ON_CAST_STOPPED,c)},e.prototype.toDomElement=function(){var e=t.prototype.toDomElement.call(this);return e.append(new o.DOM("div",{class:this.prefixCss("image")})),e},e}(r.PlaybackToggleButton);e.HugePlaybackToggleButton=s},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(1),o=n(2),s=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.audioonly=[new o.Component({tag:"div",cssClass:"ui-audioonly-overlay-indicator"})],n.config=n.mergeConfig(e,{cssClass:"ui-audioonly-overlay",components:n.audioonly,hidden:!1},n.config),n}return i(e,t),e.prototype.configure=function(e,n){t.prototype.configure.call(this,e,n);var i=this;i.getDomElement().css("background-image")},e}(r.Container);e.AudioOnlyOverlay=s},function(t,e,n){n(31),n(34),t.exports=n(47)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(9),r=n(32),o=n(33);e.default=i.module("mi.BitdashPlayer",[]).controller("MiBitdashController",r.default).directive("miBitdashPlayer",o.default)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(9),r=function(){function t(t,e){this.$scope=t,this.$log=e,this.config={},this.options={},this.$scope=t,this.$log=e}return t.prototype.$onInit=function(){i.isDefined(this.$scope.config)&&i.isDefined(this.$scope.config.key)?this.config=this.$scope.config:this.$log.error("basic config for bitdash player is missing!"),i.isDefined(this.$scope.options)&&(this.options=this.$scope.options),i.isDefined(this.$scope.webcast)&&this.processWebcast(this.$scope.webcast)},t.prototype.processWebcast=function(t){var e=t.state+"StateData";i.isDefined(this.options.forcedState)&&(e=this.options.forcedState+"StateData"),this.config.source=this.getPlayerConfigSource(t,e),this.config.style={ux:!1}},t.prototype.getPlayerConfigSource=function(t,e){return!0===t.useDVRPlaybackInPostlive&&"postliveStateData"===e?this.getDVRPlaybackToPostlive(t):this.getPlayerConfigSourceByState(t,e)},t.prototype.getDVRPlaybackToPostlive=function(t){var e=t.liveStateData.playout.hlsDvrUrl,n=t.name;if(i.isDefined(t.postliveStateData.playout.offset)){var r=parseInt(t.postliveStateData.playout.offset,10);if(r>0){var o=void 0,s=document.createElement("a");s.href=t.liveStateData.playout.hlsDvrUrl,o=s.search?"&":"?",e+=o+"wowzadvrplayliststart="+r+"000"}}return{hls:e,title:n}},t.prototype.getPlayerConfigSourceByState=function(t,e){var n=t[e].playout.hlsUrl,r=t.name,o=this.getHiveServiceUrlByLang(t);if(i.isDefined(t[e].playout.videoManagerHlsUrl)&&t[e].playout.videoManagerHlsUrl&&(n=t[e].playout.videoManagerHlsUrl),i.isDefined(t[e].playout.offset)){var s=parseInt(t[e].playout.offset,10);if(s>0){var a=void 0,u=document.createElement("a");u.href=n,a=u.search?"&":"?",n+=a+"start="+s}}return{hls:n,title:r,hiveServiceUrl:o}},t.prototype.getHiveServiceUrlByLang=function(t){var e=null;return t.languages&&t.language&&t.languages.forEach(function(n){n.language===t.language&&(e=i.copy(n.hiveServiceUrl))}),e},t}();r.$inject=["$scope","$log"],e.default=r},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(9),r=function(t,e){return{controller:"MiBitdashController",controllerAs:"bitdashVm",replace:!0,restrict:"EA",scope:{config:"=",options:"=?",webcast:"="},template:'
',link:function(n){function r(n){u.setup(n).then(function(){c=t.window.bitmovin.playerui.UIManager.Factory,o()?(c.buildAudioOnlyUI(u),s()):c.buildAudioVideoUI(u),h=a("bitmovinplayer-container"),i.isDefined(h)&&(h.style.minWidth="175px",h.style.minHeight="101px",document.getElementById("bitmovinplayer-video-mi-bitdash-player").setAttribute("title",p.name))},function(t){e.log("Error: "+t.code+" - "+t.message)})}function o(){return i.isDefined(n.webcast[f].playout.audioOnly)&&n.webcast[f].playout.audioOnly}function s(){if(i.isDefined(n.webcast[f].playout.audioOnlyStillUrl)&&""!==n.webcast[f].playout.audioOnlyStillUrl){var t=a("mi-wbc-ui-audioonly-overlay");t.style.backgroundImage="url("+n.webcast[f].playout.audioOnlyStillUrl+")",t.style.backgroundSize="contain",t.style.backgroundPosition="center"}}function a(t){return document.getElementsByClassName(t)[0]}var u,c,h,l=n.config,p=n.webcast,f=n.webcast.state+"StateData";!function(){u=t.window.bitmovin.player("mi-bitdash-player"),i.isDefined(u)&&!0===u.isReady()&&(u.destroy(),u=t.window.bitmovin.player("mi-bitdash-player")),"liveStateData"===f&&l.source.hiveServiceUrl?(t.window.bitmovin.initHiveSDN(u,{debugLevel:"off"}),u.initSession(l.source.hiveServiceUrl).then(function(t){var e=i.copy(l);e.source.hls=t.manifest,r(e)},function(t){e.warn("Hive init fails: "+t.code+" - "+t.message),r(l)})):r(l)}()}}};e.default=r,r.$inject=["$window","$log"]},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(35),r=n(6),o=n(15),s=n(28),a=n(18),u=n(12),c=n(13),h=n(21),l=n(42),p=n(8),f=n(25),d=n(17),v=n(1),g=n(7),y=n(2),m=n(26),b=n(20),w=n(23),E=n(43),O=n(44),S=n(27),T=n(45),k=n(24),C=n(19),R=n(4),I=n(14),P=n(5),A=n(16),N=n(11),x=n(46),_=n(29);"function"!=typeof Object.assign&&(Object.assign=function(t){if(null==t)throw new TypeError("Cannot convert undefined or null to object");t=Object(t);for(var e=1;e1)throw Error("Too many UIs without a condition: You cannot have more than one default UI");if(u.length>0&&u[0]!==this.uiVariants[this.uiVariants.length-1])throw Error("Invalid UI variant order: the default UI (without condition) must be at the end of the list");var p=null,f=S.BrowserUtils.isMobile,d=function(e){if(null!=e)switch(e.type){case t.EVENT.ON_AD_STARTED:p=e;break;case t.EVENT.ON_AD_FINISHED:case t.EVENT.ON_AD_SKIPPED:case t.EVENT.ON_AD_ERROR:p=null;break;case t.EVENT.ON_READY:p&&!t.isAd()&&(p=null)}for(var n=null!=p,r=n&&"vast"===p.clientType,o={isAd:n,isAdWithUI:r,adClientType:n?p.clientType:null,isFullscreen:i.player.isFullscreen(),isMobile:f,isPlaying:i.player.isPlaying(),width:i.uiContainerElement.width(),documentWidth:document.body.clientWidth},s=null,a=!1,u=0,c=i.uiVariants;uc){r=i.getDomElement().height()/e.CEA608_NUM_ROWS;var h=i.getDomElement().width()/e.CEA608_NUM_COLUMNS;o=h-r*a}else r=i.getDomElement().width()/e.CEA608_NUM_COLUMNS/a,o=0;for(var l=0,p=i.getComponents();l0?i.map(function(t){return t.label}):null},t.prototype.cueExit=function(e){var n=t.calculateId(e),i=this.activeSubtitleCueMap[n];if(i&&i.length>0){var r=i.shift();return this.activeSubtitleCueCount--,r.label}return null},Object.defineProperty(t.prototype,"cueCount",{get:function(){return this.activeSubtitleCueCount},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"hasCues",{get:function(){return this.cueCount>0},enumerable:!0,configurable:!0}),t.prototype.clear=function(){this.activeSubtitleCueMap={},this.activeSubtitleCueCount=0},t}()},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),o=n(0),s=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.canvasWidth=160,n.canvasHeight=90,n.interferenceHeight=50,n.lastFrameUpdate=0,n.frameInterval=60,n.useAnimationFrame=!!window.requestAnimationFrame,n.config=n.mergeConfig(e,{cssClass:"ui-tvnoisecanvas"},n.config),n}return i(e,t),e.prototype.toDomElement=function(){return this.canvas=new o.DOM("canvas",{class:this.getCssClasses()})},e.prototype.start=function(){this.canvasElement=this.canvas.get(0),this.canvasContext=this.canvasElement.getContext("2d"),this.noiseAnimationWindowPos=-this.canvasHeight,this.lastFrameUpdate=0,this.canvasElement.width=this.canvasWidth,this.canvasElement.height=this.canvasHeight,this.renderFrame()},e.prototype.stop=function(){this.useAnimationFrame?cancelAnimationFrame(this.frameUpdateHandlerId):clearTimeout(this.frameUpdateHandlerId)},e.prototype.renderFrame=function(){if(this.lastFrameUpdate+this.frameInterval>(new Date).getTime())return void this.scheduleNextRender();for(var t,e=this.canvasWidth,n=this.canvasHeight,i=this.canvasContext.createImageData(e,n),r=0;rthis.noiseAnimationWindowPos+this.interferenceHeight)&&(i.data[t]*=.85),i.data[t+1]=i.data[t],i.data[t+2]=i.data[t],i.data[t+3]=50;this.canvasContext.putImageData(i,0,0),this.lastFrameUpdate=(new Date).getTime(),this.noiseAnimationWindowPos+=7,this.noiseAnimationWindowPos>n&&(this.noiseAnimationWindowPos=-n),this.scheduleNextRender()},e.prototype.scheduleNextRender=function(){this.useAnimationFrame?this.frameUpdateHandlerId=window.requestAnimationFrame(this.renderFrame.bind(this)):this.frameUpdateHandlerId=setTimeout(this.renderFrame.bind(this),this.frameInterval)},e}(r.Component);e.TvNoiseCanvas=s},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(22),o=n(0),s=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.config=n.mergeConfig(e,{tag:"ul",cssClass:"ui-itemselectionlist"},n.config),n}return i(e,t),e.prototype.isActive=function(){return this.items.length>1},e.prototype.toDomElement=function(){var t=new o.DOM("ul",{id:this.config.id,class:this.getCssClasses()});return this.listElement=t,this.updateDomItems(),t},e.prototype.updateDomItems=function(t){var n=this;void 0===t&&(t=null),this.listElement.empty();for(var i=null,r=function(t){t.addClass(n.prefixCss(e.CLASS_SELECTED))},s=function(t){t.removeClass(n.prefixCss(e.CLASS_SELECTED))},a=this,u=0,c=this.items;u0&&t[0]instanceof HTMLElement){var n=t;this.elements=n}}else if(t instanceof HTMLElement){var i=t;this.elements=[i]}else if(t instanceof Document)this.elements=null;else if(e){var r=t,i=document.createElement(r);for(var o in e){var s=e[o];i.setAttribute(o,s)}this.elements=[i]}else{var a=t;this.elements=this.findChildElements(a)}}return Object.defineProperty(t.prototype,"length",{get:function(){return this.elements?this.elements.length:0},enumerable:!0,configurable:!0}),t.prototype.getElements=function(){return this.get()},t.prototype.get=function(t){return void 0===t?this.elements:!this.elements||t>=this.elements.length||t<-this.elements.length?void 0:t<0?this.elements[this.elements.length-t]:this.elements[t]},t.prototype.forEach=function(t){this.elements&&this.elements.forEach(function(e){t(e)})},t.prototype.findChildElementsOfElement=function(t,e){var n=t.querySelectorAll(e);return[].slice.call(n)},t.prototype.findChildElements=function(t){var e=this,n=[];return this.elements?(this.forEach(function(i){n=n.concat(e.findChildElementsOfElement(i,t))}),n):this.findChildElementsOfElement(document,t)},t.prototype.find=function(e){return new t(this.findChildElements(e))},t.prototype.html=function(t){return arguments.length>0?this.setHtml(t):this.getHtml()},t.prototype.getHtml=function(){return this.elements[0].innerHTML},t.prototype.setHtml=function(t){return void 0!==t&&null!=t||(t=""),this.forEach(function(e){e.innerHTML=t}),this},t.prototype.empty=function(){return this.forEach(function(t){t.innerHTML=""}),this},t.prototype.val=function(){var t=this.elements[0];if(t instanceof HTMLSelectElement||t instanceof HTMLInputElement)return t.value;throw new Error("val() not supported for "+typeof t)},t.prototype.attr=function(t,e){return arguments.length>1?this.setAttr(t,e):this.getAttr(t)},t.prototype.getAttr=function(t){return this.elements[0].getAttribute(t)},t.prototype.setAttr=function(t,e){return this.forEach(function(n){n.setAttribute(t,e)}),this},t.prototype.data=function(t,e){return arguments.length>1?this.setData(t,e):this.getData(t)},t.prototype.getData=function(t){return this.elements[0].getAttribute("data-"+t)},t.prototype.setData=function(t,e){return this.forEach(function(n){n.setAttribute("data-"+t,e)}),this},t.prototype.append=function(){for(var t=[],e=0;ei.rateMs&&(i.fireSuper(t,e),i.lastFireTime=Date.now())},i}return i(e,t),e.prototype.fireSuper=function(e,n){t.prototype.fire.call(this,e,n)},e.prototype.fire=function(t,e){this.rateLimitingEventListener(t,e)},e}(s)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});!function(t){function e(t,e){var n=t.indexOf(e);return n>-1?t.splice(n,1)[0]:null}t.remove=e}(e.ArrayUtils||(e.ArrayUtils={}))},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(3),r=n(11);!function(t){function e(t){return void 0!==t.getConfig().source}function n(t){return t.isLive()&&0!==t.getMaxTimeShift()}function o(t){return t.hasEnded()?s.FINISHED:t.isPlaying()?s.PLAYING:t.isPaused()?s.PAUSED:e(t)?s.PREPARED:s.IDLE}var s;!function(t){t[t.IDLE=0]="IDLE",t[t.PREPARED=1]="PREPARED",t[t.PLAYING=2]="PLAYING",t[t.PAUSED=3]="PAUSED",t[t.FINISHED=4]="FINISHED"}(s=t.PlayerState||(t.PlayerState={})),t.isSourceLoaded=e,t.isTimeShiftAvailable=n,t.getState=o;var a=function(){function e(t){var e=this;this.timeShiftAvailabilityChangedEvent=new i.EventDispatcher,this.player=t,this.timeShiftAvailable=void 0;var n=function(){e.detect()};t.addEventHandler(t.EVENT.ON_READY,n),t.addEventHandler(t.EVENT.ON_TIME_CHANGED,n)}return e.prototype.detect=function(){if(this.player.isLive()){var e=t.isTimeShiftAvailable(this.player);e!==this.timeShiftAvailable&&(this.timeShiftAvailabilityChangedEvent.dispatch(this.player,{timeShiftAvailable:e}),this.timeShiftAvailable=e)}},Object.defineProperty(e.prototype,"onTimeShiftAvailabilityChanged",{get:function(){return this.timeShiftAvailabilityChangedEvent.getEvent()},enumerable:!0,configurable:!0}),e}();t.TimeShiftAvailabilityDetector=a;var u=function(){function t(t){var e=this;this.liveChangedEvent=new i.EventDispatcher,this.player=t,this.live=void 0;var n=function(){e.detect()};t.addEventHandler(t.EVENT.ON_READY,n),t.addEventHandler(t.EVENT.ON_PLAY,n),r.BrowserUtils.isAndroid&&r.BrowserUtils.isChrome&&t.addEventHandler(t.EVENT.ON_TIME_CHANGED,n)}return t.prototype.detect=function(){var t=this.player.isLive();t!==this.live&&(this.liveChangedEvent.dispatch(this.player,{live:t}),this.live=t)},Object.defineProperty(t.prototype,"onLiveChanged",{get:function(){return this.liveChangedEvent.getEvent()},enumerable:!0,configurable:!0}),t}();t.LiveStreamDetector=u}(e.PlayerUtils||(e.PlayerUtils={}))},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),o=n(0),s=n(3),a=function(t){function e(e){var n=t.call(this,e)||this;return n.buttonEvents={onClick:new s.EventDispatcher},n.config=n.mergeConfig(e,{cssClass:"ui-button"},n.config),n}return i(e,t),e.prototype.toDomElement=function(){var t=this,e=new o.DOM("button",{type:"button",id:this.config.id,class:this.getCssClasses()}).append(new o.DOM("span",{class:this.prefixCss("label")}).html(this.config.text));return e.on("click",function(){t.onClickEvent()}),e},e.prototype.setText=function(t){this.getDomElement().find("."+this.prefixCss("label")).html(t)},e.prototype.onClickEvent=function(){this.buttonEvents.onClick.dispatch(this)},Object.defineProperty(e.prototype,"onClick",{get:function(){return this.buttonEvents.onClick.getEvent()},enumerable:!0,configurable:!0}),e}(r.Component);e.Button=a},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),o=n(0),s=n(3),a=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.labelEvents={onClick:new s.EventDispatcher,onTextChanged:new s.EventDispatcher},n.config=n.mergeConfig(e,{cssClass:"ui-label"},n.config),n.text=n.config.text,n}return i(e,t),e.prototype.toDomElement=function(){var t=this,e=new o.DOM("span",{id:this.config.id,class:this.getCssClasses()}).html(this.text);return e.on("click",function(){t.onClickEvent()}),e},e.prototype.setText=function(t){this.text=t,this.getDomElement().html(t),this.onTextChangedEvent(t)},e.prototype.getText=function(){return this.text},e.prototype.clearText=function(){this.getDomElement().html(""),this.onTextChangedEvent(null)},e.prototype.isEmpty=function(){return!this.text},e.prototype.onClickEvent=function(){this.labelEvents.onClick.dispatch(this)},e.prototype.onTextChangedEvent=function(t){this.labelEvents.onTextChanged.dispatch(this,t)},Object.defineProperty(e.prototype,"onClick",{get:function(){return this.labelEvents.onClick.getEvent()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"onTextChanged",{get:function(){return this.labelEvents.onTextChanged.getEvent()},enumerable:!0,configurable:!0}),e}(r.Component);e.Label=a},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(6),o=n(3),s=function(t){function e(e){var n=t.call(this,e)||this;return n.toggleButtonEvents={onToggle:new o.EventDispatcher,onToggleOn:new o.EventDispatcher,onToggleOff:new o.EventDispatcher},n.config=n.mergeConfig(e,{cssClass:"ui-togglebutton"},n.config),n}return i(e,t),e.prototype.on=function(){this.isOff()&&(this.onState=!0,this.getDomElement().removeClass(this.prefixCss(e.CLASS_OFF)),this.getDomElement().addClass(this.prefixCss(e.CLASS_ON)),this.onToggleEvent(),this.onToggleOnEvent())},e.prototype.off=function(){this.isOn()&&(this.onState=!1,this.getDomElement().removeClass(this.prefixCss(e.CLASS_ON)),this.getDomElement().addClass(this.prefixCss(e.CLASS_OFF)),this.onToggleEvent(),this.onToggleOffEvent())},e.prototype.toggle=function(){this.isOn()?this.off():this.on()},e.prototype.isOn=function(){return this.onState},e.prototype.isOff=function(){return!this.isOn()},e.prototype.onClickEvent=function(){t.prototype.onClickEvent.call(this),this.onToggleEvent()},e.prototype.onToggleEvent=function(){this.toggleButtonEvents.onToggle.dispatch(this)},e.prototype.onToggleOnEvent=function(){this.toggleButtonEvents.onToggleOn.dispatch(this)},e.prototype.onToggleOffEvent=function(){this.toggleButtonEvents.onToggleOff.dispatch(this)},Object.defineProperty(e.prototype,"onToggle",{get:function(){return this.toggleButtonEvents.onToggle.getEvent()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"onToggleOn",{get:function(){return this.toggleButtonEvents.onToggleOn.getEvent()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"onToggleOff",{get:function(){return this.toggleButtonEvents.onToggleOff.getEvent()},enumerable:!0,configurable:!0}),e}(r.Button);s.CLASS_ON="on",s.CLASS_OFF="off",e.ToggleButton=s},function(t,e){t.exports=angular},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=function(){function t(t,e,n){void 0===n&&(n=!1),this.delay=t,this.callback=e,this.repeat=n,this.timeoutHandle=0}return t.prototype.start=function(){return this.reset(),this},t.prototype.clear=function(){clearTimeout(this.timeoutHandle)},t.prototype.reset=function(){var t=this,e=0,n=0;this.clear();var i=function(){if(t.callback(),t.repeat){var r=Date.now(),o=r-e;n=t.delay-o+n,e=r,t.timeoutHandle=window.setTimeout(i,t.delay+n)}};e=Date.now(),this.timeoutHandle=window.setTimeout(i,this.delay)},t}();e.Timeout=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});!function(t){t.isMobile=navigator&&navigator.userAgent&&/Mobi/.test(navigator.userAgent),t.isChrome=navigator&&navigator.userAgent&&/Chrome/.test(navigator.userAgent),t.isAndroid=navigator&&navigator.userAgent&&/Android/.test(navigator.userAgent)}(e.BrowserUtils||(e.BrowserUtils={}))},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(8),o=n(5),s=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.config=n.mergeConfig(e,{cssClass:"ui-playbacktogglebutton",text:"Play/Pause"},n.config),n}return i(e,t),e.prototype.configure=function(n,i,r){var s=this;void 0===r&&(r=!0),t.prototype.configure.call(this,n,i);var a=!1,u=function(t){a||(n.isPlaying()?s.on():s.off())};n.addEventHandler(n.EVENT.ON_PLAY,u),n.addEventHandler(n.EVENT.ON_PAUSED,u),n.addEventHandler(n.EVENT.ON_PLAYBACK_FINISHED,u),n.addEventHandler(n.EVENT.ON_CAST_STARTED,u),n.addEventHandler(n.EVENT.ON_CAST_PLAYING,u),n.addEventHandler(n.EVENT.ON_CAST_PAUSED,u),n.addEventHandler(n.EVENT.ON_CAST_PLAYBACK_FINISHED,u);var c=new o.PlayerUtils.TimeShiftAvailabilityDetector(n);c.onTimeShiftAvailabilityChanged.subscribe(function(t,n){n.timeShiftAvailable?s.getDomElement().removeClass(s.prefixCss(e.CLASS_STOPTOGGLE)):s.getDomElement().addClass(s.prefixCss(e.CLASS_STOPTOGGLE))}),c.detect(),r&&this.onClick.subscribe(function(){n.isPlaying()?n.pause("ui"):n.play("ui")}),i.onSeek.subscribe(function(){a=!0}),i.onSeeked.subscribe(function(){a=!1}),u()},e}(r.ToggleButton);s.CLASS_STOPTOGGLE="stoptoggle",e.PlaybackToggleButton=s},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),o=n(0),s=n(3),a=n(10),u=n(5),c=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.playbackPositionPercentage=0,n.touchSupported="ontouchstart"in window,n.seekBarEvents={onSeek:new s.EventDispatcher,onSeekPreview:new s.EventDispatcher,onSeeked:new s.EventDispatcher},n.config=n.mergeConfig(e,{cssClass:"ui-seekbar",vertical:!1,smoothPlaybackPositionUpdateIntervalMs:50,hideInLivePlayback:!0},n.config),n.label=n.config.label,n.timelineMarkers=[],n}return i(e,t),e.prototype.initialize=function(){t.prototype.initialize.call(this),this.hasLabel()&&this.getLabel().initialize()},e.prototype.configure=function(n,i,r){var o=this;if(void 0===r&&(r=!0),t.prototype.configure.call(this,n,i),r){var s=!0,a=!1,c=!1,h=function(t,i){if(void 0===t&&(t=null),void 0===i&&(i=!1),s=!1,!c)if(n.isLive()){if(0===n.getMaxTimeShift())o.setPlaybackPosition(100);else{var r=100-100/n.getMaxTimeShift()*n.getTimeShift();o.setPlaybackPosition(r)}o.setBufferPosition(100),o.hide()}else{var r=100/n.getDuration()*n.getCurrentTime(),a=n.getVideoBufferLength(),u=n.getAudioBufferLength(),h=Math.min(null!=a?a:Number.MAX_VALUE,null!=u?u:Number.MAX_VALUE);h===Number.MAX_VALUE&&(h=0);var l=100/n.getDuration()*h;(o.config.smoothPlaybackPositionUpdateIntervalMs===e.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED||i||n.isPaused()||n.isPaused()===n.isPlaying())&&o.setPlaybackPosition(r),o.setBufferPosition(r+l)}};n.addEventHandler(n.EVENT.ON_READY,h),n.addEventHandler(n.EVENT.ON_TIME_CHANGED,h),n.addEventHandler(n.EVENT.ON_STALL_ENDED,h),n.addEventHandler(n.EVENT.ON_SEEKED,h),n.addEventHandler(n.EVENT.ON_TIME_SHIFTED,h),n.addEventHandler(n.EVENT.ON_SEGMENT_REQUEST_FINISHED,h),n.addEventHandler(n.EVENT.ON_CAST_TIME_UPDATED,h),n.addEventHandler(n.EVENT.ON_SEEK,function(){o.setSeeking(!0)}),n.addEventHandler(n.EVENT.ON_SEEKED,function(){o.setSeeking(!1)}),n.addEventHandler(n.EVENT.ON_TIME_SHIFT,function(){o.setSeeking(!0)}),n.addEventHandler(n.EVENT.ON_TIME_SHIFTED,function(){o.setSeeking(!1)});var l=function(t){n.isLive()?n.timeShift(n.getMaxTimeShift()-n.getMaxTimeShift()*(t/100),"ui"):n.seek(n.getDuration()*(t/100),"ui")};this.onSeek.subscribe(function(t){c=!0,i.onSeek.dispatch(t),(a=n.isPlaying())&&n.pause("ui")}),this.onSeekPreview.subscribe(function(t,e){i.onSeekPreview.dispatch(t,e)}),this.onSeekPreview.subscribeRateLimited(function(t,e){e.scrubbing&&l(e.position)},200),this.onSeeked.subscribe(function(t,e){c=!1,l(e),a&&n.play("ui"),i.onSeeked.dispatch(t)}),this.hasLabel()&&this.getLabel().configure(n,i);var p=!1,f=!1,d=function(t,e){t&&!e?o.hide():o.show(),h(null,!0),o.refreshPlaybackPosition()},v=new u.PlayerUtils.LiveStreamDetector(n);v.onLiveChanged.subscribe(function(t,e){p=e.live,d(p,f)});var g=new u.PlayerUtils.TimeShiftAvailabilityDetector(n);g.onTimeShiftAvailabilityChanged.subscribe(function(t,e){f=e.timeShiftAvailable,d(p,f)}),v.detect(),g.detect(),n.addEventHandler(n.EVENT.ON_PLAYER_RESIZE,function(){o.refreshPlaybackPosition()}),i.onConfigured.subscribe(function(){o.refreshPlaybackPosition()}),n.addEventHandler(n.EVENT.ON_READY,function(){o.refreshPlaybackPosition()}),h(),this.setBufferPosition(0),this.setSeekPosition(0),this.config.smoothPlaybackPositionUpdateIntervalMs!==e.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED&&this.configureSmoothPlaybackPositionUpdater(n,i),this.configureMarkers(n,i)}},e.prototype.configureSmoothPlaybackPositionUpdater=function(t,e){var n=this,i=0,r=0;this.smoothPlaybackPositionUpdater=new a.Timeout(50,function(){i+=.05,r=t.getCurrentTime();var e=i-r;Math.abs(e)>2?i=r:e<=-.05?i+=.05:e>=.05&&(i-=.05);var o=100/t.getDuration()*i;n.setPlaybackPosition(o)},!0);var o=function(){t.isLive()||(i=t.getCurrentTime(),n.smoothPlaybackPositionUpdater.start())},s=function(){n.smoothPlaybackPositionUpdater.clear()};t.addEventHandler(t.EVENT.ON_PLAY,o),t.addEventHandler(t.EVENT.ON_CAST_PLAYING,o),t.addEventHandler(t.EVENT.ON_PAUSED,s),t.addEventHandler(t.EVENT.ON_CAST_PAUSED,s),t.addEventHandler(t.EVENT.ON_SEEKED,function(){i=t.getCurrentTime()}),t.isPlaying()&&o()},e.prototype.configureMarkers=function(t,e){var n=this,i=function(){n.timelineMarkers=[],n.updateMarkers()},r=function(){i();var r=e.getConfig().metadata&&e.getConfig().metadata.markers&&e.getConfig().metadata.markers.length>0,o=t.getConfig().source&&t.getConfig().source.markers&&t.getConfig().source.markers.length>0,s=r?e.getConfig().metadata.markers:o?t.getConfig().source.markers:null;if(s&&t.getDuration()!==1/0)for(var a=0,u=s;a0)for(var n=0,i=this.timelineMarkers;n=r.time-1&&t<=r.time+1){e=r;break}}return e},e.prototype.getHorizontalOffset=function(t){var e=this.seekBar.offset().left,n=this.seekBar.width(),i=t-e,r=1/n*i;return this.sanitizeOffset(r)},e.prototype.getVerticalOffset=function(t){var e=this.seekBar.offset().top,n=this.seekBar.height(),i=t-e,r=1/n*i;return 1-this.sanitizeOffset(r)},e.prototype.getOffset=function(t){return this.touchSupported&&t instanceof TouchEvent?this.config.vertical?this.getVerticalOffset("touchend"===t.type?t.changedTouches[0].pageY:t.touches[0].pageY):this.getHorizontalOffset("touchend"===t.type?t.changedTouches[0].pageX:t.touches[0].pageX):t instanceof MouseEvent?this.config.vertical?this.getVerticalOffset(t.pageY):this.getHorizontalOffset(t.pageX):(console&&console.warn("invalid event"),0)},e.prototype.sanitizeOffset=function(t){return t<0?t=0:t>1&&(t=1),t},e.prototype.setPlaybackPosition=function(t){this.playbackPositionPercentage=t,this.setPosition(this.seekBarPlaybackPosition,t);var e=this.config.vertical?this.seekBar.height()-this.seekBarPlaybackPositionMarker.height():this.seekBar.width(),n=e/100*t;this.config.vertical&&(n=this.seekBar.height()-n-this.seekBarPlaybackPositionMarker.height());var i=this.config.vertical?{transform:"translateY("+n+"px)","-ms-transform":"translateY("+n+"px)"}:{transform:"translateX("+n+"px)","-ms-transform":"translateX("+n+"px)"};this.seekBarPlaybackPositionMarker.css(i)},e.prototype.refreshPlaybackPosition=function(){this.setPlaybackPosition(this.playbackPositionPercentage)},e.prototype.setBufferPosition=function(t){this.setPosition(this.seekBarBufferPosition,t)},e.prototype.setSeekPosition=function(t){this.setPosition(this.seekBarSeekPosition,t)},e.prototype.setPosition=function(t,e){var n=e/100,i=this.config.vertical?{transform:"scaleY("+n+")","-ms-transform":"scaleY("+n+")"}:{transform:"scaleX("+n+")","-ms-transform":"scaleX("+n+")"};t.css(i)},e.prototype.setSeeking=function(t){t?this.getDomElement().addClass(this.prefixCss(e.CLASS_SEEKING)):this.getDomElement().removeClass(this.prefixCss(e.CLASS_SEEKING))},e.prototype.isSeeking=function(){return this.getDomElement().hasClass(this.prefixCss(e.CLASS_SEEKING))},e.prototype.hasLabel=function(){return null!=this.label},e.prototype.getLabel=function(){return this.label},e.prototype.onSeekEvent=function(){this.seekBarEvents.onSeek.dispatch(this)},e.prototype.onSeekPreviewEvent=function(t,e){var n=this.getMarkerAtPosition(t);this.label&&this.label.getDomElement().css({left:(n?n.time:t)+"%"}),this.seekBarEvents.onSeekPreview.dispatch(this,{scrubbing:e,position:t,marker:n})},e.prototype.onSeekedEvent=function(t){this.seekBarEvents.onSeeked.dispatch(this,t)},Object.defineProperty(e.prototype,"onSeek",{get:function(){return this.seekBarEvents.onSeek.getEvent()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"onSeekPreview",{get:function(){return this.seekBarEvents.onSeekPreview.getEvent()},enumerable:!0,configurable:!0}),Object.defineProperty(e.prototype,"onSeeked",{get:function(){return this.seekBarEvents.onSeeked.getEvent()},enumerable:!0,configurable:!0}),e.prototype.onShowEvent=function(){t.prototype.onShowEvent.call(this),this.refreshPlaybackPosition()},e}(r.Component);c.SMOOTH_PLAYBACK_POSITION_UPDATE_DISABLED=-1,c.CLASS_SEEKING="seeking",e.SeekBar=c},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});!function(t){function e(e,i){void 0===i&&(i=t.FORMAT_HHMMSS);var r=e<0;r&&(e=-e);var o=Math.floor(e/3600),s=Math.floor(e/60)-60*o,a=Math.floor(e)%60;return(r?"-":"")+i.replace("hh",n(o,2)).replace("mm",n(s,2)).replace("ss",n(a,2))}function n(t,e){var n=t+"";return"0000000000".substr(0,e-n.length)+n}function i(t,e,n){var i=new RegExp("\\{(remainingTime|playedTime|adDuration)(}|%((0[1-9]\\d*(\\.\\d+(d|f)|d|f)|\\.\\d+f|d|f)|hh:mm:ss|mm:ss)})","g");return t.replace(i,function(t){var i=0;return t.indexOf("remainingTime")>-1?i=e?Math.ceil(e-n.getCurrentTime()):n.getDuration()-n.getCurrentTime():t.indexOf("playedTime")>-1?i=n.getCurrentTime():t.indexOf("adDuration")>-1&&(i=n.getDuration()),r(i,t)})}function r(t,i){var r=/%((0[1-9]\d*(\.\d+(d|f)|d|f)|\.\d+f|d|f)|hh:mm:ss|mm:ss)/,o=/(%0[1-9]\d*)(?=(\.\d+f|f|d))/,s=/\.\d*(?=f)/;r.test(i)||(i="%d");var a=0,u=i.match(o);u&&(a=parseInt(u[0].substring(2)));var c=null,h=i.match(s);if(h&&!isNaN(parseInt(h[0].substring(1)))&&(c=parseInt(h[0].substring(1)))>20&&(c=20),i.indexOf("f")>-1){var l="";return l=null!==c?t.toFixed(c):""+t,l.indexOf(".")>-1?n(l,l.length+(a-l.indexOf("."))):n(l,a)}if(i.indexOf(":")>-1){var p=Math.ceil(t);if(i.indexOf("hh")>-1)return e(p);var f=Math.floor(p/60),d=p%60;return n(f,2)+":"+n(d,2)}return n(Math.ceil(t),a)}t.FORMAT_HHMMSS="hh:mm:ss",t.FORMAT_MMSS="mm:ss",t.secondsToTime=e,t.replaceAdMessagePlaceholders=i}(e.StringUtils||(e.StringUtils={}))},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(1),o=n(16),s=n(19),a=function(t){function e(e,n){var i=t.call(this,e)||this;return i.config=i.mergeConfig(e,{cssClass:"ui-controlbar",hidden:n},i.config),i}return i(e,t),e.prototype.configure=function(e,n){t.prototype.configure.call(this,e,n);var i=this,a=0;o.UIUtils.traverseTree(this,function(t){t instanceof r.Container||t instanceof s.Spacer||t.onHoverChanged.subscribe(function(t,e){e.hovered?a++:a--})}),n.onControlsShow.subscribe(function(){i.config.hidden&&i.show()}),n.onPreviewControlsHide.subscribe(function(t,e){e.cancel=a>0}),n.onControlsHide.subscribe(function(){i.config.hidden&&i.hide()})},e}(r.Container);e.ControlBar=a},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(1);!function(t){function e(t,e){var n=function(t,r){if(e(t,r),t instanceof i.Container)for(var o=0,s=t.getComponents();oh&&(h=t,i.getDomElement().css({"min-width":h+"px"}))};e.addEventHandler(e.EVENT.ON_TIME_CHANGED,v),e.addEventHandler(e.EVENT.ON_SEEKED,v),e.addEventHandler(e.EVENT.ON_CAST_TIME_UPDATED,v),e.addEventHandler(e.EVENT.ON_TIME_SHIFT,f),e.addEventHandler(e.EVENT.ON_TIME_SHIFTED,f);var g=function(){h=0,i.getDomElement().css({"min-width":null}),i.timeFormat=Math.abs(e.isLive()?e.getMaxTimeShift():e.getDuration())>=3600?a.StringUtils.FORMAT_HHMMSS:a.StringUtils.FORMAT_MMSS,v()};e.addEventHandler(e.EVENT.ON_READY,g),g()},e.prototype.setTime=function(t,e){var n=a.StringUtils.secondsToTime(t,this.timeFormat),i=a.StringUtils.secondsToTime(e,this.timeFormat);switch(this.config.timeLabelMode){case r.CurrentTime:this.setText(""+n);break;case r.TotalTime:this.setText(""+i);break;case r.CurrentAndTotalTime:this.setText(n+" / "+i)}},e.prototype.setTimeFormat=function(t){this.timeFormat=t},e}(o.Label);e.PlaybackTimeLabel=u},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),o=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.config=n.mergeConfig(e,{cssClass:"ui-spacer"},n.config),n}return i(e,t),e.prototype.onShowEvent=function(){},e.prototype.onHideEvent=function(){},e.prototype.onHoverChangedEvent=function(t){},e}(r.Component);e.Spacer=o},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(1),o=n(7),s=n(2),a=n(14),u=n(38),c=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.timeLabel=new o.Label({cssClasses:["seekbar-label-time"]}),n.titleLabel=new o.Label({cssClasses:["seekbar-label-title"]}),n.thumbnail=new s.Component({cssClasses:["seekbar-thumbnail"]}),n.thumbnailImageLoader=new u.ImageLoader,n.config=n.mergeConfig(e,{cssClass:"ui-seekbar-label",components:[new r.Container({components:[new r.Container({components:[n.titleLabel,n.timeLabel],cssClass:"seekbar-label-metadata"})],cssClass:"seekbar-label-inner"})],hidden:!0},n.config),n}return i(e,t),e.prototype.configure=function(e,n){var i=this;t.prototype.configure.call(this,e,n),n.onSeekPreview.subscribeRateLimited(function(t,n){if(e.isLive()){var r=e.getMaxTimeShift(),o=r-r*(n.position/100);i.setTime(o)}else{var s=0;n.marker?(s=n.marker.time,i.setTitleText(n.marker.title)):(s=n.position,i.setTitleText(null));var o=e.getDuration()*(s/100);i.setTime(o),i.setThumbnail(e.getThumb(o))}},100);var r=function(){i.timeFormat=Math.abs(e.isLive()?e.getMaxTimeShift():e.getDuration())>=3600?a.StringUtils.FORMAT_HHMMSS:a.StringUtils.FORMAT_MMSS};e.addEventHandler(e.EVENT.ON_READY,r),r()},e.prototype.setText=function(t){this.timeLabel.setText(t)},e.prototype.setTime=function(t){this.setText(a.StringUtils.secondsToTime(t,this.timeFormat))},e.prototype.setTitleText=function(t){this.titleLabel.setText(t)},e.prototype.setThumbnail=function(t){void 0===t&&(t=null);var e=this.thumbnail.getDomElement();null==t?e.css({"background-image":null,display:null,width:null,height:null}):this.thumbnailImageLoader.load(t.url,function(n,i,r){var o=i/t.w,s=r/t.h,a=t.x/t.w,u=t.y/t.h,c=100*o,h=100*s,l=100*a,p=100*u,f=1/t.w*t.h;e.css({display:"inherit","background-image":"url("+t.url+")","padding-bottom":100*f+"%","background-size":c+"% "+h+"%","background-position":"-"+l+"% -"+p+"%"})})},e}(r.Container);e.SeekBarLabel=c},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(22),o=n(0),s=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.config=n.mergeConfig(e,{cssClass:"ui-selectbox"},n.config),n}return i(e,t),e.prototype.toDomElement=function(){var t=this,e=new o.DOM("select",{id:this.config.id,class:this.getCssClasses()});return this.selectElement=e,this.updateDomItems(),e.on("change",function(){var n=e.val();t.onItemSelectedEvent(n,!1)}),e},e.prototype.updateDomItems=function(t){void 0===t&&(t=null),this.selectElement.empty();for(var e=0,n=this.items;e-1},e.prototype.addItem=function(t,e){this.removeItem(t),this.items.push({key:t,label:e}),this.onItemAddedEvent(t)},e.prototype.removeItem=function(t){var e=this.getItemIndex(t);return e>-1&&(s.ArrayUtils.remove(this.items,this.items[e]),this.onItemRemovedEvent(t),!0)},e.prototype.selectItem=function(t){return t===this.selectedItem||this.getItemIndex(t)>-1&&(this.selectedItem=t,this.onItemSelectedEvent(t),!0)},e.prototype.getSelectedItem=function(){return this.selectedItem},e.prototype.clearItems=function(){var t=this.items;this.items=[],this.selectedItem=null;for(var e=0,n=t;e200&&r()},200))}),e.addEventHandler(e.EVENT.ON_PLAY,function(){s=!1});var c=function(t){t.type===e.EVENT.ON_CAST_START?i.hide():i.show()};e.addEventHandler(e.EVENT.ON_CAST_START,c),e.addEventHandler(e.EVENT.ON_CAST_STARTED,c),e.addEventHandler(e.EVENT.ON_CAST_STOPPED,c)},e.prototype.toDomElement=function(){var e=t.prototype.toDomElement.call(this);return e.append(new o.DOM("div",{class:this.prefixCss("image")})),e},e}(r.PlaybackToggleButton);e.HugePlaybackToggleButton=s},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(1),o=n(2),s=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.audioonly=[new o.Component({tag:"div",cssClass:"ui-audioonly-overlay-indicator"})],n.config=n.mergeConfig(e,{cssClass:"ui-audioonly-overlay",components:n.audioonly,hidden:!1},n.config),n}return i(e,t),e.prototype.configure=function(e,n){t.prototype.configure.call(this,e,n);var i=this;i.getDomElement().css("background-image")},e}(r.Container);e.AudioOnlyOverlay=s},function(t,e,n){n(31),n(34),t.exports=n(47)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(9),r=n(32),o=n(33);e.default=i.module("mi.BitdashPlayer",[]).controller("MiBitdashController",r.default).directive("miBitdashPlayer",o.default)},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(9),r=function(){function t(t,e){this.$scope=t,this.$log=e,this.state={},this.config={},this.options={}}return t.prototype.$onInit=function(){this.state=this.$scope.state={},i.isDefined(this.$scope.config)&&i.isDefined(this.$scope.config.key)?this.config=this.$scope.config:this.$log.error("basic config for bitdash player is missing!"),i.isDefined(this.$scope.options)&&(this.options=this.$scope.options),i.isDefined(this.$scope.webcast)&&this.processWebcast(this.$scope.webcast)},t.prototype.processWebcast=function(t){var e=t.state+"StateData";if(i.isDefined(this.options.forcedState)&&(e=this.options.forcedState+"StateData"),"ondemand"===t.state){var n=0;t.languages.some(function(e,i){if(t.language===e.language)return n=i,!0}),this.state.data=t.languages[n].ondemandStateData}else this.state.data=t[e];this.config.source=this.getPlayerConfigSource(t),this.config.style={ux:!1}},t.prototype.getPlayerConfigSource=function(t){return t.useDVRPlaybackInPostlive&&"postlive"===t.state?this.getDVRPlaybackToPostlive(t):this.getPlayerConfigSourceByState(t)},t.prototype.getDVRPlaybackToPostlive=function(t){var e=t.liveStateData.playout.hlsDvrUrl,n=t.name;if(i.isDefined(t.postliveStateData.playout.offset)){var r=parseInt(t.postliveStateData.playout.offset,10);if(r){var o=void 0,s=document.createElement("a");s.href=t.liveStateData.playout.hlsDvrUrl,o=s.search?"&":"?",e+=o+"wowzadvrplayliststart="+r+"000"}}return{hls:e,title:n}},t.prototype.getPlayerConfigSourceByState=function(t){var e=this.state.data.playout.hlsUrl,n=t.name,r=this.getHiveServiceUrlByLang(t);if(i.isDefined(this.state.data.playout.videoManagerHlsUrl)&&this.state.data.playout.videoManagerHlsUrl&&(e=this.state.data.playout.videoManagerHlsUrl),i.isDefined(this.state.data.playout.offset)){var o=parseInt(this.state.data.playout.offset,10);if(o>0){var s=void 0,a=document.createElement("a");a.href=e,s=a.search?"&":"?",e+=s+"start="+o}}return{hls:e,title:n,hiveServiceUrl:r}},t.prototype.getHiveServiceUrlByLang=function(t){var e=null;return t.languages&&t.language&&t.languages.forEach(function(n){n.language===t.language&&(e=i.copy(n.hiveServiceUrl))}),e},t}();r.$inject=["$scope","$log"],e.default=r},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(9),r=function(t,e){return{controller:"MiBitdashController",controllerAs:"bitdashVm",replace:!0,restrict:"EA",scope:{config:"=",options:"=?",webcast:"="},template:'
',link:function(n){function r(n){u.setup(n).then(function(){c=t.window.bitmovin.playerui.UIManager.Factory,o()?(c.buildAudioOnlyUI(u),s()):c.buildAudioVideoUI(u),h=a("bitmovinplayer-container"),i.isDefined(h)&&(h.style.minWidth="175px",h.style.minHeight="101px",document.getElementById("bitmovinplayer-video-mi-bitdash-player").setAttribute("title",p.name))},function(t){e.log("Error: "+t.code+" - "+t.message)})}function o(){return i.isDefined(f.playout.audioOnly)&&f.playout.audioOnly}function s(){if(i.isDefined(f.playout.audioOnlyStillUrl)&&""!==f.playout.audioOnlyStillUrl){var t=a("mi-wbc-ui-audioonly-overlay");t.style.backgroundImage="url("+f.playout.audioOnlyStillUrl+")",t.style.backgroundSize="contain",t.style.backgroundPosition="center"}}function a(t){return document.getElementsByClassName(t)[0]}var u,c,h,l=n.config,p=n.webcast,f=n.state.data;!function(){u=t.window.bitmovin.player("mi-bitdash-player"),i.isDefined(u)&&!0===u.isReady()&&(u.destroy(),u=t.window.bitmovin.player("mi-bitdash-player")),"live"===p.state&&l.source.hiveServiceUrl?(t.window.bitmovin.initHiveSDN(u,{debugLevel:"off"}),u.initSession(l.source.hiveServiceUrl).then(function(t){var e=i.copy(l);e.source.hls=t.manifest,r(e)},function(t){e.warn("Hive init fails: "+t.code+" - "+t.message),r(l)})):r(l)}()}}};e.default=r,r.$inject=["$window","$log"]},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n(35),r=n(6),o=n(15),s=n(28),a=n(18),u=n(12),c=n(13),h=n(21),l=n(42),p=n(8),f=n(25),d=n(17),v=n(1),g=n(7),y=n(2),m=n(26),b=n(20),w=n(23),E=n(43),O=n(44),S=n(27),T=n(45),k=n(24),C=n(19),R=n(4),I=n(14),P=n(5),A=n(16),N=n(11),x=n(46),_=n(29);"function"!=typeof Object.assign&&(Object.assign=function(t){if(null==t)throw new TypeError("Cannot convert undefined or null to object");t=Object(t);for(var e=1;e1)throw Error("Too many UIs without a condition: You cannot have more than one default UI");if(u.length>0&&u[0]!==this.uiVariants[this.uiVariants.length-1])throw Error("Invalid UI variant order: the default UI (without condition) must be at the end of the list");var p=null,f=S.BrowserUtils.isMobile,d=function(e){if(null!=e)switch(e.type){case t.EVENT.ON_AD_STARTED:p=e;break;case t.EVENT.ON_AD_FINISHED:case t.EVENT.ON_AD_SKIPPED:case t.EVENT.ON_AD_ERROR:p=null;break;case t.EVENT.ON_READY:p&&!t.isAd()&&(p=null)}for(var n=null!=p,r=n&&"vast"===p.clientType,o={isAd:n,isAdWithUI:r,adClientType:n?p.clientType:null,isFullscreen:i.player.isFullscreen(),isMobile:f,isPlaying:i.player.isPlaying(),width:i.uiContainerElement.width(),documentWidth:document.body.clientWidth},s=null,a=!1,u=0,c=i.uiVariants;uc){r=i.getDomElement().height()/e.CEA608_NUM_ROWS;var h=i.getDomElement().width()/e.CEA608_NUM_COLUMNS;o=h-r*a}else r=i.getDomElement().width()/e.CEA608_NUM_COLUMNS/a,o=0;for(var l=0,p=i.getComponents();l0?i.map(function(t){return t.label}):null},t.prototype.cueExit=function(e){var n=t.calculateId(e),i=this.activeSubtitleCueMap[n];if(i&&i.length>0){var r=i.shift();return this.activeSubtitleCueCount--,r.label}return null},Object.defineProperty(t.prototype,"cueCount",{get:function(){return this.activeSubtitleCueCount},enumerable:!0,configurable:!0}),Object.defineProperty(t.prototype,"hasCues",{get:function(){return this.cueCount>0},enumerable:!0,configurable:!0}),t.prototype.clear=function(){this.activeSubtitleCueMap={},this.activeSubtitleCueCount=0},t}()},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(2),o=n(0),s=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.canvasWidth=160,n.canvasHeight=90,n.interferenceHeight=50,n.lastFrameUpdate=0,n.frameInterval=60,n.useAnimationFrame=!!window.requestAnimationFrame,n.config=n.mergeConfig(e,{cssClass:"ui-tvnoisecanvas"},n.config),n}return i(e,t),e.prototype.toDomElement=function(){return this.canvas=new o.DOM("canvas",{class:this.getCssClasses()})},e.prototype.start=function(){this.canvasElement=this.canvas.get(0),this.canvasContext=this.canvasElement.getContext("2d"),this.noiseAnimationWindowPos=-this.canvasHeight,this.lastFrameUpdate=0,this.canvasElement.width=this.canvasWidth,this.canvasElement.height=this.canvasHeight,this.renderFrame()},e.prototype.stop=function(){this.useAnimationFrame?cancelAnimationFrame(this.frameUpdateHandlerId):clearTimeout(this.frameUpdateHandlerId)},e.prototype.renderFrame=function(){if(this.lastFrameUpdate+this.frameInterval>(new Date).getTime())return void this.scheduleNextRender();for(var t,e=this.canvasWidth,n=this.canvasHeight,i=this.canvasContext.createImageData(e,n),r=0;rthis.noiseAnimationWindowPos+this.interferenceHeight)&&(i.data[t]*=.85),i.data[t+1]=i.data[t],i.data[t+2]=i.data[t],i.data[t+3]=50;this.canvasContext.putImageData(i,0,0),this.lastFrameUpdate=(new Date).getTime(),this.noiseAnimationWindowPos+=7,this.noiseAnimationWindowPos>n&&(this.noiseAnimationWindowPos=-n),this.scheduleNextRender()},e.prototype.scheduleNextRender=function(){this.useAnimationFrame?this.frameUpdateHandlerId=window.requestAnimationFrame(this.renderFrame.bind(this)):this.frameUpdateHandlerId=setTimeout(this.renderFrame.bind(this),this.frameInterval)},e}(r.Component);e.TvNoiseCanvas=s},function(t,e,n){"use strict";var i=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n])};return function(e,n){function i(){this.constructor=e}t(e,n),e.prototype=null===n?Object.create(n):(i.prototype=n.prototype,new i)}}();Object.defineProperty(e,"__esModule",{value:!0});var r=n(22),o=n(0),s=function(t){function e(e){void 0===e&&(e={});var n=t.call(this,e)||this;return n.config=n.mergeConfig(e,{tag:"ul",cssClass:"ui-itemselectionlist"},n.config),n}return i(e,t),e.prototype.isActive=function(){return this.items.length>1},e.prototype.toDomElement=function(){var t=new o.DOM("ul",{id:this.config.id,class:this.getCssClasses()});return this.listElement=t,this.updateDomItems(),t},e.prototype.updateDomItems=function(t){var n=this;void 0===t&&(t=null),this.listElement.empty();for(var i=null,r=function(t){t.addClass(n.prefixCss(e.CLASS_SELECTED))},s=function(t){t.removeClass(n.prefixCss(e.CLASS_SELECTED))},a=this,u=0,c=this.items;u { + if (webcast.language === lang.language) { + languageIndex = index; + return true; + } + }); + + this.state.data = webcast.languages[languageIndex].ondemandStateData; + } else { + this.state.data = webcast[stateProperty]; + } + + this.config.source = this.getPlayerConfigSource(webcast); this.config.style = {ux: false}; } - public getPlayerConfigSource(webcast: any , state: any): any { - if ((webcast.useDVRPlaybackInPostlive === true) && (state === 'postliveStateData')) { - return this.getDVRPlaybackToPostlive(webcast); - } - return this.getPlayerConfigSourceByState(webcast, state); + private getPlayerConfigSource(webcast: any): any { + return webcast.useDVRPlaybackInPostlive && webcast.state === 'postlive' ? + this.getDVRPlaybackToPostlive(webcast) + : this.getPlayerConfigSourceByState(webcast) + ; } - public getDVRPlaybackToPostlive(webcast: any): any { + private getDVRPlaybackToPostlive(webcast: any): any { let hls: string = webcast['liveStateData'].playout.hlsDvrUrl; const title: string = webcast.name; if (angular.isDefined(webcast['postliveStateData'].playout.offset)) { const offset: number = parseInt(webcast['postliveStateData'].playout.offset, 10); - if (offset > 0) { + if (offset) { let offsetPrefix: string; const parser = document.createElement('a'); parser.href = webcast['liveStateData'].playout.hlsDvrUrl; @@ -63,17 +79,17 @@ class BitmovinController { return {hls, title}; } - public getPlayerConfigSourceByState(webcast: any, state: any): any { - let hls: string = webcast[state].playout.hlsUrl; + private getPlayerConfigSourceByState(webcast: any): any { + let hls: string = this.state.data.playout.hlsUrl; const title: string = webcast.name; const hiveServiceUrl: string = this.getHiveServiceUrlByLang(webcast); - if (angular.isDefined(webcast[state].playout.videoManagerHlsUrl) && webcast[state].playout.videoManagerHlsUrl) { - hls = webcast[state].playout.videoManagerHlsUrl; + if (angular.isDefined(this.state.data.playout.videoManagerHlsUrl) && this.state.data.playout.videoManagerHlsUrl) { + hls = this.state.data.playout.videoManagerHlsUrl; } - if (angular.isDefined(webcast[state].playout.offset)) { - const offset: number = parseInt(webcast[state].playout.offset, 10); + if (angular.isDefined(this.state.data.playout.offset)) { + const offset: number = parseInt(this.state.data.playout.offset, 10); if (offset > 0) { let offsetPrefix: string; @@ -86,7 +102,7 @@ class BitmovinController { return {hls, title, hiveServiceUrl}; } - public getHiveServiceUrlByLang(webcast: any): string { + private getHiveServiceUrlByLang(webcast: any): string { let hiveServiceUrl = null; if (webcast.languages && webcast.language) { webcast.languages.forEach((item: any) => { diff --git a/src/bitdash-directive.ts b/src/bitdash-directive.ts index f9d1738..bb1f7ce 100644 --- a/src/bitdash-directive.ts +++ b/src/bitdash-directive.ts @@ -18,7 +18,7 @@ const BitdashDirective = ($window: IWindow, $log: angular.ILogService) => ({ let bitmovinControlbar: IMyElement; const config: IConfig = scope.config; const webcast: any = scope.webcast; - const state: string = `${scope.webcast.state}StateData`; + const stateData: any = scope.state.data; buildPlayer(); function buildPlayer(): void { @@ -28,7 +28,7 @@ const BitdashDirective = ($window: IWindow, $log: angular.ILogService) => ({ bitmovinPlayer = $window.window.bitmovin.player('mi-bitdash-player'); } - if ((state === 'liveStateData') && config.source.hiveServiceUrl) { + if ((webcast.state === 'live') && config.source.hiveServiceUrl) { // Get a hive-enabled player through bitdash.initHiveSDN $window.window.bitmovin.initHiveSDN(bitmovinPlayer, {debugLevel: 'off'}); // Configure and Setup bitmovin in initSession callback @@ -70,15 +70,15 @@ const BitdashDirective = ($window: IWindow, $log: angular.ILogService) => ({ } function isAudioOnly(): boolean { - return angular.isDefined(scope.webcast[state].playout.audioOnly) && - scope.webcast[state].playout.audioOnly; + return angular.isDefined(stateData.playout.audioOnly) && + stateData.playout.audioOnly; } function setAudioOnlyStillImage(): void { - if (angular.isDefined(scope.webcast[state].playout.audioOnlyStillUrl) && - scope.webcast[state].playout.audioOnlyStillUrl !== '') { + if (angular.isDefined(stateData.playout.audioOnlyStillUrl) && + stateData.playout.audioOnlyStillUrl !== '') { const element = getElementsByClassName('mi-wbc-ui-audioonly-overlay') as IMyElement; - element.style.backgroundImage = `url(${scope.webcast[state].playout.audioOnlyStillUrl})`; + element.style.backgroundImage = `url(${stateData.playout.audioOnlyStillUrl})`; element.style.backgroundSize = 'contain'; element.style.backgroundPosition = 'center'; } diff --git a/test/bitdash-controller.spec.ts b/test/bitdash-controller.spec.ts index aad8e4f..180c16b 100644 --- a/test/bitdash-controller.spec.ts +++ b/test/bitdash-controller.spec.ts @@ -2,6 +2,7 @@ declare const angular; import BitdashController from './../src/bitdash-controller'; describe('BitdashController', () => { + let $rootScope: angular.IRootScopeService; let createController: any, locals: object = {}, $log: angular.ILogService, @@ -11,6 +12,7 @@ describe('BitdashController', () => { beforeEach(() => { angular.mock.inject(($injector: ng.auto.IInjectorService) => { $controller = $injector.get('$controller'); + $rootScope = $injector.get('$rootScope') as angular.IRootScopeService; $log = jasmine.createSpyObj('$log', ['error']); $scope = { config: {key: '123456879'}, @@ -24,6 +26,12 @@ describe('BitdashController', () => { hiveServiceUrl: 'https://api-test.hivestreaming.com/v1/events/9021/597f2ca593768a02465dGxK', hiveTicketId: 'sohJ3g8isHjlJGxK', language: 'de', + ondemandStateData: { + playout: { + hlsUrl: 'http://ondemand/master.m3u8', + offset: 0 + } + }, presentations: [] } ], @@ -155,4 +163,22 @@ describe('BitdashController', () => { expect(vm.config.source.hls).toBe('https://live-origin.edge-cdn.net/webcast/myStream/master.m3u8'); }); + it('should configure the player in ondemand with valid language', () => { + $scope.webcast.state = 'ondemand'; + $scope.webcast.languages.findIndex = jasmine.createSpy('findIndex').and.callFake(() => 0); + + const vm = new createController(); + vm.$onInit(); + expect(vm.state.data).toEqual({playout: {hlsUrl: 'http://ondemand/master.m3u8', offset: 0}}); + }); + + it('should configure the player in ondemand with invalid language', () => { + $scope.webcast.state = 'ondemand'; + $scope.webcast.languages.findIndex = jasmine.createSpy('findIndex').and.callFake(() => -1); + + const vm = new createController(); + vm.$onInit(); + expect(vm.state.data).toEqual({playout: {hlsUrl: 'http://ondemand/master.m3u8', offset: 0}}); + }); + }); diff --git a/test/bitdash-directive.spec.ts b/test/bitdash-directive.spec.ts index aac8241..0c04e11 100644 --- a/test/bitdash-directive.spec.ts +++ b/test/bitdash-directive.spec.ts @@ -12,6 +12,8 @@ describe('BitdashDirective', () => { let $rootScope: IRootScope; let $log: angular.ILogService; let template: string = ``; + let configMock; + let stateMock; const playerFuncSpy: string [] = ['isReady', 'setup', 'destroy', 'initSession']; const playerUISpy: string [] = ['buildAudioOnlyUI', 'buildAudioVideoUI']; @@ -36,9 +38,17 @@ describe('BitdashDirective', () => {
`); beforeEach(() => { + stateMock = { + data: { + playout: { + audioOnly: false + } + } + }; + angular.mock.module(($compileProvider: any, $controllerProvider: any, $provide: any) => { $compileProvider.directive('miBitdashPlayer', BitdashDirective); - $controllerProvider.register('MiBitdashController', () => { return; }); + $controllerProvider.register('MiBitdashController', ($scope) => { $scope.state = stateMock; return; }); $provide.value('document', documentSpy); $provide.value('$window', windowSpy); }); @@ -48,8 +58,16 @@ describe('BitdashDirective', () => { $rootScope = $injector.get('$rootScope') as IRootScope; $log = $injector.get('$log'); }); + + configMock = { + foo: 'bar', + source: { + hiveServiceUrl: null + } + }; + $rootScope.webcastMainVm = { - playerConfig: {foo: 'bar', source: {hiveServiceUrl: null}}, + playerConfig: configMock, webcast: { liveStateData: { playout: { @@ -75,7 +93,7 @@ describe('BitdashDirective', () => { bitmovinPlayer.isReady.and.returnValue(false); $compile(template)($rootScope); $rootScope.$apply(); - expect(bitmovinPlayer.setup).toHaveBeenCalledWith({foo: 'bar', source: {hiveServiceUrl: null}}); + expect(bitmovinPlayer.setup).toHaveBeenCalledWith(configMock); expect(bitmovinPlayer.destroy).not.toHaveBeenCalled(); expect(document.getElementsByClassName).not.toHaveBeenCalled(); expect(Factory.buildAudioVideoUI).not.toHaveBeenCalled(); @@ -87,7 +105,7 @@ describe('BitdashDirective', () => { spyOn(document, 'getElementById').and.callThrough(); $compile(template)($rootScope); $rootScope.$apply(); - expect(bitmovinPlayer.setup).toHaveBeenCalledWith({foo: 'bar', source: {hiveServiceUrl: null}}); + expect(bitmovinPlayer.setup).toHaveBeenCalledWith(configMock); expect(bitmovinPlayer.destroy).toHaveBeenCalled(); expect(document.getElementsByClassName).toHaveBeenCalledTimes(1); expect(document.getElementsByClassName).toHaveBeenCalledWith('bitmovinplayer-container'); @@ -100,10 +118,10 @@ describe('BitdashDirective', () => { it('Should set up the player for audio only', () => { spyOn(document, 'getElementsByClassName').and.callThrough(); - $rootScope.webcastMainVm.webcast.postliveStateData.playout.audioOnly = true; + stateMock.data.playout.audioOnly = true; $compile(template)($rootScope); $rootScope.$apply(); - expect(bitmovinPlayer.setup).toHaveBeenCalledWith({foo: 'bar', source: {hiveServiceUrl: null}}); + expect(bitmovinPlayer.setup).toHaveBeenCalledWith(configMock); expect(bitmovinPlayer.destroy).toHaveBeenCalled(); expect(document.getElementsByClassName).toHaveBeenCalledTimes(1); expect((document.getElementsByClassName('bitmovinplayer-container')[0] as IMyElement).style.minWidth).toEqual('175px'); @@ -113,11 +131,11 @@ describe('BitdashDirective', () => { it('Should set up the player for audio only with default StillImageUrl', () => { spyOn(document, 'getElementsByClassName').and.callThrough(); - $rootScope.webcastMainVm.webcast.postliveStateData.playout.audioOnly = true; - $rootScope.webcastMainVm.webcast.postliveStateData.playout.audioOnlyStillUrl = 'https://www.ima.ge/image.jpg'; + stateMock.data.playout.audioOnly = true; + stateMock.data.playout.audioOnlyStillUrl = 'https://www.ima.ge/image.jpg'; $compile(template)($rootScope); $rootScope.$apply(); - expect(bitmovinPlayer.setup).toHaveBeenCalledWith({foo: 'bar', source: {hiveServiceUrl: null}}); + expect(bitmovinPlayer.setup).toHaveBeenCalledWith(configMock); expect(bitmovinPlayer.destroy).toHaveBeenCalled(); expect(document.getElementsByClassName).toHaveBeenCalledTimes(2); expect((document.getElementsByClassName('bitmovinplayer-container')[0] as IMyElement).style.minWidth) @@ -180,11 +198,11 @@ describe('BitdashDirective', () => { $rootScope.webcastMainVm.webcast.state = 'live'; $rootScope.webcastMainVm.webcast.liveStateData.playout.audioOnly = false; $rootScope.webcastMainVm.playerConfig.source.hiveServiceUrl = 'https://api-test.hivestreaming.com/v1/events/9021/597f'; + configMock.source.hiveServiceUrl = 'https://api-test.hivestreaming.com/v1/events/9021/597f'; spyOn(document, 'getElementsByClassName').and.callThrough(); $compile(template)($rootScope); $rootScope.$apply(); - expect(bitmovinPlayer.setup).toHaveBeenCalledWith({foo: 'bar', source: { - hiveServiceUrl: 'https://api-test.hivestreaming.com/v1/events/9021/597f'}}); + expect(bitmovinPlayer.setup).toHaveBeenCalledWith(configMock); expect(bitmovinPlayer.destroy).toHaveBeenCalled(); expect(document.getElementsByClassName).toHaveBeenCalledTimes(1); expect(document.getElementsByClassName).toHaveBeenCalledWith('bitmovinplayer-container'); @@ -198,11 +216,12 @@ describe('BitdashDirective', () => { $rootScope.webcastMainVm.webcast.state = 'live'; $rootScope.webcastMainVm.webcast.liveStateData.playout.audioOnly = false; $rootScope.webcastMainVm.playerConfig.source.hiveServiceUrl = 'https://api-test.hivestreaming.com/v1/events/9021/597f'; + configMock.source.hiveServiceUrl = 'https://api-test.hivestreaming.com/v1/events/9021/597f'; + configMock.source.hls = 'https://api-hive.hive'; spyOn(document, 'getElementsByClassName').and.callThrough(); $compile(template)($rootScope); $rootScope.$apply(); - expect(bitmovinPlayer.setup).toHaveBeenCalledWith({foo: 'bar', source: { - hiveServiceUrl: 'https://api-test.hivestreaming.com/v1/events/9021/597f', hls: 'https://api-hive.hive'}}); + expect(bitmovinPlayer.setup).toHaveBeenCalledWith(configMock); expect(bitmovinPlayer.destroy).toHaveBeenCalled(); expect(document.getElementsByClassName).toHaveBeenCalledTimes(1); expect(document.getElementsByClassName).toHaveBeenCalledWith('bitmovinplayer-container');