You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

25 lines
518 KiB
JavaScript

"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/@remix-run";
exports.ids = ["vendor-chunks/@remix-run"];
exports.modules = {
/***/ "(ssr)/./node_modules/@remix-run/router/dist/router.js":
/*!*******************************************************!*\
!*** ./node_modules/@remix-run/router/dist/router.js ***!
\*******************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ AbortedDeferredError: () => (/* binding */ AbortedDeferredError),\n/* harmony export */ Action: () => (/* binding */ Action),\n/* harmony export */ ErrorResponse: () => (/* binding */ ErrorResponse),\n/* harmony export */ IDLE_BLOCKER: () => (/* binding */ IDLE_BLOCKER),\n/* harmony export */ IDLE_FETCHER: () => (/* binding */ IDLE_FETCHER),\n/* harmony export */ IDLE_NAVIGATION: () => (/* binding */ IDLE_NAVIGATION),\n/* harmony export */ UNSAFE_DEFERRED_SYMBOL: () => (/* binding */ UNSAFE_DEFERRED_SYMBOL),\n/* harmony export */ UNSAFE_DeferredData: () => (/* binding */ DeferredData),\n/* harmony export */ UNSAFE_convertRoutesToDataRoutes: () => (/* binding */ convertRoutesToDataRoutes),\n/* harmony export */ UNSAFE_getPathContributingMatches: () => (/* binding */ getPathContributingMatches),\n/* harmony export */ UNSAFE_invariant: () => (/* binding */ invariant),\n/* harmony export */ UNSAFE_warning: () => (/* binding */ warning),\n/* harmony export */ createBrowserHistory: () => (/* binding */ createBrowserHistory),\n/* harmony export */ createHashHistory: () => (/* binding */ createHashHistory),\n/* harmony export */ createMemoryHistory: () => (/* binding */ createMemoryHistory),\n/* harmony export */ createPath: () => (/* binding */ createPath),\n/* harmony export */ createRouter: () => (/* binding */ createRouter),\n/* harmony export */ createStaticHandler: () => (/* binding */ createStaticHandler),\n/* harmony export */ defer: () => (/* binding */ defer),\n/* harmony export */ generatePath: () => (/* binding */ generatePath),\n/* harmony export */ getStaticContextFromError: () => (/* binding */ getStaticContextFromError),\n/* harmony export */ getToPathname: () => (/* binding */ getToPathname),\n/* harmony export */ isDeferredData: () => (/* binding */ isDeferredData),\n/* harmony export */ isRouteErrorResponse: () => (/* binding */ isRouteErrorResponse),\n/* harmony export */ joinPaths: () => (/* binding */ joinPaths),\n/* harmony export */ json: () => (/* binding */ json),\n/* harmony export */ matchPath: () => (/* binding */ matchPath),\n/* harmony export */ matchRoutes: () => (/* binding */ matchRoutes),\n/* harmony export */ normalizePathname: () => (/* binding */ normalizePathname),\n/* harmony export */ parsePath: () => (/* binding */ parsePath),\n/* harmony export */ redirect: () => (/* binding */ redirect),\n/* harmony export */ redirectDocument: () => (/* binding */ redirectDocument),\n/* harmony export */ resolvePath: () => (/* binding */ resolvePath),\n/* harmony export */ resolveTo: () => (/* binding */ resolveTo),\n/* harmony export */ stripBasename: () => (/* binding */ stripBasename)\n/* harmony export */ });\n/**\n * @remix-run/router v1.8.0\n *\n * Copyright (c) Remix Software Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE.md file in the root directory of this source tree.\n *\n * @license MIT\n */ function _extends() {\n _extends = Object.assign ? Object.assign.bind() : function(target) {\n for(var i = 1; i < arguments.length; i++){\n var source = arguments[i];\n for(var key in source){\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n return target;\n };\n return _extends.apply(this, arguments);\n}\n////////////////////////////////////////////////////////////////////////////////\n//#region Types and Constants\n////////////////////////////////////////////////////////////////////////////////\n/**\n * Actions represent the type of change to a location value.\n */ var Action;\n(function(Action) {\n /**\n * A POP indicates a change to an arbitrary index in the history stack, such\n * as a back or forward navigation. It does not describe the direction of the\n * navigation, only that the current index changed.\n *\n * Note: This is the default action for newly created history objects.\n */ Action[\"Pop\"] = \"POP\";\n /**\n * A PUSH indicates a new entry being added to the history stack, such as when\n * a link is clicked and a new page loads. When this happens, all subsequent\n * entries in the stack are lost.\n */ Action[\"Push\"] = \"PUSH\";\n /**\n * A REPLACE indicates the entry at the current index in the history stack\n * being replaced by a new one.\n */ Action[\"Replace\"] = \"REPLACE\";\n})(Action || (Action = {}));\nconst PopStateEventType = \"popstate\";\n/**\n * Memory history stores the current location in memory. It is designed for use\n * in stateful non-browser environments like tests and React Native.\n */ function createMemoryHistory(options) {\n if (options === void 0) {\n options = {};\n }\n let { initialEntries = [\n \"/\"\n ], initialIndex, v5Compat = false } = options;\n let entries; // Declare so we can access from createMemoryLocation\n entries = initialEntries.map((entry, index)=>createMemoryLocation(entry, typeof entry === \"string\" ? null : entry.state, index === 0 ? \"default\" : undefined));\n let index = clampIndex(initialIndex == null ? entries.length - 1 : initialIndex);\n let action = Action.Pop;\n let listener = null;\n function clampIndex(n) {\n return Math.min(Math.max(n, 0), entries.length - 1);\n }\n function getCurrentLocation() {\n return entries[index];\n }\n function createMemoryLocation(to, state, key) {\n if (state === void 0) {\n state = null;\n }\n let location = createLocation(entries ? getCurrentLocation().pathname : \"/\", to, state, key);\n warning(location.pathname.charAt(0) === \"/\", \"relative pathnames are not supported in memory history: \" + JSON.stringify(to));\n return location;\n }\n function createHref(to) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n let history = {\n get index () {\n return index;\n },\n get action () {\n return action;\n },\n get location () {\n return getCurrentLocation();\n },\n createHref,\n createURL (to) {\n return new URL(createHref(to), \"http://localhost\");\n },\n encodeLocation (to) {\n let path = typeof to === \"string\" ? parsePath(to) : to;\n return {\n pathname: path.pathname || \"\",\n search: path.search || \"\",\n hash: path.hash || \"\"\n };\n },\n push (to, state) {\n action = Action.Push;\n let nextLocation = createMemoryLocation(to, state);\n index += 1;\n entries.splice(index, entries.length, nextLocation);\n if (v5Compat && listener) {\n listener({\n action,\n location: nextLocation,\n delta: 1\n });\n }\n },\n replace (to, state) {\n action = Action.Replace;\n let nextLocation = createMemoryLocation(to, state);\n entries[index] = nextLocation;\n if (v5Compat && listener) {\n listener({\n action,\n location: nextLocation,\n delta: 0\n });\n }\n },\n go (delta) {\n action = Action.Pop;\n let nextIndex = clampIndex(index + delta);\n let nextLocation = entries[nextIndex];\n index = nextIndex;\n if (listener) {\n listener({\n action,\n location: nextLocation,\n delta\n });\n }\n },\n listen (fn) {\n listener = fn;\n return ()=>{\n listener = null;\n };\n }\n };\n return history;\n}\n/**\n * Browser history stores the location in regular URLs. This is the standard for\n * most web apps, but it requires some configuration on the server to ensure you\n * serve the same app at multiple URLs.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createbrowserhistory\n */ function createBrowserHistory(options) {\n if (options === void 0) {\n options = {};\n }\n function createBrowserLocation(window1, globalHistory) {\n let { pathname, search, hash } = window1.location;\n return createLocation(\"\", {\n pathname,\n search,\n hash\n }, // state defaults to `null` because `window.history.state` does\n globalHistory.state && globalHistory.state.usr || null, globalHistory.state && globalHistory.state.key || \"default\");\n }\n function createBrowserHref(window1, to) {\n return typeof to === \"string\" ? to : createPath(to);\n }\n return getUrlBasedHistory(createBrowserLocation, createBrowserHref, null, options);\n}\n/**\n * Hash history stores the location in window.location.hash. This makes it ideal\n * for situations where you don't want to send the location to the server for\n * some reason, either because you do cannot configure it or the URL space is\n * reserved for something else.\n *\n * @see https://github.com/remix-run/history/tree/main/docs/api-reference.md#createhashhistory\n */ function createHashHistory(options) {\n if (options === void 0) {\n options = {};\n }\n function createHashLocation(window1, globalHistory) {\n let { pathname = \"/\", search = \"\", hash = \"\" } = parsePath(window1.location.hash.substr(1));\n // Hash URL should always have a leading / just like window.location.pathname\n // does, so if an app ends up at a route like /#something then we add a\n // leading slash so all of our path-matching behaves the same as if it would\n // in a browser router. This is particularly important when there exists a\n // root splat route (<Route path=\"*\">) since that matches internally against\n // \"/*\" and we'd expect /#something to 404 in a hash router app.\n if (!pathname.startsWith(\"/\") && !pathname.startsWith(\".\")) {\n pathname = \"/\" + pathname;\n }\n return createLocation(\"\", {\n pathname,\n search,\n hash\n }, // state defaults to `null` because `window.history.state` does\n globalHistory.state && globalHistory.state.usr || null, globalHistory.state && globalHistory.state.key || \"default\");\n }\n function createHashHref(window1, to) {\n let base = window1.document.querySelector(\"base\");\n let href = \"\";\n if (base && base.getAttribute(\"href\")) {\n let url = window1.location.href;\n let hashIndex = url.indexOf(\"#\");\n href = hashIndex === -1 ? url : url.slice(0, hashIndex);\n }\n return href + \"#\" + (typeof to === \"string\" ? to : createPath(to));\n }\n function validateHashLocation(location, to) {\n warning(location.pathname.charAt(0) === \"/\", \"relative pathnames are not supported in hash history.push(\" + JSON.stringify(to) + \")\");\n }\n return getUrlBasedHistory(createHashLocation, createHashHref, validateHashLocation, options);\n}\nfunction invariant(value, message) {\n if (value === false || value === null || typeof value === \"undefined\") {\n throw new Error(message);\n }\n}\nfunction warning(cond, message) {\n if (!cond) {\n // eslint-disable-next-line no-console\n if (typeof console !== \"undefined\") console.warn(message);\n try {\n // Welcome to debugging history!\n //\n // This error is thrown as a convenience so you can more easily\n // find the source for a warning that appears in the console by\n // enabling \"pause on exceptions\" in your JavaScript debugger.\n throw new Error(message);\n // eslint-disable-next-line no-empty\n } catch (e) {}\n }\n}\nfunction createKey() {\n return Math.random().toString(36).substr(2, 8);\n}\n/**\n * For browser-based histories, we combine the state and key into an object\n */ function getHistoryState(location, index) {\n return {\n usr: location.state,\n key: location.key,\n idx: index\n };\n}\n/**\n * Creates a Location object with a unique key from the given Path\n */ function createLocation(current, to, state, key) {\n if (state === void 0) {\n state = null;\n }\n let location = _extends({\n pathname: typeof current === \"string\" ? current : current.pathname,\n search: \"\",\n hash: \"\"\n }, typeof to === \"string\" ? parsePath(to) : to, {\n state,\n // TODO: This could be cleaned up. push/replace should probably just take\n // full Locations now and avoid the need to run through this flow at all\n // But that's a pretty big refactor to the current test suite so going to\n // keep as is for the time being and just let any incoming keys take precedence\n key: to && to.key || key || createKey()\n });\n return location;\n}\n/**\n * Creates a string URL path from the given pathname, search, and hash components.\n */ function createPath(_ref) {\n let { pathname = \"/\", search = \"\", hash = \"\" } = _ref;\n if (search && search !== \"?\") pathname += search.charAt(0) === \"?\" ? search : \"?\" + search;\n if (hash && hash !== \"#\") pathname += hash.charAt(0) === \"#\" ? hash : \"#\" + hash;\n return pathname;\n}\n/**\n * Parses a string URL path into its separate pathname, search, and hash components.\n */ function parsePath(path) {\n let parsedPath = {};\n if (path) {\n let hashIndex = path.indexOf(\"#\");\n if (hashIndex >= 0) {\n parsedPath.hash = path.substr(hashIndex);\n path = path.substr(0, hashIndex);\n }\n let searchIndex = path.indexOf(\"?\");\n if (searchIndex >= 0) {\n parsedPath.search = path.substr(searchIndex);\n path = path.substr(0, searchIndex);\n }\n if (path) {\n parsedPath.pathname = path;\n }\n }\n return parsedPath;\n}\nfunction getUrlBasedHistory(getLocation, createHref, validateLocation, options) {\n if (options === void 0) {\n options = {};\n }\n let { window: window1 = document.defaultView, v5Compat = false } = options;\n let globalHistory = window1.history;\n let action = Action.Pop;\n let listener = null;\n let index = getIndex();\n // Index should only be null when we initialize. If not, it's because the\n // user called history.pushState or history.replaceState directly, in which\n // case we should log a warning as it will result in bugs.\n if (index == null) {\n index = 0;\n globalHistory.replaceState(_extends({}, globalHistory.state, {\n idx: index\n }), \"\");\n }\n function getIndex() {\n let state = globalHistory.state || {\n idx: null\n };\n return state.idx;\n }\n function handlePop() {\n action = Action.Pop;\n let nextIndex = getIndex();\n let delta = nextIndex == null ? null : nextIndex - index;\n index = nextIndex;\n if (listener) {\n listener({\n action,\n location: history.location,\n delta\n });\n }\n }\n function push(to, state) {\n action = Action.Push;\n let location = createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n index = getIndex() + 1;\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location);\n // try...catch because iOS limits us to 100 pushState calls :/\n try {\n globalHistory.pushState(historyState, \"\", url);\n } catch (error) {\n // If the exception is because `state` can't be serialized, let that throw\n // outwards just like a replace call would so the dev knows the cause\n // https://html.spec.whatwg.org/multipage/nav-history-apis.html#shared-history-push/replace-state-steps\n // https://html.spec.whatwg.org/multipage/structured-data.html#structuredserializeinternal\n if (error instanceof DOMException && error.name === \"DataCloneError\") {\n throw error;\n }\n // They are going to lose state here, but there is no real\n // way to warn them about it since the page will refresh...\n window1.location.assign(url);\n }\n if (v5Compat && listener) {\n listener({\n action,\n location: history.location,\n delta: 1\n });\n }\n }\n function replace(to, state) {\n action = Action.Replace;\n let location = createLocation(history.location, to, state);\n if (validateLocation) validateLocation(location, to);\n index = getIndex();\n let historyState = getHistoryState(location, index);\n let url = history.createHref(location);\n globalHistory.replaceState(historyState, \"\", url);\n if (v5Compat && listener) {\n listener({\n action,\n location: history.location,\n delta: 0\n });\n }\n }\n function createURL(to) {\n // window.location.origin is \"null\" (the literal string value) in Firefox\n // under certain conditions, notably when serving from a local HTML file\n // See https://bugzilla.mozilla.org/show_bug.cgi?id=878297\n let base = window1.location.origin !== \"null\" ? window1.location.origin : window1.location.href;\n let href = typeof to === \"string\" ? to : createPath(to);\n invariant(base, \"No window.location.(origin|href) available to create URL for href: \" + href);\n return new URL(href, base);\n }\n let history = {\n get action () {\n return action;\n },\n get location () {\n return getLocation(window1, globalHistory);\n },\n listen (fn) {\n if (listener) {\n throw new Error(\"A history only accepts one active listener\");\n }\n window1.addEventListener(PopStateEventType, handlePop);\n listener = fn;\n return ()=>{\n window1.removeEventListener(PopStateEventType, handlePop);\n listener = null;\n };\n },\n createHref (to) {\n return createHref(window1, to);\n },\n createURL,\n encodeLocation (to) {\n // Encode a Location the same way window.location would\n let url = createURL(to);\n return {\n pathname: url.pathname,\n search: url.search,\n hash: url.hash\n };\n },\n push,\n replace,\n go (n) {\n return globalHistory.go(n);\n }\n };\n return history;\n}\n//#endregion\nvar ResultType;\n(function(ResultType) {\n ResultType[\"data\"] = \"data\";\n ResultType[\"deferred\"] = \"deferred\";\n ResultType[\"redirect\"] = \"redirect\";\n ResultType[\"error\"] = \"error\";\n})(ResultType || (ResultType = {}));\nconst immutableRouteKeys = new Set([\n \"lazy\",\n \"caseSensitive\",\n \"path\",\n \"id\",\n \"index\",\n \"children\"\n]);\nfunction isIndexRoute(route) {\n return route.index === true;\n}\n// Walk the route tree generating unique IDs where necessary so we are working\n// solely with AgnosticDataRouteObject's within the Router\nfunction convertRoutesToDataRoutes(routes, mapRouteProperties, parentPath, manifest) {\n if (parentPath === void 0) {\n parentPath = [];\n }\n if (manifest === void 0) {\n manifest = {};\n }\n return routes.map((route, index)=>{\n let treePath = [\n ...parentPath,\n index\n ];\n let id = typeof route.id === \"string\" ? route.id : treePath.join(\"-\");\n invariant(route.index !== true || !route.children, \"Cannot specify children on an index route\");\n invariant(!manifest[id], 'Found a route id collision on id \"' + id + '\". Route ' + \"id's must be globally unique within Data Router usages\");\n if (isIndexRoute(route)) {\n let indexRoute = _extends({}, route, mapRouteProperties(route), {\n id\n });\n manifest[id] = indexRoute;\n return indexRoute;\n } else {\n let pathOrLayoutRoute = _extends({}, route, mapRouteProperties(route), {\n id,\n children: undefined\n });\n manifest[id] = pathOrLayoutRoute;\n if (route.children) {\n pathOrLayoutRoute.children = convertRoutesToDataRoutes(route.children, mapRouteProperties, treePath, manifest);\n }\n return pathOrLayoutRoute;\n }\n });\n}\n/**\n * Matches the given routes to a location and returns the match data.\n *\n * @see https://reactrouter.com/utils/match-routes\n */ function matchRoutes(routes, locationArg, basename) {\n if (basename === void 0) {\n basename = \"/\";\n }\n let location = typeof locationArg === \"string\" ? parsePath(locationArg) : locationArg;\n let pathname = stripBasename(location.pathname || \"/\", basename);\n if (pathname == null) {\n return null;\n }\n let branches = flattenRoutes(routes);\n rankRouteBranches(branches);\n let matches = null;\n for(let i = 0; matches == null && i < branches.length; ++i){\n matches = matchRouteBranch(branches[i], // Incoming pathnames are generally encoded from either window.location\n // or from router.navigate, but we want to match against the unencoded\n // paths in the route definitions. Memory router locations won't be\n // encoded here but there also shouldn't be anything to decode so this\n // should be a safe operation. This avoids needing matchRoutes to be\n // history-aware.\n safelyDecodeURI(pathname));\n }\n return matches;\n}\nfunction flattenRoutes(routes, branches, parentsMeta, parentPath) {\n if (branches === void 0) {\n branches = [];\n }\n if (parentsMeta === void 0) {\n parentsMeta = [];\n }\n if (parentPath === void 0) {\n parentPath = \"\";\n }\n let flattenRoute = (route, index, relativePath)=>{\n let meta = {\n relativePath: relativePath === undefined ? route.path || \"\" : relativePath,\n caseSensitive: route.caseSensitive === true,\n childrenIndex: index,\n route\n };\n if (meta.relativePath.startsWith(\"/\")) {\n invariant(meta.relativePath.startsWith(parentPath), 'Absolute route path \"' + meta.relativePath + '\" nested under path ' + ('\"' + parentPath + '\" is not valid. An absolute child route path ') + \"must start with the combined path of all its parent routes.\");\n meta.relativePath = meta.relativePath.slice(parentPath.length);\n }\n let path = joinPaths([\n parentPath,\n meta.relativePath\n ]);\n let routesMeta = parentsMeta.concat(meta);\n // Add the children before adding this route to the array so we traverse the\n // route tree depth-first and child routes appear before their parents in\n // the \"flattened\" version.\n if (route.children && route.children.length > 0) {\n invariant(// Our types know better, but runtime JS may not!\n // @ts-expect-error\n route.index !== true, \"Index routes must not have child routes. Please remove \" + ('all child routes from route path \"' + path + '\".'));\n flattenRoutes(route.children, branches, routesMeta, path);\n }\n // Routes without a path shouldn't ever match by themselves unless they are\n // index routes, so don't add them to the list of possible branches.\n if (route.path == null && !route.index) {\n return;\n }\n branches.push({\n path,\n score: computeScore(path, route.index),\n routesMeta\n });\n };\n routes.forEach((route, index)=>{\n var _route$path;\n // coarse-grain check for optional params\n if (route.path === \"\" || !((_route$path = route.path) != null && _route$path.includes(\"?\"))) {\n flattenRoute(route, index);\n } else {\n for (let exploded of explodeOptionalSegments(route.path)){\n flattenRoute(route, index, exploded);\n }\n }\n });\n return branches;\n}\n/**\n * Computes all combinations of optional path segments for a given path,\n * excluding combinations that are ambiguous and of lower priority.\n *\n * For example, `/one/:two?/three/:four?/:five?` explodes to:\n * - `/one/three`\n * - `/one/:two/three`\n * - `/one/three/:four`\n * - `/one/three/:five`\n * - `/one/:two/three/:four`\n * - `/one/:two/three/:five`\n * - `/one/three/:four/:five`\n * - `/one/:two/three/:four/:five`\n */ function explodeOptionalSegments(path) {\n let segments = path.split(\"/\");\n if (segments.length === 0) return [];\n let [first, ...rest] = segments;\n // Optional path segments are denoted by a trailing `?`\n let isOptional = first.endsWith(\"?\");\n // Compute the corresponding required segment: `foo?` -> `foo`\n let required = first.replace(/\\?$/, \"\");\n if (rest.length === 0) {\n // Intepret empty string as omitting an optional segment\n // `[\"one\", \"\", \"three\"]` corresponds to omitting `:two` from `/one/:two?/three` -> `/one/three`\n return isOptional ? [\n required,\n \"\"\n ] : [\n required\n ];\n }\n let restExploded = explodeOptionalSegments(rest.join(\"/\"));\n let result = [];\n // All child paths with the prefix. Do this for all children before the\n // optional version for all children so we get consistent ordering where the\n // parent optional aspect is preferred as required. Otherwise, we can get\n // child sections interspersed where deeper optional segments are higher than\n // parent optional segments, where for example, /:two would explodes _earlier_\n // then /:one. By always including the parent as required _for all children_\n // first, we avoid this issue\n result.push(...restExploded.map((subpath)=>subpath === \"\" ? required : [\n required,\n subpath\n ].join(\"/\")));\n // Then if this is an optional value, add all child versions without\n if (isOptional) {\n result.push(...restExploded);\n }\n // for absolute paths, ensure `/` instead of empty segment\n return result.map((exploded)=>path.startsWith(\"/\") && exploded === \"\" ? \"/\" : exploded);\n}\nfunction rankRouteBranches(branches) {\n branches.sort((a, b)=>a.score !== b.score ? b.score - a.score // Higher score first\n : compareIndexes(a.routesMeta.map((meta)=>meta.childrenIndex), b.routesMeta.map((meta)=>meta.childrenIndex)));\n}\nconst paramRe = /^:\\w+$/;\nconst dynamicSegmentValue = 3;\nconst indexRouteValue = 2;\nconst emptySegmentValue = 1;\nconst staticSegmentValue = 10;\nconst splatPenalty = -2;\nconst isSplat = (s)=>s === \"*\";\nfunction computeScore(path, index) {\n let segments = path.split(\"/\");\n let initialScore = segments.length;\n if (segments.some(isSplat)) {\n initialScore += splatPenalty;\n }\n if (index) {\n initialScore += indexRouteValue;\n }\n return segments.filter((s)=>!isSplat(s)).reduce((score, segment)=>score + (paramRe.test(segment) ? dynamicSegmentValue : segment === \"\" ? emptySegmentValue : staticSegmentValue), initialScore);\n}\nfunction compareIndexes(a, b) {\n let siblings = a.length === b.length && a.slice(0, -1).every((n, i)=>n === b[i]);\n return siblings ? // If two routes are siblings, we should try to match the earlier sibling\n // first. This allows people to have fine-grained control over the matching\n // behavior by simply putting routes with identical paths in the order they\n // want them tried.\n a[a.length - 1] - b[b.length - 1] : // Otherwise, it doesn't really make sense to rank non-siblings by index,\n // so they sort equally.\n 0;\n}\nfunction matchRouteBranch(branch, pathname) {\n let { routesMeta } = branch;\n let matchedParams = {};\n let matchedPathname = \"/\";\n let matches = [];\n for(let i = 0; i < routesMeta.length; ++i){\n let meta = routesMeta[i];\n let end = i === routesMeta.length - 1;\n let remainingPathname = matchedPathname === \"/\" ? pathname : pathname.slice(matchedPathname.length) || \"/\";\n let match = matchPath({\n path: meta.relativePath,\n caseSensitive: meta.caseSensitive,\n end\n }, remainingPathname);\n if (!match) return null;\n Object.assign(matchedParams, match.params);\n let route = meta.route;\n matches.push({\n // TODO: Can this as be avoided?\n params: matchedParams,\n pathname: joinPaths([\n matchedPathname,\n match.pathname\n ]),\n pathnameBase: normalizePathname(joinPaths([\n matchedPathname,\n match.pathnameBase\n ])),\n route\n });\n if (match.pathnameBase !== \"/\") {\n matchedPathname = joinPaths([\n matchedPathname,\n match.pathnameBase\n ]);\n }\n }\n return matches;\n}\n/**\n * Returns a path with params interpolated.\n *\n * @see https://reactrouter.com/utils/generate-path\n */ function generatePath(originalPath, params) {\n if (params === void 0) {\n params = {};\n }\n let path = originalPath;\n if (path.endsWith(\"*\") && path !== \"*\" && !path.endsWith(\"/*\")) {\n warning(false, 'Route path \"' + path + '\" will be treated as if it were ' + ('\"' + path.replace(/\\*$/, \"/*\") + '\" because the `*` character must ') + \"always follow a `/` in the pattern. To get rid of this warning, \" + ('please change the route path to \"' + path.replace(/\\*$/, \"/*\") + '\".'));\n path = path.replace(/\\*$/, \"/*\");\n }\n // ensure `/` is added at the beginning if the path is absolute\n const prefix = path.startsWith(\"/\") ? \"/\" : \"\";\n const stringify = (p)=>p == null ? \"\" : typeof p === \"string\" ? p : String(p);\n const segments = path.split(/\\/+/).map((segment, index, array)=>{\n const isLastSegment = index === array.length - 1;\n // only apply the splat if it's the last segment\n if (isLastSegment && segment === \"*\") {\n const star = \"*\";\n // Apply the splat\n return stringify(params[star]);\n }\n const keyMatch = segment.match(/^:(\\w+)(\\??)$/);\n if (keyMatch) {\n const [, key, optional] = keyMatch;\n let param = params[key];\n invariant(optional === \"?\" || param != null, 'Missing \":' + key + '\" param');\n return stringify(param);\n }\n // Remove any optional markers from optional static segments\n return segment.replace(/\\?$/g, \"\");\n })// Remove empty segments\n .filter((segment)=>!!segment);\n return prefix + segments.join(\"/\");\n}\n/**\n * Performs pattern matching on a URL pathname and returns information about\n * the match.\n *\n * @see https://reactrouter.com/utils/match-path\n */ function matchPath(pattern, pathname) {\n if (typeof pattern === \"string\") {\n pattern = {\n path: pattern,\n caseSensitive: false,\n end: true\n };\n }\n let [matcher, paramNames] = compilePath(pattern.path, pattern.caseSensitive, pattern.end);\n let match = pathname.match(matcher);\n if (!match) return null;\n let matchedPathname = match[0];\n let pathnameBase = matchedPathname.replace(/(.)\\/+$/, \"$1\");\n let captureGroups = match.slice(1);\n let params = paramNames.reduce((memo, paramName, index)=>{\n // We need to compute the pathnameBase here using the raw splat value\n // instead of using params[\"*\"] later because it will be decoded then\n if (paramName === \"*\") {\n let splatValue = captureGroups[index] || \"\";\n pathnameBase = matchedPathname.slice(0, matchedPathname.length - splatValue.length).replace(/(.)\\/+$/, \"$1\");\n }\n memo[paramName] = safelyDecodeURIComponent(captureGroups[index] || \"\", paramName);\n return memo;\n }, {});\n return {\n params,\n pathname: matchedPathname,\n pathnameBase,\n pattern\n };\n}\nfunction compilePath(path, caseSensitive, end) {\n if (caseSensitive === void 0) {\n caseSensitive = false;\n }\n if (end === void 0) {\n end = true;\n }\n warning(path === \"*\" || !path.endsWith(\"*\") || path.endsWith(\"/*\"), 'Route path \"' + path + '\" will be treated as if it were ' + ('\"' + path.replace(/\\*$/, \"/*\") + '\" because the `*` character must ') + \"always follow a `/` in the pattern. To get rid of this warning, \" + ('please change the route path to \"' + path.replace(/\\*$/, \"/*\") + '\".'));\n let paramNames = [];\n let regexpSource = \"^\" + path.replace(/\\/*\\*?$/, \"\") // Ignore trailing / and /*, we'll handle it below\n .replace(/^\\/*/, \"/\") // Make sure it has a leading /\n .replace(/[\\\\.*+^$?{}|()[\\]]/g, \"\\\\$&\") // Escape special regex chars\n .replace(/\\/:(\\w+)/g, (_, paramName)=>{\n paramNames.push(paramName);\n return \"/([^\\\\/]+)\";\n });\n if (path.endsWith(\"*\")) {\n paramNames.push(\"*\");\n regexpSource += path === \"*\" || path === \"/*\" ? \"(.*)$\" // Already matched the initial /, just match the rest\n : \"(?:\\\\/(.+)|\\\\/*)$\"; // Don't include the / in params[\"*\"]\n } else if (end) {\n // When matching to the end, ignore trailing slashes\n regexpSource += \"\\\\/*$\";\n } else if (path !== \"\" && path !== \"/\") {\n // If our path is non-empty and contains anything beyond an initial slash,\n // then we have _some_ form of path in our regex so we should expect to\n // match only if we find the end of this path segment. Look for an optional\n // non-captured trailing slash (to match a portion of the URL) or the end\n // of the path (if we've matched to the end). We used to do this with a\n // word boundary but that gives false positives on routes like\n // /user-preferences since `-` counts as a word boundary.\n regexpSource += \"(?:(?=\\\\/|$))\";\n } else ;\n let matcher = new RegExp(regexpSource, caseSensitive ? undefined : \"i\");\n return [\n matcher,\n paramNames\n ];\n}\nfunction safelyDecodeURI(value) {\n try {\n return decodeURI(value);\n } catch (error) {\n warning(false, 'The URL path \"' + value + '\" could not be decoded because it is is a ' + \"malformed URL segment. This is probably due to a bad percent \" + (\"encoding (\" + error + \").\"));\n return value;\n }\n}\nfunction safelyDecodeURIComponent(value, paramName) {\n try {\n return decodeURIComponent(value);\n } catch (error) {\n warning(false, 'The value for the URL param \"' + paramName + '\" will not be decoded because' + (' the string \"' + value + '\" is a malformed URL segment. This is probably') + (\" due to a bad percent encoding (\" + error + \").\"));\n return value;\n }\n}\n/**\n * @private\n */ function stripBasename(pathname, basename) {\n if (basename === \"/\") return pathname;\n if (!pathname.toLowerCase().startsWith(basename.toLowerCase())) {\n return null;\n }\n // We want to leave trailing slash behavior in the user's control, so if they\n // specify a basename with a trailing slash, we should support it\n let startIndex = basename.endsWith(\"/\") ? basename.length - 1 : basename.length;\n let nextChar = pathname.charAt(startIndex);\n if (nextChar && nextChar !== \"/\") {\n // pathname does not start with basename/\n return null;\n }\n return pathname.slice(startIndex) || \"/\";\n}\n/**\n * Returns a resolved path object relative to the given pathname.\n *\n * @see https://reactrouter.com/utils/resolve-path\n */ function resolvePath(to, fromPathname) {\n if (fromPathname === void 0) {\n fromPathname = \"/\";\n }\n let { pathname: toPathname, search = \"\", hash = \"\" } = typeof to === \"string\" ? parsePath(to) : to;\n let pathname = toPathname ? toPathname.startsWith(\"/\") ? toPathname : resolvePathname(toPathname, fromPathname) : fromPathname;\n return {\n pathname,\n search: normalizeSearch(search),\n hash: normalizeHash(hash)\n };\n}\nfunction resolvePathname(relativePath, fromPathname) {\n let segments = fromPathname.replace(/\\/+$/, \"\").split(\"/\");\n let relativeSegments = relativePath.split(\"/\");\n relativeSegments.forEach((segment)=>{\n if (segment === \"..\") {\n // Keep the root \"\" segment so the pathname starts at /\n if (segments.length > 1) segments.pop();\n } else if (segment !== \".\") {\n segments.push(segment);\n }\n });\n return segments.length > 1 ? segments.join(\"/\") : \"/\";\n}\nfunction getInvalidPathError(char, field, dest, path) {\n return \"Cannot include a '\" + char + \"' character in a manually specified \" + (\"`to.\" + field + \"` field [\" + JSON.stringify(path) + \"]. Please separate it out to the \") + (\"`to.\" + dest + \"` field. Alternatively you may provide the full path as \") + 'a string in <Link to=\"...\"> and the router will parse it for you.';\n}\n/**\n * @private\n *\n * When processing relative navigation we want to ignore ancestor routes that\n * do not contribute to the path, such that index/pathless layout routes don't\n * interfere.\n *\n * For example, when moving a route element into an index route and/or a\n * pathless layout route, relative link behavior contained within should stay\n * the same. Both of the following examples should link back to the root:\n *\n * <Route path=\"/\">\n * <Route path=\"accounts\" element={<Link to=\"..\"}>\n * </Route>\n *\n * <Route path=\"/\">\n * <Route path=\"accounts\">\n * <Route element={<AccountsLayout />}> // <-- Does not contribute\n * <Route index element={<Link to=\"..\"} /> // <-- Does not contribute\n * </Route\n * </Route>\n * </Route>\n */ function getPathContributingMatches(matches) {\n return matches.filter((match, index)=>index === 0 || match.route.path && match.route.path.length > 0);\n}\n/**\n * @private\n */ function resolveTo(toArg, routePathnames, locationPathname, isPathRelative) {\n if (isPathRelative === void 0) {\n isPathRelative = false;\n }\n let to;\n if (typeof toArg === \"string\") {\n to = parsePath(toArg);\n } else {\n to = _extends({}, toArg);\n invariant(!to.pathname || !to.pathname.includes(\"?\"), getInvalidPathError(\"?\", \"pathname\", \"search\", to));\n invariant(!to.pathname || !to.pathname.includes(\"#\"), getInvalidPathError(\"#\", \"pathname\", \"hash\", to));\n invariant(!to.search || !to.search.includes(\"#\"), getInvalidPathError(\"#\", \"search\", \"hash\", to));\n }\n let isEmptyPath = toArg === \"\" || to.pathname === \"\";\n let toPathname = isEmptyPath ? \"/\" : to.pathname;\n let from;\n // Routing is relative to the current pathname if explicitly requested.\n //\n // If a pathname is explicitly provided in `to`, it should be relative to the\n // route context. This is explained in `Note on `<Link to>` values` in our\n // migration guide from v5 as a means of disambiguation between `to` values\n // that begin with `/` and those that do not. However, this is problematic for\n // `to` values that do not provide a pathname. `to` can simply be a search or\n // hash string, in which case we should assume that the navigation is relative\n // to the current location's pathname and *not* the route pathname.\n if (isPathRelative || toPathname == null) {\n from = locationPathname;\n } else {\n let routePathnameIndex = routePathnames.length - 1;\n if (toPathname.startsWith(\"..\")) {\n let toSegments = toPathname.split(\"/\");\n // Each leading .. segment means \"go up one route\" instead of \"go up one\n // URL segment\". This is a key difference from how <a href> works and a\n // major reason we call this a \"to\" value instead of a \"href\".\n while(toSegments[0] === \"..\"){\n toSegments.shift();\n routePathnameIndex -= 1;\n }\n to.pathname = toSegments.join(\"/\");\n }\n // If there are more \"..\" segments than parent routes, resolve relative to\n // the root / URL.\n from = routePathnameIndex >= 0 ? routePathnames[routePathnameIndex] : \"/\";\n }\n let path = resolvePath(to, from);\n // Ensure the pathname has a trailing slash if the original \"to\" had one\n let hasExplicitTrailingSlash = toPathname && toPathname !== \"/\" && toPathname.endsWith(\"/\");\n // Or if this was a link to the current path which has a trailing slash\n let hasCurrentTrailingSlash = (isEmptyPath || toPathname === \".\") && locationPathname.endsWith(\"/\");\n if (!path.pathname.endsWith(\"/\") && (hasExplicitTrailingSlash || hasCurrentTrailingSlash)) {\n path.pathname += \"/\";\n }\n return path;\n}\n/**\n * @private\n */ function getToPathname(to) {\n // Empty strings should be treated the same as / paths\n return to === \"\" || to.pathname === \"\" ? \"/\" : typeof to === \"string\" ? parsePath(to).pathname : to.pathname;\n}\n/**\n * @private\n */ const joinPaths = (paths)=>paths.join(\"/\").replace(/\\/\\/+/g, \"/\");\n/**\n * @private\n */ const normalizePathname = (pathname)=>pathname.replace(/\\/+$/, \"\").replace(/^\\/*/, \"/\");\n/**\n * @private\n */ const normalizeSearch = (search)=>!search || search === \"?\" ? \"\" : search.startsWith(\"?\") ? search : \"?\" + search;\n/**\n * @private\n */ const normalizeHash = (hash)=>!hash || hash === \"#\" ? \"\" : hash.startsWith(\"#\") ? hash : \"#\" + hash;\n/**\n * This is a shortcut for creating `application/json` responses. Converts `data`\n * to JSON and sets the `Content-Type` header.\n */ const json = function json(data, init) {\n if (init === void 0) {\n init = {};\n }\n let responseInit = typeof init === \"number\" ? {\n status: init\n } : init;\n let headers = new Headers(responseInit.headers);\n if (!headers.has(\"Content-Type\")) {\n headers.set(\"Content-Type\", \"application/json; charset=utf-8\");\n }\n return new Response(JSON.stringify(data), _extends({}, responseInit, {\n headers\n }));\n};\nclass AbortedDeferredError extends Error {\n}\nclass DeferredData {\n constructor(data, responseInit){\n this.pendingKeysSet = new Set();\n this.subscribers = new Set();\n this.deferredKeys = [];\n invariant(data && typeof data === \"object\" && !Array.isArray(data), \"defer() only accepts plain objects\");\n // Set up an AbortController + Promise we can race against to exit early\n // cancellation\n let reject;\n this.abortPromise = new Promise((_, r)=>reject = r);\n this.controller = new AbortController();\n let onAbort = ()=>reject(new AbortedDeferredError(\"Deferred data aborted\"));\n this.unlistenAbortSignal = ()=>this.controller.signal.removeEventListener(\"abort\", onAbort);\n this.controller.signal.addEventListener(\"abort\", onAbort);\n this.data = Object.entries(data).reduce((acc, _ref)=>{\n let [key, value] = _ref;\n return Object.assign(acc, {\n [key]: this.trackPromise(key, value)\n });\n }, {});\n if (this.done) {\n // All incoming values were resolved\n this.unlistenAbortSignal();\n }\n this.init = responseInit;\n }\n trackPromise(key, value) {\n if (!(value instanceof Promise)) {\n return value;\n }\n this.deferredKeys.push(key);\n this.pendingKeysSet.add(key);\n // We store a little wrapper promise that will be extended with\n // _data/_error props upon resolve/reject\n let promise = Promise.race([\n value,\n this.abortPromise\n ]).then((data)=>this.onSettle(promise, key, undefined, data), (error)=>this.onSettle(promise, key, error));\n // Register rejection listeners to avoid uncaught promise rejections on\n // errors or aborted deferred values\n promise.catch(()=>{});\n Object.defineProperty(promise, \"_tracked\", {\n get: ()=>true\n });\n return promise;\n }\n onSettle(promise, key, error, data) {\n if (this.controller.signal.aborted && error instanceof AbortedDeferredError) {\n this.unlistenAbortSignal();\n Object.defineProperty(promise, \"_error\", {\n get: ()=>error\n });\n return Promise.reject(error);\n }\n this.pendingKeysSet.delete(key);\n if (this.done) {\n // Nothing left to abort!\n this.unlistenAbortSignal();\n }\n // If the promise was resolved/rejected with undefined, we'll throw an error as you\n // should always resolve with a value or null\n if (error === undefined && data === undefined) {\n let undefinedError = new Error('Deferred data for key \"' + key + '\" resolved/rejected with `undefined`, ' + \"you must resolve/reject with a value or `null`.\");\n Object.defineProperty(promise, \"_error\", {\n get: ()=>undefinedError\n });\n this.emit(false, key);\n return Promise.reject(undefinedError);\n }\n if (data === undefined) {\n Object.defineProperty(promise, \"_error\", {\n get: ()=>error\n });\n this.emit(false, key);\n return Promise.reject(error);\n }\n Object.defineProperty(promise, \"_data\", {\n get: ()=>data\n });\n this.emit(false, key);\n return data;\n }\n emit(aborted, settledKey) {\n this.subscribers.forEach((subscriber)=>subscriber(aborted, settledKey));\n }\n subscribe(fn) {\n this.subscribers.add(fn);\n return ()=>this.subscribers.delete(fn);\n }\n cancel() {\n this.controller.abort();\n this.pendingKeysSet.forEach((v, k)=>this.pendingKeysSet.delete(k));\n this.emit(true);\n }\n async resolveData(signal) {\n let aborted = false;\n if (!this.done) {\n let onAbort = ()=>this.cancel();\n signal.addEventListener(\"abort\", onAbort);\n aborted = await new Promise((resolve)=>{\n this.subscribe((aborted)=>{\n signal.removeEventListener(\"abort\", onAbort);\n if (aborted || this.done) {\n resolve(aborted);\n }\n });\n });\n }\n return aborted;\n }\n get done() {\n return this.pendingKeysSet.size === 0;\n }\n get unwrappedData() {\n invariant(this.data !== null && this.done, \"Can only unwrap data on initialized and settled deferreds\");\n return Object.entries(this.data).reduce((acc, _ref2)=>{\n let [key, value] = _ref2;\n return Object.assign(acc, {\n [key]: unwrapTrackedPromise(value)\n });\n }, {});\n }\n get pendingKeys() {\n return Array.from(this.pendingKeysSet);\n }\n}\nfunction isTrackedPromise(value) {\n return value instanceof Promise && value._tracked === true;\n}\nfunction unwrapTrackedPromise(value) {\n if (!isTrackedPromise(value)) {\n return value;\n }\n if (value._error) {\n throw value._error;\n }\n return value._data;\n}\nconst defer = function defer(data, init) {\n if (init === void 0) {\n init = {};\n }\n let responseInit = typeof init === \"number\" ? {\n status: init\n } : init;\n return new DeferredData(data, responseInit);\n};\n/**\n * A redirect response. Sets the status code and the `Location` header.\n * Defaults to \"302 Found\".\n */ const redirect = function redirect(url, init) {\n if (init === void 0) {\n init = 302;\n }\n let responseInit = init;\n if (typeof responseInit === \"number\") {\n responseInit = {\n status: responseInit\n };\n } else if (typeof responseInit.status === \"undefined\") {\n responseInit.status = 302;\n }\n let headers = new Headers(responseInit.headers);\n headers.set(\"Location\", url);\n return new Response(null, _extends({}, responseInit, {\n headers\n }));\n};\n/**\n * A redirect response that will force a document reload to the new location.\n * Sets the status code and the `Location` header.\n * Defaults to \"302 Found\".\n */ const redirectDocument = (url, init)=>{\n let response = redirect(url, init);\n response.headers.set(\"X-Remix-Reload-Document\", \"true\");\n return response;\n};\n/**\n * @private\n * Utility class we use to hold auto-unwrapped 4xx/5xx Response bodies\n */ class ErrorResponse {\n constructor(status, statusText, data, internal){\n if (internal === void 0) {\n internal = false;\n }\n this.status = status;\n this.statusText = statusText || \"\";\n this.internal = internal;\n if (data instanceof Error) {\n this.data = data.toString();\n this.error = data;\n } else {\n this.data = data;\n }\n }\n}\n/**\n * Check if the given error is an ErrorResponse generated from a 4xx/5xx\n * Response thrown from an action/loader\n */ function isRouteErrorResponse(error) {\n return error != null && typeof error.status === \"number\" && typeof error.statusText === \"string\" && typeof error.internal === \"boolean\" && \"data\" in error;\n}\nconst validMutationMethodsArr = [\n \"post\",\n \"put\",\n \"patch\",\n \"delete\"\n];\nconst validMutationMethods = new Set(validMutationMethodsArr);\nconst validRequestMethodsArr = [\n \"get\",\n ...validMutationMethodsArr\n];\nconst validRequestMethods = new Set(validRequestMethodsArr);\nconst redirectStatusCodes = new Set([\n 301,\n 302,\n 303,\n 307,\n 308\n]);\nconst redirectPreserveMethodStatusCodes = new Set([\n 307,\n 308\n]);\nconst IDLE_NAVIGATION = {\n state: \"idle\",\n location: undefined,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined\n};\nconst IDLE_FETCHER = {\n state: \"idle\",\n data: undefined,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined\n};\nconst IDLE_BLOCKER = {\n state: \"unblocked\",\n proceed: undefined,\n reset: undefined,\n location: undefined\n};\nconst ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|\\/\\/)/i;\nconst defaultMapRouteProperties = (route)=>({\n hasErrorBoundary: Boolean(route.hasErrorBoundary)\n });\n//#endregion\n////////////////////////////////////////////////////////////////////////////////\n//#region createRouter\n////////////////////////////////////////////////////////////////////////////////\n/**\n * Create a router and listen to history POP navigations\n */ function createRouter(init) {\n const routerWindow = init.window ? init.window : false ? 0 : undefined;\n const isBrowser = typeof routerWindow !== \"undefined\" && typeof routerWindow.document !== \"undefined\" && typeof routerWindow.document.createElement !== \"undefined\";\n const isServer = !isBrowser;\n invariant(init.routes.length > 0, \"You must provide a non-empty routes array to createRouter\");\n let mapRouteProperties;\n if (init.mapRouteProperties) {\n mapRouteProperties = init.mapRouteProperties;\n } else if (init.detectErrorBoundary) {\n // If they are still using the deprecated version, wrap it with the new API\n let detectErrorBoundary = init.detectErrorBoundary;\n mapRouteProperties = (route)=>({\n hasErrorBoundary: detectErrorBoundary(route)\n });\n } else {\n mapRouteProperties = defaultMapRouteProperties;\n }\n // Routes keyed by ID\n let manifest = {};\n // Routes in tree format for matching\n let dataRoutes = convertRoutesToDataRoutes(init.routes, mapRouteProperties, undefined, manifest);\n let inFlightDataRoutes;\n let basename = init.basename || \"/\";\n // Config driven behavior flags\n let future = _extends({\n v7_normalizeFormMethod: false,\n v7_prependBasename: false\n }, init.future);\n // Cleanup function for history\n let unlistenHistory = null;\n // Externally-provided functions to call on all state changes\n let subscribers = new Set();\n // Externally-provided object to hold scroll restoration locations during routing\n let savedScrollPositions = null;\n // Externally-provided function to get scroll restoration keys\n let getScrollRestorationKey = null;\n // Externally-provided function to get current scroll position\n let getScrollPosition = null;\n // One-time flag to control the initial hydration scroll restoration. Because\n // we don't get the saved positions from <ScrollRestoration /> until _after_\n // the initial render, we need to manually trigger a separate updateState to\n // send along the restoreScrollPosition\n // Set to true if we have `hydrationData` since we assume we were SSR'd and that\n // SSR did the initial scroll restoration.\n let initialScrollRestored = init.hydrationData != null;\n let initialMatches = matchRoutes(dataRoutes, init.history.location, basename);\n let initialErrors = null;\n if (initialMatches == null) {\n // If we do not match a user-provided-route, fall back to the root\n // to allow the error boundary to take over\n let error = getInternalRouterError(404, {\n pathname: init.history.location.pathname\n });\n let { matches, route } = getShortCircuitMatches(dataRoutes);\n initialMatches = matches;\n initialErrors = {\n [route.id]: error\n };\n }\n let initialized = // All initialMatches need to be loaded before we're ready. If we have lazy\n // functions around still then we'll need to run them in initialize()\n !initialMatches.some((m)=>m.route.lazy) && // And we have to either have no loaders or have been provided hydrationData\n (!initialMatches.some((m)=>m.route.loader) || init.hydrationData != null);\n let router;\n let state = {\n historyAction: init.history.action,\n location: init.history.location,\n matches: initialMatches,\n initialized,\n navigation: IDLE_NAVIGATION,\n // Don't restore on initial updateState() if we were SSR'd\n restoreScrollPosition: init.hydrationData != null ? false : null,\n preventScrollReset: false,\n revalidation: \"idle\",\n loaderData: init.hydrationData && init.hydrationData.loaderData || {},\n actionData: init.hydrationData && init.hydrationData.actionData || null,\n errors: init.hydrationData && init.hydrationData.errors || initialErrors,\n fetchers: new Map(),\n blockers: new Map()\n };\n // -- Stateful internal variables to manage navigations --\n // Current navigation in progress (to be committed in completeNavigation)\n let pendingAction = Action.Pop;\n // Should the current navigation prevent the scroll reset if scroll cannot\n // be restored?\n let pendingPreventScrollReset = false;\n // AbortController for the active navigation\n let pendingNavigationController;\n // We use this to avoid touching history in completeNavigation if a\n // revalidation is entirely uninterrupted\n let isUninterruptedRevalidation = false;\n // Use this internal flag to force revalidation of all loaders:\n // - submissions (completed or interrupted)\n // - useRevalidator()\n // - X-Remix-Revalidate (from redirect)\n let isRevalidationRequired = false;\n // Use this internal array to capture routes that require revalidation due\n // to a cancelled deferred on action submission\n let cancelledDeferredRoutes = [];\n // Use this internal array to capture fetcher loads that were cancelled by an\n // action navigation and require revalidation\n let cancelledFetcherLoads = [];\n // AbortControllers for any in-flight fetchers\n let fetchControllers = new Map();\n // Track loads based on the order in which they started\n let incrementingLoadId = 0;\n // Track the outstanding pending navigation data load to be compared against\n // the globally incrementing load when a fetcher load lands after a completed\n // navigation\n let pendingNavigationLoadId = -1;\n // Fetchers that triggered data reloads as a result of their actions\n let fetchReloadIds = new Map();\n // Fetchers that triggered redirect navigations\n let fetchRedirectIds = new Set();\n // Most recent href/match for fetcher.load calls for fetchers\n let fetchLoadMatches = new Map();\n // Store DeferredData instances for active route matches. When a\n // route loader returns defer() we stick one in here. Then, when a nested\n // promise resolves we update loaderData. If a new navigation starts we\n // cancel active deferreds for eliminated routes.\n let activeDeferreds = new Map();\n // Store blocker functions in a separate Map outside of router state since\n // we don't need to update UI state if they change\n let blockerFunctions = new Map();\n // Flag to ignore the next history update, so we can revert the URL change on\n // a POP navigation that was blocked by the user without touching router state\n let ignoreNextHistoryUpdate = false;\n // Initialize the router, all side effects should be kicked off from here.\n // Implemented as a Fluent API for ease of:\n // let router = createRouter(init).initialize();\n function initialize() {\n // If history informs us of a POP navigation, start the navigation but do not update\n // state. We'll update our own state once the navigation completes\n unlistenHistory = init.history.listen((_ref)=>{\n let { action: historyAction, location, delta } = _ref;\n // Ignore this event if it was just us resetting the URL from a\n // blocked POP navigation\n if (ignoreNextHistoryUpdate) {\n ignoreNextHistoryUpdate = false;\n return;\n }\n warning(blockerFunctions.size === 0 || delta != null, \"You are trying to use a blocker on a POP navigation to a location \" + \"that was not created by @remix-run/router. This will fail silently in \" + \"production. This can happen if you are navigating outside the router \" + \"via `window.history.pushState`/`window.location.hash` instead of using \" + \"router navigation APIs. This can also happen if you are using \" + \"createHashRouter and the user manually changes the URL.\");\n let blockerKey = shouldBlockNavigation({\n currentLocation: state.location,\n nextLocation: location,\n historyAction\n });\n if (blockerKey && delta != null) {\n // Restore the URL to match the current UI, but don't update router state\n ignoreNextHistoryUpdate = true;\n init.history.go(delta * -1);\n // Put the blocker into a blocked state\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location,\n proceed () {\n updateBlocker(blockerKey, {\n state: \"proceeding\",\n proceed: undefined,\n reset: undefined,\n location\n });\n // Re-do the same POP navigation we just blocked\n init.history.go(delta);\n },\n reset () {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey, IDLE_BLOCKER);\n updateState({\n blockers\n });\n }\n });\n return;\n }\n return startNavigation(historyAction, location);\n });\n // Kick off initial data load if needed. Use Pop to avoid modifying history\n // Note we don't do any handling of lazy here. For SPA's it'll get handled\n // in the normal navigation flow. For SSR it's expected that lazy modules are\n // resolved prior to router creation since we can't go into a fallbackElement\n // UI for SSR'd apps\n if (!state.initialized) {\n startNavigation(Action.Pop, state.location);\n }\n return router;\n }\n // Clean up a router and it's side effects\n function dispose() {\n if (unlistenHistory) {\n unlistenHistory();\n }\n subscribers.clear();\n pendingNavigationController && pendingNavigationController.abort();\n state.fetchers.forEach((_, key)=>deleteFetcher(key));\n state.blockers.forEach((_, key)=>deleteBlocker(key));\n }\n // Subscribe to state updates for the router\n function subscribe(fn) {\n subscribers.add(fn);\n return ()=>subscribers.delete(fn);\n }\n // Update our state and notify the calling context of the change\n function updateState(newState) {\n state = _extends({}, state, newState);\n subscribers.forEach((subscriber)=>subscriber(state));\n }\n // Complete a navigation returning the state.navigation back to the IDLE_NAVIGATION\n // and setting state.[historyAction/location/matches] to the new route.\n // - Location is a required param\n // - Navigation will always be set to IDLE_NAVIGATION\n // - Can pass any other state in newState\n function completeNavigation(location, newState) {\n var _location$state, _location$state2;\n // Deduce if we're in a loading/actionReload state:\n // - We have committed actionData in the store\n // - The current navigation was a mutation submission\n // - We're past the submitting state and into the loading state\n // - The location being loaded is not the result of a redirect\n let isActionReload = state.actionData != null && state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && state.navigation.state === \"loading\" && ((_location$state = location.state) == null ? void 0 : _location$state._isRedirect) !== true;\n let actionData;\n if (newState.actionData) {\n if (Object.keys(newState.actionData).length > 0) {\n actionData = newState.actionData;\n } else {\n // Empty actionData -> clear prior actionData due to an action error\n actionData = null;\n }\n } else if (isActionReload) {\n // Keep the current data if we're wrapping up the action reload\n actionData = state.actionData;\n } else {\n // Clear actionData on any other completed navigations\n actionData = null;\n }\n // Always preserve any existing loaderData from re-used routes\n let loaderData = newState.loaderData ? mergeLoaderData(state.loaderData, newState.loaderData, newState.matches || [], newState.errors) : state.loaderData;\n // On a successful navigation we can assume we got through all blockers\n // so we can start fresh\n let blockers = state.blockers;\n if (blockers.size > 0) {\n blockers = new Map(blockers);\n blockers.forEach((_, k)=>blockers.set(k, IDLE_BLOCKER));\n }\n // Always respect the user flag. Otherwise don't reset on mutation\n // submission navigations unless they redirect\n let preventScrollReset = pendingPreventScrollReset === true || state.navigation.formMethod != null && isMutationMethod(state.navigation.formMethod) && ((_location$state2 = location.state) == null ? void 0 : _location$state2._isRedirect) !== true;\n if (inFlightDataRoutes) {\n dataRoutes = inFlightDataRoutes;\n inFlightDataRoutes = undefined;\n }\n if (isUninterruptedRevalidation) ;\n else if (pendingAction === Action.Pop) ;\n else if (pendingAction === Action.Push) {\n init.history.push(location, location.state);\n } else if (pendingAction === Action.Replace) {\n init.history.replace(location, location.state);\n }\n updateState(_extends({}, newState, {\n actionData,\n loaderData,\n historyAction: pendingAction,\n location,\n initialized: true,\n navigation: IDLE_NAVIGATION,\n revalidation: \"idle\",\n restoreScrollPosition: getSavedScrollPosition(location, newState.matches || state.matches),\n preventScrollReset,\n blockers\n }));\n // Reset stateful navigation vars\n pendingAction = Action.Pop;\n pendingPreventScrollReset = false;\n isUninterruptedRevalidation = false;\n isRevalidationRequired = false;\n cancelledDeferredRoutes = [];\n cancelledFetcherLoads = [];\n }\n // Trigger a navigation event, which can either be a numerical POP or a PUSH\n // replace with an optional submission\n async function navigate(to, opts) {\n if (typeof to === \"number\") {\n init.history.go(to);\n return;\n }\n let normalizedPath = normalizeTo(state.location, state.matches, basename, future.v7_prependBasename, to, opts == null ? void 0 : opts.fromRouteId, opts == null ? void 0 : opts.relative);\n let { path, submission, error } = normalizeNavigateOptions(future.v7_normalizeFormMethod, false, normalizedPath, opts);\n let currentLocation = state.location;\n let nextLocation = createLocation(state.location, path, opts && opts.state);\n // When using navigate as a PUSH/REPLACE we aren't reading an already-encoded\n // URL from window.location, so we need to encode it here so the behavior\n // remains the same as POP and non-data-router usages. new URL() does all\n // the same encoding we'd get from a history.pushState/window.location read\n // without having to touch history\n nextLocation = _extends({}, nextLocation, init.history.encodeLocation(nextLocation));\n let userReplace = opts && opts.replace != null ? opts.replace : undefined;\n let historyAction = Action.Push;\n if (userReplace === true) {\n historyAction = Action.Replace;\n } else if (userReplace === false) ;\n else if (submission != null && isMutationMethod(submission.formMethod) && submission.formAction === state.location.pathname + state.location.search) {\n // By default on submissions to the current location we REPLACE so that\n // users don't have to double-click the back button to get to the prior\n // location. If the user redirects to a different location from the\n // action/loader this will be ignored and the redirect will be a PUSH\n historyAction = Action.Replace;\n }\n let preventScrollReset = opts && \"preventScrollReset\" in opts ? opts.preventScrollReset === true : undefined;\n let blockerKey = shouldBlockNavigation({\n currentLocation,\n nextLocation,\n historyAction\n });\n if (blockerKey) {\n // Put the blocker into a blocked state\n updateBlocker(blockerKey, {\n state: \"blocked\",\n location: nextLocation,\n proceed () {\n updateBlocker(blockerKey, {\n state: \"proceeding\",\n proceed: undefined,\n reset: undefined,\n location: nextLocation\n });\n // Send the same navigation through\n navigate(to, opts);\n },\n reset () {\n let blockers = new Map(state.blockers);\n blockers.set(blockerKey, IDLE_BLOCKER);\n updateState({\n blockers\n });\n }\n });\n return;\n }\n return await startNavigation(historyAction, nextLocation, {\n submission,\n // Send through the formData serialization error if we have one so we can\n // render at the right error boundary after we match routes\n pendingError: error,\n preventScrollReset,\n replace: opts && opts.replace\n });\n }\n // Revalidate all current loaders. If a navigation is in progress or if this\n // is interrupted by a navigation, allow this to \"succeed\" by calling all\n // loaders during the next loader round\n function revalidate() {\n interruptActiveLoads();\n updateState({\n revalidation: \"loading\"\n });\n // If we're currently submitting an action, we don't need to start a new\n // navigation, we'll just let the follow up loader execution call all loaders\n if (state.navigation.state === \"submitting\") {\n return;\n }\n // If we're currently in an idle state, start a new navigation for the current\n // action/location and mark it as uninterrupted, which will skip the history\n // update in completeNavigation\n if (state.navigation.state === \"idle\") {\n startNavigation(state.historyAction, state.location, {\n startUninterruptedRevalidation: true\n });\n return;\n }\n // Otherwise, if we're currently in a loading state, just start a new\n // navigation to the navigation.location but do not trigger an uninterrupted\n // revalidation so that history correctly updates once the navigation completes\n startNavigation(pendingAction || state.historyAction, state.navigation.location, {\n overrideNavigation: state.navigation\n });\n }\n // Start a navigation to the given action/location. Can optionally provide a\n // overrideNavigation which will override the normalLoad in the case of a redirect\n // navigation\n async function startNavigation(historyAction, location, opts) {\n // Abort any in-progress navigations and start a new one. Unset any ongoing\n // uninterrupted revalidations unless told otherwise, since we want this\n // new navigation to update history normally\n pendingNavigationController && pendingNavigationController.abort();\n pendingNavigationController = null;\n pendingAction = historyAction;\n isUninterruptedRevalidation = (opts && opts.startUninterruptedRevalidation) === true;\n // Save the current scroll position every time we start a new navigation,\n // and track whether we should reset scroll on completion\n saveScrollPosition(state.location, state.matches);\n pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let loadingNavigation = opts && opts.overrideNavigation;\n let matches = matchRoutes(routesToUse, location, basename);\n // Short circuit with a 404 on the root error boundary if we match nothing\n if (!matches) {\n let error = getInternalRouterError(404, {\n pathname: location.pathname\n });\n let { matches: notFoundMatches, route } = getShortCircuitMatches(routesToUse);\n // Cancel all pending deferred on 404s since we don't keep any routes\n cancelActiveDeferreds();\n completeNavigation(location, {\n matches: notFoundMatches,\n loaderData: {},\n errors: {\n [route.id]: error\n }\n });\n return;\n }\n // Short circuit if it's only a hash change and not a revalidation or\n // mutation submission.\n //\n // Ignore on initial page loads because since the initial load will always\n // be \"same hash\". For example, on /page#hash and submit a <Form method=\"post\">\n // which will default to a navigation to /page\n if (state.initialized && !isRevalidationRequired && isHashChangeOnly(state.location, location) && !(opts && opts.submission && isMutationMethod(opts.submission.formMethod))) {\n completeNavigation(location, {\n matches\n });\n return;\n }\n // Create a controller/Request for this navigation\n pendingNavigationController = new AbortController();\n let request = createClientSideRequest(init.history, location, pendingNavigationController.signal, opts && opts.submission);\n let pendingActionData;\n let pendingError;\n if (opts && opts.pendingError) {\n // If we have a pendingError, it means the user attempted a GET submission\n // with binary FormData so assign here and skip to handleLoaders. That\n // way we handle calling loaders above the boundary etc. It's not really\n // different from an actionError in that sense.\n pendingError = {\n [findNearestBoundary(matches).route.id]: opts.pendingError\n };\n } else if (opts && opts.submission && isMutationMethod(opts.submission.formMethod)) {\n // Call action if we received an action submission\n let actionOutput = await handleAction(request, location, opts.submission, matches, {\n replace: opts.replace\n });\n if (actionOutput.shortCircuited) {\n return;\n }\n pendingActionData = actionOutput.pendingActionData;\n pendingError = actionOutput.pendingActionError;\n loadingNavigation = getLoadingNavigation(location, opts.submission);\n // Create a GET request for the loaders\n request = new Request(request.url, {\n signal: request.signal\n });\n }\n // Call loaders\n let { shortCircuited, loaderData, errors } = await handleLoaders(request, location, matches, loadingNavigation, opts && opts.submission, opts && opts.fetcherSubmission, opts && opts.replace, pendingActionData, pendingError);\n if (shortCircuited) {\n return;\n }\n // Clean up now that the action/loaders have completed. Don't clean up if\n // we short circuited because pendingNavigationController will have already\n // been assigned to a new controller for the next navigation\n pendingNavigationController = null;\n completeNavigation(location, _extends({\n matches\n }, pendingActionData ? {\n actionData: pendingActionData\n } : {}, {\n loaderData,\n errors\n }));\n }\n // Call the action matched by the leaf route for this navigation and handle\n // redirects/errors\n async function handleAction(request, location, submission, matches, opts) {\n if (opts === void 0) {\n opts = {};\n }\n interruptActiveLoads();\n // Put us in a submitting state\n let navigation = getSubmittingNavigation(location, submission);\n updateState({\n navigation\n });\n // Call our action and get the result\n let result;\n let actionMatch = getTargetMatch(matches, location);\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n result = {\n type: ResultType.error,\n error: getInternalRouterError(405, {\n method: request.method,\n pathname: location.pathname,\n routeId: actionMatch.route.id\n })\n };\n } else {\n result = await callLoaderOrAction(\"action\", request, actionMatch, matches, manifest, mapRouteProperties, basename);\n if (request.signal.aborted) {\n return {\n shortCircuited: true\n };\n }\n }\n if (isRedirectResult(result)) {\n let replace;\n if (opts && opts.replace != null) {\n replace = opts.replace;\n } else {\n // If the user didn't explicity indicate replace behavior, replace if\n // we redirected to the exact same location we're currently at to avoid\n // double back-buttons\n replace = result.location === state.location.pathname + state.location.search;\n }\n await startRedirectNavigation(state, result, {\n submission,\n replace\n });\n return {\n shortCircuited: true\n };\n }\n if (isErrorResult(result)) {\n // Store off the pending error - we use it to determine which loaders\n // to call and will commit it when we complete the navigation\n let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id);\n // By default, all submissions are REPLACE navigations, but if the\n // action threw an error that'll be rendered in an errorElement, we fall\n // back to PUSH so that the user can use the back button to get back to\n // the pre-submission form location to try again\n if ((opts && opts.replace) !== true) {\n pendingAction = Action.Push;\n }\n return {\n // Send back an empty object we can use to clear out any prior actionData\n pendingActionData: {},\n pendingActionError: {\n [boundaryMatch.route.id]: result.error\n }\n };\n }\n if (isDeferredResult(result)) {\n throw getInternalRouterError(400, {\n type: \"defer-action\"\n });\n }\n return {\n pendingActionData: {\n [actionMatch.route.id]: result.data\n }\n };\n }\n // Call all applicable loaders for the given matches, handling redirects,\n // errors, etc.\n async function handleLoaders(request, location, matches, overrideNavigation, submission, fetcherSubmission, replace, pendingActionData, pendingError) {\n // Figure out the right navigation we want to use for data loading\n let loadingNavigation = overrideNavigation || getLoadingNavigation(location, submission);\n // If this was a redirect from an action we don't have a \"submission\" but\n // we have it on the loading navigation so use that if available\n let activeSubmission = submission || fetcherSubmission || getSubmissionFromNavigation(loadingNavigation);\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, activeSubmission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionData, pendingError);\n // Cancel pending deferreds for no-longer-matched routes or routes we're\n // about to reload. Note that if this is an action reload we would have\n // already cancelled all pending deferreds so this would be a no-op\n cancelActiveDeferreds((routeId)=>!(matches && matches.some((m)=>m.route.id === routeId)) || matchesToLoad && matchesToLoad.some((m)=>m.route.id === routeId));\n pendingNavigationLoadId = ++incrementingLoadId;\n // Short circuit if we have no loaders to run\n if (matchesToLoad.length === 0 && revalidatingFetchers.length === 0) {\n let updatedFetchers = markFetchRedirectsDone();\n completeNavigation(location, _extends({\n matches,\n loaderData: {},\n // Commit pending error if we're short circuiting\n errors: pendingError || null\n }, pendingActionData ? {\n actionData: pendingActionData\n } : {}, updatedFetchers ? {\n fetchers: new Map(state.fetchers)\n } : {}));\n return {\n shortCircuited: true\n };\n }\n // If this is an uninterrupted revalidation, we remain in our current idle\n // state. If not, we need to switch to our loading state and load data,\n // preserving any new action data or existing action data (in the case of\n // a revalidation interrupting an actionReload)\n if (!isUninterruptedRevalidation) {\n revalidatingFetchers.forEach((rf)=>{\n let fetcher = state.fetchers.get(rf.key);\n let revalidatingFetcher = getLoadingFetcher(undefined, fetcher ? fetcher.data : undefined);\n state.fetchers.set(rf.key, revalidatingFetcher);\n });\n let actionData = pendingActionData || state.actionData;\n updateState(_extends({\n navigation: loadingNavigation\n }, actionData ? Object.keys(actionData).length === 0 ? {\n actionData: null\n } : {\n actionData\n } : {}, revalidatingFetchers.length > 0 ? {\n fetchers: new Map(state.fetchers)\n } : {}));\n }\n revalidatingFetchers.forEach((rf)=>{\n if (fetchControllers.has(rf.key)) {\n abortFetcher(rf.key);\n }\n if (rf.controller) {\n // Fetchers use an independent AbortController so that aborting a fetcher\n // (via deleteFetcher) does not abort the triggering navigation that\n // triggered the revalidation\n fetchControllers.set(rf.key, rf.controller);\n }\n });\n // Proxy navigation abort through to revalidation fetchers\n let abortPendingFetchRevalidations = ()=>revalidatingFetchers.forEach((f)=>abortFetcher(f.key));\n if (pendingNavigationController) {\n pendingNavigationController.signal.addEventListener(\"abort\", abortPendingFetchRevalidations);\n }\n let { results, loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(state.matches, matches, matchesToLoad, revalidatingFetchers, request);\n if (request.signal.aborted) {\n return {\n shortCircuited: true\n };\n }\n // Clean up _after_ loaders have completed. Don't clean up if we short\n // circuited because fetchControllers would have been aborted and\n // reassigned to new controllers for the next navigation\n if (pendingNavigationController) {\n pendingNavigationController.signal.removeEventListener(\"abort\", abortPendingFetchRevalidations);\n }\n revalidatingFetchers.forEach((rf)=>fetchControllers.delete(rf.key));\n // If any loaders returned a redirect Response, start a new REPLACE navigation\n let redirect = findRedirect(results);\n if (redirect) {\n if (redirect.idx >= matchesToLoad.length) {\n // If this redirect came from a fetcher make sure we mark it in\n // fetchRedirectIds so it doesn't get revalidated on the next set of\n // loader executions\n let fetcherKey = revalidatingFetchers[redirect.idx - matchesToLoad.length].key;\n fetchRedirectIds.add(fetcherKey);\n }\n await startRedirectNavigation(state, redirect.result, {\n replace\n });\n return {\n shortCircuited: true\n };\n }\n // Process and commit output from loaders\n let { loaderData, errors } = processLoaderData(state, matches, matchesToLoad, loaderResults, pendingError, revalidatingFetchers, fetcherResults, activeDeferreds);\n // Wire up subscribers to update loaderData as promises settle\n activeDeferreds.forEach((deferredData, routeId)=>{\n deferredData.subscribe((aborted)=>{\n // Note: No need to updateState here since the TrackedPromise on\n // loaderData is stable across resolve/reject\n // Remove this instance if we were aborted or if promises have settled\n if (aborted || deferredData.done) {\n activeDeferreds.delete(routeId);\n }\n });\n });\n let updatedFetchers = markFetchRedirectsDone();\n let didAbortFetchLoads = abortStaleFetchLoads(pendingNavigationLoadId);\n let shouldUpdateFetchers = updatedFetchers || didAbortFetchLoads || revalidatingFetchers.length > 0;\n return _extends({\n loaderData,\n errors\n }, shouldUpdateFetchers ? {\n fetchers: new Map(state.fetchers)\n } : {});\n }\n function getFetcher(key) {\n return state.fetchers.get(key) || IDLE_FETCHER;\n }\n // Trigger a fetcher load/submit for the given fetcher key\n function fetch(key, routeId, href, opts) {\n if (isServer) {\n throw new Error(\"router.fetch() was called during the server render, but it shouldn't be. \" + \"You are likely calling a useFetcher() method in the body of your component. \" + \"Try moving it to a useEffect or a callback.\");\n }\n if (fetchControllers.has(key)) abortFetcher(key);\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let normalizedPath = normalizeTo(state.location, state.matches, basename, future.v7_prependBasename, href, routeId, opts == null ? void 0 : opts.relative);\n let matches = matchRoutes(routesToUse, normalizedPath, basename);\n if (!matches) {\n setFetcherError(key, routeId, getInternalRouterError(404, {\n pathname: normalizedPath\n }));\n return;\n }\n let { path, submission, error } = normalizeNavigateOptions(future.v7_normalizeFormMethod, true, normalizedPath, opts);\n if (error) {\n setFetcherError(key, routeId, error);\n return;\n }\n let match = getTargetMatch(matches, path);\n pendingPreventScrollReset = (opts && opts.preventScrollReset) === true;\n if (submission && isMutationMethod(submission.formMethod)) {\n handleFetcherAction(key, routeId, path, match, matches, submission);\n return;\n }\n // Store off the match so we can call it's shouldRevalidate on subsequent\n // revalidations\n fetchLoadMatches.set(key, {\n routeId,\n path\n });\n handleFetcherLoader(key, routeId, path, match, matches, submission);\n }\n // Call the action for the matched fetcher.submit(), and then handle redirects,\n // errors, and revalidation\n async function handleFetcherAction(key, routeId, path, match, requestMatches, submission) {\n interruptActiveLoads();\n fetchLoadMatches.delete(key);\n if (!match.route.action && !match.route.lazy) {\n let error = getInternalRouterError(405, {\n method: submission.formMethod,\n pathname: path,\n routeId: routeId\n });\n setFetcherError(key, routeId, error);\n return;\n }\n // Put this fetcher into it's submitting state\n let existingFetcher = state.fetchers.get(key);\n let fetcher = getSubmittingFetcher(submission, existingFetcher);\n state.fetchers.set(key, fetcher);\n updateState({\n fetchers: new Map(state.fetchers)\n });\n // Call the action for the fetcher\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(init.history, path, abortController.signal, submission);\n fetchControllers.set(key, abortController);\n let originatingLoadId = incrementingLoadId;\n let actionResult = await callLoaderOrAction(\"action\", fetchRequest, match, requestMatches, manifest, mapRouteProperties, basename);\n if (fetchRequest.signal.aborted) {\n // We can delete this so long as we weren't aborted by ou our own fetcher\n // re-submit which would have put _new_ controller is in fetchControllers\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n return;\n }\n if (isRedirectResult(actionResult)) {\n fetchControllers.delete(key);\n if (pendingNavigationLoadId > originatingLoadId) {\n // A new navigation was kicked off after our action started, so that\n // should take precedence over this redirect navigation. We already\n // set isRevalidationRequired so all loaders for the new route should\n // fire unless opted out via shouldRevalidate\n let doneFetcher = getDoneFetcher(undefined);\n state.fetchers.set(key, doneFetcher);\n updateState({\n fetchers: new Map(state.fetchers)\n });\n return;\n } else {\n fetchRedirectIds.add(key);\n let loadingFetcher = getLoadingFetcher(submission);\n state.fetchers.set(key, loadingFetcher);\n updateState({\n fetchers: new Map(state.fetchers)\n });\n return startRedirectNavigation(state, actionResult, {\n submission,\n isFetchActionRedirect: true\n });\n }\n }\n // Process any non-redirect errors thrown\n if (isErrorResult(actionResult)) {\n setFetcherError(key, routeId, actionResult.error);\n return;\n }\n if (isDeferredResult(actionResult)) {\n throw getInternalRouterError(400, {\n type: \"defer-action\"\n });\n }\n // Start the data load for current matches, or the next location if we're\n // in the middle of a navigation\n let nextLocation = state.navigation.location || state.location;\n let revalidationRequest = createClientSideRequest(init.history, nextLocation, abortController.signal);\n let routesToUse = inFlightDataRoutes || dataRoutes;\n let matches = state.navigation.state !== \"idle\" ? matchRoutes(routesToUse, state.navigation.location, basename) : state.matches;\n invariant(matches, \"Didn't find any matches after fetcher action\");\n let loadId = ++incrementingLoadId;\n fetchReloadIds.set(key, loadId);\n let loadFetcher = getLoadingFetcher(submission, actionResult.data);\n state.fetchers.set(key, loadFetcher);\n let [matchesToLoad, revalidatingFetchers] = getMatchesToLoad(init.history, state, matches, submission, nextLocation, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, {\n [match.route.id]: actionResult.data\n }, undefined // No need to send through errors since we short circuit above\n );\n // Put all revalidating fetchers into the loading state, except for the\n // current fetcher which we want to keep in it's current loading state which\n // contains it's action submission info + action data\n revalidatingFetchers.filter((rf)=>rf.key !== key).forEach((rf)=>{\n let staleKey = rf.key;\n let existingFetcher = state.fetchers.get(staleKey);\n let revalidatingFetcher = getLoadingFetcher(undefined, existingFetcher ? existingFetcher.data : undefined);\n state.fetchers.set(staleKey, revalidatingFetcher);\n if (fetchControllers.has(staleKey)) {\n abortFetcher(staleKey);\n }\n if (rf.controller) {\n fetchControllers.set(staleKey, rf.controller);\n }\n });\n updateState({\n fetchers: new Map(state.fetchers)\n });\n let abortPendingFetchRevalidations = ()=>revalidatingFetchers.forEach((rf)=>abortFetcher(rf.key));\n abortController.signal.addEventListener(\"abort\", abortPendingFetchRevalidations);\n let { results, loaderResults, fetcherResults } = await callLoadersAndMaybeResolveData(state.matches, matches, matchesToLoad, revalidatingFetchers, revalidationRequest);\n if (abortController.signal.aborted) {\n return;\n }\n abortController.signal.removeEventListener(\"abort\", abortPendingFetchRevalidations);\n fetchReloadIds.delete(key);\n fetchControllers.delete(key);\n revalidatingFetchers.forEach((r)=>fetchControllers.delete(r.key));\n let redirect = findRedirect(results);\n if (redirect) {\n if (redirect.idx >= matchesToLoad.length) {\n // If this redirect came from a fetcher make sure we mark it in\n // fetchRedirectIds so it doesn't get revalidated on the next set of\n // loader executions\n let fetcherKey = revalidatingFetchers[redirect.idx - matchesToLoad.length].key;\n fetchRedirectIds.add(fetcherKey);\n }\n return startRedirectNavigation(state, redirect.result);\n }\n // Process and commit output from loaders\n let { loaderData, errors } = processLoaderData(state, state.matches, matchesToLoad, loaderResults, undefined, revalidatingFetchers, fetcherResults, activeDeferreds);\n // Since we let revalidations complete even if the submitting fetcher was\n // deleted, only put it back to idle if it hasn't been deleted\n if (state.fetchers.has(key)) {\n let doneFetcher = getDoneFetcher(actionResult.data);\n state.fetchers.set(key, doneFetcher);\n }\n let didAbortFetchLoads = abortStaleFetchLoads(loadId);\n // If we are currently in a navigation loading state and this fetcher is\n // more recent than the navigation, we want the newer data so abort the\n // navigation and complete it with the fetcher data\n if (state.navigation.state === \"loading\" && loadId > pendingNavigationLoadId) {\n invariant(pendingAction, \"Expected pending action\");\n pendingNavigationController && pendingNavigationController.abort();\n completeNavigation(state.navigation.location, {\n matches,\n loaderData,\n errors,\n fetchers: new Map(state.fetchers)\n });\n } else {\n // otherwise just update with the fetcher data, preserving any existing\n // loaderData for loaders that did not need to reload. We have to\n // manually merge here since we aren't going through completeNavigation\n updateState(_extends({\n errors,\n loaderData: mergeLoaderData(state.loaderData, loaderData, matches, errors)\n }, didAbortFetchLoads || revalidatingFetchers.length > 0 ? {\n fetchers: new Map(state.fetchers)\n } : {}));\n isRevalidationRequired = false;\n }\n }\n // Call the matched loader for fetcher.load(), handling redirects, errors, etc.\n async function handleFetcherLoader(key, routeId, path, match, matches, submission) {\n let existingFetcher = state.fetchers.get(key);\n // Put this fetcher into it's loading state\n let loadingFetcher = getLoadingFetcher(submission, existingFetcher ? existingFetcher.data : undefined);\n state.fetchers.set(key, loadingFetcher);\n updateState({\n fetchers: new Map(state.fetchers)\n });\n // Call the loader for this fetcher route match\n let abortController = new AbortController();\n let fetchRequest = createClientSideRequest(init.history, path, abortController.signal);\n fetchControllers.set(key, abortController);\n let originatingLoadId = incrementingLoadId;\n let result = await callLoaderOrAction(\"loader\", fetchRequest, match, matches, manifest, mapRouteProperties, basename);\n // Deferred isn't supported for fetcher loads, await everything and treat it\n // as a normal load. resolveDeferredData will return undefined if this\n // fetcher gets aborted, so we just leave result untouched and short circuit\n // below if that happens\n if (isDeferredResult(result)) {\n result = await resolveDeferredData(result, fetchRequest.signal, true) || result;\n }\n // We can delete this so long as we weren't aborted by our our own fetcher\n // re-load which would have put _new_ controller is in fetchControllers\n if (fetchControllers.get(key) === abortController) {\n fetchControllers.delete(key);\n }\n if (fetchRequest.signal.aborted) {\n return;\n }\n // If the loader threw a redirect Response, start a new REPLACE navigation\n if (isRedirectResult(result)) {\n if (pendingNavigationLoadId > originatingLoadId) {\n // A new navigation was kicked off after our loader started, so that\n // should take precedence over this redirect navigation\n let doneFetcher = getDoneFetcher(undefined);\n state.fetchers.set(key, doneFetcher);\n updateState({\n fetchers: new Map(state.fetchers)\n });\n return;\n } else {\n fetchRedirectIds.add(key);\n await startRedirectNavigation(state, result);\n return;\n }\n }\n // Process any non-redirect errors thrown\n if (isErrorResult(result)) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n state.fetchers.delete(key);\n // TODO: In remix, this would reset to IDLE_NAVIGATION if it was a catch -\n // do we need to behave any differently with our non-redirect errors?\n // What if it was a non-redirect Response?\n updateState({\n fetchers: new Map(state.fetchers),\n errors: {\n [boundaryMatch.route.id]: result.error\n }\n });\n return;\n }\n invariant(!isDeferredResult(result), \"Unhandled fetcher deferred data\");\n // Put the fetcher back into an idle state\n let doneFetcher = getDoneFetcher(result.data);\n state.fetchers.set(key, doneFetcher);\n updateState({\n fetchers: new Map(state.fetchers)\n });\n }\n /**\n * Utility function to handle redirects returned from an action or loader.\n * Normally, a redirect \"replaces\" the navigation that triggered it. So, for\n * example:\n *\n * - user is on /a\n * - user clicks a link to /b\n * - loader for /b redirects to /c\n *\n * In a non-JS app the browser would track the in-flight navigation to /b and\n * then replace it with /c when it encountered the redirect response. In\n * the end it would only ever update the URL bar with /c.\n *\n * In client-side routing using pushState/replaceState, we aim to emulate\n * this behavior and we also do not update history until the end of the\n * navigation (including processed redirects). This means that we never\n * actually touch history until we've processed redirects, so we just use\n * the history action from the original navigation (PUSH or REPLACE).\n */ async function startRedirectNavigation(state, redirect, _temp) {\n let { submission, replace, isFetchActionRedirect } = _temp === void 0 ? {} : _temp;\n if (redirect.revalidate) {\n isRevalidationRequired = true;\n }\n let redirectLocation = createLocation(state.location, redirect.location, _extends({\n _isRedirect: true\n }, isFetchActionRedirect ? {\n _isFetchActionRedirect: true\n } : {}));\n invariant(redirectLocation, \"Expected a location on the redirect navigation\");\n if (isBrowser) {\n let isDocumentReload = false;\n if (redirect.reloadDocument) {\n // Hard reload if the response contained X-Remix-Reload-Document\n isDocumentReload = true;\n } else if (ABSOLUTE_URL_REGEX.test(redirect.location)) {\n const url = init.history.createURL(redirect.location);\n isDocumentReload = // Hard reload if it's an absolute URL to a new origin\n url.origin !== routerWindow.location.origin || // Hard reload if it's an absolute URL that does not match our basename\n stripBasename(url.pathname, basename) == null;\n }\n if (isDocumentReload) {\n if (replace) {\n routerWindow.location.replace(redirect.location);\n } else {\n routerWindow.location.assign(redirect.location);\n }\n return;\n }\n }\n // There's no need to abort on redirects, since we don't detect the\n // redirect until the action/loaders have settled\n pendingNavigationController = null;\n let redirectHistoryAction = replace === true ? Action.Replace : Action.Push;\n // Use the incoming submission if provided, fallback on the active one in\n // state.navigation\n let activeSubmission = submission || getSubmissionFromNavigation(state.navigation);\n // If this was a 307/308 submission we want to preserve the HTTP method and\n // re-submit the GET/POST/PUT/PATCH/DELETE as a submission navigation to the\n // redirected location\n if (redirectPreserveMethodStatusCodes.has(redirect.status) && activeSubmission && isMutationMethod(activeSubmission.formMethod)) {\n await startNavigation(redirectHistoryAction, redirectLocation, {\n submission: _extends({}, activeSubmission, {\n formAction: redirect.location\n }),\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset\n });\n } else if (isFetchActionRedirect) {\n // For a fetch action redirect, we kick off a new loading navigation\n // without the fetcher submission, but we send it along for shouldRevalidate\n await startNavigation(redirectHistoryAction, redirectLocation, {\n overrideNavigation: getLoadingNavigation(redirectLocation),\n fetcherSubmission: activeSubmission,\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset\n });\n } else {\n // If we have a submission, we will preserve it through the redirect navigation\n let overrideNavigation = getLoadingNavigation(redirectLocation, activeSubmission);\n await startNavigation(redirectHistoryAction, redirectLocation, {\n overrideNavigation,\n // Preserve this flag across redirects\n preventScrollReset: pendingPreventScrollReset\n });\n }\n }\n async function callLoadersAndMaybeResolveData(currentMatches, matches, matchesToLoad, fetchersToLoad, request) {\n // Call all navigation loaders and revalidating fetcher loaders in parallel,\n // then slice off the results into separate arrays so we can handle them\n // accordingly\n let results = await Promise.all([\n ...matchesToLoad.map((match)=>callLoaderOrAction(\"loader\", request, match, matches, manifest, mapRouteProperties, basename)),\n ...fetchersToLoad.map((f)=>{\n if (f.matches && f.match && f.controller) {\n return callLoaderOrAction(\"loader\", createClientSideRequest(init.history, f.path, f.controller.signal), f.match, f.matches, manifest, mapRouteProperties, basename);\n } else {\n let error = {\n type: ResultType.error,\n error: getInternalRouterError(404, {\n pathname: f.path\n })\n };\n return error;\n }\n })\n ]);\n let loaderResults = results.slice(0, matchesToLoad.length);\n let fetcherResults = results.slice(matchesToLoad.length);\n await Promise.all([\n resolveDeferredResults(currentMatches, matchesToLoad, loaderResults, loaderResults.map(()=>request.signal), false, state.loaderData),\n resolveDeferredResults(currentMatches, fetchersToLoad.map((f)=>f.match), fetcherResults, fetchersToLoad.map((f)=>f.controller ? f.controller.signal : null), true)\n ]);\n return {\n results,\n loaderResults,\n fetcherResults\n };\n }\n function interruptActiveLoads() {\n // Every interruption triggers a revalidation\n isRevalidationRequired = true;\n // Cancel pending route-level deferreds and mark cancelled routes for\n // revalidation\n cancelledDeferredRoutes.push(...cancelActiveDeferreds());\n // Abort in-flight fetcher loads\n fetchLoadMatches.forEach((_, key)=>{\n if (fetchControllers.has(key)) {\n cancelledFetcherLoads.push(key);\n abortFetcher(key);\n }\n });\n }\n function setFetcherError(key, routeId, error) {\n let boundaryMatch = findNearestBoundary(state.matches, routeId);\n deleteFetcher(key);\n updateState({\n errors: {\n [boundaryMatch.route.id]: error\n },\n fetchers: new Map(state.fetchers)\n });\n }\n function deleteFetcher(key) {\n let fetcher = state.fetchers.get(key);\n // Don't abort the controller if this is a deletion of a fetcher.submit()\n // in it's loading phase since - we don't want to abort the corresponding\n // revalidation and want them to complete and land\n if (fetchControllers.has(key) && !(fetcher && fetcher.state === \"loading\" && fetchReloadIds.has(key))) {\n abortFetcher(key);\n }\n fetchLoadMatches.delete(key);\n fetchReloadIds.delete(key);\n fetchRedirectIds.delete(key);\n state.fetchers.delete(key);\n }\n function abortFetcher(key) {\n let controller = fetchControllers.get(key);\n invariant(controller, \"Expected fetch controller: \" + key);\n controller.abort();\n fetchControllers.delete(key);\n }\n function markFetchersDone(keys) {\n for (let key of keys){\n let fetcher = getFetcher(key);\n let doneFetcher = getDoneFetcher(fetcher.data);\n state.fetchers.set(key, doneFetcher);\n }\n }\n function markFetchRedirectsDone() {\n let doneKeys = [];\n let updatedFetchers = false;\n for (let key of fetchRedirectIds){\n let fetcher = state.fetchers.get(key);\n invariant(fetcher, \"Expected fetcher: \" + key);\n if (fetcher.state === \"loading\") {\n fetchRedirectIds.delete(key);\n doneKeys.push(key);\n updatedFetchers = true;\n }\n }\n markFetchersDone(doneKeys);\n return updatedFetchers;\n }\n function abortStaleFetchLoads(landedId) {\n let yeetedKeys = [];\n for (let [key, id] of fetchReloadIds){\n if (id < landedId) {\n let fetcher = state.fetchers.get(key);\n invariant(fetcher, \"Expected fetcher: \" + key);\n if (fetcher.state === \"loading\") {\n abortFetcher(key);\n fetchReloadIds.delete(key);\n yeetedKeys.push(key);\n }\n }\n }\n markFetchersDone(yeetedKeys);\n return yeetedKeys.length > 0;\n }\n function getBlocker(key, fn) {\n let blocker = state.blockers.get(key) || IDLE_BLOCKER;\n if (blockerFunctions.get(key) !== fn) {\n blockerFunctions.set(key, fn);\n }\n return blocker;\n }\n function deleteBlocker(key) {\n state.blockers.delete(key);\n blockerFunctions.delete(key);\n }\n // Utility function to update blockers, ensuring valid state transitions\n function updateBlocker(key, newBlocker) {\n let blocker = state.blockers.get(key) || IDLE_BLOCKER;\n // Poor mans state machine :)\n // https://mermaid.live/edit#pako:eNqVkc9OwzAMxl8l8nnjAYrEtDIOHEBIgwvKJTReGy3_lDpIqO27k6awMG0XcrLlnz87nwdonESogKXXBuE79rq75XZO3-yHds0RJVuv70YrPlUrCEe2HfrORS3rubqZfuhtpg5C9wk5tZ4VKcRUq88q9Z8RS0-48cE1iHJkL0ugbHuFLus9L6spZy8nX9MP2CNdomVaposqu3fGayT8T8-jJQwhepo_UtpgBQaDEUom04dZhAN1aJBDlUKJBxE1ceB2Smj0Mln-IBW5AFU2dwUiktt_2Qaq2dBfaKdEup85UV7Yd-dKjlnkabl2Pvr0DTkTreM\n invariant(blocker.state === \"unblocked\" && newBlocker.state === \"blocked\" || blocker.state === \"blocked\" && newBlocker.state === \"blocked\" || blocker.state === \"blocked\" && newBlocker.state === \"proceeding\" || blocker.state === \"blocked\" && newBlocker.state === \"unblocked\" || blocker.state === \"proceeding\" && newBlocker.state === \"unblocked\", \"Invalid blocker state transition: \" + blocker.state + \" -> \" + newBlocker.state);\n let blockers = new Map(state.blockers);\n blockers.set(key, newBlocker);\n updateState({\n blockers\n });\n }\n function shouldBlockNavigation(_ref2) {\n let { currentLocation, nextLocation, historyAction } = _ref2;\n if (blockerFunctions.size === 0) {\n return;\n }\n // We ony support a single active blocker at the moment since we don't have\n // any compelling use cases for multi-blocker yet\n if (blockerFunctions.size > 1) {\n warning(false, \"A router only supports one blocker at a time\");\n }\n let entries = Array.from(blockerFunctions.entries());\n let [blockerKey, blockerFunction] = entries[entries.length - 1];\n let blocker = state.blockers.get(blockerKey);\n if (blocker && blocker.state === \"proceeding\") {\n // If the blocker is currently proceeding, we don't need to re-check\n // it and can let this navigation continue\n return;\n }\n // At this point, we know we're unblocked/blocked so we need to check the\n // user-provided blocker function\n if (blockerFunction({\n currentLocation,\n nextLocation,\n historyAction\n })) {\n return blockerKey;\n }\n }\n function cancelActiveDeferreds(predicate) {\n let cancelledRouteIds = [];\n activeDeferreds.forEach((dfd, routeId)=>{\n if (!predicate || predicate(routeId)) {\n // Cancel the deferred - but do not remove from activeDeferreds here -\n // we rely on the subscribers to do that so our tests can assert proper\n // cleanup via _internalActiveDeferreds\n dfd.cancel();\n cancelledRouteIds.push(routeId);\n activeDeferreds.delete(routeId);\n }\n });\n return cancelledRouteIds;\n }\n // Opt in to capturing and reporting scroll positions during navigations,\n // used by the <ScrollRestoration> component\n function enableScrollRestoration(positions, getPosition, getKey) {\n savedScrollPositions = positions;\n getScrollPosition = getPosition;\n getScrollRestorationKey = getKey || null;\n // Perform initial hydration scroll restoration, since we miss the boat on\n // the initial updateState() because we've not yet rendered <ScrollRestoration/>\n // and therefore have no savedScrollPositions available\n if (!initialScrollRestored && state.navigation === IDLE_NAVIGATION) {\n initialScrollRestored = true;\n let y = getSavedScrollPosition(state.location, state.matches);\n if (y != null) {\n updateState({\n restoreScrollPosition: y\n });\n }\n }\n return ()=>{\n savedScrollPositions = null;\n getScrollPosition = null;\n getScrollRestorationKey = null;\n };\n }\n function getScrollKey(location, matches) {\n if (getScrollRestorationKey) {\n let key = getScrollRestorationKey(location, matches.map((m)=>createUseMatchesMatch(m, state.loaderData)));\n return key || location.key;\n }\n return location.key;\n }\n function saveScrollPosition(location, matches) {\n if (savedScrollPositions && getScrollPosition) {\n let key = getScrollKey(location, matches);\n savedScrollPositions[key] = getScrollPosition();\n }\n }\n function getSavedScrollPosition(location, matches) {\n if (savedScrollPositions) {\n let key = getScrollKey(location, matches);\n let y = savedScrollPositions[key];\n if (typeof y === \"number\") {\n return y;\n }\n }\n return null;\n }\n function _internalSetRoutes(newRoutes) {\n manifest = {};\n inFlightDataRoutes = convertRoutesToDataRoutes(newRoutes, mapRouteProperties, undefined, manifest);\n }\n router = {\n get basename () {\n return basename;\n },\n get state () {\n return state;\n },\n get routes () {\n return dataRoutes;\n },\n initialize,\n subscribe,\n enableScrollRestoration,\n navigate,\n fetch,\n revalidate,\n // Passthrough to history-aware createHref used by useHref so we get proper\n // hash-aware URLs in DOM paths\n createHref: (to)=>init.history.createHref(to),\n encodeLocation: (to)=>init.history.encodeLocation(to),\n getFetcher,\n deleteFetcher,\n dispose,\n getBlocker,\n deleteBlocker,\n _internalFetchControllers: fetchControllers,\n _internalActiveDeferreds: activeDeferreds,\n // TODO: Remove setRoutes, it's temporary to avoid dealing with\n // updating the tree while validating the update algorithm.\n _internalSetRoutes\n };\n return router;\n}\n//#endregion\n////////////////////////////////////////////////////////////////////////////////\n//#region createStaticHandler\n////////////////////////////////////////////////////////////////////////////////\nconst UNSAFE_DEFERRED_SYMBOL = Symbol(\"deferred\");\nfunction createStaticHandler(routes, opts) {\n invariant(routes.length > 0, \"You must provide a non-empty routes array to createStaticHandler\");\n let manifest = {};\n let basename = (opts ? opts.basename : null) || \"/\";\n let mapRouteProperties;\n if (opts != null && opts.mapRouteProperties) {\n mapRouteProperties = opts.mapRouteProperties;\n } else if (opts != null && opts.detectErrorBoundary) {\n // If they are still using the deprecated version, wrap it with the new API\n let detectErrorBoundary = opts.detectErrorBoundary;\n mapRouteProperties = (route)=>({\n hasErrorBoundary: detectErrorBoundary(route)\n });\n } else {\n mapRouteProperties = defaultMapRouteProperties;\n }\n let dataRoutes = convertRoutesToDataRoutes(routes, mapRouteProperties, undefined, manifest);\n /**\n * The query() method is intended for document requests, in which we want to\n * call an optional action and potentially multiple loaders for all nested\n * routes. It returns a StaticHandlerContext object, which is very similar\n * to the router state (location, loaderData, actionData, errors, etc.) and\n * also adds SSR-specific information such as the statusCode and headers\n * from action/loaders Responses.\n *\n * It _should_ never throw and should report all errors through the\n * returned context.errors object, properly associating errors to their error\n * boundary. Additionally, it tracks _deepestRenderedBoundaryId which can be\n * used to emulate React error boundaries during SSr by performing a second\n * pass only down to the boundaryId.\n *\n * The one exception where we do not return a StaticHandlerContext is when a\n * redirect response is returned or thrown from any action/loader. We\n * propagate that out and return the raw Response so the HTTP server can\n * return it directly.\n */ async function query(request, _temp2) {\n let { requestContext } = _temp2 === void 0 ? {} : _temp2;\n let url = new URL(request.url);\n let method = request.method;\n let location = createLocation(\"\", createPath(url), null, \"default\");\n let matches = matchRoutes(dataRoutes, location, basename);\n // SSR supports HEAD requests while SPA doesn't\n if (!isValidMethod(method) && method !== \"HEAD\") {\n let error = getInternalRouterError(405, {\n method\n });\n let { matches: methodNotAllowedMatches, route } = getShortCircuitMatches(dataRoutes);\n return {\n basename,\n location,\n matches: methodNotAllowedMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null\n };\n } else if (!matches) {\n let error = getInternalRouterError(404, {\n pathname: location.pathname\n });\n let { matches: notFoundMatches, route } = getShortCircuitMatches(dataRoutes);\n return {\n basename,\n location,\n matches: notFoundMatches,\n loaderData: {},\n actionData: null,\n errors: {\n [route.id]: error\n },\n statusCode: error.status,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null\n };\n }\n let result = await queryImpl(request, location, matches, requestContext);\n if (isResponse(result)) {\n return result;\n }\n // When returning StaticHandlerContext, we patch back in the location here\n // since we need it for React Context. But this helps keep our submit and\n // loadRouteData operating on a Request instead of a Location\n return _extends({\n location,\n basename\n }, result);\n }\n /**\n * The queryRoute() method is intended for targeted route requests, either\n * for fetch ?_data requests or resource route requests. In this case, we\n * are only ever calling a single action or loader, and we are returning the\n * returned value directly. In most cases, this will be a Response returned\n * from the action/loader, but it may be a primitive or other value as well -\n * and in such cases the calling context should handle that accordingly.\n *\n * We do respect the throw/return differentiation, so if an action/loader\n * throws, then this method will throw the value. This is important so we\n * can do proper boundary identification in Remix where a thrown Response\n * must go to the Catch Boundary but a returned Response is happy-path.\n *\n * One thing to note is that any Router-initiated Errors that make sense\n * to associate with a status code will be thrown as an ErrorResponse\n * instance which include the raw Error, such that the calling context can\n * serialize the error as they see fit while including the proper response\n * code. Examples here are 404 and 405 errors that occur prior to reaching\n * any user-defined loaders.\n */ async function queryRoute(request, _temp3) {\n let { routeId, requestContext } = _temp3 === void 0 ? {} : _temp3;\n let url = new URL(request.url);\n let method = request.method;\n let location = createLocation(\"\", createPath(url), null, \"default\");\n let matches = matchRoutes(dataRoutes, location, basename);\n // SSR supports HEAD requests while SPA doesn't\n if (!isValidMethod(method) && method !== \"HEAD\" && method !== \"OPTIONS\") {\n throw getInternalRouterError(405, {\n method\n });\n } else if (!matches) {\n throw getInternalRouterError(404, {\n pathname: location.pathname\n });\n }\n let match = routeId ? matches.find((m)=>m.route.id === routeId) : getTargetMatch(matches, location);\n if (routeId && !match) {\n throw getInternalRouterError(403, {\n pathname: location.pathname,\n routeId\n });\n } else if (!match) {\n // This should never hit I don't think?\n throw getInternalRouterError(404, {\n pathname: location.pathname\n });\n }\n let result = await queryImpl(request, location, matches, requestContext, match);\n if (isResponse(result)) {\n return result;\n }\n let error = result.errors ? Object.values(result.errors)[0] : undefined;\n if (error !== undefined) {\n // If we got back result.errors, that means the loader/action threw\n // _something_ that wasn't a Response, but it's not guaranteed/required\n // to be an `instanceof Error` either, so we have to use throw here to\n // preserve the \"error\" state outside of queryImpl.\n throw error;\n }\n // Pick off the right state value to return\n if (result.actionData) {\n return Object.values(result.actionData)[0];\n }\n if (result.loaderData) {\n var _result$activeDeferre;\n let data = Object.values(result.loaderData)[0];\n if ((_result$activeDeferre = result.activeDeferreds) != null && _result$activeDeferre[match.route.id]) {\n data[UNSAFE_DEFERRED_SYMBOL] = result.activeDeferreds[match.route.id];\n }\n return data;\n }\n return undefined;\n }\n async function queryImpl(request, location, matches, requestContext, routeMatch) {\n invariant(request.signal, \"query()/queryRoute() requests must contain an AbortController signal\");\n try {\n if (isMutationMethod(request.method.toLowerCase())) {\n let result = await submit(request, matches, routeMatch || getTargetMatch(matches, location), requestContext, routeMatch != null);\n return result;\n }\n let result = await loadRouteData(request, matches, requestContext, routeMatch);\n return isResponse(result) ? result : _extends({}, result, {\n actionData: null,\n actionHeaders: {}\n });\n } catch (e) {\n // If the user threw/returned a Response in callLoaderOrAction, we throw\n // it to bail out and then return or throw here based on whether the user\n // returned or threw\n if (isQueryRouteResponse(e)) {\n if (e.type === ResultType.error) {\n throw e.response;\n }\n return e.response;\n }\n // Redirects are always returned since they don't propagate to catch\n // boundaries\n if (isRedirectResponse(e)) {\n return e;\n }\n throw e;\n }\n }\n async function submit(request, matches, actionMatch, requestContext, isRouteRequest) {\n let result;\n if (!actionMatch.route.action && !actionMatch.route.lazy) {\n let error = getInternalRouterError(405, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: actionMatch.route.id\n });\n if (isRouteRequest) {\n throw error;\n }\n result = {\n type: ResultType.error,\n error\n };\n } else {\n result = await callLoaderOrAction(\"action\", request, actionMatch, matches, manifest, mapRouteProperties, basename, {\n isStaticRequest: true,\n isRouteRequest,\n requestContext\n });\n if (request.signal.aborted) {\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(method + \"() call aborted\");\n }\n }\n if (isRedirectResult(result)) {\n // Uhhhh - this should never happen, we should always throw these from\n // callLoaderOrAction, but the type narrowing here keeps TS happy and we\n // can get back on the \"throw all redirect responses\" train here should\n // this ever happen :/\n throw new Response(null, {\n status: result.status,\n headers: {\n Location: result.location\n }\n });\n }\n if (isDeferredResult(result)) {\n let error = getInternalRouterError(400, {\n type: \"defer-action\"\n });\n if (isRouteRequest) {\n throw error;\n }\n result = {\n type: ResultType.error,\n error\n };\n }\n if (isRouteRequest) {\n // Note: This should only be non-Response values if we get here, since\n // isRouteRequest should throw any Response received in callLoaderOrAction\n if (isErrorResult(result)) {\n throw result.error;\n }\n return {\n matches: [\n actionMatch\n ],\n loaderData: {},\n actionData: {\n [actionMatch.route.id]: result.data\n },\n errors: null,\n // Note: statusCode + headers are unused here since queryRoute will\n // return the raw Response or value\n statusCode: 200,\n loaderHeaders: {},\n actionHeaders: {},\n activeDeferreds: null\n };\n }\n if (isErrorResult(result)) {\n // Store off the pending error - we use it to determine which loaders\n // to call and will commit it when we complete the navigation\n let boundaryMatch = findNearestBoundary(matches, actionMatch.route.id);\n let context = await loadRouteData(request, matches, requestContext, undefined, {\n [boundaryMatch.route.id]: result.error\n });\n // action status codes take precedence over loader status codes\n return _extends({}, context, {\n statusCode: isRouteErrorResponse(result.error) ? result.error.status : 500,\n actionData: null,\n actionHeaders: _extends({}, result.headers ? {\n [actionMatch.route.id]: result.headers\n } : {})\n });\n }\n // Create a GET request for the loaders\n let loaderRequest = new Request(request.url, {\n headers: request.headers,\n redirect: request.redirect,\n signal: request.signal\n });\n let context = await loadRouteData(loaderRequest, matches, requestContext);\n return _extends({}, context, result.statusCode ? {\n statusCode: result.statusCode\n } : {}, {\n actionData: {\n [actionMatch.route.id]: result.data\n },\n actionHeaders: _extends({}, result.headers ? {\n [actionMatch.route.id]: result.headers\n } : {})\n });\n }\n async function loadRouteData(request, matches, requestContext, routeMatch, pendingActionError) {\n let isRouteRequest = routeMatch != null;\n // Short circuit if we have no loaders to run (queryRoute())\n if (isRouteRequest && !(routeMatch != null && routeMatch.route.loader) && !(routeMatch != null && routeMatch.route.lazy)) {\n throw getInternalRouterError(400, {\n method: request.method,\n pathname: new URL(request.url).pathname,\n routeId: routeMatch == null ? void 0 : routeMatch.route.id\n });\n }\n let requestMatches = routeMatch ? [\n routeMatch\n ] : getLoaderMatchesUntilBoundary(matches, Object.keys(pendingActionError || {})[0]);\n let matchesToLoad = requestMatches.filter((m)=>m.route.loader || m.route.lazy);\n // Short circuit if we have no loaders to run (query())\n if (matchesToLoad.length === 0) {\n return {\n matches,\n // Add a null for all matched routes for proper revalidation on the client\n loaderData: matches.reduce((acc, m)=>Object.assign(acc, {\n [m.route.id]: null\n }), {}),\n errors: pendingActionError || null,\n statusCode: 200,\n loaderHeaders: {},\n activeDeferreds: null\n };\n }\n let results = await Promise.all([\n ...matchesToLoad.map((match)=>callLoaderOrAction(\"loader\", request, match, matches, manifest, mapRouteProperties, basename, {\n isStaticRequest: true,\n isRouteRequest,\n requestContext\n }))\n ]);\n if (request.signal.aborted) {\n let method = isRouteRequest ? \"queryRoute\" : \"query\";\n throw new Error(method + \"() call aborted\");\n }\n // Process and commit output from loaders\n let activeDeferreds = new Map();\n let context = processRouteLoaderData(matches, matchesToLoad, results, pendingActionError, activeDeferreds);\n // Add a null for any non-loader matches for proper revalidation on the client\n let executedLoaders = new Set(matchesToLoad.map((match)=>match.route.id));\n matches.forEach((match)=>{\n if (!executedLoaders.has(match.route.id)) {\n context.loaderData[match.route.id] = null;\n }\n });\n return _extends({}, context, {\n matches,\n activeDeferreds: activeDeferreds.size > 0 ? Object.fromEntries(activeDeferreds.entries()) : null\n });\n }\n return {\n dataRoutes,\n query,\n queryRoute\n };\n}\n//#endregion\n////////////////////////////////////////////////////////////////////////////////\n//#region Helpers\n////////////////////////////////////////////////////////////////////////////////\n/**\n * Given an existing StaticHandlerContext and an error thrown at render time,\n * provide an updated StaticHandlerContext suitable for a second SSR render\n */ function getStaticContextFromError(routes, context, error) {\n let newContext = _extends({}, context, {\n statusCode: 500,\n errors: {\n [context._deepestRenderedBoundaryId || routes[0].id]: error\n }\n });\n return newContext;\n}\nfunction isSubmissionNavigation(opts) {\n return opts != null && (\"formData\" in opts && opts.formData != null || \"body\" in opts && opts.body !== undefined);\n}\nfunction normalizeTo(location, matches, basename, prependBasename, to, fromRouteId, relative) {\n let contextualMatches;\n let activeRouteMatch;\n if (fromRouteId != null && relative !== \"path\") {\n // Grab matches up to the calling route so our route-relative logic is\n // relative to the correct source route. When using relative:path,\n // fromRouteId is ignored since that is always relative to the current\n // location path\n contextualMatches = [];\n for (let match of matches){\n contextualMatches.push(match);\n if (match.route.id === fromRouteId) {\n activeRouteMatch = match;\n break;\n }\n }\n } else {\n contextualMatches = matches;\n activeRouteMatch = matches[matches.length - 1];\n }\n // Resolve the relative path\n let path = resolveTo(to ? to : \".\", getPathContributingMatches(contextualMatches).map((m)=>m.pathnameBase), stripBasename(location.pathname, basename) || location.pathname, relative === \"path\");\n // When `to` is not specified we inherit search/hash from the current\n // location, unlike when to=\".\" and we just inherit the path.\n // See https://github.com/remix-run/remix/issues/927\n if (to == null) {\n path.search = location.search;\n path.hash = location.hash;\n }\n // Add an ?index param for matched index routes if we don't already have one\n if ((to == null || to === \"\" || to === \".\") && activeRouteMatch && activeRouteMatch.route.index && !hasNakedIndexQuery(path.search)) {\n path.search = path.search ? path.search.replace(/^\\?/, \"?index&\") : \"?index\";\n }\n // If we're operating within a basename, prepend it to the pathname. If\n // this is a root navigation, then just use the raw basename which allows\n // the basename to have full control over the presence of a trailing slash\n // on root actions\n if (prependBasename && basename !== \"/\") {\n path.pathname = path.pathname === \"/\" ? basename : joinPaths([\n basename,\n path.pathname\n ]);\n }\n return createPath(path);\n}\n// Normalize navigation options by converting formMethod=GET formData objects to\n// URLSearchParams so they behave identically to links with query params\nfunction normalizeNavigateOptions(normalizeFormMethod, isFetcher, path, opts) {\n // Return location verbatim on non-submission navigations\n if (!opts || !isSubmissionNavigation(opts)) {\n return {\n path\n };\n }\n if (opts.formMethod && !isValidMethod(opts.formMethod)) {\n return {\n path,\n error: getInternalRouterError(405, {\n method: opts.formMethod\n })\n };\n }\n let getInvalidBodyError = ()=>({\n path,\n error: getInternalRouterError(400, {\n type: \"invalid-body\"\n })\n });\n // Create a Submission on non-GET navigations\n let rawFormMethod = opts.formMethod || \"get\";\n let formMethod = normalizeFormMethod ? rawFormMethod.toUpperCase() : rawFormMethod.toLowerCase();\n let formAction = stripHashFromPath(path);\n if (opts.body !== undefined) {\n if (opts.formEncType === \"text/plain\") {\n // text only support POST/PUT/PATCH/DELETE submissions\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n let text = typeof opts.body === \"string\" ? opts.body : opts.body instanceof FormData || opts.body instanceof URLSearchParams ? // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#plain-text-form-data\n Array.from(opts.body.entries()).reduce((acc, _ref3)=>{\n let [name, value] = _ref3;\n return \"\" + acc + name + \"=\" + value + \"\\n\";\n }, \"\") : String(opts.body);\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: undefined,\n json: undefined,\n text\n }\n };\n } else if (opts.formEncType === \"application/json\") {\n // json only supports POST/PUT/PATCH/DELETE submissions\n if (!isMutationMethod(formMethod)) {\n return getInvalidBodyError();\n }\n try {\n let json = typeof opts.body === \"string\" ? JSON.parse(opts.body) : opts.body;\n return {\n path,\n submission: {\n formMethod,\n formAction,\n formEncType: opts.formEncType,\n formData: undefined,\n json,\n text: undefined\n }\n };\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n }\n invariant(typeof FormData === \"function\", \"FormData is not available in this environment\");\n let searchParams;\n let formData;\n if (opts.formData) {\n searchParams = convertFormDataToSearchParams(opts.formData);\n formData = opts.formData;\n } else if (opts.body instanceof FormData) {\n searchParams = convertFormDataToSearchParams(opts.body);\n formData = opts.body;\n } else if (opts.body instanceof URLSearchParams) {\n searchParams = opts.body;\n formData = convertSearchParamsToFormData(searchParams);\n } else if (opts.body == null) {\n searchParams = new URLSearchParams();\n formData = new FormData();\n } else {\n try {\n searchParams = new URLSearchParams(opts.body);\n formData = convertSearchParamsToFormData(searchParams);\n } catch (e) {\n return getInvalidBodyError();\n }\n }\n let submission = {\n formMethod,\n formAction,\n formEncType: opts && opts.formEncType || \"application/x-www-form-urlencoded\",\n formData,\n json: undefined,\n text: undefined\n };\n if (isMutationMethod(submission.formMethod)) {\n return {\n path,\n submission\n };\n }\n // Flatten submission onto URLSearchParams for GET submissions\n let parsedPath = parsePath(path);\n // On GET navigation submissions we can drop the ?index param from the\n // resulting location since all loaders will run. But fetcher GET submissions\n // only run a single loader so we need to preserve any incoming ?index params\n if (isFetcher && parsedPath.search && hasNakedIndexQuery(parsedPath.search)) {\n searchParams.append(\"index\", \"\");\n }\n parsedPath.search = \"?\" + searchParams;\n return {\n path: createPath(parsedPath),\n submission\n };\n}\n// Filter out all routes below any caught error as they aren't going to\n// render so we don't need to load them\nfunction getLoaderMatchesUntilBoundary(matches, boundaryId) {\n let boundaryMatches = matches;\n if (boundaryId) {\n let index = matches.findIndex((m)=>m.route.id === boundaryId);\n if (index >= 0) {\n boundaryMatches = matches.slice(0, index);\n }\n }\n return boundaryMatches;\n}\nfunction getMatchesToLoad(history, state, matches, submission, location, isRevalidationRequired, cancelledDeferredRoutes, cancelledFetcherLoads, fetchLoadMatches, fetchRedirectIds, routesToUse, basename, pendingActionData, pendingError) {\n let actionResult = pendingError ? Object.values(pendingError)[0] : pendingActionData ? Object.values(pendingActionData)[0] : undefined;\n let currentUrl = history.createURL(state.location);\n let nextUrl = history.createURL(location);\n // Pick navigation matches that are net-new or qualify for revalidation\n let boundaryId = pendingError ? Object.keys(pendingError)[0] : undefined;\n let boundaryMatches = getLoaderMatchesUntilBoundary(matches, boundaryId);\n let navigationMatches = boundaryMatches.filter((match, index)=>{\n if (match.route.lazy) {\n // We haven't loaded this route yet so we don't know if it's got a loader!\n return true;\n }\n if (match.route.loader == null) {\n return false;\n }\n // Always call the loader on new route instances and pending defer cancellations\n if (isNewLoader(state.loaderData, state.matches[index], match) || cancelledDeferredRoutes.some((id)=>id === match.route.id)) {\n return true;\n }\n // This is the default implementation for when we revalidate. If the route\n // provides it's own implementation, then we give them full control but\n // provide this value so they can leverage it if needed after they check\n // their own specific use cases\n let currentRouteMatch = state.matches[index];\n let nextRouteMatch = match;\n return shouldRevalidateLoader(match, _extends({\n currentUrl,\n currentParams: currentRouteMatch.params,\n nextUrl,\n nextParams: nextRouteMatch.params\n }, submission, {\n actionResult,\n defaultShouldRevalidate: // Forced revalidation due to submission, useRevalidator, or X-Remix-Revalidate\n isRevalidationRequired || // Clicked the same link, resubmitted a GET form\n currentUrl.pathname + currentUrl.search === nextUrl.pathname + nextUrl.search || // Search params affect all loaders\n currentUrl.search !== nextUrl.search || isNewRouteInstance(currentRouteMatch, nextRouteMatch)\n }));\n });\n // Pick fetcher.loads that need to be revalidated\n let revalidatingFetchers = [];\n fetchLoadMatches.forEach((f, key)=>{\n // Don't revalidate if fetcher won't be present in the subsequent render\n if (!matches.some((m)=>m.route.id === f.routeId)) {\n return;\n }\n let fetcherMatches = matchRoutes(routesToUse, f.path, basename);\n // If the fetcher path no longer matches, push it in with null matches so\n // we can trigger a 404 in callLoadersAndMaybeResolveData. Note this is\n // currently only a use-case for Remix HMR where the route tree can change\n // at runtime and remove a route previously loaded via a fetcher\n if (!fetcherMatches) {\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: null,\n match: null,\n controller: null\n });\n return;\n }\n // Revalidating fetchers are decoupled from the route matches since they\n // load from a static href. They revalidate based on explicit revalidation\n // (submission, useRevalidator, or X-Remix-Revalidate)\n let fetcher = state.fetchers.get(key);\n let fetcherMatch = getTargetMatch(fetcherMatches, f.path);\n let shouldRevalidate = false;\n if (fetchRedirectIds.has(key)) {\n // Never trigger a revalidation of an actively redirecting fetcher\n shouldRevalidate = false;\n } else if (cancelledFetcherLoads.includes(key)) {\n // Always revalidate if the fetcher was cancelled\n shouldRevalidate = true;\n } else if (fetcher && fetcher.state !== \"idle\" && fetcher.data === undefined) {\n // If the fetcher hasn't ever completed loading yet, then this isn't a\n // revalidation, it would just be a brand new load if an explicit\n // revalidation is required\n shouldRevalidate = isRevalidationRequired;\n } else {\n // Otherwise fall back on any user-defined shouldRevalidate, defaulting\n // to explicit revalidations only\n shouldRevalidate = shouldRevalidateLoader(fetcherMatch, _extends({\n currentUrl,\n currentParams: state.matches[state.matches.length - 1].params,\n nextUrl,\n nextParams: matches[matches.length - 1].params\n }, submission, {\n actionResult,\n defaultShouldRevalidate: isRevalidationRequired\n }));\n }\n if (shouldRevalidate) {\n revalidatingFetchers.push({\n key,\n routeId: f.routeId,\n path: f.path,\n matches: fetcherMatches,\n match: fetcherMatch,\n controller: new AbortController()\n });\n }\n });\n return [\n navigationMatches,\n revalidatingFetchers\n ];\n}\nfunction isNewLoader(currentLoaderData, currentMatch, match) {\n let isNew = // [a] -> [a, b]\n !currentMatch || // [a, b] -> [a, c]\n match.route.id !== currentMatch.route.id;\n // Handle the case that we don't have data for a re-used route, potentially\n // from a prior error or from a cancelled pending deferred\n let isMissingData = currentLoaderData[match.route.id] === undefined;\n // Always load if this is a net-new route or we don't yet have data\n return isNew || isMissingData;\n}\nfunction isNewRouteInstance(currentMatch, match) {\n let currentPath = currentMatch.route.path;\n return(// param change for this match, /users/123 -> /users/456\n currentMatch.pathname !== match.pathname || // splat param changed, which is not present in match.path\n // e.g. /files/images/avatar.jpg -> files/finances.xls\n currentPath != null && currentPath.endsWith(\"*\") && currentMatch.params[\"*\"] !== match.params[\"*\"]);\n}\nfunction shouldRevalidateLoader(loaderMatch, arg) {\n if (loaderMatch.route.shouldRevalidate) {\n let routeChoice = loaderMatch.route.shouldRevalidate(arg);\n if (typeof routeChoice === \"boolean\") {\n return routeChoice;\n }\n }\n return arg.defaultShouldRevalidate;\n}\n/**\n * Execute route.lazy() methods to lazily load route modules (loader, action,\n * shouldRevalidate) and update the routeManifest in place which shares objects\n * with dataRoutes so those get updated as well.\n */ async function loadLazyRouteModule(route, mapRouteProperties, manifest) {\n if (!route.lazy) {\n return;\n }\n let lazyRoute = await route.lazy();\n // If the lazy route function was executed and removed by another parallel\n // call then we can return - first lazy() to finish wins because the return\n // value of lazy is expected to be static\n if (!route.lazy) {\n return;\n }\n let routeToUpdate = manifest[route.id];\n invariant(routeToUpdate, \"No route found in manifest\");\n // Update the route in place. This should be safe because there's no way\n // we could yet be sitting on this route as we can't get there without\n // resolving lazy() first.\n //\n // This is different than the HMR \"update\" use-case where we may actively be\n // on the route being updated. The main concern boils down to \"does this\n // mutation affect any ongoing navigations or any current state.matches\n // values?\". If not, it should be safe to update in place.\n let routeUpdates = {};\n for(let lazyRouteProperty in lazyRoute){\n let staticRouteValue = routeToUpdate[lazyRouteProperty];\n let isPropertyStaticallyDefined = staticRouteValue !== undefined && // This property isn't static since it should always be updated based\n // on the route updates\n lazyRouteProperty !== \"hasErrorBoundary\";\n warning(!isPropertyStaticallyDefined, 'Route \"' + routeToUpdate.id + '\" has a static property \"' + lazyRouteProperty + '\" ' + \"defined but its lazy function is also returning a value for this property. \" + ('The lazy route property \"' + lazyRouteProperty + '\" will be ignored.'));\n if (!isPropertyStaticallyDefined && !immutableRouteKeys.has(lazyRouteProperty)) {\n routeUpdates[lazyRouteProperty] = lazyRoute[lazyRouteProperty];\n }\n }\n // Mutate the route with the provided updates. Do this first so we pass\n // the updated version to mapRouteProperties\n Object.assign(routeToUpdate, routeUpdates);\n // Mutate the `hasErrorBoundary` property on the route based on the route\n // updates and remove the `lazy` function so we don't resolve the lazy\n // route again.\n Object.assign(routeToUpdate, _extends({}, mapRouteProperties(routeToUpdate), {\n lazy: undefined\n }));\n}\nasync function callLoaderOrAction(type, request, match, matches, manifest, mapRouteProperties, basename, opts) {\n if (opts === void 0) {\n opts = {};\n }\n let resultType;\n let result;\n let onReject;\n let runHandler = (handler)=>{\n // Setup a promise we can race against so that abort signals short circuit\n let reject;\n let abortPromise = new Promise((_, r)=>reject = r);\n onReject = ()=>reject();\n request.signal.addEventListener(\"abort\", onReject);\n return Promise.race([\n handler({\n request,\n params: match.params,\n context: opts.requestContext\n }),\n abortPromise\n ]);\n };\n try {\n let handler = match.route[type];\n if (match.route.lazy) {\n if (handler) {\n // Run statically defined handler in parallel with lazy()\n let values = await Promise.all([\n runHandler(handler),\n loadLazyRouteModule(match.route, mapRouteProperties, manifest)\n ]);\n result = values[0];\n } else {\n // Load lazy route module, then run any returned handler\n await loadLazyRouteModule(match.route, mapRouteProperties, manifest);\n handler = match.route[type];\n if (handler) {\n // Handler still run even if we got interrupted to maintain consistency\n // with un-abortable behavior of handler execution on non-lazy or\n // previously-lazy-loaded routes\n result = await runHandler(handler);\n } else if (type === \"action\") {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(405, {\n method: request.method,\n pathname,\n routeId: match.route.id\n });\n } else {\n // lazy() route has no loader to run. Short circuit here so we don't\n // hit the invariant below that errors on returning undefined.\n return {\n type: ResultType.data,\n data: undefined\n };\n }\n }\n } else if (!handler) {\n let url = new URL(request.url);\n let pathname = url.pathname + url.search;\n throw getInternalRouterError(404, {\n pathname\n });\n } else {\n result = await runHandler(handler);\n }\n invariant(result !== undefined, \"You defined \" + (type === \"action\" ? \"an action\" : \"a loader\") + \" for route \" + ('\"' + match.route.id + \"\\\" but didn't return anything from your `\" + type + \"` \") + \"function. Please return a value or `null`.\");\n } catch (e) {\n resultType = ResultType.error;\n result = e;\n } finally{\n if (onReject) {\n request.signal.removeEventListener(\"abort\", onReject);\n }\n }\n if (isResponse(result)) {\n let status = result.status;\n // Process redirects\n if (redirectStatusCodes.has(status)) {\n let location = result.headers.get(\"Location\");\n invariant(location, \"Redirects returned/thrown from loaders/actions must have a Location header\");\n // Support relative routing in internal redirects\n if (!ABSOLUTE_URL_REGEX.test(location)) {\n location = normalizeTo(new URL(request.url), matches.slice(0, matches.indexOf(match) + 1), basename, true, location);\n } else if (!opts.isStaticRequest) {\n // Strip off the protocol+origin for same-origin + same-basename absolute\n // redirects. If this is a static request, we can let it go back to the\n // browser as-is\n let currentUrl = new URL(request.url);\n let url = location.startsWith(\"//\") ? new URL(currentUrl.protocol + location) : new URL(location);\n let isSameBasename = stripBasename(url.pathname, basename) != null;\n if (url.origin === currentUrl.origin && isSameBasename) {\n location = url.pathname + url.search + url.hash;\n }\n }\n // Don't process redirects in the router during static requests requests.\n // Instead, throw the Response and let the server handle it with an HTTP\n // redirect. We also update the Location header in place in this flow so\n // basename and relative routing is taken into account\n if (opts.isStaticRequest) {\n result.headers.set(\"Location\", location);\n throw result;\n }\n return {\n type: ResultType.redirect,\n status,\n location,\n revalidate: result.headers.get(\"X-Remix-Revalidate\") !== null,\n reloadDocument: result.headers.get(\"X-Remix-Reload-Document\") !== null\n };\n }\n // For SSR single-route requests, we want to hand Responses back directly\n // without unwrapping. We do this with the QueryRouteResponse wrapper\n // interface so we can know whether it was returned or thrown\n if (opts.isRouteRequest) {\n let queryRouteResponse = {\n type: resultType === ResultType.error ? ResultType.error : ResultType.data,\n response: result\n };\n throw queryRouteResponse;\n }\n let data;\n let contentType = result.headers.get(\"Content-Type\");\n // Check between word boundaries instead of startsWith() due to the last\n // paragraph of https://httpwg.org/specs/rfc9110.html#field.content-type\n if (contentType && /\\bapplication\\/json\\b/.test(contentType)) {\n data = await result.json();\n } else {\n data = await result.text();\n }\n if (resultType === ResultType.error) {\n return {\n type: resultType,\n error: new ErrorResponse(status, result.statusText, data),\n headers: result.headers\n };\n }\n return {\n type: ResultType.data,\n data,\n statusCode: result.status,\n headers: result.headers\n };\n }\n if (resultType === ResultType.error) {\n return {\n type: resultType,\n error: result\n };\n }\n if (isDeferredData(result)) {\n var _result$init, _result$init2;\n return {\n type: ResultType.deferred,\n deferredData: result,\n statusCode: (_result$init = result.init) == null ? void 0 : _result$init.status,\n headers: ((_result$init2 = result.init) == null ? void 0 : _result$init2.headers) && new Headers(result.init.headers)\n };\n }\n return {\n type: ResultType.data,\n data: result\n };\n}\n// Utility method for creating the Request instances for loaders/actions during\n// client-side navigations and fetches. During SSR we will always have a\n// Request instance from the static handler (query/queryRoute)\nfunction createClientSideRequest(history, location, signal, submission) {\n let url = history.createURL(stripHashFromPath(location)).toString();\n let init = {\n signal\n };\n if (submission && isMutationMethod(submission.formMethod)) {\n let { formMethod, formEncType } = submission;\n // Didn't think we needed this but it turns out unlike other methods, patch\n // won't be properly normalized to uppercase and results in a 405 error.\n // See: https://fetch.spec.whatwg.org/#concept-method\n init.method = formMethod.toUpperCase();\n if (formEncType === \"application/json\") {\n init.headers = new Headers({\n \"Content-Type\": formEncType\n });\n init.body = JSON.stringify(submission.json);\n } else if (formEncType === \"text/plain\") {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = submission.text;\n } else if (formEncType === \"application/x-www-form-urlencoded\" && submission.formData) {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = convertFormDataToSearchParams(submission.formData);\n } else {\n // Content-Type is inferred (https://fetch.spec.whatwg.org/#dom-request)\n init.body = submission.formData;\n }\n }\n return new Request(url, init);\n}\nfunction convertFormDataToSearchParams(formData) {\n let searchParams = new URLSearchParams();\n for (let [key, value] of formData.entries()){\n // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#converting-an-entry-list-to-a-list-of-name-value-pairs\n searchParams.append(key, typeof value === \"string\" ? value : value.name);\n }\n return searchParams;\n}\nfunction convertSearchParamsToFormData(searchParams) {\n let formData = new FormData();\n for (let [key, value] of searchParams.entries()){\n formData.append(key, value);\n }\n return formData;\n}\nfunction processRouteLoaderData(matches, matchesToLoad, results, pendingError, activeDeferreds) {\n // Fill in loaderData/errors from our loaders\n let loaderData = {};\n let errors = null;\n let statusCode;\n let foundError = false;\n let loaderHeaders = {};\n // Process loader results into state.loaderData/state.errors\n results.forEach((result, index)=>{\n let id = matchesToLoad[index].route.id;\n invariant(!isRedirectResult(result), \"Cannot handle redirect results in processLoaderData\");\n if (isErrorResult(result)) {\n // Look upwards from the matched route for the closest ancestor\n // error boundary, defaulting to the root match\n let boundaryMatch = findNearestBoundary(matches, id);\n let error = result.error;\n // If we have a pending action error, we report it at the highest-route\n // that throws a loader error, and then clear it out to indicate that\n // it was consumed\n if (pendingError) {\n error = Object.values(pendingError)[0];\n pendingError = undefined;\n }\n errors = errors || {};\n // Prefer higher error values if lower errors bubble to the same boundary\n if (errors[boundaryMatch.route.id] == null) {\n errors[boundaryMatch.route.id] = error;\n }\n // Clear our any prior loaderData for the throwing route\n loaderData[id] = undefined;\n // Once we find our first (highest) error, we set the status code and\n // prevent deeper status codes from overriding\n if (!foundError) {\n foundError = true;\n statusCode = isRouteErrorResponse(result.error) ? result.error.status : 500;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n } else {\n if (isDeferredResult(result)) {\n activeDeferreds.set(id, result.deferredData);\n loaderData[id] = result.deferredData.data;\n } else {\n loaderData[id] = result.data;\n }\n // Error status codes always override success status codes, but if all\n // loaders are successful we take the deepest status code.\n if (result.statusCode != null && result.statusCode !== 200 && !foundError) {\n statusCode = result.statusCode;\n }\n if (result.headers) {\n loaderHeaders[id] = result.headers;\n }\n }\n });\n // If we didn't consume the pending action error (i.e., all loaders\n // resolved), then consume it here. Also clear out any loaderData for the\n // throwing route\n if (pendingError) {\n errors = pendingError;\n loaderData[Object.keys(pendingError)[0]] = undefined;\n }\n return {\n loaderData,\n errors,\n statusCode: statusCode || 200,\n loaderHeaders\n };\n}\nfunction processLoaderData(state, matches, matchesToLoad, results, pendingError, revalidatingFetchers, fetcherResults, activeDeferreds) {\n let { loaderData, errors } = processRouteLoaderData(matches, matchesToLoad, results, pendingError, activeDeferreds);\n // Process results from our revalidating fetchers\n for(let index = 0; index < revalidatingFetchers.length; index++){\n let { key, match, controller } = revalidatingFetchers[index];\n invariant(fetcherResults !== undefined && fetcherResults[index] !== undefined, \"Did not find corresponding fetcher result\");\n let result = fetcherResults[index];\n // Process fetcher non-redirect errors\n if (controller && controller.signal.aborted) {\n continue;\n } else if (isErrorResult(result)) {\n let boundaryMatch = findNearestBoundary(state.matches, match == null ? void 0 : match.route.id);\n if (!(errors && errors[boundaryMatch.route.id])) {\n errors = _extends({}, errors, {\n [boundaryMatch.route.id]: result.error\n });\n }\n state.fetchers.delete(key);\n } else if (isRedirectResult(result)) {\n // Should never get here, redirects should get processed above, but we\n // keep this to type narrow to a success result in the else\n invariant(false, \"Unhandled fetcher revalidation redirect\");\n } else if (isDeferredResult(result)) {\n // Should never get here, deferred data should be awaited for fetchers\n // in resolveDeferredResults\n invariant(false, \"Unhandled fetcher deferred data\");\n } else {\n let doneFetcher = getDoneFetcher(result.data);\n state.fetchers.set(key, doneFetcher);\n }\n }\n return {\n loaderData,\n errors\n };\n}\nfunction mergeLoaderData(loaderData, newLoaderData, matches, errors) {\n let mergedLoaderData = _extends({}, newLoaderData);\n for (let match of matches){\n let id = match.route.id;\n if (newLoaderData.hasOwnProperty(id)) {\n if (newLoaderData[id] !== undefined) {\n mergedLoaderData[id] = newLoaderData[id];\n }\n } else if (loaderData[id] !== undefined && match.route.loader) {\n // Preserve existing keys not included in newLoaderData and where a loader\n // wasn't removed by HMR\n mergedLoaderData[id] = loaderData[id];\n }\n if (errors && errors.hasOwnProperty(id)) {\n break;\n }\n }\n return mergedLoaderData;\n}\n// Find the nearest error boundary, looking upwards from the leaf route (or the\n// route specified by routeId) for the closest ancestor error boundary,\n// defaulting to the root match\nfunction findNearestBoundary(matches, routeId) {\n let eligibleMatches = routeId ? matches.slice(0, matches.findIndex((m)=>m.route.id === routeId) + 1) : [\n ...matches\n ];\n return eligibleMatches.reverse().find((m)=>m.route.hasErrorBoundary === true) || matches[0];\n}\nfunction getShortCircuitMatches(routes) {\n // Prefer a root layout route if present, otherwise shim in a route object\n let route = routes.find((r)=>r.index || !r.path || r.path === \"/\") || {\n id: \"__shim-error-route__\"\n };\n return {\n matches: [\n {\n params: {},\n pathname: \"\",\n pathnameBase: \"\",\n route\n }\n ],\n route\n };\n}\nfunction getInternalRouterError(status, _temp4) {\n let { pathname, routeId, method, type } = _temp4 === void 0 ? {} : _temp4;\n let statusText = \"Unknown Server Error\";\n let errorMessage = \"Unknown @remix-run/router error\";\n if (status === 400) {\n statusText = \"Bad Request\";\n if (method && pathname && routeId) {\n errorMessage = \"You made a \" + method + ' request to \"' + pathname + '\" but ' + ('did not provide a `loader` for route \"' + routeId + '\", ') + \"so there is no way to handle the request.\";\n } else if (type === \"defer-action\") {\n errorMessage = \"defer() is not supported in actions\";\n } else if (type === \"invalid-body\") {\n errorMessage = \"Unable to encode submission body\";\n }\n } else if (status === 403) {\n statusText = \"Forbidden\";\n errorMessage = 'Route \"' + routeId + '\" does not match URL \"' + pathname + '\"';\n } else if (status === 404) {\n statusText = \"Not Found\";\n errorMessage = 'No route matches URL \"' + pathname + '\"';\n } else if (status === 405) {\n statusText = \"Method Not Allowed\";\n if (method && pathname && routeId) {\n errorMessage = \"You made a \" + method.toUpperCase() + ' request to \"' + pathname + '\" but ' + ('did not provide an `action` for route \"' + routeId + '\", ') + \"so there is no way to handle the request.\";\n } else if (method) {\n errorMessage = 'Invalid request method \"' + method.toUpperCase() + '\"';\n }\n }\n return new ErrorResponse(status || 500, statusText, new Error(errorMessage), true);\n}\n// Find any returned redirect errors, starting from the lowest match\nfunction findRedirect(results) {\n for(let i = results.length - 1; i >= 0; i--){\n let result = results[i];\n if (isRedirectResult(result)) {\n return {\n result,\n idx: i\n };\n }\n }\n}\nfunction stripHashFromPath(path) {\n let parsedPath = typeof path === \"string\" ? parsePath(path) : path;\n return createPath(_extends({}, parsedPath, {\n hash: \"\"\n }));\n}\nfunction isHashChangeOnly(a, b) {\n if (a.pathname !== b.pathname || a.search !== b.search) {\n return false;\n }\n if (a.hash === \"\") {\n // /page -> /page#hash\n return b.hash !== \"\";\n } else if (a.hash === b.hash) {\n // /page#hash -> /page#hash\n return true;\n } else if (b.hash !== \"\") {\n // /page#hash -> /page#other\n return true;\n }\n // If the hash is removed the browser will re-perform a request to the server\n // /page#hash -> /page\n return false;\n}\nfunction isDeferredResult(result) {\n return result.type === ResultType.deferred;\n}\nfunction isErrorResult(result) {\n return result.type === ResultType.error;\n}\nfunction isRedirectResult(result) {\n return (result && result.type) === ResultType.redirect;\n}\nfunction isDeferredData(value) {\n let deferred = value;\n return deferred && typeof deferred === \"object\" && typeof deferred.data === \"object\" && typeof deferred.subscribe === \"function\" && typeof deferred.cancel === \"function\" && typeof deferred.resolveData === \"function\";\n}\nfunction isResponse(value) {\n return value != null && typeof value.status === \"number\" && typeof value.statusText === \"string\" && typeof value.headers === \"object\" && typeof value.body !== \"undefined\";\n}\nfunction isRedirectResponse(result) {\n if (!isResponse(result)) {\n return false;\n }\n let status = result.status;\n let location = result.headers.get(\"Location\");\n return status >= 300 && status <= 399 && location != null;\n}\nfunction isQueryRouteResponse(obj) {\n return obj && isResponse(obj.response) && (obj.type === ResultType.data || obj.type === ResultType.error);\n}\nfunction isValidMethod(method) {\n return validRequestMethods.has(method.toLowerCase());\n}\nfunction isMutationMethod(method) {\n return validMutationMethods.has(method.toLowerCase());\n}\nasync function resolveDeferredResults(currentMatches, matchesToLoad, results, signals, isFetcher, currentLoaderData) {\n for(let index = 0; index < results.length; index++){\n let result = results[index];\n let match = matchesToLoad[index];\n // If we don't have a match, then we can have a deferred result to do\n // anything with. This is for revalidating fetchers where the route was\n // removed during HMR\n if (!match) {\n continue;\n }\n let currentMatch = currentMatches.find((m)=>m.route.id === match.route.id);\n let isRevalidatingLoader = currentMatch != null && !isNewRouteInstance(currentMatch, match) && (currentLoaderData && currentLoaderData[match.route.id]) !== undefined;\n if (isDeferredResult(result) && (isFetcher || isRevalidatingLoader)) {\n // Note: we do not have to touch activeDeferreds here since we race them\n // against the signal in resolveDeferredData and they'll get aborted\n // there if needed\n let signal = signals[index];\n invariant(signal, \"Expected an AbortSignal for revalidating fetcher deferred result\");\n await resolveDeferredData(result, signal, isFetcher).then((result)=>{\n if (result) {\n results[index] = result || results[index];\n }\n });\n }\n }\n}\nasync function resolveDeferredData(result, signal, unwrap) {\n if (unwrap === void 0) {\n unwrap = false;\n }\n let aborted = await result.deferredData.resolveData(signal);\n if (aborted) {\n return;\n }\n if (unwrap) {\n try {\n return {\n type: ResultType.data,\n data: result.deferredData.unwrappedData\n };\n } catch (e) {\n // Handle any TrackedPromise._error values encountered while unwrapping\n return {\n type: ResultType.error,\n error: e\n };\n }\n }\n return {\n type: ResultType.data,\n data: result.deferredData.data\n };\n}\nfunction hasNakedIndexQuery(search) {\n return new URLSearchParams(search).getAll(\"index\").some((v)=>v === \"\");\n}\n// Note: This should match the format exported by useMatches, so if you change\n// this please also change that :) Eventually we'll DRY this up\nfunction createUseMatchesMatch(match, loaderData) {\n let { route, pathname, params } = match;\n return {\n id: route.id,\n pathname,\n params,\n data: loaderData[route.id],\n handle: route.handle\n };\n}\nfunction getTargetMatch(matches, location) {\n let search = typeof location === \"string\" ? parsePath(location).search : location.search;\n if (matches[matches.length - 1].route.index && hasNakedIndexQuery(search || \"\")) {\n // Return the leaf index route when index is present\n return matches[matches.length - 1];\n }\n // Otherwise grab the deepest \"path contributing\" match (ignoring index and\n // pathless layout routes)\n let pathMatches = getPathContributingMatches(matches);\n return pathMatches[pathMatches.length - 1];\n}\nfunction getSubmissionFromNavigation(navigation) {\n let { formMethod, formAction, formEncType, text, formData, json } = navigation;\n if (!formMethod || !formAction || !formEncType) {\n return;\n }\n if (text != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: undefined,\n json: undefined,\n text\n };\n } else if (formData != null) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData,\n json: undefined,\n text: undefined\n };\n } else if (json !== undefined) {\n return {\n formMethod,\n formAction,\n formEncType,\n formData: undefined,\n json,\n text: undefined\n };\n }\n}\nfunction getLoadingNavigation(location, submission) {\n if (submission) {\n let navigation = {\n state: \"loading\",\n location,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text\n };\n return navigation;\n } else {\n let navigation = {\n state: \"loading\",\n location,\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined\n };\n return navigation;\n }\n}\nfunction getSubmittingNavigation(location, submission) {\n let navigation = {\n state: \"submitting\",\n location,\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text\n };\n return navigation;\n}\nfunction getLoadingFetcher(submission, data) {\n if (submission) {\n let fetcher = {\n state: \"loading\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data,\n \" _hasFetcherDoneAnything \": true\n };\n return fetcher;\n } else {\n let fetcher = {\n state: \"loading\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n data,\n \" _hasFetcherDoneAnything \": true\n };\n return fetcher;\n }\n}\nfunction getSubmittingFetcher(submission, existingFetcher) {\n let fetcher = {\n state: \"submitting\",\n formMethod: submission.formMethod,\n formAction: submission.formAction,\n formEncType: submission.formEncType,\n formData: submission.formData,\n json: submission.json,\n text: submission.text,\n data: existingFetcher ? existingFetcher.data : undefined,\n \" _hasFetcherDoneAnything \": true\n };\n return fetcher;\n}\nfunction getDoneFetcher(data) {\n let fetcher = {\n state: \"idle\",\n formMethod: undefined,\n formAction: undefined,\n formEncType: undefined,\n formData: undefined,\n json: undefined,\n text: undefined,\n data,\n \" _hasFetcherDoneAnything \": true\n };\n return fetcher;\n}\n//#endregion\n //# sourceMappingURL=router.js.map\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvQHJlbWl4LXJ1bi9yb3V0ZXIvZGlzdC9yb3V0ZXIuanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTs7Ozs7Ozs7O0NBU0MsR0FDRCxTQUFTQTtJQUNQQSxXQUFXQyxPQUFPQyxNQUFNLEdBQUdELE9BQU9DLE1BQU0sQ0FBQ0MsSUFBSSxLQUFLLFNBQVVDLE1BQU07UUFDaEUsSUFBSyxJQUFJQyxJQUFJLEdBQUdBLElBQUlDLFVBQVVDLE1BQU0sRUFBRUYsSUFBSztZQUN6QyxJQUFJRyxTQUFTRixTQUFTLENBQUNELEVBQUU7WUFDekIsSUFBSyxJQUFJSSxPQUFPRCxPQUFRO2dCQUN0QixJQUFJUCxPQUFPUyxTQUFTLENBQUNDLGNBQWMsQ0FBQ0MsSUFBSSxDQUFDSixRQUFRQyxNQUFNO29CQUNyREwsTUFBTSxDQUFDSyxJQUFJLEdBQUdELE1BQU0sQ0FBQ0MsSUFBSTtnQkFDM0I7WUFDRjtRQUNGO1FBQ0EsT0FBT0w7SUFDVDtJQUNBLE9BQU9KLFNBQVNhLEtBQUssQ0FBQyxJQUFJLEVBQUVQO0FBQzlCO0FBRUEsZ0ZBQWdGO0FBQ2hGLDZCQUE2QjtBQUM3QixnRkFBZ0Y7QUFDaEY7O0NBRUMsR0FDRCxJQUFJUTtBQUNILFVBQVVBLE1BQU07SUFDZjs7Ozs7O0dBTUMsR0FDREEsTUFBTSxDQUFDLE1BQU0sR0FBRztJQUNoQjs7OztHQUlDLEdBQ0RBLE1BQU0sQ0FBQyxPQUFPLEdBQUc7SUFDakI7OztHQUdDLEdBQ0RBLE1BQU0sQ0FBQyxVQUFVLEdBQUc7QUFDdEIsR0FBR0EsVUFBV0EsQ0FBQUEsU0FBUyxDQUFDO0FBQ3hCLE1BQU1DLG9CQUFvQjtBQUMxQjs7O0NBR0MsR0FDRCxTQUFTQyxvQkFBb0JDLE9BQU87SUFDbEMsSUFBSUEsWUFBWSxLQUFLLEdBQUc7UUFDdEJBLFVBQVUsQ0FBQztJQUNiO0lBQ0EsSUFBSSxFQUNGQyxpQkFBaUI7UUFBQztLQUFJLEVBQ3RC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VDtZQUNibVQsVUFBVW5UO1lBQ1ZxTyxNQUFNck87WUFDTm9ULE1BQU1wVDtZQUNOc087WUFDQSw2QkFBNkI7UUFDL0I7UUFDQSxPQUFPcU47SUFDVDtBQUNGO0FBQ0EsU0FBU3dCLHFCQUFxQnRFLFVBQVUsRUFBRXFFLGVBQWU7SUFDdkQsSUFBSXZCLFVBQVU7UUFDWjViLE9BQU87UUFDUGlULFlBQVk2RixXQUFXN0YsVUFBVTtRQUNqQ0MsWUFBWTRGLFdBQVc1RixVQUFVO1FBQ2pDQyxhQUFhMkYsV0FBVzNGLFdBQVc7UUFDbkNDLFVBQVUwRixXQUFXMUYsUUFBUTtRQUM3QjlFLE1BQU13SyxXQUFXeEssSUFBSTtRQUNyQitFLE1BQU15RixXQUFXekYsSUFBSTtRQUNyQjlFLE1BQU00TyxrQkFBa0JBLGdCQUFnQjVPLElBQUksR0FBR3RPO1FBQy9DLDZCQUE2QjtJQUMvQjtJQUNBLE9BQU8yYjtBQUNUO0FBQ0EsU0FBUzhCLGVBQWVuUCxJQUFJO0lBQzFCLElBQUlxTixVQUFVO1FBQ1o1YixPQUFPO1FBQ1BpVCxZQUFZaFQ7UUFDWmlULFlBQVlqVDtRQUNaa1QsYUFBYWxUO1FBQ2JtVCxVQUFVblQ7UUFDVnFPLE1BQU1yTztRQUNOb1QsTUFBTXBUO1FBQ05zTztRQUNBLDZCQUE2QjtJQUMvQjtJQUNBLE9BQU9xTjtBQUNUO0FBQ0EsWUFBWTtBQUUycUIsQ0FDdnJCLGtDQUFrQyIsInNvdXJjZXMiOlsid2VicGFjazovL25leHRjaGF0Ly4vbm9kZV9tb2R1bGVzL0ByZW1peC1ydW4vcm91dGVyL2Rpc3Qvcm91dGVyLmpzPzUwMzkiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAcmVtaXgtcnVuL3JvdXRlciB2MS44LjBcbiAqXG4gKiBDb3B5cmlnaHQgKGMpIFJlbWl4IFNvZnR3YXJlIEluYy5cbiAqXG4gKiBUaGlzIHNvdXJjZSBjb2RlIGlzIGxpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgbGljZW5zZSBmb3VuZCBpbiB0aGVcbiAqIExJQ0VOU0UubWQgZmlsZSBpbiB0aGUgcm9vdCBkaXJlY3Rvcnkgb2YgdGhpcyBzb3VyY2UgdHJlZS5cbiAqXG4gKiBAbGljZW5zZSBNSVRcbiAqL1xuZnVuY3Rpb24gX2V4dGVuZHMoKSB7XG4gIF9leHRlbmRzID0gT2JqZWN0LmFzc2lnbiA/IE9iamVjdC5hc3NpZ24uYmluZCgpIDogZnVuY3Rpb24gKHRhcmdldCkge1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgc291cmNlID0gYXJndW1lbnRzW2ldO1xuICAgICAgZm9yICh2YXIga2V5IGluIHNvdXJjZSkge1xuICAgICAgICBpZiAoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKHNvdXJjZSwga2V5KSkge1xuICAgICAgICAgIHRhcmdldFtrZXldID0gc291cmNlW2tleV07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfTtcbiAgcmV0dXJuIF9leHRlbmRzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59XG5cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyNyZWdpb24gVHlwZXMgYW5kIENvbnN0YW50c1xuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8qKlxuICogQWN0aW9ucyByZXByZXNlbnQgdGhlIHR5cGUgb2YgY2hhbmdlIHRvIGEgbG9jYXRpb24gdmFsdWUuXG4gKi9cbnZhciBBY3Rpb247XG4oZnVuY3Rpb24gKEFjdGlvbikge1xuICAvKipcbiAgICogQSBQT1AgaW5kaWNhdGVzIGEgY2hhbmdlIHRvIGFuIGFyYml0cmFyeSBpbmRleCBpbiB0aGUgaGlzdG9yeSBzdGFjaywgc3VjaFxuICAgKiBhcyBhIGJhY2sgb3IgZm9yd2FyZCBuYXZpZ2F0aW9uLiBJdCBkb2VzIG5vdCBkZXNjcmliZSB0aGUgZGlyZWN0aW9uIG9mIHRoZVxuICAgKiBuYXZpZ2F0aW9uLCBvbmx5IHRoYXQgdGhlIGN1cnJlbnQgaW5kZXggY2hhbmdlZC5cbiAgICpcbiAgICogTm90ZTogVGhpcyBpcyB0aGUgZGVmYXVsdCBhY3Rpb24gZm9yIG5ld2x5IGNyZWF0ZWQgaGlzdG9yeSBvYmplY3RzLlxuICAgKi9cbiAgQWN0aW9uW1wiUG9wXCJdID0gXCJQT1BcIjtcbiAgLyoqXG4gICAqIEEgUFVTSCBpbmRpY2F0ZXMgYSBuZXcgZW50cnkgYmVpbmcgYWRkZWQgdG8gdGhlIGhpc3Rvcnkgc3RhY2ssIHN1Y2ggYXMgd2hlblxuICAgKiBhIGxpbmsgaXMgY2xpY2tlZCBhbmQgYSBuZXcgcGFnZSBsb2Fkcy4gV2hlbiB0aGlzIGhhcHBlbnMsIGFsbCBzdWJzZXF1ZW50XG4gICAqIGVudHJpZXMgaW4gdGhlIHN0YWNrIGFyZSBsb3N0LlxuICAgKi9cbiAgQWN0aW9uW1wiUHVzaFwiXSA9IFwiUFVTSFwiO1xuICAvKipcbiAgICogQSBSRVBMQUNFIGluZGljYXRlcyB0aGUgZW50cnkgYXQgdGhlIGN1cnJlbnQgaW5kZXggaW4gdGhlIGhpc3Rvcnkgc3RhY2tcbiAgICogYmVpbmcgcmVwbGFjZWQgYnkgYSBuZXcgb25lLlxuICAgKi9cbiAgQWN0aW9uW1wiUmVwbGFjZVwiXSA9IFwiUkVQTEFDRVwiO1xufSkoQWN0aW9uIHx8IChBY3Rpb24gPSB7fSkpO1xuY29uc3QgUG9wU3RhdGVFdmVudFR5cGUgPSBcInBvcHN0YXRlXCI7XG4vKipcbiAqIE1lbW9yeSBoaXN0b3J5IHN0b3JlcyB0aGUgY3VycmVudCBsb2NhdGlvbiBpbiBtZW1vcnkuIEl0IGlzIGRlc2lnbmVkIGZvciB1c2VcbiAqIGluIHN0YXRlZnVsIG5vbi1icm93c2VyIGVudmlyb25tZW50cyBsaWtlIHRlc3RzIGFuZCBSZWFjdCBOYXRpdmUuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZU1lbW9yeUhpc3Rvcnkob3B0aW9ucykge1xuICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIGxldCB7XG4gICAgaW5pdGlhbEVudHJpZXMgPSBbXCIvXCJdLFxuICAgIGluaXRpYWxJbmRleCxcbiAgICB2NUNvbXBhdCA9IGZhbHNlXG4gIH0gPSBvcHRpb25zO1xuICBsZXQgZW50cmllczsgLy8gRGVjbGFyZSBzbyB3ZSBjYW4gYWNjZXNzIGZyb20gY3JlYXRlTWVtb3J5TG9jYXRpb25cbiAgZW50cmllcyA9IGluaXRpYWxFbnRyaWVzLm1hcCgoZW50cnksIGluZGV4KSA9PiBjcmVhdGVNZW1vcnlMb2NhdGlvbihlbnRyeSwgdHlwZW9mIGVudHJ5ID09PSBcInN0cmluZ1wiID8gbnVsbCA6IGVudHJ5LnN0YXRlLCBpbmRleCA9PT0gMCA/IFwiZGVmYXVsdFwiIDogdW5kZWZpbmVkKSk7XG4gIGxldCBpbmRleCA9IGNsYW1wSW5kZXgoaW5pdGlhbEluZGV4ID09IG51bGwgPyBlbnRyaWVzLmxlbmd0aCAtIDEgOiBpbml0aWFsSW5kZXgpO1xuICBsZXQgYWN0aW9uID0gQWN0aW9uLlBvcDtcbiAgbGV0IGxpc3RlbmVyID0gbnVsbDtcbiAgZnVuY3Rpb24gY2xhbXBJbmRleChuKSB7XG4gICAgcmV0dXJuIE1hdGgubWluKE1hdGgubWF4KG4sIDApLCBlbnRyaWVzLmxlbmd0aCAtIDEpO1xuICB9XG4gIGZ1bmN0aW9uIGdldEN1cnJlbnRMb2NhdGlvbigpIHtcbiAgICByZXR1cm4gZW50cmllc1tpbmRleF07XG4gIH1cbiAgZnVuY3Rpb24gY3JlYXRlTWVtb3J5TG9jYXRpb24odG8sIHN0YXRlLCBrZXkpIHtcbiAgICBpZiAoc3RhdGUgPT09IHZvaWQgMCkge1xuICAgICAgc3RhdGUgPSBudWxsO1xuICAgIH1cbiAgICBsZXQgbG9jYXRpb24gPSBjcmVhdGVMb2NhdGlvbihlbnRyaWVzID8gZ2V0Q3VycmVudExvY2F0aW9uKCkucGF0aG5hbWUgOiBcIi9cIiwgdG8sIHN0YXRlLCBrZXkpO1xuICAgIHdhcm5pbmcobG9jYXRpb24ucGF0aG5hbWUuY2hhckF0KDApID09PSBcIi9cIiwgXCJyZWxhdGl2ZSBwYXRobmFtZXMgYXJlIG5vdCBzdXBwb3J0ZWQgaW4gbWVtb3J5IGhpc3Rvcnk6IFwiICsgSlNPTi5zdHJpbmdpZnkodG8pKTtcbiAgICByZXR1cm4gbG9jYXRpb247XG4gIH1cbiAgZnVuY3Rpb24gY3JlYXRlSHJlZih0bykge1xuICAgIHJldHVybiB0eXBlb2YgdG8gPT09IFwic3RyaW5nXCIgPyB0byA6IGNyZWF0ZVBhdGgodG8pO1xuICB9XG4gIGxldCBoaXN0b3J5ID0ge1xuICAgIGdldCBpbmRleCgpIHtcbiAgICAgIHJldHVybiBpbmRleDtcbiAgICB9LFxuICAgIGdldCBhY3Rpb24oKSB7XG4gICAgICByZXR1cm4gYWN0aW9uO1xuICAgIH0sXG4gICAgZ2V0IGxvY2F0aW9uKCkge1xuICAgICAgcmV0dXJuIGdldEN1cnJlbnRMb2NhdGlvbigpO1xuICAgIH0sXG4gICAgY3JlYXRlSHJlZixcbiAgICBjcmVhdGVVUkwodG8pIHtcbiAgICAgIHJldHVybiBuZXcgVVJMKGNyZWF0ZUhyZWYodG8pLCBcImh0dHA6Ly9sb2NhbGhvc3RcIik7XG4gICAgfSxcbiAgICBlbmNvZGVMb2NhdGlvbih0bykge1xuICAgICAgbGV0IHBhdGggPSB0eXBlb2YgdG8gPT09IFwic3RyaW5nXCIgPyBwYXJzZVBhdGgodG8pIDogdG87XG4gICAgICByZXR1cm4ge1xuICAgICAgICBwYXRobmFtZTogcGF0aC5wYXRobmFtZSB8fCBcIlwiLFxuICAgICAgICBzZWFyY2g6IHBhdGguc2VhcmNoIHx8IFwiXCIsXG4gICAgICAgIGhhc2g6IHBhdGguaGFzaCB8fCBcIlwiXG4gICAgICB9O1xuICAgIH0sXG4gICAgcHVzaCh0bywgc3RhdGUpIHtcbiAgICAgIGFjdGlvbiA9IEFjdGlvbi5QdXNoO1xuICAgICAgbGV0IG5leHRMb2NhdGlvbiA9IGNyZWF0ZU1lbW9yeUxvY2F0aW9uKHRvLCBzdGF0ZSk7XG4gICAgICBpbmRleCArPSAxO1xuICAgICAgZW50cmllcy5zcGxpY2UoaW5kZXgsIGVudHJpZXMubGVuZ3RoLCBuZXh0TG9jYXRpb24pO1xuICAgICAgaWYgKHY1Q29tcGF0ICYmIGxpc3RlbmVyKSB7XG4gICAgICAgIGxpc3RlbmVyKHtcbiAgICAgICAgICBhY3Rpb24sXG4gICAgICAgICAgbG9jYXRpb246IG5leHRMb2NhdGlvbixcbiAgICAgICAgICBkZWx0YTogMVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9LFxuICAgIHJlcGxhY2UodG8sIHN0YXRlKSB7XG4gICAgICBhY3Rpb24gPSBBY3Rpb24uUmVwbGFjZTtcbiAgICAgIGxldCBuZXh0TG9jYXRpb24gPSBjcmVhdGVNZW1vcnlMb2NhdGlvbih0bywgc3RhdGUpO1xuICAgICAgZW50cmllc1tpbmRleF0gPSBuZXh0TG9jYXRpb247XG4gICAgICBpZiAodjVDb21wYXQgJiYgbGlzdGVuZXIpIHtcbiAgICAgICAgbGlzdGVuZXIoe1xuICAgICAgICAgIGFjdGlvbixcbiAgICAgICAgICBsb2NhdGlvbjogbmV4dExvY2F0aW9uLFxuICAgICAgICAgIGRlbHRhOiAwXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0sXG4gICAgZ28oZGVsdGEpIHtcbiAgICAgIGFjdGlvbiA9IEFjdGlvbi5Qb3A7XG4gICAgICBsZXQgbmV4dEluZGV4ID0gY2xhbXBJbmRleChpbmRleCArIGRlbHRhKTtcbiAgICAgIGxldCBuZXh0TG9jYXRpb24gPSBlbnRyaWVzW25leHRJbmRleF07XG4gICAgICBpbmRleCA9IG5leHRJbmRleDtcbiAgICAgIGlmIChsaXN0ZW5lcikge1xuICAgICAgICBsaXN0ZW5lcih7XG4gICAgICAgICAgYWN0aW9uLFxuICAgICAgICAgIGxvY2F0aW9uOiBuZXh0TG9jYXRpb24sXG4gICAgICAgICAgZGVsdGFcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSxcbiAgICBsaXN0ZW4oZm4pIHtcbiAgICAgIGxpc3RlbmVyID0gZm47XG4gICAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBsaXN0ZW5lciA9IG51bGw7XG4gICAgICB9O1xuICAgIH1cbiAgfTtcbiAgcmV0dXJuIGhpc3Rvcnk7XG59XG4vKipcbiAqIEJyb3dzZXIgaGlzdG9yeSBzdG9yZXMgdGhlIGxvY2F0aW9uIGluIHJlZ3VsYXIgVVJMcy4gVGhpcyBpcyB0aGUgc3RhbmRhcmQgZm9yXG4gKiBtb3N0IHdlYiBhcHBzLCBidXQgaXQgcmVxdWlyZXMgc29tZSBjb25maWd1cmF0aW9uIG9uIHRoZSBzZXJ2ZXIgdG8gZW5zdXJlIHlvdVxuICogc2VydmUgdGhlIHNhbWUgYXBwIGF0IG11bHRpcGxlIFVSTHMuXG4gKlxuICogQHNlZSBodHRwczovL2dpdGh1Yi5jb20vcmVtaXgtcnVuL2hpc3RvcnkvdHJlZS9tYWluL2RvY3MvYXBpLXJlZmVyZW5jZS5tZCNjcmVhdGVicm93c2VyaGlzdG9yeVxuICovXG5mdW5jdGlvbiBjcmVhdGVCcm93c2VySGlzdG9yeShvcHRpb25zKSB7XG4gIGlmIChvcHRpb25zID09PSB2b2lkIDApIHtcbiAgICBvcHRpb25zID0ge307XG4gIH1cbiAgZnVuY3Rpb24gY3JlYXRlQnJvd3NlckxvY2F0aW9uKHdpbmRvdywgZ2xvYmFsSGlzdG9yeSkge1xuICAgIGxldCB7XG4gICAgICBwYXRobmFtZSxcbiAgICAgIHNlYXJjaCxcbiAgICAgIGhhc2hcbiAgICB9ID0gd2luZG93LmxvY2F0aW9uO1xuICAgIHJldHVybiBjcmVhdGVMb2NhdGlvbihcIlwiLCB7XG4gICAgICBwYXRobmFtZSxcbiAgICAgIHNlYXJjaCxcbiAgICAgIGhhc2hcbiAgICB9LFxuICAgIC8vIHN0YXRlIGRlZmF1bHRzIHRvIGBudWxsYCBiZWNhdXNlIGB3aW5kb3cuaGlzdG9yeS5zdGF0ZWAgZG9lc1xuICAgIGdsb2JhbEhpc3Rvcnkuc3RhdGUgJiYgZ2xvYmFsSGlzdG9yeS5zdGF0ZS51c3IgfHwgbnVsbCwgZ2xvYmFsSGlzdG9yeS5zdGF0ZSAmJiBnbG9iYWxIaXN0b3J5LnN0YXRlLmtleSB8fCBcImRlZmF1bHRcIik7XG4gIH1cbiAgZnVuY3Rpb24gY3JlYXRlQnJvd3NlckhyZWYod2luZG93LCB0bykge1xuICAgIHJldHVybiB0eXBlb2YgdG8gPT09IFwic3RyaW5nXCIgPyB0byA6IGNyZWF0ZVBhdGgodG8pO1xuICB9XG4gIHJldHVybiBnZXRVcmxCYXNlZEhpc3RvcnkoY3JlYXRlQnJvd3NlckxvY2F0aW9uLCBjcmVhdGVCcm93c2VySHJlZiwgbnVsbCwgb3B0aW9ucyk7XG59XG4vKipcbiAqIEhhc2ggaGlzdG9yeSBzdG9yZXMgdGhlIGxvY2F0aW9uIGluIHdpbmRvdy5sb2NhdGlvbi5oYXNoLiBUaGlzIG1ha2VzIGl0IGlkZWFsXG4gKiBmb3Igc2l0dWF0aW9ucyB3aGVyZSB5b3UgZG9uJ3Qgd2FudCB0byBzZW5kIHRoZSBsb2NhdGlvbiB0byB0aGUgc2VydmVyIGZvclxuICogc29tZSByZWFzb24sIGVpdGhlciBiZWNhdXNlIHlvdSBkbyBjYW5ub3QgY29uZmlndXJlIGl0IG9yIHRoZSBVUkwgc3BhY2UgaXNcbiAqIHJlc2VydmVkIGZvciBzb21ldGhpbmcgZWxzZS5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9yZW1peC1ydW4vaGlzdG9yeS90cmVlL21haW4vZG9jcy9hcGktcmVmZXJlbmNlLm1kI2NyZWF0ZWhhc2hoaXN0b3J5XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUhhc2hIaXN0b3J5KG9wdGlvbnMpIHtcbiAgaWYgKG9wdGlvbnMgPT09IHZvaWQgMCkge1xuICAgIG9wdGlvbnMgPSB7fTtcbiAgfVxuICBmdW5jdGlvbiBjcmVhdGVIYXNoTG9jYXRpb24od2luZG93LCBnbG9iYWxIaXN0b3J5KSB7XG4gICAgbGV0IHtcbiAgICAgIHBhdGhuYW1lID0gXCIvXCIsXG4gICAgICBzZWFyY2ggPSBcIlwiLFxuICAgICAgaGFzaCA9IFwiXCJcbiAgICB9ID0gcGFyc2VQYXRoKHdpbmRvdy5sb2NhdGlvbi5oYXNoLnN1YnN0cigxKSk7XG4gICAgLy8gSGFzaCBVUkwgc2hvdWxkIGFsd2F5cyBoYXZlIGEgbGVhZGluZyAvIGp1c3QgbGlrZSB3aW5kb3cubG9jYXRpb24ucGF0aG5hbWVcbiAgICAvLyBkb2VzLCBzbyBpZiBhbiBhcHAgZW5kcyB1cCBhdCBhIHJvdXRlIGxpa2UgLyNzb21ldGhpbmcgdGhlbiB3ZSBhZGQgYVxuICAgIC8vIGxlYWRpbmcgc2xhc2ggc28gYWxsIG9mIG91ciBwYXRoLW1hdGNoaW5nIGJlaGF2ZXMgdGhlIHNhbWUgYXMgaWYgaXQgd291bGRcbiAgICAvLyBpbiBhIGJyb3dzZXIgcm91dGVyLiAgVGhpcyBpcyBwYXJ0aWN1bGFybHkgaW1wb3J0YW50IHdoZW4gdGhlcmUgZXhpc3RzIGFcbiAgICAvLyByb290IHNwbGF0IHJvdXRlICg8Um91dGUgcGF0aD1cIipcIj4pIHNpbmNlIHRoYXQgbWF0Y2hlcyBpbnRlcm5hbGx5IGFnYWluc3RcbiAgICAvLyBcIi8qXCIgYW5kIHdlJ2QgZXhwZWN0IC8jc29tZXRoaW5nIHRvIDQwNCBpbiBhIGhhc2ggcm91dGVyIGFwcC5cbiAgICBpZiAoIXBhdGhuYW1lLnN0YXJ0c1dpdGgoXCIvXCIpICYmICFwYXRobmFtZS5zdGFydHNXaXRoKFwiLlwiKSkge1xuICAgICAgcGF0aG5hbWUgPSBcIi9cIiArIHBhdGhuYW1lO1xuICAgIH1cbiAgICByZXR1cm4gY3JlYXRlTG9jYXRpb24oXCJcIiwge1xuICAgICAgcGF0aG5hbWUsXG4gICAgICBzZWFyY2gsXG4gICAgICBoYXNoXG4gICAgfSxcbiAgICAvLyBzdGF0ZSBkZWZhdWx0cyB0byBgbnVsbGAgYmVjYXVzZSBgd2luZG93Lmhpc3Rvcnkuc3RhdGVgIGRvZXNcbiAgICBnbG9iYWxIaXN0b3J5LnN0YXRlICYmIGdsb2JhbEhpc3Rvcnkuc3RhdGUudXNyIHx8IG51bGwsIGdsb2JhbEhpc3Rvcnkuc3RhdGUgJiYgZ2xvYmFsSGlzdG9yeS5zdGF0ZS5rZXkgfHwgXCJkZWZhdWx0XCIpO1xuICB9XG4gIGZ1bmN0aW9uIGNyZWF0ZUhhc2hIcmVmKHdpbmRvdywgdG8pIHtcbiAgICBsZXQgYmFzZSA9IHdpbmRvdy5kb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiYmFzZVwiKTtcbiAgICBsZXQgaHJlZiA9IFwiXCI7XG4gICAgaWYgKGJhc2UgJiYgYmFzZS5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpKSB7XG4gICAgICBsZXQgdXJsID0gd2luZG93LmxvY2F0aW9uLmhyZWY7XG4gICAgICBsZXQgaGFzaEluZGV4ID0gdXJsLmluZGV4T2YoXCIjXCIpO1xuICAgICAgaHJlZiA9IGhhc2hJbmRleCA9PT0gLTEgPyB1cmwgOiB1cmwuc2xpY2UoMCwgaGFzaEluZGV4KTtcbiAgICB9XG4gICAgcmV0dXJuIGhyZWYgKyBcIiNcIiArICh0eXBlb2YgdG8gPT09IFwic3RyaW5nXCIgPyB0byA6IGNyZWF0ZVBhdGgodG8pKTtcbiAgfVxuICBmdW5jdGlvbiB2YWxpZGF0ZUhhc2hMb2NhdGlvbihsb2NhdGlvbiwgdG8pIHtcbiAgICB3YXJuaW5nKGxvY2F0aW9uLnBhdGhuYW1lLmNoYXJBdCgwKSA9PT0gXCIvXCIsIFwicmVsYXRpdmUgcGF0aG5hbWVzIGFyZSBub3Qgc3VwcG9ydGVkIGluIGhhc2ggaGlzdG9yeS5wdXNoKFwiICsgSlNPTi5zdHJpbmdpZnkodG8pICsgXCIpXCIpO1xuICB9XG4gIHJldHVybiBnZXRVcmxCYXNlZEhpc3RvcnkoY3JlYXRlSGFzaExvY2F0aW9uLCBjcmVhdGVIYXNoSHJlZiwgdmFsaWRhdGVIYXNoTG9jYXRpb24sIG9wdGlvbnMpO1xufVxuZnVuY3Rpb24gaW52YXJpYW50KHZhbHVlLCBtZXNzYWdlKSB7XG4gIGlmICh2YWx1ZSA9PT0gZmFsc2UgfHwgdmFsdWUgPT09IG51bGwgfHwgdHlwZW9mIHZhbHVlID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICB9XG59XG5mdW5jdGlvbiB3YXJuaW5nKGNvbmQsIG1lc3NhZ2UpIHtcbiAgaWYgKCFjb25kKSB7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgICBpZiAodHlwZW9mIGNvbnNvbGUgIT09IFwidW5kZWZpbmVkXCIpIGNvbnNvbGUud2FybihtZXNzYWdlKTtcbiAgICB0cnkge1xuICAgICAgLy8gV2VsY29tZSB0byBkZWJ1Z2dpbmcgaGlzdG9yeSFcbiAgICAgIC8vXG4gICAgICAvLyBUaGlzIGVycm9yIGlzIHRocm93biBhcyBhIGNvbnZlbmllbmNlIHNvIHlvdSBjYW4gbW9yZSBlYXNpbHlcbiAgICAgIC8vIGZpbmQgdGhlIHNvdXJjZSBmb3IgYSB3YXJuaW5nIHRoYXQgYXBwZWFycyBpbiB0aGUgY29uc29sZSBieVxuICAgICAgLy8gZW5hYmxpbmcgXCJwYXVzZSBvbiBleGNlcHRpb25zXCIgaW4geW91ciBKYXZhU2NyaXB0IGRlYnVnZ2VyLlxuICAgICAgdGhyb3cgbmV3IEVycm9yKG1lc3NhZ2UpO1xuICAgICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWVtcHR5XG4gICAgfSBjYXRjaCAoZSkge31cbiAgfVxufVxuZnVuY3Rpb24gY3JlYXRlS2V5KCkge1xuICByZXR1cm4gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyKDIsIDgpO1xufVxuLyoqXG4gKiBGb3IgYnJvd3Nlci1iYXNlZCBoaXN0b3JpZXMsIHdlIGNvbWJpbmUgdGhlIHN0YXRlIGFuZCBrZXkgaW50byBhbiBvYmplY3RcbiAqL1xuZnVuY3Rpb24gZ2V0SGlzdG9yeVN0YXRlKGxvY2F0aW9uLCBpbmRleCkge1xuICByZXR1cm4ge1xuICAgIHVzcjogbG9jYXRpb24uc3RhdGUsXG4gICAga2V5OiBsb2NhdGlvbi5rZXksXG4gICAgaWR4OiBpbmRleFxuICB9O1xufVxuLyoqXG4gKiBDcmVhdGVzIGEgTG9jYXRpb24gb2JqZWN0IHdpdGggYSB1bmlxdWUga2V5IGZyb20gdGhlIGdpdmVuIFBhdGhcbiAqL1xuZnVuY3Rpb24gY3JlYXRlTG9jYXRpb24oY3VycmVudCwgdG8sIHN0YXRlLCBrZXkpIHtcbiAgaWYgKHN0YXRlID09PSB2b2lkIDApIHtcbiAgICBzdGF0ZSA9IG51bGw7XG4gIH1cbiAgbGV0IGxvY2F0aW9uID0gX2V4dGVuZHMoe1xuICAgIHBhdGhuYW1lOiB0eXBlb2YgY3VycmVudCA9PT0gXCJzdHJpbmdcIiA/IGN1cnJlbnQgOiBjdXJyZW50LnBhdGhuYW1lLFxuICAgIHNlYXJjaDogXCJcIixcbiAgICBoYXNoOiBcIlwiXG4gIH0sIHR5cGVvZiB0byA9PT0gXCJzdHJpbmdcIiA/IHBhcnNlUGF0aCh0bykgOiB0bywge1xuICAgIHN0YXRlLFxuICAgIC8vIFRPRE86IFRoaXMgY291bGQgYmUgY2xlYW5lZCB1cC4gIHB1c2gvcmVwbGFjZSBzaG91bGQgcHJvYmFibHkganVzdCB0YWtlXG4gICAgLy8gZnVsbCBMb2NhdGlvbnMgbm93IGFuZCBhdm9pZCB0aGUgbmVlZCB0byBydW4gdGhyb3VnaCB0aGlzIGZsb3cgYXQgYWxsXG4gICAgLy8gQnV0IHRoYXQncyBhIHByZXR0eSBiaWcgcmVmYWN0b3IgdG8gdGhlIGN1cnJlbnQgdGVzdCBzdWl0ZSBzbyBnb2luZyB0b1xuICAgIC8vIGtlZXAgYXMgaXMgZm9yIHRoZSB0aW1lIGJlaW5nIGFuZCBqdXN0IGxldCBhbnkgaW5jb21pbmcga2V5cyB0YWtlIHByZWNlZGVuY2VcbiAgICBrZXk6IHRvICYmIHRvLmtleSB8fCBrZXkgfHwgY3JlYXRlS2V5KClcbiAgfSk7XG4gIHJldHVybiBsb2NhdGlvbjtcbn1cbi8qKlxuICogQ3JlYXRlcyBhIHN0cmluZyBVUkwgcGF0aCBmcm9tIHRoZSBnaXZlbiBwYXRobmFtZSwgc2VhcmNoLCBhbmQgaGFzaCBjb21wb25lbnRzLlxuICovXG5mdW5jdGlvbiBjcmVhdGVQYXRoKF9yZWYpIHtcbiAgbGV0IHtcbiAgICBwYXRobmFtZSA9IFwiL1wiLFxuICAgIHNlYXJjaCA9IFwiXCIsXG4gICAgaGFzaCA9IFwiXCJcbiAgfSA9IF9yZWY7XG4gIGlmIChzZWFyY2ggJiYgc2VhcmNoICE9PSBcIj9cIikgcGF0aG5hbWUgKz0gc2VhcmNoLmNoYXJBdCgwKSA9PT0gXCI/XCIgPyBzZWFyY2ggOiBcIj9cIiArIHNlYXJjaDtcbiAgaWYgKGhhc2ggJiYgaGFzaCAhPT0gXCIjXCIpIHBhdGhuYW1lICs9IGhhc2guY2hhckF0KDApID09PSBcIiNcIiA/IGhhc2ggOiBcIiNcIiArIGhhc2g7XG4gIHJldHVybiBwYXRobmFtZTtcbn1cbi8qKlxuICogUGFyc2VzIGEgc3RyaW5nIFVSTCBwYXRoIGludG8gaXRzIHNlcGFyYXRlIHBhdGhuYW1lLCBzZWFyY2gsIGFuZCBoYXNoIGNvbXBvbmVudHMuXG4gKi9cbmZ1bmN0aW9uIHBhcnNlUGF0aChwYXRoKSB7XG4gIGxldCBwYXJzZWRQYXRoID0ge307XG4gIGlmIChwYXRoKSB7XG4gICAgbGV0IGhhc2hJbmRleCA9IHBhdGguaW5kZXhPZihcIiNcIik7XG4gICAgaWYgKGhhc2hJbmRleCA+PSAwKSB7XG4gICAgICBwYXJzZWRQYXRoLmhhc2ggPSBwYXRoLnN1YnN0cihoYXNoSW5kZXgpO1xuICAgICAgcGF0aCA9IHBhdGguc3Vic3RyKDAsIGhhc2hJbmRleCk7XG4gICAgfVxuICAgIGxldCBzZWFyY2hJbmRleCA9IHBhdGguaW5kZXhPZihcIj9cIik7XG4gICAgaWYgKHNlYXJjaEluZGV4ID49IDApIHtcbiAgICAgIHBhcnNlZFBhdGguc2VhcmNoID0gcGF0aC5zdWJzdHIoc2VhcmNoSW5kZXgpO1xuICAgICAgcGF0aCA9IHBhdGguc3Vic3RyKDAsIHNlYXJjaEluZGV4KTtcbiAgICB9XG4gICAgaWYgKHBhdGgpIHtcbiAgICAgIHBhcnNlZFBhdGgucGF0aG5hbWUgPSBwYXRoO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcGFyc2VkUGF0aDtcbn1cbmZ1bmN0aW9uIGdldFVybEJhc2VkSGlzdG9yeShnZXRMb2NhdGlvbiwgY3JlYXRlSHJlZiwgdmFsaWRhdGVMb2NhdGlvbiwgb3B0aW9ucykge1xuICBpZiAob3B0aW9ucyA9PT0gdm9pZCAwKSB7XG4gICAgb3B0aW9ucyA9IHt9O1xuICB9XG4gIGxldCB7XG4gICAgd2luZG93ID0gZG9jdW1lbnQuZGVmYXVsdFZpZXcsXG4gICAgdjVDb21wYXQgPSBmYWxzZVxuICB9ID0gb3B0aW9ucztcbiAgbGV0IGdsb2JhbEhpc3RvcnkgPSB3aW5kb3cuaGlzdG9yeTtcbiAgbGV0IGFjdGlvbiA9IEFjdGlvbi5Qb3A7XG4gIGxldCBsaXN0ZW5lciA9IG51bGw7XG4gIGxldCBpbmRleCA9IGdldEluZGV4KCk7XG4gIC8vIEluZGV4IHNob3VsZCBvbmx5IGJlIG51bGwgd2hlbiB3ZSBpbml0aWFsaXplLiBJZiBub3QsIGl0J3MgYmVjYXVzZSB0aGVcbiAgLy8gdXNlciBjYWxsZWQgaGlzdG9yeS5wdXNoU3RhdGUgb3IgaGlzdG9yeS5yZXBsYWNlU3RhdGUgZGlyZWN0bHksIGluIHdoaWNoXG4gIC8vIGNhc2Ugd2Ugc2hvdWxkIGxvZyBhIHdhcm5pbmcgYXMgaXQgd2lsbCByZXN1bHQgaW4gYnVncy5cbiAgaWYgKGluZGV4ID09IG51bGwpIHtcbiAgICBpbmRleCA9IDA7XG4gICAgZ2xvYmFsSGlzdG9yeS5yZXBsYWNlU3RhdGUoX2V4dGVuZHMoe30sIGdsb2JhbEhpc3Rvcnkuc3RhdGUsIHtcbiAgICAgIGlkeDogaW5kZXhcbiAgICB9KSwgXCJcIik7XG4gIH1cbiAgZnVuY3Rpb24gZ2V0SW5kZXgoKSB7XG4gICAgbGV0IHN0YXRlID0gZ2xvYmFsSGlzdG9yeS5zdGF0ZSB8fCB7XG4gICAgICBpZHg6IG51bGxcbiAgICB9O1xuICAgIHJldHVybiBzdGF0ZS5pZHg7XG4gIH1cbiAgZnVuY3Rpb24gaGFuZGxlUG9wKCkge1xuICAgIGFjdGlvbiA9IEFjdGlvbi5Qb3A7XG4gICAgbGV0IG5leHRJbmRleCA9IGdldEluZGV4KCk7XG4gICAgbGV0IGRlbHRhID0gbmV4dEluZGV4ID09IG51bGwgPyBudWxsIDogbmV4dEluZGV4IC0gaW5kZXg7XG4gICAgaW5kZXggPSBuZXh0SW5kZXg7XG4gICAgaWYgKGxpc3RlbmVyKSB7XG4gICAgICBsaXN0ZW5lcih7XG4gICAgICAgIGFjdGlvbixcbiAgICAgICAgbG9jYXRpb246IGhpc3RvcnkubG9jYXRpb24sXG4gICAgICAgIGRlbHRhXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgZnVuY3Rpb24gcHVzaCh0bywgc3RhdGUpIHtcbiAgICBhY3Rpb24gPSBBY3Rpb24uUHVzaDtcbiAgICBsZXQgbG9jYXRpb24gPSBjcmVhdGVMb2NhdGlvbihoaXN0b3J5LmxvY2F0aW9uLCB0bywgc3RhdGUpO1xuICAgIGlmICh2YWxpZGF0ZUxvY2F0aW9uKSB2YWxpZGF0ZUxvY2F0aW9uKGxvY2F0aW9uLCB0byk7XG4gICAgaW5kZXggPSBnZXRJbmRleCgpICsgMTtcbiAgICBsZXQgaGlzdG9yeVN0YXRlID0gZ2V0SGlzdG9yeVN0YXRlKGxvY2F0aW9uLCBpbmRleCk7XG4gICAgbGV0IHVybCA9IGhpc3RvcnkuY3JlYXRlSHJlZihsb2NhdGlvbik7XG4gICAgLy8gdHJ5Li4uY2F0Y2ggYmVjYXVzZSBpT1MgbGltaXRzIHVzIHRvIDEwMCBwdXNoU3RhdGUgY2FsbHMgOi9cbiAgICB0cnkge1xuICAgICAgZ2xvYmFsSGlzdG9yeS5wdXNoU3RhdGUoaGlzdG9yeVN0YXRlLCBcIlwiLCB1cmwpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAvLyBJZiB0aGUgZXhjZXB0aW9uIGlzIGJlY2F1c2UgYHN0YXRlYCBjYW4ndCBiZSBzZXJpYWxpemVkLCBsZXQgdGhhdCB0aHJvd1xuICAgICAgLy8gb3V0d2FyZHMganVzdCBsaWtlIGEgcmVwbGFjZSBjYWxsIHdvdWxkIHNvIHRoZSBkZXYga25vd3MgdGhlIGNhdXNlXG4gICAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9uYXYtaGlzdG9yeS1hcGlzLmh0bWwjc2hhcmVkLWhpc3RvcnktcHVzaC9yZXBsYWNlLXN0YXRlLXN0ZXBzXG4gICAgICAvLyBodHRwczovL2h0bWwuc3BlYy53aGF0d2cub3JnL211bHRpcGFnZS9zdHJ1Y3R1cmVkLWRhdGEuaHRtbCNzdHJ1Y3R1cmVkc2VyaWFsaXplaW50ZXJuYWxcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIERPTUV4Y2VwdGlvbiAmJiBlcnJvci5uYW1lID09PSBcIkRhdGFDbG9uZUVycm9yXCIpIHtcbiAgICAgICAgdGhyb3cgZXJyb3I7XG4gICAgICB9XG4gICAgICAvLyBUaGV5IGFyZSBnb2luZyB0byBsb3NlIHN0YXRlIGhlcmUsIGJ1dCB0aGVyZSBpcyBubyByZWFsXG4gICAgICAvLyB3YXkgdG8gd2FybiB0aGVtIGFib3V0IGl0IHNpbmNlIHRoZSBwYWdlIHdpbGwgcmVmcmVzaC4uLlxuICAgICAgd2luZG93LmxvY2F0aW9uLmFzc2lnbih1cmwpO1xuICAgIH1cbiAgICBpZiAodjVDb21wYXQgJiYgbGlzdGVuZXIpIHtcbiAgICAgIGxpc3RlbmVyKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBsb2NhdGlvbjogaGlzdG9yeS5sb2NhdGlvbixcbiAgICAgICAgZGVsdGE6IDFcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICBmdW5jdGlvbiByZXBsYWNlKHRvLCBzdGF0ZSkge1xuICAgIGFjdGlvbiA9IEFjdGlvbi5SZXBsYWNlO1xuICAgIGxldCBsb2NhdGlvbiA9IGNyZWF0ZUxvY2F0aW9uKGhpc3RvcnkubG9jYXRpb24sIHRvLCBzdGF0ZSk7XG4gICAgaWYgKHZhbGlkYXRlTG9jYXRpb24pIHZhbGlkYXRlTG9jYXRpb24obG9jYXRpb24sIHRvKTtcbiAgICBpbmRleCA9IGdldEluZGV4KCk7XG4gICAgbGV0IGhpc3RvcnlTdGF0ZSA9IGdldEhpc3RvcnlTdGF0ZShsb2NhdGlvbiwgaW5kZXgpO1xuICAgIGxldCB1cmwgPSBoaXN0b3J5LmNyZWF0ZUhyZWYobG9jYXRpb24pO1xuICAgIGdsb2JhbEhpc3RvcnkucmVwbGFjZVN0YXRlKGhpc3RvcnlTdGF0ZSwgXCJcIiwgdXJsKTtcbiAgICBpZiAodjVDb21wYXQgJiYgbGlzdGVuZXIpIHtcbiAgICAgIGxpc3RlbmVyKHtcbiAgICAgICAgYWN0aW9uLFxuICAgICAgICBsb2NhdGlvbjogaGlzdG9yeS5sb2NhdGlvbixcbiAgICAgICAgZGVsdGE6IDBcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICBmdW5jdGlvbiBjcmVhdGVVUkwodG8pIHtcbiAgICAvLyB3aW5kb3cubG9jYXRpb24ub3JpZ2luIGlzIFwibnVsbFwiICh0aGUgbGl0ZXJhbCBzdHJpbmcgdmFsdWUpIGluIEZpcmVmb3hcbiAgICAvLyB1bmRlciBjZXJ0YWluIGNvbmRpdGlvbnMsIG5vdGFibHkgd2hlbiBzZXJ2aW5nIGZyb20gYSBsb2NhbCBIVE1MIGZpbGVcbiAgICAvLyBTZWUgaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9ODc4Mjk3XG4gICAgbGV0IGJhc2UgPSB3aW5kb3cubG9jYXRpb24ub3JpZ2luICE9PSBcIm51bGxcIiA/IHdpbmRvdy5sb2NhdGlvbi5vcmlnaW4gOiB3aW5kb3cubG9jYXRpb24uaHJlZjtcbiAgICBsZXQgaHJlZiA9IHR5cGVvZiB0byA9PT0gXCJzdHJpbmdcIiA/IHRvIDogY3JlYXRlUGF0aCh0byk7XG4gICAgaW52YXJpYW50KGJhc2UsIFwiTm8gd2luZG93LmxvY2F0aW9uLihvcmlnaW58aHJlZikgYXZhaWxhYmxlIHRvIGNyZWF0ZSBVUkwgZm9yIGhyZWY6IFwiICsgaHJlZik7XG4gICAgcmV0dXJuIG5ldyBVUkwoaHJlZiwgYmFzZSk7XG4gIH1cbiAgbGV0IGhpc3RvcnkgPSB7XG4gICAgZ2V0IGFjdGlvbigpIHtcbiAgICAgIHJldHVybiBhY3Rpb247XG4gICAgfSxcbiAgICBnZXQgbG9jYXRpb24oKSB7XG4gICAgICByZXR1cm4gZ2V0TG9jYXRpb24od2luZG93LCBnbG9iYWxIaXN0b3J5KTtcbiAgICB9LFxuICAgIGxpc3Rlbihmbikge1xuICAgICAgaWYgKGxpc3RlbmVyKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkEgaGlzdG9yeSBvbmx5IGFjY2VwdHMgb25lIGFjdGl2ZSBsaXN0ZW5lclwiKTtcbiAgICAgIH1cbiAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFBvcFN0YXRlRXZlbnRUeXBlLCBoYW5kbGVQb3ApO1xuICAgICAgbGlzdGVuZXIgPSBmbjtcbiAgICAgIHJldHVybiAoKSA9PiB7XG4gICAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKFBvcFN0YXRlRXZlbnRUeXBlLCBoYW5kbGVQb3ApO1xuICAgICAgICBsaXN0ZW5lciA9IG51bGw7XG4gICAgICB9O1xuICAgIH0sXG4gICAgY3JlYXRlSHJlZih0bykge1xuICAgICAgcmV0dXJuIGNyZWF0ZUhyZWYod2luZG93LCB0byk7XG4gICAgfSxcbiAgICBjcmVhdGVVUkwsXG4gICAgZW5jb2RlTG9jYXRpb24odG8pIHtcbiAgICAgIC8vIEVuY29kZSBhIExvY2F0aW9uIHRoZSBzYW1lIHdheSB3aW5kb3cubG9jYXRpb24gd291bGRcbiAgICAgIGxldCB1cmwgPSBjcmVhdGVVUkwodG8pO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgcGF0aG5hbWU6IHVybC5wYXRobmFtZSxcbiAgICAgICAgc2VhcmNoOiB1cmwuc2VhcmNoLFxuICAgICAgICBoYXNoOiB1cmwuaGFzaFxuICAgICAgfTtcbiAgICB9LFxuICAgIHB1c2gsXG4gICAgcmVwbGFjZSxcbiAgICBnbyhuKSB7XG4gICAgICByZXR1cm4gZ2xvYmFsSGlzdG9yeS5nbyhuKTtcbiAgICB9XG4gIH07XG4gIHJldHVybiBoaXN0b3J5O1xufVxuLy8jZW5kcmVnaW9uXG5cbnZhciBSZXN1bHRUeXBlO1xuKGZ1bmN0aW9uIChSZXN1bHRUeXBlKSB7XG4gIFJlc3VsdFR5cGVbXCJkYXRhXCJdID0gXCJkYXRhXCI7XG4gIFJlc3VsdFR5cGVbXCJkZWZlcnJlZFwiXSA9IFwiZGVmZXJyZWRcIjtcbiAgUmVzdWx0VHlwZVtcInJlZGlyZWN0XCJdID0gXCJyZWRpcmVjdFwiO1xuICBSZXN1bHRUeXBlW1wiZXJyb3JcIl0gPSBcImVycm9yXCI7XG59KShSZXN1bHRUeXBlIHx8IChSZXN1bHRUeXBlID0ge30pKTtcbmNvbnN0IGltbXV0YWJsZVJvdXRlS2V5cyA9IG5ldyBTZXQoW1wibGF6eVwiLCBcImNhc2VTZW5zaXRpdmVcIiwgXCJwYXRoXCIsIFwiaWRcIiwgXCJpbmRleFwiLCBcImNoaWxkcmVuXCJdKTtcbmZ1bmN0aW9uIGlzSW5kZXhSb3V0ZShyb3V0ZSkge1xuICByZXR1cm4gcm91dGUuaW5kZXggPT09IHRydWU7XG59XG4vLyBXYWxrIHRoZSByb3V0ZSB0cmVlIGdlbmVyYXRpbmcgdW5pcXVlIElEcyB3aGVyZSBuZWNlc3Nhcnkgc28gd2UgYXJlIHdvcmtpbmdcbi8vIHNvbGVseSB3aXRoIEFnbm9zdGljRGF0YVJvdXRlT2JqZWN0J3Mgd2l0aGluIHRoZSBSb3V0ZXJcbmZ1bmN0aW9uIGNvbnZlcnRSb3V0ZXNUb0RhdGFSb3V0ZXMocm91dGVzLCBtYXBSb3V0ZVByb3BlcnRpZXMsIHBhcmVudFBhdGgsIG1hbmlmZXN0KSB7XG4gIGlmIChwYXJlbnRQYXRoID09PSB2b2lkIDApIHtcbiAgICBwYXJlbnRQYXRoID0gW107XG4gIH1cbiAgaWYgKG1hbmlmZXN0ID09PSB2b2lkIDApIHtcbiAgICBtYW5pZmVzdCA9IHt9O1xuICB9XG4gIHJldHVybiByb3V0ZXMubWFwKChyb3V0ZSwgaW5kZXgpID0+IHtcbiAgICBsZXQgdHJlZVBhdGggPSBbLi4ucGFyZW50UGF0aCwgaW5kZXhdO1xuICAgIGxldCBpZCA9IHR5cGVvZiByb3V0ZS5pZCA9PT0gXCJzdHJpbmdcIiA/IHJvdXRlLmlkIDogdHJlZVBhdGguam9pbihcIi1cIik7XG4gICAgaW52YXJpYW50KHJvdXRlLmluZGV4ICE9PSB0cnVlIHx8ICFyb3V0ZS5jaGlsZHJlbiwgXCJDYW5ub3Qgc3BlY2lmeSBjaGlsZHJlbiBvbiBhbiBpbmRleCByb3V0ZVwiKTtcbiAgICBpbnZhcmlhbnQoIW1hbmlmZXN0W2lkXSwgXCJGb3VuZCBhIHJvdXRlIGlkIGNvbGxpc2lvbiBvbiBpZCBcXFwiXCIgKyBpZCArIFwiXFxcIi4gIFJvdXRlIFwiICsgXCJpZCdzIG11c3QgYmUgZ2xvYmFsbHkgdW5pcXVlIHdpdGhpbiBEYXRhIFJvdXRlciB1c2FnZXNcIik7XG4gICAgaWYgKGlzSW5kZXhSb3V0ZShyb3V0ZSkpIHtcbiAgICAgIGxldCBpbmRleFJvdXRlID0gX2V4dGVuZHMoe30sIHJvdXRlLCBtYXBSb3V0ZVByb3BlcnRpZXMocm91dGUpLCB7XG4gICAgICAgIGlkXG4gICAgICB9KTtcbiAgICAgIG1hbmlmZXN0W2lkXSA9IGluZGV4Um91dGU7XG4gICAgICByZXR1cm4gaW5kZXhSb3V0ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHBhdGhPckxheW91dFJvdXRlID0gX2V4dGVuZHMoe30sIHJvdXRlLCBtYXBSb3V0ZVByb3BlcnRpZXMocm91dGUpLCB7XG4gICAgICAgIGlkLFxuICAgICAgICBjaGlsZHJlbjogdW5kZWZpbmVkXG4gICAgICB9KTtcbiAgICAgIG1hbmlmZXN0W2lkXSA9IHBhdGhPckxheW91dFJvdXRlO1xuICAgICAgaWYgKHJvdXRlLmNoaWxkcmVuKSB7XG4gICAgICAgIHBhdGhPckxheW91dFJvdXRlLmNoaWxkcmVuID0gY29udmVydFJvdXRlc1RvRGF0YVJvdXRlcyhyb3V0ZS5jaGlsZHJlbiwgbWFwUm91dGVQcm9wZXJ0aWVzLCB0cmVlUGF0aCwgbWFuaWZlc3QpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHBhdGhPckxheW91dFJvdXRlO1xuICAgIH1cbiAgfSk7XG59XG4vKipcbiAqIE1hdGNoZXMgdGhlIGdpdmVuIHJvdXRlcyB0byBhIGxvY2F0aW9uIGFuZCByZXR1cm5zIHRoZSBtYXRjaCBkYXRhLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9yZWFjdHJvdXRlci5jb20vdXRpbHMvbWF0Y2gtcm91dGVzXG4gKi9cbmZ1bmN0aW9uIG1hdGNoUm91dGVzKHJvdXRlcywgbG9jYXRpb25BcmcsIGJhc2VuYW1lKSB7XG4gIGlmIChiYXNlbmFtZSA9PT0gdm9pZCAwKSB7XG4gICAgYmFzZW5hbWUgPSBcIi9cIjtcbiAgfVxuICBsZXQgbG9jYXRpb24gPSB0eXBlb2YgbG9jYXRpb25BcmcgPT09IFwic3RyaW5nXCIgPyBwYXJzZVBhdGgobG9jYXRpb25BcmcpIDogbG9jYXRpb25Bcmc7XG4gIGxldCBwYXRobmFtZSA9IHN0cmlwQmFzZW5hbWUobG9jYXRpb24ucGF0aG5hbWUgfHwgXCIvXCIsIGJhc2VuYW1lKTtcbiAgaWYgKHBhdGhuYW1lID09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBsZXQgYnJhbmNoZXMgPSBmbGF0dGVuUm91dGVzKHJvdXRlcyk7XG4gIHJhbmtSb3V0ZUJyYW5jaGVzKGJyYW5jaGVzKTtcbiAgbGV0IG1hdGNoZXMgPSBudWxsO1xuICBmb3IgKGxldCBpID0gMDsgbWF0Y2hlcyA9PSBudWxsICYmIGkgPCBicmFuY2hlcy5sZW5ndGg7ICsraSkge1xuICAgIG1hdGNoZXMgPSBtYXRjaFJvdXRlQnJhbmNoKGJyYW5jaGVzW2ldLFxuICAgIC8vIEluY29taW5nIHBhdGhuYW1lcyBhcmUgZ2VuZXJhbGx5IGVuY29kZWQgZnJvbSBlaXRoZXIgd2luZG93LmxvY2F0aW9uXG4gICAgLy8gb3IgZnJvbSByb3V0ZXIubmF2aWdhdGUsIGJ1dCB3ZSB3YW50IHRvIG1hdGNoIGFnYWluc3QgdGhlIHVuZW5jb2RlZFxuICAgIC8vIHBhdGhzIGluIHRoZSByb3V0ZSBkZWZpbml0aW9ucy4gIE1lbW9yeSByb3V0ZXIgbG9jYXRpb25zIHdvbid0IGJlXG4gICAgLy8gZW5jb2RlZCBoZXJlIGJ1dCB0aGVyZSBhbHNvIHNob3VsZG4ndCBiZSBhbnl0aGluZyB0byBkZWNvZGUgc28gdGhpc1xuICAgIC8vIHNob3VsZCBiZSBhIHNhZmUgb3BlcmF0aW9uLiAgVGhpcyBhdm9pZHMgbmVlZGluZyBtYXRjaFJvdXRlcyB0byBiZVxuICAgIC8vIGhpc3RvcnktYXdhcmUuXG4gICAgc2FmZWx5RGVjb2RlVVJJKHBhdGhuYW1lKSk7XG4gIH1cbiAgcmV0dXJuIG1hdGNoZXM7XG59XG5mdW5jdGlvbiBmbGF0dGVuUm91dGVzKHJvdXRlcywgYnJhbmNoZXMsIHBhcmVudHNNZXRhLCBwYXJlbnRQYXRoKSB7XG4gIGlmIChicmFuY2hlcyA9PT0gdm9pZCAwKSB7XG4gICAgYnJhbmNoZXMgPSBbXTtcbiAgfVxuICBpZiAocGFyZW50c01ldGEgPT09IHZvaWQgMCkge1xuICAgIHBhcmVudHNNZXRhID0gW107XG4gIH1cbiAgaWYgKHBhcmVudFBhdGggPT09IHZvaWQgMCkge1xuICAgIHBhcmVudFBhdGggPSBcIlwiO1xuICB9XG4gIGxldCBmbGF0dGVuUm91dGUgPSAocm91dGUsIGluZGV4LCByZWxhdGl2ZVBhdGgpID0+IHtcbiAgICBsZXQgbWV0YSA9IHtcbiAgICAgIHJlbGF0aXZlUGF0aDogcmVsYXRpdmVQYXRoID09PSB1bmRlZmluZWQgPyByb3V0ZS5wYXRoIHx8IFwiXCIgOiByZWxhdGl2ZVBhdGgsXG4gICAgICBjYXNlU2Vuc2l0aXZlOiByb3V0ZS5jYXNlU2Vuc2l0aXZlID09PSB0cnVlLFxuICAgICAgY2hpbGRyZW5JbmRleDogaW5kZXgsXG4gICAgICByb3V0ZVxuICAgIH07XG4gICAgaWYgKG1ldGEucmVsYXRpdmVQYXRoLnN0YXJ0c1dpdGgoXCIvXCIpKSB7XG4gICAgICBpbnZhcmlhbnQobWV0YS5yZWxhdGl2ZVBhdGguc3RhcnRzV2l0aChwYXJlbnRQYXRoKSwgXCJBYnNvbHV0ZSByb3V0ZSBwYXRoIFxcXCJcIiArIG1ldGEucmVsYXRpdmVQYXRoICsgXCJcXFwiIG5lc3RlZCB1bmRlciBwYXRoIFwiICsgKFwiXFxcIlwiICsgcGFyZW50UGF0aCArIFwiXFxcIiBpcyBub3QgdmFsaWQuIEFuIGFic29sdXRlIGNoaWxkIHJvdXRlIHBhdGggXCIpICsgXCJtdXN0IHN0YXJ0IHdpdGggdGhlIGNvbWJpbmVkIHBhdGggb2YgYWxsIGl0cyBwYXJlbnQgcm91dGVzLlwiKTtcbiAgICAgIG1ldGEucmVsYXRpdmVQYXRoID0gbWV0YS5yZWxhdGl2ZVBhdGguc2xpY2UocGFyZW50UGF0aC5sZW5ndGgpO1xuICAgIH1cbiAgICBsZXQgcGF0aCA9IGpvaW5QYXRocyhbcGFyZW50UGF0aCwgbWV0YS5yZWxhdGl2ZVBhdGhdKTtcbiAgICBsZXQgcm91dGVzTWV0YSA9IHBhcmVudHNNZXRhLmNvbmNhdChtZXRhKTtcbiAgICAvLyBBZGQgdGhlIGNoaWxkcmVuIGJlZm9yZSBhZGRpbmcgdGhpcyByb3V0ZSB0byB0aGUgYXJyYXkgc28gd2UgdHJhdmVyc2UgdGhlXG4gICAgLy8gcm91dGUgdHJlZSBkZXB0aC1maXJzdCBhbmQgY2hpbGQgcm91dGVzIGFwcGVhciBiZWZvcmUgdGhlaXIgcGFyZW50cyBpblxuICAgIC8vIHRoZSBcImZsYXR0ZW5lZFwiIHZlcnNpb24uXG4gICAgaWYgKHJvdXRlLmNoaWxkcmVuICYmIHJvdXRlLmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgIGludmFyaWFudChcbiAgICAgIC8vIE91ciB0eXBlcyBrbm93IGJldHRlciwgYnV0IHJ1bnRpbWUgSlMgbWF5IG5vdCFcbiAgICAgIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgICAgIHJvdXRlLmluZGV4ICE9PSB0cnVlLCBcIkluZGV4IHJvdXRlcyBtdXN0IG5vdCBoYXZlIGNoaWxkIHJvdXRlcy4gUGxlYXNlIHJlbW92ZSBcIiArIChcImFsbCBjaGlsZCByb3V0ZXMgZnJvbSByb3V0ZSBwYXRoIFxcXCJcIiArIHBhdGggKyBcIlxcXCIuXCIpKTtcbiAgICAgIGZsYXR0ZW5Sb3V0ZXMocm91dGUuY2hpbGRyZW4sIGJyYW5jaGVzLCByb3V0ZXNNZXRhLCBwYXRoKTtcbiAgICB9XG4gICAgLy8gUm91dGVzIHdpdGhvdXQgYSBwYXRoIHNob3VsZG4ndCBldmVyIG1hdGNoIGJ5IHRoZW1zZWx2ZXMgdW5sZXNzIHRoZXkgYXJlXG4gICAgLy8gaW5kZXggcm91dGVzLCBzbyBkb24ndCBhZGQgdGhlbSB0byB0aGUgbGlzdCBvZiBwb3NzaWJsZSBicmFuY2hlcy5cbiAgICBpZiAocm91dGUucGF0aCA9PSBudWxsICYmICFyb3V0ZS5pbmRleCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBicmFuY2hlcy5wdXNoKHtcbiAgICAgIHBhdGgsXG4gICAgICBzY29yZTogY29tcHV0ZVNjb3JlKHBhdGgsIHJvdXRlLmluZGV4KSxcbiAgICAgIHJvdXRlc01ldGFcbiAgICB9KTtcbiAgfTtcbiAgcm91dGVzLmZvckVhY2goKHJvdXRlLCBpbmRleCkgPT4ge1xuICAgIHZhciBfcm91dGUkcGF0aDtcbiAgICAvLyBjb2Fyc2UtZ3JhaW4gY2hlY2sgZm9yIG9wdGlvbmFsIHBhcmFtc1xuICAgIGlmIChyb3V0ZS5wYXRoID09PSBcIlwiIHx8ICEoKF9yb3V0ZSRwYXRoID0gcm91dGUucGF0aCkgIT0gbnVsbCAmJiBfcm91dGUkcGF0aC5pbmNsdWRlcyhcIj9cIikpKSB7XG4gICAgICBmbGF0dGVuUm91dGUocm91dGUsIGluZGV4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgZm9yIChsZXQgZXhwbG9kZWQgb2YgZXhwbG9kZU9wdGlvbmFsU2VnbWVudHMocm91dGUucGF0aCkpIHtcbiAgICAgICAgZmxhdHRlblJvdXRlKHJvdXRlLCBpbmRleCwgZXhwbG9kZWQpO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHJldHVybiBicmFuY2hlcztcbn1cbi8qKlxuICogQ29tcHV0ZXMgYWxsIGNvbWJpbmF0aW9ucyBvZiBvcHRpb25hbCBwYXRoIHNlZ21lbnRzIGZvciBhIGdpdmVuIHBhdGgsXG4gKiBleGNsdWRpbmcgY29tYmluYXRpb25zIHRoYXQgYXJlIGFtYmlndW91cyBhbmQgb2YgbG93ZXIgcHJpb3JpdHkuXG4gKlxuICogRm9yIGV4YW1wbGUsIGAvb25lLzp0d28/L3RocmVlLzpmb3VyPy86Zml2ZT9gIGV4cGxvZGVzIHRvOlxuICogLSBgL29uZS90aHJlZWBcbiAqIC0gYC9vbmUvOnR3by90aHJlZWBcbiAqIC0gYC9vbmUvdGhyZWUvOmZvdXJgXG4gKiAtIGAvb25lL3RocmVlLzpmaXZlYFxuICogLSBgL29uZS86dHdvL3RocmVlLzpmb3VyYFxuICogLSBgL29uZS86dHdvL3RocmVlLzpmaXZlYFxuICogLSBgL29uZS90aHJlZS86Zm91ci86Zml2ZWBcbiAqIC0gYC9vbmUvOnR3by90aHJlZS86Zm91ci86Zml2ZWBcbiAqL1xuZnVuY3Rpb24gZXhwbG9kZU9wdGlvbmFsU2VnbWVudHMocGF0aCkge1xuICBsZXQgc2VnbWVudHMgPSBwYXRoLnNwbGl0KFwiL1wiKTtcbiAgaWYgKHNlZ21lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIFtdO1xuICBsZXQgW2ZpcnN0LCAuLi5yZXN0XSA9IHNlZ21lbnRzO1xuICAvLyBPcHRpb25hbCBwYXRoIHNlZ21lbnRzIGFyZSBkZW5vdGVkIGJ5IGEgdHJhaWxpbmcgYD9gXG4gIGxldCBpc09wdGlvbmFsID0gZmlyc3QuZW5kc1dpdGgoXCI/XCIpO1xuICAvLyBDb21wdXRlIHRoZSBjb3JyZXNwb25kaW5nIHJlcXVpcmVkIHNlZ21lbnQ6IGBmb28/YCAtPiBgZm9vYFxuICBsZXQgcmVxdWlyZWQgPSBmaXJzdC5yZXBsYWNlKC9cXD8kLywgXCJcIik7XG4gIGlmIChyZXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIEludGVwcmV0IGVtcHR5IHN0cmluZyBhcyBvbWl0dGluZyBhbiBvcHRpb25hbCBzZWdtZW50XG4gICAgLy8gYFtcIm9uZVwiLCBcIlwiLCBcInRocmVlXCJdYCBjb3JyZXNwb25kcyB0byBvbWl0dGluZyBgOnR3b2AgZnJvbSBgL29uZS86dHdvPy90aHJlZWAgLT4gYC9vbmUvdGhyZWVgXG4gICAgcmV0dXJuIGlzT3B0aW9uYWwgPyBbcmVxdWlyZWQsIFwiXCJdIDogW3JlcXVpcmVkXTtcbiAgfVxuICBsZXQgcmVzdEV4cGxvZGVkID0gZXhwbG9kZU9wdGlvbmFsU2VnbWVudHMocmVzdC5qb2luKFwiL1wiKSk7XG4gIGxldCByZXN1bHQgPSBbXTtcbiAgLy8gQWxsIGNoaWxkIHBhdGhzIHdpdGggdGhlIHByZWZpeC4gIERvIHRoaXMgZm9yIGFsbCBjaGlsZHJlbiBiZWZvcmUgdGhlXG4gIC8vIG9wdGlvbmFsIHZlcnNpb24gZm9yIGFsbCBjaGlsZHJlbiBzbyB3ZSBnZXQgY29uc2lzdGVudCBvcmRlcmluZyB3aGVyZSB0aGVcbiAgLy8gcGFyZW50IG9wdGlvbmFsIGFzcGVjdCBpcyBwcmVmZXJyZWQgYXMgcmVxdWlyZWQuICBPdGhlcndpc2UsIHdlIGNhbiBnZXRcbiAgLy8gY2hpbGQgc2VjdGlvbnMgaW50ZXJzcGVyc2VkIHdoZXJlIGRlZXBlciBvcHRpb25hbCBzZWdtZW50cyBhcmUgaGlnaGVyIHRoYW5cbiAgLy8gcGFyZW50IG9wdGlvbmFsIHNlZ21lbnRzLCB3aGVyZSBmb3IgZXhhbXBsZSwgLzp0d28gd291bGQgZXhwbG9kZXMgX2VhcmxpZXJfXG4gIC8vIHRoZW4gLzpvbmUuICBCeSBhbHdheXMgaW5jbHVkaW5nIHRoZSBwYXJlbnQgYXMgcmVxdWlyZWQgX2ZvciBhbGwgY2hpbGRyZW5fXG4gIC8vIGZpcnN0LCB3ZSBhdm9pZCB0aGlzIGlzc3VlXG4gIHJlc3VsdC5wdXNoKC4uLnJlc3RFeHBsb2RlZC5tYXAoc3VicGF0aCA9PiBzdWJwYXRoID09PSBcIlwiID8gcmVxdWlyZWQgOiBbcmVxdWlyZWQsIHN1YnBhdGhdLmpvaW4oXCIvXCIpKSk7XG4gIC8vIFRoZW4gaWYgdGhpcyBpcyBhbiBvcHRpb25hbCB2YWx1ZSwgYWRkIGFsbCBjaGlsZCB2ZXJzaW9ucyB3aXRob3V0XG4gIGlmIChpc09wdGlvbmFsKSB7XG4gICAgcmVzdWx0LnB1c2goLi4ucmVzdEV4cGxvZGVkKTtcbiAgfVxuICAvLyBmb3IgYWJzb2x1dGUgcGF0aHMsIGVuc3VyZSBgL2AgaW5zdGVhZCBvZiBlbXB0eSBzZWdtZW50XG4gIHJldHVybiByZXN1bHQubWFwKGV4cGxvZGVkID0+IHBhdGguc3RhcnRzV2l0aChcIi9cIikgJiYgZXhwbG9kZWQgPT09IFwiXCIgPyBcIi9cIiA6IGV4cGxvZGVkKTtcbn1cbmZ1bmN0aW9uIHJhbmtSb3V0ZUJyYW5jaGVzKGJyYW5jaGVzKSB7XG4gIGJyYW5jaGVzLnNvcnQoKGEsIGIpID0+IGEuc2NvcmUgIT09IGIuc2NvcmUgPyBiLnNjb3JlIC0gYS5zY29yZSAvLyBIaWdoZXIgc2NvcmUgZmlyc3RcbiAgOiBjb21wYXJlSW5kZXhlcyhhLnJvdXRlc01ldGEubWFwKG1ldGEgPT4gbWV0YS5jaGlsZHJlbkluZGV4KSwgYi5yb3V0ZXNNZXRhLm1hcChtZXRhID0+IG1ldGEuY2hpbGRyZW5JbmRleCkpKTtcbn1cbmNvbnN0IHBhcmFtUmUgPSAvXjpcXHcrJC87XG5jb25zdCBkeW5hbWljU2VnbWVudFZhbHVlID0gMztcbmNvbnN0IGluZGV4Um91dGVWYWx1ZSA9IDI7XG5jb25zdCBlbXB0eVNlZ21lbnRWYWx1ZSA9IDE7XG5jb25zdCBzdGF0aWNTZWdtZW50VmFsdWUgPSAxMDtcbmNvbnN0IHNwbGF0UGVuYWx0eSA9IC0yO1xuY29uc3QgaXNTcGxhdCA9IHMgPT4gcyA9PT0gXCIqXCI7XG5mdW5jdGlvbiBjb21wdXRlU2NvcmUocGF0aCwgaW5kZXgpIHtcbiAgbGV0IHNlZ21lbnRzID0gcGF0aC5zcGxpdChcIi9cIik7XG4gIGxldCBpbml0aWFsU2NvcmUgPSBzZWdtZW50cy5sZW5ndGg7XG4gIGlmIChzZWdtZW50cy5zb21lKGlzU3BsYXQpKSB7XG4gICAgaW5pdGlhbFNjb3JlICs9IHNwbGF0UGVuYWx0eTtcbiAgfVxuICBpZiAoaW5kZXgpIHtcbiAgICBpbml0aWFsU2NvcmUgKz0gaW5kZXhSb3V0ZVZhbHVlO1xuICB9XG4gIHJldHVybiBzZWdtZW50cy5maWx0ZXIocyA9PiAhaXNTcGxhdChzKSkucmVkdWNlKChzY29yZSwgc2VnbWVudCkgPT4gc2NvcmUgKyAocGFyYW1SZS50ZXN0KHNlZ21lbnQpID8gZHluYW1pY1NlZ21lbnRWYWx1ZSA6IHNlZ21lbnQgPT09IFwiXCIgPyBlbXB0eVNlZ21lbnRWYWx1ZSA6IHN0YXRpY1NlZ21lbnRWYWx1ZSksIGluaXRpYWxTY29yZSk7XG59XG5mdW5jdGlvbiBjb21wYXJlSW5kZXhlcyhhLCBiKSB7XG4gIGxldCBzaWJsaW5ncyA9IGEubGVuZ3RoID09PSBiLmxlbmd0aCAmJiBhLnNsaWNlKDAsIC0xKS5ldmVyeSgobiwgaSkgPT4gbiA9PT0gYltpXSk7XG4gIHJldHVybiBzaWJsaW5ncyA/XG4gIC8vIElmIHR3byByb3V0ZXMgYXJlIHNpYmxpbmdzLCB3ZSBzaG91bGQgdHJ5IHRvIG1hdGNoIHRoZSBlYXJsaWVyIHNpYmxpbmdcbiAgLy8gZmlyc3QuIFRoaXMgYWxsb3dzIHBlb3BsZSB0byBoYXZlIGZpbmUtZ3JhaW5lZCBjb250cm9sIG92ZXIgdGhlIG1hdGNoaW5nXG4gIC8vIGJlaGF2aW9yIGJ5IHNpbXBseSBwdXR0aW5nIHJvdXRlcyB3aXRoIGlkZW50aWNhbCBwYXRocyBpbiB0aGUgb3JkZXIgdGhleVxuICAvLyB3YW50IHRoZW0gdHJpZWQuXG4gIGFbYS5sZW5ndGggLSAxXSAtIGJbYi5sZW5ndGggLSAxXSA6XG4gIC8vIE90aGVyd2lzZSwgaXQgZG9lc24ndCByZWFsbHkgbWFrZSBzZW5zZSB0byByYW5rIG5vbi1zaWJsaW5ncyBieSBpbmRleCxcbiAgLy8gc28gdGhleSBzb3J0IGVxdWFsbHkuXG4gIDA7XG59XG5mdW5jdGlvbiBtYXRjaFJvdXRlQnJhbmNoKGJyYW5jaCwgcGF0aG5hbWUpIHtcbiAgbGV0IHtcbiAgICByb3V0ZXNNZXRhXG4gIH0gPSBicmFuY2g7XG4gIGxldCBtYXRjaGVkUGFyYW1zID0ge307XG4gIGxldCBtYXRjaGVkUGF0aG5hbWUgPSBcIi9cIjtcbiAgbGV0IG1hdGNoZXMgPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3V0ZXNNZXRhLmxlbmd0aDsgKytpKSB7XG4gICAgbGV0IG1ldGEgPSByb3V0ZXNNZXRhW2ldO1xuICAgIGxldCBlbmQgPSBpID09PSByb3V0ZXNNZXRhLmxlbmd0aCAtIDE7XG4gICAgbGV0IHJlbWFpbmluZ1BhdGhuYW1lID0gbWF0Y2hlZFBhdGhuYW1lID09PSBcIi9cIiA/IHBhdGhuYW1lIDogcGF0aG5hbWUuc2xpY2UobWF0Y2hlZFBhdGhuYW1lLmxlbmd0aCkgfHwgXCIvXCI7XG4gICAgbGV0IG1hdGNoID0gbWF0Y2hQYXRoKHtcbiAgICAgIHBhdGg6IG1ldGEucmVsYXRpdmVQYXRoLFxuICAgICAgY2FzZVNlbnNpdGl2ZTogbWV0YS5jYXNlU2Vuc2l0aXZlLFxuICAgICAgZW5kXG4gICAgfSwgcmVtYWluaW5nUGF0aG5hbWUpO1xuICAgIGlmICghbWF0Y2gpIHJldHVybiBudWxsO1xuICAgIE9iamVjdC5hc3NpZ24obWF0Y2hlZFBhcmFtcywgbWF0Y2gucGFyYW1zKTtcbiAgICBsZXQgcm91dGUgPSBtZXRhLnJvdXRlO1xuICAgIG1hdGNoZXMucHVzaCh7XG4gICAgICAvLyBUT0RPOiBDYW4gdGhpcyBhcyBiZSBhdm9pZGVkP1xuICAgICAgcGFyYW1zOiBtYXRjaGVkUGFyYW1zLFxuICAgICAgcGF0aG5hbWU6IGpvaW5QYXRocyhbbWF0Y2hlZFBhdGhuYW1lLCBtYXRjaC5wYXRobmFtZV0pLFxuICAgICAgcGF0aG5hbWVCYXNlOiBub3JtYWxpemVQYXRobmFtZShqb2luUGF0aHMoW21hdGNoZWRQYXRobmFtZSwgbWF0Y2gucGF0aG5hbWVCYXNlXSkpLFxuICAgICAgcm91dGVcbiAgICB9KTtcbiAgICBpZiAobWF0Y2gucGF0aG5hbWVCYXNlICE9PSBcIi9cIikge1xuICAgICAgbWF0Y2hlZFBhdGhuYW1lID0gam9pblBhdGhzKFttYXRjaGVkUGF0aG5hbWUsIG1hdGNoLnBhdGhuYW1lQmFzZV0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbWF0Y2hlcztcbn1cbi8qKlxuICogUmV0dXJucyBhIHBhdGggd2l0aCBwYXJhbXMgaW50ZXJwb2xhdGVkLlxuICpcbiAqIEBzZWUgaHR0cHM6Ly9yZWFjdHJvdXRlci5jb20vdXRpbHMvZ2VuZXJhdGUtcGF0aFxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZVBhdGgob3JpZ2luYWxQYXRoLCBwYXJhbXMpIHtcbiAgaWYgKHBhcmFtcyA9PT0gdm9pZCAwKSB7XG4gICAgcGFyYW1zID0ge307XG4gIH1cbiAgbGV0IHBhdGggPSBvcmlnaW5hbFBhdGg7XG4gIGlmIChwYXRoLmVuZHNXaXRoKFwiKlwiKSAmJiBwYXRoICE9PSBcIipcIiAmJiAhcGF0aC5lbmRzV2l0aChcIi8qXCIpKSB7XG4gICAgd2FybmluZyhmYWxzZSwgXCJSb3V0ZSBwYXRoIFxcXCJcIiArIHBhdGggKyBcIlxcXCIgd2lsbCBiZSB0cmVhdGVkIGFzIGlmIGl0IHdlcmUgXCIgKyAoXCJcXFwiXCIgKyBwYXRoLnJlcGxhY2UoL1xcKiQvLCBcIi8qXCIpICsgXCJcXFwiIGJlY2F1c2UgdGhlIGAqYCBjaGFyYWN0ZXIgbXVzdCBcIikgKyBcImFsd2F5cyBmb2xsb3cgYSBgL2AgaW4gdGhlIHBhdHRlcm4uIFRvIGdldCByaWQgb2YgdGhpcyB3YXJuaW5nLCBcIiArIChcInBsZWFzZSBjaGFuZ2UgdGhlIHJvdXRlIHBhdGggdG8gXFxcIlwiICsgcGF0aC5yZXBsYWNlKC9cXCokLywgXCIvKlwiKSArIFwiXFxcIi5cIikpO1xuICAgIHBhdGggPSBwYXRoLnJlcGxhY2UoL1xcKiQvLCBcIi8qXCIpO1xuICB9XG4gIC8vIGVuc3VyZSBgL2AgaXMgYWRkZWQgYXQgdGhlIGJlZ2lubmluZyBpZiB0aGUgcGF0aCBpcyBhYnNvbHV0ZVxuICBjb25zdCBwcmVmaXggPSBwYXRoLnN0YXJ0c1dpdGgoXCIvXCIpID8gXCIvXCIgOiBcIlwiO1xuICBjb25zdCBzdHJpbmdpZnkgPSBwID0+IHAgPT0gbnVsbCA/IFwiXCIgOiB0eXBlb2YgcCA9PT0gXCJzdHJpbmdcIiA/IHAgOiBTdHJpbmcocCk7XG4gIGNvbnN0IHNlZ21lbnRzID0gcGF0aC5zcGxpdCgvXFwvKy8pLm1hcCgoc2VnbWVudCwgaW5kZXgsIGFycmF5KSA9PiB7XG4gICAgY29uc3QgaXNMYXN0U2VnbWVudCA9IGluZGV4ID09PSBhcnJheS5sZW5ndGggLSAxO1xuICAgIC8vIG9ubHkgYXBwbHkgdGhlIHNwbGF0IGlmIGl0J3MgdGhlIGxhc3Qgc2VnbWVudFxuICAgIGlmIChpc0xhc3RTZWdtZW50ICYmIHNlZ21lbnQgPT09IFwiKlwiKSB7XG4gICAgICBjb25zdCBzdGFyID0gXCIqXCI7XG4gICAgICAvLyBBcHBseSB0aGUgc3BsYXRcbiAgICAgIHJldHVybiBzdHJpbmdpZnkocGFyYW1zW3N0YXJdKTtcbiAgICB9XG4gICAgY29uc3Qga2V5TWF0Y2ggPSBzZWdtZW50Lm1hdGNoKC9eOihcXHcrKShcXD8/KSQvKTtcbiAgICBpZiAoa2V5TWF0Y2gpIHtcbiAgICAgIGNvbnN0IFssIGtleSwgb3B0aW9uYWxdID0ga2V5TWF0Y2g7XG4gICAgICBsZXQgcGFyYW0gPSBwYXJhbXNba2V5XTtcbiAgICAgIGludmFyaWFudChvcHRpb25hbCA9PT0gXCI/XCIgfHwgcGFyYW0gIT0gbnVsbCwgXCJNaXNzaW5nIFxcXCI6XCIgKyBrZXkgKyBcIlxcXCIgcGFyYW1cIik7XG4gICAgICByZXR1cm4gc3RyaW5naWZ5KHBhcmFtKTtcbiAgICB9XG4gICAgLy8gUmVtb3ZlIGFueSBvcHRpb25hbCBtYXJrZXJzIGZyb20gb3B0aW9uYWwgc3RhdGljIHNlZ21lbnRzXG4gICAgcmV0dXJuIHNlZ21lbnQucmVwbGFjZSgvXFw/JC9nLCBcIlwiKTtcbiAgfSlcbiAgLy8gUmVtb3ZlIGVtcHR5IHNlZ21lbnRzXG4gIC5maWx0ZXIoc2VnbWVudCA9PiAhIXNlZ21lbnQpO1xuICByZXR1cm4gcHJlZml4ICsgc2VnbWVudHMuam9pbihcIi9cIik7XG59XG4vKipcbiAqIFBlcmZvcm1zIHBhdHRlcm4gbWF0Y2hpbmcgb24gYSBVUkwgcGF0aG5hbWUgYW5kIHJldHVybnMgaW5mb3JtYXRpb24gYWJvdXRcbiAqIHRoZSBtYXRjaC5cbiAqXG4gKiBAc2VlIGh0dHBzOi8vcmVhY3Ryb3V0ZXIuY29tL3V0aWxzL21hdGNoLXBhdGhcbiAqL1xuZnVuY3Rpb24gbWF0Y2hQYXRoKHBhdHRlcm4sIHBhdGhuYW1lKSB7XG4gIGlmICh0eXBlb2YgcGF0dGVybiA9PT0gXCJzdHJpbmdcIikge1xuICAgIHBhdHRlcm4gPSB7XG4gICAgICBwYXRoOiBwYXR0ZXJuLFxuICAgICAgY2FzZVNlbnNpdGl2ZTogZmFsc2UsXG4gICAgICBlbmQ6IHRydWVcbiAgICB9O1xuICB9XG4gIGxldCBbbWF0Y2hlciwgcGFyYW1OYW1lc10gPSBjb21waWxlUGF0aChwYXR0ZXJuLnBhdGgsIHBhdHRlcm4uY2FzZVNlbnNpdGl2ZSwgcGF0dGVybi5lbmQpO1xuICBsZXQgbWF0Y2ggPSBwYXRobmFtZS5tYXRjaChtYXRjaGVyKTtcbiAgaWYgKCFtYXRjaCkgcmV0dXJuIG51bGw7XG4gIGxldCBtYXRjaGVkUGF0aG5hbWUgPSBtYXRjaFswXTtcbiAgbGV0IHBhdGhuYW1lQmFzZSA9IG1hdGNoZWRQYXRobmFtZS5yZXBsYWNlKC8oLilcXC8rJC8sIFwiJDFcIik7XG4gIGxldCBjYXB0dXJlR3JvdXBzID0gbWF0Y2guc2xpY2UoMSk7XG4gIGxldCBwYXJhbXMgPSBwYXJhbU5hbWVzLnJlZHVjZSgobWVtbywgcGFyYW1OYW1lLCBpbmRleCkgPT4ge1xuICAgIC8vIFdlIG5lZWQgdG8gY29tcHV0ZSB0aGUgcGF0aG5hbWVCYXNlIGhlcmUgdXNpbmcgdGhlIHJhdyBzcGxhdCB2YWx1ZVxuICAgIC8vIGluc3RlYWQgb2YgdXNpbmcgcGFyYW1zW1wiKlwiXSBsYXRlciBiZWNhdXNlIGl0IHdpbGwgYmUgZGVjb2RlZCB0aGVuXG4gICAgaWYgKHBhcmFtTmFtZSA9PT0gXCIqXCIpIHtcbiAgICAgIGxldCBzcGxhdFZhbHVlID0gY2FwdHVyZUdyb3Vwc1tpbmRleF0gfHwgXCJcIjtcbiAgICAgIHBhdGhuYW1lQmFzZSA9IG1hdGNoZWRQYXRobmFtZS5zbGljZSgwLCBtYXRjaGVkUGF0aG5hbWUubGVuZ3RoIC0gc3BsYXRWYWx1ZS5sZW5ndGgpLnJlcGxhY2UoLyguKVxcLyskLywgXCIkMVwiKTtcbiAgICB9XG4gICAgbWVtb1twYXJhbU5hbWVdID0gc2FmZWx5RGVjb2RlVVJJQ29tcG9uZW50KGNhcHR1cmVHcm91cHNbaW5kZXhdIHx8IFwiXCIsIHBhcmFtTmFtZSk7XG4gICAgcmV0dXJuIG1lbW87XG4gIH0sIHt9KTtcbiAgcmV0dXJuIHtcbiAgICBwYXJhbXMsXG4gICAgcGF0aG5hbWU6IG1hdGNoZWRQYXRobmFtZSxcbiAgICBwYXRobmFtZUJhc2UsXG4gICAgcGF0dGVyblxuICB9O1xufVxuZnVuY3Rpb24gY29tcGlsZVBhdGgocGF0aCwgY2FzZVNlbnNpdGl2ZSwgZW5kKSB7XG4gIGlmIChjYXNlU2Vuc2l0aXZlID09PSB2b2lkIDApIHtcbiAgICBjYXNlU2Vuc2l0aXZlID0gZmFsc2U7XG4gIH1cbiAgaWYgKGVuZCA9PT0gdm9pZCAwKSB7XG4gICAgZW5kID0gdHJ1ZTtcbiAgfVxuICB3YXJuaW5nKHBhdGggPT09IFwiKlwiIHx8ICFwYXRoLmVuZHNXaXRoKFwiKlwiKSB8fCBwYXRoLmVuZHNXaXRoKFwiLypcIiksIFwiUm91dGUgcGF0aCBcXFwiXCIgKyBwYXRoICsgXCJcXFwiIHdpbGwgYmUgdHJlYXRlZCBhcyBpZiBpdCB3ZXJlIFwiICsgKFwiXFxcIlwiICsgcGF0aC5yZXBsYWNlKC9cXCokLywgXCIvKlwiKSArIFwiXFxcIiBiZWNhdXNlIHRoZSBgKmAgY2hhcmFjdGVyIG11c3QgXCIpICsgXCJhbHdheXMgZm9sbG93IGEgYC9gIGluIHRoZSBwYXR0ZXJuLiBUbyBnZXQgcmlkIG9mIHRoaXMgd2FybmluZywgXCIgKyAoXCJwbGVhc2UgY2hhbmdlIHRoZSByb3V0ZSBwYXRoIHRvIFxcXCJcIiArIHBhdGgucmVwbGFjZSgvXFwqJC8sIFwiLypcIikgKyBcIlxcXCIuXCIpKTtcbiAgbGV0IHBhcmFtTmFtZXMgPSBbXTtcbiAgbGV0IHJlZ2V4cFNvdXJjZSA9IFwiXlwiICsgcGF0aC5yZXBsYWNlKC9cXC8qXFwqPyQvLCBcIlwiKSAvLyBJZ25vcmUgdHJhaWxpbmcgLyBhbmQgLyosIHdlJ2xsIGhhbmRsZSBpdCBiZWxvd1xuICAucmVwbGFjZSgvXlxcLyovLCBcIi9cIikgLy8gTWFrZSBzdXJlIGl0IGhhcyBhIGxlYWRpbmcgL1xuICAucmVwbGFjZSgvW1xcXFwuKiteJD97fXwoKVtcXF1dL2csIFwiXFxcXCQmXCIpIC8vIEVzY2FwZSBzcGVjaWFsIHJlZ2V4IGNoYXJzXG4gIC5yZXBsYWNlKC9cXC86KFxcdyspL2csIChfLCBwYXJhbU5hbWUpID0+IHtcbiAgICBwYXJhbU5hbWVzLnB1c2gocGFyYW1OYW1lKTtcbiAgICByZXR1cm4gXCIvKFteXFxcXC9dKylcIjtcbiAgfSk7XG4gIGlmIChwYXRoLmVuZHNXaXRoKFwiKlwiKSkge1xuICAgIHBhcmFtTmFtZXMucHVzaChcIipcIik7XG4gICAgcmVnZXhwU291cmNlICs9IHBhdGggPT09IFwiKlwiIHx8IHBhdGggPT09IFwiLypcIiA/IFwiKC4qKSRcIiAvLyBBbHJlYWR5IG1hdGNoZWQgdGhlIGluaXRpYWwgLywganVzdCBtYXRjaCB0aGUgcmVzdFxuICAgIDogXCIoPzpcXFxcLyguKyl8XFxcXC8qKSRcIjsgLy8gRG9uJ3QgaW5jbHVkZSB0aGUgLyBpbiBwYXJhbXNbXCIqXCJdXG4gIH0gZWxzZSBpZiAoZW5kKSB7XG4gICAgLy8gV2hlbiBtYXRjaGluZyB0byB0aGUgZW5kLCBpZ25vcmUgdHJhaWxpbmcgc2xhc2hlc1xuICAgIHJlZ2V4cFNvdXJjZSArPSBcIlxcXFwvKiRcIjtcbiAgfSBlbHNlIGlmIChwYXRoICE9PSBcIlwiICYmIHBhdGggIT09IFwiL1wiKSB7XG4gICAgLy8gSWYgb3VyIHBhdGggaXMgbm9uLWVtcHR5IGFuZCBjb250YWlucyBhbnl0aGluZyBiZXlvbmQgYW4gaW5pdGlhbCBzbGFzaCxcbiAgICAvLyB0aGVuIHdlIGhhdmUgX3NvbWVfIGZvcm0gb2YgcGF0aCBpbiBvdXIgcmVnZXggc28gd2Ugc2hvdWxkIGV4cGVjdCB0b1xuICAgIC8vIG1hdGNoIG9ubHkgaWYgd2UgZmluZCB0aGUgZW5kIG9mIHRoaXMgcGF0aCBzZWdtZW50LiAgTG9vayBmb3IgYW4gb3B0aW9uYWxcbiAgICAvLyBub24tY2FwdHVyZWQgdHJhaWxpbmcgc2xhc2ggKHRvIG1hdGNoIGEgcG9ydGlvbiBvZiB0aGUgVVJMKSBvciB0aGUgZW5kXG4gICAgLy8gb2YgdGhlIHBhdGggKGlmIHdlJ3ZlIG1hdGNoZWQgdG8gdGhlIGVuZCkuICBXZSB1c2VkIHRvIGRvIHRoaXMgd2l0aCBhXG4gICAgLy8gd29yZCBib3VuZGFyeSBidXQgdGhhdCBnaXZlcyBmYWxzZSBwb3NpdGl2ZXMgb24gcm91dGVzIGxpa2VcbiAgICAvLyAvdXNlci1wcmVmZXJlbmNlcyBzaW5jZSBgLWAgY291bnRzIGFzIGEgd29yZCBib3VuZGFyeS5cbiAgICByZWdleHBTb3VyY2UgKz0gXCIoPzooPz1cXFxcL3wkKSlcIjtcbiAgfSBlbHNlIDtcbiAgbGV0IG1hdGNoZXIgPSBuZXcgUmVnRXhwKHJlZ2V4cFNvdXJjZSwgY2FzZVNlbnNpdGl2ZSA/IHVuZGVmaW5lZCA6IFwiaVwiKTtcbiAgcmV0dXJuIFttYXRjaGVyLCBwYXJhbU5hbWVzXTtcbn1cbmZ1bmN0aW9uIHNhZmVseURlY29kZVVSSSh2YWx1ZSkge1xuICB0cnkge1xuICAgIHJldHVybiBkZWNvZGVVUkkodmFsdWUpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHdhcm5pbmcoZmFsc2UsIFwiVGhlIFVSTCBwYXRoIFxcXCJcIiArIHZhbHVlICsgXCJcXFwiIGNvdWxkIG5vdCBiZSBkZWNvZGVkIGJlY2F1c2UgaXQgaXMgaXMgYSBcIiArIFwibWFsZm9ybWVkIFVSTCBzZWdtZW50LiBUaGlzIGlzIHByb2JhYmx5IGR1ZSB0byBhIGJhZCBwZXJjZW50IFwiICsgKFwiZW5jb2RpbmcgKFwiICsgZXJyb3IgKyBcIikuXCIpKTtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cbmZ1bmN0aW9uIHNhZmVseURlY29kZVVSSUNvbXBvbmVudCh2YWx1ZSwgcGFyYW1OYW1lKSB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGRlY29kZVVSSUNvbXBvbmVudCh2YWx1ZSk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgd2FybmluZyhmYWxzZSwgXCJUaGUgdmFsdWUgZm9yIHRoZSBVUkwgcGFyYW0gXFxcIlwiICsgcGFyYW1OYW1lICsgXCJcXFwiIHdpbGwgbm90IGJlIGRlY29kZWQgYmVjYXVzZVwiICsgKFwiIHRoZSBzdHJpbmcgXFxcIlwiICsgdmFsdWUgKyBcIlxcXCIgaXMgYSBtYWxmb3JtZWQgVVJMIHNlZ21lbnQuIFRoaXMgaXMgcHJvYmFibHlcIikgKyAoXCIgZHVlIHRvIGEgYmFkIHBlcmNlbnQgZW5jb2RpbmcgKFwiICsgZXJyb3IgKyBcIikuXCIpKTtcbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZnVuY3Rpb24gc3RyaXBCYXNlbmFtZShwYXRobmFtZSwgYmFzZW5hbWUpIHtcbiAgaWYgKGJhc2VuYW1lID09PSBcIi9cIikgcmV0dXJuIHBhdGhuYW1lO1xuICBpZiAoIXBhdGhuYW1lLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aChiYXNlbmFtZS50b0xvd2VyQ2FzZSgpKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIC8vIFdlIHdhbnQgdG8gbGVhdmUgdHJhaWxpbmcgc2xhc2ggYmVoYXZpb3IgaW4gdGhlIHVzZXIncyBjb250cm9sLCBzbyBpZiB0aGV5XG4gIC8vIHNwZWNpZnkgYSBiYXNlbmFtZSB3aXRoIGEgdHJhaWxpbmcgc2xhc2gsIHdlIHNob3VsZCBzdXBwb3J0IGl0XG4gIGxldCBzdGFydEluZGV4ID0gYmFzZW5hbWUuZW5kc1dpdGgoXCIvXCIpID8gYmFzZW5hbWUubGVuZ3RoIC0gMSA6IGJhc2VuYW1lLmxlbmd0aDtcbiAgbGV0IG5leHRDaGFyID0gcGF0aG5hbWUuY2hhckF0KHN0YXJ0SW5kZXgpO1xuICBpZiAobmV4dENoYXIgJiYgbmV4dENoYXIgIT09IFwiL1wiKSB7XG4gICAgLy8gcGF0aG5hbWUgZG9lcyBub3Qgc3RhcnQgd2l0aCBiYXNlbmFtZS9cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICByZXR1cm4gcGF0aG5hbWUuc2xpY2Uoc3RhcnRJbmRleCkgfHwgXCIvXCI7XG59XG4vKipcbiAqIFJldHVybnMgYSByZXNvbHZlZCBwYXRoIG9iamVjdCByZWxhdGl2ZSB0byB0aGUgZ2l2ZW4gcGF0aG5hbWUuXG4gKlxuICogQHNlZSBodHRwczovL3JlYWN0cm91dGVyLmNvbS91dGlscy9yZXNvbHZlLXBhdGhcbiAqL1xuZnVuY3Rpb24gcmVzb2x2ZVBhdGgodG8sIGZyb21QYXRobmFtZSkge1xuICBpZiAoZnJvbVBhdGhuYW1lID09PSB2b2lkIDApIHtcbiAgICBmcm9tUGF0aG5hbWUgPSBcIi9cIjtcbiAgfVxuICBsZXQge1xuICAgIHBhdGhuYW1lOiB0b1BhdGhuYW1lLFxuICAgIHNlYXJjaCA9IFwiXCIsXG4gICAgaGFzaCA9IFwiXCJcbiAgfSA9IHR5cGVvZiB0byA9PT0gXCJzdHJpbmdcIiA/IHBhcnNlUGF0aCh0bykgOiB0bztcbiAgbGV0IHBhdGhuYW1lID0gdG9QYXRobmFtZSA/IHRvUGF0aG5hbWUuc3RhcnRzV2l0aChcIi9cIikgPyB0b1BhdGhuYW1lIDogcmVzb2x2ZVBhdGhuYW1lKHRvUGF0aG5hbWUsIGZyb21QYXRobmFtZSkgOiBmcm9tUGF0aG5hbWU7XG4gIHJldHVybiB7XG4gICAgcGF0aG5hbWUsXG4gICAgc2VhcmNoOiBub3JtYWxpemVTZWFyY2goc2VhcmNoKSxcbiAgICBoYXNoOiBub3JtYWxpemVIYXNoKGhhc2gpXG4gIH07XG59XG5mdW5jdGlvbiByZXNvbHZlUGF0aG5hbWUocmVsYXRpdmVQYXRoLCBmcm9tUGF0aG5hbWUpIHtcbiAgbGV0IHNlZ21lbnRzID0gZnJvbVBhdGhuYW1lLnJlcGxhY2UoL1xcLyskLywgXCJcIikuc3BsaXQoXCIvXCIpO1xuICBsZXQgcmVsYXRpdmVTZWdtZW50cyA9IHJlbGF0aXZlUGF0aC5zcGxpdChcIi9cIik7XG4gIHJlbGF0aXZlU2VnbWVudHMuZm9yRWFjaChzZWdtZW50ID0+IHtcbiAgICBpZiAoc2VnbWVudCA9PT0gXCIuLlwiKSB7XG4gICAgICAvLyBLZWVwIHRoZSByb290IFwiXCIgc2VnbWVudCBzbyB0aGUgcGF0aG5hbWUgc3RhcnRzIGF0IC9cbiAgICAgIGlmIChzZWdtZW50cy5sZW5ndGggPiAxKSBzZWdtZW50cy5wb3AoKTtcbiAgICB9IGVsc2UgaWYgKHNlZ21lbnQgIT09IFwiLlwiKSB7XG4gICAgICBzZWdtZW50cy5wdXNoKHNlZ21lbnQpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBzZWdtZW50cy5sZW5ndGggPiAxID8gc2VnbWVudHMuam9pbihcIi9cIikgOiBcIi9cIjtcbn1cbmZ1bmN0aW9uIGdldEludmFsaWRQYXRoRXJyb3IoY2hhciwgZmllbGQsIGRlc3QsIHBhdGgpIHtcbiAgcmV0dXJuIFwiQ2Fubm90IGluY2x1ZGUgYSAnXCIgKyBjaGFyICsgXCInIGNoYXJhY3RlciBpbiBhIG1hbnVhbGx5IHNwZWNpZmllZCBcIiArIChcImB0by5cIiArIGZpZWxkICsgXCJgIGZpZWxkIFtcIiArIEpTT04uc3RyaW5naWZ5KHBhdGgpICsgXCJdLiAgUGxlYXNlIHNlcGFyYXRlIGl0IG91dCB0byB0aGUgXCIpICsgKFwiYHRvLlwiICsgZGVzdCArIFwiYCBmaWVsZC4gQWx0ZXJuYXRpdmVseSB5b3UgbWF5IHByb3ZpZGUgdGhlIGZ1bGwgcGF0aCBhcyBcIikgKyBcImEgc3RyaW5nIGluIDxMaW5rIHRvPVxcXCIuLi5cXFwiPiBhbmQgdGhlIHJvdXRlciB3aWxsIHBhcnNlIGl0IGZvciB5b3UuXCI7XG59XG4vKipcbiAqIEBwcml2YXRlXG4gKlxuICogV2hlbiBwcm9jZXNzaW5nIHJlbGF0aXZlIG5hdmlnYXRpb24gd2Ugd2FudCB0byBpZ25vcmUgYW5jZXN0b3Igcm91dGVzIHRoYXRcbiAqIGRvIG5vdCBjb250cmlidXRlIHRvIHRoZSBwYXRoLCBzdWNoIHRoYXQgaW5kZXgvcGF0aGxlc3MgbGF5b3V0IHJvdXRlcyBkb24ndFxuICogaW50ZXJmZXJlLlxuICpcbiAqIEZvciBleGFtcGxlLCB3aGVuIG1vdmluZyBhIHJvdXRlIGVsZW1lbnQgaW50byBhbiBpbmRleCByb3V0ZSBhbmQvb3IgYVxuICogcGF0aGxlc3MgbGF5b3V0IHJvdXRlLCByZWxhdGl2ZSBsaW5rIGJlaGF2aW9yIGNvbnRhaW5lZCB3aXRoaW4gc2hvdWxkIHN0YXlcbiAqIHRoZSBzYW1lLiAgQm90aCBvZiB0aGUgZm9sbG93aW5nIGV4YW1wbGVzIHNob3VsZCBsaW5rIGJhY2sgdG8gdGhlIHJvb3Q6XG4gKlxuICogICA8Um91dGUgcGF0aD1cIi9cIj5cbiAqICAgICA8Um91dGUgcGF0aD1cImFjY291bnRzXCIgZWxlbWVudD17PExpbmsgdG89XCIuLlwifT5cbiAqICAgPC9Sb3V0ZT5cbiAqXG4gKiAgIDxSb3V0ZSBwYXRoPVwiL1wiPlxuICogICAgIDxSb3V0ZSBwYXRoPVwiYWNjb3VudHNcIj5cbiAqICAgICAgIDxSb3V0ZSBlbGVtZW50PXs8QWNjb3VudHNMYXlvdXQgLz59PiAgICAgICAvLyA8LS0gRG9lcyBub3QgY29udHJpYnV0ZVxuICogICAgICAgICA8Um91dGUgaW5kZXggZWxlbWVudD17PExpbmsgdG89XCIuLlwifSAvPiAgLy8gPC0tIERvZXMgbm90IGNvbnRyaWJ1dGVcbiAqICAgICAgIDwvUm91dGVcbiAqICAgICA8L1JvdXRlPlxuICogICA8L1JvdXRlPlxuICovXG5mdW5jdGlvbiBnZXRQYXRoQ29udHJpYnV0aW5nTWF0Y2hlcyhtYXRjaGVzKSB7XG4gIHJldHVybiBtYXRjaGVzLmZpbHRlcigobWF0Y2gsIGluZGV4KSA9PiBpbmRleCA9PT0gMCB8fCBtYXRjaC5yb3V0ZS5wYXRoICYmIG1hdGNoLnJvdXRlLnBhdGgubGVuZ3RoID4gMCk7XG59XG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmZ1bmN0aW9uIHJlc29sdmVUbyh0b0FyZywgcm91dGVQYXRobmFtZXMsIGxvY2F0aW9uUGF0aG5hbWUsIGlzUGF0aFJlbGF0aXZlKSB7XG4gIGlmIChpc1BhdGhSZWxhdGl2ZSA9PT0gdm9pZCAwKSB7XG4gICAgaXNQYXRoUmVsYXRpdmUgPSBmYWxzZTtcbiAgfVxuICBsZXQgdG87XG4gIGlmICh0eXBlb2YgdG9BcmcgPT09IFwic3RyaW5nXCIpIHtcbiAgICB0byA9IHBhcnNlUGF0aCh0b0FyZyk7XG4gIH0gZWxzZSB7XG4gICAgdG8gPSBfZXh0ZW5kcyh7fSwgdG9BcmcpO1xuICAgIGludmFyaWFudCghdG8ucGF0aG5hbWUgfHwgIXRvLnBhdGhuYW1lLmluY2x1ZGVzKFwiP1wiKSwgZ2V0SW52YWxpZFBhdGhFcnJvcihcIj9cIiwgXCJwYXRobmFtZVwiLCBcInNlYXJjaFwiLCB0bykpO1xuICAgIGludmFyaWFudCghdG8ucGF0aG5hbWUgfHwgIXRvLnBhdGhuYW1lLmluY2x1ZGVzKFwiI1wiKSwgZ2V0SW52YWxpZFBhdGhFcnJvcihcIiNcIiwgXCJwYXRobmFtZVwiLCBcImhhc2hcIiwgdG8pKTtcbiAgICBpbnZhcmlhbnQoIXRvLnNlYXJjaCB8fCAhdG8uc2VhcmNoLmluY2x1ZGVzKFwiI1wiKSwgZ2V0SW52YWxpZFBhdGhFcnJvcihcIiNcIiwgXCJzZWFyY2hcIiwgXCJoYXNoXCIsIHRvKSk7XG4gIH1cbiAgbGV0IGlzRW1wdHlQYXRoID0gdG9BcmcgPT09IFwiXCIgfHwgdG8ucGF0aG5hbWUgPT09IFwiXCI7XG4gIGxldCB0b1BhdGhuYW1lID0gaXNFbXB0eVBhdGggPyBcIi9cIiA6IHRvLnBhdGhuYW1lO1xuICBsZXQgZnJvbTtcbiAgLy8gUm91dGluZyBpcyByZWxhdGl2ZSB0byB0aGUgY3VycmVudCBwYXRobmFtZSBpZiBleHBsaWNpdGx5IHJlcXVlc3RlZC5cbiAgLy9cbiAgLy8gSWYgYSBwYXRobmFtZSBpcyBleHBsaWNpdGx5IHByb3ZpZGVkIGluIGB0b2AsIGl0IHNob3VsZCBiZSByZWxhdGl2ZSB0byB0aGVcbiAgLy8gcm91dGUgY29udGV4dC4gVGhpcyBpcyBleHBsYWluZWQgaW4gYE5vdGUgb24gYDxMaW5rIHRvPmAgdmFsdWVzYCBpbiBvdXJcbiAgLy8gbWlncmF0aW9uIGd1aWRlIGZyb20gdjUgYXMgYSBtZWFucyBvZiBkaXNhbWJpZ3VhdGlvbiBiZXR3ZWVuIGB0b2AgdmFsdWVzXG4gIC8vIHRoYXQgYmVnaW4gd2l0aCBgL2AgYW5kIHRob3NlIHRoYXQgZG8gbm90LiBIb3dldmVyLCB0aGlzIGlzIHByb2JsZW1hdGljIGZvclxuICAvLyBgdG9gIHZhbHVlcyB0aGF0IGRvIG5vdCBwcm92aWRlIGEgcGF0aG5hbWUuIGB0b2AgY2FuIHNpbXBseSBiZSBhIHNlYXJjaCBvclxuICAvLyBoYXNoIHN0cmluZywgaW4gd2hpY2ggY2FzZSB3ZSBzaG91bGQgYXNzdW1lIHRoYXQgdGhlIG5hdmlnYXRpb24gaXMgcmVsYXRpdmVcbiAgLy8gdG8gdGhlIGN1cnJlbnQgbG9jYXRpb24ncyBwYXRobmFtZSBhbmQgKm5vdCogdGhlIHJvdXRlIHBhdGhuYW1lLlxuICBpZiAoaXNQYXRoUmVsYXRpdmUgfHwgdG9QYXRobmFtZSA9PSBudWxsKSB7XG4gICAgZnJvbSA9IGxvY2F0aW9uUGF0aG5hbWU7XG4gIH0gZWxzZSB7XG4gICAgbGV0IHJvdXRlUGF0aG5hbWVJbmRleCA9IHJvdXRlUGF0aG5hbWVzLmxlbmd0aCAtIDE7XG4gICAgaWYgKHRvUGF0aG5hbWUuc3RhcnRzV2l0aChcIi4uXCIpKSB7XG4gICAgICBsZXQgdG9TZWdtZW50cyA9IHRvUGF0aG5hbWUuc3BsaXQoXCIvXCIpO1xuICAgICAgLy8gRWFjaCBsZWFkaW5nIC4uIHNlZ21lbnQgbWVhbnMgXCJnbyB1cCBvbmUgcm91dGVcIiBpbnN0ZWFkIG9mIFwiZ28gdXAgb25lXG4gICAgICAvLyBVUkwgc2VnbWVudFwiLiAgVGhpcyBpcyBhIGtleSBkaWZmZXJlbmNlIGZyb20gaG93IDxhIGhyZWY+IHdvcmtzIGFuZCBhXG4gICAgICAvLyBtYWpvciByZWFzb24gd2UgY2FsbCB0aGlzIGEgXCJ0b1wiIHZhbHVlIGluc3RlYWQgb2YgYSBcImhyZWZcIi5cbiAgICAgIHdoaWxlICh0b1NlZ21lbnRzWzBdID09PSBcIi4uXCIpIHtcbiAgICAgICAgdG9TZWdtZW50cy5zaGlmdCgpO1xuICAgICAgICByb3V0ZVBhdGhuYW1lSW5kZXggLT0gMTtcbiAgICAgIH1cbiAgICAgIHRvLnBhdGhuYW1lID0gdG9TZWdtZW50cy5qb2luKFwiL1wiKTtcbiAgICB9XG4gICAgLy8gSWYgdGhlcmUgYXJlIG1vcmUgXCIuLlwiIHNlZ21lbnRzIHRoYW4gcGFyZW50IHJvdXRlcywgcmVzb2x2ZSByZWxhdGl2ZSB0b1xuICAgIC8vIHRoZSByb290IC8gVVJMLlxuICAgIGZyb20gPSByb3V0ZVBhdGhuYW1lSW5kZXggPj0gMCA/IHJvdXRlUGF0aG5hbWVzW3JvdXRlUGF0aG5hbWVJbmRleF0gOiBcIi9cIjtcbiAgfVxuICBsZXQgcGF0aCA9IHJlc29sdmVQYXRoKHRvLCBmcm9tKTtcbiAgLy8gRW5zdXJlIHRoZSBwYXRobmFtZSBoYXMgYSB0cmFpbGluZyBzbGFzaCBpZiB0aGUgb3JpZ2luYWwgXCJ0b1wiIGhhZCBvbmVcbiAgbGV0IGhhc0V4cGxpY2l0VHJhaWxpbmdTbGFzaCA9IHRvUGF0aG5hbWUgJiYgdG9QYXRobmFtZSAhPT0gXCIvXCIgJiYgdG9QYXRobmFtZS5lbmRzV2l0aChcIi9cIik7XG4gIC8vIE9yIGlmIHRoaXMgd2FzIGEgbGluayB0byB0aGUgY3VycmVudCBwYXRoIHdoaWNoIGhhcyBhIHRyYWlsaW5nIHNsYXNoXG4gIGxldCBoYXNDdXJyZW50VHJhaWxpbmdTbGFzaCA9IChpc0VtcHR5UGF0aCB8fCB0b1BhdGhuYW1lID09PSBcIi5cIikgJiYgbG9jYXRpb25QYXRobmFtZS5lbmRzV2l0aChcIi9cIik7XG4gIGlmICghcGF0aC5wYXRobmFtZS5lbmRzV2l0aChcIi9cIikgJiYgKGhhc0V4cGxpY2l0VHJhaWxpbmdTbGFzaCB8fCBoYXNDdXJyZW50VHJhaWxpbmdTbGFzaCkpIHtcbiAgICBwYXRoLnBhdGhuYW1lICs9IFwiL1wiO1xuICB9XG4gIHJldHVybiBwYXRoO1xufVxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiBnZXRUb1BhdGhuYW1lKHRvKSB7XG4gIC8vIEVtcHR5IHN0cmluZ3Mgc2hvdWxkIGJlIHRyZWF0ZWQgdGhlIHNhbWUgYXMgLyBwYXRoc1xuICByZXR1cm4gdG8gPT09IFwiXCIgfHwgdG8ucGF0aG5hbWUgPT09IFwiXCIgPyBcIi9cIiA6IHR5cGVvZiB0byA9PT0gXCJzdHJpbmdcIiA/IHBhcnNlUGF0aCh0bykucGF0aG5hbWUgOiB0by5wYXRobmFtZTtcbn1cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuY29uc3Qgam9pblBhdGhzID0gcGF0aHMgPT4gcGF0aHMuam9pbihcIi9cIikucmVwbGFjZSgvXFwvXFwvKy9nLCBcIi9cIik7XG4vKipcbiAqIEBwcml2YXRlXG4gKi9cbmNvbnN0IG5vcm1hbGl6ZVBhdGhuYW1lID0gcGF0aG5hbWUgPT4gcGF0aG5hbWUucmVwbGFjZSgvXFwvKyQvLCBcIlwiKS5yZXBsYWNlKC9eXFwvKi8sIFwiL1wiKTtcbi8qKlxuICogQHByaXZhdGVcbiAqL1xuY29uc3Qgbm9ybWFsaXplU2VhcmNoID0gc2VhcmNoID0+ICFzZWFyY2ggfHwgc2VhcmNoID09PSBcIj9cIiA/IFwiXCIgOiBzZWFyY2guc3RhcnRzV2l0aChcIj9cIikgPyBzZWFyY2ggOiBcIj9cIiArIHNlYXJjaDtcbi8qKlxuICogQHByaXZhdGVcbiAqL1xuY29uc3Qgbm9ybWFsaXplSGFzaCA9IGhhc2ggPT4gIWhhc2ggfHwgaGFzaCA9PT0gXCIjXCIgPyBcIlwiIDogaGFzaC5zdGFydHNXaXRoKFwiI1wiKSA/IGhhc2ggOiBcIiNcIiArIGhhc2g7XG4vKipcbiAqIFRoaXMgaXMgYSBzaG9ydGN1dCBmb3IgY3JlYXRpbmcgYGFwcGxpY2F0aW9uL2pzb25gIHJlc3BvbnNlcy4gQ29udmVydHMgYGRhdGFgXG4gKiB0byBKU09OIGFuZCBzZXRzIHRoZSBgQ29udGVudC1UeXBlYCBoZWFkZXIuXG4gKi9cbmNvbnN0IGpzb24gPSBmdW5jdGlvbiBqc29uKGRhdGEsIGluaXQpIHtcbiAgaWYgKGluaXQgPT09IHZvaWQgMCkge1xuICAgIGluaXQgPSB7fTtcbiAgfVxuICBsZXQgcmVzcG9uc2VJbml0ID0gdHlwZW9mIGluaXQgPT09IFwibnVtYmVyXCIgPyB7XG4gICAgc3RhdHVzOiBpbml0XG4gIH0gOiBpbml0O1xuICBsZXQgaGVhZGVycyA9IG5ldyBIZWFkZXJzKHJlc3BvbnNlSW5pdC5oZWFkZXJzKTtcbiAgaWYgKCFoZWFkZXJzLmhhcyhcIkNvbnRlbnQtVHlwZVwiKSkge1xuICAgIGhlYWRlcnMuc2V0KFwiQ29udGVudC1UeXBlXCIsIFwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOFwiKTtcbiAgfVxuICByZXR1cm4gbmV3IFJlc3BvbnNlKEpTT04uc3RyaW5naWZ5KGRhdGEpLCBfZXh0ZW5kcyh7fSwgcmVzcG9uc2VJbml0LCB7XG4gICAgaGVhZGVyc1xuICB9KSk7XG59O1xuY2xhc3MgQWJvcnRlZERlZmVycmVkRXJyb3IgZXh0ZW5kcyBFcnJvciB7fVxuY2xhc3MgRGVmZXJyZWREYXRhIHtcbiAgY29uc3RydWN0b3IoZGF0YSwgcmVzcG9uc2VJbml0KSB7XG4gICAgdGhpcy5wZW5kaW5nS2V5c1NldCA9IG5ldyBTZXQoKTtcbiAgICB0aGlzLnN1YnNjcmliZXJzID0gbmV3IFNldCgpO1xuICAgIHRoaXMuZGVmZXJyZWRLZXlzID0gW107XG4gICAgaW52YXJpYW50KGRhdGEgJiYgdHlwZW9mIGRhdGEgPT09IFwib2JqZWN0XCIgJiYgIUFycmF5LmlzQXJyYXkoZGF0YSksIFwiZGVmZXIoKSBvbmx5IGFjY2VwdHMgcGxhaW4gb2JqZWN0c1wiKTtcbiAgICAvLyBTZXQgdXAgYW4gQWJvcnRDb250cm9sbGVyICsgUHJvbWlzZSB3ZSBjYW4gcmFjZSBhZ2FpbnN0IHRvIGV4aXQgZWFybHlcbiAgICAvLyBjYW5jZWxsYXRpb25cbiAgICBsZXQgcmVqZWN0O1xuICAgIHRoaXMuYWJvcnRQcm9taXNlID0gbmV3IFByb21pc2UoKF8sIHIpID0+IHJlamVjdCA9IHIpO1xuICAgIHRoaXMuY29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgICBsZXQgb25BYm9ydCA9ICgpID0+IHJlamVjdChuZXcgQWJvcnRlZERlZmVycmVkRXJyb3IoXCJEZWZlcnJlZCBkYXRhIGFib3J0ZWRcIikpO1xuICAgIHRoaXMudW5saXN0ZW5BYm9ydFNpZ25hbCA9ICgpID0+IHRoaXMuY29udHJvbGxlci5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImFib3J0XCIsIG9uQWJvcnQpO1xuICAgIHRoaXMuY29udHJvbGxlci5zaWduYWwuYWRkRXZlbnRMaXN0ZW5lcihcImFib3J0XCIsIG9uQWJvcnQpO1xuICAgIHRoaXMuZGF0YSA9IE9iamVjdC5lbnRyaWVzKGRhdGEpLnJlZHVjZSgoYWNjLCBfcmVmKSA9PiB7XG4gICAgICBsZXQgW2tleSwgdmFsdWVdID0gX3JlZjtcbiAgICAgIHJldHVybiBPYmplY3QuYXNzaWduKGFjYywge1xuICAgICAgICBba2V5XTogdGhpcy50cmFja1Byb21pc2Uoa2V5LCB2YWx1ZSlcbiAgICAgIH0pO1xuICAgIH0sIHt9KTtcbiAgICBpZiAodGhpcy5kb25lKSB7XG4gICAgICAvLyBBbGwgaW5jb21pbmcgdmFsdWVzIHdlcmUgcmVzb2x2ZWRcbiAgICAgIHRoaXMudW5saXN0ZW5BYm9ydFNpZ25hbCgpO1xuICAgIH1cbiAgICB0aGlzLmluaXQgPSByZXNwb25zZUluaXQ7XG4gIH1cbiAgdHJhY2tQcm9taXNlKGtleSwgdmFsdWUpIHtcbiAgICBpZiAoISh2YWx1ZSBpbnN0YW5jZW9mIFByb21pc2UpKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfVxuICAgIHRoaXMuZGVmZXJyZWRLZXlzLnB1c2goa2V5KTtcbiAgICB0aGlzLnBlbmRpbmdLZXlzU2V0LmFkZChrZXkpO1xuICAgIC8vIFdlIHN0b3JlIGEgbGl0dGxlIHdyYXBwZXIgcHJvbWlzZSB0aGF0IHdpbGwgYmUgZXh0ZW5kZWQgd2l0aFxuICAgIC8vIF9kYXRhL19lcnJvciBwcm9wcyB1cG9uIHJlc29sdmUvcmVqZWN0XG4gICAgbGV0IHByb21pc2UgPSBQcm9taXNlLnJhY2UoW3ZhbHVlLCB0aGlzLmFib3J0UHJvbWlzZV0pLnRoZW4oZGF0YSA9PiB0aGlzLm9uU2V0dGxlKHByb21pc2UsIGtleSwgdW5kZWZpbmVkLCBkYXRhKSwgZXJyb3IgPT4gdGhpcy5vblNldHRsZShwcm9taXNlLCBrZXksIGVycm9yKSk7XG4gICAgLy8gUmVnaXN0ZXIgcmVqZWN0aW9uIGxpc3RlbmVycyB0byBhdm9pZCB1bmNhdWdodCBwcm9taXNlIHJlamVjdGlvbnMgb25cbiAgICAvLyBlcnJvcnMgb3IgYWJvcnRlZCBkZWZlcnJlZCB2YWx1ZXNcbiAgICBwcm9taXNlLmNhdGNoKCgpID0+IHt9KTtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvbWlzZSwgXCJfdHJhY2tlZFwiLCB7XG4gICAgICBnZXQ6ICgpID0+IHRydWVcbiAgICB9KTtcbiAgICByZXR1cm4gcHJvbWlzZTtcbiAgfVxuICBvblNldHRsZShwcm9taXNlLCBrZXksIGVycm9yLCBkYXRhKSB7XG4gICAgaWYgKHRoaXMuY29udHJvbGxlci5zaWduYWwuYWJvcnRlZCAmJiBlcnJvciBpbnN0YW5jZW9mIEFib3J0ZWREZWZlcnJlZEVycm9yKSB7XG4gICAgICB0aGlzLnVubGlzdGVuQWJvcnRTaWduYWwoKTtcbiAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwcm9taXNlLCBcIl9lcnJvclwiLCB7XG4gICAgICAgIGdldDogKCkgPT4gZXJyb3JcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycm9yKTtcbiAgICB9XG4gICAgdGhpcy5wZW5kaW5nS2V5c1NldC5kZWxldGUoa2V5KTtcbiAgICBpZiAodGhpcy5kb25lKSB7XG4gICAgICAvLyBOb3RoaW5nIGxlZnQgdG8gYWJvcnQhXG4gICAgICB0aGlzLnVubGlzdGVuQWJvcnRTaWduYWwoKTtcbiAgICB9XG4gICAgLy8gSWYgdGhlIHByb21pc2Ugd2FzIHJlc29sdmVkL3JlamVjdGVkIHdpdGggdW5kZWZpbmVkLCB3ZSdsbCB0aHJvdyBhbiBlcnJvciBhcyB5b3VcbiAgICAvLyBzaG91bGQgYWx3YXlzIHJlc29sdmUgd2l0aCBhIHZhbHVlIG9yIG51bGxcbiAgICBpZiAoZXJyb3IgPT09IHVuZGVmaW5lZCAmJiBkYXRhID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGxldCB1bmRlZmluZWRFcnJvciA9IG5ldyBFcnJvcihcIkRlZmVycmVkIGRhdGEgZm9yIGtleSBcXFwiXCIgKyBrZXkgKyBcIlxcXCIgcmVzb2x2ZWQvcmVqZWN0ZWQgd2l0aCBgdW5kZWZpbmVkYCwgXCIgKyBcInlvdSBtdXN0IHJlc29sdmUvcmVqZWN0IHdpdGggYSB2YWx1ZSBvciBgbnVsbGAuXCIpO1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHByb21pc2UsIFwiX2Vycm9yXCIsIHtcbiAgICAgICAgZ2V0OiAoKSA9PiB1bmRlZmluZWRFcnJvclxuICAgICAgfSk7XG4gICAgICB0aGlzLmVtaXQoZmFsc2UsIGtleSk7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZWplY3QodW5kZWZpbmVkRXJyb3IpO1xuICAgIH1cbiAgICBpZiAoZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkocHJvbWlzZSwgXCJfZXJyb3JcIiwge1xuICAgICAgICBnZXQ6ICgpID0+IGVycm9yXG4gICAgICB9KTtcbiAgICAgIHRoaXMuZW1pdChmYWxzZSwga2V5KTtcbiAgICAgIHJldHVybiBQcm9taXNlLnJlamVjdChlcnJvcik7XG4gICAgfVxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShwcm9taXNlLCBcIl9kYXRhXCIsIHtcbiAgICAgIGdldDogKCkgPT4gZGF0YVxuICAgIH0pO1xuICAgIHRoaXMuZW1pdChmYWxzZSwga2V5KTtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuICBlbWl0KGFib3J0ZWQsIHNldHRsZWRLZXkpIHtcbiAgICB0aGlzLnN1YnNjcmliZXJzLmZvckVhY2goc3Vic2NyaWJlciA9PiBzdWJzY3JpYmVyKGFib3J0ZWQsIHNldHRsZWRLZXkpKTtcbiAgfVxuICBzdWJzY3JpYmUoZm4pIHtcbiAgICB0aGlzLnN1YnNjcmliZXJzLmFkZChmbik7XG4gICAgcmV0dXJuICgpID0+IHRoaXMuc3Vic2NyaWJlcnMuZGVsZXRlKGZuKTtcbiAgfVxuICBjYW5jZWwoKSB7XG4gICAgdGhpcy5jb250cm9sbGVyLmFib3J0KCk7XG4gICAgdGhpcy5wZW5kaW5nS2V5c1NldC5mb3JFYWNoKCh2LCBrKSA9PiB0aGlzLnBlbmRpbmdLZXlzU2V0LmRlbGV0ZShrKSk7XG4gICAgdGhpcy5lbWl0KHRydWUpO1xuICB9XG4gIGFzeW5jIHJlc29sdmVEYXRhKHNpZ25hbCkge1xuICAgIGxldCBhYm9ydGVkID0gZmFsc2U7XG4gICAgaWYgKCF0aGlzLmRvbmUpIHtcbiAgICAgIGxldCBvbkFib3J0ID0gKCkgPT4gdGhpcy5jYW5jZWwoKTtcbiAgICAgIHNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgb25BYm9ydCk7XG4gICAgICBhYm9ydGVkID0gYXdhaXQgbmV3IFByb21pc2UocmVzb2x2ZSA9PiB7XG4gICAgICAgIHRoaXMuc3Vic2NyaWJlKGFib3J0ZWQgPT4ge1xuICAgICAgICAgIHNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgb25BYm9ydCk7XG4gICAgICAgICAgaWYgKGFib3J0ZWQgfHwgdGhpcy5kb25lKSB7XG4gICAgICAgICAgICByZXNvbHZlKGFib3J0ZWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGFib3J0ZWQ7XG4gIH1cbiAgZ2V0IGRvbmUoKSB7XG4gICAgcmV0dXJuIHRoaXMucGVuZGluZ0tleXNTZXQuc2l6ZSA9PT0gMDtcbiAgfVxuICBnZXQgdW53cmFwcGVkRGF0YSgpIHtcbiAgICBpbnZhcmlhbnQodGhpcy5kYXRhICE9PSBudWxsICYmIHRoaXMuZG9uZSwgXCJDYW4gb25seSB1bndyYXAgZGF0YSBvbiBpbml0aWFsaXplZCBhbmQgc2V0dGxlZCBkZWZlcnJlZHNcIik7XG4gICAgcmV0dXJuIE9iamVjdC5lbnRyaWVzKHRoaXMuZGF0YSkucmVkdWNlKChhY2MsIF9yZWYyKSA9PiB7XG4gICAgICBsZXQgW2tleSwgdmFsdWVdID0gX3JlZjI7XG4gICAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihhY2MsIHtcbiAgICAgICAgW2tleV06IHVud3JhcFRyYWNrZWRQcm9taXNlKHZhbHVlKVxuICAgICAgfSk7XG4gICAgfSwge30pO1xuICB9XG4gIGdldCBwZW5kaW5nS2V5cygpIHtcbiAgICByZXR1cm4gQXJyYXkuZnJvbSh0aGlzLnBlbmRpbmdLZXlzU2V0KTtcbiAgfVxufVxuZnVuY3Rpb24gaXNUcmFja2VkUHJvbWlzZSh2YWx1ZSkge1xuICByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBQcm9taXNlICYmIHZhbHVlLl90cmFja2VkID09PSB0cnVlO1xufVxuZnVuY3Rpb24gdW53cmFwVHJhY2tlZFByb21pc2UodmFsdWUpIHtcbiAgaWYgKCFpc1RyYWNrZWRQcm9taXNlKHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuICBpZiAodmFsdWUuX2Vycm9yKSB7XG4gICAgdGhyb3cgdmFsdWUuX2Vycm9yO1xuICB9XG4gIHJldHVybiB2YWx1ZS5fZGF0YTtcbn1cbmNvbnN0IGRlZmVyID0gZnVuY3Rpb24gZGVmZXIoZGF0YSwgaW5pdCkge1xuICBpZiAoaW5pdCA9PT0gdm9pZCAwKSB7XG4gICAgaW5pdCA9IHt9O1xuICB9XG4gIGxldCByZXNwb25zZUluaXQgPSB0eXBlb2YgaW5pdCA9PT0gXCJudW1iZXJcIiA/IHtcbiAgICBzdGF0dXM6IGluaXRcbiAgfSA6IGluaXQ7XG4gIHJldHVybiBuZXcgRGVmZXJyZWREYXRhKGRhdGEsIHJlc3BvbnNlSW5pdCk7XG59O1xuLyoqXG4gKiBBIHJlZGlyZWN0IHJlc3BvbnNlLiBTZXRzIHRoZSBzdGF0dXMgY29kZSBhbmQgdGhlIGBMb2NhdGlvbmAgaGVhZGVyLlxuICogRGVmYXVsdHMgdG8gXCIzMDIgRm91bmRcIi5cbiAqL1xuY29uc3QgcmVkaXJlY3QgPSBmdW5jdGlvbiByZWRpcmVjdCh1cmwsIGluaXQpIHtcbiAgaWYgKGluaXQgPT09IHZvaWQgMCkge1xuICAgIGluaXQgPSAzMDI7XG4gIH1cbiAgbGV0IHJlc3BvbnNlSW5pdCA9IGluaXQ7XG4gIGlmICh0eXBlb2YgcmVzcG9uc2VJbml0ID09PSBcIm51bWJlclwiKSB7XG4gICAgcmVzcG9uc2VJbml0ID0ge1xuICAgICAgc3RhdHVzOiByZXNwb25zZUluaXRcbiAgICB9O1xuICB9IGVsc2UgaWYgKHR5cGVvZiByZXNwb25zZUluaXQuc3RhdHVzID09PSBcInVuZGVmaW5lZFwiKSB7XG4gICAgcmVzcG9uc2VJbml0LnN0YXR1cyA9IDMwMjtcbiAgfVxuICBsZXQgaGVhZGVycyA9IG5ldyBIZWFkZXJzKHJlc3BvbnNlSW5pdC5oZWFkZXJzKTtcbiAgaGVhZGVycy5zZXQoXCJMb2NhdGlvblwiLCB1cmwpO1xuICByZXR1cm4gbmV3IFJlc3BvbnNlKG51bGwsIF9leHRlbmRzKHt9LCByZXNwb25zZUluaXQsIHtcbiAgICBoZWFkZXJzXG4gIH0pKTtcbn07XG4vKipcbiAqIEEgcmVkaXJlY3QgcmVzcG9uc2UgdGhhdCB3aWxsIGZvcmNlIGEgZG9jdW1lbnQgcmVsb2FkIHRvIHRoZSBuZXcgbG9jYXRpb24uXG4gKiBTZXRzIHRoZSBzdGF0dXMgY29kZSBhbmQgdGhlIGBMb2NhdGlvbmAgaGVhZGVyLlxuICogRGVmYXVsdHMgdG8gXCIzMDIgRm91bmRcIi5cbiAqL1xuY29uc3QgcmVkaXJlY3REb2N1bWVudCA9ICh1cmwsIGluaXQpID0+IHtcbiAgbGV0IHJlc3BvbnNlID0gcmVkaXJlY3QodXJsLCBpbml0KTtcbiAgcmVzcG9uc2UuaGVhZGVycy5zZXQoXCJYLVJlbWl4LVJlbG9hZC1Eb2N1bWVudFwiLCBcInRydWVcIik7XG4gIHJldHVybiByZXNwb25zZTtcbn07XG4vKipcbiAqIEBwcml2YXRlXG4gKiBVdGlsaXR5IGNsYXNzIHdlIHVzZSB0byBob2xkIGF1dG8tdW53cmFwcGVkIDR4eC81eHggUmVzcG9uc2UgYm9kaWVzXG4gKi9cbmNsYXNzIEVycm9yUmVzcG9uc2Uge1xuICBjb25zdHJ1Y3RvcihzdGF0dXMsIHN0YXR1c1RleHQsIGRhdGEsIGludGVybmFsKSB7XG4gICAgaWYgKGludGVybmFsID09PSB2b2lkIDApIHtcbiAgICAgIGludGVybmFsID0gZmFsc2U7XG4gICAgfVxuICAgIHRoaXMuc3RhdHVzID0gc3RhdHVzO1xuICAgIHRoaXMuc3RhdHVzVGV4dCA9IHN0YXR1c1RleHQgfHwgXCJcIjtcbiAgICB0aGlzLmludGVybmFsID0gaW50ZXJuYWw7XG4gICAgaWYgKGRhdGEgaW5zdGFuY2VvZiBFcnJvcikge1xuICAgICAgdGhpcy5kYXRhID0gZGF0YS50b1N0cmluZygpO1xuICAgICAgdGhpcy5lcnJvciA9IGRhdGE7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGF0YSA9IGRhdGE7XG4gICAgfVxuICB9XG59XG4vKipcbiAqIENoZWNrIGlmIHRoZSBnaXZlbiBlcnJvciBpcyBhbiBFcnJvclJlc3BvbnNlIGdlbmVyYXRlZCBmcm9tIGEgNHh4LzV4eFxuICogUmVzcG9uc2UgdGhyb3duIGZyb20gYW4gYWN0aW9uL2xvYWRlclxuICovXG5mdW5jdGlvbiBpc1JvdXRlRXJyb3JSZXNwb25zZShlcnJvcikge1xuICByZXR1cm4gZXJyb3IgIT0gbnVsbCAmJiB0eXBlb2YgZXJyb3Iuc3RhdHVzID09PSBcIm51bWJlclwiICYmIHR5cGVvZiBlcnJvci5zdGF0dXNUZXh0ID09PSBcInN0cmluZ1wiICYmIHR5cGVvZiBlcnJvci5pbnRlcm5hbCA9PT0gXCJib29sZWFuXCIgJiYgXCJkYXRhXCIgaW4gZXJyb3I7XG59XG5cbmNvbnN0IHZhbGlkTXV0YXRpb25NZXRob2RzQXJyID0gW1wicG9zdFwiLCBcInB1dFwiLCBcInBhdGNoXCIsIFwiZGVsZXRlXCJdO1xuY29uc3QgdmFsaWRNdXRhdGlvbk1ldGhvZHMgPSBuZXcgU2V0KHZhbGlkTXV0YXRpb25NZXRob2RzQXJyKTtcbmNvbnN0IHZhbGlkUmVxdWVzdE1ldGhvZHNBcnIgPSBbXCJnZXRcIiwgLi4udmFsaWRNdXRhdGlvbk1ldGhvZHNBcnJdO1xuY29uc3QgdmFsaWRSZXF1ZXN0TWV0aG9kcyA9IG5ldyBTZXQodmFsaWRSZXF1ZXN0TWV0aG9kc0Fycik7XG5jb25zdCByZWRpcmVjdFN0YXR1c0NvZGVzID0gbmV3IFNldChbMzAxLCAzMDIsIDMwMywgMzA3LCAzMDhdKTtcbmNvbnN0IHJlZGlyZWN0UHJlc2VydmVNZXRob2RTdGF0dXNDb2RlcyA9IG5ldyBTZXQoWzMwNywgMzA4XSk7XG5jb25zdCBJRExFX05BVklHQVRJT04gPSB7XG4gIHN0YXRlOiBcImlkbGVcIixcbiAgbG9jYXRpb246IHVuZGVmaW5lZCxcbiAgZm9ybU1ldGhvZDogdW5kZWZpbmVkLFxuICBmb3JtQWN0aW9uOiB1bmRlZmluZWQsXG4gIGZvcm1FbmNUeXBlOiB1bmRlZmluZWQsXG4gIGZvcm1EYXRhOiB1bmRlZmluZWQsXG4gIGpzb246IHVuZGVmaW5lZCxcbiAgdGV4dDogdW5kZWZpbmVkXG59O1xuY29uc3QgSURMRV9GRVRDSEVSID0ge1xuICBzdGF0ZTogXCJpZGxlXCIsXG4gIGRhdGE6IHVuZGVmaW5lZCxcbiAgZm9ybU1ldGhvZDogdW5kZWZpbmVkLFxuICBmb3JtQWN0aW9uOiB1bmRlZmluZWQsXG4gIGZvcm1FbmNUeXBlOiB1bmRlZmluZWQsXG4gIGZvcm1EYXRhOiB1bmRlZmluZWQsXG4gIGpzb246IHVuZGVmaW5lZCxcbiAgdGV4dDogdW5kZWZpbmVkXG59O1xuY29uc3QgSURMRV9CTE9DS0VSID0ge1xuICBzdGF0ZTogXCJ1bmJsb2NrZWRcIixcbiAgcHJvY2VlZDogdW5kZWZpbmVkLFxuICByZXNldDogdW5kZWZpbmVkLFxuICBsb2NhdGlvbjogdW5kZWZpbmVkXG59O1xuY29uc3QgQUJTT0xVVEVfVVJMX1JFR0VYID0gL14oPzpbYS16XVthLXowLTkrLi1dKjp8XFwvXFwvKS9pO1xuY29uc3QgZGVmYXVsdE1hcFJvdXRlUHJvcGVydGllcyA9IHJvdXRlID0+ICh7XG4gIGhhc0Vycm9yQm91bmRhcnk6IEJvb2xlYW4ocm91dGUuaGFzRXJyb3JCb3VuZGFyeSlcbn0pO1xuLy8jZW5kcmVnaW9uXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLy8jcmVnaW9uIGNyZWF0ZVJvdXRlclxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8qKlxuICogQ3JlYXRlIGEgcm91dGVyIGFuZCBsaXN0ZW4gdG8gaGlzdG9yeSBQT1AgbmF2aWdhdGlvbnNcbiAqL1xuZnVuY3Rpb24gY3JlYXRlUm91dGVyKGluaXQpIHtcbiAgY29uc3Qgcm91dGVyV2luZG93ID0gaW5pdC53aW5kb3cgPyBpbml0LndpbmRvdyA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB1bmRlZmluZWQ7XG4gIGNvbnN0IGlzQnJvd3NlciA9IHR5cGVvZiByb3V0ZXJXaW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiYgdHlwZW9mIHJvdXRlcldpbmRvdy5kb2N1bWVudCAhPT0gXCJ1bmRlZmluZWRcIiAmJiB0eXBlb2Ygcm91dGVyV2luZG93LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQgIT09IFwidW5kZWZpbmVkXCI7XG4gIGNvbnN0IGlzU2VydmVyID0gIWlzQnJvd3NlcjtcbiAgaW52YXJpYW50KGluaXQucm91dGVzLmxlbmd0aCA+IDAsIFwiWW91IG11c3QgcHJvdmlkZSBhIG5vbi1lbXB0eSByb3V0ZXMgYXJyYXkgdG8gY3JlYXRlUm91dGVyXCIpO1xuICBsZXQgbWFwUm91dGVQcm9wZXJ0aWVzO1xuICBpZiAoaW5pdC5tYXBSb3V0ZVByb3BlcnRpZXMpIHtcbiAgICBtYXBSb3V0ZVByb3BlcnRpZXMgPSBpbml0Lm1hcFJvdXRlUHJvcGVydGllcztcbiAgfSBlbHNlIGlmIChpbml0LmRldGVjdEVycm9yQm91bmRhcnkpIHtcbiAgICAvLyBJZiB0aGV5IGFyZSBzdGlsbCB1c2luZyB0aGUgZGVwcmVjYXRlZCB2ZXJzaW9uLCB3cmFwIGl0IHdpdGggdGhlIG5ldyBBUElcbiAgICBsZXQgZGV0ZWN0RXJyb3JCb3VuZGFyeSA9IGluaXQuZGV0ZWN0RXJyb3JCb3VuZGFyeTtcbiAgICBtYXBSb3V0ZVByb3BlcnRpZXMgPSByb3V0ZSA9PiAoe1xuICAgICAgaGFzRXJyb3JCb3VuZGFyeTogZGV0ZWN0RXJyb3JCb3VuZGFyeShyb3V0ZSlcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICBtYXBSb3V0ZVByb3BlcnRpZXMgPSBkZWZhdWx0TWFwUm91dGVQcm9wZXJ0aWVzO1xuICB9XG4gIC8vIFJvdXRlcyBrZXllZCBieSBJRFxuICBsZXQgbWFuaWZlc3QgPSB7fTtcbiAgLy8gUm91dGVzIGluIHRyZWUgZm9ybWF0IGZvciBtYXRjaGluZ1xuICBsZXQgZGF0YVJvdXRlcyA9IGNvbnZlcnRSb3V0ZXNUb0RhdGFSb3V0ZXMoaW5pdC5yb3V0ZXMsIG1hcFJvdXRlUHJvcGVydGllcywgdW5kZWZpbmVkLCBtYW5pZmVzdCk7XG4gIGxldCBpbkZsaWdodERhdGFSb3V0ZXM7XG4gIGxldCBiYXNlbmFtZSA9IGluaXQuYmFzZW5hbWUgfHwgXCIvXCI7XG4gIC8vIENvbmZpZyBkcml2ZW4gYmVoYXZpb3IgZmxhZ3NcbiAgbGV0IGZ1dHVyZSA9IF9leHRlbmRzKHtcbiAgICB2N19ub3JtYWxpemVGb3JtTWV0aG9kOiBmYWxzZSxcbiAgICB2N19wcmVwZW5kQmFzZW5hbWU6IGZhbHNlXG4gIH0sIGluaXQuZnV0dXJlKTtcbiAgLy8gQ2xlYW51cCBmdW5jdGlvbiBmb3IgaGlzdG9yeVxuICBsZXQgdW5saXN0ZW5IaXN0b3J5ID0gbnVsbDtcbiAgLy8gRXh0ZXJuYWxseS1wcm92aWRlZCBmdW5jdGlvbnMgdG8gY2FsbCBvbiBhbGwgc3RhdGUgY2hhbmdlc1xuICBsZXQgc3Vic2NyaWJlcnMgPSBuZXcgU2V0KCk7XG4gIC8vIEV4dGVybmFsbHktcHJvdmlkZWQgb2JqZWN0IHRvIGhvbGQgc2Nyb2xsIHJlc3RvcmF0aW9uIGxvY2F0aW9ucyBkdXJpbmcgcm91dGluZ1xuICBsZXQgc2F2ZWRTY3JvbGxQb3NpdGlvbnMgPSBudWxsO1xuICAvLyBFeHRlcm5hbGx5LXByb3ZpZGVkIGZ1bmN0aW9uIHRvIGdldCBzY3JvbGwgcmVzdG9yYXRpb24ga2V5c1xuICBsZXQgZ2V0U2Nyb2xsUmVzdG9yYXRpb25LZXkgPSBudWxsO1xuICAvLyBFeHRlcm5hbGx5LXByb3ZpZGVkIGZ1bmN0aW9uIHRvIGdldCBjdXJyZW50IHNjcm9sbCBwb3NpdGlvblxuICBsZXQgZ2V0U2Nyb2xsUG9zaXRpb24gPSBudWxsO1xuICAvLyBPbmUtdGltZSBmbGFnIHRvIGNvbnRyb2wgdGhlIGluaXRpYWwgaHlkcmF0aW9uIHNjcm9sbCByZXN0b3JhdGlvbi4gIEJlY2F1c2VcbiAgLy8gd2UgZG9uJ3QgZ2V0IHRoZSBzYXZlZCBwb3NpdGlvbnMgZnJvbSA8U2Nyb2xsUmVzdG9yYXRpb24gLz4gdW50aWwgX2FmdGVyX1xuICAvLyB0aGUgaW5pdGlhbCByZW5kZXIsIHdlIG5lZWQgdG8gbWFudWFsbHkgdHJpZ2dlciBhIHNlcGFyYXRlIHVwZGF0ZVN0YXRlIHRvXG4gIC8vIHNlbmQgYWxvbmcgdGhlIHJlc3RvcmVTY3JvbGxQb3NpdGlvblxuICAvLyBTZXQgdG8gdHJ1ZSBpZiB3ZSBoYXZlIGBoeWRyYXRpb25EYXRhYCBzaW5jZSB3ZSBhc3N1bWUgd2Ugd2VyZSBTU1InZCBhbmQgdGhhdFxuICAvLyBTU1IgZGlkIHRoZSBpbml0aWFsIHNjcm9sbCByZXN0b3JhdGlvbi5cbiAgbGV0IGluaXRpYWxTY3JvbGxSZXN0b3JlZCA9IGluaXQuaHlkcmF0aW9uRGF0YSAhPSBudWxsO1xuICBsZXQgaW5pdGlhbE1hdGNoZXMgPSBtYXRjaFJvdXRlcyhkYXRhUm91dGVzLCBpbml0Lmhpc3RvcnkubG9jYXRpb24sIGJhc2VuYW1lKTtcbiAgbGV0IGluaXRpYWxFcnJvcnMgPSBudWxsO1xuICBpZiAoaW5pdGlhbE1hdGNoZXMgPT0gbnVsbCkge1xuICAgIC8vIElmIHdlIGRvIG5vdCBtYXRjaCBhIHVzZXItcHJvdmlkZWQtcm91dGUsIGZhbGwgYmFjayB0byB0aGUgcm9vdFxuICAgIC8vIHRvIGFsbG93IHRoZSBlcnJvciBib3VuZGFyeSB0byB0YWtlIG92ZXJcbiAgICBsZXQgZXJyb3IgPSBnZXRJbnRlcm5hbFJvdXRlckVycm9yKDQwNCwge1xuICAgICAgcGF0aG5hbWU6IGluaXQuaGlzdG9yeS5sb2NhdGlvbi5wYXRobmFtZVxuICAgIH0pO1xuICAgIGxldCB7XG4gICAgICBtYXRjaGVzLFxuICAgICAgcm91dGVcbiAgICB9ID0gZ2V0U2hvcnRDaXJjdWl0TWF0Y2hlcyhkYXRhUm91dGVzKTtcbiAgICBpbml0aWFsTWF0Y2hlcyA9IG1hdGNoZXM7XG4gICAgaW5pdGlhbEVycm9ycyA9IHtcbiAgICAgIFtyb3V0ZS5pZF06IGVycm9yXG4gICAgfTtcbiAgfVxuICBsZXQgaW5pdGlhbGl6ZWQgPVxuICAvLyBBbGwgaW5pdGlhbE1hdGNoZXMgbmVlZCB0byBiZSBsb2FkZWQgYmVmb3JlIHdlJ3JlIHJlYWR5LiAgSWYgd2UgaGF2ZSBsYXp5XG4gIC8vIGZ1bmN0aW9ucyBhcm91bmQgc3RpbGwgdGhlbiB3ZSdsbCBuZWVkIHRvIHJ1biB0aGVtIGluIGluaXRpYWxpemUoKVxuICAhaW5pdGlhbE1hdGNoZXMuc29tZShtID0+IG0ucm91dGUubGF6eSkgJiYgKFxuICAvLyBBbmQgd2UgaGF2ZSB0byBlaXRoZXIgaGF2ZSBubyBsb2FkZXJzIG9yIGhhdmUgYmVlbiBwcm92aWRlZCBoeWRyYXRpb25EYXRhXG4gICFpbml0aWFsTWF0Y2hlcy5zb21lKG0gPT4gbS5yb3V0ZS5sb2FkZXIpIHx8IGluaXQuaHlkcmF0aW9uRGF0YSAhPSBudWxsKTtcbiAgbGV0IHJvdXRlcjtcbiAgbGV0IHN0YXRlID0ge1xuICAgIGhpc3RvcnlBY3Rpb246IGluaXQuaGlzdG9yeS5hY3Rpb24sXG4gICAgbG9jYXRpb246IGluaXQuaGlzdG9yeS5sb2NhdGlvbixcbiAgICBtYXRjaGVzOiBpbml0aWFsTWF0Y2hlcyxcbiAgICBpbml0aWFsaXplZCxcbiAgICBuYXZpZ2F0aW9uOiBJRExFX05BVklHQVRJT04sXG4gICAgLy8gRG9uJ3QgcmVzdG9yZSBvbiBpbml0aWFsIHVwZGF0ZVN0YXRlKCkgaWYgd2Ugd2VyZSBTU1InZFxuICAgIHJlc3RvcmVTY3JvbGxQb3NpdGlvbjogaW5pdC5oeWRyYXRpb25EYXRhICE9IG51bGwgPyBmYWxzZSA6IG51bGwsXG4gICAgcHJldmVudFNjcm9sbFJlc2V0OiBmYWxzZSxcbiAgICByZXZhbGlkYXRpb246IFwiaWRsZVwiLFxuICAgIGxvYWRlckRhdGE6IGluaXQuaHlkcmF0aW9uRGF0YSAmJiBpbml0Lmh5ZHJhdGlvbkRhdGEubG9hZGVyRGF0YSB8fCB7fSxcbiAgICBhY3Rpb25EYXRhOiBpbml0Lmh5ZHJhdGlvbkRhdGEgJiYgaW5pdC5oeWRyYXRpb25EYXRhLmFjdGlvbkRhdGEgfHwgbnVsbCxcbiAgICBlcnJvcnM6IGluaXQuaHlkcmF0aW9uRGF0YSAmJiBpbml0Lmh5ZHJhdGlvbkRhdGEuZXJyb3JzIHx8IGluaXRpYWxFcnJvcnMsXG4gICAgZmV0Y2hlcnM6IG5ldyBNYXAoKSxcbiAgICBibG9ja2VyczogbmV3IE1hcCgpXG4gIH07XG4gIC8vIC0tIFN0YXRlZnVsIGludGVybmFsIHZhcmlhYmxlcyB0byBtYW5hZ2UgbmF2aWdhdGlvbnMgLS1cbiAgLy8gQ3VycmVudCBuYXZpZ2F0aW9uIGluIHByb2dyZXNzICh0byBiZSBjb21taXR0ZWQgaW4gY29tcGxldGVOYXZpZ2F0aW9uKVxuICBsZXQgcGVuZGluZ0FjdGlvbiA9IEFjdGlvbi5Qb3A7XG4gIC8vIFNob3VsZCB0aGUgY3VycmVudCBuYXZpZ2F0aW9uIHByZXZlbnQgdGhlIHNjcm9sbCByZXNldCBpZiBzY3JvbGwgY2Fubm90XG4gIC8vIGJlIHJlc3RvcmVkP1xuICBsZXQgcGVuZGluZ1ByZXZlbnRTY3JvbGxSZXNldCA9IGZhbHNlO1xuICAvLyBBYm9ydENvbnRyb2xsZXIgZm9yIHRoZSBhY3RpdmUgbmF2aWdhdGlvblxuICBsZXQgcGVuZGluZ05hdmlnYXRpb25Db250cm9sbGVyO1xuICAvLyBXZSB1c2UgdGhpcyB0byBhdm9pZCB0b3VjaGluZyBoaXN0b3J5IGluIGNvbXBsZXRlTmF2aWdhdGlvbiBpZiBhXG4gIC8vIHJldmFsaWRhdGlvbiBpcyBlbnRpcmVseSB1bmludGVycnVwdGVkXG4gIGxldCBpc1VuaW50ZXJydXB0ZWRSZXZhbGlkYXRpb24gPSBmYWxzZTtcbiAgLy8gVXNlIHRoaXMgaW50ZXJuYWwgZmxhZyB0byBmb3JjZSByZXZhbGlkYXRpb24gb2YgYWxsIGxvYWRlcnM6XG4gIC8vICAtIHN1Ym1pc3Npb25zIChjb21wbGV0ZWQgb3IgaW50ZXJydXB0ZWQpXG4gIC8vICAtIHVzZVJldmFsaWRhdG9yKClcbiAgLy8gIC0gWC1SZW1peC1SZXZhbGlkYXRlIChmcm9tIHJlZGlyZWN0KVxuICBsZXQgaXNSZXZhbGlkYXRpb25SZXF1aXJlZCA9IGZhbHNlO1xuICAvLyBVc2UgdGhpcyBpbnRlcm5hbCBhcnJheSB0byBjYXB0dXJlIHJvdXRlcyB0aGF0IHJlcXVpcmUgcmV2YWxpZGF0aW9uIGR1ZVxuICAvLyB0byBhIGNhbmNlbGxlZCBkZWZlcnJlZCBvbiBhY3Rpb24gc3VibWlzc2lvblxuICBsZXQgY2FuY2VsbGVkRGVmZXJyZWRSb3V0ZXMgPSBbXTtcbiAgLy8gVXNlIHRoaXMgaW50ZXJuYWwgYXJyYXkgdG8gY2FwdHVyZSBmZXRjaGVyIGxvYWRzIHRoYXQgd2VyZSBjYW5jZWxsZWQgYnkgYW5cbiAgLy8gYWN0aW9uIG5hdmlnYXRpb24gYW5kIHJlcXVpcmUgcmV2YWxpZGF0aW9uXG4gIGxldCBjYW5jZWxsZWRGZXRjaGVyTG9hZHMgPSBbXTtcbiAgLy8gQWJvcnRDb250cm9sbGVycyBmb3IgYW55IGluLWZsaWdodCBmZXRjaGVyc1xuICBsZXQgZmV0Y2hDb250cm9sbGVycyA9IG5ldyBNYXAoKTtcbiAgLy8gVHJhY2sgbG9hZHMgYmFzZWQgb24gdGhlIG9yZGVyIGluIHdoaWNoIHRoZXkgc3RhcnRlZFxuICBsZXQgaW5jcmVtZW50aW5nTG9hZElkID0gMDtcbiAgLy8gVHJhY2sgdGhlIG91dHN0YW5kaW5nIHBlbmRpbmcgbmF2aWdhdGlvbiBkYXRhIGxvYWQgdG8gYmUgY29tcGFyZWQgYWdhaW5zdFxuICAvLyB0aGUgZ2xvYmFsbHkgaW5jcmVtZW50aW5nIGxvYWQgd2hlbiBhIGZldGNoZXIgbG9hZCBsYW5kcyBhZnRlciBhIGNvbXBsZXRlZFxuICAvLyBuYXZpZ2F0aW9uXG4gIGxldCBwZW5kaW5nTmF2aWdhdGlvbkxvYWRJZCA9IC0xO1xuICAvLyBGZXRjaGVycyB0aGF0IHRyaWdnZXJlZCBkYXRhIHJlbG9hZHMgYXMgYSByZXN1bHQgb2YgdGhlaXIgYWN0aW9uc1xuICBsZXQgZmV0Y2hSZWxvYWRJZHMgPSBuZXcgTWFwKCk7XG4gIC8vIEZldGNoZXJzIHRoYXQgdHJpZ2dlcmVkIHJlZGlyZWN0IG5hdmlnYXRpb25zXG4gIGxldCBmZXRjaFJlZGlyZWN0SWRzID0gbmV3IFNldCgpO1xuICAvLyBNb3N0IHJlY2VudCBocmVmL21hdGNoIGZvciBmZXRjaGVyLmxvYWQgY2FsbHMgZm9yIGZldGNoZXJzXG4gIGxldCBmZXRjaExvYWRNYXRjaGVzID0gbmV3IE1hcCgpO1xuICAvLyBTdG9yZSBEZWZlcnJlZERhdGEgaW5zdGFuY2VzIGZvciBhY3RpdmUgcm91dGUgbWF0Y2hlcy4gIFdoZW4gYVxuICAvLyByb3V0ZSBsb2FkZXIgcmV0dXJucyBkZWZlcigpIHdlIHN0aWNrIG9uZSBpbiBoZXJlLiAgVGhlbiwgd2hlbiBhIG5lc3RlZFxuICAvLyBwcm9taXNlIHJlc29sdmVzIHdlIHVwZGF0ZSBsb2FkZXJEYXRhLiAgSWYgYSBuZXcgbmF2aWdhdGlvbiBzdGFydHMgd2VcbiAgLy8gY2FuY2VsIGFjdGl2ZSBkZWZlcnJlZHMgZm9yIGVsaW1pbmF0ZWQgcm91dGVzLlxuICBsZXQgYWN0aXZlRGVmZXJyZWRzID0gbmV3IE1hcCgpO1xuICAvLyBTdG9yZSBibG9ja2VyIGZ1bmN0aW9ucyBpbiBhIHNlcGFyYXRlIE1hcCBvdXRzaWRlIG9mIHJvdXRlciBzdGF0ZSBzaW5jZVxuICAvLyB3ZSBkb24ndCBuZWVkIHRvIHVwZGF0ZSBVSSBzdGF0ZSBpZiB0aGV5IGNoYW5nZVxuICBsZXQgYmxvY2tlckZ1bmN0aW9ucyA9IG5ldyBNYXAoKTtcbiAgLy8gRmxhZyB0byBpZ25vcmUgdGhlIG5leHQgaGlzdG9yeSB1cGRhdGUsIHNvIHdlIGNhbiByZXZlcnQgdGhlIFVSTCBjaGFuZ2Ugb25cbiAgLy8gYSBQT1AgbmF2aWdhdGlvbiB0aGF0IHdhcyBibG9ja2VkIGJ5IHRoZSB1c2VyIHdpdGhvdXQgdG91Y2hpbmcgcm91dGVyIHN0YXRlXG4gIGxldCBpZ25vcmVOZXh0SGlzdG9yeVVwZGF0ZSA9IGZhbHNlO1xuICAvLyBJbml0aWFsaXplIHRoZSByb3V0ZXIsIGFsbCBzaWRlIGVmZmVjdHMgc2hvdWxkIGJlIGtpY2tlZCBvZmYgZnJvbSBoZXJlLlxuICAvLyBJbXBsZW1lbnRlZCBhcyBhIEZsdWVudCBBUEkgZm9yIGVhc2Ugb2Y6XG4gIC8vICAgbGV0IHJvdXRlciA9IGNyZWF0ZVJvdXRlcihpbml0KS5pbml0aWFsaXplKCk7XG4gIGZ1bmN0aW9uIGluaXRpYWxpemUoKSB7XG4gICAgLy8gSWYgaGlzdG9yeSBpbmZvcm1zIHVzIG9mIGEgUE9QIG5hdmlnYXRpb24sIHN0YXJ0IHRoZSBuYXZpZ2F0aW9uIGJ1dCBkbyBub3QgdXBkYXRlXG4gICAgLy8gc3RhdGUuICBXZSdsbCB1cGRhdGUgb3VyIG93biBzdGF0ZSBvbmNlIHRoZSBuYXZpZ2F0aW9uIGNvbXBsZXRlc1xuICAgIHVubGlzdGVuSGlzdG9yeSA9IGluaXQuaGlzdG9yeS5saXN0ZW4oX3JlZiA9PiB7XG4gICAgICBsZXQge1xuICAgICAgICBhY3Rpb246IGhpc3RvcnlBY3Rpb24sXG4gICAgICAgIGxvY2F0aW9uLFxuICAgICAgICBkZWx0YVxuICAgICAgfSA9IF9yZWY7XG4gICAgICAvLyBJZ25vcmUgdGhpcyBldmVudCBpZiBpdCB3YXMganVzdCB1cyByZXNldHRpbmcgdGhlIFVSTCBmcm9tIGFcbiAgICAgIC8vIGJsb2NrZWQgUE9QIG5hdmlnYXRpb25cbiAgICAgIGlmIChpZ25vcmVOZXh0SGlzdG9yeVVwZGF0ZSkge1xuICAgICAgICBpZ25vcmVOZXh0SGlzdG9yeVVwZGF0ZSA9IGZhbHNlO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB3YXJuaW5nKGJsb2NrZXJGdW5jdGlvbnMuc2l6ZSA9PT0gMCB8fCBkZWx0YSAhPSBudWxsLCBcIllvdSBhcmUgdHJ5aW5nIHRvIHVzZSBhIGJsb2NrZXIgb24gYSBQT1AgbmF2aWdhdGlvbiB0byBhIGxvY2F0aW9uIFwiICsgXCJ0aGF0IHdhcyBub3QgY3JlYXRlZCBieSBAcmVtaXgtcnVuL3JvdXRlci4gVGhpcyB3aWxsIGZhaWwgc2lsZW50bHkgaW4gXCIgKyBcInByb2R1Y3Rpb24uIFRoaXMgY2FuIGhhcHBlbiBpZiB5b3UgYXJlIG5hdmlnYXRpbmcgb3V0c2lkZSB0aGUgcm91dGVyIFwiICsgXCJ2aWEgYHdpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZWAvYHdpbmRvdy5sb2NhdGlvbi5oYXNoYCBpbnN0ZWFkIG9mIHVzaW5nIFwiICsgXCJyb3V0ZXIgbmF2aWdhdGlvbiBBUElzLiAgVGhpcyBjYW4gYWxzbyBoYXBwZW4gaWYgeW91IGFyZSB1c2luZyBcIiArIFwiY3JlYXRlSGFzaFJvdXRlciBhbmQgdGhlIHVzZXIgbWFudWFsbHkgY2hhbmdlcyB0aGUgVVJMLlwiKTtcbiAgICAgIGxldCBibG9ja2VyS2V5ID0gc2hvdWxkQmxvY2tOYXZpZ2F0aW9uKHtcbiAgICAgICAgY3VycmVudExvY2F0aW9uOiBzdGF0ZS5sb2NhdGlvbixcbiAgICAgICAgbmV4dExvY2F0aW9uOiBsb2NhdGlvbixcbiAgICAgICAgaGlzdG9yeUFjdGlvblxuICAgICAgfSk7XG4gICAgICBpZiAoYmxvY2tlcktleSAmJiBkZWx0YSAhPSBudWxsKSB7XG4gICAgICAgIC8vIFJlc3RvcmUgdGhlIFVSTCB0byBtYXRjaCB0aGUgY3VycmVudCBVSSwgYnV0IGRvbid0IHVwZGF0ZSByb3V0ZXIgc3RhdGVcbiAgICAgICAgaWdub3JlTmV4dEhpc3RvcnlVcGRhdGUgPSB0cnVlO1xuICAgICAgICBpbml0Lmhpc3RvcnkuZ28oZGVsdGEgKiAtMSk7XG4gICAgICAgIC8vIFB1dCB0aGUgYmxvY2tlciBpbnRvIGEgYmxvY2tlZCBzdGF0ZVxuICAgICAgICB1cGRhdGVCbG9ja2VyKGJsb2NrZXJLZXksIHtcbiAgICAgICAgICBzdGF0ZTogXCJibG9ja2VkXCIsXG4gICAgICAgICAgbG9jYXRpb24sXG4gICAgICAgICAgcHJvY2VlZCgpIHtcbiAgICAgICAgICAgIHVwZGF0ZUJsb2NrZXIoYmxvY2tlcktleSwge1xuICAgICAgICAgICAgICBzdGF0ZTogXCJwcm9jZWVkaW5nXCIsXG4gICAgICAgICAgICAgIHByb2NlZWQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgcmVzZXQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgICAgbG9jYXRpb25cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgLy8gUmUtZG8gdGhlIHNhbWUgUE9QIG5hdmlnYXRpb24gd2UganVzdCBibG9ja2VkXG4gICAgICAgICAgICBpbml0Lmhpc3RvcnkuZ28oZGVsdGEpO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgcmVzZXQoKSB7XG4gICAgICAgICAgICBsZXQgYmxvY2tlcnMgPSBuZXcgTWFwKHN0YXRlLmJsb2NrZXJzKTtcbiAgICAgICAgICAgIGJsb2NrZXJzLnNldChibG9ja2VyS2V5LCBJRExFX0JMT0NLRVIpO1xuICAgICAgICAgICAgdXBkYXRlU3RhdGUoe1xuICAgICAgICAgICAgICBibG9ja2Vyc1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHN0YXJ0TmF2aWdhdGlvbihoaXN0b3J5QWN0aW9uLCBsb2NhdGlvbik7XG4gICAgfSk7XG4gICAgLy8gS2ljayBvZmYgaW5pdGlhbCBkYXRhIGxvYWQgaWYgbmVlZGVkLiAgVXNlIFBvcCB0byBhdm9pZCBtb2RpZnlpbmcgaGlzdG9yeVxuICAgIC8vIE5vdGUgd2UgZG9uJ3QgZG8gYW55IGhhbmRsaW5nIG9mIGxhenkgaGVyZS4gIEZvciBTUEEncyBpdCdsbCBnZXQgaGFuZGxlZFxuICAgIC8vIGluIHRoZSBub3JtYWwgbmF2aWdhdGlvbiBmbG93LiAgRm9yIFNTUiBpdCdzIGV4cGVjdGVkIHRoYXQgbGF6eSBtb2R1bGVzIGFyZVxuICAgIC8vIHJlc29sdmVkIHByaW9yIHRvIHJvdXRlciBjcmVhdGlvbiBzaW5jZSB3ZSBjYW4ndCBnbyBpbnRvIGEgZmFsbGJhY2tFbGVtZW50XG4gICAgLy8gVUkgZm9yIFNTUidkIGFwcHNcbiAgICBpZiAoIXN0YXRlLmluaXRpYWxpemVkKSB7XG4gICAgICBzdGFydE5hdmlnYXRpb24oQWN0aW9uLlBvcCwgc3RhdGUubG9jYXRpb24pO1xuICAgIH1cbiAgICByZXR1cm4gcm91dGVyO1xuICB9XG4gIC8vIENsZWFuIHVwIGEgcm91dGVyIGFuZCBpdCdzIHNpZGUgZWZmZWN0c1xuICBmdW5jdGlvbiBkaXNwb3NlKCkge1xuICAgIGlmICh1bmxpc3Rlbkhpc3RvcnkpIHtcbiAgICAgIHVubGlzdGVuSGlzdG9yeSgpO1xuICAgIH1cbiAgICBzdWJzY3JpYmVycy5jbGVhcigpO1xuICAgIHBlbmRpbmdOYXZpZ2F0aW9uQ29udHJvbGxlciAmJiBwZW5kaW5nTmF2aWdhdGlvbkNvbnRyb2xsZXIuYWJvcnQoKTtcbiAgICBzdGF0ZS5mZXRjaGVycy5mb3JFYWNoKChfLCBrZXkpID0+IGRlbGV0ZUZldGNoZXIoa2V5KSk7XG4gICAgc3RhdGUuYmxvY2tlcnMuZm9yRWFjaCgoXywga2V5KSA9PiBkZWxldGVCbG9ja2VyKGtleSkpO1xuICB9XG4gIC8vIFN1YnNjcmliZSB0byBzdGF0ZSB1cGRhdGVzIGZvciB0aGUgcm91dGVyXG4gIGZ1bmN0aW9uIHN1YnNjcmliZShmbikge1xuICAgIHN1YnNjcmliZXJzLmFkZChmbik7XG4gICAgcmV0dXJuICgpID0+IHN1YnNjcmliZXJzLmRlbGV0ZShmbik7XG4gIH1cbiAgLy8gVXBkYXRlIG91ciBzdGF0ZSBhbmQgbm90aWZ5IHRoZSBjYWxsaW5nIGNvbnRleHQgb2YgdGhlIGNoYW5nZVxuICBmdW5jdGlvbiB1cGRhdGVTdGF0ZShuZXdTdGF0ZSkge1xuICAgIHN0YXRlID0gX2V4dGVuZHMoe30sIHN0YXRlLCBuZXdTdGF0ZSk7XG4gICAgc3Vic2NyaWJlcnMuZm9yRWFjaChzdWJzY3JpYmVyID0+IHN1YnNjcmliZXIoc3RhdGUpKTtcbiAgfVxuICAvLyBDb21wbGV0ZSBhIG5hdmlnYXRpb24gcmV0dXJuaW5nIHRoZSBzdGF0ZS5uYXZpZ2F0aW9uIGJhY2sgdG8gdGhlIElETEVfTkFWSUdBVElPTlxuICAvLyBhbmQgc2V0dGluZyBzdGF0ZS5baGlzdG9yeUFjdGlvbi9sb2NhdGlvbi9tYXRjaGVzXSB0byB0aGUgbmV3IHJvdXRlLlxuICAvLyAtIExvY2F0aW9uIGlzIGEgcmVxdWlyZWQgcGFyYW1cbiAgLy8gLSBOYXZpZ2F0aW9uIHdpbGwgYWx3YXlzIGJlIHNldCB0byBJRExFX05BVklHQVRJT05cbiAgLy8gLSBDYW4gcGFzcyBhbnkgb3RoZXIgc3RhdGUgaW4gbmV3U3RhdGVcbiAgZnVuY3Rpb24gY29tcGxldGVOYXZpZ2F0aW9uKGxvY2F0aW9uLCBuZXdTdGF0ZSkge1xuICAgIHZhciBfbG9jYXRpb24kc3RhdGUsIF9sb2NhdGlvbiRzdGF0ZTI7XG4gICAgLy8gRGVkdWNlIGlmIHdlJ3JlIGluIGEgbG9hZGluZy9hY3Rpb25SZWxvYWQgc3RhdGU6XG4gICAgLy8gLSBXZSBoYXZlIGNvbW1pdHRlZCBhY3Rpb25EYXRhIGluIHRoZSBzdG9yZVxuICAgIC8vIC0gVGhlIGN1cnJlbnQgbmF2aWdhdGlvbiB3YXMgYSBtdXRhdGlvbiBzdWJtaXNzaW9uXG4gICAgLy8gLSBXZSdyZSBwYXN0IHRoZSBzdWJtaXR0aW5nIHN0YXRlIGFuZCBpbnRvIHRoZSBsb2FkaW5nIHN0YXRlXG4gICAgLy8gLSBUaGUgbG9jYXRpb24gYmVpbmcgbG9hZGVkIGlzIG5vdCB0aGUgcmVzdWx0IG9mIGEgcmVkaXJlY3RcbiAgICBsZXQgaXNBY3Rpb25SZWxvYWQgPSBzdGF0ZS5hY3Rpb25EYXRhICE9IG51bGwgJiYgc3RhdGUubmF2aWdhdGlvbi5mb3JtTWV0aG9kICE9IG51bGwgJiYgaXNNdXRhdGlvbk1ldGhvZChzdGF0ZS5uYXZpZ2F0aW9uLmZvcm1NZXRob2QpICYmIHN0YXRlLm5hdmlnYXRpb24uc3RhdGUgPT09IFwibG9hZGluZ1wiICYmICgoX2xvY2F0aW9uJHN0YXRlID0gbG9jYXRpb24uc3RhdGUpID09IG51bGwgPyB2b2lkIDAgOiBfbG9jYXRpb24kc3RhdGUuX2lzUmVkaXJlY3QpICE9PSB0cnVlO1xuICAgIGxldCBhY3Rpb25EYXRhO1xuICAgIGlmIChuZXdTdGF0ZS5hY3Rpb25EYXRhKSB7XG4gICAgICBpZiAoT2JqZWN0LmtleXMobmV3U3RhdGUuYWN0aW9uRGF0YSkubGVuZ3RoID4gMCkge1xuICAgICAgICBhY3Rpb25EYXRhID0gbmV3U3RhdGUuYWN0aW9uRGF0YTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEVtcHR5IGFjdGlvbkRhdGEgLT4gY2xlYXIgcHJpb3IgYWN0aW9uRGF0YSBkdWUgdG8gYW4gYWN0aW9uIGVycm9yXG4gICAgICAgIGFjdGlvbkRhdGEgPSBudWxsO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNBY3Rpb25SZWxvYWQpIHtcbiAgICAgIC8vIEtlZXAgdGhlIGN1cnJlbnQgZGF0YSBpZiB3ZSdyZSB3cmFwcGluZyB1cCB0aGUgYWN0aW9uIHJlbG9hZFxuICAgICAgYWN0aW9uRGF0YSA9IHN0YXRlLmFjdGlvbkRhdGE7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENsZWFyIGFjdGlvbkRhdGEgb24gYW55IG90aGVyIGNvbXBsZXRlZCBuYXZpZ2F0aW9uc1xuICAgICAgYWN0aW9uRGF0YSA9IG51bGw7XG4gICAgfVxuICAgIC8vIEFsd2F5cyBwcmVzZXJ2ZSBhbnkgZXhpc3RpbmcgbG9hZGVyRGF0YSBmcm9tIHJlLXVzZWQgcm91dGVzXG4gICAgbGV0IGxvYWRlckRhdGEgPSBuZXdTdGF0ZS5sb2FkZXJEYXRhID8gbWVyZ2VMb2FkZXJEYXRhKHN0YXRlLmxvYWRlckRhdGEsIG5ld1N0YXRlLmxvYWRlckRhdGEsIG5ld1N0YXRlLm1hdGNoZXMgfHwgW10sIG5ld1N0YXRlLmVycm9ycykgOiBzdGF0ZS5sb2FkZXJEYXRhO1xuICAgIC8vIE9uIGEgc3VjY2Vzc2Z1bCBuYXZpZ2F0aW9uIHdlIGNhbiBhc3N1bWUgd2UgZ290IHRocm91Z2ggYWxsIGJsb2NrZXJzXG4gICAgLy8gc28gd2UgY2FuIHN0YXJ0IGZyZXNoXG4gICAgbGV0IGJsb2NrZXJzID0gc3RhdGUuYmxvY2tlcnM7XG4gICAgaWYgKGJsb2NrZXJzLnNpemUgPiAwKSB7XG4gICAgICBibG9ja2VycyA9IG5ldyBNYXAoYmxvY2tlcnMpO1xuICAgICAgYmxvY2tlcnMuZm9yRWFjaCgoXywgaykgPT4gYmxvY2tlcnMuc2V0KGssIElETEVfQkxPQ0tFUikpO1xuICAgIH1cbiAgICAvLyBBbHdheXMgcmVzcGVjdCB0aGUgdXNlciBmbGFnLiAgT3RoZXJ3aXNlIGRvbid0IHJlc2V0IG9uIG11dGF0aW9uXG4gICAgLy8gc3VibWlzc2lvbiBuYXZpZ2F0aW9ucyB1bmxlc3MgdGhleSByZWRpcmVjdFxuICAgIGxldCBwcmV2ZW50U2Nyb2xsUmVzZXQgPSBwZW5kaW5nUHJldmVudFNjcm9sbFJlc2V0ID09PSB0cnVlIHx8IHN0YXRlLm5hdmlnYXRpb24uZm9ybU1ldGhvZCAhPSBudWxsICYmIGlzTXV0YXRpb25NZXRob2Qoc3RhdGUubmF2aWdhdGlvbi5mb3JtTWV0aG9kKSAmJiAoKF9sb2NhdGlvbiRzdGF0ZTIgPSBsb2NhdGlvbi5zdGF0ZSkgPT0gbnVsbCA/IHZvaWQgMCA6IF9sb2NhdGlvbiRzdGF0ZTIuX2lzUmVkaXJlY3QpICE9PSB0cnVlO1xuICAgIGlmIChpbkZsaWdodERhdGFSb3V0ZXMpIHtcbiAgICAgIGRhdGFSb3V0ZXMgPSBpbkZsaWdodERhdGFSb3V0ZXM7XG4gICAgICBpbkZsaWdodERhdGFSb3V0ZXMgPSB1bmRlZmluZWQ7XG4gICAgfVxuICAgIGlmIChpc1VuaW50ZXJydXB0ZWRSZXZhbGlkYXRpb24pIDsgZWxzZSBpZiAocGVuZGluZ0FjdGlvbiA9PT0gQWN0aW9uLlBvcCkgOyBlbHNlIGlmIChwZW5kaW5nQWN0aW9uID09PSBBY3Rpb24uUHVzaCkge1xuICAgICAgaW5pdC5oaXN0b3J5LnB1c2gobG9jYXRpb24sIGxvY2F0aW9uLnN0YXRlKTtcbiAgICB9IGVsc2UgaWYgKHBlbmRpbmdBY3Rpb24gPT09IEFjdGlvbi5SZXBsYWNlKSB7XG4gICAgICBpbml0Lmhpc3RvcnkucmVwbGFjZShsb2NhdGlvbiwgbG9jYXRpb24uc3RhdGUpO1xuICAgIH1cbiAgICB1cGRhdGVTdGF0ZShfZXh0ZW5kcyh7fSwgbmV3U3RhdGUsIHtcbiAgICAgIGFjdGlvbkRhdGEsXG4gICAgICBsb2FkZXJEYXRhLFxuICAgICAgaGlzdG9yeUFjdGlvbjogcGVuZGluZ0FjdGlvbixcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgaW5pdGlhbGl6ZWQ6IHRydWUsXG4gICAgICBuYXZpZ2F0aW9uOiBJRExFX05BVklHQVRJT04sXG4gICAgICByZXZhbGlkYXRpb246IFwiaWRsZVwiLFxuICAgICAgcmVzdG9yZVNjcm9sbFBvc2l0aW9uOiBnZXRTYXZlZFNjcm9sbFBvc2l0aW9uKGxvY2F0aW9uLCBuZXdTdGF0ZS5tYXRjaGVzIHx8IHN0YXRlLm1hdGNoZXMpLFxuICAgICAgcHJldmVudFNjcm9sbFJlc2V0LFxuICAgICAgYmxvY2tlcnNcbiAgICB9KSk7XG4gICAgLy8gUmVzZXQgc3RhdGVmdWwgbmF2aWdhdGlvbiB2YXJzXG4gICAgcGVuZGluZ0FjdGlvbiA9IEFjdGlvbi5Qb3A7XG4gICAgcGVuZGluZ1ByZXZlbnRTY3JvbGxSZXNldCA9IGZhbHNlO1xuICAgIGlzVW5pbnRlcnJ1cHRlZFJldmFsaWRhdGlvbiA9IGZhbHNlO1xuICAgIGlzUmV2YWxpZGF0aW9uUmVxdWlyZWQgPSBmYWxzZTtcbiAgICBjYW5jZWxsZWREZWZlcnJlZFJvdXRlcyA9IFtdO1xuICAgIGNhbmNlbGxlZEZldGNoZXJMb2FkcyA9IFtdO1xuICB9XG4gIC8vIFRyaWdnZXIgYSBuYXZpZ2F0aW9uIGV2ZW50LCB3aGljaCBjYW4gZWl0aGVyIGJlIGEgbnVtZXJpY2FsIFBPUCBvciBhIFBVU0hcbiAgLy8gcmVwbGFjZSB3aXRoIGFuIG9wdGlvbmFsIHN1Ym1pc3Npb25cbiAgYXN5bmMgZnVuY3Rpb24gbmF2aWdhdGUodG8sIG9wdHMpIHtcbiAgICBpZiAodHlwZW9mIHRvID09PSBcIm51bWJlclwiKSB7XG4gICAgICBpbml0Lmhpc3RvcnkuZ28odG8pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgbm9ybWFsaXplZFBhdGggPSBub3JtYWxpemVUbyhzdGF0ZS5sb2NhdGlvbiwgc3RhdGUubWF0Y2hlcywgYmFzZW5hbWUsIGZ1dHVyZS52N19wcmVwZW5kQmFzZW5hbWUsIHRvLCBvcHRzID09IG51bGwgPyB2b2lkIDAgOiBvcHRzLmZyb21Sb3V0ZUlkLCBvcHRzID09IG51bGwgPyB2b2lkIDAgOiBvcHRzLnJlbGF0aXZlKTtcbiAgICBsZXQge1xuICAgICAgcGF0aCxcbiAgICAgIHN1Ym1pc3Npb24sXG4gICAgICBlcnJvclxuICAgIH0gPSBub3JtYWxpemVOYXZpZ2F0ZU9wdGlvbnMoZnV0dXJlLnY3X25vcm1hbGl6ZUZvcm1NZXRob2QsIGZhbHNlLCBub3JtYWxpemVkUGF0aCwgb3B0cyk7XG4gICAgbGV0IGN1cnJlbnRMb2NhdGlvbiA9IHN0YXRlLmxvY2F0aW9uO1xuICAgIGxldCBuZXh0TG9jYXRpb24gPSBjcmVhdGVMb2NhdGlvbihzdGF0ZS5sb2NhdGlvbiwgcGF0aCwgb3B0cyAmJiBvcHRzLnN0YXRlKTtcbiAgICAvLyBXaGVuIHVzaW5nIG5hdmlnYXRlIGFzIGEgUFVTSC9SRVBMQUNFIHdlIGFyZW4ndCByZWFkaW5nIGFuIGFscmVhZHktZW5jb2RlZFxuICAgIC8vIFVSTCBmcm9tIHdpbmRvdy5sb2NhdGlvbiwgc28gd2UgbmVlZCB0byBlbmNvZGUgaXQgaGVyZSBzbyB0aGUgYmVoYXZpb3JcbiAgICAvLyByZW1haW5zIHRoZSBzYW1lIGFzIFBPUCBhbmQgbm9uLWRhdGEtcm91dGVyIHVzYWdlcy4gIG5ldyBVUkwoKSBkb2VzIGFsbFxuICAgIC8vIHRoZSBzYW1lIGVuY29kaW5nIHdlJ2QgZ2V0IGZyb20gYSBoaXN0b3J5LnB1c2hTdGF0ZS93aW5kb3cubG9jYXRpb24gcmVhZFxuICAgIC8vIHdpdGhvdXQgaGF2aW5nIHRvIHRvdWNoIGhpc3RvcnlcbiAgICBuZXh0TG9jYXRpb24gPSBfZXh0ZW5kcyh7fSwgbmV4dExvY2F0aW9uLCBpbml0Lmhpc3RvcnkuZW5jb2RlTG9jYXRpb24obmV4dExvY2F0aW9uKSk7XG4gICAgbGV0IHVzZXJSZXBsYWNlID0gb3B0cyAmJiBvcHRzLnJlcGxhY2UgIT0gbnVsbCA/IG9wdHMucmVwbGFjZSA6IHVuZGVmaW5lZDtcbiAgICBsZXQgaGlzdG9yeUFjdGlvbiA9IEFjdGlvbi5QdXNoO1xuICAgIGlmICh1c2VyUmVwbGFjZSA9PT0gdHJ1ZSkge1xuICAgICAgaGlzdG9yeUFjdGlvbiA9IEFjdGlvbi5SZXBsYWNlO1xuICAgIH0gZWxzZSBpZiAodXNlclJlcGxhY2UgPT09IGZhbHNlKSA7IGVsc2UgaWYgKHN1Ym1pc3Npb24gIT0gbnVsbCAmJiBpc011dGF0aW9uTWV0aG9kKHN1Ym1pc3Npb24uZm9ybU1ldGhvZCkgJiYgc3VibWlzc2lvbi5mb3JtQWN0aW9uID09PSBzdGF0ZS5sb2NhdGlvbi5wYXRobmFtZSArIHN0YXRlLmxvY2F0aW9uLnNlYXJjaCkge1xuICAgICAgLy8gQnkgZGVmYXVsdCBvbiBzdWJtaXNzaW9ucyB0byB0aGUgY3VycmVudCBsb2NhdGlvbiB3ZSBSRVBMQUNFIHNvIHRoYXRcbiAgICAgIC8vIHVzZXJzIGRvbid0IGhhdmUgdG8gZG91YmxlLWNsaWNrIHRoZSBiYWNrIGJ1dHRvbiB0byBnZXQgdG8gdGhlIHByaW9yXG4gICAgICAvLyBsb2NhdGlvbi4gIElmIHRoZSB1c2VyIHJlZGlyZWN0cyB0byBhIGRpZmZlcmVudCBsb2NhdGlvbiBmcm9tIHRoZVxuICAgICAgLy8gYWN0aW9uL2xvYWRlciB0aGlzIHdpbGwgYmUgaWdub3JlZCBhbmQgdGhlIHJlZGlyZWN0IHdpbGwgYmUgYSBQVVNIXG4gICAgICBoaXN0b3J5QWN0aW9uID0gQWN0aW9uLlJlcGxhY2U7XG4gICAgfVxuICAgIGxldCBwcmV2ZW50U2Nyb2xsUmVzZXQgPSBvcHRzICYmIFwicHJldmVudFNjcm9sbFJlc2V0XCIgaW4gb3B0cyA/IG9wdHMucHJldmVudFNjcm9sbFJlc2V0ID09PSB0cnVlIDogdW5kZWZpbmVkO1xuICAgIGxldCBibG9ja2VyS2V5ID0gc2hvdWxkQmxvY2tOYXZpZ2F0aW9uKHtcbiAgICAgIGN1cnJlbnRMb2NhdGlvbixcbiAgICAgIG5leHRMb2NhdGlvbixcbiAgICAgIGhpc3RvcnlBY3Rpb25cbiAgICB9KTtcbiAgICBpZiAoYmxvY2tlcktleSkge1xuICAgICAgLy8gUHV0IHRoZSBibG9ja2VyIGludG8gYSBibG9ja2VkIHN0YXRlXG4gICAgICB1cGRhdGVCbG9ja2VyKGJsb2NrZXJLZXksIHtcbiAgICAgICAgc3RhdGU6IFwiYmxvY2tlZFwiLFxuICAgICAgICBsb2NhdGlvbjogbmV4dExvY2F0aW9uLFxuICAgICAgICBwcm9jZWVkKCkge1xuICAgICAgICAgIHVwZGF0ZUJsb2NrZXIoYmxvY2tlcktleSwge1xuICAgICAgICAgICAgc3RhdGU6IFwicHJvY2VlZGluZ1wiLFxuICAgICAgICAgICAgcHJvY2VlZDogdW5kZWZpbmVkLFxuICAgICAgICAgICAgcmVzZXQ6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGxvY2F0aW9uOiBuZXh0TG9jYXRpb25cbiAgICAgICAgICB9KTtcbiAgICAgICAgICAvLyBTZW5kIHRoZSBzYW1lIG5hdmlnYXRpb24gdGhyb3VnaFxuICAgICAgICAgIG5hdmlnYXRlKHRvLCBvcHRzKTtcbiAgICAgICAgfSxcbiAgICAgICAgcmVzZXQoKSB7XG4gICAgICAgICAgbGV0IGJsb2NrZXJzID0gbmV3IE1hcChzdGF0ZS5ibG9ja2Vycyk7XG4gICAgICAgICAgYmxvY2tlcnMuc2V0KGJsb2NrZXJLZXksIElETEVfQkxPQ0tFUik7XG4gICAgICAgICAgdXBkYXRlU3RhdGUoe1xuICAgICAgICAgICAgYmxvY2tlcnNcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJldHVybiBhd2FpdCBzdGFydE5hdmlnYXRpb24oaGlzdG9yeUFjdGlvbiwgbmV4dExvY2F0aW9uLCB7XG4gICAgICBzdWJtaXNzaW9uLFxuICAgICAgLy8gU2VuZCB0aHJvdWdoIHRoZSBmb3JtRGF0YSBzZXJpYWxpemF0aW9uIGVycm9yIGlmIHdlIGhhdmUgb25lIHNvIHdlIGNhblxuICAgICAgLy8gcmVuZGVyIGF0IHRoZSByaWdodCBlcnJvciBib3VuZGFyeSBhZnRlciB3ZSBtYXRjaCByb3V0ZXNcbiAgICAgIHBlbmRpbmdFcnJvcjogZXJyb3IsXG4gICAgICBwcmV2ZW50U2Nyb2xsUmVzZXQsXG4gICAgICByZXBsYWNlOiBvcHRzICYmIG9wdHMucmVwbGFjZVxuICAgIH0pO1xuICB9XG4gIC8vIFJldmFsaWRhdGUgYWxsIGN1cnJlbnQgbG9hZGVycy4gIElmIGEgbmF2aWdhdGlvbiBpcyBpbiBwcm9ncmVzcyBvciBpZiB0aGlzXG4gIC8vIGlzIGludGVycnVwdGVkIGJ5IGEgbmF2aWdhdGlvbiwgYWxsb3cgdGhpcyB0byBcInN1Y2NlZWRcIiBieSBjYWxsaW5nIGFsbFxuICAvLyBsb2FkZXJzIGR1cmluZyB0aGUgbmV4dCBsb2FkZXIgcm91bmRcbiAgZnVuY3Rpb24gcmV2YWxpZGF0ZSgpIHtcbiAgICBpbnRlcnJ1cHRBY3RpdmVMb2FkcygpO1xuICAgIHVwZGF0ZVN0YXRlKHtcbiAgICAgIHJldmFsaWRhdGlvbjogXCJsb2FkaW5nXCJcbiAgICB9KTtcbiAgICAvLyBJZiB3ZSdyZSBjdXJyZW50bHkgc3VibWl0dGluZyBhbiBhY3Rpb24sIHdlIGRvbid0IG5lZWQgdG8gc3RhcnQgYSBuZXdcbiAgICAvLyBuYXZpZ2F0aW9uLCB3ZSdsbCBqdXN0IGxldCB0aGUgZm9sbG93IHVwIGxvYWRlciBleGVjdXRpb24gY2FsbCBhbGwgbG9hZGVyc1xuICAgIGlmIChzdGF0ZS5uYXZpZ2F0aW9uLnN0YXRlID09PSBcInN1Ym1pdHRpbmdcIikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBJZiB3ZSdyZSBjdXJyZW50bHkgaW4gYW4gaWRsZSBzdGF0ZSwgc3RhcnQgYSBuZXcgbmF2aWdhdGlvbiBmb3IgdGhlIGN1cnJlbnRcbiAgICAvLyBhY3Rpb24vbG9jYXRpb24gYW5kIG1hcmsgaXQgYXMgdW5pbnRlcnJ1cHRlZCwgd2hpY2ggd2lsbCBza2lwIHRoZSBoaXN0b3J5XG4gICAgLy8gdXBkYXRlIGluIGNvbXBsZXRlTmF2aWdhdGlvblxuICAgIGlmIChzdGF0ZS5uYXZpZ2F0aW9uLnN0YXRlID09PSBcImlkbGVcIikge1xuICAgICAgc3RhcnROYXZpZ2F0aW9uKHN0YXRlLmhpc3RvcnlBY3Rpb24sIHN0YXRlLmxvY2F0aW9uLCB7XG4gICAgICAgIHN0YXJ0VW5pbnRlcnJ1cHRlZFJldmFsaWRhdGlvbjogdHJ1ZVxuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIE90aGVyd2lzZSwgaWYgd2UncmUgY3VycmVudGx5IGluIGEgbG9hZGluZyBzdGF0ZSwganVzdCBzdGFydCBhIG5ld1xuICAgIC8vIG5hdmlnYXRpb24gdG8gdGhlIG5hdmlnYXRpb24ubG9jYXRpb24gYnV0IGRvIG5vdCB0cmlnZ2VyIGFuIHVuaW50ZXJydXB0ZWRcbiAgICAvLyByZXZhbGlkYXRpb24gc28gdGhhdCBoaXN0b3J5IGNvcnJlY3RseSB1cGRhdGVzIG9uY2UgdGhlIG5hdmlnYXRpb24gY29tcGxldGVzXG4gICAgc3RhcnROYXZpZ2F0aW9uKHBlbmRpbmdBY3Rpb24gfHwgc3RhdGUuaGlzdG9yeUFjdGlvbiwgc3RhdGUubmF2aWdhdGlvbi5sb2NhdGlvbiwge1xuICAgICAgb3ZlcnJpZGVOYXZpZ2F0aW9uOiBzdGF0ZS5uYXZpZ2F0aW9uXG4gICAgfSk7XG4gIH1cbiAgLy8gU3RhcnQgYSBuYXZpZ2F0aW9uIHRvIHRoZSBnaXZlbiBhY3Rpb24vbG9jYXRpb24uICBDYW4gb3B0aW9uYWxseSBwcm92aWRlIGFcbiAgLy8gb3ZlcnJpZGVOYXZpZ2F0aW9uIHdoaWNoIHdpbGwgb3ZlcnJpZGUgdGhlIG5vcm1hbExvYWQgaW4gdGhlIGNhc2Ugb2YgYSByZWRpcmVjdFxuICAvLyBuYXZpZ2F0aW9uXG4gIGFzeW5jIGZ1bmN0aW9uIHN0YXJ0TmF2aWdhdGlvbihoaXN0b3J5QWN0aW9uLCBsb2NhdGlvbiwgb3B0cykge1xuICAgIC8vIEFib3J0IGFueSBpbi1wcm9ncmVzcyBuYXZpZ2F0aW9ucyBhbmQgc3RhcnQgYSBuZXcgb25lLiBVbnNldCBhbnkgb25nb2luZ1xuICAgIC8vIHVuaW50ZXJydXB0ZWQgcmV2YWxpZGF0aW9ucyB1bmxlc3MgdG9sZCBvdGhlcndpc2UsIHNpbmNlIHdlIHdhbnQgdGhpc1xuICAgIC8vIG5ldyBuYXZpZ2F0aW9uIHRvIHVwZGF0ZSBoaXN0b3J5IG5vcm1hbGx5XG4gICAgcGVuZGluZ05hdmlnYXRpb25Db250cm9sbGVyICYmIHBlbmRpbmdOYXZpZ2F0aW9uQ29udHJvbGxlci5hYm9ydCgpO1xuICAgIHBlbmRpbmdOYXZpZ2F0aW9uQ29udHJvbGxlciA9IG51bGw7XG4gICAgcGVuZGluZ0FjdGlvbiA9IGhpc3RvcnlBY3Rpb247XG4gICAgaXNVbmludGVycnVwdGVkUmV2YWxpZGF0aW9uID0gKG9wdHMgJiYgb3B0cy5zdGFydFVuaW50ZXJydXB0ZWRSZXZhbGlkYXRpb24pID09PSB0cnVlO1xuICAgIC8vIFNhdmUgdGhlIGN1cnJlbnQgc2Nyb2xsIHBvc2l0aW9uIGV2ZXJ5IHRpbWUgd2Ugc3RhcnQgYSBuZXcgbmF2aWdhdGlvbixcbiAgICAvLyBhbmQgdHJhY2sgd2hldGhlciB3ZSBzaG91bGQgcmVzZXQgc2Nyb2xsIG9uIGNvbXBsZXRpb25cbiAgICBzYXZlU2Nyb2xsUG9zaXRpb24oc3RhdGUubG9jYXRpb24sIHN0YXRlLm1hdGNoZXMpO1xuICAgIHBlbmRpbmdQcmV2ZW50U2Nyb2xsUmVzZXQgPSAob3B0cyAmJiBvcHRzLnByZXZlbnRTY3JvbGxSZXNldCkgPT09IHRydWU7XG4gICAgbGV0IHJvdXRlc1RvVXNlID0gaW5GbGlnaHREYXRhUm91dGVzIHx8IGRhdGFSb3V0ZXM7XG4gICAgbGV0IGxvYWRpbmdOYXZpZ2F0aW9uID0gb3B0cyAmJiBvcHRzLm92ZXJyaWRlTmF2aWdhdGlvbjtcbiAgICBsZXQgbWF0Y2hlcyA9IG1hdGNoUm91dGVzKHJvdXRlc1RvVXNlLCBsb2NhdGlvbiwgYmFzZW5hbWUpO1xuICAgIC8vIFNob3J0IGNpcmN1aXQgd2l0aCBhIDQwNCBvbiB0aGUgcm9vdCBlcnJvciBib3VuZGFyeSBpZiB3ZSBtYXRjaCBub3RoaW5nXG4gICAgaWYgKCFtYXRjaGVzKSB7XG4gICAgICBsZXQgZXJyb3IgPSBnZXRJbnRlcm5hbFJvdXRlckVycm9yKDQwNCwge1xuICAgICAgICBwYXRobmFtZTogbG9jYXRpb24ucGF0aG5hbWVcbiAgICAgIH0pO1xuICAgICAgbGV0IHtcbiAgICAgICAgbWF0Y2hlczogbm90Rm91bmRNYXRjaGVzLFxuICAgICAgICByb3V0ZVxuICAgICAgfSA9IGdldFNob3J0Q2lyY3VpdE1hdGNoZXMocm91dGVzVG9Vc2UpO1xuICAgICAgLy8gQ2FuY2VsIGFsbCBwZW5kaW5nIGRlZmVycmVkIG9uIDQwNHMgc2luY2Ugd2UgZG9uJ3Qga2VlcCBhbnkgcm91dGVzXG4gICAgICBjYW5jZWxBY3RpdmVEZWZlcnJlZHMoKTtcbiAgICAgIGNvbXBsZXRlTmF2aWdhdGlvbihsb2NhdGlvbiwge1xuICAgICAgICBtYXRjaGVzOiBub3RGb3VuZE1hdGNoZXMsXG4gICAgICAgIGxvYWRlckRhdGE6IHt9LFxuICAgICAgICBlcnJvcnM6IHtcbiAgICAgICAgICBbcm91dGUuaWRdOiBlcnJvclxuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gU2hvcnQgY2lyY3VpdCBpZiBpdCdzIG9ubHkgYSBoYXNoIGNoYW5nZSBhbmQgbm90IGEgcmV2YWxpZGF0aW9uIG9yXG4gICAgLy8gbXV0YXRpb24gc3VibWlzc2lvbi5cbiAgICAvL1xuICAgIC8vIElnbm9yZSBvbiBpbml0aWFsIHBhZ2UgbG9hZHMgYmVjYXVzZSBzaW5jZSB0aGUgaW5pdGlhbCBsb2FkIHdpbGwgYWx3YXlzXG4gICAgLy8gYmUgXCJzYW1lIGhhc2hcIi4gIEZvciBleGFtcGxlLCBvbiAvcGFnZSNoYXNoIGFuZCBzdWJtaXQgYSA8Rm9ybSBtZXRob2Q9XCJwb3N0XCI+XG4gICAgLy8gd2hpY2ggd2lsbCBkZWZhdWx0IHRvIGEgbmF2aWdhdGlvbiB0byAvcGFnZVxuICAgIGlmIChzdGF0ZS5pbml0aWFsaXplZCAmJiAhaXNSZXZhbGlkYXRpb25SZXF1aXJlZCAmJiBpc0hhc2hDaGFuZ2VPbmx5KHN0YXRlLmxvY2F0aW9uLCBsb2NhdGlvbikgJiYgIShvcHRzICYmIG9wdHMuc3VibWlzc2lvbiAmJiBpc011dGF0aW9uTWV0aG9kKG9wdHMuc3VibWlzc2lvbi5mb3JtTWV0aG9kKSkpIHtcbiAgICAgIGNvbXBsZXRlTmF2aWdhdGlvbihsb2NhdGlvbiwge1xuICAgICAgICBtYXRjaGVzXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gQ3JlYXRlIGEgY29udHJvbGxlci9SZXF1ZXN0IGZvciB0aGlzIG5hdmlnYXRpb25cbiAgICBwZW5kaW5nTmF2aWdhdGlvbkNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgbGV0IHJlcXVlc3QgPSBjcmVhdGVDbGllbnRTaWRlUmVxdWVzdChpbml0Lmhpc3RvcnksIGxvY2F0aW9uLCBwZW5kaW5nTmF2aWdhdGlvbkNvbnRyb2xsZXIuc2lnbmFsLCBvcHRzICYmIG9wdHMuc3VibWlzc2lvbik7XG4gICAgbGV0IHBlbmRpbmdBY3Rpb25EYXRhO1xuICAgIGxldCBwZW5kaW5nRXJyb3I7XG4gICAgaWYgKG9wdHMgJiYgb3B0cy5wZW5kaW5nRXJyb3IpIHtcbiAgICAgIC8vIElmIHdlIGhhdmUgYSBwZW5kaW5nRXJyb3IsIGl0IG1lYW5zIHRoZSB1c2VyIGF0dGVtcHRlZCBhIEdFVCBzdWJtaXNzaW9uXG4gICAgICAvLyB3aXRoIGJpbmFyeSBGb3JtRGF0YSBzbyBhc3NpZ24gaGVyZSBhbmQgc2tpcCB0byBoYW5kbGVMb2FkZXJzLiAgVGhhdFxuICAgICAgLy8gd2F5IHdlIGhhbmRsZSBjYWxsaW5nIGxvYWRlcnMgYWJvdmUgdGhlIGJvdW5kYXJ5IGV0Yy4gIEl0J3Mgbm90IHJlYWxseVxuICAgICAgLy8gZGlmZmVyZW50IGZyb20gYW4gYWN0aW9uRXJyb3IgaW4gdGhhdCBzZW5zZS5cbiAgICAgIHBlbmRpbmdFcnJvciA9IHtcbiAgICAgICAgW2ZpbmROZWFyZXN0Qm91bmRhcnkobWF0Y2hlcykucm91dGUuaWRdOiBvcHRzLnBlbmRpbmdFcnJvclxuICAgICAgfTtcbiAgICB9IGVsc2UgaWYgKG9wdHMgJiYgb3B0cy5zdWJtaXNzaW9uICYmIGlzTXV0YXRpb25NZXRob2Qob3B0cy5zdWJtaXNzaW9uLmZvcm1NZXRob2QpKSB7XG4gICAgICAvLyBDYWxsIGFjdGlvbiBpZiB3ZSByZWNlaXZlZCBhbiBhY3Rpb24gc3VibWlzc2lvblxuICAgICAgbGV0IGFjdGlvbk91dHB1dCA9IGF3YWl0IGhhbmRsZUFjdGlvbihyZXF1ZXN0LCBsb2NhdGlvbiwgb3B0cy5zdWJtaXNzaW9uLCBtYXRjaGVzLCB7XG4gICAgICAgIHJlcGxhY2U6IG9wdHMucmVwbGFjZVxuICAgICAgfSk7XG4gICAgICBpZiAoYWN0aW9uT3V0cHV0LnNob3J0Q2lyY3VpdGVkKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHBlbmRpbmdBY3Rpb25EYXRhID0gYWN0aW9uT3V0cHV0LnBlbmRpbmdBY3Rpb25EYXRhO1xuICAgICAgcGVuZGluZ0Vycm9yID0gYWN0aW9uT3V0cHV0LnBlbmRpbmdBY3Rpb25FcnJvcjtcbiAgICAgIGxvYWRpbmdOYXZpZ2F0aW9uID0gZ2V0TG9hZGluZ05hdmlnYXRpb24obG9jYXRpb24sIG9wdHMuc3VibWlzc2lvbik7XG4gICAgICAvLyBDcmVhdGUgYSBHRVQgcmVxdWVzdCBmb3IgdGhlIGxvYWRlcnNcbiAgICAgIHJlcXVlc3QgPSBuZXcgUmVxdWVzdChyZXF1ZXN0LnVybCwge1xuICAgICAgICBzaWduYWw6IHJlcXVlc3Quc2lnbmFsXG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gQ2FsbCBsb2FkZXJzXG4gICAgbGV0IHtcbiAgICAgIHNob3J0Q2lyY3VpdGVkLFxuICAgICAgbG9hZGVyRGF0YSxcbiAgICAgIGVycm9yc1xuICAgIH0gPSBhd2FpdCBoYW5kbGVMb2FkZXJzKHJlcXVlc3QsIGxvY2F0aW9uLCBtYXRjaGVzLCBsb2FkaW5nTmF2aWdhdGlvbiwgb3B0cyAmJiBvcHRzLnN1Ym1pc3Npb24sIG9wdHMgJiYgb3B0cy5mZXRjaGVyU3VibWlzc2lvbiwgb3B0cyAmJiBvcHRzLnJlcGxhY2UsIHBlbmRpbmdBY3Rpb25EYXRhLCBwZW5kaW5nRXJyb3IpO1xuICAgIGlmIChzaG9ydENpcmN1aXRlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBDbGVhbiB1cCBub3cgdGhhdCB0aGUgYWN0aW9uL2xvYWRlcnMgaGF2ZSBjb21wbGV0ZWQuICBEb24ndCBjbGVhbiB1cCBpZlxuICAgIC8vIHdlIHNob3J0IGNpcmN1aXRlZCBiZWNhdXNlIHBlbmRpbmdOYXZpZ2F0aW9uQ29udHJvbGxlciB3aWxsIGhhdmUgYWxyZWFkeVxuICAgIC8vIGJlZW4gYXNzaWduZWQgdG8gYSBuZXcgY29udHJvbGxlciBmb3IgdGhlIG5leHQgbmF2aWdhdGlvblxuICAgIHBlbmRpbmdOYXZpZ2F0aW9uQ29udHJvbGxlciA9IG51bGw7XG4gICAgY29tcGxldGVOYXZpZ2F0aW9uKGxvY2F0aW9uLCBfZXh0ZW5kcyh7XG4gICAgICBtYXRjaGVzXG4gICAgfSwgcGVuZGluZ0FjdGlvbkRhdGEgPyB7XG4gICAgICBhY3Rpb25EYXRhOiBwZW5kaW5nQWN0aW9uRGF0YVxuICAgIH0gOiB7fSwge1xuICAgICAgbG9hZGVyRGF0YSxcbiAgICAgIGVycm9yc1xuICAgIH0pKTtcbiAgfVxuICAvLyBDYWxsIHRoZSBhY3Rpb24gbWF0Y2hlZCBieSB0aGUgbGVhZiByb3V0ZSBmb3IgdGhpcyBuYXZpZ2F0aW9uIGFuZCBoYW5kbGVcbiAgLy8gcmVkaXJlY3RzL2Vycm9yc1xuICBhc3luYyBmdW5jdGlvbiBoYW5kbGVBY3Rpb24ocmVxdWVzdCwgbG9jYXRpb24sIHN1Ym1pc3Npb24sIG1hdGNoZXMsIG9wdHMpIHtcbiAgICBpZiAob3B0cyA9PT0gdm9pZCAwKSB7XG4gICAgICBvcHRzID0ge307XG4gICAgfVxuICAgIGludGVycnVwdEFjdGl2ZUxvYWRzKCk7XG4gICAgLy8gUHV0IHVzIGluIGEgc3VibWl0dGluZyBzdGF0ZVxuICAgIGxldCBuYXZpZ2F0aW9uID0gZ2V0U3VibWl0dGluZ05hdmlnYXRpb24obG9jYXRpb24sIHN1Ym1pc3Npb24pO1xuICAgIHVwZGF0ZVN0YXRlKHtcbiAgICAgIG5hdmlnYXRpb25cbiAgICB9KTtcbiAgICAvLyBDYWxsIG91ciBhY3Rpb24gYW5kIGdldCB0aGUgcmVzdWx0XG4gICAgbGV0IHJlc3VsdDtcbiAgICBsZXQgYWN0aW9uTWF0Y2ggPSBnZXRUYXJnZXRNYXRjaChtYXRjaGVzLCBsb2NhdGlvbik7XG4gICAgaWYgKCFhY3Rpb25NYXRjaC5yb3V0ZS5hY3Rpb24gJiYgIWFjdGlvbk1hdGNoLnJvdXRlLmxhenkpIHtcbiAgICAgIHJlc3VsdCA9IHtcbiAgICAgICAgdHlwZTogUmVzdWx0VHlwZS5lcnJvcixcbiAgICAgICAgZXJyb3I6IGdldEludGVybmFsUm91dGVyRXJyb3IoNDA1LCB7XG4gICAgICAgICAgbWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICAgICAgICBwYXRobmFtZTogbG9jYXRpb24ucGF0aG5hbWUsXG4gICAgICAgICAgcm91dGVJZDogYWN0aW9uTWF0Y2gucm91dGUuaWRcbiAgICAgICAgfSlcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCA9IGF3YWl0IGNhbGxMb2FkZXJPckFjdGlvbihcImFjdGlvblwiLCByZXF1ZXN0LCBhY3Rpb25NYXRjaCwgbWF0Y2hlcywgbWFuaWZlc3QsIG1hcFJvdXRlUHJvcGVydGllcywgYmFzZW5hbWUpO1xuICAgICAgaWYgKHJlcXVlc3Quc2lnbmFsLmFib3J0ZWQpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBzaG9ydENpcmN1aXRlZDogdHJ1ZVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaXNSZWRpcmVjdFJlc3VsdChyZXN1bHQpKSB7XG4gICAgICBsZXQgcmVwbGFjZTtcbiAgICAgIGlmIChvcHRzICYmIG9wdHMucmVwbGFjZSAhPSBudWxsKSB7XG4gICAgICAgIHJlcGxhY2UgPSBvcHRzLnJlcGxhY2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBJZiB0aGUgdXNlciBkaWRuJ3QgZXhwbGljaXR5IGluZGljYXRlIHJlcGxhY2UgYmVoYXZpb3IsIHJlcGxhY2UgaWZcbiAgICAgICAgLy8gd2UgcmVkaXJlY3RlZCB0byB0aGUgZXhhY3Qgc2FtZSBsb2NhdGlvbiB3ZSdyZSBjdXJyZW50bHkgYXQgdG8gYXZvaWRcbiAgICAgICAgLy8gZG91YmxlIGJhY2stYnV0dG9uc1xuICAgICAgICByZXBsYWNlID0gcmVzdWx0LmxvY2F0aW9uID09PSBzdGF0ZS5sb2NhdGlvbi5wYXRobmFtZSArIHN0YXRlLmxvY2F0aW9uLnNlYXJjaDtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHN0YXJ0UmVkaXJlY3ROYXZpZ2F0aW9uKHN0YXRlLCByZXN1bHQsIHtcbiAgICAgICAgc3VibWlzc2lvbixcbiAgICAgICAgcmVwbGFjZVxuICAgICAgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzaG9ydENpcmN1aXRlZDogdHJ1ZVxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKGlzRXJyb3JSZXN1bHQocmVzdWx0KSkge1xuICAgICAgLy8gU3RvcmUgb2ZmIHRoZSBwZW5kaW5nIGVycm9yIC0gd2UgdXNlIGl0IHRvIGRldGVybWluZSB3aGljaCBsb2FkZXJzXG4gICAgICAvLyB0byBjYWxsIGFuZCB3aWxsIGNvbW1pdCBpdCB3aGVuIHdlIGNvbXBsZXRlIHRoZSBuYXZpZ2F0aW9uXG4gICAgICBsZXQgYm91bmRhcnlNYXRjaCA9IGZpbmROZWFyZXN0Qm91bmRhcnkobWF0Y2hlcywgYWN0aW9uTWF0Y2gucm91dGUuaWQpO1xuICAgICAgLy8gQnkgZGVmYXVsdCwgYWxsIHN1Ym1pc3Npb25zIGFyZSBSRVBMQUNFIG5hdmlnYXRpb25zLCBidXQgaWYgdGhlXG4gICAgICAvLyBhY3Rpb24gdGhyZXcgYW4gZXJyb3IgdGhhdCdsbCBiZSByZW5kZXJlZCBpbiBhbiBlcnJvckVsZW1lbnQsIHdlIGZhbGxcbiAgICAgIC8vIGJhY2sgdG8gUFVTSCBzbyB0aGF0IHRoZSB1c2VyIGNhbiB1c2UgdGhlIGJhY2sgYnV0dG9uIHRvIGdldCBiYWNrIHRvXG4gICAgICAvLyB0aGUgcHJlLXN1Ym1pc3Npb24gZm9ybSBsb2NhdGlvbiB0byB0cnkgYWdhaW5cbiAgICAgIGlmICgob3B0cyAmJiBvcHRzLnJlcGxhY2UpICE9PSB0cnVlKSB7XG4gICAgICAgIHBlbmRpbmdBY3Rpb24gPSBBY3Rpb24uUHVzaDtcbiAgICAgIH1cbiAgICAgIHJldHVybiB7XG4gICAgICAgIC8vIFNlbmQgYmFjayBhbiBlbXB0eSBvYmplY3Qgd2UgY2FuIHVzZSB0byBjbGVhciBvdXQgYW55IHByaW9yIGFjdGlvbkRhdGFcbiAgICAgICAgcGVuZGluZ0FjdGlvbkRhdGE6IHt9LFxuICAgICAgICBwZW5kaW5nQWN0aW9uRXJyb3I6IHtcbiAgICAgICAgICBbYm91bmRhcnlNYXRjaC5yb3V0ZS5pZF06IHJlc3VsdC5lcnJvclxuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cbiAgICBpZiAoaXNEZWZlcnJlZFJlc3VsdChyZXN1bHQpKSB7XG4gICAgICB0aHJvdyBnZXRJbnRlcm5hbFJvdXRlckVycm9yKDQwMCwge1xuICAgICAgICB0eXBlOiBcImRlZmVyLWFjdGlvblwiXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHBlbmRpbmdBY3Rpb25EYXRhOiB7XG4gICAgICAgIFthY3Rpb25NYXRjaC5yb3V0ZS5pZF06IHJlc3VsdC5kYXRhXG4gICAgICB9XG4gICAgfTtcbiAgfVxuICAvLyBDYWxsIGFsbCBhcHBsaWNhYmxlIGxvYWRlcnMgZm9yIHRoZSBnaXZlbiBtYXRjaGVzLCBoYW5kbGluZyByZWRpcmVjdHMsXG4gIC8vIGVycm9ycywgZXRjLlxuICBhc3luYyBmdW5jdGlvbiBoYW5kbGVMb2FkZXJzKHJlcXVlc3QsIGxvY2F0aW9uLCBtYXRjaGVzLCBvdmVycmlkZU5hdmlnYXRpb24sIHN1Ym1pc3Npb24sIGZldGNoZXJTdWJtaXNzaW9uLCByZXBsYWNlLCBwZW5kaW5nQWN0aW9uRGF0YSwgcGVuZGluZ0Vycm9yKSB7XG4gICAgLy8gRmlndXJlIG91dCB0aGUgcmlnaHQgbmF2aWdhdGlvbiB3ZSB3YW50IHRvIHVzZSBmb3IgZGF0YSBsb2FkaW5nXG4gICAgbGV0IGxvYWRpbmdOYXZpZ2F0aW9uID0gb3ZlcnJpZGVOYXZpZ2F0aW9uIHx8IGdldExvYWRpbmdOYXZpZ2F0aW9uKGxvY2F0aW9uLCBzdWJtaXNzaW9uKTtcbiAgICAvLyBJZiB0aGlzIHdhcyBhIHJlZGlyZWN0IGZyb20gYW4gYWN0aW9uIHdlIGRvbid0IGhhdmUgYSBcInN1Ym1pc3Npb25cIiBidXRcbiAgICAvLyB3ZSBoYXZlIGl0IG9uIHRoZSBsb2FkaW5nIG5hdmlnYXRpb24gc28gdXNlIHRoYXQgaWYgYXZhaWxhYmxlXG4gICAgbGV0IGFjdGl2ZVN1Ym1pc3Npb24gPSBzdWJtaXNzaW9uIHx8IGZldGNoZXJTdWJtaXNzaW9uIHx8IGdldFN1Ym1pc3Npb25Gcm9tTmF2aWdhdGlvbihsb2FkaW5nTmF2aWdhdGlvbik7XG4gICAgbGV0IHJvdXRlc1RvVXNlID0gaW5GbGlnaHREYXRhUm91dGVzIHx8IGRhdGFSb3V0ZXM7XG4gICAgbGV0IFttYXRjaGVzVG9Mb2FkLCByZXZhbGlkYXRpbmdGZXRjaGVyc10gPSBnZXRNYXRjaGVzVG9Mb2FkKGluaXQuaGlzdG9yeSwgc3RhdGUsIG1hdGNoZXMsIGFjdGl2ZVN1Ym1pc3Npb24sIGxvY2F0aW9uLCBpc1JldmFsaWRhdGlvblJlcXVpcmVkLCBjYW5jZWxsZWREZWZlcnJlZFJvdXRlcywgY2FuY2VsbGVkRmV0Y2hlckxvYWRzLCBmZXRjaExvYWRNYXRjaGVzLCBmZXRjaFJlZGlyZWN0SWRzLCByb3V0ZXNUb1VzZSwgYmFzZW5hbWUsIHBlbmRpbmdBY3Rpb25EYXRhLCBwZW5kaW5nRXJyb3IpO1xuICAgIC8vIENhbmNlbCBwZW5kaW5nIGRlZmVycmVkcyBmb3Igbm8tbG9uZ2VyLW1hdGNoZWQgcm91dGVzIG9yIHJvdXRlcyB3ZSdyZVxuICAgIC8vIGFib3V0IHRvIHJlbG9hZC4gIE5vdGUgdGhhdCBpZiB0aGlzIGlzIGFuIGFjdGlvbiByZWxvYWQgd2Ugd291bGQgaGF2ZVxuICAgIC8vIGFscmVhZHkgY2FuY2VsbGVkIGFsbCBwZW5kaW5nIGRlZmVycmVkcyBzbyB0aGlzIHdvdWxkIGJlIGEgbm8tb3BcbiAgICBjYW5jZWxBY3RpdmVEZWZlcnJlZHMocm91dGVJZCA9PiAhKG1hdGNoZXMgJiYgbWF0Y2hlcy5zb21lKG0gPT4gbS5yb3V0ZS5pZCA9PT0gcm91dGVJZCkpIHx8IG1hdGNoZXNUb0xvYWQgJiYgbWF0Y2hlc1RvTG9hZC5zb21lKG0gPT4gbS5yb3V0ZS5pZCA9PT0gcm91dGVJZCkpO1xuICAgIHBlbmRpbmdOYXZpZ2F0aW9uTG9hZElkID0gKytpbmNyZW1lbnRpbmdMb2FkSWQ7XG4gICAgLy8gU2hvcnQgY2lyY3VpdCBpZiB3ZSBoYXZlIG5vIGxvYWRlcnMgdG8gcnVuXG4gICAgaWYgKG1hdGNoZXNUb0xvYWQubGVuZ3RoID09PSAwICYmIHJldmFsaWRhdGluZ0ZldGNoZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgbGV0IHVwZGF0ZWRGZXRjaGVycyA9IG1hcmtGZXRjaFJlZGlyZWN0c0RvbmUoKTtcbiAgICAgIGNvbXBsZXRlTmF2aWdhdGlvbihsb2NhdGlvbiwgX2V4dGVuZHMoe1xuICAgICAgICBtYXRjaGVzLFxuICAgICAgICBsb2FkZXJEYXRhOiB7fSxcbiAgICAgICAgLy8gQ29tbWl0IHBlbmRpbmcgZXJyb3IgaWYgd2UncmUgc2hvcnQgY2lyY3VpdGluZ1xuICAgICAgICBlcnJvcnM6IHBlbmRpbmdFcnJvciB8fCBudWxsXG4gICAgICB9LCBwZW5kaW5nQWN0aW9uRGF0YSA/IHtcbiAgICAgICAgYWN0aW9uRGF0YTogcGVuZGluZ0FjdGlvbkRhdGFcbiAgICAgIH0gOiB7fSwgdXBkYXRlZEZldGNoZXJzID8ge1xuICAgICAgICBmZXRjaGVyczogbmV3IE1hcChzdGF0ZS5mZXRjaGVycylcbiAgICAgIH0gOiB7fSkpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc2hvcnRDaXJjdWl0ZWQ6IHRydWVcbiAgICAgIH07XG4gICAgfVxuICAgIC8vIElmIHRoaXMgaXMgYW4gdW5pbnRlcnJ1cHRlZCByZXZhbGlkYXRpb24sIHdlIHJlbWFpbiBpbiBvdXIgY3VycmVudCBpZGxlXG4gICAgLy8gc3RhdGUuICBJZiBub3QsIHdlIG5lZWQgdG8gc3dpdGNoIHRvIG91ciBsb2FkaW5nIHN0YXRlIGFuZCBsb2FkIGRhdGEsXG4gICAgLy8gcHJlc2VydmluZyBhbnkgbmV3IGFjdGlvbiBkYXRhIG9yIGV4aXN0aW5nIGFjdGlvbiBkYXRhIChpbiB0aGUgY2FzZSBvZlxuICAgIC8vIGEgcmV2YWxpZGF0aW9uIGludGVycnVwdGluZyBhbiBhY3Rpb25SZWxvYWQpXG4gICAgaWYgKCFpc1VuaW50ZXJydXB0ZWRSZXZhbGlkYXRpb24pIHtcbiAgICAgIHJldmFsaWRhdGluZ0ZldGNoZXJzLmZvckVhY2gocmYgPT4ge1xuICAgICAgICBsZXQgZmV0Y2hlciA9IHN0YXRlLmZldGNoZXJzLmdldChyZi5rZXkpO1xuICAgICAgICBsZXQgcmV2YWxpZGF0aW5nRmV0Y2hlciA9IGdldExvYWRpbmdGZXRjaGVyKHVuZGVmaW5lZCwgZmV0Y2hlciA/IGZldGNoZXIuZGF0YSA6IHVuZGVmaW5lZCk7XG4gICAgICAgIHN0YXRlLmZldGNoZXJzLnNldChyZi5rZXksIHJldmFsaWRhdGluZ0ZldGNoZXIpO1xuICAgICAgfSk7XG4gICAgICBsZXQgYWN0aW9uRGF0YSA9IHBlbmRpbmdBY3Rpb25EYXRhIHx8IHN0YXRlLmFjdGlvbkRhdGE7XG4gICAgICB1cGRhdGVTdGF0ZShfZXh0ZW5kcyh7XG4gICAgICAgIG5hdmlnYXRpb246IGxvYWRpbmdOYXZpZ2F0aW9uXG4gICAgICB9LCBhY3Rpb25EYXRhID8gT2JqZWN0LmtleXMoYWN0aW9uRGF0YSkubGVuZ3RoID09PSAwID8ge1xuICAgICAgICBhY3Rpb25EYXRhOiBudWxsXG4gICAgICB9IDoge1xuICAgICAgICBhY3Rpb25EYXRhXG4gICAgICB9IDoge30sIHJldmFsaWRhdGluZ0ZldGNoZXJzLmxlbmd0aCA+IDAgPyB7XG4gICAgICAgIGZldGNoZXJzOiBuZXcgTWFwKHN0YXRlLmZldGNoZXJzKVxuICAgICAgfSA6IHt9KSk7XG4gICAgfVxuICAgIHJldmFsaWRhdGluZ0ZldGNoZXJzLmZvckVhY2gocmYgPT4ge1xuICAgICAgaWYgKGZldGNoQ29udHJvbGxlcnMuaGFzKHJmLmtleSkpIHtcbiAgICAgICAgYWJvcnRGZXRjaGVyKHJmLmtleSk7XG4gICAgICB9XG4gICAgICBpZiAocmYuY29udHJvbGxlcikge1xuICAgICAgICAvLyBGZXRjaGVycyB1c2UgYW4gaW5kZXBlbmRlbnQgQWJvcnRDb250cm9sbGVyIHNvIHRoYXQgYWJvcnRpbmcgYSBmZXRjaGVyXG4gICAgICAgIC8vICh2aWEgZGVsZXRlRmV0Y2hlcikgZG9lcyBub3QgYWJvcnQgdGhlIHRyaWdnZXJpbmcgbmF2aWdhdGlvbiB0aGF0XG4gICAgICAgIC8vIHRyaWdnZXJlZCB0aGUgcmV2YWxpZGF0aW9uXG4gICAgICAgIGZldGNoQ29udHJvbGxlcnMuc2V0KHJmLmtleSwgcmYuY29udHJvbGxlcik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgLy8gUHJveHkgbmF2aWdhdGlvbiBhYm9ydCB0aHJvdWdoIHRvIHJldmFsaWRhdGlvbiBmZXRjaGVyc1xuICAgIGxldCBhYm9ydFBlbmRpbmdGZXRjaFJldmFsaWRhdGlvbnMgPSAoKSA9PiByZXZhbGlkYXRpbmdGZXRjaGVycy5mb3JFYWNoKGYgPT4gYWJvcnRGZXRjaGVyKGYua2V5KSk7XG4gICAgaWYgKHBlbmRpbmdOYXZpZ2F0aW9uQ29udHJvbGxlcikge1xuICAgICAgcGVuZGluZ05hdmlnYXRpb25Db250cm9sbGVyLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgYWJvcnRQZW5kaW5nRmV0Y2hSZXZhbGlkYXRpb25zKTtcbiAgICB9XG4gICAgbGV0IHtcbiAgICAgIHJlc3VsdHMsXG4gICAgICBsb2FkZXJSZXN1bHRzLFxuICAgICAgZmV0Y2hlclJlc3VsdHNcbiAgICB9ID0gYXdhaXQgY2FsbExvYWRlcnNBbmRNYXliZVJlc29sdmVEYXRhKHN0YXRlLm1hdGNoZXMsIG1hdGNoZXMsIG1hdGNoZXNUb0xvYWQsIHJldmFsaWRhdGluZ0ZldGNoZXJzLCByZXF1ZXN0KTtcbiAgICBpZiAocmVxdWVzdC5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgc2hvcnRDaXJjdWl0ZWQ6IHRydWVcbiAgICAgIH07XG4gICAgfVxuICAgIC8vIENsZWFuIHVwIF9hZnRlcl8gbG9hZGVycyBoYXZlIGNvbXBsZXRlZC4gIERvbid0IGNsZWFuIHVwIGlmIHdlIHNob3J0XG4gICAgLy8gY2lyY3VpdGVkIGJlY2F1c2UgZmV0Y2hDb250cm9sbGVycyB3b3VsZCBoYXZlIGJlZW4gYWJvcnRlZCBhbmRcbiAgICAvLyByZWFzc2lnbmVkIHRvIG5ldyBjb250cm9sbGVycyBmb3IgdGhlIG5leHQgbmF2aWdhdGlvblxuICAgIGlmIChwZW5kaW5nTmF2aWdhdGlvbkNvbnRyb2xsZXIpIHtcbiAgICAgIHBlbmRpbmdOYXZpZ2F0aW9uQ29udHJvbGxlci5zaWduYWwucmVtb3ZlRXZlbnRMaXN0ZW5lcihcImFib3J0XCIsIGFib3J0UGVuZGluZ0ZldGNoUmV2YWxpZGF0aW9ucyk7XG4gICAgfVxuICAgIHJldmFsaWRhdGluZ0ZldGNoZXJzLmZvckVhY2gocmYgPT4gZmV0Y2hDb250cm9sbGVycy5kZWxldGUocmYua2V5KSk7XG4gICAgLy8gSWYgYW55IGxvYWRlcnMgcmV0dXJuZWQgYSByZWRpcmVjdCBSZXNwb25zZSwgc3RhcnQgYSBuZXcgUkVQTEFDRSBuYXZpZ2F0aW9uXG4gICAgbGV0IHJlZGlyZWN0ID0gZmluZFJlZGlyZWN0KHJlc3VsdHMpO1xuICAgIGlmIChyZWRpcmVjdCkge1xuICAgICAgaWYgKHJlZGlyZWN0LmlkeCA+PSBtYXRjaGVzVG9Mb2FkLmxlbmd0aCkge1xuICAgICAgICAvLyBJZiB0aGlzIHJlZGlyZWN0IGNhbWUgZnJvbSBhIGZldGNoZXIgbWFrZSBzdXJlIHdlIG1hcmsgaXQgaW5cbiAgICAgICAgLy8gZmV0Y2hSZWRpcmVjdElkcyBzbyBpdCBkb2Vzbid0IGdldCByZXZhbGlkYXRlZCBvbiB0aGUgbmV4dCBzZXQgb2ZcbiAgICAgICAgLy8gbG9hZGVyIGV4ZWN1dGlvbnNcbiAgICAgICAgbGV0IGZldGNoZXJLZXkgPSByZXZhbGlkYXRpbmdGZXRjaGVyc1tyZWRpcmVjdC5pZHggLSBtYXRjaGVzVG9Mb2FkLmxlbmd0aF0ua2V5O1xuICAgICAgICBmZXRjaFJlZGlyZWN0SWRzLmFkZChmZXRjaGVyS2V5KTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHN0YXJ0UmVkaXJlY3ROYXZpZ2F0aW9uKHN0YXRlLCByZWRpcmVjdC5yZXN1bHQsIHtcbiAgICAgICAgcmVwbGFjZVxuICAgICAgfSk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzaG9ydENpcmN1aXRlZDogdHJ1ZVxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gUHJvY2VzcyBhbmQgY29tbWl0IG91dHB1dCBmcm9tIGxvYWRlcnNcbiAgICBsZXQge1xuICAgICAgbG9hZGVyRGF0YSxcbiAgICAgIGVycm9yc1xuICAgIH0gPSBwcm9jZXNzTG9hZGVyRGF0YShzdGF0ZSwgbWF0Y2hlcywgbWF0Y2hlc1RvTG9hZCwgbG9hZGVyUmVzdWx0cywgcGVuZGluZ0Vycm9yLCByZXZhbGlkYXRpbmdGZXRjaGVycywgZmV0Y2hlclJlc3VsdHMsIGFjdGl2ZURlZmVycmVkcyk7XG4gICAgLy8gV2lyZSB1cCBzdWJzY3JpYmVycyB0byB1cGRhdGUgbG9hZGVyRGF0YSBhcyBwcm9taXNlcyBzZXR0bGVcbiAgICBhY3RpdmVEZWZlcnJlZHMuZm9yRWFjaCgoZGVmZXJyZWREYXRhLCByb3V0ZUlkKSA9PiB7XG4gICAgICBkZWZlcnJlZERhdGEuc3Vic2NyaWJlKGFib3J0ZWQgPT4ge1xuICAgICAgICAvLyBOb3RlOiBObyBuZWVkIHRvIHVwZGF0ZVN0YXRlIGhlcmUgc2luY2UgdGhlIFRyYWNrZWRQcm9taXNlIG9uXG4gICAgICAgIC8vIGxvYWRlckRhdGEgaXMgc3RhYmxlIGFjcm9zcyByZXNvbHZlL3JlamVjdFxuICAgICAgICAvLyBSZW1vdmUgdGhpcyBpbnN0YW5jZSBpZiB3ZSB3ZXJlIGFib3J0ZWQgb3IgaWYgcHJvbWlzZXMgaGF2ZSBzZXR0bGVkXG4gICAgICAgIGlmIChhYm9ydGVkIHx8IGRlZmVycmVkRGF0YS5kb25lKSB7XG4gICAgICAgICAgYWN0aXZlRGVmZXJyZWRzLmRlbGV0ZShyb3V0ZUlkKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSk7XG4gICAgbGV0IHVwZGF0ZWRGZXRjaGVycyA9IG1hcmtGZXRjaFJlZGlyZWN0c0RvbmUoKTtcbiAgICBsZXQgZGlkQWJvcnRGZXRjaExvYWRzID0gYWJvcnRTdGFsZUZldGNoTG9hZHMocGVuZGluZ05hdmlnYXRpb25Mb2FkSWQpO1xuICAgIGxldCBzaG91bGRVcGRhdGVGZXRjaGVycyA9IHVwZGF0ZWRGZXRjaGVycyB8fCBkaWRBYm9ydEZldGNoTG9hZHMgfHwgcmV2YWxpZGF0aW5nRmV0Y2hlcnMubGVuZ3RoID4gMDtcbiAgICByZXR1cm4gX2V4dGVuZHMoe1xuICAgICAgbG9hZGVyRGF0YSxcbiAgICAgIGVycm9yc1xuICAgIH0sIHNob3VsZFVwZGF0ZUZldGNoZXJzID8ge1xuICAgICAgZmV0Y2hlcnM6IG5ldyBNYXAoc3RhdGUuZmV0Y2hlcnMpXG4gICAgfSA6IHt9KTtcbiAgfVxuICBmdW5jdGlvbiBnZXRGZXRjaGVyKGtleSkge1xuICAgIHJldHVybiBzdGF0ZS5mZXRjaGVycy5nZXQoa2V5KSB8fCBJRExFX0ZFVENIRVI7XG4gIH1cbiAgLy8gVHJpZ2dlciBhIGZldGNoZXIgbG9hZC9zdWJtaXQgZm9yIHRoZSBnaXZlbiBmZXRjaGVyIGtleVxuICBmdW5jdGlvbiBmZXRjaChrZXksIHJvdXRlSWQsIGhyZWYsIG9wdHMpIHtcbiAgICBpZiAoaXNTZXJ2ZXIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcInJvdXRlci5mZXRjaCgpIHdhcyBjYWxsZWQgZHVyaW5nIHRoZSBzZXJ2ZXIgcmVuZGVyLCBidXQgaXQgc2hvdWxkbid0IGJlLiBcIiArIFwiWW91IGFyZSBsaWtlbHkgY2FsbGluZyBhIHVzZUZldGNoZXIoKSBtZXRob2QgaW4gdGhlIGJvZHkgb2YgeW91ciBjb21wb25lbnQuIFwiICsgXCJUcnkgbW92aW5nIGl0IHRvIGEgdXNlRWZmZWN0IG9yIGEgY2FsbGJhY2suXCIpO1xuICAgIH1cbiAgICBpZiAoZmV0Y2hDb250cm9sbGVycy5oYXMoa2V5KSkgYWJvcnRGZXRjaGVyKGtleSk7XG4gICAgbGV0IHJvdXRlc1RvVXNlID0gaW5GbGlnaHREYXRhUm91dGVzIHx8IGRhdGFSb3V0ZXM7XG4gICAgbGV0IG5vcm1hbGl6ZWRQYXRoID0gbm9ybWFsaXplVG8oc3RhdGUubG9jYXRpb24sIHN0YXRlLm1hdGNoZXMsIGJhc2VuYW1lLCBmdXR1cmUudjdfcHJlcGVuZEJhc2VuYW1lLCBocmVmLCByb3V0ZUlkLCBvcHRzID09IG51bGwgPyB2b2lkIDAgOiBvcHRzLnJlbGF0aXZlKTtcbiAgICBsZXQgbWF0Y2hlcyA9IG1hdGNoUm91dGVzKHJvdXRlc1RvVXNlLCBub3JtYWxpemVkUGF0aCwgYmFzZW5hbWUpO1xuICAgIGlmICghbWF0Y2hlcykge1xuICAgICAgc2V0RmV0Y2hlckVycm9yKGtleSwgcm91dGVJZCwgZ2V0SW50ZXJuYWxSb3V0ZXJFcnJvcig0MDQsIHtcbiAgICAgICAgcGF0aG5hbWU6IG5vcm1hbGl6ZWRQYXRoXG4gICAgICB9KSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCB7XG4gICAgICBwYXRoLFxuICAgICAgc3VibWlzc2lvbixcbiAgICAgIGVycm9yXG4gICAgfSA9IG5vcm1hbGl6ZU5hdmlnYXRlT3B0aW9ucyhmdXR1cmUudjdfbm9ybWFsaXplRm9ybU1ldGhvZCwgdHJ1ZSwgbm9ybWFsaXplZFBhdGgsIG9wdHMpO1xuICAgIGlmIChlcnJvcikge1xuICAgICAgc2V0RmV0Y2hlckVycm9yKGtleSwgcm91dGVJZCwgZXJyb3IpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBsZXQgbWF0Y2ggPSBnZXRUYXJnZXRNYXRjaChtYXRjaGVzLCBwYXRoKTtcbiAgICBwZW5kaW5nUHJldmVudFNjcm9sbFJlc2V0ID0gKG9wdHMgJiYgb3B0cy5wcmV2ZW50U2Nyb2xsUmVzZXQpID09PSB0cnVlO1xuICAgIGlmIChzdWJtaXNzaW9uICYmIGlzTXV0YXRpb25NZXRob2Qoc3VibWlzc2lvbi5mb3JtTWV0aG9kKSkge1xuICAgICAgaGFuZGxlRmV0Y2hlckFjdGlvbihrZXksIHJvdXRlSWQsIHBhdGgsIG1hdGNoLCBtYXRjaGVzLCBzdWJtaXNzaW9uKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gU3RvcmUgb2ZmIHRoZSBtYXRjaCBzbyB3ZSBjYW4gY2FsbCBpdCdzIHNob3VsZFJldmFsaWRhdGUgb24gc3Vic2VxdWVudFxuICAgIC8vIHJldmFsaWRhdGlvbnNcbiAgICBmZXRjaExvYWRNYXRjaGVzLnNldChrZXksIHtcbiAgICAgIHJvdXRlSWQsXG4gICAgICBwYXRoXG4gICAgfSk7XG4gICAgaGFuZGxlRmV0Y2hlckxvYWRlcihrZXksIHJvdXRlSWQsIHBhdGgsIG1hdGNoLCBtYXRjaGVzLCBzdWJtaXNzaW9uKTtcbiAgfVxuICAvLyBDYWxsIHRoZSBhY3Rpb24gZm9yIHRoZSBtYXRjaGVkIGZldGNoZXIuc3VibWl0KCksIGFuZCB0aGVuIGhhbmRsZSByZWRpcmVjdHMsXG4gIC8vIGVycm9ycywgYW5kIHJldmFsaWRhdGlvblxuICBhc3luYyBmdW5jdGlvbiBoYW5kbGVGZXRjaGVyQWN0aW9uKGtleSwgcm91dGVJZCwgcGF0aCwgbWF0Y2gsIHJlcXVlc3RNYXRjaGVzLCBzdWJtaXNzaW9uKSB7XG4gICAgaW50ZXJydXB0QWN0aXZlTG9hZHMoKTtcbiAgICBmZXRjaExvYWRNYXRjaGVzLmRlbGV0ZShrZXkpO1xuICAgIGlmICghbWF0Y2gucm91dGUuYWN0aW9uICYmICFtYXRjaC5yb3V0ZS5sYXp5KSB7XG4gICAgICBsZXQgZXJyb3IgPSBnZXRJbnRlcm5hbFJvdXRlckVycm9yKDQwNSwge1xuICAgICAgICBtZXRob2Q6IHN1Ym1pc3Npb24uZm9ybU1ldGhvZCxcbiAgICAgICAgcGF0aG5hbWU6IHBhdGgsXG4gICAgICAgIHJvdXRlSWQ6IHJvdXRlSWRcbiAgICAgIH0pO1xuICAgICAgc2V0RmV0Y2hlckVycm9yKGtleSwgcm91dGVJZCwgZXJyb3IpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBQdXQgdGhpcyBmZXRjaGVyIGludG8gaXQncyBzdWJtaXR0aW5nIHN0YXRlXG4gICAgbGV0IGV4aXN0aW5nRmV0Y2hlciA9IHN0YXRlLmZldGNoZXJzLmdldChrZXkpO1xuICAgIGxldCBmZXRjaGVyID0gZ2V0U3VibWl0dGluZ0ZldGNoZXIoc3VibWlzc2lvbiwgZXhpc3RpbmdGZXRjaGVyKTtcbiAgICBzdGF0ZS5mZXRjaGVycy5zZXQoa2V5LCBmZXRjaGVyKTtcbiAgICB1cGRhdGVTdGF0ZSh7XG4gICAgICBmZXRjaGVyczogbmV3IE1hcChzdGF0ZS5mZXRjaGVycylcbiAgICB9KTtcbiAgICAvLyBDYWxsIHRoZSBhY3Rpb24gZm9yIHRoZSBmZXRjaGVyXG4gICAgbGV0IGFib3J0Q29udHJvbGxlciA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgICBsZXQgZmV0Y2hSZXF1ZXN0ID0gY3JlYXRlQ2xpZW50U2lkZVJlcXVlc3QoaW5pdC5oaXN0b3J5LCBwYXRoLCBhYm9ydENvbnRyb2xsZXIuc2lnbmFsLCBzdWJtaXNzaW9uKTtcbiAgICBmZXRjaENvbnRyb2xsZXJzLnNldChrZXksIGFib3J0Q29udHJvbGxlcik7XG4gICAgbGV0IG9yaWdpbmF0aW5nTG9hZElkID0gaW5jcmVtZW50aW5nTG9hZElkO1xuICAgIGxldCBhY3Rpb25SZXN1bHQgPSBhd2FpdCBjYWxsTG9hZGVyT3JBY3Rpb24oXCJhY3Rpb25cIiwgZmV0Y2hSZXF1ZXN0LCBtYXRjaCwgcmVxdWVzdE1hdGNoZXMsIG1hbmlmZXN0LCBtYXBSb3V0ZVByb3BlcnRpZXMsIGJhc2VuYW1lKTtcbiAgICBpZiAoZmV0Y2hSZXF1ZXN0LnNpZ25hbC5hYm9ydGVkKSB7XG4gICAgICAvLyBXZSBjYW4gZGVsZXRlIHRoaXMgc28gbG9uZyBhcyB3ZSB3ZXJlbid0IGFib3J0ZWQgYnkgb3Ugb3VyIG93biBmZXRjaGVyXG4gICAgICAvLyByZS1zdWJtaXQgd2hpY2ggd291bGQgaGF2ZSBwdXQgX25ld18gY29udHJvbGxlciBpcyBpbiBmZXRjaENvbnRyb2xsZXJzXG4gICAgICBpZiAoZmV0Y2hDb250cm9sbGVycy5nZXQoa2V5KSA9PT0gYWJvcnRDb250cm9sbGVyKSB7XG4gICAgICAgIGZldGNoQ29udHJvbGxlcnMuZGVsZXRlKGtleSk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChpc1JlZGlyZWN0UmVzdWx0KGFjdGlvblJlc3VsdCkpIHtcbiAgICAgIGZldGNoQ29udHJvbGxlcnMuZGVsZXRlKGtleSk7XG4gICAgICBpZiAocGVuZGluZ05hdmlnYXRpb25Mb2FkSWQgPiBvcmlnaW5hdGluZ0xvYWRJZCkge1xuICAgICAgICAvLyBBIG5ldyBuYXZpZ2F0aW9uIHdhcyBraWNrZWQgb2ZmIGFmdGVyIG91ciBhY3Rpb24gc3RhcnRlZCwgc28gdGhhdFxuICAgICAgICAvLyBzaG91bGQgdGFrZSBwcmVjZWRlbmNlIG92ZXIgdGhpcyByZWRpcmVjdCBuYXZpZ2F0aW9uLiAgV2UgYWxyZWFkeVxuICAgICAgICAvLyBzZXQgaXNSZXZhbGlkYXRpb25SZXF1aXJlZCBzbyBhbGwgbG9hZGVycyBmb3IgdGhlIG5ldyByb3V0ZSBzaG91bGRcbiAgICAgICAgLy8gZmlyZSB1bmxlc3Mgb3B0ZWQgb3V0IHZpYSBzaG91bGRSZXZhbGlkYXRlXG4gICAgICAgIGxldCBkb25lRmV0Y2hlciA9IGdldERvbmVGZXRjaGVyKHVuZGVmaW5lZCk7XG4gICAgICAgIHN0YXRlLmZldGNoZXJzLnNldChrZXksIGRvbmVGZXRjaGVyKTtcbiAgICAgICAgdXBkYXRlU3RhdGUoe1xuICAgICAgICAgIGZldGNoZXJzOiBuZXcgTWFwKHN0YXRlLmZldGNoZXJzKVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZmV0Y2hSZWRpcmVjdElkcy5hZGQoa2V5KTtcbiAgICAgICAgbGV0IGxvYWRpbmdGZXRjaGVyID0gZ2V0TG9hZGluZ0ZldGNoZXIoc3VibWlzc2lvbik7XG4gICAgICAgIHN0YXRlLmZldGNoZXJzLnNldChrZXksIGxvYWRpbmdGZXRjaGVyKTtcbiAgICAgICAgdXBkYXRlU3RhdGUoe1xuICAgICAgICAgIGZldGNoZXJzOiBuZXcgTWFwKHN0YXRlLmZldGNoZXJzKVxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIHN0YXJ0UmVkaXJlY3ROYXZpZ2F0aW9uKHN0YXRlLCBhY3Rpb25SZXN1bHQsIHtcbiAgICAgICAgICBzdWJtaXNzaW9uLFxuICAgICAgICAgIGlzRmV0Y2hBY3Rpb25SZWRpcmVjdDogdHJ1ZVxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gUHJvY2VzcyBhbnkgbm9uLXJlZGlyZWN0IGVycm9ycyB0aHJvd25cbiAgICBpZiAoaXNFcnJvclJlc3VsdChhY3Rpb25SZXN1bHQpKSB7XG4gICAgICBzZXRGZXRjaGVyRXJyb3Ioa2V5LCByb3V0ZUlkLCBhY3Rpb25SZXN1bHQuZXJyb3IpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoaXNEZWZlcnJlZFJlc3VsdChhY3Rpb25SZXN1bHQpKSB7XG4gICAgICB0aHJvdyBnZXRJbnRlcm5hbFJvdXRlckVycm9yKDQwMCwge1xuICAgICAgICB0eXBlOiBcImRlZmVyLWFjdGlvblwiXG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gU3RhcnQgdGhlIGRhdGEgbG9hZCBmb3IgY3VycmVudCBtYXRjaGVzLCBvciB0aGUgbmV4dCBsb2NhdGlvbiBpZiB3ZSdyZVxuICAgIC8vIGluIHRoZSBtaWRkbGUgb2YgYSBuYXZpZ2F0aW9uXG4gICAgbGV0IG5leHRMb2NhdGlvbiA9IHN0YXRlLm5hdmlnYXRpb24ubG9jYXRpb24gfHwgc3RhdGUubG9jYXRpb247XG4gICAgbGV0IHJldmFsaWRhdGlvblJlcXVlc3QgPSBjcmVhdGVDbGllbnRTaWRlUmVxdWVzdChpbml0Lmhpc3RvcnksIG5leHRMb2NhdGlvbiwgYWJvcnRDb250cm9sbGVyLnNpZ25hbCk7XG4gICAgbGV0IHJvdXRlc1RvVXNlID0gaW5GbGlnaHREYXRhUm91dGVzIHx8IGRhdGFSb3V0ZXM7XG4gICAgbGV0IG1hdGNoZXMgPSBzdGF0ZS5uYXZpZ2F0aW9uLnN0YXRlICE9PSBcImlkbGVcIiA/IG1hdGNoUm91dGVzKHJvdXRlc1RvVXNlLCBzdGF0ZS5uYXZpZ2F0aW9uLmxvY2F0aW9uLCBiYXNlbmFtZSkgOiBzdGF0ZS5tYXRjaGVzO1xuICAgIGludmFyaWFudChtYXRjaGVzLCBcIkRpZG4ndCBmaW5kIGFueSBtYXRjaGVzIGFmdGVyIGZldGNoZXIgYWN0aW9uXCIpO1xuICAgIGxldCBsb2FkSWQgPSArK2luY3JlbWVudGluZ0xvYWRJZDtcbiAgICBmZXRjaFJlbG9hZElkcy5zZXQoa2V5LCBsb2FkSWQpO1xuICAgIGxldCBsb2FkRmV0Y2hlciA9IGdldExvYWRpbmdGZXRjaGVyKHN1Ym1pc3Npb24sIGFjdGlvblJlc3VsdC5kYXRhKTtcbiAgICBzdGF0ZS5mZXRjaGVycy5zZXQoa2V5LCBsb2FkRmV0Y2hlcik7XG4gICAgbGV0IFttYXRjaGVzVG9Mb2FkLCByZXZhbGlkYXRpbmdGZXRjaGVyc10gPSBnZXRNYXRjaGVzVG9Mb2FkKGluaXQuaGlzdG9yeSwgc3RhdGUsIG1hdGNoZXMsIHN1Ym1pc3Npb24sIG5leHRMb2NhdGlvbiwgaXNSZXZhbGlkYXRpb25SZXF1aXJlZCwgY2FuY2VsbGVkRGVmZXJyZWRSb3V0ZXMsIGNhbmNlbGxlZEZldGNoZXJMb2FkcywgZmV0Y2hMb2FkTWF0Y2hlcywgZmV0Y2hSZWRpcmVjdElkcywgcm91dGVzVG9Vc2UsIGJhc2VuYW1lLCB7XG4gICAgICBbbWF0Y2gucm91dGUuaWRdOiBhY3Rpb25SZXN1bHQuZGF0YVxuICAgIH0sIHVuZGVmaW5lZCAvLyBObyBuZWVkIHRvIHNlbmQgdGhyb3VnaCBlcnJvcnMgc2luY2Ugd2Ugc2hvcnQgY2lyY3VpdCBhYm92ZVxuICAgICk7XG4gICAgLy8gUHV0IGFsbCByZXZhbGlkYXRpbmcgZmV0Y2hlcnMgaW50byB0aGUgbG9hZGluZyBzdGF0ZSwgZXhjZXB0IGZvciB0aGVcbiAgICAvLyBjdXJyZW50IGZldGNoZXIgd2hpY2ggd2Ugd2FudCB0byBrZWVwIGluIGl0J3MgY3VycmVudCBsb2FkaW5nIHN0YXRlIHdoaWNoXG4gICAgLy8gY29udGFpbnMgaXQncyBhY3Rpb24gc3VibWlzc2lvbiBpbmZvICsgYWN0aW9uIGRhdGFcbiAgICByZXZhbGlkYXRpbmdGZXRjaGVycy5maWx0ZXIocmYgPT4gcmYua2V5ICE9PSBrZXkpLmZvckVhY2gocmYgPT4ge1xuICAgICAgbGV0IHN0YWxlS2V5ID0gcmYua2V5O1xuICAgICAgbGV0IGV4aXN0aW5nRmV0Y2hlciA9IHN0YXRlLmZldGNoZXJzLmdldChzdGFsZUtleSk7XG4gICAgICBsZXQgcmV2YWxpZGF0aW5nRmV0Y2hlciA9IGdldExvYWRpbmdGZXRjaGVyKHVuZGVmaW5lZCwgZXhpc3RpbmdGZXRjaGVyID8gZXhpc3RpbmdGZXRjaGVyLmRhdGEgOiB1bmRlZmluZWQpO1xuICAgICAgc3RhdGUuZmV0Y2hlcnMuc2V0KHN0YWxlS2V5LCByZXZhbGlkYXRpbmdGZXRjaGVyKTtcbiAgICAgIGlmIChmZXRjaENvbnRyb2xsZXJzLmhhcyhzdGFsZUtleSkpIHtcbiAgICAgICAgYWJvcnRGZXRjaGVyKHN0YWxlS2V5KTtcbiAgICAgIH1cbiAgICAgIGlmIChyZi5jb250cm9sbGVyKSB7XG4gICAgICAgIGZldGNoQ29udHJvbGxlcnMuc2V0KHN0YWxlS2V5LCByZi5jb250cm9sbGVyKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICB1cGRhdGVTdGF0ZSh7XG4gICAgICBmZXRjaGVyczogbmV3IE1hcChzdGF0ZS5mZXRjaGVycylcbiAgICB9KTtcbiAgICBsZXQgYWJvcnRQZW5kaW5nRmV0Y2hSZXZhbGlkYXRpb25zID0gKCkgPT4gcmV2YWxpZGF0aW5nRmV0Y2hlcnMuZm9yRWFjaChyZiA9PiBhYm9ydEZldGNoZXIocmYua2V5KSk7XG4gICAgYWJvcnRDb250cm9sbGVyLnNpZ25hbC5hZGRFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgYWJvcnRQZW5kaW5nRmV0Y2hSZXZhbGlkYXRpb25zKTtcbiAgICBsZXQge1xuICAgICAgcmVzdWx0cyxcbiAgICAgIGxvYWRlclJlc3VsdHMsXG4gICAgICBmZXRjaGVyUmVzdWx0c1xuICAgIH0gPSBhd2FpdCBjYWxsTG9hZGVyc0FuZE1heWJlUmVzb2x2ZURhdGEoc3RhdGUubWF0Y2hlcywgbWF0Y2hlcywgbWF0Y2hlc1RvTG9hZCwgcmV2YWxpZGF0aW5nRmV0Y2hlcnMsIHJldmFsaWRhdGlvblJlcXVlc3QpO1xuICAgIGlmIChhYm9ydENvbnRyb2xsZXIuc2lnbmFsLmFib3J0ZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgYWJvcnRDb250cm9sbGVyLnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgYWJvcnRQZW5kaW5nRmV0Y2hSZXZhbGlkYXRpb25zKTtcbiAgICBmZXRjaFJlbG9hZElkcy5kZWxldGUoa2V5KTtcbiAgICBmZXRjaENvbnRyb2xsZXJzLmRlbGV0ZShrZXkpO1xuICAgIHJldmFsaWRhdGluZ0ZldGNoZXJzLmZvckVhY2gociA9PiBmZXRjaENvbnRyb2xsZXJzLmRlbGV0ZShyLmtleSkpO1xuICAgIGxldCByZWRpcmVjdCA9IGZpbmRSZWRpcmVjdChyZXN1bHRzKTtcbiAgICBpZiAocmVkaXJlY3QpIHtcbiAgICAgIGlmIChyZWRpcmVjdC5pZHggPj0gbWF0Y2hlc1RvTG9hZC5sZW5ndGgpIHtcbiAgICAgICAgLy8gSWYgdGhpcyByZWRpcmVjdCBjYW1lIGZyb20gYSBmZXRjaGVyIG1ha2Ugc3VyZSB3ZSBtYXJrIGl0IGluXG4gICAgICAgIC8vIGZldGNoUmVkaXJlY3RJZHMgc28gaXQgZG9lc24ndCBnZXQgcmV2YWxpZGF0ZWQgb24gdGhlIG5leHQgc2V0IG9mXG4gICAgICAgIC8vIGxvYWRlciBleGVjdXRpb25zXG4gICAgICAgIGxldCBmZXRjaGVyS2V5ID0gcmV2YWxpZGF0aW5nRmV0Y2hlcnNbcmVkaXJlY3QuaWR4IC0gbWF0Y2hlc1RvTG9hZC5sZW5ndGhdLmtleTtcbiAgICAgICAgZmV0Y2hSZWRpcmVjdElkcy5hZGQoZmV0Y2hlcktleSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gc3RhcnRSZWRpcmVjdE5hdmlnYXRpb24oc3RhdGUsIHJlZGlyZWN0LnJlc3VsdCk7XG4gICAgfVxuICAgIC8vIFByb2Nlc3MgYW5kIGNvbW1pdCBvdXRwdXQgZnJvbSBsb2FkZXJzXG4gICAgbGV0IHtcbiAgICAgIGxvYWRlckRhdGEsXG4gICAgICBlcnJvcnNcbiAgICB9ID0gcHJvY2Vzc0xvYWRlckRhdGEoc3RhdGUsIHN0YXRlLm1hdGNoZXMsIG1hdGNoZXNUb0xvYWQsIGxvYWRlclJlc3VsdHMsIHVuZGVmaW5lZCwgcmV2YWxpZGF0aW5nRmV0Y2hlcnMsIGZldGNoZXJSZXN1bHRzLCBhY3RpdmVEZWZlcnJlZHMpO1xuICAgIC8vIFNpbmNlIHdlIGxldCByZXZhbGlkYXRpb25zIGNvbXBsZXRlIGV2ZW4gaWYgdGhlIHN1Ym1pdHRpbmcgZmV0Y2hlciB3YXNcbiAgICAvLyBkZWxldGVkLCBvbmx5IHB1dCBpdCBiYWNrIHRvIGlkbGUgaWYgaXQgaGFzbid0IGJlZW4gZGVsZXRlZFxuICAgIGlmIChzdGF0ZS5mZXRjaGVycy5oYXMoa2V5KSkge1xuICAgICAgbGV0IGRvbmVGZXRjaGVyID0gZ2V0RG9uZUZldGNoZXIoYWN0aW9uUmVzdWx0LmRhdGEpO1xuICAgICAgc3RhdGUuZmV0Y2hlcnMuc2V0KGtleSwgZG9uZUZldGNoZXIpO1xuICAgIH1cbiAgICBsZXQgZGlkQWJvcnRGZXRjaExvYWRzID0gYWJvcnRTdGFsZUZldGNoTG9hZHMobG9hZElkKTtcbiAgICAvLyBJZiB3ZSBhcmUgY3VycmVudGx5IGluIGEgbmF2aWdhdGlvbiBsb2FkaW5nIHN0YXRlIGFuZCB0aGlzIGZldGNoZXIgaXNcbiAgICAvLyBtb3JlIHJlY2VudCB0aGFuIHRoZSBuYXZpZ2F0aW9uLCB3ZSB3YW50IHRoZSBuZXdlciBkYXRhIHNvIGFib3J0IHRoZVxuICAgIC8vIG5hdmlnYXRpb24gYW5kIGNvbXBsZXRlIGl0IHdpdGggdGhlIGZldGNoZXIgZGF0YVxuICAgIGlmIChzdGF0ZS5uYXZpZ2F0aW9uLnN0YXRlID09PSBcImxvYWRpbmdcIiAmJiBsb2FkSWQgPiBwZW5kaW5nTmF2aWdhdGlvbkxvYWRJZCkge1xuICAgICAgaW52YXJpYW50KHBlbmRpbmdBY3Rpb24sIFwiRXhwZWN0ZWQgcGVuZGluZyBhY3Rpb25cIik7XG4gICAgICBwZW5kaW5nTmF2aWdhdGlvbkNvbnRyb2xsZXIgJiYgcGVuZGluZ05hdmlnYXRpb25Db250cm9sbGVyLmFib3J0KCk7XG4gICAgICBjb21wbGV0ZU5hdmlnYXRpb24oc3RhdGUubmF2aWdhdGlvbi5sb2NhdGlvbiwge1xuICAgICAgICBtYXRjaGVzLFxuICAgICAgICBsb2FkZXJEYXRhLFxuICAgICAgICBlcnJvcnMsXG4gICAgICAgIGZldGNoZXJzOiBuZXcgTWFwKHN0YXRlLmZldGNoZXJzKVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIG90aGVyd2lzZSBqdXN0IHVwZGF0ZSB3aXRoIHRoZSBmZXRjaGVyIGRhdGEsIHByZXNlcnZpbmcgYW55IGV4aXN0aW5nXG4gICAgICAvLyBsb2FkZXJEYXRhIGZvciBsb2FkZXJzIHRoYXQgZGlkIG5vdCBuZWVkIHRvIHJlbG9hZC4gIFdlIGhhdmUgdG9cbiAgICAgIC8vIG1hbnVhbGx5IG1lcmdlIGhlcmUgc2luY2Ugd2UgYXJlbid0IGdvaW5nIHRocm91Z2ggY29tcGxldGVOYXZpZ2F0aW9uXG4gICAgICB1cGRhdGVTdGF0ZShfZXh0ZW5kcyh7XG4gICAgICAgIGVycm9ycyxcbiAgICAgICAgbG9hZGVyRGF0YTogbWVyZ2VMb2FkZXJEYXRhKHN0YXRlLmxvYWRlckRhdGEsIGxvYWRlckRhdGEsIG1hdGNoZXMsIGVycm9ycylcbiAgICAgIH0sIGRpZEFib3J0RmV0Y2hMb2FkcyB8fCByZXZhbGlkYXRpbmdGZXRjaGVycy5sZW5ndGggPiAwID8ge1xuICAgICAgICBmZXRjaGVyczogbmV3IE1hcChzdGF0ZS5mZXRjaGVycylcbiAgICAgIH0gOiB7fSkpO1xuICAgICAgaXNSZXZhbGlkYXRpb25SZXF1aXJlZCA9IGZhbHNlO1xuICAgIH1cbiAgfVxuICAvLyBDYWxsIHRoZSBtYXRjaGVkIGxvYWRlciBmb3IgZmV0Y2hlci5sb2FkKCksIGhhbmRsaW5nIHJlZGlyZWN0cywgZXJyb3JzLCBldGMuXG4gIGFzeW5jIGZ1bmN0aW9uIGhhbmRsZUZldGNoZXJMb2FkZXIoa2V5LCByb3V0ZUlkLCBwYXRoLCBtYXRjaCwgbWF0Y2hlcywgc3VibWlzc2lvbikge1xuICAgIGxldCBleGlzdGluZ0ZldGNoZXIgPSBzdGF0ZS5mZXRjaGVycy5nZXQoa2V5KTtcbiAgICAvLyBQdXQgdGhpcyBmZXRjaGVyIGludG8gaXQncyBsb2FkaW5nIHN0YXRlXG4gICAgbGV0IGxvYWRpbmdGZXRjaGVyID0gZ2V0TG9hZGluZ0ZldGNoZXIoc3VibWlzc2lvbiwgZXhpc3RpbmdGZXRjaGVyID8gZXhpc3RpbmdGZXRjaGVyLmRhdGEgOiB1bmRlZmluZWQpO1xuICAgIHN0YXRlLmZldGNoZXJzLnNldChrZXksIGxvYWRpbmdGZXRjaGVyKTtcbiAgICB1cGRhdGVTdGF0ZSh7XG4gICAgICBmZXRjaGVyczogbmV3IE1hcChzdGF0ZS5mZXRjaGVycylcbiAgICB9KTtcbiAgICAvLyBDYWxsIHRoZSBsb2FkZXIgZm9yIHRoaXMgZmV0Y2hlciByb3V0ZSBtYXRjaFxuICAgIGxldCBhYm9ydENvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG4gICAgbGV0IGZldGNoUmVxdWVzdCA9IGNyZWF0ZUNsaWVudFNpZGVSZXF1ZXN0KGluaXQuaGlzdG9yeSwgcGF0aCwgYWJvcnRDb250cm9sbGVyLnNpZ25hbCk7XG4gICAgZmV0Y2hDb250cm9sbGVycy5zZXQoa2V5LCBhYm9ydENvbnRyb2xsZXIpO1xuICAgIGxldCBvcmlnaW5hdGluZ0xvYWRJZCA9IGluY3JlbWVudGluZ0xvYWRJZDtcbiAgICBsZXQgcmVzdWx0ID0gYXdhaXQgY2FsbExvYWRlck9yQWN0aW9uKFwibG9hZGVyXCIsIGZldGNoUmVxdWVzdCwgbWF0Y2gsIG1hdGNoZXMsIG1hbmlmZXN0LCBtYXBSb3V0ZVByb3BlcnRpZXMsIGJhc2VuYW1lKTtcbiAgICAvLyBEZWZlcnJlZCBpc24ndCBzdXBwb3J0ZWQgZm9yIGZldGNoZXIgbG9hZHMsIGF3YWl0IGV2ZXJ5dGhpbmcgYW5kIHRyZWF0IGl0XG4gICAgLy8gYXMgYSBub3JtYWwgbG9hZC4gIHJlc29sdmVEZWZlcnJlZERhdGEgd2lsbCByZXR1cm4gdW5kZWZpbmVkIGlmIHRoaXNcbiAgICAvLyBmZXRjaGVyIGdldHMgYWJvcnRlZCwgc28gd2UganVzdCBsZWF2ZSByZXN1bHQgdW50b3VjaGVkIGFuZCBzaG9ydCBjaXJjdWl0XG4gICAgLy8gYmVsb3cgaWYgdGhhdCBoYXBwZW5zXG4gICAgaWYgKGlzRGVmZXJyZWRSZXN1bHQocmVzdWx0KSkge1xuICAgICAgcmVzdWx0ID0gKGF3YWl0IHJlc29sdmVEZWZlcnJlZERhdGEocmVzdWx0LCBmZXRjaFJlcXVlc3Quc2lnbmFsLCB0cnVlKSkgfHwgcmVzdWx0O1xuICAgIH1cbiAgICAvLyBXZSBjYW4gZGVsZXRlIHRoaXMgc28gbG9uZyBhcyB3ZSB3ZXJlbid0IGFib3J0ZWQgYnkgb3VyIG91ciBvd24gZmV0Y2hlclxuICAgIC8vIHJlLWxvYWQgd2hpY2ggd291bGQgaGF2ZSBwdXQgX25ld18gY29udHJvbGxlciBpcyBpbiBmZXRjaENvbnRyb2xsZXJzXG4gICAgaWYgKGZldGNoQ29udHJvbGxlcnMuZ2V0KGtleSkgPT09IGFib3J0Q29udHJvbGxlcikge1xuICAgICAgZmV0Y2hDb250cm9sbGVycy5kZWxldGUoa2V5KTtcbiAgICB9XG4gICAgaWYgKGZldGNoUmVxdWVzdC5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBJZiB0aGUgbG9hZGVyIHRocmV3IGEgcmVkaXJlY3QgUmVzcG9uc2UsIHN0YXJ0IGEgbmV3IFJFUExBQ0UgbmF2aWdhdGlvblxuICAgIGlmIChpc1JlZGlyZWN0UmVzdWx0KHJlc3VsdCkpIHtcbiAgICAgIGlmIChwZW5kaW5nTmF2aWdhdGlvbkxvYWRJZCA+IG9yaWdpbmF0aW5nTG9hZElkKSB7XG4gICAgICAgIC8vIEEgbmV3IG5hdmlnYXRpb24gd2FzIGtpY2tlZCBvZmYgYWZ0ZXIgb3VyIGxvYWRlciBzdGFydGVkLCBzbyB0aGF0XG4gICAgICAgIC8vIHNob3VsZCB0YWtlIHByZWNlZGVuY2Ugb3ZlciB0aGlzIHJlZGlyZWN0IG5hdmlnYXRpb25cbiAgICAgICAgbGV0IGRvbmVGZXRjaGVyID0gZ2V0RG9uZUZldGNoZXIodW5kZWZpbmVkKTtcbiAgICAgICAgc3RhdGUuZmV0Y2hlcnMuc2V0KGtleSwgZG9uZUZldGNoZXIpO1xuICAgICAgICB1cGRhdGVTdGF0ZSh7XG4gICAgICAgICAgZmV0Y2hlcnM6IG5ldyBNYXAoc3RhdGUuZmV0Y2hlcnMpXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmZXRjaFJlZGlyZWN0SWRzLmFkZChrZXkpO1xuICAgICAgICBhd2FpdCBzdGFydFJlZGlyZWN0TmF2aWdhdGlvbihzdGF0ZSwgcmVzdWx0KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBQcm9jZXNzIGFueSBub24tcmVkaXJlY3QgZXJyb3JzIHRocm93blxuICAgIGlmIChpc0Vycm9yUmVzdWx0KHJlc3VsdCkpIHtcbiAgICAgIGxldCBib3VuZGFyeU1hdGNoID0gZmluZE5lYXJlc3RCb3VuZGFyeShzdGF0ZS5tYXRjaGVzLCByb3V0ZUlkKTtcbiAgICAgIHN0YXRlLmZldGNoZXJzLmRlbGV0ZShrZXkpO1xuICAgICAgLy8gVE9ETzogSW4gcmVtaXgsIHRoaXMgd291bGQgcmVzZXQgdG8gSURMRV9OQVZJR0FUSU9OIGlmIGl0IHdhcyBhIGNhdGNoIC1cbiAgICAgIC8vIGRvIHdlIG5lZWQgdG8gYmVoYXZlIGFueSBkaWZmZXJlbnRseSB3aXRoIG91ciBub24tcmVkaXJlY3QgZXJyb3JzP1xuICAgICAgLy8gV2hhdCBpZiBpdCB3YXMgYSBub24tcmVkaXJlY3QgUmVzcG9uc2U/XG4gICAgICB1cGRhdGVTdGF0ZSh7XG4gICAgICAgIGZldGNoZXJzOiBuZXcgTWFwKHN0YXRlLmZldGNoZXJzKSxcbiAgICAgICAgZXJyb3JzOiB7XG4gICAgICAgICAgW2JvdW5kYXJ5TWF0Y2gucm91dGUuaWRdOiByZXN1bHQuZXJyb3JcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGludmFyaWFudCghaXNEZWZlcnJlZFJlc3VsdChyZXN1bHQpLCBcIlVuaGFuZGxlZCBmZXRjaGVyIGRlZmVycmVkIGRhdGFcIik7XG4gICAgLy8gUHV0IHRoZSBmZXRjaGVyIGJhY2sgaW50byBhbiBpZGxlIHN0YXRlXG4gICAgbGV0IGRvbmVGZXRjaGVyID0gZ2V0RG9uZUZldGNoZXIocmVzdWx0LmRhdGEpO1xuICAgIHN0YXRlLmZldGNoZXJzLnNldChrZXksIGRvbmVGZXRjaGVyKTtcbiAgICB1cGRhdGVTdGF0ZSh7XG4gICAgICBmZXRjaGVyczogbmV3IE1hcChzdGF0ZS5mZXRjaGVycylcbiAgICB9KTtcbiAgfVxuICAvKipcbiAgICogVXRpbGl0eSBmdW5jdGlvbiB0byBoYW5kbGUgcmVkaXJlY3RzIHJldHVybmVkIGZyb20gYW4gYWN0aW9uIG9yIGxvYWRlci5cbiAgICogTm9ybWFsbHksIGEgcmVkaXJlY3QgXCJyZXBsYWNlc1wiIHRoZSBuYXZpZ2F0aW9uIHRoYXQgdHJpZ2dlcmVkIGl0LiAgU28sIGZvclxuICAgKiBleGFtcGxlOlxuICAgKlxuICAgKiAgLSB1c2VyIGlzIG9uIC9hXG4gICAqICAtIHVzZXIgY2xpY2tzIGEgbGluayB0byAvYlxuICAgKiAgLSBsb2FkZXIgZm9yIC9iIHJlZGlyZWN0cyB0byAvY1xuICAgKlxuICAgKiBJbiBhIG5vbi1KUyBhcHAgdGhlIGJyb3dzZXIgd291bGQgdHJhY2sgdGhlIGluLWZsaWdodCBuYXZpZ2F0aW9uIHRvIC9iIGFuZFxuICAgKiB0aGVuIHJlcGxhY2UgaXQgd2l0aCAvYyB3aGVuIGl0IGVuY291bnRlcmVkIHRoZSByZWRpcmVjdCByZXNwb25zZS4gIEluXG4gICAqIHRoZSBlbmQgaXQgd291bGQgb25seSBldmVyIHVwZGF0ZSB0aGUgVVJMIGJhciB3aXRoIC9jLlxuICAgKlxuICAgKiBJbiBjbGllbnQtc2lkZSByb3V0aW5nIHVzaW5nIHB1c2hTdGF0ZS9yZXBsYWNlU3RhdGUsIHdlIGFpbSB0byBlbXVsYXRlXG4gICAqIHRoaXMgYmVoYXZpb3IgYW5kIHdlIGFsc28gZG8gbm90IHVwZGF0ZSBoaXN0b3J5IHVudGlsIHRoZSBlbmQgb2YgdGhlXG4gICAqIG5hdmlnYXRpb24gKGluY2x1ZGluZyBwcm9jZXNzZWQgcmVkaXJlY3RzKS4gIFRoaXMgbWVhbnMgdGhhdCB3ZSBuZXZlclxuICAgKiBhY3R1YWxseSB0b3VjaCBoaXN0b3J5IHVudGlsIHdlJ3ZlIHByb2Nlc3NlZCByZWRpcmVjdHMsIHNvIHdlIGp1c3QgdXNlXG4gICAqIHRoZSBoaXN0b3J5IGFjdGlvbiBmcm9tIHRoZSBvcmlnaW5hbCBuYXZpZ2F0aW9uIChQVVNIIG9yIFJFUExBQ0UpLlxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gc3RhcnRSZWRpcmVjdE5hdmlnYXRpb24oc3RhdGUsIHJlZGlyZWN0LCBfdGVtcCkge1xuICAgIGxldCB7XG4gICAgICBzdWJtaXNzaW9uLFxuICAgICAgcmVwbGFjZSxcbiAgICAgIGlzRmV0Y2hBY3Rpb25SZWRpcmVjdFxuICAgIH0gPSBfdGVtcCA9PT0gdm9pZCAwID8ge30gOiBfdGVtcDtcbiAgICBpZiAocmVkaXJlY3QucmV2YWxpZGF0ZSkge1xuICAgICAgaXNSZXZhbGlkYXRpb25SZXF1aXJlZCA9IHRydWU7XG4gICAgfVxuICAgIGxldCByZWRpcmVjdExvY2F0aW9uID0gY3JlYXRlTG9jYXRpb24oc3RhdGUubG9jYXRpb24sIHJlZGlyZWN0LmxvY2F0aW9uLCAvLyBUT0RPOiBUaGlzIGNhbiBiZSByZW1vdmVkIG9uY2Ugd2UgZ2V0IHJpZCBvZiB1c2VUcmFuc2l0aW9uIGluIFJlbWl4IHYyXG4gICAgX2V4dGVuZHMoe1xuICAgICAgX2lzUmVkaXJlY3Q6IHRydWVcbiAgICB9LCBpc0ZldGNoQWN0aW9uUmVkaXJlY3QgPyB7XG4gICAgICBfaXNGZXRjaEFjdGlvblJlZGlyZWN0OiB0cnVlXG4gICAgfSA6IHt9KSk7XG4gICAgaW52YXJpYW50KHJlZGlyZWN0TG9jYXRpb24sIFwiRXhwZWN0ZWQgYSBsb2NhdGlvbiBvbiB0aGUgcmVkaXJlY3QgbmF2aWdhdGlvblwiKTtcbiAgICBpZiAoaXNCcm93c2VyKSB7XG4gICAgICBsZXQgaXNEb2N1bWVudFJlbG9hZCA9IGZhbHNlO1xuICAgICAgaWYgKHJlZGlyZWN0LnJlbG9hZERvY3VtZW50KSB7XG4gICAgICAgIC8vIEhhcmQgcmVsb2FkIGlmIHRoZSByZXNwb25zZSBjb250YWluZWQgWC1SZW1peC1SZWxvYWQtRG9jdW1lbnRcbiAgICAgICAgaXNEb2N1bWVudFJlbG9hZCA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKEFCU09MVVRFX1VSTF9SRUdFWC50ZXN0KHJlZGlyZWN0LmxvY2F0aW9uKSkge1xuICAgICAgICBjb25zdCB1cmwgPSBpbml0Lmhpc3RvcnkuY3JlYXRlVVJMKHJlZGlyZWN0LmxvY2F0aW9uKTtcbiAgICAgICAgaXNEb2N1bWVudFJlbG9hZCA9XG4gICAgICAgIC8vIEhhcmQgcmVsb2FkIGlmIGl0J3MgYW4gYWJzb2x1dGUgVVJMIHRvIGEgbmV3IG9yaWdpblxuICAgICAgICB1cmwub3JpZ2luICE9PSByb3V0ZXJXaW5kb3cubG9jYXRpb24ub3JpZ2luIHx8XG4gICAgICAgIC8vIEhhcmQgcmVsb2FkIGlmIGl0J3MgYW4gYWJzb2x1dGUgVVJMIHRoYXQgZG9lcyBub3QgbWF0Y2ggb3VyIGJhc2VuYW1lXG4gICAgICAgIHN0cmlwQmFzZW5hbWUodXJsLnBhdGhuYW1lLCBiYXNlbmFtZSkgPT0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChpc0RvY3VtZW50UmVsb2FkKSB7XG4gICAgICAgIGlmIChyZXBsYWNlKSB7XG4gICAgICAgICAgcm91dGVyV2luZG93LmxvY2F0aW9uLnJlcGxhY2UocmVkaXJlY3QubG9jYXRpb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJvdXRlcldpbmRvdy5sb2NhdGlvbi5hc3NpZ24ocmVkaXJlY3QubG9jYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gVGhlcmUncyBubyBuZWVkIHRvIGFib3J0IG9uIHJlZGlyZWN0cywgc2luY2Ugd2UgZG9uJ3QgZGV0ZWN0IHRoZVxuICAgIC8vIHJlZGlyZWN0IHVudGlsIHRoZSBhY3Rpb24vbG9hZGVycyBoYXZlIHNldHRsZWRcbiAgICBwZW5kaW5nTmF2aWdhdGlvbkNvbnRyb2xsZXIgPSBudWxsO1xuICAgIGxldCByZWRpcmVjdEhpc3RvcnlBY3Rpb24gPSByZXBsYWNlID09PSB0cnVlID8gQWN0aW9uLlJlcGxhY2UgOiBBY3Rpb24uUHVzaDtcbiAgICAvLyBVc2UgdGhlIGluY29taW5nIHN1Ym1pc3Npb24gaWYgcHJvdmlkZWQsIGZhbGxiYWNrIG9uIHRoZSBhY3RpdmUgb25lIGluXG4gICAgLy8gc3RhdGUubmF2aWdhdGlvblxuICAgIGxldCBhY3RpdmVTdWJtaXNzaW9uID0gc3VibWlzc2lvbiB8fCBnZXRTdWJtaXNzaW9uRnJvbU5hdmlnYXRpb24oc3RhdGUubmF2aWdhdGlvbik7XG4gICAgLy8gSWYgdGhpcyB3YXMgYSAzMDcvMzA4IHN1Ym1pc3Npb24gd2Ugd2FudCB0byBwcmVzZXJ2ZSB0aGUgSFRUUCBtZXRob2QgYW5kXG4gICAgLy8gcmUtc3VibWl0IHRoZSBHRVQvUE9TVC9QVVQvUEFUQ0gvREVMRVRFIGFzIGEgc3VibWlzc2lvbiBuYXZpZ2F0aW9uIHRvIHRoZVxuICAgIC8vIHJlZGlyZWN0ZWQgbG9jYXRpb25cbiAgICBpZiAocmVkaXJlY3RQcmVzZXJ2ZU1ldGhvZFN0YXR1c0NvZGVzLmhhcyhyZWRpcmVjdC5zdGF0dXMpICYmIGFjdGl2ZVN1Ym1pc3Npb24gJiYgaXNNdXRhdGlvbk1ldGhvZChhY3RpdmVTdWJtaXNzaW9uLmZvcm1NZXRob2QpKSB7XG4gICAgICBhd2FpdCBzdGFydE5hdmlnYXRpb24ocmVkaXJlY3RIaXN0b3J5QWN0aW9uLCByZWRpcmVjdExvY2F0aW9uLCB7XG4gICAgICAgIHN1Ym1pc3Npb246IF9leHRlbmRzKHt9LCBhY3RpdmVTdWJtaXNzaW9uLCB7XG4gICAgICAgICAgZm9ybUFjdGlvbjogcmVkaXJlY3QubG9jYXRpb25cbiAgICAgICAgfSksXG4gICAgICAgIC8vIFByZXNlcnZlIHRoaXMgZmxhZyBhY3Jvc3MgcmVkaXJlY3RzXG4gICAgICAgIHByZXZlbnRTY3JvbGxSZXNldDogcGVuZGluZ1ByZXZlbnRTY3JvbGxSZXNldFxuICAgICAgfSk7XG4gICAgfSBlbHNlIGlmIChpc0ZldGNoQWN0aW9uUmVkaXJlY3QpIHtcbiAgICAgIC8vIEZvciBhIGZldGNoIGFjdGlvbiByZWRpcmVjdCwgd2Uga2ljayBvZmYgYSBuZXcgbG9hZGluZyBuYXZpZ2F0aW9uXG4gICAgICAvLyB3aXRob3V0IHRoZSBmZXRjaGVyIHN1Ym1pc3Npb24sIGJ1dCB3ZSBzZW5kIGl0IGFsb25nIGZvciBzaG91bGRSZXZhbGlkYXRlXG4gICAgICBhd2FpdCBzdGFydE5hdmlnYXRpb24ocmVkaXJlY3RIaXN0b3J5QWN0aW9uLCByZWRpcmVjdExvY2F0aW9uLCB7XG4gICAgICAgIG92ZXJyaWRlTmF2aWdhdGlvbjogZ2V0TG9hZGluZ05hdmlnYXRpb24ocmVkaXJlY3RMb2NhdGlvbiksXG4gICAgICAgIGZldGNoZXJTdWJtaXNzaW9uOiBhY3RpdmVTdWJtaXNzaW9uLFxuICAgICAgICAvLyBQcmVzZXJ2ZSB0aGlzIGZsYWcgYWNyb3NzIHJlZGlyZWN0c1xuICAgICAgICBwcmV2ZW50U2Nyb2xsUmVzZXQ6IHBlbmRpbmdQcmV2ZW50U2Nyb2xsUmVzZXRcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZiB3ZSBoYXZlIGEgc3VibWlzc2lvbiwgd2Ugd2lsbCBwcmVzZXJ2ZSBpdCB0aHJvdWdoIHRoZSByZWRpcmVjdCBuYXZpZ2F0aW9uXG4gICAgICBsZXQgb3ZlcnJpZGVOYXZpZ2F0aW9uID0gZ2V0TG9hZGluZ05hdmlnYXRpb24ocmVkaXJlY3RMb2NhdGlvbiwgYWN0aXZlU3VibWlzc2lvbik7XG4gICAgICBhd2FpdCBzdGFydE5hdmlnYXRpb24ocmVkaXJlY3RIaXN0b3J5QWN0aW9uLCByZWRpcmVjdExvY2F0aW9uLCB7XG4gICAgICAgIG92ZXJyaWRlTmF2aWdhdGlvbixcbiAgICAgICAgLy8gUHJlc2VydmUgdGhpcyBmbGFnIGFjcm9zcyByZWRpcmVjdHNcbiAgICAgICAgcHJldmVudFNjcm9sbFJlc2V0OiBwZW5kaW5nUHJldmVudFNjcm9sbFJlc2V0XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgYXN5bmMgZnVuY3Rpb24gY2FsbExvYWRlcnNBbmRNYXliZVJlc29sdmVEYXRhKGN1cnJlbnRNYXRjaGVzLCBtYXRjaGVzLCBtYXRjaGVzVG9Mb2FkLCBmZXRjaGVyc1RvTG9hZCwgcmVxdWVzdCkge1xuICAgIC8vIENhbGwgYWxsIG5hdmlnYXRpb24gbG9hZGVycyBhbmQgcmV2YWxpZGF0aW5nIGZldGNoZXIgbG9hZGVycyBpbiBwYXJhbGxlbCxcbiAgICAvLyB0aGVuIHNsaWNlIG9mZiB0aGUgcmVzdWx0cyBpbnRvIHNlcGFyYXRlIGFycmF5cyBzbyB3ZSBjYW4gaGFuZGxlIHRoZW1cbiAgICAvLyBhY2NvcmRpbmdseVxuICAgIGxldCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoWy4uLm1hdGNoZXNUb0xvYWQubWFwKG1hdGNoID0+IGNhbGxMb2FkZXJPckFjdGlvbihcImxvYWRlclwiLCByZXF1ZXN0LCBtYXRjaCwgbWF0Y2hlcywgbWFuaWZlc3QsIG1hcFJvdXRlUHJvcGVydGllcywgYmFzZW5hbWUpKSwgLi4uZmV0Y2hlcnNUb0xvYWQubWFwKGYgPT4ge1xuICAgICAgaWYgKGYubWF0Y2hlcyAmJiBmLm1hdGNoICYmIGYuY29udHJvbGxlcikge1xuICAgICAgICByZXR1cm4gY2FsbExvYWRlck9yQWN0aW9uKFwibG9hZGVyXCIsIGNyZWF0ZUNsaWVudFNpZGVSZXF1ZXN0KGluaXQuaGlzdG9yeSwgZi5wYXRoLCBmLmNvbnRyb2xsZXIuc2lnbmFsKSwgZi5tYXRjaCwgZi5tYXRjaGVzLCBtYW5pZmVzdCwgbWFwUm91dGVQcm9wZXJ0aWVzLCBiYXNlbmFtZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZXQgZXJyb3IgPSB7XG4gICAgICAgICAgdHlwZTogUmVzdWx0VHlwZS5lcnJvcixcbiAgICAgICAgICBlcnJvcjogZ2V0SW50ZXJuYWxSb3V0ZXJFcnJvcig0MDQsIHtcbiAgICAgICAgICAgIHBhdGhuYW1lOiBmLnBhdGhcbiAgICAgICAgICB9KVxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gZXJyb3I7XG4gICAgICB9XG4gICAgfSldKTtcbiAgICBsZXQgbG9hZGVyUmVzdWx0cyA9IHJlc3VsdHMuc2xpY2UoMCwgbWF0Y2hlc1RvTG9hZC5sZW5ndGgpO1xuICAgIGxldCBmZXRjaGVyUmVzdWx0cyA9IHJlc3VsdHMuc2xpY2UobWF0Y2hlc1RvTG9hZC5sZW5ndGgpO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFtyZXNvbHZlRGVmZXJyZWRSZXN1bHRzKGN1cnJlbnRNYXRjaGVzLCBtYXRjaGVzVG9Mb2FkLCBsb2FkZXJSZXN1bHRzLCBsb2FkZXJSZXN1bHRzLm1hcCgoKSA9PiByZXF1ZXN0LnNpZ25hbCksIGZhbHNlLCBzdGF0ZS5sb2FkZXJEYXRhKSwgcmVzb2x2ZURlZmVycmVkUmVzdWx0cyhjdXJyZW50TWF0Y2hlcywgZmV0Y2hlcnNUb0xvYWQubWFwKGYgPT4gZi5tYXRjaCksIGZldGNoZXJSZXN1bHRzLCBmZXRjaGVyc1RvTG9hZC5tYXAoZiA9PiBmLmNvbnRyb2xsZXIgPyBmLmNvbnRyb2xsZXIuc2lnbmFsIDogbnVsbCksIHRydWUpXSk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHJlc3VsdHMsXG4gICAgICBsb2FkZXJSZXN1bHRzLFxuICAgICAgZmV0Y2hlclJlc3VsdHNcbiAgICB9O1xuICB9XG4gIGZ1bmN0aW9uIGludGVycnVwdEFjdGl2ZUxvYWRzKCkge1xuICAgIC8vIEV2ZXJ5IGludGVycnVwdGlvbiB0cmlnZ2VycyBhIHJldmFsaWRhdGlvblxuICAgIGlzUmV2YWxpZGF0aW9uUmVxdWlyZWQgPSB0cnVlO1xuICAgIC8vIENhbmNlbCBwZW5kaW5nIHJvdXRlLWxldmVsIGRlZmVycmVkcyBhbmQgbWFyayBjYW5jZWxsZWQgcm91dGVzIGZvclxuICAgIC8vIHJldmFsaWRhdGlvblxuICAgIGNhbmNlbGxlZERlZmVycmVkUm91dGVzLnB1c2goLi4uY2FuY2VsQWN0aXZlRGVmZXJyZWRzKCkpO1xuICAgIC8vIEFib3J0IGluLWZsaWdodCBmZXRjaGVyIGxvYWRzXG4gICAgZmV0Y2hMb2FkTWF0Y2hlcy5mb3JFYWNoKChfLCBrZXkpID0+IHtcbiAgICAgIGlmIChmZXRjaENvbnRyb2xsZXJzLmhhcyhrZXkpKSB7XG4gICAgICAgIGNhbmNlbGxlZEZldGNoZXJMb2Fkcy5wdXNoKGtleSk7XG4gICAgICAgIGFib3J0RmV0Y2hlcihrZXkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG4gIGZ1bmN0aW9uIHNldEZldGNoZXJFcnJvcihrZXksIHJvdXRlSWQsIGVycm9yKSB7XG4gICAgbGV0IGJvdW5kYXJ5TWF0Y2ggPSBmaW5kTmVhcmVzdEJvdW5kYXJ5KHN0YXRlLm1hdGNoZXMsIHJvdXRlSWQpO1xuICAgIGRlbGV0ZUZldGNoZXIoa2V5KTtcbiAgICB1cGRhdGVTdGF0ZSh7XG4gICAgICBlcnJvcnM6IHtcbiAgICAgICAgW2JvdW5kYXJ5TWF0Y2gucm91dGUuaWRdOiBlcnJvclxuICAgICAgfSxcbiAgICAgIGZldGNoZXJzOiBuZXcgTWFwKHN0YXRlLmZldGNoZXJzKVxuICAgIH0pO1xuICB9XG4gIGZ1bmN0aW9uIGRlbGV0ZUZldGNoZXIoa2V5KSB7XG4gICAgbGV0IGZldGNoZXIgPSBzdGF0ZS5mZXRjaGVycy5nZXQoa2V5KTtcbiAgICAvLyBEb24ndCBhYm9ydCB0aGUgY29udHJvbGxlciBpZiB0aGlzIGlzIGEgZGVsZXRpb24gb2YgYSBmZXRjaGVyLnN1Ym1pdCgpXG4gICAgLy8gaW4gaXQncyBsb2FkaW5nIHBoYXNlIHNpbmNlIC0gd2UgZG9uJ3Qgd2FudCB0byBhYm9ydCB0aGUgY29ycmVzcG9uZGluZ1xuICAgIC8vIHJldmFsaWRhdGlvbiBhbmQgd2FudCB0aGVtIHRvIGNvbXBsZXRlIGFuZCBsYW5kXG4gICAgaWYgKGZldGNoQ29udHJvbGxlcnMuaGFzKGtleSkgJiYgIShmZXRjaGVyICYmIGZldGNoZXIuc3RhdGUgPT09IFwibG9hZGluZ1wiICYmIGZldGNoUmVsb2FkSWRzLmhhcyhrZXkpKSkge1xuICAgICAgYWJvcnRGZXRjaGVyKGtleSk7XG4gICAgfVxuICAgIGZldGNoTG9hZE1hdGNoZXMuZGVsZXRlKGtleSk7XG4gICAgZmV0Y2hSZWxvYWRJZHMuZGVsZXRlKGtleSk7XG4gICAgZmV0Y2hSZWRpcmVjdElkcy5kZWxldGUoa2V5KTtcbiAgICBzdGF0ZS5mZXRjaGVycy5kZWxldGUoa2V5KTtcbiAgfVxuICBmdW5jdGlvbiBhYm9ydEZldGNoZXIoa2V5KSB7XG4gICAgbGV0IGNvbnRyb2xsZXIgPSBmZXRjaENvbnRyb2xsZXJzLmdldChrZXkpO1xuICAgIGludmFyaWFudChjb250cm9sbGVyLCBcIkV4cGVjdGVkIGZldGNoIGNvbnRyb2xsZXI6IFwiICsga2V5KTtcbiAgICBjb250cm9sbGVyLmFib3J0KCk7XG4gICAgZmV0Y2hDb250cm9sbGVycy5kZWxldGUoa2V5KTtcbiAgfVxuICBmdW5jdGlvbiBtYXJrRmV0Y2hlcnNEb25lKGtleXMpIHtcbiAgICBmb3IgKGxldCBrZXkgb2Yga2V5cykge1xuICAgICAgbGV0IGZldGNoZXIgPSBnZXRGZXRjaGVyKGtleSk7XG4gICAgICBsZXQgZG9uZUZldGNoZXIgPSBnZXREb25lRmV0Y2hlcihmZXRjaGVyLmRhdGEpO1xuICAgICAgc3RhdGUuZmV0Y2hlcnMuc2V0KGtleSwgZG9uZUZldGNoZXIpO1xuICAgIH1cbiAgfVxuICBmdW5jdGlvbiBtYXJrRmV0Y2hSZWRpcmVjdHNEb25lKCkge1xuICAgIGxldCBkb25lS2V5cyA9IFtdO1xuICAgIGxldCB1cGRhdGVkRmV0Y2hlcnMgPSBmYWxzZTtcbiAgICBmb3IgKGxldCBrZXkgb2YgZmV0Y2hSZWRpcmVjdElkcykge1xuICAgICAgbGV0IGZldGNoZXIgPSBzdGF0ZS5mZXRjaGVycy5nZXQoa2V5KTtcbiAgICAgIGludmFyaWFudChmZXRjaGVyLCBcIkV4cGVjdGVkIGZldGNoZXI6IFwiICsga2V5KTtcbiAgICAgIGlmIChmZXRjaGVyLnN0YXRlID09PSBcImxvYWRpbmdcIikge1xuICAgICAgICBmZXRjaFJlZGlyZWN0SWRzLmRlbGV0ZShrZXkpO1xuICAgICAgICBkb25lS2V5cy5wdXNoKGtleSk7XG4gICAgICAgIHVwZGF0ZWRGZXRjaGVycyA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIG1hcmtGZXRjaGVyc0RvbmUoZG9uZUtleXMpO1xuICAgIHJldHVybiB1cGRhdGVkRmV0Y2hlcnM7XG4gIH1cbiAgZnVuY3Rpb24gYWJvcnRTdGFsZUZldGNoTG9hZHMobGFuZGVkSWQpIHtcbiAgICBsZXQgeWVldGVkS2V5cyA9IFtdO1xuICAgIGZvciAobGV0IFtrZXksIGlkXSBvZiBmZXRjaFJlbG9hZElkcykge1xuICAgICAgaWYgKGlkIDwgbGFuZGVkSWQpIHtcbiAgICAgICAgbGV0IGZldGNoZXIgPSBzdGF0ZS5mZXRjaGVycy5nZXQoa2V5KTtcbiAgICAgICAgaW52YXJpYW50KGZldGNoZXIsIFwiRXhwZWN0ZWQgZmV0Y2hlcjogXCIgKyBrZXkpO1xuICAgICAgICBpZiAoZmV0Y2hlci5zdGF0ZSA9PT0gXCJsb2FkaW5nXCIpIHtcbiAgICAgICAgICBhYm9ydEZldGNoZXIoa2V5KTtcbiAgICAgICAgICBmZXRjaFJlbG9hZElkcy5kZWxldGUoa2V5KTtcbiAgICAgICAgICB5ZWV0ZWRLZXlzLnB1c2goa2V5KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBtYXJrRmV0Y2hlcnNEb25lKHllZXRlZEtleXMpO1xuICAgIHJldHVybiB5ZWV0ZWRLZXlzLmxlbmd0aCA+IDA7XG4gIH1cbiAgZnVuY3Rpb24gZ2V0QmxvY2tlcihrZXksIGZuKSB7XG4gICAgbGV0IGJsb2NrZXIgPSBzdGF0ZS5ibG9ja2Vycy5nZXQoa2V5KSB8fCBJRExFX0JMT0NLRVI7XG4gICAgaWYgKGJsb2NrZXJGdW5jdGlvbnMuZ2V0KGtleSkgIT09IGZuKSB7XG4gICAgICBibG9ja2VyRnVuY3Rpb25zLnNldChrZXksIGZuKTtcbiAgICB9XG4gICAgcmV0dXJuIGJsb2NrZXI7XG4gIH1cbiAgZnVuY3Rpb24gZGVsZXRlQmxvY2tlcihrZXkpIHtcbiAgICBzdGF0ZS5ibG9ja2Vycy5kZWxldGUoa2V5KTtcbiAgICBibG9ja2VyRnVuY3Rpb25zLmRlbGV0ZShrZXkpO1xuICB9XG4gIC8vIFV0aWxpdHkgZnVuY3Rpb24gdG8gdXBkYXRlIGJsb2NrZXJzLCBlbnN1cmluZyB2YWxpZCBzdGF0ZSB0cmFuc2l0aW9uc1xuICBmdW5jdGlvbiB1cGRhdGVCbG9ja2VyKGtleSwgbmV3QmxvY2tlcikge1xuICAgIGxldCBibG9ja2VyID0gc3RhdGUuYmxvY2tlcnMuZ2V0KGtleSkgfHwgSURMRV9CTE9DS0VSO1xuICAgIC8vIFBvb3IgbWFucyBzdGF0ZSBtYWNoaW5lIDopXG4gICAgLy8gaHR0cHM6Ly9tZXJtYWlkLmxpdmUvZWRpdCNwYWtvOmVOcVZrYzlPd3pBTXhsOGw4bm5qQVlyRXRESU9IRUJJZ3d2S0pUUmVHeTNfbERwSXFPMjdrNmF3TUcwWGNyTGxuejg3bndkb25FU29nS1hYQnVFNzlycTc1WFpPMy15SGRzMFJKVnV2NzBZclBsVXJDRWUySGZyT1JTM3J1YnFaZnVodHBnNUM5d2s1dFo0VktjUlVxODhxOVo4UlMwLTQ4Y0UxaUhKa0wwdWdiSHVGTHVzOUw2c3BaeThuWDlNUDJDTmRvbVZhcG9zcXUzZkdheVQ4VDgtakpRd2hlcG9fVXRwZ0JRYURFVW9tMDRkWmhBTjFhSkJEbFVLSkJ4RTFjZUIyU21qME1sbi1JQlc1QUZVMmR3VWlrdHRfMlFhcTJkQmZhS2RFdXA4NVVWN1lkLWRLamxua2FibDJQdnIwRFRrVHJlTVxuICAgIGludmFyaWFudChibG9ja2VyLnN0YXRlID09PSBcInVuYmxvY2tlZFwiICYmIG5ld0Jsb2NrZXIuc3RhdGUgPT09IFwiYmxvY2tlZFwiIHx8IGJsb2NrZXIuc3RhdGUgPT09IFwiYmxvY2tlZFwiICYmIG5ld0Jsb2NrZXIuc3RhdGUgPT09IFwiYmxvY2tlZFwiIHx8IGJsb2NrZXIuc3RhdGUgPT09IFwiYmxvY2tlZFwiICYmIG5ld0Jsb2NrZXIuc3RhdGUgPT09IFwicHJvY2VlZGluZ1wiIHx8IGJsb2NrZXIuc3RhdGUgPT09IFwiYmxvY2tlZFwiICYmIG5ld0Jsb2NrZXIuc3RhdGUgPT09IFwidW5ibG9ja2VkXCIgfHwgYmxvY2tlci5zdGF0ZSA9PT0gXCJwcm9jZWVkaW5nXCIgJiYgbmV3QmxvY2tlci5zdGF0ZSA9PT0gXCJ1bmJsb2NrZWRcIiwgXCJJbnZhbGlkIGJsb2NrZXIgc3RhdGUgdHJhbnNpdGlvbjogXCIgKyBibG9ja2VyLnN0YXRlICsgXCIgLT4gXCIgKyBuZXdCbG9ja2VyLnN0YXRlKTtcbiAgICBsZXQgYmxvY2tlcnMgPSBuZXcgTWFwKHN0YXRlLmJsb2NrZXJzKTtcbiAgICBibG9ja2Vycy5zZXQoa2V5LCBuZXdCbG9ja2VyKTtcbiAgICB1cGRhdGVTdGF0ZSh7XG4gICAgICBibG9ja2Vyc1xuICAgIH0pO1xuICB9XG4gIGZ1bmN0aW9uIHNob3VsZEJsb2NrTmF2aWdhdGlvbihfcmVmMikge1xuICAgIGxldCB7XG4gICAgICBjdXJyZW50TG9jYXRpb24sXG4gICAgICBuZXh0TG9jYXRpb24sXG4gICAgICBoaXN0b3J5QWN0aW9uXG4gICAgfSA9IF9yZWYyO1xuICAgIGlmIChibG9ja2VyRnVuY3Rpb25zLnNpemUgPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gV2Ugb255IHN1cHBvcnQgYSBzaW5nbGUgYWN0aXZlIGJsb2NrZXIgYXQgdGhlIG1vbWVudCBzaW5jZSB3ZSBkb24ndCBoYXZlXG4gICAgLy8gYW55IGNvbXBlbGxpbmcgdXNlIGNhc2VzIGZvciBtdWx0aS1ibG9ja2VyIHlldFxuICAgIGlmIChibG9ja2VyRnVuY3Rpb25zLnNpemUgPiAxKSB7XG4gICAgICB3YXJuaW5nKGZhbHNlLCBcIkEgcm91dGVyIG9ubHkgc3VwcG9ydHMgb25lIGJsb2NrZXIgYXQgYSB0aW1lXCIpO1xuICAgIH1cbiAgICBsZXQgZW50cmllcyA9IEFycmF5LmZyb20oYmxvY2tlckZ1bmN0aW9ucy5lbnRyaWVzKCkpO1xuICAgIGxldCBbYmxvY2tlcktleSwgYmxvY2tlckZ1bmN0aW9uXSA9IGVudHJpZXNbZW50cmllcy5sZW5ndGggLSAxXTtcbiAgICBsZXQgYmxvY2tlciA9IHN0YXRlLmJsb2NrZXJzLmdldChibG9ja2VyS2V5KTtcbiAgICBpZiAoYmxvY2tlciAmJiBibG9ja2VyLnN0YXRlID09PSBcInByb2NlZWRpbmdcIikge1xuICAgICAgLy8gSWYgdGhlIGJsb2NrZXIgaXMgY3VycmVudGx5IHByb2NlZWRpbmcsIHdlIGRvbid0IG5lZWQgdG8gcmUtY2hlY2tcbiAgICAgIC8vIGl0IGFuZCBjYW4gbGV0IHRoaXMgbmF2aWdhdGlvbiBjb250aW51ZVxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBBdCB0aGlzIHBvaW50LCB3ZSBrbm93IHdlJ3JlIHVuYmxvY2tlZC9ibG9ja2VkIHNvIHdlIG5lZWQgdG8gY2hlY2sgdGhlXG4gICAgLy8gdXNlci1wcm92aWRlZCBibG9ja2VyIGZ1bmN0aW9uXG4gICAgaWYgKGJsb2NrZXJGdW5jdGlvbih7XG4gICAgICBjdXJyZW50TG9jYXRpb24sXG4gICAgICBuZXh0TG9jYXRpb24sXG4gICAgICBoaXN0b3J5QWN0aW9uXG4gICAgfSkpIHtcbiAgICAgIHJldHVybiBibG9ja2VyS2V5O1xuICAgIH1cbiAgfVxuICBmdW5jdGlvbiBjYW5jZWxBY3RpdmVEZWZlcnJlZHMocHJlZGljYXRlKSB7XG4gICAgbGV0IGNhbmNlbGxlZFJvdXRlSWRzID0gW107XG4gICAgYWN0aXZlRGVmZXJyZWRzLmZvckVhY2goKGRmZCwgcm91dGVJZCkgPT4ge1xuICAgICAgaWYgKCFwcmVkaWNhdGUgfHwgcHJlZGljYXRlKHJvdXRlSWQpKSB7XG4gICAgICAgIC8vIENhbmNlbCB0aGUgZGVmZXJyZWQgLSBidXQgZG8gbm90IHJlbW92ZSBmcm9tIGFjdGl2ZURlZmVycmVkcyBoZXJlIC1cbiAgICAgICAgLy8gd2UgcmVseSBvbiB0aGUgc3Vic2NyaWJlcnMgdG8gZG8gdGhhdCBzbyBvdXIgdGVzdHMgY2FuIGFzc2VydCBwcm9wZXJcbiAgICAgICAgLy8gY2xlYW51cCB2aWEgX2ludGVybmFsQWN0aXZlRGVmZXJyZWRzXG4gICAgICAgIGRmZC5jYW5jZWwoKTtcbiAgICAgICAgY2FuY2VsbGVkUm91dGVJZHMucHVzaChyb3V0ZUlkKTtcbiAgICAgICAgYWN0aXZlRGVmZXJyZWRzLmRlbGV0ZShyb3V0ZUlkKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gY2FuY2VsbGVkUm91dGVJZHM7XG4gIH1cbiAgLy8gT3B0IGluIHRvIGNhcHR1cmluZyBhbmQgcmVwb3J0aW5nIHNjcm9sbCBwb3NpdGlvbnMgZHVyaW5nIG5hdmlnYXRpb25zLFxuICAvLyB1c2VkIGJ5IHRoZSA8U2Nyb2xsUmVzdG9yYXRpb24+IGNvbXBvbmVudFxuICBmdW5jdGlvbiBlbmFibGVTY3JvbGxSZXN0b3JhdGlvbihwb3NpdGlvbnMsIGdldFBvc2l0aW9uLCBnZXRLZXkpIHtcbiAgICBzYXZlZFNjcm9sbFBvc2l0aW9ucyA9IHBvc2l0aW9ucztcbiAgICBnZXRTY3JvbGxQb3NpdGlvbiA9IGdldFBvc2l0aW9uO1xuICAgIGdldFNjcm9sbFJlc3RvcmF0aW9uS2V5ID0gZ2V0S2V5IHx8IG51bGw7XG4gICAgLy8gUGVyZm9ybSBpbml0aWFsIGh5ZHJhdGlvbiBzY3JvbGwgcmVzdG9yYXRpb24sIHNpbmNlIHdlIG1pc3MgdGhlIGJvYXQgb25cbiAgICAvLyB0aGUgaW5pdGlhbCB1cGRhdGVTdGF0ZSgpIGJlY2F1c2Ugd2UndmUgbm90IHlldCByZW5kZXJlZCA8U2Nyb2xsUmVzdG9yYXRpb24vPlxuICAgIC8vIGFuZCB0aGVyZWZvcmUgaGF2ZSBubyBzYXZlZFNjcm9sbFBvc2l0aW9ucyBhdmFpbGFibGVcbiAgICBpZiAoIWluaXRpYWxTY3JvbGxSZXN0b3JlZCAmJiBzdGF0ZS5uYXZpZ2F0aW9uID09PSBJRExFX05BVklHQVRJT04pIHtcbiAgICAgIGluaXRpYWxTY3JvbGxSZXN0b3JlZCA9IHRydWU7XG4gICAgICBsZXQgeSA9IGdldFNhdmVkU2Nyb2xsUG9zaXRpb24oc3RhdGUubG9jYXRpb24sIHN0YXRlLm1hdGNoZXMpO1xuICAgICAgaWYgKHkgIT0gbnVsbCkge1xuICAgICAgICB1cGRhdGVTdGF0ZSh7XG4gICAgICAgICAgcmVzdG9yZVNjcm9sbFBvc2l0aW9uOiB5XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgc2F2ZWRTY3JvbGxQb3NpdGlvbnMgPSBudWxsO1xuICAgICAgZ2V0U2Nyb2xsUG9zaXRpb24gPSBudWxsO1xuICAgICAgZ2V0U2Nyb2xsUmVzdG9yYXRpb25LZXkgPSBudWxsO1xuICAgIH07XG4gIH1cbiAgZnVuY3Rpb24gZ2V0U2Nyb2xsS2V5KGxvY2F0aW9uLCBtYXRjaGVzKSB7XG4gICAgaWYgKGdldFNjcm9sbFJlc3RvcmF0aW9uS2V5KSB7XG4gICAgICBsZXQga2V5ID0gZ2V0U2Nyb2xsUmVzdG9yYXRpb25LZXkobG9jYXRpb24sIG1hdGNoZXMubWFwKG0gPT4gY3JlYXRlVXNlTWF0Y2hlc01hdGNoKG0sIHN0YXRlLmxvYWRlckRhdGEpKSk7XG4gICAgICByZXR1cm4ga2V5IHx8IGxvY2F0aW9uLmtleTtcbiAgICB9XG4gICAgcmV0dXJuIGxvY2F0aW9uLmtleTtcbiAgfVxuICBmdW5jdGlvbiBzYXZlU2Nyb2xsUG9zaXRpb24obG9jYXRpb24sIG1hdGNoZXMpIHtcbiAgICBpZiAoc2F2ZWRTY3JvbGxQb3NpdGlvbnMgJiYgZ2V0U2Nyb2xsUG9zaXRpb24pIHtcbiAgICAgIGxldCBrZXkgPSBnZXRTY3JvbGxLZXkobG9jYXRpb24sIG1hdGNoZXMpO1xuICAgICAgc2F2ZWRTY3JvbGxQb3NpdGlvbnNba2V5XSA9IGdldFNjcm9sbFBvc2l0aW9uKCk7XG4gICAgfVxuICB9XG4gIGZ1bmN0aW9uIGdldFNhdmVkU2Nyb2xsUG9zaXRpb24obG9jYXRpb24sIG1hdGNoZXMpIHtcbiAgICBpZiAoc2F2ZWRTY3JvbGxQb3NpdGlvbnMpIHtcbiAgICAgIGxldCBrZXkgPSBnZXRTY3JvbGxLZXkobG9jYXRpb24sIG1hdGNoZXMpO1xuICAgICAgbGV0IHkgPSBzYXZlZFNjcm9sbFBvc2l0aW9uc1trZXldO1xuICAgICAgaWYgKHR5cGVvZiB5ID09PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHJldHVybiB5O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBmdW5jdGlvbiBfaW50ZXJuYWxTZXRSb3V0ZXMobmV3Um91dGVzKSB7XG4gICAgbWFuaWZlc3QgPSB7fTtcbiAgICBpbkZsaWdodERhdGFSb3V0ZXMgPSBjb252ZXJ0Um91dGVzVG9EYXRhUm91dGVzKG5ld1JvdXRlcywgbWFwUm91dGVQcm9wZXJ0aWVzLCB1bmRlZmluZWQsIG1hbmlmZXN0KTtcbiAgfVxuICByb3V0ZXIgPSB7XG4gICAgZ2V0IGJhc2VuYW1lKCkge1xuICAgICAgcmV0dXJuIGJhc2VuYW1lO1xuICAgIH0sXG4gICAgZ2V0IHN0YXRlKCkge1xuICAgICAgcmV0dXJuIHN0YXRlO1xuICAgIH0sXG4gICAgZ2V0IHJvdXRlcygpIHtcbiAgICAgIHJldHVybiBkYXRhUm91dGVzO1xuICAgIH0sXG4gICAgaW5pdGlhbGl6ZSxcbiAgICBzdWJzY3JpYmUsXG4gICAgZW5hYmxlU2Nyb2xsUmVzdG9yYXRpb24sXG4gICAgbmF2aWdhdGUsXG4gICAgZmV0Y2gsXG4gICAgcmV2YWxpZGF0ZSxcbiAgICAvLyBQYXNzdGhyb3VnaCB0byBoaXN0b3J5LWF3YXJlIGNyZWF0ZUhyZWYgdXNlZCBieSB1c2VIcmVmIHNvIHdlIGdldCBwcm9wZXJcbiAgICAvLyBoYXNoLWF3YXJlIFVSTHMgaW4gRE9NIHBhdGhzXG4gICAgY3JlYXRlSHJlZjogdG8gPT4gaW5pdC5oaXN0b3J5LmNyZWF0ZUhyZWYodG8pLFxuICAgIGVuY29kZUxvY2F0aW9uOiB0byA9PiBpbml0Lmhpc3RvcnkuZW5jb2RlTG9jYXRpb24odG8pLFxuICAgIGdldEZldGNoZXIsXG4gICAgZGVsZXRlRmV0Y2hlcixcbiAgICBkaXNwb3NlLFxuICAgIGdldEJsb2NrZXIsXG4gICAgZGVsZXRlQmxvY2tlcixcbiAgICBfaW50ZXJuYWxGZXRjaENvbnRyb2xsZXJzOiBmZXRjaENvbnRyb2xsZXJzLFxuICAgIF9pbnRlcm5hbEFjdGl2ZURlZmVycmVkczogYWN0aXZlRGVmZXJyZWRzLFxuICAgIC8vIFRPRE86IFJlbW92ZSBzZXRSb3V0ZXMsIGl0J3MgdGVtcG9yYXJ5IHRvIGF2b2lkIGRlYWxpbmcgd2l0aFxuICAgIC8vIHVwZGF0aW5nIHRoZSB0cmVlIHdoaWxlIHZhbGlkYXRpbmcgdGhlIHVwZGF0ZSBhbGdvcml0aG0uXG4gICAgX2ludGVybmFsU2V0Um91dGVzXG4gIH07XG4gIHJldHVybiByb3V0ZXI7XG59XG4vLyNlbmRyZWdpb25cbi8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4vLyNyZWdpb24gY3JlYXRlU3RhdGljSGFuZGxlclxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbmNvbnN0IFVOU0FGRV9ERUZFUlJFRF9TWU1CT0wgPSBTeW1ib2woXCJkZWZlcnJlZFwiKTtcbmZ1bmN0aW9uIGNyZWF0ZVN0YXRpY0hhbmRsZXIocm91dGVzLCBvcHRzKSB7XG4gIGludmFyaWFudChyb3V0ZXMubGVuZ3RoID4gMCwgXCJZb3UgbXVzdCBwcm92aWRlIGEgbm9uLWVtcHR5IHJvdXRlcyBhcnJheSB0byBjcmVhdGVTdGF0aWNIYW5kbGVyXCIpO1xuICBsZXQgbWFuaWZlc3QgPSB7fTtcbiAgbGV0IGJhc2VuYW1lID0gKG9wdHMgPyBvcHRzLmJhc2VuYW1lIDogbnVsbCkgfHwgXCIvXCI7XG4gIGxldCBtYXBSb3V0ZVByb3BlcnRpZXM7XG4gIGlmIChvcHRzICE9IG51bGwgJiYgb3B0cy5tYXBSb3V0ZVByb3BlcnRpZXMpIHtcbiAgICBtYXBSb3V0ZVByb3BlcnRpZXMgPSBvcHRzLm1hcFJvdXRlUHJvcGVydGllcztcbiAgfSBlbHNlIGlmIChvcHRzICE9IG51bGwgJiYgb3B0cy5kZXRlY3RFcnJvckJvdW5kYXJ5KSB7XG4gICAgLy8gSWYgdGhleSBhcmUgc3RpbGwgdXNpbmcgdGhlIGRlcHJlY2F0ZWQgdmVyc2lvbiwgd3JhcCBpdCB3aXRoIHRoZSBuZXcgQVBJXG4gICAgbGV0IGRldGVjdEVycm9yQm91bmRhcnkgPSBvcHRzLmRldGVjdEVycm9yQm91bmRhcnk7XG4gICAgbWFwUm91dGVQcm9wZXJ0aWVzID0gcm91dGUgPT4gKHtcbiAgICAgIGhhc0Vycm9yQm91bmRhcnk6IGRldGVjdEVycm9yQm91bmRhcnkocm91dGUpXG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgbWFwUm91dGVQcm9wZXJ0aWVzID0gZGVmYXVsdE1hcFJvdXRlUHJvcGVydGllcztcbiAgfVxuICBsZXQgZGF0YVJvdXRlcyA9IGNvbnZlcnRSb3V0ZXNUb0RhdGFSb3V0ZXMocm91dGVzLCBtYXBSb3V0ZVByb3BlcnRpZXMsIHVuZGVmaW5lZCwgbWFuaWZlc3QpO1xuICAvKipcbiAgICogVGhlIHF1ZXJ5KCkgbWV0aG9kIGlzIGludGVuZGVkIGZvciBkb2N1bWVudCByZXF1ZXN0cywgaW4gd2hpY2ggd2Ugd2FudCB0b1xuICAgKiBjYWxsIGFuIG9wdGlvbmFsIGFjdGlvbiBhbmQgcG90ZW50aWFsbHkgbXVsdGlwbGUgbG9hZGVycyBmb3IgYWxsIG5lc3RlZFxuICAgKiByb3V0ZXMuICBJdCByZXR1cm5zIGEgU3RhdGljSGFuZGxlckNvbnRleHQgb2JqZWN0LCB3aGljaCBpcyB2ZXJ5IHNpbWlsYXJcbiAgICogdG8gdGhlIHJvdXRlciBzdGF0ZSAobG9jYXRpb24sIGxvYWRlckRhdGEsIGFjdGlvbkRhdGEsIGVycm9ycywgZXRjLikgYW5kXG4gICAqIGFsc28gYWRkcyBTU1Itc3BlY2lmaWMgaW5mb3JtYXRpb24gc3VjaCBhcyB0aGUgc3RhdHVzQ29kZSBhbmQgaGVhZGVyc1xuICAgKiBmcm9tIGFjdGlvbi9sb2FkZXJzIFJlc3BvbnNlcy5cbiAgICpcbiAgICogSXQgX3Nob3VsZF8gbmV2ZXIgdGhyb3cgYW5kIHNob3VsZCByZXBvcnQgYWxsIGVycm9ycyB0aHJvdWdoIHRoZVxuICAgKiByZXR1cm5lZCBjb250ZXh0LmVycm9ycyBvYmplY3QsIHByb3Blcmx5IGFzc29jaWF0aW5nIGVycm9ycyB0byB0aGVpciBlcnJvclxuICAgKiBib3VuZGFyeS4gIEFkZGl0aW9uYWxseSwgaXQgdHJhY2tzIF9kZWVwZXN0UmVuZGVyZWRCb3VuZGFyeUlkIHdoaWNoIGNhbiBiZVxuICAgKiB1c2VkIHRvIGVtdWxhdGUgUmVhY3QgZXJyb3IgYm91bmRhcmllcyBkdXJpbmcgU1NyIGJ5IHBlcmZvcm1pbmcgYSBzZWNvbmRcbiAgICogcGFzcyBvbmx5IGRvd24gdG8gdGhlIGJvdW5kYXJ5SWQuXG4gICAqXG4gICAqIFRoZSBvbmUgZXhjZXB0aW9uIHdoZXJlIHdlIGRvIG5vdCByZXR1cm4gYSBTdGF0aWNIYW5kbGVyQ29udGV4dCBpcyB3aGVuIGFcbiAgICogcmVkaXJlY3QgcmVzcG9uc2UgaXMgcmV0dXJuZWQgb3IgdGhyb3duIGZyb20gYW55IGFjdGlvbi9sb2FkZXIuICBXZVxuICAgKiBwcm9wYWdhdGUgdGhhdCBvdXQgYW5kIHJldHVybiB0aGUgcmF3IFJlc3BvbnNlIHNvIHRoZSBIVFRQIHNlcnZlciBjYW5cbiAgICogcmV0dXJuIGl0IGRpcmVjdGx5LlxuICAgKi9cbiAgYXN5bmMgZnVuY3Rpb24gcXVlcnkocmVxdWVzdCwgX3RlbXAyKSB7XG4gICAgbGV0IHtcbiAgICAgIHJlcXVlc3RDb250ZXh0XG4gICAgfSA9IF90ZW1wMiA9PT0gdm9pZCAwID8ge30gOiBfdGVtcDI7XG4gICAgbGV0IHVybCA9IG5ldyBVUkwocmVxdWVzdC51cmwpO1xuICAgIGxldCBtZXRob2QgPSByZXF1ZXN0Lm1ldGhvZDtcbiAgICBsZXQgbG9jYXRpb24gPSBjcmVhdGVMb2NhdGlvbihcIlwiLCBjcmVhdGVQYXRoKHVybCksIG51bGwsIFwiZGVmYXVsdFwiKTtcbiAgICBsZXQgbWF0Y2hlcyA9IG1hdGNoUm91dGVzKGRhdGFSb3V0ZXMsIGxvY2F0aW9uLCBiYXNlbmFtZSk7XG4gICAgLy8gU1NSIHN1cHBvcnRzIEhFQUQgcmVxdWVzdHMgd2hpbGUgU1BBIGRvZXNuJ3RcbiAgICBpZiAoIWlzVmFsaWRNZXRob2QobWV0aG9kKSAmJiBtZXRob2QgIT09IFwiSEVBRFwiKSB7XG4gICAgICBsZXQgZXJyb3IgPSBnZXRJbnRlcm5hbFJvdXRlckVycm9yKDQwNSwge1xuICAgICAgICBtZXRob2RcbiAgICAgIH0pO1xuICAgICAgbGV0IHtcbiAgICAgICAgbWF0Y2hlczogbWV0aG9kTm90QWxsb3dlZE1hdGNoZXMsXG4gICAgICAgIHJvdXRlXG4gICAgICB9ID0gZ2V0U2hvcnRDaXJjdWl0TWF0Y2hlcyhkYXRhUm91dGVzKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGJhc2VuYW1lLFxuICAgICAgICBsb2NhdGlvbixcbiAgICAgICAgbWF0Y2hlczogbWV0aG9kTm90QWxsb3dlZE1hdGNoZXMsXG4gICAgICAgIGxvYWRlckRhdGE6IHt9LFxuICAgICAgICBhY3Rpb25EYXRhOiBudWxsLFxuICAgICAgICBlcnJvcnM6IHtcbiAgICAgICAgICBbcm91dGUuaWRdOiBlcnJvclxuICAgICAgICB9LFxuICAgICAgICBzdGF0dXNDb2RlOiBlcnJvci5zdGF0dXMsXG4gICAgICAgIGxvYWRlckhlYWRlcnM6IHt9LFxuICAgICAgICBhY3Rpb25IZWFkZXJzOiB7fSxcbiAgICAgICAgYWN0aXZlRGVmZXJyZWRzOiBudWxsXG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAoIW1hdGNoZXMpIHtcbiAgICAgIGxldCBlcnJvciA9IGdldEludGVybmFsUm91dGVyRXJyb3IoNDA0LCB7XG4gICAgICAgIHBhdGhuYW1lOiBsb2NhdGlvbi5wYXRobmFtZVxuICAgICAgfSk7XG4gICAgICBsZXQge1xuICAgICAgICBtYXRjaGVzOiBub3RGb3VuZE1hdGNoZXMsXG4gICAgICAgIHJvdXRlXG4gICAgICB9ID0gZ2V0U2hvcnRDaXJjdWl0TWF0Y2hlcyhkYXRhUm91dGVzKTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGJhc2VuYW1lLFxuICAgICAgICBsb2NhdGlvbixcbiAgICAgICAgbWF0Y2hlczogbm90Rm91bmRNYXRjaGVzLFxuICAgICAgICBsb2FkZXJEYXRhOiB7fSxcbiAgICAgICAgYWN0aW9uRGF0YTogbnVsbCxcbiAgICAgICAgZXJyb3JzOiB7XG4gICAgICAgICAgW3JvdXRlLmlkXTogZXJyb3JcbiAgICAgICAgfSxcbiAgICAgICAgc3RhdHVzQ29kZTogZXJyb3Iuc3RhdHVzLFxuICAgICAgICBsb2FkZXJIZWFkZXJzOiB7fSxcbiAgICAgICAgYWN0aW9uSGVhZGVyczoge30sXG4gICAgICAgIGFjdGl2ZURlZmVycmVkczogbnVsbFxuICAgICAgfTtcbiAgICB9XG4gICAgbGV0IHJlc3VsdCA9IGF3YWl0IHF1ZXJ5SW1wbChyZXF1ZXN0LCBsb2NhdGlvbiwgbWF0Y2hlcywgcmVxdWVzdENvbnRleHQpO1xuICAgIGlmIChpc1Jlc3BvbnNlKHJlc3VsdCkpIHtcbiAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgfVxuICAgIC8vIFdoZW4gcmV0dXJuaW5nIFN0YXRpY0hhbmRsZXJDb250ZXh0LCB3ZSBwYXRjaCBiYWNrIGluIHRoZSBsb2NhdGlvbiBoZXJlXG4gICAgLy8gc2luY2Ugd2UgbmVlZCBpdCBmb3IgUmVhY3QgQ29udGV4dC4gIEJ1dCB0aGlzIGhlbHBzIGtlZXAgb3VyIHN1Ym1pdCBhbmRcbiAgICAvLyBsb2FkUm91dGVEYXRhIG9wZXJhdGluZyBvbiBhIFJlcXVlc3QgaW5zdGVhZCBvZiBhIExvY2F0aW9uXG4gICAgcmV0dXJuIF9leHRlbmRzKHtcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgYmFzZW5hbWVcbiAgICB9LCByZXN1bHQpO1xuICB9XG4gIC8qKlxuICAgKiBUaGUgcXVlcnlSb3V0ZSgpIG1ldGhvZCBpcyBpbnRlbmRlZCBmb3IgdGFyZ2V0ZWQgcm91dGUgcmVxdWVzdHMsIGVpdGhlclxuICAgKiBmb3IgZmV0Y2ggP19kYXRhIHJlcXVlc3RzIG9yIHJlc291cmNlIHJvdXRlIHJlcXVlc3RzLiAgSW4gdGhpcyBjYXNlLCB3ZVxuICAgKiBhcmUgb25seSBldmVyIGNhbGxpbmcgYSBzaW5nbGUgYWN0aW9uIG9yIGxvYWRlciwgYW5kIHdlIGFyZSByZXR1cm5pbmcgdGhlXG4gICAqIHJldHVybmVkIHZhbHVlIGRpcmVjdGx5LiAgSW4gbW9zdCBjYXNlcywgdGhpcyB3aWxsIGJlIGEgUmVzcG9uc2UgcmV0dXJuZWRcbiAgICogZnJvbSB0aGUgYWN0aW9uL2xvYWRlciwgYnV0IGl0IG1heSBiZSBhIHByaW1pdGl2ZSBvciBvdGhlciB2YWx1ZSBhcyB3ZWxsIC1cbiAgICogYW5kIGluIHN1Y2ggY2FzZXMgdGhlIGNhbGxpbmcgY29udGV4dCBzaG91bGQgaGFuZGxlIHRoYXQgYWNjb3JkaW5nbHkuXG4gICAqXG4gICAqIFdlIGRvIHJlc3BlY3QgdGhlIHRocm93L3JldHVybiBkaWZmZXJlbnRpYXRpb24sIHNvIGlmIGFuIGFjdGlvbi9sb2FkZXJcbiAgICogdGhyb3dzLCB0aGVuIHRoaXMgbWV0aG9kIHdpbGwgdGhyb3cgdGhlIHZhbHVlLiAgVGhpcyBpcyBpbXBvcnRhbnQgc28gd2VcbiAgICogY2FuIGRvIHByb3BlciBib3VuZGFyeSBpZGVudGlmaWNhdGlvbiBpbiBSZW1peCB3aGVyZSBhIHRocm93biBSZXNwb25zZVxuICAgKiBtdXN0IGdvIHRvIHRoZSBDYXRjaCBCb3VuZGFyeSBidXQgYSByZXR1cm5lZCBSZXNwb25zZSBpcyBoYXBweS1wYXRoLlxuICAgKlxuICAgKiBPbmUgdGhpbmcgdG8gbm90ZSBpcyB0aGF0IGFueSBSb3V0ZXItaW5pdGlhdGVkIEVycm9ycyB0aGF0IG1ha2Ugc2Vuc2VcbiAgICogdG8gYXNzb2NpYXRlIHdpdGggYSBzdGF0dXMgY29kZSB3aWxsIGJlIHRocm93biBhcyBhbiBFcnJvclJlc3BvbnNlXG4gICAqIGluc3RhbmNlIHdoaWNoIGluY2x1ZGUgdGhlIHJhdyBFcnJvciwgc3VjaCB0aGF0IHRoZSBjYWxsaW5nIGNvbnRleHQgY2FuXG4gICAqIHNlcmlhbGl6ZSB0aGUgZXJyb3IgYXMgdGhleSBzZWUgZml0IHdoaWxlIGluY2x1ZGluZyB0aGUgcHJvcGVyIHJlc3BvbnNlXG4gICAqIGNvZGUuICBFeGFtcGxlcyBoZXJlIGFyZSA0MDQgYW5kIDQwNSBlcnJvcnMgdGhhdCBvY2N1ciBwcmlvciB0byByZWFjaGluZ1xuICAgKiBhbnkgdXNlci1kZWZpbmVkIGxvYWRlcnMuXG4gICAqL1xuICBhc3luYyBmdW5jdGlvbiBxdWVyeVJvdXRlKHJlcXVlc3QsIF90ZW1wMykge1xuICAgIGxldCB7XG4gICAgICByb3V0ZUlkLFxuICAgICAgcmVxdWVzdENvbnRleHRcbiAgICB9ID0gX3RlbXAzID09PSB2b2lkIDAgPyB7fSA6IF90ZW1wMztcbiAgICBsZXQgdXJsID0gbmV3IFVSTChyZXF1ZXN0LnVybCk7XG4gICAgbGV0IG1ldGhvZCA9IHJlcXVlc3QubWV0aG9kO1xuICAgIGxldCBsb2NhdGlvbiA9IGNyZWF0ZUxvY2F0aW9uKFwiXCIsIGNyZWF0ZVBhdGgodXJsKSwgbnVsbCwgXCJkZWZhdWx0XCIpO1xuICAgIGxldCBtYXRjaGVzID0gbWF0Y2hSb3V0ZXMoZGF0YVJvdXRlcywgbG9jYXRpb24sIGJhc2VuYW1lKTtcbiAgICAvLyBTU1Igc3VwcG9ydHMgSEVBRCByZXF1ZXN0cyB3aGlsZSBTUEEgZG9lc24ndFxuICAgIGlmICghaXNWYWxpZE1ldGhvZChtZXRob2QpICYmIG1ldGhvZCAhPT0gXCJIRUFEXCIgJiYgbWV0aG9kICE9PSBcIk9QVElPTlNcIikge1xuICAgICAgdGhyb3cgZ2V0SW50ZXJuYWxSb3V0ZXJFcnJvcig0MDUsIHtcbiAgICAgICAgbWV0aG9kXG4gICAgICB9KTtcbiAgICB9IGVsc2UgaWYgKCFtYXRjaGVzKSB7XG4gICAgICB0aHJvdyBnZXRJbnRlcm5hbFJvdXRlckVycm9yKDQwNCwge1xuICAgICAgICBwYXRobmFtZTogbG9jYXRpb24ucGF0aG5hbWVcbiAgICAgIH0pO1xuICAgIH1cbiAgICBsZXQgbWF0Y2ggPSByb3V0ZUlkID8gbWF0Y2hlcy5maW5kKG0gPT4gbS5yb3V0ZS5pZCA9PT0gcm91dGVJZCkgOiBnZXRUYXJnZXRNYXRjaChtYXRjaGVzLCBsb2NhdGlvbik7XG4gICAgaWYgKHJvdXRlSWQgJiYgIW1hdGNoKSB7XG4gICAgICB0aHJvdyBnZXRJbnRlcm5hbFJvdXRlckVycm9yKDQwMywge1xuICAgICAgICBwYXRobmFtZTogbG9jYXRpb24ucGF0aG5hbWUsXG4gICAgICAgIHJvdXRlSWRcbiAgICAgIH0pO1xuICAgIH0gZWxzZSBpZiAoIW1hdGNoKSB7XG4gICAgICAvLyBUaGlzIHNob3VsZCBuZXZlciBoaXQgSSBkb24ndCB0aGluaz9cbiAgICAgIHRocm93IGdldEludGVybmFsUm91dGVyRXJyb3IoNDA0LCB7XG4gICAgICAgIHBhdGhuYW1lOiBsb2NhdGlvbi5wYXRobmFtZVxuICAgICAgfSk7XG4gICAgfVxuICAgIGxldCByZXN1bHQgPSBhd2FpdCBxdWVyeUltcGwocmVxdWVzdCwgbG9jYXRpb24sIG1hdGNoZXMsIHJlcXVlc3RDb250ZXh0LCBtYXRjaCk7XG4gICAgaWYgKGlzUmVzcG9uc2UocmVzdWx0KSkge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgbGV0IGVycm9yID0gcmVzdWx0LmVycm9ycyA/IE9iamVjdC52YWx1ZXMocmVzdWx0LmVycm9ycylbMF0gOiB1bmRlZmluZWQ7XG4gICAgaWYgKGVycm9yICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIC8vIElmIHdlIGdvdCBiYWNrIHJlc3VsdC5lcnJvcnMsIHRoYXQgbWVhbnMgdGhlIGxvYWRlci9hY3Rpb24gdGhyZXdcbiAgICAgIC8vIF9zb21ldGhpbmdfIHRoYXQgd2Fzbid0IGEgUmVzcG9uc2UsIGJ1dCBpdCdzIG5vdCBndWFyYW50ZWVkL3JlcXVpcmVkXG4gICAgICAvLyB0byBiZSBhbiBgaW5zdGFuY2VvZiBFcnJvcmAgZWl0aGVyLCBzbyB3ZSBoYXZlIHRvIHVzZSB0aHJvdyBoZXJlIHRvXG4gICAgICAvLyBwcmVzZXJ2ZSB0aGUgXCJlcnJvclwiIHN0YXRlIG91dHNpZGUgb2YgcXVlcnlJbXBsLlxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICAgIC8vIFBpY2sgb2ZmIHRoZSByaWdodCBzdGF0ZSB2YWx1ZSB0byByZXR1cm5cbiAgICBpZiAocmVzdWx0LmFjdGlvbkRhdGEpIHtcbiAgICAgIHJldHVybiBPYmplY3QudmFsdWVzKHJlc3VsdC5hY3Rpb25EYXRhKVswXTtcbiAgICB9XG4gICAgaWYgKHJlc3VsdC5sb2FkZXJEYXRhKSB7XG4gICAgICB2YXIgX3Jlc3VsdCRhY3RpdmVEZWZlcnJlO1xuICAgICAgbGV0IGRhdGEgPSBPYmplY3QudmFsdWVzKHJlc3VsdC5sb2FkZXJEYXRhKVswXTtcbiAgICAgIGlmICgoX3Jlc3VsdCRhY3RpdmVEZWZlcnJlID0gcmVzdWx0LmFjdGl2ZURlZmVycmVkcykgIT0gbnVsbCAmJiBfcmVzdWx0JGFjdGl2ZURlZmVycmVbbWF0Y2gucm91dGUuaWRdKSB7XG4gICAgICAgIGRhdGFbVU5TQUZFX0RFRkVSUkVEX1NZTUJPTF0gPSByZXN1bHQuYWN0aXZlRGVmZXJyZWRzW21hdGNoLnJvdXRlLmlkXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG4gIGFzeW5jIGZ1bmN0aW9uIHF1ZXJ5SW1wbChyZXF1ZXN0LCBsb2NhdGlvbiwgbWF0Y2hlcywgcmVxdWVzdENvbnRleHQsIHJvdXRlTWF0Y2gpIHtcbiAgICBpbnZhcmlhbnQocmVxdWVzdC5zaWduYWwsIFwicXVlcnkoKS9xdWVyeVJvdXRlKCkgcmVxdWVzdHMgbXVzdCBjb250YWluIGFuIEFib3J0Q29udHJvbGxlciBzaWduYWxcIik7XG4gICAgdHJ5IHtcbiAgICAgIGlmIChpc011dGF0aW9uTWV0aG9kKHJlcXVlc3QubWV0aG9kLnRvTG93ZXJDYXNlKCkpKSB7XG4gICAgICAgIGxldCByZXN1bHQgPSBhd2FpdCBzdWJtaXQocmVxdWVzdCwgbWF0Y2hlcywgcm91dGVNYXRjaCB8fCBnZXRUYXJnZXRNYXRjaChtYXRjaGVzLCBsb2NhdGlvbiksIHJlcXVlc3RDb250ZXh0LCByb3V0ZU1hdGNoICE9IG51bGwpO1xuICAgICAgICByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgICAgbGV0IHJlc3VsdCA9IGF3YWl0IGxvYWRSb3V0ZURhdGEocmVxdWVzdCwgbWF0Y2hlcywgcmVxdWVzdENvbnRleHQsIHJvdXRlTWF0Y2gpO1xuICAgICAgcmV0dXJuIGlzUmVzcG9uc2UocmVzdWx0KSA/IHJlc3VsdCA6IF9leHRlbmRzKHt9LCByZXN1bHQsIHtcbiAgICAgICAgYWN0aW9uRGF0YTogbnVsbCxcbiAgICAgICAgYWN0aW9uSGVhZGVyczoge31cbiAgICAgIH0pO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIC8vIElmIHRoZSB1c2VyIHRocmV3L3JldHVybmVkIGEgUmVzcG9uc2UgaW4gY2FsbExvYWRlck9yQWN0aW9uLCB3ZSB0aHJvd1xuICAgICAgLy8gaXQgdG8gYmFpbCBvdXQgYW5kIHRoZW4gcmV0dXJuIG9yIHRocm93IGhlcmUgYmFzZWQgb24gd2hldGhlciB0aGUgdXNlclxuICAgICAgLy8gcmV0dXJuZWQgb3IgdGhyZXdcbiAgICAgIGlmIChpc1F1ZXJ5Um91dGVSZXNwb25zZShlKSkge1xuICAgICAgICBpZiAoZS50eXBlID09PSBSZXN1bHRUeXBlLmVycm9yKSB7XG4gICAgICAgICAgdGhyb3cgZS5yZXNwb25zZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZS5yZXNwb25zZTtcbiAgICAgIH1cbiAgICAgIC8vIFJlZGlyZWN0cyBhcmUgYWx3YXlzIHJldHVybmVkIHNpbmNlIHRoZXkgZG9uJ3QgcHJvcGFnYXRlIHRvIGNhdGNoXG4gICAgICAvLyBib3VuZGFyaWVzXG4gICAgICBpZiAoaXNSZWRpcmVjdFJlc3BvbnNlKGUpKSB7XG4gICAgICAgIHJldHVybiBlO1xuICAgICAgfVxuICAgICAgdGhyb3cgZTtcbiAgICB9XG4gIH1cbiAgYXN5bmMgZnVuY3Rpb24gc3VibWl0KHJlcXVlc3QsIG1hdGNoZXMsIGFjdGlvbk1hdGNoLCByZXF1ZXN0Q29udGV4dCwgaXNSb3V0ZVJlcXVlc3QpIHtcbiAgICBsZXQgcmVzdWx0O1xuICAgIGlmICghYWN0aW9uTWF0Y2gucm91dGUuYWN0aW9uICYmICFhY3Rpb25NYXRjaC5yb3V0ZS5sYXp5KSB7XG4gICAgICBsZXQgZXJyb3IgPSBnZXRJbnRlcm5hbFJvdXRlckVycm9yKDQwNSwge1xuICAgICAgICBtZXRob2Q6IHJlcXVlc3QubWV0aG9kLFxuICAgICAgICBwYXRobmFtZTogbmV3IFVSTChyZXF1ZXN0LnVybCkucGF0aG5hbWUsXG4gICAgICAgIHJvdXRlSWQ6IGFjdGlvbk1hdGNoLnJvdXRlLmlkXG4gICAgICB9KTtcbiAgICAgIGlmIChpc1JvdXRlUmVxdWVzdCkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIHJlc3VsdCA9IHtcbiAgICAgICAgdHlwZTogUmVzdWx0VHlwZS5lcnJvcixcbiAgICAgICAgZXJyb3JcbiAgICAgIH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCA9IGF3YWl0IGNhbGxMb2FkZXJPckFjdGlvbihcImFjdGlvblwiLCByZXF1ZXN0LCBhY3Rpb25NYXRjaCwgbWF0Y2hlcywgbWFuaWZlc3QsIG1hcFJvdXRlUHJvcGVydGllcywgYmFzZW5hbWUsIHtcbiAgICAgICAgaXNTdGF0aWNSZXF1ZXN0OiB0cnVlLFxuICAgICAgICBpc1JvdXRlUmVxdWVzdCxcbiAgICAgICAgcmVxdWVzdENvbnRleHRcbiAgICAgIH0pO1xuICAgICAgaWYgKHJlcXVlc3Quc2lnbmFsLmFib3J0ZWQpIHtcbiAgICAgICAgbGV0IG1ldGhvZCA9IGlzUm91dGVSZXF1ZXN0ID8gXCJxdWVyeVJvdXRlXCIgOiBcInF1ZXJ5XCI7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihtZXRob2QgKyBcIigpIGNhbGwgYWJvcnRlZFwiKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGlzUmVkaXJlY3RSZXN1bHQocmVzdWx0KSkge1xuICAgICAgLy8gVWhoaGggLSB0aGlzIHNob3VsZCBuZXZlciBoYXBwZW4sIHdlIHNob3VsZCBhbHdheXMgdGhyb3cgdGhlc2UgZnJvbVxuICAgICAgLy8gY2FsbExvYWRlck9yQWN0aW9uLCBidXQgdGhlIHR5cGUgbmFycm93aW5nIGhlcmUga2VlcHMgVFMgaGFwcHkgYW5kIHdlXG4gICAgICAvLyBjYW4gZ2V0IGJhY2sgb24gdGhlIFwidGhyb3cgYWxsIHJlZGlyZWN0IHJlc3BvbnNlc1wiIHRyYWluIGhlcmUgc2hvdWxkXG4gICAgICAvLyB0aGlzIGV2ZXIgaGFwcGVuIDovXG4gICAgICB0aHJvdyBuZXcgUmVzcG9uc2UobnVsbCwge1xuICAgICAgICBzdGF0dXM6IHJlc3VsdC5zdGF0dXMsXG4gICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICBMb2NhdGlvbjogcmVzdWx0LmxvY2F0aW9uXG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICBpZiAoaXNEZWZlcnJlZFJlc3VsdChyZXN1bHQpKSB7XG4gICAgICBsZXQgZXJyb3IgPSBnZXRJbnRlcm5hbFJvdXRlckVycm9yKDQwMCwge1xuICAgICAgICB0eXBlOiBcImRlZmVyLWFjdGlvblwiXG4gICAgICB9KTtcbiAgICAgIGlmIChpc1JvdXRlUmVxdWVzdCkge1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIHJlc3VsdCA9IHtcbiAgICAgICAgdHlwZTogUmVzdWx0VHlwZS5lcnJvcixcbiAgICAgICAgZXJyb3JcbiAgICAgIH07XG4gICAgfVxuICAgIGlmIChpc1JvdXRlUmVxdWVzdCkge1xuICAgICAgLy8gTm90ZTogVGhpcyBzaG91bGQgb25seSBiZSBub24tUmVzcG9uc2UgdmFsdWVzIGlmIHdlIGdldCBoZXJlLCBzaW5jZVxuICAgICAgLy8gaXNSb3V0ZVJlcXVlc3Qgc2hvdWxkIHRocm93IGFueSBSZXNwb25zZSByZWNlaXZlZCBpbiBjYWxsTG9hZGVyT3JBY3Rpb25cbiAgICAgIGlmIChpc0Vycm9yUmVzdWx0KHJlc3VsdCkpIHtcbiAgICAgICAgdGhyb3cgcmVzdWx0LmVycm9yO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgbWF0Y2hlczogW2FjdGlvbk1hdGNoXSxcbiAgICAgICAgbG9hZGVyRGF0YToge30sXG4gICAgICAgIGFjdGlvbkRhdGE6IHtcbiAgICAgICAgICBbYWN0aW9uTWF0Y2gucm91dGUuaWRdOiByZXN1bHQuZGF0YVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcnM6IG51bGwsXG4gICAgICAgIC8vIE5vdGU6IHN0YXR1c0NvZGUgKyBoZWFkZXJzIGFyZSB1bnVzZWQgaGVyZSBzaW5jZSBxdWVyeVJvdXRlIHdpbGxcbiAgICAgICAgLy8gcmV0dXJuIHRoZSByYXcgUmVzcG9uc2Ugb3IgdmFsdWVcbiAgICAgICAgc3RhdHVzQ29kZTogMjAwLFxuICAgICAgICBsb2FkZXJIZWFkZXJzOiB7fSxcbiAgICAgICAgYWN0aW9uSGVhZGVyczoge30sXG4gICAgICAgIGFjdGl2ZURlZmVycmVkczogbnVsbFxuICAgICAgfTtcbiAgICB9XG4gICAgaWYgKGlzRXJyb3JSZXN1bHQocmVzdWx0KSkge1xuICAgICAgLy8gU3RvcmUgb2ZmIHRoZSBwZW5kaW5nIGVycm9yIC0gd2UgdXNlIGl0IHRvIGRldGVybWluZSB3aGljaCBsb2FkZXJzXG4gICAgICAvLyB0byBjYWxsIGFuZCB3aWxsIGNvbW1pdCBpdCB3aGVuIHdlIGNvbXBsZXRlIHRoZSBuYXZpZ2F0aW9uXG4gICAgICBsZXQgYm91bmRhcnlNYXRjaCA9IGZpbmROZWFyZXN0Qm91bmRhcnkobWF0Y2hlcywgYWN0aW9uTWF0Y2gucm91dGUuaWQpO1xuICAgICAgbGV0IGNvbnRleHQgPSBhd2FpdCBsb2FkUm91dGVEYXRhKHJlcXVlc3QsIG1hdGNoZXMsIHJlcXVlc3RDb250ZXh0LCB1bmRlZmluZWQsIHtcbiAgICAgICAgW2JvdW5kYXJ5TWF0Y2gucm91dGUuaWRdOiByZXN1bHQuZXJyb3JcbiAgICAgIH0pO1xuICAgICAgLy8gYWN0aW9uIHN0YXR1cyBjb2RlcyB0YWtlIHByZWNlZGVuY2Ugb3ZlciBsb2FkZXIgc3RhdHVzIGNvZGVzXG4gICAgICByZXR1cm4gX2V4dGVuZHMoe30sIGNvbnRleHQsIHtcbiAgICAgICAgc3RhdHVzQ29kZTogaXNSb3V0ZUVycm9yUmVzcG9uc2UocmVzdWx0LmVycm9yKSA/IHJlc3VsdC5lcnJvci5zdGF0dXMgOiA1MDAsXG4gICAgICAgIGFjdGlvbkRhdGE6IG51bGwsXG4gICAgICAgIGFjdGlvbkhlYWRlcnM6IF9leHRlbmRzKHt9LCByZXN1bHQuaGVhZGVycyA/IHtcbiAgICAgICAgICBbYWN0aW9uTWF0Y2gucm91dGUuaWRdOiByZXN1bHQuaGVhZGVyc1xuICAgICAgICB9IDoge30pXG4gICAgICB9KTtcbiAgICB9XG4gICAgLy8gQ3JlYXRlIGEgR0VUIHJlcXVlc3QgZm9yIHRoZSBsb2FkZXJzXG4gICAgbGV0IGxvYWRlclJlcXVlc3QgPSBuZXcgUmVxdWVzdChyZXF1ZXN0LnVybCwge1xuICAgICAgaGVhZGVyczogcmVxdWVzdC5oZWFkZXJzLFxuICAgICAgcmVkaXJlY3Q6IHJlcXVlc3QucmVkaXJlY3QsXG4gICAgICBzaWduYWw6IHJlcXVlc3Quc2lnbmFsXG4gICAgfSk7XG4gICAgbGV0IGNvbnRleHQgPSBhd2FpdCBsb2FkUm91dGVEYXRhKGxvYWRlclJlcXVlc3QsIG1hdGNoZXMsIHJlcXVlc3RDb250ZXh0KTtcbiAgICByZXR1cm4gX2V4dGVuZHMoe30sIGNvbnRleHQsIHJlc3VsdC5zdGF0dXNDb2RlID8ge1xuICAgICAgc3RhdHVzQ29kZTogcmVzdWx0LnN0YXR1c0NvZGVcbiAgICB9IDoge30sIHtcbiAgICAgIGFjdGlvbkRhdGE6IHtcbiAgICAgICAgW2FjdGlvbk1hdGNoLnJvdXRlLmlkXTogcmVzdWx0LmRhdGFcbiAgICAgIH0sXG4gICAgICBhY3Rpb25IZWFkZXJzOiBfZXh0ZW5kcyh7fSwgcmVzdWx0LmhlYWRlcnMgPyB7XG4gICAgICAgIFthY3Rpb25NYXRjaC5yb3V0ZS5pZF06IHJlc3VsdC5oZWFkZXJzXG4gICAgICB9IDoge30pXG4gICAgfSk7XG4gIH1cbiAgYXN5bmMgZnVuY3Rpb24gbG9hZFJvdXRlRGF0YShyZXF1ZXN0LCBtYXRjaGVzLCByZXF1ZXN0Q29udGV4dCwgcm91dGVNYXRjaCwgcGVuZGluZ0FjdGlvbkVycm9yKSB7XG4gICAgbGV0IGlzUm91dGVSZXF1ZXN0ID0gcm91dGVNYXRjaCAhPSBudWxsO1xuICAgIC8vIFNob3J0IGNpcmN1aXQgaWYgd2UgaGF2ZSBubyBsb2FkZXJzIHRvIHJ1biAocXVlcnlSb3V0ZSgpKVxuICAgIGlmIChpc1JvdXRlUmVxdWVzdCAmJiAhKHJvdXRlTWF0Y2ggIT0gbnVsbCAmJiByb3V0ZU1hdGNoLnJvdXRlLmxvYWRlcikgJiYgIShyb3V0ZU1hdGNoICE9IG51bGwgJiYgcm91dGVNYXRjaC5yb3V0ZS5sYXp5KSkge1xuICAgICAgdGhyb3cgZ2V0SW50ZXJuYWxSb3V0ZXJFcnJvcig0MDAsIHtcbiAgICAgICAgbWV0aG9kOiByZXF1ZXN0Lm1ldGhvZCxcbiAgICAgICAgcGF0aG5hbWU6IG5ldyBVUkwocmVxdWVzdC51cmwpLnBhdGhuYW1lLFxuICAgICAgICByb3V0ZUlkOiByb3V0ZU1hdGNoID09IG51bGwgPyB2b2lkIDAgOiByb3V0ZU1hdGNoLnJvdXRlLmlkXG4gICAgICB9KTtcbiAgICB9XG4gICAgbGV0IHJlcXVlc3RNYXRjaGVzID0gcm91dGVNYXRjaCA/IFtyb3V0ZU1hdGNoXSA6IGdldExvYWRlck1hdGNoZXNVbnRpbEJvdW5kYXJ5KG1hdGNoZXMsIE9iamVjdC5rZXlzKHBlbmRpbmdBY3Rpb25FcnJvciB8fCB7fSlbMF0pO1xuICAgIGxldCBtYXRjaGVzVG9Mb2FkID0gcmVxdWVzdE1hdGNoZXMuZmlsdGVyKG0gPT4gbS5yb3V0ZS5sb2FkZXIgfHwgbS5yb3V0ZS5sYXp5KTtcbiAgICAvLyBTaG9ydCBjaXJjdWl0IGlmIHdlIGhhdmUgbm8gbG9hZGVycyB0byBydW4gKHF1ZXJ5KCkpXG4gICAgaWYgKG1hdGNoZXNUb0xvYWQubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBtYXRjaGVzLFxuICAgICAgICAvLyBBZGQgYSBudWxsIGZvciBhbGwgbWF0Y2hlZCByb3V0ZXMgZm9yIHByb3BlciByZXZhbGlkYXRpb24gb24gdGhlIGNsaWVudFxuICAgICAgICBsb2FkZXJEYXRhOiBtYXRjaGVzLnJlZHVjZSgoYWNjLCBtKSA9PiBPYmplY3QuYXNzaWduKGFjYywge1xuICAgICAgICAgIFttLnJvdXRlLmlkXTogbnVsbFxuICAgICAgICB9KSwge30pLFxuICAgICAgICBlcnJvcnM6IHBlbmRpbmdBY3Rpb25FcnJvciB8fCBudWxsLFxuICAgICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICAgIGxvYWRlckhlYWRlcnM6IHt9LFxuICAgICAgICBhY3RpdmVEZWZlcnJlZHM6IG51bGxcbiAgICAgIH07XG4gICAgfVxuICAgIGxldCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoWy4uLm1hdGNoZXNUb0xvYWQubWFwKG1hdGNoID0+IGNhbGxMb2FkZXJPckFjdGlvbihcImxvYWRlclwiLCByZXF1ZXN0LCBtYXRjaCwgbWF0Y2hlcywgbWFuaWZlc3QsIG1hcFJvdXRlUHJvcGVydGllcywgYmFzZW5hbWUsIHtcbiAgICAgIGlzU3RhdGljUmVxdWVzdDogdHJ1ZSxcbiAgICAgIGlzUm91dGVSZXF1ZXN0LFxuICAgICAgcmVxdWVzdENvbnRleHRcbiAgICB9KSldKTtcbiAgICBpZiAocmVxdWVzdC5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgbGV0IG1ldGhvZCA9IGlzUm91dGVSZXF1ZXN0ID8gXCJxdWVyeVJvdXRlXCIgOiBcInF1ZXJ5XCI7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IobWV0aG9kICsgXCIoKSBjYWxsIGFib3J0ZWRcIik7XG4gICAgfVxuICAgIC8vIFByb2Nlc3MgYW5kIGNvbW1pdCBvdXRwdXQgZnJvbSBsb2FkZXJzXG4gICAgbGV0IGFjdGl2ZURlZmVycmVkcyA9IG5ldyBNYXAoKTtcbiAgICBsZXQgY29udGV4dCA9IHByb2Nlc3NSb3V0ZUxvYWRlckRhdGEobWF0Y2hlcywgbWF0Y2hlc1RvTG9hZCwgcmVzdWx0cywgcGVuZGluZ0FjdGlvbkVycm9yLCBhY3RpdmVEZWZlcnJlZHMpO1xuICAgIC8vIEFkZCBhIG51bGwgZm9yIGFueSBub24tbG9hZGVyIG1hdGNoZXMgZm9yIHByb3BlciByZXZhbGlkYXRpb24gb24gdGhlIGNsaWVudFxuICAgIGxldCBleGVjdXRlZExvYWRlcnMgPSBuZXcgU2V0KG1hdGNoZXNUb0xvYWQubWFwKG1hdGNoID0+IG1hdGNoLnJvdXRlLmlkKSk7XG4gICAgbWF0Y2hlcy5mb3JFYWNoKG1hdGNoID0+IHtcbiAgICAgIGlmICghZXhlY3V0ZWRMb2FkZXJzLmhhcyhtYXRjaC5yb3V0ZS5pZCkpIHtcbiAgICAgICAgY29udGV4dC5sb2FkZXJEYXRhW21hdGNoLnJvdXRlLmlkXSA9IG51bGw7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIF9leHRlbmRzKHt9LCBjb250ZXh0LCB7XG4gICAgICBtYXRjaGVzLFxuICAgICAgYWN0aXZlRGVmZXJyZWRzOiBhY3RpdmVEZWZlcnJlZHMuc2l6ZSA+IDAgPyBPYmplY3QuZnJvbUVudHJpZXMoYWN0aXZlRGVmZXJyZWRzLmVudHJpZXMoKSkgOiBudWxsXG4gICAgfSk7XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBkYXRhUm91dGVzLFxuICAgIHF1ZXJ5LFxuICAgIHF1ZXJ5Um91dGVcbiAgfTtcbn1cbi8vI2VuZHJlZ2lvblxuLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbi8vI3JlZ2lvbiBIZWxwZXJzXG4vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuLyoqXG4gKiBHaXZlbiBhbiBleGlzdGluZyBTdGF0aWNIYW5kbGVyQ29udGV4dCBhbmQgYW4gZXJyb3IgdGhyb3duIGF0IHJlbmRlciB0aW1lLFxuICogcHJvdmlkZSBhbiB1cGRhdGVkIFN0YXRpY0hhbmRsZXJDb250ZXh0IHN1aXRhYmxlIGZvciBhIHNlY29uZCBTU1IgcmVuZGVyXG4gKi9cbmZ1bmN0aW9uIGdldFN0YXRpY0NvbnRleHRGcm9tRXJyb3Iocm91dGVzLCBjb250ZXh0LCBlcnJvcikge1xuICBsZXQgbmV3Q29udGV4dCA9IF9leHRlbmRzKHt9LCBjb250ZXh0LCB7XG4gICAgc3RhdHVzQ29kZTogNTAwLFxuICAgIGVycm9yczoge1xuICAgICAgW2NvbnRleHQuX2RlZXBlc3RSZW5kZXJlZEJvdW5kYXJ5SWQgfHwgcm91dGVzWzBdLmlkXTogZXJyb3JcbiAgICB9XG4gIH0pO1xuICByZXR1cm4gbmV3Q29udGV4dDtcbn1cbmZ1bmN0aW9uIGlzU3VibWlzc2lvbk5hdmlnYXRpb24ob3B0cykge1xuICByZXR1cm4gb3B0cyAhPSBudWxsICYmIChcImZvcm1EYXRhXCIgaW4gb3B0cyAmJiBvcHRzLmZvcm1EYXRhICE9IG51bGwgfHwgXCJib2R5XCIgaW4gb3B0cyAmJiBvcHRzLmJvZHkgIT09IHVuZGVmaW5lZCk7XG59XG5mdW5jdGlvbiBub3JtYWxpemVUbyhsb2NhdGlvbiwgbWF0Y2hlcywgYmFzZW5hbWUsIHByZXBlbmRCYXNlbmFtZSwgdG8sIGZyb21Sb3V0ZUlkLCByZWxhdGl2ZSkge1xuICBsZXQgY29udGV4dHVhbE1hdGNoZXM7XG4gIGxldCBhY3RpdmVSb3V0ZU1hdGNoO1xuICBpZiAoZnJvbVJvdXRlSWQgIT0gbnVsbCAmJiByZWxhdGl2ZSAhPT0gXCJwYXRoXCIpIHtcbiAgICAvLyBHcmFiIG1hdGNoZXMgdXAgdG8gdGhlIGNhbGxpbmcgcm91dGUgc28gb3VyIHJvdXRlLXJlbGF0aXZlIGxvZ2ljIGlzXG4gICAgLy8gcmVsYXRpdmUgdG8gdGhlIGNvcnJlY3Qgc291cmNlIHJvdXRlLiAgV2hlbiB1c2luZyByZWxhdGl2ZTpwYXRoLFxuICAgIC8vIGZyb21Sb3V0ZUlkIGlzIGlnbm9yZWQgc2luY2UgdGhhdCBpcyBhbHdheXMgcmVsYXRpdmUgdG8gdGhlIGN1cnJlbnRcbiAgICAvLyBsb2NhdGlvbiBwYXRoXG4gICAgY29udGV4dHVhbE1hdGNoZXMgPSBbXTtcbiAgICBmb3IgKGxldCBtYXRjaCBvZiBtYXRjaGVzKSB7XG4gICAgICBjb250ZXh0dWFsTWF0Y2hlcy5wdXNoKG1hdGNoKTtcbiAgICAgIGlmIChtYXRjaC5yb3V0ZS5pZCA9PT0gZnJvbVJvdXRlSWQpIHtcbiAgICAgICAgYWN0aXZlUm91dGVNYXRjaCA9IG1hdGNoO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgY29udGV4dHVhbE1hdGNoZXMgPSBtYXRjaGVzO1xuICAgIGFjdGl2ZVJvdXRlTWF0Y2ggPSBtYXRjaGVzW21hdGNoZXMubGVuZ3RoIC0gMV07XG4gIH1cbiAgLy8gUmVzb2x2ZSB0aGUgcmVsYXRpdmUgcGF0aFxuICBsZXQgcGF0aCA9IHJlc29sdmVUbyh0byA/IHRvIDogXCIuXCIsIGdldFBhdGhDb250cmlidXRpbmdNYXRjaGVzKGNvbnRleHR1YWxNYXRjaGVzKS5tYXAobSA9PiBtLnBhdGhuYW1lQmFzZSksIHN0cmlwQmFzZW5hbWUobG9jYXRpb24ucGF0aG5hbWUsIGJhc2VuYW1lKSB8fCBsb2NhdGlvbi5wYXRobmFtZSwgcmVsYXRpdmUgPT09IFwicGF0aFwiKTtcbiAgLy8gV2hlbiBgdG9gIGlzIG5vdCBzcGVjaWZpZWQgd2UgaW5oZXJpdCBzZWFyY2gvaGFzaCBmcm9tIHRoZSBjdXJyZW50XG4gIC8vIGxvY2F0aW9uLCB1bmxpa2Ugd2hlbiB0bz1cIi5cIiBhbmQgd2UganVzdCBpbmhlcml0IHRoZSBwYXRoLlxuICAvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL3JlbWl4LXJ1bi9yZW1peC9pc3N1ZXMvOTI3XG4gIGlmICh0byA9PSBudWxsKSB7XG4gICAgcGF0aC5zZWFyY2ggPSBsb2NhdGlvbi5zZWFyY2g7XG4gICAgcGF0aC5oYXNoID0gbG9jYXRpb24uaGFzaDtcbiAgfVxuICAvLyBBZGQgYW4gP2luZGV4IHBhcmFtIGZvciBtYXRjaGVkIGluZGV4IHJvdXRlcyBpZiB3ZSBkb24ndCBhbHJlYWR5IGhhdmUgb25lXG4gIGlmICgodG8gPT0gbnVsbCB8fCB0byA9PT0gXCJcIiB8fCB0byA9PT0gXCIuXCIpICYmIGFjdGl2ZVJvdXRlTWF0Y2ggJiYgYWN0aXZlUm91dGVNYXRjaC5yb3V0ZS5pbmRleCAmJiAhaGFzTmFrZWRJbmRleFF1ZXJ5KHBhdGguc2VhcmNoKSkge1xuICAgIHBhdGguc2VhcmNoID0gcGF0aC5zZWFyY2ggPyBwYXRoLnNlYXJjaC5yZXBsYWNlKC9eXFw/LywgXCI/aW5kZXgmXCIpIDogXCI/aW5kZXhcIjtcbiAgfVxuICAvLyBJZiB3ZSdyZSBvcGVyYXRpbmcgd2l0aGluIGEgYmFzZW5hbWUsIHByZXBlbmQgaXQgdG8gdGhlIHBhdGhuYW1lLiAgSWZcbiAgLy8gdGhpcyBpcyBhIHJvb3QgbmF2aWdhdGlvbiwgdGhlbiBqdXN0IHVzZSB0aGUgcmF3IGJhc2VuYW1lIHdoaWNoIGFsbG93c1xuICAvLyB0aGUgYmFzZW5hbWUgdG8gaGF2ZSBmdWxsIGNvbnRyb2wgb3ZlciB0aGUgcHJlc2VuY2Ugb2YgYSB0cmFpbGluZyBzbGFzaFxuICAvLyBvbiByb290IGFjdGlvbnNcbiAgaWYgKHByZXBlbmRCYXNlbmFtZSAmJiBiYXNlbmFtZSAhPT0gXCIvXCIpIHtcbiAgICBwYXRoLnBhdGhuYW1lID0gcGF0aC5wYXRobmFtZSA9PT0gXCIvXCIgPyBiYXNlbmFtZSA6IGpvaW5QYXRocyhbYmFzZW5hbWUsIHBhdGgucGF0aG5hbWVdKTtcbiAgfVxuICByZXR1cm4gY3JlYXRlUGF0aChwYXRoKTtcbn1cbi8vIE5vcm1hbGl6ZSBuYXZpZ2F0aW9uIG9wdGlvbnMgYnkgY29udmVydGluZyBmb3JtTWV0aG9kPUdFVCBmb3JtRGF0YSBvYmplY3RzIHRvXG4vLyBVUkxTZWFyY2hQYXJhbXMgc28gdGhleSBiZWhhdmUgaWRlbnRpY2FsbHkgdG8gbGlua3Mgd2l0aCBxdWVyeSBwYXJhbXNcbmZ1bmN0aW9uIG5vcm1hbGl6ZU5hdmlnYXRlT3B0aW9ucyhub3JtYWxpemVGb3JtTWV0aG9kLCBpc0ZldGNoZXIsIHBhdGgsIG9wdHMpIHtcbiAgLy8gUmV0dXJuIGxvY2F0aW9uIHZlcmJhdGltIG9uIG5vbi1zdWJtaXNzaW9uIG5hdmlnYXRpb25zXG4gIGlmICghb3B0cyB8fCAhaXNTdWJtaXNzaW9uTmF2aWdhdGlvbihvcHRzKSkge1xuICAgIHJldHVybiB7XG4gICAgICBwYXRoXG4gICAgfTtcbiAgfVxuICBpZiAob3B0cy5mb3JtTWV0aG9kICYmICFpc1ZhbGlkTWV0aG9kKG9wdHMuZm9ybU1ldGhvZCkpIHtcbiAgICByZXR1cm4ge1xuICAgICAgcGF0aCxcbiAgICAgIGVycm9yOiBnZXRJbnRlcm5hbFJvdXRlckVycm9yKDQwNSwge1xuICAgICAgICBtZXRob2Q6IG9wdHMuZm9ybU1ldGhvZFxuICAgICAgfSlcbiAgICB9O1xuICB9XG4gIGxldCBnZXRJbnZhbGlkQm9keUVycm9yID0gKCkgPT4gKHtcbiAgICBwYXRoLFxuICAgIGVycm9yOiBnZXRJbnRlcm5hbFJvdXRlckVycm9yKDQwMCwge1xuICAgICAgdHlwZTogXCJpbnZhbGlkLWJvZHlcIlxuICAgIH0pXG4gIH0pO1xuICAvLyBDcmVhdGUgYSBTdWJtaXNzaW9uIG9uIG5vbi1HRVQgbmF2aWdhdGlvbnNcbiAgbGV0IHJhd0Zvcm1NZXRob2QgPSBvcHRzLmZvcm1NZXRob2QgfHwgXCJnZXRcIjtcbiAgbGV0IGZvcm1NZXRob2QgPSBub3JtYWxpemVGb3JtTWV0aG9kID8gcmF3Rm9ybU1ldGhvZC50b1VwcGVyQ2FzZSgpIDogcmF3Rm9ybU1ldGhvZC50b0xvd2VyQ2FzZSgpO1xuICBsZXQgZm9ybUFjdGlvbiA9IHN0cmlwSGFzaEZyb21QYXRoKHBhdGgpO1xuICBpZiAob3B0cy5ib2R5ICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAob3B0cy5mb3JtRW5jVHlwZSA9PT0gXCJ0ZXh0L3BsYWluXCIpIHtcbiAgICAgIC8vIHRleHQgb25seSBzdXBwb3J0IFBPU1QvUFVUL1BBVENIL0RFTEVURSBzdWJtaXNzaW9uc1xuICAgICAgaWYgKCFpc011dGF0aW9uTWV0aG9kKGZvcm1NZXRob2QpKSB7XG4gICAgICAgIHJldHVybiBnZXRJbnZhbGlkQm9keUVycm9yKCk7XG4gICAgICB9XG4gICAgICBsZXQgdGV4dCA9IHR5cGVvZiBvcHRzLmJvZHkgPT09IFwic3RyaW5nXCIgPyBvcHRzLmJvZHkgOiBvcHRzLmJvZHkgaW5zdGFuY2VvZiBGb3JtRGF0YSB8fCBvcHRzLmJvZHkgaW5zdGFuY2VvZiBVUkxTZWFyY2hQYXJhbXMgP1xuICAgICAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvZm9ybS1jb250cm9sLWluZnJhc3RydWN0dXJlLmh0bWwjcGxhaW4tdGV4dC1mb3JtLWRhdGFcbiAgICAgIEFycmF5LmZyb20ob3B0cy5ib2R5LmVudHJpZXMoKSkucmVkdWNlKChhY2MsIF9yZWYzKSA9PiB7XG4gICAgICAgIGxldCBbbmFtZSwgdmFsdWVdID0gX3JlZjM7XG4gICAgICAgIHJldHVybiBcIlwiICsgYWNjICsgbmFtZSArIFwiPVwiICsgdmFsdWUgKyBcIlxcblwiO1xuICAgICAgfSwgXCJcIikgOiBTdHJpbmcob3B0cy5ib2R5KTtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHBhdGgsXG4gICAgICAgIHN1Ym1pc3Npb246IHtcbiAgICAgICAgICBmb3JtTWV0aG9kLFxuICAgICAgICAgIGZvcm1BY3Rpb24sXG4gICAgICAgICAgZm9ybUVuY1R5cGU6IG9wdHMuZm9ybUVuY1R5cGUsXG4gICAgICAgICAgZm9ybURhdGE6IHVuZGVmaW5lZCxcbiAgICAgICAgICBqc29uOiB1bmRlZmluZWQsXG4gICAgICAgICAgdGV4dFxuICAgICAgICB9XG4gICAgICB9O1xuICAgIH0gZWxzZSBpZiAob3B0cy5mb3JtRW5jVHlwZSA9PT0gXCJhcHBsaWNhdGlvbi9qc29uXCIpIHtcbiAgICAgIC8vIGpzb24gb25seSBzdXBwb3J0cyBQT1NUL1BVVC9QQVRDSC9ERUxFVEUgc3VibWlzc2lvbnNcbiAgICAgIGlmICghaXNNdXRhdGlvbk1ldGhvZChmb3JtTWV0aG9kKSkge1xuICAgICAgICByZXR1cm4gZ2V0SW52YWxpZEJvZHlFcnJvcigpO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgbGV0IGpzb24gPSB0eXBlb2Ygb3B0cy5ib2R5ID09PSBcInN0cmluZ1wiID8gSlNPTi5wYXJzZShvcHRzLmJvZHkpIDogb3B0cy5ib2R5O1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgc3VibWlzc2lvbjoge1xuICAgICAgICAgICAgZm9ybU1ldGhvZCxcbiAgICAgICAgICAgIGZvcm1BY3Rpb24sXG4gICAgICAgICAgICBmb3JtRW5jVHlwZTogb3B0cy5mb3JtRW5jVHlwZSxcbiAgICAgICAgICAgIGZvcm1EYXRhOiB1bmRlZmluZWQsXG4gICAgICAgICAgICBqc29uLFxuICAgICAgICAgICAgdGV4dDogdW5kZWZpbmVkXG4gICAgICAgICAgfVxuICAgICAgICB9O1xuICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICByZXR1cm4gZ2V0SW52YWxpZEJvZHlFcnJvcigpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICBpbnZhcmlhbnQodHlwZW9mIEZvcm1EYXRhID09PSBcImZ1bmN0aW9uXCIsIFwiRm9ybURhdGEgaXMgbm90IGF2YWlsYWJsZSBpbiB0aGlzIGVudmlyb25tZW50XCIpO1xuICBsZXQgc2VhcmNoUGFyYW1zO1xuICBsZXQgZm9ybURhdGE7XG4gIGlmIChvcHRzLmZvcm1EYXRhKSB7XG4gICAgc2VhcmNoUGFyYW1zID0gY29udmVydEZvcm1EYXRhVG9TZWFyY2hQYXJhbXMob3B0cy5mb3JtRGF0YSk7XG4gICAgZm9ybURhdGEgPSBvcHRzLmZvcm1EYXRhO1xuICB9IGVsc2UgaWYgKG9wdHMuYm9keSBpbnN0YW5jZW9mIEZvcm1EYXRhKSB7XG4gICAgc2VhcmNoUGFyYW1zID0gY29udmVydEZvcm1EYXRhVG9TZWFyY2hQYXJhbXMob3B0cy5ib2R5KTtcbiAgICBmb3JtRGF0YSA9IG9wdHMuYm9keTtcbiAgfSBlbHNlIGlmIChvcHRzLmJvZHkgaW5zdGFuY2VvZiBVUkxTZWFyY2hQYXJhbXMpIHtcbiAgICBzZWFyY2hQYXJhbXMgPSBvcHRzLmJvZHk7XG4gICAgZm9ybURhdGEgPSBjb252ZXJ0U2VhcmNoUGFyYW1zVG9Gb3JtRGF0YShzZWFyY2hQYXJhbXMpO1xuICB9IGVsc2UgaWYgKG9wdHMuYm9keSA9PSBudWxsKSB7XG4gICAgc2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuICAgIGZvcm1EYXRhID0gbmV3IEZvcm1EYXRhKCk7XG4gIH0gZWxzZSB7XG4gICAgdHJ5IHtcbiAgICAgIHNlYXJjaFBhcmFtcyA9IG5ldyBVUkxTZWFyY2hQYXJhbXMob3B0cy5ib2R5KTtcbiAgICAgIGZvcm1EYXRhID0gY29udmVydFNlYXJjaFBhcmFtc1RvRm9ybURhdGEoc2VhcmNoUGFyYW1zKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICByZXR1cm4gZ2V0SW52YWxpZEJvZHlFcnJvcigpO1xuICAgIH1cbiAgfVxuICBsZXQgc3VibWlzc2lvbiA9IHtcbiAgICBmb3JtTWV0aG9kLFxuICAgIGZvcm1BY3Rpb24sXG4gICAgZm9ybUVuY1R5cGU6IG9wdHMgJiYgb3B0cy5mb3JtRW5jVHlwZSB8fCBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiLFxuICAgIGZvcm1EYXRhLFxuICAgIGpzb246IHVuZGVmaW5lZCxcbiAgICB0ZXh0OiB1bmRlZmluZWRcbiAgfTtcbiAgaWYgKGlzTXV0YXRpb25NZXRob2Qoc3VibWlzc2lvbi5mb3JtTWV0aG9kKSkge1xuICAgIHJldHVybiB7XG4gICAgICBwYXRoLFxuICAgICAgc3VibWlzc2lvblxuICAgIH07XG4gIH1cbiAgLy8gRmxhdHRlbiBzdWJtaXNzaW9uIG9udG8gVVJMU2VhcmNoUGFyYW1zIGZvciBHRVQgc3VibWlzc2lvbnNcbiAgbGV0IHBhcnNlZFBhdGggPSBwYXJzZVBhdGgocGF0aCk7XG4gIC8vIE9uIEdFVCBuYXZpZ2F0aW9uIHN1Ym1pc3Npb25zIHdlIGNhbiBkcm9wIHRoZSA/aW5kZXggcGFyYW0gZnJvbSB0aGVcbiAgLy8gcmVzdWx0aW5nIGxvY2F0aW9uIHNpbmNlIGFsbCBsb2FkZXJzIHdpbGwgcnVuLiAgQnV0IGZldGNoZXIgR0VUIHN1Ym1pc3Npb25zXG4gIC8vIG9ubHkgcnVuIGEgc2luZ2xlIGxvYWRlciBzbyB3ZSBuZWVkIHRvIHByZXNlcnZlIGFueSBpbmNvbWluZyA/aW5kZXggcGFyYW1zXG4gIGlmIChpc0ZldGNoZXIgJiYgcGFyc2VkUGF0aC5zZWFyY2ggJiYgaGFzTmFrZWRJbmRleFF1ZXJ5KHBhcnNlZFBhdGguc2VhcmNoKSkge1xuICAgIHNlYXJjaFBhcmFtcy5hcHBlbmQoXCJpbmRleFwiLCBcIlwiKTtcbiAgfVxuICBwYXJzZWRQYXRoLnNlYXJjaCA9IFwiP1wiICsgc2VhcmNoUGFyYW1zO1xuICByZXR1cm4ge1xuICAgIHBhdGg6IGNyZWF0ZVBhdGgocGFyc2VkUGF0aCksXG4gICAgc3VibWlzc2lvblxuICB9O1xufVxuLy8gRmlsdGVyIG91dCBhbGwgcm91dGVzIGJlbG93IGFueSBjYXVnaHQgZXJyb3IgYXMgdGhleSBhcmVuJ3QgZ29pbmcgdG9cbi8vIHJlbmRlciBzbyB3ZSBkb24ndCBuZWVkIHRvIGxvYWQgdGhlbVxuZnVuY3Rpb24gZ2V0TG9hZGVyTWF0Y2hlc1VudGlsQm91bmRhcnkobWF0Y2hlcywgYm91bmRhcnlJZCkge1xuICBsZXQgYm91bmRhcnlNYXRjaGVzID0gbWF0Y2hlcztcbiAgaWYgKGJvdW5kYXJ5SWQpIHtcbiAgICBsZXQgaW5kZXggPSBtYXRjaGVzLmZpbmRJbmRleChtID0+IG0ucm91dGUuaWQgPT09IGJvdW5kYXJ5SWQpO1xuICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICBib3VuZGFyeU1hdGNoZXMgPSBtYXRjaGVzLnNsaWNlKDAsIGluZGV4KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGJvdW5kYXJ5TWF0Y2hlcztcbn1cbmZ1bmN0aW9uIGdldE1hdGNoZXNUb0xvYWQoaGlzdG9yeSwgc3RhdGUsIG1hdGNoZXMsIHN1Ym1pc3Npb24sIGxvY2F0aW9uLCBpc1JldmFsaWRhdGlvblJlcXVpcmVkLCBjYW5jZWxsZWREZWZlcnJlZFJvdXRlcywgY2FuY2VsbGVkRmV0Y2hlckxvYWRzLCBmZXRjaExvYWRNYXRjaGVzLCBmZXRjaFJlZGlyZWN0SWRzLCByb3V0ZXNUb1VzZSwgYmFzZW5hbWUsIHBlbmRpbmdBY3Rpb25EYXRhLCBwZW5kaW5nRXJyb3IpIHtcbiAgbGV0IGFjdGlvblJlc3VsdCA9IHBlbmRpbmdFcnJvciA/IE9iamVjdC52YWx1ZXMocGVuZGluZ0Vycm9yKVswXSA6IHBlbmRpbmdBY3Rpb25EYXRhID8gT2JqZWN0LnZhbHVlcyhwZW5kaW5nQWN0aW9uRGF0YSlbMF0gOiB1bmRlZmluZWQ7XG4gIGxldCBjdXJyZW50VXJsID0gaGlzdG9yeS5jcmVhdGVVUkwoc3RhdGUubG9jYXRpb24pO1xuICBsZXQgbmV4dFVybCA9IGhpc3RvcnkuY3JlYXRlVVJMKGxvY2F0aW9uKTtcbiAgLy8gUGljayBuYXZpZ2F0aW9uIG1hdGNoZXMgdGhhdCBhcmUgbmV0LW5ldyBvciBxdWFsaWZ5IGZvciByZXZhbGlkYXRpb25cbiAgbGV0IGJvdW5kYXJ5SWQgPSBwZW5kaW5nRXJyb3IgPyBPYmplY3Qua2V5cyhwZW5kaW5nRXJyb3IpWzBdIDogdW5kZWZpbmVkO1xuICBsZXQgYm91bmRhcnlNYXRjaGVzID0gZ2V0TG9hZGVyTWF0Y2hlc1VudGlsQm91bmRhcnkobWF0Y2hlcywgYm91bmRhcnlJZCk7XG4gIGxldCBuYXZpZ2F0aW9uTWF0Y2hlcyA9IGJvdW5kYXJ5TWF0Y2hlcy5maWx0ZXIoKG1hdGNoLCBpbmRleCkgPT4ge1xuICAgIGlmIChtYXRjaC5yb3V0ZS5sYXp5KSB7XG4gICAgICAvLyBXZSBoYXZlbid0IGxvYWRlZCB0aGlzIHJvdXRlIHlldCBzbyB3ZSBkb24ndCBrbm93IGlmIGl0J3MgZ290IGEgbG9hZGVyIVxuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGlmIChtYXRjaC5yb3V0ZS5sb2FkZXIgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICAvLyBBbHdheXMgY2FsbCB0aGUgbG9hZGVyIG9uIG5ldyByb3V0ZSBpbnN0YW5jZXMgYW5kIHBlbmRpbmcgZGVmZXIgY2FuY2VsbGF0aW9uc1xuICAgIGlmIChpc05ld0xvYWRlcihzdGF0ZS5sb2FkZXJEYXRhLCBzdGF0ZS5tYXRjaGVzW2luZGV4XSwgbWF0Y2gpIHx8IGNhbmNlbGxlZERlZmVycmVkUm91dGVzLnNvbWUoaWQgPT4gaWQgPT09IG1hdGNoLnJvdXRlLmlkKSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIC8vIFRoaXMgaXMgdGhlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gZm9yIHdoZW4gd2UgcmV2YWxpZGF0ZS4gIElmIHRoZSByb3V0ZVxuICAgIC8vIHByb3ZpZGVzIGl0J3Mgb3duIGltcGxlbWVudGF0aW9uLCB0aGVuIHdlIGdpdmUgdGhlbSBmdWxsIGNvbnRyb2wgYnV0XG4gICAgLy8gcHJvdmlkZSB0aGlzIHZhbHVlIHNvIHRoZXkgY2FuIGxldmVyYWdlIGl0IGlmIG5lZWRlZCBhZnRlciB0aGV5IGNoZWNrXG4gICAgLy8gdGhlaXIgb3duIHNwZWNpZmljIHVzZSBjYXNlc1xuICAgIGxldCBjdXJyZW50Um91dGVNYXRjaCA9IHN0YXRlLm1hdGNoZXNbaW5kZXhdO1xuICAgIGxldCBuZXh0Um91dGVNYXRjaCA9IG1hdGNoO1xuICAgIHJldHVybiBzaG91bGRSZXZhbGlkYXRlTG9hZGVyKG1hdGNoLCBfZXh0ZW5kcyh7XG4gICAgICBjdXJyZW50VXJsLFxuICAgICAgY3VycmVudFBhcmFtczogY3VycmVudFJvdXRlTWF0Y2gucGFyYW1zLFxuICAgICAgbmV4dFVybCxcbiAgICAgIG5leHRQYXJhbXM6IG5leHRSb3V0ZU1hdGNoLnBhcmFtc1xuICAgIH0sIHN1Ym1pc3Npb24sIHtcbiAgICAgIGFjdGlvblJlc3VsdCxcbiAgICAgIGRlZmF1bHRTaG91bGRSZXZhbGlkYXRlOlxuICAgICAgLy8gRm9yY2VkIHJldmFsaWRhdGlvbiBkdWUgdG8gc3VibWlzc2lvbiwgdXNlUmV2YWxpZGF0b3IsIG9yIFgtUmVtaXgtUmV2YWxpZGF0ZVxuICAgICAgaXNSZXZhbGlkYXRpb25SZXF1aXJlZCB8fFxuICAgICAgLy8gQ2xpY2tlZCB0aGUgc2FtZSBsaW5rLCByZXN1Ym1pdHRlZCBhIEdFVCBmb3JtXG4gICAgICBjdXJyZW50VXJsLnBhdGhuYW1lICsgY3VycmVudFVybC5zZWFyY2ggPT09IG5leHRVcmwucGF0aG5hbWUgKyBuZXh0VXJsLnNlYXJjaCB8fFxuICAgICAgLy8gU2VhcmNoIHBhcmFtcyBhZmZlY3QgYWxsIGxvYWRlcnNcbiAgICAgIGN1cnJlbnRVcmwuc2VhcmNoICE9PSBuZXh0VXJsLnNlYXJjaCB8fCBpc05ld1JvdXRlSW5zdGFuY2UoY3VycmVudFJvdXRlTWF0Y2gsIG5leHRSb3V0ZU1hdGNoKVxuICAgIH0pKTtcbiAgfSk7XG4gIC8vIFBpY2sgZmV0Y2hlci5sb2FkcyB0aGF0IG5lZWQgdG8gYmUgcmV2YWxpZGF0ZWRcbiAgbGV0IHJldmFsaWRhdGluZ0ZldGNoZXJzID0gW107XG4gIGZldGNoTG9hZE1hdGNoZXMuZm9yRWFjaCgoZiwga2V5KSA9PiB7XG4gICAgLy8gRG9uJ3QgcmV2YWxpZGF0ZSBpZiBmZXRjaGVyIHdvbid0IGJlIHByZXNlbnQgaW4gdGhlIHN1YnNlcXVlbnQgcmVuZGVyXG4gICAgaWYgKCFtYXRjaGVzLnNvbWUobSA9PiBtLnJvdXRlLmlkID09PSBmLnJvdXRlSWQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBmZXRjaGVyTWF0Y2hlcyA9IG1hdGNoUm91dGVzKHJvdXRlc1RvVXNlLCBmLnBhdGgsIGJhc2VuYW1lKTtcbiAgICAvLyBJZiB0aGUgZmV0Y2hlciBwYXRoIG5vIGxvbmdlciBtYXRjaGVzLCBwdXNoIGl0IGluIHdpdGggbnVsbCBtYXRjaGVzIHNvXG4gICAgLy8gd2UgY2FuIHRyaWdnZXIgYSA0MDQgaW4gY2FsbExvYWRlcnNBbmRNYXliZVJlc29sdmVEYXRhLiAgTm90ZSB0aGlzIGlzXG4gICAgLy8gY3VycmVudGx5IG9ubHkgYSB1c2UtY2FzZSBmb3IgUmVtaXggSE1SIHdoZXJlIHRoZSByb3V0ZSB0cmVlIGNhbiBjaGFuZ2VcbiAgICAvLyBhdCBydW50aW1lIGFuZCByZW1vdmUgYSByb3V0ZSBwcmV2aW91c2x5IGxvYWRlZCB2aWEgYSBmZXRjaGVyXG4gICAgaWYgKCFmZXRjaGVyTWF0Y2hlcykge1xuICAgICAgcmV2YWxpZGF0aW5nRmV0Y2hlcnMucHVzaCh7XG4gICAgICAgIGtleSxcbiAgICAgICAgcm91dGVJZDogZi5yb3V0ZUlkLFxuICAgICAgICBwYXRoOiBmLnBhdGgsXG4gICAgICAgIG1hdGNoZXM6IG51bGwsXG4gICAgICAgIG1hdGNoOiBudWxsLFxuICAgICAgICBjb250cm9sbGVyOiBudWxsXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gUmV2YWxpZGF0aW5nIGZldGNoZXJzIGFyZSBkZWNvdXBsZWQgZnJvbSB0aGUgcm91dGUgbWF0Y2hlcyBzaW5jZSB0aGV5XG4gICAgLy8gbG9hZCBmcm9tIGEgc3RhdGljIGhyZWYuICBUaGV5IHJldmFsaWRhdGUgYmFzZWQgb24gZXhwbGljaXQgcmV2YWxpZGF0aW9uXG4gICAgLy8gKHN1Ym1pc3Npb24sIHVzZVJldmFsaWRhdG9yLCBvciBYLVJlbWl4LVJldmFsaWRhdGUpXG4gICAgbGV0IGZldGNoZXIgPSBzdGF0ZS5mZXRjaGVycy5nZXQoa2V5KTtcbiAgICBsZXQgZmV0Y2hlck1hdGNoID0gZ2V0VGFyZ2V0TWF0Y2goZmV0Y2hlck1hdGNoZXMsIGYucGF0aCk7XG4gICAgbGV0IHNob3VsZFJldmFsaWRhdGUgPSBmYWxzZTtcbiAgICBpZiAoZmV0Y2hSZWRpcmVjdElkcy5oYXMoa2V5KSkge1xuICAgICAgLy8gTmV2ZXIgdHJpZ2dlciBhIHJldmFsaWRhdGlvbiBvZiBhbiBhY3RpdmVseSByZWRpcmVjdGluZyBmZXRjaGVyXG4gICAgICBzaG91bGRSZXZhbGlkYXRlID0gZmFsc2U7XG4gICAgfSBlbHNlIGlmIChjYW5jZWxsZWRGZXRjaGVyTG9hZHMuaW5jbHVkZXMoa2V5KSkge1xuICAgICAgLy8gQWx3YXlzIHJldmFsaWRhdGUgaWYgdGhlIGZldGNoZXIgd2FzIGNhbmNlbGxlZFxuICAgICAgc2hvdWxkUmV2YWxpZGF0ZSA9IHRydWU7XG4gICAgfSBlbHNlIGlmIChmZXRjaGVyICYmIGZldGNoZXIuc3RhdGUgIT09IFwiaWRsZVwiICYmIGZldGNoZXIuZGF0YSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAvLyBJZiB0aGUgZmV0Y2hlciBoYXNuJ3QgZXZlciBjb21wbGV0ZWQgbG9hZGluZyB5ZXQsIHRoZW4gdGhpcyBpc24ndCBhXG4gICAgICAvLyByZXZhbGlkYXRpb24sIGl0IHdvdWxkIGp1c3QgYmUgYSBicmFuZCBuZXcgbG9hZCBpZiBhbiBleHBsaWNpdFxuICAgICAgLy8gcmV2YWxpZGF0aW9uIGlzIHJlcXVpcmVkXG4gICAgICBzaG91bGRSZXZhbGlkYXRlID0gaXNSZXZhbGlkYXRpb25SZXF1aXJlZDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gT3RoZXJ3aXNlIGZhbGwgYmFjayBvbiBhbnkgdXNlci1kZWZpbmVkIHNob3VsZFJldmFsaWRhdGUsIGRlZmF1bHRpbmdcbiAgICAgIC8vIHRvIGV4cGxpY2l0IHJldmFsaWRhdGlvbnMgb25seVxuICAgICAgc2hvdWxkUmV2YWxpZGF0ZSA9IHNob3VsZFJldmFsaWRhdGVMb2FkZXIoZmV0Y2hlck1hdGNoLCBfZXh0ZW5kcyh7XG4gICAgICAgIGN1cnJlbnRVcmwsXG4gICAgICAgIGN1cnJlbnRQYXJhbXM6IHN0YXRlLm1hdGNoZXNbc3RhdGUubWF0Y2hlcy5sZW5ndGggLSAxXS5wYXJhbXMsXG4gICAgICAgIG5leHRVcmwsXG4gICAgICAgIG5leHRQYXJhbXM6IG1hdGNoZXNbbWF0Y2hlcy5sZW5ndGggLSAxXS5wYXJhbXNcbiAgICAgIH0sIHN1Ym1pc3Npb24sIHtcbiAgICAgICAgYWN0aW9uUmVzdWx0LFxuICAgICAgICBkZWZhdWx0U2hvdWxkUmV2YWxpZGF0ZTogaXNSZXZhbGlkYXRpb25SZXF1aXJlZFxuICAgICAgfSkpO1xuICAgIH1cbiAgICBpZiAoc2hvdWxkUmV2YWxpZGF0ZSkge1xuICAgICAgcmV2YWxpZGF0aW5nRmV0Y2hlcnMucHVzaCh7XG4gICAgICAgIGtleSxcbiAgICAgICAgcm91dGVJZDogZi5yb3V0ZUlkLFxuICAgICAgICBwYXRoOiBmLnBhdGgsXG4gICAgICAgIG1hdGNoZXM6IGZldGNoZXJNYXRjaGVzLFxuICAgICAgICBtYXRjaDogZmV0Y2hlck1hdGNoLFxuICAgICAgICBjb250cm9sbGVyOiBuZXcgQWJvcnRDb250cm9sbGVyKClcbiAgICAgIH0pO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBbbmF2aWdhdGlvbk1hdGNoZXMsIHJldmFsaWRhdGluZ0ZldGNoZXJzXTtcbn1cbmZ1bmN0aW9uIGlzTmV3TG9hZGVyKGN1cnJlbnRMb2FkZXJEYXRhLCBjdXJyZW50TWF0Y2gsIG1hdGNoKSB7XG4gIGxldCBpc05ldyA9XG4gIC8vIFthXSAtPiBbYSwgYl1cbiAgIWN1cnJlbnRNYXRjaCB8fFxuICAvLyBbYSwgYl0gLT4gW2EsIGNdXG4gIG1hdGNoLnJvdXRlLmlkICE9PSBjdXJyZW50TWF0Y2gucm91dGUuaWQ7XG4gIC8vIEhhbmRsZSB0aGUgY2FzZSB0aGF0IHdlIGRvbid0IGhhdmUgZGF0YSBmb3IgYSByZS11c2VkIHJvdXRlLCBwb3RlbnRpYWxseVxuICAvLyBmcm9tIGEgcHJpb3IgZXJyb3Igb3IgZnJvbSBhIGNhbmNlbGxlZCBwZW5kaW5nIGRlZmVycmVkXG4gIGxldCBpc01pc3NpbmdEYXRhID0gY3VycmVudExvYWRlckRhdGFbbWF0Y2gucm91dGUuaWRdID09PSB1bmRlZmluZWQ7XG4gIC8vIEFsd2F5cyBsb2FkIGlmIHRoaXMgaXMgYSBuZXQtbmV3IHJvdXRlIG9yIHdlIGRvbid0IHlldCBoYXZlIGRhdGFcbiAgcmV0dXJuIGlzTmV3IHx8IGlzTWlzc2luZ0RhdGE7XG59XG5mdW5jdGlvbiBpc05ld1JvdXRlSW5zdGFuY2UoY3VycmVudE1hdGNoLCBtYXRjaCkge1xuICBsZXQgY3VycmVudFBhdGggPSBjdXJyZW50TWF0Y2gucm91dGUucGF0aDtcbiAgcmV0dXJuIChcbiAgICAvLyBwYXJhbSBjaGFuZ2UgZm9yIHRoaXMgbWF0Y2gsIC91c2Vycy8xMjMgLT4gL3VzZXJzLzQ1NlxuICAgIGN1cnJlbnRNYXRjaC5wYXRobmFtZSAhPT0gbWF0Y2gucGF0aG5hbWUgfHxcbiAgICAvLyBzcGxhdCBwYXJhbSBjaGFuZ2VkLCB3aGljaCBpcyBub3QgcHJlc2VudCBpbiBtYXRjaC5wYXRoXG4gICAgLy8gZS5nLiAvZmlsZXMvaW1hZ2VzL2F2YXRhci5qcGcgLT4gZmlsZXMvZmluYW5jZXMueGxzXG4gICAgY3VycmVudFBhdGggIT0gbnVsbCAmJiBjdXJyZW50UGF0aC5lbmRzV2l0aChcIipcIikgJiYgY3VycmVudE1hdGNoLnBhcmFtc1tcIipcIl0gIT09IG1hdGNoLnBhcmFtc1tcIipcIl1cbiAgKTtcbn1cbmZ1bmN0aW9uIHNob3VsZFJldmFsaWRhdGVMb2FkZXIobG9hZGVyTWF0Y2gsIGFyZykge1xuICBpZiAobG9hZGVyTWF0Y2gucm91dGUuc2hvdWxkUmV2YWxpZGF0ZSkge1xuICAgIGxldCByb3V0ZUNob2ljZSA9IGxvYWRlck1hdGNoLnJvdXRlLnNob3VsZFJldmFsaWRhdGUoYXJnKTtcbiAgICBpZiAodHlwZW9mIHJvdXRlQ2hvaWNlID09PSBcImJvb2xlYW5cIikge1xuICAgICAgcmV0dXJuIHJvdXRlQ2hvaWNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gYXJnLmRlZmF1bHRTaG91bGRSZXZhbGlkYXRlO1xufVxuLyoqXG4gKiBFeGVjdXRlIHJvdXRlLmxhenkoKSBtZXRob2RzIHRvIGxhemlseSBsb2FkIHJvdXRlIG1vZHVsZXMgKGxvYWRlciwgYWN0aW9uLFxuICogc2hvdWxkUmV2YWxpZGF0ZSkgYW5kIHVwZGF0ZSB0aGUgcm91dGVNYW5pZmVzdCBpbiBwbGFjZSB3aGljaCBzaGFyZXMgb2JqZWN0c1xuICogd2l0aCBkYXRhUm91dGVzIHNvIHRob3NlIGdldCB1cGRhdGVkIGFzIHdlbGwuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGxvYWRMYXp5Um91dGVNb2R1bGUocm91dGUsIG1hcFJvdXRlUHJvcGVydGllcywgbWFuaWZlc3QpIHtcbiAgaWYgKCFyb3V0ZS5sYXp5KSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGxldCBsYXp5Um91dGUgPSBhd2FpdCByb3V0ZS5sYXp5KCk7XG4gIC8vIElmIHRoZSBsYXp5IHJvdXRlIGZ1bmN0aW9uIHdhcyBleGVjdXRlZCBhbmQgcmVtb3ZlZCBieSBhbm90aGVyIHBhcmFsbGVsXG4gIC8vIGNhbGwgdGhlbiB3ZSBjYW4gcmV0dXJuIC0gZmlyc3QgbGF6eSgpIHRvIGZpbmlzaCB3aW5zIGJlY2F1c2UgdGhlIHJldHVyblxuICAvLyB2YWx1ZSBvZiBsYXp5IGlzIGV4cGVjdGVkIHRvIGJlIHN0YXRpY1xuICBpZiAoIXJvdXRlLmxhenkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgbGV0IHJvdXRlVG9VcGRhdGUgPSBtYW5pZmVzdFtyb3V0ZS5pZF07XG4gIGludmFyaWFudChyb3V0ZVRvVXBkYXRlLCBcIk5vIHJvdXRlIGZvdW5kIGluIG1hbmlmZXN0XCIpO1xuICAvLyBVcGRhdGUgdGhlIHJvdXRlIGluIHBsYWNlLiAgVGhpcyBzaG91bGQgYmUgc2FmZSBiZWNhdXNlIHRoZXJlJ3Mgbm8gd2F5XG4gIC8vIHdlIGNvdWxkIHlldCBiZSBzaXR0aW5nIG9uIHRoaXMgcm91dGUgYXMgd2UgY2FuJ3QgZ2V0IHRoZXJlIHdpdGhvdXRcbiAgLy8gcmVzb2x2aW5nIGxhenkoKSBmaXJzdC5cbiAgLy9cbiAgLy8gVGhpcyBpcyBkaWZmZXJlbnQgdGhhbiB0aGUgSE1SIFwidXBkYXRlXCIgdXNlLWNhc2Ugd2hlcmUgd2UgbWF5IGFjdGl2ZWx5IGJlXG4gIC8vIG9uIHRoZSByb3V0ZSBiZWluZyB1cGRhdGVkLiAgVGhlIG1haW4gY29uY2VybiBib2lscyBkb3duIHRvIFwiZG9lcyB0aGlzXG4gIC8vIG11dGF0aW9uIGFmZmVjdCBhbnkgb25nb2luZyBuYXZpZ2F0aW9ucyBvciBhbnkgY3VycmVudCBzdGF0ZS5tYXRjaGVzXG4gIC8vIHZhbHVlcz9cIi4gIElmIG5vdCwgaXQgc2hvdWxkIGJlIHNhZmUgdG8gdXBkYXRlIGluIHBsYWNlLlxuICBsZXQgcm91dGVVcGRhdGVzID0ge307XG4gIGZvciAobGV0IGxhenlSb3V0ZVByb3BlcnR5IGluIGxhenlSb3V0ZSkge1xuICAgIGxldCBzdGF0aWNSb3V0ZVZhbHVlID0gcm91dGVUb1VwZGF0ZVtsYXp5Um91dGVQcm9wZXJ0eV07XG4gICAgbGV0IGlzUHJvcGVydHlTdGF0aWNhbGx5RGVmaW5lZCA9IHN0YXRpY1JvdXRlVmFsdWUgIT09IHVuZGVmaW5lZCAmJlxuICAgIC8vIFRoaXMgcHJvcGVydHkgaXNuJ3Qgc3RhdGljIHNpbmNlIGl0IHNob3VsZCBhbHdheXMgYmUgdXBkYXRlZCBiYXNlZFxuICAgIC8vIG9uIHRoZSByb3V0ZSB1cGRhdGVzXG4gICAgbGF6eVJvdXRlUHJvcGVydHkgIT09IFwiaGFzRXJyb3JCb3VuZGFyeVwiO1xuICAgIHdhcm5pbmcoIWlzUHJvcGVydHlTdGF0aWNhbGx5RGVmaW5lZCwgXCJSb3V0ZSBcXFwiXCIgKyByb3V0ZVRvVXBkYXRlLmlkICsgXCJcXFwiIGhhcyBhIHN0YXRpYyBwcm9wZXJ0eSBcXFwiXCIgKyBsYXp5Um91dGVQcm9wZXJ0eSArIFwiXFxcIiBcIiArIFwiZGVmaW5lZCBidXQgaXRzIGxhenkgZnVuY3Rpb24gaXMgYWxzbyByZXR1cm5pbmcgYSB2YWx1ZSBmb3IgdGhpcyBwcm9wZXJ0eS4gXCIgKyAoXCJUaGUgbGF6eSByb3V0ZSBwcm9wZXJ0eSBcXFwiXCIgKyBsYXp5Um91dGVQcm9wZXJ0eSArIFwiXFxcIiB3aWxsIGJlIGlnbm9yZWQuXCIpKTtcbiAgICBpZiAoIWlzUHJvcGVydHlTdGF0aWNhbGx5RGVmaW5lZCAmJiAhaW1tdXRhYmxlUm91dGVLZXlzLmhhcyhsYXp5Um91dGVQcm9wZXJ0eSkpIHtcbiAgICAgIHJvdXRlVXBkYXRlc1tsYXp5Um91dGVQcm9wZXJ0eV0gPSBsYXp5Um91dGVbbGF6eVJvdXRlUHJvcGVydHldO1xuICAgIH1cbiAgfVxuICAvLyBNdXRhdGUgdGhlIHJvdXRlIHdpdGggdGhlIHByb3ZpZGVkIHVwZGF0ZXMuICBEbyB0aGlzIGZpcnN0IHNvIHdlIHBhc3NcbiAgLy8gdGhlIHVwZGF0ZWQgdmVyc2lvbiB0byBtYXBSb3V0ZVByb3BlcnRpZXNcbiAgT2JqZWN0LmFzc2lnbihyb3V0ZVRvVXBkYXRlLCByb3V0ZVVwZGF0ZXMpO1xuICAvLyBNdXRhdGUgdGhlIGBoYXNFcnJvckJvdW5kYXJ5YCBwcm9wZXJ0eSBvbiB0aGUgcm91dGUgYmFzZWQgb24gdGhlIHJvdXRlXG4gIC8vIHVwZGF0ZXMgYW5kIHJlbW92ZSB0aGUgYGxhenlgIGZ1bmN0aW9uIHNvIHdlIGRvbid0IHJlc29sdmUgdGhlIGxhenlcbiAgLy8gcm91dGUgYWdhaW4uXG4gIE9iamVjdC5hc3NpZ24ocm91dGVUb1VwZGF0ZSwgX2V4dGVuZHMoe30sIG1hcFJvdXRlUHJvcGVydGllcyhyb3V0ZVRvVXBkYXRlKSwge1xuICAgIGxhenk6IHVuZGVmaW5lZFxuICB9KSk7XG59XG5hc3luYyBmdW5jdGlvbiBjYWxsTG9hZGVyT3JBY3Rpb24odHlwZSwgcmVxdWVzdCwgbWF0Y2gsIG1hdGNoZXMsIG1hbmlmZXN0LCBtYXBSb3V0ZVByb3BlcnRpZXMsIGJhc2VuYW1lLCBvcHRzKSB7XG4gIGlmIChvcHRzID09PSB2b2lkIDApIHtcbiAgICBvcHRzID0ge307XG4gIH1cbiAgbGV0IHJlc3VsdFR5cGU7XG4gIGxldCByZXN1bHQ7XG4gIGxldCBvblJlamVjdDtcbiAgbGV0IHJ1bkhhbmRsZXIgPSBoYW5kbGVyID0+IHtcbiAgICAvLyBTZXR1cCBhIHByb21pc2Ugd2UgY2FuIHJhY2UgYWdhaW5zdCBzbyB0aGF0IGFib3J0IHNpZ25hbHMgc2hvcnQgY2lyY3VpdFxuICAgIGxldCByZWplY3Q7XG4gICAgbGV0IGFib3J0UHJvbWlzZSA9IG5ldyBQcm9taXNlKChfLCByKSA9PiByZWplY3QgPSByKTtcbiAgICBvblJlamVjdCA9ICgpID0+IHJlamVjdCgpO1xuICAgIHJlcXVlc3Quc2lnbmFsLmFkZEV2ZW50TGlzdGVuZXIoXCJhYm9ydFwiLCBvblJlamVjdCk7XG4gICAgcmV0dXJuIFByb21pc2UucmFjZShbaGFuZGxlcih7XG4gICAgICByZXF1ZXN0LFxuICAgICAgcGFyYW1zOiBtYXRjaC5wYXJhbXMsXG4gICAgICBjb250ZXh0OiBvcHRzLnJlcXVlc3RDb250ZXh0XG4gICAgfSksIGFib3J0UHJvbWlzZV0pO1xuICB9O1xuICB0cnkge1xuICAgIGxldCBoYW5kbGVyID0gbWF0Y2gucm91dGVbdHlwZV07XG4gICAgaWYgKG1hdGNoLnJvdXRlLmxhenkpIHtcbiAgICAgIGlmIChoYW5kbGVyKSB7XG4gICAgICAgIC8vIFJ1biBzdGF0aWNhbGx5IGRlZmluZWQgaGFuZGxlciBpbiBwYXJhbGxlbCB3aXRoIGxhenkoKVxuICAgICAgICBsZXQgdmFsdWVzID0gYXdhaXQgUHJvbWlzZS5hbGwoW3J1bkhhbmRsZXIoaGFuZGxlciksIGxvYWRMYXp5Um91dGVNb2R1bGUobWF0Y2gucm91dGUsIG1hcFJvdXRlUHJvcGVydGllcywgbWFuaWZlc3QpXSk7XG4gICAgICAgIHJlc3VsdCA9IHZhbHVlc1swXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIExvYWQgbGF6eSByb3V0ZSBtb2R1bGUsIHRoZW4gcnVuIGFueSByZXR1cm5lZCBoYW5kbGVyXG4gICAgICAgIGF3YWl0IGxvYWRMYXp5Um91dGVNb2R1bGUobWF0Y2gucm91dGUsIG1hcFJvdXRlUHJvcGVydGllcywgbWFuaWZlc3QpO1xuICAgICAgICBoYW5kbGVyID0gbWF0Y2gucm91dGVbdHlwZV07XG4gICAgICAgIGlmIChoYW5kbGVyKSB7XG4gICAgICAgICAgLy8gSGFuZGxlciBzdGlsbCBydW4gZXZlbiBpZiB3ZSBnb3QgaW50ZXJydXB0ZWQgdG8gbWFpbnRhaW4gY29uc2lzdGVuY3lcbiAgICAgICAgICAvLyB3aXRoIHVuLWFib3J0YWJsZSBiZWhhdmlvciBvZiBoYW5kbGVyIGV4ZWN1dGlvbiBvbiBub24tbGF6eSBvclxuICAgICAgICAgIC8vIHByZXZpb3VzbHktbGF6eS1sb2FkZWQgcm91dGVzXG4gICAgICAgICAgcmVzdWx0ID0gYXdhaXQgcnVuSGFuZGxlcihoYW5kbGVyKTtcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBcImFjdGlvblwiKSB7XG4gICAgICAgICAgbGV0IHVybCA9IG5ldyBVUkwocmVxdWVzdC51cmwpO1xuICAgICAgICAgIGxldCBwYXRobmFtZSA9IHVybC5wYXRobmFtZSArIHVybC5zZWFyY2g7XG4gICAgICAgICAgdGhyb3cgZ2V0SW50ZXJuYWxSb3V0ZXJFcnJvcig0MDUsIHtcbiAgICAgICAgICAgIG1ldGhvZDogcmVxdWVzdC5tZXRob2QsXG4gICAgICAgICAgICBwYXRobmFtZSxcbiAgICAgICAgICAgIHJvdXRlSWQ6IG1hdGNoLnJvdXRlLmlkXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gbGF6eSgpIHJvdXRlIGhhcyBubyBsb2FkZXIgdG8gcnVuLiAgU2hvcnQgY2lyY3VpdCBoZXJlIHNvIHdlIGRvbid0XG4gICAgICAgICAgLy8gaGl0IHRoZSBpbnZhcmlhbnQgYmVsb3cgdGhhdCBlcnJvcnMgb24gcmV0dXJuaW5nIHVuZGVmaW5lZC5cbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdHlwZTogUmVzdWx0VHlwZS5kYXRhLFxuICAgICAgICAgICAgZGF0YTogdW5kZWZpbmVkXG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIWhhbmRsZXIpIHtcbiAgICAgIGxldCB1cmwgPSBuZXcgVVJMKHJlcXVlc3QudXJsKTtcbiAgICAgIGxldCBwYXRobmFtZSA9IHVybC5wYXRobmFtZSArIHVybC5zZWFyY2g7XG4gICAgICB0aHJvdyBnZXRJbnRlcm5hbFJvdXRlckVycm9yKDQwNCwge1xuICAgICAgICBwYXRobmFtZVxuICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc3VsdCA9IGF3YWl0IHJ1bkhhbmRsZXIoaGFuZGxlcik7XG4gICAgfVxuICAgIGludmFyaWFudChyZXN1bHQgIT09IHVuZGVmaW5lZCwgXCJZb3UgZGVmaW5lZCBcIiArICh0eXBlID09PSBcImFjdGlvblwiID8gXCJhbiBhY3Rpb25cIiA6IFwiYSBsb2FkZXJcIikgKyBcIiBmb3Igcm91dGUgXCIgKyAoXCJcXFwiXCIgKyBtYXRjaC5yb3V0ZS5pZCArIFwiXFxcIiBidXQgZGlkbid0IHJldHVybiBhbnl0aGluZyBmcm9tIHlvdXIgYFwiICsgdHlwZSArIFwiYCBcIikgKyBcImZ1bmN0aW9uLiBQbGVhc2UgcmV0dXJuIGEgdmFsdWUgb3IgYG51bGxgLlwiKTtcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJlc3VsdFR5cGUgPSBSZXN1bHRUeXBlLmVycm9yO1xuICAgIHJlc3VsdCA9IGU7XG4gIH0gZmluYWxseSB7XG4gICAgaWYgKG9uUmVqZWN0KSB7XG4gICAgICByZXF1ZXN0LnNpZ25hbC5yZW1vdmVFdmVudExpc3RlbmVyKFwiYWJvcnRcIiwgb25SZWplY3QpO1xuICAgIH1cbiAgfVxuICBpZiAoaXNSZXNwb25zZShyZXN1bHQpKSB7XG4gICAgbGV0IHN0YXR1cyA9IHJlc3VsdC5zdGF0dXM7XG4gICAgLy8gUHJvY2VzcyByZWRpcmVjdHNcbiAgICBpZiAocmVkaXJlY3RTdGF0dXNDb2Rlcy5oYXMoc3RhdHVzKSkge1xuICAgICAgbGV0IGxvY2F0aW9uID0gcmVzdWx0LmhlYWRlcnMuZ2V0KFwiTG9jYXRpb25cIik7XG4gICAgICBpbnZhcmlhbnQobG9jYXRpb24sIFwiUmVkaXJlY3RzIHJldHVybmVkL3Rocm93biBmcm9tIGxvYWRlcnMvYWN0aW9ucyBtdXN0IGhhdmUgYSBMb2NhdGlvbiBoZWFkZXJcIik7XG4gICAgICAvLyBTdXBwb3J0IHJlbGF0aXZlIHJvdXRpbmcgaW4gaW50ZXJuYWwgcmVkaXJlY3RzXG4gICAgICBpZiAoIUFCU09MVVRFX1VSTF9SRUdFWC50ZXN0KGxvY2F0aW9uKSkge1xuICAgICAgICBsb2NhdGlvbiA9IG5vcm1hbGl6ZVRvKG5ldyBVUkwocmVxdWVzdC51cmwpLCBtYXRjaGVzLnNsaWNlKDAsIG1hdGNoZXMuaW5kZXhPZihtYXRjaCkgKyAxKSwgYmFzZW5hbWUsIHRydWUsIGxvY2F0aW9uKTtcbiAgICAgIH0gZWxzZSBpZiAoIW9wdHMuaXNTdGF0aWNSZXF1ZXN0KSB7XG4gICAgICAgIC8vIFN0cmlwIG9mZiB0aGUgcHJvdG9jb2wrb3JpZ2luIGZvciBzYW1lLW9yaWdpbiArIHNhbWUtYmFzZW5hbWUgYWJzb2x1dGVcbiAgICAgICAgLy8gcmVkaXJlY3RzLiBJZiB0aGlzIGlzIGEgc3RhdGljIHJlcXVlc3QsIHdlIGNhbiBsZXQgaXQgZ28gYmFjayB0byB0aGVcbiAgICAgICAgLy8gYnJvd3NlciBhcy1pc1xuICAgICAgICBsZXQgY3VycmVudFVybCA9IG5ldyBVUkwocmVxdWVzdC51cmwpO1xuICAgICAgICBsZXQgdXJsID0gbG9jYXRpb24uc3RhcnRzV2l0aChcIi8vXCIpID8gbmV3IFVSTChjdXJyZW50VXJsLnByb3RvY29sICsgbG9jYXRpb24pIDogbmV3IFVSTChsb2NhdGlvbik7XG4gICAgICAgIGxldCBpc1NhbWVCYXNlbmFtZSA9IHN0cmlwQmFzZW5hbWUodXJsLnBhdGhuYW1lLCBiYXNlbmFtZSkgIT0gbnVsbDtcbiAgICAgICAgaWYgKHVybC5vcmlnaW4gPT09IGN1cnJlbnRVcmwub3JpZ2luICYmIGlzU2FtZUJhc2VuYW1lKSB7XG4gICAgICAgICAgbG9jYXRpb24gPSB1cmwucGF0aG5hbWUgKyB1cmwuc2VhcmNoICsgdXJsLmhhc2g7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIERvbid0IHByb2Nlc3MgcmVkaXJlY3RzIGluIHRoZSByb3V0ZXIgZHVyaW5nIHN0YXRpYyByZXF1ZXN0cyByZXF1ZXN0cy5cbiAgICAgIC8vIEluc3RlYWQsIHRocm93IHRoZSBSZXNwb25zZSBhbmQgbGV0IHRoZSBzZXJ2ZXIgaGFuZGxlIGl0IHdpdGggYW4gSFRUUFxuICAgICAgLy8gcmVkaXJlY3QuICBXZSBhbHNvIHVwZGF0ZSB0aGUgTG9jYXRpb24gaGVhZGVyIGluIHBsYWNlIGluIHRoaXMgZmxvdyBzb1xuICAgICAgLy8gYmFzZW5hbWUgYW5kIHJlbGF0aXZlIHJvdXRpbmcgaXMgdGFrZW4gaW50byBhY2NvdW50XG4gICAgICBpZiAob3B0cy5pc1N0YXRpY1JlcXVlc3QpIHtcbiAgICAgICAgcmVzdWx0LmhlYWRlcnMuc2V0KFwiTG9jYXRpb25cIiwgbG9jYXRpb24pO1xuICAgICAgICB0aHJvdyByZXN1bHQ7XG4gICAgICB9XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBSZXN1bHRUeXBlLnJlZGlyZWN0LFxuICAgICAgICBzdGF0dXMsXG4gICAgICAgIGxvY2F0aW9uLFxuICAgICAgICByZXZhbGlkYXRlOiByZXN1bHQuaGVhZGVycy5nZXQoXCJYLVJlbWl4LVJldmFsaWRhdGVcIikgIT09IG51bGwsXG4gICAgICAgIHJlbG9hZERvY3VtZW50OiByZXN1bHQuaGVhZGVycy5nZXQoXCJYLVJlbWl4LVJlbG9hZC1Eb2N1bWVudFwiKSAhPT0gbnVsbFxuICAgICAgfTtcbiAgICB9XG4gICAgLy8gRm9yIFNTUiBzaW5nbGUtcm91dGUgcmVxdWVzdHMsIHdlIHdhbnQgdG8gaGFuZCBSZXNwb25zZXMgYmFjayBkaXJlY3RseVxuICAgIC8vIHdpdGhvdXQgdW53cmFwcGluZy4gIFdlIGRvIHRoaXMgd2l0aCB0aGUgUXVlcnlSb3V0ZVJlc3BvbnNlIHdyYXBwZXJcbiAgICAvLyBpbnRlcmZhY2Ugc28gd2UgY2FuIGtub3cgd2hldGhlciBpdCB3YXMgcmV0dXJuZWQgb3IgdGhyb3duXG4gICAgaWYgKG9wdHMuaXNSb3V0ZVJlcXVlc3QpIHtcbiAgICAgIGxldCBxdWVyeVJvdXRlUmVzcG9uc2UgPSB7XG4gICAgICAgIHR5cGU6IHJlc3VsdFR5cGUgPT09IFJlc3VsdFR5cGUuZXJyb3IgPyBSZXN1bHRUeXBlLmVycm9yIDogUmVzdWx0VHlwZS5kYXRhLFxuICAgICAgICByZXNwb25zZTogcmVzdWx0XG4gICAgICB9O1xuICAgICAgdGhyb3cgcXVlcnlSb3V0ZVJlc3BvbnNlO1xuICAgIH1cbiAgICBsZXQgZGF0YTtcbiAgICBsZXQgY29udGVudFR5cGUgPSByZXN1bHQuaGVhZGVycy5nZXQoXCJDb250ZW50LVR5cGVcIik7XG4gICAgLy8gQ2hlY2sgYmV0d2VlbiB3b3JkIGJvdW5kYXJpZXMgaW5zdGVhZCBvZiBzdGFydHNXaXRoKCkgZHVlIHRvIHRoZSBsYXN0XG4gICAgLy8gcGFyYWdyYXBoIG9mIGh0dHBzOi8vaHR0cHdnLm9yZy9zcGVjcy9yZmM5MTEwLmh0bWwjZmllbGQuY29udGVudC10eXBlXG4gICAgaWYgKGNvbnRlbnRUeXBlICYmIC9cXGJhcHBsaWNhdGlvblxcL2pzb25cXGIvLnRlc3QoY29udGVudFR5cGUpKSB7XG4gICAgICBkYXRhID0gYXdhaXQgcmVzdWx0Lmpzb24oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGF0YSA9IGF3YWl0IHJlc3VsdC50ZXh0KCk7XG4gICAgfVxuICAgIGlmIChyZXN1bHRUeXBlID09PSBSZXN1bHRUeXBlLmVycm9yKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiByZXN1bHRUeXBlLFxuICAgICAgICBlcnJvcjogbmV3IEVycm9yUmVzcG9uc2Uoc3RhdHVzLCByZXN1bHQuc3RhdHVzVGV4dCwgZGF0YSksXG4gICAgICAgIGhlYWRlcnM6IHJlc3VsdC5oZWFkZXJzXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogUmVzdWx0VHlwZS5kYXRhLFxuICAgICAgZGF0YSxcbiAgICAgIHN0YXR1c0NvZGU6IHJlc3VsdC5zdGF0dXMsXG4gICAgICBoZWFkZXJzOiByZXN1bHQuaGVhZGVyc1xuICAgIH07XG4gIH1cbiAgaWYgKHJlc3VsdFR5cGUgPT09IFJlc3VsdFR5cGUuZXJyb3IpIHtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogcmVzdWx0VHlwZSxcbiAgICAgIGVycm9yOiByZXN1bHRcbiAgICB9O1xuICB9XG4gIGlmIChpc0RlZmVycmVkRGF0YShyZXN1bHQpKSB7XG4gICAgdmFyIF9yZXN1bHQkaW5pdCwgX3Jlc3VsdCRpbml0MjtcbiAgICByZXR1cm4ge1xuICAgICAgdHlwZTogUmVzdWx0VHlwZS5kZWZlcnJlZCxcbiAgICAgIGRlZmVycmVkRGF0YTogcmVzdWx0LFxuICAgICAgc3RhdHVzQ29kZTogKF9yZXN1bHQkaW5pdCA9IHJlc3VsdC5pbml0KSA9PSBudWxsID8gdm9pZCAwIDogX3Jlc3VsdCRpbml0LnN0YXR1cyxcbiAgICAgIGhlYWRlcnM6ICgoX3Jlc3VsdCRpbml0MiA9IHJlc3VsdC5pbml0KSA9PSBudWxsID8gdm9pZCAwIDogX3Jlc3VsdCRpbml0Mi5oZWFkZXJzKSAmJiBuZXcgSGVhZGVycyhyZXN1bHQuaW5pdC5oZWFkZXJzKVxuICAgIH07XG4gIH1cbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBSZXN1bHRUeXBlLmRhdGEsXG4gICAgZGF0YTogcmVzdWx0XG4gIH07XG59XG4vLyBVdGlsaXR5IG1ldGhvZCBmb3IgY3JlYXRpbmcgdGhlIFJlcXVlc3QgaW5zdGFuY2VzIGZvciBsb2FkZXJzL2FjdGlvbnMgZHVyaW5nXG4vLyBjbGllbnQtc2lkZSBuYXZpZ2F0aW9ucyBhbmQgZmV0Y2hlcy4gIER1cmluZyBTU1Igd2Ugd2lsbCBhbHdheXMgaGF2ZSBhXG4vLyBSZXF1ZXN0IGluc3RhbmNlIGZyb20gdGhlIHN0YXRpYyBoYW5kbGVyIChxdWVyeS9xdWVyeVJvdXRlKVxuZnVuY3Rpb24gY3JlYXRlQ2xpZW50U2lkZVJlcXVlc3QoaGlzdG9yeSwgbG9jYXRpb24sIHNpZ25hbCwgc3VibWlzc2lvbikge1xuICBsZXQgdXJsID0gaGlzdG9yeS5jcmVhdGVVUkwoc3RyaXBIYXNoRnJvbVBhdGgobG9jYXRpb24pKS50b1N0cmluZygpO1xuICBsZXQgaW5pdCA9IHtcbiAgICBzaWduYWxcbiAgfTtcbiAgaWYgKHN1Ym1pc3Npb24gJiYgaXNNdXRhdGlvbk1ldGhvZChzdWJtaXNzaW9uLmZvcm1NZXRob2QpKSB7XG4gICAgbGV0IHtcbiAgICAgIGZvcm1NZXRob2QsXG4gICAgICBmb3JtRW5jVHlwZVxuICAgIH0gPSBzdWJtaXNzaW9uO1xuICAgIC8vIERpZG4ndCB0aGluayB3ZSBuZWVkZWQgdGhpcyBidXQgaXQgdHVybnMgb3V0IHVubGlrZSBvdGhlciBtZXRob2RzLCBwYXRjaFxuICAgIC8vIHdvbid0IGJlIHByb3Blcmx5IG5vcm1hbGl6ZWQgdG8gdXBwZXJjYXNlIGFuZCByZXN1bHRzIGluIGEgNDA1IGVycm9yLlxuICAgIC8vIFNlZTogaHR0cHM6Ly9mZXRjaC5zcGVjLndoYXR3Zy5vcmcvI2NvbmNlcHQtbWV0aG9kXG4gICAgaW5pdC5tZXRob2QgPSBmb3JtTWV0aG9kLnRvVXBwZXJDYXNlKCk7XG4gICAgaWYgKGZvcm1FbmNUeXBlID09PSBcImFwcGxpY2F0aW9uL2pzb25cIikge1xuICAgICAgaW5pdC5oZWFkZXJzID0gbmV3IEhlYWRlcnMoe1xuICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBmb3JtRW5jVHlwZVxuICAgICAgfSk7XG4gICAgICBpbml0LmJvZHkgPSBKU09OLnN0cmluZ2lmeShzdWJtaXNzaW9uLmpzb24pO1xuICAgIH0gZWxzZSBpZiAoZm9ybUVuY1R5cGUgPT09IFwidGV4dC9wbGFpblwiKSB7XG4gICAgICAvLyBDb250ZW50LVR5cGUgaXMgaW5mZXJyZWQgKGh0dHBzOi8vZmV0Y2guc3BlYy53aGF0d2cub3JnLyNkb20tcmVxdWVzdClcbiAgICAgIGluaXQuYm9keSA9IHN1Ym1pc3Npb24udGV4dDtcbiAgICB9IGVsc2UgaWYgKGZvcm1FbmNUeXBlID09PSBcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiICYmIHN1Ym1pc3Npb24uZm9ybURhdGEpIHtcbiAgICAgIC8vIENvbnRlbnQtVHlwZSBpcyBpbmZlcnJlZCAoaHR0cHM6Ly9mZXRjaC5zcGVjLndoYXR3Zy5vcmcvI2RvbS1yZXF1ZXN0KVxuICAgICAgaW5pdC5ib2R5ID0gY29udmVydEZvcm1EYXRhVG9TZWFyY2hQYXJhbXMoc3VibWlzc2lvbi5mb3JtRGF0YSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENvbnRlbnQtVHlwZSBpcyBpbmZlcnJlZCAoaHR0cHM6Ly9mZXRjaC5zcGVjLndoYXR3Zy5vcmcvI2RvbS1yZXF1ZXN0KVxuICAgICAgaW5pdC5ib2R5ID0gc3VibWlzc2lvbi5mb3JtRGF0YTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG5ldyBSZXF1ZXN0KHVybCwgaW5pdCk7XG59XG5mdW5jdGlvbiBjb252ZXJ0Rm9ybURhdGFUb1NlYXJjaFBhcmFtcyhmb3JtRGF0YSkge1xuICBsZXQgc2VhcmNoUGFyYW1zID0gbmV3IFVSTFNlYXJjaFBhcmFtcygpO1xuICBmb3IgKGxldCBba2V5LCB2YWx1ZV0gb2YgZm9ybURhdGEuZW50cmllcygpKSB7XG4gICAgLy8gaHR0cHM6Ly9odG1sLnNwZWMud2hhdHdnLm9yZy9tdWx0aXBhZ2UvZm9ybS1jb250cm9sLWluZnJhc3RydWN0dXJlLmh0bWwjY29udmVydGluZy1hbi1lbnRyeS1saXN0LXRvLWEtbGlzdC1vZi1uYW1lLXZhbHVlLXBhaXJzXG4gICAgc2VhcmNoUGFyYW1zLmFwcGVuZChrZXksIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiA/IHZhbHVlIDogdmFsdWUubmFtZSk7XG4gIH1cbiAgcmV0dXJuIHNlYXJjaFBhcmFtcztcbn1cbmZ1bmN0aW9uIGNvbnZlcnRTZWFyY2hQYXJhbXNUb0Zvcm1EYXRhKHNlYXJjaFBhcmFtcykge1xuICBsZXQgZm9ybURhdGEgPSBuZXcgRm9ybURhdGEoKTtcbiAgZm9yIChsZXQgW2tleSwgdmFsdWVdIG9mIHNlYXJjaFBhcmFtcy5lbnRyaWVzKCkpIHtcbiAgICBmb3JtRGF0YS5hcHBlbmQoa2V5LCB2YWx1ZSk7XG4gIH1cbiAgcmV0dXJuIGZvcm1EYXRhO1xufVxuZnVuY3Rpb24gcHJvY2Vzc1JvdXRlTG9hZGVyRGF0YShtYXRjaGVzLCBtYXRjaGVzVG9Mb2FkLCByZXN1bHRzLCBwZW5kaW5nRXJyb3IsIGFjdGl2ZURlZmVycmVkcykge1xuICAvLyBGaWxsIGluIGxvYWRlckRhdGEvZXJyb3JzIGZyb20gb3VyIGxvYWRlcnNcbiAgbGV0IGxvYWRlckRhdGEgPSB7fTtcbiAgbGV0IGVycm9ycyA9IG51bGw7XG4gIGxldCBzdGF0dXNDb2RlO1xuICBsZXQgZm91bmRFcnJvciA9IGZhbHNlO1xuICBsZXQgbG9hZGVySGVhZGVycyA9IHt9O1xuICAvLyBQcm9jZXNzIGxvYWRlciByZXN1bHRzIGludG8gc3RhdGUubG9hZGVyRGF0YS9zdGF0ZS5lcnJvcnNcbiAgcmVzdWx0cy5mb3JFYWNoKChyZXN1bHQsIGluZGV4KSA9PiB7XG4gICAgbGV0IGlkID0gbWF0Y2hlc1RvTG9hZFtpbmRleF0ucm91dGUuaWQ7XG4gICAgaW52YXJpYW50KCFpc1JlZGlyZWN0UmVzdWx0KHJlc3VsdCksIFwiQ2Fubm90IGhhbmRsZSByZWRpcmVjdCByZXN1bHRzIGluIHByb2Nlc3NMb2FkZXJEYXRhXCIpO1xuICAgIGlmIChpc0Vycm9yUmVzdWx0KHJlc3VsdCkpIHtcbiAgICAgIC8vIExvb2sgdXB3YXJkcyBmcm9tIHRoZSBtYXRjaGVkIHJvdXRlIGZvciB0aGUgY2xvc2VzdCBhbmNlc3RvclxuICAgICAgLy8gZXJyb3IgYm91bmRhcnksIGRlZmF1bHRpbmcgdG8gdGhlIHJvb3QgbWF0Y2hcbiAgICAgIGxldCBib3VuZGFyeU1hdGNoID0gZmluZE5lYXJlc3RCb3VuZGFyeShtYXRjaGVzLCBpZCk7XG4gICAgICBsZXQgZXJyb3IgPSByZXN1bHQuZXJyb3I7XG4gICAgICAvLyBJZiB3ZSBoYXZlIGEgcGVuZGluZyBhY3Rpb24gZXJyb3IsIHdlIHJlcG9ydCBpdCBhdCB0aGUgaGlnaGVzdC1yb3V0ZVxuICAgICAgLy8gdGhhdCB0aHJvd3MgYSBsb2FkZXIgZXJyb3IsIGFuZCB0aGVuIGNsZWFyIGl0IG91dCB0byBpbmRpY2F0ZSB0aGF0XG4gICAgICAvLyBpdCB3YXMgY29uc3VtZWRcbiAgICAgIGlmIChwZW5kaW5nRXJyb3IpIHtcbiAgICAgICAgZXJyb3IgPSBPYmplY3QudmFsdWVzKHBlbmRpbmdFcnJvcilbMF07XG4gICAgICAgIHBlbmRpbmdFcnJvciA9IHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIGVycm9ycyA9IGVycm9ycyB8fCB7fTtcbiAgICAgIC8vIFByZWZlciBoaWdoZXIgZXJyb3IgdmFsdWVzIGlmIGxvd2VyIGVycm9ycyBidWJibGUgdG8gdGhlIHNhbWUgYm91bmRhcnlcbiAgICAgIGlmIChlcnJvcnNbYm91bmRhcnlNYXRjaC5yb3V0ZS5pZF0gPT0gbnVsbCkge1xuICAgICAgICBlcnJvcnNbYm91bmRhcnlNYXRjaC5yb3V0ZS5pZF0gPSBlcnJvcjtcbiAgICAgIH1cbiAgICAgIC8vIENsZWFyIG91ciBhbnkgcHJpb3IgbG9hZGVyRGF0YSBmb3IgdGhlIHRocm93aW5nIHJvdXRlXG4gICAgICBsb2FkZXJEYXRhW2lkXSA9IHVuZGVmaW5lZDtcbiAgICAgIC8vIE9uY2Ugd2UgZmluZCBvdXIgZmlyc3QgKGhpZ2hlc3QpIGVycm9yLCB3ZSBzZXQgdGhlIHN0YXR1cyBjb2RlIGFuZFxuICAgICAgLy8gcHJldmVudCBkZWVwZXIgc3RhdHVzIGNvZGVzIGZyb20gb3ZlcnJpZGluZ1xuICAgICAgaWYgKCFmb3VuZEVycm9yKSB7XG4gICAgICAgIGZvdW5kRXJyb3IgPSB0cnVlO1xuICAgICAgICBzdGF0dXNDb2RlID0gaXNSb3V0ZUVycm9yUmVzcG9uc2UocmVzdWx0LmVycm9yKSA/IHJlc3VsdC5lcnJvci5zdGF0dXMgOiA1MDA7XG4gICAgICB9XG4gICAgICBpZiAocmVzdWx0LmhlYWRlcnMpIHtcbiAgICAgICAgbG9hZGVySGVhZGVyc1tpZF0gPSByZXN1bHQuaGVhZGVycztcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGlzRGVmZXJyZWRSZXN1bHQocmVzdWx0KSkge1xuICAgICAgICBhY3RpdmVEZWZlcnJlZHMuc2V0KGlkLCByZXN1bHQuZGVmZXJyZWREYXRhKTtcbiAgICAgICAgbG9hZGVyRGF0YVtpZF0gPSByZXN1bHQuZGVmZXJyZWREYXRhLmRhdGE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsb2FkZXJEYXRhW2lkXSA9IHJlc3VsdC5kYXRhO1xuICAgICAgfVxuICAgICAgLy8gRXJyb3Igc3RhdHVzIGNvZGVzIGFsd2F5cyBvdmVycmlkZSBzdWNjZXNzIHN0YXR1cyBjb2RlcywgYnV0IGlmIGFsbFxuICAgICAgLy8gbG9hZGVycyBhcmUgc3VjY2Vzc2Z1bCB3ZSB0YWtlIHRoZSBkZWVwZXN0IHN0YXR1cyBjb2RlLlxuICAgICAgaWYgKHJlc3VsdC5zdGF0dXNDb2RlICE9IG51bGwgJiYgcmVzdWx0LnN0YXR1c0NvZGUgIT09IDIwMCAmJiAhZm91bmRFcnJvcikge1xuICAgICAgICBzdGF0dXNDb2RlID0gcmVzdWx0LnN0YXR1c0NvZGU7XG4gICAgICB9XG4gICAgICBpZiAocmVzdWx0LmhlYWRlcnMpIHtcbiAgICAgICAgbG9hZGVySGVhZGVyc1tpZF0gPSByZXN1bHQuaGVhZGVycztcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICAvLyBJZiB3ZSBkaWRuJ3QgY29uc3VtZSB0aGUgcGVuZGluZyBhY3Rpb24gZXJyb3IgKGkuZS4sIGFsbCBsb2FkZXJzXG4gIC8vIHJlc29sdmVkKSwgdGhlbiBjb25zdW1lIGl0IGhlcmUuICBBbHNvIGNsZWFyIG91dCBhbnkgbG9hZGVyRGF0YSBmb3IgdGhlXG4gIC8vIHRocm93aW5nIHJvdXRlXG4gIGlmIChwZW5kaW5nRXJyb3IpIHtcbiAgICBlcnJvcnMgPSBwZW5kaW5nRXJyb3I7XG4gICAgbG9hZGVyRGF0YVtPYmplY3Qua2V5cyhwZW5kaW5nRXJyb3IpWzBdXSA9IHVuZGVmaW5lZDtcbiAgfVxuICByZXR1cm4ge1xuICAgIGxvYWRlckRhdGEsXG4gICAgZXJyb3JzLFxuICAgIHN0YXR1c0NvZGU6IHN0YXR1c0NvZGUgfHwgMjAwLFxuICAgIGxvYWRlckhlYWRlcnNcbiAgfTtcbn1cbmZ1bmN0aW9uIHByb2Nlc3NMb2FkZXJEYXRhKHN0YXRlLCBtYXRjaGVzLCBtYXRjaGVzVG9Mb2FkLCByZXN1bHRzLCBwZW5kaW5nRXJyb3IsIHJldmFsaWRhdGluZ0ZldGNoZXJzLCBmZXRjaGVyUmVzdWx0cywgYWN0aXZlRGVmZXJyZWRzKSB7XG4gIGxldCB7XG4gICAgbG9hZGVyRGF0YSxcbiAgICBlcnJvcnNcbiAgfSA9IHByb2Nlc3NSb3V0ZUxvYWRlckRhdGEobWF0Y2hlcywgbWF0Y2hlc1RvTG9hZCwgcmVzdWx0cywgcGVuZGluZ0Vycm9yLCBhY3RpdmVEZWZlcnJlZHMpO1xuICAvLyBQcm9jZXNzIHJlc3VsdHMgZnJvbSBvdXIgcmV2YWxpZGF0aW5nIGZldGNoZXJzXG4gIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCByZXZhbGlkYXRpbmdGZXRjaGVycy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICBsZXQge1xuICAgICAga2V5LFxuICAgICAgbWF0Y2gsXG4gICAgICBjb250cm9sbGVyXG4gICAgfSA9IHJldmFsaWRhdGluZ0ZldGNoZXJzW2luZGV4XTtcbiAgICBpbnZhcmlhbnQoZmV0Y2hlclJlc3VsdHMgIT09IHVuZGVmaW5lZCAmJiBmZXRjaGVyUmVzdWx0c1tpbmRleF0gIT09IHVuZGVmaW5lZCwgXCJEaWQgbm90IGZpbmQgY29ycmVzcG9uZGluZyBmZXRjaGVyIHJlc3VsdFwiKTtcbiAgICBsZXQgcmVzdWx0ID0gZmV0Y2hlclJlc3VsdHNbaW5kZXhdO1xuICAgIC8vIFByb2Nlc3MgZmV0Y2hlciBub24tcmVkaXJlY3QgZXJyb3JzXG4gICAgaWYgKGNvbnRyb2xsZXIgJiYgY29udHJvbGxlci5zaWduYWwuYWJvcnRlZCkge1xuICAgICAgLy8gTm90aGluZyB0byBkbyBmb3IgYWJvcnRlZCBmZXRjaGVyc1xuICAgICAgY29udGludWU7XG4gICAgfSBlbHNlIGlmIChpc0Vycm9yUmVzdWx0KHJlc3VsdCkpIHtcbiAgICAgIGxldCBib3VuZGFyeU1hdGNoID0gZmluZE5lYXJlc3RCb3VuZGFyeShzdGF0ZS5tYXRjaGVzLCBtYXRjaCA9PSBudWxsID8gdm9pZCAwIDogbWF0Y2gucm91dGUuaWQpO1xuICAgICAgaWYgKCEoZXJyb3JzICYmIGVycm9yc1tib3VuZGFyeU1hdGNoLnJvdXRlLmlkXSkpIHtcbiAgICAgICAgZXJyb3JzID0gX2V4dGVuZHMoe30sIGVycm9ycywge1xuICAgICAgICAgIFtib3VuZGFyeU1hdGNoLnJvdXRlLmlkXTogcmVzdWx0LmVycm9yXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgc3RhdGUuZmV0Y2hlcnMuZGVsZXRlKGtleSk7XG4gICAgfSBlbHNlIGlmIChpc1JlZGlyZWN0UmVzdWx0KHJlc3VsdCkpIHtcbiAgICAgIC8vIFNob3VsZCBuZXZlciBnZXQgaGVyZSwgcmVkaXJlY3RzIHNob3VsZCBnZXQgcHJvY2Vzc2VkIGFib3ZlLCBidXQgd2VcbiAgICAgIC8vIGtlZXAgdGhpcyB0byB0eXBlIG5hcnJvdyB0byBhIHN1Y2Nlc3MgcmVzdWx0IGluIHRoZSBlbHNlXG4gICAgICBpbnZhcmlhbnQoZmFsc2UsIFwiVW5oYW5kbGVkIGZldGNoZXIgcmV2YWxpZGF0aW9uIHJlZGlyZWN0XCIpO1xuICAgIH0gZWxzZSBpZiAoaXNEZWZlcnJlZFJlc3VsdChyZXN1bHQpKSB7XG4gICAgICAvLyBTaG91bGQgbmV2ZXIgZ2V0IGhlcmUsIGRlZmVycmVkIGRhdGEgc2hvdWxkIGJlIGF3YWl0ZWQgZm9yIGZldGNoZXJzXG4gICAgICAvLyBpbiByZXNvbHZlRGVmZXJyZWRSZXN1bHRzXG4gICAgICBpbnZhcmlhbnQoZmFsc2UsIFwiVW5oYW5kbGVkIGZldGNoZXIgZGVmZXJyZWQgZGF0YVwiKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IGRvbmVGZXRjaGVyID0gZ2V0RG9uZUZldGNoZXIocmVzdWx0LmRhdGEpO1xuICAgICAgc3RhdGUuZmV0Y2hlcnMuc2V0KGtleSwgZG9uZUZldGNoZXIpO1xuICAgIH1cbiAgfVxuICByZXR1cm4ge1xuICAgIGxvYWRlckRhdGEsXG4gICAgZXJyb3JzXG4gIH07XG59XG5mdW5jdGlvbiBtZXJnZUxvYWRlckRhdGEobG9hZGVyRGF0YSwgbmV3TG9hZGVyRGF0YSwgbWF0Y2hlcywgZXJyb3JzKSB7XG4gIGxldCBtZXJnZWRMb2FkZXJEYXRhID0gX2V4dGVuZHMoe30sIG5ld0xvYWRlckRhdGEpO1xuICBmb3IgKGxldCBtYXRjaCBvZiBtYXRjaGVzKSB7XG4gICAgbGV0IGlkID0gbWF0Y2gucm91dGUuaWQ7XG4gICAgaWYgKG5ld0xvYWRlckRhdGEuaGFzT3duUHJvcGVydHkoaWQpKSB7XG4gICAgICBpZiAobmV3TG9hZGVyRGF0YVtpZF0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBtZXJnZWRMb2FkZXJEYXRhW2lkXSA9IG5ld0xvYWRlckRhdGFbaWRdO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAobG9hZGVyRGF0YVtpZF0gIT09IHVuZGVmaW5lZCAmJiBtYXRjaC5yb3V0ZS5sb2FkZXIpIHtcbiAgICAgIC8vIFByZXNlcnZlIGV4aXN0aW5nIGtleXMgbm90IGluY2x1ZGVkIGluIG5ld0xvYWRlckRhdGEgYW5kIHdoZXJlIGEgbG9hZGVyXG4gICAgICAvLyB3YXNuJ3QgcmVtb3ZlZCBieSBITVJcbiAgICAgIG1lcmdlZExvYWRlckRhdGFbaWRdID0gbG9hZGVyRGF0YVtpZF07XG4gICAgfVxuICAgIGlmIChlcnJvcnMgJiYgZXJyb3JzLmhhc093blByb3BlcnR5KGlkKSkge1xuICAgICAgLy8gRG9uJ3Qga2VlcCBhbnkgbG9hZGVyIGRhdGEgYmVsb3cgdGhlIGJvdW5kYXJ5XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG1lcmdlZExvYWRlckRhdGE7XG59XG4vLyBGaW5kIHRoZSBuZWFyZXN0IGVycm9yIGJvdW5kYXJ5LCBsb29raW5nIHVwd2FyZHMgZnJvbSB0aGUgbGVhZiByb3V0ZSAob3IgdGhlXG4vLyByb3V0ZSBzcGVjaWZpZWQgYnkgcm91dGVJZCkgZm9yIHRoZSBjbG9zZXN0IGFuY2VzdG9yIGVycm9yIGJvdW5kYXJ5LFxuLy8gZGVmYXVsdGluZyB0byB0aGUgcm9vdCBtYXRjaFxuZnVuY3Rpb24gZmluZE5lYXJlc3RCb3VuZGFyeShtYXRjaGVzLCByb3V0ZUlkKSB7XG4gIGxldCBlbGlnaWJsZU1hdGNoZXMgPSByb3V0ZUlkID8gbWF0Y2hlcy5zbGljZSgwLCBtYXRjaGVzLmZpbmRJbmRleChtID0+IG0ucm91dGUuaWQgPT09IHJvdXRlSWQpICsgMSkgOiBbLi4ubWF0Y2hlc107XG4gIHJldHVybiBlbGlnaWJsZU1hdGNoZXMucmV2ZXJzZSgpLmZpbmQobSA9PiBtLnJvdXRlLmhhc0Vycm9yQm91bmRhcnkgPT09IHRydWUpIHx8IG1hdGNoZXNbMF07XG59XG5mdW5jdGlvbiBnZXRTaG9ydENpcmN1aXRNYXRjaGVzKHJvdXRlcykge1xuICAvLyBQcmVmZXIgYSByb290IGxheW91dCByb3V0ZSBpZiBwcmVzZW50LCBvdGhlcndpc2Ugc2hpbSBpbiBhIHJvdXRlIG9iamVjdFxuICBsZXQgcm91dGUgPSByb3V0ZXMuZmluZChyID0+IHIuaW5kZXggfHwgIXIucGF0aCB8fCByLnBhdGggPT09IFwiL1wiKSB8fCB7XG4gICAgaWQ6IFwiX19zaGltLWVycm9yLXJvdXRlX19cIlxuICB9O1xuICByZXR1cm4ge1xuICAgIG1hdGNoZXM6IFt7XG4gICAgICBwYXJhbXM6IHt9LFxuICAgICAgcGF0aG5hbWU6IFwiXCIsXG4gICAgICBwYXRobmFtZUJhc2U6IFwiXCIsXG4gICAgICByb3V0ZVxuICAgIH1dLFxuICAgIHJvdXRlXG4gIH07XG59XG5mdW5jdGlvbiBnZXRJbnRlcm5hbFJvdXRlckVycm9yKHN0YXR1cywgX3RlbXA0KSB7XG4gIGxldCB7XG4gICAgcGF0aG5hbWUsXG4gICAgcm91dGVJZCxcbiAgICBtZXRob2QsXG4gICAgdHlwZVxuICB9ID0gX3RlbXA0ID09PSB2b2lkIDAgPyB7fSA6IF90ZW1wNDtcbiAgbGV0IHN0YXR1c1RleHQgPSBcIlVua25vd24gU2VydmVyIEVycm9yXCI7XG4gIGxldCBlcnJvck1lc3NhZ2UgPSBcIlVua25vd24gQHJlbWl4LXJ1bi9yb3V0ZXIgZXJyb3JcIjtcbiAgaWYgKHN0YXR1cyA9PT0gNDAwKSB7XG4gICAgc3RhdHVzVGV4dCA9IFwiQmFkIFJlcXVlc3RcIjtcbiAgICBpZiAobWV0aG9kICYmIHBhdGhuYW1lICYmIHJvdXRlSWQpIHtcbiAgICAgIGVycm9yTWVzc2FnZSA9IFwiWW91IG1hZGUgYSBcIiArIG1ldGhvZCArIFwiIHJlcXVlc3QgdG8gXFxcIlwiICsgcGF0aG5hbWUgKyBcIlxcXCIgYnV0IFwiICsgKFwiZGlkIG5vdCBwcm92aWRlIGEgYGxvYWRlcmAgZm9yIHJvdXRlIFxcXCJcIiArIHJvdXRlSWQgKyBcIlxcXCIsIFwiKSArIFwic28gdGhlcmUgaXMgbm8gd2F5IHRvIGhhbmRsZSB0aGUgcmVxdWVzdC5cIjtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFwiZGVmZXItYWN0aW9uXCIpIHtcbiAgICAgIGVycm9yTWVzc2FnZSA9IFwiZGVmZXIoKSBpcyBub3Qgc3VwcG9ydGVkIGluIGFjdGlvbnNcIjtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFwiaW52YWxpZC1ib2R5XCIpIHtcbiAgICAgIGVycm9yTWVzc2FnZSA9IFwiVW5hYmxlIHRvIGVuY29kZSBzdWJtaXNzaW9uIGJvZHlcIjtcbiAgICB9XG4gIH0gZWxzZSBpZiAoc3RhdHVzID09PSA0MDMpIHtcbiAgICBzdGF0dXNUZXh0ID0gXCJGb3JiaWRkZW5cIjtcbiAgICBlcnJvck1lc3NhZ2UgPSBcIlJvdXRlIFxcXCJcIiArIHJvdXRlSWQgKyBcIlxcXCIgZG9lcyBub3QgbWF0Y2ggVVJMIFxcXCJcIiArIHBhdGhuYW1lICsgXCJcXFwiXCI7XG4gIH0gZWxzZSBpZiAoc3RhdHVzID09PSA0MDQpIHtcbiAgICBzdGF0dXNUZXh0ID0gXCJOb3QgRm91bmRcIjtcbiAgICBlcnJvck1lc3NhZ2UgPSBcIk5vIHJvdXRlIG1hdGNoZXMgVVJMIFxcXCJcIiArIHBhdGhuYW1lICsgXCJcXFwiXCI7XG4gIH0gZWxzZSBpZiAoc3RhdHVzID09PSA0MDUpIHtcbiAgICBzdGF0dXNUZXh0ID0gXCJNZXRob2QgTm90IEFsbG93ZWRcIjtcbiAgICBpZiAobWV0aG9kICYmIHBhdGhuYW1lICYmIHJvdXRlSWQpIHtcbiAgICAgIGVycm9yTWVzc2FnZSA9IFwiWW91IG1hZGUgYSBcIiArIG1ldGhvZC50b1VwcGVyQ2FzZSgpICsgXCIgcmVxdWVzdCB0byBcXFwiXCIgKyBwYXRobmFtZSArIFwiXFxcIiBidXQgXCIgKyAoXCJkaWQgbm90IHByb3ZpZGUgYW4gYGFjdGlvbmAgZm9yIHJvdXRlIFxcXCJcIiArIHJvdXRlSWQgKyBcIlxcXCIsIFwiKSArIFwic28gdGhlcmUgaXMgbm8gd2F5IHRvIGhhbmRsZSB0aGUgcmVxdWVzdC5cIjtcbiAgICB9IGVsc2UgaWYgKG1ldGhvZCkge1xuICAgICAgZXJyb3JNZXNzYWdlID0gXCJJbnZhbGlkIHJlcXVlc3QgbWV0aG9kIFxcXCJcIiArIG1ldGhvZC50b1VwcGVyQ2FzZSgpICsgXCJcXFwiXCI7XG4gICAgfVxuICB9XG4gIHJldHVybiBuZXcgRXJyb3JSZXNwb25zZShzdGF0dXMgfHwgNTAwLCBzdGF0dXNUZXh0LCBuZXcgRXJyb3IoZXJyb3JNZXNzYWdlKSwgdHJ1ZSk7XG59XG4vLyBGaW5kIGFueSByZXR1cm5lZCByZWRpcmVjdCBlcnJvcnMsIHN0YXJ0aW5nIGZyb20gdGhlIGxvd2VzdCBtYXRjaFxuZnVuY3Rpb24gZmluZFJlZGlyZWN0KHJlc3VsdHMpIHtcbiAgZm9yIChsZXQgaSA9IHJlc3VsdHMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBsZXQgcmVzdWx0ID0gcmVzdWx0c1tpXTtcbiAgICBpZiAoaXNSZWRpcmVjdFJlc3VsdChyZXN1bHQpKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICByZXN1bHQsXG4gICAgICAgIGlkeDogaVxuICAgICAgfTtcbiAgICB9XG4gIH1cbn1cbmZ1bmN0aW9uIHN0cmlwSGFzaEZyb21QYXRoKHBhdGgpIHtcbiAgbGV0IHBhcnNlZFBhdGggPSB0eXBlb2YgcGF0aCA9PT0gXCJzdHJpbmdcIiA/IHBhcnNlUGF0aChwYXRoKSA6IHBhdGg7XG4gIHJldHVybiBjcmVhdGVQYXRoKF9leHRlbmRzKHt9LCBwYXJzZWRQYXRoLCB7XG4gICAgaGFzaDogXCJcIlxuICB9KSk7XG59XG5mdW5jdGlvbiBpc0hhc2hDaGFuZ2VPbmx5KGEsIGIpIHtcbiAgaWYgKGEucGF0aG5hbWUgIT09IGIucGF0aG5hbWUgfHwgYS5zZWFyY2ggIT09IGIuc2VhcmNoKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmIChhLmhhc2ggPT09IFwiXCIpIHtcbiAgICAvLyAvcGFnZSAtPiAvcGFnZSNoYXNoXG4gICAgcmV0dXJuIGIuaGFzaCAhPT0gXCJcIjtcbiAgfSBlbHNlIGlmIChhLmhhc2ggPT09IGIuaGFzaCkge1xuICAgIC8vIC9wYWdlI2hhc2ggLT4gL3BhZ2UjaGFzaFxuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2UgaWYgKGIuaGFzaCAhPT0gXCJcIikge1xuICAgIC8vIC9wYWdlI2hhc2ggLT4gL3BhZ2Ujb3RoZXJcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICAvLyBJZiB0aGUgaGFzaCBpcyByZW1vdmVkIHRoZSBicm93c2VyIHdpbGwgcmUtcGVyZm9ybSBhIHJlcXVlc3QgdG8gdGhlIHNlcnZlclxuICAvLyAvcGFnZSNoYXNoIC0+IC9wYWdlXG4gIHJldHVybiBmYWxzZTtcbn1cbmZ1bmN0aW9uIGlzRGVmZXJyZWRSZXN1bHQocmVzdWx0KSB7XG4gIHJldHVybiByZXN1bHQudHlwZSA9PT0gUmVzdWx0VHlwZS5kZWZlcnJlZDtcbn1cbmZ1bmN0aW9uIGlzRXJyb3JSZXN1bHQocmVzdWx0KSB7XG4gIHJldHVybiByZXN1bHQudHlwZSA9PT0gUmVzdWx0VHlwZS5lcnJvcjtcbn1cbmZ1bmN0aW9uIGlzUmVkaXJlY3RSZXN1bHQocmVzdWx0KSB7XG4gIHJldHVybiAocmVzdWx0ICYmIHJlc3VsdC50eXBlKSA9PT0gUmVzdWx0VHlwZS5yZWRpcmVjdDtcbn1cbmZ1bmN0aW9uIGlzRGVmZXJyZWREYXRhKHZhbHVlKSB7XG4gIGxldCBkZWZlcnJlZCA9IHZhbHVlO1xuICByZXR1cm4gZGVmZXJyZWQgJiYgdHlwZW9mIGRlZmVycmVkID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBkZWZlcnJlZC5kYXRhID09PSBcIm9iamVjdFwiICYmIHR5cGVvZiBkZWZlcnJlZC5zdWJzY3JpYmUgPT09IFwiZnVuY3Rpb25cIiAmJiB0eXBlb2YgZGVmZXJyZWQuY2FuY2VsID09PSBcImZ1bmN0aW9uXCIgJiYgdHlwZW9mIGRlZmVycmVkLnJlc29sdmVEYXRhID09PSBcImZ1bmN0aW9uXCI7XG59XG5mdW5jdGlvbiBpc1Jlc3BvbnNlKHZhbHVlKSB7XG4gIHJldHVybiB2YWx1ZSAhPSBudWxsICYmIHR5cGVvZiB2YWx1ZS5zdGF0dXMgPT09IFwibnVtYmVyXCIgJiYgdHlwZW9mIHZhbHVlLnN0YXR1c1RleHQgPT09IFwic3RyaW5nXCIgJiYgdHlwZW9mIHZhbHVlLmhlYWRlcnMgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHZhbHVlLmJvZHkgIT09IFwidW5kZWZpbmVkXCI7XG59XG5mdW5jdGlvbiBpc1JlZGlyZWN0UmVzcG9uc2UocmVzdWx0KSB7XG4gIGlmICghaXNSZXNwb25zZShyZXN1bHQpKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGxldCBzdGF0dXMgPSByZXN1bHQuc3RhdHVzO1xuICBsZXQgbG9jYXRpb24gPSByZXN1bHQuaGVhZGVycy5nZXQoXCJMb2NhdGlvblwiKTtcbiAgcmV0dXJuIHN0YXR1cyA+PSAzMDAgJiYgc3RhdHVzIDw9IDM5OSAmJiBsb2NhdGlvbiAhPSBudWxsO1xufVxuZnVuY3Rpb24gaXNRdWVyeVJvdXRlUmVzcG9uc2Uob2JqKSB7XG4gIHJldHVybiBvYmogJiYgaXNSZXNwb25zZShvYmoucmVzcG9uc2UpICYmIChvYmoudHlwZSA9PT0gUmVzdWx0VHlwZS5kYXRhIHx8IG9iai50eXBlID09PSBSZXN1bHRUeXBlLmVycm9yKTtcbn1cbmZ1bmN0aW9uIGlzVmFsaWRNZXRob2QobWV0aG9kKSB7XG4gIHJldHVybiB2YWxpZFJlcXVlc3RNZXRob2RzLmhhcyhtZXRob2QudG9Mb3dlckNhc2UoKSk7XG59XG5mdW5jdGlvbiBpc011dGF0aW9uTWV0aG9kKG1ldGhvZCkge1xuICByZXR1cm4gdmFsaWRNdXRhdGlvbk1ldGhvZHMuaGFzKG1ldGhvZC50b0xvd2VyQ2FzZSgpKTtcbn1cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVEZWZlcnJlZFJlc3VsdHMoY3VycmVudE1hdGNoZXMsIG1hdGNoZXNUb0xvYWQsIHJlc3VsdHMsIHNpZ25hbHMsIGlzRmV0Y2hlciwgY3VycmVudExvYWRlckRhdGEpIHtcbiAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IHJlc3VsdHMubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgbGV0IHJlc3VsdCA9IHJlc3VsdHNbaW5kZXhdO1xuICAgIGxldCBtYXRjaCA9IG1hdGNoZXNUb0xvYWRbaW5kZXhdO1xuICAgIC8vIElmIHdlIGRvbid0IGhhdmUgYSBtYXRjaCwgdGhlbiB3ZSBjYW4gaGF2ZSBhIGRlZmVycmVkIHJlc3VsdCB0byBkb1xuICAgIC8vIGFueXRoaW5nIHdpdGguICBUaGlzIGlzIGZvciByZXZhbGlkYXRpbmcgZmV0Y2hlcnMgd2hlcmUgdGhlIHJvdXRlIHdhc1xuICAgIC8vIHJlbW92ZWQgZHVyaW5nIEhNUlxuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBsZXQgY3VycmVudE1hdGNoID0gY3VycmVudE1hdGNoZXMuZmluZChtID0+IG0ucm91dGUuaWQgPT09IG1hdGNoLnJvdXRlLmlkKTtcbiAgICBsZXQgaXNSZXZhbGlkYXRpbmdMb2FkZXIgPSBjdXJyZW50TWF0Y2ggIT0gbnVsbCAmJiAhaXNOZXdSb3V0ZUluc3RhbmNlKGN1cnJlbnRNYXRjaCwgbWF0Y2gpICYmIChjdXJyZW50TG9hZGVyRGF0YSAmJiBjdXJyZW50TG9hZGVyRGF0YVttYXRjaC5yb3V0ZS5pZF0pICE9PSB1bmRlZmluZWQ7XG4gICAgaWYgKGlzRGVmZXJyZWRSZXN1bHQocmVzdWx0KSAmJiAoaXNGZXRjaGVyIHx8IGlzUmV2YWxpZGF0aW5nTG9hZGVyKSkge1xuICAgICAgLy8gTm90ZTogd2UgZG8gbm90IGhhdmUgdG8gdG91Y2ggYWN0aXZlRGVmZXJyZWRzIGhlcmUgc2luY2Ugd2UgcmFjZSB0aGVtXG4gICAgICAvLyBhZ2FpbnN0IHRoZSBzaWduYWwgaW4gcmVzb2x2ZURlZmVycmVkRGF0YSBhbmQgdGhleSdsbCBnZXQgYWJvcnRlZFxuICAgICAgLy8gdGhlcmUgaWYgbmVlZGVkXG4gICAgICBsZXQgc2lnbmFsID0gc2lnbmFsc1tpbmRleF07XG4gICAgICBpbnZhcmlhbnQoc2lnbmFsLCBcIkV4cGVjdGVkIGFuIEFib3J0U2lnbmFsIGZvciByZXZhbGlkYXRpbmcgZmV0Y2hlciBkZWZlcnJlZCByZXN1bHRcIik7XG4gICAgICBhd2FpdCByZXNvbHZlRGVmZXJyZWREYXRhKHJlc3VsdCwgc2lnbmFsLCBpc0ZldGNoZXIpLnRoZW4ocmVzdWx0ID0+IHtcbiAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgIHJlc3VsdHNbaW5kZXhdID0gcmVzdWx0IHx8IHJlc3VsdHNbaW5kZXhdO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cbmFzeW5jIGZ1bmN0aW9uIHJlc29sdmVEZWZlcnJlZERhdGEocmVzdWx0LCBzaWduYWwsIHVud3JhcCkge1xuICBpZiAodW53cmFwID09PSB2b2lkIDApIHtcbiAgICB1bndyYXAgPSBmYWxzZTtcbiAgfVxuICBsZXQgYWJvcnRlZCA9IGF3YWl0IHJlc3VsdC5kZWZlcnJlZERhdGEucmVzb2x2ZURhdGEoc2lnbmFsKTtcbiAgaWYgKGFib3J0ZWQpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHVud3JhcCkge1xuICAgIHRyeSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB0eXBlOiBSZXN1bHRUeXBlLmRhdGEsXG4gICAgICAgIGRhdGE6IHJlc3VsdC5kZWZlcnJlZERhdGEudW53cmFwcGVkRGF0YVxuICAgICAgfTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBIYW5kbGUgYW55IFRyYWNrZWRQcm9taXNlLl9lcnJvciB2YWx1ZXMgZW5jb3VudGVyZWQgd2hpbGUgdW53cmFwcGluZ1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogUmVzdWx0VHlwZS5lcnJvcixcbiAgICAgICAgZXJyb3I6IGVcbiAgICAgIH07XG4gICAgfVxuICB9XG4gIHJldHVybiB7XG4gICAgdHlwZTogUmVzdWx0VHlwZS5kYXRhLFxuICAgIGRhdGE6IHJlc3VsdC5kZWZlcnJlZERhdGEuZGF0YVxuICB9O1xufVxuZnVuY3Rpb24gaGFzTmFrZWRJbmRleFF1ZXJ5KHNlYXJjaCkge1xuICByZXR1cm4gbmV3IFVSTFNlYXJjaFBhcmFtcyhzZWFyY2gpLmdldEFsbChcImluZGV4XCIpLnNvbWUodiA9PiB2ID09PSBcIlwiKTtcbn1cbi8vIE5vdGU6IFRoaXMgc2hvdWxkIG1hdGNoIHRoZSBmb3JtYXQgZXhwb3J0ZWQgYnkgdXNlTWF0Y2hlcywgc28gaWYgeW91IGNoYW5nZVxuLy8gdGhpcyBwbGVhc2UgYWxzbyBjaGFuZ2UgdGhhdCA6KSAgRXZlbnR1YWxseSB3ZSdsbCBEUlkgdGhpcyB1cFxuZnVuY3Rpb24gY3JlYXRlVXNlTWF0Y2hlc01hdGNoKG1hdGNoLCBsb2FkZXJEYXRhKSB7XG4gIGxldCB7XG4gICAgcm91dGUsXG4gICAgcGF0aG5hbWUsXG4gICAgcGFyYW1zXG4gIH0gPSBtYXRjaDtcbiAgcmV0dXJuIHtcbiAgICBpZDogcm91dGUuaWQsXG4gICAgcGF0aG5hbWUsXG4gICAgcGFyYW1zLFxuICAgIGRhdGE6IGxvYWRlckRhdGFbcm91dGUuaWRdLFxuICAgIGhhbmRsZTogcm91dGUuaGFuZGxlXG4gIH07XG59XG5mdW5jdGlvbiBnZXRUYXJnZXRNYXRjaChtYXRjaGVzLCBsb2NhdGlvbikge1xuICBsZXQgc2VhcmNoID0gdHlwZW9mIGxvY2F0aW9uID09PSBcInN0cmluZ1wiID8gcGFyc2VQYXRoKGxvY2F0aW9uKS5zZWFyY2ggOiBsb2NhdGlvbi5zZWFyY2g7XG4gIGlmIChtYXRjaGVzW21hdGNoZXMubGVuZ3RoIC0gMV0ucm91dGUuaW5kZXggJiYgaGFzTmFrZWRJbmRleFF1ZXJ5KHNlYXJjaCB8fCBcIlwiKSkge1xuICAgIC8vIFJldHVybiB0aGUgbGVhZiBpbmRleCByb3V0ZSB3aGVuIGluZGV4IGlzIHByZXNlbnRcbiAgICByZXR1cm4gbWF0Y2hlc1ttYXRjaGVzLmxlbmd0aCAtIDFdO1xuICB9XG4gIC8vIE90aGVyd2lzZSBncmFiIHRoZSBkZWVwZXN0IFwicGF0aCBjb250cmlidXRpbmdcIiBtYXRjaCAoaWdub3JpbmcgaW5kZXggYW5kXG4gIC8vIHBhdGhsZXNzIGxheW91dCByb3V0ZXMpXG4gIGxldCBwYXRoTWF0Y2hlcyA9IGdldFBhdGhDb250cmlidXRpbmdNYXRjaGVzKG1hdGNoZXMpO1xuICByZXR1cm4gcGF0aE1hdGNoZXNbcGF0aE1hdGNoZXMubGVuZ3RoIC0gMV07XG59XG5mdW5jdGlvbiBnZXRTdWJtaXNzaW9uRnJvbU5hdmlnYXRpb24obmF2aWdhdGlvbikge1xuICBsZXQge1xuICAgIGZvcm1NZXRob2QsXG4gICAgZm9ybUFjdGlvbixcbiAgICBmb3JtRW5jVHlwZSxcbiAgICB0ZXh0LFxuICAgIGZvcm1EYXRhLFxuICAgIGpzb25cbiAgfSA9IG5hdmlnYXRpb247XG4gIGlmICghZm9ybU1ldGhvZCB8fCAhZm9ybUFjdGlvbiB8fCAhZm9ybUVuY1R5cGUpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgaWYgKHRleHQgIT0gbnVsbCkge1xuICAgIHJldHVybiB7XG4gICAgICBmb3JtTWV0aG9kLFxuICAgICAgZm9ybUFjdGlvbixcbiAgICAgIGZvcm1FbmNUeXBlLFxuICAgICAgZm9ybURhdGE6IHVuZGVmaW5lZCxcbiAgICAgIGpzb246IHVuZGVmaW5lZCxcbiAgICAgIHRleHRcbiAgICB9O1xuICB9IGVsc2UgaWYgKGZvcm1EYXRhICE9IG51bGwpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZm9ybU1ldGhvZCxcbiAgICAgIGZvcm1BY3Rpb24sXG4gICAgICBmb3JtRW5jVHlwZSxcbiAgICAgIGZvcm1EYXRhLFxuICAgICAganNvbjogdW5kZWZpbmVkLFxuICAgICAgdGV4dDogdW5kZWZpbmVkXG4gICAgfTtcbiAgfSBlbHNlIGlmIChqc29uICE9PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4ge1xuICAgICAgZm9ybU1ldGhvZCxcbiAgICAgIGZvcm1BY3Rpb24sXG4gICAgICBmb3JtRW5jVHlwZSxcbiAgICAgIGZvcm1EYXRhOiB1bmRlZmluZWQsXG4gICAgICBqc29uLFxuICAgICAgdGV4dDogdW5kZWZpbmVkXG4gICAgfTtcbiAgfVxufVxuZnVuY3Rpb24gZ2V0TG9hZGluZ05hdmlnYXRpb24obG9jYXRpb24sIHN1Ym1pc3Npb24pIHtcbiAgaWYgKHN1Ym1pc3Npb24pIHtcbiAgICBsZXQgbmF2aWdhdGlvbiA9IHtcbiAgICAgIHN0YXRlOiBcImxvYWRpbmdcIixcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgZm9ybU1ldGhvZDogc3VibWlzc2lvbi5mb3JtTWV0aG9kLFxuICAgICAgZm9ybUFjdGlvbjogc3VibWlzc2lvbi5mb3JtQWN0aW9uLFxuICAgICAgZm9ybUVuY1R5cGU6IHN1Ym1pc3Npb24uZm9ybUVuY1R5cGUsXG4gICAgICBmb3JtRGF0YTogc3VibWlzc2lvbi5mb3JtRGF0YSxcbiAgICAgIGpzb246IHN1Ym1pc3Npb24uanNvbixcbiAgICAgIHRleHQ6IHN1Ym1pc3Npb24udGV4dFxuICAgIH07XG4gICAgcmV0dXJuIG5hdmlnYXRpb247XG4gIH0gZWxzZSB7XG4gICAgbGV0IG5hdmlnYXRpb24gPSB7XG4gICAgICBzdGF0ZTogXCJsb2FkaW5nXCIsXG4gICAgICBsb2NhdGlvbixcbiAgICAgIGZvcm1NZXRob2Q6IHVuZGVmaW5lZCxcbiAgICAgIGZvcm1BY3Rpb246IHVuZGVmaW5lZCxcbiAgICAgIGZvcm1FbmNUeXBlOiB1bmRlZmluZWQsXG4gICAgICBmb3JtRGF0YTogdW5kZWZpbmVkLFxuICAgICAganNvbjogdW5kZWZpbmVkLFxuICAgICAgdGV4dDogdW5kZWZpbmVkXG4gICAgfTtcbiAgICByZXR1cm4gbmF2aWdhdGlvbjtcbiAgfVxufVxuZnVuY3Rpb24gZ2V0U3VibWl0dGluZ05hdmlnYXRpb24obG9jYXRpb24sIHN1Ym1pc3Npb24pIHtcbiAgbGV0IG5hdmlnYXRpb24gPSB7XG4gICAgc3RhdGU6IFwic3VibWl0dGluZ1wiLFxuICAgIGxvY2F0aW9uLFxuICAgIGZvcm1NZXRob2Q6IHN1Ym1pc3Npb24uZm9ybU1ldGhvZCxcbiAgICBmb3JtQWN0aW9uOiBzdWJtaXNzaW9uLmZvcm1BY3Rpb24sXG4gICAgZm9ybUVuY1R5cGU6IHN1Ym1pc3Npb24uZm9ybUVuY1R5cGUsXG4gICAgZm9ybURhdGE6IHN1Ym1pc3Npb24uZm9ybURhdGEsXG4gICAganNvbjogc3VibWlzc2lvbi5qc29uLFxuICAgIHRleHQ6IHN1Ym1pc3Npb24udGV4dFxuICB9O1xuICByZXR1cm4gbmF2aWdhdGlvbjtcbn1cbmZ1bmN0aW9uIGdldExvYWRpbmdGZXRjaGVyKHN1Ym1pc3Npb24sIGRhdGEpIHtcbiAgaWYgKHN1Ym1pc3Npb24pIHtcbiAgICBsZXQgZmV0Y2hlciA9IHtcbiAgICAgIHN0YXRlOiBcImxvYWRpbmdcIixcbiAgICAgIGZvcm1NZXRob2Q6IHN1Ym1pc3Npb24uZm9ybU1ldGhvZCxcbiAgICAgIGZvcm1BY3Rpb246IHN1Ym1pc3Npb24uZm9ybUFjdGlvbixcbiAgICAgIGZvcm1FbmNUeXBlOiBzdWJtaXNzaW9uLmZvcm1FbmNUeXBlLFxuICAgICAgZm9ybURhdGE6IHN1Ym1pc3Npb24uZm9ybURhdGEsXG4gICAgICBqc29uOiBzdWJtaXNzaW9uLmpzb24sXG4gICAgICB0ZXh0OiBzdWJtaXNzaW9uLnRleHQsXG4gICAgICBkYXRhLFxuICAgICAgXCIgX2hhc0ZldGNoZXJEb25lQW55dGhpbmcgXCI6IHRydWVcbiAgICB9O1xuICAgIHJldHVybiBmZXRjaGVyO1xuICB9IGVsc2Uge1xuICAgIGxldCBmZXRjaGVyID0ge1xuICAgICAgc3RhdGU6IFwibG9hZGluZ1wiLFxuICAgICAgZm9ybU1ldGhvZDogdW5kZWZpbmVkLFxuICAgICAgZm9ybUFjdGlvbjogdW5kZWZpbmVkLFxuICAgICAgZm9ybUVuY1R5cGU6IHVuZGVmaW5lZCxcbiAgICAgIGZvcm1EYXRhOiB1bmRlZmluZWQsXG4gICAgICBqc29uOiB1bmRlZmluZWQsXG4gICAgICB0ZXh0OiB1bmRlZmluZWQsXG4gICAgICBkYXRhLFxuICAgICAgXCIgX2hhc0ZldGNoZXJEb25lQW55dGhpbmcgXCI6IHRydWVcbiAgICB9O1xuICAgIHJldHVybiBmZXRjaGVyO1xuICB9XG59XG5mdW5jdGlvbiBnZXRTdWJtaXR0aW5nRmV0Y2hlcihzdWJtaXNzaW9uLCBleGlzdGluZ0ZldGNoZXIpIHtcbiAgbGV0IGZldGNoZXIgPSB7XG4gICAgc3RhdGU6IFwic3VibWl0dGluZ1wiLFxuICAgIGZvcm1NZXRob2Q6IHN1Ym1pc3Npb24uZm9ybU1ldGhvZCxcbiAgICBmb3JtQWN0aW9uOiBzdWJtaXNzaW9uLmZvcm1BY3Rpb24sXG4gICAgZm9ybUVuY1R5cGU6IHN1Ym1pc3Npb24uZm9ybUVuY1R5cGUsXG4gICAgZm9ybURhdGE6IHN1Ym1pc3Npb24uZm9ybURhdGEsXG4gICAganNvbjogc3VibWlzc2lvbi5qc29uLFxuICAgIHRleHQ6IHN1Ym1pc3Npb24udGV4dCxcbiAgICBkYXRhOiBleGlzdGluZ0ZldGNoZXIgPyBleGlzdGluZ0ZldGNoZXIuZGF0YSA6IHVuZGVmaW5lZCxcbiAgICBcIiBfaGFzRmV0Y2hlckRvbmVBbnl0aGluZyBcIjogdHJ1ZVxuICB9O1xuICByZXR1cm4gZmV0Y2hlcjtcbn1cbmZ1bmN0aW9uIGdldERvbmVGZXRjaGVyKGRhdGEpIHtcbiAgbGV0IGZldGNoZXIgPSB7XG4gICAgc3RhdGU6IFwiaWRsZVwiLFxuICAgIGZvcm1NZXRob2Q6IHVuZGVmaW5lZCxcbiAgICBmb3JtQWN0aW9uOiB1bmRlZmluZWQsXG4gICAgZm9ybUVuY1R5cGU6IHVuZGVmaW5lZCxcbiAgICBmb3JtRGF0YTogdW5kZWZpbmVkLFxuICAgIGpzb246IHVuZGVmaW5lZCxcbiAgICB0ZXh0OiB1bmRlZmluZWQsXG4gICAgZGF0YSxcbiAgICBcIiBfaGFzRmV0Y2hlckRvbmVBbnl0aGluZyBcIjogdHJ1ZVxuICB9O1xuICByZXR1cm4gZmV0Y2hlcjtcbn1cbi8vI2VuZHJlZ2lvblxuXG5leHBvcnQgeyBBYm9ydGVkRGVmZXJyZWRFcnJvciwgQWN0aW9uLCBFcnJvclJlc3BvbnNlLCBJRExFX0JMT0NLRVIsIElETEVfRkVUQ0hFUiwgSURMRV9OQVZJR0FUSU9OLCBVTlNBRkVfREVGRVJSRURfU1lNQk9MLCBEZWZlcnJlZERhdGEgYXMgVU5TQUZFX0RlZmVycmVkRGF0YSwgY29udmVydFJvdXRlc1RvRGF0YVJvdXRlcyBhcyBVTlNBRkVfY29udmVydFJvdXRlc1RvRGF0YVJvdXRlcywgZ2V0UGF0aENvbnRyaWJ1dGluZ01hdGNoZXMgYXMgVU5TQUZFX2dldFBhdGhDb250cmlidXRpbmdNYXRjaGVzLCBpbnZhcmlhbnQgYXMgVU5TQUZFX2ludmFyaWFudCwgd2FybmluZyBhcyBVTlNBRkVfd2FybmluZywgY3JlYXRlQnJvd3Nlckhpc3RvcnksIGNyZWF0ZUhhc2hIaXN0b3J5LCBjcmVhdGVNZW1vcnlIaXN0b3J5LCBjcmVhdGVQYXRoLCBjcmVhdGVSb3V0ZXIsIGNyZWF0ZVN0YXRpY0hhbmRsZXIsIGRlZmVyLCBnZW5lcmF0ZVBhdGgsIGdldFN0YXRpY0NvbnRleHRGcm9tRXJyb3IsIGdldFRvUGF0aG5hbWUsIGlzRGVmZXJyZWREYXRhLCBpc1JvdXRlRXJyb3JSZXNwb25zZSwgam9pblBhdGhzLCBqc29uLCBtYXRjaFBhdGgsIG1hdGNoUm91dGVzLCBub3JtYWxpemVQYXRobmFtZSwgcGFyc2VQYXRoLCByZWRpcmVjdCwgcmVkaXJlY3REb2N1bWVudCwgcmVzb2x2ZVBhdGgsIHJlc29sdmVUbywgc3RyaXBCYXNlbmFtZSB9O1xuLy8jIHNvdXJjZU1hcHBpbmdVUkw9cm91dGVyLmpzLm1hcFxuIl0sIm5hbWVzIjpbIl9leHRlbmRzIiwiT2JqZWN0IiwiYXNzaWduIiwiYmluZCIsInRhcmdldCIsImkiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJzb3VyY2UiLCJrZXkiLCJwcm90b3R5cGUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJhcHBseSIsIkFjdGlvbiIsIlBvcFN0YXRlRXZlbnRUeXBlIiwiY3JlYXRlTWVtb3J5SGlzdG9yeSIsIm9wdGlvbnMiLCJpbml0aWFsRW50cmllcyIsImluaXRpYWxJbmRleCIsInY1Q29tcGF0IiwiZW50cmllcyIsIm1hcCIsImVudHJ5IiwiaW5kZXgiLCJjcmVhdGVNZW1vcnlMb2NhdGlvbiIsInN0YXRlIiwidW5kZWZpbmVkIiwiY2xhbXBJbmRleCIsImFjdGlvbiIsIlBvcCIsImxpc3RlbmVyIiwibiIsIk1hdGgiLCJtaW4iLCJtYXgiLCJnZXRDdXJyZW50TG9jYXRpb24iLCJ0byIsImxvY2F0aW9uIiwiY3JlYXRlTG9jYXRpb24iLCJwYXRobmFtZSIsIndhcm5pbmciLCJjaGFyQXQiLCJKU09OIiwic3RyaW5naWZ5IiwiY3JlYXRlSHJlZiIsImNyZWF0ZVBhdGgiLCJoaXN0b3J5IiwiY3JlYXRlVVJMIiwiVVJMIiwiZW5jb2RlTG9jYXRpb24iLCJwYXRoIiwicGFyc2VQYXRoIiwic2VhcmNoIiwiaGFzaCIsInB1c2giLCJQdXNoIiwibmV4dExvY2F0aW9uIiwic3BsaWNlIiwiZGVsdGEiLCJyZXBsYWNlIiwiUmVwbGFjZSIsImdvIiwibmV4dEluZGV4IiwibGlzdGVuIiwiZm4iLCJjcmVhdGVCcm93c2VySGlzdG9yeSIsImNyZWF0ZUJyb3dzZXJMb2NhdGlvbiIsIndpbmRvdyIsImdsb2JhbEhpc3RvcnkiLCJ1c3IiLCJjcmVhdGVCcm93c2VySHJlZiIsImdldFVybEJhc2VkSGlzdG9yeSIsImNyZWF0ZUhhc2hIaXN0b3J5IiwiY3JlYXRlSGFzaExvY2F0aW9uIiwic3Vic3RyIiwic3RhcnRzV2l0aCIsImNyZWF0ZUhhc2hIcmVmIiwiYmFzZSIsImRvY3VtZW50IiwicXVlcnlTZWxlY3RvciIsImhyZWYiLCJnZXRBdHRyaWJ1dGUiLCJ1cmwiLCJoYXNoSW5kZXgiLCJpbmRleE9mIiwic2xpY2UiLCJ2YWxpZGF0ZUhhc2hMb2NhdGlvbiIsImludmFyaWFudCIsInZhbHVlIiwibWVzc2FnZSIsIkVycm9yIiwiY29uZCIsImNvbnNvbGUiLCJ3YXJuIiwiZSIsImNyZWF0ZUtleSIsInJhbmRvbSIsInRvU3RyaW5nIiwiZ2V0SGlzdG9yeVN0YXRlIiwiaWR4IiwiY3VycmVudCIsIl9yZWYiLCJwYXJzZWRQYXRoIiwic2VhcmNoSW5kZXgiLCJnZXRMb2NhdGlvbiIsInZhbGlkYXRlTG9jYXRpb24iLCJkZWZhdWx0VmlldyIsImdldEluZGV4IiwicmVwbGFjZVN0YXRlIiwiaGFuZGxlUG9wIiwiaGlzdG9yeVN0YXRlIiwicHVzaFN0YXRlIiwiZXJyb3IiLCJET01FeGNlcHRpb24iLCJuYW1lIiwib3JpZ2luIiwiYWRkRXZlbnRMaXN0ZW5lciIsInJlbW92ZUV2ZW50TGlzdGVuZXIiLCJSZXN1bHRUeXBlIiwiaW1tdXRhYmxlUm91dGVLZXlzIiwiU2V0IiwiaXNJbmRleFJvdXRlIiwicm91dGUiLCJjb252ZXJ0Um91dGVzVG9EYXRhUm91dGVzIiwicm91dGVzIiwibWFwUm91dGVQcm9wZXJ0aWVzIiwicGFyZW50UGF0aCIsIm1hbmlmZXN0IiwidHJlZVBhdGgiLCJpZCIsImpvaW4iLCJjaGlsZHJlbiIsImluZGV4Um91dGUiLCJwYXRoT3JMYXlvdXRSb3V0ZSIsIm1hdGNoUm91dGVzIiwibG9jYXRpb25BcmciLCJiYXNlbmFtZSIsInN0cmlwQmFzZW5hbWUiLCJicmFuY2hlcyIsImZsYXR0ZW5Sb3V0ZXMiLCJyYW5rUm91dGVCcmFuY2hlcyIsIm1hdGNoZXMiLCJtYXRjaFJvdXRlQnJhbmNoIiwic2FmZWx5RGVjb2RlVVJJIiwicGFyZW50c01ldGEiLCJmbGF0dGVuUm91dGUiLCJyZWxhdGl2ZVBhdGgiLCJtZXRhIiwiY2FzZVNlbnNpdGl2ZSIsImNoaWxkcmVuSW5kZXgiLCJqb2luUGF0aHMiLCJyb3V0ZXNNZXRhIiwiY29uY2F0Iiwic2NvcmUiLCJjb21wdXRlU2NvcmUiLCJmb3JFYWNoIiwiX3JvdXRlJHBhdGgiLCJpbmNsdWRlcyIsImV4cGxvZGVkIiwiZXhwbG9kZU9wdGlvbmFsU2VnbWVudHMiLCJzZWdtZW50cyIsInNwbGl0IiwiZmlyc3QiLCJyZXN0IiwiaXNPcHRpb25hbCIsImVuZHNXaXRoIiwicmVxdWlyZWQiLCJyZXN0RXhwbG9kZWQiLCJyZXN1bHQiLCJzdWJwYXRoIiwic29ydCIsImEiLCJiIiwiY29tcGFyZUluZGV4ZXMiLCJwYXJhbVJlIiwiZHluYW1pY1NlZ21lbnRWYWx1ZSIsImluZGV4Um91dGVWYWx1ZSIsImVtcHR5U2VnbWVudFZhbHVlIiwic3RhdGljU2VnbWVudFZhbHVlIiwic3BsYXRQZW5hbHR5IiwiaXNTcGxhdCIsInMiLCJpbml0aWFsU2NvcmUiLCJzb21lIiwiZmlsdGVyIiwicmVkdWNlIiwic2VnbWVudCIsInRlc3QiLCJzaWJsaW5ncyIsImV2ZXJ5IiwiYnJhbmNoIiwibWF0Y2hlZFBhcmFtcyIsIm1hdGNoZWRQYXRobmFtZSIsImVuZCIsInJlbWFpbmluZ1BhdGhuYW1lIiwibWF0Y2giLCJtYXRjaFBhdGgiLCJwYXJhbXMiLCJwYXRobmFtZUJhc2UiLCJub3JtYWxpemVQYXRobmFtZSIsImdlbmVyYXRlUGF0aCIsIm9yaWdpbmFsUGF0aCIsInByZWZpeCIsInAiLCJTdHJpbmciLCJhcnJheSIsImlzTGFzdFNlZ21lbnQiLCJzdGFyIiwia2V5TWF0Y2giLCJvcHRpb25hbCIsInBhcmFtIiwicGF0dGVybiIsIm1hdGNoZXIiLCJwYXJhbU5hbWVzIiwiY29tcGlsZVBhdGgiLCJjYXB0dXJlR3JvdXBzIiwibWVtbyIsInBhcmFtTmFtZSIsInNwbGF0VmFsdWUiLCJzYWZlbHlEZWNvZGVVUklDb21wb25lbnQiLCJyZWdleHBTb3VyY2UiLCJfIiwiUmVnRXhwIiwiZGVjb2RlVVJJIiwiZGVjb2RlVVJJQ29tcG9uZW50IiwidG9Mb3dlckNhc2UiLCJzdGFydEluZGV4IiwibmV4dENoYXIiLCJyZXNvbHZlUGF0aCIsImZyb21QYXRobmFtZSIsInRvUGF0aG5hbWUiLCJyZXNvbHZlUGF0aG5hbWUiLCJub3JtYWxpemVTZWFyY2giLCJub3JtYWxpemVIYXNoIiwicmVsYXRpdmVTZWdtZW50cyIsInBvcCIsImdldEludmFsaWRQYXRoRXJyb3IiLCJjaGFyIiwiZmllbGQiLCJkZXN0IiwiZ2V0UGF0aENvbnRyaWJ1dGluZ01hdGNoZXMiLCJyZXNvbHZlVG8iLCJ0b0FyZyIsInJvdXRlUGF0aG5hbWVzIiwibG9jYXRpb25QYXRobmFtZSIsImlzUGF0aFJlbGF0aXZlIiwiaXNFbXB0eVBhdGgiLCJmcm9tIiwicm91dGVQYXRobmFtZUluZGV4IiwidG9TZWdtZW50cyIsInNoaWZ0IiwiaGFzRXhwbGljaXRUcmFpbGluZ1NsYXNoIiwiaGFzQ3VycmVudFRyYWlsaW5nU2xhc2giLCJnZXRUb1BhdGhuYW1lIiwicGF0aHMiLCJqc29uIiwiZGF0YSIsImluaXQiLCJyZXNwb25zZUluaXQiLCJzdGF0dXMiLCJoZWFkZXJzIiwiSGVhZGVycyIsImhhcyIsInNldCIsIlJlc3BvbnNlIiwiQWJvcnRlZERlZmVycmVkRXJyb3IiLCJEZWZlcnJlZERhdGEiLCJjb25zdHJ1Y3RvciIsInBlbmRpbmdLZXlzU2V0Iiwic3Vic2NyaWJlcnMiLCJkZWZlcnJlZEtleXMiLCJBcnJheSIsImlzQXJyYXkiLCJyZWplY3QiLCJhYm9ydFByb21pc2UiLCJQcm9taXNlIiwiciIsImNvbnRyb2xsZXIiLCJBYm9ydENvbnRyb2xsZXIiLCJvbkFib3J0IiwidW5saXN0ZW5BYm9ydFNpZ25hbCIsInNpZ25hbCIsImFjYyIsInRyYWNrUHJvbWlzZSIsImRvbmUiLCJhZGQiLCJwcm9taXNlIiwicmFjZSIsInRoZW4iLCJvblNldHRsZSIsImNhdGNoIiwiZGVmaW5lUHJvcGVydHkiLCJnZXQiLCJhYm9ydGVkIiwiZGVsZXRlIiwidW5kZWZpbmVkRXJyb3IiLCJlbWl0Iiwic2V0dGxlZEtleSIsInN1YnNjcmliZXIiLCJzdWJzY3JpYmUiLCJjYW5jZWwiLCJhYm9ydCIsInYiLCJrIiwicmVzb2x2ZURhdGEiLCJyZXNvbHZlIiwic2l6ZSIsInVud3JhcHBlZERhdGEiLCJfcmVmMiIsInVud3JhcFRyYWNrZWRQcm9taXNlIiwicGVuZGluZ0tleXMiLCJpc1RyYWNrZWRQcm9taXNlIiwiX3RyYWNrZWQiLCJfZXJyb3IiLCJfZGF0YSIsImRlZmVyIiwicmVkaXJlY3QiLCJyZWRpcmVjdERvY3VtZW50IiwicmVzcG9uc2UiLCJFcnJvclJlc3BvbnNlIiwic3RhdHVzVGV4dCIsImludGVybmFsIiwiaXNSb3V0ZUVycm9yUmVzcG9uc2UiLCJ2YWxpZE11dGF0aW9uTWV0aG9kc0FyciIsInZhbGlkTXV0YXRpb25NZXRob2RzIiwidmFsaWRSZXF1ZXN0TWV0aG9kc0FyciIsInZhbGlkUmVxdWVzdE1ldGhvZHMiLCJyZWRpcmVjdFN0YXR1c0NvZGVzIiwicmVkaXJlY3RQcmVzZXJ2ZU1ldGhvZFN0YXR1c0NvZGVzIiwiSURMRV9OQVZJR0FUSU9OIiwiZm9ybU1ldGhvZCIsImZvcm1BY3Rpb24iLCJmb3JtRW5jVHlwZSIsImZvcm1EYXRhIiwidGV4dCIsIklETEVfRkVUQ0hFUiIsIklETEVfQkxPQ0tFUiIsInByb2NlZWQiLCJyZXNldCIsIkFCU09MVVRFX1VSTF9SRUdFWCIsImRlZmF1bHRNYXBSb3V0ZVByb3BlcnRpZXMiLCJoYXNFcnJvckJvdW5kYXJ5IiwiQm9vbGVhbiIsImNyZWF0ZVJvdXRlciIsInJvdXRlcldpbmRvdyIsImlzQnJvd3NlciIsImNyZWF0ZUVsZW1lbnQiLCJpc1NlcnZlciIsImRldGVjdEVycm9yQm91bmRhcnkiLCJkYXRhUm91dGVzIiwiaW5GbGlnaHREYXRhUm91dGVzIiwiZnV0dXJlIiwidjdfbm9ybWFsaXplRm9ybU1ldGhvZCIsInY3X3ByZXBlbmRCYXNlbmFtZSIsInVubGlzdGVuSGlzdG9yeSIsInNhdmVkU2Nyb2xsUG9zaXRpb25zIiwiZ2V0U2Nyb2xsUmVzdG9yYXRpb25LZXkiLCJnZXRTY3JvbGxQb3NpdGlvbiIsImluaXRpYWxTY3JvbGxSZXN0b3JlZCIsImh5ZHJhdGlvbkRhdGEiLCJpbml0aWFsTWF0Y2hlcyIsImluaXRpYWxFcnJvcnMiLCJnZXRJbnRlcm5hbFJvdXRlckVycm9yIiwiZ2V0U2hvcnRDaXJjdWl0TWF0Y2hlcyIsImluaXRpYWxpemVkIiwibSIsImxhenkiLCJsb2FkZXIiLCJyb3V0ZXIiLCJoaXN0b3J5QWN0aW9uIiwibmF2aWdhdGlvbiIsInJlc3RvcmVTY3JvbGxQb3NpdGlvbiIsInByZXZlbnRTY3JvbGxSZXNldCIsInJldmFsaWRhdGlvbiIsImxvYWRlckRhdGEiLCJhY3Rpb25EYXRhIiwiZXJyb3JzIiwiZmV0Y2hlcnMiLCJNYXAiLCJibG9ja2VycyIsInBlbmRpbmdBY3Rpb24iLCJwZW5kaW5nUHJldmVudFNjcm9sbFJlc2V0IiwicGVuZGluZ05hdmlnYXRpb25Db250cm9sbGVyIiwiaXNVbmludGVycnVwdGVkUmV2YWxpZGF0aW9uIiwiaXNSZXZhbGlkYXRpb25SZXF1aXJlZCIsImNhbmNlbGxlZERlZmVycmVkUm91dGVzIiwiY2FuY2VsbGVkRmV0Y2hlckxvYWRzIiwiZmV0Y2hDb250cm9sbGVycyIsImluY3JlbWVudGluZ0xvYWRJZCIsInBlbmRpbmdOYXZpZ2F0aW9uTG9hZElkIiwiZmV0Y2hSZWxvYWRJZHMiLCJmZXRjaFJlZGlyZWN0SWRzIiwiZmV0Y2hMb2FkTWF0Y2hlcyIsImFjdGl2ZURlZmVycmVkcyIsImJsb2NrZXJGdW5jdGlvbnMiLCJpZ25vcmVOZXh0SGlzdG9yeVVwZGF0ZSIsImluaXRpYWxpemUiLCJibG9ja2VyS2V5Iiwic2hvdWxkQmxvY2tOYXZpZ2F0aW9uIiwiY3VycmVudExvY2F0aW9uIiwidXBkYXRlQmxvY2tlciIsInVwZGF0ZVN0YXRlIiwic3RhcnROYXZpZ2F0aW9uIiwiZGlzcG9zZSIsImNsZWFyIiwiZGVsZXRlRmV0Y2hlciIsImRlbGV0ZUJsb2NrZXIiLCJuZXdTdGF0ZSIsImNvbXBsZXRlTmF2aWdhdGlvbiIsIl9sb2NhdGlvbiRzdGF0ZSIsIl9sb2NhdGlvbiRzdGF0ZTIiLCJpc0FjdGlvblJlbG9hZCIsImlzTXV0YXRpb25NZXRob2QiLCJfaXNSZWRpcmVjdCIsImtleXMiLCJtZXJnZUxvYWRlckRhdGEiLCJnZXRTYXZlZFNjcm9sbFBvc2l0aW9uIiwibmF2aWdhdGUiLCJvcHRzIiwibm9ybWFsaXplZFBhdGgiLCJub3JtYWxpemVUbyIsImZyb21Sb3V0ZUlkIiwicmVsYXRpdmUiLCJzdWJtaXNzaW9uIiwibm9ybWFsaXplTmF2aWdhdGVPcHRpb25zIiwidXNlclJlcGxhY2UiLCJwZW5kaW5nRXJyb3IiLCJyZXZhbGlkYXRlIiwiaW50ZXJydXB0QWN0aXZlTG9hZHMiLCJzdGFydFVuaW50ZXJydXB0ZWRSZXZhbGlkYXRpb24iLCJvdmVycmlkZU5hdmlnYXRpb24iLCJzYXZlU2Nyb2xsUG9zaXRpb24iLCJyb3V0ZXNUb1VzZSIsImxvYWRpbmdOYXZpZ2F0aW9uIiwibm90Rm91bmRNYXRjaGVzIiwiY2FuY2VsQWN0aXZlRGVmZXJyZWRzIiwiaXNIYXNoQ2hhbmdlT25seSIsInJlcXVlc3QiLCJjcmVhdGVDbGllbnRTaWRlUmVxdWVzdCIsInBlbmRpbmdBY3Rpb25EYXRhIiwiZmluZE5lYXJlc3RCb3VuZGFyeSIsImFjdGlvbk91dHB1dCIsImhhbmRsZUFjdGlvbiIsInNob3J0Q2lyY3VpdGVkIiwicGVuZGluZ0FjdGlvbkVycm9yIiwiZ2V0TG9hZGluZ05hdmlnYXRpb24iLCJSZXF1ZXN0IiwiaGFuZGxlTG9hZGVycyIsImZldGNoZXJTdWJtaXNzaW9uIiwiZ2V0U3VibWl0dGluZ05hdmlnYXRpb24iLCJhY3Rpb25NYXRjaCIsImdldFRhcmdldE1hdGNoIiwidHlwZSIsIm1ldGhvZCIsInJvdXRlSWQiLCJjYWxsTG9hZGVyT3JBY3Rpb24iLCJpc1JlZGlyZWN0UmVzdWx0Iiwic3RhcnRSZWRpcmVjdE5hdmlnYXRpb24iLCJpc0Vycm9yUmVzdWx0IiwiYm91bmRhcnlNYXRjaCIsImlzRGVmZXJyZWRSZXN1bHQiLCJhY3RpdmVTdWJtaXNzaW9uIiwiZ2V0U3VibWlzc2lvbkZyb21OYXZpZ2F0aW9uIiwibWF0Y2hlc1RvTG9hZCIsInJldmFsaWRhdGluZ0ZldGNoZXJzIiwiZ2V0TWF0Y2hlc1RvTG9hZCIsInVwZGF0ZWRGZXRjaGVycyIsIm1hcmtGZXRjaFJlZGlyZWN0c0RvbmUiLCJyZiIsImZldGNoZXIiLCJyZXZhbGlkYXRpbmdGZXRjaGVyIiwiZ2V0TG9hZGluZ0ZldGNoZXIiLCJhYm9ydEZldGNoZXIiLCJhYm9ydFBlbmRpbmdGZXRjaFJldmFsaWRhdGlvbnMiLCJmIiwicmVzdWx0cyIsImxvYWRlclJlc3VsdHMiLCJmZXRjaGVyUmVzdWx0cyIsImNhbGxMb2FkZXJzQW5kTWF5YmVSZXNvbHZlRGF0YSIsImZpbmRSZWRpcmVjdCIsImZldGNoZXJLZXkiLCJwcm9jZXNzTG9hZGVyRGF0YSIsImRlZmVycmVkRGF0YSIsImRpZEFib3J0RmV0Y2hMb2FkcyIsImFib3J0U3RhbGVGZXRjaExvYWRzIiwic2hvdWxkVXBkYXRlRmV0Y2hlcnMiLCJnZXRGZXRjaGVyIiwiZmV0Y2giLCJzZXRGZXRjaGVyRXJyb3IiLCJoYW5kbGVGZXRjaGVyQWN0aW9uIiwiaGFuZGxlRmV0Y2hlckxvYWRlciIsInJlcXVlc3RNYXRjaGVzIiwiZXhpc3RpbmdGZXRjaGVyIiwiZ2V0U3VibWl0dGluZ0ZldGNoZXIiLCJhYm9ydENvbnRyb2xsZXIiLCJmZXRjaFJlcXVlc3QiLCJvcmlnaW5hdGluZ0xvYWRJZCIsImFjdGlvblJlc3VsdCIsImRvbmVGZXRjaGVyIiwiZ2V0RG9uZUZldGNoZXIiLCJsb2FkaW5nRmV0Y2hlciIsImlzRmV0Y2hBY3Rpb25SZWRpcmVjdCIsInJldmFsaWRhdGlvblJlcXVlc3QiLCJsb2FkSWQiLCJsb2FkRmV0Y2hlciIsInN0YWxlS2V5IiwicmVzb2x2ZURlZmVycmVkRGF0YSIsIl90ZW1wIiwicmVkaXJlY3RMb2NhdGlvbiIsIl9pc0ZldGNoQWN0aW9uUmVkaXJlY3QiLCJpc0RvY3VtZW50UmVsb2FkIiwicmVsb2FkRG9jdW1lbnQiLCJyZWRpcmVjdEhpc3RvcnlBY3Rpb24iLCJjdXJyZW50TWF0Y2hlcyIsImZldGNoZXJzVG9Mb2FkIiwiYWxsIiwicmVzb2x2ZURlZmVycmVkUmVzdWx0cyIsIm1hcmtGZXRjaGVyc0RvbmUiLCJkb25lS2V5cyIsImxhbmRlZElkIiwieWVldGVkS2V5cyIsImdldEJsb2NrZXIiLCJibG9ja2VyIiwibmV3QmxvY2tlciIsImJsb2NrZXJGdW5jdGlvbiIsInByZWRpY2F0ZSIsImNhbmNlbGxlZFJvdXRlSWRzIiwiZGZkIiwiZW5hYmxlU2Nyb2xsUmVzdG9yYXRpb24iLCJwb3NpdGlvbnMiLCJnZXRQb3NpdGlvbiIsImdldEtleSIsInkiLCJnZXRTY3JvbGxLZXkiLCJjcmVhdGVVc2VNYXRjaGVzTWF0Y2giLCJfaW50ZXJuYWxTZXRSb3V0ZXMiLCJuZXdSb3V0ZXMiLCJfaW50ZXJuYWxGZXRjaENvbnRyb2xsZXJzIiwiX2ludGVybmFsQWN0aXZlRGVmZXJyZWRzIiwiVU5TQUZFX0RFRkVSUkVEX1NZTUJPTCIsIlN5bWJvbCIsImNyZWF0ZVN0YXRpY0hhbmRsZXIiLCJxdWVyeSIsIl90ZW1wMiIsInJlcXVlc3RDb250ZXh0IiwiaXNWYWxpZE1ldGhvZCIsIm1ldGhvZE5vdEFsbG93ZWRNYXRjaGVzIiwic3RhdHVzQ29kZSIsImxvYWRlckhlYWRlcnMiLCJhY3Rpb25IZWFkZXJzIiwicXVlcnlJbXBsIiwiaXNSZXNwb25zZSIsInF1ZXJ5Um91dGUiLCJfdGVtcDMiLCJmaW5kIiwidmFsdWVzIiwiX3Jlc3VsdCRhY3RpdmVEZWZlcnJlIiwicm91dGVNYXRjaCIsInN1Ym1pdCIsImxvYWRSb3V0ZURhdGEiLCJpc1F1ZXJ5Um91dGVSZXNwb25zZSIsImlzUmVkaXJlY3RSZXNwb25zZSIsImlzUm91dGVSZXF1ZXN0IiwiaXNTdGF0aWNSZXF1ZXN0IiwiTG9jYXRpb24iLCJjb250ZXh0IiwibG9hZGVyUmVxdWVzdCIsImdldExvYWRlck1hdGNoZXNVbnRpbEJvdW5kYXJ5IiwicHJvY2Vzc1JvdXRlTG9hZGVyRGF0YSIsImV4ZWN1dGVkTG9hZGVycyIsImZyb21FbnRyaWVzIiwiZ2V0U3RhdGljQ29udGV4dEZyb21FcnJvciIsIm5ld0NvbnRleHQiLCJfZGVlcGVzdFJlbmRlcmVkQm91bmRhcnlJZCIsImlzU3VibWlzc2lvbk5hdmlnYXRpb24iLCJib2R5IiwicHJlcGVuZEJhc2VuYW1lIiwiY29udGV4dHVhbE1hdGNoZXMiLCJhY3RpdmVSb3V0ZU1hdGNoIiwiaGFzTmFrZWRJbmRleFF1ZXJ5Iiwibm9ybWFsaXplRm9ybU1ldGhvZCIsImlzRmV0Y2hlciIsImdldEludmFsaWRCb2R5RXJyb3IiLCJyYXdGb3JtTWV0aG9kIiwidG9VcHBlckNhc2UiLCJzdHJpcEhhc2hGcm9tUGF0aCIsIkZvcm1EYXRhIiwiVVJMU2VhcmNoUGFyYW1zIiwiX3JlZjMiLCJwYXJzZSIsInNlYXJjaFBhcmFtcyIsImNvbnZlcnRGb3JtRGF0YVRvU2VhcmNoUGFyYW1zIiwiY29udmVydFNlYXJjaFBhcmFtc1RvRm9ybURhdGEiLCJhcHBlbmQiLCJib3VuZGFyeUlkIiwiYm91bmRhcnlNYXRjaGVzIiwiZmluZEluZGV4IiwiY3VycmVudFVybCIsIm5leHRVcmwiLCJuYXZpZ2F0aW9uTWF0Y2hlcyIsImlzTmV3TG9hZGVyIiwiY3VycmVudFJvdXRlTWF0Y2giLCJuZXh0Um91dGVNYXRjaCIsInNob3VsZFJldmFsaWRhdGVMb2FkZXIiLCJjdXJyZW50UGFyYW1zIiwibmV4dFBhcmFtcyIsImRlZmF1bHRTaG91bGRSZXZhbGlkYXRlIiwiaXNOZXdSb3V0ZUluc3RhbmNlIiwiZmV0Y2hlck1hdGNoZXMiLCJmZXRjaGVyTWF0Y2giLCJzaG91bGRSZXZhbGlkYXRlIiwiY3VycmVudExvYWRlckRhdGEiLCJjdXJyZW50TWF0Y2giLCJpc05ldyIsImlzTWlzc2luZ0RhdGEiLCJjdXJyZW50UGF0aCIsImxvYWRlck1hdGNoIiwiYXJnIiwicm91dGVDaG9pY2UiLCJsb2FkTGF6eVJvdXRlTW9kdWxlIiwibGF6eVJvdXRlIiwicm91dGVUb1VwZGF0ZSIsInJvdXRlVXBkYXRlcyIsImxhenlSb3V0ZVByb3BlcnR5Iiwic3RhdGljUm91dGVWYWx1ZSIsImlzUHJvcGVydHlTdGF0aWNhbGx5RGVmaW5lZCIsInJlc3VsdFR5cGUiLCJvblJlamVjdCIsInJ1bkhhbmRsZXIiLCJoYW5kbGVyIiwicHJvdG9jb2wiLCJpc1NhbWVCYXNlbmFtZSIsInF1ZXJ5Um91dGVSZXNwb25zZSIsImNvbnRlbnRUeXBlIiwiaXNEZWZlcnJlZERhdGEiLCJfcmVzdWx0JGluaXQiLCJfcmVzdWx0JGluaXQyIiwiZGVmZXJyZWQiLCJmb3VuZEVycm9yIiwibmV3TG9hZGVyRGF0YSIsIm1lcmdlZExvYWRlckRhdGEiLCJlbGlnaWJsZU1hdGNoZXMiLCJyZXZlcnNlIiwiX3RlbXA0IiwiZXJyb3JNZXNzYWdlIiwib2JqIiwic2lnbmFscyIsImlzUmV2YWxpZGF0aW5nTG9hZGVyIiwidW53cmFwIiwiZ2V0QWxsIiwiaGFuZGxlIiwicGF0aE1hdGNoZXMiLCJVTlNBRkVfRGVmZXJyZWREYXRhIiwiVU5TQUZFX2NvbnZlcnRSb3V0ZXNUb0RhdGFSb3V0ZXMiLCJVTlNBRkVfZ2V0UGF0aENvbnRyaWJ1dGluZ01hdGNoZXMiLCJVTlNBRkVfaW52YXJpYW50IiwiVU5TQUZFX3dhcm5pbmciXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/@remix-run/router/dist/router.js\n");
/***/ })
};
;