diff --git a/dist/minimart.js b/dist/minimart.js index 213cdee..df396ff 100644 --- a/dist/minimart.js +++ b/dist/minimart.js @@ -24,7 +24,7 @@ function checkChunks(type) { } } -function extractChunk(type, defaultOptions, args) { +function extractChunk(type, kind, defaultOptions, args) { var rawProjectionFn = args[0] var options = null; var handler = null; @@ -55,6 +55,7 @@ function extractChunk(type, defaultOptions, args) { } return { type: type, + kind: kind, rawProjectionFn: rawProjectionFn, options: options, handler: handler @@ -65,16 +66,17 @@ function recordChunk(chunk) { Actor._chunks.push(chunk); } -function chunkExtractor(type, defaultOptions) { +function chunkExtractor(type, kind, defaultOptions) { return function (/* ... */) { checkChunks(type); recordChunk(extractChunk(type, + kind, defaultOptions, Array.prototype.slice.call(arguments))); }; } -var participatorDefaults = { +var participantDefaults = { metaLevel: 0, when: function () { return true; } }; @@ -90,16 +92,17 @@ var observerDefaults = { removed: null }; -Actor.advertise = chunkExtractor('advertise', participatorDefaults); -Actor.subscribe = chunkExtractor('subscribe', participatorDefaults); +Actor.advertise = chunkExtractor('advertise', 'participant', participantDefaults); +Actor.subscribe = chunkExtractor('subscribe', 'participant', participantDefaults); -Actor.observeAdvertisers = chunkExtractor('observeAdvertisers', observerDefaults); -Actor.observeSubscribers = chunkExtractor('observeSubscribers', observerDefaults); +Actor.observeAdvertisers = chunkExtractor('observeAdvertisers', 'observer', observerDefaults); +Actor.observeSubscribers = chunkExtractor('observeSubscribers', 'observer', observerDefaults); Actor.observeGestalt = function (gestaltFn, eventHandlerFn) { checkChunks('observeGestalt'); recordChunk({ type: 'observeGestalt', + kind: 'raw', gestaltFn: gestaltFn, options: { when: function () { return true; } @@ -117,6 +120,15 @@ function finalizeActor(behavior, chunks) { behavior.boot = function () { if (oldBoot) { oldBoot.call(this); } + for (var i = 0; i < chunks.length; i++) { + var chunk = chunks[i]; + if (chunk.kind === 'observer') { + if (chunk.options.presence) { this[chunk.options.presence] = false; } + if (chunk.options.name) { this[chunk.options.name] = []; } + if (chunk.options.added) { this[chunk.options.added] = []; } + if (chunk.options.removed) { this[chunk.options.removed] = []; } + } + } this.updateRoutes(); }; @@ -125,12 +137,11 @@ function finalizeActor(behavior, chunks) { for (var i = 0; i < chunks.length; i++) { var chunk = chunks[i]; if (chunk.options.when.call(this)) { - switch (chunk.type) { - case 'observeGestalt': + switch (chunk.kind) { + case 'raw': newRoutes = newRoutes.union(chunk.gestaltFn.call(this)); break; - case 'advertise': // fall through - case 'subscribe': + case 'participant': var proj = chunk.rawProjectionFn.call(this); projections[i] = proj; var g = Route.simpleGestalt(chunk.type === 'advertise', @@ -139,8 +150,7 @@ function finalizeActor(behavior, chunks) { 0); newRoutes = newRoutes.union(g); break; - case 'observeSubscribers': // fall through - case 'observeAdvertisers': + case 'observer': var proj = chunk.rawProjectionFn.call(this); projections[i] = proj; compiledProjections[i] = Route.compileProjection(proj); @@ -154,7 +164,7 @@ function finalizeActor(behavior, chunks) { } break; default: - throw new Error("Unsupported chunk type: "+chunk.type); + throw new Error("Unsupported chunk type/kind: "+chunk.type+"/"+chunk.kind); } } } @@ -165,14 +175,14 @@ function finalizeActor(behavior, chunks) { if (oldHandleEvent) { oldHandleEvent.call(this, e); } for (var i = 0; i < chunks.length; i++) { var chunk = chunks[i]; - switch (chunk.type) { - case 'observeGestalt': + switch (chunk.kind) { + case 'raw': chunk.eventHandlerFn.call(this, e); break; - case 'advertise': // fall through - case 'subscribe': + case 'participant': if (chunk.handler && (e.type === 'message') + && (e.metaLevel === chunk.options.metaLevel) && (e.isFeedback === (chunk.type === 'advertise'))) { var matchResult = Route.matchPattern(e.message, projections[i]); @@ -181,8 +191,7 @@ function finalizeActor(behavior, chunks) { } } break; - case 'observeSubscribers': // fall through - case 'observeAdvertisers': + case 'observer': if (e.type === 'routes') { var projectionResult = e.gestalt.project(compiledProjections[i], chunk.type !== 'observeSubscribers', @@ -235,7 +244,7 @@ function finalizeActor(behavior, chunks) { } break; default: - throw new Error("Unsupported chunk type: "+chunk.type); + throw new Error("Unsupported chunk type/kind: "+chunk.type+"/"+chunk.kind); } } }; @@ -261,7 +270,42 @@ function kwApply(f, thisArg, args) { module.exports.Actor = Actor; module.exports.kwApply = kwApply; -},{"./minimart.js":5,"./reflect.js":6}],2:[function(_dereq_,module,exports){ +},{"./minimart.js":7,"./reflect.js":8}],2:[function(_dereq_,module,exports){ +// Wire protocol representation of events and actions + +var Route = _dereq_("./route.js"); + +function _encode(e) { + switch (e.type) { + case "routes": + return ["routes", e.gestalt.serialize(function (v) { return true; })]; + case "message": + return ["message", e.message, e.metaLevel, e.isFeedback]; + } +} + +function _decode(what) { + return function (j) { + switch (j[0]) { + case "routes": + return Minimart.updateRoutes([ + Route.deserializeGestalt(j[1], function (v) { return true; })]); + case "message": + return Minimart.sendMessage(j[1], j[2], j[3]); + default: + throw { message: "Invalid JSON-encoded " + what + ": " + JSON.stringify(j) }; + } + }; +} + +/////////////////////////////////////////////////////////////////////////// + +module.exports.encodeEvent = _encode; +module.exports.decodeEvent = _decode("event"); +module.exports.encodeAction = _encode; +module.exports.decodeAction = _decode("action"); + +},{"./route.js":9}],3:[function(_dereq_,module,exports){ // DOM fragment display driver var Minimart = _dereq_("./minimart.js"); var World = Minimart.World; @@ -378,7 +422,70 @@ DOMFragment.prototype.buildNodes = function () { module.exports.spawnDOMDriver = spawnDOMDriver; module.exports.defaultWrapFunction = defaultWrapFunction; -},{"./minimart.js":5}],3:[function(_dereq_,module,exports){ +},{"./minimart.js":7}],4:[function(_dereq_,module,exports){ +/* Ground interface */ +var Minimart = _dereq_("./minimart.js"); +var World = Minimart.World; + +function Ground(bootFn) { + var self = this; + this.stepperId = null; + World.withWorldStack([[this, -1]], function () { + self.world = new World(bootFn); + }); +} + +Ground.prototype.step = function () { + var self = this; + return World.withWorldStack([[this, -1]], function () { + return self.world.step(); + }); +}; + +Ground.prototype.checkPid = function (pid) { + if (pid !== -1) console.error("Weird pid in Ground markPidRunnable", pid); +}; + +Ground.prototype.markPidRunnable = function (pid) { + this.checkPid(pid); + this.startStepping(); +}; + +Ground.prototype.startStepping = function () { + var self = this; + if (this.stepperId) return; + if (this.step()) { + this.stepperId = setTimeout(function () { + self.stepperId = null; + self.startStepping(); + }, 0); + } +}; + +Ground.prototype.stopStepping = function () { + if (this.stepperId) { + clearTimeout(this.stepperId); + this.stepperId = null; + } +}; + +Ground.prototype.enqueueAction = function (pid, action) { + this.checkPid(pid); + if (action.type === 'routes') { + if (!action.gestalt.isEmpty()) { + console.error("You have subscribed to a nonexistent event source.", + action.gestalt.pretty()); + } + } else { + console.error("You have sent a message into the outer void.", action); + } +}; + +/////////////////////////////////////////////////////////////////////////// + +module.exports.Ground = Ground; + +},{"./minimart.js":7}],5:[function(_dereq_,module,exports){ // JQuery event driver var Minimart = _dereq_("./minimart.js"); var World = Minimart.World; @@ -465,7 +572,7 @@ module.exports.spawnJQueryDriver = spawnJQueryDriver; module.exports.simplifyDOMEvent = simplifyDOMEvent; module.exports.defaultWrapFunction = defaultWrapFunction; -},{"./minimart.js":5}],4:[function(_dereq_,module,exports){ +},{"./minimart.js":7}],6:[function(_dereq_,module,exports){ module.exports = _dereq_("./minimart.js"); module.exports.DOM = _dereq_("./dom-driver.js"); @@ -474,12 +581,18 @@ module.exports.RoutingTableWidget = _dereq_("./routing-table-widget.js"); module.exports.WebSocket = _dereq_("./websocket-driver.js"); module.exports.Reflect = _dereq_("./reflect.js"); +module.exports.Ground = _dereq_("./ground.js").Ground; +module.exports.Actor = _dereq_("./actor.js").Actor; module.exports.Spy = _dereq_("./spy.js").Spy; module.exports.WakeDetector = _dereq_("./wake-detector.js").WakeDetector; -module.exports.Actor = _dereq_("./actor.js").Actor; -},{"./actor.js":1,"./dom-driver.js":2,"./jquery-driver.js":3,"./minimart.js":5,"./reflect.js":6,"./routing-table-widget.js":8,"./spy.js":9,"./wake-detector.js":10,"./websocket-driver.js":11}],5:[function(_dereq_,module,exports){ +var Worker = _dereq_("./worker.js"); +module.exports.Worker = Worker.Worker; +module.exports.WorkerGround = Worker.WorkerGround; + +},{"./actor.js":1,"./dom-driver.js":3,"./ground.js":4,"./jquery-driver.js":5,"./minimart.js":7,"./reflect.js":8,"./routing-table-widget.js":10,"./spy.js":11,"./wake-detector.js":13,"./websocket-driver.js":14,"./worker.js":15}],7:[function(_dereq_,module,exports){ var Route = _dereq_("./route.js"); +var Util = _dereq_("./util.js"); /////////////////////////////////////////////////////////////////////////// @@ -871,7 +984,7 @@ World.prototype.clearTombstones = function () { /* Utilities: matching demand for some service */ function DemandMatcher(projection, metaLevel, options) { - options = $.extend({ + options = Util.extend({ demandLevel: 0, supplyLevel: 0, demandSideIsSubscription: false @@ -962,63 +1075,6 @@ Deduplicator.prototype.expireMessages = function () { } }; -/*---------------------------------------------------------------------------*/ -/* Ground interface */ - -function Ground(bootFn) { - var self = this; - this.stepperId = null; - World.withWorldStack([[this, -1]], function () { - self.world = new World(bootFn); - }); -} - -Ground.prototype.step = function () { - var self = this; - return World.withWorldStack([[this, -1]], function () { - return self.world.step(); - }); -}; - -Ground.prototype.checkPid = function (pid) { - if (pid !== -1) console.error("Weird pid in Ground markPidRunnable", pid); -}; - -Ground.prototype.markPidRunnable = function (pid) { - this.checkPid(pid); - this.startStepping(); -}; - -Ground.prototype.startStepping = function () { - var self = this; - if (this.stepperId) return; - if (this.step()) { - this.stepperId = setTimeout(function () { - self.stepperId = null; - self.startStepping(); - }, 0); - } -}; - -Ground.prototype.stopStepping = function () { - if (this.stepperId) { - clearTimeout(this.stepperId); - this.stepperId = null; - } -}; - -Ground.prototype.enqueueAction = function (pid, action) { - this.checkPid(pid); - if (action.type === 'routes') { - if (!action.gestalt.isEmpty()) { - console.error("You have subscribed to a nonexistent event source.", - action.gestalt.pretty()); - } - } else { - console.error("You have sent a message into the outer void.", action); - } -}; - /////////////////////////////////////////////////////////////////////////// module.exports.__ = __; @@ -1034,10 +1090,9 @@ module.exports.shutdownWorld = shutdownWorld; module.exports.World = World; module.exports.DemandMatcher = DemandMatcher; module.exports.Deduplicator = Deduplicator; -module.exports.Ground = Ground; module.exports.Route = Route; -},{"./route.js":7}],6:[function(_dereq_,module,exports){ +},{"./route.js":9,"./util.js":12}],8:[function(_dereq_,module,exports){ // Reflection on function formal parameter lists. // This module is based on Angular's "injector" code, // https://github.com/angular/angular.js/blob/master/src/auto/injector.js, @@ -1065,7 +1120,7 @@ function formalParameters(fn) { module.exports.formalParameters = formalParameters; -},{}],7:[function(_dereq_,module,exports){ +},{}],9:[function(_dereq_,module,exports){ var __ = "__"; /* wildcard marker */ var SOA = "__["; // start of array @@ -2652,7 +2707,7 @@ module.exports.fullGestalt = fullGestalt; module.exports.gestaltUnion = gestaltUnion; module.exports.deserializeGestalt = deserializeGestalt; -},{}],8:[function(_dereq_,module,exports){ +},{}],10:[function(_dereq_,module,exports){ var Minimart = _dereq_("./minimart.js"); var Route = Minimart.Route; var World = Minimart.World; @@ -2710,7 +2765,7 @@ function spawnRoutingTableWidget(selector, fragmentClass, domWrap, observationLe module.exports.spawnRoutingTableWidget = spawnRoutingTableWidget; -},{"./minimart.js":5}],9:[function(_dereq_,module,exports){ +},{"./minimart.js":7}],11:[function(_dereq_,module,exports){ // Generic Spy var Minimart = _dereq_("./minimart.js"); var World = Minimart.World; @@ -2750,7 +2805,22 @@ Spy.prototype.handleEvent = function (e) { module.exports.Spy = Spy; -},{"./minimart.js":5}],10:[function(_dereq_,module,exports){ +},{"./minimart.js":7}],12:[function(_dereq_,module,exports){ +// Minimal jQueryish utilities. Reimplemented because jQuery needs +// window to exist, and we want to run in Web Worker context as well. + +function extend(what, _with) { + for (var prop in _with) { + if (_with.hasOwnProperty(prop)) { + what[prop] = _with[prop]; + } + } + return what; +} + +module.exports.extend = extend; + +},{}],13:[function(_dereq_,module,exports){ // Wake detector - notices when something (such as // suspension/sleeping!) has caused periodic activities to be // interrupted, and warns others about it @@ -2786,8 +2856,9 @@ WakeDetector.prototype.trigger = function () { module.exports.WakeDetector = WakeDetector; -},{"./minimart.js":5}],11:[function(_dereq_,module,exports){ +},{"./minimart.js":7}],14:[function(_dereq_,module,exports){ var Minimart = _dereq_("./minimart.js"); +var Codec = _dereq_("./codec.js"); var Route = Minimart.Route; var World = Minimart.World; var sub = Minimart.sub; @@ -2886,7 +2957,7 @@ WebSocketConnection.prototype.safeSend = function (m) { WebSocketConnection.prototype.sendLocalRoutes = function () { var newLocalRoutesMessage = - JSON.stringify(encodeEvent(Minimart.updateRoutes([this.localGestalt]))); + JSON.stringify(Codec.encodeEvent(Minimart.updateRoutes([this.localGestalt]))); if (this.prevLocalRoutesMessage !== newLocalRoutesMessage) { this.prevLocalRoutesMessage = newLocalRoutesMessage; this.safeSend(newLocalRoutesMessage); @@ -2927,7 +2998,7 @@ WebSocketConnection.prototype.handleEvent = function (e) { var m = e.message; if (m.length && m.length === 3 && m[0] === this.label) { - var encoded = JSON.stringify(encodeEvent( + var encoded = JSON.stringify(Codec.encodeEvent( Minimart.sendMessage(m[2], m[1], e.isFeedback))); if (this.deduplicator.accept(encoded)) { this.safeSend(encoded); @@ -3017,36 +3088,68 @@ WebSocketConnection.prototype.onclose = function (e) { }; /////////////////////////////////////////////////////////////////////////// -// Wire protocol representation of events and actions -function encodeEvent(e) { - switch (e.type) { - case "routes": - return ["routes", e.gestalt.serialize(function (v) { return true; })]; - case "message": - return ["message", e.message, e.metaLevel, e.isFeedback]; - } -} +module.exports.WebSocketConnection = WebSocketConnection; -function decodeAction(j) { - switch (j[0]) { - case "routes": - return Minimart.updateRoutes([ - Route.deserializeGestalt(j[1], function (v) { return true; })]); - case "message": - return Minimart.sendMessage(j[1], j[2], j[3]); - default: - throw { message: "Invalid JSON-encoded action: " + JSON.stringify(j) }; - } -} +},{"./codec.js":2,"./minimart.js":7}],15:[function(_dereq_,module,exports){ +/* Web Worker interface */ +var Ground = _dereq_("./ground.js").Ground; +var Util = _dereq_("./util.js"); +var Codec = _dereq_("./codec.js"); + +var Minimart = _dereq_("./minimart.js"); +var World = Minimart.World; +var sub = Minimart.sub; +var pub = Minimart.pub; +var __ = Minimart.__; + +var BuiltinWorker = typeof window !== 'undefined' && window.Worker; /////////////////////////////////////////////////////////////////////////// -module.exports.WebSocketConnection = WebSocketConnection; -module.exports.encodeEvent = encodeEvent; -module.exports.decodeAction = decodeAction; +function Worker(scriptUrl) { + this.scriptUrl = scriptUrl; + this.w = new BuiltinWorker(scriptUrl); +} -},{"./minimart.js":5}]},{},[4]) -//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3RvbnlnL3NyYy9qcy1tYXJrZXRwbGFjZS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1wYWNrL19wcmVsdWRlLmpzIiwiL2hvbWUvdG9ueWcvc3JjL2pzLW1hcmtldHBsYWNlL3NyYy9hY3Rvci5qcyIsIi9ob21lL3RvbnlnL3NyYy9qcy1tYXJrZXRwbGFjZS9zcmMvZG9tLWRyaXZlci5qcyIsIi9ob21lL3RvbnlnL3NyYy9qcy1tYXJrZXRwbGFjZS9zcmMvanF1ZXJ5LWRyaXZlci5qcyIsIi9ob21lL3RvbnlnL3NyYy9qcy1tYXJrZXRwbGFjZS9zcmMvbWFpbi5qcyIsIi9ob21lL3RvbnlnL3NyYy9qcy1tYXJrZXRwbGFjZS9zcmMvbWluaW1hcnQuanMiLCIvaG9tZS90b255Zy9zcmMvanMtbWFya2V0cGxhY2Uvc3JjL3JlZmxlY3QuanMiLCIvaG9tZS90b255Zy9zcmMvanMtbWFya2V0cGxhY2Uvc3JjL3JvdXRlLmpzIiwiL2hvbWUvdG9ueWcvc3JjL2pzLW1hcmtldHBsYWNlL3NyYy9yb3V0aW5nLXRhYmxlLXdpZGdldC5qcyIsIi9ob21lL3RvbnlnL3NyYy9qcy1tYXJrZXRwbGFjZS9zcmMvc3B5LmpzIiwiL2hvbWUvdG9ueWcvc3JjL2pzLW1hcmtldHBsYWNlL3NyYy93YWtlLWRldGVjdG9yLmpzIiwiL2hvbWUvdG9ueWcvc3JjL2pzLW1hcmtldHBsYWNlL3NyYy93ZWJzb2NrZXQtZHJpdmVyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDclFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDN2lCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDampEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0Q0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dGhyb3cgbmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKX12YXIgZj1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwoZi5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxmLGYuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwidmFyIFJlZmxlY3QgPSByZXF1aXJlKFwiLi9yZWZsZWN0LmpzXCIpO1xudmFyIE1pbmltYXJ0ID0gcmVxdWlyZShcIi4vbWluaW1hcnQuanNcIik7XG52YXIgV29ybGQgPSBNaW5pbWFydC5Xb3JsZDtcbnZhciBSb3V0ZSA9IE1pbmltYXJ0LlJvdXRlO1xuXG5BY3Rvci5fY2h1bmtzID0gbnVsbDtcblxuZnVuY3Rpb24gQWN0b3IoY3Rvcikge1xuICAgIHZhciBvbGRDaHVua3MgPSBBY3Rvci5fY2h1bmtzO1xuICAgIHRyeSB7XG5cdEFjdG9yLl9jaHVua3MgPSBbXTtcblx0dmFyIGJlaGF2aW9yID0gbmV3IGN0b3IoKTtcblx0cmV0dXJuIGZpbmFsaXplQWN0b3IoYmVoYXZpb3IsIEFjdG9yLl9jaHVua3MpO1xuICAgIH0gY2F0Y2ggKGUpIHtcblx0QWN0b3IuX2NodW5rcyA9IG9sZENodW5rcztcblx0dGhyb3cgZTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGNoZWNrQ2h1bmtzKHR5cGUpIHtcbiAgICBpZiAoIUFjdG9yLl9jaHVua3MpIHtcblx0dGhyb3cgbmV3IEVycm9yKFwiQ2FsbCB0byBBY3Rvci5cIit0eXBlK1wiIG91dHNpZGUgb2YgQWN0b3IgY29uc3RydWN0b3JcIik7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBleHRyYWN0Q2h1bmsodHlwZSwgZGVmYXVsdE9wdGlvbnMsIGFyZ3MpIHtcbiAgICB2YXIgcmF3UHJvamVjdGlvbkZuID0gYXJnc1swXVxuICAgIHZhciBvcHRpb25zID0gbnVsbDtcbiAgICB2YXIgaGFuZGxlciA9IG51bGw7XG4gICAgaWYgKHR5cGVvZiByYXdQcm9qZWN0aW9uRm4gIT09ICdmdW5jdGlvbicpIHtcblx0dGhyb3cgbmV3IEVycm9yKFwiQWN0b3IuXCIrdHlwZStcIiBleHBlY3RzIGEgZnVuY3Rpb24gcHJvZHVjaW5nIGEgcGF0dGVybiBhcyBmaXJzdCBhcmd1bWVudFwiKTtcbiAgICB9XG4gICAgZm9yICh2YXIgaSA9IDE7IGkgPCBhcmdzLmxlbmd0aDsgaSsrKSB7IC8vIE5COiBza2lwIHRoZSBmaXJzdCBhcmcgLSBpdCdzIHJhd1Byb2plY3Rpb25GblxuXHRpZiAodHlwZW9mIGFyZ3NbaV0gPT09ICdmdW5jdGlvbicpIHtcblx0ICAgIGlmIChoYW5kbGVyICE9PSBudWxsKSB7IHRocm93IG5ldyBFcnJvcihcIlRvbyBtYW55IGhhbmRsZXIgZnVuY3Rpb25zIGluIEFjdG9yLlwiK3R5cGUpOyB9XG5cdCAgICBoYW5kbGVyID0gYXJnc1tpXTtcblx0fSBlbHNlIGlmICh0eXBlb2YgYXJnc1tpXSA9PT0gJ29iamVjdCcpIHtcblx0ICAgIGlmIChvcHRpb25zICE9PSBudWxsKSB7IHRocm93IG5ldyBFcnJvcihcIlRvbyBtYW55IG9wdGlvbnMgYXJndW1lbnRzIGluIEFjdG9yLlwiK3R5cGUpOyB9XG5cdCAgICBvcHRpb25zID0gYXJnc1tpXTtcblx0fSBlbHNlIHtcblx0ICAgIHRocm93IG5ldyBFcnJvcihcIlVucmVjb2duaXNlZCBhcmd1bWVudCBpbiBBY3Rvci5cIit0eXBlKTtcblx0fVxuICAgIH1cbiAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcbiAgICBmb3IgKHZhciBrIGluIG9wdGlvbnMpIHtcblx0aWYgKCEoayBpbiBkZWZhdWx0T3B0aW9ucykpIHtcblx0ICAgIHRocm93IG5ldyBFcnJvcihcIlVucmVjb2duaXNlZCBvcHRpb24gJ1wiK2srXCInIGluIEFjdG9yLlwiK3R5cGUpO1xuXHR9XG4gICAgfVxuICAgIGZvciAodmFyIGsgaW4gZGVmYXVsdE9wdGlvbnMpIHtcblx0aWYgKCEoayBpbiBvcHRpb25zKSkge1xuXHQgICAgb3B0aW9uc1trXSA9IGRlZmF1bHRPcHRpb25zW2tdO1xuXHR9XG4gICAgfVxuICAgIHJldHVybiB7XG5cdHR5cGU6IHR5cGUsXG5cdHJhd1Byb2plY3Rpb25GbjogcmF3UHJvamVjdGlvbkZuLFxuXHRvcHRpb25zOiBvcHRpb25zLFxuXHRoYW5kbGVyOiBoYW5kbGVyXG4gICAgfTtcbn1cblxuZnVuY3Rpb24gcmVjb3JkQ2h1bmsoY2h1bmspIHtcbiAgICBBY3Rvci5fY2h1bmtzLnB1c2goY2h1bmspO1xufVxuXG5mdW5jdGlvbiBjaHVua0V4dHJhY3Rvcih0eXBlLCBkZWZhdWx0T3B0aW9ucykge1xuICAgIHJldHVybiBmdW5jdGlvbiAoLyogLi4uICovKSB7XG5cdGNoZWNrQ2h1bmtzKHR5cGUpO1xuXHRyZWNvcmRDaHVuayhleHRyYWN0Q2h1bmsodHlwZSxcblx0XHRcdFx0IGRlZmF1bHRPcHRpb25zLFxuXHRcdFx0XHQgQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xuICAgIH07XG59XG5cbnZhciBwYXJ0aWNpcGF0b3JEZWZhdWx0cyA9IHtcbiAgICBtZXRhTGV2ZWw6IDAsXG4gICAgd2hlbjogZnVuY3Rpb24gKCkgeyByZXR1cm4gdHJ1ZTsgfVxufTtcblxudmFyIG9ic2VydmVyRGVmYXVsdHMgPSB7XG4gICAgbWV0YUxldmVsOiAwLFxuICAgIGxldmVsOiAwLFxuICAgIHdoZW46IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH0sXG4gICAgcHJlc2VuY2U6IG51bGwsXG4gICAgbmFtZTogbnVsbCxcbiAgICBzZXQ6IG51bGwsXG4gICAgYWRkZWQ6IG51bGwsXG4gICAgcmVtb3ZlZDogbnVsbFxufTtcblxuQWN0b3IuYWR2ZXJ0aXNlID0gY2h1bmtFeHRyYWN0b3IoJ2FkdmVydGlzZScsIHBhcnRpY2lwYXRvckRlZmF1bHRzKTtcbkFjdG9yLnN1YnNjcmliZSA9IGNodW5rRXh0cmFjdG9yKCdzdWJzY3JpYmUnLCBwYXJ0aWNpcGF0b3JEZWZhdWx0cyk7XG5cbkFjdG9yLm9ic2VydmVBZHZlcnRpc2VycyA9IGNodW5rRXh0cmFjdG9yKCdvYnNlcnZlQWR2ZXJ0aXNlcnMnLCBvYnNlcnZlckRlZmF1bHRzKTtcbkFjdG9yLm9ic2VydmVTdWJzY3JpYmVycyA9IGNodW5rRXh0cmFjdG9yKCdvYnNlcnZlU3Vic2NyaWJlcnMnLCBvYnNlcnZlckRlZmF1bHRzKTtcblxuQWN0b3Iub2JzZXJ2ZUdlc3RhbHQgPSBmdW5jdGlvbiAoZ2VzdGFsdEZuLCBldmVudEhhbmRsZXJGbikge1xuICAgIGNoZWNrQ2h1bmtzKCdvYnNlcnZlR2VzdGFsdCcpO1xuICAgIHJlY29yZENodW5rKHtcblx0dHlwZTogJ29ic2VydmVHZXN0YWx0Jyxcblx0Z2VzdGFsdEZuOiBnZXN0YWx0Rm4sXG5cdG9wdGlvbnM6IHtcblx0ICAgIHdoZW46IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH1cblx0fSxcblx0ZXZlbnRIYW5kbGVyRm46IGV2ZW50SGFuZGxlckZuXG4gICAgfSk7XG59O1xuXG5mdW5jdGlvbiBmaW5hbGl6ZUFjdG9yKGJlaGF2aW9yLCBjaHVua3MpIHtcbiAgICB2YXIgb2xkQm9vdCA9IGJlaGF2aW9yLmJvb3Q7XG4gICAgdmFyIG9sZEhhbmRsZUV2ZW50ID0gYmVoYXZpb3IuaGFuZGxlRXZlbnQ7XG4gICAgdmFyIHByb2plY3Rpb25zID0ge307XG4gICAgdmFyIGNvbXBpbGVkUHJvamVjdGlvbnMgPSB7fTtcbiAgICB2YXIgcHJldmlvdXNPYmpzID0ge307XG5cbiAgICBiZWhhdmlvci5ib290ID0gZnVuY3Rpb24gKCkge1xuXHRpZiAob2xkQm9vdCkgeyBvbGRCb290LmNhbGwodGhpcyk7IH1cblx0dGhpcy51cGRhdGVSb3V0ZXMoKTtcbiAgICB9O1xuXG4gICAgYmVoYXZpb3IudXBkYXRlUm91dGVzID0gZnVuY3Rpb24gKCkge1xuXHR2YXIgbmV3Um91dGVzID0gUm91dGUuZW1wdHlHZXN0YWx0O1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IGNodW5rcy5sZW5ndGg7IGkrKykge1xuXHQgICAgdmFyIGNodW5rID0gY2h1bmtzW2ldO1xuXHQgICAgaWYgKGNodW5rLm9wdGlvbnMud2hlbi5jYWxsKHRoaXMpKSB7XG5cdFx0c3dpdGNoIChjaHVuay50eXBlKSB7XG5cdFx0Y2FzZSAnb2JzZXJ2ZUdlc3RhbHQnOlxuXHRcdCAgICBuZXdSb3V0ZXMgPSBuZXdSb3V0ZXMudW5pb24oY2h1bmsuZ2VzdGFsdEZuLmNhbGwodGhpcykpO1xuXHRcdCAgICBicmVhaztcblx0XHRjYXNlICdhZHZlcnRpc2UnOiAvLyBmYWxsIHRocm91Z2hcblx0XHRjYXNlICdzdWJzY3JpYmUnOlxuXHRcdCAgICB2YXIgcHJvaiA9IGNodW5rLnJhd1Byb2plY3Rpb25Gbi5jYWxsKHRoaXMpO1xuXHRcdCAgICBwcm9qZWN0aW9uc1tpXSA9IHByb2o7XG5cdFx0ICAgIHZhciBnID0gUm91dGUuc2ltcGxlR2VzdGFsdChjaHVuay50eXBlID09PSAnYWR2ZXJ0aXNlJyxcblx0XHRcdFx0XHRcdFJvdXRlLnByb2plY3Rpb25Ub1BhdHRlcm4ocHJvaiksXG5cdFx0XHRcdFx0XHRjaHVuay5vcHRpb25zLm1ldGFMZXZlbCxcblx0XHRcdFx0XHRcdDApO1xuXHRcdCAgICBuZXdSb3V0ZXMgPSBuZXdSb3V0ZXMudW5pb24oZyk7XG5cdFx0ICAgIGJyZWFrO1xuXHRcdGNhc2UgJ29ic2VydmVTdWJzY3JpYmVycyc6IC8vIGZhbGwgdGhyb3VnaFxuXHRcdGNhc2UgJ29ic2VydmVBZHZlcnRpc2Vycyc6XG5cdFx0ICAgIHZhciBwcm9qID0gY2h1bmsucmF3UHJvamVjdGlvbkZuLmNhbGwodGhpcyk7XG5cdFx0ICAgIHByb2plY3Rpb25zW2ldID0gcHJvajtcblx0XHQgICAgY29tcGlsZWRQcm9qZWN0aW9uc1tpXSA9IFJvdXRlLmNvbXBpbGVQcm9qZWN0aW9uKHByb2opO1xuXHRcdCAgICB2YXIgZyA9IFJvdXRlLnNpbXBsZUdlc3RhbHQoY2h1bmsudHlwZSA9PT0gJ29ic2VydmVTdWJzY3JpYmVycycsXG5cdFx0XHRcdFx0XHRSb3V0ZS5wcm9qZWN0aW9uVG9QYXR0ZXJuKHByb2opLFxuXHRcdFx0XHRcdFx0Y2h1bmsub3B0aW9ucy5tZXRhTGV2ZWwsXG5cdFx0XHRcdFx0XHRjaHVuay5vcHRpb25zLmxldmVsICsgMSk7XG5cdFx0ICAgIG5ld1JvdXRlcyA9IG5ld1JvdXRlcy51bmlvbihnKTtcblx0XHQgICAgaWYgKGNodW5rLm9wdGlvbnMuYWRkZWQgfHwgY2h1bmsub3B0aW9ucy5yZW1vdmVkKSB7XG5cdFx0XHRwcmV2aW91c09ianNbaV0gPSBSb3V0ZS5hcnJheVRvU2V0KFtdKTtcblx0XHQgICAgfVxuXHRcdCAgICBicmVhaztcblx0XHRkZWZhdWx0OlxuXHRcdCAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbnN1cHBvcnRlZCBjaHVuayB0eXBlOiBcIitjaHVuay50eXBlKTtcblx0XHR9XG5cdCAgICB9XG5cdH1cblx0V29ybGQudXBkYXRlUm91dGVzKFtuZXdSb3V0ZXNdKTtcbiAgICB9O1xuXG4gICAgYmVoYXZpb3IuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAoZSkge1xuXHRpZiAob2xkSGFuZGxlRXZlbnQpIHsgb2xkSGFuZGxlRXZlbnQuY2FsbCh0aGlzLCBlKTsgfVxuXHRmb3IgKHZhciBpID0gMDsgaSA8IGNodW5rcy5sZW5ndGg7IGkrKykge1xuXHQgICAgdmFyIGNodW5rID0gY2h1bmtzW2ldO1xuXHQgICAgc3dpdGNoIChjaHVuay50eXBlKSB7XG5cdCAgICBjYXNlICdvYnNlcnZlR2VzdGFsdCc6XG5cdFx0Y2h1bmsuZXZlbnRIYW5kbGVyRm4uY2FsbCh0aGlzLCBlKTtcblx0XHRicmVhaztcblx0ICAgIGNhc2UgJ2FkdmVydGlzZSc6IC8vIGZhbGwgdGhyb3VnaFxuXHQgICAgY2FzZSAnc3Vic2NyaWJlJzpcblx0XHRpZiAoY2h1bmsuaGFuZGxlclxuXHRcdCAgICAmJiAoZS50eXBlID09PSAnbWVzc2FnZScpXG5cdFx0ICAgICYmIChlLmlzRmVlZGJhY2sgPT09IChjaHVuay50eXBlID09PSAnYWR2ZXJ0aXNlJykpKVxuXHRcdHtcblx0XHQgICAgdmFyIG1hdGNoUmVzdWx0ID0gUm91dGUubWF0Y2hQYXR0ZXJuKGUubWVzc2FnZSwgcHJvamVjdGlvbnNbaV0pO1xuXHRcdCAgICBpZiAobWF0Y2hSZXN1bHQpIHtcblx0XHRcdGt3QXBwbHkoY2h1bmsuaGFuZGxlciwgdGhpcywgbWF0Y2hSZXN1bHQpO1xuXHRcdCAgICB9XG5cdFx0fVxuXHRcdGJyZWFrO1xuXHQgICAgY2FzZSAnb2JzZXJ2ZVN1YnNjcmliZXJzJzogLy8gZmFsbCB0aHJvdWdoXG5cdCAgICBjYXNlICdvYnNlcnZlQWR2ZXJ0aXNlcnMnOlxuXHRcdGlmIChlLnR5cGUgPT09ICdyb3V0ZXMnKSB7XG5cdFx0ICAgIHZhciBwcm9qZWN0aW9uUmVzdWx0ID0gZS5nZXN0YWx0LnByb2plY3QoY29tcGlsZWRQcm9qZWN0aW9uc1tpXSxcblx0XHRcdFx0XHRcdFx0ICAgICBjaHVuay50eXBlICE9PSAnb2JzZXJ2ZVN1YnNjcmliZXJzJyxcblx0XHRcdFx0XHRcdFx0ICAgICBjaHVuay5vcHRpb25zLm1ldGFMZXZlbCxcblx0XHRcdFx0XHRcdFx0ICAgICBjaHVuay5vcHRpb25zLmxldmVsKTtcblxuXHRcdCAgICB2YXIgaXNQcmVzZW50ID0gIVJvdXRlLmlzX2VtcHR5TWF0Y2hlcihwcm9qZWN0aW9uUmVzdWx0KTtcblx0XHQgICAgaWYgKGNodW5rLm9wdGlvbnMucHJlc2VuY2UpIHtcblx0XHRcdHRoaXNbY2h1bmsub3B0aW9ucy5wcmVzZW5jZV0gPSBpc1ByZXNlbnQ7XG5cdFx0ICAgIH1cblxuXHRcdCAgICB2YXIgb2JqcyA9IFtdO1xuXHRcdCAgICBpZiAoaXNQcmVzZW50KSB7XG5cdFx0XHR2YXIga2V5cyA9IFJvdXRlLm1hdGNoZXJLZXlzKHByb2plY3Rpb25SZXN1bHQpO1xuXHRcdFx0aWYgKGtleXMgPT09IG51bGwpIHtcblx0XHRcdCAgICBjb25zb2xlLndhcm4oXCJXaWxkY2FyZCBkZXRlY3RlZCB3aGlsZSBwcm9qZWN0aW5nIChcIlxuXHRcdFx0XHRcdCArSlNPTi5zdHJpbmdpZnkoY2h1bmsub3B0aW9ucykrXCIpXCIpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdCAgICBvYmpzID0gUm91dGUubWF0Y2hlcktleXNUb09iamVjdHMoa2V5cywgY29tcGlsZWRQcm9qZWN0aW9uc1tpXSk7XG5cdFx0XHQgICAgaWYgKGNodW5rLm9wdGlvbnMuc2V0KSB7XG5cdFx0XHRcdGZvciAodmFyIGogPSAwOyBqIDwgb2Jqcy5sZW5ndGg7IGorKykge1xuXHRcdFx0XHQgICAgb2Jqc1tqXSA9IGNodW5rLm9wdGlvbnMuc2V0LmNhbGwodGhpcywgb2Jqc1tqXSk7XG5cdFx0XHRcdH1cblx0XHRcdCAgICB9XG5cdFx0XHR9XG5cdFx0ICAgIH1cblx0XHQgICAgaWYgKGNodW5rLm9wdGlvbnMubmFtZSkge1xuXHRcdFx0dGhpc1tjaHVuay5vcHRpb25zLm5hbWVdID0gb2Jqcztcblx0XHQgICAgfVxuXG5cdFx0ICAgIGlmIChjaHVuay5vcHRpb25zLmFkZGVkIHx8IGNodW5rLm9wdGlvbnMucmVtb3ZlZCkge1xuXHRcdFx0dmFyIG9ialNldCA9IFJvdXRlLmFycmF5VG9TZXQob2Jqcyk7XG5cblx0XHRcdGlmIChjaHVuay5vcHRpb25zLmFkZGVkKSB7XG5cdFx0XHQgICAgdGhpc1tjaHVuay5vcHRpb25zLmFkZGVkXSA9XG5cdFx0XHRcdFJvdXRlLnNldFRvQXJyYXkoUm91dGUuc2V0U3VidHJhY3Qob2JqU2V0LCBwcmV2aW91c09ianNbaV0pKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGNodW5rLm9wdGlvbnMucmVtb3ZlZCkge1xuXHRcdFx0ICAgIHRoaXNbY2h1bmsub3B0aW9ucy5yZW1vdmVkXSA9XG5cdFx0XHRcdFJvdXRlLnNldFRvQXJyYXkoUm91dGUuc2V0U3VidHJhY3QocHJldmlvdXNPYmpzW2ldLCBvYmpTZXQpKTtcblx0XHRcdH1cblxuXHRcdFx0cHJldmlvdXNPYmpzW2ldID0gb2JqU2V0O1xuXHRcdCAgICB9XG5cblx0XHQgICAgaWYgKGNodW5rLmhhbmRsZXIpIHtcblx0XHRcdGNodW5rLmhhbmRsZXIuY2FsbCh0aGlzKTtcblx0XHQgICAgfVxuXHRcdH1cblx0XHRicmVhaztcblx0ICAgIGRlZmF1bHQ6XG5cdFx0dGhyb3cgbmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgY2h1bmsgdHlwZTogXCIrY2h1bmsudHlwZSk7XG5cdCAgICB9XG5cdH1cbiAgICB9O1xuXG4gICAgcmV0dXJuIGJlaGF2aW9yO1xufVxuXG5mdW5jdGlvbiBrd0FwcGx5KGYsIHRoaXNBcmcsIGFyZ3MpIHtcbiAgICB2YXIgZm9ybWFscyA9IFJlZmxlY3QuZm9ybWFsUGFyYW1ldGVycyhmKTtcbiAgICB2YXIgYWN0dWFscyA9IFtdXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBmb3JtYWxzLmxlbmd0aDsgaSsrKSB7XG5cdHZhciBmb3JtYWwgPSBmb3JtYWxzW2ldO1xuXHRpZiAoIShmb3JtYWwgaW4gYXJncykpIHtcblx0ICAgIHRocm93IG5ldyBFcnJvcihcIkZ1bmN0aW9uIHBhcmFtZXRlciAnXCIrZm9ybWFsK1wiJyBub3QgcHJlc2VudCBpbiBhcmdzXCIpO1xuXHR9XG5cdGFjdHVhbHMucHVzaChhcmdzW2Zvcm1hbF0pO1xuICAgIH1cbiAgICByZXR1cm4gZi5hcHBseSh0aGlzQXJnLCBhY3R1YWxzKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLkFjdG9yID0gQWN0b3I7XG5tb2R1bGUuZXhwb3J0cy5rd0FwcGx5ID0ga3dBcHBseTtcbiIsIi8vIERPTSBmcmFnbWVudCBkaXNwbGF5IGRyaXZlclxudmFyIE1pbmltYXJ0ID0gcmVxdWlyZShcIi4vbWluaW1hcnQuanNcIik7XG52YXIgV29ybGQgPSBNaW5pbWFydC5Xb3JsZDtcbnZhciBzdWIgPSBNaW5pbWFydC5zdWI7XG52YXIgcHViID0gTWluaW1hcnQucHViO1xudmFyIF9fID0gTWluaW1hcnQuX187XG52YXIgXyQgPSBNaW5pbWFydC5fJDtcblxuZnVuY3Rpb24gc3Bhd25ET01Ecml2ZXIoZG9tV3JhcEZ1bmN0aW9uLCBqUXVlcnlXcmFwRnVuY3Rpb24pIHtcbiAgICBkb21XcmFwRnVuY3Rpb24gPSBkb21XcmFwRnVuY3Rpb24gfHwgZGVmYXVsdFdyYXBGdW5jdGlvbjtcbiAgICB2YXIgZCA9IG5ldyBNaW5pbWFydC5EZW1hbmRNYXRjaGVyKGRvbVdyYXBGdW5jdGlvbihfJCwgXyQsIF8kKSk7XG4gICAgZC5vbkRlbWFuZEluY3JlYXNlID0gZnVuY3Rpb24gKGNhcHR1cmVzKSB7XG5cdHZhciBzZWxlY3RvciA9IGNhcHR1cmVzWzBdO1xuXHR2YXIgZnJhZ21lbnRDbGFzcyA9IGNhcHR1cmVzWzFdO1xuXHR2YXIgZnJhZ21lbnRTcGVjID0gY2FwdHVyZXNbMl07XG5cdFdvcmxkLnNwYXduKG5ldyBET01GcmFnbWVudChzZWxlY3Rvcixcblx0XHRcdFx0ICAgIGZyYWdtZW50Q2xhc3MsXG5cdFx0XHRcdCAgICBmcmFnbWVudFNwZWMsXG5cdFx0XHRcdCAgICBkb21XcmFwRnVuY3Rpb24sXG5cdFx0XHRcdCAgICBqUXVlcnlXcmFwRnVuY3Rpb24pLFxuXHRcdCAgICBbc3ViKGRvbVdyYXBGdW5jdGlvbihzZWxlY3RvciwgZnJhZ21lbnRDbGFzcywgZnJhZ21lbnRTcGVjKSksXG5cdFx0ICAgICBzdWIoZG9tV3JhcEZ1bmN0aW9uKHNlbGVjdG9yLCBmcmFnbWVudENsYXNzLCBmcmFnbWVudFNwZWMpLCAwLCAxKV0pO1xuICAgIH07XG4gICAgV29ybGQuc3Bhd24oZCk7XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRXcmFwRnVuY3Rpb24oc2VsZWN0b3IsIGZyYWdtZW50Q2xhc3MsIGZyYWdtZW50U3BlYykge1xuICAgIHJldHVybiBbXCJET01cIiwgc2VsZWN0b3IsIGZyYWdtZW50Q2xhc3MsIGZyYWdtZW50U3BlY107XG59XG5cbmZ1bmN0aW9uIERPTUZyYWdtZW50KHNlbGVjdG9yLCBmcmFnbWVudENsYXNzLCBmcmFnbWVudFNwZWMsIGRvbVdyYXBGdW5jdGlvbiwgalF1ZXJ5V3JhcEZ1bmN0aW9uKSB7XG4gICAgdGhpcy5zZWxlY3RvciA9IHNlbGVjdG9yO1xuICAgIHRoaXMuZnJhZ21lbnRDbGFzcyA9IGZyYWdtZW50Q2xhc3M7XG4gICAgdGhpcy5mcmFnbWVudFNwZWMgPSBmcmFnbWVudFNwZWM7XG4gICAgdGhpcy5kb21XcmFwRnVuY3Rpb24gPSBkb21XcmFwRnVuY3Rpb247XG4gICAgdGhpcy5qUXVlcnlXcmFwRnVuY3Rpb24gPSBqUXVlcnlXcmFwRnVuY3Rpb247XG4gICAgdGhpcy5ub2RlcyA9IHRoaXMuYnVpbGROb2RlcygpO1xufVxuXG5ET01GcmFnbWVudC5wcm90b3R5cGUuYm9vdCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIG1vbml0b3JpbmcgPVxuXHRzdWIodGhpcy5kb21XcmFwRnVuY3Rpb24oc2VsZi5zZWxlY3Rvciwgc2VsZi5mcmFnbWVudENsYXNzLCBzZWxmLmZyYWdtZW50U3BlYyksIDEsIDIpO1xuICAgIFdvcmxkLnNwYXduKG5ldyBXb3JsZChmdW5jdGlvbiAoKSB7XG5cdE1pbmltYXJ0LkpRdWVyeS5zcGF3bkpRdWVyeURyaXZlcihzZWxmLnNlbGVjdG9yK1wiID4gLlwiK3NlbGYuZnJhZ21lbnRDbGFzcyxcblx0XHRcdFx0XHQgIDEsXG5cdFx0XHRcdFx0ICBzZWxmLmpRdWVyeVdyYXBGdW5jdGlvbik7XG5cdFdvcmxkLnNwYXduKHtcblx0ICAgIGhhbmRsZUV2ZW50OiBmdW5jdGlvbiAoZSkge1xuXHRcdGlmIChlLnR5cGUgPT09IFwicm91dGVzXCIpIHtcblx0XHQgICAgdmFyIGxldmVsID0gZS5nZXN0YWx0LmdldExldmVsKDEsIDApOyAvLyBmaW5kIHBhcnRpY2lwYW50IHBlZXJzXG5cdFx0ICAgIGlmICghZS5nZXN0YWx0LmlzRW1wdHkoKSAmJiBsZXZlbC5pc0VtcHR5KCkpIHtcblx0XHRcdFdvcmxkLnNodXRkb3duV29ybGQoKTtcblx0XHQgICAgfVxuXHRcdH1cblx0ICAgIH1cblx0fSwgW21vbml0b3JpbmddKTtcbiAgICB9KSk7XG59O1xuXG5ET01GcmFnbWVudC5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAoZSkge1xuICAgIGlmIChlLnR5cGUgPT09IFwicm91dGVzXCIgJiYgZS5nZXN0YWx0LmlzRW1wdHkoKSkge1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubm9kZXMubGVuZ3RoOyBpKyspIHtcblx0ICAgIHZhciBuID0gdGhpcy5ub2Rlc1tpXTtcblx0ICAgIG4ucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChuKTtcblx0fVxuXHRXb3JsZC5leGl0KCk7XG4gICAgfVxufTtcblxuZnVuY3Rpb24gaXNBdHRyaWJ1dGVzKHgpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheSh4KSAmJiAoKHgubGVuZ3RoID09PSAwKSB8fCBBcnJheS5pc0FycmF5KHhbMF0pKTtcbn1cblxuRE9NRnJhZ21lbnQucHJvdG90eXBlLmludGVycHJldFNwZWMgPSBmdW5jdGlvbiAoc3BlYykge1xuICAgIC8vIEZyYWdtZW50IHNwZWNzIGFyZSByb3VnaGx5IEpTT04tZXF1aXZhbGVudHMgb2YgU1hNTC5cbiAgICAvLyBzcGVjIDo6PT0gW1widGFnXCIsIHtcImF0dHJcIjogXCJ2YWx1ZVwiLCAuLi59LCBzcGVjLCBzcGVjLCAuLi5dXG4gICAgLy8gICAgICAgICB8IFtcInRhZ1wiLCBzcGVjLCBzcGVjLCAuLi5dXG4gICAgLy8gICAgICAgICB8IFwiY2RhdGFcIlxuICAgIGlmICh0eXBlb2Yoc3BlYykgPT09IFwic3RyaW5nXCIgfHwgdHlwZW9mKHNwZWMpID09PSBcIm51bWJlclwiKSB7XG5cdHJldHVybiBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShzcGVjKTtcbiAgICB9IGVsc2UgaWYgKCQuaXNBcnJheShzcGVjKSkge1xuXHR2YXIgdGFnTmFtZSA9IHNwZWNbMF07XG5cdHZhciBoYXNBdHRycyA9IGlzQXR0cmlidXRlcyhzcGVjWzFdKTtcblx0dmFyIGF0dHJzID0gaGFzQXR0cnMgPyBzcGVjWzFdIDoge307XG5cdHZhciBraWRJbmRleCA9IGhhc0F0dHJzID8gMiA6IDE7XG5cblx0Ly8gV293ISBTdWNoIFhTUyEgTWFueSBoYWNrcyEgU28gdnVsbmVyYWJpbGl0eSEgQW1hemUhXG5cdHZhciBuID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWdOYW1lKTtcblx0Zm9yICh2YXIgaSA9IDA7IGkgPCBhdHRycy5sZW5ndGg7IGkrKykge1xuXHQgICAgbi5zZXRBdHRyaWJ1dGUoYXR0cnNbaV1bMF0sIGF0dHJzW2ldWzFdKTtcblx0fVxuXHRmb3IgKHZhciBpID0ga2lkSW5kZXg7IGkgPCBzcGVjLmxlbmd0aDsgaSsrKSB7XG5cdCAgICBuLmFwcGVuZENoaWxkKHRoaXMuaW50ZXJwcmV0U3BlYyhzcGVjW2ldKSk7XG5cdH1cblx0cmV0dXJuIG47XG4gICAgfVxufTtcblxuRE9NRnJhZ21lbnQucHJvdG90eXBlLmJ1aWxkTm9kZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHZhciBub2RlcyA9IFtdO1xuICAgICQoc2VsZi5zZWxlY3RvcikuZWFjaChmdW5jdGlvbiAoaW5kZXgsIGRvbU5vZGUpIHtcblx0dmFyIG4gPSBzZWxmLmludGVycHJldFNwZWMoc2VsZi5mcmFnbWVudFNwZWMpO1xuXHRuLmNsYXNzTGlzdC5hZGQoc2VsZi5mcmFnbWVudENsYXNzKTtcblx0ZG9tTm9kZS5hcHBlbmRDaGlsZChuKTtcblx0bm9kZXMucHVzaChuKTtcbiAgICB9KTtcbiAgICByZXR1cm4gbm9kZXM7XG59O1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxubW9kdWxlLmV4cG9ydHMuc3Bhd25ET01Ecml2ZXIgPSBzcGF3bkRPTURyaXZlcjtcbm1vZHVsZS5leHBvcnRzLmRlZmF1bHRXcmFwRnVuY3Rpb24gPSBkZWZhdWx0V3JhcEZ1bmN0aW9uO1xuIiwiLy8gSlF1ZXJ5IGV2ZW50IGRyaXZlclxudmFyIE1pbmltYXJ0ID0gcmVxdWlyZShcIi4vbWluaW1hcnQuanNcIik7XG52YXIgV29ybGQgPSBNaW5pbWFydC5Xb3JsZDtcbnZhciBzdWIgPSBNaW5pbWFydC5zdWI7XG52YXIgcHViID0gTWluaW1hcnQucHViO1xudmFyIF9fID0gTWluaW1hcnQuX187XG52YXIgXyQgPSBNaW5pbWFydC5fJDtcblxuZnVuY3Rpb24gc3Bhd25KUXVlcnlEcml2ZXIoYmFzZVNlbGVjdG9yLCBtZXRhTGV2ZWwsIHdyYXBGdW5jdGlvbikge1xuICAgIG1ldGFMZXZlbCA9IG1ldGFMZXZlbCB8fCAwO1xuICAgIHdyYXBGdW5jdGlvbiA9IHdyYXBGdW5jdGlvbiB8fCBkZWZhdWx0V3JhcEZ1bmN0aW9uO1xuICAgIHZhciBkID0gbmV3IE1pbmltYXJ0LkRlbWFuZE1hdGNoZXIod3JhcEZ1bmN0aW9uKF8kLCBfJCwgX18pLCBtZXRhTGV2ZWwsXG5cdFx0XHRcdCAgICAgICB7ZGVtYW5kU2lkZUlzU3Vic2NyaXB0aW9uOiB0cnVlfSk7XG4gICAgZC5vbkRlbWFuZEluY3JlYXNlID0gZnVuY3Rpb24gKGNhcHR1cmVzKSB7XG5cdHZhciBzZWxlY3RvciA9IGNhcHR1cmVzWzBdO1xuXHR2YXIgZXZlbnROYW1lID0gY2FwdHVyZXNbMV07XG5cdFdvcmxkLnNwYXduKG5ldyBKUXVlcnlFdmVudFJvdXRlcihiYXNlU2VsZWN0b3IsXG5cdFx0XHRcdFx0ICBzZWxlY3Rvcixcblx0XHRcdFx0XHQgIGV2ZW50TmFtZSxcblx0XHRcdFx0XHQgIG1ldGFMZXZlbCxcblx0XHRcdFx0XHQgIHdyYXBGdW5jdGlvbiksXG5cdFx0ICAgIFtwdWIod3JhcEZ1bmN0aW9uKHNlbGVjdG9yLCBldmVudE5hbWUsIF9fKSwgbWV0YUxldmVsKSxcblx0XHQgICAgIHB1Yih3cmFwRnVuY3Rpb24oc2VsZWN0b3IsIGV2ZW50TmFtZSwgX18pLCBtZXRhTGV2ZWwsIDEpXSk7XG4gICAgfTtcbiAgICBXb3JsZC5zcGF3bihkKTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdFdyYXBGdW5jdGlvbihzZWxlY3RvciwgZXZlbnROYW1lLCBldmVudFZhbHVlKSB7XG4gICAgcmV0dXJuIFtcImpRdWVyeVwiLCBzZWxlY3RvciwgZXZlbnROYW1lLCBldmVudFZhbHVlXTtcbn1cblxuZnVuY3Rpb24gSlF1ZXJ5RXZlbnRSb3V0ZXIoYmFzZVNlbGVjdG9yLCBzZWxlY3RvciwgZXZlbnROYW1lLCBtZXRhTGV2ZWwsIHdyYXBGdW5jdGlvbikge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB0aGlzLmJhc2VTZWxlY3RvciA9IGJhc2VTZWxlY3RvciB8fCBudWxsO1xuICAgIHRoaXMuc2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICB0aGlzLmV2ZW50TmFtZSA9IGV2ZW50TmFtZTtcbiAgICB0aGlzLm1ldGFMZXZlbCA9IG1ldGFMZXZlbCB8fCAwO1xuICAgIHRoaXMud3JhcEZ1bmN0aW9uID0gd3JhcEZ1bmN0aW9uIHx8IGRlZmF1bHRXcmFwRnVuY3Rpb247XG4gICAgdGhpcy5wcmV2ZW50RGVmYXVsdCA9ICh0aGlzLmV2ZW50TmFtZS5jaGFyQXQoMCkgIT09IFwiK1wiKTtcbiAgICB0aGlzLmhhbmRsZXIgPVxuXHRXb3JsZC53cmFwKGZ1bmN0aW9uIChlKSB7XG5cdCAgICBXb3JsZC5zZW5kKHNlbGYud3JhcEZ1bmN0aW9uKHNlbGYuc2VsZWN0b3IsIHNlbGYuZXZlbnROYW1lLCBlKSwgc2VsZi5tZXRhTGV2ZWwpO1xuXHQgICAgaWYgKHNlbGYucHJldmVudERlZmF1bHQpIGUucHJldmVudERlZmF1bHQoKTtcblx0ICAgIHJldHVybiAhc2VsZi5wcmV2ZW50RGVmYXVsdDtcblx0fSk7XG4gICAgdGhpcy5jb21wdXRlTm9kZXMoKS5vbih0aGlzLnByZXZlbnREZWZhdWx0ID8gdGhpcy5ldmVudE5hbWUgOiB0aGlzLmV2ZW50TmFtZS5zdWJzdHJpbmcoMSksXG5cdFx0XHQgICB0aGlzLmhhbmRsZXIpO1xufVxuXG5KUXVlcnlFdmVudFJvdXRlci5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAoZSkge1xuICAgIGlmIChlLnR5cGUgPT09IFwicm91dGVzXCIgJiYgZS5nZXN0YWx0LmlzRW1wdHkoKSkge1xuXHR0aGlzLmNvbXB1dGVOb2RlcygpLm9mZih0aGlzLmV2ZW50TmFtZSwgdGhpcy5oYW5kbGVyKTtcblx0V29ybGQuZXhpdCgpO1xuICAgIH1cbn07XG5cbkpRdWVyeUV2ZW50Um91dGVyLnByb3RvdHlwZS5jb21wdXRlTm9kZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuYmFzZVNlbGVjdG9yKSB7XG5cdHJldHVybiAkKHRoaXMuYmFzZVNlbGVjdG9yKS5jaGlsZHJlbih0aGlzLnNlbGVjdG9yKS5hZGRCYWNrKHRoaXMuc2VsZWN0b3IpO1xuICAgIH0gZWxzZSB7XG5cdHJldHVybiAkKHRoaXMuc2VsZWN0b3IpO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIHNpbXBsaWZ5RE9NRXZlbnQoZSkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIgayBpbiBlKSB7XG5cdHZhciB2ID0gZVtrXTtcblx0aWYgKHR5cGVvZiB2ID09PSAnb2JqZWN0JykgY29udGludWU7XG5cdGlmICh0eXBlb2YgdiA9PT0gJ2Z1bmN0aW9uJykgY29udGludWU7XG5cdGtleXMucHVzaChrKTtcbiAgICB9XG4gICAga2V5cy5zb3J0KCk7XG4gICAgdmFyIHNpbXBsaWZpZWQgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcblx0c2ltcGxpZmllZC5wdXNoKFtrZXlzW2ldLCBlW2tleXNbaV1dXSk7XG4gICAgfVxuICAgIHJldHVybiBzaW1wbGlmaWVkO1xufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxubW9kdWxlLmV4cG9ydHMuc3Bhd25KUXVlcnlEcml2ZXIgPSBzcGF3bkpRdWVyeURyaXZlcjtcbm1vZHVsZS5leHBvcnRzLnNpbXBsaWZ5RE9NRXZlbnQgPSBzaW1wbGlmeURPTUV2ZW50O1xubW9kdWxlLmV4cG9ydHMuZGVmYXVsdFdyYXBGdW5jdGlvbiA9IGRlZmF1bHRXcmFwRnVuY3Rpb247XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL21pbmltYXJ0LmpzXCIpO1xuXG5tb2R1bGUuZXhwb3J0cy5ET00gPSByZXF1aXJlKFwiLi9kb20tZHJpdmVyLmpzXCIpO1xubW9kdWxlLmV4cG9ydHMuSlF1ZXJ5ID0gcmVxdWlyZShcIi4vanF1ZXJ5LWRyaXZlci5qc1wiKTtcbm1vZHVsZS5leHBvcnRzLlJvdXRpbmdUYWJsZVdpZGdldCA9IHJlcXVpcmUoXCIuL3JvdXRpbmctdGFibGUtd2lkZ2V0LmpzXCIpO1xubW9kdWxlLmV4cG9ydHMuV2ViU29ja2V0ID0gcmVxdWlyZShcIi4vd2Vic29ja2V0LWRyaXZlci5qc1wiKTtcbm1vZHVsZS5leHBvcnRzLlJlZmxlY3QgPSByZXF1aXJlKFwiLi9yZWZsZWN0LmpzXCIpO1xuXG5tb2R1bGUuZXhwb3J0cy5TcHkgPSByZXF1aXJlKFwiLi9zcHkuanNcIikuU3B5O1xubW9kdWxlLmV4cG9ydHMuV2FrZURldGVjdG9yID0gcmVxdWlyZShcIi4vd2FrZS1kZXRlY3Rvci5qc1wiKS5XYWtlRGV0ZWN0b3I7XG5tb2R1bGUuZXhwb3J0cy5BY3RvciA9IHJlcXVpcmUoXCIuL2FjdG9yLmpzXCIpLkFjdG9yO1xuIiwidmFyIFJvdXRlID0gcmVxdWlyZShcIi4vcm91dGUuanNcIik7XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4vLyBUT0RPOiB0cmlnZ2VyLWd1YXJkcyBhcyBwZXIgbWluaW1hcnRcblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuLyogRXZlbnRzIGFuZCBBY3Rpb25zICovXG5cbnZhciBfXyA9IFJvdXRlLl9fO1xudmFyIF8kID0gUm91dGUuXyQ7XG5cbmZ1bmN0aW9uIHN1YihwYXR0ZXJuLCBtZXRhTGV2ZWwsIGxldmVsKSB7XG4gICAgcmV0dXJuIFJvdXRlLnNpbXBsZUdlc3RhbHQoZmFsc2UsIHBhdHRlcm4sIG1ldGFMZXZlbCwgbGV2ZWwpO1xufVxuXG5mdW5jdGlvbiBwdWIocGF0dGVybiwgbWV0YUxldmVsLCBsZXZlbCkge1xuICAgIHJldHVybiBSb3V0ZS5zaW1wbGVHZXN0YWx0KHRydWUsIHBhdHRlcm4sIG1ldGFMZXZlbCwgbGV2ZWwpO1xufVxuXG5mdW5jdGlvbiBzcGF3bihiZWhhdmlvciwgaW5pdGlhbEdlc3RhbHRzKSB7XG4gICAgcmV0dXJuIHsgdHlwZTogXCJzcGF3blwiLFxuXHQgICAgIGJlaGF2aW9yOiBiZWhhdmlvcixcblx0ICAgICBpbml0aWFsR2VzdGFsdDogUm91dGUuZ2VzdGFsdFVuaW9uKGluaXRpYWxHZXN0YWx0cyB8fCBbXSkgfTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlUm91dGVzKGdlc3RhbHRzKSB7XG4gICAgcmV0dXJuIHsgdHlwZTogXCJyb3V0ZXNcIiwgZ2VzdGFsdDogUm91dGUuZ2VzdGFsdFVuaW9uKGdlc3RhbHRzKSB9O1xufVxuXG5mdW5jdGlvbiBwZW5kaW5nUm91dGluZ1VwZGF0ZShhZ2dyZWdhdGUsIGFmZmVjdGVkU3ViZ2VzdGFsdCwga25vd25UYXJnZXQpIHtcbiAgICByZXR1cm4geyB0eXBlOiBcInBlbmRpbmdSb3V0aW5nVXBkYXRlXCIsXG5cdCAgICAgYWdncmVnYXRlOiBhZ2dyZWdhdGUsXG5cdCAgICAgYWZmZWN0ZWRTdWJnZXN0YWx0OiBhZmZlY3RlZFN1Ymdlc3RhbHQsXG5cdCAgICAga25vd25UYXJnZXQ6IGtub3duVGFyZ2V0IH07XG59XG5cbmZ1bmN0aW9uIHNlbmRNZXNzYWdlKG0sIG1ldGFMZXZlbCwgaXNGZWVkYmFjaykge1xuICAgIHJldHVybiB7IHR5cGU6IFwibWVzc2FnZVwiLFxuXHQgICAgIG1ldGFMZXZlbDogKG1ldGFMZXZlbCA9PT0gdW5kZWZpbmVkKSA/IDAgOiBtZXRhTGV2ZWwsXG5cdCAgICAgbWVzc2FnZTogbSxcblx0ICAgICBpc0ZlZWRiYWNrOiAoaXNGZWVkYmFjayA9PT0gdW5kZWZpbmVkKSA/IGZhbHNlIDogaXNGZWVkYmFjayB9O1xufVxuXG5mdW5jdGlvbiBzaHV0ZG93bldvcmxkKCkge1xuICAgIHJldHVybiB7IHR5cGU6IFwic2h1dGRvd25Xb3JsZFwiIH07XG59XG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cbi8qIENvbmZpZ3VyYXRpb25zICovXG5cbmZ1bmN0aW9uIFdvcmxkKGJvb3RGbikge1xuICAgIHRoaXMuYWxpdmUgPSB0cnVlO1xuICAgIHRoaXMuZXZlbnRRdWV1ZSA9IFtdO1xuICAgIHRoaXMucnVubmFibGVQaWRzID0ge307XG4gICAgdGhpcy5wYXJ0aWFsR2VzdGFsdCA9IFJvdXRlLmVtcHR5R2VzdGFsdDsgLy8gT25seSBnZXN0YWx0IGZyb20gbG9jYWwgcHJvY2Vzc2VzXG4gICAgdGhpcy5mdWxsR2VzdGFsdCA9IFJvdXRlLmVtcHR5R2VzdGFsdCA7OyAvLyBwYXJ0aWFsR2VzdGFsdCB1bmlvbmVkIHdpdGggZG93bndhcmRHZXN0YWx0XG4gICAgdGhpcy5wcm9jZXNzVGFibGUgPSB7fTtcbiAgICB0aGlzLnRvbWJzdG9uZXMgPSB7fTtcbiAgICB0aGlzLmRvd253YXJkR2VzdGFsdCA9IFJvdXRlLmVtcHR5R2VzdGFsdDtcbiAgICB0aGlzLnByb2Nlc3NBY3Rpb25zID0gW107XG4gICAgdGhpcy5hc0NoaWxkKC0xLCBib290Rm4sIHRydWUpO1xufVxuXG4vKiBDbGFzcyBzdGF0ZSAvIG1ldGhvZHMgKi9cblxuV29ybGQubmV4dFBpZCA9IDA7XG5cbldvcmxkLnN0YWNrID0gW107XG5cbldvcmxkLmN1cnJlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIFdvcmxkLnN0YWNrW1dvcmxkLnN0YWNrLmxlbmd0aCAtIDFdWzBdO1xufTtcblxuV29ybGQuYWN0aXZlUGlkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBXb3JsZC5zdGFja1tXb3JsZC5zdGFjay5sZW5ndGggLSAxXVsxXTtcbn07XG5cbldvcmxkLnNlbmQgPSBmdW5jdGlvbiAobSwgbWV0YUxldmVsLCBpc0ZlZWRiYWNrKSB7XG4gICAgV29ybGQuY3VycmVudCgpLmVucXVldWVBY3Rpb24oV29ybGQuYWN0aXZlUGlkKCksIHNlbmRNZXNzYWdlKG0sIG1ldGFMZXZlbCwgaXNGZWVkYmFjaykpO1xufTtcblxuV29ybGQudXBkYXRlUm91dGVzID0gZnVuY3Rpb24gKGdlc3RhbHRzKSB7XG4gICAgV29ybGQuY3VycmVudCgpLmVucXVldWVBY3Rpb24oV29ybGQuYWN0aXZlUGlkKCksIHVwZGF0ZVJvdXRlcyhnZXN0YWx0cykpO1xufTtcblxuV29ybGQuc3Bhd24gPSBmdW5jdGlvbiAoYmVoYXZpb3IsIGluaXRpYWxHZXN0YWx0cykge1xuICAgIFdvcmxkLmN1cnJlbnQoKS5lbnF1ZXVlQWN0aW9uKFdvcmxkLmFjdGl2ZVBpZCgpLCBzcGF3bihiZWhhdmlvciwgaW5pdGlhbEdlc3RhbHRzKSk7XG59O1xuXG5Xb3JsZC5leGl0ID0gZnVuY3Rpb24gKGV4bikge1xuICAgIFdvcmxkLmN1cnJlbnQoKS5raWxsKFdvcmxkLmFjdGl2ZVBpZCgpLCBleG4pO1xufTtcblxuV29ybGQuc2h1dGRvd25Xb3JsZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBXb3JsZC5jdXJyZW50KCkuZW5xdWV1ZUFjdGlvbihXb3JsZC5hY3RpdmVQaWQoKSwgc2h1dGRvd25Xb3JsZCgpKTtcbn07XG5cbldvcmxkLndpdGhXb3JsZFN0YWNrID0gZnVuY3Rpb24gKHN0YWNrLCBmKSB7XG4gICAgdmFyIG9sZFN0YWNrID0gV29ybGQuc3RhY2s7XG4gICAgV29ybGQuc3RhY2sgPSBzdGFjaztcbiAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICB0cnkge1xuXHRyZXN1bHQgPSBmKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuXHRXb3JsZC5zdGFjayA9IG9sZFN0YWNrO1xuXHR0aHJvdyBlO1xuICAgIH1cbiAgICBXb3JsZC5zdGFjayA9IG9sZFN0YWNrO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xuXG5Xb3JsZC53cmFwID0gZnVuY3Rpb24gKGYpIHtcbiAgICB2YXIgc2F2ZWRTdGFjayA9IFdvcmxkLnN0YWNrLnNsaWNlKCk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcblx0dmFyIGFjdHVhbHMgPSBhcmd1bWVudHM7XG5cdHJldHVybiBXb3JsZC53aXRoV29ybGRTdGFjayhzYXZlZFN0YWNrLCBmdW5jdGlvbiAoKSB7XG5cdCAgICB2YXIgcmVzdWx0ID0gV29ybGQuY3VycmVudCgpLmFzQ2hpbGQoV29ybGQuYWN0aXZlUGlkKCksIGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gZi5hcHBseShudWxsLCBhY3R1YWxzKTtcblx0ICAgIH0pO1xuXHQgICAgZm9yICh2YXIgaSA9IFdvcmxkLnN0YWNrLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG5cdFx0V29ybGQuc3RhY2tbaV1bMF0ubWFya1BpZFJ1bm5hYmxlKFdvcmxkLnN0YWNrW2ldWzFdKTtcblx0ICAgIH1cblx0ICAgIHJldHVybiByZXN1bHQ7XG5cdH0pO1xuICAgIH07XG59O1xuXG4vKiBJbnN0YW5jZSBtZXRob2RzICovXG5cbldvcmxkLnByb3RvdHlwZS5lbnF1ZXVlQWN0aW9uID0gZnVuY3Rpb24gKHBpZCwgYWN0aW9uKSB7XG4gICAgdGhpcy5wcm9jZXNzQWN0aW9ucy5wdXNoKFtwaWQsIGFjdGlvbl0pO1xufTtcblxuLy8gVGhlIGNvZGUgaXMgd3JpdHRlbiB0byBtYWludGFpbiB0aGUgcnVubmFibGVQaWRzIHNldCBjYXJlZnVsbHksIHRvXG4vLyBlbnN1cmUgd2UgY2FuIGxvY2FsbHkgZGVjaWRlIHdoZXRoZXIgd2UncmUgaW5lcnQgb3Igbm90IHdpdGhvdXRcbi8vIGhhdmluZyB0byBzZWFyY2ggdGhlIHdob2xlIGRlZXAgcHJvY2VzcyB0cmVlLlxuV29ybGQucHJvdG90eXBlLmlzSW5lcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZXZlbnRRdWV1ZS5sZW5ndGggPT09IDBcblx0JiYgdGhpcy5wcm9jZXNzQWN0aW9ucy5sZW5ndGggPT09IDBcblx0JiYgUm91dGUuaXNfZW1wdHlTZXQodGhpcy5ydW5uYWJsZVBpZHMpO1xufTtcblxuV29ybGQucHJvdG90eXBlLm1hcmtQaWRSdW5uYWJsZSA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgICB0aGlzLnJ1bm5hYmxlUGlkc1twaWRdID0gW3BpZF07XG59O1xuXG5Xb3JsZC5wcm90b3R5cGUuc3RlcCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnRzKCk7XG4gICAgdGhpcy5wZXJmb3JtQWN0aW9ucygpO1xuICAgIHRoaXMuc3RlcENoaWxkcmVuKCk7XG4gICAgcmV0dXJuIHRoaXMuYWxpdmUgJiYgIXRoaXMuaXNJbmVydCgpO1xufTtcblxuV29ybGQucHJvdG90eXBlLmFzQ2hpbGQgPSBmdW5jdGlvbiAocGlkLCBmLCBvbWl0TGl2ZW5lc3NDaGVjaykge1xuICAgIGlmICghKHBpZCBpbiB0aGlzLnByb2Nlc3NUYWJsZSkgJiYgIW9taXRMaXZlbmVzc0NoZWNrKSB7XG5cdGNvbnNvbGUud2FybihcIldvcmxkLmFzQ2hpbGQgZWxpZGluZyBpbnZvY2F0aW9uIG9mIGRlYWQgcHJvY2Vzc1wiLCBwaWQpO1xuXHRyZXR1cm47XG4gICAgfVxuXG4gICAgV29ybGQuc3RhY2sucHVzaChbdGhpcywgcGlkXSk7XG4gICAgdmFyIHJlc3VsdCA9IG51bGw7XG4gICAgdHJ5IHtcblx0cmVzdWx0ID0gZigpO1xuICAgIH0gY2F0Y2ggKGUpIHtcblx0dGhpcy5raWxsKHBpZCwgZSk7XG4gICAgfVxuICAgIGlmIChXb3JsZC5zdGFjay5wb3AoKVswXSAhPT0gdGhpcykge1xuXHR0aHJvdyBuZXcgRXJyb3IoXCJJbnRlcm5hbCBlcnJvcjogV29ybGQgc3RhY2sgaW1iYWxhbmNlXCIpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufTtcblxuV29ybGQucHJvdG90eXBlLmtpbGwgPSBmdW5jdGlvbiAocGlkLCBleG4pIHtcbiAgICBpZiAoZXhuICYmIGV4bi5zdGFjaykge1xuXHRjb25zb2xlLmxvZyhcIlByb2Nlc3MgZXhpdGVkXCIsIHBpZCwgZXhuLCBleG4uc3RhY2spO1xuICAgIH0gZWxzZSB7XG5cdGNvbnNvbGUubG9nKFwiUHJvY2VzcyBleGl0ZWRcIiwgcGlkLCBleG4pO1xuICAgIH1cbiAgICB2YXIgcCA9IHRoaXMucHJvY2Vzc1RhYmxlW3BpZF07XG4gICAgaWYgKHAgJiYgcC5iZWhhdmlvci50cmFwZXhpdCkge1xuXHR0aGlzLmFzQ2hpbGQocGlkLCBmdW5jdGlvbiAoKSB7IHJldHVybiBwLmJlaGF2aW9yLnRyYXBleGl0KGV4bik7IH0pO1xuICAgIH1cbiAgICBkZWxldGUgdGhpcy5wcm9jZXNzVGFibGVbcGlkXTtcbiAgICBpZiAocCkge1xuXHRpZiAoZXhuKSB7XG5cdCAgICBwLmV4aXRSZWFzb24gPSBleG47XG5cdCAgICB0aGlzLnRvbWJzdG9uZXNbcGlkXSA9IHA7XG5cdH1cblx0dGhpcy5hcHBseUFuZElzc3VlUm91dGluZ1VwZGF0ZShwLmdlc3RhbHQsIFJvdXRlLmVtcHR5R2VzdGFsdCk7XG4gICAgfVxufTtcblxuV29ybGQucHJvdG90eXBlLnN0ZXBDaGlsZHJlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcGlkcyA9IHRoaXMucnVubmFibGVQaWRzO1xuICAgIHRoaXMucnVubmFibGVQaWRzID0ge307XG4gICAgZm9yICh2YXIgcGlkIGluIHBpZHMpIHtcblx0dmFyIHAgPSB0aGlzLnByb2Nlc3NUYWJsZVtwaWRdO1xuXHRpZiAocCAmJiBwLmJlaGF2aW9yLnN0ZXAgLyogZXhpc3RzLCBoYXZlbid0IGNhbGxlZCBpdCB5ZXQgKi8pIHtcblx0ICAgIHZhciBjaGlsZEJ1c3kgPSB0aGlzLmFzQ2hpbGQocGlkIHwgMCwgZnVuY3Rpb24gKCkgeyByZXR1cm4gcC5iZWhhdmlvci5zdGVwKCkgfSk7XG5cdCAgICBpZiAoY2hpbGRCdXN5KSB0aGlzLm1hcmtQaWRSdW5uYWJsZShwaWQpO1xuXHR9XG4gICAgfVxufTtcblxuV29ybGQucHJvdG90eXBlLnBlcmZvcm1BY3Rpb25zID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBxdWV1ZSA9IHRoaXMucHJvY2Vzc0FjdGlvbnM7XG4gICAgdGhpcy5wcm9jZXNzQWN0aW9ucyA9IFtdO1xuICAgIHZhciBpdGVtO1xuICAgIHdoaWxlICgoaXRlbSA9IHF1ZXVlLnNoaWZ0KCkpICYmIHRoaXMuYWxpdmUpIHtcblx0dGhpcy5wZXJmb3JtQWN0aW9uKGl0ZW1bMF0sIGl0ZW1bMV0pO1xuICAgIH1cbn07XG5cbldvcmxkLnByb3RvdHlwZS5kaXNwYXRjaEV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcXVldWUgPSB0aGlzLmV2ZW50UXVldWU7XG4gICAgdGhpcy5ldmVudFF1ZXVlID0gW107XG4gICAgdmFyIGl0ZW07XG4gICAgd2hpbGUgKChpdGVtID0gcXVldWUuc2hpZnQoKSkpIHtcblx0dGhpcy5kaXNwYXRjaEV2ZW50KGl0ZW0pO1xuICAgIH1cbn07XG5cbldvcmxkLnByb3RvdHlwZS5wZXJmb3JtQWN0aW9uID0gZnVuY3Rpb24gKHBpZCwgYWN0aW9uKSB7XG4gICAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgIGNhc2UgXCJzcGF3blwiOlxuXHR2YXIgcGlkID0gV29ybGQubmV4dFBpZCsrO1xuXHR2YXIgbmV3R2VzdGFsdCA9IGFjdGlvbi5pbml0aWFsR2VzdGFsdC5sYWJlbChwaWQpO1xuXHR0aGlzLnByb2Nlc3NUYWJsZVtwaWRdID0geyBnZXN0YWx0OiBuZXdHZXN0YWx0LCBiZWhhdmlvcjogYWN0aW9uLmJlaGF2aW9yIH07XG5cdGlmIChhY3Rpb24uYmVoYXZpb3IuYm9vdCkge1xuXHQgICAgdGhpcy5hc0NoaWxkKHBpZCwgZnVuY3Rpb24gKCkgeyBhY3Rpb24uYmVoYXZpb3IuYm9vdCgpIH0pO1xuXHQgICAgdGhpcy5tYXJrUGlkUnVubmFibGUocGlkKTtcblx0fVxuXHR0aGlzLmFwcGx5QW5kSXNzdWVSb3V0aW5nVXBkYXRlKFJvdXRlLmVtcHR5R2VzdGFsdCwgbmV3R2VzdGFsdCwgcGlkKTtcblx0YnJlYWs7XG4gICAgY2FzZSBcInJvdXRlc1wiOlxuXHRpZiAocGlkIGluIHRoaXMucHJvY2Vzc1RhYmxlKSB7XG5cdCAgICAvLyBpdCBtYXkgbm90IGJlOiB0aGlzIG1pZ2h0IGJlIHRoZSByb3V0aW5nIHVwZGF0ZSBmcm9tIGFcblx0ICAgIC8vIGtpbGwgb2YgdGhlIHByb2Nlc3Ncblx0ICAgIHZhciBvbGRHZXN0YWx0ID0gdGhpcy5wcm9jZXNzVGFibGVbcGlkXS5nZXN0YWx0O1xuXHQgICAgdmFyIG5ld0dlc3RhbHQgPSBhY3Rpb24uZ2VzdGFsdC5sYWJlbChwaWR8MCk7XG5cdCAgICAvLyBeIHBpZHwwOiBjb252ZXJ0IHBpZCBmcm9tIHN0cmluZyAodGFibGUga2V5ISkgdG8gaW50ZWdlclxuXHQgICAgdGhpcy5wcm9jZXNzVGFibGVbcGlkXS5nZXN0YWx0ID0gbmV3R2VzdGFsdDtcblx0ICAgIHRoaXMuYXBwbHlBbmRJc3N1ZVJvdXRpbmdVcGRhdGUob2xkR2VzdGFsdCwgbmV3R2VzdGFsdCwgcGlkKTtcblx0fVxuXHRicmVhaztcbiAgICBjYXNlIFwibWVzc2FnZVwiOlxuXHRpZiAoYWN0aW9uLm1ldGFMZXZlbCA9PT0gMCkge1xuXHQgICAgdGhpcy5ldmVudFF1ZXVlLnB1c2goYWN0aW9uKTtcblx0fSBlbHNlIHtcblx0ICAgIFdvcmxkLnNlbmQoYWN0aW9uLm1lc3NhZ2UsIGFjdGlvbi5tZXRhTGV2ZWwgLSAxLCBhY3Rpb24uaXNGZWVkYmFjayk7XG5cdH1cblx0YnJlYWs7XG4gICAgY2FzZSBcInNodXRkb3duV29ybGRcIjpcblx0dGhpcy5hbGl2ZSA9IGZhbHNlOyAvLyBmb3JjZSB1cyB0byBzdG9wIGRvaW5nIHRoaW5ncyBpbW1lZGlhdGVseVxuXHRXb3JsZC5leGl0KCk7XG5cdGJyZWFrO1xuICAgIGRlZmF1bHQ6XG5cdHZhciBleG4gPSBuZXcgRXJyb3IoXCJBY3Rpb24gdHlwZSBcIiArIGFjdGlvbi50eXBlICsgXCIgbm90IHVuZGVyc3Rvb2RcIik7XG5cdGV4bi5hY3Rpb24gPSBhY3Rpb247XG5cdHRocm93IGV4bjtcbiAgICB9XG59O1xuXG5Xb3JsZC5wcm90b3R5cGUudXBkYXRlRnVsbEdlc3RhbHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdWxsR2VzdGFsdCA9IHRoaXMucGFydGlhbEdlc3RhbHQudW5pb24odGhpcy5kb3dud2FyZEdlc3RhbHQpO1xufTtcblxuV29ybGQucHJvdG90eXBlLmlzc3VlTG9jYWxSb3V0aW5nVXBkYXRlID0gZnVuY3Rpb24gKGFmZmVjdGVkU3ViZ2VzdGFsdCwga25vd25UYXJnZXQpIHtcbiAgICB0aGlzLmV2ZW50UXVldWUucHVzaChwZW5kaW5nUm91dGluZ1VwZGF0ZSh0aGlzLmZ1bGxHZXN0YWx0LFxuXHRcdFx0XHRcdCAgICAgIGFmZmVjdGVkU3ViZ2VzdGFsdCxcblx0XHRcdFx0XHQgICAgICBrbm93blRhcmdldCkpO1xufTtcblxuV29ybGQucHJvdG90eXBlLmFwcGx5QW5kSXNzdWVSb3V0aW5nVXBkYXRlID0gZnVuY3Rpb24gKG9sZGcsIG5ld2csIGtub3duVGFyZ2V0KSB7XG4gICAga25vd25UYXJnZXQgPSB0eXBlb2Yga25vd25UYXJnZXQgPT09ICd1bmRlZmluZWQnID8gbnVsbCA6IGtub3duVGFyZ2V0O1xuICAgIHRoaXMucGFydGlhbEdlc3RhbHQgPSB0aGlzLnBhcnRpYWxHZXN0YWx0LmVyYXNlUGF0aChvbGRnKS51bmlvbihuZXdnKTtcbiAgICB0aGlzLnVwZGF0ZUZ1bGxHZXN0YWx0KCk7XG4gICAgdGhpcy5pc3N1ZUxvY2FsUm91dGluZ1VwZGF0ZShvbGRnLnVuaW9uKG5ld2cpLCBrbm93blRhcmdldCk7XG4gICAgV29ybGQudXBkYXRlUm91dGVzKFt0aGlzLnBhcnRpYWxHZXN0YWx0LmRyb3AoKV0pO1xufTtcblxuV29ybGQucHJvdG90eXBlLmRpc3BhdGNoRXZlbnQgPSBmdW5jdGlvbiAoZSkge1xuICAgIHN3aXRjaCAoZS50eXBlKSB7XG4gICAgY2FzZSBcInBlbmRpbmdSb3V0aW5nVXBkYXRlXCI6XG5cdHZhciBwaWRzID0gZS5hZmZlY3RlZFN1Ymdlc3RhbHQubWF0Y2goZS5hZ2dyZWdhdGUpO1xuXHRpZiAoZS5rbm93blRhcmdldCAhPT0gbnVsbCkgcGlkcy51bnNoaWZ0KGUua25vd25UYXJnZXQpO1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IHBpZHMubGVuZ3RoOyBpKyspIHtcblx0ICAgIHZhciBwaWQgPSBwaWRzW2ldO1xuXHQgICAgaWYgKHBpZCA9PT0gXCJvdXRcIikgY29uc29sZS53YXJuKFwiV291bGQgaGF2ZSBkZWxpdmVyZWQgYSByb3V0aW5nIHVwZGF0ZSB0byBlbnZpcm9ubWVudFwiKTtcblx0ICAgIHZhciBwID0gdGhpcy5wcm9jZXNzVGFibGVbcGlkXTtcblx0ICAgIGlmIChwKSB7XG5cdFx0dmFyIGcgPSBlLmFnZ3JlZ2F0ZS5maWx0ZXIocC5nZXN0YWx0KTtcblx0XHR0aGlzLmFzQ2hpbGQocGlkLCBmdW5jdGlvbiAoKSB7IHAuYmVoYXZpb3IuaGFuZGxlRXZlbnQodXBkYXRlUm91dGVzKFtnXSkpIH0pO1xuXHRcdHRoaXMubWFya1BpZFJ1bm5hYmxlKHBpZCk7XG5cdCAgICB9XG5cdH1cblx0YnJlYWs7XG5cbiAgICBjYXNlIFwibWVzc2FnZVwiOlxuXHR2YXIgcGlkcyA9IHRoaXMucGFydGlhbEdlc3RhbHQubWF0Y2hWYWx1ZShlLm1lc3NhZ2UsIGUubWV0YUxldmVsLCBlLmlzRmVlZGJhY2spO1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IHBpZHMubGVuZ3RoOyBpKyspIHtcblx0ICAgIHZhciBwaWQgPSBwaWRzW2ldO1xuXHQgICAgdmFyIHAgPSB0aGlzLnByb2Nlc3NUYWJsZVtwaWRdO1xuXHQgICAgdGhpcy5hc0NoaWxkKHBpZCwgZnVuY3Rpb24gKCkgeyBwLmJlaGF2aW9yLmhhbmRsZUV2ZW50KGUpIH0pO1xuXHQgICAgdGhpcy5tYXJrUGlkUnVubmFibGUocGlkKTtcblx0fVxuXHRicmVhaztcblxuICAgIGRlZmF1bHQ6XG5cdHZhciBleG4gPSBuZXcgRXJyb3IoXCJFdmVudCB0eXBlIFwiICsgZS50eXBlICsgXCIgbm90IGRpc3BhdGNoYWJsZVwiKTtcblx0ZXhuLmV2ZW50ID0gZTtcblx0dGhyb3cgZXhuO1xuICAgIH1cbn07XG5cbldvcmxkLnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgc3dpdGNoIChlLnR5cGUpIHtcbiAgICBjYXNlIFwicm91dGVzXCI6XG5cdHZhciBvbGREb3dud2FyZCA9IHRoaXMuZG93bndhcmRHZXN0YWx0O1xuXHR0aGlzLmRvd253YXJkR2VzdGFsdCA9IGUuZ2VzdGFsdC5sYWJlbChcIm91dFwiKS5saWZ0KCk7XG5cdHRoaXMudXBkYXRlRnVsbEdlc3RhbHQoKTtcblx0dGhpcy5pc3N1ZUxvY2FsUm91dGluZ1VwZGF0ZShvbGREb3dud2FyZC51bmlvbih0aGlzLmRvd253YXJkR2VzdGFsdCksIG51bGwpO1xuXHRicmVhaztcbiAgICBjYXNlIFwibWVzc2FnZVwiOlxuXHR0aGlzLmV2ZW50UXVldWUucHVzaChzZW5kTWVzc2FnZShlLm1lc3NhZ2UsIGUubWV0YUxldmVsICsgMSwgZS5pc0ZlZWRiYWNrKSk7XG5cdGJyZWFrO1xuICAgIGRlZmF1bHQ6XG5cdHZhciBleG4gPSBuZXcgRXJyb3IoXCJFdmVudCB0eXBlIFwiICsgZS50eXBlICsgXCIgbm90IHVuZGVyc3Rvb2RcIik7XG5cdGV4bi5ldmVudCA9IGU7XG5cdHRocm93IGV4bjtcbiAgICB9XG59O1xuXG4vKiBEZWJ1Z2dpbmcsIG1hbmFnZW1lbnQsIGFuZCBtb25pdG9yaW5nICovXG5cbldvcmxkLnByb3RvdHlwZS5wcm9jZXNzVHJlZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIga2lkcyA9IFtdO1xuICAgIGZvciAodmFyIHBpZCBpbiB0aGlzLnByb2Nlc3NUYWJsZSkge1xuXHR2YXIgcCA9IHRoaXMucHJvY2Vzc1RhYmxlW3BpZF07XG5cdGlmIChwLmJlaGF2aW9yIGluc3RhbmNlb2YgV29ybGQpIHtcblx0ICAgIGtpZHMucHVzaChbcGlkLCBwLmJlaGF2aW9yLnByb2Nlc3NUcmVlKCldKTtcblx0fSBlbHNlIHtcblx0ICAgIGtpZHMucHVzaChbcGlkLCBwXSk7XG5cdH1cbiAgICB9XG4gICAgZm9yICh2YXIgcGlkIGluIHRoaXMudG9tYnN0b25lcykge1xuXHRraWRzLnB1c2goW3BpZCwgdGhpcy50b21ic3RvbmVzW3BpZF1dKTtcbiAgICB9XG4gICAga2lkcy5zb3J0KCk7XG4gICAgcmV0dXJuIGtpZHM7XG59O1xuXG5Xb3JsZC5wcm90b3R5cGUudGV4dFByb2Nlc3NUcmVlID0gZnVuY3Rpb24gKG93blBpZCkge1xuICAgIHZhciBsaW5lcyA9IFtdO1xuXG4gICAgZnVuY3Rpb24gZHVtcFByb2Nlc3MocHJlZml4LCBwaWQsIHApIHtcblx0aWYgKEFycmF5LmlzQXJyYXkocCkpIHtcblx0ICAgIGxpbmVzLnB1c2gocHJlZml4ICsgJy0tKyAnICsgcGlkKTtcblx0ICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuXHRcdGR1bXBQcm9jZXNzKHByZWZpeCArICcgIHwnLCBwW2ldWzBdLCBwW2ldWzFdKTtcblx0ICAgIH1cblx0ICAgIGxpbmVzLnB1c2gocHJlZml4KTtcblx0fSBlbHNlIHtcblx0ICAgIHZhciBsYWJlbCA9IHAuYmVoYXZpb3IubmFtZSB8fCBwLmJlaGF2aW9yLmNvbnN0cnVjdG9yLm5hbWUgfHwgJyc7XG5cdCAgICB2YXIgdG9tYnN0b25lU3RyaW5nID0gcC5leGl0UmVhc29uID8gJyAoRVhJVEVEOiAnICsgcC5leGl0UmVhc29uICsgJykgJyA6ICcnO1xuXHQgICAgbGluZXMucHVzaChwcmVmaXggKyAnLS0gJyArIHBpZCArICc6ICcgKyBsYWJlbCArXG5cdFx0ICAgICAgIHRvbWJzdG9uZVN0cmluZyArXG5cdFx0ICAgICAgIEpTT04uc3RyaW5naWZ5KHAuYmVoYXZpb3IsIGZ1bmN0aW9uIChrLCB2KSB7XG5cdFx0XHQgICByZXR1cm4gayA9PT0gJ25hbWUnID8gdW5kZWZpbmVkIDogdjtcblx0XHQgICAgICAgfSkpO1xuXHR9XG4gICAgfVxuXG4gICAgZHVtcFByb2Nlc3MoJycsIG93blBpZCB8fCAnJywgdGhpcy5wcm9jZXNzVHJlZSgpKTtcbiAgICByZXR1cm4gbGluZXMuam9pbignXFxuJyk7XG59O1xuXG5Xb3JsZC5wcm90b3R5cGUuY2xlYXJUb21ic3RvbmVzID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMudG9tYnN0b25lcyA9IHt9O1xuICAgIGZvciAodmFyIHBpZCBpbiB0aGlzLnByb2Nlc3NUYWJsZSkge1xuXHR2YXIgcCA9IHRoaXMucHJvY2Vzc1RhYmxlW3BpZF07XG5cdGlmIChwLmJlaGF2aW9yIGluc3RhbmNlb2YgV29ybGQpIHtcblx0ICAgIHAuYmVoYXZpb3IuY2xlYXJUb21ic3RvbmVzKCk7XG5cdH1cbiAgICB9XG59O1xuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG4vKiBVdGlsaXRpZXM6IG1hdGNoaW5nIGRlbWFuZCBmb3Igc29tZSBzZXJ2aWNlICovXG5cbmZ1bmN0aW9uIERlbWFuZE1hdGNoZXIocHJvamVjdGlvbiwgbWV0YUxldmVsLCBvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9ICQuZXh0ZW5kKHtcblx0ZGVtYW5kTGV2ZWw6IDAsXG5cdHN1cHBseUxldmVsOiAwLFxuXHRkZW1hbmRTaWRlSXNTdWJzY3JpcHRpb246IGZhbHNlXG4gICAgfSwgb3B0aW9ucyk7XG4gICAgdGhpcy5wYXR0ZXJuID0gUm91dGUucHJvamVjdGlvblRvUGF0dGVybihwcm9qZWN0aW9uKTtcbiAgICB0aGlzLnByb2plY3Rpb25TcGVjID0gUm91dGUuY29tcGlsZVByb2plY3Rpb24ocHJvamVjdGlvbik7XG4gICAgdGhpcy5tZXRhTGV2ZWwgPSBtZXRhTGV2ZWwgfCAwO1xuICAgIHRoaXMuZGVtYW5kTGV2ZWwgPSBvcHRpb25zLmRlbWFuZExldmVsO1xuICAgIHRoaXMuc3VwcGx5TGV2ZWwgPSBvcHRpb25zLnN1cHBseUxldmVsO1xuICAgIHRoaXMuZGVtYW5kU2lkZUlzU3Vic2NyaXB0aW9uID0gb3B0aW9ucy5kZW1hbmRTaWRlSXNTdWJzY3JpcHRpb247XG4gICAgdGhpcy5vbkRlbWFuZEluY3JlYXNlID0gZnVuY3Rpb24gKGNhcHR1cmVzKSB7XG5cdGNvbnNvbGUuZXJyb3IoXCJVbmhhbmRsZWQgaW5jcmVhc2UgaW4gZGVtYW5kIGZvciByb3V0ZVwiLCBjYXB0dXJlcyk7XG4gICAgfTtcbiAgICB0aGlzLm9uU3VwcGx5RGVjcmVhc2UgPSBmdW5jdGlvbiAoY2FwdHVyZXMpIHtcblx0Y29uc29sZS5lcnJvcihcIlVuaGFuZGxlZCBkZWNyZWFzZSBpbiBzdXBwbHkgZm9yIHJvdXRlXCIsIGNhcHR1cmVzKTtcbiAgICB9O1xuICAgIHRoaXMuY3VycmVudERlbWFuZCA9IHt9O1xuICAgIHRoaXMuY3VycmVudFN1cHBseSA9IHt9O1xufVxuXG5EZW1hbmRNYXRjaGVyLnByb3RvdHlwZS5ib290ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBvYnNlcnZlckxldmVsID0gMSArIE1hdGgubWF4KHRoaXMuZGVtYW5kTGV2ZWwsIHRoaXMuc3VwcGx5TGV2ZWwpO1xuICAgIFdvcmxkLnVwZGF0ZVJvdXRlcyhbc3ViKHRoaXMucGF0dGVybiwgdGhpcy5tZXRhTGV2ZWwsIG9ic2VydmVyTGV2ZWwpLFxuXHRcdFx0cHViKHRoaXMucGF0dGVybiwgdGhpcy5tZXRhTGV2ZWwsIG9ic2VydmVyTGV2ZWwpXSk7XG59O1xuXG5EZW1hbmRNYXRjaGVyLnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKGUudHlwZSA9PT0gXCJyb3V0ZXNcIikge1xuXHR0aGlzLmhhbmRsZUdlc3RhbHQoZS5nZXN0YWx0KTtcbiAgICB9XG59O1xuXG5EZW1hbmRNYXRjaGVyLnByb3RvdHlwZS5oYW5kbGVHZXN0YWx0ID0gZnVuY3Rpb24gKGdlc3RhbHQpIHtcbiAgICB2YXIgbmV3RGVtYW5kTWF0Y2hlciA9IGdlc3RhbHQucHJvamVjdCh0aGlzLnByb2plY3Rpb25TcGVjLFxuXHRcdFx0XHRcdCAgICF0aGlzLmRlbWFuZFNpZGVJc1N1YnNjcmlwdGlvbixcblx0XHRcdFx0XHQgICB0aGlzLm1ldGFMZXZlbCxcblx0XHRcdFx0XHQgICB0aGlzLmRlbWFuZExldmVsKTtcbiAgICB2YXIgbmV3U3VwcGx5TWF0Y2hlciA9IGdlc3RhbHQucHJvamVjdCh0aGlzLnByb2plY3Rpb25TcGVjLFxuXHRcdFx0XHRcdCAgIHRoaXMuZGVtYW5kU2lkZUlzU3Vic2NyaXB0aW9uLFxuXHRcdFx0XHRcdCAgIHRoaXMubWV0YUxldmVsLFxuXHRcdFx0XHRcdCAgIHRoaXMuc3VwcGx5TGV2ZWwpO1xuICAgIHZhciBuZXdEZW1hbmQgPSBSb3V0ZS5hcnJheVRvU2V0KFJvdXRlLm1hdGNoZXJLZXlzKG5ld0RlbWFuZE1hdGNoZXIpKTtcbiAgICB2YXIgbmV3U3VwcGx5ID0gUm91dGUuYXJyYXlUb1NldChSb3V0ZS5tYXRjaGVyS2V5cyhuZXdTdXBwbHlNYXRjaGVyKSk7XG4gICAgdmFyIGRlbWFuZERlbHRhID0gUm91dGUuc2V0U3VidHJhY3QobmV3RGVtYW5kLCB0aGlzLmN1cnJlbnREZW1hbmQpO1xuICAgIHZhciBzdXBwbHlEZWx0YSA9IFJvdXRlLnNldFN1YnRyYWN0KHRoaXMuY3VycmVudFN1cHBseSwgbmV3U3VwcGx5KTtcbiAgICB2YXIgZGVtYW5kSW5jciA9IFJvdXRlLnNldFN1YnRyYWN0KGRlbWFuZERlbHRhLCBuZXdTdXBwbHkpO1xuICAgIHZhciBzdXBwbHlEZWNyID0gUm91dGUuc2V0SW50ZXJzZWN0KHN1cHBseURlbHRhLCBuZXdEZW1hbmQpO1xuICAgIHRoaXMuY3VycmVudERlbWFuZCA9IG5ld0RlbWFuZDtcbiAgICB0aGlzLmN1cnJlbnRTdXBwbHkgPSBuZXdTdXBwbHk7XG4gICAgZm9yICh2YXIgayBpbiBkZW1hbmRJbmNyKSB0aGlzLm9uRGVtYW5kSW5jcmVhc2UoZGVtYW5kSW5jcltrXSk7XG4gICAgZm9yICh2YXIgayBpbiBzdXBwbHlEZWNyKSB0aGlzLm9uU3VwcGx5RGVjcmVhc2Uoc3VwcGx5RGVjcltrXSk7XG59O1xuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG4vKiBVdGlsaXRpZXM6IGRlZHVwbGljYXRvciAqL1xuXG5mdW5jdGlvbiBEZWR1cGxpY2F0b3IodHRsX21zKSB7XG4gICAgdGhpcy50dGxfbXMgPSB0dGxfbXMgfHwgMTAwMDA7XG4gICAgdGhpcy5xdWV1ZSA9IFtdO1xuICAgIHRoaXMubWFwID0ge307XG4gICAgdGhpcy50aW1lcklkID0gbnVsbDtcbn1cblxuRGVkdXBsaWNhdG9yLnByb3RvdHlwZS5hY2NlcHQgPSBmdW5jdGlvbiAobSkge1xuICAgIHZhciBzID0gSlNPTi5zdHJpbmdpZnkobSk7XG4gICAgaWYgKHMgaW4gdGhpcy5tYXApIHJldHVybiBmYWxzZTtcbiAgICB2YXIgZW50cnkgPSBbKCtuZXcgRGF0ZSgpKSArIHRoaXMudHRsX21zLCBzLCBtXTtcbiAgICB0aGlzLm1hcFtzXSA9IGVudHJ5O1xuICAgIHRoaXMucXVldWUucHVzaChlbnRyeSk7XG5cbiAgICBpZiAodGhpcy50aW1lcklkID09PSBudWxsKSB7XG5cdHZhciBzZWxmID0gdGhpcztcblx0dGhpcy50aW1lcklkID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkgeyBzZWxmLmV4cGlyZU1lc3NhZ2VzKCk7IH0sXG5cdFx0XHRcdCAgIHRoaXMudHRsX21zID4gMTAwMCA/IDEwMDAgOiB0aGlzLnR0bF9tcyk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcblxuRGVkdXBsaWNhdG9yLnByb3RvdHlwZS5leHBpcmVNZXNzYWdlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbm93ID0gK25ldyBEYXRlKCk7XG4gICAgd2hpbGUgKHRoaXMucXVldWUubGVuZ3RoID4gMCAmJiB0aGlzLnF1ZXVlWzBdWzBdIDw9IG5vdykge1xuXHR2YXIgZW50cnkgPSB0aGlzLnF1ZXVlLnNoaWZ0KCk7XG5cdGRlbGV0ZSB0aGlzLm1hcFtlbnRyeVsxXV07XG4gICAgfVxuICAgIGlmICh0aGlzLnF1ZXVlLmxlbmd0aCA9PT0gMCkge1xuXHRjbGVhckludGVydmFsKHRoaXMudGltZXJJZCk7XG5cdHRoaXMudGltZXJJZCA9IG51bGw7XG4gICAgfVxufTtcblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuLyogR3JvdW5kIGludGVyZmFjZSAqL1xuXG5mdW5jdGlvbiBHcm91bmQoYm9vdEZuKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHRoaXMuc3RlcHBlcklkID0gbnVsbDtcbiAgICBXb3JsZC53aXRoV29ybGRTdGFjayhbW3RoaXMsIC0xXV0sIGZ1bmN0aW9uICgpIHtcblx0c2VsZi53b3JsZCA9IG5ldyBXb3JsZChib290Rm4pO1xuICAgIH0pO1xufVxuXG5Hcm91bmQucHJvdG90eXBlLnN0ZXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHJldHVybiBXb3JsZC53aXRoV29ybGRTdGFjayhbW3RoaXMsIC0xXV0sIGZ1bmN0aW9uICgpIHtcblx0cmV0dXJuIHNlbGYud29ybGQuc3RlcCgpO1xuICAgIH0pO1xufTtcblxuR3JvdW5kLnByb3RvdHlwZS5jaGVja1BpZCA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgICBpZiAocGlkICE9PSAtMSkgY29uc29sZS5lcnJvcihcIldlaXJkIHBpZCBpbiBHcm91bmQgbWFya1BpZFJ1bm5hYmxlXCIsIHBpZCk7XG59OyAgICBcblxuR3JvdW5kLnByb3RvdHlwZS5tYXJrUGlkUnVubmFibGUgPSBmdW5jdGlvbiAocGlkKSB7XG4gICAgdGhpcy5jaGVja1BpZChwaWQpO1xuICAgIHRoaXMuc3RhcnRTdGVwcGluZygpO1xufTtcblxuR3JvdW5kLnByb3RvdHlwZS5zdGFydFN0ZXBwaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBpZiAodGhpcy5zdGVwcGVySWQpIHJldHVybjtcbiAgICBpZiAodGhpcy5zdGVwKCkpIHtcblx0dGhpcy5zdGVwcGVySWQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcblx0ICAgIHNlbGYuc3RlcHBlcklkID0gbnVsbDtcblx0ICAgIHNlbGYuc3RhcnRTdGVwcGluZygpO1xuXHR9LCAwKTtcbiAgICB9XG59O1xuXG5Hcm91bmQucHJvdG90eXBlLnN0b3BTdGVwcGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5zdGVwcGVySWQpIHtcblx0Y2xlYXJUaW1lb3V0KHRoaXMuc3RlcHBlcklkKTtcblx0dGhpcy5zdGVwcGVySWQgPSBudWxsO1xuICAgIH1cbn07XG5cbkdyb3VuZC5wcm90b3R5cGUuZW5xdWV1ZUFjdGlvbiA9IGZ1bmN0aW9uIChwaWQsIGFjdGlvbikge1xuICAgIHRoaXMuY2hlY2tQaWQocGlkKTtcbiAgICBpZiAoYWN0aW9uLnR5cGUgPT09ICdyb3V0ZXMnKSB7XG5cdGlmICghYWN0aW9uLmdlc3RhbHQuaXNFbXB0eSgpKSB7XG5cdCAgICBjb25zb2xlLmVycm9yKFwiWW91IGhhdmUgc3Vic2NyaWJlZCB0byBhIG5vbmV4aXN0ZW50IGV2ZW50IHNvdXJjZS5cIixcblx0XHRcdCAgYWN0aW9uLmdlc3RhbHQucHJldHR5KCkpO1xuXHR9XG4gICAgfSBlbHNlIHtcblx0Y29uc29sZS5lcnJvcihcIllvdSBoYXZlIHNlbnQgYSBtZXNzYWdlIGludG8gdGhlIG91dGVyIHZvaWQuXCIsIGFjdGlvbik7XG4gICAgfVxufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLl9fID0gX187XG5tb2R1bGUuZXhwb3J0cy5fJCA9IF8kO1xuXG5tb2R1bGUuZXhwb3J0cy5zdWIgPSBzdWI7XG5tb2R1bGUuZXhwb3J0cy5wdWIgPSBwdWI7XG5tb2R1bGUuZXhwb3J0cy5zcGF3biA9IHNwYXduO1xubW9kdWxlLmV4cG9ydHMudXBkYXRlUm91dGVzID0gdXBkYXRlUm91dGVzO1xubW9kdWxlLmV4cG9ydHMuc2VuZE1lc3NhZ2UgPSBzZW5kTWVzc2FnZTtcbm1vZHVsZS5leHBvcnRzLnNodXRkb3duV29ybGQgPSBzaHV0ZG93bldvcmxkO1xuXG5tb2R1bGUuZXhwb3J0cy5Xb3JsZCA9IFdvcmxkO1xubW9kdWxlLmV4cG9ydHMuRGVtYW5kTWF0Y2hlciA9IERlbWFuZE1hdGNoZXI7XG5tb2R1bGUuZXhwb3J0cy5EZWR1cGxpY2F0b3IgPSBEZWR1cGxpY2F0b3I7XG5tb2R1bGUuZXhwb3J0cy5Hcm91bmQgPSBHcm91bmQ7XG5tb2R1bGUuZXhwb3J0cy5Sb3V0ZSA9IFJvdXRlO1xuIiwiLy8gUmVmbGVjdGlvbiBvbiBmdW5jdGlvbiBmb3JtYWwgcGFyYW1ldGVyIGxpc3RzLlxuLy8gVGhpcyBtb2R1bGUgaXMgYmFzZWQgb24gQW5ndWxhcidzIFwiaW5qZWN0b3JcIiBjb2RlLFxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci5qcy9ibG9iL21hc3Rlci9zcmMvYXV0by9pbmplY3Rvci5qcyxcbi8vIE1JVCBsaWNlbnNlZCwgYW5kIGhlbmNlOlxuLy8gQ29weXJpZ2h0IChjKSAyMDEwLTIwMTQgR29vZ2xlLCBJbmMuIGh0dHA6Ly9hbmd1bGFyanMub3JnXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTQgVG9ueSBHYXJub2NrLUpvbmVzXG5cbnZhciBGTl9BUkdTID0gL15mdW5jdGlvblxccypbXlxcKF0qXFwoXFxzKihbXlxcKV0qKVxcKS9tO1xudmFyIEZOX0FSR19TUExJVCA9IC8sLztcbnZhciBTVFJJUF9DT01NRU5UUyA9IC8oKFxcL1xcLy4qJCl8KFxcL1xcKltcXHNcXFNdKj9cXCpcXC8pKS9tZztcblxuZnVuY3Rpb24gZm9ybWFsUGFyYW1ldGVycyhmbikge1xuICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgIHZhciBmblRleHQgPSBmbi50b1N0cmluZygpLnJlcGxhY2UoU1RSSVBfQ09NTUVOVFMsICcnKTtcbiAgICB2YXIgYXJnRGVjbCA9IGZuVGV4dC5tYXRjaChGTl9BUkdTKTtcbiAgICB2YXIgYXJncyA9IGFyZ0RlY2xbMV0uc3BsaXQoRk5fQVJHX1NQTElUKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcblx0dmFyIHRyaW1tZWQgPSBhcmdzW2ldLnRyaW0oKTtcblx0aWYgKHRyaW1tZWQpIHsgcmVzdWx0LnB1c2godHJpbW1lZCk7IH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cy5mb3JtYWxQYXJhbWV0ZXJzID0gZm9ybWFsUGFyYW1ldGVycztcbiIsInZhciBfXyA9IFwiX19cIjsgLyogd2lsZGNhcmQgbWFya2VyICovXG5cbnZhciBTT0EgPSBcIl9fW1wiOyAvLyBzdGFydCBvZiBhcnJheVxudmFyIEVPQSA9IFwiX19dXCI7IC8vIGVuZCBvZiBhcnJheVxuXG5mdW5jdGlvbiBkaWUobWVzc2FnZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbn1cblxuZnVuY3Rpb24gJEVtYmVkZGVkKG1hdGNoZXIpIHtcbiAgICB0aGlzLm1hdGNoZXIgPSBtYXRjaGVyO1xufVxuXG5mdW5jdGlvbiBlbWJlZGRlZE1hdGNoZXIobWF0Y2hlcikge1xuICAgIHJldHVybiBuZXcgJEVtYmVkZGVkKG1hdGNoZXIpO1xufVxuXG4vLyBUaGUgbmFtZSBhcmd1bWVudCBzaG91bGQgYmUgYSBzdHJpbmcgb3IgbnVsbDsgaXQgZGVmYXVsdHMgdG8gbnVsbC5cbi8vIFRoZSBwYXR0ZXJuIGFyZ3VtZW50IGRlZmF1bHRzIHRvIHdpbGRjYXJkLCBfXy5cbmZ1bmN0aW9uICRDYXB0dXJlKG5hbWUsIHBhdHRlcm4pIHtcbiAgICB0aGlzLm5hbWUgPSBuYW1lIHx8IG51bGw7XG4gICAgdGhpcy5wYXR0ZXJuID0gKHR5cGVvZiBwYXR0ZXJuID09PSAndW5kZWZpbmVkJyA/IF9fIDogcGF0dGVybik7XG59XG5cbi8vIEFiYnJldmlhdGlvbjogXyQoLi4uKSA8PT0+IG5ldyAkQ2FwdHVyZSguLi4pXG5mdW5jdGlvbiBfJChuYW1lLCBwYXR0ZXJuKSB7XG4gICAgcmV0dXJuIG5ldyAkQ2FwdHVyZShuYW1lLCBwYXR0ZXJuKTtcbn1cblxuZnVuY3Rpb24gaXNDYXB0dXJlKHgpIHsgcmV0dXJuIHggaW5zdGFuY2VvZiAkQ2FwdHVyZSB8fCB4ID09PSBfJDsgfVxuZnVuY3Rpb24gY2FwdHVyZU5hbWUoeCkgeyByZXR1cm4geCBpbnN0YW5jZW9mICRDYXB0dXJlID8geC5uYW1lIDogbnVsbDsgfVxuZnVuY3Rpb24gY2FwdHVyZVBhdHRlcm4oeCkgeyByZXR1cm4geCBpbnN0YW5jZW9mICRDYXB0dXJlID8geC5wYXR0ZXJuIDogX187IH1cblxudmFyIFNPQyA9IFwiX197e1wiOyAvLyBzdGFydCBvZiBjYXB0dXJlXG52YXIgRU9DID0gXCJfX319XCI7IC8vIGVuZCBvZiBjYXB0dXJlXG5cbmZ1bmN0aW9uICRTdWNjZXNzKHZhbHVlKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xufVxuXG5mdW5jdGlvbiAkV2lsZGNhcmRTZXF1ZW5jZShtYXRjaGVyKSB7XG4gICAgdGhpcy5tYXRjaGVyID0gbWF0Y2hlcjtcbn1cblxuZnVuY3Rpb24gJERpY3QoKSB7XG4gICAgdGhpcy5sZW5ndGggPSAwO1xuICAgIHRoaXMuZW50cmllcyA9IHt9O1xufVxuXG4kRGljdC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLmVudHJpZXNba2V5XSB8fCBlbXB0eU1hdGNoZXI7XG59O1xuXG4kRGljdC5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsKSB7XG4gICAgaWYgKCEoa2V5IGluIHRoaXMuZW50cmllcykpIHRoaXMubGVuZ3RoKys7XG4gICAgdGhpcy5lbnRyaWVzW2tleV0gPSB2YWw7XG59O1xuXG4kRGljdC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgaWYgKGtleSBpbiB0aGlzLmVudHJpZXMpIHRoaXMubGVuZ3RoLS07XG4gICAgZGVsZXRlIHRoaXMuZW50cmllc1trZXldO1xufTtcblxuJERpY3QucHJvdG90eXBlLmlzRW1wdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMubGVuZ3RoID09PSAwO1xufTtcblxuJERpY3QucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG90aGVyID0gbmV3ICREaWN0KCk7XG4gICAgb3RoZXIubGVuZ3RoID0gdGhpcy5sZW5ndGg7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMuZW50cmllcykge1xuXHRpZiAodGhpcy5lbnRyaWVzLmhhc093blByb3BlcnR5KGtleSkpIHtcblx0ICAgIG90aGVyLmVudHJpZXNba2V5XSA9IHRoaXMuZW50cmllc1trZXldO1xuXHR9XG4gICAgfVxuICAgIHJldHVybiBvdGhlcjtcbn07XG5cbiREaWN0LnByb3RvdHlwZS5lbXB0eUd1YXJkID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLmlzRW1wdHkoKSkgcmV0dXJuIGVtcHR5TWF0Y2hlcjtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbiREaWN0LnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIGtleSBpbiB0aGlzLmVudHJpZXM7XG59O1xuXG4kRGljdC5wcm90b3R5cGUuc29ydGVkS2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIga3MgPSBbXTtcbiAgICBmb3IgKHZhciBrIGluIHRoaXMuZW50cmllcykga3MucHVzaChrKTtcbiAgICBrcy5zb3J0KCk7XG4gICAgcmV0dXJuIGtzO1xufVxuXG5mdW5jdGlvbiBpc19lbXB0eU1hdGNoZXIobSkge1xuICAgIHJldHVybiAobSA9PT0gZW1wdHlNYXRjaGVyKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBDb25zdHJ1Y3RvcnNcblxudmFyIGVtcHR5TWF0Y2hlciA9IG51bGw7XG5cbmZ1bmN0aW9uIHJzdWNjZXNzKHYpIHtcbiAgICByZXR1cm4gKHYgPT09IGVtcHR5TWF0Y2hlcikgPyBlbXB0eU1hdGNoZXIgOiBuZXcgJFN1Y2Nlc3Modik7XG59XG5cbmZ1bmN0aW9uIHJzZXEoZSwgcikge1xuICAgIGlmIChyID09PSBlbXB0eU1hdGNoZXIpIHJldHVybiBlbXB0eU1hdGNoZXI7XG4gICAgdmFyIHMgPSBuZXcgJERpY3QoKTtcbiAgICBzLnNldChlLCByKTtcbiAgICByZXR1cm4gcztcbn1cblxuZnVuY3Rpb24gcndpbGQocikge1xuICAgIHJldHVybiByc2VxKF9fLCByKTtcbn1cblxuZnVuY3Rpb24gcndpbGRzZXEocikge1xuICAgIHJldHVybiAociA9PT0gZW1wdHlNYXRjaGVyKSA/IGVtcHR5TWF0Y2hlciA6IG5ldyAkV2lsZGNhcmRTZXF1ZW5jZShyKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGNvbXBpbGVQYXR0ZXJuKHYsIHApIHtcbiAgICBpZiAoIXApIGRpZShcImNvbXBpbGVQYXR0ZXJuOiBtaXNzaW5nIHBhdHRlcm5cIik7XG4gICAgcmV0dXJuIHdhbGsocCwgcnNlcShFT0EsIHJzdWNjZXNzKHYpKSk7XG5cbiAgICBmdW5jdGlvbiB3YWxrKHAsIGFjYykge1xuXHRpZiAocCA9PT0gX18pIHJldHVybiByd2lsZChhY2MpO1xuXG5cdGlmIChBcnJheS5pc0FycmF5KHApKSB7XG5cdCAgICBhY2MgPSByc2VxKEVPQSwgYWNjKTtcblx0ICAgIGZvciAodmFyIGkgPSBwLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG5cdFx0YWNjID0gd2FsayhwW2ldLCBhY2MpO1xuXHQgICAgfVxuXHQgICAgcmV0dXJuIHJzZXEoU09BLCBhY2MpO1xuXHR9XG5cblx0aWYgKHAgaW5zdGFuY2VvZiAkRW1iZWRkZWQpIHtcblx0ICAgIHJldHVybiBhcHBlbmRNYXRjaGVyKHAubWF0Y2hlciwgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIGFjYzsgfSk7XG5cdH0gZWxzZSB7XG5cdCAgICByZXR1cm4gcnNlcShKU09OLnN0cmluZ2lmeShwKSwgYWNjKTtcblx0fVxuICAgIH1cbn1cblxuZnVuY3Rpb24gbWF0Y2hQYXR0ZXJuKHYsIHApIHtcbiAgICB2YXIgY2FwdHVyZUNvdW50ID0gMDtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgdHJ5IHtcblx0d2Fsayh2LCBwKTtcbiAgICB9IGNhdGNoIChlKSB7XG5cdGlmIChlLm1hdGNoUGF0dGVybkZhaWxlZCkgcmV0dXJuIG51bGw7XG5cdHRocm93IGU7XG4gICAgfVxuICAgIHJlc3VsdC5sZW5ndGggPSBjYXB0dXJlQ291bnQ7XG4gICAgcmV0dXJuIHJlc3VsdDtcblxuICAgIGZ1bmN0aW9uIHdhbGsodiwgcCkge1xuXHRpZiAocCA9PT0gdikgcmV0dXJuO1xuXG5cdGlmIChwID09PSBfXykgcmV0dXJuO1xuXG5cdGlmIChBcnJheS5pc0FycmF5KHApICYmIEFycmF5LmlzQXJyYXkodikgJiYgcC5sZW5ndGggPT09IHYubGVuZ3RoKSB7XG5cdCAgICBmb3IgKHZhciBpID0gMDsgaSA8IHAubGVuZ3RoOyBpKyspIHtcblx0XHR3YWxrKHZbaV0sIHBbaV0pO1xuXHQgICAgfVxuXHQgICAgcmV0dXJuO1xuXHR9XG5cblx0aWYgKGlzQ2FwdHVyZShwKSkge1xuXHQgICAgdmFyIHRoaXNDYXB0dXJlID0gY2FwdHVyZUNvdW50Kys7XG5cdCAgICB3YWxrKHYsIGNhcHR1cmVQYXR0ZXJuKHApKTtcblx0ICAgIHJlc3VsdFtjYXB0dXJlTmFtZShwKSB8fCAoJyQnICsgdGhpc0NhcHR1cmUpXSA9IHY7XG5cdCAgICByZXR1cm47XG5cdH1cblxuXHRpZiAocCBpbnN0YW5jZW9mICRFbWJlZGRlZCkge1xuXHQgICAgZGllKFwiJEVtYmVkZGVkIHBhdHRlcm5zIG5vdCBzdXBwb3J0ZWQgaW4gbWF0Y2hQYXR0ZXJuKClcIik7XG5cdH1cblxuXHR0aHJvdyB7bWF0Y2hQYXR0ZXJuRmFpbGVkOiB0cnVlfTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHNoYWxsb3dDb3B5QXJyYXkocykge1xuICAgIHJldHVybiBzLnNsaWNlKCk7XG59XG5cbmZ1bmN0aW9uIHJ1cGRhdGVJbnBsYWNlKHIsIGtleSwgaykge1xuICAgIGlmIChpc19lbXB0eU1hdGNoZXIoaykpIHtcblx0ci5jbGVhcihrZXkpO1xuICAgIH0gZWxzZSB7XG5cdHIuc2V0KGtleSwgayk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBtYXRjaGVyRXF1YWxzKGEsIGIpIHtcbiAgICBpZiAoYSA9PT0gbnVsbCkge1xuXHRyZXR1cm4gKGIgPT09IG51bGwpO1xuICAgIH1cbiAgICBpZiAoYiA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKGEgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHRpZiAoIShiIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpKSByZXR1cm4gZmFsc2U7XG5cdGEgPSBhLm1hdGNoZXI7XG5cdGIgPSBiLm1hdGNoZXI7XG4gICAgfSBlbHNlIGlmIChiIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHJldHVybiBmYWxzZTtcblxuICAgIGlmIChhIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0aWYgKCEoYiBpbnN0YW5jZW9mICRTdWNjZXNzKSkgcmV0dXJuIGZhbHNlO1xuXHRyZXR1cm4gdmFsdWVzRXF1YWwoYS52YWx1ZSwgYi52YWx1ZSk7XG4gICAgfVxuICAgIGlmIChiIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHJldHVybiBmYWxzZTtcblxuICAgIGZvciAodmFyIGtleSBpbiBhLmVudHJpZXMpIHtcblx0aWYgKCFiLmhhcyhrZXkpKSByZXR1cm4gZmFsc2U7XG5cdGlmICghbWF0Y2hlckVxdWFscyhhLmVudHJpZXNba2V5XSwgYi5lbnRyaWVzW2tleV0pKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBpc19rZXlPcGVuKGspIHtcbiAgICByZXR1cm4gayA9PT0gU09BO1xufVxuXG5mdW5jdGlvbiBpc19rZXlDbG9zZShrKSB7XG4gICAgcmV0dXJuIGsgPT09IEVPQTtcbn1cblxuZnVuY3Rpb24gaXNfa2V5Tm9ybWFsKGspIHtcbiAgICByZXR1cm4gIShpc19rZXlPcGVuKGspIHx8IGlzX2tleUNsb3NlKGspKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBFbm91Z2ggb2Ygc2V0cyB0byBnZXQgYnkgd2l0aFxuXG5mdW5jdGlvbiBhcnJheVRvU2V0KHhzKSB7XG4gICAgdmFyIHMgPSB7fTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG5cdHNbSlNPTi5zdHJpbmdpZnkoeHNbaV0pXSA9IHhzW2ldO1xuICAgIH1cbiAgICByZXR1cm4gcztcbn1cblxuZnVuY3Rpb24gc2V0VG9BcnJheShzKSB7XG4gICAgdmFyIHIgPSBbXTtcbiAgICBmb3IgKHZhciBrIGluIHMpIHIucHVzaChzW2tdKTtcbiAgICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gc2V0VW5pb24oczEsIHMyKSB7XG4gICAgdmFyIHMgPSB7fTtcbiAgICBzZXRVbmlvbklucGxhY2UocywgczEpO1xuICAgIHNldFVuaW9uSW5wbGFjZShzLCBzMik7XG4gICAgcmV0dXJuIHM7XG59XG5cbmZ1bmN0aW9uIGlzX2VtcHR5U2V0KHMpIHtcbiAgICBmb3IgKHZhciBrIGluIHMpIHtcblx0aWYgKHMuaGFzT3duUHJvcGVydHkoaykpXG5cdCAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBzZXRTdWJ0cmFjdChzMSwgczIpIHtcbiAgICB2YXIgcyA9IHt9O1xuICAgIGZvciAodmFyIGtleSBpbiBzMSkge1xuXHRpZiAoczEuaGFzT3duUHJvcGVydHkoa2V5KSAmJiAhczIuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuXHQgICAgc1trZXldID0gczFba2V5XTtcblx0fVxuICAgIH1cbiAgICByZXR1cm4gcztcbn1cblxuZnVuY3Rpb24gc2V0SW50ZXJzZWN0KHMxLCBzMikge1xuICAgIHZhciBzID0ge307XG4gICAgZm9yICh2YXIga2V5IGluIHMxKSB7XG5cdGlmIChzMS5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIHMyLmhhc093blByb3BlcnR5KGtleSkpIHtcblx0ICAgIHNba2V5XSA9IHMxW2tleV07XG5cdH1cbiAgICB9XG4gICAgcmV0dXJuIHM7XG59XG5cbmZ1bmN0aW9uIHNldFVuaW9uSW5wbGFjZShhY2MsIHMpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gcykge1xuXHRpZiAocy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdCAgICBhY2Nba2V5XSA9IHNba2V5XTtcblx0fVxuICAgIH1cbn1cblxuZnVuY3Rpb24gc2V0RXF1YWwoczEsIHMyKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHMxKSB7XG5cdGlmIChzMS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdCAgICBpZiAoczFba2V5XSAhPT0gczJba2V5XSkgcmV0dXJuIGZhbHNlO1xuXHR9XG4gICAgfVxuICAgIGZvciAodmFyIGtleSBpbiBzMikge1xuXHRpZiAoczIuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuXHQgICAgaWYgKHMxW2tleV0gIT09IHMyW2tleV0pIHJldHVybiBmYWxzZTtcblx0fVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbnZhciB1bmlvblN1Y2Nlc3NlcyA9IGZ1bmN0aW9uICh2MSwgdjIpIHtcbiAgICBpZiAodjEgPT09IHRydWUpIHJldHVybiB2MjtcbiAgICBpZiAodjIgPT09IHRydWUpIHJldHVybiB2MTtcbiAgICByZXR1cm4gc2V0VW5pb24odjEsIHYyKTtcbn07XG5cbnZhciBpbnRlcnNlY3RTdWNjZXNzZXMgPSBmdW5jdGlvbiAodjEsIHYyKSB7XG4gICAgcmV0dXJuIHYxO1xufTtcblxudmFyIGVyYXNlUGF0aFN1Y2Nlc3NlcyA9IGZ1bmN0aW9uICh2MSwgdjIpIHtcbiAgICB2YXIgciA9IHNldFN1YnRyYWN0KHYxLCB2Mik7XG4gICAgaWYgKGlzX2VtcHR5U2V0KHIpKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gcjtcbn07XG5cbnZhciBtYXRjaE1hdGNoZXJTdWNjZXNzZXMgPSBmdW5jdGlvbiAodjEsIHYyLCBhY2MpIHtcbiAgICBzZXRVbmlvbklucGxhY2UoYWNjLCB2Mik7XG59O1xuXG52YXIgcHJvamVjdFN1Y2Nlc3MgPSBmdW5jdGlvbiAodikge1xuICAgIHJldHVybiB2O1xufTtcblxudmFyIHZhbHVlc0VxdWFsID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gc2V0RXF1YWwoYSwgYik7XG59O1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gZXhwYW5kV2lsZHNlcShyKSB7XG4gICAgcmV0dXJuIHVuaW9uKHJ3aWxkKHJ3aWxkc2VxKHIpKSwgcnNlcShFT0EsIHIpKTtcbn1cblxuZnVuY3Rpb24gdW5pb24obzEsIG8yKSB7XG4gICAgcmV0dXJuIG1lcmdlKG8xLCBvMik7XG5cbiAgICBmdW5jdGlvbiBtZXJnZShvMSwgbzIpIHtcblx0aWYgKGlzX2VtcHR5TWF0Y2hlcihvMSkpIHJldHVybiBvMjtcblx0aWYgKGlzX2VtcHR5TWF0Y2hlcihvMikpIHJldHVybiBvMTtcblx0cmV0dXJuIHdhbGsobzEsIG8yKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3YWxrKHIxLCByMikge1xuXHRpZiAocjEgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHQgICAgaWYgKHIyIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0XHRyZXR1cm4gcndpbGRzZXEod2FsayhyMS5tYXRjaGVyLCByMi5tYXRjaGVyKSk7XG5cdCAgICB9XG5cdCAgICByMSA9IGV4cGFuZFdpbGRzZXEocjEubWF0Y2hlcik7XG5cdH0gZWxzZSBpZiAocjIgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHQgICAgcjIgPSBleHBhbmRXaWxkc2VxKHIyLm1hdGNoZXIpO1xuXHR9XG5cblx0aWYgKHIxIGluc3RhbmNlb2YgJFN1Y2Nlc3MgJiYgcjIgaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuXHQgICAgcmV0dXJuIHJzdWNjZXNzKHVuaW9uU3VjY2Vzc2VzKHIxLnZhbHVlLCByMi52YWx1ZSkpO1xuXHR9XG5cblx0dmFyIHcgPSBtZXJnZShyMS5nZXQoX18pLCByMi5nZXQoX18pKTtcblx0aWYgKGlzX2VtcHR5TWF0Y2hlcih3KSkge1xuXHQgICAgdmFyIHNtYWxsZXIgPSByMS5sZW5ndGggPCByMi5sZW5ndGggPyByMSA6IHIyO1xuXHQgICAgdmFyIGxhcmdlciAgPSByMS5sZW5ndGggPCByMi5sZW5ndGggPyByMiA6IHIxO1xuXHQgICAgdmFyIHRhcmdldCA9IGxhcmdlci5jb3B5KCk7XG5cdCAgICBmb3IgKHZhciBrZXkgaW4gc21hbGxlci5lbnRyaWVzKSB7XG5cdFx0dmFyIGsgPSBtZXJnZShzbWFsbGVyLmdldChrZXkpLCBsYXJnZXIuZ2V0KGtleSkpO1xuXHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCBrKTtcblx0ICAgIH1cblx0ICAgIHJldHVybiB0YXJnZXQuZW1wdHlHdWFyZCgpO1xuXHR9IGVsc2Uge1xuXHQgICAgZnVuY3Rpb24gZXhhbWluZUtleShyQSwga2V5LCByQikge1xuXHRcdGlmICgoa2V5ICE9PSBfXykgJiYgIXRhcmdldC5oYXMoa2V5KSkge1xuXHRcdCAgICB2YXIgayA9IG1lcmdlKHJBLmdldChrZXkpLCByQi5nZXQoa2V5KSk7XG5cdFx0ICAgIGlmIChpc19rZXlPcGVuKGtleSkpIHtcblx0XHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCBtZXJnZShyd2lsZHNlcSh3KSwgaykpO1xuXHRcdCAgICB9IGVsc2UgaWYgKGlzX2tleUNsb3NlKGtleSkpIHtcblx0XHRcdGlmICh3IGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0XHRcdCAgICBydXBkYXRlSW5wbGFjZSh0YXJnZXQsIGtleSwgbWVyZ2Uody5tYXRjaGVyLCBrKSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0ICAgIHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCBrKTtcblx0XHRcdH1cblx0XHQgICAgfSBlbHNlIHtcblx0XHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCBtZXJnZSh3LCBrKSk7XG5cdFx0ICAgIH1cblx0XHR9XG5cdCAgICB9XG5cdCAgICB2YXIgdGFyZ2V0ID0gcndpbGQodykuY29weSgpO1xuXHQgICAgZm9yICh2YXIga2V5IGluIHIxLmVudHJpZXMpIHsgZXhhbWluZUtleShyMSwga2V5LCByMik7IH1cblx0ICAgIGZvciAodmFyIGtleSBpbiByMi5lbnRyaWVzKSB7IGV4YW1pbmVLZXkocjIsIGtleSwgcjEpOyB9XG5cdCAgICByZXR1cm4gdGFyZ2V0O1xuXHR9XG4gICAgfVxufVxuXG5mdW5jdGlvbiB1bmlvbk4oKSB7XG4gICAgdmFyIGFjYyA9IGVtcHR5TWF0Y2hlcjtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuXHRhY2MgPSB1bmlvbihhY2MsIGFyZ3VtZW50c1tpXSk7XG4gICAgfVxuICAgIHJldHVybiBhY2M7XG59XG5cbmZ1bmN0aW9uIGludGVyc2VjdChvMSwgbzIpIHtcbiAgICBpZiAoaXNfZW1wdHlNYXRjaGVyKG8xKSkgcmV0dXJuIGVtcHR5TWF0Y2hlcjtcbiAgICBpZiAoaXNfZW1wdHlNYXRjaGVyKG8yKSkgcmV0dXJuIGVtcHR5TWF0Y2hlcjtcbiAgICByZXR1cm4gd2FsayhvMSwgbzIpO1xuXG4gICAgZnVuY3Rpb24gd2Fsa0ZsaXBwZWQocjIsIHIxKSB7IHJldHVybiB3YWxrKHIxLCByMik7IH1cblxuICAgIGZ1bmN0aW9uIHdhbGsocjEsIHIyKSB7XG5cdC8vIElOVkFSSUFOVDogcjEgaXMgYSBwYXJ0IG9mIHRoZSBvcmlnaW5hbCBvMSwgYW5kXG5cdC8vIGxpa2V3aXNlIGZvciByMi4gVGhpcyBpcyBzbyB0aGF0IHRoZSBmaXJzdCBhcmcgdG9cblx0Ly8gaW50ZXJzZWN0U3VjY2Vzc2VzIGFsd2F5cyBjb21lcyBmcm9tIHIxLCBhbmQgdGhlIHNlY29uZFxuXHQvLyBmcm9tIHIyLlxuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKHIxKSkgcmV0dXJuIGVtcHR5TWF0Y2hlcjtcblx0aWYgKGlzX2VtcHR5TWF0Y2hlcihyMikpIHJldHVybiBlbXB0eU1hdGNoZXI7XG5cblx0aWYgKHIxIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0ICAgIGlmIChyMiBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG5cdFx0cmV0dXJuIHJ3aWxkc2VxKHdhbGsocjEubWF0Y2hlciwgcjIubWF0Y2hlcikpO1xuXHQgICAgfVxuXHQgICAgcjEgPSBleHBhbmRXaWxkc2VxKHIxLm1hdGNoZXIpO1xuXHR9IGVsc2UgaWYgKHIyIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0ICAgIHIyID0gZXhwYW5kV2lsZHNlcShyMi5tYXRjaGVyKTtcblx0fVxuXG5cdGlmIChyMSBpbnN0YW5jZW9mICRTdWNjZXNzICYmIHIyIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0ICAgIHJldHVybiByc3VjY2VzcyhpbnRlcnNlY3RTdWNjZXNzZXMocjEudmFsdWUsIHIyLnZhbHVlKSk7XG5cdH1cblxuXHR2YXIgdzEgPSByMS5nZXQoX18pO1xuXHR2YXIgdzIgPSByMi5nZXQoX18pO1xuXHR2YXIgdyA9IHdhbGsodzEsIHcyKTtcblxuXHR2YXIgdGFyZ2V0ID0gbmV3ICREaWN0KCk7XG5cblx0ZnVuY3Rpb24gZXhhbWluZUtleShrZXkpIHtcblx0ICAgIGlmICgoa2V5ICE9PSBfXykgJiYgIXRhcmdldC5oYXMoa2V5KSkge1xuXHRcdHZhciBrMSA9IHIxLmdldChrZXkpO1xuXHRcdHZhciBrMiA9IHIyLmdldChrZXkpO1xuXHRcdGlmIChpc19lbXB0eU1hdGNoZXIoazEpKSB7XG5cdFx0ICAgIGlmIChpc19lbXB0eU1hdGNoZXIoazIpKSB7XG5cdFx0XHRydXBkYXRlSW5wbGFjZSh0YXJnZXQsIGtleSwgZW1wdHlNYXRjaGVyKTtcblx0XHQgICAgfSBlbHNlIHtcblx0XHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCB3YWxrV2lsZCh3YWxrLCB3MSwga2V5LCBrMikpO1xuXHRcdCAgICB9XG5cdFx0fSBlbHNlIHtcblx0XHQgICAgaWYgKGlzX2VtcHR5TWF0Y2hlcihrMikpIHtcblx0XHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCB3YWxrV2lsZCh3YWxrRmxpcHBlZCwgdzIsIGtleSwgazEpKTtcblx0XHQgICAgfSBlbHNlIHtcblx0XHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCB3YWxrKGsxLCBrMikpO1xuXHRcdCAgICB9XG5cdFx0fVxuXHQgICAgfVxuXHR9XG5cblx0aWYgKGlzX2VtcHR5TWF0Y2hlcih3MSkpIHtcblx0ICAgIGlmIChpc19lbXB0eU1hdGNoZXIodzIpKSB7XG5cdFx0Zm9yICh2YXIga2V5IGluIChyMS5sZW5ndGggPCByMi5sZW5ndGggPyByMSA6IHIyKS5lbnRyaWVzKSBleGFtaW5lS2V5KGtleSk7XG5cdCAgICB9IGVsc2Uge1xuXHRcdGZvciAodmFyIGtleSBpbiByMS5lbnRyaWVzKSBleGFtaW5lS2V5KGtleSk7XG5cdCAgICB9XG5cdH0gZWxzZSB7XG5cdCAgICBpZiAoaXNfZW1wdHlNYXRjaGVyKHcyKSkge1xuXHRcdGZvciAodmFyIGtleSBpbiByMi5lbnRyaWVzKSBleGFtaW5lS2V5KGtleSk7XG5cdCAgICB9IGVsc2Uge1xuXHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwgX18sIHcpO1xuXHRcdGZvciAodmFyIGtleSBpbiByMS5lbnRyaWVzKSBleGFtaW5lS2V5KGtleSk7XG5cdFx0Zm9yICh2YXIga2V5IGluIHIyLmVudHJpZXMpIGV4YW1pbmVLZXkoa2V5KTtcblx0ICAgIH1cblx0fVxuXHRyZXR1cm4gdGFyZ2V0LmVtcHR5R3VhcmQoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3YWxrV2lsZCh3YWxrZXIsIHcsIGtleSwgaykge1xuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKHcpKSByZXR1cm4gZW1wdHlNYXRjaGVyO1xuXHRpZiAoaXNfa2V5T3BlbihrZXkpKSByZXR1cm4gd2Fsa2VyKHJ3aWxkc2VxKHcpLCBrKTtcblx0aWYgKGlzX2tleUNsb3NlKGtleSkpIHtcblx0ICAgIGlmICh3IGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHJldHVybiB3YWxrZXIody5tYXRjaGVyLCBrKTtcblx0ICAgIHJldHVybiBlbXB0eU1hdGNoZXI7XG5cdH1cblx0cmV0dXJuIHdhbGtlcih3LCBrKTtcbiAgICB9XG59XG5cbi8vIFJlbW92ZXMgcjIncyBtYXBwaW5ncyBmcm9tIHIxLiBBc3N1bWVzIHIyIGhhcyBwcmV2aW91c2x5IGJlZW5cbi8vIHVuaW9uJ2QgaW50byByMS4gVGhlIGVyYXNlUGF0aFN1Y2Nlc3NlcyBmdW5jdGlvbiBzaG91bGQgcmV0dXJuXG4vLyBudWxsIHRvIHNpZ25hbCBcIm5vIHJlbWFpbmluZyBzdWNjZXNzIHZhbHVlc1wiLlxuZnVuY3Rpb24gZXJhc2VQYXRoKG8xLCBvMikge1xuICAgIHJldHVybiB3YWxrKG8xLCBvMik7XG5cbiAgICBmdW5jdGlvbiB3YWxrKHIxLCByMikge1xuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKHIxKSkge1xuXHQgICAgcmV0dXJuIGVtcHR5TWF0Y2hlcjtcblx0fSBlbHNlIHtcblx0ICAgIGlmIChpc19lbXB0eU1hdGNoZXIocjIpKSB7XG5cdFx0cmV0dXJuIHIxO1xuXHQgICAgfVxuXHR9XG5cblx0aWYgKHIxIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0ICAgIGlmIChyMiBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG5cdFx0cmV0dXJuIHJ3aWxkc2VxKHdhbGsocjEubWF0Y2hlciwgcjIubWF0Y2hlcikpO1xuXHQgICAgfVxuXHQgICAgcjEgPSBleHBhbmRXaWxkc2VxKHIxLm1hdGNoZXIpO1xuXHR9IGVsc2UgaWYgKHIyIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0ICAgIHIyID0gZXhwYW5kV2lsZHNlcShyMi5tYXRjaGVyKTtcblx0fVxuXG5cdGlmIChyMSBpbnN0YW5jZW9mICRTdWNjZXNzICYmIHIyIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0ICAgIHJldHVybiByc3VjY2VzcyhlcmFzZVBhdGhTdWNjZXNzZXMocjEudmFsdWUsIHIyLnZhbHVlKSk7XG5cdH1cblxuXHR2YXIgdzEgPSByMS5nZXQoX18pO1xuXHR2YXIgdzIgPSByMi5nZXQoX18pO1xuXHR2YXIgdyA9IHdhbGsodzEsIHcyKTtcblx0dmFyIHRhcmdldDtcblxuXHRmdW5jdGlvbiBleGFtaW5lS2V5KGtleSkge1xuXHQgICAgaWYgKGtleSAhPT0gX18pIHtcblx0XHR2YXIgazEgPSByMS5nZXQoa2V5KTtcblx0XHR2YXIgazIgPSByMi5nZXQoa2V5KTtcblx0XHR2YXIgdXBkYXRlZEs7XG5cdFx0aWYgKGlzX2VtcHR5TWF0Y2hlcihrMikpIHtcblx0XHQgICAgdXBkYXRlZEsgPSB3YWxrV2lsZChrZXksIGsxLCB3Mik7XG5cdFx0fSBlbHNlIHtcblx0XHQgICAgdXBkYXRlZEsgPSB3YWxrKGsxLCBrMik7XG5cdFx0fVxuXHRcdC8vIEhlcmUgd2UgZW5zdXJlIGEgXCJtaW5pbWFsXCIgcmVtYWluZGVyIGluIGNhc2VzXG5cdFx0Ly8gd2hlcmUgYWZ0ZXIgYW4gZXJhc3VyZSwgYSBwYXJ0aWN1bGFyIGtleSdzXG5cdFx0Ly8gY29udGludWF0aW9uIGlzIHRoZSBzYW1lIGFzIHRoZSB3aWxkY2FyZCdzXG5cdFx0Ly8gY29udGludWF0aW9uLiBUT0RPOiB0aGUgbWF0Y2hlckVxdWFscyBjaGVjayBtYXlcblx0XHQvLyBiZSBleHBlbnNpdmUuIElmIHNvLCBob3cgY2FuIGl0IGJlIG1hZGVcblx0XHQvLyBjaGVhcGVyP1xuXHRcdGlmIChpc19rZXlPcGVuKGtleSkpIHtcblx0XHQgICAgcnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBrZXksXG5cdFx0XHRcdCAgICgodXBkYXRlZEsgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkgJiZcblx0XHRcdFx0ICAgIG1hdGNoZXJFcXVhbHModXBkYXRlZEsubWF0Y2hlciwgdykpXG5cdFx0XHRcdCAgID8gZW1wdHlNYXRjaGVyXG5cdFx0XHRcdCAgIDogdXBkYXRlZEspO1xuXHRcdH0gZWxzZSBpZiAoaXNfa2V5Q2xvc2Uoa2V5KSkge1xuXHRcdCAgICAvLyBXZSB0YWtlIGNhcmUgb2YgdGhpcyBjYXNlIGxhdGVyLCBhZnRlciB0aGVcblx0XHQgICAgLy8gdGFyZ2V0IGlzIGZ1bGx5IGNvbnN0cnVjdGVkL3JlYnVpbHQuXG5cdFx0ICAgIHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCB1cGRhdGVkSyk7XG5cdFx0fSBlbHNlIHtcblx0XHQgICAgcnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBrZXksXG5cdFx0XHRcdCAgIChtYXRjaGVyRXF1YWxzKHVwZGF0ZWRLLCB3KSA/IGVtcHR5TWF0Y2hlciA6IHVwZGF0ZWRLKSk7XG5cdFx0fVxuXHQgICAgfVxuXHR9XG5cblx0aWYgKGlzX2VtcHR5TWF0Y2hlcih3MikpIHtcblx0ICAgIHRhcmdldCA9IHIxLmNvcHkoKTtcblx0ICAgIGZvciAodmFyIGtleSBpbiByMi5lbnRyaWVzKSBleGFtaW5lS2V5KGtleSk7XG5cdH0gZWxzZSB7XG5cdCAgICB0YXJnZXQgPSBuZXcgJERpY3QoKTtcblx0ICAgIHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwgX18sIHcpO1xuXHQgICAgZm9yICh2YXIga2V5IGluIHIxLmVudHJpZXMpIGV4YW1pbmVLZXkoa2V5KTtcblx0ICAgIGZvciAodmFyIGtleSBpbiByMi5lbnRyaWVzKSBleGFtaW5lS2V5KGtleSk7XG5cdH1cblxuXHQvLyBIZXJlLCB0aGUgdGFyZ2V0IGlzIGNvbXBsZXRlLiBJZiBpdCBoYXMgb25seSB0d28ga2V5cyxcblx0Ly8gb25lIHdpbGQgYW5kIG9uZSBpc19rZXlDbG9zZSwgYW5kIHdpbGQncyBjb250aW51YXRpb25cblx0Ly8gaXMgYSAkV2lsZGNhcmRTZXF1ZW5jZSBhbmQgdGhlIG90aGVyIGNvbnRpbnVhdGlvbiBpc1xuXHQvLyBpZGVudGljYWwgdG8gdGhlIHNlcXVlbmNlJ3MgY29udGludWF0aW9uLCB0aGVuIHJlcGxhY2Vcblx0Ly8gdGhlIHdob2xlIHRoaW5nIHdpdGggYSBuZXN0ZWQgJFdpbGRjYXJkU2VxdWVuY2UuXG5cdC8vIChXZSBrbm93IHcgPT09IHRhcmdldC5nZXQoX18pIGZyb20gYmVmb3JlLilcblx0Ly9cblx0Ly8gVE9ETzogSSBzdXNwZWN0IGFjdHVhbGx5IHRoaXMgYXBwbGllcyBldmVuIGlmIHRoZXJlIGFyZVxuXHQvLyBtb3JlIHRoYW4gdHdvIGtleXMsIHNvIGxvbmcgYXMgYWxsIHRoZWlyIGNvbnRpbnVhdGlvbnNcblx0Ly8gYXJlIGlkZW50aWNhbCBhbmQgdGhlcmUncyBhdCBsZWFzdCBvbmUgaXNfa2V5Q2xvc2Vcblx0Ly8gYWxvbmdzaWRlIGEgd2lsZC5cblx0aWYgKHRhcmdldC5sZW5ndGggPT09IDIpIHtcblx0ICAgIHZhciBmaW5hbFcgPSB0YXJnZXQuZ2V0KF9fKTtcblx0ICAgIGlmIChmaW5hbFcgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHRcdGZvciAodmFyIGtleSBpbiB0YXJnZXQuZW50cmllcykge1xuXHRcdCAgICBpZiAoKGtleSAhPT0gX18pICYmIGlzX2tleUNsb3NlKGtleSkpIHtcblx0XHRcdHZhciBrID0gdGFyZ2V0LmdldChrZXkpO1xuXHRcdFx0aWYgKG1hdGNoZXJFcXVhbHMoaywgZmluYWxXLm1hdGNoZXIpKSB7XG5cdFx0XHQgICAgcmV0dXJuIGZpbmFsVztcblx0XHRcdH1cblx0XHQgICAgfVxuXHRcdH1cblx0ICAgIH1cblx0fVxuXG5cdHJldHVybiB0YXJnZXQuZW1wdHlHdWFyZCgpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHdhbGtXaWxkKGtleSwgaywgdykge1xuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKHcpKSByZXR1cm4gaztcblx0aWYgKGlzX2tleU9wZW4oa2V5KSkgcmV0dXJuIHdhbGsoaywgcndpbGRzZXEodykpO1xuXHRpZiAoaXNfa2V5Q2xvc2Uoa2V5KSkge1xuXHQgICAgaWYgKHcgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkgcmV0dXJuIHdhbGsoaywgdy5tYXRjaGVyKTtcblx0ICAgIHJldHVybiBrO1xuXHR9XG5cdHJldHVybiB3YWxrKGssIHcpO1xuICAgIH1cbn1cblxuLy8gUmV0dXJucyBudWxsIG9uIGZhaWxlZCBtYXRjaCwgb3RoZXJ3aXNlIHRoZSBhcHByb3ByaWF0ZSBzdWNjZXNzXG4vLyB2YWx1ZSBjb250YWluZWQgaW4gdGhlIG1hdGNoZXIgci5cbmZ1bmN0aW9uIG1hdGNoVmFsdWUociwgdikge1xuICAgIHZhciBmYWlsdXJlUmVzdWx0ID0gbnVsbDtcblxuICAgIHZhciB2cyA9IFt2XTtcbiAgICB2YXIgc3RhY2sgPSBbW11dO1xuXG4gICAgd2hpbGUgKCFpc19lbXB0eU1hdGNoZXIocikpIHtcblx0aWYgKHIgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHQgICAgaWYgKHN0YWNrLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhaWx1cmVSZXN1bHQ7XG5cdCAgICB2cyA9IHN0YWNrLnBvcCgpO1xuXHQgICAgciA9IHIubWF0Y2hlcjtcblx0ICAgIGNvbnRpbnVlO1xuXHR9XG5cblx0aWYgKHIgaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuXHQgICAgaWYgKHZzLmxlbmd0aCA9PT0gMCAmJiBzdGFjay5sZW5ndGggPT09IDApIHJldHVybiByLnZhbHVlO1xuXHQgICAgcmV0dXJuIGZhaWx1cmVSZXN1bHQ7XG5cdH1cblxuXHRpZiAodnMubGVuZ3RoID09PSAwKSB7XG5cdCAgICBpZiAoc3RhY2subGVuZ3RoID09PSAwKSByZXR1cm4gZmFpbHVyZVJlc3VsdDtcblx0ICAgIHZzID0gc3RhY2sucG9wKCk7XG5cdCAgICByID0gci5nZXQoRU9BKTtcblx0ICAgIGNvbnRpbnVlO1xuXHR9XG5cblx0dmFyIHYgPSB2cy5zaGlmdCgpO1xuXG5cdGlmICh0eXBlb2YgdiA9PT0gJ3N0cmluZycgJiYgdi5zdWJzdHJpbmcoMCwgMikgPT09ICdfXycpIHtcblx0ICAgIGRpZShcIkNhbm5vdCBtYXRjaCBzcGVjaWFsIHN0cmluZyBzdGFydGluZyB3aXRoIF9fXCIpO1xuXHR9XG5cblx0aWYgKEFycmF5LmlzQXJyYXkodikpIHtcblx0ICAgIGlmIChTT0EgaW4gci5lbnRyaWVzKSB7XG5cdFx0ciA9IHIuZ2V0KFNPQSk7XG5cdFx0c3RhY2sucHVzaCh2cyk7XG5cdFx0dnMgPSBzaGFsbG93Q29weUFycmF5KHYpO1xuXHQgICAgfSBlbHNlIHtcblx0XHRyID0gci5nZXQoX18pO1xuXHQgICAgfVxuXHR9IGVsc2Uge1xuXHQgICAgdmFyIGtleTtcblx0ICAgIHRyeSB7XG5cdFx0a2V5ID0gSlNPTi5zdHJpbmdpZnkodik7XG5cdCAgICB9IGNhdGNoIChleG4pIHtcblx0XHQvLyBGb3IgZXhhbXBsZSwgdiBtaWdodCBiZSBjeWNsaWMsIGFzIGluIERPTSBldmVudHMuXG5cdFx0a2V5ID0gbnVsbDtcblx0ICAgIH1cblx0ICAgIGlmIChrZXkgaW4gci5lbnRyaWVzKSB7XG5cdFx0ciA9IHIuZ2V0KGtleSk7XG5cdCAgICB9IGVsc2Uge1xuXHRcdHIgPSByLmdldChfXyk7XG5cdCAgICB9XG5cdH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFpbHVyZVJlc3VsdDtcbn1cblxuLy8gVE9ETzogYmV0dGVyIG5hbWUgZm9yIHRoaXNcbmZ1bmN0aW9uIG1hdGNoTWF0Y2hlcihvMSwgbzIsIHNlZWQpIHtcbiAgICB2YXIgYWNjID0gdHlwZW9mIHNlZWQgPT09ICd1bmRlZmluZWQnID8ge30gOiBzZWVkOyAvLyB3aWxsIGJlIG1vZGlmaWVkIGluIHBsYWNlXG4gICAgd2FsayhvMSwgbzIpO1xuICAgIHJldHVybiBhY2M7XG5cbiAgICBmdW5jdGlvbiB3YWxrRmxpcHBlZChyMiwgcjEpIHsgcmV0dXJuIHdhbGsocjEsIHIyKTsgfVxuXG4gICAgZnVuY3Rpb24gd2FsayhyMSwgcjIpIHtcblx0aWYgKGlzX2VtcHR5TWF0Y2hlcihyMSkgfHwgaXNfZW1wdHlNYXRjaGVyKHIyKSkgcmV0dXJuO1xuXG5cdGlmIChyMSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG5cdCAgICBpZiAocjIgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHRcdHdhbGsocjEubWF0Y2hlciwgcjIubWF0Y2hlcik7XG5cdFx0cmV0dXJuO1xuXHQgICAgfVxuXHQgICAgcjEgPSBleHBhbmRXaWxkc2VxKHIxLm1hdGNoZXIpO1xuXHR9IGVsc2UgaWYgKHIyIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0ICAgIHIyID0gZXhwYW5kV2lsZHNlcShyMi5tYXRjaGVyKTtcblx0fVxuXG5cdGlmIChyMSBpbnN0YW5jZW9mICRTdWNjZXNzICYmIHIyIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0ICAgIG1hdGNoTWF0Y2hlclN1Y2Nlc3NlcyhyMS52YWx1ZSwgcjIudmFsdWUsIGFjYyk7XG5cdCAgICByZXR1cm47XG5cdH1cblxuXHR2YXIgdzEgPSByMS5nZXQoX18pO1xuXHR2YXIgdzIgPSByMi5nZXQoX18pO1xuXHR3YWxrKHcxLCB3Mik7XG5cblx0ZnVuY3Rpb24gZXhhbWluZUtleShrZXkpIHtcblx0ICAgIGlmIChrZXkgIT09IF9fKSB7XG5cdFx0dmFyIGsxID0gcjEuZ2V0KGtleSk7XG5cdFx0dmFyIGsyID0gcjIuZ2V0KGtleSk7XG5cdFx0aWYgKGlzX2VtcHR5TWF0Y2hlcihrMSkpIHtcblx0XHQgICAgaWYgKGlzX2VtcHR5TWF0Y2hlcihrMikpIHtcblx0XHRcdHJldHVybjtcblx0XHQgICAgfSBlbHNlIHtcblx0XHRcdHdhbGtXaWxkKHdhbGssIHcxLCBrZXksIGsyKTtcblx0XHQgICAgfVxuXHRcdH0gZWxzZSB7XG5cdFx0ICAgIGlmIChpc19lbXB0eU1hdGNoZXIoazIpKSB7XG5cdFx0XHR3YWxrV2lsZCh3YWxrRmxpcHBlZCwgdzIsIGtleSwgazEpO1xuXHRcdCAgICB9IGVsc2Uge1xuXHRcdFx0d2FsayhrMSwgazIpO1xuXHRcdCAgICB9XG5cdFx0fVxuXHQgICAgfVxuXHR9XG5cblx0Ly8gT3B0aW1pemUgc2ltaWxhcmx5IHRvIGludGVyc2VjdCgpLlxuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKHcxKSkge1xuXHQgICAgaWYgKGlzX2VtcHR5TWF0Y2hlcih3MikpIHtcblx0XHRmb3IgKHZhciBrZXkgaW4gKHIxLmxlbmd0aCA8IHIyLmxlbmd0aCA/IHIxIDogcjIpLmVudHJpZXMpIGV4YW1pbmVLZXkoa2V5KTtcblx0ICAgIH0gZWxzZSB7XG5cdFx0Zm9yICh2YXIga2V5IGluIHIxLmVudHJpZXMpIGV4YW1pbmVLZXkoa2V5KTtcblx0ICAgIH1cblx0fSBlbHNlIHtcblx0ICAgIGlmIChpc19lbXB0eU1hdGNoZXIodzIpKSB7XG5cdFx0Zm9yICh2YXIga2V5IGluIHIyLmVudHJpZXMpIGV4YW1pbmVLZXkoa2V5KTtcblx0ICAgIH0gZWxzZSB7XG5cdFx0Zm9yICh2YXIga2V5IGluIHIxLmVudHJpZXMpIGV4YW1pbmVLZXkoa2V5KTtcblx0XHRmb3IgKHZhciBrZXkgaW4gcjIuZW50cmllcykgZXhhbWluZUtleShrZXkpO1xuXHQgICAgfVxuXHR9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gd2Fsa1dpbGQod2Fsa2VyLCB3LCBrZXksIGspIHtcblx0aWYgKGlzX2VtcHR5TWF0Y2hlcih3KSkgcmV0dXJuO1xuXHRpZiAoaXNfa2V5T3BlbihrZXkpKSB7XG5cdCAgICB3YWxrZXIocndpbGRzZXEodyksIGspO1xuXHQgICAgcmV0dXJuO1xuXHR9XG5cdGlmIChpc19rZXlDbG9zZShrZXkpKSB7XG5cdCAgICBpZiAodyBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB3YWxrZXIody5tYXRjaGVyLCBrKTtcblx0ICAgIHJldHVybjtcblx0fVxuXHR3YWxrZXIodywgayk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBhcHBlbmRNYXRjaGVyKG0sIG1UYWlsRm4pIHtcbiAgICByZXR1cm4gd2FsayhtKTtcblxuICAgIGZ1bmN0aW9uIHdhbGsobSkge1xuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKG0pKSByZXR1cm4gZW1wdHlNYXRjaGVyO1xuXHRpZiAobSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSByZXR1cm4gcndpbGRzZXEod2FsayhtLm1hdGNoZXIpKTtcblx0aWYgKG0gaW5zdGFuY2VvZiAkU3VjY2VzcykgZGllKFwiSWxsLWZvcm1lZCBtYXRjaGVyXCIpO1xuXG5cdHZhciB0YXJnZXQgPSBuZXcgJERpY3QoKTtcblx0Zm9yICh2YXIga2V5IGluIG0uZW50cmllcykge1xuXHQgICAgdmFyIGsgPSBtLmdldChrZXkpO1xuXHQgICAgaWYgKGlzX2tleUNsb3NlKGtleSkgJiYgKGsgaW5zdGFuY2VvZiAkU3VjY2VzcykpIHtcblx0XHR0YXJnZXQgPSB1bmlvbih0YXJnZXQsIG1UYWlsRm4oay52YWx1ZSkpO1xuXHQgICAgfSBlbHNlIHtcblx0XHRydXBkYXRlSW5wbGFjZSh0YXJnZXQsIGtleSwgd2FsayhrKSk7XG5cdCAgICB9XG5cdH1cblx0cmV0dXJuIHRhcmdldC5lbXB0eUd1YXJkKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiByZWxhYmVsKG0sIGYpIHtcbiAgICByZXR1cm4gd2FsayhtKTtcblxuICAgIGZ1bmN0aW9uIHdhbGsobSkge1xuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKG0pKSByZXR1cm4gZW1wdHlNYXRjaGVyO1xuXHRpZiAobSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSByZXR1cm4gcndpbGRzZXEod2FsayhtLm1hdGNoZXIpKTtcblx0aWYgKG0gaW5zdGFuY2VvZiAkU3VjY2VzcykgcmV0dXJuIHJzdWNjZXNzKGYobS52YWx1ZSkpO1xuXG5cdHZhciB0YXJnZXQgPSBuZXcgJERpY3QoKTtcblx0Zm9yICh2YXIga2V5IGluIG0uZW50cmllcykge1xuXHQgICAgcnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBrZXksIHdhbGsobS5nZXQoa2V5KSkpO1xuXHR9XG5cdHJldHVybiB0YXJnZXQuZW1wdHlHdWFyZCgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY29tcGlsZVByb2plY3Rpb24oLyogcHJvamVjdGlvbiwgcHJvamVjdGlvbiwgLi4uICovKSB7XG4gICAgdmFyIG5hbWVzID0gW107XG4gICAgdmFyIGFjYyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG5cdHdhbGsoYXJndW1lbnRzW2ldKTtcbiAgICB9XG4gICAgYWNjLnB1c2goRU9BKTtcbiAgICByZXR1cm4ge25hbWVzOiBuYW1lcywgc3BlYzogYWNjfTtcblxuICAgIGZ1bmN0aW9uIHdhbGsocCkge1xuXHRpZiAoaXNDYXB0dXJlKHApKSB7XG5cdCAgICBuYW1lcy5wdXNoKGNhcHR1cmVOYW1lKHApKTtcblx0ICAgIGFjYy5wdXNoKFNPQyk7XG5cdCAgICB3YWxrKGNhcHR1cmVQYXR0ZXJuKHApKTtcblx0ICAgIGFjYy5wdXNoKEVPQyk7XG5cdCAgICByZXR1cm47XG5cdH1cblxuXHRpZiAoQXJyYXkuaXNBcnJheShwKSkge1xuXHQgICAgYWNjLnB1c2goU09BKTtcblx0ICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuXHRcdHdhbGsocFtpXSk7XG5cdCAgICB9XG5cdCAgICBhY2MucHVzaChFT0EpO1xuXHQgICAgcmV0dXJuO1xuXHR9XG5cblx0aWYgKHAgaW5zdGFuY2VvZiAkRW1iZWRkZWQpIHtcblx0ICAgIGRpZShcIkNhbm5vdCBlbWJlZCBtYXRjaGVyIGluIHByb2plY3Rpb25cIik7XG5cdH0gZWxzZSB7XG5cdCAgICBpZiAocCA9PT0gX18pIHtcblx0XHRhY2MucHVzaChwKTtcblx0ICAgIH0gZWxzZSB7XG5cdFx0YWNjLnB1c2goSlNPTi5zdHJpbmdpZnkocCkpO1xuXHQgICAgfVxuXHR9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBwcm9qZWN0aW9uVG9QYXR0ZXJuKHApIHtcbiAgICByZXR1cm4gd2FsayhwKTtcblxuICAgIGZ1bmN0aW9uIHdhbGsocCkge1xuXHRpZiAoaXNDYXB0dXJlKHApKSByZXR1cm4gd2FsayhjYXB0dXJlUGF0dGVybihwKSk7XG5cblx0aWYgKEFycmF5LmlzQXJyYXkocCkpIHtcblx0ICAgIHZhciByZXN1bHQgPSBbXTtcblx0ICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuXHRcdHJlc3VsdC5wdXNoKHdhbGsocFtpXSkpO1xuXHQgICAgfVxuXHQgICAgcmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdGlmIChwIGluc3RhbmNlb2YgJEVtYmVkZGVkKSB7XG5cdCAgICByZXR1cm4gcC5tYXRjaGVyO1xuXHR9IGVsc2Uge1xuXHQgICAgcmV0dXJuIHA7XG5cdH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIHByb2plY3QobSwgY29tcGlsZWRQcm9qZWN0aW9uKSB7XG4gICAgdmFyIHNwZWMgPSBjb21waWxlZFByb2plY3Rpb24uc3BlYztcbiAgICByZXR1cm4gd2FsayhmYWxzZSwgbSwgMCk7XG5cbiAgICBmdW5jdGlvbiB3YWxrKGlzQ2FwdHVyaW5nLCBtLCBzcGVjSW5kZXgpIHtcblx0aWYgKHNwZWNJbmRleCA+PSBzcGVjLmxlbmd0aCkge1xuXHQgICAgaWYgKGlzQ2FwdHVyaW5nKSBkaWUoXCJCYWQgc3BlY2lmaWNhdGlvbjogdW5jbG9zZWQgY2FwdHVyZVwiKTtcblx0ICAgIGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0XHRyZXR1cm4gcnNlcShFT0EsIHJzdWNjZXNzKHByb2plY3RTdWNjZXNzKG0udmFsdWUpKSk7XG5cdCAgICB9IGVsc2Uge1xuXHRcdHJldHVybiBlbXB0eU1hdGNoZXI7XG5cdCAgICB9XG5cdH1cblxuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKG0pKSByZXR1cm4gZW1wdHlNYXRjaGVyO1xuXG5cdHZhciBpdGVtID0gc3BlY1tzcGVjSW5kZXhdO1xuXHR2YXIgbmV4dEluZGV4ID0gc3BlY0luZGV4ICsgMTtcblxuXHRpZiAoaXRlbSA9PT0gRU9DKSB7XG5cdCAgICBpZiAoIWlzQ2FwdHVyaW5nKSBkaWUoXCJCYWQgc3BlY2lmaWNhdGlvbjogdW5lcHhlY3RlZCBFT0NcIik7XG5cdCAgICByZXR1cm4gd2FsayhmYWxzZSwgbSwgbmV4dEluZGV4KTtcblx0fVxuXG5cdGlmIChpdGVtID09PSBTT0MpIHtcblx0ICAgIGlmIChpc0NhcHR1cmluZykgZGllKFwiQmFkIHNwZWNpZmljYXRpb246IG5lc3RlZCBjYXB0dXJlXCIpO1xuXHQgICAgcmV0dXJuIHdhbGsodHJ1ZSwgbSwgbmV4dEluZGV4KTtcblx0fVxuXG5cdGlmIChpdGVtID09PSBfXykge1xuXHQgICAgaWYgKG0gaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHRcdGlmIChpc0NhcHR1cmluZykge1xuXHRcdCAgICByZXR1cm4gcndpbGQod2Fsayhpc0NhcHR1cmluZywgbSwgbmV4dEluZGV4KSk7XG5cdFx0fSBlbHNlIHtcblx0XHQgICAgcmV0dXJuIHdhbGsoaXNDYXB0dXJpbmcsIG0sIG5leHRJbmRleCk7XG5cdFx0fVxuXHQgICAgfVxuXG5cdCAgICBpZiAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSB7XG5cdFx0cmV0dXJuIGVtcHR5TWF0Y2hlcjtcblx0ICAgIH1cblxuXHQgICAgdmFyIHRhcmdldDtcblx0ICAgIGlmIChpc0NhcHR1cmluZykge1xuXHRcdHRhcmdldCA9IG5ldyAkRGljdCgpO1xuXHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwgX18sIHdhbGsoaXNDYXB0dXJpbmcsIG0uZ2V0KF9fKSwgbmV4dEluZGV4KSk7XG5cdFx0Zm9yICh2YXIga2V5IGluIG0uZW50cmllcykge1xuXHRcdCAgICBpZiAoa2V5ICE9PSBfXykge1xuXHRcdFx0dmFyIG1rID0gbS5nZXQoa2V5KTtcblx0XHRcdGlmIChpc19rZXlPcGVuKGtleSkpIHtcblx0XHRcdCAgICBmdW5jdGlvbiBjb250KG1rMikgeyByZXR1cm4gd2Fsayhpc0NhcHR1cmluZywgbWsyLCBuZXh0SW5kZXgpOyB9XG5cdFx0XHQgICAgcnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBrZXksIGNhcHR1cmVOZXN0ZWQobWssIGNvbnQpKTtcblx0XHRcdH0gZWxzZSBpZiAoaXNfa2V5Q2xvc2Uoa2V5KSkge1xuXHRcdFx0ICAgIC8vIGRvIG5vdGhpbmdcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHQgICAgcnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBrZXksIHdhbGsoaXNDYXB0dXJpbmcsIG1rLCBuZXh0SW5kZXgpKTtcblx0XHRcdH1cblx0XHQgICAgfVxuXHRcdH1cblx0ICAgIH0gZWxzZSB7XG5cdFx0dGFyZ2V0ID0gd2Fsayhpc0NhcHR1cmluZywgbS5nZXQoX18pLCBuZXh0SW5kZXgpO1xuXHRcdGZvciAodmFyIGtleSBpbiBtLmVudHJpZXMpIHtcblx0XHQgICAgaWYgKGtleSAhPT0gX18pIHtcblx0XHRcdHZhciBtayA9IG0uZ2V0KGtleSk7XG5cdFx0XHRpZiAoaXNfa2V5T3BlbihrZXkpKSB7XG5cdFx0XHQgICAgZnVuY3Rpb24gY29udChtazIpIHsgcmV0dXJuIHdhbGsoaXNDYXB0dXJpbmcsIG1rMiwgbmV4dEluZGV4KTsgfVxuXHRcdFx0ICAgIHRhcmdldCA9IHVuaW9uKHRhcmdldCwgc2tpcE5lc3RlZChtaywgY29udCkpO1xuXHRcdFx0fSBlbHNlIGlmIChpc19rZXlDbG9zZShrZXkpKSB7XG5cdFx0XHQgICAgLy8gZG8gbm90aGluZ1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdCAgICB0YXJnZXQgPSB1bmlvbih0YXJnZXQsIHdhbGsoaXNDYXB0dXJpbmcsIG1rLCBuZXh0SW5kZXgpKTtcblx0XHRcdH1cblx0XHQgICAgfVxuXHRcdH1cblx0ICAgIH1cblx0ICAgIHJldHVybiB0YXJnZXQ7XG5cdH1cblxuXHR2YXIgcmVzdWx0O1xuXHRpZiAobSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG5cdCAgICBpZiAoaXNfa2V5T3BlbihpdGVtKSkge1xuXHRcdHJlc3VsdCA9IHdhbGsoaXNDYXB0dXJpbmcsIHJ3aWxkc2VxKG0pLCBuZXh0SW5kZXgpO1xuXHQgICAgfSBlbHNlIGlmIChpc19rZXlDbG9zZShpdGVtKSkge1xuXHRcdHJlc3VsdCA9IHdhbGsoaXNDYXB0dXJpbmcsIG0ubWF0Y2hlciwgbmV4dEluZGV4KTtcblx0ICAgIH0gZWxzZSB7XG5cdFx0cmVzdWx0ID0gd2Fsayhpc0NhcHR1cmluZywgbSwgbmV4dEluZGV4KTtcblx0ICAgIH1cblx0fSBlbHNlIGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0ICAgIHJlc3VsdCA9IGVtcHR5TWF0Y2hlcjtcblx0fSBlbHNlIHtcblx0ICAgIGlmIChpc19rZXlPcGVuKGl0ZW0pKSB7XG5cdFx0cmVzdWx0ID0gd2Fsayhpc0NhcHR1cmluZywgcndpbGRzZXEobS5nZXQoX18pKSwgbmV4dEluZGV4KTtcblx0ICAgIH0gZWxzZSBpZiAoaXNfa2V5Q2xvc2UoaXRlbSkpIHtcblx0XHRyZXN1bHQgPSBlbXB0eU1hdGNoZXI7XG5cdCAgICB9IGVsc2Uge1xuXHRcdHJlc3VsdCA9IHdhbGsoaXNDYXB0dXJpbmcsIG0uZ2V0KF9fKSwgbmV4dEluZGV4KTtcblx0ICAgIH1cblx0ICAgIHJlc3VsdCA9IHVuaW9uKHJlc3VsdCwgd2Fsayhpc0NhcHR1cmluZywgbS5nZXQoaXRlbSksIG5leHRJbmRleCkpO1xuXHR9XG5cdGlmIChpc0NhcHR1cmluZykge1xuXHQgICAgcmVzdWx0ID0gcnNlcShpdGVtLCByZXN1bHQpO1xuXHR9XG5cdHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FwdHVyZU5lc3RlZChtLCBjb250KSB7XG5cdGlmIChtIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0ICAgIHJldHVybiByd2lsZHNlcShjb250KG0ubWF0Y2hlcikpO1xuXHR9XG5cblx0aWYgKGlzX2VtcHR5TWF0Y2hlcihtKSB8fCAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSkge1xuXHQgICAgcmV0dXJuIGVtcHR5TWF0Y2hlcjtcblx0fVxuXG5cdHZhciB0YXJnZXQgPSBuZXcgJERpY3QoKTtcblx0cnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBfXywgY2FwdHVyZU5lc3RlZChtLmdldChfXyksIGNvbnQpKTtcblx0Zm9yICh2YXIga2V5IGluIG0uZW50cmllcykge1xuXHQgICAgaWYgKGtleSAhPT0gX18pIHtcblx0XHR2YXIgbWsgPSBtLmdldChrZXkpO1xuXHRcdGlmIChpc19rZXlPcGVuKGtleSkpIHtcblx0XHQgICAgZnVuY3Rpb24gY29udDIobWsyKSB7IHJldHVybiBjYXB0dXJlTmVzdGVkKG1rMiwgY29udCk7IH1cblx0XHQgICAgcnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBrZXksIGNhcHR1cmVOZXN0ZWQobWssIGNvbnQyKSk7XG5cdFx0fSBlbHNlIGlmIChpc19rZXlDbG9zZShrZXkpKSB7XG5cdFx0ICAgIHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCBjb250KG1rKSk7XG5cdFx0fSBlbHNlIHtcblx0XHQgICAgcnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBrZXksIGNhcHR1cmVOZXN0ZWQobWssIGNvbnQpKTtcblx0XHR9XG5cdCAgICB9XG5cdH1cblx0cmV0dXJuIHRhcmdldC5lbXB0eUd1YXJkKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2tpcE5lc3RlZChtLCBjb250KSB7XG5cdGlmIChtIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0ICAgIHJldHVybiBjb250KG0ubWF0Y2hlcik7XG5cdH1cblxuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKG0pIHx8IChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpKSB7XG5cdCAgICByZXR1cm4gZW1wdHlNYXRjaGVyO1xuXHR9XG5cblx0dmFyIHRhcmdldCA9IHNraXBOZXN0ZWQobS5nZXQoX18pLCBjb250KTtcblx0Zm9yICh2YXIga2V5IGluIG0uZW50cmllcykge1xuXHQgICAgaWYgKGtleSAhPT0gX18pIHtcblx0XHR2YXIgbWsgPSBtLmdldChrZXkpO1xuXHRcdGlmIChpc19rZXlPcGVuKGtleSkpIHtcblx0XHQgICAgZnVuY3Rpb24gY29udDIobWsyKSB7IHJldHVybiBza2lwTmVzdGVkKG1rMiwgY29udCk7IH1cblx0XHQgICAgdGFyZ2V0ID0gdW5pb24odGFyZ2V0LCBza2lwTmVzdGVkKG1rLCBjb250MikpO1xuXHRcdH0gZWxzZSBpZiAoaXNfa2V5Q2xvc2Uoa2V5KSkge1xuXHRcdCAgICB0YXJnZXQgPSB1bmlvbih0YXJnZXQsIGNvbnQobWspKTtcblx0XHR9IGVsc2Uge1xuXHRcdCAgICB0YXJnZXQgPSB1bmlvbih0YXJnZXQsIHNraXBOZXN0ZWQobWssIGNvbnQpKTtcblx0XHR9XG5cdCAgICB9XG5cdH1cblx0cmV0dXJuIHRhcmdldDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXJLZXlzKG0pIHtcbiAgICBpZiAoaXNfZW1wdHlNYXRjaGVyKG0pKSByZXR1cm4gW107XG4gICAgcmV0dXJuIHdhbGtTZXEobSwgZnVuY3Rpb24gKHZzcywgdnNrKSB7IHJldHVybiB2c3M7IH0pO1xuXG4gICAgZnVuY3Rpb24gd2FsayhtLCBrKSB7XG5cdGlmIChtIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHJldHVybiBudWxsO1xuXHRpZiAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSByZXR1cm4gW107XG5cdGlmIChtLmhhcyhfXykpIHJldHVybiBudWxsO1xuXHR2YXIgYWNjID0gW107XG5cdGZvciAodmFyIGtleSBpbiBtLmVudHJpZXMpIHtcblx0ICAgIHZhciBtayA9IG0uZ2V0KGtleSk7XG5cdCAgICB2YXIgcGllY2U7XG5cdCAgICBpZiAoaXNfa2V5T3BlbihrZXkpKSB7XG5cdFx0ZnVuY3Rpb24gc2VxSyh2c3MsIHZzaykge1xuXHRcdCAgICB2YXIgYWNjID0gW107XG5cdFx0ICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdnNzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR2YXIgdnMgPSB2c3NbaV07XG5cdFx0XHRhY2MgPSBhY2MuY29uY2F0KGsodHJhbnNmb3JtU2Vxcyh2cywga2V5KSwgdnNrKSk7XG5cdFx0ICAgIH1cblx0XHQgICAgcmV0dXJuIGFjYztcblx0XHR9XG5cdFx0cGllY2UgPSB3YWxrU2VxKG1rLCBzZXFLKTtcblx0ICAgIH0gZWxzZSBpZiAoaXNfa2V5Q2xvc2Uoa2V5KSkge1xuXHRcdGRpZShcIm1hdGNoZXJLZXlzOiBpbnRlcm5hbCBlcnJvcjogdW5leHBlY3RlZCBrZXktY2xvc2VcIik7XG5cdCAgICB9IGVsc2Uge1xuXHRcdHBpZWNlID0gayhKU09OLnBhcnNlKGtleSksIG1rKTtcblx0ICAgIH1cblx0ICAgIGlmIChwaWVjZSA9PSBudWxsKSByZXR1cm4gbnVsbDtcblx0ICAgIGFjYyA9IGFjYy5jb25jYXQocGllY2UpO1xuXHR9XG5cdHJldHVybiBhY2M7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gd2Fsa1NlcShtLCBrKSB7XG5cdGlmIChtIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHJldHVybiBudWxsO1xuXHRpZiAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSByZXR1cm4gayhbXSwgZW1wdHlNYXRjaGVyKTsgLy8gVE9ETzogPz9cblx0aWYgKG0uaGFzKF9fKSkgcmV0dXJuIG51bGw7XG5cdHZhciBhY2MgPSBbXTtcblx0Zm9yICh2YXIga2V5IGluIG0uZW50cmllcykge1xuXHQgICAgdmFyIG1rID0gbS5nZXQoa2V5KTtcblx0ICAgIHZhciBwaWVjZTtcblx0ICAgIGlmIChpc19rZXlDbG9zZShrZXkpKSB7XG5cdFx0cGllY2UgPSBrKFtbXV0sIG1rKTtcblx0ICAgIH0gZWxzZSB7XG5cdFx0ZnVuY3Rpb24gb3V0ZXJLKHYsIHZrKSB7XG5cdFx0ICAgIHJldHVybiB3YWxrU2VxKHZrLCBpbm5lckspO1xuXHRcdCAgICBmdW5jdGlvbiBpbm5lcksodnNzLCB2c2spIHtcblx0XHRcdHZhciBhY2MgPSBbXTtcblx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwgdnNzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHQgICAgdmFyIHZzID0gc2hhbGxvd0NvcHlBcnJheSh2c3NbaV0pO1xuXHRcdFx0ICAgIHZzLnVuc2hpZnQodik7XG5cdFx0XHQgICAgYWNjLnB1c2godnMpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGsoYWNjLCB2c2spO1xuXHRcdCAgICB9XG5cdFx0fVxuXHRcdHBpZWNlID0gd2Fsayhyc2VxKGtleSwgbWspLCBvdXRlckspO1xuXHQgICAgfVxuXHQgICAgaWYgKHBpZWNlID09IG51bGwpIHJldHVybiBudWxsO1xuXHQgICAgYWNjID0gYWNjLmNvbmNhdChwaWVjZSk7XG5cdH1cblx0cmV0dXJuIGFjYztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0cmFuc2Zvcm1TZXFzKHZzLCBvcGVuZXIpIHtcblx0aWYgKG9wZW5lciA9PT0gU09BKSByZXR1cm4gdnM7XG5cdGRpZShcIkludGVybmFsIGVycm9yOiB1bmtub3duIG9wZW5lciBcIiArIG9wZW5lcik7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBtYXRjaGVyS2V5c1RvT2JqZWN0cyhtYXRjaGVyS2V5c1Jlc3VsdCwgY29tcGlsZWRQcm9qZWN0aW9uKSB7XG4gICAgaWYgKG1hdGNoZXJLZXlzUmVzdWx0ID09PSBudWxsKSByZXR1cm4gbnVsbDtcbiAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXRjaGVyS2V5c1Jlc3VsdC5sZW5ndGg7IGkrKykge1xuXHR2YXIgZSA9IG1hdGNoZXJLZXlzUmVzdWx0W2ldO1xuXHR2YXIgZCA9IHt9O1xuXHRmb3IgKHZhciBqID0gMDsgaiA8IGUubGVuZ3RoOyBqKyspIHtcblx0ICAgIGRbY29tcGlsZWRQcm9qZWN0aW9uLm5hbWVzW2pdIHx8ICgnJCcgKyBqKV0gPSBlW2pdO1xuXHR9XG5cdHJlc3VsdC5wdXNoKGQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBwcm9qZWN0T2JqZWN0cyhtLCBjb21waWxlZFByb2plY3Rpb24pIHtcbiAgICByZXR1cm4gbWF0Y2hlcktleXNUb09iamVjdHMobWF0Y2hlcktleXMocHJvamVjdChtLCBjb21waWxlZFByb2plY3Rpb24pKSwgY29tcGlsZWRQcm9qZWN0aW9uKTtcbn1cblxuZnVuY3Rpb24gcHJldHR5TWF0Y2hlcihtLCBpbml0aWFsSW5kZW50KSB7XG4gICAgdmFyIGFjYyA9IFtdO1xuICAgIHdhbGsoaW5pdGlhbEluZGVudCB8fCAwLCBtKTtcbiAgICByZXR1cm4gYWNjLmpvaW4oJycpO1xuXG4gICAgZnVuY3Rpb24gd2FsayhpLCBtKSB7XG5cdGlmIChpc19lbXB0eU1hdGNoZXIobSkpIHtcblx0ICAgIGFjYy5wdXNoKFwiOjo6IG5vIGZ1cnRoZXIgbWF0Y2hlcyBwb3NzaWJsZVwiKTtcblx0ICAgIHJldHVybjtcblx0fVxuXHRpZiAobSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG5cdCAgICBhY2MucHVzaChcIi4uLj5cIik7XG5cdCAgICB3YWxrKGkgKyA0LCBtLm1hdGNoZXIpO1xuXHQgICAgcmV0dXJuO1xuXHR9XG5cdGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0ICAgIHZhciB2cyA9IEpTT04uc3RyaW5naWZ5KHR5cGVvZiBtLnZhbHVlID09PSAnb2JqZWN0J1xuXHRcdFx0XHQgICAgPyBzZXRUb0FycmF5KG0udmFsdWUpXG5cdFx0XHRcdCAgICA6IG0udmFsdWUpO1xuXHQgICAgYWNjLnB1c2goXCJ7XCIgKyB2cyArIFwifVwiKTtcblx0ICAgIHJldHVybjtcblx0fVxuXG5cdGlmIChtLmxlbmd0aCA9PT0gMCkge1xuXHQgICAgYWNjLnB1c2goXCIgOjo6IGVtcHR5IGhhc2ghXCIpO1xuXHQgICAgcmV0dXJuO1xuXHR9XG5cblx0dmFyIG5lZWRTZXAgPSBmYWxzZTtcblx0dmFyIGtleXMgPSBtLnNvcnRlZEtleXMoKTtcblx0Zm9yICh2YXIga2V5aSA9IDA7IGtleWkgPCBrZXlzLmxlbmd0aDsga2V5aSsrKSB7XG5cdCAgICB2YXIga2V5ID0ga2V5c1trZXlpXTtcblx0ICAgIHZhciBrID0gbS5lbnRyaWVzW2tleV07XG5cdCAgICBpZiAobmVlZFNlcCkge1xuXHRcdGFjYy5wdXNoKFwiXFxuXCIpO1xuXHRcdGFjYy5wdXNoKGluZGVudFN0cihpKSk7XG5cdCAgICB9IGVsc2Uge1xuXHRcdG5lZWRTZXAgPSB0cnVlO1xuXHQgICAgfVxuXHQgICAgYWNjLnB1c2goXCIgXCIpO1xuXHQgICAgaWYgKGtleSA9PT0gX18pIGtleSA9ICfimIUnO1xuXHQgICAgaWYgKGtleSA9PT0gU09BKSBrZXkgPSAnPCc7XG5cdCAgICBpZiAoa2V5ID09PSBFT0EpIGtleSA9ICc+Jztcblx0ICAgIGFjYy5wdXNoKGtleSk7XG5cdCAgICB3YWxrKGkgKyBrZXkubGVuZ3RoICsgMSwgayk7XG5cdH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbmRlbnRTdHIoaSkge1xuXHRyZXR1cm4gbmV3IEFycmF5KGkgKyAxKS5qb2luKCcgJyk7IC8vIGV3d1xuICAgIH1cbn1cblxuZnVuY3Rpb24gc2VyaWFsaXplTWF0Y2hlcihtLCBzZXJpYWxpemVTdWNjZXNzKSB7XG4gICAgcmV0dXJuIHdhbGsobSk7XG4gICAgZnVuY3Rpb24gd2FsayhtKSB7XG5cdGlmIChpc19lbXB0eU1hdGNoZXIobSkpIHJldHVybiBbXTtcblx0aWYgKG0gaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHQgICAgcmV0dXJuIFtcIi4uLilcIiwgd2FsayhtLm1hdGNoZXIpXTtcblx0fVxuXHRpZiAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSB7XG5cdCAgICByZXR1cm4gW1wiXCIsIHNlcmlhbGl6ZVN1Y2Nlc3MobS52YWx1ZSldO1xuXHR9XG5cdHZhciBhY2MgPSBbXTtcblx0Zm9yICh2YXIga2V5IGluIG0uZW50cmllcykge1xuXHQgICAgdmFyIGsgPSBtLmVudHJpZXNba2V5XTtcblx0ICAgIGlmIChrZXkgPT09IF9fKSBrZXkgPSBbXCJfX1wiXTtcblx0ICAgIGVsc2UgaWYgKGtleSA9PT0gU09BKSBrZXkgPSBbXCIoXCJdO1xuXHQgICAgZWxzZSBpZiAoa2V5ID09PSBFT0EpIGtleSA9IFtcIilcIl07XG5cdCAgICBlbHNlIGtleSA9IEpTT04ucGFyc2Uoa2V5KTtcblx0ICAgIGFjYy5wdXNoKFtrZXksIHdhbGsoayldKTtcblx0fVxuXHRyZXR1cm4gYWNjO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZGVzZXJpYWxpemVNYXRjaGVyKHIsIGRlc2VyaWFsaXplU3VjY2Vzcykge1xuICAgIHJldHVybiB3YWxrKHIpO1xuICAgIGZ1bmN0aW9uIHdhbGsocikge1xuXHRpZiAoci5sZW5ndGggPT09IDApIHJldHVybiBlbXB0eU1hdGNoZXI7XG5cdGlmIChyWzBdID09PSBcIi4uLilcIikgcmV0dXJuIHJ3aWxkc2VxKHdhbGsoclsxXSkpO1xuXHRpZiAoclswXSA9PT0gXCJcIikgcmV0dXJuIHJzdWNjZXNzKGRlc2VyaWFsaXplU3VjY2VzcyhyWzFdKSk7XG5cdHZhciBhY2MgPSBuZXcgJERpY3QoKTtcblx0Zm9yICh2YXIgaSA9IDA7IGkgPCByLmxlbmd0aDsgaSsrKSB7XG5cdCAgICB2YXIgcmtleSA9IHJbaV1bMF07XG5cdCAgICB2YXIgcmsgPSByW2ldWzFdO1xuXHQgICAgdmFyIGtleTtcblx0ICAgIGlmIChBcnJheS5pc0FycmF5KHJrZXkpKSB7XG5cdFx0c3dpdGNoIChya2V5WzBdKSB7XG5cdFx0Y2FzZSBcIl9fXCI6IGtleSA9IF9fOyBicmVhaztcblx0XHRjYXNlIFwiKFwiOiBrZXkgPSBTT0E7IGJyZWFrO1xuXHRcdGNhc2UgXCIpXCI6IGtleSA9IEVPQTsgYnJlYWs7XG5cdFx0ZGVmYXVsdDogZGllKFwiSW52YWxpZCBzZXJpYWxpemVkIHNwZWNpYWwga2V5OiBcIiArIHJrZXlbMF0pO1xuXHRcdH1cblx0ICAgIH0gZWxzZSB7XG5cdFx0a2V5ID0gSlNPTi5zdHJpbmdpZnkocmtleSk7XG5cdCAgICB9XG5cdCAgICBydXBkYXRlSW5wbGFjZShhY2MsIGtleSwgd2FsayhyaykpO1xuXHR9XG5cdHJldHVybiBhY2M7XG4gICAgfVxufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIEdlc3RhbHRzLlxuLy8gVE9ETzogc3VwcG9ydCBJbmZpbml0eSBhcyBhIGxldmVsIG51bWJlclxuXG5mdW5jdGlvbiBHZXN0YWx0TGV2ZWwoc3VicywgYWR2cykge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucyA9IHN1YnM7XG4gICAgdGhpcy5hZHZlcnRpc2VtZW50cyA9IGFkdnM7XG59XG5cbkdlc3RhbHRMZXZlbC5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gaXNfZW1wdHlNYXRjaGVyKHRoaXMuc3Vic2NyaXB0aW9ucykgJiYgaXNfZW1wdHlNYXRjaGVyKHRoaXMuYWR2ZXJ0aXNlbWVudHMpO1xufTtcblxuR2VzdGFsdExldmVsLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgICByZXR1cm4gbWF0Y2hlckVxdWFscyh0aGlzLnN1YnNjcmlwdGlvbnMsIG90aGVyLnN1YnNjcmlwdGlvbnMpXG5cdCYmIG1hdGNoZXJFcXVhbHModGhpcy5hZHZlcnRpc2VtZW50cywgb3RoZXIuYWR2ZXJ0aXNlbWVudHMpO1xufTtcblxuR2VzdGFsdExldmVsLnByb3RvdHlwZS5wcmV0dHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFjYyA9IFtdO1xuICAgIGlmICghaXNfZW1wdHlNYXRjaGVyKHRoaXMuc3Vic2NyaXB0aW9ucykpIHtcblx0YWNjLnB1c2goXCIgIC0gc3ViczpcIik7XG5cdGFjYy5wdXNoKHByZXR0eU1hdGNoZXIodGhpcy5zdWJzY3JpcHRpb25zLCA5KSk7XG5cdGFjYy5wdXNoKFwiXFxuXCIpO1xuICAgIH1cbiAgICBpZiAoIWlzX2VtcHR5TWF0Y2hlcih0aGlzLmFkdmVydGlzZW1lbnRzKSkge1xuXHRhY2MucHVzaChcIiAgLSBhZHZzOlwiKTtcblx0YWNjLnB1c2gocHJldHR5TWF0Y2hlcih0aGlzLmFkdmVydGlzZW1lbnRzLCA5KSk7XG5cdGFjYy5wdXNoKFwiXFxuXCIpO1xuICAgIH1cbiAgICByZXR1cm4gYWNjLmpvaW4oJycpO1xufTtcblxuZnVuY3Rpb24gc3RyYWlnaHRHZXN0YWx0TGV2ZWxPcChvcCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAocDEsIHAyKSB7XG5cdHJldHVybiBuZXcgR2VzdGFsdExldmVsKG9wKHAxLnN1YnNjcmlwdGlvbnMsIHAyLnN1YnNjcmlwdGlvbnMpLFxuXHRcdFx0XHRvcChwMS5hZHZlcnRpc2VtZW50cywgcDIuYWR2ZXJ0aXNlbWVudHMpKTtcbiAgICB9O1xufTtcblxudmFyIGVtcHR5TGV2ZWwgPSBuZXcgR2VzdGFsdExldmVsKGVtcHR5TWF0Y2hlciwgZW1wdHlNYXRjaGVyKTtcbnZhciBlbXB0eU1ldGFMZXZlbCA9IFtdO1xuXG5mdW5jdGlvbiBHZXN0YWx0KG1ldGFMZXZlbHMpIHtcbiAgICB0aGlzLm1ldGFMZXZlbHMgPSBtZXRhTGV2ZWxzO1xufVxuXG5HZXN0YWx0LnByb3RvdHlwZS5nZXRNZXRhTGV2ZWwgPSBmdW5jdGlvbiAobikge1xuICAgIHJldHVybiB0aGlzLm1ldGFMZXZlbHNbbl0gfHwgZW1wdHlNZXRhTGV2ZWw7XG59O1xuXG5HZXN0YWx0LnByb3RvdHlwZS5nZXRMZXZlbCA9IGZ1bmN0aW9uIChtZXRhTGV2ZWwsIGxldmVsKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TWV0YUxldmVsKG1ldGFMZXZlbClbbGV2ZWxdIHx8IGVtcHR5TGV2ZWw7XG59O1xuXG5HZXN0YWx0LnByb3RvdHlwZS5tZXRhTGV2ZWxDb3VudCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMubWV0YUxldmVscy5sZW5ndGg7IH07XG5HZXN0YWx0LnByb3RvdHlwZS5sZXZlbENvdW50ID0gZnVuY3Rpb24gKG4pIHsgcmV0dXJuIHRoaXMuZ2V0TWV0YUxldmVsKG4pLmxlbmd0aDsgfTtcblxuR2VzdGFsdC5wcm90b3R5cGUubWF0Y2hWYWx1ZSA9IGZ1bmN0aW9uIChib2R5LCBtZXRhTGV2ZWwsIGlzRmVlZGJhY2spIHtcbiAgICB2YXIgbGV2ZWxzID0gdGhpcy5nZXRNZXRhTGV2ZWwobWV0YUxldmVsKTtcbiAgICB2YXIgcGlkcyA9IHt9O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGV2ZWxzLmxlbmd0aDsgaSsrKSB7XG5cdHZhciBtYXRjaGVyID0gKGlzRmVlZGJhY2sgPyBsZXZlbHNbaV0uYWR2ZXJ0aXNlbWVudHMgOiBsZXZlbHNbaV0uc3Vic2NyaXB0aW9ucyk7XG5cdHNldFVuaW9uSW5wbGFjZShwaWRzLCBtYXRjaFZhbHVlKG1hdGNoZXIsIGJvZHkpKTtcbiAgICB9XG4gICAgcmV0dXJuIHNldFRvQXJyYXkocGlkcyk7XG59O1xuXG5HZXN0YWx0LnByb3RvdHlwZS5wcm9qZWN0ID0gZnVuY3Rpb24gKHNwZWMsIGdldEFkdmVydGlzZW1lbnRzLCBtZXRhTGV2ZWwsIGxldmVsKSB7XG4gICAgdmFyIGwgPSB0aGlzLmdldExldmVsKG1ldGFMZXZlbCB8IDAsIGxldmVsIHwgMCk7XG4gICAgdmFyIG1hdGNoZXIgPSAoZ2V0QWR2ZXJ0aXNlbWVudHMgPyBsLmFkdmVydGlzZW1lbnRzIDogbC5zdWJzY3JpcHRpb25zKTtcbiAgICByZXR1cm4gcHJvamVjdChtYXRjaGVyLCBzcGVjKTtcbn07XG5cbkdlc3RhbHQucHJvdG90eXBlLmRyb3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG1scyA9IHNoYWxsb3dDb3B5QXJyYXkodGhpcy5tZXRhTGV2ZWxzKTtcbiAgICBtbHMuc2hpZnQoKTtcbiAgICByZXR1cm4gbmV3IEdlc3RhbHQobWxzKTtcbn07XG5cbkdlc3RhbHQucHJvdG90eXBlLmxpZnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG1scyA9IHNoYWxsb3dDb3B5QXJyYXkodGhpcy5tZXRhTGV2ZWxzKTtcbiAgICBtbHMudW5zaGlmdChlbXB0eU1ldGFMZXZlbCk7XG4gICAgcmV0dXJuIG5ldyBHZXN0YWx0KG1scyk7XG59O1xuXG5HZXN0YWx0LnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgICBpZiAodGhpcy5tZXRhTGV2ZWxzLmxlbmd0aCAhPT0gb3RoZXIubWV0YUxldmVscy5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubWV0YUxldmVscy5sZW5ndGg7IGkrKykge1xuXHR2YXIgbHMxID0gdGhpcy5tZXRhTGV2ZWxzW2ldO1xuXHR2YXIgbHMyID0gb3RoZXIubWV0YUxldmVsc1tpXTtcblx0aWYgKGxzMS5sZW5ndGggIT09IGxzMi5sZW5ndGgpIHJldHVybiBmYWxzZTtcblx0Zm9yICh2YXIgaiA9IDA7IGogPCBsczEubGVuZ3RoOyBqKyspIHtcblx0ICAgIHZhciBwMSA9IGxzMVtqXTtcblx0ICAgIHZhciBwMiA9IGxzMltqXTtcblx0ICAgIGlmICghcDEuZXF1YWxzKHAyKSkgcmV0dXJuIGZhbHNlO1xuXHR9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gc2ltcGxlR2VzdGFsdChpc0FkdiwgcGF0LCBtZXRhTGV2ZWwsIGxldmVsKSB7XG4gICAgbWV0YUxldmVsID0gbWV0YUxldmVsIHx8IDA7XG4gICAgbGV2ZWwgPSBsZXZlbCB8fCAwO1xuICAgIHZhciBtYXRjaGVyID0gY29tcGlsZVBhdHRlcm4odHJ1ZSwgcGF0KTtcbiAgICB2YXIgbCA9IG5ldyBHZXN0YWx0TGV2ZWwoaXNBZHYgPyBlbXB0eU1hdGNoZXIgOiBtYXRjaGVyLFxuXHRcdFx0ICAgICBpc0FkdiA/IG1hdGNoZXIgOiBlbXB0eU1hdGNoZXIpO1xuICAgIHZhciBsZXZlbHMgPSBbbF07XG4gICAgd2hpbGUgKGxldmVsLS0pIHsgbGV2ZWxzLnVuc2hpZnQoZW1wdHlMZXZlbCk7IH1cbiAgICB2YXIgbWV0YUxldmVscyA9IFtsZXZlbHNdO1xuICAgIHdoaWxlIChtZXRhTGV2ZWwtLSkgeyBtZXRhTGV2ZWxzLnVuc2hpZnQoZW1wdHlNZXRhTGV2ZWwpOyB9XG4gICAgcmV0dXJuIG5ldyBHZXN0YWx0KG1ldGFMZXZlbHMpO1xufVxuXG52YXIgZW1wdHlHZXN0YWx0ID0gbmV3IEdlc3RhbHQoW10pO1xuXG4vLyBOb3QgcXVpdGUgd2hhdCBpdCBzYXlzIG9uIHRoZSB0aW4gLSB0aGUgdHJ1ZSBmdWxsR2VzdGFsdFxuLy8gd291bGRuJ3QgYmUgcGFyYW1ldGVyaXplZCBvbiB0aGUgbnVtYmVyIG9mIGxldmVscyBhbmRcbi8vIG1ldGFsZXZlbHMsIGJ1dCBpbnN0ZWFkIHdvdWxkIGJlIGZ1bGwgYXQgKmFsbCogbGV2ZWxzIGFuZFxuLy8gbWV0YWxldmVscy4gT3VyIHJlcHJlc2VudGF0aW9uIGxlYWtzIHRocm91Z2ggaW50byB0aGUgaW50ZXJmYWNlXG4vLyBoZXJlIDotL1xuZnVuY3Rpb24gZnVsbEdlc3RhbHQobk1ldGFsZXZlbHMsIG5MZXZlbHMpIHtcbiAgICB2YXIgbWF0Y2hlciA9IGNvbXBpbGVQYXR0ZXJuKHRydWUsIF9fKTtcbiAgICB2YXIgbCA9IG5ldyBHZXN0YWx0TGV2ZWwobWF0Y2hlciwgbWF0Y2hlcik7XG4gICAgdmFyIGxldmVscyA9IFtdO1xuICAgIHdoaWxlIChuTGV2ZWxzLS0pIHsgbGV2ZWxzLnB1c2gobCk7IH1cbiAgICB2YXIgbWV0YUxldmVscyA9IFtdO1xuICAgIHdoaWxlIChuTWV0YWxldmVscy0tKSB7IG1ldGFMZXZlbHMucHVzaChsZXZlbHMpOyB9XG4gICAgcmV0dXJuIG5ldyBHZXN0YWx0KG1ldGFMZXZlbHMpO1xufVxuXG5HZXN0YWx0LnByb3RvdHlwZS5pc0VtcHR5ID0gZnVuY3Rpb24gKCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tZXRhTGV2ZWxzLmxlbmd0aDsgaSsrKSB7XG5cdHZhciBsZXZlbHMgPSB0aGlzLm1ldGFMZXZlbHNbaV07XG5cdGZvciAodmFyIGogPSAwOyBqIDwgbGV2ZWxzLmxlbmd0aDsgaisrKSB7XG5cdCAgICBpZiAoIWxldmVsc1tqXS5pc0VtcHR5KCkpIHJldHVybiBmYWxzZTtcblx0fVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5cbmZ1bmN0aW9uIG1heWJlUHVzaExldmVsKGxldmVscywgaSwgbGV2ZWwpIHtcbiAgICBpZiAoIWxldmVsLmlzRW1wdHkoKSkge1xuXHR3aGlsZSAobGV2ZWxzLmxlbmd0aCA8IGkpIGxldmVscy5wdXNoKGVtcHR5TGV2ZWwpO1xuXHRsZXZlbHMucHVzaChsZXZlbCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBtYXliZVB1c2hNZXRhTGV2ZWwobWV0YUxldmVscywgaSwgbWV0YUxldmVsKSB7XG4gICAgaWYgKG1ldGFMZXZlbC5sZW5ndGggPiAwKSB7XG5cdHdoaWxlIChtZXRhTGV2ZWxzLmxlbmd0aCA8IGkpIG1ldGFMZXZlbHMucHVzaChlbXB0eU1ldGFMZXZlbCk7XG5cdG1ldGFMZXZlbHMucHVzaChtZXRhTGV2ZWwpO1xuICAgIH1cbn1cblxuR2VzdGFsdC5wcm90b3R5cGUubWFwWmlwID0gZnVuY3Rpb24gKG90aGVyLCBsZW5ndGhDb21iaW5lciwgZikge1xuICAgIHZhciBtZXRhTGV2ZWxzID0gW107XG4gICAgdmFyIG1sczEgPSB0aGlzLm1ldGFMZXZlbHM7XG4gICAgdmFyIG1sczIgPSBvdGhlci5tZXRhTGV2ZWxzO1xuICAgIHZhciBubSA9IGxlbmd0aENvbWJpbmVyKG1sczEubGVuZ3RoLCBtbHMyLmxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBubTsgaSsrKSB7XG5cdHZhciBsZXZlbHMgPSBbXTtcblx0dmFyIGxzMSA9IG1sczFbaV0gfHwgZW1wdHlNZXRhTGV2ZWw7XG5cdHZhciBsczIgPSBtbHMyW2ldIHx8IGVtcHR5TWV0YUxldmVsO1xuXHR2YXIgbmwgPSBsZW5ndGhDb21iaW5lcihsczEubGVuZ3RoLCBsczIubGVuZ3RoKTtcblx0Zm9yICh2YXIgaiA9IDA7IGogPCBubDsgaisrKSB7XG5cdCAgICB2YXIgcDEgPSBsczFbal0gfHwgZW1wdHlMZXZlbDtcblx0ICAgIHZhciBwMiA9IGxzMltqXSB8fCBlbXB0eUxldmVsO1xuXHQgICAgdmFyIHAgPSBmKHAxLCBwMik7XG5cdCAgICBtYXliZVB1c2hMZXZlbChsZXZlbHMsIGosIHApO1xuXHR9XG5cdG1heWJlUHVzaE1ldGFMZXZlbChtZXRhTGV2ZWxzLCBpLCBsZXZlbHMpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEdlc3RhbHQobWV0YUxldmVscyk7XG59O1xuXG5HZXN0YWx0LnByb3RvdHlwZS51bmlvbjEgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgICByZXR1cm4gdGhpcy5tYXBaaXAob3RoZXIsIE1hdGgubWF4LCBzdHJhaWdodEdlc3RhbHRMZXZlbE9wKHVuaW9uKSk7XG59O1xuXG5mdW5jdGlvbiBnZXN0YWx0VW5pb24oZ3MpIHtcbiAgICBpZiAoZ3MubGVuZ3RoID09PSAwKSByZXR1cm4gZW1wdHlHZXN0YWx0O1xuICAgIHZhciBhY2MgPSBnc1swXTtcbiAgICBmb3IgKHZhciBpID0gMTsgaSA8IGdzLmxlbmd0aDsgaSsrKSB7XG5cdGFjYyA9IGFjYy51bmlvbjEoZ3NbaV0pO1xuICAgIH1cbiAgICByZXR1cm4gYWNjO1xufVxuXG5HZXN0YWx0LnByb3RvdHlwZS51bmlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA+IDAgPyB0aGlzLnVuaW9uMShnZXN0YWx0VW5pb24oYXJndW1lbnRzKSkgOiB0aGlzO1xufTtcblxuLy8gQWNjdW11bGF0ZXMgbWF0Y2hlcnMgZnJvbSBoaWdoZXItbnVtYmVyZWQgbGV2ZWxzIGludG9cbi8vIGxvd2VyLW51bWJlcmVkIGxldmVscy5cbmZ1bmN0aW9uIHRlbGVzY29wZUxldmVscyhsZXZlbHMpIHtcbiAgICB2YXIgcmVzdWx0ID0gc2hhbGxvd0NvcHlBcnJheShsZXZlbHMpO1xuICAgIGZvciAodmFyIGkgPSByZXN1bHQubGVuZ3RoIC0gMjsgaSA+PSAwOyBpLS0pIHtcblx0cmVzdWx0W2ldID1cblx0ICAgIG5ldyBHZXN0YWx0TGV2ZWwodW5pb24ocmVzdWx0W2ldLnN1YnNjcmlwdGlvbnMsIHJlc3VsdFtpKzFdLnN1YnNjcmlwdGlvbnMpLFxuXHRcdFx0ICAgICB1bmlvbihyZXN1bHRbaV0uYWR2ZXJ0aXNlbWVudHMsIHJlc3VsdFtpKzFdLmFkdmVydGlzZW1lbnRzKSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59O1xuXG5HZXN0YWx0LnByb3RvdHlwZS50ZWxlc2NvcGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBtbHMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubWV0YUxldmVscy5sZW5ndGg7IGkrKykge1xuXHRtbHMucHVzaCh0ZWxlc2NvcGVMZXZlbHModGhpcy5tZXRhTGV2ZWxzW2ldKSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgR2VzdGFsdChtbHMpO1xufTtcblxuR2VzdGFsdC5wcm90b3R5cGUuZmlsdGVyID0gZnVuY3Rpb24gKHBlcnNwZWN0aXZlKSB7XG4gICAgdmFyIG1ldGFMZXZlbHMgPSBbXTtcbiAgICB2YXIgbWxzMSA9IHRoaXMubWV0YUxldmVscztcbiAgICB2YXIgbWxzMiA9IHBlcnNwZWN0aXZlLm1ldGFMZXZlbHM7XG4gICAgdmFyIG5tID0gTWF0aC5taW4obWxzMS5sZW5ndGgsIG1sczIubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5tOyBpKyspIHtcblx0dmFyIGxldmVscyA9IFtdO1xuXHR2YXIgbHMxID0gbWxzMVtpXSB8fCBlbXB0eU1ldGFMZXZlbDtcblx0dmFyIGxzMiA9IG1sczJbaV0gfHwgZW1wdHlNZXRhTGV2ZWw7XG5cdHZhciBubCA9IE1hdGgubWluKGxzMS5sZW5ndGgsIGxzMi5sZW5ndGggLSAxKTtcblx0Zm9yICh2YXIgaiA9IDA7IGogPCBubDsgaisrKSB7XG5cdCAgICB2YXIgcDEgPSBsczFbal0gfHwgZW1wdHlMZXZlbDtcblx0ICAgIHZhciBzdWJzID0gZW1wdHlNYXRjaGVyO1xuXHQgICAgdmFyIGFkdnMgPSBlbXB0eU1hdGNoZXI7XG5cdCAgICBmb3IgKHZhciBrID0gaiArIDE7IGsgPCBsczIubGVuZ3RoOyBrKyspIHtcblx0XHR2YXIgcDIgPSBsczJba10gfHwgZW1wdHlMZXZlbDtcblx0XHRzdWJzID0gdW5pb24oc3VicywgaW50ZXJzZWN0KHAxLnN1YnNjcmlwdGlvbnMsIHAyLmFkdmVydGlzZW1lbnRzKSk7XG5cdFx0YWR2cyA9IHVuaW9uKGFkdnMsIGludGVyc2VjdChwMS5hZHZlcnRpc2VtZW50cywgcDIuc3Vic2NyaXB0aW9ucykpO1xuXHQgICAgfVxuXHQgICAgbWF5YmVQdXNoTGV2ZWwobGV2ZWxzLCBqLCBuZXcgR2VzdGFsdExldmVsKHN1YnMsIGFkdnMpKTtcblx0fVxuXHRtYXliZVB1c2hNZXRhTGV2ZWwobWV0YUxldmVscywgaSwgbGV2ZWxzKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBHZXN0YWx0KG1ldGFMZXZlbHMpO1xufTtcblxuR2VzdGFsdC5wcm90b3R5cGUubWF0Y2ggPSBmdW5jdGlvbiAocGVyc3BlY3RpdmUpIHtcbiAgICB2YXIgcGlkcyA9IHt9O1xuICAgIHZhciBubSA9IE1hdGgubWluKHRoaXMubWV0YUxldmVscy5sZW5ndGgsIHBlcnNwZWN0aXZlLm1ldGFMZXZlbHMubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5tOyBpKyspIHtcblx0dmFyIGxzMSA9IHRoaXMubWV0YUxldmVsc1tpXSB8fCBlbXB0eU1ldGFMZXZlbDtcblx0dmFyIGxzMiA9IHBlcnNwZWN0aXZlLm1ldGFMZXZlbHNbaV0gfHwgZW1wdHlNZXRhTGV2ZWw7XG5cdHZhciBubCA9IE1hdGgubWluKGxzMS5sZW5ndGgsIGxzMi5sZW5ndGggLSAxKTtcblx0Zm9yICh2YXIgaiA9IDA7IGogPCBubDsgaisrKSB7XG5cdCAgICB2YXIgcDEgPSBsczFbal0gfHwgZW1wdHlMZXZlbDtcblx0ICAgIGZvciAodmFyIGsgPSBqICsgMTsgayA8IGxzMi5sZW5ndGg7IGsrKykge1xuXHRcdHZhciBwMiA9IGxzMltrXSB8fCBlbXB0eUxldmVsO1xuXHRcdG1hdGNoTWF0Y2hlcihwMS5zdWJzY3JpcHRpb25zLCBwMi5hZHZlcnRpc2VtZW50cywgcGlkcyk7XG5cdFx0bWF0Y2hNYXRjaGVyKHAxLmFkdmVydGlzZW1lbnRzLCBwMi5zdWJzY3JpcHRpb25zLCBwaWRzKTtcblx0ICAgIH1cblx0fVxuICAgIH1cbiAgICByZXR1cm4gc2V0VG9BcnJheShwaWRzKTtcbn07XG5cbkdlc3RhbHQucHJvdG90eXBlLmVyYXNlUGF0aCA9IGZ1bmN0aW9uIChwYXRoKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwWmlwKHBhdGgsIE1hdGgubWF4LCBzdHJhaWdodEdlc3RhbHRMZXZlbE9wKGVyYXNlUGF0aCkpO1xufTtcblxuZnVuY3Rpb24gbWFwTGV2ZWxzKGlucHV0TWV0YUxldmVscywgZiwgZW1wdHlDaGVjaywgaW5wdXRFbXB0eUxldmVsLCBvdXRwdXRFbXB0eUxldmVsKSB7XG4gICAgdmFyIG91dHB1dE1ldGFMZXZlbHMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGlucHV0TWV0YUxldmVscy5sZW5ndGg7IGkrKykge1xuXHR2YXIgbHMgPSBpbnB1dE1ldGFMZXZlbHNbaV07XG5cdHZhciBsZXZlbHMgPSBbXTtcblx0Zm9yICh2YXIgaiA9IDA7IGogPCBscy5sZW5ndGg7IGorKykge1xuXHQgICAgdmFyIHAgPSBmKGxzW2pdIHx8IGlucHV0RW1wdHlMZXZlbCwgaSwgaik7XG5cdCAgICBpZiAoIWVtcHR5Q2hlY2socCwgaSwgaikpIHtcblx0XHR3aGlsZSAobGV2ZWxzLmxlbmd0aCA8IGopIGxldmVscy5wdXNoKG91dHB1dEVtcHR5TGV2ZWwpO1xuXHRcdGxldmVscy5wdXNoKHApO1xuXHQgICAgfVxuXHR9XG5cdGlmIChsZXZlbHMubGVuZ3RoID4gMCkge1xuXHQgICAgd2hpbGUgKG91dHB1dE1ldGFMZXZlbHMubGVuZ3RoIDwgaSkgb3V0cHV0TWV0YUxldmVscy5wdXNoKGVtcHR5TWV0YUxldmVsKTtcblx0ICAgIG91dHB1dE1ldGFMZXZlbHMucHVzaChsZXZlbHMpO1xuXHR9XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXRNZXRhTGV2ZWxzO1xufTtcblxuR2VzdGFsdC5wcm90b3R5cGUudHJhbnNmb3JtID0gZnVuY3Rpb24gKGYpIHtcbiAgICByZXR1cm4gbmV3IEdlc3RhbHQobWFwTGV2ZWxzKHRoaXMubWV0YUxldmVscywgZnVuY3Rpb24gKHAsIG1sLCBsKSB7XG5cdHJldHVybiBuZXcgR2VzdGFsdExldmVsKGYocC5zdWJzY3JpcHRpb25zLCBtbCwgbCwgZmFsc2UpLFxuXHRcdFx0XHRmKHAuYWR2ZXJ0aXNlbWVudHMsIG1sLCBsLCB0cnVlKSk7XG4gICAgfSwgZnVuY3Rpb24gKHApIHtcblx0cmV0dXJuIHAuaXNFbXB0eSgpO1xuICAgIH0sIGVtcHR5TGV2ZWwsIGVtcHR5TGV2ZWwpKTtcbn07XG5cbkdlc3RhbHQucHJvdG90eXBlLnN0cmlwTGFiZWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtKGZ1bmN0aW9uIChtKSB7IHJldHVybiByZWxhYmVsKG0sIGZ1bmN0aW9uICh2KSB7IHJldHVybiB0cnVlOyB9KTsgfSk7XG59O1xuXG5HZXN0YWx0LnByb3RvdHlwZS5sYWJlbCA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgICB2YXIgcGlkcyA9IGFycmF5VG9TZXQoW3BpZF0pO1xuICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybShmdW5jdGlvbiAobSkgeyByZXR1cm4gcmVsYWJlbChtLCBmdW5jdGlvbiAodikgeyByZXR1cm4gcGlkczsgfSk7IH0pO1xufTtcblxuR2VzdGFsdC5wcm90b3R5cGUucHJldHR5ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhY2MgPSBbXTtcbiAgICBpZiAodGhpcy5pc0VtcHR5KCkpIHtcblx0YWNjLnB1c2goXCJFTVBUWSBHRVNUQUxUXFxuXCIpO1xuICAgIH0gZWxzZSB7XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tZXRhTGV2ZWxzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICB2YXIgbHMgPSB0aGlzLm1ldGFMZXZlbHNbaV07XG5cdCAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxzLmxlbmd0aDsgaisrKSB7XG5cdFx0dmFyIHAgPSBsc1tqXTtcblx0XHRpZiAoIXAuaXNFbXB0eSgpKSB7XG5cdFx0ICAgIGFjYy5wdXNoKFwiR0VTVEFMVCBtZXRhbGV2ZWwgXCIgKyBpICsgXCIgbGV2ZWwgXCIgKyBqICsgXCI6XFxuXCIpO1xuXHRcdCAgICBhY2MucHVzaChwLnByZXR0eSgpKTtcblx0XHR9XG5cdCAgICB9XG5cdH1cbiAgICB9XG4gICAgcmV0dXJuIGFjYy5qb2luKCcnKTtcbn07XG5cbkdlc3RhbHQucHJvdG90eXBlLnNlcmlhbGl6ZSA9IGZ1bmN0aW9uIChzZXJpYWxpemVTdWNjZXNzKSB7XG4gICAgaWYgKHR5cGVvZiBzZXJpYWxpemVTdWNjZXNzID09PSAndW5kZWZpbmVkJykge1xuXHRzZXJpYWxpemVTdWNjZXNzID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHYgPT09IHRydWUgPyB0cnVlIDogc2V0VG9BcnJheSh2KTsgfTtcbiAgICB9XG4gICAgcmV0dXJuIFtcImdlc3RhbHRcIiwgbWFwTGV2ZWxzKHRoaXMubWV0YUxldmVscywgZnVuY3Rpb24gKHApIHtcblx0cmV0dXJuIFtzZXJpYWxpemVNYXRjaGVyKHAuc3Vic2NyaXB0aW9ucywgc2VyaWFsaXplU3VjY2VzcyksXG5cdFx0c2VyaWFsaXplTWF0Y2hlcihwLmFkdmVydGlzZW1lbnRzLCBzZXJpYWxpemVTdWNjZXNzKV07XG4gICAgfSwgZnVuY3Rpb24gKHByKSB7XG5cdHJldHVybiBwci5sZW5ndGggPT09IDIgJiYgcHJbMF0ubGVuZ3RoID09PSAwICYmIHByWzFdLmxlbmd0aCA9PT0gMDtcbiAgICB9LCBlbXB0eUxldmVsLCBbW10sW11dKV07XG59O1xuXG5mdW5jdGlvbiBkZXNlcmlhbGl6ZUdlc3RhbHQociwgZGVzZXJpYWxpemVTdWNjZXNzKSB7XG4gICAgaWYgKHR5cGVvZiBkZXNlcmlhbGl6ZVN1Y2Nlc3MgPT09ICd1bmRlZmluZWQnKSB7XG5cdGRlc2VyaWFsaXplU3VjY2VzcyA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiB2ID09PSB0cnVlID8gdHJ1ZSA6IGFycmF5VG9TZXQodik7IH07XG4gICAgfVxuICAgIGlmIChyWzBdICE9PSBcImdlc3RhbHRcIikgZGllKFwiSW52YWxpZCBnZXN0YWx0IHNlcmlhbGl6YXRpb246IFwiICsgcik7XG4gICAgcmV0dXJuIG5ldyBHZXN0YWx0KG1hcExldmVscyhyWzFdLCBmdW5jdGlvbiAocHIpIHtcblx0cmV0dXJuIG5ldyBHZXN0YWx0TGV2ZWwoZGVzZXJpYWxpemVNYXRjaGVyKHByWzBdLCBkZXNlcmlhbGl6ZVN1Y2Nlc3MpLFxuXHRcdFx0XHRkZXNlcmlhbGl6ZU1hdGNoZXIocHJbMV0sIGRlc2VyaWFsaXplU3VjY2VzcykpO1xuICAgIH0sIGZ1bmN0aW9uIChwKSB7XG5cdHJldHVybiBwLmlzRW1wdHkoKTtcbiAgICB9LCBbW10sW11dLCBlbXB0eUxldmVsKSk7XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy5fXyA9IF9fO1xubW9kdWxlLmV4cG9ydHMuYXJyYXlUb1NldCA9IGFycmF5VG9TZXQ7XG5tb2R1bGUuZXhwb3J0cy5zZXRUb0FycmF5ID0gc2V0VG9BcnJheTtcbm1vZHVsZS5leHBvcnRzLnNldFVuaW9uID0gc2V0VW5pb247XG5tb2R1bGUuZXhwb3J0cy5zZXRTdWJ0cmFjdCA9IHNldFN1YnRyYWN0O1xubW9kdWxlLmV4cG9ydHMuc2V0SW50ZXJzZWN0ID0gc2V0SW50ZXJzZWN0O1xubW9kdWxlLmV4cG9ydHMuc2V0RXF1YWwgPSBzZXRFcXVhbDtcbm1vZHVsZS5leHBvcnRzLmlzX2VtcHR5U2V0ID0gaXNfZW1wdHlTZXQ7XG5tb2R1bGUuZXhwb3J0cy4kQ2FwdHVyZSA9ICRDYXB0dXJlO1xubW9kdWxlLmV4cG9ydHMuXyQgPSBfJDtcbm1vZHVsZS5leHBvcnRzLmlzX2VtcHR5TWF0Y2hlciA9IGlzX2VtcHR5TWF0Y2hlcjtcbm1vZHVsZS5leHBvcnRzLmVtcHR5TWF0Y2hlciA9IGVtcHR5TWF0Y2hlcjtcbm1vZHVsZS5leHBvcnRzLmVtYmVkZGVkTWF0Y2hlciA9IGVtYmVkZGVkTWF0Y2hlcjtcbm1vZHVsZS5leHBvcnRzLmNvbXBpbGVQYXR0ZXJuID0gY29tcGlsZVBhdHRlcm47XG5tb2R1bGUuZXhwb3J0cy5tYXRjaFBhdHRlcm4gPSBtYXRjaFBhdHRlcm47XG5tb2R1bGUuZXhwb3J0cy51bmlvbiA9IHVuaW9uTjtcbm1vZHVsZS5leHBvcnRzLmludGVyc2VjdCA9IGludGVyc2VjdDtcbm1vZHVsZS5leHBvcnRzLmVyYXNlUGF0aCA9IGVyYXNlUGF0aDtcbm1vZHVsZS5leHBvcnRzLm1hdGNoVmFsdWUgPSBtYXRjaFZhbHVlO1xubW9kdWxlLmV4cG9ydHMubWF0Y2hNYXRjaGVyID0gbWF0Y2hNYXRjaGVyO1xubW9kdWxlLmV4cG9ydHMuYXBwZW5kTWF0Y2hlciA9IGFwcGVuZE1hdGNoZXI7XG5tb2R1bGUuZXhwb3J0cy5yZWxhYmVsID0gcmVsYWJlbDtcbm1vZHVsZS5leHBvcnRzLmNvbXBpbGVQcm9qZWN0aW9uID0gY29tcGlsZVByb2plY3Rpb247XG5tb2R1bGUuZXhwb3J0cy5wcm9qZWN0aW9uVG9QYXR0ZXJuID0gcHJvamVjdGlvblRvUGF0dGVybjtcbm1vZHVsZS5leHBvcnRzLnByb2plY3QgPSBwcm9qZWN0O1xubW9kdWxlLmV4cG9ydHMubWF0Y2hlcktleXMgPSBtYXRjaGVyS2V5cztcbm1vZHVsZS5leHBvcnRzLm1hdGNoZXJLZXlzVG9PYmplY3RzID0gbWF0Y2hlcktleXNUb09iamVjdHM7XG5tb2R1bGUuZXhwb3J0cy5wcm9qZWN0T2JqZWN0cyA9IHByb2plY3RPYmplY3RzO1xubW9kdWxlLmV4cG9ydHMubWF0Y2hlckVxdWFscyA9IG1hdGNoZXJFcXVhbHM7XG5tb2R1bGUuZXhwb3J0cy5wcmV0dHlNYXRjaGVyID0gcHJldHR5TWF0Y2hlcjtcbm1vZHVsZS5leHBvcnRzLnNlcmlhbGl6ZU1hdGNoZXIgPSBzZXJpYWxpemVNYXRjaGVyO1xubW9kdWxlLmV4cG9ydHMuZGVzZXJpYWxpemVNYXRjaGVyID0gZGVzZXJpYWxpemVNYXRjaGVyO1xuXG5tb2R1bGUuZXhwb3J0cy5HZXN0YWx0TGV2ZWwgPSBHZXN0YWx0TGV2ZWw7XG5tb2R1bGUuZXhwb3J0cy5HZXN0YWx0ID0gR2VzdGFsdDtcbm1vZHVsZS5leHBvcnRzLnNpbXBsZUdlc3RhbHQgPSBzaW1wbGVHZXN0YWx0O1xubW9kdWxlLmV4cG9ydHMuZW1wdHlHZXN0YWx0ID0gZW1wdHlHZXN0YWx0O1xubW9kdWxlLmV4cG9ydHMuZnVsbEdlc3RhbHQgPSBmdWxsR2VzdGFsdDtcbm1vZHVsZS5leHBvcnRzLmdlc3RhbHRVbmlvbiA9IGdlc3RhbHRVbmlvbjtcbm1vZHVsZS5leHBvcnRzLmRlc2VyaWFsaXplR2VzdGFsdCA9IGRlc2VyaWFsaXplR2VzdGFsdDtcbiIsInZhciBNaW5pbWFydCA9IHJlcXVpcmUoXCIuL21pbmltYXJ0LmpzXCIpO1xudmFyIFJvdXRlID0gTWluaW1hcnQuUm91dGU7XG52YXIgV29ybGQgPSBNaW5pbWFydC5Xb3JsZDtcbnZhciBzdWIgPSBNaW5pbWFydC5zdWI7XG52YXIgcHViID0gTWluaW1hcnQucHViO1xudmFyIF9fID0gTWluaW1hcnQuX187XG5cbmZ1bmN0aW9uIHNwYXduUm91dGluZ1RhYmxlV2lkZ2V0KHNlbGVjdG9yLCBmcmFnbWVudENsYXNzLCBkb21XcmFwLCBvYnNlcnZhdGlvbkxldmVsKSB7XG4gICAgb2JzZXJ2YXRpb25MZXZlbCA9IG9ic2VydmF0aW9uTGV2ZWwgfHwgMTA7XG4gICAgLy8gXiBhcmJpdHJhcnk6IHNob3VsZCBiZSBJbmZpbml0eSwgd2hlbiByb3V0ZS5qcyBzdXBwb3J0cyBpdC4gVE9ET1xuICAgIGRvbVdyYXAgPSBkb21XcmFwIHx8IE1pbmltYXJ0LkRPTS5kZWZhdWx0V3JhcEZ1bmN0aW9uO1xuXG4gICAgV29ybGQuc3Bhd24oe1xuXHRib290OiBmdW5jdGlvbiAoKSB7IHRoaXMudXBkYXRlU3RhdGUoKTsgfSxcblxuXHRzdGF0ZTogUm91dGUuZW1wdHlHZXN0YWx0LnNlcmlhbGl6ZSgpLFxuXHRuZXh0U3RhdGU6IFJvdXRlLmVtcHR5R2VzdGFsdC5zZXJpYWxpemUoKSxcblx0dGltZXI6IGZhbHNlLFxuXG5cdGxvY2FsR2VzdGFsdDogKHN1YiggICAgICAgZG9tV3JhcChzZWxlY3RvciwgZnJhZ21lbnRDbGFzcywgX18pLCAwLCAyKVxuXHRcdCAgICAgICAudW5pb24ocHViKGRvbVdyYXAoc2VsZWN0b3IsIGZyYWdtZW50Q2xhc3MsIF9fKSwgMCwgMikpXG5cdFx0ICAgICAgIC50ZWxlc2NvcGVkKCkpLFxuXG5cdGRpZ2VzdEdlc3RhbHQ6IGZ1bmN0aW9uIChnKSB7XG5cdCAgICByZXR1cm4gZy5zdHJpcExhYmVsKCkuZXJhc2VQYXRoKHRoaXMubG9jYWxHZXN0YWx0KS5zZXJpYWxpemUoKTtcblx0fSxcblxuXHR1cGRhdGVTdGF0ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgdmFyIGVsdHMgPSBbXCJwcmVcIiwgUm91dGUuZGVzZXJpYWxpemVHZXN0YWx0KHRoaXMuc3RhdGUpLnByZXR0eSgpXTtcblx0ICAgIFdvcmxkLnVwZGF0ZVJvdXRlcyhbc3ViKF9fLCAwLCBvYnNlcnZhdGlvbkxldmVsKSxcblx0XHRcdFx0cHViKF9fLCAwLCBvYnNlcnZhdGlvbkxldmVsKSxcblx0XHRcdFx0cHViKGRvbVdyYXAoc2VsZWN0b3IsIGZyYWdtZW50Q2xhc3MsIGVsdHMpKV0pO1xuXHR9LFxuXG5cdGhhbmRsZUV2ZW50OiBmdW5jdGlvbiAoZSkge1xuXHQgICAgdmFyIHNlbGYgPSB0aGlzO1xuXHQgICAgaWYgKGUudHlwZSA9PT0gXCJyb3V0ZXNcIikge1xuXHRcdHNlbGYubmV4dFN0YXRlID0gc2VsZi5kaWdlc3RHZXN0YWx0KGUuZ2VzdGFsdCk7XG5cdFx0aWYgKHNlbGYudGltZXIpIHtcblx0XHQgICAgY2xlYXJUaW1lb3V0KHNlbGYudGltZXIpO1xuXHRcdCAgICBzZWxmLnRpbWVyID0gZmFsc2U7XG5cdFx0fVxuXHRcdHNlbGYudGltZXIgPSBzZXRUaW1lb3V0KFdvcmxkLndyYXAoZnVuY3Rpb24gKCkge1xuXHRcdCAgICBpZiAoSlNPTi5zdHJpbmdpZnkoc2VsZi5uZXh0U3RhdGUpICE9PSBKU09OLnN0cmluZ2lmeShzZWxmLnN0YXRlKSkge1xuXHRcdFx0c2VsZi5zdGF0ZSA9IHNlbGYubmV4dFN0YXRlO1xuXHRcdFx0c2VsZi51cGRhdGVTdGF0ZSgpO1xuXHRcdCAgICB9XG5cdFx0ICAgIHNlbGYudGltZXIgPSBmYWxzZTtcblx0XHR9KSwgNTApO1xuXHQgICAgfVxuXHR9XG4gICAgfSk7XG5cbn1cblxubW9kdWxlLmV4cG9ydHMuc3Bhd25Sb3V0aW5nVGFibGVXaWRnZXQgPSBzcGF3blJvdXRpbmdUYWJsZVdpZGdldDtcbiIsIi8vIEdlbmVyaWMgU3B5XG52YXIgTWluaW1hcnQgPSByZXF1aXJlKFwiLi9taW5pbWFydC5qc1wiKTtcbnZhciBXb3JsZCA9IE1pbmltYXJ0LldvcmxkO1xudmFyIHN1YiA9IE1pbmltYXJ0LnN1YjtcbnZhciBwdWIgPSBNaW5pbWFydC5wdWI7XG52YXIgX18gPSBNaW5pbWFydC5fXztcblxuZnVuY3Rpb24gU3B5KGxhYmVsLCB1c2VKc29uLCBvYnNlcnZhdGlvbkxldmVsKSB7XG4gICAgdGhpcy5sYWJlbCA9IGxhYmVsIHx8IFwiU1BZXCI7XG4gICAgdGhpcy5vYnNlcnZhdGlvbkxldmVsID0gb2JzZXJ2YXRpb25MZXZlbCB8fCAxMDsgLy8gYXJiaXRyYXJ5LiBTaG91bGQgYmUgSW5maW5pdHkuIFRPRE9cbiAgICB0aGlzLnVzZUpzb24gPSB1c2VKc29uO1xufVxuXG5TcHkucHJvdG90eXBlLmJvb3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgV29ybGQudXBkYXRlUm91dGVzKFtzdWIoX18sIDAsIHRoaXMub2JzZXJ2YXRpb25MZXZlbCksIHB1YihfXywgMCwgdGhpcy5vYnNlcnZhdGlvbkxldmVsKV0pO1xufTtcblxuU3B5LnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgc3dpdGNoIChlLnR5cGUpIHtcbiAgICBjYXNlIFwicm91dGVzXCI6XG5cdGNvbnNvbGUubG9nKHRoaXMubGFiZWwsIFwicm91dGVzXCIsIGUuZ2VzdGFsdC5wcmV0dHkoKSk7XG5cdGJyZWFrO1xuICAgIGNhc2UgXCJtZXNzYWdlXCI6XG5cdHZhciBtZXNzYWdlUmVwcjtcblx0dHJ5IHtcblx0ICAgIG1lc3NhZ2VSZXByID0gdGhpcy51c2VKc29uID8gSlNPTi5zdHJpbmdpZnkoZS5tZXNzYWdlKSA6IGUubWVzc2FnZTtcblx0fSBjYXRjaCAoZXhuKSB7XG5cdCAgICBtZXNzYWdlUmVwciA9IGUubWVzc2FnZTtcblx0fVxuXHRjb25zb2xlLmxvZyh0aGlzLmxhYmVsLCBcIm1lc3NhZ2VcIiwgbWVzc2FnZVJlcHIsIGUubWV0YUxldmVsLCBlLmlzRmVlZGJhY2spO1xuXHRicmVhaztcbiAgICBkZWZhdWx0OlxuXHRjb25zb2xlLmxvZyh0aGlzLmxhYmVsLCBcInVua25vd25cIiwgZSk7XG5cdGJyZWFrO1xuICAgIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzLlNweSA9IFNweTtcbiIsIi8vIFdha2UgZGV0ZWN0b3IgLSBub3RpY2VzIHdoZW4gc29tZXRoaW5nIChzdWNoIGFzXG4vLyBzdXNwZW5zaW9uL3NsZWVwaW5nISkgaGFzIGNhdXNlZCBwZXJpb2RpYyBhY3Rpdml0aWVzIHRvIGJlXG4vLyBpbnRlcnJ1cHRlZCwgYW5kIHdhcm5zIG90aGVycyBhYm91dCBpdFxuLy8gSW5zcGlyZWQgYnkgaHR0cDovL2Jsb2cuYWxleG1hY2Nhdy5jb20vamF2YXNjcmlwdC13YWtlLWV2ZW50XG52YXIgTWluaW1hcnQgPSByZXF1aXJlKFwiLi9taW5pbWFydC5qc1wiKTtcbnZhciBXb3JsZCA9IE1pbmltYXJ0LldvcmxkO1xudmFyIHN1YiA9IE1pbmltYXJ0LnN1YjtcbnZhciBwdWIgPSBNaW5pbWFydC5wdWI7XG52YXIgX18gPSBNaW5pbWFydC5fXztcblxuZnVuY3Rpb24gV2FrZURldGVjdG9yKHBlcmlvZCkge1xuICAgIHRoaXMubWVzc2FnZSA9IFwid2FrZVwiO1xuICAgIHRoaXMucGVyaW9kID0gcGVyaW9kIHx8IDEwMDAwO1xuICAgIHRoaXMubW9zdFJlY2VudFRyaWdnZXIgPSArKG5ldyBEYXRlKCkpO1xuICAgIHRoaXMudGltZXJJZCA9IG51bGw7XG59XG5cbldha2VEZXRlY3Rvci5wcm90b3R5cGUuYm9vdCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgV29ybGQudXBkYXRlUm91dGVzKFtwdWIodGhpcy5tZXNzYWdlKV0pO1xuICAgIHRoaXMudGltZXJJZCA9IHNldEludGVydmFsKFdvcmxkLndyYXAoZnVuY3Rpb24gKCkgeyBzZWxmLnRyaWdnZXIoKTsgfSksIHRoaXMucGVyaW9kKTtcbn07XG5cbldha2VEZXRlY3Rvci5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAoZSkge307XG5cbldha2VEZXRlY3Rvci5wcm90b3R5cGUudHJpZ2dlciA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbm93ID0gKyhuZXcgRGF0ZSgpKTtcbiAgICBpZiAobm93IC0gdGhpcy5tb3N0UmVjZW50VHJpZ2dlciA+IHRoaXMucGVyaW9kICogMS41KSB7XG5cdFdvcmxkLnNlbmQodGhpcy5tZXNzYWdlKTtcbiAgICB9XG4gICAgdGhpcy5tb3N0UmVjZW50VHJpZ2dlciA9IG5vdztcbn07XG5cbm1vZHVsZS5leHBvcnRzLldha2VEZXRlY3RvciA9IFdha2VEZXRlY3RvcjtcbiIsInZhciBNaW5pbWFydCA9IHJlcXVpcmUoXCIuL21pbmltYXJ0LmpzXCIpO1xudmFyIFJvdXRlID0gTWluaW1hcnQuUm91dGU7XG52YXIgV29ybGQgPSBNaW5pbWFydC5Xb3JsZDtcbnZhciBzdWIgPSBNaW5pbWFydC5zdWI7XG52YXIgcHViID0gTWluaW1hcnQucHViO1xudmFyIF9fID0gTWluaW1hcnQuX187XG52YXIgXyQgPSBNaW5pbWFydC5fJDtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXZWJTb2NrZXQgY2xpZW50IGRyaXZlclxuXG52YXIgREVGQVVMVF9SRUNPTk5FQ1RfREVMQVkgPSAxMDA7XG52YXIgTUFYX1JFQ09OTkVDVF9ERUxBWSA9IDMwMDAwO1xudmFyIERFRkFVTFRfSURMRV9USU1FT1VUID0gMzAwMDAwOyAvLyA1IG1pbnV0ZXNcbnZhciBERUZBVUxUX1BJTkdfSU5URVJWQUwgPSBERUZBVUxUX0lETEVfVElNRU9VVCAtIDEwMDAwO1xuXG5mdW5jdGlvbiBXZWJTb2NrZXRDb25uZWN0aW9uKGxhYmVsLCB3c3VybCwgc2hvdWxkUmVjb25uZWN0KSB7XG4gICAgdGhpcy5sYWJlbCA9IGxhYmVsO1xuICAgIHRoaXMuc2VuZHNBdHRlbXB0ZWQgPSAwO1xuICAgIHRoaXMuc2VuZHNUcmFuc21pdHRlZCA9IDA7XG4gICAgdGhpcy5yZWNlaXZlQ291bnQgPSAwO1xuICAgIHRoaXMuc29jayA9IG51bGw7XG4gICAgdGhpcy53c3VybCA9IHdzdXJsO1xuICAgIHRoaXMuc2hvdWxkUmVjb25uZWN0ID0gc2hvdWxkUmVjb25uZWN0ID8gdHJ1ZSA6IGZhbHNlO1xuICAgIHRoaXMucmVjb25uZWN0RGVsYXkgPSBERUZBVUxUX1JFQ09OTkVDVF9ERUxBWTtcbiAgICB0aGlzLmxvY2FsR2VzdGFsdCA9IFJvdXRlLmVtcHR5R2VzdGFsdDtcbiAgICB0aGlzLnBlZXJHZXN0YWx0ID0gUm91dGUuZW1wdHlHZXN0YWx0O1xuICAgIHRoaXMucHJldkxvY2FsUm91dGVzTWVzc2FnZSA9IG51bGw7XG4gICAgdGhpcy5wcmV2UGVlclJvdXRlc01lc3NhZ2UgPSBudWxsO1xuICAgIHRoaXMuZGVkdXBsaWNhdG9yID0gbmV3IE1pbmltYXJ0LkRlZHVwbGljYXRvcigpO1xuICAgIHRoaXMuY29ubmVjdGlvbkNvdW50ID0gMDtcblxuICAgIHRoaXMuYWN0aXZpdHlUaW1lc3RhbXAgPSAwO1xuICAgIHRoaXMuaWRsZVRpbWVvdXQgPSBERUZBVUxUX0lETEVfVElNRU9VVDtcbiAgICB0aGlzLnBpbmdJbnRlcnZhbCA9IERFRkFVTFRfUElOR19JTlRFUlZBTDtcbiAgICB0aGlzLmlkbGVUaW1lciA9IG51bGw7XG4gICAgdGhpcy5waW5nVGltZXIgPSBudWxsO1xufVxuXG5XZWJTb2NrZXRDb25uZWN0aW9uLnByb3RvdHlwZS5jbGVhckhlYXJ0YmVhdFRpbWVycyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5pZGxlVGltZXIpIHsgY2xlYXJUaW1lb3V0KHRoaXMuaWRsZVRpbWVyKTsgdGhpcy5pZGxlVGltZXIgPSBudWxsOyB9XG4gICAgaWYgKHRoaXMucGluZ1RpbWVyKSB7IGNsZWFyVGltZW91dCh0aGlzLnBpbmdUaW1lcik7IHRoaXMucGluZ1RpbWVyID0gbnVsbDsgfVxufTtcblxuV2ViU29ja2V0Q29ubmVjdGlvbi5wcm90b3R5cGUucmVjb3JkQWN0aXZpdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHRoaXMuYWN0aXZpdHlUaW1lc3RhbXAgPSArKG5ldyBEYXRlKCkpO1xuICAgIHRoaXMuY2xlYXJIZWFydGJlYXRUaW1lcnMoKTtcbiAgICB0aGlzLmlkbGVUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyBzZWxmLmZvcmNlY2xvc2UoKTsgfSxcblx0XHRcdFx0dGhpcy5pZGxlVGltZW91dCk7XG4gICAgdGhpcy5waW5nVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsgc2VsZi5zYWZlU2VuZChKU09OLnN0cmluZ2lmeShcInBpbmdcIikpIH0sXG5cdFx0XHRcdHRoaXMucGluZ0ludGVydmFsKTtcbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLnN0YXR1c1JvdXRlID0gZnVuY3Rpb24gKHN0YXR1cykge1xuICAgIHJldHVybiBwdWIoW3RoaXMubGFiZWwgKyBcIl9zdGF0ZVwiLCBzdGF0dXNdKTtcbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLnJlbGF5R2VzdGFsdCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0dXNSb3V0ZSh0aGlzLmlzQ29ubmVjdGVkKCkgPyBcImNvbm5lY3RlZFwiIDogXCJkaXNjb25uZWN0ZWRcIilcblx0LnVuaW9uKHB1YihbdGhpcy5sYWJlbCwgX18sIF9fXSwgMCwgMTApKVxuXHQudW5pb24oc3ViKFt0aGlzLmxhYmVsLCBfXywgX19dLCAwLCAxMCkpO1xuICAgIC8vIFRPRE86IGxldmVsIDEwIGlzIGFkLWhvYzsgc3VwcG9ydCBpbmZpbml0eSBhdCBzb21lIHBvaW50IGluIGZ1dHVyZVxufTtcblxuV2ViU29ja2V0Q29ubmVjdGlvbi5wcm90b3R5cGUuYWdncmVnYXRlR2VzdGFsdCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgcmV0dXJuIHRoaXMucGVlckdlc3RhbHQudHJhbnNmb3JtKGZ1bmN0aW9uIChtLCBtZXRhTGV2ZWwpIHtcblx0cmV0dXJuIFJvdXRlLmNvbXBpbGVQYXR0ZXJuKHRydWUsXG5cdFx0XHRcdCAgICBbc2VsZi5sYWJlbCwgbWV0YUxldmVsLCBSb3V0ZS5lbWJlZGRlZE1hdGNoZXIobSldKTtcbiAgICB9KS51bmlvbih0aGlzLnJlbGF5R2VzdGFsdCgpKTtcbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLmJvb3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5yZWNvbm5lY3QoKTtcbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLnRyYXBleGl0ID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZm9yY2VjbG9zZSgpO1xufTtcblxuV2ViU29ja2V0Q29ubmVjdGlvbi5wcm90b3R5cGUuaXNDb25uZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuc29jayAmJiB0aGlzLnNvY2sucmVhZHlTdGF0ZSA9PT0gdGhpcy5zb2NrLk9QRU47XG59O1xuXG5XZWJTb2NrZXRDb25uZWN0aW9uLnByb3RvdHlwZS5zYWZlU2VuZCA9IGZ1bmN0aW9uIChtKSB7XG4gICAgdHJ5IHtcblx0dGhpcy5zZW5kc0F0dGVtcHRlZCsrO1xuXHRpZiAodGhpcy5pc0Nvbm5lY3RlZCgpKSB7XG5cdCAgICB0aGlzLnNvY2suc2VuZChtKTtcblx0ICAgIHRoaXMuc2VuZHNUcmFuc21pdHRlZCsrO1xuXHR9XG4gICAgfSBjYXRjaCAoZSkge1xuXHRjb25zb2xlLndhcm4oXCJUcmFwcGVkIGV4biB3aGlsZSBzZW5kaW5nXCIsIGUpO1xuICAgIH1cbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLnNlbmRMb2NhbFJvdXRlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbmV3TG9jYWxSb3V0ZXNNZXNzYWdlID1cblx0SlNPTi5zdHJpbmdpZnkoZW5jb2RlRXZlbnQoTWluaW1hcnQudXBkYXRlUm91dGVzKFt0aGlzLmxvY2FsR2VzdGFsdF0pKSk7XG4gICAgaWYgKHRoaXMucHJldkxvY2FsUm91dGVzTWVzc2FnZSAhPT0gbmV3TG9jYWxSb3V0ZXNNZXNzYWdlKSB7XG5cdHRoaXMucHJldkxvY2FsUm91dGVzTWVzc2FnZSA9IG5ld0xvY2FsUm91dGVzTWVzc2FnZTtcblx0dGhpcy5zYWZlU2VuZChuZXdMb2NhbFJvdXRlc01lc3NhZ2UpO1xuICAgIH1cbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLmNvbGxlY3RNYXRjaGVycyA9IGZ1bmN0aW9uIChnZXRBZHZlcnRpc2VtZW50cywgbGV2ZWwsIGcpIHtcbiAgICB2YXIgZXh0cmFjdE1ldGFMZXZlbHMgPSBSb3V0ZS5jb21waWxlUHJvamVjdGlvbihbdGhpcy5sYWJlbCwgXyQsIF9fXSk7XG4gICAgdmFyIG1scyA9IFJvdXRlLm1hdGNoZXJLZXlzKGcucHJvamVjdChleHRyYWN0TWV0YUxldmVscywgZ2V0QWR2ZXJ0aXNlbWVudHMsIDAsIGxldmVsKSk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtbHMubGVuZ3RoOyBpKyspIHtcblx0dmFyIG1ldGFMZXZlbCA9IG1sc1tpXVswXTsgLy8gb25seSBvbmUgY2FwdHVyZSBpbiB0aGUgcHJvamVjdGlvblxuXHR2YXIgZXh0cmFjdE1hdGNoZXJzID0gUm91dGUuY29tcGlsZVByb2plY3Rpb24oW3RoaXMubGFiZWwsIG1ldGFMZXZlbCwgXyRdKTtcblx0dmFyIG0gPSBnLnByb2plY3QoZXh0cmFjdE1hdGNoZXJzLCBnZXRBZHZlcnRpc2VtZW50cywgMCwgbGV2ZWwpO1xuXHR0aGlzLmxvY2FsR2VzdGFsdCA9IHRoaXMubG9jYWxHZXN0YWx0LnVuaW9uKFJvdXRlLnNpbXBsZUdlc3RhbHQoZ2V0QWR2ZXJ0aXNlbWVudHMsXG5cdFx0XHRcdFx0XHRcdFx0XHRSb3V0ZS5lbWJlZGRlZE1hdGNoZXIobSksXG5cdFx0XHRcdFx0XHRcdFx0XHRtZXRhTGV2ZWwsXG5cdFx0XHRcdFx0XHRcdFx0XHRsZXZlbCkpO1xuICAgIH1cbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24gKGUpIHtcbiAgICAvLyBjb25zb2xlLmxvZyhcIldlYlNvY2tldENvbm5lY3Rpb24uaGFuZGxlRXZlbnRcIiwgZSk7XG4gICAgc3dpdGNoIChlLnR5cGUpIHtcbiAgICBjYXNlIFwicm91dGVzXCI6XG5cdC8vIFRPRE86IEdST1NTIC0gZXJhc2luZyBieSBwaWQhXG5cdHZhciBuTGV2ZWxzID0gZS5nZXN0YWx0LmxldmVsQ291bnQoMCk7XG5cdHZhciByZWxheUdlc3RhbHQgPSBSb3V0ZS5mdWxsR2VzdGFsdCgxLCBuTGV2ZWxzKS5sYWJlbChXb3JsZC5hY3RpdmVQaWQoKSk7XG5cdHZhciBnID0gZS5nZXN0YWx0LmVyYXNlUGF0aChyZWxheUdlc3RhbHQpO1xuXHR0aGlzLmxvY2FsR2VzdGFsdCA9IFJvdXRlLmVtcHR5R2VzdGFsdDtcblx0Zm9yICh2YXIgbGV2ZWwgPSAwOyBsZXZlbCA8IG5MZXZlbHM7IGxldmVsKyspIHtcblx0ICAgIHRoaXMuY29sbGVjdE1hdGNoZXJzKGZhbHNlLCBsZXZlbCwgZyk7XG5cdCAgICB0aGlzLmNvbGxlY3RNYXRjaGVycyh0cnVlLCBsZXZlbCwgZyk7XG5cdH1cblxuXHR0aGlzLnNlbmRMb2NhbFJvdXRlcygpO1xuXHRicmVhaztcbiAgICBjYXNlIFwibWVzc2FnZVwiOlxuXHR2YXIgbSA9IGUubWVzc2FnZTtcblx0aWYgKG0ubGVuZ3RoICYmIG0ubGVuZ3RoID09PSAzICYmIG1bMF0gPT09IHRoaXMubGFiZWwpXG5cdHtcblx0ICAgIHZhciBlbmNvZGVkID0gSlNPTi5zdHJpbmdpZnkoZW5jb2RlRXZlbnQoXG5cdFx0TWluaW1hcnQuc2VuZE1lc3NhZ2UobVsyXSwgbVsxXSwgZS5pc0ZlZWRiYWNrKSkpO1xuXHQgICAgaWYgKHRoaXMuZGVkdXBsaWNhdG9yLmFjY2VwdChlbmNvZGVkKSkge1xuXHRcdHRoaXMuc2FmZVNlbmQoZW5jb2RlZCk7XG5cdCAgICB9XG5cdH1cblx0YnJlYWs7XG4gICAgfVxufTtcblxuV2ViU29ja2V0Q29ubmVjdGlvbi5wcm90b3R5cGUuZm9yY2VjbG9zZSA9IGZ1bmN0aW9uIChrZWVwUmVjb25uZWN0RGVsYXkpIHtcbiAgICBpZiAoIWtlZXBSZWNvbm5lY3REZWxheSkge1xuXHR0aGlzLnJlY29ubmVjdERlbGF5ID0gREVGQVVMVF9SRUNPTk5FQ1RfREVMQVk7XG4gICAgfVxuICAgIHRoaXMuY2xlYXJIZWFydGJlYXRUaW1lcnMoKTtcbiAgICBpZiAodGhpcy5zb2NrKSB7XG5cdGNvbnNvbGUubG9nKFwiV2ViU29ja2V0Q29ubmVjdGlvbi5mb3JjZWNsb3NlIGNhbGxlZFwiKTtcblx0dGhpcy5zb2NrLmNsb3NlKCk7XG5cdHRoaXMuc29jayA9IG51bGw7XG4gICAgfVxufTtcblxuV2ViU29ja2V0Q29ubmVjdGlvbi5wcm90b3R5cGUucmVjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB0aGlzLmZvcmNlY2xvc2UodHJ1ZSk7XG4gICAgdGhpcy5jb25uZWN0aW9uQ291bnQrKztcbiAgICB0aGlzLnNvY2sgPSBuZXcgV2ViU29ja2V0KHRoaXMud3N1cmwpO1xuICAgIHRoaXMuc29jay5vbm9wZW4gPSBXb3JsZC53cmFwKGZ1bmN0aW9uIChlKSB7IHJldHVybiBzZWxmLm9ub3BlbihlKTsgfSk7XG4gICAgdGhpcy5zb2NrLm9ubWVzc2FnZSA9IFdvcmxkLndyYXAoZnVuY3Rpb24gKGUpIHtcblx0c2VsZi5yZWNlaXZlQ291bnQrKztcblx0cmV0dXJuIHNlbGYub25tZXNzYWdlKGUpO1xuICAgIH0pO1xuICAgIHRoaXMuc29jay5vbmNsb3NlID0gV29ybGQud3JhcChmdW5jdGlvbiAoZSkgeyByZXR1cm4gc2VsZi5vbmNsb3NlKGUpOyB9KTtcbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLm9ub3BlbiA9IGZ1bmN0aW9uIChlKSB7XG4gICAgY29uc29sZS5sb2coXCJjb25uZWN0ZWQgdG8gXCIgKyB0aGlzLnNvY2sudXJsKTtcbiAgICB0aGlzLnJlY29ubmVjdERlbGF5ID0gREVGQVVMVF9SRUNPTk5FQ1RfREVMQVk7XG4gICAgdGhpcy5wcmV2TG9jYWxSb3V0ZXNNZXNzYWdlID0gbnVsbDtcbiAgICB0aGlzLnNlbmRMb2NhbFJvdXRlcygpO1xufTtcblxuV2ViU29ja2V0Q29ubmVjdGlvbi5wcm90b3R5cGUub25tZXNzYWdlID0gZnVuY3Rpb24gKHdzZSkge1xuICAgIC8vIGNvbnNvbGUubG9nKFwib25tZXNzYWdlXCIsIHdzZSk7XG4gICAgdGhpcy5yZWNvcmRBY3Rpdml0eSgpO1xuXG4gICAgdmFyIGogPSBKU09OLnBhcnNlKHdzZS5kYXRhKTtcbiAgICBpZiAoaiA9PT0gXCJwaW5nXCIpIHtcblx0dGhpcy5zYWZlU2VuZChKU09OLnN0cmluZ2lmeShcInBvbmdcIikpO1xuXHRyZXR1cm47XG4gICAgfSBlbHNlIGlmIChqID09PSBcInBvbmdcIikge1xuXHRyZXR1cm47IC8vIHJlY29yZEFjdGl2aXR5IGFscmVhZHkgdG9vayBjYXJlIG9mIG91ciB0aW1lcnNcbiAgICB9XG5cbiAgICB2YXIgZSA9IGRlY29kZUFjdGlvbihqKTtcbiAgICBzd2l0Y2ggKGUudHlwZSkge1xuICAgIGNhc2UgXCJyb3V0ZXNcIjpcblx0aWYgKHRoaXMucHJldlBlZXJSb3V0ZXNNZXNzYWdlICE9PSB3c2UuZGF0YSkge1xuXHQgICAgdGhpcy5wcmV2UGVlclJvdXRlc01lc3NhZ2UgPSB3c2UuZGF0YTtcblx0ICAgIHRoaXMucGVlckdlc3RhbHQgPSBlLmdlc3RhbHQ7XG5cdCAgICBXb3JsZC51cGRhdGVSb3V0ZXMoW3RoaXMuYWdncmVnYXRlR2VzdGFsdCgpXSk7XG5cdH1cblx0YnJlYWs7XG4gICAgY2FzZSBcIm1lc3NhZ2VcIjpcblx0aWYgKHRoaXMuZGVkdXBsaWNhdG9yLmFjY2VwdCh3c2UuZGF0YSkpIHtcblx0ICAgIFdvcmxkLnNlbmQoW3RoaXMubGFiZWwsIGUubWV0YUxldmVsLCBlLm1lc3NhZ2VdLCAwLCBlLmlzRmVlZGJhY2spO1xuXHR9XG5cdGJyZWFrO1xuICAgIH1cbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLm9uY2xvc2UgPSBmdW5jdGlvbiAoZSkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBjb25zb2xlLmxvZyhcIm9uY2xvc2VcIiwgZSk7XG5cbiAgICAvLyBVcGRhdGUgcm91dGVzIHRvIGdpdmUgY2xpZW50cyBzb21lIGluZGljYXRpb24gb2YgdGhlIGRpc2NvbnRpbnVpdHlcbiAgICBXb3JsZC51cGRhdGVSb3V0ZXMoW3RoaXMuYWdncmVnYXRlR2VzdGFsdCgpXSk7XG5cbiAgICBpZiAodGhpcy5zaG91bGRSZWNvbm5lY3QpIHtcblx0Y29uc29sZS5sb2coXCJyZWNvbm5lY3RpbmcgdG8gXCIgKyB0aGlzLndzdXJsICsgXCIgaW4gXCIgKyB0aGlzLnJlY29ubmVjdERlbGF5ICsgXCJtc1wiKTtcblx0c2V0VGltZW91dChXb3JsZC53cmFwKGZ1bmN0aW9uICgpIHsgc2VsZi5yZWNvbm5lY3QoKTsgfSksIHRoaXMucmVjb25uZWN0RGVsYXkpO1xuXHR0aGlzLnJlY29ubmVjdERlbGF5ID0gdGhpcy5yZWNvbm5lY3REZWxheSAqIDEuNjE4ICsgKE1hdGgucmFuZG9tKCkgKiAxMDAwKTtcblx0dGhpcy5yZWNvbm5lY3REZWxheSA9XG5cdCAgICB0aGlzLnJlY29ubmVjdERlbGF5ID4gTUFYX1JFQ09OTkVDVF9ERUxBWVxuXHQgICAgPyBNQVhfUkVDT05ORUNUX0RFTEFZICsgKE1hdGgucmFuZG9tKCkgKiAxMDAwKVxuXHQgICAgOiB0aGlzLnJlY29ubmVjdERlbGF5O1xuICAgIH1cbn07XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8gV2lyZSBwcm90b2NvbCByZXByZXNlbnRhdGlvbiBvZiBldmVudHMgYW5kIGFjdGlvbnNcblxuZnVuY3Rpb24gZW5jb2RlRXZlbnQoZSkge1xuICAgIHN3aXRjaCAoZS50eXBlKSB7XG4gICAgY2FzZSBcInJvdXRlc1wiOlxuXHRyZXR1cm4gW1wicm91dGVzXCIsIGUuZ2VzdGFsdC5zZXJpYWxpemUoZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHRydWU7IH0pXTtcbiAgICBjYXNlIFwibWVzc2FnZVwiOlxuXHRyZXR1cm4gW1wibWVzc2FnZVwiLCBlLm1lc3NhZ2UsIGUubWV0YUxldmVsLCBlLmlzRmVlZGJhY2tdO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZGVjb2RlQWN0aW9uKGopIHtcbiAgICBzd2l0Y2ggKGpbMF0pIHtcbiAgICBjYXNlIFwicm91dGVzXCI6XG5cdHJldHVybiBNaW5pbWFydC51cGRhdGVSb3V0ZXMoW1xuXHQgICAgUm91dGUuZGVzZXJpYWxpemVHZXN0YWx0KGpbMV0sIGZ1bmN0aW9uICh2KSB7IHJldHVybiB0cnVlOyB9KV0pO1xuICAgIGNhc2UgXCJtZXNzYWdlXCI6XG5cdHJldHVybiBNaW5pbWFydC5zZW5kTWVzc2FnZShqWzFdLCBqWzJdLCBqWzNdKTtcbiAgICBkZWZhdWx0OlxuXHR0aHJvdyB7IG1lc3NhZ2U6IFwiSW52YWxpZCBKU09OLWVuY29kZWQgYWN0aW9uOiBcIiArIEpTT04uc3RyaW5naWZ5KGopIH07XG4gICAgfVxufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxubW9kdWxlLmV4cG9ydHMuV2ViU29ja2V0Q29ubmVjdGlvbiA9IFdlYlNvY2tldENvbm5lY3Rpb247XG5tb2R1bGUuZXhwb3J0cy5lbmNvZGVFdmVudCA9IGVuY29kZUV2ZW50O1xubW9kdWxlLmV4cG9ydHMuZGVjb2RlQWN0aW9uID0gZGVjb2RlQWN0aW9uO1xuIl19 -(4) +Worker.prototype.boot = function () { + this.w.onmessage = World.wrap(function (e) { + console.log("Received from worker", JSON.stringify(e.data)); + World.current().enqueueAction(World.activePid(), Codec.decodeAction(e.data)); + }); +}; + +Worker.prototype.handleEvent = function (e) { + console.log("Sending to worker", JSON.stringify(Codec.encodeEvent(e))); + this.w.postMessage(Codec.encodeEvent(e)); +}; + +/////////////////////////////////////////////////////////////////////////// + +function WorkerGround(bootFn) { + var self = this; + Ground.call(this, bootFn); + onmessage = function (e) { + console.log("Received from main page", JSON.stringify(e.data)); + self.world.handleEvent(Codec.decodeEvent(e.data)); + self.startStepping(); + }; +} + +WorkerGround.prototype = Util.extend({}, Ground.prototype); + +WorkerGround.prototype.enqueueAction = function (pid, action) { + console.log("Sending to main page", JSON.stringify(Codec.encodeAction(action))); + postMessage(Codec.encodeAction(action)); + console.log("Sent to main page"); +}; + +/////////////////////////////////////////////////////////////////////////// + +module.exports.Worker = Worker; +module.exports.WorkerGround = WorkerGround; + +},{"./codec.js":2,"./ground.js":4,"./minimart.js":7,"./util.js":12}]},{},[6]) +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy90b255Zy9zcmMvanMtbWFya2V0cGxhY2Uvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXItcGFjay9fcHJlbHVkZS5qcyIsIi9Vc2Vycy90b255Zy9zcmMvanMtbWFya2V0cGxhY2Uvc3JjL2FjdG9yLmpzIiwiL1VzZXJzL3RvbnlnL3NyYy9qcy1tYXJrZXRwbGFjZS9zcmMvY29kZWMuanMiLCIvVXNlcnMvdG9ueWcvc3JjL2pzLW1hcmtldHBsYWNlL3NyYy9kb20tZHJpdmVyLmpzIiwiL1VzZXJzL3RvbnlnL3NyYy9qcy1tYXJrZXRwbGFjZS9zcmMvZ3JvdW5kLmpzIiwiL1VzZXJzL3RvbnlnL3NyYy9qcy1tYXJrZXRwbGFjZS9zcmMvanF1ZXJ5LWRyaXZlci5qcyIsIi9Vc2Vycy90b255Zy9zcmMvanMtbWFya2V0cGxhY2Uvc3JjL21haW4uanMiLCIvVXNlcnMvdG9ueWcvc3JjL2pzLW1hcmtldHBsYWNlL3NyYy9taW5pbWFydC5qcyIsIi9Vc2Vycy90b255Zy9zcmMvanMtbWFya2V0cGxhY2Uvc3JjL3JlZmxlY3QuanMiLCIvVXNlcnMvdG9ueWcvc3JjL2pzLW1hcmtldHBsYWNlL3NyYy9yb3V0ZS5qcyIsIi9Vc2Vycy90b255Zy9zcmMvanMtbWFya2V0cGxhY2Uvc3JjL3JvdXRpbmctdGFibGUtd2lkZ2V0LmpzIiwiL1VzZXJzL3RvbnlnL3NyYy9qcy1tYXJrZXRwbGFjZS9zcmMvc3B5LmpzIiwiL1VzZXJzL3RvbnlnL3NyYy9qcy1tYXJrZXRwbGFjZS9zcmMvdXRpbC5qcyIsIi9Vc2Vycy90b255Zy9zcmMvanMtbWFya2V0cGxhY2Uvc3JjL3dha2UtZGV0ZWN0b3IuanMiLCIvVXNlcnMvdG9ueWcvc3JjL2pzLW1hcmtldHBsYWNlL3NyYy93ZWJzb2NrZXQtZHJpdmVyLmpzIiwiL1VzZXJzL3RvbnlnL3NyYy9qcy1tYXJrZXRwbGFjZS9zcmMvd29ya2VyLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOVFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25IQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JGQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcGZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqakRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4REE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbENBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6T0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24gZSh0LG4scil7ZnVuY3Rpb24gcyhvLHUpe2lmKCFuW29dKXtpZighdFtvXSl7dmFyIGE9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtpZighdSYmYSlyZXR1cm4gYShvLCEwKTtpZihpKXJldHVybiBpKG8sITApO3Rocm93IG5ldyBFcnJvcihcIkNhbm5vdCBmaW5kIG1vZHVsZSAnXCIrbytcIidcIil9dmFyIGY9bltvXT17ZXhwb3J0czp7fX07dFtvXVswXS5jYWxsKGYuZXhwb3J0cyxmdW5jdGlvbihlKXt2YXIgbj10W29dWzFdW2VdO3JldHVybiBzKG4/bjplKX0sZixmLmV4cG9ydHMsZSx0LG4scil9cmV0dXJuIG5bb10uZXhwb3J0c312YXIgaT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2Zvcih2YXIgbz0wO288ci5sZW5ndGg7bysrKXMocltvXSk7cmV0dXJuIHN9KSIsInZhciBSZWZsZWN0ID0gcmVxdWlyZShcIi4vcmVmbGVjdC5qc1wiKTtcbnZhciBNaW5pbWFydCA9IHJlcXVpcmUoXCIuL21pbmltYXJ0LmpzXCIpO1xudmFyIFdvcmxkID0gTWluaW1hcnQuV29ybGQ7XG52YXIgUm91dGUgPSBNaW5pbWFydC5Sb3V0ZTtcblxuQWN0b3IuX2NodW5rcyA9IG51bGw7XG5cbmZ1bmN0aW9uIEFjdG9yKGN0b3IpIHtcbiAgICB2YXIgb2xkQ2h1bmtzID0gQWN0b3IuX2NodW5rcztcbiAgICB0cnkge1xuXHRBY3Rvci5fY2h1bmtzID0gW107XG5cdHZhciBiZWhhdmlvciA9IG5ldyBjdG9yKCk7XG5cdHJldHVybiBmaW5hbGl6ZUFjdG9yKGJlaGF2aW9yLCBBY3Rvci5fY2h1bmtzKTtcbiAgICB9IGNhdGNoIChlKSB7XG5cdEFjdG9yLl9jaHVua3MgPSBvbGRDaHVua3M7XG5cdHRocm93IGU7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBjaGVja0NodW5rcyh0eXBlKSB7XG4gICAgaWYgKCFBY3Rvci5fY2h1bmtzKSB7XG5cdHRocm93IG5ldyBFcnJvcihcIkNhbGwgdG8gQWN0b3IuXCIrdHlwZStcIiBvdXRzaWRlIG9mIEFjdG9yIGNvbnN0cnVjdG9yXCIpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZXh0cmFjdENodW5rKHR5cGUsIGtpbmQsIGRlZmF1bHRPcHRpb25zLCBhcmdzKSB7XG4gICAgdmFyIHJhd1Byb2plY3Rpb25GbiA9IGFyZ3NbMF1cbiAgICB2YXIgb3B0aW9ucyA9IG51bGw7XG4gICAgdmFyIGhhbmRsZXIgPSBudWxsO1xuICAgIGlmICh0eXBlb2YgcmF3UHJvamVjdGlvbkZuICE9PSAnZnVuY3Rpb24nKSB7XG5cdHRocm93IG5ldyBFcnJvcihcIkFjdG9yLlwiK3R5cGUrXCIgZXhwZWN0cyBhIGZ1bmN0aW9uIHByb2R1Y2luZyBhIHBhdHRlcm4gYXMgZmlyc3QgYXJndW1lbnRcIik7XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJncy5sZW5ndGg7IGkrKykgeyAvLyBOQjogc2tpcCB0aGUgZmlyc3QgYXJnIC0gaXQncyByYXdQcm9qZWN0aW9uRm5cblx0aWYgKHR5cGVvZiBhcmdzW2ldID09PSAnZnVuY3Rpb24nKSB7XG5cdCAgICBpZiAoaGFuZGxlciAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgRXJyb3IoXCJUb28gbWFueSBoYW5kbGVyIGZ1bmN0aW9ucyBpbiBBY3Rvci5cIit0eXBlKTsgfVxuXHQgICAgaGFuZGxlciA9IGFyZ3NbaV07XG5cdH0gZWxzZSBpZiAodHlwZW9mIGFyZ3NbaV0gPT09ICdvYmplY3QnKSB7XG5cdCAgICBpZiAob3B0aW9ucyAhPT0gbnVsbCkgeyB0aHJvdyBuZXcgRXJyb3IoXCJUb28gbWFueSBvcHRpb25zIGFyZ3VtZW50cyBpbiBBY3Rvci5cIit0eXBlKTsgfVxuXHQgICAgb3B0aW9ucyA9IGFyZ3NbaV07XG5cdH0gZWxzZSB7XG5cdCAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbnJlY29nbmlzZWQgYXJndW1lbnQgaW4gQWN0b3IuXCIrdHlwZSk7XG5cdH1cbiAgICB9XG4gICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgZm9yICh2YXIgayBpbiBvcHRpb25zKSB7XG5cdGlmICghKGsgaW4gZGVmYXVsdE9wdGlvbnMpKSB7XG5cdCAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbnJlY29nbmlzZWQgb3B0aW9uICdcIitrK1wiJyBpbiBBY3Rvci5cIit0eXBlKTtcblx0fVxuICAgIH1cbiAgICBmb3IgKHZhciBrIGluIGRlZmF1bHRPcHRpb25zKSB7XG5cdGlmICghKGsgaW4gb3B0aW9ucykpIHtcblx0ICAgIG9wdGlvbnNba10gPSBkZWZhdWx0T3B0aW9uc1trXTtcblx0fVxuICAgIH1cbiAgICByZXR1cm4ge1xuXHR0eXBlOiB0eXBlLFxuXHRraW5kOiBraW5kLFxuXHRyYXdQcm9qZWN0aW9uRm46IHJhd1Byb2plY3Rpb25Gbixcblx0b3B0aW9uczogb3B0aW9ucyxcblx0aGFuZGxlcjogaGFuZGxlclxuICAgIH07XG59XG5cbmZ1bmN0aW9uIHJlY29yZENodW5rKGNodW5rKSB7XG4gICAgQWN0b3IuX2NodW5rcy5wdXNoKGNodW5rKTtcbn1cblxuZnVuY3Rpb24gY2h1bmtFeHRyYWN0b3IodHlwZSwga2luZCwgZGVmYXVsdE9wdGlvbnMpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKC8qIC4uLiAqLykge1xuXHRjaGVja0NodW5rcyh0eXBlKTtcblx0cmVjb3JkQ2h1bmsoZXh0cmFjdENodW5rKHR5cGUsXG5cdFx0XHRcdCBraW5kLFxuXHRcdFx0XHQgZGVmYXVsdE9wdGlvbnMsXG5cdFx0XHRcdCBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgfTtcbn1cblxudmFyIHBhcnRpY2lwYW50RGVmYXVsdHMgPSB7XG4gICAgbWV0YUxldmVsOiAwLFxuICAgIHdoZW46IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH1cbn07XG5cbnZhciBvYnNlcnZlckRlZmF1bHRzID0ge1xuICAgIG1ldGFMZXZlbDogMCxcbiAgICBsZXZlbDogMCxcbiAgICB3aGVuOiBmdW5jdGlvbiAoKSB7IHJldHVybiB0cnVlOyB9LFxuICAgIHByZXNlbmNlOiBudWxsLFxuICAgIG5hbWU6IG51bGwsXG4gICAgc2V0OiBudWxsLFxuICAgIGFkZGVkOiBudWxsLFxuICAgIHJlbW92ZWQ6IG51bGxcbn07XG5cbkFjdG9yLmFkdmVydGlzZSA9IGNodW5rRXh0cmFjdG9yKCdhZHZlcnRpc2UnLCAncGFydGljaXBhbnQnLCBwYXJ0aWNpcGFudERlZmF1bHRzKTtcbkFjdG9yLnN1YnNjcmliZSA9IGNodW5rRXh0cmFjdG9yKCdzdWJzY3JpYmUnLCAncGFydGljaXBhbnQnLCBwYXJ0aWNpcGFudERlZmF1bHRzKTtcblxuQWN0b3Iub2JzZXJ2ZUFkdmVydGlzZXJzID0gY2h1bmtFeHRyYWN0b3IoJ29ic2VydmVBZHZlcnRpc2VycycsICdvYnNlcnZlcicsIG9ic2VydmVyRGVmYXVsdHMpO1xuQWN0b3Iub2JzZXJ2ZVN1YnNjcmliZXJzID0gY2h1bmtFeHRyYWN0b3IoJ29ic2VydmVTdWJzY3JpYmVycycsICdvYnNlcnZlcicsIG9ic2VydmVyRGVmYXVsdHMpO1xuXG5BY3Rvci5vYnNlcnZlR2VzdGFsdCA9IGZ1bmN0aW9uIChnZXN0YWx0Rm4sIGV2ZW50SGFuZGxlckZuKSB7XG4gICAgY2hlY2tDaHVua3MoJ29ic2VydmVHZXN0YWx0Jyk7XG4gICAgcmVjb3JkQ2h1bmsoe1xuXHR0eXBlOiAnb2JzZXJ2ZUdlc3RhbHQnLFxuXHRraW5kOiAncmF3Jyxcblx0Z2VzdGFsdEZuOiBnZXN0YWx0Rm4sXG5cdG9wdGlvbnM6IHtcblx0ICAgIHdoZW46IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRydWU7IH1cblx0fSxcblx0ZXZlbnRIYW5kbGVyRm46IGV2ZW50SGFuZGxlckZuXG4gICAgfSk7XG59O1xuXG5mdW5jdGlvbiBmaW5hbGl6ZUFjdG9yKGJlaGF2aW9yLCBjaHVua3MpIHtcbiAgICB2YXIgb2xkQm9vdCA9IGJlaGF2aW9yLmJvb3Q7XG4gICAgdmFyIG9sZEhhbmRsZUV2ZW50ID0gYmVoYXZpb3IuaGFuZGxlRXZlbnQ7XG4gICAgdmFyIHByb2plY3Rpb25zID0ge307XG4gICAgdmFyIGNvbXBpbGVkUHJvamVjdGlvbnMgPSB7fTtcbiAgICB2YXIgcHJldmlvdXNPYmpzID0ge307XG5cbiAgICBiZWhhdmlvci5ib290ID0gZnVuY3Rpb24gKCkge1xuXHRpZiAob2xkQm9vdCkgeyBvbGRCb290LmNhbGwodGhpcyk7IH1cblx0Zm9yICh2YXIgaSA9IDA7IGkgPCBjaHVua3MubGVuZ3RoOyBpKyspIHtcblx0ICAgIHZhciBjaHVuayA9IGNodW5rc1tpXTtcblx0ICAgIGlmIChjaHVuay5raW5kID09PSAnb2JzZXJ2ZXInKSB7XG5cdFx0aWYgKGNodW5rLm9wdGlvbnMucHJlc2VuY2UpIHsgdGhpc1tjaHVuay5vcHRpb25zLnByZXNlbmNlXSA9IGZhbHNlOyB9XG5cdFx0aWYgKGNodW5rLm9wdGlvbnMubmFtZSkgeyB0aGlzW2NodW5rLm9wdGlvbnMubmFtZV0gPSBbXTsgfVxuXHRcdGlmIChjaHVuay5vcHRpb25zLmFkZGVkKSB7IHRoaXNbY2h1bmsub3B0aW9ucy5hZGRlZF0gPSBbXTsgfVxuXHRcdGlmIChjaHVuay5vcHRpb25zLnJlbW92ZWQpIHsgdGhpc1tjaHVuay5vcHRpb25zLnJlbW92ZWRdID0gW107IH1cblx0ICAgIH1cblx0fVxuXHR0aGlzLnVwZGF0ZVJvdXRlcygpO1xuICAgIH07XG5cbiAgICBiZWhhdmlvci51cGRhdGVSb3V0ZXMgPSBmdW5jdGlvbiAoKSB7XG5cdHZhciBuZXdSb3V0ZXMgPSBSb3V0ZS5lbXB0eUdlc3RhbHQ7XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgY2h1bmtzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICB2YXIgY2h1bmsgPSBjaHVua3NbaV07XG5cdCAgICBpZiAoY2h1bmsub3B0aW9ucy53aGVuLmNhbGwodGhpcykpIHtcblx0XHRzd2l0Y2ggKGNodW5rLmtpbmQpIHtcblx0XHRjYXNlICdyYXcnOlxuXHRcdCAgICBuZXdSb3V0ZXMgPSBuZXdSb3V0ZXMudW5pb24oY2h1bmsuZ2VzdGFsdEZuLmNhbGwodGhpcykpO1xuXHRcdCAgICBicmVhaztcblx0XHRjYXNlICdwYXJ0aWNpcGFudCc6XG5cdFx0ICAgIHZhciBwcm9qID0gY2h1bmsucmF3UHJvamVjdGlvbkZuLmNhbGwodGhpcyk7XG5cdFx0ICAgIHByb2plY3Rpb25zW2ldID0gcHJvajtcblx0XHQgICAgdmFyIGcgPSBSb3V0ZS5zaW1wbGVHZXN0YWx0KGNodW5rLnR5cGUgPT09ICdhZHZlcnRpc2UnLFxuXHRcdFx0XHRcdFx0Um91dGUucHJvamVjdGlvblRvUGF0dGVybihwcm9qKSxcblx0XHRcdFx0XHRcdGNodW5rLm9wdGlvbnMubWV0YUxldmVsLFxuXHRcdFx0XHRcdFx0MCk7XG5cdFx0ICAgIG5ld1JvdXRlcyA9IG5ld1JvdXRlcy51bmlvbihnKTtcblx0XHQgICAgYnJlYWs7XG5cdFx0Y2FzZSAnb2JzZXJ2ZXInOlxuXHRcdCAgICB2YXIgcHJvaiA9IGNodW5rLnJhd1Byb2plY3Rpb25Gbi5jYWxsKHRoaXMpO1xuXHRcdCAgICBwcm9qZWN0aW9uc1tpXSA9IHByb2o7XG5cdFx0ICAgIGNvbXBpbGVkUHJvamVjdGlvbnNbaV0gPSBSb3V0ZS5jb21waWxlUHJvamVjdGlvbihwcm9qKTtcblx0XHQgICAgdmFyIGcgPSBSb3V0ZS5zaW1wbGVHZXN0YWx0KGNodW5rLnR5cGUgPT09ICdvYnNlcnZlU3Vic2NyaWJlcnMnLFxuXHRcdFx0XHRcdFx0Um91dGUucHJvamVjdGlvblRvUGF0dGVybihwcm9qKSxcblx0XHRcdFx0XHRcdGNodW5rLm9wdGlvbnMubWV0YUxldmVsLFxuXHRcdFx0XHRcdFx0Y2h1bmsub3B0aW9ucy5sZXZlbCArIDEpO1xuXHRcdCAgICBuZXdSb3V0ZXMgPSBuZXdSb3V0ZXMudW5pb24oZyk7XG5cdFx0ICAgIGlmIChjaHVuay5vcHRpb25zLmFkZGVkIHx8IGNodW5rLm9wdGlvbnMucmVtb3ZlZCkge1xuXHRcdFx0cHJldmlvdXNPYmpzW2ldID0gUm91dGUuYXJyYXlUb1NldChbXSk7XG5cdFx0ICAgIH1cblx0XHQgICAgYnJlYWs7XG5cdFx0ZGVmYXVsdDpcblx0XHQgICAgdGhyb3cgbmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgY2h1bmsgdHlwZS9raW5kOiBcIitjaHVuay50eXBlK1wiL1wiK2NodW5rLmtpbmQpO1xuXHRcdH1cblx0ICAgIH1cblx0fVxuXHRXb3JsZC51cGRhdGVSb3V0ZXMoW25ld1JvdXRlc10pO1xuICAgIH07XG5cbiAgICBiZWhhdmlvci5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG5cdGlmIChvbGRIYW5kbGVFdmVudCkgeyBvbGRIYW5kbGVFdmVudC5jYWxsKHRoaXMsIGUpOyB9XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgY2h1bmtzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICB2YXIgY2h1bmsgPSBjaHVua3NbaV07XG5cdCAgICBzd2l0Y2ggKGNodW5rLmtpbmQpIHtcblx0ICAgIGNhc2UgJ3Jhdyc6XG5cdFx0Y2h1bmsuZXZlbnRIYW5kbGVyRm4uY2FsbCh0aGlzLCBlKTtcblx0XHRicmVhaztcblx0ICAgIGNhc2UgJ3BhcnRpY2lwYW50Jzpcblx0XHRpZiAoY2h1bmsuaGFuZGxlclxuXHRcdCAgICAmJiAoZS50eXBlID09PSAnbWVzc2FnZScpXG5cdFx0ICAgICYmIChlLm1ldGFMZXZlbCA9PT0gY2h1bmsub3B0aW9ucy5tZXRhTGV2ZWwpXG5cdFx0ICAgICYmIChlLmlzRmVlZGJhY2sgPT09IChjaHVuay50eXBlID09PSAnYWR2ZXJ0aXNlJykpKVxuXHRcdHtcblx0XHQgICAgdmFyIG1hdGNoUmVzdWx0ID0gUm91dGUubWF0Y2hQYXR0ZXJuKGUubWVzc2FnZSwgcHJvamVjdGlvbnNbaV0pO1xuXHRcdCAgICBpZiAobWF0Y2hSZXN1bHQpIHtcblx0XHRcdGt3QXBwbHkoY2h1bmsuaGFuZGxlciwgdGhpcywgbWF0Y2hSZXN1bHQpO1xuXHRcdCAgICB9XG5cdFx0fVxuXHRcdGJyZWFrO1xuXHQgICAgY2FzZSAnb2JzZXJ2ZXInOlxuXHRcdGlmIChlLnR5cGUgPT09ICdyb3V0ZXMnKSB7XG5cdFx0ICAgIHZhciBwcm9qZWN0aW9uUmVzdWx0ID0gZS5nZXN0YWx0LnByb2plY3QoY29tcGlsZWRQcm9qZWN0aW9uc1tpXSxcblx0XHRcdFx0XHRcdFx0ICAgICBjaHVuay50eXBlICE9PSAnb2JzZXJ2ZVN1YnNjcmliZXJzJyxcblx0XHRcdFx0XHRcdFx0ICAgICBjaHVuay5vcHRpb25zLm1ldGFMZXZlbCxcblx0XHRcdFx0XHRcdFx0ICAgICBjaHVuay5vcHRpb25zLmxldmVsKTtcblxuXHRcdCAgICB2YXIgaXNQcmVzZW50ID0gIVJvdXRlLmlzX2VtcHR5TWF0Y2hlcihwcm9qZWN0aW9uUmVzdWx0KTtcblx0XHQgICAgaWYgKGNodW5rLm9wdGlvbnMucHJlc2VuY2UpIHtcblx0XHRcdHRoaXNbY2h1bmsub3B0aW9ucy5wcmVzZW5jZV0gPSBpc1ByZXNlbnQ7XG5cdFx0ICAgIH1cblxuXHRcdCAgICB2YXIgb2JqcyA9IFtdO1xuXHRcdCAgICBpZiAoaXNQcmVzZW50KSB7XG5cdFx0XHR2YXIga2V5cyA9IFJvdXRlLm1hdGNoZXJLZXlzKHByb2plY3Rpb25SZXN1bHQpO1xuXHRcdFx0aWYgKGtleXMgPT09IG51bGwpIHtcblx0XHRcdCAgICBjb25zb2xlLndhcm4oXCJXaWxkY2FyZCBkZXRlY3RlZCB3aGlsZSBwcm9qZWN0aW5nIChcIlxuXHRcdFx0XHRcdCArSlNPTi5zdHJpbmdpZnkoY2h1bmsub3B0aW9ucykrXCIpXCIpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdCAgICBvYmpzID0gUm91dGUubWF0Y2hlcktleXNUb09iamVjdHMoa2V5cywgY29tcGlsZWRQcm9qZWN0aW9uc1tpXSk7XG5cdFx0XHQgICAgaWYgKGNodW5rLm9wdGlvbnMuc2V0KSB7XG5cdFx0XHRcdGZvciAodmFyIGogPSAwOyBqIDwgb2Jqcy5sZW5ndGg7IGorKykge1xuXHRcdFx0XHQgICAgb2Jqc1tqXSA9IGNodW5rLm9wdGlvbnMuc2V0LmNhbGwodGhpcywgb2Jqc1tqXSk7XG5cdFx0XHRcdH1cblx0XHRcdCAgICB9XG5cdFx0XHR9XG5cdFx0ICAgIH1cblx0XHQgICAgaWYgKGNodW5rLm9wdGlvbnMubmFtZSkge1xuXHRcdFx0dGhpc1tjaHVuay5vcHRpb25zLm5hbWVdID0gb2Jqcztcblx0XHQgICAgfVxuXG5cdFx0ICAgIGlmIChjaHVuay5vcHRpb25zLmFkZGVkIHx8IGNodW5rLm9wdGlvbnMucmVtb3ZlZCkge1xuXHRcdFx0dmFyIG9ialNldCA9IFJvdXRlLmFycmF5VG9TZXQob2Jqcyk7XG5cblx0XHRcdGlmIChjaHVuay5vcHRpb25zLmFkZGVkKSB7XG5cdFx0XHQgICAgdGhpc1tjaHVuay5vcHRpb25zLmFkZGVkXSA9XG5cdFx0XHRcdFJvdXRlLnNldFRvQXJyYXkoUm91dGUuc2V0U3VidHJhY3Qob2JqU2V0LCBwcmV2aW91c09ianNbaV0pKTtcblx0XHRcdH1cblxuXHRcdFx0aWYgKGNodW5rLm9wdGlvbnMucmVtb3ZlZCkge1xuXHRcdFx0ICAgIHRoaXNbY2h1bmsub3B0aW9ucy5yZW1vdmVkXSA9XG5cdFx0XHRcdFJvdXRlLnNldFRvQXJyYXkoUm91dGUuc2V0U3VidHJhY3QocHJldmlvdXNPYmpzW2ldLCBvYmpTZXQpKTtcblx0XHRcdH1cblxuXHRcdFx0cHJldmlvdXNPYmpzW2ldID0gb2JqU2V0O1xuXHRcdCAgICB9XG5cblx0XHQgICAgaWYgKGNodW5rLmhhbmRsZXIpIHtcblx0XHRcdGNodW5rLmhhbmRsZXIuY2FsbCh0aGlzKTtcblx0XHQgICAgfVxuXHRcdH1cblx0XHRicmVhaztcblx0ICAgIGRlZmF1bHQ6XG5cdFx0dGhyb3cgbmV3IEVycm9yKFwiVW5zdXBwb3J0ZWQgY2h1bmsgdHlwZS9raW5kOiBcIitjaHVuay50eXBlK1wiL1wiK2NodW5rLmtpbmQpO1xuXHQgICAgfVxuXHR9XG4gICAgfTtcblxuICAgIHJldHVybiBiZWhhdmlvcjtcbn1cblxuZnVuY3Rpb24ga3dBcHBseShmLCB0aGlzQXJnLCBhcmdzKSB7XG4gICAgdmFyIGZvcm1hbHMgPSBSZWZsZWN0LmZvcm1hbFBhcmFtZXRlcnMoZik7XG4gICAgdmFyIGFjdHVhbHMgPSBbXVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZm9ybWFscy5sZW5ndGg7IGkrKykge1xuXHR2YXIgZm9ybWFsID0gZm9ybWFsc1tpXTtcblx0aWYgKCEoZm9ybWFsIGluIGFyZ3MpKSB7XG5cdCAgICB0aHJvdyBuZXcgRXJyb3IoXCJGdW5jdGlvbiBwYXJhbWV0ZXIgJ1wiK2Zvcm1hbCtcIicgbm90IHByZXNlbnQgaW4gYXJnc1wiKTtcblx0fVxuXHRhY3R1YWxzLnB1c2goYXJnc1tmb3JtYWxdKTtcbiAgICB9XG4gICAgcmV0dXJuIGYuYXBwbHkodGhpc0FyZywgYWN0dWFscyk7XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy5BY3RvciA9IEFjdG9yO1xubW9kdWxlLmV4cG9ydHMua3dBcHBseSA9IGt3QXBwbHk7XG4iLCIvLyBXaXJlIHByb3RvY29sIHJlcHJlc2VudGF0aW9uIG9mIGV2ZW50cyBhbmQgYWN0aW9uc1xuXG52YXIgUm91dGUgPSByZXF1aXJlKFwiLi9yb3V0ZS5qc1wiKTtcblxuZnVuY3Rpb24gX2VuY29kZShlKSB7XG4gICAgc3dpdGNoIChlLnR5cGUpIHtcbiAgICBjYXNlIFwicm91dGVzXCI6XG5cdHJldHVybiBbXCJyb3V0ZXNcIiwgZS5nZXN0YWx0LnNlcmlhbGl6ZShmdW5jdGlvbiAodikgeyByZXR1cm4gdHJ1ZTsgfSldO1xuICAgIGNhc2UgXCJtZXNzYWdlXCI6XG5cdHJldHVybiBbXCJtZXNzYWdlXCIsIGUubWVzc2FnZSwgZS5tZXRhTGV2ZWwsIGUuaXNGZWVkYmFja107XG4gICAgfVxufVxuXG5mdW5jdGlvbiBfZGVjb2RlKHdoYXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIChqKSB7XG4gICAgc3dpdGNoIChqWzBdKSB7XG4gICAgY2FzZSBcInJvdXRlc1wiOlxuICAgICAgcmV0dXJuIE1pbmltYXJ0LnVwZGF0ZVJvdXRlcyhbXG5cdFJvdXRlLmRlc2VyaWFsaXplR2VzdGFsdChqWzFdLCBmdW5jdGlvbiAodikgeyByZXR1cm4gdHJ1ZTsgfSldKTtcbiAgICBjYXNlIFwibWVzc2FnZVwiOlxuICAgICAgcmV0dXJuIE1pbmltYXJ0LnNlbmRNZXNzYWdlKGpbMV0sIGpbMl0sIGpbM10pO1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyB7IG1lc3NhZ2U6IFwiSW52YWxpZCBKU09OLWVuY29kZWQgXCIgKyB3aGF0ICsgXCI6IFwiICsgSlNPTi5zdHJpbmdpZnkoaikgfTtcbiAgICB9XG4gIH07XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy5lbmNvZGVFdmVudCA9IF9lbmNvZGU7XG5tb2R1bGUuZXhwb3J0cy5kZWNvZGVFdmVudCA9IF9kZWNvZGUoXCJldmVudFwiKTtcbm1vZHVsZS5leHBvcnRzLmVuY29kZUFjdGlvbiA9IF9lbmNvZGU7XG5tb2R1bGUuZXhwb3J0cy5kZWNvZGVBY3Rpb24gPSBfZGVjb2RlKFwiYWN0aW9uXCIpO1xuIiwiLy8gRE9NIGZyYWdtZW50IGRpc3BsYXkgZHJpdmVyXG52YXIgTWluaW1hcnQgPSByZXF1aXJlKFwiLi9taW5pbWFydC5qc1wiKTtcbnZhciBXb3JsZCA9IE1pbmltYXJ0LldvcmxkO1xudmFyIHN1YiA9IE1pbmltYXJ0LnN1YjtcbnZhciBwdWIgPSBNaW5pbWFydC5wdWI7XG52YXIgX18gPSBNaW5pbWFydC5fXztcbnZhciBfJCA9IE1pbmltYXJ0Ll8kO1xuXG5mdW5jdGlvbiBzcGF3bkRPTURyaXZlcihkb21XcmFwRnVuY3Rpb24sIGpRdWVyeVdyYXBGdW5jdGlvbikge1xuICAgIGRvbVdyYXBGdW5jdGlvbiA9IGRvbVdyYXBGdW5jdGlvbiB8fCBkZWZhdWx0V3JhcEZ1bmN0aW9uO1xuICAgIHZhciBkID0gbmV3IE1pbmltYXJ0LkRlbWFuZE1hdGNoZXIoZG9tV3JhcEZ1bmN0aW9uKF8kLCBfJCwgXyQpKTtcbiAgICBkLm9uRGVtYW5kSW5jcmVhc2UgPSBmdW5jdGlvbiAoY2FwdHVyZXMpIHtcblx0dmFyIHNlbGVjdG9yID0gY2FwdHVyZXNbMF07XG5cdHZhciBmcmFnbWVudENsYXNzID0gY2FwdHVyZXNbMV07XG5cdHZhciBmcmFnbWVudFNwZWMgPSBjYXB0dXJlc1syXTtcblx0V29ybGQuc3Bhd24obmV3IERPTUZyYWdtZW50KHNlbGVjdG9yLFxuXHRcdFx0XHQgICAgZnJhZ21lbnRDbGFzcyxcblx0XHRcdFx0ICAgIGZyYWdtZW50U3BlYyxcblx0XHRcdFx0ICAgIGRvbVdyYXBGdW5jdGlvbixcblx0XHRcdFx0ICAgIGpRdWVyeVdyYXBGdW5jdGlvbiksXG5cdFx0ICAgIFtzdWIoZG9tV3JhcEZ1bmN0aW9uKHNlbGVjdG9yLCBmcmFnbWVudENsYXNzLCBmcmFnbWVudFNwZWMpKSxcblx0XHQgICAgIHN1Yihkb21XcmFwRnVuY3Rpb24oc2VsZWN0b3IsIGZyYWdtZW50Q2xhc3MsIGZyYWdtZW50U3BlYyksIDAsIDEpXSk7XG4gICAgfTtcbiAgICBXb3JsZC5zcGF3bihkKTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdFdyYXBGdW5jdGlvbihzZWxlY3RvciwgZnJhZ21lbnRDbGFzcywgZnJhZ21lbnRTcGVjKSB7XG4gICAgcmV0dXJuIFtcIkRPTVwiLCBzZWxlY3RvciwgZnJhZ21lbnRDbGFzcywgZnJhZ21lbnRTcGVjXTtcbn1cblxuZnVuY3Rpb24gRE9NRnJhZ21lbnQoc2VsZWN0b3IsIGZyYWdtZW50Q2xhc3MsIGZyYWdtZW50U3BlYywgZG9tV3JhcEZ1bmN0aW9uLCBqUXVlcnlXcmFwRnVuY3Rpb24pIHtcbiAgICB0aGlzLnNlbGVjdG9yID0gc2VsZWN0b3I7XG4gICAgdGhpcy5mcmFnbWVudENsYXNzID0gZnJhZ21lbnRDbGFzcztcbiAgICB0aGlzLmZyYWdtZW50U3BlYyA9IGZyYWdtZW50U3BlYztcbiAgICB0aGlzLmRvbVdyYXBGdW5jdGlvbiA9IGRvbVdyYXBGdW5jdGlvbjtcbiAgICB0aGlzLmpRdWVyeVdyYXBGdW5jdGlvbiA9IGpRdWVyeVdyYXBGdW5jdGlvbjtcbiAgICB0aGlzLm5vZGVzID0gdGhpcy5idWlsZE5vZGVzKCk7XG59XG5cbkRPTUZyYWdtZW50LnByb3RvdHlwZS5ib290ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB2YXIgbW9uaXRvcmluZyA9XG5cdHN1Yih0aGlzLmRvbVdyYXBGdW5jdGlvbihzZWxmLnNlbGVjdG9yLCBzZWxmLmZyYWdtZW50Q2xhc3MsIHNlbGYuZnJhZ21lbnRTcGVjKSwgMSwgMik7XG4gICAgV29ybGQuc3Bhd24obmV3IFdvcmxkKGZ1bmN0aW9uICgpIHtcblx0TWluaW1hcnQuSlF1ZXJ5LnNwYXduSlF1ZXJ5RHJpdmVyKHNlbGYuc2VsZWN0b3IrXCIgPiAuXCIrc2VsZi5mcmFnbWVudENsYXNzLFxuXHRcdFx0XHRcdCAgMSxcblx0XHRcdFx0XHQgIHNlbGYualF1ZXJ5V3JhcEZ1bmN0aW9uKTtcblx0V29ybGQuc3Bhd24oe1xuXHQgICAgaGFuZGxlRXZlbnQ6IGZ1bmN0aW9uIChlKSB7XG5cdFx0aWYgKGUudHlwZSA9PT0gXCJyb3V0ZXNcIikge1xuXHRcdCAgICB2YXIgbGV2ZWwgPSBlLmdlc3RhbHQuZ2V0TGV2ZWwoMSwgMCk7IC8vIGZpbmQgcGFydGljaXBhbnQgcGVlcnNcblx0XHQgICAgaWYgKCFlLmdlc3RhbHQuaXNFbXB0eSgpICYmIGxldmVsLmlzRW1wdHkoKSkge1xuXHRcdFx0V29ybGQuc2h1dGRvd25Xb3JsZCgpO1xuXHRcdCAgICB9XG5cdFx0fVxuXHQgICAgfVxuXHR9LCBbbW9uaXRvcmluZ10pO1xuICAgIH0pKTtcbn07XG5cbkRPTUZyYWdtZW50LnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKGUudHlwZSA9PT0gXCJyb3V0ZXNcIiAmJiBlLmdlc3RhbHQuaXNFbXB0eSgpKSB7XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5ub2Rlcy5sZW5ndGg7IGkrKykge1xuXHQgICAgdmFyIG4gPSB0aGlzLm5vZGVzW2ldO1xuXHQgICAgbi5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKG4pO1xuXHR9XG5cdFdvcmxkLmV4aXQoKTtcbiAgICB9XG59O1xuXG5mdW5jdGlvbiBpc0F0dHJpYnV0ZXMoeCkge1xuICAgIHJldHVybiBBcnJheS5pc0FycmF5KHgpICYmICgoeC5sZW5ndGggPT09IDApIHx8IEFycmF5LmlzQXJyYXkoeFswXSkpO1xufVxuXG5ET01GcmFnbWVudC5wcm90b3R5cGUuaW50ZXJwcmV0U3BlYyA9IGZ1bmN0aW9uIChzcGVjKSB7XG4gICAgLy8gRnJhZ21lbnQgc3BlY3MgYXJlIHJvdWdobHkgSlNPTi1lcXVpdmFsZW50cyBvZiBTWE1MLlxuICAgIC8vIHNwZWMgOjo9PSBbXCJ0YWdcIiwge1wiYXR0clwiOiBcInZhbHVlXCIsIC4uLn0sIHNwZWMsIHNwZWMsIC4uLl1cbiAgICAvLyAgICAgICAgIHwgW1widGFnXCIsIHNwZWMsIHNwZWMsIC4uLl1cbiAgICAvLyAgICAgICAgIHwgXCJjZGF0YVwiXG4gICAgaWYgKHR5cGVvZihzcGVjKSA9PT0gXCJzdHJpbmdcIiB8fCB0eXBlb2Yoc3BlYykgPT09IFwibnVtYmVyXCIpIHtcblx0cmV0dXJuIGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHNwZWMpO1xuICAgIH0gZWxzZSBpZiAoJC5pc0FycmF5KHNwZWMpKSB7XG5cdHZhciB0YWdOYW1lID0gc3BlY1swXTtcblx0dmFyIGhhc0F0dHJzID0gaXNBdHRyaWJ1dGVzKHNwZWNbMV0pO1xuXHR2YXIgYXR0cnMgPSBoYXNBdHRycyA/IHNwZWNbMV0gOiB7fTtcblx0dmFyIGtpZEluZGV4ID0gaGFzQXR0cnMgPyAyIDogMTtcblxuXHQvLyBXb3chIFN1Y2ggWFNTISBNYW55IGhhY2tzISBTbyB2dWxuZXJhYmlsaXR5ISBBbWF6ZSFcblx0dmFyIG4gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KHRhZ05hbWUpO1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICBuLnNldEF0dHJpYnV0ZShhdHRyc1tpXVswXSwgYXR0cnNbaV1bMV0pO1xuXHR9XG5cdGZvciAodmFyIGkgPSBraWRJbmRleDsgaSA8IHNwZWMubGVuZ3RoOyBpKyspIHtcblx0ICAgIG4uYXBwZW5kQ2hpbGQodGhpcy5pbnRlcnByZXRTcGVjKHNwZWNbaV0pKTtcblx0fVxuXHRyZXR1cm4gbjtcbiAgICB9XG59O1xuXG5ET01GcmFnbWVudC5wcm90b3R5cGUuYnVpbGROb2RlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgdmFyIG5vZGVzID0gW107XG4gICAgJChzZWxmLnNlbGVjdG9yKS5lYWNoKGZ1bmN0aW9uIChpbmRleCwgZG9tTm9kZSkge1xuXHR2YXIgbiA9IHNlbGYuaW50ZXJwcmV0U3BlYyhzZWxmLmZyYWdtZW50U3BlYyk7XG5cdG4uY2xhc3NMaXN0LmFkZChzZWxmLmZyYWdtZW50Q2xhc3MpO1xuXHRkb21Ob2RlLmFwcGVuZENoaWxkKG4pO1xuXHRub2Rlcy5wdXNoKG4pO1xuICAgIH0pO1xuICAgIHJldHVybiBub2Rlcztcbn07XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy5zcGF3bkRPTURyaXZlciA9IHNwYXduRE9NRHJpdmVyO1xubW9kdWxlLmV4cG9ydHMuZGVmYXVsdFdyYXBGdW5jdGlvbiA9IGRlZmF1bHRXcmFwRnVuY3Rpb247XG4iLCIvKiBHcm91bmQgaW50ZXJmYWNlICovXG52YXIgTWluaW1hcnQgPSByZXF1aXJlKFwiLi9taW5pbWFydC5qc1wiKTtcbnZhciBXb3JsZCA9IE1pbmltYXJ0LldvcmxkO1xuXG5mdW5jdGlvbiBHcm91bmQoYm9vdEZuKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHRoaXMuc3RlcHBlcklkID0gbnVsbDtcbiAgICBXb3JsZC53aXRoV29ybGRTdGFjayhbW3RoaXMsIC0xXV0sIGZ1bmN0aW9uICgpIHtcblx0c2VsZi53b3JsZCA9IG5ldyBXb3JsZChib290Rm4pO1xuICAgIH0pO1xufVxuXG5Hcm91bmQucHJvdG90eXBlLnN0ZXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHJldHVybiBXb3JsZC53aXRoV29ybGRTdGFjayhbW3RoaXMsIC0xXV0sIGZ1bmN0aW9uICgpIHtcblx0cmV0dXJuIHNlbGYud29ybGQuc3RlcCgpO1xuICAgIH0pO1xufTtcblxuR3JvdW5kLnByb3RvdHlwZS5jaGVja1BpZCA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgICBpZiAocGlkICE9PSAtMSkgY29uc29sZS5lcnJvcihcIldlaXJkIHBpZCBpbiBHcm91bmQgbWFya1BpZFJ1bm5hYmxlXCIsIHBpZCk7XG59O1xuXG5Hcm91bmQucHJvdG90eXBlLm1hcmtQaWRSdW5uYWJsZSA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgICB0aGlzLmNoZWNrUGlkKHBpZCk7XG4gICAgdGhpcy5zdGFydFN0ZXBwaW5nKCk7XG59O1xuXG5Hcm91bmQucHJvdG90eXBlLnN0YXJ0U3RlcHBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIGlmICh0aGlzLnN0ZXBwZXJJZCkgcmV0dXJuO1xuICAgIGlmICh0aGlzLnN0ZXAoKSkge1xuXHR0aGlzLnN0ZXBwZXJJZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuXHQgICAgc2VsZi5zdGVwcGVySWQgPSBudWxsO1xuXHQgICAgc2VsZi5zdGFydFN0ZXBwaW5nKCk7XG5cdH0sIDApO1xuICAgIH1cbn07XG5cbkdyb3VuZC5wcm90b3R5cGUuc3RvcFN0ZXBwaW5nID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLnN0ZXBwZXJJZCkge1xuXHRjbGVhclRpbWVvdXQodGhpcy5zdGVwcGVySWQpO1xuXHR0aGlzLnN0ZXBwZXJJZCA9IG51bGw7XG4gICAgfVxufTtcblxuR3JvdW5kLnByb3RvdHlwZS5lbnF1ZXVlQWN0aW9uID0gZnVuY3Rpb24gKHBpZCwgYWN0aW9uKSB7XG4gICAgdGhpcy5jaGVja1BpZChwaWQpO1xuICAgIGlmIChhY3Rpb24udHlwZSA9PT0gJ3JvdXRlcycpIHtcblx0aWYgKCFhY3Rpb24uZ2VzdGFsdC5pc0VtcHR5KCkpIHtcblx0ICAgIGNvbnNvbGUuZXJyb3IoXCJZb3UgaGF2ZSBzdWJzY3JpYmVkIHRvIGEgbm9uZXhpc3RlbnQgZXZlbnQgc291cmNlLlwiLFxuXHRcdFx0ICBhY3Rpb24uZ2VzdGFsdC5wcmV0dHkoKSk7XG5cdH1cbiAgICB9IGVsc2Uge1xuXHRjb25zb2xlLmVycm9yKFwiWW91IGhhdmUgc2VudCBhIG1lc3NhZ2UgaW50byB0aGUgb3V0ZXIgdm9pZC5cIiwgYWN0aW9uKTtcbiAgICB9XG59O1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxubW9kdWxlLmV4cG9ydHMuR3JvdW5kID0gR3JvdW5kO1xuIiwiLy8gSlF1ZXJ5IGV2ZW50IGRyaXZlclxudmFyIE1pbmltYXJ0ID0gcmVxdWlyZShcIi4vbWluaW1hcnQuanNcIik7XG52YXIgV29ybGQgPSBNaW5pbWFydC5Xb3JsZDtcbnZhciBzdWIgPSBNaW5pbWFydC5zdWI7XG52YXIgcHViID0gTWluaW1hcnQucHViO1xudmFyIF9fID0gTWluaW1hcnQuX187XG52YXIgXyQgPSBNaW5pbWFydC5fJDtcblxuZnVuY3Rpb24gc3Bhd25KUXVlcnlEcml2ZXIoYmFzZVNlbGVjdG9yLCBtZXRhTGV2ZWwsIHdyYXBGdW5jdGlvbikge1xuICAgIG1ldGFMZXZlbCA9IG1ldGFMZXZlbCB8fCAwO1xuICAgIHdyYXBGdW5jdGlvbiA9IHdyYXBGdW5jdGlvbiB8fCBkZWZhdWx0V3JhcEZ1bmN0aW9uO1xuICAgIHZhciBkID0gbmV3IE1pbmltYXJ0LkRlbWFuZE1hdGNoZXIod3JhcEZ1bmN0aW9uKF8kLCBfJCwgX18pLCBtZXRhTGV2ZWwsXG5cdFx0XHRcdCAgICAgICB7ZGVtYW5kU2lkZUlzU3Vic2NyaXB0aW9uOiB0cnVlfSk7XG4gICAgZC5vbkRlbWFuZEluY3JlYXNlID0gZnVuY3Rpb24gKGNhcHR1cmVzKSB7XG5cdHZhciBzZWxlY3RvciA9IGNhcHR1cmVzWzBdO1xuXHR2YXIgZXZlbnROYW1lID0gY2FwdHVyZXNbMV07XG5cdFdvcmxkLnNwYXduKG5ldyBKUXVlcnlFdmVudFJvdXRlcihiYXNlU2VsZWN0b3IsXG5cdFx0XHRcdFx0ICBzZWxlY3Rvcixcblx0XHRcdFx0XHQgIGV2ZW50TmFtZSxcblx0XHRcdFx0XHQgIG1ldGFMZXZlbCxcblx0XHRcdFx0XHQgIHdyYXBGdW5jdGlvbiksXG5cdFx0ICAgIFtwdWIod3JhcEZ1bmN0aW9uKHNlbGVjdG9yLCBldmVudE5hbWUsIF9fKSwgbWV0YUxldmVsKSxcblx0XHQgICAgIHB1Yih3cmFwRnVuY3Rpb24oc2VsZWN0b3IsIGV2ZW50TmFtZSwgX18pLCBtZXRhTGV2ZWwsIDEpXSk7XG4gICAgfTtcbiAgICBXb3JsZC5zcGF3bihkKTtcbn1cblxuZnVuY3Rpb24gZGVmYXVsdFdyYXBGdW5jdGlvbihzZWxlY3RvciwgZXZlbnROYW1lLCBldmVudFZhbHVlKSB7XG4gICAgcmV0dXJuIFtcImpRdWVyeVwiLCBzZWxlY3RvciwgZXZlbnROYW1lLCBldmVudFZhbHVlXTtcbn1cblxuZnVuY3Rpb24gSlF1ZXJ5RXZlbnRSb3V0ZXIoYmFzZVNlbGVjdG9yLCBzZWxlY3RvciwgZXZlbnROYW1lLCBtZXRhTGV2ZWwsIHdyYXBGdW5jdGlvbikge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB0aGlzLmJhc2VTZWxlY3RvciA9IGJhc2VTZWxlY3RvciB8fCBudWxsO1xuICAgIHRoaXMuc2VsZWN0b3IgPSBzZWxlY3RvcjtcbiAgICB0aGlzLmV2ZW50TmFtZSA9IGV2ZW50TmFtZTtcbiAgICB0aGlzLm1ldGFMZXZlbCA9IG1ldGFMZXZlbCB8fCAwO1xuICAgIHRoaXMud3JhcEZ1bmN0aW9uID0gd3JhcEZ1bmN0aW9uIHx8IGRlZmF1bHRXcmFwRnVuY3Rpb247XG4gICAgdGhpcy5wcmV2ZW50RGVmYXVsdCA9ICh0aGlzLmV2ZW50TmFtZS5jaGFyQXQoMCkgIT09IFwiK1wiKTtcbiAgICB0aGlzLmhhbmRsZXIgPVxuXHRXb3JsZC53cmFwKGZ1bmN0aW9uIChlKSB7XG5cdCAgICBXb3JsZC5zZW5kKHNlbGYud3JhcEZ1bmN0aW9uKHNlbGYuc2VsZWN0b3IsIHNlbGYuZXZlbnROYW1lLCBlKSwgc2VsZi5tZXRhTGV2ZWwpO1xuXHQgICAgaWYgKHNlbGYucHJldmVudERlZmF1bHQpIGUucHJldmVudERlZmF1bHQoKTtcblx0ICAgIHJldHVybiAhc2VsZi5wcmV2ZW50RGVmYXVsdDtcblx0fSk7XG4gICAgdGhpcy5jb21wdXRlTm9kZXMoKS5vbih0aGlzLnByZXZlbnREZWZhdWx0ID8gdGhpcy5ldmVudE5hbWUgOiB0aGlzLmV2ZW50TmFtZS5zdWJzdHJpbmcoMSksXG5cdFx0XHQgICB0aGlzLmhhbmRsZXIpO1xufVxuXG5KUXVlcnlFdmVudFJvdXRlci5wcm90b3R5cGUuaGFuZGxlRXZlbnQgPSBmdW5jdGlvbiAoZSkge1xuICAgIGlmIChlLnR5cGUgPT09IFwicm91dGVzXCIgJiYgZS5nZXN0YWx0LmlzRW1wdHkoKSkge1xuXHR0aGlzLmNvbXB1dGVOb2RlcygpLm9mZih0aGlzLmV2ZW50TmFtZSwgdGhpcy5oYW5kbGVyKTtcblx0V29ybGQuZXhpdCgpO1xuICAgIH1cbn07XG5cbkpRdWVyeUV2ZW50Um91dGVyLnByb3RvdHlwZS5jb21wdXRlTm9kZXMgPSBmdW5jdGlvbiAoKSB7XG4gICAgaWYgKHRoaXMuYmFzZVNlbGVjdG9yKSB7XG5cdHJldHVybiAkKHRoaXMuYmFzZVNlbGVjdG9yKS5jaGlsZHJlbih0aGlzLnNlbGVjdG9yKS5hZGRCYWNrKHRoaXMuc2VsZWN0b3IpO1xuICAgIH0gZWxzZSB7XG5cdHJldHVybiAkKHRoaXMuc2VsZWN0b3IpO1xuICAgIH1cbn07XG5cbmZ1bmN0aW9uIHNpbXBsaWZ5RE9NRXZlbnQoZSkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIgayBpbiBlKSB7XG5cdHZhciB2ID0gZVtrXTtcblx0aWYgKHR5cGVvZiB2ID09PSAnb2JqZWN0JykgY29udGludWU7XG5cdGlmICh0eXBlb2YgdiA9PT0gJ2Z1bmN0aW9uJykgY29udGludWU7XG5cdGtleXMucHVzaChrKTtcbiAgICB9XG4gICAga2V5cy5zb3J0KCk7XG4gICAgdmFyIHNpbXBsaWZpZWQgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGtleXMubGVuZ3RoOyBpKyspIHtcblx0c2ltcGxpZmllZC5wdXNoKFtrZXlzW2ldLCBlW2tleXNbaV1dXSk7XG4gICAgfVxuICAgIHJldHVybiBzaW1wbGlmaWVkO1xufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxubW9kdWxlLmV4cG9ydHMuc3Bhd25KUXVlcnlEcml2ZXIgPSBzcGF3bkpRdWVyeURyaXZlcjtcbm1vZHVsZS5leHBvcnRzLnNpbXBsaWZ5RE9NRXZlbnQgPSBzaW1wbGlmeURPTUV2ZW50O1xubW9kdWxlLmV4cG9ydHMuZGVmYXVsdFdyYXBGdW5jdGlvbiA9IGRlZmF1bHRXcmFwRnVuY3Rpb247XG4iLCJtb2R1bGUuZXhwb3J0cyA9IHJlcXVpcmUoXCIuL21pbmltYXJ0LmpzXCIpO1xuXG5tb2R1bGUuZXhwb3J0cy5ET00gPSByZXF1aXJlKFwiLi9kb20tZHJpdmVyLmpzXCIpO1xubW9kdWxlLmV4cG9ydHMuSlF1ZXJ5ID0gcmVxdWlyZShcIi4vanF1ZXJ5LWRyaXZlci5qc1wiKTtcbm1vZHVsZS5leHBvcnRzLlJvdXRpbmdUYWJsZVdpZGdldCA9IHJlcXVpcmUoXCIuL3JvdXRpbmctdGFibGUtd2lkZ2V0LmpzXCIpO1xubW9kdWxlLmV4cG9ydHMuV2ViU29ja2V0ID0gcmVxdWlyZShcIi4vd2Vic29ja2V0LWRyaXZlci5qc1wiKTtcbm1vZHVsZS5leHBvcnRzLlJlZmxlY3QgPSByZXF1aXJlKFwiLi9yZWZsZWN0LmpzXCIpO1xuXG5tb2R1bGUuZXhwb3J0cy5Hcm91bmQgPSByZXF1aXJlKFwiLi9ncm91bmQuanNcIikuR3JvdW5kO1xubW9kdWxlLmV4cG9ydHMuQWN0b3IgPSByZXF1aXJlKFwiLi9hY3Rvci5qc1wiKS5BY3Rvcjtcbm1vZHVsZS5leHBvcnRzLlNweSA9IHJlcXVpcmUoXCIuL3NweS5qc1wiKS5TcHk7XG5tb2R1bGUuZXhwb3J0cy5XYWtlRGV0ZWN0b3IgPSByZXF1aXJlKFwiLi93YWtlLWRldGVjdG9yLmpzXCIpLldha2VEZXRlY3RvcjtcblxudmFyIFdvcmtlciA9IHJlcXVpcmUoXCIuL3dvcmtlci5qc1wiKTtcbm1vZHVsZS5leHBvcnRzLldvcmtlciA9IFdvcmtlci5Xb3JrZXI7XG5tb2R1bGUuZXhwb3J0cy5Xb3JrZXJHcm91bmQgPSBXb3JrZXIuV29ya2VyR3JvdW5kO1xuIiwidmFyIFJvdXRlID0gcmVxdWlyZShcIi4vcm91dGUuanNcIik7XG52YXIgVXRpbCA9IHJlcXVpcmUoXCIuL3V0aWwuanNcIik7XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG4vLyBUT0RPOiB0cmlnZ2VyLWd1YXJkcyBhcyBwZXIgbWluaW1hcnRcblxuLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuLyogRXZlbnRzIGFuZCBBY3Rpb25zICovXG5cbnZhciBfXyA9IFJvdXRlLl9fO1xudmFyIF8kID0gUm91dGUuXyQ7XG5cbmZ1bmN0aW9uIHN1YihwYXR0ZXJuLCBtZXRhTGV2ZWwsIGxldmVsKSB7XG4gICAgcmV0dXJuIFJvdXRlLnNpbXBsZUdlc3RhbHQoZmFsc2UsIHBhdHRlcm4sIG1ldGFMZXZlbCwgbGV2ZWwpO1xufVxuXG5mdW5jdGlvbiBwdWIocGF0dGVybiwgbWV0YUxldmVsLCBsZXZlbCkge1xuICAgIHJldHVybiBSb3V0ZS5zaW1wbGVHZXN0YWx0KHRydWUsIHBhdHRlcm4sIG1ldGFMZXZlbCwgbGV2ZWwpO1xufVxuXG5mdW5jdGlvbiBzcGF3bihiZWhhdmlvciwgaW5pdGlhbEdlc3RhbHRzKSB7XG4gICAgcmV0dXJuIHsgdHlwZTogXCJzcGF3blwiLFxuXHQgICAgIGJlaGF2aW9yOiBiZWhhdmlvcixcblx0ICAgICBpbml0aWFsR2VzdGFsdDogUm91dGUuZ2VzdGFsdFVuaW9uKGluaXRpYWxHZXN0YWx0cyB8fCBbXSkgfTtcbn1cblxuZnVuY3Rpb24gdXBkYXRlUm91dGVzKGdlc3RhbHRzKSB7XG4gICAgcmV0dXJuIHsgdHlwZTogXCJyb3V0ZXNcIiwgZ2VzdGFsdDogUm91dGUuZ2VzdGFsdFVuaW9uKGdlc3RhbHRzKSB9O1xufVxuXG5mdW5jdGlvbiBwZW5kaW5nUm91dGluZ1VwZGF0ZShhZ2dyZWdhdGUsIGFmZmVjdGVkU3ViZ2VzdGFsdCwga25vd25UYXJnZXQpIHtcbiAgICByZXR1cm4geyB0eXBlOiBcInBlbmRpbmdSb3V0aW5nVXBkYXRlXCIsXG5cdCAgICAgYWdncmVnYXRlOiBhZ2dyZWdhdGUsXG5cdCAgICAgYWZmZWN0ZWRTdWJnZXN0YWx0OiBhZmZlY3RlZFN1Ymdlc3RhbHQsXG5cdCAgICAga25vd25UYXJnZXQ6IGtub3duVGFyZ2V0IH07XG59XG5cbmZ1bmN0aW9uIHNlbmRNZXNzYWdlKG0sIG1ldGFMZXZlbCwgaXNGZWVkYmFjaykge1xuICAgIHJldHVybiB7IHR5cGU6IFwibWVzc2FnZVwiLFxuXHQgICAgIG1ldGFMZXZlbDogKG1ldGFMZXZlbCA9PT0gdW5kZWZpbmVkKSA/IDAgOiBtZXRhTGV2ZWwsXG5cdCAgICAgbWVzc2FnZTogbSxcblx0ICAgICBpc0ZlZWRiYWNrOiAoaXNGZWVkYmFjayA9PT0gdW5kZWZpbmVkKSA/IGZhbHNlIDogaXNGZWVkYmFjayB9O1xufVxuXG5mdW5jdGlvbiBzaHV0ZG93bldvcmxkKCkge1xuICAgIHJldHVybiB7IHR5cGU6IFwic2h1dGRvd25Xb3JsZFwiIH07XG59XG5cbi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cbi8qIENvbmZpZ3VyYXRpb25zICovXG5cbmZ1bmN0aW9uIFdvcmxkKGJvb3RGbikge1xuICAgIHRoaXMuYWxpdmUgPSB0cnVlO1xuICAgIHRoaXMuZXZlbnRRdWV1ZSA9IFtdO1xuICAgIHRoaXMucnVubmFibGVQaWRzID0ge307XG4gICAgdGhpcy5wYXJ0aWFsR2VzdGFsdCA9IFJvdXRlLmVtcHR5R2VzdGFsdDsgLy8gT25seSBnZXN0YWx0IGZyb20gbG9jYWwgcHJvY2Vzc2VzXG4gICAgdGhpcy5mdWxsR2VzdGFsdCA9IFJvdXRlLmVtcHR5R2VzdGFsdCA7OyAvLyBwYXJ0aWFsR2VzdGFsdCB1bmlvbmVkIHdpdGggZG93bndhcmRHZXN0YWx0XG4gICAgdGhpcy5wcm9jZXNzVGFibGUgPSB7fTtcbiAgICB0aGlzLnRvbWJzdG9uZXMgPSB7fTtcbiAgICB0aGlzLmRvd253YXJkR2VzdGFsdCA9IFJvdXRlLmVtcHR5R2VzdGFsdDtcbiAgICB0aGlzLnByb2Nlc3NBY3Rpb25zID0gW107XG4gICAgdGhpcy5hc0NoaWxkKC0xLCBib290Rm4sIHRydWUpO1xufVxuXG4vKiBDbGFzcyBzdGF0ZSAvIG1ldGhvZHMgKi9cblxuV29ybGQubmV4dFBpZCA9IDA7XG5cbldvcmxkLnN0YWNrID0gW107XG5cbldvcmxkLmN1cnJlbnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIFdvcmxkLnN0YWNrW1dvcmxkLnN0YWNrLmxlbmd0aCAtIDFdWzBdO1xufTtcblxuV29ybGQuYWN0aXZlUGlkID0gZnVuY3Rpb24gKCkge1xuICAgIHJldHVybiBXb3JsZC5zdGFja1tXb3JsZC5zdGFjay5sZW5ndGggLSAxXVsxXTtcbn07XG5cbldvcmxkLnNlbmQgPSBmdW5jdGlvbiAobSwgbWV0YUxldmVsLCBpc0ZlZWRiYWNrKSB7XG4gICAgV29ybGQuY3VycmVudCgpLmVucXVldWVBY3Rpb24oV29ybGQuYWN0aXZlUGlkKCksIHNlbmRNZXNzYWdlKG0sIG1ldGFMZXZlbCwgaXNGZWVkYmFjaykpO1xufTtcblxuV29ybGQudXBkYXRlUm91dGVzID0gZnVuY3Rpb24gKGdlc3RhbHRzKSB7XG4gICAgV29ybGQuY3VycmVudCgpLmVucXVldWVBY3Rpb24oV29ybGQuYWN0aXZlUGlkKCksIHVwZGF0ZVJvdXRlcyhnZXN0YWx0cykpO1xufTtcblxuV29ybGQuc3Bhd24gPSBmdW5jdGlvbiAoYmVoYXZpb3IsIGluaXRpYWxHZXN0YWx0cykge1xuICAgIFdvcmxkLmN1cnJlbnQoKS5lbnF1ZXVlQWN0aW9uKFdvcmxkLmFjdGl2ZVBpZCgpLCBzcGF3bihiZWhhdmlvciwgaW5pdGlhbEdlc3RhbHRzKSk7XG59O1xuXG5Xb3JsZC5leGl0ID0gZnVuY3Rpb24gKGV4bikge1xuICAgIFdvcmxkLmN1cnJlbnQoKS5raWxsKFdvcmxkLmFjdGl2ZVBpZCgpLCBleG4pO1xufTtcblxuV29ybGQuc2h1dGRvd25Xb3JsZCA9IGZ1bmN0aW9uICgpIHtcbiAgICBXb3JsZC5jdXJyZW50KCkuZW5xdWV1ZUFjdGlvbihXb3JsZC5hY3RpdmVQaWQoKSwgc2h1dGRvd25Xb3JsZCgpKTtcbn07XG5cbldvcmxkLndpdGhXb3JsZFN0YWNrID0gZnVuY3Rpb24gKHN0YWNrLCBmKSB7XG4gICAgdmFyIG9sZFN0YWNrID0gV29ybGQuc3RhY2s7XG4gICAgV29ybGQuc3RhY2sgPSBzdGFjaztcbiAgICB2YXIgcmVzdWx0ID0gbnVsbDtcbiAgICB0cnkge1xuXHRyZXN1bHQgPSBmKCk7XG4gICAgfSBjYXRjaCAoZSkge1xuXHRXb3JsZC5zdGFjayA9IG9sZFN0YWNrO1xuXHR0aHJvdyBlO1xuICAgIH1cbiAgICBXb3JsZC5zdGFjayA9IG9sZFN0YWNrO1xuICAgIHJldHVybiByZXN1bHQ7XG59O1xuXG5Xb3JsZC53cmFwID0gZnVuY3Rpb24gKGYpIHtcbiAgICB2YXIgc2F2ZWRTdGFjayA9IFdvcmxkLnN0YWNrLnNsaWNlKCk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcblx0dmFyIGFjdHVhbHMgPSBhcmd1bWVudHM7XG5cdHJldHVybiBXb3JsZC53aXRoV29ybGRTdGFjayhzYXZlZFN0YWNrLCBmdW5jdGlvbiAoKSB7XG5cdCAgICB2YXIgcmVzdWx0ID0gV29ybGQuY3VycmVudCgpLmFzQ2hpbGQoV29ybGQuYWN0aXZlUGlkKCksIGZ1bmN0aW9uICgpIHtcblx0XHRyZXR1cm4gZi5hcHBseShudWxsLCBhY3R1YWxzKTtcblx0ICAgIH0pO1xuXHQgICAgZm9yICh2YXIgaSA9IFdvcmxkLnN0YWNrLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG5cdFx0V29ybGQuc3RhY2tbaV1bMF0ubWFya1BpZFJ1bm5hYmxlKFdvcmxkLnN0YWNrW2ldWzFdKTtcblx0ICAgIH1cblx0ICAgIHJldHVybiByZXN1bHQ7XG5cdH0pO1xuICAgIH07XG59O1xuXG4vKiBJbnN0YW5jZSBtZXRob2RzICovXG5cbldvcmxkLnByb3RvdHlwZS5lbnF1ZXVlQWN0aW9uID0gZnVuY3Rpb24gKHBpZCwgYWN0aW9uKSB7XG4gICAgdGhpcy5wcm9jZXNzQWN0aW9ucy5wdXNoKFtwaWQsIGFjdGlvbl0pO1xufTtcblxuLy8gVGhlIGNvZGUgaXMgd3JpdHRlbiB0byBtYWludGFpbiB0aGUgcnVubmFibGVQaWRzIHNldCBjYXJlZnVsbHksIHRvXG4vLyBlbnN1cmUgd2UgY2FuIGxvY2FsbHkgZGVjaWRlIHdoZXRoZXIgd2UncmUgaW5lcnQgb3Igbm90IHdpdGhvdXRcbi8vIGhhdmluZyB0byBzZWFyY2ggdGhlIHdob2xlIGRlZXAgcHJvY2VzcyB0cmVlLlxuV29ybGQucHJvdG90eXBlLmlzSW5lcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuZXZlbnRRdWV1ZS5sZW5ndGggPT09IDBcblx0JiYgdGhpcy5wcm9jZXNzQWN0aW9ucy5sZW5ndGggPT09IDBcblx0JiYgUm91dGUuaXNfZW1wdHlTZXQodGhpcy5ydW5uYWJsZVBpZHMpO1xufTtcblxuV29ybGQucHJvdG90eXBlLm1hcmtQaWRSdW5uYWJsZSA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgICB0aGlzLnJ1bm5hYmxlUGlkc1twaWRdID0gW3BpZF07XG59O1xuXG5Xb3JsZC5wcm90b3R5cGUuc3RlcCA9IGZ1bmN0aW9uICgpIHtcbiAgICB0aGlzLmRpc3BhdGNoRXZlbnRzKCk7XG4gICAgdGhpcy5wZXJmb3JtQWN0aW9ucygpO1xuICAgIHRoaXMuc3RlcENoaWxkcmVuKCk7XG4gICAgcmV0dXJuIHRoaXMuYWxpdmUgJiYgIXRoaXMuaXNJbmVydCgpO1xufTtcblxuV29ybGQucHJvdG90eXBlLmFzQ2hpbGQgPSBmdW5jdGlvbiAocGlkLCBmLCBvbWl0TGl2ZW5lc3NDaGVjaykge1xuICAgIGlmICghKHBpZCBpbiB0aGlzLnByb2Nlc3NUYWJsZSkgJiYgIW9taXRMaXZlbmVzc0NoZWNrKSB7XG5cdGNvbnNvbGUud2FybihcIldvcmxkLmFzQ2hpbGQgZWxpZGluZyBpbnZvY2F0aW9uIG9mIGRlYWQgcHJvY2Vzc1wiLCBwaWQpO1xuXHRyZXR1cm47XG4gICAgfVxuXG4gICAgV29ybGQuc3RhY2sucHVzaChbdGhpcywgcGlkXSk7XG4gICAgdmFyIHJlc3VsdCA9IG51bGw7XG4gICAgdHJ5IHtcblx0cmVzdWx0ID0gZigpO1xuICAgIH0gY2F0Y2ggKGUpIHtcblx0dGhpcy5raWxsKHBpZCwgZSk7XG4gICAgfVxuICAgIGlmIChXb3JsZC5zdGFjay5wb3AoKVswXSAhPT0gdGhpcykge1xuXHR0aHJvdyBuZXcgRXJyb3IoXCJJbnRlcm5hbCBlcnJvcjogV29ybGQgc3RhY2sgaW1iYWxhbmNlXCIpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufTtcblxuV29ybGQucHJvdG90eXBlLmtpbGwgPSBmdW5jdGlvbiAocGlkLCBleG4pIHtcbiAgICBpZiAoZXhuICYmIGV4bi5zdGFjaykge1xuXHRjb25zb2xlLmxvZyhcIlByb2Nlc3MgZXhpdGVkXCIsIHBpZCwgZXhuLCBleG4uc3RhY2spO1xuICAgIH0gZWxzZSB7XG5cdGNvbnNvbGUubG9nKFwiUHJvY2VzcyBleGl0ZWRcIiwgcGlkLCBleG4pO1xuICAgIH1cbiAgICB2YXIgcCA9IHRoaXMucHJvY2Vzc1RhYmxlW3BpZF07XG4gICAgaWYgKHAgJiYgcC5iZWhhdmlvci50cmFwZXhpdCkge1xuXHR0aGlzLmFzQ2hpbGQocGlkLCBmdW5jdGlvbiAoKSB7IHJldHVybiBwLmJlaGF2aW9yLnRyYXBleGl0KGV4bik7IH0pO1xuICAgIH1cbiAgICBkZWxldGUgdGhpcy5wcm9jZXNzVGFibGVbcGlkXTtcbiAgICBpZiAocCkge1xuXHRpZiAoZXhuKSB7XG5cdCAgICBwLmV4aXRSZWFzb24gPSBleG47XG5cdCAgICB0aGlzLnRvbWJzdG9uZXNbcGlkXSA9IHA7XG5cdH1cblx0dGhpcy5hcHBseUFuZElzc3VlUm91dGluZ1VwZGF0ZShwLmdlc3RhbHQsIFJvdXRlLmVtcHR5R2VzdGFsdCk7XG4gICAgfVxufTtcblxuV29ybGQucHJvdG90eXBlLnN0ZXBDaGlsZHJlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcGlkcyA9IHRoaXMucnVubmFibGVQaWRzO1xuICAgIHRoaXMucnVubmFibGVQaWRzID0ge307XG4gICAgZm9yICh2YXIgcGlkIGluIHBpZHMpIHtcblx0dmFyIHAgPSB0aGlzLnByb2Nlc3NUYWJsZVtwaWRdO1xuXHRpZiAocCAmJiBwLmJlaGF2aW9yLnN0ZXAgLyogZXhpc3RzLCBoYXZlbid0IGNhbGxlZCBpdCB5ZXQgKi8pIHtcblx0ICAgIHZhciBjaGlsZEJ1c3kgPSB0aGlzLmFzQ2hpbGQocGlkIHwgMCwgZnVuY3Rpb24gKCkgeyByZXR1cm4gcC5iZWhhdmlvci5zdGVwKCkgfSk7XG5cdCAgICBpZiAoY2hpbGRCdXN5KSB0aGlzLm1hcmtQaWRSdW5uYWJsZShwaWQpO1xuXHR9XG4gICAgfVxufTtcblxuV29ybGQucHJvdG90eXBlLnBlcmZvcm1BY3Rpb25zID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBxdWV1ZSA9IHRoaXMucHJvY2Vzc0FjdGlvbnM7XG4gICAgdGhpcy5wcm9jZXNzQWN0aW9ucyA9IFtdO1xuICAgIHZhciBpdGVtO1xuICAgIHdoaWxlICgoaXRlbSA9IHF1ZXVlLnNoaWZ0KCkpICYmIHRoaXMuYWxpdmUpIHtcblx0dGhpcy5wZXJmb3JtQWN0aW9uKGl0ZW1bMF0sIGl0ZW1bMV0pO1xuICAgIH1cbn07XG5cbldvcmxkLnByb3RvdHlwZS5kaXNwYXRjaEV2ZW50cyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgcXVldWUgPSB0aGlzLmV2ZW50UXVldWU7XG4gICAgdGhpcy5ldmVudFF1ZXVlID0gW107XG4gICAgdmFyIGl0ZW07XG4gICAgd2hpbGUgKChpdGVtID0gcXVldWUuc2hpZnQoKSkpIHtcblx0dGhpcy5kaXNwYXRjaEV2ZW50KGl0ZW0pO1xuICAgIH1cbn07XG5cbldvcmxkLnByb3RvdHlwZS5wZXJmb3JtQWN0aW9uID0gZnVuY3Rpb24gKHBpZCwgYWN0aW9uKSB7XG4gICAgc3dpdGNoIChhY3Rpb24udHlwZSkge1xuICAgIGNhc2UgXCJzcGF3blwiOlxuXHR2YXIgcGlkID0gV29ybGQubmV4dFBpZCsrO1xuXHR2YXIgbmV3R2VzdGFsdCA9IGFjdGlvbi5pbml0aWFsR2VzdGFsdC5sYWJlbChwaWQpO1xuXHR0aGlzLnByb2Nlc3NUYWJsZVtwaWRdID0geyBnZXN0YWx0OiBuZXdHZXN0YWx0LCBiZWhhdmlvcjogYWN0aW9uLmJlaGF2aW9yIH07XG5cdGlmIChhY3Rpb24uYmVoYXZpb3IuYm9vdCkge1xuXHQgICAgdGhpcy5hc0NoaWxkKHBpZCwgZnVuY3Rpb24gKCkgeyBhY3Rpb24uYmVoYXZpb3IuYm9vdCgpIH0pO1xuXHQgICAgdGhpcy5tYXJrUGlkUnVubmFibGUocGlkKTtcblx0fVxuXHR0aGlzLmFwcGx5QW5kSXNzdWVSb3V0aW5nVXBkYXRlKFJvdXRlLmVtcHR5R2VzdGFsdCwgbmV3R2VzdGFsdCwgcGlkKTtcblx0YnJlYWs7XG4gICAgY2FzZSBcInJvdXRlc1wiOlxuXHRpZiAocGlkIGluIHRoaXMucHJvY2Vzc1RhYmxlKSB7XG5cdCAgICAvLyBpdCBtYXkgbm90IGJlOiB0aGlzIG1pZ2h0IGJlIHRoZSByb3V0aW5nIHVwZGF0ZSBmcm9tIGFcblx0ICAgIC8vIGtpbGwgb2YgdGhlIHByb2Nlc3Ncblx0ICAgIHZhciBvbGRHZXN0YWx0ID0gdGhpcy5wcm9jZXNzVGFibGVbcGlkXS5nZXN0YWx0O1xuXHQgICAgdmFyIG5ld0dlc3RhbHQgPSBhY3Rpb24uZ2VzdGFsdC5sYWJlbChwaWR8MCk7XG5cdCAgICAvLyBeIHBpZHwwOiBjb252ZXJ0IHBpZCBmcm9tIHN0cmluZyAodGFibGUga2V5ISkgdG8gaW50ZWdlclxuXHQgICAgdGhpcy5wcm9jZXNzVGFibGVbcGlkXS5nZXN0YWx0ID0gbmV3R2VzdGFsdDtcblx0ICAgIHRoaXMuYXBwbHlBbmRJc3N1ZVJvdXRpbmdVcGRhdGUob2xkR2VzdGFsdCwgbmV3R2VzdGFsdCwgcGlkKTtcblx0fVxuXHRicmVhaztcbiAgICBjYXNlIFwibWVzc2FnZVwiOlxuXHRpZiAoYWN0aW9uLm1ldGFMZXZlbCA9PT0gMCkge1xuXHQgICAgdGhpcy5ldmVudFF1ZXVlLnB1c2goYWN0aW9uKTtcblx0fSBlbHNlIHtcblx0ICAgIFdvcmxkLnNlbmQoYWN0aW9uLm1lc3NhZ2UsIGFjdGlvbi5tZXRhTGV2ZWwgLSAxLCBhY3Rpb24uaXNGZWVkYmFjayk7XG5cdH1cblx0YnJlYWs7XG4gICAgY2FzZSBcInNodXRkb3duV29ybGRcIjpcblx0dGhpcy5hbGl2ZSA9IGZhbHNlOyAvLyBmb3JjZSB1cyB0byBzdG9wIGRvaW5nIHRoaW5ncyBpbW1lZGlhdGVseVxuXHRXb3JsZC5leGl0KCk7XG5cdGJyZWFrO1xuICAgIGRlZmF1bHQ6XG5cdHZhciBleG4gPSBuZXcgRXJyb3IoXCJBY3Rpb24gdHlwZSBcIiArIGFjdGlvbi50eXBlICsgXCIgbm90IHVuZGVyc3Rvb2RcIik7XG5cdGV4bi5hY3Rpb24gPSBhY3Rpb247XG5cdHRocm93IGV4bjtcbiAgICB9XG59O1xuXG5Xb3JsZC5wcm90b3R5cGUudXBkYXRlRnVsbEdlc3RhbHQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5mdWxsR2VzdGFsdCA9IHRoaXMucGFydGlhbEdlc3RhbHQudW5pb24odGhpcy5kb3dud2FyZEdlc3RhbHQpO1xufTtcblxuV29ybGQucHJvdG90eXBlLmlzc3VlTG9jYWxSb3V0aW5nVXBkYXRlID0gZnVuY3Rpb24gKGFmZmVjdGVkU3ViZ2VzdGFsdCwga25vd25UYXJnZXQpIHtcbiAgICB0aGlzLmV2ZW50UXVldWUucHVzaChwZW5kaW5nUm91dGluZ1VwZGF0ZSh0aGlzLmZ1bGxHZXN0YWx0LFxuXHRcdFx0XHRcdCAgICAgIGFmZmVjdGVkU3ViZ2VzdGFsdCxcblx0XHRcdFx0XHQgICAgICBrbm93blRhcmdldCkpO1xufTtcblxuV29ybGQucHJvdG90eXBlLmFwcGx5QW5kSXNzdWVSb3V0aW5nVXBkYXRlID0gZnVuY3Rpb24gKG9sZGcsIG5ld2csIGtub3duVGFyZ2V0KSB7XG4gICAga25vd25UYXJnZXQgPSB0eXBlb2Yga25vd25UYXJnZXQgPT09ICd1bmRlZmluZWQnID8gbnVsbCA6IGtub3duVGFyZ2V0O1xuICAgIHRoaXMucGFydGlhbEdlc3RhbHQgPSB0aGlzLnBhcnRpYWxHZXN0YWx0LmVyYXNlUGF0aChvbGRnKS51bmlvbihuZXdnKTtcbiAgICB0aGlzLnVwZGF0ZUZ1bGxHZXN0YWx0KCk7XG4gICAgdGhpcy5pc3N1ZUxvY2FsUm91dGluZ1VwZGF0ZShvbGRnLnVuaW9uKG5ld2cpLCBrbm93blRhcmdldCk7XG4gICAgV29ybGQudXBkYXRlUm91dGVzKFt0aGlzLnBhcnRpYWxHZXN0YWx0LmRyb3AoKV0pO1xufTtcblxuV29ybGQucHJvdG90eXBlLmRpc3BhdGNoRXZlbnQgPSBmdW5jdGlvbiAoZSkge1xuICAgIHN3aXRjaCAoZS50eXBlKSB7XG4gICAgY2FzZSBcInBlbmRpbmdSb3V0aW5nVXBkYXRlXCI6XG5cdHZhciBwaWRzID0gZS5hZmZlY3RlZFN1Ymdlc3RhbHQubWF0Y2goZS5hZ2dyZWdhdGUpO1xuXHRpZiAoZS5rbm93blRhcmdldCAhPT0gbnVsbCkgcGlkcy51bnNoaWZ0KGUua25vd25UYXJnZXQpO1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IHBpZHMubGVuZ3RoOyBpKyspIHtcblx0ICAgIHZhciBwaWQgPSBwaWRzW2ldO1xuXHQgICAgaWYgKHBpZCA9PT0gXCJvdXRcIikgY29uc29sZS53YXJuKFwiV291bGQgaGF2ZSBkZWxpdmVyZWQgYSByb3V0aW5nIHVwZGF0ZSB0byBlbnZpcm9ubWVudFwiKTtcblx0ICAgIHZhciBwID0gdGhpcy5wcm9jZXNzVGFibGVbcGlkXTtcblx0ICAgIGlmIChwKSB7XG5cdFx0dmFyIGcgPSBlLmFnZ3JlZ2F0ZS5maWx0ZXIocC5nZXN0YWx0KTtcblx0XHR0aGlzLmFzQ2hpbGQocGlkLCBmdW5jdGlvbiAoKSB7IHAuYmVoYXZpb3IuaGFuZGxlRXZlbnQodXBkYXRlUm91dGVzKFtnXSkpIH0pO1xuXHRcdHRoaXMubWFya1BpZFJ1bm5hYmxlKHBpZCk7XG5cdCAgICB9XG5cdH1cblx0YnJlYWs7XG5cbiAgICBjYXNlIFwibWVzc2FnZVwiOlxuXHR2YXIgcGlkcyA9IHRoaXMucGFydGlhbEdlc3RhbHQubWF0Y2hWYWx1ZShlLm1lc3NhZ2UsIGUubWV0YUxldmVsLCBlLmlzRmVlZGJhY2spO1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IHBpZHMubGVuZ3RoOyBpKyspIHtcblx0ICAgIHZhciBwaWQgPSBwaWRzW2ldO1xuXHQgICAgdmFyIHAgPSB0aGlzLnByb2Nlc3NUYWJsZVtwaWRdO1xuXHQgICAgdGhpcy5hc0NoaWxkKHBpZCwgZnVuY3Rpb24gKCkgeyBwLmJlaGF2aW9yLmhhbmRsZUV2ZW50KGUpIH0pO1xuXHQgICAgdGhpcy5tYXJrUGlkUnVubmFibGUocGlkKTtcblx0fVxuXHRicmVhaztcblxuICAgIGRlZmF1bHQ6XG5cdHZhciBleG4gPSBuZXcgRXJyb3IoXCJFdmVudCB0eXBlIFwiICsgZS50eXBlICsgXCIgbm90IGRpc3BhdGNoYWJsZVwiKTtcblx0ZXhuLmV2ZW50ID0gZTtcblx0dGhyb3cgZXhuO1xuICAgIH1cbn07XG5cbldvcmxkLnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgc3dpdGNoIChlLnR5cGUpIHtcbiAgICBjYXNlIFwicm91dGVzXCI6XG5cdHZhciBvbGREb3dud2FyZCA9IHRoaXMuZG93bndhcmRHZXN0YWx0O1xuXHR0aGlzLmRvd253YXJkR2VzdGFsdCA9IGUuZ2VzdGFsdC5sYWJlbChcIm91dFwiKS5saWZ0KCk7XG5cdHRoaXMudXBkYXRlRnVsbEdlc3RhbHQoKTtcblx0dGhpcy5pc3N1ZUxvY2FsUm91dGluZ1VwZGF0ZShvbGREb3dud2FyZC51bmlvbih0aGlzLmRvd253YXJkR2VzdGFsdCksIG51bGwpO1xuXHRicmVhaztcbiAgICBjYXNlIFwibWVzc2FnZVwiOlxuXHR0aGlzLmV2ZW50UXVldWUucHVzaChzZW5kTWVzc2FnZShlLm1lc3NhZ2UsIGUubWV0YUxldmVsICsgMSwgZS5pc0ZlZWRiYWNrKSk7XG5cdGJyZWFrO1xuICAgIGRlZmF1bHQ6XG5cdHZhciBleG4gPSBuZXcgRXJyb3IoXCJFdmVudCB0eXBlIFwiICsgZS50eXBlICsgXCIgbm90IHVuZGVyc3Rvb2RcIik7XG5cdGV4bi5ldmVudCA9IGU7XG5cdHRocm93IGV4bjtcbiAgICB9XG59O1xuXG4vKiBEZWJ1Z2dpbmcsIG1hbmFnZW1lbnQsIGFuZCBtb25pdG9yaW5nICovXG5cbldvcmxkLnByb3RvdHlwZS5wcm9jZXNzVHJlZSA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIga2lkcyA9IFtdO1xuICAgIGZvciAodmFyIHBpZCBpbiB0aGlzLnByb2Nlc3NUYWJsZSkge1xuXHR2YXIgcCA9IHRoaXMucHJvY2Vzc1RhYmxlW3BpZF07XG5cdGlmIChwLmJlaGF2aW9yIGluc3RhbmNlb2YgV29ybGQpIHtcblx0ICAgIGtpZHMucHVzaChbcGlkLCBwLmJlaGF2aW9yLnByb2Nlc3NUcmVlKCldKTtcblx0fSBlbHNlIHtcblx0ICAgIGtpZHMucHVzaChbcGlkLCBwXSk7XG5cdH1cbiAgICB9XG4gICAgZm9yICh2YXIgcGlkIGluIHRoaXMudG9tYnN0b25lcykge1xuXHRraWRzLnB1c2goW3BpZCwgdGhpcy50b21ic3RvbmVzW3BpZF1dKTtcbiAgICB9XG4gICAga2lkcy5zb3J0KCk7XG4gICAgcmV0dXJuIGtpZHM7XG59O1xuXG5Xb3JsZC5wcm90b3R5cGUudGV4dFByb2Nlc3NUcmVlID0gZnVuY3Rpb24gKG93blBpZCkge1xuICAgIHZhciBsaW5lcyA9IFtdO1xuXG4gICAgZnVuY3Rpb24gZHVtcFByb2Nlc3MocHJlZml4LCBwaWQsIHApIHtcblx0aWYgKEFycmF5LmlzQXJyYXkocCkpIHtcblx0ICAgIGxpbmVzLnB1c2gocHJlZml4ICsgJy0tKyAnICsgcGlkKTtcblx0ICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuXHRcdGR1bXBQcm9jZXNzKHByZWZpeCArICcgIHwnLCBwW2ldWzBdLCBwW2ldWzFdKTtcblx0ICAgIH1cblx0ICAgIGxpbmVzLnB1c2gocHJlZml4KTtcblx0fSBlbHNlIHtcblx0ICAgIHZhciBsYWJlbCA9IHAuYmVoYXZpb3IubmFtZSB8fCBwLmJlaGF2aW9yLmNvbnN0cnVjdG9yLm5hbWUgfHwgJyc7XG5cdCAgICB2YXIgdG9tYnN0b25lU3RyaW5nID0gcC5leGl0UmVhc29uID8gJyAoRVhJVEVEOiAnICsgcC5leGl0UmVhc29uICsgJykgJyA6ICcnO1xuXHQgICAgbGluZXMucHVzaChwcmVmaXggKyAnLS0gJyArIHBpZCArICc6ICcgKyBsYWJlbCArXG5cdFx0ICAgICAgIHRvbWJzdG9uZVN0cmluZyArXG5cdFx0ICAgICAgIEpTT04uc3RyaW5naWZ5KHAuYmVoYXZpb3IsIGZ1bmN0aW9uIChrLCB2KSB7XG5cdFx0XHQgICByZXR1cm4gayA9PT0gJ25hbWUnID8gdW5kZWZpbmVkIDogdjtcblx0XHQgICAgICAgfSkpO1xuXHR9XG4gICAgfVxuXG4gICAgZHVtcFByb2Nlc3MoJycsIG93blBpZCB8fCAnJywgdGhpcy5wcm9jZXNzVHJlZSgpKTtcbiAgICByZXR1cm4gbGluZXMuam9pbignXFxuJyk7XG59O1xuXG5Xb3JsZC5wcm90b3R5cGUuY2xlYXJUb21ic3RvbmVzID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMudG9tYnN0b25lcyA9IHt9O1xuICAgIGZvciAodmFyIHBpZCBpbiB0aGlzLnByb2Nlc3NUYWJsZSkge1xuXHR2YXIgcCA9IHRoaXMucHJvY2Vzc1RhYmxlW3BpZF07XG5cdGlmIChwLmJlaGF2aW9yIGluc3RhbmNlb2YgV29ybGQpIHtcblx0ICAgIHAuYmVoYXZpb3IuY2xlYXJUb21ic3RvbmVzKCk7XG5cdH1cbiAgICB9XG59O1xuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG4vKiBVdGlsaXRpZXM6IG1hdGNoaW5nIGRlbWFuZCBmb3Igc29tZSBzZXJ2aWNlICovXG5cbmZ1bmN0aW9uIERlbWFuZE1hdGNoZXIocHJvamVjdGlvbiwgbWV0YUxldmVsLCBvcHRpb25zKSB7XG4gICAgb3B0aW9ucyA9IFV0aWwuZXh0ZW5kKHtcblx0ZGVtYW5kTGV2ZWw6IDAsXG5cdHN1cHBseUxldmVsOiAwLFxuXHRkZW1hbmRTaWRlSXNTdWJzY3JpcHRpb246IGZhbHNlXG4gICAgfSwgb3B0aW9ucyk7XG4gICAgdGhpcy5wYXR0ZXJuID0gUm91dGUucHJvamVjdGlvblRvUGF0dGVybihwcm9qZWN0aW9uKTtcbiAgICB0aGlzLnByb2plY3Rpb25TcGVjID0gUm91dGUuY29tcGlsZVByb2plY3Rpb24ocHJvamVjdGlvbik7XG4gICAgdGhpcy5tZXRhTGV2ZWwgPSBtZXRhTGV2ZWwgfCAwO1xuICAgIHRoaXMuZGVtYW5kTGV2ZWwgPSBvcHRpb25zLmRlbWFuZExldmVsO1xuICAgIHRoaXMuc3VwcGx5TGV2ZWwgPSBvcHRpb25zLnN1cHBseUxldmVsO1xuICAgIHRoaXMuZGVtYW5kU2lkZUlzU3Vic2NyaXB0aW9uID0gb3B0aW9ucy5kZW1hbmRTaWRlSXNTdWJzY3JpcHRpb247XG4gICAgdGhpcy5vbkRlbWFuZEluY3JlYXNlID0gZnVuY3Rpb24gKGNhcHR1cmVzKSB7XG5cdGNvbnNvbGUuZXJyb3IoXCJVbmhhbmRsZWQgaW5jcmVhc2UgaW4gZGVtYW5kIGZvciByb3V0ZVwiLCBjYXB0dXJlcyk7XG4gICAgfTtcbiAgICB0aGlzLm9uU3VwcGx5RGVjcmVhc2UgPSBmdW5jdGlvbiAoY2FwdHVyZXMpIHtcblx0Y29uc29sZS5lcnJvcihcIlVuaGFuZGxlZCBkZWNyZWFzZSBpbiBzdXBwbHkgZm9yIHJvdXRlXCIsIGNhcHR1cmVzKTtcbiAgICB9O1xuICAgIHRoaXMuY3VycmVudERlbWFuZCA9IHt9O1xuICAgIHRoaXMuY3VycmVudFN1cHBseSA9IHt9O1xufVxuXG5EZW1hbmRNYXRjaGVyLnByb3RvdHlwZS5ib290ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBvYnNlcnZlckxldmVsID0gMSArIE1hdGgubWF4KHRoaXMuZGVtYW5kTGV2ZWwsIHRoaXMuc3VwcGx5TGV2ZWwpO1xuICAgIFdvcmxkLnVwZGF0ZVJvdXRlcyhbc3ViKHRoaXMucGF0dGVybiwgdGhpcy5tZXRhTGV2ZWwsIG9ic2VydmVyTGV2ZWwpLFxuXHRcdFx0cHViKHRoaXMucGF0dGVybiwgdGhpcy5tZXRhTGV2ZWwsIG9ic2VydmVyTGV2ZWwpXSk7XG59O1xuXG5EZW1hbmRNYXRjaGVyLnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgaWYgKGUudHlwZSA9PT0gXCJyb3V0ZXNcIikge1xuXHR0aGlzLmhhbmRsZUdlc3RhbHQoZS5nZXN0YWx0KTtcbiAgICB9XG59O1xuXG5EZW1hbmRNYXRjaGVyLnByb3RvdHlwZS5oYW5kbGVHZXN0YWx0ID0gZnVuY3Rpb24gKGdlc3RhbHQpIHtcbiAgICB2YXIgbmV3RGVtYW5kTWF0Y2hlciA9IGdlc3RhbHQucHJvamVjdCh0aGlzLnByb2plY3Rpb25TcGVjLFxuXHRcdFx0XHRcdCAgICF0aGlzLmRlbWFuZFNpZGVJc1N1YnNjcmlwdGlvbixcblx0XHRcdFx0XHQgICB0aGlzLm1ldGFMZXZlbCxcblx0XHRcdFx0XHQgICB0aGlzLmRlbWFuZExldmVsKTtcbiAgICB2YXIgbmV3U3VwcGx5TWF0Y2hlciA9IGdlc3RhbHQucHJvamVjdCh0aGlzLnByb2plY3Rpb25TcGVjLFxuXHRcdFx0XHRcdCAgIHRoaXMuZGVtYW5kU2lkZUlzU3Vic2NyaXB0aW9uLFxuXHRcdFx0XHRcdCAgIHRoaXMubWV0YUxldmVsLFxuXHRcdFx0XHRcdCAgIHRoaXMuc3VwcGx5TGV2ZWwpO1xuICAgIHZhciBuZXdEZW1hbmQgPSBSb3V0ZS5hcnJheVRvU2V0KFJvdXRlLm1hdGNoZXJLZXlzKG5ld0RlbWFuZE1hdGNoZXIpKTtcbiAgICB2YXIgbmV3U3VwcGx5ID0gUm91dGUuYXJyYXlUb1NldChSb3V0ZS5tYXRjaGVyS2V5cyhuZXdTdXBwbHlNYXRjaGVyKSk7XG4gICAgdmFyIGRlbWFuZERlbHRhID0gUm91dGUuc2V0U3VidHJhY3QobmV3RGVtYW5kLCB0aGlzLmN1cnJlbnREZW1hbmQpO1xuICAgIHZhciBzdXBwbHlEZWx0YSA9IFJvdXRlLnNldFN1YnRyYWN0KHRoaXMuY3VycmVudFN1cHBseSwgbmV3U3VwcGx5KTtcbiAgICB2YXIgZGVtYW5kSW5jciA9IFJvdXRlLnNldFN1YnRyYWN0KGRlbWFuZERlbHRhLCBuZXdTdXBwbHkpO1xuICAgIHZhciBzdXBwbHlEZWNyID0gUm91dGUuc2V0SW50ZXJzZWN0KHN1cHBseURlbHRhLCBuZXdEZW1hbmQpO1xuICAgIHRoaXMuY3VycmVudERlbWFuZCA9IG5ld0RlbWFuZDtcbiAgICB0aGlzLmN1cnJlbnRTdXBwbHkgPSBuZXdTdXBwbHk7XG4gICAgZm9yICh2YXIgayBpbiBkZW1hbmRJbmNyKSB0aGlzLm9uRGVtYW5kSW5jcmVhc2UoZGVtYW5kSW5jcltrXSk7XG4gICAgZm9yICh2YXIgayBpbiBzdXBwbHlEZWNyKSB0aGlzLm9uU3VwcGx5RGVjcmVhc2Uoc3VwcGx5RGVjcltrXSk7XG59O1xuXG4vKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG4vKiBVdGlsaXRpZXM6IGRlZHVwbGljYXRvciAqL1xuXG5mdW5jdGlvbiBEZWR1cGxpY2F0b3IodHRsX21zKSB7XG4gICAgdGhpcy50dGxfbXMgPSB0dGxfbXMgfHwgMTAwMDA7XG4gICAgdGhpcy5xdWV1ZSA9IFtdO1xuICAgIHRoaXMubWFwID0ge307XG4gICAgdGhpcy50aW1lcklkID0gbnVsbDtcbn1cblxuRGVkdXBsaWNhdG9yLnByb3RvdHlwZS5hY2NlcHQgPSBmdW5jdGlvbiAobSkge1xuICAgIHZhciBzID0gSlNPTi5zdHJpbmdpZnkobSk7XG4gICAgaWYgKHMgaW4gdGhpcy5tYXApIHJldHVybiBmYWxzZTtcbiAgICB2YXIgZW50cnkgPSBbKCtuZXcgRGF0ZSgpKSArIHRoaXMudHRsX21zLCBzLCBtXTtcbiAgICB0aGlzLm1hcFtzXSA9IGVudHJ5O1xuICAgIHRoaXMucXVldWUucHVzaChlbnRyeSk7XG5cbiAgICBpZiAodGhpcy50aW1lcklkID09PSBudWxsKSB7XG5cdHZhciBzZWxmID0gdGhpcztcblx0dGhpcy50aW1lcklkID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24gKCkgeyBzZWxmLmV4cGlyZU1lc3NhZ2VzKCk7IH0sXG5cdFx0XHRcdCAgIHRoaXMudHRsX21zID4gMTAwMCA/IDEwMDAgOiB0aGlzLnR0bF9tcyk7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcblxuRGVkdXBsaWNhdG9yLnByb3RvdHlwZS5leHBpcmVNZXNzYWdlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbm93ID0gK25ldyBEYXRlKCk7XG4gICAgd2hpbGUgKHRoaXMucXVldWUubGVuZ3RoID4gMCAmJiB0aGlzLnF1ZXVlWzBdWzBdIDw9IG5vdykge1xuXHR2YXIgZW50cnkgPSB0aGlzLnF1ZXVlLnNoaWZ0KCk7XG5cdGRlbGV0ZSB0aGlzLm1hcFtlbnRyeVsxXV07XG4gICAgfVxuICAgIGlmICh0aGlzLnF1ZXVlLmxlbmd0aCA9PT0gMCkge1xuXHRjbGVhckludGVydmFsKHRoaXMudGltZXJJZCk7XG5cdHRoaXMudGltZXJJZCA9IG51bGw7XG4gICAgfVxufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLl9fID0gX187XG5tb2R1bGUuZXhwb3J0cy5fJCA9IF8kO1xuXG5tb2R1bGUuZXhwb3J0cy5zdWIgPSBzdWI7XG5tb2R1bGUuZXhwb3J0cy5wdWIgPSBwdWI7XG5tb2R1bGUuZXhwb3J0cy5zcGF3biA9IHNwYXduO1xubW9kdWxlLmV4cG9ydHMudXBkYXRlUm91dGVzID0gdXBkYXRlUm91dGVzO1xubW9kdWxlLmV4cG9ydHMuc2VuZE1lc3NhZ2UgPSBzZW5kTWVzc2FnZTtcbm1vZHVsZS5leHBvcnRzLnNodXRkb3duV29ybGQgPSBzaHV0ZG93bldvcmxkO1xuXG5tb2R1bGUuZXhwb3J0cy5Xb3JsZCA9IFdvcmxkO1xubW9kdWxlLmV4cG9ydHMuRGVtYW5kTWF0Y2hlciA9IERlbWFuZE1hdGNoZXI7XG5tb2R1bGUuZXhwb3J0cy5EZWR1cGxpY2F0b3IgPSBEZWR1cGxpY2F0b3I7XG5tb2R1bGUuZXhwb3J0cy5Sb3V0ZSA9IFJvdXRlO1xuIiwiLy8gUmVmbGVjdGlvbiBvbiBmdW5jdGlvbiBmb3JtYWwgcGFyYW1ldGVyIGxpc3RzLlxuLy8gVGhpcyBtb2R1bGUgaXMgYmFzZWQgb24gQW5ndWxhcidzIFwiaW5qZWN0b3JcIiBjb2RlLFxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci5qcy9ibG9iL21hc3Rlci9zcmMvYXV0by9pbmplY3Rvci5qcyxcbi8vIE1JVCBsaWNlbnNlZCwgYW5kIGhlbmNlOlxuLy8gQ29weXJpZ2h0IChjKSAyMDEwLTIwMTQgR29vZ2xlLCBJbmMuIGh0dHA6Ly9hbmd1bGFyanMub3JnXG4vLyBDb3B5cmlnaHQgKGMpIDIwMTQgVG9ueSBHYXJub2NrLUpvbmVzXG5cbnZhciBGTl9BUkdTID0gL15mdW5jdGlvblxccypbXlxcKF0qXFwoXFxzKihbXlxcKV0qKVxcKS9tO1xudmFyIEZOX0FSR19TUExJVCA9IC8sLztcbnZhciBTVFJJUF9DT01NRU5UUyA9IC8oKFxcL1xcLy4qJCl8KFxcL1xcKltcXHNcXFNdKj9cXCpcXC8pKS9tZztcblxuZnVuY3Rpb24gZm9ybWFsUGFyYW1ldGVycyhmbikge1xuICAgIHZhciByZXN1bHQgPSBbXTtcblxuICAgIHZhciBmblRleHQgPSBmbi50b1N0cmluZygpLnJlcGxhY2UoU1RSSVBfQ09NTUVOVFMsICcnKTtcbiAgICB2YXIgYXJnRGVjbCA9IGZuVGV4dC5tYXRjaChGTl9BUkdTKTtcbiAgICB2YXIgYXJncyA9IGFyZ0RlY2xbMV0uc3BsaXQoRk5fQVJHX1NQTElUKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcblx0dmFyIHRyaW1tZWQgPSBhcmdzW2ldLnRyaW0oKTtcblx0aWYgKHRyaW1tZWQpIHsgcmVzdWx0LnB1c2godHJpbW1lZCk7IH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5tb2R1bGUuZXhwb3J0cy5mb3JtYWxQYXJhbWV0ZXJzID0gZm9ybWFsUGFyYW1ldGVycztcbiIsInZhciBfXyA9IFwiX19cIjsgLyogd2lsZGNhcmQgbWFya2VyICovXG5cbnZhciBTT0EgPSBcIl9fW1wiOyAvLyBzdGFydCBvZiBhcnJheVxudmFyIEVPQSA9IFwiX19dXCI7IC8vIGVuZCBvZiBhcnJheVxuXG5mdW5jdGlvbiBkaWUobWVzc2FnZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihtZXNzYWdlKTtcbn1cblxuZnVuY3Rpb24gJEVtYmVkZGVkKG1hdGNoZXIpIHtcbiAgICB0aGlzLm1hdGNoZXIgPSBtYXRjaGVyO1xufVxuXG5mdW5jdGlvbiBlbWJlZGRlZE1hdGNoZXIobWF0Y2hlcikge1xuICAgIHJldHVybiBuZXcgJEVtYmVkZGVkKG1hdGNoZXIpO1xufVxuXG4vLyBUaGUgbmFtZSBhcmd1bWVudCBzaG91bGQgYmUgYSBzdHJpbmcgb3IgbnVsbDsgaXQgZGVmYXVsdHMgdG8gbnVsbC5cbi8vIFRoZSBwYXR0ZXJuIGFyZ3VtZW50IGRlZmF1bHRzIHRvIHdpbGRjYXJkLCBfXy5cbmZ1bmN0aW9uICRDYXB0dXJlKG5hbWUsIHBhdHRlcm4pIHtcbiAgICB0aGlzLm5hbWUgPSBuYW1lIHx8IG51bGw7XG4gICAgdGhpcy5wYXR0ZXJuID0gKHR5cGVvZiBwYXR0ZXJuID09PSAndW5kZWZpbmVkJyA/IF9fIDogcGF0dGVybik7XG59XG5cbi8vIEFiYnJldmlhdGlvbjogXyQoLi4uKSA8PT0+IG5ldyAkQ2FwdHVyZSguLi4pXG5mdW5jdGlvbiBfJChuYW1lLCBwYXR0ZXJuKSB7XG4gICAgcmV0dXJuIG5ldyAkQ2FwdHVyZShuYW1lLCBwYXR0ZXJuKTtcbn1cblxuZnVuY3Rpb24gaXNDYXB0dXJlKHgpIHsgcmV0dXJuIHggaW5zdGFuY2VvZiAkQ2FwdHVyZSB8fCB4ID09PSBfJDsgfVxuZnVuY3Rpb24gY2FwdHVyZU5hbWUoeCkgeyByZXR1cm4geCBpbnN0YW5jZW9mICRDYXB0dXJlID8geC5uYW1lIDogbnVsbDsgfVxuZnVuY3Rpb24gY2FwdHVyZVBhdHRlcm4oeCkgeyByZXR1cm4geCBpbnN0YW5jZW9mICRDYXB0dXJlID8geC5wYXR0ZXJuIDogX187IH1cblxudmFyIFNPQyA9IFwiX197e1wiOyAvLyBzdGFydCBvZiBjYXB0dXJlXG52YXIgRU9DID0gXCJfX319XCI7IC8vIGVuZCBvZiBjYXB0dXJlXG5cbmZ1bmN0aW9uICRTdWNjZXNzKHZhbHVlKSB7XG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xufVxuXG5mdW5jdGlvbiAkV2lsZGNhcmRTZXF1ZW5jZShtYXRjaGVyKSB7XG4gICAgdGhpcy5tYXRjaGVyID0gbWF0Y2hlcjtcbn1cblxuZnVuY3Rpb24gJERpY3QoKSB7XG4gICAgdGhpcy5sZW5ndGggPSAwO1xuICAgIHRoaXMuZW50cmllcyA9IHt9O1xufVxuXG4kRGljdC5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKGtleSkge1xuICAgIHJldHVybiB0aGlzLmVudHJpZXNba2V5XSB8fCBlbXB0eU1hdGNoZXI7XG59O1xuXG4kRGljdC5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKGtleSwgdmFsKSB7XG4gICAgaWYgKCEoa2V5IGluIHRoaXMuZW50cmllcykpIHRoaXMubGVuZ3RoKys7XG4gICAgdGhpcy5lbnRyaWVzW2tleV0gPSB2YWw7XG59O1xuXG4kRGljdC5wcm90b3R5cGUuY2xlYXIgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgaWYgKGtleSBpbiB0aGlzLmVudHJpZXMpIHRoaXMubGVuZ3RoLS07XG4gICAgZGVsZXRlIHRoaXMuZW50cmllc1trZXldO1xufTtcblxuJERpY3QucHJvdG90eXBlLmlzRW1wdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMubGVuZ3RoID09PSAwO1xufTtcblxuJERpY3QucHJvdG90eXBlLmNvcHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG90aGVyID0gbmV3ICREaWN0KCk7XG4gICAgb3RoZXIubGVuZ3RoID0gdGhpcy5sZW5ndGg7XG4gICAgZm9yICh2YXIga2V5IGluIHRoaXMuZW50cmllcykge1xuXHRpZiAodGhpcy5lbnRyaWVzLmhhc093blByb3BlcnR5KGtleSkpIHtcblx0ICAgIG90aGVyLmVudHJpZXNba2V5XSA9IHRoaXMuZW50cmllc1trZXldO1xuXHR9XG4gICAgfVxuICAgIHJldHVybiBvdGhlcjtcbn07XG5cbiREaWN0LnByb3RvdHlwZS5lbXB0eUd1YXJkID0gZnVuY3Rpb24gKCkge1xuICAgIGlmICh0aGlzLmlzRW1wdHkoKSkgcmV0dXJuIGVtcHR5TWF0Y2hlcjtcbiAgICByZXR1cm4gdGhpcztcbn07XG5cbiREaWN0LnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAoa2V5KSB7XG4gICAgcmV0dXJuIGtleSBpbiB0aGlzLmVudHJpZXM7XG59O1xuXG4kRGljdC5wcm90b3R5cGUuc29ydGVkS2V5cyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIga3MgPSBbXTtcbiAgICBmb3IgKHZhciBrIGluIHRoaXMuZW50cmllcykga3MucHVzaChrKTtcbiAgICBrcy5zb3J0KCk7XG4gICAgcmV0dXJuIGtzO1xufVxuXG5mdW5jdGlvbiBpc19lbXB0eU1hdGNoZXIobSkge1xuICAgIHJldHVybiAobSA9PT0gZW1wdHlNYXRjaGVyKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBDb25zdHJ1Y3RvcnNcblxudmFyIGVtcHR5TWF0Y2hlciA9IG51bGw7XG5cbmZ1bmN0aW9uIHJzdWNjZXNzKHYpIHtcbiAgICByZXR1cm4gKHYgPT09IGVtcHR5TWF0Y2hlcikgPyBlbXB0eU1hdGNoZXIgOiBuZXcgJFN1Y2Nlc3Modik7XG59XG5cbmZ1bmN0aW9uIHJzZXEoZSwgcikge1xuICAgIGlmIChyID09PSBlbXB0eU1hdGNoZXIpIHJldHVybiBlbXB0eU1hdGNoZXI7XG4gICAgdmFyIHMgPSBuZXcgJERpY3QoKTtcbiAgICBzLnNldChlLCByKTtcbiAgICByZXR1cm4gcztcbn1cblxuZnVuY3Rpb24gcndpbGQocikge1xuICAgIHJldHVybiByc2VxKF9fLCByKTtcbn1cblxuZnVuY3Rpb24gcndpbGRzZXEocikge1xuICAgIHJldHVybiAociA9PT0gZW1wdHlNYXRjaGVyKSA/IGVtcHR5TWF0Y2hlciA6IG5ldyAkV2lsZGNhcmRTZXF1ZW5jZShyKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIGNvbXBpbGVQYXR0ZXJuKHYsIHApIHtcbiAgICBpZiAoIXApIGRpZShcImNvbXBpbGVQYXR0ZXJuOiBtaXNzaW5nIHBhdHRlcm5cIik7XG4gICAgcmV0dXJuIHdhbGsocCwgcnNlcShFT0EsIHJzdWNjZXNzKHYpKSk7XG5cbiAgICBmdW5jdGlvbiB3YWxrKHAsIGFjYykge1xuXHRpZiAocCA9PT0gX18pIHJldHVybiByd2lsZChhY2MpO1xuXG5cdGlmIChBcnJheS5pc0FycmF5KHApKSB7XG5cdCAgICBhY2MgPSByc2VxKEVPQSwgYWNjKTtcblx0ICAgIGZvciAodmFyIGkgPSBwLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG5cdFx0YWNjID0gd2FsayhwW2ldLCBhY2MpO1xuXHQgICAgfVxuXHQgICAgcmV0dXJuIHJzZXEoU09BLCBhY2MpO1xuXHR9XG5cblx0aWYgKHAgaW5zdGFuY2VvZiAkRW1iZWRkZWQpIHtcblx0ICAgIHJldHVybiBhcHBlbmRNYXRjaGVyKHAubWF0Y2hlciwgZnVuY3Rpb24gKHYpIHsgcmV0dXJuIGFjYzsgfSk7XG5cdH0gZWxzZSB7XG5cdCAgICByZXR1cm4gcnNlcShKU09OLnN0cmluZ2lmeShwKSwgYWNjKTtcblx0fVxuICAgIH1cbn1cblxuZnVuY3Rpb24gbWF0Y2hQYXR0ZXJuKHYsIHApIHtcbiAgICB2YXIgY2FwdHVyZUNvdW50ID0gMDtcbiAgICB2YXIgcmVzdWx0ID0ge307XG4gICAgdHJ5IHtcblx0d2Fsayh2LCBwKTtcbiAgICB9IGNhdGNoIChlKSB7XG5cdGlmIChlLm1hdGNoUGF0dGVybkZhaWxlZCkgcmV0dXJuIG51bGw7XG5cdHRocm93IGU7XG4gICAgfVxuICAgIHJlc3VsdC5sZW5ndGggPSBjYXB0dXJlQ291bnQ7XG4gICAgcmV0dXJuIHJlc3VsdDtcblxuICAgIGZ1bmN0aW9uIHdhbGsodiwgcCkge1xuXHRpZiAocCA9PT0gdikgcmV0dXJuO1xuXG5cdGlmIChwID09PSBfXykgcmV0dXJuO1xuXG5cdGlmIChBcnJheS5pc0FycmF5KHApICYmIEFycmF5LmlzQXJyYXkodikgJiYgcC5sZW5ndGggPT09IHYubGVuZ3RoKSB7XG5cdCAgICBmb3IgKHZhciBpID0gMDsgaSA8IHAubGVuZ3RoOyBpKyspIHtcblx0XHR3YWxrKHZbaV0sIHBbaV0pO1xuXHQgICAgfVxuXHQgICAgcmV0dXJuO1xuXHR9XG5cblx0aWYgKGlzQ2FwdHVyZShwKSkge1xuXHQgICAgdmFyIHRoaXNDYXB0dXJlID0gY2FwdHVyZUNvdW50Kys7XG5cdCAgICB3YWxrKHYsIGNhcHR1cmVQYXR0ZXJuKHApKTtcblx0ICAgIHJlc3VsdFtjYXB0dXJlTmFtZShwKSB8fCAoJyQnICsgdGhpc0NhcHR1cmUpXSA9IHY7XG5cdCAgICByZXR1cm47XG5cdH1cblxuXHRpZiAocCBpbnN0YW5jZW9mICRFbWJlZGRlZCkge1xuXHQgICAgZGllKFwiJEVtYmVkZGVkIHBhdHRlcm5zIG5vdCBzdXBwb3J0ZWQgaW4gbWF0Y2hQYXR0ZXJuKClcIik7XG5cdH1cblxuXHR0aHJvdyB7bWF0Y2hQYXR0ZXJuRmFpbGVkOiB0cnVlfTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHNoYWxsb3dDb3B5QXJyYXkocykge1xuICAgIHJldHVybiBzLnNsaWNlKCk7XG59XG5cbmZ1bmN0aW9uIHJ1cGRhdGVJbnBsYWNlKHIsIGtleSwgaykge1xuICAgIGlmIChpc19lbXB0eU1hdGNoZXIoaykpIHtcblx0ci5jbGVhcihrZXkpO1xuICAgIH0gZWxzZSB7XG5cdHIuc2V0KGtleSwgayk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBtYXRjaGVyRXF1YWxzKGEsIGIpIHtcbiAgICBpZiAoYSA9PT0gbnVsbCkge1xuXHRyZXR1cm4gKGIgPT09IG51bGwpO1xuICAgIH1cbiAgICBpZiAoYiA9PT0gbnVsbCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKGEgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHRpZiAoIShiIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpKSByZXR1cm4gZmFsc2U7XG5cdGEgPSBhLm1hdGNoZXI7XG5cdGIgPSBiLm1hdGNoZXI7XG4gICAgfSBlbHNlIGlmIChiIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHJldHVybiBmYWxzZTtcblxuICAgIGlmIChhIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0aWYgKCEoYiBpbnN0YW5jZW9mICRTdWNjZXNzKSkgcmV0dXJuIGZhbHNlO1xuXHRyZXR1cm4gdmFsdWVzRXF1YWwoYS52YWx1ZSwgYi52YWx1ZSk7XG4gICAgfVxuICAgIGlmIChiIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHJldHVybiBmYWxzZTtcblxuICAgIGZvciAodmFyIGtleSBpbiBhLmVudHJpZXMpIHtcblx0aWYgKCFiLmhhcyhrZXkpKSByZXR1cm4gZmFsc2U7XG5cdGlmICghbWF0Y2hlckVxdWFscyhhLmVudHJpZXNba2V5XSwgYi5lbnRyaWVzW2tleV0pKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBpc19rZXlPcGVuKGspIHtcbiAgICByZXR1cm4gayA9PT0gU09BO1xufVxuXG5mdW5jdGlvbiBpc19rZXlDbG9zZShrKSB7XG4gICAgcmV0dXJuIGsgPT09IEVPQTtcbn1cblxuZnVuY3Rpb24gaXNfa2V5Tm9ybWFsKGspIHtcbiAgICByZXR1cm4gIShpc19rZXlPcGVuKGspIHx8IGlzX2tleUNsb3NlKGspKTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBFbm91Z2ggb2Ygc2V0cyB0byBnZXQgYnkgd2l0aFxuXG5mdW5jdGlvbiBhcnJheVRvU2V0KHhzKSB7XG4gICAgdmFyIHMgPSB7fTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHhzLmxlbmd0aDsgaSsrKSB7XG5cdHNbSlNPTi5zdHJpbmdpZnkoeHNbaV0pXSA9IHhzW2ldO1xuICAgIH1cbiAgICByZXR1cm4gcztcbn1cblxuZnVuY3Rpb24gc2V0VG9BcnJheShzKSB7XG4gICAgdmFyIHIgPSBbXTtcbiAgICBmb3IgKHZhciBrIGluIHMpIHIucHVzaChzW2tdKTtcbiAgICByZXR1cm4gcjtcbn1cblxuZnVuY3Rpb24gc2V0VW5pb24oczEsIHMyKSB7XG4gICAgdmFyIHMgPSB7fTtcbiAgICBzZXRVbmlvbklucGxhY2UocywgczEpO1xuICAgIHNldFVuaW9uSW5wbGFjZShzLCBzMik7XG4gICAgcmV0dXJuIHM7XG59XG5cbmZ1bmN0aW9uIGlzX2VtcHR5U2V0KHMpIHtcbiAgICBmb3IgKHZhciBrIGluIHMpIHtcblx0aWYgKHMuaGFzT3duUHJvcGVydHkoaykpXG5cdCAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBzZXRTdWJ0cmFjdChzMSwgczIpIHtcbiAgICB2YXIgcyA9IHt9O1xuICAgIGZvciAodmFyIGtleSBpbiBzMSkge1xuXHRpZiAoczEuaGFzT3duUHJvcGVydHkoa2V5KSAmJiAhczIuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuXHQgICAgc1trZXldID0gczFba2V5XTtcblx0fVxuICAgIH1cbiAgICByZXR1cm4gcztcbn1cblxuZnVuY3Rpb24gc2V0SW50ZXJzZWN0KHMxLCBzMikge1xuICAgIHZhciBzID0ge307XG4gICAgZm9yICh2YXIga2V5IGluIHMxKSB7XG5cdGlmIChzMS5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIHMyLmhhc093blByb3BlcnR5KGtleSkpIHtcblx0ICAgIHNba2V5XSA9IHMxW2tleV07XG5cdH1cbiAgICB9XG4gICAgcmV0dXJuIHM7XG59XG5cbmZ1bmN0aW9uIHNldFVuaW9uSW5wbGFjZShhY2MsIHMpIHtcbiAgICBmb3IgKHZhciBrZXkgaW4gcykge1xuXHRpZiAocy5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdCAgICBhY2Nba2V5XSA9IHNba2V5XTtcblx0fVxuICAgIH1cbn1cblxuZnVuY3Rpb24gc2V0RXF1YWwoczEsIHMyKSB7XG4gICAgZm9yICh2YXIga2V5IGluIHMxKSB7XG5cdGlmIChzMS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG5cdCAgICBpZiAoczFba2V5XSAhPT0gczJba2V5XSkgcmV0dXJuIGZhbHNlO1xuXHR9XG4gICAgfVxuICAgIGZvciAodmFyIGtleSBpbiBzMikge1xuXHRpZiAoczIuaGFzT3duUHJvcGVydHkoa2V5KSkge1xuXHQgICAgaWYgKHMxW2tleV0gIT09IHMyW2tleV0pIHJldHVybiBmYWxzZTtcblx0fVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn1cblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbnZhciB1bmlvblN1Y2Nlc3NlcyA9IGZ1bmN0aW9uICh2MSwgdjIpIHtcbiAgICBpZiAodjEgPT09IHRydWUpIHJldHVybiB2MjtcbiAgICBpZiAodjIgPT09IHRydWUpIHJldHVybiB2MTtcbiAgICByZXR1cm4gc2V0VW5pb24odjEsIHYyKTtcbn07XG5cbnZhciBpbnRlcnNlY3RTdWNjZXNzZXMgPSBmdW5jdGlvbiAodjEsIHYyKSB7XG4gICAgcmV0dXJuIHYxO1xufTtcblxudmFyIGVyYXNlUGF0aFN1Y2Nlc3NlcyA9IGZ1bmN0aW9uICh2MSwgdjIpIHtcbiAgICB2YXIgciA9IHNldFN1YnRyYWN0KHYxLCB2Mik7XG4gICAgaWYgKGlzX2VtcHR5U2V0KHIpKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gcjtcbn07XG5cbnZhciBtYXRjaE1hdGNoZXJTdWNjZXNzZXMgPSBmdW5jdGlvbiAodjEsIHYyLCBhY2MpIHtcbiAgICBzZXRVbmlvbklucGxhY2UoYWNjLCB2Mik7XG59O1xuXG52YXIgcHJvamVjdFN1Y2Nlc3MgPSBmdW5jdGlvbiAodikge1xuICAgIHJldHVybiB2O1xufTtcblxudmFyIHZhbHVlc0VxdWFsID0gZnVuY3Rpb24gKGEsIGIpIHtcbiAgICByZXR1cm4gc2V0RXF1YWwoYSwgYik7XG59O1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gZXhwYW5kV2lsZHNlcShyKSB7XG4gICAgcmV0dXJuIHVuaW9uKHJ3aWxkKHJ3aWxkc2VxKHIpKSwgcnNlcShFT0EsIHIpKTtcbn1cblxuZnVuY3Rpb24gdW5pb24obzEsIG8yKSB7XG4gICAgcmV0dXJuIG1lcmdlKG8xLCBvMik7XG5cbiAgICBmdW5jdGlvbiBtZXJnZShvMSwgbzIpIHtcblx0aWYgKGlzX2VtcHR5TWF0Y2hlcihvMSkpIHJldHVybiBvMjtcblx0aWYgKGlzX2VtcHR5TWF0Y2hlcihvMikpIHJldHVybiBvMTtcblx0cmV0dXJuIHdhbGsobzEsIG8yKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3YWxrKHIxLCByMikge1xuXHRpZiAocjEgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHQgICAgaWYgKHIyIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0XHRyZXR1cm4gcndpbGRzZXEod2FsayhyMS5tYXRjaGVyLCByMi5tYXRjaGVyKSk7XG5cdCAgICB9XG5cdCAgICByMSA9IGV4cGFuZFdpbGRzZXEocjEubWF0Y2hlcik7XG5cdH0gZWxzZSBpZiAocjIgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHQgICAgcjIgPSBleHBhbmRXaWxkc2VxKHIyLm1hdGNoZXIpO1xuXHR9XG5cblx0aWYgKHIxIGluc3RhbmNlb2YgJFN1Y2Nlc3MgJiYgcjIgaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuXHQgICAgcmV0dXJuIHJzdWNjZXNzKHVuaW9uU3VjY2Vzc2VzKHIxLnZhbHVlLCByMi52YWx1ZSkpO1xuXHR9XG5cblx0dmFyIHcgPSBtZXJnZShyMS5nZXQoX18pLCByMi5nZXQoX18pKTtcblx0aWYgKGlzX2VtcHR5TWF0Y2hlcih3KSkge1xuXHQgICAgdmFyIHNtYWxsZXIgPSByMS5sZW5ndGggPCByMi5sZW5ndGggPyByMSA6IHIyO1xuXHQgICAgdmFyIGxhcmdlciAgPSByMS5sZW5ndGggPCByMi5sZW5ndGggPyByMiA6IHIxO1xuXHQgICAgdmFyIHRhcmdldCA9IGxhcmdlci5jb3B5KCk7XG5cdCAgICBmb3IgKHZhciBrZXkgaW4gc21hbGxlci5lbnRyaWVzKSB7XG5cdFx0dmFyIGsgPSBtZXJnZShzbWFsbGVyLmdldChrZXkpLCBsYXJnZXIuZ2V0KGtleSkpO1xuXHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCBrKTtcblx0ICAgIH1cblx0ICAgIHJldHVybiB0YXJnZXQuZW1wdHlHdWFyZCgpO1xuXHR9IGVsc2Uge1xuXHQgICAgZnVuY3Rpb24gZXhhbWluZUtleShyQSwga2V5LCByQikge1xuXHRcdGlmICgoa2V5ICE9PSBfXykgJiYgIXRhcmdldC5oYXMoa2V5KSkge1xuXHRcdCAgICB2YXIgayA9IG1lcmdlKHJBLmdldChrZXkpLCByQi5nZXQoa2V5KSk7XG5cdFx0ICAgIGlmIChpc19rZXlPcGVuKGtleSkpIHtcblx0XHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCBtZXJnZShyd2lsZHNlcSh3KSwgaykpO1xuXHRcdCAgICB9IGVsc2UgaWYgKGlzX2tleUNsb3NlKGtleSkpIHtcblx0XHRcdGlmICh3IGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0XHRcdCAgICBydXBkYXRlSW5wbGFjZSh0YXJnZXQsIGtleSwgbWVyZ2Uody5tYXRjaGVyLCBrKSk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0ICAgIHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCBrKTtcblx0XHRcdH1cblx0XHQgICAgfSBlbHNlIHtcblx0XHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCBtZXJnZSh3LCBrKSk7XG5cdFx0ICAgIH1cblx0XHR9XG5cdCAgICB9XG5cdCAgICB2YXIgdGFyZ2V0ID0gcndpbGQodykuY29weSgpO1xuXHQgICAgZm9yICh2YXIga2V5IGluIHIxLmVudHJpZXMpIHsgZXhhbWluZUtleShyMSwga2V5LCByMik7IH1cblx0ICAgIGZvciAodmFyIGtleSBpbiByMi5lbnRyaWVzKSB7IGV4YW1pbmVLZXkocjIsIGtleSwgcjEpOyB9XG5cdCAgICByZXR1cm4gdGFyZ2V0O1xuXHR9XG4gICAgfVxufVxuXG5mdW5jdGlvbiB1bmlvbk4oKSB7XG4gICAgdmFyIGFjYyA9IGVtcHR5TWF0Y2hlcjtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3VtZW50cy5sZW5ndGg7IGkrKykge1xuXHRhY2MgPSB1bmlvbihhY2MsIGFyZ3VtZW50c1tpXSk7XG4gICAgfVxuICAgIHJldHVybiBhY2M7XG59XG5cbmZ1bmN0aW9uIGludGVyc2VjdChvMSwgbzIpIHtcbiAgICBpZiAoaXNfZW1wdHlNYXRjaGVyKG8xKSkgcmV0dXJuIGVtcHR5TWF0Y2hlcjtcbiAgICBpZiAoaXNfZW1wdHlNYXRjaGVyKG8yKSkgcmV0dXJuIGVtcHR5TWF0Y2hlcjtcbiAgICByZXR1cm4gd2FsayhvMSwgbzIpO1xuXG4gICAgZnVuY3Rpb24gd2Fsa0ZsaXBwZWQocjIsIHIxKSB7IHJldHVybiB3YWxrKHIxLCByMik7IH1cblxuICAgIGZ1bmN0aW9uIHdhbGsocjEsIHIyKSB7XG5cdC8vIElOVkFSSUFOVDogcjEgaXMgYSBwYXJ0IG9mIHRoZSBvcmlnaW5hbCBvMSwgYW5kXG5cdC8vIGxpa2V3aXNlIGZvciByMi4gVGhpcyBpcyBzbyB0aGF0IHRoZSBmaXJzdCBhcmcgdG9cblx0Ly8gaW50ZXJzZWN0U3VjY2Vzc2VzIGFsd2F5cyBjb21lcyBmcm9tIHIxLCBhbmQgdGhlIHNlY29uZFxuXHQvLyBmcm9tIHIyLlxuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKHIxKSkgcmV0dXJuIGVtcHR5TWF0Y2hlcjtcblx0aWYgKGlzX2VtcHR5TWF0Y2hlcihyMikpIHJldHVybiBlbXB0eU1hdGNoZXI7XG5cblx0aWYgKHIxIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0ICAgIGlmIChyMiBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG5cdFx0cmV0dXJuIHJ3aWxkc2VxKHdhbGsocjEubWF0Y2hlciwgcjIubWF0Y2hlcikpO1xuXHQgICAgfVxuXHQgICAgcjEgPSBleHBhbmRXaWxkc2VxKHIxLm1hdGNoZXIpO1xuXHR9IGVsc2UgaWYgKHIyIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0ICAgIHIyID0gZXhwYW5kV2lsZHNlcShyMi5tYXRjaGVyKTtcblx0fVxuXG5cdGlmIChyMSBpbnN0YW5jZW9mICRTdWNjZXNzICYmIHIyIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0ICAgIHJldHVybiByc3VjY2VzcyhpbnRlcnNlY3RTdWNjZXNzZXMocjEudmFsdWUsIHIyLnZhbHVlKSk7XG5cdH1cblxuXHR2YXIgdzEgPSByMS5nZXQoX18pO1xuXHR2YXIgdzIgPSByMi5nZXQoX18pO1xuXHR2YXIgdyA9IHdhbGsodzEsIHcyKTtcblxuXHR2YXIgdGFyZ2V0ID0gbmV3ICREaWN0KCk7XG5cblx0ZnVuY3Rpb24gZXhhbWluZUtleShrZXkpIHtcblx0ICAgIGlmICgoa2V5ICE9PSBfXykgJiYgIXRhcmdldC5oYXMoa2V5KSkge1xuXHRcdHZhciBrMSA9IHIxLmdldChrZXkpO1xuXHRcdHZhciBrMiA9IHIyLmdldChrZXkpO1xuXHRcdGlmIChpc19lbXB0eU1hdGNoZXIoazEpKSB7XG5cdFx0ICAgIGlmIChpc19lbXB0eU1hdGNoZXIoazIpKSB7XG5cdFx0XHRydXBkYXRlSW5wbGFjZSh0YXJnZXQsIGtleSwgZW1wdHlNYXRjaGVyKTtcblx0XHQgICAgfSBlbHNlIHtcblx0XHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCB3YWxrV2lsZCh3YWxrLCB3MSwga2V5LCBrMikpO1xuXHRcdCAgICB9XG5cdFx0fSBlbHNlIHtcblx0XHQgICAgaWYgKGlzX2VtcHR5TWF0Y2hlcihrMikpIHtcblx0XHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCB3YWxrV2lsZCh3YWxrRmxpcHBlZCwgdzIsIGtleSwgazEpKTtcblx0XHQgICAgfSBlbHNlIHtcblx0XHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCB3YWxrKGsxLCBrMikpO1xuXHRcdCAgICB9XG5cdFx0fVxuXHQgICAgfVxuXHR9XG5cblx0aWYgKGlzX2VtcHR5TWF0Y2hlcih3MSkpIHtcblx0ICAgIGlmIChpc19lbXB0eU1hdGNoZXIodzIpKSB7XG5cdFx0Zm9yICh2YXIga2V5IGluIChyMS5sZW5ndGggPCByMi5sZW5ndGggPyByMSA6IHIyKS5lbnRyaWVzKSBleGFtaW5lS2V5KGtleSk7XG5cdCAgICB9IGVsc2Uge1xuXHRcdGZvciAodmFyIGtleSBpbiByMS5lbnRyaWVzKSBleGFtaW5lS2V5KGtleSk7XG5cdCAgICB9XG5cdH0gZWxzZSB7XG5cdCAgICBpZiAoaXNfZW1wdHlNYXRjaGVyKHcyKSkge1xuXHRcdGZvciAodmFyIGtleSBpbiByMi5lbnRyaWVzKSBleGFtaW5lS2V5KGtleSk7XG5cdCAgICB9IGVsc2Uge1xuXHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwgX18sIHcpO1xuXHRcdGZvciAodmFyIGtleSBpbiByMS5lbnRyaWVzKSBleGFtaW5lS2V5KGtleSk7XG5cdFx0Zm9yICh2YXIga2V5IGluIHIyLmVudHJpZXMpIGV4YW1pbmVLZXkoa2V5KTtcblx0ICAgIH1cblx0fVxuXHRyZXR1cm4gdGFyZ2V0LmVtcHR5R3VhcmQoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB3YWxrV2lsZCh3YWxrZXIsIHcsIGtleSwgaykge1xuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKHcpKSByZXR1cm4gZW1wdHlNYXRjaGVyO1xuXHRpZiAoaXNfa2V5T3BlbihrZXkpKSByZXR1cm4gd2Fsa2VyKHJ3aWxkc2VxKHcpLCBrKTtcblx0aWYgKGlzX2tleUNsb3NlKGtleSkpIHtcblx0ICAgIGlmICh3IGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHJldHVybiB3YWxrZXIody5tYXRjaGVyLCBrKTtcblx0ICAgIHJldHVybiBlbXB0eU1hdGNoZXI7XG5cdH1cblx0cmV0dXJuIHdhbGtlcih3LCBrKTtcbiAgICB9XG59XG5cbi8vIFJlbW92ZXMgcjIncyBtYXBwaW5ncyBmcm9tIHIxLiBBc3N1bWVzIHIyIGhhcyBwcmV2aW91c2x5IGJlZW5cbi8vIHVuaW9uJ2QgaW50byByMS4gVGhlIGVyYXNlUGF0aFN1Y2Nlc3NlcyBmdW5jdGlvbiBzaG91bGQgcmV0dXJuXG4vLyBudWxsIHRvIHNpZ25hbCBcIm5vIHJlbWFpbmluZyBzdWNjZXNzIHZhbHVlc1wiLlxuZnVuY3Rpb24gZXJhc2VQYXRoKG8xLCBvMikge1xuICAgIHJldHVybiB3YWxrKG8xLCBvMik7XG5cbiAgICBmdW5jdGlvbiB3YWxrKHIxLCByMikge1xuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKHIxKSkge1xuXHQgICAgcmV0dXJuIGVtcHR5TWF0Y2hlcjtcblx0fSBlbHNlIHtcblx0ICAgIGlmIChpc19lbXB0eU1hdGNoZXIocjIpKSB7XG5cdFx0cmV0dXJuIHIxO1xuXHQgICAgfVxuXHR9XG5cblx0aWYgKHIxIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0ICAgIGlmIChyMiBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG5cdFx0cmV0dXJuIHJ3aWxkc2VxKHdhbGsocjEubWF0Y2hlciwgcjIubWF0Y2hlcikpO1xuXHQgICAgfVxuXHQgICAgcjEgPSBleHBhbmRXaWxkc2VxKHIxLm1hdGNoZXIpO1xuXHR9IGVsc2UgaWYgKHIyIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0ICAgIHIyID0gZXhwYW5kV2lsZHNlcShyMi5tYXRjaGVyKTtcblx0fVxuXG5cdGlmIChyMSBpbnN0YW5jZW9mICRTdWNjZXNzICYmIHIyIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0ICAgIHJldHVybiByc3VjY2VzcyhlcmFzZVBhdGhTdWNjZXNzZXMocjEudmFsdWUsIHIyLnZhbHVlKSk7XG5cdH1cblxuXHR2YXIgdzEgPSByMS5nZXQoX18pO1xuXHR2YXIgdzIgPSByMi5nZXQoX18pO1xuXHR2YXIgdyA9IHdhbGsodzEsIHcyKTtcblx0dmFyIHRhcmdldDtcblxuXHRmdW5jdGlvbiBleGFtaW5lS2V5KGtleSkge1xuXHQgICAgaWYgKGtleSAhPT0gX18pIHtcblx0XHR2YXIgazEgPSByMS5nZXQoa2V5KTtcblx0XHR2YXIgazIgPSByMi5nZXQoa2V5KTtcblx0XHR2YXIgdXBkYXRlZEs7XG5cdFx0aWYgKGlzX2VtcHR5TWF0Y2hlcihrMikpIHtcblx0XHQgICAgdXBkYXRlZEsgPSB3YWxrV2lsZChrZXksIGsxLCB3Mik7XG5cdFx0fSBlbHNlIHtcblx0XHQgICAgdXBkYXRlZEsgPSB3YWxrKGsxLCBrMik7XG5cdFx0fVxuXHRcdC8vIEhlcmUgd2UgZW5zdXJlIGEgXCJtaW5pbWFsXCIgcmVtYWluZGVyIGluIGNhc2VzXG5cdFx0Ly8gd2hlcmUgYWZ0ZXIgYW4gZXJhc3VyZSwgYSBwYXJ0aWN1bGFyIGtleSdzXG5cdFx0Ly8gY29udGludWF0aW9uIGlzIHRoZSBzYW1lIGFzIHRoZSB3aWxkY2FyZCdzXG5cdFx0Ly8gY29udGludWF0aW9uLiBUT0RPOiB0aGUgbWF0Y2hlckVxdWFscyBjaGVjayBtYXlcblx0XHQvLyBiZSBleHBlbnNpdmUuIElmIHNvLCBob3cgY2FuIGl0IGJlIG1hZGVcblx0XHQvLyBjaGVhcGVyP1xuXHRcdGlmIChpc19rZXlPcGVuKGtleSkpIHtcblx0XHQgICAgcnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBrZXksXG5cdFx0XHRcdCAgICgodXBkYXRlZEsgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkgJiZcblx0XHRcdFx0ICAgIG1hdGNoZXJFcXVhbHModXBkYXRlZEsubWF0Y2hlciwgdykpXG5cdFx0XHRcdCAgID8gZW1wdHlNYXRjaGVyXG5cdFx0XHRcdCAgIDogdXBkYXRlZEspO1xuXHRcdH0gZWxzZSBpZiAoaXNfa2V5Q2xvc2Uoa2V5KSkge1xuXHRcdCAgICAvLyBXZSB0YWtlIGNhcmUgb2YgdGhpcyBjYXNlIGxhdGVyLCBhZnRlciB0aGVcblx0XHQgICAgLy8gdGFyZ2V0IGlzIGZ1bGx5IGNvbnN0cnVjdGVkL3JlYnVpbHQuXG5cdFx0ICAgIHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCB1cGRhdGVkSyk7XG5cdFx0fSBlbHNlIHtcblx0XHQgICAgcnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBrZXksXG5cdFx0XHRcdCAgIChtYXRjaGVyRXF1YWxzKHVwZGF0ZWRLLCB3KSA/IGVtcHR5TWF0Y2hlciA6IHVwZGF0ZWRLKSk7XG5cdFx0fVxuXHQgICAgfVxuXHR9XG5cblx0aWYgKGlzX2VtcHR5TWF0Y2hlcih3MikpIHtcblx0ICAgIHRhcmdldCA9IHIxLmNvcHkoKTtcblx0ICAgIGZvciAodmFyIGtleSBpbiByMi5lbnRyaWVzKSBleGFtaW5lS2V5KGtleSk7XG5cdH0gZWxzZSB7XG5cdCAgICB0YXJnZXQgPSBuZXcgJERpY3QoKTtcblx0ICAgIHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwgX18sIHcpO1xuXHQgICAgZm9yICh2YXIga2V5IGluIHIxLmVudHJpZXMpIGV4YW1pbmVLZXkoa2V5KTtcblx0ICAgIGZvciAodmFyIGtleSBpbiByMi5lbnRyaWVzKSBleGFtaW5lS2V5KGtleSk7XG5cdH1cblxuXHQvLyBIZXJlLCB0aGUgdGFyZ2V0IGlzIGNvbXBsZXRlLiBJZiBpdCBoYXMgb25seSB0d28ga2V5cyxcblx0Ly8gb25lIHdpbGQgYW5kIG9uZSBpc19rZXlDbG9zZSwgYW5kIHdpbGQncyBjb250aW51YXRpb25cblx0Ly8gaXMgYSAkV2lsZGNhcmRTZXF1ZW5jZSBhbmQgdGhlIG90aGVyIGNvbnRpbnVhdGlvbiBpc1xuXHQvLyBpZGVudGljYWwgdG8gdGhlIHNlcXVlbmNlJ3MgY29udGludWF0aW9uLCB0aGVuIHJlcGxhY2Vcblx0Ly8gdGhlIHdob2xlIHRoaW5nIHdpdGggYSBuZXN0ZWQgJFdpbGRjYXJkU2VxdWVuY2UuXG5cdC8vIChXZSBrbm93IHcgPT09IHRhcmdldC5nZXQoX18pIGZyb20gYmVmb3JlLilcblx0Ly9cblx0Ly8gVE9ETzogSSBzdXNwZWN0IGFjdHVhbGx5IHRoaXMgYXBwbGllcyBldmVuIGlmIHRoZXJlIGFyZVxuXHQvLyBtb3JlIHRoYW4gdHdvIGtleXMsIHNvIGxvbmcgYXMgYWxsIHRoZWlyIGNvbnRpbnVhdGlvbnNcblx0Ly8gYXJlIGlkZW50aWNhbCBhbmQgdGhlcmUncyBhdCBsZWFzdCBvbmUgaXNfa2V5Q2xvc2Vcblx0Ly8gYWxvbmdzaWRlIGEgd2lsZC5cblx0aWYgKHRhcmdldC5sZW5ndGggPT09IDIpIHtcblx0ICAgIHZhciBmaW5hbFcgPSB0YXJnZXQuZ2V0KF9fKTtcblx0ICAgIGlmIChmaW5hbFcgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHRcdGZvciAodmFyIGtleSBpbiB0YXJnZXQuZW50cmllcykge1xuXHRcdCAgICBpZiAoKGtleSAhPT0gX18pICYmIGlzX2tleUNsb3NlKGtleSkpIHtcblx0XHRcdHZhciBrID0gdGFyZ2V0LmdldChrZXkpO1xuXHRcdFx0aWYgKG1hdGNoZXJFcXVhbHMoaywgZmluYWxXLm1hdGNoZXIpKSB7XG5cdFx0XHQgICAgcmV0dXJuIGZpbmFsVztcblx0XHRcdH1cblx0XHQgICAgfVxuXHRcdH1cblx0ICAgIH1cblx0fVxuXG5cdHJldHVybiB0YXJnZXQuZW1wdHlHdWFyZCgpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHdhbGtXaWxkKGtleSwgaywgdykge1xuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKHcpKSByZXR1cm4gaztcblx0aWYgKGlzX2tleU9wZW4oa2V5KSkgcmV0dXJuIHdhbGsoaywgcndpbGRzZXEodykpO1xuXHRpZiAoaXNfa2V5Q2xvc2Uoa2V5KSkge1xuXHQgICAgaWYgKHcgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkgcmV0dXJuIHdhbGsoaywgdy5tYXRjaGVyKTtcblx0ICAgIHJldHVybiBrO1xuXHR9XG5cdHJldHVybiB3YWxrKGssIHcpO1xuICAgIH1cbn1cblxuLy8gUmV0dXJucyBudWxsIG9uIGZhaWxlZCBtYXRjaCwgb3RoZXJ3aXNlIHRoZSBhcHByb3ByaWF0ZSBzdWNjZXNzXG4vLyB2YWx1ZSBjb250YWluZWQgaW4gdGhlIG1hdGNoZXIgci5cbmZ1bmN0aW9uIG1hdGNoVmFsdWUociwgdikge1xuICAgIHZhciBmYWlsdXJlUmVzdWx0ID0gbnVsbDtcblxuICAgIHZhciB2cyA9IFt2XTtcbiAgICB2YXIgc3RhY2sgPSBbW11dO1xuXG4gICAgd2hpbGUgKCFpc19lbXB0eU1hdGNoZXIocikpIHtcblx0aWYgKHIgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHQgICAgaWYgKHN0YWNrLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGZhaWx1cmVSZXN1bHQ7XG5cdCAgICB2cyA9IHN0YWNrLnBvcCgpO1xuXHQgICAgciA9IHIubWF0Y2hlcjtcblx0ICAgIGNvbnRpbnVlO1xuXHR9XG5cblx0aWYgKHIgaW5zdGFuY2VvZiAkU3VjY2Vzcykge1xuXHQgICAgaWYgKHZzLmxlbmd0aCA9PT0gMCAmJiBzdGFjay5sZW5ndGggPT09IDApIHJldHVybiByLnZhbHVlO1xuXHQgICAgcmV0dXJuIGZhaWx1cmVSZXN1bHQ7XG5cdH1cblxuXHRpZiAodnMubGVuZ3RoID09PSAwKSB7XG5cdCAgICBpZiAoc3RhY2subGVuZ3RoID09PSAwKSByZXR1cm4gZmFpbHVyZVJlc3VsdDtcblx0ICAgIHZzID0gc3RhY2sucG9wKCk7XG5cdCAgICByID0gci5nZXQoRU9BKTtcblx0ICAgIGNvbnRpbnVlO1xuXHR9XG5cblx0dmFyIHYgPSB2cy5zaGlmdCgpO1xuXG5cdGlmICh0eXBlb2YgdiA9PT0gJ3N0cmluZycgJiYgdi5zdWJzdHJpbmcoMCwgMikgPT09ICdfXycpIHtcblx0ICAgIGRpZShcIkNhbm5vdCBtYXRjaCBzcGVjaWFsIHN0cmluZyBzdGFydGluZyB3aXRoIF9fXCIpO1xuXHR9XG5cblx0aWYgKEFycmF5LmlzQXJyYXkodikpIHtcblx0ICAgIGlmIChTT0EgaW4gci5lbnRyaWVzKSB7XG5cdFx0ciA9IHIuZ2V0KFNPQSk7XG5cdFx0c3RhY2sucHVzaCh2cyk7XG5cdFx0dnMgPSBzaGFsbG93Q29weUFycmF5KHYpO1xuXHQgICAgfSBlbHNlIHtcblx0XHRyID0gci5nZXQoX18pO1xuXHQgICAgfVxuXHR9IGVsc2Uge1xuXHQgICAgdmFyIGtleTtcblx0ICAgIHRyeSB7XG5cdFx0a2V5ID0gSlNPTi5zdHJpbmdpZnkodik7XG5cdCAgICB9IGNhdGNoIChleG4pIHtcblx0XHQvLyBGb3IgZXhhbXBsZSwgdiBtaWdodCBiZSBjeWNsaWMsIGFzIGluIERPTSBldmVudHMuXG5cdFx0a2V5ID0gbnVsbDtcblx0ICAgIH1cblx0ICAgIGlmIChrZXkgaW4gci5lbnRyaWVzKSB7XG5cdFx0ciA9IHIuZ2V0KGtleSk7XG5cdCAgICB9IGVsc2Uge1xuXHRcdHIgPSByLmdldChfXyk7XG5cdCAgICB9XG5cdH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFpbHVyZVJlc3VsdDtcbn1cblxuLy8gVE9ETzogYmV0dGVyIG5hbWUgZm9yIHRoaXNcbmZ1bmN0aW9uIG1hdGNoTWF0Y2hlcihvMSwgbzIsIHNlZWQpIHtcbiAgICB2YXIgYWNjID0gdHlwZW9mIHNlZWQgPT09ICd1bmRlZmluZWQnID8ge30gOiBzZWVkOyAvLyB3aWxsIGJlIG1vZGlmaWVkIGluIHBsYWNlXG4gICAgd2FsayhvMSwgbzIpO1xuICAgIHJldHVybiBhY2M7XG5cbiAgICBmdW5jdGlvbiB3YWxrRmxpcHBlZChyMiwgcjEpIHsgcmV0dXJuIHdhbGsocjEsIHIyKTsgfVxuXG4gICAgZnVuY3Rpb24gd2FsayhyMSwgcjIpIHtcblx0aWYgKGlzX2VtcHR5TWF0Y2hlcihyMSkgfHwgaXNfZW1wdHlNYXRjaGVyKHIyKSkgcmV0dXJuO1xuXG5cdGlmIChyMSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG5cdCAgICBpZiAocjIgaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHRcdHdhbGsocjEubWF0Y2hlciwgcjIubWF0Y2hlcik7XG5cdFx0cmV0dXJuO1xuXHQgICAgfVxuXHQgICAgcjEgPSBleHBhbmRXaWxkc2VxKHIxLm1hdGNoZXIpO1xuXHR9IGVsc2UgaWYgKHIyIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0ICAgIHIyID0gZXhwYW5kV2lsZHNlcShyMi5tYXRjaGVyKTtcblx0fVxuXG5cdGlmIChyMSBpbnN0YW5jZW9mICRTdWNjZXNzICYmIHIyIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0ICAgIG1hdGNoTWF0Y2hlclN1Y2Nlc3NlcyhyMS52YWx1ZSwgcjIudmFsdWUsIGFjYyk7XG5cdCAgICByZXR1cm47XG5cdH1cblxuXHR2YXIgdzEgPSByMS5nZXQoX18pO1xuXHR2YXIgdzIgPSByMi5nZXQoX18pO1xuXHR3YWxrKHcxLCB3Mik7XG5cblx0ZnVuY3Rpb24gZXhhbWluZUtleShrZXkpIHtcblx0ICAgIGlmIChrZXkgIT09IF9fKSB7XG5cdFx0dmFyIGsxID0gcjEuZ2V0KGtleSk7XG5cdFx0dmFyIGsyID0gcjIuZ2V0KGtleSk7XG5cdFx0aWYgKGlzX2VtcHR5TWF0Y2hlcihrMSkpIHtcblx0XHQgICAgaWYgKGlzX2VtcHR5TWF0Y2hlcihrMikpIHtcblx0XHRcdHJldHVybjtcblx0XHQgICAgfSBlbHNlIHtcblx0XHRcdHdhbGtXaWxkKHdhbGssIHcxLCBrZXksIGsyKTtcblx0XHQgICAgfVxuXHRcdH0gZWxzZSB7XG5cdFx0ICAgIGlmIChpc19lbXB0eU1hdGNoZXIoazIpKSB7XG5cdFx0XHR3YWxrV2lsZCh3YWxrRmxpcHBlZCwgdzIsIGtleSwgazEpO1xuXHRcdCAgICB9IGVsc2Uge1xuXHRcdFx0d2FsayhrMSwgazIpO1xuXHRcdCAgICB9XG5cdFx0fVxuXHQgICAgfVxuXHR9XG5cblx0Ly8gT3B0aW1pemUgc2ltaWxhcmx5IHRvIGludGVyc2VjdCgpLlxuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKHcxKSkge1xuXHQgICAgaWYgKGlzX2VtcHR5TWF0Y2hlcih3MikpIHtcblx0XHRmb3IgKHZhciBrZXkgaW4gKHIxLmxlbmd0aCA8IHIyLmxlbmd0aCA/IHIxIDogcjIpLmVudHJpZXMpIGV4YW1pbmVLZXkoa2V5KTtcblx0ICAgIH0gZWxzZSB7XG5cdFx0Zm9yICh2YXIga2V5IGluIHIxLmVudHJpZXMpIGV4YW1pbmVLZXkoa2V5KTtcblx0ICAgIH1cblx0fSBlbHNlIHtcblx0ICAgIGlmIChpc19lbXB0eU1hdGNoZXIodzIpKSB7XG5cdFx0Zm9yICh2YXIga2V5IGluIHIyLmVudHJpZXMpIGV4YW1pbmVLZXkoa2V5KTtcblx0ICAgIH0gZWxzZSB7XG5cdFx0Zm9yICh2YXIga2V5IGluIHIxLmVudHJpZXMpIGV4YW1pbmVLZXkoa2V5KTtcblx0XHRmb3IgKHZhciBrZXkgaW4gcjIuZW50cmllcykgZXhhbWluZUtleShrZXkpO1xuXHQgICAgfVxuXHR9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gd2Fsa1dpbGQod2Fsa2VyLCB3LCBrZXksIGspIHtcblx0aWYgKGlzX2VtcHR5TWF0Y2hlcih3KSkgcmV0dXJuO1xuXHRpZiAoaXNfa2V5T3BlbihrZXkpKSB7XG5cdCAgICB3YWxrZXIocndpbGRzZXEodyksIGspO1xuXHQgICAgcmV0dXJuO1xuXHR9XG5cdGlmIChpc19rZXlDbG9zZShrZXkpKSB7XG5cdCAgICBpZiAodyBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB3YWxrZXIody5tYXRjaGVyLCBrKTtcblx0ICAgIHJldHVybjtcblx0fVxuXHR3YWxrZXIodywgayk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBhcHBlbmRNYXRjaGVyKG0sIG1UYWlsRm4pIHtcbiAgICByZXR1cm4gd2FsayhtKTtcblxuICAgIGZ1bmN0aW9uIHdhbGsobSkge1xuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKG0pKSByZXR1cm4gZW1wdHlNYXRjaGVyO1xuXHRpZiAobSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSByZXR1cm4gcndpbGRzZXEod2FsayhtLm1hdGNoZXIpKTtcblx0aWYgKG0gaW5zdGFuY2VvZiAkU3VjY2VzcykgZGllKFwiSWxsLWZvcm1lZCBtYXRjaGVyXCIpO1xuXG5cdHZhciB0YXJnZXQgPSBuZXcgJERpY3QoKTtcblx0Zm9yICh2YXIga2V5IGluIG0uZW50cmllcykge1xuXHQgICAgdmFyIGsgPSBtLmdldChrZXkpO1xuXHQgICAgaWYgKGlzX2tleUNsb3NlKGtleSkgJiYgKGsgaW5zdGFuY2VvZiAkU3VjY2VzcykpIHtcblx0XHR0YXJnZXQgPSB1bmlvbih0YXJnZXQsIG1UYWlsRm4oay52YWx1ZSkpO1xuXHQgICAgfSBlbHNlIHtcblx0XHRydXBkYXRlSW5wbGFjZSh0YXJnZXQsIGtleSwgd2FsayhrKSk7XG5cdCAgICB9XG5cdH1cblx0cmV0dXJuIHRhcmdldC5lbXB0eUd1YXJkKCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiByZWxhYmVsKG0sIGYpIHtcbiAgICByZXR1cm4gd2FsayhtKTtcblxuICAgIGZ1bmN0aW9uIHdhbGsobSkge1xuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKG0pKSByZXR1cm4gZW1wdHlNYXRjaGVyO1xuXHRpZiAobSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSByZXR1cm4gcndpbGRzZXEod2FsayhtLm1hdGNoZXIpKTtcblx0aWYgKG0gaW5zdGFuY2VvZiAkU3VjY2VzcykgcmV0dXJuIHJzdWNjZXNzKGYobS52YWx1ZSkpO1xuXG5cdHZhciB0YXJnZXQgPSBuZXcgJERpY3QoKTtcblx0Zm9yICh2YXIga2V5IGluIG0uZW50cmllcykge1xuXHQgICAgcnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBrZXksIHdhbGsobS5nZXQoa2V5KSkpO1xuXHR9XG5cdHJldHVybiB0YXJnZXQuZW1wdHlHdWFyZCgpO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY29tcGlsZVByb2plY3Rpb24oLyogcHJvamVjdGlvbiwgcHJvamVjdGlvbiwgLi4uICovKSB7XG4gICAgdmFyIG5hbWVzID0gW107XG4gICAgdmFyIGFjYyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG5cdHdhbGsoYXJndW1lbnRzW2ldKTtcbiAgICB9XG4gICAgYWNjLnB1c2goRU9BKTtcbiAgICByZXR1cm4ge25hbWVzOiBuYW1lcywgc3BlYzogYWNjfTtcblxuICAgIGZ1bmN0aW9uIHdhbGsocCkge1xuXHRpZiAoaXNDYXB0dXJlKHApKSB7XG5cdCAgICBuYW1lcy5wdXNoKGNhcHR1cmVOYW1lKHApKTtcblx0ICAgIGFjYy5wdXNoKFNPQyk7XG5cdCAgICB3YWxrKGNhcHR1cmVQYXR0ZXJuKHApKTtcblx0ICAgIGFjYy5wdXNoKEVPQyk7XG5cdCAgICByZXR1cm47XG5cdH1cblxuXHRpZiAoQXJyYXkuaXNBcnJheShwKSkge1xuXHQgICAgYWNjLnB1c2goU09BKTtcblx0ICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuXHRcdHdhbGsocFtpXSk7XG5cdCAgICB9XG5cdCAgICBhY2MucHVzaChFT0EpO1xuXHQgICAgcmV0dXJuO1xuXHR9XG5cblx0aWYgKHAgaW5zdGFuY2VvZiAkRW1iZWRkZWQpIHtcblx0ICAgIGRpZShcIkNhbm5vdCBlbWJlZCBtYXRjaGVyIGluIHByb2plY3Rpb25cIik7XG5cdH0gZWxzZSB7XG5cdCAgICBpZiAocCA9PT0gX18pIHtcblx0XHRhY2MucHVzaChwKTtcblx0ICAgIH0gZWxzZSB7XG5cdFx0YWNjLnB1c2goSlNPTi5zdHJpbmdpZnkocCkpO1xuXHQgICAgfVxuXHR9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBwcm9qZWN0aW9uVG9QYXR0ZXJuKHApIHtcbiAgICByZXR1cm4gd2FsayhwKTtcblxuICAgIGZ1bmN0aW9uIHdhbGsocCkge1xuXHRpZiAoaXNDYXB0dXJlKHApKSByZXR1cm4gd2FsayhjYXB0dXJlUGF0dGVybihwKSk7XG5cblx0aWYgKEFycmF5LmlzQXJyYXkocCkpIHtcblx0ICAgIHZhciByZXN1bHQgPSBbXTtcblx0ICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5sZW5ndGg7IGkrKykge1xuXHRcdHJlc3VsdC5wdXNoKHdhbGsocFtpXSkpO1xuXHQgICAgfVxuXHQgICAgcmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdGlmIChwIGluc3RhbmNlb2YgJEVtYmVkZGVkKSB7XG5cdCAgICByZXR1cm4gcC5tYXRjaGVyO1xuXHR9IGVsc2Uge1xuXHQgICAgcmV0dXJuIHA7XG5cdH1cbiAgICB9XG59XG5cbmZ1bmN0aW9uIHByb2plY3QobSwgY29tcGlsZWRQcm9qZWN0aW9uKSB7XG4gICAgdmFyIHNwZWMgPSBjb21waWxlZFByb2plY3Rpb24uc3BlYztcbiAgICByZXR1cm4gd2FsayhmYWxzZSwgbSwgMCk7XG5cbiAgICBmdW5jdGlvbiB3YWxrKGlzQ2FwdHVyaW5nLCBtLCBzcGVjSW5kZXgpIHtcblx0aWYgKHNwZWNJbmRleCA+PSBzcGVjLmxlbmd0aCkge1xuXHQgICAgaWYgKGlzQ2FwdHVyaW5nKSBkaWUoXCJCYWQgc3BlY2lmaWNhdGlvbjogdW5jbG9zZWQgY2FwdHVyZVwiKTtcblx0ICAgIGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0XHRyZXR1cm4gcnNlcShFT0EsIHJzdWNjZXNzKHByb2plY3RTdWNjZXNzKG0udmFsdWUpKSk7XG5cdCAgICB9IGVsc2Uge1xuXHRcdHJldHVybiBlbXB0eU1hdGNoZXI7XG5cdCAgICB9XG5cdH1cblxuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKG0pKSByZXR1cm4gZW1wdHlNYXRjaGVyO1xuXG5cdHZhciBpdGVtID0gc3BlY1tzcGVjSW5kZXhdO1xuXHR2YXIgbmV4dEluZGV4ID0gc3BlY0luZGV4ICsgMTtcblxuXHRpZiAoaXRlbSA9PT0gRU9DKSB7XG5cdCAgICBpZiAoIWlzQ2FwdHVyaW5nKSBkaWUoXCJCYWQgc3BlY2lmaWNhdGlvbjogdW5lcHhlY3RlZCBFT0NcIik7XG5cdCAgICByZXR1cm4gd2FsayhmYWxzZSwgbSwgbmV4dEluZGV4KTtcblx0fVxuXG5cdGlmIChpdGVtID09PSBTT0MpIHtcblx0ICAgIGlmIChpc0NhcHR1cmluZykgZGllKFwiQmFkIHNwZWNpZmljYXRpb246IG5lc3RlZCBjYXB0dXJlXCIpO1xuXHQgICAgcmV0dXJuIHdhbGsodHJ1ZSwgbSwgbmV4dEluZGV4KTtcblx0fVxuXG5cdGlmIChpdGVtID09PSBfXykge1xuXHQgICAgaWYgKG0gaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHRcdGlmIChpc0NhcHR1cmluZykge1xuXHRcdCAgICByZXR1cm4gcndpbGQod2Fsayhpc0NhcHR1cmluZywgbSwgbmV4dEluZGV4KSk7XG5cdFx0fSBlbHNlIHtcblx0XHQgICAgcmV0dXJuIHdhbGsoaXNDYXB0dXJpbmcsIG0sIG5leHRJbmRleCk7XG5cdFx0fVxuXHQgICAgfVxuXG5cdCAgICBpZiAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSB7XG5cdFx0cmV0dXJuIGVtcHR5TWF0Y2hlcjtcblx0ICAgIH1cblxuXHQgICAgdmFyIHRhcmdldDtcblx0ICAgIGlmIChpc0NhcHR1cmluZykge1xuXHRcdHRhcmdldCA9IG5ldyAkRGljdCgpO1xuXHRcdHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwgX18sIHdhbGsoaXNDYXB0dXJpbmcsIG0uZ2V0KF9fKSwgbmV4dEluZGV4KSk7XG5cdFx0Zm9yICh2YXIga2V5IGluIG0uZW50cmllcykge1xuXHRcdCAgICBpZiAoa2V5ICE9PSBfXykge1xuXHRcdFx0dmFyIG1rID0gbS5nZXQoa2V5KTtcblx0XHRcdGlmIChpc19rZXlPcGVuKGtleSkpIHtcblx0XHRcdCAgICBmdW5jdGlvbiBjb250KG1rMikgeyByZXR1cm4gd2Fsayhpc0NhcHR1cmluZywgbWsyLCBuZXh0SW5kZXgpOyB9XG5cdFx0XHQgICAgcnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBrZXksIGNhcHR1cmVOZXN0ZWQobWssIGNvbnQpKTtcblx0XHRcdH0gZWxzZSBpZiAoaXNfa2V5Q2xvc2Uoa2V5KSkge1xuXHRcdFx0ICAgIC8vIGRvIG5vdGhpbmdcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHQgICAgcnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBrZXksIHdhbGsoaXNDYXB0dXJpbmcsIG1rLCBuZXh0SW5kZXgpKTtcblx0XHRcdH1cblx0XHQgICAgfVxuXHRcdH1cblx0ICAgIH0gZWxzZSB7XG5cdFx0dGFyZ2V0ID0gd2Fsayhpc0NhcHR1cmluZywgbS5nZXQoX18pLCBuZXh0SW5kZXgpO1xuXHRcdGZvciAodmFyIGtleSBpbiBtLmVudHJpZXMpIHtcblx0XHQgICAgaWYgKGtleSAhPT0gX18pIHtcblx0XHRcdHZhciBtayA9IG0uZ2V0KGtleSk7XG5cdFx0XHRpZiAoaXNfa2V5T3BlbihrZXkpKSB7XG5cdFx0XHQgICAgZnVuY3Rpb24gY29udChtazIpIHsgcmV0dXJuIHdhbGsoaXNDYXB0dXJpbmcsIG1rMiwgbmV4dEluZGV4KTsgfVxuXHRcdFx0ICAgIHRhcmdldCA9IHVuaW9uKHRhcmdldCwgc2tpcE5lc3RlZChtaywgY29udCkpO1xuXHRcdFx0fSBlbHNlIGlmIChpc19rZXlDbG9zZShrZXkpKSB7XG5cdFx0XHQgICAgLy8gZG8gbm90aGluZ1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdCAgICB0YXJnZXQgPSB1bmlvbih0YXJnZXQsIHdhbGsoaXNDYXB0dXJpbmcsIG1rLCBuZXh0SW5kZXgpKTtcblx0XHRcdH1cblx0XHQgICAgfVxuXHRcdH1cblx0ICAgIH1cblx0ICAgIHJldHVybiB0YXJnZXQ7XG5cdH1cblxuXHR2YXIgcmVzdWx0O1xuXHRpZiAobSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG5cdCAgICBpZiAoaXNfa2V5T3BlbihpdGVtKSkge1xuXHRcdHJlc3VsdCA9IHdhbGsoaXNDYXB0dXJpbmcsIHJ3aWxkc2VxKG0pLCBuZXh0SW5kZXgpO1xuXHQgICAgfSBlbHNlIGlmIChpc19rZXlDbG9zZShpdGVtKSkge1xuXHRcdHJlc3VsdCA9IHdhbGsoaXNDYXB0dXJpbmcsIG0ubWF0Y2hlciwgbmV4dEluZGV4KTtcblx0ICAgIH0gZWxzZSB7XG5cdFx0cmVzdWx0ID0gd2Fsayhpc0NhcHR1cmluZywgbSwgbmV4dEluZGV4KTtcblx0ICAgIH1cblx0fSBlbHNlIGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0ICAgIHJlc3VsdCA9IGVtcHR5TWF0Y2hlcjtcblx0fSBlbHNlIHtcblx0ICAgIGlmIChpc19rZXlPcGVuKGl0ZW0pKSB7XG5cdFx0cmVzdWx0ID0gd2Fsayhpc0NhcHR1cmluZywgcndpbGRzZXEobS5nZXQoX18pKSwgbmV4dEluZGV4KTtcblx0ICAgIH0gZWxzZSBpZiAoaXNfa2V5Q2xvc2UoaXRlbSkpIHtcblx0XHRyZXN1bHQgPSBlbXB0eU1hdGNoZXI7XG5cdCAgICB9IGVsc2Uge1xuXHRcdHJlc3VsdCA9IHdhbGsoaXNDYXB0dXJpbmcsIG0uZ2V0KF9fKSwgbmV4dEluZGV4KTtcblx0ICAgIH1cblx0ICAgIHJlc3VsdCA9IHVuaW9uKHJlc3VsdCwgd2Fsayhpc0NhcHR1cmluZywgbS5nZXQoaXRlbSksIG5leHRJbmRleCkpO1xuXHR9XG5cdGlmIChpc0NhcHR1cmluZykge1xuXHQgICAgcmVzdWx0ID0gcnNlcShpdGVtLCByZXN1bHQpO1xuXHR9XG5cdHJldHVybiByZXN1bHQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2FwdHVyZU5lc3RlZChtLCBjb250KSB7XG5cdGlmIChtIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0ICAgIHJldHVybiByd2lsZHNlcShjb250KG0ubWF0Y2hlcikpO1xuXHR9XG5cblx0aWYgKGlzX2VtcHR5TWF0Y2hlcihtKSB8fCAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSkge1xuXHQgICAgcmV0dXJuIGVtcHR5TWF0Y2hlcjtcblx0fVxuXG5cdHZhciB0YXJnZXQgPSBuZXcgJERpY3QoKTtcblx0cnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBfXywgY2FwdHVyZU5lc3RlZChtLmdldChfXyksIGNvbnQpKTtcblx0Zm9yICh2YXIga2V5IGluIG0uZW50cmllcykge1xuXHQgICAgaWYgKGtleSAhPT0gX18pIHtcblx0XHR2YXIgbWsgPSBtLmdldChrZXkpO1xuXHRcdGlmIChpc19rZXlPcGVuKGtleSkpIHtcblx0XHQgICAgZnVuY3Rpb24gY29udDIobWsyKSB7IHJldHVybiBjYXB0dXJlTmVzdGVkKG1rMiwgY29udCk7IH1cblx0XHQgICAgcnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBrZXksIGNhcHR1cmVOZXN0ZWQobWssIGNvbnQyKSk7XG5cdFx0fSBlbHNlIGlmIChpc19rZXlDbG9zZShrZXkpKSB7XG5cdFx0ICAgIHJ1cGRhdGVJbnBsYWNlKHRhcmdldCwga2V5LCBjb250KG1rKSk7XG5cdFx0fSBlbHNlIHtcblx0XHQgICAgcnVwZGF0ZUlucGxhY2UodGFyZ2V0LCBrZXksIGNhcHR1cmVOZXN0ZWQobWssIGNvbnQpKTtcblx0XHR9XG5cdCAgICB9XG5cdH1cblx0cmV0dXJuIHRhcmdldC5lbXB0eUd1YXJkKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gc2tpcE5lc3RlZChtLCBjb250KSB7XG5cdGlmIChtIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHtcblx0ICAgIHJldHVybiBjb250KG0ubWF0Y2hlcik7XG5cdH1cblxuXHRpZiAoaXNfZW1wdHlNYXRjaGVyKG0pIHx8IChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpKSB7XG5cdCAgICByZXR1cm4gZW1wdHlNYXRjaGVyO1xuXHR9XG5cblx0dmFyIHRhcmdldCA9IHNraXBOZXN0ZWQobS5nZXQoX18pLCBjb250KTtcblx0Zm9yICh2YXIga2V5IGluIG0uZW50cmllcykge1xuXHQgICAgaWYgKGtleSAhPT0gX18pIHtcblx0XHR2YXIgbWsgPSBtLmdldChrZXkpO1xuXHRcdGlmIChpc19rZXlPcGVuKGtleSkpIHtcblx0XHQgICAgZnVuY3Rpb24gY29udDIobWsyKSB7IHJldHVybiBza2lwTmVzdGVkKG1rMiwgY29udCk7IH1cblx0XHQgICAgdGFyZ2V0ID0gdW5pb24odGFyZ2V0LCBza2lwTmVzdGVkKG1rLCBjb250MikpO1xuXHRcdH0gZWxzZSBpZiAoaXNfa2V5Q2xvc2Uoa2V5KSkge1xuXHRcdCAgICB0YXJnZXQgPSB1bmlvbih0YXJnZXQsIGNvbnQobWspKTtcblx0XHR9IGVsc2Uge1xuXHRcdCAgICB0YXJnZXQgPSB1bmlvbih0YXJnZXQsIHNraXBOZXN0ZWQobWssIGNvbnQpKTtcblx0XHR9XG5cdCAgICB9XG5cdH1cblx0cmV0dXJuIHRhcmdldDtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXJLZXlzKG0pIHtcbiAgICBpZiAoaXNfZW1wdHlNYXRjaGVyKG0pKSByZXR1cm4gW107XG4gICAgcmV0dXJuIHdhbGtTZXEobSwgZnVuY3Rpb24gKHZzcywgdnNrKSB7IHJldHVybiB2c3M7IH0pO1xuXG4gICAgZnVuY3Rpb24gd2FsayhtLCBrKSB7XG5cdGlmIChtIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHJldHVybiBudWxsO1xuXHRpZiAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSByZXR1cm4gW107XG5cdGlmIChtLmhhcyhfXykpIHJldHVybiBudWxsO1xuXHR2YXIgYWNjID0gW107XG5cdGZvciAodmFyIGtleSBpbiBtLmVudHJpZXMpIHtcblx0ICAgIHZhciBtayA9IG0uZ2V0KGtleSk7XG5cdCAgICB2YXIgcGllY2U7XG5cdCAgICBpZiAoaXNfa2V5T3BlbihrZXkpKSB7XG5cdFx0ZnVuY3Rpb24gc2VxSyh2c3MsIHZzaykge1xuXHRcdCAgICB2YXIgYWNjID0gW107XG5cdFx0ICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdnNzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR2YXIgdnMgPSB2c3NbaV07XG5cdFx0XHRhY2MgPSBhY2MuY29uY2F0KGsodHJhbnNmb3JtU2Vxcyh2cywga2V5KSwgdnNrKSk7XG5cdFx0ICAgIH1cblx0XHQgICAgcmV0dXJuIGFjYztcblx0XHR9XG5cdFx0cGllY2UgPSB3YWxrU2VxKG1rLCBzZXFLKTtcblx0ICAgIH0gZWxzZSBpZiAoaXNfa2V5Q2xvc2Uoa2V5KSkge1xuXHRcdGRpZShcIm1hdGNoZXJLZXlzOiBpbnRlcm5hbCBlcnJvcjogdW5leHBlY3RlZCBrZXktY2xvc2VcIik7XG5cdCAgICB9IGVsc2Uge1xuXHRcdHBpZWNlID0gayhKU09OLnBhcnNlKGtleSksIG1rKTtcblx0ICAgIH1cblx0ICAgIGlmIChwaWVjZSA9PSBudWxsKSByZXR1cm4gbnVsbDtcblx0ICAgIGFjYyA9IGFjYy5jb25jYXQocGllY2UpO1xuXHR9XG5cdHJldHVybiBhY2M7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gd2Fsa1NlcShtLCBrKSB7XG5cdGlmIChtIGluc3RhbmNlb2YgJFdpbGRjYXJkU2VxdWVuY2UpIHJldHVybiBudWxsO1xuXHRpZiAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSByZXR1cm4gayhbXSwgZW1wdHlNYXRjaGVyKTsgLy8gVE9ETzogPz9cblx0aWYgKG0uaGFzKF9fKSkgcmV0dXJuIG51bGw7XG5cdHZhciBhY2MgPSBbXTtcblx0Zm9yICh2YXIga2V5IGluIG0uZW50cmllcykge1xuXHQgICAgdmFyIG1rID0gbS5nZXQoa2V5KTtcblx0ICAgIHZhciBwaWVjZTtcblx0ICAgIGlmIChpc19rZXlDbG9zZShrZXkpKSB7XG5cdFx0cGllY2UgPSBrKFtbXV0sIG1rKTtcblx0ICAgIH0gZWxzZSB7XG5cdFx0ZnVuY3Rpb24gb3V0ZXJLKHYsIHZrKSB7XG5cdFx0ICAgIHJldHVybiB3YWxrU2VxKHZrLCBpbm5lckspO1xuXHRcdCAgICBmdW5jdGlvbiBpbm5lcksodnNzLCB2c2spIHtcblx0XHRcdHZhciBhY2MgPSBbXTtcblx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwgdnNzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHQgICAgdmFyIHZzID0gc2hhbGxvd0NvcHlBcnJheSh2c3NbaV0pO1xuXHRcdFx0ICAgIHZzLnVuc2hpZnQodik7XG5cdFx0XHQgICAgYWNjLnB1c2godnMpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGsoYWNjLCB2c2spO1xuXHRcdCAgICB9XG5cdFx0fVxuXHRcdHBpZWNlID0gd2Fsayhyc2VxKGtleSwgbWspLCBvdXRlckspO1xuXHQgICAgfVxuXHQgICAgaWYgKHBpZWNlID09IG51bGwpIHJldHVybiBudWxsO1xuXHQgICAgYWNjID0gYWNjLmNvbmNhdChwaWVjZSk7XG5cdH1cblx0cmV0dXJuIGFjYztcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0cmFuc2Zvcm1TZXFzKHZzLCBvcGVuZXIpIHtcblx0aWYgKG9wZW5lciA9PT0gU09BKSByZXR1cm4gdnM7XG5cdGRpZShcIkludGVybmFsIGVycm9yOiB1bmtub3duIG9wZW5lciBcIiArIG9wZW5lcik7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBtYXRjaGVyS2V5c1RvT2JqZWN0cyhtYXRjaGVyS2V5c1Jlc3VsdCwgY29tcGlsZWRQcm9qZWN0aW9uKSB7XG4gICAgaWYgKG1hdGNoZXJLZXlzUmVzdWx0ID09PSBudWxsKSByZXR1cm4gbnVsbDtcbiAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXRjaGVyS2V5c1Jlc3VsdC5sZW5ndGg7IGkrKykge1xuXHR2YXIgZSA9IG1hdGNoZXJLZXlzUmVzdWx0W2ldO1xuXHR2YXIgZCA9IHt9O1xuXHRmb3IgKHZhciBqID0gMDsgaiA8IGUubGVuZ3RoOyBqKyspIHtcblx0ICAgIGRbY29tcGlsZWRQcm9qZWN0aW9uLm5hbWVzW2pdIHx8ICgnJCcgKyBqKV0gPSBlW2pdO1xuXHR9XG5cdHJlc3VsdC5wdXNoKGQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBwcm9qZWN0T2JqZWN0cyhtLCBjb21waWxlZFByb2plY3Rpb24pIHtcbiAgICByZXR1cm4gbWF0Y2hlcktleXNUb09iamVjdHMobWF0Y2hlcktleXMocHJvamVjdChtLCBjb21waWxlZFByb2plY3Rpb24pKSwgY29tcGlsZWRQcm9qZWN0aW9uKTtcbn1cblxuZnVuY3Rpb24gcHJldHR5TWF0Y2hlcihtLCBpbml0aWFsSW5kZW50KSB7XG4gICAgdmFyIGFjYyA9IFtdO1xuICAgIHdhbGsoaW5pdGlhbEluZGVudCB8fCAwLCBtKTtcbiAgICByZXR1cm4gYWNjLmpvaW4oJycpO1xuXG4gICAgZnVuY3Rpb24gd2FsayhpLCBtKSB7XG5cdGlmIChpc19lbXB0eU1hdGNoZXIobSkpIHtcblx0ICAgIGFjYy5wdXNoKFwiOjo6IG5vIGZ1cnRoZXIgbWF0Y2hlcyBwb3NzaWJsZVwiKTtcblx0ICAgIHJldHVybjtcblx0fVxuXHRpZiAobSBpbnN0YW5jZW9mICRXaWxkY2FyZFNlcXVlbmNlKSB7XG5cdCAgICBhY2MucHVzaChcIi4uLj5cIik7XG5cdCAgICB3YWxrKGkgKyA0LCBtLm1hdGNoZXIpO1xuXHQgICAgcmV0dXJuO1xuXHR9XG5cdGlmIChtIGluc3RhbmNlb2YgJFN1Y2Nlc3MpIHtcblx0ICAgIHZhciB2cyA9IEpTT04uc3RyaW5naWZ5KHR5cGVvZiBtLnZhbHVlID09PSAnb2JqZWN0J1xuXHRcdFx0XHQgICAgPyBzZXRUb0FycmF5KG0udmFsdWUpXG5cdFx0XHRcdCAgICA6IG0udmFsdWUpO1xuXHQgICAgYWNjLnB1c2goXCJ7XCIgKyB2cyArIFwifVwiKTtcblx0ICAgIHJldHVybjtcblx0fVxuXG5cdGlmIChtLmxlbmd0aCA9PT0gMCkge1xuXHQgICAgYWNjLnB1c2goXCIgOjo6IGVtcHR5IGhhc2ghXCIpO1xuXHQgICAgcmV0dXJuO1xuXHR9XG5cblx0dmFyIG5lZWRTZXAgPSBmYWxzZTtcblx0dmFyIGtleXMgPSBtLnNvcnRlZEtleXMoKTtcblx0Zm9yICh2YXIga2V5aSA9IDA7IGtleWkgPCBrZXlzLmxlbmd0aDsga2V5aSsrKSB7XG5cdCAgICB2YXIga2V5ID0ga2V5c1trZXlpXTtcblx0ICAgIHZhciBrID0gbS5lbnRyaWVzW2tleV07XG5cdCAgICBpZiAobmVlZFNlcCkge1xuXHRcdGFjYy5wdXNoKFwiXFxuXCIpO1xuXHRcdGFjYy5wdXNoKGluZGVudFN0cihpKSk7XG5cdCAgICB9IGVsc2Uge1xuXHRcdG5lZWRTZXAgPSB0cnVlO1xuXHQgICAgfVxuXHQgICAgYWNjLnB1c2goXCIgXCIpO1xuXHQgICAgaWYgKGtleSA9PT0gX18pIGtleSA9ICfimIUnO1xuXHQgICAgaWYgKGtleSA9PT0gU09BKSBrZXkgPSAnPCc7XG5cdCAgICBpZiAoa2V5ID09PSBFT0EpIGtleSA9ICc+Jztcblx0ICAgIGFjYy5wdXNoKGtleSk7XG5cdCAgICB3YWxrKGkgKyBrZXkubGVuZ3RoICsgMSwgayk7XG5cdH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpbmRlbnRTdHIoaSkge1xuXHRyZXR1cm4gbmV3IEFycmF5KGkgKyAxKS5qb2luKCcgJyk7IC8vIGV3d1xuICAgIH1cbn1cblxuZnVuY3Rpb24gc2VyaWFsaXplTWF0Y2hlcihtLCBzZXJpYWxpemVTdWNjZXNzKSB7XG4gICAgcmV0dXJuIHdhbGsobSk7XG4gICAgZnVuY3Rpb24gd2FsayhtKSB7XG5cdGlmIChpc19lbXB0eU1hdGNoZXIobSkpIHJldHVybiBbXTtcblx0aWYgKG0gaW5zdGFuY2VvZiAkV2lsZGNhcmRTZXF1ZW5jZSkge1xuXHQgICAgcmV0dXJuIFtcIi4uLilcIiwgd2FsayhtLm1hdGNoZXIpXTtcblx0fVxuXHRpZiAobSBpbnN0YW5jZW9mICRTdWNjZXNzKSB7XG5cdCAgICByZXR1cm4gW1wiXCIsIHNlcmlhbGl6ZVN1Y2Nlc3MobS52YWx1ZSldO1xuXHR9XG5cdHZhciBhY2MgPSBbXTtcblx0Zm9yICh2YXIga2V5IGluIG0uZW50cmllcykge1xuXHQgICAgdmFyIGsgPSBtLmVudHJpZXNba2V5XTtcblx0ICAgIGlmIChrZXkgPT09IF9fKSBrZXkgPSBbXCJfX1wiXTtcblx0ICAgIGVsc2UgaWYgKGtleSA9PT0gU09BKSBrZXkgPSBbXCIoXCJdO1xuXHQgICAgZWxzZSBpZiAoa2V5ID09PSBFT0EpIGtleSA9IFtcIilcIl07XG5cdCAgICBlbHNlIGtleSA9IEpTT04ucGFyc2Uoa2V5KTtcblx0ICAgIGFjYy5wdXNoKFtrZXksIHdhbGsoayldKTtcblx0fVxuXHRyZXR1cm4gYWNjO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gZGVzZXJpYWxpemVNYXRjaGVyKHIsIGRlc2VyaWFsaXplU3VjY2Vzcykge1xuICAgIHJldHVybiB3YWxrKHIpO1xuICAgIGZ1bmN0aW9uIHdhbGsocikge1xuXHRpZiAoci5sZW5ndGggPT09IDApIHJldHVybiBlbXB0eU1hdGNoZXI7XG5cdGlmIChyWzBdID09PSBcIi4uLilcIikgcmV0dXJuIHJ3aWxkc2VxKHdhbGsoclsxXSkpO1xuXHRpZiAoclswXSA9PT0gXCJcIikgcmV0dXJuIHJzdWNjZXNzKGRlc2VyaWFsaXplU3VjY2VzcyhyWzFdKSk7XG5cdHZhciBhY2MgPSBuZXcgJERpY3QoKTtcblx0Zm9yICh2YXIgaSA9IDA7IGkgPCByLmxlbmd0aDsgaSsrKSB7XG5cdCAgICB2YXIgcmtleSA9IHJbaV1bMF07XG5cdCAgICB2YXIgcmsgPSByW2ldWzFdO1xuXHQgICAgdmFyIGtleTtcblx0ICAgIGlmIChBcnJheS5pc0FycmF5KHJrZXkpKSB7XG5cdFx0c3dpdGNoIChya2V5WzBdKSB7XG5cdFx0Y2FzZSBcIl9fXCI6IGtleSA9IF9fOyBicmVhaztcblx0XHRjYXNlIFwiKFwiOiBrZXkgPSBTT0E7IGJyZWFrO1xuXHRcdGNhc2UgXCIpXCI6IGtleSA9IEVPQTsgYnJlYWs7XG5cdFx0ZGVmYXVsdDogZGllKFwiSW52YWxpZCBzZXJpYWxpemVkIHNwZWNpYWwga2V5OiBcIiArIHJrZXlbMF0pO1xuXHRcdH1cblx0ICAgIH0gZWxzZSB7XG5cdFx0a2V5ID0gSlNPTi5zdHJpbmdpZnkocmtleSk7XG5cdCAgICB9XG5cdCAgICBydXBkYXRlSW5wbGFjZShhY2MsIGtleSwgd2FsayhyaykpO1xuXHR9XG5cdHJldHVybiBhY2M7XG4gICAgfVxufVxuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vIEdlc3RhbHRzLlxuLy8gVE9ETzogc3VwcG9ydCBJbmZpbml0eSBhcyBhIGxldmVsIG51bWJlclxuXG5mdW5jdGlvbiBHZXN0YWx0TGV2ZWwoc3VicywgYWR2cykge1xuICAgIHRoaXMuc3Vic2NyaXB0aW9ucyA9IHN1YnM7XG4gICAgdGhpcy5hZHZlcnRpc2VtZW50cyA9IGFkdnM7XG59XG5cbkdlc3RhbHRMZXZlbC5wcm90b3R5cGUuaXNFbXB0eSA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gaXNfZW1wdHlNYXRjaGVyKHRoaXMuc3Vic2NyaXB0aW9ucykgJiYgaXNfZW1wdHlNYXRjaGVyKHRoaXMuYWR2ZXJ0aXNlbWVudHMpO1xufTtcblxuR2VzdGFsdExldmVsLnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgICByZXR1cm4gbWF0Y2hlckVxdWFscyh0aGlzLnN1YnNjcmlwdGlvbnMsIG90aGVyLnN1YnNjcmlwdGlvbnMpXG5cdCYmIG1hdGNoZXJFcXVhbHModGhpcy5hZHZlcnRpc2VtZW50cywgb3RoZXIuYWR2ZXJ0aXNlbWVudHMpO1xufTtcblxuR2VzdGFsdExldmVsLnByb3RvdHlwZS5wcmV0dHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIGFjYyA9IFtdO1xuICAgIGlmICghaXNfZW1wdHlNYXRjaGVyKHRoaXMuc3Vic2NyaXB0aW9ucykpIHtcblx0YWNjLnB1c2goXCIgIC0gc3ViczpcIik7XG5cdGFjYy5wdXNoKHByZXR0eU1hdGNoZXIodGhpcy5zdWJzY3JpcHRpb25zLCA5KSk7XG5cdGFjYy5wdXNoKFwiXFxuXCIpO1xuICAgIH1cbiAgICBpZiAoIWlzX2VtcHR5TWF0Y2hlcih0aGlzLmFkdmVydGlzZW1lbnRzKSkge1xuXHRhY2MucHVzaChcIiAgLSBhZHZzOlwiKTtcblx0YWNjLnB1c2gocHJldHR5TWF0Y2hlcih0aGlzLmFkdmVydGlzZW1lbnRzLCA5KSk7XG5cdGFjYy5wdXNoKFwiXFxuXCIpO1xuICAgIH1cbiAgICByZXR1cm4gYWNjLmpvaW4oJycpO1xufTtcblxuZnVuY3Rpb24gc3RyYWlnaHRHZXN0YWx0TGV2ZWxPcChvcCkge1xuICAgIHJldHVybiBmdW5jdGlvbiAocDEsIHAyKSB7XG5cdHJldHVybiBuZXcgR2VzdGFsdExldmVsKG9wKHAxLnN1YnNjcmlwdGlvbnMsIHAyLnN1YnNjcmlwdGlvbnMpLFxuXHRcdFx0XHRvcChwMS5hZHZlcnRpc2VtZW50cywgcDIuYWR2ZXJ0aXNlbWVudHMpKTtcbiAgICB9O1xufTtcblxudmFyIGVtcHR5TGV2ZWwgPSBuZXcgR2VzdGFsdExldmVsKGVtcHR5TWF0Y2hlciwgZW1wdHlNYXRjaGVyKTtcbnZhciBlbXB0eU1ldGFMZXZlbCA9IFtdO1xuXG5mdW5jdGlvbiBHZXN0YWx0KG1ldGFMZXZlbHMpIHtcbiAgICB0aGlzLm1ldGFMZXZlbHMgPSBtZXRhTGV2ZWxzO1xufVxuXG5HZXN0YWx0LnByb3RvdHlwZS5nZXRNZXRhTGV2ZWwgPSBmdW5jdGlvbiAobikge1xuICAgIHJldHVybiB0aGlzLm1ldGFMZXZlbHNbbl0gfHwgZW1wdHlNZXRhTGV2ZWw7XG59O1xuXG5HZXN0YWx0LnByb3RvdHlwZS5nZXRMZXZlbCA9IGZ1bmN0aW9uIChtZXRhTGV2ZWwsIGxldmVsKSB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0TWV0YUxldmVsKG1ldGFMZXZlbClbbGV2ZWxdIHx8IGVtcHR5TGV2ZWw7XG59O1xuXG5HZXN0YWx0LnByb3RvdHlwZS5tZXRhTGV2ZWxDb3VudCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIHRoaXMubWV0YUxldmVscy5sZW5ndGg7IH07XG5HZXN0YWx0LnByb3RvdHlwZS5sZXZlbENvdW50ID0gZnVuY3Rpb24gKG4pIHsgcmV0dXJuIHRoaXMuZ2V0TWV0YUxldmVsKG4pLmxlbmd0aDsgfTtcblxuR2VzdGFsdC5wcm90b3R5cGUubWF0Y2hWYWx1ZSA9IGZ1bmN0aW9uIChib2R5LCBtZXRhTGV2ZWwsIGlzRmVlZGJhY2spIHtcbiAgICB2YXIgbGV2ZWxzID0gdGhpcy5nZXRNZXRhTGV2ZWwobWV0YUxldmVsKTtcbiAgICB2YXIgcGlkcyA9IHt9O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGV2ZWxzLmxlbmd0aDsgaSsrKSB7XG5cdHZhciBtYXRjaGVyID0gKGlzRmVlZGJhY2sgPyBsZXZlbHNbaV0uYWR2ZXJ0aXNlbWVudHMgOiBsZXZlbHNbaV0uc3Vic2NyaXB0aW9ucyk7XG5cdHNldFVuaW9uSW5wbGFjZShwaWRzLCBtYXRjaFZhbHVlKG1hdGNoZXIsIGJvZHkpKTtcbiAgICB9XG4gICAgcmV0dXJuIHNldFRvQXJyYXkocGlkcyk7XG59O1xuXG5HZXN0YWx0LnByb3RvdHlwZS5wcm9qZWN0ID0gZnVuY3Rpb24gKHNwZWMsIGdldEFkdmVydGlzZW1lbnRzLCBtZXRhTGV2ZWwsIGxldmVsKSB7XG4gICAgdmFyIGwgPSB0aGlzLmdldExldmVsKG1ldGFMZXZlbCB8IDAsIGxldmVsIHwgMCk7XG4gICAgdmFyIG1hdGNoZXIgPSAoZ2V0QWR2ZXJ0aXNlbWVudHMgPyBsLmFkdmVydGlzZW1lbnRzIDogbC5zdWJzY3JpcHRpb25zKTtcbiAgICByZXR1cm4gcHJvamVjdChtYXRjaGVyLCBzcGVjKTtcbn07XG5cbkdlc3RhbHQucHJvdG90eXBlLmRyb3AgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG1scyA9IHNoYWxsb3dDb3B5QXJyYXkodGhpcy5tZXRhTGV2ZWxzKTtcbiAgICBtbHMuc2hpZnQoKTtcbiAgICByZXR1cm4gbmV3IEdlc3RhbHQobWxzKTtcbn07XG5cbkdlc3RhbHQucHJvdG90eXBlLmxpZnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG1scyA9IHNoYWxsb3dDb3B5QXJyYXkodGhpcy5tZXRhTGV2ZWxzKTtcbiAgICBtbHMudW5zaGlmdChlbXB0eU1ldGFMZXZlbCk7XG4gICAgcmV0dXJuIG5ldyBHZXN0YWx0KG1scyk7XG59O1xuXG5HZXN0YWx0LnByb3RvdHlwZS5lcXVhbHMgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgICBpZiAodGhpcy5tZXRhTGV2ZWxzLmxlbmd0aCAhPT0gb3RoZXIubWV0YUxldmVscy5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubWV0YUxldmVscy5sZW5ndGg7IGkrKykge1xuXHR2YXIgbHMxID0gdGhpcy5tZXRhTGV2ZWxzW2ldO1xuXHR2YXIgbHMyID0gb3RoZXIubWV0YUxldmVsc1tpXTtcblx0aWYgKGxzMS5sZW5ndGggIT09IGxzMi5sZW5ndGgpIHJldHVybiBmYWxzZTtcblx0Zm9yICh2YXIgaiA9IDA7IGogPCBsczEubGVuZ3RoOyBqKyspIHtcblx0ICAgIHZhciBwMSA9IGxzMVtqXTtcblx0ICAgIHZhciBwMiA9IGxzMltqXTtcblx0ICAgIGlmICghcDEuZXF1YWxzKHAyKSkgcmV0dXJuIGZhbHNlO1xuXHR9XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xufTtcblxuZnVuY3Rpb24gc2ltcGxlR2VzdGFsdChpc0FkdiwgcGF0LCBtZXRhTGV2ZWwsIGxldmVsKSB7XG4gICAgbWV0YUxldmVsID0gbWV0YUxldmVsIHx8IDA7XG4gICAgbGV2ZWwgPSBsZXZlbCB8fCAwO1xuICAgIHZhciBtYXRjaGVyID0gY29tcGlsZVBhdHRlcm4odHJ1ZSwgcGF0KTtcbiAgICB2YXIgbCA9IG5ldyBHZXN0YWx0TGV2ZWwoaXNBZHYgPyBlbXB0eU1hdGNoZXIgOiBtYXRjaGVyLFxuXHRcdFx0ICAgICBpc0FkdiA/IG1hdGNoZXIgOiBlbXB0eU1hdGNoZXIpO1xuICAgIHZhciBsZXZlbHMgPSBbbF07XG4gICAgd2hpbGUgKGxldmVsLS0pIHsgbGV2ZWxzLnVuc2hpZnQoZW1wdHlMZXZlbCk7IH1cbiAgICB2YXIgbWV0YUxldmVscyA9IFtsZXZlbHNdO1xuICAgIHdoaWxlIChtZXRhTGV2ZWwtLSkgeyBtZXRhTGV2ZWxzLnVuc2hpZnQoZW1wdHlNZXRhTGV2ZWwpOyB9XG4gICAgcmV0dXJuIG5ldyBHZXN0YWx0KG1ldGFMZXZlbHMpO1xufVxuXG52YXIgZW1wdHlHZXN0YWx0ID0gbmV3IEdlc3RhbHQoW10pO1xuXG4vLyBOb3QgcXVpdGUgd2hhdCBpdCBzYXlzIG9uIHRoZSB0aW4gLSB0aGUgdHJ1ZSBmdWxsR2VzdGFsdFxuLy8gd291bGRuJ3QgYmUgcGFyYW1ldGVyaXplZCBvbiB0aGUgbnVtYmVyIG9mIGxldmVscyBhbmRcbi8vIG1ldGFsZXZlbHMsIGJ1dCBpbnN0ZWFkIHdvdWxkIGJlIGZ1bGwgYXQgKmFsbCogbGV2ZWxzIGFuZFxuLy8gbWV0YWxldmVscy4gT3VyIHJlcHJlc2VudGF0aW9uIGxlYWtzIHRocm91Z2ggaW50byB0aGUgaW50ZXJmYWNlXG4vLyBoZXJlIDotL1xuZnVuY3Rpb24gZnVsbEdlc3RhbHQobk1ldGFsZXZlbHMsIG5MZXZlbHMpIHtcbiAgICB2YXIgbWF0Y2hlciA9IGNvbXBpbGVQYXR0ZXJuKHRydWUsIF9fKTtcbiAgICB2YXIgbCA9IG5ldyBHZXN0YWx0TGV2ZWwobWF0Y2hlciwgbWF0Y2hlcik7XG4gICAgdmFyIGxldmVscyA9IFtdO1xuICAgIHdoaWxlIChuTGV2ZWxzLS0pIHsgbGV2ZWxzLnB1c2gobCk7IH1cbiAgICB2YXIgbWV0YUxldmVscyA9IFtdO1xuICAgIHdoaWxlIChuTWV0YWxldmVscy0tKSB7IG1ldGFMZXZlbHMucHVzaChsZXZlbHMpOyB9XG4gICAgcmV0dXJuIG5ldyBHZXN0YWx0KG1ldGFMZXZlbHMpO1xufVxuXG5HZXN0YWx0LnByb3RvdHlwZS5pc0VtcHR5ID0gZnVuY3Rpb24gKCkge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tZXRhTGV2ZWxzLmxlbmd0aDsgaSsrKSB7XG5cdHZhciBsZXZlbHMgPSB0aGlzLm1ldGFMZXZlbHNbaV07XG5cdGZvciAodmFyIGogPSAwOyBqIDwgbGV2ZWxzLmxlbmd0aDsgaisrKSB7XG5cdCAgICBpZiAoIWxldmVsc1tqXS5pc0VtcHR5KCkpIHJldHVybiBmYWxzZTtcblx0fVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbn07XG5cbmZ1bmN0aW9uIG1heWJlUHVzaExldmVsKGxldmVscywgaSwgbGV2ZWwpIHtcbiAgICBpZiAoIWxldmVsLmlzRW1wdHkoKSkge1xuXHR3aGlsZSAobGV2ZWxzLmxlbmd0aCA8IGkpIGxldmVscy5wdXNoKGVtcHR5TGV2ZWwpO1xuXHRsZXZlbHMucHVzaChsZXZlbCk7XG4gICAgfVxufVxuXG5mdW5jdGlvbiBtYXliZVB1c2hNZXRhTGV2ZWwobWV0YUxldmVscywgaSwgbWV0YUxldmVsKSB7XG4gICAgaWYgKG1ldGFMZXZlbC5sZW5ndGggPiAwKSB7XG5cdHdoaWxlIChtZXRhTGV2ZWxzLmxlbmd0aCA8IGkpIG1ldGFMZXZlbHMucHVzaChlbXB0eU1ldGFMZXZlbCk7XG5cdG1ldGFMZXZlbHMucHVzaChtZXRhTGV2ZWwpO1xuICAgIH1cbn1cblxuR2VzdGFsdC5wcm90b3R5cGUubWFwWmlwID0gZnVuY3Rpb24gKG90aGVyLCBsZW5ndGhDb21iaW5lciwgZikge1xuICAgIHZhciBtZXRhTGV2ZWxzID0gW107XG4gICAgdmFyIG1sczEgPSB0aGlzLm1ldGFMZXZlbHM7XG4gICAgdmFyIG1sczIgPSBvdGhlci5tZXRhTGV2ZWxzO1xuICAgIHZhciBubSA9IGxlbmd0aENvbWJpbmVyKG1sczEubGVuZ3RoLCBtbHMyLmxlbmd0aCk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBubTsgaSsrKSB7XG5cdHZhciBsZXZlbHMgPSBbXTtcblx0dmFyIGxzMSA9IG1sczFbaV0gfHwgZW1wdHlNZXRhTGV2ZWw7XG5cdHZhciBsczIgPSBtbHMyW2ldIHx8IGVtcHR5TWV0YUxldmVsO1xuXHR2YXIgbmwgPSBsZW5ndGhDb21iaW5lcihsczEubGVuZ3RoLCBsczIubGVuZ3RoKTtcblx0Zm9yICh2YXIgaiA9IDA7IGogPCBubDsgaisrKSB7XG5cdCAgICB2YXIgcDEgPSBsczFbal0gfHwgZW1wdHlMZXZlbDtcblx0ICAgIHZhciBwMiA9IGxzMltqXSB8fCBlbXB0eUxldmVsO1xuXHQgICAgdmFyIHAgPSBmKHAxLCBwMik7XG5cdCAgICBtYXliZVB1c2hMZXZlbChsZXZlbHMsIGosIHApO1xuXHR9XG5cdG1heWJlUHVzaE1ldGFMZXZlbChtZXRhTGV2ZWxzLCBpLCBsZXZlbHMpO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEdlc3RhbHQobWV0YUxldmVscyk7XG59O1xuXG5HZXN0YWx0LnByb3RvdHlwZS51bmlvbjEgPSBmdW5jdGlvbiAob3RoZXIpIHtcbiAgICByZXR1cm4gdGhpcy5tYXBaaXAob3RoZXIsIE1hdGgubWF4LCBzdHJhaWdodEdlc3RhbHRMZXZlbE9wKHVuaW9uKSk7XG59O1xuXG5mdW5jdGlvbiBnZXN0YWx0VW5pb24oZ3MpIHtcbiAgICBpZiAoZ3MubGVuZ3RoID09PSAwKSByZXR1cm4gZW1wdHlHZXN0YWx0O1xuICAgIHZhciBhY2MgPSBnc1swXTtcbiAgICBmb3IgKHZhciBpID0gMTsgaSA8IGdzLmxlbmd0aDsgaSsrKSB7XG5cdGFjYyA9IGFjYy51bmlvbjEoZ3NbaV0pO1xuICAgIH1cbiAgICByZXR1cm4gYWNjO1xufVxuXG5HZXN0YWx0LnByb3RvdHlwZS51bmlvbiA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA+IDAgPyB0aGlzLnVuaW9uMShnZXN0YWx0VW5pb24oYXJndW1lbnRzKSkgOiB0aGlzO1xufTtcblxuLy8gQWNjdW11bGF0ZXMgbWF0Y2hlcnMgZnJvbSBoaWdoZXItbnVtYmVyZWQgbGV2ZWxzIGludG9cbi8vIGxvd2VyLW51bWJlcmVkIGxldmVscy5cbmZ1bmN0aW9uIHRlbGVzY29wZUxldmVscyhsZXZlbHMpIHtcbiAgICB2YXIgcmVzdWx0ID0gc2hhbGxvd0NvcHlBcnJheShsZXZlbHMpO1xuICAgIGZvciAodmFyIGkgPSByZXN1bHQubGVuZ3RoIC0gMjsgaSA+PSAwOyBpLS0pIHtcblx0cmVzdWx0W2ldID1cblx0ICAgIG5ldyBHZXN0YWx0TGV2ZWwodW5pb24ocmVzdWx0W2ldLnN1YnNjcmlwdGlvbnMsIHJlc3VsdFtpKzFdLnN1YnNjcmlwdGlvbnMpLFxuXHRcdFx0ICAgICB1bmlvbihyZXN1bHRbaV0uYWR2ZXJ0aXNlbWVudHMsIHJlc3VsdFtpKzFdLmFkdmVydGlzZW1lbnRzKSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59O1xuXG5HZXN0YWx0LnByb3RvdHlwZS50ZWxlc2NvcGVkID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBtbHMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMubWV0YUxldmVscy5sZW5ndGg7IGkrKykge1xuXHRtbHMucHVzaCh0ZWxlc2NvcGVMZXZlbHModGhpcy5tZXRhTGV2ZWxzW2ldKSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgR2VzdGFsdChtbHMpO1xufTtcblxuR2VzdGFsdC5wcm90b3R5cGUuZmlsdGVyID0gZnVuY3Rpb24gKHBlcnNwZWN0aXZlKSB7XG4gICAgdmFyIG1ldGFMZXZlbHMgPSBbXTtcbiAgICB2YXIgbWxzMSA9IHRoaXMubWV0YUxldmVscztcbiAgICB2YXIgbWxzMiA9IHBlcnNwZWN0aXZlLm1ldGFMZXZlbHM7XG4gICAgdmFyIG5tID0gTWF0aC5taW4obWxzMS5sZW5ndGgsIG1sczIubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5tOyBpKyspIHtcblx0dmFyIGxldmVscyA9IFtdO1xuXHR2YXIgbHMxID0gbWxzMVtpXSB8fCBlbXB0eU1ldGFMZXZlbDtcblx0dmFyIGxzMiA9IG1sczJbaV0gfHwgZW1wdHlNZXRhTGV2ZWw7XG5cdHZhciBubCA9IE1hdGgubWluKGxzMS5sZW5ndGgsIGxzMi5sZW5ndGggLSAxKTtcblx0Zm9yICh2YXIgaiA9IDA7IGogPCBubDsgaisrKSB7XG5cdCAgICB2YXIgcDEgPSBsczFbal0gfHwgZW1wdHlMZXZlbDtcblx0ICAgIHZhciBzdWJzID0gZW1wdHlNYXRjaGVyO1xuXHQgICAgdmFyIGFkdnMgPSBlbXB0eU1hdGNoZXI7XG5cdCAgICBmb3IgKHZhciBrID0gaiArIDE7IGsgPCBsczIubGVuZ3RoOyBrKyspIHtcblx0XHR2YXIgcDIgPSBsczJba10gfHwgZW1wdHlMZXZlbDtcblx0XHRzdWJzID0gdW5pb24oc3VicywgaW50ZXJzZWN0KHAxLnN1YnNjcmlwdGlvbnMsIHAyLmFkdmVydGlzZW1lbnRzKSk7XG5cdFx0YWR2cyA9IHVuaW9uKGFkdnMsIGludGVyc2VjdChwMS5hZHZlcnRpc2VtZW50cywgcDIuc3Vic2NyaXB0aW9ucykpO1xuXHQgICAgfVxuXHQgICAgbWF5YmVQdXNoTGV2ZWwobGV2ZWxzLCBqLCBuZXcgR2VzdGFsdExldmVsKHN1YnMsIGFkdnMpKTtcblx0fVxuXHRtYXliZVB1c2hNZXRhTGV2ZWwobWV0YUxldmVscywgaSwgbGV2ZWxzKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBHZXN0YWx0KG1ldGFMZXZlbHMpO1xufTtcblxuR2VzdGFsdC5wcm90b3R5cGUubWF0Y2ggPSBmdW5jdGlvbiAocGVyc3BlY3RpdmUpIHtcbiAgICB2YXIgcGlkcyA9IHt9O1xuICAgIHZhciBubSA9IE1hdGgubWluKHRoaXMubWV0YUxldmVscy5sZW5ndGgsIHBlcnNwZWN0aXZlLm1ldGFMZXZlbHMubGVuZ3RoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5tOyBpKyspIHtcblx0dmFyIGxzMSA9IHRoaXMubWV0YUxldmVsc1tpXSB8fCBlbXB0eU1ldGFMZXZlbDtcblx0dmFyIGxzMiA9IHBlcnNwZWN0aXZlLm1ldGFMZXZlbHNbaV0gfHwgZW1wdHlNZXRhTGV2ZWw7XG5cdHZhciBubCA9IE1hdGgubWluKGxzMS5sZW5ndGgsIGxzMi5sZW5ndGggLSAxKTtcblx0Zm9yICh2YXIgaiA9IDA7IGogPCBubDsgaisrKSB7XG5cdCAgICB2YXIgcDEgPSBsczFbal0gfHwgZW1wdHlMZXZlbDtcblx0ICAgIGZvciAodmFyIGsgPSBqICsgMTsgayA8IGxzMi5sZW5ndGg7IGsrKykge1xuXHRcdHZhciBwMiA9IGxzMltrXSB8fCBlbXB0eUxldmVsO1xuXHRcdG1hdGNoTWF0Y2hlcihwMS5zdWJzY3JpcHRpb25zLCBwMi5hZHZlcnRpc2VtZW50cywgcGlkcyk7XG5cdFx0bWF0Y2hNYXRjaGVyKHAxLmFkdmVydGlzZW1lbnRzLCBwMi5zdWJzY3JpcHRpb25zLCBwaWRzKTtcblx0ICAgIH1cblx0fVxuICAgIH1cbiAgICByZXR1cm4gc2V0VG9BcnJheShwaWRzKTtcbn07XG5cbkdlc3RhbHQucHJvdG90eXBlLmVyYXNlUGF0aCA9IGZ1bmN0aW9uIChwYXRoKSB7XG4gICAgcmV0dXJuIHRoaXMubWFwWmlwKHBhdGgsIE1hdGgubWF4LCBzdHJhaWdodEdlc3RhbHRMZXZlbE9wKGVyYXNlUGF0aCkpO1xufTtcblxuZnVuY3Rpb24gbWFwTGV2ZWxzKGlucHV0TWV0YUxldmVscywgZiwgZW1wdHlDaGVjaywgaW5wdXRFbXB0eUxldmVsLCBvdXRwdXRFbXB0eUxldmVsKSB7XG4gICAgdmFyIG91dHB1dE1ldGFMZXZlbHMgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGlucHV0TWV0YUxldmVscy5sZW5ndGg7IGkrKykge1xuXHR2YXIgbHMgPSBpbnB1dE1ldGFMZXZlbHNbaV07XG5cdHZhciBsZXZlbHMgPSBbXTtcblx0Zm9yICh2YXIgaiA9IDA7IGogPCBscy5sZW5ndGg7IGorKykge1xuXHQgICAgdmFyIHAgPSBmKGxzW2pdIHx8IGlucHV0RW1wdHlMZXZlbCwgaSwgaik7XG5cdCAgICBpZiAoIWVtcHR5Q2hlY2socCwgaSwgaikpIHtcblx0XHR3aGlsZSAobGV2ZWxzLmxlbmd0aCA8IGopIGxldmVscy5wdXNoKG91dHB1dEVtcHR5TGV2ZWwpO1xuXHRcdGxldmVscy5wdXNoKHApO1xuXHQgICAgfVxuXHR9XG5cdGlmIChsZXZlbHMubGVuZ3RoID4gMCkge1xuXHQgICAgd2hpbGUgKG91dHB1dE1ldGFMZXZlbHMubGVuZ3RoIDwgaSkgb3V0cHV0TWV0YUxldmVscy5wdXNoKGVtcHR5TWV0YUxldmVsKTtcblx0ICAgIG91dHB1dE1ldGFMZXZlbHMucHVzaChsZXZlbHMpO1xuXHR9XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXRNZXRhTGV2ZWxzO1xufTtcblxuR2VzdGFsdC5wcm90b3R5cGUudHJhbnNmb3JtID0gZnVuY3Rpb24gKGYpIHtcbiAgICByZXR1cm4gbmV3IEdlc3RhbHQobWFwTGV2ZWxzKHRoaXMubWV0YUxldmVscywgZnVuY3Rpb24gKHAsIG1sLCBsKSB7XG5cdHJldHVybiBuZXcgR2VzdGFsdExldmVsKGYocC5zdWJzY3JpcHRpb25zLCBtbCwgbCwgZmFsc2UpLFxuXHRcdFx0XHRmKHAuYWR2ZXJ0aXNlbWVudHMsIG1sLCBsLCB0cnVlKSk7XG4gICAgfSwgZnVuY3Rpb24gKHApIHtcblx0cmV0dXJuIHAuaXNFbXB0eSgpO1xuICAgIH0sIGVtcHR5TGV2ZWwsIGVtcHR5TGV2ZWwpKTtcbn07XG5cbkdlc3RhbHQucHJvdG90eXBlLnN0cmlwTGFiZWwgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtKGZ1bmN0aW9uIChtKSB7IHJldHVybiByZWxhYmVsKG0sIGZ1bmN0aW9uICh2KSB7IHJldHVybiB0cnVlOyB9KTsgfSk7XG59O1xuXG5HZXN0YWx0LnByb3RvdHlwZS5sYWJlbCA9IGZ1bmN0aW9uIChwaWQpIHtcbiAgICB2YXIgcGlkcyA9IGFycmF5VG9TZXQoW3BpZF0pO1xuICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybShmdW5jdGlvbiAobSkgeyByZXR1cm4gcmVsYWJlbChtLCBmdW5jdGlvbiAodikgeyByZXR1cm4gcGlkczsgfSk7IH0pO1xufTtcblxuR2VzdGFsdC5wcm90b3R5cGUucHJldHR5ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBhY2MgPSBbXTtcbiAgICBpZiAodGhpcy5pc0VtcHR5KCkpIHtcblx0YWNjLnB1c2goXCJFTVBUWSBHRVNUQUxUXFxuXCIpO1xuICAgIH0gZWxzZSB7XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5tZXRhTGV2ZWxzLmxlbmd0aDsgaSsrKSB7XG5cdCAgICB2YXIgbHMgPSB0aGlzLm1ldGFMZXZlbHNbaV07XG5cdCAgICBmb3IgKHZhciBqID0gMDsgaiA8IGxzLmxlbmd0aDsgaisrKSB7XG5cdFx0dmFyIHAgPSBsc1tqXTtcblx0XHRpZiAoIXAuaXNFbXB0eSgpKSB7XG5cdFx0ICAgIGFjYy5wdXNoKFwiR0VTVEFMVCBtZXRhbGV2ZWwgXCIgKyBpICsgXCIgbGV2ZWwgXCIgKyBqICsgXCI6XFxuXCIpO1xuXHRcdCAgICBhY2MucHVzaChwLnByZXR0eSgpKTtcblx0XHR9XG5cdCAgICB9XG5cdH1cbiAgICB9XG4gICAgcmV0dXJuIGFjYy5qb2luKCcnKTtcbn07XG5cbkdlc3RhbHQucHJvdG90eXBlLnNlcmlhbGl6ZSA9IGZ1bmN0aW9uIChzZXJpYWxpemVTdWNjZXNzKSB7XG4gICAgaWYgKHR5cGVvZiBzZXJpYWxpemVTdWNjZXNzID09PSAndW5kZWZpbmVkJykge1xuXHRzZXJpYWxpemVTdWNjZXNzID0gZnVuY3Rpb24gKHYpIHsgcmV0dXJuIHYgPT09IHRydWUgPyB0cnVlIDogc2V0VG9BcnJheSh2KTsgfTtcbiAgICB9XG4gICAgcmV0dXJuIFtcImdlc3RhbHRcIiwgbWFwTGV2ZWxzKHRoaXMubWV0YUxldmVscywgZnVuY3Rpb24gKHApIHtcblx0cmV0dXJuIFtzZXJpYWxpemVNYXRjaGVyKHAuc3Vic2NyaXB0aW9ucywgc2VyaWFsaXplU3VjY2VzcyksXG5cdFx0c2VyaWFsaXplTWF0Y2hlcihwLmFkdmVydGlzZW1lbnRzLCBzZXJpYWxpemVTdWNjZXNzKV07XG4gICAgfSwgZnVuY3Rpb24gKHByKSB7XG5cdHJldHVybiBwci5sZW5ndGggPT09IDIgJiYgcHJbMF0ubGVuZ3RoID09PSAwICYmIHByWzFdLmxlbmd0aCA9PT0gMDtcbiAgICB9LCBlbXB0eUxldmVsLCBbW10sW11dKV07XG59O1xuXG5mdW5jdGlvbiBkZXNlcmlhbGl6ZUdlc3RhbHQociwgZGVzZXJpYWxpemVTdWNjZXNzKSB7XG4gICAgaWYgKHR5cGVvZiBkZXNlcmlhbGl6ZVN1Y2Nlc3MgPT09ICd1bmRlZmluZWQnKSB7XG5cdGRlc2VyaWFsaXplU3VjY2VzcyA9IGZ1bmN0aW9uICh2KSB7IHJldHVybiB2ID09PSB0cnVlID8gdHJ1ZSA6IGFycmF5VG9TZXQodik7IH07XG4gICAgfVxuICAgIGlmIChyWzBdICE9PSBcImdlc3RhbHRcIikgZGllKFwiSW52YWxpZCBnZXN0YWx0IHNlcmlhbGl6YXRpb246IFwiICsgcik7XG4gICAgcmV0dXJuIG5ldyBHZXN0YWx0KG1hcExldmVscyhyWzFdLCBmdW5jdGlvbiAocHIpIHtcblx0cmV0dXJuIG5ldyBHZXN0YWx0TGV2ZWwoZGVzZXJpYWxpemVNYXRjaGVyKHByWzBdLCBkZXNlcmlhbGl6ZVN1Y2Nlc3MpLFxuXHRcdFx0XHRkZXNlcmlhbGl6ZU1hdGNoZXIocHJbMV0sIGRlc2VyaWFsaXplU3VjY2VzcykpO1xuICAgIH0sIGZ1bmN0aW9uIChwKSB7XG5cdHJldHVybiBwLmlzRW1wdHkoKTtcbiAgICB9LCBbW10sW11dLCBlbXB0eUxldmVsKSk7XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy5fXyA9IF9fO1xubW9kdWxlLmV4cG9ydHMuYXJyYXlUb1NldCA9IGFycmF5VG9TZXQ7XG5tb2R1bGUuZXhwb3J0cy5zZXRUb0FycmF5ID0gc2V0VG9BcnJheTtcbm1vZHVsZS5leHBvcnRzLnNldFVuaW9uID0gc2V0VW5pb247XG5tb2R1bGUuZXhwb3J0cy5zZXRTdWJ0cmFjdCA9IHNldFN1YnRyYWN0O1xubW9kdWxlLmV4cG9ydHMuc2V0SW50ZXJzZWN0ID0gc2V0SW50ZXJzZWN0O1xubW9kdWxlLmV4cG9ydHMuc2V0RXF1YWwgPSBzZXRFcXVhbDtcbm1vZHVsZS5leHBvcnRzLmlzX2VtcHR5U2V0ID0gaXNfZW1wdHlTZXQ7XG5tb2R1bGUuZXhwb3J0cy4kQ2FwdHVyZSA9ICRDYXB0dXJlO1xubW9kdWxlLmV4cG9ydHMuXyQgPSBfJDtcbm1vZHVsZS5leHBvcnRzLmlzX2VtcHR5TWF0Y2hlciA9IGlzX2VtcHR5TWF0Y2hlcjtcbm1vZHVsZS5leHBvcnRzLmVtcHR5TWF0Y2hlciA9IGVtcHR5TWF0Y2hlcjtcbm1vZHVsZS5leHBvcnRzLmVtYmVkZGVkTWF0Y2hlciA9IGVtYmVkZGVkTWF0Y2hlcjtcbm1vZHVsZS5leHBvcnRzLmNvbXBpbGVQYXR0ZXJuID0gY29tcGlsZVBhdHRlcm47XG5tb2R1bGUuZXhwb3J0cy5tYXRjaFBhdHRlcm4gPSBtYXRjaFBhdHRlcm47XG5tb2R1bGUuZXhwb3J0cy51bmlvbiA9IHVuaW9uTjtcbm1vZHVsZS5leHBvcnRzLmludGVyc2VjdCA9IGludGVyc2VjdDtcbm1vZHVsZS5leHBvcnRzLmVyYXNlUGF0aCA9IGVyYXNlUGF0aDtcbm1vZHVsZS5leHBvcnRzLm1hdGNoVmFsdWUgPSBtYXRjaFZhbHVlO1xubW9kdWxlLmV4cG9ydHMubWF0Y2hNYXRjaGVyID0gbWF0Y2hNYXRjaGVyO1xubW9kdWxlLmV4cG9ydHMuYXBwZW5kTWF0Y2hlciA9IGFwcGVuZE1hdGNoZXI7XG5tb2R1bGUuZXhwb3J0cy5yZWxhYmVsID0gcmVsYWJlbDtcbm1vZHVsZS5leHBvcnRzLmNvbXBpbGVQcm9qZWN0aW9uID0gY29tcGlsZVByb2plY3Rpb247XG5tb2R1bGUuZXhwb3J0cy5wcm9qZWN0aW9uVG9QYXR0ZXJuID0gcHJvamVjdGlvblRvUGF0dGVybjtcbm1vZHVsZS5leHBvcnRzLnByb2plY3QgPSBwcm9qZWN0O1xubW9kdWxlLmV4cG9ydHMubWF0Y2hlcktleXMgPSBtYXRjaGVyS2V5cztcbm1vZHVsZS5leHBvcnRzLm1hdGNoZXJLZXlzVG9PYmplY3RzID0gbWF0Y2hlcktleXNUb09iamVjdHM7XG5tb2R1bGUuZXhwb3J0cy5wcm9qZWN0T2JqZWN0cyA9IHByb2plY3RPYmplY3RzO1xubW9kdWxlLmV4cG9ydHMubWF0Y2hlckVxdWFscyA9IG1hdGNoZXJFcXVhbHM7XG5tb2R1bGUuZXhwb3J0cy5wcmV0dHlNYXRjaGVyID0gcHJldHR5TWF0Y2hlcjtcbm1vZHVsZS5leHBvcnRzLnNlcmlhbGl6ZU1hdGNoZXIgPSBzZXJpYWxpemVNYXRjaGVyO1xubW9kdWxlLmV4cG9ydHMuZGVzZXJpYWxpemVNYXRjaGVyID0gZGVzZXJpYWxpemVNYXRjaGVyO1xuXG5tb2R1bGUuZXhwb3J0cy5HZXN0YWx0TGV2ZWwgPSBHZXN0YWx0TGV2ZWw7XG5tb2R1bGUuZXhwb3J0cy5HZXN0YWx0ID0gR2VzdGFsdDtcbm1vZHVsZS5leHBvcnRzLnNpbXBsZUdlc3RhbHQgPSBzaW1wbGVHZXN0YWx0O1xubW9kdWxlLmV4cG9ydHMuZW1wdHlHZXN0YWx0ID0gZW1wdHlHZXN0YWx0O1xubW9kdWxlLmV4cG9ydHMuZnVsbEdlc3RhbHQgPSBmdWxsR2VzdGFsdDtcbm1vZHVsZS5leHBvcnRzLmdlc3RhbHRVbmlvbiA9IGdlc3RhbHRVbmlvbjtcbm1vZHVsZS5leHBvcnRzLmRlc2VyaWFsaXplR2VzdGFsdCA9IGRlc2VyaWFsaXplR2VzdGFsdDtcbiIsInZhciBNaW5pbWFydCA9IHJlcXVpcmUoXCIuL21pbmltYXJ0LmpzXCIpO1xudmFyIFJvdXRlID0gTWluaW1hcnQuUm91dGU7XG52YXIgV29ybGQgPSBNaW5pbWFydC5Xb3JsZDtcbnZhciBzdWIgPSBNaW5pbWFydC5zdWI7XG52YXIgcHViID0gTWluaW1hcnQucHViO1xudmFyIF9fID0gTWluaW1hcnQuX187XG5cbmZ1bmN0aW9uIHNwYXduUm91dGluZ1RhYmxlV2lkZ2V0KHNlbGVjdG9yLCBmcmFnbWVudENsYXNzLCBkb21XcmFwLCBvYnNlcnZhdGlvbkxldmVsKSB7XG4gICAgb2JzZXJ2YXRpb25MZXZlbCA9IG9ic2VydmF0aW9uTGV2ZWwgfHwgMTA7XG4gICAgLy8gXiBhcmJpdHJhcnk6IHNob3VsZCBiZSBJbmZpbml0eSwgd2hlbiByb3V0ZS5qcyBzdXBwb3J0cyBpdC4gVE9ET1xuICAgIGRvbVdyYXAgPSBkb21XcmFwIHx8IE1pbmltYXJ0LkRPTS5kZWZhdWx0V3JhcEZ1bmN0aW9uO1xuXG4gICAgV29ybGQuc3Bhd24oe1xuXHRib290OiBmdW5jdGlvbiAoKSB7IHRoaXMudXBkYXRlU3RhdGUoKTsgfSxcblxuXHRzdGF0ZTogUm91dGUuZW1wdHlHZXN0YWx0LnNlcmlhbGl6ZSgpLFxuXHRuZXh0U3RhdGU6IFJvdXRlLmVtcHR5R2VzdGFsdC5zZXJpYWxpemUoKSxcblx0dGltZXI6IGZhbHNlLFxuXG5cdGxvY2FsR2VzdGFsdDogKHN1YiggICAgICAgZG9tV3JhcChzZWxlY3RvciwgZnJhZ21lbnRDbGFzcywgX18pLCAwLCAyKVxuXHRcdCAgICAgICAudW5pb24ocHViKGRvbVdyYXAoc2VsZWN0b3IsIGZyYWdtZW50Q2xhc3MsIF9fKSwgMCwgMikpXG5cdFx0ICAgICAgIC50ZWxlc2NvcGVkKCkpLFxuXG5cdGRpZ2VzdEdlc3RhbHQ6IGZ1bmN0aW9uIChnKSB7XG5cdCAgICByZXR1cm4gZy5zdHJpcExhYmVsKCkuZXJhc2VQYXRoKHRoaXMubG9jYWxHZXN0YWx0KS5zZXJpYWxpemUoKTtcblx0fSxcblxuXHR1cGRhdGVTdGF0ZTogZnVuY3Rpb24gKCkge1xuXHQgICAgdmFyIGVsdHMgPSBbXCJwcmVcIiwgUm91dGUuZGVzZXJpYWxpemVHZXN0YWx0KHRoaXMuc3RhdGUpLnByZXR0eSgpXTtcblx0ICAgIFdvcmxkLnVwZGF0ZVJvdXRlcyhbc3ViKF9fLCAwLCBvYnNlcnZhdGlvbkxldmVsKSxcblx0XHRcdFx0cHViKF9fLCAwLCBvYnNlcnZhdGlvbkxldmVsKSxcblx0XHRcdFx0cHViKGRvbVdyYXAoc2VsZWN0b3IsIGZyYWdtZW50Q2xhc3MsIGVsdHMpKV0pO1xuXHR9LFxuXG5cdGhhbmRsZUV2ZW50OiBmdW5jdGlvbiAoZSkge1xuXHQgICAgdmFyIHNlbGYgPSB0aGlzO1xuXHQgICAgaWYgKGUudHlwZSA9PT0gXCJyb3V0ZXNcIikge1xuXHRcdHNlbGYubmV4dFN0YXRlID0gc2VsZi5kaWdlc3RHZXN0YWx0KGUuZ2VzdGFsdCk7XG5cdFx0aWYgKHNlbGYudGltZXIpIHtcblx0XHQgICAgY2xlYXJUaW1lb3V0KHNlbGYudGltZXIpO1xuXHRcdCAgICBzZWxmLnRpbWVyID0gZmFsc2U7XG5cdFx0fVxuXHRcdHNlbGYudGltZXIgPSBzZXRUaW1lb3V0KFdvcmxkLndyYXAoZnVuY3Rpb24gKCkge1xuXHRcdCAgICBpZiAoSlNPTi5zdHJpbmdpZnkoc2VsZi5uZXh0U3RhdGUpICE9PSBKU09OLnN0cmluZ2lmeShzZWxmLnN0YXRlKSkge1xuXHRcdFx0c2VsZi5zdGF0ZSA9IHNlbGYubmV4dFN0YXRlO1xuXHRcdFx0c2VsZi51cGRhdGVTdGF0ZSgpO1xuXHRcdCAgICB9XG5cdFx0ICAgIHNlbGYudGltZXIgPSBmYWxzZTtcblx0XHR9KSwgNTApO1xuXHQgICAgfVxuXHR9XG4gICAgfSk7XG5cbn1cblxubW9kdWxlLmV4cG9ydHMuc3Bhd25Sb3V0aW5nVGFibGVXaWRnZXQgPSBzcGF3blJvdXRpbmdUYWJsZVdpZGdldDtcbiIsIi8vIEdlbmVyaWMgU3B5XG52YXIgTWluaW1hcnQgPSByZXF1aXJlKFwiLi9taW5pbWFydC5qc1wiKTtcbnZhciBXb3JsZCA9IE1pbmltYXJ0LldvcmxkO1xudmFyIHN1YiA9IE1pbmltYXJ0LnN1YjtcbnZhciBwdWIgPSBNaW5pbWFydC5wdWI7XG52YXIgX18gPSBNaW5pbWFydC5fXztcblxuZnVuY3Rpb24gU3B5KGxhYmVsLCB1c2VKc29uLCBvYnNlcnZhdGlvbkxldmVsKSB7XG4gICAgdGhpcy5sYWJlbCA9IGxhYmVsIHx8IFwiU1BZXCI7XG4gICAgdGhpcy5vYnNlcnZhdGlvbkxldmVsID0gb2JzZXJ2YXRpb25MZXZlbCB8fCAxMDsgLy8gYXJiaXRyYXJ5LiBTaG91bGQgYmUgSW5maW5pdHkuIFRPRE9cbiAgICB0aGlzLnVzZUpzb24gPSB1c2VKc29uO1xufVxuXG5TcHkucHJvdG90eXBlLmJvb3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgV29ybGQudXBkYXRlUm91dGVzKFtzdWIoX18sIDAsIHRoaXMub2JzZXJ2YXRpb25MZXZlbCksIHB1YihfXywgMCwgdGhpcy5vYnNlcnZhdGlvbkxldmVsKV0pO1xufTtcblxuU3B5LnByb3RvdHlwZS5oYW5kbGVFdmVudCA9IGZ1bmN0aW9uIChlKSB7XG4gICAgc3dpdGNoIChlLnR5cGUpIHtcbiAgICBjYXNlIFwicm91dGVzXCI6XG5cdGNvbnNvbGUubG9nKHRoaXMubGFiZWwsIFwicm91dGVzXCIsIGUuZ2VzdGFsdC5wcmV0dHkoKSk7XG5cdGJyZWFrO1xuICAgIGNhc2UgXCJtZXNzYWdlXCI6XG5cdHZhciBtZXNzYWdlUmVwcjtcblx0dHJ5IHtcblx0ICAgIG1lc3NhZ2VSZXByID0gdGhpcy51c2VKc29uID8gSlNPTi5zdHJpbmdpZnkoZS5tZXNzYWdlKSA6IGUubWVzc2FnZTtcblx0fSBjYXRjaCAoZXhuKSB7XG5cdCAgICBtZXNzYWdlUmVwciA9IGUubWVzc2FnZTtcblx0fVxuXHRjb25zb2xlLmxvZyh0aGlzLmxhYmVsLCBcIm1lc3NhZ2VcIiwgbWVzc2FnZVJlcHIsIGUubWV0YUxldmVsLCBlLmlzRmVlZGJhY2spO1xuXHRicmVhaztcbiAgICBkZWZhdWx0OlxuXHRjb25zb2xlLmxvZyh0aGlzLmxhYmVsLCBcInVua25vd25cIiwgZSk7XG5cdGJyZWFrO1xuICAgIH1cbn07XG5cbm1vZHVsZS5leHBvcnRzLlNweSA9IFNweTtcbiIsIi8vIE1pbmltYWwgalF1ZXJ5aXNoIHV0aWxpdGllcy4gUmVpbXBsZW1lbnRlZCBiZWNhdXNlIGpRdWVyeSBuZWVkc1xuLy8gd2luZG93IHRvIGV4aXN0LCBhbmQgd2Ugd2FudCB0byBydW4gaW4gV2ViIFdvcmtlciBjb250ZXh0IGFzIHdlbGwuXG5cbmZ1bmN0aW9uIGV4dGVuZCh3aGF0LCBfd2l0aCkge1xuICBmb3IgKHZhciBwcm9wIGluIF93aXRoKSB7XG4gICAgaWYgKF93aXRoLmhhc093blByb3BlcnR5KHByb3ApKSB7XG4gICAgICB3aGF0W3Byb3BdID0gX3dpdGhbcHJvcF07XG4gICAgfVxuICB9XG4gIHJldHVybiB3aGF0O1xufVxuXG5tb2R1bGUuZXhwb3J0cy5leHRlbmQgPSBleHRlbmQ7XG4iLCIvLyBXYWtlIGRldGVjdG9yIC0gbm90aWNlcyB3aGVuIHNvbWV0aGluZyAoc3VjaCBhc1xuLy8gc3VzcGVuc2lvbi9zbGVlcGluZyEpIGhhcyBjYXVzZWQgcGVyaW9kaWMgYWN0aXZpdGllcyB0byBiZVxuLy8gaW50ZXJydXB0ZWQsIGFuZCB3YXJucyBvdGhlcnMgYWJvdXQgaXRcbi8vIEluc3BpcmVkIGJ5IGh0dHA6Ly9ibG9nLmFsZXhtYWNjYXcuY29tL2phdmFzY3JpcHQtd2FrZS1ldmVudFxudmFyIE1pbmltYXJ0ID0gcmVxdWlyZShcIi4vbWluaW1hcnQuanNcIik7XG52YXIgV29ybGQgPSBNaW5pbWFydC5Xb3JsZDtcbnZhciBzdWIgPSBNaW5pbWFydC5zdWI7XG52YXIgcHViID0gTWluaW1hcnQucHViO1xudmFyIF9fID0gTWluaW1hcnQuX187XG5cbmZ1bmN0aW9uIFdha2VEZXRlY3RvcihwZXJpb2QpIHtcbiAgICB0aGlzLm1lc3NhZ2UgPSBcIndha2VcIjtcbiAgICB0aGlzLnBlcmlvZCA9IHBlcmlvZCB8fCAxMDAwMDtcbiAgICB0aGlzLm1vc3RSZWNlbnRUcmlnZ2VyID0gKyhuZXcgRGF0ZSgpKTtcbiAgICB0aGlzLnRpbWVySWQgPSBudWxsO1xufVxuXG5XYWtlRGV0ZWN0b3IucHJvdG90eXBlLmJvb3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIFdvcmxkLnVwZGF0ZVJvdXRlcyhbcHViKHRoaXMubWVzc2FnZSldKTtcbiAgICB0aGlzLnRpbWVySWQgPSBzZXRJbnRlcnZhbChXb3JsZC53cmFwKGZ1bmN0aW9uICgpIHsgc2VsZi50cmlnZ2VyKCk7IH0pLCB0aGlzLnBlcmlvZCk7XG59O1xuXG5XYWtlRGV0ZWN0b3IucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24gKGUpIHt9O1xuXG5XYWtlRGV0ZWN0b3IucHJvdG90eXBlLnRyaWdnZXIgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIG5vdyA9ICsobmV3IERhdGUoKSk7XG4gICAgaWYgKG5vdyAtIHRoaXMubW9zdFJlY2VudFRyaWdnZXIgPiB0aGlzLnBlcmlvZCAqIDEuNSkge1xuXHRXb3JsZC5zZW5kKHRoaXMubWVzc2FnZSk7XG4gICAgfVxuICAgIHRoaXMubW9zdFJlY2VudFRyaWdnZXIgPSBub3c7XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5XYWtlRGV0ZWN0b3IgPSBXYWtlRGV0ZWN0b3I7XG4iLCJ2YXIgTWluaW1hcnQgPSByZXF1aXJlKFwiLi9taW5pbWFydC5qc1wiKTtcbnZhciBDb2RlYyA9IHJlcXVpcmUoXCIuL2NvZGVjLmpzXCIpO1xudmFyIFJvdXRlID0gTWluaW1hcnQuUm91dGU7XG52YXIgV29ybGQgPSBNaW5pbWFydC5Xb3JsZDtcbnZhciBzdWIgPSBNaW5pbWFydC5zdWI7XG52YXIgcHViID0gTWluaW1hcnQucHViO1xudmFyIF9fID0gTWluaW1hcnQuX187XG52YXIgXyQgPSBNaW5pbWFydC5fJDtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyBXZWJTb2NrZXQgY2xpZW50IGRyaXZlclxuXG52YXIgREVGQVVMVF9SRUNPTk5FQ1RfREVMQVkgPSAxMDA7XG52YXIgTUFYX1JFQ09OTkVDVF9ERUxBWSA9IDMwMDAwO1xudmFyIERFRkFVTFRfSURMRV9USU1FT1VUID0gMzAwMDAwOyAvLyA1IG1pbnV0ZXNcbnZhciBERUZBVUxUX1BJTkdfSU5URVJWQUwgPSBERUZBVUxUX0lETEVfVElNRU9VVCAtIDEwMDAwO1xuXG5mdW5jdGlvbiBXZWJTb2NrZXRDb25uZWN0aW9uKGxhYmVsLCB3c3VybCwgc2hvdWxkUmVjb25uZWN0KSB7XG4gICAgdGhpcy5sYWJlbCA9IGxhYmVsO1xuICAgIHRoaXMuc2VuZHNBdHRlbXB0ZWQgPSAwO1xuICAgIHRoaXMuc2VuZHNUcmFuc21pdHRlZCA9IDA7XG4gICAgdGhpcy5yZWNlaXZlQ291bnQgPSAwO1xuICAgIHRoaXMuc29jayA9IG51bGw7XG4gICAgdGhpcy53c3VybCA9IHdzdXJsO1xuICAgIHRoaXMuc2hvdWxkUmVjb25uZWN0ID0gc2hvdWxkUmVjb25uZWN0ID8gdHJ1ZSA6IGZhbHNlO1xuICAgIHRoaXMucmVjb25uZWN0RGVsYXkgPSBERUZBVUxUX1JFQ09OTkVDVF9ERUxBWTtcbiAgICB0aGlzLmxvY2FsR2VzdGFsdCA9IFJvdXRlLmVtcHR5R2VzdGFsdDtcbiAgICB0aGlzLnBlZXJHZXN0YWx0ID0gUm91dGUuZW1wdHlHZXN0YWx0O1xuICAgIHRoaXMucHJldkxvY2FsUm91dGVzTWVzc2FnZSA9IG51bGw7XG4gICAgdGhpcy5wcmV2UGVlclJvdXRlc01lc3NhZ2UgPSBudWxsO1xuICAgIHRoaXMuZGVkdXBsaWNhdG9yID0gbmV3IE1pbmltYXJ0LkRlZHVwbGljYXRvcigpO1xuICAgIHRoaXMuY29ubmVjdGlvbkNvdW50ID0gMDtcblxuICAgIHRoaXMuYWN0aXZpdHlUaW1lc3RhbXAgPSAwO1xuICAgIHRoaXMuaWRsZVRpbWVvdXQgPSBERUZBVUxUX0lETEVfVElNRU9VVDtcbiAgICB0aGlzLnBpbmdJbnRlcnZhbCA9IERFRkFVTFRfUElOR19JTlRFUlZBTDtcbiAgICB0aGlzLmlkbGVUaW1lciA9IG51bGw7XG4gICAgdGhpcy5waW5nVGltZXIgPSBudWxsO1xufVxuXG5XZWJTb2NrZXRDb25uZWN0aW9uLnByb3RvdHlwZS5jbGVhckhlYXJ0YmVhdFRpbWVycyA9IGZ1bmN0aW9uICgpIHtcbiAgICBpZiAodGhpcy5pZGxlVGltZXIpIHsgY2xlYXJUaW1lb3V0KHRoaXMuaWRsZVRpbWVyKTsgdGhpcy5pZGxlVGltZXIgPSBudWxsOyB9XG4gICAgaWYgKHRoaXMucGluZ1RpbWVyKSB7IGNsZWFyVGltZW91dCh0aGlzLnBpbmdUaW1lcik7IHRoaXMucGluZ1RpbWVyID0gbnVsbDsgfVxufTtcblxuV2ViU29ja2V0Q29ubmVjdGlvbi5wcm90b3R5cGUucmVjb3JkQWN0aXZpdHkgPSBmdW5jdGlvbiAoKSB7XG4gICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgIHRoaXMuYWN0aXZpdHlUaW1lc3RhbXAgPSArKG5ldyBEYXRlKCkpO1xuICAgIHRoaXMuY2xlYXJIZWFydGJlYXRUaW1lcnMoKTtcbiAgICB0aGlzLmlkbGVUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkgeyBzZWxmLmZvcmNlY2xvc2UoKTsgfSxcblx0XHRcdFx0dGhpcy5pZGxlVGltZW91dCk7XG4gICAgdGhpcy5waW5nVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHsgc2VsZi5zYWZlU2VuZChKU09OLnN0cmluZ2lmeShcInBpbmdcIikpIH0sXG5cdFx0XHRcdHRoaXMucGluZ0ludGVydmFsKTtcbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLnN0YXR1c1JvdXRlID0gZnVuY3Rpb24gKHN0YXR1cykge1xuICAgIHJldHVybiBwdWIoW3RoaXMubGFiZWwgKyBcIl9zdGF0ZVwiLCBzdGF0dXNdKTtcbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLnJlbGF5R2VzdGFsdCA9IGZ1bmN0aW9uICgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0dXNSb3V0ZSh0aGlzLmlzQ29ubmVjdGVkKCkgPyBcImNvbm5lY3RlZFwiIDogXCJkaXNjb25uZWN0ZWRcIilcblx0LnVuaW9uKHB1YihbdGhpcy5sYWJlbCwgX18sIF9fXSwgMCwgMTApKVxuXHQudW5pb24oc3ViKFt0aGlzLmxhYmVsLCBfXywgX19dLCAwLCAxMCkpO1xuICAgIC8vIFRPRE86IGxldmVsIDEwIGlzIGFkLWhvYzsgc3VwcG9ydCBpbmZpbml0eSBhdCBzb21lIHBvaW50IGluIGZ1dHVyZVxufTtcblxuV2ViU29ja2V0Q29ubmVjdGlvbi5wcm90b3R5cGUuYWdncmVnYXRlR2VzdGFsdCA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgcmV0dXJuIHRoaXMucGVlckdlc3RhbHQudHJhbnNmb3JtKGZ1bmN0aW9uIChtLCBtZXRhTGV2ZWwpIHtcblx0cmV0dXJuIFJvdXRlLmNvbXBpbGVQYXR0ZXJuKHRydWUsXG5cdFx0XHRcdCAgICBbc2VsZi5sYWJlbCwgbWV0YUxldmVsLCBSb3V0ZS5lbWJlZGRlZE1hdGNoZXIobSldKTtcbiAgICB9KS51bmlvbih0aGlzLnJlbGF5R2VzdGFsdCgpKTtcbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLmJvb3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgdGhpcy5yZWNvbm5lY3QoKTtcbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLnRyYXBleGl0ID0gZnVuY3Rpb24gKCkge1xuICAgIHRoaXMuZm9yY2VjbG9zZSgpO1xufTtcblxuV2ViU29ja2V0Q29ubmVjdGlvbi5wcm90b3R5cGUuaXNDb25uZWN0ZWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgcmV0dXJuIHRoaXMuc29jayAmJiB0aGlzLnNvY2sucmVhZHlTdGF0ZSA9PT0gdGhpcy5zb2NrLk9QRU47XG59O1xuXG5XZWJTb2NrZXRDb25uZWN0aW9uLnByb3RvdHlwZS5zYWZlU2VuZCA9IGZ1bmN0aW9uIChtKSB7XG4gICAgdHJ5IHtcblx0dGhpcy5zZW5kc0F0dGVtcHRlZCsrO1xuXHRpZiAodGhpcy5pc0Nvbm5lY3RlZCgpKSB7XG5cdCAgICB0aGlzLnNvY2suc2VuZChtKTtcblx0ICAgIHRoaXMuc2VuZHNUcmFuc21pdHRlZCsrO1xuXHR9XG4gICAgfSBjYXRjaCAoZSkge1xuXHRjb25zb2xlLndhcm4oXCJUcmFwcGVkIGV4biB3aGlsZSBzZW5kaW5nXCIsIGUpO1xuICAgIH1cbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLnNlbmRMb2NhbFJvdXRlcyA9IGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgbmV3TG9jYWxSb3V0ZXNNZXNzYWdlID1cblx0SlNPTi5zdHJpbmdpZnkoQ29kZWMuZW5jb2RlRXZlbnQoTWluaW1hcnQudXBkYXRlUm91dGVzKFt0aGlzLmxvY2FsR2VzdGFsdF0pKSk7XG4gICAgaWYgKHRoaXMucHJldkxvY2FsUm91dGVzTWVzc2FnZSAhPT0gbmV3TG9jYWxSb3V0ZXNNZXNzYWdlKSB7XG5cdHRoaXMucHJldkxvY2FsUm91dGVzTWVzc2FnZSA9IG5ld0xvY2FsUm91dGVzTWVzc2FnZTtcblx0dGhpcy5zYWZlU2VuZChuZXdMb2NhbFJvdXRlc01lc3NhZ2UpO1xuICAgIH1cbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLmNvbGxlY3RNYXRjaGVycyA9IGZ1bmN0aW9uIChnZXRBZHZlcnRpc2VtZW50cywgbGV2ZWwsIGcpIHtcbiAgICB2YXIgZXh0cmFjdE1ldGFMZXZlbHMgPSBSb3V0ZS5jb21waWxlUHJvamVjdGlvbihbdGhpcy5sYWJlbCwgXyQsIF9fXSk7XG4gICAgdmFyIG1scyA9IFJvdXRlLm1hdGNoZXJLZXlzKGcucHJvamVjdChleHRyYWN0TWV0YUxldmVscywgZ2V0QWR2ZXJ0aXNlbWVudHMsIDAsIGxldmVsKSk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtbHMubGVuZ3RoOyBpKyspIHtcblx0dmFyIG1ldGFMZXZlbCA9IG1sc1tpXVswXTsgLy8gb25seSBvbmUgY2FwdHVyZSBpbiB0aGUgcHJvamVjdGlvblxuXHR2YXIgZXh0cmFjdE1hdGNoZXJzID0gUm91dGUuY29tcGlsZVByb2plY3Rpb24oW3RoaXMubGFiZWwsIG1ldGFMZXZlbCwgXyRdKTtcblx0dmFyIG0gPSBnLnByb2plY3QoZXh0cmFjdE1hdGNoZXJzLCBnZXRBZHZlcnRpc2VtZW50cywgMCwgbGV2ZWwpO1xuXHR0aGlzLmxvY2FsR2VzdGFsdCA9IHRoaXMubG9jYWxHZXN0YWx0LnVuaW9uKFJvdXRlLnNpbXBsZUdlc3RhbHQoZ2V0QWR2ZXJ0aXNlbWVudHMsXG5cdFx0XHRcdFx0XHRcdFx0XHRSb3V0ZS5lbWJlZGRlZE1hdGNoZXIobSksXG5cdFx0XHRcdFx0XHRcdFx0XHRtZXRhTGV2ZWwsXG5cdFx0XHRcdFx0XHRcdFx0XHRsZXZlbCkpO1xuICAgIH1cbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24gKGUpIHtcbiAgICAvLyBjb25zb2xlLmxvZyhcIldlYlNvY2tldENvbm5lY3Rpb24uaGFuZGxlRXZlbnRcIiwgZSk7XG4gICAgc3dpdGNoIChlLnR5cGUpIHtcbiAgICBjYXNlIFwicm91dGVzXCI6XG5cdC8vIFRPRE86IEdST1NTIC0gZXJhc2luZyBieSBwaWQhXG5cdHZhciBuTGV2ZWxzID0gZS5nZXN0YWx0LmxldmVsQ291bnQoMCk7XG5cdHZhciByZWxheUdlc3RhbHQgPSBSb3V0ZS5mdWxsR2VzdGFsdCgxLCBuTGV2ZWxzKS5sYWJlbChXb3JsZC5hY3RpdmVQaWQoKSk7XG5cdHZhciBnID0gZS5nZXN0YWx0LmVyYXNlUGF0aChyZWxheUdlc3RhbHQpO1xuXHR0aGlzLmxvY2FsR2VzdGFsdCA9IFJvdXRlLmVtcHR5R2VzdGFsdDtcblx0Zm9yICh2YXIgbGV2ZWwgPSAwOyBsZXZlbCA8IG5MZXZlbHM7IGxldmVsKyspIHtcblx0ICAgIHRoaXMuY29sbGVjdE1hdGNoZXJzKGZhbHNlLCBsZXZlbCwgZyk7XG5cdCAgICB0aGlzLmNvbGxlY3RNYXRjaGVycyh0cnVlLCBsZXZlbCwgZyk7XG5cdH1cblxuXHR0aGlzLnNlbmRMb2NhbFJvdXRlcygpO1xuXHRicmVhaztcbiAgICBjYXNlIFwibWVzc2FnZVwiOlxuXHR2YXIgbSA9IGUubWVzc2FnZTtcblx0aWYgKG0ubGVuZ3RoICYmIG0ubGVuZ3RoID09PSAzICYmIG1bMF0gPT09IHRoaXMubGFiZWwpXG5cdHtcblx0ICAgIHZhciBlbmNvZGVkID0gSlNPTi5zdHJpbmdpZnkoQ29kZWMuZW5jb2RlRXZlbnQoXG5cdFx0TWluaW1hcnQuc2VuZE1lc3NhZ2UobVsyXSwgbVsxXSwgZS5pc0ZlZWRiYWNrKSkpO1xuXHQgICAgaWYgKHRoaXMuZGVkdXBsaWNhdG9yLmFjY2VwdChlbmNvZGVkKSkge1xuXHRcdHRoaXMuc2FmZVNlbmQoZW5jb2RlZCk7XG5cdCAgICB9XG5cdH1cblx0YnJlYWs7XG4gICAgfVxufTtcblxuV2ViU29ja2V0Q29ubmVjdGlvbi5wcm90b3R5cGUuZm9yY2VjbG9zZSA9IGZ1bmN0aW9uIChrZWVwUmVjb25uZWN0RGVsYXkpIHtcbiAgICBpZiAoIWtlZXBSZWNvbm5lY3REZWxheSkge1xuXHR0aGlzLnJlY29ubmVjdERlbGF5ID0gREVGQVVMVF9SRUNPTk5FQ1RfREVMQVk7XG4gICAgfVxuICAgIHRoaXMuY2xlYXJIZWFydGJlYXRUaW1lcnMoKTtcbiAgICBpZiAodGhpcy5zb2NrKSB7XG5cdGNvbnNvbGUubG9nKFwiV2ViU29ja2V0Q29ubmVjdGlvbi5mb3JjZWNsb3NlIGNhbGxlZFwiKTtcblx0dGhpcy5zb2NrLmNsb3NlKCk7XG5cdHRoaXMuc29jayA9IG51bGw7XG4gICAgfVxufTtcblxuV2ViU29ja2V0Q29ubmVjdGlvbi5wcm90b3R5cGUucmVjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICB0aGlzLmZvcmNlY2xvc2UodHJ1ZSk7XG4gICAgdGhpcy5jb25uZWN0aW9uQ291bnQrKztcbiAgICB0aGlzLnNvY2sgPSBuZXcgV2ViU29ja2V0KHRoaXMud3N1cmwpO1xuICAgIHRoaXMuc29jay5vbm9wZW4gPSBXb3JsZC53cmFwKGZ1bmN0aW9uIChlKSB7IHJldHVybiBzZWxmLm9ub3BlbihlKTsgfSk7XG4gICAgdGhpcy5zb2NrLm9ubWVzc2FnZSA9IFdvcmxkLndyYXAoZnVuY3Rpb24gKGUpIHtcblx0c2VsZi5yZWNlaXZlQ291bnQrKztcblx0cmV0dXJuIHNlbGYub25tZXNzYWdlKGUpO1xuICAgIH0pO1xuICAgIHRoaXMuc29jay5vbmNsb3NlID0gV29ybGQud3JhcChmdW5jdGlvbiAoZSkgeyByZXR1cm4gc2VsZi5vbmNsb3NlKGUpOyB9KTtcbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLm9ub3BlbiA9IGZ1bmN0aW9uIChlKSB7XG4gICAgY29uc29sZS5sb2coXCJjb25uZWN0ZWQgdG8gXCIgKyB0aGlzLnNvY2sudXJsKTtcbiAgICB0aGlzLnJlY29ubmVjdERlbGF5ID0gREVGQVVMVF9SRUNPTk5FQ1RfREVMQVk7XG4gICAgdGhpcy5wcmV2TG9jYWxSb3V0ZXNNZXNzYWdlID0gbnVsbDtcbiAgICB0aGlzLnNlbmRMb2NhbFJvdXRlcygpO1xufTtcblxuV2ViU29ja2V0Q29ubmVjdGlvbi5wcm90b3R5cGUub25tZXNzYWdlID0gZnVuY3Rpb24gKHdzZSkge1xuICAgIC8vIGNvbnNvbGUubG9nKFwib25tZXNzYWdlXCIsIHdzZSk7XG4gICAgdGhpcy5yZWNvcmRBY3Rpdml0eSgpO1xuXG4gICAgdmFyIGogPSBKU09OLnBhcnNlKHdzZS5kYXRhKTtcbiAgICBpZiAoaiA9PT0gXCJwaW5nXCIpIHtcblx0dGhpcy5zYWZlU2VuZChKU09OLnN0cmluZ2lmeShcInBvbmdcIikpO1xuXHRyZXR1cm47XG4gICAgfSBlbHNlIGlmIChqID09PSBcInBvbmdcIikge1xuXHRyZXR1cm47IC8vIHJlY29yZEFjdGl2aXR5IGFscmVhZHkgdG9vayBjYXJlIG9mIG91ciB0aW1lcnNcbiAgICB9XG5cbiAgICB2YXIgZSA9IGRlY29kZUFjdGlvbihqKTtcbiAgICBzd2l0Y2ggKGUudHlwZSkge1xuICAgIGNhc2UgXCJyb3V0ZXNcIjpcblx0aWYgKHRoaXMucHJldlBlZXJSb3V0ZXNNZXNzYWdlICE9PSB3c2UuZGF0YSkge1xuXHQgICAgdGhpcy5wcmV2UGVlclJvdXRlc01lc3NhZ2UgPSB3c2UuZGF0YTtcblx0ICAgIHRoaXMucGVlckdlc3RhbHQgPSBlLmdlc3RhbHQ7XG5cdCAgICBXb3JsZC51cGRhdGVSb3V0ZXMoW3RoaXMuYWdncmVnYXRlR2VzdGFsdCgpXSk7XG5cdH1cblx0YnJlYWs7XG4gICAgY2FzZSBcIm1lc3NhZ2VcIjpcblx0aWYgKHRoaXMuZGVkdXBsaWNhdG9yLmFjY2VwdCh3c2UuZGF0YSkpIHtcblx0ICAgIFdvcmxkLnNlbmQoW3RoaXMubGFiZWwsIGUubWV0YUxldmVsLCBlLm1lc3NhZ2VdLCAwLCBlLmlzRmVlZGJhY2spO1xuXHR9XG5cdGJyZWFrO1xuICAgIH1cbn07XG5cbldlYlNvY2tldENvbm5lY3Rpb24ucHJvdG90eXBlLm9uY2xvc2UgPSBmdW5jdGlvbiAoZSkge1xuICAgIHZhciBzZWxmID0gdGhpcztcbiAgICBjb25zb2xlLmxvZyhcIm9uY2xvc2VcIiwgZSk7XG5cbiAgICAvLyBVcGRhdGUgcm91dGVzIHRvIGdpdmUgY2xpZW50cyBzb21lIGluZGljYXRpb24gb2YgdGhlIGRpc2NvbnRpbnVpdHlcbiAgICBXb3JsZC51cGRhdGVSb3V0ZXMoW3RoaXMuYWdncmVnYXRlR2VzdGFsdCgpXSk7XG5cbiAgICBpZiAodGhpcy5zaG91bGRSZWNvbm5lY3QpIHtcblx0Y29uc29sZS5sb2coXCJyZWNvbm5lY3RpbmcgdG8gXCIgKyB0aGlzLndzdXJsICsgXCIgaW4gXCIgKyB0aGlzLnJlY29ubmVjdERlbGF5ICsgXCJtc1wiKTtcblx0c2V0VGltZW91dChXb3JsZC53cmFwKGZ1bmN0aW9uICgpIHsgc2VsZi5yZWNvbm5lY3QoKTsgfSksIHRoaXMucmVjb25uZWN0RGVsYXkpO1xuXHR0aGlzLnJlY29ubmVjdERlbGF5ID0gdGhpcy5yZWNvbm5lY3REZWxheSAqIDEuNjE4ICsgKE1hdGgucmFuZG9tKCkgKiAxMDAwKTtcblx0dGhpcy5yZWNvbm5lY3REZWxheSA9XG5cdCAgICB0aGlzLnJlY29ubmVjdERlbGF5ID4gTUFYX1JFQ09OTkVDVF9ERUxBWVxuXHQgICAgPyBNQVhfUkVDT05ORUNUX0RFTEFZICsgKE1hdGgucmFuZG9tKCkgKiAxMDAwKVxuXHQgICAgOiB0aGlzLnJlY29ubmVjdERlbGF5O1xuICAgIH1cbn07XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuXG5tb2R1bGUuZXhwb3J0cy5XZWJTb2NrZXRDb25uZWN0aW9uID0gV2ViU29ja2V0Q29ubmVjdGlvbjtcbiIsIi8qIFdlYiBXb3JrZXIgaW50ZXJmYWNlICovXG52YXIgR3JvdW5kID0gcmVxdWlyZShcIi4vZ3JvdW5kLmpzXCIpLkdyb3VuZDtcbnZhciBVdGlsID0gcmVxdWlyZShcIi4vdXRpbC5qc1wiKTtcbnZhciBDb2RlYyA9IHJlcXVpcmUoXCIuL2NvZGVjLmpzXCIpO1xuXG52YXIgTWluaW1hcnQgPSByZXF1aXJlKFwiLi9taW5pbWFydC5qc1wiKTtcbnZhciBXb3JsZCA9IE1pbmltYXJ0LldvcmxkO1xudmFyIHN1YiA9IE1pbmltYXJ0LnN1YjtcbnZhciBwdWIgPSBNaW5pbWFydC5wdWI7XG52YXIgX18gPSBNaW5pbWFydC5fXztcblxudmFyIEJ1aWx0aW5Xb3JrZXIgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB3aW5kb3cuV29ya2VyO1xuXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cblxuZnVuY3Rpb24gV29ya2VyKHNjcmlwdFVybCkge1xuICB0aGlzLnNjcmlwdFVybCA9IHNjcmlwdFVybDtcbiAgdGhpcy53ID0gbmV3IEJ1aWx0aW5Xb3JrZXIoc2NyaXB0VXJsKTtcbn1cblxuV29ya2VyLnByb3RvdHlwZS5ib290ID0gZnVuY3Rpb24gKCkge1xuICB0aGlzLncub25tZXNzYWdlID0gV29ybGQud3JhcChmdW5jdGlvbiAoZSkge1xuICAgIGNvbnNvbGUubG9nKFwiUmVjZWl2ZWQgZnJvbSB3b3JrZXJcIiwgSlNPTi5zdHJpbmdpZnkoZS5kYXRhKSk7XG4gICAgV29ybGQuY3VycmVudCgpLmVucXVldWVBY3Rpb24oV29ybGQuYWN0aXZlUGlkKCksIENvZGVjLmRlY29kZUFjdGlvbihlLmRhdGEpKTtcbiAgfSk7XG59O1xuXG5Xb3JrZXIucHJvdG90eXBlLmhhbmRsZUV2ZW50ID0gZnVuY3Rpb24gKGUpIHtcbiAgY29uc29sZS5sb2coXCJTZW5kaW5nIHRvIHdvcmtlclwiLCBKU09OLnN0cmluZ2lmeShDb2RlYy5lbmNvZGVFdmVudChlKSkpO1xuICB0aGlzLncucG9zdE1lc3NhZ2UoQ29kZWMuZW5jb2RlRXZlbnQoZSkpO1xufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbmZ1bmN0aW9uIFdvcmtlckdyb3VuZChib290Rm4pIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICBHcm91bmQuY2FsbCh0aGlzLCBib290Rm4pO1xuICBvbm1lc3NhZ2UgPSBmdW5jdGlvbiAoZSkge1xuICAgIGNvbnNvbGUubG9nKFwiUmVjZWl2ZWQgZnJvbSBtYWluIHBhZ2VcIiwgSlNPTi5zdHJpbmdpZnkoZS5kYXRhKSk7XG4gICAgc2VsZi53b3JsZC5oYW5kbGVFdmVudChDb2RlYy5kZWNvZGVFdmVudChlLmRhdGEpKTtcbiAgICBzZWxmLnN0YXJ0U3RlcHBpbmcoKTtcbiAgfTtcbn1cblxuV29ya2VyR3JvdW5kLnByb3RvdHlwZSA9IFV0aWwuZXh0ZW5kKHt9LCBHcm91bmQucHJvdG90eXBlKTtcblxuV29ya2VyR3JvdW5kLnByb3RvdHlwZS5lbnF1ZXVlQWN0aW9uID0gZnVuY3Rpb24gKHBpZCwgYWN0aW9uKSB7XG4gIGNvbnNvbGUubG9nKFwiU2VuZGluZyB0byBtYWluIHBhZ2VcIiwgSlNPTi5zdHJpbmdpZnkoQ29kZWMuZW5jb2RlQWN0aW9uKGFjdGlvbikpKTtcbiAgcG9zdE1lc3NhZ2UoQ29kZWMuZW5jb2RlQWN0aW9uKGFjdGlvbikpO1xuICBjb25zb2xlLmxvZyhcIlNlbnQgdG8gbWFpbiBwYWdlXCIpO1xufTtcblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG5cbm1vZHVsZS5leHBvcnRzLldvcmtlciA9IFdvcmtlcjtcbm1vZHVsZS5leHBvcnRzLldvcmtlckdyb3VuZCA9IFdvcmtlckdyb3VuZDtcbiJdfQ== +(6) }); diff --git a/dist/minimart.min.js b/dist/minimart.min.js index 7bf880f..e8b0eea 100644 --- a/dist/minimart.min.js +++ b/dist/minimart.min.js @@ -1,2 +1,3 @@ -!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Minimart=e()}}(function(){var define,module,exports;return 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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o ."+self.fragmentClass,1,self.jQueryWrapFunction);World.spawn({handleEvent:function(e){if(e.type==="routes"){var level=e.gestalt.getLevel(1,0);if(!e.gestalt.isEmpty()&&level.isEmpty()){World.shutdownWorld()}}}},[monitoring])}))};DOMFragment.prototype.handleEvent=function(e){if(e.type==="routes"&&e.gestalt.isEmpty()){for(var i=0;i=0;i--){World.stack[i][0].markPidRunnable(World.stack[i][1])}return result})}};World.prototype.enqueueAction=function(pid,action){this.processActions.push([pid,action])};World.prototype.isInert=function(){return this.eventQueue.length===0&&this.processActions.length===0&&Route.is_emptySet(this.runnablePids)};World.prototype.markPidRunnable=function(pid){this.runnablePids[pid]=[pid]};World.prototype.step=function(){this.dispatchEvents();this.performActions();this.stepChildren();return this.alive&&!this.isInert()};World.prototype.asChild=function(pid,f,omitLivenessCheck){if(!(pid in this.processTable)&&!omitLivenessCheck){console.warn("World.asChild eliding invocation of dead process",pid);return}World.stack.push([this,pid]);var result=null;try{result=f()}catch(e){this.kill(pid,e)}if(World.stack.pop()[0]!==this){throw new Error("Internal error: World stack imbalance")}return result};World.prototype.kill=function(pid,exn){if(exn&&exn.stack){console.log("Process exited",pid,exn,exn.stack)}else{console.log("Process exited",pid,exn)}var p=this.processTable[pid];if(p&&p.behavior.trapexit){this.asChild(pid,function(){return p.behavior.trapexit(exn)})}delete this.processTable[pid];if(p){if(exn){p.exitReason=exn;this.tombstones[pid]=p}this.applyAndIssueRoutingUpdate(p.gestalt,Route.emptyGestalt)}};World.prototype.stepChildren=function(){var pids=this.runnablePids;this.runnablePids={};for(var pid in pids){var p=this.processTable[pid];if(p&&p.behavior.step){var childBusy=this.asChild(pid|0,function(){return p.behavior.step()});if(childBusy)this.markPidRunnable(pid)}}};World.prototype.performActions=function(){var queue=this.processActions;this.processActions=[];var item;while((item=queue.shift())&&this.alive){this.performAction(item[0],item[1])}};World.prototype.dispatchEvents=function(){var queue=this.eventQueue;this.eventQueue=[];var item;while(item=queue.shift()){this.dispatchEvent(item)}};World.prototype.performAction=function(pid,action){switch(action.type){case"spawn":var pid=World.nextPid++;var newGestalt=action.initialGestalt.label(pid);this.processTable[pid]={gestalt:newGestalt,behavior:action.behavior};if(action.behavior.boot){this.asChild(pid,function(){action.behavior.boot()});this.markPidRunnable(pid)}this.applyAndIssueRoutingUpdate(Route.emptyGestalt,newGestalt,pid);break;case"routes":if(pid in this.processTable){var oldGestalt=this.processTable[pid].gestalt;var newGestalt=action.gestalt.label(pid|0);this.processTable[pid].gestalt=newGestalt;this.applyAndIssueRoutingUpdate(oldGestalt,newGestalt,pid)}break;case"message":if(action.metaLevel===0){this.eventQueue.push(action)}else{World.send(action.message,action.metaLevel-1,action.isFeedback)}break;case"shutdownWorld":this.alive=false;World.exit();break;default:var exn=new Error("Action type "+action.type+" not understood");exn.action=action;throw exn}};World.prototype.updateFullGestalt=function(){this.fullGestalt=this.partialGestalt.union(this.downwardGestalt)};World.prototype.issueLocalRoutingUpdate=function(affectedSubgestalt,knownTarget){this.eventQueue.push(pendingRoutingUpdate(this.fullGestalt,affectedSubgestalt,knownTarget))};World.prototype.applyAndIssueRoutingUpdate=function(oldg,newg,knownTarget){knownTarget=typeof knownTarget==="undefined"?null:knownTarget;this.partialGestalt=this.partialGestalt.erasePath(oldg).union(newg);this.updateFullGestalt();this.issueLocalRoutingUpdate(oldg.union(newg),knownTarget);World.updateRoutes([this.partialGestalt.drop()])};World.prototype.dispatchEvent=function(e){switch(e.type){case"pendingRoutingUpdate":var pids=e.affectedSubgestalt.match(e.aggregate);if(e.knownTarget!==null)pids.unshift(e.knownTarget);for(var i=0;i1e3?1e3:this.ttl_ms)}return true};Deduplicator.prototype.expireMessages=function(){var now=+new Date;while(this.queue.length>0&&this.queue[0][0]<=now){var entry=this.queue.shift();delete this.map[entry[1]]}if(this.queue.length===0){clearInterval(this.timerId);this.timerId=null}};function Ground(bootFn){var self=this;this.stepperId=null;World.withWorldStack([[this,-1]],function(){self.world=new World(bootFn)})}Ground.prototype.step=function(){var self=this;return World.withWorldStack([[this,-1]],function(){return self.world.step()})};Ground.prototype.checkPid=function(pid){if(pid!==-1)console.error("Weird pid in Ground markPidRunnable",pid)};Ground.prototype.markPidRunnable=function(pid){this.checkPid(pid);this.startStepping()};Ground.prototype.startStepping=function(){var self=this;if(this.stepperId)return;if(this.step()){this.stepperId=setTimeout(function(){self.stepperId=null;self.startStepping()},0)}};Ground.prototype.stopStepping=function(){if(this.stepperId){clearTimeout(this.stepperId);this.stepperId=null}};Ground.prototype.enqueueAction=function(pid,action){this.checkPid(pid);if(action.type==="routes"){if(!action.gestalt.isEmpty()){console.error("You have subscribed to a nonexistent event source.",action.gestalt.pretty())}}else{console.error("You have sent a message into the outer void.",action)}};module.exports.__=__;module.exports._$=_$;module.exports.sub=sub;module.exports.pub=pub;module.exports.spawn=spawn;module.exports.updateRoutes=updateRoutes;module.exports.sendMessage=sendMessage;module.exports.shutdownWorld=shutdownWorld;module.exports.World=World;module.exports.DemandMatcher=DemandMatcher;module.exports.Deduplicator=Deduplicator;module.exports.Ground=Ground;module.exports.Route=Route},{"./route.js":7}],6:[function(_dereq_,module,exports){var FN_ARGS=/^function\s*[^\(]*\(\s*([^\)]*)\)/m;var FN_ARG_SPLIT=/,/;var STRIP_COMMENTS=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;function formalParameters(fn){var result=[];var fnText=fn.toString().replace(STRIP_COMMENTS,"");var argDecl=fnText.match(FN_ARGS);var args=argDecl[1].split(FN_ARG_SPLIT);for(var i=0;i=0;i--){acc=walk(p[i],acc)}return rseq(SOA,acc)}if(p instanceof $Embedded){return appendMatcher(p.matcher,function(v){return acc})}else{return rseq(JSON.stringify(p),acc)}}}function matchPattern(v,p){var captureCount=0;var result={};try{walk(v,p)}catch(e){if(e.matchPatternFailed)return null;throw e}result.length=captureCount;return result;function walk(v,p){if(p===v)return;if(p===__)return;if(Array.isArray(p)&&Array.isArray(v)&&p.length===v.length){for(var i=0;i=spec.length){if(isCapturing)die("Bad specification: unclosed capture");if(m instanceof $Success){return rseq(EOA,rsuccess(projectSuccess(m.value)))}else{return emptyMatcher}}if(is_emptyMatcher(m))return emptyMatcher;var item=spec[specIndex];var nextIndex=specIndex+1;if(item===EOC){if(!isCapturing)die("Bad specification: unepxected EOC");return walk(false,m,nextIndex)}if(item===SOC){if(isCapturing)die("Bad specification: nested capture");return walk(true,m,nextIndex)}if(item===__){if(m instanceof $WildcardSequence){if(isCapturing){return rwild(walk(isCapturing,m,nextIndex))}else{return walk(isCapturing,m,nextIndex)}}if(m instanceof $Success){return emptyMatcher}var target;if(isCapturing){target=new $Dict;rupdateInplace(target,__,walk(isCapturing,m.get(__),nextIndex));for(var key in m.entries){if(key!==__){var mk=m.get(key);if(is_keyOpen(key)){function cont(mk2){return walk(isCapturing,mk2,nextIndex)}rupdateInplace(target,key,captureNested(mk,cont))}else if(is_keyClose(key)){}else{rupdateInplace(target,key,walk(isCapturing,mk,nextIndex))}}}}else{target=walk(isCapturing,m.get(__),nextIndex);for(var key in m.entries){if(key!==__){var mk=m.get(key);if(is_keyOpen(key)){function cont(mk2){return walk(isCapturing,mk2,nextIndex)}target=union(target,skipNested(mk,cont))}else if(is_keyClose(key)){}else{target=union(target,walk(isCapturing,mk,nextIndex))}}}}return target}var result;if(m instanceof $WildcardSequence){if(is_keyOpen(item)){result=walk(isCapturing,rwildseq(m),nextIndex)}else if(is_keyClose(item)){result=walk(isCapturing,m.matcher,nextIndex)}else{result=walk(isCapturing,m,nextIndex)}}else if(m instanceof $Success){result=emptyMatcher}else{if(is_keyOpen(item)){result=walk(isCapturing,rwildseq(m.get(__)),nextIndex)}else if(is_keyClose(item)){result=emptyMatcher}else{result=walk(isCapturing,m.get(__),nextIndex)}result=union(result,walk(isCapturing,m.get(item),nextIndex))}if(isCapturing){result=rseq(item,result)}return result}function captureNested(m,cont){if(m instanceof $WildcardSequence){return rwildseq(cont(m.matcher))}if(is_emptyMatcher(m)||m instanceof $Success){return emptyMatcher}var target=new $Dict;rupdateInplace(target,__,captureNested(m.get(__),cont));for(var key in m.entries){if(key!==__){var mk=m.get(key);if(is_keyOpen(key)){function cont2(mk2){return captureNested(mk2,cont)}rupdateInplace(target,key,captureNested(mk,cont2))}else if(is_keyClose(key)){rupdateInplace(target,key,cont(mk))}else{rupdateInplace(target,key,captureNested(mk,cont))}}}return target.emptyGuard()}function skipNested(m,cont){if(m instanceof $WildcardSequence){return cont(m.matcher)}if(is_emptyMatcher(m)||m instanceof $Success){return emptyMatcher}var target=skipNested(m.get(__),cont);for(var key in m.entries){if(key!==__){var mk=m.get(key);if(is_keyOpen(key)){function cont2(mk2){return skipNested(mk2,cont)}target=union(target,skipNested(mk,cont2))}else if(is_keyClose(key)){target=union(target,cont(mk))}else{target=union(target,skipNested(mk,cont))}}}return target}}function matcherKeys(m){if(is_emptyMatcher(m))return[];return walkSeq(m,function(vss,vsk){return vss});function walk(m,k){if(m instanceof $WildcardSequence)return null;if(m instanceof $Success)return[];if(m.has(__))return null;var acc=[];for(var key in m.entries){var mk=m.get(key);var piece;if(is_keyOpen(key)){function seqK(vss,vsk){var acc=[];for(var i=0;i");walk(i+4,m.matcher);return}if(m instanceof $Success){var vs=JSON.stringify(typeof m.value==="object"?setToArray(m.value):m.value);acc.push("{"+vs+"}");return}if(m.length===0){acc.push(" ::: empty hash!");return}var needSep=false;var keys=m.sortedKeys();for(var keyi=0;keyi";acc.push(key);walk(i+key.length+1,k)}}function indentStr(i){return new Array(i+1).join(" ")}}function serializeMatcher(m,serializeSuccess){return walk(m);function walk(m){if(is_emptyMatcher(m))return[];if(m instanceof $WildcardSequence){return["...)",walk(m.matcher)]}if(m instanceof $Success){return["",serializeSuccess(m.value)]}var acc=[];for(var key in m.entries){var k=m.entries[key];if(key===__)key=["__"];else if(key===SOA)key=["("];else if(key===EOA)key=[")"];else key=JSON.parse(key);acc.push([key,walk(k)])}return acc}}function deserializeMatcher(r,deserializeSuccess){return walk(r);function walk(r){if(r.length===0)return emptyMatcher;if(r[0]==="...)")return rwildseq(walk(r[1]));if(r[0]==="")return rsuccess(deserializeSuccess(r[1]));var acc=new $Dict;for(var i=0;i0){while(metaLevels.length0?this.union1(gestaltUnion(arguments)):this};function telescopeLevels(levels){var result=shallowCopyArray(levels);for(var i=result.length-2;i>=0;i--){result[i]=new GestaltLevel(union(result[i].subscriptions,result[i+1].subscriptions),union(result[i].advertisements,result[i+1].advertisements))}return result}Gestalt.prototype.telescoped=function(){var mls=[];for(var i=0;i0){while(outputMetaLevels.lengththis.period*1.5){World.send(this.message)}this.mostRecentTrigger=now};module.exports.WakeDetector=WakeDetector},{"./minimart.js":5}],11:[function(_dereq_,module,exports){var Minimart=_dereq_("./minimart.js");var Route=Minimart.Route;var World=Minimart.World;var sub=Minimart.sub;var pub=Minimart.pub;var __=Minimart.__;var _$=Minimart._$;var DEFAULT_RECONNECT_DELAY=100;var MAX_RECONNECT_DELAY=3e4;var DEFAULT_IDLE_TIMEOUT=3e5;var DEFAULT_PING_INTERVAL=DEFAULT_IDLE_TIMEOUT-1e4;function WebSocketConnection(label,wsurl,shouldReconnect){this.label=label;this.sendsAttempted=0;this.sendsTransmitted=0;this.receiveCount=0;this.sock=null;this.wsurl=wsurl;this.shouldReconnect=shouldReconnect?true:false;this.reconnectDelay=DEFAULT_RECONNECT_DELAY;this.localGestalt=Route.emptyGestalt;this.peerGestalt=Route.emptyGestalt;this.prevLocalRoutesMessage=null;this.prevPeerRoutesMessage=null;this.deduplicator=new Minimart.Deduplicator;this.connectionCount=0;this.activityTimestamp=0;this.idleTimeout=DEFAULT_IDLE_TIMEOUT;this.pingInterval=DEFAULT_PING_INTERVAL;this.idleTimer=null;this.pingTimer=null}WebSocketConnection.prototype.clearHeartbeatTimers=function(){if(this.idleTimer){clearTimeout(this.idleTimer);this.idleTimer=null}if(this.pingTimer){clearTimeout(this.pingTimer);this.pingTimer=null}};WebSocketConnection.prototype.recordActivity=function(){var self=this;this.activityTimestamp=+new Date;this.clearHeartbeatTimers();this.idleTimer=setTimeout(function(){self.forceclose()},this.idleTimeout);this.pingTimer=setTimeout(function(){self.safeSend(JSON.stringify("ping"))},this.pingInterval)};WebSocketConnection.prototype.statusRoute=function(status){return pub([this.label+"_state",status])};WebSocketConnection.prototype.relayGestalt=function(){return this.statusRoute(this.isConnected()?"connected":"disconnected").union(pub([this.label,__,__],0,10)).union(sub([this.label,__,__],0,10))};WebSocketConnection.prototype.aggregateGestalt=function(){var self=this;return this.peerGestalt.transform(function(m,metaLevel){return Route.compilePattern(true,[self.label,metaLevel,Route.embeddedMatcher(m)])}).union(this.relayGestalt())};WebSocketConnection.prototype.boot=function(){this.reconnect()};WebSocketConnection.prototype.trapexit=function(){this.forceclose()};WebSocketConnection.prototype.isConnected=function(){return this.sock&&this.sock.readyState===this.sock.OPEN};WebSocketConnection.prototype.safeSend=function(m){try{this.sendsAttempted++;if(this.isConnected()){this.sock.send(m);this.sendsTransmitted++}}catch(e){console.warn("Trapped exn while sending",e)}};WebSocketConnection.prototype.sendLocalRoutes=function(){var newLocalRoutesMessage=JSON.stringify(encodeEvent(Minimart.updateRoutes([this.localGestalt])));if(this.prevLocalRoutesMessage!==newLocalRoutesMessage){this.prevLocalRoutesMessage=newLocalRoutesMessage;this.safeSend(newLocalRoutesMessage)}};WebSocketConnection.prototype.collectMatchers=function(getAdvertisements,level,g){var extractMetaLevels=Route.compileProjection([this.label,_$,__]);var mls=Route.matcherKeys(g.project(extractMetaLevels,getAdvertisements,0,level));for(var i=0;iMAX_RECONNECT_DELAY?MAX_RECONNECT_DELAY+Math.random()*1e3:this.reconnectDelay}};function encodeEvent(e){switch(e.type){case"routes":return["routes",e.gestalt.serialize(function(v){return true})];case"message":return["message",e.message,e.metaLevel,e.isFeedback]}}function decodeAction(j){switch(j[0]){case"routes":return Minimart.updateRoutes([Route.deserializeGestalt(j[1],function(v){return true})]);case"message":return Minimart.sendMessage(j[1],j[2],j[3]);default:throw{message:"Invalid JSON-encoded action: "+JSON.stringify(j)}}}module.exports.WebSocketConnection=WebSocketConnection;module.exports.encodeEvent=encodeEvent;module.exports.decodeAction=decodeAction},{"./minimart.js":5}]},{},[4])(4)}); \ No newline at end of file +!function(e){if("object"==typeof exports)module.exports=e();else if("function"==typeof define&&define.amd)define(e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Minimart=e()}}(function(){var define,module,exports;return 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);throw new Error("Cannot find module '"+o+"'")}var f=n[o]={exports:{}};t[o][0].call(f.exports,function(e){var n=t[o][1][e];return s(n?n:e)},f,f.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o ."+self.fragmentClass,1,self.jQueryWrapFunction);World.spawn({handleEvent:function(e){if(e.type==="routes"){var level=e.gestalt.getLevel(1,0);if(!e.gestalt.isEmpty()&&level.isEmpty()){World.shutdownWorld()}}}},[monitoring])}))};DOMFragment.prototype.handleEvent=function(e){if(e.type==="routes"&&e.gestalt.isEmpty()){for(var i=0;i=0;i--){World.stack[i][0].markPidRunnable(World.stack[i][1])}return result})}};World.prototype.enqueueAction=function(pid,action){this.processActions.push([pid,action])};World.prototype.isInert=function(){return this.eventQueue.length===0&&this.processActions.length===0&&Route.is_emptySet(this.runnablePids)};World.prototype.markPidRunnable=function(pid){this.runnablePids[pid]=[pid]};World.prototype.step=function(){this.dispatchEvents();this.performActions();this.stepChildren();return this.alive&&!this.isInert()};World.prototype.asChild=function(pid,f,omitLivenessCheck){if(!(pid in this.processTable)&&!omitLivenessCheck){console.warn("World.asChild eliding invocation of dead process",pid);return}World.stack.push([this,pid]);var result=null;try{result=f()}catch(e){this.kill(pid,e)}if(World.stack.pop()[0]!==this){throw new Error("Internal error: World stack imbalance")}return result};World.prototype.kill=function(pid,exn){if(exn&&exn.stack){console.log("Process exited",pid,exn,exn.stack)}else{console.log("Process exited",pid,exn)}var p=this.processTable[pid];if(p&&p.behavior.trapexit){this.asChild(pid,function(){return p.behavior.trapexit(exn)})}delete this.processTable[pid];if(p){if(exn){p.exitReason=exn;this.tombstones[pid]=p}this.applyAndIssueRoutingUpdate(p.gestalt,Route.emptyGestalt)}};World.prototype.stepChildren=function(){var pids=this.runnablePids;this.runnablePids={};for(var pid in pids){var p=this.processTable[pid];if(p&&p.behavior.step){var childBusy=this.asChild(pid|0,function(){return p.behavior.step()});if(childBusy)this.markPidRunnable(pid)}}};World.prototype.performActions=function(){var queue=this.processActions;this.processActions=[];var item;while((item=queue.shift())&&this.alive){this.performAction(item[0],item[1])}};World.prototype.dispatchEvents=function(){var queue=this.eventQueue;this.eventQueue=[];var item;while(item=queue.shift()){this.dispatchEvent(item)}};World.prototype.performAction=function(pid,action){switch(action.type){case"spawn":var pid=World.nextPid++;var newGestalt=action.initialGestalt.label(pid);this.processTable[pid]={gestalt:newGestalt,behavior:action.behavior};if(action.behavior.boot){this.asChild(pid,function(){action.behavior.boot()});this.markPidRunnable(pid)}this.applyAndIssueRoutingUpdate(Route.emptyGestalt,newGestalt,pid);break;case"routes":if(pid in this.processTable){var oldGestalt=this.processTable[pid].gestalt;var newGestalt=action.gestalt.label(pid|0);this.processTable[pid].gestalt=newGestalt;this.applyAndIssueRoutingUpdate(oldGestalt,newGestalt,pid)}break;case"message":if(action.metaLevel===0){this.eventQueue.push(action)}else{World.send(action.message,action.metaLevel-1,action.isFeedback)}break;case"shutdownWorld":this.alive=false;World.exit();break;default:var exn=new Error("Action type "+action.type+" not understood");exn.action=action;throw exn}};World.prototype.updateFullGestalt=function(){this.fullGestalt=this.partialGestalt.union(this.downwardGestalt)};World.prototype.issueLocalRoutingUpdate=function(affectedSubgestalt,knownTarget){this.eventQueue.push(pendingRoutingUpdate(this.fullGestalt,affectedSubgestalt,knownTarget))};World.prototype.applyAndIssueRoutingUpdate=function(oldg,newg,knownTarget){knownTarget=typeof knownTarget==="undefined"?null:knownTarget;this.partialGestalt=this.partialGestalt.erasePath(oldg).union(newg);this.updateFullGestalt();this.issueLocalRoutingUpdate(oldg.union(newg),knownTarget);World.updateRoutes([this.partialGestalt.drop()])};World.prototype.dispatchEvent=function(e){switch(e.type){case"pendingRoutingUpdate":var pids=e.affectedSubgestalt.match(e.aggregate);if(e.knownTarget!==null)pids.unshift(e.knownTarget);for(var i=0;i1e3?1e3:this.ttl_ms)}return true};Deduplicator.prototype.expireMessages=function(){var now=+new Date;while(this.queue.length>0&&this.queue[0][0]<=now){var entry=this.queue.shift();delete this.map[entry[1]]}if(this.queue.length===0){clearInterval(this.timerId);this.timerId=null}};module.exports.__=__;module.exports._$=_$;module.exports.sub=sub;module.exports.pub=pub;module.exports.spawn=spawn;module.exports.updateRoutes=updateRoutes;module.exports.sendMessage=sendMessage;module.exports.shutdownWorld=shutdownWorld;module.exports.World=World;module.exports.DemandMatcher=DemandMatcher;module.exports.Deduplicator=Deduplicator;module.exports.Route=Route},{"./route.js":9,"./util.js":12}],8:[function(_dereq_,module,exports){var FN_ARGS=/^function\s*[^\(]*\(\s*([^\)]*)\)/m;var FN_ARG_SPLIT=/,/;var STRIP_COMMENTS=/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/gm;function formalParameters(fn){var result=[];var fnText=fn.toString().replace(STRIP_COMMENTS,"");var argDecl=fnText.match(FN_ARGS);var args=argDecl[1].split(FN_ARG_SPLIT);for(var i=0;i=0;i--){acc=walk(p[i],acc)}return rseq(SOA,acc)}if(p instanceof $Embedded){return appendMatcher(p.matcher,function(v){return acc})}else{return rseq(JSON.stringify(p),acc)}}}function matchPattern(v,p){var captureCount=0;var result={};try{walk(v,p)}catch(e){if(e.matchPatternFailed)return null;throw e}result.length=captureCount;return result;function walk(v,p){if(p===v)return;if(p===__)return;if(Array.isArray(p)&&Array.isArray(v)&&p.length===v.length){for(var i=0;i=spec.length){if(isCapturing)die("Bad specification: unclosed capture");if(m instanceof $Success){return rseq(EOA,rsuccess(projectSuccess(m.value)))}else{return emptyMatcher}}if(is_emptyMatcher(m))return emptyMatcher;var item=spec[specIndex];var nextIndex=specIndex+1;if(item===EOC){if(!isCapturing)die("Bad specification: unepxected EOC");return walk(false,m,nextIndex)}if(item===SOC){if(isCapturing)die("Bad specification: nested capture");return walk(true,m,nextIndex)}if(item===__){if(m instanceof $WildcardSequence){if(isCapturing){return rwild(walk(isCapturing,m,nextIndex))}else{return walk(isCapturing,m,nextIndex)}}if(m instanceof $Success){return emptyMatcher}var target;if(isCapturing){target=new $Dict;rupdateInplace(target,__,walk(isCapturing,m.get(__),nextIndex));for(var key in m.entries){if(key!==__){var mk=m.get(key);if(is_keyOpen(key)){function cont(mk2){return walk(isCapturing,mk2,nextIndex)}rupdateInplace(target,key,captureNested(mk,cont))}else if(is_keyClose(key)){}else{rupdateInplace(target,key,walk(isCapturing,mk,nextIndex))}}}}else{target=walk(isCapturing,m.get(__),nextIndex);for(var key in m.entries){if(key!==__){var mk=m.get(key);if(is_keyOpen(key)){function cont(mk2){return walk(isCapturing,mk2,nextIndex)}target=union(target,skipNested(mk,cont))}else if(is_keyClose(key)){}else{target=union(target,walk(isCapturing,mk,nextIndex))}}}}return target}var result;if(m instanceof $WildcardSequence){if(is_keyOpen(item)){result=walk(isCapturing,rwildseq(m),nextIndex)}else if(is_keyClose(item)){result=walk(isCapturing,m.matcher,nextIndex)}else{result=walk(isCapturing,m,nextIndex)}}else if(m instanceof $Success){result=emptyMatcher}else{if(is_keyOpen(item)){result=walk(isCapturing,rwildseq(m.get(__)),nextIndex)}else if(is_keyClose(item)){result=emptyMatcher}else{result=walk(isCapturing,m.get(__),nextIndex)}result=union(result,walk(isCapturing,m.get(item),nextIndex))}if(isCapturing){result=rseq(item,result)}return result}function captureNested(m,cont){if(m instanceof $WildcardSequence){return rwildseq(cont(m.matcher))}if(is_emptyMatcher(m)||m instanceof $Success){return emptyMatcher}var target=new $Dict;rupdateInplace(target,__,captureNested(m.get(__),cont));for(var key in m.entries){if(key!==__){var mk=m.get(key);if(is_keyOpen(key)){function cont2(mk2){return captureNested(mk2,cont)}rupdateInplace(target,key,captureNested(mk,cont2))}else if(is_keyClose(key)){rupdateInplace(target,key,cont(mk))}else{rupdateInplace(target,key,captureNested(mk,cont))}}}return target.emptyGuard()}function skipNested(m,cont){if(m instanceof $WildcardSequence){return cont(m.matcher)}if(is_emptyMatcher(m)||m instanceof $Success){return emptyMatcher}var target=skipNested(m.get(__),cont);for(var key in m.entries){if(key!==__){var mk=m.get(key);if(is_keyOpen(key)){function cont2(mk2){return skipNested(mk2,cont)}target=union(target,skipNested(mk,cont2))}else if(is_keyClose(key)){target=union(target,cont(mk))}else{target=union(target,skipNested(mk,cont))}}}return target}}function matcherKeys(m){if(is_emptyMatcher(m))return[];return walkSeq(m,function(vss,vsk){return vss});function walk(m,k){if(m instanceof $WildcardSequence)return null;if(m instanceof $Success)return[];if(m.has(__))return null;var acc=[];for(var key in m.entries){var mk=m.get(key);var piece;if(is_keyOpen(key)){function seqK(vss,vsk){var acc=[];for(var i=0;i");walk(i+4,m.matcher);return}if(m instanceof $Success){var vs=JSON.stringify(typeof m.value==="object"?setToArray(m.value):m.value);acc.push("{"+vs+"}");return}if(m.length===0){acc.push(" ::: empty hash!");return}var needSep=false;var keys=m.sortedKeys();for(var keyi=0;keyi";acc.push(key);walk(i+key.length+1,k)}}function indentStr(i){return new Array(i+1).join(" ")}}function serializeMatcher(m,serializeSuccess){return walk(m);function walk(m){if(is_emptyMatcher(m))return[];if(m instanceof $WildcardSequence){return["...)",walk(m.matcher)]}if(m instanceof $Success){return["",serializeSuccess(m.value)]}var acc=[];for(var key in m.entries){var k=m.entries[key];if(key===__)key=["__"];else if(key===SOA)key=["("];else if(key===EOA)key=[")"];else key=JSON.parse(key);acc.push([key,walk(k)])}return acc}}function deserializeMatcher(r,deserializeSuccess){return walk(r);function walk(r){if(r.length===0)return emptyMatcher;if(r[0]==="...)")return rwildseq(walk(r[1]));if(r[0]==="")return rsuccess(deserializeSuccess(r[1]));var acc=new $Dict;for(var i=0;i0){while(metaLevels.length0?this.union1(gestaltUnion(arguments)):this};function telescopeLevels(levels){var result=shallowCopyArray(levels);for(var i=result.length-2;i>=0;i--){result[i]=new GestaltLevel(union(result[i].subscriptions,result[i+1].subscriptions),union(result[i].advertisements,result[i+1].advertisements))}return result}Gestalt.prototype.telescoped=function(){var mls=[];for(var i=0;i0){while(outputMetaLevels.lengththis.period*1.5){World.send(this.message)}this.mostRecentTrigger=now};module.exports.WakeDetector=WakeDetector},{"./minimart.js":7}],14:[function(_dereq_,module,exports){var Minimart=_dereq_("./minimart.js");var Codec=_dereq_("./codec.js");var Route=Minimart.Route;var World=Minimart.World;var sub=Minimart.sub;var pub=Minimart.pub;var __=Minimart.__;var _$=Minimart._$;var DEFAULT_RECONNECT_DELAY=100;var MAX_RECONNECT_DELAY=3e4;var DEFAULT_IDLE_TIMEOUT=3e5;var DEFAULT_PING_INTERVAL=DEFAULT_IDLE_TIMEOUT-1e4;function WebSocketConnection(label,wsurl,shouldReconnect){this.label=label;this.sendsAttempted=0;this.sendsTransmitted=0;this.receiveCount=0;this.sock=null;this.wsurl=wsurl;this.shouldReconnect=shouldReconnect?true:false;this.reconnectDelay=DEFAULT_RECONNECT_DELAY;this.localGestalt=Route.emptyGestalt;this.peerGestalt=Route.emptyGestalt;this.prevLocalRoutesMessage=null;this.prevPeerRoutesMessage=null;this.deduplicator=new Minimart.Deduplicator;this.connectionCount=0;this.activityTimestamp=0;this.idleTimeout=DEFAULT_IDLE_TIMEOUT;this.pingInterval=DEFAULT_PING_INTERVAL;this.idleTimer=null;this.pingTimer=null}WebSocketConnection.prototype.clearHeartbeatTimers=function(){if(this.idleTimer){clearTimeout(this.idleTimer);this.idleTimer=null}if(this.pingTimer){clearTimeout(this.pingTimer);this.pingTimer=null}};WebSocketConnection.prototype.recordActivity=function(){var self=this;this.activityTimestamp=+new Date;this.clearHeartbeatTimers();this.idleTimer=setTimeout(function(){self.forceclose()},this.idleTimeout);this.pingTimer=setTimeout(function(){self.safeSend(JSON.stringify("ping"))},this.pingInterval)};WebSocketConnection.prototype.statusRoute=function(status){return pub([this.label+"_state",status])};WebSocketConnection.prototype.relayGestalt=function(){return this.statusRoute(this.isConnected()?"connected":"disconnected").union(pub([this.label,__,__],0,10)).union(sub([this.label,__,__],0,10))};WebSocketConnection.prototype.aggregateGestalt=function(){var self=this;return this.peerGestalt.transform(function(m,metaLevel){return Route.compilePattern(true,[self.label,metaLevel,Route.embeddedMatcher(m)])}).union(this.relayGestalt())};WebSocketConnection.prototype.boot=function(){this.reconnect()};WebSocketConnection.prototype.trapexit=function(){this.forceclose()};WebSocketConnection.prototype.isConnected=function(){return this.sock&&this.sock.readyState===this.sock.OPEN};WebSocketConnection.prototype.safeSend=function(m){try{this.sendsAttempted++;if(this.isConnected()){this.sock.send(m);this.sendsTransmitted++}}catch(e){console.warn("Trapped exn while sending",e)}};WebSocketConnection.prototype.sendLocalRoutes=function(){var newLocalRoutesMessage=JSON.stringify(Codec.encodeEvent(Minimart.updateRoutes([this.localGestalt])));if(this.prevLocalRoutesMessage!==newLocalRoutesMessage){this.prevLocalRoutesMessage=newLocalRoutesMessage;this.safeSend(newLocalRoutesMessage)}};WebSocketConnection.prototype.collectMatchers=function(getAdvertisements,level,g){var extractMetaLevels=Route.compileProjection([this.label,_$,__]);var mls=Route.matcherKeys(g.project(extractMetaLevels,getAdvertisements,0,level));for(var i=0;iMAX_RECONNECT_DELAY?MAX_RECONNECT_DELAY+Math.random()*1e3:this.reconnectDelay}};module.exports.WebSocketConnection=WebSocketConnection},{"./codec.js":2,"./minimart.js":7}],15:[function(_dereq_,module,exports){var Ground=_dereq_("./ground.js").Ground;var Util=_dereq_("./util.js");var Codec=_dereq_("./codec.js");var Minimart=_dereq_("./minimart.js");var World=Minimart.World;var sub=Minimart.sub;var pub=Minimart.pub;var __=Minimart.__;var BuiltinWorker=typeof window!=="undefined"&&window.Worker;function Worker(scriptUrl){this.scriptUrl=scriptUrl;this.w=new BuiltinWorker(scriptUrl)}Worker.prototype.boot=function(){this.w.onmessage=World.wrap(function(e){console.log("Received from worker",JSON.stringify(e.data));World.current().enqueueAction(World.activePid(),Codec.decodeAction(e.data))})};Worker.prototype.handleEvent=function(e){console.log("Sending to worker",JSON.stringify(Codec.encodeEvent(e)));this.w.postMessage(Codec.encodeEvent(e))};function WorkerGround(bootFn){var self=this;Ground.call(this,bootFn);onmessage=function(e){console.log("Received from main page",JSON.stringify(e.data));self.world.handleEvent(Codec.decodeEvent(e.data));self.startStepping()}}WorkerGround.prototype=Util.extend({},Ground.prototype);WorkerGround.prototype.enqueueAction=function(pid,action){console.log("Sending to main page",JSON.stringify(Codec.encodeAction(action)));postMessage(Codec.encodeAction(action));console.log("Sent to main page")};module.exports.Worker=Worker;module.exports.WorkerGround=WorkerGround},{"./codec.js":2,"./ground.js":4,"./minimart.js":7,"./util.js":12}]},{},[6])(6)}); \ No newline at end of file