"use strict"; /* * ATTENTION: An "eval-source-map" devtool has been used. * This devtool is neither made for production nor for readable output files. * It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools. * If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/) * or disable the default devtool with "devtool: false". * If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/). */ exports.id = "vendor-chunks/async"; exports.ids = ["vendor-chunks/async"]; exports.modules = { /***/ "(rsc)/./node_modules/async/dist/async.mjs": /*!*******************************************!*\ !*** ./node_modules/async/dist/async.mjs ***! \*******************************************/ /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ all: () => (/* binding */ every$1),\n/* harmony export */ allLimit: () => (/* binding */ everyLimit$1),\n/* harmony export */ allSeries: () => (/* binding */ everySeries$1),\n/* harmony export */ any: () => (/* binding */ some$1),\n/* harmony export */ anyLimit: () => (/* binding */ someLimit$1),\n/* harmony export */ anySeries: () => (/* binding */ someSeries$1),\n/* harmony export */ apply: () => (/* binding */ apply),\n/* harmony export */ applyEach: () => (/* binding */ applyEach),\n/* harmony export */ applyEachSeries: () => (/* binding */ applyEachSeries),\n/* harmony export */ asyncify: () => (/* binding */ asyncify),\n/* harmony export */ auto: () => (/* binding */ auto),\n/* harmony export */ autoInject: () => (/* binding */ autoInject),\n/* harmony export */ cargo: () => (/* binding */ cargo$1),\n/* harmony export */ cargoQueue: () => (/* binding */ cargo),\n/* harmony export */ compose: () => (/* binding */ compose),\n/* harmony export */ concat: () => (/* binding */ concat$1),\n/* harmony export */ concatLimit: () => (/* binding */ concatLimit$1),\n/* harmony export */ concatSeries: () => (/* binding */ concatSeries$1),\n/* harmony export */ constant: () => (/* binding */ constant$1),\n/* harmony export */ \"default\": () => (/* binding */ index),\n/* harmony export */ detect: () => (/* binding */ detect$1),\n/* harmony export */ detectLimit: () => (/* binding */ detectLimit$1),\n/* harmony export */ detectSeries: () => (/* binding */ detectSeries$1),\n/* harmony export */ dir: () => (/* binding */ dir),\n/* harmony export */ doDuring: () => (/* binding */ doWhilst$1),\n/* harmony export */ doUntil: () => (/* binding */ doUntil),\n/* harmony export */ doWhilst: () => (/* binding */ doWhilst$1),\n/* harmony export */ during: () => (/* binding */ whilst$1),\n/* harmony export */ each: () => (/* binding */ each),\n/* harmony export */ eachLimit: () => (/* binding */ eachLimit$1),\n/* harmony export */ eachOf: () => (/* binding */ eachOf$1),\n/* harmony export */ eachOfLimit: () => (/* binding */ eachOfLimit$1),\n/* harmony export */ eachOfSeries: () => (/* binding */ eachOfSeries$1),\n/* harmony export */ eachSeries: () => (/* binding */ eachSeries$1),\n/* harmony export */ ensureAsync: () => (/* binding */ ensureAsync),\n/* harmony export */ every: () => (/* binding */ every$1),\n/* harmony export */ everyLimit: () => (/* binding */ everyLimit$1),\n/* harmony export */ everySeries: () => (/* binding */ everySeries$1),\n/* harmony export */ filter: () => (/* binding */ filter$1),\n/* harmony export */ filterLimit: () => (/* binding */ filterLimit$1),\n/* harmony export */ filterSeries: () => (/* binding */ filterSeries$1),\n/* harmony export */ find: () => (/* binding */ detect$1),\n/* harmony export */ findLimit: () => (/* binding */ detectLimit$1),\n/* harmony export */ findSeries: () => (/* binding */ detectSeries$1),\n/* harmony export */ flatMap: () => (/* binding */ concat$1),\n/* harmony export */ flatMapLimit: () => (/* binding */ concatLimit$1),\n/* harmony export */ flatMapSeries: () => (/* binding */ concatSeries$1),\n/* harmony export */ foldl: () => (/* binding */ reduce$1),\n/* harmony export */ foldr: () => (/* binding */ reduceRight),\n/* harmony export */ forEach: () => (/* binding */ each),\n/* harmony export */ forEachLimit: () => (/* binding */ eachLimit$1),\n/* harmony export */ forEachOf: () => (/* binding */ eachOf$1),\n/* harmony export */ forEachOfLimit: () => (/* binding */ eachOfLimit$1),\n/* harmony export */ forEachOfSeries: () => (/* binding */ eachOfSeries$1),\n/* harmony export */ forEachSeries: () => (/* binding */ eachSeries$1),\n/* harmony export */ forever: () => (/* binding */ forever$1),\n/* harmony export */ groupBy: () => (/* binding */ groupBy),\n/* harmony export */ groupByLimit: () => (/* binding */ groupByLimit$1),\n/* harmony export */ groupBySeries: () => (/* binding */ groupBySeries),\n/* harmony export */ inject: () => (/* binding */ reduce$1),\n/* harmony export */ log: () => (/* binding */ log),\n/* harmony export */ map: () => (/* binding */ map$1),\n/* harmony export */ mapLimit: () => (/* binding */ mapLimit$1),\n/* harmony export */ mapSeries: () => (/* binding */ mapSeries$1),\n/* harmony export */ mapValues: () => (/* binding */ mapValues),\n/* harmony export */ mapValuesLimit: () => (/* binding */ mapValuesLimit$1),\n/* harmony export */ mapValuesSeries: () => (/* binding */ mapValuesSeries),\n/* harmony export */ memoize: () => (/* binding */ memoize),\n/* harmony export */ nextTick: () => (/* binding */ nextTick),\n/* harmony export */ parallel: () => (/* binding */ parallel),\n/* harmony export */ parallelLimit: () => (/* binding */ parallelLimit),\n/* harmony export */ priorityQueue: () => (/* binding */ priorityQueue),\n/* harmony export */ queue: () => (/* binding */ queue),\n/* harmony export */ race: () => (/* binding */ race$1),\n/* harmony export */ reduce: () => (/* binding */ reduce$1),\n/* harmony export */ reduceRight: () => (/* binding */ reduceRight),\n/* harmony export */ reflect: () => (/* binding */ reflect),\n/* harmony export */ reflectAll: () => (/* binding */ reflectAll),\n/* harmony export */ reject: () => (/* binding */ reject$1),\n/* harmony export */ rejectLimit: () => (/* binding */ rejectLimit$1),\n/* harmony export */ rejectSeries: () => (/* binding */ rejectSeries$1),\n/* harmony export */ retry: () => (/* binding */ retry),\n/* harmony export */ retryable: () => (/* binding */ retryable),\n/* harmony export */ select: () => (/* binding */ filter$1),\n/* harmony export */ selectLimit: () => (/* binding */ filterLimit$1),\n/* harmony export */ selectSeries: () => (/* binding */ filterSeries$1),\n/* harmony export */ seq: () => (/* binding */ seq),\n/* harmony export */ series: () => (/* binding */ series),\n/* harmony export */ setImmediate: () => (/* binding */ setImmediate$1),\n/* harmony export */ some: () => (/* binding */ some$1),\n/* harmony export */ someLimit: () => (/* binding */ someLimit$1),\n/* harmony export */ someSeries: () => (/* binding */ someSeries$1),\n/* harmony export */ sortBy: () => (/* binding */ sortBy$1),\n/* harmony export */ timeout: () => (/* binding */ timeout),\n/* harmony export */ times: () => (/* binding */ times),\n/* harmony export */ timesLimit: () => (/* binding */ timesLimit),\n/* harmony export */ timesSeries: () => (/* binding */ timesSeries),\n/* harmony export */ transform: () => (/* binding */ transform),\n/* harmony export */ tryEach: () => (/* binding */ tryEach$1),\n/* harmony export */ unmemoize: () => (/* binding */ unmemoize),\n/* harmony export */ until: () => (/* binding */ until),\n/* harmony export */ waterfall: () => (/* binding */ waterfall$1),\n/* harmony export */ whilst: () => (/* binding */ whilst$1),\n/* harmony export */ wrapSync: () => (/* binding */ asyncify)\n/* harmony export */ });\n/**\n * Creates a continuation function with some arguments already applied.\n *\n * Useful as a shorthand when combined with other control flow functions. Any\n * arguments passed to the returned function are added to the arguments\n * originally passed to apply.\n *\n * @name apply\n * @static\n * @memberOf module:Utils\n * @method\n * @category Util\n * @param {Function} fn - The function you want to eventually apply all\n * arguments to. Invokes with (arguments...).\n * @param {...*} arguments... - Any number of arguments to automatically apply\n * when the continuation is called.\n * @returns {Function} the partially-applied function\n * @example\n *\n * // using apply\n * async.parallel([\n * async.apply(fs.writeFile, 'testfile1', 'test1'),\n * async.apply(fs.writeFile, 'testfile2', 'test2')\n * ]);\n *\n *\n * // the same process without using apply\n * async.parallel([\n * function(callback) {\n * fs.writeFile('testfile1', 'test1', callback);\n * },\n * function(callback) {\n * fs.writeFile('testfile2', 'test2', callback);\n * }\n * ]);\n *\n * // It's possible to pass any number of additional arguments when calling the\n * // continuation:\n *\n * node> var fn = async.apply(sys.puts, 'one');\n * node> fn('two', 'three');\n * one\n * two\n * three\n */\nfunction apply(fn, ...args) {\n return (...callArgs) => fn(...args,...callArgs);\n}\n\nfunction initialParams (fn) {\n return function (...args/*, callback*/) {\n var callback = args.pop();\n return fn.call(this, args, callback);\n };\n}\n\n/* istanbul ignore file */\n\nvar hasQueueMicrotask = typeof queueMicrotask === 'function' && queueMicrotask;\nvar hasSetImmediate = typeof setImmediate === 'function' && setImmediate;\nvar hasNextTick = typeof process === 'object' && typeof process.nextTick === 'function';\n\nfunction fallback(fn) {\n setTimeout(fn, 0);\n}\n\nfunction wrap(defer) {\n return (fn, ...args) => defer(() => fn(...args));\n}\n\nvar _defer$1;\n\nif (hasQueueMicrotask) {\n _defer$1 = queueMicrotask;\n} else if (hasSetImmediate) {\n _defer$1 = setImmediate;\n} else if (hasNextTick) {\n _defer$1 = process.nextTick;\n} else {\n _defer$1 = fallback;\n}\n\nvar setImmediate$1 = wrap(_defer$1);\n\n/**\n * Take a sync function and make it async, passing its return value to a\n * callback. This is useful for plugging sync functions into a waterfall,\n * series, or other async functions. Any arguments passed to the generated\n * function will be passed to the wrapped function (except for the final\n * callback argument). Errors thrown will be passed to the callback.\n *\n * If the function passed to `asyncify` returns a Promise, that promises's\n * resolved/rejected state will be used to call the callback, rather than simply\n * the synchronous return value.\n *\n * This also means you can asyncify ES2017 `async` functions.\n *\n * @name asyncify\n * @static\n * @memberOf module:Utils\n * @method\n * @alias wrapSync\n * @category Util\n * @param {Function} func - The synchronous function, or Promise-returning\n * function to convert to an {@link AsyncFunction}.\n * @returns {AsyncFunction} An asynchronous wrapper of the `func`. To be\n * invoked with `(args..., callback)`.\n * @example\n *\n * // passing a regular synchronous function\n * async.waterfall([\n * async.apply(fs.readFile, filename, \"utf8\"),\n * async.asyncify(JSON.parse),\n * function (data, next) {\n * // data is the result of parsing the text.\n * // If there was a parsing error, it would have been caught.\n * }\n * ], callback);\n *\n * // passing a function returning a promise\n * async.waterfall([\n * async.apply(fs.readFile, filename, \"utf8\"),\n * async.asyncify(function (contents) {\n * return db.model.create(contents);\n * }),\n * function (model, next) {\n * // `model` is the instantiated model object.\n * // If there was an error, this function would be skipped.\n * }\n * ], callback);\n *\n * // es2017 example, though `asyncify` is not needed if your JS environment\n * // supports async functions out of the box\n * var q = async.queue(async.asyncify(async function(file) {\n * var intermediateStep = await processFile(file);\n * return await somePromise(intermediateStep)\n * }));\n *\n * q.push(files);\n */\nfunction asyncify(func) {\n if (isAsync(func)) {\n return function (...args/*, callback*/) {\n const callback = args.pop();\n const promise = func.apply(this, args);\n return handlePromise(promise, callback)\n }\n }\n\n return initialParams(function (args, callback) {\n var result;\n try {\n result = func.apply(this, args);\n } catch (e) {\n return callback(e);\n }\n // if result is Promise object\n if (result && typeof result.then === 'function') {\n return handlePromise(result, callback)\n } else {\n callback(null, result);\n }\n });\n}\n\nfunction handlePromise(promise, callback) {\n return promise.then(value => {\n invokeCallback(callback, null, value);\n }, err => {\n invokeCallback(callback, err && (err instanceof Error || err.message) ? err : new Error(err));\n });\n}\n\nfunction invokeCallback(callback, error, value) {\n try {\n callback(error, value);\n } catch (err) {\n setImmediate$1(e => { throw e }, err);\n }\n}\n\nfunction isAsync(fn) {\n return fn[Symbol.toStringTag] === 'AsyncFunction';\n}\n\nfunction isAsyncGenerator(fn) {\n return fn[Symbol.toStringTag] === 'AsyncGenerator';\n}\n\nfunction isAsyncIterable(obj) {\n return typeof obj[Symbol.asyncIterator] === 'function';\n}\n\nfunction wrapAsync(asyncFn) {\n if (typeof asyncFn !== 'function') throw new Error('expected a function')\n return isAsync(asyncFn) ? asyncify(asyncFn) : asyncFn;\n}\n\n// conditionally promisify a function.\n// only return a promise if a callback is omitted\nfunction awaitify (asyncFn, arity) {\n if (!arity) arity = asyncFn.length;\n if (!arity) throw new Error('arity is undefined')\n function awaitable (...args) {\n if (typeof args[arity - 1] === 'function') {\n return asyncFn.apply(this, args)\n }\n\n return new Promise((resolve, reject) => {\n args[arity - 1] = (err, ...cbArgs) => {\n if (err) return reject(err)\n resolve(cbArgs.length > 1 ? cbArgs : cbArgs[0]);\n };\n asyncFn.apply(this, args);\n })\n }\n\n return awaitable\n}\n\nfunction applyEach$1 (eachfn) {\n return function applyEach(fns, ...callArgs) {\n const go = awaitify(function (callback) {\n var that = this;\n return eachfn(fns, (fn, cb) => {\n wrapAsync(fn).apply(that, callArgs.concat(cb));\n }, callback);\n });\n return go;\n };\n}\n\nfunction _asyncMap(eachfn, arr, iteratee, callback) {\n arr = arr || [];\n var results = [];\n var counter = 0;\n var _iteratee = wrapAsync(iteratee);\n\n return eachfn(arr, (value, _, iterCb) => {\n var index = counter++;\n _iteratee(value, (err, v) => {\n results[index] = v;\n iterCb(err);\n });\n }, err => {\n callback(err, results);\n });\n}\n\nfunction isArrayLike(value) {\n return value &&\n typeof value.length === 'number' &&\n value.length >= 0 &&\n value.length % 1 === 0;\n}\n\n// A temporary value used to identify if the loop should be broken.\n// See #1064, #1293\nconst breakLoop = {};\n\nfunction once(fn) {\n function wrapper (...args) {\n if (fn === null) return;\n var callFn = fn;\n fn = null;\n callFn.apply(this, args);\n }\n Object.assign(wrapper, fn);\n return wrapper\n}\n\nfunction getIterator (coll) {\n return coll[Symbol.iterator] && coll[Symbol.iterator]();\n}\n\nfunction createArrayIterator(coll) {\n var i = -1;\n var len = coll.length;\n return function next() {\n return ++i < len ? {value: coll[i], key: i} : null;\n }\n}\n\nfunction createES2015Iterator(iterator) {\n var i = -1;\n return function next() {\n var item = iterator.next();\n if (item.done)\n return null;\n i++;\n return {value: item.value, key: i};\n }\n}\n\nfunction createObjectIterator(obj) {\n var okeys = obj ? Object.keys(obj) : [];\n var i = -1;\n var len = okeys.length;\n return function next() {\n var key = okeys[++i];\n if (key === '__proto__') {\n return next();\n }\n return i < len ? {value: obj[key], key} : null;\n };\n}\n\nfunction createIterator(coll) {\n if (isArrayLike(coll)) {\n return createArrayIterator(coll);\n }\n\n var iterator = getIterator(coll);\n return iterator ? createES2015Iterator(iterator) : createObjectIterator(coll);\n}\n\nfunction onlyOnce(fn) {\n return function (...args) {\n if (fn === null) throw new Error(\"Callback was already called.\");\n var callFn = fn;\n fn = null;\n callFn.apply(this, args);\n };\n}\n\n// for async generators\nfunction asyncEachOfLimit(generator, limit, iteratee, callback) {\n let done = false;\n let canceled = false;\n let awaiting = false;\n let running = 0;\n let idx = 0;\n\n function replenish() {\n //console.log('replenish')\n if (running >= limit || awaiting || done) return\n //console.log('replenish awaiting')\n awaiting = true;\n generator.next().then(({value, done: iterDone}) => {\n //console.log('got value', value)\n if (canceled || done) return\n awaiting = false;\n if (iterDone) {\n done = true;\n if (running <= 0) {\n //console.log('done nextCb')\n callback(null);\n }\n return;\n }\n running++;\n iteratee(value, idx, iterateeCallback);\n idx++;\n replenish();\n }).catch(handleError);\n }\n\n function iterateeCallback(err, result) {\n //console.log('iterateeCallback')\n running -= 1;\n if (canceled) return\n if (err) return handleError(err)\n\n if (err === false) {\n done = true;\n canceled = true;\n return\n }\n\n if (result === breakLoop || (done && running <= 0)) {\n done = true;\n //console.log('done iterCb')\n return callback(null);\n }\n replenish();\n }\n\n function handleError(err) {\n if (canceled) return\n awaiting = false;\n done = true;\n callback(err);\n }\n\n replenish();\n}\n\nvar eachOfLimit$2 = (limit) => {\n return (obj, iteratee, callback) => {\n callback = once(callback);\n if (limit <= 0) {\n throw new RangeError('concurrency limit cannot be less than 1')\n }\n if (!obj) {\n return callback(null);\n }\n if (isAsyncGenerator(obj)) {\n return asyncEachOfLimit(obj, limit, iteratee, callback)\n }\n if (isAsyncIterable(obj)) {\n return asyncEachOfLimit(obj[Symbol.asyncIterator](), limit, iteratee, callback)\n }\n var nextElem = createIterator(obj);\n var done = false;\n var canceled = false;\n var running = 0;\n var looping = false;\n\n function iterateeCallback(err, value) {\n if (canceled) return\n running -= 1;\n if (err) {\n done = true;\n callback(err);\n }\n else if (err === false) {\n done = true;\n canceled = true;\n }\n else if (value === breakLoop || (done && running <= 0)) {\n done = true;\n return callback(null);\n }\n else if (!looping) {\n replenish();\n }\n }\n\n function replenish () {\n looping = true;\n while (running < limit && !done) {\n var elem = nextElem();\n if (elem === null) {\n done = true;\n if (running <= 0) {\n callback(null);\n }\n return;\n }\n running += 1;\n iteratee(elem.value, elem.key, onlyOnce(iterateeCallback));\n }\n looping = false;\n }\n\n replenish();\n };\n};\n\n/**\n * The same as [`eachOf`]{@link module:Collections.eachOf} but runs a maximum of `limit` async operations at a\n * time.\n *\n * @name eachOfLimit\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.eachOf]{@link module:Collections.eachOf}\n * @alias forEachOfLimit\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {number} limit - The maximum number of async operations at a time.\n * @param {AsyncFunction} iteratee - An async function to apply to each\n * item in `coll`. The `key` is the item's key, or index in the case of an\n * array.\n * Invoked with (item, key, callback).\n * @param {Function} [callback] - A callback which is called when all\n * `iteratee` functions have finished, or an error occurs. Invoked with (err).\n * @returns {Promise} a promise, if a callback is omitted\n */\nfunction eachOfLimit(coll, limit, iteratee, callback) {\n return eachOfLimit$2(limit)(coll, wrapAsync(iteratee), callback);\n}\n\nvar eachOfLimit$1 = awaitify(eachOfLimit, 4);\n\n// eachOf implementation optimized for array-likes\nfunction eachOfArrayLike(coll, iteratee, callback) {\n callback = once(callback);\n var index = 0,\n completed = 0,\n {length} = coll,\n canceled = false;\n if (length === 0) {\n callback(null);\n }\n\n function iteratorCallback(err, value) {\n if (err === false) {\n canceled = true;\n }\n if (canceled === true) return\n if (err) {\n callback(err);\n } else if ((++completed === length) || value === breakLoop) {\n callback(null);\n }\n }\n\n for (; index < length; index++) {\n iteratee(coll[index], index, onlyOnce(iteratorCallback));\n }\n}\n\n// a generic version of eachOf which can handle array, object, and iterator cases.\nfunction eachOfGeneric (coll, iteratee, callback) {\n return eachOfLimit$1(coll, Infinity, iteratee, callback);\n}\n\n/**\n * Like [`each`]{@link module:Collections.each}, except that it passes the key (or index) as the second argument\n * to the iteratee.\n *\n * @name eachOf\n * @static\n * @memberOf module:Collections\n * @method\n * @alias forEachOf\n * @category Collection\n * @see [async.each]{@link module:Collections.each}\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - A function to apply to each\n * item in `coll`.\n * The `key` is the item's key, or index in the case of an array.\n * Invoked with (item, key, callback).\n * @param {Function} [callback] - A callback which is called when all\n * `iteratee` functions have finished, or an error occurs. Invoked with (err).\n * @returns {Promise} a promise, if a callback is omitted\n * @example\n *\n * // dev.json is a file containing a valid json object config for dev environment\n * // dev.json is a file containing a valid json object config for test environment\n * // prod.json is a file containing a valid json object config for prod environment\n * // invalid.json is a file with a malformed json object\n *\n * let configs = {}; //global variable\n * let validConfigFileMap = {dev: 'dev.json', test: 'test.json', prod: 'prod.json'};\n * let invalidConfigFileMap = {dev: 'dev.json', test: 'test.json', invalid: 'invalid.json'};\n *\n * // asynchronous function that reads a json file and parses the contents as json object\n * function parseFile(file, key, callback) {\n * fs.readFile(file, \"utf8\", function(err, data) {\n * if (err) return calback(err);\n * try {\n * configs[key] = JSON.parse(data);\n * } catch (e) {\n * return callback(e);\n * }\n * callback();\n * });\n * }\n *\n * // Using callbacks\n * async.forEachOf(validConfigFileMap, parseFile, function (err) {\n * if (err) {\n * console.error(err);\n * } else {\n * console.log(configs);\n * // configs is now a map of JSON data, e.g.\n * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}\n * }\n * });\n *\n * //Error handing\n * async.forEachOf(invalidConfigFileMap, parseFile, function (err) {\n * if (err) {\n * console.error(err);\n * // JSON parse error exception\n * } else {\n * console.log(configs);\n * }\n * });\n *\n * // Using Promises\n * async.forEachOf(validConfigFileMap, parseFile)\n * .then( () => {\n * console.log(configs);\n * // configs is now a map of JSON data, e.g.\n * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}\n * }).catch( err => {\n * console.error(err);\n * });\n *\n * //Error handing\n * async.forEachOf(invalidConfigFileMap, parseFile)\n * .then( () => {\n * console.log(configs);\n * }).catch( err => {\n * console.error(err);\n * // JSON parse error exception\n * });\n *\n * // Using async/await\n * async () => {\n * try {\n * let result = await async.forEachOf(validConfigFileMap, parseFile);\n * console.log(configs);\n * // configs is now a map of JSON data, e.g.\n * // { dev: //parsed dev.json, test: //parsed test.json, prod: //parsed prod.json}\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n * //Error handing\n * async () => {\n * try {\n * let result = await async.forEachOf(invalidConfigFileMap, parseFile);\n * console.log(configs);\n * }\n * catch (err) {\n * console.log(err);\n * // JSON parse error exception\n * }\n * }\n *\n */\nfunction eachOf(coll, iteratee, callback) {\n var eachOfImplementation = isArrayLike(coll) ? eachOfArrayLike : eachOfGeneric;\n return eachOfImplementation(coll, wrapAsync(iteratee), callback);\n}\n\nvar eachOf$1 = awaitify(eachOf, 3);\n\n/**\n * Produces a new collection of values by mapping each value in `coll` through\n * the `iteratee` function. The `iteratee` is called with an item from `coll`\n * and a callback for when it has finished processing. Each of these callbacks\n * takes 2 arguments: an `error`, and the transformed item from `coll`. If\n * `iteratee` passes an error to its callback, the main `callback` (for the\n * `map` function) is immediately called with the error.\n *\n * Note, that since this function applies the `iteratee` to each item in\n * parallel, there is no guarantee that the `iteratee` functions will complete\n * in order. However, the results array will be in the same order as the\n * original `coll`.\n *\n * If `map` is passed an Object, the results will be an Array. The results\n * will roughly be in the order of the original Objects' keys (but this can\n * vary across JavaScript engines).\n *\n * @name map\n * @static\n * @memberOf module:Collections\n * @method\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - An async function to apply to each item in\n * `coll`.\n * The iteratee should complete with the transformed item.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called when all `iteratee`\n * functions have finished, or an error occurs. Results is an Array of the\n * transformed items from the `coll`. Invoked with (err, results).\n * @returns {Promise} a promise, if no callback is passed\n * @example\n *\n * // file1.txt is a file that is 1000 bytes in size\n * // file2.txt is a file that is 2000 bytes in size\n * // file3.txt is a file that is 3000 bytes in size\n * // file4.txt does not exist\n *\n * const fileList = ['file1.txt','file2.txt','file3.txt'];\n * const withMissingFileList = ['file1.txt','file2.txt','file4.txt'];\n *\n * // asynchronous function that returns the file size in bytes\n * function getFileSizeInBytes(file, callback) {\n * fs.stat(file, function(err, stat) {\n * if (err) {\n * return callback(err);\n * }\n * callback(null, stat.size);\n * });\n * }\n *\n * // Using callbacks\n * async.map(fileList, getFileSizeInBytes, function(err, results) {\n * if (err) {\n * console.log(err);\n * } else {\n * console.log(results);\n * // results is now an array of the file size in bytes for each file, e.g.\n * // [ 1000, 2000, 3000]\n * }\n * });\n *\n * // Error Handling\n * async.map(withMissingFileList, getFileSizeInBytes, function(err, results) {\n * if (err) {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * } else {\n * console.log(results);\n * }\n * });\n *\n * // Using Promises\n * async.map(fileList, getFileSizeInBytes)\n * .then( results => {\n * console.log(results);\n * // results is now an array of the file size in bytes for each file, e.g.\n * // [ 1000, 2000, 3000]\n * }).catch( err => {\n * console.log(err);\n * });\n *\n * // Error Handling\n * async.map(withMissingFileList, getFileSizeInBytes)\n * .then( results => {\n * console.log(results);\n * }).catch( err => {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * });\n *\n * // Using async/await\n * async () => {\n * try {\n * let results = await async.map(fileList, getFileSizeInBytes);\n * console.log(results);\n * // results is now an array of the file size in bytes for each file, e.g.\n * // [ 1000, 2000, 3000]\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n * // Error Handling\n * async () => {\n * try {\n * let results = await async.map(withMissingFileList, getFileSizeInBytes);\n * console.log(results);\n * }\n * catch (err) {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * }\n * }\n *\n */\nfunction map (coll, iteratee, callback) {\n return _asyncMap(eachOf$1, coll, iteratee, callback)\n}\nvar map$1 = awaitify(map, 3);\n\n/**\n * Applies the provided arguments to each function in the array, calling\n * `callback` after all functions have completed. If you only provide the first\n * argument, `fns`, then it will return a function which lets you pass in the\n * arguments as if it were a single function call. If more arguments are\n * provided, `callback` is required while `args` is still optional. The results\n * for each of the applied async functions are passed to the final callback\n * as an array.\n *\n * @name applyEach\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @category Control Flow\n * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s\n * to all call with the same arguments\n * @param {...*} [args] - any number of separate arguments to pass to the\n * function.\n * @param {Function} [callback] - the final argument should be the callback,\n * called when all functions have completed processing.\n * @returns {AsyncFunction} - Returns a function that takes no args other than\n * an optional callback, that is the result of applying the `args` to each\n * of the functions.\n * @example\n *\n * const appliedFn = async.applyEach([enableSearch, updateSchema], 'bucket')\n *\n * appliedFn((err, results) => {\n * // results[0] is the results for `enableSearch`\n * // results[1] is the results for `updateSchema`\n * });\n *\n * // partial application example:\n * async.each(\n * buckets,\n * async (bucket) => async.applyEach([enableSearch, updateSchema], bucket)(),\n * callback\n * );\n */\nvar applyEach = applyEach$1(map$1);\n\n/**\n * The same as [`eachOf`]{@link module:Collections.eachOf} but runs only a single async operation at a time.\n *\n * @name eachOfSeries\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.eachOf]{@link module:Collections.eachOf}\n * @alias forEachOfSeries\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - An async function to apply to each item in\n * `coll`.\n * Invoked with (item, key, callback).\n * @param {Function} [callback] - A callback which is called when all `iteratee`\n * functions have finished, or an error occurs. Invoked with (err).\n * @returns {Promise} a promise, if a callback is omitted\n */\nfunction eachOfSeries(coll, iteratee, callback) {\n return eachOfLimit$1(coll, 1, iteratee, callback)\n}\nvar eachOfSeries$1 = awaitify(eachOfSeries, 3);\n\n/**\n * The same as [`map`]{@link module:Collections.map} but runs only a single async operation at a time.\n *\n * @name mapSeries\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.map]{@link module:Collections.map}\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - An async function to apply to each item in\n * `coll`.\n * The iteratee should complete with the transformed item.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called when all `iteratee`\n * functions have finished, or an error occurs. Results is an array of the\n * transformed items from the `coll`. Invoked with (err, results).\n * @returns {Promise} a promise, if no callback is passed\n */\nfunction mapSeries (coll, iteratee, callback) {\n return _asyncMap(eachOfSeries$1, coll, iteratee, callback)\n}\nvar mapSeries$1 = awaitify(mapSeries, 3);\n\n/**\n * The same as [`applyEach`]{@link module:ControlFlow.applyEach} but runs only a single async operation at a time.\n *\n * @name applyEachSeries\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @see [async.applyEach]{@link module:ControlFlow.applyEach}\n * @category Control Flow\n * @param {Array|Iterable|AsyncIterable|Object} fns - A collection of {@link AsyncFunction}s to all\n * call with the same arguments\n * @param {...*} [args] - any number of separate arguments to pass to the\n * function.\n * @param {Function} [callback] - the final argument should be the callback,\n * called when all functions have completed processing.\n * @returns {AsyncFunction} - A function, that when called, is the result of\n * appling the `args` to the list of functions. It takes no args, other than\n * a callback.\n */\nvar applyEachSeries = applyEach$1(mapSeries$1);\n\nconst PROMISE_SYMBOL = Symbol('promiseCallback');\n\nfunction promiseCallback () {\n let resolve, reject;\n function callback (err, ...args) {\n if (err) return reject(err)\n resolve(args.length > 1 ? args : args[0]);\n }\n\n callback[PROMISE_SYMBOL] = new Promise((res, rej) => {\n resolve = res,\n reject = rej;\n });\n\n return callback\n}\n\n/**\n * Determines the best order for running the {@link AsyncFunction}s in `tasks`, based on\n * their requirements. Each function can optionally depend on other functions\n * being completed first, and each function is run as soon as its requirements\n * are satisfied.\n *\n * If any of the {@link AsyncFunction}s pass an error to their callback, the `auto` sequence\n * will stop. Further tasks will not execute (so any other functions depending\n * on it will not run), and the main `callback` is immediately called with the\n * error.\n *\n * {@link AsyncFunction}s also receive an object containing the results of functions which\n * have completed so far as the first argument, if they have dependencies. If a\n * task function has no dependencies, it will only be passed a callback.\n *\n * @name auto\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @category Control Flow\n * @param {Object} tasks - An object. Each of its properties is either a\n * function or an array of requirements, with the {@link AsyncFunction} itself the last item\n * in the array. The object's key of a property serves as the name of the task\n * defined by that property, i.e. can be used when specifying requirements for\n * other tasks. The function receives one or two arguments:\n * * a `results` object, containing the results of the previously executed\n * functions, only passed if the task has any dependencies,\n * * a `callback(err, result)` function, which must be called when finished,\n * passing an `error` (which can be `null`) and the result of the function's\n * execution.\n * @param {number} [concurrency=Infinity] - An optional `integer` for\n * determining the maximum number of tasks that can be run in parallel. By\n * default, as many as possible.\n * @param {Function} [callback] - An optional callback which is called when all\n * the tasks have been completed. It receives the `err` argument if any `tasks`\n * pass an error to their callback. Results are always returned; however, if an\n * error occurs, no further `tasks` will be performed, and the results object\n * will only contain partial results. Invoked with (err, results).\n * @returns {Promise} a promise, if a callback is not passed\n * @example\n *\n * //Using Callbacks\n * async.auto({\n * get_data: function(callback) {\n * // async code to get some data\n * callback(null, 'data', 'converted to array');\n * },\n * make_folder: function(callback) {\n * // async code to create a directory to store a file in\n * // this is run at the same time as getting the data\n * callback(null, 'folder');\n * },\n * write_file: ['get_data', 'make_folder', function(results, callback) {\n * // once there is some data and the directory exists,\n * // write the data to a file in the directory\n * callback(null, 'filename');\n * }],\n * email_link: ['write_file', function(results, callback) {\n * // once the file is written let's email a link to it...\n * callback(null, {'file':results.write_file, 'email':'user@example.com'});\n * }]\n * }, function(err, results) {\n * if (err) {\n * console.log('err = ', err);\n * }\n * console.log('results = ', results);\n * // results = {\n * // get_data: ['data', 'converted to array']\n * // make_folder; 'folder',\n * // write_file: 'filename'\n * // email_link: { file: 'filename', email: 'user@example.com' }\n * // }\n * });\n *\n * //Using Promises\n * async.auto({\n * get_data: function(callback) {\n * console.log('in get_data');\n * // async code to get some data\n * callback(null, 'data', 'converted to array');\n * },\n * make_folder: function(callback) {\n * console.log('in make_folder');\n * // async code to create a directory to store a file in\n * // this is run at the same time as getting the data\n * callback(null, 'folder');\n * },\n * write_file: ['get_data', 'make_folder', function(results, callback) {\n * // once there is some data and the directory exists,\n * // write the data to a file in the directory\n * callback(null, 'filename');\n * }],\n * email_link: ['write_file', function(results, callback) {\n * // once the file is written let's email a link to it...\n * callback(null, {'file':results.write_file, 'email':'user@example.com'});\n * }]\n * }).then(results => {\n * console.log('results = ', results);\n * // results = {\n * // get_data: ['data', 'converted to array']\n * // make_folder; 'folder',\n * // write_file: 'filename'\n * // email_link: { file: 'filename', email: 'user@example.com' }\n * // }\n * }).catch(err => {\n * console.log('err = ', err);\n * });\n *\n * //Using async/await\n * async () => {\n * try {\n * let results = await async.auto({\n * get_data: function(callback) {\n * // async code to get some data\n * callback(null, 'data', 'converted to array');\n * },\n * make_folder: function(callback) {\n * // async code to create a directory to store a file in\n * // this is run at the same time as getting the data\n * callback(null, 'folder');\n * },\n * write_file: ['get_data', 'make_folder', function(results, callback) {\n * // once there is some data and the directory exists,\n * // write the data to a file in the directory\n * callback(null, 'filename');\n * }],\n * email_link: ['write_file', function(results, callback) {\n * // once the file is written let's email a link to it...\n * callback(null, {'file':results.write_file, 'email':'user@example.com'});\n * }]\n * });\n * console.log('results = ', results);\n * // results = {\n * // get_data: ['data', 'converted to array']\n * // make_folder; 'folder',\n * // write_file: 'filename'\n * // email_link: { file: 'filename', email: 'user@example.com' }\n * // }\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n */\nfunction auto(tasks, concurrency, callback) {\n if (typeof concurrency !== 'number') {\n // concurrency is optional, shift the args.\n callback = concurrency;\n concurrency = null;\n }\n callback = once(callback || promiseCallback());\n var numTasks = Object.keys(tasks).length;\n if (!numTasks) {\n return callback(null);\n }\n if (!concurrency) {\n concurrency = numTasks;\n }\n\n var results = {};\n var runningTasks = 0;\n var canceled = false;\n var hasError = false;\n\n var listeners = Object.create(null);\n\n var readyTasks = [];\n\n // for cycle detection:\n var readyToCheck = []; // tasks that have been identified as reachable\n // without the possibility of returning to an ancestor task\n var uncheckedDependencies = {};\n\n Object.keys(tasks).forEach(key => {\n var task = tasks[key];\n if (!Array.isArray(task)) {\n // no dependencies\n enqueueTask(key, [task]);\n readyToCheck.push(key);\n return;\n }\n\n var dependencies = task.slice(0, task.length - 1);\n var remainingDependencies = dependencies.length;\n if (remainingDependencies === 0) {\n enqueueTask(key, task);\n readyToCheck.push(key);\n return;\n }\n uncheckedDependencies[key] = remainingDependencies;\n\n dependencies.forEach(dependencyName => {\n if (!tasks[dependencyName]) {\n throw new Error('async.auto task `' + key +\n '` has a non-existent dependency `' +\n dependencyName + '` in ' +\n dependencies.join(', '));\n }\n addListener(dependencyName, () => {\n remainingDependencies--;\n if (remainingDependencies === 0) {\n enqueueTask(key, task);\n }\n });\n });\n });\n\n checkForDeadlocks();\n processQueue();\n\n function enqueueTask(key, task) {\n readyTasks.push(() => runTask(key, task));\n }\n\n function processQueue() {\n if (canceled) return\n if (readyTasks.length === 0 && runningTasks === 0) {\n return callback(null, results);\n }\n while(readyTasks.length && runningTasks < concurrency) {\n var run = readyTasks.shift();\n run();\n }\n\n }\n\n function addListener(taskName, fn) {\n var taskListeners = listeners[taskName];\n if (!taskListeners) {\n taskListeners = listeners[taskName] = [];\n }\n\n taskListeners.push(fn);\n }\n\n function taskComplete(taskName) {\n var taskListeners = listeners[taskName] || [];\n taskListeners.forEach(fn => fn());\n processQueue();\n }\n\n\n function runTask(key, task) {\n if (hasError) return;\n\n var taskCallback = onlyOnce((err, ...result) => {\n runningTasks--;\n if (err === false) {\n canceled = true;\n return\n }\n if (result.length < 2) {\n [result] = result;\n }\n if (err) {\n var safeResults = {};\n Object.keys(results).forEach(rkey => {\n safeResults[rkey] = results[rkey];\n });\n safeResults[key] = result;\n hasError = true;\n listeners = Object.create(null);\n if (canceled) return\n callback(err, safeResults);\n } else {\n results[key] = result;\n taskComplete(key);\n }\n });\n\n runningTasks++;\n var taskFn = wrapAsync(task[task.length - 1]);\n if (task.length > 1) {\n taskFn(results, taskCallback);\n } else {\n taskFn(taskCallback);\n }\n }\n\n function checkForDeadlocks() {\n // Kahn's algorithm\n // https://en.wikipedia.org/wiki/Topological_sorting#Kahn.27s_algorithm\n // http://connalle.blogspot.com/2013/10/topological-sortingkahn-algorithm.html\n var currentTask;\n var counter = 0;\n while (readyToCheck.length) {\n currentTask = readyToCheck.pop();\n counter++;\n getDependents(currentTask).forEach(dependent => {\n if (--uncheckedDependencies[dependent] === 0) {\n readyToCheck.push(dependent);\n }\n });\n }\n\n if (counter !== numTasks) {\n throw new Error(\n 'async.auto cannot execute tasks due to a recursive dependency'\n );\n }\n }\n\n function getDependents(taskName) {\n var result = [];\n Object.keys(tasks).forEach(key => {\n const task = tasks[key];\n if (Array.isArray(task) && task.indexOf(taskName) >= 0) {\n result.push(key);\n }\n });\n return result;\n }\n\n return callback[PROMISE_SYMBOL]\n}\n\nvar FN_ARGS = /^(?:async\\s)?(?:function)?\\s*(?:\\w+\\s*)?\\(([^)]+)\\)(?:\\s*{)/;\nvar ARROW_FN_ARGS = /^(?:async\\s)?\\s*(?:\\(\\s*)?((?:[^)=\\s]\\s*)*)(?:\\)\\s*)?=>/;\nvar FN_ARG_SPLIT = /,/;\nvar FN_ARG = /(=.+)?(\\s*)$/;\n\nfunction stripComments(string) {\n let stripped = '';\n let index = 0;\n let endBlockComment = string.indexOf('*/');\n while (index < string.length) {\n if (string[index] === '/' && string[index+1] === '/') {\n // inline comment\n let endIndex = string.indexOf('\\n', index);\n index = (endIndex === -1) ? string.length : endIndex;\n } else if ((endBlockComment !== -1) && (string[index] === '/') && (string[index+1] === '*')) {\n // block comment\n let endIndex = string.indexOf('*/', index);\n if (endIndex !== -1) {\n index = endIndex + 2;\n endBlockComment = string.indexOf('*/', index);\n } else {\n stripped += string[index];\n index++;\n }\n } else {\n stripped += string[index];\n index++;\n }\n }\n return stripped;\n}\n\nfunction parseParams(func) {\n const src = stripComments(func.toString());\n let match = src.match(FN_ARGS);\n if (!match) {\n match = src.match(ARROW_FN_ARGS);\n }\n if (!match) throw new Error('could not parse args in autoInject\\nSource:\\n' + src)\n let [, args] = match;\n return args\n .replace(/\\s/g, '')\n .split(FN_ARG_SPLIT)\n .map((arg) => arg.replace(FN_ARG, '').trim());\n}\n\n/**\n * A dependency-injected version of the [async.auto]{@link module:ControlFlow.auto} function. Dependent\n * tasks are specified as parameters to the function, after the usual callback\n * parameter, with the parameter names matching the names of the tasks it\n * depends on. This can provide even more readable task graphs which can be\n * easier to maintain.\n *\n * If a final callback is specified, the task results are similarly injected,\n * specified as named parameters after the initial error parameter.\n *\n * The autoInject function is purely syntactic sugar and its semantics are\n * otherwise equivalent to [async.auto]{@link module:ControlFlow.auto}.\n *\n * @name autoInject\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @see [async.auto]{@link module:ControlFlow.auto}\n * @category Control Flow\n * @param {Object} tasks - An object, each of whose properties is an {@link AsyncFunction} of\n * the form 'func([dependencies...], callback). The object's key of a property\n * serves as the name of the task defined by that property, i.e. can be used\n * when specifying requirements for other tasks.\n * * The `callback` parameter is a `callback(err, result)` which must be called\n * when finished, passing an `error` (which can be `null`) and the result of\n * the function's execution. The remaining parameters name other tasks on\n * which the task is dependent, and the results from those tasks are the\n * arguments of those parameters.\n * @param {Function} [callback] - An optional callback which is called when all\n * the tasks have been completed. It receives the `err` argument if any `tasks`\n * pass an error to their callback, and a `results` object with any completed\n * task results, similar to `auto`.\n * @returns {Promise} a promise, if no callback is passed\n * @example\n *\n * // The example from `auto` can be rewritten as follows:\n * async.autoInject({\n * get_data: function(callback) {\n * // async code to get some data\n * callback(null, 'data', 'converted to array');\n * },\n * make_folder: function(callback) {\n * // async code to create a directory to store a file in\n * // this is run at the same time as getting the data\n * callback(null, 'folder');\n * },\n * write_file: function(get_data, make_folder, callback) {\n * // once there is some data and the directory exists,\n * // write the data to a file in the directory\n * callback(null, 'filename');\n * },\n * email_link: function(write_file, callback) {\n * // once the file is written let's email a link to it...\n * // write_file contains the filename returned by write_file.\n * callback(null, {'file':write_file, 'email':'user@example.com'});\n * }\n * }, function(err, results) {\n * console.log('err = ', err);\n * console.log('email_link = ', results.email_link);\n * });\n *\n * // If you are using a JS minifier that mangles parameter names, `autoInject`\n * // will not work with plain functions, since the parameter names will be\n * // collapsed to a single letter identifier. To work around this, you can\n * // explicitly specify the names of the parameters your task function needs\n * // in an array, similar to Angular.js dependency injection.\n *\n * // This still has an advantage over plain `auto`, since the results a task\n * // depends on are still spread into arguments.\n * async.autoInject({\n * //...\n * write_file: ['get_data', 'make_folder', function(get_data, make_folder, callback) {\n * callback(null, 'filename');\n * }],\n * email_link: ['write_file', function(write_file, callback) {\n * callback(null, {'file':write_file, 'email':'user@example.com'});\n * }]\n * //...\n * }, function(err, results) {\n * console.log('err = ', err);\n * console.log('email_link = ', results.email_link);\n * });\n */\nfunction autoInject(tasks, callback) {\n var newTasks = {};\n\n Object.keys(tasks).forEach(key => {\n var taskFn = tasks[key];\n var params;\n var fnIsAsync = isAsync(taskFn);\n var hasNoDeps =\n (!fnIsAsync && taskFn.length === 1) ||\n (fnIsAsync && taskFn.length === 0);\n\n if (Array.isArray(taskFn)) {\n params = [...taskFn];\n taskFn = params.pop();\n\n newTasks[key] = params.concat(params.length > 0 ? newTask : taskFn);\n } else if (hasNoDeps) {\n // no dependencies, use the function as-is\n newTasks[key] = taskFn;\n } else {\n params = parseParams(taskFn);\n if ((taskFn.length === 0 && !fnIsAsync) && params.length === 0) {\n throw new Error(\"autoInject task functions require explicit parameters.\");\n }\n\n // remove callback param\n if (!fnIsAsync) params.pop();\n\n newTasks[key] = params.concat(newTask);\n }\n\n function newTask(results, taskCb) {\n var newArgs = params.map(name => results[name]);\n newArgs.push(taskCb);\n wrapAsync(taskFn)(...newArgs);\n }\n });\n\n return auto(newTasks, callback);\n}\n\n// Simple doubly linked list (https://en.wikipedia.org/wiki/Doubly_linked_list) implementation\n// used for queues. This implementation assumes that the node provided by the user can be modified\n// to adjust the next and last properties. We implement only the minimal functionality\n// for queue support.\nclass DLL {\n constructor() {\n this.head = this.tail = null;\n this.length = 0;\n }\n\n removeLink(node) {\n if (node.prev) node.prev.next = node.next;\n else this.head = node.next;\n if (node.next) node.next.prev = node.prev;\n else this.tail = node.prev;\n\n node.prev = node.next = null;\n this.length -= 1;\n return node;\n }\n\n empty () {\n while(this.head) this.shift();\n return this;\n }\n\n insertAfter(node, newNode) {\n newNode.prev = node;\n newNode.next = node.next;\n if (node.next) node.next.prev = newNode;\n else this.tail = newNode;\n node.next = newNode;\n this.length += 1;\n }\n\n insertBefore(node, newNode) {\n newNode.prev = node.prev;\n newNode.next = node;\n if (node.prev) node.prev.next = newNode;\n else this.head = newNode;\n node.prev = newNode;\n this.length += 1;\n }\n\n unshift(node) {\n if (this.head) this.insertBefore(this.head, node);\n else setInitial(this, node);\n }\n\n push(node) {\n if (this.tail) this.insertAfter(this.tail, node);\n else setInitial(this, node);\n }\n\n shift() {\n return this.head && this.removeLink(this.head);\n }\n\n pop() {\n return this.tail && this.removeLink(this.tail);\n }\n\n toArray() {\n return [...this]\n }\n\n *[Symbol.iterator] () {\n var cur = this.head;\n while (cur) {\n yield cur.data;\n cur = cur.next;\n }\n }\n\n remove (testFn) {\n var curr = this.head;\n while(curr) {\n var {next} = curr;\n if (testFn(curr)) {\n this.removeLink(curr);\n }\n curr = next;\n }\n return this;\n }\n}\n\nfunction setInitial(dll, node) {\n dll.length = 1;\n dll.head = dll.tail = node;\n}\n\nfunction queue$1(worker, concurrency, payload) {\n if (concurrency == null) {\n concurrency = 1;\n }\n else if(concurrency === 0) {\n throw new RangeError('Concurrency must not be zero');\n }\n\n var _worker = wrapAsync(worker);\n var numRunning = 0;\n var workersList = [];\n const events = {\n error: [],\n drain: [],\n saturated: [],\n unsaturated: [],\n empty: []\n };\n\n function on (event, handler) {\n events[event].push(handler);\n }\n\n function once (event, handler) {\n const handleAndRemove = (...args) => {\n off(event, handleAndRemove);\n handler(...args);\n };\n events[event].push(handleAndRemove);\n }\n\n function off (event, handler) {\n if (!event) return Object.keys(events).forEach(ev => events[ev] = [])\n if (!handler) return events[event] = []\n events[event] = events[event].filter(ev => ev !== handler);\n }\n\n function trigger (event, ...args) {\n events[event].forEach(handler => handler(...args));\n }\n\n var processingScheduled = false;\n function _insert(data, insertAtFront, rejectOnError, callback) {\n if (callback != null && typeof callback !== 'function') {\n throw new Error('task callback must be a function');\n }\n q.started = true;\n\n var res, rej;\n function promiseCallback (err, ...args) {\n // we don't care about the error, let the global error handler\n // deal with it\n if (err) return rejectOnError ? rej(err) : res()\n if (args.length <= 1) return res(args[0])\n res(args);\n }\n\n var item = q._createTaskItem(\n data,\n rejectOnError ? promiseCallback :\n (callback || promiseCallback)\n );\n\n if (insertAtFront) {\n q._tasks.unshift(item);\n } else {\n q._tasks.push(item);\n }\n\n if (!processingScheduled) {\n processingScheduled = true;\n setImmediate$1(() => {\n processingScheduled = false;\n q.process();\n });\n }\n\n if (rejectOnError || !callback) {\n return new Promise((resolve, reject) => {\n res = resolve;\n rej = reject;\n })\n }\n }\n\n function _createCB(tasks) {\n return function (err, ...args) {\n numRunning -= 1;\n\n for (var i = 0, l = tasks.length; i < l; i++) {\n var task = tasks[i];\n\n var index = workersList.indexOf(task);\n if (index === 0) {\n workersList.shift();\n } else if (index > 0) {\n workersList.splice(index, 1);\n }\n\n task.callback(err, ...args);\n\n if (err != null) {\n trigger('error', err, task.data);\n }\n }\n\n if (numRunning <= (q.concurrency - q.buffer) ) {\n trigger('unsaturated');\n }\n\n if (q.idle()) {\n trigger('drain');\n }\n q.process();\n };\n }\n\n function _maybeDrain(data) {\n if (data.length === 0 && q.idle()) {\n // call drain immediately if there are no tasks\n setImmediate$1(() => trigger('drain'));\n return true\n }\n return false\n }\n\n const eventMethod = (name) => (handler) => {\n if (!handler) {\n return new Promise((resolve, reject) => {\n once(name, (err, data) => {\n if (err) return reject(err)\n resolve(data);\n });\n })\n }\n off(name);\n on(name, handler);\n\n };\n\n var isProcessing = false;\n var q = {\n _tasks: new DLL(),\n _createTaskItem (data, callback) {\n return {\n data,\n callback\n };\n },\n *[Symbol.iterator] () {\n yield* q._tasks[Symbol.iterator]();\n },\n concurrency,\n payload,\n buffer: concurrency / 4,\n started: false,\n paused: false,\n push (data, callback) {\n if (Array.isArray(data)) {\n if (_maybeDrain(data)) return\n return data.map(datum => _insert(datum, false, false, callback))\n }\n return _insert(data, false, false, callback);\n },\n pushAsync (data, callback) {\n if (Array.isArray(data)) {\n if (_maybeDrain(data)) return\n return data.map(datum => _insert(datum, false, true, callback))\n }\n return _insert(data, false, true, callback);\n },\n kill () {\n off();\n q._tasks.empty();\n },\n unshift (data, callback) {\n if (Array.isArray(data)) {\n if (_maybeDrain(data)) return\n return data.map(datum => _insert(datum, true, false, callback))\n }\n return _insert(data, true, false, callback);\n },\n unshiftAsync (data, callback) {\n if (Array.isArray(data)) {\n if (_maybeDrain(data)) return\n return data.map(datum => _insert(datum, true, true, callback))\n }\n return _insert(data, true, true, callback);\n },\n remove (testFn) {\n q._tasks.remove(testFn);\n },\n process () {\n // Avoid trying to start too many processing operations. This can occur\n // when callbacks resolve synchronously (#1267).\n if (isProcessing) {\n return;\n }\n isProcessing = true;\n while(!q.paused && numRunning < q.concurrency && q._tasks.length){\n var tasks = [], data = [];\n var l = q._tasks.length;\n if (q.payload) l = Math.min(l, q.payload);\n for (var i = 0; i < l; i++) {\n var node = q._tasks.shift();\n tasks.push(node);\n workersList.push(node);\n data.push(node.data);\n }\n\n numRunning += 1;\n\n if (q._tasks.length === 0) {\n trigger('empty');\n }\n\n if (numRunning === q.concurrency) {\n trigger('saturated');\n }\n\n var cb = onlyOnce(_createCB(tasks));\n _worker(data, cb);\n }\n isProcessing = false;\n },\n length () {\n return q._tasks.length;\n },\n running () {\n return numRunning;\n },\n workersList () {\n return workersList;\n },\n idle() {\n return q._tasks.length + numRunning === 0;\n },\n pause () {\n q.paused = true;\n },\n resume () {\n if (q.paused === false) { return; }\n q.paused = false;\n setImmediate$1(q.process);\n }\n };\n // define these as fixed properties, so people get useful errors when updating\n Object.defineProperties(q, {\n saturated: {\n writable: false,\n value: eventMethod('saturated')\n },\n unsaturated: {\n writable: false,\n value: eventMethod('unsaturated')\n },\n empty: {\n writable: false,\n value: eventMethod('empty')\n },\n drain: {\n writable: false,\n value: eventMethod('drain')\n },\n error: {\n writable: false,\n value: eventMethod('error')\n },\n });\n return q;\n}\n\n/**\n * Creates a `cargo` object with the specified payload. Tasks added to the\n * cargo will be processed altogether (up to the `payload` limit). If the\n * `worker` is in progress, the task is queued until it becomes available. Once\n * the `worker` has completed some tasks, each callback of those tasks is\n * called. Check out [these](https://camo.githubusercontent.com/6bbd36f4cf5b35a0f11a96dcd2e97711ffc2fb37/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130382f62626330636662302d356632392d313165322d393734662d3333393763363464633835382e676966) [animations](https://camo.githubusercontent.com/f4810e00e1c5f5f8addbe3e9f49064fd5d102699/68747470733a2f2f662e636c6f75642e6769746875622e636f6d2f6173736574732f313637363837312f36383130312f38346339323036362d356632392d313165322d383134662d3964336430323431336266642e676966)\n * for how `cargo` and `queue` work.\n *\n * While [`queue`]{@link module:ControlFlow.queue} passes only one task to one of a group of workers\n * at a time, cargo passes an array of tasks to a single worker, repeating\n * when the worker is finished.\n *\n * @name cargo\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @see [async.queue]{@link module:ControlFlow.queue}\n * @category Control Flow\n * @param {AsyncFunction} worker - An asynchronous function for processing an array\n * of queued tasks. Invoked with `(tasks, callback)`.\n * @param {number} [payload=Infinity] - An optional `integer` for determining\n * how many tasks should be processed per round; if omitted, the default is\n * unlimited.\n * @returns {module:ControlFlow.QueueObject} A cargo object to manage the tasks. Callbacks can\n * attached as certain properties to listen for specific events during the\n * lifecycle of the cargo and inner queue.\n * @example\n *\n * // create a cargo object with payload 2\n * var cargo = async.cargo(function(tasks, callback) {\n * for (var i=0; i {\n * console.log(result);\n * // 6000\n * // which is the sum of the file sizes of the three files\n * }).catch( err => {\n * console.log(err);\n * });\n *\n * // Error Handling\n * async.reduce(withMissingFileList, 0, getFileSizeInBytes)\n * .then( result => {\n * console.log(result);\n * }).catch( err => {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * });\n *\n * // Using async/await\n * async () => {\n * try {\n * let result = await async.reduce(fileList, 0, getFileSizeInBytes);\n * console.log(result);\n * // 6000\n * // which is the sum of the file sizes of the three files\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n * // Error Handling\n * async () => {\n * try {\n * let result = await async.reduce(withMissingFileList, 0, getFileSizeInBytes);\n * console.log(result);\n * }\n * catch (err) {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * }\n * }\n *\n */\nfunction reduce(coll, memo, iteratee, callback) {\n callback = once(callback);\n var _iteratee = wrapAsync(iteratee);\n return eachOfSeries$1(coll, (x, i, iterCb) => {\n _iteratee(memo, x, (err, v) => {\n memo = v;\n iterCb(err);\n });\n }, err => callback(err, memo));\n}\nvar reduce$1 = awaitify(reduce, 4);\n\n/**\n * Version of the compose function that is more natural to read. Each function\n * consumes the return value of the previous function. It is the equivalent of\n * [compose]{@link module:ControlFlow.compose} with the arguments reversed.\n *\n * Each function is executed with the `this` binding of the composed function.\n *\n * @name seq\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @see [async.compose]{@link module:ControlFlow.compose}\n * @category Control Flow\n * @param {...AsyncFunction} functions - the asynchronous functions to compose\n * @returns {Function} a function that composes the `functions` in order\n * @example\n *\n * // Requires lodash (or underscore), express3 and dresende's orm2.\n * // Part of an app, that fetches cats of the logged user.\n * // This example uses `seq` function to avoid overnesting and error\n * // handling clutter.\n * app.get('/cats', function(request, response) {\n * var User = request.models.User;\n * async.seq(\n * User.get.bind(User), // 'User.get' has signature (id, callback(err, data))\n * function(user, fn) {\n * user.getCats(fn); // 'getCats' has signature (callback(err, data))\n * }\n * )(req.session.user_id, function (err, cats) {\n * if (err) {\n * console.error(err);\n * response.json({ status: 'error', message: err.message });\n * } else {\n * response.json({ status: 'ok', message: 'Cats found', data: cats });\n * }\n * });\n * });\n */\nfunction seq(...functions) {\n var _functions = functions.map(wrapAsync);\n return function (...args) {\n var that = this;\n\n var cb = args[args.length - 1];\n if (typeof cb == 'function') {\n args.pop();\n } else {\n cb = promiseCallback();\n }\n\n reduce$1(_functions, args, (newargs, fn, iterCb) => {\n fn.apply(that, newargs.concat((err, ...nextargs) => {\n iterCb(err, nextargs);\n }));\n },\n (err, results) => cb(err, ...results));\n\n return cb[PROMISE_SYMBOL]\n };\n}\n\n/**\n * Creates a function which is a composition of the passed asynchronous\n * functions. Each function consumes the return value of the function that\n * follows. Composing functions `f()`, `g()`, and `h()` would produce the result\n * of `f(g(h()))`, only this version uses callbacks to obtain the return values.\n *\n * If the last argument to the composed function is not a function, a promise\n * is returned when you call it.\n *\n * Each function is executed with the `this` binding of the composed function.\n *\n * @name compose\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @category Control Flow\n * @param {...AsyncFunction} functions - the asynchronous functions to compose\n * @returns {Function} an asynchronous function that is the composed\n * asynchronous `functions`\n * @example\n *\n * function add1(n, callback) {\n * setTimeout(function () {\n * callback(null, n + 1);\n * }, 10);\n * }\n *\n * function mul3(n, callback) {\n * setTimeout(function () {\n * callback(null, n * 3);\n * }, 10);\n * }\n *\n * var add1mul3 = async.compose(mul3, add1);\n * add1mul3(4, function (err, result) {\n * // result now equals 15\n * });\n */\nfunction compose(...args) {\n return seq(...args.reverse());\n}\n\n/**\n * The same as [`map`]{@link module:Collections.map} but runs a maximum of `limit` async operations at a time.\n *\n * @name mapLimit\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.map]{@link module:Collections.map}\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {number} limit - The maximum number of async operations at a time.\n * @param {AsyncFunction} iteratee - An async function to apply to each item in\n * `coll`.\n * The iteratee should complete with the transformed item.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called when all `iteratee`\n * functions have finished, or an error occurs. Results is an array of the\n * transformed items from the `coll`. Invoked with (err, results).\n * @returns {Promise} a promise, if no callback is passed\n */\nfunction mapLimit (coll, limit, iteratee, callback) {\n return _asyncMap(eachOfLimit$2(limit), coll, iteratee, callback)\n}\nvar mapLimit$1 = awaitify(mapLimit, 4);\n\n/**\n * The same as [`concat`]{@link module:Collections.concat} but runs a maximum of `limit` async operations at a time.\n *\n * @name concatLimit\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.concat]{@link module:Collections.concat}\n * @category Collection\n * @alias flatMapLimit\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {number} limit - The maximum number of async operations at a time.\n * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,\n * which should use an array as its result. Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called after all the\n * `iteratee` functions have finished, or an error occurs. Results is an array\n * containing the concatenated results of the `iteratee` function. Invoked with\n * (err, results).\n * @returns A Promise, if no callback is passed\n */\nfunction concatLimit(coll, limit, iteratee, callback) {\n var _iteratee = wrapAsync(iteratee);\n return mapLimit$1(coll, limit, (val, iterCb) => {\n _iteratee(val, (err, ...args) => {\n if (err) return iterCb(err);\n return iterCb(err, args);\n });\n }, (err, mapResults) => {\n var result = [];\n for (var i = 0; i < mapResults.length; i++) {\n if (mapResults[i]) {\n result = result.concat(...mapResults[i]);\n }\n }\n\n return callback(err, result);\n });\n}\nvar concatLimit$1 = awaitify(concatLimit, 4);\n\n/**\n * Applies `iteratee` to each item in `coll`, concatenating the results. Returns\n * the concatenated list. The `iteratee`s are called in parallel, and the\n * results are concatenated as they return. The results array will be returned in\n * the original order of `coll` passed to the `iteratee` function.\n *\n * @name concat\n * @static\n * @memberOf module:Collections\n * @method\n * @category Collection\n * @alias flatMap\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`,\n * which should use an array as its result. Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called after all the\n * `iteratee` functions have finished, or an error occurs. Results is an array\n * containing the concatenated results of the `iteratee` function. Invoked with\n * (err, results).\n * @returns A Promise, if no callback is passed\n * @example\n *\n * // dir1 is a directory that contains file1.txt, file2.txt\n * // dir2 is a directory that contains file3.txt, file4.txt\n * // dir3 is a directory that contains file5.txt\n * // dir4 does not exist\n *\n * let directoryList = ['dir1','dir2','dir3'];\n * let withMissingDirectoryList = ['dir1','dir2','dir3', 'dir4'];\n *\n * // Using callbacks\n * async.concat(directoryList, fs.readdir, function(err, results) {\n * if (err) {\n * console.log(err);\n * } else {\n * console.log(results);\n * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]\n * }\n * });\n *\n * // Error Handling\n * async.concat(withMissingDirectoryList, fs.readdir, function(err, results) {\n * if (err) {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * // since dir4 does not exist\n * } else {\n * console.log(results);\n * }\n * });\n *\n * // Using Promises\n * async.concat(directoryList, fs.readdir)\n * .then(results => {\n * console.log(results);\n * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]\n * }).catch(err => {\n * console.log(err);\n * });\n *\n * // Error Handling\n * async.concat(withMissingDirectoryList, fs.readdir)\n * .then(results => {\n * console.log(results);\n * }).catch(err => {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * // since dir4 does not exist\n * });\n *\n * // Using async/await\n * async () => {\n * try {\n * let results = await async.concat(directoryList, fs.readdir);\n * console.log(results);\n * // [ 'file1.txt', 'file2.txt', 'file3.txt', 'file4.txt', file5.txt ]\n * } catch (err) {\n * console.log(err);\n * }\n * }\n *\n * // Error Handling\n * async () => {\n * try {\n * let results = await async.concat(withMissingDirectoryList, fs.readdir);\n * console.log(results);\n * } catch (err) {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * // since dir4 does not exist\n * }\n * }\n *\n */\nfunction concat(coll, iteratee, callback) {\n return concatLimit$1(coll, Infinity, iteratee, callback)\n}\nvar concat$1 = awaitify(concat, 3);\n\n/**\n * The same as [`concat`]{@link module:Collections.concat} but runs only a single async operation at a time.\n *\n * @name concatSeries\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.concat]{@link module:Collections.concat}\n * @category Collection\n * @alias flatMapSeries\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - A function to apply to each item in `coll`.\n * The iteratee should complete with an array an array of results.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called after all the\n * `iteratee` functions have finished, or an error occurs. Results is an array\n * containing the concatenated results of the `iteratee` function. Invoked with\n * (err, results).\n * @returns A Promise, if no callback is passed\n */\nfunction concatSeries(coll, iteratee, callback) {\n return concatLimit$1(coll, 1, iteratee, callback)\n}\nvar concatSeries$1 = awaitify(concatSeries, 3);\n\n/**\n * Returns a function that when called, calls-back with the values provided.\n * Useful as the first function in a [`waterfall`]{@link module:ControlFlow.waterfall}, or for plugging values in to\n * [`auto`]{@link module:ControlFlow.auto}.\n *\n * @name constant\n * @static\n * @memberOf module:Utils\n * @method\n * @category Util\n * @param {...*} arguments... - Any number of arguments to automatically invoke\n * callback with.\n * @returns {AsyncFunction} Returns a function that when invoked, automatically\n * invokes the callback with the previous given arguments.\n * @example\n *\n * async.waterfall([\n * async.constant(42),\n * function (value, next) {\n * // value === 42\n * },\n * //...\n * ], callback);\n *\n * async.waterfall([\n * async.constant(filename, \"utf8\"),\n * fs.readFile,\n * function (fileData, next) {\n * //...\n * }\n * //...\n * ], callback);\n *\n * async.auto({\n * hostname: async.constant(\"https://server.net/\"),\n * port: findFreePort,\n * launchServer: [\"hostname\", \"port\", function (options, cb) {\n * startServer(options, cb);\n * }],\n * //...\n * }, callback);\n */\nfunction constant$1(...args) {\n return function (...ignoredArgs/*, callback*/) {\n var callback = ignoredArgs.pop();\n return callback(null, ...args);\n };\n}\n\nfunction _createTester(check, getResult) {\n return (eachfn, arr, _iteratee, cb) => {\n var testPassed = false;\n var testResult;\n const iteratee = wrapAsync(_iteratee);\n eachfn(arr, (value, _, callback) => {\n iteratee(value, (err, result) => {\n if (err || err === false) return callback(err);\n\n if (check(result) && !testResult) {\n testPassed = true;\n testResult = getResult(true, value);\n return callback(null, breakLoop);\n }\n callback();\n });\n }, err => {\n if (err) return cb(err);\n cb(null, testPassed ? testResult : getResult(false));\n });\n };\n}\n\n/**\n * Returns the first value in `coll` that passes an async truth test. The\n * `iteratee` is applied in parallel, meaning the first iteratee to return\n * `true` will fire the detect `callback` with that result. That means the\n * result might not be the first item in the original `coll` (in terms of order)\n * that passes the test.\n\n * If order within the original `coll` is important, then look at\n * [`detectSeries`]{@link module:Collections.detectSeries}.\n *\n * @name detect\n * @static\n * @memberOf module:Collections\n * @method\n * @alias find\n * @category Collections\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.\n * The iteratee must complete with a boolean value as its result.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called as soon as any\n * iteratee returns `true`, or after all the `iteratee` functions have finished.\n * Result will be the first item in the array that passes the truth test\n * (iteratee) or the value `undefined` if none passed. Invoked with\n * (err, result).\n * @returns {Promise} a promise, if a callback is omitted\n * @example\n *\n * // dir1 is a directory that contains file1.txt, file2.txt\n * // dir2 is a directory that contains file3.txt, file4.txt\n * // dir3 is a directory that contains file5.txt\n *\n * // asynchronous function that checks if a file exists\n * function fileExists(file, callback) {\n * fs.access(file, fs.constants.F_OK, (err) => {\n * callback(null, !err);\n * });\n * }\n *\n * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists,\n * function(err, result) {\n * console.log(result);\n * // dir1/file1.txt\n * // result now equals the first file in the list that exists\n * }\n *);\n *\n * // Using Promises\n * async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists)\n * .then(result => {\n * console.log(result);\n * // dir1/file1.txt\n * // result now equals the first file in the list that exists\n * }).catch(err => {\n * console.log(err);\n * });\n *\n * // Using async/await\n * async () => {\n * try {\n * let result = await async.detect(['file3.txt','file2.txt','dir1/file1.txt'], fileExists);\n * console.log(result);\n * // dir1/file1.txt\n * // result now equals the file in the list that exists\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n */\nfunction detect(coll, iteratee, callback) {\n return _createTester(bool => bool, (res, item) => item)(eachOf$1, coll, iteratee, callback)\n}\nvar detect$1 = awaitify(detect, 3);\n\n/**\n * The same as [`detect`]{@link module:Collections.detect} but runs a maximum of `limit` async operations at a\n * time.\n *\n * @name detectLimit\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.detect]{@link module:Collections.detect}\n * @alias findLimit\n * @category Collections\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {number} limit - The maximum number of async operations at a time.\n * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.\n * The iteratee must complete with a boolean value as its result.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called as soon as any\n * iteratee returns `true`, or after all the `iteratee` functions have finished.\n * Result will be the first item in the array that passes the truth test\n * (iteratee) or the value `undefined` if none passed. Invoked with\n * (err, result).\n * @returns {Promise} a promise, if a callback is omitted\n */\nfunction detectLimit(coll, limit, iteratee, callback) {\n return _createTester(bool => bool, (res, item) => item)(eachOfLimit$2(limit), coll, iteratee, callback)\n}\nvar detectLimit$1 = awaitify(detectLimit, 4);\n\n/**\n * The same as [`detect`]{@link module:Collections.detect} but runs only a single async operation at a time.\n *\n * @name detectSeries\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.detect]{@link module:Collections.detect}\n * @alias findSeries\n * @category Collections\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - A truth test to apply to each item in `coll`.\n * The iteratee must complete with a boolean value as its result.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called as soon as any\n * iteratee returns `true`, or after all the `iteratee` functions have finished.\n * Result will be the first item in the array that passes the truth test\n * (iteratee) or the value `undefined` if none passed. Invoked with\n * (err, result).\n * @returns {Promise} a promise, if a callback is omitted\n */\nfunction detectSeries(coll, iteratee, callback) {\n return _createTester(bool => bool, (res, item) => item)(eachOfLimit$2(1), coll, iteratee, callback)\n}\n\nvar detectSeries$1 = awaitify(detectSeries, 3);\n\nfunction consoleFunc(name) {\n return (fn, ...args) => wrapAsync(fn)(...args, (err, ...resultArgs) => {\n /* istanbul ignore else */\n if (typeof console === 'object') {\n /* istanbul ignore else */\n if (err) {\n /* istanbul ignore else */\n if (console.error) {\n console.error(err);\n }\n } else if (console[name]) { /* istanbul ignore else */\n resultArgs.forEach(x => console[name](x));\n }\n }\n })\n}\n\n/**\n * Logs the result of an [`async` function]{@link AsyncFunction} to the\n * `console` using `console.dir` to display the properties of the resulting object.\n * Only works in Node.js or in browsers that support `console.dir` and\n * `console.error` (such as FF and Chrome).\n * If multiple arguments are returned from the async function,\n * `console.dir` is called on each argument in order.\n *\n * @name dir\n * @static\n * @memberOf module:Utils\n * @method\n * @category Util\n * @param {AsyncFunction} function - The function you want to eventually apply\n * all arguments to.\n * @param {...*} arguments... - Any number of arguments to apply to the function.\n * @example\n *\n * // in a module\n * var hello = function(name, callback) {\n * setTimeout(function() {\n * callback(null, {hello: name});\n * }, 1000);\n * };\n *\n * // in the node repl\n * node> async.dir(hello, 'world');\n * {hello: 'world'}\n */\nvar dir = consoleFunc('dir');\n\n/**\n * The post-check version of [`whilst`]{@link module:ControlFlow.whilst}. To reflect the difference in\n * the order of operations, the arguments `test` and `iteratee` are switched.\n *\n * `doWhilst` is to `whilst` as `do while` is to `while` in plain JavaScript.\n *\n * @name doWhilst\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @see [async.whilst]{@link module:ControlFlow.whilst}\n * @category Control Flow\n * @param {AsyncFunction} iteratee - A function which is called each time `test`\n * passes. Invoked with (callback).\n * @param {AsyncFunction} test - asynchronous truth test to perform after each\n * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the\n * non-error args from the previous callback of `iteratee`.\n * @param {Function} [callback] - A callback which is called after the test\n * function has failed and repeated execution of `iteratee` has stopped.\n * `callback` will be passed an error and any arguments passed to the final\n * `iteratee`'s callback. Invoked with (err, [results]);\n * @returns {Promise} a promise, if no callback is passed\n */\nfunction doWhilst(iteratee, test, callback) {\n callback = onlyOnce(callback);\n var _fn = wrapAsync(iteratee);\n var _test = wrapAsync(test);\n var results;\n\n function next(err, ...args) {\n if (err) return callback(err);\n if (err === false) return;\n results = args;\n _test(...args, check);\n }\n\n function check(err, truth) {\n if (err) return callback(err);\n if (err === false) return;\n if (!truth) return callback(null, ...results);\n _fn(next);\n }\n\n return check(null, true);\n}\n\nvar doWhilst$1 = awaitify(doWhilst, 3);\n\n/**\n * Like ['doWhilst']{@link module:ControlFlow.doWhilst}, except the `test` is inverted. Note the\n * argument ordering differs from `until`.\n *\n * @name doUntil\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @see [async.doWhilst]{@link module:ControlFlow.doWhilst}\n * @category Control Flow\n * @param {AsyncFunction} iteratee - An async function which is called each time\n * `test` fails. Invoked with (callback).\n * @param {AsyncFunction} test - asynchronous truth test to perform after each\n * execution of `iteratee`. Invoked with (...args, callback), where `...args` are the\n * non-error args from the previous callback of `iteratee`\n * @param {Function} [callback] - A callback which is called after the test\n * function has passed and repeated execution of `iteratee` has stopped. `callback`\n * will be passed an error and any arguments passed to the final `iteratee`'s\n * callback. Invoked with (err, [results]);\n * @returns {Promise} a promise, if no callback is passed\n */\nfunction doUntil(iteratee, test, callback) {\n const _test = wrapAsync(test);\n return doWhilst$1(iteratee, (...args) => {\n const cb = args.pop();\n _test(...args, (err, truth) => cb (err, !truth));\n }, callback);\n}\n\nfunction _withoutIndex(iteratee) {\n return (value, index, callback) => iteratee(value, callback);\n}\n\n/**\n * Applies the function `iteratee` to each item in `coll`, in parallel.\n * The `iteratee` is called with an item from the list, and a callback for when\n * it has finished. If the `iteratee` passes an error to its `callback`, the\n * main `callback` (for the `each` function) is immediately called with the\n * error.\n *\n * Note, that since this function applies `iteratee` to each item in parallel,\n * there is no guarantee that the iteratee functions will complete in order.\n *\n * @name each\n * @static\n * @memberOf module:Collections\n * @method\n * @alias forEach\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - An async function to apply to\n * each item in `coll`. Invoked with (item, callback).\n * The array index is not passed to the iteratee.\n * If you need the index, use `eachOf`.\n * @param {Function} [callback] - A callback which is called when all\n * `iteratee` functions have finished, or an error occurs. Invoked with (err).\n * @returns {Promise} a promise, if a callback is omitted\n * @example\n *\n * // dir1 is a directory that contains file1.txt, file2.txt\n * // dir2 is a directory that contains file3.txt, file4.txt\n * // dir3 is a directory that contains file5.txt\n * // dir4 does not exist\n *\n * const fileList = [ 'dir1/file2.txt', 'dir2/file3.txt', 'dir/file5.txt'];\n * const withMissingFileList = ['dir1/file1.txt', 'dir4/file2.txt'];\n *\n * // asynchronous function that deletes a file\n * const deleteFile = function(file, callback) {\n * fs.unlink(file, callback);\n * };\n *\n * // Using callbacks\n * async.each(fileList, deleteFile, function(err) {\n * if( err ) {\n * console.log(err);\n * } else {\n * console.log('All files have been deleted successfully');\n * }\n * });\n *\n * // Error Handling\n * async.each(withMissingFileList, deleteFile, function(err){\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * // since dir4/file2.txt does not exist\n * // dir1/file1.txt could have been deleted\n * });\n *\n * // Using Promises\n * async.each(fileList, deleteFile)\n * .then( () => {\n * console.log('All files have been deleted successfully');\n * }).catch( err => {\n * console.log(err);\n * });\n *\n * // Error Handling\n * async.each(fileList, deleteFile)\n * .then( () => {\n * console.log('All files have been deleted successfully');\n * }).catch( err => {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * // since dir4/file2.txt does not exist\n * // dir1/file1.txt could have been deleted\n * });\n *\n * // Using async/await\n * async () => {\n * try {\n * await async.each(files, deleteFile);\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n * // Error Handling\n * async () => {\n * try {\n * await async.each(withMissingFileList, deleteFile);\n * }\n * catch (err) {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * // since dir4/file2.txt does not exist\n * // dir1/file1.txt could have been deleted\n * }\n * }\n *\n */\nfunction eachLimit$2(coll, iteratee, callback) {\n return eachOf$1(coll, _withoutIndex(wrapAsync(iteratee)), callback);\n}\n\nvar each = awaitify(eachLimit$2, 3);\n\n/**\n * The same as [`each`]{@link module:Collections.each} but runs a maximum of `limit` async operations at a time.\n *\n * @name eachLimit\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.each]{@link module:Collections.each}\n * @alias forEachLimit\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {number} limit - The maximum number of async operations at a time.\n * @param {AsyncFunction} iteratee - An async function to apply to each item in\n * `coll`.\n * The array index is not passed to the iteratee.\n * If you need the index, use `eachOfLimit`.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called when all\n * `iteratee` functions have finished, or an error occurs. Invoked with (err).\n * @returns {Promise} a promise, if a callback is omitted\n */\nfunction eachLimit(coll, limit, iteratee, callback) {\n return eachOfLimit$2(limit)(coll, _withoutIndex(wrapAsync(iteratee)), callback);\n}\nvar eachLimit$1 = awaitify(eachLimit, 4);\n\n/**\n * The same as [`each`]{@link module:Collections.each} but runs only a single async operation at a time.\n *\n * Note, that unlike [`each`]{@link module:Collections.each}, this function applies iteratee to each item\n * in series and therefore the iteratee functions will complete in order.\n\n * @name eachSeries\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.each]{@link module:Collections.each}\n * @alias forEachSeries\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - An async function to apply to each\n * item in `coll`.\n * The array index is not passed to the iteratee.\n * If you need the index, use `eachOfSeries`.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called when all\n * `iteratee` functions have finished, or an error occurs. Invoked with (err).\n * @returns {Promise} a promise, if a callback is omitted\n */\nfunction eachSeries(coll, iteratee, callback) {\n return eachLimit$1(coll, 1, iteratee, callback)\n}\nvar eachSeries$1 = awaitify(eachSeries, 3);\n\n/**\n * Wrap an async function and ensure it calls its callback on a later tick of\n * the event loop. If the function already calls its callback on a next tick,\n * no extra deferral is added. This is useful for preventing stack overflows\n * (`RangeError: Maximum call stack size exceeded`) and generally keeping\n * [Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony)\n * contained. ES2017 `async` functions are returned as-is -- they are immune\n * to Zalgo's corrupting influences, as they always resolve on a later tick.\n *\n * @name ensureAsync\n * @static\n * @memberOf module:Utils\n * @method\n * @category Util\n * @param {AsyncFunction} fn - an async function, one that expects a node-style\n * callback as its last argument.\n * @returns {AsyncFunction} Returns a wrapped function with the exact same call\n * signature as the function passed in.\n * @example\n *\n * function sometimesAsync(arg, callback) {\n * if (cache[arg]) {\n * return callback(null, cache[arg]); // this would be synchronous!!\n * } else {\n * doSomeIO(arg, callback); // this IO would be asynchronous\n * }\n * }\n *\n * // this has a risk of stack overflows if many results are cached in a row\n * async.mapSeries(args, sometimesAsync, done);\n *\n * // this will defer sometimesAsync's callback if necessary,\n * // preventing stack overflows\n * async.mapSeries(args, async.ensureAsync(sometimesAsync), done);\n */\nfunction ensureAsync(fn) {\n if (isAsync(fn)) return fn;\n return function (...args/*, callback*/) {\n var callback = args.pop();\n var sync = true;\n args.push((...innerArgs) => {\n if (sync) {\n setImmediate$1(() => callback(...innerArgs));\n } else {\n callback(...innerArgs);\n }\n });\n fn.apply(this, args);\n sync = false;\n };\n}\n\n/**\n * Returns `true` if every element in `coll` satisfies an async test. If any\n * iteratee call returns `false`, the main `callback` is immediately called.\n *\n * @name every\n * @static\n * @memberOf module:Collections\n * @method\n * @alias all\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - An async truth test to apply to each item\n * in the collection in parallel.\n * The iteratee must complete with a boolean result value.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called after all the\n * `iteratee` functions have finished. Result will be either `true` or `false`\n * depending on the values of the async tests. Invoked with (err, result).\n * @returns {Promise} a promise, if no callback provided\n * @example\n *\n * // dir1 is a directory that contains file1.txt, file2.txt\n * // dir2 is a directory that contains file3.txt, file4.txt\n * // dir3 is a directory that contains file5.txt\n * // dir4 does not exist\n *\n * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file5.txt'];\n * const withMissingFileList = ['file1.txt','file2.txt','file4.txt'];\n *\n * // asynchronous function that checks if a file exists\n * function fileExists(file, callback) {\n * fs.access(file, fs.constants.F_OK, (err) => {\n * callback(null, !err);\n * });\n * }\n *\n * // Using callbacks\n * async.every(fileList, fileExists, function(err, result) {\n * console.log(result);\n * // true\n * // result is true since every file exists\n * });\n *\n * async.every(withMissingFileList, fileExists, function(err, result) {\n * console.log(result);\n * // false\n * // result is false since NOT every file exists\n * });\n *\n * // Using Promises\n * async.every(fileList, fileExists)\n * .then( result => {\n * console.log(result);\n * // true\n * // result is true since every file exists\n * }).catch( err => {\n * console.log(err);\n * });\n *\n * async.every(withMissingFileList, fileExists)\n * .then( result => {\n * console.log(result);\n * // false\n * // result is false since NOT every file exists\n * }).catch( err => {\n * console.log(err);\n * });\n *\n * // Using async/await\n * async () => {\n * try {\n * let result = await async.every(fileList, fileExists);\n * console.log(result);\n * // true\n * // result is true since every file exists\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n * async () => {\n * try {\n * let result = await async.every(withMissingFileList, fileExists);\n * console.log(result);\n * // false\n * // result is false since NOT every file exists\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n */\nfunction every(coll, iteratee, callback) {\n return _createTester(bool => !bool, res => !res)(eachOf$1, coll, iteratee, callback)\n}\nvar every$1 = awaitify(every, 3);\n\n/**\n * The same as [`every`]{@link module:Collections.every} but runs a maximum of `limit` async operations at a time.\n *\n * @name everyLimit\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.every]{@link module:Collections.every}\n * @alias allLimit\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {number} limit - The maximum number of async operations at a time.\n * @param {AsyncFunction} iteratee - An async truth test to apply to each item\n * in the collection in parallel.\n * The iteratee must complete with a boolean result value.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called after all the\n * `iteratee` functions have finished. Result will be either `true` or `false`\n * depending on the values of the async tests. Invoked with (err, result).\n * @returns {Promise} a promise, if no callback provided\n */\nfunction everyLimit(coll, limit, iteratee, callback) {\n return _createTester(bool => !bool, res => !res)(eachOfLimit$2(limit), coll, iteratee, callback)\n}\nvar everyLimit$1 = awaitify(everyLimit, 4);\n\n/**\n * The same as [`every`]{@link module:Collections.every} but runs only a single async operation at a time.\n *\n * @name everySeries\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.every]{@link module:Collections.every}\n * @alias allSeries\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - An async truth test to apply to each item\n * in the collection in series.\n * The iteratee must complete with a boolean result value.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called after all the\n * `iteratee` functions have finished. Result will be either `true` or `false`\n * depending on the values of the async tests. Invoked with (err, result).\n * @returns {Promise} a promise, if no callback provided\n */\nfunction everySeries(coll, iteratee, callback) {\n return _createTester(bool => !bool, res => !res)(eachOfSeries$1, coll, iteratee, callback)\n}\nvar everySeries$1 = awaitify(everySeries, 3);\n\nfunction filterArray(eachfn, arr, iteratee, callback) {\n var truthValues = new Array(arr.length);\n eachfn(arr, (x, index, iterCb) => {\n iteratee(x, (err, v) => {\n truthValues[index] = !!v;\n iterCb(err);\n });\n }, err => {\n if (err) return callback(err);\n var results = [];\n for (var i = 0; i < arr.length; i++) {\n if (truthValues[i]) results.push(arr[i]);\n }\n callback(null, results);\n });\n}\n\nfunction filterGeneric(eachfn, coll, iteratee, callback) {\n var results = [];\n eachfn(coll, (x, index, iterCb) => {\n iteratee(x, (err, v) => {\n if (err) return iterCb(err);\n if (v) {\n results.push({index, value: x});\n }\n iterCb(err);\n });\n }, err => {\n if (err) return callback(err);\n callback(null, results\n .sort((a, b) => a.index - b.index)\n .map(v => v.value));\n });\n}\n\nfunction _filter(eachfn, coll, iteratee, callback) {\n var filter = isArrayLike(coll) ? filterArray : filterGeneric;\n return filter(eachfn, coll, wrapAsync(iteratee), callback);\n}\n\n/**\n * Returns a new array of all the values in `coll` which pass an async truth\n * test. This operation is performed in parallel, but the results array will be\n * in the same order as the original.\n *\n * @name filter\n * @static\n * @memberOf module:Collections\n * @method\n * @alias select\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {Function} iteratee - A truth test to apply to each item in `coll`.\n * The `iteratee` is passed a `callback(err, truthValue)`, which must be called\n * with a boolean argument once it has completed. Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called after all the\n * `iteratee` functions have finished. Invoked with (err, results).\n * @returns {Promise} a promise, if no callback provided\n * @example\n *\n * // dir1 is a directory that contains file1.txt, file2.txt\n * // dir2 is a directory that contains file3.txt, file4.txt\n * // dir3 is a directory that contains file5.txt\n *\n * const files = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt'];\n *\n * // asynchronous function that checks if a file exists\n * function fileExists(file, callback) {\n * fs.access(file, fs.constants.F_OK, (err) => {\n * callback(null, !err);\n * });\n * }\n *\n * // Using callbacks\n * async.filter(files, fileExists, function(err, results) {\n * if(err) {\n * console.log(err);\n * } else {\n * console.log(results);\n * // [ 'dir1/file1.txt', 'dir2/file3.txt' ]\n * // results is now an array of the existing files\n * }\n * });\n *\n * // Using Promises\n * async.filter(files, fileExists)\n * .then(results => {\n * console.log(results);\n * // [ 'dir1/file1.txt', 'dir2/file3.txt' ]\n * // results is now an array of the existing files\n * }).catch(err => {\n * console.log(err);\n * });\n *\n * // Using async/await\n * async () => {\n * try {\n * let results = await async.filter(files, fileExists);\n * console.log(results);\n * // [ 'dir1/file1.txt', 'dir2/file3.txt' ]\n * // results is now an array of the existing files\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n */\nfunction filter (coll, iteratee, callback) {\n return _filter(eachOf$1, coll, iteratee, callback)\n}\nvar filter$1 = awaitify(filter, 3);\n\n/**\n * The same as [`filter`]{@link module:Collections.filter} but runs a maximum of `limit` async operations at a\n * time.\n *\n * @name filterLimit\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.filter]{@link module:Collections.filter}\n * @alias selectLimit\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {number} limit - The maximum number of async operations at a time.\n * @param {Function} iteratee - A truth test to apply to each item in `coll`.\n * The `iteratee` is passed a `callback(err, truthValue)`, which must be called\n * with a boolean argument once it has completed. Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called after all the\n * `iteratee` functions have finished. Invoked with (err, results).\n * @returns {Promise} a promise, if no callback provided\n */\nfunction filterLimit (coll, limit, iteratee, callback) {\n return _filter(eachOfLimit$2(limit), coll, iteratee, callback)\n}\nvar filterLimit$1 = awaitify(filterLimit, 4);\n\n/**\n * The same as [`filter`]{@link module:Collections.filter} but runs only a single async operation at a time.\n *\n * @name filterSeries\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.filter]{@link module:Collections.filter}\n * @alias selectSeries\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {Function} iteratee - A truth test to apply to each item in `coll`.\n * The `iteratee` is passed a `callback(err, truthValue)`, which must be called\n * with a boolean argument once it has completed. Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called after all the\n * `iteratee` functions have finished. Invoked with (err, results)\n * @returns {Promise} a promise, if no callback provided\n */\nfunction filterSeries (coll, iteratee, callback) {\n return _filter(eachOfSeries$1, coll, iteratee, callback)\n}\nvar filterSeries$1 = awaitify(filterSeries, 3);\n\n/**\n * Calls the asynchronous function `fn` with a callback parameter that allows it\n * to call itself again, in series, indefinitely.\n\n * If an error is passed to the callback then `errback` is called with the\n * error, and execution stops, otherwise it will never be called.\n *\n * @name forever\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @category Control Flow\n * @param {AsyncFunction} fn - an async function to call repeatedly.\n * Invoked with (next).\n * @param {Function} [errback] - when `fn` passes an error to it's callback,\n * this function will be called, and execution stops. Invoked with (err).\n * @returns {Promise} a promise that rejects if an error occurs and an errback\n * is not passed\n * @example\n *\n * async.forever(\n * function(next) {\n * // next is suitable for passing to things that need a callback(err [, whatever]);\n * // it will result in this function being called again.\n * },\n * function(err) {\n * // if next is called with a value in its first parameter, it will appear\n * // in here as 'err', and execution will stop.\n * }\n * );\n */\nfunction forever(fn, errback) {\n var done = onlyOnce(errback);\n var task = wrapAsync(ensureAsync(fn));\n\n function next(err) {\n if (err) return done(err);\n if (err === false) return;\n task(next);\n }\n return next();\n}\nvar forever$1 = awaitify(forever, 2);\n\n/**\n * The same as [`groupBy`]{@link module:Collections.groupBy} but runs a maximum of `limit` async operations at a time.\n *\n * @name groupByLimit\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.groupBy]{@link module:Collections.groupBy}\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {number} limit - The maximum number of async operations at a time.\n * @param {AsyncFunction} iteratee - An async function to apply to each item in\n * `coll`.\n * The iteratee should complete with a `key` to group the value under.\n * Invoked with (value, callback).\n * @param {Function} [callback] - A callback which is called when all `iteratee`\n * functions have finished, or an error occurs. Result is an `Object` whoses\n * properties are arrays of values which returned the corresponding key.\n * @returns {Promise} a promise, if no callback is passed\n */\nfunction groupByLimit(coll, limit, iteratee, callback) {\n var _iteratee = wrapAsync(iteratee);\n return mapLimit$1(coll, limit, (val, iterCb) => {\n _iteratee(val, (err, key) => {\n if (err) return iterCb(err);\n return iterCb(err, {key, val});\n });\n }, (err, mapResults) => {\n var result = {};\n // from MDN, handle object having an `hasOwnProperty` prop\n var {hasOwnProperty} = Object.prototype;\n\n for (var i = 0; i < mapResults.length; i++) {\n if (mapResults[i]) {\n var {key} = mapResults[i];\n var {val} = mapResults[i];\n\n if (hasOwnProperty.call(result, key)) {\n result[key].push(val);\n } else {\n result[key] = [val];\n }\n }\n }\n\n return callback(err, result);\n });\n}\n\nvar groupByLimit$1 = awaitify(groupByLimit, 4);\n\n/**\n * Returns a new object, where each value corresponds to an array of items, from\n * `coll`, that returned the corresponding key. That is, the keys of the object\n * correspond to the values passed to the `iteratee` callback.\n *\n * Note: Since this function applies the `iteratee` to each item in parallel,\n * there is no guarantee that the `iteratee` functions will complete in order.\n * However, the values for each key in the `result` will be in the same order as\n * the original `coll`. For Objects, the values will roughly be in the order of\n * the original Objects' keys (but this can vary across JavaScript engines).\n *\n * @name groupBy\n * @static\n * @memberOf module:Collections\n * @method\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - An async function to apply to each item in\n * `coll`.\n * The iteratee should complete with a `key` to group the value under.\n * Invoked with (value, callback).\n * @param {Function} [callback] - A callback which is called when all `iteratee`\n * functions have finished, or an error occurs. Result is an `Object` whoses\n * properties are arrays of values which returned the corresponding key.\n * @returns {Promise} a promise, if no callback is passed\n * @example\n *\n * // dir1 is a directory that contains file1.txt, file2.txt\n * // dir2 is a directory that contains file3.txt, file4.txt\n * // dir3 is a directory that contains file5.txt\n * // dir4 does not exist\n *\n * const files = ['dir1/file1.txt','dir2','dir4']\n *\n * // asynchronous function that detects file type as none, file, or directory\n * function detectFile(file, callback) {\n * fs.stat(file, function(err, stat) {\n * if (err) {\n * return callback(null, 'none');\n * }\n * callback(null, stat.isDirectory() ? 'directory' : 'file');\n * });\n * }\n *\n * //Using callbacks\n * async.groupBy(files, detectFile, function(err, result) {\n * if(err) {\n * console.log(err);\n * } else {\n *\t console.log(result);\n * // {\n * // file: [ 'dir1/file1.txt' ],\n * // none: [ 'dir4' ],\n * // directory: [ 'dir2']\n * // }\n * // result is object containing the files grouped by type\n * }\n * });\n *\n * // Using Promises\n * async.groupBy(files, detectFile)\n * .then( result => {\n * console.log(result);\n * // {\n * // file: [ 'dir1/file1.txt' ],\n * // none: [ 'dir4' ],\n * // directory: [ 'dir2']\n * // }\n * // result is object containing the files grouped by type\n * }).catch( err => {\n * console.log(err);\n * });\n *\n * // Using async/await\n * async () => {\n * try {\n * let result = await async.groupBy(files, detectFile);\n * console.log(result);\n * // {\n * // file: [ 'dir1/file1.txt' ],\n * // none: [ 'dir4' ],\n * // directory: [ 'dir2']\n * // }\n * // result is object containing the files grouped by type\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n */\nfunction groupBy (coll, iteratee, callback) {\n return groupByLimit$1(coll, Infinity, iteratee, callback)\n}\n\n/**\n * The same as [`groupBy`]{@link module:Collections.groupBy} but runs only a single async operation at a time.\n *\n * @name groupBySeries\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.groupBy]{@link module:Collections.groupBy}\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - An async function to apply to each item in\n * `coll`.\n * The iteratee should complete with a `key` to group the value under.\n * Invoked with (value, callback).\n * @param {Function} [callback] - A callback which is called when all `iteratee`\n * functions have finished, or an error occurs. Result is an `Object` whose\n * properties are arrays of values which returned the corresponding key.\n * @returns {Promise} a promise, if no callback is passed\n */\nfunction groupBySeries (coll, iteratee, callback) {\n return groupByLimit$1(coll, 1, iteratee, callback)\n}\n\n/**\n * Logs the result of an `async` function to the `console`. Only works in\n * Node.js or in browsers that support `console.log` and `console.error` (such\n * as FF and Chrome). If multiple arguments are returned from the async\n * function, `console.log` is called on each argument in order.\n *\n * @name log\n * @static\n * @memberOf module:Utils\n * @method\n * @category Util\n * @param {AsyncFunction} function - The function you want to eventually apply\n * all arguments to.\n * @param {...*} arguments... - Any number of arguments to apply to the function.\n * @example\n *\n * // in a module\n * var hello = function(name, callback) {\n * setTimeout(function() {\n * callback(null, 'hello ' + name);\n * }, 1000);\n * };\n *\n * // in the node repl\n * node> async.log(hello, 'world');\n * 'hello world'\n */\nvar log = consoleFunc('log');\n\n/**\n * The same as [`mapValues`]{@link module:Collections.mapValues} but runs a maximum of `limit` async operations at a\n * time.\n *\n * @name mapValuesLimit\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.mapValues]{@link module:Collections.mapValues}\n * @category Collection\n * @param {Object} obj - A collection to iterate over.\n * @param {number} limit - The maximum number of async operations at a time.\n * @param {AsyncFunction} iteratee - A function to apply to each value and key\n * in `coll`.\n * The iteratee should complete with the transformed value as its result.\n * Invoked with (value, key, callback).\n * @param {Function} [callback] - A callback which is called when all `iteratee`\n * functions have finished, or an error occurs. `result` is a new object consisting\n * of each key from `obj`, with each transformed value on the right-hand side.\n * Invoked with (err, result).\n * @returns {Promise} a promise, if no callback is passed\n */\nfunction mapValuesLimit(obj, limit, iteratee, callback) {\n callback = once(callback);\n var newObj = {};\n var _iteratee = wrapAsync(iteratee);\n return eachOfLimit$2(limit)(obj, (val, key, next) => {\n _iteratee(val, key, (err, result) => {\n if (err) return next(err);\n newObj[key] = result;\n next(err);\n });\n }, err => callback(err, newObj));\n}\n\nvar mapValuesLimit$1 = awaitify(mapValuesLimit, 4);\n\n/**\n * A relative of [`map`]{@link module:Collections.map}, designed for use with objects.\n *\n * Produces a new Object by mapping each value of `obj` through the `iteratee`\n * function. The `iteratee` is called each `value` and `key` from `obj` and a\n * callback for when it has finished processing. Each of these callbacks takes\n * two arguments: an `error`, and the transformed item from `obj`. If `iteratee`\n * passes an error to its callback, the main `callback` (for the `mapValues`\n * function) is immediately called with the error.\n *\n * Note, the order of the keys in the result is not guaranteed. The keys will\n * be roughly in the order they complete, (but this is very engine-specific)\n *\n * @name mapValues\n * @static\n * @memberOf module:Collections\n * @method\n * @category Collection\n * @param {Object} obj - A collection to iterate over.\n * @param {AsyncFunction} iteratee - A function to apply to each value and key\n * in `coll`.\n * The iteratee should complete with the transformed value as its result.\n * Invoked with (value, key, callback).\n * @param {Function} [callback] - A callback which is called when all `iteratee`\n * functions have finished, or an error occurs. `result` is a new object consisting\n * of each key from `obj`, with each transformed value on the right-hand side.\n * Invoked with (err, result).\n * @returns {Promise} a promise, if no callback is passed\n * @example\n *\n * // file1.txt is a file that is 1000 bytes in size\n * // file2.txt is a file that is 2000 bytes in size\n * // file3.txt is a file that is 3000 bytes in size\n * // file4.txt does not exist\n *\n * const fileMap = {\n * f1: 'file1.txt',\n * f2: 'file2.txt',\n * f3: 'file3.txt'\n * };\n *\n * const withMissingFileMap = {\n * f1: 'file1.txt',\n * f2: 'file2.txt',\n * f3: 'file4.txt'\n * };\n *\n * // asynchronous function that returns the file size in bytes\n * function getFileSizeInBytes(file, key, callback) {\n * fs.stat(file, function(err, stat) {\n * if (err) {\n * return callback(err);\n * }\n * callback(null, stat.size);\n * });\n * }\n *\n * // Using callbacks\n * async.mapValues(fileMap, getFileSizeInBytes, function(err, result) {\n * if (err) {\n * console.log(err);\n * } else {\n * console.log(result);\n * // result is now a map of file size in bytes for each file, e.g.\n * // {\n * // f1: 1000,\n * // f2: 2000,\n * // f3: 3000\n * // }\n * }\n * });\n *\n * // Error handling\n * async.mapValues(withMissingFileMap, getFileSizeInBytes, function(err, result) {\n * if (err) {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * } else {\n * console.log(result);\n * }\n * });\n *\n * // Using Promises\n * async.mapValues(fileMap, getFileSizeInBytes)\n * .then( result => {\n * console.log(result);\n * // result is now a map of file size in bytes for each file, e.g.\n * // {\n * // f1: 1000,\n * // f2: 2000,\n * // f3: 3000\n * // }\n * }).catch (err => {\n * console.log(err);\n * });\n *\n * // Error Handling\n * async.mapValues(withMissingFileMap, getFileSizeInBytes)\n * .then( result => {\n * console.log(result);\n * }).catch (err => {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * });\n *\n * // Using async/await\n * async () => {\n * try {\n * let result = await async.mapValues(fileMap, getFileSizeInBytes);\n * console.log(result);\n * // result is now a map of file size in bytes for each file, e.g.\n * // {\n * // f1: 1000,\n * // f2: 2000,\n * // f3: 3000\n * // }\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n * // Error Handling\n * async () => {\n * try {\n * let result = await async.mapValues(withMissingFileMap, getFileSizeInBytes);\n * console.log(result);\n * }\n * catch (err) {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * }\n * }\n *\n */\nfunction mapValues(obj, iteratee, callback) {\n return mapValuesLimit$1(obj, Infinity, iteratee, callback)\n}\n\n/**\n * The same as [`mapValues`]{@link module:Collections.mapValues} but runs only a single async operation at a time.\n *\n * @name mapValuesSeries\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.mapValues]{@link module:Collections.mapValues}\n * @category Collection\n * @param {Object} obj - A collection to iterate over.\n * @param {AsyncFunction} iteratee - A function to apply to each value and key\n * in `coll`.\n * The iteratee should complete with the transformed value as its result.\n * Invoked with (value, key, callback).\n * @param {Function} [callback] - A callback which is called when all `iteratee`\n * functions have finished, or an error occurs. `result` is a new object consisting\n * of each key from `obj`, with each transformed value on the right-hand side.\n * Invoked with (err, result).\n * @returns {Promise} a promise, if no callback is passed\n */\nfunction mapValuesSeries(obj, iteratee, callback) {\n return mapValuesLimit$1(obj, 1, iteratee, callback)\n}\n\n/**\n * Caches the results of an async function. When creating a hash to store\n * function results against, the callback is omitted from the hash and an\n * optional hash function can be used.\n *\n * **Note: if the async function errs, the result will not be cached and\n * subsequent calls will call the wrapped function.**\n *\n * If no hash function is specified, the first argument is used as a hash key,\n * which may work reasonably if it is a string or a data type that converts to a\n * distinct string. Note that objects and arrays will not behave reasonably.\n * Neither will cases where the other arguments are significant. In such cases,\n * specify your own hash function.\n *\n * The cache of results is exposed as the `memo` property of the function\n * returned by `memoize`.\n *\n * @name memoize\n * @static\n * @memberOf module:Utils\n * @method\n * @category Util\n * @param {AsyncFunction} fn - The async function to proxy and cache results from.\n * @param {Function} hasher - An optional function for generating a custom hash\n * for storing results. It has all the arguments applied to it apart from the\n * callback, and must be synchronous.\n * @returns {AsyncFunction} a memoized version of `fn`\n * @example\n *\n * var slow_fn = function(name, callback) {\n * // do something\n * callback(null, result);\n * };\n * var fn = async.memoize(slow_fn);\n *\n * // fn can now be used as if it were slow_fn\n * fn('some name', function() {\n * // callback\n * });\n */\nfunction memoize(fn, hasher = v => v) {\n var memo = Object.create(null);\n var queues = Object.create(null);\n var _fn = wrapAsync(fn);\n var memoized = initialParams((args, callback) => {\n var key = hasher(...args);\n if (key in memo) {\n setImmediate$1(() => callback(null, ...memo[key]));\n } else if (key in queues) {\n queues[key].push(callback);\n } else {\n queues[key] = [callback];\n _fn(...args, (err, ...resultArgs) => {\n // #1465 don't memoize if an error occurred\n if (!err) {\n memo[key] = resultArgs;\n }\n var q = queues[key];\n delete queues[key];\n for (var i = 0, l = q.length; i < l; i++) {\n q[i](err, ...resultArgs);\n }\n });\n }\n });\n memoized.memo = memo;\n memoized.unmemoized = fn;\n return memoized;\n}\n\n/* istanbul ignore file */\n\n/**\n * Calls `callback` on a later loop around the event loop. In Node.js this just\n * calls `process.nextTick`. In the browser it will use `setImmediate` if\n * available, otherwise `setTimeout(callback, 0)`, which means other higher\n * priority events may precede the execution of `callback`.\n *\n * This is used internally for browser-compatibility purposes.\n *\n * @name nextTick\n * @static\n * @memberOf module:Utils\n * @method\n * @see [async.setImmediate]{@link module:Utils.setImmediate}\n * @category Util\n * @param {Function} callback - The function to call on a later loop around\n * the event loop. Invoked with (args...).\n * @param {...*} args... - any number of additional arguments to pass to the\n * callback on the next tick.\n * @example\n *\n * var call_order = [];\n * async.nextTick(function() {\n * call_order.push('two');\n * // call_order now equals ['one','two']\n * });\n * call_order.push('one');\n *\n * async.setImmediate(function (a, b, c) {\n * // a, b, and c equal 1, 2, and 3\n * }, 1, 2, 3);\n */\nvar _defer;\n\nif (hasNextTick) {\n _defer = process.nextTick;\n} else if (hasSetImmediate) {\n _defer = setImmediate;\n} else {\n _defer = fallback;\n}\n\nvar nextTick = wrap(_defer);\n\nvar _parallel = awaitify((eachfn, tasks, callback) => {\n var results = isArrayLike(tasks) ? [] : {};\n\n eachfn(tasks, (task, key, taskCb) => {\n wrapAsync(task)((err, ...result) => {\n if (result.length < 2) {\n [result] = result;\n }\n results[key] = result;\n taskCb(err);\n });\n }, err => callback(err, results));\n}, 3);\n\n/**\n * Run the `tasks` collection of functions in parallel, without waiting until\n * the previous function has completed. If any of the functions pass an error to\n * its callback, the main `callback` is immediately called with the value of the\n * error. Once the `tasks` have completed, the results are passed to the final\n * `callback` as an array.\n *\n * **Note:** `parallel` is about kicking-off I/O tasks in parallel, not about\n * parallel execution of code. If your tasks do not use any timers or perform\n * any I/O, they will actually be executed in series. Any synchronous setup\n * sections for each task will happen one after the other. JavaScript remains\n * single-threaded.\n *\n * **Hint:** Use [`reflect`]{@link module:Utils.reflect} to continue the\n * execution of other tasks when a task fails.\n *\n * It is also possible to use an object instead of an array. Each property will\n * be run as a function and the results will be passed to the final `callback`\n * as an object instead of an array. This can be a more readable way of handling\n * results from {@link async.parallel}.\n *\n * @name parallel\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @category Control Flow\n * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of\n * [async functions]{@link AsyncFunction} to run.\n * Each async function can complete with any number of optional `result` values.\n * @param {Function} [callback] - An optional callback to run once all the\n * functions have completed successfully. This function gets a results array\n * (or object) containing all the result arguments passed to the task callbacks.\n * Invoked with (err, results).\n * @returns {Promise} a promise, if a callback is not passed\n *\n * @example\n *\n * //Using Callbacks\n * async.parallel([\n * function(callback) {\n * setTimeout(function() {\n * callback(null, 'one');\n * }, 200);\n * },\n * function(callback) {\n * setTimeout(function() {\n * callback(null, 'two');\n * }, 100);\n * }\n * ], function(err, results) {\n * console.log(results);\n * // results is equal to ['one','two'] even though\n * // the second function had a shorter timeout.\n * });\n *\n * // an example using an object instead of an array\n * async.parallel({\n * one: function(callback) {\n * setTimeout(function() {\n * callback(null, 1);\n * }, 200);\n * },\n * two: function(callback) {\n * setTimeout(function() {\n * callback(null, 2);\n * }, 100);\n * }\n * }, function(err, results) {\n * console.log(results);\n * // results is equal to: { one: 1, two: 2 }\n * });\n *\n * //Using Promises\n * async.parallel([\n * function(callback) {\n * setTimeout(function() {\n * callback(null, 'one');\n * }, 200);\n * },\n * function(callback) {\n * setTimeout(function() {\n * callback(null, 'two');\n * }, 100);\n * }\n * ]).then(results => {\n * console.log(results);\n * // results is equal to ['one','two'] even though\n * // the second function had a shorter timeout.\n * }).catch(err => {\n * console.log(err);\n * });\n *\n * // an example using an object instead of an array\n * async.parallel({\n * one: function(callback) {\n * setTimeout(function() {\n * callback(null, 1);\n * }, 200);\n * },\n * two: function(callback) {\n * setTimeout(function() {\n * callback(null, 2);\n * }, 100);\n * }\n * }).then(results => {\n * console.log(results);\n * // results is equal to: { one: 1, two: 2 }\n * }).catch(err => {\n * console.log(err);\n * });\n *\n * //Using async/await\n * async () => {\n * try {\n * let results = await async.parallel([\n * function(callback) {\n * setTimeout(function() {\n * callback(null, 'one');\n * }, 200);\n * },\n * function(callback) {\n * setTimeout(function() {\n * callback(null, 'two');\n * }, 100);\n * }\n * ]);\n * console.log(results);\n * // results is equal to ['one','two'] even though\n * // the second function had a shorter timeout.\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n * // an example using an object instead of an array\n * async () => {\n * try {\n * let results = await async.parallel({\n * one: function(callback) {\n * setTimeout(function() {\n * callback(null, 1);\n * }, 200);\n * },\n * two: function(callback) {\n * setTimeout(function() {\n * callback(null, 2);\n * }, 100);\n * }\n * });\n * console.log(results);\n * // results is equal to: { one: 1, two: 2 }\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n */\nfunction parallel(tasks, callback) {\n return _parallel(eachOf$1, tasks, callback);\n}\n\n/**\n * The same as [`parallel`]{@link module:ControlFlow.parallel} but runs a maximum of `limit` async operations at a\n * time.\n *\n * @name parallelLimit\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @see [async.parallel]{@link module:ControlFlow.parallel}\n * @category Control Flow\n * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection of\n * [async functions]{@link AsyncFunction} to run.\n * Each async function can complete with any number of optional `result` values.\n * @param {number} limit - The maximum number of async operations at a time.\n * @param {Function} [callback] - An optional callback to run once all the\n * functions have completed successfully. This function gets a results array\n * (or object) containing all the result arguments passed to the task callbacks.\n * Invoked with (err, results).\n * @returns {Promise} a promise, if a callback is not passed\n */\nfunction parallelLimit(tasks, limit, callback) {\n return _parallel(eachOfLimit$2(limit), tasks, callback);\n}\n\n/**\n * A queue of tasks for the worker function to complete.\n * @typedef {Iterable} QueueObject\n * @memberOf module:ControlFlow\n * @property {Function} length - a function returning the number of items\n * waiting to be processed. Invoke with `queue.length()`.\n * @property {boolean} started - a boolean indicating whether or not any\n * items have been pushed and processed by the queue.\n * @property {Function} running - a function returning the number of items\n * currently being processed. Invoke with `queue.running()`.\n * @property {Function} workersList - a function returning the array of items\n * currently being processed. Invoke with `queue.workersList()`.\n * @property {Function} idle - a function returning false if there are items\n * waiting or being processed, or true if not. Invoke with `queue.idle()`.\n * @property {number} concurrency - an integer for determining how many `worker`\n * functions should be run in parallel. This property can be changed after a\n * `queue` is created to alter the concurrency on-the-fly.\n * @property {number} payload - an integer that specifies how many items are\n * passed to the worker function at a time. only applies if this is a\n * [cargo]{@link module:ControlFlow.cargo} object\n * @property {AsyncFunction} push - add a new task to the `queue`. Calls `callback`\n * once the `worker` has finished processing the task. Instead of a single task,\n * a `tasks` array can be submitted. The respective callback is used for every\n * task in the list. Invoke with `queue.push(task, [callback])`,\n * @property {AsyncFunction} unshift - add a new task to the front of the `queue`.\n * Invoke with `queue.unshift(task, [callback])`.\n * @property {AsyncFunction} pushAsync - the same as `q.push`, except this returns\n * a promise that rejects if an error occurs.\n * @property {AsyncFunction} unshiftAsync - the same as `q.unshift`, except this returns\n * a promise that rejects if an error occurs.\n * @property {Function} remove - remove items from the queue that match a test\n * function. The test function will be passed an object with a `data` property,\n * and a `priority` property, if this is a\n * [priorityQueue]{@link module:ControlFlow.priorityQueue} object.\n * Invoked with `queue.remove(testFn)`, where `testFn` is of the form\n * `function ({data, priority}) {}` and returns a Boolean.\n * @property {Function} saturated - a function that sets a callback that is\n * called when the number of running workers hits the `concurrency` limit, and\n * further tasks will be queued. If the callback is omitted, `q.saturated()`\n * returns a promise for the next occurrence.\n * @property {Function} unsaturated - a function that sets a callback that is\n * called when the number of running workers is less than the `concurrency` &\n * `buffer` limits, and further tasks will not be queued. If the callback is\n * omitted, `q.unsaturated()` returns a promise for the next occurrence.\n * @property {number} buffer - A minimum threshold buffer in order to say that\n * the `queue` is `unsaturated`.\n * @property {Function} empty - a function that sets a callback that is called\n * when the last item from the `queue` is given to a `worker`. If the callback\n * is omitted, `q.empty()` returns a promise for the next occurrence.\n * @property {Function} drain - a function that sets a callback that is called\n * when the last item from the `queue` has returned from the `worker`. If the\n * callback is omitted, `q.drain()` returns a promise for the next occurrence.\n * @property {Function} error - a function that sets a callback that is called\n * when a task errors. Has the signature `function(error, task)`. If the\n * callback is omitted, `error()` returns a promise that rejects on the next\n * error.\n * @property {boolean} paused - a boolean for determining whether the queue is\n * in a paused state.\n * @property {Function} pause - a function that pauses the processing of tasks\n * until `resume()` is called. Invoke with `queue.pause()`.\n * @property {Function} resume - a function that resumes the processing of\n * queued tasks when the queue is paused. Invoke with `queue.resume()`.\n * @property {Function} kill - a function that removes the `drain` callback and\n * empties remaining tasks from the queue forcing it to go idle. No more tasks\n * should be pushed to the queue after calling this function. Invoke with `queue.kill()`.\n *\n * @example\n * const q = async.queue(worker, 2)\n * q.push(item1)\n * q.push(item2)\n * q.push(item3)\n * // queues are iterable, spread into an array to inspect\n * const items = [...q] // [item1, item2, item3]\n * // or use for of\n * for (let item of q) {\n * console.log(item)\n * }\n *\n * q.drain(() => {\n * console.log('all done')\n * })\n * // or\n * await q.drain()\n */\n\n/**\n * Creates a `queue` object with the specified `concurrency`. Tasks added to the\n * `queue` are processed in parallel (up to the `concurrency` limit). If all\n * `worker`s are in progress, the task is queued until one becomes available.\n * Once a `worker` completes a `task`, that `task`'s callback is called.\n *\n * @name queue\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @category Control Flow\n * @param {AsyncFunction} worker - An async function for processing a queued task.\n * If you want to handle errors from an individual task, pass a callback to\n * `q.push()`. Invoked with (task, callback).\n * @param {number} [concurrency=1] - An `integer` for determining how many\n * `worker` functions should be run in parallel. If omitted, the concurrency\n * defaults to `1`. If the concurrency is `0`, an error is thrown.\n * @returns {module:ControlFlow.QueueObject} A queue object to manage the tasks. Callbacks can be\n * attached as certain properties to listen for specific events during the\n * lifecycle of the queue.\n * @example\n *\n * // create a queue object with concurrency 2\n * var q = async.queue(function(task, callback) {\n * console.log('hello ' + task.name);\n * callback();\n * }, 2);\n *\n * // assign a callback\n * q.drain(function() {\n * console.log('all items have been processed');\n * });\n * // or await the end\n * await q.drain()\n *\n * // assign an error callback\n * q.error(function(err, task) {\n * console.error('task experienced an error');\n * });\n *\n * // add some items to the queue\n * q.push({name: 'foo'}, function(err) {\n * console.log('finished processing foo');\n * });\n * // callback is optional\n * q.push({name: 'bar'});\n *\n * // add some items to the queue (batch-wise)\n * q.push([{name: 'baz'},{name: 'bay'},{name: 'bax'}], function(err) {\n * console.log('finished processing item');\n * });\n *\n * // add some items to the front of the queue\n * q.unshift({name: 'bar'}, function (err) {\n * console.log('finished processing bar');\n * });\n */\nfunction queue (worker, concurrency) {\n var _worker = wrapAsync(worker);\n return queue$1((items, cb) => {\n _worker(items[0], cb);\n }, concurrency, 1);\n}\n\n// Binary min-heap implementation used for priority queue.\n// Implementation is stable, i.e. push time is considered for equal priorities\nclass Heap {\n constructor() {\n this.heap = [];\n this.pushCount = Number.MIN_SAFE_INTEGER;\n }\n\n get length() {\n return this.heap.length;\n }\n\n empty () {\n this.heap = [];\n return this;\n }\n\n percUp(index) {\n let p;\n\n while (index > 0 && smaller(this.heap[index], this.heap[p=parent(index)])) {\n let t = this.heap[index];\n this.heap[index] = this.heap[p];\n this.heap[p] = t;\n\n index = p;\n }\n }\n\n percDown(index) {\n let l;\n\n while ((l=leftChi(index)) < this.heap.length) {\n if (l+1 < this.heap.length && smaller(this.heap[l+1], this.heap[l])) {\n l = l+1;\n }\n\n if (smaller(this.heap[index], this.heap[l])) {\n break;\n }\n\n let t = this.heap[index];\n this.heap[index] = this.heap[l];\n this.heap[l] = t;\n\n index = l;\n }\n }\n\n push(node) {\n node.pushCount = ++this.pushCount;\n this.heap.push(node);\n this.percUp(this.heap.length-1);\n }\n\n unshift(node) {\n return this.heap.push(node);\n }\n\n shift() {\n let [top] = this.heap;\n\n this.heap[0] = this.heap[this.heap.length-1];\n this.heap.pop();\n this.percDown(0);\n\n return top;\n }\n\n toArray() {\n return [...this];\n }\n\n *[Symbol.iterator] () {\n for (let i = 0; i < this.heap.length; i++) {\n yield this.heap[i].data;\n }\n }\n\n remove (testFn) {\n let j = 0;\n for (let i = 0; i < this.heap.length; i++) {\n if (!testFn(this.heap[i])) {\n this.heap[j] = this.heap[i];\n j++;\n }\n }\n\n this.heap.splice(j);\n\n for (let i = parent(this.heap.length-1); i >= 0; i--) {\n this.percDown(i);\n }\n\n return this;\n }\n}\n\nfunction leftChi(i) {\n return (i<<1)+1;\n}\n\nfunction parent(i) {\n return ((i+1)>>1)-1;\n}\n\nfunction smaller(x, y) {\n if (x.priority !== y.priority) {\n return x.priority < y.priority;\n }\n else {\n return x.pushCount < y.pushCount;\n }\n}\n\n/**\n * The same as [async.queue]{@link module:ControlFlow.queue} only tasks are assigned a priority and\n * completed in ascending priority order.\n *\n * @name priorityQueue\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @see [async.queue]{@link module:ControlFlow.queue}\n * @category Control Flow\n * @param {AsyncFunction} worker - An async function for processing a queued task.\n * If you want to handle errors from an individual task, pass a callback to\n * `q.push()`.\n * Invoked with (task, callback).\n * @param {number} concurrency - An `integer` for determining how many `worker`\n * functions should be run in parallel. If omitted, the concurrency defaults to\n * `1`. If the concurrency is `0`, an error is thrown.\n * @returns {module:ControlFlow.QueueObject} A priorityQueue object to manage the tasks. There are three\n * differences between `queue` and `priorityQueue` objects:\n * * `push(task, priority, [callback])` - `priority` should be a number. If an\n * array of `tasks` is given, all tasks will be assigned the same priority.\n * * `pushAsync(task, priority, [callback])` - the same as `priorityQueue.push`,\n * except this returns a promise that rejects if an error occurs.\n * * The `unshift` and `unshiftAsync` methods were removed.\n */\nfunction priorityQueue(worker, concurrency) {\n // Start with a normal queue\n var q = queue(worker, concurrency);\n\n var {\n push,\n pushAsync\n } = q;\n\n q._tasks = new Heap();\n q._createTaskItem = ({data, priority}, callback) => {\n return {\n data,\n priority,\n callback\n };\n };\n\n function createDataItems(tasks, priority) {\n if (!Array.isArray(tasks)) {\n return {data: tasks, priority};\n }\n return tasks.map(data => { return {data, priority}; });\n }\n\n // Override push to accept second parameter representing priority\n q.push = function(data, priority = 0, callback) {\n return push(createDataItems(data, priority), callback);\n };\n\n q.pushAsync = function(data, priority = 0, callback) {\n return pushAsync(createDataItems(data, priority), callback);\n };\n\n // Remove unshift functions\n delete q.unshift;\n delete q.unshiftAsync;\n\n return q;\n}\n\n/**\n * Runs the `tasks` array of functions in parallel, without waiting until the\n * previous function has completed. Once any of the `tasks` complete or pass an\n * error to its callback, the main `callback` is immediately called. It's\n * equivalent to `Promise.race()`.\n *\n * @name race\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @category Control Flow\n * @param {Array} tasks - An array containing [async functions]{@link AsyncFunction}\n * to run. Each function can complete with an optional `result` value.\n * @param {Function} callback - A callback to run once any of the functions have\n * completed. This function gets an error or result from the first function that\n * completed. Invoked with (err, result).\n * @returns {Promise} a promise, if a callback is omitted\n * @example\n *\n * async.race([\n * function(callback) {\n * setTimeout(function() {\n * callback(null, 'one');\n * }, 200);\n * },\n * function(callback) {\n * setTimeout(function() {\n * callback(null, 'two');\n * }, 100);\n * }\n * ],\n * // main callback\n * function(err, result) {\n * // the result will be equal to 'two' as it finishes earlier\n * });\n */\nfunction race(tasks, callback) {\n callback = once(callback);\n if (!Array.isArray(tasks)) return callback(new TypeError('First argument to race must be an array of functions'));\n if (!tasks.length) return callback();\n for (var i = 0, l = tasks.length; i < l; i++) {\n wrapAsync(tasks[i])(callback);\n }\n}\n\nvar race$1 = awaitify(race, 2);\n\n/**\n * Same as [`reduce`]{@link module:Collections.reduce}, only operates on `array` in reverse order.\n *\n * @name reduceRight\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.reduce]{@link module:Collections.reduce}\n * @alias foldr\n * @category Collection\n * @param {Array} array - A collection to iterate over.\n * @param {*} memo - The initial state of the reduction.\n * @param {AsyncFunction} iteratee - A function applied to each item in the\n * array to produce the next step in the reduction.\n * The `iteratee` should complete with the next state of the reduction.\n * If the iteratee completes with an error, the reduction is stopped and the\n * main `callback` is immediately called with the error.\n * Invoked with (memo, item, callback).\n * @param {Function} [callback] - A callback which is called after all the\n * `iteratee` functions have finished. Result is the reduced value. Invoked with\n * (err, result).\n * @returns {Promise} a promise, if no callback is passed\n */\nfunction reduceRight (array, memo, iteratee, callback) {\n var reversed = [...array].reverse();\n return reduce$1(reversed, memo, iteratee, callback);\n}\n\n/**\n * Wraps the async function in another function that always completes with a\n * result object, even when it errors.\n *\n * The result object has either the property `error` or `value`.\n *\n * @name reflect\n * @static\n * @memberOf module:Utils\n * @method\n * @category Util\n * @param {AsyncFunction} fn - The async function you want to wrap\n * @returns {Function} - A function that always passes null to it's callback as\n * the error. The second argument to the callback will be an `object` with\n * either an `error` or a `value` property.\n * @example\n *\n * async.parallel([\n * async.reflect(function(callback) {\n * // do some stuff ...\n * callback(null, 'one');\n * }),\n * async.reflect(function(callback) {\n * // do some more stuff but error ...\n * callback('bad stuff happened');\n * }),\n * async.reflect(function(callback) {\n * // do some more stuff ...\n * callback(null, 'two');\n * })\n * ],\n * // optional callback\n * function(err, results) {\n * // values\n * // results[0].value = 'one'\n * // results[1].error = 'bad stuff happened'\n * // results[2].value = 'two'\n * });\n */\nfunction reflect(fn) {\n var _fn = wrapAsync(fn);\n return initialParams(function reflectOn(args, reflectCallback) {\n args.push((error, ...cbArgs) => {\n let retVal = {};\n if (error) {\n retVal.error = error;\n }\n if (cbArgs.length > 0){\n var value = cbArgs;\n if (cbArgs.length <= 1) {\n [value] = cbArgs;\n }\n retVal.value = value;\n }\n reflectCallback(null, retVal);\n });\n\n return _fn.apply(this, args);\n });\n}\n\n/**\n * A helper function that wraps an array or an object of functions with `reflect`.\n *\n * @name reflectAll\n * @static\n * @memberOf module:Utils\n * @method\n * @see [async.reflect]{@link module:Utils.reflect}\n * @category Util\n * @param {Array|Object|Iterable} tasks - The collection of\n * [async functions]{@link AsyncFunction} to wrap in `async.reflect`.\n * @returns {Array} Returns an array of async functions, each wrapped in\n * `async.reflect`\n * @example\n *\n * let tasks = [\n * function(callback) {\n * setTimeout(function() {\n * callback(null, 'one');\n * }, 200);\n * },\n * function(callback) {\n * // do some more stuff but error ...\n * callback(new Error('bad stuff happened'));\n * },\n * function(callback) {\n * setTimeout(function() {\n * callback(null, 'two');\n * }, 100);\n * }\n * ];\n *\n * async.parallel(async.reflectAll(tasks),\n * // optional callback\n * function(err, results) {\n * // values\n * // results[0].value = 'one'\n * // results[1].error = Error('bad stuff happened')\n * // results[2].value = 'two'\n * });\n *\n * // an example using an object instead of an array\n * let tasks = {\n * one: function(callback) {\n * setTimeout(function() {\n * callback(null, 'one');\n * }, 200);\n * },\n * two: function(callback) {\n * callback('two');\n * },\n * three: function(callback) {\n * setTimeout(function() {\n * callback(null, 'three');\n * }, 100);\n * }\n * };\n *\n * async.parallel(async.reflectAll(tasks),\n * // optional callback\n * function(err, results) {\n * // values\n * // results.one.value = 'one'\n * // results.two.error = 'two'\n * // results.three.value = 'three'\n * });\n */\nfunction reflectAll(tasks) {\n var results;\n if (Array.isArray(tasks)) {\n results = tasks.map(reflect);\n } else {\n results = {};\n Object.keys(tasks).forEach(key => {\n results[key] = reflect.call(this, tasks[key]);\n });\n }\n return results;\n}\n\nfunction reject$2(eachfn, arr, _iteratee, callback) {\n const iteratee = wrapAsync(_iteratee);\n return _filter(eachfn, arr, (value, cb) => {\n iteratee(value, (err, v) => {\n cb(err, !v);\n });\n }, callback);\n}\n\n/**\n * The opposite of [`filter`]{@link module:Collections.filter}. Removes values that pass an `async` truth test.\n *\n * @name reject\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.filter]{@link module:Collections.filter}\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {Function} iteratee - An async truth test to apply to each item in\n * `coll`.\n * The should complete with a boolean value as its `result`.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called after all the\n * `iteratee` functions have finished. Invoked with (err, results).\n * @returns {Promise} a promise, if no callback is passed\n * @example\n *\n * // dir1 is a directory that contains file1.txt, file2.txt\n * // dir2 is a directory that contains file3.txt, file4.txt\n * // dir3 is a directory that contains file5.txt\n *\n * const fileList = ['dir1/file1.txt','dir2/file3.txt','dir3/file6.txt'];\n *\n * // asynchronous function that checks if a file exists\n * function fileExists(file, callback) {\n * fs.access(file, fs.constants.F_OK, (err) => {\n * callback(null, !err);\n * });\n * }\n *\n * // Using callbacks\n * async.reject(fileList, fileExists, function(err, results) {\n * // [ 'dir3/file6.txt' ]\n * // results now equals an array of the non-existing files\n * });\n *\n * // Using Promises\n * async.reject(fileList, fileExists)\n * .then( results => {\n * console.log(results);\n * // [ 'dir3/file6.txt' ]\n * // results now equals an array of the non-existing files\n * }).catch( err => {\n * console.log(err);\n * });\n *\n * // Using async/await\n * async () => {\n * try {\n * let results = await async.reject(fileList, fileExists);\n * console.log(results);\n * // [ 'dir3/file6.txt' ]\n * // results now equals an array of the non-existing files\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n */\nfunction reject (coll, iteratee, callback) {\n return reject$2(eachOf$1, coll, iteratee, callback)\n}\nvar reject$1 = awaitify(reject, 3);\n\n/**\n * The same as [`reject`]{@link module:Collections.reject} but runs a maximum of `limit` async operations at a\n * time.\n *\n * @name rejectLimit\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.reject]{@link module:Collections.reject}\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {number} limit - The maximum number of async operations at a time.\n * @param {Function} iteratee - An async truth test to apply to each item in\n * `coll`.\n * The should complete with a boolean value as its `result`.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called after all the\n * `iteratee` functions have finished. Invoked with (err, results).\n * @returns {Promise} a promise, if no callback is passed\n */\nfunction rejectLimit (coll, limit, iteratee, callback) {\n return reject$2(eachOfLimit$2(limit), coll, iteratee, callback)\n}\nvar rejectLimit$1 = awaitify(rejectLimit, 4);\n\n/**\n * The same as [`reject`]{@link module:Collections.reject} but runs only a single async operation at a time.\n *\n * @name rejectSeries\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.reject]{@link module:Collections.reject}\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {Function} iteratee - An async truth test to apply to each item in\n * `coll`.\n * The should complete with a boolean value as its `result`.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called after all the\n * `iteratee` functions have finished. Invoked with (err, results).\n * @returns {Promise} a promise, if no callback is passed\n */\nfunction rejectSeries (coll, iteratee, callback) {\n return reject$2(eachOfSeries$1, coll, iteratee, callback)\n}\nvar rejectSeries$1 = awaitify(rejectSeries, 3);\n\nfunction constant(value) {\n return function () {\n return value;\n }\n}\n\n/**\n * Attempts to get a successful response from `task` no more than `times` times\n * before returning an error. If the task is successful, the `callback` will be\n * passed the result of the successful task. If all attempts fail, the callback\n * will be passed the error and result (if any) of the final attempt.\n *\n * @name retry\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @category Control Flow\n * @see [async.retryable]{@link module:ControlFlow.retryable}\n * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - Can be either an\n * object with `times` and `interval` or a number.\n * * `times` - The number of attempts to make before giving up. The default\n * is `5`.\n * * `interval` - The time to wait between retries, in milliseconds. The\n * default is `0`. The interval may also be specified as a function of the\n * retry count (see example).\n * * `errorFilter` - An optional synchronous function that is invoked on\n * erroneous result. If it returns `true` the retry attempts will continue;\n * if the function returns `false` the retry flow is aborted with the current\n * attempt's error and result being returned to the final callback.\n * Invoked with (err).\n * * If `opts` is a number, the number specifies the number of times to retry,\n * with the default interval of `0`.\n * @param {AsyncFunction} task - An async function to retry.\n * Invoked with (callback).\n * @param {Function} [callback] - An optional callback which is called when the\n * task has succeeded, or after the final failed attempt. It receives the `err`\n * and `result` arguments of the last attempt at completing the `task`. Invoked\n * with (err, results).\n * @returns {Promise} a promise if no callback provided\n *\n * @example\n *\n * // The `retry` function can be used as a stand-alone control flow by passing\n * // a callback, as shown below:\n *\n * // try calling apiMethod 3 times\n * async.retry(3, apiMethod, function(err, result) {\n * // do something with the result\n * });\n *\n * // try calling apiMethod 3 times, waiting 200 ms between each retry\n * async.retry({times: 3, interval: 200}, apiMethod, function(err, result) {\n * // do something with the result\n * });\n *\n * // try calling apiMethod 10 times with exponential backoff\n * // (i.e. intervals of 100, 200, 400, 800, 1600, ... milliseconds)\n * async.retry({\n * times: 10,\n * interval: function(retryCount) {\n * return 50 * Math.pow(2, retryCount);\n * }\n * }, apiMethod, function(err, result) {\n * // do something with the result\n * });\n *\n * // try calling apiMethod the default 5 times no delay between each retry\n * async.retry(apiMethod, function(err, result) {\n * // do something with the result\n * });\n *\n * // try calling apiMethod only when error condition satisfies, all other\n * // errors will abort the retry control flow and return to final callback\n * async.retry({\n * errorFilter: function(err) {\n * return err.message === 'Temporary error'; // only retry on a specific error\n * }\n * }, apiMethod, function(err, result) {\n * // do something with the result\n * });\n *\n * // to retry individual methods that are not as reliable within other\n * // control flow functions, use the `retryable` wrapper:\n * async.auto({\n * users: api.getUsers.bind(api),\n * payments: async.retryable(3, api.getPayments.bind(api))\n * }, function(err, results) {\n * // do something with the results\n * });\n *\n */\nconst DEFAULT_TIMES = 5;\nconst DEFAULT_INTERVAL = 0;\n\nfunction retry(opts, task, callback) {\n var options = {\n times: DEFAULT_TIMES,\n intervalFunc: constant(DEFAULT_INTERVAL)\n };\n\n if (arguments.length < 3 && typeof opts === 'function') {\n callback = task || promiseCallback();\n task = opts;\n } else {\n parseTimes(options, opts);\n callback = callback || promiseCallback();\n }\n\n if (typeof task !== 'function') {\n throw new Error(\"Invalid arguments for async.retry\");\n }\n\n var _task = wrapAsync(task);\n\n var attempt = 1;\n function retryAttempt() {\n _task((err, ...args) => {\n if (err === false) return\n if (err && attempt++ < options.times &&\n (typeof options.errorFilter != 'function' ||\n options.errorFilter(err))) {\n setTimeout(retryAttempt, options.intervalFunc(attempt - 1));\n } else {\n callback(err, ...args);\n }\n });\n }\n\n retryAttempt();\n return callback[PROMISE_SYMBOL]\n}\n\nfunction parseTimes(acc, t) {\n if (typeof t === 'object') {\n acc.times = +t.times || DEFAULT_TIMES;\n\n acc.intervalFunc = typeof t.interval === 'function' ?\n t.interval :\n constant(+t.interval || DEFAULT_INTERVAL);\n\n acc.errorFilter = t.errorFilter;\n } else if (typeof t === 'number' || typeof t === 'string') {\n acc.times = +t || DEFAULT_TIMES;\n } else {\n throw new Error(\"Invalid arguments for async.retry\");\n }\n}\n\n/**\n * A close relative of [`retry`]{@link module:ControlFlow.retry}. This method\n * wraps a task and makes it retryable, rather than immediately calling it\n * with retries.\n *\n * @name retryable\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @see [async.retry]{@link module:ControlFlow.retry}\n * @category Control Flow\n * @param {Object|number} [opts = {times: 5, interval: 0}| 5] - optional\n * options, exactly the same as from `retry`, except for a `opts.arity` that\n * is the arity of the `task` function, defaulting to `task.length`\n * @param {AsyncFunction} task - the asynchronous function to wrap.\n * This function will be passed any arguments passed to the returned wrapper.\n * Invoked with (...args, callback).\n * @returns {AsyncFunction} The wrapped function, which when invoked, will\n * retry on an error, based on the parameters specified in `opts`.\n * This function will accept the same parameters as `task`.\n * @example\n *\n * async.auto({\n * dep1: async.retryable(3, getFromFlakyService),\n * process: [\"dep1\", async.retryable(3, function (results, cb) {\n * maybeProcessData(results.dep1, cb);\n * })]\n * }, callback);\n */\nfunction retryable (opts, task) {\n if (!task) {\n task = opts;\n opts = null;\n }\n let arity = (opts && opts.arity) || task.length;\n if (isAsync(task)) {\n arity += 1;\n }\n var _task = wrapAsync(task);\n return initialParams((args, callback) => {\n if (args.length < arity - 1 || callback == null) {\n args.push(callback);\n callback = promiseCallback();\n }\n function taskFn(cb) {\n _task(...args, cb);\n }\n\n if (opts) retry(opts, taskFn, callback);\n else retry(taskFn, callback);\n\n return callback[PROMISE_SYMBOL]\n });\n}\n\n/**\n * Run the functions in the `tasks` collection in series, each one running once\n * the previous function has completed. If any functions in the series pass an\n * error to its callback, no more functions are run, and `callback` is\n * immediately called with the value of the error. Otherwise, `callback`\n * receives an array of results when `tasks` have completed.\n *\n * It is also possible to use an object instead of an array. Each property will\n * be run as a function, and the results will be passed to the final `callback`\n * as an object instead of an array. This can be a more readable way of handling\n * results from {@link async.series}.\n *\n * **Note** that while many implementations preserve the order of object\n * properties, the [ECMAScript Language Specification](http://www.ecma-international.org/ecma-262/5.1/#sec-8.6)\n * explicitly states that\n *\n * > The mechanics and order of enumerating the properties is not specified.\n *\n * So if you rely on the order in which your series of functions are executed,\n * and want this to work on all platforms, consider using an array.\n *\n * @name series\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @category Control Flow\n * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing\n * [async functions]{@link AsyncFunction} to run in series.\n * Each function can complete with any number of optional `result` values.\n * @param {Function} [callback] - An optional callback to run once all the\n * functions have completed. This function gets a results array (or object)\n * containing all the result arguments passed to the `task` callbacks. Invoked\n * with (err, result).\n * @return {Promise} a promise, if no callback is passed\n * @example\n *\n * //Using Callbacks\n * async.series([\n * function(callback) {\n * setTimeout(function() {\n * // do some async task\n * callback(null, 'one');\n * }, 200);\n * },\n * function(callback) {\n * setTimeout(function() {\n * // then do another async task\n * callback(null, 'two');\n * }, 100);\n * }\n * ], function(err, results) {\n * console.log(results);\n * // results is equal to ['one','two']\n * });\n *\n * // an example using objects instead of arrays\n * async.series({\n * one: function(callback) {\n * setTimeout(function() {\n * // do some async task\n * callback(null, 1);\n * }, 200);\n * },\n * two: function(callback) {\n * setTimeout(function() {\n * // then do another async task\n * callback(null, 2);\n * }, 100);\n * }\n * }, function(err, results) {\n * console.log(results);\n * // results is equal to: { one: 1, two: 2 }\n * });\n *\n * //Using Promises\n * async.series([\n * function(callback) {\n * setTimeout(function() {\n * callback(null, 'one');\n * }, 200);\n * },\n * function(callback) {\n * setTimeout(function() {\n * callback(null, 'two');\n * }, 100);\n * }\n * ]).then(results => {\n * console.log(results);\n * // results is equal to ['one','two']\n * }).catch(err => {\n * console.log(err);\n * });\n *\n * // an example using an object instead of an array\n * async.series({\n * one: function(callback) {\n * setTimeout(function() {\n * // do some async task\n * callback(null, 1);\n * }, 200);\n * },\n * two: function(callback) {\n * setTimeout(function() {\n * // then do another async task\n * callback(null, 2);\n * }, 100);\n * }\n * }).then(results => {\n * console.log(results);\n * // results is equal to: { one: 1, two: 2 }\n * }).catch(err => {\n * console.log(err);\n * });\n *\n * //Using async/await\n * async () => {\n * try {\n * let results = await async.series([\n * function(callback) {\n * setTimeout(function() {\n * // do some async task\n * callback(null, 'one');\n * }, 200);\n * },\n * function(callback) {\n * setTimeout(function() {\n * // then do another async task\n * callback(null, 'two');\n * }, 100);\n * }\n * ]);\n * console.log(results);\n * // results is equal to ['one','two']\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n * // an example using an object instead of an array\n * async () => {\n * try {\n * let results = await async.parallel({\n * one: function(callback) {\n * setTimeout(function() {\n * // do some async task\n * callback(null, 1);\n * }, 200);\n * },\n * two: function(callback) {\n * setTimeout(function() {\n * // then do another async task\n * callback(null, 2);\n * }, 100);\n * }\n * });\n * console.log(results);\n * // results is equal to: { one: 1, two: 2 }\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n */\nfunction series(tasks, callback) {\n return _parallel(eachOfSeries$1, tasks, callback);\n}\n\n/**\n * Returns `true` if at least one element in the `coll` satisfies an async test.\n * If any iteratee call returns `true`, the main `callback` is immediately\n * called.\n *\n * @name some\n * @static\n * @memberOf module:Collections\n * @method\n * @alias any\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - An async truth test to apply to each item\n * in the collections in parallel.\n * The iteratee should complete with a boolean `result` value.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called as soon as any\n * iteratee returns `true`, or after all the iteratee functions have finished.\n * Result will be either `true` or `false` depending on the values of the async\n * tests. Invoked with (err, result).\n * @returns {Promise} a promise, if no callback provided\n * @example\n *\n * // dir1 is a directory that contains file1.txt, file2.txt\n * // dir2 is a directory that contains file3.txt, file4.txt\n * // dir3 is a directory that contains file5.txt\n * // dir4 does not exist\n *\n * // asynchronous function that checks if a file exists\n * function fileExists(file, callback) {\n * fs.access(file, fs.constants.F_OK, (err) => {\n * callback(null, !err);\n * });\n * }\n *\n * // Using callbacks\n * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists,\n * function(err, result) {\n * console.log(result);\n * // true\n * // result is true since some file in the list exists\n * }\n *);\n *\n * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists,\n * function(err, result) {\n * console.log(result);\n * // false\n * // result is false since none of the files exists\n * }\n *);\n *\n * // Using Promises\n * async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists)\n * .then( result => {\n * console.log(result);\n * // true\n * // result is true since some file in the list exists\n * }).catch( err => {\n * console.log(err);\n * });\n *\n * async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists)\n * .then( result => {\n * console.log(result);\n * // false\n * // result is false since none of the files exists\n * }).catch( err => {\n * console.log(err);\n * });\n *\n * // Using async/await\n * async () => {\n * try {\n * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir3/file5.txt'], fileExists);\n * console.log(result);\n * // true\n * // result is true since some file in the list exists\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n * async () => {\n * try {\n * let result = await async.some(['dir1/missing.txt','dir2/missing.txt','dir4/missing.txt'], fileExists);\n * console.log(result);\n * // false\n * // result is false since none of the files exists\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n */\nfunction some(coll, iteratee, callback) {\n return _createTester(Boolean, res => res)(eachOf$1, coll, iteratee, callback)\n}\nvar some$1 = awaitify(some, 3);\n\n/**\n * The same as [`some`]{@link module:Collections.some} but runs a maximum of `limit` async operations at a time.\n *\n * @name someLimit\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.some]{@link module:Collections.some}\n * @alias anyLimit\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {number} limit - The maximum number of async operations at a time.\n * @param {AsyncFunction} iteratee - An async truth test to apply to each item\n * in the collections in parallel.\n * The iteratee should complete with a boolean `result` value.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called as soon as any\n * iteratee returns `true`, or after all the iteratee functions have finished.\n * Result will be either `true` or `false` depending on the values of the async\n * tests. Invoked with (err, result).\n * @returns {Promise} a promise, if no callback provided\n */\nfunction someLimit(coll, limit, iteratee, callback) {\n return _createTester(Boolean, res => res)(eachOfLimit$2(limit), coll, iteratee, callback)\n}\nvar someLimit$1 = awaitify(someLimit, 4);\n\n/**\n * The same as [`some`]{@link module:Collections.some} but runs only a single async operation at a time.\n *\n * @name someSeries\n * @static\n * @memberOf module:Collections\n * @method\n * @see [async.some]{@link module:Collections.some}\n * @alias anySeries\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - An async truth test to apply to each item\n * in the collections in series.\n * The iteratee should complete with a boolean `result` value.\n * Invoked with (item, callback).\n * @param {Function} [callback] - A callback which is called as soon as any\n * iteratee returns `true`, or after all the iteratee functions have finished.\n * Result will be either `true` or `false` depending on the values of the async\n * tests. Invoked with (err, result).\n * @returns {Promise} a promise, if no callback provided\n */\nfunction someSeries(coll, iteratee, callback) {\n return _createTester(Boolean, res => res)(eachOfSeries$1, coll, iteratee, callback)\n}\nvar someSeries$1 = awaitify(someSeries, 3);\n\n/**\n * Sorts a list by the results of running each `coll` value through an async\n * `iteratee`.\n *\n * @name sortBy\n * @static\n * @memberOf module:Collections\n * @method\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {AsyncFunction} iteratee - An async function to apply to each item in\n * `coll`.\n * The iteratee should complete with a value to use as the sort criteria as\n * its `result`.\n * Invoked with (item, callback).\n * @param {Function} callback - A callback which is called after all the\n * `iteratee` functions have finished, or an error occurs. Results is the items\n * from the original `coll` sorted by the values returned by the `iteratee`\n * calls. Invoked with (err, results).\n * @returns {Promise} a promise, if no callback passed\n * @example\n *\n * // bigfile.txt is a file that is 251100 bytes in size\n * // mediumfile.txt is a file that is 11000 bytes in size\n * // smallfile.txt is a file that is 121 bytes in size\n *\n * // asynchronous function that returns the file size in bytes\n * function getFileSizeInBytes(file, callback) {\n * fs.stat(file, function(err, stat) {\n * if (err) {\n * return callback(err);\n * }\n * callback(null, stat.size);\n * });\n * }\n *\n * // Using callbacks\n * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes,\n * function(err, results) {\n * if (err) {\n * console.log(err);\n * } else {\n * console.log(results);\n * // results is now the original array of files sorted by\n * // file size (ascending by default), e.g.\n * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']\n * }\n * }\n * );\n *\n * // By modifying the callback parameter the\n * // sorting order can be influenced:\n *\n * // ascending order\n * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], function(file, callback) {\n * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {\n * if (getFileSizeErr) return callback(getFileSizeErr);\n * callback(null, fileSize);\n * });\n * }, function(err, results) {\n * if (err) {\n * console.log(err);\n * } else {\n * console.log(results);\n * // results is now the original array of files sorted by\n * // file size (ascending by default), e.g.\n * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']\n * }\n * }\n * );\n *\n * // descending order\n * async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], function(file, callback) {\n * getFileSizeInBytes(file, function(getFileSizeErr, fileSize) {\n * if (getFileSizeErr) {\n * return callback(getFileSizeErr);\n * }\n * callback(null, fileSize * -1);\n * });\n * }, function(err, results) {\n * if (err) {\n * console.log(err);\n * } else {\n * console.log(results);\n * // results is now the original array of files sorted by\n * // file size (ascending by default), e.g.\n * // [ 'bigfile.txt', 'mediumfile.txt', 'smallfile.txt']\n * }\n * }\n * );\n *\n * // Error handling\n * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes,\n * function(err, results) {\n * if (err) {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * } else {\n * console.log(results);\n * }\n * }\n * );\n *\n * // Using Promises\n * async.sortBy(['mediumfile.txt','smallfile.txt','bigfile.txt'], getFileSizeInBytes)\n * .then( results => {\n * console.log(results);\n * // results is now the original array of files sorted by\n * // file size (ascending by default), e.g.\n * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']\n * }).catch( err => {\n * console.log(err);\n * });\n *\n * // Error handling\n * async.sortBy(['mediumfile.txt','smallfile.txt','missingfile.txt'], getFileSizeInBytes)\n * .then( results => {\n * console.log(results);\n * }).catch( err => {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * });\n *\n * // Using async/await\n * (async () => {\n * try {\n * let results = await async.sortBy(['bigfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);\n * console.log(results);\n * // results is now the original array of files sorted by\n * // file size (ascending by default), e.g.\n * // [ 'smallfile.txt', 'mediumfile.txt', 'bigfile.txt']\n * }\n * catch (err) {\n * console.log(err);\n * }\n * })();\n *\n * // Error handling\n * async () => {\n * try {\n * let results = await async.sortBy(['missingfile.txt','mediumfile.txt','smallfile.txt'], getFileSizeInBytes);\n * console.log(results);\n * }\n * catch (err) {\n * console.log(err);\n * // [ Error: ENOENT: no such file or directory ]\n * }\n * }\n *\n */\nfunction sortBy (coll, iteratee, callback) {\n var _iteratee = wrapAsync(iteratee);\n return map$1(coll, (x, iterCb) => {\n _iteratee(x, (err, criteria) => {\n if (err) return iterCb(err);\n iterCb(err, {value: x, criteria});\n });\n }, (err, results) => {\n if (err) return callback(err);\n callback(null, results.sort(comparator).map(v => v.value));\n });\n\n function comparator(left, right) {\n var a = left.criteria, b = right.criteria;\n return a < b ? -1 : a > b ? 1 : 0;\n }\n}\nvar sortBy$1 = awaitify(sortBy, 3);\n\n/**\n * Sets a time limit on an asynchronous function. If the function does not call\n * its callback within the specified milliseconds, it will be called with a\n * timeout error. The code property for the error object will be `'ETIMEDOUT'`.\n *\n * @name timeout\n * @static\n * @memberOf module:Utils\n * @method\n * @category Util\n * @param {AsyncFunction} asyncFn - The async function to limit in time.\n * @param {number} milliseconds - The specified time limit.\n * @param {*} [info] - Any variable you want attached (`string`, `object`, etc)\n * to timeout Error for more information..\n * @returns {AsyncFunction} Returns a wrapped function that can be used with any\n * of the control flow functions.\n * Invoke this function with the same parameters as you would `asyncFunc`.\n * @example\n *\n * function myFunction(foo, callback) {\n * doAsyncTask(foo, function(err, data) {\n * // handle errors\n * if (err) return callback(err);\n *\n * // do some stuff ...\n *\n * // return processed data\n * return callback(null, data);\n * });\n * }\n *\n * var wrapped = async.timeout(myFunction, 1000);\n *\n * // call `wrapped` as you would `myFunction`\n * wrapped({ bar: 'bar' }, function(err, data) {\n * // if `myFunction` takes < 1000 ms to execute, `err`\n * // and `data` will have their expected values\n *\n * // else `err` will be an Error with the code 'ETIMEDOUT'\n * });\n */\nfunction timeout(asyncFn, milliseconds, info) {\n var fn = wrapAsync(asyncFn);\n\n return initialParams((args, callback) => {\n var timedOut = false;\n var timer;\n\n function timeoutCallback() {\n var name = asyncFn.name || 'anonymous';\n var error = new Error('Callback function \"' + name + '\" timed out.');\n error.code = 'ETIMEDOUT';\n if (info) {\n error.info = info;\n }\n timedOut = true;\n callback(error);\n }\n\n args.push((...cbArgs) => {\n if (!timedOut) {\n callback(...cbArgs);\n clearTimeout(timer);\n }\n });\n\n // setup timer and call original function\n timer = setTimeout(timeoutCallback, milliseconds);\n fn(...args);\n });\n}\n\nfunction range(size) {\n var result = Array(size);\n while (size--) {\n result[size] = size;\n }\n return result;\n}\n\n/**\n * The same as [times]{@link module:ControlFlow.times} but runs a maximum of `limit` async operations at a\n * time.\n *\n * @name timesLimit\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @see [async.times]{@link module:ControlFlow.times}\n * @category Control Flow\n * @param {number} count - The number of times to run the function.\n * @param {number} limit - The maximum number of async operations at a time.\n * @param {AsyncFunction} iteratee - The async function to call `n` times.\n * Invoked with the iteration index and a callback: (n, next).\n * @param {Function} callback - see [async.map]{@link module:Collections.map}.\n * @returns {Promise} a promise, if no callback is provided\n */\nfunction timesLimit(count, limit, iteratee, callback) {\n var _iteratee = wrapAsync(iteratee);\n return mapLimit$1(range(count), limit, _iteratee, callback);\n}\n\n/**\n * Calls the `iteratee` function `n` times, and accumulates results in the same\n * manner you would use with [map]{@link module:Collections.map}.\n *\n * @name times\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @see [async.map]{@link module:Collections.map}\n * @category Control Flow\n * @param {number} n - The number of times to run the function.\n * @param {AsyncFunction} iteratee - The async function to call `n` times.\n * Invoked with the iteration index and a callback: (n, next).\n * @param {Function} callback - see {@link module:Collections.map}.\n * @returns {Promise} a promise, if no callback is provided\n * @example\n *\n * // Pretend this is some complicated async factory\n * var createUser = function(id, callback) {\n * callback(null, {\n * id: 'user' + id\n * });\n * };\n *\n * // generate 5 users\n * async.times(5, function(n, next) {\n * createUser(n, function(err, user) {\n * next(err, user);\n * });\n * }, function(err, users) {\n * // we should now have 5 users\n * });\n */\nfunction times (n, iteratee, callback) {\n return timesLimit(n, Infinity, iteratee, callback)\n}\n\n/**\n * The same as [times]{@link module:ControlFlow.times} but runs only a single async operation at a time.\n *\n * @name timesSeries\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @see [async.times]{@link module:ControlFlow.times}\n * @category Control Flow\n * @param {number} n - The number of times to run the function.\n * @param {AsyncFunction} iteratee - The async function to call `n` times.\n * Invoked with the iteration index and a callback: (n, next).\n * @param {Function} callback - see {@link module:Collections.map}.\n * @returns {Promise} a promise, if no callback is provided\n */\nfunction timesSeries (n, iteratee, callback) {\n return timesLimit(n, 1, iteratee, callback)\n}\n\n/**\n * A relative of `reduce`. Takes an Object or Array, and iterates over each\n * element in parallel, each step potentially mutating an `accumulator` value.\n * The type of the accumulator defaults to the type of collection passed in.\n *\n * @name transform\n * @static\n * @memberOf module:Collections\n * @method\n * @category Collection\n * @param {Array|Iterable|AsyncIterable|Object} coll - A collection to iterate over.\n * @param {*} [accumulator] - The initial state of the transform. If omitted,\n * it will default to an empty Object or Array, depending on the type of `coll`\n * @param {AsyncFunction} iteratee - A function applied to each item in the\n * collection that potentially modifies the accumulator.\n * Invoked with (accumulator, item, key, callback).\n * @param {Function} [callback] - A callback which is called after all the\n * `iteratee` functions have finished. Result is the transformed accumulator.\n * Invoked with (err, result).\n * @returns {Promise} a promise, if no callback provided\n * @example\n *\n * // file1.txt is a file that is 1000 bytes in size\n * // file2.txt is a file that is 2000 bytes in size\n * // file3.txt is a file that is 3000 bytes in size\n *\n * // helper function that returns human-readable size format from bytes\n * function formatBytes(bytes, decimals = 2) {\n * // implementation not included for brevity\n * return humanReadbleFilesize;\n * }\n *\n * const fileList = ['file1.txt','file2.txt','file3.txt'];\n *\n * // asynchronous function that returns the file size, transformed to human-readable format\n * // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc.\n * function transformFileSize(acc, value, key, callback) {\n * fs.stat(value, function(err, stat) {\n * if (err) {\n * return callback(err);\n * }\n * acc[key] = formatBytes(stat.size);\n * callback(null);\n * });\n * }\n *\n * // Using callbacks\n * async.transform(fileList, transformFileSize, function(err, result) {\n * if(err) {\n * console.log(err);\n * } else {\n * console.log(result);\n * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]\n * }\n * });\n *\n * // Using Promises\n * async.transform(fileList, transformFileSize)\n * .then(result => {\n * console.log(result);\n * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]\n * }).catch(err => {\n * console.log(err);\n * });\n *\n * // Using async/await\n * (async () => {\n * try {\n * let result = await async.transform(fileList, transformFileSize);\n * console.log(result);\n * // [ '1000 Bytes', '1.95 KB', '2.93 KB' ]\n * }\n * catch (err) {\n * console.log(err);\n * }\n * })();\n *\n * @example\n *\n * // file1.txt is a file that is 1000 bytes in size\n * // file2.txt is a file that is 2000 bytes in size\n * // file3.txt is a file that is 3000 bytes in size\n *\n * // helper function that returns human-readable size format from bytes\n * function formatBytes(bytes, decimals = 2) {\n * // implementation not included for brevity\n * return humanReadbleFilesize;\n * }\n *\n * const fileMap = { f1: 'file1.txt', f2: 'file2.txt', f3: 'file3.txt' };\n *\n * // asynchronous function that returns the file size, transformed to human-readable format\n * // e.g. 1024 bytes = 1KB, 1234 bytes = 1.21 KB, 1048576 bytes = 1MB, etc.\n * function transformFileSize(acc, value, key, callback) {\n * fs.stat(value, function(err, stat) {\n * if (err) {\n * return callback(err);\n * }\n * acc[key] = formatBytes(stat.size);\n * callback(null);\n * });\n * }\n *\n * // Using callbacks\n * async.transform(fileMap, transformFileSize, function(err, result) {\n * if(err) {\n * console.log(err);\n * } else {\n * console.log(result);\n * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }\n * }\n * });\n *\n * // Using Promises\n * async.transform(fileMap, transformFileSize)\n * .then(result => {\n * console.log(result);\n * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }\n * }).catch(err => {\n * console.log(err);\n * });\n *\n * // Using async/await\n * async () => {\n * try {\n * let result = await async.transform(fileMap, transformFileSize);\n * console.log(result);\n * // { f1: '1000 Bytes', f2: '1.95 KB', f3: '2.93 KB' }\n * }\n * catch (err) {\n * console.log(err);\n * }\n * }\n *\n */\nfunction transform (coll, accumulator, iteratee, callback) {\n if (arguments.length <= 3 && typeof accumulator === 'function') {\n callback = iteratee;\n iteratee = accumulator;\n accumulator = Array.isArray(coll) ? [] : {};\n }\n callback = once(callback || promiseCallback());\n var _iteratee = wrapAsync(iteratee);\n\n eachOf$1(coll, (v, k, cb) => {\n _iteratee(accumulator, v, k, cb);\n }, err => callback(err, accumulator));\n return callback[PROMISE_SYMBOL]\n}\n\n/**\n * It runs each task in series but stops whenever any of the functions were\n * successful. If one of the tasks were successful, the `callback` will be\n * passed the result of the successful task. If all tasks fail, the callback\n * will be passed the error and result (if any) of the final attempt.\n *\n * @name tryEach\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @category Control Flow\n * @param {Array|Iterable|AsyncIterable|Object} tasks - A collection containing functions to\n * run, each function is passed a `callback(err, result)` it must call on\n * completion with an error `err` (which can be `null`) and an optional `result`\n * value.\n * @param {Function} [callback] - An optional callback which is called when one\n * of the tasks has succeeded, or all have failed. It receives the `err` and\n * `result` arguments of the last attempt at completing the `task`. Invoked with\n * (err, results).\n * @returns {Promise} a promise, if no callback is passed\n * @example\n * async.tryEach([\n * function getDataFromFirstWebsite(callback) {\n * // Try getting the data from the first website\n * callback(err, data);\n * },\n * function getDataFromSecondWebsite(callback) {\n * // First website failed,\n * // Try getting the data from the backup website\n * callback(err, data);\n * }\n * ],\n * // optional callback\n * function(err, results) {\n * Now do something with the data.\n * });\n *\n */\nfunction tryEach(tasks, callback) {\n var error = null;\n var result;\n return eachSeries$1(tasks, (task, taskCb) => {\n wrapAsync(task)((err, ...args) => {\n if (err === false) return taskCb(err);\n\n if (args.length < 2) {\n [result] = args;\n } else {\n result = args;\n }\n error = err;\n taskCb(err ? null : {});\n });\n }, () => callback(error, result));\n}\n\nvar tryEach$1 = awaitify(tryEach);\n\n/**\n * Undoes a [memoize]{@link module:Utils.memoize}d function, reverting it to the original,\n * unmemoized form. Handy for testing.\n *\n * @name unmemoize\n * @static\n * @memberOf module:Utils\n * @method\n * @see [async.memoize]{@link module:Utils.memoize}\n * @category Util\n * @param {AsyncFunction} fn - the memoized function\n * @returns {AsyncFunction} a function that calls the original unmemoized function\n */\nfunction unmemoize(fn) {\n return (...args) => {\n return (fn.unmemoized || fn)(...args);\n };\n}\n\n/**\n * Repeatedly call `iteratee`, while `test` returns `true`. Calls `callback` when\n * stopped, or an error occurs.\n *\n * @name whilst\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @category Control Flow\n * @param {AsyncFunction} test - asynchronous truth test to perform before each\n * execution of `iteratee`. Invoked with (callback).\n * @param {AsyncFunction} iteratee - An async function which is called each time\n * `test` passes. Invoked with (callback).\n * @param {Function} [callback] - A callback which is called after the test\n * function has failed and repeated execution of `iteratee` has stopped. `callback`\n * will be passed an error and any arguments passed to the final `iteratee`'s\n * callback. Invoked with (err, [results]);\n * @returns {Promise} a promise, if no callback is passed\n * @example\n *\n * var count = 0;\n * async.whilst(\n * function test(cb) { cb(null, count < 5); },\n * function iter(callback) {\n * count++;\n * setTimeout(function() {\n * callback(null, count);\n * }, 1000);\n * },\n * function (err, n) {\n * // 5 seconds have passed, n = 5\n * }\n * );\n */\nfunction whilst(test, iteratee, callback) {\n callback = onlyOnce(callback);\n var _fn = wrapAsync(iteratee);\n var _test = wrapAsync(test);\n var results = [];\n\n function next(err, ...rest) {\n if (err) return callback(err);\n results = rest;\n if (err === false) return;\n _test(check);\n }\n\n function check(err, truth) {\n if (err) return callback(err);\n if (err === false) return;\n if (!truth) return callback(null, ...results);\n _fn(next);\n }\n\n return _test(check);\n}\nvar whilst$1 = awaitify(whilst, 3);\n\n/**\n * Repeatedly call `iteratee` until `test` returns `true`. Calls `callback` when\n * stopped, or an error occurs. `callback` will be passed an error and any\n * arguments passed to the final `iteratee`'s callback.\n *\n * The inverse of [whilst]{@link module:ControlFlow.whilst}.\n *\n * @name until\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @see [async.whilst]{@link module:ControlFlow.whilst}\n * @category Control Flow\n * @param {AsyncFunction} test - asynchronous truth test to perform before each\n * execution of `iteratee`. Invoked with (callback).\n * @param {AsyncFunction} iteratee - An async function which is called each time\n * `test` fails. Invoked with (callback).\n * @param {Function} [callback] - A callback which is called after the test\n * function has passed and repeated execution of `iteratee` has stopped. `callback`\n * will be passed an error and any arguments passed to the final `iteratee`'s\n * callback. Invoked with (err, [results]);\n * @returns {Promise} a promise, if a callback is not passed\n *\n * @example\n * const results = []\n * let finished = false\n * async.until(function test(cb) {\n * cb(null, finished)\n * }, function iter(next) {\n * fetchPage(url, (err, body) => {\n * if (err) return next(err)\n * results = results.concat(body.objects)\n * finished = !!body.next\n * next(err)\n * })\n * }, function done (err) {\n * // all pages have been fetched\n * })\n */\nfunction until(test, iteratee, callback) {\n const _test = wrapAsync(test);\n return whilst$1((cb) => _test((err, truth) => cb (err, !truth)), iteratee, callback);\n}\n\n/**\n * Runs the `tasks` array of functions in series, each passing their results to\n * the next in the array. However, if any of the `tasks` pass an error to their\n * own callback, the next function is not executed, and the main `callback` is\n * immediately called with the error.\n *\n * @name waterfall\n * @static\n * @memberOf module:ControlFlow\n * @method\n * @category Control Flow\n * @param {Array} tasks - An array of [async functions]{@link AsyncFunction}\n * to run.\n * Each function should complete with any number of `result` values.\n * The `result` values will be passed as arguments, in order, to the next task.\n * @param {Function} [callback] - An optional callback to run once all the\n * functions have completed. This will be passed the results of the last task's\n * callback. Invoked with (err, [results]).\n * @returns {Promise} a promise, if a callback is omitted\n * @example\n *\n * async.waterfall([\n * function(callback) {\n * callback(null, 'one', 'two');\n * },\n * function(arg1, arg2, callback) {\n * // arg1 now equals 'one' and arg2 now equals 'two'\n * callback(null, 'three');\n * },\n * function(arg1, callback) {\n * // arg1 now equals 'three'\n * callback(null, 'done');\n * }\n * ], function (err, result) {\n * // result now equals 'done'\n * });\n *\n * // Or, with named functions:\n * async.waterfall([\n * myFirstFunction,\n * mySecondFunction,\n * myLastFunction,\n * ], function (err, result) {\n * // result now equals 'done'\n * });\n * function myFirstFunction(callback) {\n * callback(null, 'one', 'two');\n * }\n * function mySecondFunction(arg1, arg2, callback) {\n * // arg1 now equals 'one' and arg2 now equals 'two'\n * callback(null, 'three');\n * }\n * function myLastFunction(arg1, callback) {\n * // arg1 now equals 'three'\n * callback(null, 'done');\n * }\n */\nfunction waterfall (tasks, callback) {\n callback = once(callback);\n if (!Array.isArray(tasks)) return callback(new Error('First argument to waterfall must be an array of functions'));\n if (!tasks.length) return callback();\n var taskIndex = 0;\n\n function nextTask(args) {\n var task = wrapAsync(tasks[taskIndex++]);\n task(...args, onlyOnce(next));\n }\n\n function next(err, ...args) {\n if (err === false) return\n if (err || taskIndex === tasks.length) {\n return callback(err, ...args);\n }\n nextTask(args);\n }\n\n nextTask([]);\n}\n\nvar waterfall$1 = awaitify(waterfall);\n\n/**\n * An \"async function\" in the context of Async is an asynchronous function with\n * a variable number of parameters, with the final parameter being a callback.\n * (`function (arg1, arg2, ..., callback) {}`)\n * The final callback is of the form `callback(err, results...)`, which must be\n * called once the function is completed. The callback should be called with a\n * Error as its first argument to signal that an error occurred.\n * Otherwise, if no error occurred, it should be called with `null` as the first\n * argument, and any additional `result` arguments that may apply, to signal\n * successful completion.\n * The callback must be called exactly once, ideally on a later tick of the\n * JavaScript event loop.\n *\n * This type of function is also referred to as a \"Node-style async function\",\n * or a \"continuation passing-style function\" (CPS). Most of the methods of this\n * library are themselves CPS/Node-style async functions, or functions that\n * return CPS/Node-style async functions.\n *\n * Wherever we accept a Node-style async function, we also directly accept an\n * [ES2017 `async` function]{@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function}.\n * In this case, the `async` function will not be passed a final callback\n * argument, and any thrown error will be used as the `err` argument of the\n * implicit callback, and the return value will be used as the `result` value.\n * (i.e. a `rejected` of the returned Promise becomes the `err` callback\n * argument, and a `resolved` value becomes the `result`.)\n *\n * Note, due to JavaScript limitations, we can only detect native `async`\n * functions and not transpilied implementations.\n * Your environment must have `async`/`await` support for this to work.\n * (e.g. Node > v7.6, or a recent version of a modern browser).\n * If you are using `async` functions through a transpiler (e.g. Babel), you\n * must still wrap the function with [asyncify]{@link module:Utils.asyncify},\n * because the `async function` will be compiled to an ordinary function that\n * returns a promise.\n *\n * @typedef {Function} AsyncFunction\n * @static\n */\n\n\nvar index = {\n apply,\n applyEach,\n applyEachSeries,\n asyncify,\n auto,\n autoInject,\n cargo: cargo$1,\n cargoQueue: cargo,\n compose,\n concat: concat$1,\n concatLimit: concatLimit$1,\n concatSeries: concatSeries$1,\n constant: constant$1,\n detect: detect$1,\n detectLimit: detectLimit$1,\n detectSeries: detectSeries$1,\n dir,\n doUntil,\n doWhilst: doWhilst$1,\n each,\n eachLimit: eachLimit$1,\n eachOf: eachOf$1,\n eachOfLimit: eachOfLimit$1,\n eachOfSeries: eachOfSeries$1,\n eachSeries: eachSeries$1,\n ensureAsync,\n every: every$1,\n everyLimit: everyLimit$1,\n everySeries: everySeries$1,\n filter: filter$1,\n filterLimit: filterLimit$1,\n filterSeries: filterSeries$1,\n forever: forever$1,\n groupBy,\n groupByLimit: groupByLimit$1,\n groupBySeries,\n log,\n map: map$1,\n mapLimit: mapLimit$1,\n mapSeries: mapSeries$1,\n mapValues,\n mapValuesLimit: mapValuesLimit$1,\n mapValuesSeries,\n memoize,\n nextTick,\n parallel,\n parallelLimit,\n priorityQueue,\n queue,\n race: race$1,\n reduce: reduce$1,\n reduceRight,\n reflect,\n reflectAll,\n reject: reject$1,\n rejectLimit: rejectLimit$1,\n rejectSeries: rejectSeries$1,\n retry,\n retryable,\n seq,\n series,\n setImmediate: setImmediate$1,\n some: some$1,\n someLimit: someLimit$1,\n someSeries: someSeries$1,\n sortBy: sortBy$1,\n timeout,\n times,\n timesLimit,\n timesSeries,\n transform,\n tryEach: tryEach$1,\n unmemoize,\n until,\n waterfall: waterfall$1,\n whilst: whilst$1,\n\n // aliases\n all: every$1,\n allLimit: everyLimit$1,\n allSeries: everySeries$1,\n any: some$1,\n anyLimit: someLimit$1,\n anySeries: someSeries$1,\n find: detect$1,\n findLimit: detectLimit$1,\n findSeries: detectSeries$1,\n flatMap: concat$1,\n flatMapLimit: concatLimit$1,\n flatMapSeries: concatSeries$1,\n forEach: each,\n forEachSeries: eachSeries$1,\n forEachLimit: eachLimit$1,\n forEachOf: eachOf$1,\n forEachOfSeries: eachOfSeries$1,\n forEachOfLimit: eachOfLimit$1,\n inject: reduce$1,\n foldl: reduce$1,\n foldr: reduceRight,\n select: filter$1,\n selectLimit: filterLimit$1,\n selectSeries: filterSeries$1,\n wrapSync: asyncify,\n during: whilst$1,\n doDuring: doWhilst$1\n};\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHJzYykvLi9ub2RlX21vZHVsZXMvYXN5bmMvZGlzdC9hc3luYy5tanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFVBQVU7QUFDckI7QUFDQSxXQUFXLE1BQU07QUFDakI7QUFDQSxhQUFhLFVBQVU7QUFDdkI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBLEVBQUU7QUFDRjtBQUNBLEVBQUU7QUFDRjtBQUNBLEVBQUU7QUFDRjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxVQUFVO0FBQ3JCLDhCQUE4QixvQkFBb0I7QUFDbEQsYUFBYSxlQUFlO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxNQUFNO0FBQ04sOEJBQThCLFNBQVM7QUFDdkM7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiLFNBQVM7QUFDVDtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDRCQUE0Qix3QkFBd0I7QUFDcEQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQixzQkFBc0I7QUFDaEQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLHNCQUFzQjtBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCLGlDQUFpQztBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBLFdBQVcscUNBQXFDO0FBQ2hELFdBQVcsUUFBUTtBQUNuQixXQUFXLGVBQWU7QUFDMUI7QUFDQTtBQUNBO0FBQ0EsV0FBVyxVQUFVO0FBQ3JCO0FBQ0EsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTLFFBQVE7QUFDakI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTtBQUNBOztBQUVBLFdBQVcsZ0JBQWdCO0FBQzNCO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlCQUFpQiw4QkFBOEI7QUFDL0M7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQixXQUFXLHFDQUFxQztBQUNoRCxXQUFXLGVBQWU7QUFDMUI7QUFDQTtBQUNBO0FBQ0EsV0FBVyxVQUFVO0FBQ3JCO0FBQ0EsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCLDZCQUE2QjtBQUM3QiwrQkFBK0I7QUFDL0I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWixJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLHFDQUFxQztBQUNoRCxXQUFXLGVBQWU7QUFDMUI7QUFDQTtBQUNBO0FBQ0EsV0FBVyxVQUFVO0FBQ3JCO0FBQ0E7QUFDQSxhQUFhLFNBQVM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLHFDQUFxQyx1QkFBdUIsb0JBQW9CO0FBQzNGO0FBQ0EsV0FBVyxNQUFNO0FBQ2pCO0FBQ0EsV0FBVyxVQUFVO0FBQ3JCO0FBQ0EsYUFBYSxlQUFlO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSwwQkFBMEIsaUNBQWlDO0FBQzNEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQTtBQUNBLFdBQVcscUNBQXFDO0FBQ2hELFdBQVcsZUFBZTtBQUMxQjtBQUNBO0FBQ0EsV0FBVyxVQUFVO0FBQ3JCO0FBQ0EsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSx1QkFBdUIsOEJBQThCO0FBQ3JEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQSxXQUFXLHFDQUFxQztBQUNoRCxXQUFXLGVBQWU7QUFDMUI7QUFDQTtBQUNBO0FBQ0EsV0FBVyxVQUFVO0FBQ3JCO0FBQ0E7QUFDQSxhQUFhLFNBQVM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLDZCQUE2QixvQ0FBb0M7QUFDakU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQjtBQUMxQjtBQUNBLFdBQVcscUNBQXFDLHVCQUF1QixvQkFBb0I7QUFDM0Y7QUFDQSxXQUFXLE1BQU07QUFDakI7QUFDQSxXQUFXLFVBQVU7QUFDckI7QUFDQSxhQUFhLGVBQWU7QUFDNUI7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBLDhDQUE4QyxvQkFBb0I7QUFDbEU7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0Isb0JBQW9CO0FBQ3RDO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSSxvQkFBb0I7QUFDeEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixtREFBbUQscUJBQXFCO0FBQ3hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkI7QUFDQTtBQUNBLFdBQVcsVUFBVTtBQUNyQjtBQUNBLGlFQUFpRTtBQUNqRTtBQUNBO0FBQ0EsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQSwyQkFBMkIsc0RBQXNEO0FBQ2pGLFFBQVE7QUFDUixJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsMkJBQTJCO0FBQzNCO0FBQ0EsNEJBQTRCO0FBQzVCO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBLDJCQUEyQixzREFBc0Q7QUFDakYsUUFBUTtBQUNSLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQSwyQkFBMkI7QUFDM0I7QUFDQSw0QkFBNEI7QUFDNUI7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0EsbUNBQW1DLHNEQUFzRDtBQUN6RixnQkFBZ0I7QUFDaEIsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBLCtCQUErQjtBQUMvQjtBQUNBLGdDQUFnQztBQUNoQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTs7QUFFQTtBQUNBLDJCQUEyQjtBQUMzQjtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2IsU0FBUztBQUNULEtBQUs7O0FBRUw7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOzs7QUFHQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsaUJBQWlCO0FBQ2pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxjQUFjO0FBQ2Q7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxhQUFhO0FBQ2I7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQSx5RUFBeUU7QUFDekU7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsY0FBYztBQUNkO0FBQ0E7QUFDQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQSxxREFBcUQsK0JBQStCO0FBQ3BGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdDQUF3Qyw4QkFBOEI7QUFDdEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBLFdBQVcsUUFBUSxtREFBbUQscUJBQXFCO0FBQzNGO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFVBQVU7QUFDckI7QUFDQTtBQUNBO0FBQ0EsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBLDJCQUEyQiw4Q0FBOEM7QUFDekU7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBLDJCQUEyQiw4Q0FBOEM7QUFDekUsUUFBUTtBQUNSO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLFVBQVU7QUFDVjtBQUNBO0FBQ0EsVUFBVTtBQUNWO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsS0FBSzs7QUFFTDtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUIsTUFBTTtBQUN2QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxVQUFVO0FBQ1Y7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBLDhDQUE4QyxPQUFPO0FBQ3JEOztBQUVBO0FBQ0E7QUFDQTtBQUNBLGtCQUFrQjtBQUNsQjtBQUNBOztBQUVBOztBQUVBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpQkFBaUI7QUFDakIsYUFBYTtBQUNiO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsZ0NBQWdDLE9BQU87QUFDdkM7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBLHNDQUFzQztBQUN0QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNULEtBQUs7QUFDTDtBQUNBOztBQUVBO0FBQ0E7QUFD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QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxlQUFlO0FBQzFCO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkI7QUFDQTtBQUNBLGFBQWEsZ0NBQWdDO0FBQzdDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxXQUFXLFlBQVk7QUFDdkI7QUFDQSxJQUFJO0FBQ0o7QUFDQSxXQUFXLFlBQVk7QUFDdkI7QUFDQTtBQUNBLFlBQVksWUFBWSxFQUFFLFlBQVksRUFBRSxZQUFZO0FBQ3BEO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxjQUFjLFlBQVk7QUFDMUI7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHdCQUF3QixzQkFBc0I7QUFDOUM7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSx3QkFBd0Isc0JBQXNCO0FBQzlDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUEsaURBQWlELFFBQVE7QUFDekQ7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsNkJBQTZCLGdDQUFnQztBQUM3RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQSxXQUFXLGVBQWU7QUFDMUI7QUFDQTtBQUNBO0FBQ0EsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQSxhQUFhLGdDQUFnQztBQUM3QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQSxNQUFNOztBQUVOO0FBQ0EsMEJBQTBCLGVBQWU7QUFDekM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQSxtQ0FBbUMsUUFBUSxrQkFBa0I7QUFDN0Q7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLE9BQU8sOENBQThDO0FBQ2hFO0FBQ0EsV0FBVyxVQUFVO0FBQ3JCO0FBQ0E7QUFDQSxhQUFhLFNBQVM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0NBQXNDLE9BQU87QUFDN0M7QUFDQTtBQUNBOztBQUVBOztBQUVBO0FBQ0Esc0JBQXNCLGdDQUFnQztBQUN0RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCO0FBQ0E7QUFDQSxXQUFXLE9BQU87QUFDbEIsV0FBVyxHQUFHO0FBQ2QsV0FBVyxlQUFlO0FBQzFCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFVBQVU7QUFDckI7QUFDQTtBQUNBLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGVBQWU7QUFDMUIsYUFBYSxVQUFVO0FBQ3ZCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUzs7QUFFVDtBQUNBLEtBQUs7QUFDTDs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHdCQUF3QjtBQUN4QjtBQUNBLFdBQVcsdUJBQXVCO0FBQ2xDLHFCQUFxQixxQkFBcUI7QUFDMUMsYUFBYSxPQUFPO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWixRQUFRO0FBQ1I7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLE1BQU07QUFDTjtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1Q7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxTQUFTO0FBQ1QsS0FBSztBQUNMOztBQUVBO0FBQ0EsOEJBQThCLGdDQUFnQztBQUM5RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCO0FBQ0EsV0FBVyxxQ0FBcUM7QUFDaEQsV0FBVyxVQUFVO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLFdBQVcsVUFBVTtBQUNyQjtBQUNBLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCLGlDQUFpQztBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx1QkFBdUI7QUFDdkI7QUFDQSxXQUFXLHFDQUFxQztBQUNoRCxXQUFXLFFBQVE7QUFDbkIsV0FBVyxVQUFVO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLFdBQVcsVUFBVTtBQUNyQjtBQUNBLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsMEJBQTBCLGlDQUFpQztBQUMzRDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsdUJBQXVCO0FBQ3ZCO0FBQ0EsV0FBVyxxQ0FBcUM7QUFDaEQsV0FBVyxVQUFVO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBLFdBQVcsVUFBVTtBQUNyQjtBQUNBLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLDBCQUEwQjtBQUMxQixXQUFXLGVBQWUsU0FBUyxzQkFBc0I7QUFDekQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLGVBQWU7QUFDMUI7QUFDQSxXQUFXLFVBQVU7QUFDckI7QUFDQTtBQUNBO0FBQ0EsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0EsZ0JBQWdCLHdCQUF3QjtBQUN4QztBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxpREFBaUQ7QUFDakQ7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGNBQWM7QUFDZDtBQUNBO0FBQ0EsU0FBUztBQUNUOztBQUVBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0EsTUFBTTtBQUNOO0FBQ0EsTUFBTTtBQUNOO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLGlDQUFpQywrQkFBK0I7QUFDaEU7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQSxXQUFXLGVBQWUsU0FBUyxzQkFBc0I7QUFDekQ7QUFDQTtBQUNBLFdBQVcsZUFBZTtBQUMxQjtBQUNBO0FBQ0EsYUFBYSxlQUFlO0FBQzVCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1IsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7O0FBRUE7QUFDQSxLQUFLO0FBQ0w7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxrQkFBa0IsbUJBQW1CO0FBQ3JDO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcscUNBQXFDO0FBQ2hELHFCQUFxQixxQkFBcUI7QUFDMUM7QUFDQSxXQUFXLFVBQVU7QUFDckI7QUFDQTtBQUNBO0FBQ0EsWUFBWSxTQUFTO0FBQ3JCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1osUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBLFlBQVk7QUFDWjtBQUNBLElBQUk7QUFDSjtBQUNBLGlDQUFpQztBQUNqQyxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1o7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1osUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsWUFBWTtBQUNaO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsaUNBQWlDO0FBQ2pDLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEIsZ0JBQWdCO0FBQ2hCO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esb0JBQW9CO0FBQ3BCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLG9CQUFvQjtBQUNwQixnQkFBZ0I7QUFDaEI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQSxZQUFZO0FBQ1o7QUFDQSxxQ0FBcUM7QUFDckM7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcscUNBQXFDO0FBQ2hELFdBQVcsZUFBZTtBQUMxQjtBQUNBO0FBQ0E7QUFDQSxXQUFXLFVBQVU7QUFDckI7QUFDQTtBQUNBO0FBQ0EsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxPQUFPO0FBQ1A7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0Esd0JBQXdCLCtCQUErQjtBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EscUJBQXFCO0FBQ3JCO0FBQ0E7QUFDQSxXQUFXLHFDQUFxQztBQUNoRCxXQUFXLFFBQVE7QUFDbkIsV0FBVyxlQUFlO0FBQzFCO0FBQ0E7QUFDQTtBQUNBLFdBQVcsVUFBVTtBQUNyQjtBQUNBO0FBQ0E7QUFDQSxhQUFhLFNBQVM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBLHdCQUF3QiwrQkFBK0I7QUFDdkQ7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLHFCQUFxQjtBQUNyQjtBQUNBO0FBQ0EsV0FBVyxxQ0FBcUM7QUFDaEQsV0FBVyxlQUFlO0FBQzFCO0FBQ0E7QUFDQTtBQUNBLFdBQVcsVUFBVTtBQUNyQjtBQUNBO0FBQ0E7QUFDQSxhQUFhLFNBQVM7QUFDdEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLHFDQUFxQztBQUNoRCxXQUFXLGVBQWU7QUFDMUI7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFVBQVU7QUFDckI7QUFDQTtBQUNBO0FBQ0EsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSLElBQUk7QUFDSjtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUixJQUFJO0FBQ0o7QUFDQTtBQUNBLGFBQWE7QUFDYjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYTtBQUNiO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLElBQUk7QUFDSjtBQUNBLElBQUk7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSx5QkFBeUIsbUJBQW1CO0FBQzVDLFNBQVM7QUFDVCxLQUFLO0FBQ0w7QUFDQTtBQUNBLEtBQUs7O0FBRUw7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxlQUFlO0FBQzFCLFdBQVcsUUFBUTtBQUNuQixXQUFXLEdBQUc7QUFDZDtBQUNBLGFBQWEsZUFBZTtBQUM1QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsYUFBYSxZQUFZO0FBQ3pCO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7O0FBRVQ7QUFDQTtBQUNBO0FBQ0EsS0FBSztBQUNMOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsdUJBQXVCLGdDQUFnQztBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxzQkFBc0I7QUFDdEI7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CLFdBQVcsZUFBZTtBQUMxQjtBQUNBLFdBQVcsVUFBVSwyQkFBMkIsNkJBQTZCO0FBQzdFLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxtQ0FBbUMsNkJBQTZCO0FBQ2hFO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxvQkFBb0I7QUFDcEI7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxlQUFlO0FBQzFCO0FBQ0EsV0FBVyxVQUFVLGdCQUFnQiw2QkFBNkI7QUFDbEUsYUFBYSxTQUFTO0FBQ3RCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFFBQVE7QUFDUjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1IsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0EsdUJBQXVCLGdDQUFnQztBQUN2RDtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esc0JBQXNCO0FBQ3RCO0FBQ0EsV0FBVyxRQUFRO0FBQ25CLFdBQVcsZUFBZTtBQUMxQjtBQUNBLFdBQVcsVUFBVSxnQkFBZ0IsNkJBQTZCO0FBQ2xFLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFdBQVcscUNBQXFDO0FBQ2hELFdBQVcsR0FBRztBQUNkO0FBQ0EsV0FBVyxlQUFlO0FBQzFCO0FBQ0E7QUFDQSxXQUFXLFVBQVU7QUFDckI7QUFDQTtBQUNBLGFBQWEsU0FBUztBQUN0QjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsUUFBUTtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLFNBQVM7QUFDVDtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxJQUFJO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxxQkFBcUI7QUFDckI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxRQUFRO0FBQ1I7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsU0FBUztBQUNUO0FBQ0EsZ0JBQWdCO0FBQ2hCO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxZQUFZO0FBQ1osSUFBSTtBQUNKO0FBQ0EsSUFBSTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGdCQUFnQjtBQUNoQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtB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O0FBQ0E7QUFDQSxhQUFhLFVBQVU7QUFDdkI7QUFDQTs7O0FBR0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUV5aEUiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9jb250cmFjdC1hcHByb3ZhbC1zeXN0ZW0vLi9ub2RlX21vZHVsZXMvYXN5bmMvZGlzdC9hc3luYy5tanM/NzEwOSJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENyZWF0ZXMgYSBjb250aW51YXRpb24gZnVuY3Rpb24gd2l0aCBzb21lIGFyZ3VtZW50cyBhbHJlYWR5IGFwcGxpZWQuXG4gKlxuICogVXNlZnVsIGFzIGEgc2hvcnRoYW5kIHdoZW4gY29tYmluZWQgd2l0aCBvdGhlciBjb250cm9sIGZsb3cgZnVuY3Rpb25zLiBBbnlcbiAqIGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhlIHJldHVybmVkIGZ1bmN0aW9uIGFyZSBhZGRlZCB0byB0aGUgYXJndW1lbnRzXG4gKiBvcmlnaW5hbGx5IHBhc3NlZCB0byBhcHBseS5cbiAqXG4gKiBAbmFtZSBhcHBseVxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpVdGlsc1xuICogQG1ldGhvZFxuICogQGNhdGVnb3J5IFV0aWxcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuIC0gVGhlIGZ1bmN0aW9uIHlvdSB3YW50IHRvIGV2ZW50dWFsbHkgYXBwbHkgYWxsXG4gKiBhcmd1bWVudHMgdG8uIEludm9rZXMgd2l0aCAoYXJndW1lbnRzLi4uKS5cbiAqIEBwYXJhbSB7Li4uKn0gYXJndW1lbnRzLi4uIC0gQW55IG51bWJlciBvZiBhcmd1bWVudHMgdG8gYXV0b21hdGljYWxseSBhcHBseVxuICogd2hlbiB0aGUgY29udGludWF0aW9uIGlzIGNhbGxlZC5cbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gdGhlIHBhcnRpYWxseS1hcHBsaWVkIGZ1bmN0aW9uXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIHVzaW5nIGFwcGx5XG4gKiBhc3luYy5wYXJhbGxlbChbXG4gKiAgICAgYXN5bmMuYXBwbHkoZnMud3JpdGVGaWxlLCAndGVzdGZpbGUxJywgJ3Rlc3QxJyksXG4gKiAgICAgYXN5bmMuYXBwbHkoZnMud3JpdGVGaWxlLCAndGVzdGZpbGUyJywgJ3Rlc3QyJylcbiAqIF0pO1xuICpcbiAqXG4gKiAvLyB0aGUgc2FtZSBwcm9jZXNzIHdpdGhvdXQgdXNpbmcgYXBwbHlcbiAqIGFzeW5jLnBhcmFsbGVsKFtcbiAqICAgICBmdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgICAgICBmcy53cml0ZUZpbGUoJ3Rlc3RmaWxlMScsICd0ZXN0MScsIGNhbGxiYWNrKTtcbiAqICAgICB9LFxuICogICAgIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIGZzLndyaXRlRmlsZSgndGVzdGZpbGUyJywgJ3Rlc3QyJywgY2FsbGJhY2spO1xuICogICAgIH1cbiAqIF0pO1xuICpcbiAqIC8vIEl0J3MgcG9zc2libGUgdG8gcGFzcyBhbnkgbnVtYmVyIG9mIGFkZGl0aW9uYWwgYXJndW1lbnRzIHdoZW4gY2FsbGluZyB0aGVcbiAqIC8vIGNvbnRpbnVhdGlvbjpcbiAqXG4gKiBub2RlPiB2YXIgZm4gPSBhc3luYy5hcHBseShzeXMucHV0cywgJ29uZScpO1xuICogbm9kZT4gZm4oJ3R3bycsICd0aHJlZScpO1xuICogb25lXG4gKiB0d29cbiAqIHRocmVlXG4gKi9cbmZ1bmN0aW9uIGFwcGx5KGZuLCAuLi5hcmdzKSB7XG4gICAgcmV0dXJuICguLi5jYWxsQXJncykgPT4gZm4oLi4uYXJncywuLi5jYWxsQXJncyk7XG59XG5cbmZ1bmN0aW9uIGluaXRpYWxQYXJhbXMgKGZuKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICguLi5hcmdzLyosIGNhbGxiYWNrKi8pIHtcbiAgICAgICAgdmFyIGNhbGxiYWNrID0gYXJncy5wb3AoKTtcbiAgICAgICAgcmV0dXJuIGZuLmNhbGwodGhpcywgYXJncywgY2FsbGJhY2spO1xuICAgIH07XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBmaWxlICovXG5cbnZhciBoYXNRdWV1ZU1pY3JvdGFzayA9IHR5cGVvZiBxdWV1ZU1pY3JvdGFzayA9PT0gJ2Z1bmN0aW9uJyAmJiBxdWV1ZU1pY3JvdGFzaztcbnZhciBoYXNTZXRJbW1lZGlhdGUgPSB0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSAnZnVuY3Rpb24nICYmIHNldEltbWVkaWF0ZTtcbnZhciBoYXNOZXh0VGljayA9IHR5cGVvZiBwcm9jZXNzID09PSAnb2JqZWN0JyAmJiB0eXBlb2YgcHJvY2Vzcy5uZXh0VGljayA9PT0gJ2Z1bmN0aW9uJztcblxuZnVuY3Rpb24gZmFsbGJhY2soZm4pIHtcbiAgICBzZXRUaW1lb3V0KGZuLCAwKTtcbn1cblxuZnVuY3Rpb24gd3JhcChkZWZlcikge1xuICAgIHJldHVybiAoZm4sIC4uLmFyZ3MpID0+IGRlZmVyKCgpID0+IGZuKC4uLmFyZ3MpKTtcbn1cblxudmFyIF9kZWZlciQxO1xuXG5pZiAoaGFzUXVldWVNaWNyb3Rhc2spIHtcbiAgICBfZGVmZXIkMSA9IHF1ZXVlTWljcm90YXNrO1xufSBlbHNlIGlmIChoYXNTZXRJbW1lZGlhdGUpIHtcbiAgICBfZGVmZXIkMSA9IHNldEltbWVkaWF0ZTtcbn0gZWxzZSBpZiAoaGFzTmV4dFRpY2spIHtcbiAgICBfZGVmZXIkMSA9IHByb2Nlc3MubmV4dFRpY2s7XG59IGVsc2Uge1xuICAgIF9kZWZlciQxID0gZmFsbGJhY2s7XG59XG5cbnZhciBzZXRJbW1lZGlhdGUkMSA9IHdyYXAoX2RlZmVyJDEpO1xuXG4vKipcbiAqIFRha2UgYSBzeW5jIGZ1bmN0aW9uIGFuZCBtYWtlIGl0IGFzeW5jLCBwYXNzaW5nIGl0cyByZXR1cm4gdmFsdWUgdG8gYVxuICogY2FsbGJhY2suIFRoaXMgaXMgdXNlZnVsIGZvciBwbHVnZ2luZyBzeW5jIGZ1bmN0aW9ucyBpbnRvIGEgd2F0ZXJmYWxsLFxuICogc2VyaWVzLCBvciBvdGhlciBhc3luYyBmdW5jdGlvbnMuIEFueSBhcmd1bWVudHMgcGFzc2VkIHRvIHRoZSBnZW5lcmF0ZWRcbiAqIGZ1bmN0aW9uIHdpbGwgYmUgcGFzc2VkIHRvIHRoZSB3cmFwcGVkIGZ1bmN0aW9uIChleGNlcHQgZm9yIHRoZSBmaW5hbFxuICogY2FsbGJhY2sgYXJndW1lbnQpLiBFcnJvcnMgdGhyb3duIHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBjYWxsYmFjay5cbiAqXG4gKiBJZiB0aGUgZnVuY3Rpb24gcGFzc2VkIHRvIGBhc3luY2lmeWAgcmV0dXJucyBhIFByb21pc2UsIHRoYXQgcHJvbWlzZXMnc1xuICogcmVzb2x2ZWQvcmVqZWN0ZWQgc3RhdGUgd2lsbCBiZSB1c2VkIHRvIGNhbGwgdGhlIGNhbGxiYWNrLCByYXRoZXIgdGhhbiBzaW1wbHlcbiAqIHRoZSBzeW5jaHJvbm91cyByZXR1cm4gdmFsdWUuXG4gKlxuICogVGhpcyBhbHNvIG1lYW5zIHlvdSBjYW4gYXN5bmNpZnkgRVMyMDE3IGBhc3luY2AgZnVuY3Rpb25zLlxuICpcbiAqIEBuYW1lIGFzeW5jaWZ5XG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOlV0aWxzXG4gKiBAbWV0aG9kXG4gKiBAYWxpYXMgd3JhcFN5bmNcbiAqIEBjYXRlZ29yeSBVdGlsXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIC0gVGhlIHN5bmNocm9ub3VzIGZ1bmN0aW9uLCBvciBQcm9taXNlLXJldHVybmluZ1xuICogZnVuY3Rpb24gdG8gY29udmVydCB0byBhbiB7QGxpbmsgQXN5bmNGdW5jdGlvbn0uXG4gKiBAcmV0dXJucyB7QXN5bmNGdW5jdGlvbn0gQW4gYXN5bmNocm9ub3VzIHdyYXBwZXIgb2YgdGhlIGBmdW5jYC4gVG8gYmVcbiAqIGludm9rZWQgd2l0aCBgKGFyZ3MuLi4sIGNhbGxiYWNrKWAuXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIHBhc3NpbmcgYSByZWd1bGFyIHN5bmNocm9ub3VzIGZ1bmN0aW9uXG4gKiBhc3luYy53YXRlcmZhbGwoW1xuICogICAgIGFzeW5jLmFwcGx5KGZzLnJlYWRGaWxlLCBmaWxlbmFtZSwgXCJ1dGY4XCIpLFxuICogICAgIGFzeW5jLmFzeW5jaWZ5KEpTT04ucGFyc2UpLFxuICogICAgIGZ1bmN0aW9uIChkYXRhLCBuZXh0KSB7XG4gKiAgICAgICAgIC8vIGRhdGEgaXMgdGhlIHJlc3VsdCBvZiBwYXJzaW5nIHRoZSB0ZXh0LlxuICogICAgICAgICAvLyBJZiB0aGVyZSB3YXMgYSBwYXJzaW5nIGVycm9yLCBpdCB3b3VsZCBoYXZlIGJlZW4gY2F1Z2h0LlxuICogICAgIH1cbiAqIF0sIGNhbGxiYWNrKTtcbiAqXG4gKiAvLyBwYXNzaW5nIGEgZnVuY3Rpb24gcmV0dXJuaW5nIGEgcHJvbWlzZVxuICogYXN5bmMud2F0ZXJmYWxsKFtcbiAqICAgICBhc3luYy5hcHBseShmcy5yZWFkRmlsZSwgZmlsZW5hbWUsIFwidXRmOFwiKSxcbiAqICAgICBhc3luYy5hc3luY2lmeShmdW5jdGlvbiAoY29udGVudHMpIHtcbiAqICAgICAgICAgcmV0dXJuIGRiLm1vZGVsLmNyZWF0ZShjb250ZW50cyk7XG4gKiAgICAgfSksXG4gKiAgICAgZnVuY3Rpb24gKG1vZGVsLCBuZXh0KSB7XG4gKiAgICAgICAgIC8vIGBtb2RlbGAgaXMgdGhlIGluc3RhbnRpYXRlZCBtb2RlbCBvYmplY3QuXG4gKiAgICAgICAgIC8vIElmIHRoZXJlIHdhcyBhbiBlcnJvciwgdGhpcyBmdW5jdGlvbiB3b3VsZCBiZSBza2lwcGVkLlxuICogICAgIH1cbiAqIF0sIGNhbGxiYWNrKTtcbiAqXG4gKiAvLyBlczIwMTcgZXhhbXBsZSwgdGhvdWdoIGBhc3luY2lmeWAgaXMgbm90IG5lZWRlZCBpZiB5b3VyIEpTIGVudmlyb25tZW50XG4gKiAvLyBzdXBwb3J0cyBhc3luYyBmdW5jdGlvbnMgb3V0IG9mIHRoZSBib3hcbiAqIHZhciBxID0gYXN5bmMucXVldWUoYXN5bmMuYXN5bmNpZnkoYXN5bmMgZnVuY3Rpb24oZmlsZSkge1xuICogICAgIHZhciBpbnRlcm1lZGlhdGVTdGVwID0gYXdhaXQgcHJvY2Vzc0ZpbGUoZmlsZSk7XG4gKiAgICAgcmV0dXJuIGF3YWl0IHNvbWVQcm9taXNlKGludGVybWVkaWF0ZVN0ZXApXG4gKiB9KSk7XG4gKlxuICogcS5wdXNoKGZpbGVzKTtcbiAqL1xuZnVuY3Rpb24gYXN5bmNpZnkoZnVuYykge1xuICAgIGlmIChpc0FzeW5jKGZ1bmMpKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoLi4uYXJncy8qLCBjYWxsYmFjayovKSB7XG4gICAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IGFyZ3MucG9wKCk7XG4gICAgICAgICAgICBjb25zdCBwcm9taXNlID0gZnVuYy5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgICAgIHJldHVybiBoYW5kbGVQcm9taXNlKHByb21pc2UsIGNhbGxiYWNrKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGluaXRpYWxQYXJhbXMoZnVuY3Rpb24gKGFyZ3MsIGNhbGxiYWNrKSB7XG4gICAgICAgIHZhciByZXN1bHQ7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICByZXN1bHQgPSBmdW5jLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gaWYgcmVzdWx0IGlzIFByb21pc2Ugb2JqZWN0XG4gICAgICAgIGlmIChyZXN1bHQgJiYgdHlwZW9mIHJlc3VsdC50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4gaGFuZGxlUHJvbWlzZShyZXN1bHQsIGNhbGxiYWNrKVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgcmVzdWx0KTtcbiAgICAgICAgfVxuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBoYW5kbGVQcm9taXNlKHByb21pc2UsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHByb21pc2UudGhlbih2YWx1ZSA9PiB7XG4gICAgICAgIGludm9rZUNhbGxiYWNrKGNhbGxiYWNrLCBudWxsLCB2YWx1ZSk7XG4gICAgfSwgZXJyID0+IHtcbiAgICAgICAgaW52b2tlQ2FsbGJhY2soY2FsbGJhY2ssIGVyciAmJiAoZXJyIGluc3RhbmNlb2YgRXJyb3IgfHwgZXJyLm1lc3NhZ2UpID8gZXJyIDogbmV3IEVycm9yKGVycikpO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBpbnZva2VDYWxsYmFjayhjYWxsYmFjaywgZXJyb3IsIHZhbHVlKSB7XG4gICAgdHJ5IHtcbiAgICAgICAgY2FsbGJhY2soZXJyb3IsIHZhbHVlKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgc2V0SW1tZWRpYXRlJDEoZSA9PiB7IHRocm93IGUgfSwgZXJyKTtcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGlzQXN5bmMoZm4pIHtcbiAgICByZXR1cm4gZm5bU3ltYm9sLnRvU3RyaW5nVGFnXSA9PT0gJ0FzeW5jRnVuY3Rpb24nO1xufVxuXG5mdW5jdGlvbiBpc0FzeW5jR2VuZXJhdG9yKGZuKSB7XG4gICAgcmV0dXJuIGZuW1N5bWJvbC50b1N0cmluZ1RhZ10gPT09ICdBc3luY0dlbmVyYXRvcic7XG59XG5cbmZ1bmN0aW9uIGlzQXN5bmNJdGVyYWJsZShvYmopIHtcbiAgICByZXR1cm4gdHlwZW9mIG9ialtTeW1ib2wuYXN5bmNJdGVyYXRvcl0gPT09ICdmdW5jdGlvbic7XG59XG5cbmZ1bmN0aW9uIHdyYXBBc3luYyhhc3luY0ZuKSB7XG4gICAgaWYgKHR5cGVvZiBhc3luY0ZuICE9PSAnZnVuY3Rpb24nKSB0aHJvdyBuZXcgRXJyb3IoJ2V4cGVjdGVkIGEgZnVuY3Rpb24nKVxuICAgIHJldHVybiBpc0FzeW5jKGFzeW5jRm4pID8gYXN5bmNpZnkoYXN5bmNGbikgOiBhc3luY0ZuO1xufVxuXG4vLyBjb25kaXRpb25hbGx5IHByb21pc2lmeSBhIGZ1bmN0aW9uLlxuLy8gb25seSByZXR1cm4gYSBwcm9taXNlIGlmIGEgY2FsbGJhY2sgaXMgb21pdHRlZFxuZnVuY3Rpb24gYXdhaXRpZnkgKGFzeW5jRm4sIGFyaXR5KSB7XG4gICAgaWYgKCFhcml0eSkgYXJpdHkgPSBhc3luY0ZuLmxlbmd0aDtcbiAgICBpZiAoIWFyaXR5KSB0aHJvdyBuZXcgRXJyb3IoJ2FyaXR5IGlzIHVuZGVmaW5lZCcpXG4gICAgZnVuY3Rpb24gYXdhaXRhYmxlICguLi5hcmdzKSB7XG4gICAgICAgIGlmICh0eXBlb2YgYXJnc1thcml0eSAtIDFdID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4gYXN5bmNGbi5hcHBseSh0aGlzLCBhcmdzKVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKChyZXNvbHZlLCByZWplY3QpID0+IHtcbiAgICAgICAgICAgIGFyZ3NbYXJpdHkgLSAxXSA9IChlcnIsIC4uLmNiQXJncykgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlcnIpIHJldHVybiByZWplY3QoZXJyKVxuICAgICAgICAgICAgICAgIHJlc29sdmUoY2JBcmdzLmxlbmd0aCA+IDEgPyBjYkFyZ3MgOiBjYkFyZ3NbMF0pO1xuICAgICAgICAgICAgfTtcbiAgICAgICAgICAgIGFzeW5jRm4uYXBwbHkodGhpcywgYXJncyk7XG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0YWJsZVxufVxuXG5mdW5jdGlvbiBhcHBseUVhY2gkMSAoZWFjaGZuKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIGFwcGx5RWFjaChmbnMsIC4uLmNhbGxBcmdzKSB7XG4gICAgICAgIGNvbnN0IGdvID0gYXdhaXRpZnkoZnVuY3Rpb24gKGNhbGxiYWNrKSB7XG4gICAgICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XG4gICAgICAgICAgICByZXR1cm4gZWFjaGZuKGZucywgKGZuLCBjYikgPT4ge1xuICAgICAgICAgICAgICAgIHdyYXBBc3luYyhmbikuYXBwbHkodGhhdCwgY2FsbEFyZ3MuY29uY2F0KGNiKSk7XG4gICAgICAgICAgICB9LCBjYWxsYmFjayk7XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gZ287XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gX2FzeW5jTWFwKGVhY2hmbiwgYXJyLCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICBhcnIgPSBhcnIgfHwgW107XG4gICAgdmFyIHJlc3VsdHMgPSBbXTtcbiAgICB2YXIgY291bnRlciA9IDA7XG4gICAgdmFyIF9pdGVyYXRlZSA9IHdyYXBBc3luYyhpdGVyYXRlZSk7XG5cbiAgICByZXR1cm4gZWFjaGZuKGFyciwgKHZhbHVlLCBfLCBpdGVyQ2IpID0+IHtcbiAgICAgICAgdmFyIGluZGV4ID0gY291bnRlcisrO1xuICAgICAgICBfaXRlcmF0ZWUodmFsdWUsIChlcnIsIHYpID0+IHtcbiAgICAgICAgICAgIHJlc3VsdHNbaW5kZXhdID0gdjtcbiAgICAgICAgICAgIGl0ZXJDYihlcnIpO1xuICAgICAgICB9KTtcbiAgICB9LCBlcnIgPT4ge1xuICAgICAgICBjYWxsYmFjayhlcnIsIHJlc3VsdHMpO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBpc0FycmF5TGlrZSh2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZSAmJlxuICAgICAgICB0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJyAmJlxuICAgICAgICB2YWx1ZS5sZW5ndGggPj0gMCAmJlxuICAgICAgICB2YWx1ZS5sZW5ndGggJSAxID09PSAwO1xufVxuXG4vLyBBIHRlbXBvcmFyeSB2YWx1ZSB1c2VkIHRvIGlkZW50aWZ5IGlmIHRoZSBsb29wIHNob3VsZCBiZSBicm9rZW4uXG4vLyBTZWUgIzEwNjQsICMxMjkzXG5jb25zdCBicmVha0xvb3AgPSB7fTtcblxuZnVuY3Rpb24gb25jZShmbikge1xuICAgIGZ1bmN0aW9uIHdyYXBwZXIgKC4uLmFyZ3MpIHtcbiAgICAgICAgaWYgKGZuID09PSBudWxsKSByZXR1cm47XG4gICAgICAgIHZhciBjYWxsRm4gPSBmbjtcbiAgICAgICAgZm4gPSBudWxsO1xuICAgICAgICBjYWxsRm4uYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICAgIE9iamVjdC5hc3NpZ24od3JhcHBlciwgZm4pO1xuICAgIHJldHVybiB3cmFwcGVyXG59XG5cbmZ1bmN0aW9uIGdldEl0ZXJhdG9yIChjb2xsKSB7XG4gICAgcmV0dXJuIGNvbGxbU3ltYm9sLml0ZXJhdG9yXSAmJiBjb2xsW1N5bWJvbC5pdGVyYXRvcl0oKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlQXJyYXlJdGVyYXRvcihjb2xsKSB7XG4gICAgdmFyIGkgPSAtMTtcbiAgICB2YXIgbGVuID0gY29sbC5sZW5ndGg7XG4gICAgcmV0dXJuIGZ1bmN0aW9uIG5leHQoKSB7XG4gICAgICAgIHJldHVybiArK2kgPCBsZW4gPyB7dmFsdWU6IGNvbGxbaV0sIGtleTogaX0gOiBudWxsO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlRVMyMDE1SXRlcmF0b3IoaXRlcmF0b3IpIHtcbiAgICB2YXIgaSA9IC0xO1xuICAgIHJldHVybiBmdW5jdGlvbiBuZXh0KCkge1xuICAgICAgICB2YXIgaXRlbSA9IGl0ZXJhdG9yLm5leHQoKTtcbiAgICAgICAgaWYgKGl0ZW0uZG9uZSlcbiAgICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICBpKys7XG4gICAgICAgIHJldHVybiB7dmFsdWU6IGl0ZW0udmFsdWUsIGtleTogaX07XG4gICAgfVxufVxuXG5mdW5jdGlvbiBjcmVhdGVPYmplY3RJdGVyYXRvcihvYmopIHtcbiAgICB2YXIgb2tleXMgPSBvYmogPyBPYmplY3Qua2V5cyhvYmopIDogW107XG4gICAgdmFyIGkgPSAtMTtcbiAgICB2YXIgbGVuID0gb2tleXMubGVuZ3RoO1xuICAgIHJldHVybiBmdW5jdGlvbiBuZXh0KCkge1xuICAgICAgICB2YXIga2V5ID0gb2tleXNbKytpXTtcbiAgICAgICAgaWYgKGtleSA9PT0gJ19fcHJvdG9fXycpIHtcbiAgICAgICAgICAgIHJldHVybiBuZXh0KCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGkgPCBsZW4gPyB7dmFsdWU6IG9ialtrZXldLCBrZXl9IDogbnVsbDtcbiAgICB9O1xufVxuXG5mdW5jdGlvbiBjcmVhdGVJdGVyYXRvcihjb2xsKSB7XG4gICAgaWYgKGlzQXJyYXlMaWtlKGNvbGwpKSB7XG4gICAgICAgIHJldHVybiBjcmVhdGVBcnJheUl0ZXJhdG9yKGNvbGwpO1xuICAgIH1cblxuICAgIHZhciBpdGVyYXRvciA9IGdldEl0ZXJhdG9yKGNvbGwpO1xuICAgIHJldHVybiBpdGVyYXRvciA/IGNyZWF0ZUVTMjAxNUl0ZXJhdG9yKGl0ZXJhdG9yKSA6IGNyZWF0ZU9iamVjdEl0ZXJhdG9yKGNvbGwpO1xufVxuXG5mdW5jdGlvbiBvbmx5T25jZShmbikge1xuICAgIHJldHVybiBmdW5jdGlvbiAoLi4uYXJncykge1xuICAgICAgICBpZiAoZm4gPT09IG51bGwpIHRocm93IG5ldyBFcnJvcihcIkNhbGxiYWNrIHdhcyBhbHJlYWR5IGNhbGxlZC5cIik7XG4gICAgICAgIHZhciBjYWxsRm4gPSBmbjtcbiAgICAgICAgZm4gPSBudWxsO1xuICAgICAgICBjYWxsRm4uYXBwbHkodGhpcywgYXJncyk7XG4gICAgfTtcbn1cblxuLy8gZm9yIGFzeW5jIGdlbmVyYXRvcnNcbmZ1bmN0aW9uIGFzeW5jRWFjaE9mTGltaXQoZ2VuZXJhdG9yLCBsaW1pdCwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgbGV0IGRvbmUgPSBmYWxzZTtcbiAgICBsZXQgY2FuY2VsZWQgPSBmYWxzZTtcbiAgICBsZXQgYXdhaXRpbmcgPSBmYWxzZTtcbiAgICBsZXQgcnVubmluZyA9IDA7XG4gICAgbGV0IGlkeCA9IDA7XG5cbiAgICBmdW5jdGlvbiByZXBsZW5pc2goKSB7XG4gICAgICAgIC8vY29uc29sZS5sb2coJ3JlcGxlbmlzaCcpXG4gICAgICAgIGlmIChydW5uaW5nID49IGxpbWl0IHx8IGF3YWl0aW5nIHx8IGRvbmUpIHJldHVyblxuICAgICAgICAvL2NvbnNvbGUubG9nKCdyZXBsZW5pc2ggYXdhaXRpbmcnKVxuICAgICAgICBhd2FpdGluZyA9IHRydWU7XG4gICAgICAgIGdlbmVyYXRvci5uZXh0KCkudGhlbigoe3ZhbHVlLCBkb25lOiBpdGVyRG9uZX0pID0+IHtcbiAgICAgICAgICAgIC8vY29uc29sZS5sb2coJ2dvdCB2YWx1ZScsIHZhbHVlKVxuICAgICAgICAgICAgaWYgKGNhbmNlbGVkIHx8IGRvbmUpIHJldHVyblxuICAgICAgICAgICAgYXdhaXRpbmcgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmIChpdGVyRG9uZSkge1xuICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGlmIChydW5uaW5nIDw9IDApIHtcbiAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZygnZG9uZSBuZXh0Q2InKVxuICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcnVubmluZysrO1xuICAgICAgICAgICAgaXRlcmF0ZWUodmFsdWUsIGlkeCwgaXRlcmF0ZWVDYWxsYmFjayk7XG4gICAgICAgICAgICBpZHgrKztcbiAgICAgICAgICAgIHJlcGxlbmlzaCgpO1xuICAgICAgICB9KS5jYXRjaChoYW5kbGVFcnJvcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gaXRlcmF0ZWVDYWxsYmFjayhlcnIsIHJlc3VsdCkge1xuICAgICAgICAvL2NvbnNvbGUubG9nKCdpdGVyYXRlZUNhbGxiYWNrJylcbiAgICAgICAgcnVubmluZyAtPSAxO1xuICAgICAgICBpZiAoY2FuY2VsZWQpIHJldHVyblxuICAgICAgICBpZiAoZXJyKSByZXR1cm4gaGFuZGxlRXJyb3IoZXJyKVxuXG4gICAgICAgIGlmIChlcnIgPT09IGZhbHNlKSB7XG4gICAgICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICAgICAgICAgIGNhbmNlbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHJlc3VsdCA9PT0gYnJlYWtMb29wIHx8IChkb25lICYmIHJ1bm5pbmcgPD0gMCkpIHtcbiAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgLy9jb25zb2xlLmxvZygnZG9uZSBpdGVyQ2InKVxuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuICAgICAgICB9XG4gICAgICAgIHJlcGxlbmlzaCgpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGhhbmRsZUVycm9yKGVycikge1xuICAgICAgICBpZiAoY2FuY2VsZWQpIHJldHVyblxuICAgICAgICBhd2FpdGluZyA9IGZhbHNlO1xuICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICAgICAgY2FsbGJhY2soZXJyKTtcbiAgICB9XG5cbiAgICByZXBsZW5pc2goKTtcbn1cblxudmFyIGVhY2hPZkxpbWl0JDIgPSAobGltaXQpID0+IHtcbiAgICByZXR1cm4gKG9iaiwgaXRlcmF0ZWUsIGNhbGxiYWNrKSA9PiB7XG4gICAgICAgIGNhbGxiYWNrID0gb25jZShjYWxsYmFjayk7XG4gICAgICAgIGlmIChsaW1pdCA8PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgUmFuZ2VFcnJvcignY29uY3VycmVuY3kgbGltaXQgY2Fubm90IGJlIGxlc3MgdGhhbiAxJylcbiAgICAgICAgfVxuICAgICAgICBpZiAoIW9iaikge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpc0FzeW5jR2VuZXJhdG9yKG9iaikpIHtcbiAgICAgICAgICAgIHJldHVybiBhc3luY0VhY2hPZkxpbWl0KG9iaiwgbGltaXQsIGl0ZXJhdGVlLCBjYWxsYmFjaylcbiAgICAgICAgfVxuICAgICAgICBpZiAoaXNBc3luY0l0ZXJhYmxlKG9iaikpIHtcbiAgICAgICAgICAgIHJldHVybiBhc3luY0VhY2hPZkxpbWl0KG9ialtTeW1ib2wuYXN5bmNJdGVyYXRvcl0oKSwgbGltaXQsIGl0ZXJhdGVlLCBjYWxsYmFjaylcbiAgICAgICAgfVxuICAgICAgICB2YXIgbmV4dEVsZW0gPSBjcmVhdGVJdGVyYXRvcihvYmopO1xuICAgICAgICB2YXIgZG9uZSA9IGZhbHNlO1xuICAgICAgICB2YXIgY2FuY2VsZWQgPSBmYWxzZTtcbiAgICAgICAgdmFyIHJ1bm5pbmcgPSAwO1xuICAgICAgICB2YXIgbG9vcGluZyA9IGZhbHNlO1xuXG4gICAgICAgIGZ1bmN0aW9uIGl0ZXJhdGVlQ2FsbGJhY2soZXJyLCB2YWx1ZSkge1xuICAgICAgICAgICAgaWYgKGNhbmNlbGVkKSByZXR1cm5cbiAgICAgICAgICAgIHJ1bm5pbmcgLT0gMTtcbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICBkb25lID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjYWxsYmFjayhlcnIpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSBpZiAoZXJyID09PSBmYWxzZSkge1xuICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIGNhbmNlbGVkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKHZhbHVlID09PSBicmVha0xvb3AgfHwgKGRvbmUgJiYgcnVubmluZyA8PSAwKSkge1xuICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKCFsb29waW5nKSB7XG4gICAgICAgICAgICAgICAgcmVwbGVuaXNoKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiByZXBsZW5pc2ggKCkge1xuICAgICAgICAgICAgbG9vcGluZyA9IHRydWU7XG4gICAgICAgICAgICB3aGlsZSAocnVubmluZyA8IGxpbWl0ICYmICFkb25lKSB7XG4gICAgICAgICAgICAgICAgdmFyIGVsZW0gPSBuZXh0RWxlbSgpO1xuICAgICAgICAgICAgICAgIGlmIChlbGVtID09PSBudWxsKSB7XG4gICAgICAgICAgICAgICAgICAgIGRvbmUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBpZiAocnVubmluZyA8PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJ1bm5pbmcgKz0gMTtcbiAgICAgICAgICAgICAgICBpdGVyYXRlZShlbGVtLnZhbHVlLCBlbGVtLmtleSwgb25seU9uY2UoaXRlcmF0ZWVDYWxsYmFjaykpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbG9vcGluZyA9IGZhbHNlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVwbGVuaXNoKCk7XG4gICAgfTtcbn07XG5cbi8qKlxuICogVGhlIHNhbWUgYXMgW2BlYWNoT2ZgXXtAbGluayBtb2R1bGU6Q29sbGVjdGlvbnMuZWFjaE9mfSBidXQgcnVucyBhIG1heGltdW0gb2YgYGxpbWl0YCBhc3luYyBvcGVyYXRpb25zIGF0IGFcbiAqIHRpbWUuXG4gKlxuICogQG5hbWUgZWFjaE9mTGltaXRcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29sbGVjdGlvbnNcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLmVhY2hPZl17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLmVhY2hPZn1cbiAqIEBhbGlhcyBmb3JFYWNoT2ZMaW1pdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IGNvbGwgLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtudW1iZXJ9IGxpbWl0IC0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGFzeW5jIG9wZXJhdGlvbnMgYXQgYSB0aW1lLlxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEFuIGFzeW5jIGZ1bmN0aW9uIHRvIGFwcGx5IHRvIGVhY2hcbiAqIGl0ZW0gaW4gYGNvbGxgLiBUaGUgYGtleWAgaXMgdGhlIGl0ZW0ncyBrZXksIG9yIGluZGV4IGluIHRoZSBjYXNlIG9mIGFuXG4gKiBhcnJheS5cbiAqIEludm9rZWQgd2l0aCAoaXRlbSwga2V5LCBjYWxsYmFjaykuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdIC0gQSBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgd2hlbiBhbGxcbiAqIGBpdGVyYXRlZWAgZnVuY3Rpb25zIGhhdmUgZmluaXNoZWQsIG9yIGFuIGVycm9yIG9jY3Vycy4gSW52b2tlZCB3aXRoIChlcnIpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgYSBjYWxsYmFjayBpcyBvbWl0dGVkXG4gKi9cbmZ1bmN0aW9uIGVhY2hPZkxpbWl0KGNvbGwsIGxpbWl0LCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gZWFjaE9mTGltaXQkMihsaW1pdCkoY29sbCwgd3JhcEFzeW5jKGl0ZXJhdGVlKSwgY2FsbGJhY2spO1xufVxuXG52YXIgZWFjaE9mTGltaXQkMSA9IGF3YWl0aWZ5KGVhY2hPZkxpbWl0LCA0KTtcblxuLy8gZWFjaE9mIGltcGxlbWVudGF0aW9uIG9wdGltaXplZCBmb3IgYXJyYXktbGlrZXNcbmZ1bmN0aW9uIGVhY2hPZkFycmF5TGlrZShjb2xsLCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IG9uY2UoY2FsbGJhY2spO1xuICAgIHZhciBpbmRleCA9IDAsXG4gICAgICAgIGNvbXBsZXRlZCA9IDAsXG4gICAgICAgIHtsZW5ndGh9ID0gY29sbCxcbiAgICAgICAgY2FuY2VsZWQgPSBmYWxzZTtcbiAgICBpZiAobGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGNhbGxiYWNrKG51bGwpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGl0ZXJhdG9yQ2FsbGJhY2soZXJyLCB2YWx1ZSkge1xuICAgICAgICBpZiAoZXJyID09PSBmYWxzZSkge1xuICAgICAgICAgICAgY2FuY2VsZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjYW5jZWxlZCA9PT0gdHJ1ZSkgcmV0dXJuXG4gICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGVycik7XG4gICAgICAgIH0gZWxzZSBpZiAoKCsrY29tcGxldGVkID09PSBsZW5ndGgpIHx8IHZhbHVlID09PSBicmVha0xvb3ApIHtcbiAgICAgICAgICAgIGNhbGxiYWNrKG51bGwpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZm9yICg7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICAgIGl0ZXJhdGVlKGNvbGxbaW5kZXhdLCBpbmRleCwgb25seU9uY2UoaXRlcmF0b3JDYWxsYmFjaykpO1xuICAgIH1cbn1cblxuLy8gYSBnZW5lcmljIHZlcnNpb24gb2YgZWFjaE9mIHdoaWNoIGNhbiBoYW5kbGUgYXJyYXksIG9iamVjdCwgYW5kIGl0ZXJhdG9yIGNhc2VzLlxuZnVuY3Rpb24gZWFjaE9mR2VuZXJpYyAoY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGVhY2hPZkxpbWl0JDEoY29sbCwgSW5maW5pdHksIGl0ZXJhdGVlLCBjYWxsYmFjayk7XG59XG5cbi8qKlxuICogTGlrZSBbYGVhY2hgXXtAbGluayBtb2R1bGU6Q29sbGVjdGlvbnMuZWFjaH0sIGV4Y2VwdCB0aGF0IGl0IHBhc3NlcyB0aGUga2V5IChvciBpbmRleCkgYXMgdGhlIHNlY29uZCBhcmd1bWVudFxuICogdG8gdGhlIGl0ZXJhdGVlLlxuICpcbiAqIEBuYW1lIGVhY2hPZlxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb2xsZWN0aW9uc1xuICogQG1ldGhvZFxuICogQGFsaWFzIGZvckVhY2hPZlxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBzZWUgW2FzeW5jLmVhY2hde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5lYWNofVxuICogQHBhcmFtIHtBcnJheXxJdGVyYWJsZXxBc3luY0l0ZXJhYmxlfE9iamVjdH0gY29sbCAtIEEgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IGl0ZXJhdGVlIC0gQSBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoXG4gKiBpdGVtIGluIGBjb2xsYC5cbiAqIFRoZSBga2V5YCBpcyB0aGUgaXRlbSdzIGtleSwgb3IgaW5kZXggaW4gdGhlIGNhc2Ugb2YgYW4gYXJyYXkuXG4gKiBJbnZva2VkIHdpdGggKGl0ZW0sIGtleSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIHdoZW4gYWxsXG4gKiBgaXRlcmF0ZWVgIGZ1bmN0aW9ucyBoYXZlIGZpbmlzaGVkLCBvciBhbiBlcnJvciBvY2N1cnMuIEludm9rZWQgd2l0aCAoZXJyKS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIGEgY2FsbGJhY2sgaXMgb21pdHRlZFxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBkZXYuanNvbiBpcyBhIGZpbGUgY29udGFpbmluZyBhIHZhbGlkIGpzb24gb2JqZWN0IGNvbmZpZyBmb3IgZGV2IGVudmlyb25tZW50XG4gKiAvLyBkZXYuanNvbiBpcyBhIGZpbGUgY29udGFpbmluZyBhIHZhbGlkIGpzb24gb2JqZWN0IGNvbmZpZyBmb3IgdGVzdCBlbnZpcm9ubWVudFxuICogLy8gcHJvZC5qc29uIGlzIGEgZmlsZSBjb250YWluaW5nIGEgdmFsaWQganNvbiBvYmplY3QgY29uZmlnIGZvciBwcm9kIGVudmlyb25tZW50XG4gKiAvLyBpbnZhbGlkLmpzb24gaXMgYSBmaWxlIHdpdGggYSBtYWxmb3JtZWQganNvbiBvYmplY3RcbiAqXG4gKiBsZXQgY29uZmlncyA9IHt9OyAvL2dsb2JhbCB2YXJpYWJsZVxuICogbGV0IHZhbGlkQ29uZmlnRmlsZU1hcCA9IHtkZXY6ICdkZXYuanNvbicsIHRlc3Q6ICd0ZXN0Lmpzb24nLCBwcm9kOiAncHJvZC5qc29uJ307XG4gKiBsZXQgaW52YWxpZENvbmZpZ0ZpbGVNYXAgPSB7ZGV2OiAnZGV2Lmpzb24nLCB0ZXN0OiAndGVzdC5qc29uJywgaW52YWxpZDogJ2ludmFsaWQuanNvbid9O1xuICpcbiAqIC8vIGFzeW5jaHJvbm91cyBmdW5jdGlvbiB0aGF0IHJlYWRzIGEganNvbiBmaWxlIGFuZCBwYXJzZXMgdGhlIGNvbnRlbnRzIGFzIGpzb24gb2JqZWN0XG4gKiBmdW5jdGlvbiBwYXJzZUZpbGUoZmlsZSwga2V5LCBjYWxsYmFjaykge1xuICogICAgIGZzLnJlYWRGaWxlKGZpbGUsIFwidXRmOFwiLCBmdW5jdGlvbihlcnIsIGRhdGEpIHtcbiAqICAgICAgICAgaWYgKGVycikgcmV0dXJuIGNhbGJhY2soZXJyKTtcbiAqICAgICAgICAgdHJ5IHtcbiAqICAgICAgICAgICAgIGNvbmZpZ3Nba2V5XSA9IEpTT04ucGFyc2UoZGF0YSk7XG4gKiAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAqICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlKTtcbiAqICAgICAgICAgfVxuICogICAgICAgICBjYWxsYmFjaygpO1xuICogICAgIH0pO1xuICogfVxuICpcbiAqIC8vIFVzaW5nIGNhbGxiYWNrc1xuICogYXN5bmMuZm9yRWFjaE9mKHZhbGlkQ29uZmlnRmlsZU1hcCwgcGFyc2VGaWxlLCBmdW5jdGlvbiAoZXJyKSB7XG4gKiAgICAgaWYgKGVycikge1xuICogICAgICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gKiAgICAgfSBlbHNlIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coY29uZmlncyk7XG4gKiAgICAgICAgIC8vIGNvbmZpZ3MgaXMgbm93IGEgbWFwIG9mIEpTT04gZGF0YSwgZS5nLlxuICogICAgICAgICAvLyB7IGRldjogLy9wYXJzZWQgZGV2Lmpzb24sIHRlc3Q6IC8vcGFyc2VkIHRlc3QuanNvbiwgcHJvZDogLy9wYXJzZWQgcHJvZC5qc29ufVxuICogICAgIH1cbiAqIH0pO1xuICpcbiAqIC8vRXJyb3IgaGFuZGluZ1xuICogYXN5bmMuZm9yRWFjaE9mKGludmFsaWRDb25maWdGaWxlTWFwLCBwYXJzZUZpbGUsIGZ1bmN0aW9uIChlcnIpIHtcbiAqICAgICBpZiAoZXJyKSB7XG4gKiAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAqICAgICAgICAgLy8gSlNPTiBwYXJzZSBlcnJvciBleGNlcHRpb25cbiAqICAgICB9IGVsc2Uge1xuICogICAgICAgICBjb25zb2xlLmxvZyhjb25maWdzKTtcbiAqICAgICB9XG4gKiB9KTtcbiAqXG4gKiAvLyBVc2luZyBQcm9taXNlc1xuICogYXN5bmMuZm9yRWFjaE9mKHZhbGlkQ29uZmlnRmlsZU1hcCwgcGFyc2VGaWxlKVxuICogLnRoZW4oICgpID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhjb25maWdzKTtcbiAqICAgICAvLyBjb25maWdzIGlzIG5vdyBhIG1hcCBvZiBKU09OIGRhdGEsIGUuZy5cbiAqICAgICAvLyB7IGRldjogLy9wYXJzZWQgZGV2Lmpzb24sIHRlc3Q6IC8vcGFyc2VkIHRlc3QuanNvbiwgcHJvZDogLy9wYXJzZWQgcHJvZC5qc29ufVxuICogfSkuY2F0Y2goIGVyciA9PiB7XG4gKiAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICogfSk7XG4gKlxuICogLy9FcnJvciBoYW5kaW5nXG4gKiBhc3luYy5mb3JFYWNoT2YoaW52YWxpZENvbmZpZ0ZpbGVNYXAsIHBhcnNlRmlsZSlcbiAqIC50aGVuKCAoKSA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coY29uZmlncyk7XG4gKiB9KS5jYXRjaCggZXJyID0+IHtcbiAqICAgICBjb25zb2xlLmVycm9yKGVycik7XG4gKiAgICAgLy8gSlNPTiBwYXJzZSBlcnJvciBleGNlcHRpb25cbiAqIH0pO1xuICpcbiAqIC8vIFVzaW5nIGFzeW5jL2F3YWl0XG4gKiBhc3luYyAoKSA9PiB7XG4gKiAgICAgdHJ5IHtcbiAqICAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IGFzeW5jLmZvckVhY2hPZih2YWxpZENvbmZpZ0ZpbGVNYXAsIHBhcnNlRmlsZSk7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKGNvbmZpZ3MpO1xuICogICAgICAgICAvLyBjb25maWdzIGlzIG5vdyBhIG1hcCBvZiBKU09OIGRhdGEsIGUuZy5cbiAqICAgICAgICAgLy8geyBkZXY6IC8vcGFyc2VkIGRldi5qc29uLCB0ZXN0OiAvL3BhcnNlZCB0ZXN0Lmpzb24sIHByb2Q6IC8vcGFyc2VkIHByb2QuanNvbn1cbiAqICAgICB9XG4gKiAgICAgY2F0Y2ggKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgIH1cbiAqIH1cbiAqXG4gKiAvL0Vycm9yIGhhbmRpbmdcbiAqIGFzeW5jICgpID0+IHtcbiAqICAgICB0cnkge1xuICogICAgICAgICBsZXQgcmVzdWx0ID0gYXdhaXQgYXN5bmMuZm9yRWFjaE9mKGludmFsaWRDb25maWdGaWxlTWFwLCBwYXJzZUZpbGUpO1xuICogICAgICAgICBjb25zb2xlLmxvZyhjb25maWdzKTtcbiAqICAgICB9XG4gKiAgICAgY2F0Y2ggKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgICAgICAvLyBKU09OIHBhcnNlIGVycm9yIGV4Y2VwdGlvblxuICogICAgIH1cbiAqIH1cbiAqXG4gKi9cbmZ1bmN0aW9uIGVhY2hPZihjb2xsLCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgZWFjaE9mSW1wbGVtZW50YXRpb24gPSBpc0FycmF5TGlrZShjb2xsKSA/IGVhY2hPZkFycmF5TGlrZSA6IGVhY2hPZkdlbmVyaWM7XG4gICAgcmV0dXJuIGVhY2hPZkltcGxlbWVudGF0aW9uKGNvbGwsIHdyYXBBc3luYyhpdGVyYXRlZSksIGNhbGxiYWNrKTtcbn1cblxudmFyIGVhY2hPZiQxID0gYXdhaXRpZnkoZWFjaE9mLCAzKTtcblxuLyoqXG4gKiBQcm9kdWNlcyBhIG5ldyBjb2xsZWN0aW9uIG9mIHZhbHVlcyBieSBtYXBwaW5nIGVhY2ggdmFsdWUgaW4gYGNvbGxgIHRocm91Z2hcbiAqIHRoZSBgaXRlcmF0ZWVgIGZ1bmN0aW9uLiBUaGUgYGl0ZXJhdGVlYCBpcyBjYWxsZWQgd2l0aCBhbiBpdGVtIGZyb20gYGNvbGxgXG4gKiBhbmQgYSBjYWxsYmFjayBmb3Igd2hlbiBpdCBoYXMgZmluaXNoZWQgcHJvY2Vzc2luZy4gRWFjaCBvZiB0aGVzZSBjYWxsYmFja3NcbiAqIHRha2VzIDIgYXJndW1lbnRzOiBhbiBgZXJyb3JgLCBhbmQgdGhlIHRyYW5zZm9ybWVkIGl0ZW0gZnJvbSBgY29sbGAuIElmXG4gKiBgaXRlcmF0ZWVgIHBhc3NlcyBhbiBlcnJvciB0byBpdHMgY2FsbGJhY2ssIHRoZSBtYWluIGBjYWxsYmFja2AgKGZvciB0aGVcbiAqIGBtYXBgIGZ1bmN0aW9uKSBpcyBpbW1lZGlhdGVseSBjYWxsZWQgd2l0aCB0aGUgZXJyb3IuXG4gKlxuICogTm90ZSwgdGhhdCBzaW5jZSB0aGlzIGZ1bmN0aW9uIGFwcGxpZXMgdGhlIGBpdGVyYXRlZWAgdG8gZWFjaCBpdGVtIGluXG4gKiBwYXJhbGxlbCwgdGhlcmUgaXMgbm8gZ3VhcmFudGVlIHRoYXQgdGhlIGBpdGVyYXRlZWAgZnVuY3Rpb25zIHdpbGwgY29tcGxldGVcbiAqIGluIG9yZGVyLiBIb3dldmVyLCB0aGUgcmVzdWx0cyBhcnJheSB3aWxsIGJlIGluIHRoZSBzYW1lIG9yZGVyIGFzIHRoZVxuICogb3JpZ2luYWwgYGNvbGxgLlxuICpcbiAqIElmIGBtYXBgIGlzIHBhc3NlZCBhbiBPYmplY3QsIHRoZSByZXN1bHRzIHdpbGwgYmUgYW4gQXJyYXkuICBUaGUgcmVzdWx0c1xuICogd2lsbCByb3VnaGx5IGJlIGluIHRoZSBvcmRlciBvZiB0aGUgb3JpZ2luYWwgT2JqZWN0cycga2V5cyAoYnV0IHRoaXMgY2FuXG4gKiB2YXJ5IGFjcm9zcyBKYXZhU2NyaXB0IGVuZ2luZXMpLlxuICpcbiAqIEBuYW1lIG1hcFxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb2xsZWN0aW9uc1xuICogQG1ldGhvZFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IGNvbGwgLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEFuIGFzeW5jIGZ1bmN0aW9uIHRvIGFwcGx5IHRvIGVhY2ggaXRlbSBpblxuICogYGNvbGxgLlxuICogVGhlIGl0ZXJhdGVlIHNob3VsZCBjb21wbGV0ZSB3aXRoIHRoZSB0cmFuc2Zvcm1lZCBpdGVtLlxuICogSW52b2tlZCB3aXRoIChpdGVtLCBjYWxsYmFjaykuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdIC0gQSBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgd2hlbiBhbGwgYGl0ZXJhdGVlYFxuICogZnVuY3Rpb25zIGhhdmUgZmluaXNoZWQsIG9yIGFuIGVycm9yIG9jY3Vycy4gUmVzdWx0cyBpcyBhbiBBcnJheSBvZiB0aGVcbiAqIHRyYW5zZm9ybWVkIGl0ZW1zIGZyb20gdGhlIGBjb2xsYC4gSW52b2tlZCB3aXRoIChlcnIsIHJlc3VsdHMpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgbm8gY2FsbGJhY2sgaXMgcGFzc2VkXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIGZpbGUxLnR4dCBpcyBhIGZpbGUgdGhhdCBpcyAxMDAwIGJ5dGVzIGluIHNpemVcbiAqIC8vIGZpbGUyLnR4dCBpcyBhIGZpbGUgdGhhdCBpcyAyMDAwIGJ5dGVzIGluIHNpemVcbiAqIC8vIGZpbGUzLnR4dCBpcyBhIGZpbGUgdGhhdCBpcyAzMDAwIGJ5dGVzIGluIHNpemVcbiAqIC8vIGZpbGU0LnR4dCBkb2VzIG5vdCBleGlzdFxuICpcbiAqIGNvbnN0IGZpbGVMaXN0ID0gWydmaWxlMS50eHQnLCdmaWxlMi50eHQnLCdmaWxlMy50eHQnXTtcbiAqIGNvbnN0IHdpdGhNaXNzaW5nRmlsZUxpc3QgPSBbJ2ZpbGUxLnR4dCcsJ2ZpbGUyLnR4dCcsJ2ZpbGU0LnR4dCddO1xuICpcbiAqIC8vIGFzeW5jaHJvbm91cyBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIGZpbGUgc2l6ZSBpbiBieXRlc1xuICogZnVuY3Rpb24gZ2V0RmlsZVNpemVJbkJ5dGVzKGZpbGUsIGNhbGxiYWNrKSB7XG4gKiAgICAgZnMuc3RhdChmaWxlLCBmdW5jdGlvbihlcnIsIHN0YXQpIHtcbiAqICAgICAgICAgaWYgKGVycikge1xuICogICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gKiAgICAgICAgIH1cbiAqICAgICAgICAgY2FsbGJhY2sobnVsbCwgc3RhdC5zaXplKTtcbiAqICAgICB9KTtcbiAqIH1cbiAqXG4gKiAvLyBVc2luZyBjYWxsYmFja3NcbiAqIGFzeW5jLm1hcChmaWxlTGlzdCwgZ2V0RmlsZVNpemVJbkJ5dGVzLCBmdW5jdGlvbihlcnIsIHJlc3VsdHMpIHtcbiAqICAgICBpZiAoZXJyKSB7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiAgICAgfSBlbHNlIHtcbiAqICAgICAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiAgICAgICAgIC8vIHJlc3VsdHMgaXMgbm93IGFuIGFycmF5IG9mIHRoZSBmaWxlIHNpemUgaW4gYnl0ZXMgZm9yIGVhY2ggZmlsZSwgZS5nLlxuICogICAgICAgICAvLyBbIDEwMDAsIDIwMDAsIDMwMDBdXG4gKiAgICAgfVxuICogfSk7XG4gKlxuICogLy8gRXJyb3IgSGFuZGxpbmdcbiAqIGFzeW5jLm1hcCh3aXRoTWlzc2luZ0ZpbGVMaXN0LCBnZXRGaWxlU2l6ZUluQnl0ZXMsIGZ1bmN0aW9uKGVyciwgcmVzdWx0cykge1xuICogICAgIGlmIChlcnIpIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICAgICAgLy8gWyBFcnJvcjogRU5PRU5UOiBubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5IF1cbiAqICAgICB9IGVsc2Uge1xuICogICAgICAgICBjb25zb2xlLmxvZyhyZXN1bHRzKTtcbiAqICAgICB9XG4gKiB9KTtcbiAqXG4gKiAvLyBVc2luZyBQcm9taXNlc1xuICogYXN5bmMubWFwKGZpbGVMaXN0LCBnZXRGaWxlU2l6ZUluQnl0ZXMpXG4gKiAudGhlbiggcmVzdWx0cyA9PiB7XG4gKiAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiAgICAgLy8gcmVzdWx0cyBpcyBub3cgYW4gYXJyYXkgb2YgdGhlIGZpbGUgc2l6ZSBpbiBieXRlcyBmb3IgZWFjaCBmaWxlLCBlLmcuXG4gKiAgICAgLy8gWyAxMDAwLCAyMDAwLCAzMDAwXVxuICogfSkuY2F0Y2goIGVyciA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqIH0pO1xuICpcbiAqIC8vIEVycm9yIEhhbmRsaW5nXG4gKiBhc3luYy5tYXAod2l0aE1pc3NpbmdGaWxlTGlzdCwgZ2V0RmlsZVNpemVJbkJ5dGVzKVxuICogLnRoZW4oIHJlc3VsdHMgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKHJlc3VsdHMpO1xuICogfSkuY2F0Y2goIGVyciA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICAvLyBbIEVycm9yOiBFTk9FTlQ6IG5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkgXVxuICogfSk7XG4gKlxuICogLy8gVXNpbmcgYXN5bmMvYXdhaXRcbiAqIGFzeW5jICgpID0+IHtcbiAqICAgICB0cnkge1xuICogICAgICAgICBsZXQgcmVzdWx0cyA9IGF3YWl0IGFzeW5jLm1hcChmaWxlTGlzdCwgZ2V0RmlsZVNpemVJbkJ5dGVzKTtcbiAqICAgICAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiAgICAgICAgIC8vIHJlc3VsdHMgaXMgbm93IGFuIGFycmF5IG9mIHRoZSBmaWxlIHNpemUgaW4gYnl0ZXMgZm9yIGVhY2ggZmlsZSwgZS5nLlxuICogICAgICAgICAvLyBbIDEwMDAsIDIwMDAsIDMwMDBdXG4gKiAgICAgfVxuICogICAgIGNhdGNoIChlcnIpIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICB9XG4gKiB9XG4gKlxuICogLy8gRXJyb3IgSGFuZGxpbmdcbiAqIGFzeW5jICgpID0+IHtcbiAqICAgICB0cnkge1xuICogICAgICAgICBsZXQgcmVzdWx0cyA9IGF3YWl0IGFzeW5jLm1hcCh3aXRoTWlzc2luZ0ZpbGVMaXN0LCBnZXRGaWxlU2l6ZUluQnl0ZXMpO1xuICogICAgICAgICBjb25zb2xlLmxvZyhyZXN1bHRzKTtcbiAqICAgICB9XG4gKiAgICAgY2F0Y2ggKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgICAgICAvLyBbIEVycm9yOiBFTk9FTlQ6IG5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkgXVxuICogICAgIH1cbiAqIH1cbiAqXG4gKi9cbmZ1bmN0aW9uIG1hcCAoY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIF9hc3luY01hcChlYWNoT2YkMSwgY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKVxufVxudmFyIG1hcCQxID0gYXdhaXRpZnkobWFwLCAzKTtcblxuLyoqXG4gKiBBcHBsaWVzIHRoZSBwcm92aWRlZCBhcmd1bWVudHMgdG8gZWFjaCBmdW5jdGlvbiBpbiB0aGUgYXJyYXksIGNhbGxpbmdcbiAqIGBjYWxsYmFja2AgYWZ0ZXIgYWxsIGZ1bmN0aW9ucyBoYXZlIGNvbXBsZXRlZC4gSWYgeW91IG9ubHkgcHJvdmlkZSB0aGUgZmlyc3RcbiAqIGFyZ3VtZW50LCBgZm5zYCwgdGhlbiBpdCB3aWxsIHJldHVybiBhIGZ1bmN0aW9uIHdoaWNoIGxldHMgeW91IHBhc3MgaW4gdGhlXG4gKiBhcmd1bWVudHMgYXMgaWYgaXQgd2VyZSBhIHNpbmdsZSBmdW5jdGlvbiBjYWxsLiBJZiBtb3JlIGFyZ3VtZW50cyBhcmVcbiAqIHByb3ZpZGVkLCBgY2FsbGJhY2tgIGlzIHJlcXVpcmVkIHdoaWxlIGBhcmdzYCBpcyBzdGlsbCBvcHRpb25hbC4gVGhlIHJlc3VsdHNcbiAqIGZvciBlYWNoIG9mIHRoZSBhcHBsaWVkIGFzeW5jIGZ1bmN0aW9ucyBhcmUgcGFzc2VkIHRvIHRoZSBmaW5hbCBjYWxsYmFja1xuICogYXMgYW4gYXJyYXkuXG4gKlxuICogQG5hbWUgYXBwbHlFYWNoXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbnRyb2xGbG93XG4gKiBAbWV0aG9kXG4gKiBAY2F0ZWdvcnkgQ29udHJvbCBGbG93XG4gKiBAcGFyYW0ge0FycmF5fEl0ZXJhYmxlfEFzeW5jSXRlcmFibGV8T2JqZWN0fSBmbnMgLSBBIGNvbGxlY3Rpb24gb2Yge0BsaW5rIEFzeW5jRnVuY3Rpb259c1xuICogdG8gYWxsIGNhbGwgd2l0aCB0aGUgc2FtZSBhcmd1bWVudHNcbiAqIEBwYXJhbSB7Li4uKn0gW2FyZ3NdIC0gYW55IG51bWJlciBvZiBzZXBhcmF0ZSBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGVcbiAqIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIHRoZSBmaW5hbCBhcmd1bWVudCBzaG91bGQgYmUgdGhlIGNhbGxiYWNrLFxuICogY2FsbGVkIHdoZW4gYWxsIGZ1bmN0aW9ucyBoYXZlIGNvbXBsZXRlZCBwcm9jZXNzaW5nLlxuICogQHJldHVybnMge0FzeW5jRnVuY3Rpb259IC0gUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgdGFrZXMgbm8gYXJncyBvdGhlciB0aGFuXG4gKiBhbiBvcHRpb25hbCBjYWxsYmFjaywgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGFwcGx5aW5nIHRoZSBgYXJnc2AgdG8gZWFjaFxuICogb2YgdGhlIGZ1bmN0aW9ucy5cbiAqIEBleGFtcGxlXG4gKlxuICogY29uc3QgYXBwbGllZEZuID0gYXN5bmMuYXBwbHlFYWNoKFtlbmFibGVTZWFyY2gsIHVwZGF0ZVNjaGVtYV0sICdidWNrZXQnKVxuICpcbiAqIGFwcGxpZWRGbigoZXJyLCByZXN1bHRzKSA9PiB7XG4gKiAgICAgLy8gcmVzdWx0c1swXSBpcyB0aGUgcmVzdWx0cyBmb3IgYGVuYWJsZVNlYXJjaGBcbiAqICAgICAvLyByZXN1bHRzWzFdIGlzIHRoZSByZXN1bHRzIGZvciBgdXBkYXRlU2NoZW1hYFxuICogfSk7XG4gKlxuICogLy8gcGFydGlhbCBhcHBsaWNhdGlvbiBleGFtcGxlOlxuICogYXN5bmMuZWFjaChcbiAqICAgICBidWNrZXRzLFxuICogICAgIGFzeW5jIChidWNrZXQpID0+IGFzeW5jLmFwcGx5RWFjaChbZW5hYmxlU2VhcmNoLCB1cGRhdGVTY2hlbWFdLCBidWNrZXQpKCksXG4gKiAgICAgY2FsbGJhY2tcbiAqICk7XG4gKi9cbnZhciBhcHBseUVhY2ggPSBhcHBseUVhY2gkMShtYXAkMSk7XG5cbi8qKlxuICogVGhlIHNhbWUgYXMgW2BlYWNoT2ZgXXtAbGluayBtb2R1bGU6Q29sbGVjdGlvbnMuZWFjaE9mfSBidXQgcnVucyBvbmx5IGEgc2luZ2xlIGFzeW5jIG9wZXJhdGlvbiBhdCBhIHRpbWUuXG4gKlxuICogQG5hbWUgZWFjaE9mU2VyaWVzXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbGxlY3Rpb25zXG4gKiBAbWV0aG9kXG4gKiBAc2VlIFthc3luYy5lYWNoT2Zde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5lYWNoT2Z9XG4gKiBAYWxpYXMgZm9yRWFjaE9mU2VyaWVzXG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxJdGVyYWJsZXxBc3luY0l0ZXJhYmxlfE9iamVjdH0gY29sbCAtIEEgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IGl0ZXJhdGVlIC0gQW4gYXN5bmMgZnVuY3Rpb24gdG8gYXBwbHkgdG8gZWFjaCBpdGVtIGluXG4gKiBgY29sbGAuXG4gKiBJbnZva2VkIHdpdGggKGl0ZW0sIGtleSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIHdoZW4gYWxsIGBpdGVyYXRlZWBcbiAqIGZ1bmN0aW9ucyBoYXZlIGZpbmlzaGVkLCBvciBhbiBlcnJvciBvY2N1cnMuIEludm9rZWQgd2l0aCAoZXJyKS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIGEgY2FsbGJhY2sgaXMgb21pdHRlZFxuICovXG5mdW5jdGlvbiBlYWNoT2ZTZXJpZXMoY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGVhY2hPZkxpbWl0JDEoY29sbCwgMSwgaXRlcmF0ZWUsIGNhbGxiYWNrKVxufVxudmFyIGVhY2hPZlNlcmllcyQxID0gYXdhaXRpZnkoZWFjaE9mU2VyaWVzLCAzKTtcblxuLyoqXG4gKiBUaGUgc2FtZSBhcyBbYG1hcGBde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5tYXB9IGJ1dCBydW5zIG9ubHkgYSBzaW5nbGUgYXN5bmMgb3BlcmF0aW9uIGF0IGEgdGltZS5cbiAqXG4gKiBAbmFtZSBtYXBTZXJpZXNcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29sbGVjdGlvbnNcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLm1hcF17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLm1hcH1cbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fEl0ZXJhYmxlfEFzeW5jSXRlcmFibGV8T2JqZWN0fSBjb2xsIC0gQSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7QXN5bmNGdW5jdGlvbn0gaXRlcmF0ZWUgLSBBbiBhc3luYyBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIGl0ZW0gaW5cbiAqIGBjb2xsYC5cbiAqIFRoZSBpdGVyYXRlZSBzaG91bGQgY29tcGxldGUgd2l0aCB0aGUgdHJhbnNmb3JtZWQgaXRlbS5cbiAqIEludm9rZWQgd2l0aCAoaXRlbSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIHdoZW4gYWxsIGBpdGVyYXRlZWBcbiAqIGZ1bmN0aW9ucyBoYXZlIGZpbmlzaGVkLCBvciBhbiBlcnJvciBvY2N1cnMuIFJlc3VsdHMgaXMgYW4gYXJyYXkgb2YgdGhlXG4gKiB0cmFuc2Zvcm1lZCBpdGVtcyBmcm9tIHRoZSBgY29sbGAuIEludm9rZWQgd2l0aCAoZXJyLCByZXN1bHRzKS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIG5vIGNhbGxiYWNrIGlzIHBhc3NlZFxuICovXG5mdW5jdGlvbiBtYXBTZXJpZXMgKGNvbGwsIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBfYXN5bmNNYXAoZWFjaE9mU2VyaWVzJDEsIGNvbGwsIGl0ZXJhdGVlLCBjYWxsYmFjaylcbn1cbnZhciBtYXBTZXJpZXMkMSA9IGF3YWl0aWZ5KG1hcFNlcmllcywgMyk7XG5cbi8qKlxuICogVGhlIHNhbWUgYXMgW2BhcHBseUVhY2hgXXtAbGluayBtb2R1bGU6Q29udHJvbEZsb3cuYXBwbHlFYWNofSBidXQgcnVucyBvbmx5IGEgc2luZ2xlIGFzeW5jIG9wZXJhdGlvbiBhdCBhIHRpbWUuXG4gKlxuICogQG5hbWUgYXBwbHlFYWNoU2VyaWVzXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbnRyb2xGbG93XG4gKiBAbWV0aG9kXG4gKiBAc2VlIFthc3luYy5hcHBseUVhY2hde0BsaW5rIG1vZHVsZTpDb250cm9sRmxvdy5hcHBseUVhY2h9XG4gKiBAY2F0ZWdvcnkgQ29udHJvbCBGbG93XG4gKiBAcGFyYW0ge0FycmF5fEl0ZXJhYmxlfEFzeW5jSXRlcmFibGV8T2JqZWN0fSBmbnMgLSBBIGNvbGxlY3Rpb24gb2Yge0BsaW5rIEFzeW5jRnVuY3Rpb259cyB0byBhbGxcbiAqIGNhbGwgd2l0aCB0aGUgc2FtZSBhcmd1bWVudHNcbiAqIEBwYXJhbSB7Li4uKn0gW2FyZ3NdIC0gYW55IG51bWJlciBvZiBzZXBhcmF0ZSBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGVcbiAqIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIHRoZSBmaW5hbCBhcmd1bWVudCBzaG91bGQgYmUgdGhlIGNhbGxiYWNrLFxuICogY2FsbGVkIHdoZW4gYWxsIGZ1bmN0aW9ucyBoYXZlIGNvbXBsZXRlZCBwcm9jZXNzaW5nLlxuICogQHJldHVybnMge0FzeW5jRnVuY3Rpb259IC0gQSBmdW5jdGlvbiwgdGhhdCB3aGVuIGNhbGxlZCwgaXMgdGhlIHJlc3VsdCBvZlxuICogYXBwbGluZyB0aGUgYGFyZ3NgIHRvIHRoZSBsaXN0IG9mIGZ1bmN0aW9ucy4gIEl0IHRha2VzIG5vIGFyZ3MsIG90aGVyIHRoYW5cbiAqIGEgY2FsbGJhY2suXG4gKi9cbnZhciBhcHBseUVhY2hTZXJpZXMgPSBhcHBseUVhY2gkMShtYXBTZXJpZXMkMSk7XG5cbmNvbnN0IFBST01JU0VfU1lNQk9MID0gU3ltYm9sKCdwcm9taXNlQ2FsbGJhY2snKTtcblxuZnVuY3Rpb24gcHJvbWlzZUNhbGxiYWNrICgpIHtcbiAgICBsZXQgcmVzb2x2ZSwgcmVqZWN0O1xuICAgIGZ1bmN0aW9uIGNhbGxiYWNrIChlcnIsIC4uLmFyZ3MpIHtcbiAgICAgICAgaWYgKGVycikgcmV0dXJuIHJlamVjdChlcnIpXG4gICAgICAgIHJlc29sdmUoYXJncy5sZW5ndGggPiAxID8gYXJncyA6IGFyZ3NbMF0pO1xuICAgIH1cblxuICAgIGNhbGxiYWNrW1BST01JU0VfU1lNQk9MXSA9IG5ldyBQcm9taXNlKChyZXMsIHJlaikgPT4ge1xuICAgICAgICByZXNvbHZlID0gcmVzLFxuICAgICAgICByZWplY3QgPSByZWo7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gY2FsbGJhY2tcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmVzIHRoZSBiZXN0IG9yZGVyIGZvciBydW5uaW5nIHRoZSB7QGxpbmsgQXN5bmNGdW5jdGlvbn1zIGluIGB0YXNrc2AsIGJhc2VkIG9uXG4gKiB0aGVpciByZXF1aXJlbWVudHMuIEVhY2ggZnVuY3Rpb24gY2FuIG9wdGlvbmFsbHkgZGVwZW5kIG9uIG90aGVyIGZ1bmN0aW9uc1xuICogYmVpbmcgY29tcGxldGVkIGZpcnN0LCBhbmQgZWFjaCBmdW5jdGlvbiBpcyBydW4gYXMgc29vbiBhcyBpdHMgcmVxdWlyZW1lbnRzXG4gKiBhcmUgc2F0aXNmaWVkLlxuICpcbiAqIElmIGFueSBvZiB0aGUge0BsaW5rIEFzeW5jRnVuY3Rpb259cyBwYXNzIGFuIGVycm9yIHRvIHRoZWlyIGNhbGxiYWNrLCB0aGUgYGF1dG9gIHNlcXVlbmNlXG4gKiB3aWxsIHN0b3AuIEZ1cnRoZXIgdGFza3Mgd2lsbCBub3QgZXhlY3V0ZSAoc28gYW55IG90aGVyIGZ1bmN0aW9ucyBkZXBlbmRpbmdcbiAqIG9uIGl0IHdpbGwgbm90IHJ1biksIGFuZCB0aGUgbWFpbiBgY2FsbGJhY2tgIGlzIGltbWVkaWF0ZWx5IGNhbGxlZCB3aXRoIHRoZVxuICogZXJyb3IuXG4gKlxuICoge0BsaW5rIEFzeW5jRnVuY3Rpb259cyBhbHNvIHJlY2VpdmUgYW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIHJlc3VsdHMgb2YgZnVuY3Rpb25zIHdoaWNoXG4gKiBoYXZlIGNvbXBsZXRlZCBzbyBmYXIgYXMgdGhlIGZpcnN0IGFyZ3VtZW50LCBpZiB0aGV5IGhhdmUgZGVwZW5kZW5jaWVzLiBJZiBhXG4gKiB0YXNrIGZ1bmN0aW9uIGhhcyBubyBkZXBlbmRlbmNpZXMsIGl0IHdpbGwgb25seSBiZSBwYXNzZWQgYSBjYWxsYmFjay5cbiAqXG4gKiBAbmFtZSBhdXRvXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbnRyb2xGbG93XG4gKiBAbWV0aG9kXG4gKiBAY2F0ZWdvcnkgQ29udHJvbCBGbG93XG4gKiBAcGFyYW0ge09iamVjdH0gdGFza3MgLSBBbiBvYmplY3QuIEVhY2ggb2YgaXRzIHByb3BlcnRpZXMgaXMgZWl0aGVyIGFcbiAqIGZ1bmN0aW9uIG9yIGFuIGFycmF5IG9mIHJlcXVpcmVtZW50cywgd2l0aCB0aGUge0BsaW5rIEFzeW5jRnVuY3Rpb259IGl0c2VsZiB0aGUgbGFzdCBpdGVtXG4gKiBpbiB0aGUgYXJyYXkuIFRoZSBvYmplY3QncyBrZXkgb2YgYSBwcm9wZXJ0eSBzZXJ2ZXMgYXMgdGhlIG5hbWUgb2YgdGhlIHRhc2tcbiAqIGRlZmluZWQgYnkgdGhhdCBwcm9wZXJ0eSwgaS5lLiBjYW4gYmUgdXNlZCB3aGVuIHNwZWNpZnlpbmcgcmVxdWlyZW1lbnRzIGZvclxuICogb3RoZXIgdGFza3MuIFRoZSBmdW5jdGlvbiByZWNlaXZlcyBvbmUgb3IgdHdvIGFyZ3VtZW50czpcbiAqICogYSBgcmVzdWx0c2Agb2JqZWN0LCBjb250YWluaW5nIHRoZSByZXN1bHRzIG9mIHRoZSBwcmV2aW91c2x5IGV4ZWN1dGVkXG4gKiAgIGZ1bmN0aW9ucywgb25seSBwYXNzZWQgaWYgdGhlIHRhc2sgaGFzIGFueSBkZXBlbmRlbmNpZXMsXG4gKiAqIGEgYGNhbGxiYWNrKGVyciwgcmVzdWx0KWAgZnVuY3Rpb24sIHdoaWNoIG11c3QgYmUgY2FsbGVkIHdoZW4gZmluaXNoZWQsXG4gKiAgIHBhc3NpbmcgYW4gYGVycm9yYCAod2hpY2ggY2FuIGJlIGBudWxsYCkgYW5kIHRoZSByZXN1bHQgb2YgdGhlIGZ1bmN0aW9uJ3NcbiAqICAgZXhlY3V0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IFtjb25jdXJyZW5jeT1JbmZpbml0eV0gLSBBbiBvcHRpb25hbCBgaW50ZWdlcmAgZm9yXG4gKiBkZXRlcm1pbmluZyB0aGUgbWF4aW11bSBudW1iZXIgb2YgdGFza3MgdGhhdCBjYW4gYmUgcnVuIGluIHBhcmFsbGVsLiBCeVxuICogZGVmYXVsdCwgYXMgbWFueSBhcyBwb3NzaWJsZS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYWxsYmFja10gLSBBbiBvcHRpb25hbCBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgd2hlbiBhbGxcbiAqIHRoZSB0YXNrcyBoYXZlIGJlZW4gY29tcGxldGVkLiBJdCByZWNlaXZlcyB0aGUgYGVycmAgYXJndW1lbnQgaWYgYW55IGB0YXNrc2BcbiAqIHBhc3MgYW4gZXJyb3IgdG8gdGhlaXIgY2FsbGJhY2suIFJlc3VsdHMgYXJlIGFsd2F5cyByZXR1cm5lZDsgaG93ZXZlciwgaWYgYW5cbiAqIGVycm9yIG9jY3Vycywgbm8gZnVydGhlciBgdGFza3NgIHdpbGwgYmUgcGVyZm9ybWVkLCBhbmQgdGhlIHJlc3VsdHMgb2JqZWN0XG4gKiB3aWxsIG9ubHkgY29udGFpbiBwYXJ0aWFsIHJlc3VsdHMuIEludm9rZWQgd2l0aCAoZXJyLCByZXN1bHRzKS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIGEgY2FsbGJhY2sgaXMgbm90IHBhc3NlZFxuICogQGV4YW1wbGVcbiAqXG4gKiAvL1VzaW5nIENhbGxiYWNrc1xuICogYXN5bmMuYXV0byh7XG4gKiAgICAgZ2V0X2RhdGE6IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIC8vIGFzeW5jIGNvZGUgdG8gZ2V0IHNvbWUgZGF0YVxuICogICAgICAgICBjYWxsYmFjayhudWxsLCAnZGF0YScsICdjb252ZXJ0ZWQgdG8gYXJyYXknKTtcbiAqICAgICB9LFxuICogICAgIG1ha2VfZm9sZGVyOiBmdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgICAgICAvLyBhc3luYyBjb2RlIHRvIGNyZWF0ZSBhIGRpcmVjdG9yeSB0byBzdG9yZSBhIGZpbGUgaW5cbiAqICAgICAgICAgLy8gdGhpcyBpcyBydW4gYXQgdGhlIHNhbWUgdGltZSBhcyBnZXR0aW5nIHRoZSBkYXRhXG4gKiAgICAgICAgIGNhbGxiYWNrKG51bGwsICdmb2xkZXInKTtcbiAqICAgICB9LFxuICogICAgIHdyaXRlX2ZpbGU6IFsnZ2V0X2RhdGEnLCAnbWFrZV9mb2xkZXInLCBmdW5jdGlvbihyZXN1bHRzLCBjYWxsYmFjaykge1xuICogICAgICAgICAvLyBvbmNlIHRoZXJlIGlzIHNvbWUgZGF0YSBhbmQgdGhlIGRpcmVjdG9yeSBleGlzdHMsXG4gKiAgICAgICAgIC8vIHdyaXRlIHRoZSBkYXRhIHRvIGEgZmlsZSBpbiB0aGUgZGlyZWN0b3J5XG4gKiAgICAgICAgIGNhbGxiYWNrKG51bGwsICdmaWxlbmFtZScpO1xuICogICAgIH1dLFxuICogICAgIGVtYWlsX2xpbms6IFsnd3JpdGVfZmlsZScsIGZ1bmN0aW9uKHJlc3VsdHMsIGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIC8vIG9uY2UgdGhlIGZpbGUgaXMgd3JpdHRlbiBsZXQncyBlbWFpbCBhIGxpbmsgdG8gaXQuLi5cbiAqICAgICAgICAgY2FsbGJhY2sobnVsbCwgeydmaWxlJzpyZXN1bHRzLndyaXRlX2ZpbGUsICdlbWFpbCc6J3VzZXJAZXhhbXBsZS5jb20nfSk7XG4gKiAgICAgfV1cbiAqIH0sIGZ1bmN0aW9uKGVyciwgcmVzdWx0cykge1xuICogICAgIGlmIChlcnIpIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coJ2VyciA9ICcsIGVycik7XG4gKiAgICAgfVxuICogICAgIGNvbnNvbGUubG9nKCdyZXN1bHRzID0gJywgcmVzdWx0cyk7XG4gKiAgICAgLy8gcmVzdWx0cyA9IHtcbiAqICAgICAvLyAgICAgZ2V0X2RhdGE6IFsnZGF0YScsICdjb252ZXJ0ZWQgdG8gYXJyYXknXVxuICogICAgIC8vICAgICBtYWtlX2ZvbGRlcjsgJ2ZvbGRlcicsXG4gKiAgICAgLy8gICAgIHdyaXRlX2ZpbGU6ICdmaWxlbmFtZSdcbiAqICAgICAvLyAgICAgZW1haWxfbGluazogeyBmaWxlOiAnZmlsZW5hbWUnLCBlbWFpbDogJ3VzZXJAZXhhbXBsZS5jb20nIH1cbiAqICAgICAvLyB9XG4gKiB9KTtcbiAqXG4gKiAvL1VzaW5nIFByb21pc2VzXG4gKiBhc3luYy5hdXRvKHtcbiAqICAgICBnZXRfZGF0YTogZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coJ2luIGdldF9kYXRhJyk7XG4gKiAgICAgICAgIC8vIGFzeW5jIGNvZGUgdG8gZ2V0IHNvbWUgZGF0YVxuICogICAgICAgICBjYWxsYmFjayhudWxsLCAnZGF0YScsICdjb252ZXJ0ZWQgdG8gYXJyYXknKTtcbiAqICAgICB9LFxuICogICAgIG1ha2VfZm9sZGVyOiBmdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgICAgICBjb25zb2xlLmxvZygnaW4gbWFrZV9mb2xkZXInKTtcbiAqICAgICAgICAgLy8gYXN5bmMgY29kZSB0byBjcmVhdGUgYSBkaXJlY3RvcnkgdG8gc3RvcmUgYSBmaWxlIGluXG4gKiAgICAgICAgIC8vIHRoaXMgaXMgcnVuIGF0IHRoZSBzYW1lIHRpbWUgYXMgZ2V0dGluZyB0aGUgZGF0YVxuICogICAgICAgICBjYWxsYmFjayhudWxsLCAnZm9sZGVyJyk7XG4gKiAgICAgfSxcbiAqICAgICB3cml0ZV9maWxlOiBbJ2dldF9kYXRhJywgJ21ha2VfZm9sZGVyJywgZnVuY3Rpb24ocmVzdWx0cywgY2FsbGJhY2spIHtcbiAqICAgICAgICAgLy8gb25jZSB0aGVyZSBpcyBzb21lIGRhdGEgYW5kIHRoZSBkaXJlY3RvcnkgZXhpc3RzLFxuICogICAgICAgICAvLyB3cml0ZSB0aGUgZGF0YSB0byBhIGZpbGUgaW4gdGhlIGRpcmVjdG9yeVxuICogICAgICAgICBjYWxsYmFjayhudWxsLCAnZmlsZW5hbWUnKTtcbiAqICAgICB9XSxcbiAqICAgICBlbWFpbF9saW5rOiBbJ3dyaXRlX2ZpbGUnLCBmdW5jdGlvbihyZXN1bHRzLCBjYWxsYmFjaykge1xuICogICAgICAgICAvLyBvbmNlIHRoZSBmaWxlIGlzIHdyaXR0ZW4gbGV0J3MgZW1haWwgYSBsaW5rIHRvIGl0Li4uXG4gKiAgICAgICAgIGNhbGxiYWNrKG51bGwsIHsnZmlsZSc6cmVzdWx0cy53cml0ZV9maWxlLCAnZW1haWwnOid1c2VyQGV4YW1wbGUuY29tJ30pO1xuICogICAgIH1dXG4gKiB9KS50aGVuKHJlc3VsdHMgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKCdyZXN1bHRzID0gJywgcmVzdWx0cyk7XG4gKiAgICAgLy8gcmVzdWx0cyA9IHtcbiAqICAgICAvLyAgICAgZ2V0X2RhdGE6IFsnZGF0YScsICdjb252ZXJ0ZWQgdG8gYXJyYXknXVxuICogICAgIC8vICAgICBtYWtlX2ZvbGRlcjsgJ2ZvbGRlcicsXG4gKiAgICAgLy8gICAgIHdyaXRlX2ZpbGU6ICdmaWxlbmFtZSdcbiAqICAgICAvLyAgICAgZW1haWxfbGluazogeyBmaWxlOiAnZmlsZW5hbWUnLCBlbWFpbDogJ3VzZXJAZXhhbXBsZS5jb20nIH1cbiAqICAgICAvLyB9XG4gKiB9KS5jYXRjaChlcnIgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKCdlcnIgPSAnLCBlcnIpO1xuICogfSk7XG4gKlxuICogLy9Vc2luZyBhc3luYy9hd2FpdFxuICogYXN5bmMgKCkgPT4ge1xuICogICAgIHRyeSB7XG4gKiAgICAgICAgIGxldCByZXN1bHRzID0gYXdhaXQgYXN5bmMuYXV0byh7XG4gKiAgICAgICAgICAgICBnZXRfZGF0YTogZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAqICAgICAgICAgICAgICAgICAvLyBhc3luYyBjb2RlIHRvIGdldCBzb21lIGRhdGFcbiAqICAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCAnZGF0YScsICdjb252ZXJ0ZWQgdG8gYXJyYXknKTtcbiAqICAgICAgICAgICAgIH0sXG4gKiAgICAgICAgICAgICBtYWtlX2ZvbGRlcjogZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAqICAgICAgICAgICAgICAgICAvLyBhc3luYyBjb2RlIHRvIGNyZWF0ZSBhIGRpcmVjdG9yeSB0byBzdG9yZSBhIGZpbGUgaW5cbiAqICAgICAgICAgICAgICAgICAvLyB0aGlzIGlzIHJ1biBhdCB0aGUgc2FtZSB0aW1lIGFzIGdldHRpbmcgdGhlIGRhdGFcbiAqICAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCAnZm9sZGVyJyk7XG4gKiAgICAgICAgICAgICB9LFxuICogICAgICAgICAgICAgd3JpdGVfZmlsZTogWydnZXRfZGF0YScsICdtYWtlX2ZvbGRlcicsIGZ1bmN0aW9uKHJlc3VsdHMsIGNhbGxiYWNrKSB7XG4gKiAgICAgICAgICAgICAgICAgLy8gb25jZSB0aGVyZSBpcyBzb21lIGRhdGEgYW5kIHRoZSBkaXJlY3RvcnkgZXhpc3RzLFxuICogICAgICAgICAgICAgICAgIC8vIHdyaXRlIHRoZSBkYXRhIHRvIGEgZmlsZSBpbiB0aGUgZGlyZWN0b3J5XG4gKiAgICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgJ2ZpbGVuYW1lJyk7XG4gKiAgICAgICAgICAgICB9XSxcbiAqICAgICAgICAgICAgIGVtYWlsX2xpbms6IFsnd3JpdGVfZmlsZScsIGZ1bmN0aW9uKHJlc3VsdHMsIGNhbGxiYWNrKSB7XG4gKiAgICAgICAgICAgICAgICAgLy8gb25jZSB0aGUgZmlsZSBpcyB3cml0dGVuIGxldCdzIGVtYWlsIGEgbGluayB0byBpdC4uLlxuICogICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHsnZmlsZSc6cmVzdWx0cy53cml0ZV9maWxlLCAnZW1haWwnOid1c2VyQGV4YW1wbGUuY29tJ30pO1xuICogICAgICAgICAgICAgfV1cbiAqICAgICAgICAgfSk7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKCdyZXN1bHRzID0gJywgcmVzdWx0cyk7XG4gKiAgICAgICAgIC8vIHJlc3VsdHMgPSB7XG4gKiAgICAgICAgIC8vICAgICBnZXRfZGF0YTogWydkYXRhJywgJ2NvbnZlcnRlZCB0byBhcnJheSddXG4gKiAgICAgICAgIC8vICAgICBtYWtlX2ZvbGRlcjsgJ2ZvbGRlcicsXG4gKiAgICAgICAgIC8vICAgICB3cml0ZV9maWxlOiAnZmlsZW5hbWUnXG4gKiAgICAgICAgIC8vICAgICBlbWFpbF9saW5rOiB7IGZpbGU6ICdmaWxlbmFtZScsIGVtYWlsOiAndXNlckBleGFtcGxlLmNvbScgfVxuICogICAgICAgICAvLyB9XG4gKiAgICAgfVxuICogICAgIGNhdGNoIChlcnIpIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICB9XG4gKiB9XG4gKlxuICovXG5mdW5jdGlvbiBhdXRvKHRhc2tzLCBjb25jdXJyZW5jeSwgY2FsbGJhY2spIHtcbiAgICBpZiAodHlwZW9mIGNvbmN1cnJlbmN5ICE9PSAnbnVtYmVyJykge1xuICAgICAgICAvLyBjb25jdXJyZW5jeSBpcyBvcHRpb25hbCwgc2hpZnQgdGhlIGFyZ3MuXG4gICAgICAgIGNhbGxiYWNrID0gY29uY3VycmVuY3k7XG4gICAgICAgIGNvbmN1cnJlbmN5ID0gbnVsbDtcbiAgICB9XG4gICAgY2FsbGJhY2sgPSBvbmNlKGNhbGxiYWNrIHx8IHByb21pc2VDYWxsYmFjaygpKTtcbiAgICB2YXIgbnVtVGFza3MgPSBPYmplY3Qua2V5cyh0YXNrcykubGVuZ3RoO1xuICAgIGlmICghbnVtVGFza3MpIHtcbiAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwpO1xuICAgIH1cbiAgICBpZiAoIWNvbmN1cnJlbmN5KSB7XG4gICAgICAgIGNvbmN1cnJlbmN5ID0gbnVtVGFza3M7XG4gICAgfVxuXG4gICAgdmFyIHJlc3VsdHMgPSB7fTtcbiAgICB2YXIgcnVubmluZ1Rhc2tzID0gMDtcbiAgICB2YXIgY2FuY2VsZWQgPSBmYWxzZTtcbiAgICB2YXIgaGFzRXJyb3IgPSBmYWxzZTtcblxuICAgIHZhciBsaXN0ZW5lcnMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuXG4gICAgdmFyIHJlYWR5VGFza3MgPSBbXTtcblxuICAgIC8vIGZvciBjeWNsZSBkZXRlY3Rpb246XG4gICAgdmFyIHJlYWR5VG9DaGVjayA9IFtdOyAvLyB0YXNrcyB0aGF0IGhhdmUgYmVlbiBpZGVudGlmaWVkIGFzIHJlYWNoYWJsZVxuICAgIC8vIHdpdGhvdXQgdGhlIHBvc3NpYmlsaXR5IG9mIHJldHVybmluZyB0byBhbiBhbmNlc3RvciB0YXNrXG4gICAgdmFyIHVuY2hlY2tlZERlcGVuZGVuY2llcyA9IHt9O1xuXG4gICAgT2JqZWN0LmtleXModGFza3MpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgdmFyIHRhc2sgPSB0YXNrc1trZXldO1xuICAgICAgICBpZiAoIUFycmF5LmlzQXJyYXkodGFzaykpIHtcbiAgICAgICAgICAgIC8vIG5vIGRlcGVuZGVuY2llc1xuICAgICAgICAgICAgZW5xdWV1ZVRhc2soa2V5LCBbdGFza10pO1xuICAgICAgICAgICAgcmVhZHlUb0NoZWNrLnB1c2goa2V5KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBkZXBlbmRlbmNpZXMgPSB0YXNrLnNsaWNlKDAsIHRhc2subGVuZ3RoIC0gMSk7XG4gICAgICAgIHZhciByZW1haW5pbmdEZXBlbmRlbmNpZXMgPSBkZXBlbmRlbmNpZXMubGVuZ3RoO1xuICAgICAgICBpZiAocmVtYWluaW5nRGVwZW5kZW5jaWVzID09PSAwKSB7XG4gICAgICAgICAgICBlbnF1ZXVlVGFzayhrZXksIHRhc2spO1xuICAgICAgICAgICAgcmVhZHlUb0NoZWNrLnB1c2goa2V5KTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICB1bmNoZWNrZWREZXBlbmRlbmNpZXNba2V5XSA9IHJlbWFpbmluZ0RlcGVuZGVuY2llcztcblxuICAgICAgICBkZXBlbmRlbmNpZXMuZm9yRWFjaChkZXBlbmRlbmN5TmFtZSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRhc2tzW2RlcGVuZGVuY3lOYW1lXSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignYXN5bmMuYXV0byB0YXNrIGAnICsga2V5ICtcbiAgICAgICAgICAgICAgICAgICAgJ2AgaGFzIGEgbm9uLWV4aXN0ZW50IGRlcGVuZGVuY3kgYCcgK1xuICAgICAgICAgICAgICAgICAgICBkZXBlbmRlbmN5TmFtZSArICdgIGluICcgK1xuICAgICAgICAgICAgICAgICAgICBkZXBlbmRlbmNpZXMuam9pbignLCAnKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBhZGRMaXN0ZW5lcihkZXBlbmRlbmN5TmFtZSwgKCkgPT4ge1xuICAgICAgICAgICAgICAgIHJlbWFpbmluZ0RlcGVuZGVuY2llcy0tO1xuICAgICAgICAgICAgICAgIGlmIChyZW1haW5pbmdEZXBlbmRlbmNpZXMgPT09IDApIHtcbiAgICAgICAgICAgICAgICAgICAgZW5xdWV1ZVRhc2soa2V5LCB0YXNrKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICBjaGVja0ZvckRlYWRsb2NrcygpO1xuICAgIHByb2Nlc3NRdWV1ZSgpO1xuXG4gICAgZnVuY3Rpb24gZW5xdWV1ZVRhc2soa2V5LCB0YXNrKSB7XG4gICAgICAgIHJlYWR5VGFza3MucHVzaCgoKSA9PiBydW5UYXNrKGtleSwgdGFzaykpO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHByb2Nlc3NRdWV1ZSgpIHtcbiAgICAgICAgaWYgKGNhbmNlbGVkKSByZXR1cm5cbiAgICAgICAgaWYgKHJlYWR5VGFza3MubGVuZ3RoID09PSAwICYmIHJ1bm5pbmdUYXNrcyA9PT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIHJlc3VsdHMpO1xuICAgICAgICB9XG4gICAgICAgIHdoaWxlKHJlYWR5VGFza3MubGVuZ3RoICYmIHJ1bm5pbmdUYXNrcyA8IGNvbmN1cnJlbmN5KSB7XG4gICAgICAgICAgICB2YXIgcnVuID0gcmVhZHlUYXNrcy5zaGlmdCgpO1xuICAgICAgICAgICAgcnVuKCk7XG4gICAgICAgIH1cblxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGFkZExpc3RlbmVyKHRhc2tOYW1lLCBmbikge1xuICAgICAgICB2YXIgdGFza0xpc3RlbmVycyA9IGxpc3RlbmVyc1t0YXNrTmFtZV07XG4gICAgICAgIGlmICghdGFza0xpc3RlbmVycykge1xuICAgICAgICAgICAgdGFza0xpc3RlbmVycyA9IGxpc3RlbmVyc1t0YXNrTmFtZV0gPSBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRhc2tMaXN0ZW5lcnMucHVzaChmbik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdGFza0NvbXBsZXRlKHRhc2tOYW1lKSB7XG4gICAgICAgIHZhciB0YXNrTGlzdGVuZXJzID0gbGlzdGVuZXJzW3Rhc2tOYW1lXSB8fCBbXTtcbiAgICAgICAgdGFza0xpc3RlbmVycy5mb3JFYWNoKGZuID0+IGZuKCkpO1xuICAgICAgICBwcm9jZXNzUXVldWUoKTtcbiAgICB9XG5cblxuICAgIGZ1bmN0aW9uIHJ1blRhc2soa2V5LCB0YXNrKSB7XG4gICAgICAgIGlmIChoYXNFcnJvcikgcmV0dXJuO1xuXG4gICAgICAgIHZhciB0YXNrQ2FsbGJhY2sgPSBvbmx5T25jZSgoZXJyLCAuLi5yZXN1bHQpID0+IHtcbiAgICAgICAgICAgIHJ1bm5pbmdUYXNrcy0tO1xuICAgICAgICAgICAgaWYgKGVyciA9PT0gZmFsc2UpIHtcbiAgICAgICAgICAgICAgICBjYW5jZWxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgcmV0dXJuXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAocmVzdWx0Lmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgICAgICBbcmVzdWx0XSA9IHJlc3VsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2FmZVJlc3VsdHMgPSB7fTtcbiAgICAgICAgICAgICAgICBPYmplY3Qua2V5cyhyZXN1bHRzKS5mb3JFYWNoKHJrZXkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBzYWZlUmVzdWx0c1tya2V5XSA9IHJlc3VsdHNbcmtleV07XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgc2FmZVJlc3VsdHNba2V5XSA9IHJlc3VsdDtcbiAgICAgICAgICAgICAgICBoYXNFcnJvciA9IHRydWU7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXJzID0gT2JqZWN0LmNyZWF0ZShudWxsKTtcbiAgICAgICAgICAgICAgICBpZiAoY2FuY2VsZWQpIHJldHVyblxuICAgICAgICAgICAgICAgIGNhbGxiYWNrKGVyciwgc2FmZVJlc3VsdHMpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHRzW2tleV0gPSByZXN1bHQ7XG4gICAgICAgICAgICAgICAgdGFza0NvbXBsZXRlKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJ1bm5pbmdUYXNrcysrO1xuICAgICAgICB2YXIgdGFza0ZuID0gd3JhcEFzeW5jKHRhc2tbdGFzay5sZW5ndGggLSAxXSk7XG4gICAgICAgIGlmICh0YXNrLmxlbmd0aCA+IDEpIHtcbiAgICAgICAgICAgIHRhc2tGbihyZXN1bHRzLCB0YXNrQ2FsbGJhY2spO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGFza0ZuKHRhc2tDYWxsYmFjayk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjaGVja0ZvckRlYWRsb2NrcygpIHtcbiAgICAgICAgLy8gS2FobidzIGFsZ29yaXRobVxuICAgICAgICAvLyBodHRwczovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9Ub3BvbG9naWNhbF9zb3J0aW5nI0thaG4uMjdzX2FsZ29yaXRobVxuICAgICAgICAvLyBodHRwOi8vY29ubmFsbGUuYmxvZ3Nwb3QuY29tLzIwMTMvMTAvdG9wb2xvZ2ljYWwtc29ydGluZ2thaG4tYWxnb3JpdGhtLmh0bWxcbiAgICAgICAgdmFyIGN1cnJlbnRUYXNrO1xuICAgICAgICB2YXIgY291bnRlciA9IDA7XG4gICAgICAgIHdoaWxlIChyZWFkeVRvQ2hlY2subGVuZ3RoKSB7XG4gICAgICAgICAgICBjdXJyZW50VGFzayA9IHJlYWR5VG9DaGVjay5wb3AoKTtcbiAgICAgICAgICAgIGNvdW50ZXIrKztcbiAgICAgICAgICAgIGdldERlcGVuZGVudHMoY3VycmVudFRhc2spLmZvckVhY2goZGVwZW5kZW50ID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoLS11bmNoZWNrZWREZXBlbmRlbmNpZXNbZGVwZW5kZW50XSA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICByZWFkeVRvQ2hlY2sucHVzaChkZXBlbmRlbnQpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGNvdW50ZXIgIT09IG51bVRhc2tzKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICAgJ2FzeW5jLmF1dG8gY2Fubm90IGV4ZWN1dGUgdGFza3MgZHVlIHRvIGEgcmVjdXJzaXZlIGRlcGVuZGVuY3knXG4gICAgICAgICAgICApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0RGVwZW5kZW50cyh0YXNrTmFtZSkge1xuICAgICAgICB2YXIgcmVzdWx0ID0gW107XG4gICAgICAgIE9iamVjdC5rZXlzKHRhc2tzKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgICAgICBjb25zdCB0YXNrID0gdGFza3Nba2V5XTtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KHRhc2spICYmIHRhc2suaW5kZXhPZih0YXNrTmFtZSkgPj0gMCkge1xuICAgICAgICAgICAgICAgIHJlc3VsdC5wdXNoKGtleSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHJldHVybiBjYWxsYmFja1tQUk9NSVNFX1NZTUJPTF1cbn1cblxudmFyIEZOX0FSR1MgPSAvXig/OmFzeW5jXFxzKT8oPzpmdW5jdGlvbik/XFxzKig/OlxcdytcXHMqKT9cXCgoW14pXSspXFwpKD86XFxzKnspLztcbnZhciBBUlJPV19GTl9BUkdTID0gL14oPzphc3luY1xccyk/XFxzKig/OlxcKFxccyopPygoPzpbXik9XFxzXVxccyopKikoPzpcXClcXHMqKT89Pi87XG52YXIgRk5fQVJHX1NQTElUID0gLywvO1xudmFyIEZOX0FSRyA9IC8oPS4rKT8oXFxzKikkLztcblxuZnVuY3Rpb24gc3RyaXBDb21tZW50cyhzdHJpbmcpIHtcbiAgICBsZXQgc3RyaXBwZWQgPSAnJztcbiAgICBsZXQgaW5kZXggPSAwO1xuICAgIGxldCBlbmRCbG9ja0NvbW1lbnQgPSBzdHJpbmcuaW5kZXhPZignKi8nKTtcbiAgICB3aGlsZSAoaW5kZXggPCBzdHJpbmcubGVuZ3RoKSB7XG4gICAgICAgIGlmIChzdHJpbmdbaW5kZXhdID09PSAnLycgJiYgc3RyaW5nW2luZGV4KzFdID09PSAnLycpIHtcbiAgICAgICAgICAgIC8vIGlubGluZSBjb21tZW50XG4gICAgICAgICAgICBsZXQgZW5kSW5kZXggPSBzdHJpbmcuaW5kZXhPZignXFxuJywgaW5kZXgpO1xuICAgICAgICAgICAgaW5kZXggPSAoZW5kSW5kZXggPT09IC0xKSA/IHN0cmluZy5sZW5ndGggOiBlbmRJbmRleDtcbiAgICAgICAgfSBlbHNlIGlmICgoZW5kQmxvY2tDb21tZW50ICE9PSAtMSkgJiYgKHN0cmluZ1tpbmRleF0gPT09ICcvJykgJiYgKHN0cmluZ1tpbmRleCsxXSA9PT0gJyonKSkge1xuICAgICAgICAgICAgLy8gYmxvY2sgY29tbWVudFxuICAgICAgICAgICAgbGV0IGVuZEluZGV4ID0gc3RyaW5nLmluZGV4T2YoJyovJywgaW5kZXgpO1xuICAgICAgICAgICAgaWYgKGVuZEluZGV4ICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIGluZGV4ID0gZW5kSW5kZXggKyAyO1xuICAgICAgICAgICAgICAgIGVuZEJsb2NrQ29tbWVudCA9IHN0cmluZy5pbmRleE9mKCcqLycsIGluZGV4KTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc3RyaXBwZWQgKz0gc3RyaW5nW2luZGV4XTtcbiAgICAgICAgICAgICAgICBpbmRleCsrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3RyaXBwZWQgKz0gc3RyaW5nW2luZGV4XTtcbiAgICAgICAgICAgIGluZGV4Kys7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHN0cmlwcGVkO1xufVxuXG5mdW5jdGlvbiBwYXJzZVBhcmFtcyhmdW5jKSB7XG4gICAgY29uc3Qgc3JjID0gc3RyaXBDb21tZW50cyhmdW5jLnRvU3RyaW5nKCkpO1xuICAgIGxldCBtYXRjaCA9IHNyYy5tYXRjaChGTl9BUkdTKTtcbiAgICBpZiAoIW1hdGNoKSB7XG4gICAgICAgIG1hdGNoID0gc3JjLm1hdGNoKEFSUk9XX0ZOX0FSR1MpO1xuICAgIH1cbiAgICBpZiAoIW1hdGNoKSB0aHJvdyBuZXcgRXJyb3IoJ2NvdWxkIG5vdCBwYXJzZSBhcmdzIGluIGF1dG9JbmplY3RcXG5Tb3VyY2U6XFxuJyArIHNyYylcbiAgICBsZXQgWywgYXJnc10gPSBtYXRjaDtcbiAgICByZXR1cm4gYXJnc1xuICAgICAgICAucmVwbGFjZSgvXFxzL2csICcnKVxuICAgICAgICAuc3BsaXQoRk5fQVJHX1NQTElUKVxuICAgICAgICAubWFwKChhcmcpID0+IGFyZy5yZXBsYWNlKEZOX0FSRywgJycpLnRyaW0oKSk7XG59XG5cbi8qKlxuICogQSBkZXBlbmRlbmN5LWluamVjdGVkIHZlcnNpb24gb2YgdGhlIFthc3luYy5hdXRvXXtAbGluayBtb2R1bGU6Q29udHJvbEZsb3cuYXV0b30gZnVuY3Rpb24uIERlcGVuZGVudFxuICogdGFza3MgYXJlIHNwZWNpZmllZCBhcyBwYXJhbWV0ZXJzIHRvIHRoZSBmdW5jdGlvbiwgYWZ0ZXIgdGhlIHVzdWFsIGNhbGxiYWNrXG4gKiBwYXJhbWV0ZXIsIHdpdGggdGhlIHBhcmFtZXRlciBuYW1lcyBtYXRjaGluZyB0aGUgbmFtZXMgb2YgdGhlIHRhc2tzIGl0XG4gKiBkZXBlbmRzIG9uLiBUaGlzIGNhbiBwcm92aWRlIGV2ZW4gbW9yZSByZWFkYWJsZSB0YXNrIGdyYXBocyB3aGljaCBjYW4gYmVcbiAqIGVhc2llciB0byBtYWludGFpbi5cbiAqXG4gKiBJZiBhIGZpbmFsIGNhbGxiYWNrIGlzIHNwZWNpZmllZCwgdGhlIHRhc2sgcmVzdWx0cyBhcmUgc2ltaWxhcmx5IGluamVjdGVkLFxuICogc3BlY2lmaWVkIGFzIG5hbWVkIHBhcmFtZXRlcnMgYWZ0ZXIgdGhlIGluaXRpYWwgZXJyb3IgcGFyYW1ldGVyLlxuICpcbiAqIFRoZSBhdXRvSW5qZWN0IGZ1bmN0aW9uIGlzIHB1cmVseSBzeW50YWN0aWMgc3VnYXIgYW5kIGl0cyBzZW1hbnRpY3MgYXJlXG4gKiBvdGhlcndpc2UgZXF1aXZhbGVudCB0byBbYXN5bmMuYXV0b117QGxpbmsgbW9kdWxlOkNvbnRyb2xGbG93LmF1dG99LlxuICpcbiAqIEBuYW1lIGF1dG9JbmplY3RcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29udHJvbEZsb3dcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLmF1dG9de0BsaW5rIG1vZHVsZTpDb250cm9sRmxvdy5hdXRvfVxuICogQGNhdGVnb3J5IENvbnRyb2wgRmxvd1xuICogQHBhcmFtIHtPYmplY3R9IHRhc2tzIC0gQW4gb2JqZWN0LCBlYWNoIG9mIHdob3NlIHByb3BlcnRpZXMgaXMgYW4ge0BsaW5rIEFzeW5jRnVuY3Rpb259IG9mXG4gKiB0aGUgZm9ybSAnZnVuYyhbZGVwZW5kZW5jaWVzLi4uXSwgY2FsbGJhY2spLiBUaGUgb2JqZWN0J3Mga2V5IG9mIGEgcHJvcGVydHlcbiAqIHNlcnZlcyBhcyB0aGUgbmFtZSBvZiB0aGUgdGFzayBkZWZpbmVkIGJ5IHRoYXQgcHJvcGVydHksIGkuZS4gY2FuIGJlIHVzZWRcbiAqIHdoZW4gc3BlY2lmeWluZyByZXF1aXJlbWVudHMgZm9yIG90aGVyIHRhc2tzLlxuICogKiBUaGUgYGNhbGxiYWNrYCBwYXJhbWV0ZXIgaXMgYSBgY2FsbGJhY2soZXJyLCByZXN1bHQpYCB3aGljaCBtdXN0IGJlIGNhbGxlZFxuICogICB3aGVuIGZpbmlzaGVkLCBwYXNzaW5nIGFuIGBlcnJvcmAgKHdoaWNoIGNhbiBiZSBgbnVsbGApIGFuZCB0aGUgcmVzdWx0IG9mXG4gKiAgIHRoZSBmdW5jdGlvbidzIGV4ZWN1dGlvbi4gVGhlIHJlbWFpbmluZyBwYXJhbWV0ZXJzIG5hbWUgb3RoZXIgdGFza3Mgb25cbiAqICAgd2hpY2ggdGhlIHRhc2sgaXMgZGVwZW5kZW50LCBhbmQgdGhlIHJlc3VsdHMgZnJvbSB0aG9zZSB0YXNrcyBhcmUgdGhlXG4gKiAgIGFyZ3VtZW50cyBvZiB0aG9zZSBwYXJhbWV0ZXJzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEFuIG9wdGlvbmFsIGNhbGxiYWNrIHdoaWNoIGlzIGNhbGxlZCB3aGVuIGFsbFxuICogdGhlIHRhc2tzIGhhdmUgYmVlbiBjb21wbGV0ZWQuIEl0IHJlY2VpdmVzIHRoZSBgZXJyYCBhcmd1bWVudCBpZiBhbnkgYHRhc2tzYFxuICogcGFzcyBhbiBlcnJvciB0byB0aGVpciBjYWxsYmFjaywgYW5kIGEgYHJlc3VsdHNgIG9iamVjdCB3aXRoIGFueSBjb21wbGV0ZWRcbiAqIHRhc2sgcmVzdWx0cywgc2ltaWxhciB0byBgYXV0b2AuXG4gKiBAcmV0dXJucyB7UHJvbWlzZX0gYSBwcm9taXNlLCBpZiBubyBjYWxsYmFjayBpcyBwYXNzZWRcbiAqIEBleGFtcGxlXG4gKlxuICogLy8gIFRoZSBleGFtcGxlIGZyb20gYGF1dG9gIGNhbiBiZSByZXdyaXR0ZW4gYXMgZm9sbG93czpcbiAqIGFzeW5jLmF1dG9JbmplY3Qoe1xuICogICAgIGdldF9kYXRhOiBmdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgICAgICAvLyBhc3luYyBjb2RlIHRvIGdldCBzb21lIGRhdGFcbiAqICAgICAgICAgY2FsbGJhY2sobnVsbCwgJ2RhdGEnLCAnY29udmVydGVkIHRvIGFycmF5Jyk7XG4gKiAgICAgfSxcbiAqICAgICBtYWtlX2ZvbGRlcjogZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAqICAgICAgICAgLy8gYXN5bmMgY29kZSB0byBjcmVhdGUgYSBkaXJlY3RvcnkgdG8gc3RvcmUgYSBmaWxlIGluXG4gKiAgICAgICAgIC8vIHRoaXMgaXMgcnVuIGF0IHRoZSBzYW1lIHRpbWUgYXMgZ2V0dGluZyB0aGUgZGF0YVxuICogICAgICAgICBjYWxsYmFjayhudWxsLCAnZm9sZGVyJyk7XG4gKiAgICAgfSxcbiAqICAgICB3cml0ZV9maWxlOiBmdW5jdGlvbihnZXRfZGF0YSwgbWFrZV9mb2xkZXIsIGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIC8vIG9uY2UgdGhlcmUgaXMgc29tZSBkYXRhIGFuZCB0aGUgZGlyZWN0b3J5IGV4aXN0cyxcbiAqICAgICAgICAgLy8gd3JpdGUgdGhlIGRhdGEgdG8gYSBmaWxlIGluIHRoZSBkaXJlY3RvcnlcbiAqICAgICAgICAgY2FsbGJhY2sobnVsbCwgJ2ZpbGVuYW1lJyk7XG4gKiAgICAgfSxcbiAqICAgICBlbWFpbF9saW5rOiBmdW5jdGlvbih3cml0ZV9maWxlLCBjYWxsYmFjaykge1xuICogICAgICAgICAvLyBvbmNlIHRoZSBmaWxlIGlzIHdyaXR0ZW4gbGV0J3MgZW1haWwgYSBsaW5rIHRvIGl0Li4uXG4gKiAgICAgICAgIC8vIHdyaXRlX2ZpbGUgY29udGFpbnMgdGhlIGZpbGVuYW1lIHJldHVybmVkIGJ5IHdyaXRlX2ZpbGUuXG4gKiAgICAgICAgIGNhbGxiYWNrKG51bGwsIHsnZmlsZSc6d3JpdGVfZmlsZSwgJ2VtYWlsJzondXNlckBleGFtcGxlLmNvbSd9KTtcbiAqICAgICB9XG4gKiB9LCBmdW5jdGlvbihlcnIsIHJlc3VsdHMpIHtcbiAqICAgICBjb25zb2xlLmxvZygnZXJyID0gJywgZXJyKTtcbiAqICAgICBjb25zb2xlLmxvZygnZW1haWxfbGluayA9ICcsIHJlc3VsdHMuZW1haWxfbGluayk7XG4gKiB9KTtcbiAqXG4gKiAvLyBJZiB5b3UgYXJlIHVzaW5nIGEgSlMgbWluaWZpZXIgdGhhdCBtYW5nbGVzIHBhcmFtZXRlciBuYW1lcywgYGF1dG9JbmplY3RgXG4gKiAvLyB3aWxsIG5vdCB3b3JrIHdpdGggcGxhaW4gZnVuY3Rpb25zLCBzaW5jZSB0aGUgcGFyYW1ldGVyIG5hbWVzIHdpbGwgYmVcbiAqIC8vIGNvbGxhcHNlZCB0byBhIHNpbmdsZSBsZXR0ZXIgaWRlbnRpZmllci4gIFRvIHdvcmsgYXJvdW5kIHRoaXMsIHlvdSBjYW5cbiAqIC8vIGV4cGxpY2l0bHkgc3BlY2lmeSB0aGUgbmFtZXMgb2YgdGhlIHBhcmFtZXRlcnMgeW91ciB0YXNrIGZ1bmN0aW9uIG5lZWRzXG4gKiAvLyBpbiBhbiBhcnJheSwgc2ltaWxhciB0byBBbmd1bGFyLmpzIGRlcGVuZGVuY3kgaW5qZWN0aW9uLlxuICpcbiAqIC8vIFRoaXMgc3RpbGwgaGFzIGFuIGFkdmFudGFnZSBvdmVyIHBsYWluIGBhdXRvYCwgc2luY2UgdGhlIHJlc3VsdHMgYSB0YXNrXG4gKiAvLyBkZXBlbmRzIG9uIGFyZSBzdGlsbCBzcHJlYWQgaW50byBhcmd1bWVudHMuXG4gKiBhc3luYy5hdXRvSW5qZWN0KHtcbiAqICAgICAvLy4uLlxuICogICAgIHdyaXRlX2ZpbGU6IFsnZ2V0X2RhdGEnLCAnbWFrZV9mb2xkZXInLCBmdW5jdGlvbihnZXRfZGF0YSwgbWFrZV9mb2xkZXIsIGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIGNhbGxiYWNrKG51bGwsICdmaWxlbmFtZScpO1xuICogICAgIH1dLFxuICogICAgIGVtYWlsX2xpbms6IFsnd3JpdGVfZmlsZScsIGZ1bmN0aW9uKHdyaXRlX2ZpbGUsIGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIGNhbGxiYWNrKG51bGwsIHsnZmlsZSc6d3JpdGVfZmlsZSwgJ2VtYWlsJzondXNlckBleGFtcGxlLmNvbSd9KTtcbiAqICAgICB9XVxuICogICAgIC8vLi4uXG4gKiB9LCBmdW5jdGlvbihlcnIsIHJlc3VsdHMpIHtcbiAqICAgICBjb25zb2xlLmxvZygnZXJyID0gJywgZXJyKTtcbiAqICAgICBjb25zb2xlLmxvZygnZW1haWxfbGluayA9ICcsIHJlc3VsdHMuZW1haWxfbGluayk7XG4gKiB9KTtcbiAqL1xuZnVuY3Rpb24gYXV0b0luamVjdCh0YXNrcywgY2FsbGJhY2spIHtcbiAgICB2YXIgbmV3VGFza3MgPSB7fTtcblxuICAgIE9iamVjdC5rZXlzKHRhc2tzKS5mb3JFYWNoKGtleSA9PiB7XG4gICAgICAgIHZhciB0YXNrRm4gPSB0YXNrc1trZXldO1xuICAgICAgICB2YXIgcGFyYW1zO1xuICAgICAgICB2YXIgZm5Jc0FzeW5jID0gaXNBc3luYyh0YXNrRm4pO1xuICAgICAgICB2YXIgaGFzTm9EZXBzID1cbiAgICAgICAgICAgICghZm5Jc0FzeW5jICYmIHRhc2tGbi5sZW5ndGggPT09IDEpIHx8XG4gICAgICAgICAgICAoZm5Jc0FzeW5jICYmIHRhc2tGbi5sZW5ndGggPT09IDApO1xuXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KHRhc2tGbikpIHtcbiAgICAgICAgICAgIHBhcmFtcyA9IFsuLi50YXNrRm5dO1xuICAgICAgICAgICAgdGFza0ZuID0gcGFyYW1zLnBvcCgpO1xuXG4gICAgICAgICAgICBuZXdUYXNrc1trZXldID0gcGFyYW1zLmNvbmNhdChwYXJhbXMubGVuZ3RoID4gMCA/IG5ld1Rhc2sgOiB0YXNrRm4pO1xuICAgICAgICB9IGVsc2UgaWYgKGhhc05vRGVwcykge1xuICAgICAgICAgICAgLy8gbm8gZGVwZW5kZW5jaWVzLCB1c2UgdGhlIGZ1bmN0aW9uIGFzLWlzXG4gICAgICAgICAgICBuZXdUYXNrc1trZXldID0gdGFza0ZuO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcGFyYW1zID0gcGFyc2VQYXJhbXModGFza0ZuKTtcbiAgICAgICAgICAgIGlmICgodGFza0ZuLmxlbmd0aCA9PT0gMCAmJiAhZm5Jc0FzeW5jKSAmJiBwYXJhbXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiYXV0b0luamVjdCB0YXNrIGZ1bmN0aW9ucyByZXF1aXJlIGV4cGxpY2l0IHBhcmFtZXRlcnMuXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyByZW1vdmUgY2FsbGJhY2sgcGFyYW1cbiAgICAgICAgICAgIGlmICghZm5Jc0FzeW5jKSBwYXJhbXMucG9wKCk7XG5cbiAgICAgICAgICAgIG5ld1Rhc2tzW2tleV0gPSBwYXJhbXMuY29uY2F0KG5ld1Rhc2spO1xuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gbmV3VGFzayhyZXN1bHRzLCB0YXNrQ2IpIHtcbiAgICAgICAgICAgIHZhciBuZXdBcmdzID0gcGFyYW1zLm1hcChuYW1lID0+IHJlc3VsdHNbbmFtZV0pO1xuICAgICAgICAgICAgbmV3QXJncy5wdXNoKHRhc2tDYik7XG4gICAgICAgICAgICB3cmFwQXN5bmModGFza0ZuKSguLi5uZXdBcmdzKTtcbiAgICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGF1dG8obmV3VGFza3MsIGNhbGxiYWNrKTtcbn1cblxuLy8gU2ltcGxlIGRvdWJseSBsaW5rZWQgbGlzdCAoaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvRG91Ymx5X2xpbmtlZF9saXN0KSBpbXBsZW1lbnRhdGlvblxuLy8gdXNlZCBmb3IgcXVldWVzLiBUaGlzIGltcGxlbWVudGF0aW9uIGFzc3VtZXMgdGhhdCB0aGUgbm9kZSBwcm92aWRlZCBieSB0aGUgdXNlciBjYW4gYmUgbW9kaWZpZWRcbi8vIHRvIGFkanVzdCB0aGUgbmV4dCBhbmQgbGFzdCBwcm9wZXJ0aWVzLiBXZSBpbXBsZW1lbnQgb25seSB0aGUgbWluaW1hbCBmdW5jdGlvbmFsaXR5XG4vLyBmb3IgcXVldWUgc3VwcG9ydC5cbmNsYXNzIERMTCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuaGVhZCA9IHRoaXMudGFpbCA9IG51bGw7XG4gICAgICAgIHRoaXMubGVuZ3RoID0gMDtcbiAgICB9XG5cbiAgICByZW1vdmVMaW5rKG5vZGUpIHtcbiAgICAgICAgaWYgKG5vZGUucHJldikgbm9kZS5wcmV2Lm5leHQgPSBub2RlLm5leHQ7XG4gICAgICAgIGVsc2UgdGhpcy5oZWFkID0gbm9kZS5uZXh0O1xuICAgICAgICBpZiAobm9kZS5uZXh0KSBub2RlLm5leHQucHJldiA9IG5vZGUucHJldjtcbiAgICAgICAgZWxzZSB0aGlzLnRhaWwgPSBub2RlLnByZXY7XG5cbiAgICAgICAgbm9kZS5wcmV2ID0gbm9kZS5uZXh0ID0gbnVsbDtcbiAgICAgICAgdGhpcy5sZW5ndGggLT0gMTtcbiAgICAgICAgcmV0dXJuIG5vZGU7XG4gICAgfVxuXG4gICAgZW1wdHkgKCkge1xuICAgICAgICB3aGlsZSh0aGlzLmhlYWQpIHRoaXMuc2hpZnQoKTtcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuXG4gICAgaW5zZXJ0QWZ0ZXIobm9kZSwgbmV3Tm9kZSkge1xuICAgICAgICBuZXdOb2RlLnByZXYgPSBub2RlO1xuICAgICAgICBuZXdOb2RlLm5leHQgPSBub2RlLm5leHQ7XG4gICAgICAgIGlmIChub2RlLm5leHQpIG5vZGUubmV4dC5wcmV2ID0gbmV3Tm9kZTtcbiAgICAgICAgZWxzZSB0aGlzLnRhaWwgPSBuZXdOb2RlO1xuICAgICAgICBub2RlLm5leHQgPSBuZXdOb2RlO1xuICAgICAgICB0aGlzLmxlbmd0aCArPSAxO1xuICAgIH1cblxuICAgIGluc2VydEJlZm9yZShub2RlLCBuZXdOb2RlKSB7XG4gICAgICAgIG5ld05vZGUucHJldiA9IG5vZGUucHJldjtcbiAgICAgICAgbmV3Tm9kZS5uZXh0ID0gbm9kZTtcbiAgICAgICAgaWYgKG5vZGUucHJldikgbm9kZS5wcmV2Lm5leHQgPSBuZXdOb2RlO1xuICAgICAgICBlbHNlIHRoaXMuaGVhZCA9IG5ld05vZGU7XG4gICAgICAgIG5vZGUucHJldiA9IG5ld05vZGU7XG4gICAgICAgIHRoaXMubGVuZ3RoICs9IDE7XG4gICAgfVxuXG4gICAgdW5zaGlmdChub2RlKSB7XG4gICAgICAgIGlmICh0aGlzLmhlYWQpIHRoaXMuaW5zZXJ0QmVmb3JlKHRoaXMuaGVhZCwgbm9kZSk7XG4gICAgICAgIGVsc2Ugc2V0SW5pdGlhbCh0aGlzLCBub2RlKTtcbiAgICB9XG5cbiAgICBwdXNoKG5vZGUpIHtcbiAgICAgICAgaWYgKHRoaXMudGFpbCkgdGhpcy5pbnNlcnRBZnRlcih0aGlzLnRhaWwsIG5vZGUpO1xuICAgICAgICBlbHNlIHNldEluaXRpYWwodGhpcywgbm9kZSk7XG4gICAgfVxuXG4gICAgc2hpZnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmhlYWQgJiYgdGhpcy5yZW1vdmVMaW5rKHRoaXMuaGVhZCk7XG4gICAgfVxuXG4gICAgcG9wKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50YWlsICYmIHRoaXMucmVtb3ZlTGluayh0aGlzLnRhaWwpO1xuICAgIH1cblxuICAgIHRvQXJyYXkoKSB7XG4gICAgICAgIHJldHVybiBbLi4udGhpc11cbiAgICB9XG5cbiAgICAqW1N5bWJvbC5pdGVyYXRvcl0gKCkge1xuICAgICAgICB2YXIgY3VyID0gdGhpcy5oZWFkO1xuICAgICAgICB3aGlsZSAoY3VyKSB7XG4gICAgICAgICAgICB5aWVsZCBjdXIuZGF0YTtcbiAgICAgICAgICAgIGN1ciA9IGN1ci5uZXh0O1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVtb3ZlICh0ZXN0Rm4pIHtcbiAgICAgICAgdmFyIGN1cnIgPSB0aGlzLmhlYWQ7XG4gICAgICAgIHdoaWxlKGN1cnIpIHtcbiAgICAgICAgICAgIHZhciB7bmV4dH0gPSBjdXJyO1xuICAgICAgICAgICAgaWYgKHRlc3RGbihjdXJyKSkge1xuICAgICAgICAgICAgICAgIHRoaXMucmVtb3ZlTGluayhjdXJyKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGN1cnIgPSBuZXh0O1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cbn1cblxuZnVuY3Rpb24gc2V0SW5pdGlhbChkbGwsIG5vZGUpIHtcbiAgICBkbGwubGVuZ3RoID0gMTtcbiAgICBkbGwuaGVhZCA9IGRsbC50YWlsID0gbm9kZTtcbn1cblxuZnVuY3Rpb24gcXVldWUkMSh3b3JrZXIsIGNvbmN1cnJlbmN5LCBwYXlsb2FkKSB7XG4gICAgaWYgKGNvbmN1cnJlbmN5ID09IG51bGwpIHtcbiAgICAgICAgY29uY3VycmVuY3kgPSAxO1xuICAgIH1cbiAgICBlbHNlIGlmKGNvbmN1cnJlbmN5ID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKCdDb25jdXJyZW5jeSBtdXN0IG5vdCBiZSB6ZXJvJyk7XG4gICAgfVxuXG4gICAgdmFyIF93b3JrZXIgPSB3cmFwQXN5bmMod29ya2VyKTtcbiAgICB2YXIgbnVtUnVubmluZyA9IDA7XG4gICAgdmFyIHdvcmtlcnNMaXN0ID0gW107XG4gICAgY29uc3QgZXZlbnRzID0ge1xuICAgICAgICBlcnJvcjogW10sXG4gICAgICAgIGRyYWluOiBbXSxcbiAgICAgICAgc2F0dXJhdGVkOiBbXSxcbiAgICAgICAgdW5zYXR1cmF0ZWQ6IFtdLFxuICAgICAgICBlbXB0eTogW11cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gb24gKGV2ZW50LCBoYW5kbGVyKSB7XG4gICAgICAgIGV2ZW50c1tldmVudF0ucHVzaChoYW5kbGVyKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBvbmNlIChldmVudCwgaGFuZGxlcikge1xuICAgICAgICBjb25zdCBoYW5kbGVBbmRSZW1vdmUgPSAoLi4uYXJncykgPT4ge1xuICAgICAgICAgICAgb2ZmKGV2ZW50LCBoYW5kbGVBbmRSZW1vdmUpO1xuICAgICAgICAgICAgaGFuZGxlciguLi5hcmdzKTtcbiAgICAgICAgfTtcbiAgICAgICAgZXZlbnRzW2V2ZW50XS5wdXNoKGhhbmRsZUFuZFJlbW92ZSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gb2ZmIChldmVudCwgaGFuZGxlcikge1xuICAgICAgICBpZiAoIWV2ZW50KSByZXR1cm4gT2JqZWN0LmtleXMoZXZlbnRzKS5mb3JFYWNoKGV2ID0+IGV2ZW50c1tldl0gPSBbXSlcbiAgICAgICAgaWYgKCFoYW5kbGVyKSByZXR1cm4gZXZlbnRzW2V2ZW50XSA9IFtdXG4gICAgICAgIGV2ZW50c1tldmVudF0gPSBldmVudHNbZXZlbnRdLmZpbHRlcihldiA9PiBldiAhPT0gaGFuZGxlcik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdHJpZ2dlciAoZXZlbnQsIC4uLmFyZ3MpIHtcbiAgICAgICAgZXZlbnRzW2V2ZW50XS5mb3JFYWNoKGhhbmRsZXIgPT4gaGFuZGxlciguLi5hcmdzKSk7XG4gICAgfVxuXG4gICAgdmFyIHByb2Nlc3NpbmdTY2hlZHVsZWQgPSBmYWxzZTtcbiAgICBmdW5jdGlvbiBfaW5zZXJ0KGRhdGEsIGluc2VydEF0RnJvbnQsIHJlamVjdE9uRXJyb3IsIGNhbGxiYWNrKSB7XG4gICAgICAgIGlmIChjYWxsYmFjayAhPSBudWxsICYmIHR5cGVvZiBjYWxsYmFjayAhPT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0YXNrIGNhbGxiYWNrIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuICAgICAgICB9XG4gICAgICAgIHEuc3RhcnRlZCA9IHRydWU7XG5cbiAgICAgICAgdmFyIHJlcywgcmVqO1xuICAgICAgICBmdW5jdGlvbiBwcm9taXNlQ2FsbGJhY2sgKGVyciwgLi4uYXJncykge1xuICAgICAgICAgICAgLy8gd2UgZG9uJ3QgY2FyZSBhYm91dCB0aGUgZXJyb3IsIGxldCB0aGUgZ2xvYmFsIGVycm9yIGhhbmRsZXJcbiAgICAgICAgICAgIC8vIGRlYWwgd2l0aCBpdFxuICAgICAgICAgICAgaWYgKGVycikgcmV0dXJuIHJlamVjdE9uRXJyb3IgPyByZWooZXJyKSA6IHJlcygpXG4gICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPD0gMSkgcmV0dXJuIHJlcyhhcmdzWzBdKVxuICAgICAgICAgICAgcmVzKGFyZ3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGl0ZW0gPSBxLl9jcmVhdGVUYXNrSXRlbShcbiAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICByZWplY3RPbkVycm9yID8gcHJvbWlzZUNhbGxiYWNrIDpcbiAgICAgICAgICAgICAgICAoY2FsbGJhY2sgfHwgcHJvbWlzZUNhbGxiYWNrKVxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChpbnNlcnRBdEZyb250KSB7XG4gICAgICAgICAgICBxLl90YXNrcy51bnNoaWZ0KGl0ZW0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcS5fdGFza3MucHVzaChpdGVtKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghcHJvY2Vzc2luZ1NjaGVkdWxlZCkge1xuICAgICAgICAgICAgcHJvY2Vzc2luZ1NjaGVkdWxlZCA9IHRydWU7XG4gICAgICAgICAgICBzZXRJbW1lZGlhdGUkMSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgcHJvY2Vzc2luZ1NjaGVkdWxlZCA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIHEucHJvY2VzcygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVqZWN0T25FcnJvciB8fCAhY2FsbGJhY2spIHtcbiAgICAgICAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICAgICAgICAgICAgcmVzID0gcmVzb2x2ZTtcbiAgICAgICAgICAgICAgICByZWogPSByZWplY3Q7XG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX2NyZWF0ZUNCKHRhc2tzKSB7XG4gICAgICAgIHJldHVybiBmdW5jdGlvbiAoZXJyLCAuLi5hcmdzKSB7XG4gICAgICAgICAgICBudW1SdW5uaW5nIC09IDE7XG5cbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGFza3MubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgdmFyIHRhc2sgPSB0YXNrc1tpXTtcblxuICAgICAgICAgICAgICAgIHZhciBpbmRleCA9IHdvcmtlcnNMaXN0LmluZGV4T2YodGFzayk7XG4gICAgICAgICAgICAgICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICAgIHdvcmtlcnNMaXN0LnNoaWZ0KCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChpbmRleCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgd29ya2Vyc0xpc3Quc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICB0YXNrLmNhbGxiYWNrKGVyciwgLi4uYXJncyk7XG5cbiAgICAgICAgICAgICAgICBpZiAoZXJyICE9IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdHJpZ2dlcignZXJyb3InLCBlcnIsIHRhc2suZGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAobnVtUnVubmluZyA8PSAocS5jb25jdXJyZW5jeSAtIHEuYnVmZmVyKSApIHtcbiAgICAgICAgICAgICAgICB0cmlnZ2VyKCd1bnNhdHVyYXRlZCcpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAocS5pZGxlKCkpIHtcbiAgICAgICAgICAgICAgICB0cmlnZ2VyKCdkcmFpbicpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcS5wcm9jZXNzKCk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gX21heWJlRHJhaW4oZGF0YSkge1xuICAgICAgICBpZiAoZGF0YS5sZW5ndGggPT09IDAgJiYgcS5pZGxlKCkpIHtcbiAgICAgICAgICAgIC8vIGNhbGwgZHJhaW4gaW1tZWRpYXRlbHkgaWYgdGhlcmUgYXJlIG5vIHRhc2tzXG4gICAgICAgICAgICBzZXRJbW1lZGlhdGUkMSgoKSA9PiB0cmlnZ2VyKCdkcmFpbicpKTtcbiAgICAgICAgICAgIHJldHVybiB0cnVlXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgY29uc3QgZXZlbnRNZXRob2QgPSAobmFtZSkgPT4gKGhhbmRsZXIpID0+IHtcbiAgICAgICAgaWYgKCFoYW5kbGVyKSB7XG4gICAgICAgICAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgICAgICAgICAgIG9uY2UobmFtZSwgKGVyciwgZGF0YSkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZXJyKSByZXR1cm4gcmVqZWN0KGVycilcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZShkYXRhKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cbiAgICAgICAgb2ZmKG5hbWUpO1xuICAgICAgICBvbihuYW1lLCBoYW5kbGVyKTtcblxuICAgIH07XG5cbiAgICB2YXIgaXNQcm9jZXNzaW5nID0gZmFsc2U7XG4gICAgdmFyIHEgPSB7XG4gICAgICAgIF90YXNrczogbmV3IERMTCgpLFxuICAgICAgICBfY3JlYXRlVGFza0l0ZW0gKGRhdGEsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIGRhdGEsXG4gICAgICAgICAgICAgICAgY2FsbGJhY2tcbiAgICAgICAgICAgIH07XG4gICAgICAgIH0sXG4gICAgICAgICpbU3ltYm9sLml0ZXJhdG9yXSAoKSB7XG4gICAgICAgICAgICB5aWVsZCogcS5fdGFza3NbU3ltYm9sLml0ZXJhdG9yXSgpO1xuICAgICAgICB9LFxuICAgICAgICBjb25jdXJyZW5jeSxcbiAgICAgICAgcGF5bG9hZCxcbiAgICAgICAgYnVmZmVyOiBjb25jdXJyZW5jeSAvIDQsXG4gICAgICAgIHN0YXJ0ZWQ6IGZhbHNlLFxuICAgICAgICBwYXVzZWQ6IGZhbHNlLFxuICAgICAgICBwdXNoIChkYXRhLCBjYWxsYmFjaykge1xuICAgICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoZGF0YSkpIHtcbiAgICAgICAgICAgICAgICBpZiAoX21heWJlRHJhaW4oZGF0YSkpIHJldHVyblxuICAgICAgICAgICAgICAgIHJldHVybiBkYXRhLm1hcChkYXR1bSA9PiBfaW5zZXJ0KGRhdHVtLCBmYWxzZSwgZmFsc2UsIGNhbGxiYWNrKSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBfaW5zZXJ0KGRhdGEsIGZhbHNlLCBmYWxzZSwgY2FsbGJhY2spO1xuICAgICAgICB9LFxuICAgICAgICBwdXNoQXN5bmMgKGRhdGEsIGNhbGxiYWNrKSB7XG4gICAgICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShkYXRhKSkge1xuICAgICAgICAgICAgICAgIGlmIChfbWF5YmVEcmFpbihkYXRhKSkgcmV0dXJuXG4gICAgICAgICAgICAgICAgcmV0dXJuIGRhdGEubWFwKGRhdHVtID0+IF9pbnNlcnQoZGF0dW0sIGZhbHNlLCB0cnVlLCBjYWxsYmFjaykpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gX2luc2VydChkYXRhLCBmYWxzZSwgdHJ1ZSwgY2FsbGJhY2spO1xuICAgICAgICB9LFxuICAgICAgICBraWxsICgpIHtcbiAgICAgICAgICAgIG9mZigpO1xuICAgICAgICAgICAgcS5fdGFza3MuZW1wdHkoKTtcbiAgICAgICAgfSxcbiAgICAgICAgdW5zaGlmdCAoZGF0YSwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgaWYgKF9tYXliZURyYWluKGRhdGEpKSByZXR1cm5cbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5tYXAoZGF0dW0gPT4gX2luc2VydChkYXR1bSwgdHJ1ZSwgZmFsc2UsIGNhbGxiYWNrKSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBfaW5zZXJ0KGRhdGEsIHRydWUsIGZhbHNlLCBjYWxsYmFjayk7XG4gICAgICAgIH0sXG4gICAgICAgIHVuc2hpZnRBc3luYyAoZGF0YSwgY2FsbGJhY2spIHtcbiAgICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGRhdGEpKSB7XG4gICAgICAgICAgICAgICAgaWYgKF9tYXliZURyYWluKGRhdGEpKSByZXR1cm5cbiAgICAgICAgICAgICAgICByZXR1cm4gZGF0YS5tYXAoZGF0dW0gPT4gX2luc2VydChkYXR1bSwgdHJ1ZSwgdHJ1ZSwgY2FsbGJhY2spKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIF9pbnNlcnQoZGF0YSwgdHJ1ZSwgdHJ1ZSwgY2FsbGJhY2spO1xuICAgICAgICB9LFxuICAgICAgICByZW1vdmUgKHRlc3RGbikge1xuICAgICAgICAgICAgcS5fdGFza3MucmVtb3ZlKHRlc3RGbik7XG4gICAgICAgIH0sXG4gICAgICAgIHByb2Nlc3MgKCkge1xuICAgICAgICAgICAgLy8gQXZvaWQgdHJ5aW5nIHRvIHN0YXJ0IHRvbyBtYW55IHByb2Nlc3Npbmcgb3BlcmF0aW9ucy4gVGhpcyBjYW4gb2NjdXJcbiAgICAgICAgICAgIC8vIHdoZW4gY2FsbGJhY2tzIHJlc29sdmUgc3luY2hyb25vdXNseSAoIzEyNjcpLlxuICAgICAgICAgICAgaWYgKGlzUHJvY2Vzc2luZykge1xuICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlzUHJvY2Vzc2luZyA9IHRydWU7XG4gICAgICAgICAgICB3aGlsZSghcS5wYXVzZWQgJiYgbnVtUnVubmluZyA8IHEuY29uY3VycmVuY3kgJiYgcS5fdGFza3MubGVuZ3RoKXtcbiAgICAgICAgICAgICAgICB2YXIgdGFza3MgPSBbXSwgZGF0YSA9IFtdO1xuICAgICAgICAgICAgICAgIHZhciBsID0gcS5fdGFza3MubGVuZ3RoO1xuICAgICAgICAgICAgICAgIGlmIChxLnBheWxvYWQpIGwgPSBNYXRoLm1pbihsLCBxLnBheWxvYWQpO1xuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHZhciBub2RlID0gcS5fdGFza3Muc2hpZnQoKTtcbiAgICAgICAgICAgICAgICAgICAgdGFza3MucHVzaChub2RlKTtcbiAgICAgICAgICAgICAgICAgICAgd29ya2Vyc0xpc3QucHVzaChub2RlKTtcbiAgICAgICAgICAgICAgICAgICAgZGF0YS5wdXNoKG5vZGUuZGF0YSk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgbnVtUnVubmluZyArPSAxO1xuXG4gICAgICAgICAgICAgICAgaWYgKHEuX3Rhc2tzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgICB0cmlnZ2VyKCdlbXB0eScpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmIChudW1SdW5uaW5nID09PSBxLmNvbmN1cnJlbmN5KSB7XG4gICAgICAgICAgICAgICAgICAgIHRyaWdnZXIoJ3NhdHVyYXRlZCcpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHZhciBjYiA9IG9ubHlPbmNlKF9jcmVhdGVDQih0YXNrcykpO1xuICAgICAgICAgICAgICAgIF93b3JrZXIoZGF0YSwgY2IpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaXNQcm9jZXNzaW5nID0gZmFsc2U7XG4gICAgICAgIH0sXG4gICAgICAgIGxlbmd0aCAoKSB7XG4gICAgICAgICAgICByZXR1cm4gcS5fdGFza3MubGVuZ3RoO1xuICAgICAgICB9LFxuICAgICAgICBydW5uaW5nICgpIHtcbiAgICAgICAgICAgIHJldHVybiBudW1SdW5uaW5nO1xuICAgICAgICB9LFxuICAgICAgICB3b3JrZXJzTGlzdCAoKSB7XG4gICAgICAgICAgICByZXR1cm4gd29ya2Vyc0xpc3Q7XG4gICAgICAgIH0sXG4gICAgICAgIGlkbGUoKSB7XG4gICAgICAgICAgICByZXR1cm4gcS5fdGFza3MubGVuZ3RoICsgbnVtUnVubmluZyA9PT0gMDtcbiAgICAgICAgfSxcbiAgICAgICAgcGF1c2UgKCkge1xuICAgICAgICAgICAgcS5wYXVzZWQgPSB0cnVlO1xuICAgICAgICB9LFxuICAgICAgICByZXN1bWUgKCkge1xuICAgICAgICAgICAgaWYgKHEucGF1c2VkID09PSBmYWxzZSkgeyByZXR1cm47IH1cbiAgICAgICAgICAgIHEucGF1c2VkID0gZmFsc2U7XG4gICAgICAgICAgICBzZXRJbW1lZGlhdGUkMShxLnByb2Nlc3MpO1xuICAgICAgICB9XG4gICAgfTtcbiAgICAvLyBkZWZpbmUgdGhlc2UgYXMgZml4ZWQgcHJvcGVydGllcywgc28gcGVvcGxlIGdldCB1c2VmdWwgZXJyb3JzIHdoZW4gdXBkYXRpbmdcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhxLCB7XG4gICAgICAgIHNhdHVyYXRlZDoge1xuICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgdmFsdWU6IGV2ZW50TWV0aG9kKCdzYXR1cmF0ZWQnKVxuICAgICAgICB9LFxuICAgICAgICB1bnNhdHVyYXRlZDoge1xuICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgdmFsdWU6IGV2ZW50TWV0aG9kKCd1bnNhdHVyYXRlZCcpXG4gICAgICAgIH0sXG4gICAgICAgIGVtcHR5OiB7XG4gICAgICAgICAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgICAgICAgICB2YWx1ZTogZXZlbnRNZXRob2QoJ2VtcHR5JylcbiAgICAgICAgfSxcbiAgICAgICAgZHJhaW46IHtcbiAgICAgICAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgICAgICAgIHZhbHVlOiBldmVudE1ldGhvZCgnZHJhaW4nKVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjoge1xuICAgICAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICAgICAgdmFsdWU6IGV2ZW50TWV0aG9kKCdlcnJvcicpXG4gICAgICAgIH0sXG4gICAgfSk7XG4gICAgcmV0dXJuIHE7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIGBjYXJnb2Agb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBwYXlsb2FkLiBUYXNrcyBhZGRlZCB0byB0aGVcbiAqIGNhcmdvIHdpbGwgYmUgcHJvY2Vzc2VkIGFsdG9nZXRoZXIgKHVwIHRvIHRoZSBgcGF5bG9hZGAgbGltaXQpLiBJZiB0aGVcbiAqIGB3b3JrZXJgIGlzIGluIHByb2dyZXNzLCB0aGUgdGFzayBpcyBxdWV1ZWQgdW50aWwgaXQgYmVjb21lcyBhdmFpbGFibGUuIE9uY2VcbiAqIHRoZSBgd29ya2VyYCBoYXMgY29tcGxldGVkIHNvbWUgdGFza3MsIGVhY2ggY2FsbGJhY2sgb2YgdGhvc2UgdGFza3MgaXNcbiAqIGNhbGxlZC4gQ2hlY2sgb3V0IFt0aGVzZV0oaHR0cHM6Ly9jYW1vLmdpdGh1YnVzZXJjb250ZW50LmNvbS82YmJkMzZmNGNmNWIzNWEwZjExYTk2ZGNkMmU5NzcxMWZmYzJmYjM3LzY4NzQ3NDcwNzMzYTJmMmY2NjJlNjM2YzZmNzU2NDJlNjc2OTc0Njg3NTYyMmU2MzZmNmQyZjYxNzM3MzY1NzQ3MzJmMzEzNjM3MzYzODM3MzEyZjM2MzgzMTMwMzgyZjYyNjI2MzMwNjM2NjYyMzAyZDM1NjYzMjM5MmQzMTMxNjUzMjJkMzkzNzM0NjYyZDMzMzMzOTM3NjMzNjM0NjQ2MzM4MzUzODJlNjc2OTY2KSBbYW5pbWF0aW9uc10oaHR0cHM6Ly9jYW1vLmdpdGh1YnVzZXJjb250ZW50LmNvbS9mNDgxMGUwMGUxYzVmNWY4YWRkYmUzZTlmNDkwNjRmZDVkMTAyNjk5LzY4NzQ3NDcwNzMzYTJmMmY2NjJlNjM2YzZmNzU2NDJlNjc2OTc0Njg3NTYyMmU2MzZmNmQyZjYxNzM3MzY1NzQ3MzJmMzEzNjM3MzYzODM3MzEyZjM2MzgzMTMwMzEyZjM4MzQ2MzM5MzIzMDM2MzYyZDM1NjYzMjM5MmQzMTMxNjUzMjJkMzgzMTM0NjYyZDM5NjQzMzY0MzAzMjM0MzEzMzYyNjY2NDJlNjc2OTY2KVxuICogZm9yIGhvdyBgY2FyZ29gIGFuZCBgcXVldWVgIHdvcmsuXG4gKlxuICogV2hpbGUgW2BxdWV1ZWBde0BsaW5rIG1vZHVsZTpDb250cm9sRmxvdy5xdWV1ZX0gcGFzc2VzIG9ubHkgb25lIHRhc2sgdG8gb25lIG9mIGEgZ3JvdXAgb2Ygd29ya2Vyc1xuICogYXQgYSB0aW1lLCBjYXJnbyBwYXNzZXMgYW4gYXJyYXkgb2YgdGFza3MgdG8gYSBzaW5nbGUgd29ya2VyLCByZXBlYXRpbmdcbiAqIHdoZW4gdGhlIHdvcmtlciBpcyBmaW5pc2hlZC5cbiAqXG4gKiBAbmFtZSBjYXJnb1xuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb250cm9sRmxvd1xuICogQG1ldGhvZFxuICogQHNlZSBbYXN5bmMucXVldWVde0BsaW5rIG1vZHVsZTpDb250cm9sRmxvdy5xdWV1ZX1cbiAqIEBjYXRlZ29yeSBDb250cm9sIEZsb3dcbiAqIEBwYXJhbSB7QXN5bmNGdW5jdGlvbn0gd29ya2VyIC0gQW4gYXN5bmNocm9ub3VzIGZ1bmN0aW9uIGZvciBwcm9jZXNzaW5nIGFuIGFycmF5XG4gKiBvZiBxdWV1ZWQgdGFza3MuIEludm9rZWQgd2l0aCBgKHRhc2tzLCBjYWxsYmFjaylgLlxuICogQHBhcmFtIHtudW1iZXJ9IFtwYXlsb2FkPUluZmluaXR5XSAtIEFuIG9wdGlvbmFsIGBpbnRlZ2VyYCBmb3IgZGV0ZXJtaW5pbmdcbiAqIGhvdyBtYW55IHRhc2tzIHNob3VsZCBiZSBwcm9jZXNzZWQgcGVyIHJvdW5kOyBpZiBvbWl0dGVkLCB0aGUgZGVmYXVsdCBpc1xuICogdW5saW1pdGVkLlxuICogQHJldHVybnMge21vZHVsZTpDb250cm9sRmxvdy5RdWV1ZU9iamVjdH0gQSBjYXJnbyBvYmplY3QgdG8gbWFuYWdlIHRoZSB0YXNrcy4gQ2FsbGJhY2tzIGNhblxuICogYXR0YWNoZWQgYXMgY2VydGFpbiBwcm9wZXJ0aWVzIHRvIGxpc3RlbiBmb3Igc3BlY2lmaWMgZXZlbnRzIGR1cmluZyB0aGVcbiAqIGxpZmVjeWNsZSBvZiB0aGUgY2FyZ28gYW5kIGlubmVyIHF1ZXVlLlxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBjcmVhdGUgYSBjYXJnbyBvYmplY3Qgd2l0aCBwYXlsb2FkIDJcbiAqIHZhciBjYXJnbyA9IGFzeW5jLmNhcmdvKGZ1bmN0aW9uKHRhc2tzLCBjYWxsYmFjaykge1xuICogICAgIGZvciAodmFyIGk9MDsgaTx0YXNrcy5sZW5ndGg7IGkrKykge1xuICogICAgICAgICBjb25zb2xlLmxvZygnaGVsbG8gJyArIHRhc2tzW2ldLm5hbWUpO1xuICogICAgIH1cbiAqICAgICBjYWxsYmFjaygpO1xuICogfSwgMik7XG4gKlxuICogLy8gYWRkIHNvbWUgaXRlbXNcbiAqIGNhcmdvLnB1c2goe25hbWU6ICdmb28nfSwgZnVuY3Rpb24oZXJyKSB7XG4gKiAgICAgY29uc29sZS5sb2coJ2ZpbmlzaGVkIHByb2Nlc3NpbmcgZm9vJyk7XG4gKiB9KTtcbiAqIGNhcmdvLnB1c2goe25hbWU6ICdiYXInfSwgZnVuY3Rpb24oZXJyKSB7XG4gKiAgICAgY29uc29sZS5sb2coJ2ZpbmlzaGVkIHByb2Nlc3NpbmcgYmFyJyk7XG4gKiB9KTtcbiAqIGF3YWl0IGNhcmdvLnB1c2goe25hbWU6ICdiYXonfSk7XG4gKiBjb25zb2xlLmxvZygnZmluaXNoZWQgcHJvY2Vzc2luZyBiYXonKTtcbiAqL1xuZnVuY3Rpb24gY2FyZ28kMSh3b3JrZXIsIHBheWxvYWQpIHtcbiAgICByZXR1cm4gcXVldWUkMSh3b3JrZXIsIDEsIHBheWxvYWQpO1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBgY2FyZ29RdWV1ZWAgb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBwYXlsb2FkLiBUYXNrcyBhZGRlZCB0byB0aGVcbiAqIGNhcmdvUXVldWUgd2lsbCBiZSBwcm9jZXNzZWQgdG9nZXRoZXIgKHVwIHRvIHRoZSBgcGF5bG9hZGAgbGltaXQpIGluIGBjb25jdXJyZW5jeWAgcGFyYWxsZWwgd29ya2Vycy5cbiAqIElmIHRoZSBhbGwgYHdvcmtlcnNgIGFyZSBpbiBwcm9ncmVzcywgdGhlIHRhc2sgaXMgcXVldWVkIHVudGlsIG9uZSBiZWNvbWVzIGF2YWlsYWJsZS4gT25jZVxuICogYSBgd29ya2VyYCBoYXMgY29tcGxldGVkIHNvbWUgdGFza3MsIGVhY2ggY2FsbGJhY2sgb2YgdGhvc2UgdGFza3MgaXNcbiAqIGNhbGxlZC4gQ2hlY2sgb3V0IFt0aGVzZV0oaHR0cHM6Ly9jYW1vLmdpdGh1YnVzZXJjb250ZW50LmNvbS82YmJkMzZmNGNmNWIzNWEwZjExYTk2ZGNkMmU5NzcxMWZmYzJmYjM3LzY4NzQ3NDcwNzMzYTJmMmY2NjJlNjM2YzZmNzU2NDJlNjc2OTc0Njg3NTYyMmU2MzZmNmQyZjYxNzM3MzY1NzQ3MzJmMzEzNjM3MzYzODM3MzEyZjM2MzgzMTMwMzgyZjYyNjI2MzMwNjM2NjYyMzAyZDM1NjYzMjM5MmQzMTMxNjUzMjJkMzkzNzM0NjYyZDMzMzMzOTM3NjMzNjM0NjQ2MzM4MzUzODJlNjc2OTY2KSBbYW5pbWF0aW9uc10oaHR0cHM6Ly9jYW1vLmdpdGh1YnVzZXJjb250ZW50LmNvbS9mNDgxMGUwMGUxYzVmNWY4YWRkYmUzZTlmNDkwNjRmZDVkMTAyNjk5LzY4NzQ3NDcwNzMzYTJmMmY2NjJlNjM2YzZmNzU2NDJlNjc2OTc0Njg3NTYyMmU2MzZmNmQyZjYxNzM3MzY1NzQ3MzJmMzEzNjM3MzYzODM3MzEyZjM2MzgzMTMwMzEyZjM4MzQ2MzM5MzIzMDM2MzYyZDM1NjYzMjM5MmQzMTMxNjUzMjJkMzgzMTM0NjYyZDM5NjQzMzY0MzAzMjM0MzEzMzYyNjY2NDJlNjc2OTY2KVxuICogZm9yIGhvdyBgY2FyZ29gIGFuZCBgcXVldWVgIHdvcmsuXG4gKlxuICogV2hpbGUgW2BxdWV1ZWBde0BsaW5rIG1vZHVsZTpDb250cm9sRmxvdy5xdWV1ZX0gcGFzc2VzIG9ubHkgb25lIHRhc2sgdG8gb25lIG9mIGEgZ3JvdXAgb2Ygd29ya2Vyc1xuICogYXQgYSB0aW1lLCBhbmQgW2BjYXJnb2Bde0BsaW5rIG1vZHVsZTpDb250cm9sRmxvdy5jYXJnb30gcGFzc2VzIGFuIGFycmF5IG9mIHRhc2tzIHRvIGEgc2luZ2xlIHdvcmtlcixcbiAqIHRoZSBjYXJnb1F1ZXVlIHBhc3NlcyBhbiBhcnJheSBvZiB0YXNrcyB0byBtdWx0aXBsZSBwYXJhbGxlbCB3b3JrZXJzLlxuICpcbiAqIEBuYW1lIGNhcmdvUXVldWVcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29udHJvbEZsb3dcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLnF1ZXVlXXtAbGluayBtb2R1bGU6Q29udHJvbEZsb3cucXVldWV9XG4gKiBAc2VlIFthc3luYy5jYXJnb117QGxpbmsgbW9kdWxlOkNvbnRyb2xGTG93LmNhcmdvfVxuICogQGNhdGVnb3J5IENvbnRyb2wgRmxvd1xuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSB3b3JrZXIgLSBBbiBhc3luY2hyb25vdXMgZnVuY3Rpb24gZm9yIHByb2Nlc3NpbmcgYW4gYXJyYXlcbiAqIG9mIHF1ZXVlZCB0YXNrcy4gSW52b2tlZCB3aXRoIGAodGFza3MsIGNhbGxiYWNrKWAuXG4gKiBAcGFyYW0ge251bWJlcn0gW2NvbmN1cnJlbmN5PTFdIC0gQW4gYGludGVnZXJgIGZvciBkZXRlcm1pbmluZyBob3cgbWFueVxuICogYHdvcmtlcmAgZnVuY3Rpb25zIHNob3VsZCBiZSBydW4gaW4gcGFyYWxsZWwuICBJZiBvbWl0dGVkLCB0aGUgY29uY3VycmVuY3lcbiAqIGRlZmF1bHRzIHRvIGAxYC4gIElmIHRoZSBjb25jdXJyZW5jeSBpcyBgMGAsIGFuIGVycm9yIGlzIHRocm93bi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbcGF5bG9hZD1JbmZpbml0eV0gLSBBbiBvcHRpb25hbCBgaW50ZWdlcmAgZm9yIGRldGVybWluaW5nXG4gKiBob3cgbWFueSB0YXNrcyBzaG91bGQgYmUgcHJvY2Vzc2VkIHBlciByb3VuZDsgaWYgb21pdHRlZCwgdGhlIGRlZmF1bHQgaXNcbiAqIHVubGltaXRlZC5cbiAqIEByZXR1cm5zIHttb2R1bGU6Q29udHJvbEZsb3cuUXVldWVPYmplY3R9IEEgY2FyZ29RdWV1ZSBvYmplY3QgdG8gbWFuYWdlIHRoZSB0YXNrcy4gQ2FsbGJhY2tzIGNhblxuICogYXR0YWNoZWQgYXMgY2VydGFpbiBwcm9wZXJ0aWVzIHRvIGxpc3RlbiBmb3Igc3BlY2lmaWMgZXZlbnRzIGR1cmluZyB0aGVcbiAqIGxpZmVjeWNsZSBvZiB0aGUgY2FyZ29RdWV1ZSBhbmQgaW5uZXIgcXVldWUuXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIGNyZWF0ZSBhIGNhcmdvUXVldWUgb2JqZWN0IHdpdGggcGF5bG9hZCAyIGFuZCBjb25jdXJyZW5jeSAyXG4gKiB2YXIgY2FyZ29RdWV1ZSA9IGFzeW5jLmNhcmdvUXVldWUoZnVuY3Rpb24odGFza3MsIGNhbGxiYWNrKSB7XG4gKiAgICAgZm9yICh2YXIgaT0wOyBpPHRhc2tzLmxlbmd0aDsgaSsrKSB7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKCdoZWxsbyAnICsgdGFza3NbaV0ubmFtZSk7XG4gKiAgICAgfVxuICogICAgIGNhbGxiYWNrKCk7XG4gKiB9LCAyLCAyKTtcbiAqXG4gKiAvLyBhZGQgc29tZSBpdGVtc1xuICogY2FyZ29RdWV1ZS5wdXNoKHtuYW1lOiAnZm9vJ30sIGZ1bmN0aW9uKGVycikge1xuICogICAgIGNvbnNvbGUubG9nKCdmaW5pc2hlZCBwcm9jZXNzaW5nIGZvbycpO1xuICogfSk7XG4gKiBjYXJnb1F1ZXVlLnB1c2goe25hbWU6ICdiYXInfSwgZnVuY3Rpb24oZXJyKSB7XG4gKiAgICAgY29uc29sZS5sb2coJ2ZpbmlzaGVkIHByb2Nlc3NpbmcgYmFyJyk7XG4gKiB9KTtcbiAqIGNhcmdvUXVldWUucHVzaCh7bmFtZTogJ2Jheid9LCBmdW5jdGlvbihlcnIpIHtcbiAqICAgICBjb25zb2xlLmxvZygnZmluaXNoZWQgcHJvY2Vzc2luZyBiYXonKTtcbiAqIH0pO1xuICogY2FyZ29RdWV1ZS5wdXNoKHtuYW1lOiAnYm9vJ30sIGZ1bmN0aW9uKGVycikge1xuICogICAgIGNvbnNvbGUubG9nKCdmaW5pc2hlZCBwcm9jZXNzaW5nIGJvbycpO1xuICogfSk7XG4gKi9cbmZ1bmN0aW9uIGNhcmdvKHdvcmtlciwgY29uY3VycmVuY3ksIHBheWxvYWQpIHtcbiAgICByZXR1cm4gcXVldWUkMSh3b3JrZXIsIGNvbmN1cnJlbmN5LCBwYXlsb2FkKTtcbn1cblxuLyoqXG4gKiBSZWR1Y2VzIGBjb2xsYCBpbnRvIGEgc2luZ2xlIHZhbHVlIHVzaW5nIGFuIGFzeW5jIGBpdGVyYXRlZWAgdG8gcmV0dXJuIGVhY2hcbiAqIHN1Y2Nlc3NpdmUgc3RlcC4gYG1lbW9gIGlzIHRoZSBpbml0aWFsIHN0YXRlIG9mIHRoZSByZWR1Y3Rpb24uIFRoaXMgZnVuY3Rpb25cbiAqIG9ubHkgb3BlcmF0ZXMgaW4gc2VyaWVzLlxuICpcbiAqIEZvciBwZXJmb3JtYW5jZSByZWFzb25zLCBpdCBtYXkgbWFrZSBzZW5zZSB0byBzcGxpdCBhIGNhbGwgdG8gdGhpcyBmdW5jdGlvblxuICogaW50byBhIHBhcmFsbGVsIG1hcCwgYW5kIHRoZW4gdXNlIHRoZSBub3JtYWwgYEFycmF5LnByb3RvdHlwZS5yZWR1Y2VgIG9uIHRoZVxuICogcmVzdWx0cy4gVGhpcyBmdW5jdGlvbiBpcyBmb3Igc2l0dWF0aW9ucyB3aGVyZSBlYWNoIHN0ZXAgaW4gdGhlIHJlZHVjdGlvblxuICogbmVlZHMgdG8gYmUgYXN5bmM7IGlmIHlvdSBjYW4gZ2V0IHRoZSBkYXRhIGJlZm9yZSByZWR1Y2luZyBpdCwgdGhlbiBpdCdzXG4gKiBwcm9iYWJseSBhIGdvb2QgaWRlYSB0byBkbyBzby5cbiAqXG4gKiBAbmFtZSByZWR1Y2VcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29sbGVjdGlvbnNcbiAqIEBtZXRob2RcbiAqIEBhbGlhcyBpbmplY3RcbiAqIEBhbGlhcyBmb2xkbFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IGNvbGwgLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHsqfSBtZW1vIC0gVGhlIGluaXRpYWwgc3RhdGUgb2YgdGhlIHJlZHVjdGlvbi5cbiAqIEBwYXJhbSB7QXN5bmNGdW5jdGlvbn0gaXRlcmF0ZWUgLSBBIGZ1bmN0aW9uIGFwcGxpZWQgdG8gZWFjaCBpdGVtIGluIHRoZVxuICogYXJyYXkgdG8gcHJvZHVjZSB0aGUgbmV4dCBzdGVwIGluIHRoZSByZWR1Y3Rpb24uXG4gKiBUaGUgYGl0ZXJhdGVlYCBzaG91bGQgY29tcGxldGUgd2l0aCB0aGUgbmV4dCBzdGF0ZSBvZiB0aGUgcmVkdWN0aW9uLlxuICogSWYgdGhlIGl0ZXJhdGVlIGNvbXBsZXRlcyB3aXRoIGFuIGVycm9yLCB0aGUgcmVkdWN0aW9uIGlzIHN0b3BwZWQgYW5kIHRoZVxuICogbWFpbiBgY2FsbGJhY2tgIGlzIGltbWVkaWF0ZWx5IGNhbGxlZCB3aXRoIHRoZSBlcnJvci5cbiAqIEludm9rZWQgd2l0aCAobWVtbywgaXRlbSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIGFmdGVyIGFsbCB0aGVcbiAqIGBpdGVyYXRlZWAgZnVuY3Rpb25zIGhhdmUgZmluaXNoZWQuIFJlc3VsdCBpcyB0aGUgcmVkdWNlZCB2YWx1ZS4gSW52b2tlZCB3aXRoXG4gKiAoZXJyLCByZXN1bHQpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgbm8gY2FsbGJhY2sgaXMgcGFzc2VkXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIGZpbGUxLnR4dCBpcyBhIGZpbGUgdGhhdCBpcyAxMDAwIGJ5dGVzIGluIHNpemVcbiAqIC8vIGZpbGUyLnR4dCBpcyBhIGZpbGUgdGhhdCBpcyAyMDAwIGJ5dGVzIGluIHNpemVcbiAqIC8vIGZpbGUzLnR4dCBpcyBhIGZpbGUgdGhhdCBpcyAzMDAwIGJ5dGVzIGluIHNpemVcbiAqIC8vIGZpbGU0LnR4dCBkb2VzIG5vdCBleGlzdFxuICpcbiAqIGNvbnN0IGZpbGVMaXN0ID0gWydmaWxlMS50eHQnLCdmaWxlMi50eHQnLCdmaWxlMy50eHQnXTtcbiAqIGNvbnN0IHdpdGhNaXNzaW5nRmlsZUxpc3QgPSBbJ2ZpbGUxLnR4dCcsJ2ZpbGUyLnR4dCcsJ2ZpbGUzLnR4dCcsICdmaWxlNC50eHQnXTtcbiAqXG4gKiAvLyBhc3luY2hyb25vdXMgZnVuY3Rpb24gdGhhdCBjb21wdXRlcyB0aGUgZmlsZSBzaXplIGluIGJ5dGVzXG4gKiAvLyBmaWxlIHNpemUgaXMgYWRkZWQgdG8gdGhlIG1lbW9pemVkIHZhbHVlLCB0aGVuIHJldHVybmVkXG4gKiBmdW5jdGlvbiBnZXRGaWxlU2l6ZUluQnl0ZXMobWVtbywgZmlsZSwgY2FsbGJhY2spIHtcbiAqICAgICBmcy5zdGF0KGZpbGUsIGZ1bmN0aW9uKGVyciwgc3RhdCkge1xuICogICAgICAgICBpZiAoZXJyKSB7XG4gKiAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAqICAgICAgICAgfVxuICogICAgICAgICBjYWxsYmFjayhudWxsLCBtZW1vICsgc3RhdC5zaXplKTtcbiAqICAgICB9KTtcbiAqIH1cbiAqXG4gKiAvLyBVc2luZyBjYWxsYmFja3NcbiAqIGFzeW5jLnJlZHVjZShmaWxlTGlzdCwgMCwgZ2V0RmlsZVNpemVJbkJ5dGVzLCBmdW5jdGlvbihlcnIsIHJlc3VsdCkge1xuICogICAgIGlmIChlcnIpIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICB9IGVsc2Uge1xuICogICAgICAgICBjb25zb2xlLmxvZyhyZXN1bHQpO1xuICogICAgICAgICAvLyA2MDAwXG4gKiAgICAgICAgIC8vIHdoaWNoIGlzIHRoZSBzdW0gb2YgdGhlIGZpbGUgc2l6ZXMgb2YgdGhlIHRocmVlIGZpbGVzXG4gKiAgICAgfVxuICogfSk7XG4gKlxuICogLy8gRXJyb3IgSGFuZGxpbmdcbiAqIGFzeW5jLnJlZHVjZSh3aXRoTWlzc2luZ0ZpbGVMaXN0LCAwLCBnZXRGaWxlU2l6ZUluQnl0ZXMsIGZ1bmN0aW9uKGVyciwgcmVzdWx0KSB7XG4gKiAgICAgaWYgKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgICAgICAvLyBbIEVycm9yOiBFTk9FTlQ6IG5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkgXVxuICogICAgIH0gZWxzZSB7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdCk7XG4gKiAgICAgfVxuICogfSk7XG4gKlxuICogLy8gVXNpbmcgUHJvbWlzZXNcbiAqIGFzeW5jLnJlZHVjZShmaWxlTGlzdCwgMCwgZ2V0RmlsZVNpemVJbkJ5dGVzKVxuICogLnRoZW4oIHJlc3VsdCA9PiB7XG4gKiAgICAgY29uc29sZS5sb2cocmVzdWx0KTtcbiAqICAgICAvLyA2MDAwXG4gKiAgICAgLy8gd2hpY2ggaXMgdGhlIHN1bSBvZiB0aGUgZmlsZSBzaXplcyBvZiB0aGUgdGhyZWUgZmlsZXNcbiAqIH0pLmNhdGNoKCBlcnIgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiB9KTtcbiAqXG4gKiAvLyBFcnJvciBIYW5kbGluZ1xuICogYXN5bmMucmVkdWNlKHdpdGhNaXNzaW5nRmlsZUxpc3QsIDAsIGdldEZpbGVTaXplSW5CeXRlcylcbiAqIC50aGVuKCByZXN1bHQgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKHJlc3VsdCk7XG4gKiB9KS5jYXRjaCggZXJyID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgIC8vIFsgRXJyb3I6IEVOT0VOVDogbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeSBdXG4gKiB9KTtcbiAqXG4gKiAvLyBVc2luZyBhc3luYy9hd2FpdFxuICogYXN5bmMgKCkgPT4ge1xuICogICAgIHRyeSB7XG4gKiAgICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCBhc3luYy5yZWR1Y2UoZmlsZUxpc3QsIDAsIGdldEZpbGVTaXplSW5CeXRlcyk7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdCk7XG4gKiAgICAgICAgIC8vIDYwMDBcbiAqICAgICAgICAgLy8gd2hpY2ggaXMgdGhlIHN1bSBvZiB0aGUgZmlsZSBzaXplcyBvZiB0aGUgdGhyZWUgZmlsZXNcbiAqICAgICB9XG4gKiAgICAgY2F0Y2ggKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgIH1cbiAqIH1cbiAqXG4gKiAvLyBFcnJvciBIYW5kbGluZ1xuICogYXN5bmMgKCkgPT4ge1xuICogICAgIHRyeSB7XG4gKiAgICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCBhc3luYy5yZWR1Y2Uod2l0aE1pc3NpbmdGaWxlTGlzdCwgMCwgZ2V0RmlsZVNpemVJbkJ5dGVzKTtcbiAqICAgICAgICAgY29uc29sZS5sb2cocmVzdWx0KTtcbiAqICAgICB9XG4gKiAgICAgY2F0Y2ggKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgICAgICAvLyBbIEVycm9yOiBFTk9FTlQ6IG5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkgXVxuICogICAgIH1cbiAqIH1cbiAqXG4gKi9cbmZ1bmN0aW9uIHJlZHVjZShjb2xsLCBtZW1vLCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICBjYWxsYmFjayA9IG9uY2UoY2FsbGJhY2spO1xuICAgIHZhciBfaXRlcmF0ZWUgPSB3cmFwQXN5bmMoaXRlcmF0ZWUpO1xuICAgIHJldHVybiBlYWNoT2ZTZXJpZXMkMShjb2xsLCAoeCwgaSwgaXRlckNiKSA9PiB7XG4gICAgICAgIF9pdGVyYXRlZShtZW1vLCB4LCAoZXJyLCB2KSA9PiB7XG4gICAgICAgICAgICBtZW1vID0gdjtcbiAgICAgICAgICAgIGl0ZXJDYihlcnIpO1xuICAgICAgICB9KTtcbiAgICB9LCBlcnIgPT4gY2FsbGJhY2soZXJyLCBtZW1vKSk7XG59XG52YXIgcmVkdWNlJDEgPSBhd2FpdGlmeShyZWR1Y2UsIDQpO1xuXG4vKipcbiAqIFZlcnNpb24gb2YgdGhlIGNvbXBvc2UgZnVuY3Rpb24gdGhhdCBpcyBtb3JlIG5hdHVyYWwgdG8gcmVhZC4gRWFjaCBmdW5jdGlvblxuICogY29uc3VtZXMgdGhlIHJldHVybiB2YWx1ZSBvZiB0aGUgcHJldmlvdXMgZnVuY3Rpb24uIEl0IGlzIHRoZSBlcXVpdmFsZW50IG9mXG4gKiBbY29tcG9zZV17QGxpbmsgbW9kdWxlOkNvbnRyb2xGbG93LmNvbXBvc2V9IHdpdGggdGhlIGFyZ3VtZW50cyByZXZlcnNlZC5cbiAqXG4gKiBFYWNoIGZ1bmN0aW9uIGlzIGV4ZWN1dGVkIHdpdGggdGhlIGB0aGlzYCBiaW5kaW5nIG9mIHRoZSBjb21wb3NlZCBmdW5jdGlvbi5cbiAqXG4gKiBAbmFtZSBzZXFcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29udHJvbEZsb3dcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLmNvbXBvc2Vde0BsaW5rIG1vZHVsZTpDb250cm9sRmxvdy5jb21wb3NlfVxuICogQGNhdGVnb3J5IENvbnRyb2wgRmxvd1xuICogQHBhcmFtIHsuLi5Bc3luY0Z1bmN0aW9ufSBmdW5jdGlvbnMgLSB0aGUgYXN5bmNocm9ub3VzIGZ1bmN0aW9ucyB0byBjb21wb3NlXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCBjb21wb3NlcyB0aGUgYGZ1bmN0aW9uc2AgaW4gb3JkZXJcbiAqIEBleGFtcGxlXG4gKlxuICogLy8gUmVxdWlyZXMgbG9kYXNoIChvciB1bmRlcnNjb3JlKSwgZXhwcmVzczMgYW5kIGRyZXNlbmRlJ3Mgb3JtMi5cbiAqIC8vIFBhcnQgb2YgYW4gYXBwLCB0aGF0IGZldGNoZXMgY2F0cyBvZiB0aGUgbG9nZ2VkIHVzZXIuXG4gKiAvLyBUaGlzIGV4YW1wbGUgdXNlcyBgc2VxYCBmdW5jdGlvbiB0byBhdm9pZCBvdmVybmVzdGluZyBhbmQgZXJyb3JcbiAqIC8vIGhhbmRsaW5nIGNsdXR0ZXIuXG4gKiBhcHAuZ2V0KCcvY2F0cycsIGZ1bmN0aW9uKHJlcXVlc3QsIHJlc3BvbnNlKSB7XG4gKiAgICAgdmFyIFVzZXIgPSByZXF1ZXN0Lm1vZGVscy5Vc2VyO1xuICogICAgIGFzeW5jLnNlcShcbiAqICAgICAgICAgVXNlci5nZXQuYmluZChVc2VyKSwgIC8vICdVc2VyLmdldCcgaGFzIHNpZ25hdHVyZSAoaWQsIGNhbGxiYWNrKGVyciwgZGF0YSkpXG4gKiAgICAgICAgIGZ1bmN0aW9uKHVzZXIsIGZuKSB7XG4gKiAgICAgICAgICAgICB1c2VyLmdldENhdHMoZm4pOyAgICAgIC8vICdnZXRDYXRzJyBoYXMgc2lnbmF0dXJlIChjYWxsYmFjayhlcnIsIGRhdGEpKVxuICogICAgICAgICB9XG4gKiAgICAgKShyZXEuc2Vzc2lvbi51c2VyX2lkLCBmdW5jdGlvbiAoZXJyLCBjYXRzKSB7XG4gKiAgICAgICAgIGlmIChlcnIpIHtcbiAqICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyKTtcbiAqICAgICAgICAgICAgIHJlc3BvbnNlLmpzb24oeyBzdGF0dXM6ICdlcnJvcicsIG1lc3NhZ2U6IGVyci5tZXNzYWdlIH0pO1xuICogICAgICAgICB9IGVsc2Uge1xuICogICAgICAgICAgICAgcmVzcG9uc2UuanNvbih7IHN0YXR1czogJ29rJywgbWVzc2FnZTogJ0NhdHMgZm91bmQnLCBkYXRhOiBjYXRzIH0pO1xuICogICAgICAgICB9XG4gKiAgICAgfSk7XG4gKiB9KTtcbiAqL1xuZnVuY3Rpb24gc2VxKC4uLmZ1bmN0aW9ucykge1xuICAgIHZhciBfZnVuY3Rpb25zID0gZnVuY3Rpb25zLm1hcCh3cmFwQXN5bmMpO1xuICAgIHJldHVybiBmdW5jdGlvbiAoLi4uYXJncykge1xuICAgICAgICB2YXIgdGhhdCA9IHRoaXM7XG5cbiAgICAgICAgdmFyIGNiID0gYXJnc1thcmdzLmxlbmd0aCAtIDFdO1xuICAgICAgICBpZiAodHlwZW9mIGNiID09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIGFyZ3MucG9wKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjYiA9IHByb21pc2VDYWxsYmFjaygpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVkdWNlJDEoX2Z1bmN0aW9ucywgYXJncywgKG5ld2FyZ3MsIGZuLCBpdGVyQ2IpID0+IHtcbiAgICAgICAgICAgIGZuLmFwcGx5KHRoYXQsIG5ld2FyZ3MuY29uY2F0KChlcnIsIC4uLm5leHRhcmdzKSA9PiB7XG4gICAgICAgICAgICAgICAgaXRlckNiKGVyciwgbmV4dGFyZ3MpO1xuICAgICAgICAgICAgfSkpO1xuICAgICAgICB9LFxuICAgICAgICAoZXJyLCByZXN1bHRzKSA9PiBjYihlcnIsIC4uLnJlc3VsdHMpKTtcblxuICAgICAgICByZXR1cm4gY2JbUFJPTUlTRV9TWU1CT0xdXG4gICAgfTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgZnVuY3Rpb24gd2hpY2ggaXMgYSBjb21wb3NpdGlvbiBvZiB0aGUgcGFzc2VkIGFzeW5jaHJvbm91c1xuICogZnVuY3Rpb25zLiBFYWNoIGZ1bmN0aW9uIGNvbnN1bWVzIHRoZSByZXR1cm4gdmFsdWUgb2YgdGhlIGZ1bmN0aW9uIHRoYXRcbiAqIGZvbGxvd3MuIENvbXBvc2luZyBmdW5jdGlvbnMgYGYoKWAsIGBnKClgLCBhbmQgYGgoKWAgd291bGQgcHJvZHVjZSB0aGUgcmVzdWx0XG4gKiBvZiBgZihnKGgoKSkpYCwgb25seSB0aGlzIHZlcnNpb24gdXNlcyBjYWxsYmFja3MgdG8gb2J0YWluIHRoZSByZXR1cm4gdmFsdWVzLlxuICpcbiAqIElmIHRoZSBsYXN0IGFyZ3VtZW50IHRvIHRoZSBjb21wb3NlZCBmdW5jdGlvbiBpcyBub3QgYSBmdW5jdGlvbiwgYSBwcm9taXNlXG4gKiBpcyByZXR1cm5lZCB3aGVuIHlvdSBjYWxsIGl0LlxuICpcbiAqIEVhY2ggZnVuY3Rpb24gaXMgZXhlY3V0ZWQgd2l0aCB0aGUgYHRoaXNgIGJpbmRpbmcgb2YgdGhlIGNvbXBvc2VkIGZ1bmN0aW9uLlxuICpcbiAqIEBuYW1lIGNvbXBvc2VcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29udHJvbEZsb3dcbiAqIEBtZXRob2RcbiAqIEBjYXRlZ29yeSBDb250cm9sIEZsb3dcbiAqIEBwYXJhbSB7Li4uQXN5bmNGdW5jdGlvbn0gZnVuY3Rpb25zIC0gdGhlIGFzeW5jaHJvbm91cyBmdW5jdGlvbnMgdG8gY29tcG9zZVxuICogQHJldHVybnMge0Z1bmN0aW9ufSBhbiBhc3luY2hyb25vdXMgZnVuY3Rpb24gdGhhdCBpcyB0aGUgY29tcG9zZWRcbiAqIGFzeW5jaHJvbm91cyBgZnVuY3Rpb25zYFxuICogQGV4YW1wbGVcbiAqXG4gKiBmdW5jdGlvbiBhZGQxKG4sIGNhbGxiYWNrKSB7XG4gKiAgICAgc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gKiAgICAgICAgIGNhbGxiYWNrKG51bGwsIG4gKyAxKTtcbiAqICAgICB9LCAxMCk7XG4gKiB9XG4gKlxuICogZnVuY3Rpb24gbXVsMyhuLCBjYWxsYmFjaykge1xuICogICAgIHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xuICogICAgICAgICBjYWxsYmFjayhudWxsLCBuICogMyk7XG4gKiAgICAgfSwgMTApO1xuICogfVxuICpcbiAqIHZhciBhZGQxbXVsMyA9IGFzeW5jLmNvbXBvc2UobXVsMywgYWRkMSk7XG4gKiBhZGQxbXVsMyg0LCBmdW5jdGlvbiAoZXJyLCByZXN1bHQpIHtcbiAqICAgICAvLyByZXN1bHQgbm93IGVxdWFscyAxNVxuICogfSk7XG4gKi9cbmZ1bmN0aW9uIGNvbXBvc2UoLi4uYXJncykge1xuICAgIHJldHVybiBzZXEoLi4uYXJncy5yZXZlcnNlKCkpO1xufVxuXG4vKipcbiAqIFRoZSBzYW1lIGFzIFtgbWFwYF17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLm1hcH0gYnV0IHJ1bnMgYSBtYXhpbXVtIG9mIGBsaW1pdGAgYXN5bmMgb3BlcmF0aW9ucyBhdCBhIHRpbWUuXG4gKlxuICogQG5hbWUgbWFwTGltaXRcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29sbGVjdGlvbnNcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLm1hcF17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLm1hcH1cbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fEl0ZXJhYmxlfEFzeW5jSXRlcmFibGV8T2JqZWN0fSBjb2xsIC0gQSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7bnVtYmVyfSBsaW1pdCAtIFRoZSBtYXhpbXVtIG51bWJlciBvZiBhc3luYyBvcGVyYXRpb25zIGF0IGEgdGltZS5cbiAqIEBwYXJhbSB7QXN5bmNGdW5jdGlvbn0gaXRlcmF0ZWUgLSBBbiBhc3luYyBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIGl0ZW0gaW5cbiAqIGBjb2xsYC5cbiAqIFRoZSBpdGVyYXRlZSBzaG91bGQgY29tcGxldGUgd2l0aCB0aGUgdHJhbnNmb3JtZWQgaXRlbS5cbiAqIEludm9rZWQgd2l0aCAoaXRlbSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIHdoZW4gYWxsIGBpdGVyYXRlZWBcbiAqIGZ1bmN0aW9ucyBoYXZlIGZpbmlzaGVkLCBvciBhbiBlcnJvciBvY2N1cnMuIFJlc3VsdHMgaXMgYW4gYXJyYXkgb2YgdGhlXG4gKiB0cmFuc2Zvcm1lZCBpdGVtcyBmcm9tIHRoZSBgY29sbGAuIEludm9rZWQgd2l0aCAoZXJyLCByZXN1bHRzKS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIG5vIGNhbGxiYWNrIGlzIHBhc3NlZFxuICovXG5mdW5jdGlvbiBtYXBMaW1pdCAoY29sbCwgbGltaXQsIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBfYXN5bmNNYXAoZWFjaE9mTGltaXQkMihsaW1pdCksIGNvbGwsIGl0ZXJhdGVlLCBjYWxsYmFjaylcbn1cbnZhciBtYXBMaW1pdCQxID0gYXdhaXRpZnkobWFwTGltaXQsIDQpO1xuXG4vKipcbiAqIFRoZSBzYW1lIGFzIFtgY29uY2F0YF17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLmNvbmNhdH0gYnV0IHJ1bnMgYSBtYXhpbXVtIG9mIGBsaW1pdGAgYXN5bmMgb3BlcmF0aW9ucyBhdCBhIHRpbWUuXG4gKlxuICogQG5hbWUgY29uY2F0TGltaXRcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29sbGVjdGlvbnNcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLmNvbmNhdF17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLmNvbmNhdH1cbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAYWxpYXMgZmxhdE1hcExpbWl0XG4gKiBAcGFyYW0ge0FycmF5fEl0ZXJhYmxlfEFzeW5jSXRlcmFibGV8T2JqZWN0fSBjb2xsIC0gQSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7bnVtYmVyfSBsaW1pdCAtIFRoZSBtYXhpbXVtIG51bWJlciBvZiBhc3luYyBvcGVyYXRpb25zIGF0IGEgdGltZS5cbiAqIEBwYXJhbSB7QXN5bmNGdW5jdGlvbn0gaXRlcmF0ZWUgLSBBIGZ1bmN0aW9uIHRvIGFwcGx5IHRvIGVhY2ggaXRlbSBpbiBgY29sbGAsXG4gKiB3aGljaCBzaG91bGQgdXNlIGFuIGFycmF5IGFzIGl0cyByZXN1bHQuIEludm9rZWQgd2l0aCAoaXRlbSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIGFmdGVyIGFsbCB0aGVcbiAqIGBpdGVyYXRlZWAgZnVuY3Rpb25zIGhhdmUgZmluaXNoZWQsIG9yIGFuIGVycm9yIG9jY3Vycy4gUmVzdWx0cyBpcyBhbiBhcnJheVxuICogY29udGFpbmluZyB0aGUgY29uY2F0ZW5hdGVkIHJlc3VsdHMgb2YgdGhlIGBpdGVyYXRlZWAgZnVuY3Rpb24uIEludm9rZWQgd2l0aFxuICogKGVyciwgcmVzdWx0cykuXG4gKiBAcmV0dXJucyBBIFByb21pc2UsIGlmIG5vIGNhbGxiYWNrIGlzIHBhc3NlZFxuICovXG5mdW5jdGlvbiBjb25jYXRMaW1pdChjb2xsLCBsaW1pdCwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgdmFyIF9pdGVyYXRlZSA9IHdyYXBBc3luYyhpdGVyYXRlZSk7XG4gICAgcmV0dXJuIG1hcExpbWl0JDEoY29sbCwgbGltaXQsICh2YWwsIGl0ZXJDYikgPT4ge1xuICAgICAgICBfaXRlcmF0ZWUodmFsLCAoZXJyLCAuLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICBpZiAoZXJyKSByZXR1cm4gaXRlckNiKGVycik7XG4gICAgICAgICAgICByZXR1cm4gaXRlckNiKGVyciwgYXJncyk7XG4gICAgICAgIH0pO1xuICAgIH0sIChlcnIsIG1hcFJlc3VsdHMpID0+IHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1hcFJlc3VsdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIGlmIChtYXBSZXN1bHRzW2ldKSB7XG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0LmNvbmNhdCguLi5tYXBSZXN1bHRzW2ldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIsIHJlc3VsdCk7XG4gICAgfSk7XG59XG52YXIgY29uY2F0TGltaXQkMSA9IGF3YWl0aWZ5KGNvbmNhdExpbWl0LCA0KTtcblxuLyoqXG4gKiBBcHBsaWVzIGBpdGVyYXRlZWAgdG8gZWFjaCBpdGVtIGluIGBjb2xsYCwgY29uY2F0ZW5hdGluZyB0aGUgcmVzdWx0cy4gUmV0dXJuc1xuICogdGhlIGNvbmNhdGVuYXRlZCBsaXN0LiBUaGUgYGl0ZXJhdGVlYHMgYXJlIGNhbGxlZCBpbiBwYXJhbGxlbCwgYW5kIHRoZVxuICogcmVzdWx0cyBhcmUgY29uY2F0ZW5hdGVkIGFzIHRoZXkgcmV0dXJuLiBUaGUgcmVzdWx0cyBhcnJheSB3aWxsIGJlIHJldHVybmVkIGluXG4gKiB0aGUgb3JpZ2luYWwgb3JkZXIgb2YgYGNvbGxgIHBhc3NlZCB0byB0aGUgYGl0ZXJhdGVlYCBmdW5jdGlvbi5cbiAqXG4gKiBAbmFtZSBjb25jYXRcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29sbGVjdGlvbnNcbiAqIEBtZXRob2RcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAYWxpYXMgZmxhdE1hcFxuICogQHBhcmFtIHtBcnJheXxJdGVyYWJsZXxBc3luY0l0ZXJhYmxlfE9iamVjdH0gY29sbCAtIEEgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IGl0ZXJhdGVlIC0gQSBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIGl0ZW0gaW4gYGNvbGxgLFxuICogd2hpY2ggc2hvdWxkIHVzZSBhbiBhcnJheSBhcyBpdHMgcmVzdWx0LiBJbnZva2VkIHdpdGggKGl0ZW0sIGNhbGxiYWNrKS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYWxsYmFja10gLSBBIGNhbGxiYWNrIHdoaWNoIGlzIGNhbGxlZCBhZnRlciBhbGwgdGhlXG4gKiBgaXRlcmF0ZWVgIGZ1bmN0aW9ucyBoYXZlIGZpbmlzaGVkLCBvciBhbiBlcnJvciBvY2N1cnMuIFJlc3VsdHMgaXMgYW4gYXJyYXlcbiAqIGNvbnRhaW5pbmcgdGhlIGNvbmNhdGVuYXRlZCByZXN1bHRzIG9mIHRoZSBgaXRlcmF0ZWVgIGZ1bmN0aW9uLiBJbnZva2VkIHdpdGhcbiAqIChlcnIsIHJlc3VsdHMpLlxuICogQHJldHVybnMgQSBQcm9taXNlLCBpZiBubyBjYWxsYmFjayBpcyBwYXNzZWRcbiAqIEBleGFtcGxlXG4gKlxuICogLy8gZGlyMSBpcyBhIGRpcmVjdG9yeSB0aGF0IGNvbnRhaW5zIGZpbGUxLnR4dCwgZmlsZTIudHh0XG4gKiAvLyBkaXIyIGlzIGEgZGlyZWN0b3J5IHRoYXQgY29udGFpbnMgZmlsZTMudHh0LCBmaWxlNC50eHRcbiAqIC8vIGRpcjMgaXMgYSBkaXJlY3RvcnkgdGhhdCBjb250YWlucyBmaWxlNS50eHRcbiAqIC8vIGRpcjQgZG9lcyBub3QgZXhpc3RcbiAqXG4gKiBsZXQgZGlyZWN0b3J5TGlzdCA9IFsnZGlyMScsJ2RpcjInLCdkaXIzJ107XG4gKiBsZXQgd2l0aE1pc3NpbmdEaXJlY3RvcnlMaXN0ID0gWydkaXIxJywnZGlyMicsJ2RpcjMnLCAnZGlyNCddO1xuICpcbiAqIC8vIFVzaW5nIGNhbGxiYWNrc1xuICogYXN5bmMuY29uY2F0KGRpcmVjdG9yeUxpc3QsIGZzLnJlYWRkaXIsIGZ1bmN0aW9uKGVyciwgcmVzdWx0cykge1xuICogICAgaWYgKGVycikge1xuICogICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiAgICB9IGVsc2Uge1xuICogICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdHMpO1xuICogICAgICAgIC8vIFsgJ2ZpbGUxLnR4dCcsICdmaWxlMi50eHQnLCAnZmlsZTMudHh0JywgJ2ZpbGU0LnR4dCcsIGZpbGU1LnR4dCBdXG4gKiAgICB9XG4gKiB9KTtcbiAqXG4gKiAvLyBFcnJvciBIYW5kbGluZ1xuICogYXN5bmMuY29uY2F0KHdpdGhNaXNzaW5nRGlyZWN0b3J5TGlzdCwgZnMucmVhZGRpciwgZnVuY3Rpb24oZXJyLCByZXN1bHRzKSB7XG4gKiAgICBpZiAoZXJyKSB7XG4gKiAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICAgICAvLyBbIEVycm9yOiBFTk9FTlQ6IG5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkgXVxuICogICAgICAgIC8vIHNpbmNlIGRpcjQgZG9lcyBub3QgZXhpc3RcbiAqICAgIH0gZWxzZSB7XG4gKiAgICAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiAgICB9XG4gKiB9KTtcbiAqXG4gKiAvLyBVc2luZyBQcm9taXNlc1xuICogYXN5bmMuY29uY2F0KGRpcmVjdG9yeUxpc3QsIGZzLnJlYWRkaXIpXG4gKiAudGhlbihyZXN1bHRzID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhyZXN1bHRzKTtcbiAqICAgICAvLyBbICdmaWxlMS50eHQnLCAnZmlsZTIudHh0JywgJ2ZpbGUzLnR4dCcsICdmaWxlNC50eHQnLCBmaWxlNS50eHQgXVxuICogfSkuY2F0Y2goZXJyID0+IHtcbiAqICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqIH0pO1xuICpcbiAqIC8vIEVycm9yIEhhbmRsaW5nXG4gKiBhc3luYy5jb25jYXQod2l0aE1pc3NpbmdEaXJlY3RvcnlMaXN0LCBmcy5yZWFkZGlyKVxuICogLnRoZW4ocmVzdWx0cyA9PiB7XG4gKiAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiB9KS5jYXRjaChlcnIgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiAgICAgLy8gWyBFcnJvcjogRU5PRU5UOiBubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5IF1cbiAqICAgICAvLyBzaW5jZSBkaXI0IGRvZXMgbm90IGV4aXN0XG4gKiB9KTtcbiAqXG4gKiAvLyBVc2luZyBhc3luYy9hd2FpdFxuICogYXN5bmMgKCkgPT4ge1xuICogICAgIHRyeSB7XG4gKiAgICAgICAgIGxldCByZXN1bHRzID0gYXdhaXQgYXN5bmMuY29uY2F0KGRpcmVjdG9yeUxpc3QsIGZzLnJlYWRkaXIpO1xuICogICAgICAgICBjb25zb2xlLmxvZyhyZXN1bHRzKTtcbiAqICAgICAgICAgLy8gWyAnZmlsZTEudHh0JywgJ2ZpbGUyLnR4dCcsICdmaWxlMy50eHQnLCAnZmlsZTQudHh0JywgZmlsZTUudHh0IF1cbiAqICAgICB9IGNhdGNoIChlcnIpIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICB9XG4gKiB9XG4gKlxuICogLy8gRXJyb3IgSGFuZGxpbmdcbiAqIGFzeW5jICgpID0+IHtcbiAqICAgICB0cnkge1xuICogICAgICAgICBsZXQgcmVzdWx0cyA9IGF3YWl0IGFzeW5jLmNvbmNhdCh3aXRoTWlzc2luZ0RpcmVjdG9yeUxpc3QsIGZzLnJlYWRkaXIpO1xuICogICAgICAgICBjb25zb2xlLmxvZyhyZXN1bHRzKTtcbiAqICAgICB9IGNhdGNoIChlcnIpIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICAgICAgLy8gWyBFcnJvcjogRU5PRU5UOiBubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5IF1cbiAqICAgICAgICAgLy8gc2luY2UgZGlyNCBkb2VzIG5vdCBleGlzdFxuICogICAgIH1cbiAqIH1cbiAqXG4gKi9cbmZ1bmN0aW9uIGNvbmNhdChjb2xsLCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gY29uY2F0TGltaXQkMShjb2xsLCBJbmZpbml0eSwgaXRlcmF0ZWUsIGNhbGxiYWNrKVxufVxudmFyIGNvbmNhdCQxID0gYXdhaXRpZnkoY29uY2F0LCAzKTtcblxuLyoqXG4gKiBUaGUgc2FtZSBhcyBbYGNvbmNhdGBde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5jb25jYXR9IGJ1dCBydW5zIG9ubHkgYSBzaW5nbGUgYXN5bmMgb3BlcmF0aW9uIGF0IGEgdGltZS5cbiAqXG4gKiBAbmFtZSBjb25jYXRTZXJpZXNcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29sbGVjdGlvbnNcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLmNvbmNhdF17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLmNvbmNhdH1cbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAYWxpYXMgZmxhdE1hcFNlcmllc1xuICogQHBhcmFtIHtBcnJheXxJdGVyYWJsZXxBc3luY0l0ZXJhYmxlfE9iamVjdH0gY29sbCAtIEEgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IGl0ZXJhdGVlIC0gQSBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIGl0ZW0gaW4gYGNvbGxgLlxuICogVGhlIGl0ZXJhdGVlIHNob3VsZCBjb21wbGV0ZSB3aXRoIGFuIGFycmF5IGFuIGFycmF5IG9mIHJlc3VsdHMuXG4gKiBJbnZva2VkIHdpdGggKGl0ZW0sIGNhbGxiYWNrKS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYWxsYmFja10gLSBBIGNhbGxiYWNrIHdoaWNoIGlzIGNhbGxlZCBhZnRlciBhbGwgdGhlXG4gKiBgaXRlcmF0ZWVgIGZ1bmN0aW9ucyBoYXZlIGZpbmlzaGVkLCBvciBhbiBlcnJvciBvY2N1cnMuIFJlc3VsdHMgaXMgYW4gYXJyYXlcbiAqIGNvbnRhaW5pbmcgdGhlIGNvbmNhdGVuYXRlZCByZXN1bHRzIG9mIHRoZSBgaXRlcmF0ZWVgIGZ1bmN0aW9uLiBJbnZva2VkIHdpdGhcbiAqIChlcnIsIHJlc3VsdHMpLlxuICogQHJldHVybnMgQSBQcm9taXNlLCBpZiBubyBjYWxsYmFjayBpcyBwYXNzZWRcbiAqL1xuZnVuY3Rpb24gY29uY2F0U2VyaWVzKGNvbGwsIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBjb25jYXRMaW1pdCQxKGNvbGwsIDEsIGl0ZXJhdGVlLCBjYWxsYmFjaylcbn1cbnZhciBjb25jYXRTZXJpZXMkMSA9IGF3YWl0aWZ5KGNvbmNhdFNlcmllcywgMyk7XG5cbi8qKlxuICogUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgd2hlbiBjYWxsZWQsIGNhbGxzLWJhY2sgd2l0aCB0aGUgdmFsdWVzIHByb3ZpZGVkLlxuICogVXNlZnVsIGFzIHRoZSBmaXJzdCBmdW5jdGlvbiBpbiBhIFtgd2F0ZXJmYWxsYF17QGxpbmsgbW9kdWxlOkNvbnRyb2xGbG93LndhdGVyZmFsbH0sIG9yIGZvciBwbHVnZ2luZyB2YWx1ZXMgaW4gdG9cbiAqIFtgYXV0b2Bde0BsaW5rIG1vZHVsZTpDb250cm9sRmxvdy5hdXRvfS5cbiAqXG4gKiBAbmFtZSBjb25zdGFudFxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpVdGlsc1xuICogQG1ldGhvZFxuICogQGNhdGVnb3J5IFV0aWxcbiAqIEBwYXJhbSB7Li4uKn0gYXJndW1lbnRzLi4uIC0gQW55IG51bWJlciBvZiBhcmd1bWVudHMgdG8gYXV0b21hdGljYWxseSBpbnZva2VcbiAqIGNhbGxiYWNrIHdpdGguXG4gKiBAcmV0dXJucyB7QXN5bmNGdW5jdGlvbn0gUmV0dXJucyBhIGZ1bmN0aW9uIHRoYXQgd2hlbiBpbnZva2VkLCBhdXRvbWF0aWNhbGx5XG4gKiBpbnZva2VzIHRoZSBjYWxsYmFjayB3aXRoIHRoZSBwcmV2aW91cyBnaXZlbiBhcmd1bWVudHMuXG4gKiBAZXhhbXBsZVxuICpcbiAqIGFzeW5jLndhdGVyZmFsbChbXG4gKiAgICAgYXN5bmMuY29uc3RhbnQoNDIpLFxuICogICAgIGZ1bmN0aW9uICh2YWx1ZSwgbmV4dCkge1xuICogICAgICAgICAvLyB2YWx1ZSA9PT0gNDJcbiAqICAgICB9LFxuICogICAgIC8vLi4uXG4gKiBdLCBjYWxsYmFjayk7XG4gKlxuICogYXN5bmMud2F0ZXJmYWxsKFtcbiAqICAgICBhc3luYy5jb25zdGFudChmaWxlbmFtZSwgXCJ1dGY4XCIpLFxuICogICAgIGZzLnJlYWRGaWxlLFxuICogICAgIGZ1bmN0aW9uIChmaWxlRGF0YSwgbmV4dCkge1xuICogICAgICAgICAvLy4uLlxuICogICAgIH1cbiAqICAgICAvLy4uLlxuICogXSwgY2FsbGJhY2spO1xuICpcbiAqIGFzeW5jLmF1dG8oe1xuICogICAgIGhvc3RuYW1lOiBhc3luYy5jb25zdGFudChcImh0dHBzOi8vc2VydmVyLm5ldC9cIiksXG4gKiAgICAgcG9ydDogZmluZEZyZWVQb3J0LFxuICogICAgIGxhdW5jaFNlcnZlcjogW1wiaG9zdG5hbWVcIiwgXCJwb3J0XCIsIGZ1bmN0aW9uIChvcHRpb25zLCBjYikge1xuICogICAgICAgICBzdGFydFNlcnZlcihvcHRpb25zLCBjYik7XG4gKiAgICAgfV0sXG4gKiAgICAgLy8uLi5cbiAqIH0sIGNhbGxiYWNrKTtcbiAqL1xuZnVuY3Rpb24gY29uc3RhbnQkMSguLi5hcmdzKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uICguLi5pZ25vcmVkQXJncy8qLCBjYWxsYmFjayovKSB7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGlnbm9yZWRBcmdzLnBvcCgpO1xuICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwgLi4uYXJncyk7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gX2NyZWF0ZVRlc3RlcihjaGVjaywgZ2V0UmVzdWx0KSB7XG4gICAgcmV0dXJuIChlYWNoZm4sIGFyciwgX2l0ZXJhdGVlLCBjYikgPT4ge1xuICAgICAgICB2YXIgdGVzdFBhc3NlZCA9IGZhbHNlO1xuICAgICAgICB2YXIgdGVzdFJlc3VsdDtcbiAgICAgICAgY29uc3QgaXRlcmF0ZWUgPSB3cmFwQXN5bmMoX2l0ZXJhdGVlKTtcbiAgICAgICAgZWFjaGZuKGFyciwgKHZhbHVlLCBfLCBjYWxsYmFjaykgPT4ge1xuICAgICAgICAgICAgaXRlcmF0ZWUodmFsdWUsIChlcnIsIHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChlcnIgfHwgZXJyID09PSBmYWxzZSkgcmV0dXJuIGNhbGxiYWNrKGVycik7XG5cbiAgICAgICAgICAgICAgICBpZiAoY2hlY2socmVzdWx0KSAmJiAhdGVzdFJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICB0ZXN0UGFzc2VkID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgdGVzdFJlc3VsdCA9IGdldFJlc3VsdCh0cnVlLCB2YWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBicmVha0xvb3ApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0sIGVyciA9PiB7XG4gICAgICAgICAgICBpZiAoZXJyKSByZXR1cm4gY2IoZXJyKTtcbiAgICAgICAgICAgIGNiKG51bGwsIHRlc3RQYXNzZWQgPyB0ZXN0UmVzdWx0IDogZ2V0UmVzdWx0KGZhbHNlKSk7XG4gICAgICAgIH0pO1xuICAgIH07XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgZmlyc3QgdmFsdWUgaW4gYGNvbGxgIHRoYXQgcGFzc2VzIGFuIGFzeW5jIHRydXRoIHRlc3QuIFRoZVxuICogYGl0ZXJhdGVlYCBpcyBhcHBsaWVkIGluIHBhcmFsbGVsLCBtZWFuaW5nIHRoZSBmaXJzdCBpdGVyYXRlZSB0byByZXR1cm5cbiAqIGB0cnVlYCB3aWxsIGZpcmUgdGhlIGRldGVjdCBgY2FsbGJhY2tgIHdpdGggdGhhdCByZXN1bHQuIFRoYXQgbWVhbnMgdGhlXG4gKiByZXN1bHQgbWlnaHQgbm90IGJlIHRoZSBmaXJzdCBpdGVtIGluIHRoZSBvcmlnaW5hbCBgY29sbGAgKGluIHRlcm1zIG9mIG9yZGVyKVxuICogdGhhdCBwYXNzZXMgdGhlIHRlc3QuXG5cbiAqIElmIG9yZGVyIHdpdGhpbiB0aGUgb3JpZ2luYWwgYGNvbGxgIGlzIGltcG9ydGFudCwgdGhlbiBsb29rIGF0XG4gKiBbYGRldGVjdFNlcmllc2Bde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5kZXRlY3RTZXJpZXN9LlxuICpcbiAqIEBuYW1lIGRldGVjdFxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb2xsZWN0aW9uc1xuICogQG1ldGhvZFxuICogQGFsaWFzIGZpbmRcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uc1xuICogQHBhcmFtIHtBcnJheXxJdGVyYWJsZXxBc3luY0l0ZXJhYmxlfE9iamVjdH0gY29sbCAtIEEgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IGl0ZXJhdGVlIC0gQSB0cnV0aCB0ZXN0IHRvIGFwcGx5IHRvIGVhY2ggaXRlbSBpbiBgY29sbGAuXG4gKiBUaGUgaXRlcmF0ZWUgbXVzdCBjb21wbGV0ZSB3aXRoIGEgYm9vbGVhbiB2YWx1ZSBhcyBpdHMgcmVzdWx0LlxuICogSW52b2tlZCB3aXRoIChpdGVtLCBjYWxsYmFjaykuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdIC0gQSBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgYXMgc29vbiBhcyBhbnlcbiAqIGl0ZXJhdGVlIHJldHVybnMgYHRydWVgLCBvciBhZnRlciBhbGwgdGhlIGBpdGVyYXRlZWAgZnVuY3Rpb25zIGhhdmUgZmluaXNoZWQuXG4gKiBSZXN1bHQgd2lsbCBiZSB0aGUgZmlyc3QgaXRlbSBpbiB0aGUgYXJyYXkgdGhhdCBwYXNzZXMgdGhlIHRydXRoIHRlc3RcbiAqIChpdGVyYXRlZSkgb3IgdGhlIHZhbHVlIGB1bmRlZmluZWRgIGlmIG5vbmUgcGFzc2VkLiBJbnZva2VkIHdpdGhcbiAqIChlcnIsIHJlc3VsdCkuXG4gKiBAcmV0dXJucyB7UHJvbWlzZX0gYSBwcm9taXNlLCBpZiBhIGNhbGxiYWNrIGlzIG9taXR0ZWRcbiAqIEBleGFtcGxlXG4gKlxuICogLy8gZGlyMSBpcyBhIGRpcmVjdG9yeSB0aGF0IGNvbnRhaW5zIGZpbGUxLnR4dCwgZmlsZTIudHh0XG4gKiAvLyBkaXIyIGlzIGEgZGlyZWN0b3J5IHRoYXQgY29udGFpbnMgZmlsZTMudHh0LCBmaWxlNC50eHRcbiAqIC8vIGRpcjMgaXMgYSBkaXJlY3RvcnkgdGhhdCBjb250YWlucyBmaWxlNS50eHRcbiAqXG4gKiAvLyBhc3luY2hyb25vdXMgZnVuY3Rpb24gdGhhdCBjaGVja3MgaWYgYSBmaWxlIGV4aXN0c1xuICogZnVuY3Rpb24gZmlsZUV4aXN0cyhmaWxlLCBjYWxsYmFjaykge1xuICogICAgZnMuYWNjZXNzKGZpbGUsIGZzLmNvbnN0YW50cy5GX09LLCAoZXJyKSA9PiB7XG4gKiAgICAgICAgY2FsbGJhY2sobnVsbCwgIWVycik7XG4gKiAgICB9KTtcbiAqIH1cbiAqXG4gKiBhc3luYy5kZXRlY3QoWydmaWxlMy50eHQnLCdmaWxlMi50eHQnLCdkaXIxL2ZpbGUxLnR4dCddLCBmaWxlRXhpc3RzLFxuICogICAgZnVuY3Rpb24oZXJyLCByZXN1bHQpIHtcbiAqICAgICAgICBjb25zb2xlLmxvZyhyZXN1bHQpO1xuICogICAgICAgIC8vIGRpcjEvZmlsZTEudHh0XG4gKiAgICAgICAgLy8gcmVzdWx0IG5vdyBlcXVhbHMgdGhlIGZpcnN0IGZpbGUgaW4gdGhlIGxpc3QgdGhhdCBleGlzdHNcbiAqICAgIH1cbiAqKTtcbiAqXG4gKiAvLyBVc2luZyBQcm9taXNlc1xuICogYXN5bmMuZGV0ZWN0KFsnZmlsZTMudHh0JywnZmlsZTIudHh0JywnZGlyMS9maWxlMS50eHQnXSwgZmlsZUV4aXN0cylcbiAqIC50aGVuKHJlc3VsdCA9PiB7XG4gKiAgICAgY29uc29sZS5sb2cocmVzdWx0KTtcbiAqICAgICAvLyBkaXIxL2ZpbGUxLnR4dFxuICogICAgIC8vIHJlc3VsdCBub3cgZXF1YWxzIHRoZSBmaXJzdCBmaWxlIGluIHRoZSBsaXN0IHRoYXQgZXhpc3RzXG4gKiB9KS5jYXRjaChlcnIgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiB9KTtcbiAqXG4gKiAvLyBVc2luZyBhc3luYy9hd2FpdFxuICogYXN5bmMgKCkgPT4ge1xuICogICAgIHRyeSB7XG4gKiAgICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCBhc3luYy5kZXRlY3QoWydmaWxlMy50eHQnLCdmaWxlMi50eHQnLCdkaXIxL2ZpbGUxLnR4dCddLCBmaWxlRXhpc3RzKTtcbiAqICAgICAgICAgY29uc29sZS5sb2cocmVzdWx0KTtcbiAqICAgICAgICAgLy8gZGlyMS9maWxlMS50eHRcbiAqICAgICAgICAgLy8gcmVzdWx0IG5vdyBlcXVhbHMgdGhlIGZpbGUgaW4gdGhlIGxpc3QgdGhhdCBleGlzdHNcbiAqICAgICB9XG4gKiAgICAgY2F0Y2ggKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgIH1cbiAqIH1cbiAqXG4gKi9cbmZ1bmN0aW9uIGRldGVjdChjb2xsLCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gX2NyZWF0ZVRlc3Rlcihib29sID0+IGJvb2wsIChyZXMsIGl0ZW0pID0+IGl0ZW0pKGVhY2hPZiQxLCBjb2xsLCBpdGVyYXRlZSwgY2FsbGJhY2spXG59XG52YXIgZGV0ZWN0JDEgPSBhd2FpdGlmeShkZXRlY3QsIDMpO1xuXG4vKipcbiAqIFRoZSBzYW1lIGFzIFtgZGV0ZWN0YF17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLmRldGVjdH0gYnV0IHJ1bnMgYSBtYXhpbXVtIG9mIGBsaW1pdGAgYXN5bmMgb3BlcmF0aW9ucyBhdCBhXG4gKiB0aW1lLlxuICpcbiAqIEBuYW1lIGRldGVjdExpbWl0XG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbGxlY3Rpb25zXG4gKiBAbWV0aG9kXG4gKiBAc2VlIFthc3luYy5kZXRlY3Rde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5kZXRlY3R9XG4gKiBAYWxpYXMgZmluZExpbWl0XG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvbnNcbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IGNvbGwgLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtudW1iZXJ9IGxpbWl0IC0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGFzeW5jIG9wZXJhdGlvbnMgYXQgYSB0aW1lLlxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEEgdHJ1dGggdGVzdCB0byBhcHBseSB0byBlYWNoIGl0ZW0gaW4gYGNvbGxgLlxuICogVGhlIGl0ZXJhdGVlIG11c3QgY29tcGxldGUgd2l0aCBhIGJvb2xlYW4gdmFsdWUgYXMgaXRzIHJlc3VsdC5cbiAqIEludm9rZWQgd2l0aCAoaXRlbSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIGFzIHNvb24gYXMgYW55XG4gKiBpdGVyYXRlZSByZXR1cm5zIGB0cnVlYCwgb3IgYWZ0ZXIgYWxsIHRoZSBgaXRlcmF0ZWVgIGZ1bmN0aW9ucyBoYXZlIGZpbmlzaGVkLlxuICogUmVzdWx0IHdpbGwgYmUgdGhlIGZpcnN0IGl0ZW0gaW4gdGhlIGFycmF5IHRoYXQgcGFzc2VzIHRoZSB0cnV0aCB0ZXN0XG4gKiAoaXRlcmF0ZWUpIG9yIHRoZSB2YWx1ZSBgdW5kZWZpbmVkYCBpZiBub25lIHBhc3NlZC4gSW52b2tlZCB3aXRoXG4gKiAoZXJyLCByZXN1bHQpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgYSBjYWxsYmFjayBpcyBvbWl0dGVkXG4gKi9cbmZ1bmN0aW9uIGRldGVjdExpbWl0KGNvbGwsIGxpbWl0LCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gX2NyZWF0ZVRlc3Rlcihib29sID0+IGJvb2wsIChyZXMsIGl0ZW0pID0+IGl0ZW0pKGVhY2hPZkxpbWl0JDIobGltaXQpLCBjb2xsLCBpdGVyYXRlZSwgY2FsbGJhY2spXG59XG52YXIgZGV0ZWN0TGltaXQkMSA9IGF3YWl0aWZ5KGRldGVjdExpbWl0LCA0KTtcblxuLyoqXG4gKiBUaGUgc2FtZSBhcyBbYGRldGVjdGBde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5kZXRlY3R9IGJ1dCBydW5zIG9ubHkgYSBzaW5nbGUgYXN5bmMgb3BlcmF0aW9uIGF0IGEgdGltZS5cbiAqXG4gKiBAbmFtZSBkZXRlY3RTZXJpZXNcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29sbGVjdGlvbnNcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLmRldGVjdF17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLmRldGVjdH1cbiAqIEBhbGlhcyBmaW5kU2VyaWVzXG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvbnNcbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IGNvbGwgLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEEgdHJ1dGggdGVzdCB0byBhcHBseSB0byBlYWNoIGl0ZW0gaW4gYGNvbGxgLlxuICogVGhlIGl0ZXJhdGVlIG11c3QgY29tcGxldGUgd2l0aCBhIGJvb2xlYW4gdmFsdWUgYXMgaXRzIHJlc3VsdC5cbiAqIEludm9rZWQgd2l0aCAoaXRlbSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIGFzIHNvb24gYXMgYW55XG4gKiBpdGVyYXRlZSByZXR1cm5zIGB0cnVlYCwgb3IgYWZ0ZXIgYWxsIHRoZSBgaXRlcmF0ZWVgIGZ1bmN0aW9ucyBoYXZlIGZpbmlzaGVkLlxuICogUmVzdWx0IHdpbGwgYmUgdGhlIGZpcnN0IGl0ZW0gaW4gdGhlIGFycmF5IHRoYXQgcGFzc2VzIHRoZSB0cnV0aCB0ZXN0XG4gKiAoaXRlcmF0ZWUpIG9yIHRoZSB2YWx1ZSBgdW5kZWZpbmVkYCBpZiBub25lIHBhc3NlZC4gSW52b2tlZCB3aXRoXG4gKiAoZXJyLCByZXN1bHQpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgYSBjYWxsYmFjayBpcyBvbWl0dGVkXG4gKi9cbmZ1bmN0aW9uIGRldGVjdFNlcmllcyhjb2xsLCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gX2NyZWF0ZVRlc3Rlcihib29sID0+IGJvb2wsIChyZXMsIGl0ZW0pID0+IGl0ZW0pKGVhY2hPZkxpbWl0JDIoMSksIGNvbGwsIGl0ZXJhdGVlLCBjYWxsYmFjaylcbn1cblxudmFyIGRldGVjdFNlcmllcyQxID0gYXdhaXRpZnkoZGV0ZWN0U2VyaWVzLCAzKTtcblxuZnVuY3Rpb24gY29uc29sZUZ1bmMobmFtZSkge1xuICAgIHJldHVybiAoZm4sIC4uLmFyZ3MpID0+IHdyYXBBc3luYyhmbikoLi4uYXJncywgKGVyciwgLi4ucmVzdWx0QXJncykgPT4ge1xuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgICBpZiAodHlwZW9mIGNvbnNvbGUgPT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgICAgICAgaWYgKGVycikge1xuICAgICAgICAgICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBlbHNlICovXG4gICAgICAgICAgICAgICAgaWYgKGNvbnNvbGUuZXJyb3IpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS5lcnJvcihlcnIpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY29uc29sZVtuYW1lXSkgeyAvKiBpc3RhbmJ1bCBpZ25vcmUgZWxzZSAqL1xuICAgICAgICAgICAgICAgIHJlc3VsdEFyZ3MuZm9yRWFjaCh4ID0+IGNvbnNvbGVbbmFtZV0oeCkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSlcbn1cblxuLyoqXG4gKiBMb2dzIHRoZSByZXN1bHQgb2YgYW4gW2Bhc3luY2AgZnVuY3Rpb25de0BsaW5rIEFzeW5jRnVuY3Rpb259IHRvIHRoZVxuICogYGNvbnNvbGVgIHVzaW5nIGBjb25zb2xlLmRpcmAgdG8gZGlzcGxheSB0aGUgcHJvcGVydGllcyBvZiB0aGUgcmVzdWx0aW5nIG9iamVjdC5cbiAqIE9ubHkgd29ya3MgaW4gTm9kZS5qcyBvciBpbiBicm93c2VycyB0aGF0IHN1cHBvcnQgYGNvbnNvbGUuZGlyYCBhbmRcbiAqIGBjb25zb2xlLmVycm9yYCAoc3VjaCBhcyBGRiBhbmQgQ2hyb21lKS5cbiAqIElmIG11bHRpcGxlIGFyZ3VtZW50cyBhcmUgcmV0dXJuZWQgZnJvbSB0aGUgYXN5bmMgZnVuY3Rpb24sXG4gKiBgY29uc29sZS5kaXJgIGlzIGNhbGxlZCBvbiBlYWNoIGFyZ3VtZW50IGluIG9yZGVyLlxuICpcbiAqIEBuYW1lIGRpclxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpVdGlsc1xuICogQG1ldGhvZFxuICogQGNhdGVnb3J5IFV0aWxcbiAqIEBwYXJhbSB7QXN5bmNGdW5jdGlvbn0gZnVuY3Rpb24gLSBUaGUgZnVuY3Rpb24geW91IHdhbnQgdG8gZXZlbnR1YWxseSBhcHBseVxuICogYWxsIGFyZ3VtZW50cyB0by5cbiAqIEBwYXJhbSB7Li4uKn0gYXJndW1lbnRzLi4uIC0gQW55IG51bWJlciBvZiBhcmd1bWVudHMgdG8gYXBwbHkgdG8gdGhlIGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBpbiBhIG1vZHVsZVxuICogdmFyIGhlbGxvID0gZnVuY3Rpb24obmFtZSwgY2FsbGJhY2spIHtcbiAqICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICogICAgICAgICBjYWxsYmFjayhudWxsLCB7aGVsbG86IG5hbWV9KTtcbiAqICAgICB9LCAxMDAwKTtcbiAqIH07XG4gKlxuICogLy8gaW4gdGhlIG5vZGUgcmVwbFxuICogbm9kZT4gYXN5bmMuZGlyKGhlbGxvLCAnd29ybGQnKTtcbiAqIHtoZWxsbzogJ3dvcmxkJ31cbiAqL1xudmFyIGRpciA9IGNvbnNvbGVGdW5jKCdkaXInKTtcblxuLyoqXG4gKiBUaGUgcG9zdC1jaGVjayB2ZXJzaW9uIG9mIFtgd2hpbHN0YF17QGxpbmsgbW9kdWxlOkNvbnRyb2xGbG93LndoaWxzdH0uIFRvIHJlZmxlY3QgdGhlIGRpZmZlcmVuY2UgaW5cbiAqIHRoZSBvcmRlciBvZiBvcGVyYXRpb25zLCB0aGUgYXJndW1lbnRzIGB0ZXN0YCBhbmQgYGl0ZXJhdGVlYCBhcmUgc3dpdGNoZWQuXG4gKlxuICogYGRvV2hpbHN0YCBpcyB0byBgd2hpbHN0YCBhcyBgZG8gd2hpbGVgIGlzIHRvIGB3aGlsZWAgaW4gcGxhaW4gSmF2YVNjcmlwdC5cbiAqXG4gKiBAbmFtZSBkb1doaWxzdFxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb250cm9sRmxvd1xuICogQG1ldGhvZFxuICogQHNlZSBbYXN5bmMud2hpbHN0XXtAbGluayBtb2R1bGU6Q29udHJvbEZsb3cud2hpbHN0fVxuICogQGNhdGVnb3J5IENvbnRyb2wgRmxvd1xuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEEgZnVuY3Rpb24gd2hpY2ggaXMgY2FsbGVkIGVhY2ggdGltZSBgdGVzdGBcbiAqIHBhc3Nlcy4gSW52b2tlZCB3aXRoIChjYWxsYmFjaykuXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IHRlc3QgLSBhc3luY2hyb25vdXMgdHJ1dGggdGVzdCB0byBwZXJmb3JtIGFmdGVyIGVhY2hcbiAqIGV4ZWN1dGlvbiBvZiBgaXRlcmF0ZWVgLiBJbnZva2VkIHdpdGggKC4uLmFyZ3MsIGNhbGxiYWNrKSwgd2hlcmUgYC4uLmFyZ3NgIGFyZSB0aGVcbiAqIG5vbi1lcnJvciBhcmdzIGZyb20gdGhlIHByZXZpb3VzIGNhbGxiYWNrIG9mIGBpdGVyYXRlZWAuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdIC0gQSBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgYWZ0ZXIgdGhlIHRlc3RcbiAqIGZ1bmN0aW9uIGhhcyBmYWlsZWQgYW5kIHJlcGVhdGVkIGV4ZWN1dGlvbiBvZiBgaXRlcmF0ZWVgIGhhcyBzdG9wcGVkLlxuICogYGNhbGxiYWNrYCB3aWxsIGJlIHBhc3NlZCBhbiBlcnJvciBhbmQgYW55IGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhlIGZpbmFsXG4gKiBgaXRlcmF0ZWVgJ3MgY2FsbGJhY2suIEludm9rZWQgd2l0aCAoZXJyLCBbcmVzdWx0c10pO1xuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgbm8gY2FsbGJhY2sgaXMgcGFzc2VkXG4gKi9cbmZ1bmN0aW9uIGRvV2hpbHN0KGl0ZXJhdGVlLCB0ZXN0LCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gb25seU9uY2UoY2FsbGJhY2spO1xuICAgIHZhciBfZm4gPSB3cmFwQXN5bmMoaXRlcmF0ZWUpO1xuICAgIHZhciBfdGVzdCA9IHdyYXBBc3luYyh0ZXN0KTtcbiAgICB2YXIgcmVzdWx0cztcblxuICAgIGZ1bmN0aW9uIG5leHQoZXJyLCAuLi5hcmdzKSB7XG4gICAgICAgIGlmIChlcnIpIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgICBpZiAoZXJyID09PSBmYWxzZSkgcmV0dXJuO1xuICAgICAgICByZXN1bHRzID0gYXJncztcbiAgICAgICAgX3Rlc3QoLi4uYXJncywgY2hlY2spO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGNoZWNrKGVyciwgdHJ1dGgpIHtcbiAgICAgICAgaWYgKGVycikgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgIGlmIChlcnIgPT09IGZhbHNlKSByZXR1cm47XG4gICAgICAgIGlmICghdHJ1dGgpIHJldHVybiBjYWxsYmFjayhudWxsLCAuLi5yZXN1bHRzKTtcbiAgICAgICAgX2ZuKG5leHQpO1xuICAgIH1cblxuICAgIHJldHVybiBjaGVjayhudWxsLCB0cnVlKTtcbn1cblxudmFyIGRvV2hpbHN0JDEgPSBhd2FpdGlmeShkb1doaWxzdCwgMyk7XG5cbi8qKlxuICogTGlrZSBbJ2RvV2hpbHN0J117QGxpbmsgbW9kdWxlOkNvbnRyb2xGbG93LmRvV2hpbHN0fSwgZXhjZXB0IHRoZSBgdGVzdGAgaXMgaW52ZXJ0ZWQuIE5vdGUgdGhlXG4gKiBhcmd1bWVudCBvcmRlcmluZyBkaWZmZXJzIGZyb20gYHVudGlsYC5cbiAqXG4gKiBAbmFtZSBkb1VudGlsXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbnRyb2xGbG93XG4gKiBAbWV0aG9kXG4gKiBAc2VlIFthc3luYy5kb1doaWxzdF17QGxpbmsgbW9kdWxlOkNvbnRyb2xGbG93LmRvV2hpbHN0fVxuICogQGNhdGVnb3J5IENvbnRyb2wgRmxvd1xuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEFuIGFzeW5jIGZ1bmN0aW9uIHdoaWNoIGlzIGNhbGxlZCBlYWNoIHRpbWVcbiAqIGB0ZXN0YCBmYWlscy4gSW52b2tlZCB3aXRoIChjYWxsYmFjaykuXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IHRlc3QgLSBhc3luY2hyb25vdXMgdHJ1dGggdGVzdCB0byBwZXJmb3JtIGFmdGVyIGVhY2hcbiAqIGV4ZWN1dGlvbiBvZiBgaXRlcmF0ZWVgLiBJbnZva2VkIHdpdGggKC4uLmFyZ3MsIGNhbGxiYWNrKSwgd2hlcmUgYC4uLmFyZ3NgIGFyZSB0aGVcbiAqIG5vbi1lcnJvciBhcmdzIGZyb20gdGhlIHByZXZpb3VzIGNhbGxiYWNrIG9mIGBpdGVyYXRlZWBcbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYWxsYmFja10gLSBBIGNhbGxiYWNrIHdoaWNoIGlzIGNhbGxlZCBhZnRlciB0aGUgdGVzdFxuICogZnVuY3Rpb24gaGFzIHBhc3NlZCBhbmQgcmVwZWF0ZWQgZXhlY3V0aW9uIG9mIGBpdGVyYXRlZWAgaGFzIHN0b3BwZWQuIGBjYWxsYmFja2BcbiAqIHdpbGwgYmUgcGFzc2VkIGFuIGVycm9yIGFuZCBhbnkgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgZmluYWwgYGl0ZXJhdGVlYCdzXG4gKiBjYWxsYmFjay4gSW52b2tlZCB3aXRoIChlcnIsIFtyZXN1bHRzXSk7XG4gKiBAcmV0dXJucyB7UHJvbWlzZX0gYSBwcm9taXNlLCBpZiBubyBjYWxsYmFjayBpcyBwYXNzZWRcbiAqL1xuZnVuY3Rpb24gZG9VbnRpbChpdGVyYXRlZSwgdGVzdCwgY2FsbGJhY2spIHtcbiAgICBjb25zdCBfdGVzdCA9IHdyYXBBc3luYyh0ZXN0KTtcbiAgICByZXR1cm4gZG9XaGlsc3QkMShpdGVyYXRlZSwgKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgY29uc3QgY2IgPSBhcmdzLnBvcCgpO1xuICAgICAgICBfdGVzdCguLi5hcmdzLCAoZXJyLCB0cnV0aCkgPT4gY2IgKGVyciwgIXRydXRoKSk7XG4gICAgfSwgY2FsbGJhY2spO1xufVxuXG5mdW5jdGlvbiBfd2l0aG91dEluZGV4KGl0ZXJhdGVlKSB7XG4gICAgcmV0dXJuICh2YWx1ZSwgaW5kZXgsIGNhbGxiYWNrKSA9PiBpdGVyYXRlZSh2YWx1ZSwgY2FsbGJhY2spO1xufVxuXG4vKipcbiAqIEFwcGxpZXMgdGhlIGZ1bmN0aW9uIGBpdGVyYXRlZWAgdG8gZWFjaCBpdGVtIGluIGBjb2xsYCwgaW4gcGFyYWxsZWwuXG4gKiBUaGUgYGl0ZXJhdGVlYCBpcyBjYWxsZWQgd2l0aCBhbiBpdGVtIGZyb20gdGhlIGxpc3QsIGFuZCBhIGNhbGxiYWNrIGZvciB3aGVuXG4gKiBpdCBoYXMgZmluaXNoZWQuIElmIHRoZSBgaXRlcmF0ZWVgIHBhc3NlcyBhbiBlcnJvciB0byBpdHMgYGNhbGxiYWNrYCwgdGhlXG4gKiBtYWluIGBjYWxsYmFja2AgKGZvciB0aGUgYGVhY2hgIGZ1bmN0aW9uKSBpcyBpbW1lZGlhdGVseSBjYWxsZWQgd2l0aCB0aGVcbiAqIGVycm9yLlxuICpcbiAqIE5vdGUsIHRoYXQgc2luY2UgdGhpcyBmdW5jdGlvbiBhcHBsaWVzIGBpdGVyYXRlZWAgdG8gZWFjaCBpdGVtIGluIHBhcmFsbGVsLFxuICogdGhlcmUgaXMgbm8gZ3VhcmFudGVlIHRoYXQgdGhlIGl0ZXJhdGVlIGZ1bmN0aW9ucyB3aWxsIGNvbXBsZXRlIGluIG9yZGVyLlxuICpcbiAqIEBuYW1lIGVhY2hcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29sbGVjdGlvbnNcbiAqIEBtZXRob2RcbiAqIEBhbGlhcyBmb3JFYWNoXG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxJdGVyYWJsZXxBc3luY0l0ZXJhYmxlfE9iamVjdH0gY29sbCAtIEEgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IGl0ZXJhdGVlIC0gQW4gYXN5bmMgZnVuY3Rpb24gdG8gYXBwbHkgdG9cbiAqIGVhY2ggaXRlbSBpbiBgY29sbGAuIEludm9rZWQgd2l0aCAoaXRlbSwgY2FsbGJhY2spLlxuICogVGhlIGFycmF5IGluZGV4IGlzIG5vdCBwYXNzZWQgdG8gdGhlIGl0ZXJhdGVlLlxuICogSWYgeW91IG5lZWQgdGhlIGluZGV4LCB1c2UgYGVhY2hPZmAuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdIC0gQSBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgd2hlbiBhbGxcbiAqIGBpdGVyYXRlZWAgZnVuY3Rpb25zIGhhdmUgZmluaXNoZWQsIG9yIGFuIGVycm9yIG9jY3Vycy4gSW52b2tlZCB3aXRoIChlcnIpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgYSBjYWxsYmFjayBpcyBvbWl0dGVkXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIGRpcjEgaXMgYSBkaXJlY3RvcnkgdGhhdCBjb250YWlucyBmaWxlMS50eHQsIGZpbGUyLnR4dFxuICogLy8gZGlyMiBpcyBhIGRpcmVjdG9yeSB0aGF0IGNvbnRhaW5zIGZpbGUzLnR4dCwgZmlsZTQudHh0XG4gKiAvLyBkaXIzIGlzIGEgZGlyZWN0b3J5IHRoYXQgY29udGFpbnMgZmlsZTUudHh0XG4gKiAvLyBkaXI0IGRvZXMgbm90IGV4aXN0XG4gKlxuICogY29uc3QgZmlsZUxpc3QgPSBbICdkaXIxL2ZpbGUyLnR4dCcsICdkaXIyL2ZpbGUzLnR4dCcsICdkaXIvZmlsZTUudHh0J107XG4gKiBjb25zdCB3aXRoTWlzc2luZ0ZpbGVMaXN0ID0gWydkaXIxL2ZpbGUxLnR4dCcsICdkaXI0L2ZpbGUyLnR4dCddO1xuICpcbiAqIC8vIGFzeW5jaHJvbm91cyBmdW5jdGlvbiB0aGF0IGRlbGV0ZXMgYSBmaWxlXG4gKiBjb25zdCBkZWxldGVGaWxlID0gZnVuY3Rpb24oZmlsZSwgY2FsbGJhY2spIHtcbiAqICAgICBmcy51bmxpbmsoZmlsZSwgY2FsbGJhY2spO1xuICogfTtcbiAqXG4gKiAvLyBVc2luZyBjYWxsYmFja3NcbiAqIGFzeW5jLmVhY2goZmlsZUxpc3QsIGRlbGV0ZUZpbGUsIGZ1bmN0aW9uKGVycikge1xuICogICAgIGlmKCBlcnIgKSB7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiAgICAgfSBlbHNlIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coJ0FsbCBmaWxlcyBoYXZlIGJlZW4gZGVsZXRlZCBzdWNjZXNzZnVsbHknKTtcbiAqICAgICB9XG4gKiB9KTtcbiAqXG4gKiAvLyBFcnJvciBIYW5kbGluZ1xuICogYXN5bmMuZWFjaCh3aXRoTWlzc2luZ0ZpbGVMaXN0LCBkZWxldGVGaWxlLCBmdW5jdGlvbihlcnIpe1xuICogICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiAgICAgLy8gWyBFcnJvcjogRU5PRU5UOiBubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5IF1cbiAqICAgICAvLyBzaW5jZSBkaXI0L2ZpbGUyLnR4dCBkb2VzIG5vdCBleGlzdFxuICogICAgIC8vIGRpcjEvZmlsZTEudHh0IGNvdWxkIGhhdmUgYmVlbiBkZWxldGVkXG4gKiB9KTtcbiAqXG4gKiAvLyBVc2luZyBQcm9taXNlc1xuICogYXN5bmMuZWFjaChmaWxlTGlzdCwgZGVsZXRlRmlsZSlcbiAqIC50aGVuKCAoKSA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coJ0FsbCBmaWxlcyBoYXZlIGJlZW4gZGVsZXRlZCBzdWNjZXNzZnVsbHknKTtcbiAqIH0pLmNhdGNoKCBlcnIgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiB9KTtcbiAqXG4gKiAvLyBFcnJvciBIYW5kbGluZ1xuICogYXN5bmMuZWFjaChmaWxlTGlzdCwgZGVsZXRlRmlsZSlcbiAqIC50aGVuKCAoKSA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coJ0FsbCBmaWxlcyBoYXZlIGJlZW4gZGVsZXRlZCBzdWNjZXNzZnVsbHknKTtcbiAqIH0pLmNhdGNoKCBlcnIgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiAgICAgLy8gWyBFcnJvcjogRU5PRU5UOiBubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5IF1cbiAqICAgICAvLyBzaW5jZSBkaXI0L2ZpbGUyLnR4dCBkb2VzIG5vdCBleGlzdFxuICogICAgIC8vIGRpcjEvZmlsZTEudHh0IGNvdWxkIGhhdmUgYmVlbiBkZWxldGVkXG4gKiB9KTtcbiAqXG4gKiAvLyBVc2luZyBhc3luYy9hd2FpdFxuICogYXN5bmMgKCkgPT4ge1xuICogICAgIHRyeSB7XG4gKiAgICAgICAgIGF3YWl0IGFzeW5jLmVhY2goZmlsZXMsIGRlbGV0ZUZpbGUpO1xuICogICAgIH1cbiAqICAgICBjYXRjaCAoZXJyKSB7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiAgICAgfVxuICogfVxuICpcbiAqIC8vIEVycm9yIEhhbmRsaW5nXG4gKiBhc3luYyAoKSA9PiB7XG4gKiAgICAgdHJ5IHtcbiAqICAgICAgICAgYXdhaXQgYXN5bmMuZWFjaCh3aXRoTWlzc2luZ0ZpbGVMaXN0LCBkZWxldGVGaWxlKTtcbiAqICAgICB9XG4gKiAgICAgY2F0Y2ggKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgICAgICAvLyBbIEVycm9yOiBFTk9FTlQ6IG5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkgXVxuICogICAgICAgICAvLyBzaW5jZSBkaXI0L2ZpbGUyLnR4dCBkb2VzIG5vdCBleGlzdFxuICogICAgICAgICAvLyBkaXIxL2ZpbGUxLnR4dCBjb3VsZCBoYXZlIGJlZW4gZGVsZXRlZFxuICogICAgIH1cbiAqIH1cbiAqXG4gKi9cbmZ1bmN0aW9uIGVhY2hMaW1pdCQyKGNvbGwsIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBlYWNoT2YkMShjb2xsLCBfd2l0aG91dEluZGV4KHdyYXBBc3luYyhpdGVyYXRlZSkpLCBjYWxsYmFjayk7XG59XG5cbnZhciBlYWNoID0gYXdhaXRpZnkoZWFjaExpbWl0JDIsIDMpO1xuXG4vKipcbiAqIFRoZSBzYW1lIGFzIFtgZWFjaGBde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5lYWNofSBidXQgcnVucyBhIG1heGltdW0gb2YgYGxpbWl0YCBhc3luYyBvcGVyYXRpb25zIGF0IGEgdGltZS5cbiAqXG4gKiBAbmFtZSBlYWNoTGltaXRcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29sbGVjdGlvbnNcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLmVhY2hde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5lYWNofVxuICogQGFsaWFzIGZvckVhY2hMaW1pdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IGNvbGwgLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtudW1iZXJ9IGxpbWl0IC0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGFzeW5jIG9wZXJhdGlvbnMgYXQgYSB0aW1lLlxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEFuIGFzeW5jIGZ1bmN0aW9uIHRvIGFwcGx5IHRvIGVhY2ggaXRlbSBpblxuICogYGNvbGxgLlxuICogVGhlIGFycmF5IGluZGV4IGlzIG5vdCBwYXNzZWQgdG8gdGhlIGl0ZXJhdGVlLlxuICogSWYgeW91IG5lZWQgdGhlIGluZGV4LCB1c2UgYGVhY2hPZkxpbWl0YC5cbiAqIEludm9rZWQgd2l0aCAoaXRlbSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIHdoZW4gYWxsXG4gKiBgaXRlcmF0ZWVgIGZ1bmN0aW9ucyBoYXZlIGZpbmlzaGVkLCBvciBhbiBlcnJvciBvY2N1cnMuIEludm9rZWQgd2l0aCAoZXJyKS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIGEgY2FsbGJhY2sgaXMgb21pdHRlZFxuICovXG5mdW5jdGlvbiBlYWNoTGltaXQoY29sbCwgbGltaXQsIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBlYWNoT2ZMaW1pdCQyKGxpbWl0KShjb2xsLCBfd2l0aG91dEluZGV4KHdyYXBBc3luYyhpdGVyYXRlZSkpLCBjYWxsYmFjayk7XG59XG52YXIgZWFjaExpbWl0JDEgPSBhd2FpdGlmeShlYWNoTGltaXQsIDQpO1xuXG4vKipcbiAqIFRoZSBzYW1lIGFzIFtgZWFjaGBde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5lYWNofSBidXQgcnVucyBvbmx5IGEgc2luZ2xlIGFzeW5jIG9wZXJhdGlvbiBhdCBhIHRpbWUuXG4gKlxuICogTm90ZSwgdGhhdCB1bmxpa2UgW2BlYWNoYF17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLmVhY2h9LCB0aGlzIGZ1bmN0aW9uIGFwcGxpZXMgaXRlcmF0ZWUgdG8gZWFjaCBpdGVtXG4gKiBpbiBzZXJpZXMgYW5kIHRoZXJlZm9yZSB0aGUgaXRlcmF0ZWUgZnVuY3Rpb25zIHdpbGwgY29tcGxldGUgaW4gb3JkZXIuXG5cbiAqIEBuYW1lIGVhY2hTZXJpZXNcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29sbGVjdGlvbnNcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLmVhY2hde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5lYWNofVxuICogQGFsaWFzIGZvckVhY2hTZXJpZXNcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fEl0ZXJhYmxlfEFzeW5jSXRlcmFibGV8T2JqZWN0fSBjb2xsIC0gQSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7QXN5bmNGdW5jdGlvbn0gaXRlcmF0ZWUgLSBBbiBhc3luYyBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoXG4gKiBpdGVtIGluIGBjb2xsYC5cbiAqIFRoZSBhcnJheSBpbmRleCBpcyBub3QgcGFzc2VkIHRvIHRoZSBpdGVyYXRlZS5cbiAqIElmIHlvdSBuZWVkIHRoZSBpbmRleCwgdXNlIGBlYWNoT2ZTZXJpZXNgLlxuICogSW52b2tlZCB3aXRoIChpdGVtLCBjYWxsYmFjaykuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdIC0gQSBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgd2hlbiBhbGxcbiAqIGBpdGVyYXRlZWAgZnVuY3Rpb25zIGhhdmUgZmluaXNoZWQsIG9yIGFuIGVycm9yIG9jY3Vycy4gSW52b2tlZCB3aXRoIChlcnIpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgYSBjYWxsYmFjayBpcyBvbWl0dGVkXG4gKi9cbmZ1bmN0aW9uIGVhY2hTZXJpZXMoY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIGVhY2hMaW1pdCQxKGNvbGwsIDEsIGl0ZXJhdGVlLCBjYWxsYmFjaylcbn1cbnZhciBlYWNoU2VyaWVzJDEgPSBhd2FpdGlmeShlYWNoU2VyaWVzLCAzKTtcblxuLyoqXG4gKiBXcmFwIGFuIGFzeW5jIGZ1bmN0aW9uIGFuZCBlbnN1cmUgaXQgY2FsbHMgaXRzIGNhbGxiYWNrIG9uIGEgbGF0ZXIgdGljayBvZlxuICogdGhlIGV2ZW50IGxvb3AuICBJZiB0aGUgZnVuY3Rpb24gYWxyZWFkeSBjYWxscyBpdHMgY2FsbGJhY2sgb24gYSBuZXh0IHRpY2ssXG4gKiBubyBleHRyYSBkZWZlcnJhbCBpcyBhZGRlZC4gVGhpcyBpcyB1c2VmdWwgZm9yIHByZXZlbnRpbmcgc3RhY2sgb3ZlcmZsb3dzXG4gKiAoYFJhbmdlRXJyb3I6IE1heGltdW0gY2FsbCBzdGFjayBzaXplIGV4Y2VlZGVkYCkgYW5kIGdlbmVyYWxseSBrZWVwaW5nXG4gKiBbWmFsZ29dKGh0dHA6Ly9ibG9nLml6cy5tZS9wb3N0LzU5MTQyNzQyMTQzL2Rlc2lnbmluZy1hcGlzLWZvci1hc3luY2hyb255KVxuICogY29udGFpbmVkLiBFUzIwMTcgYGFzeW5jYCBmdW5jdGlvbnMgYXJlIHJldHVybmVkIGFzLWlzIC0tIHRoZXkgYXJlIGltbXVuZVxuICogdG8gWmFsZ28ncyBjb3JydXB0aW5nIGluZmx1ZW5jZXMsIGFzIHRoZXkgYWx3YXlzIHJlc29sdmUgb24gYSBsYXRlciB0aWNrLlxuICpcbiAqIEBuYW1lIGVuc3VyZUFzeW5jXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOlV0aWxzXG4gKiBAbWV0aG9kXG4gKiBAY2F0ZWdvcnkgVXRpbFxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBmbiAtIGFuIGFzeW5jIGZ1bmN0aW9uLCBvbmUgdGhhdCBleHBlY3RzIGEgbm9kZS1zdHlsZVxuICogY2FsbGJhY2sgYXMgaXRzIGxhc3QgYXJndW1lbnQuXG4gKiBAcmV0dXJucyB7QXN5bmNGdW5jdGlvbn0gUmV0dXJucyBhIHdyYXBwZWQgZnVuY3Rpb24gd2l0aCB0aGUgZXhhY3Qgc2FtZSBjYWxsXG4gKiBzaWduYXR1cmUgYXMgdGhlIGZ1bmN0aW9uIHBhc3NlZCBpbi5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gc29tZXRpbWVzQXN5bmMoYXJnLCBjYWxsYmFjaykge1xuICogICAgIGlmIChjYWNoZVthcmddKSB7XG4gKiAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBjYWNoZVthcmddKTsgLy8gdGhpcyB3b3VsZCBiZSBzeW5jaHJvbm91cyEhXG4gKiAgICAgfSBlbHNlIHtcbiAqICAgICAgICAgZG9Tb21lSU8oYXJnLCBjYWxsYmFjayk7IC8vIHRoaXMgSU8gd291bGQgYmUgYXN5bmNocm9ub3VzXG4gKiAgICAgfVxuICogfVxuICpcbiAqIC8vIHRoaXMgaGFzIGEgcmlzayBvZiBzdGFjayBvdmVyZmxvd3MgaWYgbWFueSByZXN1bHRzIGFyZSBjYWNoZWQgaW4gYSByb3dcbiAqIGFzeW5jLm1hcFNlcmllcyhhcmdzLCBzb21ldGltZXNBc3luYywgZG9uZSk7XG4gKlxuICogLy8gdGhpcyB3aWxsIGRlZmVyIHNvbWV0aW1lc0FzeW5jJ3MgY2FsbGJhY2sgaWYgbmVjZXNzYXJ5LFxuICogLy8gcHJldmVudGluZyBzdGFjayBvdmVyZmxvd3NcbiAqIGFzeW5jLm1hcFNlcmllcyhhcmdzLCBhc3luYy5lbnN1cmVBc3luYyhzb21ldGltZXNBc3luYyksIGRvbmUpO1xuICovXG5mdW5jdGlvbiBlbnN1cmVBc3luYyhmbikge1xuICAgIGlmIChpc0FzeW5jKGZuKSkgcmV0dXJuIGZuO1xuICAgIHJldHVybiBmdW5jdGlvbiAoLi4uYXJncy8qLCBjYWxsYmFjayovKSB7XG4gICAgICAgIHZhciBjYWxsYmFjayA9IGFyZ3MucG9wKCk7XG4gICAgICAgIHZhciBzeW5jID0gdHJ1ZTtcbiAgICAgICAgYXJncy5wdXNoKCguLi5pbm5lckFyZ3MpID0+IHtcbiAgICAgICAgICAgIGlmIChzeW5jKSB7XG4gICAgICAgICAgICAgICAgc2V0SW1tZWRpYXRlJDEoKCkgPT4gY2FsbGJhY2soLi4uaW5uZXJBcmdzKSk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNhbGxiYWNrKC4uLmlubmVyQXJncyk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBmbi5hcHBseSh0aGlzLCBhcmdzKTtcbiAgICAgICAgc3luYyA9IGZhbHNlO1xuICAgIH07XG59XG5cbi8qKlxuICogUmV0dXJucyBgdHJ1ZWAgaWYgZXZlcnkgZWxlbWVudCBpbiBgY29sbGAgc2F0aXNmaWVzIGFuIGFzeW5jIHRlc3QuIElmIGFueVxuICogaXRlcmF0ZWUgY2FsbCByZXR1cm5zIGBmYWxzZWAsIHRoZSBtYWluIGBjYWxsYmFja2AgaXMgaW1tZWRpYXRlbHkgY2FsbGVkLlxuICpcbiAqIEBuYW1lIGV2ZXJ5XG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbGxlY3Rpb25zXG4gKiBAbWV0aG9kXG4gKiBAYWxpYXMgYWxsXG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxJdGVyYWJsZXxBc3luY0l0ZXJhYmxlfE9iamVjdH0gY29sbCAtIEEgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IGl0ZXJhdGVlIC0gQW4gYXN5bmMgdHJ1dGggdGVzdCB0byBhcHBseSB0byBlYWNoIGl0ZW1cbiAqIGluIHRoZSBjb2xsZWN0aW9uIGluIHBhcmFsbGVsLlxuICogVGhlIGl0ZXJhdGVlIG11c3QgY29tcGxldGUgd2l0aCBhIGJvb2xlYW4gcmVzdWx0IHZhbHVlLlxuICogSW52b2tlZCB3aXRoIChpdGVtLCBjYWxsYmFjaykuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdIC0gQSBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgYWZ0ZXIgYWxsIHRoZVxuICogYGl0ZXJhdGVlYCBmdW5jdGlvbnMgaGF2ZSBmaW5pc2hlZC4gUmVzdWx0IHdpbGwgYmUgZWl0aGVyIGB0cnVlYCBvciBgZmFsc2VgXG4gKiBkZXBlbmRpbmcgb24gdGhlIHZhbHVlcyBvZiB0aGUgYXN5bmMgdGVzdHMuIEludm9rZWQgd2l0aCAoZXJyLCByZXN1bHQpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgbm8gY2FsbGJhY2sgcHJvdmlkZWRcbiAqIEBleGFtcGxlXG4gKlxuICogLy8gZGlyMSBpcyBhIGRpcmVjdG9yeSB0aGF0IGNvbnRhaW5zIGZpbGUxLnR4dCwgZmlsZTIudHh0XG4gKiAvLyBkaXIyIGlzIGEgZGlyZWN0b3J5IHRoYXQgY29udGFpbnMgZmlsZTMudHh0LCBmaWxlNC50eHRcbiAqIC8vIGRpcjMgaXMgYSBkaXJlY3RvcnkgdGhhdCBjb250YWlucyBmaWxlNS50eHRcbiAqIC8vIGRpcjQgZG9lcyBub3QgZXhpc3RcbiAqXG4gKiBjb25zdCBmaWxlTGlzdCA9IFsnZGlyMS9maWxlMS50eHQnLCdkaXIyL2ZpbGUzLnR4dCcsJ2RpcjMvZmlsZTUudHh0J107XG4gKiBjb25zdCB3aXRoTWlzc2luZ0ZpbGVMaXN0ID0gWydmaWxlMS50eHQnLCdmaWxlMi50eHQnLCdmaWxlNC50eHQnXTtcbiAqXG4gKiAvLyBhc3luY2hyb25vdXMgZnVuY3Rpb24gdGhhdCBjaGVja3MgaWYgYSBmaWxlIGV4aXN0c1xuICogZnVuY3Rpb24gZmlsZUV4aXN0cyhmaWxlLCBjYWxsYmFjaykge1xuICogICAgZnMuYWNjZXNzKGZpbGUsIGZzLmNvbnN0YW50cy5GX09LLCAoZXJyKSA9PiB7XG4gKiAgICAgICAgY2FsbGJhY2sobnVsbCwgIWVycik7XG4gKiAgICB9KTtcbiAqIH1cbiAqXG4gKiAvLyBVc2luZyBjYWxsYmFja3NcbiAqIGFzeW5jLmV2ZXJ5KGZpbGVMaXN0LCBmaWxlRXhpc3RzLCBmdW5jdGlvbihlcnIsIHJlc3VsdCkge1xuICogICAgIGNvbnNvbGUubG9nKHJlc3VsdCk7XG4gKiAgICAgLy8gdHJ1ZVxuICogICAgIC8vIHJlc3VsdCBpcyB0cnVlIHNpbmNlIGV2ZXJ5IGZpbGUgZXhpc3RzXG4gKiB9KTtcbiAqXG4gKiBhc3luYy5ldmVyeSh3aXRoTWlzc2luZ0ZpbGVMaXN0LCBmaWxlRXhpc3RzLCBmdW5jdGlvbihlcnIsIHJlc3VsdCkge1xuICogICAgIGNvbnNvbGUubG9nKHJlc3VsdCk7XG4gKiAgICAgLy8gZmFsc2VcbiAqICAgICAvLyByZXN1bHQgaXMgZmFsc2Ugc2luY2UgTk9UIGV2ZXJ5IGZpbGUgZXhpc3RzXG4gKiB9KTtcbiAqXG4gKiAvLyBVc2luZyBQcm9taXNlc1xuICogYXN5bmMuZXZlcnkoZmlsZUxpc3QsIGZpbGVFeGlzdHMpXG4gKiAudGhlbiggcmVzdWx0ID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhyZXN1bHQpO1xuICogICAgIC8vIHRydWVcbiAqICAgICAvLyByZXN1bHQgaXMgdHJ1ZSBzaW5jZSBldmVyeSBmaWxlIGV4aXN0c1xuICogfSkuY2F0Y2goIGVyciA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqIH0pO1xuICpcbiAqIGFzeW5jLmV2ZXJ5KHdpdGhNaXNzaW5nRmlsZUxpc3QsIGZpbGVFeGlzdHMpXG4gKiAudGhlbiggcmVzdWx0ID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhyZXN1bHQpO1xuICogICAgIC8vIGZhbHNlXG4gKiAgICAgLy8gcmVzdWx0IGlzIGZhbHNlIHNpbmNlIE5PVCBldmVyeSBmaWxlIGV4aXN0c1xuICogfSkuY2F0Y2goIGVyciA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqIH0pO1xuICpcbiAqIC8vIFVzaW5nIGFzeW5jL2F3YWl0XG4gKiBhc3luYyAoKSA9PiB7XG4gKiAgICAgdHJ5IHtcbiAqICAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IGFzeW5jLmV2ZXJ5KGZpbGVMaXN0LCBmaWxlRXhpc3RzKTtcbiAqICAgICAgICAgY29uc29sZS5sb2cocmVzdWx0KTtcbiAqICAgICAgICAgLy8gdHJ1ZVxuICogICAgICAgICAvLyByZXN1bHQgaXMgdHJ1ZSBzaW5jZSBldmVyeSBmaWxlIGV4aXN0c1xuICogICAgIH1cbiAqICAgICBjYXRjaCAoZXJyKSB7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiAgICAgfVxuICogfVxuICpcbiAqIGFzeW5jICgpID0+IHtcbiAqICAgICB0cnkge1xuICogICAgICAgICBsZXQgcmVzdWx0ID0gYXdhaXQgYXN5bmMuZXZlcnkod2l0aE1pc3NpbmdGaWxlTGlzdCwgZmlsZUV4aXN0cyk7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdCk7XG4gKiAgICAgICAgIC8vIGZhbHNlXG4gKiAgICAgICAgIC8vIHJlc3VsdCBpcyBmYWxzZSBzaW5jZSBOT1QgZXZlcnkgZmlsZSBleGlzdHNcbiAqICAgICB9XG4gKiAgICAgY2F0Y2ggKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgIH1cbiAqIH1cbiAqXG4gKi9cbmZ1bmN0aW9uIGV2ZXJ5KGNvbGwsIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBfY3JlYXRlVGVzdGVyKGJvb2wgPT4gIWJvb2wsIHJlcyA9PiAhcmVzKShlYWNoT2YkMSwgY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKVxufVxudmFyIGV2ZXJ5JDEgPSBhd2FpdGlmeShldmVyeSwgMyk7XG5cbi8qKlxuICogVGhlIHNhbWUgYXMgW2BldmVyeWBde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5ldmVyeX0gYnV0IHJ1bnMgYSBtYXhpbXVtIG9mIGBsaW1pdGAgYXN5bmMgb3BlcmF0aW9ucyBhdCBhIHRpbWUuXG4gKlxuICogQG5hbWUgZXZlcnlMaW1pdFxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb2xsZWN0aW9uc1xuICogQG1ldGhvZFxuICogQHNlZSBbYXN5bmMuZXZlcnlde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5ldmVyeX1cbiAqIEBhbGlhcyBhbGxMaW1pdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IGNvbGwgLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtudW1iZXJ9IGxpbWl0IC0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGFzeW5jIG9wZXJhdGlvbnMgYXQgYSB0aW1lLlxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEFuIGFzeW5jIHRydXRoIHRlc3QgdG8gYXBwbHkgdG8gZWFjaCBpdGVtXG4gKiBpbiB0aGUgY29sbGVjdGlvbiBpbiBwYXJhbGxlbC5cbiAqIFRoZSBpdGVyYXRlZSBtdXN0IGNvbXBsZXRlIHdpdGggYSBib29sZWFuIHJlc3VsdCB2YWx1ZS5cbiAqIEludm9rZWQgd2l0aCAoaXRlbSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIGFmdGVyIGFsbCB0aGVcbiAqIGBpdGVyYXRlZWAgZnVuY3Rpb25zIGhhdmUgZmluaXNoZWQuIFJlc3VsdCB3aWxsIGJlIGVpdGhlciBgdHJ1ZWAgb3IgYGZhbHNlYFxuICogZGVwZW5kaW5nIG9uIHRoZSB2YWx1ZXMgb2YgdGhlIGFzeW5jIHRlc3RzLiBJbnZva2VkIHdpdGggKGVyciwgcmVzdWx0KS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIG5vIGNhbGxiYWNrIHByb3ZpZGVkXG4gKi9cbmZ1bmN0aW9uIGV2ZXJ5TGltaXQoY29sbCwgbGltaXQsIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBfY3JlYXRlVGVzdGVyKGJvb2wgPT4gIWJvb2wsIHJlcyA9PiAhcmVzKShlYWNoT2ZMaW1pdCQyKGxpbWl0KSwgY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKVxufVxudmFyIGV2ZXJ5TGltaXQkMSA9IGF3YWl0aWZ5KGV2ZXJ5TGltaXQsIDQpO1xuXG4vKipcbiAqIFRoZSBzYW1lIGFzIFtgZXZlcnlgXXtAbGluayBtb2R1bGU6Q29sbGVjdGlvbnMuZXZlcnl9IGJ1dCBydW5zIG9ubHkgYSBzaW5nbGUgYXN5bmMgb3BlcmF0aW9uIGF0IGEgdGltZS5cbiAqXG4gKiBAbmFtZSBldmVyeVNlcmllc1xuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb2xsZWN0aW9uc1xuICogQG1ldGhvZFxuICogQHNlZSBbYXN5bmMuZXZlcnlde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5ldmVyeX1cbiAqIEBhbGlhcyBhbGxTZXJpZXNcbiAqIEBjYXRlZ29yeSBDb2xsZWN0aW9uXG4gKiBAcGFyYW0ge0FycmF5fEl0ZXJhYmxlfEFzeW5jSXRlcmFibGV8T2JqZWN0fSBjb2xsIC0gQSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7QXN5bmNGdW5jdGlvbn0gaXRlcmF0ZWUgLSBBbiBhc3luYyB0cnV0aCB0ZXN0IHRvIGFwcGx5IHRvIGVhY2ggaXRlbVxuICogaW4gdGhlIGNvbGxlY3Rpb24gaW4gc2VyaWVzLlxuICogVGhlIGl0ZXJhdGVlIG11c3QgY29tcGxldGUgd2l0aCBhIGJvb2xlYW4gcmVzdWx0IHZhbHVlLlxuICogSW52b2tlZCB3aXRoIChpdGVtLCBjYWxsYmFjaykuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdIC0gQSBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgYWZ0ZXIgYWxsIHRoZVxuICogYGl0ZXJhdGVlYCBmdW5jdGlvbnMgaGF2ZSBmaW5pc2hlZC4gUmVzdWx0IHdpbGwgYmUgZWl0aGVyIGB0cnVlYCBvciBgZmFsc2VgXG4gKiBkZXBlbmRpbmcgb24gdGhlIHZhbHVlcyBvZiB0aGUgYXN5bmMgdGVzdHMuIEludm9rZWQgd2l0aCAoZXJyLCByZXN1bHQpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgbm8gY2FsbGJhY2sgcHJvdmlkZWRcbiAqL1xuZnVuY3Rpb24gZXZlcnlTZXJpZXMoY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIF9jcmVhdGVUZXN0ZXIoYm9vbCA9PiAhYm9vbCwgcmVzID0+ICFyZXMpKGVhY2hPZlNlcmllcyQxLCBjb2xsLCBpdGVyYXRlZSwgY2FsbGJhY2spXG59XG52YXIgZXZlcnlTZXJpZXMkMSA9IGF3YWl0aWZ5KGV2ZXJ5U2VyaWVzLCAzKTtcblxuZnVuY3Rpb24gZmlsdGVyQXJyYXkoZWFjaGZuLCBhcnIsIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIHZhciB0cnV0aFZhbHVlcyA9IG5ldyBBcnJheShhcnIubGVuZ3RoKTtcbiAgICBlYWNoZm4oYXJyLCAoeCwgaW5kZXgsIGl0ZXJDYikgPT4ge1xuICAgICAgICBpdGVyYXRlZSh4LCAoZXJyLCB2KSA9PiB7XG4gICAgICAgICAgICB0cnV0aFZhbHVlc1tpbmRleF0gPSAhIXY7XG4gICAgICAgICAgICBpdGVyQ2IoZXJyKTtcbiAgICAgICAgfSk7XG4gICAgfSwgZXJyID0+IHtcbiAgICAgICAgaWYgKGVycikgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgIHZhciByZXN1bHRzID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodHJ1dGhWYWx1ZXNbaV0pIHJlc3VsdHMucHVzaChhcnJbaV0pO1xuICAgICAgICB9XG4gICAgICAgIGNhbGxiYWNrKG51bGwsIHJlc3VsdHMpO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBmaWx0ZXJHZW5lcmljKGVhY2hmbiwgY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgdmFyIHJlc3VsdHMgPSBbXTtcbiAgICBlYWNoZm4oY29sbCwgKHgsIGluZGV4LCBpdGVyQ2IpID0+IHtcbiAgICAgICAgaXRlcmF0ZWUoeCwgKGVyciwgdikgPT4ge1xuICAgICAgICAgICAgaWYgKGVycikgcmV0dXJuIGl0ZXJDYihlcnIpO1xuICAgICAgICAgICAgaWYgKHYpIHtcbiAgICAgICAgICAgICAgICByZXN1bHRzLnB1c2goe2luZGV4LCB2YWx1ZTogeH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaXRlckNiKGVycik7XG4gICAgICAgIH0pO1xuICAgIH0sIGVyciA9PiB7XG4gICAgICAgIGlmIChlcnIpIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgICBjYWxsYmFjayhudWxsLCByZXN1bHRzXG4gICAgICAgICAgICAuc29ydCgoYSwgYikgPT4gYS5pbmRleCAtIGIuaW5kZXgpXG4gICAgICAgICAgICAubWFwKHYgPT4gdi52YWx1ZSkpO1xuICAgIH0pO1xufVxuXG5mdW5jdGlvbiBfZmlsdGVyKGVhY2hmbiwgY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgdmFyIGZpbHRlciA9IGlzQXJyYXlMaWtlKGNvbGwpID8gZmlsdGVyQXJyYXkgOiBmaWx0ZXJHZW5lcmljO1xuICAgIHJldHVybiBmaWx0ZXIoZWFjaGZuLCBjb2xsLCB3cmFwQXN5bmMoaXRlcmF0ZWUpLCBjYWxsYmFjayk7XG59XG5cbi8qKlxuICogUmV0dXJucyBhIG5ldyBhcnJheSBvZiBhbGwgdGhlIHZhbHVlcyBpbiBgY29sbGAgd2hpY2ggcGFzcyBhbiBhc3luYyB0cnV0aFxuICogdGVzdC4gVGhpcyBvcGVyYXRpb24gaXMgcGVyZm9ybWVkIGluIHBhcmFsbGVsLCBidXQgdGhlIHJlc3VsdHMgYXJyYXkgd2lsbCBiZVxuICogaW4gdGhlIHNhbWUgb3JkZXIgYXMgdGhlIG9yaWdpbmFsLlxuICpcbiAqIEBuYW1lIGZpbHRlclxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb2xsZWN0aW9uc1xuICogQG1ldGhvZFxuICogQGFsaWFzIHNlbGVjdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IGNvbGwgLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgLSBBIHRydXRoIHRlc3QgdG8gYXBwbHkgdG8gZWFjaCBpdGVtIGluIGBjb2xsYC5cbiAqIFRoZSBgaXRlcmF0ZWVgIGlzIHBhc3NlZCBhIGBjYWxsYmFjayhlcnIsIHRydXRoVmFsdWUpYCwgd2hpY2ggbXVzdCBiZSBjYWxsZWRcbiAqIHdpdGggYSBib29sZWFuIGFyZ3VtZW50IG9uY2UgaXQgaGFzIGNvbXBsZXRlZC4gSW52b2tlZCB3aXRoIChpdGVtLCBjYWxsYmFjaykuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdIC0gQSBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgYWZ0ZXIgYWxsIHRoZVxuICogYGl0ZXJhdGVlYCBmdW5jdGlvbnMgaGF2ZSBmaW5pc2hlZC4gSW52b2tlZCB3aXRoIChlcnIsIHJlc3VsdHMpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgbm8gY2FsbGJhY2sgcHJvdmlkZWRcbiAqIEBleGFtcGxlXG4gKlxuICogLy8gZGlyMSBpcyBhIGRpcmVjdG9yeSB0aGF0IGNvbnRhaW5zIGZpbGUxLnR4dCwgZmlsZTIudHh0XG4gKiAvLyBkaXIyIGlzIGEgZGlyZWN0b3J5IHRoYXQgY29udGFpbnMgZmlsZTMudHh0LCBmaWxlNC50eHRcbiAqIC8vIGRpcjMgaXMgYSBkaXJlY3RvcnkgdGhhdCBjb250YWlucyBmaWxlNS50eHRcbiAqXG4gKiBjb25zdCBmaWxlcyA9IFsnZGlyMS9maWxlMS50eHQnLCdkaXIyL2ZpbGUzLnR4dCcsJ2RpcjMvZmlsZTYudHh0J107XG4gKlxuICogLy8gYXN5bmNocm9ub3VzIGZ1bmN0aW9uIHRoYXQgY2hlY2tzIGlmIGEgZmlsZSBleGlzdHNcbiAqIGZ1bmN0aW9uIGZpbGVFeGlzdHMoZmlsZSwgY2FsbGJhY2spIHtcbiAqICAgIGZzLmFjY2VzcyhmaWxlLCBmcy5jb25zdGFudHMuRl9PSywgKGVycikgPT4ge1xuICogICAgICAgIGNhbGxiYWNrKG51bGwsICFlcnIpO1xuICogICAgfSk7XG4gKiB9XG4gKlxuICogLy8gVXNpbmcgY2FsbGJhY2tzXG4gKiBhc3luYy5maWx0ZXIoZmlsZXMsIGZpbGVFeGlzdHMsIGZ1bmN0aW9uKGVyciwgcmVzdWx0cykge1xuICogICAgaWYoZXJyKSB7XG4gKiAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgIH0gZWxzZSB7XG4gKiAgICAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiAgICAgICAgLy8gWyAnZGlyMS9maWxlMS50eHQnLCAnZGlyMi9maWxlMy50eHQnIF1cbiAqICAgICAgICAvLyByZXN1bHRzIGlzIG5vdyBhbiBhcnJheSBvZiB0aGUgZXhpc3RpbmcgZmlsZXNcbiAqICAgIH1cbiAqIH0pO1xuICpcbiAqIC8vIFVzaW5nIFByb21pc2VzXG4gKiBhc3luYy5maWx0ZXIoZmlsZXMsIGZpbGVFeGlzdHMpXG4gKiAudGhlbihyZXN1bHRzID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhyZXN1bHRzKTtcbiAqICAgICAvLyBbICdkaXIxL2ZpbGUxLnR4dCcsICdkaXIyL2ZpbGUzLnR4dCcgXVxuICogICAgIC8vIHJlc3VsdHMgaXMgbm93IGFuIGFycmF5IG9mIHRoZSBleGlzdGluZyBmaWxlc1xuICogfSkuY2F0Y2goZXJyID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogfSk7XG4gKlxuICogLy8gVXNpbmcgYXN5bmMvYXdhaXRcbiAqIGFzeW5jICgpID0+IHtcbiAqICAgICB0cnkge1xuICogICAgICAgICBsZXQgcmVzdWx0cyA9IGF3YWl0IGFzeW5jLmZpbHRlcihmaWxlcywgZmlsZUV4aXN0cyk7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdHMpO1xuICogICAgICAgICAvLyBbICdkaXIxL2ZpbGUxLnR4dCcsICdkaXIyL2ZpbGUzLnR4dCcgXVxuICogICAgICAgICAvLyByZXN1bHRzIGlzIG5vdyBhbiBhcnJheSBvZiB0aGUgZXhpc3RpbmcgZmlsZXNcbiAqICAgICB9XG4gKiAgICAgY2F0Y2ggKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgIH1cbiAqIH1cbiAqXG4gKi9cbmZ1bmN0aW9uIGZpbHRlciAoY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIF9maWx0ZXIoZWFjaE9mJDEsIGNvbGwsIGl0ZXJhdGVlLCBjYWxsYmFjaylcbn1cbnZhciBmaWx0ZXIkMSA9IGF3YWl0aWZ5KGZpbHRlciwgMyk7XG5cbi8qKlxuICogVGhlIHNhbWUgYXMgW2BmaWx0ZXJgXXtAbGluayBtb2R1bGU6Q29sbGVjdGlvbnMuZmlsdGVyfSBidXQgcnVucyBhIG1heGltdW0gb2YgYGxpbWl0YCBhc3luYyBvcGVyYXRpb25zIGF0IGFcbiAqIHRpbWUuXG4gKlxuICogQG5hbWUgZmlsdGVyTGltaXRcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29sbGVjdGlvbnNcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLmZpbHRlcl17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLmZpbHRlcn1cbiAqIEBhbGlhcyBzZWxlY3RMaW1pdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IGNvbGwgLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtudW1iZXJ9IGxpbWl0IC0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGFzeW5jIG9wZXJhdGlvbnMgYXQgYSB0aW1lLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZWUgLSBBIHRydXRoIHRlc3QgdG8gYXBwbHkgdG8gZWFjaCBpdGVtIGluIGBjb2xsYC5cbiAqIFRoZSBgaXRlcmF0ZWVgIGlzIHBhc3NlZCBhIGBjYWxsYmFjayhlcnIsIHRydXRoVmFsdWUpYCwgd2hpY2ggbXVzdCBiZSBjYWxsZWRcbiAqIHdpdGggYSBib29sZWFuIGFyZ3VtZW50IG9uY2UgaXQgaGFzIGNvbXBsZXRlZC4gSW52b2tlZCB3aXRoIChpdGVtLCBjYWxsYmFjaykuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdIC0gQSBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgYWZ0ZXIgYWxsIHRoZVxuICogYGl0ZXJhdGVlYCBmdW5jdGlvbnMgaGF2ZSBmaW5pc2hlZC4gSW52b2tlZCB3aXRoIChlcnIsIHJlc3VsdHMpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgbm8gY2FsbGJhY2sgcHJvdmlkZWRcbiAqL1xuZnVuY3Rpb24gZmlsdGVyTGltaXQgKGNvbGwsIGxpbWl0LCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gX2ZpbHRlcihlYWNoT2ZMaW1pdCQyKGxpbWl0KSwgY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKVxufVxudmFyIGZpbHRlckxpbWl0JDEgPSBhd2FpdGlmeShmaWx0ZXJMaW1pdCwgNCk7XG5cbi8qKlxuICogVGhlIHNhbWUgYXMgW2BmaWx0ZXJgXXtAbGluayBtb2R1bGU6Q29sbGVjdGlvbnMuZmlsdGVyfSBidXQgcnVucyBvbmx5IGEgc2luZ2xlIGFzeW5jIG9wZXJhdGlvbiBhdCBhIHRpbWUuXG4gKlxuICogQG5hbWUgZmlsdGVyU2VyaWVzXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbGxlY3Rpb25zXG4gKiBAbWV0aG9kXG4gKiBAc2VlIFthc3luYy5maWx0ZXJde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5maWx0ZXJ9XG4gKiBAYWxpYXMgc2VsZWN0U2VyaWVzXG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxJdGVyYWJsZXxBc3luY0l0ZXJhYmxlfE9iamVjdH0gY29sbCAtIEEgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEEgdHJ1dGggdGVzdCB0byBhcHBseSB0byBlYWNoIGl0ZW0gaW4gYGNvbGxgLlxuICogVGhlIGBpdGVyYXRlZWAgaXMgcGFzc2VkIGEgYGNhbGxiYWNrKGVyciwgdHJ1dGhWYWx1ZSlgLCB3aGljaCBtdXN0IGJlIGNhbGxlZFxuICogd2l0aCBhIGJvb2xlYW4gYXJndW1lbnQgb25jZSBpdCBoYXMgY29tcGxldGVkLiBJbnZva2VkIHdpdGggKGl0ZW0sIGNhbGxiYWNrKS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYWxsYmFja10gLSBBIGNhbGxiYWNrIHdoaWNoIGlzIGNhbGxlZCBhZnRlciBhbGwgdGhlXG4gKiBgaXRlcmF0ZWVgIGZ1bmN0aW9ucyBoYXZlIGZpbmlzaGVkLiBJbnZva2VkIHdpdGggKGVyciwgcmVzdWx0cylcbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIG5vIGNhbGxiYWNrIHByb3ZpZGVkXG4gKi9cbmZ1bmN0aW9uIGZpbHRlclNlcmllcyAoY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIF9maWx0ZXIoZWFjaE9mU2VyaWVzJDEsIGNvbGwsIGl0ZXJhdGVlLCBjYWxsYmFjaylcbn1cbnZhciBmaWx0ZXJTZXJpZXMkMSA9IGF3YWl0aWZ5KGZpbHRlclNlcmllcywgMyk7XG5cbi8qKlxuICogQ2FsbHMgdGhlIGFzeW5jaHJvbm91cyBmdW5jdGlvbiBgZm5gIHdpdGggYSBjYWxsYmFjayBwYXJhbWV0ZXIgdGhhdCBhbGxvd3MgaXRcbiAqIHRvIGNhbGwgaXRzZWxmIGFnYWluLCBpbiBzZXJpZXMsIGluZGVmaW5pdGVseS5cblxuICogSWYgYW4gZXJyb3IgaXMgcGFzc2VkIHRvIHRoZSBjYWxsYmFjayB0aGVuIGBlcnJiYWNrYCBpcyBjYWxsZWQgd2l0aCB0aGVcbiAqIGVycm9yLCBhbmQgZXhlY3V0aW9uIHN0b3BzLCBvdGhlcndpc2UgaXQgd2lsbCBuZXZlciBiZSBjYWxsZWQuXG4gKlxuICogQG5hbWUgZm9yZXZlclxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb250cm9sRmxvd1xuICogQG1ldGhvZFxuICogQGNhdGVnb3J5IENvbnRyb2wgRmxvd1xuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBmbiAtIGFuIGFzeW5jIGZ1bmN0aW9uIHRvIGNhbGwgcmVwZWF0ZWRseS5cbiAqIEludm9rZWQgd2l0aCAobmV4dCkuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZXJyYmFja10gLSB3aGVuIGBmbmAgcGFzc2VzIGFuIGVycm9yIHRvIGl0J3MgY2FsbGJhY2ssXG4gKiB0aGlzIGZ1bmN0aW9uIHdpbGwgYmUgY2FsbGVkLCBhbmQgZXhlY3V0aW9uIHN0b3BzLiBJbnZva2VkIHdpdGggKGVycikuXG4gKiBAcmV0dXJucyB7UHJvbWlzZX0gYSBwcm9taXNlIHRoYXQgcmVqZWN0cyBpZiBhbiBlcnJvciBvY2N1cnMgYW5kIGFuIGVycmJhY2tcbiAqIGlzIG5vdCBwYXNzZWRcbiAqIEBleGFtcGxlXG4gKlxuICogYXN5bmMuZm9yZXZlcihcbiAqICAgICBmdW5jdGlvbihuZXh0KSB7XG4gKiAgICAgICAgIC8vIG5leHQgaXMgc3VpdGFibGUgZm9yIHBhc3NpbmcgdG8gdGhpbmdzIHRoYXQgbmVlZCBhIGNhbGxiYWNrKGVyciBbLCB3aGF0ZXZlcl0pO1xuICogICAgICAgICAvLyBpdCB3aWxsIHJlc3VsdCBpbiB0aGlzIGZ1bmN0aW9uIGJlaW5nIGNhbGxlZCBhZ2Fpbi5cbiAqICAgICB9LFxuICogICAgIGZ1bmN0aW9uKGVycikge1xuICogICAgICAgICAvLyBpZiBuZXh0IGlzIGNhbGxlZCB3aXRoIGEgdmFsdWUgaW4gaXRzIGZpcnN0IHBhcmFtZXRlciwgaXQgd2lsbCBhcHBlYXJcbiAqICAgICAgICAgLy8gaW4gaGVyZSBhcyAnZXJyJywgYW5kIGV4ZWN1dGlvbiB3aWxsIHN0b3AuXG4gKiAgICAgfVxuICogKTtcbiAqL1xuZnVuY3Rpb24gZm9yZXZlcihmbiwgZXJyYmFjaykge1xuICAgIHZhciBkb25lID0gb25seU9uY2UoZXJyYmFjayk7XG4gICAgdmFyIHRhc2sgPSB3cmFwQXN5bmMoZW5zdXJlQXN5bmMoZm4pKTtcblxuICAgIGZ1bmN0aW9uIG5leHQoZXJyKSB7XG4gICAgICAgIGlmIChlcnIpIHJldHVybiBkb25lKGVycik7XG4gICAgICAgIGlmIChlcnIgPT09IGZhbHNlKSByZXR1cm47XG4gICAgICAgIHRhc2sobmV4dCk7XG4gICAgfVxuICAgIHJldHVybiBuZXh0KCk7XG59XG52YXIgZm9yZXZlciQxID0gYXdhaXRpZnkoZm9yZXZlciwgMik7XG5cbi8qKlxuICogVGhlIHNhbWUgYXMgW2Bncm91cEJ5YF17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLmdyb3VwQnl9IGJ1dCBydW5zIGEgbWF4aW11bSBvZiBgbGltaXRgIGFzeW5jIG9wZXJhdGlvbnMgYXQgYSB0aW1lLlxuICpcbiAqIEBuYW1lIGdyb3VwQnlMaW1pdFxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb2xsZWN0aW9uc1xuICogQG1ldGhvZFxuICogQHNlZSBbYXN5bmMuZ3JvdXBCeV17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLmdyb3VwQnl9XG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxJdGVyYWJsZXxBc3luY0l0ZXJhYmxlfE9iamVjdH0gY29sbCAtIEEgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge251bWJlcn0gbGltaXQgLSBUaGUgbWF4aW11bSBudW1iZXIgb2YgYXN5bmMgb3BlcmF0aW9ucyBhdCBhIHRpbWUuXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IGl0ZXJhdGVlIC0gQW4gYXN5bmMgZnVuY3Rpb24gdG8gYXBwbHkgdG8gZWFjaCBpdGVtIGluXG4gKiBgY29sbGAuXG4gKiBUaGUgaXRlcmF0ZWUgc2hvdWxkIGNvbXBsZXRlIHdpdGggYSBga2V5YCB0byBncm91cCB0aGUgdmFsdWUgdW5kZXIuXG4gKiBJbnZva2VkIHdpdGggKHZhbHVlLCBjYWxsYmFjaykuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdIC0gQSBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgd2hlbiBhbGwgYGl0ZXJhdGVlYFxuICogZnVuY3Rpb25zIGhhdmUgZmluaXNoZWQsIG9yIGFuIGVycm9yIG9jY3Vycy4gUmVzdWx0IGlzIGFuIGBPYmplY3RgIHdob3Nlc1xuICogcHJvcGVydGllcyBhcmUgYXJyYXlzIG9mIHZhbHVlcyB3aGljaCByZXR1cm5lZCB0aGUgY29ycmVzcG9uZGluZyBrZXkuXG4gKiBAcmV0dXJucyB7UHJvbWlzZX0gYSBwcm9taXNlLCBpZiBubyBjYWxsYmFjayBpcyBwYXNzZWRcbiAqL1xuZnVuY3Rpb24gZ3JvdXBCeUxpbWl0KGNvbGwsIGxpbWl0LCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgX2l0ZXJhdGVlID0gd3JhcEFzeW5jKGl0ZXJhdGVlKTtcbiAgICByZXR1cm4gbWFwTGltaXQkMShjb2xsLCBsaW1pdCwgKHZhbCwgaXRlckNiKSA9PiB7XG4gICAgICAgIF9pdGVyYXRlZSh2YWwsIChlcnIsIGtleSkgPT4ge1xuICAgICAgICAgICAgaWYgKGVycikgcmV0dXJuIGl0ZXJDYihlcnIpO1xuICAgICAgICAgICAgcmV0dXJuIGl0ZXJDYihlcnIsIHtrZXksIHZhbH0pO1xuICAgICAgICB9KTtcbiAgICB9LCAoZXJyLCBtYXBSZXN1bHRzKSA9PiB7XG4gICAgICAgIHZhciByZXN1bHQgPSB7fTtcbiAgICAgICAgLy8gZnJvbSBNRE4sIGhhbmRsZSBvYmplY3QgaGF2aW5nIGFuIGBoYXNPd25Qcm9wZXJ0eWAgcHJvcFxuICAgICAgICB2YXIge2hhc093blByb3BlcnR5fSA9IE9iamVjdC5wcm90b3R5cGU7XG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXBSZXN1bHRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAobWFwUmVzdWx0c1tpXSkge1xuICAgICAgICAgICAgICAgIHZhciB7a2V5fSA9IG1hcFJlc3VsdHNbaV07XG4gICAgICAgICAgICAgICAgdmFyIHt2YWx9ID0gbWFwUmVzdWx0c1tpXTtcblxuICAgICAgICAgICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKHJlc3VsdCwga2V5KSkge1xuICAgICAgICAgICAgICAgICAgICByZXN1bHRba2V5XS5wdXNoKHZhbCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0W2tleV0gPSBbdmFsXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCByZXN1bHQpO1xuICAgIH0pO1xufVxuXG52YXIgZ3JvdXBCeUxpbWl0JDEgPSBhd2FpdGlmeShncm91cEJ5TGltaXQsIDQpO1xuXG4vKipcbiAqIFJldHVybnMgYSBuZXcgb2JqZWN0LCB3aGVyZSBlYWNoIHZhbHVlIGNvcnJlc3BvbmRzIHRvIGFuIGFycmF5IG9mIGl0ZW1zLCBmcm9tXG4gKiBgY29sbGAsIHRoYXQgcmV0dXJuZWQgdGhlIGNvcnJlc3BvbmRpbmcga2V5LiBUaGF0IGlzLCB0aGUga2V5cyBvZiB0aGUgb2JqZWN0XG4gKiBjb3JyZXNwb25kIHRvIHRoZSB2YWx1ZXMgcGFzc2VkIHRvIHRoZSBgaXRlcmF0ZWVgIGNhbGxiYWNrLlxuICpcbiAqIE5vdGU6IFNpbmNlIHRoaXMgZnVuY3Rpb24gYXBwbGllcyB0aGUgYGl0ZXJhdGVlYCB0byBlYWNoIGl0ZW0gaW4gcGFyYWxsZWwsXG4gKiB0aGVyZSBpcyBubyBndWFyYW50ZWUgdGhhdCB0aGUgYGl0ZXJhdGVlYCBmdW5jdGlvbnMgd2lsbCBjb21wbGV0ZSBpbiBvcmRlci5cbiAqIEhvd2V2ZXIsIHRoZSB2YWx1ZXMgZm9yIGVhY2gga2V5IGluIHRoZSBgcmVzdWx0YCB3aWxsIGJlIGluIHRoZSBzYW1lIG9yZGVyIGFzXG4gKiB0aGUgb3JpZ2luYWwgYGNvbGxgLiBGb3IgT2JqZWN0cywgdGhlIHZhbHVlcyB3aWxsIHJvdWdobHkgYmUgaW4gdGhlIG9yZGVyIG9mXG4gKiB0aGUgb3JpZ2luYWwgT2JqZWN0cycga2V5cyAoYnV0IHRoaXMgY2FuIHZhcnkgYWNyb3NzIEphdmFTY3JpcHQgZW5naW5lcykuXG4gKlxuICogQG5hbWUgZ3JvdXBCeVxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb2xsZWN0aW9uc1xuICogQG1ldGhvZFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IGNvbGwgLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEFuIGFzeW5jIGZ1bmN0aW9uIHRvIGFwcGx5IHRvIGVhY2ggaXRlbSBpblxuICogYGNvbGxgLlxuICogVGhlIGl0ZXJhdGVlIHNob3VsZCBjb21wbGV0ZSB3aXRoIGEgYGtleWAgdG8gZ3JvdXAgdGhlIHZhbHVlIHVuZGVyLlxuICogSW52b2tlZCB3aXRoICh2YWx1ZSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIHdoZW4gYWxsIGBpdGVyYXRlZWBcbiAqIGZ1bmN0aW9ucyBoYXZlIGZpbmlzaGVkLCBvciBhbiBlcnJvciBvY2N1cnMuIFJlc3VsdCBpcyBhbiBgT2JqZWN0YCB3aG9zZXNcbiAqIHByb3BlcnRpZXMgYXJlIGFycmF5cyBvZiB2YWx1ZXMgd2hpY2ggcmV0dXJuZWQgdGhlIGNvcnJlc3BvbmRpbmcga2V5LlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgbm8gY2FsbGJhY2sgaXMgcGFzc2VkXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIGRpcjEgaXMgYSBkaXJlY3RvcnkgdGhhdCBjb250YWlucyBmaWxlMS50eHQsIGZpbGUyLnR4dFxuICogLy8gZGlyMiBpcyBhIGRpcmVjdG9yeSB0aGF0IGNvbnRhaW5zIGZpbGUzLnR4dCwgZmlsZTQudHh0XG4gKiAvLyBkaXIzIGlzIGEgZGlyZWN0b3J5IHRoYXQgY29udGFpbnMgZmlsZTUudHh0XG4gKiAvLyBkaXI0IGRvZXMgbm90IGV4aXN0XG4gKlxuICogY29uc3QgZmlsZXMgPSBbJ2RpcjEvZmlsZTEudHh0JywnZGlyMicsJ2RpcjQnXVxuICpcbiAqIC8vIGFzeW5jaHJvbm91cyBmdW5jdGlvbiB0aGF0IGRldGVjdHMgZmlsZSB0eXBlIGFzIG5vbmUsIGZpbGUsIG9yIGRpcmVjdG9yeVxuICogZnVuY3Rpb24gZGV0ZWN0RmlsZShmaWxlLCBjYWxsYmFjaykge1xuICogICAgIGZzLnN0YXQoZmlsZSwgZnVuY3Rpb24oZXJyLCBzdGF0KSB7XG4gKiAgICAgICAgIGlmIChlcnIpIHtcbiAqICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCAnbm9uZScpO1xuICogICAgICAgICB9XG4gKiAgICAgICAgIGNhbGxiYWNrKG51bGwsIHN0YXQuaXNEaXJlY3RvcnkoKSA/ICdkaXJlY3RvcnknIDogJ2ZpbGUnKTtcbiAqICAgICB9KTtcbiAqIH1cbiAqXG4gKiAvL1VzaW5nIGNhbGxiYWNrc1xuICogYXN5bmMuZ3JvdXBCeShmaWxlcywgZGV0ZWN0RmlsZSwgZnVuY3Rpb24oZXJyLCByZXN1bHQpIHtcbiAqICAgICBpZihlcnIpIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICB9IGVsc2Uge1xuICpcdCAgICAgICBjb25zb2xlLmxvZyhyZXN1bHQpO1xuICogICAgICAgICAvLyB7XG4gKiAgICAgICAgIC8vICAgICBmaWxlOiBbICdkaXIxL2ZpbGUxLnR4dCcgXSxcbiAqICAgICAgICAgLy8gICAgIG5vbmU6IFsgJ2RpcjQnIF0sXG4gKiAgICAgICAgIC8vICAgICBkaXJlY3Rvcnk6IFsgJ2RpcjInXVxuICogICAgICAgICAvLyB9XG4gKiAgICAgICAgIC8vIHJlc3VsdCBpcyBvYmplY3QgY29udGFpbmluZyB0aGUgZmlsZXMgZ3JvdXBlZCBieSB0eXBlXG4gKiAgICAgfVxuICogfSk7XG4gKlxuICogLy8gVXNpbmcgUHJvbWlzZXNcbiAqIGFzeW5jLmdyb3VwQnkoZmlsZXMsIGRldGVjdEZpbGUpXG4gKiAudGhlbiggcmVzdWx0ID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhyZXN1bHQpO1xuICogICAgIC8vIHtcbiAqICAgICAvLyAgICAgZmlsZTogWyAnZGlyMS9maWxlMS50eHQnIF0sXG4gKiAgICAgLy8gICAgIG5vbmU6IFsgJ2RpcjQnIF0sXG4gKiAgICAgLy8gICAgIGRpcmVjdG9yeTogWyAnZGlyMiddXG4gKiAgICAgLy8gfVxuICogICAgIC8vIHJlc3VsdCBpcyBvYmplY3QgY29udGFpbmluZyB0aGUgZmlsZXMgZ3JvdXBlZCBieSB0eXBlXG4gKiB9KS5jYXRjaCggZXJyID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogfSk7XG4gKlxuICogLy8gVXNpbmcgYXN5bmMvYXdhaXRcbiAqIGFzeW5jICgpID0+IHtcbiAqICAgICB0cnkge1xuICogICAgICAgICBsZXQgcmVzdWx0ID0gYXdhaXQgYXN5bmMuZ3JvdXBCeShmaWxlcywgZGV0ZWN0RmlsZSk7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdCk7XG4gKiAgICAgICAgIC8vIHtcbiAqICAgICAgICAgLy8gICAgIGZpbGU6IFsgJ2RpcjEvZmlsZTEudHh0JyBdLFxuICogICAgICAgICAvLyAgICAgbm9uZTogWyAnZGlyNCcgXSxcbiAqICAgICAgICAgLy8gICAgIGRpcmVjdG9yeTogWyAnZGlyMiddXG4gKiAgICAgICAgIC8vIH1cbiAqICAgICAgICAgLy8gcmVzdWx0IGlzIG9iamVjdCBjb250YWluaW5nIHRoZSBmaWxlcyBncm91cGVkIGJ5IHR5cGVcbiAqICAgICB9XG4gKiAgICAgY2F0Y2ggKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgIH1cbiAqIH1cbiAqXG4gKi9cbmZ1bmN0aW9uIGdyb3VwQnkgKGNvbGwsIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiBncm91cEJ5TGltaXQkMShjb2xsLCBJbmZpbml0eSwgaXRlcmF0ZWUsIGNhbGxiYWNrKVxufVxuXG4vKipcbiAqIFRoZSBzYW1lIGFzIFtgZ3JvdXBCeWBde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5ncm91cEJ5fSBidXQgcnVucyBvbmx5IGEgc2luZ2xlIGFzeW5jIG9wZXJhdGlvbiBhdCBhIHRpbWUuXG4gKlxuICogQG5hbWUgZ3JvdXBCeVNlcmllc1xuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb2xsZWN0aW9uc1xuICogQG1ldGhvZFxuICogQHNlZSBbYXN5bmMuZ3JvdXBCeV17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLmdyb3VwQnl9XG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxJdGVyYWJsZXxBc3luY0l0ZXJhYmxlfE9iamVjdH0gY29sbCAtIEEgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IGl0ZXJhdGVlIC0gQW4gYXN5bmMgZnVuY3Rpb24gdG8gYXBwbHkgdG8gZWFjaCBpdGVtIGluXG4gKiBgY29sbGAuXG4gKiBUaGUgaXRlcmF0ZWUgc2hvdWxkIGNvbXBsZXRlIHdpdGggYSBga2V5YCB0byBncm91cCB0aGUgdmFsdWUgdW5kZXIuXG4gKiBJbnZva2VkIHdpdGggKHZhbHVlLCBjYWxsYmFjaykuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdIC0gQSBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgd2hlbiBhbGwgYGl0ZXJhdGVlYFxuICogZnVuY3Rpb25zIGhhdmUgZmluaXNoZWQsIG9yIGFuIGVycm9yIG9jY3Vycy4gUmVzdWx0IGlzIGFuIGBPYmplY3RgIHdob3NlXG4gKiBwcm9wZXJ0aWVzIGFyZSBhcnJheXMgb2YgdmFsdWVzIHdoaWNoIHJldHVybmVkIHRoZSBjb3JyZXNwb25kaW5nIGtleS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIG5vIGNhbGxiYWNrIGlzIHBhc3NlZFxuICovXG5mdW5jdGlvbiBncm91cEJ5U2VyaWVzIChjb2xsLCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gZ3JvdXBCeUxpbWl0JDEoY29sbCwgMSwgaXRlcmF0ZWUsIGNhbGxiYWNrKVxufVxuXG4vKipcbiAqIExvZ3MgdGhlIHJlc3VsdCBvZiBhbiBgYXN5bmNgIGZ1bmN0aW9uIHRvIHRoZSBgY29uc29sZWAuIE9ubHkgd29ya3MgaW5cbiAqIE5vZGUuanMgb3IgaW4gYnJvd3NlcnMgdGhhdCBzdXBwb3J0IGBjb25zb2xlLmxvZ2AgYW5kIGBjb25zb2xlLmVycm9yYCAoc3VjaFxuICogYXMgRkYgYW5kIENocm9tZSkuIElmIG11bHRpcGxlIGFyZ3VtZW50cyBhcmUgcmV0dXJuZWQgZnJvbSB0aGUgYXN5bmNcbiAqIGZ1bmN0aW9uLCBgY29uc29sZS5sb2dgIGlzIGNhbGxlZCBvbiBlYWNoIGFyZ3VtZW50IGluIG9yZGVyLlxuICpcbiAqIEBuYW1lIGxvZ1xuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpVdGlsc1xuICogQG1ldGhvZFxuICogQGNhdGVnb3J5IFV0aWxcbiAqIEBwYXJhbSB7QXN5bmNGdW5jdGlvbn0gZnVuY3Rpb24gLSBUaGUgZnVuY3Rpb24geW91IHdhbnQgdG8gZXZlbnR1YWxseSBhcHBseVxuICogYWxsIGFyZ3VtZW50cyB0by5cbiAqIEBwYXJhbSB7Li4uKn0gYXJndW1lbnRzLi4uIC0gQW55IG51bWJlciBvZiBhcmd1bWVudHMgdG8gYXBwbHkgdG8gdGhlIGZ1bmN0aW9uLlxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBpbiBhIG1vZHVsZVxuICogdmFyIGhlbGxvID0gZnVuY3Rpb24obmFtZSwgY2FsbGJhY2spIHtcbiAqICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICogICAgICAgICBjYWxsYmFjayhudWxsLCAnaGVsbG8gJyArIG5hbWUpO1xuICogICAgIH0sIDEwMDApO1xuICogfTtcbiAqXG4gKiAvLyBpbiB0aGUgbm9kZSByZXBsXG4gKiBub2RlPiBhc3luYy5sb2coaGVsbG8sICd3b3JsZCcpO1xuICogJ2hlbGxvIHdvcmxkJ1xuICovXG52YXIgbG9nID0gY29uc29sZUZ1bmMoJ2xvZycpO1xuXG4vKipcbiAqIFRoZSBzYW1lIGFzIFtgbWFwVmFsdWVzYF17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLm1hcFZhbHVlc30gYnV0IHJ1bnMgYSBtYXhpbXVtIG9mIGBsaW1pdGAgYXN5bmMgb3BlcmF0aW9ucyBhdCBhXG4gKiB0aW1lLlxuICpcbiAqIEBuYW1lIG1hcFZhbHVlc0xpbWl0XG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbGxlY3Rpb25zXG4gKiBAbWV0aG9kXG4gKiBAc2VlIFthc3luYy5tYXBWYWx1ZXNde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5tYXBWYWx1ZXN9XG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtPYmplY3R9IG9iaiAtIEEgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge251bWJlcn0gbGltaXQgLSBUaGUgbWF4aW11bSBudW1iZXIgb2YgYXN5bmMgb3BlcmF0aW9ucyBhdCBhIHRpbWUuXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IGl0ZXJhdGVlIC0gQSBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIHZhbHVlIGFuZCBrZXlcbiAqIGluIGBjb2xsYC5cbiAqIFRoZSBpdGVyYXRlZSBzaG91bGQgY29tcGxldGUgd2l0aCB0aGUgdHJhbnNmb3JtZWQgdmFsdWUgYXMgaXRzIHJlc3VsdC5cbiAqIEludm9rZWQgd2l0aCAodmFsdWUsIGtleSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIHdoZW4gYWxsIGBpdGVyYXRlZWBcbiAqIGZ1bmN0aW9ucyBoYXZlIGZpbmlzaGVkLCBvciBhbiBlcnJvciBvY2N1cnMuIGByZXN1bHRgIGlzIGEgbmV3IG9iamVjdCBjb25zaXN0aW5nXG4gKiBvZiBlYWNoIGtleSBmcm9tIGBvYmpgLCB3aXRoIGVhY2ggdHJhbnNmb3JtZWQgdmFsdWUgb24gdGhlIHJpZ2h0LWhhbmQgc2lkZS5cbiAqIEludm9rZWQgd2l0aCAoZXJyLCByZXN1bHQpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgbm8gY2FsbGJhY2sgaXMgcGFzc2VkXG4gKi9cbmZ1bmN0aW9uIG1hcFZhbHVlc0xpbWl0KG9iaiwgbGltaXQsIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gb25jZShjYWxsYmFjayk7XG4gICAgdmFyIG5ld09iaiA9IHt9O1xuICAgIHZhciBfaXRlcmF0ZWUgPSB3cmFwQXN5bmMoaXRlcmF0ZWUpO1xuICAgIHJldHVybiBlYWNoT2ZMaW1pdCQyKGxpbWl0KShvYmosICh2YWwsIGtleSwgbmV4dCkgPT4ge1xuICAgICAgICBfaXRlcmF0ZWUodmFsLCBrZXksIChlcnIsIHJlc3VsdCkgPT4ge1xuICAgICAgICAgICAgaWYgKGVycikgcmV0dXJuIG5leHQoZXJyKTtcbiAgICAgICAgICAgIG5ld09ialtrZXldID0gcmVzdWx0O1xuICAgICAgICAgICAgbmV4dChlcnIpO1xuICAgICAgICB9KTtcbiAgICB9LCBlcnIgPT4gY2FsbGJhY2soZXJyLCBuZXdPYmopKTtcbn1cblxudmFyIG1hcFZhbHVlc0xpbWl0JDEgPSBhd2FpdGlmeShtYXBWYWx1ZXNMaW1pdCwgNCk7XG5cbi8qKlxuICogQSByZWxhdGl2ZSBvZiBbYG1hcGBde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5tYXB9LCBkZXNpZ25lZCBmb3IgdXNlIHdpdGggb2JqZWN0cy5cbiAqXG4gKiBQcm9kdWNlcyBhIG5ldyBPYmplY3QgYnkgbWFwcGluZyBlYWNoIHZhbHVlIG9mIGBvYmpgIHRocm91Z2ggdGhlIGBpdGVyYXRlZWBcbiAqIGZ1bmN0aW9uLiBUaGUgYGl0ZXJhdGVlYCBpcyBjYWxsZWQgZWFjaCBgdmFsdWVgIGFuZCBga2V5YCBmcm9tIGBvYmpgIGFuZCBhXG4gKiBjYWxsYmFjayBmb3Igd2hlbiBpdCBoYXMgZmluaXNoZWQgcHJvY2Vzc2luZy4gRWFjaCBvZiB0aGVzZSBjYWxsYmFja3MgdGFrZXNcbiAqIHR3byBhcmd1bWVudHM6IGFuIGBlcnJvcmAsIGFuZCB0aGUgdHJhbnNmb3JtZWQgaXRlbSBmcm9tIGBvYmpgLiBJZiBgaXRlcmF0ZWVgXG4gKiBwYXNzZXMgYW4gZXJyb3IgdG8gaXRzIGNhbGxiYWNrLCB0aGUgbWFpbiBgY2FsbGJhY2tgIChmb3IgdGhlIGBtYXBWYWx1ZXNgXG4gKiBmdW5jdGlvbikgaXMgaW1tZWRpYXRlbHkgY2FsbGVkIHdpdGggdGhlIGVycm9yLlxuICpcbiAqIE5vdGUsIHRoZSBvcmRlciBvZiB0aGUga2V5cyBpbiB0aGUgcmVzdWx0IGlzIG5vdCBndWFyYW50ZWVkLiAgVGhlIGtleXMgd2lsbFxuICogYmUgcm91Z2hseSBpbiB0aGUgb3JkZXIgdGhleSBjb21wbGV0ZSwgKGJ1dCB0aGlzIGlzIHZlcnkgZW5naW5lLXNwZWNpZmljKVxuICpcbiAqIEBuYW1lIG1hcFZhbHVlc1xuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb2xsZWN0aW9uc1xuICogQG1ldGhvZFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEEgZnVuY3Rpb24gdG8gYXBwbHkgdG8gZWFjaCB2YWx1ZSBhbmQga2V5XG4gKiBpbiBgY29sbGAuXG4gKiBUaGUgaXRlcmF0ZWUgc2hvdWxkIGNvbXBsZXRlIHdpdGggdGhlIHRyYW5zZm9ybWVkIHZhbHVlIGFzIGl0cyByZXN1bHQuXG4gKiBJbnZva2VkIHdpdGggKHZhbHVlLCBrZXksIGNhbGxiYWNrKS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYWxsYmFja10gLSBBIGNhbGxiYWNrIHdoaWNoIGlzIGNhbGxlZCB3aGVuIGFsbCBgaXRlcmF0ZWVgXG4gKiBmdW5jdGlvbnMgaGF2ZSBmaW5pc2hlZCwgb3IgYW4gZXJyb3Igb2NjdXJzLiBgcmVzdWx0YCBpcyBhIG5ldyBvYmplY3QgY29uc2lzdGluZ1xuICogb2YgZWFjaCBrZXkgZnJvbSBgb2JqYCwgd2l0aCBlYWNoIHRyYW5zZm9ybWVkIHZhbHVlIG9uIHRoZSByaWdodC1oYW5kIHNpZGUuXG4gKiBJbnZva2VkIHdpdGggKGVyciwgcmVzdWx0KS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIG5vIGNhbGxiYWNrIGlzIHBhc3NlZFxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBmaWxlMS50eHQgaXMgYSBmaWxlIHRoYXQgaXMgMTAwMCBieXRlcyBpbiBzaXplXG4gKiAvLyBmaWxlMi50eHQgaXMgYSBmaWxlIHRoYXQgaXMgMjAwMCBieXRlcyBpbiBzaXplXG4gKiAvLyBmaWxlMy50eHQgaXMgYSBmaWxlIHRoYXQgaXMgMzAwMCBieXRlcyBpbiBzaXplXG4gKiAvLyBmaWxlNC50eHQgZG9lcyBub3QgZXhpc3RcbiAqXG4gKiBjb25zdCBmaWxlTWFwID0ge1xuICogICAgIGYxOiAnZmlsZTEudHh0JyxcbiAqICAgICBmMjogJ2ZpbGUyLnR4dCcsXG4gKiAgICAgZjM6ICdmaWxlMy50eHQnXG4gKiB9O1xuICpcbiAqIGNvbnN0IHdpdGhNaXNzaW5nRmlsZU1hcCA9IHtcbiAqICAgICBmMTogJ2ZpbGUxLnR4dCcsXG4gKiAgICAgZjI6ICdmaWxlMi50eHQnLFxuICogICAgIGYzOiAnZmlsZTQudHh0J1xuICogfTtcbiAqXG4gKiAvLyBhc3luY2hyb25vdXMgZnVuY3Rpb24gdGhhdCByZXR1cm5zIHRoZSBmaWxlIHNpemUgaW4gYnl0ZXNcbiAqIGZ1bmN0aW9uIGdldEZpbGVTaXplSW5CeXRlcyhmaWxlLCBrZXksIGNhbGxiYWNrKSB7XG4gKiAgICAgZnMuc3RhdChmaWxlLCBmdW5jdGlvbihlcnIsIHN0YXQpIHtcbiAqICAgICAgICAgaWYgKGVycikge1xuICogICAgICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gKiAgICAgICAgIH1cbiAqICAgICAgICAgY2FsbGJhY2sobnVsbCwgc3RhdC5zaXplKTtcbiAqICAgICB9KTtcbiAqIH1cbiAqXG4gKiAvLyBVc2luZyBjYWxsYmFja3NcbiAqIGFzeW5jLm1hcFZhbHVlcyhmaWxlTWFwLCBnZXRGaWxlU2l6ZUluQnl0ZXMsIGZ1bmN0aW9uKGVyciwgcmVzdWx0KSB7XG4gKiAgICAgaWYgKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgIH0gZWxzZSB7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdCk7XG4gKiAgICAgICAgIC8vIHJlc3VsdCBpcyBub3cgYSBtYXAgb2YgZmlsZSBzaXplIGluIGJ5dGVzIGZvciBlYWNoIGZpbGUsIGUuZy5cbiAqICAgICAgICAgLy8ge1xuICogICAgICAgICAvLyAgICAgZjE6IDEwMDAsXG4gKiAgICAgICAgIC8vICAgICBmMjogMjAwMCxcbiAqICAgICAgICAgLy8gICAgIGYzOiAzMDAwXG4gKiAgICAgICAgIC8vIH1cbiAqICAgICB9XG4gKiB9KTtcbiAqXG4gKiAvLyBFcnJvciBoYW5kbGluZ1xuICogYXN5bmMubWFwVmFsdWVzKHdpdGhNaXNzaW5nRmlsZU1hcCwgZ2V0RmlsZVNpemVJbkJ5dGVzLCBmdW5jdGlvbihlcnIsIHJlc3VsdCkge1xuICogICAgIGlmIChlcnIpIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICAgICAgLy8gWyBFcnJvcjogRU5PRU5UOiBubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5IF1cbiAqICAgICB9IGVsc2Uge1xuICogICAgICAgICBjb25zb2xlLmxvZyhyZXN1bHQpO1xuICogICAgIH1cbiAqIH0pO1xuICpcbiAqIC8vIFVzaW5nIFByb21pc2VzXG4gKiBhc3luYy5tYXBWYWx1ZXMoZmlsZU1hcCwgZ2V0RmlsZVNpemVJbkJ5dGVzKVxuICogLnRoZW4oIHJlc3VsdCA9PiB7XG4gKiAgICAgY29uc29sZS5sb2cocmVzdWx0KTtcbiAqICAgICAvLyByZXN1bHQgaXMgbm93IGEgbWFwIG9mIGZpbGUgc2l6ZSBpbiBieXRlcyBmb3IgZWFjaCBmaWxlLCBlLmcuXG4gKiAgICAgLy8ge1xuICogICAgIC8vICAgICBmMTogMTAwMCxcbiAqICAgICAvLyAgICAgZjI6IDIwMDAsXG4gKiAgICAgLy8gICAgIGYzOiAzMDAwXG4gKiAgICAgLy8gfVxuICogfSkuY2F0Y2ggKGVyciA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqIH0pO1xuICpcbiAqIC8vIEVycm9yIEhhbmRsaW5nXG4gKiBhc3luYy5tYXBWYWx1ZXMod2l0aE1pc3NpbmdGaWxlTWFwLCBnZXRGaWxlU2l6ZUluQnl0ZXMpXG4gKiAudGhlbiggcmVzdWx0ID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhyZXN1bHQpO1xuICogfSkuY2F0Y2ggKGVyciA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICAvLyBbIEVycm9yOiBFTk9FTlQ6IG5vIHN1Y2ggZmlsZSBvciBkaXJlY3RvcnkgXVxuICogfSk7XG4gKlxuICogLy8gVXNpbmcgYXN5bmMvYXdhaXRcbiAqIGFzeW5jICgpID0+IHtcbiAqICAgICB0cnkge1xuICogICAgICAgICBsZXQgcmVzdWx0ID0gYXdhaXQgYXN5bmMubWFwVmFsdWVzKGZpbGVNYXAsIGdldEZpbGVTaXplSW5CeXRlcyk7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdCk7XG4gKiAgICAgICAgIC8vIHJlc3VsdCBpcyBub3cgYSBtYXAgb2YgZmlsZSBzaXplIGluIGJ5dGVzIGZvciBlYWNoIGZpbGUsIGUuZy5cbiAqICAgICAgICAgLy8ge1xuICogICAgICAgICAvLyAgICAgZjE6IDEwMDAsXG4gKiAgICAgICAgIC8vICAgICBmMjogMjAwMCxcbiAqICAgICAgICAgLy8gICAgIGYzOiAzMDAwXG4gKiAgICAgICAgIC8vIH1cbiAqICAgICB9XG4gKiAgICAgY2F0Y2ggKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgIH1cbiAqIH1cbiAqXG4gKiAvLyBFcnJvciBIYW5kbGluZ1xuICogYXN5bmMgKCkgPT4ge1xuICogICAgIHRyeSB7XG4gKiAgICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCBhc3luYy5tYXBWYWx1ZXMod2l0aE1pc3NpbmdGaWxlTWFwLCBnZXRGaWxlU2l6ZUluQnl0ZXMpO1xuICogICAgICAgICBjb25zb2xlLmxvZyhyZXN1bHQpO1xuICogICAgIH1cbiAqICAgICBjYXRjaCAoZXJyKSB7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiAgICAgICAgIC8vIFsgRXJyb3I6IEVOT0VOVDogbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeSBdXG4gKiAgICAgfVxuICogfVxuICpcbiAqL1xuZnVuY3Rpb24gbWFwVmFsdWVzKG9iaiwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIG1hcFZhbHVlc0xpbWl0JDEob2JqLCBJbmZpbml0eSwgaXRlcmF0ZWUsIGNhbGxiYWNrKVxufVxuXG4vKipcbiAqIFRoZSBzYW1lIGFzIFtgbWFwVmFsdWVzYF17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLm1hcFZhbHVlc30gYnV0IHJ1bnMgb25seSBhIHNpbmdsZSBhc3luYyBvcGVyYXRpb24gYXQgYSB0aW1lLlxuICpcbiAqIEBuYW1lIG1hcFZhbHVlc1Nlcmllc1xuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb2xsZWN0aW9uc1xuICogQG1ldGhvZFxuICogQHNlZSBbYXN5bmMubWFwVmFsdWVzXXtAbGluayBtb2R1bGU6Q29sbGVjdGlvbnMubWFwVmFsdWVzfVxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7T2JqZWN0fSBvYmogLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEEgZnVuY3Rpb24gdG8gYXBwbHkgdG8gZWFjaCB2YWx1ZSBhbmQga2V5XG4gKiBpbiBgY29sbGAuXG4gKiBUaGUgaXRlcmF0ZWUgc2hvdWxkIGNvbXBsZXRlIHdpdGggdGhlIHRyYW5zZm9ybWVkIHZhbHVlIGFzIGl0cyByZXN1bHQuXG4gKiBJbnZva2VkIHdpdGggKHZhbHVlLCBrZXksIGNhbGxiYWNrKS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYWxsYmFja10gLSBBIGNhbGxiYWNrIHdoaWNoIGlzIGNhbGxlZCB3aGVuIGFsbCBgaXRlcmF0ZWVgXG4gKiBmdW5jdGlvbnMgaGF2ZSBmaW5pc2hlZCwgb3IgYW4gZXJyb3Igb2NjdXJzLiBgcmVzdWx0YCBpcyBhIG5ldyBvYmplY3QgY29uc2lzdGluZ1xuICogb2YgZWFjaCBrZXkgZnJvbSBgb2JqYCwgd2l0aCBlYWNoIHRyYW5zZm9ybWVkIHZhbHVlIG9uIHRoZSByaWdodC1oYW5kIHNpZGUuXG4gKiBJbnZva2VkIHdpdGggKGVyciwgcmVzdWx0KS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIG5vIGNhbGxiYWNrIGlzIHBhc3NlZFxuICovXG5mdW5jdGlvbiBtYXBWYWx1ZXNTZXJpZXMob2JqLCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gbWFwVmFsdWVzTGltaXQkMShvYmosIDEsIGl0ZXJhdGVlLCBjYWxsYmFjaylcbn1cblxuLyoqXG4gKiBDYWNoZXMgdGhlIHJlc3VsdHMgb2YgYW4gYXN5bmMgZnVuY3Rpb24uIFdoZW4gY3JlYXRpbmcgYSBoYXNoIHRvIHN0b3JlXG4gKiBmdW5jdGlvbiByZXN1bHRzIGFnYWluc3QsIHRoZSBjYWxsYmFjayBpcyBvbWl0dGVkIGZyb20gdGhlIGhhc2ggYW5kIGFuXG4gKiBvcHRpb25hbCBoYXNoIGZ1bmN0aW9uIGNhbiBiZSB1c2VkLlxuICpcbiAqICoqTm90ZTogaWYgdGhlIGFzeW5jIGZ1bmN0aW9uIGVycnMsIHRoZSByZXN1bHQgd2lsbCBub3QgYmUgY2FjaGVkIGFuZFxuICogc3Vic2VxdWVudCBjYWxscyB3aWxsIGNhbGwgdGhlIHdyYXBwZWQgZnVuY3Rpb24uKipcbiAqXG4gKiBJZiBubyBoYXNoIGZ1bmN0aW9uIGlzIHNwZWNpZmllZCwgdGhlIGZpcnN0IGFyZ3VtZW50IGlzIHVzZWQgYXMgYSBoYXNoIGtleSxcbiAqIHdoaWNoIG1heSB3b3JrIHJlYXNvbmFibHkgaWYgaXQgaXMgYSBzdHJpbmcgb3IgYSBkYXRhIHR5cGUgdGhhdCBjb252ZXJ0cyB0byBhXG4gKiBkaXN0aW5jdCBzdHJpbmcuIE5vdGUgdGhhdCBvYmplY3RzIGFuZCBhcnJheXMgd2lsbCBub3QgYmVoYXZlIHJlYXNvbmFibHkuXG4gKiBOZWl0aGVyIHdpbGwgY2FzZXMgd2hlcmUgdGhlIG90aGVyIGFyZ3VtZW50cyBhcmUgc2lnbmlmaWNhbnQuIEluIHN1Y2ggY2FzZXMsXG4gKiBzcGVjaWZ5IHlvdXIgb3duIGhhc2ggZnVuY3Rpb24uXG4gKlxuICogVGhlIGNhY2hlIG9mIHJlc3VsdHMgaXMgZXhwb3NlZCBhcyB0aGUgYG1lbW9gIHByb3BlcnR5IG9mIHRoZSBmdW5jdGlvblxuICogcmV0dXJuZWQgYnkgYG1lbW9pemVgLlxuICpcbiAqIEBuYW1lIG1lbW9pemVcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6VXRpbHNcbiAqIEBtZXRob2RcbiAqIEBjYXRlZ29yeSBVdGlsXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IGZuIC0gVGhlIGFzeW5jIGZ1bmN0aW9uIHRvIHByb3h5IGFuZCBjYWNoZSByZXN1bHRzIGZyb20uXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYXNoZXIgLSBBbiBvcHRpb25hbCBmdW5jdGlvbiBmb3IgZ2VuZXJhdGluZyBhIGN1c3RvbSBoYXNoXG4gKiBmb3Igc3RvcmluZyByZXN1bHRzLiBJdCBoYXMgYWxsIHRoZSBhcmd1bWVudHMgYXBwbGllZCB0byBpdCBhcGFydCBmcm9tIHRoZVxuICogY2FsbGJhY2ssIGFuZCBtdXN0IGJlIHN5bmNocm9ub3VzLlxuICogQHJldHVybnMge0FzeW5jRnVuY3Rpb259IGEgbWVtb2l6ZWQgdmVyc2lvbiBvZiBgZm5gXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBzbG93X2ZuID0gZnVuY3Rpb24obmFtZSwgY2FsbGJhY2spIHtcbiAqICAgICAvLyBkbyBzb21ldGhpbmdcbiAqICAgICBjYWxsYmFjayhudWxsLCByZXN1bHQpO1xuICogfTtcbiAqIHZhciBmbiA9IGFzeW5jLm1lbW9pemUoc2xvd19mbik7XG4gKlxuICogLy8gZm4gY2FuIG5vdyBiZSB1c2VkIGFzIGlmIGl0IHdlcmUgc2xvd19mblxuICogZm4oJ3NvbWUgbmFtZScsIGZ1bmN0aW9uKCkge1xuICogICAgIC8vIGNhbGxiYWNrXG4gKiB9KTtcbiAqL1xuZnVuY3Rpb24gbWVtb2l6ZShmbiwgaGFzaGVyID0gdiA9PiB2KSB7XG4gICAgdmFyIG1lbW8gPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHZhciBxdWV1ZXMgPSBPYmplY3QuY3JlYXRlKG51bGwpO1xuICAgIHZhciBfZm4gPSB3cmFwQXN5bmMoZm4pO1xuICAgIHZhciBtZW1vaXplZCA9IGluaXRpYWxQYXJhbXMoKGFyZ3MsIGNhbGxiYWNrKSA9PiB7XG4gICAgICAgIHZhciBrZXkgPSBoYXNoZXIoLi4uYXJncyk7XG4gICAgICAgIGlmIChrZXkgaW4gbWVtbykge1xuICAgICAgICAgICAgc2V0SW1tZWRpYXRlJDEoKCkgPT4gY2FsbGJhY2sobnVsbCwgLi4ubWVtb1trZXldKSk7XG4gICAgICAgIH0gZWxzZSBpZiAoa2V5IGluIHF1ZXVlcykge1xuICAgICAgICAgICAgcXVldWVzW2tleV0ucHVzaChjYWxsYmFjayk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBxdWV1ZXNba2V5XSA9IFtjYWxsYmFja107XG4gICAgICAgICAgICBfZm4oLi4uYXJncywgKGVyciwgLi4ucmVzdWx0QXJncykgPT4ge1xuICAgICAgICAgICAgICAgIC8vICMxNDY1IGRvbid0IG1lbW9pemUgaWYgYW4gZXJyb3Igb2NjdXJyZWRcbiAgICAgICAgICAgICAgICBpZiAoIWVycikge1xuICAgICAgICAgICAgICAgICAgICBtZW1vW2tleV0gPSByZXN1bHRBcmdzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB2YXIgcSA9IHF1ZXVlc1trZXldO1xuICAgICAgICAgICAgICAgIGRlbGV0ZSBxdWV1ZXNba2V5XTtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbCA9IHEubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHFbaV0oZXJyLCAuLi5yZXN1bHRBcmdzKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH0pO1xuICAgIG1lbW9pemVkLm1lbW8gPSBtZW1vO1xuICAgIG1lbW9pemVkLnVubWVtb2l6ZWQgPSBmbjtcbiAgICByZXR1cm4gbWVtb2l6ZWQ7XG59XG5cbi8qIGlzdGFuYnVsIGlnbm9yZSBmaWxlICovXG5cbi8qKlxuICogQ2FsbHMgYGNhbGxiYWNrYCBvbiBhIGxhdGVyIGxvb3AgYXJvdW5kIHRoZSBldmVudCBsb29wLiBJbiBOb2RlLmpzIHRoaXMganVzdFxuICogY2FsbHMgYHByb2Nlc3MubmV4dFRpY2tgLiAgSW4gdGhlIGJyb3dzZXIgaXQgd2lsbCB1c2UgYHNldEltbWVkaWF0ZWAgaWZcbiAqIGF2YWlsYWJsZSwgb3RoZXJ3aXNlIGBzZXRUaW1lb3V0KGNhbGxiYWNrLCAwKWAsIHdoaWNoIG1lYW5zIG90aGVyIGhpZ2hlclxuICogcHJpb3JpdHkgZXZlbnRzIG1heSBwcmVjZWRlIHRoZSBleGVjdXRpb24gb2YgYGNhbGxiYWNrYC5cbiAqXG4gKiBUaGlzIGlzIHVzZWQgaW50ZXJuYWxseSBmb3IgYnJvd3Nlci1jb21wYXRpYmlsaXR5IHB1cnBvc2VzLlxuICpcbiAqIEBuYW1lIG5leHRUaWNrXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOlV0aWxzXG4gKiBAbWV0aG9kXG4gKiBAc2VlIFthc3luYy5zZXRJbW1lZGlhdGVde0BsaW5rIG1vZHVsZTpVdGlscy5zZXRJbW1lZGlhdGV9XG4gKiBAY2F0ZWdvcnkgVXRpbFxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgLSBUaGUgZnVuY3Rpb24gdG8gY2FsbCBvbiBhIGxhdGVyIGxvb3AgYXJvdW5kXG4gKiB0aGUgZXZlbnQgbG9vcC4gSW52b2tlZCB3aXRoIChhcmdzLi4uKS5cbiAqIEBwYXJhbSB7Li4uKn0gYXJncy4uLiAtIGFueSBudW1iZXIgb2YgYWRkaXRpb25hbCBhcmd1bWVudHMgdG8gcGFzcyB0byB0aGVcbiAqIGNhbGxiYWNrIG9uIHRoZSBuZXh0IHRpY2suXG4gKiBAZXhhbXBsZVxuICpcbiAqIHZhciBjYWxsX29yZGVyID0gW107XG4gKiBhc3luYy5uZXh0VGljayhmdW5jdGlvbigpIHtcbiAqICAgICBjYWxsX29yZGVyLnB1c2goJ3R3bycpO1xuICogICAgIC8vIGNhbGxfb3JkZXIgbm93IGVxdWFscyBbJ29uZScsJ3R3byddXG4gKiB9KTtcbiAqIGNhbGxfb3JkZXIucHVzaCgnb25lJyk7XG4gKlxuICogYXN5bmMuc2V0SW1tZWRpYXRlKGZ1bmN0aW9uIChhLCBiLCBjKSB7XG4gKiAgICAgLy8gYSwgYiwgYW5kIGMgZXF1YWwgMSwgMiwgYW5kIDNcbiAqIH0sIDEsIDIsIDMpO1xuICovXG52YXIgX2RlZmVyO1xuXG5pZiAoaGFzTmV4dFRpY2spIHtcbiAgICBfZGVmZXIgPSBwcm9jZXNzLm5leHRUaWNrO1xufSBlbHNlIGlmIChoYXNTZXRJbW1lZGlhdGUpIHtcbiAgICBfZGVmZXIgPSBzZXRJbW1lZGlhdGU7XG59IGVsc2Uge1xuICAgIF9kZWZlciA9IGZhbGxiYWNrO1xufVxuXG52YXIgbmV4dFRpY2sgPSB3cmFwKF9kZWZlcik7XG5cbnZhciBfcGFyYWxsZWwgPSBhd2FpdGlmeSgoZWFjaGZuLCB0YXNrcywgY2FsbGJhY2spID0+IHtcbiAgICB2YXIgcmVzdWx0cyA9IGlzQXJyYXlMaWtlKHRhc2tzKSA/IFtdIDoge307XG5cbiAgICBlYWNoZm4odGFza3MsICh0YXNrLCBrZXksIHRhc2tDYikgPT4ge1xuICAgICAgICB3cmFwQXN5bmModGFzaykoKGVyciwgLi4ucmVzdWx0KSA9PiB7XG4gICAgICAgICAgICBpZiAocmVzdWx0Lmxlbmd0aCA8IDIpIHtcbiAgICAgICAgICAgICAgICBbcmVzdWx0XSA9IHJlc3VsdDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlc3VsdHNba2V5XSA9IHJlc3VsdDtcbiAgICAgICAgICAgIHRhc2tDYihlcnIpO1xuICAgICAgICB9KTtcbiAgICB9LCBlcnIgPT4gY2FsbGJhY2soZXJyLCByZXN1bHRzKSk7XG59LCAzKTtcblxuLyoqXG4gKiBSdW4gdGhlIGB0YXNrc2AgY29sbGVjdGlvbiBvZiBmdW5jdGlvbnMgaW4gcGFyYWxsZWwsIHdpdGhvdXQgd2FpdGluZyB1bnRpbFxuICogdGhlIHByZXZpb3VzIGZ1bmN0aW9uIGhhcyBjb21wbGV0ZWQuIElmIGFueSBvZiB0aGUgZnVuY3Rpb25zIHBhc3MgYW4gZXJyb3IgdG9cbiAqIGl0cyBjYWxsYmFjaywgdGhlIG1haW4gYGNhbGxiYWNrYCBpcyBpbW1lZGlhdGVseSBjYWxsZWQgd2l0aCB0aGUgdmFsdWUgb2YgdGhlXG4gKiBlcnJvci4gT25jZSB0aGUgYHRhc2tzYCBoYXZlIGNvbXBsZXRlZCwgdGhlIHJlc3VsdHMgYXJlIHBhc3NlZCB0byB0aGUgZmluYWxcbiAqIGBjYWxsYmFja2AgYXMgYW4gYXJyYXkuXG4gKlxuICogKipOb3RlOioqIGBwYXJhbGxlbGAgaXMgYWJvdXQga2lja2luZy1vZmYgSS9PIHRhc2tzIGluIHBhcmFsbGVsLCBub3QgYWJvdXRcbiAqIHBhcmFsbGVsIGV4ZWN1dGlvbiBvZiBjb2RlLiAgSWYgeW91ciB0YXNrcyBkbyBub3QgdXNlIGFueSB0aW1lcnMgb3IgcGVyZm9ybVxuICogYW55IEkvTywgdGhleSB3aWxsIGFjdHVhbGx5IGJlIGV4ZWN1dGVkIGluIHNlcmllcy4gIEFueSBzeW5jaHJvbm91cyBzZXR1cFxuICogc2VjdGlvbnMgZm9yIGVhY2ggdGFzayB3aWxsIGhhcHBlbiBvbmUgYWZ0ZXIgdGhlIG90aGVyLiAgSmF2YVNjcmlwdCByZW1haW5zXG4gKiBzaW5nbGUtdGhyZWFkZWQuXG4gKlxuICogKipIaW50OioqIFVzZSBbYHJlZmxlY3RgXXtAbGluayBtb2R1bGU6VXRpbHMucmVmbGVjdH0gdG8gY29udGludWUgdGhlXG4gKiBleGVjdXRpb24gb2Ygb3RoZXIgdGFza3Mgd2hlbiBhIHRhc2sgZmFpbHMuXG4gKlxuICogSXQgaXMgYWxzbyBwb3NzaWJsZSB0byB1c2UgYW4gb2JqZWN0IGluc3RlYWQgb2YgYW4gYXJyYXkuIEVhY2ggcHJvcGVydHkgd2lsbFxuICogYmUgcnVuIGFzIGEgZnVuY3Rpb24gYW5kIHRoZSByZXN1bHRzIHdpbGwgYmUgcGFzc2VkIHRvIHRoZSBmaW5hbCBgY2FsbGJhY2tgXG4gKiBhcyBhbiBvYmplY3QgaW5zdGVhZCBvZiBhbiBhcnJheS4gVGhpcyBjYW4gYmUgYSBtb3JlIHJlYWRhYmxlIHdheSBvZiBoYW5kbGluZ1xuICogcmVzdWx0cyBmcm9tIHtAbGluayBhc3luYy5wYXJhbGxlbH0uXG4gKlxuICogQG5hbWUgcGFyYWxsZWxcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29udHJvbEZsb3dcbiAqIEBtZXRob2RcbiAqIEBjYXRlZ29yeSBDb250cm9sIEZsb3dcbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IHRhc2tzIC0gQSBjb2xsZWN0aW9uIG9mXG4gKiBbYXN5bmMgZnVuY3Rpb25zXXtAbGluayBBc3luY0Z1bmN0aW9ufSB0byBydW4uXG4gKiBFYWNoIGFzeW5jIGZ1bmN0aW9uIGNhbiBjb21wbGV0ZSB3aXRoIGFueSBudW1iZXIgb2Ygb3B0aW9uYWwgYHJlc3VsdGAgdmFsdWVzLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEFuIG9wdGlvbmFsIGNhbGxiYWNrIHRvIHJ1biBvbmNlIGFsbCB0aGVcbiAqIGZ1bmN0aW9ucyBoYXZlIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkuIFRoaXMgZnVuY3Rpb24gZ2V0cyBhIHJlc3VsdHMgYXJyYXlcbiAqIChvciBvYmplY3QpIGNvbnRhaW5pbmcgYWxsIHRoZSByZXN1bHQgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgdGFzayBjYWxsYmFja3MuXG4gKiBJbnZva2VkIHdpdGggKGVyciwgcmVzdWx0cykuXG4gKiBAcmV0dXJucyB7UHJvbWlzZX0gYSBwcm9taXNlLCBpZiBhIGNhbGxiYWNrIGlzIG5vdCBwYXNzZWRcbiAqXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vVXNpbmcgQ2FsbGJhY2tzXG4gKiBhc3luYy5wYXJhbGxlbChbXG4gKiAgICAgZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAqICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAqICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsICdvbmUnKTtcbiAqICAgICAgICAgfSwgMjAwKTtcbiAqICAgICB9LFxuICogICAgIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCAndHdvJyk7XG4gKiAgICAgICAgIH0sIDEwMCk7XG4gKiAgICAgfVxuICogXSwgZnVuY3Rpb24oZXJyLCByZXN1bHRzKSB7XG4gKiAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiAgICAgLy8gcmVzdWx0cyBpcyBlcXVhbCB0byBbJ29uZScsJ3R3byddIGV2ZW4gdGhvdWdoXG4gKiAgICAgLy8gdGhlIHNlY29uZCBmdW5jdGlvbiBoYWQgYSBzaG9ydGVyIHRpbWVvdXQuXG4gKiB9KTtcbiAqXG4gKiAvLyBhbiBleGFtcGxlIHVzaW5nIGFuIG9iamVjdCBpbnN0ZWFkIG9mIGFuIGFycmF5XG4gKiBhc3luYy5wYXJhbGxlbCh7XG4gKiAgICAgb25lOiBmdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICogICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgMSk7XG4gKiAgICAgICAgIH0sIDIwMCk7XG4gKiAgICAgfSxcbiAqICAgICB0d286IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCAyKTtcbiAqICAgICAgICAgfSwgMTAwKTtcbiAqICAgICB9XG4gKiB9LCBmdW5jdGlvbihlcnIsIHJlc3VsdHMpIHtcbiAqICAgICBjb25zb2xlLmxvZyhyZXN1bHRzKTtcbiAqICAgICAvLyByZXN1bHRzIGlzIGVxdWFsIHRvOiB7IG9uZTogMSwgdHdvOiAyIH1cbiAqIH0pO1xuICpcbiAqIC8vVXNpbmcgUHJvbWlzZXNcbiAqIGFzeW5jLnBhcmFsbGVsKFtcbiAqICAgICBmdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICogICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgJ29uZScpO1xuICogICAgICAgICB9LCAyMDApO1xuICogICAgIH0sXG4gKiAgICAgZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAqICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAqICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsICd0d28nKTtcbiAqICAgICAgICAgfSwgMTAwKTtcbiAqICAgICB9XG4gKiBdKS50aGVuKHJlc3VsdHMgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKHJlc3VsdHMpO1xuICogICAgIC8vIHJlc3VsdHMgaXMgZXF1YWwgdG8gWydvbmUnLCd0d28nXSBldmVuIHRob3VnaFxuICogICAgIC8vIHRoZSBzZWNvbmQgZnVuY3Rpb24gaGFkIGEgc2hvcnRlciB0aW1lb3V0LlxuICogfSkuY2F0Y2goZXJyID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogfSk7XG4gKlxuICogLy8gYW4gZXhhbXBsZSB1c2luZyBhbiBvYmplY3QgaW5zdGVhZCBvZiBhbiBhcnJheVxuICogYXN5bmMucGFyYWxsZWwoe1xuICogICAgIG9uZTogZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAqICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAqICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIDEpO1xuICogICAgICAgICB9LCAyMDApO1xuICogICAgIH0sXG4gKiAgICAgdHdvOiBmdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICogICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgMik7XG4gKiAgICAgICAgIH0sIDEwMCk7XG4gKiAgICAgfVxuICogfSkudGhlbihyZXN1bHRzID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhyZXN1bHRzKTtcbiAqICAgICAvLyByZXN1bHRzIGlzIGVxdWFsIHRvOiB7IG9uZTogMSwgdHdvOiAyIH1cbiAqIH0pLmNhdGNoKGVyciA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqIH0pO1xuICpcbiAqIC8vVXNpbmcgYXN5bmMvYXdhaXRcbiAqIGFzeW5jICgpID0+IHtcbiAqICAgICB0cnkge1xuICogICAgICAgICBsZXQgcmVzdWx0cyA9IGF3YWl0IGFzeW5jLnBhcmFsbGVsKFtcbiAqICAgICAgICAgICAgIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAqICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgJ29uZScpO1xuICogICAgICAgICAgICAgICAgIH0sIDIwMCk7XG4gKiAgICAgICAgICAgICB9LFxuICogICAgICAgICAgICAgZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAqICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICogICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCAndHdvJyk7XG4gKiAgICAgICAgICAgICAgICAgfSwgMTAwKTtcbiAqICAgICAgICAgICAgIH1cbiAqICAgICAgICAgXSk7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdHMpO1xuICogICAgICAgICAvLyByZXN1bHRzIGlzIGVxdWFsIHRvIFsnb25lJywndHdvJ10gZXZlbiB0aG91Z2hcbiAqICAgICAgICAgLy8gdGhlIHNlY29uZCBmdW5jdGlvbiBoYWQgYSBzaG9ydGVyIHRpbWVvdXQuXG4gKiAgICAgfVxuICogICAgIGNhdGNoIChlcnIpIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICB9XG4gKiB9XG4gKlxuICogLy8gYW4gZXhhbXBsZSB1c2luZyBhbiBvYmplY3QgaW5zdGVhZCBvZiBhbiBhcnJheVxuICogYXN5bmMgKCkgPT4ge1xuICogICAgIHRyeSB7XG4gKiAgICAgICAgIGxldCByZXN1bHRzID0gYXdhaXQgYXN5bmMucGFyYWxsZWwoe1xuICogICAgICAgICAgICAgb25lOiBmdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIDEpO1xuICogICAgICAgICAgICAgICAgIH0sIDIwMCk7XG4gKiAgICAgICAgICAgICB9LFxuICogICAgICAgICAgICB0d286IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAqICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgMik7XG4gKiAgICAgICAgICAgICAgICAgfSwgMTAwKTtcbiAqICAgICAgICAgICAgfVxuICogICAgICAgICB9KTtcbiAqICAgICAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiAgICAgICAgIC8vIHJlc3VsdHMgaXMgZXF1YWwgdG86IHsgb25lOiAxLCB0d286IDIgfVxuICogICAgIH1cbiAqICAgICBjYXRjaCAoZXJyKSB7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiAgICAgfVxuICogfVxuICpcbiAqL1xuZnVuY3Rpb24gcGFyYWxsZWwodGFza3MsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIF9wYXJhbGxlbChlYWNoT2YkMSwgdGFza3MsIGNhbGxiYWNrKTtcbn1cblxuLyoqXG4gKiBUaGUgc2FtZSBhcyBbYHBhcmFsbGVsYF17QGxpbmsgbW9kdWxlOkNvbnRyb2xGbG93LnBhcmFsbGVsfSBidXQgcnVucyBhIG1heGltdW0gb2YgYGxpbWl0YCBhc3luYyBvcGVyYXRpb25zIGF0IGFcbiAqIHRpbWUuXG4gKlxuICogQG5hbWUgcGFyYWxsZWxMaW1pdFxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb250cm9sRmxvd1xuICogQG1ldGhvZFxuICogQHNlZSBbYXN5bmMucGFyYWxsZWxde0BsaW5rIG1vZHVsZTpDb250cm9sRmxvdy5wYXJhbGxlbH1cbiAqIEBjYXRlZ29yeSBDb250cm9sIEZsb3dcbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IHRhc2tzIC0gQSBjb2xsZWN0aW9uIG9mXG4gKiBbYXN5bmMgZnVuY3Rpb25zXXtAbGluayBBc3luY0Z1bmN0aW9ufSB0byBydW4uXG4gKiBFYWNoIGFzeW5jIGZ1bmN0aW9uIGNhbiBjb21wbGV0ZSB3aXRoIGFueSBudW1iZXIgb2Ygb3B0aW9uYWwgYHJlc3VsdGAgdmFsdWVzLlxuICogQHBhcmFtIHtudW1iZXJ9IGxpbWl0IC0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGFzeW5jIG9wZXJhdGlvbnMgYXQgYSB0aW1lLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEFuIG9wdGlvbmFsIGNhbGxiYWNrIHRvIHJ1biBvbmNlIGFsbCB0aGVcbiAqIGZ1bmN0aW9ucyBoYXZlIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkuIFRoaXMgZnVuY3Rpb24gZ2V0cyBhIHJlc3VsdHMgYXJyYXlcbiAqIChvciBvYmplY3QpIGNvbnRhaW5pbmcgYWxsIHRoZSByZXN1bHQgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgdGFzayBjYWxsYmFja3MuXG4gKiBJbnZva2VkIHdpdGggKGVyciwgcmVzdWx0cykuXG4gKiBAcmV0dXJucyB7UHJvbWlzZX0gYSBwcm9taXNlLCBpZiBhIGNhbGxiYWNrIGlzIG5vdCBwYXNzZWRcbiAqL1xuZnVuY3Rpb24gcGFyYWxsZWxMaW1pdCh0YXNrcywgbGltaXQsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIF9wYXJhbGxlbChlYWNoT2ZMaW1pdCQyKGxpbWl0KSwgdGFza3MsIGNhbGxiYWNrKTtcbn1cblxuLyoqXG4gKiBBIHF1ZXVlIG9mIHRhc2tzIGZvciB0aGUgd29ya2VyIGZ1bmN0aW9uIHRvIGNvbXBsZXRlLlxuICogQHR5cGVkZWYge0l0ZXJhYmxlfSBRdWV1ZU9iamVjdFxuICogQG1lbWJlck9mIG1vZHVsZTpDb250cm9sRmxvd1xuICogQHByb3BlcnR5IHtGdW5jdGlvbn0gbGVuZ3RoIC0gYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG51bWJlciBvZiBpdGVtc1xuICogd2FpdGluZyB0byBiZSBwcm9jZXNzZWQuIEludm9rZSB3aXRoIGBxdWV1ZS5sZW5ndGgoKWAuXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IHN0YXJ0ZWQgLSBhIGJvb2xlYW4gaW5kaWNhdGluZyB3aGV0aGVyIG9yIG5vdCBhbnlcbiAqIGl0ZW1zIGhhdmUgYmVlbiBwdXNoZWQgYW5kIHByb2Nlc3NlZCBieSB0aGUgcXVldWUuXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBydW5uaW5nIC0gYSBmdW5jdGlvbiByZXR1cm5pbmcgdGhlIG51bWJlciBvZiBpdGVtc1xuICogY3VycmVudGx5IGJlaW5nIHByb2Nlc3NlZC4gSW52b2tlIHdpdGggYHF1ZXVlLnJ1bm5pbmcoKWAuXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSB3b3JrZXJzTGlzdCAtIGEgZnVuY3Rpb24gcmV0dXJuaW5nIHRoZSBhcnJheSBvZiBpdGVtc1xuICogY3VycmVudGx5IGJlaW5nIHByb2Nlc3NlZC4gSW52b2tlIHdpdGggYHF1ZXVlLndvcmtlcnNMaXN0KClgLlxuICogQHByb3BlcnR5IHtGdW5jdGlvbn0gaWRsZSAtIGEgZnVuY3Rpb24gcmV0dXJuaW5nIGZhbHNlIGlmIHRoZXJlIGFyZSBpdGVtc1xuICogd2FpdGluZyBvciBiZWluZyBwcm9jZXNzZWQsIG9yIHRydWUgaWYgbm90LiBJbnZva2Ugd2l0aCBgcXVldWUuaWRsZSgpYC5cbiAqIEBwcm9wZXJ0eSB7bnVtYmVyfSBjb25jdXJyZW5jeSAtIGFuIGludGVnZXIgZm9yIGRldGVybWluaW5nIGhvdyBtYW55IGB3b3JrZXJgXG4gKiBmdW5jdGlvbnMgc2hvdWxkIGJlIHJ1biBpbiBwYXJhbGxlbC4gVGhpcyBwcm9wZXJ0eSBjYW4gYmUgY2hhbmdlZCBhZnRlciBhXG4gKiBgcXVldWVgIGlzIGNyZWF0ZWQgdG8gYWx0ZXIgdGhlIGNvbmN1cnJlbmN5IG9uLXRoZS1mbHkuXG4gKiBAcHJvcGVydHkge251bWJlcn0gcGF5bG9hZCAtIGFuIGludGVnZXIgdGhhdCBzcGVjaWZpZXMgaG93IG1hbnkgaXRlbXMgYXJlXG4gKiBwYXNzZWQgdG8gdGhlIHdvcmtlciBmdW5jdGlvbiBhdCBhIHRpbWUuIG9ubHkgYXBwbGllcyBpZiB0aGlzIGlzIGFcbiAqIFtjYXJnb117QGxpbmsgbW9kdWxlOkNvbnRyb2xGbG93LmNhcmdvfSBvYmplY3RcbiAqIEBwcm9wZXJ0eSB7QXN5bmNGdW5jdGlvbn0gcHVzaCAtIGFkZCBhIG5ldyB0YXNrIHRvIHRoZSBgcXVldWVgLiBDYWxscyBgY2FsbGJhY2tgXG4gKiBvbmNlIHRoZSBgd29ya2VyYCBoYXMgZmluaXNoZWQgcHJvY2Vzc2luZyB0aGUgdGFzay4gSW5zdGVhZCBvZiBhIHNpbmdsZSB0YXNrLFxuICogYSBgdGFza3NgIGFycmF5IGNhbiBiZSBzdWJtaXR0ZWQuIFRoZSByZXNwZWN0aXZlIGNhbGxiYWNrIGlzIHVzZWQgZm9yIGV2ZXJ5XG4gKiB0YXNrIGluIHRoZSBsaXN0LiBJbnZva2Ugd2l0aCBgcXVldWUucHVzaCh0YXNrLCBbY2FsbGJhY2tdKWAsXG4gKiBAcHJvcGVydHkge0FzeW5jRnVuY3Rpb259IHVuc2hpZnQgLSBhZGQgYSBuZXcgdGFzayB0byB0aGUgZnJvbnQgb2YgdGhlIGBxdWV1ZWAuXG4gKiBJbnZva2Ugd2l0aCBgcXVldWUudW5zaGlmdCh0YXNrLCBbY2FsbGJhY2tdKWAuXG4gKiBAcHJvcGVydHkge0FzeW5jRnVuY3Rpb259IHB1c2hBc3luYyAtIHRoZSBzYW1lIGFzIGBxLnB1c2hgLCBleGNlcHQgdGhpcyByZXR1cm5zXG4gKiBhIHByb21pc2UgdGhhdCByZWplY3RzIGlmIGFuIGVycm9yIG9jY3Vycy5cbiAqIEBwcm9wZXJ0eSB7QXN5bmNGdW5jdGlvbn0gdW5zaGlmdEFzeW5jIC0gdGhlIHNhbWUgYXMgYHEudW5zaGlmdGAsIGV4Y2VwdCB0aGlzIHJldHVybnNcbiAqIGEgcHJvbWlzZSB0aGF0IHJlamVjdHMgaWYgYW4gZXJyb3Igb2NjdXJzLlxuICogQHByb3BlcnR5IHtGdW5jdGlvbn0gcmVtb3ZlIC0gcmVtb3ZlIGl0ZW1zIGZyb20gdGhlIHF1ZXVlIHRoYXQgbWF0Y2ggYSB0ZXN0XG4gKiBmdW5jdGlvbi4gIFRoZSB0ZXN0IGZ1bmN0aW9uIHdpbGwgYmUgcGFzc2VkIGFuIG9iamVjdCB3aXRoIGEgYGRhdGFgIHByb3BlcnR5LFxuICogYW5kIGEgYHByaW9yaXR5YCBwcm9wZXJ0eSwgaWYgdGhpcyBpcyBhXG4gKiBbcHJpb3JpdHlRdWV1ZV17QGxpbmsgbW9kdWxlOkNvbnRyb2xGbG93LnByaW9yaXR5UXVldWV9IG9iamVjdC5cbiAqIEludm9rZWQgd2l0aCBgcXVldWUucmVtb3ZlKHRlc3RGbilgLCB3aGVyZSBgdGVzdEZuYCBpcyBvZiB0aGUgZm9ybVxuICogYGZ1bmN0aW9uICh7ZGF0YSwgcHJpb3JpdHl9KSB7fWAgYW5kIHJldHVybnMgYSBCb29sZWFuLlxuICogQHByb3BlcnR5IHtGdW5jdGlvbn0gc2F0dXJhdGVkIC0gYSBmdW5jdGlvbiB0aGF0IHNldHMgYSBjYWxsYmFjayB0aGF0IGlzXG4gKiBjYWxsZWQgd2hlbiB0aGUgbnVtYmVyIG9mIHJ1bm5pbmcgd29ya2VycyBoaXRzIHRoZSBgY29uY3VycmVuY3lgIGxpbWl0LCBhbmRcbiAqIGZ1cnRoZXIgdGFza3Mgd2lsbCBiZSBxdWV1ZWQuICBJZiB0aGUgY2FsbGJhY2sgaXMgb21pdHRlZCwgYHEuc2F0dXJhdGVkKClgXG4gKiByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIG5leHQgb2NjdXJyZW5jZS5cbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IHVuc2F0dXJhdGVkIC0gYSBmdW5jdGlvbiB0aGF0IHNldHMgYSBjYWxsYmFjayB0aGF0IGlzXG4gKiBjYWxsZWQgd2hlbiB0aGUgbnVtYmVyIG9mIHJ1bm5pbmcgd29ya2VycyBpcyBsZXNzIHRoYW4gdGhlIGBjb25jdXJyZW5jeWAgJlxuICogYGJ1ZmZlcmAgbGltaXRzLCBhbmQgZnVydGhlciB0YXNrcyB3aWxsIG5vdCBiZSBxdWV1ZWQuIElmIHRoZSBjYWxsYmFjayBpc1xuICogb21pdHRlZCwgYHEudW5zYXR1cmF0ZWQoKWAgcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSBuZXh0IG9jY3VycmVuY2UuXG4gKiBAcHJvcGVydHkge251bWJlcn0gYnVmZmVyIC0gQSBtaW5pbXVtIHRocmVzaG9sZCBidWZmZXIgaW4gb3JkZXIgdG8gc2F5IHRoYXRcbiAqIHRoZSBgcXVldWVgIGlzIGB1bnNhdHVyYXRlZGAuXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBlbXB0eSAtIGEgZnVuY3Rpb24gdGhhdCBzZXRzIGEgY2FsbGJhY2sgdGhhdCBpcyBjYWxsZWRcbiAqIHdoZW4gdGhlIGxhc3QgaXRlbSBmcm9tIHRoZSBgcXVldWVgIGlzIGdpdmVuIHRvIGEgYHdvcmtlcmAuIElmIHRoZSBjYWxsYmFja1xuICogaXMgb21pdHRlZCwgYHEuZW1wdHkoKWAgcmV0dXJucyBhIHByb21pc2UgZm9yIHRoZSBuZXh0IG9jY3VycmVuY2UuXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBkcmFpbiAtIGEgZnVuY3Rpb24gdGhhdCBzZXRzIGEgY2FsbGJhY2sgdGhhdCBpcyBjYWxsZWRcbiAqIHdoZW4gdGhlIGxhc3QgaXRlbSBmcm9tIHRoZSBgcXVldWVgIGhhcyByZXR1cm5lZCBmcm9tIHRoZSBgd29ya2VyYC4gSWYgdGhlXG4gKiBjYWxsYmFjayBpcyBvbWl0dGVkLCBgcS5kcmFpbigpYCByZXR1cm5zIGEgcHJvbWlzZSBmb3IgdGhlIG5leHQgb2NjdXJyZW5jZS5cbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGVycm9yIC0gYSBmdW5jdGlvbiB0aGF0IHNldHMgYSBjYWxsYmFjayB0aGF0IGlzIGNhbGxlZFxuICogd2hlbiBhIHRhc2sgZXJyb3JzLiBIYXMgdGhlIHNpZ25hdHVyZSBgZnVuY3Rpb24oZXJyb3IsIHRhc2spYC4gSWYgdGhlXG4gKiBjYWxsYmFjayBpcyBvbWl0dGVkLCBgZXJyb3IoKWAgcmV0dXJucyBhIHByb21pc2UgdGhhdCByZWplY3RzIG9uIHRoZSBuZXh0XG4gKiBlcnJvci5cbiAqIEBwcm9wZXJ0eSB7Ym9vbGVhbn0gcGF1c2VkIC0gYSBib29sZWFuIGZvciBkZXRlcm1pbmluZyB3aGV0aGVyIHRoZSBxdWV1ZSBpc1xuICogaW4gYSBwYXVzZWQgc3RhdGUuXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSBwYXVzZSAtIGEgZnVuY3Rpb24gdGhhdCBwYXVzZXMgdGhlIHByb2Nlc3Npbmcgb2YgdGFza3NcbiAqIHVudGlsIGByZXN1bWUoKWAgaXMgY2FsbGVkLiBJbnZva2Ugd2l0aCBgcXVldWUucGF1c2UoKWAuXG4gKiBAcHJvcGVydHkge0Z1bmN0aW9ufSByZXN1bWUgLSBhIGZ1bmN0aW9uIHRoYXQgcmVzdW1lcyB0aGUgcHJvY2Vzc2luZyBvZlxuICogcXVldWVkIHRhc2tzIHdoZW4gdGhlIHF1ZXVlIGlzIHBhdXNlZC4gSW52b2tlIHdpdGggYHF1ZXVlLnJlc3VtZSgpYC5cbiAqIEBwcm9wZXJ0eSB7RnVuY3Rpb259IGtpbGwgLSBhIGZ1bmN0aW9uIHRoYXQgcmVtb3ZlcyB0aGUgYGRyYWluYCBjYWxsYmFjayBhbmRcbiAqIGVtcHRpZXMgcmVtYWluaW5nIHRhc2tzIGZyb20gdGhlIHF1ZXVlIGZvcmNpbmcgaXQgdG8gZ28gaWRsZS4gTm8gbW9yZSB0YXNrc1xuICogc2hvdWxkIGJlIHB1c2hlZCB0byB0aGUgcXVldWUgYWZ0ZXIgY2FsbGluZyB0aGlzIGZ1bmN0aW9uLiBJbnZva2Ugd2l0aCBgcXVldWUua2lsbCgpYC5cbiAqXG4gKiBAZXhhbXBsZVxuICogY29uc3QgcSA9IGFzeW5jLnF1ZXVlKHdvcmtlciwgMilcbiAqIHEucHVzaChpdGVtMSlcbiAqIHEucHVzaChpdGVtMilcbiAqIHEucHVzaChpdGVtMylcbiAqIC8vIHF1ZXVlcyBhcmUgaXRlcmFibGUsIHNwcmVhZCBpbnRvIGFuIGFycmF5IHRvIGluc3BlY3RcbiAqIGNvbnN0IGl0ZW1zID0gWy4uLnFdIC8vIFtpdGVtMSwgaXRlbTIsIGl0ZW0zXVxuICogLy8gb3IgdXNlIGZvciBvZlxuICogZm9yIChsZXQgaXRlbSBvZiBxKSB7XG4gKiAgICAgY29uc29sZS5sb2coaXRlbSlcbiAqIH1cbiAqXG4gKiBxLmRyYWluKCgpID0+IHtcbiAqICAgICBjb25zb2xlLmxvZygnYWxsIGRvbmUnKVxuICogfSlcbiAqIC8vIG9yXG4gKiBhd2FpdCBxLmRyYWluKClcbiAqL1xuXG4vKipcbiAqIENyZWF0ZXMgYSBgcXVldWVgIG9iamVjdCB3aXRoIHRoZSBzcGVjaWZpZWQgYGNvbmN1cnJlbmN5YC4gVGFza3MgYWRkZWQgdG8gdGhlXG4gKiBgcXVldWVgIGFyZSBwcm9jZXNzZWQgaW4gcGFyYWxsZWwgKHVwIHRvIHRoZSBgY29uY3VycmVuY3lgIGxpbWl0KS4gSWYgYWxsXG4gKiBgd29ya2VyYHMgYXJlIGluIHByb2dyZXNzLCB0aGUgdGFzayBpcyBxdWV1ZWQgdW50aWwgb25lIGJlY29tZXMgYXZhaWxhYmxlLlxuICogT25jZSBhIGB3b3JrZXJgIGNvbXBsZXRlcyBhIGB0YXNrYCwgdGhhdCBgdGFza2AncyBjYWxsYmFjayBpcyBjYWxsZWQuXG4gKlxuICogQG5hbWUgcXVldWVcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29udHJvbEZsb3dcbiAqIEBtZXRob2RcbiAqIEBjYXRlZ29yeSBDb250cm9sIEZsb3dcbiAqIEBwYXJhbSB7QXN5bmNGdW5jdGlvbn0gd29ya2VyIC0gQW4gYXN5bmMgZnVuY3Rpb24gZm9yIHByb2Nlc3NpbmcgYSBxdWV1ZWQgdGFzay5cbiAqIElmIHlvdSB3YW50IHRvIGhhbmRsZSBlcnJvcnMgZnJvbSBhbiBpbmRpdmlkdWFsIHRhc2ssIHBhc3MgYSBjYWxsYmFjayB0b1xuICogYHEucHVzaCgpYC4gSW52b2tlZCB3aXRoICh0YXNrLCBjYWxsYmFjaykuXG4gKiBAcGFyYW0ge251bWJlcn0gW2NvbmN1cnJlbmN5PTFdIC0gQW4gYGludGVnZXJgIGZvciBkZXRlcm1pbmluZyBob3cgbWFueVxuICogYHdvcmtlcmAgZnVuY3Rpb25zIHNob3VsZCBiZSBydW4gaW4gcGFyYWxsZWwuICBJZiBvbWl0dGVkLCB0aGUgY29uY3VycmVuY3lcbiAqIGRlZmF1bHRzIHRvIGAxYC4gIElmIHRoZSBjb25jdXJyZW5jeSBpcyBgMGAsIGFuIGVycm9yIGlzIHRocm93bi5cbiAqIEByZXR1cm5zIHttb2R1bGU6Q29udHJvbEZsb3cuUXVldWVPYmplY3R9IEEgcXVldWUgb2JqZWN0IHRvIG1hbmFnZSB0aGUgdGFza3MuIENhbGxiYWNrcyBjYW4gYmVcbiAqIGF0dGFjaGVkIGFzIGNlcnRhaW4gcHJvcGVydGllcyB0byBsaXN0ZW4gZm9yIHNwZWNpZmljIGV2ZW50cyBkdXJpbmcgdGhlXG4gKiBsaWZlY3ljbGUgb2YgdGhlIHF1ZXVlLlxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBjcmVhdGUgYSBxdWV1ZSBvYmplY3Qgd2l0aCBjb25jdXJyZW5jeSAyXG4gKiB2YXIgcSA9IGFzeW5jLnF1ZXVlKGZ1bmN0aW9uKHRhc2ssIGNhbGxiYWNrKSB7XG4gKiAgICAgY29uc29sZS5sb2coJ2hlbGxvICcgKyB0YXNrLm5hbWUpO1xuICogICAgIGNhbGxiYWNrKCk7XG4gKiB9LCAyKTtcbiAqXG4gKiAvLyBhc3NpZ24gYSBjYWxsYmFja1xuICogcS5kcmFpbihmdW5jdGlvbigpIHtcbiAqICAgICBjb25zb2xlLmxvZygnYWxsIGl0ZW1zIGhhdmUgYmVlbiBwcm9jZXNzZWQnKTtcbiAqIH0pO1xuICogLy8gb3IgYXdhaXQgdGhlIGVuZFxuICogYXdhaXQgcS5kcmFpbigpXG4gKlxuICogLy8gYXNzaWduIGFuIGVycm9yIGNhbGxiYWNrXG4gKiBxLmVycm9yKGZ1bmN0aW9uKGVyciwgdGFzaykge1xuICogICAgIGNvbnNvbGUuZXJyb3IoJ3Rhc2sgZXhwZXJpZW5jZWQgYW4gZXJyb3InKTtcbiAqIH0pO1xuICpcbiAqIC8vIGFkZCBzb21lIGl0ZW1zIHRvIHRoZSBxdWV1ZVxuICogcS5wdXNoKHtuYW1lOiAnZm9vJ30sIGZ1bmN0aW9uKGVycikge1xuICogICAgIGNvbnNvbGUubG9nKCdmaW5pc2hlZCBwcm9jZXNzaW5nIGZvbycpO1xuICogfSk7XG4gKiAvLyBjYWxsYmFjayBpcyBvcHRpb25hbFxuICogcS5wdXNoKHtuYW1lOiAnYmFyJ30pO1xuICpcbiAqIC8vIGFkZCBzb21lIGl0ZW1zIHRvIHRoZSBxdWV1ZSAoYmF0Y2gtd2lzZSlcbiAqIHEucHVzaChbe25hbWU6ICdiYXonfSx7bmFtZTogJ2JheSd9LHtuYW1lOiAnYmF4J31dLCBmdW5jdGlvbihlcnIpIHtcbiAqICAgICBjb25zb2xlLmxvZygnZmluaXNoZWQgcHJvY2Vzc2luZyBpdGVtJyk7XG4gKiB9KTtcbiAqXG4gKiAvLyBhZGQgc29tZSBpdGVtcyB0byB0aGUgZnJvbnQgb2YgdGhlIHF1ZXVlXG4gKiBxLnVuc2hpZnQoe25hbWU6ICdiYXInfSwgZnVuY3Rpb24gKGVycikge1xuICogICAgIGNvbnNvbGUubG9nKCdmaW5pc2hlZCBwcm9jZXNzaW5nIGJhcicpO1xuICogfSk7XG4gKi9cbmZ1bmN0aW9uIHF1ZXVlICh3b3JrZXIsIGNvbmN1cnJlbmN5KSB7XG4gICAgdmFyIF93b3JrZXIgPSB3cmFwQXN5bmMod29ya2VyKTtcbiAgICByZXR1cm4gcXVldWUkMSgoaXRlbXMsIGNiKSA9PiB7XG4gICAgICAgIF93b3JrZXIoaXRlbXNbMF0sIGNiKTtcbiAgICB9LCBjb25jdXJyZW5jeSwgMSk7XG59XG5cbi8vIEJpbmFyeSBtaW4taGVhcCBpbXBsZW1lbnRhdGlvbiB1c2VkIGZvciBwcmlvcml0eSBxdWV1ZS5cbi8vIEltcGxlbWVudGF0aW9uIGlzIHN0YWJsZSwgaS5lLiBwdXNoIHRpbWUgaXMgY29uc2lkZXJlZCBmb3IgZXF1YWwgcHJpb3JpdGllc1xuY2xhc3MgSGVhcCB7XG4gICAgY29uc3RydWN0b3IoKSB7XG4gICAgICAgIHRoaXMuaGVhcCA9IFtdO1xuICAgICAgICB0aGlzLnB1c2hDb3VudCA9IE51bWJlci5NSU5fU0FGRV9JTlRFR0VSO1xuICAgIH1cblxuICAgIGdldCBsZW5ndGgoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmhlYXAubGVuZ3RoO1xuICAgIH1cblxuICAgIGVtcHR5ICgpIHtcbiAgICAgICAgdGhpcy5oZWFwID0gW107XG4gICAgICAgIHJldHVybiB0aGlzO1xuICAgIH1cblxuICAgIHBlcmNVcChpbmRleCkge1xuICAgICAgICBsZXQgcDtcblxuICAgICAgICB3aGlsZSAoaW5kZXggPiAwICYmIHNtYWxsZXIodGhpcy5oZWFwW2luZGV4XSwgdGhpcy5oZWFwW3A9cGFyZW50KGluZGV4KV0pKSB7XG4gICAgICAgICAgICBsZXQgdCA9IHRoaXMuaGVhcFtpbmRleF07XG4gICAgICAgICAgICB0aGlzLmhlYXBbaW5kZXhdID0gdGhpcy5oZWFwW3BdO1xuICAgICAgICAgICAgdGhpcy5oZWFwW3BdID0gdDtcblxuICAgICAgICAgICAgaW5kZXggPSBwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcGVyY0Rvd24oaW5kZXgpIHtcbiAgICAgICAgbGV0IGw7XG5cbiAgICAgICAgd2hpbGUgKChsPWxlZnRDaGkoaW5kZXgpKSA8IHRoaXMuaGVhcC5sZW5ndGgpIHtcbiAgICAgICAgICAgIGlmIChsKzEgPCB0aGlzLmhlYXAubGVuZ3RoICYmIHNtYWxsZXIodGhpcy5oZWFwW2wrMV0sIHRoaXMuaGVhcFtsXSkpIHtcbiAgICAgICAgICAgICAgICBsID0gbCsxO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoc21hbGxlcih0aGlzLmhlYXBbaW5kZXhdLCB0aGlzLmhlYXBbbF0pKSB7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGxldCB0ID0gdGhpcy5oZWFwW2luZGV4XTtcbiAgICAgICAgICAgIHRoaXMuaGVhcFtpbmRleF0gPSB0aGlzLmhlYXBbbF07XG4gICAgICAgICAgICB0aGlzLmhlYXBbbF0gPSB0O1xuXG4gICAgICAgICAgICBpbmRleCA9IGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdXNoKG5vZGUpIHtcbiAgICAgICAgbm9kZS5wdXNoQ291bnQgPSArK3RoaXMucHVzaENvdW50O1xuICAgICAgICB0aGlzLmhlYXAucHVzaChub2RlKTtcbiAgICAgICAgdGhpcy5wZXJjVXAodGhpcy5oZWFwLmxlbmd0aC0xKTtcbiAgICB9XG5cbiAgICB1bnNoaWZ0KG5vZGUpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaGVhcC5wdXNoKG5vZGUpO1xuICAgIH1cblxuICAgIHNoaWZ0KCkge1xuICAgICAgICBsZXQgW3RvcF0gPSB0aGlzLmhlYXA7XG5cbiAgICAgICAgdGhpcy5oZWFwWzBdID0gdGhpcy5oZWFwW3RoaXMuaGVhcC5sZW5ndGgtMV07XG4gICAgICAgIHRoaXMuaGVhcC5wb3AoKTtcbiAgICAgICAgdGhpcy5wZXJjRG93bigwKTtcblxuICAgICAgICByZXR1cm4gdG9wO1xuICAgIH1cblxuICAgIHRvQXJyYXkoKSB7XG4gICAgICAgIHJldHVybiBbLi4udGhpc107XG4gICAgfVxuXG4gICAgKltTeW1ib2wuaXRlcmF0b3JdICgpIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmhlYXAubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgIHlpZWxkIHRoaXMuaGVhcFtpXS5kYXRhO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmVtb3ZlICh0ZXN0Rm4pIHtcbiAgICAgICAgbGV0IGogPSAwO1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuaGVhcC5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKCF0ZXN0Rm4odGhpcy5oZWFwW2ldKSkge1xuICAgICAgICAgICAgICAgIHRoaXMuaGVhcFtqXSA9IHRoaXMuaGVhcFtpXTtcbiAgICAgICAgICAgICAgICBqKys7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmhlYXAuc3BsaWNlKGopO1xuXG4gICAgICAgIGZvciAobGV0IGkgPSBwYXJlbnQodGhpcy5oZWFwLmxlbmd0aC0xKTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgICAgIHRoaXMucGVyY0Rvd24oaSk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gdGhpcztcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGxlZnRDaGkoaSkge1xuICAgIHJldHVybiAoaTw8MSkrMTtcbn1cblxuZnVuY3Rpb24gcGFyZW50KGkpIHtcbiAgICByZXR1cm4gKChpKzEpPj4xKS0xO1xufVxuXG5mdW5jdGlvbiBzbWFsbGVyKHgsIHkpIHtcbiAgICBpZiAoeC5wcmlvcml0eSAhPT0geS5wcmlvcml0eSkge1xuICAgICAgICByZXR1cm4geC5wcmlvcml0eSA8IHkucHJpb3JpdHk7XG4gICAgfVxuICAgIGVsc2Uge1xuICAgICAgICByZXR1cm4geC5wdXNoQ291bnQgPCB5LnB1c2hDb3VudDtcbiAgICB9XG59XG5cbi8qKlxuICogVGhlIHNhbWUgYXMgW2FzeW5jLnF1ZXVlXXtAbGluayBtb2R1bGU6Q29udHJvbEZsb3cucXVldWV9IG9ubHkgdGFza3MgYXJlIGFzc2lnbmVkIGEgcHJpb3JpdHkgYW5kXG4gKiBjb21wbGV0ZWQgaW4gYXNjZW5kaW5nIHByaW9yaXR5IG9yZGVyLlxuICpcbiAqIEBuYW1lIHByaW9yaXR5UXVldWVcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29udHJvbEZsb3dcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLnF1ZXVlXXtAbGluayBtb2R1bGU6Q29udHJvbEZsb3cucXVldWV9XG4gKiBAY2F0ZWdvcnkgQ29udHJvbCBGbG93XG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IHdvcmtlciAtIEFuIGFzeW5jIGZ1bmN0aW9uIGZvciBwcm9jZXNzaW5nIGEgcXVldWVkIHRhc2suXG4gKiBJZiB5b3Ugd2FudCB0byBoYW5kbGUgZXJyb3JzIGZyb20gYW4gaW5kaXZpZHVhbCB0YXNrLCBwYXNzIGEgY2FsbGJhY2sgdG9cbiAqIGBxLnB1c2goKWAuXG4gKiBJbnZva2VkIHdpdGggKHRhc2ssIGNhbGxiYWNrKS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBjb25jdXJyZW5jeSAtIEFuIGBpbnRlZ2VyYCBmb3IgZGV0ZXJtaW5pbmcgaG93IG1hbnkgYHdvcmtlcmBcbiAqIGZ1bmN0aW9ucyBzaG91bGQgYmUgcnVuIGluIHBhcmFsbGVsLiAgSWYgb21pdHRlZCwgdGhlIGNvbmN1cnJlbmN5IGRlZmF1bHRzIHRvXG4gKiBgMWAuICBJZiB0aGUgY29uY3VycmVuY3kgaXMgYDBgLCBhbiBlcnJvciBpcyB0aHJvd24uXG4gKiBAcmV0dXJucyB7bW9kdWxlOkNvbnRyb2xGbG93LlF1ZXVlT2JqZWN0fSBBIHByaW9yaXR5UXVldWUgb2JqZWN0IHRvIG1hbmFnZSB0aGUgdGFza3MuIFRoZXJlIGFyZSB0aHJlZVxuICogZGlmZmVyZW5jZXMgYmV0d2VlbiBgcXVldWVgIGFuZCBgcHJpb3JpdHlRdWV1ZWAgb2JqZWN0czpcbiAqICogYHB1c2godGFzaywgcHJpb3JpdHksIFtjYWxsYmFja10pYCAtIGBwcmlvcml0eWAgc2hvdWxkIGJlIGEgbnVtYmVyLiBJZiBhblxuICogICBhcnJheSBvZiBgdGFza3NgIGlzIGdpdmVuLCBhbGwgdGFza3Mgd2lsbCBiZSBhc3NpZ25lZCB0aGUgc2FtZSBwcmlvcml0eS5cbiAqICogYHB1c2hBc3luYyh0YXNrLCBwcmlvcml0eSwgW2NhbGxiYWNrXSlgIC0gdGhlIHNhbWUgYXMgYHByaW9yaXR5UXVldWUucHVzaGAsXG4gKiAgIGV4Y2VwdCB0aGlzIHJldHVybnMgYSBwcm9taXNlIHRoYXQgcmVqZWN0cyBpZiBhbiBlcnJvciBvY2N1cnMuXG4gKiAqIFRoZSBgdW5zaGlmdGAgYW5kIGB1bnNoaWZ0QXN5bmNgIG1ldGhvZHMgd2VyZSByZW1vdmVkLlxuICovXG5mdW5jdGlvbiBwcmlvcml0eVF1ZXVlKHdvcmtlciwgY29uY3VycmVuY3kpIHtcbiAgICAvLyBTdGFydCB3aXRoIGEgbm9ybWFsIHF1ZXVlXG4gICAgdmFyIHEgPSBxdWV1ZSh3b3JrZXIsIGNvbmN1cnJlbmN5KTtcblxuICAgIHZhciB7XG4gICAgICAgIHB1c2gsXG4gICAgICAgIHB1c2hBc3luY1xuICAgIH0gPSBxO1xuXG4gICAgcS5fdGFza3MgPSBuZXcgSGVhcCgpO1xuICAgIHEuX2NyZWF0ZVRhc2tJdGVtID0gKHtkYXRhLCBwcmlvcml0eX0sIGNhbGxiYWNrKSA9PiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBkYXRhLFxuICAgICAgICAgICAgcHJpb3JpdHksXG4gICAgICAgICAgICBjYWxsYmFja1xuICAgICAgICB9O1xuICAgIH07XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVEYXRhSXRlbXModGFza3MsIHByaW9yaXR5KSB7XG4gICAgICAgIGlmICghQXJyYXkuaXNBcnJheSh0YXNrcykpIHtcbiAgICAgICAgICAgIHJldHVybiB7ZGF0YTogdGFza3MsIHByaW9yaXR5fTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdGFza3MubWFwKGRhdGEgPT4geyByZXR1cm4ge2RhdGEsIHByaW9yaXR5fTsgfSk7XG4gICAgfVxuXG4gICAgLy8gT3ZlcnJpZGUgcHVzaCB0byBhY2NlcHQgc2Vjb25kIHBhcmFtZXRlciByZXByZXNlbnRpbmcgcHJpb3JpdHlcbiAgICBxLnB1c2ggPSBmdW5jdGlvbihkYXRhLCBwcmlvcml0eSA9IDAsIGNhbGxiYWNrKSB7XG4gICAgICAgIHJldHVybiBwdXNoKGNyZWF0ZURhdGFJdGVtcyhkYXRhLCBwcmlvcml0eSksIGNhbGxiYWNrKTtcbiAgICB9O1xuXG4gICAgcS5wdXNoQXN5bmMgPSBmdW5jdGlvbihkYXRhLCBwcmlvcml0eSA9IDAsIGNhbGxiYWNrKSB7XG4gICAgICAgIHJldHVybiBwdXNoQXN5bmMoY3JlYXRlRGF0YUl0ZW1zKGRhdGEsIHByaW9yaXR5KSwgY2FsbGJhY2spO1xuICAgIH07XG5cbiAgICAvLyBSZW1vdmUgdW5zaGlmdCBmdW5jdGlvbnNcbiAgICBkZWxldGUgcS51bnNoaWZ0O1xuICAgIGRlbGV0ZSBxLnVuc2hpZnRBc3luYztcblxuICAgIHJldHVybiBxO1xufVxuXG4vKipcbiAqIFJ1bnMgdGhlIGB0YXNrc2AgYXJyYXkgb2YgZnVuY3Rpb25zIGluIHBhcmFsbGVsLCB3aXRob3V0IHdhaXRpbmcgdW50aWwgdGhlXG4gKiBwcmV2aW91cyBmdW5jdGlvbiBoYXMgY29tcGxldGVkLiBPbmNlIGFueSBvZiB0aGUgYHRhc2tzYCBjb21wbGV0ZSBvciBwYXNzIGFuXG4gKiBlcnJvciB0byBpdHMgY2FsbGJhY2ssIHRoZSBtYWluIGBjYWxsYmFja2AgaXMgaW1tZWRpYXRlbHkgY2FsbGVkLiBJdCdzXG4gKiBlcXVpdmFsZW50IHRvIGBQcm9taXNlLnJhY2UoKWAuXG4gKlxuICogQG5hbWUgcmFjZVxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb250cm9sRmxvd1xuICogQG1ldGhvZFxuICogQGNhdGVnb3J5IENvbnRyb2wgRmxvd1xuICogQHBhcmFtIHtBcnJheX0gdGFza3MgLSBBbiBhcnJheSBjb250YWluaW5nIFthc3luYyBmdW5jdGlvbnNde0BsaW5rIEFzeW5jRnVuY3Rpb259XG4gKiB0byBydW4uIEVhY2ggZnVuY3Rpb24gY2FuIGNvbXBsZXRlIHdpdGggYW4gb3B0aW9uYWwgYHJlc3VsdGAgdmFsdWUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayAtIEEgY2FsbGJhY2sgdG8gcnVuIG9uY2UgYW55IG9mIHRoZSBmdW5jdGlvbnMgaGF2ZVxuICogY29tcGxldGVkLiBUaGlzIGZ1bmN0aW9uIGdldHMgYW4gZXJyb3Igb3IgcmVzdWx0IGZyb20gdGhlIGZpcnN0IGZ1bmN0aW9uIHRoYXRcbiAqIGNvbXBsZXRlZC4gSW52b2tlZCB3aXRoIChlcnIsIHJlc3VsdCkuXG4gKiBAcmV0dXJucyB7UHJvbWlzZX0gYSBwcm9taXNlLCBpZiBhIGNhbGxiYWNrIGlzIG9taXR0ZWRcbiAqIEBleGFtcGxlXG4gKlxuICogYXN5bmMucmFjZShbXG4gKiAgICAgZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAqICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAqICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsICdvbmUnKTtcbiAqICAgICAgICAgfSwgMjAwKTtcbiAqICAgICB9LFxuICogICAgIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCAndHdvJyk7XG4gKiAgICAgICAgIH0sIDEwMCk7XG4gKiAgICAgfVxuICogXSxcbiAqIC8vIG1haW4gY2FsbGJhY2tcbiAqIGZ1bmN0aW9uKGVyciwgcmVzdWx0KSB7XG4gKiAgICAgLy8gdGhlIHJlc3VsdCB3aWxsIGJlIGVxdWFsIHRvICd0d28nIGFzIGl0IGZpbmlzaGVzIGVhcmxpZXJcbiAqIH0pO1xuICovXG5mdW5jdGlvbiByYWNlKHRhc2tzLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gb25jZShjYWxsYmFjayk7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRhc2tzKSkgcmV0dXJuIGNhbGxiYWNrKG5ldyBUeXBlRXJyb3IoJ0ZpcnN0IGFyZ3VtZW50IHRvIHJhY2UgbXVzdCBiZSBhbiBhcnJheSBvZiBmdW5jdGlvbnMnKSk7XG4gICAgaWYgKCF0YXNrcy5sZW5ndGgpIHJldHVybiBjYWxsYmFjaygpO1xuICAgIGZvciAodmFyIGkgPSAwLCBsID0gdGFza3MubGVuZ3RoOyBpIDwgbDsgaSsrKSB7XG4gICAgICAgIHdyYXBBc3luYyh0YXNrc1tpXSkoY2FsbGJhY2spO1xuICAgIH1cbn1cblxudmFyIHJhY2UkMSA9IGF3YWl0aWZ5KHJhY2UsIDIpO1xuXG4vKipcbiAqIFNhbWUgYXMgW2ByZWR1Y2VgXXtAbGluayBtb2R1bGU6Q29sbGVjdGlvbnMucmVkdWNlfSwgb25seSBvcGVyYXRlcyBvbiBgYXJyYXlgIGluIHJldmVyc2Ugb3JkZXIuXG4gKlxuICogQG5hbWUgcmVkdWNlUmlnaHRcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29sbGVjdGlvbnNcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLnJlZHVjZV17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLnJlZHVjZX1cbiAqIEBhbGlhcyBmb2xkclxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl9IGFycmF5IC0gQSBjb2xsZWN0aW9uIHRvIGl0ZXJhdGUgb3Zlci5cbiAqIEBwYXJhbSB7Kn0gbWVtbyAtIFRoZSBpbml0aWFsIHN0YXRlIG9mIHRoZSByZWR1Y3Rpb24uXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IGl0ZXJhdGVlIC0gQSBmdW5jdGlvbiBhcHBsaWVkIHRvIGVhY2ggaXRlbSBpbiB0aGVcbiAqIGFycmF5IHRvIHByb2R1Y2UgdGhlIG5leHQgc3RlcCBpbiB0aGUgcmVkdWN0aW9uLlxuICogVGhlIGBpdGVyYXRlZWAgc2hvdWxkIGNvbXBsZXRlIHdpdGggdGhlIG5leHQgc3RhdGUgb2YgdGhlIHJlZHVjdGlvbi5cbiAqIElmIHRoZSBpdGVyYXRlZSBjb21wbGV0ZXMgd2l0aCBhbiBlcnJvciwgdGhlIHJlZHVjdGlvbiBpcyBzdG9wcGVkIGFuZCB0aGVcbiAqIG1haW4gYGNhbGxiYWNrYCBpcyBpbW1lZGlhdGVseSBjYWxsZWQgd2l0aCB0aGUgZXJyb3IuXG4gKiBJbnZva2VkIHdpdGggKG1lbW8sIGl0ZW0sIGNhbGxiYWNrKS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYWxsYmFja10gLSBBIGNhbGxiYWNrIHdoaWNoIGlzIGNhbGxlZCBhZnRlciBhbGwgdGhlXG4gKiBgaXRlcmF0ZWVgIGZ1bmN0aW9ucyBoYXZlIGZpbmlzaGVkLiBSZXN1bHQgaXMgdGhlIHJlZHVjZWQgdmFsdWUuIEludm9rZWQgd2l0aFxuICogKGVyciwgcmVzdWx0KS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIG5vIGNhbGxiYWNrIGlzIHBhc3NlZFxuICovXG5mdW5jdGlvbiByZWR1Y2VSaWdodCAoYXJyYXksIG1lbW8sIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIHZhciByZXZlcnNlZCA9IFsuLi5hcnJheV0ucmV2ZXJzZSgpO1xuICAgIHJldHVybiByZWR1Y2UkMShyZXZlcnNlZCwgbWVtbywgaXRlcmF0ZWUsIGNhbGxiYWNrKTtcbn1cblxuLyoqXG4gKiBXcmFwcyB0aGUgYXN5bmMgZnVuY3Rpb24gaW4gYW5vdGhlciBmdW5jdGlvbiB0aGF0IGFsd2F5cyBjb21wbGV0ZXMgd2l0aCBhXG4gKiByZXN1bHQgb2JqZWN0LCBldmVuIHdoZW4gaXQgZXJyb3JzLlxuICpcbiAqIFRoZSByZXN1bHQgb2JqZWN0IGhhcyBlaXRoZXIgdGhlIHByb3BlcnR5IGBlcnJvcmAgb3IgYHZhbHVlYC5cbiAqXG4gKiBAbmFtZSByZWZsZWN0XG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOlV0aWxzXG4gKiBAbWV0aG9kXG4gKiBAY2F0ZWdvcnkgVXRpbFxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBmbiAtIFRoZSBhc3luYyBmdW5jdGlvbiB5b3Ugd2FudCB0byB3cmFwXG4gKiBAcmV0dXJucyB7RnVuY3Rpb259IC0gQSBmdW5jdGlvbiB0aGF0IGFsd2F5cyBwYXNzZXMgbnVsbCB0byBpdCdzIGNhbGxiYWNrIGFzXG4gKiB0aGUgZXJyb3IuIFRoZSBzZWNvbmQgYXJndW1lbnQgdG8gdGhlIGNhbGxiYWNrIHdpbGwgYmUgYW4gYG9iamVjdGAgd2l0aFxuICogZWl0aGVyIGFuIGBlcnJvcmAgb3IgYSBgdmFsdWVgIHByb3BlcnR5LlxuICogQGV4YW1wbGVcbiAqXG4gKiBhc3luYy5wYXJhbGxlbChbXG4gKiAgICAgYXN5bmMucmVmbGVjdChmdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgICAgICAvLyBkbyBzb21lIHN0dWZmIC4uLlxuICogICAgICAgICBjYWxsYmFjayhudWxsLCAnb25lJyk7XG4gKiAgICAgfSksXG4gKiAgICAgYXN5bmMucmVmbGVjdChmdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgICAgICAvLyBkbyBzb21lIG1vcmUgc3R1ZmYgYnV0IGVycm9yIC4uLlxuICogICAgICAgICBjYWxsYmFjaygnYmFkIHN0dWZmIGhhcHBlbmVkJyk7XG4gKiAgICAgfSksXG4gKiAgICAgYXN5bmMucmVmbGVjdChmdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgICAgICAvLyBkbyBzb21lIG1vcmUgc3R1ZmYgLi4uXG4gKiAgICAgICAgIGNhbGxiYWNrKG51bGwsICd0d28nKTtcbiAqICAgICB9KVxuICogXSxcbiAqIC8vIG9wdGlvbmFsIGNhbGxiYWNrXG4gKiBmdW5jdGlvbihlcnIsIHJlc3VsdHMpIHtcbiAqICAgICAvLyB2YWx1ZXNcbiAqICAgICAvLyByZXN1bHRzWzBdLnZhbHVlID0gJ29uZSdcbiAqICAgICAvLyByZXN1bHRzWzFdLmVycm9yID0gJ2JhZCBzdHVmZiBoYXBwZW5lZCdcbiAqICAgICAvLyByZXN1bHRzWzJdLnZhbHVlID0gJ3R3bydcbiAqIH0pO1xuICovXG5mdW5jdGlvbiByZWZsZWN0KGZuKSB7XG4gICAgdmFyIF9mbiA9IHdyYXBBc3luYyhmbik7XG4gICAgcmV0dXJuIGluaXRpYWxQYXJhbXMoZnVuY3Rpb24gcmVmbGVjdE9uKGFyZ3MsIHJlZmxlY3RDYWxsYmFjaykge1xuICAgICAgICBhcmdzLnB1c2goKGVycm9yLCAuLi5jYkFyZ3MpID0+IHtcbiAgICAgICAgICAgIGxldCByZXRWYWwgPSB7fTtcbiAgICAgICAgICAgIGlmIChlcnJvcikge1xuICAgICAgICAgICAgICAgIHJldFZhbC5lcnJvciA9IGVycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNiQXJncy5sZW5ndGggPiAwKXtcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWUgPSBjYkFyZ3M7XG4gICAgICAgICAgICAgICAgaWYgKGNiQXJncy5sZW5ndGggPD0gMSkge1xuICAgICAgICAgICAgICAgICAgICBbdmFsdWVdID0gY2JBcmdzO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXRWYWwudmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJlZmxlY3RDYWxsYmFjayhudWxsLCByZXRWYWwpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gX2ZuLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICAgIH0pO1xufVxuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIHRoYXQgd3JhcHMgYW4gYXJyYXkgb3IgYW4gb2JqZWN0IG9mIGZ1bmN0aW9ucyB3aXRoIGByZWZsZWN0YC5cbiAqXG4gKiBAbmFtZSByZWZsZWN0QWxsXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOlV0aWxzXG4gKiBAbWV0aG9kXG4gKiBAc2VlIFthc3luYy5yZWZsZWN0XXtAbGluayBtb2R1bGU6VXRpbHMucmVmbGVjdH1cbiAqIEBjYXRlZ29yeSBVdGlsXG4gKiBAcGFyYW0ge0FycmF5fE9iamVjdHxJdGVyYWJsZX0gdGFza3MgLSBUaGUgY29sbGVjdGlvbiBvZlxuICogW2FzeW5jIGZ1bmN0aW9uc117QGxpbmsgQXN5bmNGdW5jdGlvbn0gdG8gd3JhcCBpbiBgYXN5bmMucmVmbGVjdGAuXG4gKiBAcmV0dXJucyB7QXJyYXl9IFJldHVybnMgYW4gYXJyYXkgb2YgYXN5bmMgZnVuY3Rpb25zLCBlYWNoIHdyYXBwZWQgaW5cbiAqIGBhc3luYy5yZWZsZWN0YFxuICogQGV4YW1wbGVcbiAqXG4gKiBsZXQgdGFza3MgPSBbXG4gKiAgICAgZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAqICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAqICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsICdvbmUnKTtcbiAqICAgICAgICAgfSwgMjAwKTtcbiAqICAgICB9LFxuICogICAgIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIC8vIGRvIHNvbWUgbW9yZSBzdHVmZiBidXQgZXJyb3IgLi4uXG4gKiAgICAgICAgIGNhbGxiYWNrKG5ldyBFcnJvcignYmFkIHN0dWZmIGhhcHBlbmVkJykpO1xuICogICAgIH0sXG4gKiAgICAgZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAqICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAqICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsICd0d28nKTtcbiAqICAgICAgICAgfSwgMTAwKTtcbiAqICAgICB9XG4gKiBdO1xuICpcbiAqIGFzeW5jLnBhcmFsbGVsKGFzeW5jLnJlZmxlY3RBbGwodGFza3MpLFxuICogLy8gb3B0aW9uYWwgY2FsbGJhY2tcbiAqIGZ1bmN0aW9uKGVyciwgcmVzdWx0cykge1xuICogICAgIC8vIHZhbHVlc1xuICogICAgIC8vIHJlc3VsdHNbMF0udmFsdWUgPSAnb25lJ1xuICogICAgIC8vIHJlc3VsdHNbMV0uZXJyb3IgPSBFcnJvcignYmFkIHN0dWZmIGhhcHBlbmVkJylcbiAqICAgICAvLyByZXN1bHRzWzJdLnZhbHVlID0gJ3R3bydcbiAqIH0pO1xuICpcbiAqIC8vIGFuIGV4YW1wbGUgdXNpbmcgYW4gb2JqZWN0IGluc3RlYWQgb2YgYW4gYXJyYXlcbiAqIGxldCB0YXNrcyA9IHtcbiAqICAgICBvbmU6IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCAnb25lJyk7XG4gKiAgICAgICAgIH0sIDIwMCk7XG4gKiAgICAgfSxcbiAqICAgICB0d286IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIGNhbGxiYWNrKCd0d28nKTtcbiAqICAgICB9LFxuICogICAgIHRocmVlOiBmdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICogICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgJ3RocmVlJyk7XG4gKiAgICAgICAgIH0sIDEwMCk7XG4gKiAgICAgfVxuICogfTtcbiAqXG4gKiBhc3luYy5wYXJhbGxlbChhc3luYy5yZWZsZWN0QWxsKHRhc2tzKSxcbiAqIC8vIG9wdGlvbmFsIGNhbGxiYWNrXG4gKiBmdW5jdGlvbihlcnIsIHJlc3VsdHMpIHtcbiAqICAgICAvLyB2YWx1ZXNcbiAqICAgICAvLyByZXN1bHRzLm9uZS52YWx1ZSA9ICdvbmUnXG4gKiAgICAgLy8gcmVzdWx0cy50d28uZXJyb3IgPSAndHdvJ1xuICogICAgIC8vIHJlc3VsdHMudGhyZWUudmFsdWUgPSAndGhyZWUnXG4gKiB9KTtcbiAqL1xuZnVuY3Rpb24gcmVmbGVjdEFsbCh0YXNrcykge1xuICAgIHZhciByZXN1bHRzO1xuICAgIGlmIChBcnJheS5pc0FycmF5KHRhc2tzKSkge1xuICAgICAgICByZXN1bHRzID0gdGFza3MubWFwKHJlZmxlY3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc3VsdHMgPSB7fTtcbiAgICAgICAgT2JqZWN0LmtleXModGFza3MpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgICAgICAgIHJlc3VsdHNba2V5XSA9IHJlZmxlY3QuY2FsbCh0aGlzLCB0YXNrc1trZXldKTtcbiAgICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHRzO1xufVxuXG5mdW5jdGlvbiByZWplY3QkMihlYWNoZm4sIGFyciwgX2l0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIGNvbnN0IGl0ZXJhdGVlID0gd3JhcEFzeW5jKF9pdGVyYXRlZSk7XG4gICAgcmV0dXJuIF9maWx0ZXIoZWFjaGZuLCBhcnIsICh2YWx1ZSwgY2IpID0+IHtcbiAgICAgICAgaXRlcmF0ZWUodmFsdWUsIChlcnIsIHYpID0+IHtcbiAgICAgICAgICAgIGNiKGVyciwgIXYpO1xuICAgICAgICB9KTtcbiAgICB9LCBjYWxsYmFjayk7XG59XG5cbi8qKlxuICogVGhlIG9wcG9zaXRlIG9mIFtgZmlsdGVyYF17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLmZpbHRlcn0uIFJlbW92ZXMgdmFsdWVzIHRoYXQgcGFzcyBhbiBgYXN5bmNgIHRydXRoIHRlc3QuXG4gKlxuICogQG5hbWUgcmVqZWN0XG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbGxlY3Rpb25zXG4gKiBAbWV0aG9kXG4gKiBAc2VlIFthc3luYy5maWx0ZXJde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5maWx0ZXJ9XG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxJdGVyYWJsZXxBc3luY0l0ZXJhYmxlfE9iamVjdH0gY29sbCAtIEEgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEFuIGFzeW5jIHRydXRoIHRlc3QgdG8gYXBwbHkgdG8gZWFjaCBpdGVtIGluXG4gKiBgY29sbGAuXG4gKiBUaGUgc2hvdWxkIGNvbXBsZXRlIHdpdGggYSBib29sZWFuIHZhbHVlIGFzIGl0cyBgcmVzdWx0YC5cbiAqIEludm9rZWQgd2l0aCAoaXRlbSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIGFmdGVyIGFsbCB0aGVcbiAqIGBpdGVyYXRlZWAgZnVuY3Rpb25zIGhhdmUgZmluaXNoZWQuIEludm9rZWQgd2l0aCAoZXJyLCByZXN1bHRzKS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIG5vIGNhbGxiYWNrIGlzIHBhc3NlZFxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBkaXIxIGlzIGEgZGlyZWN0b3J5IHRoYXQgY29udGFpbnMgZmlsZTEudHh0LCBmaWxlMi50eHRcbiAqIC8vIGRpcjIgaXMgYSBkaXJlY3RvcnkgdGhhdCBjb250YWlucyBmaWxlMy50eHQsIGZpbGU0LnR4dFxuICogLy8gZGlyMyBpcyBhIGRpcmVjdG9yeSB0aGF0IGNvbnRhaW5zIGZpbGU1LnR4dFxuICpcbiAqIGNvbnN0IGZpbGVMaXN0ID0gWydkaXIxL2ZpbGUxLnR4dCcsJ2RpcjIvZmlsZTMudHh0JywnZGlyMy9maWxlNi50eHQnXTtcbiAqXG4gKiAvLyBhc3luY2hyb25vdXMgZnVuY3Rpb24gdGhhdCBjaGVja3MgaWYgYSBmaWxlIGV4aXN0c1xuICogZnVuY3Rpb24gZmlsZUV4aXN0cyhmaWxlLCBjYWxsYmFjaykge1xuICogICAgZnMuYWNjZXNzKGZpbGUsIGZzLmNvbnN0YW50cy5GX09LLCAoZXJyKSA9PiB7XG4gKiAgICAgICAgY2FsbGJhY2sobnVsbCwgIWVycik7XG4gKiAgICB9KTtcbiAqIH1cbiAqXG4gKiAvLyBVc2luZyBjYWxsYmFja3NcbiAqIGFzeW5jLnJlamVjdChmaWxlTGlzdCwgZmlsZUV4aXN0cywgZnVuY3Rpb24oZXJyLCByZXN1bHRzKSB7XG4gKiAgICAvLyBbICdkaXIzL2ZpbGU2LnR4dCcgXVxuICogICAgLy8gcmVzdWx0cyBub3cgZXF1YWxzIGFuIGFycmF5IG9mIHRoZSBub24tZXhpc3RpbmcgZmlsZXNcbiAqIH0pO1xuICpcbiAqIC8vIFVzaW5nIFByb21pc2VzXG4gKiBhc3luYy5yZWplY3QoZmlsZUxpc3QsIGZpbGVFeGlzdHMpXG4gKiAudGhlbiggcmVzdWx0cyA9PiB7XG4gKiAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiAgICAgLy8gWyAnZGlyMy9maWxlNi50eHQnIF1cbiAqICAgICAvLyByZXN1bHRzIG5vdyBlcXVhbHMgYW4gYXJyYXkgb2YgdGhlIG5vbi1leGlzdGluZyBmaWxlc1xuICogfSkuY2F0Y2goIGVyciA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqIH0pO1xuICpcbiAqIC8vIFVzaW5nIGFzeW5jL2F3YWl0XG4gKiBhc3luYyAoKSA9PiB7XG4gKiAgICAgdHJ5IHtcbiAqICAgICAgICAgbGV0IHJlc3VsdHMgPSBhd2FpdCBhc3luYy5yZWplY3QoZmlsZUxpc3QsIGZpbGVFeGlzdHMpO1xuICogICAgICAgICBjb25zb2xlLmxvZyhyZXN1bHRzKTtcbiAqICAgICAgICAgLy8gWyAnZGlyMy9maWxlNi50eHQnIF1cbiAqICAgICAgICAgLy8gcmVzdWx0cyBub3cgZXF1YWxzIGFuIGFycmF5IG9mIHRoZSBub24tZXhpc3RpbmcgZmlsZXNcbiAqICAgICB9XG4gKiAgICAgY2F0Y2ggKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgIH1cbiAqIH1cbiAqXG4gKi9cbmZ1bmN0aW9uIHJlamVjdCAoY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHJlamVjdCQyKGVhY2hPZiQxLCBjb2xsLCBpdGVyYXRlZSwgY2FsbGJhY2spXG59XG52YXIgcmVqZWN0JDEgPSBhd2FpdGlmeShyZWplY3QsIDMpO1xuXG4vKipcbiAqIFRoZSBzYW1lIGFzIFtgcmVqZWN0YF17QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLnJlamVjdH0gYnV0IHJ1bnMgYSBtYXhpbXVtIG9mIGBsaW1pdGAgYXN5bmMgb3BlcmF0aW9ucyBhdCBhXG4gKiB0aW1lLlxuICpcbiAqIEBuYW1lIHJlamVjdExpbWl0XG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbGxlY3Rpb25zXG4gKiBAbWV0aG9kXG4gKiBAc2VlIFthc3luYy5yZWplY3Rde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5yZWplY3R9XG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxJdGVyYWJsZXxBc3luY0l0ZXJhYmxlfE9iamVjdH0gY29sbCAtIEEgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge251bWJlcn0gbGltaXQgLSBUaGUgbWF4aW11bSBudW1iZXIgb2YgYXN5bmMgb3BlcmF0aW9ucyBhdCBhIHRpbWUuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEFuIGFzeW5jIHRydXRoIHRlc3QgdG8gYXBwbHkgdG8gZWFjaCBpdGVtIGluXG4gKiBgY29sbGAuXG4gKiBUaGUgc2hvdWxkIGNvbXBsZXRlIHdpdGggYSBib29sZWFuIHZhbHVlIGFzIGl0cyBgcmVzdWx0YC5cbiAqIEludm9rZWQgd2l0aCAoaXRlbSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIGFmdGVyIGFsbCB0aGVcbiAqIGBpdGVyYXRlZWAgZnVuY3Rpb25zIGhhdmUgZmluaXNoZWQuIEludm9rZWQgd2l0aCAoZXJyLCByZXN1bHRzKS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIG5vIGNhbGxiYWNrIGlzIHBhc3NlZFxuICovXG5mdW5jdGlvbiByZWplY3RMaW1pdCAoY29sbCwgbGltaXQsIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiByZWplY3QkMihlYWNoT2ZMaW1pdCQyKGxpbWl0KSwgY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKVxufVxudmFyIHJlamVjdExpbWl0JDEgPSBhd2FpdGlmeShyZWplY3RMaW1pdCwgNCk7XG5cbi8qKlxuICogVGhlIHNhbWUgYXMgW2ByZWplY3RgXXtAbGluayBtb2R1bGU6Q29sbGVjdGlvbnMucmVqZWN0fSBidXQgcnVucyBvbmx5IGEgc2luZ2xlIGFzeW5jIG9wZXJhdGlvbiBhdCBhIHRpbWUuXG4gKlxuICogQG5hbWUgcmVqZWN0U2VyaWVzXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbGxlY3Rpb25zXG4gKiBAbWV0aG9kXG4gKiBAc2VlIFthc3luYy5yZWplY3Rde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5yZWplY3R9XG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxJdGVyYWJsZXxBc3luY0l0ZXJhYmxlfE9iamVjdH0gY29sbCAtIEEgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEFuIGFzeW5jIHRydXRoIHRlc3QgdG8gYXBwbHkgdG8gZWFjaCBpdGVtIGluXG4gKiBgY29sbGAuXG4gKiBUaGUgc2hvdWxkIGNvbXBsZXRlIHdpdGggYSBib29sZWFuIHZhbHVlIGFzIGl0cyBgcmVzdWx0YC5cbiAqIEludm9rZWQgd2l0aCAoaXRlbSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIGFmdGVyIGFsbCB0aGVcbiAqIGBpdGVyYXRlZWAgZnVuY3Rpb25zIGhhdmUgZmluaXNoZWQuIEludm9rZWQgd2l0aCAoZXJyLCByZXN1bHRzKS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIG5vIGNhbGxiYWNrIGlzIHBhc3NlZFxuICovXG5mdW5jdGlvbiByZWplY3RTZXJpZXMgKGNvbGwsIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiByZWplY3QkMihlYWNoT2ZTZXJpZXMkMSwgY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKVxufVxudmFyIHJlamVjdFNlcmllcyQxID0gYXdhaXRpZnkocmVqZWN0U2VyaWVzLCAzKTtcblxuZnVuY3Rpb24gY29uc3RhbnQodmFsdWUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xuICAgICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxufVxuXG4vKipcbiAqIEF0dGVtcHRzIHRvIGdldCBhIHN1Y2Nlc3NmdWwgcmVzcG9uc2UgZnJvbSBgdGFza2Agbm8gbW9yZSB0aGFuIGB0aW1lc2AgdGltZXNcbiAqIGJlZm9yZSByZXR1cm5pbmcgYW4gZXJyb3IuIElmIHRoZSB0YXNrIGlzIHN1Y2Nlc3NmdWwsIHRoZSBgY2FsbGJhY2tgIHdpbGwgYmVcbiAqIHBhc3NlZCB0aGUgcmVzdWx0IG9mIHRoZSBzdWNjZXNzZnVsIHRhc2suIElmIGFsbCBhdHRlbXB0cyBmYWlsLCB0aGUgY2FsbGJhY2tcbiAqIHdpbGwgYmUgcGFzc2VkIHRoZSBlcnJvciBhbmQgcmVzdWx0IChpZiBhbnkpIG9mIHRoZSBmaW5hbCBhdHRlbXB0LlxuICpcbiAqIEBuYW1lIHJldHJ5XG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbnRyb2xGbG93XG4gKiBAbWV0aG9kXG4gKiBAY2F0ZWdvcnkgQ29udHJvbCBGbG93XG4gKiBAc2VlIFthc3luYy5yZXRyeWFibGVde0BsaW5rIG1vZHVsZTpDb250cm9sRmxvdy5yZXRyeWFibGV9XG4gKiBAcGFyYW0ge09iamVjdHxudW1iZXJ9IFtvcHRzID0ge3RpbWVzOiA1LCBpbnRlcnZhbDogMH18IDVdIC0gQ2FuIGJlIGVpdGhlciBhblxuICogb2JqZWN0IHdpdGggYHRpbWVzYCBhbmQgYGludGVydmFsYCBvciBhIG51bWJlci5cbiAqICogYHRpbWVzYCAtIFRoZSBudW1iZXIgb2YgYXR0ZW1wdHMgdG8gbWFrZSBiZWZvcmUgZ2l2aW5nIHVwLiAgVGhlIGRlZmF1bHRcbiAqICAgaXMgYDVgLlxuICogKiBgaW50ZXJ2YWxgIC0gVGhlIHRpbWUgdG8gd2FpdCBiZXR3ZWVuIHJldHJpZXMsIGluIG1pbGxpc2Vjb25kcy4gIFRoZVxuICogICBkZWZhdWx0IGlzIGAwYC4gVGhlIGludGVydmFsIG1heSBhbHNvIGJlIHNwZWNpZmllZCBhcyBhIGZ1bmN0aW9uIG9mIHRoZVxuICogICByZXRyeSBjb3VudCAoc2VlIGV4YW1wbGUpLlxuICogKiBgZXJyb3JGaWx0ZXJgIC0gQW4gb3B0aW9uYWwgc3luY2hyb25vdXMgZnVuY3Rpb24gdGhhdCBpcyBpbnZva2VkIG9uXG4gKiAgIGVycm9uZW91cyByZXN1bHQuIElmIGl0IHJldHVybnMgYHRydWVgIHRoZSByZXRyeSBhdHRlbXB0cyB3aWxsIGNvbnRpbnVlO1xuICogICBpZiB0aGUgZnVuY3Rpb24gcmV0dXJucyBgZmFsc2VgIHRoZSByZXRyeSBmbG93IGlzIGFib3J0ZWQgd2l0aCB0aGUgY3VycmVudFxuICogICBhdHRlbXB0J3MgZXJyb3IgYW5kIHJlc3VsdCBiZWluZyByZXR1cm5lZCB0byB0aGUgZmluYWwgY2FsbGJhY2suXG4gKiAgIEludm9rZWQgd2l0aCAoZXJyKS5cbiAqICogSWYgYG9wdHNgIGlzIGEgbnVtYmVyLCB0aGUgbnVtYmVyIHNwZWNpZmllcyB0aGUgbnVtYmVyIG9mIHRpbWVzIHRvIHJldHJ5LFxuICogICB3aXRoIHRoZSBkZWZhdWx0IGludGVydmFsIG9mIGAwYC5cbiAqIEBwYXJhbSB7QXN5bmNGdW5jdGlvbn0gdGFzayAtIEFuIGFzeW5jIGZ1bmN0aW9uIHRvIHJldHJ5LlxuICogSW52b2tlZCB3aXRoIChjYWxsYmFjaykuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdIC0gQW4gb3B0aW9uYWwgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIHdoZW4gdGhlXG4gKiB0YXNrIGhhcyBzdWNjZWVkZWQsIG9yIGFmdGVyIHRoZSBmaW5hbCBmYWlsZWQgYXR0ZW1wdC4gSXQgcmVjZWl2ZXMgdGhlIGBlcnJgXG4gKiBhbmQgYHJlc3VsdGAgYXJndW1lbnRzIG9mIHRoZSBsYXN0IGF0dGVtcHQgYXQgY29tcGxldGluZyB0aGUgYHRhc2tgLiBJbnZva2VkXG4gKiB3aXRoIChlcnIsIHJlc3VsdHMpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSBpZiBubyBjYWxsYmFjayBwcm92aWRlZFxuICpcbiAqIEBleGFtcGxlXG4gKlxuICogLy8gVGhlIGByZXRyeWAgZnVuY3Rpb24gY2FuIGJlIHVzZWQgYXMgYSBzdGFuZC1hbG9uZSBjb250cm9sIGZsb3cgYnkgcGFzc2luZ1xuICogLy8gYSBjYWxsYmFjaywgYXMgc2hvd24gYmVsb3c6XG4gKlxuICogLy8gdHJ5IGNhbGxpbmcgYXBpTWV0aG9kIDMgdGltZXNcbiAqIGFzeW5jLnJldHJ5KDMsIGFwaU1ldGhvZCwgZnVuY3Rpb24oZXJyLCByZXN1bHQpIHtcbiAqICAgICAvLyBkbyBzb21ldGhpbmcgd2l0aCB0aGUgcmVzdWx0XG4gKiB9KTtcbiAqXG4gKiAvLyB0cnkgY2FsbGluZyBhcGlNZXRob2QgMyB0aW1lcywgd2FpdGluZyAyMDAgbXMgYmV0d2VlbiBlYWNoIHJldHJ5XG4gKiBhc3luYy5yZXRyeSh7dGltZXM6IDMsIGludGVydmFsOiAyMDB9LCBhcGlNZXRob2QsIGZ1bmN0aW9uKGVyciwgcmVzdWx0KSB7XG4gKiAgICAgLy8gZG8gc29tZXRoaW5nIHdpdGggdGhlIHJlc3VsdFxuICogfSk7XG4gKlxuICogLy8gdHJ5IGNhbGxpbmcgYXBpTWV0aG9kIDEwIHRpbWVzIHdpdGggZXhwb25lbnRpYWwgYmFja29mZlxuICogLy8gKGkuZS4gaW50ZXJ2YWxzIG9mIDEwMCwgMjAwLCA0MDAsIDgwMCwgMTYwMCwgLi4uIG1pbGxpc2Vjb25kcylcbiAqIGFzeW5jLnJldHJ5KHtcbiAqICAgdGltZXM6IDEwLFxuICogICBpbnRlcnZhbDogZnVuY3Rpb24ocmV0cnlDb3VudCkge1xuICogICAgIHJldHVybiA1MCAqIE1hdGgucG93KDIsIHJldHJ5Q291bnQpO1xuICogICB9XG4gKiB9LCBhcGlNZXRob2QsIGZ1bmN0aW9uKGVyciwgcmVzdWx0KSB7XG4gKiAgICAgLy8gZG8gc29tZXRoaW5nIHdpdGggdGhlIHJlc3VsdFxuICogfSk7XG4gKlxuICogLy8gdHJ5IGNhbGxpbmcgYXBpTWV0aG9kIHRoZSBkZWZhdWx0IDUgdGltZXMgbm8gZGVsYXkgYmV0d2VlbiBlYWNoIHJldHJ5XG4gKiBhc3luYy5yZXRyeShhcGlNZXRob2QsIGZ1bmN0aW9uKGVyciwgcmVzdWx0KSB7XG4gKiAgICAgLy8gZG8gc29tZXRoaW5nIHdpdGggdGhlIHJlc3VsdFxuICogfSk7XG4gKlxuICogLy8gdHJ5IGNhbGxpbmcgYXBpTWV0aG9kIG9ubHkgd2hlbiBlcnJvciBjb25kaXRpb24gc2F0aXNmaWVzLCBhbGwgb3RoZXJcbiAqIC8vIGVycm9ycyB3aWxsIGFib3J0IHRoZSByZXRyeSBjb250cm9sIGZsb3cgYW5kIHJldHVybiB0byBmaW5hbCBjYWxsYmFja1xuICogYXN5bmMucmV0cnkoe1xuICogICBlcnJvckZpbHRlcjogZnVuY3Rpb24oZXJyKSB7XG4gKiAgICAgcmV0dXJuIGVyci5tZXNzYWdlID09PSAnVGVtcG9yYXJ5IGVycm9yJzsgLy8gb25seSByZXRyeSBvbiBhIHNwZWNpZmljIGVycm9yXG4gKiAgIH1cbiAqIH0sIGFwaU1ldGhvZCwgZnVuY3Rpb24oZXJyLCByZXN1bHQpIHtcbiAqICAgICAvLyBkbyBzb21ldGhpbmcgd2l0aCB0aGUgcmVzdWx0XG4gKiB9KTtcbiAqXG4gKiAvLyB0byByZXRyeSBpbmRpdmlkdWFsIG1ldGhvZHMgdGhhdCBhcmUgbm90IGFzIHJlbGlhYmxlIHdpdGhpbiBvdGhlclxuICogLy8gY29udHJvbCBmbG93IGZ1bmN0aW9ucywgdXNlIHRoZSBgcmV0cnlhYmxlYCB3cmFwcGVyOlxuICogYXN5bmMuYXV0byh7XG4gKiAgICAgdXNlcnM6IGFwaS5nZXRVc2Vycy5iaW5kKGFwaSksXG4gKiAgICAgcGF5bWVudHM6IGFzeW5jLnJldHJ5YWJsZSgzLCBhcGkuZ2V0UGF5bWVudHMuYmluZChhcGkpKVxuICogfSwgZnVuY3Rpb24oZXJyLCByZXN1bHRzKSB7XG4gKiAgICAgLy8gZG8gc29tZXRoaW5nIHdpdGggdGhlIHJlc3VsdHNcbiAqIH0pO1xuICpcbiAqL1xuY29uc3QgREVGQVVMVF9USU1FUyA9IDU7XG5jb25zdCBERUZBVUxUX0lOVEVSVkFMID0gMDtcblxuZnVuY3Rpb24gcmV0cnkob3B0cywgdGFzaywgY2FsbGJhY2spIHtcbiAgICB2YXIgb3B0aW9ucyA9IHtcbiAgICAgICAgdGltZXM6IERFRkFVTFRfVElNRVMsXG4gICAgICAgIGludGVydmFsRnVuYzogY29uc3RhbnQoREVGQVVMVF9JTlRFUlZBTClcbiAgICB9O1xuXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAzICYmIHR5cGVvZiBvcHRzID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIGNhbGxiYWNrID0gdGFzayB8fCBwcm9taXNlQ2FsbGJhY2soKTtcbiAgICAgICAgdGFzayA9IG9wdHM7XG4gICAgfSBlbHNlIHtcbiAgICAgICAgcGFyc2VUaW1lcyhvcHRpb25zLCBvcHRzKTtcbiAgICAgICAgY2FsbGJhY2sgPSBjYWxsYmFjayB8fCBwcm9taXNlQ2FsbGJhY2soKTtcbiAgICB9XG5cbiAgICBpZiAodHlwZW9mIHRhc2sgIT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW52YWxpZCBhcmd1bWVudHMgZm9yIGFzeW5jLnJldHJ5XCIpO1xuICAgIH1cblxuICAgIHZhciBfdGFzayA9IHdyYXBBc3luYyh0YXNrKTtcblxuICAgIHZhciBhdHRlbXB0ID0gMTtcbiAgICBmdW5jdGlvbiByZXRyeUF0dGVtcHQoKSB7XG4gICAgICAgIF90YXNrKChlcnIsIC4uLmFyZ3MpID0+IHtcbiAgICAgICAgICAgIGlmIChlcnIgPT09IGZhbHNlKSByZXR1cm5cbiAgICAgICAgICAgIGlmIChlcnIgJiYgYXR0ZW1wdCsrIDwgb3B0aW9ucy50aW1lcyAmJlxuICAgICAgICAgICAgICAgICh0eXBlb2Ygb3B0aW9ucy5lcnJvckZpbHRlciAhPSAnZnVuY3Rpb24nIHx8XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuZXJyb3JGaWx0ZXIoZXJyKSkpIHtcbiAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KHJldHJ5QXR0ZW1wdCwgb3B0aW9ucy5pbnRlcnZhbEZ1bmMoYXR0ZW1wdCAtIDEpKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soZXJyLCAuLi5hcmdzKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0cnlBdHRlbXB0KCk7XG4gICAgcmV0dXJuIGNhbGxiYWNrW1BST01JU0VfU1lNQk9MXVxufVxuXG5mdW5jdGlvbiBwYXJzZVRpbWVzKGFjYywgdCkge1xuICAgIGlmICh0eXBlb2YgdCA9PT0gJ29iamVjdCcpIHtcbiAgICAgICAgYWNjLnRpbWVzID0gK3QudGltZXMgfHwgREVGQVVMVF9USU1FUztcblxuICAgICAgICBhY2MuaW50ZXJ2YWxGdW5jID0gdHlwZW9mIHQuaW50ZXJ2YWwgPT09ICdmdW5jdGlvbicgP1xuICAgICAgICAgICAgdC5pbnRlcnZhbCA6XG4gICAgICAgICAgICBjb25zdGFudCgrdC5pbnRlcnZhbCB8fCBERUZBVUxUX0lOVEVSVkFMKTtcblxuICAgICAgICBhY2MuZXJyb3JGaWx0ZXIgPSB0LmVycm9yRmlsdGVyO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHQgPT09ICdudW1iZXInIHx8IHR5cGVvZiB0ID09PSAnc3RyaW5nJykge1xuICAgICAgICBhY2MudGltZXMgPSArdCB8fCBERUZBVUxUX1RJTUVTO1xuICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkludmFsaWQgYXJndW1lbnRzIGZvciBhc3luYy5yZXRyeVwiKTtcbiAgICB9XG59XG5cbi8qKlxuICogQSBjbG9zZSByZWxhdGl2ZSBvZiBbYHJldHJ5YF17QGxpbmsgbW9kdWxlOkNvbnRyb2xGbG93LnJldHJ5fS4gIFRoaXMgbWV0aG9kXG4gKiB3cmFwcyBhIHRhc2sgYW5kIG1ha2VzIGl0IHJldHJ5YWJsZSwgcmF0aGVyIHRoYW4gaW1tZWRpYXRlbHkgY2FsbGluZyBpdFxuICogd2l0aCByZXRyaWVzLlxuICpcbiAqIEBuYW1lIHJldHJ5YWJsZVxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb250cm9sRmxvd1xuICogQG1ldGhvZFxuICogQHNlZSBbYXN5bmMucmV0cnlde0BsaW5rIG1vZHVsZTpDb250cm9sRmxvdy5yZXRyeX1cbiAqIEBjYXRlZ29yeSBDb250cm9sIEZsb3dcbiAqIEBwYXJhbSB7T2JqZWN0fG51bWJlcn0gW29wdHMgPSB7dGltZXM6IDUsIGludGVydmFsOiAwfXwgNV0gLSBvcHRpb25hbFxuICogb3B0aW9ucywgZXhhY3RseSB0aGUgc2FtZSBhcyBmcm9tIGByZXRyeWAsIGV4Y2VwdCBmb3IgYSBgb3B0cy5hcml0eWAgdGhhdFxuICogaXMgdGhlIGFyaXR5IG9mIHRoZSBgdGFza2AgZnVuY3Rpb24sIGRlZmF1bHRpbmcgdG8gYHRhc2subGVuZ3RoYFxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSB0YXNrIC0gdGhlIGFzeW5jaHJvbm91cyBmdW5jdGlvbiB0byB3cmFwLlxuICogVGhpcyBmdW5jdGlvbiB3aWxsIGJlIHBhc3NlZCBhbnkgYXJndW1lbnRzIHBhc3NlZCB0byB0aGUgcmV0dXJuZWQgd3JhcHBlci5cbiAqIEludm9rZWQgd2l0aCAoLi4uYXJncywgY2FsbGJhY2spLlxuICogQHJldHVybnMge0FzeW5jRnVuY3Rpb259IFRoZSB3cmFwcGVkIGZ1bmN0aW9uLCB3aGljaCB3aGVuIGludm9rZWQsIHdpbGxcbiAqIHJldHJ5IG9uIGFuIGVycm9yLCBiYXNlZCBvbiB0aGUgcGFyYW1ldGVycyBzcGVjaWZpZWQgaW4gYG9wdHNgLlxuICogVGhpcyBmdW5jdGlvbiB3aWxsIGFjY2VwdCB0aGUgc2FtZSBwYXJhbWV0ZXJzIGFzIGB0YXNrYC5cbiAqIEBleGFtcGxlXG4gKlxuICogYXN5bmMuYXV0byh7XG4gKiAgICAgZGVwMTogYXN5bmMucmV0cnlhYmxlKDMsIGdldEZyb21GbGFreVNlcnZpY2UpLFxuICogICAgIHByb2Nlc3M6IFtcImRlcDFcIiwgYXN5bmMucmV0cnlhYmxlKDMsIGZ1bmN0aW9uIChyZXN1bHRzLCBjYikge1xuICogICAgICAgICBtYXliZVByb2Nlc3NEYXRhKHJlc3VsdHMuZGVwMSwgY2IpO1xuICogICAgIH0pXVxuICogfSwgY2FsbGJhY2spO1xuICovXG5mdW5jdGlvbiByZXRyeWFibGUgKG9wdHMsIHRhc2spIHtcbiAgICBpZiAoIXRhc2spIHtcbiAgICAgICAgdGFzayA9IG9wdHM7XG4gICAgICAgIG9wdHMgPSBudWxsO1xuICAgIH1cbiAgICBsZXQgYXJpdHkgPSAob3B0cyAmJiBvcHRzLmFyaXR5KSB8fCB0YXNrLmxlbmd0aDtcbiAgICBpZiAoaXNBc3luYyh0YXNrKSkge1xuICAgICAgICBhcml0eSArPSAxO1xuICAgIH1cbiAgICB2YXIgX3Rhc2sgPSB3cmFwQXN5bmModGFzayk7XG4gICAgcmV0dXJuIGluaXRpYWxQYXJhbXMoKGFyZ3MsIGNhbGxiYWNrKSA9PiB7XG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA8IGFyaXR5IC0gMSB8fCBjYWxsYmFjayA9PSBudWxsKSB7XG4gICAgICAgICAgICBhcmdzLnB1c2goY2FsbGJhY2spO1xuICAgICAgICAgICAgY2FsbGJhY2sgPSBwcm9taXNlQ2FsbGJhY2soKTtcbiAgICAgICAgfVxuICAgICAgICBmdW5jdGlvbiB0YXNrRm4oY2IpIHtcbiAgICAgICAgICAgIF90YXNrKC4uLmFyZ3MsIGNiKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChvcHRzKSByZXRyeShvcHRzLCB0YXNrRm4sIGNhbGxiYWNrKTtcbiAgICAgICAgZWxzZSByZXRyeSh0YXNrRm4sIGNhbGxiYWNrKTtcblxuICAgICAgICByZXR1cm4gY2FsbGJhY2tbUFJPTUlTRV9TWU1CT0xdXG4gICAgfSk7XG59XG5cbi8qKlxuICogUnVuIHRoZSBmdW5jdGlvbnMgaW4gdGhlIGB0YXNrc2AgY29sbGVjdGlvbiBpbiBzZXJpZXMsIGVhY2ggb25lIHJ1bm5pbmcgb25jZVxuICogdGhlIHByZXZpb3VzIGZ1bmN0aW9uIGhhcyBjb21wbGV0ZWQuIElmIGFueSBmdW5jdGlvbnMgaW4gdGhlIHNlcmllcyBwYXNzIGFuXG4gKiBlcnJvciB0byBpdHMgY2FsbGJhY2ssIG5vIG1vcmUgZnVuY3Rpb25zIGFyZSBydW4sIGFuZCBgY2FsbGJhY2tgIGlzXG4gKiBpbW1lZGlhdGVseSBjYWxsZWQgd2l0aCB0aGUgdmFsdWUgb2YgdGhlIGVycm9yLiBPdGhlcndpc2UsIGBjYWxsYmFja2BcbiAqIHJlY2VpdmVzIGFuIGFycmF5IG9mIHJlc3VsdHMgd2hlbiBgdGFza3NgIGhhdmUgY29tcGxldGVkLlxuICpcbiAqIEl0IGlzIGFsc28gcG9zc2libGUgdG8gdXNlIGFuIG9iamVjdCBpbnN0ZWFkIG9mIGFuIGFycmF5LiBFYWNoIHByb3BlcnR5IHdpbGxcbiAqIGJlIHJ1biBhcyBhIGZ1bmN0aW9uLCBhbmQgdGhlIHJlc3VsdHMgd2lsbCBiZSBwYXNzZWQgdG8gdGhlIGZpbmFsIGBjYWxsYmFja2BcbiAqIGFzIGFuIG9iamVjdCBpbnN0ZWFkIG9mIGFuIGFycmF5LiBUaGlzIGNhbiBiZSBhIG1vcmUgcmVhZGFibGUgd2F5IG9mIGhhbmRsaW5nXG4gKiAgcmVzdWx0cyBmcm9tIHtAbGluayBhc3luYy5zZXJpZXN9LlxuICpcbiAqICoqTm90ZSoqIHRoYXQgd2hpbGUgbWFueSBpbXBsZW1lbnRhdGlvbnMgcHJlc2VydmUgdGhlIG9yZGVyIG9mIG9iamVjdFxuICogcHJvcGVydGllcywgdGhlIFtFQ01BU2NyaXB0IExhbmd1YWdlIFNwZWNpZmljYXRpb25dKGh0dHA6Ly93d3cuZWNtYS1pbnRlcm5hdGlvbmFsLm9yZy9lY21hLTI2Mi81LjEvI3NlYy04LjYpXG4gKiBleHBsaWNpdGx5IHN0YXRlcyB0aGF0XG4gKlxuICogPiBUaGUgbWVjaGFuaWNzIGFuZCBvcmRlciBvZiBlbnVtZXJhdGluZyB0aGUgcHJvcGVydGllcyBpcyBub3Qgc3BlY2lmaWVkLlxuICpcbiAqIFNvIGlmIHlvdSByZWx5IG9uIHRoZSBvcmRlciBpbiB3aGljaCB5b3VyIHNlcmllcyBvZiBmdW5jdGlvbnMgYXJlIGV4ZWN1dGVkLFxuICogYW5kIHdhbnQgdGhpcyB0byB3b3JrIG9uIGFsbCBwbGF0Zm9ybXMsIGNvbnNpZGVyIHVzaW5nIGFuIGFycmF5LlxuICpcbiAqIEBuYW1lIHNlcmllc1xuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb250cm9sRmxvd1xuICogQG1ldGhvZFxuICogQGNhdGVnb3J5IENvbnRyb2wgRmxvd1xuICogQHBhcmFtIHtBcnJheXxJdGVyYWJsZXxBc3luY0l0ZXJhYmxlfE9iamVjdH0gdGFza3MgLSBBIGNvbGxlY3Rpb24gY29udGFpbmluZ1xuICogW2FzeW5jIGZ1bmN0aW9uc117QGxpbmsgQXN5bmNGdW5jdGlvbn0gdG8gcnVuIGluIHNlcmllcy5cbiAqIEVhY2ggZnVuY3Rpb24gY2FuIGNvbXBsZXRlIHdpdGggYW55IG51bWJlciBvZiBvcHRpb25hbCBgcmVzdWx0YCB2YWx1ZXMuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdIC0gQW4gb3B0aW9uYWwgY2FsbGJhY2sgdG8gcnVuIG9uY2UgYWxsIHRoZVxuICogZnVuY3Rpb25zIGhhdmUgY29tcGxldGVkLiBUaGlzIGZ1bmN0aW9uIGdldHMgYSByZXN1bHRzIGFycmF5IChvciBvYmplY3QpXG4gKiBjb250YWluaW5nIGFsbCB0aGUgcmVzdWx0IGFyZ3VtZW50cyBwYXNzZWQgdG8gdGhlIGB0YXNrYCBjYWxsYmFja3MuIEludm9rZWRcbiAqIHdpdGggKGVyciwgcmVzdWx0KS5cbiAqIEByZXR1cm4ge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgbm8gY2FsbGJhY2sgaXMgcGFzc2VkXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vVXNpbmcgQ2FsbGJhY2tzXG4gKiBhc3luYy5zZXJpZXMoW1xuICogICAgIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgICAgICAvLyBkbyBzb21lIGFzeW5jIHRhc2tcbiAqICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsICdvbmUnKTtcbiAqICAgICAgICAgfSwgMjAwKTtcbiAqICAgICB9LFxuICogICAgIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgICAgICAvLyB0aGVuIGRvIGFub3RoZXIgYXN5bmMgdGFza1xuICogICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgJ3R3bycpO1xuICogICAgICAgICB9LCAxMDApO1xuICogICAgIH1cbiAqIF0sIGZ1bmN0aW9uKGVyciwgcmVzdWx0cykge1xuICogICAgIGNvbnNvbGUubG9nKHJlc3VsdHMpO1xuICogICAgIC8vIHJlc3VsdHMgaXMgZXF1YWwgdG8gWydvbmUnLCd0d28nXVxuICogfSk7XG4gKlxuICogLy8gYW4gZXhhbXBsZSB1c2luZyBvYmplY3RzIGluc3RlYWQgb2YgYXJyYXlzXG4gKiBhc3luYy5zZXJpZXMoe1xuICogICAgIG9uZTogZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAqICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAqICAgICAgICAgICAgIC8vIGRvIHNvbWUgYXN5bmMgdGFza1xuICogICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgMSk7XG4gKiAgICAgICAgIH0sIDIwMCk7XG4gKiAgICAgfSxcbiAqICAgICB0d286IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgICAgICAvLyB0aGVuIGRvIGFub3RoZXIgYXN5bmMgdGFza1xuICogICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgMik7XG4gKiAgICAgICAgIH0sIDEwMCk7XG4gKiAgICAgfVxuICogfSwgZnVuY3Rpb24oZXJyLCByZXN1bHRzKSB7XG4gKiAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiAgICAgLy8gcmVzdWx0cyBpcyBlcXVhbCB0bzogeyBvbmU6IDEsIHR3bzogMiB9XG4gKiB9KTtcbiAqXG4gKiAvL1VzaW5nIFByb21pc2VzXG4gKiBhc3luYy5zZXJpZXMoW1xuICogICAgIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCAnb25lJyk7XG4gKiAgICAgICAgIH0sIDIwMCk7XG4gKiAgICAgfSxcbiAqICAgICBmdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICogICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgJ3R3bycpO1xuICogICAgICAgICB9LCAxMDApO1xuICogICAgIH1cbiAqIF0pLnRoZW4ocmVzdWx0cyA9PiB7XG4gKiAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiAgICAgLy8gcmVzdWx0cyBpcyBlcXVhbCB0byBbJ29uZScsJ3R3byddXG4gKiB9KS5jYXRjaChlcnIgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiB9KTtcbiAqXG4gKiAvLyBhbiBleGFtcGxlIHVzaW5nIGFuIG9iamVjdCBpbnN0ZWFkIG9mIGFuIGFycmF5XG4gKiBhc3luYy5zZXJpZXMoe1xuICogICAgIG9uZTogZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAqICAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAqICAgICAgICAgICAgIC8vIGRvIHNvbWUgYXN5bmMgdGFza1xuICogICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgMSk7XG4gKiAgICAgICAgIH0sIDIwMCk7XG4gKiAgICAgfSxcbiAqICAgICB0d286IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgICAgICAvLyB0aGVuIGRvIGFub3RoZXIgYXN5bmMgdGFza1xuICogICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgMik7XG4gKiAgICAgICAgIH0sIDEwMCk7XG4gKiAgICAgfVxuICogfSkudGhlbihyZXN1bHRzID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhyZXN1bHRzKTtcbiAqICAgICAvLyByZXN1bHRzIGlzIGVxdWFsIHRvOiB7IG9uZTogMSwgdHdvOiAyIH1cbiAqIH0pLmNhdGNoKGVyciA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqIH0pO1xuICpcbiAqIC8vVXNpbmcgYXN5bmMvYXdhaXRcbiAqIGFzeW5jICgpID0+IHtcbiAqICAgICB0cnkge1xuICogICAgICAgICBsZXQgcmVzdWx0cyA9IGF3YWl0IGFzeW5jLnNlcmllcyhbXG4gKiAgICAgICAgICAgICBmdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgICAgICAgICAgICAgIC8vIGRvIHNvbWUgYXN5bmMgdGFza1xuICogICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCAnb25lJyk7XG4gKiAgICAgICAgICAgICAgICAgfSwgMjAwKTtcbiAqICAgICAgICAgICAgIH0sXG4gKiAgICAgICAgICAgICBmdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgICAgICAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgICAgICAgICAgICAgIC8vIHRoZW4gZG8gYW5vdGhlciBhc3luYyB0YXNrXG4gKiAgICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsICd0d28nKTtcbiAqICAgICAgICAgICAgICAgICB9LCAxMDApO1xuICogICAgICAgICAgICAgfVxuICogICAgICAgICBdKTtcbiAqICAgICAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiAgICAgICAgIC8vIHJlc3VsdHMgaXMgZXF1YWwgdG8gWydvbmUnLCd0d28nXVxuICogICAgIH1cbiAqICAgICBjYXRjaCAoZXJyKSB7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiAgICAgfVxuICogfVxuICpcbiAqIC8vIGFuIGV4YW1wbGUgdXNpbmcgYW4gb2JqZWN0IGluc3RlYWQgb2YgYW4gYXJyYXlcbiAqIGFzeW5jICgpID0+IHtcbiAqICAgICB0cnkge1xuICogICAgICAgICBsZXQgcmVzdWx0cyA9IGF3YWl0IGFzeW5jLnBhcmFsbGVsKHtcbiAqICAgICAgICAgICAgIG9uZTogZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAqICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICogICAgICAgICAgICAgICAgICAgICAvLyBkbyBzb21lIGFzeW5jIHRhc2tcbiAqICAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgMSk7XG4gKiAgICAgICAgICAgICAgICAgfSwgMjAwKTtcbiAqICAgICAgICAgICAgIH0sXG4gKiAgICAgICAgICAgIHR3bzogZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAqICAgICAgICAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICogICAgICAgICAgICAgICAgICAgICAvLyB0aGVuIGRvIGFub3RoZXIgYXN5bmMgdGFza1xuICogICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCAyKTtcbiAqICAgICAgICAgICAgICAgICB9LCAxMDApO1xuICogICAgICAgICAgICB9XG4gKiAgICAgICAgIH0pO1xuICogICAgICAgICBjb25zb2xlLmxvZyhyZXN1bHRzKTtcbiAqICAgICAgICAgLy8gcmVzdWx0cyBpcyBlcXVhbCB0bzogeyBvbmU6IDEsIHR3bzogMiB9XG4gKiAgICAgfVxuICogICAgIGNhdGNoIChlcnIpIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICB9XG4gKiB9XG4gKlxuICovXG5mdW5jdGlvbiBzZXJpZXModGFza3MsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIF9wYXJhbGxlbChlYWNoT2ZTZXJpZXMkMSwgdGFza3MsIGNhbGxiYWNrKTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGB0cnVlYCBpZiBhdCBsZWFzdCBvbmUgZWxlbWVudCBpbiB0aGUgYGNvbGxgIHNhdGlzZmllcyBhbiBhc3luYyB0ZXN0LlxuICogSWYgYW55IGl0ZXJhdGVlIGNhbGwgcmV0dXJucyBgdHJ1ZWAsIHRoZSBtYWluIGBjYWxsYmFja2AgaXMgaW1tZWRpYXRlbHlcbiAqIGNhbGxlZC5cbiAqXG4gKiBAbmFtZSBzb21lXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbGxlY3Rpb25zXG4gKiBAbWV0aG9kXG4gKiBAYWxpYXMgYW55XG4gKiBAY2F0ZWdvcnkgQ29sbGVjdGlvblxuICogQHBhcmFtIHtBcnJheXxJdGVyYWJsZXxBc3luY0l0ZXJhYmxlfE9iamVjdH0gY29sbCAtIEEgY29sbGVjdGlvbiB0byBpdGVyYXRlIG92ZXIuXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IGl0ZXJhdGVlIC0gQW4gYXN5bmMgdHJ1dGggdGVzdCB0byBhcHBseSB0byBlYWNoIGl0ZW1cbiAqIGluIHRoZSBjb2xsZWN0aW9ucyBpbiBwYXJhbGxlbC5cbiAqIFRoZSBpdGVyYXRlZSBzaG91bGQgY29tcGxldGUgd2l0aCBhIGJvb2xlYW4gYHJlc3VsdGAgdmFsdWUuXG4gKiBJbnZva2VkIHdpdGggKGl0ZW0sIGNhbGxiYWNrKS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYWxsYmFja10gLSBBIGNhbGxiYWNrIHdoaWNoIGlzIGNhbGxlZCBhcyBzb29uIGFzIGFueVxuICogaXRlcmF0ZWUgcmV0dXJucyBgdHJ1ZWAsIG9yIGFmdGVyIGFsbCB0aGUgaXRlcmF0ZWUgZnVuY3Rpb25zIGhhdmUgZmluaXNoZWQuXG4gKiBSZXN1bHQgd2lsbCBiZSBlaXRoZXIgYHRydWVgIG9yIGBmYWxzZWAgZGVwZW5kaW5nIG9uIHRoZSB2YWx1ZXMgb2YgdGhlIGFzeW5jXG4gKiB0ZXN0cy4gSW52b2tlZCB3aXRoIChlcnIsIHJlc3VsdCkuXG4gKiBAcmV0dXJucyB7UHJvbWlzZX0gYSBwcm9taXNlLCBpZiBubyBjYWxsYmFjayBwcm92aWRlZFxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBkaXIxIGlzIGEgZGlyZWN0b3J5IHRoYXQgY29udGFpbnMgZmlsZTEudHh0LCBmaWxlMi50eHRcbiAqIC8vIGRpcjIgaXMgYSBkaXJlY3RvcnkgdGhhdCBjb250YWlucyBmaWxlMy50eHQsIGZpbGU0LnR4dFxuICogLy8gZGlyMyBpcyBhIGRpcmVjdG9yeSB0aGF0IGNvbnRhaW5zIGZpbGU1LnR4dFxuICogLy8gZGlyNCBkb2VzIG5vdCBleGlzdFxuICpcbiAqIC8vIGFzeW5jaHJvbm91cyBmdW5jdGlvbiB0aGF0IGNoZWNrcyBpZiBhIGZpbGUgZXhpc3RzXG4gKiBmdW5jdGlvbiBmaWxlRXhpc3RzKGZpbGUsIGNhbGxiYWNrKSB7XG4gKiAgICBmcy5hY2Nlc3MoZmlsZSwgZnMuY29uc3RhbnRzLkZfT0ssIChlcnIpID0+IHtcbiAqICAgICAgICBjYWxsYmFjayhudWxsLCAhZXJyKTtcbiAqICAgIH0pO1xuICogfVxuICpcbiAqIC8vIFVzaW5nIGNhbGxiYWNrc1xuICogYXN5bmMuc29tZShbJ2RpcjEvbWlzc2luZy50eHQnLCdkaXIyL21pc3NpbmcudHh0JywnZGlyMy9maWxlNS50eHQnXSwgZmlsZUV4aXN0cyxcbiAqICAgIGZ1bmN0aW9uKGVyciwgcmVzdWx0KSB7XG4gKiAgICAgICAgY29uc29sZS5sb2cocmVzdWx0KTtcbiAqICAgICAgICAvLyB0cnVlXG4gKiAgICAgICAgLy8gcmVzdWx0IGlzIHRydWUgc2luY2Ugc29tZSBmaWxlIGluIHRoZSBsaXN0IGV4aXN0c1xuICogICAgfVxuICopO1xuICpcbiAqIGFzeW5jLnNvbWUoWydkaXIxL21pc3NpbmcudHh0JywnZGlyMi9taXNzaW5nLnR4dCcsJ2RpcjQvbWlzc2luZy50eHQnXSwgZmlsZUV4aXN0cyxcbiAqICAgIGZ1bmN0aW9uKGVyciwgcmVzdWx0KSB7XG4gKiAgICAgICAgY29uc29sZS5sb2cocmVzdWx0KTtcbiAqICAgICAgICAvLyBmYWxzZVxuICogICAgICAgIC8vIHJlc3VsdCBpcyBmYWxzZSBzaW5jZSBub25lIG9mIHRoZSBmaWxlcyBleGlzdHNcbiAqICAgIH1cbiAqKTtcbiAqXG4gKiAvLyBVc2luZyBQcm9taXNlc1xuICogYXN5bmMuc29tZShbJ2RpcjEvbWlzc2luZy50eHQnLCdkaXIyL21pc3NpbmcudHh0JywnZGlyMy9maWxlNS50eHQnXSwgZmlsZUV4aXN0cylcbiAqIC50aGVuKCByZXN1bHQgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKHJlc3VsdCk7XG4gKiAgICAgLy8gdHJ1ZVxuICogICAgIC8vIHJlc3VsdCBpcyB0cnVlIHNpbmNlIHNvbWUgZmlsZSBpbiB0aGUgbGlzdCBleGlzdHNcbiAqIH0pLmNhdGNoKCBlcnIgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiB9KTtcbiAqXG4gKiBhc3luYy5zb21lKFsnZGlyMS9taXNzaW5nLnR4dCcsJ2RpcjIvbWlzc2luZy50eHQnLCdkaXI0L21pc3NpbmcudHh0J10sIGZpbGVFeGlzdHMpXG4gKiAudGhlbiggcmVzdWx0ID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhyZXN1bHQpO1xuICogICAgIC8vIGZhbHNlXG4gKiAgICAgLy8gcmVzdWx0IGlzIGZhbHNlIHNpbmNlIG5vbmUgb2YgdGhlIGZpbGVzIGV4aXN0c1xuICogfSkuY2F0Y2goIGVyciA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqIH0pO1xuICpcbiAqIC8vIFVzaW5nIGFzeW5jL2F3YWl0XG4gKiBhc3luYyAoKSA9PiB7XG4gKiAgICAgdHJ5IHtcbiAqICAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IGFzeW5jLnNvbWUoWydkaXIxL21pc3NpbmcudHh0JywnZGlyMi9taXNzaW5nLnR4dCcsJ2RpcjMvZmlsZTUudHh0J10sIGZpbGVFeGlzdHMpO1xuICogICAgICAgICBjb25zb2xlLmxvZyhyZXN1bHQpO1xuICogICAgICAgICAvLyB0cnVlXG4gKiAgICAgICAgIC8vIHJlc3VsdCBpcyB0cnVlIHNpbmNlIHNvbWUgZmlsZSBpbiB0aGUgbGlzdCBleGlzdHNcbiAqICAgICB9XG4gKiAgICAgY2F0Y2ggKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgIH1cbiAqIH1cbiAqXG4gKiBhc3luYyAoKSA9PiB7XG4gKiAgICAgdHJ5IHtcbiAqICAgICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IGFzeW5jLnNvbWUoWydkaXIxL21pc3NpbmcudHh0JywnZGlyMi9taXNzaW5nLnR4dCcsJ2RpcjQvbWlzc2luZy50eHQnXSwgZmlsZUV4aXN0cyk7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdCk7XG4gKiAgICAgICAgIC8vIGZhbHNlXG4gKiAgICAgICAgIC8vIHJlc3VsdCBpcyBmYWxzZSBzaW5jZSBub25lIG9mIHRoZSBmaWxlcyBleGlzdHNcbiAqICAgICB9XG4gKiAgICAgY2F0Y2ggKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgIH1cbiAqIH1cbiAqXG4gKi9cbmZ1bmN0aW9uIHNvbWUoY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIF9jcmVhdGVUZXN0ZXIoQm9vbGVhbiwgcmVzID0+IHJlcykoZWFjaE9mJDEsIGNvbGwsIGl0ZXJhdGVlLCBjYWxsYmFjaylcbn1cbnZhciBzb21lJDEgPSBhd2FpdGlmeShzb21lLCAzKTtcblxuLyoqXG4gKiBUaGUgc2FtZSBhcyBbYHNvbWVgXXtAbGluayBtb2R1bGU6Q29sbGVjdGlvbnMuc29tZX0gYnV0IHJ1bnMgYSBtYXhpbXVtIG9mIGBsaW1pdGAgYXN5bmMgb3BlcmF0aW9ucyBhdCBhIHRpbWUuXG4gKlxuICogQG5hbWUgc29tZUxpbWl0XG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbGxlY3Rpb25zXG4gKiBAbWV0aG9kXG4gKiBAc2VlIFthc3luYy5zb21lXXtAbGluayBtb2R1bGU6Q29sbGVjdGlvbnMuc29tZX1cbiAqIEBhbGlhcyBhbnlMaW1pdFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IGNvbGwgLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtudW1iZXJ9IGxpbWl0IC0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGFzeW5jIG9wZXJhdGlvbnMgYXQgYSB0aW1lLlxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEFuIGFzeW5jIHRydXRoIHRlc3QgdG8gYXBwbHkgdG8gZWFjaCBpdGVtXG4gKiBpbiB0aGUgY29sbGVjdGlvbnMgaW4gcGFyYWxsZWwuXG4gKiBUaGUgaXRlcmF0ZWUgc2hvdWxkIGNvbXBsZXRlIHdpdGggYSBib29sZWFuIGByZXN1bHRgIHZhbHVlLlxuICogSW52b2tlZCB3aXRoIChpdGVtLCBjYWxsYmFjaykuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY2FsbGJhY2tdIC0gQSBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgYXMgc29vbiBhcyBhbnlcbiAqIGl0ZXJhdGVlIHJldHVybnMgYHRydWVgLCBvciBhZnRlciBhbGwgdGhlIGl0ZXJhdGVlIGZ1bmN0aW9ucyBoYXZlIGZpbmlzaGVkLlxuICogUmVzdWx0IHdpbGwgYmUgZWl0aGVyIGB0cnVlYCBvciBgZmFsc2VgIGRlcGVuZGluZyBvbiB0aGUgdmFsdWVzIG9mIHRoZSBhc3luY1xuICogdGVzdHMuIEludm9rZWQgd2l0aCAoZXJyLCByZXN1bHQpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgbm8gY2FsbGJhY2sgcHJvdmlkZWRcbiAqL1xuZnVuY3Rpb24gc29tZUxpbWl0KGNvbGwsIGxpbWl0LCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICByZXR1cm4gX2NyZWF0ZVRlc3RlcihCb29sZWFuLCByZXMgPT4gcmVzKShlYWNoT2ZMaW1pdCQyKGxpbWl0KSwgY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKVxufVxudmFyIHNvbWVMaW1pdCQxID0gYXdhaXRpZnkoc29tZUxpbWl0LCA0KTtcblxuLyoqXG4gKiBUaGUgc2FtZSBhcyBbYHNvbWVgXXtAbGluayBtb2R1bGU6Q29sbGVjdGlvbnMuc29tZX0gYnV0IHJ1bnMgb25seSBhIHNpbmdsZSBhc3luYyBvcGVyYXRpb24gYXQgYSB0aW1lLlxuICpcbiAqIEBuYW1lIHNvbWVTZXJpZXNcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29sbGVjdGlvbnNcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLnNvbWVde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5zb21lfVxuICogQGFsaWFzIGFueVNlcmllc1xuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IGNvbGwgLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEFuIGFzeW5jIHRydXRoIHRlc3QgdG8gYXBwbHkgdG8gZWFjaCBpdGVtXG4gKiBpbiB0aGUgY29sbGVjdGlvbnMgaW4gc2VyaWVzLlxuICogVGhlIGl0ZXJhdGVlIHNob3VsZCBjb21wbGV0ZSB3aXRoIGEgYm9vbGVhbiBgcmVzdWx0YCB2YWx1ZS5cbiAqIEludm9rZWQgd2l0aCAoaXRlbSwgY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIGFzIHNvb24gYXMgYW55XG4gKiBpdGVyYXRlZSByZXR1cm5zIGB0cnVlYCwgb3IgYWZ0ZXIgYWxsIHRoZSBpdGVyYXRlZSBmdW5jdGlvbnMgaGF2ZSBmaW5pc2hlZC5cbiAqIFJlc3VsdCB3aWxsIGJlIGVpdGhlciBgdHJ1ZWAgb3IgYGZhbHNlYCBkZXBlbmRpbmcgb24gdGhlIHZhbHVlcyBvZiB0aGUgYXN5bmNcbiAqIHRlc3RzLiBJbnZva2VkIHdpdGggKGVyciwgcmVzdWx0KS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIG5vIGNhbGxiYWNrIHByb3ZpZGVkXG4gKi9cbmZ1bmN0aW9uIHNvbWVTZXJpZXMoY29sbCwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIF9jcmVhdGVUZXN0ZXIoQm9vbGVhbiwgcmVzID0+IHJlcykoZWFjaE9mU2VyaWVzJDEsIGNvbGwsIGl0ZXJhdGVlLCBjYWxsYmFjaylcbn1cbnZhciBzb21lU2VyaWVzJDEgPSBhd2FpdGlmeShzb21lU2VyaWVzLCAzKTtcblxuLyoqXG4gKiBTb3J0cyBhIGxpc3QgYnkgdGhlIHJlc3VsdHMgb2YgcnVubmluZyBlYWNoIGBjb2xsYCB2YWx1ZSB0aHJvdWdoIGFuIGFzeW5jXG4gKiBgaXRlcmF0ZWVgLlxuICpcbiAqIEBuYW1lIHNvcnRCeVxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb2xsZWN0aW9uc1xuICogQG1ldGhvZFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IGNvbGwgLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEFuIGFzeW5jIGZ1bmN0aW9uIHRvIGFwcGx5IHRvIGVhY2ggaXRlbSBpblxuICogYGNvbGxgLlxuICogVGhlIGl0ZXJhdGVlIHNob3VsZCBjb21wbGV0ZSB3aXRoIGEgdmFsdWUgdG8gdXNlIGFzIHRoZSBzb3J0IGNyaXRlcmlhIGFzXG4gKiBpdHMgYHJlc3VsdGAuXG4gKiBJbnZva2VkIHdpdGggKGl0ZW0sIGNhbGxiYWNrKS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IGNhbGxiYWNrIC0gQSBjYWxsYmFjayB3aGljaCBpcyBjYWxsZWQgYWZ0ZXIgYWxsIHRoZVxuICogYGl0ZXJhdGVlYCBmdW5jdGlvbnMgaGF2ZSBmaW5pc2hlZCwgb3IgYW4gZXJyb3Igb2NjdXJzLiBSZXN1bHRzIGlzIHRoZSBpdGVtc1xuICogZnJvbSB0aGUgb3JpZ2luYWwgYGNvbGxgIHNvcnRlZCBieSB0aGUgdmFsdWVzIHJldHVybmVkIGJ5IHRoZSBgaXRlcmF0ZWVgXG4gKiBjYWxscy4gSW52b2tlZCB3aXRoIChlcnIsIHJlc3VsdHMpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgbm8gY2FsbGJhY2sgcGFzc2VkXG4gKiBAZXhhbXBsZVxuICpcbiAqIC8vIGJpZ2ZpbGUudHh0IGlzIGEgZmlsZSB0aGF0IGlzIDI1MTEwMCBieXRlcyBpbiBzaXplXG4gKiAvLyBtZWRpdW1maWxlLnR4dCBpcyBhIGZpbGUgdGhhdCBpcyAxMTAwMCBieXRlcyBpbiBzaXplXG4gKiAvLyBzbWFsbGZpbGUudHh0IGlzIGEgZmlsZSB0aGF0IGlzIDEyMSBieXRlcyBpbiBzaXplXG4gKlxuICogLy8gYXN5bmNocm9ub3VzIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgZmlsZSBzaXplIGluIGJ5dGVzXG4gKiBmdW5jdGlvbiBnZXRGaWxlU2l6ZUluQnl0ZXMoZmlsZSwgY2FsbGJhY2spIHtcbiAqICAgICBmcy5zdGF0KGZpbGUsIGZ1bmN0aW9uKGVyciwgc3RhdCkge1xuICogICAgICAgICBpZiAoZXJyKSB7XG4gKiAgICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAqICAgICAgICAgfVxuICogICAgICAgICBjYWxsYmFjayhudWxsLCBzdGF0LnNpemUpO1xuICogICAgIH0pO1xuICogfVxuICpcbiAqIC8vIFVzaW5nIGNhbGxiYWNrc1xuICogYXN5bmMuc29ydEJ5KFsnbWVkaXVtZmlsZS50eHQnLCdzbWFsbGZpbGUudHh0JywnYmlnZmlsZS50eHQnXSwgZ2V0RmlsZVNpemVJbkJ5dGVzLFxuICogICAgIGZ1bmN0aW9uKGVyciwgcmVzdWx0cykge1xuICogICAgICAgICBpZiAoZXJyKSB7XG4gKiAgICAgICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgICAgICB9IGVsc2Uge1xuICogICAgICAgICAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiAgICAgICAgICAgICAvLyByZXN1bHRzIGlzIG5vdyB0aGUgb3JpZ2luYWwgYXJyYXkgb2YgZmlsZXMgc29ydGVkIGJ5XG4gKiAgICAgICAgICAgICAvLyBmaWxlIHNpemUgKGFzY2VuZGluZyBieSBkZWZhdWx0KSwgZS5nLlxuICogICAgICAgICAgICAgLy8gWyAnc21hbGxmaWxlLnR4dCcsICdtZWRpdW1maWxlLnR4dCcsICdiaWdmaWxlLnR4dCddXG4gKiAgICAgICAgIH1cbiAqICAgICB9XG4gKiApO1xuICpcbiAqIC8vIEJ5IG1vZGlmeWluZyB0aGUgY2FsbGJhY2sgcGFyYW1ldGVyIHRoZVxuICogLy8gc29ydGluZyBvcmRlciBjYW4gYmUgaW5mbHVlbmNlZDpcbiAqXG4gKiAvLyBhc2NlbmRpbmcgb3JkZXJcbiAqIGFzeW5jLnNvcnRCeShbJ21lZGl1bWZpbGUudHh0Jywnc21hbGxmaWxlLnR4dCcsJ2JpZ2ZpbGUudHh0J10sIGZ1bmN0aW9uKGZpbGUsIGNhbGxiYWNrKSB7XG4gKiAgICAgZ2V0RmlsZVNpemVJbkJ5dGVzKGZpbGUsIGZ1bmN0aW9uKGdldEZpbGVTaXplRXJyLCBmaWxlU2l6ZSkge1xuICogICAgICAgICBpZiAoZ2V0RmlsZVNpemVFcnIpIHJldHVybiBjYWxsYmFjayhnZXRGaWxlU2l6ZUVycik7XG4gKiAgICAgICAgIGNhbGxiYWNrKG51bGwsIGZpbGVTaXplKTtcbiAqICAgICB9KTtcbiAqIH0sIGZ1bmN0aW9uKGVyciwgcmVzdWx0cykge1xuICogICAgICAgICBpZiAoZXJyKSB7XG4gKiAgICAgICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgICAgICB9IGVsc2Uge1xuICogICAgICAgICAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiAgICAgICAgICAgICAvLyByZXN1bHRzIGlzIG5vdyB0aGUgb3JpZ2luYWwgYXJyYXkgb2YgZmlsZXMgc29ydGVkIGJ5XG4gKiAgICAgICAgICAgICAvLyBmaWxlIHNpemUgKGFzY2VuZGluZyBieSBkZWZhdWx0KSwgZS5nLlxuICogICAgICAgICAgICAgLy8gWyAnc21hbGxmaWxlLnR4dCcsICdtZWRpdW1maWxlLnR4dCcsICdiaWdmaWxlLnR4dCddXG4gKiAgICAgICAgIH1cbiAqICAgICB9XG4gKiApO1xuICpcbiAqIC8vIGRlc2NlbmRpbmcgb3JkZXJcbiAqIGFzeW5jLnNvcnRCeShbJ2JpZ2ZpbGUudHh0JywnbWVkaXVtZmlsZS50eHQnLCdzbWFsbGZpbGUudHh0J10sIGZ1bmN0aW9uKGZpbGUsIGNhbGxiYWNrKSB7XG4gKiAgICAgZ2V0RmlsZVNpemVJbkJ5dGVzKGZpbGUsIGZ1bmN0aW9uKGdldEZpbGVTaXplRXJyLCBmaWxlU2l6ZSkge1xuICogICAgICAgICBpZiAoZ2V0RmlsZVNpemVFcnIpIHtcbiAqICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhnZXRGaWxlU2l6ZUVycik7XG4gKiAgICAgICAgIH1cbiAqICAgICAgICAgY2FsbGJhY2sobnVsbCwgZmlsZVNpemUgKiAtMSk7XG4gKiAgICAgfSk7XG4gKiB9LCBmdW5jdGlvbihlcnIsIHJlc3VsdHMpIHtcbiAqICAgICAgICAgaWYgKGVycikge1xuICogICAgICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICAgICAgfSBlbHNlIHtcbiAqICAgICAgICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdHMpO1xuICogICAgICAgICAgICAgLy8gcmVzdWx0cyBpcyBub3cgdGhlIG9yaWdpbmFsIGFycmF5IG9mIGZpbGVzIHNvcnRlZCBieVxuICogICAgICAgICAgICAgLy8gZmlsZSBzaXplIChhc2NlbmRpbmcgYnkgZGVmYXVsdCksIGUuZy5cbiAqICAgICAgICAgICAgIC8vIFsgJ2JpZ2ZpbGUudHh0JywgJ21lZGl1bWZpbGUudHh0JywgJ3NtYWxsZmlsZS50eHQnXVxuICogICAgICAgICB9XG4gKiAgICAgfVxuICogKTtcbiAqXG4gKiAvLyBFcnJvciBoYW5kbGluZ1xuICogYXN5bmMuc29ydEJ5KFsnbWVkaXVtZmlsZS50eHQnLCdzbWFsbGZpbGUudHh0JywnbWlzc2luZ2ZpbGUudHh0J10sIGdldEZpbGVTaXplSW5CeXRlcyxcbiAqICAgICBmdW5jdGlvbihlcnIsIHJlc3VsdHMpIHtcbiAqICAgICAgICAgaWYgKGVycikge1xuICogICAgICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICAgICAgICAgIC8vIFsgRXJyb3I6IEVOT0VOVDogbm8gc3VjaCBmaWxlIG9yIGRpcmVjdG9yeSBdXG4gKiAgICAgICAgIH0gZWxzZSB7XG4gKiAgICAgICAgICAgICBjb25zb2xlLmxvZyhyZXN1bHRzKTtcbiAqICAgICAgICAgfVxuICogICAgIH1cbiAqICk7XG4gKlxuICogLy8gVXNpbmcgUHJvbWlzZXNcbiAqIGFzeW5jLnNvcnRCeShbJ21lZGl1bWZpbGUudHh0Jywnc21hbGxmaWxlLnR4dCcsJ2JpZ2ZpbGUudHh0J10sIGdldEZpbGVTaXplSW5CeXRlcylcbiAqIC50aGVuKCByZXN1bHRzID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhyZXN1bHRzKTtcbiAqICAgICAvLyByZXN1bHRzIGlzIG5vdyB0aGUgb3JpZ2luYWwgYXJyYXkgb2YgZmlsZXMgc29ydGVkIGJ5XG4gKiAgICAgLy8gZmlsZSBzaXplIChhc2NlbmRpbmcgYnkgZGVmYXVsdCksIGUuZy5cbiAqICAgICAvLyBbICdzbWFsbGZpbGUudHh0JywgJ21lZGl1bWZpbGUudHh0JywgJ2JpZ2ZpbGUudHh0J11cbiAqIH0pLmNhdGNoKCBlcnIgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiB9KTtcbiAqXG4gKiAvLyBFcnJvciBoYW5kbGluZ1xuICogYXN5bmMuc29ydEJ5KFsnbWVkaXVtZmlsZS50eHQnLCdzbWFsbGZpbGUudHh0JywnbWlzc2luZ2ZpbGUudHh0J10sIGdldEZpbGVTaXplSW5CeXRlcylcbiAqIC50aGVuKCByZXN1bHRzID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhyZXN1bHRzKTtcbiAqIH0pLmNhdGNoKCBlcnIgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiAgICAgLy8gWyBFcnJvcjogRU5PRU5UOiBubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5IF1cbiAqIH0pO1xuICpcbiAqIC8vIFVzaW5nIGFzeW5jL2F3YWl0XG4gKiAoYXN5bmMgKCkgPT4ge1xuICogICAgIHRyeSB7XG4gKiAgICAgICAgIGxldCByZXN1bHRzID0gYXdhaXQgYXN5bmMuc29ydEJ5KFsnYmlnZmlsZS50eHQnLCdtZWRpdW1maWxlLnR4dCcsJ3NtYWxsZmlsZS50eHQnXSwgZ2V0RmlsZVNpemVJbkJ5dGVzKTtcbiAqICAgICAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiAgICAgICAgIC8vIHJlc3VsdHMgaXMgbm93IHRoZSBvcmlnaW5hbCBhcnJheSBvZiBmaWxlcyBzb3J0ZWQgYnlcbiAqICAgICAgICAgLy8gZmlsZSBzaXplIChhc2NlbmRpbmcgYnkgZGVmYXVsdCksIGUuZy5cbiAqICAgICAgICAgLy8gWyAnc21hbGxmaWxlLnR4dCcsICdtZWRpdW1maWxlLnR4dCcsICdiaWdmaWxlLnR4dCddXG4gKiAgICAgfVxuICogICAgIGNhdGNoIChlcnIpIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICB9XG4gKiB9KSgpO1xuICpcbiAqIC8vIEVycm9yIGhhbmRsaW5nXG4gKiBhc3luYyAoKSA9PiB7XG4gKiAgICAgdHJ5IHtcbiAqICAgICAgICAgbGV0IHJlc3VsdHMgPSBhd2FpdCBhc3luYy5zb3J0QnkoWydtaXNzaW5nZmlsZS50eHQnLCdtZWRpdW1maWxlLnR4dCcsJ3NtYWxsZmlsZS50eHQnXSwgZ2V0RmlsZVNpemVJbkJ5dGVzKTtcbiAqICAgICAgICAgY29uc29sZS5sb2cocmVzdWx0cyk7XG4gKiAgICAgfVxuICogICAgIGNhdGNoIChlcnIpIHtcbiAqICAgICAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqICAgICAgICAgLy8gWyBFcnJvcjogRU5PRU5UOiBubyBzdWNoIGZpbGUgb3IgZGlyZWN0b3J5IF1cbiAqICAgICB9XG4gKiB9XG4gKlxuICovXG5mdW5jdGlvbiBzb3J0QnkgKGNvbGwsIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIHZhciBfaXRlcmF0ZWUgPSB3cmFwQXN5bmMoaXRlcmF0ZWUpO1xuICAgIHJldHVybiBtYXAkMShjb2xsLCAoeCwgaXRlckNiKSA9PiB7XG4gICAgICAgIF9pdGVyYXRlZSh4LCAoZXJyLCBjcml0ZXJpYSkgPT4ge1xuICAgICAgICAgICAgaWYgKGVycikgcmV0dXJuIGl0ZXJDYihlcnIpO1xuICAgICAgICAgICAgaXRlckNiKGVyciwge3ZhbHVlOiB4LCBjcml0ZXJpYX0pO1xuICAgICAgICB9KTtcbiAgICB9LCAoZXJyLCByZXN1bHRzKSA9PiB7XG4gICAgICAgIGlmIChlcnIpIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICAgICAgICBjYWxsYmFjayhudWxsLCByZXN1bHRzLnNvcnQoY29tcGFyYXRvcikubWFwKHYgPT4gdi52YWx1ZSkpO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gY29tcGFyYXRvcihsZWZ0LCByaWdodCkge1xuICAgICAgICB2YXIgYSA9IGxlZnQuY3JpdGVyaWEsIGIgPSByaWdodC5jcml0ZXJpYTtcbiAgICAgICAgcmV0dXJuIGEgPCBiID8gLTEgOiBhID4gYiA/IDEgOiAwO1xuICAgIH1cbn1cbnZhciBzb3J0QnkkMSA9IGF3YWl0aWZ5KHNvcnRCeSwgMyk7XG5cbi8qKlxuICogU2V0cyBhIHRpbWUgbGltaXQgb24gYW4gYXN5bmNocm9ub3VzIGZ1bmN0aW9uLiBJZiB0aGUgZnVuY3Rpb24gZG9lcyBub3QgY2FsbFxuICogaXRzIGNhbGxiYWNrIHdpdGhpbiB0aGUgc3BlY2lmaWVkIG1pbGxpc2Vjb25kcywgaXQgd2lsbCBiZSBjYWxsZWQgd2l0aCBhXG4gKiB0aW1lb3V0IGVycm9yLiBUaGUgY29kZSBwcm9wZXJ0eSBmb3IgdGhlIGVycm9yIG9iamVjdCB3aWxsIGJlIGAnRVRJTUVET1VUJ2AuXG4gKlxuICogQG5hbWUgdGltZW91dFxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpVdGlsc1xuICogQG1ldGhvZFxuICogQGNhdGVnb3J5IFV0aWxcbiAqIEBwYXJhbSB7QXN5bmNGdW5jdGlvbn0gYXN5bmNGbiAtIFRoZSBhc3luYyBmdW5jdGlvbiB0byBsaW1pdCBpbiB0aW1lLlxuICogQHBhcmFtIHtudW1iZXJ9IG1pbGxpc2Vjb25kcyAtIFRoZSBzcGVjaWZpZWQgdGltZSBsaW1pdC5cbiAqIEBwYXJhbSB7Kn0gW2luZm9dIC0gQW55IHZhcmlhYmxlIHlvdSB3YW50IGF0dGFjaGVkIChgc3RyaW5nYCwgYG9iamVjdGAsIGV0YylcbiAqIHRvIHRpbWVvdXQgRXJyb3IgZm9yIG1vcmUgaW5mb3JtYXRpb24uLlxuICogQHJldHVybnMge0FzeW5jRnVuY3Rpb259IFJldHVybnMgYSB3cmFwcGVkIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIHVzZWQgd2l0aCBhbnlcbiAqIG9mIHRoZSBjb250cm9sIGZsb3cgZnVuY3Rpb25zLlxuICogSW52b2tlIHRoaXMgZnVuY3Rpb24gd2l0aCB0aGUgc2FtZSBwYXJhbWV0ZXJzIGFzIHlvdSB3b3VsZCBgYXN5bmNGdW5jYC5cbiAqIEBleGFtcGxlXG4gKlxuICogZnVuY3Rpb24gbXlGdW5jdGlvbihmb28sIGNhbGxiYWNrKSB7XG4gKiAgICAgZG9Bc3luY1Rhc2soZm9vLCBmdW5jdGlvbihlcnIsIGRhdGEpIHtcbiAqICAgICAgICAgLy8gaGFuZGxlIGVycm9yc1xuICogICAgICAgICBpZiAoZXJyKSByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAqXG4gKiAgICAgICAgIC8vIGRvIHNvbWUgc3R1ZmYgLi4uXG4gKlxuICogICAgICAgICAvLyByZXR1cm4gcHJvY2Vzc2VkIGRhdGFcbiAqICAgICAgICAgcmV0dXJuIGNhbGxiYWNrKG51bGwsIGRhdGEpO1xuICogICAgIH0pO1xuICogfVxuICpcbiAqIHZhciB3cmFwcGVkID0gYXN5bmMudGltZW91dChteUZ1bmN0aW9uLCAxMDAwKTtcbiAqXG4gKiAvLyBjYWxsIGB3cmFwcGVkYCBhcyB5b3Ugd291bGQgYG15RnVuY3Rpb25gXG4gKiB3cmFwcGVkKHsgYmFyOiAnYmFyJyB9LCBmdW5jdGlvbihlcnIsIGRhdGEpIHtcbiAqICAgICAvLyBpZiBgbXlGdW5jdGlvbmAgdGFrZXMgPCAxMDAwIG1zIHRvIGV4ZWN1dGUsIGBlcnJgXG4gKiAgICAgLy8gYW5kIGBkYXRhYCB3aWxsIGhhdmUgdGhlaXIgZXhwZWN0ZWQgdmFsdWVzXG4gKlxuICogICAgIC8vIGVsc2UgYGVycmAgd2lsbCBiZSBhbiBFcnJvciB3aXRoIHRoZSBjb2RlICdFVElNRURPVVQnXG4gKiB9KTtcbiAqL1xuZnVuY3Rpb24gdGltZW91dChhc3luY0ZuLCBtaWxsaXNlY29uZHMsIGluZm8pIHtcbiAgICB2YXIgZm4gPSB3cmFwQXN5bmMoYXN5bmNGbik7XG5cbiAgICByZXR1cm4gaW5pdGlhbFBhcmFtcygoYXJncywgY2FsbGJhY2spID0+IHtcbiAgICAgICAgdmFyIHRpbWVkT3V0ID0gZmFsc2U7XG4gICAgICAgIHZhciB0aW1lcjtcblxuICAgICAgICBmdW5jdGlvbiB0aW1lb3V0Q2FsbGJhY2soKSB7XG4gICAgICAgICAgICB2YXIgbmFtZSA9IGFzeW5jRm4ubmFtZSB8fCAnYW5vbnltb3VzJztcbiAgICAgICAgICAgIHZhciBlcnJvciAgPSBuZXcgRXJyb3IoJ0NhbGxiYWNrIGZ1bmN0aW9uIFwiJyArIG5hbWUgKyAnXCIgdGltZWQgb3V0LicpO1xuICAgICAgICAgICAgZXJyb3IuY29kZSA9ICdFVElNRURPVVQnO1xuICAgICAgICAgICAgaWYgKGluZm8pIHtcbiAgICAgICAgICAgICAgICBlcnJvci5pbmZvID0gaW5mbztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRpbWVkT3V0ID0gdHJ1ZTtcbiAgICAgICAgICAgIGNhbGxiYWNrKGVycm9yKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGFyZ3MucHVzaCgoLi4uY2JBcmdzKSA9PiB7XG4gICAgICAgICAgICBpZiAoIXRpbWVkT3V0KSB7XG4gICAgICAgICAgICAgICAgY2FsbGJhY2soLi4uY2JBcmdzKTtcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcblxuICAgICAgICAvLyBzZXR1cCB0aW1lciBhbmQgY2FsbCBvcmlnaW5hbCBmdW5jdGlvblxuICAgICAgICB0aW1lciA9IHNldFRpbWVvdXQodGltZW91dENhbGxiYWNrLCBtaWxsaXNlY29uZHMpO1xuICAgICAgICBmbiguLi5hcmdzKTtcbiAgICB9KTtcbn1cblxuZnVuY3Rpb24gcmFuZ2Uoc2l6ZSkge1xuICAgIHZhciByZXN1bHQgPSBBcnJheShzaXplKTtcbiAgICB3aGlsZSAoc2l6ZS0tKSB7XG4gICAgICAgIHJlc3VsdFtzaXplXSA9IHNpemU7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG59XG5cbi8qKlxuICogVGhlIHNhbWUgYXMgW3RpbWVzXXtAbGluayBtb2R1bGU6Q29udHJvbEZsb3cudGltZXN9IGJ1dCBydW5zIGEgbWF4aW11bSBvZiBgbGltaXRgIGFzeW5jIG9wZXJhdGlvbnMgYXQgYVxuICogdGltZS5cbiAqXG4gKiBAbmFtZSB0aW1lc0xpbWl0XG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbnRyb2xGbG93XG4gKiBAbWV0aG9kXG4gKiBAc2VlIFthc3luYy50aW1lc117QGxpbmsgbW9kdWxlOkNvbnRyb2xGbG93LnRpbWVzfVxuICogQGNhdGVnb3J5IENvbnRyb2wgRmxvd1xuICogQHBhcmFtIHtudW1iZXJ9IGNvdW50IC0gVGhlIG51bWJlciBvZiB0aW1lcyB0byBydW4gdGhlIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtudW1iZXJ9IGxpbWl0IC0gVGhlIG1heGltdW0gbnVtYmVyIG9mIGFzeW5jIG9wZXJhdGlvbnMgYXQgYSB0aW1lLlxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIFRoZSBhc3luYyBmdW5jdGlvbiB0byBjYWxsIGBuYCB0aW1lcy5cbiAqIEludm9rZWQgd2l0aCB0aGUgaXRlcmF0aW9uIGluZGV4IGFuZCBhIGNhbGxiYWNrOiAobiwgbmV4dCkuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayAtIHNlZSBbYXN5bmMubWFwXXtAbGluayBtb2R1bGU6Q29sbGVjdGlvbnMubWFwfS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIG5vIGNhbGxiYWNrIGlzIHByb3ZpZGVkXG4gKi9cbmZ1bmN0aW9uIHRpbWVzTGltaXQoY291bnQsIGxpbWl0LCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgX2l0ZXJhdGVlID0gd3JhcEFzeW5jKGl0ZXJhdGVlKTtcbiAgICByZXR1cm4gbWFwTGltaXQkMShyYW5nZShjb3VudCksIGxpbWl0LCBfaXRlcmF0ZWUsIGNhbGxiYWNrKTtcbn1cblxuLyoqXG4gKiBDYWxscyB0aGUgYGl0ZXJhdGVlYCBmdW5jdGlvbiBgbmAgdGltZXMsIGFuZCBhY2N1bXVsYXRlcyByZXN1bHRzIGluIHRoZSBzYW1lXG4gKiBtYW5uZXIgeW91IHdvdWxkIHVzZSB3aXRoIFttYXBde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5tYXB9LlxuICpcbiAqIEBuYW1lIHRpbWVzXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbnRyb2xGbG93XG4gKiBAbWV0aG9kXG4gKiBAc2VlIFthc3luYy5tYXBde0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5tYXB9XG4gKiBAY2F0ZWdvcnkgQ29udHJvbCBGbG93XG4gKiBAcGFyYW0ge251bWJlcn0gbiAtIFRoZSBudW1iZXIgb2YgdGltZXMgdG8gcnVuIHRoZSBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7QXN5bmNGdW5jdGlvbn0gaXRlcmF0ZWUgLSBUaGUgYXN5bmMgZnVuY3Rpb24gdG8gY2FsbCBgbmAgdGltZXMuXG4gKiBJbnZva2VkIHdpdGggdGhlIGl0ZXJhdGlvbiBpbmRleCBhbmQgYSBjYWxsYmFjazogKG4sIG5leHQpLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gY2FsbGJhY2sgLSBzZWUge0BsaW5rIG1vZHVsZTpDb2xsZWN0aW9ucy5tYXB9LlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgbm8gY2FsbGJhY2sgaXMgcHJvdmlkZWRcbiAqIEBleGFtcGxlXG4gKlxuICogLy8gUHJldGVuZCB0aGlzIGlzIHNvbWUgY29tcGxpY2F0ZWQgYXN5bmMgZmFjdG9yeVxuICogdmFyIGNyZWF0ZVVzZXIgPSBmdW5jdGlvbihpZCwgY2FsbGJhY2spIHtcbiAqICAgICBjYWxsYmFjayhudWxsLCB7XG4gKiAgICAgICAgIGlkOiAndXNlcicgKyBpZFxuICogICAgIH0pO1xuICogfTtcbiAqXG4gKiAvLyBnZW5lcmF0ZSA1IHVzZXJzXG4gKiBhc3luYy50aW1lcyg1LCBmdW5jdGlvbihuLCBuZXh0KSB7XG4gKiAgICAgY3JlYXRlVXNlcihuLCBmdW5jdGlvbihlcnIsIHVzZXIpIHtcbiAqICAgICAgICAgbmV4dChlcnIsIHVzZXIpO1xuICogICAgIH0pO1xuICogfSwgZnVuY3Rpb24oZXJyLCB1c2Vycykge1xuICogICAgIC8vIHdlIHNob3VsZCBub3cgaGF2ZSA1IHVzZXJzXG4gKiB9KTtcbiAqL1xuZnVuY3Rpb24gdGltZXMgKG4sIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIHJldHVybiB0aW1lc0xpbWl0KG4sIEluZmluaXR5LCBpdGVyYXRlZSwgY2FsbGJhY2spXG59XG5cbi8qKlxuICogVGhlIHNhbWUgYXMgW3RpbWVzXXtAbGluayBtb2R1bGU6Q29udHJvbEZsb3cudGltZXN9IGJ1dCBydW5zIG9ubHkgYSBzaW5nbGUgYXN5bmMgb3BlcmF0aW9uIGF0IGEgdGltZS5cbiAqXG4gKiBAbmFtZSB0aW1lc1Nlcmllc1xuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb250cm9sRmxvd1xuICogQG1ldGhvZFxuICogQHNlZSBbYXN5bmMudGltZXNde0BsaW5rIG1vZHVsZTpDb250cm9sRmxvdy50aW1lc31cbiAqIEBjYXRlZ29yeSBDb250cm9sIEZsb3dcbiAqIEBwYXJhbSB7bnVtYmVyfSBuIC0gVGhlIG51bWJlciBvZiB0aW1lcyB0byBydW4gdGhlIGZ1bmN0aW9uLlxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIFRoZSBhc3luYyBmdW5jdGlvbiB0byBjYWxsIGBuYCB0aW1lcy5cbiAqIEludm9rZWQgd2l0aCB0aGUgaXRlcmF0aW9uIGluZGV4IGFuZCBhIGNhbGxiYWNrOiAobiwgbmV4dCkuXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBjYWxsYmFjayAtIHNlZSB7QGxpbmsgbW9kdWxlOkNvbGxlY3Rpb25zLm1hcH0uXG4gKiBAcmV0dXJucyB7UHJvbWlzZX0gYSBwcm9taXNlLCBpZiBubyBjYWxsYmFjayBpcyBwcm92aWRlZFxuICovXG5mdW5jdGlvbiB0aW1lc1NlcmllcyAobiwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgcmV0dXJuIHRpbWVzTGltaXQobiwgMSwgaXRlcmF0ZWUsIGNhbGxiYWNrKVxufVxuXG4vKipcbiAqIEEgcmVsYXRpdmUgb2YgYHJlZHVjZWAuICBUYWtlcyBhbiBPYmplY3Qgb3IgQXJyYXksIGFuZCBpdGVyYXRlcyBvdmVyIGVhY2hcbiAqIGVsZW1lbnQgaW4gcGFyYWxsZWwsIGVhY2ggc3RlcCBwb3RlbnRpYWxseSBtdXRhdGluZyBhbiBgYWNjdW11bGF0b3JgIHZhbHVlLlxuICogVGhlIHR5cGUgb2YgdGhlIGFjY3VtdWxhdG9yIGRlZmF1bHRzIHRvIHRoZSB0eXBlIG9mIGNvbGxlY3Rpb24gcGFzc2VkIGluLlxuICpcbiAqIEBuYW1lIHRyYW5zZm9ybVxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb2xsZWN0aW9uc1xuICogQG1ldGhvZFxuICogQGNhdGVnb3J5IENvbGxlY3Rpb25cbiAqIEBwYXJhbSB7QXJyYXl8SXRlcmFibGV8QXN5bmNJdGVyYWJsZXxPYmplY3R9IGNvbGwgLSBBIGNvbGxlY3Rpb24gdG8gaXRlcmF0ZSBvdmVyLlxuICogQHBhcmFtIHsqfSBbYWNjdW11bGF0b3JdIC0gVGhlIGluaXRpYWwgc3RhdGUgb2YgdGhlIHRyYW5zZm9ybS4gIElmIG9taXR0ZWQsXG4gKiBpdCB3aWxsIGRlZmF1bHQgdG8gYW4gZW1wdHkgT2JqZWN0IG9yIEFycmF5LCBkZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YgYGNvbGxgXG4gKiBAcGFyYW0ge0FzeW5jRnVuY3Rpb259IGl0ZXJhdGVlIC0gQSBmdW5jdGlvbiBhcHBsaWVkIHRvIGVhY2ggaXRlbSBpbiB0aGVcbiAqIGNvbGxlY3Rpb24gdGhhdCBwb3RlbnRpYWxseSBtb2RpZmllcyB0aGUgYWNjdW11bGF0b3IuXG4gKiBJbnZva2VkIHdpdGggKGFjY3VtdWxhdG9yLCBpdGVtLCBrZXksIGNhbGxiYWNrKS5cbiAqIEBwYXJhbSB7RnVuY3Rpb259IFtjYWxsYmFja10gLSBBIGNhbGxiYWNrIHdoaWNoIGlzIGNhbGxlZCBhZnRlciBhbGwgdGhlXG4gKiBgaXRlcmF0ZWVgIGZ1bmN0aW9ucyBoYXZlIGZpbmlzaGVkLiBSZXN1bHQgaXMgdGhlIHRyYW5zZm9ybWVkIGFjY3VtdWxhdG9yLlxuICogSW52b2tlZCB3aXRoIChlcnIsIHJlc3VsdCkuXG4gKiBAcmV0dXJucyB7UHJvbWlzZX0gYSBwcm9taXNlLCBpZiBubyBjYWxsYmFjayBwcm92aWRlZFxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBmaWxlMS50eHQgaXMgYSBmaWxlIHRoYXQgaXMgMTAwMCBieXRlcyBpbiBzaXplXG4gKiAvLyBmaWxlMi50eHQgaXMgYSBmaWxlIHRoYXQgaXMgMjAwMCBieXRlcyBpbiBzaXplXG4gKiAvLyBmaWxlMy50eHQgaXMgYSBmaWxlIHRoYXQgaXMgMzAwMCBieXRlcyBpbiBzaXplXG4gKlxuICogLy8gaGVscGVyIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBodW1hbi1yZWFkYWJsZSBzaXplIGZvcm1hdCBmcm9tIGJ5dGVzXG4gKiBmdW5jdGlvbiBmb3JtYXRCeXRlcyhieXRlcywgZGVjaW1hbHMgPSAyKSB7XG4gKiAgIC8vIGltcGxlbWVudGF0aW9uIG5vdCBpbmNsdWRlZCBmb3IgYnJldml0eVxuICogICByZXR1cm4gaHVtYW5SZWFkYmxlRmlsZXNpemU7XG4gKiB9XG4gKlxuICogY29uc3QgZmlsZUxpc3QgPSBbJ2ZpbGUxLnR4dCcsJ2ZpbGUyLnR4dCcsJ2ZpbGUzLnR4dCddO1xuICpcbiAqIC8vIGFzeW5jaHJvbm91cyBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIGZpbGUgc2l6ZSwgdHJhbnNmb3JtZWQgdG8gaHVtYW4tcmVhZGFibGUgZm9ybWF0XG4gKiAvLyBlLmcuIDEwMjQgYnl0ZXMgPSAxS0IsIDEyMzQgYnl0ZXMgPSAxLjIxIEtCLCAxMDQ4NTc2IGJ5dGVzID0gMU1CLCBldGMuXG4gKiBmdW5jdGlvbiB0cmFuc2Zvcm1GaWxlU2l6ZShhY2MsIHZhbHVlLCBrZXksIGNhbGxiYWNrKSB7XG4gKiAgICAgZnMuc3RhdCh2YWx1ZSwgZnVuY3Rpb24oZXJyLCBzdGF0KSB7XG4gKiAgICAgICAgIGlmIChlcnIpIHtcbiAqICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICogICAgICAgICB9XG4gKiAgICAgICAgIGFjY1trZXldID0gZm9ybWF0Qnl0ZXMoc3RhdC5zaXplKTtcbiAqICAgICAgICAgY2FsbGJhY2sobnVsbCk7XG4gKiAgICAgfSk7XG4gKiB9XG4gKlxuICogLy8gVXNpbmcgY2FsbGJhY2tzXG4gKiBhc3luYy50cmFuc2Zvcm0oZmlsZUxpc3QsIHRyYW5zZm9ybUZpbGVTaXplLCBmdW5jdGlvbihlcnIsIHJlc3VsdCkge1xuICogICAgIGlmKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgIH0gZWxzZSB7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKHJlc3VsdCk7XG4gKiAgICAgICAgIC8vIFsgJzEwMDAgQnl0ZXMnLCAnMS45NSBLQicsICcyLjkzIEtCJyBdXG4gKiAgICAgfVxuICogfSk7XG4gKlxuICogLy8gVXNpbmcgUHJvbWlzZXNcbiAqIGFzeW5jLnRyYW5zZm9ybShmaWxlTGlzdCwgdHJhbnNmb3JtRmlsZVNpemUpXG4gKiAudGhlbihyZXN1bHQgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKHJlc3VsdCk7XG4gKiAgICAgLy8gWyAnMTAwMCBCeXRlcycsICcxLjk1IEtCJywgJzIuOTMgS0InIF1cbiAqIH0pLmNhdGNoKGVyciA9PiB7XG4gKiAgICAgY29uc29sZS5sb2coZXJyKTtcbiAqIH0pO1xuICpcbiAqIC8vIFVzaW5nIGFzeW5jL2F3YWl0XG4gKiAoYXN5bmMgKCkgPT4ge1xuICogICAgIHRyeSB7XG4gKiAgICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCBhc3luYy50cmFuc2Zvcm0oZmlsZUxpc3QsIHRyYW5zZm9ybUZpbGVTaXplKTtcbiAqICAgICAgICAgY29uc29sZS5sb2cocmVzdWx0KTtcbiAqICAgICAgICAgLy8gWyAnMTAwMCBCeXRlcycsICcxLjk1IEtCJywgJzIuOTMgS0InIF1cbiAqICAgICB9XG4gKiAgICAgY2F0Y2ggKGVycikge1xuICogICAgICAgICBjb25zb2xlLmxvZyhlcnIpO1xuICogICAgIH1cbiAqIH0pKCk7XG4gKlxuICogQGV4YW1wbGVcbiAqXG4gKiAvLyBmaWxlMS50eHQgaXMgYSBmaWxlIHRoYXQgaXMgMTAwMCBieXRlcyBpbiBzaXplXG4gKiAvLyBmaWxlMi50eHQgaXMgYSBmaWxlIHRoYXQgaXMgMjAwMCBieXRlcyBpbiBzaXplXG4gKiAvLyBmaWxlMy50eHQgaXMgYSBmaWxlIHRoYXQgaXMgMzAwMCBieXRlcyBpbiBzaXplXG4gKlxuICogLy8gaGVscGVyIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBodW1hbi1yZWFkYWJsZSBzaXplIGZvcm1hdCBmcm9tIGJ5dGVzXG4gKiBmdW5jdGlvbiBmb3JtYXRCeXRlcyhieXRlcywgZGVjaW1hbHMgPSAyKSB7XG4gKiAgIC8vIGltcGxlbWVudGF0aW9uIG5vdCBpbmNsdWRlZCBmb3IgYnJldml0eVxuICogICByZXR1cm4gaHVtYW5SZWFkYmxlRmlsZXNpemU7XG4gKiB9XG4gKlxuICogY29uc3QgZmlsZU1hcCA9IHsgZjE6ICdmaWxlMS50eHQnLCBmMjogJ2ZpbGUyLnR4dCcsIGYzOiAnZmlsZTMudHh0JyB9O1xuICpcbiAqIC8vIGFzeW5jaHJvbm91cyBmdW5jdGlvbiB0aGF0IHJldHVybnMgdGhlIGZpbGUgc2l6ZSwgdHJhbnNmb3JtZWQgdG8gaHVtYW4tcmVhZGFibGUgZm9ybWF0XG4gKiAvLyBlLmcuIDEwMjQgYnl0ZXMgPSAxS0IsIDEyMzQgYnl0ZXMgPSAxLjIxIEtCLCAxMDQ4NTc2IGJ5dGVzID0gMU1CLCBldGMuXG4gKiBmdW5jdGlvbiB0cmFuc2Zvcm1GaWxlU2l6ZShhY2MsIHZhbHVlLCBrZXksIGNhbGxiYWNrKSB7XG4gKiAgICAgZnMuc3RhdCh2YWx1ZSwgZnVuY3Rpb24oZXJyLCBzdGF0KSB7XG4gKiAgICAgICAgIGlmIChlcnIpIHtcbiAqICAgICAgICAgICAgIHJldHVybiBjYWxsYmFjayhlcnIpO1xuICogICAgICAgICB9XG4gKiAgICAgICAgIGFjY1trZXldID0gZm9ybWF0Qnl0ZXMoc3RhdC5zaXplKTtcbiAqICAgICAgICAgY2FsbGJhY2sobnVsbCk7XG4gKiAgICAgfSk7XG4gKiB9XG4gKlxuICogLy8gVXNpbmcgY2FsbGJhY2tzXG4gKiBhc3luYy50cmFuc2Zvcm0oZmlsZU1hcCwgdHJhbnNmb3JtRmlsZVNpemUsIGZ1bmN0aW9uKGVyciwgcmVzdWx0KSB7XG4gKiAgICAgaWYoZXJyKSB7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiAgICAgfSBlbHNlIHtcbiAqICAgICAgICAgY29uc29sZS5sb2cocmVzdWx0KTtcbiAqICAgICAgICAgLy8geyBmMTogJzEwMDAgQnl0ZXMnLCBmMjogJzEuOTUgS0InLCBmMzogJzIuOTMgS0InIH1cbiAqICAgICB9XG4gKiB9KTtcbiAqXG4gKiAvLyBVc2luZyBQcm9taXNlc1xuICogYXN5bmMudHJhbnNmb3JtKGZpbGVNYXAsIHRyYW5zZm9ybUZpbGVTaXplKVxuICogLnRoZW4ocmVzdWx0ID0+IHtcbiAqICAgICBjb25zb2xlLmxvZyhyZXN1bHQpO1xuICogICAgIC8vIHsgZjE6ICcxMDAwIEJ5dGVzJywgZjI6ICcxLjk1IEtCJywgZjM6ICcyLjkzIEtCJyB9XG4gKiB9KS5jYXRjaChlcnIgPT4ge1xuICogICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiB9KTtcbiAqXG4gKiAvLyBVc2luZyBhc3luYy9hd2FpdFxuICogYXN5bmMgKCkgPT4ge1xuICogICAgIHRyeSB7XG4gKiAgICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCBhc3luYy50cmFuc2Zvcm0oZmlsZU1hcCwgdHJhbnNmb3JtRmlsZVNpemUpO1xuICogICAgICAgICBjb25zb2xlLmxvZyhyZXN1bHQpO1xuICogICAgICAgICAvLyB7IGYxOiAnMTAwMCBCeXRlcycsIGYyOiAnMS45NSBLQicsIGYzOiAnMi45MyBLQicgfVxuICogICAgIH1cbiAqICAgICBjYXRjaCAoZXJyKSB7XG4gKiAgICAgICAgIGNvbnNvbGUubG9nKGVycik7XG4gKiAgICAgfVxuICogfVxuICpcbiAqL1xuZnVuY3Rpb24gdHJhbnNmb3JtIChjb2xsLCBhY2N1bXVsYXRvciwgaXRlcmF0ZWUsIGNhbGxiYWNrKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPD0gMyAmJiB0eXBlb2YgYWNjdW11bGF0b3IgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgY2FsbGJhY2sgPSBpdGVyYXRlZTtcbiAgICAgICAgaXRlcmF0ZWUgPSBhY2N1bXVsYXRvcjtcbiAgICAgICAgYWNjdW11bGF0b3IgPSBBcnJheS5pc0FycmF5KGNvbGwpID8gW10gOiB7fTtcbiAgICB9XG4gICAgY2FsbGJhY2sgPSBvbmNlKGNhbGxiYWNrIHx8IHByb21pc2VDYWxsYmFjaygpKTtcbiAgICB2YXIgX2l0ZXJhdGVlID0gd3JhcEFzeW5jKGl0ZXJhdGVlKTtcblxuICAgIGVhY2hPZiQxKGNvbGwsICh2LCBrLCBjYikgPT4ge1xuICAgICAgICBfaXRlcmF0ZWUoYWNjdW11bGF0b3IsIHYsIGssIGNiKTtcbiAgICB9LCBlcnIgPT4gY2FsbGJhY2soZXJyLCBhY2N1bXVsYXRvcikpO1xuICAgIHJldHVybiBjYWxsYmFja1tQUk9NSVNFX1NZTUJPTF1cbn1cblxuLyoqXG4gKiBJdCBydW5zIGVhY2ggdGFzayBpbiBzZXJpZXMgYnV0IHN0b3BzIHdoZW5ldmVyIGFueSBvZiB0aGUgZnVuY3Rpb25zIHdlcmVcbiAqIHN1Y2Nlc3NmdWwuIElmIG9uZSBvZiB0aGUgdGFza3Mgd2VyZSBzdWNjZXNzZnVsLCB0aGUgYGNhbGxiYWNrYCB3aWxsIGJlXG4gKiBwYXNzZWQgdGhlIHJlc3VsdCBvZiB0aGUgc3VjY2Vzc2Z1bCB0YXNrLiBJZiBhbGwgdGFza3MgZmFpbCwgdGhlIGNhbGxiYWNrXG4gKiB3aWxsIGJlIHBhc3NlZCB0aGUgZXJyb3IgYW5kIHJlc3VsdCAoaWYgYW55KSBvZiB0aGUgZmluYWwgYXR0ZW1wdC5cbiAqXG4gKiBAbmFtZSB0cnlFYWNoXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbnRyb2xGbG93XG4gKiBAbWV0aG9kXG4gKiBAY2F0ZWdvcnkgQ29udHJvbCBGbG93XG4gKiBAcGFyYW0ge0FycmF5fEl0ZXJhYmxlfEFzeW5jSXRlcmFibGV8T2JqZWN0fSB0YXNrcyAtIEEgY29sbGVjdGlvbiBjb250YWluaW5nIGZ1bmN0aW9ucyB0b1xuICogcnVuLCBlYWNoIGZ1bmN0aW9uIGlzIHBhc3NlZCBhIGBjYWxsYmFjayhlcnIsIHJlc3VsdClgIGl0IG11c3QgY2FsbCBvblxuICogY29tcGxldGlvbiB3aXRoIGFuIGVycm9yIGBlcnJgICh3aGljaCBjYW4gYmUgYG51bGxgKSBhbmQgYW4gb3B0aW9uYWwgYHJlc3VsdGBcbiAqIHZhbHVlLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEFuIG9wdGlvbmFsIGNhbGxiYWNrIHdoaWNoIGlzIGNhbGxlZCB3aGVuIG9uZVxuICogb2YgdGhlIHRhc2tzIGhhcyBzdWNjZWVkZWQsIG9yIGFsbCBoYXZlIGZhaWxlZC4gSXQgcmVjZWl2ZXMgdGhlIGBlcnJgIGFuZFxuICogYHJlc3VsdGAgYXJndW1lbnRzIG9mIHRoZSBsYXN0IGF0dGVtcHQgYXQgY29tcGxldGluZyB0aGUgYHRhc2tgLiBJbnZva2VkIHdpdGhcbiAqIChlcnIsIHJlc3VsdHMpLlxuICogQHJldHVybnMge1Byb21pc2V9IGEgcHJvbWlzZSwgaWYgbm8gY2FsbGJhY2sgaXMgcGFzc2VkXG4gKiBAZXhhbXBsZVxuICogYXN5bmMudHJ5RWFjaChbXG4gKiAgICAgZnVuY3Rpb24gZ2V0RGF0YUZyb21GaXJzdFdlYnNpdGUoY2FsbGJhY2spIHtcbiAqICAgICAgICAgLy8gVHJ5IGdldHRpbmcgdGhlIGRhdGEgZnJvbSB0aGUgZmlyc3Qgd2Vic2l0ZVxuICogICAgICAgICBjYWxsYmFjayhlcnIsIGRhdGEpO1xuICogICAgIH0sXG4gKiAgICAgZnVuY3Rpb24gZ2V0RGF0YUZyb21TZWNvbmRXZWJzaXRlKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIC8vIEZpcnN0IHdlYnNpdGUgZmFpbGVkLFxuICogICAgICAgICAvLyBUcnkgZ2V0dGluZyB0aGUgZGF0YSBmcm9tIHRoZSBiYWNrdXAgd2Vic2l0ZVxuICogICAgICAgICBjYWxsYmFjayhlcnIsIGRhdGEpO1xuICogICAgIH1cbiAqIF0sXG4gKiAvLyBvcHRpb25hbCBjYWxsYmFja1xuICogZnVuY3Rpb24oZXJyLCByZXN1bHRzKSB7XG4gKiAgICAgTm93IGRvIHNvbWV0aGluZyB3aXRoIHRoZSBkYXRhLlxuICogfSk7XG4gKlxuICovXG5mdW5jdGlvbiB0cnlFYWNoKHRhc2tzLCBjYWxsYmFjaykge1xuICAgIHZhciBlcnJvciA9IG51bGw7XG4gICAgdmFyIHJlc3VsdDtcbiAgICByZXR1cm4gZWFjaFNlcmllcyQxKHRhc2tzLCAodGFzaywgdGFza0NiKSA9PiB7XG4gICAgICAgIHdyYXBBc3luYyh0YXNrKSgoZXJyLCAuLi5hcmdzKSA9PiB7XG4gICAgICAgICAgICBpZiAoZXJyID09PSBmYWxzZSkgcmV0dXJuIHRhc2tDYihlcnIpO1xuXG4gICAgICAgICAgICBpZiAoYXJncy5sZW5ndGggPCAyKSB7XG4gICAgICAgICAgICAgICAgW3Jlc3VsdF0gPSBhcmdzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICByZXN1bHQgPSBhcmdzO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZXJyb3IgPSBlcnI7XG4gICAgICAgICAgICB0YXNrQ2IoZXJyID8gbnVsbCA6IHt9KTtcbiAgICAgICAgfSk7XG4gICAgfSwgKCkgPT4gY2FsbGJhY2soZXJyb3IsIHJlc3VsdCkpO1xufVxuXG52YXIgdHJ5RWFjaCQxID0gYXdhaXRpZnkodHJ5RWFjaCk7XG5cbi8qKlxuICogVW5kb2VzIGEgW21lbW9pemVde0BsaW5rIG1vZHVsZTpVdGlscy5tZW1vaXplfWQgZnVuY3Rpb24sIHJldmVydGluZyBpdCB0byB0aGUgb3JpZ2luYWwsXG4gKiB1bm1lbW9pemVkIGZvcm0uIEhhbmR5IGZvciB0ZXN0aW5nLlxuICpcbiAqIEBuYW1lIHVubWVtb2l6ZVxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpVdGlsc1xuICogQG1ldGhvZFxuICogQHNlZSBbYXN5bmMubWVtb2l6ZV17QGxpbmsgbW9kdWxlOlV0aWxzLm1lbW9pemV9XG4gKiBAY2F0ZWdvcnkgVXRpbFxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBmbiAtIHRoZSBtZW1vaXplZCBmdW5jdGlvblxuICogQHJldHVybnMge0FzeW5jRnVuY3Rpb259IGEgZnVuY3Rpb24gdGhhdCBjYWxscyB0aGUgb3JpZ2luYWwgdW5tZW1vaXplZCBmdW5jdGlvblxuICovXG5mdW5jdGlvbiB1bm1lbW9pemUoZm4pIHtcbiAgICByZXR1cm4gKC4uLmFyZ3MpID0+IHtcbiAgICAgICAgcmV0dXJuIChmbi51bm1lbW9pemVkIHx8IGZuKSguLi5hcmdzKTtcbiAgICB9O1xufVxuXG4vKipcbiAqIFJlcGVhdGVkbHkgY2FsbCBgaXRlcmF0ZWVgLCB3aGlsZSBgdGVzdGAgcmV0dXJucyBgdHJ1ZWAuIENhbGxzIGBjYWxsYmFja2Agd2hlblxuICogc3RvcHBlZCwgb3IgYW4gZXJyb3Igb2NjdXJzLlxuICpcbiAqIEBuYW1lIHdoaWxzdFxuICogQHN0YXRpY1xuICogQG1lbWJlck9mIG1vZHVsZTpDb250cm9sRmxvd1xuICogQG1ldGhvZFxuICogQGNhdGVnb3J5IENvbnRyb2wgRmxvd1xuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSB0ZXN0IC0gYXN5bmNocm9ub3VzIHRydXRoIHRlc3QgdG8gcGVyZm9ybSBiZWZvcmUgZWFjaFxuICogZXhlY3V0aW9uIG9mIGBpdGVyYXRlZWAuIEludm9rZWQgd2l0aCAoY2FsbGJhY2spLlxuICogQHBhcmFtIHtBc3luY0Z1bmN0aW9ufSBpdGVyYXRlZSAtIEFuIGFzeW5jIGZ1bmN0aW9uIHdoaWNoIGlzIGNhbGxlZCBlYWNoIHRpbWVcbiAqIGB0ZXN0YCBwYXNzZXMuIEludm9rZWQgd2l0aCAoY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIGFmdGVyIHRoZSB0ZXN0XG4gKiBmdW5jdGlvbiBoYXMgZmFpbGVkIGFuZCByZXBlYXRlZCBleGVjdXRpb24gb2YgYGl0ZXJhdGVlYCBoYXMgc3RvcHBlZC4gYGNhbGxiYWNrYFxuICogd2lsbCBiZSBwYXNzZWQgYW4gZXJyb3IgYW5kIGFueSBhcmd1bWVudHMgcGFzc2VkIHRvIHRoZSBmaW5hbCBgaXRlcmF0ZWVgJ3NcbiAqIGNhbGxiYWNrLiBJbnZva2VkIHdpdGggKGVyciwgW3Jlc3VsdHNdKTtcbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIG5vIGNhbGxiYWNrIGlzIHBhc3NlZFxuICogQGV4YW1wbGVcbiAqXG4gKiB2YXIgY291bnQgPSAwO1xuICogYXN5bmMud2hpbHN0KFxuICogICAgIGZ1bmN0aW9uIHRlc3QoY2IpIHsgY2IobnVsbCwgY291bnQgPCA1KTsgfSxcbiAqICAgICBmdW5jdGlvbiBpdGVyKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIGNvdW50Kys7XG4gKiAgICAgICAgIHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG4gKiAgICAgICAgICAgICBjYWxsYmFjayhudWxsLCBjb3VudCk7XG4gKiAgICAgICAgIH0sIDEwMDApO1xuICogICAgIH0sXG4gKiAgICAgZnVuY3Rpb24gKGVyciwgbikge1xuICogICAgICAgICAvLyA1IHNlY29uZHMgaGF2ZSBwYXNzZWQsIG4gPSA1XG4gKiAgICAgfVxuICogKTtcbiAqL1xuZnVuY3Rpb24gd2hpbHN0KHRlc3QsIGl0ZXJhdGVlLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gb25seU9uY2UoY2FsbGJhY2spO1xuICAgIHZhciBfZm4gPSB3cmFwQXN5bmMoaXRlcmF0ZWUpO1xuICAgIHZhciBfdGVzdCA9IHdyYXBBc3luYyh0ZXN0KTtcbiAgICB2YXIgcmVzdWx0cyA9IFtdO1xuXG4gICAgZnVuY3Rpb24gbmV4dChlcnIsIC4uLnJlc3QpIHtcbiAgICAgICAgaWYgKGVycikgcmV0dXJuIGNhbGxiYWNrKGVycik7XG4gICAgICAgIHJlc3VsdHMgPSByZXN0O1xuICAgICAgICBpZiAoZXJyID09PSBmYWxzZSkgcmV0dXJuO1xuICAgICAgICBfdGVzdChjaGVjayk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gY2hlY2soZXJyLCB0cnV0aCkge1xuICAgICAgICBpZiAoZXJyKSByZXR1cm4gY2FsbGJhY2soZXJyKTtcbiAgICAgICAgaWYgKGVyciA9PT0gZmFsc2UpIHJldHVybjtcbiAgICAgICAgaWYgKCF0cnV0aCkgcmV0dXJuIGNhbGxiYWNrKG51bGwsIC4uLnJlc3VsdHMpO1xuICAgICAgICBfZm4obmV4dCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIF90ZXN0KGNoZWNrKTtcbn1cbnZhciB3aGlsc3QkMSA9IGF3YWl0aWZ5KHdoaWxzdCwgMyk7XG5cbi8qKlxuICogUmVwZWF0ZWRseSBjYWxsIGBpdGVyYXRlZWAgdW50aWwgYHRlc3RgIHJldHVybnMgYHRydWVgLiBDYWxscyBgY2FsbGJhY2tgIHdoZW5cbiAqIHN0b3BwZWQsIG9yIGFuIGVycm9yIG9jY3Vycy4gYGNhbGxiYWNrYCB3aWxsIGJlIHBhc3NlZCBhbiBlcnJvciBhbmQgYW55XG4gKiBhcmd1bWVudHMgcGFzc2VkIHRvIHRoZSBmaW5hbCBgaXRlcmF0ZWVgJ3MgY2FsbGJhY2suXG4gKlxuICogVGhlIGludmVyc2Ugb2YgW3doaWxzdF17QGxpbmsgbW9kdWxlOkNvbnRyb2xGbG93LndoaWxzdH0uXG4gKlxuICogQG5hbWUgdW50aWxcbiAqIEBzdGF0aWNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6Q29udHJvbEZsb3dcbiAqIEBtZXRob2RcbiAqIEBzZWUgW2FzeW5jLndoaWxzdF17QGxpbmsgbW9kdWxlOkNvbnRyb2xGbG93LndoaWxzdH1cbiAqIEBjYXRlZ29yeSBDb250cm9sIEZsb3dcbiAqIEBwYXJhbSB7QXN5bmNGdW5jdGlvbn0gdGVzdCAtIGFzeW5jaHJvbm91cyB0cnV0aCB0ZXN0IHRvIHBlcmZvcm0gYmVmb3JlIGVhY2hcbiAqIGV4ZWN1dGlvbiBvZiBgaXRlcmF0ZWVgLiBJbnZva2VkIHdpdGggKGNhbGxiYWNrKS5cbiAqIEBwYXJhbSB7QXN5bmNGdW5jdGlvbn0gaXRlcmF0ZWUgLSBBbiBhc3luYyBmdW5jdGlvbiB3aGljaCBpcyBjYWxsZWQgZWFjaCB0aW1lXG4gKiBgdGVzdGAgZmFpbHMuIEludm9rZWQgd2l0aCAoY2FsbGJhY2spLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEEgY2FsbGJhY2sgd2hpY2ggaXMgY2FsbGVkIGFmdGVyIHRoZSB0ZXN0XG4gKiBmdW5jdGlvbiBoYXMgcGFzc2VkIGFuZCByZXBlYXRlZCBleGVjdXRpb24gb2YgYGl0ZXJhdGVlYCBoYXMgc3RvcHBlZC4gYGNhbGxiYWNrYFxuICogd2lsbCBiZSBwYXNzZWQgYW4gZXJyb3IgYW5kIGFueSBhcmd1bWVudHMgcGFzc2VkIHRvIHRoZSBmaW5hbCBgaXRlcmF0ZWVgJ3NcbiAqIGNhbGxiYWNrLiBJbnZva2VkIHdpdGggKGVyciwgW3Jlc3VsdHNdKTtcbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIGEgY2FsbGJhY2sgaXMgbm90IHBhc3NlZFxuICpcbiAqIEBleGFtcGxlXG4gKiBjb25zdCByZXN1bHRzID0gW11cbiAqIGxldCBmaW5pc2hlZCA9IGZhbHNlXG4gKiBhc3luYy51bnRpbChmdW5jdGlvbiB0ZXN0KGNiKSB7XG4gKiAgICAgY2IobnVsbCwgZmluaXNoZWQpXG4gKiB9LCBmdW5jdGlvbiBpdGVyKG5leHQpIHtcbiAqICAgICBmZXRjaFBhZ2UodXJsLCAoZXJyLCBib2R5KSA9PiB7XG4gKiAgICAgICAgIGlmIChlcnIpIHJldHVybiBuZXh0KGVycilcbiAqICAgICAgICAgcmVzdWx0cyA9IHJlc3VsdHMuY29uY2F0KGJvZHkub2JqZWN0cylcbiAqICAgICAgICAgZmluaXNoZWQgPSAhIWJvZHkubmV4dFxuICogICAgICAgICBuZXh0KGVycilcbiAqICAgICB9KVxuICogfSwgZnVuY3Rpb24gZG9uZSAoZXJyKSB7XG4gKiAgICAgLy8gYWxsIHBhZ2VzIGhhdmUgYmVlbiBmZXRjaGVkXG4gKiB9KVxuICovXG5mdW5jdGlvbiB1bnRpbCh0ZXN0LCBpdGVyYXRlZSwgY2FsbGJhY2spIHtcbiAgICBjb25zdCBfdGVzdCA9IHdyYXBBc3luYyh0ZXN0KTtcbiAgICByZXR1cm4gd2hpbHN0JDEoKGNiKSA9PiBfdGVzdCgoZXJyLCB0cnV0aCkgPT4gY2IgKGVyciwgIXRydXRoKSksIGl0ZXJhdGVlLCBjYWxsYmFjayk7XG59XG5cbi8qKlxuICogUnVucyB0aGUgYHRhc2tzYCBhcnJheSBvZiBmdW5jdGlvbnMgaW4gc2VyaWVzLCBlYWNoIHBhc3NpbmcgdGhlaXIgcmVzdWx0cyB0b1xuICogdGhlIG5leHQgaW4gdGhlIGFycmF5LiBIb3dldmVyLCBpZiBhbnkgb2YgdGhlIGB0YXNrc2AgcGFzcyBhbiBlcnJvciB0byB0aGVpclxuICogb3duIGNhbGxiYWNrLCB0aGUgbmV4dCBmdW5jdGlvbiBpcyBub3QgZXhlY3V0ZWQsIGFuZCB0aGUgbWFpbiBgY2FsbGJhY2tgIGlzXG4gKiBpbW1lZGlhdGVseSBjYWxsZWQgd2l0aCB0aGUgZXJyb3IuXG4gKlxuICogQG5hbWUgd2F0ZXJmYWxsXG4gKiBAc3RhdGljXG4gKiBAbWVtYmVyT2YgbW9kdWxlOkNvbnRyb2xGbG93XG4gKiBAbWV0aG9kXG4gKiBAY2F0ZWdvcnkgQ29udHJvbCBGbG93XG4gKiBAcGFyYW0ge0FycmF5fSB0YXNrcyAtIEFuIGFycmF5IG9mIFthc3luYyBmdW5jdGlvbnNde0BsaW5rIEFzeW5jRnVuY3Rpb259XG4gKiB0byBydW4uXG4gKiBFYWNoIGZ1bmN0aW9uIHNob3VsZCBjb21wbGV0ZSB3aXRoIGFueSBudW1iZXIgb2YgYHJlc3VsdGAgdmFsdWVzLlxuICogVGhlIGByZXN1bHRgIHZhbHVlcyB3aWxsIGJlIHBhc3NlZCBhcyBhcmd1bWVudHMsIGluIG9yZGVyLCB0byB0aGUgbmV4dCB0YXNrLlxuICogQHBhcmFtIHtGdW5jdGlvbn0gW2NhbGxiYWNrXSAtIEFuIG9wdGlvbmFsIGNhbGxiYWNrIHRvIHJ1biBvbmNlIGFsbCB0aGVcbiAqIGZ1bmN0aW9ucyBoYXZlIGNvbXBsZXRlZC4gVGhpcyB3aWxsIGJlIHBhc3NlZCB0aGUgcmVzdWx0cyBvZiB0aGUgbGFzdCB0YXNrJ3NcbiAqIGNhbGxiYWNrLiBJbnZva2VkIHdpdGggKGVyciwgW3Jlc3VsdHNdKS5cbiAqIEByZXR1cm5zIHtQcm9taXNlfSBhIHByb21pc2UsIGlmIGEgY2FsbGJhY2sgaXMgb21pdHRlZFxuICogQGV4YW1wbGVcbiAqXG4gKiBhc3luYy53YXRlcmZhbGwoW1xuICogICAgIGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIGNhbGxiYWNrKG51bGwsICdvbmUnLCAndHdvJyk7XG4gKiAgICAgfSxcbiAqICAgICBmdW5jdGlvbihhcmcxLCBhcmcyLCBjYWxsYmFjaykge1xuICogICAgICAgICAvLyBhcmcxIG5vdyBlcXVhbHMgJ29uZScgYW5kIGFyZzIgbm93IGVxdWFscyAndHdvJ1xuICogICAgICAgICBjYWxsYmFjayhudWxsLCAndGhyZWUnKTtcbiAqICAgICB9LFxuICogICAgIGZ1bmN0aW9uKGFyZzEsIGNhbGxiYWNrKSB7XG4gKiAgICAgICAgIC8vIGFyZzEgbm93IGVxdWFscyAndGhyZWUnXG4gKiAgICAgICAgIGNhbGxiYWNrKG51bGwsICdkb25lJyk7XG4gKiAgICAgfVxuICogXSwgZnVuY3Rpb24gKGVyciwgcmVzdWx0KSB7XG4gKiAgICAgLy8gcmVzdWx0IG5vdyBlcXVhbHMgJ2RvbmUnXG4gKiB9KTtcbiAqXG4gKiAvLyBPciwgd2l0aCBuYW1lZCBmdW5jdGlvbnM6XG4gKiBhc3luYy53YXRlcmZhbGwoW1xuICogICAgIG15Rmlyc3RGdW5jdGlvbixcbiAqICAgICBteVNlY29uZEZ1bmN0aW9uLFxuICogICAgIG15TGFzdEZ1bmN0aW9uLFxuICogXSwgZnVuY3Rpb24gKGVyciwgcmVzdWx0KSB7XG4gKiAgICAgLy8gcmVzdWx0IG5vdyBlcXVhbHMgJ2RvbmUnXG4gKiB9KTtcbiAqIGZ1bmN0aW9uIG15Rmlyc3RGdW5jdGlvbihjYWxsYmFjaykge1xuICogICAgIGNhbGxiYWNrKG51bGwsICdvbmUnLCAndHdvJyk7XG4gKiB9XG4gKiBmdW5jdGlvbiBteVNlY29uZEZ1bmN0aW9uKGFyZzEsIGFyZzIsIGNhbGxiYWNrKSB7XG4gKiAgICAgLy8gYXJnMSBub3cgZXF1YWxzICdvbmUnIGFuZCBhcmcyIG5vdyBlcXVhbHMgJ3R3bydcbiAqICAgICBjYWxsYmFjayhudWxsLCAndGhyZWUnKTtcbiAqIH1cbiAqIGZ1bmN0aW9uIG15TGFzdEZ1bmN0aW9uKGFyZzEsIGNhbGxiYWNrKSB7XG4gKiAgICAgLy8gYXJnMSBub3cgZXF1YWxzICd0aHJlZSdcbiAqICAgICBjYWxsYmFjayhudWxsLCAnZG9uZScpO1xuICogfVxuICovXG5mdW5jdGlvbiB3YXRlcmZhbGwgKHRhc2tzLCBjYWxsYmFjaykge1xuICAgIGNhbGxiYWNrID0gb25jZShjYWxsYmFjayk7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRhc2tzKSkgcmV0dXJuIGNhbGxiYWNrKG5ldyBFcnJvcignRmlyc3QgYXJndW1lbnQgdG8gd2F0ZXJmYWxsIG11c3QgYmUgYW4gYXJyYXkgb2YgZnVuY3Rpb25zJykpO1xuICAgIGlmICghdGFza3MubGVuZ3RoKSByZXR1cm4gY2FsbGJhY2soKTtcbiAgICB2YXIgdGFza0luZGV4ID0gMDtcblxuICAgIGZ1bmN0aW9uIG5leHRUYXNrKGFyZ3MpIHtcbiAgICAgICAgdmFyIHRhc2sgPSB3cmFwQXN5bmModGFza3NbdGFza0luZGV4KytdKTtcbiAgICAgICAgdGFzayguLi5hcmdzLCBvbmx5T25jZShuZXh0KSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbmV4dChlcnIsIC4uLmFyZ3MpIHtcbiAgICAgICAgaWYgKGVyciA9PT0gZmFsc2UpIHJldHVyblxuICAgICAgICBpZiAoZXJyIHx8IHRhc2tJbmRleCA9PT0gdGFza3MubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gY2FsbGJhY2soZXJyLCAuLi5hcmdzKTtcbiAgICAgICAgfVxuICAgICAgICBuZXh0VGFzayhhcmdzKTtcbiAgICB9XG5cbiAgICBuZXh0VGFzayhbXSk7XG59XG5cbnZhciB3YXRlcmZhbGwkMSA9IGF3YWl0aWZ5KHdhdGVyZmFsbCk7XG5cbi8qKlxuICogQW4gXCJhc3luYyBmdW5jdGlvblwiIGluIHRoZSBjb250ZXh0IG9mIEFzeW5jIGlzIGFuIGFzeW5jaHJvbm91cyBmdW5jdGlvbiB3aXRoXG4gKiBhIHZhcmlhYmxlIG51bWJlciBvZiBwYXJhbWV0ZXJzLCB3aXRoIHRoZSBmaW5hbCBwYXJhbWV0ZXIgYmVpbmcgYSBjYWxsYmFjay5cbiAqIChgZnVuY3Rpb24gKGFyZzEsIGFyZzIsIC4uLiwgY2FsbGJhY2spIHt9YClcbiAqIFRoZSBmaW5hbCBjYWxsYmFjayBpcyBvZiB0aGUgZm9ybSBgY2FsbGJhY2soZXJyLCByZXN1bHRzLi4uKWAsIHdoaWNoIG11c3QgYmVcbiAqIGNhbGxlZCBvbmNlIHRoZSBmdW5jdGlvbiBpcyBjb21wbGV0ZWQuICBUaGUgY2FsbGJhY2sgc2hvdWxkIGJlIGNhbGxlZCB3aXRoIGFcbiAqIEVycm9yIGFzIGl0cyBmaXJzdCBhcmd1bWVudCB0byBzaWduYWwgdGhhdCBhbiBlcnJvciBvY2N1cnJlZC5cbiAqIE90aGVyd2lzZSwgaWYgbm8gZXJyb3Igb2NjdXJyZWQsIGl0IHNob3VsZCBiZSBjYWxsZWQgd2l0aCBgbnVsbGAgYXMgdGhlIGZpcnN0XG4gKiBhcmd1bWVudCwgYW5kIGFueSBhZGRpdGlvbmFsIGByZXN1bHRgIGFyZ3VtZW50cyB0aGF0IG1heSBhcHBseSwgdG8gc2lnbmFsXG4gKiBzdWNjZXNzZnVsIGNvbXBsZXRpb24uXG4gKiBUaGUgY2FsbGJhY2sgbXVzdCBiZSBjYWxsZWQgZXhhY3RseSBvbmNlLCBpZGVhbGx5IG9uIGEgbGF0ZXIgdGljayBvZiB0aGVcbiAqIEphdmFTY3JpcHQgZXZlbnQgbG9vcC5cbiAqXG4gKiBUaGlzIHR5cGUgb2YgZnVuY3Rpb24gaXMgYWxzbyByZWZlcnJlZCB0byBhcyBhIFwiTm9kZS1zdHlsZSBhc3luYyBmdW5jdGlvblwiLFxuICogb3IgYSBcImNvbnRpbnVhdGlvbiBwYXNzaW5nLXN0eWxlIGZ1bmN0aW9uXCIgKENQUykuIE1vc3Qgb2YgdGhlIG1ldGhvZHMgb2YgdGhpc1xuICogbGlicmFyeSBhcmUgdGhlbXNlbHZlcyBDUFMvTm9kZS1zdHlsZSBhc3luYyBmdW5jdGlvbnMsIG9yIGZ1bmN0aW9ucyB0aGF0XG4gKiByZXR1cm4gQ1BTL05vZGUtc3R5bGUgYXN5bmMgZnVuY3Rpb25zLlxuICpcbiAqIFdoZXJldmVyIHdlIGFjY2VwdCBhIE5vZGUtc3R5bGUgYXN5bmMgZnVuY3Rpb24sIHdlIGFsc28gZGlyZWN0bHkgYWNjZXB0IGFuXG4gKiBbRVMyMDE3IGBhc3luY2AgZnVuY3Rpb25de0BsaW5rIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0phdmFTY3JpcHQvUmVmZXJlbmNlL1N0YXRlbWVudHMvYXN5bmNfZnVuY3Rpb259LlxuICogSW4gdGhpcyBjYXNlLCB0aGUgYGFzeW5jYCBmdW5jdGlvbiB3aWxsIG5vdCBiZSBwYXNzZWQgYSBmaW5hbCBjYWxsYmFja1xuICogYXJndW1lbnQsIGFuZCBhbnkgdGhyb3duIGVycm9yIHdpbGwgYmUgdXNlZCBhcyB0aGUgYGVycmAgYXJndW1lbnQgb2YgdGhlXG4gKiBpbXBsaWNpdCBjYWxsYmFjaywgYW5kIHRoZSByZXR1cm4gdmFsdWUgd2lsbCBiZSB1c2VkIGFzIHRoZSBgcmVzdWx0YCB2YWx1ZS5cbiAqIChpLmUuIGEgYHJlamVjdGVkYCBvZiB0aGUgcmV0dXJuZWQgUHJvbWlzZSBiZWNvbWVzIHRoZSBgZXJyYCBjYWxsYmFja1xuICogYXJndW1lbnQsIGFuZCBhIGByZXNvbHZlZGAgdmFsdWUgYmVjb21lcyB0aGUgYHJlc3VsdGAuKVxuICpcbiAqIE5vdGUsIGR1ZSB0byBKYXZhU2NyaXB0IGxpbWl0YXRpb25zLCB3ZSBjYW4gb25seSBkZXRlY3QgbmF0aXZlIGBhc3luY2BcbiAqIGZ1bmN0aW9ucyBhbmQgbm90IHRyYW5zcGlsaWVkIGltcGxlbWVudGF0aW9ucy5cbiAqIFlvdXIgZW52aXJvbm1lbnQgbXVzdCBoYXZlIGBhc3luY2AvYGF3YWl0YCBzdXBwb3J0IGZvciB0aGlzIHRvIHdvcmsuXG4gKiAoZS5nLiBOb2RlID4gdjcuNiwgb3IgYSByZWNlbnQgdmVyc2lvbiBvZiBhIG1vZGVybiBicm93c2VyKS5cbiAqIElmIHlvdSBhcmUgdXNpbmcgYGFzeW5jYCBmdW5jdGlvbnMgdGhyb3VnaCBhIHRyYW5zcGlsZXIgKGUuZy4gQmFiZWwpLCB5b3VcbiAqIG11c3Qgc3RpbGwgd3JhcCB0aGUgZnVuY3Rpb24gd2l0aCBbYXN5bmNpZnlde0BsaW5rIG1vZHVsZTpVdGlscy5hc3luY2lmeX0sXG4gKiBiZWNhdXNlIHRoZSBgYXN5bmMgZnVuY3Rpb25gIHdpbGwgYmUgY29tcGlsZWQgdG8gYW4gb3JkaW5hcnkgZnVuY3Rpb24gdGhhdFxuICogcmV0dXJucyBhIHByb21pc2UuXG4gKlxuICogQHR5cGVkZWYge0Z1bmN0aW9ufSBBc3luY0Z1bmN0aW9uXG4gKiBAc3RhdGljXG4gKi9cblxuXG52YXIgaW5kZXggPSB7XG4gICAgYXBwbHksXG4gICAgYXBwbHlFYWNoLFxuICAgIGFwcGx5RWFjaFNlcmllcyxcbiAgICBhc3luY2lmeSxcbiAgICBhdXRvLFxuICAgIGF1dG9JbmplY3QsXG4gICAgY2FyZ286IGNhcmdvJDEsXG4gICAgY2FyZ29RdWV1ZTogY2FyZ28sXG4gICAgY29tcG9zZSxcbiAgICBjb25jYXQ6IGNvbmNhdCQxLFxuICAgIGNvbmNhdExpbWl0OiBjb25jYXRMaW1pdCQxLFxuICAgIGNvbmNhdFNlcmllczogY29uY2F0U2VyaWVzJDEsXG4gICAgY29uc3RhbnQ6IGNvbnN0YW50JDEsXG4gICAgZGV0ZWN0OiBkZXRlY3QkMSxcbiAgICBkZXRlY3RMaW1pdDogZGV0ZWN0TGltaXQkMSxcbiAgICBkZXRlY3RTZXJpZXM6IGRldGVjdFNlcmllcyQxLFxuICAgIGRpcixcbiAgICBkb1VudGlsLFxuICAgIGRvV2hpbHN0OiBkb1doaWxzdCQxLFxuICAgIGVhY2gsXG4gICAgZWFjaExpbWl0OiBlYWNoTGltaXQkMSxcbiAgICBlYWNoT2Y6IGVhY2hPZiQxLFxuICAgIGVhY2hPZkxpbWl0OiBlYWNoT2ZMaW1pdCQxLFxuICAgIGVhY2hPZlNlcmllczogZWFjaE9mU2VyaWVzJDEsXG4gICAgZWFjaFNlcmllczogZWFjaFNlcmllcyQxLFxuICAgIGVuc3VyZUFzeW5jLFxuICAgIGV2ZXJ5OiBldmVyeSQxLFxuICAgIGV2ZXJ5TGltaXQ6IGV2ZXJ5TGltaXQkMSxcbiAgICBldmVyeVNlcmllczogZXZlcnlTZXJpZXMkMSxcbiAgICBmaWx0ZXI6IGZpbHRlciQxLFxuICAgIGZpbHRlckxpbWl0OiBmaWx0ZXJMaW1pdCQxLFxuICAgIGZpbHRlclNlcmllczogZmlsdGVyU2VyaWVzJDEsXG4gICAgZm9yZXZlcjogZm9yZXZlciQxLFxuICAgIGdyb3VwQnksXG4gICAgZ3JvdXBCeUxpbWl0OiBncm91cEJ5TGltaXQkMSxcbiAgICBncm91cEJ5U2VyaWVzLFxuICAgIGxvZyxcbiAgICBtYXA6IG1hcCQxLFxuICAgIG1hcExpbWl0OiBtYXBMaW1pdCQxLFxuICAgIG1hcFNlcmllczogbWFwU2VyaWVzJDEsXG4gICAgbWFwVmFsdWVzLFxuICAgIG1hcFZhbHVlc0xpbWl0OiBtYXBWYWx1ZXNMaW1pdCQxLFxuICAgIG1hcFZhbHVlc1NlcmllcyxcbiAgICBtZW1vaXplLFxuICAgIG5leHRUaWNrLFxuICAgIHBhcmFsbGVsLFxuICAgIHBhcmFsbGVsTGltaXQsXG4gICAgcHJpb3JpdHlRdWV1ZSxcbiAgICBxdWV1ZSxcbiAgICByYWNlOiByYWNlJDEsXG4gICAgcmVkdWNlOiByZWR1Y2UkMSxcbiAgICByZWR1Y2VSaWdodCxcbiAgICByZWZsZWN0LFxuICAgIHJlZmxlY3RBbGwsXG4gICAgcmVqZWN0OiByZWplY3QkMSxcbiAgICByZWplY3RMaW1pdDogcmVqZWN0TGltaXQkMSxcbiAgICByZWplY3RTZXJpZXM6IHJlamVjdFNlcmllcyQxLFxuICAgIHJldHJ5LFxuICAgIHJldHJ5YWJsZSxcbiAgICBzZXEsXG4gICAgc2VyaWVzLFxuICAgIHNldEltbWVkaWF0ZTogc2V0SW1tZWRpYXRlJDEsXG4gICAgc29tZTogc29tZSQxLFxuICAgIHNvbWVMaW1pdDogc29tZUxpbWl0JDEsXG4gICAgc29tZVNlcmllczogc29tZVNlcmllcyQxLFxuICAgIHNvcnRCeTogc29ydEJ5JDEsXG4gICAgdGltZW91dCxcbiAgICB0aW1lcyxcbiAgICB0aW1lc0xpbWl0LFxuICAgIHRpbWVzU2VyaWVzLFxuICAgIHRyYW5zZm9ybSxcbiAgICB0cnlFYWNoOiB0cnlFYWNoJDEsXG4gICAgdW5tZW1vaXplLFxuICAgIHVudGlsLFxuICAgIHdhdGVyZmFsbDogd2F0ZXJmYWxsJDEsXG4gICAgd2hpbHN0OiB3aGlsc3QkMSxcblxuICAgIC8vIGFsaWFzZXNcbiAgICBhbGw6IGV2ZXJ5JDEsXG4gICAgYWxsTGltaXQ6IGV2ZXJ5TGltaXQkMSxcbiAgICBhbGxTZXJpZXM6IGV2ZXJ5U2VyaWVzJDEsXG4gICAgYW55OiBzb21lJDEsXG4gICAgYW55TGltaXQ6IHNvbWVMaW1pdCQxLFxuICAgIGFueVNlcmllczogc29tZVNlcmllcyQxLFxuICAgIGZpbmQ6IGRldGVjdCQxLFxuICAgIGZpbmRMaW1pdDogZGV0ZWN0TGltaXQkMSxcbiAgICBmaW5kU2VyaWVzOiBkZXRlY3RTZXJpZXMkMSxcbiAgICBmbGF0TWFwOiBjb25jYXQkMSxcbiAgICBmbGF0TWFwTGltaXQ6IGNvbmNhdExpbWl0JDEsXG4gICAgZmxhdE1hcFNlcmllczogY29uY2F0U2VyaWVzJDEsXG4gICAgZm9yRWFjaDogZWFjaCxcbiAgICBmb3JFYWNoU2VyaWVzOiBlYWNoU2VyaWVzJDEsXG4gICAgZm9yRWFjaExpbWl0OiBlYWNoTGltaXQkMSxcbiAgICBmb3JFYWNoT2Y6IGVhY2hPZiQxLFxuICAgIGZvckVhY2hPZlNlcmllczogZWFjaE9mU2VyaWVzJDEsXG4gICAgZm9yRWFjaE9mTGltaXQ6IGVhY2hPZkxpbWl0JDEsXG4gICAgaW5qZWN0OiByZWR1Y2UkMSxcbiAgICBmb2xkbDogcmVkdWNlJDEsXG4gICAgZm9sZHI6IHJlZHVjZVJpZ2h0LFxuICAgIHNlbGVjdDogZmlsdGVyJDEsXG4gICAgc2VsZWN0TGltaXQ6IGZpbHRlckxpbWl0JDEsXG4gICAgc2VsZWN0U2VyaWVzOiBmaWx0ZXJTZXJpZXMkMSxcbiAgICB3cmFwU3luYzogYXN5bmNpZnksXG4gICAgZHVyaW5nOiB3aGlsc3QkMSxcbiAgICBkb0R1cmluZzogZG9XaGlsc3QkMVxufTtcblxuZXhwb3J0IHsgZXZlcnkkMSBhcyBhbGwsIGV2ZXJ5TGltaXQkMSBhcyBhbGxMaW1pdCwgZXZlcnlTZXJpZXMkMSBhcyBhbGxTZXJpZXMsIHNvbWUkMSBhcyBhbnksIHNvbWVMaW1pdCQxIGFzIGFueUxpbWl0LCBzb21lU2VyaWVzJDEgYXMgYW55U2VyaWVzLCBhcHBseSwgYXBwbHlFYWNoLCBhcHBseUVhY2hTZXJpZXMsIGFzeW5jaWZ5LCBhdXRvLCBhdXRvSW5qZWN0LCBjYXJnbyQxIGFzIGNhcmdvLCBjYXJnbyBhcyBjYXJnb1F1ZXVlLCBjb21wb3NlLCBjb25jYXQkMSBhcyBjb25jYXQsIGNvbmNhdExpbWl0JDEgYXMgY29uY2F0TGltaXQsIGNvbmNhdFNlcmllcyQxIGFzIGNvbmNhdFNlcmllcywgY29uc3RhbnQkMSBhcyBjb25zdGFudCwgaW5kZXggYXMgZGVmYXVsdCwgZGV0ZWN0JDEgYXMgZGV0ZWN0LCBkZXRlY3RMaW1pdCQxIGFzIGRldGVjdExpbWl0LCBkZXRlY3RTZXJpZXMkMSBhcyBkZXRlY3RTZXJpZXMsIGRpciwgZG9XaGlsc3QkMSBhcyBkb0R1cmluZywgZG9VbnRpbCwgZG9XaGlsc3QkMSBhcyBkb1doaWxzdCwgd2hpbHN0JDEgYXMgZHVyaW5nLCBlYWNoLCBlYWNoTGltaXQkMSBhcyBlYWNoTGltaXQsIGVhY2hPZiQxIGFzIGVhY2hPZiwgZWFjaE9mTGltaXQkMSBhcyBlYWNoT2ZMaW1pdCwgZWFjaE9mU2VyaWVzJDEgYXMgZWFjaE9mU2VyaWVzLCBlYWNoU2VyaWVzJDEgYXMgZWFjaFNlcmllcywgZW5zdXJlQXN5bmMsIGV2ZXJ5JDEgYXMgZXZlcnksIGV2ZXJ5TGltaXQkMSBhcyBldmVyeUxpbWl0LCBldmVyeVNlcmllcyQxIGFzIGV2ZXJ5U2VyaWVzLCBmaWx0ZXIkMSBhcyBmaWx0ZXIsIGZpbHRlckxpbWl0JDEgYXMgZmlsdGVyTGltaXQsIGZpbHRlclNlcmllcyQxIGFzIGZpbHRlclNlcmllcywgZGV0ZWN0JDEgYXMgZmluZCwgZGV0ZWN0TGltaXQkMSBhcyBmaW5kTGltaXQsIGRldGVjdFNlcmllcyQxIGFzIGZpbmRTZXJpZXMsIGNvbmNhdCQxIGFzIGZsYXRNYXAsIGNvbmNhdExpbWl0JDEgYXMgZmxhdE1hcExpbWl0LCBjb25jYXRTZXJpZXMkMSBhcyBmbGF0TWFwU2VyaWVzLCByZWR1Y2UkMSBhcyBmb2xkbCwgcmVkdWNlUmlnaHQgYXMgZm9sZHIsIGVhY2ggYXMgZm9yRWFjaCwgZWFjaExpbWl0JDEgYXMgZm9yRWFjaExpbWl0LCBlYWNoT2YkMSBhcyBmb3JFYWNoT2YsIGVhY2hPZkxpbWl0JDEgYXMgZm9yRWFjaE9mTGltaXQsIGVhY2hPZlNlcmllcyQxIGFzIGZvckVhY2hPZlNlcmllcywgZWFjaFNlcmllcyQxIGFzIGZvckVhY2hTZXJpZXMsIGZvcmV2ZXIkMSBhcyBmb3JldmVyLCBncm91cEJ5LCBncm91cEJ5TGltaXQkMSBhcyBncm91cEJ5TGltaXQsIGdyb3VwQnlTZXJpZXMsIHJlZHVjZSQxIGFzIGluamVjdCwgbG9nLCBtYXAkMSBhcyBtYXAsIG1hcExpbWl0JDEgYXMgbWFwTGltaXQsIG1hcFNlcmllcyQxIGFzIG1hcFNlcmllcywgbWFwVmFsdWVzLCBtYXBWYWx1ZXNMaW1pdCQxIGFzIG1hcFZhbHVlc0xpbWl0LCBtYXBWYWx1ZXNTZXJpZXMsIG1lbW9pemUsIG5leHRUaWNrLCBwYXJhbGxlbCwgcGFyYWxsZWxMaW1pdCwgcHJpb3JpdHlRdWV1ZSwgcXVldWUsIHJhY2UkMSBhcyByYWNlLCByZWR1Y2UkMSBhcyByZWR1Y2UsIHJlZHVjZVJpZ2h0LCByZWZsZWN0LCByZWZsZWN0QWxsLCByZWplY3QkMSBhcyByZWplY3QsIHJlamVjdExpbWl0JDEgYXMgcmVqZWN0TGltaXQsIHJlamVjdFNlcmllcyQxIGFzIHJlamVjdFNlcmllcywgcmV0cnksIHJldHJ5YWJsZSwgZmlsdGVyJDEgYXMgc2VsZWN0LCBmaWx0ZXJMaW1pdCQxIGFzIHNlbGVjdExpbWl0LCBmaWx0ZXJTZXJpZXMkMSBhcyBzZWxlY3RTZXJpZXMsIHNlcSwgc2VyaWVzLCBzZXRJbW1lZGlhdGUkMSBhcyBzZXRJbW1lZGlhdGUsIHNvbWUkMSBhcyBzb21lLCBzb21lTGltaXQkMSBhcyBzb21lTGltaXQsIHNvbWVTZXJpZXMkMSBhcyBzb21lU2VyaWVzLCBzb3J0QnkkMSBhcyBzb3J0QnksIHRpbWVvdXQsIHRpbWVzLCB0aW1lc0xpbWl0LCB0aW1lc1NlcmllcywgdHJhbnNmb3JtLCB0cnlFYWNoJDEgYXMgdHJ5RWFjaCwgdW5tZW1vaXplLCB1bnRpbCwgd2F0ZXJmYWxsJDEgYXMgd2F0ZXJmYWxsLCB3aGlsc3QkMSBhcyB3aGlsc3QsIGFzeW5jaWZ5IGFzIHdyYXBTeW5jIH07XG4iXSwibmFtZXMiOltdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///(rsc)/./node_modules/async/dist/async.mjs\n"); /***/ }) }; ;