diff --git a/.vscode/launch.json b/.vscode/launch.json
new file mode 100644
index 0000000000..709b5a4b10
--- /dev/null
+++ b/.vscode/launch.json
@@ -0,0 +1,14 @@
+{
+ // Используйте IntelliSense, чтобы узнать о возможных атрибутах.
+ // Наведите указатель мыши, чтобы просмотреть описания существующих атрибутов.
+ // Для получения дополнительной информации посетите: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "node",
+ "request": "launch",
+ "name": "Launch Program",
+ "program": "${workspaceFolder}\\server.js"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/benchmark/index.html b/benchmark/index.html
new file mode 100644
index 0000000000..4c89ec5ede
--- /dev/null
+++ b/benchmark/index.html
@@ -0,0 +1,275 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/cyclejs/.babelrc b/examples/cyclejs/.babelrc
new file mode 100644
index 0000000000..831f20a8e5
--- /dev/null
+++ b/examples/cyclejs/.babelrc
@@ -0,0 +1,4 @@
+{
+ "presets": ["es2015"],
+ "plugins": ["transform-object-rest-spread"]
+}
diff --git a/examples/cyclejs/.editorconfig b/examples/cyclejs/.editorconfig
new file mode 100644
index 0000000000..442d28d0cf
--- /dev/null
+++ b/examples/cyclejs/.editorconfig
@@ -0,0 +1,7 @@
+; editorconfig.org
+root = true
+
+[*]
+indent_style = space
+indent_size = 2
+end_of_line = LF
\ No newline at end of file
diff --git a/examples/cyclejs/.gitignore b/examples/cyclejs/.gitignore
new file mode 100644
index 0000000000..30caf22711
--- /dev/null
+++ b/examples/cyclejs/.gitignore
@@ -0,0 +1,4 @@
+.idea/
+ignore/
+node_modules/
+npm-debug.log
diff --git a/examples/cyclejs/LICENSE b/examples/cyclejs/LICENSE
new file mode 100644
index 0000000000..76dc4b5250
--- /dev/null
+++ b/examples/cyclejs/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 André Staltz
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/examples/cyclejs/README.md b/examples/cyclejs/README.md
new file mode 100644
index 0000000000..6181be490f
--- /dev/null
+++ b/examples/cyclejs/README.md
@@ -0,0 +1,10 @@
+TodoMVC in Cycle.js
+===================
+
+TodoMVC example implemented in [Cycle.js](http://cycle.js.org).
+
+[Open the app]( http://cycle.js.org/todomvc-cycle/ )
+
+- - -
+
+To see a version of this codebase using Immutable.js, [click here](https://github.com/cyclejs/todomvc-cycle/pull/9/files).
diff --git a/examples/cyclejs/index.html b/examples/cyclejs/index.html
new file mode 100644
index 0000000000..5be41b1ad1
--- /dev/null
+++ b/examples/cyclejs/index.html
@@ -0,0 +1,19 @@
+
+
+
+
+ Cycle • TodoMVC
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/cyclejs/js/app.js b/examples/cyclejs/js/app.js
new file mode 100644
index 0000000000..d4ad604ff0
--- /dev/null
+++ b/examples/cyclejs/js/app.js
@@ -0,0 +1,12327 @@
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 0) {
+ topNode = this.isolateModule.getIsolatedElement(scope) || rootElement;
+ if (selector && matchesSelector(topNode, selector)) {
+ topNodeMatches.push(topNode);
+ }
+ }
+ return toElArray(topNode.querySelectorAll(selector))
+ .filter(scopeChecker.isStrictlyInRootScope, scopeChecker)
+ .concat(topNodeMatches);
+ };
+ return ElementFinder;
+}());
+exports.ElementFinder = ElementFinder;
+
+},{"./ScopeChecker":6,"./utils":19,"matches-selector":21}],3:[function(require,module,exports){
+"use strict";
+var ScopeChecker_1 = require('./ScopeChecker');
+var utils_1 = require('./utils');
+var matchesSelector;
+try {
+ matchesSelector = require("matches-selector");
+}
+catch (e) {
+ matchesSelector = Function.prototype;
+}
+/**
+ * Attaches an actual event listener to the DOM root element,
+ * handles "destinations" (interested DOMSource output subjects), and bubbling.
+ */
+var EventDelegator = (function () {
+ function EventDelegator(topElement, eventType, useCapture, isolateModule) {
+ var _this = this;
+ this.topElement = topElement;
+ this.eventType = eventType;
+ this.useCapture = useCapture;
+ this.isolateModule = isolateModule;
+ this.destinations = [];
+ this.roof = topElement.parentElement;
+ if (useCapture) {
+ this.domListener = function (ev) { return _this.capture(ev); };
+ }
+ else {
+ this.domListener = function (ev) { return _this.bubble(ev); };
+ }
+ topElement.addEventListener(eventType, this.domListener, useCapture);
+ }
+ EventDelegator.prototype.bubble = function (rawEvent) {
+ if (!document.body.contains(rawEvent.currentTarget)) {
+ return;
+ }
+ var ev = this.patchEvent(rawEvent);
+ for (var el = ev.target; el && el !== this.roof; el = el.parentElement) {
+ if (ev.propagationHasBeenStopped) {
+ return;
+ }
+ this.matchEventAgainstDestinations(el, ev);
+ }
+ };
+ EventDelegator.prototype.matchEventAgainstDestinations = function (el, ev) {
+ for (var i = 0, n = this.destinations.length; i < n; i++) {
+ var dest = this.destinations[i];
+ if (!dest.scopeChecker.isStrictlyInRootScope(el)) {
+ continue;
+ }
+ if (matchesSelector(el, dest.selector)) {
+ this.mutateEventCurrentTarget(ev, el);
+ dest.subject._n(ev);
+ }
+ }
+ };
+ EventDelegator.prototype.capture = function (ev) {
+ for (var i = 0, n = this.destinations.length; i < n; i++) {
+ var dest = this.destinations[i];
+ if (matchesSelector(ev.target, dest.selector)) {
+ dest.subject._n(ev);
+ }
+ }
+ };
+ EventDelegator.prototype.addDestination = function (subject, namespace) {
+ var scope = utils_1.getScope(namespace);
+ var selector = utils_1.getSelectors(namespace);
+ var scopeChecker = new ScopeChecker_1.ScopeChecker(scope, this.isolateModule);
+ this.destinations.push({ subject: subject, scopeChecker: scopeChecker, selector: selector });
+ };
+ EventDelegator.prototype.patchEvent = function (event) {
+ var pEvent = event;
+ pEvent.propagationHasBeenStopped = false;
+ var oldStopPropagation = pEvent.stopPropagation;
+ pEvent.stopPropagation = function stopPropagation() {
+ oldStopPropagation.call(this);
+ this.propagationHasBeenStopped = true;
+ };
+ return pEvent;
+ };
+ EventDelegator.prototype.mutateEventCurrentTarget = function (event, currentTargetElement) {
+ try {
+ Object.defineProperty(event, "currentTarget", {
+ value: currentTargetElement,
+ configurable: true,
+ });
+ }
+ catch (err) {
+ console.log("please use event.ownerTarget");
+ }
+ event.ownerTarget = currentTargetElement;
+ };
+ EventDelegator.prototype.updateTopElement = function (newTopElement) {
+ this.topElement.removeEventListener(this.eventType, this.domListener, this.useCapture);
+ newTopElement.addEventListener(this.eventType, this.domListener, this.useCapture);
+ this.topElement = newTopElement;
+ };
+ return EventDelegator;
+}());
+exports.EventDelegator = EventDelegator;
+
+},{"./ScopeChecker":6,"./utils":19,"matches-selector":21}],4:[function(require,module,exports){
+"use strict";
+var xstream_1 = require('xstream');
+var xstream_adapter_1 = require('@cycle/xstream-adapter');
+var HTMLSource = (function () {
+ function HTMLSource(html$, runSA) {
+ this.runSA = runSA;
+ this._html$ = html$;
+ this._empty$ = runSA.adapt(xstream_1.default.empty(), xstream_adapter_1.default.streamSubscribe);
+ }
+ HTMLSource.prototype.elements = function () {
+ return this.runSA.adapt(this._html$, xstream_adapter_1.default.streamSubscribe);
+ };
+ HTMLSource.prototype.select = function (selector) {
+ return new HTMLSource(xstream_1.default.empty(), this.runSA);
+ };
+ HTMLSource.prototype.events = function (eventType, options) {
+ return this._empty$;
+ };
+ return HTMLSource;
+}());
+exports.HTMLSource = HTMLSource;
+
+},{"@cycle/xstream-adapter":20,"xstream":115}],5:[function(require,module,exports){
+"use strict";
+var xstream_adapter_1 = require('@cycle/xstream-adapter');
+var xstream_1 = require('xstream');
+var ElementFinder_1 = require('./ElementFinder');
+var fromEvent_1 = require('./fromEvent');
+var isolate_1 = require('./isolate');
+var EventDelegator_1 = require('./EventDelegator');
+var utils_1 = require('./utils');
+var matchesSelector;
+try {
+ matchesSelector = require("matches-selector");
+}
+catch (e) {
+ matchesSelector = Function.prototype;
+}
+var eventTypesThatDontBubble = [
+ "load",
+ "unload",
+ "focus",
+ "blur",
+ "mouseenter",
+ "mouseleave",
+ "submit",
+ "change",
+ "reset",
+ "timeupdate",
+ "playing",
+ "waiting",
+ "seeking",
+ "seeked",
+ "ended",
+ "loadedmetadata",
+ "loadeddata",
+ "canplay",
+ "canplaythrough",
+ "durationchange",
+ "play",
+ "pause",
+ "ratechange",
+ "volumechange",
+ "suspend",
+ "emptied",
+ "stalled",
+];
+function determineUseCapture(eventType, options) {
+ var result = false;
+ if (typeof options.useCapture === "boolean") {
+ result = options.useCapture;
+ }
+ if (eventTypesThatDontBubble.indexOf(eventType) !== -1) {
+ result = true;
+ }
+ return result;
+}
+var MainDOMSource = (function () {
+ function MainDOMSource(_rootElement$, _runStreamAdapter, _namespace, _isolateModule, _delegators) {
+ if (_namespace === void 0) { _namespace = []; }
+ this._rootElement$ = _rootElement$;
+ this._runStreamAdapter = _runStreamAdapter;
+ this._namespace = _namespace;
+ this._isolateModule = _isolateModule;
+ this._delegators = _delegators;
+ this.isolateSource = isolate_1.isolateSource;
+ this.isolateSink = isolate_1.isolateSink;
+ }
+ MainDOMSource.prototype.elements = function () {
+ var output$;
+ if (this._namespace.length === 0) {
+ output$ = this._rootElement$;
+ }
+ else {
+ var elementFinder_1 = new ElementFinder_1.ElementFinder(this._namespace, this._isolateModule);
+ output$ = this._rootElement$.map(function (el) { return elementFinder_1.call(el); });
+ }
+ var runSA = this._runStreamAdapter;
+ return runSA.remember(runSA.adapt(output$, xstream_adapter_1.default.streamSubscribe));
+ };
+ Object.defineProperty(MainDOMSource.prototype, "namespace", {
+ get: function () {
+ return this._namespace;
+ },
+ enumerable: true,
+ configurable: true
+ });
+ MainDOMSource.prototype.select = function (selector) {
+ if (typeof selector !== 'string') {
+ throw new Error("DOM driver's select() expects the argument to be a " +
+ "string as a CSS selector");
+ }
+ var trimmedSelector = selector.trim();
+ var childNamespace = trimmedSelector === ":root" ?
+ this._namespace :
+ this._namespace.concat(trimmedSelector);
+ return new MainDOMSource(this._rootElement$, this._runStreamAdapter, childNamespace, this._isolateModule, this._delegators);
+ };
+ MainDOMSource.prototype.events = function (eventType, options) {
+ if (options === void 0) { options = {}; }
+ if (typeof eventType !== "string") {
+ throw new Error("DOM driver's events() expects argument to be a " +
+ "string representing the event type to listen for.");
+ }
+ var useCapture = determineUseCapture(eventType, options);
+ var namespace = this._namespace;
+ var scope = utils_1.getScope(namespace);
+ var keyParts = [eventType, useCapture];
+ if (scope) {
+ keyParts.push(scope);
+ }
+ var key = keyParts.join('~');
+ var domSource = this;
+ var rootElement$;
+ if (scope) {
+ var hadIsolated_mutable_1 = false;
+ rootElement$ = this._rootElement$
+ .filter(function (rootElement) {
+ var hasIsolated = !!domSource._isolateModule.getIsolatedElement(scope);
+ var shouldPass = hasIsolated && !hadIsolated_mutable_1;
+ hadIsolated_mutable_1 = hasIsolated;
+ return shouldPass;
+ });
+ }
+ else {
+ rootElement$ = this._rootElement$.take(2);
+ }
+ var event$ = rootElement$
+ .map(function setupEventDelegatorOnTopElement(rootElement) {
+ // Event listener just for the root element
+ if (!namespace || namespace.length === 0) {
+ return fromEvent_1.fromEvent(rootElement, eventType, useCapture);
+ }
+ // Event listener on the top element as an EventDelegator
+ var delegators = domSource._delegators;
+ var top = scope
+ ? domSource._isolateModule.getIsolatedElement(scope)
+ : rootElement;
+ var delegator;
+ if (delegators.has(key)) {
+ delegator = delegators.get(key);
+ delegator.updateTopElement(top);
+ }
+ else {
+ delegator = new EventDelegator_1.EventDelegator(top, eventType, useCapture, domSource._isolateModule);
+ delegators.set(key, delegator);
+ }
+ var subject = xstream_1.default.create();
+ if (scope) {
+ domSource._isolateModule.addEventDelegator(scope, delegator);
+ }
+ delegator.addDestination(subject, namespace);
+ return subject;
+ })
+ .flatten();
+ return this._runStreamAdapter.adapt(event$, xstream_adapter_1.default.streamSubscribe);
+ };
+ MainDOMSource.prototype.dispose = function () {
+ this._isolateModule.reset();
+ };
+ return MainDOMSource;
+}());
+exports.MainDOMSource = MainDOMSource;
+
+},{"./ElementFinder":2,"./EventDelegator":3,"./fromEvent":8,"./isolate":12,"./utils":19,"@cycle/xstream-adapter":20,"matches-selector":21,"xstream":115}],6:[function(require,module,exports){
+"use strict";
+var ScopeChecker = (function () {
+ function ScopeChecker(scope, isolateModule) {
+ this.scope = scope;
+ this.isolateModule = isolateModule;
+ }
+ ScopeChecker.prototype.isStrictlyInRootScope = function (leaf) {
+ for (var el = leaf; el; el = el.parentElement) {
+ var scope = this.isolateModule.isIsolatedElement(el);
+ if (scope && scope !== this.scope) {
+ return false;
+ }
+ if (scope) {
+ return true;
+ }
+ }
+ return true;
+ };
+ return ScopeChecker;
+}());
+exports.ScopeChecker = ScopeChecker;
+
+},{}],7:[function(require,module,exports){
+"use strict";
+var hyperscript_1 = require('./hyperscript');
+var classNameFromVNode_1 = require('snabbdom-selector/lib/classNameFromVNode');
+var selectorParser_1 = require('snabbdom-selector/lib/selectorParser');
+var VNodeWrapper = (function () {
+ function VNodeWrapper(rootElement) {
+ this.rootElement = rootElement;
+ }
+ VNodeWrapper.prototype.call = function (vnode) {
+ var _a = selectorParser_1.default(vnode.sel), selectorTagName = _a.tagName, selectorId = _a.id;
+ var vNodeClassName = classNameFromVNode_1.default(vnode);
+ var vNodeData = vnode.data || {};
+ var vNodeDataProps = vNodeData.props || {};
+ var _b = vNodeDataProps.id, vNodeId = _b === void 0 ? selectorId : _b;
+ var isVNodeAndRootElementIdentical = vNodeId.toUpperCase() === this.rootElement.id.toUpperCase() &&
+ selectorTagName.toUpperCase() === this.rootElement.tagName.toUpperCase() &&
+ vNodeClassName.toUpperCase() === this.rootElement.className.toUpperCase();
+ if (isVNodeAndRootElementIdentical) {
+ return vnode;
+ }
+ var _c = this.rootElement, tagName = _c.tagName, id = _c.id, className = _c.className;
+ var elementId = id ? "#" + id : "";
+ var elementClassName = className ?
+ "." + className.split(" ").join(".") : "";
+ return hyperscript_1.h("" + tagName + elementId + elementClassName, {}, [vnode]);
+ };
+ return VNodeWrapper;
+}());
+exports.VNodeWrapper = VNodeWrapper;
+
+},{"./hyperscript":10,"snabbdom-selector/lib/classNameFromVNode":22,"snabbdom-selector/lib/selectorParser":23}],8:[function(require,module,exports){
+"use strict";
+var xstream_1 = require('xstream');
+function fromEvent(element, eventName, useCapture) {
+ if (useCapture === void 0) { useCapture = false; }
+ return xstream_1.Stream.create({
+ element: element,
+ next: null,
+ start: function start(listener) {
+ this.next = function next(event) { listener.next(event); };
+ this.element.addEventListener(eventName, this.next, useCapture);
+ },
+ stop: function stop() {
+ this.element.removeEventListener(eventName, this.next, useCapture);
+ }
+ });
+}
+exports.fromEvent = fromEvent;
+
+},{"xstream":115}],9:[function(require,module,exports){
+"use strict";
+var hyperscript_1 = require('./hyperscript');
+function isValidString(param) {
+ return typeof param === 'string' && param.length > 0;
+}
+function isSelector(param) {
+ return isValidString(param) && (param[0] === '.' || param[0] === '#');
+}
+function createTagFunction(tagName) {
+ return function hyperscript(first, b, c) {
+ if (isSelector(first)) {
+ if (!!b && !!c) {
+ return hyperscript_1.h(tagName + first, b, c);
+ }
+ else if (!!b) {
+ return hyperscript_1.h(tagName + first, b);
+ }
+ else {
+ return hyperscript_1.h(tagName + first, {});
+ }
+ }
+ else if (!!b) {
+ return hyperscript_1.h(tagName, first, b);
+ }
+ else if (!!first) {
+ return hyperscript_1.h(tagName, first);
+ }
+ else {
+ return hyperscript_1.h(tagName, {});
+ }
+ };
+}
+var SVG_TAG_NAMES = [
+ 'a', 'altGlyph', 'altGlyphDef', 'altGlyphItem', 'animate', 'animateColor',
+ 'animateMotion', 'animateTransform', 'circle', 'clipPath', 'colorProfile',
+ 'cursor', 'defs', 'desc', 'ellipse', 'feBlend', 'feColorMatrix',
+ 'feComponentTransfer', 'feComposite', 'feConvolveMatrix', 'feDiffuseLighting',
+ 'feDisplacementMap', 'feDistantLight', 'feFlood', 'feFuncA', 'feFuncB',
+ 'feFuncG', 'feFuncR', 'feGaussianBlur', 'feImage', 'feMerge', 'feMergeNode',
+ 'feMorphology', 'feOffset', 'fePointLight', 'feSpecularLighting',
+ 'feSpotlight', 'feTile', 'feTurbulence', 'filter', 'font', 'fontFace',
+ 'fontFaceFormat', 'fontFaceName', 'fontFaceSrc', 'fontFaceUri',
+ 'foreignObject', 'g', 'glyph', 'glyphRef', 'hkern', 'image', 'line',
+ 'linearGradient', 'marker', 'mask', 'metadata', 'missingGlyph', 'mpath',
+ 'path', 'pattern', 'polygon', 'polyling', 'radialGradient', 'rect', 'script',
+ 'set', 'stop', 'style', 'switch', 'symbol', 'text', 'textPath', 'title',
+ 'tref', 'tspan', 'use', 'view', 'vkern'
+];
+var svg = createTagFunction('svg');
+SVG_TAG_NAMES.forEach(function (tag) {
+ svg[tag] = createTagFunction(tag);
+});
+var TAG_NAMES = [
+ 'a', 'abbr', 'address', 'area', 'article', 'aside', 'audio', 'b', 'base',
+ 'bdi', 'bdo', 'blockquote', 'body', 'br', 'button', 'canvas', 'caption',
+ 'cite', 'code', 'col', 'colgroup', 'dd', 'del', 'dfn', 'dir', 'div', 'dl',
+ 'dt', 'em', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form',
+ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html',
+ 'i', 'iframe', 'img', 'input', 'ins', 'kbd', 'keygen', 'label', 'legend',
+ 'li', 'link', 'main', 'map', 'mark', 'menu', 'meta', 'nav', 'noscript',
+ 'object', 'ol', 'optgroup', 'option', 'p', 'param', 'pre', 'progress', 'q',
+ 'rp', 'rt', 'ruby', 's', 'samp', 'script', 'section', 'select', 'small',
+ 'source', 'span', 'strong', 'style', 'sub', 'sup', 'table', 'tbody', 'td',
+ 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'u', 'ul', 'video'
+];
+var exported = { SVG_TAG_NAMES: SVG_TAG_NAMES, TAG_NAMES: TAG_NAMES, svg: svg, isSelector: isSelector, createTagFunction: createTagFunction };
+TAG_NAMES.forEach(function (n) {
+ exported[n] = createTagFunction(n);
+});
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = exported;
+
+},{"./hyperscript":10}],10:[function(require,module,exports){
+"use strict";
+var is = require('snabbdom/is');
+var vnode = require('snabbdom/vnode');
+function isGenericStream(x) {
+ return !Array.isArray(x) && typeof x.map === "function";
+}
+function mutateStreamWithNS(vNode) {
+ addNS(vNode.data, vNode.children);
+ return vNode;
+}
+function addNS(data, children) {
+ data.ns = "http://www.w3.org/2000/svg";
+ if (typeof children !== "undefined" && is.array(children)) {
+ for (var i = 0; i < children.length; ++i) {
+ if (isGenericStream(children[i])) {
+ children[i] = children[i].map(mutateStreamWithNS);
+ }
+ else {
+ addNS(children[i].data, children[i].children);
+ }
+ }
+ }
+}
+function h(sel, b, c) {
+ var data = {};
+ var children;
+ var text;
+ var i;
+ if (arguments.length === 3) {
+ data = b;
+ if (is.array(c)) {
+ children = c;
+ }
+ else if (is.primitive(c)) {
+ text = c;
+ }
+ }
+ else if (arguments.length === 2) {
+ if (is.array(b)) {
+ children = b;
+ }
+ else if (is.primitive(b)) {
+ text = b;
+ }
+ else {
+ data = b;
+ }
+ }
+ if (is.array(children)) {
+ children = children.filter(function (x) { return x; });
+ for (i = 0; i < children.length; ++i) {
+ if (is.primitive(children[i])) {
+ children[i] = vnode(undefined, undefined, undefined, children[i]);
+ }
+ }
+ }
+ if (sel[0] === 's' && sel[1] === 'v' && sel[2] === 'g') {
+ addNS(data, children);
+ }
+ return vnode(sel, data, children, text, undefined);
+}
+exports.h = h;
+;
+
+},{"snabbdom/is":59,"snabbdom/vnode":68}],11:[function(require,module,exports){
+"use strict";
+var thunk = require('snabbdom/thunk');
+exports.thunk = thunk;
+var makeDOMDriver_1 = require('./makeDOMDriver');
+exports.makeDOMDriver = makeDOMDriver_1.makeDOMDriver;
+var makeHTMLDriver_1 = require('./makeHTMLDriver');
+exports.makeHTMLDriver = makeHTMLDriver_1.makeHTMLDriver;
+var mockDOMSource_1 = require('./mockDOMSource');
+exports.mockDOMSource = mockDOMSource_1.mockDOMSource;
+var hyperscript_1 = require('./hyperscript');
+exports.h = hyperscript_1.h;
+var hyperscript_helpers_1 = require('./hyperscript-helpers');
+exports.svg = hyperscript_helpers_1.default.svg;
+exports.a = hyperscript_helpers_1.default.a;
+exports.abbr = hyperscript_helpers_1.default.abbr;
+exports.address = hyperscript_helpers_1.default.address;
+exports.area = hyperscript_helpers_1.default.area;
+exports.article = hyperscript_helpers_1.default.article;
+exports.aside = hyperscript_helpers_1.default.aside;
+exports.audio = hyperscript_helpers_1.default.audio;
+exports.b = hyperscript_helpers_1.default.b;
+exports.base = hyperscript_helpers_1.default.base;
+exports.bdi = hyperscript_helpers_1.default.bdi;
+exports.bdo = hyperscript_helpers_1.default.bdo;
+exports.blockquote = hyperscript_helpers_1.default.blockquote;
+exports.body = hyperscript_helpers_1.default.body;
+exports.br = hyperscript_helpers_1.default.br;
+exports.button = hyperscript_helpers_1.default.button;
+exports.canvas = hyperscript_helpers_1.default.canvas;
+exports.caption = hyperscript_helpers_1.default.caption;
+exports.cite = hyperscript_helpers_1.default.cite;
+exports.code = hyperscript_helpers_1.default.code;
+exports.col = hyperscript_helpers_1.default.col;
+exports.colgroup = hyperscript_helpers_1.default.colgroup;
+exports.dd = hyperscript_helpers_1.default.dd;
+exports.del = hyperscript_helpers_1.default.del;
+exports.dfn = hyperscript_helpers_1.default.dfn;
+exports.dir = hyperscript_helpers_1.default.dir;
+exports.div = hyperscript_helpers_1.default.div;
+exports.dl = hyperscript_helpers_1.default.dl;
+exports.dt = hyperscript_helpers_1.default.dt;
+exports.em = hyperscript_helpers_1.default.em;
+exports.embed = hyperscript_helpers_1.default.embed;
+exports.fieldset = hyperscript_helpers_1.default.fieldset;
+exports.figcaption = hyperscript_helpers_1.default.figcaption;
+exports.figure = hyperscript_helpers_1.default.figure;
+exports.footer = hyperscript_helpers_1.default.footer;
+exports.form = hyperscript_helpers_1.default.form;
+exports.h1 = hyperscript_helpers_1.default.h1;
+exports.h2 = hyperscript_helpers_1.default.h2;
+exports.h3 = hyperscript_helpers_1.default.h3;
+exports.h4 = hyperscript_helpers_1.default.h4;
+exports.h5 = hyperscript_helpers_1.default.h5;
+exports.h6 = hyperscript_helpers_1.default.h6;
+exports.head = hyperscript_helpers_1.default.head;
+exports.header = hyperscript_helpers_1.default.header;
+exports.hgroup = hyperscript_helpers_1.default.hgroup;
+exports.hr = hyperscript_helpers_1.default.hr;
+exports.html = hyperscript_helpers_1.default.html;
+exports.i = hyperscript_helpers_1.default.i;
+exports.iframe = hyperscript_helpers_1.default.iframe;
+exports.img = hyperscript_helpers_1.default.img;
+exports.input = hyperscript_helpers_1.default.input;
+exports.ins = hyperscript_helpers_1.default.ins;
+exports.kbd = hyperscript_helpers_1.default.kbd;
+exports.keygen = hyperscript_helpers_1.default.keygen;
+exports.label = hyperscript_helpers_1.default.label;
+exports.legend = hyperscript_helpers_1.default.legend;
+exports.li = hyperscript_helpers_1.default.li;
+exports.link = hyperscript_helpers_1.default.link;
+exports.main = hyperscript_helpers_1.default.main;
+exports.map = hyperscript_helpers_1.default.map;
+exports.mark = hyperscript_helpers_1.default.mark;
+exports.menu = hyperscript_helpers_1.default.menu;
+exports.meta = hyperscript_helpers_1.default.meta;
+exports.nav = hyperscript_helpers_1.default.nav;
+exports.noscript = hyperscript_helpers_1.default.noscript;
+exports.object = hyperscript_helpers_1.default.object;
+exports.ol = hyperscript_helpers_1.default.ol;
+exports.optgroup = hyperscript_helpers_1.default.optgroup;
+exports.option = hyperscript_helpers_1.default.option;
+exports.p = hyperscript_helpers_1.default.p;
+exports.param = hyperscript_helpers_1.default.param;
+exports.pre = hyperscript_helpers_1.default.pre;
+exports.progress = hyperscript_helpers_1.default.progress;
+exports.q = hyperscript_helpers_1.default.q;
+exports.rp = hyperscript_helpers_1.default.rp;
+exports.rt = hyperscript_helpers_1.default.rt;
+exports.ruby = hyperscript_helpers_1.default.ruby;
+exports.s = hyperscript_helpers_1.default.s;
+exports.samp = hyperscript_helpers_1.default.samp;
+exports.script = hyperscript_helpers_1.default.script;
+exports.section = hyperscript_helpers_1.default.section;
+exports.select = hyperscript_helpers_1.default.select;
+exports.small = hyperscript_helpers_1.default.small;
+exports.source = hyperscript_helpers_1.default.source;
+exports.span = hyperscript_helpers_1.default.span;
+exports.strong = hyperscript_helpers_1.default.strong;
+exports.style = hyperscript_helpers_1.default.style;
+exports.sub = hyperscript_helpers_1.default.sub;
+exports.sup = hyperscript_helpers_1.default.sup;
+exports.table = hyperscript_helpers_1.default.table;
+exports.tbody = hyperscript_helpers_1.default.tbody;
+exports.td = hyperscript_helpers_1.default.td;
+exports.textarea = hyperscript_helpers_1.default.textarea;
+exports.tfoot = hyperscript_helpers_1.default.tfoot;
+exports.th = hyperscript_helpers_1.default.th;
+exports.thead = hyperscript_helpers_1.default.thead;
+exports.title = hyperscript_helpers_1.default.title;
+exports.tr = hyperscript_helpers_1.default.tr;
+exports.u = hyperscript_helpers_1.default.u;
+exports.ul = hyperscript_helpers_1.default.ul;
+exports.video = hyperscript_helpers_1.default.video;
+
+},{"./hyperscript":10,"./hyperscript-helpers":9,"./makeDOMDriver":14,"./makeHTMLDriver":15,"./mockDOMSource":16,"snabbdom/thunk":67}],12:[function(require,module,exports){
+"use strict";
+var utils_1 = require('./utils');
+function isolateSource(source, scope) {
+ return source.select(utils_1.SCOPE_PREFIX + scope);
+}
+exports.isolateSource = isolateSource;
+function isolateSink(sink, scope) {
+ return sink.map(function (vTree) {
+ if (vTree.data.isolate) {
+ var existingScope = parseInt(vTree.data.isolate.split(utils_1.SCOPE_PREFIX + 'cycle')[1]);
+ var _scope = parseInt(scope.split('cycle')[1]);
+ if (Number.isNaN(existingScope) ||
+ Number.isNaN(_scope) ||
+ existingScope > _scope) {
+ return vTree;
+ }
+ }
+ vTree.data.isolate = utils_1.SCOPE_PREFIX + scope;
+ return vTree;
+ });
+}
+exports.isolateSink = isolateSink;
+
+},{"./utils":19}],13:[function(require,module,exports){
+"use strict";
+var IsolateModule = (function () {
+ function IsolateModule(isolatedElements) {
+ this.isolatedElements = isolatedElements;
+ this.eventDelegators = new Map();
+ }
+ IsolateModule.prototype.setScope = function (elm, scope) {
+ this.isolatedElements.set(scope, elm);
+ };
+ IsolateModule.prototype.removeScope = function (scope) {
+ this.isolatedElements.delete(scope);
+ };
+ IsolateModule.prototype.getIsolatedElement = function (scope) {
+ return this.isolatedElements.get(scope);
+ };
+ IsolateModule.prototype.isIsolatedElement = function (elm) {
+ var elements = Array.from(this.isolatedElements.entries());
+ for (var i = 0; i < elements.length; ++i) {
+ if (elm === elements[i][1]) {
+ return elements[i][0];
+ }
+ }
+ return false;
+ };
+ IsolateModule.prototype.addEventDelegator = function (scope, eventDelegator) {
+ var delegators = this.eventDelegators.get(scope);
+ if (!delegators) {
+ delegators = [];
+ this.eventDelegators.set(scope, delegators);
+ }
+ delegators[delegators.length] = eventDelegator;
+ };
+ IsolateModule.prototype.reset = function () {
+ this.isolatedElements.clear();
+ };
+ IsolateModule.prototype.createModule = function () {
+ var self = this;
+ return {
+ create: function (oldVNode, vNode) {
+ var _a = oldVNode.data, oldData = _a === void 0 ? {} : _a;
+ var elm = vNode.elm, _b = vNode.data, data = _b === void 0 ? {} : _b;
+ var oldScope = oldData.isolate || "";
+ var scope = data.isolate || "";
+ if (scope) {
+ if (oldScope) {
+ self.removeScope(oldScope);
+ }
+ self.setScope(elm, scope);
+ var delegators = self.eventDelegators.get(scope);
+ if (delegators) {
+ for (var i = 0, len = delegators.length; i < len; ++i) {
+ delegators[i].updateTopElement(elm);
+ }
+ }
+ else if (delegators === void 0) {
+ self.eventDelegators.set(scope, []);
+ }
+ }
+ if (oldScope && !scope) {
+ self.removeScope(scope);
+ }
+ },
+ update: function (oldVNode, vNode) {
+ var _a = oldVNode.data, oldData = _a === void 0 ? {} : _a;
+ var elm = vNode.elm, _b = vNode.data, data = _b === void 0 ? {} : _b;
+ var oldScope = oldData.isolate || "";
+ var scope = data.isolate || "";
+ if (scope) {
+ if (oldScope) {
+ self.removeScope(oldScope);
+ }
+ self.setScope(elm, scope);
+ }
+ if (oldScope && !scope) {
+ self.removeScope(scope);
+ }
+ },
+ remove: function (_a, cb) {
+ var data = _a.data;
+ data = data || {};
+ var scope = data.isolate;
+ if (scope) {
+ self.removeScope(scope);
+ if (self.eventDelegators.get(scope)) {
+ self.eventDelegators.set(scope, []);
+ }
+ }
+ cb();
+ },
+ destroy: function (_a) {
+ var data = _a.data;
+ data = data || {};
+ var scope = data.isolate;
+ if (scope) {
+ self.removeScope(scope);
+ if (self.eventDelegators.get(scope)) {
+ self.eventDelegators.set(scope, []);
+ }
+ }
+ }
+ };
+ };
+ return IsolateModule;
+}());
+exports.IsolateModule = IsolateModule;
+
+},{}],14:[function(require,module,exports){
+"use strict";
+var snabbdom_1 = require('snabbdom');
+var xstream_1 = require('xstream');
+var MainDOMSource_1 = require('./MainDOMSource');
+var VNodeWrapper_1 = require('./VNodeWrapper');
+var utils_1 = require('./utils');
+var modules_1 = require('./modules');
+var isolateModule_1 = require('./isolateModule');
+var transposition_1 = require('./transposition');
+var xstream_adapter_1 = require('@cycle/xstream-adapter');
+function makeDOMDriverInputGuard(modules) {
+ if (!Array.isArray(modules)) {
+ throw new Error("Optional modules option must be " +
+ "an array for snabbdom modules");
+ }
+}
+function domDriverInputGuard(view$) {
+ if (!view$
+ || typeof view$.addListener !== "function"
+ || typeof view$.fold !== "function") {
+ throw new Error("The DOM driver function expects as input a Stream of " +
+ "virtual DOM elements");
+ }
+}
+function makeDOMDriver(container, options) {
+ if (!options) {
+ options = {};
+ }
+ var transposition = options.transposition || false;
+ var modules = options.modules || modules_1.default;
+ var isolateModule = new isolateModule_1.IsolateModule((new Map()));
+ var patch = snabbdom_1.init([isolateModule.createModule()].concat(modules));
+ var rootElement = utils_1.getElement(container);
+ var vnodeWrapper = new VNodeWrapper_1.VNodeWrapper(rootElement);
+ var delegators = new Map();
+ makeDOMDriverInputGuard(modules);
+ function DOMDriver(vnode$, runStreamAdapter) {
+ domDriverInputGuard(vnode$);
+ var transposeVNode = transposition_1.makeTransposeVNode(runStreamAdapter);
+ var preprocessedVNode$ = (transposition ? vnode$.map(transposeVNode).flatten() : vnode$);
+ var rootElement$ = preprocessedVNode$
+ .map(function (vnode) { return vnodeWrapper.call(vnode); })
+ .fold(patch, rootElement)
+ .drop(1)
+ .map(function unwrapElementFromVNode(vnode) { return vnode.elm; })
+ .compose(function (stream) { return xstream_1.default.merge(stream, xstream_1.default.never()); }) // don't complete this stream
+ .startWith(rootElement);
+ /* tslint:disable:no-empty */
+ rootElement$.addListener({ next: function () { }, error: function () { }, complete: function () { } });
+ /* tslint:enable:no-empty */
+ return new MainDOMSource_1.MainDOMSource(rootElement$, runStreamAdapter, [], isolateModule, delegators);
+ }
+ ;
+ DOMDriver.streamAdapter = xstream_adapter_1.default;
+ return DOMDriver;
+}
+exports.makeDOMDriver = makeDOMDriver;
+
+},{"./MainDOMSource":5,"./VNodeWrapper":7,"./isolateModule":13,"./modules":17,"./transposition":18,"./utils":19,"@cycle/xstream-adapter":20,"snabbdom":66,"xstream":115}],15:[function(require,module,exports){
+"use strict";
+var xstream_adapter_1 = require('@cycle/xstream-adapter');
+var transposition_1 = require('./transposition');
+var HTMLSource_1 = require('./HTMLSource');
+var toHTML = require('snabbdom-to-html');
+/* tslint:disable:no-empty */
+var noop = function () { };
+/* tslint:enable:no-empty */
+function makeHTMLDriver(effect, options) {
+ if (!options) {
+ options = {};
+ }
+ var transposition = options.transposition || false;
+ function htmlDriver(vnode$, runStreamAdapter) {
+ var transposeVNode = transposition_1.makeTransposeVNode(runStreamAdapter);
+ var preprocessedVNode$ = (transposition ? vnode$.map(transposeVNode).flatten() : vnode$);
+ var html$ = preprocessedVNode$.last().map(toHTML);
+ html$.addListener({
+ next: effect || noop,
+ error: noop,
+ complete: noop,
+ });
+ return new HTMLSource_1.HTMLSource(html$, runStreamAdapter);
+ }
+ ;
+ htmlDriver.streamAdapter = xstream_adapter_1.default;
+ return htmlDriver;
+}
+exports.makeHTMLDriver = makeHTMLDriver;
+
+},{"./HTMLSource":4,"./transposition":18,"@cycle/xstream-adapter":20,"snabbdom-to-html":26}],16:[function(require,module,exports){
+"use strict";
+var xstream_adapter_1 = require('@cycle/xstream-adapter');
+var xstream_1 = require('xstream');
+var MockedDOMSource = (function () {
+ function MockedDOMSource(_streamAdapter, _mockConfig) {
+ this._streamAdapter = _streamAdapter;
+ this._mockConfig = _mockConfig;
+ if (_mockConfig.elements) {
+ this._elements = _mockConfig.elements;
+ }
+ else {
+ this._elements = _streamAdapter.adapt(xstream_1.default.empty(), xstream_adapter_1.default.streamSubscribe);
+ }
+ }
+ MockedDOMSource.prototype.elements = function () {
+ return this._elements;
+ };
+ MockedDOMSource.prototype.events = function (eventType, options) {
+ var mockConfig = this._mockConfig;
+ var keys = Object.keys(mockConfig);
+ var keysLen = keys.length;
+ for (var i = 0; i < keysLen; i++) {
+ var key = keys[i];
+ if (key === eventType) {
+ return mockConfig[key];
+ }
+ }
+ return this._streamAdapter.adapt(xstream_1.default.empty(), xstream_adapter_1.default.streamSubscribe);
+ };
+ MockedDOMSource.prototype.select = function (selector) {
+ var mockConfig = this._mockConfig;
+ var keys = Object.keys(mockConfig);
+ var keysLen = keys.length;
+ for (var i = 0; i < keysLen; i++) {
+ var key = keys[i];
+ if (key === selector) {
+ return new MockedDOMSource(this._streamAdapter, mockConfig[key]);
+ }
+ }
+ return new MockedDOMSource(this._streamAdapter, {});
+ };
+ return MockedDOMSource;
+}());
+exports.MockedDOMSource = MockedDOMSource;
+function mockDOMSource(streamAdapter, mockConfig) {
+ return new MockedDOMSource(streamAdapter, mockConfig);
+}
+exports.mockDOMSource = mockDOMSource;
+
+},{"@cycle/xstream-adapter":20,"xstream":115}],17:[function(require,module,exports){
+"use strict";
+var ClassModule = require('snabbdom/modules/class');
+exports.ClassModule = ClassModule;
+var PropsModule = require('snabbdom/modules/props');
+exports.PropsModule = PropsModule;
+var AttrsModule = require('snabbdom/modules/attributes');
+exports.AttrsModule = AttrsModule;
+var EventsModule = require('snabbdom/modules/eventlisteners');
+exports.EventsModule = EventsModule;
+var StyleModule = require('snabbdom/modules/style');
+exports.StyleModule = StyleModule;
+var HeroModule = require('snabbdom/modules/hero');
+exports.HeroModule = HeroModule;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = [StyleModule, ClassModule, PropsModule, AttrsModule];
+
+},{"snabbdom/modules/attributes":60,"snabbdom/modules/class":61,"snabbdom/modules/eventlisteners":62,"snabbdom/modules/hero":63,"snabbdom/modules/props":64,"snabbdom/modules/style":65}],18:[function(require,module,exports){
+"use strict";
+var xstream_adapter_1 = require('@cycle/xstream-adapter');
+var xstream_1 = require('xstream');
+function createVTree(vnode, children) {
+ return {
+ sel: vnode.sel,
+ data: vnode.data,
+ text: vnode.text,
+ elm: vnode.elm,
+ key: vnode.key,
+ children: children,
+ };
+}
+function makeTransposeVNode(runStreamAdapter) {
+ return function transposeVNode(vnode) {
+ if (!vnode) {
+ return null;
+ }
+ else if (vnode && typeof vnode.data === "object" && vnode.data.static) {
+ return xstream_1.default.of(vnode);
+ }
+ else if (runStreamAdapter.isValidStream(vnode)) {
+ var xsStream = xstream_adapter_1.default.adapt(vnode, runStreamAdapter.streamSubscribe);
+ return xsStream.map(transposeVNode).flatten();
+ }
+ else if (typeof vnode === "object") {
+ if (!vnode.children || vnode.children.length === 0) {
+ return xstream_1.default.of(vnode);
+ }
+ var vnodeChildren = vnode.children
+ .map(transposeVNode)
+ .filter(function (x) { return x !== null; });
+ if (vnodeChildren.length === 0) {
+ return xstream_1.default.of(createVTree(vnode, []));
+ }
+ else {
+ return xstream_1.default.combine.apply(xstream_1.default, vnodeChildren)
+ .map(function (children) { return createVTree(vnode, children.slice()); });
+ }
+ }
+ else {
+ throw new Error("Unhandled vTree Value");
+ }
+ };
+}
+exports.makeTransposeVNode = makeTransposeVNode;
+
+},{"@cycle/xstream-adapter":20,"xstream":115}],19:[function(require,module,exports){
+"use strict";
+function isElement(obj) {
+ return typeof HTMLElement === "object" ?
+ obj instanceof HTMLElement || obj instanceof DocumentFragment :
+ obj && typeof obj === "object" && obj !== null &&
+ (obj.nodeType === 1 || obj.nodeType === 11) &&
+ typeof obj.nodeName === "string";
+}
+exports.SCOPE_PREFIX = "$$CYCLEDOM$$-";
+function getElement(selectors) {
+ var domElement = (typeof selectors === "string" ?
+ document.querySelector(selectors) :
+ selectors);
+ if (typeof selectors === "string" && domElement === null) {
+ throw new Error("Cannot render into unknown element `" + selectors + "`");
+ }
+ else if (!isElement(domElement)) {
+ throw new Error("Given container is not a DOM element neither a " +
+ "selector string.");
+ }
+ return domElement;
+}
+exports.getElement = getElement;
+function getScope(namespace) {
+ return namespace
+ .filter(function (c) { return c.indexOf(exports.SCOPE_PREFIX) > -1; })
+ .slice(-1) // only need the latest, most specific, isolated boundary
+ .join("");
+}
+exports.getScope = getScope;
+function getSelectors(namespace) {
+ return namespace.filter(function (c) { return c.indexOf(exports.SCOPE_PREFIX) === -1; }).join(" ");
+}
+exports.getSelectors = getSelectors;
+
+},{}],20:[function(require,module,exports){
+"use strict";
+var xstream_1 = require('xstream');
+var XStreamAdapter = {
+ adapt: function (originStream, originStreamSubscribe) {
+ if (XStreamAdapter.isValidStream(originStream)) {
+ return originStream;
+ }
+ ;
+ var dispose = null;
+ return xstream_1.default.create({
+ start: function (out) {
+ var observer = out;
+ dispose = originStreamSubscribe(originStream, observer);
+ },
+ stop: function () {
+ if (typeof dispose === 'function') {
+ dispose();
+ }
+ }
+ });
+ },
+ makeSubject: function () {
+ var stream = xstream_1.default.create();
+ var observer = {
+ next: function (x) { stream.shamefullySendNext(x); },
+ error: function (err) { stream.shamefullySendError(err); },
+ complete: function () { stream.shamefullySendComplete(); }
+ };
+ return { observer: observer, stream: stream };
+ },
+ remember: function (stream) {
+ return stream.remember();
+ },
+ isValidStream: function (stream) {
+ return (typeof stream.addListener === 'function' &&
+ typeof stream.shamefullySendNext === 'function');
+ },
+ streamSubscribe: function (stream, observer) {
+ stream.addListener(observer);
+ return function () { return stream.removeListener(observer); };
+ }
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = XStreamAdapter;
+
+},{"xstream":115}],21:[function(require,module,exports){
+'use strict';
+
+var proto = Element.prototype;
+var vendor = proto.matches
+ || proto.matchesSelector
+ || proto.webkitMatchesSelector
+ || proto.mozMatchesSelector
+ || proto.msMatchesSelector
+ || proto.oMatchesSelector;
+
+module.exports = match;
+
+/**
+ * Match `el` to `selector`.
+ *
+ * @param {Element} el
+ * @param {String} selector
+ * @return {Boolean}
+ * @api public
+ */
+
+function match(el, selector) {
+ if (vendor) return vendor.call(el, selector);
+ var nodes = el.parentNode.querySelectorAll(selector);
+ for (var i = 0; i < nodes.length; i++) {
+ if (nodes[i] == el) return true;
+ }
+ return false;
+}
+},{}],22:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = classNameFromVNode;
+
+var _selectorParser2 = require('./selectorParser');
+
+var _selectorParser3 = _interopRequireDefault(_selectorParser2);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function classNameFromVNode(vNode) {
+ var _selectorParser = (0, _selectorParser3.default)(vNode.sel);
+
+ var cn = _selectorParser.className;
+
+ if (!vNode.data) {
+ return cn;
+ }
+
+ var _vNode$data = vNode.data;
+ var dataClass = _vNode$data.class;
+ var props = _vNode$data.props;
+
+ if (dataClass) {
+ var c = Object.keys(vNode.data.class).filter(function (cl) {
+ return vNode.data.class[cl];
+ });
+ cn += ' ' + c.join(' ');
+ }
+
+ if (props && props.className) {
+ cn += ' ' + props.className;
+ }
+
+ return cn.trim();
+}
+},{"./selectorParser":23}],23:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = selectorParser;
+
+var _browserSplit = require('browser-split');
+
+var _browserSplit2 = _interopRequireDefault(_browserSplit);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var classIdSplit = /([\.#]?[a-zA-Z0-9\u007F-\uFFFF_:-]+)/;
+var notClassId = /^\.|#/;
+
+function selectorParser() {
+ var selector = arguments.length <= 0 || arguments[0] === undefined ? '' : arguments[0];
+
+ var tagName = undefined;
+ var id = '';
+ var classes = [];
+
+ var tagParts = (0, _browserSplit2.default)(selector, classIdSplit);
+
+ if (notClassId.test(tagParts[1]) || selector === '') {
+ tagName = 'div';
+ }
+
+ var part = undefined;
+ var type = undefined;
+ var i = undefined;
+
+ for (i = 0; i < tagParts.length; i++) {
+ part = tagParts[i];
+
+ if (!part) {
+ continue;
+ }
+
+ type = part.charAt(0);
+
+ if (!tagName) {
+ tagName = part;
+ } else if (type === '.') {
+ classes.push(part.substring(1, part.length));
+ } else if (type === '#') {
+ id = part.substring(1, part.length);
+ }
+ }
+
+ return {
+ tagName: tagName,
+ id: id,
+ className: classes.join(' ')
+ };
+}
+},{"browser-split":24}],24:[function(require,module,exports){
+/*!
+ * Cross-Browser Split 1.1.1
+ * Copyright 2007-2012 Steven Levithan
+ * Available under the MIT License
+ * ECMAScript compliant, uniform cross-browser split method
+ */
+
+/**
+ * Splits a string into an array of strings using a regex or string separator. Matches of the
+ * separator are not included in the result array. However, if `separator` is a regex that contains
+ * capturing groups, backreferences are spliced into the result each time `separator` is matched.
+ * Fixes browser bugs compared to the native `String.prototype.split` and can be used reliably
+ * cross-browser.
+ * @param {String} str String to split.
+ * @param {RegExp|String} separator Regex or string to use for separating the string.
+ * @param {Number} [limit] Maximum number of items to include in the result array.
+ * @returns {Array} Array of substrings.
+ * @example
+ *
+ * // Basic use
+ * split('a b c d', ' ');
+ * // -> ['a', 'b', 'c', 'd']
+ *
+ * // With limit
+ * split('a b c d', ' ', 2);
+ * // -> ['a', 'b']
+ *
+ * // Backreferences in result array
+ * split('..word1 word2..', /([a-z]+)(\d+)/i);
+ * // -> ['..', 'word', '1', ' ', 'word', '2', '..']
+ */
+module.exports = (function split(undef) {
+
+ var nativeSplit = String.prototype.split,
+ compliantExecNpcg = /()??/.exec("")[1] === undef,
+ // NPCG: nonparticipating capturing group
+ self;
+
+ self = function(str, separator, limit) {
+ // If `separator` is not a regex, use `nativeSplit`
+ if (Object.prototype.toString.call(separator) !== "[object RegExp]") {
+ return nativeSplit.call(str, separator, limit);
+ }
+ var output = [],
+ flags = (separator.ignoreCase ? "i" : "") + (separator.multiline ? "m" : "") + (separator.extended ? "x" : "") + // Proposed for ES6
+ (separator.sticky ? "y" : ""),
+ // Firefox 3+
+ lastLastIndex = 0,
+ // Make `global` and avoid `lastIndex` issues by working with a copy
+ separator = new RegExp(separator.source, flags + "g"),
+ separator2, match, lastIndex, lastLength;
+ str += ""; // Type-convert
+ if (!compliantExecNpcg) {
+ // Doesn't need flags gy, but they don't hurt
+ separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags);
+ }
+ /* Values for `limit`, per the spec:
+ * If undefined: 4294967295 // Math.pow(2, 32) - 1
+ * If 0, Infinity, or NaN: 0
+ * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296;
+ * If negative number: 4294967296 - Math.floor(Math.abs(limit))
+ * If other: Type-convert, then use the above rules
+ */
+ limit = limit === undef ? -1 >>> 0 : // Math.pow(2, 32) - 1
+ limit >>> 0; // ToUint32(limit)
+ while (match = separator.exec(str)) {
+ // `separator.lastIndex` is not reliable cross-browser
+ lastIndex = match.index + match[0].length;
+ if (lastIndex > lastLastIndex) {
+ output.push(str.slice(lastLastIndex, match.index));
+ // Fix browsers whose `exec` methods don't consistently return `undefined` for
+ // nonparticipating capturing groups
+ if (!compliantExecNpcg && match.length > 1) {
+ match[0].replace(separator2, function() {
+ for (var i = 1; i < arguments.length - 2; i++) {
+ if (arguments[i] === undef) {
+ match[i] = undef;
+ }
+ }
+ });
+ }
+ if (match.length > 1 && match.index < str.length) {
+ Array.prototype.push.apply(output, match.slice(1));
+ }
+ lastLength = match[0].length;
+ lastLastIndex = lastIndex;
+ if (output.length >= limit) {
+ break;
+ }
+ }
+ if (separator.lastIndex === match.index) {
+ separator.lastIndex++; // Avoid an infinite loop
+ }
+ }
+ if (lastLastIndex === str.length) {
+ if (lastLength || !separator.test("")) {
+ output.push("");
+ }
+ } else {
+ output.push(str.slice(lastLastIndex));
+ }
+ return output.length > limit ? output.slice(0, limit) : output;
+ };
+
+ return self;
+})();
+
+},{}],25:[function(require,module,exports){
+
+// All SVG children elements, not in this list, should self-close
+
+module.exports = {
+ // http://www.w3.org/TR/SVG/intro.html#TermContainerElement
+ 'a': true,
+ 'defs': true,
+ 'glyph': true,
+ 'g': true,
+ 'marker': true,
+ 'mask': true,
+ 'missing-glyph': true,
+ 'pattern': true,
+ 'svg': true,
+ 'switch': true,
+ 'symbol': true,
+
+ // http://www.w3.org/TR/SVG/intro.html#TermDescriptiveElement
+ 'desc': true,
+ 'metadata': true,
+ 'title': true
+};
+},{}],26:[function(require,module,exports){
+
+var init = require('./init');
+
+module.exports = init([require('./modules/attributes'), require('./modules/style')]);
+},{"./init":27,"./modules/attributes":28,"./modules/style":29}],27:[function(require,module,exports){
+
+var parseSelector = require('./parse-selector');
+var VOID_ELEMENTS = require('./void-elements');
+var CONTAINER_ELEMENTS = require('./container-elements');
+
+module.exports = function init(modules) {
+ function parse(data) {
+ return modules.reduce(function (arr, fn) {
+ arr.push(fn(data));
+ return arr;
+ }, []).filter(function (result) {
+ return result !== '';
+ });
+ }
+
+ return function renderToString(vnode) {
+ if (!vnode.sel && vnode.text) {
+ return vnode.text;
+ }
+
+ vnode.data = vnode.data || {};
+
+ // Support thunks
+ if (typeof vnode.sel === 'string' && vnode.sel.slice(0, 5) === 'thunk') {
+ vnode = vnode.data.fn.apply(null, vnode.data.args);
+ }
+
+ var tagName = parseSelector(vnode.sel).tagName;
+ var attributes = parse(vnode);
+ var svg = vnode.data.ns === 'http://www.w3.org/2000/svg';
+ var tag = [];
+
+ // Open tag
+ tag.push('<' + tagName);
+ if (attributes.length) {
+ tag.push(' ' + attributes.join(' '));
+ }
+ if (svg && CONTAINER_ELEMENTS[tagName] !== true) {
+ tag.push(' /');
+ }
+ tag.push('>');
+
+ // Close tag, if needed
+ if (VOID_ELEMENTS[tagName] !== true && !svg || svg && CONTAINER_ELEMENTS[tagName] === true) {
+ if (vnode.data.props && vnode.data.props.innerHTML) {
+ tag.push(vnode.data.props.innerHTML);
+ } else if (vnode.text) {
+ tag.push(vnode.text);
+ } else if (vnode.children) {
+ vnode.children.forEach(function (child) {
+ tag.push(renderToString(child));
+ });
+ }
+ tag.push('' + tagName + '>');
+ }
+
+ return tag.join('');
+ };
+};
+},{"./container-elements":25,"./parse-selector":30,"./void-elements":31}],28:[function(require,module,exports){
+
+var forOwn = require('lodash.forown');
+var escape = require('lodash.escape');
+var union = require('lodash.union');
+
+var parseSelector = require('../parse-selector');
+
+// data.attrs, data.props, data.class
+
+module.exports = function attributes(vnode) {
+ var selector = parseSelector(vnode.sel);
+ var parsedClasses = selector.className.split(' ');
+
+ var attributes = [];
+ var classes = [];
+ var values = {};
+
+ if (selector.id) {
+ values.id = selector.id;
+ }
+
+ setAttributes(vnode.data.props, values);
+ setAttributes(vnode.data.attrs, values); // `attrs` override `props`, not sure if this is good so
+
+ if (vnode.data.class) {
+ // Omit `className` attribute if `class` is set on vnode
+ values.class = undefined;
+ }
+ forOwn(vnode.data.class, function (value, key) {
+ if (value === true) {
+ classes.push(key);
+ }
+ });
+ classes = union(classes, values.class, parsedClasses).filter(function (x) {
+ return x !== '';
+ });
+
+ if (classes.length) {
+ values.class = classes.join(' ');
+ }
+
+ forOwn(values, function (value, key) {
+ attributes.push(value === true ? key : key + '="' + escape(value) + '"');
+ });
+
+ return attributes.length ? attributes.join(' ') : '';
+};
+
+function setAttributes(values, target) {
+ forOwn(values, function (value, key) {
+ if (key === 'htmlFor') {
+ target['for'] = value;
+ return;
+ }
+ if (key === 'className') {
+ target['class'] = value.split(' ');
+ return;
+ }
+ if (key === 'innerHTML') {
+ return;
+ }
+ target[key] = value;
+ });
+}
+},{"../parse-selector":30,"lodash.escape":33,"lodash.forown":35,"lodash.union":47}],29:[function(require,module,exports){
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var forOwn = require('lodash.forown');
+var escape = require('lodash.escape');
+var kebabCase = require('lodash.kebabcase');
+
+// data.style
+
+module.exports = function style(vnode) {
+ var styles = [];
+ var style = vnode.data.style || {};
+
+ // merge in `delayed` properties
+ if (style.delayed) {
+ _extends(style, style.delayed);
+ }
+
+ forOwn(style, function (value, key) {
+ // omit hook objects
+ if (typeof value === 'string') {
+ styles.push(kebabCase(key) + ': ' + escape(value));
+ }
+ });
+
+ return styles.length ? 'style="' + styles.join('; ') + '"' : '';
+};
+},{"lodash.escape":33,"lodash.forown":35,"lodash.kebabcase":42}],30:[function(require,module,exports){
+
+// https://github.com/Matt-Esch/virtual-dom/blob/master/virtual-hyperscript/parse-tag.js
+
+var split = require('browser-split');
+
+var classIdSplit = /([\.#]?[a-zA-Z0-9\u007F-\uFFFF_:-]+)/;
+var notClassId = /^\.|#/;
+
+module.exports = function parseSelector(selector, upper) {
+ selector = selector || '';
+ var tagName;
+ var id = '';
+ var classes = [];
+
+ var tagParts = split(selector, classIdSplit);
+
+ if (notClassId.test(tagParts[1]) || selector === '') {
+ tagName = 'div';
+ }
+
+ var part, type, i;
+
+ for (i = 0; i < tagParts.length; i++) {
+ part = tagParts[i];
+
+ if (!part) {
+ continue;
+ }
+
+ type = part.charAt(0);
+
+ if (!tagName) {
+ tagName = part;
+ } else if (type === '.') {
+ classes.push(part.substring(1, part.length));
+ } else if (type === '#') {
+ id = part.substring(1, part.length);
+ }
+ }
+
+ return {
+ tagName: upper === true ? tagName.toUpperCase() : tagName,
+ id: id,
+ className: classes.join(' ')
+ };
+};
+},{"browser-split":32}],31:[function(require,module,exports){
+
+// http://www.w3.org/html/wg/drafts/html/master/syntax.html#void-elements
+
+module.exports = {
+ area: true,
+ base: true,
+ br: true,
+ col: true,
+ embed: true,
+ hr: true,
+ img: true,
+ input: true,
+ keygen: true,
+ link: true,
+ meta: true,
+ param: true,
+ source: true,
+ track: true,
+ wbr: true
+};
+},{}],32:[function(require,module,exports){
+arguments[4][24][0].apply(exports,arguments)
+},{"dup":24}],33:[function(require,module,exports){
+/**
+ * lodash 3.2.0 (Custom Build)
+ * Build: `lodash modularize exports="npm" -o ./`
+ * Copyright 2012-2016 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var root = require('lodash._root');
+
+/** Used as references for various `Number` constants. */
+var INFINITY = 1 / 0;
+
+/** `Object#toString` result references. */
+var symbolTag = '[object Symbol]';
+
+/** Used to match HTML entities and HTML characters. */
+var reUnescapedHtml = /[&<>"'`]/g,
+ reHasUnescapedHtml = RegExp(reUnescapedHtml.source);
+
+/** Used to map characters to HTML entities. */
+var htmlEscapes = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ "'": ''',
+ '`': '`'
+};
+
+/**
+ * Used by `_.escape` to convert characters to HTML entities.
+ *
+ * @private
+ * @param {string} chr The matched character to escape.
+ * @returns {string} Returns the escaped character.
+ */
+function escapeHtmlChar(chr) {
+ return htmlEscapes[chr];
+}
+
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objectToString = objectProto.toString;
+
+/** Built-in value references. */
+var Symbol = root.Symbol;
+
+/** Used to convert symbols to primitives and strings. */
+var symbolProto = Symbol ? Symbol.prototype : undefined,
+ symbolToString = Symbol ? symbolProto.toString : undefined;
+
+/**
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
+ * and has a `typeof` result of "object".
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ * @example
+ *
+ * _.isObjectLike({});
+ * // => true
+ *
+ * _.isObjectLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isObjectLike(_.noop);
+ * // => false
+ *
+ * _.isObjectLike(null);
+ * // => false
+ */
+function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+}
+
+/**
+ * Checks if `value` is classified as a `Symbol` primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isSymbol(Symbol.iterator);
+ * // => true
+ *
+ * _.isSymbol('abc');
+ * // => false
+ */
+function isSymbol(value) {
+ return typeof value == 'symbol' ||
+ (isObjectLike(value) && objectToString.call(value) == symbolTag);
+}
+
+/**
+ * Converts `value` to a string if it's not one. An empty string is returned
+ * for `null` and `undefined` values. The sign of `-0` is preserved.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {string} Returns the string.
+ * @example
+ *
+ * _.toString(null);
+ * // => ''
+ *
+ * _.toString(-0);
+ * // => '-0'
+ *
+ * _.toString([1, 2, 3]);
+ * // => '1,2,3'
+ */
+function toString(value) {
+ // Exit early for strings to avoid a performance hit in some environments.
+ if (typeof value == 'string') {
+ return value;
+ }
+ if (value == null) {
+ return '';
+ }
+ if (isSymbol(value)) {
+ return Symbol ? symbolToString.call(value) : '';
+ }
+ var result = (value + '');
+ return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
+}
+
+/**
+ * Converts the characters "&", "<", ">", '"', "'", and "\`" in `string` to
+ * their corresponding HTML entities.
+ *
+ * **Note:** No other characters are escaped. To escape additional
+ * characters use a third-party library like [_he_](https://mths.be/he).
+ *
+ * Though the ">" character is escaped for symmetry, characters like
+ * ">" and "/" don't need escaping in HTML and have no special meaning
+ * unless they're part of a tag or unquoted attribute value.
+ * See [Mathias Bynens's article](https://mathiasbynens.be/notes/ambiguous-ampersands)
+ * (under "semi-related fun fact") for more details.
+ *
+ * Backticks are escaped because in IE < 9, they can break out of
+ * attribute values or HTML comments. See [#59](https://html5sec.org/#59),
+ * [#102](https://html5sec.org/#102), [#108](https://html5sec.org/#108), and
+ * [#133](https://html5sec.org/#133) of the [HTML5 Security Cheatsheet](https://html5sec.org/)
+ * for more details.
+ *
+ * When working with HTML you should always [quote attribute values](http://wonko.com/post/html-escaping)
+ * to reduce XSS vectors.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to escape.
+ * @returns {string} Returns the escaped string.
+ * @example
+ *
+ * _.escape('fred, barney, & pebbles');
+ * // => 'fred, barney, & pebbles'
+ */
+function escape(string) {
+ string = toString(string);
+ return (string && reHasUnescapedHtml.test(string))
+ ? string.replace(reUnescapedHtml, escapeHtmlChar)
+ : string;
+}
+
+module.exports = escape;
+
+},{"lodash._root":34}],34:[function(require,module,exports){
+(function (global){
+/**
+ * lodash 3.0.1 (Custom Build)
+ * Build: `lodash modularize exports="npm" -o ./`
+ * Copyright 2012-2016 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/** Used to determine if values are of the language type `Object`. */
+var objectTypes = {
+ 'function': true,
+ 'object': true
+};
+
+/** Detect free variable `exports`. */
+var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)
+ ? exports
+ : undefined;
+
+/** Detect free variable `module`. */
+var freeModule = (objectTypes[typeof module] && module && !module.nodeType)
+ ? module
+ : undefined;
+
+/** Detect free variable `global` from Node.js. */
+var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
+
+/** Detect free variable `self`. */
+var freeSelf = checkGlobal(objectTypes[typeof self] && self);
+
+/** Detect free variable `window`. */
+var freeWindow = checkGlobal(objectTypes[typeof window] && window);
+
+/** Detect `this` as the global object. */
+var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
+
+/**
+ * Used as a reference to the global object.
+ *
+ * The `this` value is used if it's the global object to avoid Greasemonkey's
+ * restricted `window` object, otherwise the `window` object is used.
+ */
+var root = freeGlobal ||
+ ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) ||
+ freeSelf || thisGlobal || Function('return this')();
+
+/**
+ * Checks if `value` is a global object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {null|Object} Returns `value` if it's a global object, else `null`.
+ */
+function checkGlobal(value) {
+ return (value && value.Object === Object) ? value : null;
+}
+
+module.exports = root;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{}],35:[function(require,module,exports){
+/**
+ * lodash 3.0.2 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var baseFor = require('lodash._basefor'),
+ bindCallback = require('lodash._bindcallback'),
+ keys = require('lodash.keys');
+
+/**
+ * The base implementation of `_.forOwn` without support for callback
+ * shorthands and `this` binding.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @returns {Object} Returns `object`.
+ */
+function baseForOwn(object, iteratee) {
+ return baseFor(object, iteratee, keys);
+}
+
+/**
+ * Creates a function for `_.forOwn` or `_.forOwnRight`.
+ *
+ * @private
+ * @param {Function} objectFunc The function to iterate over an object.
+ * @returns {Function} Returns the new each function.
+ */
+function createForOwn(objectFunc) {
+ return function(object, iteratee, thisArg) {
+ if (typeof iteratee != 'function' || thisArg !== undefined) {
+ iteratee = bindCallback(iteratee, thisArg, 3);
+ }
+ return objectFunc(object, iteratee);
+ };
+}
+
+/**
+ * Iterates over own enumerable properties of an object invoking `iteratee`
+ * for each property. The `iteratee` is bound to `thisArg` and invoked with
+ * three arguments: (value, key, object). Iteratee functions may exit iteration
+ * early by explicitly returning `false`.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to iterate over.
+ * @param {Function} [iteratee=_.identity] The function invoked per iteration.
+ * @param {*} [thisArg] The `this` binding of `iteratee`.
+ * @returns {Object} Returns `object`.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.forOwn(new Foo, function(value, key) {
+ * console.log(key);
+ * });
+ * // => logs 'a' and 'b' (iteration order is not guaranteed)
+ */
+var forOwn = createForOwn(baseForOwn);
+
+module.exports = forOwn;
+
+},{"lodash._basefor":36,"lodash._bindcallback":37,"lodash.keys":38}],36:[function(require,module,exports){
+/**
+ * lodash 3.0.3 (Custom Build)
+ * Build: `lodash modularize exports="npm" -o ./`
+ * Copyright 2012-2016 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/**
+ * The base implementation of `baseForIn` and `baseForOwn` which iterates
+ * over `object` properties returned by `keysFunc` invoking `iteratee` for
+ * each property. Iteratee functions may exit iteration early by explicitly
+ * returning `false`.
+ *
+ * @private
+ * @param {Object} object The object to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {Function} keysFunc The function to get the keys of `object`.
+ * @returns {Object} Returns `object`.
+ */
+var baseFor = createBaseFor();
+
+/**
+ * Creates a base function for methods like `_.forIn`.
+ *
+ * @private
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {Function} Returns the new base function.
+ */
+function createBaseFor(fromRight) {
+ return function(object, iteratee, keysFunc) {
+ var index = -1,
+ iterable = Object(object),
+ props = keysFunc(object),
+ length = props.length;
+
+ while (length--) {
+ var key = props[fromRight ? length : ++index];
+ if (iteratee(iterable[key], key, iterable) === false) {
+ break;
+ }
+ }
+ return object;
+ };
+}
+
+module.exports = baseFor;
+
+},{}],37:[function(require,module,exports){
+/**
+ * lodash 3.0.1 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/**
+ * A specialized version of `baseCallback` which only supports `this` binding
+ * and specifying the number of arguments to provide to `func`.
+ *
+ * @private
+ * @param {Function} func The function to bind.
+ * @param {*} thisArg The `this` binding of `func`.
+ * @param {number} [argCount] The number of arguments to provide to `func`.
+ * @returns {Function} Returns the callback.
+ */
+function bindCallback(func, thisArg, argCount) {
+ if (typeof func != 'function') {
+ return identity;
+ }
+ if (thisArg === undefined) {
+ return func;
+ }
+ switch (argCount) {
+ case 1: return function(value) {
+ return func.call(thisArg, value);
+ };
+ case 3: return function(value, index, collection) {
+ return func.call(thisArg, value, index, collection);
+ };
+ case 4: return function(accumulator, value, index, collection) {
+ return func.call(thisArg, accumulator, value, index, collection);
+ };
+ case 5: return function(value, other, key, object, source) {
+ return func.call(thisArg, value, other, key, object, source);
+ };
+ }
+ return function() {
+ return func.apply(thisArg, arguments);
+ };
+}
+
+/**
+ * This method returns the first argument provided to it.
+ *
+ * @static
+ * @memberOf _
+ * @category Utility
+ * @param {*} value Any value.
+ * @returns {*} Returns `value`.
+ * @example
+ *
+ * var object = { 'user': 'fred' };
+ *
+ * _.identity(object) === object;
+ * // => true
+ */
+function identity(value) {
+ return value;
+}
+
+module.exports = bindCallback;
+
+},{}],38:[function(require,module,exports){
+/**
+ * lodash 3.1.2 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var getNative = require('lodash._getnative'),
+ isArguments = require('lodash.isarguments'),
+ isArray = require('lodash.isarray');
+
+/** Used to detect unsigned integer values. */
+var reIsUint = /^\d+$/;
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeKeys = getNative(Object, 'keys');
+
+/**
+ * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
+ * of an array-like value.
+ */
+var MAX_SAFE_INTEGER = 9007199254740991;
+
+/**
+ * The base implementation of `_.property` without support for deep paths.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @returns {Function} Returns the new function.
+ */
+function baseProperty(key) {
+ return function(object) {
+ return object == null ? undefined : object[key];
+ };
+}
+
+/**
+ * Gets the "length" property value of `object`.
+ *
+ * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
+ * that affects Safari on at least iOS 8.1-8.3 ARM64.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {*} Returns the "length" value.
+ */
+var getLength = baseProperty('length');
+
+/**
+ * Checks if `value` is array-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ */
+function isArrayLike(value) {
+ return value != null && isLength(getLength(value));
+}
+
+/**
+ * Checks if `value` is a valid array-like index.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.
+ * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.
+ */
+function isIndex(value, length) {
+ value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1;
+ length = length == null ? MAX_SAFE_INTEGER : length;
+ return value > -1 && value % 1 == 0 && value < length;
+}
+
+/**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ */
+function isLength(value) {
+ return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+}
+
+/**
+ * A fallback implementation of `Object.keys` which creates an array of the
+ * own enumerable property names of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ */
+function shimKeys(object) {
+ var props = keysIn(object),
+ propsLength = props.length,
+ length = propsLength && object.length;
+
+ var allowIndexes = !!length && isLength(length) &&
+ (isArray(object) || isArguments(object));
+
+ var index = -1,
+ result = [];
+
+ while (++index < propsLength) {
+ var key = props[index];
+ if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) {
+ result.push(key);
+ }
+ }
+ return result;
+}
+
+/**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(1);
+ * // => false
+ */
+function isObject(value) {
+ // Avoid a V8 JIT bug in Chrome 19-20.
+ // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
+ var type = typeof value;
+ return !!value && (type == 'object' || type == 'function');
+}
+
+/**
+ * Creates an array of the own enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects. See the
+ * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)
+ * for more details.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keys(new Foo);
+ * // => ['a', 'b'] (iteration order is not guaranteed)
+ *
+ * _.keys('hi');
+ * // => ['0', '1']
+ */
+var keys = !nativeKeys ? shimKeys : function(object) {
+ var Ctor = object == null ? undefined : object.constructor;
+ if ((typeof Ctor == 'function' && Ctor.prototype === object) ||
+ (typeof object != 'function' && isArrayLike(object))) {
+ return shimKeys(object);
+ }
+ return isObject(object) ? nativeKeys(object) : [];
+};
+
+/**
+ * Creates an array of the own and inherited enumerable property names of `object`.
+ *
+ * **Note:** Non-object values are coerced to objects.
+ *
+ * @static
+ * @memberOf _
+ * @category Object
+ * @param {Object} object The object to query.
+ * @returns {Array} Returns the array of property names.
+ * @example
+ *
+ * function Foo() {
+ * this.a = 1;
+ * this.b = 2;
+ * }
+ *
+ * Foo.prototype.c = 3;
+ *
+ * _.keysIn(new Foo);
+ * // => ['a', 'b', 'c'] (iteration order is not guaranteed)
+ */
+function keysIn(object) {
+ if (object == null) {
+ return [];
+ }
+ if (!isObject(object)) {
+ object = Object(object);
+ }
+ var length = object.length;
+ length = (length && isLength(length) &&
+ (isArray(object) || isArguments(object)) && length) || 0;
+
+ var Ctor = object.constructor,
+ index = -1,
+ isProto = typeof Ctor == 'function' && Ctor.prototype === object,
+ result = Array(length),
+ skipIndexes = length > 0;
+
+ while (++index < length) {
+ result[index] = (index + '');
+ }
+ for (var key in object) {
+ if (!(skipIndexes && isIndex(key, length)) &&
+ !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) {
+ result.push(key);
+ }
+ }
+ return result;
+}
+
+module.exports = keys;
+
+},{"lodash._getnative":39,"lodash.isarguments":40,"lodash.isarray":41}],39:[function(require,module,exports){
+/**
+ * lodash 3.9.1 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/** `Object#toString` result references. */
+var funcTag = '[object Function]';
+
+/** Used to detect host constructors (Safari > 5). */
+var reIsHostCtor = /^\[object .+?Constructor\]$/;
+
+/**
+ * Checks if `value` is object-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ */
+function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+}
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to resolve the decompiled source of functions. */
+var fnToString = Function.prototype.toString;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/** Used to detect if a method is native. */
+var reIsNative = RegExp('^' +
+ fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
+ .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
+);
+
+/**
+ * Gets the native function at `key` of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {string} key The key of the method to get.
+ * @returns {*} Returns the function if it's native, else `undefined`.
+ */
+function getNative(object, key) {
+ var value = object == null ? undefined : object[key];
+ return isNative(value) ? value : undefined;
+}
+
+/**
+ * Checks if `value` is classified as a `Function` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isFunction(_);
+ * // => true
+ *
+ * _.isFunction(/abc/);
+ * // => false
+ */
+function isFunction(value) {
+ // The use of `Object#toString` avoids issues with the `typeof` operator
+ // in older versions of Chrome and Safari which return 'function' for regexes
+ // and Safari 8 equivalents which return 'object' for typed array constructors.
+ return isObject(value) && objToString.call(value) == funcTag;
+}
+
+/**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(1);
+ * // => false
+ */
+function isObject(value) {
+ // Avoid a V8 JIT bug in Chrome 19-20.
+ // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
+ var type = typeof value;
+ return !!value && (type == 'object' || type == 'function');
+}
+
+/**
+ * Checks if `value` is a native function.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
+ * @example
+ *
+ * _.isNative(Array.prototype.push);
+ * // => true
+ *
+ * _.isNative(_);
+ * // => false
+ */
+function isNative(value) {
+ if (value == null) {
+ return false;
+ }
+ if (isFunction(value)) {
+ return reIsNative.test(fnToString.call(value));
+ }
+ return isObjectLike(value) && reIsHostCtor.test(value);
+}
+
+module.exports = getNative;
+
+},{}],40:[function(require,module,exports){
+/**
+ * lodash (Custom Build)
+ * Build: `lodash modularize exports="npm" -o ./`
+ * Copyright jQuery Foundation and other contributors
+ * Released under MIT license
+ * Based on Underscore.js 1.8.3
+ * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ */
+
+/** Used as references for various `Number` constants. */
+var MAX_SAFE_INTEGER = 9007199254740991;
+
+/** `Object#toString` result references. */
+var argsTag = '[object Arguments]',
+ funcTag = '[object Function]',
+ genTag = '[object GeneratorFunction]';
+
+/**
+ * The base implementation of `_.property` without support for deep paths.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @returns {Function} Returns the new accessor function.
+ */
+function baseProperty(key) {
+ return function(object) {
+ return object == null ? undefined : object[key];
+ };
+}
+
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Used to resolve the
+ * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objectToString = objectProto.toString;
+
+/** Built-in value references. */
+var propertyIsEnumerable = objectProto.propertyIsEnumerable;
+
+/**
+ * Gets the "length" property value of `object`.
+ *
+ * **Note:** This function is used to avoid a
+ * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects
+ * Safari on at least iOS 8.1-8.3 ARM64.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {*} Returns the "length" value.
+ */
+var getLength = baseProperty('length');
+
+/**
+ * Checks if `value` is likely an `arguments` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an `arguments` object,
+ * else `false`.
+ * @example
+ *
+ * _.isArguments(function() { return arguments; }());
+ * // => true
+ *
+ * _.isArguments([1, 2, 3]);
+ * // => false
+ */
+function isArguments(value) {
+ // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.
+ return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&
+ (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);
+}
+
+/**
+ * Checks if `value` is array-like. A value is considered array-like if it's
+ * not a function and has a `value.length` that's an integer greater than or
+ * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ * @example
+ *
+ * _.isArrayLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLike(document.body.children);
+ * // => true
+ *
+ * _.isArrayLike('abc');
+ * // => true
+ *
+ * _.isArrayLike(_.noop);
+ * // => false
+ */
+function isArrayLike(value) {
+ return value != null && isLength(getLength(value)) && !isFunction(value);
+}
+
+/**
+ * This method is like `_.isArrayLike` except that it also checks if `value`
+ * is an object.
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an array-like object,
+ * else `false`.
+ * @example
+ *
+ * _.isArrayLikeObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isArrayLikeObject(document.body.children);
+ * // => true
+ *
+ * _.isArrayLikeObject('abc');
+ * // => false
+ *
+ * _.isArrayLikeObject(_.noop);
+ * // => false
+ */
+function isArrayLikeObject(value) {
+ return isObjectLike(value) && isArrayLike(value);
+}
+
+/**
+ * Checks if `value` is classified as a `Function` object.
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a function, else `false`.
+ * @example
+ *
+ * _.isFunction(_);
+ * // => true
+ *
+ * _.isFunction(/abc/);
+ * // => false
+ */
+function isFunction(value) {
+ // The use of `Object#toString` avoids issues with the `typeof` operator
+ // in Safari 8 which returns 'object' for typed array and weak map constructors,
+ // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.
+ var tag = isObject(value) ? objectToString.call(value) : '';
+ return tag == funcTag || tag == genTag;
+}
+
+/**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This function is loosely based on
+ * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length,
+ * else `false`.
+ * @example
+ *
+ * _.isLength(3);
+ * // => true
+ *
+ * _.isLength(Number.MIN_VALUE);
+ * // => false
+ *
+ * _.isLength(Infinity);
+ * // => false
+ *
+ * _.isLength('3');
+ * // => false
+ */
+function isLength(value) {
+ return typeof value == 'number' &&
+ value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+}
+
+/**
+ * Checks if `value` is the
+ * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @since 0.1.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(_.noop);
+ * // => true
+ *
+ * _.isObject(null);
+ * // => false
+ */
+function isObject(value) {
+ var type = typeof value;
+ return !!value && (type == 'object' || type == 'function');
+}
+
+/**
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
+ * and has a `typeof` result of "object".
+ *
+ * @static
+ * @memberOf _
+ * @since 4.0.0
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ * @example
+ *
+ * _.isObjectLike({});
+ * // => true
+ *
+ * _.isObjectLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isObjectLike(_.noop);
+ * // => false
+ *
+ * _.isObjectLike(null);
+ * // => false
+ */
+function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+}
+
+module.exports = isArguments;
+
+},{}],41:[function(require,module,exports){
+/**
+ * lodash 3.0.4 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/** `Object#toString` result references. */
+var arrayTag = '[object Array]',
+ funcTag = '[object Function]';
+
+/** Used to detect host constructors (Safari > 5). */
+var reIsHostCtor = /^\[object .+?Constructor\]$/;
+
+/**
+ * Checks if `value` is object-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ */
+function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+}
+
+/** Used for native method references. */
+var objectProto = Object.prototype;
+
+/** Used to resolve the decompiled source of functions. */
+var fnToString = Function.prototype.toString;
+
+/** Used to check objects for own properties. */
+var hasOwnProperty = objectProto.hasOwnProperty;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objToString = objectProto.toString;
+
+/** Used to detect if a method is native. */
+var reIsNative = RegExp('^' +
+ fnToString.call(hasOwnProperty).replace(/[\\^$.*+?()[\]{}|]/g, '\\$&')
+ .replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$'
+);
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeIsArray = getNative(Array, 'isArray');
+
+/**
+ * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
+ * of an array-like value.
+ */
+var MAX_SAFE_INTEGER = 9007199254740991;
+
+/**
+ * Gets the native function at `key` of `object`.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @param {string} key The key of the method to get.
+ * @returns {*} Returns the function if it's native, else `undefined`.
+ */
+function getNative(object, key) {
+ var value = object == null ? undefined : object[key];
+ return isNative(value) ? value : undefined;
+}
+
+/**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ */
+function isLength(value) {
+ return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+}
+
+/**
+ * Checks if `value` is classified as an `Array` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isArray([1, 2, 3]);
+ * // => true
+ *
+ * _.isArray(function() { return arguments; }());
+ * // => false
+ */
+var isArray = nativeIsArray || function(value) {
+ return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag;
+};
+
+/**
+ * Checks if `value` is classified as a `Function` object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isFunction(_);
+ * // => true
+ *
+ * _.isFunction(/abc/);
+ * // => false
+ */
+function isFunction(value) {
+ // The use of `Object#toString` avoids issues with the `typeof` operator
+ // in older versions of Chrome and Safari which return 'function' for regexes
+ // and Safari 8 equivalents which return 'object' for typed array constructors.
+ return isObject(value) && objToString.call(value) == funcTag;
+}
+
+/**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(1);
+ * // => false
+ */
+function isObject(value) {
+ // Avoid a V8 JIT bug in Chrome 19-20.
+ // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
+ var type = typeof value;
+ return !!value && (type == 'object' || type == 'function');
+}
+
+/**
+ * Checks if `value` is a native function.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a native function, else `false`.
+ * @example
+ *
+ * _.isNative(Array.prototype.push);
+ * // => true
+ *
+ * _.isNative(_);
+ * // => false
+ */
+function isNative(value) {
+ if (value == null) {
+ return false;
+ }
+ if (isFunction(value)) {
+ return reIsNative.test(fnToString.call(value));
+ }
+ return isObjectLike(value) && reIsHostCtor.test(value);
+}
+
+module.exports = isArray;
+
+},{}],42:[function(require,module,exports){
+/**
+ * lodash 3.1.1 (Custom Build)
+ * Build: `lodash modularize exports="npm" -o ./`
+ * Copyright 2012-2016 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var deburr = require('lodash.deburr'),
+ words = require('lodash.words');
+
+/**
+ * A specialized version of `_.reduce` for arrays without support for
+ * iteratee shorthands.
+ *
+ * @private
+ * @param {Array} array The array to iterate over.
+ * @param {Function} iteratee The function invoked per iteration.
+ * @param {*} [accumulator] The initial value.
+ * @param {boolean} [initAccum] Specify using the first element of `array` as the initial value.
+ * @returns {*} Returns the accumulated value.
+ */
+function arrayReduce(array, iteratee, accumulator, initAccum) {
+ var index = -1,
+ length = array.length;
+
+ if (initAccum && length) {
+ accumulator = array[++index];
+ }
+ while (++index < length) {
+ accumulator = iteratee(accumulator, array[index], index, array);
+ }
+ return accumulator;
+}
+
+/**
+ * Creates a function like `_.camelCase`.
+ *
+ * @private
+ * @param {Function} callback The function to combine each word.
+ * @returns {Function} Returns the new compounder function.
+ */
+function createCompounder(callback) {
+ return function(string) {
+ return arrayReduce(words(deburr(string)), callback, '');
+ };
+}
+
+/**
+ * Converts `string` to [kebab case](https://en.wikipedia.org/wiki/Letter_case#Special_case_styles).
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the kebab cased string.
+ * @example
+ *
+ * _.kebabCase('Foo Bar');
+ * // => 'foo-bar'
+ *
+ * _.kebabCase('fooBar');
+ * // => 'foo-bar'
+ *
+ * _.kebabCase('__foo_bar__');
+ * // => 'foo-bar'
+ */
+var kebabCase = createCompounder(function(result, word, index) {
+ return result + (index ? '-' : '') + word.toLowerCase();
+});
+
+module.exports = kebabCase;
+
+},{"lodash.deburr":43,"lodash.words":45}],43:[function(require,module,exports){
+/**
+ * lodash 3.2.0 (Custom Build)
+ * Build: `lodash modularize exports="npm" -o ./`
+ * Copyright 2012-2016 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var root = require('lodash._root');
+
+/** Used as references for various `Number` constants. */
+var INFINITY = 1 / 0;
+
+/** `Object#toString` result references. */
+var symbolTag = '[object Symbol]';
+
+/** Used to match latin-1 supplementary letters (excluding mathematical operators). */
+var reLatin1 = /[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g;
+
+/** Used to compose unicode character classes. */
+var rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboSymbolsRange = '\\u20d0-\\u20f0';
+
+/** Used to compose unicode capture groups. */
+var rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']';
+
+/**
+ * Used to match [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks) and
+ * [combining diacritical marks for symbols](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks_for_Symbols).
+ */
+var reComboMark = RegExp(rsCombo, 'g');
+
+/** Used to map latin-1 supplementary letters to basic latin letters. */
+var deburredLetters = {
+ '\xc0': 'A', '\xc1': 'A', '\xc2': 'A', '\xc3': 'A', '\xc4': 'A', '\xc5': 'A',
+ '\xe0': 'a', '\xe1': 'a', '\xe2': 'a', '\xe3': 'a', '\xe4': 'a', '\xe5': 'a',
+ '\xc7': 'C', '\xe7': 'c',
+ '\xd0': 'D', '\xf0': 'd',
+ '\xc8': 'E', '\xc9': 'E', '\xca': 'E', '\xcb': 'E',
+ '\xe8': 'e', '\xe9': 'e', '\xea': 'e', '\xeb': 'e',
+ '\xcC': 'I', '\xcd': 'I', '\xce': 'I', '\xcf': 'I',
+ '\xeC': 'i', '\xed': 'i', '\xee': 'i', '\xef': 'i',
+ '\xd1': 'N', '\xf1': 'n',
+ '\xd2': 'O', '\xd3': 'O', '\xd4': 'O', '\xd5': 'O', '\xd6': 'O', '\xd8': 'O',
+ '\xf2': 'o', '\xf3': 'o', '\xf4': 'o', '\xf5': 'o', '\xf6': 'o', '\xf8': 'o',
+ '\xd9': 'U', '\xda': 'U', '\xdb': 'U', '\xdc': 'U',
+ '\xf9': 'u', '\xfa': 'u', '\xfb': 'u', '\xfc': 'u',
+ '\xdd': 'Y', '\xfd': 'y', '\xff': 'y',
+ '\xc6': 'Ae', '\xe6': 'ae',
+ '\xde': 'Th', '\xfe': 'th',
+ '\xdf': 'ss'
+};
+
+/**
+ * Used by `_.deburr` to convert latin-1 supplementary letters to basic latin letters.
+ *
+ * @private
+ * @param {string} letter The matched letter to deburr.
+ * @returns {string} Returns the deburred letter.
+ */
+function deburrLetter(letter) {
+ return deburredLetters[letter];
+}
+
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objectToString = objectProto.toString;
+
+/** Built-in value references. */
+var Symbol = root.Symbol;
+
+/** Used to convert symbols to primitives and strings. */
+var symbolProto = Symbol ? Symbol.prototype : undefined,
+ symbolToString = Symbol ? symbolProto.toString : undefined;
+
+/**
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
+ * and has a `typeof` result of "object".
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ * @example
+ *
+ * _.isObjectLike({});
+ * // => true
+ *
+ * _.isObjectLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isObjectLike(_.noop);
+ * // => false
+ *
+ * _.isObjectLike(null);
+ * // => false
+ */
+function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+}
+
+/**
+ * Checks if `value` is classified as a `Symbol` primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isSymbol(Symbol.iterator);
+ * // => true
+ *
+ * _.isSymbol('abc');
+ * // => false
+ */
+function isSymbol(value) {
+ return typeof value == 'symbol' ||
+ (isObjectLike(value) && objectToString.call(value) == symbolTag);
+}
+
+/**
+ * Converts `value` to a string if it's not one. An empty string is returned
+ * for `null` and `undefined` values. The sign of `-0` is preserved.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {string} Returns the string.
+ * @example
+ *
+ * _.toString(null);
+ * // => ''
+ *
+ * _.toString(-0);
+ * // => '-0'
+ *
+ * _.toString([1, 2, 3]);
+ * // => '1,2,3'
+ */
+function toString(value) {
+ // Exit early for strings to avoid a performance hit in some environments.
+ if (typeof value == 'string') {
+ return value;
+ }
+ if (value == null) {
+ return '';
+ }
+ if (isSymbol(value)) {
+ return Symbol ? symbolToString.call(value) : '';
+ }
+ var result = (value + '');
+ return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
+}
+
+/**
+ * Deburrs `string` by converting [latin-1 supplementary letters](https://en.wikipedia.org/wiki/Latin-1_Supplement_(Unicode_block)#Character_table)
+ * to basic latin letters and removing [combining diacritical marks](https://en.wikipedia.org/wiki/Combining_Diacritical_Marks).
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to deburr.
+ * @returns {string} Returns the deburred string.
+ * @example
+ *
+ * _.deburr('déjà vu');
+ * // => 'deja vu'
+ */
+function deburr(string) {
+ string = toString(string);
+ return string && string.replace(reLatin1, deburrLetter).replace(reComboMark, '');
+}
+
+module.exports = deburr;
+
+},{"lodash._root":44}],44:[function(require,module,exports){
+(function (global){
+/**
+ * lodash 3.0.1 (Custom Build)
+ * Build: `lodash modularize exports="npm" -o ./`
+ * Copyright 2012-2016 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/** Used to determine if values are of the language type `Object`. */
+var objectTypes = {
+ 'function': true,
+ 'object': true
+};
+
+/** Detect free variable `exports`. */
+var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)
+ ? exports
+ : undefined;
+
+/** Detect free variable `module`. */
+var freeModule = (objectTypes[typeof module] && module && !module.nodeType)
+ ? module
+ : undefined;
+
+/** Detect free variable `global` from Node.js. */
+var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
+
+/** Detect free variable `self`. */
+var freeSelf = checkGlobal(objectTypes[typeof self] && self);
+
+/** Detect free variable `window`. */
+var freeWindow = checkGlobal(objectTypes[typeof window] && window);
+
+/** Detect `this` as the global object. */
+var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
+
+/**
+ * Used as a reference to the global object.
+ *
+ * The `this` value is used if it's the global object to avoid Greasemonkey's
+ * restricted `window` object, otherwise the `window` object is used.
+ */
+var root = freeGlobal ||
+ ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) ||
+ freeSelf || thisGlobal || Function('return this')();
+
+/**
+ * Checks if `value` is a global object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {null|Object} Returns `value` if it's a global object, else `null`.
+ */
+function checkGlobal(value) {
+ return (value && value.Object === Object) ? value : null;
+}
+
+module.exports = root;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{}],45:[function(require,module,exports){
+/**
+ * lodash 3.2.0 (Custom Build)
+ * Build: `lodash modularize exports="npm" -o ./`
+ * Copyright 2012-2016 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var root = require('lodash._root');
+
+/** Used as references for various `Number` constants. */
+var INFINITY = 1 / 0;
+
+/** `Object#toString` result references. */
+var symbolTag = '[object Symbol]';
+
+/** Used to compose unicode character classes. */
+var rsAstralRange = '\\ud800-\\udfff',
+ rsComboMarksRange = '\\u0300-\\u036f\\ufe20-\\ufe23',
+ rsComboSymbolsRange = '\\u20d0-\\u20f0',
+ rsDingbatRange = '\\u2700-\\u27bf',
+ rsLowerRange = 'a-z\\xdf-\\xf6\\xf8-\\xff',
+ rsMathOpRange = '\\xac\\xb1\\xd7\\xf7',
+ rsNonCharRange = '\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf',
+ rsQuoteRange = '\\u2018\\u2019\\u201c\\u201d',
+ rsSpaceRange = ' \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000',
+ rsUpperRange = 'A-Z\\xc0-\\xd6\\xd8-\\xde',
+ rsVarRange = '\\ufe0e\\ufe0f',
+ rsBreakRange = rsMathOpRange + rsNonCharRange + rsQuoteRange + rsSpaceRange;
+
+/** Used to compose unicode capture groups. */
+var rsBreak = '[' + rsBreakRange + ']',
+ rsCombo = '[' + rsComboMarksRange + rsComboSymbolsRange + ']',
+ rsDigits = '\\d+',
+ rsDingbat = '[' + rsDingbatRange + ']',
+ rsLower = '[' + rsLowerRange + ']',
+ rsMisc = '[^' + rsAstralRange + rsBreakRange + rsDigits + rsDingbatRange + rsLowerRange + rsUpperRange + ']',
+ rsFitz = '\\ud83c[\\udffb-\\udfff]',
+ rsModifier = '(?:' + rsCombo + '|' + rsFitz + ')',
+ rsNonAstral = '[^' + rsAstralRange + ']',
+ rsRegional = '(?:\\ud83c[\\udde6-\\uddff]){2}',
+ rsSurrPair = '[\\ud800-\\udbff][\\udc00-\\udfff]',
+ rsUpper = '[' + rsUpperRange + ']',
+ rsZWJ = '\\u200d';
+
+/** Used to compose unicode regexes. */
+var rsLowerMisc = '(?:' + rsLower + '|' + rsMisc + ')',
+ rsUpperMisc = '(?:' + rsUpper + '|' + rsMisc + ')',
+ reOptMod = rsModifier + '?',
+ rsOptVar = '[' + rsVarRange + ']?',
+ rsOptJoin = '(?:' + rsZWJ + '(?:' + [rsNonAstral, rsRegional, rsSurrPair].join('|') + ')' + rsOptVar + reOptMod + ')*',
+ rsSeq = rsOptVar + reOptMod + rsOptJoin,
+ rsEmoji = '(?:' + [rsDingbat, rsRegional, rsSurrPair].join('|') + ')' + rsSeq;
+
+/** Used to match non-compound words composed of alphanumeric characters. */
+var reBasicWord = /[a-zA-Z0-9]+/g;
+
+/** Used to match complex or compound words. */
+var reComplexWord = RegExp([
+ rsUpper + '?' + rsLower + '+(?=' + [rsBreak, rsUpper, '$'].join('|') + ')',
+ rsUpperMisc + '+(?=' + [rsBreak, rsUpper + rsLowerMisc, '$'].join('|') + ')',
+ rsUpper + '?' + rsLowerMisc + '+',
+ rsUpper + '+',
+ rsDigits,
+ rsEmoji
+].join('|'), 'g');
+
+/** Used to detect strings that need a more robust regexp to match words. */
+var reHasComplexWord = /[a-z][A-Z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/;
+
+/** Used for built-in method references. */
+var objectProto = Object.prototype;
+
+/**
+ * Used to resolve the [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)
+ * of values.
+ */
+var objectToString = objectProto.toString;
+
+/** Built-in value references. */
+var Symbol = root.Symbol;
+
+/** Used to convert symbols to primitives and strings. */
+var symbolProto = Symbol ? Symbol.prototype : undefined,
+ symbolToString = Symbol ? symbolProto.toString : undefined;
+
+/**
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
+ * and has a `typeof` result of "object".
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ * @example
+ *
+ * _.isObjectLike({});
+ * // => true
+ *
+ * _.isObjectLike([1, 2, 3]);
+ * // => true
+ *
+ * _.isObjectLike(_.noop);
+ * // => false
+ *
+ * _.isObjectLike(null);
+ * // => false
+ */
+function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+}
+
+/**
+ * Checks if `value` is classified as a `Symbol` primitive or object.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
+ * @example
+ *
+ * _.isSymbol(Symbol.iterator);
+ * // => true
+ *
+ * _.isSymbol('abc');
+ * // => false
+ */
+function isSymbol(value) {
+ return typeof value == 'symbol' ||
+ (isObjectLike(value) && objectToString.call(value) == symbolTag);
+}
+
+/**
+ * Converts `value` to a string if it's not one. An empty string is returned
+ * for `null` and `undefined` values. The sign of `-0` is preserved.
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to process.
+ * @returns {string} Returns the string.
+ * @example
+ *
+ * _.toString(null);
+ * // => ''
+ *
+ * _.toString(-0);
+ * // => '-0'
+ *
+ * _.toString([1, 2, 3]);
+ * // => '1,2,3'
+ */
+function toString(value) {
+ // Exit early for strings to avoid a performance hit in some environments.
+ if (typeof value == 'string') {
+ return value;
+ }
+ if (value == null) {
+ return '';
+ }
+ if (isSymbol(value)) {
+ return Symbol ? symbolToString.call(value) : '';
+ }
+ var result = (value + '');
+ return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
+}
+
+/**
+ * Splits `string` into an array of its words.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to inspect.
+ * @param {RegExp|string} [pattern] The pattern to match words.
+ * @param- {Object} [guard] Enables use as an iteratee for functions like `_.map`.
+ * @returns {Array} Returns the words of `string`.
+ * @example
+ *
+ * _.words('fred, barney, & pebbles');
+ * // => ['fred', 'barney', 'pebbles']
+ *
+ * _.words('fred, barney, & pebbles', /[^, ]+/g);
+ * // => ['fred', 'barney', '&', 'pebbles']
+ */
+function words(string, pattern, guard) {
+ string = toString(string);
+ pattern = guard ? undefined : pattern;
+
+ if (pattern === undefined) {
+ pattern = reHasComplexWord.test(string) ? reComplexWord : reBasicWord;
+ }
+ return string.match(pattern) || [];
+}
+
+module.exports = words;
+
+},{"lodash._root":46}],46:[function(require,module,exports){
+(function (global){
+/**
+ * lodash 3.0.1 (Custom Build)
+ * Build: `lodash modularize exports="npm" -o ./`
+ * Copyright 2012-2016 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/** Used to determine if values are of the language type `Object`. */
+var objectTypes = {
+ 'function': true,
+ 'object': true
+};
+
+/** Detect free variable `exports`. */
+var freeExports = (objectTypes[typeof exports] && exports && !exports.nodeType)
+ ? exports
+ : undefined;
+
+/** Detect free variable `module`. */
+var freeModule = (objectTypes[typeof module] && module && !module.nodeType)
+ ? module
+ : undefined;
+
+/** Detect free variable `global` from Node.js. */
+var freeGlobal = checkGlobal(freeExports && freeModule && typeof global == 'object' && global);
+
+/** Detect free variable `self`. */
+var freeSelf = checkGlobal(objectTypes[typeof self] && self);
+
+/** Detect free variable `window`. */
+var freeWindow = checkGlobal(objectTypes[typeof window] && window);
+
+/** Detect `this` as the global object. */
+var thisGlobal = checkGlobal(objectTypes[typeof this] && this);
+
+/**
+ * Used as a reference to the global object.
+ *
+ * The `this` value is used if it's the global object to avoid Greasemonkey's
+ * restricted `window` object, otherwise the `window` object is used.
+ */
+var root = freeGlobal ||
+ ((freeWindow !== (thisGlobal && thisGlobal.window)) && freeWindow) ||
+ freeSelf || thisGlobal || Function('return this')();
+
+/**
+ * Checks if `value` is a global object.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {null|Object} Returns `value` if it's a global object, else `null`.
+ */
+function checkGlobal(value) {
+ return (value && value.Object === Object) ? value : null;
+}
+
+module.exports = root;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{}],47:[function(require,module,exports){
+/**
+ * lodash 3.1.0 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.2
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var baseFlatten = require('lodash._baseflatten'),
+ baseUniq = require('lodash._baseuniq'),
+ restParam = require('lodash.restparam');
+
+/**
+ * Creates an array of unique values, in order, of the provided arrays using
+ * `SameValueZero` for equality comparisons.
+ *
+ * **Note:** [`SameValueZero`](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-samevaluezero)
+ * comparisons are like strict equality comparisons, e.g. `===`, except that
+ * `NaN` matches `NaN`.
+ *
+ * @static
+ * @memberOf _
+ * @category Array
+ * @param {...Array} [arrays] The arrays to inspect.
+ * @returns {Array} Returns the new array of combined values.
+ * @example
+ *
+ * _.union([1, 2], [4, 2], [2, 1]);
+ * // => [1, 2, 4]
+ */
+var union = restParam(function(arrays) {
+ return baseUniq(baseFlatten(arrays, false, true));
+});
+
+module.exports = union;
+
+},{"lodash._baseflatten":48,"lodash._baseuniq":51,"lodash.restparam":56}],48:[function(require,module,exports){
+/**
+ * lodash 3.1.4 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var isArguments = require('lodash.isarguments'),
+ isArray = require('lodash.isarray');
+
+/**
+ * Checks if `value` is object-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
+ */
+function isObjectLike(value) {
+ return !!value && typeof value == 'object';
+}
+
+/**
+ * Used as the [maximum length](http://ecma-international.org/ecma-262/6.0/#sec-number.max_safe_integer)
+ * of an array-like value.
+ */
+var MAX_SAFE_INTEGER = 9007199254740991;
+
+/**
+ * Appends the elements of `values` to `array`.
+ *
+ * @private
+ * @param {Array} array The array to modify.
+ * @param {Array} values The values to append.
+ * @returns {Array} Returns `array`.
+ */
+function arrayPush(array, values) {
+ var index = -1,
+ length = values.length,
+ offset = array.length;
+
+ while (++index < length) {
+ array[offset + index] = values[index];
+ }
+ return array;
+}
+
+/**
+ * The base implementation of `_.flatten` with added support for restricting
+ * flattening and specifying the start index.
+ *
+ * @private
+ * @param {Array} array The array to flatten.
+ * @param {boolean} [isDeep] Specify a deep flatten.
+ * @param {boolean} [isStrict] Restrict flattening to arrays-like objects.
+ * @param {Array} [result=[]] The initial result value.
+ * @returns {Array} Returns the new flattened array.
+ */
+function baseFlatten(array, isDeep, isStrict, result) {
+ result || (result = []);
+
+ var index = -1,
+ length = array.length;
+
+ while (++index < length) {
+ var value = array[index];
+ if (isObjectLike(value) && isArrayLike(value) &&
+ (isStrict || isArray(value) || isArguments(value))) {
+ if (isDeep) {
+ // Recursively flatten arrays (susceptible to call stack limits).
+ baseFlatten(value, isDeep, isStrict, result);
+ } else {
+ arrayPush(result, value);
+ }
+ } else if (!isStrict) {
+ result[result.length] = value;
+ }
+ }
+ return result;
+}
+
+/**
+ * The base implementation of `_.property` without support for deep paths.
+ *
+ * @private
+ * @param {string} key The key of the property to get.
+ * @returns {Function} Returns the new function.
+ */
+function baseProperty(key) {
+ return function(object) {
+ return object == null ? undefined : object[key];
+ };
+}
+
+/**
+ * Gets the "length" property value of `object`.
+ *
+ * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792)
+ * that affects Safari on at least iOS 8.1-8.3 ARM64.
+ *
+ * @private
+ * @param {Object} object The object to query.
+ * @returns {*} Returns the "length" value.
+ */
+var getLength = baseProperty('length');
+
+/**
+ * Checks if `value` is array-like.
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is array-like, else `false`.
+ */
+function isArrayLike(value) {
+ return value != null && isLength(getLength(value));
+}
+
+/**
+ * Checks if `value` is a valid array-like length.
+ *
+ * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).
+ *
+ * @private
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
+ */
+function isLength(value) {
+ return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
+}
+
+module.exports = baseFlatten;
+
+},{"lodash.isarguments":49,"lodash.isarray":50}],49:[function(require,module,exports){
+arguments[4][40][0].apply(exports,arguments)
+},{"dup":40}],50:[function(require,module,exports){
+arguments[4][41][0].apply(exports,arguments)
+},{"dup":41}],51:[function(require,module,exports){
+/**
+ * lodash 3.0.3 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var baseIndexOf = require('lodash._baseindexof'),
+ cacheIndexOf = require('lodash._cacheindexof'),
+ createCache = require('lodash._createcache');
+
+/** Used as the size to enable large array optimizations. */
+var LARGE_ARRAY_SIZE = 200;
+
+/**
+ * The base implementation of `_.uniq` without support for callback shorthands
+ * and `this` binding.
+ *
+ * @private
+ * @param {Array} array The array to inspect.
+ * @param {Function} [iteratee] The function invoked per iteration.
+ * @returns {Array} Returns the new duplicate-value-free array.
+ */
+function baseUniq(array, iteratee) {
+ var index = -1,
+ indexOf = baseIndexOf,
+ length = array.length,
+ isCommon = true,
+ isLarge = isCommon && length >= LARGE_ARRAY_SIZE,
+ seen = isLarge ? createCache() : null,
+ result = [];
+
+ if (seen) {
+ indexOf = cacheIndexOf;
+ isCommon = false;
+ } else {
+ isLarge = false;
+ seen = iteratee ? [] : result;
+ }
+ outer:
+ while (++index < length) {
+ var value = array[index],
+ computed = iteratee ? iteratee(value, index, array) : value;
+
+ if (isCommon && value === value) {
+ var seenIndex = seen.length;
+ while (seenIndex--) {
+ if (seen[seenIndex] === computed) {
+ continue outer;
+ }
+ }
+ if (iteratee) {
+ seen.push(computed);
+ }
+ result.push(value);
+ }
+ else if (indexOf(seen, computed, 0) < 0) {
+ if (iteratee || isLarge) {
+ seen.push(computed);
+ }
+ result.push(value);
+ }
+ }
+ return result;
+}
+
+module.exports = baseUniq;
+
+},{"lodash._baseindexof":52,"lodash._cacheindexof":53,"lodash._createcache":54}],52:[function(require,module,exports){
+/**
+ * lodash 3.1.0 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.2
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/**
+ * The base implementation of `_.indexOf` without support for binary searches.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {*} value The value to search for.
+ * @param {number} fromIndex The index to search from.
+ * @returns {number} Returns the index of the matched value, else `-1`.
+ */
+function baseIndexOf(array, value, fromIndex) {
+ if (value !== value) {
+ return indexOfNaN(array, fromIndex);
+ }
+ var index = fromIndex - 1,
+ length = array.length;
+
+ while (++index < length) {
+ if (array[index] === value) {
+ return index;
+ }
+ }
+ return -1;
+}
+
+/**
+ * Gets the index at which the first occurrence of `NaN` is found in `array`.
+ * If `fromRight` is provided elements of `array` are iterated from right to left.
+ *
+ * @private
+ * @param {Array} array The array to search.
+ * @param {number} fromIndex The index to search from.
+ * @param {boolean} [fromRight] Specify iterating from right to left.
+ * @returns {number} Returns the index of the matched `NaN`, else `-1`.
+ */
+function indexOfNaN(array, fromIndex, fromRight) {
+ var length = array.length,
+ index = fromIndex + (fromRight ? 0 : -1);
+
+ while ((fromRight ? index-- : ++index < length)) {
+ var other = array[index];
+ if (other !== other) {
+ return index;
+ }
+ }
+ return -1;
+}
+
+module.exports = baseIndexOf;
+
+},{}],53:[function(require,module,exports){
+/**
+ * lodash 3.0.2 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/**
+ * Checks if `value` is in `cache` mimicking the return signature of
+ * `_.indexOf` by returning `0` if the value is found, else `-1`.
+ *
+ * @private
+ * @param {Object} cache The cache to search.
+ * @param {*} value The value to search for.
+ * @returns {number} Returns `0` if `value` is found, else `-1`.
+ */
+function cacheIndexOf(cache, value) {
+ var data = cache.data,
+ result = (typeof value == 'string' || isObject(value)) ? data.set.has(value) : data.hash[value];
+
+ return result ? 0 : -1;
+}
+
+/**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(1);
+ * // => false
+ */
+function isObject(value) {
+ // Avoid a V8 JIT bug in Chrome 19-20.
+ // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
+ var type = typeof value;
+ return !!value && (type == 'object' || type == 'function');
+}
+
+module.exports = cacheIndexOf;
+
+},{}],54:[function(require,module,exports){
+(function (global){
+/**
+ * lodash 3.1.2 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+var getNative = require('lodash._getnative');
+
+/** Native method references. */
+var Set = getNative(global, 'Set');
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeCreate = getNative(Object, 'create');
+
+/**
+ *
+ * Creates a cache object to store unique values.
+ *
+ * @private
+ * @param {Array} [values] The values to cache.
+ */
+function SetCache(values) {
+ var length = values ? values.length : 0;
+
+ this.data = { 'hash': nativeCreate(null), 'set': new Set };
+ while (length--) {
+ this.push(values[length]);
+ }
+}
+
+/**
+ * Adds `value` to the cache.
+ *
+ * @private
+ * @name push
+ * @memberOf SetCache
+ * @param {*} value The value to cache.
+ */
+function cachePush(value) {
+ var data = this.data;
+ if (typeof value == 'string' || isObject(value)) {
+ data.set.add(value);
+ } else {
+ data.hash[value] = true;
+ }
+}
+
+/**
+ * Creates a `Set` cache object to optimize linear searches of large arrays.
+ *
+ * @private
+ * @param {Array} [values] The values to cache.
+ * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`.
+ */
+function createCache(values) {
+ return (nativeCreate && Set) ? new SetCache(values) : null;
+}
+
+/**
+ * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
+ * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
+ *
+ * @static
+ * @memberOf _
+ * @category Lang
+ * @param {*} value The value to check.
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
+ * @example
+ *
+ * _.isObject({});
+ * // => true
+ *
+ * _.isObject([1, 2, 3]);
+ * // => true
+ *
+ * _.isObject(1);
+ * // => false
+ */
+function isObject(value) {
+ // Avoid a V8 JIT bug in Chrome 19-20.
+ // See https://code.google.com/p/v8/issues/detail?id=2291 for more details.
+ var type = typeof value;
+ return !!value && (type == 'object' || type == 'function');
+}
+
+// Add functions to the `Set` cache.
+SetCache.prototype.push = cachePush;
+
+module.exports = createCache;
+
+}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
+
+},{"lodash._getnative":55}],55:[function(require,module,exports){
+arguments[4][39][0].apply(exports,arguments)
+},{"dup":39}],56:[function(require,module,exports){
+/**
+ * lodash 3.6.1 (Custom Build)
+ * Build: `lodash modern modularize exports="npm" -o ./`
+ * Copyright 2012-2015 The Dojo Foundation
+ * Based on Underscore.js 1.8.3
+ * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
+ * Available under MIT license
+ */
+
+/** Used as the `TypeError` message for "Functions" methods. */
+var FUNC_ERROR_TEXT = 'Expected a function';
+
+/* Native method references for those with the same name as other `lodash` methods. */
+var nativeMax = Math.max;
+
+/**
+ * Creates a function that invokes `func` with the `this` binding of the
+ * created function and arguments from `start` and beyond provided as an array.
+ *
+ * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters).
+ *
+ * @static
+ * @memberOf _
+ * @category Function
+ * @param {Function} func The function to apply a rest parameter to.
+ * @param {number} [start=func.length-1] The start position of the rest parameter.
+ * @returns {Function} Returns the new function.
+ * @example
+ *
+ * var say = _.restParam(function(what, names) {
+ * return what + ' ' + _.initial(names).join(', ') +
+ * (_.size(names) > 1 ? ', & ' : '') + _.last(names);
+ * });
+ *
+ * say('hello', 'fred', 'barney', 'pebbles');
+ * // => 'hello fred, barney, & pebbles'
+ */
+function restParam(func, start) {
+ if (typeof func != 'function') {
+ throw new TypeError(FUNC_ERROR_TEXT);
+ }
+ start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0);
+ return function() {
+ var args = arguments,
+ index = -1,
+ length = nativeMax(args.length - start, 0),
+ rest = Array(length);
+
+ while (++index < length) {
+ rest[index] = args[start + index];
+ }
+ switch (start) {
+ case 0: return func.call(this, rest);
+ case 1: return func.call(this, args[0], rest);
+ case 2: return func.call(this, args[0], args[1], rest);
+ }
+ var otherArgs = Array(start + 1);
+ index = -1;
+ while (++index < start) {
+ otherArgs[index] = args[index];
+ }
+ otherArgs[start] = rest;
+ return func.apply(this, otherArgs);
+ };
+}
+
+module.exports = restParam;
+
+},{}],57:[function(require,module,exports){
+var VNode = require('./vnode');
+var is = require('./is');
+
+function addNS(data, children) {
+ data.ns = 'http://www.w3.org/2000/svg';
+ if (children !== undefined) {
+ for (var i = 0; i < children.length; ++i) {
+ addNS(children[i].data, children[i].children);
+ }
+ }
+}
+
+module.exports = function h(sel, b, c) {
+ var data = {}, children, text, i;
+ if (arguments.length === 3) {
+ data = b;
+ if (is.array(c)) { children = c; }
+ else if (is.primitive(c)) { text = c; }
+ } else if (arguments.length === 2) {
+ if (is.array(b)) { children = b; }
+ else if (is.primitive(b)) { text = b; }
+ else { data = b; }
+ }
+ if (is.array(children)) {
+ for (i = 0; i < children.length; ++i) {
+ if (is.primitive(children[i])) children[i] = VNode(undefined, undefined, undefined, children[i]);
+ }
+ }
+ if (sel[0] === 's' && sel[1] === 'v' && sel[2] === 'g') {
+ addNS(data, children);
+ }
+ return VNode(sel, data, children, text, undefined);
+};
+
+},{"./is":59,"./vnode":68}],58:[function(require,module,exports){
+function createElement(tagName){
+ return document.createElement(tagName);
+}
+
+function createElementNS(namespaceURI, qualifiedName){
+ return document.createElementNS(namespaceURI, qualifiedName);
+}
+
+function createTextNode(text){
+ return document.createTextNode(text);
+}
+
+
+function insertBefore(parentNode, newNode, referenceNode){
+ parentNode.insertBefore(newNode, referenceNode);
+}
+
+
+function removeChild(node, child){
+ node.removeChild(child);
+}
+
+function appendChild(node, child){
+ node.appendChild(child);
+}
+
+function parentNode(node){
+ return node.parentElement;
+}
+
+function nextSibling(node){
+ return node.nextSibling;
+}
+
+function tagName(node){
+ return node.tagName;
+}
+
+function setTextContent(node, text){
+ node.textContent = text;
+}
+
+module.exports = {
+ createElement: createElement,
+ createElementNS: createElementNS,
+ createTextNode: createTextNode,
+ appendChild: appendChild,
+ removeChild: removeChild,
+ insertBefore: insertBefore,
+ parentNode: parentNode,
+ nextSibling: nextSibling,
+ tagName: tagName,
+ setTextContent: setTextContent
+};
+
+},{}],59:[function(require,module,exports){
+module.exports = {
+ array: Array.isArray,
+ primitive: function(s) { return typeof s === 'string' || typeof s === 'number'; },
+};
+
+},{}],60:[function(require,module,exports){
+var booleanAttrs = ["allowfullscreen", "async", "autofocus", "autoplay", "checked", "compact", "controls", "declare",
+ "default", "defaultchecked", "defaultmuted", "defaultselected", "defer", "disabled", "draggable",
+ "enabled", "formnovalidate", "hidden", "indeterminate", "inert", "ismap", "itemscope", "loop", "multiple",
+ "muted", "nohref", "noresize", "noshade", "novalidate", "nowrap", "open", "pauseonexit", "readonly",
+ "required", "reversed", "scoped", "seamless", "selected", "sortable", "spellcheck", "translate",
+ "truespeed", "typemustmatch", "visible"];
+
+var booleanAttrsDict = {};
+for(var i=0, len = booleanAttrs.length; i < len; i++) {
+ booleanAttrsDict[booleanAttrs[i]] = true;
+}
+
+function updateAttrs(oldVnode, vnode) {
+ var key, cur, old, elm = vnode.elm,
+ oldAttrs = oldVnode.data.attrs || {}, attrs = vnode.data.attrs || {};
+
+ // update modified attributes, add new attributes
+ for (key in attrs) {
+ cur = attrs[key];
+ old = oldAttrs[key];
+ if (old !== cur) {
+ // TODO: add support to namespaced attributes (setAttributeNS)
+ if(!cur && booleanAttrsDict[key])
+ elm.removeAttribute(key);
+ else
+ elm.setAttribute(key, cur);
+ }
+ }
+ //remove removed attributes
+ // use `in` operator since the previous `for` iteration uses it (.i.e. add even attributes with undefined value)
+ // the other option is to remove all attributes with value == undefined
+ for (key in oldAttrs) {
+ if (!(key in attrs)) {
+ elm.removeAttribute(key);
+ }
+ }
+}
+
+module.exports = {create: updateAttrs, update: updateAttrs};
+
+},{}],61:[function(require,module,exports){
+function updateClass(oldVnode, vnode) {
+ var cur, name, elm = vnode.elm,
+ oldClass = oldVnode.data.class || {},
+ klass = vnode.data.class || {};
+ for (name in oldClass) {
+ if (!klass[name]) {
+ elm.classList.remove(name);
+ }
+ }
+ for (name in klass) {
+ cur = klass[name];
+ if (cur !== oldClass[name]) {
+ elm.classList[cur ? 'add' : 'remove'](name);
+ }
+ }
+}
+
+module.exports = {create: updateClass, update: updateClass};
+
+},{}],62:[function(require,module,exports){
+var is = require('../is');
+
+function arrInvoker(arr) {
+ return function() {
+ // Special case when length is two, for performance
+ arr.length === 2 ? arr[0](arr[1]) : arr[0].apply(undefined, arr.slice(1));
+ };
+}
+
+function fnInvoker(o) {
+ return function(ev) { o.fn(ev); };
+}
+
+function updateEventListeners(oldVnode, vnode) {
+ var name, cur, old, elm = vnode.elm,
+ oldOn = oldVnode.data.on || {}, on = vnode.data.on;
+ if (!on) return;
+ for (name in on) {
+ cur = on[name];
+ old = oldOn[name];
+ if (old === undefined) {
+ if (is.array(cur)) {
+ elm.addEventListener(name, arrInvoker(cur));
+ } else {
+ cur = {fn: cur};
+ on[name] = cur;
+ elm.addEventListener(name, fnInvoker(cur));
+ }
+ } else if (is.array(old)) {
+ // Deliberately modify old array since it's captured in closure created with `arrInvoker`
+ old.length = cur.length;
+ for (var i = 0; i < old.length; ++i) old[i] = cur[i];
+ on[name] = old;
+ } else {
+ old.fn = cur;
+ on[name] = old;
+ }
+ }
+}
+
+module.exports = {create: updateEventListeners, update: updateEventListeners};
+
+},{"../is":59}],63:[function(require,module,exports){
+var raf = (typeof window !== 'undefined' && window.requestAnimationFrame) || setTimeout;
+var nextFrame = function(fn) { raf(function() { raf(fn); }); };
+
+function setNextFrame(obj, prop, val) {
+ nextFrame(function() { obj[prop] = val; });
+}
+
+function getTextNodeRect(textNode) {
+ var rect;
+ if (document.createRange) {
+ var range = document.createRange();
+ range.selectNodeContents(textNode);
+ if (range.getBoundingClientRect) {
+ rect = range.getBoundingClientRect();
+ }
+ }
+ return rect;
+}
+
+function calcTransformOrigin(isTextNode, textRect, boundingRect) {
+ if (isTextNode) {
+ if (textRect) {
+ //calculate pixels to center of text from left edge of bounding box
+ var relativeCenterX = textRect.left + textRect.width/2 - boundingRect.left;
+ var relativeCenterY = textRect.top + textRect.height/2 - boundingRect.top;
+ return relativeCenterX + 'px ' + relativeCenterY + 'px';
+ }
+ }
+ return '0 0'; //top left
+}
+
+function getTextDx(oldTextRect, newTextRect) {
+ if (oldTextRect && newTextRect) {
+ return ((oldTextRect.left + oldTextRect.width/2) - (newTextRect.left + newTextRect.width/2));
+ }
+ return 0;
+}
+function getTextDy(oldTextRect, newTextRect) {
+ if (oldTextRect && newTextRect) {
+ return ((oldTextRect.top + oldTextRect.height/2) - (newTextRect.top + newTextRect.height/2));
+ }
+ return 0;
+}
+
+function isTextElement(elm) {
+ return elm.childNodes.length === 1 && elm.childNodes[0].nodeType === 3;
+}
+
+var removed, created;
+
+function pre(oldVnode, vnode) {
+ removed = {};
+ created = [];
+}
+
+function create(oldVnode, vnode) {
+ var hero = vnode.data.hero;
+ if (hero && hero.id) {
+ created.push(hero.id);
+ created.push(vnode);
+ }
+}
+
+function destroy(vnode) {
+ var hero = vnode.data.hero;
+ if (hero && hero.id) {
+ var elm = vnode.elm;
+ vnode.isTextNode = isTextElement(elm); //is this a text node?
+ vnode.boundingRect = elm.getBoundingClientRect(); //save the bounding rectangle to a new property on the vnode
+ vnode.textRect = vnode.isTextNode ? getTextNodeRect(elm.childNodes[0]) : null; //save bounding rect of inner text node
+ var computedStyle = window.getComputedStyle(elm, null); //get current styles (includes inherited properties)
+ vnode.savedStyle = JSON.parse(JSON.stringify(computedStyle)); //save a copy of computed style values
+ removed[hero.id] = vnode;
+ }
+}
+
+function post() {
+ var i, id, newElm, oldVnode, oldElm, hRatio, wRatio,
+ oldRect, newRect, dx, dy, origTransform, origTransition,
+ newStyle, oldStyle, newComputedStyle, isTextNode,
+ newTextRect, oldTextRect;
+ for (i = 0; i < created.length; i += 2) {
+ id = created[i];
+ newElm = created[i+1].elm;
+ oldVnode = removed[id];
+ if (oldVnode) {
+ isTextNode = oldVnode.isTextNode && isTextElement(newElm); //Are old & new both text?
+ newStyle = newElm.style;
+ newComputedStyle = window.getComputedStyle(newElm, null); //get full computed style for new element
+ oldElm = oldVnode.elm;
+ oldStyle = oldElm.style;
+ //Overall element bounding boxes
+ newRect = newElm.getBoundingClientRect();
+ oldRect = oldVnode.boundingRect; //previously saved bounding rect
+ //Text node bounding boxes & distances
+ if (isTextNode) {
+ newTextRect = getTextNodeRect(newElm.childNodes[0]);
+ oldTextRect = oldVnode.textRect;
+ dx = getTextDx(oldTextRect, newTextRect);
+ dy = getTextDy(oldTextRect, newTextRect);
+ } else {
+ //Calculate distances between old & new positions
+ dx = oldRect.left - newRect.left;
+ dy = oldRect.top - newRect.top;
+ }
+ hRatio = newRect.height / (Math.max(oldRect.height, 1));
+ wRatio = isTextNode ? hRatio : newRect.width / (Math.max(oldRect.width, 1)); //text scales based on hRatio
+ // Animate new element
+ origTransform = newStyle.transform;
+ origTransition = newStyle.transition;
+ if (newComputedStyle.display === 'inline') //inline elements cannot be transformed
+ newStyle.display = 'inline-block'; //this does not appear to have any negative side effects
+ newStyle.transition = origTransition + 'transform 0s';
+ newStyle.transformOrigin = calcTransformOrigin(isTextNode, newTextRect, newRect);
+ newStyle.opacity = '0';
+ newStyle.transform = origTransform + 'translate('+dx+'px, '+dy+'px) ' +
+ 'scale('+1/wRatio+', '+1/hRatio+')';
+ setNextFrame(newStyle, 'transition', origTransition);
+ setNextFrame(newStyle, 'transform', origTransform);
+ setNextFrame(newStyle, 'opacity', '1');
+ // Animate old element
+ for (var key in oldVnode.savedStyle) { //re-apply saved inherited properties
+ if (parseInt(key) != key) {
+ var ms = key.substring(0,2) === 'ms';
+ var moz = key.substring(0,3) === 'moz';
+ var webkit = key.substring(0,6) === 'webkit';
+ if (!ms && !moz && !webkit) //ignore prefixed style properties
+ oldStyle[key] = oldVnode.savedStyle[key];
+ }
+ }
+ oldStyle.position = 'absolute';
+ oldStyle.top = oldRect.top + 'px'; //start at existing position
+ oldStyle.left = oldRect.left + 'px';
+ oldStyle.width = oldRect.width + 'px'; //Needed for elements who were sized relative to their parents
+ oldStyle.height = oldRect.height + 'px'; //Needed for elements who were sized relative to their parents
+ oldStyle.margin = 0; //Margin on hero element leads to incorrect positioning
+ oldStyle.transformOrigin = calcTransformOrigin(isTextNode, oldTextRect, oldRect);
+ oldStyle.transform = '';
+ oldStyle.opacity = '1';
+ document.body.appendChild(oldElm);
+ setNextFrame(oldStyle, 'transform', 'translate('+ -dx +'px, '+ -dy +'px) scale('+wRatio+', '+hRatio+')'); //scale must be on far right for translate to be correct
+ setNextFrame(oldStyle, 'opacity', '0');
+ oldElm.addEventListener('transitionend', function(ev) {
+ if (ev.propertyName === 'transform')
+ document.body.removeChild(ev.target);
+ });
+ }
+ }
+ removed = created = undefined;
+}
+
+module.exports = {pre: pre, create: create, destroy: destroy, post: post};
+
+},{}],64:[function(require,module,exports){
+function updateProps(oldVnode, vnode) {
+ var key, cur, old, elm = vnode.elm,
+ oldProps = oldVnode.data.props || {}, props = vnode.data.props || {};
+ for (key in oldProps) {
+ if (!props[key]) {
+ delete elm[key];
+ }
+ }
+ for (key in props) {
+ cur = props[key];
+ old = oldProps[key];
+ if (old !== cur && (key !== 'value' || elm[key] !== cur)) {
+ elm[key] = cur;
+ }
+ }
+}
+
+module.exports = {create: updateProps, update: updateProps};
+
+},{}],65:[function(require,module,exports){
+var raf = (typeof window !== 'undefined' && window.requestAnimationFrame) || setTimeout;
+var nextFrame = function(fn) { raf(function() { raf(fn); }); };
+
+function setNextFrame(obj, prop, val) {
+ nextFrame(function() { obj[prop] = val; });
+}
+
+function updateStyle(oldVnode, vnode) {
+ var cur, name, elm = vnode.elm,
+ oldStyle = oldVnode.data.style || {},
+ style = vnode.data.style || {},
+ oldHasDel = 'delayed' in oldStyle;
+ for (name in oldStyle) {
+ if (!style[name]) {
+ elm.style[name] = '';
+ }
+ }
+ for (name in style) {
+ cur = style[name];
+ if (name === 'delayed') {
+ for (name in style.delayed) {
+ cur = style.delayed[name];
+ if (!oldHasDel || cur !== oldStyle.delayed[name]) {
+ setNextFrame(elm.style, name, cur);
+ }
+ }
+ } else if (name !== 'remove' && cur !== oldStyle[name]) {
+ elm.style[name] = cur;
+ }
+ }
+}
+
+function applyDestroyStyle(vnode) {
+ var style, name, elm = vnode.elm, s = vnode.data.style;
+ if (!s || !(style = s.destroy)) return;
+ for (name in style) {
+ elm.style[name] = style[name];
+ }
+}
+
+function applyRemoveStyle(vnode, rm) {
+ var s = vnode.data.style;
+ if (!s || !s.remove) {
+ rm();
+ return;
+ }
+ var name, elm = vnode.elm, idx, i = 0, maxDur = 0,
+ compStyle, style = s.remove, amount = 0, applied = [];
+ for (name in style) {
+ applied.push(name);
+ elm.style[name] = style[name];
+ }
+ compStyle = getComputedStyle(elm);
+ var props = compStyle['transition-property'].split(', ');
+ for (; i < props.length; ++i) {
+ if(applied.indexOf(props[i]) !== -1) amount++;
+ }
+ elm.addEventListener('transitionend', function(ev) {
+ if (ev.target === elm) --amount;
+ if (amount === 0) rm();
+ });
+}
+
+module.exports = {create: updateStyle, update: updateStyle, destroy: applyDestroyStyle, remove: applyRemoveStyle};
+
+},{}],66:[function(require,module,exports){
+// jshint newcap: false
+/* global require, module, document, Node */
+'use strict';
+
+var VNode = require('./vnode');
+var is = require('./is');
+var domApi = require('./htmldomapi.js');
+
+function isUndef(s) { return s === undefined; }
+function isDef(s) { return s !== undefined; }
+
+var emptyNode = VNode('', {}, [], undefined, undefined);
+
+function sameVnode(vnode1, vnode2) {
+ return vnode1.key === vnode2.key && vnode1.sel === vnode2.sel;
+}
+
+function createKeyToOldIdx(children, beginIdx, endIdx) {
+ var i, map = {}, key;
+ for (i = beginIdx; i <= endIdx; ++i) {
+ key = children[i].key;
+ if (isDef(key)) map[key] = i;
+ }
+ return map;
+}
+
+var hooks = ['create', 'update', 'remove', 'destroy', 'pre', 'post'];
+
+function init(modules, api) {
+ var i, j, cbs = {};
+
+ if (isUndef(api)) api = domApi;
+
+ for (i = 0; i < hooks.length; ++i) {
+ cbs[hooks[i]] = [];
+ for (j = 0; j < modules.length; ++j) {
+ if (modules[j][hooks[i]] !== undefined) cbs[hooks[i]].push(modules[j][hooks[i]]);
+ }
+ }
+
+ function emptyNodeAt(elm) {
+ return VNode(api.tagName(elm).toLowerCase(), {}, [], undefined, elm);
+ }
+
+ function createRmCb(childElm, listeners) {
+ return function() {
+ if (--listeners === 0) {
+ var parent = api.parentNode(childElm);
+ api.removeChild(parent, childElm);
+ }
+ };
+ }
+
+ function createElm(vnode, insertedVnodeQueue) {
+ var i, thunk, data = vnode.data;
+ if (isDef(data)) {
+ if (isDef(i = data.hook) && isDef(i = i.init)) i(vnode);
+ if (isDef(i = data.vnode)) {
+ thunk = vnode;
+ vnode = i;
+ }
+ }
+ var elm, children = vnode.children, sel = vnode.sel;
+ if (isDef(sel)) {
+ // Parse selector
+ var hashIdx = sel.indexOf('#');
+ var dotIdx = sel.indexOf('.', hashIdx);
+ var hash = hashIdx > 0 ? hashIdx : sel.length;
+ var dot = dotIdx > 0 ? dotIdx : sel.length;
+ var tag = hashIdx !== -1 || dotIdx !== -1 ? sel.slice(0, Math.min(hash, dot)) : sel;
+ elm = vnode.elm = isDef(data) && isDef(i = data.ns) ? api.createElementNS(i, tag)
+ : api.createElement(tag);
+ if (hash < dot) elm.id = sel.slice(hash + 1, dot);
+ if (dotIdx > 0) elm.className = sel.slice(dot+1).replace(/\./g, ' ');
+ if (is.array(children)) {
+ for (i = 0; i < children.length; ++i) {
+ api.appendChild(elm, createElm(children[i], insertedVnodeQueue));
+ }
+ } else if (is.primitive(vnode.text)) {
+ api.appendChild(elm, api.createTextNode(vnode.text));
+ }
+ for (i = 0; i < cbs.create.length; ++i) cbs.create[i](emptyNode, vnode);
+ i = vnode.data.hook; // Reuse variable
+ if (isDef(i)) {
+ if (i.create) i.create(emptyNode, vnode);
+ if (i.insert) insertedVnodeQueue.push(vnode);
+ }
+ } else {
+ elm = vnode.elm = api.createTextNode(vnode.text);
+ }
+ if (isDef(thunk)) thunk.elm = vnode.elm;
+ return vnode.elm;
+ }
+
+ function addVnodes(parentElm, before, vnodes, startIdx, endIdx, insertedVnodeQueue) {
+ for (; startIdx <= endIdx; ++startIdx) {
+ api.insertBefore(parentElm, createElm(vnodes[startIdx], insertedVnodeQueue), before);
+ }
+ }
+
+ function invokeDestroyHook(vnode) {
+ var i, j, data = vnode.data;
+ if (isDef(data)) {
+ if (isDef(i = data.hook) && isDef(i = i.destroy)) i(vnode);
+ for (i = 0; i < cbs.destroy.length; ++i) cbs.destroy[i](vnode);
+ if (isDef(i = vnode.children)) {
+ for (j = 0; j < vnode.children.length; ++j) {
+ invokeDestroyHook(vnode.children[j]);
+ }
+ }
+ if (isDef(i = data.vnode)) invokeDestroyHook(i);
+ }
+ }
+
+ function removeVnodes(parentElm, vnodes, startIdx, endIdx) {
+ for (; startIdx <= endIdx; ++startIdx) {
+ var i, listeners, rm, ch = vnodes[startIdx];
+ if (isDef(ch)) {
+ if (isDef(ch.sel)) {
+ invokeDestroyHook(ch);
+ listeners = cbs.remove.length + 1;
+ rm = createRmCb(ch.elm, listeners);
+ for (i = 0; i < cbs.remove.length; ++i) cbs.remove[i](ch, rm);
+ if (isDef(i = ch.data) && isDef(i = i.hook) && isDef(i = i.remove)) {
+ i(ch, rm);
+ } else {
+ rm();
+ }
+ } else { // Text node
+ api.removeChild(parentElm, ch.elm);
+ }
+ }
+ }
+ }
+
+ function updateChildren(parentElm, oldCh, newCh, insertedVnodeQueue) {
+ var oldStartIdx = 0, newStartIdx = 0;
+ var oldEndIdx = oldCh.length - 1;
+ var oldStartVnode = oldCh[0];
+ var oldEndVnode = oldCh[oldEndIdx];
+ var newEndIdx = newCh.length - 1;
+ var newStartVnode = newCh[0];
+ var newEndVnode = newCh[newEndIdx];
+ var oldKeyToIdx, idxInOld, elmToMove, before;
+
+ while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
+ if (isUndef(oldStartVnode)) {
+ oldStartVnode = oldCh[++oldStartIdx]; // Vnode has been moved left
+ } else if (isUndef(oldEndVnode)) {
+ oldEndVnode = oldCh[--oldEndIdx];
+ } else if (sameVnode(oldStartVnode, newStartVnode)) {
+ patchVnode(oldStartVnode, newStartVnode, insertedVnodeQueue);
+ oldStartVnode = oldCh[++oldStartIdx];
+ newStartVnode = newCh[++newStartIdx];
+ } else if (sameVnode(oldEndVnode, newEndVnode)) {
+ patchVnode(oldEndVnode, newEndVnode, insertedVnodeQueue);
+ oldEndVnode = oldCh[--oldEndIdx];
+ newEndVnode = newCh[--newEndIdx];
+ } else if (sameVnode(oldStartVnode, newEndVnode)) { // Vnode moved right
+ patchVnode(oldStartVnode, newEndVnode, insertedVnodeQueue);
+ api.insertBefore(parentElm, oldStartVnode.elm, api.nextSibling(oldEndVnode.elm));
+ oldStartVnode = oldCh[++oldStartIdx];
+ newEndVnode = newCh[--newEndIdx];
+ } else if (sameVnode(oldEndVnode, newStartVnode)) { // Vnode moved left
+ patchVnode(oldEndVnode, newStartVnode, insertedVnodeQueue);
+ api.insertBefore(parentElm, oldEndVnode.elm, oldStartVnode.elm);
+ oldEndVnode = oldCh[--oldEndIdx];
+ newStartVnode = newCh[++newStartIdx];
+ } else {
+ if (isUndef(oldKeyToIdx)) oldKeyToIdx = createKeyToOldIdx(oldCh, oldStartIdx, oldEndIdx);
+ idxInOld = oldKeyToIdx[newStartVnode.key];
+ if (isUndef(idxInOld)) { // New element
+ api.insertBefore(parentElm, createElm(newStartVnode, insertedVnodeQueue), oldStartVnode.elm);
+ newStartVnode = newCh[++newStartIdx];
+ } else {
+ elmToMove = oldCh[idxInOld];
+ patchVnode(elmToMove, newStartVnode, insertedVnodeQueue);
+ oldCh[idxInOld] = undefined;
+ api.insertBefore(parentElm, elmToMove.elm, oldStartVnode.elm);
+ newStartVnode = newCh[++newStartIdx];
+ }
+ }
+ }
+ if (oldStartIdx > oldEndIdx) {
+ before = isUndef(newCh[newEndIdx+1]) ? null : newCh[newEndIdx+1].elm;
+ addVnodes(parentElm, before, newCh, newStartIdx, newEndIdx, insertedVnodeQueue);
+ } else if (newStartIdx > newEndIdx) {
+ removeVnodes(parentElm, oldCh, oldStartIdx, oldEndIdx);
+ }
+ }
+
+ function patchVnode(oldVnode, vnode, insertedVnodeQueue) {
+ var i, hook;
+ if (isDef(i = vnode.data) && isDef(hook = i.hook) && isDef(i = hook.prepatch)) {
+ i(oldVnode, vnode);
+ }
+ if (isDef(i = oldVnode.data) && isDef(i = i.vnode)) oldVnode = i;
+ if (isDef(i = vnode.data) && isDef(i = i.vnode)) {
+ patchVnode(oldVnode, i, insertedVnodeQueue);
+ vnode.elm = i.elm;
+ return;
+ }
+ var elm = vnode.elm = oldVnode.elm, oldCh = oldVnode.children, ch = vnode.children;
+ if (oldVnode === vnode) return;
+ if (!sameVnode(oldVnode, vnode)) {
+ var parentElm = api.parentNode(oldVnode.elm);
+ elm = createElm(vnode, insertedVnodeQueue);
+ api.insertBefore(parentElm, elm, oldVnode.elm);
+ removeVnodes(parentElm, [oldVnode], 0, 0);
+ return;
+ }
+ if (isDef(vnode.data)) {
+ for (i = 0; i < cbs.update.length; ++i) cbs.update[i](oldVnode, vnode);
+ i = vnode.data.hook;
+ if (isDef(i) && isDef(i = i.update)) i(oldVnode, vnode);
+ }
+ if (isUndef(vnode.text)) {
+ if (isDef(oldCh) && isDef(ch)) {
+ if (oldCh !== ch) updateChildren(elm, oldCh, ch, insertedVnodeQueue);
+ } else if (isDef(ch)) {
+ if (isDef(oldVnode.text)) api.setTextContent(elm, '');
+ addVnodes(elm, null, ch, 0, ch.length - 1, insertedVnodeQueue);
+ } else if (isDef(oldCh)) {
+ removeVnodes(elm, oldCh, 0, oldCh.length - 1);
+ } else if (isDef(oldVnode.text)) {
+ api.setTextContent(elm, '');
+ }
+ } else if (oldVnode.text !== vnode.text) {
+ api.setTextContent(elm, vnode.text);
+ }
+ if (isDef(hook) && isDef(i = hook.postpatch)) {
+ i(oldVnode, vnode);
+ }
+ }
+
+ return function(oldVnode, vnode) {
+ var i, elm, parent;
+ var insertedVnodeQueue = [];
+ for (i = 0; i < cbs.pre.length; ++i) cbs.pre[i]();
+
+ if (isUndef(oldVnode.sel)) {
+ oldVnode = emptyNodeAt(oldVnode);
+ }
+
+ if (sameVnode(oldVnode, vnode)) {
+ patchVnode(oldVnode, vnode, insertedVnodeQueue);
+ } else {
+ elm = oldVnode.elm;
+ parent = api.parentNode(elm);
+
+ createElm(vnode, insertedVnodeQueue);
+
+ if (parent !== null) {
+ api.insertBefore(parent, vnode.elm, api.nextSibling(elm));
+ removeVnodes(parent, [oldVnode], 0, 0);
+ }
+ }
+
+ for (i = 0; i < insertedVnodeQueue.length; ++i) {
+ insertedVnodeQueue[i].data.hook.insert(insertedVnodeQueue[i]);
+ }
+ for (i = 0; i < cbs.post.length; ++i) cbs.post[i]();
+ return vnode;
+ };
+}
+
+module.exports = {init: init};
+
+},{"./htmldomapi.js":58,"./is":59,"./vnode":68}],67:[function(require,module,exports){
+var h = require('./h');
+
+function init(thunk) {
+ var i, cur = thunk.data;
+ cur.vnode = cur.fn.apply(undefined, cur.args);
+}
+
+function prepatch(oldThunk, thunk) {
+ var i, old = oldThunk.data, cur = thunk.data;
+ var oldArgs = old.args, args = cur.args;
+ cur.vnode = old.vnode;
+ if (old.fn !== cur.fn || oldArgs.length !== args.length) {
+ cur.vnode = cur.fn.apply(undefined, args);
+ return;
+ }
+ for (i = 0; i < args.length; ++i) {
+ if (oldArgs[i] !== args[i]) {
+ cur.vnode = cur.fn.apply(undefined, args);
+ return;
+ }
+ }
+}
+
+module.exports = function(name, fn /* args */) {
+ var i, args = [];
+ for (i = 2; i < arguments.length; ++i) {
+ args[i - 2] = arguments[i];
+ }
+ return h('thunk' + name, {
+ hook: {init: init, prepatch: prepatch},
+ fn: fn, args: args,
+ });
+};
+
+},{"./h":57}],68:[function(require,module,exports){
+module.exports = function(sel, data, children, text, elm) {
+ var key = data === undefined ? undefined : data.key;
+ return {sel: sel, data: data, children: children,
+ text: text, elm: elm, key: key};
+};
+
+},{}],69:[function(require,module,exports){
+"use strict";
+var clickEvent = 'undefined' !== typeof document && document.ontouchstart ?
+ 'touchstart' : 'click';
+function which(ev) {
+ if (typeof window === 'undefined') {
+ return false;
+ }
+ var e = ev || window.event;
+ return e.which === null ? e.button : e.which;
+}
+function sameOrigin(href) {
+ if (typeof window === 'undefined') {
+ return false;
+ }
+ return href && href.indexOf(window.location.origin) === 0;
+}
+function makeClickListener(push) {
+ return function clickListener(event) {
+ if (which(event) !== 1) {
+ return;
+ }
+ if (event.metaKey || event.ctrlKey || event.shiftKey) {
+ return;
+ }
+ if (event.defaultPrevented) {
+ return;
+ }
+ var element = event.target;
+ while (element && element.nodeName !== 'A') {
+ element = element.parentNode;
+ }
+ if (!element || element.nodeName !== 'A') {
+ return;
+ }
+ if (element.hasAttribute('download') ||
+ element.getAttribute('rel') === 'external') {
+ return;
+ }
+ if (element.target) {
+ return;
+ }
+ var link = element.getAttribute('href');
+ if (link && link.indexOf('mailto:') > -1 || link === '#') {
+ return;
+ }
+ if (!sameOrigin(element.href)) {
+ return;
+ }
+ event.preventDefault();
+ var pathname = element.pathname, search = element.search, _a = element.hash, hash = _a === void 0 ? '' : _a;
+ push(pathname + search + hash);
+ };
+}
+function captureClicks(push) {
+ var listener = makeClickListener(push);
+ if (typeof window !== 'undefined') {
+ document.addEventListener(clickEvent, listener, false);
+ }
+}
+exports.captureClicks = captureClicks;
+
+},{}],70:[function(require,module,exports){
+"use strict";
+var makeHistoryDriver_1 = require('./makeHistoryDriver');
+exports.makeHistoryDriver = makeHistoryDriver_1.makeHistoryDriver;
+var serverHistory_1 = require('./serverHistory');
+exports.createServerHistory = serverHistory_1.createServerHistory;
+var util_1 = require('./util');
+exports.supportsHistory = util_1.supportsHistory;
+exports.createLocation = util_1.createLocation;
+
+},{"./makeHistoryDriver":71,"./serverHistory":72,"./util":73}],71:[function(require,module,exports){
+"use strict";
+var captureClicks_1 = require('./captureClicks');
+function makeUpdateHistory(history) {
+ return function updateHistory(location) {
+ if ('string' === typeof location) {
+ history.push(history.createLocation(location));
+ }
+ else if ('object' === typeof location) {
+ // suport things like history.replace()
+ var _a = location.type, type = _a === void 0 ? 'push' : _a;
+ if (type === 'go') {
+ history[type](location);
+ }
+ else {
+ history[type](location);
+ }
+ }
+ else {
+ throw new Error('History Driver input must be a string or an ' +
+ 'object but received ${typeof url}');
+ }
+ };
+}
+function defaultOnErrorFn(err) {
+ if (console && console.error !== void 0) {
+ console.error(err);
+ }
+}
+function makeHistoryDriver(history, options) {
+ if (!history || typeof history !== 'object'
+ || typeof history.createLocation !== 'function'
+ || typeof history.createHref !== 'function'
+ || typeof history.listen !== 'function'
+ || typeof history.push !== 'function') {
+ throw new TypeError('makeHistoryDriver requires an valid history object ' +
+ 'containing createLocation(), createHref(), push(), and listen() methods');
+ }
+ var capture = options && options.capture || false;
+ var onError = options && options.onError || defaultOnErrorFn;
+ return function historyDriver(sink$, runSA) {
+ var _a = runSA.makeSubject(), observer = _a.observer, stream = _a.stream;
+ var history$ = runSA.remember(stream
+ .startWith(history.getCurrentLocation())
+ .filter(Boolean));
+ var unlisten = history.listen(function (location) {
+ observer.next(location);
+ });
+ if (typeof history.addCompleteCallback === 'function'
+ && typeof history.complete === 'function') {
+ history.addCompleteCallback(function () {
+ observer.complete();
+ });
+ }
+ runSA.streamSubscribe(sink$, {
+ next: makeUpdateHistory(history),
+ error: onError,
+ complete: function () {
+ unlisten();
+ observer.complete();
+ }
+ });
+ if (capture) {
+ captureClicks_1.captureClicks(function (pathname) {
+ var location = history.createLocation(pathname);
+ history.push(location);
+ });
+ }
+ history$.createHref = function (href) { return history.createHref(href); };
+ history$.createLocation = function (location) { return history.createLocation(location); };
+ return history$;
+ };
+}
+exports.makeHistoryDriver = makeHistoryDriver;
+
+},{"./captureClicks":69}],72:[function(require,module,exports){
+"use strict";
+var util_1 = require('./util');
+var ServerHistory = (function () {
+ function ServerHistory(currentLocation) {
+ this.currentLocation = currentLocation;
+ this.listeners = [];
+ }
+ ServerHistory.prototype.listen = function (listener) {
+ this.listeners.push(listener);
+ return function noop() { return void 0; };
+ };
+ ServerHistory.prototype.push = function (location) {
+ var length = this.listeners.length;
+ if (length === 0) {
+ throw new Error('Must be given at least one listener before pushing');
+ }
+ for (var i = 0; i < length; ++i) {
+ this.listeners[i](util_1.createLocation(location));
+ }
+ };
+ ServerHistory.prototype.replace = function (location) {
+ this.push(location);
+ };
+ ServerHistory.prototype.createHref = function (path) {
+ return path;
+ };
+ ServerHistory.prototype.createLocation = function (location) {
+ return util_1.createLocation(location);
+ };
+ ServerHistory.prototype.getCurrentLocation = function () {
+ return this.currentLocation;
+ };
+ ServerHistory.prototype.addCompleteCallback = function (complete) {
+ this._completeCallback = complete;
+ };
+ ServerHistory.prototype.complete = function () {
+ this._completeCallback();
+ };
+ return ServerHistory;
+}());
+function createServerHistory(loc) {
+ return new ServerHistory(loc ? util_1.createLocation(loc) : null);
+}
+exports.createServerHistory = createServerHistory;
+
+},{"./util":73}],73:[function(require,module,exports){
+"use strict";
+function supportsHistory() {
+ if (typeof navigator === 'undefined') {
+ return false;
+ }
+ var ua = navigator.userAgent;
+ if ((ua.indexOf('Android 2.') !== -1 ||
+ ua.indexOf('Android 4.0') !== -1) &&
+ ua.indexOf('Mobile Safari') !== -1 &&
+ ua.indexOf('Chrome') === -1 &&
+ ua.indexOf('Windows Phone') === -1) {
+ return false;
+ }
+ if (typeof window !== 'undefined') {
+ return window.history && 'pushState' in window.history;
+ }
+ else {
+ return false;
+ }
+}
+exports.supportsHistory = supportsHistory;
+var locationDefaults = {
+ pathname: '/',
+ action: 'POP',
+ hash: '',
+ search: '',
+ state: undefined,
+ key: null,
+ query: null,
+};
+function createLocation(location) {
+ if (typeof location === 'string') {
+ return Object.assign({}, locationDefaults, { pathname: location });
+ }
+ return Object.assign({}, locationDefaults, location);
+}
+exports.createLocation = createLocation;
+
+},{}],74:[function(require,module,exports){
+"use strict";
+var counter = 0;
+function newScope() {
+ return "cycle" + ++counter;
+}
+function checkIsolateArgs(dataflowComponent, scope) {
+ if (typeof dataflowComponent !== "function") {
+ throw new Error("First argument given to isolate() must be a " +
+ "'dataflowComponent' function");
+ }
+ if (scope === null) {
+ throw new Error("Second argument given to isolate() must not be null");
+ }
+}
+function isolateAllSources(sources, scope) {
+ var scopedSources = {};
+ for (var key in sources) {
+ if (sources.hasOwnProperty(key) && sources[key]
+ && typeof sources[key].isolateSource === "function") {
+ scopedSources[key] = sources[key].isolateSource(sources[key], scope);
+ }
+ else if (sources.hasOwnProperty(key)) {
+ scopedSources[key] = sources[key];
+ }
+ }
+ return scopedSources;
+}
+function isolateAllSinks(sources, sinks, scope) {
+ var scopedSinks = {};
+ for (var key in sinks) {
+ if (sinks.hasOwnProperty(key)
+ && sources[key]
+ && typeof sources[key].isolateSink === "function") {
+ scopedSinks[key] = sources[key].isolateSink(sinks[key], scope);
+ }
+ else if (sinks.hasOwnProperty(key)) {
+ scopedSinks[key] = sinks[key];
+ }
+ }
+ return scopedSinks;
+}
+/**
+ * Takes a `dataflowComponent` function and an optional `scope` string, and
+ * returns a scoped version of the `dataflowComponent` function.
+ *
+ * When the scoped dataflow component is invoked, each source provided to the
+ * scoped dataflowComponent is isolated to the scope using
+ * `source.isolateSource(source, scope)`, if possible. Likewise, the sinks
+ * returned from the scoped dataflow component are isolate to the scope using
+ * `source.isolateSink(sink, scope)`.
+ *
+ * If the `scope` is not provided, a new scope will be automatically created.
+ * This means that while **`isolate(dataflowComponent, scope)` is pure**
+ * (referentially transparent), **`isolate(dataflowComponent)` is impure**
+ * (not referentially transparent). Two calls to `isolate(Foo, bar)` will
+ * generate two indistinct dataflow components. But, two calls to `isolate(Foo)`
+ * will generate two distinct dataflow components.
+ *
+ * Note that both `isolateSource()` and `isolateSink()` are static members of
+ * `source`. The reason for this is that drivers produce `source` while the
+ * application produces `sink`, and it's the driver's responsibility to
+ * implement `isolateSource()` and `isolateSink()`.
+ *
+ * @param {Function} dataflowComponent a function that takes `sources` as input
+ * and outputs a collection of `sinks`.
+ * @param {String} scope an optional string that is used to isolate each
+ * `sources` and `sinks` when the returned scoped dataflow component is invoked.
+ * @return {Function} the scoped dataflow component function that, as the
+ * original `dataflowComponent` function, takes `sources` and returns `sinks`.
+ * @function isolate
+ */
+function isolate(component, scope) {
+ if (scope === void 0) { scope = newScope(); }
+ checkIsolateArgs(component, scope);
+ var convertedScope = typeof scope === 'string' ? scope : scope.toString();
+ return function scopedComponent(sources) {
+ var rest = [];
+ for (var _i = 1; _i < arguments.length; _i++) {
+ rest[_i - 1] = arguments[_i];
+ }
+ var scopedSources = isolateAllSources(sources, convertedScope);
+ var sinks = component.apply(void 0, [scopedSources].concat(rest));
+ var scopedSinks = isolateAllSinks(sources, sinks, convertedScope);
+ return scopedSinks;
+ };
+}
+isolate.reset = function () { return counter = 0; };
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = isolate;
+
+},{}],75:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _xstreamAdapter = require('@cycle/xstream-adapter');
+
+var _xstreamAdapter2 = _interopRequireDefault(_xstreamAdapter);
+
+var _writeToStore = require('./writeToStore');
+
+var _writeToStore2 = _interopRequireDefault(_writeToStore);
+
+var _responseCollection = require('./responseCollection');
+
+var _responseCollection2 = _interopRequireDefault(_responseCollection);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Storage Driver.
+ *
+ * This is a localStorage and sessionStorage Driver for Cycle.js apps. The
+ * driver is also a function, and it takes a stream of requests as input, and
+ * returns a **`responseCollection`** with functions that allow reading from the
+ * storage objects. The functions on the **`responseCollection`** return streams
+ * of the storage data that was requested.
+ *
+ * **Requests**. The stream of requests should emit objects. These should be
+ * instructions to write to the desired Storage object. Here are the `request`
+ * object properties:
+ *
+ * - `target` *(String)*: type of storage, can be `local` or `session`, defaults
+ * to `local`.
+ * - `action` *(String)*: type of action, can be `setItem`, `removeItem` or
+ * `clear`, defaults to `setItem`.
+ * - `key` *(String)*: storage key.
+ * - `value` *(String)*: storage value.
+ *
+ * **responseCollection**. The **`responseCollection`** is an Object that
+ * exposes functions to read from local- and sessionStorage.
+ *
+ * ```js
+ * // Returns key of nth localStorage value.
+ * responseCollection.local.getKey(n)
+ * // Returns localStorage value of `key`.
+ * responseCollection.local.getItem(key)
+ * // Returns key of nth sessionStorage value.
+ * responseCollection.session.getKey(n)
+ * // Returns sessionStorage value of `key`.
+ * responseCollection.session.getItem(key)
+ * ```
+ *
+ * @param request$ - a stream of write request objects.
+ * @return {Object} the response collection containing functions
+ * for reading from storage.
+ * @function storageDriver
+ */
+function storageDriver(request$, runStreamAdapter) {
+ // Execute writing actions.
+ request$.addListener({
+ next: function next(request) {
+ return (0, _writeToStore2.default)(request);
+ },
+ error: function error() {},
+ complete: function complete() {}
+ });
+
+ // Return reading functions.
+ return (0, _responseCollection2.default)(request$, runStreamAdapter);
+}
+
+storageDriver.streamAdapter = _xstreamAdapter2.default;
+
+exports.default = storageDriver;
+},{"./responseCollection":76,"./writeToStore":78,"@cycle/xstream-adapter":79}],76:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+exports.default = function (request$, runStreamAdapter) {
+ return {
+ // For localStorage.
+ get local() {
+ return (0, _util2.default)(request$, runStreamAdapter);
+ },
+ // For sessionStorage.
+ get session() {
+ return (0, _util2.default)(request$, runStreamAdapter, 'session');
+ }
+ };
+};
+
+var _util = require('./util');
+
+var _util2 = _interopRequireDefault(_util);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+},{"./util":77}],77:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = getResponseObj;
+
+var _dropRepeats = require('xstream/extra/dropRepeats');
+
+var _dropRepeats2 = _interopRequireDefault(_dropRepeats);
+
+var _xstreamAdapter = require('@cycle/xstream-adapter');
+
+var _xstreamAdapter2 = _interopRequireDefault(_xstreamAdapter);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function getStorage$(request$, type) {
+ if (type === 'local') {
+ return request$.filter(function (req) {
+ return !req.target || req.target === 'local';
+ });
+ } else {
+ return request$.filter(function (req) {
+ return req.target === 'session';
+ });
+ }
+}
+
+function storageKey(n, request$) {
+ var type = arguments.length <= 2 || arguments[2] === undefined ? 'local' : arguments[2];
+
+ var storage$ = getStorage$(request$, type);
+ var key = type === 'local' ? localStorage.key(n) : sessionStorage.key(n);
+
+ return storage$.filter(function (req) {
+ return req.key === key;
+ }).map(function (req) {
+ return req.key;
+ }).startWith(key).compose((0, _dropRepeats2.default)());
+}
+
+function storageGetItem(key, request$) {
+ var type = arguments.length <= 2 || arguments[2] === undefined ? 'local' : arguments[2];
+
+ var storage$ = getStorage$(request$, type);
+ var storageObj = type === 'local' ? localStorage : sessionStorage;
+
+ return storage$.filter(function (req) {
+ return req.key === key;
+ }).map(function (req) {
+ return req.value;
+ }).startWith(storageObj.getItem(key));
+}
+
+function getResponseObj(request$, runSA) {
+ var type = arguments.length <= 2 || arguments[2] === undefined ? 'local' : arguments[2];
+
+ return {
+ // Function returning stream of the nth key.
+
+ key: function key(n) {
+ return runSA.adapt(storageKey(n, request$, type), _xstreamAdapter2.default.streamSubscribe);
+ },
+
+ // Function returning stream of item values.
+ getItem: function getItem(key) {
+ return runSA.adapt(storageGetItem(key, request$, type), _xstreamAdapter2.default.streamSubscribe);
+ }
+ };
+}
+},{"@cycle/xstream-adapter":79,"xstream/extra/dropRepeats":81}],78:[function(require,module,exports){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+/**
+ * @function writeToStore
+ * @description
+ * A universal write function for localStorage and sessionStorage.
+ * @param {object} request - the storage request object
+ * @param {string} request.target - a string determines which storage to use
+ * @param {string} request.action - a string determines the write action
+ * @param {string} request.key - the key of a storage item
+ * @param {string} request.value - the value of a storage item
+ */
+function writeToStore(_ref) {
+ var _ref$target = _ref.target;
+ var target = _ref$target === undefined ? "local" : _ref$target;
+ var _ref$action = _ref.action;
+ var action = _ref$action === undefined ? "setItem" : _ref$action;
+ var key = _ref.key;
+ var value = _ref.value;
+
+ // Determine the storage target.
+ var storage = target === "local" ? localStorage : sessionStorage;
+
+ // Execute the storage action and pass arguments if they were defined.
+ storage[action](key, value);
+}
+
+exports.default = writeToStore;
+},{}],79:[function(require,module,exports){
+"use strict";
+var xstream_1 = require('xstream');
+function logToConsoleError(err) {
+ var target = err.stack || err;
+ if (console && console.error) {
+ console.error(target);
+ }
+ else if (console && console.log) {
+ console.log(target);
+ }
+}
+var XStreamAdapter = {
+ adapt: function (originStream, originStreamSubscribe) {
+ if (XStreamAdapter.isValidStream(originStream)) {
+ return originStream;
+ }
+ ;
+ var dispose = null;
+ return xstream_1.default.create({
+ start: function (out) {
+ var observer = {
+ next: function (value) { return out.shamefullySendNext(value); },
+ error: function (err) { return out.shamefullySendError(err); },
+ complete: function () { return out.shamefullySendComplete(); },
+ };
+ dispose = originStreamSubscribe(originStream, observer);
+ },
+ stop: function () {
+ if (typeof dispose === 'function') {
+ dispose();
+ }
+ }
+ });
+ },
+ dispose: function (sinks, sinkProxies, sources) {
+ Object.keys(sources).forEach(function (k) {
+ if (typeof sources[k].dispose === 'function') {
+ sources[k].dispose();
+ }
+ });
+ Object.keys(sinks).forEach(function (k) {
+ sinks[k].removeListener(sinkProxies[k].stream);
+ });
+ },
+ makeHoldSubject: function () {
+ var stream = xstream_1.default.createWithMemory();
+ var observer = {
+ next: function (x) { stream.shamefullySendNext(x); },
+ error: function (err) {
+ logToConsoleError(err);
+ stream.shamefullySendError(err);
+ },
+ complete: function () { stream.shamefullySendComplete(); }
+ };
+ return { observer: observer, stream: stream };
+ },
+ isValidStream: function (stream) {
+ return (typeof stream.addListener === 'function' &&
+ typeof stream.shamefullySendNext === 'function');
+ },
+ streamSubscribe: function (stream, observer) {
+ stream.addListener(observer);
+ return function () { return stream.removeListener(observer); };
+ }
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = XStreamAdapter;
+
+},{"xstream":82}],80:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var empty = {};
+function noop() { }
+function copy(a) {
+ var l = a.length;
+ var b = Array(l);
+ for (var i = 0; i < l; ++i) {
+ b[i] = a[i];
+ }
+ return b;
+}
+exports.emptyListener = {
+ _n: noop,
+ _e: noop,
+ _c: noop,
+};
+// mutates the input
+function internalizeProducer(producer) {
+ producer._start =
+ function _start(il) {
+ il.next = il._n;
+ il.error = il._e;
+ il.complete = il._c;
+ this.start(il);
+ };
+ producer._stop = producer.stop;
+}
+function invoke(f, args) {
+ switch (args.length) {
+ case 0: return f();
+ case 1: return f(args[0]);
+ case 2: return f(args[0], args[1]);
+ case 3: return f(args[0], args[1], args[2]);
+ case 4: return f(args[0], args[1], args[2], args[3]);
+ case 5: return f(args[0], args[1], args[2], args[3], args[4]);
+ default: return f.apply(void 0, args);
+ }
+}
+function compose2(f1, f2) {
+ return function composedFn(arg) {
+ return f1(f2(arg));
+ };
+}
+function and(f1, f2) {
+ return function andFn(t) {
+ return f1(t) && f2(t);
+ };
+}
+var CombineListener = (function () {
+ function CombineListener(i, p) {
+ this.i = i;
+ this.p = p;
+ p.ils.push(this);
+ }
+ CombineListener.prototype._n = function (t) {
+ var p = this.p, out = p.out;
+ if (!out)
+ return;
+ if (p.up(t, this.i)) {
+ try {
+ out._n(invoke(p.project, p.vals));
+ }
+ catch (e) {
+ out._e(e);
+ }
+ }
+ };
+ CombineListener.prototype._e = function (err) {
+ var out = this.p.out;
+ if (!out)
+ return;
+ out._e(err);
+ };
+ CombineListener.prototype._c = function () {
+ var p = this.p;
+ if (!p.out)
+ return;
+ if (--p.ac === 0) {
+ p.out._c();
+ }
+ };
+ return CombineListener;
+}());
+exports.CombineListener = CombineListener;
+var CombineProducer = (function () {
+ function CombineProducer(project, streams) {
+ this.project = project;
+ this.streams = streams;
+ this.type = 'combine';
+ this.out = exports.emptyListener;
+ this.ils = [];
+ var n = this.ac = this.left = streams.length;
+ var vals = this.vals = new Array(n);
+ for (var i = 0; i < n; i++) {
+ vals[i] = empty;
+ }
+ }
+ CombineProducer.prototype.up = function (t, i) {
+ var v = this.vals[i];
+ var left = !this.left ? 0 : v === empty ? --this.left : this.left;
+ this.vals[i] = t;
+ return left === 0;
+ };
+ CombineProducer.prototype._start = function (out) {
+ this.out = out;
+ var s = this.streams;
+ var n = s.length;
+ if (n === 0)
+ this.zero(out);
+ else {
+ for (var i = 0; i < n; i++) {
+ s[i]._add(new CombineListener(i, this));
+ }
+ }
+ };
+ CombineProducer.prototype._stop = function () {
+ var s = this.streams;
+ var n = this.ac = this.left = s.length;
+ var vals = this.vals = new Array(n);
+ for (var i = 0; i < n; i++) {
+ s[i]._remove(this.ils[i]);
+ vals[i] = empty;
+ }
+ this.out = null;
+ this.ils = [];
+ };
+ CombineProducer.prototype.zero = function (out) {
+ try {
+ out._n(this.project());
+ out._c();
+ }
+ catch (e) {
+ out._e(e);
+ }
+ };
+ return CombineProducer;
+}());
+exports.CombineProducer = CombineProducer;
+var FromArrayProducer = (function () {
+ function FromArrayProducer(a) {
+ this.a = a;
+ this.type = 'fromArray';
+ }
+ FromArrayProducer.prototype._start = function (out) {
+ var a = this.a;
+ for (var i = 0, l = a.length; i < l; i++) {
+ out._n(a[i]);
+ }
+ out._c();
+ };
+ FromArrayProducer.prototype._stop = function () {
+ };
+ return FromArrayProducer;
+}());
+exports.FromArrayProducer = FromArrayProducer;
+var FromPromiseProducer = (function () {
+ function FromPromiseProducer(p) {
+ this.p = p;
+ this.type = 'fromPromise';
+ this.on = false;
+ }
+ FromPromiseProducer.prototype._start = function (out) {
+ var prod = this;
+ this.on = true;
+ this.p.then(function (v) {
+ if (prod.on) {
+ out._n(v);
+ out._c();
+ }
+ }, function (e) {
+ out._e(e);
+ }).then(null, function (err) {
+ setTimeout(function () { throw err; });
+ });
+ };
+ FromPromiseProducer.prototype._stop = function () {
+ this.on = false;
+ };
+ return FromPromiseProducer;
+}());
+exports.FromPromiseProducer = FromPromiseProducer;
+var MergeProducer = (function () {
+ function MergeProducer(streams) {
+ this.streams = streams;
+ this.type = 'merge';
+ this.out = exports.emptyListener;
+ this.ac = streams.length;
+ }
+ MergeProducer.prototype._start = function (out) {
+ this.out = out;
+ var s = this.streams;
+ var L = s.length;
+ for (var i = 0; i < L; i++) {
+ s[i]._add(this);
+ }
+ };
+ MergeProducer.prototype._stop = function () {
+ var s = this.streams;
+ var L = s.length;
+ for (var i = 0; i < L; i++) {
+ s[i]._remove(this);
+ }
+ this.out = null;
+ this.ac = L;
+ };
+ MergeProducer.prototype._n = function (t) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._n(t);
+ };
+ MergeProducer.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._e(err);
+ };
+ MergeProducer.prototype._c = function () {
+ if (--this.ac === 0) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._c();
+ }
+ };
+ return MergeProducer;
+}());
+exports.MergeProducer = MergeProducer;
+var PeriodicProducer = (function () {
+ function PeriodicProducer(period) {
+ this.period = period;
+ this.type = 'periodic';
+ this.intervalID = -1;
+ this.i = 0;
+ }
+ PeriodicProducer.prototype._start = function (stream) {
+ var self = this;
+ function intervalHandler() { stream._n(self.i++); }
+ this.intervalID = setInterval(intervalHandler, this.period);
+ };
+ PeriodicProducer.prototype._stop = function () {
+ if (this.intervalID !== -1)
+ clearInterval(this.intervalID);
+ this.intervalID = -1;
+ this.i = 0;
+ };
+ return PeriodicProducer;
+}());
+exports.PeriodicProducer = PeriodicProducer;
+var DebugOperator = (function () {
+ function DebugOperator(arg, ins) {
+ this.ins = ins;
+ this.type = 'debug';
+ this.out = null;
+ this.s = null; // spy
+ this.l = null; // label
+ if (typeof arg === 'string') {
+ this.l = arg;
+ }
+ else {
+ this.s = arg;
+ }
+ }
+ DebugOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(this);
+ };
+ DebugOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = null;
+ };
+ DebugOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (!u)
+ return;
+ var s = this.s, l = this.l;
+ if (s) {
+ try {
+ s(t);
+ }
+ catch (e) {
+ u._e(e);
+ }
+ }
+ else if (l) {
+ console.log(l + ':', t);
+ }
+ else {
+ console.log(t);
+ }
+ u._n(t);
+ };
+ DebugOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._e(err);
+ };
+ DebugOperator.prototype._c = function () {
+ var u = this.out;
+ if (!u)
+ return;
+ u._c();
+ };
+ return DebugOperator;
+}());
+exports.DebugOperator = DebugOperator;
+var DropOperator = (function () {
+ function DropOperator(max, ins) {
+ this.max = max;
+ this.ins = ins;
+ this.type = 'drop';
+ this.out = null;
+ this.dropped = 0;
+ }
+ DropOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(this);
+ };
+ DropOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = null;
+ this.dropped = 0;
+ };
+ DropOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (!u)
+ return;
+ if (this.dropped++ >= this.max)
+ u._n(t);
+ };
+ DropOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._e(err);
+ };
+ DropOperator.prototype._c = function () {
+ var u = this.out;
+ if (!u)
+ return;
+ u._c();
+ };
+ return DropOperator;
+}());
+exports.DropOperator = DropOperator;
+var OtherIL = (function () {
+ function OtherIL(out, op) {
+ this.out = out;
+ this.op = op;
+ }
+ OtherIL.prototype._n = function (t) {
+ this.op.end();
+ };
+ OtherIL.prototype._e = function (err) {
+ this.out._e(err);
+ };
+ OtherIL.prototype._c = function () {
+ this.op.end();
+ };
+ return OtherIL;
+}());
+var EndWhenOperator = (function () {
+ function EndWhenOperator(o, // o = other
+ ins) {
+ this.o = o;
+ this.ins = ins;
+ this.type = 'endWhen';
+ this.out = null;
+ this.oil = exports.emptyListener; // oil = other InternalListener
+ }
+ EndWhenOperator.prototype._start = function (out) {
+ this.out = out;
+ this.o._add(this.oil = new OtherIL(out, this));
+ this.ins._add(this);
+ };
+ EndWhenOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.o._remove(this.oil);
+ this.out = null;
+ this.oil = null;
+ };
+ EndWhenOperator.prototype.end = function () {
+ var u = this.out;
+ if (!u)
+ return;
+ u._c();
+ };
+ EndWhenOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._n(t);
+ };
+ EndWhenOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._e(err);
+ };
+ EndWhenOperator.prototype._c = function () {
+ this.end();
+ };
+ return EndWhenOperator;
+}());
+exports.EndWhenOperator = EndWhenOperator;
+var FilterOperator = (function () {
+ function FilterOperator(passes, ins) {
+ this.passes = passes;
+ this.ins = ins;
+ this.type = 'filter';
+ this.out = null;
+ }
+ FilterOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(this);
+ };
+ FilterOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = null;
+ };
+ FilterOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (!u)
+ return;
+ try {
+ if (this.passes(t))
+ u._n(t);
+ }
+ catch (e) {
+ u._e(e);
+ }
+ };
+ FilterOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._e(err);
+ };
+ FilterOperator.prototype._c = function () {
+ var u = this.out;
+ if (!u)
+ return;
+ u._c();
+ };
+ return FilterOperator;
+}());
+exports.FilterOperator = FilterOperator;
+var FlattenListener = (function () {
+ function FlattenListener(out, op) {
+ this.out = out;
+ this.op = op;
+ }
+ FlattenListener.prototype._n = function (t) {
+ this.out._n(t);
+ };
+ FlattenListener.prototype._e = function (err) {
+ this.out._e(err);
+ };
+ FlattenListener.prototype._c = function () {
+ this.op.inner = null;
+ this.op.less();
+ };
+ return FlattenListener;
+}());
+var FlattenOperator = (function () {
+ function FlattenOperator(ins) {
+ this.ins = ins;
+ this.type = 'flatten';
+ this.inner = null; // Current inner Stream
+ this.il = null; // Current inner InternalListener
+ this.open = true;
+ this.out = null;
+ }
+ FlattenOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(this);
+ };
+ FlattenOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.inner = null;
+ this.il = null;
+ this.open = true;
+ this.out = null;
+ };
+ FlattenOperator.prototype.less = function () {
+ var u = this.out;
+ if (!u)
+ return;
+ if (!this.open && !this.inner)
+ u._c();
+ };
+ FlattenOperator.prototype._n = function (s) {
+ var u = this.out;
+ if (!u)
+ return;
+ var _a = this, inner = _a.inner, il = _a.il;
+ if (inner && il)
+ inner._remove(il);
+ (this.inner = s)._add(this.il = new FlattenListener(u, this));
+ };
+ FlattenOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._e(err);
+ };
+ FlattenOperator.prototype._c = function () {
+ this.open = false;
+ this.less();
+ };
+ return FlattenOperator;
+}());
+exports.FlattenOperator = FlattenOperator;
+var FoldOperator = (function () {
+ function FoldOperator(f, seed, ins) {
+ this.f = f;
+ this.seed = seed;
+ this.ins = ins;
+ this.type = 'fold';
+ this.out = null;
+ this.acc = seed;
+ }
+ FoldOperator.prototype._start = function (out) {
+ this.out = out;
+ out._n(this.acc);
+ this.ins._add(this);
+ };
+ FoldOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = null;
+ this.acc = this.seed;
+ };
+ FoldOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (!u)
+ return;
+ try {
+ u._n(this.acc = this.f(this.acc, t));
+ }
+ catch (e) {
+ u._e(e);
+ }
+ };
+ FoldOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._e(err);
+ };
+ FoldOperator.prototype._c = function () {
+ var u = this.out;
+ if (!u)
+ return;
+ u._c();
+ };
+ return FoldOperator;
+}());
+exports.FoldOperator = FoldOperator;
+var LastOperator = (function () {
+ function LastOperator(ins) {
+ this.ins = ins;
+ this.type = 'last';
+ this.out = null;
+ this.has = false;
+ this.val = empty;
+ }
+ LastOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(this);
+ };
+ LastOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = null;
+ this.has = false;
+ this.val = empty;
+ };
+ LastOperator.prototype._n = function (t) {
+ this.has = true;
+ this.val = t;
+ };
+ LastOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._e(err);
+ };
+ LastOperator.prototype._c = function () {
+ var u = this.out;
+ if (!u)
+ return;
+ if (this.has) {
+ u._n(this.val);
+ u._c();
+ }
+ else {
+ u._e('TODO show proper error');
+ }
+ };
+ return LastOperator;
+}());
+exports.LastOperator = LastOperator;
+var MapFlattenInner = (function () {
+ function MapFlattenInner(out, op) {
+ this.out = out;
+ this.op = op;
+ }
+ MapFlattenInner.prototype._n = function (r) {
+ this.out._n(r);
+ };
+ MapFlattenInner.prototype._e = function (err) {
+ this.out._e(err);
+ };
+ MapFlattenInner.prototype._c = function () {
+ this.op.inner = null;
+ this.op.less();
+ };
+ return MapFlattenInner;
+}());
+var MapFlattenOperator = (function () {
+ function MapFlattenOperator(mapOp) {
+ this.mapOp = mapOp;
+ this.inner = null; // Current inner Stream
+ this.il = null; // Current inner InternalListener
+ this.open = true;
+ this.out = null;
+ this.type = mapOp.type + "+flatten";
+ this.ins = mapOp.ins;
+ }
+ MapFlattenOperator.prototype._start = function (out) {
+ this.out = out;
+ this.mapOp.ins._add(this);
+ };
+ MapFlattenOperator.prototype._stop = function () {
+ this.mapOp.ins._remove(this);
+ this.inner = null;
+ this.il = null;
+ this.open = true;
+ this.out = null;
+ };
+ MapFlattenOperator.prototype.less = function () {
+ if (!this.open && !this.inner) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._c();
+ }
+ };
+ MapFlattenOperator.prototype._n = function (v) {
+ var u = this.out;
+ if (!u)
+ return;
+ var _a = this, inner = _a.inner, il = _a.il;
+ if (inner && il)
+ inner._remove(il);
+ try {
+ (this.inner = this.mapOp.project(v))._add(this.il = new MapFlattenInner(u, this));
+ }
+ catch (e) {
+ u._e(e);
+ }
+ };
+ MapFlattenOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._e(err);
+ };
+ MapFlattenOperator.prototype._c = function () {
+ this.open = false;
+ this.less();
+ };
+ return MapFlattenOperator;
+}());
+exports.MapFlattenOperator = MapFlattenOperator;
+var MapOperator = (function () {
+ function MapOperator(project, ins) {
+ this.project = project;
+ this.ins = ins;
+ this.type = 'map';
+ this.out = null;
+ }
+ MapOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(this);
+ };
+ MapOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = null;
+ };
+ MapOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (!u)
+ return;
+ try {
+ u._n(this.project(t));
+ }
+ catch (e) {
+ u._e(e);
+ }
+ };
+ MapOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._e(err);
+ };
+ MapOperator.prototype._c = function () {
+ var u = this.out;
+ if (!u)
+ return;
+ u._c();
+ };
+ return MapOperator;
+}());
+exports.MapOperator = MapOperator;
+var FilterMapOperator = (function (_super) {
+ __extends(FilterMapOperator, _super);
+ function FilterMapOperator(passes, project, ins) {
+ _super.call(this, project, ins);
+ this.passes = passes;
+ this.type = 'filter+map';
+ }
+ FilterMapOperator.prototype._n = function (v) {
+ if (this.passes(v)) {
+ _super.prototype._n.call(this, v);
+ }
+ ;
+ };
+ return FilterMapOperator;
+}(MapOperator));
+exports.FilterMapOperator = FilterMapOperator;
+var ReplaceErrorOperator = (function () {
+ function ReplaceErrorOperator(fn, ins) {
+ this.fn = fn;
+ this.ins = ins;
+ this.type = 'replaceError';
+ this.out = empty;
+ }
+ ReplaceErrorOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(this);
+ };
+ ReplaceErrorOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = null;
+ };
+ ReplaceErrorOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._n(t);
+ };
+ ReplaceErrorOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ try {
+ this.ins._remove(this);
+ (this.ins = this.fn(err))._add(this);
+ }
+ catch (e) {
+ u._e(e);
+ }
+ };
+ ReplaceErrorOperator.prototype._c = function () {
+ var u = this.out;
+ if (!u)
+ return;
+ u._c();
+ };
+ return ReplaceErrorOperator;
+}());
+exports.ReplaceErrorOperator = ReplaceErrorOperator;
+var StartWithOperator = (function () {
+ function StartWithOperator(ins, value) {
+ this.ins = ins;
+ this.value = value;
+ this.type = 'startWith';
+ this.out = exports.emptyListener;
+ }
+ StartWithOperator.prototype._start = function (out) {
+ this.out = out;
+ this.out._n(this.value);
+ this.ins._add(out);
+ };
+ StartWithOperator.prototype._stop = function () {
+ this.ins._remove(this.out);
+ this.out = null;
+ };
+ return StartWithOperator;
+}());
+exports.StartWithOperator = StartWithOperator;
+var TakeOperator = (function () {
+ function TakeOperator(max, ins) {
+ this.max = max;
+ this.ins = ins;
+ this.type = 'take';
+ this.out = null;
+ this.taken = 0;
+ }
+ TakeOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(this);
+ };
+ TakeOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = null;
+ this.taken = 0;
+ };
+ TakeOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (!u)
+ return;
+ if (this.taken++ < this.max - 1) {
+ u._n(t);
+ }
+ else {
+ u._n(t);
+ u._c();
+ this._stop();
+ }
+ };
+ TakeOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._e(err);
+ };
+ TakeOperator.prototype._c = function () {
+ var u = this.out;
+ if (!u)
+ return;
+ u._c();
+ };
+ return TakeOperator;
+}());
+exports.TakeOperator = TakeOperator;
+var Stream = (function () {
+ function Stream(producer) {
+ this._stopID = empty;
+ this._prod = producer;
+ this._ils = [];
+ }
+ Stream.prototype._n = function (t) {
+ var a = this._ils;
+ var L = a.length;
+ if (L == 1)
+ a[0]._n(t);
+ else {
+ var b = copy(a);
+ for (var i = 0; i < L; i++)
+ b[i]._n(t);
+ }
+ };
+ Stream.prototype._e = function (err) {
+ var a = this._ils;
+ var L = a.length;
+ if (L == 1)
+ a[0]._e(err);
+ else {
+ var b = copy(a);
+ for (var i = 0; i < L; i++)
+ b[i]._e(err);
+ }
+ this._x();
+ };
+ Stream.prototype._c = function () {
+ var a = this._ils;
+ var L = a.length;
+ if (L == 1)
+ a[0]._c();
+ else {
+ var b = copy(a);
+ for (var i = 0; i < L; i++)
+ b[i]._c();
+ }
+ this._x();
+ };
+ Stream.prototype._x = function () {
+ if (this._ils.length === 0)
+ return;
+ if (this._prod)
+ this._prod._stop();
+ this._ils = [];
+ };
+ /**
+ * Adds a Listener to the Stream.
+ *
+ * @param {Listener} listener
+ */
+ Stream.prototype.addListener = function (listener) {
+ if (typeof listener.next !== 'function'
+ || typeof listener.error !== 'function'
+ || typeof listener.complete !== 'function') {
+ throw new Error('stream.addListener() requires all three next, error, ' +
+ 'and complete functions.');
+ }
+ listener._n = listener.next;
+ listener._e = listener.error;
+ listener._c = listener.complete;
+ this._add(listener);
+ };
+ /**
+ * Removes a Listener from the Stream, assuming the Listener was added to it.
+ *
+ * @param {Listener} listener
+ */
+ Stream.prototype.removeListener = function (listener) {
+ this._remove(listener);
+ };
+ Stream.prototype._add = function (il) {
+ var a = this._ils;
+ a.push(il);
+ if (a.length === 1) {
+ if (this._stopID !== empty) {
+ clearTimeout(this._stopID);
+ this._stopID = empty;
+ }
+ var p = this._prod;
+ if (p)
+ p._start(this);
+ }
+ };
+ Stream.prototype._remove = function (il) {
+ var a = this._ils;
+ var i = a.indexOf(il);
+ if (i > -1) {
+ a.splice(i, 1);
+ var p_1 = this._prod;
+ if (p_1 && a.length <= 0) {
+ this._stopID = setTimeout(function () { return p_1._stop(); });
+ }
+ }
+ };
+ Stream.prototype.ctor = function () {
+ return this instanceof MemoryStream ? MemoryStream : Stream;
+ };
+ /**
+ * Creates a new Stream given a Producer.
+ *
+ * @factory true
+ * @param {Producer} producer An optional Producer that dictates how to
+ * start, generate events, and stop the Stream.
+ * @return {Stream}
+ */
+ Stream.create = function (producer) {
+ if (producer) {
+ if (typeof producer.start !== 'function'
+ || typeof producer.stop !== 'function') {
+ throw new Error('producer requires both start and stop functions');
+ }
+ internalizeProducer(producer); // mutates the input
+ }
+ return new Stream(producer);
+ };
+ /**
+ * Creates a new MemoryStream given a Producer.
+ *
+ * @factory true
+ * @param {Producer} producer An optional Producer that dictates how to
+ * start, generate events, and stop the Stream.
+ * @return {MemoryStream}
+ */
+ Stream.createWithMemory = function (producer) {
+ if (producer) {
+ internalizeProducer(producer); // mutates the input
+ }
+ return new MemoryStream(producer);
+ };
+ /**
+ * Creates a new MimicStream, which can `imitate` another Stream. Only a
+ * MimicStream has the `imitate()` method.
+ *
+ * @factory true
+ * @return {MimicStream}
+ */
+ Stream.createMimic = function () {
+ return new MimicStream();
+ };
+ /**
+ * Creates a Stream that does nothing when started. It never emits any event.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * never
+ * -----------------------
+ * ```
+ *
+ * @factory true
+ * @return {Stream}
+ */
+ Stream.never = function () {
+ return new Stream({ _start: noop, _stop: noop });
+ };
+ /**
+ * Creates a Stream that immediately emits the "complete" notification when
+ * started, and that's it.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * empty
+ * -|
+ * ```
+ *
+ * @factory true
+ * @return {Stream}
+ */
+ Stream.empty = function () {
+ return new Stream({
+ _start: function (il) { il._c(); },
+ _stop: noop,
+ });
+ };
+ /**
+ * Creates a Stream that immediately emits an "error" notification with the
+ * value you passed as the `error` argument when the stream starts, and that's
+ * it.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * throw(X)
+ * -X
+ * ```
+ *
+ * @factory true
+ * @param error The error event to emit on the created stream.
+ * @return {Stream}
+ */
+ Stream.throw = function (error) {
+ return new Stream({
+ _start: function (il) { il._e(error); },
+ _stop: noop,
+ });
+ };
+ /**
+ * Creates a Stream that immediately emits the arguments that you give to
+ * *of*, then completes.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * of(1,2,3)
+ * 123|
+ * ```
+ *
+ * @factory true
+ * @param a The first value you want to emit as an event on the stream.
+ * @param b The second value you want to emit as an event on the stream. One
+ * or more of these values may be given as arguments.
+ * @return {Stream}
+ */
+ Stream.of = function () {
+ var items = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ items[_i - 0] = arguments[_i];
+ }
+ return Stream.fromArray(items);
+ };
+ /**
+ * Converts an array to a stream. The returned stream will emit synchronously
+ * all the items in the array, and then complete.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * fromArray([1,2,3])
+ * 123|
+ * ```
+ *
+ * @factory true
+ * @param {Array} array The array to be converted as a stream.
+ * @return {Stream}
+ */
+ Stream.fromArray = function (array) {
+ return new Stream(new FromArrayProducer(array));
+ };
+ /**
+ * Converts a promise to a stream. The returned stream will emit the resolved
+ * value of the promise, and then complete. However, if the promise is
+ * rejected, the stream will emit the corresponding error.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * fromPromise( ----42 )
+ * -----------------42|
+ * ```
+ *
+ * @factory true
+ * @param {Promise} promise The promise to be converted as a stream.
+ * @return {Stream}
+ */
+ Stream.fromPromise = function (promise) {
+ return new Stream(new FromPromiseProducer(promise));
+ };
+ /**
+ * Creates a stream that periodically emits incremental numbers, every
+ * `period` milliseconds.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * periodic(1000)
+ * ---0---1---2---3---4---...
+ * ```
+ *
+ * @factory true
+ * @param {number} period The interval in milliseconds to use as a rate of
+ * emission.
+ * @return {Stream}
+ */
+ Stream.periodic = function (period) {
+ return new Stream(new PeriodicProducer(period));
+ };
+ /**
+ * Blends multiple streams together, emitting events from all of them
+ * concurrently.
+ *
+ * *merge* takes multiple streams as arguments, and creates a stream that
+ * behaves like each of the argument streams, in parallel.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1----2-----3--------4---
+ * ----a-----b----c---d------
+ * merge
+ * --1-a--2--b--3-c---d--4---
+ * ```
+ *
+ * @factory true
+ * @param {Stream} stream1 A stream to merge together with other streams.
+ * @param {Stream} stream2 A stream to merge together with other streams. Two
+ * or more streams may be given as arguments.
+ * @return {Stream}
+ */
+ Stream.merge = function () {
+ var streams = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ streams[_i - 0] = arguments[_i];
+ }
+ return new Stream(new MergeProducer(streams));
+ };
+ Stream.prototype._map = function (project) {
+ var p = this._prod;
+ var ctor = this.ctor();
+ if (p instanceof FilterOperator) {
+ return new ctor(new FilterMapOperator(p.passes, project, p.ins));
+ }
+ if (p instanceof FilterMapOperator) {
+ return new ctor(new FilterMapOperator(p.passes, compose2(project, p.project), p.ins));
+ }
+ if (p instanceof MapOperator) {
+ return new ctor(new MapOperator(compose2(project, p.project), p.ins));
+ }
+ return new ctor(new MapOperator(project, this));
+ };
+ /**
+ * Transforms each event from the input Stream through a `project` function,
+ * to get a Stream that emits those transformed events.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1---3--5-----7------
+ * map(i => i * 10)
+ * --10--30-50----70-----
+ * ```
+ *
+ * @param {Function} project A function of type `(t: T) => U` that takes event
+ * `t` of type `T` from the input Stream and produces an event of type `U`, to
+ * be emitted on the output Stream.
+ * @return {Stream}
+ */
+ Stream.prototype.map = function (project) {
+ return this._map(project);
+ };
+ /**
+ * It's like `map`, but transforms each input event to always the same
+ * constant value on the output Stream.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1---3--5-----7-----
+ * mapTo(10)
+ * --10--10-10----10----
+ * ```
+ *
+ * @param projectedValue A value to emit on the output Stream whenever the
+ * input Stream emits any value.
+ * @return {Stream}
+ */
+ Stream.prototype.mapTo = function (projectedValue) {
+ var s = this.map(function () { return projectedValue; });
+ var op = s._prod;
+ op.type = op.type.replace('map', 'mapTo');
+ return s;
+ };
+ /**
+ * Only allows events that pass the test given by the `passes` argument.
+ *
+ * Each event from the input stream is given to the `passes` function. If the
+ * function returns `true`, the event is forwarded to the output stream,
+ * otherwise it is ignored and not forwarded.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1---2--3-----4-----5---6--7-8--
+ * filter(i => i % 2 === 0)
+ * ------2--------4---------6----8--
+ * ```
+ *
+ * @param {Function} passes A function of type `(t: T) +> boolean` that takes
+ * an event from the input stream and checks if it passes, by returning a
+ * boolean.
+ * @return {Stream}
+ */
+ Stream.prototype.filter = function (passes) {
+ var p = this._prod;
+ if (p instanceof FilterOperator) {
+ return new Stream(new FilterOperator(and(passes, p.passes), p.ins));
+ }
+ return new Stream(new FilterOperator(passes, this));
+ };
+ /**
+ * Lets the first `amount` many events from the input stream pass to the
+ * output stream, then makes the output stream complete.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --a---b--c----d---e--
+ * take(3)
+ * --a---b--c|
+ * ```
+ *
+ * @param {number} amount How many events to allow from the input stream
+ * before completing the output stream.
+ * @return {Stream}
+ */
+ Stream.prototype.take = function (amount) {
+ return new (this.ctor())(new TakeOperator(amount, this));
+ };
+ /**
+ * Ignores the first `amount` many events from the input stream, and then
+ * after that starts forwarding events from the input stream to the output
+ * stream.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --a---b--c----d---e--
+ * drop(3)
+ * --------------d---e--
+ * ```
+ *
+ * @param {number} amount How many events to ignore from the input stream
+ * before forwarding all events from the input stream to the output stream.
+ * @return {Stream}
+ */
+ Stream.prototype.drop = function (amount) {
+ return new Stream(new DropOperator(amount, this));
+ };
+ /**
+ * When the input stream completes, the output stream will emit the last event
+ * emitted by the input stream, and then will also complete.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --a---b--c--d----|
+ * last()
+ * -----------------d|
+ * ```
+ *
+ * @return {Stream}
+ */
+ Stream.prototype.last = function () {
+ return new Stream(new LastOperator(this));
+ };
+ /**
+ * Prepends the given `initial` value to the sequence of events emitted by the
+ * input stream. The returned stream is a MemoryStream, which means it is
+ * already `remember()`'d.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * ---1---2-----3---
+ * startWith(0)
+ * 0--1---2-----3---
+ * ```
+ *
+ * @param initial The value or event to prepend.
+ * @return {MemoryStream}
+ */
+ Stream.prototype.startWith = function (initial) {
+ return new MemoryStream(new StartWithOperator(this, initial));
+ };
+ /**
+ * Uses another stream to determine when to complete the current stream.
+ *
+ * When the given `other` stream emits an event or completes, the output
+ * stream will complete. Before that happens, the output stream will behaves
+ * like the input stream.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * ---1---2-----3--4----5----6---
+ * endWhen( --------a--b--| )
+ * ---1---2-----3--4--|
+ * ```
+ *
+ * @param other Some other stream that is used to know when should the output
+ * stream of this operator complete.
+ * @return {Stream}
+ */
+ Stream.prototype.endWhen = function (other) {
+ return new (this.ctor())(new EndWhenOperator(other, this));
+ };
+ /**
+ * "Folds" the stream onto itself.
+ *
+ * Combines events from the past throughout
+ * the entire execution of the input stream, allowing you to accumulate them
+ * together. It's essentially like `Array.prototype.reduce`. The returned
+ * stream is a MemoryStream, which means it is already `remember()`'d.
+ *
+ * The output stream starts by emitting the `seed` which you give as argument.
+ * Then, when an event happens on the input stream, it is combined with that
+ * seed value through the `accumulate` function, and the output value is
+ * emitted on the output stream. `fold` remembers that output value as `acc`
+ * ("accumulator"), and then when a new input event `t` happens, `acc` will be
+ * combined with that to produce the new `acc` and so forth.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * ------1-----1--2----1----1------
+ * fold((acc, x) => acc + x, 3)
+ * 3-----4-----5--7----8----9------
+ * ```
+ *
+ * @param {Function} accumulate A function of type `(acc: R, t: T) => R` that
+ * takes the previous accumulated value `acc` and the incoming event from the
+ * input stream and produces the new accumulated value.
+ * @param seed The initial accumulated value, of type `R`.
+ * @return {MemoryStream}
+ */
+ Stream.prototype.fold = function (accumulate, seed) {
+ return new MemoryStream(new FoldOperator(accumulate, seed, this));
+ };
+ /**
+ * Replaces an error with another stream.
+ *
+ * When (and if) an error happens on the input stream, instead of forwarding
+ * that error to the output stream, *replaceError* will call the `replace`
+ * function which returns the stream that the output stream will replicate.
+ * And, in case that new stream also emits an error, `replace` will be called
+ * again to get another stream to start replicating.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1---2-----3--4-----X
+ * replaceError( () => --10--| )
+ * --1---2-----3--4--------10--|
+ * ```
+ *
+ * @param {Function} replace A function of type `(err) => Stream` that takes
+ * the error that occurred on the input stream or on the previous replacement
+ * stream and returns a new stream. The output stream will behave like the
+ * stream that this function returns.
+ * @return {Stream}
+ */
+ Stream.prototype.replaceError = function (replace) {
+ return new (this.ctor())(new ReplaceErrorOperator(replace, this));
+ };
+ /**
+ * Flattens a "stream of streams", handling only one nested stream at a time
+ * (no concurrency).
+ *
+ * If the input stream is a stream that emits streams, then this operator will
+ * return an output stream which is a flat stream: emits regular events. The
+ * flattening happens without concurrency. It works like this: when the input
+ * stream emits a nested stream, *flatten* will start imitating that nested
+ * one. However, as soon as the next nested stream is emitted on the input
+ * stream, *flatten* will forget the previous nested one it was imitating, and
+ * will start imitating the new nested one.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --+--------+---------------
+ * \ \
+ * \ ----1----2---3--
+ * --a--b----c----d--------
+ * flatten
+ * -----a--b------1----2---3--
+ * ```
+ *
+ * @return {Stream}
+ */
+ Stream.prototype.flatten = function () {
+ var p = this._prod;
+ return new Stream(p instanceof MapOperator && !(p instanceof FilterMapOperator) ?
+ new MapFlattenOperator(p) :
+ new FlattenOperator(this));
+ };
+ /**
+ * Passes the input stream to a custom operator, to produce an output stream.
+ *
+ * *compose* is a handy way of using an existing function in a chained style.
+ * Instead of writing `outStream = f(inStream)` you can write
+ * `outStream = inStream.compose(f)`.
+ *
+ * @param {function} operator A function that takes a stream as input and
+ * returns a stream as well.
+ * @return {Stream}
+ */
+ Stream.prototype.compose = function (operator) {
+ return operator(this);
+ };
+ /**
+ * Returns an output stream that behaves like the input stream, but also
+ * remembers the most recent event that happens on the input stream, so that a
+ * newly added listener will immediately receive that memorised event.
+ *
+ * @return {MemoryStream}
+ */
+ Stream.prototype.remember = function () {
+ var _this = this;
+ return new MemoryStream({
+ _start: function (il) {
+ var p = _this._prod;
+ if (p)
+ p._start(il);
+ },
+ _stop: function () {
+ var p = _this._prod;
+ if (p)
+ p._stop();
+ },
+ });
+ };
+ /**
+ * Returns an output stream that identically behaves like the input stream,
+ * but also runs a `spy` function fo each event, to help you debug your app.
+ *
+ * *debug* takes a `spy` function as argument, and runs that for each event
+ * happening on the input stream. If you don't provide the `spy` argument,
+ * then *debug* will just `console.log` each event. This helps you to
+ * understand the flow of events through some operator chain.
+ *
+ * Please note that if the output stream has no listeners, then it will not
+ * start, which means `spy` will never run because no actual event happens in
+ * that case.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1----2-----3-----4--
+ * debug
+ * --1----2-----3-----4--
+ * ```
+ *
+ * @param {function} labelOrSpy A string to use as the label when printing
+ * debug information on the console, or a 'spy' function that takes an event
+ * as argument, and does not need to return anything.
+ * @return {Stream}
+ */
+ Stream.prototype.debug = function (labelOrSpy) {
+ return new (this.ctor())(new DebugOperator(labelOrSpy, this));
+ };
+ /**
+ * Forces the Stream to emit the given value to its listeners.
+ *
+ * As the name indicates, if you use this, you are most likely doing something
+ * The Wrong Way. Please try to understand the reactive way before using this
+ * method. Use it only when you know what you are doing.
+ *
+ * @param value The "next" value you want to broadcast to all listeners of
+ * this Stream.
+ */
+ Stream.prototype.shamefullySendNext = function (value) {
+ this._n(value);
+ };
+ /**
+ * Forces the Stream to emit the given error to its listeners.
+ *
+ * As the name indicates, if you use this, you are most likely doing something
+ * The Wrong Way. Please try to understand the reactive way before using this
+ * method. Use it only when you know what you are doing.
+ *
+ * @param {any} error The error you want to broadcast to all the listeners of
+ * this Stream.
+ */
+ Stream.prototype.shamefullySendError = function (error) {
+ this._e(error);
+ };
+ /**
+ * Forces the Stream to emit the "completed" event to its listeners.
+ *
+ * As the name indicates, if you use this, you are most likely doing something
+ * The Wrong Way. Please try to understand the reactive way before using this
+ * method. Use it only when you know what you are doing.
+ */
+ Stream.prototype.shamefullySendComplete = function () {
+ this._c();
+ };
+ /**
+ * Combines multiple streams together to return a stream whose events are
+ * calculated from the latest events of each of the input streams.
+ *
+ * *combine* remembers the most recent event from each of the input streams.
+ * When any of the input streams emits an event, that event together with all
+ * the other saved events are combined in the `project` function which should
+ * return a value. That value will be emitted on the output stream. It's
+ * essentially a way of mixing the events from multiple streams according to a
+ * formula.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1----2-----3--------4---
+ * ----a-----b-----c--d------
+ * combine((x,y) => x+y)
+ * ----1a-2a-2b-3b-3c-3d-4d--
+ * ```
+ *
+ * @factory true
+ * @param {Function} project A function of type `(x: T1, y: T2) => R` or
+ * similar that takes the most recent events `x` and `y` from the input
+ * streams and returns a value. The output stream will emit that value. The
+ * number of arguments for this function should match the number of input
+ * streams.
+ * @param {Stream} stream1 A stream to combine together with other streams.
+ * @param {Stream} stream2 A stream to combine together with other streams.
+ * Two or more streams may be given as arguments.
+ * @return {Stream}
+ */
+ Stream.combine = function combine(project) {
+ var streams = [];
+ for (var _i = 1; _i < arguments.length; _i++) {
+ streams[_i - 1] = arguments[_i];
+ }
+ return new Stream(new CombineProducer(project, streams));
+ };
+ return Stream;
+}());
+exports.Stream = Stream;
+var MimicStream = (function (_super) {
+ __extends(MimicStream, _super);
+ function MimicStream() {
+ _super.call(this);
+ }
+ MimicStream.prototype._add = function (il) {
+ var t = this._target;
+ if (!t)
+ return;
+ t._add(il);
+ };
+ MimicStream.prototype._remove = function (il) {
+ var t = this._target;
+ if (!t)
+ return;
+ t._remove(il);
+ };
+ /**
+ * This method exists only on a MimicStream, which is created through
+ * `xs.createMimic()`. *imitate* changes this current MimicStream to behave
+ * like the `other` given stream.
+ *
+ * The `imitate` method and the `MimicStream` type exist to allow one thing:
+ * **circular dependency of streams**. For instance, let's imagine that for
+ * some reason you need to create a circular dependency where stream `first$`
+ * depends on stream `second$` which in turn depends on `first$`:
+ *
+ *
+ * ```js
+ * import delay from 'xstream/extra/delay'
+ *
+ * var first$ = second$.map(x => x * 10).take(3);
+ * var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100));
+ * ```
+ *
+ * However, that is invalid JavaScript, because `second$` is undefined
+ * on the first line. This is how a MimicStream and imitate can help solve it:
+ *
+ * ```js
+ * import delay from 'xstream/extra/delay'
+ *
+ * var secondMimic$ = xs.createMimic();
+ * var first$ = secondMimic$.map(x => x * 10).take(3);
+ * var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100));
+ * secondMimic$.imitate(second$);
+ * ```
+ *
+ * We create `secondMimic$` before the others, so it can be used in the
+ * declaration of `first$`. Then, after both `first$` and `second$` are
+ * defined, we hook `secondMimic$` with `second$` with `imitate()` to tell
+ * that they are "the same". `imitate` will not trigger the start of any
+ * stream, it simply forwards listeners of `secondMimic$` to `second$`.
+ *
+ * The following is an example where `imitate()` is important in Cycle.js
+ * applications. A parent component contains some child components. A child
+ * has an action stream which is given to the parent to define its state:
+ *
+ *
+ * ```js
+ * const childActionMimic$ = xs.createMimic();
+ * const parent = Parent({...sources, childAction$: childActionMimic$});
+ * const childAction$ = parent.state$.map(s => s.child.action$).flatten();
+ * childActionMimic$.imitate(childAction$);
+ * ```
+ *
+ * The *imitate* method returns nothing. Instead, it changes the behavior of
+ * the current stream, making it re-emit whatever events are emitted by the
+ * given `other` stream.
+ *
+ * Note, though, that **`imitate()` does not support MemoryStreams**. If we
+ * would attempt to imitate a MemoryStream in a circular dependency, we would
+ * either get a race condition (where the symptom would be "nothing happens")
+ * or an infinite cyclic emission of values. It's useful to think about
+ * MemoryStreams as cells in a spreadsheet. It doesn't make any sense to
+ * define a spreadsheet cell `A1` with a formula that depends on `B1` and
+ * cell `B1` defined with a formula that depends on `A1`.
+ *
+ * If you find yourself wanting to use `imitate()` with a
+ * MemoryStream, you should rework your code around `imitate()` to use a
+ * Stream instead. Look for the stream in the circular dependency that
+ * represents an event stream, and that would be a candidate for creating a
+ * MimicStream which then imitates the real event stream.
+ *
+ * @param {Stream} other The stream to imitate on the current one. Must not be
+ * a MemoryStream.
+ */
+ MimicStream.prototype.imitate = function (other) {
+ if (other instanceof MemoryStream) {
+ throw new Error('A MemoryStream was given to imitate(), but it only ' +
+ 'supports a Stream. Read more about this restriction here: ' +
+ 'https://github.com/staltz/xstream#faq');
+ }
+ this._target = other;
+ };
+ return MimicStream;
+}(Stream));
+exports.MimicStream = MimicStream;
+var MemoryStream = (function (_super) {
+ __extends(MemoryStream, _super);
+ function MemoryStream(producer) {
+ _super.call(this, producer);
+ this._has = false;
+ }
+ MemoryStream.prototype._n = function (x) {
+ this._v = x;
+ this._has = true;
+ _super.prototype._n.call(this, x);
+ };
+ MemoryStream.prototype._add = function (il) {
+ if (this._has) {
+ il._n(this._v);
+ }
+ _super.prototype._add.call(this, il);
+ };
+ MemoryStream.prototype._x = function () {
+ this._has = false;
+ _super.prototype._x.call(this);
+ };
+ MemoryStream.prototype.map = function (project) {
+ return this._map(project);
+ };
+ MemoryStream.prototype.mapTo = function (projectedValue) {
+ return _super.prototype.mapTo.call(this, projectedValue);
+ };
+ MemoryStream.prototype.take = function (amount) {
+ return _super.prototype.take.call(this, amount);
+ };
+ MemoryStream.prototype.endWhen = function (other) {
+ return _super.prototype.endWhen.call(this, other);
+ };
+ MemoryStream.prototype.replaceError = function (replace) {
+ return _super.prototype.replaceError.call(this, replace);
+ };
+ MemoryStream.prototype.debug = function (labelOrSpy) {
+ return _super.prototype.debug.call(this, labelOrSpy);
+ };
+ return MemoryStream;
+}(Stream));
+exports.MemoryStream = MemoryStream;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = Stream;
+
+},{}],81:[function(require,module,exports){
+"use strict";
+var core_1 = require('../core');
+var empty = {};
+var DropRepeatsOperator = (function () {
+ function DropRepeatsOperator(fn, ins) {
+ this.fn = fn;
+ this.ins = ins;
+ this.type = 'dropRepeats';
+ this.out = null;
+ this.v = empty;
+ }
+ DropRepeatsOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(this);
+ };
+ DropRepeatsOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = null;
+ this.v = empty;
+ };
+ DropRepeatsOperator.prototype.isEq = function (x, y) {
+ return this.fn ? this.fn(x, y) : x === y;
+ };
+ DropRepeatsOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (!u)
+ return;
+ var v = this.v;
+ if (v === empty || !this.isEq(t, v)) {
+ u._n(t);
+ }
+ this.v = t;
+ };
+ DropRepeatsOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._e(err);
+ };
+ DropRepeatsOperator.prototype._c = function () {
+ var u = this.out;
+ if (!u)
+ return;
+ u._c();
+ };
+ return DropRepeatsOperator;
+}());
+exports.DropRepeatsOperator = DropRepeatsOperator;
+function dropRepeats(isEqual) {
+ if (isEqual === void 0) { isEqual = null; }
+ return function dropRepeatsOperator(ins) {
+ return new core_1.Stream(new DropRepeatsOperator(isEqual, ins));
+ };
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = dropRepeats;
+
+},{"../core":80}],82:[function(require,module,exports){
+"use strict";
+var core_1 = require('./core');
+exports.Stream = core_1.Stream;
+exports.MemoryStream = core_1.MemoryStream;
+exports.MimicStream = core_1.MimicStream;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = core_1.Stream;
+
+},{"./core":80}],83:[function(require,module,exports){
+"use strict";
+var base_1 = require('@cycle/base');
+var xstream_adapter_1 = require('@cycle/xstream-adapter');
+/**
+ * A function that prepares the Cycle application to be executed. Takes a `main`
+ * function and prepares to circularly connects it to the given collection of
+ * driver functions. As an output, `Cycle()` returns an object with three
+ * properties: `sources`, `sinks` and `run`. Only when `run()` is called will
+ * the application actually execute. Refer to the documentation of `run()` for
+ * more details.
+ *
+ * **Example:**
+ * ```js
+ * const {sources, sinks, run} = Cycle(main, drivers);
+ * // ...
+ * const dispose = run(); // Executes the application
+ * // ...
+ * dispose();
+ * ```
+ *
+ * @param {Function} main a function that takes `sources` as input
+ * and outputs a collection of `sinks` Observables.
+ * @param {Object} drivers an object where keys are driver names and values
+ * are driver functions.
+ * @return {Object} an object with three properties: `sources`, `sinks` and
+ * `run`. `sources` is the collection of driver sources, `sinks` is the
+ * collection of driver sinks, these can be used for debugging or testing. `run`
+ * is the function that once called will execute the application.
+ * @function Cycle
+ */
+var Cycle = function (main, drivers) {
+ return base_1.default(main, drivers, { streamAdapter: xstream_adapter_1.default });
+};
+/**
+ * Takes a `main` function and circularly connects it to the given collection
+ * of driver functions.
+ *
+ * **Example:**
+ * ```js
+ * const dispose = Cycle.run(main, drivers);
+ * // ...
+ * dispose();
+ * ```
+ *
+ * The `main` function expects a collection of "source" Observables (returned
+ * from drivers) as input, and should return a collection of "sink" Observables
+ * (to be given to drivers). A "collection of Observables" is a JavaScript
+ * object where keys match the driver names registered by the `drivers` object,
+ * and values are the Observables. Refer to the documentation of each driver to
+ * see more details on what types of sources it outputs and sinks it receives.
+ *
+ * @param {Function} main a function that takes `sources` as input
+ * and outputs a collection of `sinks` Observables.
+ * @param {Object} drivers an object where keys are driver names and values
+ * are driver functions.
+ * @return {Function} a dispose function, used to terminate the execution of the
+ * Cycle.js program, cleaning up resources used.
+ * @function run
+ */
+function run(main, drivers) {
+ var run = base_1.default(main, drivers, { streamAdapter: xstream_adapter_1.default }).run;
+ return run();
+}
+exports.run = run;
+Cycle.run = run;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = Cycle;
+
+},{"@cycle/base":84,"@cycle/xstream-adapter":85}],84:[function(require,module,exports){
+"use strict";
+function logToConsoleError(err) {
+ var target = err.stack || err;
+ if (console && console.error) {
+ console.error(target);
+ }
+ else if (console && console.log) {
+ console.log(target);
+ }
+}
+function makeSinkProxies(drivers, streamAdapter) {
+ var sinkProxies = {};
+ for (var name_1 in drivers) {
+ if (drivers.hasOwnProperty(name_1)) {
+ var holdSubject = streamAdapter.makeSubject();
+ var driverStreamAdapter = drivers[name_1].streamAdapter || streamAdapter;
+ var stream = driverStreamAdapter.adapt(holdSubject.stream, streamAdapter.streamSubscribe);
+ sinkProxies[name_1] = {
+ stream: stream,
+ observer: holdSubject.observer,
+ };
+ }
+ }
+ return sinkProxies;
+}
+function callDrivers(drivers, sinkProxies, streamAdapter) {
+ var sources = {};
+ for (var name_2 in drivers) {
+ if (drivers.hasOwnProperty(name_2)) {
+ var driverOutput = drivers[name_2](sinkProxies[name_2].stream, streamAdapter, name_2);
+ var driverStreamAdapter = drivers[name_2].streamAdapter;
+ if (driverStreamAdapter && driverStreamAdapter.isValidStream(driverOutput)) {
+ sources[name_2] = streamAdapter.adapt(driverOutput, driverStreamAdapter.streamSubscribe);
+ }
+ else {
+ sources[name_2] = driverOutput;
+ }
+ }
+ }
+ return sources;
+}
+function replicateMany(sinks, sinkProxies, streamAdapter) {
+ var results = Object.keys(sinks)
+ .filter(function (name) { return !!sinkProxies[name]; })
+ .map(function (name) {
+ return streamAdapter.streamSubscribe(sinks[name], {
+ next: function (x) { sinkProxies[name].observer.next(x); },
+ error: function (err) {
+ logToConsoleError(err);
+ sinkProxies[name].observer.error(err);
+ },
+ complete: function (x) {
+ sinkProxies[name].observer.complete(x);
+ }
+ });
+ });
+ var disposeFunctions = results
+ .filter(function (dispose) { return typeof dispose === 'function'; });
+ return function () {
+ disposeFunctions.forEach(function (dispose) { return dispose(); });
+ };
+}
+function disposeSources(sources) {
+ for (var k in sources) {
+ if (sources.hasOwnProperty(k) && sources[k]
+ && typeof sources[k].dispose === 'function') {
+ sources[k].dispose();
+ }
+ }
+}
+var isObjectEmpty = function (obj) { return Object.keys(obj).length === 0; };
+function Cycle(main, drivers, options) {
+ if (typeof main !== "function") {
+ throw new Error("First argument given to Cycle must be the 'main' " +
+ "function.");
+ }
+ if (typeof drivers !== "object" || drivers === null) {
+ throw new Error("Second argument given to Cycle must be an object " +
+ "with driver functions as properties.");
+ }
+ if (isObjectEmpty(drivers)) {
+ throw new Error("Second argument given to Cycle must be an object " +
+ "with at least one driver function declared as a property.");
+ }
+ var streamAdapter = options.streamAdapter;
+ if (!streamAdapter || isObjectEmpty(streamAdapter)) {
+ throw new Error("Third argument given to Cycle must be an options object " +
+ "with the streamAdapter key supplied with a valid stream adapter.");
+ }
+ var sinkProxies = makeSinkProxies(drivers, streamAdapter);
+ var sources = callDrivers(drivers, sinkProxies, streamAdapter);
+ var sinks = main(sources);
+ if (typeof window !== 'undefined') {
+ window.Cyclejs = { sinks: sinks };
+ }
+ var run = function () {
+ var disposeReplication = replicateMany(sinks, sinkProxies, streamAdapter);
+ return function () {
+ disposeSources(sources);
+ disposeReplication();
+ };
+ };
+ return { sinks: sinks, sources: sources, run: run };
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = Cycle;
+
+},{}],85:[function(require,module,exports){
+arguments[4][20][0].apply(exports,arguments)
+},{"dup":20,"xstream":115}],86:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+/**
+ * Indicates that navigation was caused by a call to history.push.
+ */
+var PUSH = exports.PUSH = 'PUSH';
+
+/**
+ * Indicates that navigation was caused by a call to history.replace.
+ */
+var REPLACE = exports.REPLACE = 'REPLACE';
+
+/**
+ * Indicates that navigation was caused by some other action such
+ * as using a browser's back/forward buttons and/or manually manipulating
+ * the URL in a browser's location bar. This is the default.
+ *
+ * See https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate
+ * for more information.
+ */
+var POP = exports.POP = 'POP';
+},{}],87:[function(require,module,exports){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
+
+var loopAsync = exports.loopAsync = function loopAsync(turns, work, callback) {
+ var currentTurn = 0,
+ isDone = false;
+ var isSync = false,
+ hasNext = false,
+ doneArgs = void 0;
+
+ var done = function done() {
+ for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
+ args[_key] = arguments[_key];
+ }
+
+ isDone = true;
+
+ if (isSync) {
+ // Iterate instead of recursing if possible.
+ doneArgs = args;
+ return;
+ }
+
+ callback.apply(undefined, args);
+ };
+
+ var next = function next() {
+ if (isDone) return;
+
+ hasNext = true;
+
+ if (isSync) return; // Iterate instead of recursing if possible.
+
+ isSync = true;
+
+ while (!isDone && currentTurn < turns && hasNext) {
+ hasNext = false;
+ work(currentTurn++, next, done);
+ }
+
+ isSync = false;
+
+ if (isDone) {
+ // This means the loop finished synchronously.
+ callback.apply(undefined, _toConsumableArray(doneArgs));
+ return;
+ }
+
+ if (currentTurn >= turns && hasNext) {
+ isDone = true;
+ callback();
+ }
+ };
+
+ next();
+};
+},{}],88:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.go = exports.replaceLocation = exports.pushLocation = exports.startListener = exports.getUserConfirmation = exports.getCurrentLocation = undefined;
+
+var _LocationUtils = require('./LocationUtils');
+
+var _DOMUtils = require('./DOMUtils');
+
+var _DOMStateStorage = require('./DOMStateStorage');
+
+var _PathUtils = require('./PathUtils');
+
+/* eslint-disable no-alert */
+
+
+var PopStateEvent = 'popstate';
+
+var _createLocation = function _createLocation(historyState) {
+ var key = historyState && historyState.key;
+
+ return (0, _LocationUtils.createLocation)({
+ pathname: window.location.pathname,
+ search: window.location.search,
+ hash: window.location.hash,
+ state: key ? (0, _DOMStateStorage.readState)(key) : undefined
+ }, undefined, key);
+};
+
+var getCurrentLocation = exports.getCurrentLocation = function getCurrentLocation() {
+ var historyState = void 0;
+ try {
+ historyState = window.history.state || {};
+ } catch (error) {
+ // IE 11 sometimes throws when accessing window.history.state
+ // See https://github.com/mjackson/history/pull/289
+ historyState = {};
+ }
+
+ return _createLocation(historyState);
+};
+
+var getUserConfirmation = exports.getUserConfirmation = function getUserConfirmation(message, callback) {
+ return callback(window.confirm(message));
+};
+
+var startListener = exports.startListener = function startListener(listener) {
+ var handlePopState = function handlePopState(event) {
+ if (event.state !== undefined) // Ignore extraneous popstate events in WebKit
+ listener(_createLocation(event.state));
+ };
+
+ (0, _DOMUtils.addEventListener)(window, PopStateEvent, handlePopState);
+
+ return function () {
+ return (0, _DOMUtils.removeEventListener)(window, PopStateEvent, handlePopState);
+ };
+};
+
+var updateLocation = function updateLocation(location, updateState) {
+ var state = location.state;
+ var key = location.key;
+
+
+ if (state !== undefined) (0, _DOMStateStorage.saveState)(key, state);
+
+ updateState({ key: key }, (0, _PathUtils.createPath)(location));
+};
+
+var pushLocation = exports.pushLocation = function pushLocation(location) {
+ return updateLocation(location, function (state, path) {
+ return window.history.pushState(state, null, path);
+ });
+};
+
+var replaceLocation = exports.replaceLocation = function replaceLocation(location) {
+ return updateLocation(location, function (state, path) {
+ return window.history.replaceState(state, null, path);
+ });
+};
+
+var go = exports.go = function go(n) {
+ if (n) window.history.go(n);
+};
+},{"./DOMStateStorage":89,"./DOMUtils":90,"./LocationUtils":93,"./PathUtils":94}],89:[function(require,module,exports){
+(function (process){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.readState = exports.saveState = undefined;
+
+var _warning = require('warning');
+
+var _warning2 = _interopRequireDefault(_warning);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var QuotaExceededErrors = ['QuotaExceededError', 'QUOTA_EXCEEDED_ERR']; /* eslint-disable no-empty */
+
+
+var SecurityError = 'SecurityError';
+var KeyPrefix = '@@History/';
+
+var createKey = function createKey(key) {
+ return KeyPrefix + key;
+};
+
+var saveState = exports.saveState = function saveState(key, state) {
+ if (!window.sessionStorage) {
+ // Session storage is not available or hidden.
+ // sessionStorage is undefined in Internet Explorer when served via file protocol.
+ process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(false, '[history] Unable to save state; sessionStorage is not available') : void 0;
+ return;
+ }
+
+ try {
+ if (state == null) {
+ window.sessionStorage.removeItem(createKey(key));
+ } else {
+ window.sessionStorage.setItem(createKey(key), JSON.stringify(state));
+ }
+ } catch (error) {
+ if (error.name === SecurityError) {
+ // Blocking cookies in Chrome/Firefox/Safari throws SecurityError on any
+ // attempt to access window.sessionStorage.
+ process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(false, '[history] Unable to save state; sessionStorage is not available due to security settings') : void 0;
+
+ return;
+ }
+
+ if (QuotaExceededErrors.indexOf(error.name) >= 0 && window.sessionStorage.length === 0) {
+ // Safari "private mode" throws QuotaExceededError.
+ process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(false, '[history] Unable to save state; sessionStorage is not available in Safari private mode') : void 0;
+
+ return;
+ }
+
+ throw error;
+ }
+};
+
+var readState = exports.readState = function readState(key) {
+ var json = void 0;
+ try {
+ json = window.sessionStorage.getItem(createKey(key));
+ } catch (error) {
+ if (error.name === SecurityError) {
+ // Blocking cookies in Chrome/Firefox/Safari throws SecurityError on any
+ // attempt to access window.sessionStorage.
+ process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(false, '[history] Unable to read state; sessionStorage is not available due to security settings') : void 0;
+
+ return undefined;
+ }
+ }
+
+ if (json) {
+ try {
+ return JSON.parse(json);
+ } catch (error) {
+ // Ignore invalid JSON.
+ }
+ }
+
+ return undefined;
+};
+}).call(this,require('_process'))
+
+},{"_process":110,"warning":109}],90:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+var addEventListener = exports.addEventListener = function addEventListener(node, event, listener) {
+ return node.addEventListener ? node.addEventListener(event, listener, false) : node.attachEvent('on' + event, listener);
+};
+
+var removeEventListener = exports.removeEventListener = function removeEventListener(node, event, listener) {
+ return node.removeEventListener ? node.removeEventListener(event, listener, false) : node.detachEvent('on' + event, listener);
+};
+
+/**
+ * Returns true if the HTML5 history API is supported. Taken from Modernizr.
+ *
+ * https://github.com/Modernizr/Modernizr/blob/master/LICENSE
+ * https://github.com/Modernizr/Modernizr/blob/master/feature-detects/history.js
+ * changed to avoid false negatives for Windows Phones: https://github.com/reactjs/react-router/issues/586
+ */
+var supportsHistory = exports.supportsHistory = function supportsHistory() {
+ var ua = window.navigator.userAgent;
+
+ if ((ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('Mobile Safari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1) return false;
+
+ return window.history && 'pushState' in window.history;
+};
+
+/**
+ * Returns false if using go(n) with hash history causes a full page reload.
+ */
+var supportsGoWithoutReloadUsingHash = exports.supportsGoWithoutReloadUsingHash = function supportsGoWithoutReloadUsingHash() {
+ return window.navigator.userAgent.indexOf('Firefox') === -1;
+};
+},{}],91:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+var canUseDOM = exports.canUseDOM = !!(typeof window !== 'undefined' && window.document && window.document.createElement);
+},{}],92:[function(require,module,exports){
+(function (process){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.replaceLocation = exports.pushLocation = exports.startListener = exports.getCurrentLocation = exports.go = exports.getUserConfirmation = undefined;
+
+var _BrowserProtocol = require('./BrowserProtocol');
+
+Object.defineProperty(exports, 'getUserConfirmation', {
+ enumerable: true,
+ get: function get() {
+ return _BrowserProtocol.getUserConfirmation;
+ }
+});
+Object.defineProperty(exports, 'go', {
+ enumerable: true,
+ get: function get() {
+ return _BrowserProtocol.go;
+ }
+});
+
+var _warning = require('warning');
+
+var _warning2 = _interopRequireDefault(_warning);
+
+var _LocationUtils = require('./LocationUtils');
+
+var _DOMUtils = require('./DOMUtils');
+
+var _DOMStateStorage = require('./DOMStateStorage');
+
+var _PathUtils = require('./PathUtils');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var HashChangeEvent = 'hashchange';
+
+var getHashPath = function getHashPath() {
+ // We can't use window.location.hash here because it's not
+ // consistent across browsers - Firefox will pre-decode it!
+ var href = window.location.href;
+ var index = href.indexOf('#');
+ return index === -1 ? '' : href.substring(index + 1);
+};
+
+var pushHashPath = function pushHashPath(path) {
+ return window.location.hash = path;
+};
+
+var replaceHashPath = function replaceHashPath(path) {
+ var i = window.location.href.indexOf('#');
+
+ window.location.replace(window.location.href.slice(0, i >= 0 ? i : 0) + '#' + path);
+};
+
+var ensureSlash = function ensureSlash() {
+ var path = getHashPath();
+
+ if ((0, _PathUtils.isAbsolutePath)(path)) return true;
+
+ replaceHashPath('/' + path);
+
+ return false;
+};
+
+var getCurrentLocation = exports.getCurrentLocation = function getCurrentLocation(queryKey) {
+ var path = getHashPath();
+ var key = (0, _PathUtils.getQueryStringValueFromPath)(path, queryKey);
+
+ var state = void 0;
+ if (key) {
+ path = (0, _PathUtils.stripQueryStringValueFromPath)(path, queryKey);
+ state = (0, _DOMStateStorage.readState)(key);
+ }
+
+ var init = (0, _PathUtils.parsePath)(path);
+ init.state = state;
+
+ return (0, _LocationUtils.createLocation)(init, undefined, key);
+};
+
+var prevLocation = void 0;
+
+var startListener = exports.startListener = function startListener(listener, queryKey) {
+ var handleHashChange = function handleHashChange() {
+ if (!ensureSlash()) return; // Hash path must always begin with a /
+
+ var currentLocation = getCurrentLocation(queryKey);
+
+ if (prevLocation && currentLocation.key && prevLocation.key === currentLocation.key) return; // Ignore extraneous hashchange events
+
+ prevLocation = currentLocation;
+
+ listener(currentLocation);
+ };
+
+ ensureSlash();
+ (0, _DOMUtils.addEventListener)(window, HashChangeEvent, handleHashChange);
+
+ return function () {
+ return (0, _DOMUtils.removeEventListener)(window, HashChangeEvent, handleHashChange);
+ };
+};
+
+var updateLocation = function updateLocation(location, queryKey, updateHash) {
+ var state = location.state;
+ var key = location.key;
+
+ var path = (0, _PathUtils.createPath)(location);
+
+ if (state !== undefined) {
+ path = (0, _PathUtils.addQueryStringValueToPath)(path, queryKey, key);
+ (0, _DOMStateStorage.saveState)(key, state);
+ }
+
+ prevLocation = location;
+
+ updateHash(path);
+};
+
+var pushLocation = exports.pushLocation = function pushLocation(location, queryKey) {
+ return updateLocation(location, queryKey, function (path) {
+ if (getHashPath() !== path) {
+ pushHashPath(path);
+ } else {
+ process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(false, 'You cannot PUSH the same path using hash history') : void 0;
+ }
+ });
+};
+
+var replaceLocation = exports.replaceLocation = function replaceLocation(location, queryKey) {
+ return updateLocation(location, queryKey, function (path) {
+ if (getHashPath() !== path) replaceHashPath(path);
+ });
+};
+}).call(this,require('_process'))
+
+},{"./BrowserProtocol":88,"./DOMStateStorage":89,"./DOMUtils":90,"./LocationUtils":93,"./PathUtils":94,"_process":110,"warning":109}],93:[function(require,module,exports){
+(function (process){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.locationsAreEqual = exports.statesAreEqual = exports.createLocation = exports.createQuery = undefined;
+
+var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj; };
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var _invariant = require('invariant');
+
+var _invariant2 = _interopRequireDefault(_invariant);
+
+var _PathUtils = require('./PathUtils');
+
+var _Actions = require('./Actions');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var createQuery = exports.createQuery = function createQuery(props) {
+ return _extends(Object.create(null), props);
+};
+
+var createLocation = exports.createLocation = function createLocation() {
+ var input = arguments.length <= 0 || arguments[0] === undefined ? '/' : arguments[0];
+ var action = arguments.length <= 1 || arguments[1] === undefined ? _Actions.POP : arguments[1];
+ var key = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2];
+
+ var object = typeof input === 'string' ? (0, _PathUtils.parsePath)(input) : input;
+
+ var pathname = object.pathname || '/';
+ var search = object.search || '';
+ var hash = object.hash || '';
+ var state = object.state;
+
+ return {
+ pathname: pathname,
+ search: search,
+ hash: hash,
+ state: state,
+ action: action,
+ key: key
+ };
+};
+
+var isDate = function isDate(object) {
+ return Object.prototype.toString.call(object) === '[object Date]';
+};
+
+var statesAreEqual = exports.statesAreEqual = function statesAreEqual(a, b) {
+ if (a === b) return true;
+
+ var typeofA = typeof a === 'undefined' ? 'undefined' : _typeof(a);
+ var typeofB = typeof b === 'undefined' ? 'undefined' : _typeof(b);
+
+ if (typeofA !== typeofB) return false;
+
+ !(typeofA !== 'function') ? process.env.NODE_ENV !== 'production' ? (0, _invariant2.default)(false, 'You must not store functions in location state') : (0, _invariant2.default)(false) : void 0;
+
+ // Not the same object, but same type.
+ if (typeofA === 'object') {
+ !!(isDate(a) && isDate(b)) ? process.env.NODE_ENV !== 'production' ? (0, _invariant2.default)(false, 'You must not store Date objects in location state') : (0, _invariant2.default)(false) : void 0;
+
+ if (!Array.isArray(a)) return Object.keys(a).every(function (key) {
+ return statesAreEqual(a[key], b[key]);
+ });
+
+ return Array.isArray(b) && a.length === b.length && a.every(function (item, index) {
+ return statesAreEqual(item, b[index]);
+ });
+ }
+
+ // All other serializable types (string, number, boolean)
+ // should be strict equal.
+ return false;
+};
+
+var locationsAreEqual = exports.locationsAreEqual = function locationsAreEqual(a, b) {
+ return a.key === b.key &&
+ // a.action === b.action && // Different action !== location change.
+ a.pathname === b.pathname && a.search === b.search && a.hash === b.hash && statesAreEqual(a.state, b.state);
+};
+}).call(this,require('_process'))
+
+},{"./Actions":86,"./PathUtils":94,"_process":110,"invariant":105}],94:[function(require,module,exports){
+(function (process){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.createPath = exports.parsePath = exports.getQueryStringValueFromPath = exports.stripQueryStringValueFromPath = exports.addQueryStringValueToPath = exports.isAbsolutePath = undefined;
+
+var _warning = require('warning');
+
+var _warning2 = _interopRequireDefault(_warning);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var isAbsolutePath = exports.isAbsolutePath = function isAbsolutePath(path) {
+ return typeof path === 'string' && path.charAt(0) === '/';
+};
+
+var addQueryStringValueToPath = exports.addQueryStringValueToPath = function addQueryStringValueToPath(path, key, value) {
+ var _parsePath = parsePath(path);
+
+ var pathname = _parsePath.pathname;
+ var search = _parsePath.search;
+ var hash = _parsePath.hash;
+
+
+ return createPath({
+ pathname: pathname,
+ search: search + (search.indexOf('?') === -1 ? '?' : '&') + key + '=' + value,
+ hash: hash
+ });
+};
+
+var stripQueryStringValueFromPath = exports.stripQueryStringValueFromPath = function stripQueryStringValueFromPath(path, key) {
+ var _parsePath2 = parsePath(path);
+
+ var pathname = _parsePath2.pathname;
+ var search = _parsePath2.search;
+ var hash = _parsePath2.hash;
+
+
+ return createPath({
+ pathname: pathname,
+ search: search.replace(new RegExp('([?&])' + key + '=[a-zA-Z0-9]+(&?)'), function (match, prefix, suffix) {
+ return prefix === '?' ? prefix : suffix;
+ }),
+ hash: hash
+ });
+};
+
+var getQueryStringValueFromPath = exports.getQueryStringValueFromPath = function getQueryStringValueFromPath(path, key) {
+ var _parsePath3 = parsePath(path);
+
+ var search = _parsePath3.search;
+
+ var match = search.match(new RegExp('[?&]' + key + '=([a-zA-Z0-9]+)'));
+ return match && match[1];
+};
+
+var extractPath = function extractPath(string) {
+ var match = string.match(/^(https?:)?\/\/[^\/]*/);
+ return match == null ? string : string.substring(match[0].length);
+};
+
+var parsePath = exports.parsePath = function parsePath(path) {
+ var pathname = extractPath(path);
+ var search = '';
+ var hash = '';
+
+ process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(path === pathname, 'A path must be pathname + search + hash only, not a full URL like "%s"', path) : void 0;
+
+ var hashIndex = pathname.indexOf('#');
+ if (hashIndex !== -1) {
+ hash = pathname.substring(hashIndex);
+ pathname = pathname.substring(0, hashIndex);
+ }
+
+ var searchIndex = pathname.indexOf('?');
+ if (searchIndex !== -1) {
+ search = pathname.substring(searchIndex);
+ pathname = pathname.substring(0, searchIndex);
+ }
+
+ if (pathname === '') pathname = '/';
+
+ return {
+ pathname: pathname,
+ search: search,
+ hash: hash
+ };
+};
+
+var createPath = exports.createPath = function createPath(location) {
+ if (location == null || typeof location === 'string') return location;
+
+ var basename = location.basename;
+ var pathname = location.pathname;
+ var search = location.search;
+ var hash = location.hash;
+
+ var path = (basename || '') + pathname;
+
+ if (search && search !== '?') path += search;
+
+ if (hash) path += hash;
+
+ return path;
+};
+}).call(this,require('_process'))
+
+},{"_process":110,"warning":109}],95:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.replaceLocation = exports.pushLocation = exports.getCurrentLocation = exports.go = exports.getUserConfirmation = undefined;
+
+var _BrowserProtocol = require('./BrowserProtocol');
+
+Object.defineProperty(exports, 'getUserConfirmation', {
+ enumerable: true,
+ get: function get() {
+ return _BrowserProtocol.getUserConfirmation;
+ }
+});
+Object.defineProperty(exports, 'go', {
+ enumerable: true,
+ get: function get() {
+ return _BrowserProtocol.go;
+ }
+});
+
+var _LocationUtils = require('./LocationUtils');
+
+var _PathUtils = require('./PathUtils');
+
+var getCurrentLocation = exports.getCurrentLocation = function getCurrentLocation() {
+ return (0, _LocationUtils.createLocation)(window.location);
+};
+
+var pushLocation = exports.pushLocation = function pushLocation(location) {
+ window.location.href = (0, _PathUtils.createPath)(location);
+ return false; // Don't update location
+};
+
+var replaceLocation = exports.replaceLocation = function replaceLocation(location) {
+ window.location.replace((0, _PathUtils.createPath)(location));
+ return false; // Don't update location
+};
+},{"./BrowserProtocol":88,"./LocationUtils":93,"./PathUtils":94}],96:[function(require,module,exports){
+(function (process){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var _invariant = require('invariant');
+
+var _invariant2 = _interopRequireDefault(_invariant);
+
+var _ExecutionEnvironment = require('./ExecutionEnvironment');
+
+var _BrowserProtocol = require('./BrowserProtocol');
+
+var BrowserProtocol = _interopRequireWildcard(_BrowserProtocol);
+
+var _RefreshProtocol = require('./RefreshProtocol');
+
+var RefreshProtocol = _interopRequireWildcard(_RefreshProtocol);
+
+var _DOMUtils = require('./DOMUtils');
+
+var _createHistory = require('./createHistory');
+
+var _createHistory2 = _interopRequireDefault(_createHistory);
+
+function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+/**
+ * Creates and returns a history object that uses HTML5's history API
+ * (pushState, replaceState, and the popstate event) to manage history.
+ * This is the recommended method of managing history in browsers because
+ * it provides the cleanest URLs.
+ *
+ * Note: In browsers that do not support the HTML5 history API full
+ * page reloads will be used to preserve clean URLs. You can force this
+ * behavior using { forceRefresh: true } in options.
+ */
+var createBrowserHistory = function createBrowserHistory() {
+ var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
+
+ !_ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? (0, _invariant2.default)(false, 'Browser history needs a DOM') : (0, _invariant2.default)(false) : void 0;
+
+ var useRefresh = options.forceRefresh || !(0, _DOMUtils.supportsHistory)();
+ var Protocol = useRefresh ? RefreshProtocol : BrowserProtocol;
+
+ var getUserConfirmation = Protocol.getUserConfirmation;
+ var getCurrentLocation = Protocol.getCurrentLocation;
+ var pushLocation = Protocol.pushLocation;
+ var replaceLocation = Protocol.replaceLocation;
+ var go = Protocol.go;
+
+
+ var history = (0, _createHistory2.default)(_extends({
+ getUserConfirmation: getUserConfirmation }, options, {
+ getCurrentLocation: getCurrentLocation,
+ pushLocation: pushLocation,
+ replaceLocation: replaceLocation,
+ go: go
+ }));
+
+ var listenerCount = 0,
+ stopListener = void 0;
+
+ var startListener = function startListener(listener, before) {
+ if (++listenerCount === 1) stopListener = BrowserProtocol.startListener(history.transitionTo);
+
+ var unlisten = before ? history.listenBefore(listener) : history.listen(listener);
+
+ return function () {
+ unlisten();
+
+ if (--listenerCount === 0) stopListener();
+ };
+ };
+
+ var listenBefore = function listenBefore(listener) {
+ return startListener(listener, true);
+ };
+
+ var listen = function listen(listener) {
+ return startListener(listener, false);
+ };
+
+ return _extends({}, history, {
+ listenBefore: listenBefore,
+ listen: listen
+ });
+};
+
+exports.default = createBrowserHistory;
+}).call(this,require('_process'))
+
+},{"./BrowserProtocol":88,"./DOMUtils":90,"./ExecutionEnvironment":91,"./RefreshProtocol":95,"./createHistory":98,"_process":110,"invariant":105}],97:[function(require,module,exports){
+(function (process){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var _warning = require('warning');
+
+var _warning2 = _interopRequireDefault(_warning);
+
+var _invariant = require('invariant');
+
+var _invariant2 = _interopRequireDefault(_invariant);
+
+var _ExecutionEnvironment = require('./ExecutionEnvironment');
+
+var _DOMUtils = require('./DOMUtils');
+
+var _HashProtocol = require('./HashProtocol');
+
+var HashProtocol = _interopRequireWildcard(_HashProtocol);
+
+var _createHistory = require('./createHistory');
+
+var _createHistory2 = _interopRequireDefault(_createHistory);
+
+function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var DefaultQueryKey = '_k';
+
+var createHashHistory = function createHashHistory() {
+ var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
+
+ !_ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? (0, _invariant2.default)(false, 'Hash history needs a DOM') : (0, _invariant2.default)(false) : void 0;
+
+ var queryKey = options.queryKey;
+
+
+ process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(queryKey !== false, 'Using { queryKey: false } no longer works. Instead, just don\'t ' + 'use location state if you don\'t want a key in your URL query string') : void 0;
+
+ if (typeof queryKey !== 'string') queryKey = DefaultQueryKey;
+
+ var getUserConfirmation = HashProtocol.getUserConfirmation;
+
+
+ var getCurrentLocation = function getCurrentLocation() {
+ return HashProtocol.getCurrentLocation(queryKey);
+ };
+
+ var pushLocation = function pushLocation(location) {
+ return HashProtocol.pushLocation(location, queryKey);
+ };
+
+ var replaceLocation = function replaceLocation(location) {
+ return HashProtocol.replaceLocation(location, queryKey);
+ };
+
+ var history = (0, _createHistory2.default)(_extends({
+ getUserConfirmation: getUserConfirmation }, options, {
+ getCurrentLocation: getCurrentLocation,
+ pushLocation: pushLocation,
+ replaceLocation: replaceLocation,
+ go: HashProtocol.go
+ }));
+
+ var listenerCount = 0,
+ stopListener = void 0;
+
+ var startListener = function startListener(listener, before) {
+ if (++listenerCount === 1) stopListener = HashProtocol.startListener(history.transitionTo, queryKey);
+
+ var unlisten = before ? history.listenBefore(listener) : history.listen(listener);
+
+ return function () {
+ unlisten();
+
+ if (--listenerCount === 0) stopListener();
+ };
+ };
+
+ var listenBefore = function listenBefore(listener) {
+ return startListener(listener, true);
+ };
+
+ var listen = function listen(listener) {
+ return startListener(listener, false);
+ };
+
+ var goIsSupportedWithoutReload = (0, _DOMUtils.supportsGoWithoutReloadUsingHash)();
+
+ var go = function go(n) {
+ process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(goIsSupportedWithoutReload, 'Hash history go(n) causes a full page reload in this browser') : void 0;
+
+ history.go(n);
+ };
+
+ var createHref = function createHref(path) {
+ return '#' + history.createHref(path);
+ };
+
+ return _extends({}, history, {
+ listenBefore: listenBefore,
+ listen: listen,
+ go: go,
+ createHref: createHref
+ });
+};
+
+exports.default = createHashHistory;
+}).call(this,require('_process'))
+
+},{"./DOMUtils":90,"./ExecutionEnvironment":91,"./HashProtocol":92,"./createHistory":98,"_process":110,"invariant":105,"warning":109}],98:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _AsyncUtils = require('./AsyncUtils');
+
+var _PathUtils = require('./PathUtils');
+
+var _runTransitionHook = require('./runTransitionHook');
+
+var _runTransitionHook2 = _interopRequireDefault(_runTransitionHook);
+
+var _Actions = require('./Actions');
+
+var _LocationUtils = require('./LocationUtils');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
+
+var createHistory = function createHistory() {
+ var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
+ var getCurrentLocation = options.getCurrentLocation;
+ var getUserConfirmation = options.getUserConfirmation;
+ var pushLocation = options.pushLocation;
+ var replaceLocation = options.replaceLocation;
+ var go = options.go;
+ var keyLength = options.keyLength;
+
+
+ var currentLocation = void 0;
+ var pendingLocation = void 0;
+ var beforeListeners = [];
+ var listeners = [];
+ var allKeys = [];
+
+ var getCurrentIndex = function getCurrentIndex() {
+ if (pendingLocation && pendingLocation.action === _Actions.POP) return allKeys.indexOf(pendingLocation.key);
+
+ if (currentLocation) return allKeys.indexOf(currentLocation.key);
+
+ return -1;
+ };
+
+ var updateLocation = function updateLocation(nextLocation) {
+ currentLocation = nextLocation;
+
+ var currentIndex = getCurrentIndex();
+
+ if (currentLocation.action === _Actions.PUSH) {
+ allKeys = [].concat(_toConsumableArray(allKeys.slice(0, currentIndex + 1)), [currentLocation.key]);
+ } else if (currentLocation.action === _Actions.REPLACE) {
+ allKeys[currentIndex] = currentLocation.key;
+ }
+
+ listeners.forEach(function (listener) {
+ return listener(currentLocation);
+ });
+ };
+
+ var listenBefore = function listenBefore(listener) {
+ beforeListeners.push(listener);
+
+ return function () {
+ return beforeListeners = beforeListeners.filter(function (item) {
+ return item !== listener;
+ });
+ };
+ };
+
+ var listen = function listen(listener) {
+ listeners.push(listener);
+
+ return function () {
+ return listeners = listeners.filter(function (item) {
+ return item !== listener;
+ });
+ };
+ };
+
+ var confirmTransitionTo = function confirmTransitionTo(location, callback) {
+ (0, _AsyncUtils.loopAsync)(beforeListeners.length, function (index, next, done) {
+ (0, _runTransitionHook2.default)(beforeListeners[index], location, function (result) {
+ return result != null ? done(result) : next();
+ });
+ }, function (message) {
+ if (getUserConfirmation && typeof message === 'string') {
+ getUserConfirmation(message, function (ok) {
+ return callback(ok !== false);
+ });
+ } else {
+ callback(message !== false);
+ }
+ });
+ };
+
+ var transitionTo = function transitionTo(nextLocation) {
+ if (currentLocation && (0, _LocationUtils.locationsAreEqual)(currentLocation, nextLocation) || pendingLocation && (0, _LocationUtils.locationsAreEqual)(pendingLocation, nextLocation)) return; // Nothing to do
+
+ pendingLocation = nextLocation;
+
+ confirmTransitionTo(nextLocation, function (ok) {
+ if (pendingLocation !== nextLocation) return; // Transition was interrupted during confirmation
+
+ pendingLocation = null;
+
+ if (ok) {
+ // Treat PUSH to same path like REPLACE to be consistent with browsers
+ if (nextLocation.action === _Actions.PUSH) {
+ var prevPath = (0, _PathUtils.createPath)(currentLocation);
+ var nextPath = (0, _PathUtils.createPath)(nextLocation);
+
+ if (nextPath === prevPath && (0, _LocationUtils.statesAreEqual)(currentLocation.state, nextLocation.state)) nextLocation.action = _Actions.REPLACE;
+ }
+
+ if (nextLocation.action === _Actions.POP) {
+ updateLocation(nextLocation);
+ } else if (nextLocation.action === _Actions.PUSH) {
+ if (pushLocation(nextLocation) !== false) updateLocation(nextLocation);
+ } else if (nextLocation.action === _Actions.REPLACE) {
+ if (replaceLocation(nextLocation) !== false) updateLocation(nextLocation);
+ }
+ } else if (currentLocation && nextLocation.action === _Actions.POP) {
+ var prevIndex = allKeys.indexOf(currentLocation.key);
+ var nextIndex = allKeys.indexOf(nextLocation.key);
+
+ if (prevIndex !== -1 && nextIndex !== -1) go(prevIndex - nextIndex); // Restore the URL
+ }
+ });
+ };
+
+ var push = function push(input) {
+ return transitionTo(createLocation(input, _Actions.PUSH));
+ };
+
+ var replace = function replace(input) {
+ return transitionTo(createLocation(input, _Actions.REPLACE));
+ };
+
+ var goBack = function goBack() {
+ return go(-1);
+ };
+
+ var goForward = function goForward() {
+ return go(1);
+ };
+
+ var createKey = function createKey() {
+ return Math.random().toString(36).substr(2, keyLength || 6);
+ };
+
+ var createHref = function createHref(location) {
+ return (0, _PathUtils.createPath)(location);
+ };
+
+ var createLocation = function createLocation(location, action) {
+ var key = arguments.length <= 2 || arguments[2] === undefined ? createKey() : arguments[2];
+ return (0, _LocationUtils.createLocation)(location, action, key);
+ };
+
+ return {
+ getCurrentLocation: getCurrentLocation,
+ listenBefore: listenBefore,
+ listen: listen,
+ transitionTo: transitionTo,
+ push: push,
+ replace: replace,
+ go: go,
+ goBack: goBack,
+ goForward: goForward,
+ createKey: createKey,
+ createPath: _PathUtils.createPath,
+ createHref: createHref,
+ createLocation: createLocation
+ };
+};
+
+exports.default = createHistory;
+},{"./Actions":86,"./AsyncUtils":87,"./LocationUtils":93,"./PathUtils":94,"./runTransitionHook":101}],99:[function(require,module,exports){
+(function (process){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var _warning = require('warning');
+
+var _warning2 = _interopRequireDefault(_warning);
+
+var _invariant = require('invariant');
+
+var _invariant2 = _interopRequireDefault(_invariant);
+
+var _LocationUtils = require('./LocationUtils');
+
+var _PathUtils = require('./PathUtils');
+
+var _createHistory = require('./createHistory');
+
+var _createHistory2 = _interopRequireDefault(_createHistory);
+
+var _Actions = require('./Actions');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var createStateStorage = function createStateStorage(entries) {
+ return entries.filter(function (entry) {
+ return entry.state;
+ }).reduce(function (memo, entry) {
+ memo[entry.key] = entry.state;
+ return memo;
+ }, {});
+};
+
+var createMemoryHistory = function createMemoryHistory() {
+ var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
+
+ if (Array.isArray(options)) {
+ options = { entries: options };
+ } else if (typeof options === 'string') {
+ options = { entries: [options] };
+ }
+
+ var getCurrentLocation = function getCurrentLocation() {
+ var entry = entries[current];
+ var path = (0, _PathUtils.createPath)(entry);
+
+ var key = void 0,
+ state = void 0;
+ if (entry.key) {
+ key = entry.key;
+ state = readState(key);
+ }
+
+ var init = (0, _PathUtils.parsePath)(path);
+
+ return (0, _LocationUtils.createLocation)(_extends({}, init, { state: state }), undefined, key);
+ };
+
+ var canGo = function canGo(n) {
+ var index = current + n;
+ return index >= 0 && index < entries.length;
+ };
+
+ var go = function go(n) {
+ if (!n) return;
+
+ if (!canGo(n)) {
+ process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(false, 'Cannot go(%s) there is not enough history', n) : void 0;
+
+ return;
+ }
+
+ current += n;
+ var currentLocation = getCurrentLocation();
+
+ // Change action to POP
+ history.transitionTo(_extends({}, currentLocation, { action: _Actions.POP }));
+ };
+
+ var pushLocation = function pushLocation(location) {
+ current += 1;
+
+ if (current < entries.length) entries.splice(current);
+
+ entries.push(location);
+
+ saveState(location.key, location.state);
+ };
+
+ var replaceLocation = function replaceLocation(location) {
+ entries[current] = location;
+ saveState(location.key, location.state);
+ };
+
+ var history = (0, _createHistory2.default)(_extends({}, options, {
+ getCurrentLocation: getCurrentLocation,
+ pushLocation: pushLocation,
+ replaceLocation: replaceLocation,
+ go: go
+ }));
+
+ var _options = options;
+ var entries = _options.entries;
+ var current = _options.current;
+
+
+ if (typeof entries === 'string') {
+ entries = [entries];
+ } else if (!Array.isArray(entries)) {
+ entries = ['/'];
+ }
+
+ entries = entries.map(function (entry) {
+ return (0, _LocationUtils.createLocation)(entry);
+ });
+
+ if (current == null) {
+ current = entries.length - 1;
+ } else {
+ !(current >= 0 && current < entries.length) ? process.env.NODE_ENV !== 'production' ? (0, _invariant2.default)(false, 'Current index must be >= 0 and < %s, was %s', entries.length, current) : (0, _invariant2.default)(false) : void 0;
+ }
+
+ var storage = createStateStorage(entries);
+
+ var saveState = function saveState(key, state) {
+ return storage[key] = state;
+ };
+
+ var readState = function readState(key) {
+ return storage[key];
+ };
+
+ return history;
+};
+
+exports.default = createMemoryHistory;
+}).call(this,require('_process'))
+
+},{"./Actions":86,"./LocationUtils":93,"./PathUtils":94,"./createHistory":98,"_process":110,"invariant":105,"warning":109}],100:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.locationsAreEqual = exports.Actions = exports.useQueries = exports.useBeforeUnload = exports.useBasename = exports.createMemoryHistory = exports.createHashHistory = exports.createHistory = undefined;
+
+var _LocationUtils = require('./LocationUtils');
+
+Object.defineProperty(exports, 'locationsAreEqual', {
+ enumerable: true,
+ get: function get() {
+ return _LocationUtils.locationsAreEqual;
+ }
+});
+
+var _createBrowserHistory = require('./createBrowserHistory');
+
+var _createBrowserHistory2 = _interopRequireDefault(_createBrowserHistory);
+
+var _createHashHistory2 = require('./createHashHistory');
+
+var _createHashHistory3 = _interopRequireDefault(_createHashHistory2);
+
+var _createMemoryHistory2 = require('./createMemoryHistory');
+
+var _createMemoryHistory3 = _interopRequireDefault(_createMemoryHistory2);
+
+var _useBasename2 = require('./useBasename');
+
+var _useBasename3 = _interopRequireDefault(_useBasename2);
+
+var _useBeforeUnload2 = require('./useBeforeUnload');
+
+var _useBeforeUnload3 = _interopRequireDefault(_useBeforeUnload2);
+
+var _useQueries2 = require('./useQueries');
+
+var _useQueries3 = _interopRequireDefault(_useQueries2);
+
+var _Actions2 = require('./Actions');
+
+var _Actions3 = _interopRequireDefault(_Actions2);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+exports.createHistory = _createBrowserHistory2.default;
+exports.createHashHistory = _createHashHistory3.default;
+exports.createMemoryHistory = _createMemoryHistory3.default;
+exports.useBasename = _useBasename3.default;
+exports.useBeforeUnload = _useBeforeUnload3.default;
+exports.useQueries = _useQueries3.default;
+exports.Actions = _Actions3.default;
+},{"./Actions":86,"./LocationUtils":93,"./createBrowserHistory":96,"./createHashHistory":97,"./createMemoryHistory":99,"./useBasename":102,"./useBeforeUnload":103,"./useQueries":104}],101:[function(require,module,exports){
+(function (process){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _warning = require('warning');
+
+var _warning2 = _interopRequireDefault(_warning);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var runTransitionHook = function runTransitionHook(hook, location, callback) {
+ var result = hook(location, callback);
+
+ if (hook.length < 2) {
+ // Assume the hook runs synchronously and automatically
+ // call the callback with the return value.
+ callback(result);
+ } else {
+ process.env.NODE_ENV !== 'production' ? (0, _warning2.default)(result === undefined, 'You should not "return" in a transition hook with a callback argument; ' + 'call the callback instead') : void 0;
+ }
+};
+
+exports.default = runTransitionHook;
+}).call(this,require('_process'))
+
+},{"_process":110,"warning":109}],102:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var _runTransitionHook = require('./runTransitionHook');
+
+var _runTransitionHook2 = _interopRequireDefault(_runTransitionHook);
+
+var _PathUtils = require('./PathUtils');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var useBasename = function useBasename(createHistory) {
+ return function () {
+ var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
+
+ var history = createHistory(options);
+ var basename = options.basename;
+
+
+ var addBasename = function addBasename(location) {
+ if (!location) return location;
+
+ if (basename && location.basename == null) {
+ if (location.pathname.indexOf(basename) === 0) {
+ location.pathname = location.pathname.substring(basename.length);
+ location.basename = basename;
+
+ if (location.pathname === '') location.pathname = '/';
+ } else {
+ location.basename = '';
+ }
+ }
+
+ return location;
+ };
+
+ var prependBasename = function prependBasename(location) {
+ if (!basename) return location;
+
+ var object = typeof location === 'string' ? (0, _PathUtils.parsePath)(location) : location;
+ var pname = object.pathname;
+ var normalizedBasename = basename.slice(-1) === '/' ? basename : basename + '/';
+ var normalizedPathname = pname.charAt(0) === '/' ? pname.slice(1) : pname;
+ var pathname = normalizedBasename + normalizedPathname;
+
+ return _extends({}, location, {
+ pathname: pathname
+ });
+ };
+
+ // Override all read methods with basename-aware versions.
+ var getCurrentLocation = function getCurrentLocation() {
+ return addBasename(history.getCurrentLocation());
+ };
+
+ var listenBefore = function listenBefore(hook) {
+ return history.listenBefore(function (location, callback) {
+ return (0, _runTransitionHook2.default)(hook, addBasename(location), callback);
+ });
+ };
+
+ var listen = function listen(listener) {
+ return history.listen(function (location) {
+ return listener(addBasename(location));
+ });
+ };
+
+ // Override all write methods with basename-aware versions.
+ var push = function push(location) {
+ return history.push(prependBasename(location));
+ };
+
+ var replace = function replace(location) {
+ return history.replace(prependBasename(location));
+ };
+
+ var createPath = function createPath(location) {
+ return history.createPath(prependBasename(location));
+ };
+
+ var createHref = function createHref(location) {
+ return history.createHref(prependBasename(location));
+ };
+
+ var createLocation = function createLocation(location) {
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
+
+ return addBasename(history.createLocation.apply(history, [prependBasename(location)].concat(args)));
+ };
+
+ return _extends({}, history, {
+ getCurrentLocation: getCurrentLocation,
+ listenBefore: listenBefore,
+ listen: listen,
+ push: push,
+ replace: replace,
+ createPath: createPath,
+ createHref: createHref,
+ createLocation: createLocation
+ });
+ };
+};
+
+exports.default = useBasename;
+},{"./PathUtils":94,"./runTransitionHook":101}],103:[function(require,module,exports){
+(function (process){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var _invariant = require('invariant');
+
+var _invariant2 = _interopRequireDefault(_invariant);
+
+var _DOMUtils = require('./DOMUtils');
+
+var _ExecutionEnvironment = require('./ExecutionEnvironment');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var startListener = function startListener(getPromptMessage) {
+ var handleBeforeUnload = function handleBeforeUnload(event) {
+ var message = getPromptMessage();
+
+ if (typeof message === 'string') {
+ (event || window.event).returnValue = message;
+ return message;
+ }
+
+ return undefined;
+ };
+
+ (0, _DOMUtils.addEventListener)(window, 'beforeunload', handleBeforeUnload);
+
+ return function () {
+ return (0, _DOMUtils.removeEventListener)(window, 'beforeunload', handleBeforeUnload);
+ };
+};
+
+/**
+ * Returns a new createHistory function that can be used to create
+ * history objects that know how to use the beforeunload event in web
+ * browsers to cancel navigation.
+ */
+var useBeforeUnload = function useBeforeUnload(createHistory) {
+ !_ExecutionEnvironment.canUseDOM ? process.env.NODE_ENV !== 'production' ? (0, _invariant2.default)(false, 'useBeforeUnload only works in DOM environments') : (0, _invariant2.default)(false) : void 0;
+
+ return function (options) {
+ var history = createHistory(options);
+
+ var listeners = [];
+ var stopListener = void 0;
+
+ var getPromptMessage = function getPromptMessage() {
+ var message = void 0;
+ for (var i = 0, len = listeners.length; message == null && i < len; ++i) {
+ message = listeners[i].call();
+ }return message;
+ };
+
+ var listenBeforeUnload = function listenBeforeUnload(listener) {
+ if (listeners.push(listener) === 1) stopListener = startListener(getPromptMessage);
+
+ return function () {
+ listeners = listeners.filter(function (item) {
+ return item !== listener;
+ });
+
+ if (listeners.length === 0 && stopListener) {
+ stopListener();
+ stopListener = null;
+ }
+ };
+ };
+
+ return _extends({}, history, {
+ listenBeforeUnload: listenBeforeUnload
+ });
+ };
+};
+
+exports.default = useBeforeUnload;
+}).call(this,require('_process'))
+
+},{"./DOMUtils":90,"./ExecutionEnvironment":91,"_process":110,"invariant":105}],104:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var _queryString = require('query-string');
+
+var _runTransitionHook = require('./runTransitionHook');
+
+var _runTransitionHook2 = _interopRequireDefault(_runTransitionHook);
+
+var _LocationUtils = require('./LocationUtils');
+
+var _PathUtils = require('./PathUtils');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var defaultStringifyQuery = function defaultStringifyQuery(query) {
+ return (0, _queryString.stringify)(query).replace(/%20/g, '+');
+};
+
+var defaultParseQueryString = _queryString.parse;
+
+/**
+ * Returns a new createHistory function that may be used to create
+ * history objects that know how to handle URL queries.
+ */
+var useQueries = function useQueries(createHistory) {
+ return function () {
+ var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0];
+
+ var history = createHistory(options);
+ var stringifyQuery = options.stringifyQuery;
+ var parseQueryString = options.parseQueryString;
+
+
+ if (typeof stringifyQuery !== 'function') stringifyQuery = defaultStringifyQuery;
+
+ if (typeof parseQueryString !== 'function') parseQueryString = defaultParseQueryString;
+
+ var decodeQuery = function decodeQuery(location) {
+ if (!location) return location;
+
+ if (location.query == null) location.query = parseQueryString(location.search.substring(1));
+
+ return location;
+ };
+
+ var encodeQuery = function encodeQuery(location, query) {
+ if (query == null) return location;
+
+ var object = typeof location === 'string' ? (0, _PathUtils.parsePath)(location) : location;
+ var queryString = stringifyQuery(query);
+ var search = queryString ? '?' + queryString : '';
+
+ return _extends({}, object, {
+ search: search
+ });
+ };
+
+ // Override all read methods with query-aware versions.
+ var getCurrentLocation = function getCurrentLocation() {
+ return decodeQuery(history.getCurrentLocation());
+ };
+
+ var listenBefore = function listenBefore(hook) {
+ return history.listenBefore(function (location, callback) {
+ return (0, _runTransitionHook2.default)(hook, decodeQuery(location), callback);
+ });
+ };
+
+ var listen = function listen(listener) {
+ return history.listen(function (location) {
+ return listener(decodeQuery(location));
+ });
+ };
+
+ // Override all write methods with query-aware versions.
+ var push = function push(location) {
+ return history.push(encodeQuery(location, location.query));
+ };
+
+ var replace = function replace(location) {
+ return history.replace(encodeQuery(location, location.query));
+ };
+
+ var createPath = function createPath(location) {
+ return history.createPath(encodeQuery(location, location.query));
+ };
+
+ var createHref = function createHref(location) {
+ return history.createHref(encodeQuery(location, location.query));
+ };
+
+ var createLocation = function createLocation(location) {
+ for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
+ args[_key - 1] = arguments[_key];
+ }
+
+ var newLocation = history.createLocation.apply(history, [encodeQuery(location, location.query)].concat(args));
+
+ if (location.query) newLocation.query = (0, _LocationUtils.createQuery)(location.query);
+
+ return decodeQuery(newLocation);
+ };
+
+ return _extends({}, history, {
+ getCurrentLocation: getCurrentLocation,
+ listenBefore: listenBefore,
+ listen: listen,
+ push: push,
+ replace: replace,
+ createPath: createPath,
+ createHref: createHref,
+ createLocation: createLocation
+ });
+ };
+};
+
+exports.default = useQueries;
+},{"./LocationUtils":93,"./PathUtils":94,"./runTransitionHook":101,"query-string":106}],105:[function(require,module,exports){
+(function (process){
+/**
+ * Copyright 2013-2015, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+'use strict';
+
+/**
+ * Use invariant() to assert state which your program assumes to be true.
+ *
+ * Provide sprintf-style format (only %s is supported) and arguments
+ * to provide information about what broke and what you were
+ * expecting.
+ *
+ * The invariant message will be stripped in production, but the invariant
+ * will remain to ensure logic does not differ in production.
+ */
+
+var invariant = function(condition, format, a, b, c, d, e, f) {
+ if (process.env.NODE_ENV !== 'production') {
+ if (format === undefined) {
+ throw new Error('invariant requires an error message argument');
+ }
+ }
+
+ if (!condition) {
+ var error;
+ if (format === undefined) {
+ error = new Error(
+ 'Minified exception occurred; use the non-minified dev environment ' +
+ 'for the full error message and additional helpful warnings.'
+ );
+ } else {
+ var args = [a, b, c, d, e, f];
+ var argIndex = 0;
+ error = new Error(
+ format.replace(/%s/g, function() { return args[argIndex++]; })
+ );
+ error.name = 'Invariant Violation';
+ }
+
+ error.framesToPop = 1; // we don't care about invariant's own frame
+ throw error;
+ }
+};
+
+module.exports = invariant;
+
+}).call(this,require('_process'))
+
+},{"_process":110}],106:[function(require,module,exports){
+'use strict';
+var strictUriEncode = require('strict-uri-encode');
+var objectAssign = require('object-assign');
+
+function encode(value, opts) {
+ if (opts.encode) {
+ return opts.strict ? strictUriEncode(value) : encodeURIComponent(value);
+ }
+
+ return value;
+}
+
+exports.extract = function (str) {
+ return str.split('?')[1] || '';
+};
+
+exports.parse = function (str) {
+ // Create an object with no prototype
+ // https://github.com/sindresorhus/query-string/issues/47
+ var ret = Object.create(null);
+
+ if (typeof str !== 'string') {
+ return ret;
+ }
+
+ str = str.trim().replace(/^(\?|#|&)/, '');
+
+ if (!str) {
+ return ret;
+ }
+
+ str.split('&').forEach(function (param) {
+ var parts = param.replace(/\+/g, ' ').split('=');
+ // Firefox (pre 40) decodes `%3D` to `=`
+ // https://github.com/sindresorhus/query-string/pull/37
+ var key = parts.shift();
+ var val = parts.length > 0 ? parts.join('=') : undefined;
+
+ key = decodeURIComponent(key);
+
+ // missing `=` should be `null`:
+ // http://w3.org/TR/2012/WD-url-20120524/#collect-url-parameters
+ val = val === undefined ? null : decodeURIComponent(val);
+
+ if (ret[key] === undefined) {
+ ret[key] = val;
+ } else if (Array.isArray(ret[key])) {
+ ret[key].push(val);
+ } else {
+ ret[key] = [ret[key], val];
+ }
+ });
+
+ return ret;
+};
+
+exports.stringify = function (obj, opts) {
+ var defaults = {
+ encode: true,
+ strict: true
+ };
+
+ opts = objectAssign(defaults, opts);
+
+ return obj ? Object.keys(obj).sort().map(function (key) {
+ var val = obj[key];
+
+ if (val === undefined) {
+ return '';
+ }
+
+ if (val === null) {
+ return encode(key, opts);
+ }
+
+ if (Array.isArray(val)) {
+ var result = [];
+
+ val.slice().forEach(function (val2) {
+ if (val2 === undefined) {
+ return;
+ }
+
+ if (val2 === null) {
+ result.push(encode(key, opts));
+ } else {
+ result.push(encode(key, opts) + '=' + encode(val2, opts));
+ }
+ });
+
+ return result.join('&');
+ }
+
+ return encode(key, opts) + '=' + encode(val, opts);
+ }).filter(function (x) {
+ return x.length > 0;
+ }).join('&') : '';
+};
+
+},{"object-assign":107,"strict-uri-encode":108}],107:[function(require,module,exports){
+'use strict';
+/* eslint-disable no-unused-vars */
+var hasOwnProperty = Object.prototype.hasOwnProperty;
+var propIsEnumerable = Object.prototype.propertyIsEnumerable;
+
+function toObject(val) {
+ if (val === null || val === undefined) {
+ throw new TypeError('Object.assign cannot be called with null or undefined');
+ }
+
+ return Object(val);
+}
+
+function shouldUseNative() {
+ try {
+ if (!Object.assign) {
+ return false;
+ }
+
+ // Detect buggy property enumeration order in older V8 versions.
+
+ // https://bugs.chromium.org/p/v8/issues/detail?id=4118
+ var test1 = new String('abc'); // eslint-disable-line
+ test1[5] = 'de';
+ if (Object.getOwnPropertyNames(test1)[0] === '5') {
+ return false;
+ }
+
+ // https://bugs.chromium.org/p/v8/issues/detail?id=3056
+ var test2 = {};
+ for (var i = 0; i < 10; i++) {
+ test2['_' + String.fromCharCode(i)] = i;
+ }
+ var order2 = Object.getOwnPropertyNames(test2).map(function (n) {
+ return test2[n];
+ });
+ if (order2.join('') !== '0123456789') {
+ return false;
+ }
+
+ // https://bugs.chromium.org/p/v8/issues/detail?id=3056
+ var test3 = {};
+ 'abcdefghijklmnopqrst'.split('').forEach(function (letter) {
+ test3[letter] = letter;
+ });
+ if (Object.keys(Object.assign({}, test3)).join('') !==
+ 'abcdefghijklmnopqrst') {
+ return false;
+ }
+
+ return true;
+ } catch (e) {
+ // We don't expect any of the above to throw, but better to be safe.
+ return false;
+ }
+}
+
+module.exports = shouldUseNative() ? Object.assign : function (target, source) {
+ var from;
+ var to = toObject(target);
+ var symbols;
+
+ for (var s = 1; s < arguments.length; s++) {
+ from = Object(arguments[s]);
+
+ for (var key in from) {
+ if (hasOwnProperty.call(from, key)) {
+ to[key] = from[key];
+ }
+ }
+
+ if (Object.getOwnPropertySymbols) {
+ symbols = Object.getOwnPropertySymbols(from);
+ for (var i = 0; i < symbols.length; i++) {
+ if (propIsEnumerable.call(from, symbols[i])) {
+ to[symbols[i]] = from[symbols[i]];
+ }
+ }
+ }
+ }
+
+ return to;
+};
+
+},{}],108:[function(require,module,exports){
+'use strict';
+module.exports = function (str) {
+ return encodeURIComponent(str).replace(/[!'()*]/g, function (c) {
+ return '%' + c.charCodeAt(0).toString(16).toUpperCase();
+ });
+};
+
+},{}],109:[function(require,module,exports){
+(function (process){
+/**
+ * Copyright 2014-2015, Facebook, Inc.
+ * All rights reserved.
+ *
+ * This source code is licensed under the BSD-style license found in the
+ * LICENSE file in the root directory of this source tree. An additional grant
+ * of patent rights can be found in the PATENTS file in the same directory.
+ */
+
+'use strict';
+
+/**
+ * Similar to invariant but only logs a warning if the condition is not met.
+ * This can be used to log issues in development environments in critical
+ * paths. Removing the logging code for production environments will keep the
+ * same logic and follow the same code paths.
+ */
+
+var warning = function() {};
+
+if (process.env.NODE_ENV !== 'production') {
+ warning = function(condition, format, args) {
+ var len = arguments.length;
+ args = new Array(len > 2 ? len - 2 : 0);
+ for (var key = 2; key < len; key++) {
+ args[key - 2] = arguments[key];
+ }
+ if (format === undefined) {
+ throw new Error(
+ '`warning(condition, format, ...args)` requires a warning ' +
+ 'message argument'
+ );
+ }
+
+ if (format.length < 10 || (/^[s\W]*$/).test(format)) {
+ throw new Error(
+ 'The warning format should be able to uniquely identify this ' +
+ 'warning. Please, use a more descriptive format than: ' + format
+ );
+ }
+
+ if (!condition) {
+ var argIndex = 0;
+ var message = 'Warning: ' +
+ format.replace(/%s/g, function() {
+ return args[argIndex++];
+ });
+ if (typeof console !== 'undefined') {
+ console.error(message);
+ }
+ try {
+ // This error was thrown as a convenience so that you can use this stack
+ // to find the callsite that caused this warning to fire.
+ throw new Error(message);
+ } catch(x) {}
+ }
+ };
+}
+
+module.exports = warning;
+
+}).call(this,require('_process'))
+
+},{"_process":110}],110:[function(require,module,exports){
+// shim for using process in browser
+var process = module.exports = {};
+
+// cached from whatever global is present so that test runners that stub it
+// don't break things. But we need to wrap it in a try catch in case it is
+// wrapped in strict mode code which doesn't define any globals. It's inside a
+// function because try/catches deoptimize in certain engines.
+
+var cachedSetTimeout;
+var cachedClearTimeout;
+
+(function () {
+ try {
+ cachedSetTimeout = setTimeout;
+ } catch (e) {
+ cachedSetTimeout = function () {
+ throw new Error('setTimeout is not defined');
+ }
+ }
+ try {
+ cachedClearTimeout = clearTimeout;
+ } catch (e) {
+ cachedClearTimeout = function () {
+ throw new Error('clearTimeout is not defined');
+ }
+ }
+} ())
+function runTimeout(fun) {
+ if (cachedSetTimeout === setTimeout) {
+ return setTimeout(fun, 0);
+ } else {
+ return cachedSetTimeout.call(null, fun, 0);
+ }
+}
+function runClearTimeout(marker) {
+ if (cachedClearTimeout === clearTimeout) {
+ clearTimeout(marker);
+ } else {
+ cachedClearTimeout.call(null, marker);
+ }
+}
+var queue = [];
+var draining = false;
+var currentQueue;
+var queueIndex = -1;
+
+function cleanUpNextTick() {
+ if (!draining || !currentQueue) {
+ return;
+ }
+ draining = false;
+ if (currentQueue.length) {
+ queue = currentQueue.concat(queue);
+ } else {
+ queueIndex = -1;
+ }
+ if (queue.length) {
+ drainQueue();
+ }
+}
+
+function drainQueue() {
+ if (draining) {
+ return;
+ }
+ var timeout = runTimeout(cleanUpNextTick);
+ draining = true;
+
+ var len = queue.length;
+ while(len) {
+ currentQueue = queue;
+ queue = [];
+ while (++queueIndex < len) {
+ if (currentQueue) {
+ currentQueue[queueIndex].run();
+ }
+ }
+ queueIndex = -1;
+ len = queue.length;
+ }
+ currentQueue = null;
+ draining = false;
+ runClearTimeout(timeout);
+}
+
+process.nextTick = function (fun) {
+ var args = new Array(arguments.length - 1);
+ if (arguments.length > 1) {
+ for (var i = 1; i < arguments.length; i++) {
+ args[i - 1] = arguments[i];
+ }
+ }
+ queue.push(new Item(fun, args));
+ if (queue.length === 1 && !draining) {
+ runTimeout(drainQueue);
+ }
+};
+
+// v8 likes predictible objects
+function Item(fun, array) {
+ this.fun = fun;
+ this.array = array;
+}
+Item.prototype.run = function () {
+ this.fun.apply(null, this.array);
+};
+process.title = 'browser';
+process.browser = true;
+process.env = {};
+process.argv = [];
+process.version = ''; // empty string to avoid regexp issues
+process.versions = {};
+
+function noop() {}
+
+process.on = noop;
+process.addListener = noop;
+process.once = noop;
+process.off = noop;
+process.removeListener = noop;
+process.removeAllListeners = noop;
+process.emit = noop;
+
+process.binding = function (name) {
+ throw new Error('process.binding is not supported');
+};
+
+process.cwd = function () { return '/' };
+process.chdir = function (dir) {
+ throw new Error('process.chdir is not supported');
+};
+process.umask = function() { return 0; };
+
+},{}],111:[function(require,module,exports){
+"use strict";
+var __extends = (this && this.__extends) || function (d, b) {
+ for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+ function __() { this.constructor = d; }
+ d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var NO = {};
+function noop() { }
+function copy(a) {
+ var l = a.length;
+ var b = Array(l);
+ for (var i = 0; i < l; ++i) {
+ b[i] = a[i];
+ }
+ return b;
+}
+exports.NO_IL = {
+ _n: noop,
+ _e: noop,
+ _c: noop,
+};
+// mutates the input
+function internalizeProducer(producer) {
+ producer._start =
+ function _start(il) {
+ il.next = il._n;
+ il.error = il._e;
+ il.complete = il._c;
+ this.start(il);
+ };
+ producer._stop = producer.stop;
+}
+function compose2(f1, f2) {
+ return function composedFn(arg) {
+ return f1(f2(arg));
+ };
+}
+function and(f1, f2) {
+ return function andFn(t) {
+ return f1(t) && f2(t);
+ };
+}
+var MergeProducer = (function () {
+ function MergeProducer(insArr) {
+ this.type = 'merge';
+ this.insArr = insArr;
+ this.out = NO;
+ this.ac = 0;
+ }
+ MergeProducer.prototype._start = function (out) {
+ this.out = out;
+ var s = this.insArr;
+ var L = s.length;
+ this.ac = L;
+ for (var i = 0; i < L; i++) {
+ s[i]._add(this);
+ }
+ };
+ MergeProducer.prototype._stop = function () {
+ var s = this.insArr;
+ var L = s.length;
+ for (var i = 0; i < L; i++) {
+ s[i]._remove(this);
+ }
+ this.out = NO;
+ };
+ MergeProducer.prototype._n = function (t) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._n(t);
+ };
+ MergeProducer.prototype._e = function (err) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._e(err);
+ };
+ MergeProducer.prototype._c = function () {
+ if (--this.ac <= 0) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._c();
+ }
+ };
+ return MergeProducer;
+}());
+exports.MergeProducer = MergeProducer;
+var CombineListener = (function () {
+ function CombineListener(i, out, p) {
+ this.i = i;
+ this.out = out;
+ this.p = p;
+ p.ils.push(this);
+ }
+ CombineListener.prototype._n = function (t) {
+ var p = this.p, out = this.out;
+ if (!out)
+ return;
+ if (p.up(t, this.i)) {
+ out._n(p.vals);
+ }
+ };
+ CombineListener.prototype._e = function (err) {
+ var out = this.out;
+ if (!out)
+ return;
+ out._e(err);
+ };
+ CombineListener.prototype._c = function () {
+ var p = this.p;
+ if (!p.out)
+ return;
+ if (--p.Nc === 0) {
+ p.out._c();
+ }
+ };
+ return CombineListener;
+}());
+exports.CombineListener = CombineListener;
+var CombineProducer = (function () {
+ function CombineProducer(insArr) {
+ this.type = 'combine';
+ this.insArr = insArr;
+ this.out = NO;
+ this.ils = [];
+ this.Nc = this.Nn = 0;
+ this.vals = [];
+ }
+ CombineProducer.prototype.up = function (t, i) {
+ var v = this.vals[i];
+ var Nn = !this.Nn ? 0 : v === NO ? --this.Nn : this.Nn;
+ this.vals[i] = t;
+ return Nn === 0;
+ };
+ CombineProducer.prototype._start = function (out) {
+ this.out = out;
+ var s = this.insArr;
+ var n = this.Nc = this.Nn = s.length;
+ var vals = this.vals = new Array(n);
+ if (n === 0) {
+ out._n([]);
+ out._c();
+ }
+ else {
+ for (var i = 0; i < n; i++) {
+ vals[i] = NO;
+ s[i]._add(new CombineListener(i, out, this));
+ }
+ }
+ };
+ CombineProducer.prototype._stop = function () {
+ var s = this.insArr;
+ var n = s.length;
+ for (var i = 0; i < n; i++) {
+ s[i]._remove(this.ils[i]);
+ }
+ this.out = NO;
+ this.ils = [];
+ this.vals = [];
+ };
+ return CombineProducer;
+}());
+exports.CombineProducer = CombineProducer;
+var FromArrayProducer = (function () {
+ function FromArrayProducer(a) {
+ this.type = 'fromArray';
+ this.a = a;
+ }
+ FromArrayProducer.prototype._start = function (out) {
+ var a = this.a;
+ for (var i = 0, l = a.length; i < l; i++) {
+ out._n(a[i]);
+ }
+ out._c();
+ };
+ FromArrayProducer.prototype._stop = function () {
+ };
+ return FromArrayProducer;
+}());
+exports.FromArrayProducer = FromArrayProducer;
+var FromPromiseProducer = (function () {
+ function FromPromiseProducer(p) {
+ this.type = 'fromPromise';
+ this.on = false;
+ this.p = p;
+ }
+ FromPromiseProducer.prototype._start = function (out) {
+ var prod = this;
+ this.on = true;
+ this.p.then(function (v) {
+ if (prod.on) {
+ out._n(v);
+ out._c();
+ }
+ }, function (e) {
+ out._e(e);
+ }).then(null, function (err) {
+ setTimeout(function () { throw err; });
+ });
+ };
+ FromPromiseProducer.prototype._stop = function () {
+ this.on = false;
+ };
+ return FromPromiseProducer;
+}());
+exports.FromPromiseProducer = FromPromiseProducer;
+var PeriodicProducer = (function () {
+ function PeriodicProducer(period) {
+ this.type = 'periodic';
+ this.period = period;
+ this.intervalID = -1;
+ this.i = 0;
+ }
+ PeriodicProducer.prototype._start = function (stream) {
+ var self = this;
+ function intervalHandler() { stream._n(self.i++); }
+ this.intervalID = setInterval(intervalHandler, this.period);
+ };
+ PeriodicProducer.prototype._stop = function () {
+ if (this.intervalID !== -1)
+ clearInterval(this.intervalID);
+ this.intervalID = -1;
+ this.i = 0;
+ };
+ return PeriodicProducer;
+}());
+exports.PeriodicProducer = PeriodicProducer;
+var DebugOperator = (function () {
+ function DebugOperator(arg, ins) {
+ this.type = 'debug';
+ this.ins = ins;
+ this.out = NO;
+ this.s = noop;
+ this.l = '';
+ if (typeof arg === 'string') {
+ this.l = arg;
+ }
+ else if (typeof arg === 'function') {
+ this.s = arg;
+ }
+ }
+ DebugOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(this);
+ };
+ DebugOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = NO;
+ };
+ DebugOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ var s = this.s, l = this.l;
+ if (s !== noop) {
+ try {
+ s(t);
+ }
+ catch (e) {
+ u._e(e);
+ }
+ }
+ else if (l) {
+ console.log(l + ':', t);
+ }
+ else {
+ console.log(t);
+ }
+ u._n(t);
+ };
+ DebugOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._e(err);
+ };
+ DebugOperator.prototype._c = function () {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._c();
+ };
+ return DebugOperator;
+}());
+exports.DebugOperator = DebugOperator;
+var DropOperator = (function () {
+ function DropOperator(max, ins) {
+ this.type = 'drop';
+ this.ins = ins;
+ this.out = NO;
+ this.max = max;
+ this.dropped = 0;
+ }
+ DropOperator.prototype._start = function (out) {
+ this.out = out;
+ this.dropped = 0;
+ this.ins._add(this);
+ };
+ DropOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = NO;
+ };
+ DropOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ if (this.dropped++ >= this.max)
+ u._n(t);
+ };
+ DropOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._e(err);
+ };
+ DropOperator.prototype._c = function () {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._c();
+ };
+ return DropOperator;
+}());
+exports.DropOperator = DropOperator;
+var OtherIL = (function () {
+ function OtherIL(out, op) {
+ this.out = out;
+ this.op = op;
+ }
+ OtherIL.prototype._n = function (t) {
+ this.op.end();
+ };
+ OtherIL.prototype._e = function (err) {
+ this.out._e(err);
+ };
+ OtherIL.prototype._c = function () {
+ this.op.end();
+ };
+ return OtherIL;
+}());
+var EndWhenOperator = (function () {
+ function EndWhenOperator(o, ins) {
+ this.type = 'endWhen';
+ this.ins = ins;
+ this.out = NO;
+ this.o = o;
+ this.oil = exports.NO_IL;
+ }
+ EndWhenOperator.prototype._start = function (out) {
+ this.out = out;
+ this.o._add(this.oil = new OtherIL(out, this));
+ this.ins._add(this);
+ };
+ EndWhenOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.o._remove(this.oil);
+ this.out = NO;
+ this.oil = exports.NO_IL;
+ };
+ EndWhenOperator.prototype.end = function () {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._c();
+ };
+ EndWhenOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._n(t);
+ };
+ EndWhenOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._e(err);
+ };
+ EndWhenOperator.prototype._c = function () {
+ this.end();
+ };
+ return EndWhenOperator;
+}());
+exports.EndWhenOperator = EndWhenOperator;
+var FilterOperator = (function () {
+ function FilterOperator(passes, ins) {
+ this.type = 'filter';
+ this.ins = ins;
+ this.out = NO;
+ this.passes = passes;
+ }
+ FilterOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(this);
+ };
+ FilterOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = NO;
+ };
+ FilterOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ try {
+ if (this.passes(t))
+ u._n(t);
+ }
+ catch (e) {
+ u._e(e);
+ }
+ };
+ FilterOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._e(err);
+ };
+ FilterOperator.prototype._c = function () {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._c();
+ };
+ return FilterOperator;
+}());
+exports.FilterOperator = FilterOperator;
+var FlattenListener = (function () {
+ function FlattenListener(out, op) {
+ this.out = out;
+ this.op = op;
+ }
+ FlattenListener.prototype._n = function (t) {
+ this.out._n(t);
+ };
+ FlattenListener.prototype._e = function (err) {
+ this.out._e(err);
+ };
+ FlattenListener.prototype._c = function () {
+ this.op.inner = NO;
+ this.op.less();
+ };
+ return FlattenListener;
+}());
+var FlattenOperator = (function () {
+ function FlattenOperator(ins) {
+ this.type = 'flatten';
+ this.ins = ins;
+ this.out = NO;
+ this.open = true;
+ this.inner = NO;
+ this.il = exports.NO_IL;
+ }
+ FlattenOperator.prototype._start = function (out) {
+ this.out = out;
+ this.open = true;
+ this.inner = NO;
+ this.il = exports.NO_IL;
+ this.ins._add(this);
+ };
+ FlattenOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ if (this.inner !== NO)
+ this.inner._remove(this.il);
+ this.out = NO;
+ this.open = true;
+ this.inner = NO;
+ this.il = exports.NO_IL;
+ };
+ FlattenOperator.prototype.less = function () {
+ var u = this.out;
+ if (u === NO)
+ return;
+ if (!this.open && this.inner === NO)
+ u._c();
+ };
+ FlattenOperator.prototype._n = function (s) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ var _a = this, inner = _a.inner, il = _a.il;
+ if (s === inner && s._prod !== NO)
+ s._stopNow();
+ if (inner !== NO && il !== exports.NO_IL)
+ inner._remove(il);
+ (this.inner = s)._add(this.il = new FlattenListener(u, this));
+ };
+ FlattenOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._e(err);
+ };
+ FlattenOperator.prototype._c = function () {
+ this.open = false;
+ this.less();
+ };
+ return FlattenOperator;
+}());
+exports.FlattenOperator = FlattenOperator;
+var FoldOperator = (function () {
+ function FoldOperator(f, seed, ins) {
+ this.type = 'fold';
+ this.ins = ins;
+ this.out = NO;
+ this.f = f;
+ this.acc = this.seed = seed;
+ }
+ FoldOperator.prototype._start = function (out) {
+ this.out = out;
+ this.acc = this.seed;
+ out._n(this.acc);
+ this.ins._add(this);
+ };
+ FoldOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = NO;
+ this.acc = this.seed;
+ };
+ FoldOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ try {
+ u._n(this.acc = this.f(this.acc, t));
+ }
+ catch (e) {
+ u._e(e);
+ }
+ };
+ FoldOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._e(err);
+ };
+ FoldOperator.prototype._c = function () {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._c();
+ };
+ return FoldOperator;
+}());
+exports.FoldOperator = FoldOperator;
+var LastOperator = (function () {
+ function LastOperator(ins) {
+ this.type = 'last';
+ this.ins = ins;
+ this.out = NO;
+ this.has = false;
+ this.val = NO;
+ }
+ LastOperator.prototype._start = function (out) {
+ this.out = out;
+ this.has = false;
+ this.ins._add(this);
+ };
+ LastOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = NO;
+ this.val = NO;
+ };
+ LastOperator.prototype._n = function (t) {
+ this.has = true;
+ this.val = t;
+ };
+ LastOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._e(err);
+ };
+ LastOperator.prototype._c = function () {
+ var u = this.out;
+ if (u === NO)
+ return;
+ if (this.has) {
+ u._n(this.val);
+ u._c();
+ }
+ else {
+ u._e('TODO show proper error');
+ }
+ };
+ return LastOperator;
+}());
+exports.LastOperator = LastOperator;
+var MapFlattenInner = (function () {
+ function MapFlattenInner(out, op) {
+ this.out = out;
+ this.op = op;
+ }
+ MapFlattenInner.prototype._n = function (r) {
+ this.out._n(r);
+ };
+ MapFlattenInner.prototype._e = function (err) {
+ this.out._e(err);
+ };
+ MapFlattenInner.prototype._c = function () {
+ this.op.inner = NO;
+ this.op.less();
+ };
+ return MapFlattenInner;
+}());
+var MapFlattenOperator = (function () {
+ function MapFlattenOperator(mapOp) {
+ this.type = mapOp.type + "+flatten";
+ this.ins = mapOp.ins;
+ this.out = NO;
+ this.mapOp = mapOp;
+ this.inner = NO;
+ this.il = exports.NO_IL;
+ this.open = true;
+ }
+ MapFlattenOperator.prototype._start = function (out) {
+ this.out = out;
+ this.inner = NO;
+ this.il = exports.NO_IL;
+ this.open = true;
+ this.mapOp.ins._add(this);
+ };
+ MapFlattenOperator.prototype._stop = function () {
+ this.mapOp.ins._remove(this);
+ if (this.inner !== NO)
+ this.inner._remove(this.il);
+ this.out = NO;
+ this.inner = NO;
+ this.il = exports.NO_IL;
+ };
+ MapFlattenOperator.prototype.less = function () {
+ if (!this.open && this.inner === NO) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._c();
+ }
+ };
+ MapFlattenOperator.prototype._n = function (v) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ var _a = this, inner = _a.inner, il = _a.il;
+ var s;
+ try {
+ s = this.mapOp.project(v);
+ }
+ catch (e) {
+ u._e(e);
+ return;
+ }
+ if (s === inner && s._prod !== NO)
+ s._stopNow();
+ if (inner !== NO && il !== exports.NO_IL)
+ inner._remove(il);
+ (this.inner = s)._add(this.il = new MapFlattenInner(u, this));
+ };
+ MapFlattenOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._e(err);
+ };
+ MapFlattenOperator.prototype._c = function () {
+ this.open = false;
+ this.less();
+ };
+ return MapFlattenOperator;
+}());
+exports.MapFlattenOperator = MapFlattenOperator;
+var MapOperator = (function () {
+ function MapOperator(project, ins) {
+ this.type = 'map';
+ this.ins = ins;
+ this.out = NO;
+ this.project = project;
+ }
+ MapOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(this);
+ };
+ MapOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = NO;
+ };
+ MapOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ try {
+ u._n(this.project(t));
+ }
+ catch (e) {
+ u._e(e);
+ }
+ };
+ MapOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._e(err);
+ };
+ MapOperator.prototype._c = function () {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._c();
+ };
+ return MapOperator;
+}());
+exports.MapOperator = MapOperator;
+var FilterMapOperator = (function (_super) {
+ __extends(FilterMapOperator, _super);
+ function FilterMapOperator(passes, project, ins) {
+ _super.call(this, project, ins);
+ this.type = 'filter+map';
+ this.passes = passes;
+ }
+ FilterMapOperator.prototype._n = function (v) {
+ if (this.passes(v)) {
+ _super.prototype._n.call(this, v);
+ }
+ ;
+ };
+ return FilterMapOperator;
+}(MapOperator));
+exports.FilterMapOperator = FilterMapOperator;
+var RememberOperator = (function () {
+ function RememberOperator(ins) {
+ this.type = 'remember';
+ this.ins = ins;
+ this.out = NO;
+ }
+ RememberOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(out);
+ };
+ RememberOperator.prototype._stop = function () {
+ this.ins._remove(this.out);
+ this.out = NO;
+ };
+ return RememberOperator;
+}());
+exports.RememberOperator = RememberOperator;
+var ReplaceErrorOperator = (function () {
+ function ReplaceErrorOperator(fn, ins) {
+ this.type = 'replaceError';
+ this.ins = ins;
+ this.out = NO;
+ this.fn = fn;
+ }
+ ReplaceErrorOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(this);
+ };
+ ReplaceErrorOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = NO;
+ };
+ ReplaceErrorOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._n(t);
+ };
+ ReplaceErrorOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ try {
+ this.ins._remove(this);
+ (this.ins = this.fn(err))._add(this);
+ }
+ catch (e) {
+ u._e(e);
+ }
+ };
+ ReplaceErrorOperator.prototype._c = function () {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._c();
+ };
+ return ReplaceErrorOperator;
+}());
+exports.ReplaceErrorOperator = ReplaceErrorOperator;
+var StartWithOperator = (function () {
+ function StartWithOperator(ins, val) {
+ this.type = 'startWith';
+ this.ins = ins;
+ this.out = NO;
+ this.val = val;
+ }
+ StartWithOperator.prototype._start = function (out) {
+ this.out = out;
+ this.out._n(this.val);
+ this.ins._add(out);
+ };
+ StartWithOperator.prototype._stop = function () {
+ this.ins._remove(this.out);
+ this.out = NO;
+ };
+ return StartWithOperator;
+}());
+exports.StartWithOperator = StartWithOperator;
+var TakeOperator = (function () {
+ function TakeOperator(max, ins) {
+ this.type = 'take';
+ this.ins = ins;
+ this.out = NO;
+ this.max = max;
+ this.taken = 0;
+ }
+ TakeOperator.prototype._start = function (out) {
+ this.out = out;
+ this.taken = 0;
+ this.ins._add(this);
+ };
+ TakeOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = NO;
+ };
+ TakeOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ if (this.taken++ < this.max - 1) {
+ u._n(t);
+ }
+ else {
+ u._n(t);
+ u._c();
+ }
+ };
+ TakeOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._e(err);
+ };
+ TakeOperator.prototype._c = function () {
+ var u = this.out;
+ if (u === NO)
+ return;
+ u._c();
+ };
+ return TakeOperator;
+}());
+exports.TakeOperator = TakeOperator;
+var Stream = (function () {
+ function Stream(producer) {
+ this._prod = producer || NO;
+ this._ils = [];
+ this._stopID = NO;
+ this._target = NO;
+ this._err = NO;
+ }
+ Stream.prototype._n = function (t) {
+ var a = this._ils;
+ var L = a.length;
+ if (L == 1)
+ a[0]._n(t);
+ else {
+ var b = copy(a);
+ for (var i = 0; i < L; i++)
+ b[i]._n(t);
+ }
+ };
+ Stream.prototype._e = function (err) {
+ if (this._err !== NO)
+ return;
+ this._err = err;
+ var a = this._ils;
+ var L = a.length;
+ if (L == 1)
+ a[0]._e(err);
+ else {
+ var b = copy(a);
+ for (var i = 0; i < L; i++)
+ b[i]._e(err);
+ }
+ this._x();
+ };
+ Stream.prototype._c = function () {
+ var a = this._ils;
+ var L = a.length;
+ if (L == 1)
+ a[0]._c();
+ else {
+ var b = copy(a);
+ for (var i = 0; i < L; i++)
+ b[i]._c();
+ }
+ this._x();
+ };
+ Stream.prototype._x = function () {
+ if (this._ils.length === 0)
+ return;
+ if (this._prod !== NO)
+ this._prod._stop();
+ this._err = NO;
+ this._ils = [];
+ };
+ Stream.prototype._stopNow = function () {
+ // WARNING: code that calls this method should
+ // first check if this._prod is valid (not `NO`)
+ this._prod._stop();
+ this._err = NO;
+ this._stopID = NO;
+ };
+ Stream.prototype._add = function (il) {
+ var ta = this._target;
+ if (ta !== NO)
+ return ta._add(il);
+ var a = this._ils;
+ a.push(il);
+ if (a.length === 1) {
+ if (this._stopID !== NO) {
+ clearTimeout(this._stopID);
+ this._stopID = NO;
+ }
+ var p = this._prod;
+ if (p !== NO)
+ p._start(this);
+ }
+ };
+ Stream.prototype._remove = function (il) {
+ var _this = this;
+ var ta = this._target;
+ if (ta !== NO)
+ return ta._remove(il);
+ var a = this._ils;
+ var i = a.indexOf(il);
+ if (i > -1) {
+ a.splice(i, 1);
+ if (this._prod !== NO && a.length <= 0) {
+ this._err = NO;
+ this._stopID = setTimeout(function () { return _this._stopNow(); });
+ }
+ else if (a.length === 1) {
+ this._pruneCycles();
+ }
+ }
+ };
+ // If all paths stemming from `this` stream eventually end at `this`
+ // stream, then we remove the single listener of `this` stream, to
+ // force it to end its execution and dispose resources. This method
+ // assumes as a precondition that this._ils has just one listener.
+ Stream.prototype._pruneCycles = function () {
+ if (this._hasNoSinks(this, [])) {
+ this._remove(this._ils[0]);
+ }
+ };
+ // Checks whether *there is no* path starting from `x` that leads to an end
+ // listener (sink) in the stream graph, following edges A->B where B is a
+ // listener of A. This means these paths constitute a cycle somehow. Is given
+ // a trace of all visited nodes so far.
+ Stream.prototype._hasNoSinks = function (x, trace) {
+ if (trace.indexOf(x) !== -1) {
+ return true;
+ }
+ else if (x.out === this) {
+ return true;
+ }
+ else if (x.out && x.out !== NO) {
+ return this._hasNoSinks(x.out, trace.concat(x));
+ }
+ else if (x._ils) {
+ for (var i = 0, N = x._ils.length; i < N; i++) {
+ if (!this._hasNoSinks(x._ils[i], trace.concat(x))) {
+ return false;
+ }
+ }
+ return true;
+ }
+ else {
+ return false;
+ }
+ };
+ Stream.prototype.ctor = function () {
+ return this instanceof MemoryStream ? MemoryStream : Stream;
+ };
+ /**
+ * Adds a Listener to the Stream.
+ *
+ * @param {Listener} listener
+ */
+ Stream.prototype.addListener = function (listener) {
+ if (typeof listener.next !== 'function'
+ || typeof listener.error !== 'function'
+ || typeof listener.complete !== 'function') {
+ throw new Error('stream.addListener() requires all three next, error, ' +
+ 'and complete functions.');
+ }
+ listener._n = listener.next;
+ listener._e = listener.error;
+ listener._c = listener.complete;
+ this._add(listener);
+ };
+ /**
+ * Removes a Listener from the Stream, assuming the Listener was added to it.
+ *
+ * @param {Listener} listener
+ */
+ Stream.prototype.removeListener = function (listener) {
+ this._remove(listener);
+ };
+ /**
+ * Creates a new Stream given a Producer.
+ *
+ * @factory true
+ * @param {Producer} producer An optional Producer that dictates how to
+ * start, generate events, and stop the Stream.
+ * @return {Stream}
+ */
+ Stream.create = function (producer) {
+ if (producer) {
+ if (typeof producer.start !== 'function'
+ || typeof producer.stop !== 'function') {
+ throw new Error('producer requires both start and stop functions');
+ }
+ internalizeProducer(producer); // mutates the input
+ }
+ return new Stream(producer);
+ };
+ /**
+ * Creates a new MemoryStream given a Producer.
+ *
+ * @factory true
+ * @param {Producer} producer An optional Producer that dictates how to
+ * start, generate events, and stop the Stream.
+ * @return {MemoryStream}
+ */
+ Stream.createWithMemory = function (producer) {
+ if (producer) {
+ internalizeProducer(producer); // mutates the input
+ }
+ return new MemoryStream(producer);
+ };
+ /**
+ * Creates a Stream that does nothing when started. It never emits any event.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * never
+ * -----------------------
+ * ```
+ *
+ * @factory true
+ * @return {Stream}
+ */
+ Stream.never = function () {
+ return new Stream({ _start: noop, _stop: noop });
+ };
+ /**
+ * Creates a Stream that immediately emits the "complete" notification when
+ * started, and that's it.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * empty
+ * -|
+ * ```
+ *
+ * @factory true
+ * @return {Stream}
+ */
+ Stream.empty = function () {
+ return new Stream({
+ _start: function (il) { il._c(); },
+ _stop: noop,
+ });
+ };
+ /**
+ * Creates a Stream that immediately emits an "error" notification with the
+ * value you passed as the `error` argument when the stream starts, and that's
+ * it.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * throw(X)
+ * -X
+ * ```
+ *
+ * @factory true
+ * @param error The error event to emit on the created stream.
+ * @return {Stream}
+ */
+ Stream.throw = function (error) {
+ return new Stream({
+ _start: function (il) { il._e(error); },
+ _stop: noop,
+ });
+ };
+ /**
+ * Creates a Stream that immediately emits the arguments that you give to
+ * *of*, then completes.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * of(1,2,3)
+ * 123|
+ * ```
+ *
+ * @factory true
+ * @param a The first value you want to emit as an event on the stream.
+ * @param b The second value you want to emit as an event on the stream. One
+ * or more of these values may be given as arguments.
+ * @return {Stream}
+ */
+ Stream.of = function () {
+ var items = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ items[_i - 0] = arguments[_i];
+ }
+ return Stream.fromArray(items);
+ };
+ /**
+ * Converts an array to a stream. The returned stream will emit synchronously
+ * all the items in the array, and then complete.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * fromArray([1,2,3])
+ * 123|
+ * ```
+ *
+ * @factory true
+ * @param {Array} array The array to be converted as a stream.
+ * @return {Stream}
+ */
+ Stream.fromArray = function (array) {
+ return new Stream(new FromArrayProducer(array));
+ };
+ /**
+ * Converts a promise to a stream. The returned stream will emit the resolved
+ * value of the promise, and then complete. However, if the promise is
+ * rejected, the stream will emit the corresponding error.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * fromPromise( ----42 )
+ * -----------------42|
+ * ```
+ *
+ * @factory true
+ * @param {Promise} promise The promise to be converted as a stream.
+ * @return {Stream}
+ */
+ Stream.fromPromise = function (promise) {
+ return new Stream(new FromPromiseProducer(promise));
+ };
+ /**
+ * Creates a stream that periodically emits incremental numbers, every
+ * `period` milliseconds.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * periodic(1000)
+ * ---0---1---2---3---4---...
+ * ```
+ *
+ * @factory true
+ * @param {number} period The interval in milliseconds to use as a rate of
+ * emission.
+ * @return {Stream}
+ */
+ Stream.periodic = function (period) {
+ return new Stream(new PeriodicProducer(period));
+ };
+ Stream.prototype._map = function (project) {
+ var p = this._prod;
+ var ctor = this.ctor();
+ if (p instanceof FilterOperator) {
+ return new ctor(new FilterMapOperator(p.passes, project, p.ins));
+ }
+ if (p instanceof FilterMapOperator) {
+ return new ctor(new FilterMapOperator(p.passes, compose2(project, p.project), p.ins));
+ }
+ if (p instanceof MapOperator) {
+ return new ctor(new MapOperator(compose2(project, p.project), p.ins));
+ }
+ return new ctor(new MapOperator(project, this));
+ };
+ /**
+ * Transforms each event from the input Stream through a `project` function,
+ * to get a Stream that emits those transformed events.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1---3--5-----7------
+ * map(i => i * 10)
+ * --10--30-50----70-----
+ * ```
+ *
+ * @param {Function} project A function of type `(t: T) => U` that takes event
+ * `t` of type `T` from the input Stream and produces an event of type `U`, to
+ * be emitted on the output Stream.
+ * @return {Stream}
+ */
+ Stream.prototype.map = function (project) {
+ return this._map(project);
+ };
+ /**
+ * It's like `map`, but transforms each input event to always the same
+ * constant value on the output Stream.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1---3--5-----7-----
+ * mapTo(10)
+ * --10--10-10----10----
+ * ```
+ *
+ * @param projectedValue A value to emit on the output Stream whenever the
+ * input Stream emits any value.
+ * @return {Stream}
+ */
+ Stream.prototype.mapTo = function (projectedValue) {
+ var s = this.map(function () { return projectedValue; });
+ var op = s._prod;
+ op.type = op.type.replace('map', 'mapTo');
+ return s;
+ };
+ /**
+ * Only allows events that pass the test given by the `passes` argument.
+ *
+ * Each event from the input stream is given to the `passes` function. If the
+ * function returns `true`, the event is forwarded to the output stream,
+ * otherwise it is ignored and not forwarded.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1---2--3-----4-----5---6--7-8--
+ * filter(i => i % 2 === 0)
+ * ------2--------4---------6----8--
+ * ```
+ *
+ * @param {Function} passes A function of type `(t: T) +> boolean` that takes
+ * an event from the input stream and checks if it passes, by returning a
+ * boolean.
+ * @return {Stream}
+ */
+ Stream.prototype.filter = function (passes) {
+ var p = this._prod;
+ if (p instanceof FilterOperator) {
+ return new Stream(new FilterOperator(and(p.passes, passes), p.ins));
+ }
+ return new Stream(new FilterOperator(passes, this));
+ };
+ /**
+ * Lets the first `amount` many events from the input stream pass to the
+ * output stream, then makes the output stream complete.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --a---b--c----d---e--
+ * take(3)
+ * --a---b--c|
+ * ```
+ *
+ * @param {number} amount How many events to allow from the input stream
+ * before completing the output stream.
+ * @return {Stream}
+ */
+ Stream.prototype.take = function (amount) {
+ return new (this.ctor())(new TakeOperator(amount, this));
+ };
+ /**
+ * Ignores the first `amount` many events from the input stream, and then
+ * after that starts forwarding events from the input stream to the output
+ * stream.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --a---b--c----d---e--
+ * drop(3)
+ * --------------d---e--
+ * ```
+ *
+ * @param {number} amount How many events to ignore from the input stream
+ * before forwarding all events from the input stream to the output stream.
+ * @return {Stream}
+ */
+ Stream.prototype.drop = function (amount) {
+ return new Stream(new DropOperator(amount, this));
+ };
+ /**
+ * When the input stream completes, the output stream will emit the last event
+ * emitted by the input stream, and then will also complete.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --a---b--c--d----|
+ * last()
+ * -----------------d|
+ * ```
+ *
+ * @return {Stream}
+ */
+ Stream.prototype.last = function () {
+ return new Stream(new LastOperator(this));
+ };
+ /**
+ * Prepends the given `initial` value to the sequence of events emitted by the
+ * input stream. The returned stream is a MemoryStream, which means it is
+ * already `remember()`'d.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * ---1---2-----3---
+ * startWith(0)
+ * 0--1---2-----3---
+ * ```
+ *
+ * @param initial The value or event to prepend.
+ * @return {MemoryStream}
+ */
+ Stream.prototype.startWith = function (initial) {
+ return new MemoryStream(new StartWithOperator(this, initial));
+ };
+ /**
+ * Uses another stream to determine when to complete the current stream.
+ *
+ * When the given `other` stream emits an event or completes, the output
+ * stream will complete. Before that happens, the output stream will behaves
+ * like the input stream.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * ---1---2-----3--4----5----6---
+ * endWhen( --------a--b--| )
+ * ---1---2-----3--4--|
+ * ```
+ *
+ * @param other Some other stream that is used to know when should the output
+ * stream of this operator complete.
+ * @return {Stream}
+ */
+ Stream.prototype.endWhen = function (other) {
+ return new (this.ctor())(new EndWhenOperator(other, this));
+ };
+ /**
+ * "Folds" the stream onto itself.
+ *
+ * Combines events from the past throughout
+ * the entire execution of the input stream, allowing you to accumulate them
+ * together. It's essentially like `Array.prototype.reduce`. The returned
+ * stream is a MemoryStream, which means it is already `remember()`'d.
+ *
+ * The output stream starts by emitting the `seed` which you give as argument.
+ * Then, when an event happens on the input stream, it is combined with that
+ * seed value through the `accumulate` function, and the output value is
+ * emitted on the output stream. `fold` remembers that output value as `acc`
+ * ("accumulator"), and then when a new input event `t` happens, `acc` will be
+ * combined with that to produce the new `acc` and so forth.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * ------1-----1--2----1----1------
+ * fold((acc, x) => acc + x, 3)
+ * 3-----4-----5--7----8----9------
+ * ```
+ *
+ * @param {Function} accumulate A function of type `(acc: R, t: T) => R` that
+ * takes the previous accumulated value `acc` and the incoming event from the
+ * input stream and produces the new accumulated value.
+ * @param seed The initial accumulated value, of type `R`.
+ * @return {MemoryStream}
+ */
+ Stream.prototype.fold = function (accumulate, seed) {
+ return new MemoryStream(new FoldOperator(accumulate, seed, this));
+ };
+ /**
+ * Replaces an error with another stream.
+ *
+ * When (and if) an error happens on the input stream, instead of forwarding
+ * that error to the output stream, *replaceError* will call the `replace`
+ * function which returns the stream that the output stream will replicate.
+ * And, in case that new stream also emits an error, `replace` will be called
+ * again to get another stream to start replicating.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1---2-----3--4-----X
+ * replaceError( () => --10--| )
+ * --1---2-----3--4--------10--|
+ * ```
+ *
+ * @param {Function} replace A function of type `(err) => Stream` that takes
+ * the error that occurred on the input stream or on the previous replacement
+ * stream and returns a new stream. The output stream will behave like the
+ * stream that this function returns.
+ * @return {Stream}
+ */
+ Stream.prototype.replaceError = function (replace) {
+ return new (this.ctor())(new ReplaceErrorOperator(replace, this));
+ };
+ /**
+ * Flattens a "stream of streams", handling only one nested stream at a time
+ * (no concurrency).
+ *
+ * If the input stream is a stream that emits streams, then this operator will
+ * return an output stream which is a flat stream: emits regular events. The
+ * flattening happens without concurrency. It works like this: when the input
+ * stream emits a nested stream, *flatten* will start imitating that nested
+ * one. However, as soon as the next nested stream is emitted on the input
+ * stream, *flatten* will forget the previous nested one it was imitating, and
+ * will start imitating the new nested one.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --+--------+---------------
+ * \ \
+ * \ ----1----2---3--
+ * --a--b----c----d--------
+ * flatten
+ * -----a--b------1----2---3--
+ * ```
+ *
+ * @return {Stream}
+ */
+ Stream.prototype.flatten = function () {
+ var p = this._prod;
+ return new Stream(p instanceof MapOperator && !(p instanceof FilterMapOperator) ?
+ new MapFlattenOperator(p) :
+ new FlattenOperator(this));
+ };
+ /**
+ * Passes the input stream to a custom operator, to produce an output stream.
+ *
+ * *compose* is a handy way of using an existing function in a chained style.
+ * Instead of writing `outStream = f(inStream)` you can write
+ * `outStream = inStream.compose(f)`.
+ *
+ * @param {function} operator A function that takes a stream as input and
+ * returns a stream as well.
+ * @return {Stream}
+ */
+ Stream.prototype.compose = function (operator) {
+ return operator(this);
+ };
+ /**
+ * Returns an output stream that behaves like the input stream, but also
+ * remembers the most recent event that happens on the input stream, so that a
+ * newly added listener will immediately receive that memorised event.
+ *
+ * @return {MemoryStream}
+ */
+ Stream.prototype.remember = function () {
+ return new MemoryStream(new RememberOperator(this));
+ };
+ /**
+ * Returns an output stream that identically behaves like the input stream,
+ * but also runs a `spy` function fo each event, to help you debug your app.
+ *
+ * *debug* takes a `spy` function as argument, and runs that for each event
+ * happening on the input stream. If you don't provide the `spy` argument,
+ * then *debug* will just `console.log` each event. This helps you to
+ * understand the flow of events through some operator chain.
+ *
+ * Please note that if the output stream has no listeners, then it will not
+ * start, which means `spy` will never run because no actual event happens in
+ * that case.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1----2-----3-----4--
+ * debug
+ * --1----2-----3-----4--
+ * ```
+ *
+ * @param {function} labelOrSpy A string to use as the label when printing
+ * debug information on the console, or a 'spy' function that takes an event
+ * as argument, and does not need to return anything.
+ * @return {Stream}
+ */
+ Stream.prototype.debug = function (labelOrSpy) {
+ return new (this.ctor())(new DebugOperator(labelOrSpy, this));
+ };
+ /**
+ * *imitate* changes this current Stream to emit the same events that the
+ * `other` given Stream does. This method returns nothing.
+ *
+ * This method exists to allow one thing: **circular dependency of streams**.
+ * For instance, let's imagine that for some reason you need to create a
+ * circular dependency where stream `first$` depends on stream `second$`
+ * which in turn depends on `first$`:
+ *
+ *
+ * ```js
+ * import delay from 'xstream/extra/delay'
+ *
+ * var first$ = second$.map(x => x * 10).take(3);
+ * var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100));
+ * ```
+ *
+ * However, that is invalid JavaScript, because `second$` is undefined
+ * on the first line. This is how *imitate* can help solve it:
+ *
+ * ```js
+ * import delay from 'xstream/extra/delay'
+ *
+ * var secondProxy$ = xs.create();
+ * var first$ = secondProxy$.map(x => x * 10).take(3);
+ * var second$ = first$.map(x => x + 1).startWith(1).compose(delay(100));
+ * secondProxy$.imitate(second$);
+ * ```
+ *
+ * We create `secondProxy$` before the others, so it can be used in the
+ * declaration of `first$`. Then, after both `first$` and `second$` are
+ * defined, we hook `secondProxy$` with `second$` with `imitate()` to tell
+ * that they are "the same". `imitate` will not trigger the start of any
+ * stream, it just binds `secondProxy$` and `second$` together.
+ *
+ * The following is an example where `imitate()` is important in Cycle.js
+ * applications. A parent component contains some child components. A child
+ * has an action stream which is given to the parent to define its state:
+ *
+ *
+ * ```js
+ * const childActionProxy$ = xs.create();
+ * const parent = Parent({...sources, childAction$: childActionProxy$});
+ * const childAction$ = parent.state$.map(s => s.child.action$).flatten();
+ * childActionProxy$.imitate(childAction$);
+ * ```
+ *
+ * Note, though, that **`imitate()` does not support MemoryStreams**. If we
+ * would attempt to imitate a MemoryStream in a circular dependency, we would
+ * either get a race condition (where the symptom would be "nothing happens")
+ * or an infinite cyclic emission of values. It's useful to think about
+ * MemoryStreams as cells in a spreadsheet. It doesn't make any sense to
+ * define a spreadsheet cell `A1` with a formula that depends on `B1` and
+ * cell `B1` defined with a formula that depends on `A1`.
+ *
+ * If you find yourself wanting to use `imitate()` with a
+ * MemoryStream, you should rework your code around `imitate()` to use a
+ * Stream instead. Look for the stream in the circular dependency that
+ * represents an event stream, and that would be a candidate for creating a
+ * proxy Stream which then imitates the target Stream.
+ *
+ * @param {Stream} target The other stream to imitate on the current one. Must
+ * not be a MemoryStream.
+ */
+ Stream.prototype.imitate = function (target) {
+ if (target instanceof MemoryStream) {
+ throw new Error('A MemoryStream was given to imitate(), but it only ' +
+ 'supports a Stream. Read more about this restriction here: ' +
+ 'https://github.com/staltz/xstream#faq');
+ }
+ this._target = target;
+ for (var ils = this._ils, N = ils.length, i = 0; i < N; i++) {
+ target._add(ils[i]);
+ }
+ this._ils = [];
+ };
+ /**
+ * Forces the Stream to emit the given value to its listeners.
+ *
+ * As the name indicates, if you use this, you are most likely doing something
+ * The Wrong Way. Please try to understand the reactive way before using this
+ * method. Use it only when you know what you are doing.
+ *
+ * @param value The "next" value you want to broadcast to all listeners of
+ * this Stream.
+ */
+ Stream.prototype.shamefullySendNext = function (value) {
+ this._n(value);
+ };
+ /**
+ * Forces the Stream to emit the given error to its listeners.
+ *
+ * As the name indicates, if you use this, you are most likely doing something
+ * The Wrong Way. Please try to understand the reactive way before using this
+ * method. Use it only when you know what you are doing.
+ *
+ * @param {any} error The error you want to broadcast to all the listeners of
+ * this Stream.
+ */
+ Stream.prototype.shamefullySendError = function (error) {
+ this._e(error);
+ };
+ /**
+ * Forces the Stream to emit the "completed" event to its listeners.
+ *
+ * As the name indicates, if you use this, you are most likely doing something
+ * The Wrong Way. Please try to understand the reactive way before using this
+ * method. Use it only when you know what you are doing.
+ */
+ Stream.prototype.shamefullySendComplete = function () {
+ this._c();
+ };
+ /**
+ * Blends multiple streams together, emitting events from all of them
+ * concurrently.
+ *
+ * *merge* takes multiple streams as arguments, and creates a stream that
+ * behaves like each of the argument streams, in parallel.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1----2-----3--------4---
+ * ----a-----b----c---d------
+ * merge
+ * --1-a--2--b--3-c---d--4---
+ * ```
+ *
+ * @factory true
+ * @param {Stream} stream1 A stream to merge together with other streams.
+ * @param {Stream} stream2 A stream to merge together with other streams. Two
+ * or more streams may be given as arguments.
+ * @return {Stream}
+ */
+ Stream.merge = function merge() {
+ var streams = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ streams[_i - 0] = arguments[_i];
+ }
+ return new Stream(new MergeProducer(streams));
+ };
+ /**
+ * Combines multiple input streams together to return a stream whose events
+ * are arrays that collect the latest events from each input stream.
+ *
+ * *combine* internally remembers the most recent event from each of the input
+ * streams. When any of the input streams emits an event, that event together
+ * with all the other saved events are combined into an array. That array will
+ * be emitted on the output stream. It's essentially a way of joining together
+ * the events from multiple streams.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1----2-----3--------4---
+ * ----a-----b-----c--d------
+ * combine
+ * ----1a-2a-2b-3b-3c-3d-4d--
+ * ```
+ *
+ * @factory true
+ * @param {Stream} stream1 A stream to combine together with other streams.
+ * @param {Stream} stream2 A stream to combine together with other streams.
+ * Multiple streams, not just two, may be given as arguments.
+ * @return {Stream}
+ */
+ Stream.combine = function combine() {
+ var streams = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ streams[_i - 0] = arguments[_i];
+ }
+ return new Stream(new CombineProducer(streams));
+ };
+ return Stream;
+}());
+exports.Stream = Stream;
+var MemoryStream = (function (_super) {
+ __extends(MemoryStream, _super);
+ function MemoryStream(producer) {
+ _super.call(this, producer);
+ this._has = false;
+ }
+ MemoryStream.prototype._n = function (x) {
+ this._v = x;
+ this._has = true;
+ _super.prototype._n.call(this, x);
+ };
+ MemoryStream.prototype._add = function (il) {
+ if (this._has) {
+ il._n(this._v);
+ }
+ _super.prototype._add.call(this, il);
+ };
+ MemoryStream.prototype._stopNow = function () {
+ this._has = false;
+ _super.prototype._stopNow.call(this);
+ };
+ MemoryStream.prototype._x = function () {
+ this._has = false;
+ _super.prototype._x.call(this);
+ };
+ MemoryStream.prototype.map = function (project) {
+ return this._map(project);
+ };
+ MemoryStream.prototype.mapTo = function (projectedValue) {
+ return _super.prototype.mapTo.call(this, projectedValue);
+ };
+ MemoryStream.prototype.take = function (amount) {
+ return _super.prototype.take.call(this, amount);
+ };
+ MemoryStream.prototype.endWhen = function (other) {
+ return _super.prototype.endWhen.call(this, other);
+ };
+ MemoryStream.prototype.replaceError = function (replace) {
+ return _super.prototype.replaceError.call(this, replace);
+ };
+ MemoryStream.prototype.remember = function () {
+ return this;
+ };
+ MemoryStream.prototype.debug = function (labelOrSpy) {
+ return _super.prototype.debug.call(this, labelOrSpy);
+ };
+ return MemoryStream;
+}(Stream));
+exports.MemoryStream = MemoryStream;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = Stream;
+
+},{}],112:[function(require,module,exports){
+"use strict";
+var core_1 = require('../core');
+var ConcatProducer = (function () {
+ function ConcatProducer(streams) {
+ this.streams = streams;
+ this.type = 'concat';
+ this.out = null;
+ this.i = 0;
+ }
+ ConcatProducer.prototype._start = function (out) {
+ this.out = out;
+ this.streams[this.i]._add(this);
+ };
+ ConcatProducer.prototype._stop = function () {
+ var streams = this.streams;
+ if (this.i < streams.length) {
+ streams[this.i]._remove(this);
+ }
+ this.i = 0;
+ this.out = null;
+ };
+ ConcatProducer.prototype._n = function (t) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._n(t);
+ };
+ ConcatProducer.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._e(err);
+ };
+ ConcatProducer.prototype._c = function () {
+ var u = this.out;
+ if (!u)
+ return;
+ var streams = this.streams;
+ streams[this.i]._remove(this);
+ if (++this.i < streams.length) {
+ streams[this.i]._add(this);
+ }
+ else {
+ u._c();
+ }
+ };
+ return ConcatProducer;
+}());
+/**
+ * Puts one stream after the other. *concat* is a factory that takes multiple
+ * streams as arguments, and starts the `n+1`-th stream only when the `n`-th
+ * stream has completed. It concatenates those streams together.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1--2---3---4-|
+ * ...............--a-b-c--d-|
+ * concat
+ * --1--2---3---4---a-b-c--d-|
+ * ```
+ *
+ * Example:
+ *
+ * ```js
+ * import concat from 'xstream/extra/concat'
+ *
+ * const streamA = xs.of('a', 'b', 'c')
+ * const streamB = xs.of(10, 20, 30)
+ * const streamC = xs.of('X', 'Y', 'Z')
+ *
+ * const outputStream = concat(streamA, streamB, streamC)
+ *
+ * outputStream.addListener({
+ * next: (x) => console.log(x),
+ * error: (err) => console.error(err),
+ * complete: () => console.log('concat completed'),
+ * })
+ * ```
+ *
+ * @factory true
+ * @param {Stream} stream1 A stream to concatenate together with other streams.
+ * @param {Stream} stream2 A stream to concatenate together with other streams. Two
+ * or more streams may be given as arguments.
+ * @return {Stream}
+ */
+function concat() {
+ var streams = [];
+ for (var _i = 0; _i < arguments.length; _i++) {
+ streams[_i - 0] = arguments[_i];
+ }
+ return new core_1.Stream(new ConcatProducer(streams));
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = concat;
+
+},{"../core":111}],113:[function(require,module,exports){
+"use strict";
+var core_1 = require('../core');
+var DelayOperator = (function () {
+ function DelayOperator(dt, ins) {
+ this.dt = dt;
+ this.ins = ins;
+ this.type = 'delay';
+ this.out = null;
+ }
+ DelayOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(this);
+ };
+ DelayOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = null;
+ };
+ DelayOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (!u)
+ return;
+ var id = setInterval(function () {
+ u._n(t);
+ clearInterval(id);
+ }, this.dt);
+ };
+ DelayOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ var id = setInterval(function () {
+ u._e(err);
+ clearInterval(id);
+ }, this.dt);
+ };
+ DelayOperator.prototype._c = function () {
+ var u = this.out;
+ if (!u)
+ return;
+ var id = setInterval(function () {
+ u._c();
+ clearInterval(id);
+ }, this.dt);
+ };
+ return DelayOperator;
+}());
+/**
+ * Delays periodic events by a given time period.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * 1----2--3--4----5|
+ * delay(60)
+ * ---1----2--3--4----5|
+ * ```
+ *
+ * Example:
+ *
+ * ```js
+ * import fromDiagram from 'xstream/extra/fromDiagram'
+ * import delay from 'xstream/extra/delay'
+ *
+ * const stream = fromDiagram('1----2--3--4----5|')
+ * .compose(delay(60))
+ *
+ * stream.addListener({
+ * next: i => console.log(i),
+ * error: err => console.error(err),
+ * complete: () => console.log('completed')
+ * })
+ * ```
+ *
+ * ```text
+ * > 1 (after 60 ms)
+ * > 2 (after 160 ms)
+ * > 3 (after 220 ms)
+ * > 4 (after 280 ms)
+ * > 5 (after 380 ms)
+ * > completed
+ * ```
+ *
+ * @param {number} period The amount of silence required in milliseconds.
+ * @return {Stream}
+ */
+function delay(period) {
+ return function delayOperator(ins) {
+ return new core_1.Stream(new DelayOperator(period, ins));
+ };
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = delay;
+
+},{"../core":111}],114:[function(require,module,exports){
+"use strict";
+var core_1 = require('../core');
+var empty = {};
+var DropRepeatsOperator = (function () {
+ function DropRepeatsOperator(fn, ins) {
+ this.fn = fn;
+ this.ins = ins;
+ this.type = 'dropRepeats';
+ this.out = null;
+ this.v = empty;
+ }
+ DropRepeatsOperator.prototype._start = function (out) {
+ this.out = out;
+ this.ins._add(this);
+ };
+ DropRepeatsOperator.prototype._stop = function () {
+ this.ins._remove(this);
+ this.out = null;
+ this.v = empty;
+ };
+ DropRepeatsOperator.prototype.isEq = function (x, y) {
+ return this.fn ? this.fn(x, y) : x === y;
+ };
+ DropRepeatsOperator.prototype._n = function (t) {
+ var u = this.out;
+ if (!u)
+ return;
+ var v = this.v;
+ if (v === empty || !this.isEq(t, v)) {
+ u._n(t);
+ }
+ this.v = t;
+ };
+ DropRepeatsOperator.prototype._e = function (err) {
+ var u = this.out;
+ if (!u)
+ return;
+ u._e(err);
+ };
+ DropRepeatsOperator.prototype._c = function () {
+ var u = this.out;
+ if (!u)
+ return;
+ u._c();
+ };
+ return DropRepeatsOperator;
+}());
+exports.DropRepeatsOperator = DropRepeatsOperator;
+/**
+ * Drops consecutive duplicate values in a stream.
+ *
+ * Marble diagram:
+ *
+ * ```text
+ * --1--2--1--1--1--2--3--4--3--3|
+ * dropRepeats
+ * --1--2--1--------2--3--4--3---|
+ * ```
+ *
+ * Example:
+ *
+ * ```js
+ * import dropRepeats from 'xstream/extra/dropRepeats'
+ *
+ * const stream = xs.of(1, 2, 1, 1, 1, 2, 3, 4, 3, 3)
+ * .compose(dropRepeats())
+ *
+ * stream.addListener({
+ * next: i => console.log(i),
+ * error: err => console.error(err),
+ * complete: () => console.log('completed')
+ * })
+ * ```
+ *
+ * ```text
+ * > 1
+ * > 2
+ * > 1
+ * > 2
+ * > 3
+ * > 4
+ * > 3
+ * > completed
+ * ```
+ *
+ * Example with a custom isEqual function:
+ *
+ * ```js
+ * import dropRepeats from 'xstream/extra/dropRepeats'
+ *
+ * const stream = xs.of('a', 'b', 'a', 'A', 'B', 'b')
+ * .compose(dropRepeats((x, y) => x.toLowerCase() === y.toLowerCase()))
+ *
+ * stream.addListener({
+ * next: i => console.log(i),
+ * error: err => console.error(err),
+ * complete: () => console.log('completed')
+ * })
+ * ```
+ *
+ * ```text
+ * > a
+ * > b
+ * > a
+ * > B
+ * > completed
+ * ```
+ *
+ * @param {Function} isEqual An optional function of type
+ * `(x: T, y: T) => boolean` that takes an event from the input stream and
+ * checks if it is equal to previous event, by returning a boolean.
+ * @return {Stream}
+ */
+function dropRepeats(isEqual) {
+ if (isEqual === void 0) { isEqual = null; }
+ return function dropRepeatsOperator(ins) {
+ return new core_1.Stream(new DropRepeatsOperator(isEqual, ins));
+ };
+}
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = dropRepeats;
+
+},{"../core":111}],115:[function(require,module,exports){
+"use strict";
+var core_1 = require('./core');
+exports.Stream = core_1.Stream;
+exports.MemoryStream = core_1.MemoryStream;
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.default = core_1.Stream;
+
+},{"./core":111}],116:[function(require,module,exports){
+'use strict';
+
+var _xstreamRun = require('@cycle/xstream-run');
+
+var _dom = require('@cycle/dom');
+
+var _history = require('@cycle/history');
+
+var _history2 = require('history');
+
+var _storage = require('@cycle/storage');
+
+var _storage2 = _interopRequireDefault(_storage);
+
+var _index = require('./components/TaskList/index');
+
+var _index2 = _interopRequireDefault(_index);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var main = _index2.default;
+
+// THE ENTRY POINT
+// This is where the whole story starts.
+// `run` receives a main function and an object
+// with the drivers.
+
+// THE MAIN FUNCTION
+// This is the todo list component.
+(0, _xstreamRun.run)(main, {
+ // THE DOM DRIVER
+ // `makeDOMDriver(container)` from Cycle DOM returns a
+ // driver function to interact with the DOM.
+ DOM: (0, _dom.makeDOMDriver)('.todoapp', { transposition: true }),
+ // THE HISTORY DRIVER
+ // A driver to interact with browser history
+ History: (0, _history.makeHistoryDriver)((0, _history2.createHistory)(), { capture: true }),
+ // THE STORAGE DRIVER
+ // The storage driver which can be used to access values for
+ // local- and sessionStorage keys as streams.
+ storage: _storage2.default
+});
+
+},{"./components/TaskList/index":121,"@cycle/dom":11,"@cycle/history":70,"@cycle/storage":75,"@cycle/xstream-run":83,"history":100}],117:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _intent = require('./intent');
+
+var _intent2 = _interopRequireDefault(_intent);
+
+var _model = require('./model');
+
+var _model2 = _interopRequireDefault(_model);
+
+var _view = require('./view');
+
+var _view2 = _interopRequireDefault(_view);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+// THE TODO ITEM FUNCTION
+// This is a simple todo item component,
+// structured with the MVI-pattern.
+function Task(sources) {
+ var action$ = (0, _intent2.default)(sources);
+ var state$ = (0, _model2.default)(sources.props$, action$);
+ var vtree$ = (0, _view2.default)(state$);
+
+ return {
+ DOM: vtree$,
+ action$: action$,
+ state$: state$
+ };
+}
+
+exports.default = Task;
+
+},{"./intent":118,"./model":119,"./view":120}],118:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var _xstream = require('xstream');
+
+var _xstream2 = _interopRequireDefault(_xstream);
+
+var _utils = require('../../utils');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+// THE TODO ITEM INTENT
+// This intent function returns a stream of all the different,
+// actions that can be taken on a todo.
+function intent(sources) {
+ // THE INTENT MERGE
+ // Merge all actions into one stream.
+ return _xstream2.default.merge(
+ // THE DESTROY ACTION STREAM
+ sources.DOM.select('.destroy').events('click').mapTo({ type: 'destroy' }),
+
+ // THE TOGGLE ACTION STREAM
+ sources.DOM.select('.toggle').events('change').map(function (ev) {
+ return ev.target.checked;
+ }).map(function (payload) {
+ return { type: 'toggle', payload: payload };
+ }), sources.action$.filter(function (action) {
+ return action.type === 'toggleAll';
+ }).map(function (action) {
+ return _extends({}, action, { type: 'toggle' });
+ }),
+
+ // THE START EDIT ACTION STREAM
+ sources.DOM.select('label').events('dblclick').mapTo({ type: 'startEdit' }),
+
+ // THE ESC KEY ACTION STREAM
+ sources.DOM.select('.edit').events('keyup').filter(function (ev) {
+ return ev.keyCode === _utils.ESC_KEY;
+ }).mapTo({ type: 'cancelEdit' }),
+
+ // THE ENTER KEY ACTION STREAM
+ sources.DOM.select('.edit').events('keyup').filter(function (ev) {
+ return ev.keyCode === _utils.ENTER_KEY;
+ }).compose(function (s) {
+ return _xstream2.default.merge(s, sources.DOM.select('.edit').events('blur', true));
+ }).map(function (ev) {
+ return { title: ev.target.value, type: 'doneEdit' };
+ }));
+}
+
+exports.default = intent;
+
+},{"../../utils":127,"xstream":115}],119:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var _xstream = require('xstream');
+
+var _xstream2 = _interopRequireDefault(_xstream);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function makeReducer$(action$) {
+ var startEditReducer$ = action$.filter(function (action) {
+ return action.type === 'startEdit';
+ }).mapTo(function startEditReducer(data) {
+ return _extends({}, data, {
+ editing: true
+ });
+ });
+
+ var doneEditReducer$ = action$.filter(function (action) {
+ return action.type === 'doneEdit';
+ }).map(function (action) {
+ return function doneEditReducer(data) {
+ return _extends({}, data, {
+ title: action.payload,
+ editing: false
+ });
+ };
+ });
+
+ var cancelEditReducer$ = action$.filter(function (action) {
+ return action.type === 'cancelEdit';
+ }).mapTo(function cancelEditReducer(data) {
+ return _extends({}, data, {
+ editing: false
+ });
+ });
+
+ var toggleReducer$ = action$.filter(function (action) {
+ return action.type === 'toggle';
+ }).map(function (action) {
+ return function toggleReducer(data) {
+ return _extends({}, data, {
+ completed: action.payload
+ });
+ };
+ });
+
+ return _xstream2.default.merge(startEditReducer$, doneEditReducer$, cancelEditReducer$, toggleReducer$);
+}
+
+function model(props$, action$) {
+ // THE SANITIZED PROPERTIES
+ // If the list item has no data set it as empty and not completed.
+ var sanitizedProps$ = props$.startWith({ title: '', completed: false });
+ var reducer$ = makeReducer$(action$);
+
+ return sanitizedProps$.map(function (props) {
+ return reducer$.fold(function (data, reducer) {
+ return reducer(data);
+ }, props);
+ }).flatten().remember();
+}
+
+exports.default = model;
+
+},{"xstream":115}],120:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _dom = require('@cycle/dom');
+
+function view(state$) {
+ return state$.map(function (_ref) {
+ var title = _ref.title;
+ var completed = _ref.completed;
+ var editing = _ref.editing;
+
+ var todoRootClasses = {
+ completed: completed,
+ editing: editing
+ };
+
+ return (0, _dom.li)('.todoRoot', { class: todoRootClasses }, [(0, _dom.div)('.view', [(0, _dom.input)('.toggle', {
+ props: { type: 'checkbox', checked: completed }
+ }), (0, _dom.label)(title), (0, _dom.button)('.destroy')]), (0, _dom.input)('.edit', {
+ props: { type: 'text' },
+ hook: {
+ update: function update(oldVNode, _ref2) {
+ var elm = _ref2.elm;
+
+ elm.value = title;
+ if (editing) {
+ elm.focus();
+ elm.selectionStart = elm.value.length;
+ }
+ }
+ }
+ })]);
+ });
+}
+
+exports.default = view;
+
+},{"@cycle/dom":11}],121:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
+
+var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }();
+
+var _xstream = require('xstream');
+
+var _xstream2 = _interopRequireDefault(_xstream);
+
+var _isolate = require('@cycle/isolate');
+
+var _isolate2 = _interopRequireDefault(_isolate);
+
+var _intent = require('./intent');
+
+var _intent2 = _interopRequireDefault(_intent);
+
+var _model = require('./model');
+
+var _model2 = _interopRequireDefault(_model);
+
+var _view = require('./view');
+
+var _view2 = _interopRequireDefault(_view);
+
+var _storageSource = require('./storage-source');
+
+var _storageSource2 = _interopRequireDefault(_storageSource);
+
+var _storageSink = require('./storage-sink');
+
+var _storageSink2 = _interopRequireDefault(_storageSink);
+
+var _index = require('../Task/index');
+
+var _index2 = _interopRequireDefault(_index);
+
+var _collection = require('@cycle/collection');
+
+var _collection2 = _interopRequireDefault(_collection);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+// THE TASKLIST COMPONENT
+// This is the TaskList component which is being exported below.
+function TaskList(sources) {
+ // THE LOCALSTORAGE STREAM
+ // Here we create a localStorage stream that only streams
+ // the first value read from localStorage in order to
+ // supply the application with initial state.
+ var localStorage$ = sources.storage.local.getItem('todos-cycle').take(1);
+ // THE INITIAL TODO DATA
+ // The `deserialize` function takes the serialized JSON stored in localStorage
+ // and turns it into a stream sending a JSON object.
+ var sourceTodosData$ = (0, _storageSource2.default)(localStorage$);
+ // THE INTENT (MVI PATTERN)
+ // Pass relevant sources to the intent function, which set up
+ // streams that model the users actions.
+ var action$ = (0, _intent2.default)(sources.DOM, sources.History);
+ // THE MODEL (MVI PATTERN)
+ // Actions get passed to the model function which transforms the data
+ // coming through and prepares the data for the view.
+ var state$ = (0, _model2.default)(action$, sourceTodosData$);
+ // THE ITEM ADDITION STREAM
+ // Emits objects of sources specific to each item.
+ // Merges stored items with new items
+ var add$ = _xstream2.default.merge(sourceTodosData$.map(function (data) {
+ return data.list.map(function (props) {
+ return { props$: _xstream2.default.of(props) };
+ });
+ }), action$.filter(function (action) {
+ return action.type === 'insertTodo';
+ }).map(function (action) {
+ return {
+ props$: _xstream2.default.of({
+ title: action.payload,
+ completed: false
+ })
+ };
+ }));
+ // THE ITEM REMOVAL SELECTOR FUNCTION
+ // This function takes item's sinks and returns a stream representing
+ // its removal. Merges internal removals and `deleteCompleteds` actions
+ function removeSelector(itemSinks) {
+ var deleteCompleteds$ = action$.filter(function (action) {
+ return action.type === 'deleteCompleteds';
+ });
+ return _xstream2.default.merge(
+ // Consider deleteCompleteds$ only if the task is completed.
+ // analogue of rx pausable
+ itemSinks.state$.map(function (state) {
+ return deleteCompleteds$.filter(function () {
+ return state.completed;
+ });
+ }).flatten(), itemSinks.action$.filter(function (action) {
+ return action.type === 'destroy';
+ }));
+ }
+ // THE COLLECTION STREAM
+ // Collection function takes a component function, a common sources object,
+ // a stream of item additions, and a selector function from item sinks to
+ // a stream of removals
+ var list$ = (0, _collection2.default)(_index2.default, {
+ DOM: sources.DOM,
+ action$: action$.filter(function (action) {
+ return action.type === 'toggleAll';
+ })
+ }, add$, removeSelector);
+ // THE COMBINED CHILDREN VTREE AND STATE STREAMS
+ var todoVtrees$ = _collection2.default.pluck(list$, function (itemSinks) {
+ return itemSinks.DOM;
+ });
+ var todoStates$ = _collection2.default.pluck(list$, function (itemSinks) {
+ return itemSinks.state$;
+ });
+
+ var amendedState$ = _xstream2.default.combine(state$, todoVtrees$, todoStates$).map(function (_ref) {
+ var _ref2 = _slicedToArray(_ref, 3);
+
+ var parentState = _ref2[0];
+ var todoVtrees = _ref2[1];
+ var todoStates = _ref2[2];
+ return _extends({}, parentState, {
+ list: todoStates.map(function (state, i) {
+ return _extends({}, state, {
+ todoItem: { DOM: todoVtrees[i] }
+ });
+ })
+ });
+ });
+ // THE VIEW (MVI PATTERN)
+ // We render state as markup for the DOM.
+ var vdom$ = (0, _view2.default)(amendedState$);
+ // WRITE TO LOCALSTORAGE
+ // The latest state is written to localStorage.
+ var storage$ = (0, _storageSink2.default)(amendedState$).map(function (state) {
+ return {
+ key: 'todos-cycle', value: state
+ };
+ });
+ // COMPLETE THE CYCLE
+ // Write the virtual dom stream to the DOM and write the
+ // storage stream to localStorage.
+ var sinks = {
+ DOM: vdom$,
+ storage: storage$
+ };
+ return sinks;
+}
+
+exports.default = TaskList;
+
+},{"../Task/index":117,"./intent":122,"./model":123,"./storage-sink":124,"./storage-source":125,"./view":126,"@cycle/collection":1,"@cycle/isolate":74,"xstream":115}],122:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = intent;
+
+var _xstream = require('xstream');
+
+var _xstream2 = _interopRequireDefault(_xstream);
+
+var _dropRepeats = require('xstream/extra/dropRepeats');
+
+var _dropRepeats2 = _interopRequireDefault(_dropRepeats);
+
+var _utils = require('../../utils');
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+// THE INTENT FOR THE LIST
+function intent(DOMSource, History) {
+ return _xstream2.default.merge(
+ // THE ROUTE STREAM
+ // A stream that provides the path whenever the route changes.
+ History.startWith({ pathname: '/' }).map(function (location) {
+ return location.pathname;
+ }).compose((0, _dropRepeats2.default)()).map(function (payload) {
+ return { type: 'changeRoute', payload: payload };
+ }),
+
+ // THE URL STREAM
+ // A stream of URL clicks in the app
+ DOMSource.select('a').events('click').map(function (event) {
+ return event.target.hash.replace('#', '');
+ }).map(function (payload) {
+ return { type: 'url', payload: payload };
+ }),
+
+ // CLEAR INPUT STREAM
+ // A stream of ESC key strokes in the `.new-todo` field.
+ DOMSource.select('.new-todo').events('keydown').filter(function (ev) {
+ return ev.keyCode === _utils.ESC_KEY;
+ }).map(function (payload) {
+ return { type: 'clearInput', payload: payload };
+ }),
+
+ // ENTER KEY STREAM
+ // A stream of ENTER key strokes in the `.new-todo` field.
+ DOMSource.select('.new-todo').events('keydown')
+ // Trim value and only let the data through when there
+ // is anything but whitespace in the field and the ENTER key was hit.
+ .filter(function (ev) {
+ var trimmedVal = String(ev.target.value).trim();
+ return ev.keyCode === _utils.ENTER_KEY && trimmedVal;
+ })
+ // Return the trimmed value.
+ .map(function (ev) {
+ return String(ev.target.value).trim();
+ }).map(function (payload) {
+ return { type: 'insertTodo', payload: payload };
+ }),
+
+ // TOGGLE ALL STREAM
+ // Create a stream out of the clicks on the `.toggle-all` button.
+ DOMSource.select('.toggle-all').events('click').map(function (ev) {
+ return ev.target.checked;
+ }).map(function (payload) {
+ return { type: 'toggleAll', payload: payload };
+ }),
+
+ // DELETE COMPLETED TODOS STREAM
+ // A stream of click events on the `.clear-completed` element.
+ DOMSource.select('.clear-completed').events('click').mapTo({ type: 'deleteCompleteds' }));
+};
+
+},{"../../utils":127,"xstream":115,"xstream/extra/dropRepeats":114}],123:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+
+var _xstream = require('xstream');
+
+var _xstream2 = _interopRequireDefault(_xstream);
+
+var _concat = require('xstream/extra/concat');
+
+var _concat2 = _interopRequireDefault(_concat);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+// A helper function that provides filter functions
+// depending on the route value.
+function getFilterFn(route) {
+ switch (route) {
+ case '/active':
+ return function (task) {
+ return task.completed === false;
+ };
+ case '/completed':
+ return function (task) {
+ return task.completed === true;
+ };
+ default:
+ return function () {
+ return true;
+ }; // allow anything
+ }
+}
+
+// MAKE REDUCER STREAM
+// A function that takes the actions on the todo list
+// and returns a stream of "reducers": functions that expect the current
+// todosData (the state) and return a new version of todosData.
+function makeReducer$(action$) {
+ var clearInputReducer$ = action$.filter(function (a) {
+ return a.type === 'clearInput';
+ }).mapTo(function clearInputReducer(todosData) {
+ return todosData;
+ });
+
+ var changeRouteReducer$ = action$.filter(function (a) {
+ return a.type === 'changeRoute';
+ }).map(function (a) {
+ return a.payload;
+ }).startWith('/').map(function (path) {
+ var filterFn = getFilterFn(path);
+ return function changeRouteReducer(todosData) {
+ todosData.filter = path.replace('/', '').trim();
+ todosData.filterFn = filterFn;
+ return todosData;
+ };
+ });
+
+ return _xstream2.default.merge(clearInputReducer$, changeRouteReducer$);
+}
+
+// THIS IS THE MODEL FUNCTION
+// It expects the actions coming in from the sources
+function model(action$, sourceTodosData$) {
+ // THE BUSINESS LOGIC
+ // Actions are passed to the `makeReducer$` function
+ // which creates a stream of reducer functions that needs
+ // to be applied on the todoData when an action happens.
+ var reducer$ = makeReducer$(action$);
+
+ // RETURN THE MODEL DATA
+ return sourceTodosData$.map(function (sourceTodosData) {
+ return reducer$.fold(function (todosData, reducer) {
+ return reducer(todosData);
+ }, sourceTodosData);
+ }).flatten()
+ // Make this remember its latest event, so late listeners
+ // will be updated with the latest state.
+ .remember();
+}
+
+exports.default = model;
+
+},{"xstream":115,"xstream/extra/concat":112}],124:[function(require,module,exports){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = serialize;
+// Turn the data object that contains
+// the todos into a string for localStorage.
+function serialize(todos$) {
+ return todos$.map(function (todosData) {
+ return JSON.stringify({
+ list: todosData.list.map(function (todoData) {
+ return {
+ title: todoData.title,
+ completed: todoData.completed
+ };
+ })
+ });
+ });
+};
+
+},{}],125:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = deserialize;
+function merge() {
+ var result = {};
+ for (var i = 0; i < arguments.length; i++) {
+ var object = arguments[i];
+ for (var key in object) {
+ if (object.hasOwnProperty(key)) {
+ result[key] = object[key];
+ }
+ }
+ }
+ return result;
+}
+
+var safeJSONParse = function safeJSONParse(str) {
+ return JSON.parse(str) || {};
+};
+
+var mergeWithDefaultTodosData = function mergeWithDefaultTodosData(todosData) {
+ return merge({
+ list: [],
+ filter: '',
+ filterFn: function filterFn() {
+ return true;
+ } }, todosData);
+};
+
+// Take localStorage todoData stream and transform into
+// a JavaScript object. Set default data.
+function deserialize(localStorageValue$) {
+ return localStorageValue$.map(safeJSONParse).map(mergeWithDefaultTodosData);
+};
+
+},{}],126:[function(require,module,exports){
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+exports.default = view;
+
+var _dom = require('@cycle/dom');
+
+function renderHeader() {
+ return (0, _dom.header)('.header', [(0, _dom.h1)('todos'), (0, _dom.input)('.new-todo', {
+ props: {
+ type: 'text',
+ placeholder: 'What needs to be done?',
+ autofocus: true,
+ name: 'newTodo'
+ },
+ hook: {
+ update: function update(oldVNode, _ref) {
+ var elm = _ref.elm;
+
+ elm.value = '';
+ }
+ }
+ })]);
+}
+
+function renderMainSection(todosData) {
+ var allCompleted = todosData.list.reduce(function (x, y) {
+ return x && y.completed;
+ }, true);
+ var sectionStyle = { 'display': todosData.list.length ? '' : 'none' };
+
+ return (0, _dom.section)('.main', { style: sectionStyle }, [(0, _dom.input)('.toggle-all', {
+ props: { type: 'checkbox', checked: allCompleted }
+ }), (0, _dom.ul)('.todo-list', todosData.list.filter(todosData.filterFn).map(function (data) {
+ return data.todoItem.DOM;
+ }))]);
+}
+
+function renderFilterButton(todosData, filterTag, path, label) {
+ return (0, _dom.li)([(0, _dom.a)({
+ props: { href: path },
+ class: { selected: todosData.filter === filterTag }
+ }, label)]);
+}
+
+function renderFooter(todosData) {
+ var amountCompleted = todosData.list.filter(function (todoData) {
+ return todoData.completed;
+ }).length;
+ var amountActive = todosData.list.length - amountCompleted;
+ var footerStyle = { 'display': todosData.list.length ? '' : 'none' };
+
+ return (0, _dom.footer)('.footer', { style: footerStyle }, [(0, _dom.span)('.todo-count', [(0, _dom.strong)(String(amountActive)), ' item' + (amountActive !== 1 ? 's' : '') + ' left']), (0, _dom.ul)('.filters', [renderFilterButton(todosData, '', '/', 'All'), renderFilterButton(todosData, 'active', '/active', 'Active'), renderFilterButton(todosData, 'completed', '/completed', 'Completed')]), amountCompleted > 0 ? (0, _dom.button)('.clear-completed', 'Clear completed (' + amountCompleted + ')') : null]);
+}
+
+// THE VIEW
+// This function expects the stream of todosData
+// from the model function and turns it into a
+// virtual DOM stream that is then ultimately returned into
+// the DOM sink in the index.js.
+function view(todos$) {
+ return todos$.map(function (todos) {
+ return (0, _dom.div)([renderHeader(), renderMainSection(todos), renderFooter(todos)]);
+ });
+};
+
+},{"@cycle/dom":11}],127:[function(require,module,exports){
+"use strict";
+
+Object.defineProperty(exports, "__esModule", {
+ value: true
+});
+var ENTER_KEY = 13;
+var ESC_KEY = 27;
+
+exports.ENTER_KEY = ENTER_KEY;
+exports.ESC_KEY = ESC_KEY;
+
+},{}]},{},[116])
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy93YXRjaGlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1wYWNrL19wcmVsdWRlLmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9jb2xsZWN0aW9uL2xpYi9jb2xsZWN0aW9uLmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbGliL0VsZW1lbnRGaW5kZXIuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9saWIvRXZlbnREZWxlZ2F0b3IuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9saWIvSFRNTFNvdXJjZS5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL2xpYi9NYWluRE9NU291cmNlLmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbGliL1Njb3BlQ2hlY2tlci5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL2xpYi9WTm9kZVdyYXBwZXIuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9saWIvZnJvbUV2ZW50LmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbGliL2h5cGVyc2NyaXB0LWhlbHBlcnMuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9saWIvaHlwZXJzY3JpcHQuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9saWIvaXNvbGF0ZS5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL2xpYi9pc29sYXRlTW9kdWxlLmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbGliL21ha2VET01Ecml2ZXIuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9saWIvbWFrZUhUTUxEcml2ZXIuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9saWIvbW9ja0RPTVNvdXJjZS5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL2xpYi9tb2R1bGVzLmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbGliL3RyYW5zcG9zaXRpb24uanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9saWIvdXRpbHMuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvQGN5Y2xlL3hzdHJlYW0tYWRhcHRlci9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvbWF0Y2hlcy1zZWxlY3Rvci9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS1zZWxlY3Rvci9saWIvY2xhc3NOYW1lRnJvbVZOb2RlLmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbm9kZV9tb2R1bGVzL3NuYWJiZG9tLXNlbGVjdG9yL2xpYi9zZWxlY3RvclBhcnNlci5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS1zZWxlY3Rvci9ub2RlX21vZHVsZXMvYnJvd3Nlci1zcGxpdC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS10by1odG1sL2xpYi9jb250YWluZXItZWxlbWVudHMuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvc25hYmJkb20tdG8taHRtbC9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvc25hYmJkb20tdG8taHRtbC9saWIvaW5pdC5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS10by1odG1sL2xpYi9tb2R1bGVzL2F0dHJpYnV0ZXMuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvc25hYmJkb20tdG8taHRtbC9saWIvbW9kdWxlcy9zdHlsZS5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS10by1odG1sL2xpYi9wYXJzZS1zZWxlY3Rvci5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS10by1odG1sL2xpYi92b2lkLWVsZW1lbnRzLmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbm9kZV9tb2R1bGVzL3NuYWJiZG9tLXRvLWh0bWwvbm9kZV9tb2R1bGVzL2xvZGFzaC5lc2NhcGUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvc25hYmJkb20tdG8taHRtbC9ub2RlX21vZHVsZXMvbG9kYXNoLmVzY2FwZS9ub2RlX21vZHVsZXMvbG9kYXNoLl9yb290L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbm9kZV9tb2R1bGVzL3NuYWJiZG9tLXRvLWh0bWwvbm9kZV9tb2R1bGVzL2xvZGFzaC5mb3Jvd24vaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvc25hYmJkb20tdG8taHRtbC9ub2RlX21vZHVsZXMvbG9kYXNoLmZvcm93bi9ub2RlX21vZHVsZXMvbG9kYXNoLl9iYXNlZm9yL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbm9kZV9tb2R1bGVzL3NuYWJiZG9tLXRvLWh0bWwvbm9kZV9tb2R1bGVzL2xvZGFzaC5mb3Jvd24vbm9kZV9tb2R1bGVzL2xvZGFzaC5fYmluZGNhbGxiYWNrL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbm9kZV9tb2R1bGVzL3NuYWJiZG9tLXRvLWh0bWwvbm9kZV9tb2R1bGVzL2xvZGFzaC5mb3Jvd24vbm9kZV9tb2R1bGVzL2xvZGFzaC5rZXlzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbm9kZV9tb2R1bGVzL3NuYWJiZG9tLXRvLWh0bWwvbm9kZV9tb2R1bGVzL2xvZGFzaC5mb3Jvd24vbm9kZV9tb2R1bGVzL2xvZGFzaC5rZXlzL25vZGVfbW9kdWxlcy9sb2Rhc2guX2dldG5hdGl2ZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS10by1odG1sL25vZGVfbW9kdWxlcy9sb2Rhc2guZm9yb3duL25vZGVfbW9kdWxlcy9sb2Rhc2gua2V5cy9ub2RlX21vZHVsZXMvbG9kYXNoLmlzYXJndW1lbnRzL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbm9kZV9tb2R1bGVzL3NuYWJiZG9tLXRvLWh0bWwvbm9kZV9tb2R1bGVzL2xvZGFzaC5mb3Jvd24vbm9kZV9tb2R1bGVzL2xvZGFzaC5rZXlzL25vZGVfbW9kdWxlcy9sb2Rhc2guaXNhcnJheS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS10by1odG1sL25vZGVfbW9kdWxlcy9sb2Rhc2gua2ViYWJjYXNlL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbm9kZV9tb2R1bGVzL3NuYWJiZG9tLXRvLWh0bWwvbm9kZV9tb2R1bGVzL2xvZGFzaC5rZWJhYmNhc2Uvbm9kZV9tb2R1bGVzL2xvZGFzaC5kZWJ1cnIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvc25hYmJkb20tdG8taHRtbC9ub2RlX21vZHVsZXMvbG9kYXNoLmtlYmFiY2FzZS9ub2RlX21vZHVsZXMvbG9kYXNoLmRlYnVyci9ub2RlX21vZHVsZXMvbG9kYXNoLl9yb290L2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbm9kZV9tb2R1bGVzL3NuYWJiZG9tLXRvLWh0bWwvbm9kZV9tb2R1bGVzL2xvZGFzaC5rZWJhYmNhc2Uvbm9kZV9tb2R1bGVzL2xvZGFzaC53b3Jkcy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS10by1odG1sL25vZGVfbW9kdWxlcy9sb2Rhc2gua2ViYWJjYXNlL25vZGVfbW9kdWxlcy9sb2Rhc2gud29yZHMvbm9kZV9tb2R1bGVzL2xvZGFzaC5fcm9vdC9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS10by1odG1sL25vZGVfbW9kdWxlcy9sb2Rhc2gudW5pb24vaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvc25hYmJkb20tdG8taHRtbC9ub2RlX21vZHVsZXMvbG9kYXNoLnVuaW9uL25vZGVfbW9kdWxlcy9sb2Rhc2guX2Jhc2VmbGF0dGVuL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbm9kZV9tb2R1bGVzL3NuYWJiZG9tLXRvLWh0bWwvbm9kZV9tb2R1bGVzL2xvZGFzaC51bmlvbi9ub2RlX21vZHVsZXMvbG9kYXNoLl9iYXNldW5pcS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS10by1odG1sL25vZGVfbW9kdWxlcy9sb2Rhc2gudW5pb24vbm9kZV9tb2R1bGVzL2xvZGFzaC5fYmFzZXVuaXEvbm9kZV9tb2R1bGVzL2xvZGFzaC5fYmFzZWluZGV4b2YvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvc25hYmJkb20tdG8taHRtbC9ub2RlX21vZHVsZXMvbG9kYXNoLnVuaW9uL25vZGVfbW9kdWxlcy9sb2Rhc2guX2Jhc2V1bmlxL25vZGVfbW9kdWxlcy9sb2Rhc2guX2NhY2hlaW5kZXhvZi9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS10by1odG1sL25vZGVfbW9kdWxlcy9sb2Rhc2gudW5pb24vbm9kZV9tb2R1bGVzL2xvZGFzaC5fYmFzZXVuaXEvbm9kZV9tb2R1bGVzL2xvZGFzaC5fY3JlYXRlY2FjaGUvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvc25hYmJkb20tdG8taHRtbC9ub2RlX21vZHVsZXMvbG9kYXNoLnVuaW9uL25vZGVfbW9kdWxlcy9sb2Rhc2gucmVzdHBhcmFtL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbm9kZV9tb2R1bGVzL3NuYWJiZG9tL2guanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvc25hYmJkb20vaHRtbGRvbWFwaS5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS9pcy5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS9tb2R1bGVzL2F0dHJpYnV0ZXMuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvc25hYmJkb20vbW9kdWxlcy9jbGFzcy5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS9tb2R1bGVzL2V2ZW50bGlzdGVuZXJzLmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbm9kZV9tb2R1bGVzL3NuYWJiZG9tL21vZHVsZXMvaGVyby5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvZG9tL25vZGVfbW9kdWxlcy9zbmFiYmRvbS9tb2R1bGVzL3Byb3BzLmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9kb20vbm9kZV9tb2R1bGVzL3NuYWJiZG9tL21vZHVsZXMvc3R5bGUuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvc25hYmJkb20vc25hYmJkb20uanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvc25hYmJkb20vdGh1bmsuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2RvbS9ub2RlX21vZHVsZXMvc25hYmJkb20vdm5vZGUuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2hpc3RvcnkvbGliL2NhcHR1cmVDbGlja3MuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL2hpc3RvcnkvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9oaXN0b3J5L2xpYi9tYWtlSGlzdG9yeURyaXZlci5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvaGlzdG9yeS9saWIvc2VydmVySGlzdG9yeS5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvaGlzdG9yeS9saWIvdXRpbC5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvaXNvbGF0ZS9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL3N0b3JhZ2UvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS9zdG9yYWdlL2xpYi9yZXNwb25zZUNvbGxlY3Rpb24uanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL3N0b3JhZ2UvbGliL3V0aWwuanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL3N0b3JhZ2UvbGliL3dyaXRlVG9TdG9yZS5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvc3RvcmFnZS9ub2RlX21vZHVsZXMvQGN5Y2xlL3hzdHJlYW0tYWRhcHRlci9saWIvaW5kZXguanMiLCJub2RlX21vZHVsZXMvQGN5Y2xlL3N0b3JhZ2Uvbm9kZV9tb2R1bGVzL3hzdHJlYW0vY29yZS5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvc3RvcmFnZS9ub2RlX21vZHVsZXMveHN0cmVhbS9leHRyYS9kcm9wUmVwZWF0cy5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUvc3RvcmFnZS9ub2RlX21vZHVsZXMveHN0cmVhbS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9AY3ljbGUveHN0cmVhbS1ydW4vbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL0BjeWNsZS94c3RyZWFtLXJ1bi9ub2RlX21vZHVsZXMvQGN5Y2xlL2Jhc2UvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2hpc3RvcnkvbGliL0FjdGlvbnMuanMiLCJub2RlX21vZHVsZXMvaGlzdG9yeS9saWIvQXN5bmNVdGlscy5qcyIsIm5vZGVfbW9kdWxlcy9oaXN0b3J5L2xpYi9Ccm93c2VyUHJvdG9jb2wuanMiLCJub2RlX21vZHVsZXMvaGlzdG9yeS9saWIvRE9NU3RhdGVTdG9yYWdlLmpzIiwibm9kZV9tb2R1bGVzL2hpc3RvcnkvbGliL0RPTVV0aWxzLmpzIiwibm9kZV9tb2R1bGVzL2hpc3RvcnkvbGliL0V4ZWN1dGlvbkVudmlyb25tZW50LmpzIiwibm9kZV9tb2R1bGVzL2hpc3RvcnkvbGliL0hhc2hQcm90b2NvbC5qcyIsIm5vZGVfbW9kdWxlcy9oaXN0b3J5L2xpYi9Mb2NhdGlvblV0aWxzLmpzIiwibm9kZV9tb2R1bGVzL2hpc3RvcnkvbGliL1BhdGhVdGlscy5qcyIsIm5vZGVfbW9kdWxlcy9oaXN0b3J5L2xpYi9SZWZyZXNoUHJvdG9jb2wuanMiLCJub2RlX21vZHVsZXMvaGlzdG9yeS9saWIvY3JlYXRlQnJvd3Nlckhpc3RvcnkuanMiLCJub2RlX21vZHVsZXMvaGlzdG9yeS9saWIvY3JlYXRlSGFzaEhpc3RvcnkuanMiLCJub2RlX21vZHVsZXMvaGlzdG9yeS9saWIvY3JlYXRlSGlzdG9yeS5qcyIsIm5vZGVfbW9kdWxlcy9oaXN0b3J5L2xpYi9jcmVhdGVNZW1vcnlIaXN0b3J5LmpzIiwibm9kZV9tb2R1bGVzL2hpc3RvcnkvbGliL2luZGV4LmpzIiwibm9kZV9tb2R1bGVzL2hpc3RvcnkvbGliL3J1blRyYW5zaXRpb25Ib29rLmpzIiwibm9kZV9tb2R1bGVzL2hpc3RvcnkvbGliL3VzZUJhc2VuYW1lLmpzIiwibm9kZV9tb2R1bGVzL2hpc3RvcnkvbGliL3VzZUJlZm9yZVVubG9hZC5qcyIsIm5vZGVfbW9kdWxlcy9oaXN0b3J5L2xpYi91c2VRdWVyaWVzLmpzIiwibm9kZV9tb2R1bGVzL2hpc3Rvcnkvbm9kZV9tb2R1bGVzL2ludmFyaWFudC9icm93c2VyLmpzIiwibm9kZV9tb2R1bGVzL2hpc3Rvcnkvbm9kZV9tb2R1bGVzL3F1ZXJ5LXN0cmluZy9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9oaXN0b3J5L25vZGVfbW9kdWxlcy9xdWVyeS1zdHJpbmcvbm9kZV9tb2R1bGVzL29iamVjdC1hc3NpZ24vaW5kZXguanMiLCJub2RlX21vZHVsZXMvaGlzdG9yeS9ub2RlX21vZHVsZXMvcXVlcnktc3RyaW5nL25vZGVfbW9kdWxlcy9zdHJpY3QtdXJpLWVuY29kZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9oaXN0b3J5L25vZGVfbW9kdWxlcy93YXJuaW5nL2Jyb3dzZXIuanMiLCJub2RlX21vZHVsZXMvd2F0Y2hpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIm5vZGVfbW9kdWxlcy94c3RyZWFtL2NvcmUuanMiLCJub2RlX21vZHVsZXMveHN0cmVhbS9leHRyYS9jb25jYXQuanMiLCJub2RlX21vZHVsZXMveHN0cmVhbS9leHRyYS9kZWxheS5qcyIsIm5vZGVfbW9kdWxlcy94c3RyZWFtL2V4dHJhL2Ryb3BSZXBlYXRzLmpzIiwibm9kZV9tb2R1bGVzL3hzdHJlYW0vaW5kZXguanMiLCJzcmMvYXBwLmpzIiwic3JjL2NvbXBvbmVudHMvVGFzay9pbmRleC5qcyIsInNyYy9jb21wb25lbnRzL1Rhc2svaW50ZW50LmpzIiwic3JjL2NvbXBvbmVudHMvVGFzay9tb2RlbC5qcyIsInNyYy9jb21wb25lbnRzL1Rhc2svdmlldy5qcyIsInNyYy9jb21wb25lbnRzL1Rhc2tMaXN0L2luZGV4LmpzIiwic3JjL2NvbXBvbmVudHMvVGFza0xpc3QvaW50ZW50LmpzIiwic3JjL2NvbXBvbmVudHMvVGFza0xpc3QvbW9kZWwuanMiLCJzcmMvY29tcG9uZW50cy9UYXNrTGlzdC9zdG9yYWdlLXNpbmsuanMiLCJzcmMvY29tcG9uZW50cy9UYXNrTGlzdC9zdG9yYWdlLXNvdXJjZS5qcyIsInNyYy9jb21wb25lbnRzL1Rhc2tMaXN0L3ZpZXcuanMiLCJzcmMvdXRpbHMuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyUUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTs7QUNIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN0NBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ3BMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMzREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNU9BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pRQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN2TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDM0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUN0TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDM0RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7Ozs7QUNuSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7O0FDM0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hKQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM1FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0VBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUMxR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3ZCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM1REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ2hGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7Ozs7QUN2SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7OztBQ25GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDMUdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7O0FDdENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUNoSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNuTEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQzNJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUM5R0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQy9FQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQzFIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7OztBQ25EQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuRkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ05BO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDNURBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlyREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQy9GQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7O0FDTkE7O0FBQ0E7O0FBQ0E7O0FBQ0E7O0FBQ0E7Ozs7QUFHQTs7Ozs7O0FBRUEsSUFBTSxzQkFBTjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFUQTtBQUNBO0FBU0EscUJBQUksSUFBSixFQUFVO0FBQ1I7QUFDQTtBQUNBO0FBQ0EsT0FBSyx3QkFBYyxVQUFkLEVBQTBCLEVBQUMsZUFBZSxJQUFoQixFQUExQixDQUpHO0FBS1I7QUFDQTtBQUNBLFdBQVMsZ0NBQWtCLDhCQUFsQixFQUFtQyxFQUFDLFNBQVMsSUFBVixFQUFuQyxDQVBEO0FBUVI7QUFDQTtBQUNBO0FBQ0E7QUFYUSxDQUFWOzs7Ozs7Ozs7QUNmQTs7OztBQUNBOzs7O0FBQ0E7Ozs7OztBQUVBO0FBQ0E7QUFDQTtBQUNBLFNBQVMsSUFBVCxDQUFjLE9BQWQsRUFBdUI7QUFDckIsTUFBSSxVQUFVLHNCQUFPLE9BQVAsQ0FBZDtBQUNBLE1BQUksU0FBUyxxQkFBTSxRQUFRLE1BQWQsRUFBc0IsT0FBdEIsQ0FBYjtBQUNBLE1BQUksU0FBUyxvQkFBSyxNQUFMLENBQWI7O0FBRUEsU0FBTztBQUNMLFNBQUssTUFEQTtBQUVMLG9CQUZLO0FBR0w7QUFISyxHQUFQO0FBS0Q7O2tCQUVjLEk7Ozs7Ozs7Ozs7O0FDbkJmOzs7O0FBQ0E7Ozs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLE1BQVQsQ0FBZ0IsT0FBaEIsRUFBeUI7QUFDdkI7QUFDQTtBQUNBLFNBQU8sa0JBQUcsS0FBSDtBQUNMO0FBQ0EsVUFBUSxHQUFSLENBQVksTUFBWixDQUFtQixVQUFuQixFQUErQixNQUEvQixDQUFzQyxPQUF0QyxFQUNHLEtBREgsQ0FDUyxFQUFDLE1BQU0sU0FBUCxFQURULENBRks7O0FBS0w7QUFDQSxVQUFRLEdBQVIsQ0FBWSxNQUFaLENBQW1CLFNBQW5CLEVBQThCLE1BQTlCLENBQXFDLFFBQXJDLEVBQ0csR0FESCxDQUNPO0FBQUEsV0FBTSxHQUFHLE1BQUgsQ0FBVSxPQUFoQjtBQUFBLEdBRFAsRUFFRyxHQUZILENBRU87QUFBQSxXQUFZLEVBQUMsTUFBTSxRQUFQLEVBQWlCLGdCQUFqQixFQUFaO0FBQUEsR0FGUCxDQU5LLEVBU0wsUUFBUSxPQUFSLENBQ0csTUFESCxDQUNVO0FBQUEsV0FBVSxPQUFPLElBQVAsS0FBZ0IsV0FBMUI7QUFBQSxHQURWLEVBRUcsR0FGSCxDQUVPO0FBQUEsd0JBQWUsTUFBZixJQUF1QixNQUFNLFFBQTdCO0FBQUEsR0FGUCxDQVRLOztBQWFMO0FBQ0EsVUFBUSxHQUFSLENBQVksTUFBWixDQUFtQixPQUFuQixFQUE0QixNQUE1QixDQUFtQyxVQUFuQyxFQUNHLEtBREgsQ0FDUyxFQUFDLE1BQU0sV0FBUCxFQURULENBZEs7O0FBaUJMO0FBQ0EsVUFBUSxHQUFSLENBQVksTUFBWixDQUFtQixPQUFuQixFQUE0QixNQUE1QixDQUFtQyxPQUFuQyxFQUNHLE1BREgsQ0FDVTtBQUFBLFdBQU0sR0FBRyxPQUFILG1CQUFOO0FBQUEsR0FEVixFQUVHLEtBRkgsQ0FFUyxFQUFDLE1BQU0sWUFBUCxFQUZULENBbEJLOztBQXNCTDtBQUNBLFVBQVEsR0FBUixDQUFZLE1BQVosQ0FBbUIsT0FBbkIsRUFBNEIsTUFBNUIsQ0FBbUMsT0FBbkMsRUFDRyxNQURILENBQ1U7QUFBQSxXQUFNLEdBQUcsT0FBSCxxQkFBTjtBQUFBLEdBRFYsRUFFRyxPQUZILENBRVc7QUFBQSxXQUFLLGtCQUFHLEtBQUgsQ0FBUyxDQUFULEVBQVksUUFBUSxHQUFSLENBQVksTUFBWixDQUFtQixPQUFuQixFQUE0QixNQUE1QixDQUFtQyxNQUFuQyxFQUEyQyxJQUEzQyxDQUFaLENBQUw7QUFBQSxHQUZYLEVBR0csR0FISCxDQUdPO0FBQUEsV0FBTyxFQUFDLE9BQU8sR0FBRyxNQUFILENBQVUsS0FBbEIsRUFBeUIsTUFBTSxVQUEvQixFQUFQO0FBQUEsR0FIUCxDQXZCSyxDQUFQO0FBNEJEOztrQkFFYyxNOzs7Ozs7Ozs7OztBQ3ZDZjs7Ozs7O0FBRUEsU0FBUyxZQUFULENBQXNCLE9BQXRCLEVBQStCO0FBQzdCLE1BQUksb0JBQW9CLFFBQ3JCLE1BRHFCLENBQ2Q7QUFBQSxXQUFVLE9BQU8sSUFBUCxLQUFnQixXQUExQjtBQUFBLEdBRGMsRUFFckIsS0FGcUIsQ0FFZixTQUFTLGdCQUFULENBQTBCLElBQTFCLEVBQWdDO0FBQ3JDLHdCQUNLLElBREw7QUFFRSxlQUFTO0FBRlg7QUFJRCxHQVBxQixDQUF4Qjs7QUFTQSxNQUFJLG1CQUFtQixRQUNwQixNQURvQixDQUNiO0FBQUEsV0FBVSxPQUFPLElBQVAsS0FBZ0IsVUFBMUI7QUFBQSxHQURhLEVBRXBCLEdBRm9CLENBRWhCO0FBQUEsV0FBVSxTQUFTLGVBQVQsQ0FBeUIsSUFBekIsRUFBK0I7QUFDNUMsMEJBQ0ssSUFETDtBQUVFLGVBQU8sT0FBTyxPQUZoQjtBQUdFLGlCQUFTO0FBSFg7QUFLRCxLQU5JO0FBQUEsR0FGZ0IsQ0FBdkI7O0FBVUEsTUFBSSxxQkFBcUIsUUFDdEIsTUFEc0IsQ0FDZjtBQUFBLFdBQVUsT0FBTyxJQUFQLEtBQWdCLFlBQTFCO0FBQUEsR0FEZSxFQUV0QixLQUZzQixDQUVoQixTQUFTLGlCQUFULENBQTJCLElBQTNCLEVBQWlDO0FBQ3RDLHdCQUNLLElBREw7QUFFRSxlQUFTO0FBRlg7QUFJRCxHQVBzQixDQUF6Qjs7QUFTQSxNQUFJLGlCQUFpQixRQUNsQixNQURrQixDQUNYO0FBQUEsV0FBVSxPQUFPLElBQVAsS0FBZ0IsUUFBMUI7QUFBQSxHQURXLEVBRWxCLEdBRmtCLENBRWQ7QUFBQSxXQUFVLFNBQVMsYUFBVCxDQUF1QixJQUF2QixFQUE2QjtBQUMxQywwQkFDSyxJQURMO0FBRUUsbUJBQVcsT0FBTztBQUZwQjtBQUlELEtBTEk7QUFBQSxHQUZjLENBQXJCOztBQVNBLFNBQU8sa0JBQUcsS0FBSCxDQUNMLGlCQURLLEVBRUwsZ0JBRkssRUFHTCxrQkFISyxFQUlMLGNBSkssQ0FBUDtBQU1EOztBQUVELFNBQVMsS0FBVCxDQUFlLE1BQWYsRUFBdUIsT0FBdkIsRUFBZ0M7QUFDOUI7QUFDQTtBQUNBLE1BQUksa0JBQWtCLE9BQU8sU0FBUCxDQUFpQixFQUFDLE9BQU8sRUFBUixFQUFZLFdBQVcsS0FBdkIsRUFBakIsQ0FBdEI7QUFDQSxNQUFJLFdBQVcsYUFBYSxPQUFiLENBQWY7O0FBRUEsU0FBTyxnQkFBZ0IsR0FBaEIsQ0FBb0I7QUFBQSxXQUN6QixTQUFTLElBQVQsQ0FBYyxVQUFDLElBQUQsRUFBTyxPQUFQO0FBQUEsYUFBbUIsUUFBUSxJQUFSLENBQW5CO0FBQUEsS0FBZCxFQUFnRCxLQUFoRCxDQUR5QjtBQUFBLEdBQXBCLEVBRUwsT0FGSyxHQUVLLFFBRkwsRUFBUDtBQUdEOztrQkFFYyxLOzs7Ozs7Ozs7QUMzRGY7O0FBRUEsU0FBUyxJQUFULENBQWMsTUFBZCxFQUFzQjtBQUNwQixTQUFPLE9BQU8sR0FBUCxDQUFXLGdCQUFpQztBQUFBLFFBQS9CLEtBQStCLFFBQS9CLEtBQStCO0FBQUEsUUFBeEIsU0FBd0IsUUFBeEIsU0FBd0I7QUFBQSxRQUFiLE9BQWEsUUFBYixPQUFhOztBQUNqRCxRQUFJLGtCQUFrQjtBQUNwQiwwQkFEb0I7QUFFcEI7QUFGb0IsS0FBdEI7O0FBS0EsV0FBTyxhQUFHLFdBQUgsRUFBZ0IsRUFBQyxPQUFPLGVBQVIsRUFBaEIsRUFBMEMsQ0FDL0MsY0FBSSxPQUFKLEVBQWEsQ0FDWCxnQkFBTSxTQUFOLEVBQWlCO0FBQ2YsYUFBTyxFQUFDLE1BQU0sVUFBUCxFQUFtQixTQUFTLFNBQTVCO0FBRFEsS0FBakIsQ0FEVyxFQUlYLGdCQUFNLEtBQU4sQ0FKVyxFQUtYLGlCQUFPLFVBQVAsQ0FMVyxDQUFiLENBRCtDLEVBUS9DLGdCQUFNLE9BQU4sRUFBZTtBQUNiLGFBQU8sRUFBQyxNQUFNLE1BQVAsRUFETTtBQUViLFlBQU07QUFDSixnQkFBUSxnQkFBQyxRQUFELFNBQXFCO0FBQUEsY0FBVCxHQUFTLFNBQVQsR0FBUzs7QUFDM0IsY0FBSSxLQUFKLEdBQVksS0FBWjtBQUNBLGNBQUksT0FBSixFQUFhO0FBQ1gsZ0JBQUksS0FBSjtBQUNBLGdCQUFJLGNBQUosR0FBcUIsSUFBSSxLQUFKLENBQVUsTUFBL0I7QUFDRDtBQUNGO0FBUEc7QUFGTyxLQUFmLENBUitDLENBQTFDLENBQVA7QUFxQkQsR0EzQk0sQ0FBUDtBQTRCRDs7a0JBRWMsSTs7Ozs7Ozs7Ozs7OztBQ2pDZjs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUNBOzs7O0FBQ0E7Ozs7OztBQUVBO0FBQ0E7QUFDQSxTQUFTLFFBQVQsQ0FBa0IsT0FBbEIsRUFBMkI7QUFDekI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFJLGdCQUFnQixRQUFRLE9BQVIsQ0FBZ0IsS0FBaEIsQ0FBc0IsT0FBdEIsQ0FBOEIsYUFBOUIsRUFBNkMsSUFBN0MsQ0FBa0QsQ0FBbEQsQ0FBcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFJLG1CQUFtQiw2QkFBWSxhQUFaLENBQXZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsTUFBSSxVQUFVLHNCQUFPLFFBQVEsR0FBZixFQUFvQixRQUFRLE9BQTVCLENBQWQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFJLFNBQVMscUJBQU0sT0FBTixFQUFlLGdCQUFmLENBQWI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxNQUFJLE9BQU8sa0JBQUcsS0FBSCxDQUNULGlCQUNHLEdBREgsQ0FDTztBQUFBLFdBQVEsS0FBSyxJQUFMLENBQVUsR0FBVixDQUFjO0FBQUEsYUFBVSxFQUFDLFFBQVEsa0JBQUcsRUFBSCxDQUFNLEtBQU4sQ0FBVCxFQUFWO0FBQUEsS0FBZCxDQUFSO0FBQUEsR0FEUCxDQURTLEVBR1QsUUFDRyxNQURILENBQ1U7QUFBQSxXQUFVLE9BQU8sSUFBUCxLQUFnQixZQUExQjtBQUFBLEdBRFYsRUFFRyxHQUZILENBRU87QUFBQSxXQUFXO0FBQ2QsY0FBUSxrQkFBRyxFQUFILENBQU07QUFDWixlQUFPLE9BQU8sT0FERjtBQUVaLG1CQUFXO0FBRkMsT0FBTjtBQURNLEtBQVg7QUFBQSxHQUZQLENBSFMsQ0FBWDtBQVlBO0FBQ0E7QUFDQTtBQUNBLFdBQVMsY0FBVCxDQUF3QixTQUF4QixFQUFtQztBQUNqQyxRQUFJLG9CQUFvQixRQUNyQixNQURxQixDQUNkO0FBQUEsYUFBVSxPQUFPLElBQVAsS0FBZ0Isa0JBQTFCO0FBQUEsS0FEYyxDQUF4QjtBQUVBLFdBQU8sa0JBQUcsS0FBSDtBQUNMO0FBQ0E7QUFDQSxjQUFVLE1BQVYsQ0FDRyxHQURILENBQ087QUFBQSxhQUFTLGtCQUFrQixNQUFsQixDQUF5QjtBQUFBLGVBQU0sTUFBTSxTQUFaO0FBQUEsT0FBekIsQ0FBVDtBQUFBLEtBRFAsRUFFRyxPQUZILEVBSEssRUFNTCxVQUFVLE9BQVYsQ0FDRyxNQURILENBQ1U7QUFBQSxhQUFVLE9BQU8sSUFBUCxLQUFnQixTQUExQjtBQUFBLEtBRFYsQ0FOSyxDQUFQO0FBU0Q7QUFDRDtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUksUUFBUSwyQ0FFVjtBQUNFLFNBQUssUUFBUSxHQURmO0FBRUUsYUFBUyxRQUNOLE1BRE0sQ0FDQztBQUFBLGFBQVUsT0FBTyxJQUFQLEtBQWdCLFdBQTFCO0FBQUEsS0FERDtBQUZYLEdBRlUsRUFPVixJQVBVLEVBUVYsY0FSVSxDQUFaO0FBVUE7QUFDQSxNQUFJLGNBQWMscUJBQVcsS0FBWCxDQUFpQixLQUFqQixFQUF3QjtBQUFBLFdBQWEsVUFBVSxHQUF2QjtBQUFBLEdBQXhCLENBQWxCO0FBQ0EsTUFBSSxjQUFjLHFCQUFXLEtBQVgsQ0FBaUIsS0FBakIsRUFBd0I7QUFBQSxXQUFhLFVBQVUsTUFBdkI7QUFBQSxHQUF4QixDQUFsQjs7QUFFQSxNQUFJLGdCQUFnQixrQkFBRyxPQUFILENBQVcsTUFBWCxFQUFtQixXQUFuQixFQUFnQyxXQUFoQyxFQUNqQixHQURpQixDQUNiO0FBQUE7O0FBQUEsUUFBRSxXQUFGO0FBQUEsUUFBZSxVQUFmO0FBQUEsUUFBMkIsVUFBM0I7QUFBQSx3QkFDQSxXQURBO0FBRUgsWUFBTSxXQUFXLEdBQVgsQ0FBZSxVQUFDLEtBQUQsRUFBUSxDQUFSO0FBQUEsNEJBQ2hCLEtBRGdCO0FBRW5CLG9CQUFVLEVBQUMsS0FBSyxXQUFXLENBQVgsQ0FBTjtBQUZTO0FBQUEsT0FBZjtBQUZIO0FBQUEsR0FEYSxDQUFwQjtBQVFBO0FBQ0E7QUFDQSxNQUFJLFFBQVEsb0JBQUssYUFBTCxDQUFaO0FBQ0E7QUFDQTtBQUNBLE1BQUksV0FBVywyQkFBVSxhQUFWLEVBQXlCLEdBQXpCLENBQTZCLFVBQUMsS0FBRDtBQUFBLFdBQVk7QUFDdEQsV0FBSyxhQURpRCxFQUNsQyxPQUFPO0FBRDJCLEtBQVo7QUFBQSxHQUE3QixDQUFmO0FBR0E7QUFDQTtBQUNBO0FBQ0EsTUFBSSxRQUFRO0FBQ1YsU0FBSyxLQURLO0FBRVYsYUFBUztBQUZDLEdBQVo7QUFJQSxTQUFPLEtBQVA7QUFDRDs7a0JBRWMsUTs7Ozs7Ozs7a0JDcEdTLE07O0FBTHhCOzs7O0FBQ0E7Ozs7QUFDQTs7OztBQUVBO0FBQ2UsU0FBUyxNQUFULENBQWdCLFNBQWhCLEVBQTJCLE9BQTNCLEVBQW9DO0FBQ2pELFNBQU8sa0JBQUcsS0FBSDtBQUNMO0FBQ0E7QUFDQSxVQUNHLFNBREgsQ0FDYSxFQUFDLFVBQVUsR0FBWCxFQURiLEVBRUcsR0FGSCxDQUVPO0FBQUEsV0FBWSxTQUFTLFFBQXJCO0FBQUEsR0FGUCxFQUdHLE9BSEgsQ0FHVyw0QkFIWCxFQUlHLEdBSkgsQ0FJTztBQUFBLFdBQVksRUFBQyxNQUFNLGFBQVAsRUFBc0IsZ0JBQXRCLEVBQVo7QUFBQSxHQUpQLENBSEs7O0FBU0w7QUFDQTtBQUNBLFlBQVUsTUFBVixDQUFpQixHQUFqQixFQUFzQixNQUF0QixDQUE2QixPQUE3QixFQUNHLEdBREgsQ0FDTztBQUFBLFdBQVUsTUFBTSxNQUFOLENBQWEsSUFBYixDQUFrQixPQUFsQixDQUEwQixHQUExQixFQUErQixFQUEvQixDQUFWO0FBQUEsR0FEUCxFQUVHLEdBRkgsQ0FFTztBQUFBLFdBQVksRUFBQyxNQUFNLEtBQVAsRUFBYyxnQkFBZCxFQUFaO0FBQUEsR0FGUCxDQVhLOztBQWVMO0FBQ0E7QUFDQSxZQUFVLE1BQVYsQ0FBaUIsV0FBakIsRUFBOEIsTUFBOUIsQ0FBcUMsU0FBckMsRUFDRyxNQURILENBQ1U7QUFBQSxXQUFNLEdBQUcsT0FBSCxtQkFBTjtBQUFBLEdBRFYsRUFFRyxHQUZILENBRU87QUFBQSxXQUFZLEVBQUMsTUFBTSxZQUFQLEVBQXFCLGdCQUFyQixFQUFaO0FBQUEsR0FGUCxDQWpCSzs7QUFxQkw7QUFDQTtBQUNBLFlBQVUsTUFBVixDQUFpQixXQUFqQixFQUE4QixNQUE5QixDQUFxQyxTQUFyQztBQUNFO0FBQ0E7QUFGRixHQUdHLE1BSEgsQ0FHVSxjQUFNO0FBQ1osUUFBSSxhQUFhLE9BQU8sR0FBRyxNQUFILENBQVUsS0FBakIsRUFBd0IsSUFBeEIsRUFBakI7QUFDQSxXQUFPLEdBQUcsT0FBSCx5QkFBNEIsVUFBbkM7QUFDRCxHQU5IO0FBT0U7QUFQRixHQVFHLEdBUkgsQ0FRTztBQUFBLFdBQU0sT0FBTyxHQUFHLE1BQUgsQ0FBVSxLQUFqQixFQUF3QixJQUF4QixFQUFOO0FBQUEsR0FSUCxFQVNHLEdBVEgsQ0FTTztBQUFBLFdBQVksRUFBQyxNQUFNLFlBQVAsRUFBcUIsZ0JBQXJCLEVBQVo7QUFBQSxHQVRQLENBdkJLOztBQWtDTDtBQUNBO0FBQ0EsWUFBVSxNQUFWLENBQWlCLGFBQWpCLEVBQWdDLE1BQWhDLENBQXVDLE9BQXZDLEVBQ0csR0FESCxDQUNPO0FBQUEsV0FBTSxHQUFHLE1BQUgsQ0FBVSxPQUFoQjtBQUFBLEdBRFAsRUFFRyxHQUZILENBRU87QUFBQSxXQUFZLEVBQUMsTUFBTSxXQUFQLEVBQW9CLGdCQUFwQixFQUFaO0FBQUEsR0FGUCxDQXBDSzs7QUF3Q0w7QUFDQTtBQUNBLFlBQVUsTUFBVixDQUFpQixrQkFBakIsRUFBcUMsTUFBckMsQ0FBNEMsT0FBNUMsRUFDRyxLQURILENBQ1MsRUFBQyxNQUFNLGtCQUFQLEVBRFQsQ0ExQ0ssQ0FBUDtBQTZDRDs7Ozs7Ozs7O0FDbkREOzs7O0FBQ0E7Ozs7OztBQUVBO0FBQ0E7QUFDQSxTQUFTLFdBQVQsQ0FBcUIsS0FBckIsRUFBNEI7QUFDMUIsVUFBUSxLQUFSO0FBQ0UsU0FBSyxTQUFMO0FBQWdCLGFBQVE7QUFBQSxlQUFRLEtBQUssU0FBTCxLQUFtQixLQUEzQjtBQUFBLE9BQVI7QUFDaEIsU0FBSyxZQUFMO0FBQW1CLGFBQVE7QUFBQSxlQUFRLEtBQUssU0FBTCxLQUFtQixJQUEzQjtBQUFBLE9BQVI7QUFDbkI7QUFBUyxhQUFPO0FBQUEsZUFBTSxJQUFOO0FBQUEsT0FBUCxDQUhYLENBRzhCO0FBSDlCO0FBS0Q7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLFlBQVQsQ0FBc0IsT0FBdEIsRUFBK0I7QUFDN0IsTUFBSSxxQkFBcUIsUUFDdEIsTUFEc0IsQ0FDZjtBQUFBLFdBQUssRUFBRSxJQUFGLEtBQVcsWUFBaEI7QUFBQSxHQURlLEVBRXRCLEtBRnNCLENBRWhCLFNBQVMsaUJBQVQsQ0FBMkIsU0FBM0IsRUFBc0M7QUFDM0MsV0FBTyxTQUFQO0FBQ0QsR0FKc0IsQ0FBekI7O0FBTUEsTUFBSSxzQkFBc0IsUUFDdkIsTUFEdUIsQ0FDaEI7QUFBQSxXQUFLLEVBQUUsSUFBRixLQUFXLGFBQWhCO0FBQUEsR0FEZ0IsRUFFdkIsR0FGdUIsQ0FFbkI7QUFBQSxXQUFLLEVBQUUsT0FBUDtBQUFBLEdBRm1CLEVBR3ZCLFNBSHVCLENBR2IsR0FIYSxFQUl2QixHQUp1QixDQUluQixnQkFBUTtBQUNYLFFBQUksV0FBVyxZQUFZLElBQVosQ0FBZjtBQUNBLFdBQU8sU0FBUyxrQkFBVCxDQUE0QixTQUE1QixFQUF1QztBQUM1QyxnQkFBVSxNQUFWLEdBQW1CLEtBQUssT0FBTCxDQUFhLEdBQWIsRUFBa0IsRUFBbEIsRUFBc0IsSUFBdEIsRUFBbkI7QUFDQSxnQkFBVSxRQUFWLEdBQXFCLFFBQXJCO0FBQ0EsYUFBTyxTQUFQO0FBQ0QsS0FKRDtBQUtELEdBWHVCLENBQTFCOztBQWFBLFNBQU8sa0JBQUcsS0FBSCxDQUNMLGtCQURLLEVBRUwsbUJBRkssQ0FBUDtBQUlEOztBQUVEO0FBQ0E7QUFDQSxTQUFTLEtBQVQsQ0FBZSxPQUFmLEVBQXdCLGdCQUF4QixFQUEwQztBQUN4QztBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQUksV0FBVyxhQUFhLE9BQWIsQ0FBZjs7QUFFQTtBQUNBLFNBQU8saUJBQWlCLEdBQWpCLENBQXFCO0FBQUEsV0FDMUIsU0FBUyxJQUFULENBQWMsVUFBQyxTQUFELEVBQVksT0FBWjtBQUFBLGFBQXdCLFFBQVEsU0FBUixDQUF4QjtBQUFBLEtBQWQsRUFBMEQsZUFBMUQsQ0FEMEI7QUFBQSxHQUFyQixFQUVMLE9BRks7QUFHUDtBQUNBO0FBSk8sR0FLTixRQUxNLEVBQVA7QUFNRDs7a0JBRWMsSzs7Ozs7Ozs7a0JDM0RTLFM7QUFGeEI7QUFDQTtBQUNlLFNBQVMsU0FBVCxDQUFtQixNQUFuQixFQUEyQjtBQUN4QyxTQUFPLE9BQU8sR0FBUCxDQUFXO0FBQUEsV0FBYSxLQUFLLFNBQUwsQ0FDN0I7QUFDRSxZQUFNLFVBQVUsSUFBVixDQUFlLEdBQWYsQ0FBbUI7QUFBQSxlQUN0QjtBQUNDLGlCQUFPLFNBQVMsS0FEakI7QUFFQyxxQkFBVyxTQUFTO0FBRnJCLFNBRHNCO0FBQUEsT0FBbkI7QUFEUixLQUQ2QixDQUFiO0FBQUEsR0FBWCxDQUFQO0FBVUQ7Ozs7Ozs7O2tCQ1l1QixXO0FBekJ4QixTQUFTLEtBQVQsR0FBaUI7QUFDZixNQUFJLFNBQVMsRUFBYjtBQUNBLE9BQUssSUFBSSxJQUFJLENBQWIsRUFBZ0IsSUFBSSxVQUFVLE1BQTlCLEVBQXNDLEdBQXRDLEVBQTJDO0FBQ3pDLFFBQUksU0FBUyxVQUFVLENBQVYsQ0FBYjtBQUNBLFNBQUssSUFBSSxHQUFULElBQWdCLE1BQWhCLEVBQXdCO0FBQ3RCLFVBQUksT0FBTyxjQUFQLENBQXNCLEdBQXRCLENBQUosRUFBZ0M7QUFDOUIsZUFBTyxHQUFQLElBQWMsT0FBTyxHQUFQLENBQWQ7QUFDRDtBQUNGO0FBQ0Y7QUFDRCxTQUFPLE1BQVA7QUFDRDs7QUFFRCxJQUFJLGdCQUFnQixTQUFoQixhQUFnQjtBQUFBLFNBQU8sS0FBSyxLQUFMLENBQVcsR0FBWCxLQUFtQixFQUExQjtBQUFBLENBQXBCOztBQUVBLElBQUksNEJBQTRCLFNBQTVCLHlCQUE0QixZQUFhO0FBQzNDLFNBQU8sTUFBTTtBQUNYLFVBQU0sRUFESztBQUVYLFlBQVEsRUFGRztBQUdYLGNBQVU7QUFBQSxhQUFNLElBQU47QUFBQSxLQUhDLEVBQU4sRUFJSixTQUpJLENBQVA7QUFLRCxDQU5EOztBQVFBO0FBQ0E7QUFDZSxTQUFTLFdBQVQsQ0FBcUIsa0JBQXJCLEVBQXlDO0FBQ3RELFNBQU8sbUJBQ0osR0FESSxDQUNBLGFBREEsRUFFSixHQUZJLENBRUEseUJBRkEsQ0FBUDtBQUdEOzs7Ozs7OztrQkM4Q3VCLEk7O0FBM0V4Qjs7QUFHQSxTQUFTLFlBQVQsR0FBd0I7QUFDdEIsU0FBTyxpQkFBTyxTQUFQLEVBQWtCLENBQ3ZCLGFBQUcsT0FBSCxDQUR1QixFQUV2QixnQkFBTSxXQUFOLEVBQW1CO0FBQ2pCLFdBQU87QUFDTCxZQUFNLE1BREQ7QUFFTCxtQkFBYSx3QkFGUjtBQUdMLGlCQUFXLElBSE47QUFJTCxZQUFNO0FBSkQsS0FEVTtBQU9qQixVQUFNO0FBQ0osY0FBUSxnQkFBQyxRQUFELFFBQXFCO0FBQUEsWUFBVCxHQUFTLFFBQVQsR0FBUzs7QUFDM0IsWUFBSSxLQUFKLEdBQVksRUFBWjtBQUNEO0FBSEc7QUFQVyxHQUFuQixDQUZ1QixDQUFsQixDQUFQO0FBZ0JEOztBQUVELFNBQVMsaUJBQVQsQ0FBMkIsU0FBM0IsRUFBc0M7QUFDcEMsTUFBSSxlQUFlLFVBQVUsSUFBVixDQUFlLE1BQWYsQ0FBc0IsVUFBQyxDQUFELEVBQUksQ0FBSjtBQUFBLFdBQVUsS0FBSyxFQUFFLFNBQWpCO0FBQUEsR0FBdEIsRUFBa0QsSUFBbEQsQ0FBbkI7QUFDQSxNQUFJLGVBQWUsRUFBQyxXQUFXLFVBQVUsSUFBVixDQUFlLE1BQWYsR0FBd0IsRUFBeEIsR0FBNkIsTUFBekMsRUFBbkI7O0FBRUEsU0FBTyxrQkFBUSxPQUFSLEVBQWlCLEVBQUMsT0FBTyxZQUFSLEVBQWpCLEVBQXdDLENBQzdDLGdCQUFNLGFBQU4sRUFBcUI7QUFDbkIsV0FBTyxFQUFDLE1BQU0sVUFBUCxFQUFtQixTQUFTLFlBQTVCO0FBRFksR0FBckIsQ0FENkMsRUFJN0MsYUFBRyxZQUFILEVBQWlCLFVBQVUsSUFBVixDQUNkLE1BRGMsQ0FDUCxVQUFVLFFBREgsRUFFZCxHQUZjLENBRVY7QUFBQSxXQUFRLEtBQUssUUFBTCxDQUFjLEdBQXRCO0FBQUEsR0FGVSxDQUFqQixDQUo2QyxDQUF4QyxDQUFQO0FBU0Q7O0FBRUQsU0FBUyxrQkFBVCxDQUE0QixTQUE1QixFQUF1QyxTQUF2QyxFQUFrRCxJQUFsRCxFQUF3RCxLQUF4RCxFQUErRDtBQUM3RCxTQUFPLGFBQUcsQ0FDUixZQUFFO0FBQ0EsV0FBTyxFQUFDLE1BQU0sSUFBUCxFQURQO0FBRUEsV0FBTyxFQUFDLFVBQVUsVUFBVSxNQUFWLEtBQXFCLFNBQWhDO0FBRlAsR0FBRixFQUdHLEtBSEgsQ0FEUSxDQUFILENBQVA7QUFNRDs7QUFFRCxTQUFTLFlBQVQsQ0FBc0IsU0FBdEIsRUFBaUM7QUFDL0IsTUFBSSxrQkFBa0IsVUFBVSxJQUFWLENBQ25CLE1BRG1CLENBQ1o7QUFBQSxXQUFZLFNBQVMsU0FBckI7QUFBQSxHQURZLEVBRW5CLE1BRkg7QUFHQSxNQUFJLGVBQWUsVUFBVSxJQUFWLENBQWUsTUFBZixHQUF3QixlQUEzQztBQUNBLE1BQUksY0FBYyxFQUFDLFdBQVcsVUFBVSxJQUFWLENBQWUsTUFBZixHQUF3QixFQUF4QixHQUE2QixNQUF6QyxFQUFsQjs7QUFFQSxTQUFPLGlCQUFPLFNBQVAsRUFBa0IsRUFBQyxPQUFPLFdBQVIsRUFBbEIsRUFBd0MsQ0FDN0MsZUFBSyxhQUFMLEVBQW9CLENBQ2xCLGlCQUFPLE9BQU8sWUFBUCxDQUFQLENBRGtCLEVBRWxCLFdBQVcsaUJBQWlCLENBQWpCLEdBQXFCLEdBQXJCLEdBQTJCLEVBQXRDLElBQTRDLE9BRjFCLENBQXBCLENBRDZDLEVBSzdDLGFBQUcsVUFBSCxFQUFlLENBQ2IsbUJBQW1CLFNBQW5CLEVBQThCLEVBQTlCLEVBQWtDLEdBQWxDLEVBQXVDLEtBQXZDLENBRGEsRUFFYixtQkFBbUIsU0FBbkIsRUFBOEIsUUFBOUIsRUFBd0MsU0FBeEMsRUFBbUQsUUFBbkQsQ0FGYSxFQUdiLG1CQUFtQixTQUFuQixFQUE4QixXQUE5QixFQUEyQyxZQUEzQyxFQUF5RCxXQUF6RCxDQUhhLENBQWYsQ0FMNkMsRUFVNUMsa0JBQWtCLENBQWxCLEdBQ0MsaUJBQU8sa0JBQVAsRUFBMkIsc0JBQXNCLGVBQXRCLEdBQXdDLEdBQW5FLENBREQsR0FFRyxJQVp5QyxDQUF4QyxDQUFQO0FBZUQ7O0FBRUQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNlLFNBQVMsSUFBVCxDQUFjLE1BQWQsRUFBc0I7QUFDbkMsU0FBTyxPQUFPLEdBQVAsQ0FBVztBQUFBLFdBQ2hCLGNBQUksQ0FDRixjQURFLEVBRUYsa0JBQWtCLEtBQWxCLENBRkUsRUFHRixhQUFhLEtBQWIsQ0FIRSxDQUFKLENBRGdCO0FBQUEsR0FBWCxDQUFQO0FBT0Q7Ozs7Ozs7O0FDbkZELElBQU0sWUFBWSxFQUFsQjtBQUNBLElBQU0sVUFBVSxFQUFoQjs7UUFFUSxTLEdBQUEsUztRQUFXLE8sR0FBQSxPIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3ZhciBmPW5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIik7dGhyb3cgZi5jb2RlPVwiTU9EVUxFX05PVF9GT1VORFwiLGZ9dmFyIGw9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGwuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sbCxsLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxudmFyIF94c3RyZWFtID0gcmVxdWlyZSgneHN0cmVhbScpO1xuXG52YXIgX3hzdHJlYW0yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfeHN0cmVhbSk7XG5cbnZhciBfZGVsYXkgPSByZXF1aXJlKCd4c3RyZWFtL2V4dHJhL2RlbGF5Jyk7XG5cbnZhciBfZGVsYXkyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZGVsYXkpO1xuXG52YXIgX2Ryb3BSZXBlYXRzID0gcmVxdWlyZSgneHN0cmVhbS9leHRyYS9kcm9wUmVwZWF0cycpO1xuXG52YXIgX2Ryb3BSZXBlYXRzMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2Ryb3BSZXBlYXRzKTtcblxudmFyIF9pc29sYXRlID0gcmVxdWlyZSgnQGN5Y2xlL2lzb2xhdGUnKTtcblxudmFyIF9pc29sYXRlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2lzb2xhdGUpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG5mdW5jdGlvbiBfZGVmaW5lUHJvcGVydHkob2JqLCBrZXksIHZhbHVlKSB7IGlmIChrZXkgaW4gb2JqKSB7IE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIGtleSwgeyB2YWx1ZTogdmFsdWUsIGVudW1lcmFibGU6IHRydWUsIGNvbmZpZ3VyYWJsZTogdHJ1ZSwgd3JpdGFibGU6IHRydWUgfSk7IH0gZWxzZSB7IG9ialtrZXldID0gdmFsdWU7IH0gcmV0dXJuIG9iajsgfVxuXG5mdW5jdGlvbiBfdG9Db25zdW1hYmxlQXJyYXkoYXJyKSB7IGlmIChBcnJheS5pc0FycmF5KGFycikpIHsgZm9yICh2YXIgaSA9IDAsIGFycjIgPSBBcnJheShhcnIubGVuZ3RoKTsgaSA8IGFyci5sZW5ndGg7IGkrKykgeyBhcnIyW2ldID0gYXJyW2ldOyB9IHJldHVybiBhcnIyOyB9IGVsc2UgeyByZXR1cm4gQXJyYXkuZnJvbShhcnIpOyB9IH1cblxudmFyIG5vb3AgPSBGdW5jdGlvbi5wcm90b3R5cGU7XG5cbmZ1bmN0aW9uIGlzVnRyZWUoeCkge1xuICByZXR1cm4geCAmJiB0eXBlb2YgeC5zZWwgPT09ICdzdHJpbmcnO1xufVxuXG52YXIgX2lkID0gMDtcblxuZnVuY3Rpb24gaWQoKSB7XG4gIHJldHVybiBfaWQrKztcbn1cblxuZnVuY3Rpb24gbWFrZUl0ZW0oY29tcG9uZW50LCBzb3VyY2VzKSB7XG4gIHZhciBuZXdJZCA9IGlkKCk7XG5cbiAgdmFyIG5ld0l0ZW0gPSAoMCwgX2lzb2xhdGUyLmRlZmF1bHQpKGNvbXBvbmVudCwgbmV3SWQudG9TdHJpbmcoKSkoc291cmNlcyk7XG5cbiAgbmV3SXRlbS5faWQgPSBuZXdJZDtcbiAgbmV3SXRlbS5fbmFtZSA9IGNvbXBvbmVudC5uYW1lO1xuXG4gIHJldHVybiBuZXdJdGVtO1xufVxuXG5mdW5jdGlvbiBjb2xsZWN0aW9uKG9wdGlvbnMpIHtcbiAgdmFyIGl0ZW1zID0gYXJndW1lbnRzLmxlbmd0aCA8PSAxIHx8IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8gW10gOiBhcmd1bWVudHNbMV07XG4gIHZhciBjb21wb25lbnQgPSBvcHRpb25zLmNvbXBvbmVudDtcbiAgdmFyIHNvdXJjZXMgPSBvcHRpb25zLnNvdXJjZXM7XG4gIHZhciByZW1vdmVTZWxlY3RvciA9IG9wdGlvbnMucmVtb3ZlU2VsZWN0b3I7XG5cblxuICByZXR1cm4ge1xuICAgIGFkZDogZnVuY3Rpb24gYWRkKCkge1xuICAgICAgdmFyIGFkZGl0aW9uYWxTb3VyY2VzID0gYXJndW1lbnRzLmxlbmd0aCA8PSAwIHx8IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8ge30gOiBhcmd1bWVudHNbMF07XG5cbiAgICAgIHZhciBuZXdJdGVtID0gbWFrZUl0ZW0oY29tcG9uZW50LCBfZXh0ZW5kcyh7fSwgc291cmNlcywgYWRkaXRpb25hbFNvdXJjZXMpKTtcbiAgICAgIHZhciByZW1vdmVTaW5rID0gcmVtb3ZlU2VsZWN0b3IobmV3SXRlbSkgfHwgX3hzdHJlYW0yLmRlZmF1bHQuZW1wdHkoKTtcbiAgICAgIG5ld0l0ZW0uX3JlbW92ZSQgPSByZW1vdmVTaW5rLnRha2UoMSkubWFwVG8obmV3SXRlbSk7XG5cbiAgICAgIHJldHVybiBjb2xsZWN0aW9uKG9wdGlvbnMsIFtdLmNvbmNhdChfdG9Db25zdW1hYmxlQXJyYXkoaXRlbXMpLCBbbmV3SXRlbV0pKTtcbiAgICB9LFxuICAgIHJlbW92ZTogZnVuY3Rpb24gcmVtb3ZlKGl0ZW1Gb3JSZW1vdmFsKSB7XG4gICAgICByZXR1cm4gY29sbGVjdGlvbihvcHRpb25zLCBpdGVtcy5maWx0ZXIoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgcmV0dXJuIGl0ZW0gIT09IGl0ZW1Gb3JSZW1vdmFsO1xuICAgICAgfSkpO1xuICAgIH0sXG4gICAgYXNBcnJheTogZnVuY3Rpb24gYXNBcnJheSgpIHtcbiAgICAgIHJldHVybiBpdGVtcy5zbGljZSgpOyAvLyByZXR1cm5zIGEgY29weSBvZiBpdGVtcyB0byBhdm9pZCBtdXRhdGlvblxuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gQ29sbGVjdGlvbihjb21wb25lbnQpIHtcbiAgdmFyIHNvdXJjZXMgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDEgfHwgYXJndW1lbnRzWzFdID09PSB1bmRlZmluZWQgPyB7fSA6IGFyZ3VtZW50c1sxXTtcbiAgdmFyIGFkZCQgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDIgfHwgYXJndW1lbnRzWzJdID09PSB1bmRlZmluZWQgPyBfeHN0cmVhbTIuZGVmYXVsdC5lbXB0eSgpIDogYXJndW1lbnRzWzJdO1xuICB2YXIgcmVtb3ZlU2VsZWN0b3IgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDMgfHwgYXJndW1lbnRzWzNdID09PSB1bmRlZmluZWQgPyBub29wIDogYXJndW1lbnRzWzNdO1xuXG4gIHZhciByZW1vdmVQcm94eSQgPSBfeHN0cmVhbTIuZGVmYXVsdC5jcmVhdGUoKTtcbiAgdmFyIGFkZFJlZHVjZXIkID0gYWRkJC5tYXAoZnVuY3Rpb24gKHNvdXJjZXNMaXN0KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChjb2xsZWN0aW9uKSB7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheShzb3VyY2VzTGlzdCkpIHtcbiAgICAgICAgLy8gbXVsdGlwbGUgaXRlbXNcbiAgICAgICAgcmV0dXJuIHNvdXJjZXNMaXN0LnJlZHVjZShmdW5jdGlvbiAoY29sbGVjdGlvbiwgc291cmNlcykge1xuICAgICAgICAgIHJldHVybiBjb2xsZWN0aW9uLmFkZChzb3VyY2VzKTtcbiAgICAgICAgfSwgY29sbGVjdGlvbik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBzaW5nbGUgaXRlbVxuICAgICAgICByZXR1cm4gY29sbGVjdGlvbi5hZGQoc291cmNlc0xpc3QpO1xuICAgICAgfVxuICAgIH07XG4gIH0pO1xuICB2YXIgcmVtb3ZlUmVkdWNlciQgPSByZW1vdmVQcm94eSQubWFwKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChjb2xsZWN0aW9uKSB7XG4gICAgICByZXR1cm4gY29sbGVjdGlvbi5yZW1vdmUoaXRlbSk7XG4gICAgfTtcbiAgfSk7XG4gIHZhciByZWR1Y2VyJCA9IF94c3RyZWFtMi5kZWZhdWx0Lm1lcmdlKGFkZFJlZHVjZXIkLCByZW1vdmVSZWR1Y2VyJCk7XG5cbiAgdmFyIGVtcHR5Q29sbGVjdGlvbiA9IGNvbGxlY3Rpb24oeyBjb21wb25lbnQ6IGNvbXBvbmVudCwgc291cmNlczogc291cmNlcywgcmVtb3ZlU2VsZWN0b3I6IHJlbW92ZVNlbGVjdG9yIH0pO1xuICB2YXIgY29sbGVjdGlvbiQgPSByZWR1Y2VyJC5mb2xkKGZ1bmN0aW9uIChjb2xsZWN0aW9uLCByZWR1Y2VyKSB7XG4gICAgcmV0dXJuIHJlZHVjZXIoY29sbGVjdGlvbik7XG4gIH0sIGVtcHR5Q29sbGVjdGlvbikubWFwKGZ1bmN0aW9uIChjb2xsZWN0aW9uKSB7XG4gICAgcmV0dXJuIGNvbGxlY3Rpb24uYXNBcnJheSgpO1xuICB9KTtcblxuICB2YXIgcmVtb3ZlJCA9IENvbGxlY3Rpb24ubWVyZ2UoY29sbGVjdGlvbiQsIGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgcmV0dXJuIGl0ZW0uX3JlbW92ZSQ7XG4gIH0pO1xuICByZW1vdmVQcm94eSQuaW1pdGF0ZShyZW1vdmUkKTtcblxuICByZXR1cm4gY29sbGVjdGlvbiQ7XG59XG5cbkNvbGxlY3Rpb24ucGx1Y2sgPSBmdW5jdGlvbiBwbHVjayhjb2xsZWN0aW9uJCwgcGx1Y2tTZWxlY3Rvcikge1xuICB2YXIgc2lua3MgPSB7fTtcblxuICBmdW5jdGlvbiBzaW5rJChpdGVtKSB7XG4gICAgdmFyIGtleSA9IGl0ZW0uX2lkO1xuXG4gICAgaWYgKHNpbmtzW2tleV0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgdmFyIHNpbmsgPSBwbHVja1NlbGVjdG9yKGl0ZW0pLm1hcChmdW5jdGlvbiAoeCkge1xuICAgICAgICByZXR1cm4gaXNWdHJlZSh4KSAmJiB4LmtleSA9PSBudWxsID8gX2V4dGVuZHMoe30sIHgsIHsga2V5OiBrZXkgfSkgOiB4O1xuICAgICAgfSk7XG4gICAgICBzaW5rc1trZXldID0gc2luay5yZW1lbWJlcigpO1xuICAgIH1cblxuICAgIHJldHVybiBzaW5rc1trZXldO1xuICB9XG5cbiAgcmV0dXJuIGNvbGxlY3Rpb24kLm1hcChmdW5jdGlvbiAoaXRlbXMpIHtcbiAgICByZXR1cm4gaXRlbXMubWFwKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICByZXR1cm4gc2luayQoaXRlbSk7XG4gICAgfSk7XG4gIH0pLm1hcChmdW5jdGlvbiAoc2lua1N0cmVhbXMpIHtcbiAgICByZXR1cm4gX3hzdHJlYW0yLmRlZmF1bHQuY29tYmluZS5hcHBseShfeHN0cmVhbTIuZGVmYXVsdCwgX3RvQ29uc3VtYWJsZUFycmF5KHNpbmtTdHJlYW1zKSk7XG4gIH0pLmZsYXR0ZW4oKS5zdGFydFdpdGgoW10pO1xufTtcblxuQ29sbGVjdGlvbi5tZXJnZSA9IGZ1bmN0aW9uIG1lcmdlKGNvbGxlY3Rpb24kLCBtZXJnZVNlbGVjdG9yKSB7XG4gIHZhciBzaW5rcyA9IHt9O1xuXG4gIGZ1bmN0aW9uIHNpbmskKGl0ZW0pIHtcbiAgICB2YXIga2V5ID0gaXRlbS5faWQ7XG5cbiAgICBpZiAoc2lua3Nba2V5XSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB2YXIgc2luayA9IG1lcmdlU2VsZWN0b3IoaXRlbSkubWFwKGZ1bmN0aW9uICh4KSB7XG4gICAgICAgIHJldHVybiBpc1Z0cmVlKHgpICYmIHgua2V5ID09IG51bGwgPyBfZXh0ZW5kcyh7fSwgeCwgeyBrZXk6IGtleSB9KSA6IHg7XG4gICAgICB9KTtcbiAgICAgIC8vIHByZXZlbnQgc2luayBmcm9tIGVhcmx5IGNvbXBsZXRpb24gYW5kIHJlaW5pdGlhbGl6YXRpb25cbiAgICAgIHNpbmtzW2tleV0gPSBfeHN0cmVhbTIuZGVmYXVsdC5tZXJnZShzaW5rLCBfeHN0cmVhbTIuZGVmYXVsdC5uZXZlcigpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gc2lua3Nba2V5XTtcbiAgfVxuXG4gIHJldHVybiBjb2xsZWN0aW9uJC5tYXAoZnVuY3Rpb24gKGl0ZW1zKSB7XG4gICAgcmV0dXJuIGl0ZW1zLm1hcChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgcmV0dXJuIHNpbmskKGl0ZW0pO1xuICAgIH0pO1xuICB9KS5tYXAoZnVuY3Rpb24gKHNpbmtTdHJlYW1zKSB7XG4gICAgcmV0dXJuIF94c3RyZWFtMi5kZWZhdWx0Lm1lcmdlLmFwcGx5KF94c3RyZWFtMi5kZWZhdWx0LCBfdG9Db25zdW1hYmxlQXJyYXkoc2lua1N0cmVhbXMpKTtcbiAgfSkuZmxhdHRlbigpO1xufTtcblxuLy8gY29udmVydCBhIHN0cmVhbSBvZiBpdGVtcycgc291cmNlcyBzbmFwc2hvdHMgaW50byBhIHN0cmVhbSBvZiBjb2xsZWN0aW9uc1xuQ29sbGVjdGlvbi5nYXRoZXIgPSBmdW5jdGlvbiBnYXRoZXIoY29tcG9uZW50LCBzb3VyY2VzLCBpdGVtcyQpIHtcbiAgdmFyIGlkQXR0cmlidXRlID0gYXJndW1lbnRzLmxlbmd0aCA8PSAzIHx8IGFyZ3VtZW50c1szXSA9PT0gdW5kZWZpbmVkID8gJ2lkJyA6IGFyZ3VtZW50c1szXTtcblxuICBmdW5jdGlvbiBtYWtlRGVzdHJveWFibGUoY29tcG9uZW50KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIChzb3VyY2VzKSB7XG4gICAgICByZXR1cm4gX2V4dGVuZHMoe30sIGNvbXBvbmVudChzb3VyY2VzKSwge1xuICAgICAgICBfZGVzdHJveSQ6IHNvdXJjZXMuX2Rlc3Ryb3kkXG4gICAgICB9KTtcbiAgICB9O1xuICB9XG5cbiAgLy8gZmluZHMgaXRlbXMgbm90IHByZXNlbnQgaW4gcHJldmlvdXMgc25hcHNob3RcbiAgZnVuY3Rpb24gZmluZE5ld0l0ZW1zKF9yZWYsIGl0ZW1zKSB7XG4gICAgdmFyIHByZXZJZHMgPSBfcmVmLnByZXZJZHM7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcHJldklkczogaXRlbXMubWFwKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgIHJldHVybiBpdGVtW2lkQXR0cmlidXRlXTtcbiAgICAgIH0pLFxuICAgICAgYWRkZWRJdGVtczogaXRlbXMuZmlsdGVyKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgIHJldHVybiBwcmV2SWRzLmluZGV4T2YoaXRlbVtpZEF0dHJpYnV0ZV0pID09PSAtMTtcbiAgICAgIH0pXG4gICAgfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNvbXBhcmVKU09OKHZhbHVlLCBuZXh0VmFsdWUpIHtcbiAgICBpZiAodmFsdWUgPT09IG5leHRWYWx1ZSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBpZiAoSlNPTi5zdHJpbmdpZnkodmFsdWUpID09PSBKU09OLnN0cmluZ2lmeShuZXh0VmFsdWUpKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgLy8gaWYgbm90IGVxdWFsIG9yIG5vdCBzZXJpYWxpemFibGVcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvLyB0dXJuIGEgbmV3IGl0ZW0gaW50byBhIGhhc2ggb2Ygc291cmNlIHN0cmVhbXMsIHRyYWNraW5nIGFsbCB0aGUgZnV0dXJlIHVwZGF0ZXNcbiAgZnVuY3Rpb24gaXRlbVRvU291cmNlU3RyZWFtcyhhZGRlZEl0ZW0sIGl0ZW1zU3RhdGUkKSB7XG4gICAgdmFyIGl0ZW1TdGF0ZUluZmluaXRlJCA9IGl0ZW1zU3RhdGUkLm1hcChmdW5jdGlvbiAoaXRlbXMpIHtcbiAgICAgIHJldHVybiBpdGVtcy5maW5kKGZ1bmN0aW9uIChpdGVtKSB7XG4gICAgICAgIHJldHVybiBpdGVtW2lkQXR0cmlidXRlXSA9PT0gYWRkZWRJdGVtW2lkQXR0cmlidXRlXTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIC8vIGlmIGFuIGl0ZW0gaXNuJ3QgcHJlc2VudCBpZiBhIG5ldyBzbmFwc2hvdCwgaXQgc2hhbGwgYmUgZGVzdHJveWVkXG4gICAgdmFyIF9kZXN0cm95JCA9IGl0ZW1TdGF0ZUluZmluaXRlJC5maWx0ZXIoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgIHJldHVybiAhaXRlbTtcbiAgICB9KS50YWtlKDEpO1xuICAgIHZhciBpdGVtU3RhdGUkID0gaXRlbVN0YXRlSW5maW5pdGUkLmVuZFdoZW4oX2Rlc3Ryb3kkLmNvbXBvc2UoKDAsIF9kZWxheTIuZGVmYXVsdCkoKSkpO1xuXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKGFkZGVkSXRlbSkucmVkdWNlKGZ1bmN0aW9uIChzb3VyY2VzLCBrZXkpIHtcbiAgICAgIC8vIHNraXAgaWRBdHRyaWJ1dGVcbiAgICAgIGlmIChrZXkgPT09IGlkQXR0cmlidXRlKSB7XG4gICAgICAgIHJldHVybiBzb3VyY2VzO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gX2V4dGVuZHMoe30sIHNvdXJjZXMsIF9kZWZpbmVQcm9wZXJ0eSh7fSwga2V5LCBpdGVtU3RhdGUkLm1hcChmdW5jdGlvbiAoc3RhdGUpIHtcbiAgICAgICAgcmV0dXJuIHN0YXRlW2tleV07XG4gICAgICB9KS5zdGFydFdpdGgoYWRkZWRJdGVtW2tleV0pXG4gICAgICAvLyBza2lwIHRoZSBzbmFwc2hvdCBpZiB0aGUgdmFsdWUgZGlkbid0IGNoYW5nZVxuICAgICAgLmNvbXBvc2UoKDAsIF9kcm9wUmVwZWF0czIuZGVmYXVsdCkoY29tcGFyZUpTT04pKS5yZW1lbWJlcigpKSk7XG4gICAgfSwge1xuICAgICAgX2Rlc3Ryb3kkOiBfZGVzdHJveSRcbiAgICB9KTtcbiAgfVxuXG4gIHZhciBpdGVtc1N0YXRlJCA9IGl0ZW1zJC5yZW1lbWJlcigpO1xuXG4gIHZhciBhZGQkID0gaXRlbXNTdGF0ZSRcbiAgLy8gZ2V0IHRoZSBhZGRlZCBpdGVtcyBhdCBlYWNoIHN0ZXBcbiAgLmZvbGQoZmluZE5ld0l0ZW1zLCB7IHByZXZJZHM6IFtdLCBhZGRlZEl0ZW1zOiBbXSB9KS5tYXAoZnVuY3Rpb24gKF9yZWYyKSB7XG4gICAgdmFyIGFkZGVkSXRlbXMgPSBfcmVmMi5hZGRlZEl0ZW1zO1xuICAgIHJldHVybiBhZGRlZEl0ZW1zO1xuICB9KS5maWx0ZXIoZnVuY3Rpb24gKGFkZGVkSXRlbXMpIHtcbiAgICByZXR1cm4gYWRkZWRJdGVtcy5sZW5ndGg7XG4gIH0pLm1hcChmdW5jdGlvbiAoYWRkZWRJdGVtcykge1xuICAgIHJldHVybiBhZGRlZEl0ZW1zLm1hcChmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgcmV0dXJuIGl0ZW1Ub1NvdXJjZVN0cmVhbXMoaXRlbSwgaXRlbXNTdGF0ZSQpO1xuICAgIH0pO1xuICB9KTtcblxuICByZXR1cm4gQ29sbGVjdGlvbihtYWtlRGVzdHJveWFibGUoY29tcG9uZW50KSwgc291cmNlcywgYWRkJCwgZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICByZXR1cm4gaXRlbS5fZGVzdHJveSQ7XG4gIH0pO1xufTtcblxuZXhwb3J0cy5kZWZhdWx0ID0gQ29sbGVjdGlvbjsiLCJcInVzZSBzdHJpY3RcIjtcbnZhciBTY29wZUNoZWNrZXJfMSA9IHJlcXVpcmUoJy4vU2NvcGVDaGVja2VyJyk7XG52YXIgdXRpbHNfMSA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBtYXRjaGVzU2VsZWN0b3I7XG50cnkge1xuICAgIG1hdGNoZXNTZWxlY3RvciA9IHJlcXVpcmUoXCJtYXRjaGVzLXNlbGVjdG9yXCIpO1xufVxuY2F0Y2ggKGUpIHtcbiAgICBtYXRjaGVzU2VsZWN0b3IgPSBGdW5jdGlvbi5wcm90b3R5cGU7XG59XG5mdW5jdGlvbiB0b0VsQXJyYXkoaW5wdXQpIHtcbiAgICByZXR1cm4gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoaW5wdXQpO1xufVxudmFyIEVsZW1lbnRGaW5kZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEVsZW1lbnRGaW5kZXIobmFtZXNwYWNlLCBpc29sYXRlTW9kdWxlKSB7XG4gICAgICAgIHRoaXMubmFtZXNwYWNlID0gbmFtZXNwYWNlO1xuICAgICAgICB0aGlzLmlzb2xhdGVNb2R1bGUgPSBpc29sYXRlTW9kdWxlO1xuICAgIH1cbiAgICBFbGVtZW50RmluZGVyLnByb3RvdHlwZS5jYWxsID0gZnVuY3Rpb24gKHJvb3RFbGVtZW50KSB7XG4gICAgICAgIHZhciBuYW1lc3BhY2UgPSB0aGlzLm5hbWVzcGFjZTtcbiAgICAgICAgaWYgKG5hbWVzcGFjZS5qb2luKFwiXCIpID09PSBcIlwiKSB7XG4gICAgICAgICAgICByZXR1cm4gcm9vdEVsZW1lbnQ7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHNjb3BlID0gdXRpbHNfMS5nZXRTY29wZShuYW1lc3BhY2UpO1xuICAgICAgICB2YXIgc2NvcGVDaGVja2VyID0gbmV3IFNjb3BlQ2hlY2tlcl8xLlNjb3BlQ2hlY2tlcihzY29wZSwgdGhpcy5pc29sYXRlTW9kdWxlKTtcbiAgICAgICAgdmFyIHNlbGVjdG9yID0gdXRpbHNfMS5nZXRTZWxlY3RvcnMobmFtZXNwYWNlKTtcbiAgICAgICAgdmFyIHRvcE5vZGUgPSByb290RWxlbWVudDtcbiAgICAgICAgdmFyIHRvcE5vZGVNYXRjaGVzID0gW107XG4gICAgICAgIGlmIChzY29wZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICB0b3BOb2RlID0gdGhpcy5pc29sYXRlTW9kdWxlLmdldElzb2xhdGVkRWxlbWVudChzY29wZSkgfHwgcm9vdEVsZW1lbnQ7XG4gICAgICAgICAgICBpZiAoc2VsZWN0b3IgJiYgbWF0Y2hlc1NlbGVjdG9yKHRvcE5vZGUsIHNlbGVjdG9yKSkge1xuICAgICAgICAgICAgICAgIHRvcE5vZGVNYXRjaGVzLnB1c2godG9wTm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRvRWxBcnJheSh0b3BOb2RlLnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpKVxuICAgICAgICAgICAgLmZpbHRlcihzY29wZUNoZWNrZXIuaXNTdHJpY3RseUluUm9vdFNjb3BlLCBzY29wZUNoZWNrZXIpXG4gICAgICAgICAgICAuY29uY2F0KHRvcE5vZGVNYXRjaGVzKTtcbiAgICB9O1xuICAgIHJldHVybiBFbGVtZW50RmluZGVyO1xufSgpKTtcbmV4cG9ydHMuRWxlbWVudEZpbmRlciA9IEVsZW1lbnRGaW5kZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1FbGVtZW50RmluZGVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xudmFyIFNjb3BlQ2hlY2tlcl8xID0gcmVxdWlyZSgnLi9TY29wZUNoZWNrZXInKTtcbnZhciB1dGlsc18xID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIG1hdGNoZXNTZWxlY3RvcjtcbnRyeSB7XG4gICAgbWF0Y2hlc1NlbGVjdG9yID0gcmVxdWlyZShcIm1hdGNoZXMtc2VsZWN0b3JcIik7XG59XG5jYXRjaCAoZSkge1xuICAgIG1hdGNoZXNTZWxlY3RvciA9IEZ1bmN0aW9uLnByb3RvdHlwZTtcbn1cbi8qKlxuICogQXR0YWNoZXMgYW4gYWN0dWFsIGV2ZW50IGxpc3RlbmVyIHRvIHRoZSBET00gcm9vdCBlbGVtZW50LFxuICogaGFuZGxlcyBcImRlc3RpbmF0aW9uc1wiIChpbnRlcmVzdGVkIERPTVNvdXJjZSBvdXRwdXQgc3ViamVjdHMpLCBhbmQgYnViYmxpbmcuXG4gKi9cbnZhciBFdmVudERlbGVnYXRvciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRXZlbnREZWxlZ2F0b3IodG9wRWxlbWVudCwgZXZlbnRUeXBlLCB1c2VDYXB0dXJlLCBpc29sYXRlTW9kdWxlKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHRoaXMudG9wRWxlbWVudCA9IHRvcEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuZXZlbnRUeXBlID0gZXZlbnRUeXBlO1xuICAgICAgICB0aGlzLnVzZUNhcHR1cmUgPSB1c2VDYXB0dXJlO1xuICAgICAgICB0aGlzLmlzb2xhdGVNb2R1bGUgPSBpc29sYXRlTW9kdWxlO1xuICAgICAgICB0aGlzLmRlc3RpbmF0aW9ucyA9IFtdO1xuICAgICAgICB0aGlzLnJvb2YgPSB0b3BFbGVtZW50LnBhcmVudEVsZW1lbnQ7XG4gICAgICAgIGlmICh1c2VDYXB0dXJlKSB7XG4gICAgICAgICAgICB0aGlzLmRvbUxpc3RlbmVyID0gZnVuY3Rpb24gKGV2KSB7IHJldHVybiBfdGhpcy5jYXB0dXJlKGV2KTsgfTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuZG9tTGlzdGVuZXIgPSBmdW5jdGlvbiAoZXYpIHsgcmV0dXJuIF90aGlzLmJ1YmJsZShldik7IH07XG4gICAgICAgIH1cbiAgICAgICAgdG9wRWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50VHlwZSwgdGhpcy5kb21MaXN0ZW5lciwgdXNlQ2FwdHVyZSk7XG4gICAgfVxuICAgIEV2ZW50RGVsZWdhdG9yLnByb3RvdHlwZS5idWJibGUgPSBmdW5jdGlvbiAocmF3RXZlbnQpIHtcbiAgICAgICAgaWYgKCFkb2N1bWVudC5ib2R5LmNvbnRhaW5zKHJhd0V2ZW50LmN1cnJlbnRUYXJnZXQpKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGV2ID0gdGhpcy5wYXRjaEV2ZW50KHJhd0V2ZW50KTtcbiAgICAgICAgZm9yICh2YXIgZWwgPSBldi50YXJnZXQ7IGVsICYmIGVsICE9PSB0aGlzLnJvb2Y7IGVsID0gZWwucGFyZW50RWxlbWVudCkge1xuICAgICAgICAgICAgaWYgKGV2LnByb3BhZ2F0aW9uSGFzQmVlblN0b3BwZWQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLm1hdGNoRXZlbnRBZ2FpbnN0RGVzdGluYXRpb25zKGVsLCBldik7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEV2ZW50RGVsZWdhdG9yLnByb3RvdHlwZS5tYXRjaEV2ZW50QWdhaW5zdERlc3RpbmF0aW9ucyA9IGZ1bmN0aW9uIChlbCwgZXYpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIG4gPSB0aGlzLmRlc3RpbmF0aW9ucy5sZW5ndGg7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBkZXN0ID0gdGhpcy5kZXN0aW5hdGlvbnNbaV07XG4gICAgICAgICAgICBpZiAoIWRlc3Quc2NvcGVDaGVja2VyLmlzU3RyaWN0bHlJblJvb3RTY29wZShlbCkpIHtcbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChtYXRjaGVzU2VsZWN0b3IoZWwsIGRlc3Quc2VsZWN0b3IpKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tdXRhdGVFdmVudEN1cnJlbnRUYXJnZXQoZXYsIGVsKTtcbiAgICAgICAgICAgICAgICBkZXN0LnN1YmplY3QuX24oZXYpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBFdmVudERlbGVnYXRvci5wcm90b3R5cGUuY2FwdHVyZSA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbiA9IHRoaXMuZGVzdGluYXRpb25zLmxlbmd0aDsgaSA8IG47IGkrKykge1xuICAgICAgICAgICAgdmFyIGRlc3QgPSB0aGlzLmRlc3RpbmF0aW9uc1tpXTtcbiAgICAgICAgICAgIGlmIChtYXRjaGVzU2VsZWN0b3IoZXYudGFyZ2V0LCBkZXN0LnNlbGVjdG9yKSkge1xuICAgICAgICAgICAgICAgIGRlc3Quc3ViamVjdC5fbihldik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEV2ZW50RGVsZWdhdG9yLnByb3RvdHlwZS5hZGREZXN0aW5hdGlvbiA9IGZ1bmN0aW9uIChzdWJqZWN0LCBuYW1lc3BhY2UpIHtcbiAgICAgICAgdmFyIHNjb3BlID0gdXRpbHNfMS5nZXRTY29wZShuYW1lc3BhY2UpO1xuICAgICAgICB2YXIgc2VsZWN0b3IgPSB1dGlsc18xLmdldFNlbGVjdG9ycyhuYW1lc3BhY2UpO1xuICAgICAgICB2YXIgc2NvcGVDaGVja2VyID0gbmV3IFNjb3BlQ2hlY2tlcl8xLlNjb3BlQ2hlY2tlcihzY29wZSwgdGhpcy5pc29sYXRlTW9kdWxlKTtcbiAgICAgICAgdGhpcy5kZXN0aW5hdGlvbnMucHVzaCh7IHN1YmplY3Q6IHN1YmplY3QsIHNjb3BlQ2hlY2tlcjogc2NvcGVDaGVja2VyLCBzZWxlY3Rvcjogc2VsZWN0b3IgfSk7XG4gICAgfTtcbiAgICBFdmVudERlbGVnYXRvci5wcm90b3R5cGUucGF0Y2hFdmVudCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICB2YXIgcEV2ZW50ID0gZXZlbnQ7XG4gICAgICAgIHBFdmVudC5wcm9wYWdhdGlvbkhhc0JlZW5TdG9wcGVkID0gZmFsc2U7XG4gICAgICAgIHZhciBvbGRTdG9wUHJvcGFnYXRpb24gPSBwRXZlbnQuc3RvcFByb3BhZ2F0aW9uO1xuICAgICAgICBwRXZlbnQuc3RvcFByb3BhZ2F0aW9uID0gZnVuY3Rpb24gc3RvcFByb3BhZ2F0aW9uKCkge1xuICAgICAgICAgICAgb2xkU3RvcFByb3BhZ2F0aW9uLmNhbGwodGhpcyk7XG4gICAgICAgICAgICB0aGlzLnByb3BhZ2F0aW9uSGFzQmVlblN0b3BwZWQgPSB0cnVlO1xuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gcEV2ZW50O1xuICAgIH07XG4gICAgRXZlbnREZWxlZ2F0b3IucHJvdG90eXBlLm11dGF0ZUV2ZW50Q3VycmVudFRhcmdldCA9IGZ1bmN0aW9uIChldmVudCwgY3VycmVudFRhcmdldEVsZW1lbnQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShldmVudCwgXCJjdXJyZW50VGFyZ2V0XCIsIHtcbiAgICAgICAgICAgICAgICB2YWx1ZTogY3VycmVudFRhcmdldEVsZW1lbnQsXG4gICAgICAgICAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGVycikge1xuICAgICAgICAgICAgY29uc29sZS5sb2coXCJwbGVhc2UgdXNlIGV2ZW50Lm93bmVyVGFyZ2V0XCIpO1xuICAgICAgICB9XG4gICAgICAgIGV2ZW50Lm93bmVyVGFyZ2V0ID0gY3VycmVudFRhcmdldEVsZW1lbnQ7XG4gICAgfTtcbiAgICBFdmVudERlbGVnYXRvci5wcm90b3R5cGUudXBkYXRlVG9wRWxlbWVudCA9IGZ1bmN0aW9uIChuZXdUb3BFbGVtZW50KSB7XG4gICAgICAgIHRoaXMudG9wRWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKHRoaXMuZXZlbnRUeXBlLCB0aGlzLmRvbUxpc3RlbmVyLCB0aGlzLnVzZUNhcHR1cmUpO1xuICAgICAgICBuZXdUb3BFbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIodGhpcy5ldmVudFR5cGUsIHRoaXMuZG9tTGlzdGVuZXIsIHRoaXMudXNlQ2FwdHVyZSk7XG4gICAgICAgIHRoaXMudG9wRWxlbWVudCA9IG5ld1RvcEVsZW1lbnQ7XG4gICAgfTtcbiAgICByZXR1cm4gRXZlbnREZWxlZ2F0b3I7XG59KCkpO1xuZXhwb3J0cy5FdmVudERlbGVnYXRvciA9IEV2ZW50RGVsZWdhdG9yO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9RXZlbnREZWxlZ2F0b3IuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgeHN0cmVhbV8xID0gcmVxdWlyZSgneHN0cmVhbScpO1xudmFyIHhzdHJlYW1fYWRhcHRlcl8xID0gcmVxdWlyZSgnQGN5Y2xlL3hzdHJlYW0tYWRhcHRlcicpO1xudmFyIEhUTUxTb3VyY2UgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEhUTUxTb3VyY2UoaHRtbCQsIHJ1blNBKSB7XG4gICAgICAgIHRoaXMucnVuU0EgPSBydW5TQTtcbiAgICAgICAgdGhpcy5faHRtbCQgPSBodG1sJDtcbiAgICAgICAgdGhpcy5fZW1wdHkkID0gcnVuU0EuYWRhcHQoeHN0cmVhbV8xLmRlZmF1bHQuZW1wdHkoKSwgeHN0cmVhbV9hZGFwdGVyXzEuZGVmYXVsdC5zdHJlYW1TdWJzY3JpYmUpO1xuICAgIH1cbiAgICBIVE1MU291cmNlLnByb3RvdHlwZS5lbGVtZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucnVuU0EuYWRhcHQodGhpcy5faHRtbCQsIHhzdHJlYW1fYWRhcHRlcl8xLmRlZmF1bHQuc3RyZWFtU3Vic2NyaWJlKTtcbiAgICB9O1xuICAgIEhUTUxTb3VyY2UucHJvdG90eXBlLnNlbGVjdCA9IGZ1bmN0aW9uIChzZWxlY3Rvcikge1xuICAgICAgICByZXR1cm4gbmV3IEhUTUxTb3VyY2UoeHN0cmVhbV8xLmRlZmF1bHQuZW1wdHkoKSwgdGhpcy5ydW5TQSk7XG4gICAgfTtcbiAgICBIVE1MU291cmNlLnByb3RvdHlwZS5ldmVudHMgPSBmdW5jdGlvbiAoZXZlbnRUeXBlLCBvcHRpb25zKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbXB0eSQ7XG4gICAgfTtcbiAgICByZXR1cm4gSFRNTFNvdXJjZTtcbn0oKSk7XG5leHBvcnRzLkhUTUxTb3VyY2UgPSBIVE1MU291cmNlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9SFRNTFNvdXJjZS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbnZhciB4c3RyZWFtX2FkYXB0ZXJfMSA9IHJlcXVpcmUoJ0BjeWNsZS94c3RyZWFtLWFkYXB0ZXInKTtcbnZhciB4c3RyZWFtXzEgPSByZXF1aXJlKCd4c3RyZWFtJyk7XG52YXIgRWxlbWVudEZpbmRlcl8xID0gcmVxdWlyZSgnLi9FbGVtZW50RmluZGVyJyk7XG52YXIgZnJvbUV2ZW50XzEgPSByZXF1aXJlKCcuL2Zyb21FdmVudCcpO1xudmFyIGlzb2xhdGVfMSA9IHJlcXVpcmUoJy4vaXNvbGF0ZScpO1xudmFyIEV2ZW50RGVsZWdhdG9yXzEgPSByZXF1aXJlKCcuL0V2ZW50RGVsZWdhdG9yJyk7XG52YXIgdXRpbHNfMSA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbnZhciBtYXRjaGVzU2VsZWN0b3I7XG50cnkge1xuICAgIG1hdGNoZXNTZWxlY3RvciA9IHJlcXVpcmUoXCJtYXRjaGVzLXNlbGVjdG9yXCIpO1xufVxuY2F0Y2ggKGUpIHtcbiAgICBtYXRjaGVzU2VsZWN0b3IgPSBGdW5jdGlvbi5wcm90b3R5cGU7XG59XG52YXIgZXZlbnRUeXBlc1RoYXREb250QnViYmxlID0gW1xuICAgIFwibG9hZFwiLFxuICAgIFwidW5sb2FkXCIsXG4gICAgXCJmb2N1c1wiLFxuICAgIFwiYmx1clwiLFxuICAgIFwibW91c2VlbnRlclwiLFxuICAgIFwibW91c2VsZWF2ZVwiLFxuICAgIFwic3VibWl0XCIsXG4gICAgXCJjaGFuZ2VcIixcbiAgICBcInJlc2V0XCIsXG4gICAgXCJ0aW1ldXBkYXRlXCIsXG4gICAgXCJwbGF5aW5nXCIsXG4gICAgXCJ3YWl0aW5nXCIsXG4gICAgXCJzZWVraW5nXCIsXG4gICAgXCJzZWVrZWRcIixcbiAgICBcImVuZGVkXCIsXG4gICAgXCJsb2FkZWRtZXRhZGF0YVwiLFxuICAgIFwibG9hZGVkZGF0YVwiLFxuICAgIFwiY2FucGxheVwiLFxuICAgIFwiY2FucGxheXRocm91Z2hcIixcbiAgICBcImR1cmF0aW9uY2hhbmdlXCIsXG4gICAgXCJwbGF5XCIsXG4gICAgXCJwYXVzZVwiLFxuICAgIFwicmF0ZWNoYW5nZVwiLFxuICAgIFwidm9sdW1lY2hhbmdlXCIsXG4gICAgXCJzdXNwZW5kXCIsXG4gICAgXCJlbXB0aWVkXCIsXG4gICAgXCJzdGFsbGVkXCIsXG5dO1xuZnVuY3Rpb24gZGV0ZXJtaW5lVXNlQ2FwdHVyZShldmVudFR5cGUsIG9wdGlvbnMpIHtcbiAgICB2YXIgcmVzdWx0ID0gZmFsc2U7XG4gICAgaWYgKHR5cGVvZiBvcHRpb25zLnVzZUNhcHR1cmUgPT09IFwiYm9vbGVhblwiKSB7XG4gICAgICAgIHJlc3VsdCA9IG9wdGlvbnMudXNlQ2FwdHVyZTtcbiAgICB9XG4gICAgaWYgKGV2ZW50VHlwZXNUaGF0RG9udEJ1YmJsZS5pbmRleE9mKGV2ZW50VHlwZSkgIT09IC0xKSB7XG4gICAgICAgIHJlc3VsdCA9IHRydWU7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG52YXIgTWFpbkRPTVNvdXJjZSA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTWFpbkRPTVNvdXJjZShfcm9vdEVsZW1lbnQkLCBfcnVuU3RyZWFtQWRhcHRlciwgX25hbWVzcGFjZSwgX2lzb2xhdGVNb2R1bGUsIF9kZWxlZ2F0b3JzKSB7XG4gICAgICAgIGlmIChfbmFtZXNwYWNlID09PSB2b2lkIDApIHsgX25hbWVzcGFjZSA9IFtdOyB9XG4gICAgICAgIHRoaXMuX3Jvb3RFbGVtZW50JCA9IF9yb290RWxlbWVudCQ7XG4gICAgICAgIHRoaXMuX3J1blN0cmVhbUFkYXB0ZXIgPSBfcnVuU3RyZWFtQWRhcHRlcjtcbiAgICAgICAgdGhpcy5fbmFtZXNwYWNlID0gX25hbWVzcGFjZTtcbiAgICAgICAgdGhpcy5faXNvbGF0ZU1vZHVsZSA9IF9pc29sYXRlTW9kdWxlO1xuICAgICAgICB0aGlzLl9kZWxlZ2F0b3JzID0gX2RlbGVnYXRvcnM7XG4gICAgICAgIHRoaXMuaXNvbGF0ZVNvdXJjZSA9IGlzb2xhdGVfMS5pc29sYXRlU291cmNlO1xuICAgICAgICB0aGlzLmlzb2xhdGVTaW5rID0gaXNvbGF0ZV8xLmlzb2xhdGVTaW5rO1xuICAgIH1cbiAgICBNYWluRE9NU291cmNlLnByb3RvdHlwZS5lbGVtZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIG91dHB1dCQ7XG4gICAgICAgIGlmICh0aGlzLl9uYW1lc3BhY2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICBvdXRwdXQkID0gdGhpcy5fcm9vdEVsZW1lbnQkO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIGVsZW1lbnRGaW5kZXJfMSA9IG5ldyBFbGVtZW50RmluZGVyXzEuRWxlbWVudEZpbmRlcih0aGlzLl9uYW1lc3BhY2UsIHRoaXMuX2lzb2xhdGVNb2R1bGUpO1xuICAgICAgICAgICAgb3V0cHV0JCA9IHRoaXMuX3Jvb3RFbGVtZW50JC5tYXAoZnVuY3Rpb24gKGVsKSB7IHJldHVybiBlbGVtZW50RmluZGVyXzEuY2FsbChlbCk7IH0pO1xuICAgICAgICB9XG4gICAgICAgIHZhciBydW5TQSA9IHRoaXMuX3J1blN0cmVhbUFkYXB0ZXI7XG4gICAgICAgIHJldHVybiBydW5TQS5yZW1lbWJlcihydW5TQS5hZGFwdChvdXRwdXQkLCB4c3RyZWFtX2FkYXB0ZXJfMS5kZWZhdWx0LnN0cmVhbVN1YnNjcmliZSkpO1xuICAgIH07XG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KE1haW5ET01Tb3VyY2UucHJvdG90eXBlLCBcIm5hbWVzcGFjZVwiLCB7XG4gICAgICAgIGdldDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX25hbWVzcGFjZTtcbiAgICAgICAgfSxcbiAgICAgICAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSk7XG4gICAgTWFpbkRPTVNvdXJjZS5wcm90b3R5cGUuc2VsZWN0ID0gZnVuY3Rpb24gKHNlbGVjdG9yKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygc2VsZWN0b3IgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJET00gZHJpdmVyJ3Mgc2VsZWN0KCkgZXhwZWN0cyB0aGUgYXJndW1lbnQgdG8gYmUgYSBcIiArXG4gICAgICAgICAgICAgICAgXCJzdHJpbmcgYXMgYSBDU1Mgc2VsZWN0b3JcIik7XG4gICAgICAgIH1cbiAgICAgICAgdmFyIHRyaW1tZWRTZWxlY3RvciA9IHNlbGVjdG9yLnRyaW0oKTtcbiAgICAgICAgdmFyIGNoaWxkTmFtZXNwYWNlID0gdHJpbW1lZFNlbGVjdG9yID09PSBcIjpyb290XCIgP1xuICAgICAgICAgICAgdGhpcy5fbmFtZXNwYWNlIDpcbiAgICAgICAgICAgIHRoaXMuX25hbWVzcGFjZS5jb25jYXQodHJpbW1lZFNlbGVjdG9yKTtcbiAgICAgICAgcmV0dXJuIG5ldyBNYWluRE9NU291cmNlKHRoaXMuX3Jvb3RFbGVtZW50JCwgdGhpcy5fcnVuU3RyZWFtQWRhcHRlciwgY2hpbGROYW1lc3BhY2UsIHRoaXMuX2lzb2xhdGVNb2R1bGUsIHRoaXMuX2RlbGVnYXRvcnMpO1xuICAgIH07XG4gICAgTWFpbkRPTVNvdXJjZS5wcm90b3R5cGUuZXZlbnRzID0gZnVuY3Rpb24gKGV2ZW50VHlwZSwgb3B0aW9ucykge1xuICAgICAgICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7IG9wdGlvbnMgPSB7fTsgfVxuICAgICAgICBpZiAodHlwZW9mIGV2ZW50VHlwZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRE9NIGRyaXZlcidzIGV2ZW50cygpIGV4cGVjdHMgYXJndW1lbnQgdG8gYmUgYSBcIiArXG4gICAgICAgICAgICAgICAgXCJzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBldmVudCB0eXBlIHRvIGxpc3RlbiBmb3IuXCIpO1xuICAgICAgICB9XG4gICAgICAgIHZhciB1c2VDYXB0dXJlID0gZGV0ZXJtaW5lVXNlQ2FwdHVyZShldmVudFR5cGUsIG9wdGlvbnMpO1xuICAgICAgICB2YXIgbmFtZXNwYWNlID0gdGhpcy5fbmFtZXNwYWNlO1xuICAgICAgICB2YXIgc2NvcGUgPSB1dGlsc18xLmdldFNjb3BlKG5hbWVzcGFjZSk7XG4gICAgICAgIHZhciBrZXlQYXJ0cyA9IFtldmVudFR5cGUsIHVzZUNhcHR1cmVdO1xuICAgICAgICBpZiAoc2NvcGUpIHtcbiAgICAgICAgICAgIGtleVBhcnRzLnB1c2goc2NvcGUpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBrZXkgPSBrZXlQYXJ0cy5qb2luKCd+Jyk7XG4gICAgICAgIHZhciBkb21Tb3VyY2UgPSB0aGlzO1xuICAgICAgICB2YXIgcm9vdEVsZW1lbnQkO1xuICAgICAgICBpZiAoc2NvcGUpIHtcbiAgICAgICAgICAgIHZhciBoYWRJc29sYXRlZF9tdXRhYmxlXzEgPSBmYWxzZTtcbiAgICAgICAgICAgIHJvb3RFbGVtZW50JCA9IHRoaXMuX3Jvb3RFbGVtZW50JFxuICAgICAgICAgICAgICAgIC5maWx0ZXIoZnVuY3Rpb24gKHJvb3RFbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgdmFyIGhhc0lzb2xhdGVkID0gISFkb21Tb3VyY2UuX2lzb2xhdGVNb2R1bGUuZ2V0SXNvbGF0ZWRFbGVtZW50KHNjb3BlKTtcbiAgICAgICAgICAgICAgICB2YXIgc2hvdWxkUGFzcyA9IGhhc0lzb2xhdGVkICYmICFoYWRJc29sYXRlZF9tdXRhYmxlXzE7XG4gICAgICAgICAgICAgICAgaGFkSXNvbGF0ZWRfbXV0YWJsZV8xID0gaGFzSXNvbGF0ZWQ7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHNob3VsZFBhc3M7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHJvb3RFbGVtZW50JCA9IHRoaXMuX3Jvb3RFbGVtZW50JC50YWtlKDIpO1xuICAgICAgICB9XG4gICAgICAgIHZhciBldmVudCQgPSByb290RWxlbWVudCRcbiAgICAgICAgICAgIC5tYXAoZnVuY3Rpb24gc2V0dXBFdmVudERlbGVnYXRvck9uVG9wRWxlbWVudChyb290RWxlbWVudCkge1xuICAgICAgICAgICAgLy8gRXZlbnQgbGlzdGVuZXIganVzdCBmb3IgdGhlIHJvb3QgZWxlbWVudFxuICAgICAgICAgICAgaWYgKCFuYW1lc3BhY2UgfHwgbmFtZXNwYWNlLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmcm9tRXZlbnRfMS5mcm9tRXZlbnQocm9vdEVsZW1lbnQsIGV2ZW50VHlwZSwgdXNlQ2FwdHVyZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBFdmVudCBsaXN0ZW5lciBvbiB0aGUgdG9wIGVsZW1lbnQgYXMgYW4gRXZlbnREZWxlZ2F0b3JcbiAgICAgICAgICAgIHZhciBkZWxlZ2F0b3JzID0gZG9tU291cmNlLl9kZWxlZ2F0b3JzO1xuICAgICAgICAgICAgdmFyIHRvcCA9IHNjb3BlXG4gICAgICAgICAgICAgICAgPyBkb21Tb3VyY2UuX2lzb2xhdGVNb2R1bGUuZ2V0SXNvbGF0ZWRFbGVtZW50KHNjb3BlKVxuICAgICAgICAgICAgICAgIDogcm9vdEVsZW1lbnQ7XG4gICAgICAgICAgICB2YXIgZGVsZWdhdG9yO1xuICAgICAgICAgICAgaWYgKGRlbGVnYXRvcnMuaGFzKGtleSkpIHtcbiAgICAgICAgICAgICAgICBkZWxlZ2F0b3IgPSBkZWxlZ2F0b3JzLmdldChrZXkpO1xuICAgICAgICAgICAgICAgIGRlbGVnYXRvci51cGRhdGVUb3BFbGVtZW50KHRvcCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBkZWxlZ2F0b3IgPSBuZXcgRXZlbnREZWxlZ2F0b3JfMS5FdmVudERlbGVnYXRvcih0b3AsIGV2ZW50VHlwZSwgdXNlQ2FwdHVyZSwgZG9tU291cmNlLl9pc29sYXRlTW9kdWxlKTtcbiAgICAgICAgICAgICAgICBkZWxlZ2F0b3JzLnNldChrZXksIGRlbGVnYXRvcik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgc3ViamVjdCA9IHhzdHJlYW1fMS5kZWZhdWx0LmNyZWF0ZSgpO1xuICAgICAgICAgICAgaWYgKHNjb3BlKSB7XG4gICAgICAgICAgICAgICAgZG9tU291cmNlLl9pc29sYXRlTW9kdWxlLmFkZEV2ZW50RGVsZWdhdG9yKHNjb3BlLCBkZWxlZ2F0b3IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZGVsZWdhdG9yLmFkZERlc3RpbmF0aW9uKHN1YmplY3QsIG5hbWVzcGFjZSk7XG4gICAgICAgICAgICByZXR1cm4gc3ViamVjdDtcbiAgICAgICAgfSlcbiAgICAgICAgICAgIC5mbGF0dGVuKCk7XG4gICAgICAgIHJldHVybiB0aGlzLl9ydW5TdHJlYW1BZGFwdGVyLmFkYXB0KGV2ZW50JCwgeHN0cmVhbV9hZGFwdGVyXzEuZGVmYXVsdC5zdHJlYW1TdWJzY3JpYmUpO1xuICAgIH07XG4gICAgTWFpbkRPTVNvdXJjZS5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5faXNvbGF0ZU1vZHVsZS5yZXNldCgpO1xuICAgIH07XG4gICAgcmV0dXJuIE1haW5ET01Tb3VyY2U7XG59KCkpO1xuZXhwb3J0cy5NYWluRE9NU291cmNlID0gTWFpbkRPTVNvdXJjZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPU1haW5ET01Tb3VyY2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgU2NvcGVDaGVja2VyID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBTY29wZUNoZWNrZXIoc2NvcGUsIGlzb2xhdGVNb2R1bGUpIHtcbiAgICAgICAgdGhpcy5zY29wZSA9IHNjb3BlO1xuICAgICAgICB0aGlzLmlzb2xhdGVNb2R1bGUgPSBpc29sYXRlTW9kdWxlO1xuICAgIH1cbiAgICBTY29wZUNoZWNrZXIucHJvdG90eXBlLmlzU3RyaWN0bHlJblJvb3RTY29wZSA9IGZ1bmN0aW9uIChsZWFmKSB7XG4gICAgICAgIGZvciAodmFyIGVsID0gbGVhZjsgZWw7IGVsID0gZWwucGFyZW50RWxlbWVudCkge1xuICAgICAgICAgICAgdmFyIHNjb3BlID0gdGhpcy5pc29sYXRlTW9kdWxlLmlzSXNvbGF0ZWRFbGVtZW50KGVsKTtcbiAgICAgICAgICAgIGlmIChzY29wZSAmJiBzY29wZSAhPT0gdGhpcy5zY29wZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChzY29wZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH07XG4gICAgcmV0dXJuIFNjb3BlQ2hlY2tlcjtcbn0oKSk7XG5leHBvcnRzLlNjb3BlQ2hlY2tlciA9IFNjb3BlQ2hlY2tlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVNjb3BlQ2hlY2tlci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbnZhciBoeXBlcnNjcmlwdF8xID0gcmVxdWlyZSgnLi9oeXBlcnNjcmlwdCcpO1xudmFyIGNsYXNzTmFtZUZyb21WTm9kZV8xID0gcmVxdWlyZSgnc25hYmJkb20tc2VsZWN0b3IvbGliL2NsYXNzTmFtZUZyb21WTm9kZScpO1xudmFyIHNlbGVjdG9yUGFyc2VyXzEgPSByZXF1aXJlKCdzbmFiYmRvbS1zZWxlY3Rvci9saWIvc2VsZWN0b3JQYXJzZXInKTtcbnZhciBWTm9kZVdyYXBwZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFZOb2RlV3JhcHBlcihyb290RWxlbWVudCkge1xuICAgICAgICB0aGlzLnJvb3RFbGVtZW50ID0gcm9vdEVsZW1lbnQ7XG4gICAgfVxuICAgIFZOb2RlV3JhcHBlci5wcm90b3R5cGUuY2FsbCA9IGZ1bmN0aW9uICh2bm9kZSkge1xuICAgICAgICB2YXIgX2EgPSBzZWxlY3RvclBhcnNlcl8xLmRlZmF1bHQodm5vZGUuc2VsKSwgc2VsZWN0b3JUYWdOYW1lID0gX2EudGFnTmFtZSwgc2VsZWN0b3JJZCA9IF9hLmlkO1xuICAgICAgICB2YXIgdk5vZGVDbGFzc05hbWUgPSBjbGFzc05hbWVGcm9tVk5vZGVfMS5kZWZhdWx0KHZub2RlKTtcbiAgICAgICAgdmFyIHZOb2RlRGF0YSA9IHZub2RlLmRhdGEgfHwge307XG4gICAgICAgIHZhciB2Tm9kZURhdGFQcm9wcyA9IHZOb2RlRGF0YS5wcm9wcyB8fCB7fTtcbiAgICAgICAgdmFyIF9iID0gdk5vZGVEYXRhUHJvcHMuaWQsIHZOb2RlSWQgPSBfYiA9PT0gdm9pZCAwID8gc2VsZWN0b3JJZCA6IF9iO1xuICAgICAgICB2YXIgaXNWTm9kZUFuZFJvb3RFbGVtZW50SWRlbnRpY2FsID0gdk5vZGVJZC50b1VwcGVyQ2FzZSgpID09PSB0aGlzLnJvb3RFbGVtZW50LmlkLnRvVXBwZXJDYXNlKCkgJiZcbiAgICAgICAgICAgIHNlbGVjdG9yVGFnTmFtZS50b1VwcGVyQ2FzZSgpID09PSB0aGlzLnJvb3RFbGVtZW50LnRhZ05hbWUudG9VcHBlckNhc2UoKSAmJlxuICAgICAgICAgICAgdk5vZGVDbGFzc05hbWUudG9VcHBlckNhc2UoKSA9PT0gdGhpcy5yb290RWxlbWVudC5jbGFzc05hbWUudG9VcHBlckNhc2UoKTtcbiAgICAgICAgaWYgKGlzVk5vZGVBbmRSb290RWxlbWVudElkZW50aWNhbCkge1xuICAgICAgICAgICAgcmV0dXJuIHZub2RlO1xuICAgICAgICB9XG4gICAgICAgIHZhciBfYyA9IHRoaXMucm9vdEVsZW1lbnQsIHRhZ05hbWUgPSBfYy50YWdOYW1lLCBpZCA9IF9jLmlkLCBjbGFzc05hbWUgPSBfYy5jbGFzc05hbWU7XG4gICAgICAgIHZhciBlbGVtZW50SWQgPSBpZCA/IFwiI1wiICsgaWQgOiBcIlwiO1xuICAgICAgICB2YXIgZWxlbWVudENsYXNzTmFtZSA9IGNsYXNzTmFtZSA/XG4gICAgICAgICAgICBcIi5cIiArIGNsYXNzTmFtZS5zcGxpdChcIiBcIikuam9pbihcIi5cIikgOiBcIlwiO1xuICAgICAgICByZXR1cm4gaHlwZXJzY3JpcHRfMS5oKFwiXCIgKyB0YWdOYW1lICsgZWxlbWVudElkICsgZWxlbWVudENsYXNzTmFtZSwge30sIFt2bm9kZV0pO1xuICAgIH07XG4gICAgcmV0dXJuIFZOb2RlV3JhcHBlcjtcbn0oKSk7XG5leHBvcnRzLlZOb2RlV3JhcHBlciA9IFZOb2RlV3JhcHBlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPVZOb2RlV3JhcHBlci5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbnZhciB4c3RyZWFtXzEgPSByZXF1aXJlKCd4c3RyZWFtJyk7XG5mdW5jdGlvbiBmcm9tRXZlbnQoZWxlbWVudCwgZXZlbnROYW1lLCB1c2VDYXB0dXJlKSB7XG4gICAgaWYgKHVzZUNhcHR1cmUgPT09IHZvaWQgMCkgeyB1c2VDYXB0dXJlID0gZmFsc2U7IH1cbiAgICByZXR1cm4geHN0cmVhbV8xLlN0cmVhbS5jcmVhdGUoe1xuICAgICAgICBlbGVtZW50OiBlbGVtZW50LFxuICAgICAgICBuZXh0OiBudWxsLFxuICAgICAgICBzdGFydDogZnVuY3Rpb24gc3RhcnQobGlzdGVuZXIpIHtcbiAgICAgICAgICAgIHRoaXMubmV4dCA9IGZ1bmN0aW9uIG5leHQoZXZlbnQpIHsgbGlzdGVuZXIubmV4dChldmVudCk7IH07XG4gICAgICAgICAgICB0aGlzLmVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIHRoaXMubmV4dCwgdXNlQ2FwdHVyZSk7XG4gICAgICAgIH0sXG4gICAgICAgIHN0b3A6IGZ1bmN0aW9uIHN0b3AoKSB7XG4gICAgICAgICAgICB0aGlzLmVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudE5hbWUsIHRoaXMubmV4dCwgdXNlQ2FwdHVyZSk7XG4gICAgICAgIH1cbiAgICB9KTtcbn1cbmV4cG9ydHMuZnJvbUV2ZW50ID0gZnJvbUV2ZW50O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZnJvbUV2ZW50LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xudmFyIGh5cGVyc2NyaXB0XzEgPSByZXF1aXJlKCcuL2h5cGVyc2NyaXB0Jyk7XG5mdW5jdGlvbiBpc1ZhbGlkU3RyaW5nKHBhcmFtKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBwYXJhbSA9PT0gJ3N0cmluZycgJiYgcGFyYW0ubGVuZ3RoID4gMDtcbn1cbmZ1bmN0aW9uIGlzU2VsZWN0b3IocGFyYW0pIHtcbiAgICByZXR1cm4gaXNWYWxpZFN0cmluZyhwYXJhbSkgJiYgKHBhcmFtWzBdID09PSAnLicgfHwgcGFyYW1bMF0gPT09ICcjJyk7XG59XG5mdW5jdGlvbiBjcmVhdGVUYWdGdW5jdGlvbih0YWdOYW1lKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIGh5cGVyc2NyaXB0KGZpcnN0LCBiLCBjKSB7XG4gICAgICAgIGlmIChpc1NlbGVjdG9yKGZpcnN0KSkge1xuICAgICAgICAgICAgaWYgKCEhYiAmJiAhIWMpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaHlwZXJzY3JpcHRfMS5oKHRhZ05hbWUgKyBmaXJzdCwgYiwgYyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmICghIWIpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaHlwZXJzY3JpcHRfMS5oKHRhZ05hbWUgKyBmaXJzdCwgYik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gaHlwZXJzY3JpcHRfMS5oKHRhZ05hbWUgKyBmaXJzdCwge30pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCEhYikge1xuICAgICAgICAgICAgcmV0dXJuIGh5cGVyc2NyaXB0XzEuaCh0YWdOYW1lLCBmaXJzdCwgYik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoISFmaXJzdCkge1xuICAgICAgICAgICAgcmV0dXJuIGh5cGVyc2NyaXB0XzEuaCh0YWdOYW1lLCBmaXJzdCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gaHlwZXJzY3JpcHRfMS5oKHRhZ05hbWUsIHt9KTtcbiAgICAgICAgfVxuICAgIH07XG59XG52YXIgU1ZHX1RBR19OQU1FUyA9IFtcbiAgICAnYScsICdhbHRHbHlwaCcsICdhbHRHbHlwaERlZicsICdhbHRHbHlwaEl0ZW0nLCAnYW5pbWF0ZScsICdhbmltYXRlQ29sb3InLFxuICAgICdhbmltYXRlTW90aW9uJywgJ2FuaW1hdGVUcmFuc2Zvcm0nLCAnY2lyY2xlJywgJ2NsaXBQYXRoJywgJ2NvbG9yUHJvZmlsZScsXG4gICAgJ2N1cnNvcicsICdkZWZzJywgJ2Rlc2MnLCAnZWxsaXBzZScsICdmZUJsZW5kJywgJ2ZlQ29sb3JNYXRyaXgnLFxuICAgICdmZUNvbXBvbmVudFRyYW5zZmVyJywgJ2ZlQ29tcG9zaXRlJywgJ2ZlQ29udm9sdmVNYXRyaXgnLCAnZmVEaWZmdXNlTGlnaHRpbmcnLFxuICAgICdmZURpc3BsYWNlbWVudE1hcCcsICdmZURpc3RhbnRMaWdodCcsICdmZUZsb29kJywgJ2ZlRnVuY0EnLCAnZmVGdW5jQicsXG4gICAgJ2ZlRnVuY0cnLCAnZmVGdW5jUicsICdmZUdhdXNzaWFuQmx1cicsICdmZUltYWdlJywgJ2ZlTWVyZ2UnLCAnZmVNZXJnZU5vZGUnLFxuICAgICdmZU1vcnBob2xvZ3knLCAnZmVPZmZzZXQnLCAnZmVQb2ludExpZ2h0JywgJ2ZlU3BlY3VsYXJMaWdodGluZycsXG4gICAgJ2ZlU3BvdGxpZ2h0JywgJ2ZlVGlsZScsICdmZVR1cmJ1bGVuY2UnLCAnZmlsdGVyJywgJ2ZvbnQnLCAnZm9udEZhY2UnLFxuICAgICdmb250RmFjZUZvcm1hdCcsICdmb250RmFjZU5hbWUnLCAnZm9udEZhY2VTcmMnLCAnZm9udEZhY2VVcmknLFxuICAgICdmb3JlaWduT2JqZWN0JywgJ2cnLCAnZ2x5cGgnLCAnZ2x5cGhSZWYnLCAnaGtlcm4nLCAnaW1hZ2UnLCAnbGluZScsXG4gICAgJ2xpbmVhckdyYWRpZW50JywgJ21hcmtlcicsICdtYXNrJywgJ21ldGFkYXRhJywgJ21pc3NpbmdHbHlwaCcsICdtcGF0aCcsXG4gICAgJ3BhdGgnLCAncGF0dGVybicsICdwb2x5Z29uJywgJ3BvbHlsaW5nJywgJ3JhZGlhbEdyYWRpZW50JywgJ3JlY3QnLCAnc2NyaXB0JyxcbiAgICAnc2V0JywgJ3N0b3AnLCAnc3R5bGUnLCAnc3dpdGNoJywgJ3N5bWJvbCcsICd0ZXh0JywgJ3RleHRQYXRoJywgJ3RpdGxlJyxcbiAgICAndHJlZicsICd0c3BhbicsICd1c2UnLCAndmlldycsICd2a2Vybidcbl07XG52YXIgc3ZnID0gY3JlYXRlVGFnRnVuY3Rpb24oJ3N2ZycpO1xuU1ZHX1RBR19OQU1FUy5mb3JFYWNoKGZ1bmN0aW9uICh0YWcpIHtcbiAgICBzdmdbdGFnXSA9IGNyZWF0ZVRhZ0Z1bmN0aW9uKHRhZyk7XG59KTtcbnZhciBUQUdfTkFNRVMgPSBbXG4gICAgJ2EnLCAnYWJicicsICdhZGRyZXNzJywgJ2FyZWEnLCAnYXJ0aWNsZScsICdhc2lkZScsICdhdWRpbycsICdiJywgJ2Jhc2UnLFxuICAgICdiZGknLCAnYmRvJywgJ2Jsb2NrcXVvdGUnLCAnYm9keScsICdicicsICdidXR0b24nLCAnY2FudmFzJywgJ2NhcHRpb24nLFxuICAgICdjaXRlJywgJ2NvZGUnLCAnY29sJywgJ2NvbGdyb3VwJywgJ2RkJywgJ2RlbCcsICdkZm4nLCAnZGlyJywgJ2RpdicsICdkbCcsXG4gICAgJ2R0JywgJ2VtJywgJ2VtYmVkJywgJ2ZpZWxkc2V0JywgJ2ZpZ2NhcHRpb24nLCAnZmlndXJlJywgJ2Zvb3RlcicsICdmb3JtJyxcbiAgICAnaDEnLCAnaDInLCAnaDMnLCAnaDQnLCAnaDUnLCAnaDYnLCAnaGVhZCcsICdoZWFkZXInLCAnaGdyb3VwJywgJ2hyJywgJ2h0bWwnLFxuICAgICdpJywgJ2lmcmFtZScsICdpbWcnLCAnaW5wdXQnLCAnaW5zJywgJ2tiZCcsICdrZXlnZW4nLCAnbGFiZWwnLCAnbGVnZW5kJyxcbiAgICAnbGknLCAnbGluaycsICdtYWluJywgJ21hcCcsICdtYXJrJywgJ21lbnUnLCAnbWV0YScsICduYXYnLCAnbm9zY3JpcHQnLFxuICAgICdvYmplY3QnLCAnb2wnLCAnb3B0Z3JvdXAnLCAnb3B0aW9uJywgJ3AnLCAncGFyYW0nLCAncHJlJywgJ3Byb2dyZXNzJywgJ3EnLFxuICAgICdycCcsICdydCcsICdydWJ5JywgJ3MnLCAnc2FtcCcsICdzY3JpcHQnLCAnc2VjdGlvbicsICdzZWxlY3QnLCAnc21hbGwnLFxuICAgICdzb3VyY2UnLCAnc3BhbicsICdzdHJvbmcnLCAnc3R5bGUnLCAnc3ViJywgJ3N1cCcsICd0YWJsZScsICd0Ym9keScsICd0ZCcsXG4gICAgJ3RleHRhcmVhJywgJ3Rmb290JywgJ3RoJywgJ3RoZWFkJywgJ3RpdGxlJywgJ3RyJywgJ3UnLCAndWwnLCAndmlkZW8nXG5dO1xudmFyIGV4cG9ydGVkID0geyBTVkdfVEFHX05BTUVTOiBTVkdfVEFHX05BTUVTLCBUQUdfTkFNRVM6IFRBR19OQU1FUywgc3ZnOiBzdmcsIGlzU2VsZWN0b3I6IGlzU2VsZWN0b3IsIGNyZWF0ZVRhZ0Z1bmN0aW9uOiBjcmVhdGVUYWdGdW5jdGlvbiB9O1xuVEFHX05BTUVTLmZvckVhY2goZnVuY3Rpb24gKG4pIHtcbiAgICBleHBvcnRlZFtuXSA9IGNyZWF0ZVRhZ0Z1bmN0aW9uKG4pO1xufSk7XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmRlZmF1bHQgPSBleHBvcnRlZDtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWh5cGVyc2NyaXB0LWhlbHBlcnMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgaXMgPSByZXF1aXJlKCdzbmFiYmRvbS9pcycpO1xudmFyIHZub2RlID0gcmVxdWlyZSgnc25hYmJkb20vdm5vZGUnKTtcbmZ1bmN0aW9uIGlzR2VuZXJpY1N0cmVhbSh4KSB7XG4gICAgcmV0dXJuICFBcnJheS5pc0FycmF5KHgpICYmIHR5cGVvZiB4Lm1hcCA9PT0gXCJmdW5jdGlvblwiO1xufVxuZnVuY3Rpb24gbXV0YXRlU3RyZWFtV2l0aE5TKHZOb2RlKSB7XG4gICAgYWRkTlModk5vZGUuZGF0YSwgdk5vZGUuY2hpbGRyZW4pO1xuICAgIHJldHVybiB2Tm9kZTtcbn1cbmZ1bmN0aW9uIGFkZE5TKGRhdGEsIGNoaWxkcmVuKSB7XG4gICAgZGF0YS5ucyA9IFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIjtcbiAgICBpZiAodHlwZW9mIGNoaWxkcmVuICE9PSBcInVuZGVmaW5lZFwiICYmIGlzLmFycmF5KGNoaWxkcmVuKSkge1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBpZiAoaXNHZW5lcmljU3RyZWFtKGNoaWxkcmVuW2ldKSkge1xuICAgICAgICAgICAgICAgIGNoaWxkcmVuW2ldID0gY2hpbGRyZW5baV0ubWFwKG11dGF0ZVN0cmVhbVdpdGhOUyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBhZGROUyhjaGlsZHJlbltpXS5kYXRhLCBjaGlsZHJlbltpXS5jaGlsZHJlbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5mdW5jdGlvbiBoKHNlbCwgYiwgYykge1xuICAgIHZhciBkYXRhID0ge307XG4gICAgdmFyIGNoaWxkcmVuO1xuICAgIHZhciB0ZXh0O1xuICAgIHZhciBpO1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAzKSB7XG4gICAgICAgIGRhdGEgPSBiO1xuICAgICAgICBpZiAoaXMuYXJyYXkoYykpIHtcbiAgICAgICAgICAgIGNoaWxkcmVuID0gYztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChpcy5wcmltaXRpdmUoYykpIHtcbiAgICAgICAgICAgIHRleHQgPSBjO1xuICAgICAgICB9XG4gICAgfVxuICAgIGVsc2UgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIHtcbiAgICAgICAgaWYgKGlzLmFycmF5KGIpKSB7XG4gICAgICAgICAgICBjaGlsZHJlbiA9IGI7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoaXMucHJpbWl0aXZlKGIpKSB7XG4gICAgICAgICAgICB0ZXh0ID0gYjtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGRhdGEgPSBiO1xuICAgICAgICB9XG4gICAgfVxuICAgIGlmIChpcy5hcnJheShjaGlsZHJlbikpIHtcbiAgICAgICAgY2hpbGRyZW4gPSBjaGlsZHJlbi5maWx0ZXIoZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHg7IH0pO1xuICAgICAgICBmb3IgKGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgICAgIGlmIChpcy5wcmltaXRpdmUoY2hpbGRyZW5baV0pKSB7XG4gICAgICAgICAgICAgICAgY2hpbGRyZW5baV0gPSB2bm9kZSh1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBjaGlsZHJlbltpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKHNlbFswXSA9PT0gJ3MnICYmIHNlbFsxXSA9PT0gJ3YnICYmIHNlbFsyXSA9PT0gJ2cnKSB7XG4gICAgICAgIGFkZE5TKGRhdGEsIGNoaWxkcmVuKTtcbiAgICB9XG4gICAgcmV0dXJuIHZub2RlKHNlbCwgZGF0YSwgY2hpbGRyZW4sIHRleHQsIHVuZGVmaW5lZCk7XG59XG5leHBvcnRzLmggPSBoO1xuO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aHlwZXJzY3JpcHQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgdGh1bmsgPSByZXF1aXJlKCdzbmFiYmRvbS90aHVuaycpO1xuZXhwb3J0cy50aHVuayA9IHRodW5rO1xudmFyIG1ha2VET01Ecml2ZXJfMSA9IHJlcXVpcmUoJy4vbWFrZURPTURyaXZlcicpO1xuZXhwb3J0cy5tYWtlRE9NRHJpdmVyID0gbWFrZURPTURyaXZlcl8xLm1ha2VET01Ecml2ZXI7XG52YXIgbWFrZUhUTUxEcml2ZXJfMSA9IHJlcXVpcmUoJy4vbWFrZUhUTUxEcml2ZXInKTtcbmV4cG9ydHMubWFrZUhUTUxEcml2ZXIgPSBtYWtlSFRNTERyaXZlcl8xLm1ha2VIVE1MRHJpdmVyO1xudmFyIG1vY2tET01Tb3VyY2VfMSA9IHJlcXVpcmUoJy4vbW9ja0RPTVNvdXJjZScpO1xuZXhwb3J0cy5tb2NrRE9NU291cmNlID0gbW9ja0RPTVNvdXJjZV8xLm1vY2tET01Tb3VyY2U7XG52YXIgaHlwZXJzY3JpcHRfMSA9IHJlcXVpcmUoJy4vaHlwZXJzY3JpcHQnKTtcbmV4cG9ydHMuaCA9IGh5cGVyc2NyaXB0XzEuaDtcbnZhciBoeXBlcnNjcmlwdF9oZWxwZXJzXzEgPSByZXF1aXJlKCcuL2h5cGVyc2NyaXB0LWhlbHBlcnMnKTtcbmV4cG9ydHMuc3ZnID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuc3ZnO1xuZXhwb3J0cy5hID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuYTtcbmV4cG9ydHMuYWJiciA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LmFiYnI7XG5leHBvcnRzLmFkZHJlc3MgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5hZGRyZXNzO1xuZXhwb3J0cy5hcmVhID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuYXJlYTtcbmV4cG9ydHMuYXJ0aWNsZSA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LmFydGljbGU7XG5leHBvcnRzLmFzaWRlID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuYXNpZGU7XG5leHBvcnRzLmF1ZGlvID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuYXVkaW87XG5leHBvcnRzLmIgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5iO1xuZXhwb3J0cy5iYXNlID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuYmFzZTtcbmV4cG9ydHMuYmRpID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuYmRpO1xuZXhwb3J0cy5iZG8gPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5iZG87XG5leHBvcnRzLmJsb2NrcXVvdGUgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5ibG9ja3F1b3RlO1xuZXhwb3J0cy5ib2R5ID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuYm9keTtcbmV4cG9ydHMuYnIgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5icjtcbmV4cG9ydHMuYnV0dG9uID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuYnV0dG9uO1xuZXhwb3J0cy5jYW52YXMgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5jYW52YXM7XG5leHBvcnRzLmNhcHRpb24gPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5jYXB0aW9uO1xuZXhwb3J0cy5jaXRlID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuY2l0ZTtcbmV4cG9ydHMuY29kZSA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LmNvZGU7XG5leHBvcnRzLmNvbCA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LmNvbDtcbmV4cG9ydHMuY29sZ3JvdXAgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5jb2xncm91cDtcbmV4cG9ydHMuZGQgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5kZDtcbmV4cG9ydHMuZGVsID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuZGVsO1xuZXhwb3J0cy5kZm4gPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5kZm47XG5leHBvcnRzLmRpciA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LmRpcjtcbmV4cG9ydHMuZGl2ID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuZGl2O1xuZXhwb3J0cy5kbCA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LmRsO1xuZXhwb3J0cy5kdCA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LmR0O1xuZXhwb3J0cy5lbSA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LmVtO1xuZXhwb3J0cy5lbWJlZCA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LmVtYmVkO1xuZXhwb3J0cy5maWVsZHNldCA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LmZpZWxkc2V0O1xuZXhwb3J0cy5maWdjYXB0aW9uID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuZmlnY2FwdGlvbjtcbmV4cG9ydHMuZmlndXJlID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuZmlndXJlO1xuZXhwb3J0cy5mb290ZXIgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5mb290ZXI7XG5leHBvcnRzLmZvcm0gPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5mb3JtO1xuZXhwb3J0cy5oMSA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LmgxO1xuZXhwb3J0cy5oMiA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LmgyO1xuZXhwb3J0cy5oMyA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LmgzO1xuZXhwb3J0cy5oNCA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0Lmg0O1xuZXhwb3J0cy5oNSA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0Lmg1O1xuZXhwb3J0cy5oNiA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0Lmg2O1xuZXhwb3J0cy5oZWFkID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuaGVhZDtcbmV4cG9ydHMuaGVhZGVyID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuaGVhZGVyO1xuZXhwb3J0cy5oZ3JvdXAgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5oZ3JvdXA7XG5leHBvcnRzLmhyID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuaHI7XG5leHBvcnRzLmh0bWwgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5odG1sO1xuZXhwb3J0cy5pID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuaTtcbmV4cG9ydHMuaWZyYW1lID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuaWZyYW1lO1xuZXhwb3J0cy5pbWcgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5pbWc7XG5leHBvcnRzLmlucHV0ID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuaW5wdXQ7XG5leHBvcnRzLmlucyA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LmlucztcbmV4cG9ydHMua2JkID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQua2JkO1xuZXhwb3J0cy5rZXlnZW4gPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5rZXlnZW47XG5leHBvcnRzLmxhYmVsID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQubGFiZWw7XG5leHBvcnRzLmxlZ2VuZCA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LmxlZ2VuZDtcbmV4cG9ydHMubGkgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5saTtcbmV4cG9ydHMubGluayA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0Lmxpbms7XG5leHBvcnRzLm1haW4gPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5tYWluO1xuZXhwb3J0cy5tYXAgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5tYXA7XG5leHBvcnRzLm1hcmsgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5tYXJrO1xuZXhwb3J0cy5tZW51ID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQubWVudTtcbmV4cG9ydHMubWV0YSA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0Lm1ldGE7XG5leHBvcnRzLm5hdiA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0Lm5hdjtcbmV4cG9ydHMubm9zY3JpcHQgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5ub3NjcmlwdDtcbmV4cG9ydHMub2JqZWN0ID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQub2JqZWN0O1xuZXhwb3J0cy5vbCA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0Lm9sO1xuZXhwb3J0cy5vcHRncm91cCA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0Lm9wdGdyb3VwO1xuZXhwb3J0cy5vcHRpb24gPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5vcHRpb247XG5leHBvcnRzLnAgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5wO1xuZXhwb3J0cy5wYXJhbSA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LnBhcmFtO1xuZXhwb3J0cy5wcmUgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5wcmU7XG5leHBvcnRzLnByb2dyZXNzID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQucHJvZ3Jlc3M7XG5leHBvcnRzLnEgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5xO1xuZXhwb3J0cy5ycCA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LnJwO1xuZXhwb3J0cy5ydCA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LnJ0O1xuZXhwb3J0cy5ydWJ5ID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQucnVieTtcbmV4cG9ydHMucyA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LnM7XG5leHBvcnRzLnNhbXAgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5zYW1wO1xuZXhwb3J0cy5zY3JpcHQgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5zY3JpcHQ7XG5leHBvcnRzLnNlY3Rpb24gPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5zZWN0aW9uO1xuZXhwb3J0cy5zZWxlY3QgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5zZWxlY3Q7XG5leHBvcnRzLnNtYWxsID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuc21hbGw7XG5leHBvcnRzLnNvdXJjZSA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LnNvdXJjZTtcbmV4cG9ydHMuc3BhbiA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LnNwYW47XG5leHBvcnRzLnN0cm9uZyA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LnN0cm9uZztcbmV4cG9ydHMuc3R5bGUgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5zdHlsZTtcbmV4cG9ydHMuc3ViID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQuc3ViO1xuZXhwb3J0cy5zdXAgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC5zdXA7XG5leHBvcnRzLnRhYmxlID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQudGFibGU7XG5leHBvcnRzLnRib2R5ID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQudGJvZHk7XG5leHBvcnRzLnRkID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQudGQ7XG5leHBvcnRzLnRleHRhcmVhID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQudGV4dGFyZWE7XG5leHBvcnRzLnRmb290ID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQudGZvb3Q7XG5leHBvcnRzLnRoID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQudGg7XG5leHBvcnRzLnRoZWFkID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQudGhlYWQ7XG5leHBvcnRzLnRpdGxlID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQudGl0bGU7XG5leHBvcnRzLnRyID0gaHlwZXJzY3JpcHRfaGVscGVyc18xLmRlZmF1bHQudHI7XG5leHBvcnRzLnUgPSBoeXBlcnNjcmlwdF9oZWxwZXJzXzEuZGVmYXVsdC51O1xuZXhwb3J0cy51bCA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LnVsO1xuZXhwb3J0cy52aWRlbyA9IGh5cGVyc2NyaXB0X2hlbHBlcnNfMS5kZWZhdWx0LnZpZGVvO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgdXRpbHNfMSA9IHJlcXVpcmUoJy4vdXRpbHMnKTtcbmZ1bmN0aW9uIGlzb2xhdGVTb3VyY2Uoc291cmNlLCBzY29wZSkge1xuICAgIHJldHVybiBzb3VyY2Uuc2VsZWN0KHV0aWxzXzEuU0NPUEVfUFJFRklYICsgc2NvcGUpO1xufVxuZXhwb3J0cy5pc29sYXRlU291cmNlID0gaXNvbGF0ZVNvdXJjZTtcbmZ1bmN0aW9uIGlzb2xhdGVTaW5rKHNpbmssIHNjb3BlKSB7XG4gICAgcmV0dXJuIHNpbmsubWFwKGZ1bmN0aW9uICh2VHJlZSkge1xuICAgICAgICBpZiAodlRyZWUuZGF0YS5pc29sYXRlKSB7XG4gICAgICAgICAgICB2YXIgZXhpc3RpbmdTY29wZSA9IHBhcnNlSW50KHZUcmVlLmRhdGEuaXNvbGF0ZS5zcGxpdCh1dGlsc18xLlNDT1BFX1BSRUZJWCArICdjeWNsZScpWzFdKTtcbiAgICAgICAgICAgIHZhciBfc2NvcGUgPSBwYXJzZUludChzY29wZS5zcGxpdCgnY3ljbGUnKVsxXSk7XG4gICAgICAgICAgICBpZiAoTnVtYmVyLmlzTmFOKGV4aXN0aW5nU2NvcGUpIHx8XG4gICAgICAgICAgICAgICAgTnVtYmVyLmlzTmFOKF9zY29wZSkgfHxcbiAgICAgICAgICAgICAgICBleGlzdGluZ1Njb3BlID4gX3Njb3BlKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHZUcmVlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHZUcmVlLmRhdGEuaXNvbGF0ZSA9IHV0aWxzXzEuU0NPUEVfUFJFRklYICsgc2NvcGU7XG4gICAgICAgIHJldHVybiB2VHJlZTtcbiAgICB9KTtcbn1cbmV4cG9ydHMuaXNvbGF0ZVNpbmsgPSBpc29sYXRlU2luaztcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzb2xhdGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgSXNvbGF0ZU1vZHVsZSA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gSXNvbGF0ZU1vZHVsZShpc29sYXRlZEVsZW1lbnRzKSB7XG4gICAgICAgIHRoaXMuaXNvbGF0ZWRFbGVtZW50cyA9IGlzb2xhdGVkRWxlbWVudHM7XG4gICAgICAgIHRoaXMuZXZlbnREZWxlZ2F0b3JzID0gbmV3IE1hcCgpO1xuICAgIH1cbiAgICBJc29sYXRlTW9kdWxlLnByb3RvdHlwZS5zZXRTY29wZSA9IGZ1bmN0aW9uIChlbG0sIHNjb3BlKSB7XG4gICAgICAgIHRoaXMuaXNvbGF0ZWRFbGVtZW50cy5zZXQoc2NvcGUsIGVsbSk7XG4gICAgfTtcbiAgICBJc29sYXRlTW9kdWxlLnByb3RvdHlwZS5yZW1vdmVTY29wZSA9IGZ1bmN0aW9uIChzY29wZSkge1xuICAgICAgICB0aGlzLmlzb2xhdGVkRWxlbWVudHMuZGVsZXRlKHNjb3BlKTtcbiAgICB9O1xuICAgIElzb2xhdGVNb2R1bGUucHJvdG90eXBlLmdldElzb2xhdGVkRWxlbWVudCA9IGZ1bmN0aW9uIChzY29wZSkge1xuICAgICAgICByZXR1cm4gdGhpcy5pc29sYXRlZEVsZW1lbnRzLmdldChzY29wZSk7XG4gICAgfTtcbiAgICBJc29sYXRlTW9kdWxlLnByb3RvdHlwZS5pc0lzb2xhdGVkRWxlbWVudCA9IGZ1bmN0aW9uIChlbG0pIHtcbiAgICAgICAgdmFyIGVsZW1lbnRzID0gQXJyYXkuZnJvbSh0aGlzLmlzb2xhdGVkRWxlbWVudHMuZW50cmllcygpKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7ICsraSkge1xuICAgICAgICAgICAgaWYgKGVsbSA9PT0gZWxlbWVudHNbaV1bMV0pIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZWxlbWVudHNbaV1bMF07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH07XG4gICAgSXNvbGF0ZU1vZHVsZS5wcm90b3R5cGUuYWRkRXZlbnREZWxlZ2F0b3IgPSBmdW5jdGlvbiAoc2NvcGUsIGV2ZW50RGVsZWdhdG9yKSB7XG4gICAgICAgIHZhciBkZWxlZ2F0b3JzID0gdGhpcy5ldmVudERlbGVnYXRvcnMuZ2V0KHNjb3BlKTtcbiAgICAgICAgaWYgKCFkZWxlZ2F0b3JzKSB7XG4gICAgICAgICAgICBkZWxlZ2F0b3JzID0gW107XG4gICAgICAgICAgICB0aGlzLmV2ZW50RGVsZWdhdG9ycy5zZXQoc2NvcGUsIGRlbGVnYXRvcnMpO1xuICAgICAgICB9XG4gICAgICAgIGRlbGVnYXRvcnNbZGVsZWdhdG9ycy5sZW5ndGhdID0gZXZlbnREZWxlZ2F0b3I7XG4gICAgfTtcbiAgICBJc29sYXRlTW9kdWxlLnByb3RvdHlwZS5yZXNldCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5pc29sYXRlZEVsZW1lbnRzLmNsZWFyKCk7XG4gICAgfTtcbiAgICBJc29sYXRlTW9kdWxlLnByb3RvdHlwZS5jcmVhdGVNb2R1bGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIGNyZWF0ZTogZnVuY3Rpb24gKG9sZFZOb2RlLCB2Tm9kZSkge1xuICAgICAgICAgICAgICAgIHZhciBfYSA9IG9sZFZOb2RlLmRhdGEsIG9sZERhdGEgPSBfYSA9PT0gdm9pZCAwID8ge30gOiBfYTtcbiAgICAgICAgICAgICAgICB2YXIgZWxtID0gdk5vZGUuZWxtLCBfYiA9IHZOb2RlLmRhdGEsIGRhdGEgPSBfYiA9PT0gdm9pZCAwID8ge30gOiBfYjtcbiAgICAgICAgICAgICAgICB2YXIgb2xkU2NvcGUgPSBvbGREYXRhLmlzb2xhdGUgfHwgXCJcIjtcbiAgICAgICAgICAgICAgICB2YXIgc2NvcGUgPSBkYXRhLmlzb2xhdGUgfHwgXCJcIjtcbiAgICAgICAgICAgICAgICBpZiAoc2NvcGUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9sZFNjb3BlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzZWxmLnJlbW92ZVNjb3BlKG9sZFNjb3BlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBzZWxmLnNldFNjb3BlKGVsbSwgc2NvcGUpO1xuICAgICAgICAgICAgICAgICAgICB2YXIgZGVsZWdhdG9ycyA9IHNlbGYuZXZlbnREZWxlZ2F0b3JzLmdldChzY29wZSk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChkZWxlZ2F0b3JzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gZGVsZWdhdG9ycy5sZW5ndGg7IGkgPCBsZW47ICsraSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlbGVnYXRvcnNbaV0udXBkYXRlVG9wRWxlbWVudChlbG0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGRlbGVnYXRvcnMgPT09IHZvaWQgMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5ldmVudERlbGVnYXRvcnMuc2V0KHNjb3BlLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKG9sZFNjb3BlICYmICFzY29wZSkge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLnJlbW92ZVNjb3BlKHNjb3BlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgdXBkYXRlOiBmdW5jdGlvbiAob2xkVk5vZGUsIHZOb2RlKSB7XG4gICAgICAgICAgICAgICAgdmFyIF9hID0gb2xkVk5vZGUuZGF0YSwgb2xkRGF0YSA9IF9hID09PSB2b2lkIDAgPyB7fSA6IF9hO1xuICAgICAgICAgICAgICAgIHZhciBlbG0gPSB2Tm9kZS5lbG0sIF9iID0gdk5vZGUuZGF0YSwgZGF0YSA9IF9iID09PSB2b2lkIDAgPyB7fSA6IF9iO1xuICAgICAgICAgICAgICAgIHZhciBvbGRTY29wZSA9IG9sZERhdGEuaXNvbGF0ZSB8fCBcIlwiO1xuICAgICAgICAgICAgICAgIHZhciBzY29wZSA9IGRhdGEuaXNvbGF0ZSB8fCBcIlwiO1xuICAgICAgICAgICAgICAgIGlmIChzY29wZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAob2xkU2NvcGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYucmVtb3ZlU2NvcGUob2xkU2NvcGUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHNlbGYuc2V0U2NvcGUoZWxtLCBzY29wZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGlmIChvbGRTY29wZSAmJiAhc2NvcGUpIHtcbiAgICAgICAgICAgICAgICAgICAgc2VsZi5yZW1vdmVTY29wZShzY29wZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHJlbW92ZTogZnVuY3Rpb24gKF9hLCBjYikge1xuICAgICAgICAgICAgICAgIHZhciBkYXRhID0gX2EuZGF0YTtcbiAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSB8fCB7fTtcbiAgICAgICAgICAgICAgICB2YXIgc2NvcGUgPSBkYXRhLmlzb2xhdGU7XG4gICAgICAgICAgICAgICAgaWYgKHNjb3BlKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYucmVtb3ZlU2NvcGUoc2NvcGUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5ldmVudERlbGVnYXRvcnMuZ2V0KHNjb3BlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5ldmVudERlbGVnYXRvcnMuc2V0KHNjb3BlLCBbXSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2IoKTtcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBkZXN0cm95OiBmdW5jdGlvbiAoX2EpIHtcbiAgICAgICAgICAgICAgICB2YXIgZGF0YSA9IF9hLmRhdGE7XG4gICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEgfHwge307XG4gICAgICAgICAgICAgICAgdmFyIHNjb3BlID0gZGF0YS5pc29sYXRlO1xuICAgICAgICAgICAgICAgIGlmIChzY29wZSkge1xuICAgICAgICAgICAgICAgICAgICBzZWxmLnJlbW92ZVNjb3BlKHNjb3BlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlbGYuZXZlbnREZWxlZ2F0b3JzLmdldChzY29wZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYuZXZlbnREZWxlZ2F0b3JzLnNldChzY29wZSwgW10pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIElzb2xhdGVNb2R1bGU7XG59KCkpO1xuZXhwb3J0cy5Jc29sYXRlTW9kdWxlID0gSXNvbGF0ZU1vZHVsZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWlzb2xhdGVNb2R1bGUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgc25hYmJkb21fMSA9IHJlcXVpcmUoJ3NuYWJiZG9tJyk7XG52YXIgeHN0cmVhbV8xID0gcmVxdWlyZSgneHN0cmVhbScpO1xudmFyIE1haW5ET01Tb3VyY2VfMSA9IHJlcXVpcmUoJy4vTWFpbkRPTVNvdXJjZScpO1xudmFyIFZOb2RlV3JhcHBlcl8xID0gcmVxdWlyZSgnLi9WTm9kZVdyYXBwZXInKTtcbnZhciB1dGlsc18xID0gcmVxdWlyZSgnLi91dGlscycpO1xudmFyIG1vZHVsZXNfMSA9IHJlcXVpcmUoJy4vbW9kdWxlcycpO1xudmFyIGlzb2xhdGVNb2R1bGVfMSA9IHJlcXVpcmUoJy4vaXNvbGF0ZU1vZHVsZScpO1xudmFyIHRyYW5zcG9zaXRpb25fMSA9IHJlcXVpcmUoJy4vdHJhbnNwb3NpdGlvbicpO1xudmFyIHhzdHJlYW1fYWRhcHRlcl8xID0gcmVxdWlyZSgnQGN5Y2xlL3hzdHJlYW0tYWRhcHRlcicpO1xuZnVuY3Rpb24gbWFrZURPTURyaXZlcklucHV0R3VhcmQobW9kdWxlcykge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShtb2R1bGVzKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJPcHRpb25hbCBtb2R1bGVzIG9wdGlvbiBtdXN0IGJlIFwiICtcbiAgICAgICAgICAgIFwiYW4gYXJyYXkgZm9yIHNuYWJiZG9tIG1vZHVsZXNcIik7XG4gICAgfVxufVxuZnVuY3Rpb24gZG9tRHJpdmVySW5wdXRHdWFyZCh2aWV3JCkge1xuICAgIGlmICghdmlldyRcbiAgICAgICAgfHwgdHlwZW9mIHZpZXckLmFkZExpc3RlbmVyICE9PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgfHwgdHlwZW9mIHZpZXckLmZvbGQgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUaGUgRE9NIGRyaXZlciBmdW5jdGlvbiBleHBlY3RzIGFzIGlucHV0IGEgU3RyZWFtIG9mIFwiICtcbiAgICAgICAgICAgIFwidmlydHVhbCBET00gZWxlbWVudHNcIik7XG4gICAgfVxufVxuZnVuY3Rpb24gbWFrZURPTURyaXZlcihjb250YWluZXIsIG9wdGlvbnMpIHtcbiAgICBpZiAoIW9wdGlvbnMpIHtcbiAgICAgICAgb3B0aW9ucyA9IHt9O1xuICAgIH1cbiAgICB2YXIgdHJhbnNwb3NpdGlvbiA9IG9wdGlvbnMudHJhbnNwb3NpdGlvbiB8fCBmYWxzZTtcbiAgICB2YXIgbW9kdWxlcyA9IG9wdGlvbnMubW9kdWxlcyB8fCBtb2R1bGVzXzEuZGVmYXVsdDtcbiAgICB2YXIgaXNvbGF0ZU1vZHVsZSA9IG5ldyBpc29sYXRlTW9kdWxlXzEuSXNvbGF0ZU1vZHVsZSgobmV3IE1hcCgpKSk7XG4gICAgdmFyIHBhdGNoID0gc25hYmJkb21fMS5pbml0KFtpc29sYXRlTW9kdWxlLmNyZWF0ZU1vZHVsZSgpXS5jb25jYXQobW9kdWxlcykpO1xuICAgIHZhciByb290RWxlbWVudCA9IHV0aWxzXzEuZ2V0RWxlbWVudChjb250YWluZXIpO1xuICAgIHZhciB2bm9kZVdyYXBwZXIgPSBuZXcgVk5vZGVXcmFwcGVyXzEuVk5vZGVXcmFwcGVyKHJvb3RFbGVtZW50KTtcbiAgICB2YXIgZGVsZWdhdG9ycyA9IG5ldyBNYXAoKTtcbiAgICBtYWtlRE9NRHJpdmVySW5wdXRHdWFyZChtb2R1bGVzKTtcbiAgICBmdW5jdGlvbiBET01Ecml2ZXIodm5vZGUkLCBydW5TdHJlYW1BZGFwdGVyKSB7XG4gICAgICAgIGRvbURyaXZlcklucHV0R3VhcmQodm5vZGUkKTtcbiAgICAgICAgdmFyIHRyYW5zcG9zZVZOb2RlID0gdHJhbnNwb3NpdGlvbl8xLm1ha2VUcmFuc3Bvc2VWTm9kZShydW5TdHJlYW1BZGFwdGVyKTtcbiAgICAgICAgdmFyIHByZXByb2Nlc3NlZFZOb2RlJCA9ICh0cmFuc3Bvc2l0aW9uID8gdm5vZGUkLm1hcCh0cmFuc3Bvc2VWTm9kZSkuZmxhdHRlbigpIDogdm5vZGUkKTtcbiAgICAgICAgdmFyIHJvb3RFbGVtZW50JCA9IHByZXByb2Nlc3NlZFZOb2RlJFxuICAgICAgICAgICAgLm1hcChmdW5jdGlvbiAodm5vZGUpIHsgcmV0dXJuIHZub2RlV3JhcHBlci5jYWxsKHZub2RlKTsgfSlcbiAgICAgICAgICAgIC5mb2xkKHBhdGNoLCByb290RWxlbWVudClcbiAgICAgICAgICAgIC5kcm9wKDEpXG4gICAgICAgICAgICAubWFwKGZ1bmN0aW9uIHVud3JhcEVsZW1lbnRGcm9tVk5vZGUodm5vZGUpIHsgcmV0dXJuIHZub2RlLmVsbTsgfSlcbiAgICAgICAgICAgIC5jb21wb3NlKGZ1bmN0aW9uIChzdHJlYW0pIHsgcmV0dXJuIHhzdHJlYW1fMS5kZWZhdWx0Lm1lcmdlKHN0cmVhbSwgeHN0cmVhbV8xLmRlZmF1bHQubmV2ZXIoKSk7IH0pIC8vIGRvbid0IGNvbXBsZXRlIHRoaXMgc3RyZWFtXG4gICAgICAgICAgICAuc3RhcnRXaXRoKHJvb3RFbGVtZW50KTtcbiAgICAgICAgLyogdHNsaW50OmRpc2FibGU6bm8tZW1wdHkgKi9cbiAgICAgICAgcm9vdEVsZW1lbnQkLmFkZExpc3RlbmVyKHsgbmV4dDogZnVuY3Rpb24gKCkgeyB9LCBlcnJvcjogZnVuY3Rpb24gKCkgeyB9LCBjb21wbGV0ZTogZnVuY3Rpb24gKCkgeyB9IH0pO1xuICAgICAgICAvKiB0c2xpbnQ6ZW5hYmxlOm5vLWVtcHR5ICovXG4gICAgICAgIHJldHVybiBuZXcgTWFpbkRPTVNvdXJjZV8xLk1haW5ET01Tb3VyY2Uocm9vdEVsZW1lbnQkLCBydW5TdHJlYW1BZGFwdGVyLCBbXSwgaXNvbGF0ZU1vZHVsZSwgZGVsZWdhdG9ycyk7XG4gICAgfVxuICAgIDtcbiAgICBET01Ecml2ZXIuc3RyZWFtQWRhcHRlciA9IHhzdHJlYW1fYWRhcHRlcl8xLmRlZmF1bHQ7XG4gICAgcmV0dXJuIERPTURyaXZlcjtcbn1cbmV4cG9ydHMubWFrZURPTURyaXZlciA9IG1ha2VET01Ecml2ZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1tYWtlRE9NRHJpdmVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xudmFyIHhzdHJlYW1fYWRhcHRlcl8xID0gcmVxdWlyZSgnQGN5Y2xlL3hzdHJlYW0tYWRhcHRlcicpO1xudmFyIHRyYW5zcG9zaXRpb25fMSA9IHJlcXVpcmUoJy4vdHJhbnNwb3NpdGlvbicpO1xudmFyIEhUTUxTb3VyY2VfMSA9IHJlcXVpcmUoJy4vSFRNTFNvdXJjZScpO1xudmFyIHRvSFRNTCA9IHJlcXVpcmUoJ3NuYWJiZG9tLXRvLWh0bWwnKTtcbi8qIHRzbGludDpkaXNhYmxlOm5vLWVtcHR5ICovXG52YXIgbm9vcCA9IGZ1bmN0aW9uICgpIHsgfTtcbi8qIHRzbGludDplbmFibGU6bm8tZW1wdHkgKi9cbmZ1bmN0aW9uIG1ha2VIVE1MRHJpdmVyKGVmZmVjdCwgb3B0aW9ucykge1xuICAgIGlmICghb3B0aW9ucykge1xuICAgICAgICBvcHRpb25zID0ge307XG4gICAgfVxuICAgIHZhciB0cmFuc3Bvc2l0aW9uID0gb3B0aW9ucy50cmFuc3Bvc2l0aW9uIHx8IGZhbHNlO1xuICAgIGZ1bmN0aW9uIGh0bWxEcml2ZXIodm5vZGUkLCBydW5TdHJlYW1BZGFwdGVyKSB7XG4gICAgICAgIHZhciB0cmFuc3Bvc2VWTm9kZSA9IHRyYW5zcG9zaXRpb25fMS5tYWtlVHJhbnNwb3NlVk5vZGUocnVuU3RyZWFtQWRhcHRlcik7XG4gICAgICAgIHZhciBwcmVwcm9jZXNzZWRWTm9kZSQgPSAodHJhbnNwb3NpdGlvbiA/IHZub2RlJC5tYXAodHJhbnNwb3NlVk5vZGUpLmZsYXR0ZW4oKSA6IHZub2RlJCk7XG4gICAgICAgIHZhciBodG1sJCA9IHByZXByb2Nlc3NlZFZOb2RlJC5sYXN0KCkubWFwKHRvSFRNTCk7XG4gICAgICAgIGh0bWwkLmFkZExpc3RlbmVyKHtcbiAgICAgICAgICAgIG5leHQ6IGVmZmVjdCB8fCBub29wLFxuICAgICAgICAgICAgZXJyb3I6IG5vb3AsXG4gICAgICAgICAgICBjb21wbGV0ZTogbm9vcCxcbiAgICAgICAgfSk7XG4gICAgICAgIHJldHVybiBuZXcgSFRNTFNvdXJjZV8xLkhUTUxTb3VyY2UoaHRtbCQsIHJ1blN0cmVhbUFkYXB0ZXIpO1xuICAgIH1cbiAgICA7XG4gICAgaHRtbERyaXZlci5zdHJlYW1BZGFwdGVyID0geHN0cmVhbV9hZGFwdGVyXzEuZGVmYXVsdDtcbiAgICByZXR1cm4gaHRtbERyaXZlcjtcbn1cbmV4cG9ydHMubWFrZUhUTUxEcml2ZXIgPSBtYWtlSFRNTERyaXZlcjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1ha2VIVE1MRHJpdmVyLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xudmFyIHhzdHJlYW1fYWRhcHRlcl8xID0gcmVxdWlyZSgnQGN5Y2xlL3hzdHJlYW0tYWRhcHRlcicpO1xudmFyIHhzdHJlYW1fMSA9IHJlcXVpcmUoJ3hzdHJlYW0nKTtcbnZhciBNb2NrZWRET01Tb3VyY2UgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIE1vY2tlZERPTVNvdXJjZShfc3RyZWFtQWRhcHRlciwgX21vY2tDb25maWcpIHtcbiAgICAgICAgdGhpcy5fc3RyZWFtQWRhcHRlciA9IF9zdHJlYW1BZGFwdGVyO1xuICAgICAgICB0aGlzLl9tb2NrQ29uZmlnID0gX21vY2tDb25maWc7XG4gICAgICAgIGlmIChfbW9ja0NvbmZpZy5lbGVtZW50cykge1xuICAgICAgICAgICAgdGhpcy5fZWxlbWVudHMgPSBfbW9ja0NvbmZpZy5lbGVtZW50cztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuX2VsZW1lbnRzID0gX3N0cmVhbUFkYXB0ZXIuYWRhcHQoeHN0cmVhbV8xLmRlZmF1bHQuZW1wdHkoKSwgeHN0cmVhbV9hZGFwdGVyXzEuZGVmYXVsdC5zdHJlYW1TdWJzY3JpYmUpO1xuICAgICAgICB9XG4gICAgfVxuICAgIE1vY2tlZERPTVNvdXJjZS5wcm90b3R5cGUuZWxlbWVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9lbGVtZW50cztcbiAgICB9O1xuICAgIE1vY2tlZERPTVNvdXJjZS5wcm90b3R5cGUuZXZlbnRzID0gZnVuY3Rpb24gKGV2ZW50VHlwZSwgb3B0aW9ucykge1xuICAgICAgICB2YXIgbW9ja0NvbmZpZyA9IHRoaXMuX21vY2tDb25maWc7XG4gICAgICAgIHZhciBrZXlzID0gT2JqZWN0LmtleXMobW9ja0NvbmZpZyk7XG4gICAgICAgIHZhciBrZXlzTGVuID0ga2V5cy5sZW5ndGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5c0xlbjsgaSsrKSB7XG4gICAgICAgICAgICB2YXIga2V5ID0ga2V5c1tpXTtcbiAgICAgICAgICAgIGlmIChrZXkgPT09IGV2ZW50VHlwZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBtb2NrQ29uZmlnW2tleV07XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHRoaXMuX3N0cmVhbUFkYXB0ZXIuYWRhcHQoeHN0cmVhbV8xLmRlZmF1bHQuZW1wdHkoKSwgeHN0cmVhbV9hZGFwdGVyXzEuZGVmYXVsdC5zdHJlYW1TdWJzY3JpYmUpO1xuICAgIH07XG4gICAgTW9ja2VkRE9NU291cmNlLnByb3RvdHlwZS5zZWxlY3QgPSBmdW5jdGlvbiAoc2VsZWN0b3IpIHtcbiAgICAgICAgdmFyIG1vY2tDb25maWcgPSB0aGlzLl9tb2NrQ29uZmlnO1xuICAgICAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKG1vY2tDb25maWcpO1xuICAgICAgICB2YXIga2V5c0xlbiA9IGtleXMubGVuZ3RoO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXNMZW47IGkrKykge1xuICAgICAgICAgICAgdmFyIGtleSA9IGtleXNbaV07XG4gICAgICAgICAgICBpZiAoa2V5ID09PSBzZWxlY3Rvcikge1xuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgTW9ja2VkRE9NU291cmNlKHRoaXMuX3N0cmVhbUFkYXB0ZXIsIG1vY2tDb25maWdba2V5XSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBNb2NrZWRET01Tb3VyY2UodGhpcy5fc3RyZWFtQWRhcHRlciwge30pO1xuICAgIH07XG4gICAgcmV0dXJuIE1vY2tlZERPTVNvdXJjZTtcbn0oKSk7XG5leHBvcnRzLk1vY2tlZERPTVNvdXJjZSA9IE1vY2tlZERPTVNvdXJjZTtcbmZ1bmN0aW9uIG1vY2tET01Tb3VyY2Uoc3RyZWFtQWRhcHRlciwgbW9ja0NvbmZpZykge1xuICAgIHJldHVybiBuZXcgTW9ja2VkRE9NU291cmNlKHN0cmVhbUFkYXB0ZXIsIG1vY2tDb25maWcpO1xufVxuZXhwb3J0cy5tb2NrRE9NU291cmNlID0gbW9ja0RPTVNvdXJjZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1vY2tET01Tb3VyY2UuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgQ2xhc3NNb2R1bGUgPSByZXF1aXJlKCdzbmFiYmRvbS9tb2R1bGVzL2NsYXNzJyk7XG5leHBvcnRzLkNsYXNzTW9kdWxlID0gQ2xhc3NNb2R1bGU7XG52YXIgUHJvcHNNb2R1bGUgPSByZXF1aXJlKCdzbmFiYmRvbS9tb2R1bGVzL3Byb3BzJyk7XG5leHBvcnRzLlByb3BzTW9kdWxlID0gUHJvcHNNb2R1bGU7XG52YXIgQXR0cnNNb2R1bGUgPSByZXF1aXJlKCdzbmFiYmRvbS9tb2R1bGVzL2F0dHJpYnV0ZXMnKTtcbmV4cG9ydHMuQXR0cnNNb2R1bGUgPSBBdHRyc01vZHVsZTtcbnZhciBFdmVudHNNb2R1bGUgPSByZXF1aXJlKCdzbmFiYmRvbS9tb2R1bGVzL2V2ZW50bGlzdGVuZXJzJyk7XG5leHBvcnRzLkV2ZW50c01vZHVsZSA9IEV2ZW50c01vZHVsZTtcbnZhciBTdHlsZU1vZHVsZSA9IHJlcXVpcmUoJ3NuYWJiZG9tL21vZHVsZXMvc3R5bGUnKTtcbmV4cG9ydHMuU3R5bGVNb2R1bGUgPSBTdHlsZU1vZHVsZTtcbnZhciBIZXJvTW9kdWxlID0gcmVxdWlyZSgnc25hYmJkb20vbW9kdWxlcy9oZXJvJyk7XG5leHBvcnRzLkhlcm9Nb2R1bGUgPSBIZXJvTW9kdWxlO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gW1N0eWxlTW9kdWxlLCBDbGFzc01vZHVsZSwgUHJvcHNNb2R1bGUsIEF0dHJzTW9kdWxlXTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1vZHVsZXMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgeHN0cmVhbV9hZGFwdGVyXzEgPSByZXF1aXJlKCdAY3ljbGUveHN0cmVhbS1hZGFwdGVyJyk7XG52YXIgeHN0cmVhbV8xID0gcmVxdWlyZSgneHN0cmVhbScpO1xuZnVuY3Rpb24gY3JlYXRlVlRyZWUodm5vZGUsIGNoaWxkcmVuKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgICAgc2VsOiB2bm9kZS5zZWwsXG4gICAgICAgIGRhdGE6IHZub2RlLmRhdGEsXG4gICAgICAgIHRleHQ6IHZub2RlLnRleHQsXG4gICAgICAgIGVsbTogdm5vZGUuZWxtLFxuICAgICAgICBrZXk6IHZub2RlLmtleSxcbiAgICAgICAgY2hpbGRyZW46IGNoaWxkcmVuLFxuICAgIH07XG59XG5mdW5jdGlvbiBtYWtlVHJhbnNwb3NlVk5vZGUocnVuU3RyZWFtQWRhcHRlcikge1xuICAgIHJldHVybiBmdW5jdGlvbiB0cmFuc3Bvc2VWTm9kZSh2bm9kZSkge1xuICAgICAgICBpZiAoIXZub2RlKSB7XG4gICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh2bm9kZSAmJiB0eXBlb2Ygdm5vZGUuZGF0YSA9PT0gXCJvYmplY3RcIiAmJiB2bm9kZS5kYXRhLnN0YXRpYykge1xuICAgICAgICAgICAgcmV0dXJuIHhzdHJlYW1fMS5kZWZhdWx0Lm9mKHZub2RlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChydW5TdHJlYW1BZGFwdGVyLmlzVmFsaWRTdHJlYW0odm5vZGUpKSB7XG4gICAgICAgICAgICB2YXIgeHNTdHJlYW0gPSB4c3RyZWFtX2FkYXB0ZXJfMS5kZWZhdWx0LmFkYXB0KHZub2RlLCBydW5TdHJlYW1BZGFwdGVyLnN0cmVhbVN1YnNjcmliZSk7XG4gICAgICAgICAgICByZXR1cm4geHNTdHJlYW0ubWFwKHRyYW5zcG9zZVZOb2RlKS5mbGF0dGVuKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIHZub2RlID09PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICBpZiAoIXZub2RlLmNoaWxkcmVuIHx8IHZub2RlLmNoaWxkcmVuLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB4c3RyZWFtXzEuZGVmYXVsdC5vZih2bm9kZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgdm5vZGVDaGlsZHJlbiA9IHZub2RlLmNoaWxkcmVuXG4gICAgICAgICAgICAgICAgLm1hcCh0cmFuc3Bvc2VWTm9kZSlcbiAgICAgICAgICAgICAgICAuZmlsdGVyKGZ1bmN0aW9uICh4KSB7IHJldHVybiB4ICE9PSBudWxsOyB9KTtcbiAgICAgICAgICAgIGlmICh2bm9kZUNoaWxkcmVuLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB4c3RyZWFtXzEuZGVmYXVsdC5vZihjcmVhdGVWVHJlZSh2bm9kZSwgW10pKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHJldHVybiB4c3RyZWFtXzEuZGVmYXVsdC5jb21iaW5lLmFwcGx5KHhzdHJlYW1fMS5kZWZhdWx0LCB2bm9kZUNoaWxkcmVuKVxuICAgICAgICAgICAgICAgICAgICAubWFwKGZ1bmN0aW9uIChjaGlsZHJlbikgeyByZXR1cm4gY3JlYXRlVlRyZWUodm5vZGUsIGNoaWxkcmVuLnNsaWNlKCkpOyB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcIlVuaGFuZGxlZCB2VHJlZSBWYWx1ZVwiKTtcbiAgICAgICAgfVxuICAgIH07XG59XG5leHBvcnRzLm1ha2VUcmFuc3Bvc2VWTm9kZSA9IG1ha2VUcmFuc3Bvc2VWTm9kZTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXRyYW5zcG9zaXRpb24uanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5mdW5jdGlvbiBpc0VsZW1lbnQob2JqKSB7XG4gICAgcmV0dXJuIHR5cGVvZiBIVE1MRWxlbWVudCA9PT0gXCJvYmplY3RcIiA/XG4gICAgICAgIG9iaiBpbnN0YW5jZW9mIEhUTUxFbGVtZW50IHx8IG9iaiBpbnN0YW5jZW9mIERvY3VtZW50RnJhZ21lbnQgOlxuICAgICAgICBvYmogJiYgdHlwZW9mIG9iaiA9PT0gXCJvYmplY3RcIiAmJiBvYmogIT09IG51bGwgJiZcbiAgICAgICAgICAgIChvYmoubm9kZVR5cGUgPT09IDEgfHwgb2JqLm5vZGVUeXBlID09PSAxMSkgJiZcbiAgICAgICAgICAgIHR5cGVvZiBvYmoubm9kZU5hbWUgPT09IFwic3RyaW5nXCI7XG59XG5leHBvcnRzLlNDT1BFX1BSRUZJWCA9IFwiJCRDWUNMRURPTSQkLVwiO1xuZnVuY3Rpb24gZ2V0RWxlbWVudChzZWxlY3RvcnMpIHtcbiAgICB2YXIgZG9tRWxlbWVudCA9ICh0eXBlb2Ygc2VsZWN0b3JzID09PSBcInN0cmluZ1wiID9cbiAgICAgICAgZG9jdW1lbnQucXVlcnlTZWxlY3RvcihzZWxlY3RvcnMpIDpcbiAgICAgICAgc2VsZWN0b3JzKTtcbiAgICBpZiAodHlwZW9mIHNlbGVjdG9ycyA9PT0gXCJzdHJpbmdcIiAmJiBkb21FbGVtZW50ID09PSBudWxsKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkNhbm5vdCByZW5kZXIgaW50byB1bmtub3duIGVsZW1lbnQgYFwiICsgc2VsZWN0b3JzICsgXCJgXCIpO1xuICAgIH1cbiAgICBlbHNlIGlmICghaXNFbGVtZW50KGRvbUVsZW1lbnQpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkdpdmVuIGNvbnRhaW5lciBpcyBub3QgYSBET00gZWxlbWVudCBuZWl0aGVyIGEgXCIgK1xuICAgICAgICAgICAgXCJzZWxlY3RvciBzdHJpbmcuXCIpO1xuICAgIH1cbiAgICByZXR1cm4gZG9tRWxlbWVudDtcbn1cbmV4cG9ydHMuZ2V0RWxlbWVudCA9IGdldEVsZW1lbnQ7XG5mdW5jdGlvbiBnZXRTY29wZShuYW1lc3BhY2UpIHtcbiAgICByZXR1cm4gbmFtZXNwYWNlXG4gICAgICAgIC5maWx0ZXIoZnVuY3Rpb24gKGMpIHsgcmV0dXJuIGMuaW5kZXhPZihleHBvcnRzLlNDT1BFX1BSRUZJWCkgPiAtMTsgfSlcbiAgICAgICAgLnNsaWNlKC0xKSAvLyBvbmx5IG5lZWQgdGhlIGxhdGVzdCwgbW9zdCBzcGVjaWZpYywgaXNvbGF0ZWQgYm91bmRhcnlcbiAgICAgICAgLmpvaW4oXCJcIik7XG59XG5leHBvcnRzLmdldFNjb3BlID0gZ2V0U2NvcGU7XG5mdW5jdGlvbiBnZXRTZWxlY3RvcnMobmFtZXNwYWNlKSB7XG4gICAgcmV0dXJuIG5hbWVzcGFjZS5maWx0ZXIoZnVuY3Rpb24gKGMpIHsgcmV0dXJuIGMuaW5kZXhPZihleHBvcnRzLlNDT1BFX1BSRUZJWCkgPT09IC0xOyB9KS5qb2luKFwiIFwiKTtcbn1cbmV4cG9ydHMuZ2V0U2VsZWN0b3JzID0gZ2V0U2VsZWN0b3JzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9dXRpbHMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgeHN0cmVhbV8xID0gcmVxdWlyZSgneHN0cmVhbScpO1xudmFyIFhTdHJlYW1BZGFwdGVyID0ge1xuICAgIGFkYXB0OiBmdW5jdGlvbiAob3JpZ2luU3RyZWFtLCBvcmlnaW5TdHJlYW1TdWJzY3JpYmUpIHtcbiAgICAgICAgaWYgKFhTdHJlYW1BZGFwdGVyLmlzVmFsaWRTdHJlYW0ob3JpZ2luU3RyZWFtKSkge1xuICAgICAgICAgICAgcmV0dXJuIG9yaWdpblN0cmVhbTtcbiAgICAgICAgfVxuICAgICAgICA7XG4gICAgICAgIHZhciBkaXNwb3NlID0gbnVsbDtcbiAgICAgICAgcmV0dXJuIHhzdHJlYW1fMS5kZWZhdWx0LmNyZWF0ZSh7XG4gICAgICAgICAgICBzdGFydDogZnVuY3Rpb24gKG91dCkge1xuICAgICAgICAgICAgICAgIHZhciBvYnNlcnZlciA9IG91dDtcbiAgICAgICAgICAgICAgICBkaXNwb3NlID0gb3JpZ2luU3RyZWFtU3Vic2NyaWJlKG9yaWdpblN0cmVhbSwgb2JzZXJ2ZXIpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHN0b3A6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIGRpc3Bvc2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgZGlzcG9zZSgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfSxcbiAgICBtYWtlU3ViamVjdDogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc3RyZWFtID0geHN0cmVhbV8xLmRlZmF1bHQuY3JlYXRlKCk7XG4gICAgICAgIHZhciBvYnNlcnZlciA9IHtcbiAgICAgICAgICAgIG5leHQ6IGZ1bmN0aW9uICh4KSB7IHN0cmVhbS5zaGFtZWZ1bGx5U2VuZE5leHQoeCk7IH0sXG4gICAgICAgICAgICBlcnJvcjogZnVuY3Rpb24gKGVycikgeyBzdHJlYW0uc2hhbWVmdWxseVNlbmRFcnJvcihlcnIpOyB9LFxuICAgICAgICAgICAgY29tcGxldGU6IGZ1bmN0aW9uICgpIHsgc3RyZWFtLnNoYW1lZnVsbHlTZW5kQ29tcGxldGUoKTsgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4geyBvYnNlcnZlcjogb2JzZXJ2ZXIsIHN0cmVhbTogc3RyZWFtIH07XG4gICAgfSxcbiAgICByZW1lbWJlcjogZnVuY3Rpb24gKHN0cmVhbSkge1xuICAgICAgICByZXR1cm4gc3RyZWFtLnJlbWVtYmVyKCk7XG4gICAgfSxcbiAgICBpc1ZhbGlkU3RyZWFtOiBmdW5jdGlvbiAoc3RyZWFtKSB7XG4gICAgICAgIHJldHVybiAodHlwZW9mIHN0cmVhbS5hZGRMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgICAgICAgdHlwZW9mIHN0cmVhbS5zaGFtZWZ1bGx5U2VuZE5leHQgPT09ICdmdW5jdGlvbicpO1xuICAgIH0sXG4gICAgc3RyZWFtU3Vic2NyaWJlOiBmdW5jdGlvbiAoc3RyZWFtLCBvYnNlcnZlcikge1xuICAgICAgICBzdHJlYW0uYWRkTGlzdGVuZXIob2JzZXJ2ZXIpO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkgeyByZXR1cm4gc3RyZWFtLnJlbW92ZUxpc3RlbmVyKG9ic2VydmVyKTsgfTtcbiAgICB9XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gWFN0cmVhbUFkYXB0ZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCIndXNlIHN0cmljdCc7XG5cbnZhciBwcm90byA9IEVsZW1lbnQucHJvdG90eXBlO1xudmFyIHZlbmRvciA9IHByb3RvLm1hdGNoZXNcbiAgfHwgcHJvdG8ubWF0Y2hlc1NlbGVjdG9yXG4gIHx8IHByb3RvLndlYmtpdE1hdGNoZXNTZWxlY3RvclxuICB8fCBwcm90by5tb3pNYXRjaGVzU2VsZWN0b3JcbiAgfHwgcHJvdG8ubXNNYXRjaGVzU2VsZWN0b3JcbiAgfHwgcHJvdG8ub01hdGNoZXNTZWxlY3RvcjtcblxubW9kdWxlLmV4cG9ydHMgPSBtYXRjaDtcblxuLyoqXG4gKiBNYXRjaCBgZWxgIHRvIGBzZWxlY3RvcmAuXG4gKlxuICogQHBhcmFtIHtFbGVtZW50fSBlbFxuICogQHBhcmFtIHtTdHJpbmd9IHNlbGVjdG9yXG4gKiBAcmV0dXJuIHtCb29sZWFufVxuICogQGFwaSBwdWJsaWNcbiAqL1xuXG5mdW5jdGlvbiBtYXRjaChlbCwgc2VsZWN0b3IpIHtcbiAgaWYgKHZlbmRvcikgcmV0dXJuIHZlbmRvci5jYWxsKGVsLCBzZWxlY3Rvcik7XG4gIHZhciBub2RlcyA9IGVsLnBhcmVudE5vZGUucXVlcnlTZWxlY3RvckFsbChzZWxlY3Rvcik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbm9kZXMubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAobm9kZXNbaV0gPT0gZWwpIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn0iLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLmRlZmF1bHQgPSBjbGFzc05hbWVGcm9tVk5vZGU7XG5cbnZhciBfc2VsZWN0b3JQYXJzZXIyID0gcmVxdWlyZSgnLi9zZWxlY3RvclBhcnNlcicpO1xuXG52YXIgX3NlbGVjdG9yUGFyc2VyMyA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3NlbGVjdG9yUGFyc2VyMik7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIGNsYXNzTmFtZUZyb21WTm9kZSh2Tm9kZSkge1xuICB2YXIgX3NlbGVjdG9yUGFyc2VyID0gKDAsIF9zZWxlY3RvclBhcnNlcjMuZGVmYXVsdCkodk5vZGUuc2VsKTtcblxuICB2YXIgY24gPSBfc2VsZWN0b3JQYXJzZXIuY2xhc3NOYW1lO1xuXG4gIGlmICghdk5vZGUuZGF0YSkge1xuICAgIHJldHVybiBjbjtcbiAgfVxuXG4gIHZhciBfdk5vZGUkZGF0YSA9IHZOb2RlLmRhdGE7XG4gIHZhciBkYXRhQ2xhc3MgPSBfdk5vZGUkZGF0YS5jbGFzcztcbiAgdmFyIHByb3BzID0gX3ZOb2RlJGRhdGEucHJvcHM7XG5cbiAgaWYgKGRhdGFDbGFzcykge1xuICAgIHZhciBjID0gT2JqZWN0LmtleXModk5vZGUuZGF0YS5jbGFzcykuZmlsdGVyKGZ1bmN0aW9uIChjbCkge1xuICAgICAgcmV0dXJuIHZOb2RlLmRhdGEuY2xhc3NbY2xdO1xuICAgIH0pO1xuICAgIGNuICs9ICcgJyArIGMuam9pbignICcpO1xuICB9XG5cbiAgaWYgKHByb3BzICYmIHByb3BzLmNsYXNzTmFtZSkge1xuICAgIGNuICs9ICcgJyArIHByb3BzLmNsYXNzTmFtZTtcbiAgfVxuXG4gIHJldHVybiBjbi50cmltKCk7XG59IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gc2VsZWN0b3JQYXJzZXI7XG5cbnZhciBfYnJvd3NlclNwbGl0ID0gcmVxdWlyZSgnYnJvd3Nlci1zcGxpdCcpO1xuXG52YXIgX2Jyb3dzZXJTcGxpdDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9icm93c2VyU3BsaXQpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG52YXIgY2xhc3NJZFNwbGl0ID0gLyhbXFwuI10/W2EtekEtWjAtOVxcdTAwN0YtXFx1RkZGRl86LV0rKS87XG52YXIgbm90Q2xhc3NJZCA9IC9eXFwufCMvO1xuXG5mdW5jdGlvbiBzZWxlY3RvclBhcnNlcigpIHtcbiAgdmFyIHNlbGVjdG9yID0gYXJndW1lbnRzLmxlbmd0aCA8PSAwIHx8IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8gJycgOiBhcmd1bWVudHNbMF07XG5cbiAgdmFyIHRhZ05hbWUgPSB1bmRlZmluZWQ7XG4gIHZhciBpZCA9ICcnO1xuICB2YXIgY2xhc3NlcyA9IFtdO1xuXG4gIHZhciB0YWdQYXJ0cyA9ICgwLCBfYnJvd3NlclNwbGl0Mi5kZWZhdWx0KShzZWxlY3RvciwgY2xhc3NJZFNwbGl0KTtcblxuICBpZiAobm90Q2xhc3NJZC50ZXN0KHRhZ1BhcnRzWzFdKSB8fCBzZWxlY3RvciA9PT0gJycpIHtcbiAgICB0YWdOYW1lID0gJ2Rpdic7XG4gIH1cblxuICB2YXIgcGFydCA9IHVuZGVmaW5lZDtcbiAgdmFyIHR5cGUgPSB1bmRlZmluZWQ7XG4gIHZhciBpID0gdW5kZWZpbmVkO1xuXG4gIGZvciAoaSA9IDA7IGkgPCB0YWdQYXJ0cy5sZW5ndGg7IGkrKykge1xuICAgIHBhcnQgPSB0YWdQYXJ0c1tpXTtcblxuICAgIGlmICghcGFydCkge1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgdHlwZSA9IHBhcnQuY2hhckF0KDApO1xuXG4gICAgaWYgKCF0YWdOYW1lKSB7XG4gICAgICB0YWdOYW1lID0gcGFydDtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICcuJykge1xuICAgICAgY2xhc3Nlcy5wdXNoKHBhcnQuc3Vic3RyaW5nKDEsIHBhcnQubGVuZ3RoKSk7XG4gICAgfSBlbHNlIGlmICh0eXBlID09PSAnIycpIHtcbiAgICAgIGlkID0gcGFydC5zdWJzdHJpbmcoMSwgcGFydC5sZW5ndGgpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdGFnTmFtZTogdGFnTmFtZSxcbiAgICBpZDogaWQsXG4gICAgY2xhc3NOYW1lOiBjbGFzc2VzLmpvaW4oJyAnKVxuICB9O1xufSIsIi8qIVxuICogQ3Jvc3MtQnJvd3NlciBTcGxpdCAxLjEuMVxuICogQ29weXJpZ2h0IDIwMDctMjAxMiBTdGV2ZW4gTGV2aXRoYW4gPHN0ZXZlbmxldml0aGFuLmNvbT5cbiAqIEF2YWlsYWJsZSB1bmRlciB0aGUgTUlUIExpY2Vuc2VcbiAqIEVDTUFTY3JpcHQgY29tcGxpYW50LCB1bmlmb3JtIGNyb3NzLWJyb3dzZXIgc3BsaXQgbWV0aG9kXG4gKi9cblxuLyoqXG4gKiBTcGxpdHMgYSBzdHJpbmcgaW50byBhbiBhcnJheSBvZiBzdHJpbmdzIHVzaW5nIGEgcmVnZXggb3Igc3RyaW5nIHNlcGFyYXRvci4gTWF0Y2hlcyBvZiB0aGVcbiAqIHNlcGFyYXRvciBhcmUgbm90IGluY2x1ZGVkIGluIHRoZSByZXN1bHQgYXJyYXkuIEhvd2V2ZXIsIGlmIGBzZXBhcmF0b3JgIGlzIGEgcmVnZXggdGhhdCBjb250YWluc1xuICogY2FwdHVyaW5nIGdyb3VwcywgYmFja3JlZmVyZW5jZXMgYXJlIHNwbGljZWQgaW50byB0aGUgcmVzdWx0IGVhY2ggdGltZSBgc2VwYXJhdG9yYCBpcyBtYXRjaGVkLlxuICogRml4ZXMgYnJvd3NlciBidWdzIGNvbXBhcmVkIHRvIHRoZSBuYXRpdmUgYFN0cmluZy5wcm90b3R5cGUuc3BsaXRgIGFuZCBjYW4gYmUgdXNlZCByZWxpYWJseVxuICogY3Jvc3MtYnJvd3Nlci5cbiAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgU3RyaW5nIHRvIHNwbGl0LlxuICogQHBhcmFtIHtSZWdFeHB8U3RyaW5nfSBzZXBhcmF0b3IgUmVnZXggb3Igc3RyaW5nIHRvIHVzZSBmb3Igc2VwYXJhdGluZyB0aGUgc3RyaW5nLlxuICogQHBhcmFtIHtOdW1iZXJ9IFtsaW1pdF0gTWF4aW11bSBudW1iZXIgb2YgaXRlbXMgdG8gaW5jbHVkZSBpbiB0aGUgcmVzdWx0IGFycmF5LlxuICogQHJldHVybnMge0FycmF5fSBBcnJheSBvZiBzdWJzdHJpbmdzLlxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBCYXNpYyB1c2VcbiAqIHNwbGl0KCdhIGIgYyBkJywgJyAnKTtcbiAqIC8vIC0+IFsnYScsICdiJywgJ2MnLCAnZCddXG4gKlxuICogLy8gV2l0aCBsaW1pdFxuICogc3BsaXQoJ2EgYiBjIGQnLCAnICcsIDIpO1xuICogLy8gLT4gWydhJywgJ2InXVxuICpcbiAqIC8vIEJhY2tyZWZlcmVuY2VzIGluIHJlc3VsdCBhcnJheVxuICogc3BsaXQoJy4ud29yZDEgd29yZDIuLicsIC8oW2Etel0rKShcXGQrKS9pKTtcbiAqIC8vIC0+IFsnLi4nLCAnd29yZCcsICcxJywgJyAnLCAnd29yZCcsICcyJywgJy4uJ11cbiAqL1xubW9kdWxlLmV4cG9ydHMgPSAoZnVuY3Rpb24gc3BsaXQodW5kZWYpIHtcblxuICB2YXIgbmF0aXZlU3BsaXQgPSBTdHJpbmcucHJvdG90eXBlLnNwbGl0LFxuICAgIGNvbXBsaWFudEV4ZWNOcGNnID0gLygpPz8vLmV4ZWMoXCJcIilbMV0gPT09IHVuZGVmLFxuICAgIC8vIE5QQ0c6IG5vbnBhcnRpY2lwYXRpbmcgY2FwdHVyaW5nIGdyb3VwXG4gICAgc2VsZjtcblxuICBzZWxmID0gZnVuY3Rpb24oc3RyLCBzZXBhcmF0b3IsIGxpbWl0KSB7XG4gICAgLy8gSWYgYHNlcGFyYXRvcmAgaXMgbm90IGEgcmVnZXgsIHVzZSBgbmF0aXZlU3BsaXRgXG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChzZXBhcmF0b3IpICE9PSBcIltvYmplY3QgUmVnRXhwXVwiKSB7XG4gICAgICByZXR1cm4gbmF0aXZlU3BsaXQuY2FsbChzdHIsIHNlcGFyYXRvciwgbGltaXQpO1xuICAgIH1cbiAgICB2YXIgb3V0cHV0ID0gW10sXG4gICAgICBmbGFncyA9IChzZXBhcmF0b3IuaWdub3JlQ2FzZSA/IFwiaVwiIDogXCJcIikgKyAoc2VwYXJhdG9yLm11bHRpbGluZSA/IFwibVwiIDogXCJcIikgKyAoc2VwYXJhdG9yLmV4dGVuZGVkID8gXCJ4XCIgOiBcIlwiKSArIC8vIFByb3Bvc2VkIGZvciBFUzZcbiAgICAgIChzZXBhcmF0b3Iuc3RpY2t5ID8gXCJ5XCIgOiBcIlwiKSxcbiAgICAgIC8vIEZpcmVmb3ggMytcbiAgICAgIGxhc3RMYXN0SW5kZXggPSAwLFxuICAgICAgLy8gTWFrZSBgZ2xvYmFsYCBhbmQgYXZvaWQgYGxhc3RJbmRleGAgaXNzdWVzIGJ5IHdvcmtpbmcgd2l0aCBhIGNvcHlcbiAgICAgIHNlcGFyYXRvciA9IG5ldyBSZWdFeHAoc2VwYXJhdG9yLnNvdXJjZSwgZmxhZ3MgKyBcImdcIiksXG4gICAgICBzZXBhcmF0b3IyLCBtYXRjaCwgbGFzdEluZGV4LCBsYXN0TGVuZ3RoO1xuICAgIHN0ciArPSBcIlwiOyAvLyBUeXBlLWNvbnZlcnRcbiAgICBpZiAoIWNvbXBsaWFudEV4ZWNOcGNnKSB7XG4gICAgICAvLyBEb2Vzbid0IG5lZWQgZmxhZ3MgZ3ksIGJ1dCB0aGV5IGRvbid0IGh1cnRcbiAgICAgIHNlcGFyYXRvcjIgPSBuZXcgUmVnRXhwKFwiXlwiICsgc2VwYXJhdG9yLnNvdXJjZSArIFwiJCg/IVxcXFxzKVwiLCBmbGFncyk7XG4gICAgfVxuICAgIC8qIFZhbHVlcyBmb3IgYGxpbWl0YCwgcGVyIHRoZSBzcGVjOlxuICAgICAqIElmIHVuZGVmaW5lZDogNDI5NDk2NzI5NSAvLyBNYXRoLnBvdygyLCAzMikgLSAxXG4gICAgICogSWYgMCwgSW5maW5pdHksIG9yIE5hTjogMFxuICAgICAqIElmIHBvc2l0aXZlIG51bWJlcjogbGltaXQgPSBNYXRoLmZsb29yKGxpbWl0KTsgaWYgKGxpbWl0ID4gNDI5NDk2NzI5NSkgbGltaXQgLT0gNDI5NDk2NzI5NjtcbiAgICAgKiBJZiBuZWdhdGl2ZSBudW1iZXI6IDQyOTQ5NjcyOTYgLSBNYXRoLmZsb29yKE1hdGguYWJzKGxpbWl0KSlcbiAgICAgKiBJZiBvdGhlcjogVHlwZS1jb252ZXJ0LCB0aGVuIHVzZSB0aGUgYWJvdmUgcnVsZXNcbiAgICAgKi9cbiAgICBsaW1pdCA9IGxpbWl0ID09PSB1bmRlZiA/IC0xID4+PiAwIDogLy8gTWF0aC5wb3coMiwgMzIpIC0gMVxuICAgIGxpbWl0ID4+PiAwOyAvLyBUb1VpbnQzMihsaW1pdClcbiAgICB3aGlsZSAobWF0Y2ggPSBzZXBhcmF0b3IuZXhlYyhzdHIpKSB7XG4gICAgICAvLyBgc2VwYXJhdG9yLmxhc3RJbmRleGAgaXMgbm90IHJlbGlhYmxlIGNyb3NzLWJyb3dzZXJcbiAgICAgIGxhc3RJbmRleCA9IG1hdGNoLmluZGV4ICsgbWF0Y2hbMF0ubGVuZ3RoO1xuICAgICAgaWYgKGxhc3RJbmRleCA+IGxhc3RMYXN0SW5kZXgpIHtcbiAgICAgICAgb3V0cHV0LnB1c2goc3RyLnNsaWNlKGxhc3RMYXN0SW5kZXgsIG1hdGNoLmluZGV4KSk7XG4gICAgICAgIC8vIEZpeCBicm93c2VycyB3aG9zZSBgZXhlY2AgbWV0aG9kcyBkb24ndCBjb25zaXN0ZW50bHkgcmV0dXJuIGB1bmRlZmluZWRgIGZvclxuICAgICAgICAvLyBub25wYXJ0aWNpcGF0aW5nIGNhcHR1cmluZyBncm91cHNcbiAgICAgICAgaWYgKCFjb21wbGlhbnRFeGVjTnBjZyAmJiBtYXRjaC5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgbWF0Y2hbMF0ucmVwbGFjZShzZXBhcmF0b3IyLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aCAtIDI7IGkrKykge1xuICAgICAgICAgICAgICBpZiAoYXJndW1lbnRzW2ldID09PSB1bmRlZikge1xuICAgICAgICAgICAgICAgIG1hdGNoW2ldID0gdW5kZWY7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgICBpZiAobWF0Y2gubGVuZ3RoID4gMSAmJiBtYXRjaC5pbmRleCA8IHN0ci5sZW5ndGgpIHtcbiAgICAgICAgICBBcnJheS5wcm90b3R5cGUucHVzaC5hcHBseShvdXRwdXQsIG1hdGNoLnNsaWNlKDEpKTtcbiAgICAgICAgfVxuICAgICAgICBsYXN0TGVuZ3RoID0gbWF0Y2hbMF0ubGVuZ3RoO1xuICAgICAgICBsYXN0TGFzdEluZGV4ID0gbGFzdEluZGV4O1xuICAgICAgICBpZiAob3V0cHV0Lmxlbmd0aCA+PSBsaW1pdCkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoc2VwYXJhdG9yLmxhc3RJbmRleCA9PT0gbWF0Y2guaW5kZXgpIHtcbiAgICAgICAgc2VwYXJhdG9yLmxhc3RJbmRleCsrOyAvLyBBdm9pZCBhbiBpbmZpbml0ZSBsb29wXG4gICAgICB9XG4gICAgfVxuICAgIGlmIChsYXN0TGFzdEluZGV4ID09PSBzdHIubGVuZ3RoKSB7XG4gICAgICBpZiAobGFzdExlbmd0aCB8fCAhc2VwYXJhdG9yLnRlc3QoXCJcIikpIHtcbiAgICAgICAgb3V0cHV0LnB1c2goXCJcIik7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG91dHB1dC5wdXNoKHN0ci5zbGljZShsYXN0TGFzdEluZGV4KSk7XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQubGVuZ3RoID4gbGltaXQgPyBvdXRwdXQuc2xpY2UoMCwgbGltaXQpIDogb3V0cHV0O1xuICB9O1xuXG4gIHJldHVybiBzZWxmO1xufSkoKTtcbiIsIlxuLy8gQWxsIFNWRyBjaGlsZHJlbiBlbGVtZW50cywgbm90IGluIHRoaXMgbGlzdCwgc2hvdWxkIHNlbGYtY2xvc2VcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL1NWRy9pbnRyby5odG1sI1Rlcm1Db250YWluZXJFbGVtZW50XG4gICdhJzogdHJ1ZSxcbiAgJ2RlZnMnOiB0cnVlLFxuICAnZ2x5cGgnOiB0cnVlLFxuICAnZyc6IHRydWUsXG4gICdtYXJrZXInOiB0cnVlLFxuICAnbWFzayc6IHRydWUsXG4gICdtaXNzaW5nLWdseXBoJzogdHJ1ZSxcbiAgJ3BhdHRlcm4nOiB0cnVlLFxuICAnc3ZnJzogdHJ1ZSxcbiAgJ3N3aXRjaCc6IHRydWUsXG4gICdzeW1ib2wnOiB0cnVlLFxuXG4gIC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL1NWRy9pbnRyby5odG1sI1Rlcm1EZXNjcmlwdGl2ZUVsZW1lbnRcbiAgJ2Rlc2MnOiB0cnVlLFxuICAnbWV0YWRhdGEnOiB0cnVlLFxuICAndGl0bGUnOiB0cnVlXG59OyIsIlxudmFyIGluaXQgPSByZXF1aXJlKCcuL2luaXQnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBpbml0KFtyZXF1aXJlKCcuL21vZHVsZXMvYXR0cmlidXRlcycpLCByZXF1aXJlKCcuL21vZHVsZXMvc3R5bGUnKV0pOyIsIlxudmFyIHBhcnNlU2VsZWN0b3IgPSByZXF1aXJlKCcuL3BhcnNlLXNlbGVjdG9yJyk7XG52YXIgVk9JRF9FTEVNRU5UUyA9IHJlcXVpcmUoJy4vdm9pZC1lbGVtZW50cycpO1xudmFyIENPTlRBSU5FUl9FTEVNRU5UUyA9IHJlcXVpcmUoJy4vY29udGFpbmVyLWVsZW1lbnRzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5pdChtb2R1bGVzKSB7XG4gIGZ1bmN0aW9uIHBhcnNlKGRhdGEpIHtcbiAgICByZXR1cm4gbW9kdWxlcy5yZWR1Y2UoZnVuY3Rpb24gKGFyciwgZm4pIHtcbiAgICAgIGFyci5wdXNoKGZuKGRhdGEpKTtcbiAgICAgIHJldHVybiBhcnI7XG4gICAgfSwgW10pLmZpbHRlcihmdW5jdGlvbiAocmVzdWx0KSB7XG4gICAgICByZXR1cm4gcmVzdWx0ICE9PSAnJztcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbiByZW5kZXJUb1N0cmluZyh2bm9kZSkge1xuICAgIGlmICghdm5vZGUuc2VsICYmIHZub2RlLnRleHQpIHtcbiAgICAgIHJldHVybiB2bm9kZS50ZXh0O1xuICAgIH1cblxuICAgIHZub2RlLmRhdGEgPSB2bm9kZS5kYXRhIHx8IHt9O1xuXG4gICAgLy8gU3VwcG9ydCB0aHVua3NcbiAgICBpZiAodHlwZW9mIHZub2RlLnNlbCA9PT0gJ3N0cmluZycgJiYgdm5vZGUuc2VsLnNsaWNlKDAsIDUpID09PSAndGh1bmsnKSB7XG4gICAgICB2bm9kZSA9IHZub2RlLmRhdGEuZm4uYXBwbHkobnVsbCwgdm5vZGUuZGF0YS5hcmdzKTtcbiAgICB9XG5cbiAgICB2YXIgdGFnTmFtZSA9IHBhcnNlU2VsZWN0b3Iodm5vZGUuc2VsKS50YWdOYW1lO1xuICAgIHZhciBhdHRyaWJ1dGVzID0gcGFyc2Uodm5vZGUpO1xuICAgIHZhciBzdmcgPSB2bm9kZS5kYXRhLm5zID09PSAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnO1xuICAgIHZhciB0YWcgPSBbXTtcblxuICAgIC8vIE9wZW4gdGFnXG4gICAgdGFnLnB1c2goJzwnICsgdGFnTmFtZSk7XG4gICAgaWYgKGF0dHJpYnV0ZXMubGVuZ3RoKSB7XG4gICAgICB0YWcucHVzaCgnICcgKyBhdHRyaWJ1dGVzLmpvaW4oJyAnKSk7XG4gICAgfVxuICAgIGlmIChzdmcgJiYgQ09OVEFJTkVSX0VMRU1FTlRTW3RhZ05hbWVdICE9PSB0cnVlKSB7XG4gICAgICB0YWcucHVzaCgnIC8nKTtcbiAgICB9XG4gICAgdGFnLnB1c2goJz4nKTtcblxuICAgIC8vIENsb3NlIHRhZywgaWYgbmVlZGVkXG4gICAgaWYgKFZPSURfRUxFTUVOVFNbdGFnTmFtZV0gIT09IHRydWUgJiYgIXN2ZyB8fCBzdmcgJiYgQ09OVEFJTkVSX0VMRU1FTlRTW3RhZ05hbWVdID09PSB0cnVlKSB7XG4gICAgICBpZiAodm5vZGUuZGF0YS5wcm9wcyAmJiB2bm9kZS5kYXRhLnByb3BzLmlubmVySFRNTCkge1xuICAgICAgICB0YWcucHVzaCh2bm9kZS5kYXRhLnByb3BzLmlubmVySFRNTCk7XG4gICAgICB9IGVsc2UgaWYgKHZub2RlLnRleHQpIHtcbiAgICAgICAgdGFnLnB1c2godm5vZGUudGV4dCk7XG4gICAgICB9IGVsc2UgaWYgKHZub2RlLmNoaWxkcmVuKSB7XG4gICAgICAgIHZub2RlLmNoaWxkcmVuLmZvckVhY2goZnVuY3Rpb24gKGNoaWxkKSB7XG4gICAgICAgICAgdGFnLnB1c2gocmVuZGVyVG9TdHJpbmcoY2hpbGQpKTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICB0YWcucHVzaCgnPC8nICsgdGFnTmFtZSArICc+Jyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRhZy5qb2luKCcnKTtcbiAgfTtcbn07IiwiXG52YXIgZm9yT3duID0gcmVxdWlyZSgnbG9kYXNoLmZvcm93bicpO1xudmFyIGVzY2FwZSA9IHJlcXVpcmUoJ2xvZGFzaC5lc2NhcGUnKTtcbnZhciB1bmlvbiA9IHJlcXVpcmUoJ2xvZGFzaC51bmlvbicpO1xuXG52YXIgcGFyc2VTZWxlY3RvciA9IHJlcXVpcmUoJy4uL3BhcnNlLXNlbGVjdG9yJyk7XG5cbi8vIGRhdGEuYXR0cnMsIGRhdGEucHJvcHMsIGRhdGEuY2xhc3NcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBhdHRyaWJ1dGVzKHZub2RlKSB7XG4gIHZhciBzZWxlY3RvciA9IHBhcnNlU2VsZWN0b3Iodm5vZGUuc2VsKTtcbiAgdmFyIHBhcnNlZENsYXNzZXMgPSBzZWxlY3Rvci5jbGFzc05hbWUuc3BsaXQoJyAnKTtcblxuICB2YXIgYXR0cmlidXRlcyA9IFtdO1xuICB2YXIgY2xhc3NlcyA9IFtdO1xuICB2YXIgdmFsdWVzID0ge307XG5cbiAgaWYgKHNlbGVjdG9yLmlkKSB7XG4gICAgdmFsdWVzLmlkID0gc2VsZWN0b3IuaWQ7XG4gIH1cblxuICBzZXRBdHRyaWJ1dGVzKHZub2RlLmRhdGEucHJvcHMsIHZhbHVlcyk7XG4gIHNldEF0dHJpYnV0ZXModm5vZGUuZGF0YS5hdHRycywgdmFsdWVzKTsgLy8gYGF0dHJzYCBvdmVycmlkZSBgcHJvcHNgLCBub3Qgc3VyZSBpZiB0aGlzIGlzIGdvb2Qgc29cblxuICBpZiAodm5vZGUuZGF0YS5jbGFzcykge1xuICAgIC8vIE9taXQgYGNsYXNzTmFtZWAgYXR0cmlidXRlIGlmIGBjbGFzc2AgaXMgc2V0IG9uIHZub2RlXG4gICAgdmFsdWVzLmNsYXNzID0gdW5kZWZpbmVkO1xuICB9XG4gIGZvck93bih2bm9kZS5kYXRhLmNsYXNzLCBmdW5jdGlvbiAodmFsdWUsIGtleSkge1xuICAgIGlmICh2YWx1ZSA9PT0gdHJ1ZSkge1xuICAgICAgY2xhc3Nlcy5wdXNoKGtleSk7XG4gICAgfVxuICB9KTtcbiAgY2xhc3NlcyA9IHVuaW9uKGNsYXNzZXMsIHZhbHVlcy5jbGFzcywgcGFyc2VkQ2xhc3NlcykuZmlsdGVyKGZ1bmN0aW9uICh4KSB7XG4gICAgcmV0dXJuIHggIT09ICcnO1xuICB9KTtcblxuICBpZiAoY2xhc3Nlcy5sZW5ndGgpIHtcbiAgICB2YWx1ZXMuY2xhc3MgPSBjbGFzc2VzLmpvaW4oJyAnKTtcbiAgfVxuXG4gIGZvck93bih2YWx1ZXMsIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgYXR0cmlidXRlcy5wdXNoKHZhbHVlID09PSB0cnVlID8ga2V5IDoga2V5ICsgJz1cIicgKyBlc2NhcGUodmFsdWUpICsgJ1wiJyk7XG4gIH0pO1xuXG4gIHJldHVybiBhdHRyaWJ1dGVzLmxlbmd0aCA/IGF0dHJpYnV0ZXMuam9pbignICcpIDogJyc7XG59O1xuXG5mdW5jdGlvbiBzZXRBdHRyaWJ1dGVzKHZhbHVlcywgdGFyZ2V0KSB7XG4gIGZvck93bih2YWx1ZXMsIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgaWYgKGtleSA9PT0gJ2h0bWxGb3InKSB7XG4gICAgICB0YXJnZXRbJ2ZvciddID0gdmFsdWU7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChrZXkgPT09ICdjbGFzc05hbWUnKSB7XG4gICAgICB0YXJnZXRbJ2NsYXNzJ10gPSB2YWx1ZS5zcGxpdCgnICcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoa2V5ID09PSAnaW5uZXJIVE1MJykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0YXJnZXRba2V5XSA9IHZhbHVlO1xuICB9KTtcbn0iLCJ2YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG52YXIgZm9yT3duID0gcmVxdWlyZSgnbG9kYXNoLmZvcm93bicpO1xudmFyIGVzY2FwZSA9IHJlcXVpcmUoJ2xvZGFzaC5lc2NhcGUnKTtcbnZhciBrZWJhYkNhc2UgPSByZXF1aXJlKCdsb2Rhc2gua2ViYWJjYXNlJyk7XG5cbi8vIGRhdGEuc3R5bGVcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBzdHlsZSh2bm9kZSkge1xuICB2YXIgc3R5bGVzID0gW107XG4gIHZhciBzdHlsZSA9IHZub2RlLmRhdGEuc3R5bGUgfHwge307XG5cbiAgLy8gbWVyZ2UgaW4gYGRlbGF5ZWRgIHByb3BlcnRpZXNcbiAgaWYgKHN0eWxlLmRlbGF5ZWQpIHtcbiAgICBfZXh0ZW5kcyhzdHlsZSwgc3R5bGUuZGVsYXllZCk7XG4gIH1cblxuICBmb3JPd24oc3R5bGUsIGZ1bmN0aW9uICh2YWx1ZSwga2V5KSB7XG4gICAgLy8gb21pdCBob29rIG9iamVjdHNcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgc3R5bGVzLnB1c2goa2ViYWJDYXNlKGtleSkgKyAnOiAnICsgZXNjYXBlKHZhbHVlKSk7XG4gICAgfVxuICB9KTtcblxuICByZXR1cm4gc3R5bGVzLmxlbmd0aCA/ICdzdHlsZT1cIicgKyBzdHlsZXMuam9pbignOyAnKSArICdcIicgOiAnJztcbn07IiwiXG4vLyBodHRwczovL2dpdGh1Yi5jb20vTWF0dC1Fc2NoL3ZpcnR1YWwtZG9tL2Jsb2IvbWFzdGVyL3ZpcnR1YWwtaHlwZXJzY3JpcHQvcGFyc2UtdGFnLmpzXG5cbnZhciBzcGxpdCA9IHJlcXVpcmUoJ2Jyb3dzZXItc3BsaXQnKTtcblxudmFyIGNsYXNzSWRTcGxpdCA9IC8oW1xcLiNdP1thLXpBLVowLTlcXHUwMDdGLVxcdUZGRkZfOi1dKykvO1xudmFyIG5vdENsYXNzSWQgPSAvXlxcLnwjLztcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYXJzZVNlbGVjdG9yKHNlbGVjdG9yLCB1cHBlcikge1xuICBzZWxlY3RvciA9IHNlbGVjdG9yIHx8ICcnO1xuICB2YXIgdGFnTmFtZTtcbiAgdmFyIGlkID0gJyc7XG4gIHZhciBjbGFzc2VzID0gW107XG5cbiAgdmFyIHRhZ1BhcnRzID0gc3BsaXQoc2VsZWN0b3IsIGNsYXNzSWRTcGxpdCk7XG5cbiAgaWYgKG5vdENsYXNzSWQudGVzdCh0YWdQYXJ0c1sxXSkgfHwgc2VsZWN0b3IgPT09ICcnKSB7XG4gICAgdGFnTmFtZSA9ICdkaXYnO1xuICB9XG5cbiAgdmFyIHBhcnQsIHR5cGUsIGk7XG5cbiAgZm9yIChpID0gMDsgaSA8IHRhZ1BhcnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgcGFydCA9IHRhZ1BhcnRzW2ldO1xuXG4gICAgaWYgKCFwYXJ0KSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICB0eXBlID0gcGFydC5jaGFyQXQoMCk7XG5cbiAgICBpZiAoIXRhZ05hbWUpIHtcbiAgICAgIHRhZ05hbWUgPSBwYXJ0O1xuICAgIH0gZWxzZSBpZiAodHlwZSA9PT0gJy4nKSB7XG4gICAgICBjbGFzc2VzLnB1c2gocGFydC5zdWJzdHJpbmcoMSwgcGFydC5sZW5ndGgpKTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09ICcjJykge1xuICAgICAgaWQgPSBwYXJ0LnN1YnN0cmluZygxLCBwYXJ0Lmxlbmd0aCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0YWdOYW1lOiB1cHBlciA9PT0gdHJ1ZSA/IHRhZ05hbWUudG9VcHBlckNhc2UoKSA6IHRhZ05hbWUsXG4gICAgaWQ6IGlkLFxuICAgIGNsYXNzTmFtZTogY2xhc3Nlcy5qb2luKCcgJylcbiAgfTtcbn07IiwiXG4vLyBodHRwOi8vd3d3LnczLm9yZy9odG1sL3dnL2RyYWZ0cy9odG1sL21hc3Rlci9zeW50YXguaHRtbCN2b2lkLWVsZW1lbnRzXG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBhcmVhOiB0cnVlLFxuICBiYXNlOiB0cnVlLFxuICBicjogdHJ1ZSxcbiAgY29sOiB0cnVlLFxuICBlbWJlZDogdHJ1ZSxcbiAgaHI6IHRydWUsXG4gIGltZzogdHJ1ZSxcbiAgaW5wdXQ6IHRydWUsXG4gIGtleWdlbjogdHJ1ZSxcbiAgbGluazogdHJ1ZSxcbiAgbWV0YTogdHJ1ZSxcbiAgcGFyYW06IHRydWUsXG4gIHNvdXJjZTogdHJ1ZSxcbiAgdHJhY2s6IHRydWUsXG4gIHdicjogdHJ1ZVxufTsiLCIvKipcbiAqIGxvZGFzaCAzLjIuMCAoQ3VzdG9tIEJ1aWxkKSA8aHR0cHM6Ly9sb2Rhc2guY29tLz5cbiAqIEJ1aWxkOiBgbG9kYXNoIG1vZHVsYXJpemUgZXhwb3J0cz1cIm5wbVwiIC1vIC4vYFxuICogQ29weXJpZ2h0IDIwMTItMjAxNiBUaGUgRG9qbyBGb3VuZGF0aW9uIDxodHRwOi8vZG9qb2ZvdW5kYXRpb24ub3JnLz5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgMjAwOS0yMDE2IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICovXG52YXIgcm9vdCA9IHJlcXVpcmUoJ2xvZGFzaC5fcm9vdCcpO1xuXG4vKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi9cbnZhciBJTkZJTklUWSA9IDEgLyAwO1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgc3ltYm9sVGFnID0gJ1tvYmplY3QgU3ltYm9sXSc7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIEhUTUwgZW50aXRpZXMgYW5kIEhUTUwgY2hhcmFjdGVycy4gKi9cbnZhciByZVVuZXNjYXBlZEh0bWwgPSAvWyY8PlwiJ2BdL2csXG4gICAgcmVIYXNVbmVzY2FwZWRIdG1sID0gUmVnRXhwKHJlVW5lc2NhcGVkSHRtbC5zb3VyY2UpO1xuXG4vKiogVXNlZCB0byBtYXAgY2hhcmFjdGVycyB0byBIVE1MIGVudGl0aWVzLiAqL1xudmFyIGh0bWxFc2NhcGVzID0ge1xuICAnJic6ICcmYW1wOycsXG4gICc8JzogJyZsdDsnLFxuICAnPic6ICcmZ3Q7JyxcbiAgJ1wiJzogJyZxdW90OycsXG4gIFwiJ1wiOiAnJiMzOTsnLFxuICAnYCc6ICcmIzk2Oydcbn07XG5cbi8qKlxuICogVXNlZCBieSBgXy5lc2NhcGVgIHRvIGNvbnZlcnQgY2hhcmFjdGVycyB0byBIVE1MIGVudGl0aWVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gY2hyIFRoZSBtYXRjaGVkIGNoYXJhY3RlciB0byBlc2NhcGUuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBlc2NhcGVkIGNoYXJhY3Rlci5cbiAqL1xuZnVuY3Rpb24gZXNjYXBlSHRtbENoYXIoY2hyKSB7XG4gIHJldHVybiBodG1sRXNjYXBlc1tjaHJdO1xufVxuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgW2B0b1N0cmluZ1RhZ2BdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5wcm90b3R5cGUudG9zdHJpbmcpXG4gKiBvZiB2YWx1ZXMuXG4gKi9cbnZhciBvYmplY3RUb1N0cmluZyA9IG9iamVjdFByb3RvLnRvU3RyaW5nO1xuXG4vKiogQnVpbHQtaW4gdmFsdWUgcmVmZXJlbmNlcy4gKi9cbnZhciBTeW1ib2wgPSByb290LlN5bWJvbDtcblxuLyoqIFVzZWQgdG8gY29udmVydCBzeW1ib2xzIHRvIHByaW1pdGl2ZXMgYW5kIHN0cmluZ3MuICovXG52YXIgc3ltYm9sUHJvdG8gPSBTeW1ib2wgPyBTeW1ib2wucHJvdG90eXBlIDogdW5kZWZpbmVkLFxuICAgIHN5bWJvbFRvU3RyaW5nID0gU3ltYm9sID8gc3ltYm9sUHJvdG8udG9TdHJpbmcgOiB1bmRlZmluZWQ7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UuIEEgdmFsdWUgaXMgb2JqZWN0LWxpa2UgaWYgaXQncyBub3QgYG51bGxgXG4gKiBhbmQgaGFzIGEgYHR5cGVvZmAgcmVzdWx0IG9mIFwib2JqZWN0XCIuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKF8ubm9vcCk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKG51bGwpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3RMaWtlKHZhbHVlKSB7XG4gIHJldHVybiAhIXZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jztcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBjbGFzc2lmaWVkIGFzIGEgYFN5bWJvbGAgcHJpbWl0aXZlIG9yIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc1N5bWJvbChTeW1ib2wuaXRlcmF0b3IpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNTeW1ib2woJ2FiYycpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNTeW1ib2wodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnc3ltYm9sJyB8fFxuICAgIChpc09iamVjdExpa2UodmFsdWUpICYmIG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpID09IHN5bWJvbFRhZyk7XG59XG5cbi8qKlxuICogQ29udmVydHMgYHZhbHVlYCB0byBhIHN0cmluZyBpZiBpdCdzIG5vdCBvbmUuIEFuIGVtcHR5IHN0cmluZyBpcyByZXR1cm5lZFxuICogZm9yIGBudWxsYCBhbmQgYHVuZGVmaW5lZGAgdmFsdWVzLiBUaGUgc2lnbiBvZiBgLTBgIGlzIHByZXNlcnZlZC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHByb2Nlc3MuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBzdHJpbmcuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8udG9TdHJpbmcobnVsbCk7XG4gKiAvLyA9PiAnJ1xuICpcbiAqIF8udG9TdHJpbmcoLTApO1xuICogLy8gPT4gJy0wJ1xuICpcbiAqIF8udG9TdHJpbmcoWzEsIDIsIDNdKTtcbiAqIC8vID0+ICcxLDIsMydcbiAqL1xuZnVuY3Rpb24gdG9TdHJpbmcodmFsdWUpIHtcbiAgLy8gRXhpdCBlYXJseSBmb3Igc3RyaW5ncyB0byBhdm9pZCBhIHBlcmZvcm1hbmNlIGhpdCBpbiBzb21lIGVudmlyb25tZW50cy5cbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJykge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgIHJldHVybiAnJztcbiAgfVxuICBpZiAoaXNTeW1ib2wodmFsdWUpKSB7XG4gICAgcmV0dXJuIFN5bWJvbCA/IHN5bWJvbFRvU3RyaW5nLmNhbGwodmFsdWUpIDogJyc7XG4gIH1cbiAgdmFyIHJlc3VsdCA9ICh2YWx1ZSArICcnKTtcbiAgcmV0dXJuIChyZXN1bHQgPT0gJzAnICYmICgxIC8gdmFsdWUpID09IC1JTkZJTklUWSkgPyAnLTAnIDogcmVzdWx0O1xufVxuXG4vKipcbiAqIENvbnZlcnRzIHRoZSBjaGFyYWN0ZXJzIFwiJlwiLCBcIjxcIiwgXCI+XCIsICdcIicsIFwiJ1wiLCBhbmQgXCJcXGBcIiBpbiBgc3RyaW5nYCB0b1xuICogdGhlaXIgY29ycmVzcG9uZGluZyBIVE1MIGVudGl0aWVzLlxuICpcbiAqICoqTm90ZToqKiBObyBvdGhlciBjaGFyYWN0ZXJzIGFyZSBlc2NhcGVkLiBUbyBlc2NhcGUgYWRkaXRpb25hbFxuICogY2hhcmFjdGVycyB1c2UgYSB0aGlyZC1wYXJ0eSBsaWJyYXJ5IGxpa2UgW19oZV9dKGh0dHBzOi8vbXRocy5iZS9oZSkuXG4gKlxuICogVGhvdWdoIHRoZSBcIj5cIiBjaGFyYWN0ZXIgaXMgZXNjYXBlZCBmb3Igc3ltbWV0cnksIGNoYXJhY3RlcnMgbGlrZVxuICogXCI+XCIgYW5kIFwiL1wiIGRvbid0IG5lZWQgZXNjYXBpbmcgaW4gSFRNTCBhbmQgaGF2ZSBubyBzcGVjaWFsIG1lYW5pbmdcbiAqIHVubGVzcyB0aGV5J3JlIHBhcnQgb2YgYSB0YWcgb3IgdW5xdW90ZWQgYXR0cmlidXRlIHZhbHVlLlxuICogU2VlIFtNYXRoaWFzIEJ5bmVucydzIGFydGljbGVdKGh0dHBzOi8vbWF0aGlhc2J5bmVucy5iZS9ub3Rlcy9hbWJpZ3VvdXMtYW1wZXJzYW5kcylcbiAqICh1bmRlciBcInNlbWktcmVsYXRlZCBmdW4gZmFjdFwiKSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIEJhY2t0aWNrcyBhcmUgZXNjYXBlZCBiZWNhdXNlIGluIElFIDwgOSwgdGhleSBjYW4gYnJlYWsgb3V0IG9mXG4gKiBhdHRyaWJ1dGUgdmFsdWVzIG9yIEhUTUwgY29tbWVudHMuIFNlZSBbIzU5XShodHRwczovL2h0bWw1c2VjLm9yZy8jNTkpLFxuICogWyMxMDJdKGh0dHBzOi8vaHRtbDVzZWMub3JnLyMxMDIpLCBbIzEwOF0oaHR0cHM6Ly9odG1sNXNlYy5vcmcvIzEwOCksIGFuZFxuICogWyMxMzNdKGh0dHBzOi8vaHRtbDVzZWMub3JnLyMxMzMpIG9mIHRoZSBbSFRNTDUgU2VjdXJpdHkgQ2hlYXRzaGVldF0oaHR0cHM6Ly9odG1sNXNlYy5vcmcvKVxuICogZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBXaGVuIHdvcmtpbmcgd2l0aCBIVE1MIHlvdSBzaG91bGQgYWx3YXlzIFtxdW90ZSBhdHRyaWJ1dGUgdmFsdWVzXShodHRwOi8vd29ua28uY29tL3Bvc3QvaHRtbC1lc2NhcGluZylcbiAqIHRvIHJlZHVjZSBYU1MgdmVjdG9ycy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IFN0cmluZ1xuICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gZXNjYXBlLlxuICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgZXNjYXBlZCBzdHJpbmcuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uZXNjYXBlKCdmcmVkLCBiYXJuZXksICYgcGViYmxlcycpO1xuICogLy8gPT4gJ2ZyZWQsIGJhcm5leSwgJmFtcDsgcGViYmxlcydcbiAqL1xuZnVuY3Rpb24gZXNjYXBlKHN0cmluZykge1xuICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICByZXR1cm4gKHN0cmluZyAmJiByZUhhc1VuZXNjYXBlZEh0bWwudGVzdChzdHJpbmcpKVxuICAgID8gc3RyaW5nLnJlcGxhY2UocmVVbmVzY2FwZWRIdG1sLCBlc2NhcGVIdG1sQ2hhcilcbiAgICA6IHN0cmluZztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBlc2NhcGU7XG4iLCIvKipcbiAqIGxvZGFzaCAzLjAuMSAoQ3VzdG9tIEJ1aWxkKSA8aHR0cHM6Ly9sb2Rhc2guY29tLz5cbiAqIEJ1aWxkOiBgbG9kYXNoIG1vZHVsYXJpemUgZXhwb3J0cz1cIm5wbVwiIC1vIC4vYFxuICogQ29weXJpZ2h0IDIwMTItMjAxNiBUaGUgRG9qbyBGb3VuZGF0aW9uIDxodHRwOi8vZG9qb2ZvdW5kYXRpb24ub3JnLz5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgMjAwOS0yMDE2IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICovXG5cbi8qKiBVc2VkIHRvIGRldGVybWluZSBpZiB2YWx1ZXMgYXJlIG9mIHRoZSBsYW5ndWFnZSB0eXBlIGBPYmplY3RgLiAqL1xudmFyIG9iamVjdFR5cGVzID0ge1xuICAnZnVuY3Rpb24nOiB0cnVlLFxuICAnb2JqZWN0JzogdHJ1ZVxufTtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBleHBvcnRzYC4gKi9cbnZhciBmcmVlRXhwb3J0cyA9IChvYmplY3RUeXBlc1t0eXBlb2YgZXhwb3J0c10gJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSlcbiAgPyBleHBvcnRzXG4gIDogdW5kZWZpbmVkO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWAuICovXG52YXIgZnJlZU1vZHVsZSA9IChvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlXSAmJiBtb2R1bGUgJiYgIW1vZHVsZS5ub2RlVHlwZSlcbiAgPyBtb2R1bGVcbiAgOiB1bmRlZmluZWQ7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCBmcm9tIE5vZGUuanMuICovXG52YXIgZnJlZUdsb2JhbCA9IGNoZWNrR2xvYmFsKGZyZWVFeHBvcnRzICYmIGZyZWVNb2R1bGUgJiYgdHlwZW9mIGdsb2JhbCA9PSAnb2JqZWN0JyAmJiBnbG9iYWwpO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHNlbGZgLiAqL1xudmFyIGZyZWVTZWxmID0gY2hlY2tHbG9iYWwob2JqZWN0VHlwZXNbdHlwZW9mIHNlbGZdICYmIHNlbGYpO1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYHdpbmRvd2AuICovXG52YXIgZnJlZVdpbmRvdyA9IGNoZWNrR2xvYmFsKG9iamVjdFR5cGVzW3R5cGVvZiB3aW5kb3ddICYmIHdpbmRvdyk7XG5cbi8qKiBEZXRlY3QgYHRoaXNgIGFzIHRoZSBnbG9iYWwgb2JqZWN0LiAqL1xudmFyIHRoaXNHbG9iYWwgPSBjaGVja0dsb2JhbChvYmplY3RUeXBlc1t0eXBlb2YgdGhpc10gJiYgdGhpcyk7XG5cbi8qKlxuICogVXNlZCBhcyBhIHJlZmVyZW5jZSB0byB0aGUgZ2xvYmFsIG9iamVjdC5cbiAqXG4gKiBUaGUgYHRoaXNgIHZhbHVlIGlzIHVzZWQgaWYgaXQncyB0aGUgZ2xvYmFsIG9iamVjdCB0byBhdm9pZCBHcmVhc2Vtb25rZXknc1xuICogcmVzdHJpY3RlZCBgd2luZG93YCBvYmplY3QsIG90aGVyd2lzZSB0aGUgYHdpbmRvd2Agb2JqZWN0IGlzIHVzZWQuXG4gKi9cbnZhciByb290ID0gZnJlZUdsb2JhbCB8fFxuICAoKGZyZWVXaW5kb3cgIT09ICh0aGlzR2xvYmFsICYmIHRoaXNHbG9iYWwud2luZG93KSkgJiYgZnJlZVdpbmRvdykgfHxcbiAgICBmcmVlU2VsZiB8fCB0aGlzR2xvYmFsIHx8IEZ1bmN0aW9uKCdyZXR1cm4gdGhpcycpKCk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSBnbG9iYWwgb2JqZWN0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtudWxsfE9iamVjdH0gUmV0dXJucyBgdmFsdWVgIGlmIGl0J3MgYSBnbG9iYWwgb2JqZWN0LCBlbHNlIGBudWxsYC5cbiAqL1xuZnVuY3Rpb24gY2hlY2tHbG9iYWwodmFsdWUpIHtcbiAgcmV0dXJuICh2YWx1ZSAmJiB2YWx1ZS5PYmplY3QgPT09IE9iamVjdCkgPyB2YWx1ZSA6IG51bGw7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gcm9vdDtcbiIsIi8qKlxuICogbG9kYXNoIDMuMC4yIChDdXN0b20gQnVpbGQpIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQnVpbGQ6IGBsb2Rhc2ggbW9kZXJuIG1vZHVsYXJpemUgZXhwb3J0cz1cIm5wbVwiIC1vIC4vYFxuICogQ29weXJpZ2h0IDIwMTItMjAxNSBUaGUgRG9qbyBGb3VuZGF0aW9uIDxodHRwOi8vZG9qb2ZvdW5kYXRpb24ub3JnLz5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgMjAwOS0yMDE1IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICovXG52YXIgYmFzZUZvciA9IHJlcXVpcmUoJ2xvZGFzaC5fYmFzZWZvcicpLFxuICAgIGJpbmRDYWxsYmFjayA9IHJlcXVpcmUoJ2xvZGFzaC5fYmluZGNhbGxiYWNrJyksXG4gICAga2V5cyA9IHJlcXVpcmUoJ2xvZGFzaC5rZXlzJyk7XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8uZm9yT3duYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrXG4gKiBzaG9ydGhhbmRzIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGl0ZXJhdGVlIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICovXG5mdW5jdGlvbiBiYXNlRm9yT3duKG9iamVjdCwgaXRlcmF0ZWUpIHtcbiAgcmV0dXJuIGJhc2VGb3Iob2JqZWN0LCBpdGVyYXRlZSwga2V5cyk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIGZvciBgXy5mb3JPd25gIG9yIGBfLmZvck93blJpZ2h0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gb2JqZWN0RnVuYyBUaGUgZnVuY3Rpb24gdG8gaXRlcmF0ZSBvdmVyIGFuIG9iamVjdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGVhY2ggZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUZvck93bihvYmplY3RGdW5jKSB7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QsIGl0ZXJhdGVlLCB0aGlzQXJnKSB7XG4gICAgaWYgKHR5cGVvZiBpdGVyYXRlZSAhPSAnZnVuY3Rpb24nIHx8IHRoaXNBcmcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaXRlcmF0ZWUgPSBiaW5kQ2FsbGJhY2soaXRlcmF0ZWUsIHRoaXNBcmcsIDMpO1xuICAgIH1cbiAgICByZXR1cm4gb2JqZWN0RnVuYyhvYmplY3QsIGl0ZXJhdGVlKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBJdGVyYXRlcyBvdmVyIG93biBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb2YgYW4gb2JqZWN0IGludm9raW5nIGBpdGVyYXRlZWBcbiAqIGZvciBlYWNoIHByb3BlcnR5LiBUaGUgYGl0ZXJhdGVlYCBpcyBib3VuZCB0byBgdGhpc0FyZ2AgYW5kIGludm9rZWQgd2l0aFxuICogdGhyZWUgYXJndW1lbnRzOiAodmFsdWUsIGtleSwgb2JqZWN0KS4gSXRlcmF0ZWUgZnVuY3Rpb25zIG1heSBleGl0IGl0ZXJhdGlvblxuICogZWFybHkgYnkgZXhwbGljaXRseSByZXR1cm5pbmcgYGZhbHNlYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtpdGVyYXRlZT1fLmlkZW50aXR5XSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHsqfSBbdGhpc0FyZ10gVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBpdGVyYXRlZWAuXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGBvYmplY3RgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBGb28oKSB7XG4gKiAgIHRoaXMuYSA9IDE7XG4gKiAgIHRoaXMuYiA9IDI7XG4gKiB9XG4gKlxuICogRm9vLnByb3RvdHlwZS5jID0gMztcbiAqXG4gKiBfLmZvck93bihuZXcgRm9vLCBmdW5jdGlvbih2YWx1ZSwga2V5KSB7XG4gKiAgIGNvbnNvbGUubG9nKGtleSk7XG4gKiB9KTtcbiAqIC8vID0+IGxvZ3MgJ2EnIGFuZCAnYicgKGl0ZXJhdGlvbiBvcmRlciBpcyBub3QgZ3VhcmFudGVlZClcbiAqL1xudmFyIGZvck93biA9IGNyZWF0ZUZvck93bihiYXNlRm9yT3duKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmb3JPd247XG4iLCIvKipcbiAqIGxvZGFzaCAzLjAuMyAoQ3VzdG9tIEJ1aWxkKSA8aHR0cHM6Ly9sb2Rhc2guY29tLz5cbiAqIEJ1aWxkOiBgbG9kYXNoIG1vZHVsYXJpemUgZXhwb3J0cz1cIm5wbVwiIC1vIC4vYFxuICogQ29weXJpZ2h0IDIwMTItMjAxNiBUaGUgRG9qbyBGb3VuZGF0aW9uIDxodHRwOi8vZG9qb2ZvdW5kYXRpb24ub3JnLz5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgMjAwOS0yMDE2IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICovXG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYGJhc2VGb3JJbmAgYW5kIGBiYXNlRm9yT3duYCB3aGljaCBpdGVyYXRlc1xuICogb3ZlciBgb2JqZWN0YCBwcm9wZXJ0aWVzIHJldHVybmVkIGJ5IGBrZXlzRnVuY2AgaW52b2tpbmcgYGl0ZXJhdGVlYCBmb3JcbiAqIGVhY2ggcHJvcGVydHkuIEl0ZXJhdGVlIGZ1bmN0aW9ucyBtYXkgZXhpdCBpdGVyYXRpb24gZWFybHkgYnkgZXhwbGljaXRseVxuICogcmV0dXJuaW5nIGBmYWxzZWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSBUaGUgZnVuY3Rpb24gaW52b2tlZCBwZXIgaXRlcmF0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5c0Z1bmMgVGhlIGZ1bmN0aW9uIHRvIGdldCB0aGUga2V5cyBvZiBgb2JqZWN0YC5cbiAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYG9iamVjdGAuXG4gKi9cbnZhciBiYXNlRm9yID0gY3JlYXRlQmFzZUZvcigpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBiYXNlIGZ1bmN0aW9uIGZvciBtZXRob2RzIGxpa2UgYF8uZm9ySW5gLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtmcm9tUmlnaHRdIFNwZWNpZnkgaXRlcmF0aW5nIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGJhc2UgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUJhc2VGb3IoZnJvbVJpZ2h0KSB7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QsIGl0ZXJhdGVlLCBrZXlzRnVuYykge1xuICAgIHZhciBpbmRleCA9IC0xLFxuICAgICAgICBpdGVyYWJsZSA9IE9iamVjdChvYmplY3QpLFxuICAgICAgICBwcm9wcyA9IGtleXNGdW5jKG9iamVjdCksXG4gICAgICAgIGxlbmd0aCA9IHByb3BzLmxlbmd0aDtcblxuICAgIHdoaWxlIChsZW5ndGgtLSkge1xuICAgICAgdmFyIGtleSA9IHByb3BzW2Zyb21SaWdodCA/IGxlbmd0aCA6ICsraW5kZXhdO1xuICAgICAgaWYgKGl0ZXJhdGVlKGl0ZXJhYmxlW2tleV0sIGtleSwgaXRlcmFibGUpID09PSBmYWxzZSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdDtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRm9yO1xuIiwiLyoqXG4gKiBsb2Rhc2ggMy4wLjEgKEN1c3RvbSBCdWlsZCkgPGh0dHBzOi8vbG9kYXNoLmNvbS8+XG4gKiBCdWlsZDogYGxvZGFzaCBtb2Rlcm4gbW9kdWxhcml6ZSBleHBvcnRzPVwibnBtXCIgLW8gLi9gXG4gKiBDb3B5cmlnaHQgMjAxMi0yMDE1IFRoZSBEb2pvIEZvdW5kYXRpb24gPGh0dHA6Ly9kb2pvZm91bmRhdGlvbi5vcmcvPlxuICogQmFzZWQgb24gVW5kZXJzY29yZS5qcyAxLjguMyA8aHR0cDovL3VuZGVyc2NvcmVqcy5vcmcvTElDRU5TRT5cbiAqIENvcHlyaWdodCAyMDA5LTIwMTUgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbiAqIEF2YWlsYWJsZSB1bmRlciBNSVQgbGljZW5zZSA8aHR0cHM6Ly9sb2Rhc2guY29tL2xpY2Vuc2U+XG4gKi9cblxuLyoqXG4gKiBBIHNwZWNpYWxpemVkIHZlcnNpb24gb2YgYGJhc2VDYWxsYmFja2Agd2hpY2ggb25seSBzdXBwb3J0cyBgdGhpc2AgYmluZGluZ1xuICogYW5kIHNwZWNpZnlpbmcgdGhlIG51bWJlciBvZiBhcmd1bWVudHMgdG8gcHJvdmlkZSB0byBgZnVuY2AuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGJpbmQuXG4gKiBAcGFyYW0geyp9IHRoaXNBcmcgVGhlIGB0aGlzYCBiaW5kaW5nIG9mIGBmdW5jYC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbYXJnQ291bnRdIFRoZSBudW1iZXIgb2YgYXJndW1lbnRzIHRvIHByb3ZpZGUgdG8gYGZ1bmNgLlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBjYWxsYmFjay5cbiAqL1xuZnVuY3Rpb24gYmluZENhbGxiYWNrKGZ1bmMsIHRoaXNBcmcsIGFyZ0NvdW50KSB7XG4gIGlmICh0eXBlb2YgZnVuYyAhPSAnZnVuY3Rpb24nKSB7XG4gICAgcmV0dXJuIGlkZW50aXR5O1xuICB9XG4gIGlmICh0aGlzQXJnID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4gZnVuYztcbiAgfVxuICBzd2l0Y2ggKGFyZ0NvdW50KSB7XG4gICAgY2FzZSAxOiByZXR1cm4gZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJldHVybiBmdW5jLmNhbGwodGhpc0FyZywgdmFsdWUpO1xuICAgIH07XG4gICAgY2FzZSAzOiByZXR1cm4gZnVuY3Rpb24odmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIHZhbHVlLCBpbmRleCwgY29sbGVjdGlvbik7XG4gICAgfTtcbiAgICBjYXNlIDQ6IHJldHVybiBmdW5jdGlvbihhY2N1bXVsYXRvciwgdmFsdWUsIGluZGV4LCBjb2xsZWN0aW9uKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIGFjY3VtdWxhdG9yLCB2YWx1ZSwgaW5kZXgsIGNvbGxlY3Rpb24pO1xuICAgIH07XG4gICAgY2FzZSA1OiByZXR1cm4gZnVuY3Rpb24odmFsdWUsIG90aGVyLCBrZXksIG9iamVjdCwgc291cmNlKSB7XG4gICAgICByZXR1cm4gZnVuYy5jYWxsKHRoaXNBcmcsIHZhbHVlLCBvdGhlciwga2V5LCBvYmplY3QsIHNvdXJjZSk7XG4gICAgfTtcbiAgfVxuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpc0FyZywgYXJndW1lbnRzKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCByZXR1cm5zIHRoZSBmaXJzdCBhcmd1bWVudCBwcm92aWRlZCB0byBpdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IFV0aWxpdHlcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgQW55IHZhbHVlLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgYHZhbHVlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIG9iamVjdCA9IHsgJ3VzZXInOiAnZnJlZCcgfTtcbiAqXG4gKiBfLmlkZW50aXR5KG9iamVjdCkgPT09IG9iamVjdDtcbiAqIC8vID0+IHRydWVcbiAqL1xuZnVuY3Rpb24gaWRlbnRpdHkodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGJpbmRDYWxsYmFjaztcbiIsIi8qKlxuICogbG9kYXNoIDMuMS4yIChDdXN0b20gQnVpbGQpIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQnVpbGQ6IGBsb2Rhc2ggbW9kZXJuIG1vZHVsYXJpemUgZXhwb3J0cz1cIm5wbVwiIC1vIC4vYFxuICogQ29weXJpZ2h0IDIwMTItMjAxNSBUaGUgRG9qbyBGb3VuZGF0aW9uIDxodHRwOi8vZG9qb2ZvdW5kYXRpb24ub3JnLz5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgMjAwOS0yMDE1IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICovXG52YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnbG9kYXNoLl9nZXRuYXRpdmUnKSxcbiAgICBpc0FyZ3VtZW50cyA9IHJlcXVpcmUoJ2xvZGFzaC5pc2FyZ3VtZW50cycpLFxuICAgIGlzQXJyYXkgPSByZXF1aXJlKCdsb2Rhc2guaXNhcnJheScpO1xuXG4vKiogVXNlZCB0byBkZXRlY3QgdW5zaWduZWQgaW50ZWdlciB2YWx1ZXMuICovXG52YXIgcmVJc1VpbnQgPSAvXlxcZCskLztcblxuLyoqIFVzZWQgZm9yIG5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlS2V5cyA9IGdldE5hdGl2ZShPYmplY3QsICdrZXlzJyk7XG5cbi8qKlxuICogVXNlZCBhcyB0aGUgW21heGltdW0gbGVuZ3RoXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1udW1iZXIubWF4X3NhZmVfaW50ZWdlcilcbiAqIG9mIGFuIGFycmF5LWxpa2UgdmFsdWUuXG4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5wcm9wZXJ0eWAgd2l0aG91dCBzdXBwb3J0IGZvciBkZWVwIHBhdGhzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBrZXkgb2YgdGhlIHByb3BlcnR5IHRvIGdldC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gUmV0dXJucyB0aGUgbmV3IGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBiYXNlUHJvcGVydHkoa2V5KSB7XG4gIHJldHVybiBmdW5jdGlvbihvYmplY3QpIHtcbiAgICByZXR1cm4gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTtcbiAgfTtcbn1cblxuLyoqXG4gKiBHZXRzIHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IHZhbHVlIG9mIGBvYmplY3RgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gYXZvaWQgYSBbSklUIGJ1Z10oaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTE0Mjc5MilcbiAqIHRoYXQgYWZmZWN0cyBTYWZhcmkgb24gYXQgbGVhc3QgaU9TIDguMS04LjMgQVJNNjQuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBcImxlbmd0aFwiIHZhbHVlLlxuICovXG52YXIgZ2V0TGVuZ3RoID0gYmFzZVByb3BlcnR5KCdsZW5ndGgnKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFycmF5LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNBcnJheUxpa2UodmFsdWUpIHtcbiAgcmV0dXJuIHZhbHVlICE9IG51bGwgJiYgaXNMZW5ndGgoZ2V0TGVuZ3RoKHZhbHVlKSk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBhcnJheS1saWtlIGluZGV4LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbbGVuZ3RoPU1BWF9TQUZFX0lOVEVHRVJdIFRoZSB1cHBlciBib3VuZHMgb2YgYSB2YWxpZCBpbmRleC5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgaW5kZXgsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNJbmRleCh2YWx1ZSwgbGVuZ3RoKSB7XG4gIHZhbHVlID0gKHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyB8fCByZUlzVWludC50ZXN0KHZhbHVlKSkgPyArdmFsdWUgOiAtMTtcbiAgbGVuZ3RoID0gbGVuZ3RoID09IG51bGwgPyBNQVhfU0FGRV9JTlRFR0VSIDogbGVuZ3RoO1xuICByZXR1cm4gdmFsdWUgPiAtMSAmJiB2YWx1ZSAlIDEgPT0gMCAmJiB2YWx1ZSA8IGxlbmd0aDtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgbGVuZ3RoLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIGJhc2VkIG9uIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b2xlbmd0aCkuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBsZW5ndGgsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNMZW5ndGgodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG59XG5cbi8qKlxuICogQSBmYWxsYmFjayBpbXBsZW1lbnRhdGlvbiBvZiBgT2JqZWN0LmtleXNgIHdoaWNoIGNyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlXG4gKiBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqL1xuZnVuY3Rpb24gc2hpbUtleXMob2JqZWN0KSB7XG4gIHZhciBwcm9wcyA9IGtleXNJbihvYmplY3QpLFxuICAgICAgcHJvcHNMZW5ndGggPSBwcm9wcy5sZW5ndGgsXG4gICAgICBsZW5ndGggPSBwcm9wc0xlbmd0aCAmJiBvYmplY3QubGVuZ3RoO1xuXG4gIHZhciBhbGxvd0luZGV4ZXMgPSAhIWxlbmd0aCAmJiBpc0xlbmd0aChsZW5ndGgpICYmXG4gICAgKGlzQXJyYXkob2JqZWN0KSB8fCBpc0FyZ3VtZW50cyhvYmplY3QpKTtcblxuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgcHJvcHNMZW5ndGgpIHtcbiAgICB2YXIga2V5ID0gcHJvcHNbaW5kZXhdO1xuICAgIGlmICgoYWxsb3dJbmRleGVzICYmIGlzSW5kZXgoa2V5LCBsZW5ndGgpKSB8fCBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkge1xuICAgICAgcmVzdWx0LnB1c2goa2V5KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyB0aGUgW2xhbmd1YWdlIHR5cGVdKGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDgpIG9mIGBPYmplY3RgLlxuICogKGUuZy4gYXJyYXlzLCBmdW5jdGlvbnMsIG9iamVjdHMsIHJlZ2V4ZXMsIGBuZXcgTnVtYmVyKDApYCwgYW5kIGBuZXcgU3RyaW5nKCcnKWApXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0KHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdCgxKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gIC8vIEF2b2lkIGEgVjggSklUIGJ1ZyBpbiBDaHJvbWUgMTktMjAuXG4gIC8vIFNlZSBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MjI5MSBmb3IgbW9yZSBkZXRhaWxzLlxuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgcmV0dXJuICEhdmFsdWUgJiYgKHR5cGUgPT0gJ29iamVjdCcgfHwgdHlwZSA9PSAnZnVuY3Rpb24nKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGFuIGFycmF5IG9mIHRoZSBvd24gZW51bWVyYWJsZSBwcm9wZXJ0eSBuYW1lcyBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogTm9uLW9iamVjdCB2YWx1ZXMgYXJlIGNvZXJjZWQgdG8gb2JqZWN0cy4gU2VlIHRoZVxuICogW0VTIHNwZWNdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLW9iamVjdC5rZXlzKVxuICogZm9yIG1vcmUgZGV0YWlscy5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IE9iamVjdFxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcy5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gRm9vKCkge1xuICogICB0aGlzLmEgPSAxO1xuICogICB0aGlzLmIgPSAyO1xuICogfVxuICpcbiAqIEZvby5wcm90b3R5cGUuYyA9IDM7XG4gKlxuICogXy5rZXlzKG5ldyBGb28pO1xuICogLy8gPT4gWydhJywgJ2InXSAoaXRlcmF0aW9uIG9yZGVyIGlzIG5vdCBndWFyYW50ZWVkKVxuICpcbiAqIF8ua2V5cygnaGknKTtcbiAqIC8vID0+IFsnMCcsICcxJ11cbiAqL1xudmFyIGtleXMgPSAhbmF0aXZlS2V5cyA/IHNoaW1LZXlzIDogZnVuY3Rpb24ob2JqZWN0KSB7XG4gIHZhciBDdG9yID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3QuY29uc3RydWN0b3I7XG4gIGlmICgodHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yLnByb3RvdHlwZSA9PT0gb2JqZWN0KSB8fFxuICAgICAgKHR5cGVvZiBvYmplY3QgIT0gJ2Z1bmN0aW9uJyAmJiBpc0FycmF5TGlrZShvYmplY3QpKSkge1xuICAgIHJldHVybiBzaGltS2V5cyhvYmplY3QpO1xuICB9XG4gIHJldHVybiBpc09iamVjdChvYmplY3QpID8gbmF0aXZlS2V5cyhvYmplY3QpIDogW107XG59O1xuXG4vKipcbiAqIENyZWF0ZXMgYW4gYXJyYXkgb2YgdGhlIG93biBhbmQgaW5oZXJpdGVkIGVudW1lcmFibGUgcHJvcGVydHkgbmFtZXMgb2YgYG9iamVjdGAuXG4gKlxuICogKipOb3RlOioqIE5vbi1vYmplY3QgdmFsdWVzIGFyZSBjb2VyY2VkIHRvIG9iamVjdHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBPYmplY3RcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgYXJyYXkgb2YgcHJvcGVydHkgbmFtZXMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGZ1bmN0aW9uIEZvbygpIHtcbiAqICAgdGhpcy5hID0gMTtcbiAqICAgdGhpcy5iID0gMjtcbiAqIH1cbiAqXG4gKiBGb28ucHJvdG90eXBlLmMgPSAzO1xuICpcbiAqIF8ua2V5c0luKG5ldyBGb28pO1xuICogLy8gPT4gWydhJywgJ2InLCAnYyddIChpdGVyYXRpb24gb3JkZXIgaXMgbm90IGd1YXJhbnRlZWQpXG4gKi9cbmZ1bmN0aW9uIGtleXNJbihvYmplY3QpIHtcbiAgaWYgKG9iamVjdCA9PSBudWxsKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIGlmICghaXNPYmplY3Qob2JqZWN0KSkge1xuICAgIG9iamVjdCA9IE9iamVjdChvYmplY3QpO1xuICB9XG4gIHZhciBsZW5ndGggPSBvYmplY3QubGVuZ3RoO1xuICBsZW5ndGggPSAobGVuZ3RoICYmIGlzTGVuZ3RoKGxlbmd0aCkgJiZcbiAgICAoaXNBcnJheShvYmplY3QpIHx8IGlzQXJndW1lbnRzKG9iamVjdCkpICYmIGxlbmd0aCkgfHwgMDtcblxuICB2YXIgQ3RvciA9IG9iamVjdC5jb25zdHJ1Y3RvcixcbiAgICAgIGluZGV4ID0gLTEsXG4gICAgICBpc1Byb3RvID0gdHlwZW9mIEN0b3IgPT0gJ2Z1bmN0aW9uJyAmJiBDdG9yLnByb3RvdHlwZSA9PT0gb2JqZWN0LFxuICAgICAgcmVzdWx0ID0gQXJyYXkobGVuZ3RoKSxcbiAgICAgIHNraXBJbmRleGVzID0gbGVuZ3RoID4gMDtcblxuICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xuICAgIHJlc3VsdFtpbmRleF0gPSAoaW5kZXggKyAnJyk7XG4gIH1cbiAgZm9yICh2YXIga2V5IGluIG9iamVjdCkge1xuICAgIGlmICghKHNraXBJbmRleGVzICYmIGlzSW5kZXgoa2V5LCBsZW5ndGgpKSAmJlxuICAgICAgICAhKGtleSA9PSAnY29uc3RydWN0b3InICYmIChpc1Byb3RvIHx8ICFoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkpKSB7XG4gICAgICByZXN1bHQucHVzaChrZXkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGtleXM7XG4iLCIvKipcbiAqIGxvZGFzaCAzLjkuMSAoQ3VzdG9tIEJ1aWxkKSA8aHR0cHM6Ly9sb2Rhc2guY29tLz5cbiAqIEJ1aWxkOiBgbG9kYXNoIG1vZGVybiBtb2R1bGFyaXplIGV4cG9ydHM9XCJucG1cIiAtbyAuL2BcbiAqIENvcHlyaWdodCAyMDEyLTIwMTUgVGhlIERvam8gRm91bmRhdGlvbiA8aHR0cDovL2Rvam9mb3VuZGF0aW9uLm9yZy8+XG4gKiBCYXNlZCBvbiBVbmRlcnNjb3JlLmpzIDEuOC4zIDxodHRwOi8vdW5kZXJzY29yZWpzLm9yZy9MSUNFTlNFPlxuICogQ29weXJpZ2h0IDIwMDktMjAxNSBKZXJlbXkgQXNoa2VuYXMsIERvY3VtZW50Q2xvdWQgYW5kIEludmVzdGlnYXRpdmUgUmVwb3J0ZXJzICYgRWRpdG9yc1xuICogQXZhaWxhYmxlIHVuZGVyIE1JVCBsaWNlbnNlIDxodHRwczovL2xvZGFzaC5jb20vbGljZW5zZT5cbiAqL1xuXG4vKiogYE9iamVjdCN0b1N0cmluZ2AgcmVzdWx0IHJlZmVyZW5jZXMuICovXG52YXIgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBob3N0IGNvbnN0cnVjdG9ycyAoU2FmYXJpID4gNSkuICovXG52YXIgcmVJc0hvc3RDdG9yID0gL15cXFtvYmplY3QgLis/Q29uc3RydWN0b3JcXF0kLztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc09iamVjdExpa2UodmFsdWUpIHtcbiAgcmV0dXJuICEhdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xufVxuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVjb21waWxlZCBzb3VyY2Ugb2YgZnVuY3Rpb25zLiAqL1xudmFyIGZuVG9TdHJpbmcgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBpZiBhIG1ldGhvZCBpcyBuYXRpdmUuICovXG52YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgK1xuICBmblRvU3RyaW5nLmNhbGwoaGFzT3duUHJvcGVydHkpLnJlcGxhY2UoL1tcXFxcXiQuKis/KClbXFxde318XS9nLCAnXFxcXCQmJylcbiAgLnJlcGxhY2UoL2hhc093blByb3BlcnR5fChmdW5jdGlvbikuKj8oPz1cXFxcXFwoKXwgZm9yIC4rPyg/PVxcXFxcXF0pL2csICckMS4qPycpICsgJyQnXG4pO1xuXG4vKipcbiAqIEdldHMgdGhlIG5hdGl2ZSBmdW5jdGlvbiBhdCBga2V5YCBvZiBgb2JqZWN0YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtPYmplY3R9IG9iamVjdCBUaGUgb2JqZWN0IHRvIHF1ZXJ5LlxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBtZXRob2QgdG8gZ2V0LlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGZ1bmN0aW9uIGlmIGl0J3MgbmF0aXZlLCBlbHNlIGB1bmRlZmluZWRgLlxuICovXG5mdW5jdGlvbiBnZXROYXRpdmUob2JqZWN0LCBrZXkpIHtcbiAgdmFyIHZhbHVlID0gb2JqZWN0ID09IG51bGwgPyB1bmRlZmluZWQgOiBvYmplY3Rba2V5XTtcbiAgcmV0dXJuIGlzTmF0aXZlKHZhbHVlKSA/IHZhbHVlIDogdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0Z1bmN0aW9uKF8pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNGdW5jdGlvbigvYWJjLyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XG4gIC8vIFRoZSB1c2Ugb2YgYE9iamVjdCN0b1N0cmluZ2AgYXZvaWRzIGlzc3VlcyB3aXRoIHRoZSBgdHlwZW9mYCBvcGVyYXRvclxuICAvLyBpbiBvbGRlciB2ZXJzaW9ucyBvZiBDaHJvbWUgYW5kIFNhZmFyaSB3aGljaCByZXR1cm4gJ2Z1bmN0aW9uJyBmb3IgcmVnZXhlc1xuICAvLyBhbmQgU2FmYXJpIDggZXF1aXZhbGVudHMgd2hpY2ggcmV0dXJuICdvYmplY3QnIGZvciB0eXBlZCBhcnJheSBjb25zdHJ1Y3RvcnMuXG4gIHJldHVybiBpc09iamVjdCh2YWx1ZSkgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gZnVuY1RhZztcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyB0aGUgW2xhbmd1YWdlIHR5cGVdKGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDgpIG9mIGBPYmplY3RgLlxuICogKGUuZy4gYXJyYXlzLCBmdW5jdGlvbnMsIG9iamVjdHMsIHJlZ2V4ZXMsIGBuZXcgTnVtYmVyKDApYCwgYW5kIGBuZXcgU3RyaW5nKCcnKWApXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0KHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdCgxKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gIC8vIEF2b2lkIGEgVjggSklUIGJ1ZyBpbiBDaHJvbWUgMTktMjAuXG4gIC8vIFNlZSBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MjI5MSBmb3IgbW9yZSBkZXRhaWxzLlxuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgcmV0dXJuICEhdmFsdWUgJiYgKHR5cGUgPT0gJ29iamVjdCcgfHwgdHlwZSA9PSAnZnVuY3Rpb24nKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIG5hdGl2ZSBmdW5jdGlvbi5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24sIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc05hdGl2ZShBcnJheS5wcm90b3R5cGUucHVzaCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc05hdGl2ZShfKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzTmF0aXZlKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHJldHVybiByZUlzTmF0aXZlLnRlc3QoZm5Ub1N0cmluZy5jYWxsKHZhbHVlKSk7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgcmVJc0hvc3RDdG9yLnRlc3QodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGdldE5hdGl2ZTtcbiIsIi8qKlxuICogbG9kYXNoIChDdXN0b20gQnVpbGQpIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQnVpbGQ6IGBsb2Rhc2ggbW9kdWxhcml6ZSBleHBvcnRzPVwibnBtXCIgLW8gLi9gXG4gKiBDb3B5cmlnaHQgalF1ZXJ5IEZvdW5kYXRpb24gYW5kIG90aGVyIGNvbnRyaWJ1dG9ycyA8aHR0cHM6Ly9qcXVlcnkub3JnLz5cbiAqIFJlbGVhc2VkIHVuZGVyIE1JVCBsaWNlbnNlIDxodHRwczovL2xvZGFzaC5jb20vbGljZW5zZT5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbiAqL1xuXG4vKiogVXNlZCBhcyByZWZlcmVuY2VzIGZvciB2YXJpb3VzIGBOdW1iZXJgIGNvbnN0YW50cy4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIGFyZ3NUYWcgPSAnW29iamVjdCBBcmd1bWVudHNdJyxcbiAgICBmdW5jVGFnID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcbiAgICBnZW5UYWcgPSAnW29iamVjdCBHZW5lcmF0b3JGdW5jdGlvbl0nO1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLnByb3BlcnR5YCB3aXRob3V0IHN1cHBvcnQgZm9yIGRlZXAgcGF0aHMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgcHJvcGVydHkgdG8gZ2V0LlxuICogQHJldHVybnMge0Z1bmN0aW9ufSBSZXR1cm5zIHRoZSBuZXcgYWNjZXNzb3IgZnVuY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIGJhc2VQcm9wZXJ0eShrZXkpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIHJldHVybiBvYmplY3QgPT0gbnVsbCA/IHVuZGVmaW5lZCA6IG9iamVjdFtrZXldO1xuICB9O1xufVxuXG4vKiogVXNlZCBmb3IgYnVpbHQtaW4gbWV0aG9kIHJlZmVyZW5jZXMuICovXG52YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlO1xuXG4vKiogVXNlZCB0byBjaGVjayBvYmplY3RzIGZvciBvd24gcHJvcGVydGllcy4gKi9cbnZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5O1xuXG4vKipcbiAqIFVzZWQgdG8gcmVzb2x2ZSB0aGVcbiAqIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgcHJvcGVydHlJc0VudW1lcmFibGUgPSBvYmplY3RQcm90by5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblxuLyoqXG4gKiBHZXRzIHRoZSBcImxlbmd0aFwiIHByb3BlcnR5IHZhbHVlIG9mIGBvYmplY3RgLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgdG8gYXZvaWQgYVxuICogW0pJVCBidWddKGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xNDI3OTIpIHRoYXQgYWZmZWN0c1xuICogU2FmYXJpIG9uIGF0IGxlYXN0IGlPUyA4LjEtOC4zIEFSTTY0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgXCJsZW5ndGhcIiB2YWx1ZS5cbiAqL1xudmFyIGdldExlbmd0aCA9IGJhc2VQcm9wZXJ0eSgnbGVuZ3RoJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgbGlrZWx5IGFuIGBhcmd1bWVudHNgIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhbiBgYXJndW1lbnRzYCBvYmplY3QsXG4gKiAgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJndW1lbnRzKGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcmd1bWVudHMoWzEsIDIsIDNdKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXJndW1lbnRzKHZhbHVlKSB7XG4gIC8vIFNhZmFyaSA4LjEgaW5jb3JyZWN0bHkgbWFrZXMgYGFyZ3VtZW50cy5jYWxsZWVgIGVudW1lcmFibGUgaW4gc3RyaWN0IG1vZGUuXG4gIHJldHVybiBpc0FycmF5TGlrZU9iamVjdCh2YWx1ZSkgJiYgaGFzT3duUHJvcGVydHkuY2FsbCh2YWx1ZSwgJ2NhbGxlZScpICYmXG4gICAgKCFwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKHZhbHVlLCAnY2FsbGVlJykgfHwgb2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gYXJnc1RhZyk7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZS4gQSB2YWx1ZSBpcyBjb25zaWRlcmVkIGFycmF5LWxpa2UgaWYgaXQnc1xuICogbm90IGEgZnVuY3Rpb24gYW5kIGhhcyBhIGB2YWx1ZS5sZW5ndGhgIHRoYXQncyBhbiBpbnRlZ2VyIGdyZWF0ZXIgdGhhbiBvclxuICogZXF1YWwgdG8gYDBgIGFuZCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gYE51bWJlci5NQVhfU0FGRV9JTlRFR0VSYC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNBcnJheUxpa2UoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXlMaWtlKGRvY3VtZW50LmJvZHkuY2hpbGRyZW4pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheUxpa2UoJ2FiYycpO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNBcnJheUxpa2UoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzQXJyYXlMaWtlKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIGlzTGVuZ3RoKGdldExlbmd0aCh2YWx1ZSkpICYmICFpc0Z1bmN0aW9uKHZhbHVlKTtcbn1cblxuLyoqXG4gKiBUaGlzIG1ldGhvZCBpcyBsaWtlIGBfLmlzQXJyYXlMaWtlYCBleGNlcHQgdGhhdCBpdCBhbHNvIGNoZWNrcyBpZiBgdmFsdWVgXG4gKiBpcyBhbiBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSA0LjAuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gYXJyYXktbGlrZSBvYmplY3QsXG4gKiAgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzQXJyYXlMaWtlT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5TGlrZU9iamVjdChkb2N1bWVudC5ib2R5LmNoaWxkcmVuKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzQXJyYXlMaWtlT2JqZWN0KCdhYmMnKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0FycmF5TGlrZU9iamVjdChfLm5vb3ApO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNBcnJheUxpa2VPYmplY3QodmFsdWUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgaXNBcnJheUxpa2UodmFsdWUpO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDAuMS4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIGZ1bmN0aW9uLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNGdW5jdGlvbihfKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzRnVuY3Rpb24oL2FiYy8pO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNGdW5jdGlvbih2YWx1ZSkge1xuICAvLyBUaGUgdXNlIG9mIGBPYmplY3QjdG9TdHJpbmdgIGF2b2lkcyBpc3N1ZXMgd2l0aCB0aGUgYHR5cGVvZmAgb3BlcmF0b3JcbiAgLy8gaW4gU2FmYXJpIDggd2hpY2ggcmV0dXJucyAnb2JqZWN0JyBmb3IgdHlwZWQgYXJyYXkgYW5kIHdlYWsgbWFwIGNvbnN0cnVjdG9ycyxcbiAgLy8gYW5kIFBoYW50b21KUyAxLjkgd2hpY2ggcmV0dXJucyAnZnVuY3Rpb24nIGZvciBgTm9kZUxpc3RgIGluc3RhbmNlcy5cbiAgdmFyIHRhZyA9IGlzT2JqZWN0KHZhbHVlKSA/IG9iamVjdFRvU3RyaW5nLmNhbGwodmFsdWUpIDogJyc7XG4gIHJldHVybiB0YWcgPT0gZnVuY1RhZyB8fCB0YWcgPT0gZ2VuVGFnO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBsZW5ndGguXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gaXMgbG9vc2VseSBiYXNlZCBvblxuICogW2BUb0xlbmd0aGBdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvbGVuZ3RoKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQHNpbmNlIDQuMC4wXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCxcbiAqICBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNMZW5ndGgoMyk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0xlbmd0aChOdW1iZXIuTUlOX1ZBTFVFKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc0xlbmd0aChJbmZpbml0eSk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNMZW5ndGgoJzMnKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzTGVuZ3RoKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ251bWJlcicgJiZcbiAgICB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgdGhlXG4gKiBbbGFuZ3VhZ2UgdHlwZV0oaHR0cDovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLWVjbWFzY3JpcHQtbGFuZ3VhZ2UtdHlwZXMpXG4gKiBvZiBgT2JqZWN0YC4gKGUuZy4gYXJyYXlzLCBmdW5jdGlvbnMsIG9iamVjdHMsIHJlZ2V4ZXMsIGBuZXcgTnVtYmVyKDApYCwgYW5kIGBuZXcgU3RyaW5nKCcnKWApXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBzaW5jZSAwLjEuMFxuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3Qoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KF8ubm9vcCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdChudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICByZXR1cm4gISF2YWx1ZSAmJiAodHlwZSA9PSAnb2JqZWN0JyB8fCB0eXBlID09ICdmdW5jdGlvbicpO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLiBBIHZhbHVlIGlzIG9iamVjdC1saWtlIGlmIGl0J3Mgbm90IGBudWxsYFxuICogYW5kIGhhcyBhIGB0eXBlb2ZgIHJlc3VsdCBvZiBcIm9iamVjdFwiLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAc2luY2UgNC4wLjBcbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShbMSwgMiwgM10pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKF8ubm9vcCk7XG4gKiAvLyA9PiBmYWxzZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKG51bGwpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3RMaWtlKHZhbHVlKSB7XG4gIHJldHVybiAhIXZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0Jztcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBpc0FyZ3VtZW50cztcbiIsIi8qKlxuICogbG9kYXNoIDMuMC40IChDdXN0b20gQnVpbGQpIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQnVpbGQ6IGBsb2Rhc2ggbW9kZXJuIG1vZHVsYXJpemUgZXhwb3J0cz1cIm5wbVwiIC1vIC4vYFxuICogQ29weXJpZ2h0IDIwMTItMjAxNSBUaGUgRG9qbyBGb3VuZGF0aW9uIDxodHRwOi8vZG9qb2ZvdW5kYXRpb24ub3JnLz5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgMjAwOS0yMDE1IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICovXG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBhcnJheVRhZyA9ICdbb2JqZWN0IEFycmF5XScsXG4gICAgZnVuY1RhZyA9ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBob3N0IGNvbnN0cnVjdG9ycyAoU2FmYXJpID4gNSkuICovXG52YXIgcmVJc0hvc3RDdG9yID0gL15cXFtvYmplY3QgLis/Q29uc3RydWN0b3JcXF0kLztcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc09iamVjdExpa2UodmFsdWUpIHtcbiAgcmV0dXJuICEhdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xufVxuXG4vKiogVXNlZCBmb3IgbmF0aXZlIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqIFVzZWQgdG8gcmVzb2x2ZSB0aGUgZGVjb21waWxlZCBzb3VyY2Ugb2YgZnVuY3Rpb25zLiAqL1xudmFyIGZuVG9TdHJpbmcgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGNoZWNrIG9iamVjdHMgZm9yIG93biBwcm9wZXJ0aWVzLiAqL1xudmFyIGhhc093blByb3BlcnR5ID0gb2JqZWN0UHJvdG8uaGFzT3duUHJvcGVydHk7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9ialRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKiBVc2VkIHRvIGRldGVjdCBpZiBhIG1ldGhvZCBpcyBuYXRpdmUuICovXG52YXIgcmVJc05hdGl2ZSA9IFJlZ0V4cCgnXicgK1xuICBmblRvU3RyaW5nLmNhbGwoaGFzT3duUHJvcGVydHkpLnJlcGxhY2UoL1tcXFxcXiQuKis/KClbXFxde318XS9nLCAnXFxcXCQmJylcbiAgLnJlcGxhY2UoL2hhc093blByb3BlcnR5fChmdW5jdGlvbikuKj8oPz1cXFxcXFwoKXwgZm9yIC4rPyg/PVxcXFxcXF0pL2csICckMS4qPycpICsgJyQnXG4pO1xuXG4vKiBOYXRpdmUgbWV0aG9kIHJlZmVyZW5jZXMgZm9yIHRob3NlIHdpdGggdGhlIHNhbWUgbmFtZSBhcyBvdGhlciBgbG9kYXNoYCBtZXRob2RzLiAqL1xudmFyIG5hdGl2ZUlzQXJyYXkgPSBnZXROYXRpdmUoQXJyYXksICdpc0FycmF5Jyk7XG5cbi8qKlxuICogVXNlZCBhcyB0aGUgW21heGltdW0gbGVuZ3RoXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1udW1iZXIubWF4X3NhZmVfaW50ZWdlcilcbiAqIG9mIGFuIGFycmF5LWxpa2UgdmFsdWUuXG4gKi9cbnZhciBNQVhfU0FGRV9JTlRFR0VSID0gOTAwNzE5OTI1NDc0MDk5MTtcblxuLyoqXG4gKiBHZXRzIHRoZSBuYXRpdmUgZnVuY3Rpb24gYXQgYGtleWAgb2YgYG9iamVjdGAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmplY3QgVGhlIG9iamVjdCB0byBxdWVyeS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgVGhlIGtleSBvZiB0aGUgbWV0aG9kIHRvIGdldC5cbiAqIEByZXR1cm5zIHsqfSBSZXR1cm5zIHRoZSBmdW5jdGlvbiBpZiBpdCdzIG5hdGl2ZSwgZWxzZSBgdW5kZWZpbmVkYC5cbiAqL1xuZnVuY3Rpb24gZ2V0TmF0aXZlKG9iamVjdCwga2V5KSB7XG4gIHZhciB2YWx1ZSA9IG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07XG4gIHJldHVybiBpc05hdGl2ZSh2YWx1ZSkgPyB2YWx1ZSA6IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGFycmF5LWxpa2UgbGVuZ3RoLlxuICpcbiAqICoqTm90ZToqKiBUaGlzIGZ1bmN0aW9uIGlzIGJhc2VkIG9uIFtgVG9MZW5ndGhgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy10b2xlbmd0aCkuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSB2YWxpZCBsZW5ndGgsIGVsc2UgYGZhbHNlYC5cbiAqL1xuZnVuY3Rpb24gaXNMZW5ndGgodmFsdWUpIHtcbiAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnbnVtYmVyJyAmJiB2YWx1ZSA+IC0xICYmIHZhbHVlICUgMSA9PSAwICYmIHZhbHVlIDw9IE1BWF9TQUZFX0lOVEVHRVI7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhbiBgQXJyYXlgIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0FycmF5KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc0FycmF5KGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJndW1lbnRzOyB9KCkpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xudmFyIGlzQXJyYXkgPSBuYXRpdmVJc0FycmF5IHx8IGZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiBpc09iamVjdExpa2UodmFsdWUpICYmIGlzTGVuZ3RoKHZhbHVlLmxlbmd0aCkgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gYXJyYXlUYWc7XG59O1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgRnVuY3Rpb25gIG9iamVjdC5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgY29ycmVjdGx5IGNsYXNzaWZpZWQsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc0Z1bmN0aW9uKF8pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNGdW5jdGlvbigvYWJjLyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XG4gIC8vIFRoZSB1c2Ugb2YgYE9iamVjdCN0b1N0cmluZ2AgYXZvaWRzIGlzc3VlcyB3aXRoIHRoZSBgdHlwZW9mYCBvcGVyYXRvclxuICAvLyBpbiBvbGRlciB2ZXJzaW9ucyBvZiBDaHJvbWUgYW5kIFNhZmFyaSB3aGljaCByZXR1cm4gJ2Z1bmN0aW9uJyBmb3IgcmVnZXhlc1xuICAvLyBhbmQgU2FmYXJpIDggZXF1aXZhbGVudHMgd2hpY2ggcmV0dXJuICdvYmplY3QnIGZvciB0eXBlZCBhcnJheSBjb25zdHJ1Y3RvcnMuXG4gIHJldHVybiBpc09iamVjdCh2YWx1ZSkgJiYgb2JqVG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gZnVuY1RhZztcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyB0aGUgW2xhbmd1YWdlIHR5cGVdKGh0dHBzOi8vZXM1LmdpdGh1Yi5pby8jeDgpIG9mIGBPYmplY3RgLlxuICogKGUuZy4gYXJyYXlzLCBmdW5jdGlvbnMsIG9iamVjdHMsIHJlZ2V4ZXMsIGBuZXcgTnVtYmVyKDApYCwgYW5kIGBuZXcgU3RyaW5nKCcnKWApXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGFuIG9iamVjdCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0KHt9KTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdCgxKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0KHZhbHVlKSB7XG4gIC8vIEF2b2lkIGEgVjggSklUIGJ1ZyBpbiBDaHJvbWUgMTktMjAuXG4gIC8vIFNlZSBodHRwczovL2NvZGUuZ29vZ2xlLmNvbS9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MjI5MSBmb3IgbW9yZSBkZXRhaWxzLlxuICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcbiAgcmV0dXJuICEhdmFsdWUgJiYgKHR5cGUgPT0gJ29iamVjdCcgfHwgdHlwZSA9PSAnZnVuY3Rpb24nKTtcbn1cblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIG5hdGl2ZSBmdW5jdGlvbi5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYSBuYXRpdmUgZnVuY3Rpb24sIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc05hdGl2ZShBcnJheS5wcm90b3R5cGUucHVzaCk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc05hdGl2ZShfKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzTmF0aXZlKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHJldHVybiByZUlzTmF0aXZlLnRlc3QoZm5Ub1N0cmluZy5jYWxsKHZhbHVlKSk7XG4gIH1cbiAgcmV0dXJuIGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgcmVJc0hvc3RDdG9yLnRlc3QodmFsdWUpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzQXJyYXk7XG4iLCIvKipcbiAqIGxvZGFzaCAzLjEuMSAoQ3VzdG9tIEJ1aWxkKSA8aHR0cHM6Ly9sb2Rhc2guY29tLz5cbiAqIEJ1aWxkOiBgbG9kYXNoIG1vZHVsYXJpemUgZXhwb3J0cz1cIm5wbVwiIC1vIC4vYFxuICogQ29weXJpZ2h0IDIwMTItMjAxNiBUaGUgRG9qbyBGb3VuZGF0aW9uIDxodHRwOi8vZG9qb2ZvdW5kYXRpb24ub3JnLz5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgMjAwOS0yMDE2IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICovXG52YXIgZGVidXJyID0gcmVxdWlyZSgnbG9kYXNoLmRlYnVycicpLFxuICAgIHdvcmRzID0gcmVxdWlyZSgnbG9kYXNoLndvcmRzJyk7XG5cbi8qKlxuICogQSBzcGVjaWFsaXplZCB2ZXJzaW9uIG9mIGBfLnJlZHVjZWAgZm9yIGFycmF5cyB3aXRob3V0IHN1cHBvcnQgZm9yXG4gKiBpdGVyYXRlZSBzaG9ydGhhbmRzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgVGhlIGZ1bmN0aW9uIGludm9rZWQgcGVyIGl0ZXJhdGlvbi5cbiAqIEBwYXJhbSB7Kn0gW2FjY3VtdWxhdG9yXSBUaGUgaW5pdGlhbCB2YWx1ZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2luaXRBY2N1bV0gU3BlY2lmeSB1c2luZyB0aGUgZmlyc3QgZWxlbWVudCBvZiBgYXJyYXlgIGFzIHRoZSBpbml0aWFsIHZhbHVlLlxuICogQHJldHVybnMgeyp9IFJldHVybnMgdGhlIGFjY3VtdWxhdGVkIHZhbHVlLlxuICovXG5mdW5jdGlvbiBhcnJheVJlZHVjZShhcnJheSwgaXRlcmF0ZWUsIGFjY3VtdWxhdG9yLCBpbml0QWNjdW0pIHtcbiAgdmFyIGluZGV4ID0gLTEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgaWYgKGluaXRBY2N1bSAmJiBsZW5ndGgpIHtcbiAgICBhY2N1bXVsYXRvciA9IGFycmF5WysraW5kZXhdO1xuICB9XG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgYWNjdW11bGF0b3IgPSBpdGVyYXRlZShhY2N1bXVsYXRvciwgYXJyYXlbaW5kZXhdLCBpbmRleCwgYXJyYXkpO1xuICB9XG4gIHJldHVybiBhY2N1bXVsYXRvcjtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gbGlrZSBgXy5jYW1lbENhc2VgLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayBUaGUgZnVuY3Rpb24gdG8gY29tYmluZSBlYWNoIHdvcmQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBjb21wb3VuZGVyIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiBjcmVhdGVDb21wb3VuZGVyKGNhbGxiYWNrKSB7XG4gIHJldHVybiBmdW5jdGlvbihzdHJpbmcpIHtcbiAgICByZXR1cm4gYXJyYXlSZWR1Y2Uod29yZHMoZGVidXJyKHN0cmluZykpLCBjYWxsYmFjaywgJycpO1xuICB9O1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGBzdHJpbmdgIHRvIFtrZWJhYiBjYXNlXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9MZXR0ZXJfY2FzZSNTcGVjaWFsX2Nhc2Vfc3R5bGVzKS5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IFN0cmluZ1xuICogQHBhcmFtIHtzdHJpbmd9IFtzdHJpbmc9JyddIFRoZSBzdHJpbmcgdG8gY29udmVydC5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGtlYmFiIGNhc2VkIHN0cmluZy5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5rZWJhYkNhc2UoJ0ZvbyBCYXInKTtcbiAqIC8vID0+ICdmb28tYmFyJ1xuICpcbiAqIF8ua2ViYWJDYXNlKCdmb29CYXInKTtcbiAqIC8vID0+ICdmb28tYmFyJ1xuICpcbiAqIF8ua2ViYWJDYXNlKCdfX2Zvb19iYXJfXycpO1xuICogLy8gPT4gJ2Zvby1iYXInXG4gKi9cbnZhciBrZWJhYkNhc2UgPSBjcmVhdGVDb21wb3VuZGVyKGZ1bmN0aW9uKHJlc3VsdCwgd29yZCwgaW5kZXgpIHtcbiAgcmV0dXJuIHJlc3VsdCArIChpbmRleCA/ICctJyA6ICcnKSArIHdvcmQudG9Mb3dlckNhc2UoKTtcbn0pO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGtlYmFiQ2FzZTtcbiIsIi8qKlxuICogbG9kYXNoIDMuMi4wIChDdXN0b20gQnVpbGQpIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQnVpbGQ6IGBsb2Rhc2ggbW9kdWxhcml6ZSBleHBvcnRzPVwibnBtXCIgLW8gLi9gXG4gKiBDb3B5cmlnaHQgMjAxMi0yMDE2IFRoZSBEb2pvIEZvdW5kYXRpb24gPGh0dHA6Ly9kb2pvZm91bmRhdGlvbi5vcmcvPlxuICogQmFzZWQgb24gVW5kZXJzY29yZS5qcyAxLjguMyA8aHR0cDovL3VuZGVyc2NvcmVqcy5vcmcvTElDRU5TRT5cbiAqIENvcHlyaWdodCAyMDA5LTIwMTYgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbiAqIEF2YWlsYWJsZSB1bmRlciBNSVQgbGljZW5zZSA8aHR0cHM6Ly9sb2Rhc2guY29tL2xpY2Vuc2U+XG4gKi9cbnZhciByb290ID0gcmVxdWlyZSgnbG9kYXNoLl9yb290Jyk7XG5cbi8qKiBVc2VkIGFzIHJlZmVyZW5jZXMgZm9yIHZhcmlvdXMgYE51bWJlcmAgY29uc3RhbnRzLiAqL1xudmFyIElORklOSVRZID0gMSAvIDA7XG5cbi8qKiBgT2JqZWN0I3RvU3RyaW5nYCByZXN1bHQgcmVmZXJlbmNlcy4gKi9cbnZhciBzeW1ib2xUYWcgPSAnW29iamVjdCBTeW1ib2xdJztcblxuLyoqIFVzZWQgdG8gbWF0Y2ggbGF0aW4tMSBzdXBwbGVtZW50YXJ5IGxldHRlcnMgKGV4Y2x1ZGluZyBtYXRoZW1hdGljYWwgb3BlcmF0b3JzKS4gKi9cbnZhciByZUxhdGluMSA9IC9bXFx4YzAtXFx4ZDZcXHhkOC1cXHhkZVxceGRmLVxceGY2XFx4ZjgtXFx4ZmZdL2c7XG5cbi8qKiBVc2VkIHRvIGNvbXBvc2UgdW5pY29kZSBjaGFyYWN0ZXIgY2xhc3Nlcy4gKi9cbnZhciByc0NvbWJvTWFya3NSYW5nZSA9ICdcXFxcdTAzMDAtXFxcXHUwMzZmXFxcXHVmZTIwLVxcXFx1ZmUyMycsXG4gICAgcnNDb21ib1N5bWJvbHNSYW5nZSA9ICdcXFxcdTIwZDAtXFxcXHUyMGYwJztcblxuLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIGNhcHR1cmUgZ3JvdXBzLiAqL1xudmFyIHJzQ29tYm8gPSAnWycgKyByc0NvbWJvTWFya3NSYW5nZSArIHJzQ29tYm9TeW1ib2xzUmFuZ2UgKyAnXSc7XG5cbi8qKlxuICogVXNlZCB0byBtYXRjaCBbY29tYmluaW5nIGRpYWNyaXRpY2FsIG1hcmtzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db21iaW5pbmdfRGlhY3JpdGljYWxfTWFya3MpIGFuZFxuICogW2NvbWJpbmluZyBkaWFjcml0aWNhbCBtYXJrcyBmb3Igc3ltYm9sc10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ29tYmluaW5nX0RpYWNyaXRpY2FsX01hcmtzX2Zvcl9TeW1ib2xzKS5cbiAqL1xudmFyIHJlQ29tYm9NYXJrID0gUmVnRXhwKHJzQ29tYm8sICdnJyk7XG5cbi8qKiBVc2VkIHRvIG1hcCBsYXRpbi0xIHN1cHBsZW1lbnRhcnkgbGV0dGVycyB0byBiYXNpYyBsYXRpbiBsZXR0ZXJzLiAqL1xudmFyIGRlYnVycmVkTGV0dGVycyA9IHtcbiAgJ1xceGMwJzogJ0EnLCAgJ1xceGMxJzogJ0EnLCAnXFx4YzInOiAnQScsICdcXHhjMyc6ICdBJywgJ1xceGM0JzogJ0EnLCAnXFx4YzUnOiAnQScsXG4gICdcXHhlMCc6ICdhJywgICdcXHhlMSc6ICdhJywgJ1xceGUyJzogJ2EnLCAnXFx4ZTMnOiAnYScsICdcXHhlNCc6ICdhJywgJ1xceGU1JzogJ2EnLFxuICAnXFx4YzcnOiAnQycsICAnXFx4ZTcnOiAnYycsXG4gICdcXHhkMCc6ICdEJywgICdcXHhmMCc6ICdkJyxcbiAgJ1xceGM4JzogJ0UnLCAgJ1xceGM5JzogJ0UnLCAnXFx4Y2EnOiAnRScsICdcXHhjYic6ICdFJyxcbiAgJ1xceGU4JzogJ2UnLCAgJ1xceGU5JzogJ2UnLCAnXFx4ZWEnOiAnZScsICdcXHhlYic6ICdlJyxcbiAgJ1xceGNDJzogJ0knLCAgJ1xceGNkJzogJ0knLCAnXFx4Y2UnOiAnSScsICdcXHhjZic6ICdJJyxcbiAgJ1xceGVDJzogJ2knLCAgJ1xceGVkJzogJ2knLCAnXFx4ZWUnOiAnaScsICdcXHhlZic6ICdpJyxcbiAgJ1xceGQxJzogJ04nLCAgJ1xceGYxJzogJ24nLFxuICAnXFx4ZDInOiAnTycsICAnXFx4ZDMnOiAnTycsICdcXHhkNCc6ICdPJywgJ1xceGQ1JzogJ08nLCAnXFx4ZDYnOiAnTycsICdcXHhkOCc6ICdPJyxcbiAgJ1xceGYyJzogJ28nLCAgJ1xceGYzJzogJ28nLCAnXFx4ZjQnOiAnbycsICdcXHhmNSc6ICdvJywgJ1xceGY2JzogJ28nLCAnXFx4ZjgnOiAnbycsXG4gICdcXHhkOSc6ICdVJywgICdcXHhkYSc6ICdVJywgJ1xceGRiJzogJ1UnLCAnXFx4ZGMnOiAnVScsXG4gICdcXHhmOSc6ICd1JywgICdcXHhmYSc6ICd1JywgJ1xceGZiJzogJ3UnLCAnXFx4ZmMnOiAndScsXG4gICdcXHhkZCc6ICdZJywgICdcXHhmZCc6ICd5JywgJ1xceGZmJzogJ3knLFxuICAnXFx4YzYnOiAnQWUnLCAnXFx4ZTYnOiAnYWUnLFxuICAnXFx4ZGUnOiAnVGgnLCAnXFx4ZmUnOiAndGgnLFxuICAnXFx4ZGYnOiAnc3MnXG59O1xuXG4vKipcbiAqIFVzZWQgYnkgYF8uZGVidXJyYCB0byBjb252ZXJ0IGxhdGluLTEgc3VwcGxlbWVudGFyeSBsZXR0ZXJzIHRvIGJhc2ljIGxhdGluIGxldHRlcnMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBsZXR0ZXIgVGhlIG1hdGNoZWQgbGV0dGVyIHRvIGRlYnVyci5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIGRlYnVycmVkIGxldHRlci5cbiAqL1xuZnVuY3Rpb24gZGVidXJyTGV0dGVyKGxldHRlcikge1xuICByZXR1cm4gZGVidXJyZWRMZXR0ZXJzW2xldHRlcl07XG59XG5cbi8qKiBVc2VkIGZvciBidWlsdC1pbiBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBvYmplY3RQcm90byA9IE9iamVjdC5wcm90b3R5cGU7XG5cbi8qKlxuICogVXNlZCB0byByZXNvbHZlIHRoZSBbYHRvU3RyaW5nVGFnYF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtb2JqZWN0LnByb3RvdHlwZS50b3N0cmluZylcbiAqIG9mIHZhbHVlcy5cbiAqL1xudmFyIG9iamVjdFRvU3RyaW5nID0gb2JqZWN0UHJvdG8udG9TdHJpbmc7XG5cbi8qKiBCdWlsdC1pbiB2YWx1ZSByZWZlcmVuY2VzLiAqL1xudmFyIFN5bWJvbCA9IHJvb3QuU3ltYm9sO1xuXG4vKiogVXNlZCB0byBjb252ZXJ0IHN5bWJvbHMgdG8gcHJpbWl0aXZlcyBhbmQgc3RyaW5ncy4gKi9cbnZhciBzeW1ib2xQcm90byA9IFN5bWJvbCA/IFN5bWJvbC5wcm90b3R5cGUgOiB1bmRlZmluZWQsXG4gICAgc3ltYm9sVG9TdHJpbmcgPSBTeW1ib2wgPyBzeW1ib2xQcm90by50b1N0cmluZyA6IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZS4gQSB2YWx1ZSBpcyBvYmplY3QtbGlrZSBpZiBpdCdzIG5vdCBgbnVsbGBcbiAqIGFuZCBoYXMgYSBgdHlwZW9mYCByZXN1bHQgb2YgXCJvYmplY3RcIi5cbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgb2JqZWN0LWxpa2UsIGVsc2UgYGZhbHNlYC5cbiAqIEBleGFtcGxlXG4gKlxuICogXy5pc09iamVjdExpa2Uoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3RMaWtlKFsxLCAyLCAzXSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdExpa2UoXy5ub29wKTtcbiAqIC8vID0+IGZhbHNlXG4gKlxuICogXy5pc09iamVjdExpa2UobnVsbCk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc09iamVjdExpa2UodmFsdWUpIHtcbiAgcmV0dXJuICEhdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGNsYXNzaWZpZWQgYXMgYSBgU3ltYm9sYCBwcmltaXRpdmUgb3Igb2JqZWN0LlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBjb3JyZWN0bHkgY2xhc3NpZmllZCwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzU3ltYm9sKFN5bWJvbC5pdGVyYXRvcik7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc1N5bWJvbCgnYWJjJyk7XG4gKiAvLyA9PiBmYWxzZVxuICovXG5mdW5jdGlvbiBpc1N5bWJvbCh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdzeW1ib2wnIHx8XG4gICAgKGlzT2JqZWN0TGlrZSh2YWx1ZSkgJiYgb2JqZWN0VG9TdHJpbmcuY2FsbCh2YWx1ZSkgPT0gc3ltYm9sVGFnKTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBgdmFsdWVgIHRvIGEgc3RyaW5nIGlmIGl0J3Mgbm90IG9uZS4gQW4gZW1wdHkgc3RyaW5nIGlzIHJldHVybmVkXG4gKiBmb3IgYG51bGxgIGFuZCBgdW5kZWZpbmVkYCB2YWx1ZXMuIFRoZSBzaWduIG9mIGAtMGAgaXMgcHJlc2VydmVkLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gcHJvY2Vzcy5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IFJldHVybnMgdGhlIHN0cmluZy5cbiAqIEBleGFtcGxlXG4gKlxuICogXy50b1N0cmluZyhudWxsKTtcbiAqIC8vID0+ICcnXG4gKlxuICogXy50b1N0cmluZygtMCk7XG4gKiAvLyA9PiAnLTAnXG4gKlxuICogXy50b1N0cmluZyhbMSwgMiwgM10pO1xuICogLy8gPT4gJzEsMiwzJ1xuICovXG5mdW5jdGlvbiB0b1N0cmluZyh2YWx1ZSkge1xuICAvLyBFeGl0IGVhcmx5IGZvciBzdHJpbmdzIHRvIGF2b2lkIGEgcGVyZm9ybWFuY2UgaGl0IGluIHNvbWUgZW52aXJvbm1lbnRzLlxuICBpZiAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIHZhbHVlO1xuICB9XG4gIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG4gIGlmIChpc1N5bWJvbCh2YWx1ZSkpIHtcbiAgICByZXR1cm4gU3ltYm9sID8gc3ltYm9sVG9TdHJpbmcuY2FsbCh2YWx1ZSkgOiAnJztcbiAgfVxuICB2YXIgcmVzdWx0ID0gKHZhbHVlICsgJycpO1xuICByZXR1cm4gKHJlc3VsdCA9PSAnMCcgJiYgKDEgLyB2YWx1ZSkgPT0gLUlORklOSVRZKSA/ICctMCcgOiByZXN1bHQ7XG59XG5cbi8qKlxuICogRGVidXJycyBgc3RyaW5nYCBieSBjb252ZXJ0aW5nIFtsYXRpbi0xIHN1cHBsZW1lbnRhcnkgbGV0dGVyc10oaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvTGF0aW4tMV9TdXBwbGVtZW50XyhVbmljb2RlX2Jsb2NrKSNDaGFyYWN0ZXJfdGFibGUpXG4gKiB0byBiYXNpYyBsYXRpbiBsZXR0ZXJzIGFuZCByZW1vdmluZyBbY29tYmluaW5nIGRpYWNyaXRpY2FsIG1hcmtzXShodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Db21iaW5pbmdfRGlhY3JpdGljYWxfTWFya3MpLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgU3RyaW5nXG4gKiBAcGFyYW0ge3N0cmluZ30gW3N0cmluZz0nJ10gVGhlIHN0cmluZyB0byBkZWJ1cnIuXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBSZXR1cm5zIHRoZSBkZWJ1cnJlZCBzdHJpbmcuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uZGVidXJyKCdkw6lqw6AgdnUnKTtcbiAqIC8vID0+ICdkZWphIHZ1J1xuICovXG5mdW5jdGlvbiBkZWJ1cnIoc3RyaW5nKSB7XG4gIHN0cmluZyA9IHRvU3RyaW5nKHN0cmluZyk7XG4gIHJldHVybiBzdHJpbmcgJiYgc3RyaW5nLnJlcGxhY2UocmVMYXRpbjEsIGRlYnVyckxldHRlcikucmVwbGFjZShyZUNvbWJvTWFyaywgJycpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGRlYnVycjtcbiIsIi8qKlxuICogbG9kYXNoIDMuMC4xIChDdXN0b20gQnVpbGQpIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQnVpbGQ6IGBsb2Rhc2ggbW9kdWxhcml6ZSBleHBvcnRzPVwibnBtXCIgLW8gLi9gXG4gKiBDb3B5cmlnaHQgMjAxMi0yMDE2IFRoZSBEb2pvIEZvdW5kYXRpb24gPGh0dHA6Ly9kb2pvZm91bmRhdGlvbi5vcmcvPlxuICogQmFzZWQgb24gVW5kZXJzY29yZS5qcyAxLjguMyA8aHR0cDovL3VuZGVyc2NvcmVqcy5vcmcvTElDRU5TRT5cbiAqIENvcHlyaWdodCAyMDA5LTIwMTYgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbiAqIEF2YWlsYWJsZSB1bmRlciBNSVQgbGljZW5zZSA8aHR0cHM6Ly9sb2Rhc2guY29tL2xpY2Vuc2U+XG4gKi9cblxuLyoqIFVzZWQgdG8gZGV0ZXJtaW5lIGlmIHZhbHVlcyBhcmUgb2YgdGhlIGxhbmd1YWdlIHR5cGUgYE9iamVjdGAuICovXG52YXIgb2JqZWN0VHlwZXMgPSB7XG4gICdmdW5jdGlvbic6IHRydWUsXG4gICdvYmplY3QnOiB0cnVlXG59O1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGV4cG9ydHNgLiAqL1xudmFyIGZyZWVFeHBvcnRzID0gKG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlKVxuICA/IGV4cG9ydHNcbiAgOiB1bmRlZmluZWQ7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbnZhciBmcmVlTW9kdWxlID0gKG9iamVjdFR5cGVzW3R5cGVvZiBtb2R1bGVdICYmIG1vZHVsZSAmJiAhbW9kdWxlLm5vZGVUeXBlKVxuICA/IG1vZHVsZVxuICA6IHVuZGVmaW5lZDtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcy4gKi9cbnZhciBmcmVlR2xvYmFsID0gY2hlY2tHbG9iYWwoZnJlZUV4cG9ydHMgJiYgZnJlZU1vZHVsZSAmJiB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbCk7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgc2VsZmAuICovXG52YXIgZnJlZVNlbGYgPSBjaGVja0dsb2JhbChvYmplY3RUeXBlc1t0eXBlb2Ygc2VsZl0gJiYgc2VsZik7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgd2luZG93YC4gKi9cbnZhciBmcmVlV2luZG93ID0gY2hlY2tHbG9iYWwob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KTtcblxuLyoqIERldGVjdCBgdGhpc2AgYXMgdGhlIGdsb2JhbCBvYmplY3QuICovXG52YXIgdGhpc0dsb2JhbCA9IGNoZWNrR2xvYmFsKG9iamVjdFR5cGVzW3R5cGVvZiB0aGlzXSAmJiB0aGlzKTtcblxuLyoqXG4gKiBVc2VkIGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBnbG9iYWwgb2JqZWN0LlxuICpcbiAqIFRoZSBgdGhpc2AgdmFsdWUgaXMgdXNlZCBpZiBpdCdzIHRoZSBnbG9iYWwgb2JqZWN0IHRvIGF2b2lkIEdyZWFzZW1vbmtleSdzXG4gKiByZXN0cmljdGVkIGB3aW5kb3dgIG9iamVjdCwgb3RoZXJ3aXNlIHRoZSBgd2luZG93YCBvYmplY3QgaXMgdXNlZC5cbiAqL1xudmFyIHJvb3QgPSBmcmVlR2xvYmFsIHx8XG4gICgoZnJlZVdpbmRvdyAhPT0gKHRoaXNHbG9iYWwgJiYgdGhpc0dsb2JhbC53aW5kb3cpKSAmJiBmcmVlV2luZG93KSB8fFxuICAgIGZyZWVTZWxmIHx8IHRoaXNHbG9iYWwgfHwgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIGdsb2JhbCBvYmplY3QuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge251bGx8T2JqZWN0fSBSZXR1cm5zIGB2YWx1ZWAgaWYgaXQncyBhIGdsb2JhbCBvYmplY3QsIGVsc2UgYG51bGxgLlxuICovXG5mdW5jdGlvbiBjaGVja0dsb2JhbCh2YWx1ZSkge1xuICByZXR1cm4gKHZhbHVlICYmIHZhbHVlLk9iamVjdCA9PT0gT2JqZWN0KSA/IHZhbHVlIDogbnVsbDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByb290O1xuIiwiLyoqXG4gKiBsb2Rhc2ggMy4yLjAgKEN1c3RvbSBCdWlsZCkgPGh0dHBzOi8vbG9kYXNoLmNvbS8+XG4gKiBCdWlsZDogYGxvZGFzaCBtb2R1bGFyaXplIGV4cG9ydHM9XCJucG1cIiAtbyAuL2BcbiAqIENvcHlyaWdodCAyMDEyLTIwMTYgVGhlIERvam8gRm91bmRhdGlvbiA8aHR0cDovL2Rvam9mb3VuZGF0aW9uLm9yZy8+XG4gKiBCYXNlZCBvbiBVbmRlcnNjb3JlLmpzIDEuOC4zIDxodHRwOi8vdW5kZXJzY29yZWpzLm9yZy9MSUNFTlNFPlxuICogQ29weXJpZ2h0IDIwMDktMjAxNiBKZXJlbXkgQXNoa2VuYXMsIERvY3VtZW50Q2xvdWQgYW5kIEludmVzdGlnYXRpdmUgUmVwb3J0ZXJzICYgRWRpdG9yc1xuICogQXZhaWxhYmxlIHVuZGVyIE1JVCBsaWNlbnNlIDxodHRwczovL2xvZGFzaC5jb20vbGljZW5zZT5cbiAqL1xudmFyIHJvb3QgPSByZXF1aXJlKCdsb2Rhc2guX3Jvb3QnKTtcblxuLyoqIFVzZWQgYXMgcmVmZXJlbmNlcyBmb3IgdmFyaW91cyBgTnVtYmVyYCBjb25zdGFudHMuICovXG52YXIgSU5GSU5JVFkgPSAxIC8gMDtcblxuLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCByZWZlcmVuY2VzLiAqL1xudmFyIHN5bWJvbFRhZyA9ICdbb2JqZWN0IFN5bWJvbF0nO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIHVuaWNvZGUgY2hhcmFjdGVyIGNsYXNzZXMuICovXG52YXIgcnNBc3RyYWxSYW5nZSA9ICdcXFxcdWQ4MDAtXFxcXHVkZmZmJyxcbiAgICByc0NvbWJvTWFya3NSYW5nZSA9ICdcXFxcdTAzMDAtXFxcXHUwMzZmXFxcXHVmZTIwLVxcXFx1ZmUyMycsXG4gICAgcnNDb21ib1N5bWJvbHNSYW5nZSA9ICdcXFxcdTIwZDAtXFxcXHUyMGYwJyxcbiAgICByc0RpbmdiYXRSYW5nZSA9ICdcXFxcdTI3MDAtXFxcXHUyN2JmJyxcbiAgICByc0xvd2VyUmFuZ2UgPSAnYS16XFxcXHhkZi1cXFxceGY2XFxcXHhmOC1cXFxceGZmJyxcbiAgICByc01hdGhPcFJhbmdlID0gJ1xcXFx4YWNcXFxceGIxXFxcXHhkN1xcXFx4ZjcnLFxuICAgIHJzTm9uQ2hhclJhbmdlID0gJ1xcXFx4MDAtXFxcXHgyZlxcXFx4M2EtXFxcXHg0MFxcXFx4NWItXFxcXHg2MFxcXFx4N2ItXFxcXHhiZicsXG4gICAgcnNRdW90ZVJhbmdlID0gJ1xcXFx1MjAxOFxcXFx1MjAxOVxcXFx1MjAxY1xcXFx1MjAxZCcsXG4gICAgcnNTcGFjZVJhbmdlID0gJyBcXFxcdFxcXFx4MGJcXFxcZlxcXFx4YTBcXFxcdWZlZmZcXFxcblxcXFxyXFxcXHUyMDI4XFxcXHUyMDI5XFxcXHUxNjgwXFxcXHUxODBlXFxcXHUyMDAwXFxcXHUyMDAxXFxcXHUyMDAyXFxcXHUyMDAzXFxcXHUyMDA0XFxcXHUyMDA1XFxcXHUyMDA2XFxcXHUyMDA3XFxcXHUyMDA4XFxcXHUyMDA5XFxcXHUyMDBhXFxcXHUyMDJmXFxcXHUyMDVmXFxcXHUzMDAwJyxcbiAgICByc1VwcGVyUmFuZ2UgPSAnQS1aXFxcXHhjMC1cXFxceGQ2XFxcXHhkOC1cXFxceGRlJyxcbiAgICByc1ZhclJhbmdlID0gJ1xcXFx1ZmUwZVxcXFx1ZmUwZicsXG4gICAgcnNCcmVha1JhbmdlID0gcnNNYXRoT3BSYW5nZSArIHJzTm9uQ2hhclJhbmdlICsgcnNRdW90ZVJhbmdlICsgcnNTcGFjZVJhbmdlO1xuXG4vKiogVXNlZCB0byBjb21wb3NlIHVuaWNvZGUgY2FwdHVyZSBncm91cHMuICovXG52YXIgcnNCcmVhayA9ICdbJyArIHJzQnJlYWtSYW5nZSArICddJyxcbiAgICByc0NvbWJvID0gJ1snICsgcnNDb21ib01hcmtzUmFuZ2UgKyByc0NvbWJvU3ltYm9sc1JhbmdlICsgJ10nLFxuICAgIHJzRGlnaXRzID0gJ1xcXFxkKycsXG4gICAgcnNEaW5nYmF0ID0gJ1snICsgcnNEaW5nYmF0UmFuZ2UgKyAnXScsXG4gICAgcnNMb3dlciA9ICdbJyArIHJzTG93ZXJSYW5nZSArICddJyxcbiAgICByc01pc2MgPSAnW14nICsgcnNBc3RyYWxSYW5nZSArIHJzQnJlYWtSYW5nZSArIHJzRGlnaXRzICsgcnNEaW5nYmF0UmFuZ2UgKyByc0xvd2VyUmFuZ2UgKyByc1VwcGVyUmFuZ2UgKyAnXScsXG4gICAgcnNGaXR6ID0gJ1xcXFx1ZDgzY1tcXFxcdWRmZmItXFxcXHVkZmZmXScsXG4gICAgcnNNb2RpZmllciA9ICcoPzonICsgcnNDb21ibyArICd8JyArIHJzRml0eiArICcpJyxcbiAgICByc05vbkFzdHJhbCA9ICdbXicgKyByc0FzdHJhbFJhbmdlICsgJ10nLFxuICAgIHJzUmVnaW9uYWwgPSAnKD86XFxcXHVkODNjW1xcXFx1ZGRlNi1cXFxcdWRkZmZdKXsyfScsXG4gICAgcnNTdXJyUGFpciA9ICdbXFxcXHVkODAwLVxcXFx1ZGJmZl1bXFxcXHVkYzAwLVxcXFx1ZGZmZl0nLFxuICAgIHJzVXBwZXIgPSAnWycgKyByc1VwcGVyUmFuZ2UgKyAnXScsXG4gICAgcnNaV0ogPSAnXFxcXHUyMDBkJztcblxuLyoqIFVzZWQgdG8gY29tcG9zZSB1bmljb2RlIHJlZ2V4ZXMuICovXG52YXIgcnNMb3dlck1pc2MgPSAnKD86JyArIHJzTG93ZXIgKyAnfCcgKyByc01pc2MgKyAnKScsXG4gICAgcnNVcHBlck1pc2MgPSAnKD86JyArIHJzVXBwZXIgKyAnfCcgKyByc01pc2MgKyAnKScsXG4gICAgcmVPcHRNb2QgPSByc01vZGlmaWVyICsgJz8nLFxuICAgIHJzT3B0VmFyID0gJ1snICsgcnNWYXJSYW5nZSArICddPycsXG4gICAgcnNPcHRKb2luID0gJyg/OicgKyByc1pXSiArICcoPzonICsgW3JzTm9uQXN0cmFsLCByc1JlZ2lvbmFsLCByc1N1cnJQYWlyXS5qb2luKCd8JykgKyAnKScgKyByc09wdFZhciArIHJlT3B0TW9kICsgJykqJyxcbiAgICByc1NlcSA9IHJzT3B0VmFyICsgcmVPcHRNb2QgKyByc09wdEpvaW4sXG4gICAgcnNFbW9qaSA9ICcoPzonICsgW3JzRGluZ2JhdCwgcnNSZWdpb25hbCwgcnNTdXJyUGFpcl0uam9pbignfCcpICsgJyknICsgcnNTZXE7XG5cbi8qKiBVc2VkIHRvIG1hdGNoIG5vbi1jb21wb3VuZCB3b3JkcyBjb21wb3NlZCBvZiBhbHBoYW51bWVyaWMgY2hhcmFjdGVycy4gKi9cbnZhciByZUJhc2ljV29yZCA9IC9bYS16QS1aMC05XSsvZztcblxuLyoqIFVzZWQgdG8gbWF0Y2ggY29tcGxleCBvciBjb21wb3VuZCB3b3Jkcy4gKi9cbnZhciByZUNvbXBsZXhXb3JkID0gUmVnRXhwKFtcbiAgcnNVcHBlciArICc/JyArIHJzTG93ZXIgKyAnKyg/PScgKyBbcnNCcmVhaywgcnNVcHBlciwgJyQnXS5qb2luKCd8JykgKyAnKScsXG4gIHJzVXBwZXJNaXNjICsgJysoPz0nICsgW3JzQnJlYWssIHJzVXBwZXIgKyByc0xvd2VyTWlzYywgJyQnXS5qb2luKCd8JykgKyAnKScsXG4gIHJzVXBwZXIgKyAnPycgKyByc0xvd2VyTWlzYyArICcrJyxcbiAgcnNVcHBlciArICcrJyxcbiAgcnNEaWdpdHMsXG4gIHJzRW1vamlcbl0uam9pbignfCcpLCAnZycpO1xuXG4vKiogVXNlZCB0byBkZXRlY3Qgc3RyaW5ncyB0aGF0IG5lZWQgYSBtb3JlIHJvYnVzdCByZWdleHAgdG8gbWF0Y2ggd29yZHMuICovXG52YXIgcmVIYXNDb21wbGV4V29yZCA9IC9bYS16XVtBLVpdfFswLTldW2EtekEtWl18W2EtekEtWl1bMC05XXxbXmEtekEtWjAtOSBdLztcblxuLyoqIFVzZWQgZm9yIGJ1aWx0LWluIG1ldGhvZCByZWZlcmVuY2VzLiAqL1xudmFyIG9iamVjdFByb3RvID0gT2JqZWN0LnByb3RvdHlwZTtcblxuLyoqXG4gKiBVc2VkIHRvIHJlc29sdmUgdGhlIFtgdG9TdHJpbmdUYWdgXShodHRwOi8vZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi82LjAvI3NlYy1vYmplY3QucHJvdG90eXBlLnRvc3RyaW5nKVxuICogb2YgdmFsdWVzLlxuICovXG52YXIgb2JqZWN0VG9TdHJpbmcgPSBvYmplY3RQcm90by50b1N0cmluZztcblxuLyoqIEJ1aWx0LWluIHZhbHVlIHJlZmVyZW5jZXMuICovXG52YXIgU3ltYm9sID0gcm9vdC5TeW1ib2w7XG5cbi8qKiBVc2VkIHRvIGNvbnZlcnQgc3ltYm9scyB0byBwcmltaXRpdmVzIGFuZCBzdHJpbmdzLiAqL1xudmFyIHN5bWJvbFByb3RvID0gU3ltYm9sID8gU3ltYm9sLnByb3RvdHlwZSA6IHVuZGVmaW5lZCxcbiAgICBzeW1ib2xUb1N0cmluZyA9IFN5bWJvbCA/IHN5bWJvbFByb3RvLnRvU3RyaW5nIDogdW5kZWZpbmVkO1xuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIG9iamVjdC1saWtlLiBBIHZhbHVlIGlzIG9iamVjdC1saWtlIGlmIGl0J3Mgbm90IGBudWxsYFxuICogYW5kIGhhcyBhIGB0eXBlb2ZgIHJlc3VsdCBvZiBcIm9iamVjdFwiLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgTGFuZ1xuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZSh7fSk7XG4gKiAvLyA9PiB0cnVlXG4gKlxuICogXy5pc09iamVjdExpa2UoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShfLm5vb3ApO1xuICogLy8gPT4gZmFsc2VcbiAqXG4gKiBfLmlzT2JqZWN0TGlrZShudWxsKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzT2JqZWN0TGlrZSh2YWx1ZSkge1xuICByZXR1cm4gISF2YWx1ZSAmJiB0eXBlb2YgdmFsdWUgPT0gJ29iamVjdCc7XG59XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgY2xhc3NpZmllZCBhcyBhIGBTeW1ib2xgIHByaW1pdGl2ZSBvciBvYmplY3QuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm5zIHtib29sZWFufSBSZXR1cm5zIGB0cnVlYCBpZiBgdmFsdWVgIGlzIGNvcnJlY3RseSBjbGFzc2lmaWVkLCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNTeW1ib2woU3ltYm9sLml0ZXJhdG9yKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzU3ltYm9sKCdhYmMnKTtcbiAqIC8vID0+IGZhbHNlXG4gKi9cbmZ1bmN0aW9uIGlzU3ltYm9sKHZhbHVlKSB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT0gJ3N5bWJvbCcgfHxcbiAgICAoaXNPYmplY3RMaWtlKHZhbHVlKSAmJiBvYmplY3RUb1N0cmluZy5jYWxsKHZhbHVlKSA9PSBzeW1ib2xUYWcpO1xufVxuXG4vKipcbiAqIENvbnZlcnRzIGB2YWx1ZWAgdG8gYSBzdHJpbmcgaWYgaXQncyBub3Qgb25lLiBBbiBlbXB0eSBzdHJpbmcgaXMgcmV0dXJuZWRcbiAqIGZvciBgbnVsbGAgYW5kIGB1bmRlZmluZWRgIHZhbHVlcy4gVGhlIHNpZ24gb2YgYC0wYCBpcyBwcmVzZXJ2ZWQuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBMYW5nXG4gKiBAcGFyYW0geyp9IHZhbHVlIFRoZSB2YWx1ZSB0byBwcm9jZXNzLlxuICogQHJldHVybnMge3N0cmluZ30gUmV0dXJucyB0aGUgc3RyaW5nLlxuICogQGV4YW1wbGVcbiAqXG4gKiBfLnRvU3RyaW5nKG51bGwpO1xuICogLy8gPT4gJydcbiAqXG4gKiBfLnRvU3RyaW5nKC0wKTtcbiAqIC8vID0+ICctMCdcbiAqXG4gKiBfLnRvU3RyaW5nKFsxLCAyLCAzXSk7XG4gKiAvLyA9PiAnMSwyLDMnXG4gKi9cbmZ1bmN0aW9uIHRvU3RyaW5nKHZhbHVlKSB7XG4gIC8vIEV4aXQgZWFybHkgZm9yIHN0cmluZ3MgdG8gYXZvaWQgYSBwZXJmb3JtYW5jZSBoaXQgaW4gc29tZSBlbnZpcm9ubWVudHMuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbiAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICByZXR1cm4gJyc7XG4gIH1cbiAgaWYgKGlzU3ltYm9sKHZhbHVlKSkge1xuICAgIHJldHVybiBTeW1ib2wgPyBzeW1ib2xUb1N0cmluZy5jYWxsKHZhbHVlKSA6ICcnO1xuICB9XG4gIHZhciByZXN1bHQgPSAodmFsdWUgKyAnJyk7XG4gIHJldHVybiAocmVzdWx0ID09ICcwJyAmJiAoMSAvIHZhbHVlKSA9PSAtSU5GSU5JVFkpID8gJy0wJyA6IHJlc3VsdDtcbn1cblxuLyoqXG4gKiBTcGxpdHMgYHN0cmluZ2AgaW50byBhbiBhcnJheSBvZiBpdHMgd29yZHMuXG4gKlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIF9cbiAqIEBjYXRlZ29yeSBTdHJpbmdcbiAqIEBwYXJhbSB7c3RyaW5nfSBbc3RyaW5nPScnXSBUaGUgc3RyaW5nIHRvIGluc3BlY3QuXG4gKiBAcGFyYW0ge1JlZ0V4cHxzdHJpbmd9IFtwYXR0ZXJuXSBUaGUgcGF0dGVybiB0byBtYXRjaCB3b3Jkcy5cbiAqIEBwYXJhbS0ge09iamVjdH0gW2d1YXJkXSBFbmFibGVzIHVzZSBhcyBhbiBpdGVyYXRlZSBmb3IgZnVuY3Rpb25zIGxpa2UgYF8ubWFwYC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgd29yZHMgb2YgYHN0cmluZ2AuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8ud29yZHMoJ2ZyZWQsIGJhcm5leSwgJiBwZWJibGVzJyk7XG4gKiAvLyA9PiBbJ2ZyZWQnLCAnYmFybmV5JywgJ3BlYmJsZXMnXVxuICpcbiAqIF8ud29yZHMoJ2ZyZWQsIGJhcm5leSwgJiBwZWJibGVzJywgL1teLCBdKy9nKTtcbiAqIC8vID0+IFsnZnJlZCcsICdiYXJuZXknLCAnJicsICdwZWJibGVzJ11cbiAqL1xuZnVuY3Rpb24gd29yZHMoc3RyaW5nLCBwYXR0ZXJuLCBndWFyZCkge1xuICBzdHJpbmcgPSB0b1N0cmluZyhzdHJpbmcpO1xuICBwYXR0ZXJuID0gZ3VhcmQgPyB1bmRlZmluZWQgOiBwYXR0ZXJuO1xuXG4gIGlmIChwYXR0ZXJuID09PSB1bmRlZmluZWQpIHtcbiAgICBwYXR0ZXJuID0gcmVIYXNDb21wbGV4V29yZC50ZXN0KHN0cmluZykgPyByZUNvbXBsZXhXb3JkIDogcmVCYXNpY1dvcmQ7XG4gIH1cbiAgcmV0dXJuIHN0cmluZy5tYXRjaChwYXR0ZXJuKSB8fCBbXTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB3b3JkcztcbiIsIi8qKlxuICogbG9kYXNoIDMuMC4xIChDdXN0b20gQnVpbGQpIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQnVpbGQ6IGBsb2Rhc2ggbW9kdWxhcml6ZSBleHBvcnRzPVwibnBtXCIgLW8gLi9gXG4gKiBDb3B5cmlnaHQgMjAxMi0yMDE2IFRoZSBEb2pvIEZvdW5kYXRpb24gPGh0dHA6Ly9kb2pvZm91bmRhdGlvbi5vcmcvPlxuICogQmFzZWQgb24gVW5kZXJzY29yZS5qcyAxLjguMyA8aHR0cDovL3VuZGVyc2NvcmVqcy5vcmcvTElDRU5TRT5cbiAqIENvcHlyaWdodCAyMDA5LTIwMTYgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbiAqIEF2YWlsYWJsZSB1bmRlciBNSVQgbGljZW5zZSA8aHR0cHM6Ly9sb2Rhc2guY29tL2xpY2Vuc2U+XG4gKi9cblxuLyoqIFVzZWQgdG8gZGV0ZXJtaW5lIGlmIHZhbHVlcyBhcmUgb2YgdGhlIGxhbmd1YWdlIHR5cGUgYE9iamVjdGAuICovXG52YXIgb2JqZWN0VHlwZXMgPSB7XG4gICdmdW5jdGlvbic6IHRydWUsXG4gICdvYmplY3QnOiB0cnVlXG59O1xuXG4vKiogRGV0ZWN0IGZyZWUgdmFyaWFibGUgYGV4cG9ydHNgLiAqL1xudmFyIGZyZWVFeHBvcnRzID0gKG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlKVxuICA/IGV4cG9ydHNcbiAgOiB1bmRlZmluZWQ7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgbW9kdWxlYC4gKi9cbnZhciBmcmVlTW9kdWxlID0gKG9iamVjdFR5cGVzW3R5cGVvZiBtb2R1bGVdICYmIG1vZHVsZSAmJiAhbW9kdWxlLm5vZGVUeXBlKVxuICA/IG1vZHVsZVxuICA6IHVuZGVmaW5lZDtcblxuLyoqIERldGVjdCBmcmVlIHZhcmlhYmxlIGBnbG9iYWxgIGZyb20gTm9kZS5qcy4gKi9cbnZhciBmcmVlR2xvYmFsID0gY2hlY2tHbG9iYWwoZnJlZUV4cG9ydHMgJiYgZnJlZU1vZHVsZSAmJiB0eXBlb2YgZ2xvYmFsID09ICdvYmplY3QnICYmIGdsb2JhbCk7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgc2VsZmAuICovXG52YXIgZnJlZVNlbGYgPSBjaGVja0dsb2JhbChvYmplY3RUeXBlc1t0eXBlb2Ygc2VsZl0gJiYgc2VsZik7XG5cbi8qKiBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgd2luZG93YC4gKi9cbnZhciBmcmVlV2luZG93ID0gY2hlY2tHbG9iYWwob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KTtcblxuLyoqIERldGVjdCBgdGhpc2AgYXMgdGhlIGdsb2JhbCBvYmplY3QuICovXG52YXIgdGhpc0dsb2JhbCA9IGNoZWNrR2xvYmFsKG9iamVjdFR5cGVzW3R5cGVvZiB0aGlzXSAmJiB0aGlzKTtcblxuLyoqXG4gKiBVc2VkIGFzIGEgcmVmZXJlbmNlIHRvIHRoZSBnbG9iYWwgb2JqZWN0LlxuICpcbiAqIFRoZSBgdGhpc2AgdmFsdWUgaXMgdXNlZCBpZiBpdCdzIHRoZSBnbG9iYWwgb2JqZWN0IHRvIGF2b2lkIEdyZWFzZW1vbmtleSdzXG4gKiByZXN0cmljdGVkIGB3aW5kb3dgIG9iamVjdCwgb3RoZXJ3aXNlIHRoZSBgd2luZG93YCBvYmplY3QgaXMgdXNlZC5cbiAqL1xudmFyIHJvb3QgPSBmcmVlR2xvYmFsIHx8XG4gICgoZnJlZVdpbmRvdyAhPT0gKHRoaXNHbG9iYWwgJiYgdGhpc0dsb2JhbC53aW5kb3cpKSAmJiBmcmVlV2luZG93KSB8fFxuICAgIGZyZWVTZWxmIHx8IHRoaXNHbG9iYWwgfHwgRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBhIGdsb2JhbCBvYmplY3QuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge251bGx8T2JqZWN0fSBSZXR1cm5zIGB2YWx1ZWAgaWYgaXQncyBhIGdsb2JhbCBvYmplY3QsIGVsc2UgYG51bGxgLlxuICovXG5mdW5jdGlvbiBjaGVja0dsb2JhbCh2YWx1ZSkge1xuICByZXR1cm4gKHZhbHVlICYmIHZhbHVlLk9iamVjdCA9PT0gT2JqZWN0KSA/IHZhbHVlIDogbnVsbDtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByb290O1xuIiwiLyoqXG4gKiBsb2Rhc2ggMy4xLjAgKEN1c3RvbSBCdWlsZCkgPGh0dHBzOi8vbG9kYXNoLmNvbS8+XG4gKiBCdWlsZDogYGxvZGFzaCBtb2Rlcm4gbW9kdWxhcml6ZSBleHBvcnRzPVwibnBtXCIgLW8gLi9gXG4gKiBDb3B5cmlnaHQgMjAxMi0yMDE1IFRoZSBEb2pvIEZvdW5kYXRpb24gPGh0dHA6Ly9kb2pvZm91bmRhdGlvbi5vcmcvPlxuICogQmFzZWQgb24gVW5kZXJzY29yZS5qcyAxLjguMiA8aHR0cDovL3VuZGVyc2NvcmVqcy5vcmcvTElDRU5TRT5cbiAqIENvcHlyaWdodCAyMDA5LTIwMTUgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbiAqIEF2YWlsYWJsZSB1bmRlciBNSVQgbGljZW5zZSA8aHR0cHM6Ly9sb2Rhc2guY29tL2xpY2Vuc2U+XG4gKi9cbnZhciBiYXNlRmxhdHRlbiA9IHJlcXVpcmUoJ2xvZGFzaC5fYmFzZWZsYXR0ZW4nKSxcbiAgICBiYXNlVW5pcSA9IHJlcXVpcmUoJ2xvZGFzaC5fYmFzZXVuaXEnKSxcbiAgICByZXN0UGFyYW0gPSByZXF1aXJlKCdsb2Rhc2gucmVzdHBhcmFtJyk7XG5cbi8qKlxuICogQ3JlYXRlcyBhbiBhcnJheSBvZiB1bmlxdWUgdmFsdWVzLCBpbiBvcmRlciwgb2YgdGhlIHByb3ZpZGVkIGFycmF5cyB1c2luZ1xuICogYFNhbWVWYWx1ZVplcm9gIGZvciBlcXVhbGl0eSBjb21wYXJpc29ucy5cbiAqXG4gKiAqKk5vdGU6KiogW2BTYW1lVmFsdWVaZXJvYF0oaHR0cHM6Ly9wZW9wbGUubW96aWxsYS5vcmcvfmpvcmVuZG9yZmYvZXM2LWRyYWZ0Lmh0bWwjc2VjLXNhbWV2YWx1ZXplcm8pXG4gKiBjb21wYXJpc29ucyBhcmUgbGlrZSBzdHJpY3QgZXF1YWxpdHkgY29tcGFyaXNvbnMsIGUuZy4gYD09PWAsIGV4Y2VwdCB0aGF0XG4gKiBgTmFOYCBtYXRjaGVzIGBOYU5gLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgQXJyYXlcbiAqIEBwYXJhbSB7Li4uQXJyYXl9IFthcnJheXNdIFRoZSBhcnJheXMgdG8gaW5zcGVjdC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyB0aGUgbmV3IGFycmF5IG9mIGNvbWJpbmVkIHZhbHVlcy5cbiAqIEBleGFtcGxlXG4gKlxuICogXy51bmlvbihbMSwgMl0sIFs0LCAyXSwgWzIsIDFdKTtcbiAqIC8vID0+IFsxLCAyLCA0XVxuICovXG52YXIgdW5pb24gPSByZXN0UGFyYW0oZnVuY3Rpb24oYXJyYXlzKSB7XG4gIHJldHVybiBiYXNlVW5pcShiYXNlRmxhdHRlbihhcnJheXMsIGZhbHNlLCB0cnVlKSk7XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSB1bmlvbjtcbiIsIi8qKlxuICogbG9kYXNoIDMuMS40IChDdXN0b20gQnVpbGQpIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQnVpbGQ6IGBsb2Rhc2ggbW9kZXJuIG1vZHVsYXJpemUgZXhwb3J0cz1cIm5wbVwiIC1vIC4vYFxuICogQ29weXJpZ2h0IDIwMTItMjAxNSBUaGUgRG9qbyBGb3VuZGF0aW9uIDxodHRwOi8vZG9qb2ZvdW5kYXRpb24ub3JnLz5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgMjAwOS0yMDE1IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICovXG52YXIgaXNBcmd1bWVudHMgPSByZXF1aXJlKCdsb2Rhc2guaXNhcmd1bWVudHMnKSxcbiAgICBpc0FycmF5ID0gcmVxdWlyZSgnbG9kYXNoLmlzYXJyYXknKTtcblxuLyoqXG4gKiBDaGVja3MgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBvYmplY3QtbGlrZSwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc09iamVjdExpa2UodmFsdWUpIHtcbiAgcmV0dXJuICEhdmFsdWUgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnO1xufVxuXG4vKipcbiAqIFVzZWQgYXMgdGhlIFttYXhpbXVtIGxlbmd0aF0oaHR0cDovL2VjbWEtaW50ZXJuYXRpb25hbC5vcmcvZWNtYS0yNjIvNi4wLyNzZWMtbnVtYmVyLm1heF9zYWZlX2ludGVnZXIpXG4gKiBvZiBhbiBhcnJheS1saWtlIHZhbHVlLlxuICovXG52YXIgTUFYX1NBRkVfSU5URUdFUiA9IDkwMDcxOTkyNTQ3NDA5OTE7XG5cbi8qKlxuICogQXBwZW5kcyB0aGUgZWxlbWVudHMgb2YgYHZhbHVlc2AgdG8gYGFycmF5YC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIG1vZGlmeS5cbiAqIEBwYXJhbSB7QXJyYXl9IHZhbHVlcyBUaGUgdmFsdWVzIHRvIGFwcGVuZC5cbiAqIEByZXR1cm5zIHtBcnJheX0gUmV0dXJucyBgYXJyYXlgLlxuICovXG5mdW5jdGlvbiBhcnJheVB1c2goYXJyYXksIHZhbHVlcykge1xuICB2YXIgaW5kZXggPSAtMSxcbiAgICAgIGxlbmd0aCA9IHZhbHVlcy5sZW5ndGgsXG4gICAgICBvZmZzZXQgPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBhcnJheVtvZmZzZXQgKyBpbmRleF0gPSB2YWx1ZXNbaW5kZXhdO1xuICB9XG4gIHJldHVybiBhcnJheTtcbn1cblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy5mbGF0dGVuYCB3aXRoIGFkZGVkIHN1cHBvcnQgZm9yIHJlc3RyaWN0aW5nXG4gKiBmbGF0dGVuaW5nIGFuZCBzcGVjaWZ5aW5nIHRoZSBzdGFydCBpbmRleC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGZsYXR0ZW4uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc0RlZXBdIFNwZWNpZnkgYSBkZWVwIGZsYXR0ZW4uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtpc1N0cmljdF0gUmVzdHJpY3QgZmxhdHRlbmluZyB0byBhcnJheXMtbGlrZSBvYmplY3RzLlxuICogQHBhcmFtIHtBcnJheX0gW3Jlc3VsdD1bXV0gVGhlIGluaXRpYWwgcmVzdWx0IHZhbHVlLlxuICogQHJldHVybnMge0FycmF5fSBSZXR1cm5zIHRoZSBuZXcgZmxhdHRlbmVkIGFycmF5LlxuICovXG5mdW5jdGlvbiBiYXNlRmxhdHRlbihhcnJheSwgaXNEZWVwLCBpc1N0cmljdCwgcmVzdWx0KSB7XG4gIHJlc3VsdCB8fCAocmVzdWx0ID0gW10pO1xuXG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuXG4gIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgdmFyIHZhbHVlID0gYXJyYXlbaW5kZXhdO1xuICAgIGlmIChpc09iamVjdExpa2UodmFsdWUpICYmIGlzQXJyYXlMaWtlKHZhbHVlKSAmJlxuICAgICAgICAoaXNTdHJpY3QgfHwgaXNBcnJheSh2YWx1ZSkgfHwgaXNBcmd1bWVudHModmFsdWUpKSkge1xuICAgICAgaWYgKGlzRGVlcCkge1xuICAgICAgICAvLyBSZWN1cnNpdmVseSBmbGF0dGVuIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpLlxuICAgICAgICBiYXNlRmxhdHRlbih2YWx1ZSwgaXNEZWVwLCBpc1N0cmljdCwgcmVzdWx0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFycmF5UHVzaChyZXN1bHQsIHZhbHVlKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCFpc1N0cmljdCkge1xuICAgICAgcmVzdWx0W3Jlc3VsdC5sZW5ndGhdID0gdmFsdWU7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogVGhlIGJhc2UgaW1wbGVtZW50YXRpb24gb2YgYF8ucHJvcGVydHlgIHdpdGhvdXQgc3VwcG9ydCBmb3IgZGVlcCBwYXRocy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtzdHJpbmd9IGtleSBUaGUga2V5IG9mIHRoZSBwcm9wZXJ0eSB0byBnZXQuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqL1xuZnVuY3Rpb24gYmFzZVByb3BlcnR5KGtleSkge1xuICByZXR1cm4gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgcmV0dXJuIG9iamVjdCA9PSBudWxsID8gdW5kZWZpbmVkIDogb2JqZWN0W2tleV07XG4gIH07XG59XG5cbi8qKlxuICogR2V0cyB0aGUgXCJsZW5ndGhcIiBwcm9wZXJ0eSB2YWx1ZSBvZiBgb2JqZWN0YC5cbiAqXG4gKiAqKk5vdGU6KiogVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIGF2b2lkIGEgW0pJVCBidWddKGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0xNDI3OTIpXG4gKiB0aGF0IGFmZmVjdHMgU2FmYXJpIG9uIGF0IGxlYXN0IGlPUyA4LjEtOC4zIEFSTTY0LlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge09iamVjdH0gb2JqZWN0IFRoZSBvYmplY3QgdG8gcXVlcnkuXG4gKiBAcmV0dXJucyB7Kn0gUmV0dXJucyB0aGUgXCJsZW5ndGhcIiB2YWx1ZS5cbiAqL1xudmFyIGdldExlbmd0aCA9IGJhc2VQcm9wZXJ0eSgnbGVuZ3RoJyk7XG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgYXJyYXktbGlrZS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhcnJheS1saWtlLCBlbHNlIGBmYWxzZWAuXG4gKi9cbmZ1bmN0aW9uIGlzQXJyYXlMaWtlKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIGlzTGVuZ3RoKGdldExlbmd0aCh2YWx1ZSkpO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIGEgdmFsaWQgYXJyYXktbGlrZSBsZW5ndGguXG4gKlxuICogKipOb3RlOioqIFRoaXMgZnVuY3Rpb24gaXMgYmFzZWQgb24gW2BUb0xlbmd0aGBdKGh0dHA6Ly9lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzYuMC8jc2VjLXRvbGVuZ3RoKS5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2hlY2suXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gUmV0dXJucyBgdHJ1ZWAgaWYgYHZhbHVlYCBpcyBhIHZhbGlkIGxlbmd0aCwgZWxzZSBgZmFsc2VgLlxuICovXG5mdW5jdGlvbiBpc0xlbmd0aCh2YWx1ZSkge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdudW1iZXInICYmIHZhbHVlID4gLTEgJiYgdmFsdWUgJSAxID09IDAgJiYgdmFsdWUgPD0gTUFYX1NBRkVfSU5URUdFUjtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlRmxhdHRlbjtcbiIsIi8qKlxuICogbG9kYXNoIDMuMC4zIChDdXN0b20gQnVpbGQpIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQnVpbGQ6IGBsb2Rhc2ggbW9kZXJuIG1vZHVsYXJpemUgZXhwb3J0cz1cIm5wbVwiIC1vIC4vYFxuICogQ29weXJpZ2h0IDIwMTItMjAxNSBUaGUgRG9qbyBGb3VuZGF0aW9uIDxodHRwOi8vZG9qb2ZvdW5kYXRpb24ub3JnLz5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgMjAwOS0yMDE1IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICovXG52YXIgYmFzZUluZGV4T2YgPSByZXF1aXJlKCdsb2Rhc2guX2Jhc2VpbmRleG9mJyksXG4gICAgY2FjaGVJbmRleE9mID0gcmVxdWlyZSgnbG9kYXNoLl9jYWNoZWluZGV4b2YnKSxcbiAgICBjcmVhdGVDYWNoZSA9IHJlcXVpcmUoJ2xvZGFzaC5fY3JlYXRlY2FjaGUnKTtcblxuLyoqIFVzZWQgYXMgdGhlIHNpemUgdG8gZW5hYmxlIGxhcmdlIGFycmF5IG9wdGltaXphdGlvbnMuICovXG52YXIgTEFSR0VfQVJSQVlfU0laRSA9IDIwMDtcblxuLyoqXG4gKiBUaGUgYmFzZSBpbXBsZW1lbnRhdGlvbiBvZiBgXy51bmlxYCB3aXRob3V0IHN1cHBvcnQgZm9yIGNhbGxiYWNrIHNob3J0aGFuZHNcbiAqIGFuZCBgdGhpc2AgYmluZGluZy5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIGluc3BlY3QuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbaXRlcmF0ZWVdIFRoZSBmdW5jdGlvbiBpbnZva2VkIHBlciBpdGVyYXRpb24uXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgdGhlIG5ldyBkdXBsaWNhdGUtdmFsdWUtZnJlZSBhcnJheS5cbiAqL1xuZnVuY3Rpb24gYmFzZVVuaXEoYXJyYXksIGl0ZXJhdGVlKSB7XG4gIHZhciBpbmRleCA9IC0xLFxuICAgICAgaW5kZXhPZiA9IGJhc2VJbmRleE9mLFxuICAgICAgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgaXNDb21tb24gPSB0cnVlLFxuICAgICAgaXNMYXJnZSA9IGlzQ29tbW9uICYmIGxlbmd0aCA+PSBMQVJHRV9BUlJBWV9TSVpFLFxuICAgICAgc2VlbiA9IGlzTGFyZ2UgPyBjcmVhdGVDYWNoZSgpIDogbnVsbCxcbiAgICAgIHJlc3VsdCA9IFtdO1xuXG4gIGlmIChzZWVuKSB7XG4gICAgaW5kZXhPZiA9IGNhY2hlSW5kZXhPZjtcbiAgICBpc0NvbW1vbiA9IGZhbHNlO1xuICB9IGVsc2Uge1xuICAgIGlzTGFyZ2UgPSBmYWxzZTtcbiAgICBzZWVuID0gaXRlcmF0ZWUgPyBbXSA6IHJlc3VsdDtcbiAgfVxuICBvdXRlcjpcbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICB2YXIgdmFsdWUgPSBhcnJheVtpbmRleF0sXG4gICAgICAgIGNvbXB1dGVkID0gaXRlcmF0ZWUgPyBpdGVyYXRlZSh2YWx1ZSwgaW5kZXgsIGFycmF5KSA6IHZhbHVlO1xuXG4gICAgaWYgKGlzQ29tbW9uICYmIHZhbHVlID09PSB2YWx1ZSkge1xuICAgICAgdmFyIHNlZW5JbmRleCA9IHNlZW4ubGVuZ3RoO1xuICAgICAgd2hpbGUgKHNlZW5JbmRleC0tKSB7XG4gICAgICAgIGlmIChzZWVuW3NlZW5JbmRleF0gPT09IGNvbXB1dGVkKSB7XG4gICAgICAgICAgY29udGludWUgb3V0ZXI7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChpdGVyYXRlZSkge1xuICAgICAgICBzZWVuLnB1c2goY29tcHV0ZWQpO1xuICAgICAgfVxuICAgICAgcmVzdWx0LnB1c2godmFsdWUpO1xuICAgIH1cbiAgICBlbHNlIGlmIChpbmRleE9mKHNlZW4sIGNvbXB1dGVkLCAwKSA8IDApIHtcbiAgICAgIGlmIChpdGVyYXRlZSB8fCBpc0xhcmdlKSB7XG4gICAgICAgIHNlZW4ucHVzaChjb21wdXRlZCk7XG4gICAgICB9XG4gICAgICByZXN1bHQucHVzaCh2YWx1ZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cbm1vZHVsZS5leHBvcnRzID0gYmFzZVVuaXE7XG4iLCIvKipcbiAqIGxvZGFzaCAzLjEuMCAoQ3VzdG9tIEJ1aWxkKSA8aHR0cHM6Ly9sb2Rhc2guY29tLz5cbiAqIEJ1aWxkOiBgbG9kYXNoIG1vZGVybiBtb2R1bGFyaXplIGV4cG9ydHM9XCJucG1cIiAtbyAuL2BcbiAqIENvcHlyaWdodCAyMDEyLTIwMTUgVGhlIERvam8gRm91bmRhdGlvbiA8aHR0cDovL2Rvam9mb3VuZGF0aW9uLm9yZy8+XG4gKiBCYXNlZCBvbiBVbmRlcnNjb3JlLmpzIDEuOC4yIDxodHRwOi8vdW5kZXJzY29yZWpzLm9yZy9MSUNFTlNFPlxuICogQ29weXJpZ2h0IDIwMDktMjAxNSBKZXJlbXkgQXNoa2VuYXMsIERvY3VtZW50Q2xvdWQgYW5kIEludmVzdGlnYXRpdmUgUmVwb3J0ZXJzICYgRWRpdG9yc1xuICogQXZhaWxhYmxlIHVuZGVyIE1JVCBsaWNlbnNlIDxodHRwczovL2xvZGFzaC5jb20vbGljZW5zZT5cbiAqL1xuXG4vKipcbiAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIG9mIGBfLmluZGV4T2ZgIHdpdGhvdXQgc3VwcG9ydCBmb3IgYmluYXJ5IHNlYXJjaGVzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gc2VhcmNoLlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICogQHJldHVybnMge251bWJlcn0gUmV0dXJucyB0aGUgaW5kZXggb2YgdGhlIG1hdGNoZWQgdmFsdWUsIGVsc2UgYC0xYC5cbiAqL1xuZnVuY3Rpb24gYmFzZUluZGV4T2YoYXJyYXksIHZhbHVlLCBmcm9tSW5kZXgpIHtcbiAgaWYgKHZhbHVlICE9PSB2YWx1ZSkge1xuICAgIHJldHVybiBpbmRleE9mTmFOKGFycmF5LCBmcm9tSW5kZXgpO1xuICB9XG4gIHZhciBpbmRleCA9IGZyb21JbmRleCAtIDEsXG4gICAgICBsZW5ndGggPSBhcnJheS5sZW5ndGg7XG5cbiAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICBpZiAoYXJyYXlbaW5kZXhdID09PSB2YWx1ZSkge1xuICAgICAgcmV0dXJuIGluZGV4O1xuICAgIH1cbiAgfVxuICByZXR1cm4gLTE7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgaW5kZXggYXQgd2hpY2ggdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYE5hTmAgaXMgZm91bmQgaW4gYGFycmF5YC5cbiAqIElmIGBmcm9tUmlnaHRgIGlzIHByb3ZpZGVkIGVsZW1lbnRzIG9mIGBhcnJheWAgYXJlIGl0ZXJhdGVkIGZyb20gcmlnaHQgdG8gbGVmdC5cbiAqXG4gKiBAcHJpdmF0ZVxuICogQHBhcmFtIHtBcnJheX0gYXJyYXkgVGhlIGFycmF5IHRvIHNlYXJjaC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmcm9tSW5kZXggVGhlIGluZGV4IHRvIHNlYXJjaCBmcm9tLlxuICogQHBhcmFtIHtib29sZWFufSBbZnJvbVJpZ2h0XSBTcGVjaWZ5IGl0ZXJhdGluZyBmcm9tIHJpZ2h0IHRvIGxlZnQuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBSZXR1cm5zIHRoZSBpbmRleCBvZiB0aGUgbWF0Y2hlZCBgTmFOYCwgZWxzZSBgLTFgLlxuICovXG5mdW5jdGlvbiBpbmRleE9mTmFOKGFycmF5LCBmcm9tSW5kZXgsIGZyb21SaWdodCkge1xuICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoLFxuICAgICAgaW5kZXggPSBmcm9tSW5kZXggKyAoZnJvbVJpZ2h0ID8gMCA6IC0xKTtcblxuICB3aGlsZSAoKGZyb21SaWdodCA/IGluZGV4LS0gOiArK2luZGV4IDwgbGVuZ3RoKSkge1xuICAgIHZhciBvdGhlciA9IGFycmF5W2luZGV4XTtcbiAgICBpZiAob3RoZXIgIT09IG90aGVyKSB7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSBiYXNlSW5kZXhPZjtcbiIsIi8qKlxuICogbG9kYXNoIDMuMC4yIChDdXN0b20gQnVpbGQpIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQnVpbGQ6IGBsb2Rhc2ggbW9kZXJuIG1vZHVsYXJpemUgZXhwb3J0cz1cIm5wbVwiIC1vIC4vYFxuICogQ29weXJpZ2h0IDIwMTItMjAxNSBUaGUgRG9qbyBGb3VuZGF0aW9uIDxodHRwOi8vZG9qb2ZvdW5kYXRpb24ub3JnLz5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgMjAwOS0yMDE1IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICovXG5cbi8qKlxuICogQ2hlY2tzIGlmIGB2YWx1ZWAgaXMgaW4gYGNhY2hlYCBtaW1pY2tpbmcgdGhlIHJldHVybiBzaWduYXR1cmUgb2ZcbiAqIGBfLmluZGV4T2ZgIGJ5IHJldHVybmluZyBgMGAgaWYgdGhlIHZhbHVlIGlzIGZvdW5kLCBlbHNlIGAtMWAuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7T2JqZWN0fSBjYWNoZSBUaGUgY2FjaGUgdG8gc2VhcmNoLlxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VhcmNoIGZvci5cbiAqIEByZXR1cm5zIHtudW1iZXJ9IFJldHVybnMgYDBgIGlmIGB2YWx1ZWAgaXMgZm91bmQsIGVsc2UgYC0xYC5cbiAqL1xuZnVuY3Rpb24gY2FjaGVJbmRleE9mKGNhY2hlLCB2YWx1ZSkge1xuICB2YXIgZGF0YSA9IGNhY2hlLmRhdGEsXG4gICAgICByZXN1bHQgPSAodHlwZW9mIHZhbHVlID09ICdzdHJpbmcnIHx8IGlzT2JqZWN0KHZhbHVlKSkgPyBkYXRhLnNldC5oYXModmFsdWUpIDogZGF0YS5oYXNoW3ZhbHVlXTtcblxuICByZXR1cm4gcmVzdWx0ID8gMCA6IC0xO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHRoZSBbbGFuZ3VhZ2UgdHlwZV0oaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyN4OCkgb2YgYE9iamVjdGAuXG4gKiAoZS5nLiBhcnJheXMsIGZ1bmN0aW9ucywgb2JqZWN0cywgcmVnZXhlcywgYG5ldyBOdW1iZXIoMClgLCBhbmQgYG5ldyBTdHJpbmcoJycpYClcbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3Qoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KDEpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgLy8gQXZvaWQgYSBWOCBKSVQgYnVnIGluIENocm9tZSAxOS0yMC5cbiAgLy8gU2VlIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0yMjkxIGZvciBtb3JlIGRldGFpbHMuXG4gIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICByZXR1cm4gISF2YWx1ZSAmJiAodHlwZSA9PSAnb2JqZWN0JyB8fCB0eXBlID09ICdmdW5jdGlvbicpO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNhY2hlSW5kZXhPZjtcbiIsIi8qKlxuICogbG9kYXNoIDMuMS4yIChDdXN0b20gQnVpbGQpIDxodHRwczovL2xvZGFzaC5jb20vPlxuICogQnVpbGQ6IGBsb2Rhc2ggbW9kZXJuIG1vZHVsYXJpemUgZXhwb3J0cz1cIm5wbVwiIC1vIC4vYFxuICogQ29weXJpZ2h0IDIwMTItMjAxNSBUaGUgRG9qbyBGb3VuZGF0aW9uIDxodHRwOi8vZG9qb2ZvdW5kYXRpb24ub3JnLz5cbiAqIEJhc2VkIG9uIFVuZGVyc2NvcmUuanMgMS44LjMgPGh0dHA6Ly91bmRlcnNjb3JlanMub3JnL0xJQ0VOU0U+XG4gKiBDb3B5cmlnaHQgMjAwOS0yMDE1IEplcmVteSBBc2hrZW5hcywgRG9jdW1lbnRDbG91ZCBhbmQgSW52ZXN0aWdhdGl2ZSBSZXBvcnRlcnMgJiBFZGl0b3JzXG4gKiBBdmFpbGFibGUgdW5kZXIgTUlUIGxpY2Vuc2UgPGh0dHBzOi8vbG9kYXNoLmNvbS9saWNlbnNlPlxuICovXG52YXIgZ2V0TmF0aXZlID0gcmVxdWlyZSgnbG9kYXNoLl9nZXRuYXRpdmUnKTtcblxuLyoqIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcy4gKi9cbnZhciBTZXQgPSBnZXROYXRpdmUoZ2xvYmFsLCAnU2V0Jyk7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlQ3JlYXRlID0gZ2V0TmF0aXZlKE9iamVjdCwgJ2NyZWF0ZScpO1xuXG4vKipcbiAqXG4gKiBDcmVhdGVzIGEgY2FjaGUgb2JqZWN0IHRvIHN0b3JlIHVuaXF1ZSB2YWx1ZXMuXG4gKlxuICogQHByaXZhdGVcbiAqIEBwYXJhbSB7QXJyYXl9IFt2YWx1ZXNdIFRoZSB2YWx1ZXMgdG8gY2FjaGUuXG4gKi9cbmZ1bmN0aW9uIFNldENhY2hlKHZhbHVlcykge1xuICB2YXIgbGVuZ3RoID0gdmFsdWVzID8gdmFsdWVzLmxlbmd0aCA6IDA7XG5cbiAgdGhpcy5kYXRhID0geyAnaGFzaCc6IG5hdGl2ZUNyZWF0ZShudWxsKSwgJ3NldCc6IG5ldyBTZXQgfTtcbiAgd2hpbGUgKGxlbmd0aC0tKSB7XG4gICAgdGhpcy5wdXNoKHZhbHVlc1tsZW5ndGhdKTtcbiAgfVxufVxuXG4vKipcbiAqIEFkZHMgYHZhbHVlYCB0byB0aGUgY2FjaGUuXG4gKlxuICogQHByaXZhdGVcbiAqIEBuYW1lIHB1c2hcbiAqIEBtZW1iZXJPZiBTZXRDYWNoZVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gY2FjaGUuXG4gKi9cbmZ1bmN0aW9uIGNhY2hlUHVzaCh2YWx1ZSkge1xuICB2YXIgZGF0YSA9IHRoaXMuZGF0YTtcbiAgaWYgKHR5cGVvZiB2YWx1ZSA9PSAnc3RyaW5nJyB8fCBpc09iamVjdCh2YWx1ZSkpIHtcbiAgICBkYXRhLnNldC5hZGQodmFsdWUpO1xuICB9IGVsc2Uge1xuICAgIGRhdGEuaGFzaFt2YWx1ZV0gPSB0cnVlO1xuICB9XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGBTZXRgIGNhY2hlIG9iamVjdCB0byBvcHRpbWl6ZSBsaW5lYXIgc2VhcmNoZXMgb2YgbGFyZ2UgYXJyYXlzLlxuICpcbiAqIEBwcml2YXRlXG4gKiBAcGFyYW0ge0FycmF5fSBbdmFsdWVzXSBUaGUgdmFsdWVzIHRvIGNhY2hlLlxuICogQHJldHVybnMge251bGx8T2JqZWN0fSBSZXR1cm5zIHRoZSBuZXcgY2FjaGUgb2JqZWN0IGlmIGBTZXRgIGlzIHN1cHBvcnRlZCwgZWxzZSBgbnVsbGAuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUNhY2hlKHZhbHVlcykge1xuICByZXR1cm4gKG5hdGl2ZUNyZWF0ZSAmJiBTZXQpID8gbmV3IFNldENhY2hlKHZhbHVlcykgOiBudWxsO1xufVxuXG4vKipcbiAqIENoZWNrcyBpZiBgdmFsdWVgIGlzIHRoZSBbbGFuZ3VhZ2UgdHlwZV0oaHR0cHM6Ly9lczUuZ2l0aHViLmlvLyN4OCkgb2YgYE9iamVjdGAuXG4gKiAoZS5nLiBhcnJheXMsIGZ1bmN0aW9ucywgb2JqZWN0cywgcmVnZXhlcywgYG5ldyBOdW1iZXIoMClgLCBhbmQgYG5ldyBTdHJpbmcoJycpYClcbiAqXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgX1xuICogQGNhdGVnb3J5IExhbmdcbiAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIGNoZWNrLlxuICogQHJldHVybnMge2Jvb2xlYW59IFJldHVybnMgYHRydWVgIGlmIGB2YWx1ZWAgaXMgYW4gb2JqZWN0LCBlbHNlIGBmYWxzZWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIF8uaXNPYmplY3Qoe30pO1xuICogLy8gPT4gdHJ1ZVxuICpcbiAqIF8uaXNPYmplY3QoWzEsIDIsIDNdKTtcbiAqIC8vID0+IHRydWVcbiAqXG4gKiBfLmlzT2JqZWN0KDEpO1xuICogLy8gPT4gZmFsc2VcbiAqL1xuZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcbiAgLy8gQXZvaWQgYSBWOCBKSVQgYnVnIGluIENocm9tZSAxOS0yMC5cbiAgLy8gU2VlIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0yMjkxIGZvciBtb3JlIGRldGFpbHMuXG4gIHZhciB0eXBlID0gdHlwZW9mIHZhbHVlO1xuICByZXR1cm4gISF2YWx1ZSAmJiAodHlwZSA9PSAnb2JqZWN0JyB8fCB0eXBlID09ICdmdW5jdGlvbicpO1xufVxuXG4vLyBBZGQgZnVuY3Rpb25zIHRvIHRoZSBgU2V0YCBjYWNoZS5cblNldENhY2hlLnByb3RvdHlwZS5wdXNoID0gY2FjaGVQdXNoO1xuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUNhY2hlO1xuIiwiLyoqXG4gKiBsb2Rhc2ggMy42LjEgKEN1c3RvbSBCdWlsZCkgPGh0dHBzOi8vbG9kYXNoLmNvbS8+XG4gKiBCdWlsZDogYGxvZGFzaCBtb2Rlcm4gbW9kdWxhcml6ZSBleHBvcnRzPVwibnBtXCIgLW8gLi9gXG4gKiBDb3B5cmlnaHQgMjAxMi0yMDE1IFRoZSBEb2pvIEZvdW5kYXRpb24gPGh0dHA6Ly9kb2pvZm91bmRhdGlvbi5vcmcvPlxuICogQmFzZWQgb24gVW5kZXJzY29yZS5qcyAxLjguMyA8aHR0cDovL3VuZGVyc2NvcmVqcy5vcmcvTElDRU5TRT5cbiAqIENvcHlyaWdodCAyMDA5LTIwMTUgSmVyZW15IEFzaGtlbmFzLCBEb2N1bWVudENsb3VkIGFuZCBJbnZlc3RpZ2F0aXZlIFJlcG9ydGVycyAmIEVkaXRvcnNcbiAqIEF2YWlsYWJsZSB1bmRlciBNSVQgbGljZW5zZSA8aHR0cHM6Ly9sb2Rhc2guY29tL2xpY2Vuc2U+XG4gKi9cblxuLyoqIFVzZWQgYXMgdGhlIGBUeXBlRXJyb3JgIG1lc3NhZ2UgZm9yIFwiRnVuY3Rpb25zXCIgbWV0aG9kcy4gKi9cbnZhciBGVU5DX0VSUk9SX1RFWFQgPSAnRXhwZWN0ZWQgYSBmdW5jdGlvbic7XG5cbi8qIE5hdGl2ZSBtZXRob2QgcmVmZXJlbmNlcyBmb3IgdGhvc2Ugd2l0aCB0aGUgc2FtZSBuYW1lIGFzIG90aGVyIGBsb2Rhc2hgIG1ldGhvZHMuICovXG52YXIgbmF0aXZlTWF4ID0gTWF0aC5tYXg7XG5cbi8qKlxuICogQ3JlYXRlcyBhIGZ1bmN0aW9uIHRoYXQgaW52b2tlcyBgZnVuY2Agd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgdGhlXG4gKiBjcmVhdGVkIGZ1bmN0aW9uIGFuZCBhcmd1bWVudHMgZnJvbSBgc3RhcnRgIGFuZCBiZXlvbmQgcHJvdmlkZWQgYXMgYW4gYXJyYXkuXG4gKlxuICogKipOb3RlOioqIFRoaXMgbWV0aG9kIGlzIGJhc2VkIG9uIHRoZSBbcmVzdCBwYXJhbWV0ZXJdKGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL0Z1bmN0aW9ucy9yZXN0X3BhcmFtZXRlcnMpLlxuICpcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBfXG4gKiBAY2F0ZWdvcnkgRnVuY3Rpb25cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgVGhlIGZ1bmN0aW9uIHRvIGFwcGx5IGEgcmVzdCBwYXJhbWV0ZXIgdG8uXG4gKiBAcGFyYW0ge251bWJlcn0gW3N0YXJ0PWZ1bmMubGVuZ3RoLTFdIFRoZSBzdGFydCBwb3NpdGlvbiBvZiB0aGUgcmVzdCBwYXJhbWV0ZXIuXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IFJldHVybnMgdGhlIG5ldyBmdW5jdGlvbi5cbiAqIEBleGFtcGxlXG4gKlxuICogdmFyIHNheSA9IF8ucmVzdFBhcmFtKGZ1bmN0aW9uKHdoYXQsIG5hbWVzKSB7XG4gKiAgIHJldHVybiB3aGF0ICsgJyAnICsgXy5pbml0aWFsKG5hbWVzKS5qb2luKCcsICcpICtcbiAqICAgICAoXy5zaXplKG5hbWVzKSA+IDEgPyAnLCAmICcgOiAnJykgKyBfLmxhc3QobmFtZXMpO1xuICogfSk7XG4gKlxuICogc2F5KCdoZWxsbycsICdmcmVkJywgJ2Jhcm5leScsICdwZWJibGVzJyk7XG4gKiAvLyA9PiAnaGVsbG8gZnJlZCwgYmFybmV5LCAmIHBlYmJsZXMnXG4gKi9cbmZ1bmN0aW9uIHJlc3RQYXJhbShmdW5jLCBzdGFydCkge1xuICBpZiAodHlwZW9mIGZ1bmMgIT0gJ2Z1bmN0aW9uJykge1xuICAgIHRocm93IG5ldyBUeXBlRXJyb3IoRlVOQ19FUlJPUl9URVhUKTtcbiAgfVxuICBzdGFydCA9IG5hdGl2ZU1heChzdGFydCA9PT0gdW5kZWZpbmVkID8gKGZ1bmMubGVuZ3RoIC0gMSkgOiAoK3N0YXJ0IHx8IDApLCAwKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzID0gYXJndW1lbnRzLFxuICAgICAgICBpbmRleCA9IC0xLFxuICAgICAgICBsZW5ndGggPSBuYXRpdmVNYXgoYXJncy5sZW5ndGggLSBzdGFydCwgMCksXG4gICAgICAgIHJlc3QgPSBBcnJheShsZW5ndGgpO1xuXG4gICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgIHJlc3RbaW5kZXhdID0gYXJnc1tzdGFydCArIGluZGV4XTtcbiAgICB9XG4gICAgc3dpdGNoIChzdGFydCkge1xuICAgICAgY2FzZSAwOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIHJlc3QpO1xuICAgICAgY2FzZSAxOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIGFyZ3NbMF0sIHJlc3QpO1xuICAgICAgY2FzZSAyOiByZXR1cm4gZnVuYy5jYWxsKHRoaXMsIGFyZ3NbMF0sIGFyZ3NbMV0sIHJlc3QpO1xuICAgIH1cbiAgICB2YXIgb3RoZXJBcmdzID0gQXJyYXkoc3RhcnQgKyAxKTtcbiAgICBpbmRleCA9IC0xO1xuICAgIHdoaWxlICgrK2luZGV4IDwgc3RhcnQpIHtcbiAgICAgIG90aGVyQXJnc1tpbmRleF0gPSBhcmdzW2luZGV4XTtcbiAgICB9XG4gICAgb3RoZXJBcmdzW3N0YXJ0XSA9IHJlc3Q7XG4gICAgcmV0dXJuIGZ1bmMuYXBwbHkodGhpcywgb3RoZXJBcmdzKTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSByZXN0UGFyYW07XG4iLCJ2YXIgVk5vZGUgPSByZXF1aXJlKCcuL3Zub2RlJyk7XG52YXIgaXMgPSByZXF1aXJlKCcuL2lzJyk7XG5cbmZ1bmN0aW9uIGFkZE5TKGRhdGEsIGNoaWxkcmVuKSB7XG4gIGRhdGEubnMgPSAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnO1xuICBpZiAoY2hpbGRyZW4gIT09IHVuZGVmaW5lZCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyArK2kpIHtcbiAgICAgIGFkZE5TKGNoaWxkcmVuW2ldLmRhdGEsIGNoaWxkcmVuW2ldLmNoaWxkcmVuKTtcbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBoKHNlbCwgYiwgYykge1xuICB2YXIgZGF0YSA9IHt9LCBjaGlsZHJlbiwgdGV4dCwgaTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDMpIHtcbiAgICBkYXRhID0gYjtcbiAgICBpZiAoaXMuYXJyYXkoYykpIHsgY2hpbGRyZW4gPSBjOyB9XG4gICAgZWxzZSBpZiAoaXMucHJpbWl0aXZlKGMpKSB7IHRleHQgPSBjOyB9XG4gIH0gZWxzZSBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMikge1xuICAgIGlmIChpcy5hcnJheShiKSkgeyBjaGlsZHJlbiA9IGI7IH1cbiAgICBlbHNlIGlmIChpcy5wcmltaXRpdmUoYikpIHsgdGV4dCA9IGI7IH1cbiAgICBlbHNlIHsgZGF0YSA9IGI7IH1cbiAgfVxuICBpZiAoaXMuYXJyYXkoY2hpbGRyZW4pKSB7XG4gICAgZm9yIChpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgKytpKSB7XG4gICAgICBpZiAoaXMucHJpbWl0aXZlKGNoaWxkcmVuW2ldKSkgY2hpbGRyZW5baV0gPSBWTm9kZSh1bmRlZmluZWQsIHVuZGVmaW5lZCwgdW5kZWZpbmVkLCBjaGlsZHJlbltpXSk7XG4gICAgfVxuICB9XG4gIGlmIChzZWxbMF0gPT09ICdzJyAmJiBzZWxbMV0gPT09ICd2JyAmJiBzZWxbMl0gPT09ICdnJykge1xuICAgIGFkZE5TKGRhdGEsIGNoaWxkcmVuKTtcbiAgfVxuICByZXR1cm4gVk5vZGUoc2VsLCBkYXRhLCBjaGlsZHJlbiwgdGV4dCwgdW5kZWZpbmVkKTtcbn07XG4iLCJmdW5jdGlvbiBjcmVhdGVFbGVtZW50KHRhZ05hbWUpe1xuICByZXR1cm4gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWdOYW1lKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlRWxlbWVudE5TKG5hbWVzcGFjZVVSSSwgcXVhbGlmaWVkTmFtZSl7XG4gIHJldHVybiBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMobmFtZXNwYWNlVVJJLCBxdWFsaWZpZWROYW1lKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlVGV4dE5vZGUodGV4dCl7XG4gIHJldHVybiBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh0ZXh0KTtcbn1cblxuXG5mdW5jdGlvbiBpbnNlcnRCZWZvcmUocGFyZW50Tm9kZSwgbmV3Tm9kZSwgcmVmZXJlbmNlTm9kZSl7XG4gIHBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5ld05vZGUsIHJlZmVyZW5jZU5vZGUpO1xufVxuXG5cbmZ1bmN0aW9uIHJlbW92ZUNoaWxkKG5vZGUsIGNoaWxkKXtcbiAgbm9kZS5yZW1vdmVDaGlsZChjaGlsZCk7XG59XG5cbmZ1bmN0aW9uIGFwcGVuZENoaWxkKG5vZGUsIGNoaWxkKXtcbiAgbm9kZS5hcHBlbmRDaGlsZChjaGlsZCk7XG59XG5cbmZ1bmN0aW9uIHBhcmVudE5vZGUobm9kZSl7XG4gIHJldHVybiBub2RlLnBhcmVudEVsZW1lbnQ7XG59XG5cbmZ1bmN0aW9uIG5leHRTaWJsaW5nKG5vZGUpe1xuICByZXR1cm4gbm9kZS5uZXh0U2libGluZztcbn1cblxuZnVuY3Rpb24gdGFnTmFtZShub2RlKXtcbiAgcmV0dXJuIG5vZGUudGFnTmFtZTtcbn1cblxuZnVuY3Rpb24gc2V0VGV4dENvbnRlbnQobm9kZSwgdGV4dCl7XG4gIG5vZGUudGV4dENvbnRlbnQgPSB0ZXh0O1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgY3JlYXRlRWxlbWVudDogY3JlYXRlRWxlbWVudCxcbiAgY3JlYXRlRWxlbWVudE5TOiBjcmVhdGVFbGVtZW50TlMsXG4gIGNyZWF0ZVRleHROb2RlOiBjcmVhdGVUZXh0Tm9kZSxcbiAgYXBwZW5kQ2hpbGQ6IGFwcGVuZENoaWxkLFxuICByZW1vdmVDaGlsZDogcmVtb3ZlQ2hpbGQsXG4gIGluc2VydEJlZm9yZTogaW5zZXJ0QmVmb3JlLFxuICBwYXJlbnROb2RlOiBwYXJlbnROb2RlLFxuICBuZXh0U2libGluZzogbmV4dFNpYmxpbmcsXG4gIHRhZ05hbWU6IHRhZ05hbWUsXG4gIHNldFRleHRDb250ZW50OiBzZXRUZXh0Q29udGVudFxufTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge1xuICBhcnJheTogQXJyYXkuaXNBcnJheSxcbiAgcHJpbWl0aXZlOiBmdW5jdGlvbihzKSB7IHJldHVybiB0eXBlb2YgcyA9PT0gJ3N0cmluZycgfHwgdHlwZW9mIHMgPT09ICdudW1iZXInOyB9LFxufTtcbiIsInZhciBib29sZWFuQXR0cnMgPSBbXCJhbGxvd2Z1bGxzY3JlZW5cIiwgXCJhc3luY1wiLCBcImF1dG9mb2N1c1wiLCBcImF1dG9wbGF5XCIsIFwiY2hlY2tlZFwiLCBcImNvbXBhY3RcIiwgXCJjb250cm9sc1wiLCBcImRlY2xhcmVcIiwgXG4gICAgICAgICAgICAgICAgXCJkZWZhdWx0XCIsIFwiZGVmYXVsdGNoZWNrZWRcIiwgXCJkZWZhdWx0bXV0ZWRcIiwgXCJkZWZhdWx0c2VsZWN0ZWRcIiwgXCJkZWZlclwiLCBcImRpc2FibGVkXCIsIFwiZHJhZ2dhYmxlXCIsIFxuICAgICAgICAgICAgICAgIFwiZW5hYmxlZFwiLCBcImZvcm1ub3ZhbGlkYXRlXCIsIFwiaGlkZGVuXCIsIFwiaW5kZXRlcm1pbmF0ZVwiLCBcImluZXJ0XCIsIFwiaXNtYXBcIiwgXCJpdGVtc2NvcGVcIiwgXCJsb29wXCIsIFwibXVsdGlwbGVcIiwgXG4gICAgICAgICAgICAgICAgXCJtdXRlZFwiLCBcIm5vaHJlZlwiLCBcIm5vcmVzaXplXCIsIFwibm9zaGFkZVwiLCBcIm5vdmFsaWRhdGVcIiwgXCJub3dyYXBcIiwgXCJvcGVuXCIsIFwicGF1c2VvbmV4aXRcIiwgXCJyZWFkb25seVwiLCBcbiAgICAgICAgICAgICAgICBcInJlcXVpcmVkXCIsIFwicmV2ZXJzZWRcIiwgXCJzY29wZWRcIiwgXCJzZWFtbGVzc1wiLCBcInNlbGVjdGVkXCIsIFwic29ydGFibGVcIiwgXCJzcGVsbGNoZWNrXCIsIFwidHJhbnNsYXRlXCIsIFxuICAgICAgICAgICAgICAgIFwidHJ1ZXNwZWVkXCIsIFwidHlwZW11c3RtYXRjaFwiLCBcInZpc2libGVcIl07XG4gICAgXG52YXIgYm9vbGVhbkF0dHJzRGljdCA9IHt9O1xuZm9yKHZhciBpPTAsIGxlbiA9IGJvb2xlYW5BdHRycy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICBib29sZWFuQXR0cnNEaWN0W2Jvb2xlYW5BdHRyc1tpXV0gPSB0cnVlO1xufVxuICAgIFxuZnVuY3Rpb24gdXBkYXRlQXR0cnMob2xkVm5vZGUsIHZub2RlKSB7XG4gIHZhciBrZXksIGN1ciwgb2xkLCBlbG0gPSB2bm9kZS5lbG0sXG4gICAgICBvbGRBdHRycyA9IG9sZFZub2RlLmRhdGEuYXR0cnMgfHwge30sIGF0dHJzID0gdm5vZGUuZGF0YS5hdHRycyB8fCB7fTtcbiAgXG4gIC8vIHVwZGF0ZSBtb2RpZmllZCBhdHRyaWJ1dGVzLCBhZGQgbmV3IGF0dHJpYnV0ZXNcbiAgZm9yIChrZXkgaW4gYXR0cnMpIHtcbiAgICBjdXIgPSBhdHRyc1trZXldO1xuICAgIG9sZCA9IG9sZEF0dHJzW2tleV07XG4gICAgaWYgKG9sZCAhPT0gY3VyKSB7XG4gICAgICAvLyBUT0RPOiBhZGQgc3VwcG9ydCB0byBuYW1lc3BhY2VkIGF0dHJpYnV0ZXMgKHNldEF0dHJpYnV0ZU5TKVxuICAgICAgaWYoIWN1ciAmJiBib29sZWFuQXR0cnNEaWN0W2tleV0pXG4gICAgICAgIGVsbS5yZW1vdmVBdHRyaWJ1dGUoa2V5KTtcbiAgICAgIGVsc2VcbiAgICAgICAgZWxtLnNldEF0dHJpYnV0ZShrZXksIGN1cik7XG4gICAgfVxuICB9XG4gIC8vcmVtb3ZlIHJlbW92ZWQgYXR0cmlidXRlc1xuICAvLyB1c2UgYGluYCBvcGVyYXRvciBzaW5jZSB0aGUgcHJldmlvdXMgYGZvcmAgaXRlcmF0aW9uIHVzZXMgaXQgKC5pLmUuIGFkZCBldmVuIGF0dHJpYnV0ZXMgd2l0aCB1bmRlZmluZWQgdmFsdWUpXG4gIC8vIHRoZSBvdGhlciBvcHRpb24gaXMgdG8gcmVtb3ZlIGFsbCBhdHRyaWJ1dGVzIHdpdGggdmFsdWUgPT0gdW5kZWZpbmVkXG4gIGZvciAoa2V5IGluIG9sZEF0dHJzKSB7XG4gICAgaWYgKCEoa2V5IGluIGF0dHJzKSkge1xuICAgICAgZWxtLnJlbW92ZUF0dHJpYnV0ZShrZXkpO1xuICAgIH1cbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtjcmVhdGU6IHVwZGF0ZUF0dHJzLCB1cGRhdGU6IHVwZGF0ZUF0dHJzfTtcbiIsImZ1bmN0aW9uIHVwZGF0ZUNsYXNzKG9sZFZub2RlLCB2bm9kZSkge1xuICB2YXIgY3VyLCBuYW1lLCBlbG0gPSB2bm9kZS5lbG0sXG4gICAgICBvbGRDbGFzcyA9IG9sZFZub2RlLmRhdGEuY2xhc3MgfHwge30sXG4gICAgICBrbGFzcyA9IHZub2RlLmRhdGEuY2xhc3MgfHwge307XG4gIGZvciAobmFtZSBpbiBvbGRDbGFzcykge1xuICAgIGlmICgha2xhc3NbbmFtZV0pIHtcbiAgICAgIGVsbS5jbGFzc0xpc3QucmVtb3ZlKG5hbWUpO1xuICAgIH1cbiAgfVxuICBmb3IgKG5hbWUgaW4ga2xhc3MpIHtcbiAgICBjdXIgPSBrbGFzc1tuYW1lXTtcbiAgICBpZiAoY3VyICE9PSBvbGRDbGFzc1tuYW1lXSkge1xuICAgICAgZWxtLmNsYXNzTGlzdFtjdXIgPyAnYWRkJyA6ICdyZW1vdmUnXShuYW1lKTtcbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7Y3JlYXRlOiB1cGRhdGVDbGFzcywgdXBkYXRlOiB1cGRhdGVDbGFzc307XG4iLCJ2YXIgaXMgPSByZXF1aXJlKCcuLi9pcycpO1xuXG5mdW5jdGlvbiBhcnJJbnZva2VyKGFycikge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgLy8gU3BlY2lhbCBjYXNlIHdoZW4gbGVuZ3RoIGlzIHR3bywgZm9yIHBlcmZvcm1hbmNlXG4gICAgYXJyLmxlbmd0aCA9PT0gMiA/IGFyclswXShhcnJbMV0pIDogYXJyWzBdLmFwcGx5KHVuZGVmaW5lZCwgYXJyLnNsaWNlKDEpKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZm5JbnZva2VyKG8pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGV2KSB7IG8uZm4oZXYpOyB9O1xufVxuXG5mdW5jdGlvbiB1cGRhdGVFdmVudExpc3RlbmVycyhvbGRWbm9kZSwgdm5vZGUpIHtcbiAgdmFyIG5hbWUsIGN1ciwgb2xkLCBlbG0gPSB2bm9kZS5lbG0sXG4gICAgICBvbGRPbiA9IG9sZFZub2RlLmRhdGEub24gfHwge30sIG9uID0gdm5vZGUuZGF0YS5vbjtcbiAgaWYgKCFvbikgcmV0dXJuO1xuICBmb3IgKG5hbWUgaW4gb24pIHtcbiAgICBjdXIgPSBvbltuYW1lXTtcbiAgICBvbGQgPSBvbGRPbltuYW1lXTtcbiAgICBpZiAob2xkID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGlmIChpcy5hcnJheShjdXIpKSB7XG4gICAgICAgIGVsbS5hZGRFdmVudExpc3RlbmVyKG5hbWUsIGFyckludm9rZXIoY3VyKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjdXIgPSB7Zm46IGN1cn07XG4gICAgICAgIG9uW25hbWVdID0gY3VyO1xuICAgICAgICBlbG0uYWRkRXZlbnRMaXN0ZW5lcihuYW1lLCBmbkludm9rZXIoY3VyKSk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChpcy5hcnJheShvbGQpKSB7XG4gICAgICAvLyBEZWxpYmVyYXRlbHkgbW9kaWZ5IG9sZCBhcnJheSBzaW5jZSBpdCdzIGNhcHR1cmVkIGluIGNsb3N1cmUgY3JlYXRlZCB3aXRoIGBhcnJJbnZva2VyYFxuICAgICAgb2xkLmxlbmd0aCA9IGN1ci5sZW5ndGg7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9sZC5sZW5ndGg7ICsraSkgb2xkW2ldID0gY3VyW2ldO1xuICAgICAgb25bbmFtZV0gID0gb2xkO1xuICAgIH0gZWxzZSB7XG4gICAgICBvbGQuZm4gPSBjdXI7XG4gICAgICBvbltuYW1lXSA9IG9sZDtcbiAgICB9XG4gIH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7Y3JlYXRlOiB1cGRhdGVFdmVudExpc3RlbmVycywgdXBkYXRlOiB1cGRhdGVFdmVudExpc3RlbmVyc307XG4iLCJ2YXIgcmFmID0gKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUpIHx8IHNldFRpbWVvdXQ7XG52YXIgbmV4dEZyYW1lID0gZnVuY3Rpb24oZm4pIHsgcmFmKGZ1bmN0aW9uKCkgeyByYWYoZm4pOyB9KTsgfTtcblxuZnVuY3Rpb24gc2V0TmV4dEZyYW1lKG9iaiwgcHJvcCwgdmFsKSB7XG4gIG5leHRGcmFtZShmdW5jdGlvbigpIHsgb2JqW3Byb3BdID0gdmFsOyB9KTtcbn1cblxuZnVuY3Rpb24gZ2V0VGV4dE5vZGVSZWN0KHRleHROb2RlKSB7XG4gIHZhciByZWN0O1xuICBpZiAoZG9jdW1lbnQuY3JlYXRlUmFuZ2UpIHtcbiAgICB2YXIgcmFuZ2UgPSBkb2N1bWVudC5jcmVhdGVSYW5nZSgpO1xuICAgIHJhbmdlLnNlbGVjdE5vZGVDb250ZW50cyh0ZXh0Tm9kZSk7XG4gICAgaWYgKHJhbmdlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCkge1xuICAgICAgICByZWN0ID0gcmFuZ2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZWN0O1xufVxuXG5mdW5jdGlvbiBjYWxjVHJhbnNmb3JtT3JpZ2luKGlzVGV4dE5vZGUsIHRleHRSZWN0LCBib3VuZGluZ1JlY3QpIHtcbiAgaWYgKGlzVGV4dE5vZGUpIHtcbiAgICBpZiAodGV4dFJlY3QpIHtcbiAgICAgIC8vY2FsY3VsYXRlIHBpeGVscyB0byBjZW50ZXIgb2YgdGV4dCBmcm9tIGxlZnQgZWRnZSBvZiBib3VuZGluZyBib3hcbiAgICAgIHZhciByZWxhdGl2ZUNlbnRlclggPSB0ZXh0UmVjdC5sZWZ0ICsgdGV4dFJlY3Qud2lkdGgvMiAtIGJvdW5kaW5nUmVjdC5sZWZ0O1xuICAgICAgdmFyIHJlbGF0aXZlQ2VudGVyWSA9IHRleHRSZWN0LnRvcCArIHRleHRSZWN0LmhlaWdodC8yIC0gYm91bmRpbmdSZWN0LnRvcDtcbiAgICAgIHJldHVybiByZWxhdGl2ZUNlbnRlclggKyAncHggJyArIHJlbGF0aXZlQ2VudGVyWSArICdweCc7XG4gICAgfVxuICB9XG4gIHJldHVybiAnMCAwJzsgLy90b3AgbGVmdFxufVxuXG5mdW5jdGlvbiBnZXRUZXh0RHgob2xkVGV4dFJlY3QsIG5ld1RleHRSZWN0KSB7XG4gIGlmIChvbGRUZXh0UmVjdCAmJiBuZXdUZXh0UmVjdCkge1xuICAgIHJldHVybiAoKG9sZFRleHRSZWN0LmxlZnQgKyBvbGRUZXh0UmVjdC53aWR0aC8yKSAtIChuZXdUZXh0UmVjdC5sZWZ0ICsgbmV3VGV4dFJlY3Qud2lkdGgvMikpO1xuICB9XG4gIHJldHVybiAwO1xufVxuZnVuY3Rpb24gZ2V0VGV4dER5KG9sZFRleHRSZWN0LCBuZXdUZXh0UmVjdCkge1xuICBpZiAob2xkVGV4dFJlY3QgJiYgbmV3VGV4dFJlY3QpIHtcbiAgICByZXR1cm4gKChvbGRUZXh0UmVjdC50b3AgKyBvbGRUZXh0UmVjdC5oZWlnaHQvMikgLSAobmV3VGV4dFJlY3QudG9wICsgbmV3VGV4dFJlY3QuaGVpZ2h0LzIpKTtcbiAgfVxuICByZXR1cm4gMDtcbn1cblxuZnVuY3Rpb24gaXNUZXh0RWxlbWVudChlbG0pIHtcbiAgcmV0dXJuIGVsbS5jaGlsZE5vZGVzLmxlbmd0aCA9PT0gMSAmJiBlbG0uY2hpbGROb2Rlc1swXS5ub2RlVHlwZSA9PT0gMztcbn1cblxudmFyIHJlbW92ZWQsIGNyZWF0ZWQ7XG5cbmZ1bmN0aW9uIHByZShvbGRWbm9kZSwgdm5vZGUpIHtcbiAgcmVtb3ZlZCA9IHt9O1xuICBjcmVhdGVkID0gW107XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZShvbGRWbm9kZSwgdm5vZGUpIHtcbiAgdmFyIGhlcm8gPSB2bm9kZS5kYXRhLmhlcm87XG4gIGlmIChoZXJvICYmIGhlcm8uaWQpIHtcbiAgICBjcmVhdGVkLnB1c2goaGVyby5pZCk7XG4gICAgY3JlYXRlZC5wdXNoKHZub2RlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBkZXN0cm95KHZub2RlKSB7XG4gIHZhciBoZXJvID0gdm5vZGUuZGF0YS5oZXJvO1xuICBpZiAoaGVybyAmJiBoZXJvLmlkKSB7XG4gICAgdmFyIGVsbSA9IHZub2RlLmVsbTtcbiAgICB2bm9kZS5pc1RleHROb2RlID0gaXNUZXh0RWxlbWVudChlbG0pOyAvL2lzIHRoaXMgYSB0ZXh0IG5vZGU/XG4gICAgdm5vZGUuYm91bmRpbmdSZWN0ID0gZWxtLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpOyAvL3NhdmUgdGhlIGJvdW5kaW5nIHJlY3RhbmdsZSB0byBhIG5ldyBwcm9wZXJ0eSBvbiB0aGUgdm5vZGVcbiAgICB2bm9kZS50ZXh0UmVjdCA9IHZub2RlLmlzVGV4dE5vZGUgPyBnZXRUZXh0Tm9kZVJlY3QoZWxtLmNoaWxkTm9kZXNbMF0pIDogbnVsbDsgLy9zYXZlIGJvdW5kaW5nIHJlY3Qgb2YgaW5uZXIgdGV4dCBub2RlXG4gICAgdmFyIGNvbXB1dGVkU3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShlbG0sIG51bGwpOyAvL2dldCBjdXJyZW50IHN0eWxlcyAoaW5jbHVkZXMgaW5oZXJpdGVkIHByb3BlcnRpZXMpXG4gICAgdm5vZGUuc2F2ZWRTdHlsZSA9IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoY29tcHV0ZWRTdHlsZSkpOyAvL3NhdmUgYSBjb3B5IG9mIGNvbXB1dGVkIHN0eWxlIHZhbHVlc1xuICAgIHJlbW92ZWRbaGVyby5pZF0gPSB2bm9kZTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwb3N0KCkge1xuICB2YXIgaSwgaWQsIG5ld0VsbSwgb2xkVm5vZGUsIG9sZEVsbSwgaFJhdGlvLCB3UmF0aW8sXG4gICAgICBvbGRSZWN0LCBuZXdSZWN0LCBkeCwgZHksIG9yaWdUcmFuc2Zvcm0sIG9yaWdUcmFuc2l0aW9uLFxuICAgICAgbmV3U3R5bGUsIG9sZFN0eWxlLCBuZXdDb21wdXRlZFN0eWxlLCBpc1RleHROb2RlLFxuICAgICAgbmV3VGV4dFJlY3QsIG9sZFRleHRSZWN0O1xuICBmb3IgKGkgPSAwOyBpIDwgY3JlYXRlZC5sZW5ndGg7IGkgKz0gMikge1xuICAgIGlkID0gY3JlYXRlZFtpXTtcbiAgICBuZXdFbG0gPSBjcmVhdGVkW2krMV0uZWxtO1xuICAgIG9sZFZub2RlID0gcmVtb3ZlZFtpZF07XG4gICAgaWYgKG9sZFZub2RlKSB7XG4gICAgICBpc1RleHROb2RlID0gb2xkVm5vZGUuaXNUZXh0Tm9kZSAmJiBpc1RleHRFbGVtZW50KG5ld0VsbSk7IC8vQXJlIG9sZCAmIG5ldyBib3RoIHRleHQ/XG4gICAgICBuZXdTdHlsZSA9IG5ld0VsbS5zdHlsZTtcbiAgICAgIG5ld0NvbXB1dGVkU3R5bGUgPSB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZShuZXdFbG0sIG51bGwpOyAvL2dldCBmdWxsIGNvbXB1dGVkIHN0eWxlIGZvciBuZXcgZWxlbWVudFxuICAgICAgb2xkRWxtID0gb2xkVm5vZGUuZWxtO1xuICAgICAgb2xkU3R5bGUgPSBvbGRFbG0uc3R5bGU7XG4gICAgICAvL092ZXJhbGwgZWxlbWVudCBib3VuZGluZyBib3hlc1xuICAgICAgbmV3UmVjdCA9IG5ld0VsbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIG9sZFJlY3QgPSBvbGRWbm9kZS5ib3VuZGluZ1JlY3Q7IC8vcHJldmlvdXNseSBzYXZlZCBib3VuZGluZyByZWN0XG4gICAgICAvL1RleHQgbm9kZSBib3VuZGluZyBib3hlcyAmIGRpc3RhbmNlc1xuICAgICAgaWYgKGlzVGV4dE5vZGUpIHtcbiAgICAgICAgbmV3VGV4dFJlY3QgPSBnZXRUZXh0Tm9kZVJlY3QobmV3RWxtLmNoaWxkTm9kZXNbMF0pO1xuICAgICAgICBvbGRUZXh0UmVjdCA9IG9sZFZub2RlLnRleHRSZWN0O1xuICAgICAgICBkeCA9IGdldFRleHREeChvbGRUZXh0UmVjdCwgbmV3VGV4dFJlY3QpO1xuICAgICAgICBkeSA9IGdldFRleHREeShvbGRUZXh0UmVjdCwgbmV3VGV4dFJlY3QpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy9DYWxjdWxhdGUgZGlzdGFuY2VzIGJldHdlZW4gb2xkICYgbmV3IHBvc2l0aW9uc1xuICAgICAgICBkeCA9IG9sZFJlY3QubGVmdCAtIG5ld1JlY3QubGVmdDtcbiAgICAgICAgZHkgPSBvbGRSZWN0LnRvcCAtIG5ld1JlY3QudG9wO1xuICAgICAgfVxuICAgICAgaFJhdGlvID0gbmV3UmVjdC5oZWlnaHQgLyAoTWF0aC5tYXgob2xkUmVjdC5oZWlnaHQsIDEpKTtcbiAgICAgIHdSYXRpbyA9IGlzVGV4dE5vZGUgPyBoUmF0aW8gOiBuZXdSZWN0LndpZHRoIC8gKE1hdGgubWF4KG9sZFJlY3Qud2lkdGgsIDEpKTsgLy90ZXh0IHNjYWxlcyBiYXNlZCBvbiBoUmF0aW9cbiAgICAgIC8vIEFuaW1hdGUgbmV3IGVsZW1lbnRcbiAgICAgIG9yaWdUcmFuc2Zvcm0gPSBuZXdTdHlsZS50cmFuc2Zvcm07XG4gICAgICBvcmlnVHJhbnNpdGlvbiA9IG5ld1N0eWxlLnRyYW5zaXRpb247XG4gICAgICBpZiAobmV3Q29tcHV0ZWRTdHlsZS5kaXNwbGF5ID09PSAnaW5saW5lJykgLy9pbmxpbmUgZWxlbWVudHMgY2Fubm90IGJlIHRyYW5zZm9ybWVkXG4gICAgICAgIG5ld1N0eWxlLmRpc3BsYXkgPSAnaW5saW5lLWJsb2NrJzsgICAgICAgIC8vdGhpcyBkb2VzIG5vdCBhcHBlYXIgdG8gaGF2ZSBhbnkgbmVnYXRpdmUgc2lkZSBlZmZlY3RzXG4gICAgICBuZXdTdHlsZS50cmFuc2l0aW9uID0gb3JpZ1RyYW5zaXRpb24gKyAndHJhbnNmb3JtIDBzJztcbiAgICAgIG5ld1N0eWxlLnRyYW5zZm9ybU9yaWdpbiA9IGNhbGNUcmFuc2Zvcm1PcmlnaW4oaXNUZXh0Tm9kZSwgbmV3VGV4dFJlY3QsIG5ld1JlY3QpO1xuICAgICAgbmV3U3R5bGUub3BhY2l0eSA9ICcwJztcbiAgICAgIG5ld1N0eWxlLnRyYW5zZm9ybSA9IG9yaWdUcmFuc2Zvcm0gKyAndHJhbnNsYXRlKCcrZHgrJ3B4LCAnK2R5KydweCkgJyArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NjYWxlKCcrMS93UmF0aW8rJywgJysxL2hSYXRpbysnKSc7XG4gICAgICBzZXROZXh0RnJhbWUobmV3U3R5bGUsICd0cmFuc2l0aW9uJywgb3JpZ1RyYW5zaXRpb24pO1xuICAgICAgc2V0TmV4dEZyYW1lKG5ld1N0eWxlLCAndHJhbnNmb3JtJywgb3JpZ1RyYW5zZm9ybSk7XG4gICAgICBzZXROZXh0RnJhbWUobmV3U3R5bGUsICdvcGFjaXR5JywgJzEnKTtcbiAgICAgIC8vIEFuaW1hdGUgb2xkIGVsZW1lbnRcbiAgICAgIGZvciAodmFyIGtleSBpbiBvbGRWbm9kZS5zYXZlZFN0eWxlKSB7IC8vcmUtYXBwbHkgc2F2ZWQgaW5oZXJpdGVkIHByb3BlcnRpZXNcbiAgICAgICAgaWYgKHBhcnNlSW50KGtleSkgIT0ga2V5KSB7XG4gICAgICAgICAgdmFyIG1zID0ga2V5LnN1YnN0cmluZygwLDIpID09PSAnbXMnO1xuICAgICAgICAgIHZhciBtb3ogPSBrZXkuc3Vic3RyaW5nKDAsMykgPT09ICdtb3onO1xuICAgICAgICAgIHZhciB3ZWJraXQgPSBrZXkuc3Vic3RyaW5nKDAsNikgPT09ICd3ZWJraXQnO1xuICAgICAgXHQgIGlmICghbXMgJiYgIW1veiAmJiAhd2Via2l0KSAvL2lnbm9yZSBwcmVmaXhlZCBzdHlsZSBwcm9wZXJ0aWVzXG4gICAgICAgIFx0ICBvbGRTdHlsZVtrZXldID0gb2xkVm5vZGUuc2F2ZWRTdHlsZVtrZXldO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBvbGRTdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgICBvbGRTdHlsZS50b3AgPSBvbGRSZWN0LnRvcCArICdweCc7IC8vc3RhcnQgYXQgZXhpc3RpbmcgcG9zaXRpb25cbiAgICAgIG9sZFN0eWxlLmxlZnQgPSBvbGRSZWN0LmxlZnQgKyAncHgnO1xuICAgICAgb2xkU3R5bGUud2lkdGggPSBvbGRSZWN0LndpZHRoICsgJ3B4JzsgLy9OZWVkZWQgZm9yIGVsZW1lbnRzIHdobyB3ZXJlIHNpemVkIHJlbGF0aXZlIHRvIHRoZWlyIHBhcmVudHNcbiAgICAgIG9sZFN0eWxlLmhlaWdodCA9IG9sZFJlY3QuaGVpZ2h0ICsgJ3B4JzsgLy9OZWVkZWQgZm9yIGVsZW1lbnRzIHdobyB3ZXJlIHNpemVkIHJlbGF0aXZlIHRvIHRoZWlyIHBhcmVudHNcbiAgICAgIG9sZFN0eWxlLm1hcmdpbiA9IDA7IC8vTWFyZ2luIG9uIGhlcm8gZWxlbWVudCBsZWFkcyB0byBpbmNvcnJlY3QgcG9zaXRpb25pbmdcbiAgICAgIG9sZFN0eWxlLnRyYW5zZm9ybU9yaWdpbiA9IGNhbGNUcmFuc2Zvcm1PcmlnaW4oaXNUZXh0Tm9kZSwgb2xkVGV4dFJlY3QsIG9sZFJlY3QpO1xuICAgICAgb2xkU3R5bGUudHJhbnNmb3JtID0gJyc7XG4gICAgICBvbGRTdHlsZS5vcGFjaXR5ID0gJzEnO1xuICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChvbGRFbG0pO1xuICAgICAgc2V0TmV4dEZyYW1lKG9sZFN0eWxlLCAndHJhbnNmb3JtJywgJ3RyYW5zbGF0ZSgnKyAtZHggKydweCwgJysgLWR5ICsncHgpIHNjYWxlKCcrd1JhdGlvKycsICcraFJhdGlvKycpJyk7IC8vc2NhbGUgbXVzdCBiZSBvbiBmYXIgcmlnaHQgZm9yIHRyYW5zbGF0ZSB0byBiZSBjb3JyZWN0XG4gICAgICBzZXROZXh0RnJhbWUob2xkU3R5bGUsICdvcGFjaXR5JywgJzAnKTtcbiAgICAgIG9sZEVsbS5hZGRFdmVudExpc3RlbmVyKCd0cmFuc2l0aW9uZW5kJywgZnVuY3Rpb24oZXYpIHtcbiAgICAgICAgaWYgKGV2LnByb3BlcnR5TmFtZSA9PT0gJ3RyYW5zZm9ybScpXG4gICAgICAgICAgZG9jdW1lbnQuYm9keS5yZW1vdmVDaGlsZChldi50YXJnZXQpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIHJlbW92ZWQgPSBjcmVhdGVkID0gdW5kZWZpbmVkO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtwcmU6IHByZSwgY3JlYXRlOiBjcmVhdGUsIGRlc3Ryb3k6IGRlc3Ryb3ksIHBvc3Q6IHBvc3R9O1xuIiwiZnVuY3Rpb24gdXBkYXRlUHJvcHMob2xkVm5vZGUsIHZub2RlKSB7XG4gIHZhciBrZXksIGN1ciwgb2xkLCBlbG0gPSB2bm9kZS5lbG0sXG4gICAgICBvbGRQcm9wcyA9IG9sZFZub2RlLmRhdGEucHJvcHMgfHwge30sIHByb3BzID0gdm5vZGUuZGF0YS5wcm9wcyB8fCB7fTtcbiAgZm9yIChrZXkgaW4gb2xkUHJvcHMpIHtcbiAgICBpZiAoIXByb3BzW2tleV0pIHtcbiAgICAgIGRlbGV0ZSBlbG1ba2V5XTtcbiAgICB9XG4gIH1cbiAgZm9yIChrZXkgaW4gcHJvcHMpIHtcbiAgICBjdXIgPSBwcm9wc1trZXldO1xuICAgIG9sZCA9IG9sZFByb3BzW2tleV07XG4gICAgaWYgKG9sZCAhPT0gY3VyICYmIChrZXkgIT09ICd2YWx1ZScgfHwgZWxtW2tleV0gIT09IGN1cikpIHtcbiAgICAgIGVsbVtrZXldID0gY3VyO1xuICAgIH1cbiAgfVxufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtjcmVhdGU6IHVwZGF0ZVByb3BzLCB1cGRhdGU6IHVwZGF0ZVByb3BzfTtcbiIsInZhciByYWYgPSAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgJiYgd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSkgfHwgc2V0VGltZW91dDtcbnZhciBuZXh0RnJhbWUgPSBmdW5jdGlvbihmbikgeyByYWYoZnVuY3Rpb24oKSB7IHJhZihmbik7IH0pOyB9O1xuXG5mdW5jdGlvbiBzZXROZXh0RnJhbWUob2JqLCBwcm9wLCB2YWwpIHtcbiAgbmV4dEZyYW1lKGZ1bmN0aW9uKCkgeyBvYmpbcHJvcF0gPSB2YWw7IH0pO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVTdHlsZShvbGRWbm9kZSwgdm5vZGUpIHtcbiAgdmFyIGN1ciwgbmFtZSwgZWxtID0gdm5vZGUuZWxtLFxuICAgICAgb2xkU3R5bGUgPSBvbGRWbm9kZS5kYXRhLnN0eWxlIHx8IHt9LFxuICAgICAgc3R5bGUgPSB2bm9kZS5kYXRhLnN0eWxlIHx8IHt9LFxuICAgICAgb2xkSGFzRGVsID0gJ2RlbGF5ZWQnIGluIG9sZFN0eWxlO1xuICBmb3IgKG5hbWUgaW4gb2xkU3R5bGUpIHtcbiAgICBpZiAoIXN0eWxlW25hbWVdKSB7XG4gICAgICBlbG0uc3R5bGVbbmFtZV0gPSAnJztcbiAgICB9XG4gIH1cbiAgZm9yIChuYW1lIGluIHN0eWxlKSB7XG4gICAgY3VyID0gc3R5bGVbbmFtZV07XG4gICAgaWYgKG5hbWUgPT09ICdkZWxheWVkJykge1xuICAgICAgZm9yIChuYW1lIGluIHN0eWxlLmRlbGF5ZWQpIHtcbiAgICAgICAgY3VyID0gc3R5bGUuZGVsYXllZFtuYW1lXTtcbiAgICAgICAgaWYgKCFvbGRIYXNEZWwgfHwgY3VyICE9PSBvbGRTdHlsZS5kZWxheWVkW25hbWVdKSB7XG4gICAgICAgICAgc2V0TmV4dEZyYW1lKGVsbS5zdHlsZSwgbmFtZSwgY3VyKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobmFtZSAhPT0gJ3JlbW92ZScgJiYgY3VyICE9PSBvbGRTdHlsZVtuYW1lXSkge1xuICAgICAgZWxtLnN0eWxlW25hbWVdID0gY3VyO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBhcHBseURlc3Ryb3lTdHlsZSh2bm9kZSkge1xuICB2YXIgc3R5bGUsIG5hbWUsIGVsbSA9IHZub2RlLmVsbSwgcyA9IHZub2RlLmRhdGEuc3R5bGU7XG4gIGlmICghcyB8fCAhKHN0eWxlID0gcy5kZXN0cm95KSkgcmV0dXJuO1xuICBmb3IgKG5hbWUgaW4gc3R5bGUpIHtcbiAgICBlbG0uc3R5bGVbbmFtZV0gPSBzdHlsZVtuYW1lXTtcbiAgfVxufVxuXG5mdW5jdGlvbiBhcHBseVJlbW92ZVN0eWxlKHZub2RlLCBybSkge1xuICB2YXIgcyA9IHZub2RlLmRhdGEuc3R5bGU7XG4gIGlmICghcyB8fCAhcy5yZW1vdmUpIHtcbiAgICBybSgpO1xuICAgIHJldHVybjtcbiAgfVxuICB2YXIgbmFtZSwgZWxtID0gdm5vZGUuZWxtLCBpZHgsIGkgPSAwLCBtYXhEdXIgPSAwLFxuICAgICAgY29tcFN0eWxlLCBzdHlsZSA9IHMucmVtb3ZlLCBhbW91bnQgPSAwLCBhcHBsaWVkID0gW107XG4gIGZvciAobmFtZSBpbiBzdHlsZSkge1xuICAgIGFwcGxpZWQucHVzaChuYW1lKTtcbiAgICBlbG0uc3R5bGVbbmFtZV0gPSBzdHlsZVtuYW1lXTtcbiAgfVxuICBjb21wU3R5bGUgPSBnZXRDb21wdXRlZFN0eWxlKGVsbSk7XG4gIHZhciBwcm9wcyA9IGNvbXBTdHlsZVsndHJhbnNpdGlvbi1wcm9wZXJ0eSddLnNwbGl0KCcsICcpO1xuICBmb3IgKDsgaSA8IHByb3BzLmxlbmd0aDsgKytpKSB7XG4gICAgaWYoYXBwbGllZC5pbmRleE9mKHByb3BzW2ldKSAhPT0gLTEpIGFtb3VudCsrO1xuICB9XG4gIGVsbS5hZGRFdmVudExpc3RlbmVyKCd0cmFuc2l0aW9uZW5kJywgZnVuY3Rpb24oZXYpIHtcbiAgICBpZiAoZXYudGFyZ2V0ID09PSBlbG0pIC0tYW1vdW50O1xuICAgIGlmIChhbW91bnQgPT09IDApIHJtKCk7XG4gIH0pO1xufVxuXG5tb2R1bGUuZXhwb3J0cyA9IHtjcmVhdGU6IHVwZGF0ZVN0eWxlLCB1cGRhdGU6IHVwZGF0ZVN0eWxlLCBkZXN0cm95OiBhcHBseURlc3Ryb3lTdHlsZSwgcmVtb3ZlOiBhcHBseVJlbW92ZVN0eWxlfTtcbiIsIi8vIGpzaGludCBuZXdjYXA6IGZhbHNlXG4vKiBnbG9iYWwgcmVxdWlyZSwgbW9kdWxlLCBkb2N1bWVudCwgTm9kZSAqL1xuJ3VzZSBzdHJpY3QnO1xuXG52YXIgVk5vZGUgPSByZXF1aXJlKCcuL3Zub2RlJyk7XG52YXIgaXMgPSByZXF1aXJlKCcuL2lzJyk7XG52YXIgZG9tQXBpID0gcmVxdWlyZSgnLi9odG1sZG9tYXBpLmpzJyk7XG5cbmZ1bmN0aW9uIGlzVW5kZWYocykgeyByZXR1cm4gcyA9PT0gdW5kZWZpbmVkOyB9XG5mdW5jdGlvbiBpc0RlZihzKSB7IHJldHVybiBzICE9PSB1bmRlZmluZWQ7IH1cblxudmFyIGVtcHR5Tm9kZSA9IFZOb2RlKCcnLCB7fSwgW10sIHVuZGVmaW5lZCwgdW5kZWZpbmVkKTtcblxuZnVuY3Rpb24gc2FtZVZub2RlKHZub2RlMSwgdm5vZGUyKSB7XG4gIHJldHVybiB2bm9kZTEua2V5ID09PSB2bm9kZTIua2V5ICYmIHZub2RlMS5zZWwgPT09IHZub2RlMi5zZWw7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUtleVRvT2xkSWR4KGNoaWxkcmVuLCBiZWdpbklkeCwgZW5kSWR4KSB7XG4gIHZhciBpLCBtYXAgPSB7fSwga2V5O1xuICBmb3IgKGkgPSBiZWdpbklkeDsgaSA8PSBlbmRJZHg7ICsraSkge1xuICAgIGtleSA9IGNoaWxkcmVuW2ldLmtleTtcbiAgICBpZiAoaXNEZWYoa2V5KSkgbWFwW2tleV0gPSBpO1xuICB9XG4gIHJldHVybiBtYXA7XG59XG5cbnZhciBob29rcyA9IFsnY3JlYXRlJywgJ3VwZGF0ZScsICdyZW1vdmUnLCAnZGVzdHJveScsICdwcmUnLCAncG9zdCddO1xuXG5mdW5jdGlvbiBpbml0KG1vZHVsZXMsIGFwaSkge1xuICB2YXIgaSwgaiwgY2JzID0ge307XG5cbiAgaWYgKGlzVW5kZWYoYXBpKSkgYXBpID0gZG9tQXBpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBob29rcy5sZW5ndGg7ICsraSkge1xuICAgIGNic1tob29rc1tpXV0gPSBbXTtcbiAgICBmb3IgKGogPSAwOyBqIDwgbW9kdWxlcy5sZW5ndGg7ICsraikge1xuICAgICAgaWYgKG1vZHVsZXNbal1baG9va3NbaV1dICE9PSB1bmRlZmluZWQpIGNic1tob29rc1tpXV0ucHVzaChtb2R1bGVzW2pdW2hvb2tzW2ldXSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZW1wdHlOb2RlQXQoZWxtKSB7XG4gICAgcmV0dXJuIFZOb2RlKGFwaS50YWdOYW1lKGVsbSkudG9Mb3dlckNhc2UoKSwge30sIFtdLCB1bmRlZmluZWQsIGVsbSk7XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVSbUNiKGNoaWxkRWxtLCBsaXN0ZW5lcnMpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoLS1saXN0ZW5lcnMgPT09IDApIHtcbiAgICAgICAgdmFyIHBhcmVudCA9IGFwaS5wYXJlbnROb2RlKGNoaWxkRWxtKTtcbiAgICAgICAgYXBpLnJlbW92ZUNoaWxkKHBhcmVudCwgY2hpbGRFbG0pO1xuICAgICAgfVxuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBjcmVhdGVFbG0odm5vZGUsIGluc2VydGVkVm5vZGVRdWV1ZSkge1xuICAgIHZhciBpLCB0aHVuaywgZGF0YSA9IHZub2RlLmRhdGE7XG4gICAgaWYgKGlzRGVmKGRhdGEpKSB7XG4gICAgICBpZiAoaXNEZWYoaSA9IGRhdGEuaG9vaykgJiYgaXNEZWYoaSA9IGkuaW5pdCkpIGkodm5vZGUpO1xuICAgICAgaWYgKGlzRGVmKGkgPSBkYXRhLnZub2RlKSkge1xuICAgICAgICAgIHRodW5rID0gdm5vZGU7XG4gICAgICAgICAgdm5vZGUgPSBpO1xuICAgICAgfVxuICAgIH1cbiAgICB2YXIgZWxtLCBjaGlsZHJlbiA9IHZub2RlLmNoaWxkcmVuLCBzZWwgPSB2bm9kZS5zZWw7XG4gICAgaWYgKGlzRGVmKHNlbCkpIHtcbiAgICAgIC8vIFBhcnNlIHNlbGVjdG9yXG4gICAgICB2YXIgaGFzaElkeCA9IHNlbC5pbmRleE9mKCcjJyk7XG4gICAgICB2YXIgZG90SWR4ID0gc2VsLmluZGV4T2YoJy4nLCBoYXNoSWR4KTtcbiAgICAgIHZhciBoYXNoID0gaGFzaElkeCA+IDAgPyBoYXNoSWR4IDogc2VsLmxlbmd0aDtcbiAgICAgIHZhciBkb3QgPSBkb3RJZHggPiAwID8gZG90SWR4IDogc2VsLmxlbmd0aDtcbiAgICAgIHZhciB0YWcgPSBoYXNoSWR4ICE9PSAtMSB8fCBkb3RJZHggIT09IC0xID8gc2VsLnNsaWNlKDAsIE1hdGgubWluKGhhc2gsIGRvdCkpIDogc2VsO1xuICAgICAgZWxtID0gdm5vZGUuZWxtID0gaXNEZWYoZGF0YSkgJiYgaXNEZWYoaSA9IGRhdGEubnMpID8gYXBpLmNyZWF0ZUVsZW1lbnROUyhpLCB0YWcpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBhcGkuY3JlYXRlRWxlbWVudCh0YWcpO1xuICAgICAgaWYgKGhhc2ggPCBkb3QpIGVsbS5pZCA9IHNlbC5zbGljZShoYXNoICsgMSwgZG90KTtcbiAgICAgIGlmIChkb3RJZHggPiAwKSBlbG0uY2xhc3NOYW1lID0gc2VsLnNsaWNlKGRvdCsxKS5yZXBsYWNlKC9cXC4vZywgJyAnKTtcbiAgICAgIGlmIChpcy5hcnJheShjaGlsZHJlbikpIHtcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgYXBpLmFwcGVuZENoaWxkKGVsbSwgY3JlYXRlRWxtKGNoaWxkcmVuW2ldLCBpbnNlcnRlZFZub2RlUXVldWUpKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChpcy5wcmltaXRpdmUodm5vZGUudGV4dCkpIHtcbiAgICAgICAgYXBpLmFwcGVuZENoaWxkKGVsbSwgYXBpLmNyZWF0ZVRleHROb2RlKHZub2RlLnRleHQpKTtcbiAgICAgIH1cbiAgICAgIGZvciAoaSA9IDA7IGkgPCBjYnMuY3JlYXRlLmxlbmd0aDsgKytpKSBjYnMuY3JlYXRlW2ldKGVtcHR5Tm9kZSwgdm5vZGUpO1xuICAgICAgaSA9IHZub2RlLmRhdGEuaG9vazsgLy8gUmV1c2UgdmFyaWFibGVcbiAgICAgIGlmIChpc0RlZihpKSkge1xuICAgICAgICBpZiAoaS5jcmVhdGUpIGkuY3JlYXRlKGVtcHR5Tm9kZSwgdm5vZGUpO1xuICAgICAgICBpZiAoaS5pbnNlcnQpIGluc2VydGVkVm5vZGVRdWV1ZS5wdXNoKHZub2RlKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgZWxtID0gdm5vZGUuZWxtID0gYXBpLmNyZWF0ZVRleHROb2RlKHZub2RlLnRleHQpO1xuICAgIH1cbiAgICBpZiAoaXNEZWYodGh1bmspKSB0aHVuay5lbG0gPSB2bm9kZS5lbG07XG4gICAgcmV0dXJuIHZub2RlLmVsbTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGFkZFZub2RlcyhwYXJlbnRFbG0sIGJlZm9yZSwgdm5vZGVzLCBzdGFydElkeCwgZW5kSWR4LCBpbnNlcnRlZFZub2RlUXVldWUpIHtcbiAgICBmb3IgKDsgc3RhcnRJZHggPD0gZW5kSWR4OyArK3N0YXJ0SWR4KSB7XG4gICAgICBhcGkuaW5zZXJ0QmVmb3JlKHBhcmVudEVsbSwgY3JlYXRlRWxtKHZub2Rlc1tzdGFydElkeF0sIGluc2VydGVkVm5vZGVRdWV1ZSksIGJlZm9yZSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW52b2tlRGVzdHJveUhvb2sodm5vZGUpIHtcbiAgICB2YXIgaSwgaiwgZGF0YSA9IHZub2RlLmRhdGE7XG4gICAgaWYgKGlzRGVmKGRhdGEpKSB7XG4gICAgICBpZiAoaXNEZWYoaSA9IGRhdGEuaG9vaykgJiYgaXNEZWYoaSA9IGkuZGVzdHJveSkpIGkodm5vZGUpO1xuICAgICAgZm9yIChpID0gMDsgaSA8IGNicy5kZXN0cm95Lmxlbmd0aDsgKytpKSBjYnMuZGVzdHJveVtpXSh2bm9kZSk7XG4gICAgICBpZiAoaXNEZWYoaSA9IHZub2RlLmNoaWxkcmVuKSkge1xuICAgICAgICBmb3IgKGogPSAwOyBqIDwgdm5vZGUuY2hpbGRyZW4ubGVuZ3RoOyArK2opIHtcbiAgICAgICAgICBpbnZva2VEZXN0cm95SG9vayh2bm9kZS5jaGlsZHJlbltqXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmIChpc0RlZihpID0gZGF0YS52bm9kZSkpIGludm9rZURlc3Ryb3lIb29rKGkpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZVZub2RlcyhwYXJlbnRFbG0sIHZub2Rlcywgc3RhcnRJZHgsIGVuZElkeCkge1xuICAgIGZvciAoOyBzdGFydElkeCA8PSBlbmRJZHg7ICsrc3RhcnRJZHgpIHtcbiAgICAgIHZhciBpLCBsaXN0ZW5lcnMsIHJtLCBjaCA9IHZub2Rlc1tzdGFydElkeF07XG4gICAgICBpZiAoaXNEZWYoY2gpKSB7XG4gICAgICAgIGlmIChpc0RlZihjaC5zZWwpKSB7XG4gICAgICAgICAgaW52b2tlRGVzdHJveUhvb2soY2gpO1xuICAgICAgICAgIGxpc3RlbmVycyA9IGNicy5yZW1vdmUubGVuZ3RoICsgMTtcbiAgICAgICAgICBybSA9IGNyZWF0ZVJtQ2IoY2guZWxtLCBsaXN0ZW5lcnMpO1xuICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjYnMucmVtb3ZlLmxlbmd0aDsgKytpKSBjYnMucmVtb3ZlW2ldKGNoLCBybSk7XG4gICAgICAgICAgaWYgKGlzRGVmKGkgPSBjaC5kYXRhKSAmJiBpc0RlZihpID0gaS5ob29rKSAmJiBpc0RlZihpID0gaS5yZW1vdmUpKSB7XG4gICAgICAgICAgICBpKGNoLCBybSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJtKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgeyAvLyBUZXh0IG5vZGVcbiAgICAgICAgICBhcGkucmVtb3ZlQ2hpbGQocGFyZW50RWxtLCBjaC5lbG0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlQ2hpbGRyZW4ocGFyZW50RWxtLCBvbGRDaCwgbmV3Q2gsIGluc2VydGVkVm5vZGVRdWV1ZSkge1xuICAgIHZhciBvbGRTdGFydElkeCA9IDAsIG5ld1N0YXJ0SWR4ID0gMDtcbiAgICB2YXIgb2xkRW5kSWR4ID0gb2xkQ2gubGVuZ3RoIC0gMTtcbiAgICB2YXIgb2xkU3RhcnRWbm9kZSA9IG9sZENoWzBdO1xuICAgIHZhciBvbGRFbmRWbm9kZSA9IG9sZENoW29sZEVuZElkeF07XG4gICAgdmFyIG5ld0VuZElkeCA9IG5ld0NoLmxlbmd0aCAtIDE7XG4gICAgdmFyIG5ld1N0YXJ0Vm5vZGUgPSBuZXdDaFswXTtcbiAgICB2YXIgbmV3RW5kVm5vZGUgPSBuZXdDaFtuZXdFbmRJZHhdO1xuICAgIHZhciBvbGRLZXlUb0lkeCwgaWR4SW5PbGQsIGVsbVRvTW92ZSwgYmVmb3JlO1xuXG4gICAgd2hpbGUgKG9sZFN0YXJ0SWR4IDw9IG9sZEVuZElkeCAmJiBuZXdTdGFydElkeCA8PSBuZXdFbmRJZHgpIHtcbiAgICAgIGlmIChpc1VuZGVmKG9sZFN0YXJ0Vm5vZGUpKSB7XG4gICAgICAgIG9sZFN0YXJ0Vm5vZGUgPSBvbGRDaFsrK29sZFN0YXJ0SWR4XTsgLy8gVm5vZGUgaGFzIGJlZW4gbW92ZWQgbGVmdFxuICAgICAgfSBlbHNlIGlmIChpc1VuZGVmKG9sZEVuZFZub2RlKSkge1xuICAgICAgICBvbGRFbmRWbm9kZSA9IG9sZENoWy0tb2xkRW5kSWR4XTtcbiAgICAgIH0gZWxzZSBpZiAoc2FtZVZub2RlKG9sZFN0YXJ0Vm5vZGUsIG5ld1N0YXJ0Vm5vZGUpKSB7XG4gICAgICAgIHBhdGNoVm5vZGUob2xkU3RhcnRWbm9kZSwgbmV3U3RhcnRWbm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTtcbiAgICAgICAgb2xkU3RhcnRWbm9kZSA9IG9sZENoWysrb2xkU3RhcnRJZHhdO1xuICAgICAgICBuZXdTdGFydFZub2RlID0gbmV3Q2hbKytuZXdTdGFydElkeF07XG4gICAgICB9IGVsc2UgaWYgKHNhbWVWbm9kZShvbGRFbmRWbm9kZSwgbmV3RW5kVm5vZGUpKSB7XG4gICAgICAgIHBhdGNoVm5vZGUob2xkRW5kVm5vZGUsIG5ld0VuZFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgICBvbGRFbmRWbm9kZSA9IG9sZENoWy0tb2xkRW5kSWR4XTtcbiAgICAgICAgbmV3RW5kVm5vZGUgPSBuZXdDaFstLW5ld0VuZElkeF07XG4gICAgICB9IGVsc2UgaWYgKHNhbWVWbm9kZShvbGRTdGFydFZub2RlLCBuZXdFbmRWbm9kZSkpIHsgLy8gVm5vZGUgbW92ZWQgcmlnaHRcbiAgICAgICAgcGF0Y2hWbm9kZShvbGRTdGFydFZub2RlLCBuZXdFbmRWbm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTtcbiAgICAgICAgYXBpLmluc2VydEJlZm9yZShwYXJlbnRFbG0sIG9sZFN0YXJ0Vm5vZGUuZWxtLCBhcGkubmV4dFNpYmxpbmcob2xkRW5kVm5vZGUuZWxtKSk7XG4gICAgICAgIG9sZFN0YXJ0Vm5vZGUgPSBvbGRDaFsrK29sZFN0YXJ0SWR4XTtcbiAgICAgICAgbmV3RW5kVm5vZGUgPSBuZXdDaFstLW5ld0VuZElkeF07XG4gICAgICB9IGVsc2UgaWYgKHNhbWVWbm9kZShvbGRFbmRWbm9kZSwgbmV3U3RhcnRWbm9kZSkpIHsgLy8gVm5vZGUgbW92ZWQgbGVmdFxuICAgICAgICBwYXRjaFZub2RlKG9sZEVuZFZub2RlLCBuZXdTdGFydFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgICBhcGkuaW5zZXJ0QmVmb3JlKHBhcmVudEVsbSwgb2xkRW5kVm5vZGUuZWxtLCBvbGRTdGFydFZub2RlLmVsbSk7XG4gICAgICAgIG9sZEVuZFZub2RlID0gb2xkQ2hbLS1vbGRFbmRJZHhdO1xuICAgICAgICBuZXdTdGFydFZub2RlID0gbmV3Q2hbKytuZXdTdGFydElkeF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoaXNVbmRlZihvbGRLZXlUb0lkeCkpIG9sZEtleVRvSWR4ID0gY3JlYXRlS2V5VG9PbGRJZHgob2xkQ2gsIG9sZFN0YXJ0SWR4LCBvbGRFbmRJZHgpO1xuICAgICAgICBpZHhJbk9sZCA9IG9sZEtleVRvSWR4W25ld1N0YXJ0Vm5vZGUua2V5XTtcbiAgICAgICAgaWYgKGlzVW5kZWYoaWR4SW5PbGQpKSB7IC8vIE5ldyBlbGVtZW50XG4gICAgICAgICAgYXBpLmluc2VydEJlZm9yZShwYXJlbnRFbG0sIGNyZWF0ZUVsbShuZXdTdGFydFZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpLCBvbGRTdGFydFZub2RlLmVsbSk7XG4gICAgICAgICAgbmV3U3RhcnRWbm9kZSA9IG5ld0NoWysrbmV3U3RhcnRJZHhdO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGVsbVRvTW92ZSA9IG9sZENoW2lkeEluT2xkXTtcbiAgICAgICAgICBwYXRjaFZub2RlKGVsbVRvTW92ZSwgbmV3U3RhcnRWbm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTtcbiAgICAgICAgICBvbGRDaFtpZHhJbk9sZF0gPSB1bmRlZmluZWQ7XG4gICAgICAgICAgYXBpLmluc2VydEJlZm9yZShwYXJlbnRFbG0sIGVsbVRvTW92ZS5lbG0sIG9sZFN0YXJ0Vm5vZGUuZWxtKTtcbiAgICAgICAgICBuZXdTdGFydFZub2RlID0gbmV3Q2hbKytuZXdTdGFydElkeF07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKG9sZFN0YXJ0SWR4ID4gb2xkRW5kSWR4KSB7XG4gICAgICBiZWZvcmUgPSBpc1VuZGVmKG5ld0NoW25ld0VuZElkeCsxXSkgPyBudWxsIDogbmV3Q2hbbmV3RW5kSWR4KzFdLmVsbTtcbiAgICAgIGFkZFZub2RlcyhwYXJlbnRFbG0sIGJlZm9yZSwgbmV3Q2gsIG5ld1N0YXJ0SWR4LCBuZXdFbmRJZHgsIGluc2VydGVkVm5vZGVRdWV1ZSk7XG4gICAgfSBlbHNlIGlmIChuZXdTdGFydElkeCA+IG5ld0VuZElkeCkge1xuICAgICAgcmVtb3ZlVm5vZGVzKHBhcmVudEVsbSwgb2xkQ2gsIG9sZFN0YXJ0SWR4LCBvbGRFbmRJZHgpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHBhdGNoVm5vZGUob2xkVm5vZGUsIHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpIHtcbiAgICB2YXIgaSwgaG9vaztcbiAgICBpZiAoaXNEZWYoaSA9IHZub2RlLmRhdGEpICYmIGlzRGVmKGhvb2sgPSBpLmhvb2spICYmIGlzRGVmKGkgPSBob29rLnByZXBhdGNoKSkge1xuICAgICAgaShvbGRWbm9kZSwgdm5vZGUpO1xuICAgIH1cbiAgICBpZiAoaXNEZWYoaSA9IG9sZFZub2RlLmRhdGEpICYmIGlzRGVmKGkgPSBpLnZub2RlKSkgb2xkVm5vZGUgPSBpO1xuICAgIGlmIChpc0RlZihpID0gdm5vZGUuZGF0YSkgJiYgaXNEZWYoaSA9IGkudm5vZGUpKSB7XG4gICAgICBwYXRjaFZub2RlKG9sZFZub2RlLCBpLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgdm5vZGUuZWxtID0gaS5lbG07XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciBlbG0gPSB2bm9kZS5lbG0gPSBvbGRWbm9kZS5lbG0sIG9sZENoID0gb2xkVm5vZGUuY2hpbGRyZW4sIGNoID0gdm5vZGUuY2hpbGRyZW47XG4gICAgaWYgKG9sZFZub2RlID09PSB2bm9kZSkgcmV0dXJuO1xuICAgIGlmICghc2FtZVZub2RlKG9sZFZub2RlLCB2bm9kZSkpIHtcbiAgICAgIHZhciBwYXJlbnRFbG0gPSBhcGkucGFyZW50Tm9kZShvbGRWbm9kZS5lbG0pO1xuICAgICAgZWxtID0gY3JlYXRlRWxtKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgYXBpLmluc2VydEJlZm9yZShwYXJlbnRFbG0sIGVsbSwgb2xkVm5vZGUuZWxtKTtcbiAgICAgIHJlbW92ZVZub2RlcyhwYXJlbnRFbG0sIFtvbGRWbm9kZV0sIDAsIDApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaXNEZWYodm5vZGUuZGF0YSkpIHtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBjYnMudXBkYXRlLmxlbmd0aDsgKytpKSBjYnMudXBkYXRlW2ldKG9sZFZub2RlLCB2bm9kZSk7XG4gICAgICBpID0gdm5vZGUuZGF0YS5ob29rO1xuICAgICAgaWYgKGlzRGVmKGkpICYmIGlzRGVmKGkgPSBpLnVwZGF0ZSkpIGkob2xkVm5vZGUsIHZub2RlKTtcbiAgICB9XG4gICAgaWYgKGlzVW5kZWYodm5vZGUudGV4dCkpIHtcbiAgICAgIGlmIChpc0RlZihvbGRDaCkgJiYgaXNEZWYoY2gpKSB7XG4gICAgICAgIGlmIChvbGRDaCAhPT0gY2gpIHVwZGF0ZUNoaWxkcmVuKGVsbSwgb2xkQ2gsIGNoLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgfSBlbHNlIGlmIChpc0RlZihjaCkpIHtcbiAgICAgICAgaWYgKGlzRGVmKG9sZFZub2RlLnRleHQpKSBhcGkuc2V0VGV4dENvbnRlbnQoZWxtLCAnJyk7XG4gICAgICAgIGFkZFZub2RlcyhlbG0sIG51bGwsIGNoLCAwLCBjaC5sZW5ndGggLSAxLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuICAgICAgfSBlbHNlIGlmIChpc0RlZihvbGRDaCkpIHtcbiAgICAgICAgcmVtb3ZlVm5vZGVzKGVsbSwgb2xkQ2gsIDAsIG9sZENoLmxlbmd0aCAtIDEpO1xuICAgICAgfSBlbHNlIGlmIChpc0RlZihvbGRWbm9kZS50ZXh0KSkge1xuICAgICAgICBhcGkuc2V0VGV4dENvbnRlbnQoZWxtLCAnJyk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChvbGRWbm9kZS50ZXh0ICE9PSB2bm9kZS50ZXh0KSB7XG4gICAgICBhcGkuc2V0VGV4dENvbnRlbnQoZWxtLCB2bm9kZS50ZXh0KTtcbiAgICB9XG4gICAgaWYgKGlzRGVmKGhvb2spICYmIGlzRGVmKGkgPSBob29rLnBvc3RwYXRjaCkpIHtcbiAgICAgIGkob2xkVm5vZGUsIHZub2RlKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24ob2xkVm5vZGUsIHZub2RlKSB7XG4gICAgdmFyIGksIGVsbSwgcGFyZW50O1xuICAgIHZhciBpbnNlcnRlZFZub2RlUXVldWUgPSBbXTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgY2JzLnByZS5sZW5ndGg7ICsraSkgY2JzLnByZVtpXSgpO1xuXG4gICAgaWYgKGlzVW5kZWYob2xkVm5vZGUuc2VsKSkge1xuICAgICAgb2xkVm5vZGUgPSBlbXB0eU5vZGVBdChvbGRWbm9kZSk7XG4gICAgfVxuXG4gICAgaWYgKHNhbWVWbm9kZShvbGRWbm9kZSwgdm5vZGUpKSB7XG4gICAgICBwYXRjaFZub2RlKG9sZFZub2RlLCB2bm9kZSwgaW5zZXJ0ZWRWbm9kZVF1ZXVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZWxtID0gb2xkVm5vZGUuZWxtO1xuICAgICAgcGFyZW50ID0gYXBpLnBhcmVudE5vZGUoZWxtKTtcblxuICAgICAgY3JlYXRlRWxtKHZub2RlLCBpbnNlcnRlZFZub2RlUXVldWUpO1xuXG4gICAgICBpZiAocGFyZW50ICE9PSBudWxsKSB7XG4gICAgICAgIGFwaS5pbnNlcnRCZWZvcmUocGFyZW50LCB2bm9kZS5lbG0sIGFwaS5uZXh0U2libGluZyhlbG0pKTtcbiAgICAgICAgcmVtb3ZlVm5vZGVzKHBhcmVudCwgW29sZFZub2RlXSwgMCwgMCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChpID0gMDsgaSA8IGluc2VydGVkVm5vZGVRdWV1ZS5sZW5ndGg7ICsraSkge1xuICAgICAgaW5zZXJ0ZWRWbm9kZVF1ZXVlW2ldLmRhdGEuaG9vay5pbnNlcnQoaW5zZXJ0ZWRWbm9kZVF1ZXVlW2ldKTtcbiAgICB9XG4gICAgZm9yIChpID0gMDsgaSA8IGNicy5wb3N0Lmxlbmd0aDsgKytpKSBjYnMucG9zdFtpXSgpO1xuICAgIHJldHVybiB2bm9kZTtcbiAgfTtcbn1cblxubW9kdWxlLmV4cG9ydHMgPSB7aW5pdDogaW5pdH07XG4iLCJ2YXIgaCA9IHJlcXVpcmUoJy4vaCcpO1xuXG5mdW5jdGlvbiBpbml0KHRodW5rKSB7XG4gIHZhciBpLCBjdXIgPSB0aHVuay5kYXRhO1xuICBjdXIudm5vZGUgPSBjdXIuZm4uYXBwbHkodW5kZWZpbmVkLCBjdXIuYXJncyk7XG59XG5cbmZ1bmN0aW9uIHByZXBhdGNoKG9sZFRodW5rLCB0aHVuaykge1xuICB2YXIgaSwgb2xkID0gb2xkVGh1bmsuZGF0YSwgY3VyID0gdGh1bmsuZGF0YTtcbiAgdmFyIG9sZEFyZ3MgPSBvbGQuYXJncywgYXJncyA9IGN1ci5hcmdzO1xuICBjdXIudm5vZGUgPSBvbGQudm5vZGU7XG4gIGlmIChvbGQuZm4gIT09IGN1ci5mbiB8fCBvbGRBcmdzLmxlbmd0aCAhPT0gYXJncy5sZW5ndGgpIHtcbiAgICBjdXIudm5vZGUgPSBjdXIuZm4uYXBwbHkodW5kZWZpbmVkLCBhcmdzKTtcbiAgICByZXR1cm47XG4gIH1cbiAgZm9yIChpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAob2xkQXJnc1tpXSAhPT0gYXJnc1tpXSkge1xuICAgICAgY3VyLnZub2RlID0gY3VyLmZuLmFwcGx5KHVuZGVmaW5lZCwgYXJncyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG59XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24obmFtZSwgZm4gLyogYXJncyAqLykge1xuICB2YXIgaSwgYXJncyA9IFtdO1xuICBmb3IgKGkgPSAyOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgKytpKSB7XG4gICAgYXJnc1tpIC0gMl0gPSBhcmd1bWVudHNbaV07XG4gIH1cbiAgcmV0dXJuIGgoJ3RodW5rJyArIG5hbWUsIHtcbiAgICBob29rOiB7aW5pdDogaW5pdCwgcHJlcGF0Y2g6IHByZXBhdGNofSxcbiAgICBmbjogZm4sIGFyZ3M6IGFyZ3MsXG4gIH0pO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24oc2VsLCBkYXRhLCBjaGlsZHJlbiwgdGV4dCwgZWxtKSB7XG4gIHZhciBrZXkgPSBkYXRhID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBkYXRhLmtleTtcbiAgcmV0dXJuIHtzZWw6IHNlbCwgZGF0YTogZGF0YSwgY2hpbGRyZW46IGNoaWxkcmVuLFxuICAgICAgICAgIHRleHQ6IHRleHQsIGVsbTogZWxtLCBrZXk6IGtleX07XG59O1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgY2xpY2tFdmVudCA9ICd1bmRlZmluZWQnICE9PSB0eXBlb2YgZG9jdW1lbnQgJiYgZG9jdW1lbnQub250b3VjaHN0YXJ0ID9cbiAgICAndG91Y2hzdGFydCcgOiAnY2xpY2snO1xuZnVuY3Rpb24gd2hpY2goZXYpIHtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB2YXIgZSA9IGV2IHx8IHdpbmRvdy5ldmVudDtcbiAgICByZXR1cm4gZS53aGljaCA9PT0gbnVsbCA/IGUuYnV0dG9uIDogZS53aGljaDtcbn1cbmZ1bmN0aW9uIHNhbWVPcmlnaW4oaHJlZikge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ID09PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiBocmVmICYmIGhyZWYuaW5kZXhPZih3aW5kb3cubG9jYXRpb24ub3JpZ2luKSA9PT0gMDtcbn1cbmZ1bmN0aW9uIG1ha2VDbGlja0xpc3RlbmVyKHB1c2gpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gY2xpY2tMaXN0ZW5lcihldmVudCkge1xuICAgICAgICBpZiAod2hpY2goZXZlbnQpICE9PSAxKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGV2ZW50Lm1ldGFLZXkgfHwgZXZlbnQuY3RybEtleSB8fCBldmVudC5zaGlmdEtleSkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmIChldmVudC5kZWZhdWx0UHJldmVudGVkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgdmFyIGVsZW1lbnQgPSBldmVudC50YXJnZXQ7XG4gICAgICAgIHdoaWxlIChlbGVtZW50ICYmIGVsZW1lbnQubm9kZU5hbWUgIT09ICdBJykge1xuICAgICAgICAgICAgZWxlbWVudCA9IGVsZW1lbnQucGFyZW50Tm9kZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIWVsZW1lbnQgfHwgZWxlbWVudC5ub2RlTmFtZSAhPT0gJ0EnKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGVsZW1lbnQuaGFzQXR0cmlidXRlKCdkb3dubG9hZCcpIHx8XG4gICAgICAgICAgICBlbGVtZW50LmdldEF0dHJpYnV0ZSgncmVsJykgPT09ICdleHRlcm5hbCcpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAoZWxlbWVudC50YXJnZXQpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgbGluayA9IGVsZW1lbnQuZ2V0QXR0cmlidXRlKCdocmVmJyk7XG4gICAgICAgIGlmIChsaW5rICYmIGxpbmsuaW5kZXhPZignbWFpbHRvOicpID4gLTEgfHwgbGluayA9PT0gJyMnKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFzYW1lT3JpZ2luKGVsZW1lbnQuaHJlZikpIHtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB2YXIgcGF0aG5hbWUgPSBlbGVtZW50LnBhdGhuYW1lLCBzZWFyY2ggPSBlbGVtZW50LnNlYXJjaCwgX2EgPSBlbGVtZW50Lmhhc2gsIGhhc2ggPSBfYSA9PT0gdm9pZCAwID8gJycgOiBfYTtcbiAgICAgICAgcHVzaChwYXRobmFtZSArIHNlYXJjaCArIGhhc2gpO1xuICAgIH07XG59XG5mdW5jdGlvbiBjYXB0dXJlQ2xpY2tzKHB1c2gpIHtcbiAgICB2YXIgbGlzdGVuZXIgPSBtYWtlQ2xpY2tMaXN0ZW5lcihwdXNoKTtcbiAgICBpZiAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihjbGlja0V2ZW50LCBsaXN0ZW5lciwgZmFsc2UpO1xuICAgIH1cbn1cbmV4cG9ydHMuY2FwdHVyZUNsaWNrcyA9IGNhcHR1cmVDbGlja3M7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jYXB0dXJlQ2xpY2tzLmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xudmFyIG1ha2VIaXN0b3J5RHJpdmVyXzEgPSByZXF1aXJlKCcuL21ha2VIaXN0b3J5RHJpdmVyJyk7XG5leHBvcnRzLm1ha2VIaXN0b3J5RHJpdmVyID0gbWFrZUhpc3RvcnlEcml2ZXJfMS5tYWtlSGlzdG9yeURyaXZlcjtcbnZhciBzZXJ2ZXJIaXN0b3J5XzEgPSByZXF1aXJlKCcuL3NlcnZlckhpc3RvcnknKTtcbmV4cG9ydHMuY3JlYXRlU2VydmVySGlzdG9yeSA9IHNlcnZlckhpc3RvcnlfMS5jcmVhdGVTZXJ2ZXJIaXN0b3J5O1xudmFyIHV0aWxfMSA9IHJlcXVpcmUoJy4vdXRpbCcpO1xuZXhwb3J0cy5zdXBwb3J0c0hpc3RvcnkgPSB1dGlsXzEuc3VwcG9ydHNIaXN0b3J5O1xuZXhwb3J0cy5jcmVhdGVMb2NhdGlvbiA9IHV0aWxfMS5jcmVhdGVMb2NhdGlvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsIlwidXNlIHN0cmljdFwiO1xudmFyIGNhcHR1cmVDbGlja3NfMSA9IHJlcXVpcmUoJy4vY2FwdHVyZUNsaWNrcycpO1xuZnVuY3Rpb24gbWFrZVVwZGF0ZUhpc3RvcnkoaGlzdG9yeSkge1xuICAgIHJldHVybiBmdW5jdGlvbiB1cGRhdGVIaXN0b3J5KGxvY2F0aW9uKSB7XG4gICAgICAgIGlmICgnc3RyaW5nJyA9PT0gdHlwZW9mIGxvY2F0aW9uKSB7XG4gICAgICAgICAgICBoaXN0b3J5LnB1c2goaGlzdG9yeS5jcmVhdGVMb2NhdGlvbihsb2NhdGlvbikpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKCdvYmplY3QnID09PSB0eXBlb2YgbG9jYXRpb24pIHtcbiAgICAgICAgICAgIC8vIHN1cG9ydCB0aGluZ3MgbGlrZSBoaXN0b3J5LnJlcGxhY2UoKVxuICAgICAgICAgICAgdmFyIF9hID0gbG9jYXRpb24udHlwZSwgdHlwZSA9IF9hID09PSB2b2lkIDAgPyAncHVzaCcgOiBfYTtcbiAgICAgICAgICAgIGlmICh0eXBlID09PSAnZ28nKSB7XG4gICAgICAgICAgICAgICAgaGlzdG9yeVt0eXBlXShsb2NhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBoaXN0b3J5W3R5cGVdKGxvY2F0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSGlzdG9yeSBEcml2ZXIgaW5wdXQgbXVzdCBiZSBhIHN0cmluZyBvciBhbiAnICtcbiAgICAgICAgICAgICAgICAnb2JqZWN0IGJ1dCByZWNlaXZlZCAke3R5cGVvZiB1cmx9Jyk7XG4gICAgICAgIH1cbiAgICB9O1xufVxuZnVuY3Rpb24gZGVmYXVsdE9uRXJyb3JGbihlcnIpIHtcbiAgICBpZiAoY29uc29sZSAmJiBjb25zb2xlLmVycm9yICE9PSB2b2lkIDApIHtcbiAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIG1ha2VIaXN0b3J5RHJpdmVyKGhpc3RvcnksIG9wdGlvbnMpIHtcbiAgICBpZiAoIWhpc3RvcnkgfHwgdHlwZW9mIGhpc3RvcnkgIT09ICdvYmplY3QnXG4gICAgICAgIHx8IHR5cGVvZiBoaXN0b3J5LmNyZWF0ZUxvY2F0aW9uICE9PSAnZnVuY3Rpb24nXG4gICAgICAgIHx8IHR5cGVvZiBoaXN0b3J5LmNyZWF0ZUhyZWYgIT09ICdmdW5jdGlvbidcbiAgICAgICAgfHwgdHlwZW9mIGhpc3RvcnkubGlzdGVuICE9PSAnZnVuY3Rpb24nXG4gICAgICAgIHx8IHR5cGVvZiBoaXN0b3J5LnB1c2ggIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcignbWFrZUhpc3RvcnlEcml2ZXIgcmVxdWlyZXMgYW4gdmFsaWQgaGlzdG9yeSBvYmplY3QgJyArXG4gICAgICAgICAgICAnY29udGFpbmluZyBjcmVhdGVMb2NhdGlvbigpLCBjcmVhdGVIcmVmKCksIHB1c2goKSwgYW5kIGxpc3RlbigpIG1ldGhvZHMnKTtcbiAgICB9XG4gICAgdmFyIGNhcHR1cmUgPSBvcHRpb25zICYmIG9wdGlvbnMuY2FwdHVyZSB8fCBmYWxzZTtcbiAgICB2YXIgb25FcnJvciA9IG9wdGlvbnMgJiYgb3B0aW9ucy5vbkVycm9yIHx8IGRlZmF1bHRPbkVycm9yRm47XG4gICAgcmV0dXJuIGZ1bmN0aW9uIGhpc3RvcnlEcml2ZXIoc2luayQsIHJ1blNBKSB7XG4gICAgICAgIHZhciBfYSA9IHJ1blNBLm1ha2VTdWJqZWN0KCksIG9ic2VydmVyID0gX2Eub2JzZXJ2ZXIsIHN0cmVhbSA9IF9hLnN0cmVhbTtcbiAgICAgICAgdmFyIGhpc3RvcnkkID0gcnVuU0EucmVtZW1iZXIoc3RyZWFtXG4gICAgICAgICAgICAuc3RhcnRXaXRoKGhpc3RvcnkuZ2V0Q3VycmVudExvY2F0aW9uKCkpXG4gICAgICAgICAgICAuZmlsdGVyKEJvb2xlYW4pKTtcbiAgICAgICAgdmFyIHVubGlzdGVuID0gaGlzdG9yeS5saXN0ZW4oZnVuY3Rpb24gKGxvY2F0aW9uKSB7XG4gICAgICAgICAgICBvYnNlcnZlci5uZXh0KGxvY2F0aW9uKTtcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICh0eXBlb2YgaGlzdG9yeS5hZGRDb21wbGV0ZUNhbGxiYWNrID09PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAmJiB0eXBlb2YgaGlzdG9yeS5jb21wbGV0ZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgaGlzdG9yeS5hZGRDb21wbGV0ZUNhbGxiYWNrKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZSgpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgcnVuU0Euc3RyZWFtU3Vic2NyaWJlKHNpbmskLCB7XG4gICAgICAgICAgICBuZXh0OiBtYWtlVXBkYXRlSGlzdG9yeShoaXN0b3J5KSxcbiAgICAgICAgICAgIGVycm9yOiBvbkVycm9yLFxuICAgICAgICAgICAgY29tcGxldGU6IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB1bmxpc3RlbigpO1xuICAgICAgICAgICAgICAgIG9ic2VydmVyLmNvbXBsZXRlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBpZiAoY2FwdHVyZSkge1xuICAgICAgICAgICAgY2FwdHVyZUNsaWNrc18xLmNhcHR1cmVDbGlja3MoZnVuY3Rpb24gKHBhdGhuYW1lKSB7XG4gICAgICAgICAgICAgICAgdmFyIGxvY2F0aW9uID0gaGlzdG9yeS5jcmVhdGVMb2NhdGlvbihwYXRobmFtZSk7XG4gICAgICAgICAgICAgICAgaGlzdG9yeS5wdXNoKGxvY2F0aW9uKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIGhpc3RvcnkkLmNyZWF0ZUhyZWYgPSBmdW5jdGlvbiAoaHJlZikgeyByZXR1cm4gaGlzdG9yeS5jcmVhdGVIcmVmKGhyZWYpOyB9O1xuICAgICAgICBoaXN0b3J5JC5jcmVhdGVMb2NhdGlvbiA9IGZ1bmN0aW9uIChsb2NhdGlvbikgeyByZXR1cm4gaGlzdG9yeS5jcmVhdGVMb2NhdGlvbihsb2NhdGlvbik7IH07XG4gICAgICAgIHJldHVybiBoaXN0b3J5JDtcbiAgICB9O1xufVxuZXhwb3J0cy5tYWtlSGlzdG9yeURyaXZlciA9IG1ha2VIaXN0b3J5RHJpdmVyO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9bWFrZUhpc3RvcnlEcml2ZXIuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgdXRpbF8xID0gcmVxdWlyZSgnLi91dGlsJyk7XG52YXIgU2VydmVySGlzdG9yeSA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gU2VydmVySGlzdG9yeShjdXJyZW50TG9jYXRpb24pIHtcbiAgICAgICAgdGhpcy5jdXJyZW50TG9jYXRpb24gPSBjdXJyZW50TG9jYXRpb247XG4gICAgICAgIHRoaXMubGlzdGVuZXJzID0gW107XG4gICAgfVxuICAgIFNlcnZlckhpc3RvcnkucHJvdG90eXBlLmxpc3RlbiA9IGZ1bmN0aW9uIChsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLmxpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIG5vb3AoKSB7IHJldHVybiB2b2lkIDA7IH07XG4gICAgfTtcbiAgICBTZXJ2ZXJIaXN0b3J5LnByb3RvdHlwZS5wdXNoID0gZnVuY3Rpb24gKGxvY2F0aW9uKSB7XG4gICAgICAgIHZhciBsZW5ndGggPSB0aGlzLmxpc3RlbmVycy5sZW5ndGg7XG4gICAgICAgIGlmIChsZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTXVzdCBiZSBnaXZlbiBhdCBsZWFzdCBvbmUgbGlzdGVuZXIgYmVmb3JlIHB1c2hpbmcnKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICB0aGlzLmxpc3RlbmVyc1tpXSh1dGlsXzEuY3JlYXRlTG9jYXRpb24obG9jYXRpb24pKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgU2VydmVySGlzdG9yeS5wcm90b3R5cGUucmVwbGFjZSA9IGZ1bmN0aW9uIChsb2NhdGlvbikge1xuICAgICAgICB0aGlzLnB1c2gobG9jYXRpb24pO1xuICAgIH07XG4gICAgU2VydmVySGlzdG9yeS5wcm90b3R5cGUuY3JlYXRlSHJlZiA9IGZ1bmN0aW9uIChwYXRoKSB7XG4gICAgICAgIHJldHVybiBwYXRoO1xuICAgIH07XG4gICAgU2VydmVySGlzdG9yeS5wcm90b3R5cGUuY3JlYXRlTG9jYXRpb24gPSBmdW5jdGlvbiAobG9jYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIHV0aWxfMS5jcmVhdGVMb2NhdGlvbihsb2NhdGlvbik7XG4gICAgfTtcbiAgICBTZXJ2ZXJIaXN0b3J5LnByb3RvdHlwZS5nZXRDdXJyZW50TG9jYXRpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmN1cnJlbnRMb2NhdGlvbjtcbiAgICB9O1xuICAgIFNlcnZlckhpc3RvcnkucHJvdG90eXBlLmFkZENvbXBsZXRlQ2FsbGJhY2sgPSBmdW5jdGlvbiAoY29tcGxldGUpIHtcbiAgICAgICAgdGhpcy5fY29tcGxldGVDYWxsYmFjayA9IGNvbXBsZXRlO1xuICAgIH07XG4gICAgU2VydmVySGlzdG9yeS5wcm90b3R5cGUuY29tcGxldGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX2NvbXBsZXRlQ2FsbGJhY2soKTtcbiAgICB9O1xuICAgIHJldHVybiBTZXJ2ZXJIaXN0b3J5O1xufSgpKTtcbmZ1bmN0aW9uIGNyZWF0ZVNlcnZlckhpc3RvcnkobG9jKSB7XG4gICAgcmV0dXJuIG5ldyBTZXJ2ZXJIaXN0b3J5KGxvYyA/IHV0aWxfMS5jcmVhdGVMb2NhdGlvbihsb2MpIDogbnVsbCk7XG59XG5leHBvcnRzLmNyZWF0ZVNlcnZlckhpc3RvcnkgPSBjcmVhdGVTZXJ2ZXJIaXN0b3J5O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9c2VydmVySGlzdG9yeS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbmZ1bmN0aW9uIHN1cHBvcnRzSGlzdG9yeSgpIHtcbiAgICBpZiAodHlwZW9mIG5hdmlnYXRvciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICB2YXIgdWEgPSBuYXZpZ2F0b3IudXNlckFnZW50O1xuICAgIGlmICgodWEuaW5kZXhPZignQW5kcm9pZCAyLicpICE9PSAtMSB8fFxuICAgICAgICB1YS5pbmRleE9mKCdBbmRyb2lkIDQuMCcpICE9PSAtMSkgJiZcbiAgICAgICAgdWEuaW5kZXhPZignTW9iaWxlIFNhZmFyaScpICE9PSAtMSAmJlxuICAgICAgICB1YS5pbmRleE9mKCdDaHJvbWUnKSA9PT0gLTEgJiZcbiAgICAgICAgdWEuaW5kZXhPZignV2luZG93cyBQaG9uZScpID09PSAtMSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICByZXR1cm4gd2luZG93Lmhpc3RvcnkgJiYgJ3B1c2hTdGF0ZScgaW4gd2luZG93Lmhpc3Rvcnk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxufVxuZXhwb3J0cy5zdXBwb3J0c0hpc3RvcnkgPSBzdXBwb3J0c0hpc3Rvcnk7XG52YXIgbG9jYXRpb25EZWZhdWx0cyA9IHtcbiAgICBwYXRobmFtZTogJy8nLFxuICAgIGFjdGlvbjogJ1BPUCcsXG4gICAgaGFzaDogJycsXG4gICAgc2VhcmNoOiAnJyxcbiAgICBzdGF0ZTogdW5kZWZpbmVkLFxuICAgIGtleTogbnVsbCxcbiAgICBxdWVyeTogbnVsbCxcbn07XG5mdW5jdGlvbiBjcmVhdGVMb2NhdGlvbihsb2NhdGlvbikge1xuICAgIGlmICh0eXBlb2YgbG9jYXRpb24gPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKHt9LCBsb2NhdGlvbkRlZmF1bHRzLCB7IHBhdGhuYW1lOiBsb2NhdGlvbiB9KTtcbiAgICB9XG4gICAgcmV0dXJuIE9iamVjdC5hc3NpZ24oe30sIGxvY2F0aW9uRGVmYXVsdHMsIGxvY2F0aW9uKTtcbn1cbmV4cG9ydHMuY3JlYXRlTG9jYXRpb24gPSBjcmVhdGVMb2NhdGlvbjtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPXV0aWwuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgY291bnRlciA9IDA7XG5mdW5jdGlvbiBuZXdTY29wZSgpIHtcbiAgICByZXR1cm4gXCJjeWNsZVwiICsgKytjb3VudGVyO1xufVxuZnVuY3Rpb24gY2hlY2tJc29sYXRlQXJncyhkYXRhZmxvd0NvbXBvbmVudCwgc2NvcGUpIHtcbiAgICBpZiAodHlwZW9mIGRhdGFmbG93Q29tcG9uZW50ICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRmlyc3QgYXJndW1lbnQgZ2l2ZW4gdG8gaXNvbGF0ZSgpIG11c3QgYmUgYSBcIiArXG4gICAgICAgICAgICBcIidkYXRhZmxvd0NvbXBvbmVudCcgZnVuY3Rpb25cIik7XG4gICAgfVxuICAgIGlmIChzY29wZSA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTZWNvbmQgYXJndW1lbnQgZ2l2ZW4gdG8gaXNvbGF0ZSgpIG11c3Qgbm90IGJlIG51bGxcIik7XG4gICAgfVxufVxuZnVuY3Rpb24gaXNvbGF0ZUFsbFNvdXJjZXMoc291cmNlcywgc2NvcGUpIHtcbiAgICB2YXIgc2NvcGVkU291cmNlcyA9IHt9O1xuICAgIGZvciAodmFyIGtleSBpbiBzb3VyY2VzKSB7XG4gICAgICAgIGlmIChzb3VyY2VzLmhhc093blByb3BlcnR5KGtleSkgJiYgc291cmNlc1trZXldXG4gICAgICAgICAgICAmJiB0eXBlb2Ygc291cmNlc1trZXldLmlzb2xhdGVTb3VyY2UgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgc2NvcGVkU291cmNlc1trZXldID0gc291cmNlc1trZXldLmlzb2xhdGVTb3VyY2Uoc291cmNlc1trZXldLCBzY29wZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc291cmNlcy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICAgICAgICBzY29wZWRTb3VyY2VzW2tleV0gPSBzb3VyY2VzW2tleV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNjb3BlZFNvdXJjZXM7XG59XG5mdW5jdGlvbiBpc29sYXRlQWxsU2lua3Moc291cmNlcywgc2lua3MsIHNjb3BlKSB7XG4gICAgdmFyIHNjb3BlZFNpbmtzID0ge307XG4gICAgZm9yICh2YXIga2V5IGluIHNpbmtzKSB7XG4gICAgICAgIGlmIChzaW5rcy5oYXNPd25Qcm9wZXJ0eShrZXkpXG4gICAgICAgICAgICAmJiBzb3VyY2VzW2tleV1cbiAgICAgICAgICAgICYmIHR5cGVvZiBzb3VyY2VzW2tleV0uaXNvbGF0ZVNpbmsgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgc2NvcGVkU2lua3Nba2V5XSA9IHNvdXJjZXNba2V5XS5pc29sYXRlU2luayhzaW5rc1trZXldLCBzY29wZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAoc2lua3MuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICAgICAgc2NvcGVkU2lua3Nba2V5XSA9IHNpbmtzW2tleV07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNjb3BlZFNpbmtzO1xufVxuLyoqXG4gKiBUYWtlcyBhIGBkYXRhZmxvd0NvbXBvbmVudGAgZnVuY3Rpb24gYW5kIGFuIG9wdGlvbmFsIGBzY29wZWAgc3RyaW5nLCBhbmRcbiAqIHJldHVybnMgYSBzY29wZWQgdmVyc2lvbiBvZiB0aGUgYGRhdGFmbG93Q29tcG9uZW50YCBmdW5jdGlvbi5cbiAqXG4gKiBXaGVuIHRoZSBzY29wZWQgZGF0YWZsb3cgY29tcG9uZW50IGlzIGludm9rZWQsIGVhY2ggc291cmNlIHByb3ZpZGVkIHRvIHRoZVxuICogc2NvcGVkIGRhdGFmbG93Q29tcG9uZW50IGlzIGlzb2xhdGVkIHRvIHRoZSBzY29wZSB1c2luZ1xuICogYHNvdXJjZS5pc29sYXRlU291cmNlKHNvdXJjZSwgc2NvcGUpYCwgaWYgcG9zc2libGUuIExpa2V3aXNlLCB0aGUgc2lua3NcbiAqIHJldHVybmVkIGZyb20gdGhlIHNjb3BlZCBkYXRhZmxvdyBjb21wb25lbnQgYXJlIGlzb2xhdGUgdG8gdGhlIHNjb3BlIHVzaW5nXG4gKiBgc291cmNlLmlzb2xhdGVTaW5rKHNpbmssIHNjb3BlKWAuXG4gKlxuICogSWYgdGhlIGBzY29wZWAgaXMgbm90IHByb3ZpZGVkLCBhIG5ldyBzY29wZSB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgY3JlYXRlZC5cbiAqIFRoaXMgbWVhbnMgdGhhdCB3aGlsZSAqKmBpc29sYXRlKGRhdGFmbG93Q29tcG9uZW50LCBzY29wZSlgIGlzIHB1cmUqKlxuICogKHJlZmVyZW50aWFsbHkgdHJhbnNwYXJlbnQpLCAqKmBpc29sYXRlKGRhdGFmbG93Q29tcG9uZW50KWAgaXMgaW1wdXJlKipcbiAqIChub3QgcmVmZXJlbnRpYWxseSB0cmFuc3BhcmVudCkuIFR3byBjYWxscyB0byBgaXNvbGF0ZShGb28sIGJhcilgIHdpbGxcbiAqIGdlbmVyYXRlIHR3byBpbmRpc3RpbmN0IGRhdGFmbG93IGNvbXBvbmVudHMuIEJ1dCwgdHdvIGNhbGxzIHRvIGBpc29sYXRlKEZvbylgXG4gKiB3aWxsIGdlbmVyYXRlIHR3byBkaXN0aW5jdCBkYXRhZmxvdyBjb21wb25lbnRzLlxuICpcbiAqIE5vdGUgdGhhdCBib3RoIGBpc29sYXRlU291cmNlKClgIGFuZCBgaXNvbGF0ZVNpbmsoKWAgYXJlIHN0YXRpYyBtZW1iZXJzIG9mXG4gKiBgc291cmNlYC4gVGhlIHJlYXNvbiBmb3IgdGhpcyBpcyB0aGF0IGRyaXZlcnMgcHJvZHVjZSBgc291cmNlYCB3aGlsZSB0aGVcbiAqIGFwcGxpY2F0aW9uIHByb2R1Y2VzIGBzaW5rYCwgYW5kIGl0J3MgdGhlIGRyaXZlcidzIHJlc3BvbnNpYmlsaXR5IHRvXG4gKiBpbXBsZW1lbnQgYGlzb2xhdGVTb3VyY2UoKWAgYW5kIGBpc29sYXRlU2luaygpYC5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBkYXRhZmxvd0NvbXBvbmVudCBhIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYHNvdXJjZXNgIGFzIGlucHV0XG4gKiBhbmQgb3V0cHV0cyBhIGNvbGxlY3Rpb24gb2YgYHNpbmtzYC5cbiAqIEBwYXJhbSB7U3RyaW5nfSBzY29wZSBhbiBvcHRpb25hbCBzdHJpbmcgdGhhdCBpcyB1c2VkIHRvIGlzb2xhdGUgZWFjaFxuICogYHNvdXJjZXNgIGFuZCBgc2lua3NgIHdoZW4gdGhlIHJldHVybmVkIHNjb3BlZCBkYXRhZmxvdyBjb21wb25lbnQgaXMgaW52b2tlZC5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSB0aGUgc2NvcGVkIGRhdGFmbG93IGNvbXBvbmVudCBmdW5jdGlvbiB0aGF0LCBhcyB0aGVcbiAqIG9yaWdpbmFsIGBkYXRhZmxvd0NvbXBvbmVudGAgZnVuY3Rpb24sIHRha2VzIGBzb3VyY2VzYCBhbmQgcmV0dXJucyBgc2lua3NgLlxuICogQGZ1bmN0aW9uIGlzb2xhdGVcbiAqL1xuZnVuY3Rpb24gaXNvbGF0ZShjb21wb25lbnQsIHNjb3BlKSB7XG4gICAgaWYgKHNjb3BlID09PSB2b2lkIDApIHsgc2NvcGUgPSBuZXdTY29wZSgpOyB9XG4gICAgY2hlY2tJc29sYXRlQXJncyhjb21wb25lbnQsIHNjb3BlKTtcbiAgICB2YXIgY29udmVydGVkU2NvcGUgPSB0eXBlb2Ygc2NvcGUgPT09ICdzdHJpbmcnID8gc2NvcGUgOiBzY29wZS50b1N0cmluZygpO1xuICAgIHJldHVybiBmdW5jdGlvbiBzY29wZWRDb21wb25lbnQoc291cmNlcykge1xuICAgICAgICB2YXIgcmVzdCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDE7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgcmVzdFtfaSAtIDFdID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgc2NvcGVkU291cmNlcyA9IGlzb2xhdGVBbGxTb3VyY2VzKHNvdXJjZXMsIGNvbnZlcnRlZFNjb3BlKTtcbiAgICAgICAgdmFyIHNpbmtzID0gY29tcG9uZW50LmFwcGx5KHZvaWQgMCwgW3Njb3BlZFNvdXJjZXNdLmNvbmNhdChyZXN0KSk7XG4gICAgICAgIHZhciBzY29wZWRTaW5rcyA9IGlzb2xhdGVBbGxTaW5rcyhzb3VyY2VzLCBzaW5rcywgY29udmVydGVkU2NvcGUpO1xuICAgICAgICByZXR1cm4gc2NvcGVkU2lua3M7XG4gICAgfTtcbn1cbmlzb2xhdGUucmVzZXQgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBjb3VudGVyID0gMDsgfTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGlzb2xhdGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5cbnZhciBfeHN0cmVhbUFkYXB0ZXIgPSByZXF1aXJlKCdAY3ljbGUveHN0cmVhbS1hZGFwdGVyJyk7XG5cbnZhciBfeHN0cmVhbUFkYXB0ZXIyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfeHN0cmVhbUFkYXB0ZXIpO1xuXG52YXIgX3dyaXRlVG9TdG9yZSA9IHJlcXVpcmUoJy4vd3JpdGVUb1N0b3JlJyk7XG5cbnZhciBfd3JpdGVUb1N0b3JlMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3dyaXRlVG9TdG9yZSk7XG5cbnZhciBfcmVzcG9uc2VDb2xsZWN0aW9uID0gcmVxdWlyZSgnLi9yZXNwb25zZUNvbGxlY3Rpb24nKTtcblxudmFyIF9yZXNwb25zZUNvbGxlY3Rpb24yID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcmVzcG9uc2VDb2xsZWN0aW9uKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuLyoqXG4gKiBTdG9yYWdlIERyaXZlci5cbiAqXG4gKiBUaGlzIGlzIGEgbG9jYWxTdG9yYWdlIGFuZCBzZXNzaW9uU3RvcmFnZSBEcml2ZXIgZm9yIEN5Y2xlLmpzIGFwcHMuIFRoZVxuICogZHJpdmVyIGlzIGFsc28gYSBmdW5jdGlvbiwgYW5kIGl0IHRha2VzIGEgc3RyZWFtIG9mIHJlcXVlc3RzIGFzIGlucHV0LCBhbmRcbiAqIHJldHVybnMgYSAqKmByZXNwb25zZUNvbGxlY3Rpb25gKiogd2l0aCBmdW5jdGlvbnMgdGhhdCBhbGxvdyByZWFkaW5nIGZyb20gdGhlXG4gKiBzdG9yYWdlIG9iamVjdHMuIFRoZSBmdW5jdGlvbnMgb24gdGhlICoqYHJlc3BvbnNlQ29sbGVjdGlvbmAqKiByZXR1cm4gc3RyZWFtc1xuICogb2YgdGhlIHN0b3JhZ2UgZGF0YSB0aGF0IHdhcyByZXF1ZXN0ZWQuXG4gKlxuICogKipSZXF1ZXN0cyoqLiBUaGUgc3RyZWFtIG9mIHJlcXVlc3RzIHNob3VsZCBlbWl0IG9iamVjdHMuIFRoZXNlIHNob3VsZCBiZVxuICogaW5zdHJ1Y3Rpb25zIHRvIHdyaXRlIHRvIHRoZSBkZXNpcmVkIFN0b3JhZ2Ugb2JqZWN0LiBIZXJlIGFyZSB0aGUgYHJlcXVlc3RgXG4gKiBvYmplY3QgcHJvcGVydGllczpcbiAqXG4gKiAtIGB0YXJnZXRgICooU3RyaW5nKSo6IHR5cGUgb2Ygc3RvcmFnZSwgY2FuIGJlIGBsb2NhbGAgb3IgYHNlc3Npb25gLCBkZWZhdWx0c1xuICogdG8gYGxvY2FsYC5cbiAqIC0gYGFjdGlvbmAgKihTdHJpbmcpKjogdHlwZSBvZiBhY3Rpb24sIGNhbiBiZSBgc2V0SXRlbWAsIGByZW1vdmVJdGVtYCBvclxuICogYGNsZWFyYCwgZGVmYXVsdHMgdG8gYHNldEl0ZW1gLlxuICogLSBga2V5YCAqKFN0cmluZykqOiBzdG9yYWdlIGtleS5cbiAqIC0gYHZhbHVlYCAqKFN0cmluZykqOiBzdG9yYWdlIHZhbHVlLlxuICpcbiAqICoqcmVzcG9uc2VDb2xsZWN0aW9uKiouIFRoZSAqKmByZXNwb25zZUNvbGxlY3Rpb25gKiogaXMgYW4gT2JqZWN0IHRoYXRcbiAqIGV4cG9zZXMgZnVuY3Rpb25zIHRvIHJlYWQgZnJvbSBsb2NhbC0gYW5kIHNlc3Npb25TdG9yYWdlLlxuICpcbiAqIGBgYGpzXG4gKiAvLyBSZXR1cm5zIGtleSBvZiBudGggbG9jYWxTdG9yYWdlIHZhbHVlLlxuICogcmVzcG9uc2VDb2xsZWN0aW9uLmxvY2FsLmdldEtleShuKVxuICogLy8gUmV0dXJucyBsb2NhbFN0b3JhZ2UgdmFsdWUgb2YgYGtleWAuXG4gKiByZXNwb25zZUNvbGxlY3Rpb24ubG9jYWwuZ2V0SXRlbShrZXkpXG4gKiAvLyBSZXR1cm5zIGtleSBvZiBudGggc2Vzc2lvblN0b3JhZ2UgdmFsdWUuXG4gKiByZXNwb25zZUNvbGxlY3Rpb24uc2Vzc2lvbi5nZXRLZXkobilcbiAqIC8vIFJldHVybnMgc2Vzc2lvblN0b3JhZ2UgdmFsdWUgb2YgYGtleWAuXG4gKiByZXNwb25zZUNvbGxlY3Rpb24uc2Vzc2lvbi5nZXRJdGVtKGtleSlcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSByZXF1ZXN0JCAtIGEgc3RyZWFtIG9mIHdyaXRlIHJlcXVlc3Qgb2JqZWN0cy5cbiAqIEByZXR1cm4ge09iamVjdH0gdGhlIHJlc3BvbnNlIGNvbGxlY3Rpb24gY29udGFpbmluZyBmdW5jdGlvbnNcbiAqIGZvciByZWFkaW5nIGZyb20gc3RvcmFnZS5cbiAqIEBmdW5jdGlvbiBzdG9yYWdlRHJpdmVyXG4gKi9cbmZ1bmN0aW9uIHN0b3JhZ2VEcml2ZXIocmVxdWVzdCQsIHJ1blN0cmVhbUFkYXB0ZXIpIHtcbiAgLy8gRXhlY3V0ZSB3cml0aW5nIGFjdGlvbnMuXG4gIHJlcXVlc3QkLmFkZExpc3RlbmVyKHtcbiAgICBuZXh0OiBmdW5jdGlvbiBuZXh0KHJlcXVlc3QpIHtcbiAgICAgIHJldHVybiAoMCwgX3dyaXRlVG9TdG9yZTIuZGVmYXVsdCkocmVxdWVzdCk7XG4gICAgfSxcbiAgICBlcnJvcjogZnVuY3Rpb24gZXJyb3IoKSB7fSxcbiAgICBjb21wbGV0ZTogZnVuY3Rpb24gY29tcGxldGUoKSB7fVxuICB9KTtcblxuICAvLyBSZXR1cm4gcmVhZGluZyBmdW5jdGlvbnMuXG4gIHJldHVybiAoMCwgX3Jlc3BvbnNlQ29sbGVjdGlvbjIuZGVmYXVsdCkocmVxdWVzdCQsIHJ1blN0cmVhbUFkYXB0ZXIpO1xufVxuXG5zdG9yYWdlRHJpdmVyLnN0cmVhbUFkYXB0ZXIgPSBfeHN0cmVhbUFkYXB0ZXIyLmRlZmF1bHQ7XG5cbmV4cG9ydHMuZGVmYXVsdCA9IHN0b3JhZ2VEcml2ZXI7IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuXG5leHBvcnRzLmRlZmF1bHQgPSBmdW5jdGlvbiAocmVxdWVzdCQsIHJ1blN0cmVhbUFkYXB0ZXIpIHtcbiAgcmV0dXJuIHtcbiAgICAvLyBGb3IgbG9jYWxTdG9yYWdlLlxuICAgIGdldCBsb2NhbCgpIHtcbiAgICAgIHJldHVybiAoMCwgX3V0aWwyLmRlZmF1bHQpKHJlcXVlc3QkLCBydW5TdHJlYW1BZGFwdGVyKTtcbiAgICB9LFxuICAgIC8vIEZvciBzZXNzaW9uU3RvcmFnZS5cbiAgICBnZXQgc2Vzc2lvbigpIHtcbiAgICAgIHJldHVybiAoMCwgX3V0aWwyLmRlZmF1bHQpKHJlcXVlc3QkLCBydW5TdHJlYW1BZGFwdGVyLCAnc2Vzc2lvbicpO1xuICAgIH1cbiAgfTtcbn07XG5cbnZhciBfdXRpbCA9IHJlcXVpcmUoJy4vdXRpbCcpO1xuXG52YXIgX3V0aWwyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdXRpbCk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gZ2V0UmVzcG9uc2VPYmo7XG5cbnZhciBfZHJvcFJlcGVhdHMgPSByZXF1aXJlKCd4c3RyZWFtL2V4dHJhL2Ryb3BSZXBlYXRzJyk7XG5cbnZhciBfZHJvcFJlcGVhdHMyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfZHJvcFJlcGVhdHMpO1xuXG52YXIgX3hzdHJlYW1BZGFwdGVyID0gcmVxdWlyZSgnQGN5Y2xlL3hzdHJlYW0tYWRhcHRlcicpO1xuXG52YXIgX3hzdHJlYW1BZGFwdGVyMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3hzdHJlYW1BZGFwdGVyKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxuZnVuY3Rpb24gZ2V0U3RvcmFnZSQocmVxdWVzdCQsIHR5cGUpIHtcbiAgaWYgKHR5cGUgPT09ICdsb2NhbCcpIHtcbiAgICByZXR1cm4gcmVxdWVzdCQuZmlsdGVyKGZ1bmN0aW9uIChyZXEpIHtcbiAgICAgIHJldHVybiAhcmVxLnRhcmdldCB8fCByZXEudGFyZ2V0ID09PSAnbG9jYWwnO1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiByZXF1ZXN0JC5maWx0ZXIoZnVuY3Rpb24gKHJlcSkge1xuICAgICAgcmV0dXJuIHJlcS50YXJnZXQgPT09ICdzZXNzaW9uJztcbiAgICB9KTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzdG9yYWdlS2V5KG4sIHJlcXVlc3QkKSB7XG4gIHZhciB0eXBlID0gYXJndW1lbnRzLmxlbmd0aCA8PSAyIHx8IGFyZ3VtZW50c1syXSA9PT0gdW5kZWZpbmVkID8gJ2xvY2FsJyA6IGFyZ3VtZW50c1syXTtcblxuICB2YXIgc3RvcmFnZSQgPSBnZXRTdG9yYWdlJChyZXF1ZXN0JCwgdHlwZSk7XG4gIHZhciBrZXkgPSB0eXBlID09PSAnbG9jYWwnID8gbG9jYWxTdG9yYWdlLmtleShuKSA6IHNlc3Npb25TdG9yYWdlLmtleShuKTtcblxuICByZXR1cm4gc3RvcmFnZSQuZmlsdGVyKGZ1bmN0aW9uIChyZXEpIHtcbiAgICByZXR1cm4gcmVxLmtleSA9PT0ga2V5O1xuICB9KS5tYXAoZnVuY3Rpb24gKHJlcSkge1xuICAgIHJldHVybiByZXEua2V5O1xuICB9KS5zdGFydFdpdGgoa2V5KS5jb21wb3NlKCgwLCBfZHJvcFJlcGVhdHMyLmRlZmF1bHQpKCkpO1xufVxuXG5mdW5jdGlvbiBzdG9yYWdlR2V0SXRlbShrZXksIHJlcXVlc3QkKSB7XG4gIHZhciB0eXBlID0gYXJndW1lbnRzLmxlbmd0aCA8PSAyIHx8IGFyZ3VtZW50c1syXSA9PT0gdW5kZWZpbmVkID8gJ2xvY2FsJyA6IGFyZ3VtZW50c1syXTtcblxuICB2YXIgc3RvcmFnZSQgPSBnZXRTdG9yYWdlJChyZXF1ZXN0JCwgdHlwZSk7XG4gIHZhciBzdG9yYWdlT2JqID0gdHlwZSA9PT0gJ2xvY2FsJyA/IGxvY2FsU3RvcmFnZSA6IHNlc3Npb25TdG9yYWdlO1xuXG4gIHJldHVybiBzdG9yYWdlJC5maWx0ZXIoZnVuY3Rpb24gKHJlcSkge1xuICAgIHJldHVybiByZXEua2V5ID09PSBrZXk7XG4gIH0pLm1hcChmdW5jdGlvbiAocmVxKSB7XG4gICAgcmV0dXJuIHJlcS52YWx1ZTtcbiAgfSkuc3RhcnRXaXRoKHN0b3JhZ2VPYmouZ2V0SXRlbShrZXkpKTtcbn1cblxuZnVuY3Rpb24gZ2V0UmVzcG9uc2VPYmoocmVxdWVzdCQsIHJ1blNBKSB7XG4gIHZhciB0eXBlID0gYXJndW1lbnRzLmxlbmd0aCA8PSAyIHx8IGFyZ3VtZW50c1syXSA9PT0gdW5kZWZpbmVkID8gJ2xvY2FsJyA6IGFyZ3VtZW50c1syXTtcblxuICByZXR1cm4ge1xuICAgIC8vIEZ1bmN0aW9uIHJldHVybmluZyBzdHJlYW0gb2YgdGhlIG50aCBrZXkuXG5cbiAgICBrZXk6IGZ1bmN0aW9uIGtleShuKSB7XG4gICAgICByZXR1cm4gcnVuU0EuYWRhcHQoc3RvcmFnZUtleShuLCByZXF1ZXN0JCwgdHlwZSksIF94c3RyZWFtQWRhcHRlcjIuZGVmYXVsdC5zdHJlYW1TdWJzY3JpYmUpO1xuICAgIH0sXG5cbiAgICAvLyBGdW5jdGlvbiByZXR1cm5pbmcgc3RyZWFtIG9mIGl0ZW0gdmFsdWVzLlxuICAgIGdldEl0ZW06IGZ1bmN0aW9uIGdldEl0ZW0oa2V5KSB7XG4gICAgICByZXR1cm4gcnVuU0EuYWRhcHQoc3RvcmFnZUdldEl0ZW0oa2V5LCByZXF1ZXN0JCwgdHlwZSksIF94c3RyZWFtQWRhcHRlcjIuZGVmYXVsdC5zdHJlYW1TdWJzY3JpYmUpO1xuICAgIH1cbiAgfTtcbn0iLCJcInVzZSBzdHJpY3RcIjtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbi8qKlxuICogQGZ1bmN0aW9uIHdyaXRlVG9TdG9yZVxuICogQGRlc2NyaXB0aW9uXG4gKiBBIHVuaXZlcnNhbCB3cml0ZSBmdW5jdGlvbiBmb3IgbG9jYWxTdG9yYWdlIGFuZCBzZXNzaW9uU3RvcmFnZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSByZXF1ZXN0IC0gdGhlIHN0b3JhZ2UgcmVxdWVzdCBvYmplY3RcbiAqIEBwYXJhbSB7c3RyaW5nfSByZXF1ZXN0LnRhcmdldCAtIGEgc3RyaW5nIGRldGVybWluZXMgd2hpY2ggc3RvcmFnZSB0byB1c2VcbiAqIEBwYXJhbSB7c3RyaW5nfSByZXF1ZXN0LmFjdGlvbiAtIGEgc3RyaW5nIGRldGVybWluZXMgdGhlIHdyaXRlIGFjdGlvblxuICogQHBhcmFtIHtzdHJpbmd9IHJlcXVlc3Qua2V5IC0gdGhlIGtleSBvZiBhIHN0b3JhZ2UgaXRlbVxuICogQHBhcmFtIHtzdHJpbmd9IHJlcXVlc3QudmFsdWUgLSB0aGUgdmFsdWUgb2YgYSBzdG9yYWdlIGl0ZW1cbiAqL1xuZnVuY3Rpb24gd3JpdGVUb1N0b3JlKF9yZWYpIHtcbiAgdmFyIF9yZWYkdGFyZ2V0ID0gX3JlZi50YXJnZXQ7XG4gIHZhciB0YXJnZXQgPSBfcmVmJHRhcmdldCA9PT0gdW5kZWZpbmVkID8gXCJsb2NhbFwiIDogX3JlZiR0YXJnZXQ7XG4gIHZhciBfcmVmJGFjdGlvbiA9IF9yZWYuYWN0aW9uO1xuICB2YXIgYWN0aW9uID0gX3JlZiRhY3Rpb24gPT09IHVuZGVmaW5lZCA/IFwic2V0SXRlbVwiIDogX3JlZiRhY3Rpb247XG4gIHZhciBrZXkgPSBfcmVmLmtleTtcbiAgdmFyIHZhbHVlID0gX3JlZi52YWx1ZTtcblxuICAvLyBEZXRlcm1pbmUgdGhlIHN0b3JhZ2UgdGFyZ2V0LlxuICB2YXIgc3RvcmFnZSA9IHRhcmdldCA9PT0gXCJsb2NhbFwiID8gbG9jYWxTdG9yYWdlIDogc2Vzc2lvblN0b3JhZ2U7XG5cbiAgLy8gRXhlY3V0ZSB0aGUgc3RvcmFnZSBhY3Rpb24gYW5kIHBhc3MgYXJndW1lbnRzIGlmIHRoZXkgd2VyZSBkZWZpbmVkLlxuICBzdG9yYWdlW2FjdGlvbl0oa2V5LCB2YWx1ZSk7XG59XG5cbmV4cG9ydHMuZGVmYXVsdCA9IHdyaXRlVG9TdG9yZTsiLCJcInVzZSBzdHJpY3RcIjtcbnZhciB4c3RyZWFtXzEgPSByZXF1aXJlKCd4c3RyZWFtJyk7XG5mdW5jdGlvbiBsb2dUb0NvbnNvbGVFcnJvcihlcnIpIHtcbiAgICB2YXIgdGFyZ2V0ID0gZXJyLnN0YWNrIHx8IGVycjtcbiAgICBpZiAoY29uc29sZSAmJiBjb25zb2xlLmVycm9yKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IodGFyZ2V0KTtcbiAgICB9XG4gICAgZWxzZSBpZiAoY29uc29sZSAmJiBjb25zb2xlLmxvZykge1xuICAgICAgICBjb25zb2xlLmxvZyh0YXJnZXQpO1xuICAgIH1cbn1cbnZhciBYU3RyZWFtQWRhcHRlciA9IHtcbiAgICBhZGFwdDogZnVuY3Rpb24gKG9yaWdpblN0cmVhbSwgb3JpZ2luU3RyZWFtU3Vic2NyaWJlKSB7XG4gICAgICAgIGlmIChYU3RyZWFtQWRhcHRlci5pc1ZhbGlkU3RyZWFtKG9yaWdpblN0cmVhbSkpIHtcbiAgICAgICAgICAgIHJldHVybiBvcmlnaW5TdHJlYW07XG4gICAgICAgIH1cbiAgICAgICAgO1xuICAgICAgICB2YXIgZGlzcG9zZSA9IG51bGw7XG4gICAgICAgIHJldHVybiB4c3RyZWFtXzEuZGVmYXVsdC5jcmVhdGUoe1xuICAgICAgICAgICAgc3RhcnQ6IGZ1bmN0aW9uIChvdXQpIHtcbiAgICAgICAgICAgICAgICB2YXIgb2JzZXJ2ZXIgPSB7XG4gICAgICAgICAgICAgICAgICAgIG5leHQ6IGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gb3V0LnNoYW1lZnVsbHlTZW5kTmV4dCh2YWx1ZSk7IH0sXG4gICAgICAgICAgICAgICAgICAgIGVycm9yOiBmdW5jdGlvbiAoZXJyKSB7IHJldHVybiBvdXQuc2hhbWVmdWxseVNlbmRFcnJvcihlcnIpOyB9LFxuICAgICAgICAgICAgICAgICAgICBjb21wbGV0ZTogZnVuY3Rpb24gKCkgeyByZXR1cm4gb3V0LnNoYW1lZnVsbHlTZW5kQ29tcGxldGUoKTsgfSxcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIGRpc3Bvc2UgPSBvcmlnaW5TdHJlYW1TdWJzY3JpYmUob3JpZ2luU3RyZWFtLCBvYnNlcnZlcik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgc3RvcDogZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZGlzcG9zZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgICAgICBkaXNwb3NlKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9LFxuICAgIGRpc3Bvc2U6IGZ1bmN0aW9uIChzaW5rcywgc2lua1Byb3hpZXMsIHNvdXJjZXMpIHtcbiAgICAgICAgT2JqZWN0LmtleXMoc291cmNlcykuZm9yRWFjaChmdW5jdGlvbiAoaykge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBzb3VyY2VzW2tdLmRpc3Bvc2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICBzb3VyY2VzW2tdLmRpc3Bvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICAgIE9iamVjdC5rZXlzKHNpbmtzKS5mb3JFYWNoKGZ1bmN0aW9uIChrKSB7XG4gICAgICAgICAgICBzaW5rc1trXS5yZW1vdmVMaXN0ZW5lcihzaW5rUHJveGllc1trXS5zdHJlYW0pO1xuICAgICAgICB9KTtcbiAgICB9LFxuICAgIG1ha2VIb2xkU3ViamVjdDogZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc3RyZWFtID0geHN0cmVhbV8xLmRlZmF1bHQuY3JlYXRlV2l0aE1lbW9yeSgpO1xuICAgICAgICB2YXIgb2JzZXJ2ZXIgPSB7XG4gICAgICAgICAgICBuZXh0OiBmdW5jdGlvbiAoeCkgeyBzdHJlYW0uc2hhbWVmdWxseVNlbmROZXh0KHgpOyB9LFxuICAgICAgICAgICAgZXJyb3I6IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgICAgICBsb2dUb0NvbnNvbGVFcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgIHN0cmVhbS5zaGFtZWZ1bGx5U2VuZEVycm9yKGVycik7XG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgY29tcGxldGU6IGZ1bmN0aW9uICgpIHsgc3RyZWFtLnNoYW1lZnVsbHlTZW5kQ29tcGxldGUoKTsgfVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4geyBvYnNlcnZlcjogb2JzZXJ2ZXIsIHN0cmVhbTogc3RyZWFtIH07XG4gICAgfSxcbiAgICBpc1ZhbGlkU3RyZWFtOiBmdW5jdGlvbiAoc3RyZWFtKSB7XG4gICAgICAgIHJldHVybiAodHlwZW9mIHN0cmVhbS5hZGRMaXN0ZW5lciA9PT0gJ2Z1bmN0aW9uJyAmJlxuICAgICAgICAgICAgdHlwZW9mIHN0cmVhbS5zaGFtZWZ1bGx5U2VuZE5leHQgPT09ICdmdW5jdGlvbicpO1xuICAgIH0sXG4gICAgc3RyZWFtU3Vic2NyaWJlOiBmdW5jdGlvbiAoc3RyZWFtLCBvYnNlcnZlcikge1xuICAgICAgICBzdHJlYW0uYWRkTGlzdGVuZXIob2JzZXJ2ZXIpO1xuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkgeyByZXR1cm4gc3RyZWFtLnJlbW92ZUxpc3RlbmVyKG9ic2VydmVyKTsgfTtcbiAgICB9XG59O1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gWFN0cmVhbUFkYXB0ZXI7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbnZhciBfX2V4dGVuZHMgPSAodGhpcyAmJiB0aGlzLl9fZXh0ZW5kcykgfHwgZnVuY3Rpb24gKGQsIGIpIHtcbiAgICBmb3IgKHZhciBwIGluIGIpIGlmIChiLmhhc093blByb3BlcnR5KHApKSBkW3BdID0gYltwXTtcbiAgICBmdW5jdGlvbiBfXygpIHsgdGhpcy5jb25zdHJ1Y3RvciA9IGQ7IH1cbiAgICBkLnByb3RvdHlwZSA9IGIgPT09IG51bGwgPyBPYmplY3QuY3JlYXRlKGIpIDogKF9fLnByb3RvdHlwZSA9IGIucHJvdG90eXBlLCBuZXcgX18oKSk7XG59O1xudmFyIGVtcHR5ID0ge307XG5mdW5jdGlvbiBub29wKCkgeyB9XG5mdW5jdGlvbiBjb3B5KGEpIHtcbiAgICB2YXIgbCA9IGEubGVuZ3RoO1xuICAgIHZhciBiID0gQXJyYXkobCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsOyArK2kpIHtcbiAgICAgICAgYltpXSA9IGFbaV07XG4gICAgfVxuICAgIHJldHVybiBiO1xufVxuZXhwb3J0cy5lbXB0eUxpc3RlbmVyID0ge1xuICAgIF9uOiBub29wLFxuICAgIF9lOiBub29wLFxuICAgIF9jOiBub29wLFxufTtcbi8vIG11dGF0ZXMgdGhlIGlucHV0XG5mdW5jdGlvbiBpbnRlcm5hbGl6ZVByb2R1Y2VyKHByb2R1Y2VyKSB7XG4gICAgcHJvZHVjZXIuX3N0YXJ0ID1cbiAgICAgICAgZnVuY3Rpb24gX3N0YXJ0KGlsKSB7XG4gICAgICAgICAgICBpbC5uZXh0ID0gaWwuX247XG4gICAgICAgICAgICBpbC5lcnJvciA9IGlsLl9lO1xuICAgICAgICAgICAgaWwuY29tcGxldGUgPSBpbC5fYztcbiAgICAgICAgICAgIHRoaXMuc3RhcnQoaWwpO1xuICAgICAgICB9O1xuICAgIHByb2R1Y2VyLl9zdG9wID0gcHJvZHVjZXIuc3RvcDtcbn1cbmZ1bmN0aW9uIGludm9rZShmLCBhcmdzKSB7XG4gICAgc3dpdGNoIChhcmdzLmxlbmd0aCkge1xuICAgICAgICBjYXNlIDA6IHJldHVybiBmKCk7XG4gICAgICAgIGNhc2UgMTogcmV0dXJuIGYoYXJnc1swXSk7XG4gICAgICAgIGNhc2UgMjogcmV0dXJuIGYoYXJnc1swXSwgYXJnc1sxXSk7XG4gICAgICAgIGNhc2UgMzogcmV0dXJuIGYoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSk7XG4gICAgICAgIGNhc2UgNDogcmV0dXJuIGYoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSk7XG4gICAgICAgIGNhc2UgNTogcmV0dXJuIGYoYXJnc1swXSwgYXJnc1sxXSwgYXJnc1syXSwgYXJnc1szXSwgYXJnc1s0XSk7XG4gICAgICAgIGRlZmF1bHQ6IHJldHVybiBmLmFwcGx5KHZvaWQgMCwgYXJncyk7XG4gICAgfVxufVxuZnVuY3Rpb24gY29tcG9zZTIoZjEsIGYyKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIGNvbXBvc2VkRm4oYXJnKSB7XG4gICAgICAgIHJldHVybiBmMShmMihhcmcpKTtcbiAgICB9O1xufVxuZnVuY3Rpb24gYW5kKGYxLCBmMikge1xuICAgIHJldHVybiBmdW5jdGlvbiBhbmRGbih0KSB7XG4gICAgICAgIHJldHVybiBmMSh0KSAmJiBmMih0KTtcbiAgICB9O1xufVxudmFyIENvbWJpbmVMaXN0ZW5lciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gQ29tYmluZUxpc3RlbmVyKGksIHApIHtcbiAgICAgICAgdGhpcy5pID0gaTtcbiAgICAgICAgdGhpcy5wID0gcDtcbiAgICAgICAgcC5pbHMucHVzaCh0aGlzKTtcbiAgICB9XG4gICAgQ29tYmluZUxpc3RlbmVyLnByb3RvdHlwZS5fbiA9IGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHZhciBwID0gdGhpcy5wLCBvdXQgPSBwLm91dDtcbiAgICAgICAgaWYgKCFvdXQpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGlmIChwLnVwKHQsIHRoaXMuaSkpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgb3V0Ll9uKGludm9rZShwLnByb2plY3QsIHAudmFscykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBvdXQuX2UoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENvbWJpbmVMaXN0ZW5lci5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHZhciBvdXQgPSB0aGlzLnAub3V0O1xuICAgICAgICBpZiAoIW91dClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgb3V0Ll9lKGVycik7XG4gICAgfTtcbiAgICBDb21iaW5lTGlzdGVuZXIucHJvdG90eXBlLl9jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcCA9IHRoaXMucDtcbiAgICAgICAgaWYgKCFwLm91dClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgaWYgKC0tcC5hYyA9PT0gMCkge1xuICAgICAgICAgICAgcC5vdXQuX2MoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIENvbWJpbmVMaXN0ZW5lcjtcbn0oKSk7XG5leHBvcnRzLkNvbWJpbmVMaXN0ZW5lciA9IENvbWJpbmVMaXN0ZW5lcjtcbnZhciBDb21iaW5lUHJvZHVjZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIENvbWJpbmVQcm9kdWNlcihwcm9qZWN0LCBzdHJlYW1zKSB7XG4gICAgICAgIHRoaXMucHJvamVjdCA9IHByb2plY3Q7XG4gICAgICAgIHRoaXMuc3RyZWFtcyA9IHN0cmVhbXM7XG4gICAgICAgIHRoaXMudHlwZSA9ICdjb21iaW5lJztcbiAgICAgICAgdGhpcy5vdXQgPSBleHBvcnRzLmVtcHR5TGlzdGVuZXI7XG4gICAgICAgIHRoaXMuaWxzID0gW107XG4gICAgICAgIHZhciBuID0gdGhpcy5hYyA9IHRoaXMubGVmdCA9IHN0cmVhbXMubGVuZ3RoO1xuICAgICAgICB2YXIgdmFscyA9IHRoaXMudmFscyA9IG5ldyBBcnJheShuKTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgICAgIHZhbHNbaV0gPSBlbXB0eTtcbiAgICAgICAgfVxuICAgIH1cbiAgICBDb21iaW5lUHJvZHVjZXIucHJvdG90eXBlLnVwID0gZnVuY3Rpb24gKHQsIGkpIHtcbiAgICAgICAgdmFyIHYgPSB0aGlzLnZhbHNbaV07XG4gICAgICAgIHZhciBsZWZ0ID0gIXRoaXMubGVmdCA/IDAgOiB2ID09PSBlbXB0eSA/IC0tdGhpcy5sZWZ0IDogdGhpcy5sZWZ0O1xuICAgICAgICB0aGlzLnZhbHNbaV0gPSB0O1xuICAgICAgICByZXR1cm4gbGVmdCA9PT0gMDtcbiAgICB9O1xuICAgIENvbWJpbmVQcm9kdWNlci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB0aGlzLm91dCA9IG91dDtcbiAgICAgICAgdmFyIHMgPSB0aGlzLnN0cmVhbXM7XG4gICAgICAgIHZhciBuID0gcy5sZW5ndGg7XG4gICAgICAgIGlmIChuID09PSAwKVxuICAgICAgICAgICAgdGhpcy56ZXJvKG91dCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyBpKyspIHtcbiAgICAgICAgICAgICAgICBzW2ldLl9hZGQobmV3IENvbWJpbmVMaXN0ZW5lcihpLCB0aGlzKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9O1xuICAgIENvbWJpbmVQcm9kdWNlci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzID0gdGhpcy5zdHJlYW1zO1xuICAgICAgICB2YXIgbiA9IHRoaXMuYWMgPSB0aGlzLmxlZnQgPSBzLmxlbmd0aDtcbiAgICAgICAgdmFyIHZhbHMgPSB0aGlzLnZhbHMgPSBuZXcgQXJyYXkobik7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgaSsrKSB7XG4gICAgICAgICAgICBzW2ldLl9yZW1vdmUodGhpcy5pbHNbaV0pO1xuICAgICAgICAgICAgdmFsc1tpXSA9IGVtcHR5O1xuICAgICAgICB9XG4gICAgICAgIHRoaXMub3V0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5pbHMgPSBbXTtcbiAgICB9O1xuICAgIENvbWJpbmVQcm9kdWNlci5wcm90b3R5cGUuemVybyA9IGZ1bmN0aW9uIChvdXQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIG91dC5fbih0aGlzLnByb2plY3QoKSk7XG4gICAgICAgICAgICBvdXQuX2MoKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgb3V0Ll9lKGUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gQ29tYmluZVByb2R1Y2VyO1xufSgpKTtcbmV4cG9ydHMuQ29tYmluZVByb2R1Y2VyID0gQ29tYmluZVByb2R1Y2VyO1xudmFyIEZyb21BcnJheVByb2R1Y2VyID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBGcm9tQXJyYXlQcm9kdWNlcihhKSB7XG4gICAgICAgIHRoaXMuYSA9IGE7XG4gICAgICAgIHRoaXMudHlwZSA9ICdmcm9tQXJyYXknO1xuICAgIH1cbiAgICBGcm9tQXJyYXlQcm9kdWNlci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB2YXIgYSA9IHRoaXMuYTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBhLmxlbmd0aDsgaSA8IGw7IGkrKykge1xuICAgICAgICAgICAgb3V0Ll9uKGFbaV0pO1xuICAgICAgICB9XG4gICAgICAgIG91dC5fYygpO1xuICAgIH07XG4gICAgRnJvbUFycmF5UHJvZHVjZXIucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKCkge1xuICAgIH07XG4gICAgcmV0dXJuIEZyb21BcnJheVByb2R1Y2VyO1xufSgpKTtcbmV4cG9ydHMuRnJvbUFycmF5UHJvZHVjZXIgPSBGcm9tQXJyYXlQcm9kdWNlcjtcbnZhciBGcm9tUHJvbWlzZVByb2R1Y2VyID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBGcm9tUHJvbWlzZVByb2R1Y2VyKHApIHtcbiAgICAgICAgdGhpcy5wID0gcDtcbiAgICAgICAgdGhpcy50eXBlID0gJ2Zyb21Qcm9taXNlJztcbiAgICAgICAgdGhpcy5vbiA9IGZhbHNlO1xuICAgIH1cbiAgICBGcm9tUHJvbWlzZVByb2R1Y2VyLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAob3V0KSB7XG4gICAgICAgIHZhciBwcm9kID0gdGhpcztcbiAgICAgICAgdGhpcy5vbiA9IHRydWU7XG4gICAgICAgIHRoaXMucC50aGVuKGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgICBpZiAocHJvZC5vbikge1xuICAgICAgICAgICAgICAgIG91dC5fbih2KTtcbiAgICAgICAgICAgICAgICBvdXQuX2MoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSwgZnVuY3Rpb24gKGUpIHtcbiAgICAgICAgICAgIG91dC5fZShlKTtcbiAgICAgICAgfSkudGhlbihudWxsLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsgdGhyb3cgZXJyOyB9KTtcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICBGcm9tUHJvbWlzZVByb2R1Y2VyLnByb3RvdHlwZS5fc3RvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5vbiA9IGZhbHNlO1xuICAgIH07XG4gICAgcmV0dXJuIEZyb21Qcm9taXNlUHJvZHVjZXI7XG59KCkpO1xuZXhwb3J0cy5Gcm9tUHJvbWlzZVByb2R1Y2VyID0gRnJvbVByb21pc2VQcm9kdWNlcjtcbnZhciBNZXJnZVByb2R1Y2VyID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBNZXJnZVByb2R1Y2VyKHN0cmVhbXMpIHtcbiAgICAgICAgdGhpcy5zdHJlYW1zID0gc3RyZWFtcztcbiAgICAgICAgdGhpcy50eXBlID0gJ21lcmdlJztcbiAgICAgICAgdGhpcy5vdXQgPSBleHBvcnRzLmVtcHR5TGlzdGVuZXI7XG4gICAgICAgIHRoaXMuYWMgPSBzdHJlYW1zLmxlbmd0aDtcbiAgICB9XG4gICAgTWVyZ2VQcm9kdWNlci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB0aGlzLm91dCA9IG91dDtcbiAgICAgICAgdmFyIHMgPSB0aGlzLnN0cmVhbXM7XG4gICAgICAgIHZhciBMID0gcy5sZW5ndGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgTDsgaSsrKSB7XG4gICAgICAgICAgICBzW2ldLl9hZGQodGhpcyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIE1lcmdlUHJvZHVjZXIucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcyA9IHRoaXMuc3RyZWFtcztcbiAgICAgICAgdmFyIEwgPSBzLmxlbmd0aDtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBMOyBpKyspIHtcbiAgICAgICAgICAgIHNbaV0uX3JlbW92ZSh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm91dCA9IG51bGw7XG4gICAgICAgIHRoaXMuYWMgPSBMO1xuICAgIH07XG4gICAgTWVyZ2VQcm9kdWNlci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAoIXUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHUuX24odCk7XG4gICAgfTtcbiAgICBNZXJnZVByb2R1Y2VyLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9lKGVycik7XG4gICAgfTtcbiAgICBNZXJnZVByb2R1Y2VyLnByb3RvdHlwZS5fYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKC0tdGhpcy5hYyA9PT0gMCkge1xuICAgICAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgICAgIGlmICghdSlcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB1Ll9jKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBNZXJnZVByb2R1Y2VyO1xufSgpKTtcbmV4cG9ydHMuTWVyZ2VQcm9kdWNlciA9IE1lcmdlUHJvZHVjZXI7XG52YXIgUGVyaW9kaWNQcm9kdWNlciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gUGVyaW9kaWNQcm9kdWNlcihwZXJpb2QpIHtcbiAgICAgICAgdGhpcy5wZXJpb2QgPSBwZXJpb2Q7XG4gICAgICAgIHRoaXMudHlwZSA9ICdwZXJpb2RpYyc7XG4gICAgICAgIHRoaXMuaW50ZXJ2YWxJRCA9IC0xO1xuICAgICAgICB0aGlzLmkgPSAwO1xuICAgIH1cbiAgICBQZXJpb2RpY1Byb2R1Y2VyLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAoc3RyZWFtKSB7XG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgZnVuY3Rpb24gaW50ZXJ2YWxIYW5kbGVyKCkgeyBzdHJlYW0uX24oc2VsZi5pKyspOyB9XG4gICAgICAgIHRoaXMuaW50ZXJ2YWxJRCA9IHNldEludGVydmFsKGludGVydmFsSGFuZGxlciwgdGhpcy5wZXJpb2QpO1xuICAgIH07XG4gICAgUGVyaW9kaWNQcm9kdWNlci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICh0aGlzLmludGVydmFsSUQgIT09IC0xKVxuICAgICAgICAgICAgY2xlYXJJbnRlcnZhbCh0aGlzLmludGVydmFsSUQpO1xuICAgICAgICB0aGlzLmludGVydmFsSUQgPSAtMTtcbiAgICAgICAgdGhpcy5pID0gMDtcbiAgICB9O1xuICAgIHJldHVybiBQZXJpb2RpY1Byb2R1Y2VyO1xufSgpKTtcbmV4cG9ydHMuUGVyaW9kaWNQcm9kdWNlciA9IFBlcmlvZGljUHJvZHVjZXI7XG52YXIgRGVidWdPcGVyYXRvciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRGVidWdPcGVyYXRvcihhcmcsIGlucykge1xuICAgICAgICB0aGlzLmlucyA9IGlucztcbiAgICAgICAgdGhpcy50eXBlID0gJ2RlYnVnJztcbiAgICAgICAgdGhpcy5vdXQgPSBudWxsO1xuICAgICAgICB0aGlzLnMgPSBudWxsOyAvLyBzcHlcbiAgICAgICAgdGhpcy5sID0gbnVsbDsgLy8gbGFiZWxcbiAgICAgICAgaWYgKHR5cGVvZiBhcmcgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aGlzLmwgPSBhcmc7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aGlzLnMgPSBhcmc7XG4gICAgICAgIH1cbiAgICB9XG4gICAgRGVidWdPcGVyYXRvci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB0aGlzLm91dCA9IG91dDtcbiAgICAgICAgdGhpcy5pbnMuX2FkZCh0aGlzKTtcbiAgICB9O1xuICAgIERlYnVnT3BlcmF0b3IucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmlucy5fcmVtb3ZlKHRoaXMpO1xuICAgICAgICB0aGlzLm91dCA9IG51bGw7XG4gICAgfTtcbiAgICBEZWJ1Z09wZXJhdG9yLnByb3RvdHlwZS5fbiA9IGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdmFyIHMgPSB0aGlzLnMsIGwgPSB0aGlzLmw7XG4gICAgICAgIGlmIChzKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHModCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHUuX2UoZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSBpZiAobCkge1xuICAgICAgICAgICAgY29uc29sZS5sb2cobCArICc6JywgdCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZyh0KTtcbiAgICAgICAgfVxuICAgICAgICB1Ll9uKHQpO1xuICAgIH07XG4gICAgRGVidWdPcGVyYXRvci5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdS5fZShlcnIpO1xuICAgIH07XG4gICAgRGVidWdPcGVyYXRvci5wcm90b3R5cGUuX2MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdS5fYygpO1xuICAgIH07XG4gICAgcmV0dXJuIERlYnVnT3BlcmF0b3I7XG59KCkpO1xuZXhwb3J0cy5EZWJ1Z09wZXJhdG9yID0gRGVidWdPcGVyYXRvcjtcbnZhciBEcm9wT3BlcmF0b3IgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIERyb3BPcGVyYXRvcihtYXgsIGlucykge1xuICAgICAgICB0aGlzLm1heCA9IG1heDtcbiAgICAgICAgdGhpcy5pbnMgPSBpbnM7XG4gICAgICAgIHRoaXMudHlwZSA9ICdkcm9wJztcbiAgICAgICAgdGhpcy5vdXQgPSBudWxsO1xuICAgICAgICB0aGlzLmRyb3BwZWQgPSAwO1xuICAgIH1cbiAgICBEcm9wT3BlcmF0b3IucHJvdG90eXBlLl9zdGFydCA9IGZ1bmN0aW9uIChvdXQpIHtcbiAgICAgICAgdGhpcy5vdXQgPSBvdXQ7XG4gICAgICAgIHRoaXMuaW5zLl9hZGQodGhpcyk7XG4gICAgfTtcbiAgICBEcm9wT3BlcmF0b3IucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmlucy5fcmVtb3ZlKHRoaXMpO1xuICAgICAgICB0aGlzLm91dCA9IG51bGw7XG4gICAgICAgIHRoaXMuZHJvcHBlZCA9IDA7XG4gICAgfTtcbiAgICBEcm9wT3BlcmF0b3IucHJvdG90eXBlLl9uID0gZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBpZiAodGhpcy5kcm9wcGVkKysgPj0gdGhpcy5tYXgpXG4gICAgICAgICAgICB1Ll9uKHQpO1xuICAgIH07XG4gICAgRHJvcE9wZXJhdG9yLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9lKGVycik7XG4gICAgfTtcbiAgICBEcm9wT3BlcmF0b3IucHJvdG90eXBlLl9jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAoIXUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHUuX2MoKTtcbiAgICB9O1xuICAgIHJldHVybiBEcm9wT3BlcmF0b3I7XG59KCkpO1xuZXhwb3J0cy5Ecm9wT3BlcmF0b3IgPSBEcm9wT3BlcmF0b3I7XG52YXIgT3RoZXJJTCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gT3RoZXJJTChvdXQsIG9wKSB7XG4gICAgICAgIHRoaXMub3V0ID0gb3V0O1xuICAgICAgICB0aGlzLm9wID0gb3A7XG4gICAgfVxuICAgIE90aGVySUwucHJvdG90eXBlLl9uID0gZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgdGhpcy5vcC5lbmQoKTtcbiAgICB9O1xuICAgIE90aGVySUwucHJvdG90eXBlLl9lID0gZnVuY3Rpb24gKGVycikge1xuICAgICAgICB0aGlzLm91dC5fZShlcnIpO1xuICAgIH07XG4gICAgT3RoZXJJTC5wcm90b3R5cGUuX2MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMub3AuZW5kKCk7XG4gICAgfTtcbiAgICByZXR1cm4gT3RoZXJJTDtcbn0oKSk7XG52YXIgRW5kV2hlbk9wZXJhdG9yID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBFbmRXaGVuT3BlcmF0b3IobywgLy8gbyA9IG90aGVyXG4gICAgICAgIGlucykge1xuICAgICAgICB0aGlzLm8gPSBvO1xuICAgICAgICB0aGlzLmlucyA9IGlucztcbiAgICAgICAgdGhpcy50eXBlID0gJ2VuZFdoZW4nO1xuICAgICAgICB0aGlzLm91dCA9IG51bGw7XG4gICAgICAgIHRoaXMub2lsID0gZXhwb3J0cy5lbXB0eUxpc3RlbmVyOyAvLyBvaWwgPSBvdGhlciBJbnRlcm5hbExpc3RlbmVyXG4gICAgfVxuICAgIEVuZFdoZW5PcGVyYXRvci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB0aGlzLm91dCA9IG91dDtcbiAgICAgICAgdGhpcy5vLl9hZGQodGhpcy5vaWwgPSBuZXcgT3RoZXJJTChvdXQsIHRoaXMpKTtcbiAgICAgICAgdGhpcy5pbnMuX2FkZCh0aGlzKTtcbiAgICB9O1xuICAgIEVuZFdoZW5PcGVyYXRvci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuaW5zLl9yZW1vdmUodGhpcyk7XG4gICAgICAgIHRoaXMuby5fcmVtb3ZlKHRoaXMub2lsKTtcbiAgICAgICAgdGhpcy5vdXQgPSBudWxsO1xuICAgICAgICB0aGlzLm9pbCA9IG51bGw7XG4gICAgfTtcbiAgICBFbmRXaGVuT3BlcmF0b3IucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9jKCk7XG4gICAgfTtcbiAgICBFbmRXaGVuT3BlcmF0b3IucHJvdG90eXBlLl9uID0gZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9uKHQpO1xuICAgIH07XG4gICAgRW5kV2hlbk9wZXJhdG9yLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9lKGVycik7XG4gICAgfTtcbiAgICBFbmRXaGVuT3BlcmF0b3IucHJvdG90eXBlLl9jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmVuZCgpO1xuICAgIH07XG4gICAgcmV0dXJuIEVuZFdoZW5PcGVyYXRvcjtcbn0oKSk7XG5leHBvcnRzLkVuZFdoZW5PcGVyYXRvciA9IEVuZFdoZW5PcGVyYXRvcjtcbnZhciBGaWx0ZXJPcGVyYXRvciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRmlsdGVyT3BlcmF0b3IocGFzc2VzLCBpbnMpIHtcbiAgICAgICAgdGhpcy5wYXNzZXMgPSBwYXNzZXM7XG4gICAgICAgIHRoaXMuaW5zID0gaW5zO1xuICAgICAgICB0aGlzLnR5cGUgPSAnZmlsdGVyJztcbiAgICAgICAgdGhpcy5vdXQgPSBudWxsO1xuICAgIH1cbiAgICBGaWx0ZXJPcGVyYXRvci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB0aGlzLm91dCA9IG91dDtcbiAgICAgICAgdGhpcy5pbnMuX2FkZCh0aGlzKTtcbiAgICB9O1xuICAgIEZpbHRlck9wZXJhdG9yLnByb3RvdHlwZS5fc3RvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5pbnMuX3JlbW92ZSh0aGlzKTtcbiAgICAgICAgdGhpcy5vdXQgPSBudWxsO1xuICAgIH07XG4gICAgRmlsdGVyT3BlcmF0b3IucHJvdG90eXBlLl9uID0gZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKHRoaXMucGFzc2VzKHQpKVxuICAgICAgICAgICAgICAgIHUuX24odCk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHUuX2UoZSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEZpbHRlck9wZXJhdG9yLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9lKGVycik7XG4gICAgfTtcbiAgICBGaWx0ZXJPcGVyYXRvci5wcm90b3R5cGUuX2MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdS5fYygpO1xuICAgIH07XG4gICAgcmV0dXJuIEZpbHRlck9wZXJhdG9yO1xufSgpKTtcbmV4cG9ydHMuRmlsdGVyT3BlcmF0b3IgPSBGaWx0ZXJPcGVyYXRvcjtcbnZhciBGbGF0dGVuTGlzdGVuZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEZsYXR0ZW5MaXN0ZW5lcihvdXQsIG9wKSB7XG4gICAgICAgIHRoaXMub3V0ID0gb3V0O1xuICAgICAgICB0aGlzLm9wID0gb3A7XG4gICAgfVxuICAgIEZsYXR0ZW5MaXN0ZW5lci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodCkge1xuICAgICAgICB0aGlzLm91dC5fbih0KTtcbiAgICB9O1xuICAgIEZsYXR0ZW5MaXN0ZW5lci5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHRoaXMub3V0Ll9lKGVycik7XG4gICAgfTtcbiAgICBGbGF0dGVuTGlzdGVuZXIucHJvdG90eXBlLl9jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLm9wLmlubmVyID0gbnVsbDtcbiAgICAgICAgdGhpcy5vcC5sZXNzKCk7XG4gICAgfTtcbiAgICByZXR1cm4gRmxhdHRlbkxpc3RlbmVyO1xufSgpKTtcbnZhciBGbGF0dGVuT3BlcmF0b3IgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEZsYXR0ZW5PcGVyYXRvcihpbnMpIHtcbiAgICAgICAgdGhpcy5pbnMgPSBpbnM7XG4gICAgICAgIHRoaXMudHlwZSA9ICdmbGF0dGVuJztcbiAgICAgICAgdGhpcy5pbm5lciA9IG51bGw7IC8vIEN1cnJlbnQgaW5uZXIgU3RyZWFtXG4gICAgICAgIHRoaXMuaWwgPSBudWxsOyAvLyBDdXJyZW50IGlubmVyIEludGVybmFsTGlzdGVuZXJcbiAgICAgICAgdGhpcy5vcGVuID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5vdXQgPSBudWxsO1xuICAgIH1cbiAgICBGbGF0dGVuT3BlcmF0b3IucHJvdG90eXBlLl9zdGFydCA9IGZ1bmN0aW9uIChvdXQpIHtcbiAgICAgICAgdGhpcy5vdXQgPSBvdXQ7XG4gICAgICAgIHRoaXMuaW5zLl9hZGQodGhpcyk7XG4gICAgfTtcbiAgICBGbGF0dGVuT3BlcmF0b3IucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmlucy5fcmVtb3ZlKHRoaXMpO1xuICAgICAgICB0aGlzLmlubmVyID0gbnVsbDtcbiAgICAgICAgdGhpcy5pbCA9IG51bGw7XG4gICAgICAgIHRoaXMub3BlbiA9IHRydWU7XG4gICAgICAgIHRoaXMub3V0ID0gbnVsbDtcbiAgICB9O1xuICAgIEZsYXR0ZW5PcGVyYXRvci5wcm90b3R5cGUubGVzcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBpZiAoIXRoaXMub3BlbiAmJiAhdGhpcy5pbm5lcilcbiAgICAgICAgICAgIHUuX2MoKTtcbiAgICB9O1xuICAgIEZsYXR0ZW5PcGVyYXRvci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAocykge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAoIXUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHZhciBfYSA9IHRoaXMsIGlubmVyID0gX2EuaW5uZXIsIGlsID0gX2EuaWw7XG4gICAgICAgIGlmIChpbm5lciAmJiBpbClcbiAgICAgICAgICAgIGlubmVyLl9yZW1vdmUoaWwpO1xuICAgICAgICAodGhpcy5pbm5lciA9IHMpLl9hZGQodGhpcy5pbCA9IG5ldyBGbGF0dGVuTGlzdGVuZXIodSwgdGhpcykpO1xuICAgIH07XG4gICAgRmxhdHRlbk9wZXJhdG9yLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9lKGVycik7XG4gICAgfTtcbiAgICBGbGF0dGVuT3BlcmF0b3IucHJvdG90eXBlLl9jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLm9wZW4gPSBmYWxzZTtcbiAgICAgICAgdGhpcy5sZXNzKCk7XG4gICAgfTtcbiAgICByZXR1cm4gRmxhdHRlbk9wZXJhdG9yO1xufSgpKTtcbmV4cG9ydHMuRmxhdHRlbk9wZXJhdG9yID0gRmxhdHRlbk9wZXJhdG9yO1xudmFyIEZvbGRPcGVyYXRvciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRm9sZE9wZXJhdG9yKGYsIHNlZWQsIGlucykge1xuICAgICAgICB0aGlzLmYgPSBmO1xuICAgICAgICB0aGlzLnNlZWQgPSBzZWVkO1xuICAgICAgICB0aGlzLmlucyA9IGlucztcbiAgICAgICAgdGhpcy50eXBlID0gJ2ZvbGQnO1xuICAgICAgICB0aGlzLm91dCA9IG51bGw7XG4gICAgICAgIHRoaXMuYWNjID0gc2VlZDtcbiAgICB9XG4gICAgRm9sZE9wZXJhdG9yLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAob3V0KSB7XG4gICAgICAgIHRoaXMub3V0ID0gb3V0O1xuICAgICAgICBvdXQuX24odGhpcy5hY2MpO1xuICAgICAgICB0aGlzLmlucy5fYWRkKHRoaXMpO1xuICAgIH07XG4gICAgRm9sZE9wZXJhdG9yLnByb3RvdHlwZS5fc3RvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5pbnMuX3JlbW92ZSh0aGlzKTtcbiAgICAgICAgdGhpcy5vdXQgPSBudWxsO1xuICAgICAgICB0aGlzLmFjYyA9IHRoaXMuc2VlZDtcbiAgICB9O1xuICAgIEZvbGRPcGVyYXRvci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAoIXUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB1Ll9uKHRoaXMuYWNjID0gdGhpcy5mKHRoaXMuYWNjLCB0KSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHUuX2UoZSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIEZvbGRPcGVyYXRvci5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdS5fZShlcnIpO1xuICAgIH07XG4gICAgRm9sZE9wZXJhdG9yLnByb3RvdHlwZS5fYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9jKCk7XG4gICAgfTtcbiAgICByZXR1cm4gRm9sZE9wZXJhdG9yO1xufSgpKTtcbmV4cG9ydHMuRm9sZE9wZXJhdG9yID0gRm9sZE9wZXJhdG9yO1xudmFyIExhc3RPcGVyYXRvciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTGFzdE9wZXJhdG9yKGlucykge1xuICAgICAgICB0aGlzLmlucyA9IGlucztcbiAgICAgICAgdGhpcy50eXBlID0gJ2xhc3QnO1xuICAgICAgICB0aGlzLm91dCA9IG51bGw7XG4gICAgICAgIHRoaXMuaGFzID0gZmFsc2U7XG4gICAgICAgIHRoaXMudmFsID0gZW1wdHk7XG4gICAgfVxuICAgIExhc3RPcGVyYXRvci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB0aGlzLm91dCA9IG91dDtcbiAgICAgICAgdGhpcy5pbnMuX2FkZCh0aGlzKTtcbiAgICB9O1xuICAgIExhc3RPcGVyYXRvci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuaW5zLl9yZW1vdmUodGhpcyk7XG4gICAgICAgIHRoaXMub3V0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5oYXMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy52YWwgPSBlbXB0eTtcbiAgICB9O1xuICAgIExhc3RPcGVyYXRvci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodCkge1xuICAgICAgICB0aGlzLmhhcyA9IHRydWU7XG4gICAgICAgIHRoaXMudmFsID0gdDtcbiAgICB9O1xuICAgIExhc3RPcGVyYXRvci5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdS5fZShlcnIpO1xuICAgIH07XG4gICAgTGFzdE9wZXJhdG9yLnByb3RvdHlwZS5fYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBpZiAodGhpcy5oYXMpIHtcbiAgICAgICAgICAgIHUuX24odGhpcy52YWwpO1xuICAgICAgICAgICAgdS5fYygpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdS5fZSgnVE9ETyBzaG93IHByb3BlciBlcnJvcicpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gTGFzdE9wZXJhdG9yO1xufSgpKTtcbmV4cG9ydHMuTGFzdE9wZXJhdG9yID0gTGFzdE9wZXJhdG9yO1xudmFyIE1hcEZsYXR0ZW5Jbm5lciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTWFwRmxhdHRlbklubmVyKG91dCwgb3ApIHtcbiAgICAgICAgdGhpcy5vdXQgPSBvdXQ7XG4gICAgICAgIHRoaXMub3AgPSBvcDtcbiAgICB9XG4gICAgTWFwRmxhdHRlbklubmVyLnByb3RvdHlwZS5fbiA9IGZ1bmN0aW9uIChyKSB7XG4gICAgICAgIHRoaXMub3V0Ll9uKHIpO1xuICAgIH07XG4gICAgTWFwRmxhdHRlbklubmVyLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgdGhpcy5vdXQuX2UoZXJyKTtcbiAgICB9O1xuICAgIE1hcEZsYXR0ZW5Jbm5lci5wcm90b3R5cGUuX2MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMub3AuaW5uZXIgPSBudWxsO1xuICAgICAgICB0aGlzLm9wLmxlc3MoKTtcbiAgICB9O1xuICAgIHJldHVybiBNYXBGbGF0dGVuSW5uZXI7XG59KCkpO1xudmFyIE1hcEZsYXR0ZW5PcGVyYXRvciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTWFwRmxhdHRlbk9wZXJhdG9yKG1hcE9wKSB7XG4gICAgICAgIHRoaXMubWFwT3AgPSBtYXBPcDtcbiAgICAgICAgdGhpcy5pbm5lciA9IG51bGw7IC8vIEN1cnJlbnQgaW5uZXIgU3RyZWFtXG4gICAgICAgIHRoaXMuaWwgPSBudWxsOyAvLyBDdXJyZW50IGlubmVyIEludGVybmFsTGlzdGVuZXJcbiAgICAgICAgdGhpcy5vcGVuID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5vdXQgPSBudWxsO1xuICAgICAgICB0aGlzLnR5cGUgPSBtYXBPcC50eXBlICsgXCIrZmxhdHRlblwiO1xuICAgICAgICB0aGlzLmlucyA9IG1hcE9wLmlucztcbiAgICB9XG4gICAgTWFwRmxhdHRlbk9wZXJhdG9yLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAob3V0KSB7XG4gICAgICAgIHRoaXMub3V0ID0gb3V0O1xuICAgICAgICB0aGlzLm1hcE9wLmlucy5fYWRkKHRoaXMpO1xuICAgIH07XG4gICAgTWFwRmxhdHRlbk9wZXJhdG9yLnByb3RvdHlwZS5fc3RvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5tYXBPcC5pbnMuX3JlbW92ZSh0aGlzKTtcbiAgICAgICAgdGhpcy5pbm5lciA9IG51bGw7XG4gICAgICAgIHRoaXMuaWwgPSBudWxsO1xuICAgICAgICB0aGlzLm9wZW4gPSB0cnVlO1xuICAgICAgICB0aGlzLm91dCA9IG51bGw7XG4gICAgfTtcbiAgICBNYXBGbGF0dGVuT3BlcmF0b3IucHJvdG90eXBlLmxlc3MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGlmICghdGhpcy5vcGVuICYmICF0aGlzLmlubmVyKSB7XG4gICAgICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIHUuX2MoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgTWFwRmxhdHRlbk9wZXJhdG9yLnByb3RvdHlwZS5fbiA9IGZ1bmN0aW9uICh2KSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdmFyIF9hID0gdGhpcywgaW5uZXIgPSBfYS5pbm5lciwgaWwgPSBfYS5pbDtcbiAgICAgICAgaWYgKGlubmVyICYmIGlsKVxuICAgICAgICAgICAgaW5uZXIuX3JlbW92ZShpbCk7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICAodGhpcy5pbm5lciA9IHRoaXMubWFwT3AucHJvamVjdCh2KSkuX2FkZCh0aGlzLmlsID0gbmV3IE1hcEZsYXR0ZW5Jbm5lcih1LCB0aGlzKSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHUuX2UoZSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIE1hcEZsYXR0ZW5PcGVyYXRvci5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdS5fZShlcnIpO1xuICAgIH07XG4gICAgTWFwRmxhdHRlbk9wZXJhdG9yLnByb3RvdHlwZS5fYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5vcGVuID0gZmFsc2U7XG4gICAgICAgIHRoaXMubGVzcygpO1xuICAgIH07XG4gICAgcmV0dXJuIE1hcEZsYXR0ZW5PcGVyYXRvcjtcbn0oKSk7XG5leHBvcnRzLk1hcEZsYXR0ZW5PcGVyYXRvciA9IE1hcEZsYXR0ZW5PcGVyYXRvcjtcbnZhciBNYXBPcGVyYXRvciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTWFwT3BlcmF0b3IocHJvamVjdCwgaW5zKSB7XG4gICAgICAgIHRoaXMucHJvamVjdCA9IHByb2plY3Q7XG4gICAgICAgIHRoaXMuaW5zID0gaW5zO1xuICAgICAgICB0aGlzLnR5cGUgPSAnbWFwJztcbiAgICAgICAgdGhpcy5vdXQgPSBudWxsO1xuICAgIH1cbiAgICBNYXBPcGVyYXRvci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB0aGlzLm91dCA9IG91dDtcbiAgICAgICAgdGhpcy5pbnMuX2FkZCh0aGlzKTtcbiAgICB9O1xuICAgIE1hcE9wZXJhdG9yLnByb3RvdHlwZS5fc3RvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5pbnMuX3JlbW92ZSh0aGlzKTtcbiAgICAgICAgdGhpcy5vdXQgPSBudWxsO1xuICAgIH07XG4gICAgTWFwT3BlcmF0b3IucHJvdG90eXBlLl9uID0gZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdS5fbih0aGlzLnByb2plY3QodCkpO1xuICAgICAgICB9XG4gICAgICAgIGNhdGNoIChlKSB7XG4gICAgICAgICAgICB1Ll9lKGUpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBNYXBPcGVyYXRvci5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdS5fZShlcnIpO1xuICAgIH07XG4gICAgTWFwT3BlcmF0b3IucHJvdG90eXBlLl9jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAoIXUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHUuX2MoKTtcbiAgICB9O1xuICAgIHJldHVybiBNYXBPcGVyYXRvcjtcbn0oKSk7XG5leHBvcnRzLk1hcE9wZXJhdG9yID0gTWFwT3BlcmF0b3I7XG52YXIgRmlsdGVyTWFwT3BlcmF0b3IgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhGaWx0ZXJNYXBPcGVyYXRvciwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBGaWx0ZXJNYXBPcGVyYXRvcihwYXNzZXMsIHByb2plY3QsIGlucykge1xuICAgICAgICBfc3VwZXIuY2FsbCh0aGlzLCBwcm9qZWN0LCBpbnMpO1xuICAgICAgICB0aGlzLnBhc3NlcyA9IHBhc3NlcztcbiAgICAgICAgdGhpcy50eXBlID0gJ2ZpbHRlcittYXAnO1xuICAgIH1cbiAgICBGaWx0ZXJNYXBPcGVyYXRvci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodikge1xuICAgICAgICBpZiAodGhpcy5wYXNzZXModikpIHtcbiAgICAgICAgICAgIF9zdXBlci5wcm90b3R5cGUuX24uY2FsbCh0aGlzLCB2KTtcbiAgICAgICAgfVxuICAgICAgICA7XG4gICAgfTtcbiAgICByZXR1cm4gRmlsdGVyTWFwT3BlcmF0b3I7XG59KE1hcE9wZXJhdG9yKSk7XG5leHBvcnRzLkZpbHRlck1hcE9wZXJhdG9yID0gRmlsdGVyTWFwT3BlcmF0b3I7XG52YXIgUmVwbGFjZUVycm9yT3BlcmF0b3IgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFJlcGxhY2VFcnJvck9wZXJhdG9yKGZuLCBpbnMpIHtcbiAgICAgICAgdGhpcy5mbiA9IGZuO1xuICAgICAgICB0aGlzLmlucyA9IGlucztcbiAgICAgICAgdGhpcy50eXBlID0gJ3JlcGxhY2VFcnJvcic7XG4gICAgICAgIHRoaXMub3V0ID0gZW1wdHk7XG4gICAgfVxuICAgIFJlcGxhY2VFcnJvck9wZXJhdG9yLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAob3V0KSB7XG4gICAgICAgIHRoaXMub3V0ID0gb3V0O1xuICAgICAgICB0aGlzLmlucy5fYWRkKHRoaXMpO1xuICAgIH07XG4gICAgUmVwbGFjZUVycm9yT3BlcmF0b3IucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmlucy5fcmVtb3ZlKHRoaXMpO1xuICAgICAgICB0aGlzLm91dCA9IG51bGw7XG4gICAgfTtcbiAgICBSZXBsYWNlRXJyb3JPcGVyYXRvci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAoIXUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHUuX24odCk7XG4gICAgfTtcbiAgICBSZXBsYWNlRXJyb3JPcGVyYXRvci5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuaW5zLl9yZW1vdmUodGhpcyk7XG4gICAgICAgICAgICAodGhpcy5pbnMgPSB0aGlzLmZuKGVycikpLl9hZGQodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHUuX2UoZSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFJlcGxhY2VFcnJvck9wZXJhdG9yLnByb3RvdHlwZS5fYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9jKCk7XG4gICAgfTtcbiAgICByZXR1cm4gUmVwbGFjZUVycm9yT3BlcmF0b3I7XG59KCkpO1xuZXhwb3J0cy5SZXBsYWNlRXJyb3JPcGVyYXRvciA9IFJlcGxhY2VFcnJvck9wZXJhdG9yO1xudmFyIFN0YXJ0V2l0aE9wZXJhdG9yID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBTdGFydFdpdGhPcGVyYXRvcihpbnMsIHZhbHVlKSB7XG4gICAgICAgIHRoaXMuaW5zID0gaW5zO1xuICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgICAgIHRoaXMudHlwZSA9ICdzdGFydFdpdGgnO1xuICAgICAgICB0aGlzLm91dCA9IGV4cG9ydHMuZW1wdHlMaXN0ZW5lcjtcbiAgICB9XG4gICAgU3RhcnRXaXRoT3BlcmF0b3IucHJvdG90eXBlLl9zdGFydCA9IGZ1bmN0aW9uIChvdXQpIHtcbiAgICAgICAgdGhpcy5vdXQgPSBvdXQ7XG4gICAgICAgIHRoaXMub3V0Ll9uKHRoaXMudmFsdWUpO1xuICAgICAgICB0aGlzLmlucy5fYWRkKG91dCk7XG4gICAgfTtcbiAgICBTdGFydFdpdGhPcGVyYXRvci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuaW5zLl9yZW1vdmUodGhpcy5vdXQpO1xuICAgICAgICB0aGlzLm91dCA9IG51bGw7XG4gICAgfTtcbiAgICByZXR1cm4gU3RhcnRXaXRoT3BlcmF0b3I7XG59KCkpO1xuZXhwb3J0cy5TdGFydFdpdGhPcGVyYXRvciA9IFN0YXJ0V2l0aE9wZXJhdG9yO1xudmFyIFRha2VPcGVyYXRvciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gVGFrZU9wZXJhdG9yKG1heCwgaW5zKSB7XG4gICAgICAgIHRoaXMubWF4ID0gbWF4O1xuICAgICAgICB0aGlzLmlucyA9IGlucztcbiAgICAgICAgdGhpcy50eXBlID0gJ3Rha2UnO1xuICAgICAgICB0aGlzLm91dCA9IG51bGw7XG4gICAgICAgIHRoaXMudGFrZW4gPSAwO1xuICAgIH1cbiAgICBUYWtlT3BlcmF0b3IucHJvdG90eXBlLl9zdGFydCA9IGZ1bmN0aW9uIChvdXQpIHtcbiAgICAgICAgdGhpcy5vdXQgPSBvdXQ7XG4gICAgICAgIHRoaXMuaW5zLl9hZGQodGhpcyk7XG4gICAgfTtcbiAgICBUYWtlT3BlcmF0b3IucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmlucy5fcmVtb3ZlKHRoaXMpO1xuICAgICAgICB0aGlzLm91dCA9IG51bGw7XG4gICAgICAgIHRoaXMudGFrZW4gPSAwO1xuICAgIH07XG4gICAgVGFrZU9wZXJhdG9yLnByb3RvdHlwZS5fbiA9IGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgaWYgKHRoaXMudGFrZW4rKyA8IHRoaXMubWF4IC0gMSkge1xuICAgICAgICAgICAgdS5fbih0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHUuX24odCk7XG4gICAgICAgICAgICB1Ll9jKCk7XG4gICAgICAgICAgICB0aGlzLl9zdG9wKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFRha2VPcGVyYXRvci5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdS5fZShlcnIpO1xuICAgIH07XG4gICAgVGFrZU9wZXJhdG9yLnByb3RvdHlwZS5fYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9jKCk7XG4gICAgfTtcbiAgICByZXR1cm4gVGFrZU9wZXJhdG9yO1xufSgpKTtcbmV4cG9ydHMuVGFrZU9wZXJhdG9yID0gVGFrZU9wZXJhdG9yO1xudmFyIFN0cmVhbSA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gU3RyZWFtKHByb2R1Y2VyKSB7XG4gICAgICAgIHRoaXMuX3N0b3BJRCA9IGVtcHR5O1xuICAgICAgICB0aGlzLl9wcm9kID0gcHJvZHVjZXI7XG4gICAgICAgIHRoaXMuX2lscyA9IFtdO1xuICAgIH1cbiAgICBTdHJlYW0ucHJvdG90eXBlLl9uID0gZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgdmFyIGEgPSB0aGlzLl9pbHM7XG4gICAgICAgIHZhciBMID0gYS5sZW5ndGg7XG4gICAgICAgIGlmIChMID09IDEpXG4gICAgICAgICAgICBhWzBdLl9uKHQpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBiID0gY29weShhKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgTDsgaSsrKVxuICAgICAgICAgICAgICAgIGJbaV0uX24odCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFN0cmVhbS5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHZhciBhID0gdGhpcy5faWxzO1xuICAgICAgICB2YXIgTCA9IGEubGVuZ3RoO1xuICAgICAgICBpZiAoTCA9PSAxKVxuICAgICAgICAgICAgYVswXS5fZShlcnIpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBiID0gY29weShhKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgTDsgaSsrKVxuICAgICAgICAgICAgICAgIGJbaV0uX2UoZXJyKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl94KCk7XG4gICAgfTtcbiAgICBTdHJlYW0ucHJvdG90eXBlLl9jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgYSA9IHRoaXMuX2lscztcbiAgICAgICAgdmFyIEwgPSBhLmxlbmd0aDtcbiAgICAgICAgaWYgKEwgPT0gMSlcbiAgICAgICAgICAgIGFbMF0uX2MoKTtcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB2YXIgYiA9IGNvcHkoYSk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IEw7IGkrKylcbiAgICAgICAgICAgICAgICBiW2ldLl9jKCk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5feCgpO1xuICAgIH07XG4gICAgU3RyZWFtLnByb3RvdHlwZS5feCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2lscy5sZW5ndGggPT09IDApXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGlmICh0aGlzLl9wcm9kKVxuICAgICAgICAgICAgdGhpcy5fcHJvZC5fc3RvcCgpO1xuICAgICAgICB0aGlzLl9pbHMgPSBbXTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEFkZHMgYSBMaXN0ZW5lciB0byB0aGUgU3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtMaXN0ZW5lcjxUPn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBTdHJlYW0ucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24gKGxpc3RlbmVyKSB7XG4gICAgICAgIGlmICh0eXBlb2YgbGlzdGVuZXIubmV4dCAhPT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgfHwgdHlwZW9mIGxpc3RlbmVyLmVycm9yICE9PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICB8fCB0eXBlb2YgbGlzdGVuZXIuY29tcGxldGUgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignc3RyZWFtLmFkZExpc3RlbmVyKCkgcmVxdWlyZXMgYWxsIHRocmVlIG5leHQsIGVycm9yLCAnICtcbiAgICAgICAgICAgICAgICAnYW5kIGNvbXBsZXRlIGZ1bmN0aW9ucy4nKTtcbiAgICAgICAgfVxuICAgICAgICBsaXN0ZW5lci5fbiA9IGxpc3RlbmVyLm5leHQ7XG4gICAgICAgIGxpc3RlbmVyLl9lID0gbGlzdGVuZXIuZXJyb3I7XG4gICAgICAgIGxpc3RlbmVyLl9jID0gbGlzdGVuZXIuY29tcGxldGU7XG4gICAgICAgIHRoaXMuX2FkZChsaXN0ZW5lcik7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBSZW1vdmVzIGEgTGlzdGVuZXIgZnJvbSB0aGUgU3RyZWFtLCBhc3N1bWluZyB0aGUgTGlzdGVuZXIgd2FzIGFkZGVkIHRvIGl0LlxuICAgICAqXG4gICAgICogQHBhcmFtIHtMaXN0ZW5lcjxUPn0gbGlzdGVuZXJcbiAgICAgKi9cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlbW92ZUxpc3RlbmVyID0gZnVuY3Rpb24gKGxpc3RlbmVyKSB7XG4gICAgICAgIHRoaXMuX3JlbW92ZShsaXN0ZW5lcik7XG4gICAgfTtcbiAgICBTdHJlYW0ucHJvdG90eXBlLl9hZGQgPSBmdW5jdGlvbiAoaWwpIHtcbiAgICAgICAgdmFyIGEgPSB0aGlzLl9pbHM7XG4gICAgICAgIGEucHVzaChpbCk7XG4gICAgICAgIGlmIChhLmxlbmd0aCA9PT0gMSkge1xuICAgICAgICAgICAgaWYgKHRoaXMuX3N0b3BJRCAhPT0gZW1wdHkpIHtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5fc3RvcElEKTtcbiAgICAgICAgICAgICAgICB0aGlzLl9zdG9wSUQgPSBlbXB0eTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHZhciBwID0gdGhpcy5fcHJvZDtcbiAgICAgICAgICAgIGlmIChwKVxuICAgICAgICAgICAgICAgIHAuX3N0YXJ0KHRoaXMpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBTdHJlYW0ucHJvdG90eXBlLl9yZW1vdmUgPSBmdW5jdGlvbiAoaWwpIHtcbiAgICAgICAgdmFyIGEgPSB0aGlzLl9pbHM7XG4gICAgICAgIHZhciBpID0gYS5pbmRleE9mKGlsKTtcbiAgICAgICAgaWYgKGkgPiAtMSkge1xuICAgICAgICAgICAgYS5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICB2YXIgcF8xID0gdGhpcy5fcHJvZDtcbiAgICAgICAgICAgIGlmIChwXzEgJiYgYS5sZW5ndGggPD0gMCkge1xuICAgICAgICAgICAgICAgIHRoaXMuX3N0b3BJRCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyByZXR1cm4gcF8xLl9zdG9wKCk7IH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBTdHJlYW0ucHJvdG90eXBlLmN0b3IgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzIGluc3RhbmNlb2YgTWVtb3J5U3RyZWFtID8gTWVtb3J5U3RyZWFtIDogU3RyZWFtO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBTdHJlYW0gZ2l2ZW4gYSBQcm9kdWNlci5cbiAgICAgKlxuICAgICAqIEBmYWN0b3J5IHRydWVcbiAgICAgKiBAcGFyYW0ge1Byb2R1Y2VyfSBwcm9kdWNlciBBbiBvcHRpb25hbCBQcm9kdWNlciB0aGF0IGRpY3RhdGVzIGhvdyB0b1xuICAgICAqIHN0YXJ0LCBnZW5lcmF0ZSBldmVudHMsIGFuZCBzdG9wIHRoZSBTdHJlYW0uXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5jcmVhdGUgPSBmdW5jdGlvbiAocHJvZHVjZXIpIHtcbiAgICAgICAgaWYgKHByb2R1Y2VyKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHByb2R1Y2VyLnN0YXJ0ICE9PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgICAgfHwgdHlwZW9mIHByb2R1Y2VyLnN0b3AgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2R1Y2VyIHJlcXVpcmVzIGJvdGggc3RhcnQgYW5kIHN0b3AgZnVuY3Rpb25zJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbnRlcm5hbGl6ZVByb2R1Y2VyKHByb2R1Y2VyKTsgLy8gbXV0YXRlcyB0aGUgaW5wdXRcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFN0cmVhbShwcm9kdWNlcik7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IE1lbW9yeVN0cmVhbSBnaXZlbiBhIFByb2R1Y2VyLlxuICAgICAqXG4gICAgICogQGZhY3RvcnkgdHJ1ZVxuICAgICAqIEBwYXJhbSB7UHJvZHVjZXJ9IHByb2R1Y2VyIEFuIG9wdGlvbmFsIFByb2R1Y2VyIHRoYXQgZGljdGF0ZXMgaG93IHRvXG4gICAgICogc3RhcnQsIGdlbmVyYXRlIGV2ZW50cywgYW5kIHN0b3AgdGhlIFN0cmVhbS5cbiAgICAgKiBAcmV0dXJuIHtNZW1vcnlTdHJlYW19XG4gICAgICovXG4gICAgU3RyZWFtLmNyZWF0ZVdpdGhNZW1vcnkgPSBmdW5jdGlvbiAocHJvZHVjZXIpIHtcbiAgICAgICAgaWYgKHByb2R1Y2VyKSB7XG4gICAgICAgICAgICBpbnRlcm5hbGl6ZVByb2R1Y2VyKHByb2R1Y2VyKTsgLy8gbXV0YXRlcyB0aGUgaW5wdXRcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IE1lbW9yeVN0cmVhbShwcm9kdWNlcik7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IE1pbWljU3RyZWFtLCB3aGljaCBjYW4gYGltaXRhdGVgIGFub3RoZXIgU3RyZWFtLiBPbmx5IGFcbiAgICAgKiBNaW1pY1N0cmVhbSBoYXMgdGhlIGBpbWl0YXRlKClgIG1ldGhvZC5cbiAgICAgKlxuICAgICAqIEBmYWN0b3J5IHRydWVcbiAgICAgKiBAcmV0dXJuIHtNaW1pY1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0uY3JlYXRlTWltaWMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgTWltaWNTdHJlYW0oKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBTdHJlYW0gdGhhdCBkb2VzIG5vdGhpbmcgd2hlbiBzdGFydGVkLiBJdCBuZXZlciBlbWl0cyBhbnkgZXZlbnQuXG4gICAgICpcbiAgICAgKiBNYXJibGUgZGlhZ3JhbTpcbiAgICAgKlxuICAgICAqIGBgYHRleHRcbiAgICAgKiAgICAgICAgICBuZXZlclxuICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAZmFjdG9yeSB0cnVlXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5uZXZlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTdHJlYW0oeyBfc3RhcnQ6IG5vb3AsIF9zdG9wOiBub29wIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIFN0cmVhbSB0aGF0IGltbWVkaWF0ZWx5IGVtaXRzIHRoZSBcImNvbXBsZXRlXCIgbm90aWZpY2F0aW9uIHdoZW5cbiAgICAgKiBzdGFydGVkLCBhbmQgdGhhdCdzIGl0LlxuICAgICAqXG4gICAgICogTWFyYmxlIGRpYWdyYW06XG4gICAgICpcbiAgICAgKiBgYGB0ZXh0XG4gICAgICogZW1wdHlcbiAgICAgKiAtfFxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQGZhY3RvcnkgdHJ1ZVxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0uZW1wdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RyZWFtKHtcbiAgICAgICAgICAgIF9zdGFydDogZnVuY3Rpb24gKGlsKSB7IGlsLl9jKCk7IH0sXG4gICAgICAgICAgICBfc3RvcDogbm9vcCxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgU3RyZWFtIHRoYXQgaW1tZWRpYXRlbHkgZW1pdHMgYW4gXCJlcnJvclwiIG5vdGlmaWNhdGlvbiB3aXRoIHRoZVxuICAgICAqIHZhbHVlIHlvdSBwYXNzZWQgYXMgdGhlIGBlcnJvcmAgYXJndW1lbnQgd2hlbiB0aGUgc3RyZWFtIHN0YXJ0cywgYW5kIHRoYXQnc1xuICAgICAqIGl0LlxuICAgICAqXG4gICAgICogTWFyYmxlIGRpYWdyYW06XG4gICAgICpcbiAgICAgKiBgYGB0ZXh0XG4gICAgICogdGhyb3coWClcbiAgICAgKiAtWFxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQGZhY3RvcnkgdHJ1ZVxuICAgICAqIEBwYXJhbSBlcnJvciBUaGUgZXJyb3IgZXZlbnQgdG8gZW1pdCBvbiB0aGUgY3JlYXRlZCBzdHJlYW0uXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS50aHJvdyA9IGZ1bmN0aW9uIChlcnJvcikge1xuICAgICAgICByZXR1cm4gbmV3IFN0cmVhbSh7XG4gICAgICAgICAgICBfc3RhcnQ6IGZ1bmN0aW9uIChpbCkgeyBpbC5fZShlcnJvcik7IH0sXG4gICAgICAgICAgICBfc3RvcDogbm9vcCxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgU3RyZWFtIHRoYXQgaW1tZWRpYXRlbHkgZW1pdHMgdGhlIGFyZ3VtZW50cyB0aGF0IHlvdSBnaXZlIHRvXG4gICAgICogKm9mKiwgdGhlbiBjb21wbGV0ZXMuXG4gICAgICpcbiAgICAgKiBNYXJibGUgZGlhZ3JhbTpcbiAgICAgKlxuICAgICAqIGBgYHRleHRcbiAgICAgKiBvZigxLDIsMylcbiAgICAgKiAxMjN8XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAZmFjdG9yeSB0cnVlXG4gICAgICogQHBhcmFtIGEgVGhlIGZpcnN0IHZhbHVlIHlvdSB3YW50IHRvIGVtaXQgYXMgYW4gZXZlbnQgb24gdGhlIHN0cmVhbS5cbiAgICAgKiBAcGFyYW0gYiBUaGUgc2Vjb25kIHZhbHVlIHlvdSB3YW50IHRvIGVtaXQgYXMgYW4gZXZlbnQgb24gdGhlIHN0cmVhbS4gT25lXG4gICAgICogb3IgbW9yZSBvZiB0aGVzZSB2YWx1ZXMgbWF5IGJlIGdpdmVuIGFzIGFyZ3VtZW50cy5cbiAgICAgKiBAcmV0dXJuIHtTdHJlYW19XG4gICAgICovXG4gICAgU3RyZWFtLm9mID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgaXRlbXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIGl0ZW1zW19pIC0gMF0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBTdHJlYW0uZnJvbUFycmF5KGl0ZW1zKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGFuIGFycmF5IHRvIGEgc3RyZWFtLiBUaGUgcmV0dXJuZWQgc3RyZWFtIHdpbGwgZW1pdCBzeW5jaHJvbm91c2x5XG4gICAgICogYWxsIHRoZSBpdGVtcyBpbiB0aGUgYXJyYXksIGFuZCB0aGVuIGNvbXBsZXRlLlxuICAgICAqXG4gICAgICogTWFyYmxlIGRpYWdyYW06XG4gICAgICpcbiAgICAgKiBgYGB0ZXh0XG4gICAgICogZnJvbUFycmF5KFsxLDIsM10pXG4gICAgICogMTIzfFxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQGZhY3RvcnkgdHJ1ZVxuICAgICAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IFRoZSBhcnJheSB0byBiZSBjb252ZXJ0ZWQgYXMgYSBzdHJlYW0uXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5mcm9tQXJyYXkgPSBmdW5jdGlvbiAoYXJyYXkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTdHJlYW0obmV3IEZyb21BcnJheVByb2R1Y2VyKGFycmF5KSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBhIHByb21pc2UgdG8gYSBzdHJlYW0uIFRoZSByZXR1cm5lZCBzdHJlYW0gd2lsbCBlbWl0IHRoZSByZXNvbHZlZFxuICAgICAqIHZhbHVlIG9mIHRoZSBwcm9taXNlLCBhbmQgdGhlbiBjb21wbGV0ZS4gSG93ZXZlciwgaWYgdGhlIHByb21pc2UgaXNcbiAgICAgKiByZWplY3RlZCwgdGhlIHN0cmVhbSB3aWxsIGVtaXQgdGhlIGNvcnJlc3BvbmRpbmcgZXJyb3IuXG4gICAgICpcbiAgICAgKiBNYXJibGUgZGlhZ3JhbTpcbiAgICAgKlxuICAgICAqIGBgYHRleHRcbiAgICAgKiBmcm9tUHJvbWlzZSggLS0tLTQyIClcbiAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLTQyfFxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQGZhY3RvcnkgdHJ1ZVxuICAgICAqIEBwYXJhbSB7UHJvbWlzZX0gcHJvbWlzZSBUaGUgcHJvbWlzZSB0byBiZSBjb252ZXJ0ZWQgYXMgYSBzdHJlYW0uXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5mcm9tUHJvbWlzZSA9IGZ1bmN0aW9uIChwcm9taXNlKSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RyZWFtKG5ldyBGcm9tUHJvbWlzZVByb2R1Y2VyKHByb21pc2UpKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBzdHJlYW0gdGhhdCBwZXJpb2RpY2FsbHkgZW1pdHMgaW5jcmVtZW50YWwgbnVtYmVycywgZXZlcnlcbiAgICAgKiBgcGVyaW9kYCBtaWxsaXNlY29uZHMuXG4gICAgICpcbiAgICAgKiBNYXJibGUgZGlhZ3JhbTpcbiAgICAgKlxuICAgICAqIGBgYHRleHRcbiAgICAgKiAgICAgcGVyaW9kaWMoMTAwMClcbiAgICAgKiAtLS0wLS0tMS0tLTItLS0zLS0tNC0tLS4uLlxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQGZhY3RvcnkgdHJ1ZVxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBwZXJpb2QgVGhlIGludGVydmFsIGluIG1pbGxpc2Vjb25kcyB0byB1c2UgYXMgYSByYXRlIG9mXG4gICAgICogZW1pc3Npb24uXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5wZXJpb2RpYyA9IGZ1bmN0aW9uIChwZXJpb2QpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTdHJlYW0obmV3IFBlcmlvZGljUHJvZHVjZXIocGVyaW9kKSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBCbGVuZHMgbXVsdGlwbGUgc3RyZWFtcyB0b2dldGhlciwgZW1pdHRpbmcgZXZlbnRzIGZyb20gYWxsIG9mIHRoZW1cbiAgICAgKiBjb25jdXJyZW50bHkuXG4gICAgICpcbiAgICAgKiAqbWVyZ2UqIHRha2VzIG11bHRpcGxlIHN0cmVhbXMgYXMgYXJndW1lbnRzLCBhbmQgY3JlYXRlcyBhIHN0cmVhbSB0aGF0XG4gICAgICogYmVoYXZlcyBsaWtlIGVhY2ggb2YgdGhlIGFyZ3VtZW50IHN0cmVhbXMsIGluIHBhcmFsbGVsLlxuICAgICAqXG4gICAgICogTWFyYmxlIGRpYWdyYW06XG4gICAgICpcbiAgICAgKiBgYGB0ZXh0XG4gICAgICogLS0xLS0tLTItLS0tLTMtLS0tLS0tLTQtLS1cbiAgICAgKiAtLS0tYS0tLS0tYi0tLS1jLS0tZC0tLS0tLVxuICAgICAqICAgICAgICAgICAgbWVyZ2VcbiAgICAgKiAtLTEtYS0tMi0tYi0tMy1jLS0tZC0tNC0tLVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQGZhY3RvcnkgdHJ1ZVxuICAgICAqIEBwYXJhbSB7U3RyZWFtfSBzdHJlYW0xIEEgc3RyZWFtIHRvIG1lcmdlIHRvZ2V0aGVyIHdpdGggb3RoZXIgc3RyZWFtcy5cbiAgICAgKiBAcGFyYW0ge1N0cmVhbX0gc3RyZWFtMiBBIHN0cmVhbSB0byBtZXJnZSB0b2dldGhlciB3aXRoIG90aGVyIHN0cmVhbXMuIFR3b1xuICAgICAqIG9yIG1vcmUgc3RyZWFtcyBtYXkgYmUgZ2l2ZW4gYXMgYXJndW1lbnRzLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0ubWVyZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBzdHJlYW1zID0gW107XG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICBzdHJlYW1zW19pIC0gMF0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgU3RyZWFtKG5ldyBNZXJnZVByb2R1Y2VyKHN0cmVhbXMpKTtcbiAgICB9O1xuICAgIFN0cmVhbS5wcm90b3R5cGUuX21hcCA9IGZ1bmN0aW9uIChwcm9qZWN0KSB7XG4gICAgICAgIHZhciBwID0gdGhpcy5fcHJvZDtcbiAgICAgICAgdmFyIGN0b3IgPSB0aGlzLmN0b3IoKTtcbiAgICAgICAgaWYgKHAgaW5zdGFuY2VvZiBGaWx0ZXJPcGVyYXRvcikge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBjdG9yKG5ldyBGaWx0ZXJNYXBPcGVyYXRvcihwLnBhc3NlcywgcHJvamVjdCwgcC5pbnMpKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocCBpbnN0YW5jZW9mIEZpbHRlck1hcE9wZXJhdG9yKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGN0b3IobmV3IEZpbHRlck1hcE9wZXJhdG9yKHAucGFzc2VzLCBjb21wb3NlMihwcm9qZWN0LCBwLnByb2plY3QpLCBwLmlucykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwIGluc3RhbmNlb2YgTWFwT3BlcmF0b3IpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgY3RvcihuZXcgTWFwT3BlcmF0b3IoY29tcG9zZTIocHJvamVjdCwgcC5wcm9qZWN0KSwgcC5pbnMpKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IGN0b3IobmV3IE1hcE9wZXJhdG9yKHByb2plY3QsIHRoaXMpKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIFRyYW5zZm9ybXMgZWFjaCBldmVudCBmcm9tIHRoZSBpbnB1dCBTdHJlYW0gdGhyb3VnaCBhIGBwcm9qZWN0YCBmdW5jdGlvbixcbiAgICAgKiB0byBnZXQgYSBTdHJlYW0gdGhhdCBlbWl0cyB0aG9zZSB0cmFuc2Zvcm1lZCBldmVudHMuXG4gICAgICpcbiAgICAgKiBNYXJibGUgZGlhZ3JhbTpcbiAgICAgKlxuICAgICAqIGBgYHRleHRcbiAgICAgKiAtLTEtLS0zLS01LS0tLS03LS0tLS0tXG4gICAgICogICAgbWFwKGkgPT4gaSAqIDEwKVxuICAgICAqIC0tMTAtLTMwLTUwLS0tLTcwLS0tLS1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByb2plY3QgQSBmdW5jdGlvbiBvZiB0eXBlIGAodDogVCkgPT4gVWAgdGhhdCB0YWtlcyBldmVudFxuICAgICAqIGB0YCBvZiB0eXBlIGBUYCBmcm9tIHRoZSBpbnB1dCBTdHJlYW0gYW5kIHByb2R1Y2VzIGFuIGV2ZW50IG9mIHR5cGUgYFVgLCB0b1xuICAgICAqIGJlIGVtaXR0ZWQgb24gdGhlIG91dHB1dCBTdHJlYW0uXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5wcm90b3R5cGUubWFwID0gZnVuY3Rpb24gKHByb2plY3QpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX21hcChwcm9qZWN0KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEl0J3MgbGlrZSBgbWFwYCwgYnV0IHRyYW5zZm9ybXMgZWFjaCBpbnB1dCBldmVudCB0byBhbHdheXMgdGhlIHNhbWVcbiAgICAgKiBjb25zdGFudCB2YWx1ZSBvbiB0aGUgb3V0cHV0IFN0cmVhbS5cbiAgICAgKlxuICAgICAqIE1hcmJsZSBkaWFncmFtOlxuICAgICAqXG4gICAgICogYGBgdGV4dFxuICAgICAqIC0tMS0tLTMtLTUtLS0tLTctLS0tLVxuICAgICAqICAgICAgIG1hcFRvKDEwKVxuICAgICAqIC0tMTAtLTEwLTEwLS0tLTEwLS0tLVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHByb2plY3RlZFZhbHVlIEEgdmFsdWUgdG8gZW1pdCBvbiB0aGUgb3V0cHV0IFN0cmVhbSB3aGVuZXZlciB0aGVcbiAgICAgKiBpbnB1dCBTdHJlYW0gZW1pdHMgYW55IHZhbHVlLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0ucHJvdG90eXBlLm1hcFRvID0gZnVuY3Rpb24gKHByb2plY3RlZFZhbHVlKSB7XG4gICAgICAgIHZhciBzID0gdGhpcy5tYXAoZnVuY3Rpb24gKCkgeyByZXR1cm4gcHJvamVjdGVkVmFsdWU7IH0pO1xuICAgICAgICB2YXIgb3AgPSBzLl9wcm9kO1xuICAgICAgICBvcC50eXBlID0gb3AudHlwZS5yZXBsYWNlKCdtYXAnLCAnbWFwVG8nKTtcbiAgICAgICAgcmV0dXJuIHM7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBPbmx5IGFsbG93cyBldmVudHMgdGhhdCBwYXNzIHRoZSB0ZXN0IGdpdmVuIGJ5IHRoZSBgcGFzc2VzYCBhcmd1bWVudC5cbiAgICAgKlxuICAgICAqIEVhY2ggZXZlbnQgZnJvbSB0aGUgaW5wdXQgc3RyZWFtIGlzIGdpdmVuIHRvIHRoZSBgcGFzc2VzYCBmdW5jdGlvbi4gSWYgdGhlXG4gICAgICogZnVuY3Rpb24gcmV0dXJucyBgdHJ1ZWAsIHRoZSBldmVudCBpcyBmb3J3YXJkZWQgdG8gdGhlIG91dHB1dCBzdHJlYW0sXG4gICAgICogb3RoZXJ3aXNlIGl0IGlzIGlnbm9yZWQgYW5kIG5vdCBmb3J3YXJkZWQuXG4gICAgICpcbiAgICAgKiBNYXJibGUgZGlhZ3JhbTpcbiAgICAgKlxuICAgICAqIGBgYHRleHRcbiAgICAgKiAtLTEtLS0yLS0zLS0tLS00LS0tLS01LS0tNi0tNy04LS1cbiAgICAgKiAgICAgZmlsdGVyKGkgPT4gaSAlIDIgPT09IDApXG4gICAgICogLS0tLS0tMi0tLS0tLS0tNC0tLS0tLS0tLTYtLS0tOC0tXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwYXNzZXMgQSBmdW5jdGlvbiBvZiB0eXBlIGAodDogVCkgKz4gYm9vbGVhbmAgdGhhdCB0YWtlc1xuICAgICAqIGFuIGV2ZW50IGZyb20gdGhlIGlucHV0IHN0cmVhbSBhbmQgY2hlY2tzIGlmIGl0IHBhc3NlcywgYnkgcmV0dXJuaW5nIGFcbiAgICAgKiBib29sZWFuLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0ucHJvdG90eXBlLmZpbHRlciA9IGZ1bmN0aW9uIChwYXNzZXMpIHtcbiAgICAgICAgdmFyIHAgPSB0aGlzLl9wcm9kO1xuICAgICAgICBpZiAocCBpbnN0YW5jZW9mIEZpbHRlck9wZXJhdG9yKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFN0cmVhbShuZXcgRmlsdGVyT3BlcmF0b3IoYW5kKHBhc3NlcywgcC5wYXNzZXMpLCBwLmlucykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgU3RyZWFtKG5ldyBGaWx0ZXJPcGVyYXRvcihwYXNzZXMsIHRoaXMpKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIExldHMgdGhlIGZpcnN0IGBhbW91bnRgIG1hbnkgZXZlbnRzIGZyb20gdGhlIGlucHV0IHN0cmVhbSBwYXNzIHRvIHRoZVxuICAgICAqIG91dHB1dCBzdHJlYW0sIHRoZW4gbWFrZXMgdGhlIG91dHB1dCBzdHJlYW0gY29tcGxldGUuXG4gICAgICpcbiAgICAgKiBNYXJibGUgZGlhZ3JhbTpcbiAgICAgKlxuICAgICAqIGBgYHRleHRcbiAgICAgKiAtLWEtLS1iLS1jLS0tLWQtLS1lLS1cbiAgICAgKiAgICB0YWtlKDMpXG4gICAgICogLS1hLS0tYi0tY3xcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7bnVtYmVyfSBhbW91bnQgSG93IG1hbnkgZXZlbnRzIHRvIGFsbG93IGZyb20gdGhlIGlucHV0IHN0cmVhbVxuICAgICAqIGJlZm9yZSBjb21wbGV0aW5nIHRoZSBvdXRwdXQgc3RyZWFtLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0ucHJvdG90eXBlLnRha2UgPSBmdW5jdGlvbiAoYW1vdW50KSB7XG4gICAgICAgIHJldHVybiBuZXcgKHRoaXMuY3RvcigpKShuZXcgVGFrZU9wZXJhdG9yKGFtb3VudCwgdGhpcykpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogSWdub3JlcyB0aGUgZmlyc3QgYGFtb3VudGAgbWFueSBldmVudHMgZnJvbSB0aGUgaW5wdXQgc3RyZWFtLCBhbmQgdGhlblxuICAgICAqIGFmdGVyIHRoYXQgc3RhcnRzIGZvcndhcmRpbmcgZXZlbnRzIGZyb20gdGhlIGlucHV0IHN0cmVhbSB0byB0aGUgb3V0cHV0XG4gICAgICogc3RyZWFtLlxuICAgICAqXG4gICAgICogTWFyYmxlIGRpYWdyYW06XG4gICAgICpcbiAgICAgKiBgYGB0ZXh0XG4gICAgICogLS1hLS0tYi0tYy0tLS1kLS0tZS0tXG4gICAgICogICAgICAgZHJvcCgzKVxuICAgICAqIC0tLS0tLS0tLS0tLS0tZC0tLWUtLVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGFtb3VudCBIb3cgbWFueSBldmVudHMgdG8gaWdub3JlIGZyb20gdGhlIGlucHV0IHN0cmVhbVxuICAgICAqIGJlZm9yZSBmb3J3YXJkaW5nIGFsbCBldmVudHMgZnJvbSB0aGUgaW5wdXQgc3RyZWFtIHRvIHRoZSBvdXRwdXQgc3RyZWFtLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0ucHJvdG90eXBlLmRyb3AgPSBmdW5jdGlvbiAoYW1vdW50KSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RyZWFtKG5ldyBEcm9wT3BlcmF0b3IoYW1vdW50LCB0aGlzKSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBXaGVuIHRoZSBpbnB1dCBzdHJlYW0gY29tcGxldGVzLCB0aGUgb3V0cHV0IHN0cmVhbSB3aWxsIGVtaXQgdGhlIGxhc3QgZXZlbnRcbiAgICAgKiBlbWl0dGVkIGJ5IHRoZSBpbnB1dCBzdHJlYW0sIGFuZCB0aGVuIHdpbGwgYWxzbyBjb21wbGV0ZS5cbiAgICAgKlxuICAgICAqIE1hcmJsZSBkaWFncmFtOlxuICAgICAqXG4gICAgICogYGBgdGV4dFxuICAgICAqIC0tYS0tLWItLWMtLWQtLS0tfFxuICAgICAqICAgICAgIGxhc3QoKVxuICAgICAqIC0tLS0tLS0tLS0tLS0tLS0tZHxcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0ucHJvdG90eXBlLmxhc3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RyZWFtKG5ldyBMYXN0T3BlcmF0b3IodGhpcykpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogUHJlcGVuZHMgdGhlIGdpdmVuIGBpbml0aWFsYCB2YWx1ZSB0byB0aGUgc2VxdWVuY2Ugb2YgZXZlbnRzIGVtaXR0ZWQgYnkgdGhlXG4gICAgICogaW5wdXQgc3RyZWFtLiBUaGUgcmV0dXJuZWQgc3RyZWFtIGlzIGEgTWVtb3J5U3RyZWFtLCB3aGljaCBtZWFucyBpdCBpc1xuICAgICAqIGFscmVhZHkgYHJlbWVtYmVyKClgJ2QuXG4gICAgICpcbiAgICAgKiBNYXJibGUgZGlhZ3JhbTpcbiAgICAgKlxuICAgICAqIGBgYHRleHRcbiAgICAgKiAtLS0xLS0tMi0tLS0tMy0tLVxuICAgICAqICAgc3RhcnRXaXRoKDApXG4gICAgICogMC0tMS0tLTItLS0tLTMtLS1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSBpbml0aWFsIFRoZSB2YWx1ZSBvciBldmVudCB0byBwcmVwZW5kLlxuICAgICAqIEByZXR1cm4ge01lbW9yeVN0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0ucHJvdG90eXBlLnN0YXJ0V2l0aCA9IGZ1bmN0aW9uIChpbml0aWFsKSB7XG4gICAgICAgIHJldHVybiBuZXcgTWVtb3J5U3RyZWFtKG5ldyBTdGFydFdpdGhPcGVyYXRvcih0aGlzLCBpbml0aWFsKSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBVc2VzIGFub3RoZXIgc3RyZWFtIHRvIGRldGVybWluZSB3aGVuIHRvIGNvbXBsZXRlIHRoZSBjdXJyZW50IHN0cmVhbS5cbiAgICAgKlxuICAgICAqIFdoZW4gdGhlIGdpdmVuIGBvdGhlcmAgc3RyZWFtIGVtaXRzIGFuIGV2ZW50IG9yIGNvbXBsZXRlcywgdGhlIG91dHB1dFxuICAgICAqIHN0cmVhbSB3aWxsIGNvbXBsZXRlLiBCZWZvcmUgdGhhdCBoYXBwZW5zLCB0aGUgb3V0cHV0IHN0cmVhbSB3aWxsIGJlaGF2ZXNcbiAgICAgKiBsaWtlIHRoZSBpbnB1dCBzdHJlYW0uXG4gICAgICpcbiAgICAgKiBNYXJibGUgZGlhZ3JhbTpcbiAgICAgKlxuICAgICAqIGBgYHRleHRcbiAgICAgKiAtLS0xLS0tMi0tLS0tMy0tNC0tLS01LS0tLTYtLS1cbiAgICAgKiAgIGVuZFdoZW4oIC0tLS0tLS0tYS0tYi0tfCApXG4gICAgICogLS0tMS0tLTItLS0tLTMtLTQtLXxcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSBvdGhlciBTb21lIG90aGVyIHN0cmVhbSB0aGF0IGlzIHVzZWQgdG8ga25vdyB3aGVuIHNob3VsZCB0aGUgb3V0cHV0XG4gICAgICogc3RyZWFtIG9mIHRoaXMgb3BlcmF0b3IgY29tcGxldGUuXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5wcm90b3R5cGUuZW5kV2hlbiA9IGZ1bmN0aW9uIChvdGhlcikge1xuICAgICAgICByZXR1cm4gbmV3ICh0aGlzLmN0b3IoKSkobmV3IEVuZFdoZW5PcGVyYXRvcihvdGhlciwgdGhpcykpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogXCJGb2xkc1wiIHRoZSBzdHJlYW0gb250byBpdHNlbGYuXG4gICAgICpcbiAgICAgKiBDb21iaW5lcyBldmVudHMgZnJvbSB0aGUgcGFzdCB0aHJvdWdob3V0XG4gICAgICogdGhlIGVudGlyZSBleGVjdXRpb24gb2YgdGhlIGlucHV0IHN0cmVhbSwgYWxsb3dpbmcgeW91IHRvIGFjY3VtdWxhdGUgdGhlbVxuICAgICAqIHRvZ2V0aGVyLiBJdCdzIGVzc2VudGlhbGx5IGxpa2UgYEFycmF5LnByb3RvdHlwZS5yZWR1Y2VgLiBUaGUgcmV0dXJuZWRcbiAgICAgKiBzdHJlYW0gaXMgYSBNZW1vcnlTdHJlYW0sIHdoaWNoIG1lYW5zIGl0IGlzIGFscmVhZHkgYHJlbWVtYmVyKClgJ2QuXG4gICAgICpcbiAgICAgKiBUaGUgb3V0cHV0IHN0cmVhbSBzdGFydHMgYnkgZW1pdHRpbmcgdGhlIGBzZWVkYCB3aGljaCB5b3UgZ2l2ZSBhcyBhcmd1bWVudC5cbiAgICAgKiBUaGVuLCB3aGVuIGFuIGV2ZW50IGhhcHBlbnMgb24gdGhlIGlucHV0IHN0cmVhbSwgaXQgaXMgY29tYmluZWQgd2l0aCB0aGF0XG4gICAgICogc2VlZCB2YWx1ZSB0aHJvdWdoIHRoZSBgYWNjdW11bGF0ZWAgZnVuY3Rpb24sIGFuZCB0aGUgb3V0cHV0IHZhbHVlIGlzXG4gICAgICogZW1pdHRlZCBvbiB0aGUgb3V0cHV0IHN0cmVhbS4gYGZvbGRgIHJlbWVtYmVycyB0aGF0IG91dHB1dCB2YWx1ZSBhcyBgYWNjYFxuICAgICAqIChcImFjY3VtdWxhdG9yXCIpLCBhbmQgdGhlbiB3aGVuIGEgbmV3IGlucHV0IGV2ZW50IGB0YCBoYXBwZW5zLCBgYWNjYCB3aWxsIGJlXG4gICAgICogY29tYmluZWQgd2l0aCB0aGF0IHRvIHByb2R1Y2UgdGhlIG5ldyBgYWNjYCBhbmQgc28gZm9ydGguXG4gICAgICpcbiAgICAgKiBNYXJibGUgZGlhZ3JhbTpcbiAgICAgKlxuICAgICAqIGBgYHRleHRcbiAgICAgKiAtLS0tLS0xLS0tLS0xLS0yLS0tLTEtLS0tMS0tLS0tLVxuICAgICAqICAgZm9sZCgoYWNjLCB4KSA9PiBhY2MgKyB4LCAzKVxuICAgICAqIDMtLS0tLTQtLS0tLTUtLTctLS0tOC0tLS05LS0tLS0tXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBhY2N1bXVsYXRlIEEgZnVuY3Rpb24gb2YgdHlwZSBgKGFjYzogUiwgdDogVCkgPT4gUmAgdGhhdFxuICAgICAqIHRha2VzIHRoZSBwcmV2aW91cyBhY2N1bXVsYXRlZCB2YWx1ZSBgYWNjYCBhbmQgdGhlIGluY29taW5nIGV2ZW50IGZyb20gdGhlXG4gICAgICogaW5wdXQgc3RyZWFtIGFuZCBwcm9kdWNlcyB0aGUgbmV3IGFjY3VtdWxhdGVkIHZhbHVlLlxuICAgICAqIEBwYXJhbSBzZWVkIFRoZSBpbml0aWFsIGFjY3VtdWxhdGVkIHZhbHVlLCBvZiB0eXBlIGBSYC5cbiAgICAgKiBAcmV0dXJuIHtNZW1vcnlTdHJlYW19XG4gICAgICovXG4gICAgU3RyZWFtLnByb3RvdHlwZS5mb2xkID0gZnVuY3Rpb24gKGFjY3VtdWxhdGUsIHNlZWQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBNZW1vcnlTdHJlYW0obmV3IEZvbGRPcGVyYXRvcihhY2N1bXVsYXRlLCBzZWVkLCB0aGlzKSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBSZXBsYWNlcyBhbiBlcnJvciB3aXRoIGFub3RoZXIgc3RyZWFtLlxuICAgICAqXG4gICAgICogV2hlbiAoYW5kIGlmKSBhbiBlcnJvciBoYXBwZW5zIG9uIHRoZSBpbnB1dCBzdHJlYW0sIGluc3RlYWQgb2YgZm9yd2FyZGluZ1xuICAgICAqIHRoYXQgZXJyb3IgdG8gdGhlIG91dHB1dCBzdHJlYW0sICpyZXBsYWNlRXJyb3IqIHdpbGwgY2FsbCB0aGUgYHJlcGxhY2VgXG4gICAgICogZnVuY3Rpb24gd2hpY2ggcmV0dXJucyB0aGUgc3RyZWFtIHRoYXQgdGhlIG91dHB1dCBzdHJlYW0gd2lsbCByZXBsaWNhdGUuXG4gICAgICogQW5kLCBpbiBjYXNlIHRoYXQgbmV3IHN0cmVhbSBhbHNvIGVtaXRzIGFuIGVycm9yLCBgcmVwbGFjZWAgd2lsbCBiZSBjYWxsZWRcbiAgICAgKiBhZ2FpbiB0byBnZXQgYW5vdGhlciBzdHJlYW0gdG8gc3RhcnQgcmVwbGljYXRpbmcuXG4gICAgICpcbiAgICAgKiBNYXJibGUgZGlhZ3JhbTpcbiAgICAgKlxuICAgICAqIGBgYHRleHRcbiAgICAgKiAtLTEtLS0yLS0tLS0zLS00LS0tLS1YXG4gICAgICogICByZXBsYWNlRXJyb3IoICgpID0+IC0tMTAtLXwgKVxuICAgICAqIC0tMS0tLTItLS0tLTMtLTQtLS0tLS0tLTEwLS18XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSByZXBsYWNlIEEgZnVuY3Rpb24gb2YgdHlwZSBgKGVycikgPT4gU3RyZWFtYCB0aGF0IHRha2VzXG4gICAgICogdGhlIGVycm9yIHRoYXQgb2NjdXJyZWQgb24gdGhlIGlucHV0IHN0cmVhbSBvciBvbiB0aGUgcHJldmlvdXMgcmVwbGFjZW1lbnRcbiAgICAgKiBzdHJlYW0gYW5kIHJldHVybnMgYSBuZXcgc3RyZWFtLiBUaGUgb3V0cHV0IHN0cmVhbSB3aWxsIGJlaGF2ZSBsaWtlIHRoZVxuICAgICAqIHN0cmVhbSB0aGF0IHRoaXMgZnVuY3Rpb24gcmV0dXJucy5cbiAgICAgKiBAcmV0dXJuIHtTdHJlYW19XG4gICAgICovXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZXBsYWNlRXJyb3IgPSBmdW5jdGlvbiAocmVwbGFjZSkge1xuICAgICAgICByZXR1cm4gbmV3ICh0aGlzLmN0b3IoKSkobmV3IFJlcGxhY2VFcnJvck9wZXJhdG9yKHJlcGxhY2UsIHRoaXMpKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEZsYXR0ZW5zIGEgXCJzdHJlYW0gb2Ygc3RyZWFtc1wiLCBoYW5kbGluZyBvbmx5IG9uZSBuZXN0ZWQgc3RyZWFtIGF0IGEgdGltZVxuICAgICAqIChubyBjb25jdXJyZW5jeSkuXG4gICAgICpcbiAgICAgKiBJZiB0aGUgaW5wdXQgc3RyZWFtIGlzIGEgc3RyZWFtIHRoYXQgZW1pdHMgc3RyZWFtcywgdGhlbiB0aGlzIG9wZXJhdG9yIHdpbGxcbiAgICAgKiByZXR1cm4gYW4gb3V0cHV0IHN0cmVhbSB3aGljaCBpcyBhIGZsYXQgc3RyZWFtOiBlbWl0cyByZWd1bGFyIGV2ZW50cy4gVGhlXG4gICAgICogZmxhdHRlbmluZyBoYXBwZW5zIHdpdGhvdXQgY29uY3VycmVuY3kuIEl0IHdvcmtzIGxpa2UgdGhpczogd2hlbiB0aGUgaW5wdXRcbiAgICAgKiBzdHJlYW0gZW1pdHMgYSBuZXN0ZWQgc3RyZWFtLCAqZmxhdHRlbiogd2lsbCBzdGFydCBpbWl0YXRpbmcgdGhhdCBuZXN0ZWRcbiAgICAgKiBvbmUuIEhvd2V2ZXIsIGFzIHNvb24gYXMgdGhlIG5leHQgbmVzdGVkIHN0cmVhbSBpcyBlbWl0dGVkIG9uIHRoZSBpbnB1dFxuICAgICAqIHN0cmVhbSwgKmZsYXR0ZW4qIHdpbGwgZm9yZ2V0IHRoZSBwcmV2aW91cyBuZXN0ZWQgb25lIGl0IHdhcyBpbWl0YXRpbmcsIGFuZFxuICAgICAqIHdpbGwgc3RhcnQgaW1pdGF0aW5nIHRoZSBuZXcgbmVzdGVkIG9uZS5cbiAgICAgKlxuICAgICAqIE1hcmJsZSBkaWFncmFtOlxuICAgICAqXG4gICAgICogYGBgdGV4dFxuICAgICAqIC0tKy0tLS0tLS0tKy0tLS0tLS0tLS0tLS0tLVxuICAgICAqICAgXFwgICAgICAgIFxcXG4gICAgICogICAgXFwgICAgICAgLS0tLTEtLS0tMi0tLTMtLVxuICAgICAqICAgIC0tYS0tYi0tLS1jLS0tLWQtLS0tLS0tLVxuICAgICAqICAgICAgICAgICBmbGF0dGVuXG4gICAgICogLS0tLS1hLS1iLS0tLS0tMS0tLS0yLS0tMy0tXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtTdHJlYW19XG4gICAgICovXG4gICAgU3RyZWFtLnByb3RvdHlwZS5mbGF0dGVuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcCA9IHRoaXMuX3Byb2Q7XG4gICAgICAgIHJldHVybiBuZXcgU3RyZWFtKHAgaW5zdGFuY2VvZiBNYXBPcGVyYXRvciAmJiAhKHAgaW5zdGFuY2VvZiBGaWx0ZXJNYXBPcGVyYXRvcikgP1xuICAgICAgICAgICAgbmV3IE1hcEZsYXR0ZW5PcGVyYXRvcihwKSA6XG4gICAgICAgICAgICBuZXcgRmxhdHRlbk9wZXJhdG9yKHRoaXMpKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIFBhc3NlcyB0aGUgaW5wdXQgc3RyZWFtIHRvIGEgY3VzdG9tIG9wZXJhdG9yLCB0byBwcm9kdWNlIGFuIG91dHB1dCBzdHJlYW0uXG4gICAgICpcbiAgICAgKiAqY29tcG9zZSogaXMgYSBoYW5keSB3YXkgb2YgdXNpbmcgYW4gZXhpc3RpbmcgZnVuY3Rpb24gaW4gYSBjaGFpbmVkIHN0eWxlLlxuICAgICAqIEluc3RlYWQgb2Ygd3JpdGluZyBgb3V0U3RyZWFtID0gZihpblN0cmVhbSlgIHlvdSBjYW4gd3JpdGVcbiAgICAgKiBgb3V0U3RyZWFtID0gaW5TdHJlYW0uY29tcG9zZShmKWAuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBvcGVyYXRvciBBIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYSBzdHJlYW0gYXMgaW5wdXQgYW5kXG4gICAgICogcmV0dXJucyBhIHN0cmVhbSBhcyB3ZWxsLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0ucHJvdG90eXBlLmNvbXBvc2UgPSBmdW5jdGlvbiAob3BlcmF0b3IpIHtcbiAgICAgICAgcmV0dXJuIG9wZXJhdG9yKHRoaXMpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhbiBvdXRwdXQgc3RyZWFtIHRoYXQgYmVoYXZlcyBsaWtlIHRoZSBpbnB1dCBzdHJlYW0sIGJ1dCBhbHNvXG4gICAgICogcmVtZW1iZXJzIHRoZSBtb3N0IHJlY2VudCBldmVudCB0aGF0IGhhcHBlbnMgb24gdGhlIGlucHV0IHN0cmVhbSwgc28gdGhhdCBhXG4gICAgICogbmV3bHkgYWRkZWQgbGlzdGVuZXIgd2lsbCBpbW1lZGlhdGVseSByZWNlaXZlIHRoYXQgbWVtb3Jpc2VkIGV2ZW50LlxuICAgICAqXG4gICAgICogQHJldHVybiB7TWVtb3J5U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5wcm90b3R5cGUucmVtZW1iZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBfdGhpcyA9IHRoaXM7XG4gICAgICAgIHJldHVybiBuZXcgTWVtb3J5U3RyZWFtKHtcbiAgICAgICAgICAgIF9zdGFydDogZnVuY3Rpb24gKGlsKSB7XG4gICAgICAgICAgICAgICAgdmFyIHAgPSBfdGhpcy5fcHJvZDtcbiAgICAgICAgICAgICAgICBpZiAocClcbiAgICAgICAgICAgICAgICAgICAgcC5fc3RhcnQoaWwpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF9zdG9wOiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIHAgPSBfdGhpcy5fcHJvZDtcbiAgICAgICAgICAgICAgICBpZiAocClcbiAgICAgICAgICAgICAgICAgICAgcC5fc3RvcCgpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgfSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIG91dHB1dCBzdHJlYW0gdGhhdCBpZGVudGljYWxseSBiZWhhdmVzIGxpa2UgdGhlIGlucHV0IHN0cmVhbSxcbiAgICAgKiBidXQgYWxzbyBydW5zIGEgYHNweWAgZnVuY3Rpb24gZm8gZWFjaCBldmVudCwgdG8gaGVscCB5b3UgZGVidWcgeW91ciBhcHAuXG4gICAgICpcbiAgICAgKiAqZGVidWcqIHRha2VzIGEgYHNweWAgZnVuY3Rpb24gYXMgYXJndW1lbnQsIGFuZCBydW5zIHRoYXQgZm9yIGVhY2ggZXZlbnRcbiAgICAgKiBoYXBwZW5pbmcgb24gdGhlIGlucHV0IHN0cmVhbS4gSWYgeW91IGRvbid0IHByb3ZpZGUgdGhlIGBzcHlgIGFyZ3VtZW50LFxuICAgICAqIHRoZW4gKmRlYnVnKiB3aWxsIGp1c3QgYGNvbnNvbGUubG9nYCBlYWNoIGV2ZW50LiBUaGlzIGhlbHBzIHlvdSB0b1xuICAgICAqIHVuZGVyc3RhbmQgdGhlIGZsb3cgb2YgZXZlbnRzIHRocm91Z2ggc29tZSBvcGVyYXRvciBjaGFpbi5cbiAgICAgKlxuICAgICAqIFBsZWFzZSBub3RlIHRoYXQgaWYgdGhlIG91dHB1dCBzdHJlYW0gaGFzIG5vIGxpc3RlbmVycywgdGhlbiBpdCB3aWxsIG5vdFxuICAgICAqIHN0YXJ0LCB3aGljaCBtZWFucyBgc3B5YCB3aWxsIG5ldmVyIHJ1biBiZWNhdXNlIG5vIGFjdHVhbCBldmVudCBoYXBwZW5zIGluXG4gICAgICogdGhhdCBjYXNlLlxuICAgICAqXG4gICAgICogTWFyYmxlIGRpYWdyYW06XG4gICAgICpcbiAgICAgKiBgYGB0ZXh0XG4gICAgICogLS0xLS0tLTItLS0tLTMtLS0tLTQtLVxuICAgICAqICAgICAgICAgZGVidWdcbiAgICAgKiAtLTEtLS0tMi0tLS0tMy0tLS0tNC0tXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge2Z1bmN0aW9ufSBsYWJlbE9yU3B5IEEgc3RyaW5nIHRvIHVzZSBhcyB0aGUgbGFiZWwgd2hlbiBwcmludGluZ1xuICAgICAqIGRlYnVnIGluZm9ybWF0aW9uIG9uIHRoZSBjb25zb2xlLCBvciBhICdzcHknIGZ1bmN0aW9uIHRoYXQgdGFrZXMgYW4gZXZlbnRcbiAgICAgKiBhcyBhcmd1bWVudCwgYW5kIGRvZXMgbm90IG5lZWQgdG8gcmV0dXJuIGFueXRoaW5nLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0ucHJvdG90eXBlLmRlYnVnID0gZnVuY3Rpb24gKGxhYmVsT3JTcHkpIHtcbiAgICAgICAgcmV0dXJuIG5ldyAodGhpcy5jdG9yKCkpKG5ldyBEZWJ1Z09wZXJhdG9yKGxhYmVsT3JTcHksIHRoaXMpKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEZvcmNlcyB0aGUgU3RyZWFtIHRvIGVtaXQgdGhlIGdpdmVuIHZhbHVlIHRvIGl0cyBsaXN0ZW5lcnMuXG4gICAgICpcbiAgICAgKiBBcyB0aGUgbmFtZSBpbmRpY2F0ZXMsIGlmIHlvdSB1c2UgdGhpcywgeW91IGFyZSBtb3N0IGxpa2VseSBkb2luZyBzb21ldGhpbmdcbiAgICAgKiBUaGUgV3JvbmcgV2F5LiBQbGVhc2UgdHJ5IHRvIHVuZGVyc3RhbmQgdGhlIHJlYWN0aXZlIHdheSBiZWZvcmUgdXNpbmcgdGhpc1xuICAgICAqIG1ldGhvZC4gVXNlIGl0IG9ubHkgd2hlbiB5b3Uga25vdyB3aGF0IHlvdSBhcmUgZG9pbmcuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIFwibmV4dFwiIHZhbHVlIHlvdSB3YW50IHRvIGJyb2FkY2FzdCB0byBhbGwgbGlzdGVuZXJzIG9mXG4gICAgICogdGhpcyBTdHJlYW0uXG4gICAgICovXG4gICAgU3RyZWFtLnByb3RvdHlwZS5zaGFtZWZ1bGx5U2VuZE5leHQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fbih2YWx1ZSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBGb3JjZXMgdGhlIFN0cmVhbSB0byBlbWl0IHRoZSBnaXZlbiBlcnJvciB0byBpdHMgbGlzdGVuZXJzLlxuICAgICAqXG4gICAgICogQXMgdGhlIG5hbWUgaW5kaWNhdGVzLCBpZiB5b3UgdXNlIHRoaXMsIHlvdSBhcmUgbW9zdCBsaWtlbHkgZG9pbmcgc29tZXRoaW5nXG4gICAgICogVGhlIFdyb25nIFdheS4gUGxlYXNlIHRyeSB0byB1bmRlcnN0YW5kIHRoZSByZWFjdGl2ZSB3YXkgYmVmb3JlIHVzaW5nIHRoaXNcbiAgICAgKiBtZXRob2QuIFVzZSBpdCBvbmx5IHdoZW4geW91IGtub3cgd2hhdCB5b3UgYXJlIGRvaW5nLlxuICAgICAqXG4gICAgICogQHBhcmFtIHthbnl9IGVycm9yIFRoZSBlcnJvciB5b3Ugd2FudCB0byBicm9hZGNhc3QgdG8gYWxsIHRoZSBsaXN0ZW5lcnMgb2ZcbiAgICAgKiB0aGlzIFN0cmVhbS5cbiAgICAgKi9cbiAgICBTdHJlYW0ucHJvdG90eXBlLnNoYW1lZnVsbHlTZW5kRXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgdGhpcy5fZShlcnJvcik7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBGb3JjZXMgdGhlIFN0cmVhbSB0byBlbWl0IHRoZSBcImNvbXBsZXRlZFwiIGV2ZW50IHRvIGl0cyBsaXN0ZW5lcnMuXG4gICAgICpcbiAgICAgKiBBcyB0aGUgbmFtZSBpbmRpY2F0ZXMsIGlmIHlvdSB1c2UgdGhpcywgeW91IGFyZSBtb3N0IGxpa2VseSBkb2luZyBzb21ldGhpbmdcbiAgICAgKiBUaGUgV3JvbmcgV2F5LiBQbGVhc2UgdHJ5IHRvIHVuZGVyc3RhbmQgdGhlIHJlYWN0aXZlIHdheSBiZWZvcmUgdXNpbmcgdGhpc1xuICAgICAqIG1ldGhvZC4gVXNlIGl0IG9ubHkgd2hlbiB5b3Uga25vdyB3aGF0IHlvdSBhcmUgZG9pbmcuXG4gICAgICovXG4gICAgU3RyZWFtLnByb3RvdHlwZS5zaGFtZWZ1bGx5U2VuZENvbXBsZXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLl9jKCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBDb21iaW5lcyBtdWx0aXBsZSBzdHJlYW1zIHRvZ2V0aGVyIHRvIHJldHVybiBhIHN0cmVhbSB3aG9zZSBldmVudHMgYXJlXG4gICAgICogY2FsY3VsYXRlZCBmcm9tIHRoZSBsYXRlc3QgZXZlbnRzIG9mIGVhY2ggb2YgdGhlIGlucHV0IHN0cmVhbXMuXG4gICAgICpcbiAgICAgKiAqY29tYmluZSogcmVtZW1iZXJzIHRoZSBtb3N0IHJlY2VudCBldmVudCBmcm9tIGVhY2ggb2YgdGhlIGlucHV0IHN0cmVhbXMuXG4gICAgICogV2hlbiBhbnkgb2YgdGhlIGlucHV0IHN0cmVhbXMgZW1pdHMgYW4gZXZlbnQsIHRoYXQgZXZlbnQgdG9nZXRoZXIgd2l0aCBhbGxcbiAgICAgKiB0aGUgb3RoZXIgc2F2ZWQgZXZlbnRzIGFyZSBjb21iaW5lZCBpbiB0aGUgYHByb2plY3RgIGZ1bmN0aW9uIHdoaWNoIHNob3VsZFxuICAgICAqIHJldHVybiBhIHZhbHVlLiBUaGF0IHZhbHVlIHdpbGwgYmUgZW1pdHRlZCBvbiB0aGUgb3V0cHV0IHN0cmVhbS4gSXQnc1xuICAgICAqIGVzc2VudGlhbGx5IGEgd2F5IG9mIG1peGluZyB0aGUgZXZlbnRzIGZyb20gbXVsdGlwbGUgc3RyZWFtcyBhY2NvcmRpbmcgdG8gYVxuICAgICAqIGZvcm11bGEuXG4gICAgICpcbiAgICAgKiBNYXJibGUgZGlhZ3JhbTpcbiAgICAgKlxuICAgICAqIGBgYHRleHRcbiAgICAgKiAtLTEtLS0tMi0tLS0tMy0tLS0tLS0tNC0tLVxuICAgICAqIC0tLS1hLS0tLS1iLS0tLS1jLS1kLS0tLS0tXG4gICAgICogICBjb21iaW5lKCh4LHkpID0+IHgreSlcbiAgICAgKiAtLS0tMWEtMmEtMmItM2ItM2MtM2QtNGQtLVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQGZhY3RvcnkgdHJ1ZVxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByb2plY3QgQSBmdW5jdGlvbiBvZiB0eXBlIGAoeDogVDEsIHk6IFQyKSA9PiBSYCBvclxuICAgICAqIHNpbWlsYXIgdGhhdCB0YWtlcyB0aGUgbW9zdCByZWNlbnQgZXZlbnRzIGB4YCBhbmQgYHlgIGZyb20gdGhlIGlucHV0XG4gICAgICogc3RyZWFtcyBhbmQgcmV0dXJucyBhIHZhbHVlLiBUaGUgb3V0cHV0IHN0cmVhbSB3aWxsIGVtaXQgdGhhdCB2YWx1ZS4gVGhlXG4gICAgICogbnVtYmVyIG9mIGFyZ3VtZW50cyBmb3IgdGhpcyBmdW5jdGlvbiBzaG91bGQgbWF0Y2ggdGhlIG51bWJlciBvZiBpbnB1dFxuICAgICAqIHN0cmVhbXMuXG4gICAgICogQHBhcmFtIHtTdHJlYW19IHN0cmVhbTEgQSBzdHJlYW0gdG8gY29tYmluZSB0b2dldGhlciB3aXRoIG90aGVyIHN0cmVhbXMuXG4gICAgICogQHBhcmFtIHtTdHJlYW19IHN0cmVhbTIgQSBzdHJlYW0gdG8gY29tYmluZSB0b2dldGhlciB3aXRoIG90aGVyIHN0cmVhbXMuXG4gICAgICogVHdvIG9yIG1vcmUgc3RyZWFtcyBtYXkgYmUgZ2l2ZW4gYXMgYXJndW1lbnRzLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0uY29tYmluZSA9IGZ1bmN0aW9uIGNvbWJpbmUocHJvamVjdCkge1xuICAgICAgICB2YXIgc3RyZWFtcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBfaSA9IDE7IF9pIDwgYXJndW1lbnRzLmxlbmd0aDsgX2krKykge1xuICAgICAgICAgICAgc3RyZWFtc1tfaSAtIDFdID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFN0cmVhbShuZXcgQ29tYmluZVByb2R1Y2VyKHByb2plY3QsIHN0cmVhbXMpKTtcbiAgICB9O1xuICAgIHJldHVybiBTdHJlYW07XG59KCkpO1xuZXhwb3J0cy5TdHJlYW0gPSBTdHJlYW07XG52YXIgTWltaWNTdHJlYW0gPSAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhNaW1pY1N0cmVhbSwgX3N1cGVyKTtcbiAgICBmdW5jdGlvbiBNaW1pY1N0cmVhbSgpIHtcbiAgICAgICAgX3N1cGVyLmNhbGwodGhpcyk7XG4gICAgfVxuICAgIE1pbWljU3RyZWFtLnByb3RvdHlwZS5fYWRkID0gZnVuY3Rpb24gKGlsKSB7XG4gICAgICAgIHZhciB0ID0gdGhpcy5fdGFyZ2V0O1xuICAgICAgICBpZiAoIXQpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHQuX2FkZChpbCk7XG4gICAgfTtcbiAgICBNaW1pY1N0cmVhbS5wcm90b3R5cGUuX3JlbW92ZSA9IGZ1bmN0aW9uIChpbCkge1xuICAgICAgICB2YXIgdCA9IHRoaXMuX3RhcmdldDtcbiAgICAgICAgaWYgKCF0KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB0Ll9yZW1vdmUoaWwpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogVGhpcyBtZXRob2QgZXhpc3RzIG9ubHkgb24gYSBNaW1pY1N0cmVhbSwgd2hpY2ggaXMgY3JlYXRlZCB0aHJvdWdoXG4gICAgICogYHhzLmNyZWF0ZU1pbWljKClgLiAqaW1pdGF0ZSogY2hhbmdlcyB0aGlzIGN1cnJlbnQgTWltaWNTdHJlYW0gdG8gYmVoYXZlXG4gICAgICogbGlrZSB0aGUgYG90aGVyYCBnaXZlbiBzdHJlYW0uXG4gICAgICpcbiAgICAgKiBUaGUgYGltaXRhdGVgIG1ldGhvZCBhbmQgdGhlIGBNaW1pY1N0cmVhbWAgdHlwZSBleGlzdCB0byBhbGxvdyBvbmUgdGhpbmc6XG4gICAgICogKipjaXJjdWxhciBkZXBlbmRlbmN5IG9mIHN0cmVhbXMqKi4gRm9yIGluc3RhbmNlLCBsZXQncyBpbWFnaW5lIHRoYXQgZm9yXG4gICAgICogc29tZSByZWFzb24geW91IG5lZWQgdG8gY3JlYXRlIGEgY2lyY3VsYXIgZGVwZW5kZW5jeSB3aGVyZSBzdHJlYW0gYGZpcnN0JGBcbiAgICAgKiBkZXBlbmRzIG9uIHN0cmVhbSBgc2Vjb25kJGAgd2hpY2ggaW4gdHVybiBkZXBlbmRzIG9uIGBmaXJzdCRgOlxuICAgICAqXG4gICAgICogPCEtLSBza2lwLWV4YW1wbGUgLS0+XG4gICAgICogYGBganNcbiAgICAgKiBpbXBvcnQgZGVsYXkgZnJvbSAneHN0cmVhbS9leHRyYS9kZWxheSdcbiAgICAgKlxuICAgICAqIHZhciBmaXJzdCQgPSBzZWNvbmQkLm1hcCh4ID0+IHggKiAxMCkudGFrZSgzKTtcbiAgICAgKiB2YXIgc2Vjb25kJCA9IGZpcnN0JC5tYXAoeCA9PiB4ICsgMSkuc3RhcnRXaXRoKDEpLmNvbXBvc2UoZGVsYXkoMTAwKSk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBIb3dldmVyLCB0aGF0IGlzIGludmFsaWQgSmF2YVNjcmlwdCwgYmVjYXVzZSBgc2Vjb25kJGAgaXMgdW5kZWZpbmVkXG4gICAgICogb24gdGhlIGZpcnN0IGxpbmUuIFRoaXMgaXMgaG93IGEgTWltaWNTdHJlYW0gYW5kIGltaXRhdGUgY2FuIGhlbHAgc29sdmUgaXQ6XG4gICAgICpcbiAgICAgKiBgYGBqc1xuICAgICAqIGltcG9ydCBkZWxheSBmcm9tICd4c3RyZWFtL2V4dHJhL2RlbGF5J1xuICAgICAqXG4gICAgICogdmFyIHNlY29uZE1pbWljJCA9IHhzLmNyZWF0ZU1pbWljKCk7XG4gICAgICogdmFyIGZpcnN0JCA9IHNlY29uZE1pbWljJC5tYXAoeCA9PiB4ICogMTApLnRha2UoMyk7XG4gICAgICogdmFyIHNlY29uZCQgPSBmaXJzdCQubWFwKHggPT4geCArIDEpLnN0YXJ0V2l0aCgxKS5jb21wb3NlKGRlbGF5KDEwMCkpO1xuICAgICAqIHNlY29uZE1pbWljJC5pbWl0YXRlKHNlY29uZCQpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogV2UgY3JlYXRlIGBzZWNvbmRNaW1pYyRgIGJlZm9yZSB0aGUgb3RoZXJzLCBzbyBpdCBjYW4gYmUgdXNlZCBpbiB0aGVcbiAgICAgKiBkZWNsYXJhdGlvbiBvZiBgZmlyc3QkYC4gVGhlbiwgYWZ0ZXIgYm90aCBgZmlyc3QkYCBhbmQgYHNlY29uZCRgIGFyZVxuICAgICAqIGRlZmluZWQsIHdlIGhvb2sgYHNlY29uZE1pbWljJGAgd2l0aCBgc2Vjb25kJGAgd2l0aCBgaW1pdGF0ZSgpYCB0byB0ZWxsXG4gICAgICogdGhhdCB0aGV5IGFyZSBcInRoZSBzYW1lXCIuIGBpbWl0YXRlYCB3aWxsIG5vdCB0cmlnZ2VyIHRoZSBzdGFydCBvZiBhbnlcbiAgICAgKiBzdHJlYW0sIGl0IHNpbXBseSBmb3J3YXJkcyBsaXN0ZW5lcnMgb2YgYHNlY29uZE1pbWljJGAgdG8gYHNlY29uZCRgLlxuICAgICAqXG4gICAgICogVGhlIGZvbGxvd2luZyBpcyBhbiBleGFtcGxlIHdoZXJlIGBpbWl0YXRlKClgIGlzIGltcG9ydGFudCBpbiBDeWNsZS5qc1xuICAgICAqIGFwcGxpY2F0aW9ucy4gQSBwYXJlbnQgY29tcG9uZW50IGNvbnRhaW5zIHNvbWUgY2hpbGQgY29tcG9uZW50cy4gQSBjaGlsZFxuICAgICAqIGhhcyBhbiBhY3Rpb24gc3RyZWFtIHdoaWNoIGlzIGdpdmVuIHRvIHRoZSBwYXJlbnQgdG8gZGVmaW5lIGl0cyBzdGF0ZTpcbiAgICAgKlxuICAgICAqIDwhLS0gc2tpcC1leGFtcGxlIC0tPlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgY2hpbGRBY3Rpb25NaW1pYyQgPSB4cy5jcmVhdGVNaW1pYygpO1xuICAgICAqIGNvbnN0IHBhcmVudCA9IFBhcmVudCh7Li4uc291cmNlcywgY2hpbGRBY3Rpb24kOiBjaGlsZEFjdGlvbk1pbWljJH0pO1xuICAgICAqIGNvbnN0IGNoaWxkQWN0aW9uJCA9IHBhcmVudC5zdGF0ZSQubWFwKHMgPT4gcy5jaGlsZC5hY3Rpb24kKS5mbGF0dGVuKCk7XG4gICAgICogY2hpbGRBY3Rpb25NaW1pYyQuaW1pdGF0ZShjaGlsZEFjdGlvbiQpO1xuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogVGhlICppbWl0YXRlKiBtZXRob2QgcmV0dXJucyBub3RoaW5nLiBJbnN0ZWFkLCBpdCBjaGFuZ2VzIHRoZSBiZWhhdmlvciBvZlxuICAgICAqIHRoZSBjdXJyZW50IHN0cmVhbSwgbWFraW5nIGl0IHJlLWVtaXQgd2hhdGV2ZXIgZXZlbnRzIGFyZSBlbWl0dGVkIGJ5IHRoZVxuICAgICAqIGdpdmVuIGBvdGhlcmAgc3RyZWFtLlxuICAgICAqXG4gICAgICogTm90ZSwgdGhvdWdoLCB0aGF0ICoqYGltaXRhdGUoKWAgZG9lcyBub3Qgc3VwcG9ydCBNZW1vcnlTdHJlYW1zKiouIElmIHdlXG4gICAgICogd291bGQgYXR0ZW1wdCB0byBpbWl0YXRlIGEgTWVtb3J5U3RyZWFtIGluIGEgY2lyY3VsYXIgZGVwZW5kZW5jeSwgd2Ugd291bGRcbiAgICAgKiBlaXRoZXIgZ2V0IGEgcmFjZSBjb25kaXRpb24gKHdoZXJlIHRoZSBzeW1wdG9tIHdvdWxkIGJlIFwibm90aGluZyBoYXBwZW5zXCIpXG4gICAgICogb3IgYW4gaW5maW5pdGUgY3ljbGljIGVtaXNzaW9uIG9mIHZhbHVlcy4gSXQncyB1c2VmdWwgdG8gdGhpbmsgYWJvdXRcbiAgICAgKiBNZW1vcnlTdHJlYW1zIGFzIGNlbGxzIGluIGEgc3ByZWFkc2hlZXQuIEl0IGRvZXNuJ3QgbWFrZSBhbnkgc2Vuc2UgdG9cbiAgICAgKiBkZWZpbmUgYSBzcHJlYWRzaGVldCBjZWxsIGBBMWAgd2l0aCBhIGZvcm11bGEgdGhhdCBkZXBlbmRzIG9uIGBCMWAgYW5kXG4gICAgICogY2VsbCBgQjFgIGRlZmluZWQgd2l0aCBhIGZvcm11bGEgdGhhdCBkZXBlbmRzIG9uIGBBMWAuXG4gICAgICpcbiAgICAgKiBJZiB5b3UgZmluZCB5b3Vyc2VsZiB3YW50aW5nIHRvIHVzZSBgaW1pdGF0ZSgpYCB3aXRoIGFcbiAgICAgKiBNZW1vcnlTdHJlYW0sIHlvdSBzaG91bGQgcmV3b3JrIHlvdXIgY29kZSBhcm91bmQgYGltaXRhdGUoKWAgdG8gdXNlIGFcbiAgICAgKiBTdHJlYW0gaW5zdGVhZC4gTG9vayBmb3IgdGhlIHN0cmVhbSBpbiB0aGUgY2lyY3VsYXIgZGVwZW5kZW5jeSB0aGF0XG4gICAgICogcmVwcmVzZW50cyBhbiBldmVudCBzdHJlYW0sIGFuZCB0aGF0IHdvdWxkIGJlIGEgY2FuZGlkYXRlIGZvciBjcmVhdGluZyBhXG4gICAgICogTWltaWNTdHJlYW0gd2hpY2ggdGhlbiBpbWl0YXRlcyB0aGUgcmVhbCBldmVudCBzdHJlYW0uXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1N0cmVhbX0gb3RoZXIgVGhlIHN0cmVhbSB0byBpbWl0YXRlIG9uIHRoZSBjdXJyZW50IG9uZS4gTXVzdCBub3QgYmVcbiAgICAgKiBhIE1lbW9yeVN0cmVhbS5cbiAgICAgKi9cbiAgICBNaW1pY1N0cmVhbS5wcm90b3R5cGUuaW1pdGF0ZSA9IGZ1bmN0aW9uIChvdGhlcikge1xuICAgICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBNZW1vcnlTdHJlYW0pIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQSBNZW1vcnlTdHJlYW0gd2FzIGdpdmVuIHRvIGltaXRhdGUoKSwgYnV0IGl0IG9ubHkgJyArXG4gICAgICAgICAgICAgICAgJ3N1cHBvcnRzIGEgU3RyZWFtLiBSZWFkIG1vcmUgYWJvdXQgdGhpcyByZXN0cmljdGlvbiBoZXJlOiAnICtcbiAgICAgICAgICAgICAgICAnaHR0cHM6Ly9naXRodWIuY29tL3N0YWx0ei94c3RyZWFtI2ZhcScpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3RhcmdldCA9IG90aGVyO1xuICAgIH07XG4gICAgcmV0dXJuIE1pbWljU3RyZWFtO1xufShTdHJlYW0pKTtcbmV4cG9ydHMuTWltaWNTdHJlYW0gPSBNaW1pY1N0cmVhbTtcbnZhciBNZW1vcnlTdHJlYW0gPSAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhNZW1vcnlTdHJlYW0sIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gTWVtb3J5U3RyZWFtKHByb2R1Y2VyKSB7XG4gICAgICAgIF9zdXBlci5jYWxsKHRoaXMsIHByb2R1Y2VyKTtcbiAgICAgICAgdGhpcy5faGFzID0gZmFsc2U7XG4gICAgfVxuICAgIE1lbW9yeVN0cmVhbS5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAoeCkge1xuICAgICAgICB0aGlzLl92ID0geDtcbiAgICAgICAgdGhpcy5faGFzID0gdHJ1ZTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5fbi5jYWxsKHRoaXMsIHgpO1xuICAgIH07XG4gICAgTWVtb3J5U3RyZWFtLnByb3RvdHlwZS5fYWRkID0gZnVuY3Rpb24gKGlsKSB7XG4gICAgICAgIGlmICh0aGlzLl9oYXMpIHtcbiAgICAgICAgICAgIGlsLl9uKHRoaXMuX3YpO1xuICAgICAgICB9XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuX2FkZC5jYWxsKHRoaXMsIGlsKTtcbiAgICB9O1xuICAgIE1lbW9yeVN0cmVhbS5wcm90b3R5cGUuX3ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX2hhcyA9IGZhbHNlO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLl94LmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBNZW1vcnlTdHJlYW0ucHJvdG90eXBlLm1hcCA9IGZ1bmN0aW9uIChwcm9qZWN0KSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9tYXAocHJvamVjdCk7XG4gICAgfTtcbiAgICBNZW1vcnlTdHJlYW0ucHJvdG90eXBlLm1hcFRvID0gZnVuY3Rpb24gKHByb2plY3RlZFZhbHVlKSB7XG4gICAgICAgIHJldHVybiBfc3VwZXIucHJvdG90eXBlLm1hcFRvLmNhbGwodGhpcywgcHJvamVjdGVkVmFsdWUpO1xuICAgIH07XG4gICAgTWVtb3J5U3RyZWFtLnByb3RvdHlwZS50YWtlID0gZnVuY3Rpb24gKGFtb3VudCkge1xuICAgICAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS50YWtlLmNhbGwodGhpcywgYW1vdW50KTtcbiAgICB9O1xuICAgIE1lbW9yeVN0cmVhbS5wcm90b3R5cGUuZW5kV2hlbiA9IGZ1bmN0aW9uIChvdGhlcikge1xuICAgICAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5lbmRXaGVuLmNhbGwodGhpcywgb3RoZXIpO1xuICAgIH07XG4gICAgTWVtb3J5U3RyZWFtLnByb3RvdHlwZS5yZXBsYWNlRXJyb3IgPSBmdW5jdGlvbiAocmVwbGFjZSkge1xuICAgICAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5yZXBsYWNlRXJyb3IuY2FsbCh0aGlzLCByZXBsYWNlKTtcbiAgICB9O1xuICAgIE1lbW9yeVN0cmVhbS5wcm90b3R5cGUuZGVidWcgPSBmdW5jdGlvbiAobGFiZWxPclNweSkge1xuICAgICAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5kZWJ1Zy5jYWxsKHRoaXMsIGxhYmVsT3JTcHkpO1xuICAgIH07XG4gICAgcmV0dXJuIE1lbW9yeVN0cmVhbTtcbn0oU3RyZWFtKSk7XG5leHBvcnRzLk1lbW9yeVN0cmVhbSA9IE1lbW9yeVN0cmVhbTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZGVmYXVsdCA9IFN0cmVhbTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvcmUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgY29yZV8xID0gcmVxdWlyZSgnLi4vY29yZScpO1xudmFyIGVtcHR5ID0ge307XG52YXIgRHJvcFJlcGVhdHNPcGVyYXRvciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRHJvcFJlcGVhdHNPcGVyYXRvcihmbiwgaW5zKSB7XG4gICAgICAgIHRoaXMuZm4gPSBmbjtcbiAgICAgICAgdGhpcy5pbnMgPSBpbnM7XG4gICAgICAgIHRoaXMudHlwZSA9ICdkcm9wUmVwZWF0cyc7XG4gICAgICAgIHRoaXMub3V0ID0gbnVsbDtcbiAgICAgICAgdGhpcy52ID0gZW1wdHk7XG4gICAgfVxuICAgIERyb3BSZXBlYXRzT3BlcmF0b3IucHJvdG90eXBlLl9zdGFydCA9IGZ1bmN0aW9uIChvdXQpIHtcbiAgICAgICAgdGhpcy5vdXQgPSBvdXQ7XG4gICAgICAgIHRoaXMuaW5zLl9hZGQodGhpcyk7XG4gICAgfTtcbiAgICBEcm9wUmVwZWF0c09wZXJhdG9yLnByb3RvdHlwZS5fc3RvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5pbnMuX3JlbW92ZSh0aGlzKTtcbiAgICAgICAgdGhpcy5vdXQgPSBudWxsO1xuICAgICAgICB0aGlzLnYgPSBlbXB0eTtcbiAgICB9O1xuICAgIERyb3BSZXBlYXRzT3BlcmF0b3IucHJvdG90eXBlLmlzRXEgPSBmdW5jdGlvbiAoeCwgeSkge1xuICAgICAgICByZXR1cm4gdGhpcy5mbiA/IHRoaXMuZm4oeCwgeSkgOiB4ID09PSB5O1xuICAgIH07XG4gICAgRHJvcFJlcGVhdHNPcGVyYXRvci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAoIXUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHZhciB2ID0gdGhpcy52O1xuICAgICAgICBpZiAodiA9PT0gZW1wdHkgfHwgIXRoaXMuaXNFcSh0LCB2KSkge1xuICAgICAgICAgICAgdS5fbih0KTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnYgPSB0O1xuICAgIH07XG4gICAgRHJvcFJlcGVhdHNPcGVyYXRvci5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdS5fZShlcnIpO1xuICAgIH07XG4gICAgRHJvcFJlcGVhdHNPcGVyYXRvci5wcm90b3R5cGUuX2MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdS5fYygpO1xuICAgIH07XG4gICAgcmV0dXJuIERyb3BSZXBlYXRzT3BlcmF0b3I7XG59KCkpO1xuZXhwb3J0cy5Ecm9wUmVwZWF0c09wZXJhdG9yID0gRHJvcFJlcGVhdHNPcGVyYXRvcjtcbmZ1bmN0aW9uIGRyb3BSZXBlYXRzKGlzRXF1YWwpIHtcbiAgICBpZiAoaXNFcXVhbCA9PT0gdm9pZCAwKSB7IGlzRXF1YWwgPSBudWxsOyB9XG4gICAgcmV0dXJuIGZ1bmN0aW9uIGRyb3BSZXBlYXRzT3BlcmF0b3IoaW5zKSB7XG4gICAgICAgIHJldHVybiBuZXcgY29yZV8xLlN0cmVhbShuZXcgRHJvcFJlcGVhdHNPcGVyYXRvcihpc0VxdWFsLCBpbnMpKTtcbiAgICB9O1xufVxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gZHJvcFJlcGVhdHM7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kcm9wUmVwZWF0cy5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbnZhciBjb3JlXzEgPSByZXF1aXJlKCcuL2NvcmUnKTtcbmV4cG9ydHMuU3RyZWFtID0gY29yZV8xLlN0cmVhbTtcbmV4cG9ydHMuTWVtb3J5U3RyZWFtID0gY29yZV8xLk1lbW9yeVN0cmVhbTtcbmV4cG9ydHMuTWltaWNTdHJlYW0gPSBjb3JlXzEuTWltaWNTdHJlYW07XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmRlZmF1bHQgPSBjb3JlXzEuU3RyZWFtO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgYmFzZV8xID0gcmVxdWlyZSgnQGN5Y2xlL2Jhc2UnKTtcbnZhciB4c3RyZWFtX2FkYXB0ZXJfMSA9IHJlcXVpcmUoJ0BjeWNsZS94c3RyZWFtLWFkYXB0ZXInKTtcbi8qKlxuICogQSBmdW5jdGlvbiB0aGF0IHByZXBhcmVzIHRoZSBDeWNsZSBhcHBsaWNhdGlvbiB0byBiZSBleGVjdXRlZC4gVGFrZXMgYSBgbWFpbmBcbiAqIGZ1bmN0aW9uIGFuZCBwcmVwYXJlcyB0byBjaXJjdWxhcmx5IGNvbm5lY3RzIGl0IHRvIHRoZSBnaXZlbiBjb2xsZWN0aW9uIG9mXG4gKiBkcml2ZXIgZnVuY3Rpb25zLiBBcyBhbiBvdXRwdXQsIGBDeWNsZSgpYCByZXR1cm5zIGFuIG9iamVjdCB3aXRoIHRocmVlXG4gKiBwcm9wZXJ0aWVzOiBgc291cmNlc2AsIGBzaW5rc2AgYW5kIGBydW5gLiBPbmx5IHdoZW4gYHJ1bigpYCBpcyBjYWxsZWQgd2lsbFxuICogdGhlIGFwcGxpY2F0aW9uIGFjdHVhbGx5IGV4ZWN1dGUuIFJlZmVyIHRvIHRoZSBkb2N1bWVudGF0aW9uIG9mIGBydW4oKWAgZm9yXG4gKiBtb3JlIGRldGFpbHMuXG4gKlxuICogKipFeGFtcGxlOioqXG4gKiBgYGBqc1xuICogY29uc3Qge3NvdXJjZXMsIHNpbmtzLCBydW59ID0gQ3ljbGUobWFpbiwgZHJpdmVycyk7XG4gKiAvLyAuLi5cbiAqIGNvbnN0IGRpc3Bvc2UgPSBydW4oKTsgLy8gRXhlY3V0ZXMgdGhlIGFwcGxpY2F0aW9uXG4gKiAvLyAuLi5cbiAqIGRpc3Bvc2UoKTtcbiAqIGBgYFxuICpcbiAqIEBwYXJhbSB7RnVuY3Rpb259IG1haW4gYSBmdW5jdGlvbiB0aGF0IHRha2VzIGBzb3VyY2VzYCBhcyBpbnB1dFxuICogYW5kIG91dHB1dHMgYSBjb2xsZWN0aW9uIG9mIGBzaW5rc2AgT2JzZXJ2YWJsZXMuXG4gKiBAcGFyYW0ge09iamVjdH0gZHJpdmVycyBhbiBvYmplY3Qgd2hlcmUga2V5cyBhcmUgZHJpdmVyIG5hbWVzIGFuZCB2YWx1ZXNcbiAqIGFyZSBkcml2ZXIgZnVuY3Rpb25zLlxuICogQHJldHVybiB7T2JqZWN0fSBhbiBvYmplY3Qgd2l0aCB0aHJlZSBwcm9wZXJ0aWVzOiBgc291cmNlc2AsIGBzaW5rc2AgYW5kXG4gKiBgcnVuYC4gYHNvdXJjZXNgIGlzIHRoZSBjb2xsZWN0aW9uIG9mIGRyaXZlciBzb3VyY2VzLCBgc2lua3NgIGlzIHRoZVxuICogY29sbGVjdGlvbiBvZiBkcml2ZXIgc2lua3MsIHRoZXNlIGNhbiBiZSB1c2VkIGZvciBkZWJ1Z2dpbmcgb3IgdGVzdGluZy4gYHJ1bmBcbiAqIGlzIHRoZSBmdW5jdGlvbiB0aGF0IG9uY2UgY2FsbGVkIHdpbGwgZXhlY3V0ZSB0aGUgYXBwbGljYXRpb24uXG4gKiBAZnVuY3Rpb24gQ3ljbGVcbiAqL1xudmFyIEN5Y2xlID0gZnVuY3Rpb24gKG1haW4sIGRyaXZlcnMpIHtcbiAgICByZXR1cm4gYmFzZV8xLmRlZmF1bHQobWFpbiwgZHJpdmVycywgeyBzdHJlYW1BZGFwdGVyOiB4c3RyZWFtX2FkYXB0ZXJfMS5kZWZhdWx0IH0pO1xufTtcbi8qKlxuICogVGFrZXMgYSBgbWFpbmAgZnVuY3Rpb24gYW5kIGNpcmN1bGFybHkgY29ubmVjdHMgaXQgdG8gdGhlIGdpdmVuIGNvbGxlY3Rpb25cbiAqIG9mIGRyaXZlciBmdW5jdGlvbnMuXG4gKlxuICogKipFeGFtcGxlOioqXG4gKiBgYGBqc1xuICogY29uc3QgZGlzcG9zZSA9IEN5Y2xlLnJ1bihtYWluLCBkcml2ZXJzKTtcbiAqIC8vIC4uLlxuICogZGlzcG9zZSgpO1xuICogYGBgXG4gKlxuICogVGhlIGBtYWluYCBmdW5jdGlvbiBleHBlY3RzIGEgY29sbGVjdGlvbiBvZiBcInNvdXJjZVwiIE9ic2VydmFibGVzIChyZXR1cm5lZFxuICogZnJvbSBkcml2ZXJzKSBhcyBpbnB1dCwgYW5kIHNob3VsZCByZXR1cm4gYSBjb2xsZWN0aW9uIG9mIFwic2lua1wiIE9ic2VydmFibGVzXG4gKiAodG8gYmUgZ2l2ZW4gdG8gZHJpdmVycykuIEEgXCJjb2xsZWN0aW9uIG9mIE9ic2VydmFibGVzXCIgaXMgYSBKYXZhU2NyaXB0XG4gKiBvYmplY3Qgd2hlcmUga2V5cyBtYXRjaCB0aGUgZHJpdmVyIG5hbWVzIHJlZ2lzdGVyZWQgYnkgdGhlIGBkcml2ZXJzYCBvYmplY3QsXG4gKiBhbmQgdmFsdWVzIGFyZSB0aGUgT2JzZXJ2YWJsZXMuIFJlZmVyIHRvIHRoZSBkb2N1bWVudGF0aW9uIG9mIGVhY2ggZHJpdmVyIHRvXG4gKiBzZWUgbW9yZSBkZXRhaWxzIG9uIHdoYXQgdHlwZXMgb2Ygc291cmNlcyBpdCBvdXRwdXRzIGFuZCBzaW5rcyBpdCByZWNlaXZlcy5cbiAqXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBtYWluIGEgZnVuY3Rpb24gdGhhdCB0YWtlcyBgc291cmNlc2AgYXMgaW5wdXRcbiAqIGFuZCBvdXRwdXRzIGEgY29sbGVjdGlvbiBvZiBgc2lua3NgIE9ic2VydmFibGVzLlxuICogQHBhcmFtIHtPYmplY3R9IGRyaXZlcnMgYW4gb2JqZWN0IHdoZXJlIGtleXMgYXJlIGRyaXZlciBuYW1lcyBhbmQgdmFsdWVzXG4gKiBhcmUgZHJpdmVyIGZ1bmN0aW9ucy5cbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBhIGRpc3Bvc2UgZnVuY3Rpb24sIHVzZWQgdG8gdGVybWluYXRlIHRoZSBleGVjdXRpb24gb2YgdGhlXG4gKiBDeWNsZS5qcyBwcm9ncmFtLCBjbGVhbmluZyB1cCByZXNvdXJjZXMgdXNlZC5cbiAqIEBmdW5jdGlvbiBydW5cbiAqL1xuZnVuY3Rpb24gcnVuKG1haW4sIGRyaXZlcnMpIHtcbiAgICB2YXIgcnVuID0gYmFzZV8xLmRlZmF1bHQobWFpbiwgZHJpdmVycywgeyBzdHJlYW1BZGFwdGVyOiB4c3RyZWFtX2FkYXB0ZXJfMS5kZWZhdWx0IH0pLnJ1bjtcbiAgICByZXR1cm4gcnVuKCk7XG59XG5leHBvcnRzLnJ1biA9IHJ1bjtcbkN5Y2xlLnJ1biA9IHJ1bjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZGVmYXVsdCA9IEN5Y2xlO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG5mdW5jdGlvbiBsb2dUb0NvbnNvbGVFcnJvcihlcnIpIHtcbiAgICB2YXIgdGFyZ2V0ID0gZXJyLnN0YWNrIHx8IGVycjtcbiAgICBpZiAoY29uc29sZSAmJiBjb25zb2xlLmVycm9yKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IodGFyZ2V0KTtcbiAgICB9XG4gICAgZWxzZSBpZiAoY29uc29sZSAmJiBjb25zb2xlLmxvZykge1xuICAgICAgICBjb25zb2xlLmxvZyh0YXJnZXQpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIG1ha2VTaW5rUHJveGllcyhkcml2ZXJzLCBzdHJlYW1BZGFwdGVyKSB7XG4gICAgdmFyIHNpbmtQcm94aWVzID0ge307XG4gICAgZm9yICh2YXIgbmFtZV8xIGluIGRyaXZlcnMpIHtcbiAgICAgICAgaWYgKGRyaXZlcnMuaGFzT3duUHJvcGVydHkobmFtZV8xKSkge1xuICAgICAgICAgICAgdmFyIGhvbGRTdWJqZWN0ID0gc3RyZWFtQWRhcHRlci5tYWtlU3ViamVjdCgpO1xuICAgICAgICAgICAgdmFyIGRyaXZlclN0cmVhbUFkYXB0ZXIgPSBkcml2ZXJzW25hbWVfMV0uc3RyZWFtQWRhcHRlciB8fCBzdHJlYW1BZGFwdGVyO1xuICAgICAgICAgICAgdmFyIHN0cmVhbSA9IGRyaXZlclN0cmVhbUFkYXB0ZXIuYWRhcHQoaG9sZFN1YmplY3Quc3RyZWFtLCBzdHJlYW1BZGFwdGVyLnN0cmVhbVN1YnNjcmliZSk7XG4gICAgICAgICAgICBzaW5rUHJveGllc1tuYW1lXzFdID0ge1xuICAgICAgICAgICAgICAgIHN0cmVhbTogc3RyZWFtLFxuICAgICAgICAgICAgICAgIG9ic2VydmVyOiBob2xkU3ViamVjdC5vYnNlcnZlcixcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHNpbmtQcm94aWVzO1xufVxuZnVuY3Rpb24gY2FsbERyaXZlcnMoZHJpdmVycywgc2lua1Byb3hpZXMsIHN0cmVhbUFkYXB0ZXIpIHtcbiAgICB2YXIgc291cmNlcyA9IHt9O1xuICAgIGZvciAodmFyIG5hbWVfMiBpbiBkcml2ZXJzKSB7XG4gICAgICAgIGlmIChkcml2ZXJzLmhhc093blByb3BlcnR5KG5hbWVfMikpIHtcbiAgICAgICAgICAgIHZhciBkcml2ZXJPdXRwdXQgPSBkcml2ZXJzW25hbWVfMl0oc2lua1Byb3hpZXNbbmFtZV8yXS5zdHJlYW0sIHN0cmVhbUFkYXB0ZXIsIG5hbWVfMik7XG4gICAgICAgICAgICB2YXIgZHJpdmVyU3RyZWFtQWRhcHRlciA9IGRyaXZlcnNbbmFtZV8yXS5zdHJlYW1BZGFwdGVyO1xuICAgICAgICAgICAgaWYgKGRyaXZlclN0cmVhbUFkYXB0ZXIgJiYgZHJpdmVyU3RyZWFtQWRhcHRlci5pc1ZhbGlkU3RyZWFtKGRyaXZlck91dHB1dCkpIHtcbiAgICAgICAgICAgICAgICBzb3VyY2VzW25hbWVfMl0gPSBzdHJlYW1BZGFwdGVyLmFkYXB0KGRyaXZlck91dHB1dCwgZHJpdmVyU3RyZWFtQWRhcHRlci5zdHJlYW1TdWJzY3JpYmUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc291cmNlc1tuYW1lXzJdID0gZHJpdmVyT3V0cHV0O1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzb3VyY2VzO1xufVxuZnVuY3Rpb24gcmVwbGljYXRlTWFueShzaW5rcywgc2lua1Byb3hpZXMsIHN0cmVhbUFkYXB0ZXIpIHtcbiAgICB2YXIgcmVzdWx0cyA9IE9iamVjdC5rZXlzKHNpbmtzKVxuICAgICAgICAuZmlsdGVyKGZ1bmN0aW9uIChuYW1lKSB7IHJldHVybiAhIXNpbmtQcm94aWVzW25hbWVdOyB9KVxuICAgICAgICAubWFwKGZ1bmN0aW9uIChuYW1lKSB7XG4gICAgICAgIHJldHVybiBzdHJlYW1BZGFwdGVyLnN0cmVhbVN1YnNjcmliZShzaW5rc1tuYW1lXSwge1xuICAgICAgICAgICAgbmV4dDogZnVuY3Rpb24gKHgpIHsgc2lua1Byb3hpZXNbbmFtZV0ub2JzZXJ2ZXIubmV4dCh4KTsgfSxcbiAgICAgICAgICAgIGVycm9yOiBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICAgICAgbG9nVG9Db25zb2xlRXJyb3IoZXJyKTtcbiAgICAgICAgICAgICAgICBzaW5rUHJveGllc1tuYW1lXS5vYnNlcnZlci5lcnJvcihlcnIpO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNvbXBsZXRlOiBmdW5jdGlvbiAoeCkge1xuICAgICAgICAgICAgICAgIHNpbmtQcm94aWVzW25hbWVdLm9ic2VydmVyLmNvbXBsZXRlKHgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9KTtcbiAgICB2YXIgZGlzcG9zZUZ1bmN0aW9ucyA9IHJlc3VsdHNcbiAgICAgICAgLmZpbHRlcihmdW5jdGlvbiAoZGlzcG9zZSkgeyByZXR1cm4gdHlwZW9mIGRpc3Bvc2UgPT09ICdmdW5jdGlvbic7IH0pO1xuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGRpc3Bvc2VGdW5jdGlvbnMuZm9yRWFjaChmdW5jdGlvbiAoZGlzcG9zZSkgeyByZXR1cm4gZGlzcG9zZSgpOyB9KTtcbiAgICB9O1xufVxuZnVuY3Rpb24gZGlzcG9zZVNvdXJjZXMoc291cmNlcykge1xuICAgIGZvciAodmFyIGsgaW4gc291cmNlcykge1xuICAgICAgICBpZiAoc291cmNlcy5oYXNPd25Qcm9wZXJ0eShrKSAmJiBzb3VyY2VzW2tdXG4gICAgICAgICAgICAmJiB0eXBlb2Ygc291cmNlc1trXS5kaXNwb3NlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICBzb3VyY2VzW2tdLmRpc3Bvc2UoKTtcbiAgICAgICAgfVxuICAgIH1cbn1cbnZhciBpc09iamVjdEVtcHR5ID0gZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gT2JqZWN0LmtleXMob2JqKS5sZW5ndGggPT09IDA7IH07XG5mdW5jdGlvbiBDeWNsZShtYWluLCBkcml2ZXJzLCBvcHRpb25zKSB7XG4gICAgaWYgKHR5cGVvZiBtYWluICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRmlyc3QgYXJndW1lbnQgZ2l2ZW4gdG8gQ3ljbGUgbXVzdCBiZSB0aGUgJ21haW4nIFwiICtcbiAgICAgICAgICAgIFwiZnVuY3Rpb24uXCIpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIGRyaXZlcnMgIT09IFwib2JqZWN0XCIgfHwgZHJpdmVycyA9PT0gbnVsbCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTZWNvbmQgYXJndW1lbnQgZ2l2ZW4gdG8gQ3ljbGUgbXVzdCBiZSBhbiBvYmplY3QgXCIgK1xuICAgICAgICAgICAgXCJ3aXRoIGRyaXZlciBmdW5jdGlvbnMgYXMgcHJvcGVydGllcy5cIik7XG4gICAgfVxuICAgIGlmIChpc09iamVjdEVtcHR5KGRyaXZlcnMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIlNlY29uZCBhcmd1bWVudCBnaXZlbiB0byBDeWNsZSBtdXN0IGJlIGFuIG9iamVjdCBcIiArXG4gICAgICAgICAgICBcIndpdGggYXQgbGVhc3Qgb25lIGRyaXZlciBmdW5jdGlvbiBkZWNsYXJlZCBhcyBhIHByb3BlcnR5LlwiKTtcbiAgICB9XG4gICAgdmFyIHN0cmVhbUFkYXB0ZXIgPSBvcHRpb25zLnN0cmVhbUFkYXB0ZXI7XG4gICAgaWYgKCFzdHJlYW1BZGFwdGVyIHx8IGlzT2JqZWN0RW1wdHkoc3RyZWFtQWRhcHRlcikpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiVGhpcmQgYXJndW1lbnQgZ2l2ZW4gdG8gQ3ljbGUgbXVzdCBiZSBhbiBvcHRpb25zIG9iamVjdCBcIiArXG4gICAgICAgICAgICBcIndpdGggdGhlIHN0cmVhbUFkYXB0ZXIga2V5IHN1cHBsaWVkIHdpdGggYSB2YWxpZCBzdHJlYW0gYWRhcHRlci5cIik7XG4gICAgfVxuICAgIHZhciBzaW5rUHJveGllcyA9IG1ha2VTaW5rUHJveGllcyhkcml2ZXJzLCBzdHJlYW1BZGFwdGVyKTtcbiAgICB2YXIgc291cmNlcyA9IGNhbGxEcml2ZXJzKGRyaXZlcnMsIHNpbmtQcm94aWVzLCBzdHJlYW1BZGFwdGVyKTtcbiAgICB2YXIgc2lua3MgPSBtYWluKHNvdXJjZXMpO1xuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICB3aW5kb3cuQ3ljbGVqcyA9IHsgc2lua3M6IHNpbmtzIH07XG4gICAgfVxuICAgIHZhciBydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBkaXNwb3NlUmVwbGljYXRpb24gPSByZXBsaWNhdGVNYW55KHNpbmtzLCBzaW5rUHJveGllcywgc3RyZWFtQWRhcHRlcik7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBkaXNwb3NlU291cmNlcyhzb3VyY2VzKTtcbiAgICAgICAgICAgIGRpc3Bvc2VSZXBsaWNhdGlvbigpO1xuICAgICAgICB9O1xuICAgIH07XG4gICAgcmV0dXJuIHsgc2lua3M6IHNpbmtzLCBzb3VyY2VzOiBzb3VyY2VzLCBydW46IHJ1biB9O1xufVxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gQ3ljbGU7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1pbmRleC5qcy5tYXAiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG4vKipcbiAqIEluZGljYXRlcyB0aGF0IG5hdmlnYXRpb24gd2FzIGNhdXNlZCBieSBhIGNhbGwgdG8gaGlzdG9yeS5wdXNoLlxuICovXG52YXIgUFVTSCA9IGV4cG9ydHMuUFVTSCA9ICdQVVNIJztcblxuLyoqXG4gKiBJbmRpY2F0ZXMgdGhhdCBuYXZpZ2F0aW9uIHdhcyBjYXVzZWQgYnkgYSBjYWxsIHRvIGhpc3RvcnkucmVwbGFjZS5cbiAqL1xudmFyIFJFUExBQ0UgPSBleHBvcnRzLlJFUExBQ0UgPSAnUkVQTEFDRSc7XG5cbi8qKlxuICogSW5kaWNhdGVzIHRoYXQgbmF2aWdhdGlvbiB3YXMgY2F1c2VkIGJ5IHNvbWUgb3RoZXIgYWN0aW9uIHN1Y2hcbiAqIGFzIHVzaW5nIGEgYnJvd3NlcidzIGJhY2svZm9yd2FyZCBidXR0b25zIGFuZC9vciBtYW51YWxseSBtYW5pcHVsYXRpbmdcbiAqIHRoZSBVUkwgaW4gYSBicm93c2VyJ3MgbG9jYXRpb24gYmFyLiBUaGlzIGlzIHRoZSBkZWZhdWx0LlxuICpcbiAqIFNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvV2luZG93RXZlbnRIYW5kbGVycy9vbnBvcHN0YXRlXG4gKiBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAqL1xudmFyIFBPUCA9IGV4cG9ydHMuUE9QID0gJ1BPUCc7IiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5cbmZ1bmN0aW9uIF90b0NvbnN1bWFibGVBcnJheShhcnIpIHsgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgeyBmb3IgKHZhciBpID0gMCwgYXJyMiA9IEFycmF5KGFyci5sZW5ndGgpOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7IGFycjJbaV0gPSBhcnJbaV07IH0gcmV0dXJuIGFycjI7IH0gZWxzZSB7IHJldHVybiBBcnJheS5mcm9tKGFycik7IH0gfVxuXG52YXIgbG9vcEFzeW5jID0gZXhwb3J0cy5sb29wQXN5bmMgPSBmdW5jdGlvbiBsb29wQXN5bmModHVybnMsIHdvcmssIGNhbGxiYWNrKSB7XG4gIHZhciBjdXJyZW50VHVybiA9IDAsXG4gICAgICBpc0RvbmUgPSBmYWxzZTtcbiAgdmFyIGlzU3luYyA9IGZhbHNlLFxuICAgICAgaGFzTmV4dCA9IGZhbHNlLFxuICAgICAgZG9uZUFyZ3MgPSB2b2lkIDA7XG5cbiAgdmFyIGRvbmUgPSBmdW5jdGlvbiBkb25lKCkge1xuICAgIGZvciAodmFyIF9sZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gQXJyYXkoX2xlbiksIF9rZXkgPSAwOyBfa2V5IDwgX2xlbjsgX2tleSsrKSB7XG4gICAgICBhcmdzW19rZXldID0gYXJndW1lbnRzW19rZXldO1xuICAgIH1cblxuICAgIGlzRG9uZSA9IHRydWU7XG5cbiAgICBpZiAoaXNTeW5jKSB7XG4gICAgICAvLyBJdGVyYXRlIGluc3RlYWQgb2YgcmVjdXJzaW5nIGlmIHBvc3NpYmxlLlxuICAgICAgZG9uZUFyZ3MgPSBhcmdzO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNhbGxiYWNrLmFwcGx5KHVuZGVmaW5lZCwgYXJncyk7XG4gIH07XG5cbiAgdmFyIG5leHQgPSBmdW5jdGlvbiBuZXh0KCkge1xuICAgIGlmIChpc0RvbmUpIHJldHVybjtcblxuICAgIGhhc05leHQgPSB0cnVlO1xuXG4gICAgaWYgKGlzU3luYykgcmV0dXJuOyAvLyBJdGVyYXRlIGluc3RlYWQgb2YgcmVjdXJzaW5nIGlmIHBvc3NpYmxlLlxuXG4gICAgaXNTeW5jID0gdHJ1ZTtcblxuICAgIHdoaWxlICghaXNEb25lICYmIGN1cnJlbnRUdXJuIDwgdHVybnMgJiYgaGFzTmV4dCkge1xuICAgICAgaGFzTmV4dCA9IGZhbHNlO1xuICAgICAgd29yayhjdXJyZW50VHVybisrLCBuZXh0LCBkb25lKTtcbiAgICB9XG5cbiAgICBpc1N5bmMgPSBmYWxzZTtcblxuICAgIGlmIChpc0RvbmUpIHtcbiAgICAgIC8vIFRoaXMgbWVhbnMgdGhlIGxvb3AgZmluaXNoZWQgc3luY2hyb25vdXNseS5cbiAgICAgIGNhbGxiYWNrLmFwcGx5KHVuZGVmaW5lZCwgX3RvQ29uc3VtYWJsZUFycmF5KGRvbmVBcmdzKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaWYgKGN1cnJlbnRUdXJuID49IHR1cm5zICYmIGhhc05leHQpIHtcbiAgICAgIGlzRG9uZSA9IHRydWU7XG4gICAgICBjYWxsYmFjaygpO1xuICAgIH1cbiAgfTtcblxuICBuZXh0KCk7XG59OyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuZ28gPSBleHBvcnRzLnJlcGxhY2VMb2NhdGlvbiA9IGV4cG9ydHMucHVzaExvY2F0aW9uID0gZXhwb3J0cy5zdGFydExpc3RlbmVyID0gZXhwb3J0cy5nZXRVc2VyQ29uZmlybWF0aW9uID0gZXhwb3J0cy5nZXRDdXJyZW50TG9jYXRpb24gPSB1bmRlZmluZWQ7XG5cbnZhciBfTG9jYXRpb25VdGlscyA9IHJlcXVpcmUoJy4vTG9jYXRpb25VdGlscycpO1xuXG52YXIgX0RPTVV0aWxzID0gcmVxdWlyZSgnLi9ET01VdGlscycpO1xuXG52YXIgX0RPTVN0YXRlU3RvcmFnZSA9IHJlcXVpcmUoJy4vRE9NU3RhdGVTdG9yYWdlJyk7XG5cbnZhciBfUGF0aFV0aWxzID0gcmVxdWlyZSgnLi9QYXRoVXRpbHMnKTtcblxuLyogZXNsaW50LWRpc2FibGUgbm8tYWxlcnQgKi9cblxuXG52YXIgUG9wU3RhdGVFdmVudCA9ICdwb3BzdGF0ZSc7XG5cbnZhciBfY3JlYXRlTG9jYXRpb24gPSBmdW5jdGlvbiBfY3JlYXRlTG9jYXRpb24oaGlzdG9yeVN0YXRlKSB7XG4gIHZhciBrZXkgPSBoaXN0b3J5U3RhdGUgJiYgaGlzdG9yeVN0YXRlLmtleTtcblxuICByZXR1cm4gKDAsIF9Mb2NhdGlvblV0aWxzLmNyZWF0ZUxvY2F0aW9uKSh7XG4gICAgcGF0aG5hbWU6IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSxcbiAgICBzZWFyY2g6IHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gsXG4gICAgaGFzaDogd2luZG93LmxvY2F0aW9uLmhhc2gsXG4gICAgc3RhdGU6IGtleSA/ICgwLCBfRE9NU3RhdGVTdG9yYWdlLnJlYWRTdGF0ZSkoa2V5KSA6IHVuZGVmaW5lZFxuICB9LCB1bmRlZmluZWQsIGtleSk7XG59O1xuXG52YXIgZ2V0Q3VycmVudExvY2F0aW9uID0gZXhwb3J0cy5nZXRDdXJyZW50TG9jYXRpb24gPSBmdW5jdGlvbiBnZXRDdXJyZW50TG9jYXRpb24oKSB7XG4gIHZhciBoaXN0b3J5U3RhdGUgPSB2b2lkIDA7XG4gIHRyeSB7XG4gICAgaGlzdG9yeVN0YXRlID0gd2luZG93Lmhpc3Rvcnkuc3RhdGUgfHwge307XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgLy8gSUUgMTEgc29tZXRpbWVzIHRocm93cyB3aGVuIGFjY2Vzc2luZyB3aW5kb3cuaGlzdG9yeS5zdGF0ZVxuICAgIC8vIFNlZSBodHRwczovL2dpdGh1Yi5jb20vbWphY2tzb24vaGlzdG9yeS9wdWxsLzI4OVxuICAgIGhpc3RvcnlTdGF0ZSA9IHt9O1xuICB9XG5cbiAgcmV0dXJuIF9jcmVhdGVMb2NhdGlvbihoaXN0b3J5U3RhdGUpO1xufTtcblxudmFyIGdldFVzZXJDb25maXJtYXRpb24gPSBleHBvcnRzLmdldFVzZXJDb25maXJtYXRpb24gPSBmdW5jdGlvbiBnZXRVc2VyQ29uZmlybWF0aW9uKG1lc3NhZ2UsIGNhbGxiYWNrKSB7XG4gIHJldHVybiBjYWxsYmFjayh3aW5kb3cuY29uZmlybShtZXNzYWdlKSk7XG59O1xuXG52YXIgc3RhcnRMaXN0ZW5lciA9IGV4cG9ydHMuc3RhcnRMaXN0ZW5lciA9IGZ1bmN0aW9uIHN0YXJ0TGlzdGVuZXIobGlzdGVuZXIpIHtcbiAgdmFyIGhhbmRsZVBvcFN0YXRlID0gZnVuY3Rpb24gaGFuZGxlUG9wU3RhdGUoZXZlbnQpIHtcbiAgICBpZiAoZXZlbnQuc3RhdGUgIT09IHVuZGVmaW5lZCkgLy8gSWdub3JlIGV4dHJhbmVvdXMgcG9wc3RhdGUgZXZlbnRzIGluIFdlYktpdFxuICAgICAgbGlzdGVuZXIoX2NyZWF0ZUxvY2F0aW9uKGV2ZW50LnN0YXRlKSk7XG4gIH07XG5cbiAgKDAsIF9ET01VdGlscy5hZGRFdmVudExpc3RlbmVyKSh3aW5kb3csIFBvcFN0YXRlRXZlbnQsIGhhbmRsZVBvcFN0YXRlKTtcblxuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoMCwgX0RPTVV0aWxzLnJlbW92ZUV2ZW50TGlzdGVuZXIpKHdpbmRvdywgUG9wU3RhdGVFdmVudCwgaGFuZGxlUG9wU3RhdGUpO1xuICB9O1xufTtcblxudmFyIHVwZGF0ZUxvY2F0aW9uID0gZnVuY3Rpb24gdXBkYXRlTG9jYXRpb24obG9jYXRpb24sIHVwZGF0ZVN0YXRlKSB7XG4gIHZhciBzdGF0ZSA9IGxvY2F0aW9uLnN0YXRlO1xuICB2YXIga2V5ID0gbG9jYXRpb24ua2V5O1xuXG5cbiAgaWYgKHN0YXRlICE9PSB1bmRlZmluZWQpICgwLCBfRE9NU3RhdGVTdG9yYWdlLnNhdmVTdGF0ZSkoa2V5LCBzdGF0ZSk7XG5cbiAgdXBkYXRlU3RhdGUoeyBrZXk6IGtleSB9LCAoMCwgX1BhdGhVdGlscy5jcmVhdGVQYXRoKShsb2NhdGlvbikpO1xufTtcblxudmFyIHB1c2hMb2NhdGlvbiA9IGV4cG9ydHMucHVzaExvY2F0aW9uID0gZnVuY3Rpb24gcHVzaExvY2F0aW9uKGxvY2F0aW9uKSB7XG4gIHJldHVybiB1cGRhdGVMb2NhdGlvbihsb2NhdGlvbiwgZnVuY3Rpb24gKHN0YXRlLCBwYXRoKSB7XG4gICAgcmV0dXJuIHdpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZShzdGF0ZSwgbnVsbCwgcGF0aCk7XG4gIH0pO1xufTtcblxudmFyIHJlcGxhY2VMb2NhdGlvbiA9IGV4cG9ydHMucmVwbGFjZUxvY2F0aW9uID0gZnVuY3Rpb24gcmVwbGFjZUxvY2F0aW9uKGxvY2F0aW9uKSB7XG4gIHJldHVybiB1cGRhdGVMb2NhdGlvbihsb2NhdGlvbiwgZnVuY3Rpb24gKHN0YXRlLCBwYXRoKSB7XG4gICAgcmV0dXJuIHdpbmRvdy5oaXN0b3J5LnJlcGxhY2VTdGF0ZShzdGF0ZSwgbnVsbCwgcGF0aCk7XG4gIH0pO1xufTtcblxudmFyIGdvID0gZXhwb3J0cy5nbyA9IGZ1bmN0aW9uIGdvKG4pIHtcbiAgaWYgKG4pIHdpbmRvdy5oaXN0b3J5LmdvKG4pO1xufTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5leHBvcnRzLnJlYWRTdGF0ZSA9IGV4cG9ydHMuc2F2ZVN0YXRlID0gdW5kZWZpbmVkO1xuXG52YXIgX3dhcm5pbmcgPSByZXF1aXJlKCd3YXJuaW5nJyk7XG5cbnZhciBfd2FybmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF93YXJuaW5nKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxudmFyIFF1b3RhRXhjZWVkZWRFcnJvcnMgPSBbJ1F1b3RhRXhjZWVkZWRFcnJvcicsICdRVU9UQV9FWENFRURFRF9FUlInXTsgLyogZXNsaW50LWRpc2FibGUgbm8tZW1wdHkgKi9cblxuXG52YXIgU2VjdXJpdHlFcnJvciA9ICdTZWN1cml0eUVycm9yJztcbnZhciBLZXlQcmVmaXggPSAnQEBIaXN0b3J5Lyc7XG5cbnZhciBjcmVhdGVLZXkgPSBmdW5jdGlvbiBjcmVhdGVLZXkoa2V5KSB7XG4gIHJldHVybiBLZXlQcmVmaXggKyBrZXk7XG59O1xuXG52YXIgc2F2ZVN0YXRlID0gZXhwb3J0cy5zYXZlU3RhdGUgPSBmdW5jdGlvbiBzYXZlU3RhdGUoa2V5LCBzdGF0ZSkge1xuICBpZiAoIXdpbmRvdy5zZXNzaW9uU3RvcmFnZSkge1xuICAgIC8vIFNlc3Npb24gc3RvcmFnZSBpcyBub3QgYXZhaWxhYmxlIG9yIGhpZGRlbi5cbiAgICAvLyBzZXNzaW9uU3RvcmFnZSBpcyB1bmRlZmluZWQgaW4gSW50ZXJuZXQgRXhwbG9yZXIgd2hlbiBzZXJ2ZWQgdmlhIGZpbGUgcHJvdG9jb2wuXG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/ICgwLCBfd2FybmluZzIuZGVmYXVsdCkoZmFsc2UsICdbaGlzdG9yeV0gVW5hYmxlIHRvIHNhdmUgc3RhdGU7IHNlc3Npb25TdG9yYWdlIGlzIG5vdCBhdmFpbGFibGUnKSA6IHZvaWQgMDtcbiAgICByZXR1cm47XG4gIH1cblxuICB0cnkge1xuICAgIGlmIChzdGF0ZSA9PSBudWxsKSB7XG4gICAgICB3aW5kb3cuc2Vzc2lvblN0b3JhZ2UucmVtb3ZlSXRlbShjcmVhdGVLZXkoa2V5KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHdpbmRvdy5zZXNzaW9uU3RvcmFnZS5zZXRJdGVtKGNyZWF0ZUtleShrZXkpLCBKU09OLnN0cmluZ2lmeShzdGF0ZSkpO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IubmFtZSA9PT0gU2VjdXJpdHlFcnJvcikge1xuICAgICAgLy8gQmxvY2tpbmcgY29va2llcyBpbiBDaHJvbWUvRmlyZWZveC9TYWZhcmkgdGhyb3dzIFNlY3VyaXR5RXJyb3Igb24gYW55XG4gICAgICAvLyBhdHRlbXB0IHRvIGFjY2VzcyB3aW5kb3cuc2Vzc2lvblN0b3JhZ2UuXG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gKDAsIF93YXJuaW5nMi5kZWZhdWx0KShmYWxzZSwgJ1toaXN0b3J5XSBVbmFibGUgdG8gc2F2ZSBzdGF0ZTsgc2Vzc2lvblN0b3JhZ2UgaXMgbm90IGF2YWlsYWJsZSBkdWUgdG8gc2VjdXJpdHkgc2V0dGluZ3MnKSA6IHZvaWQgMDtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChRdW90YUV4Y2VlZGVkRXJyb3JzLmluZGV4T2YoZXJyb3IubmFtZSkgPj0gMCAmJiB3aW5kb3cuc2Vzc2lvblN0b3JhZ2UubGVuZ3RoID09PSAwKSB7XG4gICAgICAvLyBTYWZhcmkgXCJwcml2YXRlIG1vZGVcIiB0aHJvd3MgUXVvdGFFeGNlZWRlZEVycm9yLlxuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/ICgwLCBfd2FybmluZzIuZGVmYXVsdCkoZmFsc2UsICdbaGlzdG9yeV0gVW5hYmxlIHRvIHNhdmUgc3RhdGU7IHNlc3Npb25TdG9yYWdlIGlzIG5vdCBhdmFpbGFibGUgaW4gU2FmYXJpIHByaXZhdGUgbW9kZScpIDogdm9pZCAwO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn07XG5cbnZhciByZWFkU3RhdGUgPSBleHBvcnRzLnJlYWRTdGF0ZSA9IGZ1bmN0aW9uIHJlYWRTdGF0ZShrZXkpIHtcbiAgdmFyIGpzb24gPSB2b2lkIDA7XG4gIHRyeSB7XG4gICAganNvbiA9IHdpbmRvdy5zZXNzaW9uU3RvcmFnZS5nZXRJdGVtKGNyZWF0ZUtleShrZXkpKTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBpZiAoZXJyb3IubmFtZSA9PT0gU2VjdXJpdHlFcnJvcikge1xuICAgICAgLy8gQmxvY2tpbmcgY29va2llcyBpbiBDaHJvbWUvRmlyZWZveC9TYWZhcmkgdGhyb3dzIFNlY3VyaXR5RXJyb3Igb24gYW55XG4gICAgICAvLyBhdHRlbXB0IHRvIGFjY2VzcyB3aW5kb3cuc2Vzc2lvblN0b3JhZ2UuXG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gKDAsIF93YXJuaW5nMi5kZWZhdWx0KShmYWxzZSwgJ1toaXN0b3J5XSBVbmFibGUgdG8gcmVhZCBzdGF0ZTsgc2Vzc2lvblN0b3JhZ2UgaXMgbm90IGF2YWlsYWJsZSBkdWUgdG8gc2VjdXJpdHkgc2V0dGluZ3MnKSA6IHZvaWQgMDtcblxuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG4gIH1cblxuICBpZiAoanNvbikge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4gSlNPTi5wYXJzZShqc29uKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgLy8gSWdub3JlIGludmFsaWQgSlNPTi5cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdW5kZWZpbmVkO1xufTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG52YXIgYWRkRXZlbnRMaXN0ZW5lciA9IGV4cG9ydHMuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uIGFkZEV2ZW50TGlzdGVuZXIobm9kZSwgZXZlbnQsIGxpc3RlbmVyKSB7XG4gIHJldHVybiBub2RlLmFkZEV2ZW50TGlzdGVuZXIgPyBub2RlLmFkZEV2ZW50TGlzdGVuZXIoZXZlbnQsIGxpc3RlbmVyLCBmYWxzZSkgOiBub2RlLmF0dGFjaEV2ZW50KCdvbicgKyBldmVudCwgbGlzdGVuZXIpO1xufTtcblxudmFyIHJlbW92ZUV2ZW50TGlzdGVuZXIgPSBleHBvcnRzLnJlbW92ZUV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiByZW1vdmVFdmVudExpc3RlbmVyKG5vZGUsIGV2ZW50LCBsaXN0ZW5lcikge1xuICByZXR1cm4gbm9kZS5yZW1vdmVFdmVudExpc3RlbmVyID8gbm9kZS5yZW1vdmVFdmVudExpc3RlbmVyKGV2ZW50LCBsaXN0ZW5lciwgZmFsc2UpIDogbm9kZS5kZXRhY2hFdmVudCgnb24nICsgZXZlbnQsIGxpc3RlbmVyKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIGlmIHRoZSBIVE1MNSBoaXN0b3J5IEFQSSBpcyBzdXBwb3J0ZWQuIFRha2VuIGZyb20gTW9kZXJuaXpyLlxuICpcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9Nb2Rlcm5penIvTW9kZXJuaXpyL2Jsb2IvbWFzdGVyL0xJQ0VOU0VcbiAqIGh0dHBzOi8vZ2l0aHViLmNvbS9Nb2Rlcm5penIvTW9kZXJuaXpyL2Jsb2IvbWFzdGVyL2ZlYXR1cmUtZGV0ZWN0cy9oaXN0b3J5LmpzXG4gKiBjaGFuZ2VkIHRvIGF2b2lkIGZhbHNlIG5lZ2F0aXZlcyBmb3IgV2luZG93cyBQaG9uZXM6IGh0dHBzOi8vZ2l0aHViLmNvbS9yZWFjdGpzL3JlYWN0LXJvdXRlci9pc3N1ZXMvNTg2XG4gKi9cbnZhciBzdXBwb3J0c0hpc3RvcnkgPSBleHBvcnRzLnN1cHBvcnRzSGlzdG9yeSA9IGZ1bmN0aW9uIHN1cHBvcnRzSGlzdG9yeSgpIHtcbiAgdmFyIHVhID0gd2luZG93Lm5hdmlnYXRvci51c2VyQWdlbnQ7XG5cbiAgaWYgKCh1YS5pbmRleE9mKCdBbmRyb2lkIDIuJykgIT09IC0xIHx8IHVhLmluZGV4T2YoJ0FuZHJvaWQgNC4wJykgIT09IC0xKSAmJiB1YS5pbmRleE9mKCdNb2JpbGUgU2FmYXJpJykgIT09IC0xICYmIHVhLmluZGV4T2YoJ0Nocm9tZScpID09PSAtMSAmJiB1YS5pbmRleE9mKCdXaW5kb3dzIFBob25lJykgPT09IC0xKSByZXR1cm4gZmFsc2U7XG5cbiAgcmV0dXJuIHdpbmRvdy5oaXN0b3J5ICYmICdwdXNoU3RhdGUnIGluIHdpbmRvdy5oaXN0b3J5O1xufTtcblxuLyoqXG4gKiBSZXR1cm5zIGZhbHNlIGlmIHVzaW5nIGdvKG4pIHdpdGggaGFzaCBoaXN0b3J5IGNhdXNlcyBhIGZ1bGwgcGFnZSByZWxvYWQuXG4gKi9cbnZhciBzdXBwb3J0c0dvV2l0aG91dFJlbG9hZFVzaW5nSGFzaCA9IGV4cG9ydHMuc3VwcG9ydHNHb1dpdGhvdXRSZWxvYWRVc2luZ0hhc2ggPSBmdW5jdGlvbiBzdXBwb3J0c0dvV2l0aG91dFJlbG9hZFVzaW5nSGFzaCgpIHtcbiAgcmV0dXJuIHdpbmRvdy5uYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ0ZpcmVmb3gnKSA9PT0gLTE7XG59OyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbnZhciBjYW5Vc2VET00gPSBleHBvcnRzLmNhblVzZURPTSA9ICEhKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdy5kb2N1bWVudCAmJiB3aW5kb3cuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5yZXBsYWNlTG9jYXRpb24gPSBleHBvcnRzLnB1c2hMb2NhdGlvbiA9IGV4cG9ydHMuc3RhcnRMaXN0ZW5lciA9IGV4cG9ydHMuZ2V0Q3VycmVudExvY2F0aW9uID0gZXhwb3J0cy5nbyA9IGV4cG9ydHMuZ2V0VXNlckNvbmZpcm1hdGlvbiA9IHVuZGVmaW5lZDtcblxudmFyIF9Ccm93c2VyUHJvdG9jb2wgPSByZXF1aXJlKCcuL0Jyb3dzZXJQcm90b2NvbCcpO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ2dldFVzZXJDb25maXJtYXRpb24nLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiBfQnJvd3NlclByb3RvY29sLmdldFVzZXJDb25maXJtYXRpb247XG4gIH1cbn0pO1xuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdnbycsIHtcbiAgZW51bWVyYWJsZTogdHJ1ZSxcbiAgZ2V0OiBmdW5jdGlvbiBnZXQoKSB7XG4gICAgcmV0dXJuIF9Ccm93c2VyUHJvdG9jb2wuZ287XG4gIH1cbn0pO1xuXG52YXIgX3dhcm5pbmcgPSByZXF1aXJlKCd3YXJuaW5nJyk7XG5cbnZhciBfd2FybmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF93YXJuaW5nKTtcblxudmFyIF9Mb2NhdGlvblV0aWxzID0gcmVxdWlyZSgnLi9Mb2NhdGlvblV0aWxzJyk7XG5cbnZhciBfRE9NVXRpbHMgPSByZXF1aXJlKCcuL0RPTVV0aWxzJyk7XG5cbnZhciBfRE9NU3RhdGVTdG9yYWdlID0gcmVxdWlyZSgnLi9ET01TdGF0ZVN0b3JhZ2UnKTtcblxudmFyIF9QYXRoVXRpbHMgPSByZXF1aXJlKCcuL1BhdGhVdGlscycpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG52YXIgSGFzaENoYW5nZUV2ZW50ID0gJ2hhc2hjaGFuZ2UnO1xuXG52YXIgZ2V0SGFzaFBhdGggPSBmdW5jdGlvbiBnZXRIYXNoUGF0aCgpIHtcbiAgLy8gV2UgY2FuJ3QgdXNlIHdpbmRvdy5sb2NhdGlvbi5oYXNoIGhlcmUgYmVjYXVzZSBpdCdzIG5vdFxuICAvLyBjb25zaXN0ZW50IGFjcm9zcyBicm93c2VycyAtIEZpcmVmb3ggd2lsbCBwcmUtZGVjb2RlIGl0IVxuICB2YXIgaHJlZiA9IHdpbmRvdy5sb2NhdGlvbi5ocmVmO1xuICB2YXIgaW5kZXggPSBocmVmLmluZGV4T2YoJyMnKTtcbiAgcmV0dXJuIGluZGV4ID09PSAtMSA/ICcnIDogaHJlZi5zdWJzdHJpbmcoaW5kZXggKyAxKTtcbn07XG5cbnZhciBwdXNoSGFzaFBhdGggPSBmdW5jdGlvbiBwdXNoSGFzaFBhdGgocGF0aCkge1xuICByZXR1cm4gd2luZG93LmxvY2F0aW9uLmhhc2ggPSBwYXRoO1xufTtcblxudmFyIHJlcGxhY2VIYXNoUGF0aCA9IGZ1bmN0aW9uIHJlcGxhY2VIYXNoUGF0aChwYXRoKSB7XG4gIHZhciBpID0gd2luZG93LmxvY2F0aW9uLmhyZWYuaW5kZXhPZignIycpO1xuXG4gIHdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKHdpbmRvdy5sb2NhdGlvbi5ocmVmLnNsaWNlKDAsIGkgPj0gMCA/IGkgOiAwKSArICcjJyArIHBhdGgpO1xufTtcblxudmFyIGVuc3VyZVNsYXNoID0gZnVuY3Rpb24gZW5zdXJlU2xhc2goKSB7XG4gIHZhciBwYXRoID0gZ2V0SGFzaFBhdGgoKTtcblxuICBpZiAoKDAsIF9QYXRoVXRpbHMuaXNBYnNvbHV0ZVBhdGgpKHBhdGgpKSByZXR1cm4gdHJ1ZTtcblxuICByZXBsYWNlSGFzaFBhdGgoJy8nICsgcGF0aCk7XG5cbiAgcmV0dXJuIGZhbHNlO1xufTtcblxudmFyIGdldEN1cnJlbnRMb2NhdGlvbiA9IGV4cG9ydHMuZ2V0Q3VycmVudExvY2F0aW9uID0gZnVuY3Rpb24gZ2V0Q3VycmVudExvY2F0aW9uKHF1ZXJ5S2V5KSB7XG4gIHZhciBwYXRoID0gZ2V0SGFzaFBhdGgoKTtcbiAgdmFyIGtleSA9ICgwLCBfUGF0aFV0aWxzLmdldFF1ZXJ5U3RyaW5nVmFsdWVGcm9tUGF0aCkocGF0aCwgcXVlcnlLZXkpO1xuXG4gIHZhciBzdGF0ZSA9IHZvaWQgMDtcbiAgaWYgKGtleSkge1xuICAgIHBhdGggPSAoMCwgX1BhdGhVdGlscy5zdHJpcFF1ZXJ5U3RyaW5nVmFsdWVGcm9tUGF0aCkocGF0aCwgcXVlcnlLZXkpO1xuICAgIHN0YXRlID0gKDAsIF9ET01TdGF0ZVN0b3JhZ2UucmVhZFN0YXRlKShrZXkpO1xuICB9XG5cbiAgdmFyIGluaXQgPSAoMCwgX1BhdGhVdGlscy5wYXJzZVBhdGgpKHBhdGgpO1xuICBpbml0LnN0YXRlID0gc3RhdGU7XG5cbiAgcmV0dXJuICgwLCBfTG9jYXRpb25VdGlscy5jcmVhdGVMb2NhdGlvbikoaW5pdCwgdW5kZWZpbmVkLCBrZXkpO1xufTtcblxudmFyIHByZXZMb2NhdGlvbiA9IHZvaWQgMDtcblxudmFyIHN0YXJ0TGlzdGVuZXIgPSBleHBvcnRzLnN0YXJ0TGlzdGVuZXIgPSBmdW5jdGlvbiBzdGFydExpc3RlbmVyKGxpc3RlbmVyLCBxdWVyeUtleSkge1xuICB2YXIgaGFuZGxlSGFzaENoYW5nZSA9IGZ1bmN0aW9uIGhhbmRsZUhhc2hDaGFuZ2UoKSB7XG4gICAgaWYgKCFlbnN1cmVTbGFzaCgpKSByZXR1cm47IC8vIEhhc2ggcGF0aCBtdXN0IGFsd2F5cyBiZWdpbiB3aXRoIGEgL1xuXG4gICAgdmFyIGN1cnJlbnRMb2NhdGlvbiA9IGdldEN1cnJlbnRMb2NhdGlvbihxdWVyeUtleSk7XG5cbiAgICBpZiAocHJldkxvY2F0aW9uICYmIGN1cnJlbnRMb2NhdGlvbi5rZXkgJiYgcHJldkxvY2F0aW9uLmtleSA9PT0gY3VycmVudExvY2F0aW9uLmtleSkgcmV0dXJuOyAvLyBJZ25vcmUgZXh0cmFuZW91cyBoYXNoY2hhbmdlIGV2ZW50c1xuXG4gICAgcHJldkxvY2F0aW9uID0gY3VycmVudExvY2F0aW9uO1xuXG4gICAgbGlzdGVuZXIoY3VycmVudExvY2F0aW9uKTtcbiAgfTtcblxuICBlbnN1cmVTbGFzaCgpO1xuICAoMCwgX0RPTVV0aWxzLmFkZEV2ZW50TGlzdGVuZXIpKHdpbmRvdywgSGFzaENoYW5nZUV2ZW50LCBoYW5kbGVIYXNoQ2hhbmdlKTtcblxuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiAoMCwgX0RPTVV0aWxzLnJlbW92ZUV2ZW50TGlzdGVuZXIpKHdpbmRvdywgSGFzaENoYW5nZUV2ZW50LCBoYW5kbGVIYXNoQ2hhbmdlKTtcbiAgfTtcbn07XG5cbnZhciB1cGRhdGVMb2NhdGlvbiA9IGZ1bmN0aW9uIHVwZGF0ZUxvY2F0aW9uKGxvY2F0aW9uLCBxdWVyeUtleSwgdXBkYXRlSGFzaCkge1xuICB2YXIgc3RhdGUgPSBsb2NhdGlvbi5zdGF0ZTtcbiAgdmFyIGtleSA9IGxvY2F0aW9uLmtleTtcblxuICB2YXIgcGF0aCA9ICgwLCBfUGF0aFV0aWxzLmNyZWF0ZVBhdGgpKGxvY2F0aW9uKTtcblxuICBpZiAoc3RhdGUgIT09IHVuZGVmaW5lZCkge1xuICAgIHBhdGggPSAoMCwgX1BhdGhVdGlscy5hZGRRdWVyeVN0cmluZ1ZhbHVlVG9QYXRoKShwYXRoLCBxdWVyeUtleSwga2V5KTtcbiAgICAoMCwgX0RPTVN0YXRlU3RvcmFnZS5zYXZlU3RhdGUpKGtleSwgc3RhdGUpO1xuICB9XG5cbiAgcHJldkxvY2F0aW9uID0gbG9jYXRpb247XG5cbiAgdXBkYXRlSGFzaChwYXRoKTtcbn07XG5cbnZhciBwdXNoTG9jYXRpb24gPSBleHBvcnRzLnB1c2hMb2NhdGlvbiA9IGZ1bmN0aW9uIHB1c2hMb2NhdGlvbihsb2NhdGlvbiwgcXVlcnlLZXkpIHtcbiAgcmV0dXJuIHVwZGF0ZUxvY2F0aW9uKGxvY2F0aW9uLCBxdWVyeUtleSwgZnVuY3Rpb24gKHBhdGgpIHtcbiAgICBpZiAoZ2V0SGFzaFBhdGgoKSAhPT0gcGF0aCkge1xuICAgICAgcHVzaEhhc2hQYXRoKHBhdGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gKDAsIF93YXJuaW5nMi5kZWZhdWx0KShmYWxzZSwgJ1lvdSBjYW5ub3QgUFVTSCB0aGUgc2FtZSBwYXRoIHVzaW5nIGhhc2ggaGlzdG9yeScpIDogdm9pZCAwO1xuICAgIH1cbiAgfSk7XG59O1xuXG52YXIgcmVwbGFjZUxvY2F0aW9uID0gZXhwb3J0cy5yZXBsYWNlTG9jYXRpb24gPSBmdW5jdGlvbiByZXBsYWNlTG9jYXRpb24obG9jYXRpb24sIHF1ZXJ5S2V5KSB7XG4gIHJldHVybiB1cGRhdGVMb2NhdGlvbihsb2NhdGlvbiwgcXVlcnlLZXksIGZ1bmN0aW9uIChwYXRoKSB7XG4gICAgaWYgKGdldEhhc2hQYXRoKCkgIT09IHBhdGgpIHJlcGxhY2VIYXNoUGF0aChwYXRoKTtcbiAgfSk7XG59OyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMubG9jYXRpb25zQXJlRXF1YWwgPSBleHBvcnRzLnN0YXRlc0FyZUVxdWFsID0gZXhwb3J0cy5jcmVhdGVMb2NhdGlvbiA9IGV4cG9ydHMuY3JlYXRlUXVlcnkgPSB1bmRlZmluZWQ7XG5cbnZhciBfdHlwZW9mID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCA/IFwic3ltYm9sXCIgOiB0eXBlb2Ygb2JqOyB9O1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG52YXIgX2ludmFyaWFudCA9IHJlcXVpcmUoJ2ludmFyaWFudCcpO1xuXG52YXIgX2ludmFyaWFudDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pbnZhcmlhbnQpO1xuXG52YXIgX1BhdGhVdGlscyA9IHJlcXVpcmUoJy4vUGF0aFV0aWxzJyk7XG5cbnZhciBfQWN0aW9ucyA9IHJlcXVpcmUoJy4vQWN0aW9ucycpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG52YXIgY3JlYXRlUXVlcnkgPSBleHBvcnRzLmNyZWF0ZVF1ZXJ5ID0gZnVuY3Rpb24gY3JlYXRlUXVlcnkocHJvcHMpIHtcbiAgcmV0dXJuIF9leHRlbmRzKE9iamVjdC5jcmVhdGUobnVsbCksIHByb3BzKTtcbn07XG5cbnZhciBjcmVhdGVMb2NhdGlvbiA9IGV4cG9ydHMuY3JlYXRlTG9jYXRpb24gPSBmdW5jdGlvbiBjcmVhdGVMb2NhdGlvbigpIHtcbiAgdmFyIGlucHV0ID0gYXJndW1lbnRzLmxlbmd0aCA8PSAwIHx8IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8gJy8nIDogYXJndW1lbnRzWzBdO1xuICB2YXIgYWN0aW9uID0gYXJndW1lbnRzLmxlbmd0aCA8PSAxIHx8IGFyZ3VtZW50c1sxXSA9PT0gdW5kZWZpbmVkID8gX0FjdGlvbnMuUE9QIDogYXJndW1lbnRzWzFdO1xuICB2YXIga2V5ID0gYXJndW1lbnRzLmxlbmd0aCA8PSAyIHx8IGFyZ3VtZW50c1syXSA9PT0gdW5kZWZpbmVkID8gbnVsbCA6IGFyZ3VtZW50c1syXTtcblxuICB2YXIgb2JqZWN0ID0gdHlwZW9mIGlucHV0ID09PSAnc3RyaW5nJyA/ICgwLCBfUGF0aFV0aWxzLnBhcnNlUGF0aCkoaW5wdXQpIDogaW5wdXQ7XG5cbiAgdmFyIHBhdGhuYW1lID0gb2JqZWN0LnBhdGhuYW1lIHx8ICcvJztcbiAgdmFyIHNlYXJjaCA9IG9iamVjdC5zZWFyY2ggfHwgJyc7XG4gIHZhciBoYXNoID0gb2JqZWN0Lmhhc2ggfHwgJyc7XG4gIHZhciBzdGF0ZSA9IG9iamVjdC5zdGF0ZTtcblxuICByZXR1cm4ge1xuICAgIHBhdGhuYW1lOiBwYXRobmFtZSxcbiAgICBzZWFyY2g6IHNlYXJjaCxcbiAgICBoYXNoOiBoYXNoLFxuICAgIHN0YXRlOiBzdGF0ZSxcbiAgICBhY3Rpb246IGFjdGlvbixcbiAgICBrZXk6IGtleVxuICB9O1xufTtcblxudmFyIGlzRGF0ZSA9IGZ1bmN0aW9uIGlzRGF0ZShvYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpID09PSAnW29iamVjdCBEYXRlXSc7XG59O1xuXG52YXIgc3RhdGVzQXJlRXF1YWwgPSBleHBvcnRzLnN0YXRlc0FyZUVxdWFsID0gZnVuY3Rpb24gc3RhdGVzQXJlRXF1YWwoYSwgYikge1xuICBpZiAoYSA9PT0gYikgcmV0dXJuIHRydWU7XG5cbiAgdmFyIHR5cGVvZkEgPSB0eXBlb2YgYSA9PT0gJ3VuZGVmaW5lZCcgPyAndW5kZWZpbmVkJyA6IF90eXBlb2YoYSk7XG4gIHZhciB0eXBlb2ZCID0gdHlwZW9mIGIgPT09ICd1bmRlZmluZWQnID8gJ3VuZGVmaW5lZCcgOiBfdHlwZW9mKGIpO1xuXG4gIGlmICh0eXBlb2ZBICE9PSB0eXBlb2ZCKSByZXR1cm4gZmFsc2U7XG5cbiAgISh0eXBlb2ZBICE9PSAnZnVuY3Rpb24nKSA/IHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicgPyAoMCwgX2ludmFyaWFudDIuZGVmYXVsdCkoZmFsc2UsICdZb3UgbXVzdCBub3Qgc3RvcmUgZnVuY3Rpb25zIGluIGxvY2F0aW9uIHN0YXRlJykgOiAoMCwgX2ludmFyaWFudDIuZGVmYXVsdCkoZmFsc2UpIDogdm9pZCAwO1xuXG4gIC8vIE5vdCB0aGUgc2FtZSBvYmplY3QsIGJ1dCBzYW1lIHR5cGUuXG4gIGlmICh0eXBlb2ZBID09PSAnb2JqZWN0Jykge1xuICAgICEhKGlzRGF0ZShhKSAmJiBpc0RhdGUoYikpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/ICgwLCBfaW52YXJpYW50Mi5kZWZhdWx0KShmYWxzZSwgJ1lvdSBtdXN0IG5vdCBzdG9yZSBEYXRlIG9iamVjdHMgaW4gbG9jYXRpb24gc3RhdGUnKSA6ICgwLCBfaW52YXJpYW50Mi5kZWZhdWx0KShmYWxzZSkgOiB2b2lkIDA7XG5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoYSkpIHJldHVybiBPYmplY3Qua2V5cyhhKS5ldmVyeShmdW5jdGlvbiAoa2V5KSB7XG4gICAgICByZXR1cm4gc3RhdGVzQXJlRXF1YWwoYVtrZXldLCBiW2tleV0pO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkoYikgJiYgYS5sZW5ndGggPT09IGIubGVuZ3RoICYmIGEuZXZlcnkoZnVuY3Rpb24gKGl0ZW0sIGluZGV4KSB7XG4gICAgICByZXR1cm4gc3RhdGVzQXJlRXF1YWwoaXRlbSwgYltpbmRleF0pO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gQWxsIG90aGVyIHNlcmlhbGl6YWJsZSB0eXBlcyAoc3RyaW5nLCBudW1iZXIsIGJvb2xlYW4pXG4gIC8vIHNob3VsZCBiZSBzdHJpY3QgZXF1YWwuXG4gIHJldHVybiBmYWxzZTtcbn07XG5cbnZhciBsb2NhdGlvbnNBcmVFcXVhbCA9IGV4cG9ydHMubG9jYXRpb25zQXJlRXF1YWwgPSBmdW5jdGlvbiBsb2NhdGlvbnNBcmVFcXVhbChhLCBiKSB7XG4gIHJldHVybiBhLmtleSA9PT0gYi5rZXkgJiZcbiAgLy8gYS5hY3Rpb24gPT09IGIuYWN0aW9uICYmIC8vIERpZmZlcmVudCBhY3Rpb24gIT09IGxvY2F0aW9uIGNoYW5nZS5cbiAgYS5wYXRobmFtZSA9PT0gYi5wYXRobmFtZSAmJiBhLnNlYXJjaCA9PT0gYi5zZWFyY2ggJiYgYS5oYXNoID09PSBiLmhhc2ggJiYgc3RhdGVzQXJlRXF1YWwoYS5zdGF0ZSwgYi5zdGF0ZSk7XG59OyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMuY3JlYXRlUGF0aCA9IGV4cG9ydHMucGFyc2VQYXRoID0gZXhwb3J0cy5nZXRRdWVyeVN0cmluZ1ZhbHVlRnJvbVBhdGggPSBleHBvcnRzLnN0cmlwUXVlcnlTdHJpbmdWYWx1ZUZyb21QYXRoID0gZXhwb3J0cy5hZGRRdWVyeVN0cmluZ1ZhbHVlVG9QYXRoID0gZXhwb3J0cy5pc0Fic29sdXRlUGF0aCA9IHVuZGVmaW5lZDtcblxudmFyIF93YXJuaW5nID0gcmVxdWlyZSgnd2FybmluZycpO1xuXG52YXIgX3dhcm5pbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfd2FybmluZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciBpc0Fic29sdXRlUGF0aCA9IGV4cG9ydHMuaXNBYnNvbHV0ZVBhdGggPSBmdW5jdGlvbiBpc0Fic29sdXRlUGF0aChwYXRoKSB7XG4gIHJldHVybiB0eXBlb2YgcGF0aCA9PT0gJ3N0cmluZycgJiYgcGF0aC5jaGFyQXQoMCkgPT09ICcvJztcbn07XG5cbnZhciBhZGRRdWVyeVN0cmluZ1ZhbHVlVG9QYXRoID0gZXhwb3J0cy5hZGRRdWVyeVN0cmluZ1ZhbHVlVG9QYXRoID0gZnVuY3Rpb24gYWRkUXVlcnlTdHJpbmdWYWx1ZVRvUGF0aChwYXRoLCBrZXksIHZhbHVlKSB7XG4gIHZhciBfcGFyc2VQYXRoID0gcGFyc2VQYXRoKHBhdGgpO1xuXG4gIHZhciBwYXRobmFtZSA9IF9wYXJzZVBhdGgucGF0aG5hbWU7XG4gIHZhciBzZWFyY2ggPSBfcGFyc2VQYXRoLnNlYXJjaDtcbiAgdmFyIGhhc2ggPSBfcGFyc2VQYXRoLmhhc2g7XG5cblxuICByZXR1cm4gY3JlYXRlUGF0aCh7XG4gICAgcGF0aG5hbWU6IHBhdGhuYW1lLFxuICAgIHNlYXJjaDogc2VhcmNoICsgKHNlYXJjaC5pbmRleE9mKCc/JykgPT09IC0xID8gJz8nIDogJyYnKSArIGtleSArICc9JyArIHZhbHVlLFxuICAgIGhhc2g6IGhhc2hcbiAgfSk7XG59O1xuXG52YXIgc3RyaXBRdWVyeVN0cmluZ1ZhbHVlRnJvbVBhdGggPSBleHBvcnRzLnN0cmlwUXVlcnlTdHJpbmdWYWx1ZUZyb21QYXRoID0gZnVuY3Rpb24gc3RyaXBRdWVyeVN0cmluZ1ZhbHVlRnJvbVBhdGgocGF0aCwga2V5KSB7XG4gIHZhciBfcGFyc2VQYXRoMiA9IHBhcnNlUGF0aChwYXRoKTtcblxuICB2YXIgcGF0aG5hbWUgPSBfcGFyc2VQYXRoMi5wYXRobmFtZTtcbiAgdmFyIHNlYXJjaCA9IF9wYXJzZVBhdGgyLnNlYXJjaDtcbiAgdmFyIGhhc2ggPSBfcGFyc2VQYXRoMi5oYXNoO1xuXG5cbiAgcmV0dXJuIGNyZWF0ZVBhdGgoe1xuICAgIHBhdGhuYW1lOiBwYXRobmFtZSxcbiAgICBzZWFyY2g6IHNlYXJjaC5yZXBsYWNlKG5ldyBSZWdFeHAoJyhbPyZdKScgKyBrZXkgKyAnPVthLXpBLVowLTldKygmPyknKSwgZnVuY3Rpb24gKG1hdGNoLCBwcmVmaXgsIHN1ZmZpeCkge1xuICAgICAgcmV0dXJuIHByZWZpeCA9PT0gJz8nID8gcHJlZml4IDogc3VmZml4O1xuICAgIH0pLFxuICAgIGhhc2g6IGhhc2hcbiAgfSk7XG59O1xuXG52YXIgZ2V0UXVlcnlTdHJpbmdWYWx1ZUZyb21QYXRoID0gZXhwb3J0cy5nZXRRdWVyeVN0cmluZ1ZhbHVlRnJvbVBhdGggPSBmdW5jdGlvbiBnZXRRdWVyeVN0cmluZ1ZhbHVlRnJvbVBhdGgocGF0aCwga2V5KSB7XG4gIHZhciBfcGFyc2VQYXRoMyA9IHBhcnNlUGF0aChwYXRoKTtcblxuICB2YXIgc2VhcmNoID0gX3BhcnNlUGF0aDMuc2VhcmNoO1xuXG4gIHZhciBtYXRjaCA9IHNlYXJjaC5tYXRjaChuZXcgUmVnRXhwKCdbPyZdJyArIGtleSArICc9KFthLXpBLVowLTldKyknKSk7XG4gIHJldHVybiBtYXRjaCAmJiBtYXRjaFsxXTtcbn07XG5cbnZhciBleHRyYWN0UGF0aCA9IGZ1bmN0aW9uIGV4dHJhY3RQYXRoKHN0cmluZykge1xuICB2YXIgbWF0Y2ggPSBzdHJpbmcubWF0Y2goL14oaHR0cHM/Oik/XFwvXFwvW15cXC9dKi8pO1xuICByZXR1cm4gbWF0Y2ggPT0gbnVsbCA/IHN0cmluZyA6IHN0cmluZy5zdWJzdHJpbmcobWF0Y2hbMF0ubGVuZ3RoKTtcbn07XG5cbnZhciBwYXJzZVBhdGggPSBleHBvcnRzLnBhcnNlUGF0aCA9IGZ1bmN0aW9uIHBhcnNlUGF0aChwYXRoKSB7XG4gIHZhciBwYXRobmFtZSA9IGV4dHJhY3RQYXRoKHBhdGgpO1xuICB2YXIgc2VhcmNoID0gJyc7XG4gIHZhciBoYXNoID0gJyc7XG5cbiAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/ICgwLCBfd2FybmluZzIuZGVmYXVsdCkocGF0aCA9PT0gcGF0aG5hbWUsICdBIHBhdGggbXVzdCBiZSBwYXRobmFtZSArIHNlYXJjaCArIGhhc2ggb25seSwgbm90IGEgZnVsbCBVUkwgbGlrZSBcIiVzXCInLCBwYXRoKSA6IHZvaWQgMDtcblxuICB2YXIgaGFzaEluZGV4ID0gcGF0aG5hbWUuaW5kZXhPZignIycpO1xuICBpZiAoaGFzaEluZGV4ICE9PSAtMSkge1xuICAgIGhhc2ggPSBwYXRobmFtZS5zdWJzdHJpbmcoaGFzaEluZGV4KTtcbiAgICBwYXRobmFtZSA9IHBhdGhuYW1lLnN1YnN0cmluZygwLCBoYXNoSW5kZXgpO1xuICB9XG5cbiAgdmFyIHNlYXJjaEluZGV4ID0gcGF0aG5hbWUuaW5kZXhPZignPycpO1xuICBpZiAoc2VhcmNoSW5kZXggIT09IC0xKSB7XG4gICAgc2VhcmNoID0gcGF0aG5hbWUuc3Vic3RyaW5nKHNlYXJjaEluZGV4KTtcbiAgICBwYXRobmFtZSA9IHBhdGhuYW1lLnN1YnN0cmluZygwLCBzZWFyY2hJbmRleCk7XG4gIH1cblxuICBpZiAocGF0aG5hbWUgPT09ICcnKSBwYXRobmFtZSA9ICcvJztcblxuICByZXR1cm4ge1xuICAgIHBhdGhuYW1lOiBwYXRobmFtZSxcbiAgICBzZWFyY2g6IHNlYXJjaCxcbiAgICBoYXNoOiBoYXNoXG4gIH07XG59O1xuXG52YXIgY3JlYXRlUGF0aCA9IGV4cG9ydHMuY3JlYXRlUGF0aCA9IGZ1bmN0aW9uIGNyZWF0ZVBhdGgobG9jYXRpb24pIHtcbiAgaWYgKGxvY2F0aW9uID09IG51bGwgfHwgdHlwZW9mIGxvY2F0aW9uID09PSAnc3RyaW5nJykgcmV0dXJuIGxvY2F0aW9uO1xuXG4gIHZhciBiYXNlbmFtZSA9IGxvY2F0aW9uLmJhc2VuYW1lO1xuICB2YXIgcGF0aG5hbWUgPSBsb2NhdGlvbi5wYXRobmFtZTtcbiAgdmFyIHNlYXJjaCA9IGxvY2F0aW9uLnNlYXJjaDtcbiAgdmFyIGhhc2ggPSBsb2NhdGlvbi5oYXNoO1xuXG4gIHZhciBwYXRoID0gKGJhc2VuYW1lIHx8ICcnKSArIHBhdGhuYW1lO1xuXG4gIGlmIChzZWFyY2ggJiYgc2VhcmNoICE9PSAnPycpIHBhdGggKz0gc2VhcmNoO1xuXG4gIGlmIChoYXNoKSBwYXRoICs9IGhhc2g7XG5cbiAgcmV0dXJuIHBhdGg7XG59OyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcbmV4cG9ydHMucmVwbGFjZUxvY2F0aW9uID0gZXhwb3J0cy5wdXNoTG9jYXRpb24gPSBleHBvcnRzLmdldEN1cnJlbnRMb2NhdGlvbiA9IGV4cG9ydHMuZ28gPSBleHBvcnRzLmdldFVzZXJDb25maXJtYXRpb24gPSB1bmRlZmluZWQ7XG5cbnZhciBfQnJvd3NlclByb3RvY29sID0gcmVxdWlyZSgnLi9Ccm93c2VyUHJvdG9jb2wnKTtcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsICdnZXRVc2VyQ29uZmlybWF0aW9uJywge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX0Jyb3dzZXJQcm90b2NvbC5nZXRVc2VyQ29uZmlybWF0aW9uO1xuICB9XG59KTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnZ28nLCB7XG4gIGVudW1lcmFibGU6IHRydWUsXG4gIGdldDogZnVuY3Rpb24gZ2V0KCkge1xuICAgIHJldHVybiBfQnJvd3NlclByb3RvY29sLmdvO1xuICB9XG59KTtcblxudmFyIF9Mb2NhdGlvblV0aWxzID0gcmVxdWlyZSgnLi9Mb2NhdGlvblV0aWxzJyk7XG5cbnZhciBfUGF0aFV0aWxzID0gcmVxdWlyZSgnLi9QYXRoVXRpbHMnKTtcblxudmFyIGdldEN1cnJlbnRMb2NhdGlvbiA9IGV4cG9ydHMuZ2V0Q3VycmVudExvY2F0aW9uID0gZnVuY3Rpb24gZ2V0Q3VycmVudExvY2F0aW9uKCkge1xuICByZXR1cm4gKDAsIF9Mb2NhdGlvblV0aWxzLmNyZWF0ZUxvY2F0aW9uKSh3aW5kb3cubG9jYXRpb24pO1xufTtcblxudmFyIHB1c2hMb2NhdGlvbiA9IGV4cG9ydHMucHVzaExvY2F0aW9uID0gZnVuY3Rpb24gcHVzaExvY2F0aW9uKGxvY2F0aW9uKSB7XG4gIHdpbmRvdy5sb2NhdGlvbi5ocmVmID0gKDAsIF9QYXRoVXRpbHMuY3JlYXRlUGF0aCkobG9jYXRpb24pO1xuICByZXR1cm4gZmFsc2U7IC8vIERvbid0IHVwZGF0ZSBsb2NhdGlvblxufTtcblxudmFyIHJlcGxhY2VMb2NhdGlvbiA9IGV4cG9ydHMucmVwbGFjZUxvY2F0aW9uID0gZnVuY3Rpb24gcmVwbGFjZUxvY2F0aW9uKGxvY2F0aW9uKSB7XG4gIHdpbmRvdy5sb2NhdGlvbi5yZXBsYWNlKCgwLCBfUGF0aFV0aWxzLmNyZWF0ZVBhdGgpKGxvY2F0aW9uKSk7XG4gIHJldHVybiBmYWxzZTsgLy8gRG9uJ3QgdXBkYXRlIGxvY2F0aW9uXG59OyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxudmFyIF9pbnZhcmlhbnQgPSByZXF1aXJlKCdpbnZhcmlhbnQnKTtcblxudmFyIF9pbnZhcmlhbnQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaW52YXJpYW50KTtcblxudmFyIF9FeGVjdXRpb25FbnZpcm9ubWVudCA9IHJlcXVpcmUoJy4vRXhlY3V0aW9uRW52aXJvbm1lbnQnKTtcblxudmFyIF9Ccm93c2VyUHJvdG9jb2wgPSByZXF1aXJlKCcuL0Jyb3dzZXJQcm90b2NvbCcpO1xuXG52YXIgQnJvd3NlclByb3RvY29sID0gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQoX0Jyb3dzZXJQcm90b2NvbCk7XG5cbnZhciBfUmVmcmVzaFByb3RvY29sID0gcmVxdWlyZSgnLi9SZWZyZXNoUHJvdG9jb2wnKTtcblxudmFyIFJlZnJlc2hQcm90b2NvbCA9IF9pbnRlcm9wUmVxdWlyZVdpbGRjYXJkKF9SZWZyZXNoUHJvdG9jb2wpO1xuXG52YXIgX0RPTVV0aWxzID0gcmVxdWlyZSgnLi9ET01VdGlscycpO1xuXG52YXIgX2NyZWF0ZUhpc3RvcnkgPSByZXF1aXJlKCcuL2NyZWF0ZUhpc3RvcnknKTtcblxudmFyIF9jcmVhdGVIaXN0b3J5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2NyZWF0ZUhpc3RvcnkpO1xuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChvYmopIHsgaWYgKG9iaiAmJiBvYmouX19lc01vZHVsZSkgeyByZXR1cm4gb2JqOyB9IGVsc2UgeyB2YXIgbmV3T2JqID0ge307IGlmIChvYmogIT0gbnVsbCkgeyBmb3IgKHZhciBrZXkgaW4gb2JqKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpKSBuZXdPYmpba2V5XSA9IG9ialtrZXldOyB9IH0gbmV3T2JqLmRlZmF1bHQgPSBvYmo7IHJldHVybiBuZXdPYmo7IH0gfVxuXG5mdW5jdGlvbiBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KG9iaikgeyByZXR1cm4gb2JqICYmIG9iai5fX2VzTW9kdWxlID8gb2JqIDogeyBkZWZhdWx0OiBvYmogfTsgfVxuXG4vKipcbiAqIENyZWF0ZXMgYW5kIHJldHVybnMgYSBoaXN0b3J5IG9iamVjdCB0aGF0IHVzZXMgSFRNTDUncyBoaXN0b3J5IEFQSVxuICogKHB1c2hTdGF0ZSwgcmVwbGFjZVN0YXRlLCBhbmQgdGhlIHBvcHN0YXRlIGV2ZW50KSB0byBtYW5hZ2UgaGlzdG9yeS5cbiAqIFRoaXMgaXMgdGhlIHJlY29tbWVuZGVkIG1ldGhvZCBvZiBtYW5hZ2luZyBoaXN0b3J5IGluIGJyb3dzZXJzIGJlY2F1c2VcbiAqIGl0IHByb3ZpZGVzIHRoZSBjbGVhbmVzdCBVUkxzLlxuICpcbiAqIE5vdGU6IEluIGJyb3dzZXJzIHRoYXQgZG8gbm90IHN1cHBvcnQgdGhlIEhUTUw1IGhpc3RvcnkgQVBJIGZ1bGxcbiAqIHBhZ2UgcmVsb2FkcyB3aWxsIGJlIHVzZWQgdG8gcHJlc2VydmUgY2xlYW4gVVJMcy4gWW91IGNhbiBmb3JjZSB0aGlzXG4gKiBiZWhhdmlvciB1c2luZyB7IGZvcmNlUmVmcmVzaDogdHJ1ZSB9IGluIG9wdGlvbnMuXG4gKi9cbnZhciBjcmVhdGVCcm93c2VySGlzdG9yeSA9IGZ1bmN0aW9uIGNyZWF0ZUJyb3dzZXJIaXN0b3J5KCkge1xuICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMCB8fCBhcmd1bWVudHNbMF0gPT09IHVuZGVmaW5lZCA/IHt9IDogYXJndW1lbnRzWzBdO1xuXG4gICFfRXhlY3V0aW9uRW52aXJvbm1lbnQuY2FuVXNlRE9NID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/ICgwLCBfaW52YXJpYW50Mi5kZWZhdWx0KShmYWxzZSwgJ0Jyb3dzZXIgaGlzdG9yeSBuZWVkcyBhIERPTScpIDogKDAsIF9pbnZhcmlhbnQyLmRlZmF1bHQpKGZhbHNlKSA6IHZvaWQgMDtcblxuICB2YXIgdXNlUmVmcmVzaCA9IG9wdGlvbnMuZm9yY2VSZWZyZXNoIHx8ICEoMCwgX0RPTVV0aWxzLnN1cHBvcnRzSGlzdG9yeSkoKTtcbiAgdmFyIFByb3RvY29sID0gdXNlUmVmcmVzaCA/IFJlZnJlc2hQcm90b2NvbCA6IEJyb3dzZXJQcm90b2NvbDtcblxuICB2YXIgZ2V0VXNlckNvbmZpcm1hdGlvbiA9IFByb3RvY29sLmdldFVzZXJDb25maXJtYXRpb247XG4gIHZhciBnZXRDdXJyZW50TG9jYXRpb24gPSBQcm90b2NvbC5nZXRDdXJyZW50TG9jYXRpb247XG4gIHZhciBwdXNoTG9jYXRpb24gPSBQcm90b2NvbC5wdXNoTG9jYXRpb247XG4gIHZhciByZXBsYWNlTG9jYXRpb24gPSBQcm90b2NvbC5yZXBsYWNlTG9jYXRpb247XG4gIHZhciBnbyA9IFByb3RvY29sLmdvO1xuXG5cbiAgdmFyIGhpc3RvcnkgPSAoMCwgX2NyZWF0ZUhpc3RvcnkyLmRlZmF1bHQpKF9leHRlbmRzKHtcbiAgICBnZXRVc2VyQ29uZmlybWF0aW9uOiBnZXRVc2VyQ29uZmlybWF0aW9uIH0sIG9wdGlvbnMsIHtcbiAgICBnZXRDdXJyZW50TG9jYXRpb246IGdldEN1cnJlbnRMb2NhdGlvbixcbiAgICBwdXNoTG9jYXRpb246IHB1c2hMb2NhdGlvbixcbiAgICByZXBsYWNlTG9jYXRpb246IHJlcGxhY2VMb2NhdGlvbixcbiAgICBnbzogZ29cbiAgfSkpO1xuXG4gIHZhciBsaXN0ZW5lckNvdW50ID0gMCxcbiAgICAgIHN0b3BMaXN0ZW5lciA9IHZvaWQgMDtcblxuICB2YXIgc3RhcnRMaXN0ZW5lciA9IGZ1bmN0aW9uIHN0YXJ0TGlzdGVuZXIobGlzdGVuZXIsIGJlZm9yZSkge1xuICAgIGlmICgrK2xpc3RlbmVyQ291bnQgPT09IDEpIHN0b3BMaXN0ZW5lciA9IEJyb3dzZXJQcm90b2NvbC5zdGFydExpc3RlbmVyKGhpc3RvcnkudHJhbnNpdGlvblRvKTtcblxuICAgIHZhciB1bmxpc3RlbiA9IGJlZm9yZSA/IGhpc3RvcnkubGlzdGVuQmVmb3JlKGxpc3RlbmVyKSA6IGhpc3RvcnkubGlzdGVuKGxpc3RlbmVyKTtcblxuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICB1bmxpc3RlbigpO1xuXG4gICAgICBpZiAoLS1saXN0ZW5lckNvdW50ID09PSAwKSBzdG9wTGlzdGVuZXIoKTtcbiAgICB9O1xuICB9O1xuXG4gIHZhciBsaXN0ZW5CZWZvcmUgPSBmdW5jdGlvbiBsaXN0ZW5CZWZvcmUobGlzdGVuZXIpIHtcbiAgICByZXR1cm4gc3RhcnRMaXN0ZW5lcihsaXN0ZW5lciwgdHJ1ZSk7XG4gIH07XG5cbiAgdmFyIGxpc3RlbiA9IGZ1bmN0aW9uIGxpc3RlbihsaXN0ZW5lcikge1xuICAgIHJldHVybiBzdGFydExpc3RlbmVyKGxpc3RlbmVyLCBmYWxzZSk7XG4gIH07XG5cbiAgcmV0dXJuIF9leHRlbmRzKHt9LCBoaXN0b3J5LCB7XG4gICAgbGlzdGVuQmVmb3JlOiBsaXN0ZW5CZWZvcmUsXG4gICAgbGlzdGVuOiBsaXN0ZW5cbiAgfSk7XG59O1xuXG5leHBvcnRzLmRlZmF1bHQgPSBjcmVhdGVCcm93c2VySGlzdG9yeTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbnZhciBfd2FybmluZyA9IHJlcXVpcmUoJ3dhcm5pbmcnKTtcblxudmFyIF93YXJuaW5nMiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX3dhcm5pbmcpO1xuXG52YXIgX2ludmFyaWFudCA9IHJlcXVpcmUoJ2ludmFyaWFudCcpO1xuXG52YXIgX2ludmFyaWFudDIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9pbnZhcmlhbnQpO1xuXG52YXIgX0V4ZWN1dGlvbkVudmlyb25tZW50ID0gcmVxdWlyZSgnLi9FeGVjdXRpb25FbnZpcm9ubWVudCcpO1xuXG52YXIgX0RPTVV0aWxzID0gcmVxdWlyZSgnLi9ET01VdGlscycpO1xuXG52YXIgX0hhc2hQcm90b2NvbCA9IHJlcXVpcmUoJy4vSGFzaFByb3RvY29sJyk7XG5cbnZhciBIYXNoUHJvdG9jb2wgPSBfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZChfSGFzaFByb3RvY29sKTtcblxudmFyIF9jcmVhdGVIaXN0b3J5ID0gcmVxdWlyZSgnLi9jcmVhdGVIaXN0b3J5Jyk7XG5cbnZhciBfY3JlYXRlSGlzdG9yeTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9jcmVhdGVIaXN0b3J5KTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQob2JqKSB7IGlmIChvYmogJiYgb2JqLl9fZXNNb2R1bGUpIHsgcmV0dXJuIG9iajsgfSBlbHNlIHsgdmFyIG5ld09iaiA9IHt9OyBpZiAob2JqICE9IG51bGwpIHsgZm9yICh2YXIga2V5IGluIG9iaikgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwga2V5KSkgbmV3T2JqW2tleV0gPSBvYmpba2V5XTsgfSB9IG5ld09iai5kZWZhdWx0ID0gb2JqOyByZXR1cm4gbmV3T2JqOyB9IH1cblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxudmFyIERlZmF1bHRRdWVyeUtleSA9ICdfayc7XG5cbnZhciBjcmVhdGVIYXNoSGlzdG9yeSA9IGZ1bmN0aW9uIGNyZWF0ZUhhc2hIaXN0b3J5KCkge1xuICB2YXIgb3B0aW9ucyA9IGFyZ3VtZW50cy5sZW5ndGggPD0gMCB8fCBhcmd1bWVudHNbMF0gPT09IHVuZGVmaW5lZCA/IHt9IDogYXJndW1lbnRzWzBdO1xuXG4gICFfRXhlY3V0aW9uRW52aXJvbm1lbnQuY2FuVXNlRE9NID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/ICgwLCBfaW52YXJpYW50Mi5kZWZhdWx0KShmYWxzZSwgJ0hhc2ggaGlzdG9yeSBuZWVkcyBhIERPTScpIDogKDAsIF9pbnZhcmlhbnQyLmRlZmF1bHQpKGZhbHNlKSA6IHZvaWQgMDtcblxuICB2YXIgcXVlcnlLZXkgPSBvcHRpb25zLnF1ZXJ5S2V5O1xuXG5cbiAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/ICgwLCBfd2FybmluZzIuZGVmYXVsdCkocXVlcnlLZXkgIT09IGZhbHNlLCAnVXNpbmcgeyBxdWVyeUtleTogZmFsc2UgfSBubyBsb25nZXIgd29ya3MuIEluc3RlYWQsIGp1c3QgZG9uXFwndCAnICsgJ3VzZSBsb2NhdGlvbiBzdGF0ZSBpZiB5b3UgZG9uXFwndCB3YW50IGEga2V5IGluIHlvdXIgVVJMIHF1ZXJ5IHN0cmluZycpIDogdm9pZCAwO1xuXG4gIGlmICh0eXBlb2YgcXVlcnlLZXkgIT09ICdzdHJpbmcnKSBxdWVyeUtleSA9IERlZmF1bHRRdWVyeUtleTtcblxuICB2YXIgZ2V0VXNlckNvbmZpcm1hdGlvbiA9IEhhc2hQcm90b2NvbC5nZXRVc2VyQ29uZmlybWF0aW9uO1xuXG5cbiAgdmFyIGdldEN1cnJlbnRMb2NhdGlvbiA9IGZ1bmN0aW9uIGdldEN1cnJlbnRMb2NhdGlvbigpIHtcbiAgICByZXR1cm4gSGFzaFByb3RvY29sLmdldEN1cnJlbnRMb2NhdGlvbihxdWVyeUtleSk7XG4gIH07XG5cbiAgdmFyIHB1c2hMb2NhdGlvbiA9IGZ1bmN0aW9uIHB1c2hMb2NhdGlvbihsb2NhdGlvbikge1xuICAgIHJldHVybiBIYXNoUHJvdG9jb2wucHVzaExvY2F0aW9uKGxvY2F0aW9uLCBxdWVyeUtleSk7XG4gIH07XG5cbiAgdmFyIHJlcGxhY2VMb2NhdGlvbiA9IGZ1bmN0aW9uIHJlcGxhY2VMb2NhdGlvbihsb2NhdGlvbikge1xuICAgIHJldHVybiBIYXNoUHJvdG9jb2wucmVwbGFjZUxvY2F0aW9uKGxvY2F0aW9uLCBxdWVyeUtleSk7XG4gIH07XG5cbiAgdmFyIGhpc3RvcnkgPSAoMCwgX2NyZWF0ZUhpc3RvcnkyLmRlZmF1bHQpKF9leHRlbmRzKHtcbiAgICBnZXRVc2VyQ29uZmlybWF0aW9uOiBnZXRVc2VyQ29uZmlybWF0aW9uIH0sIG9wdGlvbnMsIHtcbiAgICBnZXRDdXJyZW50TG9jYXRpb246IGdldEN1cnJlbnRMb2NhdGlvbixcbiAgICBwdXNoTG9jYXRpb246IHB1c2hMb2NhdGlvbixcbiAgICByZXBsYWNlTG9jYXRpb246IHJlcGxhY2VMb2NhdGlvbixcbiAgICBnbzogSGFzaFByb3RvY29sLmdvXG4gIH0pKTtcblxuICB2YXIgbGlzdGVuZXJDb3VudCA9IDAsXG4gICAgICBzdG9wTGlzdGVuZXIgPSB2b2lkIDA7XG5cbiAgdmFyIHN0YXJ0TGlzdGVuZXIgPSBmdW5jdGlvbiBzdGFydExpc3RlbmVyKGxpc3RlbmVyLCBiZWZvcmUpIHtcbiAgICBpZiAoKytsaXN0ZW5lckNvdW50ID09PSAxKSBzdG9wTGlzdGVuZXIgPSBIYXNoUHJvdG9jb2wuc3RhcnRMaXN0ZW5lcihoaXN0b3J5LnRyYW5zaXRpb25UbywgcXVlcnlLZXkpO1xuXG4gICAgdmFyIHVubGlzdGVuID0gYmVmb3JlID8gaGlzdG9yeS5saXN0ZW5CZWZvcmUobGlzdGVuZXIpIDogaGlzdG9yeS5saXN0ZW4obGlzdGVuZXIpO1xuXG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcbiAgICAgIHVubGlzdGVuKCk7XG5cbiAgICAgIGlmICgtLWxpc3RlbmVyQ291bnQgPT09IDApIHN0b3BMaXN0ZW5lcigpO1xuICAgIH07XG4gIH07XG5cbiAgdmFyIGxpc3RlbkJlZm9yZSA9IGZ1bmN0aW9uIGxpc3RlbkJlZm9yZShsaXN0ZW5lcikge1xuICAgIHJldHVybiBzdGFydExpc3RlbmVyKGxpc3RlbmVyLCB0cnVlKTtcbiAgfTtcblxuICB2YXIgbGlzdGVuID0gZnVuY3Rpb24gbGlzdGVuKGxpc3RlbmVyKSB7XG4gICAgcmV0dXJuIHN0YXJ0TGlzdGVuZXIobGlzdGVuZXIsIGZhbHNlKTtcbiAgfTtcblxuICB2YXIgZ29Jc1N1cHBvcnRlZFdpdGhvdXRSZWxvYWQgPSAoMCwgX0RPTVV0aWxzLnN1cHBvcnRzR29XaXRob3V0UmVsb2FkVXNpbmdIYXNoKSgpO1xuXG4gIHZhciBnbyA9IGZ1bmN0aW9uIGdvKG4pIHtcbiAgICBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gKDAsIF93YXJuaW5nMi5kZWZhdWx0KShnb0lzU3VwcG9ydGVkV2l0aG91dFJlbG9hZCwgJ0hhc2ggaGlzdG9yeSBnbyhuKSBjYXVzZXMgYSBmdWxsIHBhZ2UgcmVsb2FkIGluIHRoaXMgYnJvd3NlcicpIDogdm9pZCAwO1xuXG4gICAgaGlzdG9yeS5nbyhuKTtcbiAgfTtcblxuICB2YXIgY3JlYXRlSHJlZiA9IGZ1bmN0aW9uIGNyZWF0ZUhyZWYocGF0aCkge1xuICAgIHJldHVybiAnIycgKyBoaXN0b3J5LmNyZWF0ZUhyZWYocGF0aCk7XG4gIH07XG5cbiAgcmV0dXJuIF9leHRlbmRzKHt9LCBoaXN0b3J5LCB7XG4gICAgbGlzdGVuQmVmb3JlOiBsaXN0ZW5CZWZvcmUsXG4gICAgbGlzdGVuOiBsaXN0ZW4sXG4gICAgZ286IGdvLFxuICAgIGNyZWF0ZUhyZWY6IGNyZWF0ZUhyZWZcbiAgfSk7XG59O1xuXG5leHBvcnRzLmRlZmF1bHQgPSBjcmVhdGVIYXNoSGlzdG9yeTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5cbnZhciBfQXN5bmNVdGlscyA9IHJlcXVpcmUoJy4vQXN5bmNVdGlscycpO1xuXG52YXIgX1BhdGhVdGlscyA9IHJlcXVpcmUoJy4vUGF0aFV0aWxzJyk7XG5cbnZhciBfcnVuVHJhbnNpdGlvbkhvb2sgPSByZXF1aXJlKCcuL3J1blRyYW5zaXRpb25Ib29rJyk7XG5cbnZhciBfcnVuVHJhbnNpdGlvbkhvb2syID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfcnVuVHJhbnNpdGlvbkhvb2spO1xuXG52YXIgX0FjdGlvbnMgPSByZXF1aXJlKCcuL0FjdGlvbnMnKTtcblxudmFyIF9Mb2NhdGlvblV0aWxzID0gcmVxdWlyZSgnLi9Mb2NhdGlvblV0aWxzJyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmZ1bmN0aW9uIF90b0NvbnN1bWFibGVBcnJheShhcnIpIHsgaWYgKEFycmF5LmlzQXJyYXkoYXJyKSkgeyBmb3IgKHZhciBpID0gMCwgYXJyMiA9IEFycmF5KGFyci5sZW5ndGgpOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7IGFycjJbaV0gPSBhcnJbaV07IH0gcmV0dXJuIGFycjI7IH0gZWxzZSB7IHJldHVybiBBcnJheS5mcm9tKGFycik7IH0gfVxuXG52YXIgY3JlYXRlSGlzdG9yeSA9IGZ1bmN0aW9uIGNyZWF0ZUhpc3RvcnkoKSB7XG4gIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA8PSAwIHx8IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8ge30gOiBhcmd1bWVudHNbMF07XG4gIHZhciBnZXRDdXJyZW50TG9jYXRpb24gPSBvcHRpb25zLmdldEN1cnJlbnRMb2NhdGlvbjtcbiAgdmFyIGdldFVzZXJDb25maXJtYXRpb24gPSBvcHRpb25zLmdldFVzZXJDb25maXJtYXRpb247XG4gIHZhciBwdXNoTG9jYXRpb24gPSBvcHRpb25zLnB1c2hMb2NhdGlvbjtcbiAgdmFyIHJlcGxhY2VMb2NhdGlvbiA9IG9wdGlvbnMucmVwbGFjZUxvY2F0aW9uO1xuICB2YXIgZ28gPSBvcHRpb25zLmdvO1xuICB2YXIga2V5TGVuZ3RoID0gb3B0aW9ucy5rZXlMZW5ndGg7XG5cblxuICB2YXIgY3VycmVudExvY2F0aW9uID0gdm9pZCAwO1xuICB2YXIgcGVuZGluZ0xvY2F0aW9uID0gdm9pZCAwO1xuICB2YXIgYmVmb3JlTGlzdGVuZXJzID0gW107XG4gIHZhciBsaXN0ZW5lcnMgPSBbXTtcbiAgdmFyIGFsbEtleXMgPSBbXTtcblxuICB2YXIgZ2V0Q3VycmVudEluZGV4ID0gZnVuY3Rpb24gZ2V0Q3VycmVudEluZGV4KCkge1xuICAgIGlmIChwZW5kaW5nTG9jYXRpb24gJiYgcGVuZGluZ0xvY2F0aW9uLmFjdGlvbiA9PT0gX0FjdGlvbnMuUE9QKSByZXR1cm4gYWxsS2V5cy5pbmRleE9mKHBlbmRpbmdMb2NhdGlvbi5rZXkpO1xuXG4gICAgaWYgKGN1cnJlbnRMb2NhdGlvbikgcmV0dXJuIGFsbEtleXMuaW5kZXhPZihjdXJyZW50TG9jYXRpb24ua2V5KTtcblxuICAgIHJldHVybiAtMTtcbiAgfTtcblxuICB2YXIgdXBkYXRlTG9jYXRpb24gPSBmdW5jdGlvbiB1cGRhdGVMb2NhdGlvbihuZXh0TG9jYXRpb24pIHtcbiAgICBjdXJyZW50TG9jYXRpb24gPSBuZXh0TG9jYXRpb247XG5cbiAgICB2YXIgY3VycmVudEluZGV4ID0gZ2V0Q3VycmVudEluZGV4KCk7XG5cbiAgICBpZiAoY3VycmVudExvY2F0aW9uLmFjdGlvbiA9PT0gX0FjdGlvbnMuUFVTSCkge1xuICAgICAgYWxsS2V5cyA9IFtdLmNvbmNhdChfdG9Db25zdW1hYmxlQXJyYXkoYWxsS2V5cy5zbGljZSgwLCBjdXJyZW50SW5kZXggKyAxKSksIFtjdXJyZW50TG9jYXRpb24ua2V5XSk7XG4gICAgfSBlbHNlIGlmIChjdXJyZW50TG9jYXRpb24uYWN0aW9uID09PSBfQWN0aW9ucy5SRVBMQUNFKSB7XG4gICAgICBhbGxLZXlzW2N1cnJlbnRJbmRleF0gPSBjdXJyZW50TG9jYXRpb24ua2V5O1xuICAgIH1cblxuICAgIGxpc3RlbmVycy5mb3JFYWNoKGZ1bmN0aW9uIChsaXN0ZW5lcikge1xuICAgICAgcmV0dXJuIGxpc3RlbmVyKGN1cnJlbnRMb2NhdGlvbik7XG4gICAgfSk7XG4gIH07XG5cbiAgdmFyIGxpc3RlbkJlZm9yZSA9IGZ1bmN0aW9uIGxpc3RlbkJlZm9yZShsaXN0ZW5lcikge1xuICAgIGJlZm9yZUxpc3RlbmVycy5wdXNoKGxpc3RlbmVyKTtcblxuICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICByZXR1cm4gYmVmb3JlTGlzdGVuZXJzID0gYmVmb3JlTGlzdGVuZXJzLmZpbHRlcihmdW5jdGlvbiAoaXRlbSkge1xuICAgICAgICByZXR1cm4gaXRlbSAhPT0gbGlzdGVuZXI7XG4gICAgICB9KTtcbiAgICB9O1xuICB9O1xuXG4gIHZhciBsaXN0ZW4gPSBmdW5jdGlvbiBsaXN0ZW4obGlzdGVuZXIpIHtcbiAgICBsaXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgcmV0dXJuIGxpc3RlbmVycyA9IGxpc3RlbmVycy5maWx0ZXIoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgcmV0dXJuIGl0ZW0gIT09IGxpc3RlbmVyO1xuICAgICAgfSk7XG4gICAgfTtcbiAgfTtcblxuICB2YXIgY29uZmlybVRyYW5zaXRpb25UbyA9IGZ1bmN0aW9uIGNvbmZpcm1UcmFuc2l0aW9uVG8obG9jYXRpb24sIGNhbGxiYWNrKSB7XG4gICAgKDAsIF9Bc3luY1V0aWxzLmxvb3BBc3luYykoYmVmb3JlTGlzdGVuZXJzLmxlbmd0aCwgZnVuY3Rpb24gKGluZGV4LCBuZXh0LCBkb25lKSB7XG4gICAgICAoMCwgX3J1blRyYW5zaXRpb25Ib29rMi5kZWZhdWx0KShiZWZvcmVMaXN0ZW5lcnNbaW5kZXhdLCBsb2NhdGlvbiwgZnVuY3Rpb24gKHJlc3VsdCkge1xuICAgICAgICByZXR1cm4gcmVzdWx0ICE9IG51bGwgPyBkb25lKHJlc3VsdCkgOiBuZXh0KCk7XG4gICAgICB9KTtcbiAgICB9LCBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgaWYgKGdldFVzZXJDb25maXJtYXRpb24gJiYgdHlwZW9mIG1lc3NhZ2UgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGdldFVzZXJDb25maXJtYXRpb24obWVzc2FnZSwgZnVuY3Rpb24gKG9rKSB7XG4gICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG9rICE9PSBmYWxzZSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2FsbGJhY2sobWVzc2FnZSAhPT0gZmFsc2UpO1xuICAgICAgfVxuICAgIH0pO1xuICB9O1xuXG4gIHZhciB0cmFuc2l0aW9uVG8gPSBmdW5jdGlvbiB0cmFuc2l0aW9uVG8obmV4dExvY2F0aW9uKSB7XG4gICAgaWYgKGN1cnJlbnRMb2NhdGlvbiAmJiAoMCwgX0xvY2F0aW9uVXRpbHMubG9jYXRpb25zQXJlRXF1YWwpKGN1cnJlbnRMb2NhdGlvbiwgbmV4dExvY2F0aW9uKSB8fCBwZW5kaW5nTG9jYXRpb24gJiYgKDAsIF9Mb2NhdGlvblV0aWxzLmxvY2F0aW9uc0FyZUVxdWFsKShwZW5kaW5nTG9jYXRpb24sIG5leHRMb2NhdGlvbikpIHJldHVybjsgLy8gTm90aGluZyB0byBkb1xuXG4gICAgcGVuZGluZ0xvY2F0aW9uID0gbmV4dExvY2F0aW9uO1xuXG4gICAgY29uZmlybVRyYW5zaXRpb25UbyhuZXh0TG9jYXRpb24sIGZ1bmN0aW9uIChvaykge1xuICAgICAgaWYgKHBlbmRpbmdMb2NhdGlvbiAhPT0gbmV4dExvY2F0aW9uKSByZXR1cm47IC8vIFRyYW5zaXRpb24gd2FzIGludGVycnVwdGVkIGR1cmluZyBjb25maXJtYXRpb25cblxuICAgICAgcGVuZGluZ0xvY2F0aW9uID0gbnVsbDtcblxuICAgICAgaWYgKG9rKSB7XG4gICAgICAgIC8vIFRyZWF0IFBVU0ggdG8gc2FtZSBwYXRoIGxpa2UgUkVQTEFDRSB0byBiZSBjb25zaXN0ZW50IHdpdGggYnJvd3NlcnNcbiAgICAgICAgaWYgKG5leHRMb2NhdGlvbi5hY3Rpb24gPT09IF9BY3Rpb25zLlBVU0gpIHtcbiAgICAgICAgICB2YXIgcHJldlBhdGggPSAoMCwgX1BhdGhVdGlscy5jcmVhdGVQYXRoKShjdXJyZW50TG9jYXRpb24pO1xuICAgICAgICAgIHZhciBuZXh0UGF0aCA9ICgwLCBfUGF0aFV0aWxzLmNyZWF0ZVBhdGgpKG5leHRMb2NhdGlvbik7XG5cbiAgICAgICAgICBpZiAobmV4dFBhdGggPT09IHByZXZQYXRoICYmICgwLCBfTG9jYXRpb25VdGlscy5zdGF0ZXNBcmVFcXVhbCkoY3VycmVudExvY2F0aW9uLnN0YXRlLCBuZXh0TG9jYXRpb24uc3RhdGUpKSBuZXh0TG9jYXRpb24uYWN0aW9uID0gX0FjdGlvbnMuUkVQTEFDRTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChuZXh0TG9jYXRpb24uYWN0aW9uID09PSBfQWN0aW9ucy5QT1ApIHtcbiAgICAgICAgICB1cGRhdGVMb2NhdGlvbihuZXh0TG9jYXRpb24pO1xuICAgICAgICB9IGVsc2UgaWYgKG5leHRMb2NhdGlvbi5hY3Rpb24gPT09IF9BY3Rpb25zLlBVU0gpIHtcbiAgICAgICAgICBpZiAocHVzaExvY2F0aW9uKG5leHRMb2NhdGlvbikgIT09IGZhbHNlKSB1cGRhdGVMb2NhdGlvbihuZXh0TG9jYXRpb24pO1xuICAgICAgICB9IGVsc2UgaWYgKG5leHRMb2NhdGlvbi5hY3Rpb24gPT09IF9BY3Rpb25zLlJFUExBQ0UpIHtcbiAgICAgICAgICBpZiAocmVwbGFjZUxvY2F0aW9uKG5leHRMb2NhdGlvbikgIT09IGZhbHNlKSB1cGRhdGVMb2NhdGlvbihuZXh0TG9jYXRpb24pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRMb2NhdGlvbiAmJiBuZXh0TG9jYXRpb24uYWN0aW9uID09PSBfQWN0aW9ucy5QT1ApIHtcbiAgICAgICAgdmFyIHByZXZJbmRleCA9IGFsbEtleXMuaW5kZXhPZihjdXJyZW50TG9jYXRpb24ua2V5KTtcbiAgICAgICAgdmFyIG5leHRJbmRleCA9IGFsbEtleXMuaW5kZXhPZihuZXh0TG9jYXRpb24ua2V5KTtcblxuICAgICAgICBpZiAocHJldkluZGV4ICE9PSAtMSAmJiBuZXh0SW5kZXggIT09IC0xKSBnbyhwcmV2SW5kZXggLSBuZXh0SW5kZXgpOyAvLyBSZXN0b3JlIHRoZSBVUkxcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcblxuICB2YXIgcHVzaCA9IGZ1bmN0aW9uIHB1c2goaW5wdXQpIHtcbiAgICByZXR1cm4gdHJhbnNpdGlvblRvKGNyZWF0ZUxvY2F0aW9uKGlucHV0LCBfQWN0aW9ucy5QVVNIKSk7XG4gIH07XG5cbiAgdmFyIHJlcGxhY2UgPSBmdW5jdGlvbiByZXBsYWNlKGlucHV0KSB7XG4gICAgcmV0dXJuIHRyYW5zaXRpb25UbyhjcmVhdGVMb2NhdGlvbihpbnB1dCwgX0FjdGlvbnMuUkVQTEFDRSkpO1xuICB9O1xuXG4gIHZhciBnb0JhY2sgPSBmdW5jdGlvbiBnb0JhY2soKSB7XG4gICAgcmV0dXJuIGdvKC0xKTtcbiAgfTtcblxuICB2YXIgZ29Gb3J3YXJkID0gZnVuY3Rpb24gZ29Gb3J3YXJkKCkge1xuICAgIHJldHVybiBnbygxKTtcbiAgfTtcblxuICB2YXIgY3JlYXRlS2V5ID0gZnVuY3Rpb24gY3JlYXRlS2V5KCkge1xuICAgIHJldHVybiBNYXRoLnJhbmRvbSgpLnRvU3RyaW5nKDM2KS5zdWJzdHIoMiwga2V5TGVuZ3RoIHx8IDYpO1xuICB9O1xuXG4gIHZhciBjcmVhdGVIcmVmID0gZnVuY3Rpb24gY3JlYXRlSHJlZihsb2NhdGlvbikge1xuICAgIHJldHVybiAoMCwgX1BhdGhVdGlscy5jcmVhdGVQYXRoKShsb2NhdGlvbik7XG4gIH07XG5cbiAgdmFyIGNyZWF0ZUxvY2F0aW9uID0gZnVuY3Rpb24gY3JlYXRlTG9jYXRpb24obG9jYXRpb24sIGFjdGlvbikge1xuICAgIHZhciBrZXkgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDIgfHwgYXJndW1lbnRzWzJdID09PSB1bmRlZmluZWQgPyBjcmVhdGVLZXkoKSA6IGFyZ3VtZW50c1syXTtcbiAgICByZXR1cm4gKDAsIF9Mb2NhdGlvblV0aWxzLmNyZWF0ZUxvY2F0aW9uKShsb2NhdGlvbiwgYWN0aW9uLCBrZXkpO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgZ2V0Q3VycmVudExvY2F0aW9uOiBnZXRDdXJyZW50TG9jYXRpb24sXG4gICAgbGlzdGVuQmVmb3JlOiBsaXN0ZW5CZWZvcmUsXG4gICAgbGlzdGVuOiBsaXN0ZW4sXG4gICAgdHJhbnNpdGlvblRvOiB0cmFuc2l0aW9uVG8sXG4gICAgcHVzaDogcHVzaCxcbiAgICByZXBsYWNlOiByZXBsYWNlLFxuICAgIGdvOiBnbyxcbiAgICBnb0JhY2s6IGdvQmFjayxcbiAgICBnb0ZvcndhcmQ6IGdvRm9yd2FyZCxcbiAgICBjcmVhdGVLZXk6IGNyZWF0ZUtleSxcbiAgICBjcmVhdGVQYXRoOiBfUGF0aFV0aWxzLmNyZWF0ZVBhdGgsXG4gICAgY3JlYXRlSHJlZjogY3JlYXRlSHJlZixcbiAgICBjcmVhdGVMb2NhdGlvbjogY3JlYXRlTG9jYXRpb25cbiAgfTtcbn07XG5cbmV4cG9ydHMuZGVmYXVsdCA9IGNyZWF0ZUhpc3Rvcnk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuXG52YXIgX2V4dGVuZHMgPSBPYmplY3QuYXNzaWduIHx8IGZ1bmN0aW9uICh0YXJnZXQpIHsgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHsgdmFyIHNvdXJjZSA9IGFyZ3VtZW50c1tpXTsgZm9yICh2YXIga2V5IGluIHNvdXJjZSkgeyBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkgeyB0YXJnZXRba2V5XSA9IHNvdXJjZVtrZXldOyB9IH0gfSByZXR1cm4gdGFyZ2V0OyB9O1xuXG52YXIgX3dhcm5pbmcgPSByZXF1aXJlKCd3YXJuaW5nJyk7XG5cbnZhciBfd2FybmluZzIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF93YXJuaW5nKTtcblxudmFyIF9pbnZhcmlhbnQgPSByZXF1aXJlKCdpbnZhcmlhbnQnKTtcblxudmFyIF9pbnZhcmlhbnQyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfaW52YXJpYW50KTtcblxudmFyIF9Mb2NhdGlvblV0aWxzID0gcmVxdWlyZSgnLi9Mb2NhdGlvblV0aWxzJyk7XG5cbnZhciBfUGF0aFV0aWxzID0gcmVxdWlyZSgnLi9QYXRoVXRpbHMnKTtcblxudmFyIF9jcmVhdGVIaXN0b3J5ID0gcmVxdWlyZSgnLi9jcmVhdGVIaXN0b3J5Jyk7XG5cbnZhciBfY3JlYXRlSGlzdG9yeTIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9jcmVhdGVIaXN0b3J5KTtcblxudmFyIF9BY3Rpb25zID0gcmVxdWlyZSgnLi9BY3Rpb25zJyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciBjcmVhdGVTdGF0ZVN0b3JhZ2UgPSBmdW5jdGlvbiBjcmVhdGVTdGF0ZVN0b3JhZ2UoZW50cmllcykge1xuICByZXR1cm4gZW50cmllcy5maWx0ZXIoZnVuY3Rpb24gKGVudHJ5KSB7XG4gICAgcmV0dXJuIGVudHJ5LnN0YXRlO1xuICB9KS5yZWR1Y2UoZnVuY3Rpb24gKG1lbW8sIGVudHJ5KSB7XG4gICAgbWVtb1tlbnRyeS5rZXldID0gZW50cnkuc3RhdGU7XG4gICAgcmV0dXJuIG1lbW87XG4gIH0sIHt9KTtcbn07XG5cbnZhciBjcmVhdGVNZW1vcnlIaXN0b3J5ID0gZnVuY3Rpb24gY3JlYXRlTWVtb3J5SGlzdG9yeSgpIHtcbiAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDAgfHwgYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQgPyB7fSA6IGFyZ3VtZW50c1swXTtcblxuICBpZiAoQXJyYXkuaXNBcnJheShvcHRpb25zKSkge1xuICAgIG9wdGlvbnMgPSB7IGVudHJpZXM6IG9wdGlvbnMgfTtcbiAgfSBlbHNlIGlmICh0eXBlb2Ygb3B0aW9ucyA9PT0gJ3N0cmluZycpIHtcbiAgICBvcHRpb25zID0geyBlbnRyaWVzOiBbb3B0aW9uc10gfTtcbiAgfVxuXG4gIHZhciBnZXRDdXJyZW50TG9jYXRpb24gPSBmdW5jdGlvbiBnZXRDdXJyZW50TG9jYXRpb24oKSB7XG4gICAgdmFyIGVudHJ5ID0gZW50cmllc1tjdXJyZW50XTtcbiAgICB2YXIgcGF0aCA9ICgwLCBfUGF0aFV0aWxzLmNyZWF0ZVBhdGgpKGVudHJ5KTtcblxuICAgIHZhciBrZXkgPSB2b2lkIDAsXG4gICAgICAgIHN0YXRlID0gdm9pZCAwO1xuICAgIGlmIChlbnRyeS5rZXkpIHtcbiAgICAgIGtleSA9IGVudHJ5LmtleTtcbiAgICAgIHN0YXRlID0gcmVhZFN0YXRlKGtleSk7XG4gICAgfVxuXG4gICAgdmFyIGluaXQgPSAoMCwgX1BhdGhVdGlscy5wYXJzZVBhdGgpKHBhdGgpO1xuXG4gICAgcmV0dXJuICgwLCBfTG9jYXRpb25VdGlscy5jcmVhdGVMb2NhdGlvbikoX2V4dGVuZHMoe30sIGluaXQsIHsgc3RhdGU6IHN0YXRlIH0pLCB1bmRlZmluZWQsIGtleSk7XG4gIH07XG5cbiAgdmFyIGNhbkdvID0gZnVuY3Rpb24gY2FuR28obikge1xuICAgIHZhciBpbmRleCA9IGN1cnJlbnQgKyBuO1xuICAgIHJldHVybiBpbmRleCA+PSAwICYmIGluZGV4IDwgZW50cmllcy5sZW5ndGg7XG4gIH07XG5cbiAgdmFyIGdvID0gZnVuY3Rpb24gZ28obikge1xuICAgIGlmICghbikgcmV0dXJuO1xuXG4gICAgaWYgKCFjYW5HbyhuKSkge1xuICAgICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/ICgwLCBfd2FybmluZzIuZGVmYXVsdCkoZmFsc2UsICdDYW5ub3QgZ28oJXMpIHRoZXJlIGlzIG5vdCBlbm91Z2ggaGlzdG9yeScsIG4pIDogdm9pZCAwO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY3VycmVudCArPSBuO1xuICAgIHZhciBjdXJyZW50TG9jYXRpb24gPSBnZXRDdXJyZW50TG9jYXRpb24oKTtcblxuICAgIC8vIENoYW5nZSBhY3Rpb24gdG8gUE9QXG4gICAgaGlzdG9yeS50cmFuc2l0aW9uVG8oX2V4dGVuZHMoe30sIGN1cnJlbnRMb2NhdGlvbiwgeyBhY3Rpb246IF9BY3Rpb25zLlBPUCB9KSk7XG4gIH07XG5cbiAgdmFyIHB1c2hMb2NhdGlvbiA9IGZ1bmN0aW9uIHB1c2hMb2NhdGlvbihsb2NhdGlvbikge1xuICAgIGN1cnJlbnQgKz0gMTtcblxuICAgIGlmIChjdXJyZW50IDwgZW50cmllcy5sZW5ndGgpIGVudHJpZXMuc3BsaWNlKGN1cnJlbnQpO1xuXG4gICAgZW50cmllcy5wdXNoKGxvY2F0aW9uKTtcblxuICAgIHNhdmVTdGF0ZShsb2NhdGlvbi5rZXksIGxvY2F0aW9uLnN0YXRlKTtcbiAgfTtcblxuICB2YXIgcmVwbGFjZUxvY2F0aW9uID0gZnVuY3Rpb24gcmVwbGFjZUxvY2F0aW9uKGxvY2F0aW9uKSB7XG4gICAgZW50cmllc1tjdXJyZW50XSA9IGxvY2F0aW9uO1xuICAgIHNhdmVTdGF0ZShsb2NhdGlvbi5rZXksIGxvY2F0aW9uLnN0YXRlKTtcbiAgfTtcblxuICB2YXIgaGlzdG9yeSA9ICgwLCBfY3JlYXRlSGlzdG9yeTIuZGVmYXVsdCkoX2V4dGVuZHMoe30sIG9wdGlvbnMsIHtcbiAgICBnZXRDdXJyZW50TG9jYXRpb246IGdldEN1cnJlbnRMb2NhdGlvbixcbiAgICBwdXNoTG9jYXRpb246IHB1c2hMb2NhdGlvbixcbiAgICByZXBsYWNlTG9jYXRpb246IHJlcGxhY2VMb2NhdGlvbixcbiAgICBnbzogZ29cbiAgfSkpO1xuXG4gIHZhciBfb3B0aW9ucyA9IG9wdGlvbnM7XG4gIHZhciBlbnRyaWVzID0gX29wdGlvbnMuZW50cmllcztcbiAgdmFyIGN1cnJlbnQgPSBfb3B0aW9ucy5jdXJyZW50O1xuXG5cbiAgaWYgKHR5cGVvZiBlbnRyaWVzID09PSAnc3RyaW5nJykge1xuICAgIGVudHJpZXMgPSBbZW50cmllc107XG4gIH0gZWxzZSBpZiAoIUFycmF5LmlzQXJyYXkoZW50cmllcykpIHtcbiAgICBlbnRyaWVzID0gWycvJ107XG4gIH1cblxuICBlbnRyaWVzID0gZW50cmllcy5tYXAoZnVuY3Rpb24gKGVudHJ5KSB7XG4gICAgcmV0dXJuICgwLCBfTG9jYXRpb25VdGlscy5jcmVhdGVMb2NhdGlvbikoZW50cnkpO1xuICB9KTtcblxuICBpZiAoY3VycmVudCA9PSBudWxsKSB7XG4gICAgY3VycmVudCA9IGVudHJpZXMubGVuZ3RoIC0gMTtcbiAgfSBlbHNlIHtcbiAgICAhKGN1cnJlbnQgPj0gMCAmJiBjdXJyZW50IDwgZW50cmllcy5sZW5ndGgpID8gcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/ICgwLCBfaW52YXJpYW50Mi5kZWZhdWx0KShmYWxzZSwgJ0N1cnJlbnQgaW5kZXggbXVzdCBiZSA+PSAwIGFuZCA8ICVzLCB3YXMgJXMnLCBlbnRyaWVzLmxlbmd0aCwgY3VycmVudCkgOiAoMCwgX2ludmFyaWFudDIuZGVmYXVsdCkoZmFsc2UpIDogdm9pZCAwO1xuICB9XG5cbiAgdmFyIHN0b3JhZ2UgPSBjcmVhdGVTdGF0ZVN0b3JhZ2UoZW50cmllcyk7XG5cbiAgdmFyIHNhdmVTdGF0ZSA9IGZ1bmN0aW9uIHNhdmVTdGF0ZShrZXksIHN0YXRlKSB7XG4gICAgcmV0dXJuIHN0b3JhZ2Vba2V5XSA9IHN0YXRlO1xuICB9O1xuXG4gIHZhciByZWFkU3RhdGUgPSBmdW5jdGlvbiByZWFkU3RhdGUoa2V5KSB7XG4gICAgcmV0dXJuIHN0b3JhZ2Vba2V5XTtcbiAgfTtcblxuICByZXR1cm4gaGlzdG9yeTtcbn07XG5cbmV4cG9ydHMuZGVmYXVsdCA9IGNyZWF0ZU1lbW9yeUhpc3Rvcnk7IiwiJ3VzZSBzdHJpY3QnO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHtcbiAgdmFsdWU6IHRydWVcbn0pO1xuZXhwb3J0cy5sb2NhdGlvbnNBcmVFcXVhbCA9IGV4cG9ydHMuQWN0aW9ucyA9IGV4cG9ydHMudXNlUXVlcmllcyA9IGV4cG9ydHMudXNlQmVmb3JlVW5sb2FkID0gZXhwb3J0cy51c2VCYXNlbmFtZSA9IGV4cG9ydHMuY3JlYXRlTWVtb3J5SGlzdG9yeSA9IGV4cG9ydHMuY3JlYXRlSGFzaEhpc3RvcnkgPSBleHBvcnRzLmNyZWF0ZUhpc3RvcnkgPSB1bmRlZmluZWQ7XG5cbnZhciBfTG9jYXRpb25VdGlscyA9IHJlcXVpcmUoJy4vTG9jYXRpb25VdGlscycpO1xuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgJ2xvY2F0aW9uc0FyZUVxdWFsJywge1xuICBlbnVtZXJhYmxlOiB0cnVlLFxuICBnZXQ6IGZ1bmN0aW9uIGdldCgpIHtcbiAgICByZXR1cm4gX0xvY2F0aW9uVXRpbHMubG9jYXRpb25zQXJlRXF1YWw7XG4gIH1cbn0pO1xuXG52YXIgX2NyZWF0ZUJyb3dzZXJIaXN0b3J5ID0gcmVxdWlyZSgnLi9jcmVhdGVCcm93c2VySGlzdG9yeScpO1xuXG52YXIgX2NyZWF0ZUJyb3dzZXJIaXN0b3J5MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2NyZWF0ZUJyb3dzZXJIaXN0b3J5KTtcblxudmFyIF9jcmVhdGVIYXNoSGlzdG9yeTIgPSByZXF1aXJlKCcuL2NyZWF0ZUhhc2hIaXN0b3J5Jyk7XG5cbnZhciBfY3JlYXRlSGFzaEhpc3RvcnkzID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfY3JlYXRlSGFzaEhpc3RvcnkyKTtcblxudmFyIF9jcmVhdGVNZW1vcnlIaXN0b3J5MiA9IHJlcXVpcmUoJy4vY3JlYXRlTWVtb3J5SGlzdG9yeScpO1xuXG52YXIgX2NyZWF0ZU1lbW9yeUhpc3RvcnkzID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfY3JlYXRlTWVtb3J5SGlzdG9yeTIpO1xuXG52YXIgX3VzZUJhc2VuYW1lMiA9IHJlcXVpcmUoJy4vdXNlQmFzZW5hbWUnKTtcblxudmFyIF91c2VCYXNlbmFtZTMgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF91c2VCYXNlbmFtZTIpO1xuXG52YXIgX3VzZUJlZm9yZVVubG9hZDIgPSByZXF1aXJlKCcuL3VzZUJlZm9yZVVubG9hZCcpO1xuXG52YXIgX3VzZUJlZm9yZVVubG9hZDMgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF91c2VCZWZvcmVVbmxvYWQyKTtcblxudmFyIF91c2VRdWVyaWVzMiA9IHJlcXVpcmUoJy4vdXNlUXVlcmllcycpO1xuXG52YXIgX3VzZVF1ZXJpZXMzID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfdXNlUXVlcmllczIpO1xuXG52YXIgX0FjdGlvbnMyID0gcmVxdWlyZSgnLi9BY3Rpb25zJyk7XG5cbnZhciBfQWN0aW9uczMgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9BY3Rpb25zMik7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbmV4cG9ydHMuY3JlYXRlSGlzdG9yeSA9IF9jcmVhdGVCcm93c2VySGlzdG9yeTIuZGVmYXVsdDtcbmV4cG9ydHMuY3JlYXRlSGFzaEhpc3RvcnkgPSBfY3JlYXRlSGFzaEhpc3RvcnkzLmRlZmF1bHQ7XG5leHBvcnRzLmNyZWF0ZU1lbW9yeUhpc3RvcnkgPSBfY3JlYXRlTWVtb3J5SGlzdG9yeTMuZGVmYXVsdDtcbmV4cG9ydHMudXNlQmFzZW5hbWUgPSBfdXNlQmFzZW5hbWUzLmRlZmF1bHQ7XG5leHBvcnRzLnVzZUJlZm9yZVVubG9hZCA9IF91c2VCZWZvcmVVbmxvYWQzLmRlZmF1bHQ7XG5leHBvcnRzLnVzZVF1ZXJpZXMgPSBfdXNlUXVlcmllczMuZGVmYXVsdDtcbmV4cG9ydHMuQWN0aW9ucyA9IF9BY3Rpb25zMy5kZWZhdWx0OyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF93YXJuaW5nID0gcmVxdWlyZSgnd2FybmluZycpO1xuXG52YXIgX3dhcm5pbmcyID0gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChfd2FybmluZyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciBydW5UcmFuc2l0aW9uSG9vayA9IGZ1bmN0aW9uIHJ1blRyYW5zaXRpb25Ib29rKGhvb2ssIGxvY2F0aW9uLCBjYWxsYmFjaykge1xuICB2YXIgcmVzdWx0ID0gaG9vayhsb2NhdGlvbiwgY2FsbGJhY2spO1xuXG4gIGlmIChob29rLmxlbmd0aCA8IDIpIHtcbiAgICAvLyBBc3N1bWUgdGhlIGhvb2sgcnVucyBzeW5jaHJvbm91c2x5IGFuZCBhdXRvbWF0aWNhbGx5XG4gICAgLy8gY2FsbCB0aGUgY2FsbGJhY2sgd2l0aCB0aGUgcmV0dXJuIHZhbHVlLlxuICAgIGNhbGxiYWNrKHJlc3VsdCk7XG4gIH0gZWxzZSB7XG4gICAgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09ICdwcm9kdWN0aW9uJyA/ICgwLCBfd2FybmluZzIuZGVmYXVsdCkocmVzdWx0ID09PSB1bmRlZmluZWQsICdZb3Ugc2hvdWxkIG5vdCBcInJldHVyblwiIGluIGEgdHJhbnNpdGlvbiBob29rIHdpdGggYSBjYWxsYmFjayBhcmd1bWVudDsgJyArICdjYWxsIHRoZSBjYWxsYmFjayBpbnN0ZWFkJykgOiB2b2lkIDA7XG4gIH1cbn07XG5cbmV4cG9ydHMuZGVmYXVsdCA9IHJ1blRyYW5zaXRpb25Ib29rOyIsIid1c2Ugc3RyaWN0JztcblxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7XG4gIHZhbHVlOiB0cnVlXG59KTtcblxudmFyIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiB8fCBmdW5jdGlvbiAodGFyZ2V0KSB7IGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7IHZhciBzb3VyY2UgPSBhcmd1bWVudHNbaV07IGZvciAodmFyIGtleSBpbiBzb3VyY2UpIHsgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChzb3VyY2UsIGtleSkpIHsgdGFyZ2V0W2tleV0gPSBzb3VyY2Vba2V5XTsgfSB9IH0gcmV0dXJuIHRhcmdldDsgfTtcblxudmFyIF9ydW5UcmFuc2l0aW9uSG9vayA9IHJlcXVpcmUoJy4vcnVuVHJhbnNpdGlvbkhvb2snKTtcblxudmFyIF9ydW5UcmFuc2l0aW9uSG9vazIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9ydW5UcmFuc2l0aW9uSG9vayk7XG5cbnZhciBfUGF0aFV0aWxzID0gcmVxdWlyZSgnLi9QYXRoVXRpbHMnKTtcblxuZnVuY3Rpb24gX2ludGVyb3BSZXF1aXJlRGVmYXVsdChvYmopIHsgcmV0dXJuIG9iaiAmJiBvYmouX19lc01vZHVsZSA/IG9iaiA6IHsgZGVmYXVsdDogb2JqIH07IH1cblxudmFyIHVzZUJhc2VuYW1lID0gZnVuY3Rpb24gdXNlQmFzZW5hbWUoY3JlYXRlSGlzdG9yeSkge1xuICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgIHZhciBvcHRpb25zID0gYXJndW1lbnRzLmxlbmd0aCA8PSAwIHx8IGFyZ3VtZW50c1swXSA9PT0gdW5kZWZpbmVkID8ge30gOiBhcmd1bWVudHNbMF07XG5cbiAgICB2YXIgaGlzdG9yeSA9IGNyZWF0ZUhpc3Rvcnkob3B0aW9ucyk7XG4gICAgdmFyIGJhc2VuYW1lID0gb3B0aW9ucy5iYXNlbmFtZTtcblxuXG4gICAgdmFyIGFkZEJhc2VuYW1lID0gZnVuY3Rpb24gYWRkQmFzZW5hbWUobG9jYXRpb24pIHtcbiAgICAgIGlmICghbG9jYXRpb24pIHJldHVybiBsb2NhdGlvbjtcblxuICAgICAgaWYgKGJhc2VuYW1lICYmIGxvY2F0aW9uLmJhc2VuYW1lID09IG51bGwpIHtcbiAgICAgICAgaWYgKGxvY2F0aW9uLnBhdGhuYW1lLmluZGV4T2YoYmFzZW5hbWUpID09PSAwKSB7XG4gICAgICAgICAgbG9jYXRpb24ucGF0aG5hbWUgPSBsb2NhdGlvbi5wYXRobmFtZS5zdWJzdHJpbmcoYmFzZW5hbWUubGVuZ3RoKTtcbiAgICAgICAgICBsb2NhdGlvbi5iYXNlbmFtZSA9IGJhc2VuYW1lO1xuXG4gICAgICAgICAgaWYgKGxvY2F0aW9uLnBhdGhuYW1lID09PSAnJykgbG9jYXRpb24ucGF0aG5hbWUgPSAnLyc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbG9jYXRpb24uYmFzZW5hbWUgPSAnJztcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gbG9jYXRpb247XG4gICAgfTtcblxuICAgIHZhciBwcmVwZW5kQmFzZW5hbWUgPSBmdW5jdGlvbiBwcmVwZW5kQmFzZW5hbWUobG9jYXRpb24pIHtcbiAgICAgIGlmICghYmFzZW5hbWUpIHJldHVybiBsb2NhdGlvbjtcblxuICAgICAgdmFyIG9iamVjdCA9IHR5cGVvZiBsb2NhdGlvbiA9PT0gJ3N0cmluZycgPyAoMCwgX1BhdGhVdGlscy5wYXJzZVBhdGgpKGxvY2F0aW9uKSA6IGxvY2F0aW9uO1xuICAgICAgdmFyIHBuYW1lID0gb2JqZWN0LnBhdGhuYW1lO1xuICAgICAgdmFyIG5vcm1hbGl6ZWRCYXNlbmFtZSA9IGJhc2VuYW1lLnNsaWNlKC0xKSA9PT0gJy8nID8gYmFzZW5hbWUgOiBiYXNlbmFtZSArICcvJztcbiAgICAgIHZhciBub3JtYWxpemVkUGF0aG5hbWUgPSBwbmFtZS5jaGFyQXQoMCkgPT09ICcvJyA/IHBuYW1lLnNsaWNlKDEpIDogcG5hbWU7XG4gICAgICB2YXIgcGF0aG5hbWUgPSBub3JtYWxpemVkQmFzZW5hbWUgKyBub3JtYWxpemVkUGF0aG5hbWU7XG5cbiAgICAgIHJldHVybiBfZXh0ZW5kcyh7fSwgbG9jYXRpb24sIHtcbiAgICAgICAgcGF0aG5hbWU6IHBhdGhuYW1lXG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgLy8gT3ZlcnJpZGUgYWxsIHJlYWQgbWV0aG9kcyB3aXRoIGJhc2VuYW1lLWF3YXJlIHZlcnNpb25zLlxuICAgIHZhciBnZXRDdXJyZW50TG9jYXRpb24gPSBmdW5jdGlvbiBnZXRDdXJyZW50TG9jYXRpb24oKSB7XG4gICAgICByZXR1cm4gYWRkQmFzZW5hbWUoaGlzdG9yeS5nZXRDdXJyZW50TG9jYXRpb24oKSk7XG4gICAgfTtcblxuICAgIHZhciBsaXN0ZW5CZWZvcmUgPSBmdW5jdGlvbiBsaXN0ZW5CZWZvcmUoaG9vaykge1xuICAgICAgcmV0dXJuIGhpc3RvcnkubGlzdGVuQmVmb3JlKGZ1bmN0aW9uIChsb2NhdGlvbiwgY2FsbGJhY2spIHtcbiAgICAgICAgcmV0dXJuICgwLCBfcnVuVHJhbnNpdGlvbkhvb2syLmRlZmF1bHQpKGhvb2ssIGFkZEJhc2VuYW1lKGxvY2F0aW9uKSwgY2FsbGJhY2spO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIHZhciBsaXN0ZW4gPSBmdW5jdGlvbiBsaXN0ZW4obGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBoaXN0b3J5Lmxpc3RlbihmdW5jdGlvbiAobG9jYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIGxpc3RlbmVyKGFkZEJhc2VuYW1lKGxvY2F0aW9uKSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgLy8gT3ZlcnJpZGUgYWxsIHdyaXRlIG1ldGhvZHMgd2l0aCBiYXNlbmFtZS1hd2FyZSB2ZXJzaW9ucy5cbiAgICB2YXIgcHVzaCA9IGZ1bmN0aW9uIHB1c2gobG9jYXRpb24pIHtcbiAgICAgIHJldHVybiBoaXN0b3J5LnB1c2gocHJlcGVuZEJhc2VuYW1lKGxvY2F0aW9uKSk7XG4gICAgfTtcblxuICAgIHZhciByZXBsYWNlID0gZnVuY3Rpb24gcmVwbGFjZShsb2NhdGlvbikge1xuICAgICAgcmV0dXJuIGhpc3RvcnkucmVwbGFjZShwcmVwZW5kQmFzZW5hbWUobG9jYXRpb24pKTtcbiAgICB9O1xuXG4gICAgdmFyIGNyZWF0ZVBhdGggPSBmdW5jdGlvbiBjcmVhdGVQYXRoKGxvY2F0aW9uKSB7XG4gICAgICByZXR1cm4gaGlzdG9yeS5jcmVhdGVQYXRoKHByZXBlbmRCYXNlbmFtZShsb2NhdGlvbikpO1xuICAgIH07XG5cbiAgICB2YXIgY3JlYXRlSHJlZiA9IGZ1bmN0aW9uIGNyZWF0ZUhyZWYobG9jYXRpb24pIHtcbiAgICAgIHJldHVybiBoaXN0b3J5LmNyZWF0ZUhyZWYocHJlcGVuZEJhc2VuYW1lKGxvY2F0aW9uKSk7XG4gICAgfTtcblxuICAgIHZhciBjcmVhdGVMb2NhdGlvbiA9IGZ1bmN0aW9uIGNyZWF0ZUxvY2F0aW9uKGxvY2F0aW9uKSB7XG4gICAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW4gPiAxID8gX2xlbiAtIDEgOiAwKSwgX2tleSA9IDE7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgICAgYXJnc1tfa2V5IC0gMV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBhZGRCYXNlbmFtZShoaXN0b3J5LmNyZWF0ZUxvY2F0aW9uLmFwcGx5KGhpc3RvcnksIFtwcmVwZW5kQmFzZW5hbWUobG9jYXRpb24pXS5jb25jYXQoYXJncykpKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRzKHt9LCBoaXN0b3J5LCB7XG4gICAgICBnZXRDdXJyZW50TG9jYXRpb246IGdldEN1cnJlbnRMb2NhdGlvbixcbiAgICAgIGxpc3RlbkJlZm9yZTogbGlzdGVuQmVmb3JlLFxuICAgICAgbGlzdGVuOiBsaXN0ZW4sXG4gICAgICBwdXNoOiBwdXNoLFxuICAgICAgcmVwbGFjZTogcmVwbGFjZSxcbiAgICAgIGNyZWF0ZVBhdGg6IGNyZWF0ZVBhdGgsXG4gICAgICBjcmVhdGVIcmVmOiBjcmVhdGVIcmVmLFxuICAgICAgY3JlYXRlTG9jYXRpb246IGNyZWF0ZUxvY2F0aW9uXG4gICAgfSk7XG4gIH07XG59O1xuXG5leHBvcnRzLmRlZmF1bHQgPSB1c2VCYXNlbmFtZTsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbnZhciBfaW52YXJpYW50ID0gcmVxdWlyZSgnaW52YXJpYW50Jyk7XG5cbnZhciBfaW52YXJpYW50MiA9IF9pbnRlcm9wUmVxdWlyZURlZmF1bHQoX2ludmFyaWFudCk7XG5cbnZhciBfRE9NVXRpbHMgPSByZXF1aXJlKCcuL0RPTVV0aWxzJyk7XG5cbnZhciBfRXhlY3V0aW9uRW52aXJvbm1lbnQgPSByZXF1aXJlKCcuL0V4ZWN1dGlvbkVudmlyb25tZW50Jyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciBzdGFydExpc3RlbmVyID0gZnVuY3Rpb24gc3RhcnRMaXN0ZW5lcihnZXRQcm9tcHRNZXNzYWdlKSB7XG4gIHZhciBoYW5kbGVCZWZvcmVVbmxvYWQgPSBmdW5jdGlvbiBoYW5kbGVCZWZvcmVVbmxvYWQoZXZlbnQpIHtcbiAgICB2YXIgbWVzc2FnZSA9IGdldFByb21wdE1lc3NhZ2UoKTtcblxuICAgIGlmICh0eXBlb2YgbWVzc2FnZSA9PT0gJ3N0cmluZycpIHtcbiAgICAgIChldmVudCB8fCB3aW5kb3cuZXZlbnQpLnJldHVyblZhbHVlID0gbWVzc2FnZTtcbiAgICAgIHJldHVybiBtZXNzYWdlO1xuICAgIH1cblxuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH07XG5cbiAgKDAsIF9ET01VdGlscy5hZGRFdmVudExpc3RlbmVyKSh3aW5kb3csICdiZWZvcmV1bmxvYWQnLCBoYW5kbGVCZWZvcmVVbmxvYWQpO1xuXG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuICgwLCBfRE9NVXRpbHMucmVtb3ZlRXZlbnRMaXN0ZW5lcikod2luZG93LCAnYmVmb3JldW5sb2FkJywgaGFuZGxlQmVmb3JlVW5sb2FkKTtcbiAgfTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBhIG5ldyBjcmVhdGVIaXN0b3J5IGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQgdG8gY3JlYXRlXG4gKiBoaXN0b3J5IG9iamVjdHMgdGhhdCBrbm93IGhvdyB0byB1c2UgdGhlIGJlZm9yZXVubG9hZCBldmVudCBpbiB3ZWJcbiAqIGJyb3dzZXJzIHRvIGNhbmNlbCBuYXZpZ2F0aW9uLlxuICovXG52YXIgdXNlQmVmb3JlVW5sb2FkID0gZnVuY3Rpb24gdXNlQmVmb3JlVW5sb2FkKGNyZWF0ZUhpc3RvcnkpIHtcbiAgIV9FeGVjdXRpb25FbnZpcm9ubWVudC5jYW5Vc2VET00gPyBwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nID8gKDAsIF9pbnZhcmlhbnQyLmRlZmF1bHQpKGZhbHNlLCAndXNlQmVmb3JlVW5sb2FkIG9ubHkgd29ya3MgaW4gRE9NIGVudmlyb25tZW50cycpIDogKDAsIF9pbnZhcmlhbnQyLmRlZmF1bHQpKGZhbHNlKSA6IHZvaWQgMDtcblxuICByZXR1cm4gZnVuY3Rpb24gKG9wdGlvbnMpIHtcbiAgICB2YXIgaGlzdG9yeSA9IGNyZWF0ZUhpc3Rvcnkob3B0aW9ucyk7XG5cbiAgICB2YXIgbGlzdGVuZXJzID0gW107XG4gICAgdmFyIHN0b3BMaXN0ZW5lciA9IHZvaWQgMDtcblxuICAgIHZhciBnZXRQcm9tcHRNZXNzYWdlID0gZnVuY3Rpb24gZ2V0UHJvbXB0TWVzc2FnZSgpIHtcbiAgICAgIHZhciBtZXNzYWdlID0gdm9pZCAwO1xuICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7IG1lc3NhZ2UgPT0gbnVsbCAmJiBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgbWVzc2FnZSA9IGxpc3RlbmVyc1tpXS5jYWxsKCk7XG4gICAgICB9cmV0dXJuIG1lc3NhZ2U7XG4gICAgfTtcblxuICAgIHZhciBsaXN0ZW5CZWZvcmVVbmxvYWQgPSBmdW5jdGlvbiBsaXN0ZW5CZWZvcmVVbmxvYWQobGlzdGVuZXIpIHtcbiAgICAgIGlmIChsaXN0ZW5lcnMucHVzaChsaXN0ZW5lcikgPT09IDEpIHN0b3BMaXN0ZW5lciA9IHN0YXJ0TGlzdGVuZXIoZ2V0UHJvbXB0TWVzc2FnZSk7XG5cbiAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgICAgIGxpc3RlbmVycyA9IGxpc3RlbmVycy5maWx0ZXIoZnVuY3Rpb24gKGl0ZW0pIHtcbiAgICAgICAgICByZXR1cm4gaXRlbSAhPT0gbGlzdGVuZXI7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID09PSAwICYmIHN0b3BMaXN0ZW5lcikge1xuICAgICAgICAgIHN0b3BMaXN0ZW5lcigpO1xuICAgICAgICAgIHN0b3BMaXN0ZW5lciA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfTtcblxuICAgIHJldHVybiBfZXh0ZW5kcyh7fSwgaGlzdG9yeSwge1xuICAgICAgbGlzdGVuQmVmb3JlVW5sb2FkOiBsaXN0ZW5CZWZvcmVVbmxvYWRcbiAgICB9KTtcbiAgfTtcbn07XG5cbmV4cG9ydHMuZGVmYXVsdCA9IHVzZUJlZm9yZVVubG9hZDsiLCIndXNlIHN0cmljdCc7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwge1xuICB2YWx1ZTogdHJ1ZVxufSk7XG5cbnZhciBfZXh0ZW5kcyA9IE9iamVjdC5hc3NpZ24gfHwgZnVuY3Rpb24gKHRhcmdldCkgeyBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykgeyB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldOyBmb3IgKHZhciBrZXkgaW4gc291cmNlKSB7IGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoc291cmNlLCBrZXkpKSB7IHRhcmdldFtrZXldID0gc291cmNlW2tleV07IH0gfSB9IHJldHVybiB0YXJnZXQ7IH07XG5cbnZhciBfcXVlcnlTdHJpbmcgPSByZXF1aXJlKCdxdWVyeS1zdHJpbmcnKTtcblxudmFyIF9ydW5UcmFuc2l0aW9uSG9vayA9IHJlcXVpcmUoJy4vcnVuVHJhbnNpdGlvbkhvb2snKTtcblxudmFyIF9ydW5UcmFuc2l0aW9uSG9vazIgPSBfaW50ZXJvcFJlcXVpcmVEZWZhdWx0KF9ydW5UcmFuc2l0aW9uSG9vayk7XG5cbnZhciBfTG9jYXRpb25VdGlscyA9IHJlcXVpcmUoJy4vTG9jYXRpb25VdGlscycpO1xuXG52YXIgX1BhdGhVdGlscyA9IHJlcXVpcmUoJy4vUGF0aFV0aWxzJyk7XG5cbmZ1bmN0aW9uIF9pbnRlcm9wUmVxdWlyZURlZmF1bHQob2JqKSB7IHJldHVybiBvYmogJiYgb2JqLl9fZXNNb2R1bGUgPyBvYmogOiB7IGRlZmF1bHQ6IG9iaiB9OyB9XG5cbnZhciBkZWZhdWx0U3RyaW5naWZ5UXVlcnkgPSBmdW5jdGlvbiBkZWZhdWx0U3RyaW5naWZ5UXVlcnkocXVlcnkpIHtcbiAgcmV0dXJuICgwLCBfcXVlcnlTdHJpbmcuc3RyaW5naWZ5KShxdWVyeSkucmVwbGFjZSgvJTIwL2csICcrJyk7XG59O1xuXG52YXIgZGVmYXVsdFBhcnNlUXVlcnlTdHJpbmcgPSBfcXVlcnlTdHJpbmcucGFyc2U7XG5cbi8qKlxuICogUmV0dXJucyBhIG5ldyBjcmVhdGVIaXN0b3J5IGZ1bmN0aW9uIHRoYXQgbWF5IGJlIHVzZWQgdG8gY3JlYXRlXG4gKiBoaXN0b3J5IG9iamVjdHMgdGhhdCBrbm93IGhvdyB0byBoYW5kbGUgVVJMIHF1ZXJpZXMuXG4gKi9cbnZhciB1c2VRdWVyaWVzID0gZnVuY3Rpb24gdXNlUXVlcmllcyhjcmVhdGVIaXN0b3J5KSB7XG4gIHJldHVybiBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG9wdGlvbnMgPSBhcmd1bWVudHMubGVuZ3RoIDw9IDAgfHwgYXJndW1lbnRzWzBdID09PSB1bmRlZmluZWQgPyB7fSA6IGFyZ3VtZW50c1swXTtcblxuICAgIHZhciBoaXN0b3J5ID0gY3JlYXRlSGlzdG9yeShvcHRpb25zKTtcbiAgICB2YXIgc3RyaW5naWZ5UXVlcnkgPSBvcHRpb25zLnN0cmluZ2lmeVF1ZXJ5O1xuICAgIHZhciBwYXJzZVF1ZXJ5U3RyaW5nID0gb3B0aW9ucy5wYXJzZVF1ZXJ5U3RyaW5nO1xuXG5cbiAgICBpZiAodHlwZW9mIHN0cmluZ2lmeVF1ZXJ5ICE9PSAnZnVuY3Rpb24nKSBzdHJpbmdpZnlRdWVyeSA9IGRlZmF1bHRTdHJpbmdpZnlRdWVyeTtcblxuICAgIGlmICh0eXBlb2YgcGFyc2VRdWVyeVN0cmluZyAhPT0gJ2Z1bmN0aW9uJykgcGFyc2VRdWVyeVN0cmluZyA9IGRlZmF1bHRQYXJzZVF1ZXJ5U3RyaW5nO1xuXG4gICAgdmFyIGRlY29kZVF1ZXJ5ID0gZnVuY3Rpb24gZGVjb2RlUXVlcnkobG9jYXRpb24pIHtcbiAgICAgIGlmICghbG9jYXRpb24pIHJldHVybiBsb2NhdGlvbjtcblxuICAgICAgaWYgKGxvY2F0aW9uLnF1ZXJ5ID09IG51bGwpIGxvY2F0aW9uLnF1ZXJ5ID0gcGFyc2VRdWVyeVN0cmluZyhsb2NhdGlvbi5zZWFyY2guc3Vic3RyaW5nKDEpKTtcblxuICAgICAgcmV0dXJuIGxvY2F0aW9uO1xuICAgIH07XG5cbiAgICB2YXIgZW5jb2RlUXVlcnkgPSBmdW5jdGlvbiBlbmNvZGVRdWVyeShsb2NhdGlvbiwgcXVlcnkpIHtcbiAgICAgIGlmIChxdWVyeSA9PSBudWxsKSByZXR1cm4gbG9jYXRpb247XG5cbiAgICAgIHZhciBvYmplY3QgPSB0eXBlb2YgbG9jYXRpb24gPT09ICdzdHJpbmcnID8gKDAsIF9QYXRoVXRpbHMucGFyc2VQYXRoKShsb2NhdGlvbikgOiBsb2NhdGlvbjtcbiAgICAgIHZhciBxdWVyeVN0cmluZyA9IHN0cmluZ2lmeVF1ZXJ5KHF1ZXJ5KTtcbiAgICAgIHZhciBzZWFyY2ggPSBxdWVyeVN0cmluZyA/ICc/JyArIHF1ZXJ5U3RyaW5nIDogJyc7XG5cbiAgICAgIHJldHVybiBfZXh0ZW5kcyh7fSwgb2JqZWN0LCB7XG4gICAgICAgIHNlYXJjaDogc2VhcmNoXG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgLy8gT3ZlcnJpZGUgYWxsIHJlYWQgbWV0aG9kcyB3aXRoIHF1ZXJ5LWF3YXJlIHZlcnNpb25zLlxuICAgIHZhciBnZXRDdXJyZW50TG9jYXRpb24gPSBmdW5jdGlvbiBnZXRDdXJyZW50TG9jYXRpb24oKSB7XG4gICAgICByZXR1cm4gZGVjb2RlUXVlcnkoaGlzdG9yeS5nZXRDdXJyZW50TG9jYXRpb24oKSk7XG4gICAgfTtcblxuICAgIHZhciBsaXN0ZW5CZWZvcmUgPSBmdW5jdGlvbiBsaXN0ZW5CZWZvcmUoaG9vaykge1xuICAgICAgcmV0dXJuIGhpc3RvcnkubGlzdGVuQmVmb3JlKGZ1bmN0aW9uIChsb2NhdGlvbiwgY2FsbGJhY2spIHtcbiAgICAgICAgcmV0dXJuICgwLCBfcnVuVHJhbnNpdGlvbkhvb2syLmRlZmF1bHQpKGhvb2ssIGRlY29kZVF1ZXJ5KGxvY2F0aW9uKSwgY2FsbGJhY2spO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIHZhciBsaXN0ZW4gPSBmdW5jdGlvbiBsaXN0ZW4obGlzdGVuZXIpIHtcbiAgICAgIHJldHVybiBoaXN0b3J5Lmxpc3RlbihmdW5jdGlvbiAobG9jYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIGxpc3RlbmVyKGRlY29kZVF1ZXJ5KGxvY2F0aW9uKSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgLy8gT3ZlcnJpZGUgYWxsIHdyaXRlIG1ldGhvZHMgd2l0aCBxdWVyeS1hd2FyZSB2ZXJzaW9ucy5cbiAgICB2YXIgcHVzaCA9IGZ1bmN0aW9uIHB1c2gobG9jYXRpb24pIHtcbiAgICAgIHJldHVybiBoaXN0b3J5LnB1c2goZW5jb2RlUXVlcnkobG9jYXRpb24sIGxvY2F0aW9uLnF1ZXJ5KSk7XG4gICAgfTtcblxuICAgIHZhciByZXBsYWNlID0gZnVuY3Rpb24gcmVwbGFjZShsb2NhdGlvbikge1xuICAgICAgcmV0dXJuIGhpc3RvcnkucmVwbGFjZShlbmNvZGVRdWVyeShsb2NhdGlvbiwgbG9jYXRpb24ucXVlcnkpKTtcbiAgICB9O1xuXG4gICAgdmFyIGNyZWF0ZVBhdGggPSBmdW5jdGlvbiBjcmVhdGVQYXRoKGxvY2F0aW9uKSB7XG4gICAgICByZXR1cm4gaGlzdG9yeS5jcmVhdGVQYXRoKGVuY29kZVF1ZXJ5KGxvY2F0aW9uLCBsb2NhdGlvbi5xdWVyeSkpO1xuICAgIH07XG5cbiAgICB2YXIgY3JlYXRlSHJlZiA9IGZ1bmN0aW9uIGNyZWF0ZUhyZWYobG9jYXRpb24pIHtcbiAgICAgIHJldHVybiBoaXN0b3J5LmNyZWF0ZUhyZWYoZW5jb2RlUXVlcnkobG9jYXRpb24sIGxvY2F0aW9uLnF1ZXJ5KSk7XG4gICAgfTtcblxuICAgIHZhciBjcmVhdGVMb2NhdGlvbiA9IGZ1bmN0aW9uIGNyZWF0ZUxvY2F0aW9uKGxvY2F0aW9uKSB7XG4gICAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW4gPiAxID8gX2xlbiAtIDEgOiAwKSwgX2tleSA9IDE7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgICAgYXJnc1tfa2V5IC0gMV0gPSBhcmd1bWVudHNbX2tleV07XG4gICAgICB9XG5cbiAgICAgIHZhciBuZXdMb2NhdGlvbiA9IGhpc3RvcnkuY3JlYXRlTG9jYXRpb24uYXBwbHkoaGlzdG9yeSwgW2VuY29kZVF1ZXJ5KGxvY2F0aW9uLCBsb2NhdGlvbi5xdWVyeSldLmNvbmNhdChhcmdzKSk7XG5cbiAgICAgIGlmIChsb2NhdGlvbi5xdWVyeSkgbmV3TG9jYXRpb24ucXVlcnkgPSAoMCwgX0xvY2F0aW9uVXRpbHMuY3JlYXRlUXVlcnkpKGxvY2F0aW9uLnF1ZXJ5KTtcblxuICAgICAgcmV0dXJuIGRlY29kZVF1ZXJ5KG5ld0xvY2F0aW9uKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIF9leHRlbmRzKHt9LCBoaXN0b3J5LCB7XG4gICAgICBnZXRDdXJyZW50TG9jYXRpb246IGdldEN1cnJlbnRMb2NhdGlvbixcbiAgICAgIGxpc3RlbkJlZm9yZTogbGlzdGVuQmVmb3JlLFxuICAgICAgbGlzdGVuOiBsaXN0ZW4sXG4gICAgICBwdXNoOiBwdXNoLFxuICAgICAgcmVwbGFjZTogcmVwbGFjZSxcbiAgICAgIGNyZWF0ZVBhdGg6IGNyZWF0ZVBhdGgsXG4gICAgICBjcmVhdGVIcmVmOiBjcmVhdGVIcmVmLFxuICAgICAgY3JlYXRlTG9jYXRpb246IGNyZWF0ZUxvY2F0aW9uXG4gICAgfSk7XG4gIH07XG59O1xuXG5leHBvcnRzLmRlZmF1bHQgPSB1c2VRdWVyaWVzOyIsIi8qKlxuICogQ29weXJpZ2h0IDIwMTMtMjAxNSwgRmFjZWJvb2ssIEluYy5cbiAqIEFsbCByaWdodHMgcmVzZXJ2ZWQuXG4gKlxuICogVGhpcyBzb3VyY2UgY29kZSBpcyBsaWNlbnNlZCB1bmRlciB0aGUgQlNELXN0eWxlIGxpY2Vuc2UgZm91bmQgaW4gdGhlXG4gKiBMSUNFTlNFIGZpbGUgaW4gdGhlIHJvb3QgZGlyZWN0b3J5IG9mIHRoaXMgc291cmNlIHRyZWUuIEFuIGFkZGl0aW9uYWwgZ3JhbnRcbiAqIG9mIHBhdGVudCByaWdodHMgY2FuIGJlIGZvdW5kIGluIHRoZSBQQVRFTlRTIGZpbGUgaW4gdGhlIHNhbWUgZGlyZWN0b3J5LlxuICovXG5cbid1c2Ugc3RyaWN0JztcblxuLyoqXG4gKiBVc2UgaW52YXJpYW50KCkgdG8gYXNzZXJ0IHN0YXRlIHdoaWNoIHlvdXIgcHJvZ3JhbSBhc3N1bWVzIHRvIGJlIHRydWUuXG4gKlxuICogUHJvdmlkZSBzcHJpbnRmLXN0eWxlIGZvcm1hdCAob25seSAlcyBpcyBzdXBwb3J0ZWQpIGFuZCBhcmd1bWVudHNcbiAqIHRvIHByb3ZpZGUgaW5mb3JtYXRpb24gYWJvdXQgd2hhdCBicm9rZSBhbmQgd2hhdCB5b3Ugd2VyZVxuICogZXhwZWN0aW5nLlxuICpcbiAqIFRoZSBpbnZhcmlhbnQgbWVzc2FnZSB3aWxsIGJlIHN0cmlwcGVkIGluIHByb2R1Y3Rpb24sIGJ1dCB0aGUgaW52YXJpYW50XG4gKiB3aWxsIHJlbWFpbiB0byBlbnN1cmUgbG9naWMgZG9lcyBub3QgZGlmZmVyIGluIHByb2R1Y3Rpb24uXG4gKi9cblxudmFyIGludmFyaWFudCA9IGZ1bmN0aW9uKGNvbmRpdGlvbiwgZm9ybWF0LCBhLCBiLCBjLCBkLCBlLCBmKSB7XG4gIGlmIChwcm9jZXNzLmVudi5OT0RFX0VOViAhPT0gJ3Byb2R1Y3Rpb24nKSB7XG4gICAgaWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ2ludmFyaWFudCByZXF1aXJlcyBhbiBlcnJvciBtZXNzYWdlIGFyZ3VtZW50Jyk7XG4gICAgfVxuICB9XG5cbiAgaWYgKCFjb25kaXRpb24pIHtcbiAgICB2YXIgZXJyb3I7XG4gICAgaWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBlcnJvciA9IG5ldyBFcnJvcihcbiAgICAgICAgJ01pbmlmaWVkIGV4Y2VwdGlvbiBvY2N1cnJlZDsgdXNlIHRoZSBub24tbWluaWZpZWQgZGV2IGVudmlyb25tZW50ICcgK1xuICAgICAgICAnZm9yIHRoZSBmdWxsIGVycm9yIG1lc3NhZ2UgYW5kIGFkZGl0aW9uYWwgaGVscGZ1bCB3YXJuaW5ncy4nXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgYXJncyA9IFthLCBiLCBjLCBkLCBlLCBmXTtcbiAgICAgIHZhciBhcmdJbmRleCA9IDA7XG4gICAgICBlcnJvciA9IG5ldyBFcnJvcihcbiAgICAgICAgZm9ybWF0LnJlcGxhY2UoLyVzL2csIGZ1bmN0aW9uKCkgeyByZXR1cm4gYXJnc1thcmdJbmRleCsrXTsgfSlcbiAgICAgICk7XG4gICAgICBlcnJvci5uYW1lID0gJ0ludmFyaWFudCBWaW9sYXRpb24nO1xuICAgIH1cblxuICAgIGVycm9yLmZyYW1lc1RvUG9wID0gMTsgLy8gd2UgZG9uJ3QgY2FyZSBhYm91dCBpbnZhcmlhbnQncyBvd24gZnJhbWVcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBpbnZhcmlhbnQ7XG4iLCIndXNlIHN0cmljdCc7XG52YXIgc3RyaWN0VXJpRW5jb2RlID0gcmVxdWlyZSgnc3RyaWN0LXVyaS1lbmNvZGUnKTtcbnZhciBvYmplY3RBc3NpZ24gPSByZXF1aXJlKCdvYmplY3QtYXNzaWduJyk7XG5cbmZ1bmN0aW9uIGVuY29kZSh2YWx1ZSwgb3B0cykge1xuXHRpZiAob3B0cy5lbmNvZGUpIHtcblx0XHRyZXR1cm4gb3B0cy5zdHJpY3QgPyBzdHJpY3RVcmlFbmNvZGUodmFsdWUpIDogZW5jb2RlVVJJQ29tcG9uZW50KHZhbHVlKTtcblx0fVxuXG5cdHJldHVybiB2YWx1ZTtcbn1cblxuZXhwb3J0cy5leHRyYWN0ID0gZnVuY3Rpb24gKHN0cikge1xuXHRyZXR1cm4gc3RyLnNwbGl0KCc/JylbMV0gfHwgJyc7XG59O1xuXG5leHBvcnRzLnBhcnNlID0gZnVuY3Rpb24gKHN0cikge1xuXHQvLyBDcmVhdGUgYW4gb2JqZWN0IHdpdGggbm8gcHJvdG90eXBlXG5cdC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9zaW5kcmVzb3JodXMvcXVlcnktc3RyaW5nL2lzc3Vlcy80N1xuXHR2YXIgcmV0ID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcblxuXHRpZiAodHlwZW9mIHN0ciAhPT0gJ3N0cmluZycpIHtcblx0XHRyZXR1cm4gcmV0O1xuXHR9XG5cblx0c3RyID0gc3RyLnRyaW0oKS5yZXBsYWNlKC9eKFxcP3wjfCYpLywgJycpO1xuXG5cdGlmICghc3RyKSB7XG5cdFx0cmV0dXJuIHJldDtcblx0fVxuXG5cdHN0ci5zcGxpdCgnJicpLmZvckVhY2goZnVuY3Rpb24gKHBhcmFtKSB7XG5cdFx0dmFyIHBhcnRzID0gcGFyYW0ucmVwbGFjZSgvXFwrL2csICcgJykuc3BsaXQoJz0nKTtcblx0XHQvLyBGaXJlZm94IChwcmUgNDApIGRlY29kZXMgYCUzRGAgdG8gYD1gXG5cdFx0Ly8gaHR0cHM6Ly9naXRodWIuY29tL3NpbmRyZXNvcmh1cy9xdWVyeS1zdHJpbmcvcHVsbC8zN1xuXHRcdHZhciBrZXkgPSBwYXJ0cy5zaGlmdCgpO1xuXHRcdHZhciB2YWwgPSBwYXJ0cy5sZW5ndGggPiAwID8gcGFydHMuam9pbignPScpIDogdW5kZWZpbmVkO1xuXG5cdFx0a2V5ID0gZGVjb2RlVVJJQ29tcG9uZW50KGtleSk7XG5cblx0XHQvLyBtaXNzaW5nIGA9YCBzaG91bGQgYmUgYG51bGxgOlxuXHRcdC8vIGh0dHA6Ly93My5vcmcvVFIvMjAxMi9XRC11cmwtMjAxMjA1MjQvI2NvbGxlY3QtdXJsLXBhcmFtZXRlcnNcblx0XHR2YWwgPSB2YWwgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBkZWNvZGVVUklDb21wb25lbnQodmFsKTtcblxuXHRcdGlmIChyZXRba2V5XSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRyZXRba2V5XSA9IHZhbDtcblx0XHR9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkocmV0W2tleV0pKSB7XG5cdFx0XHRyZXRba2V5XS5wdXNoKHZhbCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldFtrZXldID0gW3JldFtrZXldLCB2YWxdO1xuXHRcdH1cblx0fSk7XG5cblx0cmV0dXJuIHJldDtcbn07XG5cbmV4cG9ydHMuc3RyaW5naWZ5ID0gZnVuY3Rpb24gKG9iaiwgb3B0cykge1xuXHR2YXIgZGVmYXVsdHMgPSB7XG5cdFx0ZW5jb2RlOiB0cnVlLFxuXHRcdHN0cmljdDogdHJ1ZVxuXHR9O1xuXG5cdG9wdHMgPSBvYmplY3RBc3NpZ24oZGVmYXVsdHMsIG9wdHMpO1xuXG5cdHJldHVybiBvYmogPyBPYmplY3Qua2V5cyhvYmopLnNvcnQoKS5tYXAoZnVuY3Rpb24gKGtleSkge1xuXHRcdHZhciB2YWwgPSBvYmpba2V5XTtcblxuXHRcdGlmICh2YWwgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0cmV0dXJuICcnO1xuXHRcdH1cblxuXHRcdGlmICh2YWwgPT09IG51bGwpIHtcblx0XHRcdHJldHVybiBlbmNvZGUoa2V5LCBvcHRzKTtcblx0XHR9XG5cblx0XHRpZiAoQXJyYXkuaXNBcnJheSh2YWwpKSB7XG5cdFx0XHR2YXIgcmVzdWx0ID0gW107XG5cblx0XHRcdHZhbC5zbGljZSgpLmZvckVhY2goZnVuY3Rpb24gKHZhbDIpIHtcblx0XHRcdFx0aWYgKHZhbDIgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICh2YWwyID09PSBudWxsKSB7XG5cdFx0XHRcdFx0cmVzdWx0LnB1c2goZW5jb2RlKGtleSwgb3B0cykpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHJlc3VsdC5wdXNoKGVuY29kZShrZXksIG9wdHMpICsgJz0nICsgZW5jb2RlKHZhbDIsIG9wdHMpKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cblx0XHRcdHJldHVybiByZXN1bHQuam9pbignJicpO1xuXHRcdH1cblxuXHRcdHJldHVybiBlbmNvZGUoa2V5LCBvcHRzKSArICc9JyArIGVuY29kZSh2YWwsIG9wdHMpO1xuXHR9KS5maWx0ZXIoZnVuY3Rpb24gKHgpIHtcblx0XHRyZXR1cm4geC5sZW5ndGggPiAwO1xuXHR9KS5qb2luKCcmJykgOiAnJztcbn07XG4iLCIndXNlIHN0cmljdCc7XG4vKiBlc2xpbnQtZGlzYWJsZSBuby11bnVzZWQtdmFycyAqL1xudmFyIGhhc093blByb3BlcnR5ID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eTtcbnZhciBwcm9wSXNFbnVtZXJhYmxlID0gT2JqZWN0LnByb3RvdHlwZS5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcblxuZnVuY3Rpb24gdG9PYmplY3QodmFsKSB7XG5cdGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQpIHtcblx0XHR0aHJvdyBuZXcgVHlwZUVycm9yKCdPYmplY3QuYXNzaWduIGNhbm5vdCBiZSBjYWxsZWQgd2l0aCBudWxsIG9yIHVuZGVmaW5lZCcpO1xuXHR9XG5cblx0cmV0dXJuIE9iamVjdCh2YWwpO1xufVxuXG5mdW5jdGlvbiBzaG91bGRVc2VOYXRpdmUoKSB7XG5cdHRyeSB7XG5cdFx0aWYgKCFPYmplY3QuYXNzaWduKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gRGV0ZWN0IGJ1Z2d5IHByb3BlcnR5IGVudW1lcmF0aW9uIG9yZGVyIGluIG9sZGVyIFY4IHZlcnNpb25zLlxuXG5cdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9NDExOFxuXHRcdHZhciB0ZXN0MSA9IG5ldyBTdHJpbmcoJ2FiYycpOyAgLy8gZXNsaW50LWRpc2FibGUtbGluZVxuXHRcdHRlc3QxWzVdID0gJ2RlJztcblx0XHRpZiAoT2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModGVzdDEpWzBdID09PSAnNScpIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBodHRwczovL2J1Z3MuY2hyb21pdW0ub3JnL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0zMDU2XG5cdFx0dmFyIHRlc3QyID0ge307XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCAxMDsgaSsrKSB7XG5cdFx0XHR0ZXN0MlsnXycgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGkpXSA9IGk7XG5cdFx0fVxuXHRcdHZhciBvcmRlcjIgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0ZXN0MikubWFwKGZ1bmN0aW9uIChuKSB7XG5cdFx0XHRyZXR1cm4gdGVzdDJbbl07XG5cdFx0fSk7XG5cdFx0aWYgKG9yZGVyMi5qb2luKCcnKSAhPT0gJzAxMjM0NTY3ODknKSB7XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0fVxuXG5cdFx0Ly8gaHR0cHM6Ly9idWdzLmNocm9taXVtLm9yZy9wL3Y4L2lzc3Vlcy9kZXRhaWw/aWQ9MzA1NlxuXHRcdHZhciB0ZXN0MyA9IHt9O1xuXHRcdCdhYmNkZWZnaGlqa2xtbm9wcXJzdCcuc3BsaXQoJycpLmZvckVhY2goZnVuY3Rpb24gKGxldHRlcikge1xuXHRcdFx0dGVzdDNbbGV0dGVyXSA9IGxldHRlcjtcblx0XHR9KTtcblx0XHRpZiAoT2JqZWN0LmtleXMoT2JqZWN0LmFzc2lnbih7fSwgdGVzdDMpKS5qb2luKCcnKSAhPT1cblx0XHRcdFx0J2FiY2RlZmdoaWprbG1ub3BxcnN0Jykge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblxuXHRcdHJldHVybiB0cnVlO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0Ly8gV2UgZG9uJ3QgZXhwZWN0IGFueSBvZiB0aGUgYWJvdmUgdG8gdGhyb3csIGJ1dCBiZXR0ZXIgdG8gYmUgc2FmZS5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn1cblxubW9kdWxlLmV4cG9ydHMgPSBzaG91bGRVc2VOYXRpdmUoKSA/IE9iamVjdC5hc3NpZ24gOiBmdW5jdGlvbiAodGFyZ2V0LCBzb3VyY2UpIHtcblx0dmFyIGZyb207XG5cdHZhciB0byA9IHRvT2JqZWN0KHRhcmdldCk7XG5cdHZhciBzeW1ib2xzO1xuXG5cdGZvciAodmFyIHMgPSAxOyBzIDwgYXJndW1lbnRzLmxlbmd0aDsgcysrKSB7XG5cdFx0ZnJvbSA9IE9iamVjdChhcmd1bWVudHNbc10pO1xuXG5cdFx0Zm9yICh2YXIga2V5IGluIGZyb20pIHtcblx0XHRcdGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKGZyb20sIGtleSkpIHtcblx0XHRcdFx0dG9ba2V5XSA9IGZyb21ba2V5XTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoT2JqZWN0LmdldE93blByb3BlcnR5U3ltYm9scykge1xuXHRcdFx0c3ltYm9scyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eVN5bWJvbHMoZnJvbSk7XG5cdFx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHN5bWJvbHMubGVuZ3RoOyBpKyspIHtcblx0XHRcdFx0aWYgKHByb3BJc0VudW1lcmFibGUuY2FsbChmcm9tLCBzeW1ib2xzW2ldKSkge1xuXHRcdFx0XHRcdHRvW3N5bWJvbHNbaV1dID0gZnJvbVtzeW1ib2xzW2ldXTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB0bztcbn07XG4iLCIndXNlIHN0cmljdCc7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChzdHIpIHtcblx0cmV0dXJuIGVuY29kZVVSSUNvbXBvbmVudChzdHIpLnJlcGxhY2UoL1shJygpKl0vZywgZnVuY3Rpb24gKGMpIHtcblx0XHRyZXR1cm4gJyUnICsgYy5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpO1xuXHR9KTtcbn07XG4iLCIvKipcbiAqIENvcHlyaWdodCAyMDE0LTIwMTUsIEZhY2Vib29rLCBJbmMuXG4gKiBBbGwgcmlnaHRzIHJlc2VydmVkLlxuICpcbiAqIFRoaXMgc291cmNlIGNvZGUgaXMgbGljZW5zZWQgdW5kZXIgdGhlIEJTRC1zdHlsZSBsaWNlbnNlIGZvdW5kIGluIHRoZVxuICogTElDRU5TRSBmaWxlIGluIHRoZSByb290IGRpcmVjdG9yeSBvZiB0aGlzIHNvdXJjZSB0cmVlLiBBbiBhZGRpdGlvbmFsIGdyYW50XG4gKiBvZiBwYXRlbnQgcmlnaHRzIGNhbiBiZSBmb3VuZCBpbiB0aGUgUEFURU5UUyBmaWxlIGluIHRoZSBzYW1lIGRpcmVjdG9yeS5cbiAqL1xuXG4ndXNlIHN0cmljdCc7XG5cbi8qKlxuICogU2ltaWxhciB0byBpbnZhcmlhbnQgYnV0IG9ubHkgbG9ncyBhIHdhcm5pbmcgaWYgdGhlIGNvbmRpdGlvbiBpcyBub3QgbWV0LlxuICogVGhpcyBjYW4gYmUgdXNlZCB0byBsb2cgaXNzdWVzIGluIGRldmVsb3BtZW50IGVudmlyb25tZW50cyBpbiBjcml0aWNhbFxuICogcGF0aHMuIFJlbW92aW5nIHRoZSBsb2dnaW5nIGNvZGUgZm9yIHByb2R1Y3Rpb24gZW52aXJvbm1lbnRzIHdpbGwga2VlcCB0aGVcbiAqIHNhbWUgbG9naWMgYW5kIGZvbGxvdyB0aGUgc2FtZSBjb2RlIHBhdGhzLlxuICovXG5cbnZhciB3YXJuaW5nID0gZnVuY3Rpb24oKSB7fTtcblxuaWYgKHByb2Nlc3MuZW52Lk5PREVfRU5WICE9PSAncHJvZHVjdGlvbicpIHtcbiAgd2FybmluZyA9IGZ1bmN0aW9uKGNvbmRpdGlvbiwgZm9ybWF0LCBhcmdzKSB7XG4gICAgdmFyIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGg7XG4gICAgYXJncyA9IG5ldyBBcnJheShsZW4gPiAyID8gbGVuIC0gMiA6IDApO1xuICAgIGZvciAodmFyIGtleSA9IDI7IGtleSA8IGxlbjsga2V5KyspIHtcbiAgICAgIGFyZ3Nba2V5IC0gMl0gPSBhcmd1bWVudHNba2V5XTtcbiAgICB9XG4gICAgaWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdgd2FybmluZyhjb25kaXRpb24sIGZvcm1hdCwgLi4uYXJncylgIHJlcXVpcmVzIGEgd2FybmluZyAnICtcbiAgICAgICAgJ21lc3NhZ2UgYXJndW1lbnQnXG4gICAgICApO1xuICAgIH1cblxuICAgIGlmIChmb3JtYXQubGVuZ3RoIDwgMTAgfHwgKC9eW3NcXFddKiQvKS50ZXN0KGZvcm1hdCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ1RoZSB3YXJuaW5nIGZvcm1hdCBzaG91bGQgYmUgYWJsZSB0byB1bmlxdWVseSBpZGVudGlmeSB0aGlzICcgK1xuICAgICAgICAnd2FybmluZy4gUGxlYXNlLCB1c2UgYSBtb3JlIGRlc2NyaXB0aXZlIGZvcm1hdCB0aGFuOiAnICsgZm9ybWF0XG4gICAgICApO1xuICAgIH1cblxuICAgIGlmICghY29uZGl0aW9uKSB7XG4gICAgICB2YXIgYXJnSW5kZXggPSAwO1xuICAgICAgdmFyIG1lc3NhZ2UgPSAnV2FybmluZzogJyArXG4gICAgICAgIGZvcm1hdC5yZXBsYWNlKC8lcy9nLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICByZXR1cm4gYXJnc1thcmdJbmRleCsrXTtcbiAgICAgICAgfSk7XG4gICAgICBpZiAodHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IobWVzc2FnZSk7XG4gICAgICB9XG4gICAgICB0cnkge1xuICAgICAgICAvLyBUaGlzIGVycm9yIHdhcyB0aHJvd24gYXMgYSBjb252ZW5pZW5jZSBzbyB0aGF0IHlvdSBjYW4gdXNlIHRoaXMgc3RhY2tcbiAgICAgICAgLy8gdG8gZmluZCB0aGUgY2FsbHNpdGUgdGhhdCBjYXVzZWQgdGhpcyB3YXJuaW5nIHRvIGZpcmUuXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbiAgICAgIH0gY2F0Y2goeCkge31cbiAgICB9XG4gIH07XG59XG5cbm1vZHVsZS5leHBvcnRzID0gd2FybmluZztcbiIsIi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxudmFyIHByb2Nlc3MgPSBtb2R1bGUuZXhwb3J0cyA9IHt9O1xuXG4vLyBjYWNoZWQgZnJvbSB3aGF0ZXZlciBnbG9iYWwgaXMgcHJlc2VudCBzbyB0aGF0IHRlc3QgcnVubmVycyB0aGF0IHN0dWIgaXRcbi8vIGRvbid0IGJyZWFrIHRoaW5ncy4gIEJ1dCB3ZSBuZWVkIHRvIHdyYXAgaXQgaW4gYSB0cnkgY2F0Y2ggaW4gY2FzZSBpdCBpc1xuLy8gd3JhcHBlZCBpbiBzdHJpY3QgbW9kZSBjb2RlIHdoaWNoIGRvZXNuJ3QgZGVmaW5lIGFueSBnbG9iYWxzLiAgSXQncyBpbnNpZGUgYVxuLy8gZnVuY3Rpb24gYmVjYXVzZSB0cnkvY2F0Y2hlcyBkZW9wdGltaXplIGluIGNlcnRhaW4gZW5naW5lcy5cblxudmFyIGNhY2hlZFNldFRpbWVvdXQ7XG52YXIgY2FjaGVkQ2xlYXJUaW1lb3V0O1xuXG4oZnVuY3Rpb24gKCkge1xuICAgIHRyeSB7XG4gICAgICAgIGNhY2hlZFNldFRpbWVvdXQgPSBzZXRUaW1lb3V0O1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY2FjaGVkU2V0VGltZW91dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignc2V0VGltZW91dCBpcyBub3QgZGVmaW5lZCcpO1xuICAgICAgICB9XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGNsZWFyVGltZW91dDtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignY2xlYXJUaW1lb3V0IGlzIG5vdCBkZWZpbmVkJyk7XG4gICAgICAgIH1cbiAgICB9XG59ICgpKVxuZnVuY3Rpb24gcnVuVGltZW91dChmdW4pIHtcbiAgICBpZiAoY2FjaGVkU2V0VGltZW91dCA9PT0gc2V0VGltZW91dCkge1xuICAgICAgICByZXR1cm4gc2V0VGltZW91dChmdW4sIDApO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBjYWNoZWRTZXRUaW1lb3V0LmNhbGwobnVsbCwgZnVuLCAwKTtcbiAgICB9XG59XG5mdW5jdGlvbiBydW5DbGVhclRpbWVvdXQobWFya2VyKSB7XG4gICAgaWYgKGNhY2hlZENsZWFyVGltZW91dCA9PT0gY2xlYXJUaW1lb3V0KSB7XG4gICAgICAgIGNsZWFyVGltZW91dChtYXJrZXIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIGNhY2hlZENsZWFyVGltZW91dC5jYWxsKG51bGwsIG1hcmtlcik7XG4gICAgfVxufVxudmFyIHF1ZXVlID0gW107XG52YXIgZHJhaW5pbmcgPSBmYWxzZTtcbnZhciBjdXJyZW50UXVldWU7XG52YXIgcXVldWVJbmRleCA9IC0xO1xuXG5mdW5jdGlvbiBjbGVhblVwTmV4dFRpY2soKSB7XG4gICAgaWYgKCFkcmFpbmluZyB8fCAhY3VycmVudFF1ZXVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZHJhaW5pbmcgPSBmYWxzZTtcbiAgICBpZiAoY3VycmVudFF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBxdWV1ZSA9IGN1cnJlbnRRdWV1ZS5jb25jYXQocXVldWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICB9XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCkge1xuICAgICAgICBkcmFpblF1ZXVlKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBkcmFpblF1ZXVlKCkge1xuICAgIGlmIChkcmFpbmluZykge1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIHZhciB0aW1lb3V0ID0gcnVuVGltZW91dChjbGVhblVwTmV4dFRpY2spO1xuICAgIGRyYWluaW5nID0gdHJ1ZTtcblxuICAgIHZhciBsZW4gPSBxdWV1ZS5sZW5ndGg7XG4gICAgd2hpbGUobGVuKSB7XG4gICAgICAgIGN1cnJlbnRRdWV1ZSA9IHF1ZXVlO1xuICAgICAgICBxdWV1ZSA9IFtdO1xuICAgICAgICB3aGlsZSAoKytxdWV1ZUluZGV4IDwgbGVuKSB7XG4gICAgICAgICAgICBpZiAoY3VycmVudFF1ZXVlKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudFF1ZXVlW3F1ZXVlSW5kZXhdLnJ1bigpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHF1ZXVlSW5kZXggPSAtMTtcbiAgICAgICAgbGVuID0gcXVldWUubGVuZ3RoO1xuICAgIH1cbiAgICBjdXJyZW50UXVldWUgPSBudWxsO1xuICAgIGRyYWluaW5nID0gZmFsc2U7XG4gICAgcnVuQ2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xufVxuXG5wcm9jZXNzLm5leHRUaWNrID0gZnVuY3Rpb24gKGZ1bikge1xuICAgIHZhciBhcmdzID0gbmV3IEFycmF5KGFyZ3VtZW50cy5sZW5ndGggLSAxKTtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuICAgICAgICB9XG4gICAgfVxuICAgIHF1ZXVlLnB1c2gobmV3IEl0ZW0oZnVuLCBhcmdzKSk7XG4gICAgaWYgKHF1ZXVlLmxlbmd0aCA9PT0gMSAmJiAhZHJhaW5pbmcpIHtcbiAgICAgICAgcnVuVGltZW91dChkcmFpblF1ZXVlKTtcbiAgICB9XG59O1xuXG4vLyB2OCBsaWtlcyBwcmVkaWN0aWJsZSBvYmplY3RzXG5mdW5jdGlvbiBJdGVtKGZ1biwgYXJyYXkpIHtcbiAgICB0aGlzLmZ1biA9IGZ1bjtcbiAgICB0aGlzLmFycmF5ID0gYXJyYXk7XG59XG5JdGVtLnByb3RvdHlwZS5ydW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdW4uYXBwbHkobnVsbCwgdGhpcy5hcnJheSk7XG59O1xucHJvY2Vzcy50aXRsZSA9ICdicm93c2VyJztcbnByb2Nlc3MuYnJvd3NlciA9IHRydWU7XG5wcm9jZXNzLmVudiA9IHt9O1xucHJvY2Vzcy5hcmd2ID0gW107XG5wcm9jZXNzLnZlcnNpb24gPSAnJzsgLy8gZW1wdHkgc3RyaW5nIHRvIGF2b2lkIHJlZ2V4cCBpc3N1ZXNcbnByb2Nlc3MudmVyc2lvbnMgPSB7fTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn07XG5cbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xucHJvY2Vzcy51bWFzayA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gMDsgfTtcbiIsIlwidXNlIHN0cmljdFwiO1xudmFyIF9fZXh0ZW5kcyA9ICh0aGlzICYmIHRoaXMuX19leHRlbmRzKSB8fCBmdW5jdGlvbiAoZCwgYikge1xuICAgIGZvciAodmFyIHAgaW4gYikgaWYgKGIuaGFzT3duUHJvcGVydHkocCkpIGRbcF0gPSBiW3BdO1xuICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gZDsgfVxuICAgIGQucHJvdG90eXBlID0gYiA9PT0gbnVsbCA/IE9iamVjdC5jcmVhdGUoYikgOiAoX18ucHJvdG90eXBlID0gYi5wcm90b3R5cGUsIG5ldyBfXygpKTtcbn07XG52YXIgTk8gPSB7fTtcbmZ1bmN0aW9uIG5vb3AoKSB7IH1cbmZ1bmN0aW9uIGNvcHkoYSkge1xuICAgIHZhciBsID0gYS5sZW5ndGg7XG4gICAgdmFyIGIgPSBBcnJheShsKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGw7ICsraSkge1xuICAgICAgICBiW2ldID0gYVtpXTtcbiAgICB9XG4gICAgcmV0dXJuIGI7XG59XG5leHBvcnRzLk5PX0lMID0ge1xuICAgIF9uOiBub29wLFxuICAgIF9lOiBub29wLFxuICAgIF9jOiBub29wLFxufTtcbi8vIG11dGF0ZXMgdGhlIGlucHV0XG5mdW5jdGlvbiBpbnRlcm5hbGl6ZVByb2R1Y2VyKHByb2R1Y2VyKSB7XG4gICAgcHJvZHVjZXIuX3N0YXJ0ID1cbiAgICAgICAgZnVuY3Rpb24gX3N0YXJ0KGlsKSB7XG4gICAgICAgICAgICBpbC5uZXh0ID0gaWwuX247XG4gICAgICAgICAgICBpbC5lcnJvciA9IGlsLl9lO1xuICAgICAgICAgICAgaWwuY29tcGxldGUgPSBpbC5fYztcbiAgICAgICAgICAgIHRoaXMuc3RhcnQoaWwpO1xuICAgICAgICB9O1xuICAgIHByb2R1Y2VyLl9zdG9wID0gcHJvZHVjZXIuc3RvcDtcbn1cbmZ1bmN0aW9uIGNvbXBvc2UyKGYxLCBmMikge1xuICAgIHJldHVybiBmdW5jdGlvbiBjb21wb3NlZEZuKGFyZykge1xuICAgICAgICByZXR1cm4gZjEoZjIoYXJnKSk7XG4gICAgfTtcbn1cbmZ1bmN0aW9uIGFuZChmMSwgZjIpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gYW5kRm4odCkge1xuICAgICAgICByZXR1cm4gZjEodCkgJiYgZjIodCk7XG4gICAgfTtcbn1cbnZhciBNZXJnZVByb2R1Y2VyID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBNZXJnZVByb2R1Y2VyKGluc0Fycikge1xuICAgICAgICB0aGlzLnR5cGUgPSAnbWVyZ2UnO1xuICAgICAgICB0aGlzLmluc0FyciA9IGluc0FycjtcbiAgICAgICAgdGhpcy5vdXQgPSBOTztcbiAgICAgICAgdGhpcy5hYyA9IDA7XG4gICAgfVxuICAgIE1lcmdlUHJvZHVjZXIucHJvdG90eXBlLl9zdGFydCA9IGZ1bmN0aW9uIChvdXQpIHtcbiAgICAgICAgdGhpcy5vdXQgPSBvdXQ7XG4gICAgICAgIHZhciBzID0gdGhpcy5pbnNBcnI7XG4gICAgICAgIHZhciBMID0gcy5sZW5ndGg7XG4gICAgICAgIHRoaXMuYWMgPSBMO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IEw7IGkrKykge1xuICAgICAgICAgICAgc1tpXS5fYWRkKHRoaXMpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICBNZXJnZVByb2R1Y2VyLnByb3RvdHlwZS5fc3RvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHMgPSB0aGlzLmluc0FycjtcbiAgICAgICAgdmFyIEwgPSBzLmxlbmd0aDtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBMOyBpKyspIHtcbiAgICAgICAgICAgIHNbaV0uX3JlbW92ZSh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm91dCA9IE5PO1xuICAgIH07XG4gICAgTWVyZ2VQcm9kdWNlci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAodSA9PT0gTk8pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHUuX24odCk7XG4gICAgfTtcbiAgICBNZXJnZVByb2R1Y2VyLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKHUgPT09IE5PKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9lKGVycik7XG4gICAgfTtcbiAgICBNZXJnZVByb2R1Y2VyLnByb3RvdHlwZS5fYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKC0tdGhpcy5hYyA8PSAwKSB7XG4gICAgICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICAgICAgaWYgKHUgPT09IE5PKVxuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIHUuX2MoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIE1lcmdlUHJvZHVjZXI7XG59KCkpO1xuZXhwb3J0cy5NZXJnZVByb2R1Y2VyID0gTWVyZ2VQcm9kdWNlcjtcbnZhciBDb21iaW5lTGlzdGVuZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIENvbWJpbmVMaXN0ZW5lcihpLCBvdXQsIHApIHtcbiAgICAgICAgdGhpcy5pID0gaTtcbiAgICAgICAgdGhpcy5vdXQgPSBvdXQ7XG4gICAgICAgIHRoaXMucCA9IHA7XG4gICAgICAgIHAuaWxzLnB1c2godGhpcyk7XG4gICAgfVxuICAgIENvbWJpbmVMaXN0ZW5lci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodCkge1xuICAgICAgICB2YXIgcCA9IHRoaXMucCwgb3V0ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghb3V0KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBpZiAocC51cCh0LCB0aGlzLmkpKSB7XG4gICAgICAgICAgICBvdXQuX24ocC52YWxzKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgQ29tYmluZUxpc3RlbmVyLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgdmFyIG91dCA9IHRoaXMub3V0O1xuICAgICAgICBpZiAoIW91dClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgb3V0Ll9lKGVycik7XG4gICAgfTtcbiAgICBDb21iaW5lTGlzdGVuZXIucHJvdG90eXBlLl9jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcCA9IHRoaXMucDtcbiAgICAgICAgaWYgKCFwLm91dClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgaWYgKC0tcC5OYyA9PT0gMCkge1xuICAgICAgICAgICAgcC5vdXQuX2MoKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIENvbWJpbmVMaXN0ZW5lcjtcbn0oKSk7XG5leHBvcnRzLkNvbWJpbmVMaXN0ZW5lciA9IENvbWJpbmVMaXN0ZW5lcjtcbnZhciBDb21iaW5lUHJvZHVjZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIENvbWJpbmVQcm9kdWNlcihpbnNBcnIpIHtcbiAgICAgICAgdGhpcy50eXBlID0gJ2NvbWJpbmUnO1xuICAgICAgICB0aGlzLmluc0FyciA9IGluc0FycjtcbiAgICAgICAgdGhpcy5vdXQgPSBOTztcbiAgICAgICAgdGhpcy5pbHMgPSBbXTtcbiAgICAgICAgdGhpcy5OYyA9IHRoaXMuTm4gPSAwO1xuICAgICAgICB0aGlzLnZhbHMgPSBbXTtcbiAgICB9XG4gICAgQ29tYmluZVByb2R1Y2VyLnByb3RvdHlwZS51cCA9IGZ1bmN0aW9uICh0LCBpKSB7XG4gICAgICAgIHZhciB2ID0gdGhpcy52YWxzW2ldO1xuICAgICAgICB2YXIgTm4gPSAhdGhpcy5ObiA/IDAgOiB2ID09PSBOTyA/IC0tdGhpcy5ObiA6IHRoaXMuTm47XG4gICAgICAgIHRoaXMudmFsc1tpXSA9IHQ7XG4gICAgICAgIHJldHVybiBObiA9PT0gMDtcbiAgICB9O1xuICAgIENvbWJpbmVQcm9kdWNlci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB0aGlzLm91dCA9IG91dDtcbiAgICAgICAgdmFyIHMgPSB0aGlzLmluc0FycjtcbiAgICAgICAgdmFyIG4gPSB0aGlzLk5jID0gdGhpcy5ObiA9IHMubGVuZ3RoO1xuICAgICAgICB2YXIgdmFscyA9IHRoaXMudmFscyA9IG5ldyBBcnJheShuKTtcbiAgICAgICAgaWYgKG4gPT09IDApIHtcbiAgICAgICAgICAgIG91dC5fbihbXSk7XG4gICAgICAgICAgICBvdXQuX2MoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFsc1tpXSA9IE5PO1xuICAgICAgICAgICAgICAgIHNbaV0uX2FkZChuZXcgQ29tYmluZUxpc3RlbmVyKGksIG91dCwgdGhpcykpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICBDb21iaW5lUHJvZHVjZXIucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgcyA9IHRoaXMuaW5zQXJyO1xuICAgICAgICB2YXIgbiA9IHMubGVuZ3RoO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG47IGkrKykge1xuICAgICAgICAgICAgc1tpXS5fcmVtb3ZlKHRoaXMuaWxzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLm91dCA9IE5PO1xuICAgICAgICB0aGlzLmlscyA9IFtdO1xuICAgICAgICB0aGlzLnZhbHMgPSBbXTtcbiAgICB9O1xuICAgIHJldHVybiBDb21iaW5lUHJvZHVjZXI7XG59KCkpO1xuZXhwb3J0cy5Db21iaW5lUHJvZHVjZXIgPSBDb21iaW5lUHJvZHVjZXI7XG52YXIgRnJvbUFycmF5UHJvZHVjZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEZyb21BcnJheVByb2R1Y2VyKGEpIHtcbiAgICAgICAgdGhpcy50eXBlID0gJ2Zyb21BcnJheSc7XG4gICAgICAgIHRoaXMuYSA9IGE7XG4gICAgfVxuICAgIEZyb21BcnJheVByb2R1Y2VyLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAob3V0KSB7XG4gICAgICAgIHZhciBhID0gdGhpcy5hO1xuICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGEubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICBvdXQuX24oYVtpXSk7XG4gICAgICAgIH1cbiAgICAgICAgb3V0Ll9jKCk7XG4gICAgfTtcbiAgICBGcm9tQXJyYXlQcm9kdWNlci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgfTtcbiAgICByZXR1cm4gRnJvbUFycmF5UHJvZHVjZXI7XG59KCkpO1xuZXhwb3J0cy5Gcm9tQXJyYXlQcm9kdWNlciA9IEZyb21BcnJheVByb2R1Y2VyO1xudmFyIEZyb21Qcm9taXNlUHJvZHVjZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEZyb21Qcm9taXNlUHJvZHVjZXIocCkge1xuICAgICAgICB0aGlzLnR5cGUgPSAnZnJvbVByb21pc2UnO1xuICAgICAgICB0aGlzLm9uID0gZmFsc2U7XG4gICAgICAgIHRoaXMucCA9IHA7XG4gICAgfVxuICAgIEZyb21Qcm9taXNlUHJvZHVjZXIucHJvdG90eXBlLl9zdGFydCA9IGZ1bmN0aW9uIChvdXQpIHtcbiAgICAgICAgdmFyIHByb2QgPSB0aGlzO1xuICAgICAgICB0aGlzLm9uID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5wLnRoZW4oZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICAgIGlmIChwcm9kLm9uKSB7XG4gICAgICAgICAgICAgICAgb3V0Ll9uKHYpO1xuICAgICAgICAgICAgICAgIG91dC5fYygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9LCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgb3V0Ll9lKGUpO1xuICAgICAgICB9KS50aGVuKG51bGwsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyB0aHJvdyBlcnI7IH0pO1xuICAgICAgICB9KTtcbiAgICB9O1xuICAgIEZyb21Qcm9taXNlUHJvZHVjZXIucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLm9uID0gZmFsc2U7XG4gICAgfTtcbiAgICByZXR1cm4gRnJvbVByb21pc2VQcm9kdWNlcjtcbn0oKSk7XG5leHBvcnRzLkZyb21Qcm9taXNlUHJvZHVjZXIgPSBGcm9tUHJvbWlzZVByb2R1Y2VyO1xudmFyIFBlcmlvZGljUHJvZHVjZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFBlcmlvZGljUHJvZHVjZXIocGVyaW9kKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICdwZXJpb2RpYyc7XG4gICAgICAgIHRoaXMucGVyaW9kID0gcGVyaW9kO1xuICAgICAgICB0aGlzLmludGVydmFsSUQgPSAtMTtcbiAgICAgICAgdGhpcy5pID0gMDtcbiAgICB9XG4gICAgUGVyaW9kaWNQcm9kdWNlci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKHN0cmVhbSkge1xuICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgIGZ1bmN0aW9uIGludGVydmFsSGFuZGxlcigpIHsgc3RyZWFtLl9uKHNlbGYuaSsrKTsgfVxuICAgICAgICB0aGlzLmludGVydmFsSUQgPSBzZXRJbnRlcnZhbChpbnRlcnZhbEhhbmRsZXIsIHRoaXMucGVyaW9kKTtcbiAgICB9O1xuICAgIFBlcmlvZGljUHJvZHVjZXIucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5pbnRlcnZhbElEICE9PSAtMSlcbiAgICAgICAgICAgIGNsZWFySW50ZXJ2YWwodGhpcy5pbnRlcnZhbElEKTtcbiAgICAgICAgdGhpcy5pbnRlcnZhbElEID0gLTE7XG4gICAgICAgIHRoaXMuaSA9IDA7XG4gICAgfTtcbiAgICByZXR1cm4gUGVyaW9kaWNQcm9kdWNlcjtcbn0oKSk7XG5leHBvcnRzLlBlcmlvZGljUHJvZHVjZXIgPSBQZXJpb2RpY1Byb2R1Y2VyO1xudmFyIERlYnVnT3BlcmF0b3IgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIERlYnVnT3BlcmF0b3IoYXJnLCBpbnMpIHtcbiAgICAgICAgdGhpcy50eXBlID0gJ2RlYnVnJztcbiAgICAgICAgdGhpcy5pbnMgPSBpbnM7XG4gICAgICAgIHRoaXMub3V0ID0gTk87XG4gICAgICAgIHRoaXMucyA9IG5vb3A7XG4gICAgICAgIHRoaXMubCA9ICcnO1xuICAgICAgICBpZiAodHlwZW9mIGFyZyA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgIHRoaXMubCA9IGFyZztcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh0eXBlb2YgYXJnID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLnMgPSBhcmc7XG4gICAgICAgIH1cbiAgICB9XG4gICAgRGVidWdPcGVyYXRvci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB0aGlzLm91dCA9IG91dDtcbiAgICAgICAgdGhpcy5pbnMuX2FkZCh0aGlzKTtcbiAgICB9O1xuICAgIERlYnVnT3BlcmF0b3IucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmlucy5fcmVtb3ZlKHRoaXMpO1xuICAgICAgICB0aGlzLm91dCA9IE5PO1xuICAgIH07XG4gICAgRGVidWdPcGVyYXRvci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAodSA9PT0gTk8pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHZhciBzID0gdGhpcy5zLCBsID0gdGhpcy5sO1xuICAgICAgICBpZiAocyAhPT0gbm9vcCkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBzKHQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICB1Ll9lKGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGwpIHtcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGwgKyAnOicsIHQpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS5sb2codCk7XG4gICAgICAgIH1cbiAgICAgICAgdS5fbih0KTtcbiAgICB9O1xuICAgIERlYnVnT3BlcmF0b3IucHJvdG90eXBlLl9lID0gZnVuY3Rpb24gKGVycikge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAodSA9PT0gTk8pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHUuX2UoZXJyKTtcbiAgICB9O1xuICAgIERlYnVnT3BlcmF0b3IucHJvdG90eXBlLl9jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAodSA9PT0gTk8pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHUuX2MoKTtcbiAgICB9O1xuICAgIHJldHVybiBEZWJ1Z09wZXJhdG9yO1xufSgpKTtcbmV4cG9ydHMuRGVidWdPcGVyYXRvciA9IERlYnVnT3BlcmF0b3I7XG52YXIgRHJvcE9wZXJhdG9yID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBEcm9wT3BlcmF0b3IobWF4LCBpbnMpIHtcbiAgICAgICAgdGhpcy50eXBlID0gJ2Ryb3AnO1xuICAgICAgICB0aGlzLmlucyA9IGlucztcbiAgICAgICAgdGhpcy5vdXQgPSBOTztcbiAgICAgICAgdGhpcy5tYXggPSBtYXg7XG4gICAgICAgIHRoaXMuZHJvcHBlZCA9IDA7XG4gICAgfVxuICAgIERyb3BPcGVyYXRvci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB0aGlzLm91dCA9IG91dDtcbiAgICAgICAgdGhpcy5kcm9wcGVkID0gMDtcbiAgICAgICAgdGhpcy5pbnMuX2FkZCh0aGlzKTtcbiAgICB9O1xuICAgIERyb3BPcGVyYXRvci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuaW5zLl9yZW1vdmUodGhpcyk7XG4gICAgICAgIHRoaXMub3V0ID0gTk87XG4gICAgfTtcbiAgICBEcm9wT3BlcmF0b3IucHJvdG90eXBlLl9uID0gZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKHUgPT09IE5PKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICBpZiAodGhpcy5kcm9wcGVkKysgPj0gdGhpcy5tYXgpXG4gICAgICAgICAgICB1Ll9uKHQpO1xuICAgIH07XG4gICAgRHJvcE9wZXJhdG9yLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKHUgPT09IE5PKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9lKGVycik7XG4gICAgfTtcbiAgICBEcm9wT3BlcmF0b3IucHJvdG90eXBlLl9jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAodSA9PT0gTk8pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHUuX2MoKTtcbiAgICB9O1xuICAgIHJldHVybiBEcm9wT3BlcmF0b3I7XG59KCkpO1xuZXhwb3J0cy5Ecm9wT3BlcmF0b3IgPSBEcm9wT3BlcmF0b3I7XG52YXIgT3RoZXJJTCA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gT3RoZXJJTChvdXQsIG9wKSB7XG4gICAgICAgIHRoaXMub3V0ID0gb3V0O1xuICAgICAgICB0aGlzLm9wID0gb3A7XG4gICAgfVxuICAgIE90aGVySUwucHJvdG90eXBlLl9uID0gZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgdGhpcy5vcC5lbmQoKTtcbiAgICB9O1xuICAgIE90aGVySUwucHJvdG90eXBlLl9lID0gZnVuY3Rpb24gKGVycikge1xuICAgICAgICB0aGlzLm91dC5fZShlcnIpO1xuICAgIH07XG4gICAgT3RoZXJJTC5wcm90b3R5cGUuX2MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMub3AuZW5kKCk7XG4gICAgfTtcbiAgICByZXR1cm4gT3RoZXJJTDtcbn0oKSk7XG52YXIgRW5kV2hlbk9wZXJhdG9yID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBFbmRXaGVuT3BlcmF0b3IobywgaW5zKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICdlbmRXaGVuJztcbiAgICAgICAgdGhpcy5pbnMgPSBpbnM7XG4gICAgICAgIHRoaXMub3V0ID0gTk87XG4gICAgICAgIHRoaXMubyA9IG87XG4gICAgICAgIHRoaXMub2lsID0gZXhwb3J0cy5OT19JTDtcbiAgICB9XG4gICAgRW5kV2hlbk9wZXJhdG9yLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAob3V0KSB7XG4gICAgICAgIHRoaXMub3V0ID0gb3V0O1xuICAgICAgICB0aGlzLm8uX2FkZCh0aGlzLm9pbCA9IG5ldyBPdGhlcklMKG91dCwgdGhpcykpO1xuICAgICAgICB0aGlzLmlucy5fYWRkKHRoaXMpO1xuICAgIH07XG4gICAgRW5kV2hlbk9wZXJhdG9yLnByb3RvdHlwZS5fc3RvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5pbnMuX3JlbW92ZSh0aGlzKTtcbiAgICAgICAgdGhpcy5vLl9yZW1vdmUodGhpcy5vaWwpO1xuICAgICAgICB0aGlzLm91dCA9IE5PO1xuICAgICAgICB0aGlzLm9pbCA9IGV4cG9ydHMuTk9fSUw7XG4gICAgfTtcbiAgICBFbmRXaGVuT3BlcmF0b3IucHJvdG90eXBlLmVuZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKHUgPT09IE5PKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9jKCk7XG4gICAgfTtcbiAgICBFbmRXaGVuT3BlcmF0b3IucHJvdG90eXBlLl9uID0gZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKHUgPT09IE5PKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9uKHQpO1xuICAgIH07XG4gICAgRW5kV2hlbk9wZXJhdG9yLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKHUgPT09IE5PKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9lKGVycik7XG4gICAgfTtcbiAgICBFbmRXaGVuT3BlcmF0b3IucHJvdG90eXBlLl9jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmVuZCgpO1xuICAgIH07XG4gICAgcmV0dXJuIEVuZFdoZW5PcGVyYXRvcjtcbn0oKSk7XG5leHBvcnRzLkVuZFdoZW5PcGVyYXRvciA9IEVuZFdoZW5PcGVyYXRvcjtcbnZhciBGaWx0ZXJPcGVyYXRvciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRmlsdGVyT3BlcmF0b3IocGFzc2VzLCBpbnMpIHtcbiAgICAgICAgdGhpcy50eXBlID0gJ2ZpbHRlcic7XG4gICAgICAgIHRoaXMuaW5zID0gaW5zO1xuICAgICAgICB0aGlzLm91dCA9IE5PO1xuICAgICAgICB0aGlzLnBhc3NlcyA9IHBhc3NlcztcbiAgICB9XG4gICAgRmlsdGVyT3BlcmF0b3IucHJvdG90eXBlLl9zdGFydCA9IGZ1bmN0aW9uIChvdXQpIHtcbiAgICAgICAgdGhpcy5vdXQgPSBvdXQ7XG4gICAgICAgIHRoaXMuaW5zLl9hZGQodGhpcyk7XG4gICAgfTtcbiAgICBGaWx0ZXJPcGVyYXRvci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuaW5zLl9yZW1vdmUodGhpcyk7XG4gICAgICAgIHRoaXMub3V0ID0gTk87XG4gICAgfTtcbiAgICBGaWx0ZXJPcGVyYXRvci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAodSA9PT0gTk8pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYXNzZXModCkpXG4gICAgICAgICAgICAgICAgdS5fbih0KTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdS5fZShlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgRmlsdGVyT3BlcmF0b3IucHJvdG90eXBlLl9lID0gZnVuY3Rpb24gKGVycikge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAodSA9PT0gTk8pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHUuX2UoZXJyKTtcbiAgICB9O1xuICAgIEZpbHRlck9wZXJhdG9yLnByb3RvdHlwZS5fYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKHUgPT09IE5PKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9jKCk7XG4gICAgfTtcbiAgICByZXR1cm4gRmlsdGVyT3BlcmF0b3I7XG59KCkpO1xuZXhwb3J0cy5GaWx0ZXJPcGVyYXRvciA9IEZpbHRlck9wZXJhdG9yO1xudmFyIEZsYXR0ZW5MaXN0ZW5lciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gRmxhdHRlbkxpc3RlbmVyKG91dCwgb3ApIHtcbiAgICAgICAgdGhpcy5vdXQgPSBvdXQ7XG4gICAgICAgIHRoaXMub3AgPSBvcDtcbiAgICB9XG4gICAgRmxhdHRlbkxpc3RlbmVyLnByb3RvdHlwZS5fbiA9IGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHRoaXMub3V0Ll9uKHQpO1xuICAgIH07XG4gICAgRmxhdHRlbkxpc3RlbmVyLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgdGhpcy5vdXQuX2UoZXJyKTtcbiAgICB9O1xuICAgIEZsYXR0ZW5MaXN0ZW5lci5wcm90b3R5cGUuX2MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMub3AuaW5uZXIgPSBOTztcbiAgICAgICAgdGhpcy5vcC5sZXNzKCk7XG4gICAgfTtcbiAgICByZXR1cm4gRmxhdHRlbkxpc3RlbmVyO1xufSgpKTtcbnZhciBGbGF0dGVuT3BlcmF0b3IgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIEZsYXR0ZW5PcGVyYXRvcihpbnMpIHtcbiAgICAgICAgdGhpcy50eXBlID0gJ2ZsYXR0ZW4nO1xuICAgICAgICB0aGlzLmlucyA9IGlucztcbiAgICAgICAgdGhpcy5vdXQgPSBOTztcbiAgICAgICAgdGhpcy5vcGVuID0gdHJ1ZTtcbiAgICAgICAgdGhpcy5pbm5lciA9IE5PO1xuICAgICAgICB0aGlzLmlsID0gZXhwb3J0cy5OT19JTDtcbiAgICB9XG4gICAgRmxhdHRlbk9wZXJhdG9yLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAob3V0KSB7XG4gICAgICAgIHRoaXMub3V0ID0gb3V0O1xuICAgICAgICB0aGlzLm9wZW4gPSB0cnVlO1xuICAgICAgICB0aGlzLmlubmVyID0gTk87XG4gICAgICAgIHRoaXMuaWwgPSBleHBvcnRzLk5PX0lMO1xuICAgICAgICB0aGlzLmlucy5fYWRkKHRoaXMpO1xuICAgIH07XG4gICAgRmxhdHRlbk9wZXJhdG9yLnByb3RvdHlwZS5fc3RvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5pbnMuX3JlbW92ZSh0aGlzKTtcbiAgICAgICAgaWYgKHRoaXMuaW5uZXIgIT09IE5PKVxuICAgICAgICAgICAgdGhpcy5pbm5lci5fcmVtb3ZlKHRoaXMuaWwpO1xuICAgICAgICB0aGlzLm91dCA9IE5PO1xuICAgICAgICB0aGlzLm9wZW4gPSB0cnVlO1xuICAgICAgICB0aGlzLmlubmVyID0gTk87XG4gICAgICAgIHRoaXMuaWwgPSBleHBvcnRzLk5PX0lMO1xuICAgIH07XG4gICAgRmxhdHRlbk9wZXJhdG9yLnByb3RvdHlwZS5sZXNzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAodSA9PT0gTk8pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIGlmICghdGhpcy5vcGVuICYmIHRoaXMuaW5uZXIgPT09IE5PKVxuICAgICAgICAgICAgdS5fYygpO1xuICAgIH07XG4gICAgRmxhdHRlbk9wZXJhdG9yLnByb3RvdHlwZS5fbiA9IGZ1bmN0aW9uIChzKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICh1ID09PSBOTylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdmFyIF9hID0gdGhpcywgaW5uZXIgPSBfYS5pbm5lciwgaWwgPSBfYS5pbDtcbiAgICAgICAgaWYgKHMgPT09IGlubmVyICYmIHMuX3Byb2QgIT09IE5PKVxuICAgICAgICAgICAgcy5fc3RvcE5vdygpO1xuICAgICAgICBpZiAoaW5uZXIgIT09IE5PICYmIGlsICE9PSBleHBvcnRzLk5PX0lMKVxuICAgICAgICAgICAgaW5uZXIuX3JlbW92ZShpbCk7XG4gICAgICAgICh0aGlzLmlubmVyID0gcykuX2FkZCh0aGlzLmlsID0gbmV3IEZsYXR0ZW5MaXN0ZW5lcih1LCB0aGlzKSk7XG4gICAgfTtcbiAgICBGbGF0dGVuT3BlcmF0b3IucHJvdG90eXBlLl9lID0gZnVuY3Rpb24gKGVycikge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAodSA9PT0gTk8pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHUuX2UoZXJyKTtcbiAgICB9O1xuICAgIEZsYXR0ZW5PcGVyYXRvci5wcm90b3R5cGUuX2MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMub3BlbiA9IGZhbHNlO1xuICAgICAgICB0aGlzLmxlc3MoKTtcbiAgICB9O1xuICAgIHJldHVybiBGbGF0dGVuT3BlcmF0b3I7XG59KCkpO1xuZXhwb3J0cy5GbGF0dGVuT3BlcmF0b3IgPSBGbGF0dGVuT3BlcmF0b3I7XG52YXIgRm9sZE9wZXJhdG9yID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBGb2xkT3BlcmF0b3IoZiwgc2VlZCwgaW5zKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICdmb2xkJztcbiAgICAgICAgdGhpcy5pbnMgPSBpbnM7XG4gICAgICAgIHRoaXMub3V0ID0gTk87XG4gICAgICAgIHRoaXMuZiA9IGY7XG4gICAgICAgIHRoaXMuYWNjID0gdGhpcy5zZWVkID0gc2VlZDtcbiAgICB9XG4gICAgRm9sZE9wZXJhdG9yLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAob3V0KSB7XG4gICAgICAgIHRoaXMub3V0ID0gb3V0O1xuICAgICAgICB0aGlzLmFjYyA9IHRoaXMuc2VlZDtcbiAgICAgICAgb3V0Ll9uKHRoaXMuYWNjKTtcbiAgICAgICAgdGhpcy5pbnMuX2FkZCh0aGlzKTtcbiAgICB9O1xuICAgIEZvbGRPcGVyYXRvci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuaW5zLl9yZW1vdmUodGhpcyk7XG4gICAgICAgIHRoaXMub3V0ID0gTk87XG4gICAgICAgIHRoaXMuYWNjID0gdGhpcy5zZWVkO1xuICAgIH07XG4gICAgRm9sZE9wZXJhdG9yLnByb3RvdHlwZS5fbiA9IGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICh1ID09PSBOTylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHUuX24odGhpcy5hY2MgPSB0aGlzLmYodGhpcy5hY2MsIHQpKTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdS5fZShlKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgRm9sZE9wZXJhdG9yLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKHUgPT09IE5PKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9lKGVycik7XG4gICAgfTtcbiAgICBGb2xkT3BlcmF0b3IucHJvdG90eXBlLl9jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAodSA9PT0gTk8pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHUuX2MoKTtcbiAgICB9O1xuICAgIHJldHVybiBGb2xkT3BlcmF0b3I7XG59KCkpO1xuZXhwb3J0cy5Gb2xkT3BlcmF0b3IgPSBGb2xkT3BlcmF0b3I7XG52YXIgTGFzdE9wZXJhdG9yID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBMYXN0T3BlcmF0b3IoaW5zKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICdsYXN0JztcbiAgICAgICAgdGhpcy5pbnMgPSBpbnM7XG4gICAgICAgIHRoaXMub3V0ID0gTk87XG4gICAgICAgIHRoaXMuaGFzID0gZmFsc2U7XG4gICAgICAgIHRoaXMudmFsID0gTk87XG4gICAgfVxuICAgIExhc3RPcGVyYXRvci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB0aGlzLm91dCA9IG91dDtcbiAgICAgICAgdGhpcy5oYXMgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5pbnMuX2FkZCh0aGlzKTtcbiAgICB9O1xuICAgIExhc3RPcGVyYXRvci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuaW5zLl9yZW1vdmUodGhpcyk7XG4gICAgICAgIHRoaXMub3V0ID0gTk87XG4gICAgICAgIHRoaXMudmFsID0gTk87XG4gICAgfTtcbiAgICBMYXN0T3BlcmF0b3IucHJvdG90eXBlLl9uID0gZnVuY3Rpb24gKHQpIHtcbiAgICAgICAgdGhpcy5oYXMgPSB0cnVlO1xuICAgICAgICB0aGlzLnZhbCA9IHQ7XG4gICAgfTtcbiAgICBMYXN0T3BlcmF0b3IucHJvdG90eXBlLl9lID0gZnVuY3Rpb24gKGVycikge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAodSA9PT0gTk8pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHUuX2UoZXJyKTtcbiAgICB9O1xuICAgIExhc3RPcGVyYXRvci5wcm90b3R5cGUuX2MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICh1ID09PSBOTylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgaWYgKHRoaXMuaGFzKSB7XG4gICAgICAgICAgICB1Ll9uKHRoaXMudmFsKTtcbiAgICAgICAgICAgIHUuX2MoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHUuX2UoJ1RPRE8gc2hvdyBwcm9wZXIgZXJyb3InKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgcmV0dXJuIExhc3RPcGVyYXRvcjtcbn0oKSk7XG5leHBvcnRzLkxhc3RPcGVyYXRvciA9IExhc3RPcGVyYXRvcjtcbnZhciBNYXBGbGF0dGVuSW5uZXIgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIE1hcEZsYXR0ZW5Jbm5lcihvdXQsIG9wKSB7XG4gICAgICAgIHRoaXMub3V0ID0gb3V0O1xuICAgICAgICB0aGlzLm9wID0gb3A7XG4gICAgfVxuICAgIE1hcEZsYXR0ZW5Jbm5lci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAocikge1xuICAgICAgICB0aGlzLm91dC5fbihyKTtcbiAgICB9O1xuICAgIE1hcEZsYXR0ZW5Jbm5lci5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHRoaXMub3V0Ll9lKGVycik7XG4gICAgfTtcbiAgICBNYXBGbGF0dGVuSW5uZXIucHJvdG90eXBlLl9jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLm9wLmlubmVyID0gTk87XG4gICAgICAgIHRoaXMub3AubGVzcygpO1xuICAgIH07XG4gICAgcmV0dXJuIE1hcEZsYXR0ZW5Jbm5lcjtcbn0oKSk7XG52YXIgTWFwRmxhdHRlbk9wZXJhdG9yID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBNYXBGbGF0dGVuT3BlcmF0b3IobWFwT3ApIHtcbiAgICAgICAgdGhpcy50eXBlID0gbWFwT3AudHlwZSArIFwiK2ZsYXR0ZW5cIjtcbiAgICAgICAgdGhpcy5pbnMgPSBtYXBPcC5pbnM7XG4gICAgICAgIHRoaXMub3V0ID0gTk87XG4gICAgICAgIHRoaXMubWFwT3AgPSBtYXBPcDtcbiAgICAgICAgdGhpcy5pbm5lciA9IE5PO1xuICAgICAgICB0aGlzLmlsID0gZXhwb3J0cy5OT19JTDtcbiAgICAgICAgdGhpcy5vcGVuID0gdHJ1ZTtcbiAgICB9XG4gICAgTWFwRmxhdHRlbk9wZXJhdG9yLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAob3V0KSB7XG4gICAgICAgIHRoaXMub3V0ID0gb3V0O1xuICAgICAgICB0aGlzLmlubmVyID0gTk87XG4gICAgICAgIHRoaXMuaWwgPSBleHBvcnRzLk5PX0lMO1xuICAgICAgICB0aGlzLm9wZW4gPSB0cnVlO1xuICAgICAgICB0aGlzLm1hcE9wLmlucy5fYWRkKHRoaXMpO1xuICAgIH07XG4gICAgTWFwRmxhdHRlbk9wZXJhdG9yLnByb3RvdHlwZS5fc3RvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5tYXBPcC5pbnMuX3JlbW92ZSh0aGlzKTtcbiAgICAgICAgaWYgKHRoaXMuaW5uZXIgIT09IE5PKVxuICAgICAgICAgICAgdGhpcy5pbm5lci5fcmVtb3ZlKHRoaXMuaWwpO1xuICAgICAgICB0aGlzLm91dCA9IE5PO1xuICAgICAgICB0aGlzLmlubmVyID0gTk87XG4gICAgICAgIHRoaXMuaWwgPSBleHBvcnRzLk5PX0lMO1xuICAgIH07XG4gICAgTWFwRmxhdHRlbk9wZXJhdG9yLnByb3RvdHlwZS5sZXNzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAoIXRoaXMub3BlbiAmJiB0aGlzLmlubmVyID09PSBOTykge1xuICAgICAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgICAgIGlmICh1ID09PSBOTylcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB1Ll9jKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIE1hcEZsYXR0ZW5PcGVyYXRvci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodikge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAodSA9PT0gTk8pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHZhciBfYSA9IHRoaXMsIGlubmVyID0gX2EuaW5uZXIsIGlsID0gX2EuaWw7XG4gICAgICAgIHZhciBzO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgcyA9IHRoaXMubWFwT3AucHJvamVjdCh2KTtcbiAgICAgICAgfVxuICAgICAgICBjYXRjaCAoZSkge1xuICAgICAgICAgICAgdS5fZShlKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBpZiAocyA9PT0gaW5uZXIgJiYgcy5fcHJvZCAhPT0gTk8pXG4gICAgICAgICAgICBzLl9zdG9wTm93KCk7XG4gICAgICAgIGlmIChpbm5lciAhPT0gTk8gJiYgaWwgIT09IGV4cG9ydHMuTk9fSUwpXG4gICAgICAgICAgICBpbm5lci5fcmVtb3ZlKGlsKTtcbiAgICAgICAgKHRoaXMuaW5uZXIgPSBzKS5fYWRkKHRoaXMuaWwgPSBuZXcgTWFwRmxhdHRlbklubmVyKHUsIHRoaXMpKTtcbiAgICB9O1xuICAgIE1hcEZsYXR0ZW5PcGVyYXRvci5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICh1ID09PSBOTylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdS5fZShlcnIpO1xuICAgIH07XG4gICAgTWFwRmxhdHRlbk9wZXJhdG9yLnByb3RvdHlwZS5fYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5vcGVuID0gZmFsc2U7XG4gICAgICAgIHRoaXMubGVzcygpO1xuICAgIH07XG4gICAgcmV0dXJuIE1hcEZsYXR0ZW5PcGVyYXRvcjtcbn0oKSk7XG5leHBvcnRzLk1hcEZsYXR0ZW5PcGVyYXRvciA9IE1hcEZsYXR0ZW5PcGVyYXRvcjtcbnZhciBNYXBPcGVyYXRvciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gTWFwT3BlcmF0b3IocHJvamVjdCwgaW5zKSB7XG4gICAgICAgIHRoaXMudHlwZSA9ICdtYXAnO1xuICAgICAgICB0aGlzLmlucyA9IGlucztcbiAgICAgICAgdGhpcy5vdXQgPSBOTztcbiAgICAgICAgdGhpcy5wcm9qZWN0ID0gcHJvamVjdDtcbiAgICB9XG4gICAgTWFwT3BlcmF0b3IucHJvdG90eXBlLl9zdGFydCA9IGZ1bmN0aW9uIChvdXQpIHtcbiAgICAgICAgdGhpcy5vdXQgPSBvdXQ7XG4gICAgICAgIHRoaXMuaW5zLl9hZGQodGhpcyk7XG4gICAgfTtcbiAgICBNYXBPcGVyYXRvci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuaW5zLl9yZW1vdmUodGhpcyk7XG4gICAgICAgIHRoaXMub3V0ID0gTk87XG4gICAgfTtcbiAgICBNYXBPcGVyYXRvci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAodSA9PT0gTk8pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB1Ll9uKHRoaXMucHJvamVjdCh0KSk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHUuX2UoZSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIE1hcE9wZXJhdG9yLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKHUgPT09IE5PKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9lKGVycik7XG4gICAgfTtcbiAgICBNYXBPcGVyYXRvci5wcm90b3R5cGUuX2MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICh1ID09PSBOTylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdS5fYygpO1xuICAgIH07XG4gICAgcmV0dXJuIE1hcE9wZXJhdG9yO1xufSgpKTtcbmV4cG9ydHMuTWFwT3BlcmF0b3IgPSBNYXBPcGVyYXRvcjtcbnZhciBGaWx0ZXJNYXBPcGVyYXRvciA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XG4gICAgX19leHRlbmRzKEZpbHRlck1hcE9wZXJhdG9yLCBfc3VwZXIpO1xuICAgIGZ1bmN0aW9uIEZpbHRlck1hcE9wZXJhdG9yKHBhc3NlcywgcHJvamVjdCwgaW5zKSB7XG4gICAgICAgIF9zdXBlci5jYWxsKHRoaXMsIHByb2plY3QsIGlucyk7XG4gICAgICAgIHRoaXMudHlwZSA9ICdmaWx0ZXIrbWFwJztcbiAgICAgICAgdGhpcy5wYXNzZXMgPSBwYXNzZXM7XG4gICAgfVxuICAgIEZpbHRlck1hcE9wZXJhdG9yLnByb3RvdHlwZS5fbiA9IGZ1bmN0aW9uICh2KSB7XG4gICAgICAgIGlmICh0aGlzLnBhc3Nlcyh2KSkge1xuICAgICAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5fbi5jYWxsKHRoaXMsIHYpO1xuICAgICAgICB9XG4gICAgICAgIDtcbiAgICB9O1xuICAgIHJldHVybiBGaWx0ZXJNYXBPcGVyYXRvcjtcbn0oTWFwT3BlcmF0b3IpKTtcbmV4cG9ydHMuRmlsdGVyTWFwT3BlcmF0b3IgPSBGaWx0ZXJNYXBPcGVyYXRvcjtcbnZhciBSZW1lbWJlck9wZXJhdG9yID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBSZW1lbWJlck9wZXJhdG9yKGlucykge1xuICAgICAgICB0aGlzLnR5cGUgPSAncmVtZW1iZXInO1xuICAgICAgICB0aGlzLmlucyA9IGlucztcbiAgICAgICAgdGhpcy5vdXQgPSBOTztcbiAgICB9XG4gICAgUmVtZW1iZXJPcGVyYXRvci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB0aGlzLm91dCA9IG91dDtcbiAgICAgICAgdGhpcy5pbnMuX2FkZChvdXQpO1xuICAgIH07XG4gICAgUmVtZW1iZXJPcGVyYXRvci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuaW5zLl9yZW1vdmUodGhpcy5vdXQpO1xuICAgICAgICB0aGlzLm91dCA9IE5PO1xuICAgIH07XG4gICAgcmV0dXJuIFJlbWVtYmVyT3BlcmF0b3I7XG59KCkpO1xuZXhwb3J0cy5SZW1lbWJlck9wZXJhdG9yID0gUmVtZW1iZXJPcGVyYXRvcjtcbnZhciBSZXBsYWNlRXJyb3JPcGVyYXRvciA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gUmVwbGFjZUVycm9yT3BlcmF0b3IoZm4sIGlucykge1xuICAgICAgICB0aGlzLnR5cGUgPSAncmVwbGFjZUVycm9yJztcbiAgICAgICAgdGhpcy5pbnMgPSBpbnM7XG4gICAgICAgIHRoaXMub3V0ID0gTk87XG4gICAgICAgIHRoaXMuZm4gPSBmbjtcbiAgICB9XG4gICAgUmVwbGFjZUVycm9yT3BlcmF0b3IucHJvdG90eXBlLl9zdGFydCA9IGZ1bmN0aW9uIChvdXQpIHtcbiAgICAgICAgdGhpcy5vdXQgPSBvdXQ7XG4gICAgICAgIHRoaXMuaW5zLl9hZGQodGhpcyk7XG4gICAgfTtcbiAgICBSZXBsYWNlRXJyb3JPcGVyYXRvci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuaW5zLl9yZW1vdmUodGhpcyk7XG4gICAgICAgIHRoaXMub3V0ID0gTk87XG4gICAgfTtcbiAgICBSZXBsYWNlRXJyb3JPcGVyYXRvci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAodSA9PT0gTk8pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHUuX24odCk7XG4gICAgfTtcbiAgICBSZXBsYWNlRXJyb3JPcGVyYXRvci5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICh1ID09PSBOTylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuaW5zLl9yZW1vdmUodGhpcyk7XG4gICAgICAgICAgICAodGhpcy5pbnMgPSB0aGlzLmZuKGVycikpLl9hZGQodGhpcyk7XG4gICAgICAgIH1cbiAgICAgICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIHUuX2UoZSk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFJlcGxhY2VFcnJvck9wZXJhdG9yLnByb3RvdHlwZS5fYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKHUgPT09IE5PKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9jKCk7XG4gICAgfTtcbiAgICByZXR1cm4gUmVwbGFjZUVycm9yT3BlcmF0b3I7XG59KCkpO1xuZXhwb3J0cy5SZXBsYWNlRXJyb3JPcGVyYXRvciA9IFJlcGxhY2VFcnJvck9wZXJhdG9yO1xudmFyIFN0YXJ0V2l0aE9wZXJhdG9yID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBTdGFydFdpdGhPcGVyYXRvcihpbnMsIHZhbCkge1xuICAgICAgICB0aGlzLnR5cGUgPSAnc3RhcnRXaXRoJztcbiAgICAgICAgdGhpcy5pbnMgPSBpbnM7XG4gICAgICAgIHRoaXMub3V0ID0gTk87XG4gICAgICAgIHRoaXMudmFsID0gdmFsO1xuICAgIH1cbiAgICBTdGFydFdpdGhPcGVyYXRvci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB0aGlzLm91dCA9IG91dDtcbiAgICAgICAgdGhpcy5vdXQuX24odGhpcy52YWwpO1xuICAgICAgICB0aGlzLmlucy5fYWRkKG91dCk7XG4gICAgfTtcbiAgICBTdGFydFdpdGhPcGVyYXRvci5wcm90b3R5cGUuX3N0b3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuaW5zLl9yZW1vdmUodGhpcy5vdXQpO1xuICAgICAgICB0aGlzLm91dCA9IE5PO1xuICAgIH07XG4gICAgcmV0dXJuIFN0YXJ0V2l0aE9wZXJhdG9yO1xufSgpKTtcbmV4cG9ydHMuU3RhcnRXaXRoT3BlcmF0b3IgPSBTdGFydFdpdGhPcGVyYXRvcjtcbnZhciBUYWtlT3BlcmF0b3IgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIFRha2VPcGVyYXRvcihtYXgsIGlucykge1xuICAgICAgICB0aGlzLnR5cGUgPSAndGFrZSc7XG4gICAgICAgIHRoaXMuaW5zID0gaW5zO1xuICAgICAgICB0aGlzLm91dCA9IE5PO1xuICAgICAgICB0aGlzLm1heCA9IG1heDtcbiAgICAgICAgdGhpcy50YWtlbiA9IDA7XG4gICAgfVxuICAgIFRha2VPcGVyYXRvci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB0aGlzLm91dCA9IG91dDtcbiAgICAgICAgdGhpcy50YWtlbiA9IDA7XG4gICAgICAgIHRoaXMuaW5zLl9hZGQodGhpcyk7XG4gICAgfTtcbiAgICBUYWtlT3BlcmF0b3IucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmlucy5fcmVtb3ZlKHRoaXMpO1xuICAgICAgICB0aGlzLm91dCA9IE5PO1xuICAgIH07XG4gICAgVGFrZU9wZXJhdG9yLnByb3RvdHlwZS5fbiA9IGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICh1ID09PSBOTylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgaWYgKHRoaXMudGFrZW4rKyA8IHRoaXMubWF4IC0gMSkge1xuICAgICAgICAgICAgdS5fbih0KTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHUuX24odCk7XG4gICAgICAgICAgICB1Ll9jKCk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFRha2VPcGVyYXRvci5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICh1ID09PSBOTylcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdS5fZShlcnIpO1xuICAgIH07XG4gICAgVGFrZU9wZXJhdG9yLnByb3RvdHlwZS5fYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKHUgPT09IE5PKVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9jKCk7XG4gICAgfTtcbiAgICByZXR1cm4gVGFrZU9wZXJhdG9yO1xufSgpKTtcbmV4cG9ydHMuVGFrZU9wZXJhdG9yID0gVGFrZU9wZXJhdG9yO1xudmFyIFN0cmVhbSA9IChmdW5jdGlvbiAoKSB7XG4gICAgZnVuY3Rpb24gU3RyZWFtKHByb2R1Y2VyKSB7XG4gICAgICAgIHRoaXMuX3Byb2QgPSBwcm9kdWNlciB8fCBOTztcbiAgICAgICAgdGhpcy5faWxzID0gW107XG4gICAgICAgIHRoaXMuX3N0b3BJRCA9IE5PO1xuICAgICAgICB0aGlzLl90YXJnZXQgPSBOTztcbiAgICAgICAgdGhpcy5fZXJyID0gTk87XG4gICAgfVxuICAgIFN0cmVhbS5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodCkge1xuICAgICAgICB2YXIgYSA9IHRoaXMuX2lscztcbiAgICAgICAgdmFyIEwgPSBhLmxlbmd0aDtcbiAgICAgICAgaWYgKEwgPT0gMSlcbiAgICAgICAgICAgIGFbMF0uX24odCk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIGIgPSBjb3B5KGEpO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBMOyBpKyspXG4gICAgICAgICAgICAgICAgYltpXS5fbih0KTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgU3RyZWFtLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgaWYgKHRoaXMuX2VyciAhPT0gTk8pXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHRoaXMuX2VyciA9IGVycjtcbiAgICAgICAgdmFyIGEgPSB0aGlzLl9pbHM7XG4gICAgICAgIHZhciBMID0gYS5sZW5ndGg7XG4gICAgICAgIGlmIChMID09IDEpXG4gICAgICAgICAgICBhWzBdLl9lKGVycik7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdmFyIGIgPSBjb3B5KGEpO1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBMOyBpKyspXG4gICAgICAgICAgICAgICAgYltpXS5fZShlcnIpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuX3goKTtcbiAgICB9O1xuICAgIFN0cmVhbS5wcm90b3R5cGUuX2MgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBhID0gdGhpcy5faWxzO1xuICAgICAgICB2YXIgTCA9IGEubGVuZ3RoO1xuICAgICAgICBpZiAoTCA9PSAxKVxuICAgICAgICAgICAgYVswXS5fYygpO1xuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHZhciBiID0gY29weShhKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgTDsgaSsrKVxuICAgICAgICAgICAgICAgIGJbaV0uX2MoKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl94KCk7XG4gICAgfTtcbiAgICBTdHJlYW0ucHJvdG90eXBlLl94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICBpZiAodGhpcy5faWxzLmxlbmd0aCA9PT0gMClcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgaWYgKHRoaXMuX3Byb2QgIT09IE5PKVxuICAgICAgICAgICAgdGhpcy5fcHJvZC5fc3RvcCgpO1xuICAgICAgICB0aGlzLl9lcnIgPSBOTztcbiAgICAgICAgdGhpcy5faWxzID0gW107XG4gICAgfTtcbiAgICBTdHJlYW0ucHJvdG90eXBlLl9zdG9wTm93ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAvLyBXQVJOSU5HOiBjb2RlIHRoYXQgY2FsbHMgdGhpcyBtZXRob2Qgc2hvdWxkXG4gICAgICAgIC8vIGZpcnN0IGNoZWNrIGlmIHRoaXMuX3Byb2QgaXMgdmFsaWQgKG5vdCBgTk9gKVxuICAgICAgICB0aGlzLl9wcm9kLl9zdG9wKCk7XG4gICAgICAgIHRoaXMuX2VyciA9IE5PO1xuICAgICAgICB0aGlzLl9zdG9wSUQgPSBOTztcbiAgICB9O1xuICAgIFN0cmVhbS5wcm90b3R5cGUuX2FkZCA9IGZ1bmN0aW9uIChpbCkge1xuICAgICAgICB2YXIgdGEgPSB0aGlzLl90YXJnZXQ7XG4gICAgICAgIGlmICh0YSAhPT0gTk8pXG4gICAgICAgICAgICByZXR1cm4gdGEuX2FkZChpbCk7XG4gICAgICAgIHZhciBhID0gdGhpcy5faWxzO1xuICAgICAgICBhLnB1c2goaWwpO1xuICAgICAgICBpZiAoYS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdG9wSUQgIT09IE5PKSB7XG4gICAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuX3N0b3BJRCk7XG4gICAgICAgICAgICAgICAgdGhpcy5fc3RvcElEID0gTk87XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgcCA9IHRoaXMuX3Byb2Q7XG4gICAgICAgICAgICBpZiAocCAhPT0gTk8pXG4gICAgICAgICAgICAgICAgcC5fc3RhcnQodGhpcyk7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFN0cmVhbS5wcm90b3R5cGUuX3JlbW92ZSA9IGZ1bmN0aW9uIChpbCkge1xuICAgICAgICB2YXIgX3RoaXMgPSB0aGlzO1xuICAgICAgICB2YXIgdGEgPSB0aGlzLl90YXJnZXQ7XG4gICAgICAgIGlmICh0YSAhPT0gTk8pXG4gICAgICAgICAgICByZXR1cm4gdGEuX3JlbW92ZShpbCk7XG4gICAgICAgIHZhciBhID0gdGhpcy5faWxzO1xuICAgICAgICB2YXIgaSA9IGEuaW5kZXhPZihpbCk7XG4gICAgICAgIGlmIChpID4gLTEpIHtcbiAgICAgICAgICAgIGEuc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgaWYgKHRoaXMuX3Byb2QgIT09IE5PICYmIGEubGVuZ3RoIDw9IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9lcnIgPSBOTztcbiAgICAgICAgICAgICAgICB0aGlzLl9zdG9wSUQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsgcmV0dXJuIF90aGlzLl9zdG9wTm93KCk7IH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoYS5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgICAgICAgICB0aGlzLl9wcnVuZUN5Y2xlcygpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyBJZiBhbGwgcGF0aHMgc3RlbW1pbmcgZnJvbSBgdGhpc2Agc3RyZWFtIGV2ZW50dWFsbHkgZW5kIGF0IGB0aGlzYFxuICAgIC8vIHN0cmVhbSwgdGhlbiB3ZSByZW1vdmUgdGhlIHNpbmdsZSBsaXN0ZW5lciBvZiBgdGhpc2Agc3RyZWFtLCB0b1xuICAgIC8vIGZvcmNlIGl0IHRvIGVuZCBpdHMgZXhlY3V0aW9uIGFuZCBkaXNwb3NlIHJlc291cmNlcy4gVGhpcyBtZXRob2RcbiAgICAvLyBhc3N1bWVzIGFzIGEgcHJlY29uZGl0aW9uIHRoYXQgdGhpcy5faWxzIGhhcyBqdXN0IG9uZSBsaXN0ZW5lci5cbiAgICBTdHJlYW0ucHJvdG90eXBlLl9wcnVuZUN5Y2xlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgaWYgKHRoaXMuX2hhc05vU2lua3ModGhpcywgW10pKSB7XG4gICAgICAgICAgICB0aGlzLl9yZW1vdmUodGhpcy5faWxzWzBdKTtcbiAgICAgICAgfVxuICAgIH07XG4gICAgLy8gQ2hlY2tzIHdoZXRoZXIgKnRoZXJlIGlzIG5vKiBwYXRoIHN0YXJ0aW5nIGZyb20gYHhgIHRoYXQgbGVhZHMgdG8gYW4gZW5kXG4gICAgLy8gbGlzdGVuZXIgKHNpbmspIGluIHRoZSBzdHJlYW0gZ3JhcGgsIGZvbGxvd2luZyBlZGdlcyBBLT5CIHdoZXJlIEIgaXMgYVxuICAgIC8vIGxpc3RlbmVyIG9mIEEuIFRoaXMgbWVhbnMgdGhlc2UgcGF0aHMgY29uc3RpdHV0ZSBhIGN5Y2xlIHNvbWVob3cuIElzIGdpdmVuXG4gICAgLy8gYSB0cmFjZSBvZiBhbGwgdmlzaXRlZCBub2RlcyBzbyBmYXIuXG4gICAgU3RyZWFtLnByb3RvdHlwZS5faGFzTm9TaW5rcyA9IGZ1bmN0aW9uICh4LCB0cmFjZSkge1xuICAgICAgICBpZiAodHJhY2UuaW5kZXhPZih4KSAhPT0gLTEpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHgub3V0ID09PSB0aGlzKSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmICh4Lm91dCAmJiB4Lm91dCAhPT0gTk8pIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9oYXNOb1NpbmtzKHgub3V0LCB0cmFjZS5jb25jYXQoeCkpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHguX2lscykge1xuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIE4gPSB4Ll9pbHMubGVuZ3RoOyBpIDwgTjsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLl9oYXNOb1NpbmtzKHguX2lsc1tpXSwgdHJhY2UuY29uY2F0KHgpKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9O1xuICAgIFN0cmVhbS5wcm90b3R5cGUuY3RvciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMgaW5zdGFuY2VvZiBNZW1vcnlTdHJlYW0gPyBNZW1vcnlTdHJlYW0gOiBTdHJlYW07XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBBZGRzIGEgTGlzdGVuZXIgdG8gdGhlIFN0cmVhbS5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TGlzdGVuZXI8VD59IGxpc3RlbmVyXG4gICAgICovXG4gICAgU3RyZWFtLnByb3RvdHlwZS5hZGRMaXN0ZW5lciA9IGZ1bmN0aW9uIChsaXN0ZW5lcikge1xuICAgICAgICBpZiAodHlwZW9mIGxpc3RlbmVyLm5leHQgIT09ICdmdW5jdGlvbidcbiAgICAgICAgICAgIHx8IHR5cGVvZiBsaXN0ZW5lci5lcnJvciAhPT0gJ2Z1bmN0aW9uJ1xuICAgICAgICAgICAgfHwgdHlwZW9mIGxpc3RlbmVyLmNvbXBsZXRlICE9PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3N0cmVhbS5hZGRMaXN0ZW5lcigpIHJlcXVpcmVzIGFsbCB0aHJlZSBuZXh0LCBlcnJvciwgJyArXG4gICAgICAgICAgICAgICAgJ2FuZCBjb21wbGV0ZSBmdW5jdGlvbnMuJyk7XG4gICAgICAgIH1cbiAgICAgICAgbGlzdGVuZXIuX24gPSBsaXN0ZW5lci5uZXh0O1xuICAgICAgICBsaXN0ZW5lci5fZSA9IGxpc3RlbmVyLmVycm9yO1xuICAgICAgICBsaXN0ZW5lci5fYyA9IGxpc3RlbmVyLmNvbXBsZXRlO1xuICAgICAgICB0aGlzLl9hZGQobGlzdGVuZXIpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogUmVtb3ZlcyBhIExpc3RlbmVyIGZyb20gdGhlIFN0cmVhbSwgYXNzdW1pbmcgdGhlIExpc3RlbmVyIHdhcyBhZGRlZCB0byBpdC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7TGlzdGVuZXI8VD59IGxpc3RlbmVyXG4gICAgICovXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9IGZ1bmN0aW9uIChsaXN0ZW5lcikge1xuICAgICAgICB0aGlzLl9yZW1vdmUobGlzdGVuZXIpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIG5ldyBTdHJlYW0gZ2l2ZW4gYSBQcm9kdWNlci5cbiAgICAgKlxuICAgICAqIEBmYWN0b3J5IHRydWVcbiAgICAgKiBAcGFyYW0ge1Byb2R1Y2VyfSBwcm9kdWNlciBBbiBvcHRpb25hbCBQcm9kdWNlciB0aGF0IGRpY3RhdGVzIGhvdyB0b1xuICAgICAqIHN0YXJ0LCBnZW5lcmF0ZSBldmVudHMsIGFuZCBzdG9wIHRoZSBTdHJlYW0uXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5jcmVhdGUgPSBmdW5jdGlvbiAocHJvZHVjZXIpIHtcbiAgICAgICAgaWYgKHByb2R1Y2VyKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHByb2R1Y2VyLnN0YXJ0ICE9PSAnZnVuY3Rpb24nXG4gICAgICAgICAgICAgICAgfHwgdHlwZW9mIHByb2R1Y2VyLnN0b3AgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ3Byb2R1Y2VyIHJlcXVpcmVzIGJvdGggc3RhcnQgYW5kIHN0b3AgZnVuY3Rpb25zJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpbnRlcm5hbGl6ZVByb2R1Y2VyKHByb2R1Y2VyKTsgLy8gbXV0YXRlcyB0aGUgaW5wdXRcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IFN0cmVhbShwcm9kdWNlcik7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgbmV3IE1lbW9yeVN0cmVhbSBnaXZlbiBhIFByb2R1Y2VyLlxuICAgICAqXG4gICAgICogQGZhY3RvcnkgdHJ1ZVxuICAgICAqIEBwYXJhbSB7UHJvZHVjZXJ9IHByb2R1Y2VyIEFuIG9wdGlvbmFsIFByb2R1Y2VyIHRoYXQgZGljdGF0ZXMgaG93IHRvXG4gICAgICogc3RhcnQsIGdlbmVyYXRlIGV2ZW50cywgYW5kIHN0b3AgdGhlIFN0cmVhbS5cbiAgICAgKiBAcmV0dXJuIHtNZW1vcnlTdHJlYW19XG4gICAgICovXG4gICAgU3RyZWFtLmNyZWF0ZVdpdGhNZW1vcnkgPSBmdW5jdGlvbiAocHJvZHVjZXIpIHtcbiAgICAgICAgaWYgKHByb2R1Y2VyKSB7XG4gICAgICAgICAgICBpbnRlcm5hbGl6ZVByb2R1Y2VyKHByb2R1Y2VyKTsgLy8gbXV0YXRlcyB0aGUgaW5wdXRcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbmV3IE1lbW9yeVN0cmVhbShwcm9kdWNlcik7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgU3RyZWFtIHRoYXQgZG9lcyBub3RoaW5nIHdoZW4gc3RhcnRlZC4gSXQgbmV2ZXIgZW1pdHMgYW55IGV2ZW50LlxuICAgICAqXG4gICAgICogTWFyYmxlIGRpYWdyYW06XG4gICAgICpcbiAgICAgKiBgYGB0ZXh0XG4gICAgICogICAgICAgICAgbmV2ZXJcbiAgICAgKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQGZhY3RvcnkgdHJ1ZVxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0ubmV2ZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RyZWFtKHsgX3N0YXJ0OiBub29wLCBfc3RvcDogbm9vcCB9KTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBTdHJlYW0gdGhhdCBpbW1lZGlhdGVseSBlbWl0cyB0aGUgXCJjb21wbGV0ZVwiIG5vdGlmaWNhdGlvbiB3aGVuXG4gICAgICogc3RhcnRlZCwgYW5kIHRoYXQncyBpdC5cbiAgICAgKlxuICAgICAqIE1hcmJsZSBkaWFncmFtOlxuICAgICAqXG4gICAgICogYGBgdGV4dFxuICAgICAqIGVtcHR5XG4gICAgICogLXxcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBmYWN0b3J5IHRydWVcbiAgICAgKiBAcmV0dXJuIHtTdHJlYW19XG4gICAgICovXG4gICAgU3RyZWFtLmVtcHR5ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gbmV3IFN0cmVhbSh7XG4gICAgICAgICAgICBfc3RhcnQ6IGZ1bmN0aW9uIChpbCkgeyBpbC5fYygpOyB9LFxuICAgICAgICAgICAgX3N0b3A6IG5vb3AsXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIFN0cmVhbSB0aGF0IGltbWVkaWF0ZWx5IGVtaXRzIGFuIFwiZXJyb3JcIiBub3RpZmljYXRpb24gd2l0aCB0aGVcbiAgICAgKiB2YWx1ZSB5b3UgcGFzc2VkIGFzIHRoZSBgZXJyb3JgIGFyZ3VtZW50IHdoZW4gdGhlIHN0cmVhbSBzdGFydHMsIGFuZCB0aGF0J3NcbiAgICAgKiBpdC5cbiAgICAgKlxuICAgICAqIE1hcmJsZSBkaWFncmFtOlxuICAgICAqXG4gICAgICogYGBgdGV4dFxuICAgICAqIHRocm93KFgpXG4gICAgICogLVhcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBmYWN0b3J5IHRydWVcbiAgICAgKiBAcGFyYW0gZXJyb3IgVGhlIGVycm9yIGV2ZW50IHRvIGVtaXQgb24gdGhlIGNyZWF0ZWQgc3RyZWFtLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0udGhyb3cgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTdHJlYW0oe1xuICAgICAgICAgICAgX3N0YXJ0OiBmdW5jdGlvbiAoaWwpIHsgaWwuX2UoZXJyb3IpOyB9LFxuICAgICAgICAgICAgX3N0b3A6IG5vb3AsXG4gICAgICAgIH0pO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIFN0cmVhbSB0aGF0IGltbWVkaWF0ZWx5IGVtaXRzIHRoZSBhcmd1bWVudHMgdGhhdCB5b3UgZ2l2ZSB0b1xuICAgICAqICpvZiosIHRoZW4gY29tcGxldGVzLlxuICAgICAqXG4gICAgICogTWFyYmxlIGRpYWdyYW06XG4gICAgICpcbiAgICAgKiBgYGB0ZXh0XG4gICAgICogb2YoMSwyLDMpXG4gICAgICogMTIzfFxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQGZhY3RvcnkgdHJ1ZVxuICAgICAqIEBwYXJhbSBhIFRoZSBmaXJzdCB2YWx1ZSB5b3Ugd2FudCB0byBlbWl0IGFzIGFuIGV2ZW50IG9uIHRoZSBzdHJlYW0uXG4gICAgICogQHBhcmFtIGIgVGhlIHNlY29uZCB2YWx1ZSB5b3Ugd2FudCB0byBlbWl0IGFzIGFuIGV2ZW50IG9uIHRoZSBzdHJlYW0uIE9uZVxuICAgICAqIG9yIG1vcmUgb2YgdGhlc2UgdmFsdWVzIG1heSBiZSBnaXZlbiBhcyBhcmd1bWVudHMuXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5vZiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIGl0ZW1zID0gW107XG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICBpdGVtc1tfaSAtIDBdID0gYXJndW1lbnRzW19pXTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gU3RyZWFtLmZyb21BcnJheShpdGVtcyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBhbiBhcnJheSB0byBhIHN0cmVhbS4gVGhlIHJldHVybmVkIHN0cmVhbSB3aWxsIGVtaXQgc3luY2hyb25vdXNseVxuICAgICAqIGFsbCB0aGUgaXRlbXMgaW4gdGhlIGFycmF5LCBhbmQgdGhlbiBjb21wbGV0ZS5cbiAgICAgKlxuICAgICAqIE1hcmJsZSBkaWFncmFtOlxuICAgICAqXG4gICAgICogYGBgdGV4dFxuICAgICAqIGZyb21BcnJheShbMSwyLDNdKVxuICAgICAqIDEyM3xcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBmYWN0b3J5IHRydWVcbiAgICAgKiBAcGFyYW0ge0FycmF5fSBhcnJheSBUaGUgYXJyYXkgdG8gYmUgY29udmVydGVkIGFzIGEgc3RyZWFtLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0uZnJvbUFycmF5ID0gZnVuY3Rpb24gKGFycmF5KSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RyZWFtKG5ldyBGcm9tQXJyYXlQcm9kdWNlcihhcnJheSkpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYSBwcm9taXNlIHRvIGEgc3RyZWFtLiBUaGUgcmV0dXJuZWQgc3RyZWFtIHdpbGwgZW1pdCB0aGUgcmVzb2x2ZWRcbiAgICAgKiB2YWx1ZSBvZiB0aGUgcHJvbWlzZSwgYW5kIHRoZW4gY29tcGxldGUuIEhvd2V2ZXIsIGlmIHRoZSBwcm9taXNlIGlzXG4gICAgICogcmVqZWN0ZWQsIHRoZSBzdHJlYW0gd2lsbCBlbWl0IHRoZSBjb3JyZXNwb25kaW5nIGVycm9yLlxuICAgICAqXG4gICAgICogTWFyYmxlIGRpYWdyYW06XG4gICAgICpcbiAgICAgKiBgYGB0ZXh0XG4gICAgICogZnJvbVByb21pc2UoIC0tLS00MiApXG4gICAgICogLS0tLS0tLS0tLS0tLS0tLS00MnxcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBmYWN0b3J5IHRydWVcbiAgICAgKiBAcGFyYW0ge1Byb21pc2V9IHByb21pc2UgVGhlIHByb21pc2UgdG8gYmUgY29udmVydGVkIGFzIGEgc3RyZWFtLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0uZnJvbVByb21pc2UgPSBmdW5jdGlvbiAocHJvbWlzZSkge1xuICAgICAgICByZXR1cm4gbmV3IFN0cmVhbShuZXcgRnJvbVByb21pc2VQcm9kdWNlcihwcm9taXNlKSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgc3RyZWFtIHRoYXQgcGVyaW9kaWNhbGx5IGVtaXRzIGluY3JlbWVudGFsIG51bWJlcnMsIGV2ZXJ5XG4gICAgICogYHBlcmlvZGAgbWlsbGlzZWNvbmRzLlxuICAgICAqXG4gICAgICogTWFyYmxlIGRpYWdyYW06XG4gICAgICpcbiAgICAgKiBgYGB0ZXh0XG4gICAgICogICAgIHBlcmlvZGljKDEwMDApXG4gICAgICogLS0tMC0tLTEtLS0yLS0tMy0tLTQtLS0uLi5cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBmYWN0b3J5IHRydWVcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gcGVyaW9kIFRoZSBpbnRlcnZhbCBpbiBtaWxsaXNlY29uZHMgdG8gdXNlIGFzIGEgcmF0ZSBvZlxuICAgICAqIGVtaXNzaW9uLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0ucGVyaW9kaWMgPSBmdW5jdGlvbiAocGVyaW9kKSB7XG4gICAgICAgIHJldHVybiBuZXcgU3RyZWFtKG5ldyBQZXJpb2RpY1Byb2R1Y2VyKHBlcmlvZCkpO1xuICAgIH07XG4gICAgU3RyZWFtLnByb3RvdHlwZS5fbWFwID0gZnVuY3Rpb24gKHByb2plY3QpIHtcbiAgICAgICAgdmFyIHAgPSB0aGlzLl9wcm9kO1xuICAgICAgICB2YXIgY3RvciA9IHRoaXMuY3RvcigpO1xuICAgICAgICBpZiAocCBpbnN0YW5jZW9mIEZpbHRlck9wZXJhdG9yKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IGN0b3IobmV3IEZpbHRlck1hcE9wZXJhdG9yKHAucGFzc2VzLCBwcm9qZWN0LCBwLmlucykpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwIGluc3RhbmNlb2YgRmlsdGVyTWFwT3BlcmF0b3IpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgY3RvcihuZXcgRmlsdGVyTWFwT3BlcmF0b3IocC5wYXNzZXMsIGNvbXBvc2UyKHByb2plY3QsIHAucHJvamVjdCksIHAuaW5zKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHAgaW5zdGFuY2VvZiBNYXBPcGVyYXRvcikge1xuICAgICAgICAgICAgcmV0dXJuIG5ldyBjdG9yKG5ldyBNYXBPcGVyYXRvcihjb21wb3NlMihwcm9qZWN0LCBwLnByb2plY3QpLCBwLmlucykpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgY3RvcihuZXcgTWFwT3BlcmF0b3IocHJvamVjdCwgdGhpcykpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogVHJhbnNmb3JtcyBlYWNoIGV2ZW50IGZyb20gdGhlIGlucHV0IFN0cmVhbSB0aHJvdWdoIGEgYHByb2plY3RgIGZ1bmN0aW9uLFxuICAgICAqIHRvIGdldCBhIFN0cmVhbSB0aGF0IGVtaXRzIHRob3NlIHRyYW5zZm9ybWVkIGV2ZW50cy5cbiAgICAgKlxuICAgICAqIE1hcmJsZSBkaWFncmFtOlxuICAgICAqXG4gICAgICogYGBgdGV4dFxuICAgICAqIC0tMS0tLTMtLTUtLS0tLTctLS0tLS1cbiAgICAgKiAgICBtYXAoaSA9PiBpICogMTApXG4gICAgICogLS0xMC0tMzAtNTAtLS0tNzAtLS0tLVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJvamVjdCBBIGZ1bmN0aW9uIG9mIHR5cGUgYCh0OiBUKSA9PiBVYCB0aGF0IHRha2VzIGV2ZW50XG4gICAgICogYHRgIG9mIHR5cGUgYFRgIGZyb20gdGhlIGlucHV0IFN0cmVhbSBhbmQgcHJvZHVjZXMgYW4gZXZlbnQgb2YgdHlwZSBgVWAsIHRvXG4gICAgICogYmUgZW1pdHRlZCBvbiB0aGUgb3V0cHV0IFN0cmVhbS5cbiAgICAgKiBAcmV0dXJuIHtTdHJlYW19XG4gICAgICovXG4gICAgU3RyZWFtLnByb3RvdHlwZS5tYXAgPSBmdW5jdGlvbiAocHJvamVjdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwKHByb2plY3QpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogSXQncyBsaWtlIGBtYXBgLCBidXQgdHJhbnNmb3JtcyBlYWNoIGlucHV0IGV2ZW50IHRvIGFsd2F5cyB0aGUgc2FtZVxuICAgICAqIGNvbnN0YW50IHZhbHVlIG9uIHRoZSBvdXRwdXQgU3RyZWFtLlxuICAgICAqXG4gICAgICogTWFyYmxlIGRpYWdyYW06XG4gICAgICpcbiAgICAgKiBgYGB0ZXh0XG4gICAgICogLS0xLS0tMy0tNS0tLS0tNy0tLS0tXG4gICAgICogICAgICAgbWFwVG8oMTApXG4gICAgICogLS0xMC0tMTAtMTAtLS0tMTAtLS0tXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0gcHJvamVjdGVkVmFsdWUgQSB2YWx1ZSB0byBlbWl0IG9uIHRoZSBvdXRwdXQgU3RyZWFtIHdoZW5ldmVyIHRoZVxuICAgICAqIGlucHV0IFN0cmVhbSBlbWl0cyBhbnkgdmFsdWUuXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5wcm90b3R5cGUubWFwVG8gPSBmdW5jdGlvbiAocHJvamVjdGVkVmFsdWUpIHtcbiAgICAgICAgdmFyIHMgPSB0aGlzLm1hcChmdW5jdGlvbiAoKSB7IHJldHVybiBwcm9qZWN0ZWRWYWx1ZTsgfSk7XG4gICAgICAgIHZhciBvcCA9IHMuX3Byb2Q7XG4gICAgICAgIG9wLnR5cGUgPSBvcC50eXBlLnJlcGxhY2UoJ21hcCcsICdtYXBUbycpO1xuICAgICAgICByZXR1cm4gcztcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIE9ubHkgYWxsb3dzIGV2ZW50cyB0aGF0IHBhc3MgdGhlIHRlc3QgZ2l2ZW4gYnkgdGhlIGBwYXNzZXNgIGFyZ3VtZW50LlxuICAgICAqXG4gICAgICogRWFjaCBldmVudCBmcm9tIHRoZSBpbnB1dCBzdHJlYW0gaXMgZ2l2ZW4gdG8gdGhlIGBwYXNzZXNgIGZ1bmN0aW9uLiBJZiB0aGVcbiAgICAgKiBmdW5jdGlvbiByZXR1cm5zIGB0cnVlYCwgdGhlIGV2ZW50IGlzIGZvcndhcmRlZCB0byB0aGUgb3V0cHV0IHN0cmVhbSxcbiAgICAgKiBvdGhlcndpc2UgaXQgaXMgaWdub3JlZCBhbmQgbm90IGZvcndhcmRlZC5cbiAgICAgKlxuICAgICAqIE1hcmJsZSBkaWFncmFtOlxuICAgICAqXG4gICAgICogYGBgdGV4dFxuICAgICAqIC0tMS0tLTItLTMtLS0tLTQtLS0tLTUtLS02LS03LTgtLVxuICAgICAqICAgICBmaWx0ZXIoaSA9PiBpICUgMiA9PT0gMClcbiAgICAgKiAtLS0tLS0yLS0tLS0tLS00LS0tLS0tLS0tNi0tLS04LS1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHBhc3NlcyBBIGZ1bmN0aW9uIG9mIHR5cGUgYCh0OiBUKSArPiBib29sZWFuYCB0aGF0IHRha2VzXG4gICAgICogYW4gZXZlbnQgZnJvbSB0aGUgaW5wdXQgc3RyZWFtIGFuZCBjaGVja3MgaWYgaXQgcGFzc2VzLCBieSByZXR1cm5pbmcgYVxuICAgICAqIGJvb2xlYW4uXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5wcm90b3R5cGUuZmlsdGVyID0gZnVuY3Rpb24gKHBhc3Nlcykge1xuICAgICAgICB2YXIgcCA9IHRoaXMuX3Byb2Q7XG4gICAgICAgIGlmIChwIGluc3RhbmNlb2YgRmlsdGVyT3BlcmF0b3IpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgU3RyZWFtKG5ldyBGaWx0ZXJPcGVyYXRvcihhbmQocC5wYXNzZXMsIHBhc3NlcyksIHAuaW5zKSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBTdHJlYW0obmV3IEZpbHRlck9wZXJhdG9yKHBhc3NlcywgdGhpcykpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogTGV0cyB0aGUgZmlyc3QgYGFtb3VudGAgbWFueSBldmVudHMgZnJvbSB0aGUgaW5wdXQgc3RyZWFtIHBhc3MgdG8gdGhlXG4gICAgICogb3V0cHV0IHN0cmVhbSwgdGhlbiBtYWtlcyB0aGUgb3V0cHV0IHN0cmVhbSBjb21wbGV0ZS5cbiAgICAgKlxuICAgICAqIE1hcmJsZSBkaWFncmFtOlxuICAgICAqXG4gICAgICogYGBgdGV4dFxuICAgICAqIC0tYS0tLWItLWMtLS0tZC0tLWUtLVxuICAgICAqICAgIHRha2UoMylcbiAgICAgKiAtLWEtLS1iLS1jfFxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHtudW1iZXJ9IGFtb3VudCBIb3cgbWFueSBldmVudHMgdG8gYWxsb3cgZnJvbSB0aGUgaW5wdXQgc3RyZWFtXG4gICAgICogYmVmb3JlIGNvbXBsZXRpbmcgdGhlIG91dHB1dCBzdHJlYW0uXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5wcm90b3R5cGUudGFrZSA9IGZ1bmN0aW9uIChhbW91bnQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyAodGhpcy5jdG9yKCkpKG5ldyBUYWtlT3BlcmF0b3IoYW1vdW50LCB0aGlzKSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBJZ25vcmVzIHRoZSBmaXJzdCBgYW1vdW50YCBtYW55IGV2ZW50cyBmcm9tIHRoZSBpbnB1dCBzdHJlYW0sIGFuZCB0aGVuXG4gICAgICogYWZ0ZXIgdGhhdCBzdGFydHMgZm9yd2FyZGluZyBldmVudHMgZnJvbSB0aGUgaW5wdXQgc3RyZWFtIHRvIHRoZSBvdXRwdXRcbiAgICAgKiBzdHJlYW0uXG4gICAgICpcbiAgICAgKiBNYXJibGUgZGlhZ3JhbTpcbiAgICAgKlxuICAgICAqIGBgYHRleHRcbiAgICAgKiAtLWEtLS1iLS1jLS0tLWQtLS1lLS1cbiAgICAgKiAgICAgICBkcm9wKDMpXG4gICAgICogLS0tLS0tLS0tLS0tLS1kLS0tZS0tXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge251bWJlcn0gYW1vdW50IEhvdyBtYW55IGV2ZW50cyB0byBpZ25vcmUgZnJvbSB0aGUgaW5wdXQgc3RyZWFtXG4gICAgICogYmVmb3JlIGZvcndhcmRpbmcgYWxsIGV2ZW50cyBmcm9tIHRoZSBpbnB1dCBzdHJlYW0gdG8gdGhlIG91dHB1dCBzdHJlYW0uXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5wcm90b3R5cGUuZHJvcCA9IGZ1bmN0aW9uIChhbW91bnQpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTdHJlYW0obmV3IERyb3BPcGVyYXRvcihhbW91bnQsIHRoaXMpKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIFdoZW4gdGhlIGlucHV0IHN0cmVhbSBjb21wbGV0ZXMsIHRoZSBvdXRwdXQgc3RyZWFtIHdpbGwgZW1pdCB0aGUgbGFzdCBldmVudFxuICAgICAqIGVtaXR0ZWQgYnkgdGhlIGlucHV0IHN0cmVhbSwgYW5kIHRoZW4gd2lsbCBhbHNvIGNvbXBsZXRlLlxuICAgICAqXG4gICAgICogTWFyYmxlIGRpYWdyYW06XG4gICAgICpcbiAgICAgKiBgYGB0ZXh0XG4gICAgICogLS1hLS0tYi0tYy0tZC0tLS18XG4gICAgICogICAgICAgbGFzdCgpXG4gICAgICogLS0tLS0tLS0tLS0tLS0tLS1kfFxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5wcm90b3R5cGUubGFzdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBTdHJlYW0obmV3IExhc3RPcGVyYXRvcih0aGlzKSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBQcmVwZW5kcyB0aGUgZ2l2ZW4gYGluaXRpYWxgIHZhbHVlIHRvIHRoZSBzZXF1ZW5jZSBvZiBldmVudHMgZW1pdHRlZCBieSB0aGVcbiAgICAgKiBpbnB1dCBzdHJlYW0uIFRoZSByZXR1cm5lZCBzdHJlYW0gaXMgYSBNZW1vcnlTdHJlYW0sIHdoaWNoIG1lYW5zIGl0IGlzXG4gICAgICogYWxyZWFkeSBgcmVtZW1iZXIoKWAnZC5cbiAgICAgKlxuICAgICAqIE1hcmJsZSBkaWFncmFtOlxuICAgICAqXG4gICAgICogYGBgdGV4dFxuICAgICAqIC0tLTEtLS0yLS0tLS0zLS0tXG4gICAgICogICBzdGFydFdpdGgoMClcbiAgICAgKiAwLS0xLS0tMi0tLS0tMy0tLVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIGluaXRpYWwgVGhlIHZhbHVlIG9yIGV2ZW50IHRvIHByZXBlbmQuXG4gICAgICogQHJldHVybiB7TWVtb3J5U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5wcm90b3R5cGUuc3RhcnRXaXRoID0gZnVuY3Rpb24gKGluaXRpYWwpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBNZW1vcnlTdHJlYW0obmV3IFN0YXJ0V2l0aE9wZXJhdG9yKHRoaXMsIGluaXRpYWwpKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIFVzZXMgYW5vdGhlciBzdHJlYW0gdG8gZGV0ZXJtaW5lIHdoZW4gdG8gY29tcGxldGUgdGhlIGN1cnJlbnQgc3RyZWFtLlxuICAgICAqXG4gICAgICogV2hlbiB0aGUgZ2l2ZW4gYG90aGVyYCBzdHJlYW0gZW1pdHMgYW4gZXZlbnQgb3IgY29tcGxldGVzLCB0aGUgb3V0cHV0XG4gICAgICogc3RyZWFtIHdpbGwgY29tcGxldGUuIEJlZm9yZSB0aGF0IGhhcHBlbnMsIHRoZSBvdXRwdXQgc3RyZWFtIHdpbGwgYmVoYXZlc1xuICAgICAqIGxpa2UgdGhlIGlucHV0IHN0cmVhbS5cbiAgICAgKlxuICAgICAqIE1hcmJsZSBkaWFncmFtOlxuICAgICAqXG4gICAgICogYGBgdGV4dFxuICAgICAqIC0tLTEtLS0yLS0tLS0zLS00LS0tLTUtLS0tNi0tLVxuICAgICAqICAgZW5kV2hlbiggLS0tLS0tLS1hLS1iLS18IClcbiAgICAgKiAtLS0xLS0tMi0tLS0tMy0tNC0tfFxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIG90aGVyIFNvbWUgb3RoZXIgc3RyZWFtIHRoYXQgaXMgdXNlZCB0byBrbm93IHdoZW4gc2hvdWxkIHRoZSBvdXRwdXRcbiAgICAgKiBzdHJlYW0gb2YgdGhpcyBvcGVyYXRvciBjb21wbGV0ZS5cbiAgICAgKiBAcmV0dXJuIHtTdHJlYW19XG4gICAgICovXG4gICAgU3RyZWFtLnByb3RvdHlwZS5lbmRXaGVuID0gZnVuY3Rpb24gKG90aGVyKSB7XG4gICAgICAgIHJldHVybiBuZXcgKHRoaXMuY3RvcigpKShuZXcgRW5kV2hlbk9wZXJhdG9yKG90aGVyLCB0aGlzKSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBcIkZvbGRzXCIgdGhlIHN0cmVhbSBvbnRvIGl0c2VsZi5cbiAgICAgKlxuICAgICAqIENvbWJpbmVzIGV2ZW50cyBmcm9tIHRoZSBwYXN0IHRocm91Z2hvdXRcbiAgICAgKiB0aGUgZW50aXJlIGV4ZWN1dGlvbiBvZiB0aGUgaW5wdXQgc3RyZWFtLCBhbGxvd2luZyB5b3UgdG8gYWNjdW11bGF0ZSB0aGVtXG4gICAgICogdG9nZXRoZXIuIEl0J3MgZXNzZW50aWFsbHkgbGlrZSBgQXJyYXkucHJvdG90eXBlLnJlZHVjZWAuIFRoZSByZXR1cm5lZFxuICAgICAqIHN0cmVhbSBpcyBhIE1lbW9yeVN0cmVhbSwgd2hpY2ggbWVhbnMgaXQgaXMgYWxyZWFkeSBgcmVtZW1iZXIoKWAnZC5cbiAgICAgKlxuICAgICAqIFRoZSBvdXRwdXQgc3RyZWFtIHN0YXJ0cyBieSBlbWl0dGluZyB0aGUgYHNlZWRgIHdoaWNoIHlvdSBnaXZlIGFzIGFyZ3VtZW50LlxuICAgICAqIFRoZW4sIHdoZW4gYW4gZXZlbnQgaGFwcGVucyBvbiB0aGUgaW5wdXQgc3RyZWFtLCBpdCBpcyBjb21iaW5lZCB3aXRoIHRoYXRcbiAgICAgKiBzZWVkIHZhbHVlIHRocm91Z2ggdGhlIGBhY2N1bXVsYXRlYCBmdW5jdGlvbiwgYW5kIHRoZSBvdXRwdXQgdmFsdWUgaXNcbiAgICAgKiBlbWl0dGVkIG9uIHRoZSBvdXRwdXQgc3RyZWFtLiBgZm9sZGAgcmVtZW1iZXJzIHRoYXQgb3V0cHV0IHZhbHVlIGFzIGBhY2NgXG4gICAgICogKFwiYWNjdW11bGF0b3JcIiksIGFuZCB0aGVuIHdoZW4gYSBuZXcgaW5wdXQgZXZlbnQgYHRgIGhhcHBlbnMsIGBhY2NgIHdpbGwgYmVcbiAgICAgKiBjb21iaW5lZCB3aXRoIHRoYXQgdG8gcHJvZHVjZSB0aGUgbmV3IGBhY2NgIGFuZCBzbyBmb3J0aC5cbiAgICAgKlxuICAgICAqIE1hcmJsZSBkaWFncmFtOlxuICAgICAqXG4gICAgICogYGBgdGV4dFxuICAgICAqIC0tLS0tLTEtLS0tLTEtLTItLS0tMS0tLS0xLS0tLS0tXG4gICAgICogICBmb2xkKChhY2MsIHgpID0+IGFjYyArIHgsIDMpXG4gICAgICogMy0tLS0tNC0tLS0tNS0tNy0tLS04LS0tLTktLS0tLS1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGFjY3VtdWxhdGUgQSBmdW5jdGlvbiBvZiB0eXBlIGAoYWNjOiBSLCB0OiBUKSA9PiBSYCB0aGF0XG4gICAgICogdGFrZXMgdGhlIHByZXZpb3VzIGFjY3VtdWxhdGVkIHZhbHVlIGBhY2NgIGFuZCB0aGUgaW5jb21pbmcgZXZlbnQgZnJvbSB0aGVcbiAgICAgKiBpbnB1dCBzdHJlYW0gYW5kIHByb2R1Y2VzIHRoZSBuZXcgYWNjdW11bGF0ZWQgdmFsdWUuXG4gICAgICogQHBhcmFtIHNlZWQgVGhlIGluaXRpYWwgYWNjdW11bGF0ZWQgdmFsdWUsIG9mIHR5cGUgYFJgLlxuICAgICAqIEByZXR1cm4ge01lbW9yeVN0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0ucHJvdG90eXBlLmZvbGQgPSBmdW5jdGlvbiAoYWNjdW11bGF0ZSwgc2VlZCkge1xuICAgICAgICByZXR1cm4gbmV3IE1lbW9yeVN0cmVhbShuZXcgRm9sZE9wZXJhdG9yKGFjY3VtdWxhdGUsIHNlZWQsIHRoaXMpKTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIFJlcGxhY2VzIGFuIGVycm9yIHdpdGggYW5vdGhlciBzdHJlYW0uXG4gICAgICpcbiAgICAgKiBXaGVuIChhbmQgaWYpIGFuIGVycm9yIGhhcHBlbnMgb24gdGhlIGlucHV0IHN0cmVhbSwgaW5zdGVhZCBvZiBmb3J3YXJkaW5nXG4gICAgICogdGhhdCBlcnJvciB0byB0aGUgb3V0cHV0IHN0cmVhbSwgKnJlcGxhY2VFcnJvciogd2lsbCBjYWxsIHRoZSBgcmVwbGFjZWBcbiAgICAgKiBmdW5jdGlvbiB3aGljaCByZXR1cm5zIHRoZSBzdHJlYW0gdGhhdCB0aGUgb3V0cHV0IHN0cmVhbSB3aWxsIHJlcGxpY2F0ZS5cbiAgICAgKiBBbmQsIGluIGNhc2UgdGhhdCBuZXcgc3RyZWFtIGFsc28gZW1pdHMgYW4gZXJyb3IsIGByZXBsYWNlYCB3aWxsIGJlIGNhbGxlZFxuICAgICAqIGFnYWluIHRvIGdldCBhbm90aGVyIHN0cmVhbSB0byBzdGFydCByZXBsaWNhdGluZy5cbiAgICAgKlxuICAgICAqIE1hcmJsZSBkaWFncmFtOlxuICAgICAqXG4gICAgICogYGBgdGV4dFxuICAgICAqIC0tMS0tLTItLS0tLTMtLTQtLS0tLVhcbiAgICAgKiAgIHJlcGxhY2VFcnJvciggKCkgPT4gLS0xMC0tfCApXG4gICAgICogLS0xLS0tMi0tLS0tMy0tNC0tLS0tLS0tMTAtLXxcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHJlcGxhY2UgQSBmdW5jdGlvbiBvZiB0eXBlIGAoZXJyKSA9PiBTdHJlYW1gIHRoYXQgdGFrZXNcbiAgICAgKiB0aGUgZXJyb3IgdGhhdCBvY2N1cnJlZCBvbiB0aGUgaW5wdXQgc3RyZWFtIG9yIG9uIHRoZSBwcmV2aW91cyByZXBsYWNlbWVudFxuICAgICAqIHN0cmVhbSBhbmQgcmV0dXJucyBhIG5ldyBzdHJlYW0uIFRoZSBvdXRwdXQgc3RyZWFtIHdpbGwgYmVoYXZlIGxpa2UgdGhlXG4gICAgICogc3RyZWFtIHRoYXQgdGhpcyBmdW5jdGlvbiByZXR1cm5zLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0ucHJvdG90eXBlLnJlcGxhY2VFcnJvciA9IGZ1bmN0aW9uIChyZXBsYWNlKSB7XG4gICAgICAgIHJldHVybiBuZXcgKHRoaXMuY3RvcigpKShuZXcgUmVwbGFjZUVycm9yT3BlcmF0b3IocmVwbGFjZSwgdGhpcykpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogRmxhdHRlbnMgYSBcInN0cmVhbSBvZiBzdHJlYW1zXCIsIGhhbmRsaW5nIG9ubHkgb25lIG5lc3RlZCBzdHJlYW0gYXQgYSB0aW1lXG4gICAgICogKG5vIGNvbmN1cnJlbmN5KS5cbiAgICAgKlxuICAgICAqIElmIHRoZSBpbnB1dCBzdHJlYW0gaXMgYSBzdHJlYW0gdGhhdCBlbWl0cyBzdHJlYW1zLCB0aGVuIHRoaXMgb3BlcmF0b3Igd2lsbFxuICAgICAqIHJldHVybiBhbiBvdXRwdXQgc3RyZWFtIHdoaWNoIGlzIGEgZmxhdCBzdHJlYW06IGVtaXRzIHJlZ3VsYXIgZXZlbnRzLiBUaGVcbiAgICAgKiBmbGF0dGVuaW5nIGhhcHBlbnMgd2l0aG91dCBjb25jdXJyZW5jeS4gSXQgd29ya3MgbGlrZSB0aGlzOiB3aGVuIHRoZSBpbnB1dFxuICAgICAqIHN0cmVhbSBlbWl0cyBhIG5lc3RlZCBzdHJlYW0sICpmbGF0dGVuKiB3aWxsIHN0YXJ0IGltaXRhdGluZyB0aGF0IG5lc3RlZFxuICAgICAqIG9uZS4gSG93ZXZlciwgYXMgc29vbiBhcyB0aGUgbmV4dCBuZXN0ZWQgc3RyZWFtIGlzIGVtaXR0ZWQgb24gdGhlIGlucHV0XG4gICAgICogc3RyZWFtLCAqZmxhdHRlbiogd2lsbCBmb3JnZXQgdGhlIHByZXZpb3VzIG5lc3RlZCBvbmUgaXQgd2FzIGltaXRhdGluZywgYW5kXG4gICAgICogd2lsbCBzdGFydCBpbWl0YXRpbmcgdGhlIG5ldyBuZXN0ZWQgb25lLlxuICAgICAqXG4gICAgICogTWFyYmxlIGRpYWdyYW06XG4gICAgICpcbiAgICAgKiBgYGB0ZXh0XG4gICAgICogLS0rLS0tLS0tLS0rLS0tLS0tLS0tLS0tLS0tXG4gICAgICogICBcXCAgICAgICAgXFxcbiAgICAgKiAgICBcXCAgICAgICAtLS0tMS0tLS0yLS0tMy0tXG4gICAgICogICAgLS1hLS1iLS0tLWMtLS0tZC0tLS0tLS0tXG4gICAgICogICAgICAgICAgIGZsYXR0ZW5cbiAgICAgKiAtLS0tLWEtLWItLS0tLS0xLS0tLTItLS0zLS1cbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0ucHJvdG90eXBlLmZsYXR0ZW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBwID0gdGhpcy5fcHJvZDtcbiAgICAgICAgcmV0dXJuIG5ldyBTdHJlYW0ocCBpbnN0YW5jZW9mIE1hcE9wZXJhdG9yICYmICEocCBpbnN0YW5jZW9mIEZpbHRlck1hcE9wZXJhdG9yKSA/XG4gICAgICAgICAgICBuZXcgTWFwRmxhdHRlbk9wZXJhdG9yKHApIDpcbiAgICAgICAgICAgIG5ldyBGbGF0dGVuT3BlcmF0b3IodGhpcykpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogUGFzc2VzIHRoZSBpbnB1dCBzdHJlYW0gdG8gYSBjdXN0b20gb3BlcmF0b3IsIHRvIHByb2R1Y2UgYW4gb3V0cHV0IHN0cmVhbS5cbiAgICAgKlxuICAgICAqICpjb21wb3NlKiBpcyBhIGhhbmR5IHdheSBvZiB1c2luZyBhbiBleGlzdGluZyBmdW5jdGlvbiBpbiBhIGNoYWluZWQgc3R5bGUuXG4gICAgICogSW5zdGVhZCBvZiB3cml0aW5nIGBvdXRTdHJlYW0gPSBmKGluU3RyZWFtKWAgeW91IGNhbiB3cml0ZVxuICAgICAqIGBvdXRTdHJlYW0gPSBpblN0cmVhbS5jb21wb3NlKGYpYC5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb259IG9wZXJhdG9yIEEgZnVuY3Rpb24gdGhhdCB0YWtlcyBhIHN0cmVhbSBhcyBpbnB1dCBhbmRcbiAgICAgKiByZXR1cm5zIGEgc3RyZWFtIGFzIHdlbGwuXG4gICAgICogQHJldHVybiB7U3RyZWFtfVxuICAgICAqL1xuICAgIFN0cmVhbS5wcm90b3R5cGUuY29tcG9zZSA9IGZ1bmN0aW9uIChvcGVyYXRvcikge1xuICAgICAgICByZXR1cm4gb3BlcmF0b3IodGhpcyk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBSZXR1cm5zIGFuIG91dHB1dCBzdHJlYW0gdGhhdCBiZWhhdmVzIGxpa2UgdGhlIGlucHV0IHN0cmVhbSwgYnV0IGFsc29cbiAgICAgKiByZW1lbWJlcnMgdGhlIG1vc3QgcmVjZW50IGV2ZW50IHRoYXQgaGFwcGVucyBvbiB0aGUgaW5wdXQgc3RyZWFtLCBzbyB0aGF0IGFcbiAgICAgKiBuZXdseSBhZGRlZCBsaXN0ZW5lciB3aWxsIGltbWVkaWF0ZWx5IHJlY2VpdmUgdGhhdCBtZW1vcmlzZWQgZXZlbnQuXG4gICAgICpcbiAgICAgKiBAcmV0dXJuIHtNZW1vcnlTdHJlYW19XG4gICAgICovXG4gICAgU3RyZWFtLnByb3RvdHlwZS5yZW1lbWJlciA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBNZW1vcnlTdHJlYW0obmV3IFJlbWVtYmVyT3BlcmF0b3IodGhpcykpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogUmV0dXJucyBhbiBvdXRwdXQgc3RyZWFtIHRoYXQgaWRlbnRpY2FsbHkgYmVoYXZlcyBsaWtlIHRoZSBpbnB1dCBzdHJlYW0sXG4gICAgICogYnV0IGFsc28gcnVucyBhIGBzcHlgIGZ1bmN0aW9uIGZvIGVhY2ggZXZlbnQsIHRvIGhlbHAgeW91IGRlYnVnIHlvdXIgYXBwLlxuICAgICAqXG4gICAgICogKmRlYnVnKiB0YWtlcyBhIGBzcHlgIGZ1bmN0aW9uIGFzIGFyZ3VtZW50LCBhbmQgcnVucyB0aGF0IGZvciBlYWNoIGV2ZW50XG4gICAgICogaGFwcGVuaW5nIG9uIHRoZSBpbnB1dCBzdHJlYW0uIElmIHlvdSBkb24ndCBwcm92aWRlIHRoZSBgc3B5YCBhcmd1bWVudCxcbiAgICAgKiB0aGVuICpkZWJ1Zyogd2lsbCBqdXN0IGBjb25zb2xlLmxvZ2AgZWFjaCBldmVudC4gVGhpcyBoZWxwcyB5b3UgdG9cbiAgICAgKiB1bmRlcnN0YW5kIHRoZSBmbG93IG9mIGV2ZW50cyB0aHJvdWdoIHNvbWUgb3BlcmF0b3IgY2hhaW4uXG4gICAgICpcbiAgICAgKiBQbGVhc2Ugbm90ZSB0aGF0IGlmIHRoZSBvdXRwdXQgc3RyZWFtIGhhcyBubyBsaXN0ZW5lcnMsIHRoZW4gaXQgd2lsbCBub3RcbiAgICAgKiBzdGFydCwgd2hpY2ggbWVhbnMgYHNweWAgd2lsbCBuZXZlciBydW4gYmVjYXVzZSBubyBhY3R1YWwgZXZlbnQgaGFwcGVucyBpblxuICAgICAqIHRoYXQgY2FzZS5cbiAgICAgKlxuICAgICAqIE1hcmJsZSBkaWFncmFtOlxuICAgICAqXG4gICAgICogYGBgdGV4dFxuICAgICAqIC0tMS0tLS0yLS0tLS0zLS0tLS00LS1cbiAgICAgKiAgICAgICAgIGRlYnVnXG4gICAgICogLS0xLS0tLTItLS0tLTMtLS0tLTQtLVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQHBhcmFtIHtmdW5jdGlvbn0gbGFiZWxPclNweSBBIHN0cmluZyB0byB1c2UgYXMgdGhlIGxhYmVsIHdoZW4gcHJpbnRpbmdcbiAgICAgKiBkZWJ1ZyBpbmZvcm1hdGlvbiBvbiB0aGUgY29uc29sZSwgb3IgYSAnc3B5JyBmdW5jdGlvbiB0aGF0IHRha2VzIGFuIGV2ZW50XG4gICAgICogYXMgYXJndW1lbnQsIGFuZCBkb2VzIG5vdCBuZWVkIHRvIHJldHVybiBhbnl0aGluZy5cbiAgICAgKiBAcmV0dXJuIHtTdHJlYW19XG4gICAgICovXG4gICAgU3RyZWFtLnByb3RvdHlwZS5kZWJ1ZyA9IGZ1bmN0aW9uIChsYWJlbE9yU3B5KSB7XG4gICAgICAgIHJldHVybiBuZXcgKHRoaXMuY3RvcigpKShuZXcgRGVidWdPcGVyYXRvcihsYWJlbE9yU3B5LCB0aGlzKSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiAqaW1pdGF0ZSogY2hhbmdlcyB0aGlzIGN1cnJlbnQgU3RyZWFtIHRvIGVtaXQgdGhlIHNhbWUgZXZlbnRzIHRoYXQgdGhlXG4gICAgICogYG90aGVyYCBnaXZlbiBTdHJlYW0gZG9lcy4gVGhpcyBtZXRob2QgcmV0dXJucyBub3RoaW5nLlxuICAgICAqXG4gICAgICogVGhpcyBtZXRob2QgZXhpc3RzIHRvIGFsbG93IG9uZSB0aGluZzogKipjaXJjdWxhciBkZXBlbmRlbmN5IG9mIHN0cmVhbXMqKi5cbiAgICAgKiBGb3IgaW5zdGFuY2UsIGxldCdzIGltYWdpbmUgdGhhdCBmb3Igc29tZSByZWFzb24geW91IG5lZWQgdG8gY3JlYXRlIGFcbiAgICAgKiBjaXJjdWxhciBkZXBlbmRlbmN5IHdoZXJlIHN0cmVhbSBgZmlyc3QkYCBkZXBlbmRzIG9uIHN0cmVhbSBgc2Vjb25kJGBcbiAgICAgKiB3aGljaCBpbiB0dXJuIGRlcGVuZHMgb24gYGZpcnN0JGA6XG4gICAgICpcbiAgICAgKiA8IS0tIHNraXAtZXhhbXBsZSAtLT5cbiAgICAgKiBgYGBqc1xuICAgICAqIGltcG9ydCBkZWxheSBmcm9tICd4c3RyZWFtL2V4dHJhL2RlbGF5J1xuICAgICAqXG4gICAgICogdmFyIGZpcnN0JCA9IHNlY29uZCQubWFwKHggPT4geCAqIDEwKS50YWtlKDMpO1xuICAgICAqIHZhciBzZWNvbmQkID0gZmlyc3QkLm1hcCh4ID0+IHggKyAxKS5zdGFydFdpdGgoMSkuY29tcG9zZShkZWxheSgxMDApKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIEhvd2V2ZXIsIHRoYXQgaXMgaW52YWxpZCBKYXZhU2NyaXB0LCBiZWNhdXNlIGBzZWNvbmQkYCBpcyB1bmRlZmluZWRcbiAgICAgKiBvbiB0aGUgZmlyc3QgbGluZS4gVGhpcyBpcyBob3cgKmltaXRhdGUqIGNhbiBoZWxwIHNvbHZlIGl0OlxuICAgICAqXG4gICAgICogYGBganNcbiAgICAgKiBpbXBvcnQgZGVsYXkgZnJvbSAneHN0cmVhbS9leHRyYS9kZWxheSdcbiAgICAgKlxuICAgICAqIHZhciBzZWNvbmRQcm94eSQgPSB4cy5jcmVhdGUoKTtcbiAgICAgKiB2YXIgZmlyc3QkID0gc2Vjb25kUHJveHkkLm1hcCh4ID0+IHggKiAxMCkudGFrZSgzKTtcbiAgICAgKiB2YXIgc2Vjb25kJCA9IGZpcnN0JC5tYXAoeCA9PiB4ICsgMSkuc3RhcnRXaXRoKDEpLmNvbXBvc2UoZGVsYXkoMTAwKSk7XG4gICAgICogc2Vjb25kUHJveHkkLmltaXRhdGUoc2Vjb25kJCk7XG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBXZSBjcmVhdGUgYHNlY29uZFByb3h5JGAgYmVmb3JlIHRoZSBvdGhlcnMsIHNvIGl0IGNhbiBiZSB1c2VkIGluIHRoZVxuICAgICAqIGRlY2xhcmF0aW9uIG9mIGBmaXJzdCRgLiBUaGVuLCBhZnRlciBib3RoIGBmaXJzdCRgIGFuZCBgc2Vjb25kJGAgYXJlXG4gICAgICogZGVmaW5lZCwgd2UgaG9vayBgc2Vjb25kUHJveHkkYCB3aXRoIGBzZWNvbmQkYCB3aXRoIGBpbWl0YXRlKClgIHRvIHRlbGxcbiAgICAgKiB0aGF0IHRoZXkgYXJlIFwidGhlIHNhbWVcIi4gYGltaXRhdGVgIHdpbGwgbm90IHRyaWdnZXIgdGhlIHN0YXJ0IG9mIGFueVxuICAgICAqIHN0cmVhbSwgaXQganVzdCBiaW5kcyBgc2Vjb25kUHJveHkkYCBhbmQgYHNlY29uZCRgIHRvZ2V0aGVyLlxuICAgICAqXG4gICAgICogVGhlIGZvbGxvd2luZyBpcyBhbiBleGFtcGxlIHdoZXJlIGBpbWl0YXRlKClgIGlzIGltcG9ydGFudCBpbiBDeWNsZS5qc1xuICAgICAqIGFwcGxpY2F0aW9ucy4gQSBwYXJlbnQgY29tcG9uZW50IGNvbnRhaW5zIHNvbWUgY2hpbGQgY29tcG9uZW50cy4gQSBjaGlsZFxuICAgICAqIGhhcyBhbiBhY3Rpb24gc3RyZWFtIHdoaWNoIGlzIGdpdmVuIHRvIHRoZSBwYXJlbnQgdG8gZGVmaW5lIGl0cyBzdGF0ZTpcbiAgICAgKlxuICAgICAqIDwhLS0gc2tpcC1leGFtcGxlIC0tPlxuICAgICAqIGBgYGpzXG4gICAgICogY29uc3QgY2hpbGRBY3Rpb25Qcm94eSQgPSB4cy5jcmVhdGUoKTtcbiAgICAgKiBjb25zdCBwYXJlbnQgPSBQYXJlbnQoey4uLnNvdXJjZXMsIGNoaWxkQWN0aW9uJDogY2hpbGRBY3Rpb25Qcm94eSR9KTtcbiAgICAgKiBjb25zdCBjaGlsZEFjdGlvbiQgPSBwYXJlbnQuc3RhdGUkLm1hcChzID0+IHMuY2hpbGQuYWN0aW9uJCkuZmxhdHRlbigpO1xuICAgICAqIGNoaWxkQWN0aW9uUHJveHkkLmltaXRhdGUoY2hpbGRBY3Rpb24kKTtcbiAgICAgKiBgYGBcbiAgICAgKlxuICAgICAqIE5vdGUsIHRob3VnaCwgdGhhdCAqKmBpbWl0YXRlKClgIGRvZXMgbm90IHN1cHBvcnQgTWVtb3J5U3RyZWFtcyoqLiBJZiB3ZVxuICAgICAqIHdvdWxkIGF0dGVtcHQgdG8gaW1pdGF0ZSBhIE1lbW9yeVN0cmVhbSBpbiBhIGNpcmN1bGFyIGRlcGVuZGVuY3ksIHdlIHdvdWxkXG4gICAgICogZWl0aGVyIGdldCBhIHJhY2UgY29uZGl0aW9uICh3aGVyZSB0aGUgc3ltcHRvbSB3b3VsZCBiZSBcIm5vdGhpbmcgaGFwcGVuc1wiKVxuICAgICAqIG9yIGFuIGluZmluaXRlIGN5Y2xpYyBlbWlzc2lvbiBvZiB2YWx1ZXMuIEl0J3MgdXNlZnVsIHRvIHRoaW5rIGFib3V0XG4gICAgICogTWVtb3J5U3RyZWFtcyBhcyBjZWxscyBpbiBhIHNwcmVhZHNoZWV0LiBJdCBkb2Vzbid0IG1ha2UgYW55IHNlbnNlIHRvXG4gICAgICogZGVmaW5lIGEgc3ByZWFkc2hlZXQgY2VsbCBgQTFgIHdpdGggYSBmb3JtdWxhIHRoYXQgZGVwZW5kcyBvbiBgQjFgIGFuZFxuICAgICAqIGNlbGwgYEIxYCBkZWZpbmVkIHdpdGggYSBmb3JtdWxhIHRoYXQgZGVwZW5kcyBvbiBgQTFgLlxuICAgICAqXG4gICAgICogSWYgeW91IGZpbmQgeW91cnNlbGYgd2FudGluZyB0byB1c2UgYGltaXRhdGUoKWAgd2l0aCBhXG4gICAgICogTWVtb3J5U3RyZWFtLCB5b3Ugc2hvdWxkIHJld29yayB5b3VyIGNvZGUgYXJvdW5kIGBpbWl0YXRlKClgIHRvIHVzZSBhXG4gICAgICogU3RyZWFtIGluc3RlYWQuIExvb2sgZm9yIHRoZSBzdHJlYW0gaW4gdGhlIGNpcmN1bGFyIGRlcGVuZGVuY3kgdGhhdFxuICAgICAqIHJlcHJlc2VudHMgYW4gZXZlbnQgc3RyZWFtLCBhbmQgdGhhdCB3b3VsZCBiZSBhIGNhbmRpZGF0ZSBmb3IgY3JlYXRpbmcgYVxuICAgICAqIHByb3h5IFN0cmVhbSB3aGljaCB0aGVuIGltaXRhdGVzIHRoZSB0YXJnZXQgU3RyZWFtLlxuICAgICAqXG4gICAgICogQHBhcmFtIHtTdHJlYW19IHRhcmdldCBUaGUgb3RoZXIgc3RyZWFtIHRvIGltaXRhdGUgb24gdGhlIGN1cnJlbnQgb25lLiBNdXN0XG4gICAgICogbm90IGJlIGEgTWVtb3J5U3RyZWFtLlxuICAgICAqL1xuICAgIFN0cmVhbS5wcm90b3R5cGUuaW1pdGF0ZSA9IGZ1bmN0aW9uICh0YXJnZXQpIHtcbiAgICAgICAgaWYgKHRhcmdldCBpbnN0YW5jZW9mIE1lbW9yeVN0cmVhbSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIE1lbW9yeVN0cmVhbSB3YXMgZ2l2ZW4gdG8gaW1pdGF0ZSgpLCBidXQgaXQgb25seSAnICtcbiAgICAgICAgICAgICAgICAnc3VwcG9ydHMgYSBTdHJlYW0uIFJlYWQgbW9yZSBhYm91dCB0aGlzIHJlc3RyaWN0aW9uIGhlcmU6ICcgK1xuICAgICAgICAgICAgICAgICdodHRwczovL2dpdGh1Yi5jb20vc3RhbHR6L3hzdHJlYW0jZmFxJyk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5fdGFyZ2V0ID0gdGFyZ2V0O1xuICAgICAgICBmb3IgKHZhciBpbHMgPSB0aGlzLl9pbHMsIE4gPSBpbHMubGVuZ3RoLCBpID0gMDsgaSA8IE47IGkrKykge1xuICAgICAgICAgICAgdGFyZ2V0Ll9hZGQoaWxzW2ldKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLl9pbHMgPSBbXTtcbiAgICB9O1xuICAgIC8qKlxuICAgICAqIEZvcmNlcyB0aGUgU3RyZWFtIHRvIGVtaXQgdGhlIGdpdmVuIHZhbHVlIHRvIGl0cyBsaXN0ZW5lcnMuXG4gICAgICpcbiAgICAgKiBBcyB0aGUgbmFtZSBpbmRpY2F0ZXMsIGlmIHlvdSB1c2UgdGhpcywgeW91IGFyZSBtb3N0IGxpa2VseSBkb2luZyBzb21ldGhpbmdcbiAgICAgKiBUaGUgV3JvbmcgV2F5LiBQbGVhc2UgdHJ5IHRvIHVuZGVyc3RhbmQgdGhlIHJlYWN0aXZlIHdheSBiZWZvcmUgdXNpbmcgdGhpc1xuICAgICAqIG1ldGhvZC4gVXNlIGl0IG9ubHkgd2hlbiB5b3Uga25vdyB3aGF0IHlvdSBhcmUgZG9pbmcuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIFwibmV4dFwiIHZhbHVlIHlvdSB3YW50IHRvIGJyb2FkY2FzdCB0byBhbGwgbGlzdGVuZXJzIG9mXG4gICAgICogdGhpcyBTdHJlYW0uXG4gICAgICovXG4gICAgU3RyZWFtLnByb3RvdHlwZS5zaGFtZWZ1bGx5U2VuZE5leHQgPSBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fbih2YWx1ZSk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBGb3JjZXMgdGhlIFN0cmVhbSB0byBlbWl0IHRoZSBnaXZlbiBlcnJvciB0byBpdHMgbGlzdGVuZXJzLlxuICAgICAqXG4gICAgICogQXMgdGhlIG5hbWUgaW5kaWNhdGVzLCBpZiB5b3UgdXNlIHRoaXMsIHlvdSBhcmUgbW9zdCBsaWtlbHkgZG9pbmcgc29tZXRoaW5nXG4gICAgICogVGhlIFdyb25nIFdheS4gUGxlYXNlIHRyeSB0byB1bmRlcnN0YW5kIHRoZSByZWFjdGl2ZSB3YXkgYmVmb3JlIHVzaW5nIHRoaXNcbiAgICAgKiBtZXRob2QuIFVzZSBpdCBvbmx5IHdoZW4geW91IGtub3cgd2hhdCB5b3UgYXJlIGRvaW5nLlxuICAgICAqXG4gICAgICogQHBhcmFtIHthbnl9IGVycm9yIFRoZSBlcnJvciB5b3Ugd2FudCB0byBicm9hZGNhc3QgdG8gYWxsIHRoZSBsaXN0ZW5lcnMgb2ZcbiAgICAgKiB0aGlzIFN0cmVhbS5cbiAgICAgKi9cbiAgICBTdHJlYW0ucHJvdG90eXBlLnNoYW1lZnVsbHlTZW5kRXJyb3IgPSBmdW5jdGlvbiAoZXJyb3IpIHtcbiAgICAgICAgdGhpcy5fZShlcnJvcik7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBGb3JjZXMgdGhlIFN0cmVhbSB0byBlbWl0IHRoZSBcImNvbXBsZXRlZFwiIGV2ZW50IHRvIGl0cyBsaXN0ZW5lcnMuXG4gICAgICpcbiAgICAgKiBBcyB0aGUgbmFtZSBpbmRpY2F0ZXMsIGlmIHlvdSB1c2UgdGhpcywgeW91IGFyZSBtb3N0IGxpa2VseSBkb2luZyBzb21ldGhpbmdcbiAgICAgKiBUaGUgV3JvbmcgV2F5LiBQbGVhc2UgdHJ5IHRvIHVuZGVyc3RhbmQgdGhlIHJlYWN0aXZlIHdheSBiZWZvcmUgdXNpbmcgdGhpc1xuICAgICAqIG1ldGhvZC4gVXNlIGl0IG9ubHkgd2hlbiB5b3Uga25vdyB3aGF0IHlvdSBhcmUgZG9pbmcuXG4gICAgICovXG4gICAgU3RyZWFtLnByb3RvdHlwZS5zaGFtZWZ1bGx5U2VuZENvbXBsZXRlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLl9jKCk7XG4gICAgfTtcbiAgICAvKipcbiAgICAgKiBCbGVuZHMgbXVsdGlwbGUgc3RyZWFtcyB0b2dldGhlciwgZW1pdHRpbmcgZXZlbnRzIGZyb20gYWxsIG9mIHRoZW1cbiAgICAgKiBjb25jdXJyZW50bHkuXG4gICAgICpcbiAgICAgKiAqbWVyZ2UqIHRha2VzIG11bHRpcGxlIHN0cmVhbXMgYXMgYXJndW1lbnRzLCBhbmQgY3JlYXRlcyBhIHN0cmVhbSB0aGF0XG4gICAgICogYmVoYXZlcyBsaWtlIGVhY2ggb2YgdGhlIGFyZ3VtZW50IHN0cmVhbXMsIGluIHBhcmFsbGVsLlxuICAgICAqXG4gICAgICogTWFyYmxlIGRpYWdyYW06XG4gICAgICpcbiAgICAgKiBgYGB0ZXh0XG4gICAgICogLS0xLS0tLTItLS0tLTMtLS0tLS0tLTQtLS1cbiAgICAgKiAtLS0tYS0tLS0tYi0tLS1jLS0tZC0tLS0tLVxuICAgICAqICAgICAgICAgICAgbWVyZ2VcbiAgICAgKiAtLTEtYS0tMi0tYi0tMy1jLS0tZC0tNC0tLVxuICAgICAqIGBgYFxuICAgICAqXG4gICAgICogQGZhY3RvcnkgdHJ1ZVxuICAgICAqIEBwYXJhbSB7U3RyZWFtfSBzdHJlYW0xIEEgc3RyZWFtIHRvIG1lcmdlIHRvZ2V0aGVyIHdpdGggb3RoZXIgc3RyZWFtcy5cbiAgICAgKiBAcGFyYW0ge1N0cmVhbX0gc3RyZWFtMiBBIHN0cmVhbSB0byBtZXJnZSB0b2dldGhlciB3aXRoIG90aGVyIHN0cmVhbXMuIFR3b1xuICAgICAqIG9yIG1vcmUgc3RyZWFtcyBtYXkgYmUgZ2l2ZW4gYXMgYXJndW1lbnRzLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0ubWVyZ2UgPSBmdW5jdGlvbiBtZXJnZSgpIHtcbiAgICAgICAgdmFyIHN0cmVhbXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgICAgIHN0cmVhbXNbX2kgLSAwXSA9IGFyZ3VtZW50c1tfaV07XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5ldyBTdHJlYW0obmV3IE1lcmdlUHJvZHVjZXIoc3RyZWFtcykpO1xuICAgIH07XG4gICAgLyoqXG4gICAgICogQ29tYmluZXMgbXVsdGlwbGUgaW5wdXQgc3RyZWFtcyB0b2dldGhlciB0byByZXR1cm4gYSBzdHJlYW0gd2hvc2UgZXZlbnRzXG4gICAgICogYXJlIGFycmF5cyB0aGF0IGNvbGxlY3QgdGhlIGxhdGVzdCBldmVudHMgZnJvbSBlYWNoIGlucHV0IHN0cmVhbS5cbiAgICAgKlxuICAgICAqICpjb21iaW5lKiBpbnRlcm5hbGx5IHJlbWVtYmVycyB0aGUgbW9zdCByZWNlbnQgZXZlbnQgZnJvbSBlYWNoIG9mIHRoZSBpbnB1dFxuICAgICAqIHN0cmVhbXMuIFdoZW4gYW55IG9mIHRoZSBpbnB1dCBzdHJlYW1zIGVtaXRzIGFuIGV2ZW50LCB0aGF0IGV2ZW50IHRvZ2V0aGVyXG4gICAgICogd2l0aCBhbGwgdGhlIG90aGVyIHNhdmVkIGV2ZW50cyBhcmUgY29tYmluZWQgaW50byBhbiBhcnJheS4gVGhhdCBhcnJheSB3aWxsXG4gICAgICogYmUgZW1pdHRlZCBvbiB0aGUgb3V0cHV0IHN0cmVhbS4gSXQncyBlc3NlbnRpYWxseSBhIHdheSBvZiBqb2luaW5nIHRvZ2V0aGVyXG4gICAgICogdGhlIGV2ZW50cyBmcm9tIG11bHRpcGxlIHN0cmVhbXMuXG4gICAgICpcbiAgICAgKiBNYXJibGUgZGlhZ3JhbTpcbiAgICAgKlxuICAgICAqIGBgYHRleHRcbiAgICAgKiAtLTEtLS0tMi0tLS0tMy0tLS0tLS0tNC0tLVxuICAgICAqIC0tLS1hLS0tLS1iLS0tLS1jLS1kLS0tLS0tXG4gICAgICogICAgICAgICAgY29tYmluZVxuICAgICAqIC0tLS0xYS0yYS0yYi0zYi0zYy0zZC00ZC0tXG4gICAgICogYGBgXG4gICAgICpcbiAgICAgKiBAZmFjdG9yeSB0cnVlXG4gICAgICogQHBhcmFtIHtTdHJlYW19IHN0cmVhbTEgQSBzdHJlYW0gdG8gY29tYmluZSB0b2dldGhlciB3aXRoIG90aGVyIHN0cmVhbXMuXG4gICAgICogQHBhcmFtIHtTdHJlYW19IHN0cmVhbTIgQSBzdHJlYW0gdG8gY29tYmluZSB0b2dldGhlciB3aXRoIG90aGVyIHN0cmVhbXMuXG4gICAgICogTXVsdGlwbGUgc3RyZWFtcywgbm90IGp1c3QgdHdvLCBtYXkgYmUgZ2l2ZW4gYXMgYXJndW1lbnRzLlxuICAgICAqIEByZXR1cm4ge1N0cmVhbX1cbiAgICAgKi9cbiAgICBTdHJlYW0uY29tYmluZSA9IGZ1bmN0aW9uIGNvbWJpbmUoKSB7XG4gICAgICAgIHZhciBzdHJlYW1zID0gW107XG4gICAgICAgIGZvciAodmFyIF9pID0gMDsgX2kgPCBhcmd1bWVudHMubGVuZ3RoOyBfaSsrKSB7XG4gICAgICAgICAgICBzdHJlYW1zW19pIC0gMF0gPSBhcmd1bWVudHNbX2ldO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgU3RyZWFtKG5ldyBDb21iaW5lUHJvZHVjZXIoc3RyZWFtcykpO1xuICAgIH07XG4gICAgcmV0dXJuIFN0cmVhbTtcbn0oKSk7XG5leHBvcnRzLlN0cmVhbSA9IFN0cmVhbTtcbnZhciBNZW1vcnlTdHJlYW0gPSAoZnVuY3Rpb24gKF9zdXBlcikge1xuICAgIF9fZXh0ZW5kcyhNZW1vcnlTdHJlYW0sIF9zdXBlcik7XG4gICAgZnVuY3Rpb24gTWVtb3J5U3RyZWFtKHByb2R1Y2VyKSB7XG4gICAgICAgIF9zdXBlci5jYWxsKHRoaXMsIHByb2R1Y2VyKTtcbiAgICAgICAgdGhpcy5faGFzID0gZmFsc2U7XG4gICAgfVxuICAgIE1lbW9yeVN0cmVhbS5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAoeCkge1xuICAgICAgICB0aGlzLl92ID0geDtcbiAgICAgICAgdGhpcy5faGFzID0gdHJ1ZTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5fbi5jYWxsKHRoaXMsIHgpO1xuICAgIH07XG4gICAgTWVtb3J5U3RyZWFtLnByb3RvdHlwZS5fYWRkID0gZnVuY3Rpb24gKGlsKSB7XG4gICAgICAgIGlmICh0aGlzLl9oYXMpIHtcbiAgICAgICAgICAgIGlsLl9uKHRoaXMuX3YpO1xuICAgICAgICB9XG4gICAgICAgIF9zdXBlci5wcm90b3R5cGUuX2FkZC5jYWxsKHRoaXMsIGlsKTtcbiAgICB9O1xuICAgIE1lbW9yeVN0cmVhbS5wcm90b3R5cGUuX3N0b3BOb3cgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgIHRoaXMuX2hhcyA9IGZhbHNlO1xuICAgICAgICBfc3VwZXIucHJvdG90eXBlLl9zdG9wTm93LmNhbGwodGhpcyk7XG4gICAgfTtcbiAgICBNZW1vcnlTdHJlYW0ucHJvdG90eXBlLl94ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLl9oYXMgPSBmYWxzZTtcbiAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5feC5jYWxsKHRoaXMpO1xuICAgIH07XG4gICAgTWVtb3J5U3RyZWFtLnByb3RvdHlwZS5tYXAgPSBmdW5jdGlvbiAocHJvamVjdCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fbWFwKHByb2plY3QpO1xuICAgIH07XG4gICAgTWVtb3J5U3RyZWFtLnByb3RvdHlwZS5tYXBUbyA9IGZ1bmN0aW9uIChwcm9qZWN0ZWRWYWx1ZSkge1xuICAgICAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5tYXBUby5jYWxsKHRoaXMsIHByb2plY3RlZFZhbHVlKTtcbiAgICB9O1xuICAgIE1lbW9yeVN0cmVhbS5wcm90b3R5cGUudGFrZSA9IGZ1bmN0aW9uIChhbW91bnQpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlci5wcm90b3R5cGUudGFrZS5jYWxsKHRoaXMsIGFtb3VudCk7XG4gICAgfTtcbiAgICBNZW1vcnlTdHJlYW0ucHJvdG90eXBlLmVuZFdoZW4gPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlci5wcm90b3R5cGUuZW5kV2hlbi5jYWxsKHRoaXMsIG90aGVyKTtcbiAgICB9O1xuICAgIE1lbW9yeVN0cmVhbS5wcm90b3R5cGUucmVwbGFjZUVycm9yID0gZnVuY3Rpb24gKHJlcGxhY2UpIHtcbiAgICAgICAgcmV0dXJuIF9zdXBlci5wcm90b3R5cGUucmVwbGFjZUVycm9yLmNhbGwodGhpcywgcmVwbGFjZSk7XG4gICAgfTtcbiAgICBNZW1vcnlTdHJlYW0ucHJvdG90eXBlLnJlbWVtYmVyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9O1xuICAgIE1lbW9yeVN0cmVhbS5wcm90b3R5cGUuZGVidWcgPSBmdW5jdGlvbiAobGFiZWxPclNweSkge1xuICAgICAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5kZWJ1Zy5jYWxsKHRoaXMsIGxhYmVsT3JTcHkpO1xuICAgIH07XG4gICAgcmV0dXJuIE1lbW9yeVN0cmVhbTtcbn0oU3RyZWFtKSk7XG5leHBvcnRzLk1lbW9yeVN0cmVhbSA9IE1lbW9yeVN0cmVhbTtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZGVmYXVsdCA9IFN0cmVhbTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWNvcmUuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgY29yZV8xID0gcmVxdWlyZSgnLi4vY29yZScpO1xudmFyIENvbmNhdFByb2R1Y2VyID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBDb25jYXRQcm9kdWNlcihzdHJlYW1zKSB7XG4gICAgICAgIHRoaXMuc3RyZWFtcyA9IHN0cmVhbXM7XG4gICAgICAgIHRoaXMudHlwZSA9ICdjb25jYXQnO1xuICAgICAgICB0aGlzLm91dCA9IG51bGw7XG4gICAgICAgIHRoaXMuaSA9IDA7XG4gICAgfVxuICAgIENvbmNhdFByb2R1Y2VyLnByb3RvdHlwZS5fc3RhcnQgPSBmdW5jdGlvbiAob3V0KSB7XG4gICAgICAgIHRoaXMub3V0ID0gb3V0O1xuICAgICAgICB0aGlzLnN0cmVhbXNbdGhpcy5pXS5fYWRkKHRoaXMpO1xuICAgIH07XG4gICAgQ29uY2F0UHJvZHVjZXIucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgc3RyZWFtcyA9IHRoaXMuc3RyZWFtcztcbiAgICAgICAgaWYgKHRoaXMuaSA8IHN0cmVhbXMubGVuZ3RoKSB7XG4gICAgICAgICAgICBzdHJlYW1zW3RoaXMuaV0uX3JlbW92ZSh0aGlzKTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmkgPSAwO1xuICAgICAgICB0aGlzLm91dCA9IG51bGw7XG4gICAgfTtcbiAgICBDb25jYXRQcm9kdWNlci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAoIXUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHUuX24odCk7XG4gICAgfTtcbiAgICBDb25jYXRQcm9kdWNlci5wcm90b3R5cGUuX2UgPSBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdS5fZShlcnIpO1xuICAgIH07XG4gICAgQ29uY2F0UHJvZHVjZXIucHJvdG90eXBlLl9jID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAoIXUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHZhciBzdHJlYW1zID0gdGhpcy5zdHJlYW1zO1xuICAgICAgICBzdHJlYW1zW3RoaXMuaV0uX3JlbW92ZSh0aGlzKTtcbiAgICAgICAgaWYgKCsrdGhpcy5pIDwgc3RyZWFtcy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHN0cmVhbXNbdGhpcy5pXS5fYWRkKHRoaXMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgdS5fYygpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICByZXR1cm4gQ29uY2F0UHJvZHVjZXI7XG59KCkpO1xuLyoqXG4gKiBQdXRzIG9uZSBzdHJlYW0gYWZ0ZXIgdGhlIG90aGVyLiAqY29uY2F0KiBpcyBhIGZhY3RvcnkgdGhhdCB0YWtlcyBtdWx0aXBsZVxuICogc3RyZWFtcyBhcyBhcmd1bWVudHMsIGFuZCBzdGFydHMgdGhlIGBuKzFgLXRoIHN0cmVhbSBvbmx5IHdoZW4gdGhlIGBuYC10aFxuICogc3RyZWFtIGhhcyBjb21wbGV0ZWQuIEl0IGNvbmNhdGVuYXRlcyB0aG9zZSBzdHJlYW1zIHRvZ2V0aGVyLlxuICpcbiAqIE1hcmJsZSBkaWFncmFtOlxuICpcbiAqIGBgYHRleHRcbiAqIC0tMS0tMi0tLTMtLS00LXxcbiAqIC4uLi4uLi4uLi4uLi4uLi0tYS1iLWMtLWQtfFxuICogICAgICAgICAgIGNvbmNhdFxuICogLS0xLS0yLS0tMy0tLTQtLS1hLWItYy0tZC18XG4gKiBgYGBcbiAqXG4gKiBFeGFtcGxlOlxuICpcbiAqIGBgYGpzXG4gKiBpbXBvcnQgY29uY2F0IGZyb20gJ3hzdHJlYW0vZXh0cmEvY29uY2F0J1xuICpcbiAqIGNvbnN0IHN0cmVhbUEgPSB4cy5vZignYScsICdiJywgJ2MnKVxuICogY29uc3Qgc3RyZWFtQiA9IHhzLm9mKDEwLCAyMCwgMzApXG4gKiBjb25zdCBzdHJlYW1DID0geHMub2YoJ1gnLCAnWScsICdaJylcbiAqXG4gKiBjb25zdCBvdXRwdXRTdHJlYW0gPSBjb25jYXQoc3RyZWFtQSwgc3RyZWFtQiwgc3RyZWFtQylcbiAqXG4gKiBvdXRwdXRTdHJlYW0uYWRkTGlzdGVuZXIoe1xuICogICBuZXh0OiAoeCkgPT4gY29uc29sZS5sb2coeCksXG4gKiAgIGVycm9yOiAoZXJyKSA9PiBjb25zb2xlLmVycm9yKGVyciksXG4gKiAgIGNvbXBsZXRlOiAoKSA9PiBjb25zb2xlLmxvZygnY29uY2F0IGNvbXBsZXRlZCcpLFxuICogfSlcbiAqIGBgYFxuICpcbiAqIEBmYWN0b3J5IHRydWVcbiAqIEBwYXJhbSB7U3RyZWFtfSBzdHJlYW0xIEEgc3RyZWFtIHRvIGNvbmNhdGVuYXRlIHRvZ2V0aGVyIHdpdGggb3RoZXIgc3RyZWFtcy5cbiAqIEBwYXJhbSB7U3RyZWFtfSBzdHJlYW0yIEEgc3RyZWFtIHRvIGNvbmNhdGVuYXRlIHRvZ2V0aGVyIHdpdGggb3RoZXIgc3RyZWFtcy4gVHdvXG4gKiBvciBtb3JlIHN0cmVhbXMgbWF5IGJlIGdpdmVuIGFzIGFyZ3VtZW50cy5cbiAqIEByZXR1cm4ge1N0cmVhbX1cbiAqL1xuZnVuY3Rpb24gY29uY2F0KCkge1xuICAgIHZhciBzdHJlYW1zID0gW107XG4gICAgZm9yICh2YXIgX2kgPSAwOyBfaSA8IGFyZ3VtZW50cy5sZW5ndGg7IF9pKyspIHtcbiAgICAgICAgc3RyZWFtc1tfaSAtIDBdID0gYXJndW1lbnRzW19pXTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBjb3JlXzEuU3RyZWFtKG5ldyBDb25jYXRQcm9kdWNlcihzdHJlYW1zKSk7XG59XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmRlZmF1bHQgPSBjb25jYXQ7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1jb25jYXQuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgY29yZV8xID0gcmVxdWlyZSgnLi4vY29yZScpO1xudmFyIERlbGF5T3BlcmF0b3IgPSAoZnVuY3Rpb24gKCkge1xuICAgIGZ1bmN0aW9uIERlbGF5T3BlcmF0b3IoZHQsIGlucykge1xuICAgICAgICB0aGlzLmR0ID0gZHQ7XG4gICAgICAgIHRoaXMuaW5zID0gaW5zO1xuICAgICAgICB0aGlzLnR5cGUgPSAnZGVsYXknO1xuICAgICAgICB0aGlzLm91dCA9IG51bGw7XG4gICAgfVxuICAgIERlbGF5T3BlcmF0b3IucHJvdG90eXBlLl9zdGFydCA9IGZ1bmN0aW9uIChvdXQpIHtcbiAgICAgICAgdGhpcy5vdXQgPSBvdXQ7XG4gICAgICAgIHRoaXMuaW5zLl9hZGQodGhpcyk7XG4gICAgfTtcbiAgICBEZWxheU9wZXJhdG9yLnByb3RvdHlwZS5fc3RvcCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdGhpcy5pbnMuX3JlbW92ZSh0aGlzKTtcbiAgICAgICAgdGhpcy5vdXQgPSBudWxsO1xuICAgIH07XG4gICAgRGVsYXlPcGVyYXRvci5wcm90b3R5cGUuX24gPSBmdW5jdGlvbiAodCkge1xuICAgICAgICB2YXIgdSA9IHRoaXMub3V0O1xuICAgICAgICBpZiAoIXUpXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIHZhciBpZCA9IHNldEludGVydmFsKGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHUuX24odCk7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKGlkKTtcbiAgICAgICAgfSwgdGhpcy5kdCk7XG4gICAgfTtcbiAgICBEZWxheU9wZXJhdG9yLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB2YXIgaWQgPSBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB1Ll9lKGVycik7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKGlkKTtcbiAgICAgICAgfSwgdGhpcy5kdCk7XG4gICAgfTtcbiAgICBEZWxheU9wZXJhdG9yLnByb3RvdHlwZS5fYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB2YXIgaWQgPSBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB1Ll9jKCk7XG4gICAgICAgICAgICBjbGVhckludGVydmFsKGlkKTtcbiAgICAgICAgfSwgdGhpcy5kdCk7XG4gICAgfTtcbiAgICByZXR1cm4gRGVsYXlPcGVyYXRvcjtcbn0oKSk7XG4vKipcbiAqIERlbGF5cyBwZXJpb2RpYyBldmVudHMgYnkgYSBnaXZlbiB0aW1lIHBlcmlvZC5cbiAqXG4gKiBNYXJibGUgZGlhZ3JhbTpcbiAqXG4gKiBgYGB0ZXh0XG4gKiAxLS0tLTItLTMtLTQtLS0tNXxcbiAqICAgICBkZWxheSg2MClcbiAqIC0tLTEtLS0tMi0tMy0tNC0tLS01fFxuICogYGBgXG4gKlxuICogRXhhbXBsZTpcbiAqXG4gKiBgYGBqc1xuICogaW1wb3J0IGZyb21EaWFncmFtIGZyb20gJ3hzdHJlYW0vZXh0cmEvZnJvbURpYWdyYW0nXG4gKiBpbXBvcnQgZGVsYXkgZnJvbSAneHN0cmVhbS9leHRyYS9kZWxheSdcbiAqXG4gKiBjb25zdCBzdHJlYW0gPSBmcm9tRGlhZ3JhbSgnMS0tLS0yLS0zLS00LS0tLTV8JylcbiAqICAuY29tcG9zZShkZWxheSg2MCkpXG4gKlxuICogc3RyZWFtLmFkZExpc3RlbmVyKHtcbiAqICAgbmV4dDogaSA9PiBjb25zb2xlLmxvZyhpKSxcbiAqICAgZXJyb3I6IGVyciA9PiBjb25zb2xlLmVycm9yKGVyciksXG4gKiAgIGNvbXBsZXRlOiAoKSA9PiBjb25zb2xlLmxvZygnY29tcGxldGVkJylcbiAqIH0pXG4gKiBgYGBcbiAqXG4gKiBgYGB0ZXh0XG4gKiA+IDEgIChhZnRlciA2MCBtcylcbiAqID4gMiAgKGFmdGVyIDE2MCBtcylcbiAqID4gMyAgKGFmdGVyIDIyMCBtcylcbiAqID4gNCAgKGFmdGVyIDI4MCBtcylcbiAqID4gNSAgKGFmdGVyIDM4MCBtcylcbiAqID4gY29tcGxldGVkXG4gKiBgYGBcbiAqXG4gKiBAcGFyYW0ge251bWJlcn0gcGVyaW9kIFRoZSBhbW91bnQgb2Ygc2lsZW5jZSByZXF1aXJlZCBpbiBtaWxsaXNlY29uZHMuXG4gKiBAcmV0dXJuIHtTdHJlYW19XG4gKi9cbmZ1bmN0aW9uIGRlbGF5KHBlcmlvZCkge1xuICAgIHJldHVybiBmdW5jdGlvbiBkZWxheU9wZXJhdG9yKGlucykge1xuICAgICAgICByZXR1cm4gbmV3IGNvcmVfMS5TdHJlYW0obmV3IERlbGF5T3BlcmF0b3IocGVyaW9kLCBpbnMpKTtcbiAgICB9O1xufVxuT2JqZWN0LmRlZmluZVByb3BlcnR5KGV4cG9ydHMsIFwiX19lc01vZHVsZVwiLCB7IHZhbHVlOiB0cnVlIH0pO1xuZXhwb3J0cy5kZWZhdWx0ID0gZGVsYXk7XG4vLyMgc291cmNlTWFwcGluZ1VSTD1kZWxheS5qcy5tYXAiLCJcInVzZSBzdHJpY3RcIjtcbnZhciBjb3JlXzEgPSByZXF1aXJlKCcuLi9jb3JlJyk7XG52YXIgZW1wdHkgPSB7fTtcbnZhciBEcm9wUmVwZWF0c09wZXJhdG9yID0gKGZ1bmN0aW9uICgpIHtcbiAgICBmdW5jdGlvbiBEcm9wUmVwZWF0c09wZXJhdG9yKGZuLCBpbnMpIHtcbiAgICAgICAgdGhpcy5mbiA9IGZuO1xuICAgICAgICB0aGlzLmlucyA9IGlucztcbiAgICAgICAgdGhpcy50eXBlID0gJ2Ryb3BSZXBlYXRzJztcbiAgICAgICAgdGhpcy5vdXQgPSBudWxsO1xuICAgICAgICB0aGlzLnYgPSBlbXB0eTtcbiAgICB9XG4gICAgRHJvcFJlcGVhdHNPcGVyYXRvci5wcm90b3R5cGUuX3N0YXJ0ID0gZnVuY3Rpb24gKG91dCkge1xuICAgICAgICB0aGlzLm91dCA9IG91dDtcbiAgICAgICAgdGhpcy5pbnMuX2FkZCh0aGlzKTtcbiAgICB9O1xuICAgIERyb3BSZXBlYXRzT3BlcmF0b3IucHJvdG90eXBlLl9zdG9wID0gZnVuY3Rpb24gKCkge1xuICAgICAgICB0aGlzLmlucy5fcmVtb3ZlKHRoaXMpO1xuICAgICAgICB0aGlzLm91dCA9IG51bGw7XG4gICAgICAgIHRoaXMudiA9IGVtcHR5O1xuICAgIH07XG4gICAgRHJvcFJlcGVhdHNPcGVyYXRvci5wcm90b3R5cGUuaXNFcSA9IGZ1bmN0aW9uICh4LCB5KSB7XG4gICAgICAgIHJldHVybiB0aGlzLmZuID8gdGhpcy5mbih4LCB5KSA6IHggPT09IHk7XG4gICAgfTtcbiAgICBEcm9wUmVwZWF0c09wZXJhdG9yLnByb3RvdHlwZS5fbiA9IGZ1bmN0aW9uICh0KSB7XG4gICAgICAgIHZhciB1ID0gdGhpcy5vdXQ7XG4gICAgICAgIGlmICghdSlcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgdmFyIHYgPSB0aGlzLnY7XG4gICAgICAgIGlmICh2ID09PSBlbXB0eSB8fCAhdGhpcy5pc0VxKHQsIHYpKSB7XG4gICAgICAgICAgICB1Ll9uKHQpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMudiA9IHQ7XG4gICAgfTtcbiAgICBEcm9wUmVwZWF0c09wZXJhdG9yLnByb3RvdHlwZS5fZSA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9lKGVycik7XG4gICAgfTtcbiAgICBEcm9wUmVwZWF0c09wZXJhdG9yLnByb3RvdHlwZS5fYyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgdmFyIHUgPSB0aGlzLm91dDtcbiAgICAgICAgaWYgKCF1KVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB1Ll9jKCk7XG4gICAgfTtcbiAgICByZXR1cm4gRHJvcFJlcGVhdHNPcGVyYXRvcjtcbn0oKSk7XG5leHBvcnRzLkRyb3BSZXBlYXRzT3BlcmF0b3IgPSBEcm9wUmVwZWF0c09wZXJhdG9yO1xuLyoqXG4gKiBEcm9wcyBjb25zZWN1dGl2ZSBkdXBsaWNhdGUgdmFsdWVzIGluIGEgc3RyZWFtLlxuICpcbiAqIE1hcmJsZSBkaWFncmFtOlxuICpcbiAqIGBgYHRleHRcbiAqIC0tMS0tMi0tMS0tMS0tMS0tMi0tMy0tNC0tMy0tM3xcbiAqICAgICBkcm9wUmVwZWF0c1xuICogLS0xLS0yLS0xLS0tLS0tLS0yLS0zLS00LS0zLS0tfFxuICogYGBgXG4gKlxuICogRXhhbXBsZTpcbiAqXG4gKiBgYGBqc1xuICogaW1wb3J0IGRyb3BSZXBlYXRzIGZyb20gJ3hzdHJlYW0vZXh0cmEvZHJvcFJlcGVhdHMnXG4gKlxuICogY29uc3Qgc3RyZWFtID0geHMub2YoMSwgMiwgMSwgMSwgMSwgMiwgMywgNCwgMywgMylcbiAqICAgLmNvbXBvc2UoZHJvcFJlcGVhdHMoKSlcbiAqXG4gKiBzdHJlYW0uYWRkTGlzdGVuZXIoe1xuICogICBuZXh0OiBpID0+IGNvbnNvbGUubG9nKGkpLFxuICogICBlcnJvcjogZXJyID0+IGNvbnNvbGUuZXJyb3IoZXJyKSxcbiAqICAgY29tcGxldGU6ICgpID0+IGNvbnNvbGUubG9nKCdjb21wbGV0ZWQnKVxuICogfSlcbiAqIGBgYFxuICpcbiAqIGBgYHRleHRcbiAqID4gMVxuICogPiAyXG4gKiA+IDFcbiAqID4gMlxuICogPiAzXG4gKiA+IDRcbiAqID4gM1xuICogPiBjb21wbGV0ZWRcbiAqIGBgYFxuICpcbiAqIEV4YW1wbGUgd2l0aCBhIGN1c3RvbSBpc0VxdWFsIGZ1bmN0aW9uOlxuICpcbiAqIGBgYGpzXG4gKiBpbXBvcnQgZHJvcFJlcGVhdHMgZnJvbSAneHN0cmVhbS9leHRyYS9kcm9wUmVwZWF0cydcbiAqXG4gKiBjb25zdCBzdHJlYW0gPSB4cy5vZignYScsICdiJywgJ2EnLCAnQScsICdCJywgJ2InKVxuICogICAuY29tcG9zZShkcm9wUmVwZWF0cygoeCwgeSkgPT4geC50b0xvd2VyQ2FzZSgpID09PSB5LnRvTG93ZXJDYXNlKCkpKVxuICpcbiAqIHN0cmVhbS5hZGRMaXN0ZW5lcih7XG4gKiAgIG5leHQ6IGkgPT4gY29uc29sZS5sb2coaSksXG4gKiAgIGVycm9yOiBlcnIgPT4gY29uc29sZS5lcnJvcihlcnIpLFxuICogICBjb21wbGV0ZTogKCkgPT4gY29uc29sZS5sb2coJ2NvbXBsZXRlZCcpXG4gKiB9KVxuICogYGBgXG4gKlxuICogYGBgdGV4dFxuICogPiBhXG4gKiA+IGJcbiAqID4gYVxuICogPiBCXG4gKiA+IGNvbXBsZXRlZFxuICogYGBgXG4gKlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXNFcXVhbCBBbiBvcHRpb25hbCBmdW5jdGlvbiBvZiB0eXBlXG4gKiBgKHg6IFQsIHk6IFQpID0+IGJvb2xlYW5gIHRoYXQgdGFrZXMgYW4gZXZlbnQgZnJvbSB0aGUgaW5wdXQgc3RyZWFtIGFuZFxuICogY2hlY2tzIGlmIGl0IGlzIGVxdWFsIHRvIHByZXZpb3VzIGV2ZW50LCBieSByZXR1cm5pbmcgYSBib29sZWFuLlxuICogQHJldHVybiB7U3RyZWFtfVxuICovXG5mdW5jdGlvbiBkcm9wUmVwZWF0cyhpc0VxdWFsKSB7XG4gICAgaWYgKGlzRXF1YWwgPT09IHZvaWQgMCkgeyBpc0VxdWFsID0gbnVsbDsgfVxuICAgIHJldHVybiBmdW5jdGlvbiBkcm9wUmVwZWF0c09wZXJhdG9yKGlucykge1xuICAgICAgICByZXR1cm4gbmV3IGNvcmVfMS5TdHJlYW0obmV3IERyb3BSZXBlYXRzT3BlcmF0b3IoaXNFcXVhbCwgaW5zKSk7XG4gICAgfTtcbn1cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbmV4cG9ydHMuZGVmYXVsdCA9IGRyb3BSZXBlYXRzO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9ZHJvcFJlcGVhdHMuanMubWFwIiwiXCJ1c2Ugc3RyaWN0XCI7XG52YXIgY29yZV8xID0gcmVxdWlyZSgnLi9jb3JlJyk7XG5leHBvcnRzLlN0cmVhbSA9IGNvcmVfMS5TdHJlYW07XG5leHBvcnRzLk1lbW9yeVN0cmVhbSA9IGNvcmVfMS5NZW1vcnlTdHJlYW07XG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZXhwb3J0cywgXCJfX2VzTW9kdWxlXCIsIHsgdmFsdWU6IHRydWUgfSk7XG5leHBvcnRzLmRlZmF1bHQgPSBjb3JlXzEuU3RyZWFtO1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9aW5kZXguanMubWFwIiwiaW1wb3J0IHtydW59IGZyb20gJ0BjeWNsZS94c3RyZWFtLXJ1bic7XG5pbXBvcnQge21ha2VET01Ecml2ZXJ9IGZyb20gJ0BjeWNsZS9kb20nO1xuaW1wb3J0IHttYWtlSGlzdG9yeURyaXZlcn0gZnJvbSAnQGN5Y2xlL2hpc3RvcnknXG5pbXBvcnQge2NyZWF0ZUhpc3Rvcnl9IGZyb20gJ2hpc3RvcnknO1xuaW1wb3J0IHN0b3JhZ2VEcml2ZXIgZnJvbSAnQGN5Y2xlL3N0b3JhZ2UnO1xuLy8gVEhFIE1BSU4gRlVOQ1RJT05cbi8vIFRoaXMgaXMgdGhlIHRvZG8gbGlzdCBjb21wb25lbnQuXG5pbXBvcnQgVGFza0xpc3QgZnJvbSAnLi9jb21wb25lbnRzL1Rhc2tMaXN0L2luZGV4JztcblxuY29uc3QgbWFpbiA9IFRhc2tMaXN0O1xuXG4vLyBUSEUgRU5UUlkgUE9JTlRcbi8vIFRoaXMgaXMgd2hlcmUgdGhlIHdob2xlIHN0b3J5IHN0YXJ0cy5cbi8vIGBydW5gIHJlY2VpdmVzIGEgbWFpbiBmdW5jdGlvbiBhbmQgYW4gb2JqZWN0XG4vLyB3aXRoIHRoZSBkcml2ZXJzLlxucnVuKG1haW4sIHtcbiAgLy8gVEhFIERPTSBEUklWRVJcbiAgLy8gYG1ha2VET01Ecml2ZXIoY29udGFpbmVyKWAgZnJvbSBDeWNsZSBET00gcmV0dXJucyBhXG4gIC8vIGRyaXZlciBmdW5jdGlvbiB0byBpbnRlcmFjdCB3aXRoIHRoZSBET00uXG4gIERPTTogbWFrZURPTURyaXZlcignLnRvZG9hcHAnLCB7dHJhbnNwb3NpdGlvbjogdHJ1ZX0pLFxuICAvLyBUSEUgSElTVE9SWSBEUklWRVJcbiAgLy8gQSBkcml2ZXIgdG8gaW50ZXJhY3Qgd2l0aCBicm93c2VyIGhpc3RvcnlcbiAgSGlzdG9yeTogbWFrZUhpc3RvcnlEcml2ZXIoY3JlYXRlSGlzdG9yeSgpLCB7Y2FwdHVyZTogdHJ1ZX0pLFxuICAvLyBUSEUgU1RPUkFHRSBEUklWRVJcbiAgLy8gVGhlIHN0b3JhZ2UgZHJpdmVyIHdoaWNoIGNhbiBiZSB1c2VkIHRvIGFjY2VzcyB2YWx1ZXMgZm9yXG4gIC8vIGxvY2FsLSBhbmQgc2Vzc2lvblN0b3JhZ2Uga2V5cyBhcyBzdHJlYW1zLlxuICBzdG9yYWdlOiBzdG9yYWdlRHJpdmVyXG59KTtcbiIsImltcG9ydCBpbnRlbnQgZnJvbSAnLi9pbnRlbnQnO1xuaW1wb3J0IG1vZGVsIGZyb20gJy4vbW9kZWwnO1xuaW1wb3J0IHZpZXcgZnJvbSAnLi92aWV3JztcblxuLy8gVEhFIFRPRE8gSVRFTSBGVU5DVElPTlxuLy8gVGhpcyBpcyBhIHNpbXBsZSB0b2RvIGl0ZW0gY29tcG9uZW50LFxuLy8gc3RydWN0dXJlZCB3aXRoIHRoZSBNVkktcGF0dGVybi5cbmZ1bmN0aW9uIFRhc2soc291cmNlcykge1xuICBsZXQgYWN0aW9uJCA9IGludGVudChzb3VyY2VzKTtcbiAgbGV0IHN0YXRlJCA9IG1vZGVsKHNvdXJjZXMucHJvcHMkLCBhY3Rpb24kKTtcbiAgbGV0IHZ0cmVlJCA9IHZpZXcoc3RhdGUkKTtcblxuICByZXR1cm4ge1xuICAgIERPTTogdnRyZWUkLFxuICAgIGFjdGlvbiQsXG4gICAgc3RhdGUkXG4gIH07XG59XG5cbmV4cG9ydCBkZWZhdWx0IFRhc2s7XG4iLCJpbXBvcnQgeHMgZnJvbSAneHN0cmVhbSc7XG5pbXBvcnQge0VOVEVSX0tFWSwgRVNDX0tFWX0gZnJvbSAnLi4vLi4vdXRpbHMnO1xuXG4vLyBUSEUgVE9ETyBJVEVNIElOVEVOVFxuLy8gVGhpcyBpbnRlbnQgZnVuY3Rpb24gcmV0dXJucyBhIHN0cmVhbSBvZiBhbGwgdGhlIGRpZmZlcmVudCxcbi8vIGFjdGlvbnMgdGhhdCBjYW4gYmUgdGFrZW4gb24gYSB0b2RvLlxuZnVuY3Rpb24gaW50ZW50KHNvdXJjZXMpIHtcbiAgLy8gVEhFIElOVEVOVCBNRVJHRVxuICAvLyBNZXJnZSBhbGwgYWN0aW9ucyBpbnRvIG9uZSBzdHJlYW0uXG4gIHJldHVybiB4cy5tZXJnZShcbiAgICAvLyBUSEUgREVTVFJPWSBBQ1RJT04gU1RSRUFNXG4gICAgc291cmNlcy5ET00uc2VsZWN0KCcuZGVzdHJveScpLmV2ZW50cygnY2xpY2snKVxuICAgICAgLm1hcFRvKHt0eXBlOiAnZGVzdHJveSd9KSxcblxuICAgIC8vIFRIRSBUT0dHTEUgQUNUSU9OIFNUUkVBTVxuICAgIHNvdXJjZXMuRE9NLnNlbGVjdCgnLnRvZ2dsZScpLmV2ZW50cygnY2hhbmdlJylcbiAgICAgIC5tYXAoZXYgPT4gZXYudGFyZ2V0LmNoZWNrZWQpXG4gICAgICAubWFwKHBheWxvYWQgPT4gKHt0eXBlOiAndG9nZ2xlJywgcGF5bG9hZH0pKSxcbiAgICBzb3VyY2VzLmFjdGlvbiRcbiAgICAgIC5maWx0ZXIoYWN0aW9uID0+IGFjdGlvbi50eXBlID09PSAndG9nZ2xlQWxsJylcbiAgICAgIC5tYXAoYWN0aW9uID0+ICh7Li4uYWN0aW9uLCB0eXBlOiAndG9nZ2xlJ30pKSxcblxuICAgIC8vIFRIRSBTVEFSVCBFRElUIEFDVElPTiBTVFJFQU1cbiAgICBzb3VyY2VzLkRPTS5zZWxlY3QoJ2xhYmVsJykuZXZlbnRzKCdkYmxjbGljaycpXG4gICAgICAubWFwVG8oe3R5cGU6ICdzdGFydEVkaXQnfSksXG5cbiAgICAvLyBUSEUgRVNDIEtFWSBBQ1RJT04gU1RSRUFNXG4gICAgc291cmNlcy5ET00uc2VsZWN0KCcuZWRpdCcpLmV2ZW50cygna2V5dXAnKVxuICAgICAgLmZpbHRlcihldiA9PiBldi5rZXlDb2RlID09PSBFU0NfS0VZKVxuICAgICAgLm1hcFRvKHt0eXBlOiAnY2FuY2VsRWRpdCd9KSxcblxuICAgIC8vIFRIRSBFTlRFUiBLRVkgQUNUSU9OIFNUUkVBTVxuICAgIHNvdXJjZXMuRE9NLnNlbGVjdCgnLmVkaXQnKS5ldmVudHMoJ2tleXVwJylcbiAgICAgIC5maWx0ZXIoZXYgPT4gZXYua2V5Q29kZSA9PT0gRU5URVJfS0VZKVxuICAgICAgLmNvbXBvc2UocyA9PiB4cy5tZXJnZShzLCBzb3VyY2VzLkRPTS5zZWxlY3QoJy5lZGl0JykuZXZlbnRzKCdibHVyJywgdHJ1ZSkpKVxuICAgICAgLm1hcChldiA9PiAoe3RpdGxlOiBldi50YXJnZXQudmFsdWUsIHR5cGU6ICdkb25lRWRpdCd9KSlcbiAgKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgaW50ZW50O1xuIiwiaW1wb3J0IHhzIGZyb20gJ3hzdHJlYW0nO1xuXG5mdW5jdGlvbiBtYWtlUmVkdWNlciQoYWN0aW9uJCkge1xuICBsZXQgc3RhcnRFZGl0UmVkdWNlciQgPSBhY3Rpb24kXG4gICAgLmZpbHRlcihhY3Rpb24gPT4gYWN0aW9uLnR5cGUgPT09ICdzdGFydEVkaXQnKVxuICAgIC5tYXBUbyhmdW5jdGlvbiBzdGFydEVkaXRSZWR1Y2VyKGRhdGEpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLmRhdGEsXG4gICAgICAgIGVkaXRpbmc6IHRydWVcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgbGV0IGRvbmVFZGl0UmVkdWNlciQgPSBhY3Rpb24kXG4gICAgLmZpbHRlcihhY3Rpb24gPT4gYWN0aW9uLnR5cGUgPT09ICdkb25lRWRpdCcpXG4gICAgLm1hcChhY3Rpb24gPT4gZnVuY3Rpb24gZG9uZUVkaXRSZWR1Y2VyKGRhdGEpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIC4uLmRhdGEsXG4gICAgICAgIHRpdGxlOiBhY3Rpb24ucGF5bG9hZCxcbiAgICAgICAgZWRpdGluZzogZmFsc2VcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgbGV0IGNhbmNlbEVkaXRSZWR1Y2VyJCA9IGFjdGlvbiRcbiAgICAuZmlsdGVyKGFjdGlvbiA9PiBhY3Rpb24udHlwZSA9PT0gJ2NhbmNlbEVkaXQnKVxuICAgIC5tYXBUbyhmdW5jdGlvbiBjYW5jZWxFZGl0UmVkdWNlcihkYXRhKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5kYXRhLFxuICAgICAgICBlZGl0aW5nOiBmYWxzZVxuICAgICAgfTtcbiAgICB9KTtcblxuICBsZXQgdG9nZ2xlUmVkdWNlciQgPSBhY3Rpb24kXG4gICAgLmZpbHRlcihhY3Rpb24gPT4gYWN0aW9uLnR5cGUgPT09ICd0b2dnbGUnKVxuICAgIC5tYXAoYWN0aW9uID0+IGZ1bmN0aW9uIHRvZ2dsZVJlZHVjZXIoZGF0YSkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uZGF0YSxcbiAgICAgICAgY29tcGxldGVkOiBhY3Rpb24ucGF5bG9hZFxuICAgICAgfTtcbiAgICB9KTtcblxuICByZXR1cm4geHMubWVyZ2UoXG4gICAgc3RhcnRFZGl0UmVkdWNlciQsXG4gICAgZG9uZUVkaXRSZWR1Y2VyJCxcbiAgICBjYW5jZWxFZGl0UmVkdWNlciQsXG4gICAgdG9nZ2xlUmVkdWNlciRcbiAgKTtcbn1cblxuZnVuY3Rpb24gbW9kZWwocHJvcHMkLCBhY3Rpb24kKSB7XG4gIC8vIFRIRSBTQU5JVElaRUQgUFJPUEVSVElFU1xuICAvLyBJZiB0aGUgbGlzdCBpdGVtIGhhcyBubyBkYXRhIHNldCBpdCBhcyBlbXB0eSBhbmQgbm90IGNvbXBsZXRlZC5cbiAgbGV0IHNhbml0aXplZFByb3BzJCA9IHByb3BzJC5zdGFydFdpdGgoe3RpdGxlOiAnJywgY29tcGxldGVkOiBmYWxzZX0pO1xuICBsZXQgcmVkdWNlciQgPSBtYWtlUmVkdWNlciQoYWN0aW9uJCk7XG5cbiAgcmV0dXJuIHNhbml0aXplZFByb3BzJC5tYXAocHJvcHMgPT5cbiAgICByZWR1Y2VyJC5mb2xkKChkYXRhLCByZWR1Y2VyKSA9PiByZWR1Y2VyKGRhdGEpLCBwcm9wcylcbiAgKS5mbGF0dGVuKCkucmVtZW1iZXIoKTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgbW9kZWw7XG4iLCJpbXBvcnQge2J1dHRvbiwgZGl2LCBpbnB1dCwgbGFiZWwsIGxpfSBmcm9tICdAY3ljbGUvZG9tJztcblxuZnVuY3Rpb24gdmlldyhzdGF0ZSQpIHtcbiAgcmV0dXJuIHN0YXRlJC5tYXAoKHt0aXRsZSwgY29tcGxldGVkLCBlZGl0aW5nfSkgPT4ge1xuICAgIGxldCB0b2RvUm9vdENsYXNzZXMgPSB7XG4gICAgICBjb21wbGV0ZWQsXG4gICAgICBlZGl0aW5nLFxuICAgIH07XG5cbiAgICByZXR1cm4gbGkoJy50b2RvUm9vdCcsIHtjbGFzczogdG9kb1Jvb3RDbGFzc2VzfSwgW1xuICAgICAgZGl2KCcudmlldycsIFtcbiAgICAgICAgaW5wdXQoJy50b2dnbGUnLCB7XG4gICAgICAgICAgcHJvcHM6IHt0eXBlOiAnY2hlY2tib3gnLCBjaGVja2VkOiBjb21wbGV0ZWR9LFxuICAgICAgICB9KSxcbiAgICAgICAgbGFiZWwodGl0bGUpLFxuICAgICAgICBidXR0b24oJy5kZXN0cm95JylcbiAgICAgIF0pLFxuICAgICAgaW5wdXQoJy5lZGl0Jywge1xuICAgICAgICBwcm9wczoge3R5cGU6ICd0ZXh0J30sXG4gICAgICAgIGhvb2s6IHtcbiAgICAgICAgICB1cGRhdGU6IChvbGRWTm9kZSwge2VsbX0pID0+IHtcbiAgICAgICAgICAgIGVsbS52YWx1ZSA9IHRpdGxlO1xuICAgICAgICAgICAgaWYgKGVkaXRpbmcpIHtcbiAgICAgICAgICAgICAgZWxtLmZvY3VzKCk7XG4gICAgICAgICAgICAgIGVsbS5zZWxlY3Rpb25TdGFydCA9IGVsbS52YWx1ZS5sZW5ndGg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIF0pO1xuICB9KTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgdmlldztcbiIsImltcG9ydCB4cyBmcm9tICd4c3RyZWFtJztcbmltcG9ydCBpc29sYXRlIGZyb20gJ0BjeWNsZS9pc29sYXRlJ1xuaW1wb3J0IGludGVudCBmcm9tICcuL2ludGVudCc7XG5pbXBvcnQgbW9kZWwgZnJvbSAnLi9tb2RlbCc7XG5pbXBvcnQgdmlldyBmcm9tICcuL3ZpZXcnO1xuaW1wb3J0IGRlc2VyaWFsaXplIGZyb20gJy4vc3RvcmFnZS1zb3VyY2UnO1xuaW1wb3J0IHNlcmlhbGl6ZSBmcm9tICcuL3N0b3JhZ2Utc2luayc7XG5pbXBvcnQgVGFzayBmcm9tICcuLi9UYXNrL2luZGV4JztcbmltcG9ydCBDb2xsZWN0aW9uIGZyb20gJ0BjeWNsZS9jb2xsZWN0aW9uJztcblxuLy8gVEhFIFRBU0tMSVNUIENPTVBPTkVOVFxuLy8gVGhpcyBpcyB0aGUgVGFza0xpc3QgY29tcG9uZW50IHdoaWNoIGlzIGJlaW5nIGV4cG9ydGVkIGJlbG93LlxuZnVuY3Rpb24gVGFza0xpc3Qoc291cmNlcykge1xuICAvLyBUSEUgTE9DQUxTVE9SQUdFIFNUUkVBTVxuICAvLyBIZXJlIHdlIGNyZWF0ZSBhIGxvY2FsU3RvcmFnZSBzdHJlYW0gdGhhdCBvbmx5IHN0cmVhbXNcbiAgLy8gdGhlIGZpcnN0IHZhbHVlIHJlYWQgZnJvbSBsb2NhbFN0b3JhZ2UgaW4gb3JkZXIgdG9cbiAgLy8gc3VwcGx5IHRoZSBhcHBsaWNhdGlvbiB3aXRoIGluaXRpYWwgc3RhdGUuXG4gIGxldCBsb2NhbFN0b3JhZ2UkID0gc291cmNlcy5zdG9yYWdlLmxvY2FsLmdldEl0ZW0oJ3RvZG9zLWN5Y2xlJykudGFrZSgxKTtcbiAgLy8gVEhFIElOSVRJQUwgVE9ETyBEQVRBXG4gIC8vIFRoZSBgZGVzZXJpYWxpemVgIGZ1bmN0aW9uIHRha2VzIHRoZSBzZXJpYWxpemVkIEpTT04gc3RvcmVkIGluIGxvY2FsU3RvcmFnZVxuICAvLyBhbmQgdHVybnMgaXQgaW50byBhIHN0cmVhbSBzZW5kaW5nIGEgSlNPTiBvYmplY3QuXG4gIGxldCBzb3VyY2VUb2Rvc0RhdGEkID0gZGVzZXJpYWxpemUobG9jYWxTdG9yYWdlJCk7XG4gIC8vIFRIRSBJTlRFTlQgKE1WSSBQQVRURVJOKVxuICAvLyBQYXNzIHJlbGV2YW50IHNvdXJjZXMgdG8gdGhlIGludGVudCBmdW5jdGlvbiwgd2hpY2ggc2V0IHVwXG4gIC8vIHN0cmVhbXMgdGhhdCBtb2RlbCB0aGUgdXNlcnMgYWN0aW9ucy5cbiAgbGV0IGFjdGlvbiQgPSBpbnRlbnQoc291cmNlcy5ET00sIHNvdXJjZXMuSGlzdG9yeSk7XG4gIC8vIFRIRSBNT0RFTCAoTVZJIFBBVFRFUk4pXG4gIC8vIEFjdGlvbnMgZ2V0IHBhc3NlZCB0byB0aGUgbW9kZWwgZnVuY3Rpb24gd2hpY2ggdHJhbnNmb3JtcyB0aGUgZGF0YVxuICAvLyBjb21pbmcgdGhyb3VnaCBhbmQgcHJlcGFyZXMgdGhlIGRhdGEgZm9yIHRoZSB2aWV3LlxuICBsZXQgc3RhdGUkID0gbW9kZWwoYWN0aW9uJCwgc291cmNlVG9kb3NEYXRhJCk7XG4gIC8vIFRIRSBJVEVNIEFERElUSU9OIFNUUkVBTVxuICAvLyBFbWl0cyBvYmplY3RzIG9mIHNvdXJjZXMgc3BlY2lmaWMgdG8gZWFjaCBpdGVtLlxuICAvLyBNZXJnZXMgc3RvcmVkIGl0ZW1zIHdpdGggbmV3IGl0ZW1zXG4gIGxldCBhZGQkID0geHMubWVyZ2UoXG4gICAgc291cmNlVG9kb3NEYXRhJFxuICAgICAgLm1hcChkYXRhID0+IGRhdGEubGlzdC5tYXAocHJvcHMgPT4gKHtwcm9wcyQ6IHhzLm9mKHByb3BzKX0pKSksXG4gICAgYWN0aW9uJFxuICAgICAgLmZpbHRlcihhY3Rpb24gPT4gYWN0aW9uLnR5cGUgPT09ICdpbnNlcnRUb2RvJylcbiAgICAgIC5tYXAoYWN0aW9uID0+ICh7XG4gICAgICAgIHByb3BzJDogeHMub2Yoe1xuICAgICAgICAgIHRpdGxlOiBhY3Rpb24ucGF5bG9hZCxcbiAgICAgICAgICBjb21wbGV0ZWQ6IGZhbHNlXG4gICAgICAgIH0pXG4gICAgICB9KSlcbiAgKTtcbiAgLy8gVEhFIElURU0gUkVNT1ZBTCBTRUxFQ1RPUiBGVU5DVElPTlxuICAvLyBUaGlzIGZ1bmN0aW9uIHRha2VzIGl0ZW0ncyBzaW5rcyBhbmQgcmV0dXJucyBhIHN0cmVhbSByZXByZXNlbnRpbmdcbiAgLy8gaXRzIHJlbW92YWwuIE1lcmdlcyBpbnRlcm5hbCByZW1vdmFscyBhbmQgYGRlbGV0ZUNvbXBsZXRlZHNgIGFjdGlvbnNcbiAgZnVuY3Rpb24gcmVtb3ZlU2VsZWN0b3IoaXRlbVNpbmtzKSB7XG4gICAgbGV0IGRlbGV0ZUNvbXBsZXRlZHMkID0gYWN0aW9uJFxuICAgICAgLmZpbHRlcihhY3Rpb24gPT4gYWN0aW9uLnR5cGUgPT09ICdkZWxldGVDb21wbGV0ZWRzJyk7XG4gICAgcmV0dXJuIHhzLm1lcmdlKFxuICAgICAgLy8gQ29uc2lkZXIgZGVsZXRlQ29tcGxldGVkcyQgb25seSBpZiB0aGUgdGFzayBpcyBjb21wbGV0ZWQuXG4gICAgICAvLyBhbmFsb2d1ZSBvZiByeCBwYXVzYWJsZVxuICAgICAgaXRlbVNpbmtzLnN0YXRlJFxuICAgICAgICAubWFwKHN0YXRlID0+IGRlbGV0ZUNvbXBsZXRlZHMkLmZpbHRlcigoKSA9PiBzdGF0ZS5jb21wbGV0ZWQpKVxuICAgICAgICAuZmxhdHRlbigpLFxuICAgICAgaXRlbVNpbmtzLmFjdGlvbiRcbiAgICAgICAgLmZpbHRlcihhY3Rpb24gPT4gYWN0aW9uLnR5cGUgPT09ICdkZXN0cm95JylcbiAgICApO1xuICB9XG4gIC8vIFRIRSBDT0xMRUNUSU9OIFNUUkVBTVxuICAvLyBDb2xsZWN0aW9uIGZ1bmN0aW9uIHRha2VzIGEgY29tcG9uZW50IGZ1bmN0aW9uLCBhIGNvbW1vbiBzb3VyY2VzIG9iamVjdCxcbiAgLy8gYSBzdHJlYW0gb2YgaXRlbSBhZGRpdGlvbnMsIGFuZCBhIHNlbGVjdG9yIGZ1bmN0aW9uIGZyb20gaXRlbSBzaW5rcyB0b1xuICAvLyBhIHN0cmVhbSBvZiByZW1vdmFsc1xuICBsZXQgbGlzdCQgPSBDb2xsZWN0aW9uKFxuICAgIFRhc2ssXG4gICAge1xuICAgICAgRE9NOiBzb3VyY2VzLkRPTSxcbiAgICAgIGFjdGlvbiQ6IGFjdGlvbiRcbiAgICAgICAgLmZpbHRlcihhY3Rpb24gPT4gYWN0aW9uLnR5cGUgPT09ICd0b2dnbGVBbGwnKVxuICAgIH0sXG4gICAgYWRkJCxcbiAgICByZW1vdmVTZWxlY3RvclxuICApO1xuICAvLyBUSEUgQ09NQklORUQgQ0hJTERSRU4gVlRSRUUgQU5EIFNUQVRFIFNUUkVBTVNcbiAgbGV0IHRvZG9WdHJlZXMkID0gQ29sbGVjdGlvbi5wbHVjayhsaXN0JCwgaXRlbVNpbmtzID0+IGl0ZW1TaW5rcy5ET00pO1xuICBsZXQgdG9kb1N0YXRlcyQgPSBDb2xsZWN0aW9uLnBsdWNrKGxpc3QkLCBpdGVtU2lua3MgPT4gaXRlbVNpbmtzLnN0YXRlJCk7XG5cbiAgbGV0IGFtZW5kZWRTdGF0ZSQgPSB4cy5jb21iaW5lKHN0YXRlJCwgdG9kb1Z0cmVlcyQsIHRvZG9TdGF0ZXMkKVxuICAgIC5tYXAoKFtwYXJlbnRTdGF0ZSwgdG9kb1Z0cmVlcywgdG9kb1N0YXRlc10pID0+ICh7XG4gICAgICAuLi5wYXJlbnRTdGF0ZSxcbiAgICAgIGxpc3Q6IHRvZG9TdGF0ZXMubWFwKChzdGF0ZSwgaSkgPT4gKHtcbiAgICAgICAgLi4uc3RhdGUsXG4gICAgICAgIHRvZG9JdGVtOiB7RE9NOiB0b2RvVnRyZWVzW2ldfVxuICAgICAgfSkpXG4gICAgfSkpO1xuICAvLyBUSEUgVklFVyAoTVZJIFBBVFRFUk4pXG4gIC8vIFdlIHJlbmRlciBzdGF0ZSBhcyBtYXJrdXAgZm9yIHRoZSBET00uXG4gIGxldCB2ZG9tJCA9IHZpZXcoYW1lbmRlZFN0YXRlJCk7XG4gIC8vIFdSSVRFIFRPIExPQ0FMU1RPUkFHRVxuICAvLyBUaGUgbGF0ZXN0IHN0YXRlIGlzIHdyaXR0ZW4gdG8gbG9jYWxTdG9yYWdlLlxuICBsZXQgc3RvcmFnZSQgPSBzZXJpYWxpemUoYW1lbmRlZFN0YXRlJCkubWFwKChzdGF0ZSkgPT4gKHtcbiAgICBrZXk6ICd0b2Rvcy1jeWNsZScsIHZhbHVlOiBzdGF0ZVxuICB9KSk7XG4gIC8vIENPTVBMRVRFIFRIRSBDWUNMRVxuICAvLyBXcml0ZSB0aGUgdmlydHVhbCBkb20gc3RyZWFtIHRvIHRoZSBET00gYW5kIHdyaXRlIHRoZVxuICAvLyBzdG9yYWdlIHN0cmVhbSB0byBsb2NhbFN0b3JhZ2UuXG4gIGxldCBzaW5rcyA9IHtcbiAgICBET006IHZkb20kLFxuICAgIHN0b3JhZ2U6IHN0b3JhZ2UkLFxuICB9O1xuICByZXR1cm4gc2lua3M7XG59XG5cbmV4cG9ydCBkZWZhdWx0IFRhc2tMaXN0O1xuIiwiaW1wb3J0IHhzIGZyb20gJ3hzdHJlYW0nO1xuaW1wb3J0IGRyb3BSZXBlYXRzIGZyb20gJ3hzdHJlYW0vZXh0cmEvZHJvcFJlcGVhdHMnO1xuaW1wb3J0IHtFTlRFUl9LRVksIEVTQ19LRVl9IGZyb20gJy4uLy4uL3V0aWxzJztcblxuLy8gVEhFIElOVEVOVCBGT1IgVEhFIExJU1RcbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGludGVudChET01Tb3VyY2UsIEhpc3RvcnkpIHtcbiAgcmV0dXJuIHhzLm1lcmdlKFxuICAgIC8vIFRIRSBST1VURSBTVFJFQU1cbiAgICAvLyBBIHN0cmVhbSB0aGF0IHByb3ZpZGVzIHRoZSBwYXRoIHdoZW5ldmVyIHRoZSByb3V0ZSBjaGFuZ2VzLlxuICAgIEhpc3RvcnlcbiAgICAgIC5zdGFydFdpdGgoe3BhdGhuYW1lOiAnLyd9KVxuICAgICAgLm1hcChsb2NhdGlvbiA9PiBsb2NhdGlvbi5wYXRobmFtZSlcbiAgICAgIC5jb21wb3NlKGRyb3BSZXBlYXRzKCkpXG4gICAgICAubWFwKHBheWxvYWQgPT4gKHt0eXBlOiAnY2hhbmdlUm91dGUnLCBwYXlsb2FkfSkpLFxuXG4gICAgLy8gVEhFIFVSTCBTVFJFQU1cbiAgICAvLyBBIHN0cmVhbSBvZiBVUkwgY2xpY2tzIGluIHRoZSBhcHBcbiAgICBET01Tb3VyY2Uuc2VsZWN0KCdhJykuZXZlbnRzKCdjbGljaycpXG4gICAgICAubWFwKGV2ZW50ID0+ICBldmVudC50YXJnZXQuaGFzaC5yZXBsYWNlKCcjJywgJycpKVxuICAgICAgLm1hcChwYXlsb2FkID0+ICh7dHlwZTogJ3VybCcsIHBheWxvYWR9KSksXG5cbiAgICAvLyBDTEVBUiBJTlBVVCBTVFJFQU1cbiAgICAvLyBBIHN0cmVhbSBvZiBFU0Mga2V5IHN0cm9rZXMgaW4gdGhlIGAubmV3LXRvZG9gIGZpZWxkLlxuICAgIERPTVNvdXJjZS5zZWxlY3QoJy5uZXctdG9kbycpLmV2ZW50cygna2V5ZG93bicpXG4gICAgICAuZmlsdGVyKGV2ID0+IGV2LmtleUNvZGUgPT09IEVTQ19LRVkpXG4gICAgICAubWFwKHBheWxvYWQgPT4gKHt0eXBlOiAnY2xlYXJJbnB1dCcsIHBheWxvYWR9KSksXG5cbiAgICAvLyBFTlRFUiBLRVkgU1RSRUFNXG4gICAgLy8gQSBzdHJlYW0gb2YgRU5URVIga2V5IHN0cm9rZXMgaW4gdGhlIGAubmV3LXRvZG9gIGZpZWxkLlxuICAgIERPTVNvdXJjZS5zZWxlY3QoJy5uZXctdG9kbycpLmV2ZW50cygna2V5ZG93bicpXG4gICAgICAvLyBUcmltIHZhbHVlIGFuZCBvbmx5IGxldCB0aGUgZGF0YSB0aHJvdWdoIHdoZW4gdGhlcmVcbiAgICAgIC8vIGlzIGFueXRoaW5nIGJ1dCB3aGl0ZXNwYWNlIGluIHRoZSBmaWVsZCBhbmQgdGhlIEVOVEVSIGtleSB3YXMgaGl0LlxuICAgICAgLmZpbHRlcihldiA9PiB7XG4gICAgICAgIGxldCB0cmltbWVkVmFsID0gU3RyaW5nKGV2LnRhcmdldC52YWx1ZSkudHJpbSgpO1xuICAgICAgICByZXR1cm4gZXYua2V5Q29kZSA9PT0gRU5URVJfS0VZICYmIHRyaW1tZWRWYWw7XG4gICAgICB9KVxuICAgICAgLy8gUmV0dXJuIHRoZSB0cmltbWVkIHZhbHVlLlxuICAgICAgLm1hcChldiA9PiBTdHJpbmcoZXYudGFyZ2V0LnZhbHVlKS50cmltKCkpXG4gICAgICAubWFwKHBheWxvYWQgPT4gKHt0eXBlOiAnaW5zZXJ0VG9kbycsIHBheWxvYWR9KSksXG5cbiAgICAvLyBUT0dHTEUgQUxMIFNUUkVBTVxuICAgIC8vIENyZWF0ZSBhIHN0cmVhbSBvdXQgb2YgdGhlIGNsaWNrcyBvbiB0aGUgYC50b2dnbGUtYWxsYCBidXR0b24uXG4gICAgRE9NU291cmNlLnNlbGVjdCgnLnRvZ2dsZS1hbGwnKS5ldmVudHMoJ2NsaWNrJylcbiAgICAgIC5tYXAoZXYgPT4gZXYudGFyZ2V0LmNoZWNrZWQpXG4gICAgICAubWFwKHBheWxvYWQgPT4gKHt0eXBlOiAndG9nZ2xlQWxsJywgcGF5bG9hZH0pKSxcblxuICAgIC8vIERFTEVURSBDT01QTEVURUQgVE9ET1MgU1RSRUFNXG4gICAgLy8gQSBzdHJlYW0gb2YgY2xpY2sgZXZlbnRzIG9uIHRoZSBgLmNsZWFyLWNvbXBsZXRlZGAgZWxlbWVudC5cbiAgICBET01Tb3VyY2Uuc2VsZWN0KCcuY2xlYXItY29tcGxldGVkJykuZXZlbnRzKCdjbGljaycpXG4gICAgICAubWFwVG8oe3R5cGU6ICdkZWxldGVDb21wbGV0ZWRzJ30pXG4gICk7XG59O1xuIiwiaW1wb3J0IHhzIGZyb20gJ3hzdHJlYW0nO1xuaW1wb3J0IGNvbmNhdCBmcm9tICd4c3RyZWFtL2V4dHJhL2NvbmNhdCc7XG5cbi8vIEEgaGVscGVyIGZ1bmN0aW9uIHRoYXQgcHJvdmlkZXMgZmlsdGVyIGZ1bmN0aW9uc1xuLy8gZGVwZW5kaW5nIG9uIHRoZSByb3V0ZSB2YWx1ZS5cbmZ1bmN0aW9uIGdldEZpbHRlckZuKHJvdXRlKSB7XG4gIHN3aXRjaCAocm91dGUpIHtcbiAgICBjYXNlICcvYWN0aXZlJzogcmV0dXJuICh0YXNrID0+IHRhc2suY29tcGxldGVkID09PSBmYWxzZSk7XG4gICAgY2FzZSAnL2NvbXBsZXRlZCc6IHJldHVybiAodGFzayA9PiB0YXNrLmNvbXBsZXRlZCA9PT0gdHJ1ZSk7XG4gICAgZGVmYXVsdDogcmV0dXJuICgpID0+IHRydWU7IC8vIGFsbG93IGFueXRoaW5nXG4gIH1cbn1cblxuLy8gTUFLRSBSRURVQ0VSIFNUUkVBTVxuLy8gQSBmdW5jdGlvbiB0aGF0IHRha2VzIHRoZSBhY3Rpb25zIG9uIHRoZSB0b2RvIGxpc3Rcbi8vIGFuZCByZXR1cm5zIGEgc3RyZWFtIG9mIFwicmVkdWNlcnNcIjogZnVuY3Rpb25zIHRoYXQgZXhwZWN0IHRoZSBjdXJyZW50XG4vLyB0b2Rvc0RhdGEgKHRoZSBzdGF0ZSkgYW5kIHJldHVybiBhIG5ldyB2ZXJzaW9uIG9mIHRvZG9zRGF0YS5cbmZ1bmN0aW9uIG1ha2VSZWR1Y2VyJChhY3Rpb24kKSB7XG4gIGxldCBjbGVhcklucHV0UmVkdWNlciQgPSBhY3Rpb24kXG4gICAgLmZpbHRlcihhID0+IGEudHlwZSA9PT0gJ2NsZWFySW5wdXQnKVxuICAgIC5tYXBUbyhmdW5jdGlvbiBjbGVhcklucHV0UmVkdWNlcih0b2Rvc0RhdGEpIHtcbiAgICAgIHJldHVybiB0b2Rvc0RhdGE7XG4gICAgfSk7XG5cbiAgbGV0IGNoYW5nZVJvdXRlUmVkdWNlciQgPSBhY3Rpb24kXG4gICAgLmZpbHRlcihhID0+IGEudHlwZSA9PT0gJ2NoYW5nZVJvdXRlJylcbiAgICAubWFwKGEgPT4gYS5wYXlsb2FkKVxuICAgIC5zdGFydFdpdGgoJy8nKVxuICAgIC5tYXAocGF0aCA9PiB7XG4gICAgICBsZXQgZmlsdGVyRm4gPSBnZXRGaWx0ZXJGbihwYXRoKTtcbiAgICAgIHJldHVybiBmdW5jdGlvbiBjaGFuZ2VSb3V0ZVJlZHVjZXIodG9kb3NEYXRhKSB7XG4gICAgICAgIHRvZG9zRGF0YS5maWx0ZXIgPSBwYXRoLnJlcGxhY2UoJy8nLCAnJykudHJpbSgpO1xuICAgICAgICB0b2Rvc0RhdGEuZmlsdGVyRm4gPSBmaWx0ZXJGbjtcbiAgICAgICAgcmV0dXJuIHRvZG9zRGF0YTtcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgcmV0dXJuIHhzLm1lcmdlKFxuICAgIGNsZWFySW5wdXRSZWR1Y2VyJCxcbiAgICBjaGFuZ2VSb3V0ZVJlZHVjZXIkXG4gICk7XG59XG5cbi8vIFRISVMgSVMgVEhFIE1PREVMIEZVTkNUSU9OXG4vLyBJdCBleHBlY3RzIHRoZSBhY3Rpb25zIGNvbWluZyBpbiBmcm9tIHRoZSBzb3VyY2VzXG5mdW5jdGlvbiBtb2RlbChhY3Rpb24kLCBzb3VyY2VUb2Rvc0RhdGEkKSB7XG4gIC8vIFRIRSBCVVNJTkVTUyBMT0dJQ1xuICAvLyBBY3Rpb25zIGFyZSBwYXNzZWQgdG8gdGhlIGBtYWtlUmVkdWNlciRgIGZ1bmN0aW9uXG4gIC8vIHdoaWNoIGNyZWF0ZXMgYSBzdHJlYW0gb2YgcmVkdWNlciBmdW5jdGlvbnMgdGhhdCBuZWVkc1xuICAvLyB0byBiZSBhcHBsaWVkIG9uIHRoZSB0b2RvRGF0YSB3aGVuIGFuIGFjdGlvbiBoYXBwZW5zLlxuICBsZXQgcmVkdWNlciQgPSBtYWtlUmVkdWNlciQoYWN0aW9uJCk7XG5cbiAgLy8gUkVUVVJOIFRIRSBNT0RFTCBEQVRBXG4gIHJldHVybiBzb3VyY2VUb2Rvc0RhdGEkLm1hcChzb3VyY2VUb2Rvc0RhdGEgPT5cbiAgICByZWR1Y2VyJC5mb2xkKCh0b2Rvc0RhdGEsIHJlZHVjZXIpID0+IHJlZHVjZXIodG9kb3NEYXRhKSwgc291cmNlVG9kb3NEYXRhKVxuICApLmZsYXR0ZW4oKVxuICAvLyBNYWtlIHRoaXMgcmVtZW1iZXIgaXRzIGxhdGVzdCBldmVudCwgc28gbGF0ZSBsaXN0ZW5lcnNcbiAgLy8gd2lsbCBiZSB1cGRhdGVkIHdpdGggdGhlIGxhdGVzdCBzdGF0ZS5cbiAgLnJlbWVtYmVyKCk7XG59XG5cbmV4cG9ydCBkZWZhdWx0IG1vZGVsO1xuIiwiLy8gVHVybiB0aGUgZGF0YSBvYmplY3QgdGhhdCBjb250YWluc1xuLy8gdGhlIHRvZG9zIGludG8gYSBzdHJpbmcgZm9yIGxvY2FsU3RvcmFnZS5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHNlcmlhbGl6ZSh0b2RvcyQpIHtcbiAgcmV0dXJuIHRvZG9zJC5tYXAodG9kb3NEYXRhID0+IEpTT04uc3RyaW5naWZ5KFxuICAgIHtcbiAgICAgIGxpc3Q6IHRvZG9zRGF0YS5saXN0Lm1hcCh0b2RvRGF0YSA9PlxuICAgICAgICAoe1xuICAgICAgICAgIHRpdGxlOiB0b2RvRGF0YS50aXRsZSxcbiAgICAgICAgICBjb21wbGV0ZWQ6IHRvZG9EYXRhLmNvbXBsZXRlZFxuICAgICAgICB9KVxuICAgICAgKVxuICAgIH1cbiAgKSk7XG59O1xuIiwiZnVuY3Rpb24gbWVyZ2UoKSB7XG4gIGxldCByZXN1bHQgPSB7fTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBhcmd1bWVudHMubGVuZ3RoOyBpKyspIHtcbiAgICBsZXQgb2JqZWN0ID0gYXJndW1lbnRzW2ldO1xuICAgIGZvciAobGV0IGtleSBpbiBvYmplY3QpIHtcbiAgICAgIGlmIChvYmplY3QuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuICAgICAgICByZXN1bHRba2V5XSA9IG9iamVjdFtrZXldO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5sZXQgc2FmZUpTT05QYXJzZSA9IHN0ciA9PiBKU09OLnBhcnNlKHN0cikgfHwge307XG5cbmxldCBtZXJnZVdpdGhEZWZhdWx0VG9kb3NEYXRhID0gdG9kb3NEYXRhID0+IHtcbiAgcmV0dXJuIG1lcmdlKHtcbiAgICBsaXN0OiBbXSxcbiAgICBmaWx0ZXI6ICcnLFxuICAgIGZpbHRlckZuOiAoKSA9PiB0cnVlLCAvLyBhbGxvdyBhbnl0aGluZ1xuICB9LCB0b2Rvc0RhdGEpO1xufVxuXG4vLyBUYWtlIGxvY2FsU3RvcmFnZSB0b2RvRGF0YSBzdHJlYW0gYW5kIHRyYW5zZm9ybSBpbnRvXG4vLyBhIEphdmFTY3JpcHQgb2JqZWN0LiBTZXQgZGVmYXVsdCBkYXRhLlxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZGVzZXJpYWxpemUobG9jYWxTdG9yYWdlVmFsdWUkKSB7XG4gIHJldHVybiBsb2NhbFN0b3JhZ2VWYWx1ZSRcbiAgICAubWFwKHNhZmVKU09OUGFyc2UpXG4gICAgLm1hcChtZXJnZVdpdGhEZWZhdWx0VG9kb3NEYXRhKTtcbn07XG4iLCJpbXBvcnQge2EsIGJ1dHRvbiwgZGl2LCBmb290ZXIsIGgxLCBoZWFkZXIsIGlucHV0LCBsaSxcbiAgICAgICAgc2VjdGlvbiwgc3Bhbiwgc3Ryb25nLCB1bH0gZnJvbSAnQGN5Y2xlL2RvbSc7XG5cbmZ1bmN0aW9uIHJlbmRlckhlYWRlcigpIHtcbiAgcmV0dXJuIGhlYWRlcignLmhlYWRlcicsIFtcbiAgICBoMSgndG9kb3MnKSxcbiAgICBpbnB1dCgnLm5ldy10b2RvJywge1xuICAgICAgcHJvcHM6IHtcbiAgICAgICAgdHlwZTogJ3RleHQnLFxuICAgICAgICBwbGFjZWhvbGRlcjogJ1doYXQgbmVlZHMgdG8gYmUgZG9uZT8nLFxuICAgICAgICBhdXRvZm9jdXM6IHRydWUsXG4gICAgICAgIG5hbWU6ICduZXdUb2RvJ1xuICAgICAgfSxcbiAgICAgIGhvb2s6IHtcbiAgICAgICAgdXBkYXRlOiAob2xkVk5vZGUsIHtlbG19KSA9PiB7XG4gICAgICAgICAgZWxtLnZhbHVlID0gJyc7XG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgIH0pXG4gIF0pO1xufVxuXG5mdW5jdGlvbiByZW5kZXJNYWluU2VjdGlvbih0b2Rvc0RhdGEpIHtcbiAgbGV0IGFsbENvbXBsZXRlZCA9IHRvZG9zRGF0YS5saXN0LnJlZHVjZSgoeCwgeSkgPT4geCAmJiB5LmNvbXBsZXRlZCwgdHJ1ZSk7XG4gIGxldCBzZWN0aW9uU3R5bGUgPSB7J2Rpc3BsYXknOiB0b2Rvc0RhdGEubGlzdC5sZW5ndGggPyAnJyA6ICdub25lJ307XG5cbiAgcmV0dXJuIHNlY3Rpb24oJy5tYWluJywge3N0eWxlOiBzZWN0aW9uU3R5bGV9LCBbXG4gICAgaW5wdXQoJy50b2dnbGUtYWxsJywge1xuICAgICAgcHJvcHM6IHt0eXBlOiAnY2hlY2tib3gnLCBjaGVja2VkOiBhbGxDb21wbGV0ZWR9LFxuICAgIH0pLFxuICAgIHVsKCcudG9kby1saXN0JywgdG9kb3NEYXRhLmxpc3RcbiAgICAgIC5maWx0ZXIodG9kb3NEYXRhLmZpbHRlckZuKVxuICAgICAgLm1hcChkYXRhID0+IGRhdGEudG9kb0l0ZW0uRE9NKVxuICAgIClcbiAgXSk7XG59XG5cbmZ1bmN0aW9uIHJlbmRlckZpbHRlckJ1dHRvbih0b2Rvc0RhdGEsIGZpbHRlclRhZywgcGF0aCwgbGFiZWwpIHtcbiAgcmV0dXJuIGxpKFtcbiAgICBhKHtcbiAgICAgIHByb3BzOiB7aHJlZjogcGF0aH0sXG4gICAgICBjbGFzczoge3NlbGVjdGVkOiB0b2Rvc0RhdGEuZmlsdGVyID09PSBmaWx0ZXJUYWd9XG4gICAgfSwgbGFiZWwpXG4gIF0pO1xufVxuXG5mdW5jdGlvbiByZW5kZXJGb290ZXIodG9kb3NEYXRhKSB7XG4gIGxldCBhbW91bnRDb21wbGV0ZWQgPSB0b2Rvc0RhdGEubGlzdFxuICAgIC5maWx0ZXIodG9kb0RhdGEgPT4gdG9kb0RhdGEuY29tcGxldGVkKVxuICAgIC5sZW5ndGg7XG4gIGxldCBhbW91bnRBY3RpdmUgPSB0b2Rvc0RhdGEubGlzdC5sZW5ndGggLSBhbW91bnRDb21wbGV0ZWQ7XG4gIGxldCBmb290ZXJTdHlsZSA9IHsnZGlzcGxheSc6IHRvZG9zRGF0YS5saXN0Lmxlbmd0aCA/ICcnIDogJ25vbmUnfTtcblxuICByZXR1cm4gZm9vdGVyKCcuZm9vdGVyJywge3N0eWxlOiBmb290ZXJTdHlsZX0sIFtcbiAgICBzcGFuKCcudG9kby1jb3VudCcsIFtcbiAgICAgIHN0cm9uZyhTdHJpbmcoYW1vdW50QWN0aXZlKSksXG4gICAgICAnIGl0ZW0nICsgKGFtb3VudEFjdGl2ZSAhPT0gMSA/ICdzJyA6ICcnKSArICcgbGVmdCdcbiAgICBdKSxcbiAgICB1bCgnLmZpbHRlcnMnLCBbXG4gICAgICByZW5kZXJGaWx0ZXJCdXR0b24odG9kb3NEYXRhLCAnJywgJy8nLCAnQWxsJyksXG4gICAgICByZW5kZXJGaWx0ZXJCdXR0b24odG9kb3NEYXRhLCAnYWN0aXZlJywgJy9hY3RpdmUnLCAnQWN0aXZlJyksXG4gICAgICByZW5kZXJGaWx0ZXJCdXR0b24odG9kb3NEYXRhLCAnY29tcGxldGVkJywgJy9jb21wbGV0ZWQnLCAnQ29tcGxldGVkJyksXG4gICAgXSksXG4gICAgKGFtb3VudENvbXBsZXRlZCA+IDAgP1xuICAgICAgYnV0dG9uKCcuY2xlYXItY29tcGxldGVkJywgJ0NsZWFyIGNvbXBsZXRlZCAoJyArIGFtb3VudENvbXBsZXRlZCArICcpJylcbiAgICAgIDogbnVsbFxuICAgIClcbiAgXSlcbn1cblxuLy8gVEhFIFZJRVdcbi8vIFRoaXMgZnVuY3Rpb24gZXhwZWN0cyB0aGUgc3RyZWFtIG9mIHRvZG9zRGF0YVxuLy8gZnJvbSB0aGUgbW9kZWwgZnVuY3Rpb24gYW5kIHR1cm5zIGl0IGludG8gYVxuLy8gdmlydHVhbCBET00gc3RyZWFtIHRoYXQgaXMgdGhlbiB1bHRpbWF0ZWx5IHJldHVybmVkIGludG9cbi8vIHRoZSBET00gc2luayBpbiB0aGUgaW5kZXguanMuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB2aWV3KHRvZG9zJCkge1xuICByZXR1cm4gdG9kb3MkLm1hcCh0b2RvcyA9PlxuICAgIGRpdihbXG4gICAgICByZW5kZXJIZWFkZXIoKSxcbiAgICAgIHJlbmRlck1haW5TZWN0aW9uKHRvZG9zKSxcbiAgICAgIHJlbmRlckZvb3Rlcih0b2RvcylcbiAgICBdKVxuICApO1xufTtcbiIsImNvbnN0IEVOVEVSX0tFWSA9IDEzO1xuY29uc3QgRVNDX0tFWSA9IDI3O1xuXG5leHBvcnQge0VOVEVSX0tFWSwgRVNDX0tFWX07XG4iXX0=
diff --git a/examples/cyclejs/js/app.min.js b/examples/cyclejs/js/app.min.js
new file mode 100644
index 0000000000..d481f809e9
--- /dev/null
+++ b/examples/cyclejs/js/app.min.js
@@ -0,0 +1,12 @@
+(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o2?_len-2:0),_key=2;_key<_len;_key++){children[_key-2]=arguments[_key]}return h(tag,attrs,children)},svg:svg,mockDOMSource:mockDOMSource});module.exports=CycleDOM},{"./mock-dom-source":4,"./render-dom":5,"./render-html":6,"./virtual-hyperscript":9,"./virtual-hyperscript-svg":8,"hyperscript-helpers":10}],3:[function(require,module,exports){"use strict";var Rx=require("rx");var disposableCreate=Rx.Disposable.create;var CompositeDisposable=Rx.CompositeDisposable;var AnonymousObservable=Rx.AnonymousObservable;function createListener(_ref){var element=_ref.element;var eventName=_ref.eventName;var handler=_ref.handler;var useCapture=_ref.useCapture;if(element.addEventListener){element.addEventListener(eventName,handler,useCapture);return disposableCreate(function removeEventListener(){element.removeEventListener(eventName,handler,useCapture)})}throw new Error("No listener found")}function createEventListener(_ref2){var element=_ref2.element;var eventName=_ref2.eventName;var handler=_ref2.handler;var useCapture=_ref2.useCapture;var disposables=new CompositeDisposable;if(Array.isArray(element)){for(var i=0,len=element.length;i0){return Rx.Observable.combineLatest(vtree.children.map(transposeVTree),function(){for(var _len=arguments.length,arr=Array(_len),_key=0;_key<_len;_key++){arr[_key]=arguments[_key]}return new VirtualNode(vtree.tagName,vtree.properties,arr,vtree.key,vtree.namespace)})}else if(vtree.type==="VirtualNode"||vtree.type==="Widget"||vtree.type==="Thunk"){return Rx.Observable.just(vtree)}else{throw new Error("Unhandled case in transposeVTree()")}}module.exports={transposeVTree:transposeVTree}},{rx:66,"virtual-dom/vnode/vnode":53}],8:[function(require,module,exports){"use strict";var isArray=require("x-is-array");var h=require("./virtual-hyperscript");var SVGAttributeNamespace=require("virtual-dom/virtual-hyperscript/svg-attribute-namespace");var attributeHook=require("virtual-dom/virtual-hyperscript/hooks/attribute-hook");var SVG_NAMESPACE="http://www.w3.org/2000/svg";module.exports=svg;function svg(tagName,properties,children){if(!children&&isChildren(properties)){children=properties;properties={}}properties=properties||{};properties.namespace=SVG_NAMESPACE;var attributes=properties.attributes||(properties.attributes={});for(var key in properties){if(!properties.hasOwnProperty(key)){continue}var namespace=SVGAttributeNamespace(key);if(namespace===undefined){continue}var value=properties[key];if(typeof value!=="string"&&typeof value!=="number"&&typeof value!=="boolean"){continue}if(namespace!==null){properties[key]=attributeHook(namespace,value);continue}attributes[key]=value;properties[key]=undefined}return h(tagName,properties,children)}function isObservable(x){return x&&typeof x.subscribe==="function"}function isChildren(x){return typeof x==="string"||isArray(x)||isObservable(x)}},{"./virtual-hyperscript":9,"virtual-dom/virtual-hyperscript/hooks/attribute-hook":41,"virtual-dom/virtual-hyperscript/svg-attribute-namespace":45,"x-is-array":58}],9:[function(require,module,exports){"use strict";var isArray=require("x-is-array");var VNode=require("virtual-dom/vnode/vnode.js");var VText=require("virtual-dom/vnode/vtext.js");var isVNode=require("virtual-dom/vnode/is-vnode");var isVText=require("virtual-dom/vnode/is-vtext");var isWidget=require("virtual-dom/vnode/is-widget");var isHook=require("virtual-dom/vnode/is-vhook");var isVThunk=require("virtual-dom/vnode/is-thunk");var parseTag=require("virtual-dom/virtual-hyperscript/parse-tag.js");var softSetHook=require("virtual-dom/virtual-hyperscript/hooks/soft-set-hook.js");var evHook=require("virtual-dom/virtual-hyperscript/hooks/ev-hook.js");module.exports=h;function h(tagName,properties,children){var childNodes=[];var tag,props,key,namespace;if(!children&&isChildren(properties)){children=properties;props={}}props=props||properties||{};tag=parseTag(tagName,props);if(props.hasOwnProperty("key")){key=props.key;props.key=undefined}if(props.hasOwnProperty("namespace")){namespace=props.namespace;props.namespace=undefined}if(tag==="INPUT"&&!namespace&&props.hasOwnProperty("value")&&props.value!==undefined&&!isHook(props.value)){props.value=softSetHook(props.value)}transformProperties(props);if(children!==undefined&&children!==null){addChild(children,childNodes,tag,props)}return new VNode(tag,props,childNodes,key,namespace)}function addChild(c,childNodes,tag,props){if(typeof c==="string"){childNodes.push(new VText(c))}else if(typeof c==="number"){childNodes.push(new VText(String(c)))}else if(isChild(c)){childNodes.push(c)}else if(isArray(c)){for(var i=0;i0};var startsWith=function startsWith(string,start){return string.indexOf(start)===0};var isSelector=function isSelector(param){return isValidString(param)&&(startsWith(param,".")||startsWith(param,"#"))};var node=function node(h){return function(tagName){return function(first){for(var _len=arguments.length,rest=Array(_len>1?_len-1:0),_key=1;_key<_len;_key++){rest[_key-1]=arguments[_key]}if(isSelector(first)){return h.apply(undefined,[tagName+first].concat(rest))}else{return h.apply(undefined,[tagName,first].concat(rest))}}}};var TAG_NAMES=["a","abbr","address","area","article","aside","audio","b","base","bdi","bdo","blockquote","body","br","button","canvas","caption","cite","code","col","colgroup","dd","del","dfn","dir","div","dl","dt","em","embed","fieldset","figcaption","figure","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","iframe","img","input","ins","kbd","keygen","label","legend","li","link","map","mark","menu","meta","nav","noscript","object","ol","optgroup","option","p","param","pre","q","rp","rt","ruby","s","samp","script","section","select","small","source","span","strong","style","sub","sup","table","tbody","td","textarea","tfoot","th","thead","title","tr","u","ul","video"];module.exports=function(h){var exported={TAG_NAMES:TAG_NAMES,isSelector:isSelector};var appliedNode=node(h);TAG_NAMES.forEach(function(n){exported[n]=appliedNode(n)});return exported}},{}],11:[function(require,module,exports){"use strict";var proto=Element.prototype;var vendor=proto.matches||proto.matchesSelector||proto.webkitMatchesSelector||proto.mozMatchesSelector||proto.msMatchesSelector||proto.oMatchesSelector;module.exports=match;function match(el,selector){if(vendor)return vendor.call(el,selector);var nodes=el.parentNode.querySelectorAll(selector);for(var i=0;i"}function tagContent(node){var innerHTML=node.properties.innerHTML;if(innerHTML!=null)return innerHTML;else{var ret="";if(node.children&&node.children.length){for(var i=0,l=node.children.length;i"}},{"./create-attribute":15,"./void-elements":26,"escape-html":17,"param-case":23,"virtual-dom/virtual-hyperscript/hooks/attribute-hook":41,"virtual-dom/virtual-hyperscript/hooks/soft-set-hook":43,"virtual-dom/vnode/is-thunk":47,"virtual-dom/vnode/is-vnode":49,"virtual-dom/vnode/is-vtext":50,"virtual-dom/vnode/is-widget":51,xtend:24}],17:[function(require,module,exports){"use strict";var matchHtmlRegExp=/["'&<>]/;module.exports=escapeHtml;function escapeHtml(string){var str=""+string;var match=matchHtmlRegExp.exec(str);if(!match){return str}var escape;var html="";var index=0;var lastIndex=0;for(index=match.index;index>>0:limit>>>0;while(match=separator.exec(str)){lastIndex=match.index+match[0].length;if(lastIndex>lastLastIndex){output.push(str.slice(lastLastIndex,match.index));if(!compliantExecNpcg&&match.length>1){match[0].replace(separator2,function(){for(var i=1;i1&&match.index=limit){break}}if(separator.lastIndex===match.index){separator.lastIndex++}}if(lastLastIndex===str.length){if(lastLength||!separator.test("")){output.push("")}}else{output.push(str.slice(lastLastIndex))}return output.length>limit?output.slice(0,limit):output};return self}()},{}],29:[function(require,module,exports){"use strict";var OneVersionConstraint=require("individual/one-version");var MY_VERSION="7";OneVersionConstraint("ev-store",MY_VERSION);var hashKey="__EV_STORE_KEY@"+MY_VERSION;module.exports=EvStore;function EvStore(elem){var hash=elem[hashKey];if(!hash){hash=elem[hashKey]={}}return hash}},{"individual/one-version":31}],30:[function(require,module,exports){(function(global){"use strict";var root=typeof window!=="undefined"?window:typeof global!=="undefined"?global:{};module.exports=Individual;function Individual(key,value){if(key in root){return root[key]}root[key]=value;return value}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{}],31:[function(require,module,exports){"use strict";var Individual=require("./index.js");module.exports=OneVersion;function OneVersion(moduleName,version,defaultValue){var key="__INDIVIDUAL_ONE_VERSION_"+moduleName;var enforceKey=key+"_ENFORCE_SINGLETON";var versionValue=Individual(enforceKey,version);if(versionValue!==version){throw new Error("Can only have one copy of "+moduleName+".\n"+"You already have version "+versionValue+" installed.\n"+"This means you cannot install version "+version)}return Individual(key,defaultValue)}},{"./index.js":30}],32:[function(require,module,exports){(function(global){var topLevel=typeof global!=="undefined"?global:typeof window!=="undefined"?window:{};var minDoc=require("min-document");if(typeof document!=="undefined"){module.exports=document}else{var doccy=topLevel["__GLOBAL_DOCUMENT_CACHE@4"];if(!doccy){doccy=topLevel["__GLOBAL_DOCUMENT_CACHE@4"]=minDoc}module.exports=doccy}}).call(this,typeof global!=="undefined"?global:typeof self!=="undefined"?self:typeof window!=="undefined"?window:{})},{"min-document":64}],33:[function(require,module,exports){"use strict";module.exports=function isObject(x){return typeof x==="object"&&x!==null}},{}],34:[function(require,module,exports){var patch=require("./vdom/patch.js");module.exports=patch},{"./vdom/patch.js":39}],35:[function(require,module,exports){var isObject=require("is-object");var isHook=require("../vnode/is-vhook.js");module.exports=applyProperties;function applyProperties(node,props,previous){for(var propName in props){var propValue=props[propName];if(propValue===undefined){removeProperty(node,propName,propValue,previous)}else if(isHook(propValue)){removeProperty(node,propName,propValue,previous);if(propValue.hook){propValue.hook(node,propName,previous?previous[propName]:undefined)}}else{if(isObject(propValue)){patchObject(node,props,previous,propName,propValue)}else{node[propName]=propValue}}}}function removeProperty(node,propName,propValue,previous){if(previous){var previousValue=previous[propName];if(!isHook(previousValue)){if(propName==="attributes"){for(var attrName in previousValue){node.removeAttribute(attrName)}}else if(propName==="style"){for(var i in previousValue){
+node.style[i]=""}}else if(typeof previousValue==="string"){node[propName]=""}else{node[propName]=null}}else if(previousValue.unhook){previousValue.unhook(node,propName,propValue)}}}function patchObject(node,props,previous,propName,propValue){var previousValue=previous?previous[propName]:undefined;if(propName==="attributes"){for(var attrName in propValue){var attrValue=propValue[attrName];if(attrValue===undefined){node.removeAttribute(attrName)}else{node.setAttribute(attrName,attrValue)}}return}if(previousValue&&isObject(previousValue)&&getPrototype(previousValue)!==getPrototype(propValue)){node[propName]=propValue;return}if(!isObject(node[propName])){node[propName]={}}var replacer=propName==="style"?"":undefined;for(var k in propValue){var value=propValue[k];node[propName][k]=value===undefined?replacer:value}}function getPrototype(value){if(Object.getPrototypeOf){return Object.getPrototypeOf(value)}else if(value.__proto__){return value.__proto__}else if(value.constructor){return value.constructor.prototype}}},{"../vnode/is-vhook.js":48,"is-object":33}],36:[function(require,module,exports){var document=require("global/document");var applyProperties=require("./apply-properties");var isVNode=require("../vnode/is-vnode.js");var isVText=require("../vnode/is-vtext.js");var isWidget=require("../vnode/is-widget.js");var handleThunk=require("../vnode/handle-thunk.js");module.exports=createElement;function createElement(vnode,opts){var doc=opts?opts.document||document:document;var warn=opts?opts.warn:null;vnode=handleThunk(vnode).a;if(isWidget(vnode)){return vnode.init()}else if(isVText(vnode)){return doc.createTextNode(vnode.text)}else if(!isVNode(vnode)){if(warn){warn("Item is not a valid virtual dom node",vnode)}return null}var node=vnode.namespace===null?doc.createElement(vnode.tagName):doc.createElementNS(vnode.namespace,vnode.tagName);var props=vnode.properties;applyProperties(node,props);var children=vnode.children;for(var i=0;i>0;currentItem=indices[currentIndex];if(minIndex===maxIndex){return currentItem>=left&¤tItem<=right}else if(currentItemright){maxIndex=currentIndex-1}else{return true}}return false}function ascending(a,b){return a>b?1:-1}},{}],38:[function(require,module,exports){var applyProperties=require("./apply-properties");var isWidget=require("../vnode/is-widget.js");var VPatch=require("../vnode/vpatch.js");var updateWidget=require("./update-widget");module.exports=applyPatch;function applyPatch(vpatch,domNode,renderOptions){var type=vpatch.type;var vNode=vpatch.vNode;var patch=vpatch.patch;switch(type){case VPatch.REMOVE:return removeNode(domNode,vNode);case VPatch.INSERT:return insertNode(domNode,patch,renderOptions);case VPatch.VTEXT:return stringPatch(domNode,vNode,patch,renderOptions);case VPatch.WIDGET:return widgetPatch(domNode,vNode,patch,renderOptions);case VPatch.VNODE:return vNodePatch(domNode,vNode,patch,renderOptions);case VPatch.ORDER:reorderChildren(domNode,patch);return domNode;case VPatch.PROPS:applyProperties(domNode,patch,vNode.properties);return domNode;case VPatch.THUNK:return replaceRoot(domNode,renderOptions.patch(domNode,patch,renderOptions));default:return domNode}}function removeNode(domNode,vNode){var parentNode=domNode.parentNode;if(parentNode){parentNode.removeChild(domNode)}destroyWidget(domNode,vNode);return null}function insertNode(parentNode,vNode,renderOptions){var newNode=renderOptions.render(vNode,renderOptions);if(parentNode){parentNode.appendChild(newNode)}return parentNode}function stringPatch(domNode,leftVNode,vText,renderOptions){var newNode;if(domNode.nodeType===3){domNode.replaceData(0,domNode.length,vText.text);newNode=domNode}else{var parentNode=domNode.parentNode;newNode=renderOptions.render(vText,renderOptions);if(parentNode&&newNode!==domNode){parentNode.replaceChild(newNode,domNode)}}return newNode}function widgetPatch(domNode,leftVNode,widget,renderOptions){var updating=updateWidget(leftVNode,widget);var newNode;if(updating){newNode=widget.update(leftVNode,domNode)||domNode}else{newNode=renderOptions.render(widget,renderOptions)}var parentNode=domNode.parentNode;if(parentNode&&newNode!==domNode){parentNode.replaceChild(newNode,domNode)}if(!updating){destroyWidget(domNode,leftVNode)}return newNode}function vNodePatch(domNode,leftVNode,vNode,renderOptions){var parentNode=domNode.parentNode;var newNode=renderOptions.render(vNode,renderOptions);if(parentNode&&newNode!==domNode){parentNode.replaceChild(newNode,domNode)}return newNode}function destroyWidget(domNode,w){if(typeof w.destroy==="function"&&isWidget(w)){w.destroy(domNode)}}function reorderChildren(domNode,moves){var childNodes=domNode.childNodes;var keyMap={};var node;var remove;var insert;for(var i=0;i=length++?null:childNodes[insert.to])}}function replaceRoot(oldRoot,newRoot){if(oldRoot&&newRoot&&oldRoot!==newRoot&&oldRoot.parentNode){oldRoot.parentNode.replaceChild(newRoot,oldRoot)}return newRoot}},{"../vnode/is-widget.js":51,"../vnode/vpatch.js":54,"./apply-properties":35,"./update-widget":40}],39:[function(require,module,exports){var document=require("global/document");var isArray=require("x-is-array");var render=require("./create-element");var domIndex=require("./dom-index");var patchOp=require("./patch-op");module.exports=patch;function patch(rootNode,patches,renderOptions){renderOptions=renderOptions||{};renderOptions.patch=renderOptions.patch&&renderOptions.patch!==patch?renderOptions.patch:patchRecursive;renderOptions.render=renderOptions.render||render;return renderOptions.patch(rootNode,patches,renderOptions)}function patchRecursive(rootNode,patches,renderOptions){var indices=patchIndices(patches);if(indices.length===0){return rootNode}var index=domIndex(rootNode,patches.a,indices);var ownerDocument=rootNode.ownerDocument;if(!renderOptions.document&&ownerDocument!==document){renderOptions.document=ownerDocument}for(var i=0;i-1?prop.substr(colonPosition+1):prop;node.removeAttributeNS(this.namespace,localName)};AttributeHook.prototype.type="AttributeHook"},{}],42:[function(require,module,exports){"use strict";var EvStore=require("ev-store");module.exports=EvHook;function EvHook(value){if(!(this instanceof EvHook)){return new EvHook(value)}this.value=value}EvHook.prototype.hook=function(node,propertyName){var es=EvStore(node);var propName=propertyName.substr(3);es[propName]=this.value};EvHook.prototype.unhook=function(node,propertyName){var es=EvStore(node);var propName=propertyName.substr(3);es[propName]=undefined}},{"ev-store":29}],43:[function(require,module,exports){"use strict";module.exports=SoftSetHook;function SoftSetHook(value){if(!(this instanceof SoftSetHook)){return new SoftSetHook(value)}this.value=value}SoftSetHook.prototype.hook=function(node,propertyName){if(node[propertyName]!==this.value){node[propertyName]=this.value}}},{}],44:[function(require,module,exports){"use strict";var split=require("browser-split");var classIdSplit=/([\.#]?[a-zA-Z0-9\u007F-\uFFFF_:-]+)/;var notClassId=/^\.|#/;module.exports=parseTag;function parseTag(tag,props){if(!tag){return"DIV"}var noId=!props.hasOwnProperty("id");var tagParts=split(tag,classIdSplit);var tagName=null;if(notClassId.test(tagParts[1])){tagName="DIV"}var classes,part,type,i;for(i=0;ibLen?aLen:bLen;for(var i=0;i=bFree.length?bChildren.length:bFree[freeIndex];for(var j=0;j=lastFreeIndex){newChildren.push(newItem)}}var simulate=newChildren.slice();var simulateIndex=0;var removes=[];var inserts=[];var simulateItem;for(var k=0;k1?_len-1:0),_key=1;_key<_len;_key++){rest[_key-1]=arguments[_key]}var sinks=dataflowComponent.apply(undefined,[scopedSources].concat(rest));var scopedSinks={};for(var key in sinks){if(sinks.hasOwnProperty(key)&&sources.hasOwnProperty(key)&&typeof sources[key].isolateSink==="function"){scopedSinks[key]=sources[key].isolateSink(sinks[key],scope)}else if(sinks.hasOwnProperty(key)){scopedSinks[key]=sinks[key]}}return scopedSinks}}isolate.reset=function(){return counter=0};module.exports=isolate},{}],60:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.default=storageDriver;var _writeToStore=require("./writeToStore");var _writeToStore2=_interopRequireDefault(_writeToStore);var _responseCollection=require("./responseCollection");var _responseCollection2=_interopRequireDefault(_responseCollection);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}function storageDriver(request$){request$.subscribe(function(request){return(0,_writeToStore2.default)(request)});return(0,_responseCollection2.default)(request$)}},{"./responseCollection":61,"./writeToStore":63}],61:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.default=function(request$){return{get local(){return(0,_util2.default)(request$)},get session(){return(0,_util2.default)(request$,"session")}}};var _util=require("./util");var _util2=_interopRequireDefault(_util);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}},{"./util":62}],62:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.default=getResponseObj;var _rx=require("rx");var _rx2=_interopRequireDefault(_rx);function _interopRequireDefault(obj){return obj&&obj.__esModule?obj:{"default":obj}}function getStorage$(request$,type){return _rx2.default.Observable.if(function(){return type==="local"},request$.filter(function(req){return!req.target||req.target==="local"}),request$.filter(function(req){return req.target==="session"}))}function storageKey(n,request$){var type=arguments.length<=2||arguments[2]===undefined?"local":arguments[2];var storage$=getStorage$(request$,type);var key=type==="local"?localStorage.key(n):sessionStorage.key(n);return storage$.filter(function(req){return req.key===key}).map(function(req){return req.key}).startWith(key).distinctUntilChanged()}function storageGetItem(key,request$){var type=arguments.length<=2||arguments[2]===undefined?"local":arguments[2];var storage$=getStorage$(request$,type);var storageObj=type==="local"?localStorage:sessionStorage;return storage$.filter(function(req){return req.key===key}).map(function(req){return req.value}).startWith(storageObj.getItem(key))}function getResponseObj(request$){var type=arguments.length<=1||arguments[1]===undefined?"local":arguments[1];return{key:function key(n){return storageKey(n,request$,type)},getItem:function getItem(key){return storageGetItem(key,request$,type)}}}},{rx:66}],63:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});function writeToStore(_ref){var _ref$target=_ref.target;var target=_ref$target===undefined?"local":_ref$target;var _ref$action=_ref.action;var action=_ref$action===undefined?"setItem":_ref$action;var key=_ref.key;var value=_ref.value;var storage=target==="local"?localStorage:sessionStorage;storage[action](key,value)}exports.default=writeToStore},{}],64:[function(require,module,exports){},{}],65:[function(require,module,exports){var process=module.exports={};var queue=[];var draining=false;var currentQueue;var queueIndex=-1;function cleanUpNextTick(){draining=false;if(currentQueue.length){queue=currentQueue.concat(queue)}else{queueIndex=-1}if(queue.length){drainQueue()}}function drainQueue(){if(draining){return}var timeout=setTimeout(cleanUpNextTick);draining=true;var len=queue.length;while(len){currentQueue=queue;queue=[];while(++queueIndex1){for(var i=1;iy?1:x=rStartingLine&&lineNumber<=rEndingLine}function isNodeFrame(stackLine){return stackLine.indexOf("(module.js:")!==-1||stackLine.indexOf("(node.js:")!==-1}function captureLine(){if(!hasStacks){return}try{throw new Error}catch(e){var lines=e.stack.split("\n");var firstLine=lines[0].indexOf("@")>0?lines[1]:lines[2];var fileNameAndLineNumber=getFileNameAndLineNumber(firstLine);if(!fileNameAndLineNumber){return}rFileName=fileNameAndLineNumber[0];return fileNameAndLineNumber[1]}}function getFileNameAndLineNumber(stackLine){var attempt1=/at .+ \((.+):(\d+):(?:\d+)\)$/.exec(stackLine);if(attempt1){return[attempt1[1],Number(attempt1[2])]}var attempt2=/at ([^ ]+):(\d+):(?:\d+)$/.exec(stackLine);if(attempt2){return[attempt2[1],Number(attempt2[2])]}var attempt3=/.*@(.+):(\d+)$/.exec(stackLine);if(attempt3){return[attempt3[1],Number(attempt3[2])]}}var EmptyError=Rx.EmptyError=function(){this.message="Sequence contains no elements.";Error.call(this)};EmptyError.prototype=Object.create(Error.prototype);EmptyError.prototype.name="EmptyError";var ObjectDisposedError=Rx.ObjectDisposedError=function(){this.message="Object has been disposed";Error.call(this)};ObjectDisposedError.prototype=Object.create(Error.prototype);ObjectDisposedError.prototype.name="ObjectDisposedError";var ArgumentOutOfRangeError=Rx.ArgumentOutOfRangeError=function(){this.message="Argument out of range";Error.call(this)};ArgumentOutOfRangeError.prototype=Object.create(Error.prototype);ArgumentOutOfRangeError.prototype.name="ArgumentOutOfRangeError";var NotSupportedError=Rx.NotSupportedError=function(message){this.message=message||"This operation is not supported";Error.call(this)};NotSupportedError.prototype=Object.create(Error.prototype);NotSupportedError.prototype.name="NotSupportedError";var NotImplementedError=Rx.NotImplementedError=function(message){this.message=message||"This operation is not implemented";Error.call(this)};NotImplementedError.prototype=Object.create(Error.prototype);NotImplementedError.prototype.name="NotImplementedError";var notImplemented=Rx.helpers.notImplemented=function(){throw new NotImplementedError};var notSupported=Rx.helpers.notSupported=function(){throw new NotSupportedError};var $iterator$=typeof Symbol==="function"&&Symbol.iterator||"_es6shim_iterator_";if(root.Set&&typeof(new root.Set)["@@iterator"]==="function"){$iterator$="@@iterator"}var doneEnumerator=Rx.doneEnumerator={done:true,value:undefined};var isIterable=Rx.helpers.isIterable=function(o){return o&&o[$iterator$]!==undefined};var isArrayLike=Rx.helpers.isArrayLike=function(o){return o&&o.length!==undefined};Rx.helpers.iterator=$iterator$;var bindCallback=Rx.internals.bindCallback=function(func,thisArg,argCount){if(typeof thisArg==="undefined"){return func}switch(argCount){case 0:return function(){return func.call(thisArg)};case 1:return function(arg){return func.call(thisArg,arg)};case 2:return function(value,index){return func.call(thisArg,value,index)};case 3:return function(value,index,collection){return func.call(thisArg,value,index,collection)}}return function(){return func.apply(thisArg,arguments)}};var dontEnums=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],dontEnumsLength=dontEnums.length;var argsTag="[object Arguments]",arrayTag="[object Array]",boolTag="[object Boolean]",dateTag="[object Date]",errorTag="[object Error]",funcTag="[object Function]",mapTag="[object Map]",numberTag="[object Number]",objectTag="[object Object]",regexpTag="[object RegExp]",setTag="[object Set]",stringTag="[object String]",weakMapTag="[object WeakMap]";var arrayBufferTag="[object ArrayBuffer]",float32Tag="[object Float32Array]",float64Tag="[object Float64Array]",int8Tag="[object Int8Array]",int16Tag="[object Int16Array]",int32Tag="[object Int32Array]",uint8Tag="[object Uint8Array]",uint8ClampedTag="[object Uint8ClampedArray]",uint16Tag="[object Uint16Array]",uint32Tag="[object Uint32Array]";var typedArrayTags={};typedArrayTags[float32Tag]=typedArrayTags[float64Tag]=typedArrayTags[int8Tag]=typedArrayTags[int16Tag]=typedArrayTags[int32Tag]=typedArrayTags[uint8Tag]=typedArrayTags[uint8ClampedTag]=typedArrayTags[uint16Tag]=typedArrayTags[uint32Tag]=true;typedArrayTags[argsTag]=typedArrayTags[arrayTag]=typedArrayTags[arrayBufferTag]=typedArrayTags[boolTag]=typedArrayTags[dateTag]=typedArrayTags[errorTag]=typedArrayTags[funcTag]=typedArrayTags[mapTag]=typedArrayTags[numberTag]=typedArrayTags[objectTag]=typedArrayTags[regexpTag]=typedArrayTags[setTag]=typedArrayTags[stringTag]=typedArrayTags[weakMapTag]=false;var objectProto=Object.prototype,hasOwnProperty=objectProto.hasOwnProperty,objToString=objectProto.toString,MAX_SAFE_INTEGER=Math.pow(2,53)-1;var keys=Object.keys||function(){var hasOwnProperty=Object.prototype.hasOwnProperty,hasDontEnumBug=!{toString:null}.propertyIsEnumerable("toString"),dontEnums=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],dontEnumsLength=dontEnums.length;return function(obj){if(typeof obj!=="object"&&(typeof obj!=="function"||obj===null)){throw new TypeError("Object.keys called on non-object")}var result=[],prop,i;for(prop in obj){if(hasOwnProperty.call(obj,prop)){result.push(prop)}}if(hasDontEnumBug){for(i=0;i-1&&value%1===0&&value<=MAX_SAFE_INTEGER}var isHostObject=function(){try{Object({toString:0}+"")}catch(e){return function(){return false}}return function(value){return typeof value.toString!=="function"&&typeof(value+"")==="string"}}();function isTypedArray(value){return isObjectLike(value)&&isLength(value.length)&&!!typedArrayTags[objToString.call(value)]}var isArray=Array.isArray||function(value){return isObjectLike(value)&&isLength(value.length)&&objToString.call(value)===arrayTag};function arraySome(array,predicate){var index=-1,length=array.length;while(++indexarrLength)){return false}while(++index=this.length||index<0){return}var parent=index-1>>1;if(parent<0||parent===index){return}if(this.isHigherPriority(index,parent)){var temp=this.items[index];this.items[index]=this.items[parent];this.items[parent]=temp;this.percolate(parent)}};priorityProto.heapify=function(index){+index||(index=0);if(index>=this.length||index<0){return}var left=2*index+1,right=2*index+2,first=index;if(left0){var item=queue.dequeue();!item.isCancelled()&&item.invoke()}}inherits(CurrentThreadScheduler,__super__);function CurrentThreadScheduler(){__super__.call(this)}CurrentThreadScheduler.prototype.schedule=function(state,action){var si=new ScheduledItem(this,state,action,this.now());if(!queue){queue=new PriorityQueue(4);queue.enqueue(si);var result=tryCatch(runTrampoline)();queue=null;if(result===errorObj){thrower(result.e)}}else{queue.enqueue(si)}return si.disposable};CurrentThreadScheduler.prototype.scheduleRequired=function(){return!queue};return CurrentThreadScheduler}(Scheduler);var currentThreadScheduler=Scheduler.currentThread=new CurrentThreadScheduler;var scheduleMethod,clearMethod;var localTimer=function(){var localSetTimeout,localClearTimeout=noop;if(!!root.setTimeout){localSetTimeout=root.setTimeout;localClearTimeout=root.clearTimeout}else if(!!root.WScript){localSetTimeout=function(fn,time){root.WScript.Sleep(time);fn()}}else{throw new NotSupportedError}return{setTimeout:localSetTimeout,clearTimeout:localClearTimeout}}();var localSetTimeout=localTimer.setTimeout,localClearTimeout=localTimer.clearTimeout;(function(){var nextHandle=1,tasksByHandle={},currentlyRunning=false;clearMethod=function(handle){delete tasksByHandle[handle]};function runTask(handle){if(currentlyRunning){localSetTimeout(function(){runTask(handle)},0)}else{var task=tasksByHandle[handle];if(task){currentlyRunning=true;var result=tryCatch(task)();clearMethod(handle);currentlyRunning=false;if(result===errorObj){thrower(result.e)}}}}var reNative=new RegExp("^"+String(toString).replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/toString| for [^\]]+/g,".*?")+"$");var setImmediate=typeof(setImmediate=freeGlobal&&moduleExports&&freeGlobal.setImmediate)=="function"&&!reNative.test(setImmediate)&&setImmediate;function postMessageSupported(){if(!root.postMessage||root.importScripts){return false}var isAsync=false,oldHandler=root.onmessage;root.onmessage=function(){isAsync=true};root.postMessage("","*");root.onmessage=oldHandler;return isAsync}if(isFunction(setImmediate)){scheduleMethod=function(action){var id=nextHandle++;tasksByHandle[id]=action;setImmediate(function(){runTask(id)});return id}}else if(typeof process!=="undefined"&&{}.toString.call(process)==="[object process]"){
+scheduleMethod=function(action){var id=nextHandle++;tasksByHandle[id]=action;process.nextTick(function(){runTask(id)});return id}}else if(postMessageSupported()){var MSG_PREFIX="ms.rx.schedule"+Math.random();var onGlobalPostMessage=function(event){if(typeof event.data==="string"&&event.data.substring(0,MSG_PREFIX.length)===MSG_PREFIX){runTask(event.data.substring(MSG_PREFIX.length))}};root.addEventListener("message",onGlobalPostMessage,false);scheduleMethod=function(action){var id=nextHandle++;tasksByHandle[id]=action;root.postMessage(MSG_PREFIX+currentId,"*");return id}}else if(!!root.MessageChannel){var channel=new root.MessageChannel;channel.port1.onmessage=function(e){runTask(e.data)};scheduleMethod=function(action){var id=nextHandle++;tasksByHandle[id]=action;channel.port2.postMessage(id);return id}}else if("document"in root&&"onreadystatechange"in root.document.createElement("script")){scheduleMethod=function(action){var scriptElement=root.document.createElement("script");var id=nextHandle++;tasksByHandle[id]=action;scriptElement.onreadystatechange=function(){runTask(id);scriptElement.onreadystatechange=null;scriptElement.parentNode.removeChild(scriptElement);scriptElement=null};root.document.documentElement.appendChild(scriptElement);return id}}else{scheduleMethod=function(action){var id=nextHandle++;tasksByHandle[id]=action;localSetTimeout(function(){runTask(id)},0);return id}}})();var DefaultScheduler=function(__super__){inherits(DefaultScheduler,__super__);function DefaultScheduler(){__super__.call(this)}function scheduleAction(disposable,action,scheduler,state){return function schedule(){disposable.setDisposable(Disposable._fixup(action(scheduler,state)))}}function ClearDisposable(id){this._id=id;this.isDisposed=false}ClearDisposable.prototype.dispose=function(){if(!this.isDisposed){this.isDisposed=true;clearMethod(this._id)}};function LocalClearDisposable(id){this._id=id;this.isDisposed=false}LocalClearDisposable.prototype.dispose=function(){if(!this.isDisposed){this.isDisposed=true;localClearTimeout(this._id)}};DefaultScheduler.prototype.schedule=function(state,action){var disposable=new SingleAssignmentDisposable,id=scheduleMethod(scheduleAction(disposable,action,this,state));return new BinaryDisposable(disposable,new ClearDisposable(id))};DefaultScheduler.prototype._scheduleFuture=function(state,dueTime,action){if(dueTime===0){return this.schedule(state,action)}var disposable=new SingleAssignmentDisposable,id=localSetTimeout(scheduleAction(disposable,action,this,state),dueTime);return new BinaryDisposable(disposable,new LocalClearDisposable(id))};return DefaultScheduler}(Scheduler);var defaultScheduler=Scheduler["default"]=Scheduler.async=new DefaultScheduler;var CatchScheduler=function(__super__){inherits(CatchScheduler,__super__);function CatchScheduler(scheduler,handler){this._scheduler=scheduler;this._handler=handler;this._recursiveOriginal=null;this._recursiveWrapper=null;__super__.call(this)}CatchScheduler.prototype.schedule=function(state,action){return this._scheduler.schedule(state,this._wrap(action))};CatchScheduler.prototype._scheduleFuture=function(state,dueTime,action){return this._scheduler.schedule(state,dueTime,this._wrap(action))};CatchScheduler.prototype.now=function(){return this._scheduler.now()};CatchScheduler.prototype._clone=function(scheduler){return new CatchScheduler(scheduler,this._handler)};CatchScheduler.prototype._wrap=function(action){var parent=this;return function(self,state){var res=tryCatch(action)(parent._getRecursiveWrapper(self),state);if(res===errorObj){if(!parent._handler(res.e)){thrower(res.e)}return disposableEmpty}return disposableFixup(res)}};CatchScheduler.prototype._getRecursiveWrapper=function(scheduler){if(this._recursiveOriginal!==scheduler){this._recursiveOriginal=scheduler;var wrapper=this._clone(scheduler);wrapper._recursiveOriginal=scheduler;wrapper._recursiveWrapper=wrapper;this._recursiveWrapper=wrapper}return this._recursiveWrapper};CatchScheduler.prototype.schedulePeriodic=function(state,period,action){var self=this,failed=false,d=new SingleAssignmentDisposable;d.setDisposable(this._scheduler.schedulePeriodic(state,period,function(state1){if(failed){return null}var res=tryCatch(action)(state1);if(res===errorObj){failed=true;if(!self._handler(res.e)){thrower(res.e)}d.dispose();return null}return res}));return d};return CatchScheduler}(Scheduler);var Notification=Rx.Notification=function(){function Notification(){}Notification.prototype._accept=function(onNext,onError,onCompleted){throw new NotImplementedError};Notification.prototype._acceptObserver=function(onNext,onError,onCompleted){throw new NotImplementedError};Notification.prototype.accept=function(observerOrOnNext,onError,onCompleted){return observerOrOnNext&&typeof observerOrOnNext==="object"?this._acceptObserver(observerOrOnNext):this._accept(observerOrOnNext,onError,onCompleted)};Notification.prototype.toObservable=function(scheduler){var self=this;isScheduler(scheduler)||(scheduler=immediateScheduler);return new AnonymousObservable(function(o){return scheduler.schedule(self,function(_,notification){notification._acceptObserver(o);notification.kind==="N"&&o.onCompleted()})})};return Notification}();var OnNextNotification=function(__super__){inherits(OnNextNotification,__super__);function OnNextNotification(value){this.value=value;this.kind="N"}OnNextNotification.prototype._accept=function(onNext){return onNext(this.value)};OnNextNotification.prototype._acceptObserver=function(o){return o.onNext(this.value)};OnNextNotification.prototype.toString=function(){return"OnNext("+this.value+")"};return OnNextNotification}(Notification);var OnErrorNotification=function(__super__){inherits(OnErrorNotification,__super__);function OnErrorNotification(error){this.error=error;this.kind="E"}OnErrorNotification.prototype._accept=function(onNext,onError){return onError(this.error)};OnErrorNotification.prototype._acceptObserver=function(o){return o.onError(this.error)};OnErrorNotification.prototype.toString=function(){return"OnError("+this.error+")"};return OnErrorNotification}(Notification);var OnCompletedNotification=function(__super__){inherits(OnCompletedNotification,__super__);function OnCompletedNotification(){this.kind="C"}OnCompletedNotification.prototype._accept=function(onNext,onError,onCompleted){return onCompleted()};OnCompletedNotification.prototype._acceptObserver=function(o){return o.onCompleted()};OnCompletedNotification.prototype.toString=function(){return"OnCompleted()"};return OnCompletedNotification}(Notification);var notificationCreateOnNext=Notification.createOnNext=function(value){return new OnNextNotification(value)};var notificationCreateOnError=Notification.createOnError=function(error){return new OnErrorNotification(error)};var notificationCreateOnCompleted=Notification.createOnCompleted=function(){return new OnCompletedNotification};var Observer=Rx.Observer=function(){};Observer.prototype.toNotifier=function(){var observer=this;return function(n){return n.accept(observer)}};Observer.prototype.asObserver=function(){var self=this;return new AnonymousObserver(function(x){self.onNext(x)},function(err){self.onError(err)},function(){self.onCompleted()})};Observer.prototype.checked=function(){return new CheckedObserver(this)};var observerCreate=Observer.create=function(onNext,onError,onCompleted){onNext||(onNext=noop);onError||(onError=defaultError);onCompleted||(onCompleted=noop);return new AnonymousObserver(onNext,onError,onCompleted)};Observer.fromNotifier=function(handler,thisArg){var cb=bindCallback(handler,thisArg,1);return new AnonymousObserver(function(x){return cb(notificationCreateOnNext(x))},function(e){return cb(notificationCreateOnError(e))},function(){return cb(notificationCreateOnCompleted())})};Observer.prototype.notifyOn=function(scheduler){return new ObserveOnObserver(scheduler,this)};Observer.prototype.makeSafe=function(disposable){return new AnonymousSafeObserver(this._onNext,this._onError,this._onCompleted,disposable)};var AbstractObserver=Rx.internals.AbstractObserver=function(__super__){inherits(AbstractObserver,__super__);function AbstractObserver(){this.isStopped=false}AbstractObserver.prototype.next=notImplemented;AbstractObserver.prototype.error=notImplemented;AbstractObserver.prototype.completed=notImplemented;AbstractObserver.prototype.onNext=function(value){!this.isStopped&&this.next(value)};AbstractObserver.prototype.onError=function(error){if(!this.isStopped){this.isStopped=true;this.error(error)}};AbstractObserver.prototype.onCompleted=function(){if(!this.isStopped){this.isStopped=true;this.completed()}};AbstractObserver.prototype.dispose=function(){this.isStopped=true};AbstractObserver.prototype.fail=function(e){if(!this.isStopped){this.isStopped=true;this.error(e);return true}return false};return AbstractObserver}(Observer);var AnonymousObserver=Rx.AnonymousObserver=function(__super__){inherits(AnonymousObserver,__super__);function AnonymousObserver(onNext,onError,onCompleted){__super__.call(this);this._onNext=onNext;this._onError=onError;this._onCompleted=onCompleted}AnonymousObserver.prototype.next=function(value){this._onNext(value)};AnonymousObserver.prototype.error=function(error){this._onError(error)};AnonymousObserver.prototype.completed=function(){this._onCompleted()};return AnonymousObserver}(AbstractObserver);var CheckedObserver=function(__super__){inherits(CheckedObserver,__super__);function CheckedObserver(observer){__super__.call(this);this._observer=observer;this._state=0}var CheckedObserverPrototype=CheckedObserver.prototype;CheckedObserverPrototype.onNext=function(value){this.checkAccess();var res=tryCatch(this._observer.onNext).call(this._observer,value);this._state=0;res===errorObj&&thrower(res.e)};CheckedObserverPrototype.onError=function(err){this.checkAccess();var res=tryCatch(this._observer.onError).call(this._observer,err);this._state=2;res===errorObj&&thrower(res.e)};CheckedObserverPrototype.onCompleted=function(){this.checkAccess();var res=tryCatch(this._observer.onCompleted).call(this._observer);this._state=2;res===errorObj&&thrower(res.e)};CheckedObserverPrototype.checkAccess=function(){if(this._state===1){throw new Error("Re-entrancy detected")}if(this._state===2){throw new Error("Observer completed")}if(this._state===0){this._state=1}};return CheckedObserver}(Observer);var ScheduledObserver=Rx.internals.ScheduledObserver=function(__super__){inherits(ScheduledObserver,__super__);function ScheduledObserver(scheduler,observer){__super__.call(this);this.scheduler=scheduler;this.observer=observer;this.isAcquired=false;this.hasFaulted=false;this.queue=[];this.disposable=new SerialDisposable}function enqueueNext(observer,x){return function(){observer.onNext(x)}}function enqueueError(observer,e){return function(){observer.onError(e)}}function enqueueCompleted(observer){return function(){observer.onCompleted()}}ScheduledObserver.prototype.next=function(x){this.queue.push(enqueueNext(this.observer,x))};ScheduledObserver.prototype.error=function(e){this.queue.push(enqueueError(this.observer,e))};ScheduledObserver.prototype.completed=function(){this.queue.push(enqueueCompleted(this.observer))};function scheduleMethod(state,recurse){var work;if(state.queue.length>0){work=state.queue.shift()}else{state.isAcquired=false;return}var res=tryCatch(work)();if(res===errorObj){state.queue=[];state.hasFaulted=true;return thrower(res.e)}recurse(state)}ScheduledObserver.prototype.ensureActive=function(){var isOwner=false;if(!this.hasFaulted&&this.queue.length>0){isOwner=!this.isAcquired;this.isAcquired=true}isOwner&&this.disposable.setDisposable(this.scheduler.scheduleRecursive(this,scheduleMethod))};ScheduledObserver.prototype.dispose=function(){__super__.prototype.dispose.call(this);this.disposable.dispose()};return ScheduledObserver}(AbstractObserver);var ObserveOnObserver=function(__super__){inherits(ObserveOnObserver,__super__);function ObserveOnObserver(scheduler,observer,cancel){__super__.call(this,scheduler,observer);this._cancel=cancel}ObserveOnObserver.prototype.next=function(value){__super__.prototype.next.call(this,value);this.ensureActive()};ObserveOnObserver.prototype.error=function(e){__super__.prototype.error.call(this,e);this.ensureActive()};ObserveOnObserver.prototype.completed=function(){__super__.prototype.completed.call(this);this.ensureActive()};ObserveOnObserver.prototype.dispose=function(){__super__.prototype.dispose.call(this);this._cancel&&this._cancel.dispose();this._cancel=null};return ObserveOnObserver}(ScheduledObserver);var observableProto;var Observable=Rx.Observable=function(){function makeSubscribe(self,subscribe){return function(o){var oldOnError=o.onError;o.onError=function(e){makeStackTraceLong(e,self);oldOnError.call(o,e)};return subscribe.call(self,o)}}function Observable(){if(Rx.config.longStackSupport&&hasStacks){var oldSubscribe=this._subscribe;var e=tryCatch(thrower)(new Error).e;this.stack=e.stack.substring(e.stack.indexOf("\n")+1);this._subscribe=makeSubscribe(this,oldSubscribe)}}observableProto=Observable.prototype;Observable.isObservable=function(o){return o&&isFunction(o.subscribe)};observableProto.subscribe=observableProto.forEach=function(oOrOnNext,onError,onCompleted){return this._subscribe(typeof oOrOnNext==="object"?oOrOnNext:observerCreate(oOrOnNext,onError,onCompleted))};observableProto.subscribeOnNext=function(onNext,thisArg){return this._subscribe(observerCreate(typeof thisArg!=="undefined"?function(x){onNext.call(thisArg,x)}:onNext))};observableProto.subscribeOnError=function(onError,thisArg){return this._subscribe(observerCreate(null,typeof thisArg!=="undefined"?function(e){onError.call(thisArg,e)}:onError))};observableProto.subscribeOnCompleted=function(onCompleted,thisArg){return this._subscribe(observerCreate(null,null,typeof thisArg!=="undefined"?function(){onCompleted.call(thisArg)}:onCompleted))};return Observable}();var ObservableBase=Rx.ObservableBase=function(__super__){inherits(ObservableBase,__super__);function fixSubscriber(subscriber){return subscriber&&isFunction(subscriber.dispose)?subscriber:isFunction(subscriber)?disposableCreate(subscriber):disposableEmpty}function setDisposable(s,state){var ado=state[0],self=state[1];var sub=tryCatch(self.subscribeCore).call(self,ado);if(sub===errorObj&&!ado.fail(errorObj.e)){thrower(errorObj.e)}ado.setDisposable(fixSubscriber(sub))}function ObservableBase(){__super__.call(this)}ObservableBase.prototype._subscribe=function(o){var ado=new AutoDetachObserver(o),state=[ado,this];if(currentThreadScheduler.scheduleRequired()){currentThreadScheduler.schedule(state,setDisposable)}else{setDisposable(null,state)}return ado};ObservableBase.prototype.subscribeCore=notImplemented;return ObservableBase}(Observable);var FlatMapObservable=Rx.FlatMapObservable=function(__super__){inherits(FlatMapObservable,__super__);function FlatMapObservable(source,selector,resultSelector,thisArg){this.resultSelector=isFunction(resultSelector)?resultSelector:null;this.selector=bindCallback(isFunction(selector)?selector:function(){return selector},thisArg,3);this.source=source;__super__.call(this)}FlatMapObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new InnerObserver(o,this.selector,this.resultSelector,this))};inherits(InnerObserver,AbstractObserver);function InnerObserver(observer,selector,resultSelector,source){this.i=0;this.selector=selector;this.resultSelector=resultSelector;this.source=source;this.o=observer;AbstractObserver.call(this)}InnerObserver.prototype._wrapResult=function(result,x,i){return this.resultSelector?result.map(function(y,i2){return this.resultSelector(x,y,i,i2)},this):result};InnerObserver.prototype.next=function(x){var i=this.i++;var result=tryCatch(this.selector)(x,i,this.source);if(result===errorObj){return this.o.onError(result.e)}isPromise(result)&&(result=observableFromPromise(result));(isArrayLike(result)||isIterable(result))&&(result=Observable.from(result));this.o.onNext(this._wrapResult(result,x,i))};InnerObserver.prototype.error=function(e){this.o.onError(e)};InnerObserver.prototype.completed=function(){this.o.onCompleted()};return FlatMapObservable}(ObservableBase);var Enumerable=Rx.internals.Enumerable=function(){};function IsDisposedDisposable(state){this._s=state;this.isDisposed=false}IsDisposedDisposable.prototype.dispose=function(){if(!this.isDisposed){this.isDisposed=true;this._s.isDisposed=true}};var ConcatEnumerableObservable=function(__super__){inherits(ConcatEnumerableObservable,__super__);function ConcatEnumerableObservable(sources){this.sources=sources;__super__.call(this)}function scheduleMethod(state,recurse){if(state.isDisposed){return}var currentItem=tryCatch(state.e.next).call(state.e);if(currentItem===errorObj){return state.o.onError(currentItem.e)}if(currentItem.done){return state.o.onCompleted()}var currentValue=currentItem.value;isPromise(currentValue)&&(currentValue=observableFromPromise(currentValue));var d=new SingleAssignmentDisposable;state.subscription.setDisposable(d);d.setDisposable(currentValue.subscribe(new InnerObserver(state,recurse)))}ConcatEnumerableObservable.prototype.subscribeCore=function(o){var subscription=new SerialDisposable;var state={isDisposed:false,o:o,subscription:subscription,e:this.sources[$iterator$]()};var cancelable=currentThreadScheduler.scheduleRecursive(state,scheduleMethod);return new NAryDisposable([subscription,cancelable,new IsDisposedDisposable(state)])};function InnerObserver(state,recurse){this._state=state;this._recurse=recurse;AbstractObserver.call(this)}inherits(InnerObserver,AbstractObserver);InnerObserver.prototype.next=function(x){this._state.o.onNext(x)};InnerObserver.prototype.error=function(e){this._state.o.onError(e)};InnerObserver.prototype.completed=function(){this._recurse(this._state)};return ConcatEnumerableObservable}(ObservableBase);Enumerable.prototype.concat=function(){return new ConcatEnumerableObservable(this)};var CatchErrorObservable=function(__super__){function CatchErrorObservable(sources){this.sources=sources;__super__.call(this)}inherits(CatchErrorObservable,__super__);function scheduleMethod(state,recurse){if(state.isDisposed){return}var currentItem=tryCatch(state.e.next).call(state.e);if(currentItem===errorObj){return state.o.onError(currentItem.e)}if(currentItem.done){return state.lastError!==null?state.o.onError(state.lastError):state.o.onCompleted()}var currentValue=currentItem.value;isPromise(currentValue)&&(currentValue=observableFromPromise(currentValue));var d=new SingleAssignmentDisposable;state.subscription.setDisposable(d);d.setDisposable(currentValue.subscribe(new InnerObserver(state,recurse)))}CatchErrorObservable.prototype.subscribeCore=function(o){var subscription=new SerialDisposable;var state={isDisposed:false,e:this.sources[$iterator$](),subscription:subscription,lastError:null,o:o};var cancelable=currentThreadScheduler.scheduleRecursive(state,scheduleMethod);return new NAryDisposable([subscription,cancelable,new IsDisposedDisposable(state)])};function InnerObserver(state,recurse){this._state=state;this._recurse=recurse;AbstractObserver.call(this)}inherits(InnerObserver,AbstractObserver);InnerObserver.prototype.next=function(x){this._state.o.onNext(x)};InnerObserver.prototype.error=function(e){this._state.lastError=e;this._recurse(this._state)};InnerObserver.prototype.completed=function(){this._state.o.onCompleted()};return CatchErrorObservable}(ObservableBase);Enumerable.prototype.catchError=function(){return new CatchErrorObservable(this)};Enumerable.prototype.catchErrorWhen=function(notificationHandler){var sources=this;return new AnonymousObservable(function(o){var exceptions=new Subject,notifier=new Subject,handled=notificationHandler(exceptions),notificationDisposable=handled.subscribe(notifier);var e=sources[$iterator$]();var state={isDisposed:false},lastError,subscription=new SerialDisposable;var cancelable=currentThreadScheduler.scheduleRecursive(null,function(_,self){if(state.isDisposed){return}var currentItem=tryCatch(e.next).call(e);if(currentItem===errorObj){return o.onError(currentItem.e)}if(currentItem.done){if(lastError){o.onError(lastError)}else{o.onCompleted()}return}var currentValue=currentItem.value;isPromise(currentValue)&&(currentValue=observableFromPromise(currentValue));var outer=new SingleAssignmentDisposable;var inner=new SingleAssignmentDisposable;subscription.setDisposable(new BinaryDisposable(inner,outer));outer.setDisposable(currentValue.subscribe(function(x){o.onNext(x)},function(exn){inner.setDisposable(notifier.subscribe(self,function(ex){o.onError(ex)},function(){o.onCompleted()}));exceptions.onNext(exn)},function(){o.onCompleted()}))});return new NAryDisposable([notificationDisposable,subscription,cancelable,new IsDisposedDisposable(state)])})};var RepeatEnumerable=function(__super__){inherits(RepeatEnumerable,__super__);function RepeatEnumerable(v,c){this.v=v;this.c=c==null?-1:c}RepeatEnumerable.prototype[$iterator$]=function(){return new RepeatEnumerator(this)};function RepeatEnumerator(p){this.v=p.v;this.l=p.c}RepeatEnumerator.prototype.next=function(){if(this.l===0){return doneEnumerator}if(this.l>0){this.l--}return{done:false,value:this.v}};return RepeatEnumerable}(Enumerable);var enumerableRepeat=Enumerable.repeat=function(value,repeatCount){return new RepeatEnumerable(value,repeatCount)};var OfEnumerable=function(__super__){inherits(OfEnumerable,__super__);function OfEnumerable(s,fn,thisArg){this.s=s;this.fn=fn?bindCallback(fn,thisArg,3):null}OfEnumerable.prototype[$iterator$]=function(){return new OfEnumerator(this)};function OfEnumerator(p){this.i=-1;this.s=p.s;this.l=this.s.length;this.fn=p.fn}OfEnumerator.prototype.next=function(){return++this.imaxSafeInteger){return maxSafeInteger}return len}var observableFrom=Observable.from=function(iterable,mapFn,thisArg,scheduler){if(iterable==null){throw new Error("iterable cannot be null.")}if(mapFn&&!isFunction(mapFn)){throw new Error("mapFn when provided must be a function")}if(mapFn){var mapper=bindCallback(mapFn,thisArg,2)}isScheduler(scheduler)||(scheduler=currentThreadScheduler);return new FromObservable(iterable,mapper,scheduler)};var FromArrayObservable=function(__super__){inherits(FromArrayObservable,__super__);function FromArrayObservable(args,scheduler){this._args=args;this._scheduler=scheduler;__super__.call(this)}function scheduleMethod(o,args){var len=args.length;return function loopRecursive(i,recurse){if(i0){observer.onNext(value);i>0&&i--}if(i===0){return observer.onCompleted()}recurse(i)}return this.parent.scheduler.scheduleRecursive(this.parent.repeatCount,loopRecursive)};Observable.repeat=function(value,repeatCount,scheduler){isScheduler(scheduler)||(scheduler=currentThreadScheduler);return new RepeatObservable(value,repeatCount,scheduler)};var JustObservable=function(__super__){inherits(JustObservable,__super__);function JustObservable(value,scheduler){this._value=value;this._scheduler=scheduler;__super__.call(this)}JustObservable.prototype.subscribeCore=function(o){var state=[this._value,o];return this._scheduler===immediateScheduler?scheduleItem(null,state):this._scheduler.schedule(state,scheduleItem)};function scheduleItem(s,state){var value=state[0],observer=state[1];observer.onNext(value);observer.onCompleted();return disposableEmpty}return JustObservable}(ObservableBase);var observableReturn=Observable["return"]=Observable.just=function(value,scheduler){isScheduler(scheduler)||(scheduler=immediateScheduler);return new JustObservable(value,scheduler)};var ThrowObservable=function(__super__){inherits(ThrowObservable,__super__);function ThrowObservable(error,scheduler){this._error=error;this._scheduler=scheduler;__super__.call(this)}ThrowObservable.prototype.subscribeCore=function(o){var state=[this._error,o];return this._scheduler===immediateScheduler?scheduleItem(null,state):this._scheduler.schedule(state,scheduleItem)};function scheduleItem(s,state){var e=state[0],o=state[1];o.onError(e);return disposableEmpty}return ThrowObservable}(ObservableBase);var observableThrow=Observable["throw"]=function(error,scheduler){isScheduler(scheduler)||(scheduler=immediateScheduler);return new ThrowObservable(error,scheduler)};var UsingObservable=function(__super__){inherits(UsingObservable,__super__);function UsingObservable(resFn,obsFn){this._resFn=resFn;this._obsFn=obsFn;__super__.call(this)}UsingObservable.prototype.subscribeCore=function(o){var disposable=disposableEmpty;var resource=tryCatch(this._resFn)();if(resource===errorObj){return new BinaryDisposable(observableThrow(resource.e).subscribe(o),disposable)}resource&&(disposable=resource);var source=tryCatch(this._obsFn)(resource);if(source===errorObj){return new BinaryDisposable(observableThrow(source.e).subscribe(o),disposable)}return new BinaryDisposable(source.subscribe(o),disposable)};return UsingObservable}(ObservableBase);Observable.using=function(resourceFactory,observableFactory){return new UsingObservable(resourceFactory,observableFactory)};observableProto.amb=function(rightSource){var leftSource=this;return new AnonymousObservable(function(observer){var choice,leftChoice="L",rightChoice="R",leftSubscription=new SingleAssignmentDisposable,rightSubscription=new SingleAssignmentDisposable;isPromise(rightSource)&&(rightSource=observableFromPromise(rightSource));function choiceL(){if(!choice){choice=leftChoice;rightSubscription.dispose()}}function choiceR(){if(!choice){choice=rightChoice;leftSubscription.dispose()}}var leftSubscribe=observerCreate(function(left){choiceL();choice===leftChoice&&observer.onNext(left)},function(e){choiceL();choice===leftChoice&&observer.onError(e)},function(){choiceL();choice===leftChoice&&observer.onCompleted()});var rightSubscribe=observerCreate(function(right){choiceR();choice===rightChoice&&observer.onNext(right)},function(e){choiceR();choice===rightChoice&&observer.onError(e)},function(){choiceR();choice===rightChoice&&observer.onCompleted()});leftSubscription.setDisposable(leftSource.subscribe(leftSubscribe));rightSubscription.setDisposable(rightSource.subscribe(rightSubscribe));return new BinaryDisposable(leftSubscription,rightSubscription)})};function amb(p,c){return p.amb(c)}Observable.amb=function(){var acc=observableNever(),items;if(Array.isArray(arguments[0])){items=arguments[0]}else{var len=arguments.length;items=new Array(items);for(var i=0;i0){this.parent.handleSubscribe(this.parent.q.shift())}else{this.parent.activeCount--;this.parent.done&&this.parent.activeCount===0&&this.parent.o.onCompleted()}};return MergeObserver}(AbstractObserver);observableProto.merge=function(maxConcurrentOrOther){return typeof maxConcurrentOrOther!=="number"?observableMerge(this,maxConcurrentOrOther):new MergeObservable(this,maxConcurrentOrOther)};var observableMerge=Observable.merge=function(){var scheduler,sources=[],i,len=arguments.length;if(!arguments[0]){scheduler=immediateScheduler;for(i=1;i0}function shiftEach(x){return x.shift()}function notTheSame(i){return function(x,j){return j!==i}}ZipObserver.prototype.next=function(x){this._q[this._i].push(x);if(this._q.every(notEmpty)){var queuedValues=this._q.map(shiftEach);var res=tryCatch(this._p._cb).apply(null,queuedValues);if(res===errorObj){return this._o.onError(res.e)}this._o.onNext(res)}else if(this._d.filter(notTheSame(this._i)).every(identity)){this._o.onCompleted()}};ZipObserver.prototype.error=function(e){this._o.onError(e)};ZipObserver.prototype.completed=function(){this._d[this._i]=true;this._d.every(identity)&&this._o.onCompleted()};return ZipObserver}(AbstractObserver);observableProto.zip=function(){if(arguments.length===0){throw new Error("invalid arguments")}var len=arguments.length,args=new Array(len);for(var i=0;i0}function shiftEach(x){return x.shift()}function notTheSame(i){return function(x,j){return j!==i}}ZipIterableObserver.prototype.next=function(x){this._s.q[this._i].push(x);if(this._s.q.every(notEmpty)){var queuedValues=this._s.q.map(shiftEach),res=tryCatch(this._s.cb).apply(null,queuedValues);if(res===errorObj){return this._s.o.onError(res.e)}this._s.o.onNext(res)}else if(this._s.done.filter(notTheSame(this._i)).every(identity)){this._s.o.onCompleted()}};ZipIterableObserver.prototype.error=function(e){this._s.o.onError(e)};ZipIterableObserver.prototype.completed=function(){this._s.done[this._i]=true;
+this._s.done.every(identity)&&this._s.o.onCompleted()};return ZipIterableObserver}(AbstractObserver);observableProto.zipIterable=function(){if(arguments.length===0){throw new Error("invalid arguments")}var len=arguments.length,args=new Array(len);for(var i=0;i0}observableProto.bufferWithCount=function(count,skip){typeof skip!=="number"&&(skip=count);return this.windowWithCount(count,skip).flatMap(toArray).filter(notEmpty)};var DematerializeObservable=function(__super__){inherits(DematerializeObservable,__super__);function DematerializeObservable(source){this.source=source;__super__.call(this)}DematerializeObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new DematerializeObserver(o))};return DematerializeObservable}(ObservableBase);var DematerializeObserver=function(__super__){inherits(DematerializeObserver,__super__);function DematerializeObserver(o){this._o=o;__super__.call(this)}DematerializeObserver.prototype.next=function(x){x.accept(this._o)};DematerializeObserver.prototype.error=function(e){this._o.onError(e)};DematerializeObserver.prototype.completed=function(){this._o.onCompleted()};return DematerializeObserver}(AbstractObserver);observableProto.dematerialize=function(){return new DematerializeObservable(this)};var DistinctUntilChangedObservable=function(__super__){inherits(DistinctUntilChangedObservable,__super__);function DistinctUntilChangedObservable(source,keyFn,comparer){this.source=source;this.keyFn=keyFn;this.comparer=comparer;__super__.call(this)}DistinctUntilChangedObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new DistinctUntilChangedObserver(o,this.keyFn,this.comparer))};return DistinctUntilChangedObservable}(ObservableBase);var DistinctUntilChangedObserver=function(__super__){inherits(DistinctUntilChangedObserver,__super__);function DistinctUntilChangedObserver(o,keyFn,comparer){this.o=o;this.keyFn=keyFn;this.comparer=comparer;this.hasCurrentKey=false;this.currentKey=null;__super__.call(this)}DistinctUntilChangedObserver.prototype.next=function(x){var key=x,comparerEquals;if(isFunction(this.keyFn)){key=tryCatch(this.keyFn)(x);if(key===errorObj){return this.o.onError(key.e)}}if(this.hasCurrentKey){comparerEquals=tryCatch(this.comparer)(this.currentKey,key);if(comparerEquals===errorObj){return this.o.onError(comparerEquals.e)}}if(!this.hasCurrentKey||!comparerEquals){this.hasCurrentKey=true;this.currentKey=key;this.o.onNext(x)}};DistinctUntilChangedObserver.prototype.error=function(e){this.o.onError(e)};DistinctUntilChangedObserver.prototype.completed=function(){this.o.onCompleted()};return DistinctUntilChangedObserver}(AbstractObserver);observableProto.distinctUntilChanged=function(keyFn,comparer){comparer||(comparer=defaultComparer);return new DistinctUntilChangedObservable(this,keyFn,comparer)};var TapObservable=function(__super__){inherits(TapObservable,__super__);function TapObservable(source,observerOrOnNext,onError,onCompleted){this.source=source;this._oN=observerOrOnNext;this._oE=onError;this._oC=onCompleted;__super__.call(this)}TapObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new InnerObserver(o,this))};inherits(InnerObserver,AbstractObserver);function InnerObserver(o,p){this.o=o;this.t=!p._oN||isFunction(p._oN)?observerCreate(p._oN||noop,p._oE||noop,p._oC||noop):p._oN;this.isStopped=false;AbstractObserver.call(this)}InnerObserver.prototype.next=function(x){var res=tryCatch(this.t.onNext).call(this.t,x);if(res===errorObj){this.o.onError(res.e)}this.o.onNext(x)};InnerObserver.prototype.error=function(err){var res=tryCatch(this.t.onError).call(this.t,err);if(res===errorObj){return this.o.onError(res.e)}this.o.onError(err)};InnerObserver.prototype.completed=function(){var res=tryCatch(this.t.onCompleted).call(this.t);if(res===errorObj){return this.o.onError(res.e)}this.o.onCompleted()};return TapObservable}(ObservableBase);observableProto["do"]=observableProto.tap=observableProto.doAction=function(observerOrOnNext,onError,onCompleted){return new TapObservable(this,observerOrOnNext,onError,onCompleted)};observableProto.doOnNext=observableProto.tapOnNext=function(onNext,thisArg){return this.tap(typeof thisArg!=="undefined"?function(x){onNext.call(thisArg,x)}:onNext)};observableProto.doOnError=observableProto.tapOnError=function(onError,thisArg){return this.tap(noop,typeof thisArg!=="undefined"?function(e){onError.call(thisArg,e)}:onError)};observableProto.doOnCompleted=observableProto.tapOnCompleted=function(onCompleted,thisArg){return this.tap(noop,null,typeof thisArg!=="undefined"?function(){onCompleted.call(thisArg)}:onCompleted)};var FinallyObservable=function(__super__){inherits(FinallyObservable,__super__);function FinallyObservable(source,fn,thisArg){this.source=source;this._fn=bindCallback(fn,thisArg,0);__super__.call(this)}FinallyObservable.prototype.subscribeCore=function(o){var d=tryCatch(this.source.subscribe).call(this.source,o);if(d===errorObj){this._fn();thrower(d.e)}return new FinallyDisposable(d,this._fn)};function FinallyDisposable(s,fn){this.isDisposed=false;this._s=s;this._fn=fn}FinallyDisposable.prototype.dispose=function(){if(!this.isDisposed){var res=tryCatch(this._s.dispose).call(this._s);this._fn();res===errorObj&&thrower(res.e)}};return FinallyObservable}(ObservableBase);observableProto["finally"]=function(action,thisArg){return new FinallyObservable(this,action,thisArg)};var IgnoreElementsObservable=function(__super__){inherits(IgnoreElementsObservable,__super__);function IgnoreElementsObservable(source){this.source=source;__super__.call(this)}IgnoreElementsObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new InnerObserver(o))};function InnerObserver(o){this.o=o;this.isStopped=false}InnerObserver.prototype.onNext=noop;InnerObserver.prototype.onError=function(err){if(!this.isStopped){this.isStopped=true;this.o.onError(err)}};InnerObserver.prototype.onCompleted=function(){if(!this.isStopped){this.isStopped=true;this.o.onCompleted()}};InnerObserver.prototype.dispose=function(){this.isStopped=true};InnerObserver.prototype.fail=function(e){if(!this.isStopped){this.isStopped=true;this.observer.onError(e);return true}return false};return IgnoreElementsObservable}(ObservableBase);observableProto.ignoreElements=function(){return new IgnoreElementsObservable(this)};var MaterializeObservable=function(__super__){inherits(MaterializeObservable,__super__);function MaterializeObservable(source,fn){this.source=source;__super__.call(this)}MaterializeObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new MaterializeObserver(o))};return MaterializeObservable}(ObservableBase);var MaterializeObserver=function(__super__){inherits(MaterializeObserver,__super__);function MaterializeObserver(o){this._o=o;__super__.call(this)}MaterializeObserver.prototype.next=function(x){this._o.onNext(notificationCreateOnNext(x))};MaterializeObserver.prototype.error=function(e){this._o.onNext(notificationCreateOnError(e));this._o.onCompleted()};MaterializeObserver.prototype.completed=function(){this._o.onNext(notificationCreateOnCompleted());this._o.onCompleted()};return MaterializeObserver}(AbstractObserver);observableProto.materialize=function(){return new MaterializeObservable(this)};observableProto.repeat=function(repeatCount){return enumerableRepeat(this,repeatCount).concat()};observableProto.retry=function(retryCount){return enumerableRepeat(this,retryCount).catchError()};observableProto.retryWhen=function(notifier){return enumerableRepeat(this).catchErrorWhen(notifier)};var ScanObservable=function(__super__){inherits(ScanObservable,__super__);function ScanObservable(source,accumulator,hasSeed,seed){this.source=source;this.accumulator=accumulator;this.hasSeed=hasSeed;this.seed=seed;__super__.call(this)}ScanObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new ScanObserver(o,this))};return ScanObservable}(ObservableBase);var ScanObserver=function(__super__){inherits(ScanObserver,__super__);function ScanObserver(o,parent){this._o=o;this._p=parent;this._fn=parent.accumulator;this._hs=parent.hasSeed;this._s=parent.seed;this._ha=false;this._a=null;this._hv=false;this._i=0;__super__.call(this)}ScanObserver.prototype.next=function(x){!this._hv&&(this._hv=true);if(this._ha){this._a=tryCatch(this._fn)(this._a,x,this._i,this._p)}else{this._a=this._hs?tryCatch(this._fn)(this._s,x,this._i,this._p):x;this._ha=true}if(this._a===errorObj){return this._o.onError(this._a.e)}this._o.onNext(this._a);this._i++};ScanObserver.prototype.error=function(e){this._o.onError(e)};ScanObserver.prototype.completed=function(){!this._hv&&this._hs&&this._o.onNext(this._s);this._o.onCompleted()};return ScanObserver}(AbstractObserver);observableProto.scan=function(){var hasSeed=false,seed,accumulator=arguments[0];if(arguments.length===2){hasSeed=true;seed=arguments[1]}return new ScanObservable(this,accumulator,hasSeed,seed)};var SkipLastObservable=function(__super__){inherits(SkipLastObservable,__super__);function SkipLastObservable(source,c){this.source=source;this._c=c;__super__.call(this)}SkipLastObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new SkipLastObserver(o,this._c))};return SkipLastObservable}(ObservableBase);var SkipLastObserver=function(__super__){inherits(SkipLastObserver,__super__);function SkipLastObserver(o,c){this._o=o;this._c=c;this._q=[];__super__.call(this)}SkipLastObserver.prototype.next=function(x){this._q.push(x);this._q.length>this._c&&this._o.onNext(this._q.shift())};SkipLastObserver.prototype.error=function(e){this._o.onError(e)};SkipLastObserver.prototype.completed=function(){this._o.onCompleted()};return SkipLastObserver}(AbstractObserver);observableProto.skipLast=function(count){if(count<0){throw new ArgumentOutOfRangeError}return new SkipLastObservable(this,count)};observableProto.startWith=function(){var values,scheduler,start=0;if(!!arguments.length&&isScheduler(arguments[0])){scheduler=arguments[0];start=1}else{scheduler=immediateScheduler}for(var args=[],i=start,len=arguments.length;ithis._c&&this._q.shift()};TakeLastObserver.prototype.error=function(e){this._o.onError(e)};TakeLastObserver.prototype.completed=function(){while(this._q.length>0){this._o.onNext(this._q.shift())}this._o.onCompleted()};return TakeLastObserver}(AbstractObserver);observableProto.takeLast=function(count){if(count<0){throw new ArgumentOutOfRangeError}var source=this;return new AnonymousObservable(function(o){return source.subscribe(new TakeLastObserver(o,count))},source)};var TakeLastBufferObserver=function(__super__){inherits(TakeLastBufferObserver,__super__);function TakeLastBufferObserver(o,c){this._o=o;this._c=c;this._q=[];__super__.call(this)}TakeLastBufferObserver.prototype.next=function(x){this._q.push(x);this._q.length>this._c&&this._q.shift()};TakeLastBufferObserver.prototype.error=function(e){this._o.onError(e)};TakeLastBufferObserver.prototype.completed=function(){this._o.onNext(this._q);this._o.onCompleted()};return TakeLastBufferObserver}(AbstractObserver);observableProto.takeLastBuffer=function(count){if(count<0){throw new ArgumentOutOfRangeError}var source=this;return new AnonymousObservable(function(o){return source.subscribe(new TakeLastBufferObserver(o,count))},source)};observableProto.windowWithCount=function(count,skip){var source=this;+count||(count=0);Math.abs(count)===Infinity&&(count=0);if(count<=0){throw new ArgumentOutOfRangeError}skip==null&&(skip=count);+skip||(skip=0);Math.abs(skip)===Infinity&&(skip=0);if(skip<=0){throw new ArgumentOutOfRangeError}return new AnonymousObservable(function(observer){var m=new SingleAssignmentDisposable,refCountDisposable=new RefCountDisposable(m),n=0,q=[];function createWindow(){var s=new Subject;q.push(s);observer.onNext(addRef(s,refCountDisposable))}createWindow();m.setDisposable(source.subscribe(function(x){for(var i=0,len=q.length;i=0&&c%skip===0&&q.shift().onCompleted();++n%skip===0&&createWindow()},function(e){while(q.length>0){q.shift().onError(e)}observer.onError(e)},function(){while(q.length>0){q.shift().onCompleted()}observer.onCompleted()}));return refCountDisposable},source)};function concatMap(source,selector,thisArg){var selectorFunc=bindCallback(selector,thisArg,3);return source.map(function(x,i){var result=selectorFunc(x,i,source);isPromise(result)&&(result=observableFromPromise(result));(isArrayLike(result)||isIterable(result))&&(result=observableFrom(result));return result}).concatAll()}observableProto.selectConcat=observableProto.concatMap=function(selector,resultSelector,thisArg){if(isFunction(selector)&&isFunction(resultSelector)){return this.concatMap(function(x,i){var selectorResult=selector(x,i);isPromise(selectorResult)&&(selectorResult=observableFromPromise(selectorResult));(isArrayLike(selectorResult)||isIterable(selectorResult))&&(selectorResult=observableFrom(selectorResult));return selectorResult.map(function(y,i2){return resultSelector(x,y,i,i2)})})}return isFunction(selector)?concatMap(this,selector,thisArg):concatMap(this,function(){return selector})};observableProto.concatMapObserver=observableProto.selectConcatObserver=function(onNext,onError,onCompleted,thisArg){var source=this,onNextFunc=bindCallback(onNext,thisArg,2),onErrorFunc=bindCallback(onError,thisArg,1),onCompletedFunc=bindCallback(onCompleted,thisArg,0);return new AnonymousObservable(function(observer){var index=0;return source.subscribe(function(x){var result;try{result=onNextFunc(x,index++)}catch(e){observer.onError(e);return}isPromise(result)&&(result=observableFromPromise(result));observer.onNext(result)},function(err){var result;try{result=onErrorFunc(err)}catch(e){observer.onError(e);return}isPromise(result)&&(result=observableFromPromise(result));observer.onNext(result);observer.onCompleted()},function(){var result;try{result=onCompletedFunc()}catch(e){observer.onError(e);return}isPromise(result)&&(result=observableFromPromise(result));observer.onNext(result);observer.onCompleted()})},this).concatAll()};var DefaultIfEmptyObserver=function(__super__){inherits(DefaultIfEmptyObserver,__super__);function DefaultIfEmptyObserver(o,d){this._o=o;this._d=d;this._f=false;__super__.call(this)}DefaultIfEmptyObserver.prototype.next=function(x){this._f=true;this._o.onNext(x)};DefaultIfEmptyObserver.prototype.error=function(e){this._o.onError(e)};DefaultIfEmptyObserver.prototype.completed=function(){!this._f&&this._o.onNext(this._d);this._o.onCompleted()};return DefaultIfEmptyObserver}(AbstractObserver);observableProto.defaultIfEmpty=function(defaultValue){var source=this;defaultValue===undefined&&(defaultValue=null);return new AnonymousObservable(function(o){return source.subscribe(new DefaultIfEmptyObserver(o,defaultValue))},source)};function arrayIndexOfComparer(array,item,comparer){for(var i=0,len=array.length;i0){this._o.onNext(x);this._r<=0&&this._o.onCompleted()}};TakeObserver.prototype.error=function(e){this._o.onError(e)};TakeObserver.prototype.completed=function(){this._o.onCompleted()};return TakeObservable}(ObservableBase);observableProto.take=function(count,scheduler){if(count<0){throw new ArgumentOutOfRangeError}if(count===0){return observableEmpty(scheduler)}return new TakeObservable(this,count)};var TakeWhileObservable=function(__super__){inherits(TakeWhileObservable,__super__);function TakeWhileObservable(source,fn){this.source=source;this._fn=fn;__super__.call(this)}TakeWhileObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new TakeWhileObserver(o,this))};return TakeWhileObservable}(ObservableBase);var TakeWhileObserver=function(__super__){inherits(TakeWhileObserver,__super__);function TakeWhileObserver(o,p){this._o=o;this._p=p;this._i=0;this._r=true;__super__.call(this)}TakeWhileObserver.prototype.next=function(x){if(this._r){this._r=tryCatch(this._p._fn)(x,this._i++,this._p);if(this._r===errorObj){return this._o.onError(this._r.e)}}if(this._r){this._o.onNext(x)}else{this._o.onCompleted()}};TakeWhileObserver.prototype.error=function(e){this._o.onError(e)};TakeWhileObserver.prototype.completed=function(){this._o.onCompleted()};return TakeWhileObserver}(AbstractObserver);observableProto.takeWhile=function(predicate,thisArg){var fn=bindCallback(predicate,thisArg,3);return new TakeWhileObservable(this,fn)};var FilterObservable=function(__super__){inherits(FilterObservable,__super__);function FilterObservable(source,predicate,thisArg){this.source=source;this.predicate=bindCallback(predicate,thisArg,3);__super__.call(this)}FilterObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new InnerObserver(o,this.predicate,this))};function innerPredicate(predicate,self){return function(x,i,o){return self.predicate(x,i,o)&&predicate.call(this,x,i,o)}}FilterObservable.prototype.internalFilter=function(predicate,thisArg){return new FilterObservable(this.source,innerPredicate(predicate,this),thisArg)};inherits(InnerObserver,AbstractObserver);function InnerObserver(o,predicate,source){this.o=o;this.predicate=predicate;this.source=source;this.i=0;AbstractObserver.call(this)}InnerObserver.prototype.next=function(x){var shouldYield=tryCatch(this.predicate)(x,this.i++,this.source);if(shouldYield===errorObj){return this.o.onError(shouldYield.e)}shouldYield&&this.o.onNext(x)};InnerObserver.prototype.error=function(e){this.o.onError(e)};InnerObserver.prototype.completed=function(){this.o.onCompleted()};return FilterObservable}(ObservableBase);observableProto.filter=observableProto.where=function(predicate,thisArg){return this instanceof FilterObservable?this.internalFilter(predicate,thisArg):new FilterObservable(this,predicate,thisArg)};var ExtremaByObservable=function(__super__){inherits(ExtremaByObservable,__super__);function ExtremaByObservable(source,k,c){this.source=source;this._k=k;this._c=c;__super__.call(this)}ExtremaByObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new ExtremaByObserver(o,this._k,this._c))};return ExtremaByObservable}(ObservableBase);var ExtremaByObserver=function(__super__){inherits(ExtremaByObserver,__super__);function ExtremaByObserver(o,k,c){this._o=o;this._k=k;this._c=c;this._v=null;this._hv=false;this._l=[];__super__.call(this)}ExtremaByObserver.prototype.next=function(x){var key=tryCatch(this._k)(x);if(key===errorObj){return this._o.onError(key.e)}var comparison=0;if(!this._hv){this._hv=true;this._v=key}else{comparison=tryCatch(this._c)(key,this._v);if(comparison===errorObj){return this._o.onError(comparison.e)}}if(comparison>0){this._v=key;this._l=[]}if(comparison>=0){this._l.push(x)}};ExtremaByObserver.prototype.error=function(e){this._o.onError(e)};ExtremaByObserver.prototype.completed=function(){this._o.onNext(this._l);this._o.onCompleted()};return ExtremaByObserver}(AbstractObserver);function firstOnly(x){if(x.length===0){throw new EmptyError}return x[0]}var ReduceObservable=function(__super__){inherits(ReduceObservable,__super__);function ReduceObservable(source,accumulator,hasSeed,seed){this.source=source;this.accumulator=accumulator;this.hasSeed=hasSeed;this.seed=seed;__super__.call(this)}ReduceObservable.prototype.subscribeCore=function(observer){return this.source.subscribe(new ReduceObserver(observer,this))};return ReduceObservable}(ObservableBase);var ReduceObserver=function(__super__){inherits(ReduceObserver,__super__);function ReduceObserver(o,parent){this._o=o;this._p=parent;this._fn=parent.accumulator;this._hs=parent.hasSeed;this._s=parent.seed;this._ha=false;this._a=null;this._hv=false;this._i=0;__super__.call(this)}ReduceObserver.prototype.next=function(x){!this._hv&&(this._hv=true);if(this._ha){this._a=tryCatch(this._fn)(this._a,x,this._i,this._p)}else{this._a=this._hs?tryCatch(this._fn)(this._s,x,this._i,this._p):x;this._ha=true}if(this._a===errorObj){return this._o.onError(this._a.e)}this._i++};ReduceObserver.prototype.error=function(e){this._o.onError(e)};ReduceObserver.prototype.completed=function(){this._hv&&this._o.onNext(this._a);!this._hv&&this._hs&&this._o.onNext(this._s);!this._hv&&!this._hs&&this._o.onError(new EmptyError);this._o.onCompleted()};return ReduceObserver}(AbstractObserver);observableProto.reduce=function(){var hasSeed=false,seed,accumulator=arguments[0];if(arguments.length===2){hasSeed=true;seed=arguments[1]}return new ReduceObservable(this,accumulator,hasSeed,seed)};var SomeObservable=function(__super__){inherits(SomeObservable,__super__);function SomeObservable(source,fn){this.source=source;this._fn=fn;__super__.call(this)}SomeObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new SomeObserver(o,this._fn,this.source))};return SomeObservable}(ObservableBase);var SomeObserver=function(__super__){inherits(SomeObserver,__super__);function SomeObserver(o,fn,s){this._o=o;this._fn=fn;this._s=s;this._i=0;__super__.call(this)}SomeObserver.prototype.next=function(x){var result=tryCatch(this._fn)(x,this._i++,this._s);if(result===errorObj){return this._o.onError(result.e)}if(Boolean(result)){this._o.onNext(true);this._o.onCompleted()}};SomeObserver.prototype.error=function(e){this._o.onError(e)};SomeObserver.prototype.completed=function(){this._o.onNext(false);this._o.onCompleted()};return SomeObserver}(AbstractObserver);observableProto.some=function(predicate,thisArg){var fn=bindCallback(predicate,thisArg,3);return new SomeObservable(this,fn)};var IsEmptyObservable=function(__super__){inherits(IsEmptyObservable,__super__);function IsEmptyObservable(source){this.source=source;__super__.call(this)}IsEmptyObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new IsEmptyObserver(o))};return IsEmptyObservable}(ObservableBase);var IsEmptyObserver=function(__super__){inherits(IsEmptyObserver,__super__);function IsEmptyObserver(o){this._o=o;__super__.call(this)}IsEmptyObserver.prototype.next=function(){this._o.onNext(false);this._o.onCompleted()};IsEmptyObserver.prototype.error=function(e){this._o.onError(e)};IsEmptyObserver.prototype.completed=function(){this._o.onNext(true);this._o.onCompleted()};return IsEmptyObserver}(AbstractObserver);observableProto.isEmpty=function(){return new IsEmptyObservable(this)};var EveryObservable=function(__super__){inherits(EveryObservable,__super__);function EveryObservable(source,fn){this.source=source;this._fn=fn;__super__.call(this)}EveryObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new EveryObserver(o,this._fn,this.source))};return EveryObservable}(ObservableBase);var EveryObserver=function(__super__){inherits(EveryObserver,__super__);function EveryObserver(o,fn,s){this._o=o;this._fn=fn;this._s=s;this._i=0;__super__.call(this)}EveryObserver.prototype.next=function(x){var result=tryCatch(this._fn)(x,this._i++,this._s);if(result===errorObj){return this._o.onError(result.e)}if(!Boolean(result)){this._o.onNext(false);this._o.onCompleted()}};EveryObserver.prototype.error=function(e){this._o.onError(e)};EveryObserver.prototype.completed=function(){
+this._o.onNext(true);this._o.onCompleted()};return EveryObserver}(AbstractObserver);observableProto.every=function(predicate,thisArg){var fn=bindCallback(predicate,thisArg,3);return new EveryObservable(this,fn)};var IncludesObservable=function(__super__){inherits(IncludesObservable,__super__);function IncludesObservable(source,elem,idx){var n=+idx||0;Math.abs(n)===Infinity&&(n=0);this.source=source;this._elem=elem;this._n=n;__super__.call(this)}IncludesObservable.prototype.subscribeCore=function(o){if(this._n<0){o.onNext(false);o.onCompleted();return disposableEmpty}return this.source.subscribe(new IncludesObserver(o,this._elem,this._n))};return IncludesObservable}(ObservableBase);var IncludesObserver=function(__super__){inherits(IncludesObserver,__super__);function IncludesObserver(o,elem,n){this._o=o;this._elem=elem;this._n=n;this._i=0;__super__.call(this)}function comparer(a,b){return a===0&&b===0||(a===b||isNaN(a)&&isNaN(b))}IncludesObserver.prototype.next=function(x){if(this._i++>=this._n&&comparer(x,this._elem)){this._o.onNext(true);this._o.onCompleted()}};IncludesObserver.prototype.error=function(e){this._o.onError(e)};IncludesObserver.prototype.completed=function(){this._o.onNext(false);this._o.onCompleted()};return IncludesObserver}(AbstractObserver);observableProto.includes=function(searchElement,fromIndex){return new IncludesObservable(this,searchElement,fromIndex)};var CountObservable=function(__super__){inherits(CountObservable,__super__);function CountObservable(source,fn){this.source=source;this._fn=fn;__super__.call(this)}CountObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new CountObserver(o,this._fn,this.source))};return CountObservable}(ObservableBase);var CountObserver=function(__super__){inherits(CountObserver,__super__);function CountObserver(o,fn,s){this._o=o;this._fn=fn;this._s=s;this._i=0;this._c=0;__super__.call(this)}CountObserver.prototype.next=function(x){if(this._fn){var result=tryCatch(this._fn)(x,this._i++,this._s);if(result===errorObj){return this._o.onError(result.e)}Boolean(result)&&this._c++}else{this._c++}};CountObserver.prototype.error=function(e){this._o.onError(e)};CountObserver.prototype.completed=function(){this._o.onNext(this._c);this._o.onCompleted()};return CountObserver}(AbstractObserver);observableProto.count=function(predicate,thisArg){var fn=bindCallback(predicate,thisArg,3);return new CountObservable(this,fn)};var IndexOfObservable=function(__super__){inherits(IndexOfObservable,__super__);function IndexOfObservable(source,e,n){this.source=source;this._e=e;this._n=n;__super__.call(this)}IndexOfObservable.prototype.subscribeCore=function(o){if(this._n<0){o.onNext(-1);o.onCompleted();return disposableEmpty}return this.source.subscribe(new IndexOfObserver(o,this._e,this._n))};return IndexOfObservable}(ObservableBase);var IndexOfObserver=function(__super__){inherits(IndexOfObserver,__super__);function IndexOfObserver(o,e,n){this._o=o;this._e=e;this._n=n;this._i=0;__super__.call(this)}IndexOfObserver.prototype.next=function(x){if(this._i>=this._n&&x===this._e){this._o.onNext(this._i);this._o.onCompleted()}this._i++};IndexOfObserver.prototype.error=function(e){this._o.onError(e)};IndexOfObserver.prototype.completed=function(){this._o.onNext(-1);this._o.onCompleted()};return IndexOfObserver}(AbstractObserver);observableProto.indexOf=function(searchElement,fromIndex){var n=+fromIndex||0;Math.abs(n)===Infinity&&(n=0);return new IndexOfObservable(this,searchElement,n)};var SumObservable=function(__super__){inherits(SumObservable,__super__);function SumObservable(source,fn){this.source=source;this._fn=fn;__super__.call(this)}SumObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new SumObserver(o,this._fn,this.source))};return SumObservable}(ObservableBase);var SumObserver=function(__super__){inherits(SumObserver,__super__);function SumObserver(o,fn,s){this._o=o;this._fn=fn;this._s=s;this._i=0;this._c=0;__super__.call(this)}SumObserver.prototype.next=function(x){if(this._fn){var result=tryCatch(this._fn)(x,this._i++,this._s);if(result===errorObj){return this._o.onError(result.e)}this._c+=result}else{this._c+=x}};SumObserver.prototype.error=function(e){this._o.onError(e)};SumObserver.prototype.completed=function(){this._o.onNext(this._c);this._o.onCompleted()};return SumObserver}(AbstractObserver);observableProto.sum=function(keySelector,thisArg){var fn=bindCallback(keySelector,thisArg,3);return new SumObservable(this,fn)};observableProto.minBy=function(keySelector,comparer){comparer||(comparer=defaultSubComparer);return new ExtremaByObservable(this,keySelector,function(x,y){return comparer(x,y)*-1})};observableProto.min=function(comparer){return this.minBy(identity,comparer).map(function(x){return firstOnly(x)})};observableProto.maxBy=function(keySelector,comparer){comparer||(comparer=defaultSubComparer);return new ExtremaByObservable(this,keySelector,comparer)};observableProto.max=function(comparer){return this.maxBy(identity,comparer).map(function(x){return firstOnly(x)})};var AverageObservable=function(__super__){inherits(AverageObservable,__super__);function AverageObservable(source,fn){this.source=source;this._fn=fn;__super__.call(this)}AverageObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new AverageObserver(o,this._fn,this.source))};return AverageObservable}(ObservableBase);var AverageObserver=function(__super__){inherits(AverageObserver,__super__);function AverageObserver(o,fn,s){this._o=o;this._fn=fn;this._s=s;this._c=0;this._t=0;__super__.call(this)}AverageObserver.prototype.next=function(x){if(this._fn){var r=tryCatch(this._fn)(x,this._c++,this._s);if(r===errorObj){return this._o.onError(r.e)}this._t+=r}else{this._c++;this._t+=x}};AverageObserver.prototype.error=function(e){this._o.onError(e)};AverageObserver.prototype.completed=function(){if(this._c===0){return this._o.onError(new EmptyError)}this._o.onNext(this._t/this._c);this._o.onCompleted()};return AverageObserver}(AbstractObserver);observableProto.average=function(keySelector,thisArg){var source=this,fn;if(isFunction(keySelector)){fn=bindCallback(keySelector,thisArg,3)}return new AverageObservable(source,fn)};observableProto.sequenceEqual=function(second,comparer){var first=this;comparer||(comparer=defaultComparer);return new AnonymousObservable(function(o){var donel=false,doner=false,ql=[],qr=[];var subscription1=first.subscribe(function(x){if(qr.length>0){var v=qr.shift();var equal=tryCatch(comparer)(v,x);if(equal===errorObj){return o.onError(equal.e)}if(!equal){o.onNext(false);o.onCompleted()}}else if(doner){o.onNext(false);o.onCompleted()}else{ql.push(x)}},function(e){o.onError(e)},function(){donel=true;if(ql.length===0){if(qr.length>0){o.onNext(false);o.onCompleted()}else if(doner){o.onNext(true);o.onCompleted()}}});(isArrayLike(second)||isIterable(second))&&(second=observableFrom(second));isPromise(second)&&(second=observableFromPromise(second));var subscription2=second.subscribe(function(x){if(ql.length>0){var v=ql.shift();var equal=tryCatch(comparer)(v,x);if(equal===errorObj){return o.onError(equal.e)}if(!equal){o.onNext(false);o.onCompleted()}}else if(donel){o.onNext(false);o.onCompleted()}else{qr.push(x)}},function(e){o.onError(e)},function(){doner=true;if(qr.length===0){if(ql.length>0){o.onNext(false);o.onCompleted()}else if(donel){o.onNext(true);o.onCompleted()}}});return new BinaryDisposable(subscription1,subscription2)},first)};var ElementAtObservable=function(__super__){inherits(ElementAtObservable,__super__);function ElementAtObservable(source,i,d){this.source=source;this._i=i;this._d=d;__super__.call(this)}ElementAtObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new ElementAtObserver(o,this._i,this._d))};return ElementAtObservable}(ObservableBase);var ElementAtObserver=function(__super__){inherits(ElementAtObserver,__super__);function ElementAtObserver(o,i,d){this._o=o;this._i=i;this._d=d;__super__.call(this)}ElementAtObserver.prototype.next=function(x){if(this._i--===0){this._o.onNext(x);this._o.onCompleted()}};ElementAtObserver.prototype.error=function(e){this._o.onError(e)};ElementAtObserver.prototype.completed=function(){if(this._d===undefined){this._o.onError(new ArgumentOutOfRangeError)}else{this._o.onNext(this._d);this._o.onCompleted()}};return ElementAtObserver}(AbstractObserver);observableProto.elementAt=function(index,defaultValue){if(index<0){throw new ArgumentOutOfRangeError}return new ElementAtObservable(this,index,defaultValue)};var SingleObserver=function(__super__){inherits(SingleObserver,__super__);function SingleObserver(o,obj,s){this._o=o;this._obj=obj;this._s=s;this._i=0;this._hv=false;this._v=null;__super__.call(this)}SingleObserver.prototype.next=function(x){var shouldYield=false;if(this._obj.predicate){var res=tryCatch(this._obj.predicate)(x,this._i++,this._s);if(res===errorObj){return this._o.onError(res.e)}Boolean(res)&&(shouldYield=true)}else if(!this._obj.predicate){shouldYield=true}if(shouldYield){if(this._hv){return this._o.onError(new Error("Sequence contains more than one matching element"))}this._hv=true;this._v=x}};SingleObserver.prototype.error=function(e){this._o.onError(e)};SingleObserver.prototype.completed=function(){if(this._hv){this._o.onNext(this._v);this._o.onCompleted()}else if(this._obj.defaultValue===undefined){this._o.onError(new EmptyError)}else{this._o.onNext(this._obj.defaultValue);this._o.onCompleted()}};return SingleObserver}(AbstractObserver);observableProto.single=function(predicate,thisArg){var obj={},source=this;if(typeof arguments[0]==="object"){obj=arguments[0]}else{obj={predicate:arguments[0],thisArg:arguments[1],defaultValue:arguments[2]}}if(isFunction(obj.predicate)){var fn=obj.predicate;obj.predicate=bindCallback(fn,obj.thisArg,3)}return new AnonymousObservable(function(o){return source.subscribe(new SingleObserver(o,obj,source))},source)};var FirstObservable=function(__super__){inherits(FirstObservable,__super__);function FirstObservable(source,obj){this.source=source;this._obj=obj;__super__.call(this)}FirstObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new FirstObserver(o,this._obj,this.source))};return FirstObservable}(ObservableBase);var FirstObserver=function(__super__){inherits(FirstObserver,__super__);function FirstObserver(o,obj,s){this._o=o;this._obj=obj;this._s=s;this._i=0;__super__.call(this)}FirstObserver.prototype.next=function(x){if(this._obj.predicate){var res=tryCatch(this._obj.predicate)(x,this._i++,this._s);if(res===errorObj){return this._o.onError(res.e)}if(Boolean(res)){this._o.onNext(x);this._o.onCompleted()}}else if(!this._obj.predicate){this._o.onNext(x);this._o.onCompleted()}};FirstObserver.prototype.error=function(e){this._o.onError(e)};FirstObserver.prototype.completed=function(){if(this._obj.defaultValue===undefined){this._o.onError(new EmptyError)}else{this._o.onNext(this._obj.defaultValue);this._o.onCompleted()}};return FirstObserver}(AbstractObserver);observableProto.first=function(){var obj={},source=this;if(typeof arguments[0]==="object"){obj=arguments[0]}else{obj={predicate:arguments[0],thisArg:arguments[1],defaultValue:arguments[2]}}if(isFunction(obj.predicate)){var fn=obj.predicate;obj.predicate=bindCallback(fn,obj.thisArg,3)}return new FirstObservable(this,obj)};var LastObservable=function(__super__){inherits(LastObservable,__super__);function LastObservable(source,obj){this.source=source;this._obj=obj;__super__.call(this)}LastObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new LastObserver(o,this._obj,this.source))};return LastObservable}(ObservableBase);var LastObserver=function(__super__){inherits(LastObserver,__super__);function LastObserver(o,obj,s){this._o=o;this._obj=obj;this._s=s;this._i=0;this._hv=false;this._v=null;__super__.call(this)}LastObserver.prototype.next=function(x){var shouldYield=false;if(this._obj.predicate){var res=tryCatch(this._obj.predicate)(x,this._i++,this._s);if(res===errorObj){return this._o.onError(res.e)}Boolean(res)&&(shouldYield=true)}else if(!this._obj.predicate){shouldYield=true}if(shouldYield){this._hv=true;this._v=x}};LastObserver.prototype.error=function(e){this._o.onError(e)};LastObserver.prototype.completed=function(){if(this._hv){this._o.onNext(this._v);this._o.onCompleted()}else if(this._obj.defaultValue===undefined){this._o.onError(new EmptyError)}else{this._o.onNext(this._obj.defaultValue);this._o.onCompleted()}};return LastObserver}(AbstractObserver);observableProto.last=function(){var obj={},source=this;if(typeof arguments[0]==="object"){obj=arguments[0]}else{obj={predicate:arguments[0],thisArg:arguments[1],defaultValue:arguments[2]}}if(isFunction(obj.predicate)){var fn=obj.predicate;obj.predicate=bindCallback(fn,obj.thisArg,3)}return new LastObservable(this,obj)};var FindValueObserver=function(__super__){inherits(FindValueObserver,__super__);function FindValueObserver(observer,source,callback,yieldIndex){this._o=observer;this._s=source;this._cb=callback;this._y=yieldIndex;this._i=0;__super__.call(this)}FindValueObserver.prototype.next=function(x){var shouldRun=tryCatch(this._cb)(x,this._i,this._s);if(shouldRun===errorObj){return this._o.onError(shouldRun.e)}if(shouldRun){this._o.onNext(this._y?this._i:x);this._o.onCompleted()}else{this._i++}};FindValueObserver.prototype.error=function(e){this._o.onError(e)};FindValueObserver.prototype.completed=function(){this._y&&this._o.onNext(-1);this._o.onCompleted()};return FindValueObserver}(AbstractObserver);function findValue(source,predicate,thisArg,yieldIndex){var callback=bindCallback(predicate,thisArg,3);return new AnonymousObservable(function(o){return source.subscribe(new FindValueObserver(o,source,callback,yieldIndex))},source)}observableProto.find=function(predicate,thisArg){return findValue(this,predicate,thisArg,false)};observableProto.findIndex=function(predicate,thisArg){return findValue(this,predicate,thisArg,true)};var ToSetObservable=function(__super__){inherits(ToSetObservable,__super__);function ToSetObservable(source){this.source=source;__super__.call(this)}ToSetObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new ToSetObserver(o))};return ToSetObservable}(ObservableBase);var ToSetObserver=function(__super__){inherits(ToSetObserver,__super__);function ToSetObserver(o){this._o=o;this._s=new root.Set;__super__.call(this)}ToSetObserver.prototype.next=function(x){this._s.add(x)};ToSetObserver.prototype.error=function(e){this._o.onError(e)};ToSetObserver.prototype.completed=function(){this._o.onNext(this._s);this._o.onCompleted()};return ToSetObserver}(AbstractObserver);observableProto.toSet=function(){if(typeof root.Set==="undefined"){throw new TypeError}return new ToSetObservable(this)};var ToMapObservable=function(__super__){inherits(ToMapObservable,__super__);function ToMapObservable(source,k,e){this.source=source;this._k=k;this._e=e;__super__.call(this)}ToMapObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new ToMapObserver(o,this._k,this._e))};return ToMapObservable}(ObservableBase);var ToMapObserver=function(__super__){inherits(ToMapObserver,__super__);function ToMapObserver(o,k,e){this._o=o;this._k=k;this._e=e;this._m=new root.Map;__super__.call(this)}ToMapObserver.prototype.next=function(x){var key=tryCatch(this._k)(x);if(key===errorObj){return this._o.onError(key.e)}var elem=x;if(this._e){elem=tryCatch(this._e)(x);if(elem===errorObj){return this._o.onError(elem.e)}}this._m.set(key,elem)};ToMapObserver.prototype.error=function(e){this._o.onError(e)};ToMapObserver.prototype.completed=function(){this._o.onNext(this._m);this._o.onCompleted()};return ToMapObserver}(AbstractObserver);observableProto.toMap=function(keySelector,elementSelector){if(typeof root.Map==="undefined"){throw new TypeError}return new ToMapObservable(this,keySelector,elementSelector)};var SliceObservable=function(__super__){inherits(SliceObservable,__super__);function SliceObservable(source,b,e){this.source=source;this._b=b;this._e=e;__super__.call(this)}SliceObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new SliceObserver(o,this._b,this._e))};return SliceObservable}(ObservableBase);var SliceObserver=function(__super__){inherits(SliceObserver,__super__);function SliceObserver(o,b,e){this._o=o;this._b=b;this._e=e;this._i=0;__super__.call(this)}SliceObserver.prototype.next=function(x){if(this._i>=this._b){if(this._e===this._i){this._o.onCompleted()}else{this._o.onNext(x)}}this._i++};SliceObserver.prototype.error=function(e){this._o.onError(e)};SliceObserver.prototype.completed=function(){this._o.onCompleted()};return SliceObserver}(AbstractObserver);observableProto.slice=function(begin,end){var start=begin||0;if(start<0){throw new Rx.ArgumentOutOfRangeError}if(typeof end==="number"&&end=this._n&&x===this._e){this._hv=true;this._v=this._i}this._i++};LastIndexOfObserver.prototype.error=function(e){this._o.onError(e)};LastIndexOfObserver.prototype.completed=function(){if(this._hv){this._o.onNext(this._v)}else{this._o.onNext(-1)}this._o.onCompleted()};return LastIndexOfObserver}(AbstractObserver);observableProto.lastIndexOf=function(searchElement,fromIndex){var n=+fromIndex||0;Math.abs(n)===Infinity&&(n=0);return new LastIndexOfObservable(this,searchElement,n)};Observable.wrap=function(fn){function createObservable(){return Observable.spawn.call(this,fn.apply(this,arguments))}createObservable.__generatorFunction__=fn;return createObservable};var spawn=Observable.spawn=function(){var gen=arguments[0],self=this,args=[];for(var i=1,len=arguments.length;i2){var args=[];for(var i=1,len=arguments.length;i0){o.onNext(q.shift())}}var subscription=combineLatestSource(this.source,this.pauser.startWith(false).distinctUntilChanged(),function(data,shouldFire){return{data:data,shouldFire:shouldFire}}).subscribe(function(results){if(previousShouldFire!==undefined&&results.shouldFire!==previousShouldFire){previousShouldFire=results.shouldFire;if(results.shouldFire){drainQueue()}}else{previousShouldFire=results.shouldFire;if(results.shouldFire){o.onNext(results.data)}else{q.push(results.data)}}},function(err){drainQueue();o.onError(err)},function(){drainQueue();o.onCompleted()});return subscription};PausableBufferedObservable.prototype.pause=function(){this.controller.onNext(false)};PausableBufferedObservable.prototype.resume=function(){this.controller.onNext(true)};return PausableBufferedObservable}(Observable);observableProto.pausableBuffered=function(pauser){return new PausableBufferedObservable(this,pauser)};var ControlledObservable=function(__super__){inherits(ControlledObservable,__super__);function ControlledObservable(source,enableQueue,scheduler){__super__.call(this);this.subject=new ControlledSubject(enableQueue,scheduler);this.source=source.multicast(this.subject).refCount()}ControlledObservable.prototype._subscribe=function(o){return this.source.subscribe(o)};ControlledObservable.prototype.request=function(numberOfItems){return this.subject.request(numberOfItems==null?-1:numberOfItems)};return ControlledObservable}(Observable);var ControlledSubject=function(__super__){inherits(ControlledSubject,__super__);function ControlledSubject(enableQueue,scheduler){enableQueue==null&&(enableQueue=true);__super__.call(this);this.subject=new Subject;this.enableQueue=enableQueue;this.queue=enableQueue?[]:null;this.requestedCount=0;this.requestedDisposable=null;this.error=null;this.hasFailed=false;this.hasCompleted=false;this.scheduler=scheduler||currentThreadScheduler}addProperties(ControlledSubject.prototype,Observer,{_subscribe:function(o){return this.subject.subscribe(o)},onCompleted:function(){this.hasCompleted=true;if(!this.enableQueue||this.queue.length===0){this.subject.onCompleted();this.disposeCurrentRequest()}else{this.queue.push(Notification.createOnCompleted())}},onError:function(error){this.hasFailed=true;this.error=error;if(!this.enableQueue||this.queue.length===0){this.subject.onError(error);this.disposeCurrentRequest()}else{this.queue.push(Notification.createOnError(error))}},onNext:function(value){if(this.requestedCount<=0){this.enableQueue&&this.queue.push(Notification.createOnNext(value))}else{this.requestedCount--===0&&this.disposeCurrentRequest();this.subject.onNext(value)}},_processRequest:function(numberOfItems){if(this.enableQueue){while(this.queue.length>0&&(numberOfItems>0||this.queue[0].kind!=="N")){var first=this.queue.shift();first.accept(this.subject);if(first.kind==="N"){numberOfItems--}else{this.disposeCurrentRequest();this.queue=[]}}}return numberOfItems},request:function(number){this.disposeCurrentRequest();var self=this;this.requestedDisposable=this.scheduler.schedule(number,function(s,i){var remaining=self._processRequest(i);var stopped=self.hasCompleted||self.hasFailed;if(!stopped&&remaining>0){self.requestedCount=remaining;return disposableCreate(function(){self.requestedCount=0})}});return this.requestedDisposable},disposeCurrentRequest:function(){if(this.requestedDisposable){this.requestedDisposable.dispose();this.requestedDisposable=null}}});return ControlledSubject}(Observable);observableProto.controlled=function(enableQueue,scheduler){
+if(enableQueue&&isScheduler(enableQueue)){scheduler=enableQueue;enableQueue=true}if(enableQueue==null){enableQueue=true}return new ControlledObservable(this,enableQueue,scheduler)};var StopAndWaitObservable=function(__super__){inherits(StopAndWaitObservable,__super__);function StopAndWaitObservable(source){__super__.call(this);this.source=source}function scheduleMethod(s,self){self.source.request(1)}StopAndWaitObservable.prototype._subscribe=function(o){this.subscription=this.source.subscribe(new StopAndWaitObserver(o,this,this.subscription));return new BinaryDisposable(this.subscription,defaultScheduler.schedule(this,scheduleMethod))};var StopAndWaitObserver=function(__sub__){inherits(StopAndWaitObserver,__sub__);function StopAndWaitObserver(observer,observable,cancel){__sub__.call(this);this.observer=observer;this.observable=observable;this.cancel=cancel;this.scheduleDisposable=null}StopAndWaitObserver.prototype.completed=function(){this.observer.onCompleted();this.dispose()};StopAndWaitObserver.prototype.error=function(error){this.observer.onError(error);this.dispose()};function innerScheduleMethod(s,self){self.observable.source.request(1)}StopAndWaitObserver.prototype.next=function(value){this.observer.onNext(value);this.scheduleDisposable=defaultScheduler.schedule(this,innerScheduleMethod)};StopAndWaitObservable.dispose=function(){this.observer=null;if(this.cancel){this.cancel.dispose();this.cancel=null}if(this.scheduleDisposable){this.scheduleDisposable.dispose();this.scheduleDisposable=null}__sub__.prototype.dispose.call(this)};return StopAndWaitObserver}(AbstractObserver);return StopAndWaitObservable}(Observable);ControlledObservable.prototype.stopAndWait=function(){return new StopAndWaitObservable(this)};var WindowedObservable=function(__super__){inherits(WindowedObservable,__super__);function WindowedObservable(source,windowSize){__super__.call(this);this.source=source;this.windowSize=windowSize}function scheduleMethod(s,self){self.source.request(self.windowSize)}WindowedObservable.prototype._subscribe=function(o){this.subscription=this.source.subscribe(new WindowedObserver(o,this,this.subscription));return new BinaryDisposable(this.subscription,defaultScheduler.schedule(this,scheduleMethod))};var WindowedObserver=function(__sub__){inherits(WindowedObserver,__sub__);function WindowedObserver(observer,observable,cancel){this.observer=observer;this.observable=observable;this.cancel=cancel;this.received=0;this.scheduleDisposable=null;__sub__.call(this)}WindowedObserver.prototype.completed=function(){this.observer.onCompleted();this.dispose()};WindowedObserver.prototype.error=function(error){this.observer.onError(error);this.dispose()};function innerScheduleMethod(s,self){self.observable.source.request(self.observable.windowSize)}WindowedObserver.prototype.next=function(value){this.observer.onNext(value);this.received=++this.received%this.observable.windowSize;this.received===0&&(this.scheduleDisposable=defaultScheduler.schedule(this,innerScheduleMethod))};WindowedObserver.prototype.dispose=function(){this.observer=null;if(this.cancel){this.cancel.dispose();this.cancel=null}if(this.scheduleDisposable){this.scheduleDisposable.dispose();this.scheduleDisposable=null}__sub__.prototype.dispose.call(this)};return WindowedObserver}(AbstractObserver);return WindowedObservable}(Observable);ControlledObservable.prototype.windowed=function(windowSize){return new WindowedObservable(this,windowSize)};observableProto.pipe=function(dest){var source=this.pausableBuffered();function onDrain(){source.resume()}dest.addListener("drain",onDrain);source.subscribe(function(x){!dest.write(String(x))&&source.pause()},function(err){dest.emit("error",err)},function(){!dest._isStdio&&dest.end();dest.removeListener("drain",onDrain)});source.resume();return dest};var MulticastObservable=function(__super__){inherits(MulticastObservable,__super__);function MulticastObservable(source,fn1,fn2){this.source=source;this._fn1=fn1;this._fn2=fn2;__super__.call(this)}MulticastObservable.prototype.subscribeCore=function(o){var connectable=this.source.multicast(this._fn1());return new BinaryDisposable(this._fn2(connectable).subscribe(o),connectable.connect())};return MulticastObservable}(ObservableBase);observableProto.multicast=function(subjectOrSubjectSelector,selector){return isFunction(subjectOrSubjectSelector)?new MulticastObservable(this,subjectOrSubjectSelector,selector):new ConnectableObservable(this,subjectOrSubjectSelector)};observableProto.publish=function(selector){return selector&&isFunction(selector)?this.multicast(function(){return new Subject},selector):this.multicast(new Subject)};observableProto.share=function(){return this.publish().refCount()};observableProto.publishLast=function(selector){return selector&&isFunction(selector)?this.multicast(function(){return new AsyncSubject},selector):this.multicast(new AsyncSubject)};observableProto.publishValue=function(initialValueOrSelector,initialValue){return arguments.length===2?this.multicast(function(){return new BehaviorSubject(initialValue)},initialValueOrSelector):this.multicast(new BehaviorSubject(initialValueOrSelector))};observableProto.shareValue=function(initialValue){return this.publishValue(initialValue).refCount()};observableProto.replay=function(selector,bufferSize,windowSize,scheduler){return selector&&isFunction(selector)?this.multicast(function(){return new ReplaySubject(bufferSize,windowSize,scheduler)},selector):this.multicast(new ReplaySubject(bufferSize,windowSize,scheduler))};observableProto.shareReplay=function(bufferSize,windowSize,scheduler){return this.replay(null,bufferSize,windowSize,scheduler).refCount()};var InnerSubscription=function(s,o){this._s=s;this._o=o};InnerSubscription.prototype.dispose=function(){if(!this._s.isDisposed&&this._o!==null){var idx=this._s.observers.indexOf(this._o);this._s.observers.splice(idx,1);this._o=null}};var RefCountObservable=function(__super__){inherits(RefCountObservable,__super__);function RefCountObservable(source){this.source=source;this._count=0;this._connectableSubscription=null;__super__.call(this)}RefCountObservable.prototype.subscribeCore=function(o){var subscription=this.source.subscribe(o);++this._count===1&&(this._connectableSubscription=this.source.connect());return new RefCountDisposable(this,subscription)};function RefCountDisposable(p,s){this._p=p;this._s=s;this.isDisposed=false}RefCountDisposable.prototype.dispose=function(){if(!this.isDisposed){this.isDisposed=true;this._s.dispose();--this._p._count===0&&this._p._connectableSubscription.dispose()}};return RefCountObservable}(ObservableBase);var ConnectableObservable=Rx.ConnectableObservable=function(__super__){inherits(ConnectableObservable,__super__);function ConnectableObservable(source,subject){this.source=source;this._connection=null;this._source=source.asObservable();this._subject=subject;__super__.call(this)}function ConnectDisposable(parent,subscription){this._p=parent;this._s=subscription}ConnectDisposable.prototype.dispose=function(){if(this._s){this._s.dispose();this._s=null;this._p._connection=null}};ConnectableObservable.prototype.connect=function(){if(!this._connection){var subscription=this._source.subscribe(this._subject);this._connection=new ConnectDisposable(this,subscription)}return this._connection};ConnectableObservable.prototype._subscribe=function(o){return this._subject.subscribe(o)};ConnectableObservable.prototype.refCount=function(){return new RefCountObservable(this)};return ConnectableObservable}(Observable);observableProto.singleInstance=function(){var source=this,hasObservable=false,observable;function getObservable(){if(!hasObservable){hasObservable=true;observable=source["finally"](function(){hasObservable=false}).publish().refCount()}return observable}return new AnonymousObservable(function(o){return getObservable().subscribe(o)})};observableProto.join=function(right,leftDurationSelector,rightDurationSelector,resultSelector){var left=this;return new AnonymousObservable(function(o){var group=new CompositeDisposable;var leftDone=false,rightDone=false;var leftId=0,rightId=0;var leftMap=new Map,rightMap=new Map;var handleError=function(e){o.onError(e)};group.add(left.subscribe(function(value){var id=leftId++,md=new SingleAssignmentDisposable;leftMap.set(id,value);group.add(md);var duration=tryCatch(leftDurationSelector)(value);if(duration===errorObj){return o.onError(duration.e)}md.setDisposable(duration.take(1).subscribe(noop,handleError,function(){leftMap["delete"](id)&&leftMap.size===0&&leftDone&&o.onCompleted();group.remove(md)}));rightMap.forEach(function(v){var result=tryCatch(resultSelector)(value,v);if(result===errorObj){return o.onError(result.e)}o.onNext(result)})},handleError,function(){leftDone=true;(rightDone||leftMap.size===0)&&o.onCompleted()}));group.add(right.subscribe(function(value){var id=rightId++,md=new SingleAssignmentDisposable;rightMap.set(id,value);group.add(md);var duration=tryCatch(rightDurationSelector)(value);if(duration===errorObj){return o.onError(duration.e)}md.setDisposable(duration.take(1).subscribe(noop,handleError,function(){rightMap["delete"](id)&&rightMap.size===0&&rightDone&&o.onCompleted();group.remove(md)}));leftMap.forEach(function(v){var result=tryCatch(resultSelector)(v,value);if(result===errorObj){return o.onError(result.e)}o.onNext(result)})},handleError,function(){rightDone=true;(leftDone||rightMap.size===0)&&o.onCompleted()}));return group},left)};observableProto.groupJoin=function(right,leftDurationSelector,rightDurationSelector,resultSelector){var left=this;return new AnonymousObservable(function(o){var group=new CompositeDisposable;var r=new RefCountDisposable(group);var leftMap=new Map,rightMap=new Map;var leftId=0,rightId=0;var handleError=function(e){return function(v){v.onError(e)}};function handleError(e){}group.add(left.subscribe(function(value){var s=new Subject;var id=leftId++;leftMap.set(id,s);var result=tryCatch(resultSelector)(value,addRef(s,r));if(result===errorObj){leftMap.forEach(handleError(result.e));return o.onError(result.e)}o.onNext(result);rightMap.forEach(function(v){s.onNext(v)});var md=new SingleAssignmentDisposable;group.add(md);var duration=tryCatch(leftDurationSelector)(value);if(duration===errorObj){leftMap.forEach(handleError(duration.e));return o.onError(duration.e)}md.setDisposable(duration.take(1).subscribe(noop,function(e){leftMap.forEach(handleError(e));o.onError(e)},function(){leftMap["delete"](id)&&s.onCompleted();group.remove(md)}))},function(e){leftMap.forEach(handleError(e));o.onError(e)},function(){o.onCompleted()}));group.add(right.subscribe(function(value){var id=rightId++;rightMap.set(id,value);var md=new SingleAssignmentDisposable;group.add(md);var duration=tryCatch(rightDurationSelector)(value);if(duration===errorObj){leftMap.forEach(handleError(duration.e));return o.onError(duration.e)}md.setDisposable(duration.take(1).subscribe(noop,function(e){leftMap.forEach(handleError(e));o.onError(e)},function(){rightMap["delete"](id);group.remove(md)}));leftMap.forEach(function(v){v.onNext(value)})},function(e){leftMap.forEach(handleError(e));o.onError(e)}));return r},left)};function toArray(x){return x.toArray()}observableProto.buffer=function(){return this.window.apply(this,arguments).flatMap(toArray)};observableProto.window=function(windowOpeningsOrClosingSelector,windowClosingSelector){if(arguments.length===1&&typeof arguments[0]!=="function"){return observableWindowWithBoundaries.call(this,windowOpeningsOrClosingSelector)}return typeof windowOpeningsOrClosingSelector==="function"?observableWindowWithClosingSelector.call(this,windowOpeningsOrClosingSelector):observableWindowWithOpenings.call(this,windowOpeningsOrClosingSelector,windowClosingSelector)};function observableWindowWithOpenings(windowOpenings,windowClosingSelector){return windowOpenings.groupJoin(this,windowClosingSelector,observableEmpty,function(_,win){return win})}function observableWindowWithBoundaries(windowBoundaries){var source=this;return new AnonymousObservable(function(observer){var win=new Subject,d=new CompositeDisposable,r=new RefCountDisposable(d);observer.onNext(addRef(win,r));d.add(source.subscribe(function(x){win.onNext(x)},function(err){win.onError(err);observer.onError(err)},function(){win.onCompleted();observer.onCompleted()}));isPromise(windowBoundaries)&&(windowBoundaries=observableFromPromise(windowBoundaries));d.add(windowBoundaries.subscribe(function(w){win.onCompleted();win=new Subject;observer.onNext(addRef(win,r))},function(err){win.onError(err);observer.onError(err)},function(){win.onCompleted();observer.onCompleted()}));return r},source)}function observableWindowWithClosingSelector(windowClosingSelector){var source=this;return new AnonymousObservable(function(observer){var m=new SerialDisposable,d=new CompositeDisposable(m),r=new RefCountDisposable(d),win=new Subject;observer.onNext(addRef(win,r));d.add(source.subscribe(function(x){win.onNext(x)},function(err){win.onError(err);observer.onError(err)},function(){win.onCompleted();observer.onCompleted()}));function createWindowClose(){var windowClose;try{windowClose=windowClosingSelector()}catch(e){observer.onError(e);return}isPromise(windowClose)&&(windowClose=observableFromPromise(windowClose));var m1=new SingleAssignmentDisposable;m.setDisposable(m1);m1.setDisposable(windowClose.take(1).subscribe(noop,function(err){win.onError(err);observer.onError(err)},function(){win.onCompleted();win=new Subject;observer.onNext(addRef(win,r));createWindowClose()}))}createWindowClose();return r},source)}var PairwiseObservable=function(__super__){inherits(PairwiseObservable,__super__);function PairwiseObservable(source){this.source=source;__super__.call(this)}PairwiseObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new PairwiseObserver(o))};return PairwiseObservable}(ObservableBase);var PairwiseObserver=function(__super__){inherits(PairwiseObserver,__super__);function PairwiseObserver(o){this._o=o;this._p=null;this._hp=false}PairwiseObserver.prototype.next=function(x){if(this._hp){this._o.onNext([this._p,x])}else{this._hp=true}this._p=x};PairwiseObserver.prototype.error=function(err){this._o.onError(err)};PairwiseObserver.prototype.completed=function(){this._o.onCompleted()};return PairwiseObserver}(AbstractObserver);observableProto.pairwise=function(){return new PairwiseObservable(this)};observableProto.partition=function(predicate,thisArg){var fn=bindCallback(predicate,thisArg,3);return[this.filter(predicate,thisArg),this.filter(function(x,i,o){return!fn(x,i,o)})]};var WhileEnumerable=function(__super__){inherits(WhileEnumerable,__super__);function WhileEnumerable(c,s){this.c=c;this.s=s}WhileEnumerable.prototype[$iterator$]=function(){var self=this;return{next:function(){return self.c()?{done:false,value:self.s}:{done:true,value:void 0}}}};return WhileEnumerable}(Enumerable);function enumerableWhile(condition,source){return new WhileEnumerable(condition,source)}observableProto.letBind=observableProto["let"]=function(func){return func(this)};Observable["if"]=function(condition,thenSource,elseSourceOrScheduler){return observableDefer(function(){elseSourceOrScheduler||(elseSourceOrScheduler=observableEmpty());isPromise(thenSource)&&(thenSource=observableFromPromise(thenSource));isPromise(elseSourceOrScheduler)&&(elseSourceOrScheduler=observableFromPromise(elseSourceOrScheduler));typeof elseSourceOrScheduler.now==="function"&&(elseSourceOrScheduler=observableEmpty(elseSourceOrScheduler));return condition()?thenSource:elseSourceOrScheduler})};Observable["for"]=Observable.forIn=function(sources,resultSelector,thisArg){return enumerableOf(sources,resultSelector,thisArg).concat()};var observableWhileDo=Observable["while"]=Observable.whileDo=function(condition,source){isPromise(source)&&(source=observableFromPromise(source));return enumerableWhile(condition,source).concat()};observableProto.doWhile=function(condition){return observableConcat([this,observableWhileDo(condition,this)])};Observable["case"]=function(selector,sources,defaultSourceOrScheduler){return observableDefer(function(){isPromise(defaultSourceOrScheduler)&&(defaultSourceOrScheduler=observableFromPromise(defaultSourceOrScheduler));defaultSourceOrScheduler||(defaultSourceOrScheduler=observableEmpty());isScheduler(defaultSourceOrScheduler)&&(defaultSourceOrScheduler=observableEmpty(defaultSourceOrScheduler));var result=sources[selector()];isPromise(result)&&(result=observableFromPromise(result));return result||defaultSourceOrScheduler})};var ExpandObservable=function(__super__){inherits(ExpandObservable,__super__);function ExpandObservable(source,fn,scheduler){this.source=source;this._fn=fn;this._scheduler=scheduler;__super__.call(this)}function scheduleRecursive(args,recurse){var state=args[0],self=args[1];var work;if(state.q.length>0){work=state.q.shift()}else{state.isAcquired=false;return}var m1=new SingleAssignmentDisposable;state.d.add(m1);m1.setDisposable(work.subscribe(new ExpandObserver(state,self,m1)));recurse([state,self])}ExpandObservable.prototype._ensureActive=function(state){var isOwner=false;if(state.q.length>0){isOwner=!state.isAcquired;state.isAcquired=true}isOwner&&state.m.setDisposable(this._scheduler.scheduleRecursive([state,this],scheduleRecursive))};ExpandObservable.prototype.subscribeCore=function(o){var m=new SerialDisposable,d=new CompositeDisposable(m),state={q:[],m:m,d:d,activeCount:0,isAcquired:false,o:o};state.q.push(this.source);state.activeCount++;this._ensureActive(state);return d};return ExpandObservable}(ObservableBase);var ExpandObserver=function(__super__){inherits(ExpandObserver,__super__);function ExpandObserver(state,parent,m1){this._s=state;this._p=parent;this._m1=m1;__super__.call(this)}ExpandObserver.prototype.next=function(x){this._s.o.onNext(x);var result=tryCatch(this._p._fn)(x);if(result===errorObj){return this._s.o.onError(result.e)}this._s.q.push(result);this._s.activeCount++;this._p._ensureActive(this._s)};ExpandObserver.prototype.error=function(e){this._s.o.onError(e)};ExpandObserver.prototype.completed=function(){this._s.d.remove(this._m1);this._s.activeCount--;this._s.activeCount===0&&this._s.o.onCompleted()};return ExpandObserver}(AbstractObserver);observableProto.expand=function(selector,scheduler){isScheduler(scheduler)||(scheduler=currentThreadScheduler);return new ExpandObservable(this,selector,scheduler)};function argumentsToArray(){var len=arguments.length,args=new Array(len);for(var i=0;i0){var now=scheduler.now();d=new Date(d.getTime()+p);d.getTime()<=now&&(d=new Date(now+p))}observer.onNext(count);self(count+1,new Date(d))})})}function observableTimerTimeSpanAndPeriod(dueTime,period,scheduler){return dueTime===period?new AnonymousObservable(function(observer){return scheduler.schedulePeriodic(0,period,function(count){observer.onNext(count);return count+1})}):observableDefer(function(){return observableTimerDateAndPeriod(new Date(scheduler.now()+dueTime),period,scheduler)})}var observableinterval=Observable.interval=function(period,scheduler){return observableTimerTimeSpanAndPeriod(period,period,isScheduler(scheduler)?scheduler:defaultScheduler)};var observableTimer=Observable.timer=function(dueTime,periodOrScheduler,scheduler){var period;isScheduler(scheduler)||(scheduler=defaultScheduler);if(periodOrScheduler!=null&&typeof periodOrScheduler==="number"){period=periodOrScheduler}else if(isScheduler(periodOrScheduler)){scheduler=periodOrScheduler}if((dueTime instanceof Date||typeof dueTime==="number")&&period===undefined){return _observableTimer(dueTime,scheduler)}if(dueTime instanceof Date&&period!==undefined){return observableTimerDateAndPeriod(dueTime.getTime(),periodOrScheduler,scheduler)}return observableTimerTimeSpanAndPeriod(dueTime,period,scheduler)};function observableDelayRelative(source,dueTime,scheduler){return new AnonymousObservable(function(o){var active=false,cancelable=new SerialDisposable,exception=null,q=[],running=false,subscription;subscription=source.materialize().timestamp(scheduler).subscribe(function(notification){var d,shouldRun;if(notification.value.kind==="E"){q=[];q.push(notification);exception=notification.value.error;shouldRun=!running}else{q.push({value:notification.value,timestamp:notification.timestamp+dueTime});shouldRun=!active;active=true}if(shouldRun){if(exception!==null){o.onError(exception)}else{d=new SingleAssignmentDisposable;cancelable.setDisposable(d);d.setDisposable(scheduler.scheduleRecursiveFuture(null,dueTime,function(_,self){var e,recurseDueTime,result,shouldRecurse;if(exception!==null){return}running=true;do{result=null;if(q.length>0&&q[0].timestamp-scheduler.now()<=0){result=q.shift().value}if(result!==null){result.accept(o)}}while(result!==null);shouldRecurse=false;recurseDueTime=0;if(q.length>0){shouldRecurse=true;recurseDueTime=Math.max(0,q[0].timestamp-scheduler.now())}else{active=false}e=exception;running=false;if(e!==null){o.onError(e)}else if(shouldRecurse){self(null,recurseDueTime)}}))}}});return new BinaryDisposable(subscription,cancelable)},source)}function observableDelayAbsolute(source,dueTime,scheduler){return observableDefer(function(){return observableDelayRelative(source,dueTime-scheduler.now(),scheduler)})}function delayWithSelector(source,subscriptionDelay,delayDurationSelector){var subDelay,selector;if(isFunction(subscriptionDelay)){selector=subscriptionDelay}else{subDelay=subscriptionDelay;selector=delayDurationSelector}return new AnonymousObservable(function(o){var delays=new CompositeDisposable,atEnd=false,subscription=new SerialDisposable;function start(){subscription.setDisposable(source.subscribe(function(x){var delay=tryCatch(selector)(x);if(delay===errorObj){return o.onError(delay.e)}var d=new SingleAssignmentDisposable;delays.add(d);d.setDisposable(delay.subscribe(function(){o.onNext(x);delays.remove(d);done()},function(e){o.onError(e)},function(){o.onNext(x);delays.remove(d);done()}))},function(e){o.onError(e)},function(){atEnd=true;subscription.dispose();done()}))}function done(){atEnd&&delays.length===0&&o.onCompleted()}if(!subDelay){start()}else{subscription.setDisposable(subDelay.subscribe(start,function(e){o.onError(e)},start))}return new BinaryDisposable(subscription,delays)},this)}observableProto.delay=function(){var firstArg=arguments[0];if(typeof firstArg==="number"||firstArg instanceof Date){var dueTime=firstArg,scheduler=arguments[1];isScheduler(scheduler)||(scheduler=defaultScheduler);return dueTime instanceof Date?observableDelayAbsolute(this,dueTime,scheduler):observableDelayRelative(this,dueTime,scheduler)}else if(Observable.isObservable(firstArg)||isFunction(firstArg)){
+return delayWithSelector(this,firstArg,arguments[1])}else{throw new Error("Invalid arguments")}};var DebounceObservable=function(__super__){inherits(DebounceObservable,__super__);function DebounceObservable(source,dt,s){isScheduler(s)||(s=defaultScheduler);this.source=source;this._dt=dt;this._s=s;__super__.call(this)}DebounceObservable.prototype.subscribeCore=function(o){var cancelable=new SerialDisposable;return new BinaryDisposable(this.source.subscribe(new DebounceObserver(o,this.source,this._dt,this._s,cancelable)),cancelable)};return DebounceObservable}(ObservableBase);var DebounceObserver=function(__super__){inherits(DebounceObserver,__super__);function DebounceObserver(observer,source,dueTime,scheduler,cancelable){this._o=observer;this._s=source;this._d=dueTime;this._scheduler=scheduler;this._c=cancelable;this._v=null;this._hv=false;this._id=0;__super__.call(this)}DebounceObserver.prototype.next=function(x){this._hv=true;this._v=x;var currentId=++this._id,d=new SingleAssignmentDisposable;this._c.setDisposable(d);d.setDisposable(this._scheduler.scheduleFuture(this,this._d,function(_,self){self._hv&&self._id===currentId&&self._o.onNext(x);self._hv=false}))};DebounceObserver.prototype.error=function(e){this._c.dispose();this._o.onError(e);this._hv=false;this._id++};DebounceObserver.prototype.completed=function(){this._c.dispose();this._hv&&this._o.onNext(this._v);this._o.onCompleted();this._hv=false;this._id++};return DebounceObserver}(AbstractObserver);function debounceWithSelector(source,durationSelector){return new AnonymousObservable(function(o){var value,hasValue=false,cancelable=new SerialDisposable,id=0;var subscription=source.subscribe(function(x){var throttle=tryCatch(durationSelector)(x);if(throttle===errorObj){return o.onError(throttle.e)}isPromise(throttle)&&(throttle=observableFromPromise(throttle));hasValue=true;value=x;id++;var currentid=id,d=new SingleAssignmentDisposable;cancelable.setDisposable(d);d.setDisposable(throttle.subscribe(function(){hasValue&&id===currentid&&o.onNext(value);hasValue=false;d.dispose()},function(e){o.onError(e)},function(){hasValue&&id===currentid&&o.onNext(value);hasValue=false;d.dispose()}))},function(e){cancelable.dispose();o.onError(e);hasValue=false;id++},function(){cancelable.dispose();hasValue&&o.onNext(value);o.onCompleted();hasValue=false;id++});return new BinaryDisposable(subscription,cancelable)},source)}observableProto.debounce=function(){if(isFunction(arguments[0])){return debounceWithSelector(this,arguments[0])}else if(typeof arguments[0]==="number"){return new DebounceObservable(this,arguments[0],arguments[1])}else{throw new Error("Invalid arguments")}};observableProto.windowWithTime=function(timeSpan,timeShiftOrScheduler,scheduler){var source=this,timeShift;timeShiftOrScheduler==null&&(timeShift=timeSpan);isScheduler(scheduler)||(scheduler=defaultScheduler);if(typeof timeShiftOrScheduler==="number"){timeShift=timeShiftOrScheduler}else if(isScheduler(timeShiftOrScheduler)){timeShift=timeSpan;scheduler=timeShiftOrScheduler}return new AnonymousObservable(function(observer){var groupDisposable,nextShift=timeShift,nextSpan=timeSpan,q=[],refCountDisposable,timerD=new SerialDisposable,totalTime=0;groupDisposable=new CompositeDisposable(timerD),refCountDisposable=new RefCountDisposable(groupDisposable);function createTimer(){var m=new SingleAssignmentDisposable,isSpan=false,isShift=false;timerD.setDisposable(m);if(nextSpan===nextShift){isSpan=true;isShift=true}else if(nextSpan0&&now-this._q[0].interval>=this._d){this._o.onNext(this._q.shift().value)}};SkipLastWithTimeObserver.prototype.error=function(e){this._o.onError(e)};SkipLastWithTimeObserver.prototype.completed=function(){var now=this._s.now();while(this._q.length>0&&now-this._q[0].interval>=this._d){this._o.onNext(this._q.shift().value)}this._o.onCompleted()};return SkipLastWithTimeObserver}(AbstractObserver);observableProto.skipLastWithTime=function(duration,scheduler){isScheduler(scheduler)||(scheduler=defaultScheduler);return new SkipLastWithTimeObservable(this,duration,scheduler)};var TakeLastWithTimeObservable=function(__super__){inherits(TakeLastWithTimeObservable,__super__);function TakeLastWithTimeObservable(source,d,s){this.source=source;this._d=d;this._s=s;__super__.call(this)}TakeLastWithTimeObservable.prototype.subscribeCore=function(o){return this.source.subscribe(new TakeLastWithTimeObserver(o,this._d,this._s))};return TakeLastWithTimeObservable}(ObservableBase);var TakeLastWithTimeObserver=function(__super__){inherits(TakeLastWithTimeObserver,__super__);function TakeLastWithTimeObserver(o,d,s){this._o=o;this._d=d;this._s=s;this._q=[];__super__.call(this)}TakeLastWithTimeObserver.prototype.next=function(x){var now=this._s.now();this._q.push({interval:now,value:x});while(this._q.length>0&&now-this._q[0].interval>=this._d){this._q.shift()}};TakeLastWithTimeObserver.prototype.error=function(e){this._o.onError(e)};TakeLastWithTimeObserver.prototype.completed=function(){var now=this._s.now();while(this._q.length>0){var next=this._q.shift();if(now-next.interval<=this._d){this._o.onNext(next.value)}}this._o.onCompleted()};return TakeLastWithTimeObserver}(AbstractObserver);observableProto.takeLastWithTime=function(duration,scheduler){isScheduler(scheduler)||(scheduler=defaultScheduler);return new TakeLastWithTimeObservable(this,duration,scheduler)};observableProto.takeLastBufferWithTime=function(duration,scheduler){var source=this;isScheduler(scheduler)||(scheduler=defaultScheduler);return new AnonymousObservable(function(o){var q=[];return source.subscribe(function(x){var now=scheduler.now();q.push({interval:now,value:x});while(q.length>0&&now-q[0].interval>=duration){q.shift()}},function(e){o.onError(e)},function(){var now=scheduler.now(),res=[];while(q.length>0){var next=q.shift();now-next.interval<=duration&&res.push(next.value)}o.onNext(res);o.onCompleted()})},source)};var TakeWithTimeObservable=function(__super__){inherits(TakeWithTimeObservable,__super__);function TakeWithTimeObservable(source,d,s){this.source=source;this._d=d;this._s=s;__super__.call(this)}function scheduleMethod(s,o){o.onCompleted()}TakeWithTimeObservable.prototype.subscribeCore=function(o){return new BinaryDisposable(this._s.scheduleFuture(o,this._d,scheduleMethod),this.source.subscribe(o))};return TakeWithTimeObservable}(ObservableBase);observableProto.takeWithTime=function(duration,scheduler){isScheduler(scheduler)||(scheduler=defaultScheduler);return new TakeWithTimeObservable(this,duration,scheduler)};var SkipWithTimeObservable=function(__super__){inherits(SkipWithTimeObservable,__super__);function SkipWithTimeObservable(source,d,s){this.source=source;this._d=d;this._s=s;this._open=false;__super__.call(this)}function scheduleMethod(s,self){self._open=true}SkipWithTimeObservable.prototype.subscribeCore=function(o){return new BinaryDisposable(this._s.scheduleFuture(this,this._d,scheduleMethod),this.source.subscribe(new SkipWithTimeObserver(o,this)))};return SkipWithTimeObservable}(ObservableBase);var SkipWithTimeObserver=function(__super__){inherits(SkipWithTimeObserver,__super__);function SkipWithTimeObserver(o,p){this._o=o;this._p=p;__super__.call(this)}SkipWithTimeObserver.prototype.next=function(x){this._p._open&&this._o.onNext(x)};SkipWithTimeObserver.prototype.error=function(e){this._o.onError(e)};SkipWithTimeObserver.prototype.completed=function(){this._o.onCompleted()};return SkipWithTimeObserver}(AbstractObserver);observableProto.skipWithTime=function(duration,scheduler){isScheduler(scheduler)||(scheduler=defaultScheduler);return new SkipWithTimeObservable(this,duration,scheduler)};var SkipUntilWithTimeObservable=function(__super__){inherits(SkipUntilWithTimeObservable,__super__);function SkipUntilWithTimeObservable(source,startTime,scheduler){this.source=source;this._st=startTime;this._s=scheduler;__super__.call(this)}function scheduleMethod(s,state){state._open=true}SkipUntilWithTimeObservable.prototype.subscribeCore=function(o){this._open=false;return new BinaryDisposable(this._s.scheduleFuture(this,this._st,scheduleMethod),this.source.subscribe(new SkipUntilWithTimeObserver(o,this)))};return SkipUntilWithTimeObservable}(ObservableBase);var SkipUntilWithTimeObserver=function(__super__){inherits(SkipUntilWithTimeObserver,__super__);function SkipUntilWithTimeObserver(o,p){this._o=o;this._p=p;__super__.call(this)}SkipUntilWithTimeObserver.prototype.next=function(x){this._p._open&&this._o.onNext(x)};SkipUntilWithTimeObserver.prototype.error=function(e){this._o.onError(e)};SkipUntilWithTimeObserver.prototype.completed=function(){this._o.onCompleted()};return SkipUntilWithTimeObserver}(AbstractObserver);observableProto.skipUntilWithTime=function(startTime,scheduler){isScheduler(scheduler)||(scheduler=defaultScheduler);return new SkipUntilWithTimeObservable(this,startTime,scheduler)};observableProto.takeUntilWithTime=function(endTime,scheduler){isScheduler(scheduler)||(scheduler=defaultScheduler);var source=this;return new AnonymousObservable(function(o){return new BinaryDisposable(scheduler.scheduleFuture(o,endTime,function(_,o){o.onCompleted()}),source.subscribe(o))},source)};observableProto.throttle=function(windowDuration,scheduler){isScheduler(scheduler)||(scheduler=defaultScheduler);var duration=+windowDuration||0;if(duration<=0){throw new RangeError("windowDuration cannot be less or equal zero.")}var source=this;return new AnonymousObservable(function(o){var lastOnNext=0;return source.subscribe(function(x){var now=scheduler.now();if(lastOnNext===0||now-lastOnNext>=duration){lastOnNext=now;o.onNext(x)}},function(e){o.onError(e)},function(){o.onCompleted()})},source)};var TransduceObserver=function(__super__){inherits(TransduceObserver,__super__);function TransduceObserver(o,xform){this._o=o;this._xform=xform;__super__.call(this)}TransduceObserver.prototype.next=function(x){var res=tryCatch(this._xform["@@transducer/step"]).call(this._xform,this._o,x);if(res===errorObj){this._o.onError(res.e)}};TransduceObserver.prototype.error=function(e){this._o.onError(e)};TransduceObserver.prototype.completed=function(){this._xform["@@transducer/result"](this._o)};return TransduceObserver}(AbstractObserver);function transformForObserver(o){return{"@@transducer/init":function(){return o},"@@transducer/step":function(obs,input){return obs.onNext(input)},"@@transducer/result":function(obs){return obs.onCompleted()}}}observableProto.transduce=function(transducer){var source=this;return new AnonymousObservable(function(o){var xform=transducer(transformForObserver(o));return source.subscribe(new TransduceObserver(o,xform))},source)};var SwitchFirstObservable=function(__super__){inherits(SwitchFirstObservable,__super__);function SwitchFirstObservable(source){this.source=source;__super__.call(this)}SwitchFirstObservable.prototype.subscribeCore=function(o){var m=new SingleAssignmentDisposable,g=new CompositeDisposable,state={hasCurrent:false,isStopped:false,o:o,g:g};g.add(m);m.setDisposable(this.source.subscribe(new SwitchFirstObserver(state)));return g};return SwitchFirstObservable}(ObservableBase);var SwitchFirstObserver=function(__super__){inherits(SwitchFirstObserver,__super__);function SwitchFirstObserver(state){this._s=state;__super__.call(this)}SwitchFirstObserver.prototype.next=function(x){if(!this._s.hasCurrent){this._s.hasCurrent=true;isPromise(x)&&(x=observableFromPromise(x));var inner=new SingleAssignmentDisposable;this._s.g.add(inner);inner.setDisposable(x.subscribe(new InnerObserver(this._s,inner)))}};SwitchFirstObserver.prototype.error=function(e){this._s.o.onError(e)};SwitchFirstObserver.prototype.completed=function(){this._s.isStopped=true;!this._s.hasCurrent&&this._s.g.length===1&&this._s.o.onCompleted()};inherits(InnerObserver,__super__);function InnerObserver(state,inner){this._s=state;this._i=inner;__super__.call(this)}InnerObserver.prototype.next=function(x){this._s.o.onNext(x)};InnerObserver.prototype.error=function(e){this._s.o.onError(e)};InnerObserver.prototype.completed=function(){this._s.g.remove(this._i);this._s.hasCurrent=false;this._s.isStopped&&this._s.g.length===1&&this._s.o.onCompleted()};return SwitchFirstObserver}(AbstractObserver);observableProto.switchFirst=function(){return new SwitchFirstObservable(this)};observableProto.flatMapFirst=observableProto.selectManyFirst=function(selector,resultSelector,thisArg){return new FlatMapObservable(this,selector,resultSelector,thisArg).switchFirst()};Rx.Observable.prototype.flatMapWithMaxConcurrent=function(limit,selector,resultSelector,thisArg){return new FlatMapObservable(this,selector,resultSelector,thisArg).merge(limit)};var VirtualTimeScheduler=Rx.VirtualTimeScheduler=function(__super__){inherits(VirtualTimeScheduler,__super__);function VirtualTimeScheduler(initialClock,comparer){this.clock=initialClock;this.comparer=comparer;this.isEnabled=false;this.queue=new PriorityQueue(1024);__super__.call(this)}var VirtualTimeSchedulerPrototype=VirtualTimeScheduler.prototype;VirtualTimeSchedulerPrototype.now=function(){return this.toAbsoluteTime(this.clock)};VirtualTimeSchedulerPrototype.schedule=function(state,action){return this.scheduleAbsolute(state,this.clock,action)};VirtualTimeSchedulerPrototype.scheduleFuture=function(state,dueTime,action){var dt=dueTime instanceof Date?this.toRelativeTime(dueTime-this.now()):this.toRelativeTime(dueTime);return this.scheduleRelative(state,dt,action)};VirtualTimeSchedulerPrototype.add=notImplemented;VirtualTimeSchedulerPrototype.toAbsoluteTime=notImplemented;VirtualTimeSchedulerPrototype.toRelativeTime=notImplemented;VirtualTimeSchedulerPrototype.schedulePeriodic=function(state,period,action){var s=new SchedulePeriodicRecursive(this,state,period,action);return s.start()};VirtualTimeSchedulerPrototype.scheduleRelative=function(state,dueTime,action){var runAt=this.add(this.clock,dueTime);return this.scheduleAbsolute(state,runAt,action)};VirtualTimeSchedulerPrototype.start=function(){if(!this.isEnabled){this.isEnabled=true;do{var next=this.getNext();if(next!==null){this.comparer(next.dueTime,this.clock)>0&&(this.clock=next.dueTime);next.invoke()}else{this.isEnabled=false}}while(this.isEnabled)}};VirtualTimeSchedulerPrototype.stop=function(){this.isEnabled=false};VirtualTimeSchedulerPrototype.advanceTo=function(time){var dueToClock=this.comparer(this.clock,time);if(this.comparer(this.clock,time)>0){throw new ArgumentOutOfRangeError}if(dueToClock===0){return}if(!this.isEnabled){this.isEnabled=true;do{var next=this.getNext();if(next!==null&&this.comparer(next.dueTime,time)<=0){this.comparer(next.dueTime,this.clock)>0&&(this.clock=next.dueTime);next.invoke()}else{this.isEnabled=false}}while(this.isEnabled);this.clock=time}};VirtualTimeSchedulerPrototype.advanceBy=function(time){var dt=this.add(this.clock,time),dueToClock=this.comparer(this.clock,dt);if(dueToClock>0){throw new ArgumentOutOfRangeError}if(dueToClock===0){return}this.advanceTo(dt)};VirtualTimeSchedulerPrototype.sleep=function(time){var dt=this.add(this.clock,time);if(this.comparer(this.clock,dt)>=0){throw new ArgumentOutOfRangeError}this.clock=dt};VirtualTimeSchedulerPrototype.getNext=function(){while(this.queue.length>0){var next=this.queue.peek();if(next.isCancelled()){this.queue.dequeue()}else{return next}}return null};VirtualTimeSchedulerPrototype.scheduleAbsolute=function(state,dueTime,action){var self=this;function run(scheduler,state1){self.queue.remove(si);return action(scheduler,state1)}var si=new ScheduledItem(this,state,run,dueTime,this.comparer);this.queue.enqueue(si);return si.disposable};return VirtualTimeScheduler}(Scheduler);Rx.HistoricalScheduler=function(__super__){inherits(HistoricalScheduler,__super__);function HistoricalScheduler(initialClock,comparer){var clock=initialClock==null?0:initialClock;var cmp=comparer||defaultSubComparer;__super__.call(this,clock,cmp)}var HistoricalSchedulerProto=HistoricalScheduler.prototype;HistoricalSchedulerProto.add=function(absolute,relative){return absolute+relative};HistoricalSchedulerProto.toAbsoluteTime=function(absolute){return new Date(absolute).getTime()};HistoricalSchedulerProto.toRelativeTime=function(timeSpan){return timeSpan};return HistoricalScheduler}(Rx.VirtualTimeScheduler);function OnNextPredicate(predicate){this.predicate=predicate}OnNextPredicate.prototype.equals=function(other){if(other===this){return true}if(other==null){return false}if(other.kind!=="N"){return false}return this.predicate(other.value)};function OnErrorPredicate(predicate){this.predicate=predicate}OnErrorPredicate.prototype.equals=function(other){if(other===this){return true}if(other==null){return false}if(other.kind!=="E"){return false}return this.predicate(other.error)};var ReactiveTest=Rx.ReactiveTest={created:100,subscribed:200,disposed:1e3,onNext:function(ticks,value){return typeof value==="function"?new Recorded(ticks,new OnNextPredicate(value)):new Recorded(ticks,Notification.createOnNext(value))},onError:function(ticks,error){return typeof error==="function"?new Recorded(ticks,new OnErrorPredicate(error)):new Recorded(ticks,Notification.createOnError(error))},onCompleted:function(ticks){return new Recorded(ticks,Notification.createOnCompleted())},subscribe:function(start,end){return new Subscription(start,end)}};var Recorded=Rx.Recorded=function(time,value,comparer){this.time=time;this.value=value;this.comparer=comparer||defaultComparer};Recorded.prototype.equals=function(other){return this.time===other.time&&this.comparer(this.value,other.value)};Recorded.prototype.toString=function(){return this.value.toString()+"@"+this.time};var Subscription=Rx.Subscription=function(start,end){this.subscribe=start;this.unsubscribe=end||Number.MAX_VALUE};Subscription.prototype.equals=function(other){return this.subscribe===other.subscribe&&this.unsubscribe===other.unsubscribe};Subscription.prototype.toString=function(){return"("+this.subscribe+", "+(this.unsubscribe===Number.MAX_VALUE?"Infinite":this.unsubscribe)+")"};var MockDisposable=Rx.MockDisposable=function(scheduler){this.scheduler=scheduler;this.disposes=[];this.disposes.push(this.scheduler.clock)};MockDisposable.prototype.dispose=function(){this.disposes.push(this.scheduler.clock)};var MockObserver=function(__super__){inherits(MockObserver,__super__);function MockObserver(scheduler){__super__.call(this);this.scheduler=scheduler;this.messages=[]}var MockObserverPrototype=MockObserver.prototype;MockObserverPrototype.onNext=function(value){this.messages.push(new Recorded(this.scheduler.clock,Notification.createOnNext(value)))};MockObserverPrototype.onError=function(e){this.messages.push(new Recorded(this.scheduler.clock,Notification.createOnError(e)))};MockObserverPrototype.onCompleted=function(){this.messages.push(new Recorded(this.scheduler.clock,Notification.createOnCompleted()))};return MockObserver}(Observer);function MockPromise(scheduler,messages){var self=this;this.scheduler=scheduler;this.messages=messages;this.subscriptions=[];this.observers=[];for(var i=0,len=this.messages.length;iy?1:x0},onCompleted:function(){checkDisposed(this);if(!this.isStopped){this.isStopped=true;for(var i=0,os=cloneArray(this.observers),len=os.length;i0},onCompleted:function(){var i,len;checkDisposed(this);if(!this.isStopped){this.isStopped=true;var os=cloneArray(this.observers),len=os.length;if(this.hasValue){for(i=0;i0},onCompleted:function(){checkDisposed(this);if(this.isStopped){return}this.isStopped=true;for(var i=0,os=cloneArray(this.observers),len=os.length;i0},_trim:function(now){while(this.q.length>this.bufferSize){this.q.shift()}while(this.q.length>0&&now-this.q[0].interval>this.windowSize){this.q.shift()}},onNext:function(value){checkDisposed(this);if(this.isStopped){return}var now=this.scheduler.now();this.q.push({interval:now,value:value});this._trim(now);for(var i=0,os=cloneArray(this.observers),len=os.length;i=0;i--){index=bottom+(top-bottom>>1);pointerId=todosList[index].id;if(pointerId===todoid){return index}else if(pointerIdtodoid){top=index}}return null}function makeModification$(actions){var clearInputMod$=actions.clearInput$.map(function(){return function(todosData){return todosData}});var insertTodoMod$=actions.insertTodo$.map(function(todoTitle){return function(todosData){var lastId=todosData.list.length>0?todosData.list[todosData.list.length-1].id:0;todosData.list.push({id:lastId+1,title:todoTitle,completed:false});return todosData}});var editTodoMod$=actions.editTodo$.map(function(action){return function(todosData){var todoIndex=searchTodoIndex(todosData.list,action.id);todosData.list[todoIndex].title=action.title;return todosData}});var toggleTodoMod$=actions.toggleTodo$.map(function(action){return function(todosData){var todoIndex=searchTodoIndex(todosData.list,action.id);var previousCompleted=todosData.list[todoIndex].completed;todosData.list[todoIndex].completed=!previousCompleted;return todosData}});var toggleAllMod$=actions.toggleAll$.map(function(){return function(todosData){var allAreCompleted=todosData.list.reduce(function(x,y){return x&&y.completed},true);todosData.list.forEach(function(todoData){todoData.completed=allAreCompleted?false:true});return todosData}});var deleteTodoMod$=actions.deleteTodo$.map(function(action){return function(todosData){var todoIndex=searchTodoIndex(todosData.list,action.id);todosData.list.splice(todoIndex,1);return todosData}});var deleteCompletedsMod$=actions.deleteCompleteds$.map(function(){return function(todosData){todosData.list=todosData.list.filter(function(todoData){return todoData.completed===false});return todosData}});var changeRouteMod$=actions.changeRoute$.startWith("/").map(function(route){var filterFn=getFilterFn(route);return function(todosData){todosData.filter=route.replace("/","").trim();todosData.filterFn=filterFn;return todosData}});return _rx.Observable.merge(insertTodoMod$,deleteTodoMod$,toggleTodoMod$,toggleAllMod$,clearInputMod$,deleteCompletedsMod$,editTodoMod$,changeRouteMod$)}function model(actions,sourceTodosData$){var modification$=makeModification$(actions);return sourceTodosData$.concat(modification$).scan(function(todosData,modFn){return modFn(todosData)}).shareReplay(1)}exports["default"]=model;module.exports=exports["default"]},{rx:66}],72:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports["default"]=serialize;function serialize(todos$){return todos$.map(function(todosData){return JSON.stringify({list:todosData.list.map(function(todoData){return{title:todoData.title,completed:todoData.completed,id:todoData.id}})})})}module.exports=exports["default"]},{}],73:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports["default"]=deserialize;function merge(){var result={};for(var i=0;i0?(0,_cycleDom.button)(".clear-completed","Clear completed ("+amountCompleted+")"):null])}function view(todos$){return todos$.map(function(todos){return(0,_cycleDom.div)([renderHeader(),renderMainSection(todos),renderFooter(todos)])})}module.exports=exports["default"]},{"@cycle/dom":2}],75:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _extends=Object.assign||function(target){for(var i=1;i=0;i--){index=bottom+(top-bottom>>1);pointerId=todosList[index].id;if(pointerId===todoid){return index}else if(pointerIdtodoid){top=index}}return null}function makeModification$(actions){var clearInputMod$=actions.clearInput$.map(function(){return function(todosData){return todosData}});var insertTodoMod$=actions.insertTodo$.map(function(todoTitle){return function(todosData){var lastId=todosData.list.length>0?todosData.list[todosData.list.length-1].id:0;todosData.list.push({id:lastId+1,title:todoTitle,completed:false});return todosData}});var editTodoMod$=actions.editTodo$.map(function(action){return function(todosData){var todoIndex=searchTodoIndex(todosData.list,action.id);todosData.list[todoIndex].title=action.title;return todosData}});var toggleTodoMod$=actions.toggleTodo$.map(function(action){return function(todosData){var todoIndex=searchTodoIndex(todosData.list,action.id);var previousCompleted=todosData.list[todoIndex].completed;todosData.list[todoIndex].completed=!previousCompleted;return todosData}});var toggleAllMod$=actions.toggleAll$.map(function(){return function(todosData){var allAreCompleted=todosData.list.reduce(function(x,y){return x&&y.completed},true);todosData.list.forEach(function(todoData){todoData.completed=allAreCompleted?false:true});return todosData}});var deleteTodoMod$=actions.deleteTodo$.map(function(action){return function(todosData){var todoIndex=searchTodoIndex(todosData.list,action.id);todosData.list.splice(todoIndex,1);return todosData}});var deleteCompletedsMod$=actions.deleteCompleteds$.map(function(){return function(todosData){todosData.list=todosData.list.filter(function(todoData){return todoData.completed===false});return todosData}});var changeRouteMod$=actions.changeRoute$.startWith("/").map(function(route){var filterFn=getFilterFn(route);return function(todosData){todosData.filter=route.replace("/","").trim();todosData.filterFn=filterFn;return todosData}});return _rx.Observable.merge(insertTodoMod$,deleteTodoMod$,toggleTodoMod$,toggleAllMod$,clearInputMod$,deleteCompletedsMod$,editTodoMod$,changeRouteMod$)}function model(actions,sourceTodosData$){var modification$=makeModification$(actions);return sourceTodosData$.concat(modification$).scan(function(todosData,modFn){return modFn(todosData)}).shareReplay(1)}exports["default"]=model;module.exports=exports["default"]},{rx:66}],78:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports["default"]=serialize;function serialize(todos$){return todos$.map(function(todosData){return JSON.stringify({list:todosData.list.map(function(todoData){return{title:todoData.title,completed:todoData.completed,id:todoData.id}})})})}module.exports=exports["default"]},{}],79:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports["default"]=deserialize;function merge(){var result={};for(var i=0;i0?(0,_cycleDom.button)(".clear-completed","Clear completed ("+amountCompleted+")"):null])}function view(todos$){return todos$.map(function(todos){return(0,_cycleDom.div)([renderHeader(),renderMainSection(todos),renderFooter(todos)])})}module.exports=exports["default"]},{"@cycle/dom":2}],81:[function(require,module,exports){"use strict";Object.defineProperty(exports,"__esModule",{value:true});var _createClass=function(){function defineProperties(target,props){for(var i=0;i ');
+}
+
+.todo-list li .toggle:checked:after {
+ content: url('data:image/svg+xml;utf8, ');
+}
+
+.todo-list li label {
+ white-space: pre-line;
+ word-break: break-all;
+ padding: 15px 60px 15px 15px;
+ margin-left: 45px;
+ display: block;
+ line-height: 1.2;
+ transition: color 0.4s;
+}
+
+.todo-list li.completed label {
+ color: #d9d9d9;
+ text-decoration: line-through;
+}
+
+.todo-list li .destroy {
+ display: none;
+ position: absolute;
+ top: 0;
+ right: 10px;
+ bottom: 0;
+ width: 40px;
+ height: 40px;
+ margin: auto 0;
+ font-size: 30px;
+ color: #cc9a9a;
+ margin-bottom: 11px;
+ transition: color 0.2s ease-out;
+}
+
+.todo-list li .destroy:hover {
+ color: #af5b5e;
+}
+
+.todo-list li .destroy:after {
+ content: '×';
+}
+
+.todo-list li:hover .destroy {
+ display: block;
+}
+
+.todo-list li .edit {
+ display: none;
+}
+
+.todo-list li.editing:last-child {
+ margin-bottom: -1px;
+}
+
+.footer {
+ color: #777;
+ padding: 10px 15px;
+ height: 20px;
+ text-align: center;
+ border-top: 1px solid #e6e6e6;
+}
+
+.footer:before {
+ content: '';
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ height: 50px;
+ overflow: hidden;
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
+ 0 8px 0 -3px #f6f6f6,
+ 0 9px 1px -3px rgba(0, 0, 0, 0.2),
+ 0 16px 0 -6px #f6f6f6,
+ 0 17px 2px -6px rgba(0, 0, 0, 0.2);
+}
+
+.todo-count {
+ float: left;
+ text-align: left;
+}
+
+.todo-count strong {
+ font-weight: 300;
+}
+
+.filters {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ position: absolute;
+ right: 0;
+ left: 0;
+}
+
+.filters li {
+ display: inline;
+}
+
+.filters li a {
+ color: inherit;
+ margin: 3px;
+ padding: 3px 7px;
+ text-decoration: none;
+ border: 1px solid transparent;
+ border-radius: 3px;
+}
+
+.filters li a.selected,
+.filters li a:hover {
+ border-color: rgba(175, 47, 47, 0.1);
+}
+
+.filters li a.selected {
+ border-color: rgba(175, 47, 47, 0.2);
+}
+
+.clear-completed,
+html .clear-completed:active {
+ float: right;
+ position: relative;
+ line-height: 20px;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.clear-completed:hover {
+ text-decoration: underline;
+}
+
+.info {
+ margin: 65px auto 0;
+ color: #bfbfbf;
+ font-size: 10px;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+ text-align: center;
+}
+
+.info p {
+ line-height: 1;
+}
+
+.info a {
+ color: inherit;
+ text-decoration: none;
+ font-weight: 400;
+}
+
+.info a:hover {
+ text-decoration: underline;
+}
+
+/*
+ Hack to remove background from Mobile Safari.
+ Can't use it globally since it destroys checkboxes in Firefox
+*/
+@media screen and (-webkit-min-device-pixel-ratio:0) {
+ .toggle-all,
+ .todo-list li .toggle {
+ background: none;
+ }
+
+ .todo-list li .toggle {
+ height: 40px;
+ }
+
+ .toggle-all {
+ -webkit-transform: rotate(90deg);
+ transform: rotate(90deg);
+ -webkit-appearance: none;
+ appearance: none;
+ }
+}
+
+@media (max-width: 430px) {
+ .footer {
+ height: 50px;
+ }
+
+ .filters {
+ bottom: 10px;
+ }
+}
diff --git a/examples/cyclejs/node_modules/todomvc-app-css/package.json b/examples/cyclejs/node_modules/todomvc-app-css/package.json
new file mode 100644
index 0000000000..8fb2379517
--- /dev/null
+++ b/examples/cyclejs/node_modules/todomvc-app-css/package.json
@@ -0,0 +1,96 @@
+{
+ "_args": [
+ [
+ "todomvc-app-css@2.0.3",
+ "/Users/staltz/oss/cycle/todomvc-cycle"
+ ]
+ ],
+ "_from": "todomvc-app-css@2.0.3",
+ "_id": "todomvc-app-css@2.0.3",
+ "_inCache": true,
+ "_installable": true,
+ "_location": "/todomvc-app-css",
+ "_nodeVersion": "4.2.1",
+ "_npmUser": {
+ "email": "sindresorhus@gmail.com",
+ "name": "sindresorhus"
+ },
+ "_npmVersion": "2.14.7",
+ "_phantomChildren": {},
+ "_requested": {
+ "name": "todomvc-app-css",
+ "raw": "todomvc-app-css@2.0.3",
+ "rawSpec": "2.0.3",
+ "scope": null,
+ "spec": "2.0.3",
+ "type": "version"
+ },
+ "_requiredBy": [
+ "/"
+ ],
+ "_resolved": "https://registry.npmjs.org/todomvc-app-css/-/todomvc-app-css-2.0.3.tgz",
+ "_shasum": "3f6a9e5a9e6303d90f0f4e4b3d4363676d5c1936",
+ "_shrinkwrap": null,
+ "_spec": "todomvc-app-css@2.0.3",
+ "_where": "/Users/staltz/oss/cycle/todomvc-cycle",
+ "author": {
+ "email": "sindresorhus@gmail.com",
+ "name": "Sindre Sorhus",
+ "url": "sindresorhus.com"
+ },
+ "bugs": {
+ "url": "https://github.com/tastejs/todomvc-app-css/issues"
+ },
+ "dependencies": {},
+ "description": "CSS for TodoMVC apps",
+ "devDependencies": {},
+ "directories": {},
+ "dist": {
+ "shasum": "3f6a9e5a9e6303d90f0f4e4b3d4363676d5c1936",
+ "tarball": "https://registry.npmjs.org/todomvc-app-css/-/todomvc-app-css-2.0.3.tgz"
+ },
+ "files": [
+ "index.css"
+ ],
+ "gitHead": "18b796505e44bd7fcf1c92d2a5a7a754d2f23e7f",
+ "homepage": "https://github.com/tastejs/todomvc-app-css",
+ "keywords": [
+ "todomvc",
+ "tastejs",
+ "app",
+ "todo",
+ "template",
+ "css",
+ "style",
+ "stylesheet"
+ ],
+ "license": "CC-BY-4.0",
+ "maintainers": [
+ {
+ "email": "sindresorhus@gmail.com",
+ "name": "sindresorhus"
+ },
+ {
+ "email": "addyosmani@gmail.com",
+ "name": "addyosmani"
+ },
+ {
+ "email": "phartig@rdrei.net",
+ "name": "passy"
+ },
+ {
+ "email": "sawchuk@gmail.com",
+ "name": "stephenplusplus"
+ }
+ ],
+ "name": "todomvc-app-css",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/tastejs/todomvc-app-css.git"
+ },
+ "scripts": {},
+ "style": "index.css",
+ "version": "2.0.3"
+}
diff --git a/examples/cyclejs/node_modules/todomvc-app-css/readme.md b/examples/cyclejs/node_modules/todomvc-app-css/readme.md
new file mode 100644
index 0000000000..6ddbebf024
--- /dev/null
+++ b/examples/cyclejs/node_modules/todomvc-app-css/readme.md
@@ -0,0 +1,28 @@
+# todomvc-app-css
+
+> CSS for TodoMVC apps
+
+![](screenshot.png)
+
+
+## Install
+
+
+```
+$ npm install --save todomvc-app-css
+```
+
+
+## Getting started
+
+```html
+
+```
+
+See the [TodoMVC app template](https://github.com/tastejs/todomvc-app-template).
+
+
+
+## License
+
+ This work by Sindre Sorhus is licensed under a Creative Commons Attribution 4.0 International License .
diff --git a/examples/cyclejs/node_modules/todomvc-common/base.css b/examples/cyclejs/node_modules/todomvc-common/base.css
new file mode 100644
index 0000000000..da65968a73
--- /dev/null
+++ b/examples/cyclejs/node_modules/todomvc-common/base.css
@@ -0,0 +1,141 @@
+hr {
+ margin: 20px 0;
+ border: 0;
+ border-top: 1px dashed #c5c5c5;
+ border-bottom: 1px dashed #f7f7f7;
+}
+
+.learn a {
+ font-weight: normal;
+ text-decoration: none;
+ color: #b83f45;
+}
+
+.learn a:hover {
+ text-decoration: underline;
+ color: #787e7e;
+}
+
+.learn h3,
+.learn h4,
+.learn h5 {
+ margin: 10px 0;
+ font-weight: 500;
+ line-height: 1.2;
+ color: #000;
+}
+
+.learn h3 {
+ font-size: 24px;
+}
+
+.learn h4 {
+ font-size: 18px;
+}
+
+.learn h5 {
+ margin-bottom: 0;
+ font-size: 14px;
+}
+
+.learn ul {
+ padding: 0;
+ margin: 0 0 30px 25px;
+}
+
+.learn li {
+ line-height: 20px;
+}
+
+.learn p {
+ font-size: 15px;
+ font-weight: 300;
+ line-height: 1.3;
+ margin-top: 0;
+ margin-bottom: 0;
+}
+
+#issue-count {
+ display: none;
+}
+
+.quote {
+ border: none;
+ margin: 20px 0 60px 0;
+}
+
+.quote p {
+ font-style: italic;
+}
+
+.quote p:before {
+ content: '“';
+ font-size: 50px;
+ opacity: .15;
+ position: absolute;
+ top: -20px;
+ left: 3px;
+}
+
+.quote p:after {
+ content: '”';
+ font-size: 50px;
+ opacity: .15;
+ position: absolute;
+ bottom: -42px;
+ right: 3px;
+}
+
+.quote footer {
+ position: absolute;
+ bottom: -40px;
+ right: 0;
+}
+
+.quote footer img {
+ border-radius: 3px;
+}
+
+.quote footer a {
+ margin-left: 5px;
+ vertical-align: middle;
+}
+
+.speech-bubble {
+ position: relative;
+ padding: 10px;
+ background: rgba(0, 0, 0, .04);
+ border-radius: 5px;
+}
+
+.speech-bubble:after {
+ content: '';
+ position: absolute;
+ top: 100%;
+ right: 30px;
+ border: 13px solid transparent;
+ border-top-color: rgba(0, 0, 0, .04);
+}
+
+.learn-bar > .learn {
+ position: absolute;
+ width: 272px;
+ top: 8px;
+ left: -300px;
+ padding: 10px;
+ border-radius: 5px;
+ background-color: rgba(255, 255, 255, .6);
+ transition-property: left;
+ transition-duration: 500ms;
+}
+
+@media (min-width: 899px) {
+ .learn-bar {
+ width: auto;
+ padding-left: 300px;
+ }
+
+ .learn-bar > .learn {
+ left: 8px;
+ }
+}
diff --git a/examples/cyclejs/node_modules/todomvc-common/base.js b/examples/cyclejs/node_modules/todomvc-common/base.js
new file mode 100644
index 0000000000..44fb50c613
--- /dev/null
+++ b/examples/cyclejs/node_modules/todomvc-common/base.js
@@ -0,0 +1,244 @@
+/* global _ */
+(function () {
+ 'use strict';
+
+ /* jshint ignore:start */
+ // Underscore's Template Module
+ // Courtesy of underscorejs.org
+ var _ = (function (_) {
+ _.defaults = function (object) {
+ if (!object) {
+ return object;
+ }
+ for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
+ var iterable = arguments[argsIndex];
+ if (iterable) {
+ for (var key in iterable) {
+ if (object[key] == null) {
+ object[key] = iterable[key];
+ }
+ }
+ }
+ }
+ return object;
+ }
+
+ // By default, Underscore uses ERB-style template delimiters, change the
+ // following template settings to use alternative delimiters.
+ _.templateSettings = {
+ evaluate : /<%([\s\S]+?)%>/g,
+ interpolate : /<%=([\s\S]+?)%>/g,
+ escape : /<%-([\s\S]+?)%>/g
+ };
+
+ // When customizing `templateSettings`, if you don't want to define an
+ // interpolation, evaluation or escaping regex, we need one that is
+ // guaranteed not to match.
+ var noMatch = /(.)^/;
+
+ // Certain characters need to be escaped so that they can be put into a
+ // string literal.
+ var escapes = {
+ "'": "'",
+ '\\': '\\',
+ '\r': 'r',
+ '\n': 'n',
+ '\t': 't',
+ '\u2028': 'u2028',
+ '\u2029': 'u2029'
+ };
+
+ var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
+
+ // JavaScript micro-templating, similar to John Resig's implementation.
+ // Underscore templating handles arbitrary delimiters, preserves whitespace,
+ // and correctly escapes quotes within interpolated code.
+ _.template = function(text, data, settings) {
+ var render;
+ settings = _.defaults({}, settings, _.templateSettings);
+
+ // Combine delimiters into one regular expression via alternation.
+ var matcher = new RegExp([
+ (settings.escape || noMatch).source,
+ (settings.interpolate || noMatch).source,
+ (settings.evaluate || noMatch).source
+ ].join('|') + '|$', 'g');
+
+ // Compile the template source, escaping string literals appropriately.
+ var index = 0;
+ var source = "__p+='";
+ text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
+ source += text.slice(index, offset)
+ .replace(escaper, function(match) { return '\\' + escapes[match]; });
+
+ if (escape) {
+ source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
+ }
+ if (interpolate) {
+ source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
+ }
+ if (evaluate) {
+ source += "';\n" + evaluate + "\n__p+='";
+ }
+ index = offset + match.length;
+ return match;
+ });
+ source += "';\n";
+
+ // If a variable is not specified, place data values in local scope.
+ if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
+
+ source = "var __t,__p='',__j=Array.prototype.join," +
+ "print=function(){__p+=__j.call(arguments,'');};\n" +
+ source + "return __p;\n";
+
+ try {
+ render = new Function(settings.variable || 'obj', '_', source);
+ } catch (e) {
+ e.source = source;
+ throw e;
+ }
+
+ if (data) return render(data, _);
+ var template = function(data) {
+ return render.call(this, data, _);
+ };
+
+ // Provide the compiled function source as a convenience for precompilation.
+ template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
+
+ return template;
+ };
+
+ return _;
+ })({});
+
+ if (location.hostname === 'todomvc.com') {
+ window._gaq = [['_setAccount','UA-31081062-1'],['_trackPageview']];(function(d,t){var g=d.createElement(t),s=d.getElementsByTagName(t)[0];g.src='//www.google-analytics.com/ga.js';s.parentNode.insertBefore(g,s)}(document,'script'));
+ }
+ /* jshint ignore:end */
+
+ function redirect() {
+ if (location.hostname === 'tastejs.github.io') {
+ location.href = location.href.replace('tastejs.github.io/todomvc', 'todomvc.com');
+ }
+ }
+
+ function findRoot() {
+ var base = location.href.indexOf('examples/');
+ return location.href.substr(0, base);
+ }
+
+ function getFile(file, callback) {
+ if (!location.host) {
+ return console.info('Miss the info bar? Run TodoMVC from a server to avoid a cross-origin error.');
+ }
+
+ var xhr = new XMLHttpRequest();
+
+ xhr.open('GET', findRoot() + file, true);
+ xhr.send();
+
+ xhr.onload = function () {
+ if (xhr.status === 200 && callback) {
+ callback(xhr.responseText);
+ }
+ };
+ }
+
+ function Learn(learnJSON, config) {
+ if (!(this instanceof Learn)) {
+ return new Learn(learnJSON, config);
+ }
+
+ var template, framework;
+
+ if (typeof learnJSON !== 'object') {
+ try {
+ learnJSON = JSON.parse(learnJSON);
+ } catch (e) {
+ return;
+ }
+ }
+
+ if (config) {
+ template = config.template;
+ framework = config.framework;
+ }
+
+ if (!template && learnJSON.templates) {
+ template = learnJSON.templates.todomvc;
+ }
+
+ if (!framework && document.querySelector('[data-framework]')) {
+ framework = document.querySelector('[data-framework]').dataset.framework;
+ }
+
+ this.template = template;
+
+ if (learnJSON.backend) {
+ this.frameworkJSON = learnJSON.backend;
+ this.frameworkJSON.issueLabel = framework;
+ this.append({
+ backend: true
+ });
+ } else if (learnJSON[framework]) {
+ this.frameworkJSON = learnJSON[framework];
+ this.frameworkJSON.issueLabel = framework;
+ this.append();
+ }
+
+ this.fetchIssueCount();
+ }
+
+ Learn.prototype.append = function (opts) {
+ var aside = document.createElement('aside');
+ aside.innerHTML = _.template(this.template, this.frameworkJSON);
+ aside.className = 'learn';
+
+ if (opts && opts.backend) {
+ // Remove demo link
+ var sourceLinks = aside.querySelector('.source-links');
+ var heading = sourceLinks.firstElementChild;
+ var sourceLink = sourceLinks.lastElementChild;
+ // Correct link path
+ var href = sourceLink.getAttribute('href');
+ sourceLink.setAttribute('href', href.substr(href.lastIndexOf('http')));
+ sourceLinks.innerHTML = heading.outerHTML + sourceLink.outerHTML;
+ } else {
+ // Localize demo links
+ var demoLinks = aside.querySelectorAll('.demo-link');
+ Array.prototype.forEach.call(demoLinks, function (demoLink) {
+ if (demoLink.getAttribute('href').substr(0, 4) !== 'http') {
+ demoLink.setAttribute('href', findRoot() + demoLink.getAttribute('href'));
+ }
+ });
+ }
+
+ document.body.className = (document.body.className + ' learn-bar').trim();
+ document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
+ };
+
+ Learn.prototype.fetchIssueCount = function () {
+ var issueLink = document.getElementById('issue-count-link');
+ if (issueLink) {
+ var url = issueLink.href.replace('https://github.com', 'https://api.github.com/repos');
+ var xhr = new XMLHttpRequest();
+ xhr.open('GET', url, true);
+ xhr.onload = function (e) {
+ var parsedResponse = JSON.parse(e.target.responseText);
+ if (parsedResponse instanceof Array) {
+ var count = parsedResponse.length
+ if (count !== 0) {
+ issueLink.innerHTML = 'This app has ' + count + ' open issues';
+ document.getElementById('issue-count').style.display = 'inline';
+ }
+ }
+ };
+ xhr.send();
+ }
+ };
+
+ redirect();
+ getFile('learn.json', Learn);
+})();
diff --git a/examples/cyclejs/node_modules/todomvc-common/package.json b/examples/cyclejs/node_modules/todomvc-common/package.json
new file mode 100644
index 0000000000..7296c94b3c
--- /dev/null
+++ b/examples/cyclejs/node_modules/todomvc-common/package.json
@@ -0,0 +1,90 @@
+{
+ "_args": [
+ [
+ "todomvc-common@1.0.1",
+ "/Users/staltz/oss/cycle/todomvc-cycle"
+ ]
+ ],
+ "_from": "todomvc-common@1.0.1",
+ "_id": "todomvc-common@1.0.1",
+ "_inCache": true,
+ "_installable": true,
+ "_location": "/todomvc-common",
+ "_npmUser": {
+ "email": "sindresorhus@gmail.com",
+ "name": "sindresorhus"
+ },
+ "_npmVersion": "1.4.28",
+ "_phantomChildren": {},
+ "_requested": {
+ "name": "todomvc-common",
+ "raw": "todomvc-common@1.0.1",
+ "rawSpec": "1.0.1",
+ "scope": null,
+ "spec": "1.0.1",
+ "type": "version"
+ },
+ "_requiredBy": [
+ "/"
+ ],
+ "_resolved": "https://registry.npmjs.org/todomvc-common/-/todomvc-common-1.0.1.tgz",
+ "_shasum": "547af687c3152bb57eb2d3f7c527a0ef44e3c831",
+ "_shrinkwrap": null,
+ "_spec": "todomvc-common@1.0.1",
+ "_where": "/Users/staltz/oss/cycle/todomvc-cycle",
+ "author": {
+ "name": "TasteJS"
+ },
+ "bugs": {
+ "url": "https://github.com/tastejs/todomvc-common/issues"
+ },
+ "dependencies": {},
+ "description": "Common TodoMVC utilities used by our apps",
+ "devDependencies": {},
+ "directories": {},
+ "dist": {
+ "shasum": "547af687c3152bb57eb2d3f7c527a0ef44e3c831",
+ "tarball": "https://registry.npmjs.org/todomvc-common/-/todomvc-common-1.0.1.tgz"
+ },
+ "files": [
+ "base.js",
+ "base.css"
+ ],
+ "gitHead": "a5e821ea0bd6974a827834eeae0e5e6e05538abd",
+ "homepage": "https://github.com/tastejs/todomvc-common",
+ "keywords": [
+ "todomvc",
+ "tastejs",
+ "util",
+ "utilities"
+ ],
+ "license": "MIT",
+ "main": "base.js",
+ "maintainers": [
+ {
+ "email": "sindresorhus@gmail.com",
+ "name": "sindresorhus"
+ },
+ {
+ "email": "addyosmani@gmail.com",
+ "name": "addyosmani"
+ },
+ {
+ "email": "phartig@rdrei.net",
+ "name": "passy"
+ },
+ {
+ "email": "sawchuk@gmail.com",
+ "name": "stephenplusplus"
+ }
+ ],
+ "name": "todomvc-common",
+ "optionalDependencies": {},
+ "readme": "ERROR: No README data found!",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/tastejs/todomvc-common.git"
+ },
+ "scripts": {},
+ "version": "1.0.1"
+}
diff --git a/examples/cyclejs/node_modules/todomvc-common/readme.md b/examples/cyclejs/node_modules/todomvc-common/readme.md
new file mode 100644
index 0000000000..7a5de5118f
--- /dev/null
+++ b/examples/cyclejs/node_modules/todomvc-common/readme.md
@@ -0,0 +1,15 @@
+# todomvc-common
+
+> Common TodoMVC utilities used by our apps
+
+
+## Install
+
+```
+$ npm install --save todomvc-common
+```
+
+
+## License
+
+MIT © [TasteJS](http://tastejs.com)
diff --git a/examples/cyclejs/package.json b/examples/cyclejs/package.json
new file mode 100644
index 0000000000..78d9cdec0f
--- /dev/null
+++ b/examples/cyclejs/package.json
@@ -0,0 +1,52 @@
+{
+ "name": "todomvc-cycle",
+ "version": "0.0.0",
+ "author": "Andre Staltz",
+ "repository": {
+ "type": "git",
+ "url": "git@github.com:staltz/todomvc-cycle.git"
+ },
+ "license": "MIT",
+ "private": true,
+ "contributors": [
+ {
+ "name": "Frederik Krautwald"
+ },
+ {
+ "name": "Kahlil Lechelt",
+ "email": "hello@kahlil.info"
+ }
+ ],
+ "dependencies": {
+ "@cycle/collection": "^0.3.0",
+ "@cycle/dom": "10.0.0-rc33",
+ "@cycle/history": "^4.0.0",
+ "@cycle/isolate": "1.4.x",
+ "@cycle/storage": "3.0.0-rc2",
+ "@cycle/xstream-run": "3.0.0",
+ "history": "^3.0.0",
+ "todomvc-app-css": "2.0.3",
+ "todomvc-common": "1.0.1",
+ "xstream": "^5.0.5"
+ },
+ "devDependencies": {
+ "babel-plugin-transform-object-rest-spread": "^6.6.5",
+ "babel-preset-es2015": "^6.3.13",
+ "babel-register": "^6.4.3",
+ "babelify": "^7.2.0",
+ "browserify": "12.0.1",
+ "live-server": "^0.9.0",
+ "mkdirp": "^0.5.1",
+ "npm-run-all": "^1.4.0",
+ "uglify-js": "2.6.1",
+ "watchify": "^3.6.1"
+ },
+ "scripts": {
+ "build-debug": "mkdirp js && browserify src/app.js -t babelify --outfile js/app.js",
+ "watch:js": "mkdirp js && watchify src/app.js -t babelify --outfile js/app.js -dv",
+ "serve": "live-server ./",
+ "uglify": "uglifyjs js/app.js -o js/app.min.js",
+ "build": "npm run build-debug && npm run uglify",
+ "start": "npm-run-all --parallel watch:js serve"
+ }
+}
diff --git a/examples/cyclejs/src/app.js b/examples/cyclejs/src/app.js
new file mode 100644
index 0000000000..e725549619
--- /dev/null
+++ b/examples/cyclejs/src/app.js
@@ -0,0 +1,28 @@
+import {run} from '@cycle/xstream-run';
+import {makeDOMDriver} from '@cycle/dom';
+import {makeHistoryDriver} from '@cycle/history'
+import {createHistory} from 'history';
+import storageDriver from '@cycle/storage';
+// THE MAIN FUNCTION
+// This is the todo list component.
+import TaskList from './components/TaskList/index';
+
+const main = TaskList;
+
+// THE ENTRY POINT
+// This is where the whole story starts.
+// `run` receives a main function and an object
+// with the drivers.
+run(main, {
+ // THE DOM DRIVER
+ // `makeDOMDriver(container)` from Cycle DOM returns a
+ // driver function to interact with the DOM.
+ DOM: makeDOMDriver('.todoapp', {transposition: true}),
+ // THE HISTORY DRIVER
+ // A driver to interact with browser history
+ History: makeHistoryDriver(createHistory(), {capture: true}),
+ // THE STORAGE DRIVER
+ // The storage driver which can be used to access values for
+ // local- and sessionStorage keys as streams.
+ storage: storageDriver
+});
diff --git a/examples/cyclejs/src/components/Task/index.js b/examples/cyclejs/src/components/Task/index.js
new file mode 100644
index 0000000000..64613a8a20
--- /dev/null
+++ b/examples/cyclejs/src/components/Task/index.js
@@ -0,0 +1,20 @@
+import intent from './intent';
+import model from './model';
+import view from './view';
+
+// THE TODO ITEM FUNCTION
+// This is a simple todo item component,
+// structured with the MVI-pattern.
+function Task(sources) {
+ let action$ = intent(sources);
+ let state$ = model(sources.props$, action$);
+ let vtree$ = view(state$);
+
+ return {
+ DOM: vtree$,
+ action$,
+ state$
+ };
+}
+
+export default Task;
diff --git a/examples/cyclejs/src/components/Task/intent.js b/examples/cyclejs/src/components/Task/intent.js
new file mode 100644
index 0000000000..30c662a1a5
--- /dev/null
+++ b/examples/cyclejs/src/components/Task/intent.js
@@ -0,0 +1,40 @@
+import xs from 'xstream';
+import {ENTER_KEY, ESC_KEY} from '../../utils';
+
+// THE TODO ITEM INTENT
+// This intent function returns a stream of all the different,
+// actions that can be taken on a todo.
+function intent(sources) {
+ // THE INTENT MERGE
+ // Merge all actions into one stream.
+ return xs.merge(
+ // THE DESTROY ACTION STREAM
+ sources.DOM.select('.destroy').events('click')
+ .mapTo({type: 'destroy'}),
+
+ // THE TOGGLE ACTION STREAM
+ sources.DOM.select('.toggle').events('change')
+ .map(ev => ev.target.checked)
+ .map(payload => ({type: 'toggle', payload})),
+ sources.action$
+ .filter(action => action.type === 'toggleAll')
+ .map(action => ({...action, type: 'toggle'})),
+
+ // THE START EDIT ACTION STREAM
+ sources.DOM.select('label').events('dblclick')
+ .mapTo({type: 'startEdit'}),
+
+ // THE ESC KEY ACTION STREAM
+ sources.DOM.select('.edit').events('keyup')
+ .filter(ev => ev.keyCode === ESC_KEY)
+ .mapTo({type: 'cancelEdit'}),
+
+ // THE ENTER KEY ACTION STREAM
+ sources.DOM.select('.edit').events('keyup')
+ .filter(ev => ev.keyCode === ENTER_KEY)
+ .compose(s => xs.merge(s, sources.DOM.select('.edit').events('blur', true)))
+ .map(ev => ({title: ev.target.value, type: 'doneEdit'}))
+ );
+}
+
+export default intent;
diff --git a/examples/cyclejs/src/components/Task/model.js b/examples/cyclejs/src/components/Task/model.js
new file mode 100644
index 0000000000..474f16141e
--- /dev/null
+++ b/examples/cyclejs/src/components/Task/model.js
@@ -0,0 +1,60 @@
+import xs from 'xstream';
+
+function makeReducer$(action$) {
+ let startEditReducer$ = action$
+ .filter(action => action.type === 'startEdit')
+ .mapTo(function startEditReducer(data) {
+ return {
+ ...data,
+ editing: true
+ };
+ });
+
+ let doneEditReducer$ = action$
+ .filter(action => action.type === 'doneEdit')
+ .map(action => function doneEditReducer(data) {
+ return {
+ ...data,
+ title: action.payload,
+ editing: false
+ };
+ });
+
+ let cancelEditReducer$ = action$
+ .filter(action => action.type === 'cancelEdit')
+ .mapTo(function cancelEditReducer(data) {
+ return {
+ ...data,
+ editing: false
+ };
+ });
+
+ let toggleReducer$ = action$
+ .filter(action => action.type === 'toggle')
+ .map(action => function toggleReducer(data) {
+ return {
+ ...data,
+ completed: action.payload
+ };
+ });
+
+ return xs.merge(
+ startEditReducer$,
+ doneEditReducer$,
+ cancelEditReducer$,
+ toggleReducer$
+ );
+}
+
+function model(props$, action$) {
+ // THE SANITIZED PROPERTIES
+ // If the list item has no data set it as empty and not completed.
+ let sanitizedProps$ = props$.startWith({title: '', completed: false});
+ let reducer$ = makeReducer$(action$);
+
+ return sanitizedProps$.map(props =>
+ reducer$.fold((data, reducer) => reducer(data), props)
+ ).flatten().remember();
+}
+
+export default model;
diff --git a/examples/cyclejs/src/components/Task/view.js b/examples/cyclejs/src/components/Task/view.js
new file mode 100644
index 0000000000..3f60c5450e
--- /dev/null
+++ b/examples/cyclejs/src/components/Task/view.js
@@ -0,0 +1,34 @@
+import {button, div, input, label, li} from '@cycle/dom';
+
+function view(state$) {
+ return state$.map(({title, completed, editing}) => {
+ let todoRootClasses = {
+ completed,
+ editing,
+ };
+
+ return li('.todoRoot', {class: todoRootClasses}, [
+ div('.view', [
+ input('.toggle', {
+ props: {type: 'checkbox', checked: completed},
+ }),
+ label(title),
+ button('.destroy')
+ ]),
+ input('.edit', {
+ props: {type: 'text'},
+ hook: {
+ update: (oldVNode, {elm}) => {
+ elm.value = title;
+ if (editing) {
+ elm.focus();
+ elm.selectionStart = elm.value.length;
+ }
+ }
+ }
+ })
+ ]);
+ });
+}
+
+export default view;
diff --git a/examples/cyclejs/src/components/TaskList/index.js b/examples/cyclejs/src/components/TaskList/index.js
new file mode 100644
index 0000000000..c261c32f70
--- /dev/null
+++ b/examples/cyclejs/src/components/TaskList/index.js
@@ -0,0 +1,106 @@
+import xs from 'xstream';
+import isolate from '@cycle/isolate'
+import intent from './intent';
+import model from './model';
+import view from './view';
+import deserialize from './storage-source';
+import serialize from './storage-sink';
+import Task from '../Task/index';
+import Collection from '@cycle/collection';
+
+// THE TASKLIST COMPONENT
+// This is the TaskList component which is being exported below.
+function TaskList(sources) {
+ // THE LOCALSTORAGE STREAM
+ // Here we create a localStorage stream that only streams
+ // the first value read from localStorage in order to
+ // supply the application with initial state.
+ let localStorage$ = sources.storage.local.getItem('todos-cycle').take(1);
+ // THE INITIAL TODO DATA
+ // The `deserialize` function takes the serialized JSON stored in localStorage
+ // and turns it into a stream sending a JSON object.
+ let sourceTodosData$ = deserialize(localStorage$);
+ // THE INTENT (MVI PATTERN)
+ // Pass relevant sources to the intent function, which set up
+ // streams that model the users actions.
+ let action$ = intent(sources.DOM, sources.History);
+ // THE MODEL (MVI PATTERN)
+ // Actions get passed to the model function which transforms the data
+ // coming through and prepares the data for the view.
+ let state$ = model(action$, sourceTodosData$);
+ // THE ITEM ADDITION STREAM
+ // Emits objects of sources specific to each item.
+ // Merges stored items with new items
+ let add$ = xs.merge(
+ sourceTodosData$
+ .map(data => data.list.map(props => ({props$: xs.of(props)}))),
+ action$
+ .filter(action => action.type === 'insertTodo')
+ .map(action => ({
+ props$: xs.of({
+ title: action.payload,
+ completed: false
+ })
+ }))
+ );
+ // THE ITEM REMOVAL SELECTOR FUNCTION
+ // This function takes item's sinks and returns a stream representing
+ // its removal. Merges internal removals and `deleteCompleteds` actions
+ function removeSelector(itemSinks) {
+ let deleteCompleteds$ = action$
+ .filter(action => action.type === 'deleteCompleteds');
+ return xs.merge(
+ // Consider deleteCompleteds$ only if the task is completed.
+ // analogue of rx pausable
+ itemSinks.state$
+ .map(state => deleteCompleteds$.filter(() => state.completed))
+ .flatten(),
+ itemSinks.action$
+ .filter(action => action.type === 'destroy')
+ );
+ }
+ // THE COLLECTION STREAM
+ // Collection function takes a component function, a common sources object,
+ // a stream of item additions, and a selector function from item sinks to
+ // a stream of removals
+ let list$ = Collection(
+ Task,
+ {
+ DOM: sources.DOM,
+ action$: action$
+ .filter(action => action.type === 'toggleAll')
+ },
+ add$,
+ removeSelector
+ );
+ // THE COMBINED CHILDREN VTREE AND STATE STREAMS
+ let todoVtrees$ = Collection.pluck(list$, itemSinks => itemSinks.DOM);
+ let todoStates$ = Collection.pluck(list$, itemSinks => itemSinks.state$);
+
+ let amendedState$ = xs.combine(state$, todoVtrees$, todoStates$)
+ .map(([parentState, todoVtrees, todoStates]) => ({
+ ...parentState,
+ list: todoStates.map((state, i) => ({
+ ...state,
+ todoItem: {DOM: todoVtrees[i]}
+ }))
+ }));
+ // THE VIEW (MVI PATTERN)
+ // We render state as markup for the DOM.
+ let vdom$ = view(amendedState$);
+ // WRITE TO LOCALSTORAGE
+ // The latest state is written to localStorage.
+ let storage$ = serialize(todoStates$).map((state) => ({
+ key: 'todos-cycle', value: state
+ }));
+ // COMPLETE THE CYCLE
+ // Write the virtual dom stream to the DOM and write the
+ // storage stream to localStorage.
+ let sinks = {
+ DOM: vdom$,
+ storage: storage$,
+ };
+ return sinks;
+}
+
+export default TaskList;
diff --git a/examples/cyclejs/src/components/TaskList/intent.js b/examples/cyclejs/src/components/TaskList/intent.js
new file mode 100644
index 0000000000..6a65c70fa9
--- /dev/null
+++ b/examples/cyclejs/src/components/TaskList/intent.js
@@ -0,0 +1,52 @@
+import xs from 'xstream';
+import dropRepeats from 'xstream/extra/dropRepeats';
+import {ENTER_KEY, ESC_KEY} from '../../utils';
+
+// THE INTENT FOR THE LIST
+export default function intent(DOMSource, History) {
+ return xs.merge(
+ // THE ROUTE STREAM
+ // A stream that provides the path whenever the route changes.
+ History
+ .startWith({pathname: '/'})
+ .map(location => location.pathname)
+ .compose(dropRepeats())
+ .map(payload => ({type: 'changeRoute', payload})),
+
+ // THE URL STREAM
+ // A stream of URL clicks in the app
+ DOMSource.select('a').events('click')
+ .map(event => event.target.hash.replace('#', ''))
+ .map(payload => ({type: 'url', payload})),
+
+ // CLEAR INPUT STREAM
+ // A stream of ESC key strokes in the `.new-todo` field.
+ DOMSource.select('.new-todo').events('keydown')
+ .filter(ev => ev.keyCode === ESC_KEY)
+ .map(payload => ({type: 'clearInput', payload})),
+
+ // ENTER KEY STREAM
+ // A stream of ENTER key strokes in the `.new-todo` field.
+ DOMSource.select('.new-todo').events('keydown')
+ // Trim value and only let the data through when there
+ // is anything but whitespace in the field and the ENTER key was hit.
+ .filter(ev => {
+ let trimmedVal = String(ev.target.value).trim();
+ return ev.keyCode === ENTER_KEY && trimmedVal;
+ })
+ // Return the trimmed value.
+ .map(ev => String(ev.target.value).trim())
+ .map(payload => ({type: 'insertTodo', payload})),
+
+ // TOGGLE ALL STREAM
+ // Create a stream out of the clicks on the `.toggle-all` button.
+ DOMSource.select('.toggle-all').events('click')
+ .map(ev => ev.target.checked)
+ .map(payload => ({type: 'toggleAll', payload})),
+
+ // DELETE COMPLETED TODOS STREAM
+ // A stream of click events on the `.clear-completed` element.
+ DOMSource.select('.clear-completed').events('click')
+ .mapTo({type: 'deleteCompleteds'})
+ );
+};
diff --git a/examples/cyclejs/src/components/TaskList/model.js b/examples/cyclejs/src/components/TaskList/model.js
new file mode 100644
index 0000000000..1df793bba9
--- /dev/null
+++ b/examples/cyclejs/src/components/TaskList/model.js
@@ -0,0 +1,62 @@
+import xs from 'xstream';
+import concat from 'xstream/extra/concat';
+
+// A helper function that provides filter functions
+// depending on the route value.
+function getFilterFn(route) {
+ switch (route) {
+ case '/active': return (task => task.completed === false);
+ case '/completed': return (task => task.completed === true);
+ default: return () => true; // allow anything
+ }
+}
+
+// MAKE REDUCER STREAM
+// A function that takes the actions on the todo list
+// and returns a stream of "reducers": functions that expect the current
+// todosData (the state) and return a new version of todosData.
+function makeReducer$(action$) {
+ let clearInputReducer$ = action$
+ .filter(a => a.type === 'clearInput')
+ .mapTo(function clearInputReducer(todosData) {
+ return todosData;
+ });
+
+ let changeRouteReducer$ = action$
+ .filter(a => a.type === 'changeRoute')
+ .map(a => a.payload)
+ .startWith('/')
+ .map(path => {
+ let filterFn = getFilterFn(path);
+ return function changeRouteReducer(todosData) {
+ todosData.filter = path.replace('/', '').trim();
+ todosData.filterFn = filterFn;
+ return todosData;
+ };
+ });
+
+ return xs.merge(
+ clearInputReducer$,
+ changeRouteReducer$
+ );
+}
+
+// THIS IS THE MODEL FUNCTION
+// It expects the actions coming in from the sources
+function model(action$, sourceTodosData$) {
+ // THE BUSINESS LOGIC
+ // Actions are passed to the `makeReducer$` function
+ // which creates a stream of reducer functions that needs
+ // to be applied on the todoData when an action happens.
+ let reducer$ = makeReducer$(action$);
+
+ // RETURN THE MODEL DATA
+ return sourceTodosData$.map(sourceTodosData =>
+ reducer$.fold((todosData, reducer) => reducer(todosData), sourceTodosData)
+ ).flatten()
+ // Make this remember its latest event, so late listeners
+ // will be updated with the latest state.
+ .remember();
+}
+
+export default model;
diff --git a/examples/cyclejs/src/components/TaskList/storage-sink.js b/examples/cyclejs/src/components/TaskList/storage-sink.js
new file mode 100644
index 0000000000..eaa75c64e2
--- /dev/null
+++ b/examples/cyclejs/src/components/TaskList/storage-sink.js
@@ -0,0 +1,14 @@
+// Turn the data object that contains
+// the todos into a string for localStorage.
+export default function serialize(todos$) {
+ return todos$.map(todosData => JSON.stringify(
+ {
+ list: todosData.map(todoData =>
+ ({
+ title: todoData.title,
+ completed: todoData.completed
+ })
+ )
+ }
+ ));
+};
diff --git a/examples/cyclejs/src/components/TaskList/storage-source.js b/examples/cyclejs/src/components/TaskList/storage-source.js
new file mode 100644
index 0000000000..6743553642
--- /dev/null
+++ b/examples/cyclejs/src/components/TaskList/storage-source.js
@@ -0,0 +1,30 @@
+function merge() {
+ let result = {};
+ for (let i = 0; i < arguments.length; i++) {
+ let object = arguments[i];
+ for (let key in object) {
+ if (object.hasOwnProperty(key)) {
+ result[key] = object[key];
+ }
+ }
+ }
+ return result;
+}
+
+let safeJSONParse = str => JSON.parse(str) || {};
+
+let mergeWithDefaultTodosData = todosData => {
+ return merge({
+ list: [],
+ filter: '',
+ filterFn: () => true, // allow anything
+ }, todosData);
+}
+
+// Take localStorage todoData stream and transform into
+// a JavaScript object. Set default data.
+export default function deserialize(localStorageValue$) {
+ return localStorageValue$
+ .map(safeJSONParse)
+ .map(mergeWithDefaultTodosData);
+};
diff --git a/examples/cyclejs/src/components/TaskList/view.js b/examples/cyclejs/src/components/TaskList/view.js
new file mode 100644
index 0000000000..a359e95c82
--- /dev/null
+++ b/examples/cyclejs/src/components/TaskList/view.js
@@ -0,0 +1,84 @@
+import {a, button, div, footer, h1, header, input, li,
+ section, span, strong, ul} from '@cycle/dom';
+
+function renderHeader() {
+ return header('.header', [
+ h1('todos'),
+ input('.new-todo', {
+ props: {
+ type: 'text',
+ placeholder: 'What needs to be done?',
+ autofocus: true,
+ name: 'newTodo'
+ },
+ hook: {
+ update: (oldVNode, {elm}) => {
+ elm.value = '';
+ },
+ },
+ })
+ ]);
+}
+
+function renderMainSection(todosData) {
+ let allCompleted = todosData.list.reduce((x, y) => x && y.completed, true);
+ let sectionStyle = {'display': todosData.list.length ? '' : 'none'};
+
+ return section('.main', {style: sectionStyle}, [
+ input('.toggle-all', {
+ props: {type: 'checkbox', checked: allCompleted},
+ }),
+ ul('.todo-list', todosData.list
+ .filter(todosData.filterFn)
+ .map(data => data.todoItem.DOM)
+ )
+ ]);
+}
+
+function renderFilterButton(todosData, filterTag, path, label) {
+ return li([
+ a({
+ props: {href: path},
+ class: {selected: todosData.filter === filterTag}
+ }, label)
+ ]);
+}
+
+function renderFooter(todosData) {
+ let amountCompleted = todosData.list
+ .filter(todoData => todoData.completed)
+ .length;
+ let amountActive = todosData.list.length - amountCompleted;
+ let footerStyle = {'display': todosData.list.length ? '' : 'none'};
+
+ return footer('.footer', {style: footerStyle}, [
+ span('.todo-count', [
+ strong(String(amountActive)),
+ ' item' + (amountActive !== 1 ? 's' : '') + ' left'
+ ]),
+ ul('.filters', [
+ renderFilterButton(todosData, '', '/', 'All'),
+ renderFilterButton(todosData, 'active', '/active', 'Active'),
+ renderFilterButton(todosData, 'completed', '/completed', 'Completed'),
+ ]),
+ (amountCompleted > 0 ?
+ button('.clear-completed', 'Clear completed (' + amountCompleted + ')')
+ : null
+ )
+ ])
+}
+
+// THE VIEW
+// This function expects the stream of todosData
+// from the model function and turns it into a
+// virtual DOM stream that is then ultimately returned into
+// the DOM sink in the index.js.
+export default function view(todos$) {
+ return todos$.map(todos =>
+ div([
+ renderHeader(),
+ renderMainSection(todos),
+ renderFooter(todos)
+ ])
+ );
+};
diff --git a/examples/cyclejs/src/utils.js b/examples/cyclejs/src/utils.js
new file mode 100644
index 0000000000..68033e65ed
--- /dev/null
+++ b/examples/cyclejs/src/utils.js
@@ -0,0 +1,4 @@
+const ENTER_KEY = 13;
+const ESC_KEY = 27;
+
+export {ENTER_KEY, ESC_KEY};
diff --git a/examples/effector/.editorconfig b/examples/effector/.editorconfig
new file mode 100644
index 0000000000..86c8f59f7d
--- /dev/null
+++ b/examples/effector/.editorconfig
@@ -0,0 +1,15 @@
+root = true
+
+[*]
+indent_style = tab
+end_of_line = lf
+charset = utf-8
+trim_trailing_whitespace = true
+insert_final_newline = true
+
+[package.json]
+indent_style = space
+indent_size = 2
+
+[*.md]
+trim_trailing_whitespace = false
diff --git a/examples/effector/.gitattributes b/examples/effector/.gitattributes
new file mode 100644
index 0000000000..176a458f94
--- /dev/null
+++ b/examples/effector/.gitattributes
@@ -0,0 +1 @@
+* text=auto
diff --git a/examples/effector/.gitignore b/examples/effector/.gitignore
new file mode 100644
index 0000000000..3c3629e647
--- /dev/null
+++ b/examples/effector/.gitignore
@@ -0,0 +1 @@
+node_modules
diff --git a/examples/effector/dist/index.092052ec.css b/examples/effector/dist/index.092052ec.css
new file mode 100644
index 0000000000..78672a14b2
--- /dev/null
+++ b/examples/effector/dist/index.092052ec.css
@@ -0,0 +1,394 @@
+html,
+body {
+ margin: 0;
+ padding: 0;
+}
+
+button {
+ margin: 0;
+ padding: 0;
+ border: 0;
+ background: none;
+ font-size: 100%;
+ vertical-align: baseline;
+ font-family: inherit;
+ font-weight: inherit;
+ color: inherit;
+ -webkit-appearance: none;
+ appearance: none;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+body {
+ font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
+ line-height: 1.4em;
+ background: #f5f5f5;
+ color: #111111;
+ min-width: 230px;
+ max-width: 550px;
+ margin: 0 auto;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+ font-weight: 300;
+}
+
+.hidden {
+ display: none;
+}
+
+.todoapp {
+ background: #fff;
+ margin: 130px 0 40px 0;
+ position: relative;
+ box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
+ 0 25px 50px 0 rgba(0, 0, 0, 0.1);
+}
+
+.todoapp input::-webkit-input-placeholder {
+ font-style: italic;
+ font-weight: 400;
+ color: rgba(0, 0, 0, 0.4);
+}
+
+.todoapp input::-moz-placeholder {
+ font-style: italic;
+ font-weight: 400;
+ color: rgba(0, 0, 0, 0.4);
+}
+
+.todoapp input::input-placeholder {
+ font-style: italic;
+ font-weight: 400;
+ color: rgba(0, 0, 0, 0.4);
+}
+
+.todoapp h1 {
+ position: absolute;
+ top: -140px;
+ width: 100%;
+ font-size: 80px;
+ font-weight: 200;
+ text-align: center;
+ color: #b83f45;
+ -webkit-text-rendering: optimizeLegibility;
+ -moz-text-rendering: optimizeLegibility;
+ text-rendering: optimizeLegibility;
+}
+
+.new-todo,
+.edit {
+ position: relative;
+ margin: 0;
+ width: 100%;
+ font-size: 24px;
+ font-family: inherit;
+ font-weight: inherit;
+ line-height: 1.4em;
+ color: inherit;
+ padding: 6px;
+ border: 1px solid #999;
+ box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
+ box-sizing: border-box;
+ -webkit-font-smoothing: antialiased;
+ -moz-osx-font-smoothing: grayscale;
+}
+
+.new-todo {
+ padding: 16px 16px 16px 60px;
+ height: 65px;
+ border: none;
+ background: rgba(0, 0, 0, 0.003);
+ box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
+}
+
+.main {
+ position: relative;
+ z-index: 2;
+ border-top: 1px solid #e6e6e6;
+}
+
+.toggle-all {
+ width: 1px;
+ height: 1px;
+ border: none; /* Mobile Safari */
+ opacity: 0;
+ position: absolute;
+ right: 100%;
+ bottom: 100%;
+}
+
+.toggle-all + label {
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 45px;
+ height: 65px;
+ font-size: 0;
+ position: absolute;
+ top: -65px;
+ left: -0;
+}
+
+.toggle-all + label:before {
+ content: '❯';
+ display: inline-block;
+ font-size: 22px;
+ color: #949494;
+ padding: 10px 27px 10px 27px;
+ -webkit-transform: rotate(90deg);
+ transform: rotate(90deg);
+}
+
+.toggle-all:checked + label:before {
+ color: #484848;
+}
+
+.todo-list {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+}
+
+.todo-list li {
+ position: relative;
+ font-size: 24px;
+ border-bottom: 1px solid #ededed;
+}
+
+.todo-list li:last-child {
+ border-bottom: none;
+}
+
+.todo-list li.editing {
+ border-bottom: none;
+ padding: 0;
+}
+
+.todo-list li.editing .edit {
+ display: block;
+ width: calc(100% - 43px);
+ padding: 12px 16px;
+ margin: 0 0 0 43px;
+}
+
+.todo-list li.editing .view {
+ display: none;
+}
+
+.todo-list li .toggle {
+ text-align: center;
+ width: 40px;
+ /* auto, since non-WebKit browsers doesn't support input styling */
+ height: auto;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ margin: auto 0;
+ border: none; /* Mobile Safari */
+ -webkit-appearance: none;
+ appearance: none;
+}
+
+.todo-list li .toggle {
+ opacity: 0;
+}
+
+.todo-list li .toggle + label {
+ /*
+ Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433
+ IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/
+ */
+ background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23949494%22%20stroke-width%3D%223%22/%3E%3C/svg%3E');
+ background-repeat: no-repeat;
+ background-position: center left;
+}
+
+.todo-list li .toggle:checked + label {
+ background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%2359A193%22%20stroke-width%3D%223%22%2F%3E%3Cpath%20fill%3D%22%233EA390%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22%2F%3E%3C%2Fsvg%3E');
+}
+
+.todo-list li label {
+ word-break: break-all;
+ padding: 15px 15px 15px 60px;
+ display: block;
+ line-height: 1.2;
+ transition: color 0.4s;
+ font-weight: 400;
+ color: #484848;
+}
+
+.todo-list li.completed label {
+ color: #949494;
+ text-decoration: line-through;
+}
+
+.todo-list li .destroy {
+ display: none;
+ position: absolute;
+ top: 0;
+ right: 10px;
+ bottom: 0;
+ width: 40px;
+ height: 40px;
+ margin: auto 0;
+ font-size: 30px;
+ color: #949494;
+ transition: color 0.2s ease-out;
+}
+
+.todo-list li .destroy:hover,
+.todo-list li .destroy:focus {
+ color: #C18585;
+}
+
+.todo-list li .destroy:after {
+ content: '×';
+ display: block;
+ height: 100%;
+ line-height: 1.1;
+}
+
+.todo-list li:hover .destroy {
+ display: block;
+}
+
+.todo-list li .edit {
+ display: none;
+}
+
+.todo-list li.editing:last-child {
+ margin-bottom: -1px;
+}
+
+.footer {
+ padding: 10px 15px;
+ height: 20px;
+ text-align: center;
+ font-size: 15px;
+ border-top: 1px solid #e6e6e6;
+}
+
+.footer:before {
+ content: '';
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ height: 50px;
+ overflow: hidden;
+ box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
+ 0 8px 0 -3px #f6f6f6,
+ 0 9px 1px -3px rgba(0, 0, 0, 0.2),
+ 0 16px 0 -6px #f6f6f6,
+ 0 17px 2px -6px rgba(0, 0, 0, 0.2);
+}
+
+.todo-count {
+ float: left;
+ text-align: left;
+}
+
+.todo-count strong {
+ font-weight: 300;
+}
+
+.filters {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+ position: absolute;
+ right: 0;
+ left: 0;
+}
+
+.filters li {
+ display: inline;
+}
+
+.filters li a {
+ color: inherit;
+ margin: 3px;
+ padding: 3px 7px;
+ text-decoration: none;
+ border: 1px solid transparent;
+ border-radius: 3px;
+}
+
+.filters li a:hover {
+ border-color: #DB7676;
+}
+
+.filters li a.selected {
+ border-color: #CE4646;
+}
+
+.clear-completed,
+html .clear-completed:active {
+ float: right;
+ position: relative;
+ line-height: 19px;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.clear-completed:hover {
+ text-decoration: underline;
+}
+
+.info {
+ margin: 65px auto 0;
+ color: #4d4d4d;
+ font-size: 11px;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+ text-align: center;
+}
+
+.info p {
+ line-height: 1;
+}
+
+.info a {
+ color: inherit;
+ text-decoration: none;
+ font-weight: 400;
+}
+
+.info a:hover {
+ text-decoration: underline;
+}
+
+/*
+ Hack to remove background from Mobile Safari.
+ Can't use it globally since it destroys checkboxes in Firefox
+*/
+
+@media screen and (-webkit-min-device-pixel-ratio:0) {
+ .toggle-all,
+ .todo-list li .toggle {
+ background: none;
+ }
+
+ .todo-list li .toggle {
+ height: 40px;
+ }
+}
+
+@media (max-width: 430px) {
+ .footer {
+ height: 50px;
+ }
+
+ .filters {
+ bottom: 10px;
+ }
+}
+
+:focus,
+.toggle:focus + label,
+.toggle-all:focus + label {
+ box-shadow: 0 0 2px 2px #CF7D7D;
+ outline: 0;
+}
+
+/*# sourceMappingURL=index.092052ec.css.map */
diff --git a/examples/effector/dist/index.092052ec.css.map b/examples/effector/dist/index.092052ec.css.map
new file mode 100644
index 0000000000..17ea08f6b1
--- /dev/null
+++ b/examples/effector/dist/index.092052ec.css.map
@@ -0,0 +1 @@
+{"mappings":"AAAA;;CAEC,SAAS;CACT,UAAU;AACX;;AAEA;CACC,SAAS;CACT,UAAU;CACV,SAAS;CACT,gBAAgB;CAChB,eAAe;CACf,wBAAwB;CACxB,oBAAoB;CACpB,oBAAoB;CACpB,cAAc;CACd,wBAAwB;CACxB,gBAAgB;CAChB,mCAAmC;CACnC,kCAAkC;AACnC;;AAEA;CACC,yDAAyD;CACzD,kBAAkB;CAClB,mBAAmB;CACnB,cAAc;CACd,gBAAgB;CAChB,gBAAgB;CAChB,cAAc;CACd,mCAAmC;CACnC,kCAAkC;CAClC,gBAAgB;AACjB;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,gBAAgB;CAChB,sBAAsB;CACtB,kBAAkB;CAClB;6CAC4C;AAC7C;;AAEA;CACC,kBAAkB;CAClB,gBAAgB;CAChB,yBAAyB;AAC1B;;AAEA;CACC,kBAAkB;CAClB,gBAAgB;CAChB,yBAAyB;AAC1B;;AAEA;CACC,kBAAkB;CAClB,gBAAgB;CAChB,yBAAyB;AAC1B;;AAEA;CACC,kBAAkB;CAClB,WAAW;CACX,WAAW;CACX,eAAe;CACf,gBAAgB;CAChB,kBAAkB;CAClB,cAAc;CACd,0CAA0C;CAC1C,uCAAuC;CACvC,kCAAkC;AACnC;;AAEA;;CAEC,kBAAkB;CAClB,SAAS;CACT,WAAW;CACX,eAAe;CACf,oBAAoB;CACpB,oBAAoB;CACpB,kBAAkB;CAClB,cAAc;CACd,YAAY;CACZ,sBAAsB;CACtB,iDAAiD;CACjD,sBAAsB;CACtB,mCAAmC;CACnC,kCAAkC;AACnC;;AAEA;CACC,4BAA4B;CAC5B,YAAY;CACZ,YAAY;CACZ,gCAAgC;CAChC,6CAA6C;AAC9C;;AAEA;CACC,kBAAkB;CAClB,UAAU;CACV,6BAA6B;AAC9B;;AAEA;CACC,UAAU;CACV,WAAW;CACX,YAAY,EAAE,kBAAkB;CAChC,UAAU;CACV,kBAAkB;CAClB,WAAW;CACX,YAAY;AACb;;AAEA;CACC,aAAa;CACb,mBAAmB;CACnB,uBAAuB;CACvB,WAAW;CACX,YAAY;CACZ,YAAY;CACZ,kBAAkB;CAClB,UAAU;CACV,QAAQ;AACT;;AAEA;CACC,YAAY;CACZ,qBAAqB;CACrB,eAAe;CACf,cAAc;CACd,4BAA4B;CAC5B,gCAAgC;CAChC,wBAAwB;AACzB;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,SAAS;CACT,UAAU;CACV,gBAAgB;AACjB;;AAEA;CACC,kBAAkB;CAClB,eAAe;CACf,gCAAgC;AACjC;;AAEA;CACC,mBAAmB;AACpB;;AAEA;CACC,mBAAmB;CACnB,UAAU;AACX;;AAEA;CACC,cAAc;CACd,wBAAwB;CACxB,kBAAkB;CAClB,kBAAkB;AACnB;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,kBAAkB;CAClB,WAAW;CACX,kEAAkE;CAClE,YAAY;CACZ,kBAAkB;CAClB,MAAM;CACN,SAAS;CACT,cAAc;CACd,YAAY,EAAE,kBAAkB;CAChC,wBAAwB;CACxB,gBAAgB;AACjB;;AAEA;CACC,UAAU;AACX;;AAEA;CACC;;;EAGC;CACD,yCAAoU;CACpU,4BAA4B;CAC5B,gCAAgC;AACjC;;AAEA;CACC,yCAAub;AACxb;;AAEA;CACC,qBAAqB;CACrB,4BAA4B;CAC5B,cAAc;CACd,gBAAgB;CAChB,sBAAsB;CACtB,gBAAgB;CAChB,cAAc;AACf;;AAEA;CACC,cAAc;CACd,6BAA6B;AAC9B;;AAEA;CACC,aAAa;CACb,kBAAkB;CAClB,MAAM;CACN,WAAW;CACX,SAAS;CACT,WAAW;CACX,YAAY;CACZ,cAAc;CACd,eAAe;CACf,cAAc;CACd,+BAA+B;AAChC;;AAEA;;CAEC,cAAc;AACf;;AAEA;CACC,YAAY;CACZ,cAAc;CACd,YAAY;CACZ,gBAAgB;AACjB;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,aAAa;AACd;;AAEA;CACC,mBAAmB;AACpB;;AAEA;CACC,kBAAkB;CAClB,YAAY;CACZ,kBAAkB;CAClB,eAAe;CACf,6BAA6B;AAC9B;;AAEA;CACC,WAAW;CACX,kBAAkB;CAClB,QAAQ;CACR,SAAS;CACT,OAAO;CACP,YAAY;CACZ,gBAAgB;CAChB;;;;+CAI8C;AAC/C;;AAEA;CACC,WAAW;CACX,gBAAgB;AACjB;;AAEA;CACC,gBAAgB;AACjB;;AAEA;CACC,SAAS;CACT,UAAU;CACV,gBAAgB;CAChB,kBAAkB;CAClB,QAAQ;CACR,OAAO;AACR;;AAEA;CACC,eAAe;AAChB;;AAEA;CACC,cAAc;CACd,WAAW;CACX,gBAAgB;CAChB,qBAAqB;CACrB,6BAA6B;CAC7B,kBAAkB;AACnB;;AAEA;CACC,qBAAqB;AACtB;;AAEA;CACC,qBAAqB;AACtB;;AAEA;;CAEC,YAAY;CACZ,kBAAkB;CAClB,iBAAiB;CACjB,qBAAqB;CACrB,eAAe;AAChB;;AAEA;CACC,0BAA0B;AAC3B;;AAEA;CACC,mBAAmB;CACnB,cAAc;CACd,eAAe;CACf,6CAA6C;CAC7C,kBAAkB;AACnB;;AAEA;CACC,cAAc;AACf;;AAEA;CACC,cAAc;CACd,qBAAqB;CACrB,gBAAgB;AACjB;;AAEA;CACC,0BAA0B;AAC3B;;AAEA;;;CAGC;;AACD;CACC;;EAEC,gBAAgB;CACjB;;CAEA;EACC,YAAY;CACb;AACD;;AAEA;CACC;EACC,YAAY;CACb;;CAEA;EACC,YAAY;CACb;AACD;;AAEA;;;CAGC,+BAA+B;CAC/B,UAAU;AACX","sources":["node_modules/todomvc-app-css/index.css"],"sourcesContent":[null],"names":[],"version":3,"file":"index.092052ec.css.map","sourceRoot":"/__parcel_source_root/"}
\ No newline at end of file
diff --git a/examples/effector/dist/index.5780389f.css b/examples/effector/dist/index.5780389f.css
new file mode 100644
index 0000000000..976fa24762
--- /dev/null
+++ b/examples/effector/dist/index.5780389f.css
@@ -0,0 +1,10 @@
+/*
+
+app-template.css overrides
+
+remove this comment if used
+remove this file if not
+
+*/
+
+/*# sourceMappingURL=index.5780389f.css.map */
diff --git a/examples/effector/dist/index.5780389f.css.map b/examples/effector/dist/index.5780389f.css.map
new file mode 100644
index 0000000000..2c15e674a0
--- /dev/null
+++ b/examples/effector/dist/index.5780389f.css.map
@@ -0,0 +1 @@
+{"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sources":["css/app.css"],"sourcesContent":["/*\n\napp-template.css overrides\n\nremove this comment if used\nremove this file if not\n\n*/\n"],"names":[],"version":3,"file":"index.5780389f.css.map","sourceRoot":"/__parcel_source_root/"}
\ No newline at end of file
diff --git a/examples/effector/dist/index.69062844.js b/examples/effector/dist/index.69062844.js
new file mode 100644
index 0000000000..8b1672e471
--- /dev/null
+++ b/examples/effector/dist/index.69062844.js
@@ -0,0 +1,3879 @@
+// modules are defined as an array
+// [ module function, map of requires ]
+//
+// map of requires is short require name -> numeric require
+//
+// anything defined in a previous bundle is accessed via the
+// orig method which is the require for previous bundles
+
+(function (modules, entry, mainEntry, parcelRequireName, globalName) {
+ /* eslint-disable no-undef */
+ var globalObject =
+ typeof globalThis !== 'undefined'
+ ? globalThis
+ : typeof self !== 'undefined'
+ ? self
+ : typeof window !== 'undefined'
+ ? window
+ : typeof global !== 'undefined'
+ ? global
+ : {};
+ /* eslint-enable no-undef */
+
+ // Save the require from previous bundle to this closure if any
+ var previousRequire =
+ typeof globalObject[parcelRequireName] === 'function' &&
+ globalObject[parcelRequireName];
+
+ var cache = previousRequire.cache || {};
+ // Do not use `require` to prevent Webpack from trying to bundle this call
+ var nodeRequire =
+ typeof module !== 'undefined' &&
+ typeof module.require === 'function' &&
+ module.require.bind(module);
+
+ function newRequire(name, jumped) {
+ if (!cache[name]) {
+ if (!modules[name]) {
+ // if we cannot find the module within our internal map or
+ // cache jump to the current global require ie. the last bundle
+ // that was added to the page.
+ var currentRequire =
+ typeof globalObject[parcelRequireName] === 'function' &&
+ globalObject[parcelRequireName];
+ if (!jumped && currentRequire) {
+ return currentRequire(name, true);
+ }
+
+ // If there are other bundles on this page the require from the
+ // previous one is saved to 'previousRequire'. Repeat this as
+ // many times as there are bundles until the module is found or
+ // we exhaust the require chain.
+ if (previousRequire) {
+ return previousRequire(name, true);
+ }
+
+ // Try the node require function if it exists.
+ if (nodeRequire && typeof name === 'string') {
+ return nodeRequire(name);
+ }
+
+ var err = new Error("Cannot find module '" + name + "'");
+ err.code = 'MODULE_NOT_FOUND';
+ throw err;
+ }
+
+ localRequire.resolve = resolve;
+ localRequire.cache = {};
+
+ var module = (cache[name] = new newRequire.Module(name));
+
+ modules[name][0].call(
+ module.exports,
+ localRequire,
+ module,
+ module.exports,
+ this
+ );
+ }
+
+ return cache[name].exports;
+
+ function localRequire(x) {
+ return newRequire(localRequire.resolve(x));
+ }
+
+ function resolve(x) {
+ return modules[name][1][x] || x;
+ }
+ }
+
+ function Module(moduleName) {
+ this.id = moduleName;
+ this.bundle = newRequire;
+ this.exports = {};
+ }
+
+ newRequire.isParcelRequire = true;
+ newRequire.Module = Module;
+ newRequire.modules = modules;
+ newRequire.cache = cache;
+ newRequire.parent = previousRequire;
+ newRequire.register = function (id, exports) {
+ modules[id] = [
+ function (require, module) {
+ module.exports = exports;
+ },
+ {},
+ ];
+ };
+
+ Object.defineProperty(newRequire, 'root', {
+ get: function () {
+ return globalObject[parcelRequireName];
+ },
+ });
+
+ globalObject[parcelRequireName] = newRequire;
+
+ for (var i = 0; i < entry.length; i++) {
+ newRequire(entry[i]);
+ }
+
+ if (mainEntry) {
+ // Expose entry point to Node, AMD or browser globals
+ // Based on https://github.com/ForbesLindesay/umd/blob/master/template.js
+ var mainExports = newRequire(mainEntry);
+
+ // CommonJS
+ if (typeof exports === 'object' && typeof module !== 'undefined') {
+ module.exports = mainExports;
+
+ // RequireJS
+ } else if (typeof define === 'function' && define.amd) {
+ define(function () {
+ return mainExports;
+ });
+
+ //
+
+
+