Files
beimi/client/beimi/temp/1.5.2/scripts-compile-cache/persistify_677326446
2017-08-04 17:31:46 +08:00

1 line
637 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"persistifyArgs":{"cache":{"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\c3\\c3362f07-3cd8-4e58-8025-6ae3c744fd20.js":{"source":"(function (global){\n\"use strict\";\ncc._RF.push(module, 'c33628HPNhOWIAlauPHRP0g', 'socket.io');\n// script/lib/socket.io.js\n\n\"use strict\";\n\nvar _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj; };\n\nif (!cc.sys.isNative) {\n (function (f) {\n if ((typeof exports === \"undefined\" ? \"undefined\" : _typeof(exports)) === \"object\" && typeof module !== \"undefined\") {\n module.exports = f();\n } else if (typeof define === \"function\" && define.amd) {\n define([], f);\n } else {\n var g;if (typeof window !== \"undefined\") {\n g = window;\n } else if (typeof global !== \"undefined\") {\n g = global;\n } else if (typeof self !== \"undefined\") {\n g = self;\n } else {\n g = this;\n }g.io = f();\n }\n })(function () {\n var define, module, exports;return function e(t, n, r) {\n function s(o, u) {\n if (!n[o]) {\n if (!t[o]) {\n var a = typeof require == \"function\" && require;if (!u && a) return a(o, !0);if (i) return i(o, !0);var f = new Error(\"Cannot find module '\" + o + \"'\");throw f.code = \"MODULE_NOT_FOUND\", f;\n }var l = n[o] = { exports: {} };t[o][0].call(l.exports, function (e) {\n var n = t[o][1][e];return s(n ? n : e);\n }, l, l.exports, e, t, n, r);\n }return n[o].exports;\n }var i = typeof require == \"function\" && require;for (var o = 0; o < r.length; o++) {\n s(r[o]);\n }return s;\n }({ 1: [function (_dereq_, module, exports) {\n\n module.exports = _dereq_('./lib/');\n }, { \"./lib/\": 2 }], 2: [function (_dereq_, module, exports) {\n\n module.exports = _dereq_('./socket');\n\n /**\n * Exports parser\n *\n * @api public\n *\n */\n module.exports.parser = _dereq_('engine.io-parser');\n }, { \"./socket\": 3, \"engine.io-parser\": 19 }], 3: [function (_dereq_, module, exports) {\n (function (global) {\n /**\n * Module dependencies.\n */\n\n var transports = _dereq_('./transports');\n var Emitter = _dereq_('component-emitter');\n var debug = _dereq_('debug')('engine.io-client:socket');\n var index = _dereq_('indexof');\n var parser = _dereq_('engine.io-parser');\n var parseuri = _dereq_('parseuri');\n var parsejson = _dereq_('parsejson');\n var parseqs = _dereq_('parseqs');\n\n /**\n * Module exports.\n */\n\n module.exports = Socket;\n\n /**\n * Noop function.\n *\n * @api private\n */\n\n function noop() {}\n\n /**\n * Socket constructor.\n *\n * @param {String|Object} uri or options\n * @param {Object} options\n * @api public\n */\n\n function Socket(uri, opts) {\n if (!(this instanceof Socket)) return new Socket(uri, opts);\n\n opts = opts || {};\n\n if (uri && 'object' == (typeof uri === \"undefined\" ? \"undefined\" : _typeof(uri))) {\n opts = uri;\n uri = null;\n }\n\n if (uri) {\n uri = parseuri(uri);\n opts.hostname = uri.host;\n opts.secure = uri.protocol == 'https' || uri.protocol == 'wss';\n opts.port = uri.port;\n if (uri.query) opts.query = uri.query;\n } else if (opts.host) {\n opts.hostname = parseuri(opts.host).host;\n }\n\n this.secure = null != opts.secure ? opts.secure : global.location && 'https:' == location.protocol;\n\n if (opts.hostname && !opts.port) {\n // if no port is specified manually, use the protocol default\n opts.port = this.secure ? '443' : '80';\n }\n\n this.agent = opts.agent || false;\n this.hostname = opts.hostname || (global.location ? location.hostname : 'localhost');\n this.port = opts.port || (global.location && location.port ? location.port : this.secure ? 443 : 80);\n this.query = opts.query || {};\n if ('string' == typeof this.query) this.query = parseqs.decode(this.query);\n this.upgrade = false !== opts.upgrade;\n this.path = (opts.path || '/engine.io').replace(/\\/$/, '') + '/';\n this.forceJSONP = !!opts.forceJSONP;\n this.jsonp = false !== opts.jsonp;\n this.forceBase64 = !!opts.forceBase64;\n this.enablesXDR = !!opts.enablesXDR;\n this.timestampParam = opts.timestampParam || 't';\n this.timestampRequests = opts.timestampRequests;\n this.transports = opts.transports || ['polling', 'websocket'];\n this.readyState = '';\n this.writeBuffer = [];\n this.policyPort = opts.policyPort || 843;\n this.rememberUpgrade = opts.rememberUpgrade || false;\n this.binaryType = null;\n this.onlyBinaryUpgrades = opts.onlyBinaryUpgrades;\n this.perMessageDeflate = false !== opts.perMessageDeflate ? opts.perMessageDeflate || {} : false;\n\n if (true === this.perMessageDeflate) this.perMessageDeflate = {};\n if (this.perMessageDeflate && null == this.perMessageDeflate.threshold) {\n this.perMessageDeflate.threshold = 1024;\n }\n\n // SSL options for Node.js client\n this.pfx = opts.pfx || null;\n this.key = opts.key || null;\n this.passphrase = opts.passphrase || null;\n this.cert = opts.cert || null;\n this.ca = opts.ca || null;\n this.ciphers = opts.ciphers || null;\n this.rejectUnauthorized = opts.rejectUnauthorized === undefined ? null : opts.rejectUnauthorized;\n\n // other options for Node.js client\n var freeGlobal = (typeof global === \"undefined\" ? \"undefined\" : _typeof(global)) == 'object' && global;\n if (freeGlobal.global === freeGlobal) {\n if (opts.extraHeaders && Object.keys(opts.extraHeaders).length > 0) {\n this.extraHeaders = opts.extraHeaders;\n }\n }\n\n this.open();\n }\n\n Socket.priorWebsocketSuccess = false;\n\n /**\n * Mix in `Emitter`.\n */\n\n Emitter(Socket.prototype);\n\n /**\n * Protocol version.\n *\n * @api public\n */\n\n Socket.protocol = parser.protocol; // this is an int\n\n /**\n * Expose deps for legacy compatibility\n * and standalone browser access.\n */\n\n Socket.Socket = Socket;\n Socket.Transport = _dereq_('./transport');\n Socket.transports = _dereq_('./transports');\n Socket.parser = _dereq_('engine.io-parser');\n\n /**\n * Creates transport of the given type.\n *\n * @param {String} transport name\n * @return {Transport}\n * @api private\n */\n\n Socket.prototype.createTransport = function (name) {\n debug('creating transport \"%s\"', name);\n var query = clone(this.query);\n\n // append engine.io protocol identifier\n query.EIO = parser.protocol;\n\n // transport name\n query.transport = name;\n\n // session id if we already have one\n if (this.id) query.sid = this.id;\n\n var transport = new transports[name]({\n agent: this.agent,\n hostname: this.hostname,\n port: this.port,\n secure: this.secure,\n path: this.path,\n query: query,\n forceJSONP: this.forceJSONP,\n jsonp: this.jsonp,\n forceBase64: this.forceBase64,\n enablesXDR: this.enablesXDR,\n timestampRequests: this.timestampRequests,\n timestampParam: this.timestampParam,\n policyPort: this.policyPort,\n socket: this,\n pfx: this.pfx,\n key: this.key,\n passphrase: this.passphrase,\n cert: this.cert,\n ca: this.ca,\n ciphers: this.ciphers,\n rejectUnauthorized: this.rejectUnauthorized,\n perMessageDeflate: this.perMessageDeflate,\n extraHeaders: this.extraHeaders\n });\n\n return transport;\n };\n\n function clone(obj) {\n var o = {};\n for (var i in obj) {\n if (obj.hasOwnProperty(i)) {\n o[i] = obj[i];\n }\n }\n return o;\n }\n\n /**\n * Initializes transport to use and starts probe.\n *\n * @api private\n */\n Socket.prototype.open = function () {\n var transport;\n if (this.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf('websocket') != -1) {\n transport = 'websocket';\n } else if (0 === this.transports.length) {\n // Emit error on next tick so it can be listened to\n var self = this;\n setTimeout(function () {\n self.emit('error', 'No transports available');\n }, 0);\n return;\n } else {\n transport = this.transports[0];\n }\n this.readyState = 'opening';\n\n // Retry with the next transport if the transport is disabled (jsonp: false)\n try {\n transport = this.createTransport(transport);\n } catch (e) {\n this.transports.shift();\n this.open();\n return;\n }\n\n transport.open();\n this.setTransport(transport);\n };\n\n /**\n * Sets the current transport. Disables the existing one (if any).\n *\n * @api private\n */\n\n Socket.prototype.setTransport = function (transport) {\n debug('setting transport %s', transport.name);\n var self = this;\n\n if (this.transport) {\n debug('clearing existing transport %s', this.transport.name);\n this.transport.removeAllListeners();\n }\n\n // set up transport\n this.transport = transport;\n\n // set up transport listeners\n transport.on('drain', function () {\n self.onDrain();\n }).on('packet', function (packet) {\n self.onPacket(packet);\n }).on('error', function (e) {\n self.onError(e);\n }).on('close', function () {\n self.onClose('transport close');\n });\n };\n\n /**\n * Probes a transport.\n *\n * @param {String} transport name\n * @api private\n */\n\n Socket.prototype.probe = function (name) {\n debug('probing transport \"%s\"', name);\n var transport = this.createTransport(name, { probe: 1 }),\n failed = false,\n self = this;\n\n Socket.priorWebsocketSuccess = false;\n\n function onTransportOpen() {\n if (self.onlyBinaryUpgrades) {\n var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary;\n failed = failed || upgradeLosesBinary;\n }\n if (failed) return;\n\n debug('probe transport \"%s\" opened', name);\n transport.send([{ type: 'ping', data: 'probe' }]);\n transport.once('packet', function (msg) {\n if (failed) return;\n if ('pong' == msg.type && 'probe' == msg.data) {\n debug('probe transport \"%s\" pong', name);\n self.upgrading = true;\n self.emit('upgrading', transport);\n if (!transport) return;\n Socket.priorWebsocketSuccess = 'websocket' == transport.name;\n\n debug('pausing current transport \"%s\"', self.transport.name);\n self.transport.pause(function () {\n if (failed) return;\n if ('closed' == self.readyState) return;\n debug('changing transport and sending upgrade packet');\n\n cleanup();\n\n self.setTransport(transport);\n transport.send([{ type: 'upgrade' }]);\n self.emit('upgrade', transport);\n transport = null;\n self.upgrading = false;\n self.flush();\n });\n } else {\n debug('probe transport \"%s\" failed', name);\n var err = new Error('probe error');\n err.transport = transport.name;\n self.emit('upgradeError', err);\n }\n });\n }\n\n function freezeTransport() {\n if (failed) return;\n\n // Any callback called by transport should be ignored since now\n failed = true;\n\n cleanup();\n\n transport.close();\n transport = null;\n }\n\n //Handle any error that happens while probing\n function onerror(err) {\n var error = new Error('probe error: ' + err);\n error.transport = transport.name;\n\n freezeTransport();\n\n debug('probe transport \"%s\" failed because of error: %s', name, err);\n\n self.emit('upgradeError', error);\n }\n\n function onTransportClose() {\n onerror(\"transport closed\");\n }\n\n //When the socket is closed while we're probing\n function onclose() {\n onerror(\"socket closed\");\n }\n\n //When the socket is upgraded while we're probing\n function onupgrade(to) {\n if (transport && to.name != transport.name) {\n debug('\"%s\" works - aborting \"%s\"', to.name, transport.name);\n freezeTransport();\n }\n }\n\n //Remove all listeners on the transport and on self\n function cleanup() {\n transport.removeListener('open', onTransportOpen);\n transport.removeListener('error', onerror);\n transport.removeListener('close', onTransportClose);\n self.removeListener('close', onclose);\n self.removeListener('upgrading', onupgrade);\n }\n\n transport.once('open', onTransportOpen);\n transport.once('error', onerror);\n transport.once('close', onTransportClose);\n\n this.once('close', onclose);\n this.once('upgrading', onupgrade);\n\n transport.open();\n };\n\n /**\n * Called when connection is deemed open.\n *\n * @api public\n */\n\n Socket.prototype.onOpen = function () {\n debug('socket open');\n this.readyState = 'open';\n Socket.priorWebsocketSuccess = 'websocket' == this.transport.name;\n this.emit('open');\n this.flush();\n\n // we check for `readyState` in case an `open`\n // listener already closed the socket\n if ('open' == this.readyState && this.upgrade && this.transport.pause) {\n debug('starting upgrade probes');\n for (var i = 0, l = this.upgrades.length; i < l; i++) {\n this.probe(this.upgrades[i]);\n }\n }\n };\n\n /**\n * Handles a packet.\n *\n * @api private\n */\n\n Socket.prototype.onPacket = function (packet) {\n if ('opening' == this.readyState || 'open' == this.readyState) {\n debug('socket receive: type \"%s\", data \"%s\"', packet.type, packet.data);\n\n this.emit('packet', packet);\n\n // Socket is live - any packet counts\n this.emit('heartbeat');\n\n switch (packet.type) {\n case 'open':\n this.onHandshake(parsejson(packet.data));\n break;\n\n case 'pong':\n this.setPing();\n this.emit('pong');\n break;\n\n case 'error':\n var err = new Error('server error');\n err.code = packet.data;\n this.onError(err);\n break;\n\n case 'message':\n this.emit('data', packet.data);\n this.emit('message', packet.data);\n break;\n }\n } else {\n debug('packet received with socket readyState \"%s\"', this.readyState);\n }\n };\n\n /**\n * Called upon handshake completion.\n *\n * @param {Object} handshake obj\n * @api private\n */\n\n Socket.prototype.onHandshake = function (data) {\n this.emit('handshake', data);\n this.id = data.sid;\n this.transport.query.sid = data.sid;\n this.upgrades = this.filterUpgrades(data.upgrades);\n this.pingInterval = data.pingInterval;\n this.pingTimeout = data.pingTimeout;\n this.onOpen();\n // In case open handler closes socket\n if ('closed' == this.readyState) return;\n this.setPing();\n\n // Prolong liveness of socket on heartbeat\n this.removeListener('heartbeat', this.onHeartbeat);\n this.on('heartbeat', this.onHeartbeat);\n };\n\n /**\n * Resets ping timeout.\n *\n * @api private\n */\n\n Socket.prototype.onHeartbeat = function (timeout) {\n clearTimeout(this.pingTimeoutTimer);\n var self = this;\n self.pingTimeoutTimer = setTimeout(function () {\n if ('closed' == self.readyState) return;\n self.onClose('ping timeout');\n }, timeout || self.pingInterval + self.pingTimeout);\n };\n\n /**\n * Pings server every `this.pingInterval` and expects response\n * within `this.pingTimeout` or closes connection.\n *\n * @api private\n */\n\n Socket.prototype.setPing = function () {\n var self = this;\n clearTimeout(self.pingIntervalTimer);\n self.pingIntervalTimer = setTimeout(function () {\n debug('writing ping packet - expecting pong within %sms', self.pingTimeout);\n self.ping();\n self.onHeartbeat(self.pingTimeout);\n }, self.pingInterval);\n };\n\n /**\n * Sends a ping packet.\n *\n * @api private\n */\n\n Socket.prototype.ping = function () {\n var self = this;\n this.sendPacket('ping', function () {\n self.emit('ping');\n });\n };\n\n /**\n * Called on `drain` event\n *\n * @api private\n */\n\n Socket.prototype.onDrain = function () {\n this.writeBuffer.splice(0, this.prevBufferLen);\n\n // setting prevBufferLen = 0 is very important\n // for example, when upgrading, upgrade packet is sent over,\n // and a nonzero prevBufferLen could cause problems on `drain`\n this.prevBufferLen = 0;\n\n if (0 === this.writeBuffer.length) {\n this.emit('drain');\n } else {\n this.flush();\n }\n };\n\n /**\n * Flush write buffers.\n *\n * @api private\n */\n\n Socket.prototype.flush = function () {\n if ('closed' != this.readyState && this.transport.writable && !this.upgrading && this.writeBuffer.length) {\n debug('flushing %d packets in socket', this.writeBuffer.length);\n this.transport.send(this.writeBuffer);\n // keep track of current length of writeBuffer\n // splice writeBuffer and callbackBuffer on `drain`\n this.prevBufferLen = this.writeBuffer.length;\n this.emit('flush');\n }\n };\n\n /**\n * Sends a message.\n *\n * @param {String} message.\n * @param {Function} callback function.\n * @param {Object} options.\n * @return {Socket} for chaining.\n * @api public\n */\n\n Socket.prototype.write = Socket.prototype.send = function (msg, options, fn) {\n this.sendPacket('message', msg, options, fn);\n return this;\n };\n\n /**\n * Sends a packet.\n *\n * @param {String} packet type.\n * @param {String} data.\n * @param {Object} options.\n * @param {Function} callback function.\n * @api private\n */\n\n Socket.prototype.sendPacket = function (type, data, options, fn) {\n if ('function' == typeof data) {\n fn = data;\n data = undefined;\n }\n\n if ('function' == typeof options) {\n fn = options;\n options = null;\n }\n\n if ('closing' == this.readyState || 'closed' == this.readyState) {\n return;\n }\n\n options = options || {};\n options.compress = false !== options.compress;\n\n var packet = {\n type: type,\n data: data,\n options: options\n };\n this.emit('packetCreate', packet);\n this.writeBuffer.push(packet);\n if (fn) this.once('flush', fn);\n this.flush();\n };\n\n /**\n * Closes the connection.\n *\n * @api private\n */\n\n Socket.prototype.close = function () {\n if ('opening' == this.readyState || 'open' == this.readyState) {\n this.readyState = 'closing';\n\n var self = this;\n\n if (this.writeBuffer.length) {\n this.once('drain', function () {\n if (this.upgrading) {\n waitForUpgrade();\n } else {\n close();\n }\n });\n } else if (this.upgrading) {\n waitForUpgrade();\n } else {\n close();\n }\n }\n\n function close() {\n self.onClose('forced close');\n debug('socket closing - telling transport to close');\n self.transport.close();\n }\n\n function cleanupAndClose() {\n self.removeListener('upgrade', cleanupAndClose);\n self.removeListener('upgradeError', cleanupAndClose);\n close();\n }\n\n function waitForUpgrade() {\n // wait for upgrade to finish since we can't send packets while pausing a transport\n self.once('upgrade', cleanupAndClose);\n self.once('upgradeError', cleanupAndClose);\n }\n\n return this;\n };\n\n /**\n * Called upon transport error\n *\n * @api private\n */\n\n Socket.prototype.onError = function (err) {\n debug('socket error %j', err);\n Socket.priorWebsocketSuccess = false;\n this.emit('error', err);\n this.onClose('transport error', err);\n };\n\n /**\n * Called upon transport close.\n *\n * @api private\n */\n\n Socket.prototype.onClose = function (reason, desc) {\n if ('opening' == this.readyState || 'open' == this.readyState || 'closing' == this.readyState) {\n debug('socket close with reason: \"%s\"', reason);\n var self = this;\n\n // clear timers\n clearTimeout(this.pingIntervalTimer);\n clearTimeout(this.pingTimeoutTimer);\n\n // stop event from firing again for transport\n this.transport.removeAllListeners('close');\n\n // ensure transport won't stay open\n this.transport.close();\n\n // ignore further transport communication\n this.transport.removeAllListeners();\n\n // set ready state\n this.readyState = 'closed';\n\n // clear session id\n this.id = null;\n\n // emit close event\n this.emit('close', reason, desc);\n\n // clean buffers after, so users can still\n // grab the buffers on `close` event\n self.writeBuffer = [];\n self.prevBufferLen = 0;\n }\n };\n\n /**\n * Filters upgrades, returning only those matching client transports.\n *\n * @param {Array} server upgrades\n * @api private\n *\n */\n\n Socket.prototype.filterUpgrades = function (upgrades) {\n var filteredUpgrades = [];\n for (var i = 0, j = upgrades.length; i < j; i++) {\n if (\\x7eindex(this.transports, upgrades[i])) filteredUpgrades.push(upgrades[i]);\n }\n return filteredUpgrades;\n };\n }).call(this, typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n }, { \"./transport\": 4, \"./transports\": 5, \"component-emitter\": 15, \"debug\": 17, \"engine.io-parser\": 19, \"indexof\": 23, \"parsejson\": 26, \"parseqs\": 27, \"parseuri\": 28 }], 4: [function (_dereq_, module, exports) {\n /**\n * Module dependencies.\n */\n\n var parser = _dereq_('engine.io-parser');\n var Emitter = _dereq_('component-emitter');\n\n /**\n * Module exports.\n */\n\n module.exports = Transport;\n\n /**\n * Transport abstract constructor.\n *\n * @param {Object} options.\n * @api private\n */\n\n function Transport(opts) {\n this.path = opts.path;\n this.hostname = opts.hostname;\n this.port = opts.port;\n this.secure = opts.secure;\n this.query = opts.query;\n this.timestampParam = opts.timestampParam;\n this.timestampRequests = opts.timestampRequests;\n this.readyState = '';\n this.agent = opts.agent || false;\n this.socket = opts.socket;\n this.enablesXDR = opts.enablesXDR;\n\n // SSL options for Node.js client\n this.pfx = opts.pfx;\n this.key = opts.key;\n this.passphrase = opts.passphrase;\n this.cert = opts.cert;\n this.ca = opts.ca;\n this.ciphers = opts.ciphers;\n this.rejectUnauthorized = opts.rejectUnauthorized;\n\n // other options for Node.js client\n this.extraHeaders = opts.extraHeaders;\n }\n\n /**\n * Mix in `Emitter`.\n */\n\n Emitter(Transport.prototype);\n\n /**\n * Emits an error.\n *\n * @param {String} str\n * @return {Transport} for chaining\n * @api public\n */\n\n Transport.prototype.onError = function (msg, desc) {\n var err = new Error(msg);\n err.type = 'TransportError';\n err.description = desc;\n this.emit('error', err);\n return this;\n };\n\n /**\n * Opens the transport.\n *\n * @api public\n */\n\n Transport.prototype.open = function () {\n if ('closed' == this.readyState || '' == this.readyState) {\n this.readyState = 'opening';\n this.doOpen();\n }\n\n return this;\n };\n\n /**\n * Closes the transport.\n *\n * @api private\n */\n\n Transport.prototype.close = function () {\n if ('opening' == this.readyState || 'open' == this.readyState) {\n this.doClose();\n this.onClose();\n }\n\n return this;\n };\n\n /**\n * Sends multiple packets.\n *\n * @param {Array} packets\n * @api private\n */\n\n Transport.prototype.send = function (packets) {\n if ('open' == this.readyState) {\n this.write(packets);\n } else {\n throw new Error('Transport not open');\n }\n };\n\n /**\n * Called upon open\n *\n * @api private\n */\n\n Transport.prototype.onOpen = function () {\n this.readyState = 'open';\n this.writable = true;\n this.emit('open');\n };\n\n /**\n * Called with data.\n *\n * @param {String} data\n * @api private\n */\n\n Transport.prototype.onData = function (data) {\n var packet = parser.decodePacket(data, this.socket.binaryType);\n this.onPacket(packet);\n };\n\n /**\n * Called with a decoded packet.\n */\n\n Transport.prototype.onPacket = function (packet) {\n this.emit('packet', packet);\n };\n\n /**\n * Called upon close.\n *\n * @api private\n */\n\n Transport.prototype.onClose = function () {\n this.readyState = 'closed';\n this.emit('close');\n };\n }, { \"component-emitter\": 15, \"engine.io-parser\": 19 }], 5: [function (_dereq_, module, exports) {\n (function (global) {\n /**\n * Module dependencies\n */\n\n var XMLHttpRequest = _dereq_('xmlhttprequest-ssl');\n var XHR = _dereq_('./polling-xhr');\n var JSONP = _dereq_('./polling-jsonp');\n var websocket = _dereq_('./websocket');\n\n /**\n * Export transports.\n */\n\n exports.polling = polling;\n exports.websocket = websocket;\n\n /**\n * Polling transport polymorphic constructor.\n * Decides on xhr vs jsonp based on feature detection.\n *\n * @api private\n */\n\n function polling(opts) {\n var xhr;\n var xd = false;\n var xs = false;\n var jsonp = false !== opts.jsonp;\n\n if (global.location) {\n var isSSL = 'https:' == location.protocol;\n var port = location.port;\n\n // some user agents have empty `location.port`\n if (!port) {\n port = isSSL ? 443 : 80;\n }\n\n xd = opts.hostname != location.hostname || port != opts.port;\n xs = opts.secure != isSSL;\n }\n\n opts.xdomain = xd;\n opts.xscheme = xs;\n xhr = new XMLHttpRequest(opts);\n\n if ('open' in xhr && !opts.forceJSONP) {\n return new XHR(opts);\n } else {\n if (!jsonp) throw new Error('JSONP disabled');\n return new JSONP(opts);\n }\n }\n }).call(this, typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n }, { \"./polling-jsonp\": 6, \"./polling-xhr\": 7, \"./websocket\": 9, \"xmlhttprequest-ssl\": 10 }], 6: [function (_dereq_, module, exports) {\n (function (global) {\n\n /**\n * Module requirements.\n */\n\n var Polling = _dereq_('./polling');\n var inherit = _dereq_('component-inherit');\n\n /**\n * Module exports.\n */\n\n module.exports = JSONPPolling;\n\n /**\n * Cached regular expressions.\n */\n\n var rNewline = /\\n/g;\n var rEscapedNewline = /\\\\n/g;\n\n /**\n * Global JSONP callbacks.\n */\n\n var callbacks;\n\n /**\n * Callbacks count.\n */\n\n var index = 0;\n\n /**\n * Noop.\n */\n\n function empty() {}\n\n /**\n * JSONP Polling constructor.\n *\n * @param {Object} opts.\n * @api public\n */\n\n function JSONPPolling(opts) {\n Polling.call(this, opts);\n\n this.query = this.query || {};\n\n // define global callbacks array if not present\n // we do this here (lazily) to avoid unneeded global pollution\n if (!callbacks) {\n // we need to consider multiple engines in the same page\n if (!global.___eio) global.___eio = [];\n callbacks = global.___eio;\n }\n\n // callback identifier\n this.index = callbacks.length;\n\n // add callback to jsonp global\n var self = this;\n callbacks.push(function (msg) {\n self.onData(msg);\n });\n\n // append to query string\n this.query.j = this.index;\n\n // prevent spurious errors from being emitted when the window is unloaded\n if (global.document && global.addEventListener) {\n global.addEventListener('beforeunload', function () {\n if (self.script) self.script.onerror = empty;\n }, false);\n }\n }\n\n /**\n * Inherits from Polling.\n */\n\n inherit(JSONPPolling, Polling);\n\n /*\n * JSONP only supports binary as base64 encoded strings\n */\n\n JSONPPolling.prototype.supportsBinary = false;\n\n /**\n * Closes the socket.\n *\n * @api private\n */\n\n JSONPPolling.prototype.doClose = function () {\n if (this.script) {\n this.script.parentNode.removeChild(this.script);\n this.script = null;\n }\n\n if (this.form) {\n this.form.parentNode.removeChild(this.form);\n this.form = null;\n this.iframe = null;\n }\n\n Polling.prototype.doClose.call(this);\n };\n\n /**\n * Starts a poll cycle.\n *\n * @api private\n */\n\n JSONPPolling.prototype.doPoll = function () {\n var self = this;\n var script = document.createElement('script');\n\n if (this.script) {\n this.script.parentNode.removeChild(this.script);\n this.script = null;\n }\n\n script.async = true;\n script.src = this.uri();\n script.onerror = function (e) {\n self.onError('jsonp poll error', e);\n };\n\n var insertAt = document.getElementsByTagName('script')[0];\n if (insertAt) {\n insertAt.parentNode.insertBefore(script, insertAt);\n } else {\n (document.head || document.body).appendChild(script);\n }\n this.script = script;\n\n var isUAgecko = 'undefined' != typeof navigator && /gecko/i.test(navigator.userAgent);\n\n if (isUAgecko) {\n setTimeout(function () {\n var iframe = document.createElement('iframe');\n document.body.appendChild(iframe);\n document.body.removeChild(iframe);\n }, 100);\n }\n };\n\n /**\n * Writes with a hidden iframe.\n *\n * @param {String} data to send\n * @param {Function} called upon flush.\n * @api private\n */\n\n JSONPPolling.prototype.doWrite = function (data, fn) {\n var self = this;\n\n if (!this.form) {\n var form = document.createElement('form');\n var area = document.createElement('textarea');\n var id = this.iframeId = 'eio_iframe_' + this.index;\n var iframe;\n\n form.className = 'socketio';\n form.style.position = 'absolute';\n form.style.top = '-1000px';\n form.style.left = '-1000px';\n form.target = id;\n form.method = 'POST';\n form.setAttribute('accept-charset', 'utf-8');\n area.name = 'd';\n form.appendChild(area);\n document.body.appendChild(form);\n\n this.form = form;\n this.area = area;\n }\n\n this.form.action = this.uri();\n\n function complete() {\n initIframe();\n fn();\n }\n\n function initIframe() {\n if (self.iframe) {\n try {\n self.form.removeChild(self.iframe);\n } catch (e) {\n self.onError('jsonp polling iframe removal error', e);\n }\n }\n\n try {\n // ie6 dynamic iframes with target=\"\" support (thanks Chris Lambacher)\n var html = '<iframe src=\"javascript:0\" name=\"' + self.iframeId + '\">';\n iframe = document.createElement(html);\n } catch (e) {\n iframe = document.createElement('iframe');\n iframe.name = self.iframeId;\n iframe.src = 'javascript:0';\n }\n\n iframe.id = self.iframeId;\n\n self.form.appendChild(iframe);\n self.iframe = iframe;\n }\n\n initIframe();\n\n // escape \\n to prevent it from being converted into \\r\\n by some UAs\n // double escaping is required for escaped new lines because unescaping of new lines can be done safely on server-side\n data = data.replace(rEscapedNewline, '\\\\\\n');\n this.area.value = data.replace(rNewline, '\\\\n');\n\n try {\n this.form.submit();\n } catch (e) {}\n\n if (this.iframe.attachEvent) {\n this.iframe.onreadystatechange = function () {\n if (self.iframe.readyState == 'complete') {\n complete();\n }\n };\n } else {\n this.iframe.onload = complete;\n }\n };\n }).call(this, typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n }, { \"./polling\": 8, \"component-inherit\": 16 }], 7: [function (_dereq_, module, exports) {\n (function (global) {\n /**\n * Module requirements.\n */\n\n var XMLHttpRequest = _dereq_('xmlhttprequest-ssl');\n var Polling = _dereq_('./polling');\n var Emitter = _dereq_('component-emitter');\n var inherit = _dereq_('component-inherit');\n var debug = _dereq_('debug')('engine.io-client:polling-xhr');\n\n /**\n * Module exports.\n */\n\n module.exports = XHR;\n module.exports.Request = Request;\n\n /**\n * Empty function\n */\n\n function empty() {}\n\n /**\n * XHR Polling constructor.\n *\n * @param {Object} opts\n * @api public\n */\n\n function XHR(opts) {\n Polling.call(this, opts);\n\n if (global.location) {\n var isSSL = 'https:' == location.protocol;\n var port = location.port;\n\n // some user agents have empty `location.port`\n if (!port) {\n port = isSSL ? 443 : 80;\n }\n\n this.xd = opts.hostname != global.location.hostname || port != opts.port;\n this.xs = opts.secure != isSSL;\n } else {\n this.extraHeaders = opts.extraHeaders;\n }\n }\n\n /**\n * Inherits from Polling.\n */\n\n inherit(XHR, Polling);\n\n /**\n * XHR supports binary\n */\n\n XHR.prototype.supportsBinary = true;\n\n /**\n * Creates a request.\n *\n * @param {String} method\n * @api private\n */\n\n XHR.prototype.request = function (opts) {\n opts = opts || {};\n opts.uri = this.uri();\n opts.xd = this.xd;\n opts.xs = this.xs;\n opts.agent = this.agent || false;\n opts.supportsBinary = this.supportsBinary;\n opts.enablesXDR = this.enablesXDR;\n\n // SSL options for Node.js client\n opts.pfx = this.pfx;\n opts.key = this.key;\n opts.passphrase = this.passphrase;\n opts.cert = this.cert;\n opts.ca = this.ca;\n opts.ciphers = this.ciphers;\n opts.rejectUnauthorized = this.rejectUnauthorized;\n\n // other options for Node.js client\n opts.extraHeaders = this.extraHeaders;\n\n return new Request(opts);\n };\n\n /**\n * Sends data.\n *\n * @param {String} data to send.\n * @param {Function} called upon flush.\n * @api private\n */\n\n XHR.prototype.doWrite = function (data, fn) {\n var isBinary = typeof data !== 'string' && data !== undefined;\n var req = this.request({ method: 'POST', data: data, isBinary: isBinary });\n var self = this;\n req.on('success', fn);\n req.on('error', function (err) {\n self.onError('xhr post error', err);\n });\n this.sendXhr = req;\n };\n\n /**\n * Starts a poll cycle.\n *\n * @api private\n */\n\n XHR.prototype.doPoll = function () {\n debug('xhr poll');\n var req = this.request();\n var self = this;\n req.on('data', function (data) {\n self.onData(data);\n });\n req.on('error', function (err) {\n self.onError('xhr poll error', err);\n });\n this.pollXhr = req;\n };\n\n /**\n * Request constructor\n *\n * @param {Object} options\n * @api public\n */\n\n function Request(opts) {\n this.method = opts.method || 'GET';\n this.uri = opts.uri;\n this.xd = !!opts.xd;\n this.xs = !!opts.xs;\n this.async = false !== opts.async;\n this.data = undefined != opts.data ? opts.data : null;\n this.agent = opts.agent;\n this.isBinary = opts.isBinary;\n this.supportsBinary = opts.supportsBinary;\n this.enablesXDR = opts.enablesXDR;\n\n // SSL options for Node.js client\n this.pfx = opts.pfx;\n this.key = opts.key;\n this.passphrase = opts.passphrase;\n this.cert = opts.cert;\n this.ca = opts.ca;\n this.ciphers = opts.ciphers;\n this.rejectUnauthorized = opts.rejectUnauthorized;\n\n // other options for Node.js client\n this.extraHeaders = opts.extraHeaders;\n\n this.create();\n }\n\n /**\n * Mix in `Emitter`.\n */\n\n Emitter(Request.prototype);\n\n /**\n * Creates the XHR object and sends the request.\n *\n * @api private\n */\n\n Request.prototype.create = function () {\n var opts = { agent: this.agent, xdomain: this.xd, xscheme: this.xs, enablesXDR: this.enablesXDR };\n\n // SSL options for Node.js client\n opts.pfx = this.pfx;\n opts.key = this.key;\n opts.passphrase = this.passphrase;\n opts.cert = this.cert;\n opts.ca = this.ca;\n opts.ciphers = this.ciphers;\n opts.rejectUnauthorized = this.rejectUnauthorized;\n\n var xhr = this.xhr = new XMLHttpRequest(opts);\n var self = this;\n\n try {\n debug('xhr open %s: %s', this.method, this.uri);\n xhr.open(this.method, this.uri, this.async);\n try {\n if (this.extraHeaders) {\n xhr.setDisableHeaderCheck(true);\n for (var i in this.extraHeaders) {\n if (this.extraHeaders.hasOwnProperty(i)) {\n xhr.setRequestHeader(i, this.extraHeaders[i]);\n }\n }\n }\n } catch (e) {}\n if (this.supportsBinary) {\n // This has to be done after open because Firefox is stupid\n // http://stackoverflow.com/questions/13216903/get-binary-data-with-xmlhttprequest-in-a-firefox-extension\n xhr.responseType = 'arraybuffer';\n }\n\n if ('POST' == this.method) {\n try {\n if (this.isBinary) {\n xhr.setRequestHeader('Content-type', 'application/octet-stream');\n } else {\n xhr.setRequestHeader('Content-type', 'text/plain;charset=UTF-8');\n }\n } catch (e) {}\n }\n\n // ie6 check\n if ('withCredentials' in xhr) {\n xhr.withCredentials = true;\n }\n\n if (this.hasXDR()) {\n xhr.onload = function () {\n self.onLoad();\n };\n xhr.onerror = function () {\n self.onError(xhr.responseText);\n };\n } else {\n xhr.onreadystatechange = function () {\n if (4 != xhr.readyState) return;\n if (200 == xhr.status || 1223 == xhr.status) {\n self.onLoad();\n } else {\n // make sure the `error` event handler that's user-set\n // does not throw in the same tick and gets caught here\n setTimeout(function () {\n self.onError(xhr.status);\n }, 0);\n }\n };\n }\n\n debug('xhr data %s', this.data);\n xhr.send(this.data);\n } catch (e) {\n // Need to defer since .create() is called directly fhrom the constructor\n // and thus the 'error' event can only be only bound *after* this exception\n // occurs. Therefore, also, we cannot throw here at all.\n setTimeout(function () {\n self.onError(e);\n }, 0);\n return;\n }\n\n if (global.document) {\n this.index = Request.requestsCount++;\n Request.requests[this.index] = this;\n }\n };\n\n /**\n * Called upon successful response.\n *\n * @api private\n */\n\n Request.prototype.onSuccess = function () {\n this.emit('success');\n this.cleanup();\n };\n\n /**\n * Called if we have data.\n *\n * @api private\n */\n\n Request.prototype.onData = function (data) {\n this.emit('data', data);\n this.onSuccess();\n };\n\n /**\n * Called upon error.\n *\n * @api private\n */\n\n Request.prototype.onError = function (err) {\n this.emit('error', err);\n this.cleanup(true);\n };\n\n /**\n * Cleans up house.\n *\n * @api private\n */\n\n Request.prototype.cleanup = function (fromError) {\n if ('undefined' == typeof this.xhr || null === this.xhr) {\n return;\n }\n // xmlhttprequest\n if (this.hasXDR()) {\n this.xhr.onload = this.xhr.onerror = empty;\n } else {\n this.xhr.onreadystatechange = empty;\n }\n\n if (fromError) {\n try {\n this.xhr.abort();\n } catch (e) {}\n }\n\n if (global.document) {\n delete Request.requests[this.index];\n }\n\n this.xhr = null;\n };\n\n /**\n * Called upon load.\n *\n * @api private\n */\n\n Request.prototype.onLoad = function () {\n var data;\n try {\n var contentType;\n try {\n contentType = this.xhr.getResponseHeader('Content-Type').split(';')[0];\n } catch (e) {}\n if (contentType === 'application/octet-stream') {\n data = this.xhr.response;\n } else {\n if (!this.supportsBinary) {\n data = this.xhr.responseText;\n } else {\n try {\n data = String.fromCharCode.apply(null, new Uint8Array(this.xhr.response));\n } catch (e) {\n var ui8Arr = new Uint8Array(this.xhr.response);\n var dataArray = [];\n for (var idx = 0, length = ui8Arr.length; idx < length; idx++) {\n dataArray.push(ui8Arr[idx]);\n }\n\n data = String.fromCharCode.apply(null, dataArray);\n }\n }\n }\n } catch (e) {\n this.onError(e);\n }\n if (null != data) {\n this.onData(data);\n }\n };\n\n /**\n * Check if it has XDomainRequest.\n *\n * @api private\n */\n\n Request.prototype.hasXDR = function () {\n return 'undefined' !== typeof global.XDomainRequest && !this.xs && this.enablesXDR;\n };\n\n /**\n * Aborts the request.\n *\n * @api public\n */\n\n Request.prototype.abort = function () {\n this.cleanup();\n };\n\n /**\n * Aborts pending requests when unloading the window. This is needed to prevent\n * memory leaks (e.g. when using IE) and to ensure that no spurious error is\n * emitted.\n */\n\n if (global.document) {\n Request.requestsCount = 0;\n Request.requests = {};\n if (global.attachEvent) {\n global.attachEvent('onunload', unloadHandler);\n } else if (global.addEventListener) {\n global.addEventListener('beforeunload', unloadHandler, false);\n }\n }\n\n function unloadHandler() {\n for (var i in Request.requests) {\n if (Request.requests.hasOwnProperty(i)) {\n Request.requests[i].abort();\n }\n }\n }\n }).call(this, typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n }, { \"./polling\": 8, \"component-emitter\": 15, \"component-inherit\": 16, \"debug\": 17, \"xmlhttprequest-ssl\": 10 }], 8: [function (_dereq_, module, exports) {\n /**\n * Module dependencies.\n */\n\n var Transport = _dereq_('../transport');\n var parseqs = _dereq_('parseqs');\n var parser = _dereq_('engine.io-parser');\n var inherit = _dereq_('component-inherit');\n var yeast = _dereq_('yeast');\n var debug = _dereq_('debug')('engine.io-client:polling');\n\n /**\n * Module exports.\n */\n\n module.exports = Polling;\n\n /**\n * Is XHR2 supported?\n */\n\n var hasXHR2 = function () {\n var XMLHttpRequest = _dereq_('xmlhttprequest-ssl');\n var xhr = new XMLHttpRequest({ xdomain: false });\n return null != xhr.responseType;\n }();\n\n /**\n * Polling interface.\n *\n * @param {Object} opts\n * @api private\n */\n\n function Polling(opts) {\n var forceBase64 = opts && opts.forceBase64;\n if (!hasXHR2 || forceBase64) {\n this.supportsBinary = false;\n }\n Transport.call(this, opts);\n }\n\n /**\n * Inherits from Transport.\n */\n\n inherit(Polling, Transport);\n\n /**\n * Transport name.\n */\n\n Polling.prototype.name = 'polling';\n\n /**\n * Opens the socket (triggers polling). We write a PING message to determine\n * when the transport is open.\n *\n * @api private\n */\n\n Polling.prototype.doOpen = function () {\n this.poll();\n };\n\n /**\n * Pauses polling.\n *\n * @param {Function} callback upon buffers are flushed and transport is paused\n * @api private\n */\n\n Polling.prototype.pause = function (onPause) {\n var pending = 0;\n var self = this;\n\n this.readyState = 'pausing';\n\n function pause() {\n debug('paused');\n self.readyState = 'paused';\n onPause();\n }\n\n if (this.polling || !this.writable) {\n var total = 0;\n\n if (this.polling) {\n debug('we are currently polling - waiting to pause');\n total++;\n this.once('pollComplete', function () {\n debug('pre-pause polling complete');\n --total || pause();\n });\n }\n\n if (!this.writable) {\n debug('we are currently writing - waiting to pause');\n total++;\n this.once('drain', function () {\n debug('pre-pause writing complete');\n --total || pause();\n });\n }\n } else {\n pause();\n }\n };\n\n /**\n * Starts polling cycle.\n *\n * @api public\n */\n\n Polling.prototype.poll = function () {\n debug('polling');\n this.polling = true;\n this.doPoll();\n this.emit('poll');\n };\n\n /**\n * Overloads onData to detect payloads.\n *\n * @api private\n */\n\n Polling.prototype.onData = function (data) {\n var self = this;\n debug('polling got data %s', data);\n var callback = function callback(packet, index, total) {\n // if its the first message we consider the transport open\n if ('opening' == self.readyState) {\n self.onOpen();\n }\n\n // if its a close packet, we close the ongoing requests\n if ('close' == packet.type) {\n self.onClose();\n return false;\n }\n\n // otherwise bypass onData and handle the message\n self.onPacket(packet);\n };\n\n // decode payload\n parser.decodePayload(data, this.socket.binaryType, callback);\n\n // if an event did not trigger closing\n if ('closed' != this.readyState) {\n // if we got data we're not polling\n this.polling = false;\n this.emit('pollComplete');\n\n if ('open' == this.readyState) {\n this.poll();\n } else {\n debug('ignoring poll - transport state \"%s\"', this.readyState);\n }\n }\n };\n\n /**\n * For polling, send a close packet.\n *\n * @api private\n */\n\n Polling.prototype.doClose = function () {\n var self = this;\n\n function close() {\n debug('writing close packet');\n self.write([{ type: 'close' }]);\n }\n\n if ('open' == this.readyState) {\n debug('transport open - closing');\n close();\n } else {\n // in case we're trying to close while\n // handshaking is in progress (GH-164)\n debug('transport not open - deferring close');\n this.once('open', close);\n }\n };\n\n /**\n * Writes a packets payload.\n *\n * @param {Array} data packets\n * @param {Function} drain callback\n * @api private\n */\n\n Polling.prototype.write = function (packets) {\n var self = this;\n this.writable = false;\n var callbackfn = function callbackfn() {\n self.writable = true;\n self.emit('drain');\n };\n\n var self = this;\n parser.encodePayload(packets, this.supportsBinary, function (data) {\n self.doWrite(data, callbackfn);\n });\n };\n\n /**\n * Generates uri for connection.\n *\n * @api private\n */\n\n Polling.prototype.uri = function () {\n var query = this.query || {};\n var schema = this.secure ? 'https' : 'http';\n var port = '';\n\n // cache busting is forced\n if (false !== this.timestampRequests) {\n query[this.timestampParam] = yeast();\n }\n\n if (!this.supportsBinary && !query.sid) {\n query.b64 = 1;\n }\n\n query = parseqs.encode(query);\n\n // avoid port if default for schema\n if (this.port && ('https' == schema && this.port != 443 || 'http' == schema && this.port != 80)) {\n port = ':' + this.port;\n }\n\n // prepend ? to query\n if (query.length) {\n query = '?' + query;\n }\n\n var ipv6 = this.hostname.indexOf(':') !== -1;\n return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;\n };\n }, { \"../transport\": 4, \"component-inherit\": 16, \"debug\": 17, \"engine.io-parser\": 19, \"parseqs\": 27, \"xmlhttprequest-ssl\": 10, \"yeast\": 30 }], 9: [function (_dereq_, module, exports) {\n (function (global) {\n /**\n * Module dependencies.\n */\n\n var Transport = _dereq_('../transport');\n var parser = _dereq_('engine.io-parser');\n var parseqs = _dereq_('parseqs');\n var inherit = _dereq_('component-inherit');\n var yeast = _dereq_('yeast');\n var debug = _dereq_('debug')('engine.io-client:websocket');\n var BrowserWebSocket = global.WebSocket || global.MozWebSocket;\n\n /**\n * Get either the `WebSocket` or `MozWebSocket` globals\n * in the browser or the WebSocket-compatible interface\n * exposed by `ws` for Node environment.\n */\n\n var WebSocket = BrowserWebSocket || (typeof window !== 'undefined' ? null : _dereq_('ws'));\n\n /**\n * Module exports.\n */\n\n module.exports = WS;\n\n /**\n * WebSocket transport constructor.\n *\n * @api {Object} connection options\n * @api public\n */\n\n function WS(opts) {\n var forceBase64 = opts && opts.forceBase64;\n if (forceBase64) {\n this.supportsBinary = false;\n }\n this.perMessageDeflate = opts.perMessageDeflate;\n Transport.call(this, opts);\n }\n\n /**\n * Inherits from Transport.\n */\n\n inherit(WS, Transport);\n\n /**\n * Transport name.\n *\n * @api public\n */\n\n WS.prototype.name = 'websocket';\n\n /*\n * WebSockets support binary\n */\n\n WS.prototype.supportsBinary = true;\n\n /**\n * Opens socket.\n *\n * @api private\n */\n\n WS.prototype.doOpen = function () {\n if (!this.check()) {\n // let probe timeout\n return;\n }\n\n var self = this;\n var uri = this.uri();\n var protocols = void 0;\n var opts = {\n agent: this.agent,\n perMessageDeflate: this.perMessageDeflate\n };\n\n // SSL options for Node.js client\n opts.pfx = this.pfx;\n opts.key = this.key;\n opts.passphrase = this.passphrase;\n opts.cert = this.cert;\n opts.ca = this.ca;\n opts.ciphers = this.ciphers;\n opts.rejectUnauthorized = this.rejectUnauthorized;\n if (this.extraHeaders) {\n opts.headers = this.extraHeaders;\n }\n\n this.ws = BrowserWebSocket ? new WebSocket(uri) : new WebSocket(uri, protocols, opts);\n\n if (this.ws.binaryType === undefined) {\n this.supportsBinary = false;\n }\n\n if (this.ws.supports && this.ws.supports.binary) {\n this.supportsBinary = true;\n this.ws.binaryType = 'buffer';\n } else {\n this.ws.binaryType = 'arraybuffer';\n }\n\n this.addEventListeners();\n };\n\n /**\n * Adds event listeners to the socket\n *\n * @api private\n */\n\n WS.prototype.addEventListeners = function () {\n var self = this;\n\n this.ws.onopen = function () {\n self.onOpen();\n };\n this.ws.onclose = function () {\n self.onClose();\n };\n this.ws.onmessage = function (ev) {\n self.onData(ev.data);\n };\n this.ws.onerror = function (e) {\n self.onError('websocket error', e);\n };\n };\n\n /**\n * Override `onData` to use a timer on iOS.\n * See: https://gist.github.com/mloughran/2052006\n *\n * @api private\n */\n\n if ('undefined' != typeof navigator && /iPad|iPhone|iPod/i.test(navigator.userAgent)) {\n WS.prototype.onData = function (data) {\n var self = this;\n setTimeout(function () {\n Transport.prototype.onData.call(self, data);\n }, 0);\n };\n }\n\n /**\n * Writes data to socket.\n *\n * @param {Array} array of packets.\n * @api private\n */\n\n WS.prototype.write = function (packets) {\n var self = this;\n this.writable = false;\n\n // encodePacket efficient as it uses WS framing\n // no need for encodePayload\n var total = packets.length;\n for (var i = 0, l = total; i < l; i++) {\n (function (packet) {\n parser.encodePacket(packet, self.supportsBinary, function (data) {\n if (!BrowserWebSocket) {\n // always create a new object (GH-437)\n var opts = {};\n if (packet.options) {\n opts.compress = packet.options.compress;\n }\n\n if (self.perMessageDeflate) {\n var len = 'string' == typeof data ? global.Buffer.byteLength(data) : data.length;\n if (len < self.perMessageDeflate.threshold) {\n opts.compress = false;\n }\n }\n }\n\n //Sometimes the websocket has already been closed but the browser didn't\n //have a chance of informing us about it yet, in that case send will\n //throw an error\n try {\n if (BrowserWebSocket) {\n // TypeError is thrown when passing the second argument on Safari\n self.ws.send(data);\n } else {\n self.ws.send(data, opts);\n }\n } catch (e) {\n debug('websocket closed before onclose event');\n }\n\n --total || done();\n });\n })(packets[i]);\n }\n\n function done() {\n self.emit('flush');\n\n // fake drain\n // defer to next tick to allow Socket to clear writeBuffer\n setTimeout(function () {\n self.writable = true;\n self.emit('drain');\n }, 0);\n }\n };\n\n /**\n * Called upon close\n *\n * @api private\n */\n\n WS.prototype.onClose = function () {\n Transport.prototype.onClose.call(this);\n };\n\n /**\n * Closes socket.\n *\n * @api private\n */\n\n WS.prototype.doClose = function () {\n if (typeof this.ws !== 'undefined') {\n this.ws.close();\n }\n };\n\n /**\n * Generates uri for connection.\n *\n * @api private\n */\n\n WS.prototype.uri = function () {\n var query = this.query || {};\n var schema = this.secure ? 'wss' : 'ws';\n var port = '';\n\n // avoid port if default for schema\n if (this.port && ('wss' == schema && this.port != 443 || 'ws' == schema && this.port != 80)) {\n port = ':' + this.port;\n }\n\n // append timestamp to URI\n if (this.timestampRequests) {\n query[this.timestampParam] = yeast();\n }\n\n // communicate binary support capabilities\n if (!this.supportsBinary) {\n query.b64 = 1;\n }\n\n query = parseqs.encode(query);\n\n // prepend ? to query\n if (query.length) {\n query = '?' + query;\n }\n\n var ipv6 = this.hostname.indexOf(':') !== -1;\n return schema + '://' + (ipv6 ? '[' + this.hostname + ']' : this.hostname) + port + this.path + query;\n };\n\n /**\n * Feature detection for WebSocket.\n *\n * @return {Boolean} whether this transport is available.\n * @api public\n */\n\n WS.prototype.check = function () {\n return !!WebSocket && !('__initialize' in WebSocket && this.name === WS.prototype.name);\n };\n }).call(this, typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n }, { \"../transport\": 4, \"component-inherit\": 16, \"debug\": 17, \"engine.io-parser\": 19, \"parseqs\": 27, \"ws\": undefined, \"yeast\": 30 }], 10: [function (_dereq_, module, exports) {\n // browser shim for xmlhttprequest module\n var hasCORS = _dereq_('has-cors');\n\n module.exports = function (opts) {\n var xdomain = opts.xdomain;\n\n // scheme must be same when usign XDomainRequest\n // http://blogs.msdn.com/b/ieinternals/archive/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds.aspx\n var xscheme = opts.xscheme;\n\n // XDomainRequest has a flow of not sending cookie, therefore it should be disabled as a default.\n // https://github.com/Automattic/engine.io-client/pull/217\n var enablesXDR = opts.enablesXDR;\n\n // XMLHttpRequest can be disabled on IE\n try {\n if ('undefined' != typeof XMLHttpRequest && (!xdomain || hasCORS)) {\n return new XMLHttpRequest();\n }\n } catch (e) {}\n\n // Use XDomainRequest for IE8 if enablesXDR is true\n // because loading bar keeps flashing when using jsonp-polling\n // https://github.com/yujiosaka/socke.io-ie8-loading-example\n try {\n if ('undefined' != typeof XDomainRequest && !xscheme && enablesXDR) {\n return new XDomainRequest();\n }\n } catch (e) {}\n\n if (!xdomain) {\n try {\n return new ActiveXObject('Microsoft.XMLHTTP');\n } catch (e) {}\n }\n };\n }, { \"has-cors\": 22 }], 11: [function (_dereq_, module, exports) {\n module.exports = after;\n\n function after(count, callback, err_cb) {\n var bail = false;\n err_cb = err_cb || noop;\n proxy.count = count;\n\n return count === 0 ? callback() : proxy;\n\n function proxy(err, result) {\n if (proxy.count <= 0) {\n throw new Error('after called too many times');\n }\n --proxy.count;\n\n // after first error, rest are passed to err_cb\n if (err) {\n bail = true;\n callback(err);\n // future error callbacks will go to error handler\n callback = err_cb;\n } else if (proxy.count === 0 && !bail) {\n callback(null, result);\n }\n }\n }\n\n function noop() {}\n }, {}], 12: [function (_dereq_, module, exports) {\n /**\n * An abstraction for slicing an arraybuffer even when\n * ArrayBuffer.prototype.slice is not supported\n *\n * @api public\n */\n\n module.exports = function (arraybuffer, start, end) {\n var bytes = arraybuffer.byteLength;\n start = start || 0;\n end = end || bytes;\n\n if (arraybuffer.slice) {\n return arraybuffer.slice(start, end);\n }\n\n if (start < 0) {\n start += bytes;\n }\n if (end < 0) {\n end += bytes;\n }\n if (end > bytes) {\n end = bytes;\n }\n\n if (start >= bytes || start >= end || bytes === 0) {\n return new ArrayBuffer(0);\n }\n\n var abv = new Uint8Array(arraybuffer);\n var result = new Uint8Array(end - start);\n for (var i = start, ii = 0; i < end; i++, ii++) {\n result[ii] = abv[i];\n }\n return result.buffer;\n };\n }, {}], 13: [function (_dereq_, module, exports) {\n /*\n * base64-arraybuffer\n * https://github.com/niklasvh/base64-arraybuffer\n *\n * Copyright (c) 2012 Niklas von Hertzen\n * Licensed under the MIT license.\n */\n (function (chars) {\n \"use strict\";\n\n exports.encode = function (arraybuffer) {\n var bytes = new Uint8Array(arraybuffer),\n i,\n len = bytes.length,\n base64 = \"\";\n\n for (i = 0; i < len; i += 3) {\n base64 += chars[bytes[i] >> 2];\n base64 += chars[(bytes[i] & 3) << 4 | bytes[i + 1] >> 4];\n base64 += chars[(bytes[i + 1] & 15) << 2 | bytes[i + 2] >> 6];\n base64 += chars[bytes[i + 2] & 63];\n }\n\n if (len % 3 === 2) {\n base64 = base64.substring(0, base64.length - 1) + \"=\";\n } else if (len % 3 === 1) {\n base64 = base64.substring(0, base64.length - 2) + \"==\";\n }\n\n return base64;\n };\n\n exports.decode = function (base64) {\n var bufferLength = base64.length * 0.75,\n len = base64.length,\n i,\n p = 0,\n encoded1,\n encoded2,\n encoded3,\n encoded4;\n\n if (base64[base64.length - 1] === \"=\") {\n bufferLength--;\n if (base64[base64.length - 2] === \"=\") {\n bufferLength--;\n }\n }\n\n var arraybuffer = new ArrayBuffer(bufferLength),\n bytes = new Uint8Array(arraybuffer);\n\n for (i = 0; i < len; i += 4) {\n encoded1 = chars.indexOf(base64[i]);\n encoded2 = chars.indexOf(base64[i + 1]);\n encoded3 = chars.indexOf(base64[i + 2]);\n encoded4 = chars.indexOf(base64[i + 3]);\n\n bytes[p++] = encoded1 << 2 | encoded2 >> 4;\n bytes[p++] = (encoded2 & 15) << 4 | encoded3 >> 2;\n bytes[p++] = (encoded3 & 3) << 6 | encoded4 & 63;\n }\n\n return arraybuffer;\n };\n })(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\");\n }, {}], 14: [function (_dereq_, module, exports) {\n (function (global) {\n /**\n * Create a blob builder even when vendor prefixes exist\n */\n\n var BlobBuilder = global.BlobBuilder || global.WebKitBlobBuilder || global.MSBlobBuilder || global.MozBlobBuilder;\n\n /**\n * Check if Blob constructor is supported\n */\n\n var blobSupported = function () {\n try {\n var a = new Blob(['hi']);\n return a.size === 2;\n } catch (e) {\n return false;\n }\n }();\n\n /**\n * Check if Blob constructor supports ArrayBufferViews\n * Fails in Safari 6, so we need to map to ArrayBuffers there.\n */\n\n var blobSupportsArrayBufferView = blobSupported && function () {\n try {\n var b = new Blob([new Uint8Array([1, 2])]);\n return b.size === 2;\n } catch (e) {\n return false;\n }\n }();\n\n /**\n * Check if BlobBuilder is supported\n */\n\n var blobBuilderSupported = BlobBuilder && BlobBuilder.prototype.append && BlobBuilder.prototype.getBlob;\n\n /**\n * Helper function that maps ArrayBufferViews to ArrayBuffers\n * Used by BlobBuilder constructor and old browsers that didn't\n * support it in the Blob constructor.\n */\n\n function mapArrayBufferViews(ary) {\n for (var i = 0; i < ary.length; i++) {\n var chunk = ary[i];\n if (chunk.buffer instanceof ArrayBuffer) {\n var buf = chunk.buffer;\n\n // if this is a subarray, make a copy so we only\n // include the subarray region from the underlying buffer\n if (chunk.byteLength !== buf.byteLength) {\n var copy = new Uint8Array(chunk.byteLength);\n copy.set(new Uint8Array(buf, chunk.byteOffset, chunk.byteLength));\n buf = copy.buffer;\n }\n\n ary[i] = buf;\n }\n }\n }\n\n function BlobBuilderConstructor(ary, options) {\n options = options || {};\n\n var bb = new BlobBuilder();\n mapArrayBufferViews(ary);\n\n for (var i = 0; i < ary.length; i++) {\n bb.append(ary[i]);\n }\n\n return options.type ? bb.getBlob(options.type) : bb.getBlob();\n };\n\n function BlobConstructor(ary, options) {\n mapArrayBufferViews(ary);\n return new Blob(ary, options || {});\n };\n\n module.exports = function () {\n if (blobSupported) {\n return blobSupportsArrayBufferView ? global.Blob : BlobConstructor;\n } else if (blobBuilderSupported) {\n return BlobBuilderConstructor;\n } else {\n return undefined;\n }\n }();\n }).call(this, typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n }, {}], 15: [function (_dereq_, module, exports) {\n\n /**\n * Expose `Emitter`.\n */\n\n module.exports = Emitter;\n\n /**\n * Initialize a new `Emitter`.\n *\n * @api public\n */\n\n function Emitter(obj) {\n if (obj) return mixin(obj);\n };\n\n /**\n * Mixin the emitter properties.\n *\n * @param {Object} obj\n * @return {Object}\n * @api private\n */\n\n function mixin(obj) {\n for (var key in Emitter.prototype) {\n obj[key] = Emitter.prototype[key];\n }\n return obj;\n }\n\n /**\n * Listen on the given `event` with `fn`.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\n Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) {\n this._callbacks = this._callbacks || {};\n (this._callbacks[event] = this._callbacks[event] || []).push(fn);\n return this;\n };\n\n /**\n * Adds an `event` listener that will be invoked a single\n * time then automatically removed.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\n Emitter.prototype.once = function (event, fn) {\n var self = this;\n this._callbacks = this._callbacks || {};\n\n function on() {\n self.off(event, on);\n fn.apply(this, arguments);\n }\n\n on.fn = fn;\n this.on(event, on);\n return this;\n };\n\n /**\n * Remove the given callback for `event` or all\n * registered callbacks.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\n Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) {\n this._callbacks = this._callbacks || {};\n\n // all\n if (0 == arguments.length) {\n this._callbacks = {};\n return this;\n }\n\n // specific event\n var callbacks = this._callbacks[event];\n if (!callbacks) return this;\n\n // remove all handlers\n if (1 == arguments.length) {\n delete this._callbacks[event];\n return this;\n }\n\n // remove specific handler\n var cb;\n for (var i = 0; i < callbacks.length; i++) {\n cb = callbacks[i];\n if (cb === fn || cb.fn === fn) {\n callbacks.splice(i, 1);\n break;\n }\n }\n return this;\n };\n\n /**\n * Emit `event` with the given args.\n *\n * @param {String} event\n * @param {Mixed} ...\n * @return {Emitter}\n */\n\n Emitter.prototype.emit = function (event) {\n this._callbacks = this._callbacks || {};\n var args = [].slice.call(arguments, 1),\n callbacks = this._callbacks[event];\n\n if (callbacks) {\n callbacks = callbacks.slice(0);\n for (var i = 0, len = callbacks.length; i < len; ++i) {\n callbacks[i].apply(this, args);\n }\n }\n\n return this;\n };\n\n /**\n * Return array of callbacks for `event`.\n *\n * @param {String} event\n * @return {Array}\n * @api public\n */\n\n Emitter.prototype.listeners = function (event) {\n this._callbacks = this._callbacks || {};\n return this._callbacks[event] || [];\n };\n\n /**\n * Check if this emitter has `event` handlers.\n *\n * @param {String} event\n * @return {Boolean}\n * @api public\n */\n\n Emitter.prototype.hasListeners = function (event) {\n return !!this.listeners(event).length;\n };\n }, {}], 16: [function (_dereq_, module, exports) {\n\n module.exports = function (a, b) {\n var fn = function fn() {};\n fn.prototype = b.prototype;\n a.prototype = new fn();\n a.prototype.constructor = a;\n };\n }, {}], 17: [function (_dereq_, module, exports) {\n\n /**\n * This is the web browser implementation of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\n exports = module.exports = _dereq_('./debug');\n exports.log = log;\n exports.formatArgs = formatArgs;\n exports.save = save;\n exports.load = load;\n exports.useColors = useColors;\n exports.storage = 'undefined' != typeof chrome && 'undefined' != typeof chrome.storage ? chrome.storage.local : localstorage();\n\n /**\n * Colors.\n */\n\n exports.colors = ['lightseagreen', 'forestgreen', 'goldenrod', 'dodgerblue', 'darkorchid', 'crimson'];\n\n /**\n * Currently only WebKit-based Web Inspectors, Firefox >= v31,\n * and the Firebug extension (any Firefox version) are known\n * to support \"%c\" CSS customizations.\n *\n * TODO: add a `localStorage` variable to explicitly enable/disable colors\n */\n\n function useColors() {\n // is webkit? http://stackoverflow.com/a/16459606/376773\n return 'WebkitAppearance' in document.documentElement.style ||\n // is firebug? http://stackoverflow.com/a/398120/376773\n window.console && (console.firebug || console.exception && console.table) ||\n // is firefox >= v31?\n // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages\n navigator.userAgent.toLowerCase().match(/firefox\\/(\\d+)/) && parseInt(RegExp.$1, 10) >= 31;\n }\n\n /**\n * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.\n */\n\n exports.formatters.j = function (v) {\n return JSON.stringify(v);\n };\n\n /**\n * Colorize log arguments if enabled.\n *\n * @api public\n */\n\n function formatArgs() {\n var args = arguments;\n var useColors = this.useColors;\n\n args[0] = (useColors ? '%c' : '') + this.namespace + (useColors ? ' %c' : ' ') + args[0] + (useColors ? '%c ' : ' ') + '+' + exports.humanize(this.diff);\n\n if (!useColors) return args;\n\n var c = 'color: ' + this.color;\n args = [args[0], c, 'color: inherit'].concat(Array.prototype.slice.call(args, 1));\n\n // the final \"%c\" is somewhat tricky, because there could be other\n // arguments passed either before or after the %c, so we need to\n // figure out the correct index to insert the CSS into\n var index = 0;\n var lastC = 0;\n args[0].replace(/%[a-z%]/g, function (match) {\n if ('%%' === match) return;\n index++;\n if ('%c' === match) {\n // we only are interested in the *last* %c\n // (the user may have provided their own)\n lastC = index;\n }\n });\n\n args.splice(lastC, 0, c);\n return args;\n }\n\n /**\n * Invokes `console.log()` when available.\n * No-op when `console.log` is not a \"function\".\n *\n * @api public\n */\n\n function log() {\n // this hackery is required for IE8/9, where\n // the `console.log` function doesn't have 'apply'\n return 'object' === (typeof console === \"undefined\" ? \"undefined\" : _typeof(console)) && console.log && Function.prototype.apply.call(console.log, console, arguments);\n }\n\n /**\n * Save `namespaces`.\n *\n * @param {String} namespaces\n * @api private\n */\n\n function save(namespaces) {\n try {\n if (null == namespaces) {\n exports.storage.removeItem('debug');\n } else {\n exports.storage.debug = namespaces;\n }\n } catch (e) {}\n }\n\n /**\n * Load `namespaces`.\n *\n * @return {String} returns the previously persisted debug modes\n * @api private\n */\n\n function load() {\n var r;\n try {\n r = exports.storage.debug;\n } catch (e) {}\n return r;\n }\n\n /**\n * Enable namespaces listed in `localStorage.debug` initially.\n */\n\n exports.enable(load());\n\n /**\n * Localstorage attempts to return the localstorage.\n *\n * This is necessary because safari throws\n * when a user disables cookies/localstorage\n * and you attempt to access it.\n *\n * @return {LocalStorage}\n * @api private\n */\n\n function localstorage() {\n try {\n return window.localStorage;\n } catch (e) {}\n }\n }, { \"./debug\": 18 }], 18: [function (_dereq_, module, exports) {\n\n /**\n * This is the common logic for both the Node.js and web browser\n * implementations of `debug()`.\n *\n * Expose `debug()` as the module.\n */\n\n exports = module.exports = debug;\n exports.coerce = coerce;\n exports.disable = disable;\n exports.enable = enable;\n exports.enabled = enabled;\n exports.humanize = _dereq_('ms');\n\n /**\n * The currently active debug mode names, and names to skip.\n */\n\n exports.names = [];\n exports.skips = [];\n\n /**\n * Map of special \"%n\" handling functions, for the debug \"format\" argument.\n *\n * Valid key names are a single, lowercased letter, i.e. \"n\".\n */\n\n exports.formatters = {};\n\n /**\n * Previously assigned color.\n */\n\n var prevColor = 0;\n\n /**\n * Previous log timestamp.\n */\n\n var prevTime;\n\n /**\n * Select a color.\n *\n * @return {Number}\n * @api private\n */\n\n function selectColor() {\n return exports.colors[prevColor++ % exports.colors.length];\n }\n\n /**\n * Create a debugger with the given `namespace`.\n *\n * @param {String} namespace\n * @return {Function}\n * @api public\n */\n\n function debug(namespace) {\n\n // define the `disabled` version\n function disabled() {}\n disabled.enabled = false;\n\n // define the `enabled` version\n function enabled() {\n\n var self = enabled;\n\n // set `diff` timestamp\n var curr = +new Date();\n var ms = curr - (prevTime || curr);\n self.diff = ms;\n self.prev = prevTime;\n self.curr = curr;\n prevTime = curr;\n\n // add the `color` if not set\n if (null == self.useColors) self.useColors = exports.useColors();\n if (null == self.color && self.useColors) self.color = selectColor();\n\n var args = Array.prototype.slice.call(arguments);\n\n args[0] = exports.coerce(args[0]);\n\n if ('string' !== typeof args[0]) {\n // anything else let's inspect with %o\n args = ['%o'].concat(args);\n }\n\n // apply any `formatters` transformations\n var index = 0;\n args[0] = args[0].replace(/%([a-z%])/g, function (match, format) {\n // if we encounter an escaped % then don't increase the array index\n if (match === '%%') return match;\n index++;\n var formatter = exports.formatters[format];\n if ('function' === typeof formatter) {\n var val = args[index];\n match = formatter.call(self, val);\n\n // now we need to remove `args[index]` since it's inlined in the `format`\n args.splice(index, 1);\n index--;\n }\n return match;\n });\n\n if ('function' === typeof exports.formatArgs) {\n args = exports.formatArgs.apply(self, args);\n }\n var logFn = enabled.log || exports.log || console.log.bind(console);\n logFn.apply(self, args);\n }\n enabled.enabled = true;\n\n var fn = exports.enabled(namespace) ? enabled : disabled;\n\n fn.namespace = namespace;\n\n return fn;\n }\n\n /**\n * Enables a debug mode by namespaces. This can include modes\n * separated by a colon and wildcards.\n *\n * @param {String} namespaces\n * @api public\n */\n\n function enable(namespaces) {\n exports.save(namespaces);\n\n var split = (namespaces || '').split(/[\\s,]+/);\n var len = split.length;\n\n for (var i = 0; i < len; i++) {\n if (!split[i]) continue; // ignore empty strings\n namespaces = split[i].replace(/\\*/g, '.*?');\n if (namespaces[0] === '-') {\n exports.skips.push(new RegExp('^' + namespaces.substr(1) + '$'));\n } else {\n exports.names.push(new RegExp('^' + namespaces + '$'));\n }\n }\n }\n\n /**\n * Disable debug output.\n *\n * @api public\n */\n\n function disable() {\n exports.enable('');\n }\n\n /**\n * Returns true if the given mode name is enabled, false otherwise.\n *\n * @param {String} name\n * @return {Boolean}\n * @api public\n */\n\n function enabled(name) {\n var i, len;\n for (i = 0, len = exports.skips.length; i < len; i++) {\n if (exports.skips[i].test(name)) {\n return false;\n }\n }\n for (i = 0, len = exports.names.length; i < len; i++) {\n if (exports.names[i].test(name)) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Coerce `val`.\n *\n * @param {Mixed} val\n * @return {Mixed}\n * @api private\n */\n\n function coerce(val) {\n if (val instanceof Error) return val.stack || val.message;\n return val;\n }\n }, { \"ms\": 25 }], 19: [function (_dereq_, module, exports) {\n (function (global) {\n /**\n * Module dependencies.\n */\n\n var keys = _dereq_('./keys');\n var hasBinary = _dereq_('has-binary');\n var sliceBuffer = _dereq_('arraybuffer.slice');\n var base64encoder = _dereq_('base64-arraybuffer');\n var after = _dereq_('after');\n var utf8 = _dereq_('utf8');\n\n /**\n * Check if we are running an android browser. That requires us to use\n * ArrayBuffer with polling transports...\n *\n * http://ghinda.net/jpeg-blob-ajax-android/\n */\n\n var isAndroid = navigator.userAgent.match(/Android/i);\n\n /**\n * Check if we are running in PhantomJS.\n * Uploading a Blob with PhantomJS does not work correctly, as reported here:\n * https://github.com/ariya/phantomjs/issues/11395\n * @type boolean\n */\n var isPhantomJS = /PhantomJS/i.test(navigator.userAgent);\n\n /**\n * When true, avoids using Blobs to encode payloads.\n * @type boolean\n */\n var dontSendBlobs = isAndroid || isPhantomJS;\n\n /**\n * Current protocol version.\n */\n\n exports.protocol = 3;\n\n /**\n * Packet types.\n */\n\n var packets = exports.packets = {\n open: 0 // non-ws\n , close: 1 // non-ws\n , ping: 2,\n pong: 3,\n message: 4,\n upgrade: 5,\n noop: 6\n };\n\n var packetslist = keys(packets);\n\n /**\n * Premade error packet.\n */\n\n var err = { type: 'error', data: 'parser error' };\n\n /**\n * Create a blob api even for blob builder when vendor prefixes exist\n */\n\n var Blob = _dereq_('blob');\n\n /**\n * Encodes a packet.\n *\n * <packet type id> [ <data> ]\n *\n * Example:\n *\n * 5hello world\n * 3\n * 4\n *\n * Binary is encoded in an identical principle\n *\n * @api private\n */\n\n exports.encodePacket = function (packet, supportsBinary, utf8encode, callback) {\n if ('function' == typeof supportsBinary) {\n callback = supportsBinary;\n supportsBinary = false;\n }\n\n if ('function' == typeof utf8encode) {\n callback = utf8encode;\n utf8encode = null;\n }\n\n var data = packet.data === undefined ? undefined : packet.data.buffer || packet.data;\n\n if (global.ArrayBuffer && data instanceof ArrayBuffer) {\n return encodeArrayBuffer(packet, supportsBinary, callback);\n } else if (Blob && data instanceof global.Blob) {\n return encodeBlob(packet, supportsBinary, callback);\n }\n\n // might be an object with { base64: true, data: dataAsBase64String }\n if (data && data.base64) {\n return encodeBase64Object(packet, callback);\n }\n\n // Sending data as a utf-8 string\n var encoded = packets[packet.type];\n\n // data fragment is optional\n if (undefined !== packet.data) {\n encoded += utf8encode ? utf8.encode(String(packet.data)) : String(packet.data);\n }\n\n return callback('' + encoded);\n };\n\n function encodeBase64Object(packet, callback) {\n // packet data is an object { base64: true, data: dataAsBase64String }\n var message = 'b' + exports.packets[packet.type] + packet.data.data;\n return callback(message);\n }\n\n /**\n * Encode packet helpers for binary types\n */\n\n function encodeArrayBuffer(packet, supportsBinary, callback) {\n if (!supportsBinary) {\n return exports.encodeBase64Packet(packet, callback);\n }\n\n var data = packet.data;\n var contentArray = new Uint8Array(data);\n var resultBuffer = new Uint8Array(1 + data.byteLength);\n\n resultBuffer[0] = packets[packet.type];\n for (var i = 0; i < contentArray.length; i++) {\n resultBuffer[i + 1] = contentArray[i];\n }\n\n return callback(resultBuffer.buffer);\n }\n\n function encodeBlobAsArrayBuffer(packet, supportsBinary, callback) {\n if (!supportsBinary) {\n return exports.encodeBase64Packet(packet, callback);\n }\n\n var fr = new FileReader();\n fr.onload = function () {\n packet.data = fr.result;\n exports.encodePacket(packet, supportsBinary, true, callback);\n };\n return fr.readAsArrayBuffer(packet.data);\n }\n\n function encodeBlob(packet, supportsBinary, callback) {\n if (!supportsBinary) {\n return exports.encodeBase64Packet(packet, callback);\n }\n\n if (dontSendBlobs) {\n return encodeBlobAsArrayBuffer(packet, supportsBinary, callback);\n }\n\n var length = new Uint8Array(1);\n length[0] = packets[packet.type];\n var blob = new Blob([length.buffer, packet.data]);\n\n return callback(blob);\n }\n\n /**\n * Encodes a packet with binary data in a base64 string\n *\n * @param {Object} packet, has `type` and `data`\n * @return {String} base64 encoded message\n */\n\n exports.encodeBase64Packet = function (packet, callback) {\n var message = 'b' + exports.packets[packet.type];\n if (Blob && packet.data instanceof global.Blob) {\n var fr = new FileReader();\n fr.onload = function () {\n var b64 = fr.result.split(',')[1];\n callback(message + b64);\n };\n return fr.readAsDataURL(packet.data);\n }\n\n var b64data;\n try {\n b64data = String.fromCharCode.apply(null, new Uint8Array(packet.data));\n } catch (e) {\n // iPhone Safari doesn't let you apply with typed arrays\n var typed = new Uint8Array(packet.data);\n var basic = new Array(typed.length);\n for (var i = 0; i < typed.length; i++) {\n basic[i] = typed[i];\n }\n b64data = String.fromCharCode.apply(null, basic);\n }\n message += global.btoa(b64data);\n return callback(message);\n };\n\n /**\n * Decodes a packet. Changes format to Blob if requested.\n *\n * @return {Object} with `type` and `data` (if any)\n * @api private\n */\n\n exports.decodePacket = function (data, binaryType, utf8decode) {\n // String data\n if (typeof data == 'string' || data === undefined) {\n if (data.charAt(0) == 'b') {\n return exports.decodeBase64Packet(data.substr(1), binaryType);\n }\n\n if (utf8decode) {\n try {\n data = utf8.decode(data);\n } catch (e) {\n return err;\n }\n }\n var type = data.charAt(0);\n\n if (Number(type) != type || !packetslist[type]) {\n return err;\n }\n\n if (data.length > 1) {\n return { type: packetslist[type], data: data.substring(1) };\n } else {\n return { type: packetslist[type] };\n }\n }\n\n var asArray = new Uint8Array(data);\n var type = asArray[0];\n var rest = sliceBuffer(data, 1);\n if (Blob && binaryType === 'blob') {\n rest = new Blob([rest]);\n }\n return { type: packetslist[type], data: rest };\n };\n\n /**\n * Decodes a packet encoded in a base64 string\n *\n * @param {String} base64 encoded message\n * @return {Object} with `type` and `data` (if any)\n */\n\n exports.decodeBase64Packet = function (msg, binaryType) {\n var type = packetslist[msg.charAt(0)];\n if (!global.ArrayBuffer) {\n return { type: type, data: { base64: true, data: msg.substr(1) } };\n }\n\n var data = base64encoder.decode(msg.substr(1));\n\n if (binaryType === 'blob' && Blob) {\n data = new Blob([data]);\n }\n\n return { type: type, data: data };\n };\n\n /**\n * Encodes multiple messages (payload).\n *\n * <length>:data\n *\n * Example:\n *\n * 11:hello world2:hi\n *\n * If any contents are binary, they will be encoded as base64 strings. Base64\n * encoded strings are marked with a b before the length specifier\n *\n * @param {Array} packets\n * @api private\n */\n\n exports.encodePayload = function (packets, supportsBinary, callback) {\n if (typeof supportsBinary == 'function') {\n callback = supportsBinary;\n supportsBinary = null;\n }\n\n var isBinary = hasBinary(packets);\n\n if (supportsBinary && isBinary) {\n if (Blob && !dontSendBlobs) {\n return exports.encodePayloadAsBlob(packets, callback);\n }\n\n return exports.encodePayloadAsArrayBuffer(packets, callback);\n }\n\n if (!packets.length) {\n return callback('0:');\n }\n\n function setLengthHeader(message) {\n return message.length + ':' + message;\n }\n\n function encodeOne(packet, doneCallback) {\n exports.encodePacket(packet, !isBinary ? false : supportsBinary, true, function (message) {\n doneCallback(null, setLengthHeader(message));\n });\n }\n\n map(packets, encodeOne, function (err, results) {\n return callback(results.join(''));\n });\n };\n\n /**\n * Async array map using after\n */\n\n function map(ary, each, done) {\n var result = new Array(ary.length);\n var next = after(ary.length, done);\n\n var eachWithIndex = function eachWithIndex(i, el, cb) {\n each(el, function (error, msg) {\n result[i] = msg;\n cb(error, result);\n });\n };\n\n for (var i = 0; i < ary.length; i++) {\n eachWithIndex(i, ary[i], next);\n }\n }\n\n /*\n * Decodes data when a payload is maybe expected. Possible binary contents are\n * decoded from their base64 representation\n *\n * @param {String} data, callback method\n * @api public\n */\n\n exports.decodePayload = function (data, binaryType, callback) {\n if (typeof data != 'string') {\n return exports.decodePayloadAsBinary(data, binaryType, callback);\n }\n\n if (typeof binaryType === 'function') {\n callback = binaryType;\n binaryType = null;\n }\n\n var packet;\n if (data == '') {\n // parser error - ignoring payload\n return callback(err, 0, 1);\n }\n\n var length = '',\n n,\n msg;\n\n for (var i = 0, l = data.length; i < l; i++) {\n var chr = data.charAt(i);\n\n if (':' != chr) {\n length += chr;\n } else {\n if ('' == length || length != (n = Number(length))) {\n // parser error - ignoring payload\n return callback(err, 0, 1);\n }\n\n msg = data.substr(i + 1, n);\n\n if (length != msg.length) {\n // parser error - ignoring payload\n return callback(err, 0, 1);\n }\n\n if (msg.length) {\n packet = exports.decodePacket(msg, binaryType, true);\n\n if (err.type == packet.type && err.data == packet.data) {\n // parser error in individual packet - ignoring payload\n return callback(err, 0, 1);\n }\n\n var ret = callback(packet, i + n, l);\n if (false === ret) return;\n }\n\n // advance cursor\n i += n;\n length = '';\n }\n }\n\n if (length != '') {\n // parser error - ignoring payload\n return callback(err, 0, 1);\n }\n };\n\n /**\n * Encodes multiple messages (payload) as binary.\n *\n * <1 = binary, 0 = string><number from 0-9><number from 0-9>[...]<number\n * 255><data>\n *\n * Example:\n * 1 3 255 1 2 3, if the binary contents are interpreted as 8 bit integers\n *\n * @param {Array} packets\n * @return {ArrayBuffer} encoded payload\n * @api private\n */\n\n exports.encodePayloadAsArrayBuffer = function (packets, callback) {\n if (!packets.length) {\n return callback(new ArrayBuffer(0));\n }\n\n function encodeOne(packet, doneCallback) {\n exports.encodePacket(packet, true, true, function (data) {\n return doneCallback(null, data);\n });\n }\n\n map(packets, encodeOne, function (err, encodedPackets) {\n var totalLength = encodedPackets.reduce(function (acc, p) {\n var len;\n if (typeof p === 'string') {\n len = p.length;\n } else {\n len = p.byteLength;\n }\n return acc + len.toString().length + len + 2; // string/binary identifier + separator = 2\n }, 0);\n\n var resultArray = new Uint8Array(totalLength);\n\n var bufferIndex = 0;\n encodedPackets.forEach(function (p) {\n var isString = typeof p === 'string';\n var ab = p;\n if (isString) {\n var view = new Uint8Array(p.length);\n for (var i = 0; i < p.length; i++) {\n view[i] = p.charCodeAt(i);\n }\n ab = view.buffer;\n }\n\n if (isString) {\n // not true binary\n resultArray[bufferIndex++] = 0;\n } else {\n // true binary\n resultArray[bufferIndex++] = 1;\n }\n\n var lenStr = ab.byteLength.toString();\n for (var i = 0; i < lenStr.length; i++) {\n resultArray[bufferIndex++] = parseInt(lenStr[i]);\n }\n resultArray[bufferIndex++] = 255;\n\n var view = new Uint8Array(ab);\n for (var i = 0; i < view.length; i++) {\n resultArray[bufferIndex++] = view[i];\n }\n });\n\n return callback(resultArray.buffer);\n });\n };\n\n /**\n * Encode as Blob\n */\n\n exports.encodePayloadAsBlob = function (packets, callback) {\n function encodeOne(packet, doneCallback) {\n exports.encodePacket(packet, true, true, function (encoded) {\n var binaryIdentifier = new Uint8Array(1);\n binaryIdentifier[0] = 1;\n if (typeof encoded === 'string') {\n var view = new Uint8Array(encoded.length);\n for (var i = 0; i < encoded.length; i++) {\n view[i] = encoded.charCodeAt(i);\n }\n encoded = view.buffer;\n binaryIdentifier[0] = 0;\n }\n\n var len = encoded instanceof ArrayBuffer ? encoded.byteLength : encoded.size;\n\n var lenStr = len.toString();\n var lengthAry = new Uint8Array(lenStr.length + 1);\n for (var i = 0; i < lenStr.length; i++) {\n lengthAry[i] = parseInt(lenStr[i]);\n }\n lengthAry[lenStr.length] = 255;\n\n if (Blob) {\n var blob = new Blob([binaryIdentifier.buffer, lengthAry.buffer, encoded]);\n doneCallback(null, blob);\n }\n });\n }\n\n map(packets, encodeOne, function (err, results) {\n return callback(new Blob(results));\n });\n };\n\n /*\n * Decodes data when a payload is maybe expected. Strings are decoded by\n * interpreting each byte as a key code for entries marked to start with 0. See\n * description of encodePayloadAsBinary\n *\n * @param {ArrayBuffer} data, callback method\n * @api public\n */\n\n exports.decodePayloadAsBinary = function (data, binaryType, callback) {\n if (typeof binaryType === 'function') {\n callback = binaryType;\n binaryType = null;\n }\n\n var bufferTail = data;\n var buffers = [];\n\n var numberTooLong = false;\n while (bufferTail.byteLength > 0) {\n var tailArray = new Uint8Array(bufferTail);\n var isString = tailArray[0] === 0;\n var msgLength = '';\n\n for (var i = 1;; i++) {\n if (tailArray[i] == 255) break;\n\n if (msgLength.length > 310) {\n numberTooLong = true;\n break;\n }\n\n msgLength += tailArray[i];\n }\n\n if (numberTooLong) return callback(err, 0, 1);\n\n bufferTail = sliceBuffer(bufferTail, 2 + msgLength.length);\n msgLength = parseInt(msgLength);\n\n var msg = sliceBuffer(bufferTail, 0, msgLength);\n if (isString) {\n try {\n msg = String.fromCharCode.apply(null, new Uint8Array(msg));\n } catch (e) {\n // iPhone Safari doesn't let you apply to typed arrays\n var typed = new Uint8Array(msg);\n msg = '';\n for (var i = 0; i < typed.length; i++) {\n msg += String.fromCharCode(typed[i]);\n }\n }\n }\n\n buffers.push(msg);\n bufferTail = sliceBuffer(bufferTail, msgLength);\n }\n\n var total = buffers.length;\n buffers.forEach(function (buffer, i) {\n callback(exports.decodePacket(buffer, binaryType, true), i, total);\n });\n };\n }).call(this, typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n }, { \"./keys\": 20, \"after\": 11, \"arraybuffer.slice\": 12, \"base64-arraybuffer\": 13, \"blob\": 14, \"has-binary\": 21, \"utf8\": 29 }], 20: [function (_dereq_, module, exports) {\n\n /**\n * Gets the keys for an object.\n *\n * @return {Array} keys\n * @api private\n */\n\n module.exports = Object.keys || function keys(obj) {\n var arr = [];\n var has = Object.prototype.hasOwnProperty;\n\n for (var i in obj) {\n if (has.call(obj, i)) {\n arr.push(i);\n }\n }\n return arr;\n };\n }, {}], 21: [function (_dereq_, module, exports) {\n (function (global) {\n\n /*\n * Module requirements.\n */\n\n var isArray = _dereq_('isarray');\n\n /**\n * Module exports.\n */\n\n module.exports = hasBinary;\n\n /**\n * Checks for binary data.\n *\n * Right now only Buffer and ArrayBuffer are supported..\n *\n * @param {Object} anything\n * @api public\n */\n\n function hasBinary(data) {\n\n function _hasBinary(obj) {\n if (!obj) return false;\n\n if (global.Buffer && global.Buffer.isBuffer(obj) || global.ArrayBuffer && obj instanceof ArrayBuffer || global.Blob && obj instanceof Blob || global.File && obj instanceof File) {\n return true;\n }\n\n if (isArray(obj)) {\n for (var i = 0; i < obj.length; i++) {\n if (_hasBinary(obj[i])) {\n return true;\n }\n }\n } else if (obj && 'object' == (typeof obj === \"undefined\" ? \"undefined\" : _typeof(obj))) {\n if (obj.toJSON) {\n obj = obj.toJSON();\n }\n\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key) && _hasBinary(obj[key])) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n return _hasBinary(data);\n }\n }).call(this, typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n }, { \"isarray\": 24 }], 22: [function (_dereq_, module, exports) {\n\n /**\n * Module exports.\n *\n * Logic borrowed from Modernizr:\n *\n * - https://github.com/Modernizr/Modernizr/blob/master/feature-detects/cors.js\n */\n\n try {\n module.exports = typeof XMLHttpRequest !== 'undefined' && 'withCredentials' in new XMLHttpRequest();\n } catch (err) {\n // if XMLHttp support is disabled in IE then it will throw\n // when trying to create\n module.exports = false;\n }\n }, {}], 23: [function (_dereq_, module, exports) {\n\n var indexOf = [].indexOf;\n\n module.exports = function (arr, obj) {\n if (indexOf) return arr.indexOf(obj);\n for (var i = 0; i < arr.length; ++i) {\n if (arr[i] === obj) return i;\n }\n return -1;\n };\n }, {}], 24: [function (_dereq_, module, exports) {\n module.exports = Array.isArray || function (arr) {\n return Object.prototype.toString.call(arr) == '[object Array]';\n };\n }, {}], 25: [function (_dereq_, module, exports) {\n /**\n * Helpers.\n */\n\n var s = 1000;\n var m = s * 60;\n var h = m * 60;\n var d = h * 24;\n var y = d * 365.25;\n\n /**\n * Parse or format the given `val`.\n *\n * Options:\n *\n * - `long` verbose formatting [false]\n *\n * @param {String|Number} val\n * @param {Object} options\n * @return {String|Number}\n * @api public\n */\n\n module.exports = function (val, options) {\n options = options || {};\n if ('string' == typeof val) return parse(val);\n return options.long ? long(val) : short(val);\n };\n\n /**\n * Parse the given `str` and return milliseconds.\n *\n * @param {String} str\n * @return {Number}\n * @api private\n */\n\n function parse(str) {\n str = '' + str;\n if (str.length > 10000) return;\n var match = /^((?:\\d+)?\\.?\\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|years?|yrs?|y)?$/i.exec(str);\n if (!match) return;\n var n = parseFloat(match[1]);\n var type = (match[2] || 'ms').toLowerCase();\n switch (type) {\n case 'years':\n case 'year':\n case 'yrs':\n case 'yr':\n case 'y':\n return n * y;\n case 'days':\n case 'day':\n case 'd':\n return n * d;\n case 'hours':\n case 'hour':\n case 'hrs':\n case 'hr':\n case 'h':\n return n * h;\n case 'minutes':\n case 'minute':\n case 'mins':\n case 'min':\n case 'm':\n return n * m;\n case 'seconds':\n case 'second':\n case 'secs':\n case 'sec':\n case 's':\n return n * s;\n case 'milliseconds':\n case 'millisecond':\n case 'msecs':\n case 'msec':\n case 'ms':\n return n;\n }\n }\n\n /**\n * Short format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\n function short(ms) {\n if (ms >= d) return Math.round(ms / d) + 'd';\n if (ms >= h) return Math.round(ms / h) + 'h';\n if (ms >= m) return Math.round(ms / m) + 'm';\n if (ms >= s) return Math.round(ms / s) + 's';\n return ms + 'ms';\n }\n\n /**\n * Long format for `ms`.\n *\n * @param {Number} ms\n * @return {String}\n * @api private\n */\n\n function long(ms) {\n return plural(ms, d, 'day') || plural(ms, h, 'hour') || plural(ms, m, 'minute') || plural(ms, s, 'second') || ms + ' ms';\n }\n\n /**\n * Pluralization helper.\n */\n\n function plural(ms, n, name) {\n if (ms < n) return;\n if (ms < n * 1.5) return Math.floor(ms / n) + ' ' + name;\n return Math.ceil(ms / n) + ' ' + name + 's';\n }\n }, {}], 26: [function (_dereq_, module, exports) {\n (function (global) {\n /**\n * JSON parse.\n *\n * @see Based on jQuery#parseJSON (MIT) and JSON2\n * @api private\n */\n\n var rvalidchars = /^[\\],:{}\\s]*$/;\n var rvalidescape = /\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g;\n var rvalidtokens = /\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g;\n var rvalidbraces = /(?:^|:|,)(?:\\s*\\[)+/g;\n var rtrimLeft = /^\\s+/;\n var rtrimRight = /\\s+$/;\n\n module.exports = function parsejson(data) {\n if ('string' != typeof data || !data) {\n return null;\n }\n\n data = data.replace(rtrimLeft, '').replace(rtrimRight, '');\n\n // Attempt to parse using the native JSON parser first\n if (global.JSON && JSON.parse) {\n return JSON.parse(data);\n }\n\n if (rvalidchars.test(data.replace(rvalidescape, '@').replace(rvalidtokens, ']').replace(rvalidbraces, ''))) {\n return new Function('return ' + data)();\n }\n };\n }).call(this, typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n }, {}], 27: [function (_dereq_, module, exports) {\n /**\n * Compiles a querystring\n * Returns string representation of the object\n *\n * @param {Object}\n * @api private\n */\n\n exports.encode = function (obj) {\n var str = '';\n\n for (var i in obj) {\n if (obj.hasOwnProperty(i)) {\n if (str.length) str += '&';\n str += encodeURIComponent(i) + '=' + encodeURIComponent(obj[i]);\n }\n }\n\n return str;\n };\n\n /**\n * Parses a simple querystring into an object\n *\n * @param {String} qs\n * @api private\n */\n\n exports.decode = function (qs) {\n var qry = {};\n var pairs = qs.split('&');\n for (var i = 0, l = pairs.length; i < l; i++) {\n var pair = pairs[i].split('=');\n qry[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);\n }\n return qry;\n };\n }, {}], 28: [function (_dereq_, module, exports) {\n /**\n * Parses an URI\n *\n * @author Steven Levithan <stevenlevithan.com> (MIT license)\n * @api private\n */\n\n var re = /^(?:(?![^:@]+:[^:@\\/]*@)(http|https|ws|wss):\\/\\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\\/?#]*)(?::(\\d*))?)(((\\/(?:[^?#](?![^?#\\/]*\\.[^?#\\/.]+(?:[?#]|$)))*\\/?)?([^?#\\/]*))(?:\\?([^#]*))?(?:#(.*))?)/;\n\n var parts = ['source', 'protocol', 'authority', 'userInfo', 'user', 'password', 'host', 'port', 'relative', 'path', 'directory', 'file', 'query', 'anchor'];\n\n module.exports = function parseuri(str) {\n var src = str,\n b = str.indexOf('['),\n e = str.indexOf(']');\n\n if (b != -1 && e != -1) {\n str = str.substring(0, b) + str.substring(b, e).replace(/:/g, ';') + str.substring(e, str.length);\n }\n\n var m = re.exec(str || ''),\n uri = {},\n i = 14;\n\n while (i--) {\n uri[parts[i]] = m[i] || '';\n }\n\n if (b != -1 && e != -1) {\n uri.source = src;\n uri.host = uri.host.substring(1, uri.host.length - 1).replace(/;/g, ':');\n uri.authority = uri.authority.replace('[', '').replace(']', '').replace(/;/g, ':');\n uri.ipv6uri = true;\n }\n\n return uri;\n };\n }, {}], 29: [function (_dereq_, module, exports) {\n (function (global) {\n /*! https://mths.be/utf8js v2.0.0 by @mathias */\n ;(function (root) {\n\n // Detect free variables `exports`\n var freeExports = (typeof exports === \"undefined\" ? \"undefined\" : _typeof(exports)) == 'object' && exports;\n\n // Detect free variable `module`\n var freeModule = (typeof module === \"undefined\" ? \"undefined\" : _typeof(module)) == 'object' && module && module.exports == freeExports && module;\n\n // Detect free variable `global`, from Node.js or Browserified code,\n // and use it as `root`\n var freeGlobal = (typeof global === \"undefined\" ? \"undefined\" : _typeof(global)) == 'object' && global;\n if (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal) {\n root = freeGlobal;\n }\n\n /*--------------------------------------------------------------------------*/\n\n var stringFromCharCode = String.fromCharCode;\n\n // Taken from https://mths.be/punycode\n function ucs2decode(string) {\n var output = [];\n var counter = 0;\n var length = string.length;\n var value;\n var extra;\n while (counter < length) {\n value = string.charCodeAt(counter++);\n if (value >= 0xD800 && value <= 0xDBFF && counter < length) {\n // high surrogate, and there is a next character\n extra = string.charCodeAt(counter++);\n if ((extra & 0xFC00) == 0xDC00) {\n // low surrogate\n output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);\n } else {\n // unmatched surrogate; only append this code unit, in case the next\n // code unit is the high surrogate of a surrogate pair\n output.push(value);\n counter--;\n }\n } else {\n output.push(value);\n }\n }\n return output;\n }\n\n // Taken from https://mths.be/punycode\n function ucs2encode(array) {\n var length = array.length;\n var index = -1;\n var value;\n var output = '';\n while (++index < length) {\n value = array[index];\n if (value > 0xFFFF) {\n value -= 0x10000;\n output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);\n value = 0xDC00 | value & 0x3FF;\n }\n output += stringFromCharCode(value);\n }\n return output;\n }\n\n function checkScalarValue(codePoint) {\n if (codePoint >= 0xD800 && codePoint <= 0xDFFF) {\n throw Error('Lone surrogate U+' + codePoint.toString(16).toUpperCase() + ' is not a scalar value');\n }\n }\n /*--------------------------------------------------------------------------*/\n\n function createByte(codePoint, shift) {\n return stringFromCharCode(codePoint >> shift & 0x3F | 0x80);\n }\n\n function encodeCodePoint(codePoint) {\n if ((codePoint & 0xFFFFFF80) == 0) {\n // 1-byte sequence\n return stringFromCharCode(codePoint);\n }\n var symbol = '';\n if ((codePoint & 0xFFFFF800) == 0) {\n // 2-byte sequence\n symbol = stringFromCharCode(codePoint >> 6 & 0x1F | 0xC0);\n } else if ((codePoint & 0xFFFF0000) == 0) {\n // 3-byte sequence\n checkScalarValue(codePoint);\n symbol = stringFromCharCode(codePoint >> 12 & 0x0F | 0xE0);\n symbol += createByte(codePoint, 6);\n } else if ((codePoint & 0xFFE00000) == 0) {\n // 4-byte sequence\n symbol = stringFromCharCode(codePoint >> 18 & 0x07 | 0xF0);\n symbol += createByte(codePoint, 12);\n symbol += createByte(codePoint, 6);\n }\n symbol += stringFromCharCode(codePoint & 0x3F | 0x80);\n return symbol;\n }\n\n function utf8encode(string) {\n var codePoints = ucs2decode(string);\n var length = codePoints.length;\n var index = -1;\n var codePoint;\n var byteString = '';\n while (++index < length) {\n codePoint = codePoints[index];\n byteString += encodeCodePoint(codePoint);\n }\n return byteString;\n }\n\n /*--------------------------------------------------------------------------*/\n\n function readContinuationByte() {\n if (byteIndex >= byteCount) {\n throw Error('Invalid byte index');\n }\n\n var continuationByte = byteArray[byteIndex] & 0xFF;\n byteIndex++;\n\n if ((continuationByte & 0xC0) == 0x80) {\n return continuationByte & 0x3F;\n }\n\n // If we end up here, its not a continuation byte\n throw Error('Invalid continuation byte');\n }\n\n function decodeSymbol() {\n var byte1;\n var byte2;\n var byte3;\n var byte4;\n var codePoint;\n\n if (byteIndex > byteCount) {\n throw Error('Invalid byte index');\n }\n\n if (byteIndex == byteCount) {\n return false;\n }\n\n // Read first byte\n byte1 = byteArray[byteIndex] & 0xFF;\n byteIndex++;\n\n // 1-byte sequence (no continuation bytes)\n if ((byte1 & 0x80) == 0) {\n return byte1;\n }\n\n // 2-byte sequence\n if ((byte1 & 0xE0) == 0xC0) {\n var byte2 = readContinuationByte();\n codePoint = (byte1 & 0x1F) << 6 | byte2;\n if (codePoint >= 0x80) {\n return codePoint;\n } else {\n throw Error('Invalid continuation byte');\n }\n }\n\n // 3-byte sequence (may include unpaired surrogates)\n if ((byte1 & 0xF0) == 0xE0) {\n byte2 = readContinuationByte();\n byte3 = readContinuationByte();\n codePoint = (byte1 & 0x0F) << 12 | byte2 << 6 | byte3;\n if (codePoint >= 0x0800) {\n checkScalarValue(codePoint);\n return codePoint;\n } else {\n throw Error('Invalid continuation byte');\n }\n }\n\n // 4-byte sequence\n if ((byte1 & 0xF8) == 0xF0) {\n byte2 = readContinuationByte();\n byte3 = readContinuationByte();\n byte4 = readContinuationByte();\n codePoint = (byte1 & 0x0F) << 0x12 | byte2 << 0x0C | byte3 << 0x06 | byte4;\n if (codePoint >= 0x010000 && codePoint <= 0x10FFFF) {\n return codePoint;\n }\n }\n\n throw Error('Invalid UTF-8 detected');\n }\n\n var byteArray;\n var byteCount;\n var byteIndex;\n function utf8decode(byteString) {\n byteArray = ucs2decode(byteString);\n byteCount = byteArray.length;\n byteIndex = 0;\n var codePoints = [];\n var tmp;\n while ((tmp = decodeSymbol()) !== false) {\n codePoints.push(tmp);\n }\n return ucs2encode(codePoints);\n }\n\n /*--------------------------------------------------------------------------*/\n\n var utf8 = {\n 'version': '2.0.0',\n 'encode': utf8encode,\n 'decode': utf8decode\n };\n\n // Some AMD build optimizers, like r.js, check for specific condition patterns\n // like the following:\n if (typeof define == 'function' && _typeof(define.amd) == 'object' && define.amd) {\n define(function () {\n return utf8;\n });\n } else if (freeExports && !freeExports.nodeType) {\n if (freeModule) {\n // in Node.js or RingoJS v0.8.0+\n freeModule.exports = utf8;\n } else {\n // in Narwhal or RingoJS v0.7.0-\n var object = {};\n var hasOwnProperty = object.hasOwnProperty;\n for (var key in utf8) {\n hasOwnProperty.call(utf8, key) && (freeExports[key] = utf8[key]);\n }\n }\n } else {\n // in Rhino or a web browser\n root.utf8 = utf8;\n }\n })(this);\n }).call(this, typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n }, {}], 30: [function (_dereq_, module, exports) {\n 'use strict';\n\n var alphabet = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_'.split(''),\n length = 64,\n map = {},\n seed = 0,\n i = 0,\n prev;\n\n /**\n * Return a string representing the specified number.\n *\n * @param {Number} num The number to convert.\n * @returns {String} The string representation of the number.\n * @api public\n */\n function encode(num) {\n var encoded = '';\n\n do {\n encoded = alphabet[num % length] + encoded;\n num = Math.floor(num / length);\n } while (num > 0);\n\n return encoded;\n }\n\n /**\n * Return the integer value specified by the given string.\n *\n * @param {String} str The string to convert.\n * @returns {Number} The integer value represented by the string.\n * @api public\n */\n function decode(str) {\n var decoded = 0;\n\n for (i = 0; i < str.length; i++) {\n decoded = decoded * length + map[str.charAt(i)];\n }\n\n return decoded;\n }\n\n /**\n * Yeast: A tiny growing id generator.\n *\n * @returns {String} A unique id.\n * @api public\n */\n function yeast() {\n var now = encode(+new Date());\n\n if (now !== prev) return seed = 0, prev = now;\n return now + '.' + encode(seed++);\n }\n\n //\n // Map each character to its index.\n //\n for (; i < length; i++) {\n map[alphabet[i]] = i;\n } //\n // Expose the `yeast`, `encode` and `decode` functions.\n //\n yeast.encode = encode;\n yeast.decode = decode;\n module.exports = yeast;\n }, {}], 31: [function (_dereq_, module, exports) {\n\n /**\n * Module dependencies.\n */\n\n var url = _dereq_('./url');\n var parser = _dereq_('socket.io-parser');\n var Manager = _dereq_('./manager');\n var debug = _dereq_('debug')('socket.io-client');\n\n /**\n * Module exports.\n */\n\n module.exports = exports = lookup;\n\n /**\n * Managers cache.\n */\n\n var cache = exports.managers = {};\n\n /**\n * Looks up an existing `Manager` for multiplexing.\n * If the user summons:\n *\n * `io('http://localhost/a');`\n * `io('http://localhost/b');`\n *\n * We reuse the existing instance based on same scheme/port/host,\n * and we initialize sockets for each namespace.\n *\n * @api public\n */\n\n function lookup(uri, opts) {\n if ((typeof uri === \"undefined\" ? \"undefined\" : _typeof(uri)) == 'object') {\n opts = uri;\n uri = undefined;\n }\n\n opts = opts || {};\n\n var parsed = url(uri);\n var source = parsed.source;\n var id = parsed.id;\n var path = parsed.path;\n var sameNamespace = cache[id] && path in cache[id].nsps;\n var newConnection = opts.forceNew || opts['force new connection'] || false === opts.multiplex || sameNamespace;\n\n var io;\n\n if (newConnection) {\n debug('ignoring socket cache for %s', source);\n io = Manager(source, opts);\n } else {\n if (!cache[id]) {\n debug('new io instance for %s', source);\n cache[id] = Manager(source, opts);\n }\n io = cache[id];\n }\n\n return io.socket(parsed.path);\n }\n\n /**\n * Protocol version.\n *\n * @api public\n */\n\n exports.protocol = parser.protocol;\n\n /**\n * `connect`.\n *\n * @param {String} uri\n * @api public\n */\n\n exports.connect = lookup;\n\n /**\n * Expose constructors for standalone build.\n *\n * @api public\n */\n\n exports.Manager = _dereq_('./manager');\n exports.Socket = _dereq_('./socket');\n }, { \"./manager\": 32, \"./socket\": 34, \"./url\": 35, \"debug\": 39, \"socket.io-parser\": 47 }], 32: [function (_dereq_, module, exports) {\n\n /**\n * Module dependencies.\n */\n\n var eio = _dereq_('engine.io-client');\n var Socket = _dereq_('./socket');\n var Emitter = _dereq_('component-emitter');\n var parser = _dereq_('socket.io-parser');\n var on = _dereq_('./on');\n var bind = _dereq_('component-bind');\n var debug = _dereq_('debug')('socket.io-client:manager');\n var indexOf = _dereq_('indexof');\n var Backoff = _dereq_('backo2');\n\n /**\n * IE6+ hasOwnProperty\n */\n\n var has = Object.prototype.hasOwnProperty;\n\n /**\n * Module exports\n */\n\n module.exports = Manager;\n\n /**\n * `Manager` constructor.\n *\n * @param {String} engine instance or engine uri/opts\n * @param {Object} options\n * @api public\n */\n\n function Manager(uri, opts) {\n if (!(this instanceof Manager)) return new Manager(uri, opts);\n if (uri && 'object' == (typeof uri === \"undefined\" ? \"undefined\" : _typeof(uri))) {\n opts = uri;\n uri = undefined;\n }\n opts = opts || {};\n\n opts.path = opts.path || '/socket.io';\n this.nsps = {};\n this.subs = [];\n this.opts = opts;\n this.reconnection(opts.reconnection !== false);\n this.reconnectionAttempts(opts.reconnectionAttempts || Infinity);\n this.reconnectionDelay(opts.reconnectionDelay || 1000);\n this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000);\n this.randomizationFactor(opts.randomizationFactor || 0.5);\n this.backoff = new Backoff({\n min: this.reconnectionDelay(),\n max: this.reconnectionDelayMax(),\n jitter: this.randomizationFactor()\n });\n this.timeout(null == opts.timeout ? 20000 : opts.timeout);\n this.readyState = 'closed';\n this.uri = uri;\n this.connecting = [];\n this.lastPing = null;\n this.encoding = false;\n this.packetBuffer = [];\n this.encoder = new parser.Encoder();\n this.decoder = new parser.Decoder();\n this.autoConnect = opts.autoConnect !== false;\n if (this.autoConnect) this.open();\n }\n\n /**\n * Propagate given event to sockets and emit on `this`\n *\n * @api private\n */\n\n Manager.prototype.emitAll = function () {\n this.emit.apply(this, arguments);\n for (var nsp in this.nsps) {\n if (has.call(this.nsps, nsp)) {\n this.nsps[nsp].emit.apply(this.nsps[nsp], arguments);\n }\n }\n };\n\n /**\n * Update `socket.id` of all sockets\n *\n * @api private\n */\n\n Manager.prototype.updateSocketIds = function () {\n for (var nsp in this.nsps) {\n if (has.call(this.nsps, nsp)) {\n this.nsps[nsp].id = this.engine.id;\n }\n }\n };\n\n /**\n * Mix in `Emitter`.\n */\n\n Emitter(Manager.prototype);\n\n /**\n * Sets the `reconnection` config.\n *\n * @param {Boolean} true/false if it should automatically reconnect\n * @return {Manager} self or value\n * @api public\n */\n\n Manager.prototype.reconnection = function (v) {\n if (!arguments.length) return this._reconnection;\n this._reconnection = !!v;\n return this;\n };\n\n /**\n * Sets the reconnection attempts config.\n *\n * @param {Number} max reconnection attempts before giving up\n * @return {Manager} self or value\n * @api public\n */\n\n Manager.prototype.reconnectionAttempts = function (v) {\n if (!arguments.length) return this._reconnectionAttempts;\n this._reconnectionAttempts = v;\n return this;\n };\n\n /**\n * Sets the delay between reconnections.\n *\n * @param {Number} delay\n * @return {Manager} self or value\n * @api public\n */\n\n Manager.prototype.reconnectionDelay = function (v) {\n if (!arguments.length) return this._reconnectionDelay;\n this._reconnectionDelay = v;\n this.backoff && this.backoff.setMin(v);\n return this;\n };\n\n Manager.prototype.randomizationFactor = function (v) {\n if (!arguments.length) return this._randomizationFactor;\n this._randomizationFactor = v;\n this.backoff && this.backoff.setJitter(v);\n return this;\n };\n\n /**\n * Sets the maximum delay between reconnections.\n *\n * @param {Number} delay\n * @return {Manager} self or value\n * @api public\n */\n\n Manager.prototype.reconnectionDelayMax = function (v) {\n if (!arguments.length) return this._reconnectionDelayMax;\n this._reconnectionDelayMax = v;\n this.backoff && this.backoff.setMax(v);\n return this;\n };\n\n /**\n * Sets the connection timeout. `false` to disable\n *\n * @return {Manager} self or value\n * @api public\n */\n\n Manager.prototype.timeout = function (v) {\n if (!arguments.length) return this._timeout;\n this._timeout = v;\n return this;\n };\n\n /**\n * Starts trying to reconnect if reconnection is enabled and we have not\n * started reconnecting yet\n *\n * @api private\n */\n\n Manager.prototype.maybeReconnectOnOpen = function () {\n // Only try to reconnect if it's the first time we're connecting\n if (!this.reconnecting && this._reconnection && this.backoff.attempts === 0) {\n // keeps reconnection from firing twice for the same reconnection loop\n this.reconnect();\n }\n };\n\n /**\n * Sets the current transport `socket`.\n *\n * @param {Function} optional, callback\n * @return {Manager} self\n * @api public\n */\n\n Manager.prototype.open = Manager.prototype.connect = function (fn) {\n debug('readyState %s', this.readyState);\n if (~this.readyState.indexOf('open')) return this;\n\n debug('opening %s', this.uri);\n this.engine = eio(this.uri, this.opts);\n var socket = this.engine;\n var self = this;\n this.readyState = 'opening';\n this.skipReconnect = false;\n\n // emit `open`\n var openSub = on(socket, 'open', function () {\n self.onopen();\n fn && fn();\n });\n\n // emit `connect_error`\n var errorSub = on(socket, 'error', function (data) {\n debug('connect_error');\n self.cleanup();\n self.readyState = 'closed';\n self.emitAll('connect_error', data);\n if (fn) {\n var err = new Error('Connection error');\n err.data = data;\n fn(err);\n } else {\n // Only do this if there is no fn to handle the error\n self.maybeReconnectOnOpen();\n }\n });\n\n // emit `connect_timeout`\n if (false !== this._timeout) {\n var timeout = this._timeout;\n debug('connect attempt will timeout after %d', timeout);\n\n // set timer\n var timer = setTimeout(function () {\n debug('connect attempt timed out after %d', timeout);\n openSub.destroy();\n socket.close();\n socket.emit('error', 'timeout');\n self.emitAll('connect_timeout', timeout);\n }, timeout);\n\n this.subs.push({\n destroy: function destroy() {\n clearTimeout(timer);\n }\n });\n }\n\n this.subs.push(openSub);\n this.subs.push(errorSub);\n\n return this;\n };\n\n /**\n * Called upon transport open.\n *\n * @api private\n */\n\n Manager.prototype.onopen = function () {\n debug('open');\n\n // clear old subs\n this.cleanup();\n\n // mark as open\n this.readyState = 'open';\n this.emit('open');\n\n // add new subs\n var socket = this.engine;\n this.subs.push(on(socket, 'data', bind(this, 'ondata')));\n this.subs.push(on(socket, 'ping', bind(this, 'onping')));\n this.subs.push(on(socket, 'pong', bind(this, 'onpong')));\n this.subs.push(on(socket, 'error', bind(this, 'onerror')));\n this.subs.push(on(socket, 'close', bind(this, 'onclose')));\n this.subs.push(on(this.decoder, 'decoded', bind(this, 'ondecoded')));\n };\n\n /**\n * Called upon a ping.\n *\n * @api private\n */\n\n Manager.prototype.onping = function () {\n this.lastPing = new Date();\n this.emitAll('ping');\n };\n\n /**\n * Called upon a packet.\n *\n * @api private\n */\n\n Manager.prototype.onpong = function () {\n this.emitAll('pong', new Date() - this.lastPing);\n };\n\n /**\n * Called with data.\n *\n * @api private\n */\n\n Manager.prototype.ondata = function (data) {\n this.decoder.add(data);\n };\n\n /**\n * Called when parser fully decodes a packet.\n *\n * @api private\n */\n\n Manager.prototype.ondecoded = function (packet) {\n this.emit('packet', packet);\n };\n\n /**\n * Called upon socket error.\n *\n * @api private\n */\n\n Manager.prototype.onerror = function (err) {\n debug('error', err);\n this.emitAll('error', err);\n };\n\n /**\n * Creates a new socket for the given `nsp`.\n *\n * @return {Socket}\n * @api public\n */\n\n Manager.prototype.socket = function (nsp) {\n var socket = this.nsps[nsp];\n if (!socket) {\n socket = new Socket(this, nsp);\n this.nsps[nsp] = socket;\n var self = this;\n socket.on('connecting', onConnecting);\n socket.on('connect', function () {\n socket.id = self.engine.id;\n });\n\n if (this.autoConnect) {\n // manually call here since connecting evnet is fired before listening\n onConnecting();\n }\n }\n\n function onConnecting() {\n if (!~indexOf(self.connecting, socket)) {\n self.connecting.push(socket);\n }\n }\n\n return socket;\n };\n\n /**\n * Called upon a socket close.\n *\n * @param {Socket} socket\n */\n\n Manager.prototype.destroy = function (socket) {\n var index = indexOf(this.connecting, socket);\n if (~index) this.connecting.splice(index, 1);\n if (this.connecting.length) return;\n\n this.close();\n };\n\n /**\n * Writes a packet.\n *\n * @param {Object} packet\n * @api private\n */\n\n Manager.prototype.packet = function (packet) {\n debug('writing packet %j', packet);\n var self = this;\n\n if (!self.encoding) {\n // encode, then write to engine with result\n self.encoding = true;\n this.encoder.encode(packet, function (encodedPackets) {\n for (var i = 0; i < encodedPackets.length; i++) {\n self.engine.write(encodedPackets[i], packet.options);\n }\n self.encoding = false;\n self.processPacketQueue();\n });\n } else {\n // add packet to the queue\n self.packetBuffer.push(packet);\n }\n };\n\n /**\n * If packet buffer is non-empty, begins encoding the\n * next packet in line.\n *\n * @api private\n */\n\n Manager.prototype.processPacketQueue = function () {\n if (this.packetBuffer.length > 0 && !this.encoding) {\n var pack = this.packetBuffer.shift();\n this.packet(pack);\n }\n };\n\n /**\n * Clean up transport subscriptions and packet buffer.\n *\n * @api private\n */\n\n Manager.prototype.cleanup = function () {\n debug('cleanup');\n\n var sub;\n while (sub = this.subs.shift()) {\n sub.destroy();\n }this.packetBuffer = [];\n this.encoding = false;\n this.lastPing = null;\n\n this.decoder.destroy();\n };\n\n /**\n * Close the current socket.\n *\n * @api private\n */\n\n Manager.prototype.close = Manager.prototype.disconnect = function () {\n debug('disconnect');\n this.skipReconnect = true;\n this.reconnecting = false;\n if ('opening' == this.readyState) {\n // `onclose` will not fire because\n // an open event never happened\n this.cleanup();\n }\n this.backoff.reset();\n this.readyState = 'closed';\n if (this.engine) this.engine.close();\n };\n\n /**\n * Called upon engine close.\n *\n * @api private\n */\n\n Manager.prototype.onclose = function (reason) {\n debug('onclose');\n\n this.cleanup();\n this.backoff.reset();\n this.readyState = 'closed';\n this.emit('close', reason);\n\n if (this._reconnection && !this.skipReconnect) {\n this.reconnect();\n }\n };\n\n /**\n * Attempt a reconnection.\n *\n * @api private\n */\n\n Manager.prototype.reconnect = function () {\n if (this.reconnecting || this.skipReconnect) return this;\n\n var self = this;\n\n if (this.backoff.attempts >= this._reconnectionAttempts) {\n debug('reconnect failed');\n this.backoff.reset();\n this.emitAll('reconnect_failed');\n this.reconnecting = false;\n } else {\n var delay = this.backoff.duration();\n debug('will wait %dms before reconnect attempt', delay);\n\n this.reconnecting = true;\n var timer = setTimeout(function () {\n if (self.skipReconnect) return;\n\n debug('attempting reconnect');\n self.emitAll('reconnect_attempt', self.backoff.attempts);\n self.emitAll('reconnecting', self.backoff.attempts);\n\n // check again for the case socket closed in above events\n if (self.skipReconnect) return;\n\n self.open(function (err) {\n if (err) {\n debug('reconnect attempt error');\n self.reconnecting = false;\n self.reconnect();\n self.emitAll('reconnect_error', err.data);\n } else {\n debug('reconnect success');\n self.onreconnect();\n }\n });\n }, delay);\n\n this.subs.push({\n destroy: function destroy() {\n clearTimeout(timer);\n }\n });\n }\n };\n\n /**\n * Called upon successful reconnect.\n *\n * @api private\n */\n\n Manager.prototype.onreconnect = function () {\n var attempt = this.backoff.attempts;\n this.reconnecting = false;\n this.backoff.reset();\n this.updateSocketIds();\n this.emitAll('reconnect', attempt);\n };\n }, { \"./on\": 33, \"./socket\": 34, \"backo2\": 36, \"component-bind\": 37, \"component-emitter\": 38, \"debug\": 39, \"engine.io-client\": 1, \"indexof\": 42, \"socket.io-parser\": 47 }], 33: [function (_dereq_, module, exports) {\n\n /**\n * Module exports.\n */\n\n module.exports = on;\n\n /**\n * Helper for subscriptions.\n *\n * @param {Object|EventEmitter} obj with `Emitter` mixin or `EventEmitter`\n * @param {String} event name\n * @param {Function} callback\n * @api public\n */\n\n function on(obj, ev, fn) {\n obj.on(ev, fn);\n return {\n destroy: function destroy() {\n obj.removeListener(ev, fn);\n }\n };\n }\n }, {}], 34: [function (_dereq_, module, exports) {\n\n /**\n * Module dependencies.\n */\n\n var parser = _dereq_('socket.io-parser');\n var Emitter = _dereq_('component-emitter');\n var toArray = _dereq_('to-array');\n var on = _dereq_('./on');\n var bind = _dereq_('component-bind');\n var debug = _dereq_('debug')('socket.io-client:socket');\n var hasBin = _dereq_('has-binary');\n\n /**\n * Module exports.\n */\n\n module.exports = exports = Socket;\n\n /**\n * Internal events (blacklisted).\n * These events can't be emitted by the user.\n *\n * @api private\n */\n\n var events = {\n connect: 1,\n connect_error: 1,\n connect_timeout: 1,\n connecting: 1,\n disconnect: 1,\n error: 1,\n reconnect: 1,\n reconnect_attempt: 1,\n reconnect_failed: 1,\n reconnect_error: 1,\n reconnecting: 1,\n ping: 1,\n pong: 1\n };\n\n /**\n * Shortcut to `Emitter#emit`.\n */\n\n var emit = Emitter.prototype.emit;\n\n /**\n * `Socket` constructor.\n *\n * @api public\n */\n\n function Socket(io, nsp) {\n this.io = io;\n this.nsp = nsp;\n this.json = this; // compat\n this.ids = 0;\n this.acks = {};\n this.receiveBuffer = [];\n this.sendBuffer = [];\n this.connected = false;\n this.disconnected = true;\n if (this.io.autoConnect) this.open();\n }\n\n /**\n * Mix in `Emitter`.\n */\n\n Emitter(Socket.prototype);\n\n /**\n * Subscribe to open, close and packet events\n *\n * @api private\n */\n\n Socket.prototype.subEvents = function () {\n if (this.subs) return;\n\n var io = this.io;\n this.subs = [on(io, 'open', bind(this, 'onopen')), on(io, 'packet', bind(this, 'onpacket')), on(io, 'close', bind(this, 'onclose'))];\n };\n\n /**\n * \"Opens\" the socket.\n *\n * @api public\n */\n\n Socket.prototype.open = Socket.prototype.connect = function () {\n if (this.connected) return this;\n\n this.subEvents();\n this.io.open(); // ensure open\n if ('open' == this.io.readyState) this.onopen();\n this.emit('connecting');\n return this;\n };\n\n /**\n * Sends a `message` event.\n *\n * @return {Socket} self\n * @api public\n */\n\n Socket.prototype.send = function () {\n var args = toArray(arguments);\n args.unshift('message');\n this.emit.apply(this, args);\n return this;\n };\n\n /**\n * Override `emit`.\n * If the event is in `events`, it's emitted normally.\n *\n * @param {String} event name\n * @return {Socket} self\n * @api public\n */\n\n Socket.prototype.emit = function (ev) {\n if (events.hasOwnProperty(ev)) {\n emit.apply(this, arguments);\n return this;\n }\n\n var args = toArray(arguments);\n var parserType = parser.EVENT; // default\n if (hasBin(args)) {\n parserType = parser.BINARY_EVENT;\n } // binary\n var packet = { type: parserType, data: args };\n\n packet.options = {};\n packet.options.compress = !this.flags || false !== this.flags.compress;\n\n // event ack callback\n if ('function' == typeof args[args.length - 1]) {\n debug('emitting packet with ack id %d', this.ids);\n this.acks[this.ids] = args.pop();\n packet.id = this.ids++;\n }\n\n if (this.connected) {\n this.packet(packet);\n } else {\n this.sendBuffer.push(packet);\n }\n\n delete this.flags;\n\n return this;\n };\n\n /**\n * Sends a packet.\n *\n * @param {Object} packet\n * @api private\n */\n\n Socket.prototype.packet = function (packet) {\n packet.nsp = this.nsp;\n this.io.packet(packet);\n };\n\n /**\n * Called upon engine `open`.\n *\n * @api private\n */\n\n Socket.prototype.onopen = function () {\n debug('transport is open - connecting');\n\n // write connect packet if necessary\n if ('/' != this.nsp) {\n this.packet({ type: parser.CONNECT });\n }\n };\n\n /**\n * Called upon engine `close`.\n *\n * @param {String} reason\n * @api private\n */\n\n Socket.prototype.onclose = function (reason) {\n debug('close (%s)', reason);\n this.connected = false;\n this.disconnected = true;\n delete this.id;\n this.emit('disconnect', reason);\n };\n\n /**\n * Called with socket packet.\n *\n * @param {Object} packet\n * @api private\n */\n\n Socket.prototype.onpacket = function (packet) {\n if (packet.nsp != this.nsp) return;\n\n switch (packet.type) {\n case parser.CONNECT:\n this.onconnect();\n break;\n\n case parser.EVENT:\n this.onevent(packet);\n break;\n\n case parser.BINARY_EVENT:\n this.onevent(packet);\n break;\n\n case parser.ACK:\n this.onack(packet);\n break;\n\n case parser.BINARY_ACK:\n this.onack(packet);\n break;\n\n case parser.DISCONNECT:\n this.ondisconnect();\n break;\n\n case parser.ERROR:\n this.emit('error', packet.data);\n break;\n }\n };\n\n /**\n * Called upon a server event.\n *\n * @param {Object} packet\n * @api private\n */\n\n Socket.prototype.onevent = function (packet) {\n var args = packet.data || [];\n debug('emitting event %j', args);\n\n if (null != packet.id) {\n debug('attaching ack callback to event');\n args.push(this.ack(packet.id));\n }\n\n if (this.connected) {\n emit.apply(this, args);\n } else {\n this.receiveBuffer.push(args);\n }\n };\n\n /**\n * Produces an ack callback to emit with an event.\n *\n * @api private\n */\n\n Socket.prototype.ack = function (id) {\n var self = this;\n var sent = false;\n return function () {\n // prevent double callbacks\n if (sent) return;\n sent = true;\n var args = toArray(arguments);\n debug('sending ack %j', args);\n\n var type = hasBin(args) ? parser.BINARY_ACK : parser.ACK;\n self.packet({\n type: type,\n id: id,\n data: args\n });\n };\n };\n\n /**\n * Called upon a server acknowlegement.\n *\n * @param {Object} packet\n * @api private\n */\n\n Socket.prototype.onack = function (packet) {\n var ack = this.acks[packet.id];\n if ('function' == typeof ack) {\n debug('calling ack %s with %j', packet.id, packet.data);\n ack.apply(this, packet.data);\n delete this.acks[packet.id];\n } else {\n debug('bad ack %s', packet.id);\n }\n };\n\n /**\n * Called upon server connect.\n *\n * @api private\n */\n\n Socket.prototype.onconnect = function () {\n this.connected = true;\n this.disconnected = false;\n this.emit('connect');\n this.emitBuffered();\n };\n\n /**\n * Emit buffered events (received and emitted).\n *\n * @api private\n */\n\n Socket.prototype.emitBuffered = function () {\n var i;\n for (i = 0; i < this.receiveBuffer.length; i++) {\n emit.apply(this, this.receiveBuffer[i]);\n }\n this.receiveBuffer = [];\n\n for (i = 0; i < this.sendBuffer.length; i++) {\n this.packet(this.sendBuffer[i]);\n }\n this.sendBuffer = [];\n };\n\n /**\n * Called upon server disconnect.\n *\n * @api private\n */\n\n Socket.prototype.ondisconnect = function () {\n debug('server disconnect (%s)', this.nsp);\n this.destroy();\n this.onclose('io server disconnect');\n };\n\n /**\n * Called upon forced client/server side disconnections,\n * this method ensures the manager stops tracking us and\n * that reconnections don't get triggered for this.\n *\n * @api private.\n */\n\n Socket.prototype.destroy = function () {\n if (this.subs) {\n // clean subscriptions to avoid reconnections\n for (var i = 0; i < this.subs.length; i++) {\n this.subs[i].destroy();\n }\n this.subs = null;\n }\n\n this.io.destroy(this);\n };\n\n /**\n * Disconnects the socket manually.\n *\n * @return {Socket} self\n * @api public\n */\n\n Socket.prototype.close = Socket.prototype.disconnect = function () {\n if (this.connected) {\n debug('performing disconnect (%s)', this.nsp);\n this.packet({ type: parser.DISCONNECT });\n }\n\n // remove socket from pool\n this.destroy();\n\n if (this.connected) {\n // fire events\n this.onclose('io client disconnect');\n }\n return this;\n };\n\n /**\n * Sets the compress flag.\n *\n * @param {Boolean} if `true`, compresses the sending data\n * @return {Socket} self\n * @api public\n */\n\n Socket.prototype.compress = function (compress) {\n this.flags = this.flags || {};\n this.flags.compress = compress;\n return this;\n };\n }, { \"./on\": 33, \"component-bind\": 37, \"component-emitter\": 38, \"debug\": 39, \"has-binary\": 41, \"socket.io-parser\": 47, \"to-array\": 51 }], 35: [function (_dereq_, module, exports) {\n (function (global) {\n\n /**\n * Module dependencies.\n */\n\n var parseuri = _dereq_('parseuri');\n var debug = _dereq_('debug')('socket.io-client:url');\n\n /**\n * Module exports.\n */\n\n module.exports = url;\n\n /**\n * URL parser.\n *\n * @param {String} url\n * @param {Object} An object meant to mimic window.location.\n * Defaults to window.location.\n * @api public\n */\n\n function url(uri, loc) {\n var obj = uri;\n\n // default to window.location\n var loc = loc || global.location;\n if (null == uri) uri = loc.protocol + '//' + loc.host;\n\n // relative path support\n if ('string' == typeof uri) {\n if ('/' == uri.charAt(0)) {\n if ('/' == uri.charAt(1)) {\n uri = loc.protocol + uri;\n } else {\n uri = loc.host + uri;\n }\n }\n\n if (!/^(https?|wss?):\\/\\//.test(uri)) {\n debug('protocol-less url %s', uri);\n if ('undefined' != typeof loc) {\n uri = loc.protocol + '//' + uri;\n } else {\n uri = 'https://' + uri;\n }\n }\n\n // parse\n debug('parse %s', uri);\n obj = parseuri(uri);\n }\n\n // make sure we treat `localhost:80` and `localhost` equally\n if (!obj.port) {\n if (/^(http|ws)$/.test(obj.protocol)) {\n obj.port = '80';\n } else if (/^(http|ws)s$/.test(obj.protocol)) {\n obj.port = '443';\n }\n }\n\n obj.path = obj.path || '/';\n\n var ipv6 = obj.host.indexOf(':') !== -1;\n var host = ipv6 ? '[' + obj.host + ']' : obj.host;\n\n // define unique id\n obj.id = obj.protocol + '://' + host + ':' + obj.port;\n // define href\n obj.href = obj.protocol + '://' + host + (loc && loc.port == obj.port ? '' : ':' + obj.port);\n\n return obj;\n }\n }).call(this, typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n }, { \"debug\": 39, \"parseuri\": 45 }], 36: [function (_dereq_, module, exports) {\n\n /**\n * Expose `Backoff`.\n */\n\n module.exports = Backoff;\n\n /**\n * Initialize backoff timer with `opts`.\n *\n * - `min` initial timeout in milliseconds [100]\n * - `max` max timeout [10000]\n * - `jitter` [0]\n * - `factor` [2]\n *\n * @param {Object} opts\n * @api public\n */\n\n function Backoff(opts) {\n opts = opts || {};\n this.ms = opts.min || 100;\n this.max = opts.max || 10000;\n this.factor = opts.factor || 2;\n this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0;\n this.attempts = 0;\n }\n\n /**\n * Return the backoff duration.\n *\n * @return {Number}\n * @api public\n */\n\n Backoff.prototype.duration = function () {\n var ms = this.ms * Math.pow(this.factor, this.attempts++);\n if (this.jitter) {\n var rand = Math.random();\n var deviation = Math.floor(rand * this.jitter * ms);\n ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation;\n }\n return Math.min(ms, this.max) | 0;\n };\n\n /**\n * Reset the number of attempts.\n *\n * @api public\n */\n\n Backoff.prototype.reset = function () {\n this.attempts = 0;\n };\n\n /**\n * Set the minimum duration\n *\n * @api public\n */\n\n Backoff.prototype.setMin = function (min) {\n this.ms = min;\n };\n\n /**\n * Set the maximum duration\n *\n * @api public\n */\n\n Backoff.prototype.setMax = function (max) {\n this.max = max;\n };\n\n /**\n * Set the jitter\n *\n * @api public\n */\n\n Backoff.prototype.setJitter = function (jitter) {\n this.jitter = jitter;\n };\n }, {}], 37: [function (_dereq_, module, exports) {\n /**\n * Slice reference.\n */\n\n var slice = [].slice;\n\n /**\n * Bind `obj` to `fn`.\n *\n * @param {Object} obj\n * @param {Function|String} fn or string\n * @return {Function}\n * @api public\n */\n\n module.exports = function (obj, fn) {\n if ('string' == typeof fn) fn = obj[fn];\n if ('function' != typeof fn) throw new Error('bind() requires a function');\n var args = slice.call(arguments, 2);\n return function () {\n return fn.apply(obj, args.concat(slice.call(arguments)));\n };\n };\n }, {}], 38: [function (_dereq_, module, exports) {\n\n /**\n * Expose `Emitter`.\n */\n\n module.exports = Emitter;\n\n /**\n * Initialize a new `Emitter`.\n *\n * @api public\n */\n\n function Emitter(obj) {\n if (obj) return mixin(obj);\n };\n\n /**\n * Mixin the emitter properties.\n *\n * @param {Object} obj\n * @return {Object}\n * @api private\n */\n\n function mixin(obj) {\n for (var key in Emitter.prototype) {\n obj[key] = Emitter.prototype[key];\n }\n return obj;\n }\n\n /**\n * Listen on the given `event` with `fn`.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\n Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) {\n this._callbacks = this._callbacks || {};\n (this._callbacks['$' + event] = this._callbacks['$' + event] || []).push(fn);\n return this;\n };\n\n /**\n * Adds an `event` listener that will be invoked a single\n * time then automatically removed.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\n Emitter.prototype.once = function (event, fn) {\n function on() {\n this.off(event, on);\n fn.apply(this, arguments);\n }\n\n on.fn = fn;\n this.on(event, on);\n return this;\n };\n\n /**\n * Remove the given callback for `event` or all\n * registered callbacks.\n *\n * @param {String} event\n * @param {Function} fn\n * @return {Emitter}\n * @api public\n */\n\n Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) {\n this._callbacks = this._callbacks || {};\n\n // all\n if (0 == arguments.length) {\n this._callbacks = {};\n return this;\n }\n\n // specific event\n var callbacks = this._callbacks['$' + event];\n if (!callbacks) return this;\n\n // remove all handlers\n if (1 == arguments.length) {\n delete this._callbacks['$' + event];\n return this;\n }\n\n // remove specific handler\n var cb;\n for (var i = 0; i < callbacks.length; i++) {\n cb = callbacks[i];\n if (cb === fn || cb.fn === fn) {\n callbacks.splice(i, 1);\n break;\n }\n }\n return this;\n };\n\n /**\n * Emit `event` with the given args.\n *\n * @param {String} event\n * @param {Mixed} ...\n * @return {Emitter}\n */\n\n Emitter.prototype.emit = function (event) {\n this._callbacks = this._callbacks || {};\n var args = [].slice.call(arguments, 1),\n callbacks = this._callbacks['$' + event];\n\n if (callbacks) {\n callbacks = callbacks.slice(0);\n for (var i = 0, len = callbacks.length; i < len; ++i) {\n callbacks[i].apply(this, args);\n }\n }\n\n return this;\n };\n\n /**\n * Return array of callbacks for `event`.\n *\n * @param {String} event\n * @return {Array}\n * @api public\n */\n\n Emitter.prototype.listeners = function (event) {\n this._callbacks = this._callbacks || {};\n return this._callbacks['$' + event] || [];\n };\n\n /**\n * Check if this emitter has `event` handlers.\n *\n * @param {String} event\n * @return {Boolean}\n * @api public\n */\n\n Emitter.prototype.hasListeners = function (event) {\n return !!this.listeners(event).length;\n };\n }, {}], 39: [function (_dereq_, module, exports) {\n arguments[4][17][0].apply(exports, arguments);\n }, { \"./debug\": 40, \"dup\": 17 }], 40: [function (_dereq_, module, exports) {\n arguments[4][18][0].apply(exports, arguments);\n }, { \"dup\": 18, \"ms\": 44 }], 41: [function (_dereq_, module, exports) {\n (function (global) {\n\n /*\n * Module requirements.\n */\n\n var isArray = _dereq_('isarray');\n\n /**\n * Module exports.\n */\n\n module.exports = hasBinary;\n\n /**\n * Checks for binary data.\n *\n * Right now only Buffer and ArrayBuffer are supported..\n *\n * @param {Object} anything\n * @api public\n */\n\n function hasBinary(data) {\n\n function _hasBinary(obj) {\n if (!obj) return false;\n\n if (global.Buffer && global.Buffer.isBuffer && global.Buffer.isBuffer(obj) || global.ArrayBuffer && obj instanceof ArrayBuffer || global.Blob && obj instanceof Blob || global.File && obj instanceof File) {\n return true;\n }\n\n if (isArray(obj)) {\n for (var i = 0; i < obj.length; i++) {\n if (_hasBinary(obj[i])) {\n return true;\n }\n }\n } else if (obj && 'object' == (typeof obj === \"undefined\" ? \"undefined\" : _typeof(obj))) {\n // see: https://github.com/Automattic/has-binary/pull/4\n if (obj.toJSON && 'function' == typeof obj.toJSON) {\n obj = obj.toJSON();\n }\n\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key) && _hasBinary(obj[key])) {\n return true;\n }\n }\n }\n\n return false;\n }\n\n return _hasBinary(data);\n }\n }).call(this, typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n }, { \"isarray\": 43 }], 42: [function (_dereq_, module, exports) {\n arguments[4][23][0].apply(exports, arguments);\n }, { \"dup\": 23 }], 43: [function (_dereq_, module, exports) {\n arguments[4][24][0].apply(exports, arguments);\n }, { \"dup\": 24 }], 44: [function (_dereq_, module, exports) {\n arguments[4][25][0].apply(exports, arguments);\n }, { \"dup\": 25 }], 45: [function (_dereq_, module, exports) {\n arguments[4][28][0].apply(exports, arguments);\n }, { \"dup\": 28 }], 46: [function (_dereq_, module, exports) {\n (function (global) {\n /*global Blob,File*/\n\n /**\n * Module requirements\n */\n\n var isArray = _dereq_('isarray');\n var isBuf = _dereq_('./is-buffer');\n\n /**\n * Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder.\n * Anything with blobs or files should be fed through removeBlobs before coming\n * here.\n *\n * @param {Object} packet - socket.io event packet\n * @return {Object} with deconstructed packet and list of buffers\n * @api public\n */\n\n exports.deconstructPacket = function (packet) {\n var buffers = [];\n var packetData = packet.data;\n\n function _deconstructPacket(data) {\n if (!data) return data;\n\n if (isBuf(data)) {\n var placeholder = { _placeholder: true, num: buffers.length };\n buffers.push(data);\n return placeholder;\n } else if (isArray(data)) {\n var newData = new Array(data.length);\n for (var i = 0; i < data.length; i++) {\n newData[i] = _deconstructPacket(data[i]);\n }\n return newData;\n } else if ('object' == (typeof data === \"undefined\" ? \"undefined\" : _typeof(data)) && !(data instanceof Date)) {\n var newData = {};\n for (var key in data) {\n newData[key] = _deconstructPacket(data[key]);\n }\n return newData;\n }\n return data;\n }\n\n var pack = packet;\n pack.data = _deconstructPacket(packetData);\n pack.attachments = buffers.length; // number of binary 'attachments'\n return { packet: pack, buffers: buffers };\n };\n\n /**\n * Reconstructs a binary packet from its placeholder packet and buffers\n *\n * @param {Object} packet - event packet with placeholders\n * @param {Array} buffers - binary buffers to put in placeholder positions\n * @return {Object} reconstructed packet\n * @api public\n */\n\n exports.reconstructPacket = function (packet, buffers) {\n var curPlaceHolder = 0;\n\n function _reconstructPacket(data) {\n if (data && data._placeholder) {\n var buf = buffers[data.num]; // appropriate buffer (should be natural order anyway)\n return buf;\n } else if (isArray(data)) {\n for (var i = 0; i < data.length; i++) {\n data[i] = _reconstructPacket(data[i]);\n }\n return data;\n } else if (data && 'object' == (typeof data === \"undefined\" ? \"undefined\" : _typeof(data))) {\n for (var key in data) {\n data[key] = _reconstructPacket(data[key]);\n }\n return data;\n }\n return data;\n }\n\n packet.data = _reconstructPacket(packet.data);\n packet.attachments = undefined; // no longer useful\n return packet;\n };\n\n /**\n * Asynchronously removes Blobs or Files from data via\n * FileReader's readAsArrayBuffer method. Used before encoding\n * data as msgpack. Calls callback with the blobless data.\n *\n * @param {Object} data\n * @param {Function} callback\n * @api private\n */\n\n exports.removeBlobs = function (data, callback) {\n function _removeBlobs(obj, curKey, containingObject) {\n if (!obj) return obj;\n\n // convert any blob\n if (global.Blob && obj instanceof Blob || global.File && obj instanceof File) {\n pendingBlobs++;\n\n // async filereader\n var fileReader = new FileReader();\n fileReader.onload = function () {\n // this.result == arraybuffer\n if (containingObject) {\n containingObject[curKey] = this.result;\n } else {\n bloblessData = this.result;\n }\n\n // if nothing pending its callback time\n if (! --pendingBlobs) {\n callback(bloblessData);\n }\n };\n\n fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer\n } else if (isArray(obj)) {\n // handle array\n for (var i = 0; i < obj.length; i++) {\n _removeBlobs(obj[i], i, obj);\n }\n } else if (obj && 'object' == (typeof obj === \"undefined\" ? \"undefined\" : _typeof(obj)) && !isBuf(obj)) {\n // and object\n for (var key in obj) {\n _removeBlobs(obj[key], key, obj);\n }\n }\n }\n\n var pendingBlobs = 0;\n var bloblessData = data;\n _removeBlobs(bloblessData);\n if (!pendingBlobs) {\n callback(bloblessData);\n }\n };\n }).call(this, typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n }, { \"./is-buffer\": 48, \"isarray\": 43 }], 47: [function (_dereq_, module, exports) {\n\n /**\n * Module dependencies.\n */\n\n var debug = _dereq_('debug')('socket.io-parser');\n var json = _dereq_('json3');\n var isArray = _dereq_('isarray');\n var Emitter = _dereq_('component-emitter');\n var binary = _dereq_('./binary');\n var isBuf = _dereq_('./is-buffer');\n\n /**\n * Protocol version.\n *\n * @api public\n */\n\n exports.protocol = 4;\n\n /**\n * Packet types.\n *\n * @api public\n */\n\n exports.types = ['CONNECT', 'DISCONNECT', 'EVENT', 'BINARY_EVENT', 'ACK', 'BINARY_ACK', 'ERROR'];\n\n /**\n * Packet type `connect`.\n *\n * @api public\n */\n\n exports.CONNECT = 0;\n\n /**\n * Packet type `disconnect`.\n *\n * @api public\n */\n\n exports.DISCONNECT = 1;\n\n /**\n * Packet type `event`.\n *\n * @api public\n */\n\n exports.EVENT = 2;\n\n /**\n * Packet type `ack`.\n *\n * @api public\n */\n\n exports.ACK = 3;\n\n /**\n * Packet type `error`.\n *\n * @api public\n */\n\n exports.ERROR = 4;\n\n /**\n * Packet type 'binary event'\n *\n * @api public\n */\n\n exports.BINARY_EVENT = 5;\n\n /**\n * Packet type `binary ack`. For acks with binary arguments.\n *\n * @api public\n */\n\n exports.BINARY_ACK = 6;\n\n /**\n * Encoder constructor.\n *\n * @api public\n */\n\n exports.Encoder = Encoder;\n\n /**\n * Decoder constructor.\n *\n * @api public\n */\n\n exports.Decoder = Decoder;\n\n /**\n * A socket.io Encoder instance\n *\n * @api public\n */\n\n function Encoder() {}\n\n /**\n * Encode a packet as a single string if non-binary, or as a\n * buffer sequence, depending on packet type.\n *\n * @param {Object} obj - packet object\n * @param {Function} callback - function to handle encodings (likely engine.write)\n * @return Calls callback with Array of encodings\n * @api public\n */\n\n Encoder.prototype.encode = function (obj, callback) {\n debug('encoding packet %j', obj);\n\n if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {\n encodeAsBinary(obj, callback);\n } else {\n var encoding = encodeAsString(obj);\n callback([encoding]);\n }\n };\n\n /**\n * Encode packet as string.\n *\n * @param {Object} packet\n * @return {String} encoded\n * @api private\n */\n\n function encodeAsString(obj) {\n var str = '';\n var nsp = false;\n\n // first is type\n str += obj.type;\n\n // attachments if we have them\n if (exports.BINARY_EVENT == obj.type || exports.BINARY_ACK == obj.type) {\n str += obj.attachments;\n str += '-';\n }\n\n // if we have a namespace other than `/`\n // we append it followed by a comma `,`\n if (obj.nsp && '/' != obj.nsp) {\n nsp = true;\n str += obj.nsp;\n }\n\n // immediately followed by the id\n if (null != obj.id) {\n if (nsp) {\n str += ',';\n nsp = false;\n }\n str += obj.id;\n }\n\n // json data\n if (null != obj.data) {\n if (nsp) str += ',';\n str += json.stringify(obj.data);\n }\n\n debug('encoded %j as %s', obj, str);\n return str;\n }\n\n /**\n * Encode packet as 'buffer sequence' by removing blobs, and\n * deconstructing packet into object with placeholders and\n * a list of buffers.\n *\n * @param {Object} packet\n * @return {Buffer} encoded\n * @api private\n */\n\n function encodeAsBinary(obj, callback) {\n\n function writeEncoding(bloblessData) {\n var deconstruction = binary.deconstructPacket(bloblessData);\n var pack = encodeAsString(deconstruction.packet);\n var buffers = deconstruction.buffers;\n\n buffers.unshift(pack); // add packet info to beginning of data list\n callback(buffers); // write all the buffers\n }\n\n binary.removeBlobs(obj, writeEncoding);\n }\n\n /**\n * A socket.io Decoder instance\n *\n * @return {Object} decoder\n * @api public\n */\n\n function Decoder() {\n this.reconstructor = null;\n }\n\n /**\n * Mix in `Emitter` with Decoder.\n */\n\n Emitter(Decoder.prototype);\n\n /**\n * Decodes an ecoded packet string into packet JSON.\n *\n * @param {String} obj - encoded packet\n * @return {Object} packet\n * @api public\n */\n\n Decoder.prototype.add = function (obj) {\n var packet;\n if ('string' == typeof obj) {\n packet = decodeString(obj);\n if (exports.BINARY_EVENT == packet.type || exports.BINARY_ACK == packet.type) {\n // binary packet's json\n this.reconstructor = new BinaryReconstructor(packet);\n\n // no attachments, labeled binary but no binary data to follow\n if (this.reconstructor.reconPack.attachments === 0) {\n this.emit('decoded', packet);\n }\n } else {\n // non-binary full packet\n this.emit('decoded', packet);\n }\n } else if (isBuf(obj) || obj.base64) {\n // raw binary data\n if (!this.reconstructor) {\n throw new Error('got binary data when not reconstructing a packet');\n } else {\n packet = this.reconstructor.takeBinaryData(obj);\n if (packet) {\n // received final buffer\n this.reconstructor = null;\n this.emit('decoded', packet);\n }\n }\n } else {\n throw new Error('Unknown type: ' + obj);\n }\n };\n\n /**\n * Decode a packet String (JSON data)\n *\n * @param {String} str\n * @return {Object} packet\n * @api private\n */\n\n function decodeString(str) {\n var p = {};\n var i = 0;\n\n // look up type\n p.type = Number(str.charAt(0));\n if (null == exports.types[p.type]) return error();\n\n // look up attachments if type binary\n if (exports.BINARY_EVENT == p.type || exports.BINARY_ACK == p.type) {\n var buf = '';\n while (str.charAt(++i) != '-') {\n buf += str.charAt(i);\n if (i == str.length) break;\n }\n if (buf != Number(buf) || str.charAt(i) != '-') {\n throw new Error('Illegal attachments');\n }\n p.attachments = Number(buf);\n }\n\n // look up namespace (if any)\n if ('/' == str.charAt(i + 1)) {\n p.nsp = '';\n while (++i) {\n var c = str.charAt(i);\n if (',' == c) break;\n p.nsp += c;\n if (i == str.length) break;\n }\n } else {\n p.nsp = '/';\n }\n\n // look up id\n var next = str.charAt(i + 1);\n if ('' !== next && Number(next) == next) {\n p.id = '';\n while (++i) {\n var c = str.charAt(i);\n if (null == c || Number(c) != c) {\n --i;\n break;\n }\n p.id += str.charAt(i);\n if (i == str.length) break;\n }\n p.id = Number(p.id);\n }\n\n // look up json data\n if (str.charAt(++i)) {\n try {\n p.data = json.parse(str.substr(i));\n } catch (e) {\n return error();\n }\n }\n\n debug('decoded %s as %j', str, p);\n return p;\n }\n\n /**\n * Deallocates a parser's resources\n *\n * @api public\n */\n\n Decoder.prototype.destroy = function () {\n if (this.reconstructor) {\n this.reconstructor.finishedReconstruction();\n }\n };\n\n /**\n * A manager of a binary event's 'buffer sequence'. Should\n * be constructed whenever a packet of type BINARY_EVENT is\n * decoded.\n *\n * @param {Object} packet\n * @return {BinaryReconstructor} initialized reconstructor\n * @api private\n */\n\n function BinaryReconstructor(packet) {\n this.reconPack = packet;\n this.buffers = [];\n }\n\n /**\n * Method to be called when binary data received from connection\n * after a BINARY_EVENT packet.\n *\n * @param {Buffer | ArrayBuffer} binData - the raw binary data received\n * @return {null | Object} returns null if more binary data is expected or\n * a reconstructed packet object if all buffers have been received.\n * @api private\n */\n\n BinaryReconstructor.prototype.takeBinaryData = function (binData) {\n this.buffers.push(binData);\n if (this.buffers.length == this.reconPack.attachments) {\n // done with buffer list\n var packet = binary.reconstructPacket(this.reconPack, this.buffers);\n this.finishedReconstruction();\n return packet;\n }\n return null;\n };\n\n /**\n * Cleans up binary packet reconstruction variables.\n *\n * @api private\n */\n\n BinaryReconstructor.prototype.finishedReconstruction = function () {\n this.reconPack = null;\n this.buffers = [];\n };\n\n function error(data) {\n return {\n type: exports.ERROR,\n data: 'parser error'\n };\n }\n }, { \"./binary\": 46, \"./is-buffer\": 48, \"component-emitter\": 49, \"debug\": 39, \"isarray\": 43, \"json3\": 50 }], 48: [function (_dereq_, module, exports) {\n (function (global) {\n\n module.exports = isBuf;\n\n /**\n * Returns true if obj is a buffer or an arraybuffer.\n *\n * @api private\n */\n\n function isBuf(obj) {\n return global.Buffer && global.Buffer.isBuffer(obj) || global.ArrayBuffer && obj instanceof ArrayBuffer;\n }\n }).call(this, typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n }, {}], 49: [function (_dereq_, module, exports) {\n arguments[4][15][0].apply(exports, arguments);\n }, { \"dup\": 15 }], 50: [function (_dereq_, module, exports) {\n (function (global) {\n /*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */\n ;(function () {\n // Detect the `define` function exposed by asynchronous module loaders. The\n // strict `define` check is necessary for compatibility with `r.js`.\n var isLoader = typeof define === \"function\" && define.amd;\n\n // A set of types used to distinguish objects from primitives.\n var objectTypes = {\n \"function\": true,\n \"object\": true\n };\n\n // Detect the `exports` object exposed by CommonJS implementations.\n var freeExports = objectTypes[typeof exports === \"undefined\" ? \"undefined\" : _typeof(exports)] && exports && !exports.nodeType && exports;\n\n // Use the `global` object exposed by Node (including Browserify via\n // `insert-module-globals`), Narwhal, and Ringo as the default context,\n // and the `window` object in browsers. Rhino exports a `global` function\n // instead.\n var root = objectTypes[typeof window === \"undefined\" ? \"undefined\" : _typeof(window)] && window || this,\n freeGlobal = freeExports && objectTypes[typeof module === \"undefined\" ? \"undefined\" : _typeof(module)] && module && !module.nodeType && (typeof global === \"undefined\" ? \"undefined\" : _typeof(global)) == \"object\" && global;\n\n if (freeGlobal && (freeGlobal[\"global\"] === freeGlobal || freeGlobal[\"window\"] === freeGlobal || freeGlobal[\"self\"] === freeGlobal)) {\n root = freeGlobal;\n }\n\n // Public: Initializes JSON 3 using the given `context` object, attaching the\n // `stringify` and `parse` functions to the specified `exports` object.\n function runInContext(context, exports) {\n context || (context = root[\"Object\"]());\n exports || (exports = root[\"Object\"]());\n\n // Native constructor aliases.\n var Number = context[\"Number\"] || root[\"Number\"],\n String = context[\"String\"] || root[\"String\"],\n Object = context[\"Object\"] || root[\"Object\"],\n Date = context[\"Date\"] || root[\"Date\"],\n SyntaxError = context[\"SyntaxError\"] || root[\"SyntaxError\"],\n TypeError = context[\"TypeError\"] || root[\"TypeError\"],\n Math = context[\"Math\"] || root[\"Math\"],\n nativeJSON = context[\"JSON\"] || root[\"JSON\"];\n\n // Delegate to the native `stringify` and `parse` implementations.\n if ((typeof nativeJSON === \"undefined\" ? \"undefined\" : _typeof(nativeJSON)) == \"object\" && nativeJSON) {\n exports.stringify = nativeJSON.stringify;\n exports.parse = nativeJSON.parse;\n }\n\n // Convenience aliases.\n var objectProto = Object.prototype,\n getClass = objectProto.toString,\n _isProperty,\n _forEach,\n undef;\n\n // Test the `Date#getUTC*` methods. Based on work by @Yaffle.\n var isExtended = new Date(-3509827334573292);\n try {\n // The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical\n // results for certain dates in Opera >= 10.53.\n isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 &&\n // Safari < 2.0.2 stores the internal millisecond time value correctly,\n // but clips the values returned by the date methods to the range of\n // signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).\n isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;\n } catch (exception) {}\n\n // Internal: Determines whether the native `JSON.stringify` and `parse`\n // implementations are spec-compliant. Based on work by Ken Snyder.\n function has(name) {\n if (has[name] !== undef) {\n // Return cached feature test result.\n return has[name];\n }\n var isSupported;\n if (name == \"bug-string-char-index\") {\n // IE <= 7 doesn't support accessing string characters using square\n // bracket notation. IE 8 only supports this for primitives.\n isSupported = \"a\"[0] != \"a\";\n } else if (name == \"json\") {\n // Indicates whether both `JSON.stringify` and `JSON.parse` are\n // supported.\n isSupported = has(\"json-stringify\") && has(\"json-parse\");\n } else {\n var value,\n serialized = \"{\\\"a\\\":[1,true,false,null,\\\"\\\\u0000\\\\b\\\\n\\\\f\\\\r\\\\t\\\"]}\";\n // Test `JSON.stringify`.\n if (name == \"json-stringify\") {\n var stringify = exports.stringify,\n stringifySupported = typeof stringify == \"function\" && isExtended;\n if (stringifySupported) {\n // A test function object with a custom `toJSON` method.\n (value = function value() {\n return 1;\n }).toJSON = value;\n try {\n stringifySupported =\n // Firefox 3.1b1 and b2 serialize string, number, and boolean\n // primitives as object literals.\n stringify(0) === \"0\" &&\n // FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object\n // literals.\n stringify(new Number()) === \"0\" && stringify(new String()) == '\"\"' &&\n // FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or\n // does not define a canonical JSON representation (this applies to\n // objects with `toJSON` properties as well, *unless* they are nested\n // within an object or array).\n stringify(getClass) === undef &&\n // IE 8 serializes `undefined` as `\"undefined\"`. Safari <= 5.1.7 and\n // FF 3.1b3 pass this test.\n stringify(undef) === undef &&\n // Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,\n // respectively, if the value is omitted entirely.\n stringify() === undef &&\n // FF 3.1b1, 2 throw an error if the given value is not a number,\n // string, array, object, Boolean, or `null` literal. This applies to\n // objects with custom `toJSON` methods as well, unless they are nested\n // inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`\n // methods entirely.\n stringify(value) === \"1\" && stringify([value]) == \"[1]\" &&\n // Prototype <= 1.6.1 serializes `[undefined]` as `\"[]\"` instead of\n // `\"[null]\"`.\n stringify([undef]) == \"[null]\" &&\n // YUI 3.0.0b1 fails to serialize `null` literals.\n stringify(null) == \"null\" &&\n // FF 3.1b1, 2 halts serialization if an array contains a function:\n // `[1, true, getClass, 1]` serializes as \"[1,true,],\". FF 3.1b3\n // elides non-JSON values from objects and arrays, unless they\n // define custom `toJSON` methods.\n stringify([undef, getClass, null]) == \"[null,null,null]\" &&\n // Simple serialization test. FF 3.1b1 uses Unicode escape sequences\n // where character escape codes are expected (e.g., `\\b` => `\\u0008`).\n stringify({ \"a\": [value, true, false, null, \"\\x00\\b\\n\\f\\r\\t\"] }) == serialized &&\n // FF 3.1b1 and b2 ignore the `filter` and `width` arguments.\n stringify(null, value) === \"1\" && stringify([1, 2], null, 1) == \"[\\n 1,\\n 2\\n]\" &&\n // JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly\n // serialize extended years.\n stringify(new Date(-8.64e15)) == '\"-271821-04-20T00:00:00.000Z\"' &&\n // The milliseconds are optional in ES 5, but required in 5.1.\n stringify(new Date(8.64e15)) == '\"+275760-09-13T00:00:00.000Z\"' &&\n // Firefox <= 11.0 incorrectly serializes years prior to 0 as negative\n // four-digit years instead of six-digit years. Credits: @Yaffle.\n stringify(new Date(-621987552e5)) == '\"-000001-01-01T00:00:00.000Z\"' &&\n // Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond\n // values less than 1000. Credits: @Yaffle.\n stringify(new Date(-1)) == '\"1969-12-31T23:59:59.999Z\"';\n } catch (exception) {\n stringifySupported = false;\n }\n }\n isSupported = stringifySupported;\n }\n // Test `JSON.parse`.\n if (name == \"json-parse\") {\n var parse = exports.parse;\n if (typeof parse == \"function\") {\n try {\n // FF 3.1b1, b2 will throw an exception if a bare literal is provided.\n // Conforming implementations should also coerce the initial argument to\n // a string prior to parsing.\n if (parse(\"0\") === 0 && !parse(false)) {\n // Simple parsing test.\n value = parse(serialized);\n var parseSupported = value[\"a\"].length == 5 && value[\"a\"][0] === 1;\n if (parseSupported) {\n try {\n // Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.\n parseSupported = !parse('\"\\t\"');\n } catch (exception) {}\n if (parseSupported) {\n try {\n // FF 4.0 and 4.0.1 allow leading `+` signs and leading\n // decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow\n // certain octal literals.\n parseSupported = parse(\"01\") !== 1;\n } catch (exception) {}\n }\n if (parseSupported) {\n try {\n // FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal\n // points. These environments, along with FF 3.1b1 and 2,\n // also allow trailing commas in JSON objects and arrays.\n parseSupported = parse(\"1.\") !== 1;\n } catch (exception) {}\n }\n }\n }\n } catch (exception) {\n parseSupported = false;\n }\n }\n isSupported = parseSupported;\n }\n }\n return has[name] = !!isSupported;\n }\n\n if (!has(\"json\")) {\n // Common `[[Class]]` name aliases.\n var functionClass = \"[object Function]\",\n dateClass = \"[object Date]\",\n numberClass = \"[object Number]\",\n stringClass = \"[object String]\",\n arrayClass = \"[object Array]\",\n booleanClass = \"[object Boolean]\";\n\n // Detect incomplete support for accessing string characters by index.\n var charIndexBuggy = has(\"bug-string-char-index\");\n\n // Define additional utility methods if the `Date` methods are buggy.\n if (!isExtended) {\n var floor = Math.floor;\n // A mapping between the months of the year and the number of days between\n // January 1st and the first of the respective month.\n var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];\n // Internal: Calculates the number of days between the Unix epoch and the\n // first day of the given month.\n var getDay = function getDay(year, month) {\n return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);\n };\n }\n\n // Internal: Determines if a property is a direct property of the given\n // object. Delegates to the native `Object#hasOwnProperty` method.\n if (!(_isProperty = objectProto.hasOwnProperty)) {\n _isProperty = function isProperty(property) {\n var members = {},\n constructor;\n if ((members.__proto__ = null, members.__proto__ = {\n // The *proto* property cannot be set multiple times in recent\n // versions of Firefox and SeaMonkey.\n \"toString\": 1\n }, members).toString != getClass) {\n // Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but\n // supports the mutable *proto* property.\n _isProperty = function isProperty(property) {\n // Capture and break the object's prototype chain (see section 8.6.2\n // of the ES 5.1 spec). The parenthesized expression prevents an\n // unsafe transformation by the Closure Compiler.\n var original = this.__proto__,\n result = property in (this.__proto__ = null, this);\n // Restore the original prototype chain.\n this.__proto__ = original;\n return result;\n };\n } else {\n // Capture a reference to the top-level `Object` constructor.\n constructor = members.constructor;\n // Use the `constructor` property to simulate `Object#hasOwnProperty` in\n // other environments.\n _isProperty = function isProperty(property) {\n var parent = (this.constructor || constructor).prototype;\n return property in this && !(property in parent && this[property] === parent[property]);\n };\n }\n members = null;\n return _isProperty.call(this, property);\n };\n }\n\n // Internal: Normalizes the `for...in` iteration algorithm across\n // environments. Each enumerated key is yielded to a `callback` function.\n _forEach = function forEach(object, callback) {\n var size = 0,\n Properties,\n members,\n property;\n\n // Tests for bugs in the current environment's `for...in` algorithm. The\n // `valueOf` property inherits the non-enumerable flag from\n // `Object.prototype` in older versions of IE, Netscape, and Mozilla.\n (Properties = function Properties() {\n this.valueOf = 0;\n }).prototype.valueOf = 0;\n\n // Iterate over a new instance of the `Properties` class.\n members = new Properties();\n for (property in members) {\n // Ignore all properties inherited from `Object.prototype`.\n if (_isProperty.call(members, property)) {\n size++;\n }\n }\n Properties = members = null;\n\n // Normalize the iteration algorithm.\n if (!size) {\n // A list of non-enumerable properties inherited from `Object.prototype`.\n members = [\"valueOf\", \"toString\", \"toLocaleString\", \"propertyIsEnumerable\", \"isPrototypeOf\", \"hasOwnProperty\", \"constructor\"];\n // IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable\n // properties.\n _forEach = function forEach(object, callback) {\n var isFunction = getClass.call(object) == functionClass,\n property,\n length;\n var hasProperty = !isFunction && typeof object.constructor != \"function\" && objectTypes[_typeof(object.hasOwnProperty)] && object.hasOwnProperty || _isProperty;\n for (property in object) {\n // Gecko <= 1.0 enumerates the `prototype` property of functions under\n // certain conditions; IE does not.\n if (!(isFunction && property == \"prototype\") && hasProperty.call(object, property)) {\n callback(property);\n }\n }\n // Manually invoke the callback for each non-enumerable property.\n for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property)) {}\n };\n } else if (size == 2) {\n // Safari <= 2.0.4 enumerates shadowed properties twice.\n _forEach = function forEach(object, callback) {\n // Create a set of iterated properties.\n var members = {},\n isFunction = getClass.call(object) == functionClass,\n property;\n for (property in object) {\n // Store each property name to prevent double enumeration. The\n // `prototype` property of functions is not enumerated due to cross-\n // environment inconsistencies.\n if (!(isFunction && property == \"prototype\") && !_isProperty.call(members, property) && (members[property] = 1) && _isProperty.call(object, property)) {\n callback(property);\n }\n }\n };\n } else {\n // No bugs detected; use the standard `for...in` algorithm.\n _forEach = function forEach(object, callback) {\n var isFunction = getClass.call(object) == functionClass,\n property,\n isConstructor;\n for (property in object) {\n if (!(isFunction && property == \"prototype\") && _isProperty.call(object, property) && !(isConstructor = property === \"constructor\")) {\n callback(property);\n }\n }\n // Manually invoke the callback for the `constructor` property due to\n // cross-environment inconsistencies.\n if (isConstructor || _isProperty.call(object, property = \"constructor\")) {\n callback(property);\n }\n };\n }\n return _forEach(object, callback);\n };\n\n // Public: Serializes a JavaScript `value` as a JSON string. The optional\n // `filter` argument may specify either a function that alters how object and\n // array members are serialized, or an array of strings and numbers that\n // indicates which properties should be serialized. The optional `width`\n // argument may be either a string or number that specifies the indentation\n // level of the output.\n if (!has(\"json-stringify\")) {\n // Internal: A map of control characters and their escaped equivalents.\n var Escapes = {\n 92: \"\\\\\\\\\",\n 34: '\\\\\"',\n 8: \"\\\\b\",\n 12: \"\\\\f\",\n 10: \"\\\\n\",\n 13: \"\\\\r\",\n 9: \"\\\\t\"\n };\n\n // Internal: Converts `value` into a zero-padded string such that its\n // length is at least equal to `width`. The `width` must be <= 6.\n var leadingZeroes = \"000000\";\n var toPaddedString = function toPaddedString(width, value) {\n // The `|| 0` expression is necessary to work around a bug in\n // Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== \"0\"`.\n return (leadingZeroes + (value || 0)).slice(-width);\n };\n\n // Internal: Double-quotes a string `value`, replacing all ASCII control\n // characters (characters with code unit values between 0 and 31) with\n // their escaped equivalents. This is an implementation of the\n // `Quote(value)` operation defined in ES 5.1 section 15.12.3.\n var unicodePrefix = \"\\\\u00\";\n var quote = function quote(value) {\n var result = '\"',\n index = 0,\n length = value.length,\n useCharIndex = !charIndexBuggy || length > 10;\n var symbols = useCharIndex && (charIndexBuggy ? value.split(\"\") : value);\n for (; index < length; index++) {\n var charCode = value.charCodeAt(index);\n // If the character is a control character, append its Unicode or\n // shorthand escape sequence; otherwise, append the character as-is.\n switch (charCode) {\n case 8:case 9:case 10:case 12:case 13:case 34:case 92:\n result += Escapes[charCode];\n break;\n default:\n if (charCode < 32) {\n result += unicodePrefix + toPaddedString(2, charCode.toString(16));\n break;\n }\n result += useCharIndex ? symbols[index] : value.charAt(index);\n }\n }\n return result + '\"';\n };\n\n // Internal: Recursively serializes an object. Implements the\n // `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.\n var serialize = function serialize(property, object, callback, properties, whitespace, indentation, stack) {\n var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result;\n try {\n // Necessary for host object support.\n value = object[property];\n } catch (exception) {}\n if ((typeof value === \"undefined\" ? \"undefined\" : _typeof(value)) == \"object\" && value) {\n className = getClass.call(value);\n if (className == dateClass && !_isProperty.call(value, \"toJSON\")) {\n if (value > -1 / 0 && value < 1 / 0) {\n // Dates are serialized according to the `Date#toJSON` method\n // specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15\n // for the ISO 8601 date time string format.\n if (getDay) {\n // Manually compute the year, month, date, hours, minutes,\n // seconds, and milliseconds if the `getUTC*` methods are\n // buggy. Adapted from @Yaffle's `date-shim` project.\n date = floor(value / 864e5);\n for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++) {}\n for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++) {}\n date = 1 + date - getDay(year, month);\n // The `time` value specifies the time within the day (see ES\n // 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used\n // to compute `A modulo B`, as the `%` operator does not\n // correspond to the `modulo` operation for negative numbers.\n time = (value % 864e5 + 864e5) % 864e5;\n // The hours, minutes, seconds, and milliseconds are obtained by\n // decomposing the time within the day. See section 15.9.1.10.\n hours = floor(time / 36e5) % 24;\n minutes = floor(time / 6e4) % 60;\n seconds = floor(time / 1e3) % 60;\n milliseconds = time % 1e3;\n } else {\n year = value.getUTCFullYear();\n month = value.getUTCMonth();\n date = value.getUTCDate();\n hours = value.getUTCHours();\n minutes = value.getUTCMinutes();\n seconds = value.getUTCSeconds();\n milliseconds = value.getUTCMilliseconds();\n }\n // Serialize extended years correctly.\n value = (year <= 0 || year >= 1e4 ? (year < 0 ? \"-\" : \"+\") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) + \"-\" + toPaddedString(2, month + 1) + \"-\" + toPaddedString(2, date) +\n // Months, dates, hours, minutes, and seconds should have two\n // digits; milliseconds should have three.\n \"T\" + toPaddedString(2, hours) + \":\" + toPaddedString(2, minutes) + \":\" + toPaddedString(2, seconds) +\n // Milliseconds are optional in ES 5.0, but required in 5.1.\n \".\" + toPaddedString(3, milliseconds) + \"Z\";\n } else {\n value = null;\n }\n } else if (typeof value.toJSON == \"function\" && (className != numberClass && className != stringClass && className != arrayClass || _isProperty.call(value, \"toJSON\"))) {\n // Prototype <= 1.6.1 adds non-standard `toJSON` methods to the\n // `Number`, `String`, `Date`, and `Array` prototypes. JSON 3\n // ignores all `toJSON` methods on these objects unless they are\n // defined directly on an instance.\n value = value.toJSON(property);\n }\n }\n if (callback) {\n // If a replacement function was provided, call it to obtain the value\n // for serialization.\n value = callback.call(object, property, value);\n }\n if (value === null) {\n return \"null\";\n }\n className = getClass.call(value);\n if (className == booleanClass) {\n // Booleans are represented literally.\n return \"\" + value;\n } else if (className == numberClass) {\n // JSON numbers must be finite. `Infinity` and `NaN` are serialized as\n // `\"null\"`.\n return value > -1 / 0 && value < 1 / 0 ? \"\" + value : \"null\";\n } else if (className == stringClass) {\n // Strings are double-quoted and escaped.\n return quote(\"\" + value);\n }\n // Recursively serialize objects and arrays.\n if ((typeof value === \"undefined\" ? \"undefined\" : _typeof(value)) == \"object\") {\n // Check for cyclic structures. This is a linear search; performance\n // is inversely proportional to the number of unique nested objects.\n for (length = stack.length; length--;) {\n if (stack[length] === value) {\n // Cyclic structures cannot be serialized by `JSON.stringify`.\n throw TypeError();\n }\n }\n // Add the object to the stack of traversed objects.\n stack.push(value);\n results = [];\n // Save the current indentation level and indent one additional level.\n prefix = indentation;\n indentation += whitespace;\n if (className == arrayClass) {\n // Recursively serialize array elements.\n for (index = 0, length = value.length; index < length; index++) {\n element = serialize(index, value, callback, properties, whitespace, indentation, stack);\n results.push(element === undef ? \"null\" : element);\n }\n result = results.length ? whitespace ? \"[\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"]\" : \"[\" + results.join(\",\") + \"]\" : \"[]\";\n } else {\n // Recursively serialize object members. Members are selected from\n // either a user-specified list of property names, or the object\n // itself.\n _forEach(properties || value, function (property) {\n var element = serialize(property, value, callback, properties, whitespace, indentation, stack);\n if (element !== undef) {\n // According to ES 5.1 section 15.12.3: \"If `gap` {whitespace}\n // is not the empty string, let `member` {quote(property) + \":\"}\n // be the concatenation of `member` and the `space` character.\"\n // The \"`space` character\" refers to the literal space\n // character, not the `space` {width} argument provided to\n // `JSON.stringify`.\n results.push(quote(property) + \":\" + (whitespace ? \" \" : \"\") + element);\n }\n });\n result = results.length ? whitespace ? \"{\\n\" + indentation + results.join(\",\\n\" + indentation) + \"\\n\" + prefix + \"}\" : \"{\" + results.join(\",\") + \"}\" : \"{}\";\n }\n // Remove the object from the traversed object stack.\n stack.pop();\n return result;\n }\n };\n\n // Public: `JSON.stringify`. See ES 5.1 section 15.12.3.\n exports.stringify = function (source, filter, width) {\n var whitespace, callback, properties, className;\n if (objectTypes[typeof filter === \"undefined\" ? \"undefined\" : _typeof(filter)] && filter) {\n if ((className = getClass.call(filter)) == functionClass) {\n callback = filter;\n } else if (className == arrayClass) {\n // Convert the property names array into a makeshift set.\n properties = {};\n for (var index = 0, length = filter.length, value; index < length; value = filter[index++], (className = getClass.call(value), className == stringClass || className == numberClass) && (properties[value] = 1)) {}\n }\n }\n if (width) {\n if ((className = getClass.call(width)) == numberClass) {\n // Convert the `width` to an integer and create a string containing\n // `width` number of space characters.\n if ((width -= width % 1) > 0) {\n for (whitespace = \"\", width > 10 && (width = 10); whitespace.length < width; whitespace += \" \") {}\n }\n } else if (className == stringClass) {\n whitespace = width.length <= 10 ? width : width.slice(0, 10);\n }\n }\n // Opera <= 7.54u2 discards the values associated with empty string keys\n // (`\"\"`) only if they are used directly within an object member list\n // (e.g., `!(\"\" in { \"\": 1})`).\n return serialize(\"\", (value = {}, value[\"\"] = source, value), callback, properties, whitespace, \"\", []);\n };\n }\n\n // Public: Parses a JSON source string.\n if (!has(\"json-parse\")) {\n var fromCharCode = String.fromCharCode;\n\n // Internal: A map of escaped control characters and their unescaped\n // equivalents.\n var Unescapes = {\n 92: \"\\\\\",\n 34: '\"',\n 47: \"/\",\n 98: \"\\b\",\n 116: \"\\t\",\n 110: \"\\n\",\n 102: \"\\f\",\n 114: \"\\r\"\n };\n\n // Internal: Stores the parser state.\n var Index, Source;\n\n // Internal: Resets the parser state and throws a `SyntaxError`.\n var abort = function abort() {\n Index = Source = null;\n throw SyntaxError();\n };\n\n // Internal: Returns the next token, or `\"$\"` if the parser has reached\n // the end of the source string. A token may be a string, number, `null`\n // literal, or Boolean literal.\n var lex = function lex() {\n var source = Source,\n length = source.length,\n value,\n begin,\n position,\n isSigned,\n charCode;\n while (Index < length) {\n charCode = source.charCodeAt(Index);\n switch (charCode) {\n case 9:case 10:case 13:case 32:\n // Skip whitespace tokens, including tabs, carriage returns, line\n // feeds, and space characters.\n Index++;\n break;\n case 123:case 125:case 91:case 93:case 58:case 44:\n // Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at\n // the current position.\n value = charIndexBuggy ? source.charAt(Index) : source[Index];\n Index++;\n return value;\n case 34:\n // `\"` delimits a JSON string; advance to the next character and\n // begin parsing the string. String tokens are prefixed with the\n // sentinel `@` character to distinguish them from punctuators and\n // end-of-string tokens.\n for (value = \"@\", Index++; Index < length;) {\n charCode = source.charCodeAt(Index);\n if (charCode < 32) {\n // Unescaped ASCII control characters (those with a code unit\n // less than the space character) are not permitted.\n abort();\n } else if (charCode == 92) {\n // A reverse solidus (`\\`) marks the beginning of an escaped\n // control character (including `\"`, `\\`, and `/`) or Unicode\n // escape sequence.\n charCode = source.charCodeAt(++Index);\n switch (charCode) {\n case 92:case 34:case 47:case 98:case 116:case 110:case 102:case 114:\n // Revive escaped control characters.\n value += Unescapes[charCode];\n Index++;\n break;\n case 117:\n // `\\u` marks the beginning of a Unicode escape sequence.\n // Advance to the first character and validate the\n // four-digit code point.\n begin = ++Index;\n for (position = Index + 4; Index < position; Index++) {\n charCode = source.charCodeAt(Index);\n // A valid sequence comprises four hexdigits (case-\n // insensitive) that form a single hexadecimal value.\n if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) {\n // Invalid Unicode escape sequence.\n abort();\n }\n }\n // Revive the escaped character.\n value += fromCharCode(\"0x\" + source.slice(begin, Index));\n break;\n default:\n // Invalid escape sequence.\n abort();\n }\n } else {\n if (charCode == 34) {\n // An unescaped double-quote character marks the end of the\n // string.\n break;\n }\n charCode = source.charCodeAt(Index);\n begin = Index;\n // Optimize for the common case where a string is valid.\n while (charCode >= 32 && charCode != 92 && charCode != 34) {\n charCode = source.charCodeAt(++Index);\n }\n // Append the string as-is.\n value += source.slice(begin, Index);\n }\n }\n if (source.charCodeAt(Index) == 34) {\n // Advance to the next character and return the revived string.\n Index++;\n return value;\n }\n // Unterminated string.\n abort();\n default:\n // Parse numbers and literals.\n begin = Index;\n // Advance past the negative sign, if one is specified.\n if (charCode == 45) {\n isSigned = true;\n charCode = source.charCodeAt(++Index);\n }\n // Parse an integer or floating-point value.\n if (charCode >= 48 && charCode <= 57) {\n // Leading zeroes are interpreted as octal literals.\n if (charCode == 48 && (charCode = source.charCodeAt(Index + 1), charCode >= 48 && charCode <= 57)) {\n // Illegal octal literal.\n abort();\n }\n isSigned = false;\n // Parse the integer component.\n for (; Index < length && (charCode = source.charCodeAt(Index), charCode >= 48 && charCode <= 57); Index++) {}\n // Floats cannot contain a leading decimal point; however, this\n // case is already accounted for by the parser.\n if (source.charCodeAt(Index) == 46) {\n position = ++Index;\n // Parse the decimal component.\n for (; position < length && (charCode = source.charCodeAt(position), charCode >= 48 && charCode <= 57); position++) {}\n if (position == Index) {\n // Illegal trailing decimal.\n abort();\n }\n Index = position;\n }\n // Parse exponents. The `e` denoting the exponent is\n // case-insensitive.\n charCode = source.charCodeAt(Index);\n if (charCode == 101 || charCode == 69) {\n charCode = source.charCodeAt(++Index);\n // Skip past the sign following the exponent, if one is\n // specified.\n if (charCode == 43 || charCode == 45) {\n Index++;\n }\n // Parse the exponential component.\n for (position = Index; position < length && (charCode = source.charCodeAt(position), charCode >= 48 && charCode <= 57); position++) {}\n if (position == Index) {\n // Illegal empty exponent.\n abort();\n }\n Index = position;\n }\n // Coerce the parsed value to a JavaScript number.\n return +source.slice(begin, Index);\n }\n // A negative sign may only precede numbers.\n if (isSigned) {\n abort();\n }\n // `true`, `false`, and `null` literals.\n if (source.slice(Index, Index + 4) == \"true\") {\n Index += 4;\n return true;\n } else if (source.slice(Index, Index + 5) == \"false\") {\n Index += 5;\n return false;\n } else if (source.slice(Index, Index + 4) == \"null\") {\n Index += 4;\n return null;\n }\n // Unrecognized token.\n abort();\n }\n }\n // Return the sentinel `$` character if the parser has reached the end\n // of the source string.\n return \"$\";\n };\n\n // Internal: Parses a JSON `value` token.\n var get = function get(value) {\n var results, hasMembers;\n if (value == \"$\") {\n // Unexpected end of input.\n abort();\n }\n if (typeof value == \"string\") {\n if ((charIndexBuggy ? value.charAt(0) : value[0]) == \"@\") {\n // Remove the sentinel `@` character.\n return value.slice(1);\n }\n // Parse object and array literals.\n if (value == \"[\") {\n // Parses a JSON array, returning a new JavaScript array.\n results = [];\n for (;; hasMembers || (hasMembers = true)) {\n value = lex();\n // A closing square bracket marks the end of the array literal.\n if (value == \"]\") {\n break;\n }\n // If the array literal contains elements, the current token\n // should be a comma separating the previous element from the\n // next.\n if (hasMembers) {\n if (value == \",\") {\n value = lex();\n if (value == \"]\") {\n // Unexpected trailing `,` in array literal.\n abort();\n }\n } else {\n // A `,` must separate each array element.\n abort();\n }\n }\n // Elisions and leading commas are not permitted.\n if (value == \",\") {\n abort();\n }\n results.push(get(value));\n }\n return results;\n } else if (value == \"{\") {\n // Parses a JSON object, returning a new JavaScript object.\n results = {};\n for (;; hasMembers || (hasMembers = true)) {\n value = lex();\n // A closing curly brace marks the end of the object literal.\n if (value == \"}\") {\n break;\n }\n // If the object literal contains members, the current token\n // should be a comma separator.\n if (hasMembers) {\n if (value == \",\") {\n value = lex();\n if (value == \"}\") {\n // Unexpected trailing `,` in object literal.\n abort();\n }\n } else {\n // A `,` must separate each object member.\n abort();\n }\n }\n // Leading commas are not permitted, object property names must be\n // double-quoted strings, and a `:` must separate each property\n // name and value.\n if (value == \",\" || typeof value != \"string\" || (charIndexBuggy ? value.charAt(0) : value[0]) != \"@\" || lex() != \":\") {\n abort();\n }\n results[value.slice(1)] = get(lex());\n }\n return results;\n }\n // Unexpected token encountered.\n abort();\n }\n return value;\n };\n\n // Internal: Updates a traversed object member.\n var update = function update(source, property, callback) {\n var element = walk(source, property, callback);\n if (element === undef) {\n delete source[property];\n } else {\n source[property] = element;\n }\n };\n\n // Internal: Recursively traverses a parsed JSON object, invoking the\n // `callback` function for each value. This is an implementation of the\n // `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.\n var walk = function walk(source, property, callback) {\n var value = source[property],\n length;\n if ((typeof value === \"undefined\" ? \"undefined\" : _typeof(value)) == \"object\" && value) {\n // `forEach` can't be used to traverse an array in Opera <= 8.54\n // because its `Object#hasOwnProperty` implementation returns `false`\n // for array indices (e.g., `![1, 2, 3].hasOwnProperty(\"0\")`).\n if (getClass.call(value) == arrayClass) {\n for (length = value.length; length--;) {\n update(value, length, callback);\n }\n } else {\n _forEach(value, function (property) {\n update(value, property, callback);\n });\n }\n }\n return callback.call(source, property, value);\n };\n\n // Public: `JSON.parse`. See ES 5.1 section 15.12.2.\n exports.parse = function (source, callback) {\n var result, value;\n Index = 0;\n Source = \"\" + source;\n result = get(lex());\n // If a JSON string contains multiple tokens, it is invalid.\n if (lex() != \"$\") {\n abort();\n }\n // Reset the parser state.\n Index = Source = null;\n return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[\"\"] = result, value), \"\", callback) : result;\n };\n }\n }\n\n exports[\"runInContext\"] = runInContext;\n return exports;\n }\n\n if (freeExports && !isLoader) {\n // Export for CommonJS environments.\n runInContext(root, freeExports);\n } else {\n // Export for web browsers and JavaScript engines.\n var nativeJSON = root.JSON,\n previousJSON = root[\"JSON3\"],\n isRestored = false;\n\n var JSON3 = runInContext(root, root[\"JSON3\"] = {\n // Public: Restores the original value of the global `JSON` object and\n // returns a reference to the `JSON3` object.\n \"noConflict\": function noConflict() {\n if (!isRestored) {\n isRestored = true;\n root.JSON = nativeJSON;\n root[\"JSON3\"] = previousJSON;\n nativeJSON = previousJSON = null;\n }\n return JSON3;\n }\n });\n\n root.JSON = {\n \"parse\": JSON3.parse,\n \"stringify\": JSON3.stringify\n };\n }\n\n // Export for asynchronous module loaders.\n if (isLoader) {\n define(function () {\n return JSON3;\n });\n }\n }).call(this);\n }).call(this, typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : typeof global !== \"undefined\" ? global : {});\n }, {}], 51: [function (_dereq_, module, exports) {\n module.exports = toArray;\n\n function toArray(list, index) {\n var array = [];\n\n index = index || 0;\n\n for (var i = index || 0; i < list.length; i++) {\n array[i - index] = list[i];\n }\n\n return array;\n }\n }, {}] }, {}, [31])(31);\n });\n}\n\ncc._RF.pop();\n}).call(this,typeof global !== \"undefined\" ? global : typeof self !== \"undefined\" ? self : typeof window !== \"undefined\" ? window : {})\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImxpYnJhcnkvaW1wb3J0cy9jMy9jMzM2MmYwNy0zY2Q4LTRlNTgtODAyNS02YWUzYzc0NGZkMjAuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyJcInVzZSBzdHJpY3RcIjtcbmNjLl9SRi5wdXNoKG1vZHVsZSwgJ2MzMzYyOEhQTmhPV0lBbGF1UEhSUDBnJywgJ3NvY2tldC5pbycpO1xuLy8gc2NyaXB0L2xpYi9zb2NrZXQuaW8uanNcblxuXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfdHlwZW9mID0gdHlwZW9mIFN5bWJvbCA9PT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBTeW1ib2wuaXRlcmF0b3IgPT09IFwic3ltYm9sXCIgPyBmdW5jdGlvbiAob2JqKSB7IHJldHVybiB0eXBlb2Ygb2JqOyB9IDogZnVuY3Rpb24gKG9iaikgeyByZXR1cm4gb2JqICYmIHR5cGVvZiBTeW1ib2wgPT09IFwiZnVuY3Rpb25cIiAmJiBvYmouY29uc3RydWN0b3IgPT09IFN5bWJvbCAmJiBvYmogIT09IFN5bWJvbC5wcm90b3R5cGUgPyBcInN5bWJvbFwiIDogdHlwZW9mIG9iajsgfTtcblxuaWYgKCFjYy5zeXMuaXNOYXRpdmUpIHtcbiAgKGZ1bmN0aW9uIChmKSB7XG4gICAgaWYgKCh0eXBlb2YgZXhwb3J0cyA9PT0gXCJ1bmRlZmluZWRcIiA/IFwidW5kZWZpbmVkXCIgOiBfdHlwZW9mKGV4cG9ydHMpKSA9PT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICBtb2R1bGUuZXhwb3J0cyA9IGYoKTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSB7XG4gICAgICBkZWZpbmUoW10sIGYpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgZztpZiAodHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICBnID0gd2luZG93O1xuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIGcgPSBnbG9iYWw7XG4gICAgICB9IGVsc2UgaWYgKHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgICAgIGcgPSBzZWxmO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZyA9IHRoaXM7XG4gICAgICB9Zy5pbyA9IGYoKTtcbiAgICB9XG4gIH0pKGZ1bmN0aW9uICgpIHtcbiAgICB2YXIgZGVmaW5lLCBtb2R1bGUsIGV4cG9ydHM7cmV0dXJuIGZ1bmN0aW9uIGUodCwgbiwgcikge1xuICAgICAgZnVuY3Rpb24gcyhvLCB1KSB7XG4gICAgICAgIGlmICghbltvXSkge1xuICAgICAgICAgIGlmICghdFtvXSkge1xuICAgICAgICAgICAgdmFyIGEgPSB0eXBlb2YgcmVxdWlyZSA9PSBcImZ1bmN0aW9uXCIgJiYgcmVxdWlyZTtpZiAoIXUgJiYgYSkgcmV0dXJuIGEobywgITApO2lmIChpKSByZXR1cm4gaShvLCAhMCk7dmFyIGYgPSBuZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiICsgbyArIFwiJ1wiKTt0aHJvdyBmLmNvZGUgPSBcIk1PRFVMRV9OT1RfRk9VTkRcIiwgZjtcbiAgICAgICAgICB9dmFyIGwgPSBuW29dID0geyBleHBvcnRzOiB7fSB9O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsIGZ1bmN0aW9uIChlKSB7XG4gICAgICAgICAgICB2YXIgbiA9IHRbb11bMV1bZV07cmV0dXJuIHMobiA/IG4gOiBlKTtcbiAgICAgICAgICB9LCBsLCBsLmV4cG9ydHMsIGUsIHQsIG4sIHIpO1xuICAgICAgICB9cmV0dXJuIG5bb10uZXhwb3J0cztcbiAgICAgIH12YXIgaSA9IHR5cGVvZiByZXF1aXJlID09IFwiZnVuY3Rpb25cIiAmJiByZXF1aXJlO2ZvciAodmFyIG8gPSAwOyBvIDwgci5sZW5ndGg7IG8rKykge1xuICAgICAgICBzKHJbb10pO1xuICAgICAgfXJldHVybiBzO1xuICAgIH0oeyAxOiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuXG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gX2RlcmVxXygnLi9saWIvJyk7XG4gICAgICB9LCB7IFwiLi9saWIvXCI6IDIgfV0sIDI6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG5cbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBfZGVyZXFfKCcuL3NvY2tldCcpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFeHBvcnRzIHBhcnNlclxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKlxuICAgICAgICAgKi9cbiAgICAgICAgbW9kdWxlLmV4cG9ydHMucGFyc2VyID0gX2RlcmVxXygnZW5naW5lLmlvLXBhcnNlcicpO1xuICAgICAgfSwgeyBcIi4vc29ja2V0XCI6IDMsIFwiZW5naW5lLmlvLXBhcnNlclwiOiAxOSB9XSwgMzogW2Z1bmN0aW9uIChfZGVyZXFfLCBtb2R1bGUsIGV4cG9ydHMpIHtcbiAgICAgICAgKGZ1bmN0aW9uIChnbG9iYWwpIHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgdmFyIHRyYW5zcG9ydHMgPSBfZGVyZXFfKCcuL3RyYW5zcG9ydHMnKTtcbiAgICAgICAgICB2YXIgRW1pdHRlciA9IF9kZXJlcV8oJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG4gICAgICAgICAgdmFyIGRlYnVnID0gX2RlcmVxXygnZGVidWcnKSgnZW5naW5lLmlvLWNsaWVudDpzb2NrZXQnKTtcbiAgICAgICAgICB2YXIgaW5kZXggPSBfZGVyZXFfKCdpbmRleG9mJyk7XG4gICAgICAgICAgdmFyIHBhcnNlciA9IF9kZXJlcV8oJ2VuZ2luZS5pby1wYXJzZXInKTtcbiAgICAgICAgICB2YXIgcGFyc2V1cmkgPSBfZGVyZXFfKCdwYXJzZXVyaScpO1xuICAgICAgICAgIHZhciBwYXJzZWpzb24gPSBfZGVyZXFfKCdwYXJzZWpzb24nKTtcbiAgICAgICAgICB2YXIgcGFyc2VxcyA9IF9kZXJlcV8oJ3BhcnNlcXMnKTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIE1vZHVsZSBleHBvcnRzLlxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBTb2NrZXQ7XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBOb29wIGZ1bmN0aW9uLlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBmdW5jdGlvbiBub29wKCkge31cblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFNvY2tldCBjb25zdHJ1Y3Rvci5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfE9iamVjdH0gdXJpIG9yIG9wdGlvbnNcbiAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICAgICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBmdW5jdGlvbiBTb2NrZXQodXJpLCBvcHRzKSB7XG4gICAgICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU29ja2V0KSkgcmV0dXJuIG5ldyBTb2NrZXQodXJpLCBvcHRzKTtcblxuICAgICAgICAgICAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgICAgICAgICAgIGlmICh1cmkgJiYgJ29iamVjdCcgPT0gKHR5cGVvZiB1cmkgPT09IFwidW5kZWZpbmVkXCIgPyBcInVuZGVmaW5lZFwiIDogX3R5cGVvZih1cmkpKSkge1xuICAgICAgICAgICAgICBvcHRzID0gdXJpO1xuICAgICAgICAgICAgICB1cmkgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAodXJpKSB7XG4gICAgICAgICAgICAgIHVyaSA9IHBhcnNldXJpKHVyaSk7XG4gICAgICAgICAgICAgIG9wdHMuaG9zdG5hbWUgPSB1cmkuaG9zdDtcbiAgICAgICAgICAgICAgb3B0cy5zZWN1cmUgPSB1cmkucHJvdG9jb2wgPT0gJ2h0dHBzJyB8fCB1cmkucHJvdG9jb2wgPT0gJ3dzcyc7XG4gICAgICAgICAgICAgIG9wdHMucG9ydCA9IHVyaS5wb3J0O1xuICAgICAgICAgICAgICBpZiAodXJpLnF1ZXJ5KSBvcHRzLnF1ZXJ5ID0gdXJpLnF1ZXJ5O1xuICAgICAgICAgICAgfSBlbHNlIGlmIChvcHRzLmhvc3QpIHtcbiAgICAgICAgICAgICAgb3B0cy5ob3N0bmFtZSA9IHBhcnNldXJpKG9wdHMuaG9zdCkuaG9zdDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5zZWN1cmUgPSBudWxsICE9IG9wdHMuc2VjdXJlID8gb3B0cy5zZWN1cmUgOiBnbG9iYWwubG9jYXRpb24gJiYgJ2h0dHBzOicgPT0gbG9jYXRpb24ucHJvdG9jb2w7XG5cbiAgICAgICAgICAgIGlmIChvcHRzLmhvc3RuYW1lICYmICFvcHRzLnBvcnQpIHtcbiAgICAgICAgICAgICAgLy8gaWYgbm8gcG9ydCBpcyBzcGVjaWZpZWQgbWFudWFsbHksIHVzZSB0aGUgcHJvdG9jb2wgZGVmYXVsdFxuICAgICAgICAgICAgICBvcHRzLnBvcnQgPSB0aGlzLnNlY3VyZSA/ICc0NDMnIDogJzgwJztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5hZ2VudCA9IG9wdHMuYWdlbnQgfHwgZmFsc2U7XG4gICAgICAgICAgICB0aGlzLmhvc3RuYW1lID0gb3B0cy5ob3N0bmFtZSB8fCAoZ2xvYmFsLmxvY2F0aW9uID8gbG9jYXRpb24uaG9zdG5hbWUgOiAnbG9jYWxob3N0Jyk7XG4gICAgICAgICAgICB0aGlzLnBvcnQgPSBvcHRzLnBvcnQgfHwgKGdsb2JhbC5sb2NhdGlvbiAmJiBsb2NhdGlvbi5wb3J0ID8gbG9jYXRpb24ucG9ydCA6IHRoaXMuc2VjdXJlID8gNDQzIDogODApO1xuICAgICAgICAgICAgdGhpcy5xdWVyeSA9IG9wdHMucXVlcnkgfHwge307XG4gICAgICAgICAgICBpZiAoJ3N0cmluZycgPT0gdHlwZW9mIHRoaXMucXVlcnkpIHRoaXMucXVlcnkgPSBwYXJzZXFzLmRlY29kZSh0aGlzLnF1ZXJ5KTtcbiAgICAgICAgICAgIHRoaXMudXBncmFkZSA9IGZhbHNlICE9PSBvcHRzLnVwZ3JhZGU7XG4gICAgICAgICAgICB0aGlzLnBhdGggPSAob3B0cy5wYXRoIHx8ICcvZW5naW5lLmlvJykucmVwbGFjZSgvXFwvJC8sICcnKSArICcvJztcbiAgICAgICAgICAgIHRoaXMuZm9yY2VKU09OUCA9ICEhb3B0cy5mb3JjZUpTT05QO1xuICAgICAgICAgICAgdGhpcy5qc29ucCA9IGZhbHNlICE9PSBvcHRzLmpzb25wO1xuICAgICAgICAgICAgdGhpcy5mb3JjZUJhc2U2NCA9ICEhb3B0cy5mb3JjZUJhc2U2NDtcbiAgICAgICAgICAgIHRoaXMuZW5hYmxlc1hEUiA9ICEhb3B0cy5lbmFibGVzWERSO1xuICAgICAgICAgICAgdGhpcy50aW1lc3RhbXBQYXJhbSA9IG9wdHMudGltZXN0YW1wUGFyYW0gfHwgJ3QnO1xuICAgICAgICAgICAgdGhpcy50aW1lc3RhbXBSZXF1ZXN0cyA9IG9wdHMudGltZXN0YW1wUmVxdWVzdHM7XG4gICAgICAgICAgICB0aGlzLnRyYW5zcG9ydHMgPSBvcHRzLnRyYW5zcG9ydHMgfHwgWydwb2xsaW5nJywgJ3dlYnNvY2tldCddO1xuICAgICAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gJyc7XG4gICAgICAgICAgICB0aGlzLndyaXRlQnVmZmVyID0gW107XG4gICAgICAgICAgICB0aGlzLnBvbGljeVBvcnQgPSBvcHRzLnBvbGljeVBvcnQgfHwgODQzO1xuICAgICAgICAgICAgdGhpcy5yZW1lbWJlclVwZ3JhZGUgPSBvcHRzLnJlbWVtYmVyVXBncmFkZSB8fCBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuYmluYXJ5VHlwZSA9IG51bGw7XG4gICAgICAgICAgICB0aGlzLm9ubHlCaW5hcnlVcGdyYWRlcyA9IG9wdHMub25seUJpbmFyeVVwZ3JhZGVzO1xuICAgICAgICAgICAgdGhpcy5wZXJNZXNzYWdlRGVmbGF0ZSA9IGZhbHNlICE9PSBvcHRzLnBlck1lc3NhZ2VEZWZsYXRlID8gb3B0cy5wZXJNZXNzYWdlRGVmbGF0ZSB8fCB7fSA6IGZhbHNlO1xuXG4gICAgICAgICAgICBpZiAodHJ1ZSA9PT0gdGhpcy5wZXJNZXNzYWdlRGVmbGF0ZSkgdGhpcy5wZXJNZXNzYWdlRGVmbGF0ZSA9IHt9O1xuICAgICAgICAgICAgaWYgKHRoaXMucGVyTWVzc2FnZURlZmxhdGUgJiYgbnVsbCA9PSB0aGlzLnBlck1lc3NhZ2VEZWZsYXRlLnRocmVzaG9sZCkge1xuICAgICAgICAgICAgICB0aGlzLnBlck1lc3NhZ2VEZWZsYXRlLnRocmVzaG9sZCA9IDEwMjQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNTTCBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICAgICAgICAgICAgdGhpcy5wZnggPSBvcHRzLnBmeCB8fCBudWxsO1xuICAgICAgICAgICAgdGhpcy5rZXkgPSBvcHRzLmtleSB8fCBudWxsO1xuICAgICAgICAgICAgdGhpcy5wYXNzcGhyYXNlID0gb3B0cy5wYXNzcGhyYXNlIHx8IG51bGw7XG4gICAgICAgICAgICB0aGlzLmNlcnQgPSBvcHRzLmNlcnQgfHwgbnVsbDtcbiAgICAgICAgICAgIHRoaXMuY2EgPSBvcHRzLmNhIHx8IG51bGw7XG4gICAgICAgICAgICB0aGlzLmNpcGhlcnMgPSBvcHRzLmNpcGhlcnMgfHwgbnVsbDtcbiAgICAgICAgICAgIHRoaXMucmVqZWN0VW5hdXRob3JpemVkID0gb3B0cy5yZWplY3RVbmF1dGhvcml6ZWQgPT09IHVuZGVmaW5lZCA/IG51bGwgOiBvcHRzLnJlamVjdFVuYXV0aG9yaXplZDtcblxuICAgICAgICAgICAgLy8gb3RoZXIgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgICAgICAgICAgIHZhciBmcmVlR2xvYmFsID0gKHR5cGVvZiBnbG9iYWwgPT09IFwidW5kZWZpbmVkXCIgPyBcInVuZGVmaW5lZFwiIDogX3R5cGVvZihnbG9iYWwpKSA9PSAnb2JqZWN0JyAmJiBnbG9iYWw7XG4gICAgICAgICAgICBpZiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwpIHtcbiAgICAgICAgICAgICAgaWYgKG9wdHMuZXh0cmFIZWFkZXJzICYmIE9iamVjdC5rZXlzKG9wdHMuZXh0cmFIZWFkZXJzKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5leHRyYUhlYWRlcnMgPSBvcHRzLmV4dHJhSGVhZGVycztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLm9wZW4oKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBTb2NrZXQucHJpb3JXZWJzb2NrZXRTdWNjZXNzID0gZmFsc2U7XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBNaXggaW4gYEVtaXR0ZXJgLlxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgRW1pdHRlcihTb2NrZXQucHJvdG90eXBlKTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFByb3RvY29sIHZlcnNpb24uXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgU29ja2V0LnByb3RvY29sID0gcGFyc2VyLnByb3RvY29sOyAvLyB0aGlzIGlzIGFuIGludFxuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRXhwb3NlIGRlcHMgZm9yIGxlZ2FjeSBjb21wYXRpYmlsaXR5XG4gICAgICAgICAgICogYW5kIHN0YW5kYWxvbmUgYnJvd3NlciBhY2Nlc3MuXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBTb2NrZXQuU29ja2V0ID0gU29ja2V0O1xuICAgICAgICAgIFNvY2tldC5UcmFuc3BvcnQgPSBfZGVyZXFfKCcuL3RyYW5zcG9ydCcpO1xuICAgICAgICAgIFNvY2tldC50cmFuc3BvcnRzID0gX2RlcmVxXygnLi90cmFuc3BvcnRzJyk7XG4gICAgICAgICAgU29ja2V0LnBhcnNlciA9IF9kZXJlcV8oJ2VuZ2luZS5pby1wYXJzZXInKTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIENyZWF0ZXMgdHJhbnNwb3J0IG9mIHRoZSBnaXZlbiB0eXBlLlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHRyYW5zcG9ydCBuYW1lXG4gICAgICAgICAgICogQHJldHVybiB7VHJhbnNwb3J0fVxuICAgICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgU29ja2V0LnByb3RvdHlwZS5jcmVhdGVUcmFuc3BvcnQgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgICAgICAgICAgZGVidWcoJ2NyZWF0aW5nIHRyYW5zcG9ydCBcIiVzXCInLCBuYW1lKTtcbiAgICAgICAgICAgIHZhciBxdWVyeSA9IGNsb25lKHRoaXMucXVlcnkpO1xuXG4gICAgICAgICAgICAvLyBhcHBlbmQgZW5naW5lLmlvIHByb3RvY29sIGlkZW50aWZpZXJcbiAgICAgICAgICAgIHF1ZXJ5LkVJTyA9IHBhcnNlci5wcm90b2NvbDtcblxuICAgICAgICAgICAgLy8gdHJhbnNwb3J0IG5hbWVcbiAgICAgICAgICAgIHF1ZXJ5LnRyYW5zcG9ydCA9IG5hbWU7XG5cbiAgICAgICAgICAgIC8vIHNlc3Npb24gaWQgaWYgd2UgYWxyZWFkeSBoYXZlIG9uZVxuICAgICAgICAgICAgaWYgKHRoaXMuaWQpIHF1ZXJ5LnNpZCA9IHRoaXMuaWQ7XG5cbiAgICAgICAgICAgIHZhciB0cmFuc3BvcnQgPSBuZXcgdHJhbnNwb3J0c1tuYW1lXSh7XG4gICAgICAgICAgICAgIGFnZW50OiB0aGlzLmFnZW50LFxuICAgICAgICAgICAgICBob3N0bmFtZTogdGhpcy5ob3N0bmFtZSxcbiAgICAgICAgICAgICAgcG9ydDogdGhpcy5wb3J0LFxuICAgICAgICAgICAgICBzZWN1cmU6IHRoaXMuc2VjdXJlLFxuICAgICAgICAgICAgICBwYXRoOiB0aGlzLnBhdGgsXG4gICAgICAgICAgICAgIHF1ZXJ5OiBxdWVyeSxcbiAgICAgICAgICAgICAgZm9yY2VKU09OUDogdGhpcy5mb3JjZUpTT05QLFxuICAgICAgICAgICAgICBqc29ucDogdGhpcy5qc29ucCxcbiAgICAgICAgICAgICAgZm9yY2VCYXNlNjQ6IHRoaXMuZm9yY2VCYXNlNjQsXG4gICAgICAgICAgICAgIGVuYWJsZXNYRFI6IHRoaXMuZW5hYmxlc1hEUixcbiAgICAgICAgICAgICAgdGltZXN0YW1wUmVxdWVzdHM6IHRoaXMudGltZXN0YW1wUmVxdWVzdHMsXG4gICAgICAgICAgICAgIHRpbWVzdGFtcFBhcmFtOiB0aGlzLnRpbWVzdGFtcFBhcmFtLFxuICAgICAgICAgICAgICBwb2xpY3lQb3J0OiB0aGlzLnBvbGljeVBvcnQsXG4gICAgICAgICAgICAgIHNvY2tldDogdGhpcyxcbiAgICAgICAgICAgICAgcGZ4OiB0aGlzLnBmeCxcbiAgICAgICAgICAgICAga2V5OiB0aGlzLmtleSxcbiAgICAgICAgICAgICAgcGFzc3BocmFzZTogdGhpcy5wYXNzcGhyYXNlLFxuICAgICAgICAgICAgICBjZXJ0OiB0aGlzLmNlcnQsXG4gICAgICAgICAgICAgIGNhOiB0aGlzLmNhLFxuICAgICAgICAgICAgICBjaXBoZXJzOiB0aGlzLmNpcGhlcnMsXG4gICAgICAgICAgICAgIHJlamVjdFVuYXV0aG9yaXplZDogdGhpcy5yZWplY3RVbmF1dGhvcml6ZWQsXG4gICAgICAgICAgICAgIHBlck1lc3NhZ2VEZWZsYXRlOiB0aGlzLnBlck1lc3NhZ2VEZWZsYXRlLFxuICAgICAgICAgICAgICBleHRyYUhlYWRlcnM6IHRoaXMuZXh0cmFIZWFkZXJzXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgcmV0dXJuIHRyYW5zcG9ydDtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgZnVuY3Rpb24gY2xvbmUob2JqKSB7XG4gICAgICAgICAgICB2YXIgbyA9IHt9O1xuICAgICAgICAgICAgZm9yICh2YXIgaSBpbiBvYmopIHtcbiAgICAgICAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShpKSkge1xuICAgICAgICAgICAgICAgIG9baV0gPSBvYmpbaV07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBvO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEluaXRpYWxpemVzIHRyYW5zcG9ydCB0byB1c2UgYW5kIHN0YXJ0cyBwcm9iZS5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgICAqL1xuICAgICAgICAgIFNvY2tldC5wcm90b3R5cGUub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciB0cmFuc3BvcnQ7XG4gICAgICAgICAgICBpZiAodGhpcy5yZW1lbWJlclVwZ3JhZGUgJiYgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyAmJiB0aGlzLnRyYW5zcG9ydHMuaW5kZXhPZignd2Vic29ja2V0JykgIT0gLTEpIHtcbiAgICAgICAgICAgICAgdHJhbnNwb3J0ID0gJ3dlYnNvY2tldCc7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKDAgPT09IHRoaXMudHJhbnNwb3J0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgLy8gRW1pdCBlcnJvciBvbiBuZXh0IHRpY2sgc28gaXQgY2FuIGJlIGxpc3RlbmVkIHRvXG4gICAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5lbWl0KCdlcnJvcicsICdObyB0cmFuc3BvcnRzIGF2YWlsYWJsZScpO1xuICAgICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdHJhbnNwb3J0ID0gdGhpcy50cmFuc3BvcnRzWzBdO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW5pbmcnO1xuXG4gICAgICAgICAgICAvLyBSZXRyeSB3aXRoIHRoZSBuZXh0IHRyYW5zcG9ydCBpZiB0aGUgdHJhbnNwb3J0IGlzIGRpc2FibGVkIChqc29ucDogZmFsc2UpXG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICB0cmFuc3BvcnQgPSB0aGlzLmNyZWF0ZVRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICB0aGlzLnRyYW5zcG9ydHMuc2hpZnQoKTtcbiAgICAgICAgICAgICAgdGhpcy5vcGVuKCk7XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdHJhbnNwb3J0Lm9wZW4oKTtcbiAgICAgICAgICAgIHRoaXMuc2V0VHJhbnNwb3J0KHRyYW5zcG9ydCk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFNldHMgdGhlIGN1cnJlbnQgdHJhbnNwb3J0LiBEaXNhYmxlcyB0aGUgZXhpc3Rpbmcgb25lIChpZiBhbnkpLlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBTb2NrZXQucHJvdG90eXBlLnNldFRyYW5zcG9ydCA9IGZ1bmN0aW9uICh0cmFuc3BvcnQpIHtcbiAgICAgICAgICAgIGRlYnVnKCdzZXR0aW5nIHRyYW5zcG9ydCAlcycsIHRyYW5zcG9ydC5uYW1lKTtcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgICAgICAgICAgaWYgKHRoaXMudHJhbnNwb3J0KSB7XG4gICAgICAgICAgICAgIGRlYnVnKCdjbGVhcmluZyBleGlzdGluZyB0cmFuc3BvcnQgJXMnLCB0aGlzLnRyYW5zcG9ydC5uYW1lKTtcbiAgICAgICAgICAgICAgdGhpcy50cmFuc3BvcnQucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHNldCB1cCB0cmFuc3BvcnRcbiAgICAgICAgICAgIHRoaXMudHJhbnNwb3J0ID0gdHJhbnNwb3J0O1xuXG4gICAgICAgICAgICAvLyBzZXQgdXAgdHJhbnNwb3J0IGxpc3RlbmVyc1xuICAgICAgICAgICAgdHJhbnNwb3J0Lm9uKCdkcmFpbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgc2VsZi5vbkRyYWluKCk7XG4gICAgICAgICAgICB9KS5vbigncGFja2V0JywgZnVuY3Rpb24gKHBhY2tldCkge1xuICAgICAgICAgICAgICBzZWxmLm9uUGFja2V0KHBhY2tldCk7XG4gICAgICAgICAgICB9KS5vbignZXJyb3InLCBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICBzZWxmLm9uRXJyb3IoZSk7XG4gICAgICAgICAgICB9KS5vbignY2xvc2UnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIHNlbGYub25DbG9zZSgndHJhbnNwb3J0IGNsb3NlJyk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogUHJvYmVzIGEgdHJhbnNwb3J0LlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHRyYW5zcG9ydCBuYW1lXG4gICAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBTb2NrZXQucHJvdG90eXBlLnByb2JlID0gZnVuY3Rpb24gKG5hbWUpIHtcbiAgICAgICAgICAgIGRlYnVnKCdwcm9iaW5nIHRyYW5zcG9ydCBcIiVzXCInLCBuYW1lKTtcbiAgICAgICAgICAgIHZhciB0cmFuc3BvcnQgPSB0aGlzLmNyZWF0ZVRyYW5zcG9ydChuYW1lLCB7IHByb2JlOiAxIH0pLFxuICAgICAgICAgICAgICAgIGZhaWxlZCA9IGZhbHNlLFxuICAgICAgICAgICAgICAgIHNlbGYgPSB0aGlzO1xuXG4gICAgICAgICAgICBTb2NrZXQucHJpb3JXZWJzb2NrZXRTdWNjZXNzID0gZmFsc2U7XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIG9uVHJhbnNwb3J0T3BlbigpIHtcbiAgICAgICAgICAgICAgaWYgKHNlbGYub25seUJpbmFyeVVwZ3JhZGVzKSB7XG4gICAgICAgICAgICAgICAgdmFyIHVwZ3JhZGVMb3Nlc0JpbmFyeSA9ICF0aGlzLnN1cHBvcnRzQmluYXJ5ICYmIHNlbGYudHJhbnNwb3J0LnN1cHBvcnRzQmluYXJ5O1xuICAgICAgICAgICAgICAgIGZhaWxlZCA9IGZhaWxlZCB8fCB1cGdyYWRlTG9zZXNCaW5hcnk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgaWYgKGZhaWxlZCkgcmV0dXJuO1xuXG4gICAgICAgICAgICAgIGRlYnVnKCdwcm9iZSB0cmFuc3BvcnQgXCIlc1wiIG9wZW5lZCcsIG5hbWUpO1xuICAgICAgICAgICAgICB0cmFuc3BvcnQuc2VuZChbeyB0eXBlOiAncGluZycsIGRhdGE6ICdwcm9iZScgfV0pO1xuICAgICAgICAgICAgICB0cmFuc3BvcnQub25jZSgncGFja2V0JywgZnVuY3Rpb24gKG1zZykge1xuICAgICAgICAgICAgICAgIGlmIChmYWlsZWQpIHJldHVybjtcbiAgICAgICAgICAgICAgICBpZiAoJ3BvbmcnID09IG1zZy50eXBlICYmICdwcm9iZScgPT0gbXNnLmRhdGEpIHtcbiAgICAgICAgICAgICAgICAgIGRlYnVnKCdwcm9iZSB0cmFuc3BvcnQgXCIlc1wiIHBvbmcnLCBuYW1lKTtcbiAgICAgICAgICAgICAgICAgIHNlbGYudXBncmFkaW5nID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgIHNlbGYuZW1pdCgndXBncmFkaW5nJywgdHJhbnNwb3J0KTtcbiAgICAgICAgICAgICAgICAgIGlmICghdHJhbnNwb3J0KSByZXR1cm47XG4gICAgICAgICAgICAgICAgICBTb2NrZXQucHJpb3JXZWJzb2NrZXRTdWNjZXNzID0gJ3dlYnNvY2tldCcgPT0gdHJhbnNwb3J0Lm5hbWU7XG5cbiAgICAgICAgICAgICAgICAgIGRlYnVnKCdwYXVzaW5nIGN1cnJlbnQgdHJhbnNwb3J0IFwiJXNcIicsIHNlbGYudHJhbnNwb3J0Lm5hbWUpO1xuICAgICAgICAgICAgICAgICAgc2VsZi50cmFuc3BvcnQucGF1c2UoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZmFpbGVkKSByZXR1cm47XG4gICAgICAgICAgICAgICAgICAgIGlmICgnY2xvc2VkJyA9PSBzZWxmLnJlYWR5U3RhdGUpIHJldHVybjtcbiAgICAgICAgICAgICAgICAgICAgZGVidWcoJ2NoYW5naW5nIHRyYW5zcG9ydCBhbmQgc2VuZGluZyB1cGdyYWRlIHBhY2tldCcpO1xuXG4gICAgICAgICAgICAgICAgICAgIGNsZWFudXAoKTtcblxuICAgICAgICAgICAgICAgICAgICBzZWxmLnNldFRyYW5zcG9ydCh0cmFuc3BvcnQpO1xuICAgICAgICAgICAgICAgICAgICB0cmFuc3BvcnQuc2VuZChbeyB0eXBlOiAndXBncmFkZScgfV0pO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmVtaXQoJ3VwZ3JhZGUnLCB0cmFuc3BvcnQpO1xuICAgICAgICAgICAgICAgICAgICB0cmFuc3BvcnQgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLnVwZ3JhZGluZyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBzZWxmLmZsdXNoKCk7XG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgZmFpbGVkJywgbmFtZSk7XG4gICAgICAgICAgICAgICAgICB2YXIgZXJyID0gbmV3IEVycm9yKCdwcm9iZSBlcnJvcicpO1xuICAgICAgICAgICAgICAgICAgZXJyLnRyYW5zcG9ydCA9IHRyYW5zcG9ydC5uYW1lO1xuICAgICAgICAgICAgICAgICAgc2VsZi5lbWl0KCd1cGdyYWRlRXJyb3InLCBlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIGZyZWV6ZVRyYW5zcG9ydCgpIHtcbiAgICAgICAgICAgICAgaWYgKGZhaWxlZCkgcmV0dXJuO1xuXG4gICAgICAgICAgICAgIC8vIEFueSBjYWxsYmFjayBjYWxsZWQgYnkgdHJhbnNwb3J0IHNob3VsZCBiZSBpZ25vcmVkIHNpbmNlIG5vd1xuICAgICAgICAgICAgICBmYWlsZWQgPSB0cnVlO1xuXG4gICAgICAgICAgICAgIGNsZWFudXAoKTtcblxuICAgICAgICAgICAgICB0cmFuc3BvcnQuY2xvc2UoKTtcbiAgICAgICAgICAgICAgdHJhbnNwb3J0ID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy9IYW5kbGUgYW55IGVycm9yIHRoYXQgaGFwcGVucyB3aGlsZSBwcm9iaW5nXG4gICAgICAgICAgICBmdW5jdGlvbiBvbmVycm9yKGVycikge1xuICAgICAgICAgICAgICB2YXIgZXJyb3IgPSBuZXcgRXJyb3IoJ3Byb2JlIGVycm9yOiAnICsgZXJyKTtcbiAgICAgICAgICAgICAgZXJyb3IudHJhbnNwb3J0ID0gdHJhbnNwb3J0Lm5hbWU7XG5cbiAgICAgICAgICAgICAgZnJlZXplVHJhbnNwb3J0KCk7XG5cbiAgICAgICAgICAgICAgZGVidWcoJ3Byb2JlIHRyYW5zcG9ydCBcIiVzXCIgZmFpbGVkIGJlY2F1c2Ugb2YgZXJyb3I6ICVzJywgbmFtZSwgZXJyKTtcblxuICAgICAgICAgICAgICBzZWxmLmVtaXQoJ3VwZ3JhZGVFcnJvcicsIGVycm9yKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZnVuY3Rpb24gb25UcmFuc3BvcnRDbG9zZSgpIHtcbiAgICAgICAgICAgICAgb25lcnJvcihcInRyYW5zcG9ydCBjbG9zZWRcIik7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vV2hlbiB0aGUgc29ja2V0IGlzIGNsb3NlZCB3aGlsZSB3ZSdyZSBwcm9iaW5nXG4gICAgICAgICAgICBmdW5jdGlvbiBvbmNsb3NlKCkge1xuICAgICAgICAgICAgICBvbmVycm9yKFwic29ja2V0IGNsb3NlZFwiKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy9XaGVuIHRoZSBzb2NrZXQgaXMgdXBncmFkZWQgd2hpbGUgd2UncmUgcHJvYmluZ1xuICAgICAgICAgICAgZnVuY3Rpb24gb251cGdyYWRlKHRvKSB7XG4gICAgICAgICAgICAgIGlmICh0cmFuc3BvcnQgJiYgdG8ubmFtZSAhPSB0cmFuc3BvcnQubmFtZSkge1xuICAgICAgICAgICAgICAgIGRlYnVnKCdcIiVzXCIgd29ya3MgLSBhYm9ydGluZyBcIiVzXCInLCB0by5uYW1lLCB0cmFuc3BvcnQubmFtZSk7XG4gICAgICAgICAgICAgICAgZnJlZXplVHJhbnNwb3J0KCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy9SZW1vdmUgYWxsIGxpc3RlbmVycyBvbiB0aGUgdHJhbnNwb3J0IGFuZCBvbiBzZWxmXG4gICAgICAgICAgICBmdW5jdGlvbiBjbGVhbnVwKCkge1xuICAgICAgICAgICAgICB0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIoJ29wZW4nLCBvblRyYW5zcG9ydE9wZW4pO1xuICAgICAgICAgICAgICB0cmFuc3BvcnQucmVtb3ZlTGlzdGVuZXIoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgICAgICAgICAgIHRyYW5zcG9ydC5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvblRyYW5zcG9ydENsb3NlKTtcbiAgICAgICAgICAgICAgc2VsZi5yZW1vdmVMaXN0ZW5lcignY2xvc2UnLCBvbmNsb3NlKTtcbiAgICAgICAgICAgICAgc2VsZi5yZW1vdmVMaXN0ZW5lcigndXBncmFkaW5nJywgb251cGdyYWRlKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdHJhbnNwb3J0Lm9uY2UoJ29wZW4nLCBvblRyYW5zcG9ydE9wZW4pO1xuICAgICAgICAgICAgdHJhbnNwb3J0Lm9uY2UoJ2Vycm9yJywgb25lcnJvcik7XG4gICAgICAgICAgICB0cmFuc3BvcnQub25jZSgnY2xvc2UnLCBvblRyYW5zcG9ydENsb3NlKTtcblxuICAgICAgICAgICAgdGhpcy5vbmNlKCdjbG9zZScsIG9uY2xvc2UpO1xuICAgICAgICAgICAgdGhpcy5vbmNlKCd1cGdyYWRpbmcnLCBvbnVwZ3JhZGUpO1xuXG4gICAgICAgICAgICB0cmFuc3BvcnQub3BlbigpO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBDYWxsZWQgd2hlbiBjb25uZWN0aW9uIGlzIGRlZW1lZCBvcGVuLlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIFNvY2tldC5wcm90b3R5cGUub25PcGVuID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZGVidWcoJ3NvY2tldCBvcGVuJyk7XG4gICAgICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSAnb3Blbic7XG4gICAgICAgICAgICBTb2NrZXQucHJpb3JXZWJzb2NrZXRTdWNjZXNzID0gJ3dlYnNvY2tldCcgPT0gdGhpcy50cmFuc3BvcnQubmFtZTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnb3BlbicpO1xuICAgICAgICAgICAgdGhpcy5mbHVzaCgpO1xuXG4gICAgICAgICAgICAvLyB3ZSBjaGVjayBmb3IgYHJlYWR5U3RhdGVgIGluIGNhc2UgYW4gYG9wZW5gXG4gICAgICAgICAgICAvLyBsaXN0ZW5lciBhbHJlYWR5IGNsb3NlZCB0aGUgc29ja2V0XG4gICAgICAgICAgICBpZiAoJ29wZW4nID09IHRoaXMucmVhZHlTdGF0ZSAmJiB0aGlzLnVwZ3JhZGUgJiYgdGhpcy50cmFuc3BvcnQucGF1c2UpIHtcbiAgICAgICAgICAgICAgZGVidWcoJ3N0YXJ0aW5nIHVwZ3JhZGUgcHJvYmVzJyk7XG4gICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGhpcy51cGdyYWRlcy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgICAgICB0aGlzLnByb2JlKHRoaXMudXBncmFkZXNbaV0pO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEhhbmRsZXMgYSBwYWNrZXQuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIFNvY2tldC5wcm90b3R5cGUub25QYWNrZXQgPSBmdW5jdGlvbiAocGFja2V0KSB7XG4gICAgICAgICAgICBpZiAoJ29wZW5pbmcnID09IHRoaXMucmVhZHlTdGF0ZSB8fCAnb3BlbicgPT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgICAgICAgICAgIGRlYnVnKCdzb2NrZXQgcmVjZWl2ZTogdHlwZSBcIiVzXCIsIGRhdGEgXCIlc1wiJywgcGFja2V0LnR5cGUsIHBhY2tldC5kYXRhKTtcblxuICAgICAgICAgICAgICB0aGlzLmVtaXQoJ3BhY2tldCcsIHBhY2tldCk7XG5cbiAgICAgICAgICAgICAgLy8gU29ja2V0IGlzIGxpdmUgLSBhbnkgcGFja2V0IGNvdW50c1xuICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2hlYXJ0YmVhdCcpO1xuXG4gICAgICAgICAgICAgIHN3aXRjaCAocGFja2V0LnR5cGUpIHtcbiAgICAgICAgICAgICAgICBjYXNlICdvcGVuJzpcbiAgICAgICAgICAgICAgICAgIHRoaXMub25IYW5kc2hha2UocGFyc2Vqc29uKHBhY2tldC5kYXRhKSk7XG4gICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgIGNhc2UgJ3BvbmcnOlxuICAgICAgICAgICAgICAgICAgdGhpcy5zZXRQaW5nKCk7XG4gICAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ3BvbmcnKTtcbiAgICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgY2FzZSAnZXJyb3InOlxuICAgICAgICAgICAgICAgICAgdmFyIGVyciA9IG5ldyBFcnJvcignc2VydmVyIGVycm9yJyk7XG4gICAgICAgICAgICAgICAgICBlcnIuY29kZSA9IHBhY2tldC5kYXRhO1xuICAgICAgICAgICAgICAgICAgdGhpcy5vbkVycm9yKGVycik7XG4gICAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgICAgIGNhc2UgJ21lc3NhZ2UnOlxuICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdkYXRhJywgcGFja2V0LmRhdGEpO1xuICAgICAgICAgICAgICAgICAgdGhpcy5lbWl0KCdtZXNzYWdlJywgcGFja2V0LmRhdGEpO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGRlYnVnKCdwYWNrZXQgcmVjZWl2ZWQgd2l0aCBzb2NrZXQgcmVhZHlTdGF0ZSBcIiVzXCInLCB0aGlzLnJlYWR5U3RhdGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH07XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBDYWxsZWQgdXBvbiBoYW5kc2hha2UgY29tcGxldGlvbi5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBoYW5kc2hha2Ugb2JqXG4gICAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBTb2NrZXQucHJvdG90eXBlLm9uSGFuZHNoYWtlID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnaGFuZHNoYWtlJywgZGF0YSk7XG4gICAgICAgICAgICB0aGlzLmlkID0gZGF0YS5zaWQ7XG4gICAgICAgICAgICB0aGlzLnRyYW5zcG9ydC5xdWVyeS5zaWQgPSBkYXRhLnNpZDtcbiAgICAgICAgICAgIHRoaXMudXBncmFkZXMgPSB0aGlzLmZpbHRlclVwZ3JhZGVzKGRhdGEudXBncmFkZXMpO1xuICAgICAgICAgICAgdGhpcy5waW5nSW50ZXJ2YWwgPSBkYXRhLnBpbmdJbnRlcnZhbDtcbiAgICAgICAgICAgIHRoaXMucGluZ1RpbWVvdXQgPSBkYXRhLnBpbmdUaW1lb3V0O1xuICAgICAgICAgICAgdGhpcy5vbk9wZW4oKTtcbiAgICAgICAgICAgIC8vIEluIGNhc2Ugb3BlbiBoYW5kbGVyIGNsb3NlcyBzb2NrZXRcbiAgICAgICAgICAgIGlmICgnY2xvc2VkJyA9PSB0aGlzLnJlYWR5U3RhdGUpIHJldHVybjtcbiAgICAgICAgICAgIHRoaXMuc2V0UGluZygpO1xuXG4gICAgICAgICAgICAvLyBQcm9sb25nIGxpdmVuZXNzIG9mIHNvY2tldCBvbiBoZWFydGJlYXRcbiAgICAgICAgICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIoJ2hlYXJ0YmVhdCcsIHRoaXMub25IZWFydGJlYXQpO1xuICAgICAgICAgICAgdGhpcy5vbignaGVhcnRiZWF0JywgdGhpcy5vbkhlYXJ0YmVhdCk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFJlc2V0cyBwaW5nIHRpbWVvdXQuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIFNvY2tldC5wcm90b3R5cGUub25IZWFydGJlYXQgPSBmdW5jdGlvbiAodGltZW91dCkge1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucGluZ1RpbWVvdXRUaW1lcik7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgICBzZWxmLnBpbmdUaW1lb3V0VGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgaWYgKCdjbG9zZWQnID09IHNlbGYucmVhZHlTdGF0ZSkgcmV0dXJuO1xuICAgICAgICAgICAgICBzZWxmLm9uQ2xvc2UoJ3BpbmcgdGltZW91dCcpO1xuICAgICAgICAgICAgfSwgdGltZW91dCB8fCBzZWxmLnBpbmdJbnRlcnZhbCArIHNlbGYucGluZ1RpbWVvdXQpO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBQaW5ncyBzZXJ2ZXIgZXZlcnkgYHRoaXMucGluZ0ludGVydmFsYCBhbmQgZXhwZWN0cyByZXNwb25zZVxuICAgICAgICAgICAqIHdpdGhpbiBgdGhpcy5waW5nVGltZW91dGAgb3IgY2xvc2VzIGNvbm5lY3Rpb24uXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIFNvY2tldC5wcm90b3R5cGUuc2V0UGluZyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICAgIGNsZWFyVGltZW91dChzZWxmLnBpbmdJbnRlcnZhbFRpbWVyKTtcbiAgICAgICAgICAgIHNlbGYucGluZ0ludGVydmFsVGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgZGVidWcoJ3dyaXRpbmcgcGluZyBwYWNrZXQgLSBleHBlY3RpbmcgcG9uZyB3aXRoaW4gJXNtcycsIHNlbGYucGluZ1RpbWVvdXQpO1xuICAgICAgICAgICAgICBzZWxmLnBpbmcoKTtcbiAgICAgICAgICAgICAgc2VsZi5vbkhlYXJ0YmVhdChzZWxmLnBpbmdUaW1lb3V0KTtcbiAgICAgICAgICAgIH0sIHNlbGYucGluZ0ludGVydmFsKTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgKiBTZW5kcyBhIHBpbmcgcGFja2V0LlxuICAgICAgICAgICpcbiAgICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgICovXG5cbiAgICAgICAgICBTb2NrZXQucHJvdG90eXBlLnBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgICB0aGlzLnNlbmRQYWNrZXQoJ3BpbmcnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIHNlbGYuZW1pdCgncGluZycpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIENhbGxlZCBvbiBgZHJhaW5gIGV2ZW50XG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIFNvY2tldC5wcm90b3R5cGUub25EcmFpbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRoaXMud3JpdGVCdWZmZXIuc3BsaWNlKDAsIHRoaXMucHJldkJ1ZmZlckxlbik7XG5cbiAgICAgICAgICAgIC8vIHNldHRpbmcgcHJldkJ1ZmZlckxlbiA9IDAgaXMgdmVyeSBpbXBvcnRhbnRcbiAgICAgICAgICAgIC8vIGZvciBleGFtcGxlLCB3aGVuIHVwZ3JhZGluZywgdXBncmFkZSBwYWNrZXQgaXMgc2VudCBvdmVyLFxuICAgICAgICAgICAgLy8gYW5kIGEgbm9uemVybyBwcmV2QnVmZmVyTGVuIGNvdWxkIGNhdXNlIHByb2JsZW1zIG9uIGBkcmFpbmBcbiAgICAgICAgICAgIHRoaXMucHJldkJ1ZmZlckxlbiA9IDA7XG5cbiAgICAgICAgICAgIGlmICgwID09PSB0aGlzLndyaXRlQnVmZmVyLmxlbmd0aCkge1xuICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2RyYWluJyk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLmZsdXNoKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEZsdXNoIHdyaXRlIGJ1ZmZlcnMuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIFNvY2tldC5wcm90b3R5cGUuZmx1c2ggPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoJ2Nsb3NlZCcgIT0gdGhpcy5yZWFkeVN0YXRlICYmIHRoaXMudHJhbnNwb3J0LndyaXRhYmxlICYmICF0aGlzLnVwZ3JhZGluZyAmJiB0aGlzLndyaXRlQnVmZmVyLmxlbmd0aCkge1xuICAgICAgICAgICAgICBkZWJ1ZygnZmx1c2hpbmcgJWQgcGFja2V0cyBpbiBzb2NrZXQnLCB0aGlzLndyaXRlQnVmZmVyLmxlbmd0aCk7XG4gICAgICAgICAgICAgIHRoaXMudHJhbnNwb3J0LnNlbmQodGhpcy53cml0ZUJ1ZmZlcik7XG4gICAgICAgICAgICAgIC8vIGtlZXAgdHJhY2sgb2YgY3VycmVudCBsZW5ndGggb2Ygd3JpdGVCdWZmZXJcbiAgICAgICAgICAgICAgLy8gc3BsaWNlIHdyaXRlQnVmZmVyIGFuZCBjYWxsYmFja0J1ZmZlciBvbiBgZHJhaW5gXG4gICAgICAgICAgICAgIHRoaXMucHJldkJ1ZmZlckxlbiA9IHRoaXMud3JpdGVCdWZmZXIubGVuZ3RoO1xuICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2ZsdXNoJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFNlbmRzIGEgbWVzc2FnZS5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBtZXNzYWdlLlxuICAgICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIGZ1bmN0aW9uLlxuICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICAgICAgICAgICAqIEByZXR1cm4ge1NvY2tldH0gZm9yIGNoYWluaW5nLlxuICAgICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBTb2NrZXQucHJvdG90eXBlLndyaXRlID0gU29ja2V0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKG1zZywgb3B0aW9ucywgZm4pIHtcbiAgICAgICAgICAgIHRoaXMuc2VuZFBhY2tldCgnbWVzc2FnZScsIG1zZywgb3B0aW9ucywgZm4pO1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFNlbmRzIGEgcGFja2V0LlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHBhY2tldCB0eXBlLlxuICAgICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhLlxuICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLlxuICAgICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIGZ1bmN0aW9uLlxuICAgICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgU29ja2V0LnByb3RvdHlwZS5zZW5kUGFja2V0ID0gZnVuY3Rpb24gKHR5cGUsIGRhdGEsIG9wdGlvbnMsIGZuKSB7XG4gICAgICAgICAgICBpZiAoJ2Z1bmN0aW9uJyA9PSB0eXBlb2YgZGF0YSkge1xuICAgICAgICAgICAgICBmbiA9IGRhdGE7XG4gICAgICAgICAgICAgIGRhdGEgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiBvcHRpb25zKSB7XG4gICAgICAgICAgICAgIGZuID0gb3B0aW9ucztcbiAgICAgICAgICAgICAgb3B0aW9ucyA9IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICgnY2xvc2luZycgPT0gdGhpcy5yZWFkeVN0YXRlIHx8ICdjbG9zZWQnID09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9O1xuICAgICAgICAgICAgb3B0aW9ucy5jb21wcmVzcyA9IGZhbHNlICE9PSBvcHRpb25zLmNvbXByZXNzO1xuXG4gICAgICAgICAgICB2YXIgcGFja2V0ID0ge1xuICAgICAgICAgICAgICB0eXBlOiB0eXBlLFxuICAgICAgICAgICAgICBkYXRhOiBkYXRhLFxuICAgICAgICAgICAgICBvcHRpb25zOiBvcHRpb25zXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdwYWNrZXRDcmVhdGUnLCBwYWNrZXQpO1xuICAgICAgICAgICAgdGhpcy53cml0ZUJ1ZmZlci5wdXNoKHBhY2tldCk7XG4gICAgICAgICAgICBpZiAoZm4pIHRoaXMub25jZSgnZmx1c2gnLCBmbik7XG4gICAgICAgICAgICB0aGlzLmZsdXNoKCk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIENsb3NlcyB0aGUgY29ubmVjdGlvbi5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgU29ja2V0LnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICgnb3BlbmluZycgPT0gdGhpcy5yZWFkeVN0YXRlIHx8ICdvcGVuJyA9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICAgICAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NpbmcnO1xuXG4gICAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgICAgICAgICAgICBpZiAodGhpcy53cml0ZUJ1ZmZlci5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm9uY2UoJ2RyYWluJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgaWYgKHRoaXMudXBncmFkaW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIHdhaXRGb3JVcGdyYWRlKCk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBjbG9zZSgpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMudXBncmFkaW5nKSB7XG4gICAgICAgICAgICAgICAgd2FpdEZvclVwZ3JhZGUoKTtcbiAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBjbG9zZSgpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIGNsb3NlKCkge1xuICAgICAgICAgICAgICBzZWxmLm9uQ2xvc2UoJ2ZvcmNlZCBjbG9zZScpO1xuICAgICAgICAgICAgICBkZWJ1Zygnc29ja2V0IGNsb3NpbmcgLSB0ZWxsaW5nIHRyYW5zcG9ydCB0byBjbG9zZScpO1xuICAgICAgICAgICAgICBzZWxmLnRyYW5zcG9ydC5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmdW5jdGlvbiBjbGVhbnVwQW5kQ2xvc2UoKSB7XG4gICAgICAgICAgICAgIHNlbGYucmVtb3ZlTGlzdGVuZXIoJ3VwZ3JhZGUnLCBjbGVhbnVwQW5kQ2xvc2UpO1xuICAgICAgICAgICAgICBzZWxmLnJlbW92ZUxpc3RlbmVyKCd1cGdyYWRlRXJyb3InLCBjbGVhbnVwQW5kQ2xvc2UpO1xuICAgICAgICAgICAgICBjbG9zZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmdW5jdGlvbiB3YWl0Rm9yVXBncmFkZSgpIHtcbiAgICAgICAgICAgICAgLy8gd2FpdCBmb3IgdXBncmFkZSB0byBmaW5pc2ggc2luY2Ugd2UgY2FuJ3Qgc2VuZCBwYWNrZXRzIHdoaWxlIHBhdXNpbmcgYSB0cmFuc3BvcnRcbiAgICAgICAgICAgICAgc2VsZi5vbmNlKCd1cGdyYWRlJywgY2xlYW51cEFuZENsb3NlKTtcbiAgICAgICAgICAgICAgc2VsZi5vbmNlKCd1cGdyYWRlRXJyb3InLCBjbGVhbnVwQW5kQ2xvc2UpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogQ2FsbGVkIHVwb24gdHJhbnNwb3J0IGVycm9yXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIFNvY2tldC5wcm90b3R5cGUub25FcnJvciA9IGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgIGRlYnVnKCdzb2NrZXQgZXJyb3IgJWonLCBlcnIpO1xuICAgICAgICAgICAgU29ja2V0LnByaW9yV2Vic29ja2V0U3VjY2VzcyA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICAgICAgICB0aGlzLm9uQ2xvc2UoJ3RyYW5zcG9ydCBlcnJvcicsIGVycik7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIENhbGxlZCB1cG9uIHRyYW5zcG9ydCBjbG9zZS5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgU29ja2V0LnByb3RvdHlwZS5vbkNsb3NlID0gZnVuY3Rpb24gKHJlYXNvbiwgZGVzYykge1xuICAgICAgICAgICAgaWYgKCdvcGVuaW5nJyA9PSB0aGlzLnJlYWR5U3RhdGUgfHwgJ29wZW4nID09IHRoaXMucmVhZHlTdGF0ZSB8fCAnY2xvc2luZycgPT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgICAgICAgICAgIGRlYnVnKCdzb2NrZXQgY2xvc2Ugd2l0aCByZWFzb246IFwiJXNcIicsIHJlYXNvbik7XG4gICAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgICAgICAgICAgICAvLyBjbGVhciB0aW1lcnNcbiAgICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMucGluZ0ludGVydmFsVGltZXIpO1xuICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGhpcy5waW5nVGltZW91dFRpbWVyKTtcblxuICAgICAgICAgICAgICAvLyBzdG9wIGV2ZW50IGZyb20gZmlyaW5nIGFnYWluIGZvciB0cmFuc3BvcnRcbiAgICAgICAgICAgICAgdGhpcy50cmFuc3BvcnQucmVtb3ZlQWxsTGlzdGVuZXJzKCdjbG9zZScpO1xuXG4gICAgICAgICAgICAgIC8vIGVuc3VyZSB0cmFuc3BvcnQgd29uJ3Qgc3RheSBvcGVuXG4gICAgICAgICAgICAgIHRoaXMudHJhbnNwb3J0LmNsb3NlKCk7XG5cbiAgICAgICAgICAgICAgLy8gaWdub3JlIGZ1cnRoZXIgdHJhbnNwb3J0IGNvbW11bmljYXRpb25cbiAgICAgICAgICAgICAgdGhpcy50cmFuc3BvcnQucmVtb3ZlQWxsTGlzdGVuZXJzKCk7XG5cbiAgICAgICAgICAgICAgLy8gc2V0IHJlYWR5IHN0YXRlXG4gICAgICAgICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zZWQnO1xuXG4gICAgICAgICAgICAgIC8vIGNsZWFyIHNlc3Npb24gaWRcbiAgICAgICAgICAgICAgdGhpcy5pZCA9IG51bGw7XG5cbiAgICAgICAgICAgICAgLy8gZW1pdCBjbG9zZSBldmVudFxuICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2Nsb3NlJywgcmVhc29uLCBkZXNjKTtcblxuICAgICAgICAgICAgICAvLyBjbGVhbiBidWZmZXJzIGFmdGVyLCBzbyB1c2VycyBjYW4gc3RpbGxcbiAgICAgICAgICAgICAgLy8gZ3JhYiB0aGUgYnVmZmVycyBvbiBgY2xvc2VgIGV2ZW50XG4gICAgICAgICAgICAgIHNlbGYud3JpdGVCdWZmZXIgPSBbXTtcbiAgICAgICAgICAgICAgc2VsZi5wcmV2QnVmZmVyTGVuID0gMDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRmlsdGVycyB1cGdyYWRlcywgcmV0dXJuaW5nIG9ubHkgdGhvc2UgbWF0Y2hpbmcgY2xpZW50IHRyYW5zcG9ydHMuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBzZXJ2ZXIgdXBncmFkZXNcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKlxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgU29ja2V0LnByb3RvdHlwZS5maWx0ZXJVcGdyYWRlcyA9IGZ1bmN0aW9uICh1cGdyYWRlcykge1xuICAgICAgICAgICAgdmFyIGZpbHRlcmVkVXBncmFkZXMgPSBbXTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBqID0gdXBncmFkZXMubGVuZ3RoOyBpIDwgajsgaSsrKSB7XG4gICAgICAgICAgICAgIGlmICh+aW5kZXgodGhpcy50cmFuc3BvcnRzLCB1cGdyYWRlc1tpXSkpIGZpbHRlcmVkVXBncmFkZXMucHVzaCh1cGdyYWRlc1tpXSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZmlsdGVyZWRVcGdyYWRlcztcbiAgICAgICAgICB9O1xuICAgICAgICB9KS5jYWxsKHRoaXMsIHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDoge30pO1xuICAgICAgfSwgeyBcIi4vdHJhbnNwb3J0XCI6IDQsIFwiLi90cmFuc3BvcnRzXCI6IDUsIFwiY29tcG9uZW50LWVtaXR0ZXJcIjogMTUsIFwiZGVidWdcIjogMTcsIFwiZW5naW5lLmlvLXBhcnNlclwiOiAxOSwgXCJpbmRleG9mXCI6IDIzLCBcInBhcnNlanNvblwiOiAyNiwgXCJwYXJzZXFzXCI6IDI3LCBcInBhcnNldXJpXCI6IDI4IH1dLCA0OiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuICAgICAgICAvKipcbiAgICAgICAgICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAgICAgICAgICovXG5cbiAgICAgICAgdmFyIHBhcnNlciA9IF9kZXJlcV8oJ2VuZ2luZS5pby1wYXJzZXInKTtcbiAgICAgICAgdmFyIEVtaXR0ZXIgPSBfZGVyZXFfKCdjb21wb25lbnQtZW1pdHRlcicpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNb2R1bGUgZXhwb3J0cy5cbiAgICAgICAgICovXG5cbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBUcmFuc3BvcnQ7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRyYW5zcG9ydCBhYnN0cmFjdCBjb25zdHJ1Y3Rvci5cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnMuXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBmdW5jdGlvbiBUcmFuc3BvcnQob3B0cykge1xuICAgICAgICAgIHRoaXMucGF0aCA9IG9wdHMucGF0aDtcbiAgICAgICAgICB0aGlzLmhvc3RuYW1lID0gb3B0cy5ob3N0bmFtZTtcbiAgICAgICAgICB0aGlzLnBvcnQgPSBvcHRzLnBvcnQ7XG4gICAgICAgICAgdGhpcy5zZWN1cmUgPSBvcHRzLnNlY3VyZTtcbiAgICAgICAgICB0aGlzLnF1ZXJ5ID0gb3B0cy5xdWVyeTtcbiAgICAgICAgICB0aGlzLnRpbWVzdGFtcFBhcmFtID0gb3B0cy50aW1lc3RhbXBQYXJhbTtcbiAgICAgICAgICB0aGlzLnRpbWVzdGFtcFJlcXVlc3RzID0gb3B0cy50aW1lc3RhbXBSZXF1ZXN0cztcbiAgICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSAnJztcbiAgICAgICAgICB0aGlzLmFnZW50ID0gb3B0cy5hZ2VudCB8fCBmYWxzZTtcbiAgICAgICAgICB0aGlzLnNvY2tldCA9IG9wdHMuc29ja2V0O1xuICAgICAgICAgIHRoaXMuZW5hYmxlc1hEUiA9IG9wdHMuZW5hYmxlc1hEUjtcblxuICAgICAgICAgIC8vIFNTTCBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICAgICAgICAgIHRoaXMucGZ4ID0gb3B0cy5wZng7XG4gICAgICAgICAgdGhpcy5rZXkgPSBvcHRzLmtleTtcbiAgICAgICAgICB0aGlzLnBhc3NwaHJhc2UgPSBvcHRzLnBhc3NwaHJhc2U7XG4gICAgICAgICAgdGhpcy5jZXJ0ID0gb3B0cy5jZXJ0O1xuICAgICAgICAgIHRoaXMuY2EgPSBvcHRzLmNhO1xuICAgICAgICAgIHRoaXMuY2lwaGVycyA9IG9wdHMuY2lwaGVycztcbiAgICAgICAgICB0aGlzLnJlamVjdFVuYXV0aG9yaXplZCA9IG9wdHMucmVqZWN0VW5hdXRob3JpemVkO1xuXG4gICAgICAgICAgLy8gb3RoZXIgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgICAgICAgICB0aGlzLmV4dHJhSGVhZGVycyA9IG9wdHMuZXh0cmFIZWFkZXJzO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1peCBpbiBgRW1pdHRlcmAuXG4gICAgICAgICAqL1xuXG4gICAgICAgIEVtaXR0ZXIoVHJhbnNwb3J0LnByb3RvdHlwZSk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVtaXRzIGFuIGVycm9yLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyXG4gICAgICAgICAqIEByZXR1cm4ge1RyYW5zcG9ydH0gZm9yIGNoYWluaW5nXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIFRyYW5zcG9ydC5wcm90b3R5cGUub25FcnJvciA9IGZ1bmN0aW9uIChtc2csIGRlc2MpIHtcbiAgICAgICAgICB2YXIgZXJyID0gbmV3IEVycm9yKG1zZyk7XG4gICAgICAgICAgZXJyLnR5cGUgPSAnVHJhbnNwb3J0RXJyb3InO1xuICAgICAgICAgIGVyci5kZXNjcmlwdGlvbiA9IGRlc2M7XG4gICAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE9wZW5zIHRoZSB0cmFuc3BvcnQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIFRyYW5zcG9ydC5wcm90b3R5cGUub3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpZiAoJ2Nsb3NlZCcgPT0gdGhpcy5yZWFkeVN0YXRlIHx8ICcnID09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgICAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gJ29wZW5pbmcnO1xuICAgICAgICAgICAgdGhpcy5kb09wZW4oKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ2xvc2VzIHRoZSB0cmFuc3BvcnQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBUcmFuc3BvcnQucHJvdG90eXBlLmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmICgnb3BlbmluZycgPT0gdGhpcy5yZWFkeVN0YXRlIHx8ICdvcGVuJyA9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICAgICAgICAgIHRoaXMuZG9DbG9zZSgpO1xuICAgICAgICAgICAgdGhpcy5vbkNsb3NlKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNlbmRzIG11bHRpcGxlIHBhY2tldHMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IHBhY2tldHNcbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIFRyYW5zcG9ydC5wcm90b3R5cGUuc2VuZCA9IGZ1bmN0aW9uIChwYWNrZXRzKSB7XG4gICAgICAgICAgaWYgKCdvcGVuJyA9PSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICAgICAgICAgIHRoaXMud3JpdGUocGFja2V0cyk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVHJhbnNwb3J0IG5vdCBvcGVuJyk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYWxsZWQgdXBvbiBvcGVuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBUcmFuc3BvcnQucHJvdG90eXBlLm9uT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSAnb3Blbic7XG4gICAgICAgICAgdGhpcy53cml0YWJsZSA9IHRydWU7XG4gICAgICAgICAgdGhpcy5lbWl0KCdvcGVuJyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENhbGxlZCB3aXRoIGRhdGEuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBUcmFuc3BvcnQucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgdmFyIHBhY2tldCA9IHBhcnNlci5kZWNvZGVQYWNrZXQoZGF0YSwgdGhpcy5zb2NrZXQuYmluYXJ5VHlwZSk7XG4gICAgICAgICAgdGhpcy5vblBhY2tldChwYWNrZXQpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYWxsZWQgd2l0aCBhIGRlY29kZWQgcGFja2V0LlxuICAgICAgICAgKi9cblxuICAgICAgICBUcmFuc3BvcnQucHJvdG90eXBlLm9uUGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICAgICAgICAgIHRoaXMuZW1pdCgncGFja2V0JywgcGFja2V0KTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGVkIHVwb24gY2xvc2UuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBUcmFuc3BvcnQucHJvdG90eXBlLm9uQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gICAgICAgICAgdGhpcy5lbWl0KCdjbG9zZScpO1xuICAgICAgICB9O1xuICAgICAgfSwgeyBcImNvbXBvbmVudC1lbWl0dGVyXCI6IDE1LCBcImVuZ2luZS5pby1wYXJzZXJcIjogMTkgfV0sIDU6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG4gICAgICAgIChmdW5jdGlvbiAoZ2xvYmFsKSB7XG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogTW9kdWxlIGRlcGVuZGVuY2llc1xuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgdmFyIFhNTEh0dHBSZXF1ZXN0ID0gX2RlcmVxXygneG1saHR0cHJlcXVlc3Qtc3NsJyk7XG4gICAgICAgICAgdmFyIFhIUiA9IF9kZXJlcV8oJy4vcG9sbGluZy14aHInKTtcbiAgICAgICAgICB2YXIgSlNPTlAgPSBfZGVyZXFfKCcuL3BvbGxpbmctanNvbnAnKTtcbiAgICAgICAgICB2YXIgd2Vic29ja2V0ID0gX2RlcmVxXygnLi93ZWJzb2NrZXQnKTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEV4cG9ydCB0cmFuc3BvcnRzLlxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgZXhwb3J0cy5wb2xsaW5nID0gcG9sbGluZztcbiAgICAgICAgICBleHBvcnRzLndlYnNvY2tldCA9IHdlYnNvY2tldDtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFBvbGxpbmcgdHJhbnNwb3J0IHBvbHltb3JwaGljIGNvbnN0cnVjdG9yLlxuICAgICAgICAgICAqIERlY2lkZXMgb24geGhyIHZzIGpzb25wIGJhc2VkIG9uIGZlYXR1cmUgZGV0ZWN0aW9uLlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBmdW5jdGlvbiBwb2xsaW5nKG9wdHMpIHtcbiAgICAgICAgICAgIHZhciB4aHI7XG4gICAgICAgICAgICB2YXIgeGQgPSBmYWxzZTtcbiAgICAgICAgICAgIHZhciB4cyA9IGZhbHNlO1xuICAgICAgICAgICAgdmFyIGpzb25wID0gZmFsc2UgIT09IG9wdHMuanNvbnA7XG5cbiAgICAgICAgICAgIGlmIChnbG9iYWwubG9jYXRpb24pIHtcbiAgICAgICAgICAgICAgdmFyIGlzU1NMID0gJ2h0dHBzOicgPT0gbG9jYXRpb24ucHJvdG9jb2w7XG4gICAgICAgICAgICAgIHZhciBwb3J0ID0gbG9jYXRpb24ucG9ydDtcblxuICAgICAgICAgICAgICAvLyBzb21lIHVzZXIgYWdlbnRzIGhhdmUgZW1wdHkgYGxvY2F0aW9uLnBvcnRgXG4gICAgICAgICAgICAgIGlmICghcG9ydCkge1xuICAgICAgICAgICAgICAgIHBvcnQgPSBpc1NTTCA/IDQ0MyA6IDgwO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgeGQgPSBvcHRzLmhvc3RuYW1lICE9IGxvY2F0aW9uLmhvc3RuYW1lIHx8IHBvcnQgIT0gb3B0cy5wb3J0O1xuICAgICAgICAgICAgICB4cyA9IG9wdHMuc2VjdXJlICE9IGlzU1NMO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBvcHRzLnhkb21haW4gPSB4ZDtcbiAgICAgICAgICAgIG9wdHMueHNjaGVtZSA9IHhzO1xuICAgICAgICAgICAgeGhyID0gbmV3IFhNTEh0dHBSZXF1ZXN0KG9wdHMpO1xuXG4gICAgICAgICAgICBpZiAoJ29wZW4nIGluIHhociAmJiAhb3B0cy5mb3JjZUpTT05QKSB7XG4gICAgICAgICAgICAgIHJldHVybiBuZXcgWEhSKG9wdHMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgaWYgKCFqc29ucCkgdGhyb3cgbmV3IEVycm9yKCdKU09OUCBkaXNhYmxlZCcpO1xuICAgICAgICAgICAgICByZXR1cm4gbmV3IEpTT05QKG9wdHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSkuY2FsbCh0aGlzLCB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHt9KTtcbiAgICAgIH0sIHsgXCIuL3BvbGxpbmctanNvbnBcIjogNiwgXCIuL3BvbGxpbmcteGhyXCI6IDcsIFwiLi93ZWJzb2NrZXRcIjogOSwgXCJ4bWxodHRwcmVxdWVzdC1zc2xcIjogMTAgfV0sIDY6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG4gICAgICAgIChmdW5jdGlvbiAoZ2xvYmFsKSB7XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBNb2R1bGUgcmVxdWlyZW1lbnRzLlxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgdmFyIFBvbGxpbmcgPSBfZGVyZXFfKCcuL3BvbGxpbmcnKTtcbiAgICAgICAgICB2YXIgaW5oZXJpdCA9IF9kZXJlcV8oJ2NvbXBvbmVudC1pbmhlcml0Jyk7XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBNb2R1bGUgZXhwb3J0cy5cbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gSlNPTlBQb2xsaW5nO1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogQ2FjaGVkIHJlZ3VsYXIgZXhwcmVzc2lvbnMuXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICB2YXIgck5ld2xpbmUgPSAvXFxuL2c7XG4gICAgICAgICAgdmFyIHJFc2NhcGVkTmV3bGluZSA9IC9cXFxcbi9nO1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogR2xvYmFsIEpTT05QIGNhbGxiYWNrcy5cbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIHZhciBjYWxsYmFja3M7XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBDYWxsYmFja3MgY291bnQuXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICB2YXIgaW5kZXggPSAwO1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogTm9vcC5cbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIGZ1bmN0aW9uIGVtcHR5KCkge31cblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEpTT05QIFBvbGxpbmcgY29uc3RydWN0b3IuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0cy5cbiAgICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgZnVuY3Rpb24gSlNPTlBQb2xsaW5nKG9wdHMpIHtcbiAgICAgICAgICAgIFBvbGxpbmcuY2FsbCh0aGlzLCBvcHRzKTtcblxuICAgICAgICAgICAgdGhpcy5xdWVyeSA9IHRoaXMucXVlcnkgfHwge307XG5cbiAgICAgICAgICAgIC8vIGRlZmluZSBnbG9iYWwgY2FsbGJhY2tzIGFycmF5IGlmIG5vdCBwcmVzZW50XG4gICAgICAgICAgICAvLyB3ZSBkbyB0aGlzIGhlcmUgKGxhemlseSkgdG8gYXZvaWQgdW5uZWVkZWQgZ2xvYmFsIHBvbGx1dGlvblxuICAgICAgICAgICAgaWYgKCFjYWxsYmFja3MpIHtcbiAgICAgICAgICAgICAgLy8gd2UgbmVlZCB0byBjb25zaWRlciBtdWx0aXBsZSBlbmdpbmVzIGluIHRoZSBzYW1lIHBhZ2VcbiAgICAgICAgICAgICAgaWYgKCFnbG9iYWwuX19fZWlvKSBnbG9iYWwuX19fZWlvID0gW107XG4gICAgICAgICAgICAgIGNhbGxiYWNrcyA9IGdsb2JhbC5fX19laW87XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGNhbGxiYWNrIGlkZW50aWZpZXJcbiAgICAgICAgICAgIHRoaXMuaW5kZXggPSBjYWxsYmFja3MubGVuZ3RoO1xuXG4gICAgICAgICAgICAvLyBhZGQgY2FsbGJhY2sgdG8ganNvbnAgZ2xvYmFsXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgICBjYWxsYmFja3MucHVzaChmdW5jdGlvbiAobXNnKSB7XG4gICAgICAgICAgICAgIHNlbGYub25EYXRhKG1zZyk7XG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgLy8gYXBwZW5kIHRvIHF1ZXJ5IHN0cmluZ1xuICAgICAgICAgICAgdGhpcy5xdWVyeS5qID0gdGhpcy5pbmRleDtcblxuICAgICAgICAgICAgLy8gcHJldmVudCBzcHVyaW91cyBlcnJvcnMgZnJvbSBiZWluZyBlbWl0dGVkIHdoZW4gdGhlIHdpbmRvdyBpcyB1bmxvYWRlZFxuICAgICAgICAgICAgaWYgKGdsb2JhbC5kb2N1bWVudCAmJiBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcikge1xuICAgICAgICAgICAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIGlmIChzZWxmLnNjcmlwdCkgc2VsZi5zY3JpcHQub25lcnJvciA9IGVtcHR5O1xuICAgICAgICAgICAgICB9LCBmYWxzZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogSW5oZXJpdHMgZnJvbSBQb2xsaW5nLlxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgaW5oZXJpdChKU09OUFBvbGxpbmcsIFBvbGxpbmcpO1xuXG4gICAgICAgICAgLypcbiAgICAgICAgICAgKiBKU09OUCBvbmx5IHN1cHBvcnRzIGJpbmFyeSBhcyBiYXNlNjQgZW5jb2RlZCBzdHJpbmdzXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBKU09OUFBvbGxpbmcucHJvdG90eXBlLnN1cHBvcnRzQmluYXJ5ID0gZmFsc2U7XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBDbG9zZXMgdGhlIHNvY2tldC5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgSlNPTlBQb2xsaW5nLnByb3RvdHlwZS5kb0Nsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgaWYgKHRoaXMuc2NyaXB0KSB7XG4gICAgICAgICAgICAgIHRoaXMuc2NyaXB0LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5zY3JpcHQpO1xuICAgICAgICAgICAgICB0aGlzLnNjcmlwdCA9IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmZvcm0pIHtcbiAgICAgICAgICAgICAgdGhpcy5mb3JtLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5mb3JtKTtcbiAgICAgICAgICAgICAgdGhpcy5mb3JtID0gbnVsbDtcbiAgICAgICAgICAgICAgdGhpcy5pZnJhbWUgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBQb2xsaW5nLnByb3RvdHlwZS5kb0Nsb3NlLmNhbGwodGhpcyk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFN0YXJ0cyBhIHBvbGwgY3ljbGUuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIEpTT05QUG9sbGluZy5wcm90b3R5cGUuZG9Qb2xsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICAgICAgdmFyIHNjcmlwdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5zY3JpcHQpIHtcbiAgICAgICAgICAgICAgdGhpcy5zY3JpcHQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLnNjcmlwdCk7XG4gICAgICAgICAgICAgIHRoaXMuc2NyaXB0ID0gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgc2NyaXB0LmFzeW5jID0gdHJ1ZTtcbiAgICAgICAgICAgIHNjcmlwdC5zcmMgPSB0aGlzLnVyaSgpO1xuICAgICAgICAgICAgc2NyaXB0Lm9uZXJyb3IgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICBzZWxmLm9uRXJyb3IoJ2pzb25wIHBvbGwgZXJyb3InLCBlKTtcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgIHZhciBpbnNlcnRBdCA9IGRvY3VtZW50LmdldEVsZW1lbnRzQnlUYWdOYW1lKCdzY3JpcHQnKVswXTtcbiAgICAgICAgICAgIGlmIChpbnNlcnRBdCkge1xuICAgICAgICAgICAgICBpbnNlcnRBdC5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzY3JpcHQsIGluc2VydEF0KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIChkb2N1bWVudC5oZWFkIHx8IGRvY3VtZW50LmJvZHkpLmFwcGVuZENoaWxkKHNjcmlwdCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnNjcmlwdCA9IHNjcmlwdDtcblxuICAgICAgICAgICAgdmFyIGlzVUFnZWNrbyA9ICd1bmRlZmluZWQnICE9IHR5cGVvZiBuYXZpZ2F0b3IgJiYgL2dlY2tvL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcblxuICAgICAgICAgICAgaWYgKGlzVUFnZWNrbykge1xuICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICB2YXIgaWZyYW1lID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnaWZyYW1lJyk7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChpZnJhbWUpO1xuICAgICAgICAgICAgICAgIGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoaWZyYW1lKTtcbiAgICAgICAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogV3JpdGVzIHdpdGggYSBoaWRkZW4gaWZyYW1lLlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGRhdGEgdG8gc2VuZFxuICAgICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxlZCB1cG9uIGZsdXNoLlxuICAgICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgSlNPTlBQb2xsaW5nLnByb3RvdHlwZS5kb1dyaXRlID0gZnVuY3Rpb24gKGRhdGEsIGZuKSB7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgICAgIGlmICghdGhpcy5mb3JtKSB7XG4gICAgICAgICAgICAgIHZhciBmb3JtID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZm9ybScpO1xuICAgICAgICAgICAgICB2YXIgYXJlYSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3RleHRhcmVhJyk7XG4gICAgICAgICAgICAgIHZhciBpZCA9IHRoaXMuaWZyYW1lSWQgPSAnZWlvX2lmcmFtZV8nICsgdGhpcy5pbmRleDtcbiAgICAgICAgICAgICAgdmFyIGlmcmFtZTtcblxuICAgICAgICAgICAgICBmb3JtLmNsYXNzTmFtZSA9ICdzb2NrZXRpbyc7XG4gICAgICAgICAgICAgIGZvcm0uc3R5bGUucG9zaXRpb24gPSAnYWJzb2x1dGUnO1xuICAgICAgICAgICAgICBmb3JtLnN0eWxlLnRvcCA9ICctMTAwMHB4JztcbiAgICAgICAgICAgICAgZm9ybS5zdHlsZS5sZWZ0ID0gJy0xMDAwcHgnO1xuICAgICAgICAgICAgICBmb3JtLnRhcmdldCA9IGlkO1xuICAgICAgICAgICAgICBmb3JtLm1ldGhvZCA9ICdQT1NUJztcbiAgICAgICAgICAgICAgZm9ybS5zZXRBdHRyaWJ1dGUoJ2FjY2VwdC1jaGFyc2V0JywgJ3V0Zi04Jyk7XG4gICAgICAgICAgICAgIGFyZWEubmFtZSA9ICdkJztcbiAgICAgICAgICAgICAgZm9ybS5hcHBlbmRDaGlsZChhcmVhKTtcbiAgICAgICAgICAgICAgZG9jdW1lbnQuYm9keS5hcHBlbmRDaGlsZChmb3JtKTtcblxuICAgICAgICAgICAgICB0aGlzLmZvcm0gPSBmb3JtO1xuICAgICAgICAgICAgICB0aGlzLmFyZWEgPSBhcmVhO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmZvcm0uYWN0aW9uID0gdGhpcy51cmkoKTtcblxuICAgICAgICAgICAgZnVuY3Rpb24gY29tcGxldGUoKSB7XG4gICAgICAgICAgICAgIGluaXRJZnJhbWUoKTtcbiAgICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZnVuY3Rpb24gaW5pdElmcmFtZSgpIHtcbiAgICAgICAgICAgICAgaWYgKHNlbGYuaWZyYW1lKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIHNlbGYuZm9ybS5yZW1vdmVDaGlsZChzZWxmLmlmcmFtZSk7XG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgc2VsZi5vbkVycm9yKCdqc29ucCBwb2xsaW5nIGlmcmFtZSByZW1vdmFsIGVycm9yJywgZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAvLyBpZTYgZHluYW1pYyBpZnJhbWVzIHdpdGggdGFyZ2V0PVwiXCIgc3VwcG9ydCAodGhhbmtzIENocmlzIExhbWJhY2hlcilcbiAgICAgICAgICAgICAgICB2YXIgaHRtbCA9ICc8aWZyYW1lIHNyYz1cImphdmFzY3JpcHQ6MFwiIG5hbWU9XCInICsgc2VsZi5pZnJhbWVJZCArICdcIj4nO1xuICAgICAgICAgICAgICAgIGlmcmFtZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoaHRtbCk7XG4gICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBpZnJhbWUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdpZnJhbWUnKTtcbiAgICAgICAgICAgICAgICBpZnJhbWUubmFtZSA9IHNlbGYuaWZyYW1lSWQ7XG4gICAgICAgICAgICAgICAgaWZyYW1lLnNyYyA9ICdqYXZhc2NyaXB0OjAnO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWZyYW1lLmlkID0gc2VsZi5pZnJhbWVJZDtcblxuICAgICAgICAgICAgICBzZWxmLmZvcm0uYXBwZW5kQ2hpbGQoaWZyYW1lKTtcbiAgICAgICAgICAgICAgc2VsZi5pZnJhbWUgPSBpZnJhbWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGluaXRJZnJhbWUoKTtcblxuICAgICAgICAgICAgLy8gZXNjYXBlIFxcbiB0byBwcmV2ZW50IGl0IGZyb20gYmVpbmcgY29udmVydGVkIGludG8gXFxyXFxuIGJ5IHNvbWUgVUFzXG4gICAgICAgICAgICAvLyBkb3VibGUgZXNjYXBpbmcgaXMgcmVxdWlyZWQgZm9yIGVzY2FwZWQgbmV3IGxpbmVzIGJlY2F1c2UgdW5lc2NhcGluZyBvZiBuZXcgbGluZXMgY2FuIGJlIGRvbmUgc2FmZWx5IG9uIHNlcnZlci1zaWRlXG4gICAgICAgICAgICBkYXRhID0gZGF0YS5yZXBsYWNlKHJFc2NhcGVkTmV3bGluZSwgJ1xcXFxcXG4nKTtcbiAgICAgICAgICAgIHRoaXMuYXJlYS52YWx1ZSA9IGRhdGEucmVwbGFjZShyTmV3bGluZSwgJ1xcXFxuJyk7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIHRoaXMuZm9ybS5zdWJtaXQoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG5cbiAgICAgICAgICAgIGlmICh0aGlzLmlmcmFtZS5hdHRhY2hFdmVudCkge1xuICAgICAgICAgICAgICB0aGlzLmlmcmFtZS5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgaWYgKHNlbGYuaWZyYW1lLnJlYWR5U3RhdGUgPT0gJ2NvbXBsZXRlJykge1xuICAgICAgICAgICAgICAgICAgY29tcGxldGUoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLmlmcmFtZS5vbmxvYWQgPSBjb21wbGV0ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuICAgICAgICB9KS5jYWxsKHRoaXMsIHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDoge30pO1xuICAgICAgfSwgeyBcIi4vcG9sbGluZ1wiOiA4LCBcImNvbXBvbmVudC1pbmhlcml0XCI6IDE2IH1dLCA3OiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuICAgICAgICAoZnVuY3Rpb24gKGdsb2JhbCkge1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIE1vZHVsZSByZXF1aXJlbWVudHMuXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICB2YXIgWE1MSHR0cFJlcXVlc3QgPSBfZGVyZXFfKCd4bWxodHRwcmVxdWVzdC1zc2wnKTtcbiAgICAgICAgICB2YXIgUG9sbGluZyA9IF9kZXJlcV8oJy4vcG9sbGluZycpO1xuICAgICAgICAgIHZhciBFbWl0dGVyID0gX2RlcmVxXygnY29tcG9uZW50LWVtaXR0ZXInKTtcbiAgICAgICAgICB2YXIgaW5oZXJpdCA9IF9kZXJlcV8oJ2NvbXBvbmVudC1pbmhlcml0Jyk7XG4gICAgICAgICAgdmFyIGRlYnVnID0gX2RlcmVxXygnZGVidWcnKSgnZW5naW5lLmlvLWNsaWVudDpwb2xsaW5nLXhocicpO1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogTW9kdWxlIGV4cG9ydHMuXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IFhIUjtcbiAgICAgICAgICBtb2R1bGUuZXhwb3J0cy5SZXF1ZXN0ID0gUmVxdWVzdDtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEVtcHR5IGZ1bmN0aW9uXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBmdW5jdGlvbiBlbXB0eSgpIHt9XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBYSFIgUG9sbGluZyBjb25zdHJ1Y3Rvci5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzXG4gICAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIGZ1bmN0aW9uIFhIUihvcHRzKSB7XG4gICAgICAgICAgICBQb2xsaW5nLmNhbGwodGhpcywgb3B0cyk7XG5cbiAgICAgICAgICAgIGlmIChnbG9iYWwubG9jYXRpb24pIHtcbiAgICAgICAgICAgICAgdmFyIGlzU1NMID0gJ2h0dHBzOicgPT0gbG9jYXRpb24ucHJvdG9jb2w7XG4gICAgICAgICAgICAgIHZhciBwb3J0ID0gbG9jYXRpb24ucG9ydDtcblxuICAgICAgICAgICAgICAvLyBzb21lIHVzZXIgYWdlbnRzIGhhdmUgZW1wdHkgYGxvY2F0aW9uLnBvcnRgXG4gICAgICAgICAgICAgIGlmICghcG9ydCkge1xuICAgICAgICAgICAgICAgIHBvcnQgPSBpc1NTTCA/IDQ0MyA6IDgwO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgdGhpcy54ZCA9IG9wdHMuaG9zdG5hbWUgIT0gZ2xvYmFsLmxvY2F0aW9uLmhvc3RuYW1lIHx8IHBvcnQgIT0gb3B0cy5wb3J0O1xuICAgICAgICAgICAgICB0aGlzLnhzID0gb3B0cy5zZWN1cmUgIT0gaXNTU0w7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICB0aGlzLmV4dHJhSGVhZGVycyA9IG9wdHMuZXh0cmFIZWFkZXJzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEluaGVyaXRzIGZyb20gUG9sbGluZy5cbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIGluaGVyaXQoWEhSLCBQb2xsaW5nKTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFhIUiBzdXBwb3J0cyBiaW5hcnlcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIFhIUi5wcm90b3R5cGUuc3VwcG9ydHNCaW5hcnkgPSB0cnVlO1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogQ3JlYXRlcyBhIHJlcXVlc3QuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gbWV0aG9kXG4gICAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBYSFIucHJvdG90eXBlLnJlcXVlc3QgPSBmdW5jdGlvbiAob3B0cykge1xuICAgICAgICAgICAgb3B0cyA9IG9wdHMgfHwge307XG4gICAgICAgICAgICBvcHRzLnVyaSA9IHRoaXMudXJpKCk7XG4gICAgICAgICAgICBvcHRzLnhkID0gdGhpcy54ZDtcbiAgICAgICAgICAgIG9wdHMueHMgPSB0aGlzLnhzO1xuICAgICAgICAgICAgb3B0cy5hZ2VudCA9IHRoaXMuYWdlbnQgfHwgZmFsc2U7XG4gICAgICAgICAgICBvcHRzLnN1cHBvcnRzQmluYXJ5ID0gdGhpcy5zdXBwb3J0c0JpbmFyeTtcbiAgICAgICAgICAgIG9wdHMuZW5hYmxlc1hEUiA9IHRoaXMuZW5hYmxlc1hEUjtcblxuICAgICAgICAgICAgLy8gU1NMIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gICAgICAgICAgICBvcHRzLnBmeCA9IHRoaXMucGZ4O1xuICAgICAgICAgICAgb3B0cy5rZXkgPSB0aGlzLmtleTtcbiAgICAgICAgICAgIG9wdHMucGFzc3BocmFzZSA9IHRoaXMucGFzc3BocmFzZTtcbiAgICAgICAgICAgIG9wdHMuY2VydCA9IHRoaXMuY2VydDtcbiAgICAgICAgICAgIG9wdHMuY2EgPSB0aGlzLmNhO1xuICAgICAgICAgICAgb3B0cy5jaXBoZXJzID0gdGhpcy5jaXBoZXJzO1xuICAgICAgICAgICAgb3B0cy5yZWplY3RVbmF1dGhvcml6ZWQgPSB0aGlzLnJlamVjdFVuYXV0aG9yaXplZDtcblxuICAgICAgICAgICAgLy8gb3RoZXIgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgICAgICAgICAgIG9wdHMuZXh0cmFIZWFkZXJzID0gdGhpcy5leHRyYUhlYWRlcnM7XG5cbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVxdWVzdChvcHRzKTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogU2VuZHMgZGF0YS5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBkYXRhIHRvIHNlbmQuXG4gICAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGVkIHVwb24gZmx1c2guXG4gICAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBYSFIucHJvdG90eXBlLmRvV3JpdGUgPSBmdW5jdGlvbiAoZGF0YSwgZm4pIHtcbiAgICAgICAgICAgIHZhciBpc0JpbmFyeSA9IHR5cGVvZiBkYXRhICE9PSAnc3RyaW5nJyAmJiBkYXRhICE9PSB1bmRlZmluZWQ7XG4gICAgICAgICAgICB2YXIgcmVxID0gdGhpcy5yZXF1ZXN0KHsgbWV0aG9kOiAnUE9TVCcsIGRhdGE6IGRhdGEsIGlzQmluYXJ5OiBpc0JpbmFyeSB9KTtcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICAgIHJlcS5vbignc3VjY2VzcycsIGZuKTtcbiAgICAgICAgICAgIHJlcS5vbignZXJyb3InLCBmdW5jdGlvbiAoZXJyKSB7XG4gICAgICAgICAgICAgIHNlbGYub25FcnJvcigneGhyIHBvc3QgZXJyb3InLCBlcnIpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB0aGlzLnNlbmRYaHIgPSByZXE7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFN0YXJ0cyBhIHBvbGwgY3ljbGUuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIFhIUi5wcm90b3R5cGUuZG9Qb2xsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgZGVidWcoJ3hociBwb2xsJyk7XG4gICAgICAgICAgICB2YXIgcmVxID0gdGhpcy5yZXF1ZXN0KCk7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgICByZXEub24oJ2RhdGEnLCBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgICBzZWxmLm9uRGF0YShkYXRhKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgcmVxLm9uKCdlcnJvcicsIGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgICAgc2VsZi5vbkVycm9yKCd4aHIgcG9sbCBlcnJvcicsIGVycik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHRoaXMucG9sbFhociA9IHJlcTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogUmVxdWVzdCBjb25zdHJ1Y3RvclxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgZnVuY3Rpb24gUmVxdWVzdChvcHRzKSB7XG4gICAgICAgICAgICB0aGlzLm1ldGhvZCA9IG9wdHMubWV0aG9kIHx8ICdHRVQnO1xuICAgICAgICAgICAgdGhpcy51cmkgPSBvcHRzLnVyaTtcbiAgICAgICAgICAgIHRoaXMueGQgPSAhIW9wdHMueGQ7XG4gICAgICAgICAgICB0aGlzLnhzID0gISFvcHRzLnhzO1xuICAgICAgICAgICAgdGhpcy5hc3luYyA9IGZhbHNlICE9PSBvcHRzLmFzeW5jO1xuICAgICAgICAgICAgdGhpcy5kYXRhID0gdW5kZWZpbmVkICE9IG9wdHMuZGF0YSA/IG9wdHMuZGF0YSA6IG51bGw7XG4gICAgICAgICAgICB0aGlzLmFnZW50ID0gb3B0cy5hZ2VudDtcbiAgICAgICAgICAgIHRoaXMuaXNCaW5hcnkgPSBvcHRzLmlzQmluYXJ5O1xuICAgICAgICAgICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IG9wdHMuc3VwcG9ydHNCaW5hcnk7XG4gICAgICAgICAgICB0aGlzLmVuYWJsZXNYRFIgPSBvcHRzLmVuYWJsZXNYRFI7XG5cbiAgICAgICAgICAgIC8vIFNTTCBvcHRpb25zIGZvciBOb2RlLmpzIGNsaWVudFxuICAgICAgICAgICAgdGhpcy5wZnggPSBvcHRzLnBmeDtcbiAgICAgICAgICAgIHRoaXMua2V5ID0gb3B0cy5rZXk7XG4gICAgICAgICAgICB0aGlzLnBhc3NwaHJhc2UgPSBvcHRzLnBhc3NwaHJhc2U7XG4gICAgICAgICAgICB0aGlzLmNlcnQgPSBvcHRzLmNlcnQ7XG4gICAgICAgICAgICB0aGlzLmNhID0gb3B0cy5jYTtcbiAgICAgICAgICAgIHRoaXMuY2lwaGVycyA9IG9wdHMuY2lwaGVycztcbiAgICAgICAgICAgIHRoaXMucmVqZWN0VW5hdXRob3JpemVkID0gb3B0cy5yZWplY3RVbmF1dGhvcml6ZWQ7XG5cbiAgICAgICAgICAgIC8vIG90aGVyIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gICAgICAgICAgICB0aGlzLmV4dHJhSGVhZGVycyA9IG9wdHMuZXh0cmFIZWFkZXJzO1xuXG4gICAgICAgICAgICB0aGlzLmNyZWF0ZSgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIE1peCBpbiBgRW1pdHRlcmAuXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBFbWl0dGVyKFJlcXVlc3QucHJvdG90eXBlKTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIENyZWF0ZXMgdGhlIFhIUiBvYmplY3QgYW5kIHNlbmRzIHRoZSByZXF1ZXN0LlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBSZXF1ZXN0LnByb3RvdHlwZS5jcmVhdGUgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgb3B0cyA9IHsgYWdlbnQ6IHRoaXMuYWdlbnQsIHhkb21haW46IHRoaXMueGQsIHhzY2hlbWU6IHRoaXMueHMsIGVuYWJsZXNYRFI6IHRoaXMuZW5hYmxlc1hEUiB9O1xuXG4gICAgICAgICAgICAvLyBTU0wgb3B0aW9ucyBmb3IgTm9kZS5qcyBjbGllbnRcbiAgICAgICAgICAgIG9wdHMucGZ4ID0gdGhpcy5wZng7XG4gICAgICAgICAgICBvcHRzLmtleSA9IHRoaXMua2V5O1xuICAgICAgICAgICAgb3B0cy5wYXNzcGhyYXNlID0gdGhpcy5wYXNzcGhyYXNlO1xuICAgICAgICAgICAgb3B0cy5jZXJ0ID0gdGhpcy5jZXJ0O1xuICAgICAgICAgICAgb3B0cy5jYSA9IHRoaXMuY2E7XG4gICAgICAgICAgICBvcHRzLmNpcGhlcnMgPSB0aGlzLmNpcGhlcnM7XG4gICAgICAgICAgICBvcHRzLnJlamVjdFVuYXV0aG9yaXplZCA9IHRoaXMucmVqZWN0VW5hdXRob3JpemVkO1xuXG4gICAgICAgICAgICB2YXIgeGhyID0gdGhpcy54aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3Qob3B0cyk7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGRlYnVnKCd4aHIgb3BlbiAlczogJXMnLCB0aGlzLm1ldGhvZCwgdGhpcy51cmkpO1xuICAgICAgICAgICAgICB4aHIub3Blbih0aGlzLm1ldGhvZCwgdGhpcy51cmksIHRoaXMuYXN5bmMpO1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGlmICh0aGlzLmV4dHJhSGVhZGVycykge1xuICAgICAgICAgICAgICAgICAgeGhyLnNldERpc2FibGVIZWFkZXJDaGVjayh0cnVlKTtcbiAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgaW4gdGhpcy5leHRyYUhlYWRlcnMpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZXh0cmFIZWFkZXJzLmhhc093blByb3BlcnR5KGkpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgeGhyLnNldFJlcXVlc3RIZWFkZXIoaSwgdGhpcy5leHRyYUhlYWRlcnNbaV0pO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICAgICAgICBpZiAodGhpcy5zdXBwb3J0c0JpbmFyeSkge1xuICAgICAgICAgICAgICAgIC8vIFRoaXMgaGFzIHRvIGJlIGRvbmUgYWZ0ZXIgb3BlbiBiZWNhdXNlIEZpcmVmb3ggaXMgc3R1cGlkXG4gICAgICAgICAgICAgICAgLy8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8xMzIxNjkwMy9nZXQtYmluYXJ5LWRhdGEtd2l0aC14bWxodHRwcmVxdWVzdC1pbi1hLWZpcmVmb3gtZXh0ZW5zaW9uXG4gICAgICAgICAgICAgICAgeGhyLnJlc3BvbnNlVHlwZSA9ICdhcnJheWJ1ZmZlcic7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoJ1BPU1QnID09IHRoaXMubWV0aG9kKSB7XG4gICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmlzQmluYXJ5KSB7XG4gICAgICAgICAgICAgICAgICAgIHhoci5zZXRSZXF1ZXN0SGVhZGVyKCdDb250ZW50LXR5cGUnLCAnYXBwbGljYXRpb24vb2N0ZXQtc3RyZWFtJyk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICB4aHIuc2V0UmVxdWVzdEhlYWRlcignQ29udGVudC10eXBlJywgJ3RleHQvcGxhaW47Y2hhcnNldD1VVEYtOCcpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHt9XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBpZTYgY2hlY2tcbiAgICAgICAgICAgICAgaWYgKCd3aXRoQ3JlZGVudGlhbHMnIGluIHhocikge1xuICAgICAgICAgICAgICAgIHhoci53aXRoQ3JlZGVudGlhbHMgPSB0cnVlO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKHRoaXMuaGFzWERSKCkpIHtcbiAgICAgICAgICAgICAgICB4aHIub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgc2VsZi5vbkxvYWQoKTtcbiAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIHhoci5vbmVycm9yID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgICAgc2VsZi5vbkVycm9yKHhoci5yZXNwb25zZVRleHQpO1xuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgIGlmICg0ICE9IHhoci5yZWFkeVN0YXRlKSByZXR1cm47XG4gICAgICAgICAgICAgICAgICBpZiAoMjAwID09IHhoci5zdGF0dXMgfHwgMTIyMyA9PSB4aHIuc3RhdHVzKSB7XG4gICAgICAgICAgICAgICAgICAgIHNlbGYub25Mb2FkKCk7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAvLyBtYWtlIHN1cmUgdGhlIGBlcnJvcmAgZXZlbnQgaGFuZGxlciB0aGF0J3MgdXNlci1zZXRcbiAgICAgICAgICAgICAgICAgICAgLy8gZG9lcyBub3QgdGhyb3cgaW4gdGhlIHNhbWUgdGljayBhbmQgZ2V0cyBjYXVnaHQgaGVyZVxuICAgICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICAgICAgICBzZWxmLm9uRXJyb3IoeGhyLnN0YXR1cyk7XG4gICAgICAgICAgICAgICAgICAgIH0sIDApO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBkZWJ1ZygneGhyIGRhdGEgJXMnLCB0aGlzLmRhdGEpO1xuICAgICAgICAgICAgICB4aHIuc2VuZCh0aGlzLmRhdGEpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAvLyBOZWVkIHRvIGRlZmVyIHNpbmNlIC5jcmVhdGUoKSBpcyBjYWxsZWQgZGlyZWN0bHkgZmhyb20gdGhlIGNvbnN0cnVjdG9yXG4gICAgICAgICAgICAgIC8vIGFuZCB0aHVzIHRoZSAnZXJyb3InIGV2ZW50IGNhbiBvbmx5IGJlIG9ubHkgYm91bmQgKmFmdGVyKiB0aGlzIGV4Y2VwdGlvblxuICAgICAgICAgICAgICAvLyBvY2N1cnMuICBUaGVyZWZvcmUsIGFsc28sIHdlIGNhbm5vdCB0aHJvdyBoZXJlIGF0IGFsbC5cbiAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgc2VsZi5vbkVycm9yKGUpO1xuICAgICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZ2xvYmFsLmRvY3VtZW50KSB7XG4gICAgICAgICAgICAgIHRoaXMuaW5kZXggPSBSZXF1ZXN0LnJlcXVlc3RzQ291bnQrKztcbiAgICAgICAgICAgICAgUmVxdWVzdC5yZXF1ZXN0c1t0aGlzLmluZGV4XSA9IHRoaXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIENhbGxlZCB1cG9uIHN1Y2Nlc3NmdWwgcmVzcG9uc2UuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIFJlcXVlc3QucHJvdG90eXBlLm9uU3VjY2VzcyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgnc3VjY2VzcycpO1xuICAgICAgICAgICAgdGhpcy5jbGVhbnVwKCk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIENhbGxlZCBpZiB3ZSBoYXZlIGRhdGEuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIFJlcXVlc3QucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICB0aGlzLmVtaXQoJ2RhdGEnLCBkYXRhKTtcbiAgICAgICAgICAgIHRoaXMub25TdWNjZXNzKCk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIENhbGxlZCB1cG9uIGVycm9yLlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBSZXF1ZXN0LnByb3RvdHlwZS5vbkVycm9yID0gZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgdGhpcy5lbWl0KCdlcnJvcicsIGVycik7XG4gICAgICAgICAgICB0aGlzLmNsZWFudXAodHJ1ZSk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIENsZWFucyB1cCBob3VzZS5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgUmVxdWVzdC5wcm90b3R5cGUuY2xlYW51cCA9IGZ1bmN0aW9uIChmcm9tRXJyb3IpIHtcbiAgICAgICAgICAgIGlmICgndW5kZWZpbmVkJyA9PSB0eXBlb2YgdGhpcy54aHIgfHwgbnVsbCA9PT0gdGhpcy54aHIpIHtcbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLy8geG1saHR0cHJlcXVlc3RcbiAgICAgICAgICAgIGlmICh0aGlzLmhhc1hEUigpKSB7XG4gICAgICAgICAgICAgIHRoaXMueGhyLm9ubG9hZCA9IHRoaXMueGhyLm9uZXJyb3IgPSBlbXB0eTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHRoaXMueGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGVtcHR5O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoZnJvbUVycm9yKSB7XG4gICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgdGhpcy54aHIuYWJvcnQoKTtcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGdsb2JhbC5kb2N1bWVudCkge1xuICAgICAgICAgICAgICBkZWxldGUgUmVxdWVzdC5yZXF1ZXN0c1t0aGlzLmluZGV4XTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy54aHIgPSBudWxsO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBDYWxsZWQgdXBvbiBsb2FkLlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBSZXF1ZXN0LnByb3RvdHlwZS5vbkxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB2YXIgZGF0YTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIHZhciBjb250ZW50VHlwZTtcbiAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBjb250ZW50VHlwZSA9IHRoaXMueGhyLmdldFJlc3BvbnNlSGVhZGVyKCdDb250ZW50LVR5cGUnKS5zcGxpdCgnOycpWzBdO1xuICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICAgICAgICBpZiAoY29udGVudFR5cGUgPT09ICdhcHBsaWNhdGlvbi9vY3RldC1zdHJlYW0nKSB7XG4gICAgICAgICAgICAgICAgZGF0YSA9IHRoaXMueGhyLnJlc3BvbnNlO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGlmICghdGhpcy5zdXBwb3J0c0JpbmFyeSkge1xuICAgICAgICAgICAgICAgICAgZGF0YSA9IHRoaXMueGhyLnJlc3BvbnNlVGV4dDtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgbmV3IFVpbnQ4QXJyYXkodGhpcy54aHIucmVzcG9uc2UpKTtcbiAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHVpOEFyciA9IG5ldyBVaW50OEFycmF5KHRoaXMueGhyLnJlc3BvbnNlKTtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGRhdGFBcnJheSA9IFtdO1xuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpZHggPSAwLCBsZW5ndGggPSB1aThBcnIubGVuZ3RoOyBpZHggPCBsZW5ndGg7IGlkeCsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgZGF0YUFycmF5LnB1c2godWk4QXJyW2lkeF0pO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgZGF0YSA9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgZGF0YUFycmF5KTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgdGhpcy5vbkVycm9yKGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKG51bGwgIT0gZGF0YSkge1xuICAgICAgICAgICAgICB0aGlzLm9uRGF0YShkYXRhKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogQ2hlY2sgaWYgaXQgaGFzIFhEb21haW5SZXF1ZXN0LlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBSZXF1ZXN0LnByb3RvdHlwZS5oYXNYRFIgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICByZXR1cm4gJ3VuZGVmaW5lZCcgIT09IHR5cGVvZiBnbG9iYWwuWERvbWFpblJlcXVlc3QgJiYgIXRoaXMueHMgJiYgdGhpcy5lbmFibGVzWERSO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBBYm9ydHMgdGhlIHJlcXVlc3QuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgUmVxdWVzdC5wcm90b3R5cGUuYWJvcnQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0aGlzLmNsZWFudXAoKTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogQWJvcnRzIHBlbmRpbmcgcmVxdWVzdHMgd2hlbiB1bmxvYWRpbmcgdGhlIHdpbmRvdy4gVGhpcyBpcyBuZWVkZWQgdG8gcHJldmVudFxuICAgICAgICAgICAqIG1lbW9yeSBsZWFrcyAoZS5nLiB3aGVuIHVzaW5nIElFKSBhbmQgdG8gZW5zdXJlIHRoYXQgbm8gc3B1cmlvdXMgZXJyb3IgaXNcbiAgICAgICAgICAgKiBlbWl0dGVkLlxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgaWYgKGdsb2JhbC5kb2N1bWVudCkge1xuICAgICAgICAgICAgUmVxdWVzdC5yZXF1ZXN0c0NvdW50ID0gMDtcbiAgICAgICAgICAgIFJlcXVlc3QucmVxdWVzdHMgPSB7fTtcbiAgICAgICAgICAgIGlmIChnbG9iYWwuYXR0YWNoRXZlbnQpIHtcbiAgICAgICAgICAgICAgZ2xvYmFsLmF0dGFjaEV2ZW50KCdvbnVubG9hZCcsIHVubG9hZEhhbmRsZXIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcikge1xuICAgICAgICAgICAgICBnbG9iYWwuYWRkRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgdW5sb2FkSGFuZGxlciwgZmFsc2UpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGZ1bmN0aW9uIHVubG9hZEhhbmRsZXIoKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpIGluIFJlcXVlc3QucmVxdWVzdHMpIHtcbiAgICAgICAgICAgICAgaWYgKFJlcXVlc3QucmVxdWVzdHMuaGFzT3duUHJvcGVydHkoaSkpIHtcbiAgICAgICAgICAgICAgICBSZXF1ZXN0LnJlcXVlc3RzW2ldLmFib3J0KCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH0pLmNhbGwodGhpcywgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB7fSk7XG4gICAgICB9LCB7IFwiLi9wb2xsaW5nXCI6IDgsIFwiY29tcG9uZW50LWVtaXR0ZXJcIjogMTUsIFwiY29tcG9uZW50LWluaGVyaXRcIjogMTYsIFwiZGVidWdcIjogMTcsIFwieG1saHR0cHJlcXVlc3Qtc3NsXCI6IDEwIH1dLCA4OiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuICAgICAgICAvKipcbiAgICAgICAgICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAgICAgICAgICovXG5cbiAgICAgICAgdmFyIFRyYW5zcG9ydCA9IF9kZXJlcV8oJy4uL3RyYW5zcG9ydCcpO1xuICAgICAgICB2YXIgcGFyc2VxcyA9IF9kZXJlcV8oJ3BhcnNlcXMnKTtcbiAgICAgICAgdmFyIHBhcnNlciA9IF9kZXJlcV8oJ2VuZ2luZS5pby1wYXJzZXInKTtcbiAgICAgICAgdmFyIGluaGVyaXQgPSBfZGVyZXFfKCdjb21wb25lbnQtaW5oZXJpdCcpO1xuICAgICAgICB2YXIgeWVhc3QgPSBfZGVyZXFfKCd5ZWFzdCcpO1xuICAgICAgICB2YXIgZGVidWcgPSBfZGVyZXFfKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OnBvbGxpbmcnKTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTW9kdWxlIGV4cG9ydHMuXG4gICAgICAgICAqL1xuXG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gUG9sbGluZztcblxuICAgICAgICAvKipcbiAgICAgICAgICogSXMgWEhSMiBzdXBwb3J0ZWQ/XG4gICAgICAgICAqL1xuXG4gICAgICAgIHZhciBoYXNYSFIyID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciBYTUxIdHRwUmVxdWVzdCA9IF9kZXJlcV8oJ3htbGh0dHByZXF1ZXN0LXNzbCcpO1xuICAgICAgICAgIHZhciB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QoeyB4ZG9tYWluOiBmYWxzZSB9KTtcbiAgICAgICAgICByZXR1cm4gbnVsbCAhPSB4aHIucmVzcG9uc2VUeXBlO1xuICAgICAgICB9KCk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFBvbGxpbmcgaW50ZXJmYWNlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0c1xuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgZnVuY3Rpb24gUG9sbGluZyhvcHRzKSB7XG4gICAgICAgICAgdmFyIGZvcmNlQmFzZTY0ID0gb3B0cyAmJiBvcHRzLmZvcmNlQmFzZTY0O1xuICAgICAgICAgIGlmICghaGFzWEhSMiB8fCBmb3JjZUJhc2U2NCkge1xuICAgICAgICAgICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IGZhbHNlO1xuICAgICAgICAgIH1cbiAgICAgICAgICBUcmFuc3BvcnQuY2FsbCh0aGlzLCBvcHRzKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbmhlcml0cyBmcm9tIFRyYW5zcG9ydC5cbiAgICAgICAgICovXG5cbiAgICAgICAgaW5oZXJpdChQb2xsaW5nLCBUcmFuc3BvcnQpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUcmFuc3BvcnQgbmFtZS5cbiAgICAgICAgICovXG5cbiAgICAgICAgUG9sbGluZy5wcm90b3R5cGUubmFtZSA9ICdwb2xsaW5nJztcblxuICAgICAgICAvKipcbiAgICAgICAgICogT3BlbnMgdGhlIHNvY2tldCAodHJpZ2dlcnMgcG9sbGluZykuIFdlIHdyaXRlIGEgUElORyBtZXNzYWdlIHRvIGRldGVybWluZVxuICAgICAgICAgKiB3aGVuIHRoZSB0cmFuc3BvcnQgaXMgb3Blbi5cbiAgICAgICAgICpcbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIFBvbGxpbmcucHJvdG90eXBlLmRvT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB0aGlzLnBvbGwoKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUGF1c2VzIHBvbGxpbmcuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIHVwb24gYnVmZmVycyBhcmUgZmx1c2hlZCBhbmQgdHJhbnNwb3J0IGlzIHBhdXNlZFxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgUG9sbGluZy5wcm90b3R5cGUucGF1c2UgPSBmdW5jdGlvbiAob25QYXVzZSkge1xuICAgICAgICAgIHZhciBwZW5kaW5nID0gMDtcbiAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSAncGF1c2luZyc7XG5cbiAgICAgICAgICBmdW5jdGlvbiBwYXVzZSgpIHtcbiAgICAgICAgICAgIGRlYnVnKCdwYXVzZWQnKTtcbiAgICAgICAgICAgIHNlbGYucmVhZHlTdGF0ZSA9ICdwYXVzZWQnO1xuICAgICAgICAgICAgb25QYXVzZSgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0aGlzLnBvbGxpbmcgfHwgIXRoaXMud3JpdGFibGUpIHtcbiAgICAgICAgICAgIHZhciB0b3RhbCA9IDA7XG5cbiAgICAgICAgICAgIGlmICh0aGlzLnBvbGxpbmcpIHtcbiAgICAgICAgICAgICAgZGVidWcoJ3dlIGFyZSBjdXJyZW50bHkgcG9sbGluZyAtIHdhaXRpbmcgdG8gcGF1c2UnKTtcbiAgICAgICAgICAgICAgdG90YWwrKztcbiAgICAgICAgICAgICAgdGhpcy5vbmNlKCdwb2xsQ29tcGxldGUnLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZGVidWcoJ3ByZS1wYXVzZSBwb2xsaW5nIGNvbXBsZXRlJyk7XG4gICAgICAgICAgICAgICAgLS10b3RhbCB8fCBwYXVzZSgpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCF0aGlzLndyaXRhYmxlKSB7XG4gICAgICAgICAgICAgIGRlYnVnKCd3ZSBhcmUgY3VycmVudGx5IHdyaXRpbmcgLSB3YWl0aW5nIHRvIHBhdXNlJyk7XG4gICAgICAgICAgICAgIHRvdGFsKys7XG4gICAgICAgICAgICAgIHRoaXMub25jZSgnZHJhaW4nLCBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgZGVidWcoJ3ByZS1wYXVzZSB3cml0aW5nIGNvbXBsZXRlJyk7XG4gICAgICAgICAgICAgICAgLS10b3RhbCB8fCBwYXVzZSgpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGF1c2UoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFN0YXJ0cyBwb2xsaW5nIGN5Y2xlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBQb2xsaW5nLnByb3RvdHlwZS5wb2xsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGRlYnVnKCdwb2xsaW5nJyk7XG4gICAgICAgICAgdGhpcy5wb2xsaW5nID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLmRvUG9sbCgpO1xuICAgICAgICAgIHRoaXMuZW1pdCgncG9sbCcpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBPdmVybG9hZHMgb25EYXRhIHRvIGRldGVjdCBwYXlsb2Fkcy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIFBvbGxpbmcucHJvdG90eXBlLm9uRGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICAgIGRlYnVnKCdwb2xsaW5nIGdvdCBkYXRhICVzJywgZGF0YSk7XG4gICAgICAgICAgdmFyIGNhbGxiYWNrID0gZnVuY3Rpb24gY2FsbGJhY2socGFja2V0LCBpbmRleCwgdG90YWwpIHtcbiAgICAgICAgICAgIC8vIGlmIGl0cyB0aGUgZmlyc3QgbWVzc2FnZSB3ZSBjb25zaWRlciB0aGUgdHJhbnNwb3J0IG9wZW5cbiAgICAgICAgICAgIGlmICgnb3BlbmluZycgPT0gc2VsZi5yZWFkeVN0YXRlKSB7XG4gICAgICAgICAgICAgIHNlbGYub25PcGVuKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIGlmIGl0cyBhIGNsb3NlIHBhY2tldCwgd2UgY2xvc2UgdGhlIG9uZ29pbmcgcmVxdWVzdHNcbiAgICAgICAgICAgIGlmICgnY2xvc2UnID09IHBhY2tldC50eXBlKSB7XG4gICAgICAgICAgICAgIHNlbGYub25DbG9zZSgpO1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIG90aGVyd2lzZSBieXBhc3Mgb25EYXRhIGFuZCBoYW5kbGUgdGhlIG1lc3NhZ2VcbiAgICAgICAgICAgIHNlbGYub25QYWNrZXQocGFja2V0KTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLy8gZGVjb2RlIHBheWxvYWRcbiAgICAgICAgICBwYXJzZXIuZGVjb2RlUGF5bG9hZChkYXRhLCB0aGlzLnNvY2tldC5iaW5hcnlUeXBlLCBjYWxsYmFjayk7XG5cbiAgICAgICAgICAvLyBpZiBhbiBldmVudCBkaWQgbm90IHRyaWdnZXIgY2xvc2luZ1xuICAgICAgICAgIGlmICgnY2xvc2VkJyAhPSB0aGlzLnJlYWR5U3RhdGUpIHtcbiAgICAgICAgICAgIC8vIGlmIHdlIGdvdCBkYXRhIHdlJ3JlIG5vdCBwb2xsaW5nXG4gICAgICAgICAgICB0aGlzLnBvbGxpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIHRoaXMuZW1pdCgncG9sbENvbXBsZXRlJyk7XG5cbiAgICAgICAgICAgIGlmICgnb3BlbicgPT0gdGhpcy5yZWFkeVN0YXRlKSB7XG4gICAgICAgICAgICAgIHRoaXMucG9sbCgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgZGVidWcoJ2lnbm9yaW5nIHBvbGwgLSB0cmFuc3BvcnQgc3RhdGUgXCIlc1wiJywgdGhpcy5yZWFkeVN0YXRlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEZvciBwb2xsaW5nLCBzZW5kIGEgY2xvc2UgcGFja2V0LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgUG9sbGluZy5wcm90b3R5cGUuZG9DbG9zZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG5cbiAgICAgICAgICBmdW5jdGlvbiBjbG9zZSgpIHtcbiAgICAgICAgICAgIGRlYnVnKCd3cml0aW5nIGNsb3NlIHBhY2tldCcpO1xuICAgICAgICAgICAgc2VsZi53cml0ZShbeyB0eXBlOiAnY2xvc2UnIH1dKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoJ29wZW4nID09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgICAgICAgICAgZGVidWcoJ3RyYW5zcG9ydCBvcGVuIC0gY2xvc2luZycpO1xuICAgICAgICAgICAgY2xvc2UoKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgLy8gaW4gY2FzZSB3ZSdyZSB0cnlpbmcgdG8gY2xvc2Ugd2hpbGVcbiAgICAgICAgICAgIC8vIGhhbmRzaGFraW5nIGlzIGluIHByb2dyZXNzIChHSC0xNjQpXG4gICAgICAgICAgICBkZWJ1ZygndHJhbnNwb3J0IG5vdCBvcGVuIC0gZGVmZXJyaW5nIGNsb3NlJyk7XG4gICAgICAgICAgICB0aGlzLm9uY2UoJ29wZW4nLCBjbG9zZSk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXcml0ZXMgYSBwYWNrZXRzIHBheWxvYWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IGRhdGEgcGFja2V0c1xuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkcmFpbiBjYWxsYmFja1xuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgUG9sbGluZy5wcm90b3R5cGUud3JpdGUgPSBmdW5jdGlvbiAocGFja2V0cykge1xuICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICB0aGlzLndyaXRhYmxlID0gZmFsc2U7XG4gICAgICAgICAgdmFyIGNhbGxiYWNrZm4gPSBmdW5jdGlvbiBjYWxsYmFja2ZuKCkge1xuICAgICAgICAgICAgc2VsZi53cml0YWJsZSA9IHRydWU7XG4gICAgICAgICAgICBzZWxmLmVtaXQoJ2RyYWluJyk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICBwYXJzZXIuZW5jb2RlUGF5bG9hZChwYWNrZXRzLCB0aGlzLnN1cHBvcnRzQmluYXJ5LCBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgc2VsZi5kb1dyaXRlKGRhdGEsIGNhbGxiYWNrZm4pO1xuICAgICAgICAgIH0pO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZW5lcmF0ZXMgdXJpIGZvciBjb25uZWN0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgUG9sbGluZy5wcm90b3R5cGUudXJpID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciBxdWVyeSA9IHRoaXMucXVlcnkgfHwge307XG4gICAgICAgICAgdmFyIHNjaGVtYSA9IHRoaXMuc2VjdXJlID8gJ2h0dHBzJyA6ICdodHRwJztcbiAgICAgICAgICB2YXIgcG9ydCA9ICcnO1xuXG4gICAgICAgICAgLy8gY2FjaGUgYnVzdGluZyBpcyBmb3JjZWRcbiAgICAgICAgICBpZiAoZmFsc2UgIT09IHRoaXMudGltZXN0YW1wUmVxdWVzdHMpIHtcbiAgICAgICAgICAgIHF1ZXJ5W3RoaXMudGltZXN0YW1wUGFyYW1dID0geWVhc3QoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoIXRoaXMuc3VwcG9ydHNCaW5hcnkgJiYgIXF1ZXJ5LnNpZCkge1xuICAgICAgICAgICAgcXVlcnkuYjY0ID0gMTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBxdWVyeSA9IHBhcnNlcXMuZW5jb2RlKHF1ZXJ5KTtcblxuICAgICAgICAgIC8vIGF2b2lkIHBvcnQgaWYgZGVmYXVsdCBmb3Igc2NoZW1hXG4gICAgICAgICAgaWYgKHRoaXMucG9ydCAmJiAoJ2h0dHBzJyA9PSBzY2hlbWEgJiYgdGhpcy5wb3J0ICE9IDQ0MyB8fCAnaHR0cCcgPT0gc2NoZW1hICYmIHRoaXMucG9ydCAhPSA4MCkpIHtcbiAgICAgICAgICAgIHBvcnQgPSAnOicgKyB0aGlzLnBvcnQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gcHJlcGVuZCA/IHRvIHF1ZXJ5XG4gICAgICAgICAgaWYgKHF1ZXJ5Lmxlbmd0aCkge1xuICAgICAgICAgICAgcXVlcnkgPSAnPycgKyBxdWVyeTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgaXB2NiA9IHRoaXMuaG9zdG5hbWUuaW5kZXhPZignOicpICE9PSAtMTtcbiAgICAgICAgICByZXR1cm4gc2NoZW1hICsgJzovLycgKyAoaXB2NiA/ICdbJyArIHRoaXMuaG9zdG5hbWUgKyAnXScgOiB0aGlzLmhvc3RuYW1lKSArIHBvcnQgKyB0aGlzLnBhdGggKyBxdWVyeTtcbiAgICAgICAgfTtcbiAgICAgIH0sIHsgXCIuLi90cmFuc3BvcnRcIjogNCwgXCJjb21wb25lbnQtaW5oZXJpdFwiOiAxNiwgXCJkZWJ1Z1wiOiAxNywgXCJlbmdpbmUuaW8tcGFyc2VyXCI6IDE5LCBcInBhcnNlcXNcIjogMjcsIFwieG1saHR0cHJlcXVlc3Qtc3NsXCI6IDEwLCBcInllYXN0XCI6IDMwIH1dLCA5OiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuICAgICAgICAoZnVuY3Rpb24gKGdsb2JhbCkge1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICB2YXIgVHJhbnNwb3J0ID0gX2RlcmVxXygnLi4vdHJhbnNwb3J0Jyk7XG4gICAgICAgICAgdmFyIHBhcnNlciA9IF9kZXJlcV8oJ2VuZ2luZS5pby1wYXJzZXInKTtcbiAgICAgICAgICB2YXIgcGFyc2VxcyA9IF9kZXJlcV8oJ3BhcnNlcXMnKTtcbiAgICAgICAgICB2YXIgaW5oZXJpdCA9IF9kZXJlcV8oJ2NvbXBvbmVudC1pbmhlcml0Jyk7XG4gICAgICAgICAgdmFyIHllYXN0ID0gX2RlcmVxXygneWVhc3QnKTtcbiAgICAgICAgICB2YXIgZGVidWcgPSBfZGVyZXFfKCdkZWJ1ZycpKCdlbmdpbmUuaW8tY2xpZW50OndlYnNvY2tldCcpO1xuICAgICAgICAgIHZhciBCcm93c2VyV2ViU29ja2V0ID0gZ2xvYmFsLldlYlNvY2tldCB8fCBnbG9iYWwuTW96V2ViU29ja2V0O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogR2V0IGVpdGhlciB0aGUgYFdlYlNvY2tldGAgb3IgYE1veldlYlNvY2tldGAgZ2xvYmFsc1xuICAgICAgICAgICAqIGluIHRoZSBicm93c2VyIG9yIHRoZSBXZWJTb2NrZXQtY29tcGF0aWJsZSBpbnRlcmZhY2VcbiAgICAgICAgICAgKiBleHBvc2VkIGJ5IGB3c2AgZm9yIE5vZGUgZW52aXJvbm1lbnQuXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICB2YXIgV2ViU29ja2V0ID0gQnJvd3NlcldlYlNvY2tldCB8fCAodHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyBudWxsIDogX2RlcmVxXygnd3MnKSk7XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBNb2R1bGUgZXhwb3J0cy5cbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gV1M7XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBXZWJTb2NrZXQgdHJhbnNwb3J0IGNvbnN0cnVjdG9yLlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQGFwaSB7T2JqZWN0fSBjb25uZWN0aW9uIG9wdGlvbnNcbiAgICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgZnVuY3Rpb24gV1Mob3B0cykge1xuICAgICAgICAgICAgdmFyIGZvcmNlQmFzZTY0ID0gb3B0cyAmJiBvcHRzLmZvcmNlQmFzZTY0O1xuICAgICAgICAgICAgaWYgKGZvcmNlQmFzZTY0KSB7XG4gICAgICAgICAgICAgIHRoaXMuc3VwcG9ydHNCaW5hcnkgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMucGVyTWVzc2FnZURlZmxhdGUgPSBvcHRzLnBlck1lc3NhZ2VEZWZsYXRlO1xuICAgICAgICAgICAgVHJhbnNwb3J0LmNhbGwodGhpcywgb3B0cyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogSW5oZXJpdHMgZnJvbSBUcmFuc3BvcnQuXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBpbmhlcml0KFdTLCBUcmFuc3BvcnQpO1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogVHJhbnNwb3J0IG5hbWUuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgV1MucHJvdG90eXBlLm5hbWUgPSAnd2Vic29ja2V0JztcblxuICAgICAgICAgIC8qXG4gICAgICAgICAgICogV2ViU29ja2V0cyBzdXBwb3J0IGJpbmFyeVxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgV1MucHJvdG90eXBlLnN1cHBvcnRzQmluYXJ5ID0gdHJ1ZTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIE9wZW5zIHNvY2tldC5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgV1MucHJvdG90eXBlLmRvT3BlbiA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIGlmICghdGhpcy5jaGVjaygpKSB7XG4gICAgICAgICAgICAgIC8vIGxldCBwcm9iZSB0aW1lb3V0XG4gICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICAgICAgdmFyIHVyaSA9IHRoaXMudXJpKCk7XG4gICAgICAgICAgICB2YXIgcHJvdG9jb2xzID0gdm9pZCAwO1xuICAgICAgICAgICAgdmFyIG9wdHMgPSB7XG4gICAgICAgICAgICAgIGFnZW50OiB0aGlzLmFnZW50LFxuICAgICAgICAgICAgICBwZXJNZXNzYWdlRGVmbGF0ZTogdGhpcy5wZXJNZXNzYWdlRGVmbGF0ZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gU1NMIG9wdGlvbnMgZm9yIE5vZGUuanMgY2xpZW50XG4gICAgICAgICAgICBvcHRzLnBmeCA9IHRoaXMucGZ4O1xuICAgICAgICAgICAgb3B0cy5rZXkgPSB0aGlzLmtleTtcbiAgICAgICAgICAgIG9wdHMucGFzc3BocmFzZSA9IHRoaXMucGFzc3BocmFzZTtcbiAgICAgICAgICAgIG9wdHMuY2VydCA9IHRoaXMuY2VydDtcbiAgICAgICAgICAgIG9wdHMuY2EgPSB0aGlzLmNhO1xuICAgICAgICAgICAgb3B0cy5jaXBoZXJzID0gdGhpcy5jaXBoZXJzO1xuICAgICAgICAgICAgb3B0cy5yZWplY3RVbmF1dGhvcml6ZWQgPSB0aGlzLnJlamVjdFVuYXV0aG9yaXplZDtcbiAgICAgICAgICAgIGlmICh0aGlzLmV4dHJhSGVhZGVycykge1xuICAgICAgICAgICAgICBvcHRzLmhlYWRlcnMgPSB0aGlzLmV4dHJhSGVhZGVycztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy53cyA9IEJyb3dzZXJXZWJTb2NrZXQgPyBuZXcgV2ViU29ja2V0KHVyaSkgOiBuZXcgV2ViU29ja2V0KHVyaSwgcHJvdG9jb2xzLCBvcHRzKTtcblxuICAgICAgICAgICAgaWYgKHRoaXMud3MuYmluYXJ5VHlwZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIHRoaXMuc3VwcG9ydHNCaW5hcnkgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHRoaXMud3Muc3VwcG9ydHMgJiYgdGhpcy53cy5zdXBwb3J0cy5iaW5hcnkpIHtcbiAgICAgICAgICAgICAgdGhpcy5zdXBwb3J0c0JpbmFyeSA9IHRydWU7XG4gICAgICAgICAgICAgIHRoaXMud3MuYmluYXJ5VHlwZSA9ICdidWZmZXInO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgdGhpcy53cy5iaW5hcnlUeXBlID0gJ2FycmF5YnVmZmVyJztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdGhpcy5hZGRFdmVudExpc3RlbmVycygpO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBBZGRzIGV2ZW50IGxpc3RlbmVycyB0byB0aGUgc29ja2V0XG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIFdTLnByb3RvdHlwZS5hZGRFdmVudExpc3RlbmVycyA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgICAgICAgICAgdGhpcy53cy5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgIHNlbGYub25PcGVuKCk7XG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgdGhpcy53cy5vbmNsb3NlID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBzZWxmLm9uQ2xvc2UoKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLndzLm9ubWVzc2FnZSA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICAgICAgICBzZWxmLm9uRGF0YShldi5kYXRhKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgICB0aGlzLndzLm9uZXJyb3IgPSBmdW5jdGlvbiAoZSkge1xuICAgICAgICAgICAgICBzZWxmLm9uRXJyb3IoJ3dlYnNvY2tldCBlcnJvcicsIGUpO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogT3ZlcnJpZGUgYG9uRGF0YWAgdG8gdXNlIGEgdGltZXIgb24gaU9TLlxuICAgICAgICAgICAqIFNlZTogaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vbWxvdWdocmFuLzIwNTIwMDZcbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgaWYgKCd1bmRlZmluZWQnICE9IHR5cGVvZiBuYXZpZ2F0b3IgJiYgL2lQYWR8aVBob25lfGlQb2QvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpKSB7XG4gICAgICAgICAgICBXUy5wcm90b3R5cGUub25EYXRhID0gZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgICBUcmFuc3BvcnQucHJvdG90eXBlLm9uRGF0YS5jYWxsKHNlbGYsIGRhdGEpO1xuICAgICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgICAgIH07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogV3JpdGVzIGRhdGEgdG8gc29ja2V0LlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQHBhcmFtIHtBcnJheX0gYXJyYXkgb2YgcGFja2V0cy5cbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIFdTLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChwYWNrZXRzKSB7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgICB0aGlzLndyaXRhYmxlID0gZmFsc2U7XG5cbiAgICAgICAgICAgIC8vIGVuY29kZVBhY2tldCBlZmZpY2llbnQgYXMgaXQgdXNlcyBXUyBmcmFtaW5nXG4gICAgICAgICAgICAvLyBubyBuZWVkIGZvciBlbmNvZGVQYXlsb2FkXG4gICAgICAgICAgICB2YXIgdG90YWwgPSBwYWNrZXRzLmxlbmd0aDtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gdG90YWw7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgICAgKGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgICAgICAgICAgICAgICBwYXJzZXIuZW5jb2RlUGFja2V0KHBhY2tldCwgc2VsZi5zdXBwb3J0c0JpbmFyeSwgZnVuY3Rpb24gKGRhdGEpIHtcbiAgICAgICAgICAgICAgICAgIGlmICghQnJvd3NlcldlYlNvY2tldCkge1xuICAgICAgICAgICAgICAgICAgICAvLyBhbHdheXMgY3JlYXRlIGEgbmV3IG9iamVjdCAoR0gtNDM3KVxuICAgICAgICAgICAgICAgICAgICB2YXIgb3B0cyA9IHt9O1xuICAgICAgICAgICAgICAgICAgICBpZiAocGFja2V0Lm9wdGlvbnMpIHtcbiAgICAgICAgICAgICAgICAgICAgICBvcHRzLmNvbXByZXNzID0gcGFja2V0Lm9wdGlvbnMuY29tcHJlc3M7XG4gICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZi5wZXJNZXNzYWdlRGVmbGF0ZSkge1xuICAgICAgICAgICAgICAgICAgICAgIHZhciBsZW4gPSAnc3RyaW5nJyA9PSB0eXBlb2YgZGF0YSA/IGdsb2JhbC5CdWZmZXIuYnl0ZUxlbmd0aChkYXRhKSA6IGRhdGEubGVuZ3RoO1xuICAgICAgICAgICAgICAgICAgICAgIGlmIChsZW4gPCBzZWxmLnBlck1lc3NhZ2VEZWZsYXRlLnRocmVzaG9sZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgb3B0cy5jb21wcmVzcyA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAvL1NvbWV0aW1lcyB0aGUgd2Vic29ja2V0IGhhcyBhbHJlYWR5IGJlZW4gY2xvc2VkIGJ1dCB0aGUgYnJvd3NlciBkaWRuJ3RcbiAgICAgICAgICAgICAgICAgIC8vaGF2ZSBhIGNoYW5jZSBvZiBpbmZvcm1pbmcgdXMgYWJvdXQgaXQgeWV0LCBpbiB0aGF0IGNhc2Ugc2VuZCB3aWxsXG4gICAgICAgICAgICAgICAgICAvL3Rocm93IGFuIGVycm9yXG4gICAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoQnJvd3NlcldlYlNvY2tldCkge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIFR5cGVFcnJvciBpcyB0aHJvd24gd2hlbiBwYXNzaW5nIHRoZSBzZWNvbmQgYXJndW1lbnQgb24gU2FmYXJpXG4gICAgICAgICAgICAgICAgICAgICAgc2VsZi53cy5zZW5kKGRhdGEpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgIHNlbGYud3Muc2VuZChkYXRhLCBvcHRzKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgICAgICBkZWJ1Zygnd2Vic29ja2V0IGNsb3NlZCBiZWZvcmUgb25jbG9zZSBldmVudCcpO1xuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAtLXRvdGFsIHx8IGRvbmUoKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgfSkocGFja2V0c1tpXSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIGRvbmUoKSB7XG4gICAgICAgICAgICAgIHNlbGYuZW1pdCgnZmx1c2gnKTtcblxuICAgICAgICAgICAgICAvLyBmYWtlIGRyYWluXG4gICAgICAgICAgICAgIC8vIGRlZmVyIHRvIG5leHQgdGljayB0byBhbGxvdyBTb2NrZXQgdG8gY2xlYXIgd3JpdGVCdWZmZXJcbiAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgc2VsZi53cml0YWJsZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgc2VsZi5lbWl0KCdkcmFpbicpO1xuICAgICAgICAgICAgICB9LCAwKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogQ2FsbGVkIHVwb24gY2xvc2VcbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgV1MucHJvdG90eXBlLm9uQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBUcmFuc3BvcnQucHJvdG90eXBlLm9uQ2xvc2UuY2FsbCh0aGlzKTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogQ2xvc2VzIHNvY2tldC5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgV1MucHJvdG90eXBlLmRvQ2xvc2UgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIHRoaXMud3MgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICAgIHRoaXMud3MuY2xvc2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogR2VuZXJhdGVzIHVyaSBmb3IgY29ubmVjdGlvbi5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgV1MucHJvdG90eXBlLnVyaSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHZhciBxdWVyeSA9IHRoaXMucXVlcnkgfHwge307XG4gICAgICAgICAgICB2YXIgc2NoZW1hID0gdGhpcy5zZWN1cmUgPyAnd3NzJyA6ICd3cyc7XG4gICAgICAgICAgICB2YXIgcG9ydCA9ICcnO1xuXG4gICAgICAgICAgICAvLyBhdm9pZCBwb3J0IGlmIGRlZmF1bHQgZm9yIHNjaGVtYVxuICAgICAgICAgICAgaWYgKHRoaXMucG9ydCAmJiAoJ3dzcycgPT0gc2NoZW1hICYmIHRoaXMucG9ydCAhPSA0NDMgfHwgJ3dzJyA9PSBzY2hlbWEgJiYgdGhpcy5wb3J0ICE9IDgwKSkge1xuICAgICAgICAgICAgICBwb3J0ID0gJzonICsgdGhpcy5wb3J0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBhcHBlbmQgdGltZXN0YW1wIHRvIFVSSVxuICAgICAgICAgICAgaWYgKHRoaXMudGltZXN0YW1wUmVxdWVzdHMpIHtcbiAgICAgICAgICAgICAgcXVlcnlbdGhpcy50aW1lc3RhbXBQYXJhbV0gPSB5ZWFzdCgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBjb21tdW5pY2F0ZSBiaW5hcnkgc3VwcG9ydCBjYXBhYmlsaXRpZXNcbiAgICAgICAgICAgIGlmICghdGhpcy5zdXBwb3J0c0JpbmFyeSkge1xuICAgICAgICAgICAgICBxdWVyeS5iNjQgPSAxO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBxdWVyeSA9IHBhcnNlcXMuZW5jb2RlKHF1ZXJ5KTtcblxuICAgICAgICAgICAgLy8gcHJlcGVuZCA/IHRvIHF1ZXJ5XG4gICAgICAgICAgICBpZiAocXVlcnkubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIHF1ZXJ5ID0gJz8nICsgcXVlcnk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBpcHY2ID0gdGhpcy5ob3N0bmFtZS5pbmRleE9mKCc6JykgIT09IC0xO1xuICAgICAgICAgICAgcmV0dXJuIHNjaGVtYSArICc6Ly8nICsgKGlwdjYgPyAnWycgKyB0aGlzLmhvc3RuYW1lICsgJ10nIDogdGhpcy5ob3N0bmFtZSkgKyBwb3J0ICsgdGhpcy5wYXRoICsgcXVlcnk7XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEZlYXR1cmUgZGV0ZWN0aW9uIGZvciBXZWJTb2NrZXQuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAcmV0dXJuIHtCb29sZWFufSB3aGV0aGVyIHRoaXMgdHJhbnNwb3J0IGlzIGF2YWlsYWJsZS5cbiAgICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgV1MucHJvdG90eXBlLmNoZWNrID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuICEhV2ViU29ja2V0ICYmICEoJ19faW5pdGlhbGl6ZScgaW4gV2ViU29ja2V0ICYmIHRoaXMubmFtZSA9PT0gV1MucHJvdG90eXBlLm5hbWUpO1xuICAgICAgICAgIH07XG4gICAgICAgIH0pLmNhbGwodGhpcywgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB7fSk7XG4gICAgICB9LCB7IFwiLi4vdHJhbnNwb3J0XCI6IDQsIFwiY29tcG9uZW50LWluaGVyaXRcIjogMTYsIFwiZGVidWdcIjogMTcsIFwiZW5naW5lLmlvLXBhcnNlclwiOiAxOSwgXCJwYXJzZXFzXCI6IDI3LCBcIndzXCI6IHVuZGVmaW5lZCwgXCJ5ZWFzdFwiOiAzMCB9XSwgMTA6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG4gICAgICAgIC8vIGJyb3dzZXIgc2hpbSBmb3IgeG1saHR0cHJlcXVlc3QgbW9kdWxlXG4gICAgICAgIHZhciBoYXNDT1JTID0gX2RlcmVxXygnaGFzLWNvcnMnKTtcblxuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIChvcHRzKSB7XG4gICAgICAgICAgdmFyIHhkb21haW4gPSBvcHRzLnhkb21haW47XG5cbiAgICAgICAgICAvLyBzY2hlbWUgbXVzdCBiZSBzYW1lIHdoZW4gdXNpZ24gWERvbWFpblJlcXVlc3RcbiAgICAgICAgICAvLyBodHRwOi8vYmxvZ3MubXNkbi5jb20vYi9pZWludGVybmFscy9hcmNoaXZlLzIwMTAvMDUvMTMveGRvbWFpbnJlcXVlc3QtcmVzdHJpY3Rpb25zLWxpbWl0YXRpb25zLWFuZC13b3JrYXJvdW5kcy5hc3B4XG4gICAgICAgICAgdmFyIHhzY2hlbWUgPSBvcHRzLnhzY2hlbWU7XG5cbiAgICAgICAgICAvLyBYRG9tYWluUmVxdWVzdCBoYXMgYSBmbG93IG9mIG5vdCBzZW5kaW5nIGNvb2tpZSwgdGhlcmVmb3JlIGl0IHNob3VsZCBiZSBkaXNhYmxlZCBhcyBhIGRlZmF1bHQuXG4gICAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL0F1dG9tYXR0aWMvZW5naW5lLmlvLWNsaWVudC9wdWxsLzIxN1xuICAgICAgICAgIHZhciBlbmFibGVzWERSID0gb3B0cy5lbmFibGVzWERSO1xuXG4gICAgICAgICAgLy8gWE1MSHR0cFJlcXVlc3QgY2FuIGJlIGRpc2FibGVkIG9uIElFXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICgndW5kZWZpbmVkJyAhPSB0eXBlb2YgWE1MSHR0cFJlcXVlc3QgJiYgKCF4ZG9tYWluIHx8IGhhc0NPUlMpKSB7XG4gICAgICAgICAgICAgIHJldHVybiBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgICAgICAgLy8gVXNlIFhEb21haW5SZXF1ZXN0IGZvciBJRTggaWYgZW5hYmxlc1hEUiBpcyB0cnVlXG4gICAgICAgICAgLy8gYmVjYXVzZSBsb2FkaW5nIGJhciBrZWVwcyBmbGFzaGluZyB3aGVuIHVzaW5nIGpzb25wLXBvbGxpbmdcbiAgICAgICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20veXVqaW9zYWthL3NvY2tlLmlvLWllOC1sb2FkaW5nLWV4YW1wbGVcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKCd1bmRlZmluZWQnICE9IHR5cGVvZiBYRG9tYWluUmVxdWVzdCAmJiAheHNjaGVtZSAmJiBlbmFibGVzWERSKSB7XG4gICAgICAgICAgICAgIHJldHVybiBuZXcgWERvbWFpblJlcXVlc3QoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGNhdGNoIChlKSB7fVxuXG4gICAgICAgICAgaWYgKCF4ZG9tYWluKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICByZXR1cm4gbmV3IEFjdGl2ZVhPYmplY3QoJ01pY3Jvc29mdC5YTUxIVFRQJyk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH0sIHsgXCJoYXMtY29yc1wiOiAyMiB9XSwgMTE6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gYWZ0ZXI7XG5cbiAgICAgICAgZnVuY3Rpb24gYWZ0ZXIoY291bnQsIGNhbGxiYWNrLCBlcnJfY2IpIHtcbiAgICAgICAgICB2YXIgYmFpbCA9IGZhbHNlO1xuICAgICAgICAgIGVycl9jYiA9IGVycl9jYiB8fCBub29wO1xuICAgICAgICAgIHByb3h5LmNvdW50ID0gY291bnQ7XG5cbiAgICAgICAgICByZXR1cm4gY291bnQgPT09IDAgPyBjYWxsYmFjaygpIDogcHJveHk7XG5cbiAgICAgICAgICBmdW5jdGlvbiBwcm94eShlcnIsIHJlc3VsdCkge1xuICAgICAgICAgICAgaWYgKHByb3h5LmNvdW50IDw9IDApIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdhZnRlciBjYWxsZWQgdG9vIG1hbnkgdGltZXMnKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC0tcHJveHkuY291bnQ7XG5cbiAgICAgICAgICAgIC8vIGFmdGVyIGZpcnN0IGVycm9yLCByZXN0IGFyZSBwYXNzZWQgdG8gZXJyX2NiXG4gICAgICAgICAgICBpZiAoZXJyKSB7XG4gICAgICAgICAgICAgIGJhaWwgPSB0cnVlO1xuICAgICAgICAgICAgICBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgICAvLyBmdXR1cmUgZXJyb3IgY2FsbGJhY2tzIHdpbGwgZ28gdG8gZXJyb3IgaGFuZGxlclxuICAgICAgICAgICAgICBjYWxsYmFjayA9IGVycl9jYjtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAocHJveHkuY291bnQgPT09IDAgJiYgIWJhaWwpIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgcmVzdWx0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBub29wKCkge31cbiAgICAgIH0sIHt9XSwgMTI6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBbiBhYnN0cmFjdGlvbiBmb3Igc2xpY2luZyBhbiBhcnJheWJ1ZmZlciBldmVuIHdoZW5cbiAgICAgICAgICogQXJyYXlCdWZmZXIucHJvdG90eXBlLnNsaWNlIGlzIG5vdCBzdXBwb3J0ZWRcbiAgICAgICAgICpcbiAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICovXG5cbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoYXJyYXlidWZmZXIsIHN0YXJ0LCBlbmQpIHtcbiAgICAgICAgICB2YXIgYnl0ZXMgPSBhcnJheWJ1ZmZlci5ieXRlTGVuZ3RoO1xuICAgICAgICAgIHN0YXJ0ID0gc3RhcnQgfHwgMDtcbiAgICAgICAgICBlbmQgPSBlbmQgfHwgYnl0ZXM7XG5cbiAgICAgICAgICBpZiAoYXJyYXlidWZmZXIuc2xpY2UpIHtcbiAgICAgICAgICAgIHJldHVybiBhcnJheWJ1ZmZlci5zbGljZShzdGFydCwgZW5kKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICAgICAgICBzdGFydCArPSBieXRlcztcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGVuZCA8IDApIHtcbiAgICAgICAgICAgIGVuZCArPSBieXRlcztcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGVuZCA+IGJ5dGVzKSB7XG4gICAgICAgICAgICBlbmQgPSBieXRlcztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAoc3RhcnQgPj0gYnl0ZXMgfHwgc3RhcnQgPj0gZW5kIHx8IGJ5dGVzID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEFycmF5QnVmZmVyKDApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBhYnYgPSBuZXcgVWludDhBcnJheShhcnJheWJ1ZmZlcik7XG4gICAgICAgICAgdmFyIHJlc3VsdCA9IG5ldyBVaW50OEFycmF5KGVuZCAtIHN0YXJ0KTtcbiAgICAgICAgICBmb3IgKHZhciBpID0gc3RhcnQsIGlpID0gMDsgaSA8IGVuZDsgaSsrLCBpaSsrKSB7XG4gICAgICAgICAgICByZXN1bHRbaWldID0gYWJ2W2ldO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gcmVzdWx0LmJ1ZmZlcjtcbiAgICAgICAgfTtcbiAgICAgIH0sIHt9XSwgMTM6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG4gICAgICAgIC8qXG4gICAgICAgICAqIGJhc2U2NC1hcnJheWJ1ZmZlclxuICAgICAgICAgKiBodHRwczovL2dpdGh1Yi5jb20vbmlrbGFzdmgvYmFzZTY0LWFycmF5YnVmZmVyXG4gICAgICAgICAqXG4gICAgICAgICAqIENvcHlyaWdodCAoYykgMjAxMiBOaWtsYXMgdm9uIEhlcnR6ZW5cbiAgICAgICAgICogTGljZW5zZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlLlxuICAgICAgICAgKi9cbiAgICAgICAgKGZ1bmN0aW9uIChjaGFycykge1xuICAgICAgICAgIFwidXNlIHN0cmljdFwiO1xuXG4gICAgICAgICAgZXhwb3J0cy5lbmNvZGUgPSBmdW5jdGlvbiAoYXJyYXlidWZmZXIpIHtcbiAgICAgICAgICAgIHZhciBieXRlcyA9IG5ldyBVaW50OEFycmF5KGFycmF5YnVmZmVyKSxcbiAgICAgICAgICAgICAgICBpLFxuICAgICAgICAgICAgICAgIGxlbiA9IGJ5dGVzLmxlbmd0aCxcbiAgICAgICAgICAgICAgICBiYXNlNjQgPSBcIlwiO1xuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IDMpIHtcbiAgICAgICAgICAgICAgYmFzZTY0ICs9IGNoYXJzW2J5dGVzW2ldID4+IDJdO1xuICAgICAgICAgICAgICBiYXNlNjQgKz0gY2hhcnNbKGJ5dGVzW2ldICYgMykgPDwgNCB8IGJ5dGVzW2kgKyAxXSA+PiA0XTtcbiAgICAgICAgICAgICAgYmFzZTY0ICs9IGNoYXJzWyhieXRlc1tpICsgMV0gJiAxNSkgPDwgMiB8IGJ5dGVzW2kgKyAyXSA+PiA2XTtcbiAgICAgICAgICAgICAgYmFzZTY0ICs9IGNoYXJzW2J5dGVzW2kgKyAyXSAmIDYzXTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGxlbiAlIDMgPT09IDIpIHtcbiAgICAgICAgICAgICAgYmFzZTY0ID0gYmFzZTY0LnN1YnN0cmluZygwLCBiYXNlNjQubGVuZ3RoIC0gMSkgKyBcIj1cIjtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAobGVuICUgMyA9PT0gMSkge1xuICAgICAgICAgICAgICBiYXNlNjQgPSBiYXNlNjQuc3Vic3RyaW5nKDAsIGJhc2U2NC5sZW5ndGggLSAyKSArIFwiPT1cIjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIGJhc2U2NDtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgZXhwb3J0cy5kZWNvZGUgPSBmdW5jdGlvbiAoYmFzZTY0KSB7XG4gICAgICAgICAgICB2YXIgYnVmZmVyTGVuZ3RoID0gYmFzZTY0Lmxlbmd0aCAqIDAuNzUsXG4gICAgICAgICAgICAgICAgbGVuID0gYmFzZTY0Lmxlbmd0aCxcbiAgICAgICAgICAgICAgICBpLFxuICAgICAgICAgICAgICAgIHAgPSAwLFxuICAgICAgICAgICAgICAgIGVuY29kZWQxLFxuICAgICAgICAgICAgICAgIGVuY29kZWQyLFxuICAgICAgICAgICAgICAgIGVuY29kZWQzLFxuICAgICAgICAgICAgICAgIGVuY29kZWQ0O1xuXG4gICAgICAgICAgICBpZiAoYmFzZTY0W2Jhc2U2NC5sZW5ndGggLSAxXSA9PT0gXCI9XCIpIHtcbiAgICAgICAgICAgICAgYnVmZmVyTGVuZ3RoLS07XG4gICAgICAgICAgICAgIGlmIChiYXNlNjRbYmFzZTY0Lmxlbmd0aCAtIDJdID09PSBcIj1cIikge1xuICAgICAgICAgICAgICAgIGJ1ZmZlckxlbmd0aC0tO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBhcnJheWJ1ZmZlciA9IG5ldyBBcnJheUJ1ZmZlcihidWZmZXJMZW5ndGgpLFxuICAgICAgICAgICAgICAgIGJ5dGVzID0gbmV3IFVpbnQ4QXJyYXkoYXJyYXlidWZmZXIpO1xuXG4gICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpICs9IDQpIHtcbiAgICAgICAgICAgICAgZW5jb2RlZDEgPSBjaGFycy5pbmRleE9mKGJhc2U2NFtpXSk7XG4gICAgICAgICAgICAgIGVuY29kZWQyID0gY2hhcnMuaW5kZXhPZihiYXNlNjRbaSArIDFdKTtcbiAgICAgICAgICAgICAgZW5jb2RlZDMgPSBjaGFycy5pbmRleE9mKGJhc2U2NFtpICsgMl0pO1xuICAgICAgICAgICAgICBlbmNvZGVkNCA9IGNoYXJzLmluZGV4T2YoYmFzZTY0W2kgKyAzXSk7XG5cbiAgICAgICAgICAgICAgYnl0ZXNbcCsrXSA9IGVuY29kZWQxIDw8IDIgfCBlbmNvZGVkMiA+PiA0O1xuICAgICAgICAgICAgICBieXRlc1twKytdID0gKGVuY29kZWQyICYgMTUpIDw8IDQgfCBlbmNvZGVkMyA+PiAyO1xuICAgICAgICAgICAgICBieXRlc1twKytdID0gKGVuY29kZWQzICYgMykgPDwgNiB8IGVuY29kZWQ0ICYgNjM7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiBhcnJheWJ1ZmZlcjtcbiAgICAgICAgICB9O1xuICAgICAgICB9KShcIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky9cIik7XG4gICAgICB9LCB7fV0sIDE0OiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuICAgICAgICAoZnVuY3Rpb24gKGdsb2JhbCkge1xuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIENyZWF0ZSBhIGJsb2IgYnVpbGRlciBldmVuIHdoZW4gdmVuZG9yIHByZWZpeGVzIGV4aXN0XG4gICAgICAgICAgICovXG5cbiAgICAgICAgICB2YXIgQmxvYkJ1aWxkZXIgPSBnbG9iYWwuQmxvYkJ1aWxkZXIgfHwgZ2xvYmFsLldlYktpdEJsb2JCdWlsZGVyIHx8IGdsb2JhbC5NU0Jsb2JCdWlsZGVyIHx8IGdsb2JhbC5Nb3pCbG9iQnVpbGRlcjtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIENoZWNrIGlmIEJsb2IgY29uc3RydWN0b3IgaXMgc3VwcG9ydGVkXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICB2YXIgYmxvYlN1cHBvcnRlZCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIHZhciBhID0gbmV3IEJsb2IoWydoaSddKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGEuc2l6ZSA9PT0gMjtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0oKTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIENoZWNrIGlmIEJsb2IgY29uc3RydWN0b3Igc3VwcG9ydHMgQXJyYXlCdWZmZXJWaWV3c1xuICAgICAgICAgICAqIEZhaWxzIGluIFNhZmFyaSA2LCBzbyB3ZSBuZWVkIHRvIG1hcCB0byBBcnJheUJ1ZmZlcnMgdGhlcmUuXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICB2YXIgYmxvYlN1cHBvcnRzQXJyYXlCdWZmZXJWaWV3ID0gYmxvYlN1cHBvcnRlZCAmJiBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICB2YXIgYiA9IG5ldyBCbG9iKFtuZXcgVWludDhBcnJheShbMSwgMl0pXSk7XG4gICAgICAgICAgICAgIHJldHVybiBiLnNpemUgPT09IDI7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KCk7XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBDaGVjayBpZiBCbG9iQnVpbGRlciBpcyBzdXBwb3J0ZWRcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIHZhciBibG9iQnVpbGRlclN1cHBvcnRlZCA9IEJsb2JCdWlsZGVyICYmIEJsb2JCdWlsZGVyLnByb3RvdHlwZS5hcHBlbmQgJiYgQmxvYkJ1aWxkZXIucHJvdG90eXBlLmdldEJsb2I7XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBIZWxwZXIgZnVuY3Rpb24gdGhhdCBtYXBzIEFycmF5QnVmZmVyVmlld3MgdG8gQXJyYXlCdWZmZXJzXG4gICAgICAgICAgICogVXNlZCBieSBCbG9iQnVpbGRlciBjb25zdHJ1Y3RvciBhbmQgb2xkIGJyb3dzZXJzIHRoYXQgZGlkbid0XG4gICAgICAgICAgICogc3VwcG9ydCBpdCBpbiB0aGUgQmxvYiBjb25zdHJ1Y3Rvci5cbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIGZ1bmN0aW9uIG1hcEFycmF5QnVmZmVyVmlld3MoYXJ5KSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyeS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICB2YXIgY2h1bmsgPSBhcnlbaV07XG4gICAgICAgICAgICAgIGlmIChjaHVuay5idWZmZXIgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcikge1xuICAgICAgICAgICAgICAgIHZhciBidWYgPSBjaHVuay5idWZmZXI7XG5cbiAgICAgICAgICAgICAgICAvLyBpZiB0aGlzIGlzIGEgc3ViYXJyYXksIG1ha2UgYSBjb3B5IHNvIHdlIG9ubHlcbiAgICAgICAgICAgICAgICAvLyBpbmNsdWRlIHRoZSBzdWJhcnJheSByZWdpb24gZnJvbSB0aGUgdW5kZXJseWluZyBidWZmZXJcbiAgICAgICAgICAgICAgICBpZiAoY2h1bmsuYnl0ZUxlbmd0aCAhPT0gYnVmLmJ5dGVMZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgIHZhciBjb3B5ID0gbmV3IFVpbnQ4QXJyYXkoY2h1bmsuYnl0ZUxlbmd0aCk7XG4gICAgICAgICAgICAgICAgICBjb3B5LnNldChuZXcgVWludDhBcnJheShidWYsIGNodW5rLmJ5dGVPZmZzZXQsIGNodW5rLmJ5dGVMZW5ndGgpKTtcbiAgICAgICAgICAgICAgICAgIGJ1ZiA9IGNvcHkuYnVmZmVyO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGFyeVtpXSA9IGJ1ZjtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGZ1bmN0aW9uIEJsb2JCdWlsZGVyQ29uc3RydWN0b3IoYXJ5LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fTtcblxuICAgICAgICAgICAgdmFyIGJiID0gbmV3IEJsb2JCdWlsZGVyKCk7XG4gICAgICAgICAgICBtYXBBcnJheUJ1ZmZlclZpZXdzKGFyeSk7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJ5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgIGJiLmFwcGVuZChhcnlbaV0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gb3B0aW9ucy50eXBlID8gYmIuZ2V0QmxvYihvcHRpb25zLnR5cGUpIDogYmIuZ2V0QmxvYigpO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICBmdW5jdGlvbiBCbG9iQ29uc3RydWN0b3IoYXJ5LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBtYXBBcnJheUJ1ZmZlclZpZXdzKGFyeSk7XG4gICAgICAgICAgICByZXR1cm4gbmV3IEJsb2IoYXJ5LCBvcHRpb25zIHx8IHt9KTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICBpZiAoYmxvYlN1cHBvcnRlZCkge1xuICAgICAgICAgICAgICByZXR1cm4gYmxvYlN1cHBvcnRzQXJyYXlCdWZmZXJWaWV3ID8gZ2xvYmFsLkJsb2IgOiBCbG9iQ29uc3RydWN0b3I7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGJsb2JCdWlsZGVyU3VwcG9ydGVkKSB7XG4gICAgICAgICAgICAgIHJldHVybiBCbG9iQnVpbGRlckNvbnN0cnVjdG9yO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KCk7XG4gICAgICAgIH0pLmNhbGwodGhpcywgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB7fSk7XG4gICAgICB9LCB7fV0sIDE1OiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFeHBvc2UgYEVtaXR0ZXJgLlxuICAgICAgICAgKi9cblxuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IEVtaXR0ZXI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluaXRpYWxpemUgYSBuZXcgYEVtaXR0ZXJgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBmdW5jdGlvbiBFbWl0dGVyKG9iaikge1xuICAgICAgICAgIGlmIChvYmopIHJldHVybiBtaXhpbihvYmopO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNaXhpbiB0aGUgZW1pdHRlciBwcm9wZXJ0aWVzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gb2JqXG4gICAgICAgICAqIEByZXR1cm4ge09iamVjdH1cbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIGZ1bmN0aW9uIG1peGluKG9iaikge1xuICAgICAgICAgIGZvciAodmFyIGtleSBpbiBFbWl0dGVyLnByb3RvdHlwZSkge1xuICAgICAgICAgICAgb2JqW2tleV0gPSBFbWl0dGVyLnByb3RvdHlwZVtrZXldO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gb2JqO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIExpc3RlbiBvbiB0aGUgZ2l2ZW4gYGV2ZW50YCB3aXRoIGBmbmAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICAgICAgICAgKiBAcmV0dXJuIHtFbWl0dGVyfVxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBFbWl0dGVyLnByb3RvdHlwZS5vbiA9IEVtaXR0ZXIucHJvdG90eXBlLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiAoZXZlbnQsIGZuKSB7XG4gICAgICAgICAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuICAgICAgICAgICh0aGlzLl9jYWxsYmFja3NbZXZlbnRdID0gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XSB8fCBbXSkucHVzaChmbik7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEFkZHMgYW4gYGV2ZW50YCBsaXN0ZW5lciB0aGF0IHdpbGwgYmUgaW52b2tlZCBhIHNpbmdsZVxuICAgICAgICAgKiB0aW1lIHRoZW4gYXV0b21hdGljYWxseSByZW1vdmVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAgICAgICAgICogQHJldHVybiB7RW1pdHRlcn1cbiAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICovXG5cbiAgICAgICAgRW1pdHRlci5wcm90b3R5cGUub25jZSA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcbiAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuXG4gICAgICAgICAgZnVuY3Rpb24gb24oKSB7XG4gICAgICAgICAgICBzZWxmLm9mZihldmVudCwgb24pO1xuICAgICAgICAgICAgZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBvbi5mbiA9IGZuO1xuICAgICAgICAgIHRoaXMub24oZXZlbnQsIG9uKTtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUmVtb3ZlIHRoZSBnaXZlbiBjYWxsYmFjayBmb3IgYGV2ZW50YCBvciBhbGxcbiAgICAgICAgICogcmVnaXN0ZXJlZCBjYWxsYmFja3MuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICAgICAgICAgKiBAcmV0dXJuIHtFbWl0dGVyfVxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBFbWl0dGVyLnByb3RvdHlwZS5vZmYgPSBFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVMaXN0ZW5lciA9IEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9IEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbiAoZXZlbnQsIGZuKSB7XG4gICAgICAgICAgdGhpcy5fY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzIHx8IHt9O1xuXG4gICAgICAgICAgLy8gYWxsXG4gICAgICAgICAgaWYgKDAgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgdGhpcy5fY2FsbGJhY2tzID0ge307XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBzcGVjaWZpYyBldmVudFxuICAgICAgICAgIHZhciBjYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3NbZXZlbnRdO1xuICAgICAgICAgIGlmICghY2FsbGJhY2tzKSByZXR1cm4gdGhpcztcblxuICAgICAgICAgIC8vIHJlbW92ZSBhbGwgaGFuZGxlcnNcbiAgICAgICAgICBpZiAoMSA9PSBhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5fY2FsbGJhY2tzW2V2ZW50XTtcbiAgICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIHJlbW92ZSBzcGVjaWZpYyBoYW5kbGVyXG4gICAgICAgICAgdmFyIGNiO1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2FsbGJhY2tzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjYiA9IGNhbGxiYWNrc1tpXTtcbiAgICAgICAgICAgIGlmIChjYiA9PT0gZm4gfHwgY2IuZm4gPT09IGZuKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrcy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW1pdCBgZXZlbnRgIHdpdGggdGhlIGdpdmVuIGFyZ3MuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICAgICAgICAgKiBAcGFyYW0ge01peGVkfSAuLi5cbiAgICAgICAgICogQHJldHVybiB7RW1pdHRlcn1cbiAgICAgICAgICovXG5cbiAgICAgICAgRW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKSxcbiAgICAgICAgICAgICAgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XTtcblxuICAgICAgICAgIGlmIChjYWxsYmFja3MpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrcyA9IGNhbGxiYWNrcy5zbGljZSgwKTtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBjYWxsYmFja3MubGVuZ3RoOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgICAgICAgY2FsbGJhY2tzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXR1cm4gYXJyYXkgb2YgY2FsbGJhY2tzIGZvciBgZXZlbnRgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAgICAgICAgICogQHJldHVybiB7QXJyYXl9XG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcbiAgICAgICAgICByZXR1cm4gdGhpcy5fY2FsbGJhY2tzW2V2ZW50XSB8fCBbXTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ2hlY2sgaWYgdGhpcyBlbWl0dGVyIGhhcyBgZXZlbnRgIGhhbmRsZXJzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAgICAgICAgICogQHJldHVybiB7Qm9vbGVhbn1cbiAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICovXG5cbiAgICAgICAgRW1pdHRlci5wcm90b3R5cGUuaGFzTGlzdGVuZXJzID0gZnVuY3Rpb24gKGV2ZW50KSB7XG4gICAgICAgICAgcmV0dXJuICEhdGhpcy5saXN0ZW5lcnMoZXZlbnQpLmxlbmd0aDtcbiAgICAgICAgfTtcbiAgICAgIH0sIHt9XSwgMTY6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG5cbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAoYSwgYikge1xuICAgICAgICAgIHZhciBmbiA9IGZ1bmN0aW9uIGZuKCkge307XG4gICAgICAgICAgZm4ucHJvdG90eXBlID0gYi5wcm90b3R5cGU7XG4gICAgICAgICAgYS5wcm90b3R5cGUgPSBuZXcgZm4oKTtcbiAgICAgICAgICBhLnByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGE7XG4gICAgICAgIH07XG4gICAgICB9LCB7fV0sIDE3OiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGlzIGlzIHRoZSB3ZWIgYnJvd3NlciBpbXBsZW1lbnRhdGlvbiBvZiBgZGVidWcoKWAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEV4cG9zZSBgZGVidWcoKWAgYXMgdGhlIG1vZHVsZS5cbiAgICAgICAgICovXG5cbiAgICAgICAgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gX2RlcmVxXygnLi9kZWJ1ZycpO1xuICAgICAgICBleHBvcnRzLmxvZyA9IGxvZztcbiAgICAgICAgZXhwb3J0cy5mb3JtYXRBcmdzID0gZm9ybWF0QXJncztcbiAgICAgICAgZXhwb3J0cy5zYXZlID0gc2F2ZTtcbiAgICAgICAgZXhwb3J0cy5sb2FkID0gbG9hZDtcbiAgICAgICAgZXhwb3J0cy51c2VDb2xvcnMgPSB1c2VDb2xvcnM7XG4gICAgICAgIGV4cG9ydHMuc3RvcmFnZSA9ICd1bmRlZmluZWQnICE9IHR5cGVvZiBjaHJvbWUgJiYgJ3VuZGVmaW5lZCcgIT0gdHlwZW9mIGNocm9tZS5zdG9yYWdlID8gY2hyb21lLnN0b3JhZ2UubG9jYWwgOiBsb2NhbHN0b3JhZ2UoKTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29sb3JzLlxuICAgICAgICAgKi9cblxuICAgICAgICBleHBvcnRzLmNvbG9ycyA9IFsnbGlnaHRzZWFncmVlbicsICdmb3Jlc3RncmVlbicsICdnb2xkZW5yb2QnLCAnZG9kZ2VyYmx1ZScsICdkYXJrb3JjaGlkJywgJ2NyaW1zb24nXTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ3VycmVudGx5IG9ubHkgV2ViS2l0LWJhc2VkIFdlYiBJbnNwZWN0b3JzLCBGaXJlZm94ID49IHYzMSxcbiAgICAgICAgICogYW5kIHRoZSBGaXJlYnVnIGV4dGVuc2lvbiAoYW55IEZpcmVmb3ggdmVyc2lvbikgYXJlIGtub3duXG4gICAgICAgICAqIHRvIHN1cHBvcnQgXCIlY1wiIENTUyBjdXN0b21pemF0aW9ucy5cbiAgICAgICAgICpcbiAgICAgICAgICogVE9ETzogYWRkIGEgYGxvY2FsU3RvcmFnZWAgdmFyaWFibGUgdG8gZXhwbGljaXRseSBlbmFibGUvZGlzYWJsZSBjb2xvcnNcbiAgICAgICAgICovXG5cbiAgICAgICAgZnVuY3Rpb24gdXNlQ29sb3JzKCkge1xuICAgICAgICAgIC8vIGlzIHdlYmtpdD8gaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMTY0NTk2MDYvMzc2NzczXG4gICAgICAgICAgcmV0dXJuICdXZWJraXRBcHBlYXJhbmNlJyBpbiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc3R5bGUgfHxcbiAgICAgICAgICAvLyBpcyBmaXJlYnVnPyBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8zOTgxMjAvMzc2NzczXG4gICAgICAgICAgd2luZG93LmNvbnNvbGUgJiYgKGNvbnNvbGUuZmlyZWJ1ZyB8fCBjb25zb2xlLmV4Y2VwdGlvbiAmJiBjb25zb2xlLnRhYmxlKSB8fFxuICAgICAgICAgIC8vIGlzIGZpcmVmb3ggPj0gdjMxP1xuICAgICAgICAgIC8vIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvVG9vbHMvV2ViX0NvbnNvbGUjU3R5bGluZ19tZXNzYWdlc1xuICAgICAgICAgIG5hdmlnYXRvci51c2VyQWdlbnQudG9Mb3dlckNhc2UoKS5tYXRjaCgvZmlyZWZveFxcLyhcXGQrKS8pICYmIHBhcnNlSW50KFJlZ0V4cC4kMSwgMTApID49IDMxO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1hcCAlaiB0byBgSlNPTi5zdHJpbmdpZnkoKWAsIHNpbmNlIG5vIFdlYiBJbnNwZWN0b3JzIGRvIHRoYXQgYnkgZGVmYXVsdC5cbiAgICAgICAgICovXG5cbiAgICAgICAgZXhwb3J0cy5mb3JtYXR0ZXJzLmogPSBmdW5jdGlvbiAodikge1xuICAgICAgICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh2KTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ29sb3JpemUgbG9nIGFyZ3VtZW50cyBpZiBlbmFibGVkLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBmdW5jdGlvbiBmb3JtYXRBcmdzKCkge1xuICAgICAgICAgIHZhciBhcmdzID0gYXJndW1lbnRzO1xuICAgICAgICAgIHZhciB1c2VDb2xvcnMgPSB0aGlzLnVzZUNvbG9ycztcblxuICAgICAgICAgIGFyZ3NbMF0gPSAodXNlQ29sb3JzID8gJyVjJyA6ICcnKSArIHRoaXMubmFtZXNwYWNlICsgKHVzZUNvbG9ycyA/ICcgJWMnIDogJyAnKSArIGFyZ3NbMF0gKyAodXNlQ29sb3JzID8gJyVjICcgOiAnICcpICsgJysnICsgZXhwb3J0cy5odW1hbml6ZSh0aGlzLmRpZmYpO1xuXG4gICAgICAgICAgaWYgKCF1c2VDb2xvcnMpIHJldHVybiBhcmdzO1xuXG4gICAgICAgICAgdmFyIGMgPSAnY29sb3I6ICcgKyB0aGlzLmNvbG9yO1xuICAgICAgICAgIGFyZ3MgPSBbYXJnc1swXSwgYywgJ2NvbG9yOiBpbmhlcml0J10uY29uY2F0KEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3MsIDEpKTtcblxuICAgICAgICAgIC8vIHRoZSBmaW5hbCBcIiVjXCIgaXMgc29tZXdoYXQgdHJpY2t5LCBiZWNhdXNlIHRoZXJlIGNvdWxkIGJlIG90aGVyXG4gICAgICAgICAgLy8gYXJndW1lbnRzIHBhc3NlZCBlaXRoZXIgYmVmb3JlIG9yIGFmdGVyIHRoZSAlYywgc28gd2UgbmVlZCB0b1xuICAgICAgICAgIC8vIGZpZ3VyZSBvdXQgdGhlIGNvcnJlY3QgaW5kZXggdG8gaW5zZXJ0IHRoZSBDU1MgaW50b1xuICAgICAgICAgIHZhciBpbmRleCA9IDA7XG4gICAgICAgICAgdmFyIGxhc3RDID0gMDtcbiAgICAgICAgICBhcmdzWzBdLnJlcGxhY2UoLyVbYS16JV0vZywgZnVuY3Rpb24gKG1hdGNoKSB7XG4gICAgICAgICAgICBpZiAoJyUlJyA9PT0gbWF0Y2gpIHJldHVybjtcbiAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgICAgICBpZiAoJyVjJyA9PT0gbWF0Y2gpIHtcbiAgICAgICAgICAgICAgLy8gd2Ugb25seSBhcmUgaW50ZXJlc3RlZCBpbiB0aGUgKmxhc3QqICVjXG4gICAgICAgICAgICAgIC8vICh0aGUgdXNlciBtYXkgaGF2ZSBwcm92aWRlZCB0aGVpciBvd24pXG4gICAgICAgICAgICAgIGxhc3RDID0gaW5kZXg7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBhcmdzLnNwbGljZShsYXN0QywgMCwgYyk7XG4gICAgICAgICAgcmV0dXJuIGFyZ3M7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogSW52b2tlcyBgY29uc29sZS5sb2coKWAgd2hlbiBhdmFpbGFibGUuXG4gICAgICAgICAqIE5vLW9wIHdoZW4gYGNvbnNvbGUubG9nYCBpcyBub3QgYSBcImZ1bmN0aW9uXCIuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIGZ1bmN0aW9uIGxvZygpIHtcbiAgICAgICAgICAvLyB0aGlzIGhhY2tlcnkgaXMgcmVxdWlyZWQgZm9yIElFOC85LCB3aGVyZVxuICAgICAgICAgIC8vIHRoZSBgY29uc29sZS5sb2dgIGZ1bmN0aW9uIGRvZXNuJ3QgaGF2ZSAnYXBwbHknXG4gICAgICAgICAgcmV0dXJuICdvYmplY3QnID09PSAodHlwZW9mIGNvbnNvbGUgPT09IFwidW5kZWZpbmVkXCIgPyBcInVuZGVmaW5lZFwiIDogX3R5cGVvZihjb25zb2xlKSkgJiYgY29uc29sZS5sb2cgJiYgRnVuY3Rpb24ucHJvdG90eXBlLmFwcGx5LmNhbGwoY29uc29sZS5sb2csIGNvbnNvbGUsIGFyZ3VtZW50cyk7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogU2F2ZSBgbmFtZXNwYWNlc2AuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lc3BhY2VzXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBmdW5jdGlvbiBzYXZlKG5hbWVzcGFjZXMpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgaWYgKG51bGwgPT0gbmFtZXNwYWNlcykge1xuICAgICAgICAgICAgICBleHBvcnRzLnN0b3JhZ2UucmVtb3ZlSXRlbSgnZGVidWcnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGV4cG9ydHMuc3RvcmFnZS5kZWJ1ZyA9IG5hbWVzcGFjZXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBMb2FkIGBuYW1lc3BhY2VzYC5cbiAgICAgICAgICpcbiAgICAgICAgICogQHJldHVybiB7U3RyaW5nfSByZXR1cm5zIHRoZSBwcmV2aW91c2x5IHBlcnNpc3RlZCBkZWJ1ZyBtb2Rlc1xuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgZnVuY3Rpb24gbG9hZCgpIHtcbiAgICAgICAgICB2YXIgcjtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgciA9IGV4cG9ydHMuc3RvcmFnZS5kZWJ1ZztcbiAgICAgICAgICB9IGNhdGNoIChlKSB7fVxuICAgICAgICAgIHJldHVybiByO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuYWJsZSBuYW1lc3BhY2VzIGxpc3RlZCBpbiBgbG9jYWxTdG9yYWdlLmRlYnVnYCBpbml0aWFsbHkuXG4gICAgICAgICAqL1xuXG4gICAgICAgIGV4cG9ydHMuZW5hYmxlKGxvYWQoKSk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIExvY2Fsc3RvcmFnZSBhdHRlbXB0cyB0byByZXR1cm4gdGhlIGxvY2Fsc3RvcmFnZS5cbiAgICAgICAgICpcbiAgICAgICAgICogVGhpcyBpcyBuZWNlc3NhcnkgYmVjYXVzZSBzYWZhcmkgdGhyb3dzXG4gICAgICAgICAqIHdoZW4gYSB1c2VyIGRpc2FibGVzIGNvb2tpZXMvbG9jYWxzdG9yYWdlXG4gICAgICAgICAqIGFuZCB5b3UgYXR0ZW1wdCB0byBhY2Nlc3MgaXQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEByZXR1cm4ge0xvY2FsU3RvcmFnZX1cbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIGZ1bmN0aW9uIGxvY2Fsc3RvcmFnZSgpIHtcbiAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdy5sb2NhbFN0b3JhZ2U7XG4gICAgICAgICAgfSBjYXRjaCAoZSkge31cbiAgICAgICAgfVxuICAgICAgfSwgeyBcIi4vZGVidWdcIjogMTggfV0sIDE4OiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBUaGlzIGlzIHRoZSBjb21tb24gbG9naWMgZm9yIGJvdGggdGhlIE5vZGUuanMgYW5kIHdlYiBicm93c2VyXG4gICAgICAgICAqIGltcGxlbWVudGF0aW9ucyBvZiBgZGVidWcoKWAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEV4cG9zZSBgZGVidWcoKWAgYXMgdGhlIG1vZHVsZS5cbiAgICAgICAgICovXG5cbiAgICAgICAgZXhwb3J0cyA9IG1vZHVsZS5leHBvcnRzID0gZGVidWc7XG4gICAgICAgIGV4cG9ydHMuY29lcmNlID0gY29lcmNlO1xuICAgICAgICBleHBvcnRzLmRpc2FibGUgPSBkaXNhYmxlO1xuICAgICAgICBleHBvcnRzLmVuYWJsZSA9IGVuYWJsZTtcbiAgICAgICAgZXhwb3J0cy5lbmFibGVkID0gZW5hYmxlZDtcbiAgICAgICAgZXhwb3J0cy5odW1hbml6ZSA9IF9kZXJlcV8oJ21zJyk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFRoZSBjdXJyZW50bHkgYWN0aXZlIGRlYnVnIG1vZGUgbmFtZXMsIGFuZCBuYW1lcyB0byBza2lwLlxuICAgICAgICAgKi9cblxuICAgICAgICBleHBvcnRzLm5hbWVzID0gW107XG4gICAgICAgIGV4cG9ydHMuc2tpcHMgPSBbXTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTWFwIG9mIHNwZWNpYWwgXCIlblwiIGhhbmRsaW5nIGZ1bmN0aW9ucywgZm9yIHRoZSBkZWJ1ZyBcImZvcm1hdFwiIGFyZ3VtZW50LlxuICAgICAgICAgKlxuICAgICAgICAgKiBWYWxpZCBrZXkgbmFtZXMgYXJlIGEgc2luZ2xlLCBsb3dlcmNhc2VkIGxldHRlciwgaS5lLiBcIm5cIi5cbiAgICAgICAgICovXG5cbiAgICAgICAgZXhwb3J0cy5mb3JtYXR0ZXJzID0ge307XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByZXZpb3VzbHkgYXNzaWduZWQgY29sb3IuXG4gICAgICAgICAqL1xuXG4gICAgICAgIHZhciBwcmV2Q29sb3IgPSAwO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcmV2aW91cyBsb2cgdGltZXN0YW1wLlxuICAgICAgICAgKi9cblxuICAgICAgICB2YXIgcHJldlRpbWU7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNlbGVjdCBhIGNvbG9yLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBmdW5jdGlvbiBzZWxlY3RDb2xvcigpIHtcbiAgICAgICAgICByZXR1cm4gZXhwb3J0cy5jb2xvcnNbcHJldkNvbG9yKysgJSBleHBvcnRzLmNvbG9ycy5sZW5ndGhdO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZSBhIGRlYnVnZ2VyIHdpdGggdGhlIGdpdmVuIGBuYW1lc3BhY2VgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gbmFtZXNwYWNlXG4gICAgICAgICAqIEByZXR1cm4ge0Z1bmN0aW9ufVxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBmdW5jdGlvbiBkZWJ1ZyhuYW1lc3BhY2UpIHtcblxuICAgICAgICAgIC8vIGRlZmluZSB0aGUgYGRpc2FibGVkYCB2ZXJzaW9uXG4gICAgICAgICAgZnVuY3Rpb24gZGlzYWJsZWQoKSB7fVxuICAgICAgICAgIGRpc2FibGVkLmVuYWJsZWQgPSBmYWxzZTtcblxuICAgICAgICAgIC8vIGRlZmluZSB0aGUgYGVuYWJsZWRgIHZlcnNpb25cbiAgICAgICAgICBmdW5jdGlvbiBlbmFibGVkKCkge1xuXG4gICAgICAgICAgICB2YXIgc2VsZiA9IGVuYWJsZWQ7XG5cbiAgICAgICAgICAgIC8vIHNldCBgZGlmZmAgdGltZXN0YW1wXG4gICAgICAgICAgICB2YXIgY3VyciA9ICtuZXcgRGF0ZSgpO1xuICAgICAgICAgICAgdmFyIG1zID0gY3VyciAtIChwcmV2VGltZSB8fCBjdXJyKTtcbiAgICAgICAgICAgIHNlbGYuZGlmZiA9IG1zO1xuICAgICAgICAgICAgc2VsZi5wcmV2ID0gcHJldlRpbWU7XG4gICAgICAgICAgICBzZWxmLmN1cnIgPSBjdXJyO1xuICAgICAgICAgICAgcHJldlRpbWUgPSBjdXJyO1xuXG4gICAgICAgICAgICAvLyBhZGQgdGhlIGBjb2xvcmAgaWYgbm90IHNldFxuICAgICAgICAgICAgaWYgKG51bGwgPT0gc2VsZi51c2VDb2xvcnMpIHNlbGYudXNlQ29sb3JzID0gZXhwb3J0cy51c2VDb2xvcnMoKTtcbiAgICAgICAgICAgIGlmIChudWxsID09IHNlbGYuY29sb3IgJiYgc2VsZi51c2VDb2xvcnMpIHNlbGYuY29sb3IgPSBzZWxlY3RDb2xvcigpO1xuXG4gICAgICAgICAgICB2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cyk7XG5cbiAgICAgICAgICAgIGFyZ3NbMF0gPSBleHBvcnRzLmNvZXJjZShhcmdzWzBdKTtcblxuICAgICAgICAgICAgaWYgKCdzdHJpbmcnICE9PSB0eXBlb2YgYXJnc1swXSkge1xuICAgICAgICAgICAgICAvLyBhbnl0aGluZyBlbHNlIGxldCdzIGluc3BlY3Qgd2l0aCAlb1xuICAgICAgICAgICAgICBhcmdzID0gWyclbyddLmNvbmNhdChhcmdzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gYXBwbHkgYW55IGBmb3JtYXR0ZXJzYCB0cmFuc2Zvcm1hdGlvbnNcbiAgICAgICAgICAgIHZhciBpbmRleCA9IDA7XG4gICAgICAgICAgICBhcmdzWzBdID0gYXJnc1swXS5yZXBsYWNlKC8lKFthLXolXSkvZywgZnVuY3Rpb24gKG1hdGNoLCBmb3JtYXQpIHtcbiAgICAgICAgICAgICAgLy8gaWYgd2UgZW5jb3VudGVyIGFuIGVzY2FwZWQgJSB0aGVuIGRvbid0IGluY3JlYXNlIHRoZSBhcnJheSBpbmRleFxuICAgICAgICAgICAgICBpZiAobWF0Y2ggPT09ICclJScpIHJldHVybiBtYXRjaDtcbiAgICAgICAgICAgICAgaW5kZXgrKztcbiAgICAgICAgICAgICAgdmFyIGZvcm1hdHRlciA9IGV4cG9ydHMuZm9ybWF0dGVyc1tmb3JtYXRdO1xuICAgICAgICAgICAgICBpZiAoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIGZvcm1hdHRlcikge1xuICAgICAgICAgICAgICAgIHZhciB2YWwgPSBhcmdzW2luZGV4XTtcbiAgICAgICAgICAgICAgICBtYXRjaCA9IGZvcm1hdHRlci5jYWxsKHNlbGYsIHZhbCk7XG5cbiAgICAgICAgICAgICAgICAvLyBub3cgd2UgbmVlZCB0byByZW1vdmUgYGFyZ3NbaW5kZXhdYCBzaW5jZSBpdCdzIGlubGluZWQgaW4gdGhlIGBmb3JtYXRgXG4gICAgICAgICAgICAgICAgYXJncy5zcGxpY2UoaW5kZXgsIDEpO1xuICAgICAgICAgICAgICAgIGluZGV4LS07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIG1hdGNoO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGlmICgnZnVuY3Rpb24nID09PSB0eXBlb2YgZXhwb3J0cy5mb3JtYXRBcmdzKSB7XG4gICAgICAgICAgICAgIGFyZ3MgPSBleHBvcnRzLmZvcm1hdEFyZ3MuYXBwbHkoc2VsZiwgYXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB2YXIgbG9nRm4gPSBlbmFibGVkLmxvZyB8fCBleHBvcnRzLmxvZyB8fCBjb25zb2xlLmxvZy5iaW5kKGNvbnNvbGUpO1xuICAgICAgICAgICAgbG9nRm4uYXBwbHkoc2VsZiwgYXJncyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGVuYWJsZWQuZW5hYmxlZCA9IHRydWU7XG5cbiAgICAgICAgICB2YXIgZm4gPSBleHBvcnRzLmVuYWJsZWQobmFtZXNwYWNlKSA/IGVuYWJsZWQgOiBkaXNhYmxlZDtcblxuICAgICAgICAgIGZuLm5hbWVzcGFjZSA9IG5hbWVzcGFjZTtcblxuICAgICAgICAgIHJldHVybiBmbjtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFbmFibGVzIGEgZGVidWcgbW9kZSBieSBuYW1lc3BhY2VzLiBUaGlzIGNhbiBpbmNsdWRlIG1vZGVzXG4gICAgICAgICAqIHNlcGFyYXRlZCBieSBhIGNvbG9uIGFuZCB3aWxkY2FyZHMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lc3BhY2VzXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIGZ1bmN0aW9uIGVuYWJsZShuYW1lc3BhY2VzKSB7XG4gICAgICAgICAgZXhwb3J0cy5zYXZlKG5hbWVzcGFjZXMpO1xuXG4gICAgICAgICAgdmFyIHNwbGl0ID0gKG5hbWVzcGFjZXMgfHwgJycpLnNwbGl0KC9bXFxzLF0rLyk7XG4gICAgICAgICAgdmFyIGxlbiA9IHNwbGl0Lmxlbmd0aDtcblxuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGlmICghc3BsaXRbaV0pIGNvbnRpbnVlOyAvLyBpZ25vcmUgZW1wdHkgc3RyaW5nc1xuICAgICAgICAgICAgbmFtZXNwYWNlcyA9IHNwbGl0W2ldLnJlcGxhY2UoL1xcKi9nLCAnLio/Jyk7XG4gICAgICAgICAgICBpZiAobmFtZXNwYWNlc1swXSA9PT0gJy0nKSB7XG4gICAgICAgICAgICAgIGV4cG9ydHMuc2tpcHMucHVzaChuZXcgUmVnRXhwKCdeJyArIG5hbWVzcGFjZXMuc3Vic3RyKDEpICsgJyQnKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBleHBvcnRzLm5hbWVzLnB1c2gobmV3IFJlZ0V4cCgnXicgKyBuYW1lc3BhY2VzICsgJyQnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERpc2FibGUgZGVidWcgb3V0cHV0LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBmdW5jdGlvbiBkaXNhYmxlKCkge1xuICAgICAgICAgIGV4cG9ydHMuZW5hYmxlKCcnKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXR1cm5zIHRydWUgaWYgdGhlIGdpdmVuIG1vZGUgbmFtZSBpcyBlbmFibGVkLCBmYWxzZSBvdGhlcndpc2UuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBuYW1lXG4gICAgICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIGZ1bmN0aW9uIGVuYWJsZWQobmFtZSkge1xuICAgICAgICAgIHZhciBpLCBsZW47XG4gICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gZXhwb3J0cy5za2lwcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgaWYgKGV4cG9ydHMuc2tpcHNbaV0udGVzdChuYW1lKSkge1xuICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGV4cG9ydHMubmFtZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChleHBvcnRzLm5hbWVzW2ldLnRlc3QobmFtZSkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb2VyY2UgYHZhbGAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7TWl4ZWR9IHZhbFxuICAgICAgICAgKiBAcmV0dXJuIHtNaXhlZH1cbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIGZ1bmN0aW9uIGNvZXJjZSh2YWwpIHtcbiAgICAgICAgICBpZiAodmFsIGluc3RhbmNlb2YgRXJyb3IpIHJldHVybiB2YWwuc3RhY2sgfHwgdmFsLm1lc3NhZ2U7XG4gICAgICAgICAgcmV0dXJuIHZhbDtcbiAgICAgICAgfVxuICAgICAgfSwgeyBcIm1zXCI6IDI1IH1dLCAxOTogW2Z1bmN0aW9uIChfZGVyZXFfLCBtb2R1bGUsIGV4cG9ydHMpIHtcbiAgICAgICAgKGZ1bmN0aW9uIChnbG9iYWwpIHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgdmFyIGtleXMgPSBfZGVyZXFfKCcuL2tleXMnKTtcbiAgICAgICAgICB2YXIgaGFzQmluYXJ5ID0gX2RlcmVxXygnaGFzLWJpbmFyeScpO1xuICAgICAgICAgIHZhciBzbGljZUJ1ZmZlciA9IF9kZXJlcV8oJ2FycmF5YnVmZmVyLnNsaWNlJyk7XG4gICAgICAgICAgdmFyIGJhc2U2NGVuY29kZXIgPSBfZGVyZXFfKCdiYXNlNjQtYXJyYXlidWZmZXInKTtcbiAgICAgICAgICB2YXIgYWZ0ZXIgPSBfZGVyZXFfKCdhZnRlcicpO1xuICAgICAgICAgIHZhciB1dGY4ID0gX2RlcmVxXygndXRmOCcpO1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogQ2hlY2sgaWYgd2UgYXJlIHJ1bm5pbmcgYW4gYW5kcm9pZCBicm93c2VyLiBUaGF0IHJlcXVpcmVzIHVzIHRvIHVzZVxuICAgICAgICAgICAqIEFycmF5QnVmZmVyIHdpdGggcG9sbGluZyB0cmFuc3BvcnRzLi4uXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBodHRwOi8vZ2hpbmRhLm5ldC9qcGVnLWJsb2ItYWpheC1hbmRyb2lkL1xuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgdmFyIGlzQW5kcm9pZCA9IG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL0FuZHJvaWQvaSk7XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBDaGVjayBpZiB3ZSBhcmUgcnVubmluZyBpbiBQaGFudG9tSlMuXG4gICAgICAgICAgICogVXBsb2FkaW5nIGEgQmxvYiB3aXRoIFBoYW50b21KUyBkb2VzIG5vdCB3b3JrIGNvcnJlY3RseSwgYXMgcmVwb3J0ZWQgaGVyZTpcbiAgICAgICAgICAgKiBodHRwczovL2dpdGh1Yi5jb20vYXJpeWEvcGhhbnRvbWpzL2lzc3Vlcy8xMTM5NVxuICAgICAgICAgICAqIEB0eXBlIGJvb2xlYW5cbiAgICAgICAgICAgKi9cbiAgICAgICAgICB2YXIgaXNQaGFudG9tSlMgPSAvUGhhbnRvbUpTL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFdoZW4gdHJ1ZSwgYXZvaWRzIHVzaW5nIEJsb2JzIHRvIGVuY29kZSBwYXlsb2Fkcy5cbiAgICAgICAgICAgKiBAdHlwZSBib29sZWFuXG4gICAgICAgICAgICovXG4gICAgICAgICAgdmFyIGRvbnRTZW5kQmxvYnMgPSBpc0FuZHJvaWQgfHwgaXNQaGFudG9tSlM7XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBDdXJyZW50IHByb3RvY29sIHZlcnNpb24uXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBleHBvcnRzLnByb3RvY29sID0gMztcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFBhY2tldCB0eXBlcy5cbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIHZhciBwYWNrZXRzID0gZXhwb3J0cy5wYWNrZXRzID0ge1xuICAgICAgICAgICAgb3BlbjogMCAvLyBub24td3NcbiAgICAgICAgICAgICwgY2xvc2U6IDEgLy8gbm9uLXdzXG4gICAgICAgICAgICAsIHBpbmc6IDIsXG4gICAgICAgICAgICBwb25nOiAzLFxuICAgICAgICAgICAgbWVzc2FnZTogNCxcbiAgICAgICAgICAgIHVwZ3JhZGU6IDUsXG4gICAgICAgICAgICBub29wOiA2XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIHZhciBwYWNrZXRzbGlzdCA9IGtleXMocGFja2V0cyk7XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBQcmVtYWRlIGVycm9yIHBhY2tldC5cbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIHZhciBlcnIgPSB7IHR5cGU6ICdlcnJvcicsIGRhdGE6ICdwYXJzZXIgZXJyb3InIH07XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBDcmVhdGUgYSBibG9iIGFwaSBldmVuIGZvciBibG9iIGJ1aWxkZXIgd2hlbiB2ZW5kb3IgcHJlZml4ZXMgZXhpc3RcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIHZhciBCbG9iID0gX2RlcmVxXygnYmxvYicpO1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRW5jb2RlcyBhIHBhY2tldC5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqICAgICA8cGFja2V0IHR5cGUgaWQ+IFsgPGRhdGE+IF1cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEV4YW1wbGU6XG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiAgICAgNWhlbGxvIHdvcmxkXG4gICAgICAgICAgICogICAgIDNcbiAgICAgICAgICAgKiAgICAgNFxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQmluYXJ5IGlzIGVuY29kZWQgaW4gYW4gaWRlbnRpY2FsIHByaW5jaXBsZVxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBleHBvcnRzLmVuY29kZVBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCB1dGY4ZW5jb2RlLCBjYWxsYmFjaykge1xuICAgICAgICAgICAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIHN1cHBvcnRzQmluYXJ5KSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrID0gc3VwcG9ydHNCaW5hcnk7XG4gICAgICAgICAgICAgIHN1cHBvcnRzQmluYXJ5ID0gZmFsc2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICgnZnVuY3Rpb24nID09IHR5cGVvZiB1dGY4ZW5jb2RlKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrID0gdXRmOGVuY29kZTtcbiAgICAgICAgICAgICAgdXRmOGVuY29kZSA9IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBkYXRhID0gcGFja2V0LmRhdGEgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IHBhY2tldC5kYXRhLmJ1ZmZlciB8fCBwYWNrZXQuZGF0YTtcblxuICAgICAgICAgICAgaWYgKGdsb2JhbC5BcnJheUJ1ZmZlciAmJiBkYXRhIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGVuY29kZUFycmF5QnVmZmVyKHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoQmxvYiAmJiBkYXRhIGluc3RhbmNlb2YgZ2xvYmFsLkJsb2IpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGVuY29kZUJsb2IocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBtaWdodCBiZSBhbiBvYmplY3Qgd2l0aCB7IGJhc2U2NDogdHJ1ZSwgZGF0YTogZGF0YUFzQmFzZTY0U3RyaW5nIH1cbiAgICAgICAgICAgIGlmIChkYXRhICYmIGRhdGEuYmFzZTY0KSB7XG4gICAgICAgICAgICAgIHJldHVybiBlbmNvZGVCYXNlNjRPYmplY3QocGFja2V0LCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNlbmRpbmcgZGF0YSBhcyBhIHV0Zi04IHN0cmluZ1xuICAgICAgICAgICAgdmFyIGVuY29kZWQgPSBwYWNrZXRzW3BhY2tldC50eXBlXTtcblxuICAgICAgICAgICAgLy8gZGF0YSBmcmFnbWVudCBpcyBvcHRpb25hbFxuICAgICAgICAgICAgaWYgKHVuZGVmaW5lZCAhPT0gcGFja2V0LmRhdGEpIHtcbiAgICAgICAgICAgICAgZW5jb2RlZCArPSB1dGY4ZW5jb2RlID8gdXRmOC5lbmNvZGUoU3RyaW5nKHBhY2tldC5kYXRhKSkgOiBTdHJpbmcocGFja2V0LmRhdGEpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soJycgKyBlbmNvZGVkKTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgZnVuY3Rpb24gZW5jb2RlQmFzZTY0T2JqZWN0KHBhY2tldCwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIC8vIHBhY2tldCBkYXRhIGlzIGFuIG9iamVjdCB7IGJhc2U2NDogdHJ1ZSwgZGF0YTogZGF0YUFzQmFzZTY0U3RyaW5nIH1cbiAgICAgICAgICAgIHZhciBtZXNzYWdlID0gJ2InICsgZXhwb3J0cy5wYWNrZXRzW3BhY2tldC50eXBlXSArIHBhY2tldC5kYXRhLmRhdGE7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2sobWVzc2FnZSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRW5jb2RlIHBhY2tldCBoZWxwZXJzIGZvciBiaW5hcnkgdHlwZXNcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIGZ1bmN0aW9uIGVuY29kZUFycmF5QnVmZmVyKHBhY2tldCwgc3VwcG9ydHNCaW5hcnksIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBpZiAoIXN1cHBvcnRzQmluYXJ5KSB7XG4gICAgICAgICAgICAgIHJldHVybiBleHBvcnRzLmVuY29kZUJhc2U2NFBhY2tldChwYWNrZXQsIGNhbGxiYWNrKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGRhdGEgPSBwYWNrZXQuZGF0YTtcbiAgICAgICAgICAgIHZhciBjb250ZW50QXJyYXkgPSBuZXcgVWludDhBcnJheShkYXRhKTtcbiAgICAgICAgICAgIHZhciByZXN1bHRCdWZmZXIgPSBuZXcgVWludDhBcnJheSgxICsgZGF0YS5ieXRlTGVuZ3RoKTtcblxuICAgICAgICAgICAgcmVzdWx0QnVmZmVyWzBdID0gcGFja2V0c1twYWNrZXQudHlwZV07XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbnRlbnRBcnJheS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICByZXN1bHRCdWZmZXJbaSArIDFdID0gY29udGVudEFycmF5W2ldO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2socmVzdWx0QnVmZmVyLmJ1ZmZlcik7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZnVuY3Rpb24gZW5jb2RlQmxvYkFzQXJyYXlCdWZmZXIocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGlmICghc3VwcG9ydHNCaW5hcnkpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGV4cG9ydHMuZW5jb2RlQmFzZTY0UGFja2V0KHBhY2tldCwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgZnIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgICAgICAgICAgZnIub25sb2FkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBwYWNrZXQuZGF0YSA9IGZyLnJlc3VsdDtcbiAgICAgICAgICAgICAgZXhwb3J0cy5lbmNvZGVQYWNrZXQocGFja2V0LCBzdXBwb3J0c0JpbmFyeSwgdHJ1ZSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIHJldHVybiBmci5yZWFkQXNBcnJheUJ1ZmZlcihwYWNrZXQuZGF0YSk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZnVuY3Rpb24gZW5jb2RlQmxvYihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgaWYgKCFzdXBwb3J0c0JpbmFyeSkge1xuICAgICAgICAgICAgICByZXR1cm4gZXhwb3J0cy5lbmNvZGVCYXNlNjRQYWNrZXQocGFja2V0LCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChkb250U2VuZEJsb2JzKSB7XG4gICAgICAgICAgICAgIHJldHVybiBlbmNvZGVCbG9iQXNBcnJheUJ1ZmZlcihwYWNrZXQsIHN1cHBvcnRzQmluYXJ5LCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBsZW5ndGggPSBuZXcgVWludDhBcnJheSgxKTtcbiAgICAgICAgICAgIGxlbmd0aFswXSA9IHBhY2tldHNbcGFja2V0LnR5cGVdO1xuICAgICAgICAgICAgdmFyIGJsb2IgPSBuZXcgQmxvYihbbGVuZ3RoLmJ1ZmZlciwgcGFja2V0LmRhdGFdKTtcblxuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGJsb2IpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIEVuY29kZXMgYSBwYWNrZXQgd2l0aCBiaW5hcnkgZGF0YSBpbiBhIGJhc2U2NCBzdHJpbmdcbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXQsIGhhcyBgdHlwZWAgYW5kIGBkYXRhYFxuICAgICAgICAgICAqIEByZXR1cm4ge1N0cmluZ30gYmFzZTY0IGVuY29kZWQgbWVzc2FnZVxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgZXhwb3J0cy5lbmNvZGVCYXNlNjRQYWNrZXQgPSBmdW5jdGlvbiAocGFja2V0LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgdmFyIG1lc3NhZ2UgPSAnYicgKyBleHBvcnRzLnBhY2tldHNbcGFja2V0LnR5cGVdO1xuICAgICAgICAgICAgaWYgKEJsb2IgJiYgcGFja2V0LmRhdGEgaW5zdGFuY2VvZiBnbG9iYWwuQmxvYikge1xuICAgICAgICAgICAgICB2YXIgZnIgPSBuZXcgRmlsZVJlYWRlcigpO1xuICAgICAgICAgICAgICBmci5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgdmFyIGI2NCA9IGZyLnJlc3VsdC5zcGxpdCgnLCcpWzFdO1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKG1lc3NhZ2UgKyBiNjQpO1xuICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICByZXR1cm4gZnIucmVhZEFzRGF0YVVSTChwYWNrZXQuZGF0YSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBiNjRkYXRhO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgYjY0ZGF0YSA9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgbmV3IFVpbnQ4QXJyYXkocGFja2V0LmRhdGEpKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgLy8gaVBob25lIFNhZmFyaSBkb2Vzbid0IGxldCB5b3UgYXBwbHkgd2l0aCB0eXBlZCBhcnJheXNcbiAgICAgICAgICAgICAgdmFyIHR5cGVkID0gbmV3IFVpbnQ4QXJyYXkocGFja2V0LmRhdGEpO1xuICAgICAgICAgICAgICB2YXIgYmFzaWMgPSBuZXcgQXJyYXkodHlwZWQubGVuZ3RoKTtcbiAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0eXBlZC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIGJhc2ljW2ldID0gdHlwZWRbaV07XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgYjY0ZGF0YSA9IFN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCwgYmFzaWMpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbWVzc2FnZSArPSBnbG9iYWwuYnRvYShiNjRkYXRhKTtcbiAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhtZXNzYWdlKTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRGVjb2RlcyBhIHBhY2tldC4gQ2hhbmdlcyBmb3JtYXQgdG8gQmxvYiBpZiByZXF1ZXN0ZWQuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IHdpdGggYHR5cGVgIGFuZCBgZGF0YWAgKGlmIGFueSlcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIGV4cG9ydHMuZGVjb2RlUGFja2V0ID0gZnVuY3Rpb24gKGRhdGEsIGJpbmFyeVR5cGUsIHV0ZjhkZWNvZGUpIHtcbiAgICAgICAgICAgIC8vIFN0cmluZyBkYXRhXG4gICAgICAgICAgICBpZiAodHlwZW9mIGRhdGEgPT0gJ3N0cmluZycgfHwgZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgIGlmIChkYXRhLmNoYXJBdCgwKSA9PSAnYicpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gZXhwb3J0cy5kZWNvZGVCYXNlNjRQYWNrZXQoZGF0YS5zdWJzdHIoMSksIGJpbmFyeVR5cGUpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKHV0ZjhkZWNvZGUpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgZGF0YSA9IHV0ZjguZGVjb2RlKGRhdGEpO1xuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICAgIHJldHVybiBlcnI7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHZhciB0eXBlID0gZGF0YS5jaGFyQXQoMCk7XG5cbiAgICAgICAgICAgICAgaWYgKE51bWJlcih0eXBlKSAhPSB0eXBlIHx8ICFwYWNrZXRzbGlzdFt0eXBlXSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBlcnI7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoZGF0YS5sZW5ndGggPiAxKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgdHlwZTogcGFja2V0c2xpc3RbdHlwZV0sIGRhdGE6IGRhdGEuc3Vic3RyaW5nKDEpIH07XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgdHlwZTogcGFja2V0c2xpc3RbdHlwZV0gfTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgYXNBcnJheSA9IG5ldyBVaW50OEFycmF5KGRhdGEpO1xuICAgICAgICAgICAgdmFyIHR5cGUgPSBhc0FycmF5WzBdO1xuICAgICAgICAgICAgdmFyIHJlc3QgPSBzbGljZUJ1ZmZlcihkYXRhLCAxKTtcbiAgICAgICAgICAgIGlmIChCbG9iICYmIGJpbmFyeVR5cGUgPT09ICdibG9iJykge1xuICAgICAgICAgICAgICByZXN0ID0gbmV3IEJsb2IoW3Jlc3RdKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7IHR5cGU6IHBhY2tldHNsaXN0W3R5cGVdLCBkYXRhOiByZXN0IH07XG4gICAgICAgICAgfTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIERlY29kZXMgYSBwYWNrZXQgZW5jb2RlZCBpbiBhIGJhc2U2NCBzdHJpbmdcbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBiYXNlNjQgZW5jb2RlZCBtZXNzYWdlXG4gICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSB3aXRoIGB0eXBlYCBhbmQgYGRhdGFgIChpZiBhbnkpXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBleHBvcnRzLmRlY29kZUJhc2U2NFBhY2tldCA9IGZ1bmN0aW9uIChtc2csIGJpbmFyeVR5cGUpIHtcbiAgICAgICAgICAgIHZhciB0eXBlID0gcGFja2V0c2xpc3RbbXNnLmNoYXJBdCgwKV07XG4gICAgICAgICAgICBpZiAoIWdsb2JhbC5BcnJheUJ1ZmZlcikge1xuICAgICAgICAgICAgICByZXR1cm4geyB0eXBlOiB0eXBlLCBkYXRhOiB7IGJhc2U2NDogdHJ1ZSwgZGF0YTogbXNnLnN1YnN0cigxKSB9IH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBkYXRhID0gYmFzZTY0ZW5jb2Rlci5kZWNvZGUobXNnLnN1YnN0cigxKSk7XG5cbiAgICAgICAgICAgIGlmIChiaW5hcnlUeXBlID09PSAnYmxvYicgJiYgQmxvYikge1xuICAgICAgICAgICAgICBkYXRhID0gbmV3IEJsb2IoW2RhdGFdKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHsgdHlwZTogdHlwZSwgZGF0YTogZGF0YSB9O1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBFbmNvZGVzIG11bHRpcGxlIG1lc3NhZ2VzIChwYXlsb2FkKS5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqICAgICA8bGVuZ3RoPjpkYXRhXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBFeGFtcGxlOlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogICAgIDExOmhlbGxvIHdvcmxkMjpoaVxuICAgICAgICAgICAqXG4gICAgICAgICAgICogSWYgYW55IGNvbnRlbnRzIGFyZSBiaW5hcnksIHRoZXkgd2lsbCBiZSBlbmNvZGVkIGFzIGJhc2U2NCBzdHJpbmdzLiBCYXNlNjRcbiAgICAgICAgICAgKiBlbmNvZGVkIHN0cmluZ3MgYXJlIG1hcmtlZCB3aXRoIGEgYiBiZWZvcmUgdGhlIGxlbmd0aCBzcGVjaWZpZXJcbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IHBhY2tldHNcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIGV4cG9ydHMuZW5jb2RlUGF5bG9hZCA9IGZ1bmN0aW9uIChwYWNrZXRzLCBzdXBwb3J0c0JpbmFyeSwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygc3VwcG9ydHNCaW5hcnkgPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICBjYWxsYmFjayA9IHN1cHBvcnRzQmluYXJ5O1xuICAgICAgICAgICAgICBzdXBwb3J0c0JpbmFyeSA9IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBpc0JpbmFyeSA9IGhhc0JpbmFyeShwYWNrZXRzKTtcblxuICAgICAgICAgICAgaWYgKHN1cHBvcnRzQmluYXJ5ICYmIGlzQmluYXJ5KSB7XG4gICAgICAgICAgICAgIGlmIChCbG9iICYmICFkb250U2VuZEJsb2JzKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGV4cG9ydHMuZW5jb2RlUGF5bG9hZEFzQmxvYihwYWNrZXRzLCBjYWxsYmFjayk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICByZXR1cm4gZXhwb3J0cy5lbmNvZGVQYXlsb2FkQXNBcnJheUJ1ZmZlcihwYWNrZXRzLCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghcGFja2V0cy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKCcwOicpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmdW5jdGlvbiBzZXRMZW5ndGhIZWFkZXIobWVzc2FnZSkge1xuICAgICAgICAgICAgICByZXR1cm4gbWVzc2FnZS5sZW5ndGggKyAnOicgKyBtZXNzYWdlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmdW5jdGlvbiBlbmNvZGVPbmUocGFja2V0LCBkb25lQ2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgZXhwb3J0cy5lbmNvZGVQYWNrZXQocGFja2V0LCAhaXNCaW5hcnkgPyBmYWxzZSA6IHN1cHBvcnRzQmluYXJ5LCB0cnVlLCBmdW5jdGlvbiAobWVzc2FnZSkge1xuICAgICAgICAgICAgICAgIGRvbmVDYWxsYmFjayhudWxsLCBzZXRMZW5ndGhIZWFkZXIobWVzc2FnZSkpO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbWFwKHBhY2tldHMsIGVuY29kZU9uZSwgZnVuY3Rpb24gKGVyciwgcmVzdWx0cykge1xuICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2socmVzdWx0cy5qb2luKCcnKSk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogQXN5bmMgYXJyYXkgbWFwIHVzaW5nIGFmdGVyXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBmdW5jdGlvbiBtYXAoYXJ5LCBlYWNoLCBkb25lKSB7XG4gICAgICAgICAgICB2YXIgcmVzdWx0ID0gbmV3IEFycmF5KGFyeS5sZW5ndGgpO1xuICAgICAgICAgICAgdmFyIG5leHQgPSBhZnRlcihhcnkubGVuZ3RoLCBkb25lKTtcblxuICAgICAgICAgICAgdmFyIGVhY2hXaXRoSW5kZXggPSBmdW5jdGlvbiBlYWNoV2l0aEluZGV4KGksIGVsLCBjYikge1xuICAgICAgICAgICAgICBlYWNoKGVsLCBmdW5jdGlvbiAoZXJyb3IsIG1zZykge1xuICAgICAgICAgICAgICAgIHJlc3VsdFtpXSA9IG1zZztcbiAgICAgICAgICAgICAgICBjYihlcnJvciwgcmVzdWx0KTtcbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyeS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICBlYWNoV2l0aEluZGV4KGksIGFyeVtpXSwgbmV4dCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLypcbiAgICAgICAgICAgKiBEZWNvZGVzIGRhdGEgd2hlbiBhIHBheWxvYWQgaXMgbWF5YmUgZXhwZWN0ZWQuIFBvc3NpYmxlIGJpbmFyeSBjb250ZW50cyBhcmVcbiAgICAgICAgICAgKiBkZWNvZGVkIGZyb20gdGhlaXIgYmFzZTY0IHJlcHJlc2VudGF0aW9uXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gZGF0YSwgY2FsbGJhY2sgbWV0aG9kXG4gICAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIGV4cG9ydHMuZGVjb2RlUGF5bG9hZCA9IGZ1bmN0aW9uIChkYXRhLCBiaW5hcnlUeXBlLCBjYWxsYmFjaykge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBkYXRhICE9ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICAgIHJldHVybiBleHBvcnRzLmRlY29kZVBheWxvYWRBc0JpbmFyeShkYXRhLCBiaW5hcnlUeXBlLCBjYWxsYmFjayk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgYmluYXJ5VHlwZSA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICBjYWxsYmFjayA9IGJpbmFyeVR5cGU7XG4gICAgICAgICAgICAgIGJpbmFyeVR5cGUgPSBudWxsO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgcGFja2V0O1xuICAgICAgICAgICAgaWYgKGRhdGEgPT0gJycpIHtcbiAgICAgICAgICAgICAgLy8gcGFyc2VyIGVycm9yIC0gaWdub3JpbmcgcGF5bG9hZFxuICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGxlbmd0aCA9ICcnLFxuICAgICAgICAgICAgICAgIG4sXG4gICAgICAgICAgICAgICAgbXNnO1xuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IGRhdGEubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICAgIHZhciBjaHIgPSBkYXRhLmNoYXJBdChpKTtcblxuICAgICAgICAgICAgICBpZiAoJzonICE9IGNocikge1xuICAgICAgICAgICAgICAgIGxlbmd0aCArPSBjaHI7XG4gICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgaWYgKCcnID09IGxlbmd0aCB8fCBsZW5ndGggIT0gKG4gPSBOdW1iZXIobGVuZ3RoKSkpIHtcbiAgICAgICAgICAgICAgICAgIC8vIHBhcnNlciBlcnJvciAtIGlnbm9yaW5nIHBheWxvYWRcbiAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIsIDAsIDEpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIG1zZyA9IGRhdGEuc3Vic3RyKGkgKyAxLCBuKTtcblxuICAgICAgICAgICAgICAgIGlmIChsZW5ndGggIT0gbXNnLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgLy8gcGFyc2VyIGVycm9yIC0gaWdub3JpbmcgcGF5bG9hZFxuICAgICAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVyciwgMCwgMSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaWYgKG1zZy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgIHBhY2tldCA9IGV4cG9ydHMuZGVjb2RlUGFja2V0KG1zZywgYmluYXJ5VHlwZSwgdHJ1ZSk7XG5cbiAgICAgICAgICAgICAgICAgIGlmIChlcnIudHlwZSA9PSBwYWNrZXQudHlwZSAmJiBlcnIuZGF0YSA9PSBwYWNrZXQuZGF0YSkge1xuICAgICAgICAgICAgICAgICAgICAvLyBwYXJzZXIgZXJyb3IgaW4gaW5kaXZpZHVhbCBwYWNrZXQgLSBpZ25vcmluZyBwYXlsb2FkXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIsIDAsIDEpO1xuICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICB2YXIgcmV0ID0gY2FsbGJhY2socGFja2V0LCBpICsgbiwgbCk7XG4gICAgICAgICAgICAgICAgICBpZiAoZmFsc2UgPT09IHJldCkgcmV0dXJuO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIGFkdmFuY2UgY3Vyc29yXG4gICAgICAgICAgICAgICAgaSArPSBuO1xuICAgICAgICAgICAgICAgIGxlbmd0aCA9ICcnO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChsZW5ndGggIT0gJycpIHtcbiAgICAgICAgICAgICAgLy8gcGFyc2VyIGVycm9yIC0gaWdub3JpbmcgcGF5bG9hZFxuICAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRW5jb2RlcyBtdWx0aXBsZSBtZXNzYWdlcyAocGF5bG9hZCkgYXMgYmluYXJ5LlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogPDEgPSBiaW5hcnksIDAgPSBzdHJpbmc+PG51bWJlciBmcm9tIDAtOT48bnVtYmVyIGZyb20gMC05PlsuLi5dPG51bWJlclxuICAgICAgICAgICAqIDI1NT48ZGF0YT5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEV4YW1wbGU6XG4gICAgICAgICAgICogMSAzIDI1NSAxIDIgMywgaWYgdGhlIGJpbmFyeSBjb250ZW50cyBhcmUgaW50ZXJwcmV0ZWQgYXMgOCBiaXQgaW50ZWdlcnNcbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBwYXJhbSB7QXJyYXl9IHBhY2tldHNcbiAgICAgICAgICAgKiBAcmV0dXJuIHtBcnJheUJ1ZmZlcn0gZW5jb2RlZCBwYXlsb2FkXG4gICAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBleHBvcnRzLmVuY29kZVBheWxvYWRBc0FycmF5QnVmZmVyID0gZnVuY3Rpb24gKHBhY2tldHMsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBpZiAoIXBhY2tldHMubGVuZ3RoKSB7XG4gICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhuZXcgQXJyYXlCdWZmZXIoMCkpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmdW5jdGlvbiBlbmNvZGVPbmUocGFja2V0LCBkb25lQ2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgZXhwb3J0cy5lbmNvZGVQYWNrZXQocGFja2V0LCB0cnVlLCB0cnVlLCBmdW5jdGlvbiAoZGF0YSkge1xuICAgICAgICAgICAgICAgIHJldHVybiBkb25lQ2FsbGJhY2sobnVsbCwgZGF0YSk7XG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBtYXAocGFja2V0cywgZW5jb2RlT25lLCBmdW5jdGlvbiAoZXJyLCBlbmNvZGVkUGFja2V0cykge1xuICAgICAgICAgICAgICB2YXIgdG90YWxMZW5ndGggPSBlbmNvZGVkUGFja2V0cy5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgcCkge1xuICAgICAgICAgICAgICAgIHZhciBsZW47XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBwID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgbGVuID0gcC5sZW5ndGg7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIGxlbiA9IHAuYnl0ZUxlbmd0aDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIGFjYyArIGxlbi50b1N0cmluZygpLmxlbmd0aCArIGxlbiArIDI7IC8vIHN0cmluZy9iaW5hcnkgaWRlbnRpZmllciArIHNlcGFyYXRvciA9IDJcbiAgICAgICAgICAgICAgfSwgMCk7XG5cbiAgICAgICAgICAgICAgdmFyIHJlc3VsdEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkodG90YWxMZW5ndGgpO1xuXG4gICAgICAgICAgICAgIHZhciBidWZmZXJJbmRleCA9IDA7XG4gICAgICAgICAgICAgIGVuY29kZWRQYWNrZXRzLmZvckVhY2goZnVuY3Rpb24gKHApIHtcbiAgICAgICAgICAgICAgICB2YXIgaXNTdHJpbmcgPSB0eXBlb2YgcCA9PT0gJ3N0cmluZyc7XG4gICAgICAgICAgICAgICAgdmFyIGFiID0gcDtcbiAgICAgICAgICAgICAgICBpZiAoaXNTdHJpbmcpIHtcbiAgICAgICAgICAgICAgICAgIHZhciB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkocC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBwLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHZpZXdbaV0gPSBwLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBhYiA9IHZpZXcuYnVmZmVyO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChpc1N0cmluZykge1xuICAgICAgICAgICAgICAgICAgLy8gbm90IHRydWUgYmluYXJ5XG4gICAgICAgICAgICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IDA7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIC8vIHRydWUgYmluYXJ5XG4gICAgICAgICAgICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IDE7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgdmFyIGxlblN0ciA9IGFiLmJ5dGVMZW5ndGgudG9TdHJpbmcoKTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlblN0ci5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgcmVzdWx0QXJyYXlbYnVmZmVySW5kZXgrK10gPSBwYXJzZUludChsZW5TdHJbaV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXN1bHRBcnJheVtidWZmZXJJbmRleCsrXSA9IDI1NTtcblxuICAgICAgICAgICAgICAgIHZhciB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkoYWIpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmlldy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgcmVzdWx0QXJyYXlbYnVmZmVySW5kZXgrK10gPSB2aWV3W2ldO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKHJlc3VsdEFycmF5LmJ1ZmZlcik7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogRW5jb2RlIGFzIEJsb2JcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIGV4cG9ydHMuZW5jb2RlUGF5bG9hZEFzQmxvYiA9IGZ1bmN0aW9uIChwYWNrZXRzLCBjYWxsYmFjaykge1xuICAgICAgICAgICAgZnVuY3Rpb24gZW5jb2RlT25lKHBhY2tldCwgZG9uZUNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgIGV4cG9ydHMuZW5jb2RlUGFja2V0KHBhY2tldCwgdHJ1ZSwgdHJ1ZSwgZnVuY3Rpb24gKGVuY29kZWQpIHtcbiAgICAgICAgICAgICAgICB2YXIgYmluYXJ5SWRlbnRpZmllciA9IG5ldyBVaW50OEFycmF5KDEpO1xuICAgICAgICAgICAgICAgIGJpbmFyeUlkZW50aWZpZXJbMF0gPSAxO1xuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgZW5jb2RlZCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICAgICAgICAgIHZhciB2aWV3ID0gbmV3IFVpbnQ4QXJyYXkoZW5jb2RlZC5sZW5ndGgpO1xuICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbmNvZGVkLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHZpZXdbaV0gPSBlbmNvZGVkLmNoYXJDb2RlQXQoaSk7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBlbmNvZGVkID0gdmlldy5idWZmZXI7XG4gICAgICAgICAgICAgICAgICBiaW5hcnlJZGVudGlmaWVyWzBdID0gMDtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB2YXIgbGVuID0gZW5jb2RlZCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyID8gZW5jb2RlZC5ieXRlTGVuZ3RoIDogZW5jb2RlZC5zaXplO1xuXG4gICAgICAgICAgICAgICAgdmFyIGxlblN0ciA9IGxlbi50b1N0cmluZygpO1xuICAgICAgICAgICAgICAgIHZhciBsZW5ndGhBcnkgPSBuZXcgVWludDhBcnJheShsZW5TdHIubGVuZ3RoICsgMSk7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW5TdHIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgIGxlbmd0aEFyeVtpXSA9IHBhcnNlSW50KGxlblN0cltpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGxlbmd0aEFyeVtsZW5TdHIubGVuZ3RoXSA9IDI1NTtcblxuICAgICAgICAgICAgICAgIGlmIChCbG9iKSB7XG4gICAgICAgICAgICAgICAgICB2YXIgYmxvYiA9IG5ldyBCbG9iKFtiaW5hcnlJZGVudGlmaWVyLmJ1ZmZlciwgbGVuZ3RoQXJ5LmJ1ZmZlciwgZW5jb2RlZF0pO1xuICAgICAgICAgICAgICAgICAgZG9uZUNhbGxiYWNrKG51bGwsIGJsb2IpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG1hcChwYWNrZXRzLCBlbmNvZGVPbmUsIGZ1bmN0aW9uIChlcnIsIHJlc3VsdHMpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG5ldyBCbG9iKHJlc3VsdHMpKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICAvKlxuICAgICAgICAgICAqIERlY29kZXMgZGF0YSB3aGVuIGEgcGF5bG9hZCBpcyBtYXliZSBleHBlY3RlZC4gU3RyaW5ncyBhcmUgZGVjb2RlZCBieVxuICAgICAgICAgICAqIGludGVycHJldGluZyBlYWNoIGJ5dGUgYXMgYSBrZXkgY29kZSBmb3IgZW50cmllcyBtYXJrZWQgdG8gc3RhcnQgd2l0aCAwLiBTZWVcbiAgICAgICAgICAgKiBkZXNjcmlwdGlvbiBvZiBlbmNvZGVQYXlsb2FkQXNCaW5hcnlcbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBwYXJhbSB7QXJyYXlCdWZmZXJ9IGRhdGEsIGNhbGxiYWNrIG1ldGhvZFxuICAgICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBleHBvcnRzLmRlY29kZVBheWxvYWRBc0JpbmFyeSA9IGZ1bmN0aW9uIChkYXRhLCBiaW5hcnlUeXBlLCBjYWxsYmFjaykge1xuICAgICAgICAgICAgaWYgKHR5cGVvZiBiaW5hcnlUeXBlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrID0gYmluYXJ5VHlwZTtcbiAgICAgICAgICAgICAgYmluYXJ5VHlwZSA9IG51bGw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBidWZmZXJUYWlsID0gZGF0YTtcbiAgICAgICAgICAgIHZhciBidWZmZXJzID0gW107XG5cbiAgICAgICAgICAgIHZhciBudW1iZXJUb29Mb25nID0gZmFsc2U7XG4gICAgICAgICAgICB3aGlsZSAoYnVmZmVyVGFpbC5ieXRlTGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICB2YXIgdGFpbEFycmF5ID0gbmV3IFVpbnQ4QXJyYXkoYnVmZmVyVGFpbCk7XG4gICAgICAgICAgICAgIHZhciBpc1N0cmluZyA9IHRhaWxBcnJheVswXSA9PT0gMDtcbiAgICAgICAgICAgICAgdmFyIG1zZ0xlbmd0aCA9ICcnO1xuXG4gICAgICAgICAgICAgIGZvciAodmFyIGkgPSAxOzsgaSsrKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRhaWxBcnJheVtpXSA9PSAyNTUpIGJyZWFrO1xuXG4gICAgICAgICAgICAgICAgaWYgKG1zZ0xlbmd0aC5sZW5ndGggPiAzMTApIHtcbiAgICAgICAgICAgICAgICAgIG51bWJlclRvb0xvbmcgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbXNnTGVuZ3RoICs9IHRhaWxBcnJheVtpXTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChudW1iZXJUb29Mb25nKSByZXR1cm4gY2FsbGJhY2soZXJyLCAwLCAxKTtcblxuICAgICAgICAgICAgICBidWZmZXJUYWlsID0gc2xpY2VCdWZmZXIoYnVmZmVyVGFpbCwgMiArIG1zZ0xlbmd0aC5sZW5ndGgpO1xuICAgICAgICAgICAgICBtc2dMZW5ndGggPSBwYXJzZUludChtc2dMZW5ndGgpO1xuXG4gICAgICAgICAgICAgIHZhciBtc2cgPSBzbGljZUJ1ZmZlcihidWZmZXJUYWlsLCAwLCBtc2dMZW5ndGgpO1xuICAgICAgICAgICAgICBpZiAoaXNTdHJpbmcpIHtcbiAgICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgICAgbXNnID0gU3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLCBuZXcgVWludDhBcnJheShtc2cpKTtcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgICAgICAvLyBpUGhvbmUgU2FmYXJpIGRvZXNuJ3QgbGV0IHlvdSBhcHBseSB0byB0eXBlZCBhcnJheXNcbiAgICAgICAgICAgICAgICAgIHZhciB0eXBlZCA9IG5ldyBVaW50OEFycmF5KG1zZyk7XG4gICAgICAgICAgICAgICAgICBtc2cgPSAnJztcbiAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdHlwZWQubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgbXNnICs9IFN0cmluZy5mcm9tQ2hhckNvZGUodHlwZWRbaV0pO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGJ1ZmZlcnMucHVzaChtc2cpO1xuICAgICAgICAgICAgICBidWZmZXJUYWlsID0gc2xpY2VCdWZmZXIoYnVmZmVyVGFpbCwgbXNnTGVuZ3RoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIHRvdGFsID0gYnVmZmVycy5sZW5ndGg7XG4gICAgICAgICAgICBidWZmZXJzLmZvckVhY2goZnVuY3Rpb24gKGJ1ZmZlciwgaSkge1xuICAgICAgICAgICAgICBjYWxsYmFjayhleHBvcnRzLmRlY29kZVBhY2tldChidWZmZXIsIGJpbmFyeVR5cGUsIHRydWUpLCBpLCB0b3RhbCk7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9O1xuICAgICAgICB9KS5jYWxsKHRoaXMsIHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDoge30pO1xuICAgICAgfSwgeyBcIi4va2V5c1wiOiAyMCwgXCJhZnRlclwiOiAxMSwgXCJhcnJheWJ1ZmZlci5zbGljZVwiOiAxMiwgXCJiYXNlNjQtYXJyYXlidWZmZXJcIjogMTMsIFwiYmxvYlwiOiAxNCwgXCJoYXMtYmluYXJ5XCI6IDIxLCBcInV0ZjhcIjogMjkgfV0sIDIwOiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBHZXRzIHRoZSBrZXlzIGZvciBhbiBvYmplY3QuXG4gICAgICAgICAqXG4gICAgICAgICAqIEByZXR1cm4ge0FycmF5fSBrZXlzXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIGtleXMob2JqKSB7XG4gICAgICAgICAgdmFyIGFyciA9IFtdO1xuICAgICAgICAgIHZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG4gICAgICAgICAgZm9yICh2YXIgaSBpbiBvYmopIHtcbiAgICAgICAgICAgIGlmIChoYXMuY2FsbChvYmosIGkpKSB7XG4gICAgICAgICAgICAgIGFyci5wdXNoKGkpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gYXJyO1xuICAgICAgICB9O1xuICAgICAgfSwge31dLCAyMTogW2Z1bmN0aW9uIChfZGVyZXFfLCBtb2R1bGUsIGV4cG9ydHMpIHtcbiAgICAgICAgKGZ1bmN0aW9uIChnbG9iYWwpIHtcblxuICAgICAgICAgIC8qXG4gICAgICAgICAgICogTW9kdWxlIHJlcXVpcmVtZW50cy5cbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIHZhciBpc0FycmF5ID0gX2RlcmVxXygnaXNhcnJheScpO1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogTW9kdWxlIGV4cG9ydHMuXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGhhc0JpbmFyeTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIENoZWNrcyBmb3IgYmluYXJ5IGRhdGEuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBSaWdodCBub3cgb25seSBCdWZmZXIgYW5kIEFycmF5QnVmZmVyIGFyZSBzdXBwb3J0ZWQuLlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGFueXRoaW5nXG4gICAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIGZ1bmN0aW9uIGhhc0JpbmFyeShkYXRhKSB7XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIF9oYXNCaW5hcnkob2JqKSB7XG4gICAgICAgICAgICAgIGlmICghb2JqKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgICAgICAgaWYgKGdsb2JhbC5CdWZmZXIgJiYgZ2xvYmFsLkJ1ZmZlci5pc0J1ZmZlcihvYmopIHx8IGdsb2JhbC5BcnJheUJ1ZmZlciAmJiBvYmogaW5zdGFuY2VvZiBBcnJheUJ1ZmZlciB8fCBnbG9iYWwuQmxvYiAmJiBvYmogaW5zdGFuY2VvZiBCbG9iIHx8IGdsb2JhbC5GaWxlICYmIG9iaiBpbnN0YW5jZW9mIEZpbGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgaWYgKF9oYXNCaW5hcnkob2JqW2ldKSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAob2JqICYmICdvYmplY3QnID09ICh0eXBlb2Ygb2JqID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6IF90eXBlb2Yob2JqKSkpIHtcbiAgICAgICAgICAgICAgICBpZiAob2JqLnRvSlNPTikge1xuICAgICAgICAgICAgICAgICAgb2JqID0gb2JqLnRvSlNPTigpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgICAgICAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwob2JqLCBrZXkpICYmIF9oYXNCaW5hcnkob2JqW2tleV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIF9oYXNCaW5hcnkoZGF0YSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KS5jYWxsKHRoaXMsIHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDoge30pO1xuICAgICAgfSwgeyBcImlzYXJyYXlcIjogMjQgfV0sIDIyOiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNb2R1bGUgZXhwb3J0cy5cbiAgICAgICAgICpcbiAgICAgICAgICogTG9naWMgYm9ycm93ZWQgZnJvbSBNb2Rlcm5penI6XG4gICAgICAgICAqXG4gICAgICAgICAqICAgLSBodHRwczovL2dpdGh1Yi5jb20vTW9kZXJuaXpyL01vZGVybml6ci9ibG9iL21hc3Rlci9mZWF0dXJlLWRldGVjdHMvY29ycy5qc1xuICAgICAgICAgKi9cblxuICAgICAgICB0cnkge1xuICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gdHlwZW9mIFhNTEh0dHBSZXF1ZXN0ICE9PSAndW5kZWZpbmVkJyAmJiAnd2l0aENyZWRlbnRpYWxzJyBpbiBuZXcgWE1MSHR0cFJlcXVlc3QoKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgLy8gaWYgWE1MSHR0cCBzdXBwb3J0IGlzIGRpc2FibGVkIGluIElFIHRoZW4gaXQgd2lsbCB0aHJvd1xuICAgICAgICAgIC8vIHdoZW4gdHJ5aW5nIHRvIGNyZWF0ZVxuICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0sIHt9XSwgMjM6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG5cbiAgICAgICAgdmFyIGluZGV4T2YgPSBbXS5pbmRleE9mO1xuXG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gKGFyciwgb2JqKSB7XG4gICAgICAgICAgaWYgKGluZGV4T2YpIHJldHVybiBhcnIuaW5kZXhPZihvYmopO1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgICBpZiAoYXJyW2ldID09PSBvYmopIHJldHVybiBpO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH07XG4gICAgICB9LCB7fV0sIDI0OiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24gKGFycikge1xuICAgICAgICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoYXJyKSA9PSAnW29iamVjdCBBcnJheV0nO1xuICAgICAgICB9O1xuICAgICAgfSwge31dLCAyNTogW2Z1bmN0aW9uIChfZGVyZXFfLCBtb2R1bGUsIGV4cG9ydHMpIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIEhlbHBlcnMuXG4gICAgICAgICAqL1xuXG4gICAgICAgIHZhciBzID0gMTAwMDtcbiAgICAgICAgdmFyIG0gPSBzICogNjA7XG4gICAgICAgIHZhciBoID0gbSAqIDYwO1xuICAgICAgICB2YXIgZCA9IGggKiAyNDtcbiAgICAgICAgdmFyIHkgPSBkICogMzY1LjI1O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQYXJzZSBvciBmb3JtYXQgdGhlIGdpdmVuIGB2YWxgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBPcHRpb25zOlxuICAgICAgICAgKlxuICAgICAgICAgKiAgLSBgbG9uZ2AgdmVyYm9zZSBmb3JtYXR0aW5nIFtmYWxzZV1cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd8TnVtYmVyfSB2YWxcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICAgICAgICogQHJldHVybiB7U3RyaW5nfE51bWJlcn1cbiAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICovXG5cbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAodmFsLCBvcHRpb25zKSB7XG4gICAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG4gICAgICAgICAgaWYgKCdzdHJpbmcnID09IHR5cGVvZiB2YWwpIHJldHVybiBwYXJzZSh2YWwpO1xuICAgICAgICAgIHJldHVybiBvcHRpb25zLmxvbmcgPyBsb25nKHZhbCkgOiBzaG9ydCh2YWwpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQYXJzZSB0aGUgZ2l2ZW4gYHN0cmAgYW5kIHJldHVybiBtaWxsaXNlY29uZHMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBzdHJcbiAgICAgICAgICogQHJldHVybiB7TnVtYmVyfVxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgZnVuY3Rpb24gcGFyc2Uoc3RyKSB7XG4gICAgICAgICAgc3RyID0gJycgKyBzdHI7XG4gICAgICAgICAgaWYgKHN0ci5sZW5ndGggPiAxMDAwMCkgcmV0dXJuO1xuICAgICAgICAgIHZhciBtYXRjaCA9IC9eKCg/OlxcZCspP1xcLj9cXGQrKSAqKG1pbGxpc2Vjb25kcz98bXNlY3M/fG1zfHNlY29uZHM/fHNlY3M/fHN8bWludXRlcz98bWlucz98bXxob3Vycz98aHJzP3xofGRheXM/fGR8eWVhcnM/fHlycz98eSk/JC9pLmV4ZWMoc3RyKTtcbiAgICAgICAgICBpZiAoIW1hdGNoKSByZXR1cm47XG4gICAgICAgICAgdmFyIG4gPSBwYXJzZUZsb2F0KG1hdGNoWzFdKTtcbiAgICAgICAgICB2YXIgdHlwZSA9IChtYXRjaFsyXSB8fCAnbXMnKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICAgICAgY2FzZSAneWVhcnMnOlxuICAgICAgICAgICAgY2FzZSAneWVhcic6XG4gICAgICAgICAgICBjYXNlICd5cnMnOlxuICAgICAgICAgICAgY2FzZSAneXInOlxuICAgICAgICAgICAgY2FzZSAneSc6XG4gICAgICAgICAgICAgIHJldHVybiBuICogeTtcbiAgICAgICAgICAgIGNhc2UgJ2RheXMnOlxuICAgICAgICAgICAgY2FzZSAnZGF5JzpcbiAgICAgICAgICAgIGNhc2UgJ2QnOlxuICAgICAgICAgICAgICByZXR1cm4gbiAqIGQ7XG4gICAgICAgICAgICBjYXNlICdob3Vycyc6XG4gICAgICAgICAgICBjYXNlICdob3VyJzpcbiAgICAgICAgICAgIGNhc2UgJ2hycyc6XG4gICAgICAgICAgICBjYXNlICdocic6XG4gICAgICAgICAgICBjYXNlICdoJzpcbiAgICAgICAgICAgICAgcmV0dXJuIG4gKiBoO1xuICAgICAgICAgICAgY2FzZSAnbWludXRlcyc6XG4gICAgICAgICAgICBjYXNlICdtaW51dGUnOlxuICAgICAgICAgICAgY2FzZSAnbWlucyc6XG4gICAgICAgICAgICBjYXNlICdtaW4nOlxuICAgICAgICAgICAgY2FzZSAnbSc6XG4gICAgICAgICAgICAgIHJldHVybiBuICogbTtcbiAgICAgICAgICAgIGNhc2UgJ3NlY29uZHMnOlxuICAgICAgICAgICAgY2FzZSAnc2Vjb25kJzpcbiAgICAgICAgICAgIGNhc2UgJ3NlY3MnOlxuICAgICAgICAgICAgY2FzZSAnc2VjJzpcbiAgICAgICAgICAgIGNhc2UgJ3MnOlxuICAgICAgICAgICAgICByZXR1cm4gbiAqIHM7XG4gICAgICAgICAgICBjYXNlICdtaWxsaXNlY29uZHMnOlxuICAgICAgICAgICAgY2FzZSAnbWlsbGlzZWNvbmQnOlxuICAgICAgICAgICAgY2FzZSAnbXNlY3MnOlxuICAgICAgICAgICAgY2FzZSAnbXNlYyc6XG4gICAgICAgICAgICBjYXNlICdtcyc6XG4gICAgICAgICAgICAgIHJldHVybiBuO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTaG9ydCBmb3JtYXQgZm9yIGBtc2AuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSBtc1xuICAgICAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBmdW5jdGlvbiBzaG9ydChtcykge1xuICAgICAgICAgIGlmIChtcyA+PSBkKSByZXR1cm4gTWF0aC5yb3VuZChtcyAvIGQpICsgJ2QnO1xuICAgICAgICAgIGlmIChtcyA+PSBoKSByZXR1cm4gTWF0aC5yb3VuZChtcyAvIGgpICsgJ2gnO1xuICAgICAgICAgIGlmIChtcyA+PSBtKSByZXR1cm4gTWF0aC5yb3VuZChtcyAvIG0pICsgJ20nO1xuICAgICAgICAgIGlmIChtcyA+PSBzKSByZXR1cm4gTWF0aC5yb3VuZChtcyAvIHMpICsgJ3MnO1xuICAgICAgICAgIHJldHVybiBtcyArICdtcyc7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogTG9uZyBmb3JtYXQgZm9yIGBtc2AuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSBtc1xuICAgICAgICAgKiBAcmV0dXJuIHtTdHJpbmd9XG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBmdW5jdGlvbiBsb25nKG1zKSB7XG4gICAgICAgICAgcmV0dXJuIHBsdXJhbChtcywgZCwgJ2RheScpIHx8IHBsdXJhbChtcywgaCwgJ2hvdXInKSB8fCBwbHVyYWwobXMsIG0sICdtaW51dGUnKSB8fCBwbHVyYWwobXMsIHMsICdzZWNvbmQnKSB8fCBtcyArICcgbXMnO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFBsdXJhbGl6YXRpb24gaGVscGVyLlxuICAgICAgICAgKi9cblxuICAgICAgICBmdW5jdGlvbiBwbHVyYWwobXMsIG4sIG5hbWUpIHtcbiAgICAgICAgICBpZiAobXMgPCBuKSByZXR1cm47XG4gICAgICAgICAgaWYgKG1zIDwgbiAqIDEuNSkgcmV0dXJuIE1hdGguZmxvb3IobXMgLyBuKSArICcgJyArIG5hbWU7XG4gICAgICAgICAgcmV0dXJuIE1hdGguY2VpbChtcyAvIG4pICsgJyAnICsgbmFtZSArICdzJztcbiAgICAgICAgfVxuICAgICAgfSwge31dLCAyNjogW2Z1bmN0aW9uIChfZGVyZXFfLCBtb2R1bGUsIGV4cG9ydHMpIHtcbiAgICAgICAgKGZ1bmN0aW9uIChnbG9iYWwpIHtcbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBKU09OIHBhcnNlLlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQHNlZSBCYXNlZCBvbiBqUXVlcnkjcGFyc2VKU09OIChNSVQpIGFuZCBKU09OMlxuICAgICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgdmFyIHJ2YWxpZGNoYXJzID0gL15bXFxdLDp7fVxcc10qJC87XG4gICAgICAgICAgdmFyIHJ2YWxpZGVzY2FwZSA9IC9cXFxcKD86W1wiXFxcXFxcL2JmbnJ0XXx1WzAtOWEtZkEtRl17NH0pL2c7XG4gICAgICAgICAgdmFyIHJ2YWxpZHRva2VucyA9IC9cIlteXCJcXFxcXFxuXFxyXSpcInx0cnVlfGZhbHNlfG51bGx8LT9cXGQrKD86XFwuXFxkKik/KD86W2VFXVsrXFwtXT9cXGQrKT8vZztcbiAgICAgICAgICB2YXIgcnZhbGlkYnJhY2VzID0gLyg/Ol58OnwsKSg/OlxccypcXFspKy9nO1xuICAgICAgICAgIHZhciBydHJpbUxlZnQgPSAvXlxccysvO1xuICAgICAgICAgIHZhciBydHJpbVJpZ2h0ID0gL1xccyskLztcblxuICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gcGFyc2Vqc29uKGRhdGEpIHtcbiAgICAgICAgICAgIGlmICgnc3RyaW5nJyAhPSB0eXBlb2YgZGF0YSB8fCAhZGF0YSkge1xuICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZGF0YSA9IGRhdGEucmVwbGFjZShydHJpbUxlZnQsICcnKS5yZXBsYWNlKHJ0cmltUmlnaHQsICcnKTtcblxuICAgICAgICAgICAgLy8gQXR0ZW1wdCB0byBwYXJzZSB1c2luZyB0aGUgbmF0aXZlIEpTT04gcGFyc2VyIGZpcnN0XG4gICAgICAgICAgICBpZiAoZ2xvYmFsLkpTT04gJiYgSlNPTi5wYXJzZSkge1xuICAgICAgICAgICAgICByZXR1cm4gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKHJ2YWxpZGNoYXJzLnRlc3QoZGF0YS5yZXBsYWNlKHJ2YWxpZGVzY2FwZSwgJ0AnKS5yZXBsYWNlKHJ2YWxpZHRva2VucywgJ10nKS5yZXBsYWNlKHJ2YWxpZGJyYWNlcywgJycpKSkge1xuICAgICAgICAgICAgICByZXR1cm4gbmV3IEZ1bmN0aW9uKCdyZXR1cm4gJyArIGRhdGEpKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgfSkuY2FsbCh0aGlzLCB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHt9KTtcbiAgICAgIH0sIHt9XSwgMjc6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDb21waWxlcyBhIHF1ZXJ5c3RyaW5nXG4gICAgICAgICAqIFJldHVybnMgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBvYmplY3RcbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9XG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBleHBvcnRzLmVuY29kZSA9IGZ1bmN0aW9uIChvYmopIHtcbiAgICAgICAgICB2YXIgc3RyID0gJyc7XG5cbiAgICAgICAgICBmb3IgKHZhciBpIGluIG9iaikge1xuICAgICAgICAgICAgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShpKSkge1xuICAgICAgICAgICAgICBpZiAoc3RyLmxlbmd0aCkgc3RyICs9ICcmJztcbiAgICAgICAgICAgICAgc3RyICs9IGVuY29kZVVSSUNvbXBvbmVudChpKSArICc9JyArIGVuY29kZVVSSUNvbXBvbmVudChvYmpbaV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBzdHI7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFBhcnNlcyBhIHNpbXBsZSBxdWVyeXN0cmluZyBpbnRvIGFuIG9iamVjdFxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gcXNcbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIGV4cG9ydHMuZGVjb2RlID0gZnVuY3Rpb24gKHFzKSB7XG4gICAgICAgICAgdmFyIHFyeSA9IHt9O1xuICAgICAgICAgIHZhciBwYWlycyA9IHFzLnNwbGl0KCcmJyk7XG4gICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGwgPSBwYWlycy5sZW5ndGg7IGkgPCBsOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBwYWlyID0gcGFpcnNbaV0uc3BsaXQoJz0nKTtcbiAgICAgICAgICAgIHFyeVtkZWNvZGVVUklDb21wb25lbnQocGFpclswXSldID0gZGVjb2RlVVJJQ29tcG9uZW50KHBhaXJbMV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gcXJ5O1xuICAgICAgICB9O1xuICAgICAgfSwge31dLCAyODogW2Z1bmN0aW9uIChfZGVyZXFfLCBtb2R1bGUsIGV4cG9ydHMpIHtcbiAgICAgICAgLyoqXG4gICAgICAgICAqIFBhcnNlcyBhbiBVUklcbiAgICAgICAgICpcbiAgICAgICAgICogQGF1dGhvciBTdGV2ZW4gTGV2aXRoYW4gPHN0ZXZlbmxldml0aGFuLmNvbT4gKE1JVCBsaWNlbnNlKVxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgdmFyIHJlID0gL14oPzooPyFbXjpAXSs6W146QFxcL10qQCkoaHR0cHxodHRwc3x3c3x3c3MpOlxcL1xcLyk/KCg/OigoW146QF0qKSg/OjooW146QF0qKSk/KT9AKT8oKD86W2EtZjAtOV17MCw0fTopezIsN31bYS1mMC05XXswLDR9fFteOlxcLz8jXSopKD86OihcXGQqKSk/KSgoKFxcLyg/OltePyNdKD8hW14/I1xcL10qXFwuW14/I1xcLy5dKyg/Ols/I118JCkpKSpcXC8/KT8oW14/I1xcL10qKSkoPzpcXD8oW14jXSopKT8oPzojKC4qKSk/KS87XG5cbiAgICAgICAgdmFyIHBhcnRzID0gWydzb3VyY2UnLCAncHJvdG9jb2wnLCAnYXV0aG9yaXR5JywgJ3VzZXJJbmZvJywgJ3VzZXInLCAncGFzc3dvcmQnLCAnaG9zdCcsICdwb3J0JywgJ3JlbGF0aXZlJywgJ3BhdGgnLCAnZGlyZWN0b3J5JywgJ2ZpbGUnLCAncXVlcnknLCAnYW5jaG9yJ107XG5cbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBwYXJzZXVyaShzdHIpIHtcbiAgICAgICAgICB2YXIgc3JjID0gc3RyLFxuICAgICAgICAgICAgICBiID0gc3RyLmluZGV4T2YoJ1snKSxcbiAgICAgICAgICAgICAgZSA9IHN0ci5pbmRleE9mKCddJyk7XG5cbiAgICAgICAgICBpZiAoYiAhPSAtMSAmJiBlICE9IC0xKSB7XG4gICAgICAgICAgICBzdHIgPSBzdHIuc3Vic3RyaW5nKDAsIGIpICsgc3RyLnN1YnN0cmluZyhiLCBlKS5yZXBsYWNlKC86L2csICc7JykgKyBzdHIuc3Vic3RyaW5nKGUsIHN0ci5sZW5ndGgpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHZhciBtID0gcmUuZXhlYyhzdHIgfHwgJycpLFxuICAgICAgICAgICAgICB1cmkgPSB7fSxcbiAgICAgICAgICAgICAgaSA9IDE0O1xuXG4gICAgICAgICAgd2hpbGUgKGktLSkge1xuICAgICAgICAgICAgdXJpW3BhcnRzW2ldXSA9IG1baV0gfHwgJyc7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGIgIT0gLTEgJiYgZSAhPSAtMSkge1xuICAgICAgICAgICAgdXJpLnNvdXJjZSA9IHNyYztcbiAgICAgICAgICAgIHVyaS5ob3N0ID0gdXJpLmhvc3Quc3Vic3RyaW5nKDEsIHVyaS5ob3N0Lmxlbmd0aCAtIDEpLnJlcGxhY2UoLzsvZywgJzonKTtcbiAgICAgICAgICAgIHVyaS5hdXRob3JpdHkgPSB1cmkuYXV0aG9yaXR5LnJlcGxhY2UoJ1snLCAnJykucmVwbGFjZSgnXScsICcnKS5yZXBsYWNlKC87L2csICc6Jyk7XG4gICAgICAgICAgICB1cmkuaXB2NnVyaSA9IHRydWU7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHVyaTtcbiAgICAgICAgfTtcbiAgICAgIH0sIHt9XSwgMjk6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG4gICAgICAgIChmdW5jdGlvbiAoZ2xvYmFsKSB7XG4gICAgICAgICAgLyohIGh0dHBzOi8vbXRocy5iZS91dGY4anMgdjIuMC4wIGJ5IEBtYXRoaWFzICovXG4gICAgICAgICAgOyhmdW5jdGlvbiAocm9vdCkge1xuXG4gICAgICAgICAgICAvLyBEZXRlY3QgZnJlZSB2YXJpYWJsZXMgYGV4cG9ydHNgXG4gICAgICAgICAgICB2YXIgZnJlZUV4cG9ydHMgPSAodHlwZW9mIGV4cG9ydHMgPT09IFwidW5kZWZpbmVkXCIgPyBcInVuZGVmaW5lZFwiIDogX3R5cGVvZihleHBvcnRzKSkgPT0gJ29iamVjdCcgJiYgZXhwb3J0cztcblxuICAgICAgICAgICAgLy8gRGV0ZWN0IGZyZWUgdmFyaWFibGUgYG1vZHVsZWBcbiAgICAgICAgICAgIHZhciBmcmVlTW9kdWxlID0gKHR5cGVvZiBtb2R1bGUgPT09IFwidW5kZWZpbmVkXCIgPyBcInVuZGVmaW5lZFwiIDogX3R5cGVvZihtb2R1bGUpKSA9PSAnb2JqZWN0JyAmJiBtb2R1bGUgJiYgbW9kdWxlLmV4cG9ydHMgPT0gZnJlZUV4cG9ydHMgJiYgbW9kdWxlO1xuXG4gICAgICAgICAgICAvLyBEZXRlY3QgZnJlZSB2YXJpYWJsZSBgZ2xvYmFsYCwgZnJvbSBOb2RlLmpzIG9yIEJyb3dzZXJpZmllZCBjb2RlLFxuICAgICAgICAgICAgLy8gYW5kIHVzZSBpdCBhcyBgcm9vdGBcbiAgICAgICAgICAgIHZhciBmcmVlR2xvYmFsID0gKHR5cGVvZiBnbG9iYWwgPT09IFwidW5kZWZpbmVkXCIgPyBcInVuZGVmaW5lZFwiIDogX3R5cGVvZihnbG9iYWwpKSA9PSAnb2JqZWN0JyAmJiBnbG9iYWw7XG4gICAgICAgICAgICBpZiAoZnJlZUdsb2JhbC5nbG9iYWwgPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbC53aW5kb3cgPT09IGZyZWVHbG9iYWwpIHtcbiAgICAgICAgICAgICAgcm9vdCA9IGZyZWVHbG9iYWw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qL1xuXG4gICAgICAgICAgICB2YXIgc3RyaW5nRnJvbUNoYXJDb2RlID0gU3RyaW5nLmZyb21DaGFyQ29kZTtcblxuICAgICAgICAgICAgLy8gVGFrZW4gZnJvbSBodHRwczovL210aHMuYmUvcHVueWNvZGVcbiAgICAgICAgICAgIGZ1bmN0aW9uIHVjczJkZWNvZGUoc3RyaW5nKSB7XG4gICAgICAgICAgICAgIHZhciBvdXRwdXQgPSBbXTtcbiAgICAgICAgICAgICAgdmFyIGNvdW50ZXIgPSAwO1xuICAgICAgICAgICAgICB2YXIgbGVuZ3RoID0gc3RyaW5nLmxlbmd0aDtcbiAgICAgICAgICAgICAgdmFyIHZhbHVlO1xuICAgICAgICAgICAgICB2YXIgZXh0cmE7XG4gICAgICAgICAgICAgIHdoaWxlIChjb3VudGVyIDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBzdHJpbmcuY2hhckNvZGVBdChjb3VudGVyKyspO1xuICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA+PSAweEQ4MDAgJiYgdmFsdWUgPD0gMHhEQkZGICYmIGNvdW50ZXIgPCBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICAgIC8vIGhpZ2ggc3Vycm9nYXRlLCBhbmQgdGhlcmUgaXMgYSBuZXh0IGNoYXJhY3RlclxuICAgICAgICAgICAgICAgICAgZXh0cmEgPSBzdHJpbmcuY2hhckNvZGVBdChjb3VudGVyKyspO1xuICAgICAgICAgICAgICAgICAgaWYgKChleHRyYSAmIDB4RkMwMCkgPT0gMHhEQzAwKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIGxvdyBzdXJyb2dhdGVcbiAgICAgICAgICAgICAgICAgICAgb3V0cHV0LnB1c2goKCh2YWx1ZSAmIDB4M0ZGKSA8PCAxMCkgKyAoZXh0cmEgJiAweDNGRikgKyAweDEwMDAwKTtcbiAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHVubWF0Y2hlZCBzdXJyb2dhdGU7IG9ubHkgYXBwZW5kIHRoaXMgY29kZSB1bml0LCBpbiBjYXNlIHRoZSBuZXh0XG4gICAgICAgICAgICAgICAgICAgIC8vIGNvZGUgdW5pdCBpcyB0aGUgaGlnaCBzdXJyb2dhdGUgb2YgYSBzdXJyb2dhdGUgcGFpclxuICAgICAgICAgICAgICAgICAgICBvdXRwdXQucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIGNvdW50ZXItLTtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgb3V0cHV0LnB1c2godmFsdWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gb3V0cHV0O1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBUYWtlbiBmcm9tIGh0dHBzOi8vbXRocy5iZS9wdW55Y29kZVxuICAgICAgICAgICAgZnVuY3Rpb24gdWNzMmVuY29kZShhcnJheSkge1xuICAgICAgICAgICAgICB2YXIgbGVuZ3RoID0gYXJyYXkubGVuZ3RoO1xuICAgICAgICAgICAgICB2YXIgaW5kZXggPSAtMTtcbiAgICAgICAgICAgICAgdmFyIHZhbHVlO1xuICAgICAgICAgICAgICB2YXIgb3V0cHV0ID0gJyc7XG4gICAgICAgICAgICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgdmFsdWUgPSBhcnJheVtpbmRleF07XG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlID4gMHhGRkZGKSB7XG4gICAgICAgICAgICAgICAgICB2YWx1ZSAtPSAweDEwMDAwO1xuICAgICAgICAgICAgICAgICAgb3V0cHV0ICs9IHN0cmluZ0Zyb21DaGFyQ29kZSh2YWx1ZSA+Pj4gMTAgJiAweDNGRiB8IDB4RDgwMCk7XG4gICAgICAgICAgICAgICAgICB2YWx1ZSA9IDB4REMwMCB8IHZhbHVlICYgMHgzRkY7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG91dHB1dCArPSBzdHJpbmdGcm9tQ2hhckNvZGUodmFsdWUpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBvdXRwdXQ7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIGNoZWNrU2NhbGFyVmFsdWUoY29kZVBvaW50KSB7XG4gICAgICAgICAgICAgIGlmIChjb2RlUG9pbnQgPj0gMHhEODAwICYmIGNvZGVQb2ludCA8PSAweERGRkYpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcignTG9uZSBzdXJyb2dhdGUgVSsnICsgY29kZVBvaW50LnRvU3RyaW5nKDE2KS50b1VwcGVyQ2FzZSgpICsgJyBpcyBub3QgYSBzY2FsYXIgdmFsdWUnKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIGNyZWF0ZUJ5dGUoY29kZVBvaW50LCBzaGlmdCkge1xuICAgICAgICAgICAgICByZXR1cm4gc3RyaW5nRnJvbUNoYXJDb2RlKGNvZGVQb2ludCA+PiBzaGlmdCAmIDB4M0YgfCAweDgwKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZnVuY3Rpb24gZW5jb2RlQ29kZVBvaW50KGNvZGVQb2ludCkge1xuICAgICAgICAgICAgICBpZiAoKGNvZGVQb2ludCAmIDB4RkZGRkZGODApID09IDApIHtcbiAgICAgICAgICAgICAgICAvLyAxLWJ5dGUgc2VxdWVuY2VcbiAgICAgICAgICAgICAgICByZXR1cm4gc3RyaW5nRnJvbUNoYXJDb2RlKGNvZGVQb2ludCk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgdmFyIHN5bWJvbCA9ICcnO1xuICAgICAgICAgICAgICBpZiAoKGNvZGVQb2ludCAmIDB4RkZGRkY4MDApID09IDApIHtcbiAgICAgICAgICAgICAgICAvLyAyLWJ5dGUgc2VxdWVuY2VcbiAgICAgICAgICAgICAgICBzeW1ib2wgPSBzdHJpbmdGcm9tQ2hhckNvZGUoY29kZVBvaW50ID4+IDYgJiAweDFGIHwgMHhDMCk7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoKGNvZGVQb2ludCAmIDB4RkZGRjAwMDApID09IDApIHtcbiAgICAgICAgICAgICAgICAvLyAzLWJ5dGUgc2VxdWVuY2VcbiAgICAgICAgICAgICAgICBjaGVja1NjYWxhclZhbHVlKGNvZGVQb2ludCk7XG4gICAgICAgICAgICAgICAgc3ltYm9sID0gc3RyaW5nRnJvbUNoYXJDb2RlKGNvZGVQb2ludCA+PiAxMiAmIDB4MEYgfCAweEUwKTtcbiAgICAgICAgICAgICAgICBzeW1ib2wgKz0gY3JlYXRlQnl0ZShjb2RlUG9pbnQsIDYpO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKChjb2RlUG9pbnQgJiAweEZGRTAwMDAwKSA9PSAwKSB7XG4gICAgICAgICAgICAgICAgLy8gNC1ieXRlIHNlcXVlbmNlXG4gICAgICAgICAgICAgICAgc3ltYm9sID0gc3RyaW5nRnJvbUNoYXJDb2RlKGNvZGVQb2ludCA+PiAxOCAmIDB4MDcgfCAweEYwKTtcbiAgICAgICAgICAgICAgICBzeW1ib2wgKz0gY3JlYXRlQnl0ZShjb2RlUG9pbnQsIDEyKTtcbiAgICAgICAgICAgICAgICBzeW1ib2wgKz0gY3JlYXRlQnl0ZShjb2RlUG9pbnQsIDYpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHN5bWJvbCArPSBzdHJpbmdGcm9tQ2hhckNvZGUoY29kZVBvaW50ICYgMHgzRiB8IDB4ODApO1xuICAgICAgICAgICAgICByZXR1cm4gc3ltYm9sO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmdW5jdGlvbiB1dGY4ZW5jb2RlKHN0cmluZykge1xuICAgICAgICAgICAgICB2YXIgY29kZVBvaW50cyA9IHVjczJkZWNvZGUoc3RyaW5nKTtcbiAgICAgICAgICAgICAgdmFyIGxlbmd0aCA9IGNvZGVQb2ludHMubGVuZ3RoO1xuICAgICAgICAgICAgICB2YXIgaW5kZXggPSAtMTtcbiAgICAgICAgICAgICAgdmFyIGNvZGVQb2ludDtcbiAgICAgICAgICAgICAgdmFyIGJ5dGVTdHJpbmcgPSAnJztcbiAgICAgICAgICAgICAgd2hpbGUgKCsraW5kZXggPCBsZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBjb2RlUG9pbnQgPSBjb2RlUG9pbnRzW2luZGV4XTtcbiAgICAgICAgICAgICAgICBieXRlU3RyaW5nICs9IGVuY29kZUNvZGVQb2ludChjb2RlUG9pbnQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBieXRlU3RyaW5nO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi9cblxuICAgICAgICAgICAgZnVuY3Rpb24gcmVhZENvbnRpbnVhdGlvbkJ5dGUoKSB7XG4gICAgICAgICAgICAgIGlmIChieXRlSW5kZXggPj0gYnl0ZUNvdW50KSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgRXJyb3IoJ0ludmFsaWQgYnl0ZSBpbmRleCcpO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgdmFyIGNvbnRpbnVhdGlvbkJ5dGUgPSBieXRlQXJyYXlbYnl0ZUluZGV4XSAmIDB4RkY7XG4gICAgICAgICAgICAgIGJ5dGVJbmRleCsrO1xuXG4gICAgICAgICAgICAgIGlmICgoY29udGludWF0aW9uQnl0ZSAmIDB4QzApID09IDB4ODApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gY29udGludWF0aW9uQnl0ZSAmIDB4M0Y7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBJZiB3ZSBlbmQgdXAgaGVyZSwgaXTigJlzIG5vdCBhIGNvbnRpbnVhdGlvbiBieXRlXG4gICAgICAgICAgICAgIHRocm93IEVycm9yKCdJbnZhbGlkIGNvbnRpbnVhdGlvbiBieXRlJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIGRlY29kZVN5bWJvbCgpIHtcbiAgICAgICAgICAgICAgdmFyIGJ5dGUxO1xuICAgICAgICAgICAgICB2YXIgYnl0ZTI7XG4gICAgICAgICAgICAgIHZhciBieXRlMztcbiAgICAgICAgICAgICAgdmFyIGJ5dGU0O1xuICAgICAgICAgICAgICB2YXIgY29kZVBvaW50O1xuXG4gICAgICAgICAgICAgIGlmIChieXRlSW5kZXggPiBieXRlQ291bnQpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcignSW52YWxpZCBieXRlIGluZGV4Jyk7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoYnl0ZUluZGV4ID09IGJ5dGVDb3VudCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIFJlYWQgZmlyc3QgYnl0ZVxuICAgICAgICAgICAgICBieXRlMSA9IGJ5dGVBcnJheVtieXRlSW5kZXhdICYgMHhGRjtcbiAgICAgICAgICAgICAgYnl0ZUluZGV4Kys7XG5cbiAgICAgICAgICAgICAgLy8gMS1ieXRlIHNlcXVlbmNlIChubyBjb250aW51YXRpb24gYnl0ZXMpXG4gICAgICAgICAgICAgIGlmICgoYnl0ZTEgJiAweDgwKSA9PSAwKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGJ5dGUxO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgLy8gMi1ieXRlIHNlcXVlbmNlXG4gICAgICAgICAgICAgIGlmICgoYnl0ZTEgJiAweEUwKSA9PSAweEMwKSB7XG4gICAgICAgICAgICAgICAgdmFyIGJ5dGUyID0gcmVhZENvbnRpbnVhdGlvbkJ5dGUoKTtcbiAgICAgICAgICAgICAgICBjb2RlUG9pbnQgPSAoYnl0ZTEgJiAweDFGKSA8PCA2IHwgYnl0ZTI7XG4gICAgICAgICAgICAgICAgaWYgKGNvZGVQb2ludCA+PSAweDgwKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gY29kZVBvaW50O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcignSW52YWxpZCBjb250aW51YXRpb24gYnl0ZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIDMtYnl0ZSBzZXF1ZW5jZSAobWF5IGluY2x1ZGUgdW5wYWlyZWQgc3Vycm9nYXRlcylcbiAgICAgICAgICAgICAgaWYgKChieXRlMSAmIDB4RjApID09IDB4RTApIHtcbiAgICAgICAgICAgICAgICBieXRlMiA9IHJlYWRDb250aW51YXRpb25CeXRlKCk7XG4gICAgICAgICAgICAgICAgYnl0ZTMgPSByZWFkQ29udGludWF0aW9uQnl0ZSgpO1xuICAgICAgICAgICAgICAgIGNvZGVQb2ludCA9IChieXRlMSAmIDB4MEYpIDw8IDEyIHwgYnl0ZTIgPDwgNiB8IGJ5dGUzO1xuICAgICAgICAgICAgICAgIGlmIChjb2RlUG9pbnQgPj0gMHgwODAwKSB7XG4gICAgICAgICAgICAgICAgICBjaGVja1NjYWxhclZhbHVlKGNvZGVQb2ludCk7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gY29kZVBvaW50O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICB0aHJvdyBFcnJvcignSW52YWxpZCBjb250aW51YXRpb24gYnl0ZScpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIC8vIDQtYnl0ZSBzZXF1ZW5jZVxuICAgICAgICAgICAgICBpZiAoKGJ5dGUxICYgMHhGOCkgPT0gMHhGMCkge1xuICAgICAgICAgICAgICAgIGJ5dGUyID0gcmVhZENvbnRpbnVhdGlvbkJ5dGUoKTtcbiAgICAgICAgICAgICAgICBieXRlMyA9IHJlYWRDb250aW51YXRpb25CeXRlKCk7XG4gICAgICAgICAgICAgICAgYnl0ZTQgPSByZWFkQ29udGludWF0aW9uQnl0ZSgpO1xuICAgICAgICAgICAgICAgIGNvZGVQb2ludCA9IChieXRlMSAmIDB4MEYpIDw8IDB4MTIgfCBieXRlMiA8PCAweDBDIHwgYnl0ZTMgPDwgMHgwNiB8IGJ5dGU0O1xuICAgICAgICAgICAgICAgIGlmIChjb2RlUG9pbnQgPj0gMHgwMTAwMDAgJiYgY29kZVBvaW50IDw9IDB4MTBGRkZGKSB7XG4gICAgICAgICAgICAgICAgICByZXR1cm4gY29kZVBvaW50O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIHRocm93IEVycm9yKCdJbnZhbGlkIFVURi04IGRldGVjdGVkJyk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBieXRlQXJyYXk7XG4gICAgICAgICAgICB2YXIgYnl0ZUNvdW50O1xuICAgICAgICAgICAgdmFyIGJ5dGVJbmRleDtcbiAgICAgICAgICAgIGZ1bmN0aW9uIHV0ZjhkZWNvZGUoYnl0ZVN0cmluZykge1xuICAgICAgICAgICAgICBieXRlQXJyYXkgPSB1Y3MyZGVjb2RlKGJ5dGVTdHJpbmcpO1xuICAgICAgICAgICAgICBieXRlQ291bnQgPSBieXRlQXJyYXkubGVuZ3RoO1xuICAgICAgICAgICAgICBieXRlSW5kZXggPSAwO1xuICAgICAgICAgICAgICB2YXIgY29kZVBvaW50cyA9IFtdO1xuICAgICAgICAgICAgICB2YXIgdG1wO1xuICAgICAgICAgICAgICB3aGlsZSAoKHRtcCA9IGRlY29kZVN5bWJvbCgpKSAhPT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBjb2RlUG9pbnRzLnB1c2godG1wKTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gdWNzMmVuY29kZShjb2RlUG9pbnRzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovXG5cbiAgICAgICAgICAgIHZhciB1dGY4ID0ge1xuICAgICAgICAgICAgICAndmVyc2lvbic6ICcyLjAuMCcsXG4gICAgICAgICAgICAgICdlbmNvZGUnOiB1dGY4ZW5jb2RlLFxuICAgICAgICAgICAgICAnZGVjb2RlJzogdXRmOGRlY29kZVxuICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgLy8gU29tZSBBTUQgYnVpbGQgb3B0aW1pemVycywgbGlrZSByLmpzLCBjaGVjayBmb3Igc3BlY2lmaWMgY29uZGl0aW9uIHBhdHRlcm5zXG4gICAgICAgICAgICAvLyBsaWtlIHRoZSBmb2xsb3dpbmc6XG4gICAgICAgICAgICBpZiAodHlwZW9mIGRlZmluZSA9PSAnZnVuY3Rpb24nICYmIF90eXBlb2YoZGVmaW5lLmFtZCkgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xuICAgICAgICAgICAgICBkZWZpbmUoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICAgIHJldHVybiB1dGY4O1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZnJlZUV4cG9ydHMgJiYgIWZyZWVFeHBvcnRzLm5vZGVUeXBlKSB7XG4gICAgICAgICAgICAgIGlmIChmcmVlTW9kdWxlKSB7XG4gICAgICAgICAgICAgICAgLy8gaW4gTm9kZS5qcyBvciBSaW5nb0pTIHYwLjguMCtcbiAgICAgICAgICAgICAgICBmcmVlTW9kdWxlLmV4cG9ydHMgPSB1dGY4O1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIC8vIGluIE5hcndoYWwgb3IgUmluZ29KUyB2MC43LjAtXG4gICAgICAgICAgICAgICAgdmFyIG9iamVjdCA9IHt9O1xuICAgICAgICAgICAgICAgIHZhciBoYXNPd25Qcm9wZXJ0eSA9IG9iamVjdC5oYXNPd25Qcm9wZXJ0eTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gdXRmOCkge1xuICAgICAgICAgICAgICAgICAgaGFzT3duUHJvcGVydHkuY2FsbCh1dGY4LCBrZXkpICYmIChmcmVlRXhwb3J0c1trZXldID0gdXRmOFtrZXldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIGluIFJoaW5vIG9yIGEgd2ViIGJyb3dzZXJcbiAgICAgICAgICAgICAgcm9vdC51dGY4ID0gdXRmODtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KSh0aGlzKTtcbiAgICAgICAgfSkuY2FsbCh0aGlzLCB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHt9KTtcbiAgICAgIH0sIHt9XSwgMzA6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG4gICAgICAgICd1c2Ugc3RyaWN0JztcblxuICAgICAgICB2YXIgYWxwaGFiZXQgPSAnMDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXotXycuc3BsaXQoJycpLFxuICAgICAgICAgICAgbGVuZ3RoID0gNjQsXG4gICAgICAgICAgICBtYXAgPSB7fSxcbiAgICAgICAgICAgIHNlZWQgPSAwLFxuICAgICAgICAgICAgaSA9IDAsXG4gICAgICAgICAgICBwcmV2O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXR1cm4gYSBzdHJpbmcgcmVwcmVzZW50aW5nIHRoZSBzcGVjaWZpZWQgbnVtYmVyLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gbnVtIFRoZSBudW1iZXIgdG8gY29udmVydC5cbiAgICAgICAgICogQHJldHVybnMge1N0cmluZ30gVGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgbnVtYmVyLlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZW5jb2RlKG51bSkge1xuICAgICAgICAgIHZhciBlbmNvZGVkID0gJyc7XG5cbiAgICAgICAgICBkbyB7XG4gICAgICAgICAgICBlbmNvZGVkID0gYWxwaGFiZXRbbnVtICUgbGVuZ3RoXSArIGVuY29kZWQ7XG4gICAgICAgICAgICBudW0gPSBNYXRoLmZsb29yKG51bSAvIGxlbmd0aCk7XG4gICAgICAgICAgfSB3aGlsZSAobnVtID4gMCk7XG5cbiAgICAgICAgICByZXR1cm4gZW5jb2RlZDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBSZXR1cm4gdGhlIGludGVnZXIgdmFsdWUgc3BlY2lmaWVkIGJ5IHRoZSBnaXZlbiBzdHJpbmcuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgVGhlIHN0cmluZyB0byBjb252ZXJ0LlxuICAgICAgICAgKiBAcmV0dXJucyB7TnVtYmVyfSBUaGUgaW50ZWdlciB2YWx1ZSByZXByZXNlbnRlZCBieSB0aGUgc3RyaW5nLlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24gZGVjb2RlKHN0cikge1xuICAgICAgICAgIHZhciBkZWNvZGVkID0gMDtcblxuICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGRlY29kZWQgPSBkZWNvZGVkICogbGVuZ3RoICsgbWFwW3N0ci5jaGFyQXQoaSldO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBkZWNvZGVkO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFllYXN0OiBBIHRpbnkgZ3Jvd2luZyBpZCBnZW5lcmF0b3IuXG4gICAgICAgICAqXG4gICAgICAgICAqIEByZXR1cm5zIHtTdHJpbmd9IEEgdW5pcXVlIGlkLlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cbiAgICAgICAgZnVuY3Rpb24geWVhc3QoKSB7XG4gICAgICAgICAgdmFyIG5vdyA9IGVuY29kZSgrbmV3IERhdGUoKSk7XG5cbiAgICAgICAgICBpZiAobm93ICE9PSBwcmV2KSByZXR1cm4gc2VlZCA9IDAsIHByZXYgPSBub3c7XG4gICAgICAgICAgcmV0dXJuIG5vdyArICcuJyArIGVuY29kZShzZWVkKyspO1xuICAgICAgICB9XG5cbiAgICAgICAgLy9cbiAgICAgICAgLy8gTWFwIGVhY2ggY2hhcmFjdGVyIHRvIGl0cyBpbmRleC5cbiAgICAgICAgLy9cbiAgICAgICAgZm9yICg7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgICAgIG1hcFthbHBoYWJldFtpXV0gPSBpO1xuICAgICAgICB9IC8vXG4gICAgICAgIC8vIEV4cG9zZSB0aGUgYHllYXN0YCwgYGVuY29kZWAgYW5kIGBkZWNvZGVgIGZ1bmN0aW9ucy5cbiAgICAgICAgLy9cbiAgICAgICAgeWVhc3QuZW5jb2RlID0gZW5jb2RlO1xuICAgICAgICB5ZWFzdC5kZWNvZGUgPSBkZWNvZGU7XG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0geWVhc3Q7XG4gICAgICB9LCB7fV0sIDMxOiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICAgICAgICAgKi9cblxuICAgICAgICB2YXIgdXJsID0gX2RlcmVxXygnLi91cmwnKTtcbiAgICAgICAgdmFyIHBhcnNlciA9IF9kZXJlcV8oJ3NvY2tldC5pby1wYXJzZXInKTtcbiAgICAgICAgdmFyIE1hbmFnZXIgPSBfZGVyZXFfKCcuL21hbmFnZXInKTtcbiAgICAgICAgdmFyIGRlYnVnID0gX2RlcmVxXygnZGVidWcnKSgnc29ja2V0LmlvLWNsaWVudCcpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNb2R1bGUgZXhwb3J0cy5cbiAgICAgICAgICovXG5cbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gbG9va3VwO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNYW5hZ2VycyBjYWNoZS5cbiAgICAgICAgICovXG5cbiAgICAgICAgdmFyIGNhY2hlID0gZXhwb3J0cy5tYW5hZ2VycyA9IHt9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBMb29rcyB1cCBhbiBleGlzdGluZyBgTWFuYWdlcmAgZm9yIG11bHRpcGxleGluZy5cbiAgICAgICAgICogSWYgdGhlIHVzZXIgc3VtbW9uczpcbiAgICAgICAgICpcbiAgICAgICAgICogICBgaW8oJ2h0dHA6Ly9sb2NhbGhvc3QvYScpO2BcbiAgICAgICAgICogICBgaW8oJ2h0dHA6Ly9sb2NhbGhvc3QvYicpO2BcbiAgICAgICAgICpcbiAgICAgICAgICogV2UgcmV1c2UgdGhlIGV4aXN0aW5nIGluc3RhbmNlIGJhc2VkIG9uIHNhbWUgc2NoZW1lL3BvcnQvaG9zdCxcbiAgICAgICAgICogYW5kIHdlIGluaXRpYWxpemUgc29ja2V0cyBmb3IgZWFjaCBuYW1lc3BhY2UuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIGZ1bmN0aW9uIGxvb2t1cCh1cmksIG9wdHMpIHtcbiAgICAgICAgICBpZiAoKHR5cGVvZiB1cmkgPT09IFwidW5kZWZpbmVkXCIgPyBcInVuZGVmaW5lZFwiIDogX3R5cGVvZih1cmkpKSA9PSAnb2JqZWN0Jykge1xuICAgICAgICAgICAgb3B0cyA9IHVyaTtcbiAgICAgICAgICAgIHVyaSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBvcHRzID0gb3B0cyB8fCB7fTtcblxuICAgICAgICAgIHZhciBwYXJzZWQgPSB1cmwodXJpKTtcbiAgICAgICAgICB2YXIgc291cmNlID0gcGFyc2VkLnNvdXJjZTtcbiAgICAgICAgICB2YXIgaWQgPSBwYXJzZWQuaWQ7XG4gICAgICAgICAgdmFyIHBhdGggPSBwYXJzZWQucGF0aDtcbiAgICAgICAgICB2YXIgc2FtZU5hbWVzcGFjZSA9IGNhY2hlW2lkXSAmJiBwYXRoIGluIGNhY2hlW2lkXS5uc3BzO1xuICAgICAgICAgIHZhciBuZXdDb25uZWN0aW9uID0gb3B0cy5mb3JjZU5ldyB8fCBvcHRzWydmb3JjZSBuZXcgY29ubmVjdGlvbiddIHx8IGZhbHNlID09PSBvcHRzLm11bHRpcGxleCB8fCBzYW1lTmFtZXNwYWNlO1xuXG4gICAgICAgICAgdmFyIGlvO1xuXG4gICAgICAgICAgaWYgKG5ld0Nvbm5lY3Rpb24pIHtcbiAgICAgICAgICAgIGRlYnVnKCdpZ25vcmluZyBzb2NrZXQgY2FjaGUgZm9yICVzJywgc291cmNlKTtcbiAgICAgICAgICAgIGlvID0gTWFuYWdlcihzb3VyY2UsIG9wdHMpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoIWNhY2hlW2lkXSkge1xuICAgICAgICAgICAgICBkZWJ1ZygnbmV3IGlvIGluc3RhbmNlIGZvciAlcycsIHNvdXJjZSk7XG4gICAgICAgICAgICAgIGNhY2hlW2lkXSA9IE1hbmFnZXIoc291cmNlLCBvcHRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlvID0gY2FjaGVbaWRdO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBpby5zb2NrZXQocGFyc2VkLnBhdGgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFByb3RvY29sIHZlcnNpb24uXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIGV4cG9ydHMucHJvdG9jb2wgPSBwYXJzZXIucHJvdG9jb2w7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIGBjb25uZWN0YC5cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHVyaVxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBleHBvcnRzLmNvbm5lY3QgPSBsb29rdXA7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEV4cG9zZSBjb25zdHJ1Y3RvcnMgZm9yIHN0YW5kYWxvbmUgYnVpbGQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIGV4cG9ydHMuTWFuYWdlciA9IF9kZXJlcV8oJy4vbWFuYWdlcicpO1xuICAgICAgICBleHBvcnRzLlNvY2tldCA9IF9kZXJlcV8oJy4vc29ja2V0Jyk7XG4gICAgICB9LCB7IFwiLi9tYW5hZ2VyXCI6IDMyLCBcIi4vc29ja2V0XCI6IDM0LCBcIi4vdXJsXCI6IDM1LCBcImRlYnVnXCI6IDM5LCBcInNvY2tldC5pby1wYXJzZXJcIjogNDcgfV0sIDMyOiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNb2R1bGUgZGVwZW5kZW5jaWVzLlxuICAgICAgICAgKi9cblxuICAgICAgICB2YXIgZWlvID0gX2RlcmVxXygnZW5naW5lLmlvLWNsaWVudCcpO1xuICAgICAgICB2YXIgU29ja2V0ID0gX2RlcmVxXygnLi9zb2NrZXQnKTtcbiAgICAgICAgdmFyIEVtaXR0ZXIgPSBfZGVyZXFfKCdjb21wb25lbnQtZW1pdHRlcicpO1xuICAgICAgICB2YXIgcGFyc2VyID0gX2RlcmVxXygnc29ja2V0LmlvLXBhcnNlcicpO1xuICAgICAgICB2YXIgb24gPSBfZGVyZXFfKCcuL29uJyk7XG4gICAgICAgIHZhciBiaW5kID0gX2RlcmVxXygnY29tcG9uZW50LWJpbmQnKTtcbiAgICAgICAgdmFyIGRlYnVnID0gX2RlcmVxXygnZGVidWcnKSgnc29ja2V0LmlvLWNsaWVudDptYW5hZ2VyJyk7XG4gICAgICAgIHZhciBpbmRleE9mID0gX2RlcmVxXygnaW5kZXhvZicpO1xuICAgICAgICB2YXIgQmFja29mZiA9IF9kZXJlcV8oJ2JhY2tvMicpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJRTYrIGhhc093blByb3BlcnR5XG4gICAgICAgICAqL1xuXG4gICAgICAgIHZhciBoYXMgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNb2R1bGUgZXhwb3J0c1xuICAgICAgICAgKi9cblxuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IE1hbmFnZXI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIGBNYW5hZ2VyYCBjb25zdHJ1Y3Rvci5cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGVuZ2luZSBpbnN0YW5jZSBvciBlbmdpbmUgdXJpL29wdHNcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IG9wdGlvbnNcbiAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICovXG5cbiAgICAgICAgZnVuY3Rpb24gTWFuYWdlcih1cmksIG9wdHMpIHtcbiAgICAgICAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgTWFuYWdlcikpIHJldHVybiBuZXcgTWFuYWdlcih1cmksIG9wdHMpO1xuICAgICAgICAgIGlmICh1cmkgJiYgJ29iamVjdCcgPT0gKHR5cGVvZiB1cmkgPT09IFwidW5kZWZpbmVkXCIgPyBcInVuZGVmaW5lZFwiIDogX3R5cGVvZih1cmkpKSkge1xuICAgICAgICAgICAgb3B0cyA9IHVyaTtcbiAgICAgICAgICAgIHVyaSA9IHVuZGVmaW5lZDtcbiAgICAgICAgICB9XG4gICAgICAgICAgb3B0cyA9IG9wdHMgfHwge307XG5cbiAgICAgICAgICBvcHRzLnBhdGggPSBvcHRzLnBhdGggfHwgJy9zb2NrZXQuaW8nO1xuICAgICAgICAgIHRoaXMubnNwcyA9IHt9O1xuICAgICAgICAgIHRoaXMuc3VicyA9IFtdO1xuICAgICAgICAgIHRoaXMub3B0cyA9IG9wdHM7XG4gICAgICAgICAgdGhpcy5yZWNvbm5lY3Rpb24ob3B0cy5yZWNvbm5lY3Rpb24gIT09IGZhbHNlKTtcbiAgICAgICAgICB0aGlzLnJlY29ubmVjdGlvbkF0dGVtcHRzKG9wdHMucmVjb25uZWN0aW9uQXR0ZW1wdHMgfHwgSW5maW5pdHkpO1xuICAgICAgICAgIHRoaXMucmVjb25uZWN0aW9uRGVsYXkob3B0cy5yZWNvbm5lY3Rpb25EZWxheSB8fCAxMDAwKTtcbiAgICAgICAgICB0aGlzLnJlY29ubmVjdGlvbkRlbGF5TWF4KG9wdHMucmVjb25uZWN0aW9uRGVsYXlNYXggfHwgNTAwMCk7XG4gICAgICAgICAgdGhpcy5yYW5kb21pemF0aW9uRmFjdG9yKG9wdHMucmFuZG9taXphdGlvbkZhY3RvciB8fCAwLjUpO1xuICAgICAgICAgIHRoaXMuYmFja29mZiA9IG5ldyBCYWNrb2ZmKHtcbiAgICAgICAgICAgIG1pbjogdGhpcy5yZWNvbm5lY3Rpb25EZWxheSgpLFxuICAgICAgICAgICAgbWF4OiB0aGlzLnJlY29ubmVjdGlvbkRlbGF5TWF4KCksXG4gICAgICAgICAgICBqaXR0ZXI6IHRoaXMucmFuZG9taXphdGlvbkZhY3RvcigpXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgdGhpcy50aW1lb3V0KG51bGwgPT0gb3B0cy50aW1lb3V0ID8gMjAwMDAgOiBvcHRzLnRpbWVvdXQpO1xuICAgICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zZWQnO1xuICAgICAgICAgIHRoaXMudXJpID0gdXJpO1xuICAgICAgICAgIHRoaXMuY29ubmVjdGluZyA9IFtdO1xuICAgICAgICAgIHRoaXMubGFzdFBpbmcgPSBudWxsO1xuICAgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLnBhY2tldEJ1ZmZlciA9IFtdO1xuICAgICAgICAgIHRoaXMuZW5jb2RlciA9IG5ldyBwYXJzZXIuRW5jb2RlcigpO1xuICAgICAgICAgIHRoaXMuZGVjb2RlciA9IG5ldyBwYXJzZXIuRGVjb2RlcigpO1xuICAgICAgICAgIHRoaXMuYXV0b0Nvbm5lY3QgPSBvcHRzLmF1dG9Db25uZWN0ICE9PSBmYWxzZTtcbiAgICAgICAgICBpZiAodGhpcy5hdXRvQ29ubmVjdCkgdGhpcy5vcGVuKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogUHJvcGFnYXRlIGdpdmVuIGV2ZW50IHRvIHNvY2tldHMgYW5kIGVtaXQgb24gYHRoaXNgXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBNYW5hZ2VyLnByb3RvdHlwZS5lbWl0QWxsID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHRoaXMuZW1pdC5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgICAgIGZvciAodmFyIG5zcCBpbiB0aGlzLm5zcHMpIHtcbiAgICAgICAgICAgIGlmIChoYXMuY2FsbCh0aGlzLm5zcHMsIG5zcCkpIHtcbiAgICAgICAgICAgICAgdGhpcy5uc3BzW25zcF0uZW1pdC5hcHBseSh0aGlzLm5zcHNbbnNwXSwgYXJndW1lbnRzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFVwZGF0ZSBgc29ja2V0LmlkYCBvZiBhbGwgc29ja2V0c1xuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgTWFuYWdlci5wcm90b3R5cGUudXBkYXRlU29ja2V0SWRzID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGZvciAodmFyIG5zcCBpbiB0aGlzLm5zcHMpIHtcbiAgICAgICAgICAgIGlmIChoYXMuY2FsbCh0aGlzLm5zcHMsIG5zcCkpIHtcbiAgICAgICAgICAgICAgdGhpcy5uc3BzW25zcF0uaWQgPSB0aGlzLmVuZ2luZS5pZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1peCBpbiBgRW1pdHRlcmAuXG4gICAgICAgICAqL1xuXG4gICAgICAgIEVtaXR0ZXIoTWFuYWdlci5wcm90b3R5cGUpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTZXRzIHRoZSBgcmVjb25uZWN0aW9uYCBjb25maWcuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7Qm9vbGVhbn0gdHJ1ZS9mYWxzZSBpZiBpdCBzaG91bGQgYXV0b21hdGljYWxseSByZWNvbm5lY3RcbiAgICAgICAgICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBNYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb24gPSBmdW5jdGlvbiAodikge1xuICAgICAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3JlY29ubmVjdGlvbjtcbiAgICAgICAgICB0aGlzLl9yZWNvbm5lY3Rpb24gPSAhIXY7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNldHMgdGhlIHJlY29ubmVjdGlvbiBhdHRlbXB0cyBjb25maWcuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSBtYXggcmVjb25uZWN0aW9uIGF0dGVtcHRzIGJlZm9yZSBnaXZpbmcgdXBcbiAgICAgICAgICogQHJldHVybiB7TWFuYWdlcn0gc2VsZiBvciB2YWx1ZVxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBNYW5hZ2VyLnByb3RvdHlwZS5yZWNvbm5lY3Rpb25BdHRlbXB0cyA9IGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGhpcy5fcmVjb25uZWN0aW9uQXR0ZW1wdHM7XG4gICAgICAgICAgdGhpcy5fcmVjb25uZWN0aW9uQXR0ZW1wdHMgPSB2O1xuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTZXRzIHRoZSBkZWxheSBiZXR3ZWVuIHJlY29ubmVjdGlvbnMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkZWxheVxuICAgICAgICAgKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmIG9yIHZhbHVlXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIE1hbmFnZXIucHJvdG90eXBlLnJlY29ubmVjdGlvbkRlbGF5ID0gZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl9yZWNvbm5lY3Rpb25EZWxheTtcbiAgICAgICAgICB0aGlzLl9yZWNvbm5lY3Rpb25EZWxheSA9IHY7XG4gICAgICAgICAgdGhpcy5iYWNrb2ZmICYmIHRoaXMuYmFja29mZi5zZXRNaW4odik7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH07XG5cbiAgICAgICAgTWFuYWdlci5wcm90b3R5cGUucmFuZG9taXphdGlvbkZhY3RvciA9IGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGhpcy5fcmFuZG9taXphdGlvbkZhY3RvcjtcbiAgICAgICAgICB0aGlzLl9yYW5kb21pemF0aW9uRmFjdG9yID0gdjtcbiAgICAgICAgICB0aGlzLmJhY2tvZmYgJiYgdGhpcy5iYWNrb2ZmLnNldEppdHRlcih2KTtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogU2V0cyB0aGUgbWF4aW11bSBkZWxheSBiZXR3ZWVuIHJlY29ubmVjdGlvbnMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkZWxheVxuICAgICAgICAgKiBAcmV0dXJuIHtNYW5hZ2VyfSBzZWxmIG9yIHZhbHVlXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIE1hbmFnZXIucHJvdG90eXBlLnJlY29ubmVjdGlvbkRlbGF5TWF4ID0gZnVuY3Rpb24gKHYpIHtcbiAgICAgICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiB0aGlzLl9yZWNvbm5lY3Rpb25EZWxheU1heDtcbiAgICAgICAgICB0aGlzLl9yZWNvbm5lY3Rpb25EZWxheU1heCA9IHY7XG4gICAgICAgICAgdGhpcy5iYWNrb2ZmICYmIHRoaXMuYmFja29mZi5zZXRNYXgodik7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNldHMgdGhlIGNvbm5lY3Rpb24gdGltZW91dC4gYGZhbHNlYCB0byBkaXNhYmxlXG4gICAgICAgICAqXG4gICAgICAgICAqIEByZXR1cm4ge01hbmFnZXJ9IHNlbGYgb3IgdmFsdWVcbiAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICovXG5cbiAgICAgICAgTWFuYWdlci5wcm90b3R5cGUudGltZW91dCA9IGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGhpcy5fdGltZW91dDtcbiAgICAgICAgICB0aGlzLl90aW1lb3V0ID0gdjtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogU3RhcnRzIHRyeWluZyB0byByZWNvbm5lY3QgaWYgcmVjb25uZWN0aW9uIGlzIGVuYWJsZWQgYW5kIHdlIGhhdmUgbm90XG4gICAgICAgICAqIHN0YXJ0ZWQgcmVjb25uZWN0aW5nIHlldFxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgTWFuYWdlci5wcm90b3R5cGUubWF5YmVSZWNvbm5lY3RPbk9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgLy8gT25seSB0cnkgdG8gcmVjb25uZWN0IGlmIGl0J3MgdGhlIGZpcnN0IHRpbWUgd2UncmUgY29ubmVjdGluZ1xuICAgICAgICAgIGlmICghdGhpcy5yZWNvbm5lY3RpbmcgJiYgdGhpcy5fcmVjb25uZWN0aW9uICYmIHRoaXMuYmFja29mZi5hdHRlbXB0cyA9PT0gMCkge1xuICAgICAgICAgICAgLy8ga2VlcHMgcmVjb25uZWN0aW9uIGZyb20gZmlyaW5nIHR3aWNlIGZvciB0aGUgc2FtZSByZWNvbm5lY3Rpb24gbG9vcFxuICAgICAgICAgICAgdGhpcy5yZWNvbm5lY3QoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNldHMgdGhlIGN1cnJlbnQgdHJhbnNwb3J0IGBzb2NrZXRgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBvcHRpb25hbCwgY2FsbGJhY2tcbiAgICAgICAgICogQHJldHVybiB7TWFuYWdlcn0gc2VsZlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBNYW5hZ2VyLnByb3RvdHlwZS5vcGVuID0gTWFuYWdlci5wcm90b3R5cGUuY29ubmVjdCA9IGZ1bmN0aW9uIChmbikge1xuICAgICAgICAgIGRlYnVnKCdyZWFkeVN0YXRlICVzJywgdGhpcy5yZWFkeVN0YXRlKTtcbiAgICAgICAgICBpZiAofnRoaXMucmVhZHlTdGF0ZS5pbmRleE9mKCdvcGVuJykpIHJldHVybiB0aGlzO1xuXG4gICAgICAgICAgZGVidWcoJ29wZW5pbmcgJXMnLCB0aGlzLnVyaSk7XG4gICAgICAgICAgdGhpcy5lbmdpbmUgPSBlaW8odGhpcy51cmksIHRoaXMub3B0cyk7XG4gICAgICAgICAgdmFyIHNvY2tldCA9IHRoaXMuZW5naW5lO1xuICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcbiAgICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSAnb3BlbmluZyc7XG4gICAgICAgICAgdGhpcy5za2lwUmVjb25uZWN0ID0gZmFsc2U7XG5cbiAgICAgICAgICAvLyBlbWl0IGBvcGVuYFxuICAgICAgICAgIHZhciBvcGVuU3ViID0gb24oc29ja2V0LCAnb3BlbicsIGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgIHNlbGYub25vcGVuKCk7XG4gICAgICAgICAgICBmbiAmJiBmbigpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8gZW1pdCBgY29ubmVjdF9lcnJvcmBcbiAgICAgICAgICB2YXIgZXJyb3JTdWIgPSBvbihzb2NrZXQsICdlcnJvcicsIGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgICBkZWJ1ZygnY29ubmVjdF9lcnJvcicpO1xuICAgICAgICAgICAgc2VsZi5jbGVhbnVwKCk7XG4gICAgICAgICAgICBzZWxmLnJlYWR5U3RhdGUgPSAnY2xvc2VkJztcbiAgICAgICAgICAgIHNlbGYuZW1pdEFsbCgnY29ubmVjdF9lcnJvcicsIGRhdGEpO1xuICAgICAgICAgICAgaWYgKGZuKSB7XG4gICAgICAgICAgICAgIHZhciBlcnIgPSBuZXcgRXJyb3IoJ0Nvbm5lY3Rpb24gZXJyb3InKTtcbiAgICAgICAgICAgICAgZXJyLmRhdGEgPSBkYXRhO1xuICAgICAgICAgICAgICBmbihlcnIpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgLy8gT25seSBkbyB0aGlzIGlmIHRoZXJlIGlzIG5vIGZuIHRvIGhhbmRsZSB0aGUgZXJyb3JcbiAgICAgICAgICAgICAgc2VsZi5tYXliZVJlY29ubmVjdE9uT3BlbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgLy8gZW1pdCBgY29ubmVjdF90aW1lb3V0YFxuICAgICAgICAgIGlmIChmYWxzZSAhPT0gdGhpcy5fdGltZW91dCkge1xuICAgICAgICAgICAgdmFyIHRpbWVvdXQgPSB0aGlzLl90aW1lb3V0O1xuICAgICAgICAgICAgZGVidWcoJ2Nvbm5lY3QgYXR0ZW1wdCB3aWxsIHRpbWVvdXQgYWZ0ZXIgJWQnLCB0aW1lb3V0KTtcblxuICAgICAgICAgICAgLy8gc2V0IHRpbWVyXG4gICAgICAgICAgICB2YXIgdGltZXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICAgICAgZGVidWcoJ2Nvbm5lY3QgYXR0ZW1wdCB0aW1lZCBvdXQgYWZ0ZXIgJWQnLCB0aW1lb3V0KTtcbiAgICAgICAgICAgICAgb3BlblN1Yi5kZXN0cm95KCk7XG4gICAgICAgICAgICAgIHNvY2tldC5jbG9zZSgpO1xuICAgICAgICAgICAgICBzb2NrZXQuZW1pdCgnZXJyb3InLCAndGltZW91dCcpO1xuICAgICAgICAgICAgICBzZWxmLmVtaXRBbGwoJ2Nvbm5lY3RfdGltZW91dCcsIHRpbWVvdXQpO1xuICAgICAgICAgICAgfSwgdGltZW91dCk7XG5cbiAgICAgICAgICAgIHRoaXMuc3Vicy5wdXNoKHtcbiAgICAgICAgICAgICAgZGVzdHJveTogZnVuY3Rpb24gZGVzdHJveSgpIHtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB0aGlzLnN1YnMucHVzaChvcGVuU3ViKTtcbiAgICAgICAgICB0aGlzLnN1YnMucHVzaChlcnJvclN1Yik7XG5cbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGVkIHVwb24gdHJhbnNwb3J0IG9wZW4uXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBNYW5hZ2VyLnByb3RvdHlwZS5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZGVidWcoJ29wZW4nKTtcblxuICAgICAgICAgIC8vIGNsZWFyIG9sZCBzdWJzXG4gICAgICAgICAgdGhpcy5jbGVhbnVwKCk7XG5cbiAgICAgICAgICAvLyBtYXJrIGFzIG9wZW5cbiAgICAgICAgICB0aGlzLnJlYWR5U3RhdGUgPSAnb3Blbic7XG4gICAgICAgICAgdGhpcy5lbWl0KCdvcGVuJyk7XG5cbiAgICAgICAgICAvLyBhZGQgbmV3IHN1YnNcbiAgICAgICAgICB2YXIgc29ja2V0ID0gdGhpcy5lbmdpbmU7XG4gICAgICAgICAgdGhpcy5zdWJzLnB1c2gob24oc29ja2V0LCAnZGF0YScsIGJpbmQodGhpcywgJ29uZGF0YScpKSk7XG4gICAgICAgICAgdGhpcy5zdWJzLnB1c2gob24oc29ja2V0LCAncGluZycsIGJpbmQodGhpcywgJ29ucGluZycpKSk7XG4gICAgICAgICAgdGhpcy5zdWJzLnB1c2gob24oc29ja2V0LCAncG9uZycsIGJpbmQodGhpcywgJ29ucG9uZycpKSk7XG4gICAgICAgICAgdGhpcy5zdWJzLnB1c2gob24oc29ja2V0LCAnZXJyb3InLCBiaW5kKHRoaXMsICdvbmVycm9yJykpKTtcbiAgICAgICAgICB0aGlzLnN1YnMucHVzaChvbihzb2NrZXQsICdjbG9zZScsIGJpbmQodGhpcywgJ29uY2xvc2UnKSkpO1xuICAgICAgICAgIHRoaXMuc3Vicy5wdXNoKG9uKHRoaXMuZGVjb2RlciwgJ2RlY29kZWQnLCBiaW5kKHRoaXMsICdvbmRlY29kZWQnKSkpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYWxsZWQgdXBvbiBhIHBpbmcuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBNYW5hZ2VyLnByb3RvdHlwZS5vbnBpbmcgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdGhpcy5sYXN0UGluZyA9IG5ldyBEYXRlKCk7XG4gICAgICAgICAgdGhpcy5lbWl0QWxsKCdwaW5nJyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENhbGxlZCB1cG9uIGEgcGFja2V0LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgTWFuYWdlci5wcm90b3R5cGUub25wb25nID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHRoaXMuZW1pdEFsbCgncG9uZycsIG5ldyBEYXRlKCkgLSB0aGlzLmxhc3RQaW5nKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGVkIHdpdGggZGF0YS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIE1hbmFnZXIucHJvdG90eXBlLm9uZGF0YSA9IGZ1bmN0aW9uIChkYXRhKSB7XG4gICAgICAgICAgdGhpcy5kZWNvZGVyLmFkZChkYXRhKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGVkIHdoZW4gcGFyc2VyIGZ1bGx5IGRlY29kZXMgYSBwYWNrZXQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBNYW5hZ2VyLnByb3RvdHlwZS5vbmRlY29kZWQgPSBmdW5jdGlvbiAocGFja2V0KSB7XG4gICAgICAgICAgdGhpcy5lbWl0KCdwYWNrZXQnLCBwYWNrZXQpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYWxsZWQgdXBvbiBzb2NrZXQgZXJyb3IuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBNYW5hZ2VyLnByb3RvdHlwZS5vbmVycm9yID0gZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgIGRlYnVnKCdlcnJvcicsIGVycik7XG4gICAgICAgICAgdGhpcy5lbWl0QWxsKCdlcnJvcicsIGVycik7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENyZWF0ZXMgYSBuZXcgc29ja2V0IGZvciB0aGUgZ2l2ZW4gYG5zcGAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEByZXR1cm4ge1NvY2tldH1cbiAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICovXG5cbiAgICAgICAgTWFuYWdlci5wcm90b3R5cGUuc29ja2V0ID0gZnVuY3Rpb24gKG5zcCkge1xuICAgICAgICAgIHZhciBzb2NrZXQgPSB0aGlzLm5zcHNbbnNwXTtcbiAgICAgICAgICBpZiAoIXNvY2tldCkge1xuICAgICAgICAgICAgc29ja2V0ID0gbmV3IFNvY2tldCh0aGlzLCBuc3ApO1xuICAgICAgICAgICAgdGhpcy5uc3BzW25zcF0gPSBzb2NrZXQ7XG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgICBzb2NrZXQub24oJ2Nvbm5lY3RpbmcnLCBvbkNvbm5lY3RpbmcpO1xuICAgICAgICAgICAgc29ja2V0Lm9uKCdjb25uZWN0JywgZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBzb2NrZXQuaWQgPSBzZWxmLmVuZ2luZS5pZDtcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAodGhpcy5hdXRvQ29ubmVjdCkge1xuICAgICAgICAgICAgICAvLyBtYW51YWxseSBjYWxsIGhlcmUgc2luY2UgY29ubmVjdGluZyBldm5ldCBpcyBmaXJlZCBiZWZvcmUgbGlzdGVuaW5nXG4gICAgICAgICAgICAgIG9uQ29ubmVjdGluZygpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGZ1bmN0aW9uIG9uQ29ubmVjdGluZygpIHtcbiAgICAgICAgICAgIGlmICghfmluZGV4T2Yoc2VsZi5jb25uZWN0aW5nLCBzb2NrZXQpKSB7XG4gICAgICAgICAgICAgIHNlbGYuY29ubmVjdGluZy5wdXNoKHNvY2tldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIHNvY2tldDtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGVkIHVwb24gYSBzb2NrZXQgY2xvc2UuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7U29ja2V0fSBzb2NrZXRcbiAgICAgICAgICovXG5cbiAgICAgICAgTWFuYWdlci5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uIChzb2NrZXQpIHtcbiAgICAgICAgICB2YXIgaW5kZXggPSBpbmRleE9mKHRoaXMuY29ubmVjdGluZywgc29ja2V0KTtcbiAgICAgICAgICBpZiAofmluZGV4KSB0aGlzLmNvbm5lY3Rpbmcuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICBpZiAodGhpcy5jb25uZWN0aW5nLmxlbmd0aCkgcmV0dXJuO1xuXG4gICAgICAgICAgdGhpcy5jbG9zZSgpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBXcml0ZXMgYSBwYWNrZXQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIE1hbmFnZXIucHJvdG90eXBlLnBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgICAgICAgICBkZWJ1Zygnd3JpdGluZyBwYWNrZXQgJWonLCBwYWNrZXQpO1xuICAgICAgICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgICAgICAgIGlmICghc2VsZi5lbmNvZGluZykge1xuICAgICAgICAgICAgLy8gZW5jb2RlLCB0aGVuIHdyaXRlIHRvIGVuZ2luZSB3aXRoIHJlc3VsdFxuICAgICAgICAgICAgc2VsZi5lbmNvZGluZyA9IHRydWU7XG4gICAgICAgICAgICB0aGlzLmVuY29kZXIuZW5jb2RlKHBhY2tldCwgZnVuY3Rpb24gKGVuY29kZWRQYWNrZXRzKSB7XG4gICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZW5jb2RlZFBhY2tldHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBzZWxmLmVuZ2luZS53cml0ZShlbmNvZGVkUGFja2V0c1tpXSwgcGFja2V0Lm9wdGlvbnMpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHNlbGYuZW5jb2RpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgc2VsZi5wcm9jZXNzUGFja2V0UXVldWUoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBhZGQgcGFja2V0IHRvIHRoZSBxdWV1ZVxuICAgICAgICAgICAgc2VsZi5wYWNrZXRCdWZmZXIucHVzaChwYWNrZXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogSWYgcGFja2V0IGJ1ZmZlciBpcyBub24tZW1wdHksIGJlZ2lucyBlbmNvZGluZyB0aGVcbiAgICAgICAgICogbmV4dCBwYWNrZXQgaW4gbGluZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIE1hbmFnZXIucHJvdG90eXBlLnByb2Nlc3NQYWNrZXRRdWV1ZSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpZiAodGhpcy5wYWNrZXRCdWZmZXIubGVuZ3RoID4gMCAmJiAhdGhpcy5lbmNvZGluZykge1xuICAgICAgICAgICAgdmFyIHBhY2sgPSB0aGlzLnBhY2tldEJ1ZmZlci5zaGlmdCgpO1xuICAgICAgICAgICAgdGhpcy5wYWNrZXQocGFjayk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDbGVhbiB1cCB0cmFuc3BvcnQgc3Vic2NyaXB0aW9ucyBhbmQgcGFja2V0IGJ1ZmZlci5cbiAgICAgICAgICpcbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIE1hbmFnZXIucHJvdG90eXBlLmNsZWFudXAgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZGVidWcoJ2NsZWFudXAnKTtcblxuICAgICAgICAgIHZhciBzdWI7XG4gICAgICAgICAgd2hpbGUgKHN1YiA9IHRoaXMuc3Vicy5zaGlmdCgpKSB7XG4gICAgICAgICAgICBzdWIuZGVzdHJveSgpO1xuICAgICAgICAgIH10aGlzLnBhY2tldEJ1ZmZlciA9IFtdO1xuICAgICAgICAgIHRoaXMuZW5jb2RpbmcgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLmxhc3RQaW5nID0gbnVsbDtcblxuICAgICAgICAgIHRoaXMuZGVjb2Rlci5kZXN0cm95KCk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENsb3NlIHRoZSBjdXJyZW50IHNvY2tldC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIE1hbmFnZXIucHJvdG90eXBlLmNsb3NlID0gTWFuYWdlci5wcm90b3R5cGUuZGlzY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBkZWJ1ZygnZGlzY29ubmVjdCcpO1xuICAgICAgICAgIHRoaXMuc2tpcFJlY29ubmVjdCA9IHRydWU7XG4gICAgICAgICAgdGhpcy5yZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICBpZiAoJ29wZW5pbmcnID09IHRoaXMucmVhZHlTdGF0ZSkge1xuICAgICAgICAgICAgLy8gYG9uY2xvc2VgIHdpbGwgbm90IGZpcmUgYmVjYXVzZVxuICAgICAgICAgICAgLy8gYW4gb3BlbiBldmVudCBuZXZlciBoYXBwZW5lZFxuICAgICAgICAgICAgdGhpcy5jbGVhbnVwKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuYmFja29mZi5yZXNldCgpO1xuICAgICAgICAgIHRoaXMucmVhZHlTdGF0ZSA9ICdjbG9zZWQnO1xuICAgICAgICAgIGlmICh0aGlzLmVuZ2luZSkgdGhpcy5lbmdpbmUuY2xvc2UoKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGVkIHVwb24gZW5naW5lIGNsb3NlLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgTWFuYWdlci5wcm90b3R5cGUub25jbG9zZSA9IGZ1bmN0aW9uIChyZWFzb24pIHtcbiAgICAgICAgICBkZWJ1Zygnb25jbG9zZScpO1xuXG4gICAgICAgICAgdGhpcy5jbGVhbnVwKCk7XG4gICAgICAgICAgdGhpcy5iYWNrb2ZmLnJlc2V0KCk7XG4gICAgICAgICAgdGhpcy5yZWFkeVN0YXRlID0gJ2Nsb3NlZCc7XG4gICAgICAgICAgdGhpcy5lbWl0KCdjbG9zZScsIHJlYXNvbik7XG5cbiAgICAgICAgICBpZiAodGhpcy5fcmVjb25uZWN0aW9uICYmICF0aGlzLnNraXBSZWNvbm5lY3QpIHtcbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0KCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBdHRlbXB0IGEgcmVjb25uZWN0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgTWFuYWdlci5wcm90b3R5cGUucmVjb25uZWN0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmICh0aGlzLnJlY29ubmVjdGluZyB8fCB0aGlzLnNraXBSZWNvbm5lY3QpIHJldHVybiB0aGlzO1xuXG4gICAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuXG4gICAgICAgICAgaWYgKHRoaXMuYmFja29mZi5hdHRlbXB0cyA+PSB0aGlzLl9yZWNvbm5lY3Rpb25BdHRlbXB0cykge1xuICAgICAgICAgICAgZGVidWcoJ3JlY29ubmVjdCBmYWlsZWQnKTtcbiAgICAgICAgICAgIHRoaXMuYmFja29mZi5yZXNldCgpO1xuICAgICAgICAgICAgdGhpcy5lbWl0QWxsKCdyZWNvbm5lY3RfZmFpbGVkJyk7XG4gICAgICAgICAgICB0aGlzLnJlY29ubmVjdGluZyA9IGZhbHNlO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB2YXIgZGVsYXkgPSB0aGlzLmJhY2tvZmYuZHVyYXRpb24oKTtcbiAgICAgICAgICAgIGRlYnVnKCd3aWxsIHdhaXQgJWRtcyBiZWZvcmUgcmVjb25uZWN0IGF0dGVtcHQnLCBkZWxheSk7XG5cbiAgICAgICAgICAgIHRoaXMucmVjb25uZWN0aW5nID0gdHJ1ZTtcbiAgICAgICAgICAgIHZhciB0aW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgICBpZiAoc2VsZi5za2lwUmVjb25uZWN0KSByZXR1cm47XG5cbiAgICAgICAgICAgICAgZGVidWcoJ2F0dGVtcHRpbmcgcmVjb25uZWN0Jyk7XG4gICAgICAgICAgICAgIHNlbGYuZW1pdEFsbCgncmVjb25uZWN0X2F0dGVtcHQnLCBzZWxmLmJhY2tvZmYuYXR0ZW1wdHMpO1xuICAgICAgICAgICAgICBzZWxmLmVtaXRBbGwoJ3JlY29ubmVjdGluZycsIHNlbGYuYmFja29mZi5hdHRlbXB0cyk7XG5cbiAgICAgICAgICAgICAgLy8gY2hlY2sgYWdhaW4gZm9yIHRoZSBjYXNlIHNvY2tldCBjbG9zZWQgaW4gYWJvdmUgZXZlbnRzXG4gICAgICAgICAgICAgIGlmIChzZWxmLnNraXBSZWNvbm5lY3QpIHJldHVybjtcblxuICAgICAgICAgICAgICBzZWxmLm9wZW4oZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICAgIGRlYnVnKCdyZWNvbm5lY3QgYXR0ZW1wdCBlcnJvcicpO1xuICAgICAgICAgICAgICAgICAgc2VsZi5yZWNvbm5lY3RpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgIHNlbGYucmVjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgICBzZWxmLmVtaXRBbGwoJ3JlY29ubmVjdF9lcnJvcicsIGVyci5kYXRhKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgZGVidWcoJ3JlY29ubmVjdCBzdWNjZXNzJyk7XG4gICAgICAgICAgICAgICAgICBzZWxmLm9ucmVjb25uZWN0KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0sIGRlbGF5KTtcblxuICAgICAgICAgICAgdGhpcy5zdWJzLnB1c2goe1xuICAgICAgICAgICAgICBkZXN0cm95OiBmdW5jdGlvbiBkZXN0cm95KCkge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lcik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGVkIHVwb24gc3VjY2Vzc2Z1bCByZWNvbm5lY3QuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBNYW5hZ2VyLnByb3RvdHlwZS5vbnJlY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICB2YXIgYXR0ZW1wdCA9IHRoaXMuYmFja29mZi5hdHRlbXB0cztcbiAgICAgICAgICB0aGlzLnJlY29ubmVjdGluZyA9IGZhbHNlO1xuICAgICAgICAgIHRoaXMuYmFja29mZi5yZXNldCgpO1xuICAgICAgICAgIHRoaXMudXBkYXRlU29ja2V0SWRzKCk7XG4gICAgICAgICAgdGhpcy5lbWl0QWxsKCdyZWNvbm5lY3QnLCBhdHRlbXB0KTtcbiAgICAgICAgfTtcbiAgICAgIH0sIHsgXCIuL29uXCI6IDMzLCBcIi4vc29ja2V0XCI6IDM0LCBcImJhY2tvMlwiOiAzNiwgXCJjb21wb25lbnQtYmluZFwiOiAzNywgXCJjb21wb25lbnQtZW1pdHRlclwiOiAzOCwgXCJkZWJ1Z1wiOiAzOSwgXCJlbmdpbmUuaW8tY2xpZW50XCI6IDEsIFwiaW5kZXhvZlwiOiA0MiwgXCJzb2NrZXQuaW8tcGFyc2VyXCI6IDQ3IH1dLCAzMzogW2Z1bmN0aW9uIChfZGVyZXFfLCBtb2R1bGUsIGV4cG9ydHMpIHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTW9kdWxlIGV4cG9ydHMuXG4gICAgICAgICAqL1xuXG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gb247XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEhlbHBlciBmb3Igc3Vic2NyaXB0aW9ucy5cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R8RXZlbnRFbWl0dGVyfSBvYmogd2l0aCBgRW1pdHRlcmAgbWl4aW4gb3IgYEV2ZW50RW1pdHRlcmBcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IG5hbWVcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICovXG5cbiAgICAgICAgZnVuY3Rpb24gb24ob2JqLCBldiwgZm4pIHtcbiAgICAgICAgICBvYmoub24oZXYsIGZuKTtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgZGVzdHJveTogZnVuY3Rpb24gZGVzdHJveSgpIHtcbiAgICAgICAgICAgICAgb2JqLnJlbW92ZUxpc3RlbmVyKGV2LCBmbik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSwge31dLCAzNDogW2Z1bmN0aW9uIChfZGVyZXFfLCBtb2R1bGUsIGV4cG9ydHMpIHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAgICAgICAgICovXG5cbiAgICAgICAgdmFyIHBhcnNlciA9IF9kZXJlcV8oJ3NvY2tldC5pby1wYXJzZXInKTtcbiAgICAgICAgdmFyIEVtaXR0ZXIgPSBfZGVyZXFfKCdjb21wb25lbnQtZW1pdHRlcicpO1xuICAgICAgICB2YXIgdG9BcnJheSA9IF9kZXJlcV8oJ3RvLWFycmF5Jyk7XG4gICAgICAgIHZhciBvbiA9IF9kZXJlcV8oJy4vb24nKTtcbiAgICAgICAgdmFyIGJpbmQgPSBfZGVyZXFfKCdjb21wb25lbnQtYmluZCcpO1xuICAgICAgICB2YXIgZGVidWcgPSBfZGVyZXFfKCdkZWJ1ZycpKCdzb2NrZXQuaW8tY2xpZW50OnNvY2tldCcpO1xuICAgICAgICB2YXIgaGFzQmluID0gX2RlcmVxXygnaGFzLWJpbmFyeScpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNb2R1bGUgZXhwb3J0cy5cbiAgICAgICAgICovXG5cbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBleHBvcnRzID0gU29ja2V0O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBJbnRlcm5hbCBldmVudHMgKGJsYWNrbGlzdGVkKS5cbiAgICAgICAgICogVGhlc2UgZXZlbnRzIGNhbid0IGJlIGVtaXR0ZWQgYnkgdGhlIHVzZXIuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICB2YXIgZXZlbnRzID0ge1xuICAgICAgICAgIGNvbm5lY3Q6IDEsXG4gICAgICAgICAgY29ubmVjdF9lcnJvcjogMSxcbiAgICAgICAgICBjb25uZWN0X3RpbWVvdXQ6IDEsXG4gICAgICAgICAgY29ubmVjdGluZzogMSxcbiAgICAgICAgICBkaXNjb25uZWN0OiAxLFxuICAgICAgICAgIGVycm9yOiAxLFxuICAgICAgICAgIHJlY29ubmVjdDogMSxcbiAgICAgICAgICByZWNvbm5lY3RfYXR0ZW1wdDogMSxcbiAgICAgICAgICByZWNvbm5lY3RfZmFpbGVkOiAxLFxuICAgICAgICAgIHJlY29ubmVjdF9lcnJvcjogMSxcbiAgICAgICAgICByZWNvbm5lY3Rpbmc6IDEsXG4gICAgICAgICAgcGluZzogMSxcbiAgICAgICAgICBwb25nOiAxXG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNob3J0Y3V0IHRvIGBFbWl0dGVyI2VtaXRgLlxuICAgICAgICAgKi9cblxuICAgICAgICB2YXIgZW1pdCA9IEVtaXR0ZXIucHJvdG90eXBlLmVtaXQ7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIGBTb2NrZXRgIGNvbnN0cnVjdG9yLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBmdW5jdGlvbiBTb2NrZXQoaW8sIG5zcCkge1xuICAgICAgICAgIHRoaXMuaW8gPSBpbztcbiAgICAgICAgICB0aGlzLm5zcCA9IG5zcDtcbiAgICAgICAgICB0aGlzLmpzb24gPSB0aGlzOyAvLyBjb21wYXRcbiAgICAgICAgICB0aGlzLmlkcyA9IDA7XG4gICAgICAgICAgdGhpcy5hY2tzID0ge307XG4gICAgICAgICAgdGhpcy5yZWNlaXZlQnVmZmVyID0gW107XG4gICAgICAgICAgdGhpcy5zZW5kQnVmZmVyID0gW107XG4gICAgICAgICAgdGhpcy5jb25uZWN0ZWQgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLmRpc2Nvbm5lY3RlZCA9IHRydWU7XG4gICAgICAgICAgaWYgKHRoaXMuaW8uYXV0b0Nvbm5lY3QpIHRoaXMub3BlbigpO1xuICAgICAgICB9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1peCBpbiBgRW1pdHRlcmAuXG4gICAgICAgICAqL1xuXG4gICAgICAgIEVtaXR0ZXIoU29ja2V0LnByb3RvdHlwZSk7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFN1YnNjcmliZSB0byBvcGVuLCBjbG9zZSBhbmQgcGFja2V0IGV2ZW50c1xuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgU29ja2V0LnByb3RvdHlwZS5zdWJFdmVudHMgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc3VicykgcmV0dXJuO1xuXG4gICAgICAgICAgdmFyIGlvID0gdGhpcy5pbztcbiAgICAgICAgICB0aGlzLnN1YnMgPSBbb24oaW8sICdvcGVuJywgYmluZCh0aGlzLCAnb25vcGVuJykpLCBvbihpbywgJ3BhY2tldCcsIGJpbmQodGhpcywgJ29ucGFja2V0JykpLCBvbihpbywgJ2Nsb3NlJywgYmluZCh0aGlzLCAnb25jbG9zZScpKV07XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFwiT3BlbnNcIiB0aGUgc29ja2V0LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBTb2NrZXQucHJvdG90eXBlLm9wZW4gPSBTb2NrZXQucHJvdG90eXBlLmNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKHRoaXMuY29ubmVjdGVkKSByZXR1cm4gdGhpcztcblxuICAgICAgICAgIHRoaXMuc3ViRXZlbnRzKCk7XG4gICAgICAgICAgdGhpcy5pby5vcGVuKCk7IC8vIGVuc3VyZSBvcGVuXG4gICAgICAgICAgaWYgKCdvcGVuJyA9PSB0aGlzLmlvLnJlYWR5U3RhdGUpIHRoaXMub25vcGVuKCk7XG4gICAgICAgICAgdGhpcy5lbWl0KCdjb25uZWN0aW5nJyk7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNlbmRzIGEgYG1lc3NhZ2VgIGV2ZW50LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcmV0dXJuIHtTb2NrZXR9IHNlbGZcbiAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICovXG5cbiAgICAgICAgU29ja2V0LnByb3RvdHlwZS5zZW5kID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciBhcmdzID0gdG9BcnJheShhcmd1bWVudHMpO1xuICAgICAgICAgIGFyZ3MudW5zaGlmdCgnbWVzc2FnZScpO1xuICAgICAgICAgIHRoaXMuZW1pdC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogT3ZlcnJpZGUgYGVtaXRgLlxuICAgICAgICAgKiBJZiB0aGUgZXZlbnQgaXMgaW4gYGV2ZW50c2AsIGl0J3MgZW1pdHRlZCBub3JtYWxseS5cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IG5hbWVcbiAgICAgICAgICogQHJldHVybiB7U29ja2V0fSBzZWxmXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIFNvY2tldC5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uIChldikge1xuICAgICAgICAgIGlmIChldmVudHMuaGFzT3duUHJvcGVydHkoZXYpKSB7XG4gICAgICAgICAgICBlbWl0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzKTtcbiAgICAgICAgICB2YXIgcGFyc2VyVHlwZSA9IHBhcnNlci5FVkVOVDsgLy8gZGVmYXVsdFxuICAgICAgICAgIGlmIChoYXNCaW4oYXJncykpIHtcbiAgICAgICAgICAgIHBhcnNlclR5cGUgPSBwYXJzZXIuQklOQVJZX0VWRU5UO1xuICAgICAgICAgIH0gLy8gYmluYXJ5XG4gICAgICAgICAgdmFyIHBhY2tldCA9IHsgdHlwZTogcGFyc2VyVHlwZSwgZGF0YTogYXJncyB9O1xuXG4gICAgICAgICAgcGFja2V0Lm9wdGlvbnMgPSB7fTtcbiAgICAgICAgICBwYWNrZXQub3B0aW9ucy5jb21wcmVzcyA9ICF0aGlzLmZsYWdzIHx8IGZhbHNlICE9PSB0aGlzLmZsYWdzLmNvbXByZXNzO1xuXG4gICAgICAgICAgLy8gZXZlbnQgYWNrIGNhbGxiYWNrXG4gICAgICAgICAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGFyZ3NbYXJncy5sZW5ndGggLSAxXSkge1xuICAgICAgICAgICAgZGVidWcoJ2VtaXR0aW5nIHBhY2tldCB3aXRoIGFjayBpZCAlZCcsIHRoaXMuaWRzKTtcbiAgICAgICAgICAgIHRoaXMuYWNrc1t0aGlzLmlkc10gPSBhcmdzLnBvcCgpO1xuICAgICAgICAgICAgcGFja2V0LmlkID0gdGhpcy5pZHMrKztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBpZiAodGhpcy5jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIHRoaXMucGFja2V0KHBhY2tldCk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRoaXMuc2VuZEJ1ZmZlci5wdXNoKHBhY2tldCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZGVsZXRlIHRoaXMuZmxhZ3M7XG5cbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogU2VuZHMgYSBwYWNrZXQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIFNvY2tldC5wcm90b3R5cGUucGFja2V0ID0gZnVuY3Rpb24gKHBhY2tldCkge1xuICAgICAgICAgIHBhY2tldC5uc3AgPSB0aGlzLm5zcDtcbiAgICAgICAgICB0aGlzLmlvLnBhY2tldChwYWNrZXQpO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYWxsZWQgdXBvbiBlbmdpbmUgYG9wZW5gLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgU29ja2V0LnByb3RvdHlwZS5vbm9wZW4gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgZGVidWcoJ3RyYW5zcG9ydCBpcyBvcGVuIC0gY29ubmVjdGluZycpO1xuXG4gICAgICAgICAgLy8gd3JpdGUgY29ubmVjdCBwYWNrZXQgaWYgbmVjZXNzYXJ5XG4gICAgICAgICAgaWYgKCcvJyAhPSB0aGlzLm5zcCkge1xuICAgICAgICAgICAgdGhpcy5wYWNrZXQoeyB0eXBlOiBwYXJzZXIuQ09OTkVDVCB9KTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENhbGxlZCB1cG9uIGVuZ2luZSBgY2xvc2VgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gcmVhc29uXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBTb2NrZXQucHJvdG90eXBlLm9uY2xvc2UgPSBmdW5jdGlvbiAocmVhc29uKSB7XG4gICAgICAgICAgZGVidWcoJ2Nsb3NlICglcyknLCByZWFzb24pO1xuICAgICAgICAgIHRoaXMuY29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5kaXNjb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgIGRlbGV0ZSB0aGlzLmlkO1xuICAgICAgICAgIHRoaXMuZW1pdCgnZGlzY29ubmVjdCcsIHJlYXNvbik7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENhbGxlZCB3aXRoIHNvY2tldCBwYWNrZXQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIFNvY2tldC5wcm90b3R5cGUub25wYWNrZXQgPSBmdW5jdGlvbiAocGFja2V0KSB7XG4gICAgICAgICAgaWYgKHBhY2tldC5uc3AgIT0gdGhpcy5uc3ApIHJldHVybjtcblxuICAgICAgICAgIHN3aXRjaCAocGFja2V0LnR5cGUpIHtcbiAgICAgICAgICAgIGNhc2UgcGFyc2VyLkNPTk5FQ1Q6XG4gICAgICAgICAgICAgIHRoaXMub25jb25uZWN0KCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlIHBhcnNlci5FVkVOVDpcbiAgICAgICAgICAgICAgdGhpcy5vbmV2ZW50KHBhY2tldCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlIHBhcnNlci5CSU5BUllfRVZFTlQ6XG4gICAgICAgICAgICAgIHRoaXMub25ldmVudChwYWNrZXQpO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSBwYXJzZXIuQUNLOlxuICAgICAgICAgICAgICB0aGlzLm9uYWNrKHBhY2tldCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlIHBhcnNlci5CSU5BUllfQUNLOlxuICAgICAgICAgICAgICB0aGlzLm9uYWNrKHBhY2tldCk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlIHBhcnNlci5ESVNDT05ORUNUOlxuICAgICAgICAgICAgICB0aGlzLm9uZGlzY29ubmVjdCgpO1xuICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSBwYXJzZXIuRVJST1I6XG4gICAgICAgICAgICAgIHRoaXMuZW1pdCgnZXJyb3InLCBwYWNrZXQuZGF0YSk7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGVkIHVwb24gYSBzZXJ2ZXIgZXZlbnQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIFNvY2tldC5wcm90b3R5cGUub25ldmVudCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgICAgICAgICB2YXIgYXJncyA9IHBhY2tldC5kYXRhIHx8IFtdO1xuICAgICAgICAgIGRlYnVnKCdlbWl0dGluZyBldmVudCAlaicsIGFyZ3MpO1xuXG4gICAgICAgICAgaWYgKG51bGwgIT0gcGFja2V0LmlkKSB7XG4gICAgICAgICAgICBkZWJ1ZygnYXR0YWNoaW5nIGFjayBjYWxsYmFjayB0byBldmVudCcpO1xuICAgICAgICAgICAgYXJncy5wdXNoKHRoaXMuYWNrKHBhY2tldC5pZCkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGlmICh0aGlzLmNvbm5lY3RlZCkge1xuICAgICAgICAgICAgZW1pdC5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy5yZWNlaXZlQnVmZmVyLnB1c2goYXJncyk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcm9kdWNlcyBhbiBhY2sgY2FsbGJhY2sgdG8gZW1pdCB3aXRoIGFuIGV2ZW50LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgU29ja2V0LnByb3RvdHlwZS5hY2sgPSBmdW5jdGlvbiAoaWQpIHtcbiAgICAgICAgICB2YXIgc2VsZiA9IHRoaXM7XG4gICAgICAgICAgdmFyIHNlbnQgPSBmYWxzZTtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgLy8gcHJldmVudCBkb3VibGUgY2FsbGJhY2tzXG4gICAgICAgICAgICBpZiAoc2VudCkgcmV0dXJuO1xuICAgICAgICAgICAgc2VudCA9IHRydWU7XG4gICAgICAgICAgICB2YXIgYXJncyA9IHRvQXJyYXkoYXJndW1lbnRzKTtcbiAgICAgICAgICAgIGRlYnVnKCdzZW5kaW5nIGFjayAlaicsIGFyZ3MpO1xuXG4gICAgICAgICAgICB2YXIgdHlwZSA9IGhhc0JpbihhcmdzKSA/IHBhcnNlci5CSU5BUllfQUNLIDogcGFyc2VyLkFDSztcbiAgICAgICAgICAgIHNlbGYucGFja2V0KHtcbiAgICAgICAgICAgICAgdHlwZTogdHlwZSxcbiAgICAgICAgICAgICAgaWQ6IGlkLFxuICAgICAgICAgICAgICBkYXRhOiBhcmdzXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICB9O1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBDYWxsZWQgdXBvbiBhIHNlcnZlciBhY2tub3dsZWdlbWVudC5cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IHBhY2tldFxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgU29ja2V0LnByb3RvdHlwZS5vbmFjayA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgICAgICAgICB2YXIgYWNrID0gdGhpcy5hY2tzW3BhY2tldC5pZF07XG4gICAgICAgICAgaWYgKCdmdW5jdGlvbicgPT0gdHlwZW9mIGFjaykge1xuICAgICAgICAgICAgZGVidWcoJ2NhbGxpbmcgYWNrICVzIHdpdGggJWonLCBwYWNrZXQuaWQsIHBhY2tldC5kYXRhKTtcbiAgICAgICAgICAgIGFjay5hcHBseSh0aGlzLCBwYWNrZXQuZGF0YSk7XG4gICAgICAgICAgICBkZWxldGUgdGhpcy5hY2tzW3BhY2tldC5pZF07XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRlYnVnKCdiYWQgYWNrICVzJywgcGFja2V0LmlkKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENhbGxlZCB1cG9uIHNlcnZlciBjb25uZWN0LlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgU29ja2V0LnByb3RvdHlwZS5vbmNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdGhpcy5jb25uZWN0ZWQgPSB0cnVlO1xuICAgICAgICAgIHRoaXMuZGlzY29ubmVjdGVkID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5lbWl0KCdjb25uZWN0Jyk7XG4gICAgICAgICAgdGhpcy5lbWl0QnVmZmVyZWQoKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW1pdCBidWZmZXJlZCBldmVudHMgKHJlY2VpdmVkIGFuZCBlbWl0dGVkKS5cbiAgICAgICAgICpcbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIFNvY2tldC5wcm90b3R5cGUuZW1pdEJ1ZmZlcmVkID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciBpO1xuICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLnJlY2VpdmVCdWZmZXIubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGVtaXQuYXBwbHkodGhpcywgdGhpcy5yZWNlaXZlQnVmZmVyW2ldKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5yZWNlaXZlQnVmZmVyID0gW107XG5cbiAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGhpcy5zZW5kQnVmZmVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICB0aGlzLnBhY2tldCh0aGlzLnNlbmRCdWZmZXJbaV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLnNlbmRCdWZmZXIgPSBbXTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQ2FsbGVkIHVwb24gc2VydmVyIGRpc2Nvbm5lY3QuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBTb2NrZXQucHJvdG90eXBlLm9uZGlzY29ubmVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBkZWJ1Zygnc2VydmVyIGRpc2Nvbm5lY3QgKCVzKScsIHRoaXMubnNwKTtcbiAgICAgICAgICB0aGlzLmRlc3Ryb3koKTtcbiAgICAgICAgICB0aGlzLm9uY2xvc2UoJ2lvIHNlcnZlciBkaXNjb25uZWN0Jyk7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENhbGxlZCB1cG9uIGZvcmNlZCBjbGllbnQvc2VydmVyIHNpZGUgZGlzY29ubmVjdGlvbnMsXG4gICAgICAgICAqIHRoaXMgbWV0aG9kIGVuc3VyZXMgdGhlIG1hbmFnZXIgc3RvcHMgdHJhY2tpbmcgdXMgYW5kXG4gICAgICAgICAqIHRoYXQgcmVjb25uZWN0aW9ucyBkb24ndCBnZXQgdHJpZ2dlcmVkIGZvciB0aGlzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHByaXZhdGUuXG4gICAgICAgICAqL1xuXG4gICAgICAgIFNvY2tldC5wcm90b3R5cGUuZGVzdHJveSA9IGZ1bmN0aW9uICgpIHtcbiAgICAgICAgICBpZiAodGhpcy5zdWJzKSB7XG4gICAgICAgICAgICAvLyBjbGVhbiBzdWJzY3JpcHRpb25zIHRvIGF2b2lkIHJlY29ubmVjdGlvbnNcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5zdWJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgIHRoaXMuc3Vic1tpXS5kZXN0cm95KCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLnN1YnMgPSBudWxsO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuaW8uZGVzdHJveSh0aGlzKTtcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRGlzY29ubmVjdHMgdGhlIHNvY2tldCBtYW51YWxseS5cbiAgICAgICAgICpcbiAgICAgICAgICogQHJldHVybiB7U29ja2V0fSBzZWxmXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIFNvY2tldC5wcm90b3R5cGUuY2xvc2UgPSBTb2NrZXQucHJvdG90eXBlLmRpc2Nvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgaWYgKHRoaXMuY29ubmVjdGVkKSB7XG4gICAgICAgICAgICBkZWJ1ZygncGVyZm9ybWluZyBkaXNjb25uZWN0ICglcyknLCB0aGlzLm5zcCk7XG4gICAgICAgICAgICB0aGlzLnBhY2tldCh7IHR5cGU6IHBhcnNlci5ESVNDT05ORUNUIH0pO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIHJlbW92ZSBzb2NrZXQgZnJvbSBwb29sXG4gICAgICAgICAgdGhpcy5kZXN0cm95KCk7XG5cbiAgICAgICAgICBpZiAodGhpcy5jb25uZWN0ZWQpIHtcbiAgICAgICAgICAgIC8vIGZpcmUgZXZlbnRzXG4gICAgICAgICAgICB0aGlzLm9uY2xvc2UoJ2lvIGNsaWVudCBkaXNjb25uZWN0Jyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTZXRzIHRoZSBjb21wcmVzcyBmbGFnLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge0Jvb2xlYW59IGlmIGB0cnVlYCwgY29tcHJlc3NlcyB0aGUgc2VuZGluZyBkYXRhXG4gICAgICAgICAqIEByZXR1cm4ge1NvY2tldH0gc2VsZlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBTb2NrZXQucHJvdG90eXBlLmNvbXByZXNzID0gZnVuY3Rpb24gKGNvbXByZXNzKSB7XG4gICAgICAgICAgdGhpcy5mbGFncyA9IHRoaXMuZmxhZ3MgfHwge307XG4gICAgICAgICAgdGhpcy5mbGFncy5jb21wcmVzcyA9IGNvbXByZXNzO1xuICAgICAgICAgIHJldHVybiB0aGlzO1xuICAgICAgICB9O1xuICAgICAgfSwgeyBcIi4vb25cIjogMzMsIFwiY29tcG9uZW50LWJpbmRcIjogMzcsIFwiY29tcG9uZW50LWVtaXR0ZXJcIjogMzgsIFwiZGVidWdcIjogMzksIFwiaGFzLWJpbmFyeVwiOiA0MSwgXCJzb2NrZXQuaW8tcGFyc2VyXCI6IDQ3LCBcInRvLWFycmF5XCI6IDUxIH1dLCAzNTogW2Z1bmN0aW9uIChfZGVyZXFfLCBtb2R1bGUsIGV4cG9ydHMpIHtcbiAgICAgICAgKGZ1bmN0aW9uIChnbG9iYWwpIHtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIE1vZHVsZSBkZXBlbmRlbmNpZXMuXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICB2YXIgcGFyc2V1cmkgPSBfZGVyZXFfKCdwYXJzZXVyaScpO1xuICAgICAgICAgIHZhciBkZWJ1ZyA9IF9kZXJlcV8oJ2RlYnVnJykoJ3NvY2tldC5pby1jbGllbnQ6dXJsJyk7XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBNb2R1bGUgZXhwb3J0cy5cbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIG1vZHVsZS5leHBvcnRzID0gdXJsO1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogVVJMIHBhcnNlci5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSB1cmxcbiAgICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gQW4gb2JqZWN0IG1lYW50IHRvIG1pbWljIHdpbmRvdy5sb2NhdGlvbi5cbiAgICAgICAgICAgKiAgICAgICAgICAgICAgICAgRGVmYXVsdHMgdG8gd2luZG93LmxvY2F0aW9uLlxuICAgICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBmdW5jdGlvbiB1cmwodXJpLCBsb2MpIHtcbiAgICAgICAgICAgIHZhciBvYmogPSB1cmk7XG5cbiAgICAgICAgICAgIC8vIGRlZmF1bHQgdG8gd2luZG93LmxvY2F0aW9uXG4gICAgICAgICAgICB2YXIgbG9jID0gbG9jIHx8IGdsb2JhbC5sb2NhdGlvbjtcbiAgICAgICAgICAgIGlmIChudWxsID09IHVyaSkgdXJpID0gbG9jLnByb3RvY29sICsgJy8vJyArIGxvYy5ob3N0O1xuXG4gICAgICAgICAgICAvLyByZWxhdGl2ZSBwYXRoIHN1cHBvcnRcbiAgICAgICAgICAgIGlmICgnc3RyaW5nJyA9PSB0eXBlb2YgdXJpKSB7XG4gICAgICAgICAgICAgIGlmICgnLycgPT0gdXJpLmNoYXJBdCgwKSkge1xuICAgICAgICAgICAgICAgIGlmICgnLycgPT0gdXJpLmNoYXJBdCgxKSkge1xuICAgICAgICAgICAgICAgICAgdXJpID0gbG9jLnByb3RvY29sICsgdXJpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICB1cmkgPSBsb2MuaG9zdCArIHVyaTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBpZiAoIS9eKGh0dHBzP3x3c3M/KTpcXC9cXC8vLnRlc3QodXJpKSkge1xuICAgICAgICAgICAgICAgIGRlYnVnKCdwcm90b2NvbC1sZXNzIHVybCAlcycsIHVyaSk7XG4gICAgICAgICAgICAgICAgaWYgKCd1bmRlZmluZWQnICE9IHR5cGVvZiBsb2MpIHtcbiAgICAgICAgICAgICAgICAgIHVyaSA9IGxvYy5wcm90b2NvbCArICcvLycgKyB1cmk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHVyaSA9ICdodHRwczovLycgKyB1cmk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgLy8gcGFyc2VcbiAgICAgICAgICAgICAgZGVidWcoJ3BhcnNlICVzJywgdXJpKTtcbiAgICAgICAgICAgICAgb2JqID0gcGFyc2V1cmkodXJpKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gbWFrZSBzdXJlIHdlIHRyZWF0IGBsb2NhbGhvc3Q6ODBgIGFuZCBgbG9jYWxob3N0YCBlcXVhbGx5XG4gICAgICAgICAgICBpZiAoIW9iai5wb3J0KSB7XG4gICAgICAgICAgICAgIGlmICgvXihodHRwfHdzKSQvLnRlc3Qob2JqLnByb3RvY29sKSkge1xuICAgICAgICAgICAgICAgIG9iai5wb3J0ID0gJzgwJztcbiAgICAgICAgICAgICAgfSBlbHNlIGlmICgvXihodHRwfHdzKXMkLy50ZXN0KG9iai5wcm90b2NvbCkpIHtcbiAgICAgICAgICAgICAgICBvYmoucG9ydCA9ICc0NDMnO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG9iai5wYXRoID0gb2JqLnBhdGggfHwgJy8nO1xuXG4gICAgICAgICAgICB2YXIgaXB2NiA9IG9iai5ob3N0LmluZGV4T2YoJzonKSAhPT0gLTE7XG4gICAgICAgICAgICB2YXIgaG9zdCA9IGlwdjYgPyAnWycgKyBvYmouaG9zdCArICddJyA6IG9iai5ob3N0O1xuXG4gICAgICAgICAgICAvLyBkZWZpbmUgdW5pcXVlIGlkXG4gICAgICAgICAgICBvYmouaWQgPSBvYmoucHJvdG9jb2wgKyAnOi8vJyArIGhvc3QgKyAnOicgKyBvYmoucG9ydDtcbiAgICAgICAgICAgIC8vIGRlZmluZSBocmVmXG4gICAgICAgICAgICBvYmouaHJlZiA9IG9iai5wcm90b2NvbCArICc6Ly8nICsgaG9zdCArIChsb2MgJiYgbG9jLnBvcnQgPT0gb2JqLnBvcnQgPyAnJyA6ICc6JyArIG9iai5wb3J0KTtcblxuICAgICAgICAgICAgcmV0dXJuIG9iajtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLmNhbGwodGhpcywgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB7fSk7XG4gICAgICB9LCB7IFwiZGVidWdcIjogMzksIFwicGFyc2V1cmlcIjogNDUgfV0sIDM2OiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBFeHBvc2UgYEJhY2tvZmZgLlxuICAgICAgICAgKi9cblxuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IEJhY2tvZmY7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEluaXRpYWxpemUgYmFja29mZiB0aW1lciB3aXRoIGBvcHRzYC5cbiAgICAgICAgICpcbiAgICAgICAgICogLSBgbWluYCBpbml0aWFsIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzIFsxMDBdXG4gICAgICAgICAqIC0gYG1heGAgbWF4IHRpbWVvdXQgWzEwMDAwXVxuICAgICAgICAgKiAtIGBqaXR0ZXJgIFswXVxuICAgICAgICAgKiAtIGBmYWN0b3JgIFsyXVxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gb3B0c1xuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBmdW5jdGlvbiBCYWNrb2ZmKG9wdHMpIHtcbiAgICAgICAgICBvcHRzID0gb3B0cyB8fCB7fTtcbiAgICAgICAgICB0aGlzLm1zID0gb3B0cy5taW4gfHwgMTAwO1xuICAgICAgICAgIHRoaXMubWF4ID0gb3B0cy5tYXggfHwgMTAwMDA7XG4gICAgICAgICAgdGhpcy5mYWN0b3IgPSBvcHRzLmZhY3RvciB8fCAyO1xuICAgICAgICAgIHRoaXMuaml0dGVyID0gb3B0cy5qaXR0ZXIgPiAwICYmIG9wdHMuaml0dGVyIDw9IDEgPyBvcHRzLmppdHRlciA6IDA7XG4gICAgICAgICAgdGhpcy5hdHRlbXB0cyA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogUmV0dXJuIHRoZSBiYWNrb2ZmIGR1cmF0aW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9XG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIEJhY2tvZmYucHJvdG90eXBlLmR1cmF0aW9uID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHZhciBtcyA9IHRoaXMubXMgKiBNYXRoLnBvdyh0aGlzLmZhY3RvciwgdGhpcy5hdHRlbXB0cysrKTtcbiAgICAgICAgICBpZiAodGhpcy5qaXR0ZXIpIHtcbiAgICAgICAgICAgIHZhciByYW5kID0gTWF0aC5yYW5kb20oKTtcbiAgICAgICAgICAgIHZhciBkZXZpYXRpb24gPSBNYXRoLmZsb29yKHJhbmQgKiB0aGlzLmppdHRlciAqIG1zKTtcbiAgICAgICAgICAgIG1zID0gKE1hdGguZmxvb3IocmFuZCAqIDEwKSAmIDEpID09IDAgPyBtcyAtIGRldmlhdGlvbiA6IG1zICsgZGV2aWF0aW9uO1xuICAgICAgICAgIH1cbiAgICAgICAgICByZXR1cm4gTWF0aC5taW4obXMsIHRoaXMubWF4KSB8IDA7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJlc2V0IHRoZSBudW1iZXIgb2YgYXR0ZW1wdHMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIEJhY2tvZmYucHJvdG90eXBlLnJlc2V0ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIHRoaXMuYXR0ZW1wdHMgPSAwO1xuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTZXQgdGhlIG1pbmltdW0gZHVyYXRpb25cbiAgICAgICAgICpcbiAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICovXG5cbiAgICAgICAgQmFja29mZi5wcm90b3R5cGUuc2V0TWluID0gZnVuY3Rpb24gKG1pbikge1xuICAgICAgICAgIHRoaXMubXMgPSBtaW47XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNldCB0aGUgbWF4aW11bSBkdXJhdGlvblxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBCYWNrb2ZmLnByb3RvdHlwZS5zZXRNYXggPSBmdW5jdGlvbiAobWF4KSB7XG4gICAgICAgICAgdGhpcy5tYXggPSBtYXg7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFNldCB0aGUgaml0dGVyXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIEJhY2tvZmYucHJvdG90eXBlLnNldEppdHRlciA9IGZ1bmN0aW9uIChqaXR0ZXIpIHtcbiAgICAgICAgICB0aGlzLmppdHRlciA9IGppdHRlcjtcbiAgICAgICAgfTtcbiAgICAgIH0sIHt9XSwgMzc6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTbGljZSByZWZlcmVuY2UuXG4gICAgICAgICAqL1xuXG4gICAgICAgIHZhciBzbGljZSA9IFtdLnNsaWNlO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBCaW5kIGBvYmpgIHRvIGBmbmAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbnxTdHJpbmd9IGZuIG9yIHN0cmluZ1xuICAgICAgICAgKiBAcmV0dXJuIHtGdW5jdGlvbn1cbiAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICovXG5cbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiAob2JqLCBmbikge1xuICAgICAgICAgIGlmICgnc3RyaW5nJyA9PSB0eXBlb2YgZm4pIGZuID0gb2JqW2ZuXTtcbiAgICAgICAgICBpZiAoJ2Z1bmN0aW9uJyAhPSB0eXBlb2YgZm4pIHRocm93IG5ldyBFcnJvcignYmluZCgpIHJlcXVpcmVzIGEgZnVuY3Rpb24nKTtcbiAgICAgICAgICB2YXIgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTtcbiAgICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICAgICAgcmV0dXJuIGZuLmFwcGx5KG9iaiwgYXJncy5jb25jYXQoc2xpY2UuY2FsbChhcmd1bWVudHMpKSk7XG4gICAgICAgICAgfTtcbiAgICAgICAgfTtcbiAgICAgIH0sIHt9XSwgMzg6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEV4cG9zZSBgRW1pdHRlcmAuXG4gICAgICAgICAqL1xuXG4gICAgICAgIG1vZHVsZS5leHBvcnRzID0gRW1pdHRlcjtcblxuICAgICAgICAvKipcbiAgICAgICAgICogSW5pdGlhbGl6ZSBhIG5ldyBgRW1pdHRlcmAuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIGZ1bmN0aW9uIEVtaXR0ZXIob2JqKSB7XG4gICAgICAgICAgaWYgKG9iaikgcmV0dXJuIG1peGluKG9iaik7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIE1peGluIHRoZSBlbWl0dGVyIHByb3BlcnRpZXMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvYmpcbiAgICAgICAgICogQHJldHVybiB7T2JqZWN0fVxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgZnVuY3Rpb24gbWl4aW4ob2JqKSB7XG4gICAgICAgICAgZm9yICh2YXIga2V5IGluIEVtaXR0ZXIucHJvdG90eXBlKSB7XG4gICAgICAgICAgICBvYmpba2V5XSA9IEVtaXR0ZXIucHJvdG90eXBlW2tleV07XG4gICAgICAgICAgfVxuICAgICAgICAgIHJldHVybiBvYmo7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogTGlzdGVuIG9uIHRoZSBnaXZlbiBgZXZlbnRgIHdpdGggYGZuYC5cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gICAgICAgICAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIEVtaXR0ZXIucHJvdG90eXBlLm9uID0gRW1pdHRlci5wcm90b3R5cGUuYWRkRXZlbnRMaXN0ZW5lciA9IGZ1bmN0aW9uIChldmVudCwgZm4pIHtcbiAgICAgICAgICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XG4gICAgICAgICAgKHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gPSB0aGlzLl9jYWxsYmFja3NbJyQnICsgZXZlbnRdIHx8IFtdKS5wdXNoKGZuKTtcbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogQWRkcyBhbiBgZXZlbnRgIGxpc3RlbmVyIHRoYXQgd2lsbCBiZSBpbnZva2VkIGEgc2luZ2xlXG4gICAgICAgICAqIHRpbWUgdGhlbiBhdXRvbWF0aWNhbGx5IHJlbW92ZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudFxuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmblxuICAgICAgICAgKiBAcmV0dXJuIHtFbWl0dGVyfVxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24gKGV2ZW50LCBmbikge1xuICAgICAgICAgIGZ1bmN0aW9uIG9uKCkge1xuICAgICAgICAgICAgdGhpcy5vZmYoZXZlbnQsIG9uKTtcbiAgICAgICAgICAgIGZuLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgb24uZm4gPSBmbjtcbiAgICAgICAgICB0aGlzLm9uKGV2ZW50LCBvbik7XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFJlbW92ZSB0aGUgZ2l2ZW4gY2FsbGJhY2sgZm9yIGBldmVudGAgb3IgYWxsXG4gICAgICAgICAqIHJlZ2lzdGVyZWQgY2FsbGJhY2tzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZm5cbiAgICAgICAgICogQHJldHVybiB7RW1pdHRlcn1cbiAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICovXG5cbiAgICAgICAgRW1pdHRlci5wcm90b3R5cGUub2ZmID0gRW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPSBFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVBbGxMaXN0ZW5lcnMgPSBFbWl0dGVyLnByb3RvdHlwZS5yZW1vdmVFdmVudExpc3RlbmVyID0gZnVuY3Rpb24gKGV2ZW50LCBmbikge1xuICAgICAgICAgIHRoaXMuX2NhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrcyB8fCB7fTtcblxuICAgICAgICAgIC8vIGFsbFxuICAgICAgICAgIGlmICgwID09IGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgICAgIHRoaXMuX2NhbGxiYWNrcyA9IHt9O1xuICAgICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gc3BlY2lmaWMgZXZlbnRcbiAgICAgICAgICB2YXIgY2FsbGJhY2tzID0gdGhpcy5fY2FsbGJhY2tzWyckJyArIGV2ZW50XTtcbiAgICAgICAgICBpZiAoIWNhbGxiYWNrcykgcmV0dXJuIHRoaXM7XG5cbiAgICAgICAgICAvLyByZW1vdmUgYWxsIGhhbmRsZXJzXG4gICAgICAgICAgaWYgKDEgPT0gYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF07XG4gICAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyByZW1vdmUgc3BlY2lmaWMgaGFuZGxlclxuICAgICAgICAgIHZhciBjYjtcbiAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNhbGxiYWNrcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgY2IgPSBjYWxsYmFja3NbaV07XG4gICAgICAgICAgICBpZiAoY2IgPT09IGZuIHx8IGNiLmZuID09PSBmbikge1xuICAgICAgICAgICAgICBjYWxsYmFja3Muc3BsaWNlKGksIDEpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVtaXQgYGV2ZW50YCB3aXRoIHRoZSBnaXZlbiBhcmdzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnRcbiAgICAgICAgICogQHBhcmFtIHtNaXhlZH0gLi4uXG4gICAgICAgICAqIEByZXR1cm4ge0VtaXR0ZXJ9XG4gICAgICAgICAqL1xuXG4gICAgICAgIEVtaXR0ZXIucHJvdG90eXBlLmVtaXQgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XG4gICAgICAgICAgdmFyIGFyZ3MgPSBbXS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSksXG4gICAgICAgICAgICAgIGNhbGxiYWNrcyA9IHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF07XG5cbiAgICAgICAgICBpZiAoY2FsbGJhY2tzKSB7XG4gICAgICAgICAgICBjYWxsYmFja3MgPSBjYWxsYmFja3Muc2xpY2UoMCk7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gY2FsbGJhY2tzLmxlbmd0aDsgaSA8IGxlbjsgKytpKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrc1tpXS5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gdGhpcztcbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUmV0dXJuIGFycmF5IG9mIGNhbGxiYWNrcyBmb3IgYGV2ZW50YC5cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gICAgICAgICAqIEByZXR1cm4ge0FycmF5fVxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBFbWl0dGVyLnByb3RvdHlwZS5saXN0ZW5lcnMgPSBmdW5jdGlvbiAoZXZlbnQpIHtcbiAgICAgICAgICB0aGlzLl9jYWxsYmFja3MgPSB0aGlzLl9jYWxsYmFja3MgfHwge307XG4gICAgICAgICAgcmV0dXJuIHRoaXMuX2NhbGxiYWNrc1snJCcgKyBldmVudF0gfHwgW107XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENoZWNrIGlmIHRoaXMgZW1pdHRlciBoYXMgYGV2ZW50YCBoYW5kbGVycy5cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50XG4gICAgICAgICAqIEByZXR1cm4ge0Jvb2xlYW59XG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIEVtaXR0ZXIucHJvdG90eXBlLmhhc0xpc3RlbmVycyA9IGZ1bmN0aW9uIChldmVudCkge1xuICAgICAgICAgIHJldHVybiAhIXRoaXMubGlzdGVuZXJzKGV2ZW50KS5sZW5ndGg7XG4gICAgICAgIH07XG4gICAgICB9LCB7fV0sIDM5OiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuICAgICAgICBhcmd1bWVudHNbNF1bMTddWzBdLmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cyk7XG4gICAgICB9LCB7IFwiLi9kZWJ1Z1wiOiA0MCwgXCJkdXBcIjogMTcgfV0sIDQwOiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuICAgICAgICBhcmd1bWVudHNbNF1bMThdWzBdLmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cyk7XG4gICAgICB9LCB7IFwiZHVwXCI6IDE4LCBcIm1zXCI6IDQ0IH1dLCA0MTogW2Z1bmN0aW9uIChfZGVyZXFfLCBtb2R1bGUsIGV4cG9ydHMpIHtcbiAgICAgICAgKGZ1bmN0aW9uIChnbG9iYWwpIHtcblxuICAgICAgICAgIC8qXG4gICAgICAgICAgICogTW9kdWxlIHJlcXVpcmVtZW50cy5cbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIHZhciBpc0FycmF5ID0gX2RlcmVxXygnaXNhcnJheScpO1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogTW9kdWxlIGV4cG9ydHMuXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGhhc0JpbmFyeTtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIENoZWNrcyBmb3IgYmluYXJ5IGRhdGEuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBSaWdodCBub3cgb25seSBCdWZmZXIgYW5kIEFycmF5QnVmZmVyIGFyZSBzdXBwb3J0ZWQuLlxuICAgICAgICAgICAqXG4gICAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IGFueXRoaW5nXG4gICAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIGZ1bmN0aW9uIGhhc0JpbmFyeShkYXRhKSB7XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIF9oYXNCaW5hcnkob2JqKSB7XG4gICAgICAgICAgICAgIGlmICghb2JqKSByZXR1cm4gZmFsc2U7XG5cbiAgICAgICAgICAgICAgaWYgKGdsb2JhbC5CdWZmZXIgJiYgZ2xvYmFsLkJ1ZmZlci5pc0J1ZmZlciAmJiBnbG9iYWwuQnVmZmVyLmlzQnVmZmVyKG9iaikgfHwgZ2xvYmFsLkFycmF5QnVmZmVyICYmIG9iaiBpbnN0YW5jZW9mIEFycmF5QnVmZmVyIHx8IGdsb2JhbC5CbG9iICYmIG9iaiBpbnN0YW5jZW9mIEJsb2IgfHwgZ2xvYmFsLkZpbGUgJiYgb2JqIGluc3RhbmNlb2YgRmlsZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgaWYgKGlzQXJyYXkob2JqKSkge1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2JqLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICBpZiAoX2hhc0JpbmFyeShvYmpbaV0pKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChvYmogJiYgJ29iamVjdCcgPT0gKHR5cGVvZiBvYmogPT09IFwidW5kZWZpbmVkXCIgPyBcInVuZGVmaW5lZFwiIDogX3R5cGVvZihvYmopKSkge1xuICAgICAgICAgICAgICAgIC8vIHNlZTogaHR0cHM6Ly9naXRodWIuY29tL0F1dG9tYXR0aWMvaGFzLWJpbmFyeS9wdWxsLzRcbiAgICAgICAgICAgICAgICBpZiAob2JqLnRvSlNPTiAmJiAnZnVuY3Rpb24nID09IHR5cGVvZiBvYmoudG9KU09OKSB7XG4gICAgICAgICAgICAgICAgICBvYmogPSBvYmoudG9KU09OKCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgICAgICAgICAgICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIGtleSkgJiYgX2hhc0JpbmFyeShvYmpba2V5XSkpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4gX2hhc0JpbmFyeShkYXRhKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLmNhbGwodGhpcywgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB7fSk7XG4gICAgICB9LCB7IFwiaXNhcnJheVwiOiA0MyB9XSwgNDI6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG4gICAgICAgIGFyZ3VtZW50c1s0XVsyM11bMF0uYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKTtcbiAgICAgIH0sIHsgXCJkdXBcIjogMjMgfV0sIDQzOiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuICAgICAgICBhcmd1bWVudHNbNF1bMjRdWzBdLmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cyk7XG4gICAgICB9LCB7IFwiZHVwXCI6IDI0IH1dLCA0NDogW2Z1bmN0aW9uIChfZGVyZXFfLCBtb2R1bGUsIGV4cG9ydHMpIHtcbiAgICAgICAgYXJndW1lbnRzWzRdWzI1XVswXS5hcHBseShleHBvcnRzLCBhcmd1bWVudHMpO1xuICAgICAgfSwgeyBcImR1cFwiOiAyNSB9XSwgNDU6IFtmdW5jdGlvbiAoX2RlcmVxXywgbW9kdWxlLCBleHBvcnRzKSB7XG4gICAgICAgIGFyZ3VtZW50c1s0XVsyOF1bMF0uYXBwbHkoZXhwb3J0cywgYXJndW1lbnRzKTtcbiAgICAgIH0sIHsgXCJkdXBcIjogMjggfV0sIDQ2OiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuICAgICAgICAoZnVuY3Rpb24gKGdsb2JhbCkge1xuICAgICAgICAgIC8qZ2xvYmFsIEJsb2IsRmlsZSovXG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBNb2R1bGUgcmVxdWlyZW1lbnRzXG4gICAgICAgICAgICovXG5cbiAgICAgICAgICB2YXIgaXNBcnJheSA9IF9kZXJlcV8oJ2lzYXJyYXknKTtcbiAgICAgICAgICB2YXIgaXNCdWYgPSBfZGVyZXFfKCcuL2lzLWJ1ZmZlcicpO1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogUmVwbGFjZXMgZXZlcnkgQnVmZmVyIHwgQXJyYXlCdWZmZXIgaW4gcGFja2V0IHdpdGggYSBudW1iZXJlZCBwbGFjZWhvbGRlci5cbiAgICAgICAgICAgKiBBbnl0aGluZyB3aXRoIGJsb2JzIG9yIGZpbGVzIHNob3VsZCBiZSBmZWQgdGhyb3VnaCByZW1vdmVCbG9icyBiZWZvcmUgY29taW5nXG4gICAgICAgICAgICogaGVyZS5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXQgLSBzb2NrZXQuaW8gZXZlbnQgcGFja2V0XG4gICAgICAgICAgICogQHJldHVybiB7T2JqZWN0fSB3aXRoIGRlY29uc3RydWN0ZWQgcGFja2V0IGFuZCBsaXN0IG9mIGJ1ZmZlcnNcbiAgICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgZXhwb3J0cy5kZWNvbnN0cnVjdFBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQpIHtcbiAgICAgICAgICAgIHZhciBidWZmZXJzID0gW107XG4gICAgICAgICAgICB2YXIgcGFja2V0RGF0YSA9IHBhY2tldC5kYXRhO1xuXG4gICAgICAgICAgICBmdW5jdGlvbiBfZGVjb25zdHJ1Y3RQYWNrZXQoZGF0YSkge1xuICAgICAgICAgICAgICBpZiAoIWRhdGEpIHJldHVybiBkYXRhO1xuXG4gICAgICAgICAgICAgIGlmIChpc0J1ZihkYXRhKSkge1xuICAgICAgICAgICAgICAgIHZhciBwbGFjZWhvbGRlciA9IHsgX3BsYWNlaG9sZGVyOiB0cnVlLCBudW06IGJ1ZmZlcnMubGVuZ3RoIH07XG4gICAgICAgICAgICAgICAgYnVmZmVycy5wdXNoKGRhdGEpO1xuICAgICAgICAgICAgICAgIHJldHVybiBwbGFjZWhvbGRlcjtcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgdmFyIG5ld0RhdGEgPSBuZXcgQXJyYXkoZGF0YS5sZW5ndGgpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgbmV3RGF0YVtpXSA9IF9kZWNvbnN0cnVjdFBhY2tldChkYXRhW2ldKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ld0RhdGE7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAoJ29iamVjdCcgPT0gKHR5cGVvZiBkYXRhID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6IF90eXBlb2YoZGF0YSkpICYmICEoZGF0YSBpbnN0YW5jZW9mIERhdGUpKSB7XG4gICAgICAgICAgICAgICAgdmFyIG5ld0RhdGEgPSB7fTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBrZXkgaW4gZGF0YSkge1xuICAgICAgICAgICAgICAgICAgbmV3RGF0YVtrZXldID0gX2RlY29uc3RydWN0UGFja2V0KGRhdGFba2V5XSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBuZXdEYXRhO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB2YXIgcGFjayA9IHBhY2tldDtcbiAgICAgICAgICAgIHBhY2suZGF0YSA9IF9kZWNvbnN0cnVjdFBhY2tldChwYWNrZXREYXRhKTtcbiAgICAgICAgICAgIHBhY2suYXR0YWNobWVudHMgPSBidWZmZXJzLmxlbmd0aDsgLy8gbnVtYmVyIG9mIGJpbmFyeSAnYXR0YWNobWVudHMnXG4gICAgICAgICAgICByZXR1cm4geyBwYWNrZXQ6IHBhY2ssIGJ1ZmZlcnM6IGJ1ZmZlcnMgfTtcbiAgICAgICAgICB9O1xuXG4gICAgICAgICAgLyoqXG4gICAgICAgICAgICogUmVjb25zdHJ1Y3RzIGEgYmluYXJ5IHBhY2tldCBmcm9tIGl0cyBwbGFjZWhvbGRlciBwYWNrZXQgYW5kIGJ1ZmZlcnNcbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXQgLSBldmVudCBwYWNrZXQgd2l0aCBwbGFjZWhvbGRlcnNcbiAgICAgICAgICAgKiBAcGFyYW0ge0FycmF5fSBidWZmZXJzIC0gYmluYXJ5IGJ1ZmZlcnMgdG8gcHV0IGluIHBsYWNlaG9sZGVyIHBvc2l0aW9uc1xuICAgICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gcmVjb25zdHJ1Y3RlZCBwYWNrZXRcbiAgICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgICAqL1xuXG4gICAgICAgICAgZXhwb3J0cy5yZWNvbnN0cnVjdFBhY2tldCA9IGZ1bmN0aW9uIChwYWNrZXQsIGJ1ZmZlcnMpIHtcbiAgICAgICAgICAgIHZhciBjdXJQbGFjZUhvbGRlciA9IDA7XG5cbiAgICAgICAgICAgIGZ1bmN0aW9uIF9yZWNvbnN0cnVjdFBhY2tldChkYXRhKSB7XG4gICAgICAgICAgICAgIGlmIChkYXRhICYmIGRhdGEuX3BsYWNlaG9sZGVyKSB7XG4gICAgICAgICAgICAgICAgdmFyIGJ1ZiA9IGJ1ZmZlcnNbZGF0YS5udW1dOyAvLyBhcHByb3ByaWF0ZSBidWZmZXIgKHNob3VsZCBiZSBuYXR1cmFsIG9yZGVyIGFueXdheSlcbiAgICAgICAgICAgICAgICByZXR1cm4gYnVmO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgIGRhdGFbaV0gPSBfcmVjb25zdHJ1Y3RQYWNrZXQoZGF0YVtpXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhO1xuICAgICAgICAgICAgICB9IGVsc2UgaWYgKGRhdGEgJiYgJ29iamVjdCcgPT0gKHR5cGVvZiBkYXRhID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6IF90eXBlb2YoZGF0YSkpKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIGRhdGEpIHtcbiAgICAgICAgICAgICAgICAgIGRhdGFba2V5XSA9IF9yZWNvbnN0cnVjdFBhY2tldChkYXRhW2tleV0pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICByZXR1cm4gZGF0YTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcGFja2V0LmRhdGEgPSBfcmVjb25zdHJ1Y3RQYWNrZXQocGFja2V0LmRhdGEpO1xuICAgICAgICAgICAgcGFja2V0LmF0dGFjaG1lbnRzID0gdW5kZWZpbmVkOyAvLyBubyBsb25nZXIgdXNlZnVsXG4gICAgICAgICAgICByZXR1cm4gcGFja2V0O1xuICAgICAgICAgIH07XG5cbiAgICAgICAgICAvKipcbiAgICAgICAgICAgKiBBc3luY2hyb25vdXNseSByZW1vdmVzIEJsb2JzIG9yIEZpbGVzIGZyb20gZGF0YSB2aWFcbiAgICAgICAgICAgKiBGaWxlUmVhZGVyJ3MgcmVhZEFzQXJyYXlCdWZmZXIgbWV0aG9kLiBVc2VkIGJlZm9yZSBlbmNvZGluZ1xuICAgICAgICAgICAqIGRhdGEgYXMgbXNncGFjay4gQ2FsbHMgY2FsbGJhY2sgd2l0aCB0aGUgYmxvYmxlc3MgZGF0YS5cbiAgICAgICAgICAgKlxuICAgICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBkYXRhXG4gICAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIGV4cG9ydHMucmVtb3ZlQmxvYnMgPSBmdW5jdGlvbiAoZGF0YSwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGZ1bmN0aW9uIF9yZW1vdmVCbG9icyhvYmosIGN1cktleSwgY29udGFpbmluZ09iamVjdCkge1xuICAgICAgICAgICAgICBpZiAoIW9iaikgcmV0dXJuIG9iajtcblxuICAgICAgICAgICAgICAvLyBjb252ZXJ0IGFueSBibG9iXG4gICAgICAgICAgICAgIGlmIChnbG9iYWwuQmxvYiAmJiBvYmogaW5zdGFuY2VvZiBCbG9iIHx8IGdsb2JhbC5GaWxlICYmIG9iaiBpbnN0YW5jZW9mIEZpbGUpIHtcbiAgICAgICAgICAgICAgICBwZW5kaW5nQmxvYnMrKztcblxuICAgICAgICAgICAgICAgIC8vIGFzeW5jIGZpbGVyZWFkZXJcbiAgICAgICAgICAgICAgICB2YXIgZmlsZVJlYWRlciA9IG5ldyBGaWxlUmVhZGVyKCk7XG4gICAgICAgICAgICAgICAgZmlsZVJlYWRlci5vbmxvYWQgPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgICAvLyB0aGlzLnJlc3VsdCA9PSBhcnJheWJ1ZmZlclxuICAgICAgICAgICAgICAgICAgaWYgKGNvbnRhaW5pbmdPYmplY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgY29udGFpbmluZ09iamVjdFtjdXJLZXldID0gdGhpcy5yZXN1bHQ7XG4gICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBibG9ibGVzc0RhdGEgPSB0aGlzLnJlc3VsdDtcbiAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgLy8gaWYgbm90aGluZyBwZW5kaW5nIGl0cyBjYWxsYmFjayB0aW1lXG4gICAgICAgICAgICAgICAgICBpZiAoISAtLXBlbmRpbmdCbG9icykge1xuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhibG9ibGVzc0RhdGEpO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICBmaWxlUmVhZGVyLnJlYWRBc0FycmF5QnVmZmVyKG9iaik7IC8vIGJsb2IgLT4gYXJyYXlidWZmZXJcbiAgICAgICAgICAgICAgfSBlbHNlIGlmIChpc0FycmF5KG9iaikpIHtcbiAgICAgICAgICAgICAgICAvLyBoYW5kbGUgYXJyYXlcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9iai5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgICAgX3JlbW92ZUJsb2JzKG9ialtpXSwgaSwgb2JqKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAob2JqICYmICdvYmplY3QnID09ICh0eXBlb2Ygb2JqID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6IF90eXBlb2Yob2JqKSkgJiYgIWlzQnVmKG9iaikpIHtcbiAgICAgICAgICAgICAgICAvLyBhbmQgb2JqZWN0XG4gICAgICAgICAgICAgICAgZm9yICh2YXIga2V5IGluIG9iaikge1xuICAgICAgICAgICAgICAgICAgX3JlbW92ZUJsb2JzKG9ialtrZXldLCBrZXksIG9iaik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHZhciBwZW5kaW5nQmxvYnMgPSAwO1xuICAgICAgICAgICAgdmFyIGJsb2JsZXNzRGF0YSA9IGRhdGE7XG4gICAgICAgICAgICBfcmVtb3ZlQmxvYnMoYmxvYmxlc3NEYXRhKTtcbiAgICAgICAgICAgIGlmICghcGVuZGluZ0Jsb2JzKSB7XG4gICAgICAgICAgICAgIGNhbGxiYWNrKGJsb2JsZXNzRGF0YSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgfSkuY2FsbCh0aGlzLCB0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDogdHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIiA/IGdsb2JhbCA6IHt9KTtcbiAgICAgIH0sIHsgXCIuL2lzLWJ1ZmZlclwiOiA0OCwgXCJpc2FycmF5XCI6IDQzIH1dLCA0NzogW2Z1bmN0aW9uIChfZGVyZXFfLCBtb2R1bGUsIGV4cG9ydHMpIHtcblxuICAgICAgICAvKipcbiAgICAgICAgICogTW9kdWxlIGRlcGVuZGVuY2llcy5cbiAgICAgICAgICovXG5cbiAgICAgICAgdmFyIGRlYnVnID0gX2RlcmVxXygnZGVidWcnKSgnc29ja2V0LmlvLXBhcnNlcicpO1xuICAgICAgICB2YXIganNvbiA9IF9kZXJlcV8oJ2pzb24zJyk7XG4gICAgICAgIHZhciBpc0FycmF5ID0gX2RlcmVxXygnaXNhcnJheScpO1xuICAgICAgICB2YXIgRW1pdHRlciA9IF9kZXJlcV8oJ2NvbXBvbmVudC1lbWl0dGVyJyk7XG4gICAgICAgIHZhciBiaW5hcnkgPSBfZGVyZXFfKCcuL2JpbmFyeScpO1xuICAgICAgICB2YXIgaXNCdWYgPSBfZGVyZXFfKCcuL2lzLWJ1ZmZlcicpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQcm90b2NvbCB2ZXJzaW9uLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBleHBvcnRzLnByb3RvY29sID0gNDtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUGFja2V0IHR5cGVzLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBleHBvcnRzLnR5cGVzID0gWydDT05ORUNUJywgJ0RJU0NPTk5FQ1QnLCAnRVZFTlQnLCAnQklOQVJZX0VWRU5UJywgJ0FDSycsICdCSU5BUllfQUNLJywgJ0VSUk9SJ107XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFBhY2tldCB0eXBlIGBjb25uZWN0YC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICovXG5cbiAgICAgICAgZXhwb3J0cy5DT05ORUNUID0gMDtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUGFja2V0IHR5cGUgYGRpc2Nvbm5lY3RgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBleHBvcnRzLkRJU0NPTk5FQ1QgPSAxO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBQYWNrZXQgdHlwZSBgZXZlbnRgLlxuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBleHBvcnRzLkVWRU5UID0gMjtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUGFja2V0IHR5cGUgYGFja2AuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIGV4cG9ydHMuQUNLID0gMztcblxuICAgICAgICAvKipcbiAgICAgICAgICogUGFja2V0IHR5cGUgYGVycm9yYC5cbiAgICAgICAgICpcbiAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICovXG5cbiAgICAgICAgZXhwb3J0cy5FUlJPUiA9IDQ7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIFBhY2tldCB0eXBlICdiaW5hcnkgZXZlbnQnXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIGV4cG9ydHMuQklOQVJZX0VWRU5UID0gNTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogUGFja2V0IHR5cGUgYGJpbmFyeSBhY2tgLiBGb3IgYWNrcyB3aXRoIGJpbmFyeSBhcmd1bWVudHMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIGV4cG9ydHMuQklOQVJZX0FDSyA9IDY7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZXIgY29uc3RydWN0b3IuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIGV4cG9ydHMuRW5jb2RlciA9IEVuY29kZXI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlY29kZXIgY29uc3RydWN0b3IuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIGV4cG9ydHMuRGVjb2RlciA9IERlY29kZXI7XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEEgc29ja2V0LmlvIEVuY29kZXIgaW5zdGFuY2VcbiAgICAgICAgICpcbiAgICAgICAgICogQGFwaSBwdWJsaWNcbiAgICAgICAgICovXG5cbiAgICAgICAgZnVuY3Rpb24gRW5jb2RlcigpIHt9XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIEVuY29kZSBhIHBhY2tldCBhcyBhIHNpbmdsZSBzdHJpbmcgaWYgbm9uLWJpbmFyeSwgb3IgYXMgYVxuICAgICAgICAgKiBidWZmZXIgc2VxdWVuY2UsIGRlcGVuZGluZyBvbiBwYWNrZXQgdHlwZS5cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IG9iaiAtIHBhY2tldCBvYmplY3RcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgLSBmdW5jdGlvbiB0byBoYW5kbGUgZW5jb2RpbmdzIChsaWtlbHkgZW5naW5lLndyaXRlKVxuICAgICAgICAgKiBAcmV0dXJuIENhbGxzIGNhbGxiYWNrIHdpdGggQXJyYXkgb2YgZW5jb2RpbmdzXG4gICAgICAgICAqIEBhcGkgcHVibGljXG4gICAgICAgICAqL1xuXG4gICAgICAgIEVuY29kZXIucHJvdG90eXBlLmVuY29kZSA9IGZ1bmN0aW9uIChvYmosIGNhbGxiYWNrKSB7XG4gICAgICAgICAgZGVidWcoJ2VuY29kaW5nIHBhY2tldCAlaicsIG9iaik7XG5cbiAgICAgICAgICBpZiAoZXhwb3J0cy5CSU5BUllfRVZFTlQgPT0gb2JqLnR5cGUgfHwgZXhwb3J0cy5CSU5BUllfQUNLID09IG9iai50eXBlKSB7XG4gICAgICAgICAgICBlbmNvZGVBc0JpbmFyeShvYmosIGNhbGxiYWNrKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdmFyIGVuY29kaW5nID0gZW5jb2RlQXNTdHJpbmcob2JqKTtcbiAgICAgICAgICAgIGNhbGxiYWNrKFtlbmNvZGluZ10pO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlIHBhY2tldCBhcyBzdHJpbmcuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAgICAgICAgICogQHJldHVybiB7U3RyaW5nfSBlbmNvZGVkXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBmdW5jdGlvbiBlbmNvZGVBc1N0cmluZyhvYmopIHtcbiAgICAgICAgICB2YXIgc3RyID0gJyc7XG4gICAgICAgICAgdmFyIG5zcCA9IGZhbHNlO1xuXG4gICAgICAgICAgLy8gZmlyc3QgaXMgdHlwZVxuICAgICAgICAgIHN0ciArPSBvYmoudHlwZTtcblxuICAgICAgICAgIC8vIGF0dGFjaG1lbnRzIGlmIHdlIGhhdmUgdGhlbVxuICAgICAgICAgIGlmIChleHBvcnRzLkJJTkFSWV9FVkVOVCA9PSBvYmoudHlwZSB8fCBleHBvcnRzLkJJTkFSWV9BQ0sgPT0gb2JqLnR5cGUpIHtcbiAgICAgICAgICAgIHN0ciArPSBvYmouYXR0YWNobWVudHM7XG4gICAgICAgICAgICBzdHIgKz0gJy0nO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGlmIHdlIGhhdmUgYSBuYW1lc3BhY2Ugb3RoZXIgdGhhbiBgL2BcbiAgICAgICAgICAvLyB3ZSBhcHBlbmQgaXQgZm9sbG93ZWQgYnkgYSBjb21tYSBgLGBcbiAgICAgICAgICBpZiAob2JqLm5zcCAmJiAnLycgIT0gb2JqLm5zcCkge1xuICAgICAgICAgICAgbnNwID0gdHJ1ZTtcbiAgICAgICAgICAgIHN0ciArPSBvYmoubnNwO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGltbWVkaWF0ZWx5IGZvbGxvd2VkIGJ5IHRoZSBpZFxuICAgICAgICAgIGlmIChudWxsICE9IG9iai5pZCkge1xuICAgICAgICAgICAgaWYgKG5zcCkge1xuICAgICAgICAgICAgICBzdHIgKz0gJywnO1xuICAgICAgICAgICAgICBuc3AgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHN0ciArPSBvYmouaWQ7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8ganNvbiBkYXRhXG4gICAgICAgICAgaWYgKG51bGwgIT0gb2JqLmRhdGEpIHtcbiAgICAgICAgICAgIGlmIChuc3ApIHN0ciArPSAnLCc7XG4gICAgICAgICAgICBzdHIgKz0ganNvbi5zdHJpbmdpZnkob2JqLmRhdGEpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGRlYnVnKCdlbmNvZGVkICVqIGFzICVzJywgb2JqLCBzdHIpO1xuICAgICAgICAgIHJldHVybiBzdHI7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogRW5jb2RlIHBhY2tldCBhcyAnYnVmZmVyIHNlcXVlbmNlJyBieSByZW1vdmluZyBibG9icywgYW5kXG4gICAgICAgICAqIGRlY29uc3RydWN0aW5nIHBhY2tldCBpbnRvIG9iamVjdCB3aXRoIHBsYWNlaG9sZGVycyBhbmRcbiAgICAgICAgICogYSBsaXN0IG9mIGJ1ZmZlcnMuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAgICAgICAgICogQHJldHVybiB7QnVmZmVyfSBlbmNvZGVkXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBmdW5jdGlvbiBlbmNvZGVBc0JpbmFyeShvYmosIGNhbGxiYWNrKSB7XG5cbiAgICAgICAgICBmdW5jdGlvbiB3cml0ZUVuY29kaW5nKGJsb2JsZXNzRGF0YSkge1xuICAgICAgICAgICAgdmFyIGRlY29uc3RydWN0aW9uID0gYmluYXJ5LmRlY29uc3RydWN0UGFja2V0KGJsb2JsZXNzRGF0YSk7XG4gICAgICAgICAgICB2YXIgcGFjayA9IGVuY29kZUFzU3RyaW5nKGRlY29uc3RydWN0aW9uLnBhY2tldCk7XG4gICAgICAgICAgICB2YXIgYnVmZmVycyA9IGRlY29uc3RydWN0aW9uLmJ1ZmZlcnM7XG5cbiAgICAgICAgICAgIGJ1ZmZlcnMudW5zaGlmdChwYWNrKTsgLy8gYWRkIHBhY2tldCBpbmZvIHRvIGJlZ2lubmluZyBvZiBkYXRhIGxpc3RcbiAgICAgICAgICAgIGNhbGxiYWNrKGJ1ZmZlcnMpOyAvLyB3cml0ZSBhbGwgdGhlIGJ1ZmZlcnNcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBiaW5hcnkucmVtb3ZlQmxvYnMob2JqLCB3cml0ZUVuY29kaW5nKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBIHNvY2tldC5pbyBEZWNvZGVyIGluc3RhbmNlXG4gICAgICAgICAqXG4gICAgICAgICAqIEByZXR1cm4ge09iamVjdH0gZGVjb2RlclxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBmdW5jdGlvbiBEZWNvZGVyKCkge1xuICAgICAgICAgIHRoaXMucmVjb25zdHJ1Y3RvciA9IG51bGw7XG4gICAgICAgIH1cblxuICAgICAgICAvKipcbiAgICAgICAgICogTWl4IGluIGBFbWl0dGVyYCB3aXRoIERlY29kZXIuXG4gICAgICAgICAqL1xuXG4gICAgICAgIEVtaXR0ZXIoRGVjb2Rlci5wcm90b3R5cGUpO1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWNvZGVzIGFuIGVjb2RlZCBwYWNrZXQgc3RyaW5nIGludG8gcGFja2V0IEpTT04uXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7U3RyaW5nfSBvYmogLSBlbmNvZGVkIHBhY2tldFxuICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IHBhY2tldFxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBEZWNvZGVyLnByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgICAgdmFyIHBhY2tldDtcbiAgICAgICAgICBpZiAoJ3N0cmluZycgPT0gdHlwZW9mIG9iaikge1xuICAgICAgICAgICAgcGFja2V0ID0gZGVjb2RlU3RyaW5nKG9iaik7XG4gICAgICAgICAgICBpZiAoZXhwb3J0cy5CSU5BUllfRVZFTlQgPT0gcGFja2V0LnR5cGUgfHwgZXhwb3J0cy5CSU5BUllfQUNLID09IHBhY2tldC50eXBlKSB7XG4gICAgICAgICAgICAgIC8vIGJpbmFyeSBwYWNrZXQncyBqc29uXG4gICAgICAgICAgICAgIHRoaXMucmVjb25zdHJ1Y3RvciA9IG5ldyBCaW5hcnlSZWNvbnN0cnVjdG9yKHBhY2tldCk7XG5cbiAgICAgICAgICAgICAgLy8gbm8gYXR0YWNobWVudHMsIGxhYmVsZWQgYmluYXJ5IGJ1dCBubyBiaW5hcnkgZGF0YSB0byBmb2xsb3dcbiAgICAgICAgICAgICAgaWYgKHRoaXMucmVjb25zdHJ1Y3Rvci5yZWNvblBhY2suYXR0YWNobWVudHMgPT09IDApIHtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2RlY29kZWQnLCBwYWNrZXQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAvLyBub24tYmluYXJ5IGZ1bGwgcGFja2V0XG4gICAgICAgICAgICAgIHRoaXMuZW1pdCgnZGVjb2RlZCcsIHBhY2tldCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChpc0J1ZihvYmopIHx8IG9iai5iYXNlNjQpIHtcbiAgICAgICAgICAgIC8vIHJhdyBiaW5hcnkgZGF0YVxuICAgICAgICAgICAgaWYgKCF0aGlzLnJlY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdnb3QgYmluYXJ5IGRhdGEgd2hlbiBub3QgcmVjb25zdHJ1Y3RpbmcgYSBwYWNrZXQnKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIHBhY2tldCA9IHRoaXMucmVjb25zdHJ1Y3Rvci50YWtlQmluYXJ5RGF0YShvYmopO1xuICAgICAgICAgICAgICBpZiAocGFja2V0KSB7XG4gICAgICAgICAgICAgICAgLy8gcmVjZWl2ZWQgZmluYWwgYnVmZmVyXG4gICAgICAgICAgICAgICAgdGhpcy5yZWNvbnN0cnVjdG9yID0gbnVsbDtcbiAgICAgICAgICAgICAgICB0aGlzLmVtaXQoJ2RlY29kZWQnLCBwYWNrZXQpO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biB0eXBlOiAnICsgb2JqKTtcbiAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIERlY29kZSBhIHBhY2tldCBTdHJpbmcgKEpTT04gZGF0YSlcbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtTdHJpbmd9IHN0clxuICAgICAgICAgKiBAcmV0dXJuIHtPYmplY3R9IHBhY2tldFxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgZnVuY3Rpb24gZGVjb2RlU3RyaW5nKHN0cikge1xuICAgICAgICAgIHZhciBwID0ge307XG4gICAgICAgICAgdmFyIGkgPSAwO1xuXG4gICAgICAgICAgLy8gbG9vayB1cCB0eXBlXG4gICAgICAgICAgcC50eXBlID0gTnVtYmVyKHN0ci5jaGFyQXQoMCkpO1xuICAgICAgICAgIGlmIChudWxsID09IGV4cG9ydHMudHlwZXNbcC50eXBlXSkgcmV0dXJuIGVycm9yKCk7XG5cbiAgICAgICAgICAvLyBsb29rIHVwIGF0dGFjaG1lbnRzIGlmIHR5cGUgYmluYXJ5XG4gICAgICAgICAgaWYgKGV4cG9ydHMuQklOQVJZX0VWRU5UID09IHAudHlwZSB8fCBleHBvcnRzLkJJTkFSWV9BQ0sgPT0gcC50eXBlKSB7XG4gICAgICAgICAgICB2YXIgYnVmID0gJyc7XG4gICAgICAgICAgICB3aGlsZSAoc3RyLmNoYXJBdCgrK2kpICE9ICctJykge1xuICAgICAgICAgICAgICBidWYgKz0gc3RyLmNoYXJBdChpKTtcbiAgICAgICAgICAgICAgaWYgKGkgPT0gc3RyLmxlbmd0aCkgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoYnVmICE9IE51bWJlcihidWYpIHx8IHN0ci5jaGFyQXQoaSkgIT0gJy0nKSB7XG4gICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSWxsZWdhbCBhdHRhY2htZW50cycpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcC5hdHRhY2htZW50cyA9IE51bWJlcihidWYpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIGxvb2sgdXAgbmFtZXNwYWNlIChpZiBhbnkpXG4gICAgICAgICAgaWYgKCcvJyA9PSBzdHIuY2hhckF0KGkgKyAxKSkge1xuICAgICAgICAgICAgcC5uc3AgPSAnJztcbiAgICAgICAgICAgIHdoaWxlICgrK2kpIHtcbiAgICAgICAgICAgICAgdmFyIGMgPSBzdHIuY2hhckF0KGkpO1xuICAgICAgICAgICAgICBpZiAoJywnID09IGMpIGJyZWFrO1xuICAgICAgICAgICAgICBwLm5zcCArPSBjO1xuICAgICAgICAgICAgICBpZiAoaSA9PSBzdHIubGVuZ3RoKSBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcC5uc3AgPSAnLyc7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gbG9vayB1cCBpZFxuICAgICAgICAgIHZhciBuZXh0ID0gc3RyLmNoYXJBdChpICsgMSk7XG4gICAgICAgICAgaWYgKCcnICE9PSBuZXh0ICYmIE51bWJlcihuZXh0KSA9PSBuZXh0KSB7XG4gICAgICAgICAgICBwLmlkID0gJyc7XG4gICAgICAgICAgICB3aGlsZSAoKytpKSB7XG4gICAgICAgICAgICAgIHZhciBjID0gc3RyLmNoYXJBdChpKTtcbiAgICAgICAgICAgICAgaWYgKG51bGwgPT0gYyB8fCBOdW1iZXIoYykgIT0gYykge1xuICAgICAgICAgICAgICAgIC0taTtcbiAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICBwLmlkICs9IHN0ci5jaGFyQXQoaSk7XG4gICAgICAgICAgICAgIGlmIChpID09IHN0ci5sZW5ndGgpIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcC5pZCA9IE51bWJlcihwLmlkKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBsb29rIHVwIGpzb24gZGF0YVxuICAgICAgICAgIGlmIChzdHIuY2hhckF0KCsraSkpIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIHAuZGF0YSA9IGpzb24ucGFyc2Uoc3RyLnN1YnN0cihpKSk7XG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICAgIHJldHVybiBlcnJvcigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIGRlYnVnKCdkZWNvZGVkICVzIGFzICVqJywgc3RyLCBwKTtcbiAgICAgICAgICByZXR1cm4gcDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBEZWFsbG9jYXRlcyBhIHBhcnNlcidzIHJlc291cmNlc1xuICAgICAgICAgKlxuICAgICAgICAgKiBAYXBpIHB1YmxpY1xuICAgICAgICAgKi9cblxuICAgICAgICBEZWNvZGVyLnByb3RvdHlwZS5kZXN0cm95ID0gZnVuY3Rpb24gKCkge1xuICAgICAgICAgIGlmICh0aGlzLnJlY29uc3RydWN0b3IpIHtcbiAgICAgICAgICAgIHRoaXMucmVjb25zdHJ1Y3Rvci5maW5pc2hlZFJlY29uc3RydWN0aW9uKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9O1xuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBBIG1hbmFnZXIgb2YgYSBiaW5hcnkgZXZlbnQncyAnYnVmZmVyIHNlcXVlbmNlJy4gU2hvdWxkXG4gICAgICAgICAqIGJlIGNvbnN0cnVjdGVkIHdoZW5ldmVyIGEgcGFja2V0IG9mIHR5cGUgQklOQVJZX0VWRU5UIGlzXG4gICAgICAgICAqIGRlY29kZWQuXG4gICAgICAgICAqXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBwYWNrZXRcbiAgICAgICAgICogQHJldHVybiB7QmluYXJ5UmVjb25zdHJ1Y3Rvcn0gaW5pdGlhbGl6ZWQgcmVjb25zdHJ1Y3RvclxuICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICovXG5cbiAgICAgICAgZnVuY3Rpb24gQmluYXJ5UmVjb25zdHJ1Y3RvcihwYWNrZXQpIHtcbiAgICAgICAgICB0aGlzLnJlY29uUGFjayA9IHBhY2tldDtcbiAgICAgICAgICB0aGlzLmJ1ZmZlcnMgPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qKlxuICAgICAgICAgKiBNZXRob2QgdG8gYmUgY2FsbGVkIHdoZW4gYmluYXJ5IGRhdGEgcmVjZWl2ZWQgZnJvbSBjb25uZWN0aW9uXG4gICAgICAgICAqIGFmdGVyIGEgQklOQVJZX0VWRU5UIHBhY2tldC5cbiAgICAgICAgICpcbiAgICAgICAgICogQHBhcmFtIHtCdWZmZXIgfCBBcnJheUJ1ZmZlcn0gYmluRGF0YSAtIHRoZSByYXcgYmluYXJ5IGRhdGEgcmVjZWl2ZWRcbiAgICAgICAgICogQHJldHVybiB7bnVsbCB8IE9iamVjdH0gcmV0dXJucyBudWxsIGlmIG1vcmUgYmluYXJ5IGRhdGEgaXMgZXhwZWN0ZWQgb3JcbiAgICAgICAgICogICBhIHJlY29uc3RydWN0ZWQgcGFja2V0IG9iamVjdCBpZiBhbGwgYnVmZmVycyBoYXZlIGJlZW4gcmVjZWl2ZWQuXG4gICAgICAgICAqIEBhcGkgcHJpdmF0ZVxuICAgICAgICAgKi9cblxuICAgICAgICBCaW5hcnlSZWNvbnN0cnVjdG9yLnByb3RvdHlwZS50YWtlQmluYXJ5RGF0YSA9IGZ1bmN0aW9uIChiaW5EYXRhKSB7XG4gICAgICAgICAgdGhpcy5idWZmZXJzLnB1c2goYmluRGF0YSk7XG4gICAgICAgICAgaWYgKHRoaXMuYnVmZmVycy5sZW5ndGggPT0gdGhpcy5yZWNvblBhY2suYXR0YWNobWVudHMpIHtcbiAgICAgICAgICAgIC8vIGRvbmUgd2l0aCBidWZmZXIgbGlzdFxuICAgICAgICAgICAgdmFyIHBhY2tldCA9IGJpbmFyeS5yZWNvbnN0cnVjdFBhY2tldCh0aGlzLnJlY29uUGFjaywgdGhpcy5idWZmZXJzKTtcbiAgICAgICAgICAgIHRoaXMuZmluaXNoZWRSZWNvbnN0cnVjdGlvbigpO1xuICAgICAgICAgICAgcmV0dXJuIHBhY2tldDtcbiAgICAgICAgICB9XG4gICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgIH07XG5cbiAgICAgICAgLyoqXG4gICAgICAgICAqIENsZWFucyB1cCBiaW5hcnkgcGFja2V0IHJlY29uc3RydWN0aW9uIHZhcmlhYmxlcy5cbiAgICAgICAgICpcbiAgICAgICAgICogQGFwaSBwcml2YXRlXG4gICAgICAgICAqL1xuXG4gICAgICAgIEJpbmFyeVJlY29uc3RydWN0b3IucHJvdG90eXBlLmZpbmlzaGVkUmVjb25zdHJ1Y3Rpb24gPSBmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgdGhpcy5yZWNvblBhY2sgPSBudWxsO1xuICAgICAgICAgIHRoaXMuYnVmZmVycyA9IFtdO1xuICAgICAgICB9O1xuXG4gICAgICAgIGZ1bmN0aW9uIGVycm9yKGRhdGEpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogZXhwb3J0cy5FUlJPUixcbiAgICAgICAgICAgIGRhdGE6ICdwYXJzZXIgZXJyb3InXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSwgeyBcIi4vYmluYXJ5XCI6IDQ2LCBcIi4vaXMtYnVmZmVyXCI6IDQ4LCBcImNvbXBvbmVudC1lbWl0dGVyXCI6IDQ5LCBcImRlYnVnXCI6IDM5LCBcImlzYXJyYXlcIjogNDMsIFwianNvbjNcIjogNTAgfV0sIDQ4OiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuICAgICAgICAoZnVuY3Rpb24gKGdsb2JhbCkge1xuXG4gICAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBpc0J1ZjtcblxuICAgICAgICAgIC8qKlxuICAgICAgICAgICAqIFJldHVybnMgdHJ1ZSBpZiBvYmogaXMgYSBidWZmZXIgb3IgYW4gYXJyYXlidWZmZXIuXG4gICAgICAgICAgICpcbiAgICAgICAgICAgKiBAYXBpIHByaXZhdGVcbiAgICAgICAgICAgKi9cblxuICAgICAgICAgIGZ1bmN0aW9uIGlzQnVmKG9iaikge1xuICAgICAgICAgICAgcmV0dXJuIGdsb2JhbC5CdWZmZXIgJiYgZ2xvYmFsLkJ1ZmZlci5pc0J1ZmZlcihvYmopIHx8IGdsb2JhbC5BcnJheUJ1ZmZlciAmJiBvYmogaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcjtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLmNhbGwodGhpcywgdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHR5cGVvZiBnbG9iYWwgIT09IFwidW5kZWZpbmVkXCIgPyBnbG9iYWwgOiB7fSk7XG4gICAgICB9LCB7fV0sIDQ5OiBbZnVuY3Rpb24gKF9kZXJlcV8sIG1vZHVsZSwgZXhwb3J0cykge1xuICAgICAgICBhcmd1bWVudHNbNF1bMTVdWzBdLmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cyk7XG4gICAgICB9LCB7IFwiZHVwXCI6IDE1IH1dLCA1MDogW2Z1bmN0aW9uIChfZGVyZXFfLCBtb2R1bGUsIGV4cG9ydHMpIHtcbiAgICAgICAgKGZ1bmN0aW9uIChnbG9iYWwpIHtcbiAgICAgICAgICAvKiEgSlNPTiB2My4zLjIgfCBodHRwOi8vYmVzdGllanMuZ2l0aHViLmlvL2pzb24zIHwgQ29weXJpZ2h0IDIwMTItMjAxNCwgS2l0IENhbWJyaWRnZSB8IGh0dHA6Ly9raXQubWl0LWxpY2Vuc2Uub3JnICovXG4gICAgICAgICAgOyhmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAvLyBEZXRlY3QgdGhlIGBkZWZpbmVgIGZ1bmN0aW9uIGV4cG9zZWQgYnkgYXN5bmNocm9ub3VzIG1vZHVsZSBsb2FkZXJzLiBUaGVcbiAgICAgICAgICAgIC8vIHN0cmljdCBgZGVmaW5lYCBjaGVjayBpcyBuZWNlc3NhcnkgZm9yIGNvbXBhdGliaWxpdHkgd2l0aCBgci5qc2AuXG4gICAgICAgICAgICB2YXIgaXNMb2FkZXIgPSB0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZDtcblxuICAgICAgICAgICAgLy8gQSBzZXQgb2YgdHlwZXMgdXNlZCB0byBkaXN0aW5ndWlzaCBvYmplY3RzIGZyb20gcHJpbWl0aXZlcy5cbiAgICAgICAgICAgIHZhciBvYmplY3RUeXBlcyA9IHtcbiAgICAgICAgICAgICAgXCJmdW5jdGlvblwiOiB0cnVlLFxuICAgICAgICAgICAgICBcIm9iamVjdFwiOiB0cnVlXG4gICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAvLyBEZXRlY3QgdGhlIGBleHBvcnRzYCBvYmplY3QgZXhwb3NlZCBieSBDb21tb25KUyBpbXBsZW1lbnRhdGlvbnMuXG4gICAgICAgICAgICB2YXIgZnJlZUV4cG9ydHMgPSBvYmplY3RUeXBlc1t0eXBlb2YgZXhwb3J0cyA9PT0gXCJ1bmRlZmluZWRcIiA/IFwidW5kZWZpbmVkXCIgOiBfdHlwZW9mKGV4cG9ydHMpXSAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlICYmIGV4cG9ydHM7XG5cbiAgICAgICAgICAgIC8vIFVzZSB0aGUgYGdsb2JhbGAgb2JqZWN0IGV4cG9zZWQgYnkgTm9kZSAoaW5jbHVkaW5nIEJyb3dzZXJpZnkgdmlhXG4gICAgICAgICAgICAvLyBgaW5zZXJ0LW1vZHVsZS1nbG9iYWxzYCksIE5hcndoYWwsIGFuZCBSaW5nbyBhcyB0aGUgZGVmYXVsdCBjb250ZXh0LFxuICAgICAgICAgICAgLy8gYW5kIHRoZSBgd2luZG93YCBvYmplY3QgaW4gYnJvd3NlcnMuIFJoaW5vIGV4cG9ydHMgYSBgZ2xvYmFsYCBmdW5jdGlvblxuICAgICAgICAgICAgLy8gaW5zdGVhZC5cbiAgICAgICAgICAgIHZhciByb290ID0gb2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvdyA9PT0gXCJ1bmRlZmluZWRcIiA/IFwidW5kZWZpbmVkXCIgOiBfdHlwZW9mKHdpbmRvdyldICYmIHdpbmRvdyB8fCB0aGlzLFxuICAgICAgICAgICAgICAgIGZyZWVHbG9iYWwgPSBmcmVlRXhwb3J0cyAmJiBvYmplY3RUeXBlc1t0eXBlb2YgbW9kdWxlID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6IF90eXBlb2YobW9kdWxlKV0gJiYgbW9kdWxlICYmICFtb2R1bGUubm9kZVR5cGUgJiYgKHR5cGVvZiBnbG9iYWwgPT09IFwidW5kZWZpbmVkXCIgPyBcInVuZGVmaW5lZFwiIDogX3R5cGVvZihnbG9iYWwpKSA9PSBcIm9iamVjdFwiICYmIGdsb2JhbDtcblxuICAgICAgICAgICAgaWYgKGZyZWVHbG9iYWwgJiYgKGZyZWVHbG9iYWxbXCJnbG9iYWxcIl0gPT09IGZyZWVHbG9iYWwgfHwgZnJlZUdsb2JhbFtcIndpbmRvd1wiXSA9PT0gZnJlZUdsb2JhbCB8fCBmcmVlR2xvYmFsW1wic2VsZlwiXSA9PT0gZnJlZUdsb2JhbCkpIHtcbiAgICAgICAgICAgICAgcm9vdCA9IGZyZWVHbG9iYWw7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFB1YmxpYzogSW5pdGlhbGl6ZXMgSlNPTiAzIHVzaW5nIHRoZSBnaXZlbiBgY29udGV4dGAgb2JqZWN0LCBhdHRhY2hpbmcgdGhlXG4gICAgICAgICAgICAvLyBgc3RyaW5naWZ5YCBhbmQgYHBhcnNlYCBmdW5jdGlvbnMgdG8gdGhlIHNwZWNpZmllZCBgZXhwb3J0c2Agb2JqZWN0LlxuICAgICAgICAgICAgZnVuY3Rpb24gcnVuSW5Db250ZXh0KGNvbnRleHQsIGV4cG9ydHMpIHtcbiAgICAgICAgICAgICAgY29udGV4dCB8fCAoY29udGV4dCA9IHJvb3RbXCJPYmplY3RcIl0oKSk7XG4gICAgICAgICAgICAgIGV4cG9ydHMgfHwgKGV4cG9ydHMgPSByb290W1wiT2JqZWN0XCJdKCkpO1xuXG4gICAgICAgICAgICAgIC8vIE5hdGl2ZSBjb25zdHJ1Y3RvciBhbGlhc2VzLlxuICAgICAgICAgICAgICB2YXIgTnVtYmVyID0gY29udGV4dFtcIk51bWJlclwiXSB8fCByb290W1wiTnVtYmVyXCJdLFxuICAgICAgICAgICAgICAgICAgU3RyaW5nID0gY29udGV4dFtcIlN0cmluZ1wiXSB8fCByb290W1wiU3RyaW5nXCJdLFxuICAgICAgICAgICAgICAgICAgT2JqZWN0ID0gY29udGV4dFtcIk9iamVjdFwiXSB8fCByb290W1wiT2JqZWN0XCJdLFxuICAgICAgICAgICAgICAgICAgRGF0ZSA9IGNvbnRleHRbXCJEYXRlXCJdIHx8IHJvb3RbXCJEYXRlXCJdLFxuICAgICAgICAgICAgICAgICAgU3ludGF4RXJyb3IgPSBjb250ZXh0W1wiU3ludGF4RXJyb3JcIl0gfHwgcm9vdFtcIlN5bnRheEVycm9yXCJdLFxuICAgICAgICAgICAgICAgICAgVHlwZUVycm9yID0gY29udGV4dFtcIlR5cGVFcnJvclwiXSB8fCByb290W1wiVHlwZUVycm9yXCJdLFxuICAgICAgICAgICAgICAgICAgTWF0aCA9IGNvbnRleHRbXCJNYXRoXCJdIHx8IHJvb3RbXCJNYXRoXCJdLFxuICAgICAgICAgICAgICAgICAgbmF0aXZlSlNPTiA9IGNvbnRleHRbXCJKU09OXCJdIHx8IHJvb3RbXCJKU09OXCJdO1xuXG4gICAgICAgICAgICAgIC8vIERlbGVnYXRlIHRvIHRoZSBuYXRpdmUgYHN0cmluZ2lmeWAgYW5kIGBwYXJzZWAgaW1wbGVtZW50YXRpb25zLlxuICAgICAgICAgICAgICBpZiAoKHR5cGVvZiBuYXRpdmVKU09OID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6IF90eXBlb2YobmF0aXZlSlNPTikpID09IFwib2JqZWN0XCIgJiYgbmF0aXZlSlNPTikge1xuICAgICAgICAgICAgICAgIGV4cG9ydHMuc3RyaW5naWZ5ID0gbmF0aXZlSlNPTi5zdHJpbmdpZnk7XG4gICAgICAgICAgICAgICAgZXhwb3J0cy5wYXJzZSA9IG5hdGl2ZUpTT04ucGFyc2U7XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAvLyBDb252ZW5pZW5jZSBhbGlhc2VzLlxuICAgICAgICAgICAgICB2YXIgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlLFxuICAgICAgICAgICAgICAgICAgZ2V0Q2xhc3MgPSBvYmplY3RQcm90by50b1N0cmluZyxcbiAgICAgICAgICAgICAgICAgIF9pc1Byb3BlcnR5LFxuICAgICAgICAgICAgICAgICAgX2ZvckVhY2gsXG4gICAgICAgICAgICAgICAgICB1bmRlZjtcblxuICAgICAgICAgICAgICAvLyBUZXN0IHRoZSBgRGF0ZSNnZXRVVEMqYCBtZXRob2RzLiBCYXNlZCBvbiB3b3JrIGJ5IEBZYWZmbGUuXG4gICAgICAgICAgICAgIHZhciBpc0V4dGVuZGVkID0gbmV3IERhdGUoLTM1MDk4MjczMzQ1NzMyOTIpO1xuICAgICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIC8vIFRoZSBgZ2V0VVRDRnVsbFllYXJgLCBgTW9udGhgLCBhbmQgYERhdGVgIG1ldGhvZHMgcmV0dXJuIG5vbnNlbnNpY2FsXG4gICAgICAgICAgICAgICAgLy8gcmVzdWx0cyBmb3IgY2VydGFpbiBkYXRlcyBpbiBPcGVyYSA+PSAxMC41My5cbiAgICAgICAgICAgICAgICBpc0V4dGVuZGVkID0gaXNFeHRlbmRlZC5nZXRVVENGdWxsWWVhcigpID09IC0xMDkyNTIgJiYgaXNFeHRlbmRlZC5nZXRVVENNb250aCgpID09PSAwICYmIGlzRXh0ZW5kZWQuZ2V0VVRDRGF0ZSgpID09PSAxICYmXG4gICAgICAgICAgICAgICAgLy8gU2FmYXJpIDwgMi4wLjIgc3RvcmVzIHRoZSBpbnRlcm5hbCBtaWxsaXNlY29uZCB0aW1lIHZhbHVlIGNvcnJlY3RseSxcbiAgICAgICAgICAgICAgICAvLyBidXQgY2xpcHMgdGhlIHZhbHVlcyByZXR1cm5lZCBieSB0aGUgZGF0ZSBtZXRob2RzIHRvIHRoZSByYW5nZSBvZlxuICAgICAgICAgICAgICAgIC8vIHNpZ25lZCAzMi1iaXQgaW50ZWdlcnMgKFstMiAqKiAzMSwgMiAqKiAzMSAtIDFdKS5cbiAgICAgICAgICAgICAgICBpc0V4dGVuZGVkLmdldFVUQ0hvdXJzKCkgPT0gMTAgJiYgaXNFeHRlbmRlZC5nZXRVVENNaW51dGVzKCkgPT0gMzcgJiYgaXNFeHRlbmRlZC5nZXRVVENTZWNvbmRzKCkgPT0gNiAmJiBpc0V4dGVuZGVkLmdldFVUQ01pbGxpc2Vjb25kcygpID09IDcwODtcbiAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7fVxuXG4gICAgICAgICAgICAgIC8vIEludGVybmFsOiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIG5hdGl2ZSBgSlNPTi5zdHJpbmdpZnlgIGFuZCBgcGFyc2VgXG4gICAgICAgICAgICAgIC8vIGltcGxlbWVudGF0aW9ucyBhcmUgc3BlYy1jb21wbGlhbnQuIEJhc2VkIG9uIHdvcmsgYnkgS2VuIFNueWRlci5cbiAgICAgICAgICAgICAgZnVuY3Rpb24gaGFzKG5hbWUpIHtcbiAgICAgICAgICAgICAgICBpZiAoaGFzW25hbWVdICE9PSB1bmRlZikge1xuICAgICAgICAgICAgICAgICAgLy8gUmV0dXJuIGNhY2hlZCBmZWF0dXJlIHRlc3QgcmVzdWx0LlxuICAgICAgICAgICAgICAgICAgcmV0dXJuIGhhc1tuYW1lXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgdmFyIGlzU3VwcG9ydGVkO1xuICAgICAgICAgICAgICAgIGlmIChuYW1lID09IFwiYnVnLXN0cmluZy1jaGFyLWluZGV4XCIpIHtcbiAgICAgICAgICAgICAgICAgIC8vIElFIDw9IDcgZG9lc24ndCBzdXBwb3J0IGFjY2Vzc2luZyBzdHJpbmcgY2hhcmFjdGVycyB1c2luZyBzcXVhcmVcbiAgICAgICAgICAgICAgICAgIC8vIGJyYWNrZXQgbm90YXRpb24uIElFIDggb25seSBzdXBwb3J0cyB0aGlzIGZvciBwcmltaXRpdmVzLlxuICAgICAgICAgICAgICAgICAgaXNTdXBwb3J0ZWQgPSBcImFcIlswXSAhPSBcImFcIjtcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5hbWUgPT0gXCJqc29uXCIpIHtcbiAgICAgICAgICAgICAgICAgIC8vIEluZGljYXRlcyB3aGV0aGVyIGJvdGggYEpTT04uc3RyaW5naWZ5YCBhbmQgYEpTT04ucGFyc2VgIGFyZVxuICAgICAgICAgICAgICAgICAgLy8gc3VwcG9ydGVkLlxuICAgICAgICAgICAgICAgICAgaXNTdXBwb3J0ZWQgPSBoYXMoXCJqc29uLXN0cmluZ2lmeVwiKSAmJiBoYXMoXCJqc29uLXBhcnNlXCIpO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICB2YXIgdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgc2VyaWFsaXplZCA9IFwie1xcXCJhXFxcIjpbMSx0cnVlLGZhbHNlLG51bGwsXFxcIlxcXFx1MDAwMFxcXFxiXFxcXG5cXFxcZlxcXFxyXFxcXHRcXFwiXX1cIjtcbiAgICAgICAgICAgICAgICAgIC8vIFRlc3QgYEpTT04uc3RyaW5naWZ5YC5cbiAgICAgICAgICAgICAgICAgIGlmIChuYW1lID09IFwianNvbi1zdHJpbmdpZnlcIikge1xuICAgICAgICAgICAgICAgICAgICB2YXIgc3RyaW5naWZ5ID0gZXhwb3J0cy5zdHJpbmdpZnksXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdpZnlTdXBwb3J0ZWQgPSB0eXBlb2Ygc3RyaW5naWZ5ID09IFwiZnVuY3Rpb25cIiAmJiBpc0V4dGVuZGVkO1xuICAgICAgICAgICAgICAgICAgICBpZiAoc3RyaW5naWZ5U3VwcG9ydGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gQSB0ZXN0IGZ1bmN0aW9uIG9iamVjdCB3aXRoIGEgY3VzdG9tIGB0b0pTT05gIG1ldGhvZC5cbiAgICAgICAgICAgICAgICAgICAgICAodmFsdWUgPSBmdW5jdGlvbiB2YWx1ZSgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICAgICAgICAgICAgICAgIH0pLnRvSlNPTiA9IHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdpZnlTdXBwb3J0ZWQgPVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRmlyZWZveCAzLjFiMSBhbmQgYjIgc2VyaWFsaXplIHN0cmluZywgbnVtYmVyLCBhbmQgYm9vbGVhblxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gcHJpbWl0aXZlcyBhcyBvYmplY3QgbGl0ZXJhbHMuXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdpZnkoMCkgPT09IFwiMFwiICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGRiAzLjFiMSwgYjIsIGFuZCBKU09OIDIgc2VyaWFsaXplIHdyYXBwZWQgcHJpbWl0aXZlcyBhcyBvYmplY3RcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxpdGVyYWxzLlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBOdW1iZXIoKSkgPT09IFwiMFwiICYmIHN0cmluZ2lmeShuZXcgU3RyaW5nKCkpID09ICdcIlwiJyAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gRkYgMy4xYjEsIDIgdGhyb3cgYW4gZXJyb3IgaWYgdGhlIHZhbHVlIGlzIGBudWxsYCwgYHVuZGVmaW5lZGAsIG9yXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBkb2VzIG5vdCBkZWZpbmUgYSBjYW5vbmljYWwgSlNPTiByZXByZXNlbnRhdGlvbiAodGhpcyBhcHBsaWVzIHRvXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBvYmplY3RzIHdpdGggYHRvSlNPTmAgcHJvcGVydGllcyBhcyB3ZWxsLCAqdW5sZXNzKiB0aGV5IGFyZSBuZXN0ZWRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHdpdGhpbiBhbiBvYmplY3Qgb3IgYXJyYXkpLlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5naWZ5KGdldENsYXNzKSA9PT0gdW5kZWYgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIElFIDggc2VyaWFsaXplcyBgdW5kZWZpbmVkYCBhcyBgXCJ1bmRlZmluZWRcImAuIFNhZmFyaSA8PSA1LjEuNyBhbmRcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZGIDMuMWIzIHBhc3MgdGhpcyB0ZXN0LlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5naWZ5KHVuZGVmKSA9PT0gdW5kZWYgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSA8PSA1LjEuNyBhbmQgRkYgMy4xYjMgdGhyb3cgYEVycm9yYHMgYW5kIGBUeXBlRXJyb3JgcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIHJlc3BlY3RpdmVseSwgaWYgdGhlIHZhbHVlIGlzIG9taXR0ZWQgZW50aXJlbHkuXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdpZnkoKSA9PT0gdW5kZWYgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZGIDMuMWIxLCAyIHRocm93IGFuIGVycm9yIGlmIHRoZSBnaXZlbiB2YWx1ZSBpcyBub3QgYSBudW1iZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBzdHJpbmcsIGFycmF5LCBvYmplY3QsIEJvb2xlYW4sIG9yIGBudWxsYCBsaXRlcmFsLiBUaGlzIGFwcGxpZXMgdG9cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIG9iamVjdHMgd2l0aCBjdXN0b20gYHRvSlNPTmAgbWV0aG9kcyBhcyB3ZWxsLCB1bmxlc3MgdGhleSBhcmUgbmVzdGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpbnNpZGUgb2JqZWN0IG9yIGFycmF5IGxpdGVyYWxzLiBZVUkgMy4wLjBiMSBpZ25vcmVzIGN1c3RvbSBgdG9KU09OYFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbWV0aG9kcyBlbnRpcmVseS5cbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ2lmeSh2YWx1ZSkgPT09IFwiMVwiICYmIHN0cmluZ2lmeShbdmFsdWVdKSA9PSBcIlsxXVwiICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBQcm90b3R5cGUgPD0gMS42LjEgc2VyaWFsaXplcyBgW3VuZGVmaW5lZF1gIGFzIGBcIltdXCJgIGluc3RlYWQgb2ZcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGBcIltudWxsXVwiYC5cbiAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZ2lmeShbdW5kZWZdKSA9PSBcIltudWxsXVwiICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBZVUkgMy4wLjBiMSBmYWlscyB0byBzZXJpYWxpemUgYG51bGxgIGxpdGVyYWxzLlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5naWZ5KG51bGwpID09IFwibnVsbFwiICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGRiAzLjFiMSwgMiBoYWx0cyBzZXJpYWxpemF0aW9uIGlmIGFuIGFycmF5IGNvbnRhaW5zIGEgZnVuY3Rpb246XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBgWzEsIHRydWUsIGdldENsYXNzLCAxXWAgc2VyaWFsaXplcyBhcyBcIlsxLHRydWUsXSxcIi4gRkYgMy4xYjNcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGVsaWRlcyBub24tSlNPTiB2YWx1ZXMgZnJvbSBvYmplY3RzIGFuZCBhcnJheXMsIHVubGVzcyB0aGV5XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBkZWZpbmUgY3VzdG9tIGB0b0pTT05gIG1ldGhvZHMuXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdpZnkoW3VuZGVmLCBnZXRDbGFzcywgbnVsbF0pID09IFwiW251bGwsbnVsbCxudWxsXVwiICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBTaW1wbGUgc2VyaWFsaXphdGlvbiB0ZXN0LiBGRiAzLjFiMSB1c2VzIFVuaWNvZGUgZXNjYXBlIHNlcXVlbmNlc1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gd2hlcmUgY2hhcmFjdGVyIGVzY2FwZSBjb2RlcyBhcmUgZXhwZWN0ZWQgKGUuZy4sIGBcXGJgID0+IGBcXHUwMDA4YCkuXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdpZnkoeyBcImFcIjogW3ZhbHVlLCB0cnVlLCBmYWxzZSwgbnVsbCwgXCJcXHgwMFxcYlxcblxcZlxcclxcdFwiXSB9KSA9PSBzZXJpYWxpemVkICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGRiAzLjFiMSBhbmQgYjIgaWdub3JlIHRoZSBgZmlsdGVyYCBhbmQgYHdpZHRoYCBhcmd1bWVudHMuXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdpZnkobnVsbCwgdmFsdWUpID09PSBcIjFcIiAmJiBzdHJpbmdpZnkoWzEsIDJdLCBudWxsLCAxKSA9PSBcIltcXG4gMSxcXG4gMlxcbl1cIiAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSlNPTiAyLCBQcm90b3R5cGUgPD0gMS43LCBhbmQgb2xkZXIgV2ViS2l0IGJ1aWxkcyBpbmNvcnJlY3RseVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gc2VyaWFsaXplIGV4dGVuZGVkIHllYXJzLlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBEYXRlKC04LjY0ZTE1KSkgPT0gJ1wiLTI3MTgyMS0wNC0yMFQwMDowMDowMC4wMDBaXCInICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgbWlsbGlzZWNvbmRzIGFyZSBvcHRpb25hbCBpbiBFUyA1LCBidXQgcmVxdWlyZWQgaW4gNS4xLlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBEYXRlKDguNjRlMTUpKSA9PSAnXCIrMjc1NzYwLTA5LTEzVDAwOjAwOjAwLjAwMFpcIicgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEZpcmVmb3ggPD0gMTEuMCBpbmNvcnJlY3RseSBzZXJpYWxpemVzIHllYXJzIHByaW9yIHRvIDAgYXMgbmVnYXRpdmVcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvdXItZGlnaXQgeWVhcnMgaW5zdGVhZCBvZiBzaXgtZGlnaXQgeWVhcnMuIENyZWRpdHM6IEBZYWZmbGUuXG4gICAgICAgICAgICAgICAgICAgICAgICBzdHJpbmdpZnkobmV3IERhdGUoLTYyMTk4NzU1MmU1KSkgPT0gJ1wiLTAwMDAwMS0wMS0wMVQwMDowMDowMC4wMDBaXCInICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgPD0gNS4xLjUgYW5kIE9wZXJhID49IDEwLjUzIGluY29ycmVjdGx5IHNlcmlhbGl6ZSBtaWxsaXNlY29uZFxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gdmFsdWVzIGxlc3MgdGhhbiAxMDAwLiBDcmVkaXRzOiBAWWFmZmxlLlxuICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5naWZ5KG5ldyBEYXRlKC0xKSkgPT0gJ1wiMTk2OS0xMi0zMVQyMzo1OTo1OS45OTlaXCInO1xuICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5naWZ5U3VwcG9ydGVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlzU3VwcG9ydGVkID0gc3RyaW5naWZ5U3VwcG9ydGVkO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgLy8gVGVzdCBgSlNPTi5wYXJzZWAuXG4gICAgICAgICAgICAgICAgICBpZiAobmFtZSA9PSBcImpzb24tcGFyc2VcIikge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcGFyc2UgPSBleHBvcnRzLnBhcnNlO1xuICAgICAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHBhcnNlID09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBGRiAzLjFiMSwgYjIgd2lsbCB0aHJvdyBhbiBleGNlcHRpb24gaWYgYSBiYXJlIGxpdGVyYWwgaXMgcHJvdmlkZWQuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBDb25mb3JtaW5nIGltcGxlbWVudGF0aW9ucyBzaG91bGQgYWxzbyBjb2VyY2UgdGhlIGluaXRpYWwgYXJndW1lbnQgdG9cbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGEgc3RyaW5nIHByaW9yIHRvIHBhcnNpbmcuXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocGFyc2UoXCIwXCIpID09PSAwICYmICFwYXJzZShmYWxzZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2ltcGxlIHBhcnNpbmcgdGVzdC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBwYXJzZShzZXJpYWxpemVkKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHBhcnNlU3VwcG9ydGVkID0gdmFsdWVbXCJhXCJdLmxlbmd0aCA9PSA1ICYmIHZhbHVlW1wiYVwiXVswXSA9PT0gMTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHBhcnNlU3VwcG9ydGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSA8PSA1LjEuMiBhbmQgRkYgMy4xYjEgYWxsb3cgdW5lc2NhcGVkIHRhYnMgaW4gc3RyaW5ncy5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBhcnNlU3VwcG9ydGVkID0gIXBhcnNlKCdcIlxcdFwiJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZVN1cHBvcnRlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRkYgNC4wIGFuZCA0LjAuMSBhbGxvdyBsZWFkaW5nIGArYCBzaWducyBhbmQgbGVhZGluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkZWNpbWFsIHBvaW50cy4gRkYgNC4wLCA0LjAuMSwgYW5kIElFIDktMTAgYWxzbyBhbGxvd1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjZXJ0YWluIG9jdGFsIGxpdGVyYWxzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZVN1cHBvcnRlZCA9IHBhcnNlKFwiMDFcIikgIT09IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwYXJzZVN1cHBvcnRlZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRkYgNC4wLCA0LjAuMSwgYW5kIFJoaW5vIDEuN1IzLVI0IGFsbG93IHRyYWlsaW5nIGRlY2ltYWxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcG9pbnRzLiBUaGVzZSBlbnZpcm9ubWVudHMsIGFsb25nIHdpdGggRkYgMy4xYjEgYW5kIDIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFsc28gYWxsb3cgdHJhaWxpbmcgY29tbWFzIGluIEpTT04gb2JqZWN0cyBhbmQgYXJyYXlzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYXJzZVN1cHBvcnRlZCA9IHBhcnNlKFwiMS5cIikgIT09IDE7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBwYXJzZVN1cHBvcnRlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpc1N1cHBvcnRlZCA9IHBhcnNlU3VwcG9ydGVkO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gaGFzW25hbWVdID0gISFpc1N1cHBvcnRlZDtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmICghaGFzKFwianNvblwiKSkge1xuICAgICAgICAgICAgICAgIC8vIENvbW1vbiBgW1tDbGFzc11dYCBuYW1lIGFsaWFzZXMuXG4gICAgICAgICAgICAgICAgdmFyIGZ1bmN0aW9uQ2xhc3MgPSBcIltvYmplY3QgRnVuY3Rpb25dXCIsXG4gICAgICAgICAgICAgICAgICAgIGRhdGVDbGFzcyA9IFwiW29iamVjdCBEYXRlXVwiLFxuICAgICAgICAgICAgICAgICAgICBudW1iZXJDbGFzcyA9IFwiW29iamVjdCBOdW1iZXJdXCIsXG4gICAgICAgICAgICAgICAgICAgIHN0cmluZ0NsYXNzID0gXCJbb2JqZWN0IFN0cmluZ11cIixcbiAgICAgICAgICAgICAgICAgICAgYXJyYXlDbGFzcyA9IFwiW29iamVjdCBBcnJheV1cIixcbiAgICAgICAgICAgICAgICAgICAgYm9vbGVhbkNsYXNzID0gXCJbb2JqZWN0IEJvb2xlYW5dXCI7XG5cbiAgICAgICAgICAgICAgICAvLyBEZXRlY3QgaW5jb21wbGV0ZSBzdXBwb3J0IGZvciBhY2Nlc3Npbmcgc3RyaW5nIGNoYXJhY3RlcnMgYnkgaW5kZXguXG4gICAgICAgICAgICAgICAgdmFyIGNoYXJJbmRleEJ1Z2d5ID0gaGFzKFwiYnVnLXN0cmluZy1jaGFyLWluZGV4XCIpO1xuXG4gICAgICAgICAgICAgICAgLy8gRGVmaW5lIGFkZGl0aW9uYWwgdXRpbGl0eSBtZXRob2RzIGlmIHRoZSBgRGF0ZWAgbWV0aG9kcyBhcmUgYnVnZ3kuXG4gICAgICAgICAgICAgICAgaWYgKCFpc0V4dGVuZGVkKSB7XG4gICAgICAgICAgICAgICAgICB2YXIgZmxvb3IgPSBNYXRoLmZsb29yO1xuICAgICAgICAgICAgICAgICAgLy8gQSBtYXBwaW5nIGJldHdlZW4gdGhlIG1vbnRocyBvZiB0aGUgeWVhciBhbmQgdGhlIG51bWJlciBvZiBkYXlzIGJldHdlZW5cbiAgICAgICAgICAgICAgICAgIC8vIEphbnVhcnkgMXN0IGFuZCB0aGUgZmlyc3Qgb2YgdGhlIHJlc3BlY3RpdmUgbW9udGguXG4gICAgICAgICAgICAgICAgICB2YXIgTW9udGhzID0gWzAsIDMxLCA1OSwgOTAsIDEyMCwgMTUxLCAxODEsIDIxMiwgMjQzLCAyNzMsIDMwNCwgMzM0XTtcbiAgICAgICAgICAgICAgICAgIC8vIEludGVybmFsOiBDYWxjdWxhdGVzIHRoZSBudW1iZXIgb2YgZGF5cyBiZXR3ZWVuIHRoZSBVbml4IGVwb2NoIGFuZCB0aGVcbiAgICAgICAgICAgICAgICAgIC8vIGZpcnN0IGRheSBvZiB0aGUgZ2l2ZW4gbW9udGguXG4gICAgICAgICAgICAgICAgICB2YXIgZ2V0RGF5ID0gZnVuY3Rpb24gZ2V0RGF5KHllYXIsIG1vbnRoKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBNb250aHNbbW9udGhdICsgMzY1ICogKHllYXIgLSAxOTcwKSArIGZsb29yKCh5ZWFyIC0gMTk2OSArIChtb250aCA9ICsobW9udGggPiAxKSkpIC8gNCkgLSBmbG9vcigoeWVhciAtIDE5MDEgKyBtb250aCkgLyAxMDApICsgZmxvb3IoKHllYXIgLSAxNjAxICsgbW9udGgpIC8gNDAwKTtcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gSW50ZXJuYWw6IERldGVybWluZXMgaWYgYSBwcm9wZXJ0eSBpcyBhIGRpcmVjdCBwcm9wZXJ0eSBvZiB0aGUgZ2l2ZW5cbiAgICAgICAgICAgICAgICAvLyBvYmplY3QuIERlbGVnYXRlcyB0byB0aGUgbmF0aXZlIGBPYmplY3QjaGFzT3duUHJvcGVydHlgIG1ldGhvZC5cbiAgICAgICAgICAgICAgICBpZiAoIShfaXNQcm9wZXJ0eSA9IG9iamVjdFByb3RvLmhhc093blByb3BlcnR5KSkge1xuICAgICAgICAgICAgICAgICAgX2lzUHJvcGVydHkgPSBmdW5jdGlvbiBpc1Byb3BlcnR5KHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBtZW1iZXJzID0ge30sXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdHJ1Y3RvcjtcbiAgICAgICAgICAgICAgICAgICAgaWYgKChtZW1iZXJzLl9fcHJvdG9fXyA9IG51bGwsIG1lbWJlcnMuX19wcm90b19fID0ge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSAqcHJvdG8qIHByb3BlcnR5IGNhbm5vdCBiZSBzZXQgbXVsdGlwbGUgdGltZXMgaW4gcmVjZW50XG4gICAgICAgICAgICAgICAgICAgICAgLy8gdmVyc2lvbnMgb2YgRmlyZWZveCBhbmQgU2VhTW9ua2V5LlxuICAgICAgICAgICAgICAgICAgICAgIFwidG9TdHJpbmdcIjogMVxuICAgICAgICAgICAgICAgICAgICB9LCBtZW1iZXJzKS50b1N0cmluZyAhPSBnZXRDbGFzcykge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIFNhZmFyaSA8PSAyLjAuMyBkb2Vzbid0IGltcGxlbWVudCBgT2JqZWN0I2hhc093blByb3BlcnR5YCwgYnV0XG4gICAgICAgICAgICAgICAgICAgICAgLy8gc3VwcG9ydHMgdGhlIG11dGFibGUgKnByb3RvKiBwcm9wZXJ0eS5cbiAgICAgICAgICAgICAgICAgICAgICBfaXNQcm9wZXJ0eSA9IGZ1bmN0aW9uIGlzUHJvcGVydHkocHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENhcHR1cmUgYW5kIGJyZWFrIHRoZSBvYmplY3QncyBwcm90b3R5cGUgY2hhaW4gKHNlZSBzZWN0aW9uIDguNi4yXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBvZiB0aGUgRVMgNS4xIHNwZWMpLiBUaGUgcGFyZW50aGVzaXplZCBleHByZXNzaW9uIHByZXZlbnRzIGFuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB1bnNhZmUgdHJhbnNmb3JtYXRpb24gYnkgdGhlIENsb3N1cmUgQ29tcGlsZXIuXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgb3JpZ2luYWwgPSB0aGlzLl9fcHJvdG9fXyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBwcm9wZXJ0eSBpbiAodGhpcy5fX3Byb3RvX18gPSBudWxsLCB0aGlzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlc3RvcmUgdGhlIG9yaWdpbmFsIHByb3RvdHlwZSBjaGFpbi5cbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuX19wcm90b19fID0gb3JpZ2luYWw7XG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gQ2FwdHVyZSBhIHJlZmVyZW5jZSB0byB0aGUgdG9wLWxldmVsIGBPYmplY3RgIGNvbnN0cnVjdG9yLlxuICAgICAgICAgICAgICAgICAgICAgIGNvbnN0cnVjdG9yID0gbWVtYmVycy5jb25zdHJ1Y3RvcjtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBVc2UgdGhlIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHkgdG8gc2ltdWxhdGUgYE9iamVjdCNoYXNPd25Qcm9wZXJ0eWAgaW5cbiAgICAgICAgICAgICAgICAgICAgICAvLyBvdGhlciBlbnZpcm9ubWVudHMuXG4gICAgICAgICAgICAgICAgICAgICAgX2lzUHJvcGVydHkgPSBmdW5jdGlvbiBpc1Byb3BlcnR5KHByb3BlcnR5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcGFyZW50ID0gKHRoaXMuY29uc3RydWN0b3IgfHwgY29uc3RydWN0b3IpLnByb3RvdHlwZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBwcm9wZXJ0eSBpbiB0aGlzICYmICEocHJvcGVydHkgaW4gcGFyZW50ICYmIHRoaXNbcHJvcGVydHldID09PSBwYXJlbnRbcHJvcGVydHldKTtcbiAgICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIG1lbWJlcnMgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gX2lzUHJvcGVydHkuY2FsbCh0aGlzLCBwcm9wZXJ0eSk7XG4gICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIEludGVybmFsOiBOb3JtYWxpemVzIHRoZSBgZm9yLi4uaW5gIGl0ZXJhdGlvbiBhbGdvcml0aG0gYWNyb3NzXG4gICAgICAgICAgICAgICAgLy8gZW52aXJvbm1lbnRzLiBFYWNoIGVudW1lcmF0ZWQga2V5IGlzIHlpZWxkZWQgdG8gYSBgY2FsbGJhY2tgIGZ1bmN0aW9uLlxuICAgICAgICAgICAgICAgIF9mb3JFYWNoID0gZnVuY3Rpb24gZm9yRWFjaChvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgICB2YXIgc2l6ZSA9IDAsXG4gICAgICAgICAgICAgICAgICAgICAgUHJvcGVydGllcyxcbiAgICAgICAgICAgICAgICAgICAgICBtZW1iZXJzLFxuICAgICAgICAgICAgICAgICAgICAgIHByb3BlcnR5O1xuXG4gICAgICAgICAgICAgICAgICAvLyBUZXN0cyBmb3IgYnVncyBpbiB0aGUgY3VycmVudCBlbnZpcm9ubWVudCdzIGBmb3IuLi5pbmAgYWxnb3JpdGhtLiBUaGVcbiAgICAgICAgICAgICAgICAgIC8vIGB2YWx1ZU9mYCBwcm9wZXJ0eSBpbmhlcml0cyB0aGUgbm9uLWVudW1lcmFibGUgZmxhZyBmcm9tXG4gICAgICAgICAgICAgICAgICAvLyBgT2JqZWN0LnByb3RvdHlwZWAgaW4gb2xkZXIgdmVyc2lvbnMgb2YgSUUsIE5ldHNjYXBlLCBhbmQgTW96aWxsYS5cbiAgICAgICAgICAgICAgICAgIChQcm9wZXJ0aWVzID0gZnVuY3Rpb24gUHJvcGVydGllcygpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhpcy52YWx1ZU9mID0gMDtcbiAgICAgICAgICAgICAgICAgIH0pLnByb3RvdHlwZS52YWx1ZU9mID0gMDtcblxuICAgICAgICAgICAgICAgICAgLy8gSXRlcmF0ZSBvdmVyIGEgbmV3IGluc3RhbmNlIG9mIHRoZSBgUHJvcGVydGllc2AgY2xhc3MuXG4gICAgICAgICAgICAgICAgICBtZW1iZXJzID0gbmV3IFByb3BlcnRpZXMoKTtcbiAgICAgICAgICAgICAgICAgIGZvciAocHJvcGVydHkgaW4gbWVtYmVycykge1xuICAgICAgICAgICAgICAgICAgICAvLyBJZ25vcmUgYWxsIHByb3BlcnRpZXMgaW5oZXJpdGVkIGZyb20gYE9iamVjdC5wcm90b3R5cGVgLlxuICAgICAgICAgICAgICAgICAgICBpZiAoX2lzUHJvcGVydHkuY2FsbChtZW1iZXJzLCBwcm9wZXJ0eSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICBzaXplKys7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIFByb3BlcnRpZXMgPSBtZW1iZXJzID0gbnVsbDtcblxuICAgICAgICAgICAgICAgICAgLy8gTm9ybWFsaXplIHRoZSBpdGVyYXRpb24gYWxnb3JpdGhtLlxuICAgICAgICAgICAgICAgICAgaWYgKCFzaXplKSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIEEgbGlzdCBvZiBub24tZW51bWVyYWJsZSBwcm9wZXJ0aWVzIGluaGVyaXRlZCBmcm9tIGBPYmplY3QucHJvdG90eXBlYC5cbiAgICAgICAgICAgICAgICAgICAgbWVtYmVycyA9IFtcInZhbHVlT2ZcIiwgXCJ0b1N0cmluZ1wiLCBcInRvTG9jYWxlU3RyaW5nXCIsIFwicHJvcGVydHlJc0VudW1lcmFibGVcIiwgXCJpc1Byb3RvdHlwZU9mXCIsIFwiaGFzT3duUHJvcGVydHlcIiwgXCJjb25zdHJ1Y3RvclwiXTtcbiAgICAgICAgICAgICAgICAgICAgLy8gSUUgPD0gOCwgTW96aWxsYSAxLjAsIGFuZCBOZXRzY2FwZSA2LjIgaWdub3JlIHNoYWRvd2VkIG5vbi1lbnVtZXJhYmxlXG4gICAgICAgICAgICAgICAgICAgIC8vIHByb3BlcnRpZXMuXG4gICAgICAgICAgICAgICAgICAgIF9mb3JFYWNoID0gZnVuY3Rpb24gZm9yRWFjaChvYmplY3QsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgdmFyIGlzRnVuY3Rpb24gPSBnZXRDbGFzcy5jYWxsKG9iamVjdCkgPT0gZnVuY3Rpb25DbGFzcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgICB2YXIgaGFzUHJvcGVydHkgPSAhaXNGdW5jdGlvbiAmJiB0eXBlb2Ygb2JqZWN0LmNvbnN0cnVjdG9yICE9IFwiZnVuY3Rpb25cIiAmJiBvYmplY3RUeXBlc1tfdHlwZW9mKG9iamVjdC5oYXNPd25Qcm9wZXJ0eSldICYmIG9iamVjdC5oYXNPd25Qcm9wZXJ0eSB8fCBfaXNQcm9wZXJ0eTtcbiAgICAgICAgICAgICAgICAgICAgICBmb3IgKHByb3BlcnR5IGluIG9iamVjdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gR2Vja28gPD0gMS4wIGVudW1lcmF0ZXMgdGhlIGBwcm90b3R5cGVgIHByb3BlcnR5IG9mIGZ1bmN0aW9ucyB1bmRlclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2VydGFpbiBjb25kaXRpb25zOyBJRSBkb2VzIG5vdC5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghKGlzRnVuY3Rpb24gJiYgcHJvcGVydHkgPT0gXCJwcm90b3R5cGVcIikgJiYgaGFzUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhwcm9wZXJ0eSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIC8vIE1hbnVhbGx5IGludm9rZSB0aGUgY2FsbGJhY2sgZm9yIGVhY2ggbm9uLWVudW1lcmFibGUgcHJvcGVydHkuXG4gICAgICAgICAgICAgICAgICAgICAgZm9yIChsZW5ndGggPSBtZW1iZXJzLmxlbmd0aDsgcHJvcGVydHkgPSBtZW1iZXJzWy0tbGVuZ3RoXTsgaGFzUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KSAmJiBjYWxsYmFjayhwcm9wZXJ0eSkpIHt9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNpemUgPT0gMikge1xuICAgICAgICAgICAgICAgICAgICAvLyBTYWZhcmkgPD0gMi4wLjQgZW51bWVyYXRlcyBzaGFkb3dlZCBwcm9wZXJ0aWVzIHR3aWNlLlxuICAgICAgICAgICAgICAgICAgICBfZm9yRWFjaCA9IGZ1bmN0aW9uIGZvckVhY2gob2JqZWN0LCBjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIENyZWF0ZSBhIHNldCBvZiBpdGVyYXRlZCBwcm9wZXJ0aWVzLlxuICAgICAgICAgICAgICAgICAgICAgIHZhciBtZW1iZXJzID0ge30sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlzRnVuY3Rpb24gPSBnZXRDbGFzcy5jYWxsKG9iamVjdCkgPT0gZnVuY3Rpb25DbGFzcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydHk7XG4gICAgICAgICAgICAgICAgICAgICAgZm9yIChwcm9wZXJ0eSBpbiBvYmplY3QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFN0b3JlIGVhY2ggcHJvcGVydHkgbmFtZSB0byBwcmV2ZW50IGRvdWJsZSBlbnVtZXJhdGlvbi4gVGhlXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBgcHJvdG90eXBlYCBwcm9wZXJ0eSBvZiBmdW5jdGlvbnMgaXMgbm90IGVudW1lcmF0ZWQgZHVlIHRvIGNyb3NzLVxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gZW52aXJvbm1lbnQgaW5jb25zaXN0ZW5jaWVzLlxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoaXNGdW5jdGlvbiAmJiBwcm9wZXJ0eSA9PSBcInByb3RvdHlwZVwiKSAmJiAhX2lzUHJvcGVydHkuY2FsbChtZW1iZXJzLCBwcm9wZXJ0eSkgJiYgKG1lbWJlcnNbcHJvcGVydHldID0gMSkgJiYgX2lzUHJvcGVydHkuY2FsbChvYmplY3QsIHByb3BlcnR5KSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhwcm9wZXJ0eSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gTm8gYnVncyBkZXRlY3RlZDsgdXNlIHRoZSBzdGFuZGFyZCBgZm9yLi4uaW5gIGFsZ29yaXRobS5cbiAgICAgICAgICAgICAgICAgICAgX2ZvckVhY2ggPSBmdW5jdGlvbiBmb3JFYWNoKG9iamVjdCwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgICB2YXIgaXNGdW5jdGlvbiA9IGdldENsYXNzLmNhbGwob2JqZWN0KSA9PSBmdW5jdGlvbkNsYXNzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9wZXJ0eSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaXNDb25zdHJ1Y3RvcjtcbiAgICAgICAgICAgICAgICAgICAgICBmb3IgKHByb3BlcnR5IGluIG9iamVjdCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoaXNGdW5jdGlvbiAmJiBwcm9wZXJ0eSA9PSBcInByb3RvdHlwZVwiKSAmJiBfaXNQcm9wZXJ0eS5jYWxsKG9iamVjdCwgcHJvcGVydHkpICYmICEoaXNDb25zdHJ1Y3RvciA9IHByb3BlcnR5ID09PSBcImNvbnN0cnVjdG9yXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgLy8gTWFudWFsbHkgaW52b2tlIHRoZSBjYWxsYmFjayBmb3IgdGhlIGBjb25zdHJ1Y3RvcmAgcHJvcGVydHkgZHVlIHRvXG4gICAgICAgICAgICAgICAgICAgICAgLy8gY3Jvc3MtZW52aXJvbm1lbnQgaW5jb25zaXN0ZW5jaWVzLlxuICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0NvbnN0cnVjdG9yIHx8IF9pc1Byb3BlcnR5LmNhbGwob2JqZWN0LCBwcm9wZXJ0eSA9IFwiY29uc3RydWN0b3JcIikpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKHByb3BlcnR5KTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICByZXR1cm4gX2ZvckVhY2gob2JqZWN0LCBjYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgIC8vIFB1YmxpYzogU2VyaWFsaXplcyBhIEphdmFTY3JpcHQgYHZhbHVlYCBhcyBhIEpTT04gc3RyaW5nLiBUaGUgb3B0aW9uYWxcbiAgICAgICAgICAgICAgICAvLyBgZmlsdGVyYCBhcmd1bWVudCBtYXkgc3BlY2lmeSBlaXRoZXIgYSBmdW5jdGlvbiB0aGF0IGFsdGVycyBob3cgb2JqZWN0IGFuZFxuICAgICAgICAgICAgICAgIC8vIGFycmF5IG1lbWJlcnMgYXJlIHNlcmlhbGl6ZWQsIG9yIGFuIGFycmF5IG9mIHN0cmluZ3MgYW5kIG51bWJlcnMgdGhhdFxuICAgICAgICAgICAgICAgIC8vIGluZGljYXRlcyB3aGljaCBwcm9wZXJ0aWVzIHNob3VsZCBiZSBzZXJpYWxpemVkLiBUaGUgb3B0aW9uYWwgYHdpZHRoYFxuICAgICAgICAgICAgICAgIC8vIGFyZ3VtZW50IG1heSBiZSBlaXRoZXIgYSBzdHJpbmcgb3IgbnVtYmVyIHRoYXQgc3BlY2lmaWVzIHRoZSBpbmRlbnRhdGlvblxuICAgICAgICAgICAgICAgIC8vIGxldmVsIG9mIHRoZSBvdXRwdXQuXG4gICAgICAgICAgICAgICAgaWYgKCFoYXMoXCJqc29uLXN0cmluZ2lmeVwiKSkge1xuICAgICAgICAgICAgICAgICAgLy8gSW50ZXJuYWw6IEEgbWFwIG9mIGNvbnRyb2wgY2hhcmFjdGVycyBhbmQgdGhlaXIgZXNjYXBlZCBlcXVpdmFsZW50cy5cbiAgICAgICAgICAgICAgICAgIHZhciBFc2NhcGVzID0ge1xuICAgICAgICAgICAgICAgICAgICA5MjogXCJcXFxcXFxcXFwiLFxuICAgICAgICAgICAgICAgICAgICAzNDogJ1xcXFxcIicsXG4gICAgICAgICAgICAgICAgICAgIDg6IFwiXFxcXGJcIixcbiAgICAgICAgICAgICAgICAgICAgMTI6IFwiXFxcXGZcIixcbiAgICAgICAgICAgICAgICAgICAgMTA6IFwiXFxcXG5cIixcbiAgICAgICAgICAgICAgICAgICAgMTM6IFwiXFxcXHJcIixcbiAgICAgICAgICAgICAgICAgICAgOTogXCJcXFxcdFwiXG4gICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAvLyBJbnRlcm5hbDogQ29udmVydHMgYHZhbHVlYCBpbnRvIGEgemVyby1wYWRkZWQgc3RyaW5nIHN1Y2ggdGhhdCBpdHNcbiAgICAgICAgICAgICAgICAgIC8vIGxlbmd0aCBpcyBhdCBsZWFzdCBlcXVhbCB0byBgd2lkdGhgLiBUaGUgYHdpZHRoYCBtdXN0IGJlIDw9IDYuXG4gICAgICAgICAgICAgICAgICB2YXIgbGVhZGluZ1plcm9lcyA9IFwiMDAwMDAwXCI7XG4gICAgICAgICAgICAgICAgICB2YXIgdG9QYWRkZWRTdHJpbmcgPSBmdW5jdGlvbiB0b1BhZGRlZFN0cmluZyh3aWR0aCwgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gVGhlIGB8fCAwYCBleHByZXNzaW9uIGlzIG5lY2Vzc2FyeSB0byB3b3JrIGFyb3VuZCBhIGJ1ZyBpblxuICAgICAgICAgICAgICAgICAgICAvLyBPcGVyYSA8PSA3LjU0dTIgd2hlcmUgYDAgPT0gLTBgLCBidXQgYFN0cmluZygtMCkgIT09IFwiMFwiYC5cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIChsZWFkaW5nWmVyb2VzICsgKHZhbHVlIHx8IDApKS5zbGljZSgtd2lkdGgpO1xuICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgLy8gSW50ZXJuYWw6IERvdWJsZS1xdW90ZXMgYSBzdHJpbmcgYHZhbHVlYCwgcmVwbGFjaW5nIGFsbCBBU0NJSSBjb250cm9sXG4gICAgICAgICAgICAgICAgICAvLyBjaGFyYWN0ZXJzIChjaGFyYWN0ZXJzIHdpdGggY29kZSB1bml0IHZhbHVlcyBiZXR3ZWVuIDAgYW5kIDMxKSB3aXRoXG4gICAgICAgICAgICAgICAgICAvLyB0aGVpciBlc2NhcGVkIGVxdWl2YWxlbnRzLiBUaGlzIGlzIGFuIGltcGxlbWVudGF0aW9uIG9mIHRoZVxuICAgICAgICAgICAgICAgICAgLy8gYFF1b3RlKHZhbHVlKWAgb3BlcmF0aW9uIGRlZmluZWQgaW4gRVMgNS4xIHNlY3Rpb24gMTUuMTIuMy5cbiAgICAgICAgICAgICAgICAgIHZhciB1bmljb2RlUHJlZml4ID0gXCJcXFxcdTAwXCI7XG4gICAgICAgICAgICAgICAgICB2YXIgcXVvdGUgPSBmdW5jdGlvbiBxdW90ZSh2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0ID0gJ1wiJyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGluZGV4ID0gMCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA9IHZhbHVlLmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHVzZUNoYXJJbmRleCA9ICFjaGFySW5kZXhCdWdneSB8fCBsZW5ndGggPiAxMDtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHN5bWJvbHMgPSB1c2VDaGFySW5kZXggJiYgKGNoYXJJbmRleEJ1Z2d5ID8gdmFsdWUuc3BsaXQoXCJcIikgOiB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIGZvciAoOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgICAgICAgICAgIHZhciBjaGFyQ29kZSA9IHZhbHVlLmNoYXJDb2RlQXQoaW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBjaGFyYWN0ZXIgaXMgYSBjb250cm9sIGNoYXJhY3RlciwgYXBwZW5kIGl0cyBVbmljb2RlIG9yXG4gICAgICAgICAgICAgICAgICAgICAgLy8gc2hvcnRoYW5kIGVzY2FwZSBzZXF1ZW5jZTsgb3RoZXJ3aXNlLCBhcHBlbmQgdGhlIGNoYXJhY3RlciBhcy1pcy5cbiAgICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGNoYXJDb2RlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDg6Y2FzZSA5OmNhc2UgMTA6Y2FzZSAxMjpjYXNlIDEzOmNhc2UgMzQ6Y2FzZSA5MjpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICs9IEVzY2FwZXNbY2hhckNvZGVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA8IDMyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ICs9IHVuaWNvZGVQcmVmaXggKyB0b1BhZGRlZFN0cmluZygyLCBjaGFyQ29kZS50b1N0cmluZygxNikpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCArPSB1c2VDaGFySW5kZXggPyBzeW1ib2xzW2luZGV4XSA6IHZhbHVlLmNoYXJBdChpbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQgKyAnXCInO1xuICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgLy8gSW50ZXJuYWw6IFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZXMgYW4gb2JqZWN0LiBJbXBsZW1lbnRzIHRoZVxuICAgICAgICAgICAgICAgICAgLy8gYFN0cihrZXksIGhvbGRlcilgLCBgSk8odmFsdWUpYCwgYW5kIGBKQSh2YWx1ZSlgIG9wZXJhdGlvbnMuXG4gICAgICAgICAgICAgICAgICB2YXIgc2VyaWFsaXplID0gZnVuY3Rpb24gc2VyaWFsaXplKHByb3BlcnR5LCBvYmplY3QsIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCB3aGl0ZXNwYWNlLCBpbmRlbnRhdGlvbiwgc3RhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlLCBjbGFzc05hbWUsIHllYXIsIG1vbnRoLCBkYXRlLCB0aW1lLCBob3VycywgbWludXRlcywgc2Vjb25kcywgbWlsbGlzZWNvbmRzLCByZXN1bHRzLCBlbGVtZW50LCBpbmRleCwgbGVuZ3RoLCBwcmVmaXgsIHJlc3VsdDtcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBOZWNlc3NhcnkgZm9yIGhvc3Qgb2JqZWN0IHN1cHBvcnQuXG4gICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBvYmplY3RbcHJvcGVydHldO1xuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHt9XG4gICAgICAgICAgICAgICAgICAgIGlmICgodHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6IF90eXBlb2YodmFsdWUpKSA9PSBcIm9iamVjdFwiICYmIHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgY2xhc3NOYW1lID0gZ2V0Q2xhc3MuY2FsbCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBkYXRlQ2xhc3MgJiYgIV9pc1Byb3BlcnR5LmNhbGwodmFsdWUsIFwidG9KU09OXCIpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPiAtMSAvIDAgJiYgdmFsdWUgPCAxIC8gMCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBEYXRlcyBhcmUgc2VyaWFsaXplZCBhY2NvcmRpbmcgdG8gdGhlIGBEYXRlI3RvSlNPTmAgbWV0aG9kXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNwZWNpZmllZCBpbiBFUyA1LjEgc2VjdGlvbiAxNS45LjUuNDQuIFNlZSBzZWN0aW9uIDE1LjkuMS4xNVxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgdGhlIElTTyA4NjAxIGRhdGUgdGltZSBzdHJpbmcgZm9ybWF0LlxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2V0RGF5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWFudWFsbHkgY29tcHV0ZSB0aGUgeWVhciwgbW9udGgsIGRhdGUsIGhvdXJzLCBtaW51dGVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHNlY29uZHMsIGFuZCBtaWxsaXNlY29uZHMgaWYgdGhlIGBnZXRVVEMqYCBtZXRob2RzIGFyZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGJ1Z2d5LiBBZGFwdGVkIGZyb20gQFlhZmZsZSdzIGBkYXRlLXNoaW1gIHByb2plY3QuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0ZSA9IGZsb29yKHZhbHVlIC8gODY0ZTUpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoeWVhciA9IGZsb29yKGRhdGUgLyAzNjUuMjQyNSkgKyAxOTcwIC0gMTsgZ2V0RGF5KHllYXIgKyAxLCAwKSA8PSBkYXRlOyB5ZWFyKyspIHt9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChtb250aCA9IGZsb29yKChkYXRlIC0gZ2V0RGF5KHllYXIsIDApKSAvIDMwLjQyKTsgZ2V0RGF5KHllYXIsIG1vbnRoICsgMSkgPD0gZGF0ZTsgbW9udGgrKykge31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRlID0gMSArIGRhdGUgLSBnZXREYXkoeWVhciwgbW9udGgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBgdGltZWAgdmFsdWUgc3BlY2lmaWVzIHRoZSB0aW1lIHdpdGhpbiB0aGUgZGF5IChzZWUgRVNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyA1LjEgc2VjdGlvbiAxNS45LjEuMikuIFRoZSBmb3JtdWxhIGAoQSAlIEIgKyBCKSAlIEJgIGlzIHVzZWRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0byBjb21wdXRlIGBBIG1vZHVsbyBCYCwgYXMgdGhlIGAlYCBvcGVyYXRvciBkb2VzIG5vdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGNvcnJlc3BvbmQgdG8gdGhlIGBtb2R1bG9gIG9wZXJhdGlvbiBmb3IgbmVnYXRpdmUgbnVtYmVycy5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aW1lID0gKHZhbHVlICUgODY0ZTUgKyA4NjRlNSkgJSA4NjRlNTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBUaGUgaG91cnMsIG1pbnV0ZXMsIHNlY29uZHMsIGFuZCBtaWxsaXNlY29uZHMgYXJlIG9idGFpbmVkIGJ5XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZGVjb21wb3NpbmcgdGhlIHRpbWUgd2l0aGluIHRoZSBkYXkuIFNlZSBzZWN0aW9uIDE1LjkuMS4xMC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3VycyA9IGZsb29yKHRpbWUgLyAzNmU1KSAlIDI0O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbnV0ZXMgPSBmbG9vcih0aW1lIC8gNmU0KSAlIDYwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlY29uZHMgPSBmbG9vcih0aW1lIC8gMWUzKSAlIDYwO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbGxpc2Vjb25kcyA9IHRpbWUgJSAxZTM7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhciA9IHZhbHVlLmdldFVUQ0Z1bGxZZWFyKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbW9udGggPSB2YWx1ZS5nZXRVVENNb250aCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGUgPSB2YWx1ZS5nZXRVVENEYXRlKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaG91cnMgPSB2YWx1ZS5nZXRVVENIb3VycygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1pbnV0ZXMgPSB2YWx1ZS5nZXRVVENNaW51dGVzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vjb25kcyA9IHZhbHVlLmdldFVUQ1NlY29uZHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaWxsaXNlY29uZHMgPSB2YWx1ZS5nZXRVVENNaWxsaXNlY29uZHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTZXJpYWxpemUgZXh0ZW5kZWQgeWVhcnMgY29ycmVjdGx5LlxuICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9ICh5ZWFyIDw9IDAgfHwgeWVhciA+PSAxZTQgPyAoeWVhciA8IDAgPyBcIi1cIiA6IFwiK1wiKSArIHRvUGFkZGVkU3RyaW5nKDYsIHllYXIgPCAwID8gLXllYXIgOiB5ZWFyKSA6IHRvUGFkZGVkU3RyaW5nKDQsIHllYXIpKSArIFwiLVwiICsgdG9QYWRkZWRTdHJpbmcoMiwgbW9udGggKyAxKSArIFwiLVwiICsgdG9QYWRkZWRTdHJpbmcoMiwgZGF0ZSkgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBNb250aHMsIGRhdGVzLCBob3VycywgbWludXRlcywgYW5kIHNlY29uZHMgc2hvdWxkIGhhdmUgdHdvXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRpZ2l0czsgbWlsbGlzZWNvbmRzIHNob3VsZCBoYXZlIHRocmVlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICBcIlRcIiArIHRvUGFkZGVkU3RyaW5nKDIsIGhvdXJzKSArIFwiOlwiICsgdG9QYWRkZWRTdHJpbmcoMiwgbWludXRlcykgKyBcIjpcIiArIHRvUGFkZGVkU3RyaW5nKDIsIHNlY29uZHMpICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTWlsbGlzZWNvbmRzIGFyZSBvcHRpb25hbCBpbiBFUyA1LjAsIGJ1dCByZXF1aXJlZCBpbiA1LjEuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFwiLlwiICsgdG9QYWRkZWRTdHJpbmcoMywgbWlsbGlzZWNvbmRzKSArIFwiWlwiO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBudWxsO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlLnRvSlNPTiA9PSBcImZ1bmN0aW9uXCIgJiYgKGNsYXNzTmFtZSAhPSBudW1iZXJDbGFzcyAmJiBjbGFzc05hbWUgIT0gc3RyaW5nQ2xhc3MgJiYgY2xhc3NOYW1lICE9IGFycmF5Q2xhc3MgfHwgX2lzUHJvcGVydHkuY2FsbCh2YWx1ZSwgXCJ0b0pTT05cIikpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBQcm90b3R5cGUgPD0gMS42LjEgYWRkcyBub24tc3RhbmRhcmQgYHRvSlNPTmAgbWV0aG9kcyB0byB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGBOdW1iZXJgLCBgU3RyaW5nYCwgYERhdGVgLCBhbmQgYEFycmF5YCBwcm90b3R5cGVzLiBKU09OIDNcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGlnbm9yZXMgYWxsIGB0b0pTT05gIG1ldGhvZHMgb24gdGhlc2Ugb2JqZWN0cyB1bmxlc3MgdGhleSBhcmVcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIGRlZmluZWQgZGlyZWN0bHkgb24gYW4gaW5zdGFuY2UuXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnRvSlNPTihwcm9wZXJ0eSk7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICAgIC8vIElmIGEgcmVwbGFjZW1lbnQgZnVuY3Rpb24gd2FzIHByb3ZpZGVkLCBjYWxsIGl0IHRvIG9idGFpbiB0aGUgdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAvLyBmb3Igc2VyaWFsaXphdGlvbi5cbiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGNhbGxiYWNrLmNhbGwob2JqZWN0LCBwcm9wZXJ0eSwgdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBjbGFzc05hbWUgPSBnZXRDbGFzcy5jYWxsKHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PSBib29sZWFuQ2xhc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBCb29sZWFucyBhcmUgcmVwcmVzZW50ZWQgbGl0ZXJhbGx5LlxuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBcIlwiICsgdmFsdWU7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2xhc3NOYW1lID09IG51bWJlckNsYXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gSlNPTiBudW1iZXJzIG11c3QgYmUgZmluaXRlLiBgSW5maW5pdHlgIGFuZCBgTmFOYCBhcmUgc2VyaWFsaXplZCBhc1xuICAgICAgICAgICAgICAgICAgICAgIC8vIGBcIm51bGxcImAuXG4gICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlID4gLTEgLyAwICYmIHZhbHVlIDwgMSAvIDAgPyBcIlwiICsgdmFsdWUgOiBcIm51bGxcIjtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjbGFzc05hbWUgPT0gc3RyaW5nQ2xhc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBTdHJpbmdzIGFyZSBkb3VibGUtcXVvdGVkIGFuZCBlc2NhcGVkLlxuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBxdW90ZShcIlwiICsgdmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZSBvYmplY3RzIGFuZCBhcnJheXMuXG4gICAgICAgICAgICAgICAgICAgIGlmICgodHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6IF90eXBlb2YodmFsdWUpKSA9PSBcIm9iamVjdFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGN5Y2xpYyBzdHJ1Y3R1cmVzLiBUaGlzIGlzIGEgbGluZWFyIHNlYXJjaDsgcGVyZm9ybWFuY2VcbiAgICAgICAgICAgICAgICAgICAgICAvLyBpcyBpbnZlcnNlbHkgcHJvcG9ydGlvbmFsIHRvIHRoZSBudW1iZXIgb2YgdW5pcXVlIG5lc3RlZCBvYmplY3RzLlxuICAgICAgICAgICAgICAgICAgICAgIGZvciAobGVuZ3RoID0gc3RhY2subGVuZ3RoOyBsZW5ndGgtLTspIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzdGFja1tsZW5ndGhdID09PSB2YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBDeWNsaWMgc3RydWN0dXJlcyBjYW5ub3QgYmUgc2VyaWFsaXplZCBieSBgSlNPTi5zdHJpbmdpZnlgLlxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBUeXBlRXJyb3IoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgLy8gQWRkIHRoZSBvYmplY3QgdG8gdGhlIHN0YWNrIG9mIHRyYXZlcnNlZCBvYmplY3RzLlxuICAgICAgICAgICAgICAgICAgICAgIHN0YWNrLnB1c2godmFsdWUpO1xuICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMgPSBbXTtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBTYXZlIHRoZSBjdXJyZW50IGluZGVudGF0aW9uIGxldmVsIGFuZCBpbmRlbnQgb25lIGFkZGl0aW9uYWwgbGV2ZWwuXG4gICAgICAgICAgICAgICAgICAgICAgcHJlZml4ID0gaW5kZW50YXRpb247XG4gICAgICAgICAgICAgICAgICAgICAgaW5kZW50YXRpb24gKz0gd2hpdGVzcGFjZTtcbiAgICAgICAgICAgICAgICAgICAgICBpZiAoY2xhc3NOYW1lID09IGFycmF5Q2xhc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlY3Vyc2l2ZWx5IHNlcmlhbGl6ZSBhcnJheSBlbGVtZW50cy5cbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaW5kZXggPSAwLCBsZW5ndGggPSB2YWx1ZS5sZW5ndGg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBzZXJpYWxpemUoaW5kZXgsIHZhbHVlLCBjYWxsYmFjaywgcHJvcGVydGllcywgd2hpdGVzcGFjZSwgaW5kZW50YXRpb24sIHN0YWNrKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKGVsZW1lbnQgPT09IHVuZGVmID8gXCJudWxsXCIgOiBlbGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdHMubGVuZ3RoID8gd2hpdGVzcGFjZSA/IFwiW1xcblwiICsgaW5kZW50YXRpb24gKyByZXN1bHRzLmpvaW4oXCIsXFxuXCIgKyBpbmRlbnRhdGlvbikgKyBcIlxcblwiICsgcHJlZml4ICsgXCJdXCIgOiBcIltcIiArIHJlc3VsdHMuam9pbihcIixcIikgKyBcIl1cIiA6IFwiW11cIjtcbiAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gUmVjdXJzaXZlbHkgc2VyaWFsaXplIG9iamVjdCBtZW1iZXJzLiBNZW1iZXJzIGFyZSBzZWxlY3RlZCBmcm9tXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBlaXRoZXIgYSB1c2VyLXNwZWNpZmllZCBsaXN0IG9mIHByb3BlcnR5IG5hbWVzLCBvciB0aGUgb2JqZWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBpdHNlbGYuXG4gICAgICAgICAgICAgICAgICAgICAgICBfZm9yRWFjaChwcm9wZXJ0aWVzIHx8IHZhbHVlLCBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSBzZXJpYWxpemUocHJvcGVydHksIHZhbHVlLCBjYWxsYmFjaywgcHJvcGVydGllcywgd2hpdGVzcGFjZSwgaW5kZW50YXRpb24sIHN0YWNrKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgIT09IHVuZGVmKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQWNjb3JkaW5nIHRvIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjM6IFwiSWYgYGdhcGAge3doaXRlc3BhY2V9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gaXMgbm90IHRoZSBlbXB0eSBzdHJpbmcsIGxldCBgbWVtYmVyYCB7cXVvdGUocHJvcGVydHkpICsgXCI6XCJ9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYmUgdGhlIGNvbmNhdGVuYXRpb24gb2YgYG1lbWJlcmAgYW5kIHRoZSBgc3BhY2VgIGNoYXJhY3Rlci5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFRoZSBcImBzcGFjZWAgY2hhcmFjdGVyXCIgcmVmZXJzIHRvIHRoZSBsaXRlcmFsIHNwYWNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2hhcmFjdGVyLCBub3QgdGhlIGBzcGFjZWAge3dpZHRofSBhcmd1bWVudCBwcm92aWRlZCB0b1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGBKU09OLnN0cmluZ2lmeWAuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cy5wdXNoKHF1b3RlKHByb3BlcnR5KSArIFwiOlwiICsgKHdoaXRlc3BhY2UgPyBcIiBcIiA6IFwiXCIpICsgZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0cy5sZW5ndGggPyB3aGl0ZXNwYWNlID8gXCJ7XFxuXCIgKyBpbmRlbnRhdGlvbiArIHJlc3VsdHMuam9pbihcIixcXG5cIiArIGluZGVudGF0aW9uKSArIFwiXFxuXCIgKyBwcmVmaXggKyBcIn1cIiA6IFwie1wiICsgcmVzdWx0cy5qb2luKFwiLFwiKSArIFwifVwiIDogXCJ7fVwiO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAvLyBSZW1vdmUgdGhlIG9iamVjdCBmcm9tIHRoZSB0cmF2ZXJzZWQgb2JqZWN0IHN0YWNrLlxuICAgICAgICAgICAgICAgICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgIC8vIFB1YmxpYzogYEpTT04uc3RyaW5naWZ5YC4gU2VlIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjMuXG4gICAgICAgICAgICAgICAgICBleHBvcnRzLnN0cmluZ2lmeSA9IGZ1bmN0aW9uIChzb3VyY2UsIGZpbHRlciwgd2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHdoaXRlc3BhY2UsIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCBjbGFzc05hbWU7XG4gICAgICAgICAgICAgICAgICAgIGlmIChvYmplY3RUeXBlc1t0eXBlb2YgZmlsdGVyID09PSBcInVuZGVmaW5lZFwiID8gXCJ1bmRlZmluZWRcIiA6IF90eXBlb2YoZmlsdGVyKV0gJiYgZmlsdGVyKSB7XG4gICAgICAgICAgICAgICAgICAgICAgaWYgKChjbGFzc05hbWUgPSBnZXRDbGFzcy5jYWxsKGZpbHRlcikpID09IGZ1bmN0aW9uQ2xhc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrID0gZmlsdGVyO1xuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoY2xhc3NOYW1lID09IGFycmF5Q2xhc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIENvbnZlcnQgdGhlIHByb3BlcnR5IG5hbWVzIGFycmF5IGludG8gYSBtYWtlc2hpZnQgc2V0LlxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvcGVydGllcyA9IHt9O1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaW5kZXggPSAwLCBsZW5ndGggPSBmaWx0ZXIubGVuZ3RoLCB2YWx1ZTsgaW5kZXggPCBsZW5ndGg7IHZhbHVlID0gZmlsdGVyW2luZGV4KytdLCAoY2xhc3NOYW1lID0gZ2V0Q2xhc3MuY2FsbCh2YWx1ZSksIGNsYXNzTmFtZSA9PSBzdHJpbmdDbGFzcyB8fCBjbGFzc05hbWUgPT0gbnVtYmVyQ2xhc3MpICYmIChwcm9wZXJ0aWVzW3ZhbHVlXSA9IDEpKSB7fVxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBpZiAod2lkdGgpIHtcbiAgICAgICAgICAgICAgICAgICAgICBpZiAoKGNsYXNzTmFtZSA9IGdldENsYXNzLmNhbGwod2lkdGgpKSA9PSBudW1iZXJDbGFzcykge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29udmVydCB0aGUgYHdpZHRoYCB0byBhbiBpbnRlZ2VyIGFuZCBjcmVhdGUgYSBzdHJpbmcgY29udGFpbmluZ1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gYHdpZHRoYCBudW1iZXIgb2Ygc3BhY2UgY2hhcmFjdGVycy5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICgod2lkdGggLT0gd2lkdGggJSAxKSA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh3aGl0ZXNwYWNlID0gXCJcIiwgd2lkdGggPiAxMCAmJiAod2lkdGggPSAxMCk7IHdoaXRlc3BhY2UubGVuZ3RoIDwgd2lkdGg7IHdoaXRlc3BhY2UgKz0gXCIgXCIpIHt9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjbGFzc05hbWUgPT0gc3RyaW5nQ2xhc3MpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHdoaXRlc3BhY2UgPSB3aWR0aC5sZW5ndGggPD0gMTAgPyB3aWR0aCA6IHdpZHRoLnNsaWNlKDAsIDEwKTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gT3BlcmEgPD0gNy41NHUyIGRpc2NhcmRzIHRoZSB2YWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGVtcHR5IHN0cmluZyBrZXlzXG4gICAgICAgICAgICAgICAgICAgIC8vIChgXCJcImApIG9ubHkgaWYgdGhleSBhcmUgdXNlZCBkaXJlY3RseSB3aXRoaW4gYW4gb2JqZWN0IG1lbWJlciBsaXN0XG4gICAgICAgICAgICAgICAgICAgIC8vIChlLmcuLCBgIShcIlwiIGluIHsgXCJcIjogMX0pYCkuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBzZXJpYWxpemUoXCJcIiwgKHZhbHVlID0ge30sIHZhbHVlW1wiXCJdID0gc291cmNlLCB2YWx1ZSksIGNhbGxiYWNrLCBwcm9wZXJ0aWVzLCB3aGl0ZXNwYWNlLCBcIlwiLCBbXSk7XG4gICAgICAgICAgICAgICAgICB9O1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIFB1YmxpYzogUGFyc2VzIGEgSlNPTiBzb3VyY2Ugc3RyaW5nLlxuICAgICAgICAgICAgICAgIGlmICghaGFzKFwianNvbi1wYXJzZVwiKSkge1xuICAgICAgICAgICAgICAgICAgdmFyIGZyb21DaGFyQ29kZSA9IFN0cmluZy5mcm9tQ2hhckNvZGU7XG5cbiAgICAgICAgICAgICAgICAgIC8vIEludGVybmFsOiBBIG1hcCBvZiBlc2NhcGVkIGNvbnRyb2wgY2hhcmFjdGVycyBhbmQgdGhlaXIgdW5lc2NhcGVkXG4gICAgICAgICAgICAgICAgICAvLyBlcXVpdmFsZW50cy5cbiAgICAgICAgICAgICAgICAgIHZhciBVbmVzY2FwZXMgPSB7XG4gICAgICAgICAgICAgICAgICAgIDkyOiBcIlxcXFxcIixcbiAgICAgICAgICAgICAgICAgICAgMzQ6ICdcIicsXG4gICAgICAgICAgICAgICAgICAgIDQ3OiBcIi9cIixcbiAgICAgICAgICAgICAgICAgICAgOTg6IFwiXFxiXCIsXG4gICAgICAgICAgICAgICAgICAgIDExNjogXCJcXHRcIixcbiAgICAgICAgICAgICAgICAgICAgMTEwOiBcIlxcblwiLFxuICAgICAgICAgICAgICAgICAgICAxMDI6IFwiXFxmXCIsXG4gICAgICAgICAgICAgICAgICAgIDExNDogXCJcXHJcIlxuICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgLy8gSW50ZXJuYWw6IFN0b3JlcyB0aGUgcGFyc2VyIHN0YXRlLlxuICAgICAgICAgICAgICAgICAgdmFyIEluZGV4LCBTb3VyY2U7XG5cbiAgICAgICAgICAgICAgICAgIC8vIEludGVybmFsOiBSZXNldHMgdGhlIHBhcnNlciBzdGF0ZSBhbmQgdGhyb3dzIGEgYFN5bnRheEVycm9yYC5cbiAgICAgICAgICAgICAgICAgIHZhciBhYm9ydCA9IGZ1bmN0aW9uIGFib3J0KCkge1xuICAgICAgICAgICAgICAgICAgICBJbmRleCA9IFNvdXJjZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IFN5bnRheEVycm9yKCk7XG4gICAgICAgICAgICAgICAgICB9O1xuXG4gICAgICAgICAgICAgICAgICAvLyBJbnRlcm5hbDogUmV0dXJucyB0aGUgbmV4dCB0b2tlbiwgb3IgYFwiJFwiYCBpZiB0aGUgcGFyc2VyIGhhcyByZWFjaGVkXG4gICAgICAgICAgICAgICAgICAvLyB0aGUgZW5kIG9mIHRoZSBzb3VyY2Ugc3RyaW5nLiBBIHRva2VuIG1heSBiZSBhIHN0cmluZywgbnVtYmVyLCBgbnVsbGBcbiAgICAgICAgICAgICAgICAgIC8vIGxpdGVyYWwsIG9yIEJvb2xlYW4gbGl0ZXJhbC5cbiAgICAgICAgICAgICAgICAgIHZhciBsZXggPSBmdW5jdGlvbiBsZXgoKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBzb3VyY2UgPSBTb3VyY2UsXG4gICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggPSBzb3VyY2UubGVuZ3RoLFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUsXG4gICAgICAgICAgICAgICAgICAgICAgICBiZWdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgaXNTaWduZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICBjaGFyQ29kZTtcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKEluZGV4IDwgbGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjaGFyQ29kZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA5OmNhc2UgMTA6Y2FzZSAxMzpjYXNlIDMyOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBTa2lwIHdoaXRlc3BhY2UgdG9rZW5zLCBpbmNsdWRpbmcgdGFicywgY2FycmlhZ2UgcmV0dXJucywgbGluZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBmZWVkcywgYW5kIHNwYWNlIGNoYXJhY3RlcnMuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxMjM6Y2FzZSAxMjU6Y2FzZSA5MTpjYXNlIDkzOmNhc2UgNTg6Y2FzZSA0NDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgYSBwdW5jdHVhdG9yIHRva2VuIChge2AsIGB9YCwgYFtgLCBgXWAsIGA6YCwgb3IgYCxgKSBhdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGUgY3VycmVudCBwb3NpdGlvbi5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBjaGFySW5kZXhCdWdneSA/IHNvdXJjZS5jaGFyQXQoSW5kZXgpIDogc291cmNlW0luZGV4XTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgSW5kZXgrKztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAzNDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYFwiYCBkZWxpbWl0cyBhIEpTT04gc3RyaW5nOyBhZHZhbmNlIHRvIHRoZSBuZXh0IGNoYXJhY3RlciBhbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYmVnaW4gcGFyc2luZyB0aGUgc3RyaW5nLiBTdHJpbmcgdG9rZW5zIGFyZSBwcmVmaXhlZCB3aXRoIHRoZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzZW50aW5lbCBgQGAgY2hhcmFjdGVyIHRvIGRpc3Rpbmd1aXNoIHRoZW0gZnJvbSBwdW5jdHVhdG9ycyBhbmRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gZW5kLW9mLXN0cmluZyB0b2tlbnMuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFsdWUgPSBcIkBcIiwgSW5kZXgrKzsgSW5kZXggPCBsZW5ndGg7KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlIDwgMzIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVuZXNjYXBlZCBBU0NJSSBjb250cm9sIGNoYXJhY3RlcnMgKHRob3NlIHdpdGggYSBjb2RlIHVuaXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxlc3MgdGhhbiB0aGUgc3BhY2UgY2hhcmFjdGVyKSBhcmUgbm90IHBlcm1pdHRlZC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjaGFyQ29kZSA9PSA5Mikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQSByZXZlcnNlIHNvbGlkdXMgKGBcXGApIG1hcmtzIHRoZSBiZWdpbm5pbmcgb2YgYW4gZXNjYXBlZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29udHJvbCBjaGFyYWN0ZXIgKGluY2x1ZGluZyBgXCJgLCBgXFxgLCBhbmQgYC9gKSBvciBVbmljb2RlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KCsrSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoIChjaGFyQ29kZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDkyOmNhc2UgMzQ6Y2FzZSA0NzpjYXNlIDk4OmNhc2UgMTE2OmNhc2UgMTEwOmNhc2UgMTAyOmNhc2UgMTE0OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJldml2ZSBlc2NhcGVkIGNvbnRyb2wgY2hhcmFjdGVycy5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSArPSBVbmVzY2FwZXNbY2hhckNvZGVdO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMTE3OlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGBcXHVgIG1hcmtzIHRoZSBiZWdpbm5pbmcgb2YgYSBVbmljb2RlIGVzY2FwZSBzZXF1ZW5jZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBZHZhbmNlIHRvIHRoZSBmaXJzdCBjaGFyYWN0ZXIgYW5kIHZhbGlkYXRlIHRoZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZvdXItZGlnaXQgY29kZSBwb2ludC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZWdpbiA9ICsrSW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChwb3NpdGlvbiA9IEluZGV4ICsgNDsgSW5kZXggPCBwb3NpdGlvbjsgSW5kZXgrKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBIHZhbGlkIHNlcXVlbmNlIGNvbXByaXNlcyBmb3VyIGhleGRpZ2l0cyAoY2FzZS1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGluc2Vuc2l0aXZlKSB0aGF0IGZvcm0gYSBzaW5nbGUgaGV4YWRlY2ltYWwgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShjaGFyQ29kZSA+PSA0OCAmJiBjaGFyQ29kZSA8PSA1NyB8fCBjaGFyQ29kZSA+PSA5NyAmJiBjaGFyQ29kZSA8PSAxMDIgfHwgY2hhckNvZGUgPj0gNjUgJiYgY2hhckNvZGUgPD0gNzApKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEludmFsaWQgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJldml2ZSB0aGUgZXNjYXBlZCBjaGFyYWN0ZXIuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgKz0gZnJvbUNoYXJDb2RlKFwiMHhcIiArIHNvdXJjZS5zbGljZShiZWdpbiwgSW5kZXgpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbnZhbGlkIGVzY2FwZSBzZXF1ZW5jZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPT0gMzQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQW4gdW5lc2NhcGVkIGRvdWJsZS1xdW90ZSBjaGFyYWN0ZXIgbWFya3MgdGhlIGVuZCBvZiB0aGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3RyaW5nLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmVnaW4gPSBJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIE9wdGltaXplIGZvciB0aGUgY29tbW9uIGNhc2Ugd2hlcmUgYSBzdHJpbmcgaXMgdmFsaWQuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3aGlsZSAoY2hhckNvZGUgPj0gMzIgJiYgY2hhckNvZGUgIT0gOTIgJiYgY2hhckNvZGUgIT0gMzQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdCgrK0luZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFwcGVuZCB0aGUgc3RyaW5nIGFzLWlzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgKz0gc291cmNlLnNsaWNlKGJlZ2luLCBJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuY2hhckNvZGVBdChJbmRleCkgPT0gMzQpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBZHZhbmNlIHRvIHRoZSBuZXh0IGNoYXJhY3RlciBhbmQgcmV0dXJuIHRoZSByZXZpdmVkIHN0cmluZy5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRleCsrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBVbnRlcm1pbmF0ZWQgc3RyaW5nLlxuICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgbnVtYmVycyBhbmQgbGl0ZXJhbHMuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGJlZ2luID0gSW5kZXg7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEFkdmFuY2UgcGFzdCB0aGUgbmVnYXRpdmUgc2lnbiwgaWYgb25lIGlzIHNwZWNpZmllZC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID09IDQ1KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNTaWduZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXJDb2RlID0gc291cmNlLmNoYXJDb2RlQXQoKytJbmRleCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgYW4gaW50ZWdlciBvciBmbG9hdGluZy1wb2ludCB2YWx1ZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gTGVhZGluZyB6ZXJvZXMgYXJlIGludGVycHJldGVkIGFzIG9jdGFsIGxpdGVyYWxzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGFyQ29kZSA9PSA0OCAmJiAoY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCArIDEpLCBjaGFyQ29kZSA+PSA0OCAmJiBjaGFyQ29kZSA8PSA1NykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElsbGVnYWwgb2N0YWwgbGl0ZXJhbC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzU2lnbmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2UgdGhlIGludGVnZXIgY29tcG9uZW50LlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBJbmRleCA8IGxlbmd0aCAmJiAoY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChJbmRleCksIGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3KTsgSW5kZXgrKykge31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBGbG9hdHMgY2Fubm90IGNvbnRhaW4gYSBsZWFkaW5nIGRlY2ltYWwgcG9pbnQ7IGhvd2V2ZXIsIHRoaXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBjYXNlIGlzIGFscmVhZHkgYWNjb3VudGVkIGZvciBieSB0aGUgcGFyc2VyLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChzb3VyY2UuY2hhckNvZGVBdChJbmRleCkgPT0gNDYpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uID0gKytJbmRleDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBhcnNlIHRoZSBkZWNpbWFsIGNvbXBvbmVudC5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoOyBwb3NpdGlvbiA8IGxlbmd0aCAmJiAoY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChwb3NpdGlvbiksIGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3KTsgcG9zaXRpb24rKykge31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwb3NpdGlvbiA9PSBJbmRleCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbGxlZ2FsIHRyYWlsaW5nIGRlY2ltYWwuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJbmRleCA9IHBvc2l0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQYXJzZSBleHBvbmVudHMuIFRoZSBgZWAgZGVub3RpbmcgdGhlIGV4cG9uZW50IGlzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY2FzZS1pbnNlbnNpdGl2ZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KEluZGV4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hhckNvZGUgPT0gMTAxIHx8IGNoYXJDb2RlID09IDY5KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyQ29kZSA9IHNvdXJjZS5jaGFyQ29kZUF0KCsrSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gU2tpcCBwYXN0IHRoZSBzaWduIGZvbGxvd2luZyB0aGUgZXhwb25lbnQsIGlmIG9uZSBpc1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3BlY2lmaWVkLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoYXJDb2RlID09IDQzIHx8IGNoYXJDb2RlID09IDQ1KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEluZGV4Kys7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBQYXJzZSB0aGUgZXhwb25lbnRpYWwgY29tcG9uZW50LlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChwb3NpdGlvbiA9IEluZGV4OyBwb3NpdGlvbiA8IGxlbmd0aCAmJiAoY2hhckNvZGUgPSBzb3VyY2UuY2hhckNvZGVBdChwb3NpdGlvbiksIGNoYXJDb2RlID49IDQ4ICYmIGNoYXJDb2RlIDw9IDU3KTsgcG9zaXRpb24rKykge31cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwb3NpdGlvbiA9PSBJbmRleCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBJbGxlZ2FsIGVtcHR5IGV4cG9uZW50LlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5kZXggPSBwb3NpdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ29lcmNlIHRoZSBwYXJzZWQgdmFsdWUgdG8gYSBKYXZhU2NyaXB0IG51bWJlci5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gK3NvdXJjZS5zbGljZShiZWdpbiwgSW5kZXgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEEgbmVnYXRpdmUgc2lnbiBtYXkgb25seSBwcmVjZWRlIG51bWJlcnMuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc1NpZ25lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gYHRydWVgLCBgZmFsc2VgLCBhbmQgYG51bGxgIGxpdGVyYWxzLlxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoc291cmNlLnNsaWNlKEluZGV4LCBJbmRleCArIDQpID09IFwidHJ1ZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5kZXggKz0gNDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzb3VyY2Uuc2xpY2UoSW5kZXgsIEluZGV4ICsgNSkgPT0gXCJmYWxzZVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5kZXggKz0gNTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoc291cmNlLnNsaWNlKEluZGV4LCBJbmRleCArIDQpID09IFwibnVsbFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgSW5kZXggKz0gNDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBVbnJlY29nbml6ZWQgdG9rZW4uXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIFJldHVybiB0aGUgc2VudGluZWwgYCRgIGNoYXJhY3RlciBpZiB0aGUgcGFyc2VyIGhhcyByZWFjaGVkIHRoZSBlbmRcbiAgICAgICAgICAgICAgICAgICAgLy8gb2YgdGhlIHNvdXJjZSBzdHJpbmcuXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBcIiRcIjtcbiAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgIC8vIEludGVybmFsOiBQYXJzZXMgYSBKU09OIGB2YWx1ZWAgdG9rZW4uXG4gICAgICAgICAgICAgICAgICB2YXIgZ2V0ID0gZnVuY3Rpb24gZ2V0KHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHRzLCBoYXNNZW1iZXJzO1xuICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCIkXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBVbmV4cGVjdGVkIGVuZCBvZiBpbnB1dC5cbiAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT0gXCJzdHJpbmdcIikge1xuICAgICAgICAgICAgICAgICAgICAgIGlmICgoY2hhckluZGV4QnVnZ3kgPyB2YWx1ZS5jaGFyQXQoMCkgOiB2YWx1ZVswXSkgPT0gXCJAXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlbW92ZSB0aGUgc2VudGluZWwgYEBgIGNoYXJhY3Rlci5cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB2YWx1ZS5zbGljZSgxKTtcbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgLy8gUGFyc2Ugb2JqZWN0IGFuZCBhcnJheSBsaXRlcmFscy5cbiAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCJbXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBhcnNlcyBhIEpTT04gYXJyYXksIHJldHVybmluZyBhIG5ldyBKYXZhU2NyaXB0IGFycmF5LlxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IFtdO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICg7OyBoYXNNZW1iZXJzIHx8IChoYXNNZW1iZXJzID0gdHJ1ZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPSBsZXgoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQSBjbG9zaW5nIHNxdWFyZSBicmFja2V0IG1hcmtzIHRoZSBlbmQgb2YgdGhlIGFycmF5IGxpdGVyYWwuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIl1cIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBhcnJheSBsaXRlcmFsIGNvbnRhaW5zIGVsZW1lbnRzLCB0aGUgY3VycmVudCB0b2tlblxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaG91bGQgYmUgYSBjb21tYSBzZXBhcmF0aW5nIHRoZSBwcmV2aW91cyBlbGVtZW50IGZyb20gdGhlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIG5leHQuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoYXNNZW1iZXJzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiLFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiXVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVuZXhwZWN0ZWQgdHJhaWxpbmcgYCxgIGluIGFycmF5IGxpdGVyYWwuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIEEgYCxgIG11c3Qgc2VwYXJhdGUgZWFjaCBhcnJheSBlbGVtZW50LlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gRWxpc2lvbnMgYW5kIGxlYWRpbmcgY29tbWFzIGFyZSBub3QgcGVybWl0dGVkLlxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gXCIsXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHMucHVzaChnZXQodmFsdWUpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodmFsdWUgPT0gXCJ7XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFBhcnNlcyBhIEpTT04gb2JqZWN0LCByZXR1cm5pbmcgYSBuZXcgSmF2YVNjcmlwdCBvYmplY3QuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRzID0ge307XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKDs7IGhhc01lbWJlcnMgfHwgKGhhc01lbWJlcnMgPSB0cnVlKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBIGNsb3NpbmcgY3VybHkgYnJhY2UgbWFya3MgdGhlIGVuZCBvZiB0aGUgb2JqZWN0IGxpdGVyYWwuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIn1cIikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIElmIHRoZSBvYmplY3QgbGl0ZXJhbCBjb250YWlucyBtZW1iZXJzLCB0aGUgY3VycmVudCB0b2tlblxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzaG91bGQgYmUgYSBjb21tYSBzZXBhcmF0b3IuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoYXNNZW1iZXJzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwiLFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IGxleCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IFwifVwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIFVuZXhwZWN0ZWQgdHJhaWxpbmcgYCxgIGluIG9iamVjdCBsaXRlcmFsLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBBIGAsYCBtdXN0IHNlcGFyYXRlIGVhY2ggb2JqZWN0IG1lbWJlci5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIExlYWRpbmcgY29tbWFzIGFyZSBub3QgcGVybWl0dGVkLCBvYmplY3QgcHJvcGVydHkgbmFtZXMgbXVzdCBiZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBkb3VibGUtcXVvdGVkIHN0cmluZ3MsIGFuZCBhIGA6YCBtdXN0IHNlcGFyYXRlIGVhY2ggcHJvcGVydHlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gbmFtZSBhbmQgdmFsdWUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBcIixcIiB8fCB0eXBlb2YgdmFsdWUgIT0gXCJzdHJpbmdcIiB8fCAoY2hhckluZGV4QnVnZ3kgPyB2YWx1ZS5jaGFyQXQoMCkgOiB2YWx1ZVswXSkgIT0gXCJAXCIgfHwgbGV4KCkgIT0gXCI6XCIpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhYm9ydCgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdHNbdmFsdWUuc2xpY2UoMSldID0gZ2V0KGxleCgpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHRzO1xuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAvLyBVbmV4cGVjdGVkIHRva2VuIGVuY291bnRlcmVkLlxuICAgICAgICAgICAgICAgICAgICAgIGFib3J0KCk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHZhbHVlO1xuICAgICAgICAgICAgICAgICAgfTtcblxuICAgICAgICAgICAgICAgICAgLy8gSW50ZXJuYWw6IFVwZGF0ZXMgYSB0cmF2ZXJzZWQgb2JqZWN0IG1lbWJlci5cbiAgICAgICAgICAgICAgICAgIHZhciB1cGRhdGUgPSBmdW5jdGlvbiB1cGRhdGUoc291cmNlLCBwcm9wZXJ0eSwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGVsZW1lbnQgPSB3YWxrKHNvdXJjZSwgcHJvcGVydHksIGNhbGxiYWNrKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVsZW1lbnQgPT09IHVuZGVmKSB7XG4gICAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHNvdXJjZVtwcm9wZXJ0eV07XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgc291cmNlW3Byb3BlcnR5XSA9IGVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgIC8vIEludGVybmFsOiBSZWN1cnNpdmVseSB0cmF2ZXJzZXMgYSBwYXJzZWQgSlNPTiBvYmplY3QsIGludm9raW5nIHRoZVxuICAgICAgICAgICAgICAgICAgLy8gYGNhbGxiYWNrYCBmdW5jdGlvbiBmb3IgZWFjaCB2YWx1ZS4gVGhpcyBpcyBhbiBpbXBsZW1lbnRhdGlvbiBvZiB0aGVcbiAgICAgICAgICAgICAgICAgIC8vIGBXYWxrKGhvbGRlciwgbmFtZSlgIG9wZXJhdGlvbiBkZWZpbmVkIGluIEVTIDUuMSBzZWN0aW9uIDE1LjEyLjIuXG4gICAgICAgICAgICAgICAgICB2YXIgd2FsayA9IGZ1bmN0aW9uIHdhbGsoc291cmNlLCBwcm9wZXJ0eSwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gc291cmNlW3Byb3BlcnR5XSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aDtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCh0eXBlb2YgdmFsdWUgPT09IFwidW5kZWZpbmVkXCIgPyBcInVuZGVmaW5lZFwiIDogX3R5cGVvZih2YWx1ZSkpID09IFwib2JqZWN0XCIgJiYgdmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAvLyBgZm9yRWFjaGAgY2FuJ3QgYmUgdXNlZCB0byB0cmF2ZXJzZSBhbiBhcnJheSBpbiBPcGVyYSA8PSA4LjU0XG4gICAgICAgICAgICAgICAgICAgICAgLy8gYmVjYXVzZSBpdHMgYE9iamVjdCNoYXNPd25Qcm9wZXJ0eWAgaW1wbGVtZW50YXRpb24gcmV0dXJucyBgZmFsc2VgXG4gICAgICAgICAgICAgICAgICAgICAgLy8gZm9yIGFycmF5IGluZGljZXMgKGUuZy4sIGAhWzEsIDIsIDNdLmhhc093blByb3BlcnR5KFwiMFwiKWApLlxuICAgICAgICAgICAgICAgICAgICAgIGlmIChnZXRDbGFzcy5jYWxsKHZhbHVlKSA9PSBhcnJheUNsYXNzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGxlbmd0aCA9IHZhbHVlLmxlbmd0aDsgbGVuZ3RoLS07KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZSh2YWx1ZSwgbGVuZ3RoLCBjYWxsYmFjayk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIF9mb3JFYWNoKHZhbHVlLCBmdW5jdGlvbiAocHJvcGVydHkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKHZhbHVlLCBwcm9wZXJ0eSwgY2FsbGJhY2spO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjay5jYWxsKHNvdXJjZSwgcHJvcGVydHksIHZhbHVlKTtcbiAgICAgICAgICAgICAgICAgIH07XG5cbiAgICAgICAgICAgICAgICAgIC8vIFB1YmxpYzogYEpTT04ucGFyc2VgLiBTZWUgRVMgNS4xIHNlY3Rpb24gMTUuMTIuMi5cbiAgICAgICAgICAgICAgICAgIGV4cG9ydHMucGFyc2UgPSBmdW5jdGlvbiAoc291cmNlLCBjYWxsYmFjaykge1xuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0LCB2YWx1ZTtcbiAgICAgICAgICAgICAgICAgICAgSW5kZXggPSAwO1xuICAgICAgICAgICAgICAgICAgICBTb3VyY2UgPSBcIlwiICsgc291cmNlO1xuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBnZXQobGV4KCkpO1xuICAgICAgICAgICAgICAgICAgICAvLyBJZiBhIEpTT04gc3RyaW5nIGNvbnRhaW5zIG11bHRpcGxlIHRva2VucywgaXQgaXMgaW52YWxpZC5cbiAgICAgICAgICAgICAgICAgICAgaWYgKGxleCgpICE9IFwiJFwiKSB7XG4gICAgICAgICAgICAgICAgICAgICAgYWJvcnQoKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAvLyBSZXNldCB0aGUgcGFyc2VyIHN0YXRlLlxuICAgICAgICAgICAgICAgICAgICBJbmRleCA9IFNvdXJjZSA9IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayAmJiBnZXRDbGFzcy5jYWxsKGNhbGxiYWNrKSA9PSBmdW5jdGlvbkNsYXNzID8gd2FsaygodmFsdWUgPSB7fSwgdmFsdWVbXCJcIl0gPSByZXN1bHQsIHZhbHVlKSwgXCJcIiwgY2FsbGJhY2spIDogcmVzdWx0O1xuICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBleHBvcnRzW1wicnVuSW5Db250ZXh0XCJdID0gcnVuSW5Db250ZXh0O1xuICAgICAgICAgICAgICByZXR1cm4gZXhwb3J0cztcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGZyZWVFeHBvcnRzICYmICFpc0xvYWRlcikge1xuICAgICAgICAgICAgICAvLyBFeHBvcnQgZm9yIENvbW1vbkpTIGVudmlyb25tZW50cy5cbiAgICAgICAgICAgICAgcnVuSW5Db250ZXh0KHJvb3QsIGZyZWVFeHBvcnRzKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIEV4cG9ydCBmb3Igd2ViIGJyb3dzZXJzIGFuZCBKYXZhU2NyaXB0IGVuZ2luZXMuXG4gICAgICAgICAgICAgIHZhciBuYXRpdmVKU09OID0gcm9vdC5KU09OLFxuICAgICAgICAgICAgICAgICAgcHJldmlvdXNKU09OID0gcm9vdFtcIkpTT04zXCJdLFxuICAgICAgICAgICAgICAgICAgaXNSZXN0b3JlZCA9IGZhbHNlO1xuXG4gICAgICAgICAgICAgIHZhciBKU09OMyA9IHJ1bkluQ29udGV4dChyb290LCByb290W1wiSlNPTjNcIl0gPSB7XG4gICAgICAgICAgICAgICAgLy8gUHVibGljOiBSZXN0b3JlcyB0aGUgb3JpZ2luYWwgdmFsdWUgb2YgdGhlIGdsb2JhbCBgSlNPTmAgb2JqZWN0IGFuZFxuICAgICAgICAgICAgICAgIC8vIHJldHVybnMgYSByZWZlcmVuY2UgdG8gdGhlIGBKU09OM2Agb2JqZWN0LlxuICAgICAgICAgICAgICAgIFwibm9Db25mbGljdFwiOiBmdW5jdGlvbiBub0NvbmZsaWN0KCkge1xuICAgICAgICAgICAgICAgICAgaWYgKCFpc1Jlc3RvcmVkKSB7XG4gICAgICAgICAgICAgICAgICAgIGlzUmVzdG9yZWQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICByb290LkpTT04gPSBuYXRpdmVKU09OO1xuICAgICAgICAgICAgICAgICAgICByb290W1wiSlNPTjNcIl0gPSBwcmV2aW91c0pTT047XG4gICAgICAgICAgICAgICAgICAgIG5hdGl2ZUpTT04gPSBwcmV2aW91c0pTT04gPSBudWxsO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgcmV0dXJuIEpTT04zO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgcm9vdC5KU09OID0ge1xuICAgICAgICAgICAgICAgIFwicGFyc2VcIjogSlNPTjMucGFyc2UsXG4gICAgICAgICAgICAgICAgXCJzdHJpbmdpZnlcIjogSlNPTjMuc3RyaW5naWZ5XG4gICAgICAgICAgICAgIH07XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEV4cG9ydCBmb3IgYXN5bmNocm9ub3VzIG1vZHVsZSBsb2FkZXJzLlxuICAgICAgICAgICAgaWYgKGlzTG9hZGVyKSB7XG4gICAgICAgICAgICAgIGRlZmluZShmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIEpTT04zO1xuICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KS5jYWxsKHRoaXMpO1xuICAgICAgICB9KS5jYWxsKHRoaXMsIHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB0eXBlb2YgZ2xvYmFsICE9PSBcInVuZGVmaW5lZFwiID8gZ2xvYmFsIDoge30pO1xuICAgICAgfSwge31dLCA1MTogW2Z1bmN0aW9uIChfZGVyZXFfLCBtb2R1bGUsIGV4cG9ydHMpIHtcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSB0b0FycmF5O1xuXG4gICAgICAgIGZ1bmN0aW9uIHRvQXJyYXkobGlzdCwgaW5kZXgpIHtcbiAgICAgICAgICB2YXIgYXJyYXkgPSBbXTtcblxuICAgICAgICAgIGluZGV4ID0gaW5kZXggfHwgMDtcblxuICAgICAgICAgIGZvciAodmFyIGkgPSBpbmRleCB8fCAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgYXJyYXlbaSAtIGluZGV4XSA9IGxpc3RbaV07XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgcmV0dXJuIGFycmF5O1xuICAgICAgICB9XG4gICAgICB9LCB7fV0gfSwge30sIFszMV0pKDMxKTtcbiAgfSk7XG59XG5cbmNjLl9SRi5wb3AoKTsiXX0=","deps":{}},"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\9e\\9e146e9e-d85e-4863-b061-aece26cbd6c3.js":{"source":"\"use strict\";\ncc._RF.push(module, '9e1466e2F5IY7Bhrs4my9bD', 'register');\n// script/action/login/register.js\n\n\"use strict\";\n\ncc.Class({\n extends: cc.Component,\n\n properties: {\n // foo: {\n // default: null, // The default value will be used only when the component attaching\n // to a node for the first time\n // url: cc.Texture2D, // optional, default is typeof default\n // serializable: true, // optional, default is true\n // visible: true, // optional, default is true\n // displayName: 'Foo', // optional\n // readonly: false, // optional, default is false\n // },\n // ...\n },\n\n // use this for initialization\n onLoad: function onLoad() {\n var self = this;\n this._login = cc.find(\"Canvas/login\");\n },\n onClick: function onClick() {\n this._login.active = false;\n }\n // called every frame, uncomment this function to activate update callback\n // update: function (dt) {\n\n // },\n});\n\ncc._RF.pop();","deps":{}},"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\fb\\fb977eef-db8f-432a-8f42-bf3d8d970e95.js":{"source":"\"use strict\";\ncc._RF.push(module, 'fb9777v249DKo9Cvz2Nlw6V', 'HTTP');\n// script/lib/HTTP.js\n\n\"use strict\";\n\nvar URL = \"http://127.0.0.1\";\ncc.VERSION = 2017061001;\nvar HTTP = cc.Class({\n extends: cc.Component,\n\n properties: {\n // foo: {\n // default: null, // The default value will be used only when the component attaching\n // to a node for the first time\n // url: cc.Texture2D, // optional, default is typeof default\n // serializable: true, // optional, default is true\n // visible: true, // optional, default is true\n // displayName: 'Foo', // optional\n // readonly: false, // optional, default is false\n // },\n // ...\n },\n\n statics: {\n baseURL: URL,\n authorization: null,\n httpGet: function httpGet(url, callback) {\n var xhr = cc.loader.getXMLHttpRequest();\n\n xhr.onreadystatechange = function () {\n if (xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 300) {\n var respone = xhr.responseText;\n if (callback) {\n callback(respone);\n }\n }\n };\n xhr.open(\"GET\", HTTP.baseURL + url, true);\n if (HTTP.authorization != null) {\n xhr.setRequestHeader(\"authorization\", HTTP.authorization);\n }\n if (cc.sys.isNative) {\n xhr.setRequestHeader(\"Accept-Encoding\", \"gzip,deflate\");\n }\n\n // note: In Internet Explorer, the timeout property may be set only after calling the open()\n // method and before calling the send() method.\n xhr.timeout = 5000; // 5 seconds for timeout\n\n xhr.send();\n },\n encodeFormData: function encodeFormData(data) {\n var pairs = [];\n var regexp = /%20/g;\n\n for (var name in data) {\n var value = data[name].toString();\n var pair = encodeURIComponent(name).replace(regexp, \"+\") + \"=\" + encodeURIComponent(value).replace(regexp, \"+\");\n pairs.push(pair);\n }\n return pairs.join(\"&\");\n },\n httpPost: function httpPost(url, params, callback) {\n var xhr = cc.loader.getXMLHttpRequest();\n\n xhr.onreadystatechange = function () {\n if (xhr.readyState === 4 && xhr.status >= 200 && xhr.status < 300) {\n var respone = xhr.responseText;\n if (callback) {\n callback(respone);\n }\n } else {\n if (callback) {\n callback(-1);\n }\n }\n };\n xhr.open(\"POST\", HTTP.baseURL + url, true);\n if (HTTP.authorization !== null) {\n xhr.setRequestHeader(\"authorization\", HTTP.authorization);\n }\n if (cc.sys.isNative) {\n xhr.setRequestHeader(\"Accept-Encoding\", \"gzip,deflate\");\n }\n xhr.setRequestHeader(\"Content-Type\", \"application/x-www-form-urlencoded\");\n\n // note: In Internet Explorer, the timeout property may be set only after calling the open()\n // method and before calling the send() method.\n xhr.timeout = 5000; // 5 seconds for timeout\n\n xhr.send(HTTP.encodeFormData(params));\n }\n },\n\n // use this for initialization\n onLoad: function onLoad() {}\n\n});\n\ncc._RF.pop();","deps":{}},"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\cb\\cb804921-c57f-4d32-84f3-5ba70007a34b.js":{"source":"\"use strict\";\ncc._RF.push(module, 'cb804khxX9NMoTzW6cAB6NL', 'loading');\n// script/components/loading.js\n\n\"use strict\";\n\ncc.Class({\n extends: cc.Component,\n\n properties: {\n // foo: {\n // default: null, // The default value will be used only when the component attaching\n // to a node for the first time\n // url: cc.Texture2D, // optional, default is typeof default\n // serializable: true, // optional, default is true\n // visible: true, // optional, default is true\n // displayName: 'Foo', // optional\n // readonly: false, // optional, default is false\n // },\n // ...\n _progress: 0.0,\n _splash: null,\n _isLoading: false\n },\n\n // use this for initialization\n onLoad: function onLoad() {\n if (!cc.sys.isNative && cc.sys.isMobile) {\n var canvas = this.node.getComponent(cc.Canvas);\n canvas.fitHeight = true;\n canvas.fitWidth = true;\n }\n this.initMgr();\n this._splash = cc.find(\"Canvas/splash\");\n this._splash.active = true;\n\n cc.tools.audio.playBGM(\"bgMain.mp3\");\n var xhr = cc.tools.http.httpPost(\"/tokens\", { username: 'admin', password: '123456' }, function (ret) {\n cc.tools.http.authorization = ret;\n cc.tools.http.httpGet(\"/tokens\", function (ret) {\n //console.log(ret);\n /**\r\n * 后台交互需要token \r\n **/\n io(\"http://127.0.0.1:9081/bm/system?token=\" + cc.tools.http.authorization);\n });\n });\n },\n start: function start() {\n var self = this;\n var SHOW_TIME = 3000;\n var FADE_TIME = 500;\n if (cc.sys.os != cc.sys.OS_IOS || !cc.sys.isNative) {\n self._splash.active = true;\n } else {\n self._splash.active = false;\n }\n },\n initMgr: function initMgr() {\n cc.tools = {};\n cc.tools.http = require(\"HTTP\");\n\n var Audio = require(\"Audio\");\n cc.tools.audio = new Audio();\n cc.tools.audio.init();\n\n if (cc.sys.isNative) {\n window.io = SocketIO;\n } else {\n window.io = require(\"socket.io\");\n }\n }\n\n});\n\ncc._RF.pop();","deps":{"HTTP":"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\fb\\fb977eef-db8f-432a-8f42-bf3d8d970e95.js","socket.io":"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\c3\\c3362f07-3cd8-4e58-8025-6ae3c744fd20.js","Audio":"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\08\\088657d1-aafb-450b-8525-cc8d95776cca.js"}},"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\08\\088657d1-aafb-450b-8525-cc8d95776cca.js":{"source":"\"use strict\";\ncc._RF.push(module, '08865fRqvtFC4UlzI2Vd2zK', 'Audio');\n// script/lib/Audio.js\n\n\"use strict\";\n\ncc.Class({\n extends: cc.Component,\n\n properties: {\n // foo: {\n // default: null, // The default value will be used only when the component attaching\n // to a node for the first time\n // url: cc.Texture2D, // optional, default is typeof default\n // serializable: true, // optional, default is true\n // visible: true, // optional, default is true\n // displayName: 'Foo', // optional\n // readonly: false, // optional, default is false\n // },\n // ...\n bgVolume: 1.0, // 背景音量\n\n deskVolume: 1.0, // 房间 房间音量\n\n bgAudioID: -1 // 背景 音乐 id\n },\n\n // use this for initialization\n init: function init() {\n var t = cc.sys.localStorage.getItem(\"bgVolume\");\n if (t != null) {\n this.bgVolume = parseFloat(t);\n }\n\n var t = cc.sys.localStorage.getItem(\"deskVolume\");\n\n if (t != null) {\n this.deskVolume = parseFloat(t);\n }\n\n cc.game.on(cc.game.EVENT_HIDE, function () {\n cc.audioEngine.pauseAll();\n });\n cc.game.on(cc.game.EVENT_SHOW, function () {\n cc.audioEngine.resumeAll();\n });\n },\n\n // called every frame, uncomment this function to activate update callback\n // update: function (dt) {\n\n // },\n\n getUrl: function getUrl(url) {\n return cc.url.raw(\"resources/sounds/\" + url);\n },\n\n playBGM: function playBGM(url) {\n var audioUrl = this.getUrl(url);\n if (this.bgAudioID >= 0) {\n cc.audioEngine.stop(this.bgAudioID);\n }\n this.bgAudioID = cc.audioEngine.play(audioUrl, true, this.bgVolume);\n },\n playSFX: function playSFX(url) {\n var audioUrl = this.getUrl(url);\n if (this.sfxVolume > 0) {\n var audioId = cc.audioEngine.play(audioUrl, false, this.deskVolume);\n }\n },\n\n\n setSFXVolume: function setSFXVolume(v) {\n if (this.sfxVolume != v) {\n cc.sys.localStorage.setItem(\"deskVolume\", v);\n this.deskVolume = v;\n }\n },\n\n setBGMVolume: function setBGMVolume(v, force) {\n if (this.bgAudioID >= 0) {\n if (v > 0) {\n cc.audioEngine.resume(this.bgAudioID);\n } else {\n cc.audioEngine.pause(this.bgAudioID);\n }\n }\n if (this.bgVolume != v || force) {\n cc.sys.localStorage.setItem(\"bgVolume\", v);\n this.bgmVolume = v;\n cc.audioEngine.setVolume(this.bgAudioID, v);\n }\n },\n\n pauseAll: function pauseAll() {\n cc.audioEngine.pauseAll();\n },\n\n resumeAll: function resumeAll() {\n cc.audioEngine.resumeAll();\n }\n});\n\ncc._RF.pop();","deps":{}}},"packageCache":{"D:\\wordspace\\program\\beimi\\Client\\beimi\\assets\\script\\action\\login\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\assets\\script\\action\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\assets\\script\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\assets\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\package.json":false,"D:\\wordspace\\program\\beimi\\package.json":false,"D:\\wordspace\\program\\package.json":false,"D:\\wordspace\\package.json":false,"D:\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\assets\\script\\action\\login\\register.js":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\assets\\script\\components\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\assets\\script\\components\\loading.js":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\assets\\script\\lib\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\assets\\script\\lib\\Audio.js":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\assets\\script\\lib\\HTTP.js":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\assets\\script\\lib\\socket.io.js":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\fb\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\08\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\31\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\9e\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\cb\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\31\\31eac1eb-4757-4710-a879-200d307fae6a.js":{"__dirname":"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\31"},"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\9e\\9e146e9e-d85e-4863-b061-aece26cbd6c3.js":{"__dirname":"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\9e"},"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\cb\\cb804921-c57f-4d32-84f3-5ba70007a34b.js":{"__dirname":"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\cb"},"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\fb\\fb977eef-db8f-432a-8f42-bf3d8d970e95.js":{"__dirname":"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\fb"},"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\08\\088657d1-aafb-450b-8525-cc8d95776cca.js":{"__dirname":"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\08"},"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\c3\\package.json":false,"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\c3\\c3362f07-3cd8-4e58-8025-6ae3c744fd20.js":{"__dirname":"D:\\wordspace\\program\\beimi\\Client\\beimi\\library\\imports\\c3"},"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\assets\\script\\action\\login\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\assets\\script\\action\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\assets\\script\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\assets\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\client\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\assets\\script\\action\\login\\register.js":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\assets\\script\\components\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\assets\\script\\components\\loading.js":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\assets\\script\\lib\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\assets\\script\\lib\\Audio.js":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\assets\\script\\lib\\HTTP.js":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\assets\\script\\lib\\socket.io.js":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\cb\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\c3\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\08\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\9e\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\fb\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\package.json":false,"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\08\\088657d1-aafb-450b-8525-cc8d95776cca.js":{"__dirname":"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\08"},"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\cb\\cb804921-c57f-4d32-84f3-5ba70007a34b.js":{"__dirname":"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\cb"},"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\9e\\9e146e9e-d85e-4863-b061-aece26cbd6c3.js":{"__dirname":"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\9e"},"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\fb\\fb977eef-db8f-432a-8f42-bf3d8d970e95.js":{"__dirname":"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\fb"},"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\c3\\c3362f07-3cd8-4e58-8025-6ae3c744fd20.js":{"__dirname":"D:\\wordspace\\program\\beimi\\chess\\client\\beimi\\library\\imports\\c3"}}}}